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,202 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { abilitiesForCharacter, learnedAbilityForBuild } from "./abilityCatalog";
|
||||
import { resolveDamageValue as resolveAuraDamageValue } from "./combatAuras";
|
||||
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
|
||||
import { PLAYER_AGGRO_ID } from "./aggro";
|
||||
import { useCombatStore } from "./combatStore";
|
||||
import { clearPartyRuntimeRegistry, registerPartyRuntimePosition } from "./partyRuntimeRegistry";
|
||||
import { advanceDungeonPartyCombat, resetPartyRuntimeClock } from "./partyRuntime";
|
||||
import { createConfiguredPartyMember, usePartyStore } from "./partyStore";
|
||||
import { EMPTY_ITEM_STATS, type WeaponStats } from "./itemStats";
|
||||
import type { InventoryItem } from "./lootTypes";
|
||||
|
||||
const OFFHAND_ID = "coa-gods-sword-test-offhand";
|
||||
const OFFHAND: WeaponStats = {
|
||||
damageMin: 100,
|
||||
damageMax: 300,
|
||||
damageSchool: "physical",
|
||||
speedMs: 2_000,
|
||||
};
|
||||
|
||||
function offhandItem(instanceId = OFFHAND_ID): InventoryItem {
|
||||
return {
|
||||
instanceId,
|
||||
itemId: 1,
|
||||
itemKey: instanceId,
|
||||
name: "Test Off-hand Dagger",
|
||||
quality: "uncommon",
|
||||
inventorySlot: "off-hand",
|
||||
armorType: null,
|
||||
weaponType: "mace",
|
||||
itemLevel: 1,
|
||||
sourceItemLevel: 1,
|
||||
stats: { ...EMPTY_ITEM_STATS, meleeWeapon: OFFHAND, hitRating: 1_000_000 },
|
||||
quantity: 1,
|
||||
sourceBossKey: "test",
|
||||
sourceBossName: "Test",
|
||||
acquiredAt: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function registerTarget(id: string): void {
|
||||
useCombatStore.getState().registerMob(id, {
|
||||
name: id,
|
||||
level: 1,
|
||||
maxHealth: 1_000_000,
|
||||
xpReward: 0,
|
||||
});
|
||||
setMobPosition(id, [2, 0, 0]);
|
||||
useCombatStore.getState().selectMob(id);
|
||||
}
|
||||
|
||||
function expectedLightRiderAmount(actorId: string): number {
|
||||
const auras = useCombatStore.getState().auras.filter((aura) => aura.targetId === actorId);
|
||||
return Math.round(resolveAuraDamageValue(350, auras, {
|
||||
direction: "dealt",
|
||||
school: "holy",
|
||||
attackKind: "spell",
|
||||
}));
|
||||
}
|
||||
|
||||
describe("current CoA Knight/Rogue God's Sword runtime", () => {
|
||||
beforeEach(() => {
|
||||
clearMobRuntimeRegistry();
|
||||
clearPartyRuntimeRegistry();
|
||||
resetPartyRuntimeClock();
|
||||
useCombatStore.getState().initializeCharacter({
|
||||
classId: "rom-knight",
|
||||
secondaryClassId: "rom-rogue",
|
||||
raceId: "rom-human",
|
||||
level: 80,
|
||||
xp: 0,
|
||||
});
|
||||
usePartyStore.getState().initializeParty("coa-gods-sword-runtime", 80, useCombatStore.getState().health);
|
||||
});
|
||||
|
||||
it("adds one separate 350% off-hand-DPS Light hit to a landed player physical ability", () => {
|
||||
const item = offhandItem();
|
||||
useCombatStore.getState().initializeCharacter({
|
||||
classId: "rom-knight",
|
||||
secondaryClassId: "rom-rogue",
|
||||
raceId: "rom-human",
|
||||
level: 80,
|
||||
xp: 0,
|
||||
inventory: [item],
|
||||
equipment: { player: { "off-hand": item.instanceId } },
|
||||
});
|
||||
registerTarget("coa-gods-sword-player-target");
|
||||
|
||||
const ability = useCombatStore.getState().abilities.find((candidate) => candidate.dbcSpellId === 490148)!;
|
||||
expect(useCombatStore.getState().abilities.find((candidate) => candidate.dbcSpellId === 491621))
|
||||
.toMatchObject({ passive: true, unlockLevel: 15 });
|
||||
expect(useCombatStore.getState().castAbility(ability.id, undefined, 1_000)).toMatchObject({ ok: true });
|
||||
|
||||
const events = useCombatStore.getState().combatEvents.filter((event) => (
|
||||
event.kind === "damage"
|
||||
&& event.sourceActorId === PLAYER_AGGRO_ID
|
||||
&& event.targetActorId === "coa-gods-sword-player-target"
|
||||
&& event.abilityId === ability.id
|
||||
));
|
||||
expect(events.some((event) => event.school === "holy" && event.rawAmount !== 350
|
||||
&& event.effectiveAmount > 0)).toBe(true);
|
||||
expect(events.filter((event) => event.school === "holy"
|
||||
&& event.rawAmount === expectedLightRiderAmount(PLAYER_AGGRO_ID)))
|
||||
.toHaveLength(1);
|
||||
});
|
||||
|
||||
it("does not add the CoA rider before the passive is learned or without an off-hand weapon", () => {
|
||||
const simulate = (level: number, equipOffhand: boolean) => {
|
||||
const item = offhandItem(`coa-gods-sword-gate-${level}-${equipOffhand}`);
|
||||
useCombatStore.getState().initializeCharacter({
|
||||
classId: "rom-knight",
|
||||
secondaryClassId: "rom-rogue",
|
||||
raceId: "rom-human",
|
||||
level,
|
||||
xp: 0,
|
||||
...(equipOffhand ? {
|
||||
inventory: [item],
|
||||
equipment: { player: { "off-hand": item.instanceId } },
|
||||
} : {}),
|
||||
});
|
||||
const targetId = `coa-gods-sword-gate-target-${level}-${equipOffhand}`;
|
||||
registerTarget(targetId);
|
||||
const ability = useCombatStore.getState().abilities.find((candidate) => candidate.dbcSpellId === 490148)!;
|
||||
useCombatStore.getState().castAbility(ability.id, undefined, 1_000);
|
||||
return useCombatStore.getState().combatEvents.filter((event) => (
|
||||
event.kind === "damage"
|
||||
&& event.targetActorId === targetId
|
||||
&& event.abilityId === ability.id
|
||||
&& event.school === "holy"
|
||||
&& event.rawAmount === 350
|
||||
));
|
||||
};
|
||||
|
||||
expect(simulate(14, true)).toHaveLength(0);
|
||||
expect(simulate(80, false)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("adds the same landed-hit rider for a generated Knight/Rogue companion", () => {
|
||||
useCombatStore.getState().initializeCharacter({ classId: "rom-mage", level: 80, xp: 0 });
|
||||
const seed = "coa-gods-sword-party";
|
||||
const companion = createConfiguredPartyMember({
|
||||
name: "Knight/Rogue",
|
||||
classId: "rom-knight",
|
||||
secondaryClassId: "rom-rogue",
|
||||
raceId: "rom-human",
|
||||
specialization: "Knight/Rogue",
|
||||
role: "damage",
|
||||
}, 80, 0, seed);
|
||||
const sourceAbility = abilitiesForCharacter("rom-knight", "rom-rogue")
|
||||
.find((candidate) => candidate.dbcSpellId === 490148)!;
|
||||
const ability = learnedAbilityForBuild(sourceAbility, 80, companion.talentRanks)!;
|
||||
const targetId = "coa-gods-sword-companion-target";
|
||||
const item = {
|
||||
...offhandItem(`${companion.id}:${OFFHAND_ID}`),
|
||||
};
|
||||
|
||||
usePartyStore.getState().initializeParty(seed, 80, useCombatStore.getState().health, "damage", 2, "rom");
|
||||
usePartyStore.setState({
|
||||
members: [{
|
||||
...companion,
|
||||
gearStats: { ...EMPTY_ITEM_STATS, hitRating: 1_000_000 },
|
||||
globalCooldownEndsAt: 0,
|
||||
nextActionAt: 0,
|
||||
activeCast: {
|
||||
abilityId: ability.id,
|
||||
school: "physical",
|
||||
mode: "cast",
|
||||
startedAt: 1_000,
|
||||
completesAt: 1_000,
|
||||
originalDurationMs: 0,
|
||||
pushbackHits: 0,
|
||||
origin: [0, 0, 0],
|
||||
targetId,
|
||||
},
|
||||
activeCastTargetId: targetId,
|
||||
status: "attacking",
|
||||
}],
|
||||
command: "attack",
|
||||
activeMobId: targetId,
|
||||
});
|
||||
useCombatStore.setState((state) => ({
|
||||
inventory: [...state.inventory, item],
|
||||
equipment: { ...state.equipment, [companion.id]: { "off-hand": item.instanceId } },
|
||||
}));
|
||||
registerPartyRuntimePosition(companion.id, [0, 0, 0]);
|
||||
useCombatStore.getState().synchronizeActors();
|
||||
registerTarget(targetId);
|
||||
|
||||
advanceDungeonPartyCombat(1_000);
|
||||
const events = useCombatStore.getState().combatEvents.filter((event) => (
|
||||
event.kind === "damage"
|
||||
&& event.sourceActorId === companion.id
|
||||
&& event.targetActorId === targetId
|
||||
&& event.abilityId === ability.id
|
||||
));
|
||||
expect(events.some((event) => event.school === "holy" && event.rawAmount !== 350
|
||||
&& event.effectiveAmount > 0)).toBe(true);
|
||||
expect(events.filter((event) => event.school === "holy"
|
||||
&& event.rawAmount === expectedLightRiderAmount(companion.id)))
|
||||
.toHaveLength(1);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user