import { describe, expect, it } from "vitest"; import { applyAura, expireAuras, resolveDamageValue, resolveStatValue } from "./combatAuras"; import { ENEMY_STANCE_SOURCE_PINS, enemyStanceContract, removeEnemyStanceAura, supportedEnemyStanceAuraDefinition, } from "./enemyStances"; describe("pinned enemy warrior stance contracts", () => { it("pins both client profiles and preserves the direct form, duration, and no-restriction rows", () => { expect(ENEMY_STANCE_SOURCE_PINS.ascension.spellDbcSha256) .toBe("2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce"); expect(ENEMY_STANCE_SOURCE_PINS.epoch.spellDbcSha256) .toBe("d5cce1a83550dcfa9eb2f0251dbb11fd24c272534b2b1a9b230924a44d817ab3"); expect(ENEMY_STANCE_SOURCE_PINS.epoch.durationDbcSha256) .toBe("eeae44ef0185924f3d6ec57ab2701c66566db86e51ab0bae017a9449126eb3a0"); for (const profile of ["ascension", "epoch"] as const) { expect(enemyStanceContract(7164, profile)).toMatchObject({ name: "Defensive Stance", form: 18, durationMs: 180_000, target: "self", signature: { attributes0: 327_696, dispel: 0, durationIndex: 25, durationMs: 180_000, rangeIndex: 1, schoolMask: 1, damageClass: 0, stackAmount: 0, stanceMask: [0, 0], stanceExcludeMask: [0, 0], equippedItemClass: -1, equippedItemSubclassMask: 0, equippedItemInventoryMask: 0, effects: [{ effectType: 6, auraType: 36, basePoints: 0, implicitTargetA: 1, implicitTargetB: 0, radiusIndex: 0, radius: 0, miscValue: 18, triggerSpellId: 0 }], }, }); expect(enemyStanceContract(7165, profile)).toMatchObject({ name: "Battle Stance", form: 17, durationMs: null, target: "self", signature: { attributes0: 327_696, durationIndex: 21, durationMs: -1, damageClass: 2, stanceMask: [0, 0], stanceExcludeMask: [0, 0], effects: [{ effectType: 6, auraType: 36, basePoints: 0, miscValue: 17, triggerSpellId: 0 }], }, }); } expect(enemyStanceContract(99999, "epoch")).toBeUndefined(); }); it("uses the server-linked child passives and applies only supported numeric effects", () => { const ascDefensive = enemyStanceContract(7164, "ascension")!; const epochDefensive = enemyStanceContract(7164, "epoch")!; const ascBattle = enemyStanceContract(7165, "ascension")!; const epochBattle = enemyStanceContract(7165, "epoch")!; expect(ascDefensive).toMatchObject({ childPassiveSpellId: 7376, childPassiveScalars: { attributes0: 327_888, dispel: 0, durationIndex: 0, durationMs: 0, rangeIndex: 1, schoolMask: 1, damageClass: 0, stackAmount: 0, stanceMask: [0, 0], stanceExcludeMask: [0, 0], equippedItemClass: -1, equippedItemSubclassMask: 0, equippedItemInventoryMask: 0, }, childPassiveEffects: [ { effectType: 6, auraType: 87, basePoints: -10, miscValue: 127, triggerSpellId: 0 }, { effectType: 6, auraType: 79, basePoints: -5, miscValue: 127, triggerSpellId: 0 }, { effectType: 6, auraType: 4, basePoints: 42, miscValue: 127, triggerSpellId: 0 }, ], modifiers: [ { kind: "damage", direction: "taken", value: -0.10, multiplicative: true }, { kind: "damage", direction: "dealt", value: -0.05, multiplicative: true }, ], unsupportedEffects: [{ auraType: 4, basePoints: 42 }], }); expect(epochDefensive.childPassiveEffects[2]).toMatchObject({ auraType: 10, basePoints: 45 }); expect(epochDefensive.modifiers).toContainEqual({ kind: "stat", stat: "threat", operation: "percent", value: 0.45, multiplicative: true, }); expect(ascBattle).toMatchObject({ childPassiveSpellId: 21156, childPassiveScalars: { attributes0: 327_888, durationIndex: 0, rangeIndex: 1, schoolMask: 1, damageClass: 0, stackAmount: 0 }, childPassiveEffects: [{ auraType: 10, basePoints: 0 }, { auraType: 280, basePoints: 0 }], modifiers: [], unsupportedEffects: [], }); expect(epochBattle).toMatchObject({ childPassiveSpellId: 21156, childPassiveScalars: { attributes0: 327_888, durationIndex: 0, rangeIndex: 1, schoolMask: 1, damageClass: 0, stackAmount: 0 }, childPassiveEffects: [{ auraType: 10, basePoints: -20, miscValue: 127 }], modifiers: [{ kind: "stat", stat: "threat", operation: "percent", value: -0.20, multiplicative: true }], unsupportedEffects: [], }); const definition = supportedEnemyStanceAuraDefinition(ascDefensive); const active = applyAura([], { definition, sourceId: "mob", targetId: "mob", now: 0 }).auras; expect(resolveDamageValue(100, active, { direction: "taken", school: "fire", attackKind: "spell" })).toBe(90); expect(resolveDamageValue(100, active, { direction: "dealt", school: "physical", attackKind: "melee" })).toBe(95); const combinedMitigation = applyAura(active, { definition: { id: "another-source-damage-mitigation", name: "Another sourced mitigation", disposition: "buff", durationMs: null, modifiers: [{ kind: "damage", direction: "taken", operation: "percent", value: 0.20, multiplicative: true }], }, sourceId: "second-source", targetId: "mob", now: 1, }).auras; expect(resolveDamageValue(100, combinedMitigation, { direction: "taken", school: "physical", attackKind: "melee" })) .toBeCloseTo(108); expect(resolveStatValue(1, applyAura([], { definition: supportedEnemyStanceAuraDefinition(epochDefensive), sourceId: "epoch-mob", targetId: "epoch-mob", now: 0, }).auras, "threat")).toBeCloseTo(1.45); expect(resolveStatValue(1, applyAura([], { definition: supportedEnemyStanceAuraDefinition(epochBattle), sourceId: "epoch-mob", targetId: "epoch-mob", now: 0, }).auras, "threat")).toBeCloseTo(0.80); }); it("expires Defensive Stance, switches exclusively into metadata-only Battle Stance, then removes it on reset", () => { const defensive = supportedEnemyStanceAuraDefinition(enemyStanceContract(7164, "ascension")!); const battle = supportedEnemyStanceAuraDefinition(enemyStanceContract(7165, "ascension")!); const first = applyAura([], { definition: defensive, sourceId: "mob", targetId: "mob", now: 10 }).auras; expect(expireAuras(first, 180_009).active).toHaveLength(1); expect(expireAuras(first, 180_010)).toMatchObject({ active: [], expired: first }); const switchedResult = applyAura(first, { definition: battle, sourceId: "mob", targetId: "mob", now: 20 }); const switched = switchedResult.auras; expect(defensive.exclusiveGroup).toBe("enemy-warrior-stance"); expect(battle.exclusiveGroup).toBe("enemy-warrior-stance"); expect(switched).toHaveLength(1); expect(switched[0]).toMatchObject({ definition: { id: "enemy-source-spell-7165", modifiers: [], utilityTags: ["enemy-warrior-stance", "enemy-warrior-form:17", "enemy-passive-spell:21156"], }, appliedAt: 20, expiresAt: null, }); expect(switchedResult.replaced?.definition.id).toBe("enemy-source-spell-7164"); expect(resolveDamageValue(100, switched, { direction: "taken", school: "physical", attackKind: "melee" })).toBe(100); expect(removeEnemyStanceAura(switched, "another-mob")).toEqual(switched); expect(removeEnemyStanceAura(switched, "mob")).toEqual([]); }); });