forked from phenom/healer-man
Release Healer Man 0.1.22
This commit is contained in:
1 parent
f6f2375145
commit
7f6001723a
144 files changed
+54107
-690
No files matched your search
@@ -250,6 +250,168 @@ describe("server-backed enemy ability runtime", () => {
|
||||
}));
|
||||
});
|
||||
|
||||
it("resolves compound enemy damage and control against the same target", () => {
|
||||
useCombatStore.getState().registerMob("compound-hammer", {
|
||||
name: "Compound Hammer",
|
||||
maxHealth: 1_000,
|
||||
attacks: [{
|
||||
id: "hammer-pair",
|
||||
name: "Hammer Pair",
|
||||
delivery: "projectile",
|
||||
target: "primary",
|
||||
school: "holy",
|
||||
animation: "cast",
|
||||
castTimeMs: 0,
|
||||
range: 20,
|
||||
cooldownMs: 25_000,
|
||||
initialCooldownMs: [0, 0],
|
||||
repeatCooldownMs: [25_000, 25_000],
|
||||
damageMultiplier: 1.3,
|
||||
effect: {
|
||||
kind: "control",
|
||||
mechanic: "stun",
|
||||
durationMs: 2_500,
|
||||
damageMultiplier: 1.3,
|
||||
},
|
||||
}],
|
||||
});
|
||||
setMobPosition("compound-hammer", [2, 0, 0]);
|
||||
useCombatStore.getState().damageMob("compound-hammer", 1, 1_000);
|
||||
const healthBefore = useCombatStore.getState().health;
|
||||
|
||||
useCombatStore.getState().advanceMobCombat(1_000, [0, 0, 0]);
|
||||
|
||||
expect(useCombatStore.getState().health).toBeLessThan(healthBefore);
|
||||
expect(useCombatStore.getState()).toMatchObject({
|
||||
controlMechanic: "stun",
|
||||
controlledUntil: 3_500,
|
||||
});
|
||||
expect(useCombatStore.getState().auras).toContainEqual(expect.objectContaining({
|
||||
sourceId: "compound-hammer",
|
||||
targetId: PLAYER_AGGRO_ID,
|
||||
expiresAt: 3_500,
|
||||
}));
|
||||
});
|
||||
|
||||
it("arms, limits, and consumes a next-melee critical proc only from main-hand autos", () => {
|
||||
useCombatStore.getState().registerMob("melee-proc-boss-1", {
|
||||
name: "Melee Proc Boss",
|
||||
level: 20,
|
||||
maxHealth: 1_000,
|
||||
damageMultiplier: 0.05,
|
||||
attacks: [
|
||||
{
|
||||
id: "vengeance-driver",
|
||||
name: "Vengeance",
|
||||
delivery: "area",
|
||||
target: "self",
|
||||
school: "holy",
|
||||
animation: "cast",
|
||||
castTimeMs: 0,
|
||||
range: 0,
|
||||
cooldownMs: 1,
|
||||
initialCooldownMs: [0, 0],
|
||||
repeatCooldownMs: [1, 1],
|
||||
maximumCasts: 1,
|
||||
damageMultiplier: 0,
|
||||
effect: {
|
||||
kind: "aura",
|
||||
aura: "vengeance",
|
||||
durationMs: 0,
|
||||
meleeAutoCriticalProc: {
|
||||
chance: 1,
|
||||
triggeredAura: "vengeance-next-melee-critical",
|
||||
durationMs: 6_000,
|
||||
criticalChancePercent: 100,
|
||||
charges: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "melee-special",
|
||||
name: "Melee Special",
|
||||
delivery: "melee",
|
||||
target: "primary",
|
||||
school: "physical",
|
||||
animation: "attack",
|
||||
castTimeMs: 0,
|
||||
range: 5,
|
||||
cooldownMs: 1_000,
|
||||
initialCooldownMs: [500, 500],
|
||||
repeatCooldownMs: [1_000, 1_000],
|
||||
damageMultiplier: 1,
|
||||
},
|
||||
{
|
||||
id: "basic-attack",
|
||||
name: "Basic Attack",
|
||||
delivery: "melee",
|
||||
target: "primary",
|
||||
school: "physical",
|
||||
animation: "attack",
|
||||
castTimeMs: 0,
|
||||
range: 4.5,
|
||||
cooldownMs: 2_000,
|
||||
initialCooldownMs: [1_000, 1_000],
|
||||
repeatCooldownMs: [2_000, 2_000],
|
||||
damageMultiplier: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
setMobPosition("melee-proc-boss-1", [2, 0, 0]);
|
||||
useCombatStore.getState().damageMob("melee-proc-boss-1", 1, 1_000);
|
||||
|
||||
useCombatStore.getState().advanceMobCombat(1_000, [0, 0, 0]);
|
||||
useCombatStore.getState().advanceMobCombat(1_500, [0, 0, 0]);
|
||||
expect(useCombatStore.getState().mobs["melee-proc-boss-1"].auras.map((aura) => aura.id))
|
||||
.toEqual(["vengeance"]);
|
||||
|
||||
useCombatStore.getState().advanceMobCombat(2_000, [0, 0, 0]);
|
||||
expect(useCombatStore.getState().lastCombatResult?.landed).toBe(true);
|
||||
expect(useCombatStore.getState().lastCombatResult?.attackTable.criticalPercent).toBe(5);
|
||||
expect(useCombatStore.getState().mobs["melee-proc-boss-1"].auras).toContainEqual({
|
||||
id: "vengeance-next-melee-critical",
|
||||
sourceAbilityId: "vengeance-driver",
|
||||
endsAt: 8_000,
|
||||
nextMeleeCriticalChancePercent: 100,
|
||||
charges: 1,
|
||||
});
|
||||
|
||||
useCombatStore.getState().advanceMobCombat(2_500, [0, 0, 0]);
|
||||
expect(useCombatStore.getState().mobs["melee-proc-boss-1"].auras).toContainEqual(
|
||||
expect.objectContaining({ id: "vengeance-next-melee-critical", endsAt: 8_000, charges: 1 }),
|
||||
);
|
||||
|
||||
useCombatStore.getState().advanceMobCombat(4_000, [0, 0, 0]);
|
||||
expect(useCombatStore.getState().lastCombatResult).toMatchObject({
|
||||
outcome: "crit",
|
||||
critical: true,
|
||||
landed: true,
|
||||
});
|
||||
expect(useCombatStore.getState().lastCombatResult?.damageBeforeMitigation)
|
||||
.toBe((useCombatStore.getState().lastCombatResult?.rawDamage ?? 0) * 2);
|
||||
expect(useCombatStore.getState().mobs["melee-proc-boss-1"].auras).toContainEqual(
|
||||
expect.objectContaining({ id: "vengeance-next-melee-critical", endsAt: 10_000, charges: 1 }),
|
||||
);
|
||||
|
||||
useCombatStore.setState((state) => ({
|
||||
mobs: {
|
||||
...state.mobs,
|
||||
"melee-proc-boss-1": {
|
||||
...state.mobs["melee-proc-boss-1"],
|
||||
auras: state.mobs["melee-proc-boss-1"].auras.map((aura) => (
|
||||
aura.id === "vengeance" ? { ...aura, meleeAutoCriticalProc: undefined } : aura
|
||||
)),
|
||||
},
|
||||
},
|
||||
}));
|
||||
useCombatStore.getState().advanceMobCombat(5_000, [0, 0, 0]);
|
||||
useCombatStore.getState().advanceMobCombat(6_000, [0, 0, 0]);
|
||||
expect(useCombatStore.getState().lastCombatResult?.critical).toBe(true);
|
||||
expect(useCombatStore.getState().mobs["melee-proc-boss-1"].auras.some(
|
||||
(aura) => aura.id === "vengeance-next-melee-critical",
|
||||
)).toBe(false);
|
||||
});
|
||||
|
||||
it("honors encounter-state conditions before selecting an ability", () => {
|
||||
useWailingEncounterStore.getState().reset();
|
||||
useCombatStore.getState().registerMob("event-caster", {
|
||||
|
||||
Reference in new issue
Block a user