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,6 +1,6 @@
|
||||
import { beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import type { AbilityEffect } from "./abilityCatalog";
|
||||
import { abilitiesForCharacter, preloadAbilityCatalogsForClasses } from "./abilityCatalog";
|
||||
import { abilitiesForCharacter, learnedAbilityForBuild, preloadAbilityCatalogsForClasses } from "./abilityCatalog";
|
||||
import { cooldownResetCandidates } from "./cooldownReset";
|
||||
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
|
||||
import {
|
||||
@@ -194,18 +194,179 @@ describe("RuneWaker Warlock runtime", () => {
|
||||
))).toBe(false);
|
||||
});
|
||||
|
||||
it("converts the RoM Warlock/Warrior Rage pool to psi at 35:1", () => {
|
||||
it("converts a fixed 75 Rage cost into six Psi for Mind Transference", () => {
|
||||
prepareWarlock("rom-warrior");
|
||||
useCombatStore.setState((state) => ({
|
||||
resourcePools: { ...state.resourcePools, rage: 70, psi: 1 },
|
||||
resourcePools: { ...state.resourcePools, rage: 100, psi: 1 },
|
||||
}));
|
||||
|
||||
const mindTransference = ability(498642);
|
||||
expect(mindTransference.costs).toEqual([]);
|
||||
expect(mindTransference.costs).toEqual([{ resource: "rage", amount: 75, percentage: false }]);
|
||||
expect(mindTransference.cooldownMs).toBe(1_000);
|
||||
expect(mindTransference.effects).toEqual([{ kind: "resource", resource: "psi", amount: 6 }]);
|
||||
expect(useCombatStore.getState().castAbility(mindTransference.id, { now: 1_000 }).ok).toBe(true);
|
||||
|
||||
expect(useCombatStore.getState().resourcePools.rage).toBe(0);
|
||||
expect(useCombatStore.getState().resourcePools.psi).toBe(3);
|
||||
expect(useCombatStore.getState().resourcePools.rage).toBe(25);
|
||||
expect(useCombatStore.getState().resourcePools.psi).toBe(6);
|
||||
});
|
||||
|
||||
it("uses current Warlock/Priest passive effects and pair upgrades", () => {
|
||||
const context = {
|
||||
sealStacks: 0,
|
||||
bleedCount: 0,
|
||||
charged: false,
|
||||
mainHandDagger: false,
|
||||
casterMaxHealth: 10_000,
|
||||
targetHealthPercent: 1,
|
||||
learnedPassiveSpellIds: [498633, 498643, 498648, 498668],
|
||||
} as const;
|
||||
const divineAssistance = ability(498668);
|
||||
expect(divineAssistance.description).toContain("magical damage and healing by 16%");
|
||||
expect(divineAssistance.effects).toContainEqual(expect.objectContaining({
|
||||
kind: "apply-aura",
|
||||
aura: expect.objectContaining({
|
||||
durationMs: null,
|
||||
modifiers: expect.arrayContaining([
|
||||
expect.objectContaining({ kind: "damage", direction: "dealt", school: "shadow", value: 0.16 }),
|
||||
expect.objectContaining({ kind: "healing", direction: "done", value: 0.16 }),
|
||||
]),
|
||||
}),
|
||||
}));
|
||||
|
||||
const healingFortune = romEffectsForCast(ability(497957), context)
|
||||
.find((effect) => effect.kind === "apply-aura");
|
||||
expect(healingFortune).toMatchObject({
|
||||
kind: "apply-aura",
|
||||
recipient: "caster",
|
||||
requiresLandedHit: true,
|
||||
aura: {
|
||||
durationMs: 20_000,
|
||||
modifiers: expect.arrayContaining([
|
||||
expect.objectContaining({ kind: "healing", direction: "done", value: 0.12 }),
|
||||
expect.objectContaining({ kind: "stat", stat: "wisdom", value: 0.12 }),
|
||||
]),
|
||||
},
|
||||
});
|
||||
|
||||
const pairAbilities = abilitiesForCharacter("rom-warlock", "rom-priest");
|
||||
const risingTide = pairAbilities.find((candidate) => candidate.dbcSpellId === 490256)!;
|
||||
expect(learnedAbilityForBuild(risingTide, 29, {})).toMatchObject({ castTimeMs: 2_000, cooldownMs: 0 });
|
||||
const upgradedRisingTide = learnedAbilityForBuild(risingTide, 30, {})!;
|
||||
expect(upgradedRisingTide).toMatchObject({ castMode: "instant", castTimeMs: 0, cooldownMs: 5_000 });
|
||||
expect(upgradedRisingTide.description).toContain("cannot redirect an ally-targeted cast");
|
||||
expect(romEffectsForCast(upgradedRisingTide, context)).toContainEqual({
|
||||
kind: "resource", resource: "psi", amount: 1,
|
||||
});
|
||||
expect(romEffectsForCast(upgradedRisingTide, context).find((effect) => (
|
||||
effect.kind === "apply-aura" && effect.requiresCriticalHit
|
||||
))).toBeDefined();
|
||||
|
||||
const warpCharge = pairAbilities.find((candidate) => candidate.dbcSpellId === 497958)!;
|
||||
expect(learnedAbilityForBuild(warpCharge, 14, {})?.target).toBe("hostile");
|
||||
const upgradedWarpCharge = learnedAbilityForBuild(warpCharge, 15, {})!;
|
||||
expect(upgradedWarpCharge.target).toBe("any");
|
||||
const friendlyEffects = romEffectsForCast(upgradedWarpCharge, {
|
||||
...context,
|
||||
selectedTargetRelationship: "friendly",
|
||||
});
|
||||
expect(friendlyEffects.some((effect) => effect.kind === "heal")).toBe(true);
|
||||
expect(friendlyEffects.some((effect) => effect.kind === "damage")).toBe(false);
|
||||
expect(romEffectsForCast(upgradedWarpCharge, {
|
||||
...context,
|
||||
selectedTargetRelationship: "hostile",
|
||||
}).some((effect) => effect.kind === "damage")).toBe(true);
|
||||
|
||||
expect(romEffectsForCast(ability(491147), context)).toContainEqual({
|
||||
kind: "resource", resource: "psi", amount: 1,
|
||||
});
|
||||
expect(ability(498633).description).toContain("12% Wisdom for 20 seconds");
|
||||
expect(ability(498648).description).toContain("Ring of Comfort's reset chance is not specified");
|
||||
});
|
||||
|
||||
it("applies Healing Fortune and Divine Assistance for the player and generated companion", () => {
|
||||
prepareWarlock("rom-priest");
|
||||
expect(useCombatStore.getState().auras.some((aura) => aura.sourceId === PLAYER_AURA_ENTITY_ID
|
||||
&& aura.targetId === PLAYER_AURA_ENTITY_ID
|
||||
&& aura.definition.id === "rom-warlock-divine-assistance-498668")).toBe(true);
|
||||
registerTarget();
|
||||
|
||||
const psychicArrows = ability(497957);
|
||||
expect(useCombatStore.getState().castAbility(psychicArrows.id, {
|
||||
targetActorId: TARGET_ID,
|
||||
now: 1_000,
|
||||
}).ok).toBe(true);
|
||||
finishCast(1_000);
|
||||
expect(useCombatStore.getState().auras.some((aura) => aura.sourceId === PLAYER_AURA_ENTITY_ID
|
||||
&& aura.targetId === PLAYER_AURA_ENTITY_ID
|
||||
&& aura.definition.id === "rom-warlock-healing-fortune-498633")).toBe(true);
|
||||
|
||||
useCombatStore.getState().initializeCharacter({ classId: "rom-priest", raceId: "rom-dwarf", level: 80 });
|
||||
usePartyStore.getState().initializeParty("rom-warlock-priest-companion", 80,
|
||||
useCombatStore.getState().health, "damage", 2, "rom");
|
||||
const companion = createConfiguredPartyMember({
|
||||
name: "Warlock/Priest Companion",
|
||||
classId: "rom-warlock",
|
||||
secondaryClassId: "rom-priest",
|
||||
raceId: "rom-dwarf",
|
||||
specialization: "Warlock",
|
||||
role: "damage",
|
||||
}, 80, 0, "rom-warlock-priest-companion");
|
||||
const pairAbilities = abilitiesForCharacter("rom-warlock", "rom-priest");
|
||||
usePartyStore.setState({
|
||||
command: "attack",
|
||||
members: [{
|
||||
...companion,
|
||||
cooldowns: Object.fromEntries(pairAbilities
|
||||
.filter((candidate) => candidate.dbcSpellId !== 497957)
|
||||
.map((candidate) => [candidate.id, 100_000])),
|
||||
resourcePools: { ...companion.resourcePools, focus: 100 },
|
||||
resource: 100,
|
||||
}],
|
||||
});
|
||||
useCombatStore.getState().synchronizeActors();
|
||||
registerPartyRuntimePosition(companion.id, [0, 0, 0]);
|
||||
registerTarget();
|
||||
useCombatStore.getState().damageMob(TARGET_ID, 1, 900);
|
||||
updatePartyRuntimeTargetVisibility(companion.id, TARGET_ID, true);
|
||||
|
||||
advanceDungeonPartyCombat(1_000);
|
||||
advanceDungeonPartyCombat(3_100);
|
||||
|
||||
expect(useCombatStore.getState().auras.some((aura) => aura.sourceId === companion.id
|
||||
&& aura.targetId === companion.id
|
||||
&& aura.definition.id === "rom-warlock-divine-assistance-498668")).toBe(true);
|
||||
expect(useCombatStore.getState().auras.some((aura) => aura.sourceId === companion.id
|
||||
&& aura.targetId === companion.id
|
||||
&& aura.definition.id === "rom-warlock-healing-fortune-498633")).toBe(true);
|
||||
});
|
||||
|
||||
it("turns friendly Warp Charge into a heal for a Warlock/Priest player", () => {
|
||||
prepareWarlock("rom-priest");
|
||||
useCombatStore.setState((state) => ({
|
||||
health: Math.max(1, state.maxHealth - 100),
|
||||
}));
|
||||
usePartyStore.getState().selectSelf();
|
||||
const warpCharge = abilitiesForCharacter("rom-warlock", "rom-priest")
|
||||
.find((candidate) => candidate.dbcSpellId === 497958)!;
|
||||
const result = useCombatStore.getState().castAbility(warpCharge.id, {
|
||||
now: 1_000,
|
||||
});
|
||||
expect(result.ok).toBe(true);
|
||||
expect(useCombatStore.getState().health).toBeGreaterThan(useCombatStore.getState().maxHealth - 100);
|
||||
});
|
||||
|
||||
it("applies the pair upgrade when the player casts Rising Tide", () => {
|
||||
prepareWarlock("rom-priest");
|
||||
registerTarget();
|
||||
const risingTide = abilitiesForCharacter("rom-warlock", "rom-priest")
|
||||
.find((candidate) => candidate.dbcSpellId === 490256)!;
|
||||
expect(useCombatStore.getState().castAbility(risingTide.id, {
|
||||
targetActorId: TARGET_ID,
|
||||
now: 1_000,
|
||||
}).ok).toBe(true);
|
||||
expect(useCombatStore.getState().activeCast).toBeNull();
|
||||
expect(useCombatStore.getState().resourcePools.psi).toBe(1);
|
||||
expect(useCombatStore.getState().cooldowns[risingTide.id]).toBe(6_000);
|
||||
});
|
||||
|
||||
it("consumes all Rage for Heart Fence and extends its duration by one second per 20 Rage", () => {
|
||||
|
||||
Reference in new issue
Block a user