forked from phenom/healer-man
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,153 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { abilityById } from "./abilityCatalog";
|
||||
import { PLAYER_AGGRO_ID } from "./aggro";
|
||||
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
|
||||
import { useCombatStore, equipmentAdjustedCombatAmount } from "./combatStore";
|
||||
import { advanceDungeonPartyCombat, resetPartyRuntimeClock } from "./partyRuntime";
|
||||
import { clearPartyRuntimeRegistry, registerPartyRuntimePosition, updatePartyRuntimeTargetVisibility } from "./partyRuntimeRegistry";
|
||||
import { createConfiguredPartyMember, usePartyStore } from "./partyStore";
|
||||
import { ROM_PRIEST_HOLY_BLESSING_TAG, romPriestHolyBlessingStats } from "./romPriestHolyBlessingRuntime";
|
||||
import { resolveDamageValue } from "./combatAuras";
|
||||
import { deriveCharacterStats } from "./wotlkStats";
|
||||
|
||||
const spell = abilityById("rom-priest-general-1");
|
||||
const spellEffect = spell?.effects.find((effect) => effect.kind === "damage");
|
||||
|
||||
function damageWithSchool(targetId: string, sourceActorId: string, school: "holy" | "nature", now: number) {
|
||||
return useCombatStore.getState().damageMob(
|
||||
targetId,
|
||||
1_000,
|
||||
now,
|
||||
{ actorId: sourceActorId, role: "damage" },
|
||||
school,
|
||||
{
|
||||
attackKind: "spell",
|
||||
seed: `holy-blessing:${sourceActorId}:${school}:${now}`,
|
||||
rules: {
|
||||
canMiss: false,
|
||||
canCrit: false,
|
||||
canDodge: false,
|
||||
canParry: false,
|
||||
canBlock: false,
|
||||
},
|
||||
},
|
||||
).amount;
|
||||
}
|
||||
|
||||
describe("RoM Priest Holy Blessing combat integration", () => {
|
||||
beforeEach(() => {
|
||||
clearMobRuntimeRegistry();
|
||||
clearPartyRuntimeRegistry();
|
||||
resetPartyRuntimeClock();
|
||||
useCombatStore.getState().initializeCharacter({
|
||||
classId: "rom-priest",
|
||||
raceId: "rom-human",
|
||||
level: 80,
|
||||
role: "healer",
|
||||
});
|
||||
usePartyStore.getState().initializeParty(
|
||||
"rom-priest-holy-blessing-integration", 80, useCombatStore.getState().health, "healer", 2, "rom",
|
||||
);
|
||||
for (const id of ["holy-blessing-holy-target", "holy-blessing-nature-target"]) {
|
||||
useCombatStore.getState().registerMob(id, { name: id, maxHealth: 100_000, level: 80 });
|
||||
setMobPosition(id, [3, 0, 0]);
|
||||
}
|
||||
});
|
||||
|
||||
it("adds the Wisdom-derived spell power to a real player spell amount and buffs only Holy damage", () => {
|
||||
if (!spell || spellEffect?.kind !== "damage") throw new Error("Missing generated Priest spell damage row");
|
||||
const state = useCombatStore.getState();
|
||||
const passiveAura = state.auras.find((aura) => aura.targetId === PLAYER_AGGRO_ID
|
||||
&& aura.definition.utilityTags?.includes(ROM_PRIEST_HOLY_BLESSING_TAG));
|
||||
expect(passiveAura).toBeDefined();
|
||||
const base = deriveCharacterStats("rom-priest", 80, state.gearStats, state.raceId, {}, state.secondaryClassId);
|
||||
const bonus = romPriestHolyBlessingStats(base, state.auras).spellPowerBonus;
|
||||
const expectedAmount = equipmentAdjustedCombatAmount(spellEffect, 80, state.gearStats, "rom-priest", spell, bonus);
|
||||
const unblessedAmount = equipmentAdjustedCombatAmount(spellEffect, 80, state.gearStats, "rom-priest", spell);
|
||||
const playerSourceAuras = state.auras.filter((aura) => aura.targetId === PLAYER_AGGRO_ID);
|
||||
const expectedCombatAmount = resolveDamageValue(expectedAmount, playerSourceAuras, {
|
||||
direction: "dealt", school: "frost", attackKind: "spell",
|
||||
});
|
||||
const unblessedCombatAmount = resolveDamageValue(
|
||||
unblessedAmount,
|
||||
playerSourceAuras.filter((aura) => !aura.definition.utilityTags?.includes(ROM_PRIEST_HOLY_BLESSING_TAG)),
|
||||
{ direction: "dealt", school: "frost", attackKind: "spell" },
|
||||
);
|
||||
expect(bonus).toBeGreaterThan(0);
|
||||
expect(expectedCombatAmount).toBeGreaterThan(unblessedCombatAmount);
|
||||
|
||||
useCombatStore.getState().selectMob("holy-blessing-nature-target");
|
||||
expect(useCombatStore.getState().castAbility(spell.id, undefined, 1_000)).toMatchObject({ ok: true });
|
||||
useCombatStore.getState().tick(3, 5_000);
|
||||
const damage = useCombatStore.getState().combatEvents.find((event) => event.kind === "damage"
|
||||
&& event.sourceActorId === PLAYER_AGGRO_ID && event.abilityId === spell.id);
|
||||
expect(damage).toBeDefined();
|
||||
expect(damage?.rawAmount).toBe(Math.round(expectedCombatAmount * (damage?.critical ? 1.5 : 1)));
|
||||
|
||||
const holy = damageWithSchool("holy-blessing-holy-target", PLAYER_AGGRO_ID, "holy", 21_000);
|
||||
const nature = damageWithSchool("holy-blessing-nature-target", PLAYER_AGGRO_ID, "nature", 22_000);
|
||||
expect(holy).toBe(2_009);
|
||||
expect(nature).toBe(1_000);
|
||||
});
|
||||
|
||||
it("adds the Wisdom-derived spell power to a generated-companion spell and buffs only Holy damage", () => {
|
||||
if (!spell || spellEffect?.kind !== "damage") throw new Error("Missing generated Priest spell damage row");
|
||||
const seed = "rom-priest-holy-blessing-companion";
|
||||
const priest = createConfiguredPartyMember({
|
||||
name: "Holy Blessing Priest",
|
||||
classId: "rom-priest",
|
||||
specialization: "Primary",
|
||||
role: "healer",
|
||||
}, 80, 0, seed);
|
||||
usePartyStore.setState({ members: [{
|
||||
...priest,
|
||||
status: "attacking",
|
||||
resource: 10_000,
|
||||
maxResource: 10_000,
|
||||
resourcePools: { ...priest.resourcePools, mana: 10_000 },
|
||||
activeCast: {
|
||||
abilityId: spell.id,
|
||||
school: "frost",
|
||||
mode: "cast",
|
||||
startedAt: 500,
|
||||
completesAt: 1_000,
|
||||
originalDurationMs: 500,
|
||||
pushbackHits: 0,
|
||||
origin: [0, 0, 0],
|
||||
targetId: "holy-blessing-nature-target",
|
||||
},
|
||||
activeCastTargetId: "holy-blessing-nature-target",
|
||||
}] });
|
||||
registerPartyRuntimePosition(priest.id, [0, 0, 0]);
|
||||
updatePartyRuntimeTargetVisibility(priest.id, "holy-blessing-nature-target", true);
|
||||
usePartyStore.getState().setCommand("attack");
|
||||
useCombatStore.getState().synchronizeActors();
|
||||
|
||||
const beforeCastAuras = useCombatStore.getState().auras.filter((aura) => aura.targetId === priest.id);
|
||||
expect(beforeCastAuras.some((aura) => aura.definition.utilityTags?.includes(ROM_PRIEST_HOLY_BLESSING_TAG)))
|
||||
.toBe(false);
|
||||
advanceDungeonPartyCombat(1_000);
|
||||
|
||||
const state = useCombatStore.getState();
|
||||
const companionAura = state.auras.filter((aura) => aura.targetId === priest.id);
|
||||
expect(companionAura.some((aura) => aura.definition.utilityTags?.includes(ROM_PRIEST_HOLY_BLESSING_TAG)))
|
||||
.toBe(true);
|
||||
const base = deriveCharacterStats(
|
||||
priest.classId, priest.level, priest.gearStats, priest.raceId, {}, priest.secondaryClassId,
|
||||
);
|
||||
const bonus = romPriestHolyBlessingStats(base, companionAura).spellPowerBonus;
|
||||
const expectedAmount = equipmentAdjustedCombatAmount(spellEffect, 80, priest.gearStats, "rom-priest", spell, bonus);
|
||||
const unblessedAmount = equipmentAdjustedCombatAmount(spellEffect, 80, priest.gearStats, "rom-priest", spell);
|
||||
expect(bonus).toBeGreaterThan(0);
|
||||
expect(expectedAmount).toBeGreaterThan(unblessedAmount);
|
||||
const damage = state.combatEvents.find((event) => event.kind === "damage"
|
||||
&& event.sourceActorId === priest.id && event.abilityId === spell.id);
|
||||
expect(damage).toBeDefined();
|
||||
expect(damage?.rawAmount).toBe(expectedAmount);
|
||||
|
||||
const holy = damageWithSchool("holy-blessing-holy-target", priest.id, "holy", 5_000);
|
||||
const nature = damageWithSchool("holy-blessing-nature-target", priest.id, "nature", 6_000);
|
||||
expect(holy).toBe(2_009);
|
||||
expect(nature).toBe(1_000);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user