Load rune skill reqs from rune_skill_grant instead of static_skill_skillreq
SkillReq.getSkillReqsForRune builds each rune's list from the RUNE JSON on first use and caches it: skill_value is the grant level and skill_granted_skills are the prereqs. The prereq amounts (80, Warrior 50, Sun Dancer 60) are loaded but not yet read; CharacterSkill keeps its hard-coded 80 and validForWarrior. Parity (scripts/p29.py): 47 of 79 DB runes match. Value changes (JSON wins, Task 2.9 decisions): - Thief Dagger Mastery, Throwing, Unarmed Combat Mastery: level 15 -> 20 - Sentinel Axe/Great Axe/Hammer/Great Hammer/Sword Mastery: 20 -> 15; gains Great Sword Mastery (15, Sword); loses Wear Armor, Medium - Channeler loses Sword; Storm Lord loses Stormcalling - Blood Horn gains Hammer Mastery (20, Hammer) - No weapon prereq any more on Archer Archery, Blade Weaver Blade Weaving, Sun Dancer Sun Dancing and the 11 Master of X talents - No effect: Druid/Prelate Sword and Fury Spear 10 -> 1 (promotion is at 10), discipline/talent level changes (they need level 20), Throwing prereqs (always granted), Blade Master Sword prereq (granted at 1) - JSON-only runes (Archon, Duelist, War Correspondent, Pet, mob/guard races) gain lists; Archon resistances and Duelist Dueling are not skills and are skipped with a warning Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d6df01f8f3
commit
4170749a59
6 files changed
+84
-12
No files matched your search
@@ -102,7 +102,7 @@ public class BaseClass extends AbstractGameObject {
|
||||
this.healthMod = rs.getInt("healthMod");
|
||||
this.manaMod = rs.getInt("manaMod");
|
||||
this.staminaMod = rs.getInt("staminaMod");
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsList = (DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID()));
|
||||
|
||||
@@ -125,7 +125,7 @@ public class BaseClass extends AbstractGameObject {
|
||||
this.healthMod = rune.rune_health;
|
||||
this.manaMod = rune.rune_mana;
|
||||
this.staminaMod = rune.rune_stamina;
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsList = (DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID()));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class CharacterRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
@@ -57,7 +57,7 @@ public class CharacterRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
@@ -78,7 +78,7 @@ public class CharacterRune extends AbstractGameObject {
|
||||
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||
this.player = rs.getInt("CharacterID");
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
|
||||
@@ -33,7 +33,7 @@ public class NPCRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase != null)
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
@@ -47,7 +47,7 @@ public class NPCRune extends AbstractGameObject {
|
||||
this.runeBase = runeBase;
|
||||
this.player = characterID;
|
||||
if (this.runeBase == null)
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
else
|
||||
this.skillsGranted = new ArrayList<>();
|
||||
this.effectsGranted = new ArrayList<>();
|
||||
@@ -62,7 +62,7 @@ public class NPCRune extends AbstractGameObject {
|
||||
this.runeBase = RuneBase.getRuneBase(rs.getInt("RuneBaseID"));
|
||||
this.player = rs.getInt("NpcID");
|
||||
if (this.runeBase != null) {
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.runeBase.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.runeBase.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.runeBase.getObjectUUID());
|
||||
} else {
|
||||
Logger.error("Failed to find RuneBase for NPCRune " + this.getObjectUUID());
|
||||
|
||||
@@ -96,7 +96,7 @@ public class PromotionClass extends AbstractGameObject {
|
||||
this.manaMod = rs.getFloat("manaMod");
|
||||
this.staminaMod = rs.getFloat("staminaMod");
|
||||
this.allowedRunes = DbManager.PromotionQueries.GET_ALLOWED_RUNES(this);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.getObjectUUID());
|
||||
this.effectsGrantedFighter = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2500);
|
||||
@@ -121,7 +121,7 @@ public class PromotionClass extends AbstractGameObject {
|
||||
this.manaMod = rune.rune_mana;
|
||||
this.staminaMod = rune.rune_stamina;
|
||||
this.allowedRunes = getAllowedRuneTokens(rune);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(this.getObjectUUID());
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(this.getObjectUUID());
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(this.getObjectUUID());
|
||||
this.effectsGranted = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE(this.getObjectUUID());
|
||||
this.effectsGrantedFighter = DbManager.RuneBaseEffectQueries.GET_EFFECTS_FOR_RUNEBASE((this.getObjectUUID() * 10) + 2500);
|
||||
|
||||
@@ -108,7 +108,7 @@ public class Race {
|
||||
this.beardColors = DbManager.RaceQueries.BEARD_COLORS_FOR_RACE(raceRuneID);
|
||||
this.hairColors = DbManager.RaceQueries.HAIR_COLORS_FOR_RACE(raceRuneID);
|
||||
this.baseClasses = DbManager.BaseClassQueries.GET_BASECLASS_FOR_RACE(raceRuneID);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(raceRuneID);
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(raceRuneID);
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(raceRuneID);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.raceRuneID);
|
||||
|
||||
@@ -152,7 +152,7 @@ public class Race {
|
||||
this.beardColors = DbManager.RaceQueries.BEARD_COLORS_FOR_RACE(raceRuneID);
|
||||
this.hairColors = DbManager.RaceQueries.HAIR_COLORS_FOR_RACE(raceRuneID);
|
||||
this.baseClasses = getBaseClassesForRace(rune);
|
||||
this.skillsGranted = DbManager.SkillReqQueries.GET_REQS_FOR_RUNE(raceRuneID);
|
||||
this.skillsGranted = SkillReq.getSkillReqsForRune(raceRuneID);
|
||||
this.powersGranted = PowerReq.getPowerReqsForRune(raceRuneID);
|
||||
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.raceRuneID);
|
||||
|
||||
|
||||
@@ -10,18 +10,27 @@
|
||||
package engine.objects;
|
||||
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.parsers.objects.RuneTemplate;
|
||||
import engine.server.MBServerStatics;
|
||||
import org.pmw.tinylog.Logger;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
public class SkillReq extends AbstractGameObject {
|
||||
|
||||
private static final int DB_SKILL_REQ_AMOUNT = 80;
|
||||
private static final ConcurrentHashMap<Integer, ArrayList<SkillReq>> skillReqsByRune = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
|
||||
|
||||
private int skillID;
|
||||
private short level;
|
||||
private ArrayList<Byte> skillReqs;
|
||||
private HashMap<Byte, Integer> skillReqAmounts;
|
||||
|
||||
/* This shouldn't be used
|
||||
public SkillReq(SkillsBase skillsBase, short level, ArrayList<Byte>skillReqs) {
|
||||
@@ -60,6 +69,7 @@ public class SkillReq extends AbstractGameObject {
|
||||
this.skillID = rs.getInt("skillID");
|
||||
this.level = rs.getShort("level");
|
||||
skillReqs = new ArrayList<>(0);
|
||||
skillReqAmounts = new HashMap<>();
|
||||
|
||||
int skillReq;
|
||||
skillReq = rs.getInt("skillreq1");
|
||||
@@ -71,6 +81,64 @@ public class SkillReq extends AbstractGameObject {
|
||||
skillReq = rs.getInt("skillreq3");
|
||||
if (skillReq > 0)
|
||||
skillReqs.add((byte) skillReq);
|
||||
|
||||
// DB rows carry no amount; the server hard-codes 80
|
||||
for (byte reqSkillID : skillReqs)
|
||||
skillReqAmounts.put(reqSkillID, DB_SKILL_REQ_AMOUNT);
|
||||
}
|
||||
|
||||
// skill_value is the level the skill is granted at; skill_granted_skills are prereq skills with amounts
|
||||
public SkillReq(RuneTemplate.SkillGrant skillGrant, SkillsBase skillsBase, int runeID) {
|
||||
super();
|
||||
|
||||
SkillsBase reqSkillsBase;
|
||||
|
||||
this.skillID = skillsBase.getObjectUUID();
|
||||
this.level = (short) skillGrant.skill_value;
|
||||
this.skillReqs = new ArrayList<>(0);
|
||||
this.skillReqAmounts = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, Integer> reqSkill : skillGrant.skill_granted_skills.entrySet()) {
|
||||
|
||||
reqSkillsBase = DbManager.SkillsBaseQueries.GET_BASE_BY_NAME(reqSkill.getKey());
|
||||
|
||||
if (reqSkillsBase == null) {
|
||||
Logger.warn("Rune " + runeID + " skill grant " + skillGrant.skill_type + ": unknown prereq skill " + reqSkill.getKey());
|
||||
continue;
|
||||
}
|
||||
|
||||
this.skillReqs.add((byte) reqSkillsBase.getObjectUUID());
|
||||
this.skillReqAmounts.put((byte) reqSkillsBase.getObjectUUID(), reqSkill.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<SkillReq> getSkillReqsForRune(int runeID) {
|
||||
return skillReqsByRune.computeIfAbsent(runeID, SkillReq::loadSkillReqsForRune);
|
||||
}
|
||||
|
||||
private static ArrayList<SkillReq> loadSkillReqsForRune(int runeID) {
|
||||
|
||||
ArrayList<SkillReq> runeSkillReqs = new ArrayList<>();
|
||||
RuneTemplate rune = RuneTemplate._runes.get(runeID);
|
||||
SkillsBase skillsBase;
|
||||
|
||||
if (rune == null)
|
||||
return runeSkillReqs;
|
||||
|
||||
for (RuneTemplate.SkillGrant skillGrant : rune.rune_skill_grant) {
|
||||
|
||||
skillsBase = DbManager.SkillsBaseQueries.GET_BASE_BY_NAME(skillGrant.skill_type);
|
||||
|
||||
// Archon 2018 grants resistances and Duelist 3010 grants Dueling; neither is a skill
|
||||
if (skillsBase == null) {
|
||||
Logger.warn("Rune " + runeID + ": skill grant " + skillGrant.skill_type + " is not a skill");
|
||||
continue;
|
||||
}
|
||||
|
||||
runeSkillReqs.add(new SkillReq(skillGrant, skillsBase, runeID));
|
||||
}
|
||||
|
||||
return runeSkillReqs;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -92,6 +160,10 @@ public class SkillReq extends AbstractGameObject {
|
||||
return this.skillReqs;
|
||||
}
|
||||
|
||||
public int getSkillReqAmount(byte reqSkillID) {
|
||||
return this.skillReqAmounts.getOrDefault(reqSkillID, DB_SKILL_REQ_AMOUNT);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateDatabase() {
|
||||
|
||||
Reference in new issue
Block a user