Update Healer Man server

This commit is contained in:
phenom committed 2026-09-28 22:46:45 -04:00
1 parent 9d7e0e2f9e
commit 35dfdaed61
94 files changed
+17034 -418

No files matched your search

+67 -5
View File
@@ -1,10 +1,14 @@
import { beforeEach, describe, expect, it } from "vitest";
import { abilitiesForCharacter, learnedAbilityForBuild, type AbilityDefinition } from "./abilityCatalog";
import { abilitiesForCharacter, abilitiesForClass, learnedAbilityForBuild, type AbilityDefinition } from "./abilityCatalog";
import { applyAura } from "./combatAuras";
import { PLAYER_AGGRO_ID } from "./aggro";
import { useCombatStore } from "./combatStore";
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
import { romScoutRogueCastEffects, romScoutRogueProcActionSpec, romScoutRogueWhirlwindBonusEffect } from "./romScoutRogueOverrides";
const scoutRogue = abilitiesForCharacter("rom-scout", "rom-rogue");
const scoutWarrior = abilitiesForCharacter("rom-scout", "rom-warrior");
const roguePrimary = abilitiesForClass("rom-rogue");
const rogueWarrior = abilitiesForCharacter("rom-rogue", "rom-warrior");
function skill(abilities: readonly AbilityDefinition[], id: string): AbilityDefinition {
@@ -37,6 +41,20 @@ function prime(primary: "rom-scout" | "rom-rogue", level: number): void {
useCombatStore.getState().selectMob("target");
}
function primeScoutWarrior(level: number): void {
useCombatStore.getState().initializeCharacter({
classId: "rom-scout",
secondaryClassId: "rom-warrior",
raceId: "rom-elf",
level,
});
for (const [id, x, z] of [["target", 3, 0], ["behind", 6, 0], ["nearby", 3, 3]] as const) {
useCombatStore.getState().registerMob(id, { name: id, maxHealth: 1_000_000 });
setMobPosition(id, [x, 0, z]);
}
useCombatStore.getState().selectMob("target");
}
describe("accepted RoM Scout/Rogue and Rogue/Warrior pairings", () => {
beforeEach(() => clearMobRuntimeRegistry());
@@ -159,9 +177,10 @@ describe("accepted RoM Scout/Rogue and Rogue/Warrior pairings", () => {
expect(proc?.kind === "apply-aura" ? proc.aura.procs?.[0]?.internalCooldownMs : null).toBe(20_000);
});
it("proc resolver poisons Reflected or Combo Shot with unlimited Poison Powder", () => {
it("Poisonous Spit only adds its source poison while Poison Powder is active", () => {
for (const sourceId of [490457, 490424]) {
expect(romScoutRogueProcActionSpec("rom-poisonous-spit", sourceId, false)).toMatchObject({
expect(romScoutRogueProcActionSpec("rom-poisonous-spit", sourceId, false)).toBeNull();
expect(romScoutRogueProcActionSpec("rom-poisonous-spit", sourceId, true)).toMatchObject({
kind: "dot", recipient: "target", provenance: "source",
effect: { kind: "dot", ticks: 4, intervalMs: 2_000, basePoints: 7.1, pointsPerLevel: 2.1 },
});
@@ -171,14 +190,57 @@ describe("accepted RoM Scout/Rogue and Rogue/Warrior pairings", () => {
expect(proc?.kind === "apply-aura" ? proc.aura.procs?.[0]?.internalCooldownMs : null).toBe(20_000);
});
it("executes the Scout/Rogue poison rider on a successful reflected hit", () => {
it("does not execute Poisonous Spit without Poison Powder, then poisons after it is applied", () => {
prime("rom-scout", 60);
expect(useCombatStore.getState().castAbility("rom-scout-primary-11", undefined, 2_600))
expect(useCombatStore.getState().castAbility("rom-scout-primary-11", undefined, 1_000))
.toMatchObject({ ok: true });
expect(useCombatStore.getState().effects.some((effect) => effect.tag === "rom-poisonous-spit"
&& effect.targetId === "target")).toBe(false);
const poisonPowder = roguePrimary.find((ability) => ability.dbcSpellId === 490329);
if (!poisonPowder) throw new Error("Missing Poison Powder");
const powderAura = poisonPowder.effects.find((effect) => effect.kind === "apply-aura");
if (powderAura?.kind !== "apply-aura") throw new Error("Poison Powder has no aura");
const applied = applyAura(useCombatStore.getState().auras, {
definition: powderAura.aura,
sourceId: PLAYER_AGGRO_ID,
targetId: PLAYER_AGGRO_ID,
now: 3_000,
});
useCombatStore.setState({ auras: applied.auras });
expect(useCombatStore.getState().auras.some((aura) => aura.definition.utilityTags?.includes("rom-poisonous")))
.toBe(true);
expect(useCombatStore.getState().castAbility("rom-scout-primary-11", undefined, 22_000))
.toMatchObject({ ok: true });
expect(useCombatStore.getState().effects.some((effect) => effect.tag === "rom-poisonous-spit"
&& effect.targetId === "target")).toBe(true);
});
it("executes Accurate Targeting on a successful Shot for its sourced duration and modifier", () => {
primeScoutWarrior(60);
const passive = scoutWarrior.find((ability) => ability.dbcSpellId === 493006);
if (!passive) throw new Error("Missing Accurate Targeting");
const proc = passive.effects.find((effect) => effect.kind === "apply-aura");
expect(proc?.kind === "apply-aura" ? proc.aura.procs?.[0] : null).toMatchObject({
internalCooldownMs: 30_000,
action: { kind: "custom", id: "rom-accurate-targeting" },
});
expect(romScoutRogueProcActionSpec("rom-accurate-targeting", 490457, false)).toBeNull();
expect(romScoutRogueProcActionSpec("rom-accurate-targeting", 490423, false)).toMatchObject({
kind: "aura", recipient: "caster", provenance: "source", aura: {
durationMs: 15_000,
modifiers: [{ kind: "stat", stat: "physical-attack", operation: "flat", value: 50 }],
},
});
const shot = scoutRogue.find((ability) => ability.dbcSpellId === 490423);
if (!shot) throw new Error("Missing Shot");
expect(useCombatStore.getState().castAbility(shot.id, undefined, 1_000)).toMatchObject({ ok: true });
expect(useCombatStore.getState().auras.some((aura) => aura.definition.id === "rom-scout-accurate-targeting"
&& aura.definition.modifiers?.some((modifier) => modifier.kind === "stat"
&& modifier.stat === "physical-attack" && modifier.value === 50))).toBe(true);
});
it("proc resolver routes Reclaim Energy by trigger skill", () => {
expect(romScoutRogueProcActionSpec("rom-reclaim-energy", 490306, false)).toMatchObject({
kind: "resource", resource: "energy", amount: 15, provenance: "hybrid-estimate",