diff --git a/src/engine/devcmd/cmds/aiInfoCmd.java b/src/engine/devcmd/cmds/aiInfoCmd.java index f148f56c..ea04332b 100644 --- a/src/engine/devcmd/cmds/aiInfoCmd.java +++ b/src/engine/devcmd/cmds/aiInfoCmd.java @@ -118,18 +118,17 @@ public class aiInfoCmd extends AbstractDevCmd { ArrayList powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID())); - // Additional powers may come from the contract ID. This is to support - // powers for player guards irrespective of the mobbase used. + // Player guards also cast their captain contract's powers, irrespective of the mobbase used. if (mob.isPlayerGuard()) { ArrayList contractEntries = new ArrayList<>(); if (mob.contract != null) - contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.contractUUID)); + contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.contractUUID)); if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) - contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.guardCaptain.contractUUID)); + contractEntries = new ArrayList<>(mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID)); powerEntries.addAll(contractEntries); diff --git a/src/engine/mbEnums.java b/src/engine/mbEnums.java index 3be3dd7d..e51f78e0 100644 --- a/src/engine/mbEnums.java +++ b/src/engine/mbEnums.java @@ -18,6 +18,7 @@ import engine.objects.AbstractCharacter; import engine.objects.Shrine; import engine.objects.Zone; import engine.powers.EffectsBase; +import engine.powers.RunePowerEntry; import org.pmw.tinylog.Logger; import java.util.ArrayList; @@ -2633,55 +2634,61 @@ public class mbEnums { public enum MinionType { AELFBORNGUARD(951, 1637, MinionClass.MELEE, "Guard", "Aelfborn"), - AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn"), + AELFBORNMAGE(952, 1635, MinionClass.MAGE, "Adept", "Aelfborn", "WIZ-016", "WIZ-061", "WIZ-025", "WIZ-020"), AMAZONGUARD(1500, 1670, MinionClass.MELEE, "Guard", "Amazon"), - AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon"), + AMAZONMAGE(1502, 1638, MinionClass.MAGE, "Fury", "Amazon", "FUR-003", "FUR-011", "FUR-009", "FUR-005"), ARACOIXGUARD(1600, 1672, MinionClass.MELEE, "Guard", "Aracoix"), //used guard captain equipset. - ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix"), + ARACOIXMAGE(1602, 885, MinionClass.MAGE, "Adept", "Aracoix", "WLR-029", "WLR-019", "WLR-027", "WLR-012"), CENTAURGUARD(1650, 1642, MinionClass.MELEE, "Guard", "Centaur"), - CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur"), + CENTAURMAGE(1652, 1640, MinionClass.MAGE, "Druid", "Centaur", "PRL-017", "PRL-046", "PRL-033", "PRL-009"), DWARVENARCHER(845, 1644, MinionClass.ARCHER, "Marksman", "Dwarven"), DWARVENGUARD(1050, 1666, MinionClass.MELEE, "Guard", "Dwarven"), - DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven"), + DWARVENMAGE(1052, 1643, MinionClass.MAGE, "War Priest", "Dwarven", "PRL-017", "PRL-046", "PRL-033", "PRL-009"), ELFGUARD(1180, 1671, MinionClass.MELEE, "Guard", "Elven"), //old 1645 - ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven"), + ELFMAGE(1182, 1667, MinionClass.MAGE, "Adept", "Elven", "WIZ-020", "WIZ-025", "WIZ-016", "WIZ-061"), FORESTGUARD(1550, 1668, MinionClass.MELEE, "Guard", "Forest"), //captain changed to guard equipset - FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest"), + FORESTMAGE(1552, 436, MinionClass.MAGE, "Adept", "Forest", "DRU-009", "DRU-023", "DRU-036", "DRU-015"), HOLYGUARD(1525, 1658, MinionClass.MELEE, "Guard", "Holy Church"), - HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church"), + HOLYMAGE(1527, 1646, MinionClass.MAGE, "Prelate", "Holy Church", "PRL-017", "PRL-046", "PRL-033", "PRL-009"), HUMANARCHER(846, 1654, MinionClass.ARCHER, "Archer", "Human"), HUMANGUARD(840, 1665, MinionClass.MELEE, "Guard", "Human"), - HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human"), + HUMANMAGE(848, 1655, MinionClass.MAGE, "Adept", "Human", "WIZ-016", "WIZ-025", "WIZ-020", "WIZ-061"), IREKEIGUARD(1350, 1659, MinionClass.MELEE, "Guard", "Irekei"), - IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei"), + IREKEIMAGE(1352, 1660, MinionClass.MAGE, "Adept", "Irekei", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"), MINOTAURARCHER(1701, 0, MinionClass.ARCHER, "Archer", "Minotaur"), MINOTAURGUARD(1700, 1673, MinionClass.MELEE, "Guard", "Minotaur"), NORTHMANGUARD(1250, 1669, MinionClass.MELEE, "Guard", "Northman"), - NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman"), + NORTHMANMAGE(1252, 1650, MinionClass.MAGE, "Runecaster", "Northman", "WIZ-061", "WIZ-016", "WIZ-025", "WIZ-020"), SHADEGUARD(1450, 1662, MinionClass.MELEE, "Guard", "Shade"), - SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade"), + SHADEMAGE(1452, 1664, MinionClass.MAGE, "Adept", "Shade", "NEC-001", "NEC-003", "MAG-013", "MAG-025"), TEMPLARGUARD(841, 1564, MinionClass.MELEE, "Marksman", "Templar"), TEMPLEGUARD(1575, 1652, MinionClass.MELEE, "Guard", "Temple"), - TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple"), + TEMPLEMAGE(1577, 1656, MinionClass.MAGE, "Confessor", "Temple", "CON-048", "CON-015", "CON-012", "CON-051"), UNDEADGUARD(980100, 1674, MinionClass.MELEE, "Guard", "Undead"), - UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead"), + UNDEADMAGE(980102, 1675, MinionClass.MAGE, "Adept", "Undead", "NEC-001", "NEC-003", "MAG-013", "MAG-025"), WEREWOLFGUARD(980104, 0, MinionClass.MELEE, "Guard", "Werewolf"), WEREBEARGUARD(980103, 0, MinionClass.MELEE, "Guard", "Werebear"); public static HashMap ContractToMinionMap = new HashMap<>(); + private static final int CAPTAIN_POWER_RANK = 40; private final int captainContractID; private final int equipSetID; private final MinionClass minionClass; private final String name; private final String race; + private final ArrayList captainPowers; - MinionType(int captainContractID, int equipSetID, MinionClass minionClass, String name, String race) { + // Captain powers were hand-made by the server team; no client rune or deed lists them + MinionType(int captainContractID, int equipSetID, MinionClass minionClass, String name, String race, String... captainPowerTypes) { this.captainContractID = captainContractID; this.equipSetID = equipSetID; this.minionClass = minionClass; this.name = name; this.race = race; + this.captainPowers = new ArrayList<>(); + for (String powerType : captainPowerTypes) + this.captainPowers.add(new RunePowerEntry(race + " " + name, powerType, CAPTAIN_POWER_RANK)); } public static void InitializeMinions() { @@ -2690,6 +2697,17 @@ public class mbEnums { ContractToMinionMap.put(minionType.captainContractID, minionType); } + // The powers a guard captain's contract casts, shared by its minions; empty for non-caster contracts + public static ArrayList getCaptainPowers(int captainContractID) { + + MinionType minionType = ContractToMinionMap.get(captainContractID); + + if (minionType == null) + return new ArrayList<>(); + + return minionType.captainPowers; + } + public String getName() { return name; } diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index bc0c8dc0..a4010e1a 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -276,7 +276,7 @@ public class MobAI { // Mobile has no powers defined in mobbase or contract.. - if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && PowersManager.getPowersForRune(contractID).isEmpty()) + if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && mbEnums.MinionType.getCaptainPowers(contractID).isEmpty()) return false; if (mob.nextCastTime == 0) @@ -309,18 +309,17 @@ public class MobAI { powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID())); purgeEntries = new ArrayList<>(); - // Additional powers may come from the contract ID. This is to support - // powers for player guards irrespective of the mobbase used. + // Player guards also cast their captain contract's powers, irrespective of the mobbase used. if (mob.isPlayerGuard()) { ArrayList contractEntries = new ArrayList<>(); if (mob.contract != null) - contractEntries = PowersManager.getPowersForRune(mob.contractUUID); + contractEntries = mbEnums.MinionType.getCaptainPowers(mob.contractUUID); if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) - contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID); + contractEntries = mbEnums.MinionType.getCaptainPowers(mob.guardCaptain.contractUUID); powerEntries.addAll(contractEntries); diff --git a/src/engine/powers/RunePowerEntry.java b/src/engine/powers/RunePowerEntry.java index e2beb4e7..36307803 100644 --- a/src/engine/powers/RunePowerEntry.java +++ b/src/engine/powers/RunePowerEntry.java @@ -17,7 +17,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; -import java.util.Map; public class RunePowerEntry { @@ -41,13 +40,19 @@ public class RunePowerEntry { this.rank = powerGrant.power_value; } - // Guard contract powers have no client source, so ids without a rune keep their DB rows. - public static HashMap> loadAllRunePowers(HashMap> dbRunePowers) { + public RunePowerEntry(String name, String powerType, int rank) { + this.name = name; + this.token = Hasher.SBStringHash(powerType); + this.power_type = powerType; + this.rank = rank; + } + + // Guard captain contract powers have no rune; they live on mbEnums.MinionType + public static HashMap> loadAllRunePowers() { HashMap> runePowers = new HashMap<>(); ArrayList powerList; int entryCount = 0; - int fallbackCount = 0; for (RuneTemplate rune : RuneTemplate._runes.values()) { @@ -63,16 +68,7 @@ public class RunePowerEntry { entryCount += powerList.size(); } - for (Map.Entry> dbEntry : dbRunePowers.entrySet()) { - - if (RuneTemplate._runes.containsKey(dbEntry.getKey())) - continue; - - runePowers.put(dbEntry.getKey(), dbEntry.getValue()); - fallbackCount++; - } - - Logger.info("Loaded " + entryCount + " rune powers from runes, " + fallbackCount + " ids from the DB; " + runePowers.size() + " ids"); + Logger.info("Loaded " + entryCount + " rune powers for " + runePowers.size() + " runes"); return runePowers; } diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index a60126ce..d798ca94 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -450,7 +450,7 @@ public class WorldServer { DbManager.MobBaseQueries.GET_ALL_MOBBASES(); Logger.info("Loading Rune Powers"); - PowersManager._allRunePowers = RunePowerEntry.loadAllRunePowers(dbRuneBaseHandler.LOAD_RUNE_POWERS()); + PowersManager._allRunePowers = RunePowerEntry.loadAllRunePowers(); Logger.info("Loading Rune Skill Adjusts"); PowersManager._allRuneSkillAdjusts = RuneSkillAdjustEntry.loadAllRuneSkillAdjusts();