Update Healer Man server

This commit is contained in:
phenom committed 2026-09-20 20:15:40 -04:00
1 parent f864b5aea7
commit fdb6739f8d
10 files changed
+236 -16

No files matched your search

+42 -3
View File
@@ -209,9 +209,9 @@ describe("shared combat rotations", () => {
const contracts = [
{ classId: "warrior" as const, specialization: "Protection", id: "warrior:protection", actions: ["Defensive Stance", "Taunt", "Shield Bash", "Shield Slam", "Revenge", "Devastate", "Thunder Clap", "Shield Block", "Shield Wall", "Last Stand", "Enraged Regeneration"] },
{ classId: "priest" as const, specialization: "Discipline", id: "priest:discipline", actions: ["Penance", "Power Word: Shield", "Flash Heal", "Greater Heal", "Renew", "Dispel Magic", "Cure Disease", "Resurrection", "Pain Suppression", "Inner Focus", "Power Infusion", "Shadowfiend"] },
{ classId: "hunter" as const, specialization: "Marksmanship", id: "hunter:marksmanship", actions: ["Call Pet", "Aspect of the Dragonhawk", "Serpent Sting", "Chimera Shot", "Aimed Shot", "Arcane Shot", "Steady Shot", "Kill Shot", "Rapid Fire", "Readiness", "Misdirection", "Feign Death", "Silencing Shot", "Disengage"] },
{ classId: "mage" as const, specialization: "Fire", id: "mage:fire", actions: ["Molten Armor", "Living Bomb", "Fireball", "Scorch", "Fire Blast", "Combustion", "Mirror Image", "Counterspell", "Fire Ward", "Frost Ward", "Ice Block", "Blink"] },
{ classId: "rogue" as const, specialization: "Assassination", id: "rogue:assassination", actions: ["Instant Poison", "Deadly Poison", "Mutilate", "Shiv", "Rupture", "Envenom", "Cold Blood", "Kick", "Tricks of the Trade", "Evasion", "Cloak of Shadows", "Vanish"] },
{ classId: "hunter" as const, specialization: "Marksmanship", id: "hunter:marksmanship", actions: ["Call Pet", "Aspect of the Dragonhawk", "Serpent Sting", "Chimera Shot", "Aimed Shot", "Arcane Shot", "Steady Shot", "Multi-Shot", "Volley", "Kill Shot", "Rapid Fire", "Readiness", "Misdirection", "Feign Death", "Silencing Shot", "Disengage"] },
{ classId: "mage" as const, specialization: "Fire", id: "mage:fire", actions: ["Molten Armor", "Living Bomb", "Fireball", "Scorch", "Fire Blast", "Flamestrike", "Combustion", "Mirror Image", "Counterspell", "Fire Ward", "Frost Ward", "Ice Block", "Blink"] },
{ classId: "rogue" as const, specialization: "Assassination", id: "rogue:assassination", actions: ["Instant Poison", "Deadly Poison", "Mutilate", "Fan of Knives", "Shiv", "Rupture", "Envenom", "Cold Blood", "Kick", "Tricks of the Trade", "Evasion", "Cloak of Shadows", "Vanish"] },
];
for (const contract of contracts) {
const profile = rotationProfileFor(contract.classId, contract.id)!;
@@ -432,6 +432,45 @@ describe("shared combat rotations", () => {
.toBe("Envenom");
});
it("uses Ready DPS area actions only at their authored pack thresholds", () => {
const multiShot = ability("hunter", "Multi-Shot");
const volley = ability("hunter", "Volley");
const hunter = context({
classId: "hunter",
specializationId: "hunter:marksmanship",
primaryResource: "mana",
resources: { mana: 10_000 },
maximumResources: { mana: 10_000 },
abilities: [volley, multiShot],
});
expect(evaluateCombatRotation({ ...hunter, hostileCount: 1 })).toBeNull();
expect(evaluateCombatRotation({ ...hunter, hostileCount: 2 })?.ability.name).toBe("Multi-Shot");
expect(evaluateCombatRotation({ ...hunter, hostileCount: 3 })?.ability.name).toBe("Volley");
const flamestrike = ability("mage", "Flamestrike");
const fire = context({
classId: "mage",
specializationId: "mage:fire",
primaryResource: "mana",
resources: { mana: 10_000 },
maximumResources: { mana: 10_000 },
abilities: [flamestrike],
});
expect(evaluateCombatRotation({ ...fire, hostileCount: 2 })).toBeNull();
expect(evaluateCombatRotation({ ...fire, hostileCount: 3 })?.ability.name).toBe("Flamestrike");
const fan = ability("rogue", "Fan of Knives");
const assassination = context({
specializationId: "rogue:assassination",
primaryResource: "energy",
resources: { energy: 100 },
maximumResources: { energy: 100 },
abilities: [fan],
});
expect(evaluateCombatRotation({ ...assassination, hostileCount: 2 })).toBeNull();
expect(evaluateCombatRotation({ ...assassination, hostileCount: 3 })?.ability.name).toBe("Fan of Knives");
});
it("reacts before throughput and conserves long offensive cooldowns for durable targets", () => {
const kick = ability("rogue", "Kick");
const strike = ability("rogue", "Sinister Strike");