Update Healer Man server
This commit is contained in:
1 parent
4c768fbec6
commit
b16821e92e
330 files changed
+35406
-1760
No files matched your search
@@ -0,0 +1,113 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { useCombatStore, PLAYER_AURA_ENTITY_ID } from "./combatStore";
|
||||
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
|
||||
import {
|
||||
clearPartyRuntimeRegistry,
|
||||
registerPartyRuntimePosition,
|
||||
updatePartyRuntimeTargetVisibility,
|
||||
} from "./partyRuntimeRegistry";
|
||||
import { abilityAtLevel, abilitiesForClass, preloadAbilityCatalogsForClasses } from "./abilityCatalog";
|
||||
import { WOW335_MAGE_NETHERWIND_PRESENCE_TAG } from "./wow335MageNetherwindPresenceRuntime";
|
||||
import { advanceDungeonPartyCombat, resetPartyRuntimeClock } from "./partyRuntime";
|
||||
import { createConfiguredPartyMember, usePartyStore } from "./partyStore";
|
||||
import { EMPTY_ITEM_STATS } from "./itemStats";
|
||||
|
||||
async function resetMage(): Promise<void> {
|
||||
clearMobRuntimeRegistry();
|
||||
clearPartyRuntimeRegistry();
|
||||
resetPartyRuntimeClock();
|
||||
await preloadAbilityCatalogsForClasses(["mage"]);
|
||||
useCombatStore.getState().initializeCharacter({ classId: "mage", level: 80 });
|
||||
useCombatStore.getState().resetSettings();
|
||||
useCombatStore.getState().setPlayerPosition([0, 0, 0]);
|
||||
useCombatStore.setState((state) => ({
|
||||
resource: state.maxResource,
|
||||
resourcePools: { ...state.resourcePools, mana: state.maxResourcePools.mana },
|
||||
talentRanks: { ...state.talentRanks, "talent-1846": 1 },
|
||||
}));
|
||||
useCombatStore.getState().registerMob("netherwind-target", { name: "Target", maxHealth: 100_000 });
|
||||
setMobPosition("netherwind-target", [4, 0, 0]);
|
||||
useCombatStore.getState().selectMob("netherwind-target");
|
||||
}
|
||||
|
||||
describe("WoW Mage Netherwind Presence cast integration", () => {
|
||||
beforeEach(resetMage);
|
||||
|
||||
it("grants one stack for an accepted Arcane Missiles cast, not for each channel pulse", () => {
|
||||
const arcaneMissiles = useCombatStore.getState().abilities.find((ability) => ability.name === "Arcane Missiles")!;
|
||||
const started = useCombatStore.getState().castAbility(arcaneMissiles.id, undefined, 1_000);
|
||||
expect(started).toMatchObject({ ok: true });
|
||||
const cast = useCombatStore.getState().activeCast!;
|
||||
expect(cast.mode).toBe("channel");
|
||||
|
||||
const hasteAura = () => useCombatStore.getState().auras.find((aura) => (
|
||||
aura.sourceId === PLAYER_AURA_ENTITY_ID
|
||||
&& aura.targetId === PLAYER_AURA_ENTITY_ID
|
||||
&& aura.definition.utilityTags?.includes(WOW335_MAGE_NETHERWIND_PRESENCE_TAG)
|
||||
));
|
||||
expect(hasteAura()).toMatchObject({ stacks: 1 });
|
||||
|
||||
useCombatStore.getState().tick(0.1, cast.completesAt);
|
||||
const impacts = useCombatStore.getState().combatEvents.filter((event) => (
|
||||
event.kind === "damage" && event.abilityId === arcaneMissiles.id
|
||||
));
|
||||
expect(impacts).toHaveLength(5);
|
||||
expect(hasteAura()).toMatchObject({ stacks: 1 });
|
||||
|
||||
const nextStartAt = cast.completesAt + 1_000;
|
||||
const nextStarted = useCombatStore.getState().castAbility(arcaneMissiles.id, undefined, nextStartAt);
|
||||
expect(nextStarted).toMatchObject({ ok: true });
|
||||
expect(useCombatStore.getState().activeCast!.originalDurationMs).toBeLessThan(cast.originalDurationMs);
|
||||
expect(hasteAura()).toMatchObject({ stacks: 2 });
|
||||
});
|
||||
|
||||
it("grants the same cast-commit stack to a generated party Mage", async () => {
|
||||
await preloadAbilityCatalogsForClasses(["mage"]);
|
||||
useCombatStore.getState().initializeCharacter({ classId: "mage", level: 80 });
|
||||
usePartyStore.getState().initializeParty("netherwind-party-mage", 80,
|
||||
useCombatStore.getState().health, "damage", 1);
|
||||
const mage = createConfiguredPartyMember({
|
||||
name: "Netherwind Companion",
|
||||
classId: "mage",
|
||||
specialization: "Arcane",
|
||||
specializationId: "mage:arcane",
|
||||
talentTreeId: "mage-arcane",
|
||||
talentRanks: { "talent-1846": 1 },
|
||||
role: "damage",
|
||||
}, 80, 0, "netherwind-party-mage");
|
||||
const arcaneMissiles = abilityAtLevel(
|
||||
abilitiesForClass("mage").find((ability) => ability.name === "Arcane Missiles")!,
|
||||
80,
|
||||
);
|
||||
const cooldowns = Object.fromEntries(abilitiesForClass("mage").map((ability) => [ability.id, 100_000]));
|
||||
delete cooldowns[arcaneMissiles.id];
|
||||
usePartyStore.setState({ members: [{
|
||||
...mage,
|
||||
talentRanks: { "talent-1846": 1 },
|
||||
gearStats: EMPTY_ITEM_STATS,
|
||||
cooldowns,
|
||||
globalCooldownEndsAt: 0,
|
||||
resource: 10_000,
|
||||
maxResource: 10_000,
|
||||
resourcePools: { ...mage.resourcePools, mana: 10_000 },
|
||||
}] });
|
||||
registerPartyRuntimePosition(mage.id, [0, 0, 0]);
|
||||
useCombatStore.getState().synchronizeActors();
|
||||
useCombatStore.getState().registerMob("netherwind-party-target", {
|
||||
name: "Party Target", maxHealth: 100_000, level: 80, xpReward: 0,
|
||||
});
|
||||
setMobPosition("netherwind-party-target", [4, 0, 0]);
|
||||
useCombatStore.getState().damageMob("netherwind-party-target", 1, 100);
|
||||
updatePartyRuntimeTargetVisibility(mage.id, "netherwind-party-target", true);
|
||||
usePartyStore.setState({ command: "attack", activeMobId: "netherwind-party-target" });
|
||||
|
||||
advanceDungeonPartyCombat(1_000);
|
||||
|
||||
expect(usePartyStore.getState().members[0]?.activeCast?.abilityId).toBe(arcaneMissiles.id);
|
||||
expect(useCombatStore.getState().auras.find((aura) => (
|
||||
aura.sourceId === mage.id
|
||||
&& aura.targetId === mage.id
|
||||
&& aura.definition.utilityTags?.includes(WOW335_MAGE_NETHERWIND_PRESENCE_TAG)
|
||||
))).toMatchObject({ stacks: 1 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user