Update Healer Man server
This commit is contained in:
1 parent
4c768fbec6
commit
b16821e92e
330 files changed
+35406
-1760
No files matched your search
@@ -1,12 +1,16 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { abilityAtLevel, abilitiesForClass, preloadAbilityCatalogsForClasses } from "./abilityCatalog";
|
||||
import { useCombatStore } from "./combatStore";
|
||||
import { clearMobRuntimeRegistry } from "./mobRuntimeRegistry";
|
||||
import { clearPartyRuntimeRegistry, registerPartyRuntimePosition } from "./partyRuntimeRegistry";
|
||||
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
|
||||
import {
|
||||
clearPartyRuntimeRegistry,
|
||||
registerPartyRuntimePosition,
|
||||
updatePartyRuntimeTargetVisibility,
|
||||
} from "./partyRuntimeRegistry";
|
||||
import { advanceDungeonPartyCombat, resetPartyRuntimeClock } from "./partyRuntime";
|
||||
import { createConfiguredPartyMember, usePartyStore, type PartyMember } from "./partyStore";
|
||||
import { EMPTY_ITEM_STATS } from "./itemStats";
|
||||
import { partyAbilityAmount } from "./partyAbilityAi";
|
||||
import { partyAbilityAmount, partyAbilityCosts } from "./partyAbilityAi";
|
||||
import { WOW335_SHAMAN_TIDAL_WAVES_AURA_TAG } from "./wow335ShamanTidalWavesRuntime";
|
||||
|
||||
function stableUnit(seed: string): number {
|
||||
@@ -52,6 +56,8 @@ async function setupShamanParty(options: {
|
||||
readonly tidalRank?: number;
|
||||
readonly riptideRank?: number;
|
||||
readonly waterShieldRank?: number;
|
||||
readonly improvedShieldsRank?: number;
|
||||
readonly elementalFocusRank?: number;
|
||||
readonly secondShaman?: boolean;
|
||||
readonly secondShamanTidalRank?: number;
|
||||
readonly spellPower?: number;
|
||||
@@ -69,6 +75,8 @@ async function setupShamanParty(options: {
|
||||
"talent-2063": options.tidalRank ?? 0,
|
||||
"talent-2064": options.riptideRank ?? 0,
|
||||
"talent-583": options.waterShieldRank ?? 0,
|
||||
"talent-607": options.improvedShieldsRank ?? 0,
|
||||
"talent-574": options.elementalFocusRank ?? 0,
|
||||
};
|
||||
const firstShamanBase = createConfiguredPartyMember({
|
||||
name: "Party Shaman",
|
||||
@@ -150,11 +158,77 @@ function findPartyHealTime(
|
||||
}
|
||||
|
||||
describe("party WoW Shaman healing talents", () => {
|
||||
it("grants and consumes party Elemental Focus Clearcasting after a critical elemental spell", async () => {
|
||||
const members = await setupShamanParty({ elementalFocusRank: 2, criticalStrikeRating: 1_000_000 });
|
||||
const shaman = members[0];
|
||||
const bolt = shamanAbility("Lightning Bolt");
|
||||
const targetId = "shaman-elemental-focus-party-target";
|
||||
useCombatStore.getState().registerMob(targetId, {
|
||||
name: "Elemental Focus target",
|
||||
level: 80,
|
||||
maxHealth: 100_000,
|
||||
xpReward: 0,
|
||||
});
|
||||
setMobPosition(targetId, [2, 0, 0]);
|
||||
useCombatStore.getState().damageMob(targetId, 1, 500);
|
||||
updatePartyRuntimeTargetVisibility(shaman.id, targetId, true);
|
||||
const damageShaman: PartyMember = {
|
||||
...onlyReady(shaman, "Lightning Bolt"),
|
||||
role: "damage",
|
||||
health: shaman.maxHealth,
|
||||
globalCooldownEndsAt: 0,
|
||||
nextActionAt: 0,
|
||||
};
|
||||
const fullManaCost = partyAbilityCosts(damageShaman, bolt, 1_000)
|
||||
.find((cost) => cost.resource === "mana")?.amount;
|
||||
usePartyStore.setState((state) => ({
|
||||
command: "attack",
|
||||
activeMobId: targetId,
|
||||
members: state.members.map((member) => member.id === shaman.id
|
||||
? damageShaman
|
||||
: { ...member, cooldowns: Object.fromEntries(abilitiesForClass("warrior").map((ability) => [ability.id, 1_000_000])) }),
|
||||
}));
|
||||
useCombatStore.getState().commitCompanionActors(usePartyStore.getState().members);
|
||||
|
||||
advanceDungeonPartyCombat(1_000);
|
||||
const firstCast = usePartyStore.getState().members.find((member) => member.id === shaman.id)?.activeCast;
|
||||
expect(firstCast?.abilityId).toBe(bolt.id);
|
||||
advanceDungeonPartyCombat(firstCast!.completesAt);
|
||||
|
||||
const hit = [...useCombatStore.getState().combatEvents].reverse().find((event) => (
|
||||
event.kind === "damage" && event.sourceActorId === shaman.id && event.abilityId === bolt.id
|
||||
));
|
||||
expect(hit).toMatchObject({ critical: true });
|
||||
const clearcasting = () => useCombatStore.getState().auras.find((aura) => (
|
||||
aura.sourceId === shaman.id
|
||||
&& aura.targetId === shaman.id
|
||||
&& aura.definition.utilityTags?.includes("wow335-shaman-elemental-focus-clearcasting")
|
||||
));
|
||||
expect(clearcasting()).toMatchObject({ stacks: 2, expiresAt: hit!.occurredAt + 15_000 });
|
||||
|
||||
expect(fullManaCost).toBeGreaterThan(0);
|
||||
expect(partyAbilityCosts(shaman, bolt, hit!.occurredAt)
|
||||
.find((cost) => cost.resource === "mana")?.amount).toBe(Math.round(fullManaCost! * 0.7));
|
||||
|
||||
const currentShaman = usePartyStore.getState().members.find((member) => member.id === shaman.id)!;
|
||||
usePartyStore.setState((state) => ({
|
||||
members: state.members.map((member) => member.id === shaman.id
|
||||
? { ...onlyReady(currentShaman, "Lightning Bolt"), globalCooldownEndsAt: 0, nextActionAt: 0 }
|
||||
: member),
|
||||
}));
|
||||
useCombatStore.getState().commitCompanionActors(usePartyStore.getState().members);
|
||||
advanceDungeonPartyCombat(hit!.occurredAt + 1_000);
|
||||
expect(usePartyStore.getState().members.find((member) => member.id === shaman.id)?.activeCast?.abilityId)
|
||||
.toBe(bolt.id);
|
||||
expect(clearcasting()?.stacks).toBe(1);
|
||||
});
|
||||
|
||||
it("procs rank-owned Improved Water Shield from its own critical Healing Wave and restores only its mana", async () => {
|
||||
const members = await setupShamanParty({
|
||||
tidalRank: 3,
|
||||
riptideRank: 1,
|
||||
waterShieldRank: 3,
|
||||
improvedShieldsRank: 3,
|
||||
spellPower: 1_000,
|
||||
criticalStrikeRating: 100_000,
|
||||
secondShaman: true,
|
||||
@@ -225,7 +299,8 @@ describe("party WoW Shaman healing talents", () => {
|
||||
expect(healingEvent?.rawAmount).toBe(Math.round((ordinaryHeal + 120) * 1.5));
|
||||
expect(waterShieldEvent).toMatchObject({
|
||||
targetActorId: shaman.id,
|
||||
effectiveAmount: 400,
|
||||
rawAmount: 460,
|
||||
effectiveAmount: 460,
|
||||
overheal: 0,
|
||||
});
|
||||
expect(combat.combatEvents).not.toContainEqual(expect.objectContaining({
|
||||
|
||||
Reference in new issue
Block a user