diff --git a/src/engine/objects/BaseClass.java b/src/engine/objects/BaseClass.java index bc231d2b..da9aa920 100644 --- a/src/engine/objects/BaseClass.java +++ b/src/engine/objects/BaseClass.java @@ -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())); } diff --git a/src/engine/objects/CharacterRune.java b/src/engine/objects/CharacterRune.java index ff7e1c17..59e70abe 100644 --- a/src/engine/objects/CharacterRune.java +++ b/src/engine/objects/CharacterRune.java @@ -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 { diff --git a/src/engine/objects/NPCRune.java b/src/engine/objects/NPCRune.java index ed692bbe..8ce6d103 100644 --- a/src/engine/objects/NPCRune.java +++ b/src/engine/objects/NPCRune.java @@ -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()); diff --git a/src/engine/objects/PromotionClass.java b/src/engine/objects/PromotionClass.java index 1cb4cf96..5944c432 100644 --- a/src/engine/objects/PromotionClass.java +++ b/src/engine/objects/PromotionClass.java @@ -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); diff --git a/src/engine/objects/Race.java b/src/engine/objects/Race.java index a3bc1c14..d290d31e 100644 --- a/src/engine/objects/Race.java +++ b/src/engine/objects/Race.java @@ -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); diff --git a/src/engine/objects/SkillReq.java b/src/engine/objects/SkillReq.java index e20fb180..98da092d 100644 --- a/src/engine/objects/SkillReq.java +++ b/src/engine/objects/SkillReq.java @@ -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> skillReqsByRune = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); private int skillID; private short level; private ArrayList skillReqs; + private HashMap skillReqAmounts; /* This shouldn't be used public SkillReq(SkillsBase skillsBase, short level, ArrayListskillReqs) { @@ -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 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 getSkillReqsForRune(int runeID) { + return skillReqsByRune.computeIfAbsent(runeID, SkillReq::loadSkillReqsForRune); + } + + private static ArrayList loadSkillReqsForRune(int runeID) { + + ArrayList 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() {