import { describe, expect, it } from "vitest"; import { applyAura, dispelAuras, resolveDamageValue } from "./combatAuras"; import { enemyDisarmBlocksCombatChannel, enemyDisarmCanApplyToTarget, enemyDisarmInvalidatesAbilityRequirement, enemyDisarmWeaponChannels, enemyWeaponDebuffAuraDefinition, enemyWeaponDebuffContract, } from "./enemyWeaponDebuffs"; describe("pinned enemy weapon debuffs", () => { it("pins Disarm's main-hand/ranged rows and per-profile hit and duration contract", () => { const ascension = enemyWeaponDebuffContract(6713, "ascension")!; const epoch = enemyWeaponDebuffContract(6713, "epoch")!; expect(ascension).toMatchObject({ spellMechanic: 3, signature: { schoolMask: 1, damageClass: 2, durationMs: 5_000, effects: [ { effectType: 6, auraType: 67, basePoints: 0, implicitTargetA: 6, miscValue: 0 }, { effectType: 6, auraType: 278, basePoints: 1, implicitTargetA: 6, miscValue: 0 }, ], }, durationMs: 5_000, dispelType: 0, stackAmount: 0, casterWeaponRequirement: { itemClass: -1, subclassMask: 0, inventoryMask: 0 }, applicationGate: "landed-melee-hit", weaponChannels: ["main-hand", "ranged"], }); expect(epoch.signature.effects).toEqual([ { effectType: 6, auraType: 67, basePoints: 0, mechanic: 0, implicitTargetA: 6, implicitTargetB: 0, radius: 0, miscValue: 0, periodMs: 0 }, ]); expect(enemyDisarmWeaponChannels("ascension")).toEqual(["main-hand", "ranged"]); expect(enemyDisarmWeaponChannels("epoch")).toEqual(["main-hand"]); expect(enemyWeaponDebuffContract(999_999, "ascension")).toBeUndefined(); }); it("requires an affected target weapon and leaves off-hand and casting channels alone", () => { const offHandOnly = { mainHand: false, offHand: true, ranged: false }; expect(enemyDisarmCanApplyToTarget("ascension", offHandOnly)).toBe(false); expect(enemyDisarmCanApplyToTarget("epoch", offHandOnly)).toBe(false); expect(enemyDisarmCanApplyToTarget("ascension", { ...offHandOnly, ranged: true })).toBe(true); expect(enemyDisarmCanApplyToTarget("epoch", { ...offHandOnly, ranged: true })).toBe(false); expect(enemyDisarmCanApplyToTarget("ascension", { mainHand: true, offHand: false, ranged: false, feralForm: true })).toBe(false); expect(enemyDisarmBlocksCombatChannel("ascension", "main-hand")).toBe(true); expect(enemyDisarmBlocksCombatChannel("ascension", "ranged")).toBe(true); expect(enemyDisarmBlocksCombatChannel("ascension", "off-hand")).toBe(false); expect(enemyDisarmBlocksCombatChannel("ascension", "spell-cast")).toBe(false); expect(enemyDisarmBlocksCombatChannel("epoch", "ranged")).toBe(false); }); it("blocks an explicit weapon requirement only when Disarm disables every matching equipped slot", () => { const daggerRequirement = { equippedItemClass: 2, equippedItemSubclassMask: 1 << 15 }; const mainHandDagger = [{ channel: "main-hand" as const, itemClass: 2, subclass: 15 }]; const mainHandAndOffHandDaggers = [ ...mainHandDagger, { channel: "off-hand" as const, itemClass: 2, subclass: 15 }, ]; expect(enemyDisarmInvalidatesAbilityRequirement("ascension", daggerRequirement, mainHandDagger)).toBe(true); expect(enemyDisarmInvalidatesAbilityRequirement("epoch", daggerRequirement, mainHandDagger)).toBe(true); expect(enemyDisarmInvalidatesAbilityRequirement("ascension", daggerRequirement, mainHandAndOffHandDaggers)).toBe(false); expect(enemyDisarmInvalidatesAbilityRequirement("ascension", { ...daggerRequirement, equippedItemSubclassMask: 1 << 4 }, mainHandDagger)).toBe(false); expect(enemyDisarmInvalidatesAbilityRequirement("ascension", { equippedItemClass: -1, equippedItemSubclassMask: 0 }, mainHandDagger)).toBe(false); }); it("pins Infected Wound as flat physical damage taken, pre-mitigation, disease dispel, and refresh", () => { for (const profile of ["ascension", "epoch"] as const) { const contract = enemyWeaponDebuffContract(17230, profile)!; expect(contract).toMatchObject({ signature: { schoolMask: 8, damageClass: 0, durationMs: 300_000, effects: [{ effectType: 6, auraType: 14, basePoints: 6, implicitTargetA: 6, miscValue: 1 }], }, durationMs: 300_000, dispelType: 3, dispelCategory: "disease", stackAmount: 0, casterWeaponRequirement: { itemClass: -1, subclassMask: 0, inventoryMask: 0 }, applicationGate: "aura-only-no-miss-roll", modifiers: [{ kind: "damage", direction: "taken", school: "physical", operation: "flat", value: 6, phase: "pre-mitigation" }], }); } const definition = enemyWeaponDebuffAuraDefinition(enemyWeaponDebuffContract(17230, "ascension")!); let auras = applyAura([], { definition, sourceId: "infected-caster-a", targetId: "player", now: 100 }).auras; auras = applyAura(auras, { definition, sourceId: "infected-caster-b", targetId: "player", now: 1_000 }).auras; expect(auras).toHaveLength(1); expect(auras[0]).toMatchObject({ sourceId: "infected-caster-b", appliedAt: 1_000, expiresAt: 301_000 }); expect(resolveDamageValue(100, auras, { direction: "taken", school: "physical", attackKind: "melee", phase: "pre-mitigation", })).toBe(106); expect(resolveDamageValue(100, auras, { direction: "taken", school: "fire", attackKind: "spell", phase: "pre-mitigation", })).toBe(100); expect(resolveDamageValue(100, auras, { direction: "taken", school: "physical", attackKind: "melee", })).toBe(100); expect(dispelAuras(auras, { relationship: "friendly", categories: ["poison"] }).removed).toHaveLength(0); const diseaseDispel = dispelAuras(auras, { relationship: "friendly", categories: ["disease"] }); expect(diseaseDispel.removed).toHaveLength(1); expect(diseaseDispel.auras).toHaveLength(0); }); });