From b4a15ebf6029eb1f47b1d3e321968d8241bb53da Mon Sep 17 00:00:00 2001 From: MagicBot Date: Sat, 24 Oct 2026 13:44:08 -0400 Subject: [PATCH] Take guard spell rank from the Standing Guard rune steps The client ranks a power by adding every POWERSADJ (item_power_action) step at or below the character's level (0x4B34B0). The Standing Guard rune's Wizard steps (10@10, 10@20, 10@30, 5@40..70) now set the rank of every captain spell, capped at the power's MaxLevel as player casts are. Value change by guard rank 1-7: before 10/15/20/25/30/35/40 after 10/20/30/35/40/40/40 All 28 captain spells have MaxLevel 40; the uncapped sum would be 50. Using one curve for the non-Wizard faction spells and the cap are user decisions (Task 3.9 follow-up 3). Co-Authored-By: Claude Opus 5.5 --- src/engine/mobileAI/MobAI.java | 51 ++++++++++++++++------------------ 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/engine/mobileAI/MobAI.java b/src/engine/mobileAI/MobAI.java index a4010e1a..8c78ab4b 100644 --- a/src/engine/mobileAI/MobAI.java +++ b/src/engine/mobileAI/MobAI.java @@ -19,6 +19,7 @@ import engine.mobileAI.Threads.ReSpawner; import engine.mobileAI.utilities.MovementUtilities; import engine.net.client.msg.PerformActionMsg; import engine.objects.*; +import engine.parsers.objects.RuneTemplate; import engine.powers.ActionsBase; import engine.powers.PowersBase; import engine.powers.RunePowerEntry; @@ -49,6 +50,8 @@ public class MobAI { private static final boolean PET_AGGRO_ENABLED = false; + private static final int STANDING_GUARD_RUNE_ID = 252623; + private static void attackTarget(Mob mob, AbstractWorldObject target) { try { @@ -356,7 +359,7 @@ public class MobAI { int powerRank = runePowerEntry.rank; if (mob.isPlayerGuard()) - powerRank = getGuardPowerRank(mob); + powerRank = getGuardPowerRank(mob, mobPower); // Cast the spell @@ -386,33 +389,27 @@ public class MobAI { return false; } - public static int getGuardPowerRank(Mob mob) { - int powerRank = 1; + // Client power rank adds every POWERSADJ step at or below the level (0x4B34B0). The Standing Guard rune's + // Wizard steps are the curve for every captain spell, capped at MaxLevel as player casts are. + public static int getGuardPowerRank(Mob mob, PowersBase power) { - switch (mob.getRank()) { - case 1: - powerRank = 10; - break; - case 2: - powerRank = 15; - break; - case 3: - powerRank = 20; - break; - case 4: - powerRank = 25; - break; - case 5: - powerRank = 30; - break; - case 6: - powerRank = 35; - break; - case 7: - powerRank = 40; - break; - } - return powerRank; + RuneTemplate guardRune = RuneTemplate._runes.get(STANDING_GUARD_RUNE_ID); + ArrayList rankSteps; + int powerRank = 0; + + if (guardRune == null || guardRune.item_power_action.isEmpty()) + return 1; + + rankSteps = guardRune.item_power_action.get(power.getIDString()); + + if (rankSteps == null) + rankSteps = guardRune.item_power_action.values().iterator().next(); + + for (int[] rankStep : rankSteps) + if (rankStep[1] <= mob.getLevel()) + powerRank += rankStep[0]; + + return Math.max(1, Math.min(powerRank, power.getMaxTrains())); } public static void mobCallForHelp(Mob mob) {