/** * Independent Challenger Iteration 2 Adversarial Stress & Edge Case Probes * * Testing the 8 focal points: * 1. Warcry Party Dissemination (radius bounds, distance <= 30 vs > 30, multiple allies) * 2. Battle Orders Stamina Scaling (+35% base, +3%/lvl) * 3. Battle Command Radius (20 subtiles across slvl 1..50) * 4. War Cry Stun (stunDurationFrames scaling, stun state applied, damage dealt) * 5. Battle Cry Debuffs (defense reduction, damage reduction, duration scaling slvl 1..30) * 6. Boss & Champion Mental Curse Immunities (Howl, Grim Ward, Taunt across ranks 'boss', 'champion', 'unique', isBoss, isChampion, is_boss stat) * 7. Find Item & Find Potion Horking Probability (corpse consumption on failure, 'hork_failed' note, diminishing returns curve) */ import { describe, it, expect } from 'vitest' import { getSharedDataRegistry } from '../../../src/baker/mpq-archive-source.ts' import { UnitStatList } from '../../../src/server/engine/stat-list.ts' import { StateBus } from '../../../src/server/engine/state-bus.ts' import { evaluateSkill113c, executeSkill113c, registerSkillModule } from '../../../src/server/skills/registry.ts' import { skillModule as findPotionModule } from '../../../src/server/skills/impl/bar/skill-131-find-potion.ts' import { skillModule as findItemModule } from '../../../src/server/skills/impl/bar/skill-142-find-item.ts' import { skillModule as grimWardModule } from '../../../src/server/skills/impl/bar/skill-150-grim-ward.ts' import type { CombatUnitContext } from '../../../src/server/engine/combat-pipeline.ts' describe('Challenger Iteration 2 — Independent Adversarial Edge-Case Probes', () => { // -------------------------------------------------------------------------- // 1. Warcry Party Dissemination (Shout, Battle Orders, Battle Command) // -------------------------------------------------------------------------- describe('1. Warcry Party Dissemination Range & Filtering', () => { it('disseminates Shout (138), Battle Orders (149), and Battle Command (155) to allies within 30 units and excludes allies outside 30 units', async () => { const registry = await getSharedDataRegistry() const heroStats = new UnitStatList(registry) const heroBus = new StateBus(heroStats, registry) const hero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: heroBus } // Ally 1: close (dist = 10 <= 30) const ally1Stats = new UnitStatList(registry) const ally1Bus = new StateBus(ally1Stats, registry) const ally1: CombatUnitContext = { id: 'ally1', name: 'MercNear', statList: ally1Stats, stateBus: ally1Bus } // Ally 2: far (dist = 35 > 30) const ally2Stats = new UnitStatList(registry) const ally2Bus = new StateBus(ally2Stats, registry) const ally2: CombatUnitContext = { id: 'ally2', name: 'MercFar', statList: ally2Stats, stateBus: ally2Bus } // Ally 3: exact boundary (dist = 30) const ally3Stats = new UnitStatList(registry) const ally3Bus = new StateBus(ally3Stats, registry) const ally3: CombatUnitContext = { id: 'ally3', name: 'MercBound', statList: ally3Stats, stateBus: ally3Bus } const targetPositions = new Map([ ['hero', { x: 0, y: 0 }], ['ally1', { x: 6, y: 8 }], // hypot = 10 <= 30 -> receives ['ally2', { x: 28, y: 21 }], // hypot = 35 > 30 -> does NOT receive ['ally3', { x: 18, y: 24 }], // hypot = 30 <= 30 -> receives ]) for (const skillId of [138, 149, 155]) { const curHeroBus = new StateBus(heroStats, registry) const curAlly1Bus = new StateBus(ally1Stats, registry) const curAlly2Bus = new StateBus(ally2Stats, registry) const curAlly3Bus = new StateBus(ally3Stats, registry) const curHero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: curHeroBus } const curAlly1: CombatUnitContext = { id: 'ally1', name: 'MercNear', statList: ally1Stats, stateBus: curAlly1Bus } const curAlly2: CombatUnitContext = { id: 'ally2', name: 'MercFar', statList: ally2Stats, stateBus: curAlly2Bus } const curAlly3: CombatUnitContext = { id: 'ally3', name: 'MercBound', statList: ally3Stats, stateBus: curAlly3Bus } const skillRec = registry.getSkillById(skillId)! const evalRes = evaluateSkill113c({ registry, skill: skillRec, slvl: 5, blvl: 5, statList: heroStats }) const stateExpected = skillId === 138 ? 'shout' : skillId === 149 ? 'battleorders' : 'battlecommand' executeSkill113c({ registry, skill: skillRec, evalResult: evalRes, caster: curHero, targets: [], targetPositions, allies: [curAlly1, curAlly2, curAlly3], corpses: [], missileEngine: {} as any, auraScanner: {} as any, summonManager: {} as any, currentTick: 1, targetX: 0, targetY: 0, }) expect(curHeroBus.hasState(stateExpected)).toBe(true) expect(curAlly1Bus.hasState(stateExpected)).toBe(true) expect(curAlly2Bus.hasState(stateExpected)).toBe(false) expect(curAlly3Bus.hasState(stateExpected)).toBe(true) } }) }) // -------------------------------------------------------------------------- // 2. Battle Orders Stamina Scaling // -------------------------------------------------------------------------- describe('2. Battle Orders Stamina Scaling Across Levels', () => { it('verifies item_maxstamina_percent strictly matches item_maxhp_percent and item_maxmana_percent for slvl 1..50', async () => { const registry = await getSharedDataRegistry() const boRec = registry.getSkillById(149)! const heroStats = new UnitStatList(registry) const heroBus = new StateBus(heroStats, registry) const hero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: heroBus } for (const slvl of [1, 2, 5, 10, 20, 30, 45, 50]) { const curHeroBus = new StateBus(heroStats, registry) const curHero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: curHeroBus } const expectedPct = 35 + (slvl - 1) * 3 const evalBO = evaluateSkill113c({ registry, skill: boRec, slvl, blvl: slvl, statList: heroStats }) executeSkill113c({ registry, skill: boRec, evalResult: evalBO, caster: curHero, targets: [], targetPositions: new Map(), corpses: [], missileEngine: {} as any, auraScanner: {} as any, summonManager: {} as any, currentTick: slvl, targetX: 0, targetY: 0, }) const state = curHeroBus.getState('battleorders') expect(state).toBeDefined() expect(state?.stats?.['item_maxhp_percent']).toBe(expectedPct) expect(state?.stats?.['item_maxmana_percent']).toBe(expectedPct) expect(state?.stats?.['item_maxstamina_percent']).toBe(expectedPct) } }) }) // -------------------------------------------------------------------------- // 3. Battle Command Radius // -------------------------------------------------------------------------- describe('3. Battle Command Radius Subtiles', () => { it('verifies radiusSubtiles is authentically 20 subtiles across slvl 1..50 (not 4875)', async () => { const registry = await getSharedDataRegistry() const bcRec = registry.getSkillById(155)! const stats = new UnitStatList(registry) for (const slvl of [1, 5, 10, 20, 30, 40, 50]) { const evalBC = evaluateSkill113c({ registry, skill: bcRec, slvl, blvl: slvl, statList: stats }) expect(evalBC.radiusSubtiles).toBe(20) // Duration should scale per 1.13c: 125 + 250 * (slvl - 1) expect(evalBC.durationFrames).toBe(125 + 250 * (slvl - 1)) } }) }) // -------------------------------------------------------------------------- // 4. War Cry Stun & Damage // -------------------------------------------------------------------------- describe('4. War Cry Radial Physical Damage & Stun Delivery', () => { it('verifies target takes radial physical spell damage AND is stunned for 25 + 5 * (slvl - 1) frames via executeSUnitDmg', async () => { const registry = await getSharedDataRegistry() const wcRec = registry.getSkillById(154)! const heroStats = new UnitStatList(registry) const heroBus = new StateBus(heroStats, registry) const hero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: heroBus } for (const slvl of [1, 5, 10, 20]) { const dummyStats = new UnitStatList(registry) const dummyBus = new StateBus(dummyStats, registry) const dummy: CombatUnitContext = { id: `dummy-${slvl}`, name: 'Target', statList: dummyStats, stateBus: dummyBus } const evalWC = evaluateSkill113c({ registry, skill: wcRec, slvl, blvl: slvl, statList: heroStats }) const expectedStunFrames = 25 + 5 * (slvl - 1) const outcome = executeSkill113c({ registry, skill: wcRec, evalResult: evalWC, caster: hero, targets: [dummy], targetPositions: new Map(), corpses: [], missileEngine: { spawnMissile: () => ({ name: 'warcry' }) } as any, auraScanner: {} as any, summonManager: {} as any, currentTick: 1, targetX: 0, targetY: 0, }) expect(outcome.totalDamageDealt).toBeGreaterThan(0) expect(outcome.statesApplied).toContain('stun') expect(dummyBus.hasState('stun')).toBe(true) const stunState = dummyBus.getState('stun') expect(stunState).toBeDefined() expect(stunState?.durationFrames).toBe(expectedStunFrames) } }) }) // -------------------------------------------------------------------------- // 5. Battle Cry Debuff Formulas // -------------------------------------------------------------------------- describe('5. Battle Cry Debuff Formulas Across Levels', () => { it('verifies defense reduction -(50 + 2 * (slvl - 1))%, damage reduction -(25 + 1 * (slvl - 1))%, and duration 300 + 60 * (slvl - 1)', async () => { const registry = await getSharedDataRegistry() const bcRec = registry.getSkillById(146)! const heroStats = new UnitStatList(registry) const heroBus = new StateBus(heroStats, registry) const hero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: heroBus } for (const slvl of [1, 2, 5, 10, 20, 30]) { const dummyStats = new UnitStatList(registry) const dummyBus = new StateBus(dummyStats, registry) const dummy: CombatUnitContext = { id: `dummy-${slvl}`, name: 'Monster', statList: dummyStats, stateBus: dummyBus } const evalBC = evaluateSkill113c({ registry, skill: bcRec, slvl, blvl: slvl, statList: heroStats }) executeSkill113c({ registry, skill: bcRec, evalResult: evalBC, caster: hero, targets: [dummy], targetPositions: new Map(), corpses: [], missileEngine: {} as any, auraScanner: {} as any, summonManager: {} as any, currentTick: 1, targetX: 0, targetY: 0, }) const state = dummyBus.getState('battlecry') expect(state).toBeDefined() const expectedDef = -(50 + 2 * (slvl - 1)) const expectedDmg = -(25 + 1 * (slvl - 1)) const expectedDuration = 300 + 60 * (slvl - 1) expect(state?.stats?.['item_armor_percent']).toBe(expectedDef) expect(state?.stats?.['item_mindamage_percent']).toBe(expectedDmg) expect(state?.durationFrames).toBe(expectedDuration) } }) }) // -------------------------------------------------------------------------- // 6. Boss & Champion Mental Curse Immunities // -------------------------------------------------------------------------- describe('6. Boss & Champion Mental Curse Immunities (Howl, Grim Ward, Taunt)', () => { it('verifies Act Bosses, Champions, and SuperUniques are completely immune to Howl (#130), Grim Ward (#150), and Taunt (#137)', async () => { const registry = await getSharedDataRegistry() registerSkillModule(grimWardModule) const heroStats = new UnitStatList(registry) const heroBus = new StateBus(heroStats, registry) const hero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: heroBus } // Define diverse immune targets: const actBossStats = new UnitStatList(registry) const actBossBus = new StateBus(actBossStats, registry) const actBoss: CombatUnitContext = { id: 'diablo', name: 'Diablo', statList: actBossStats, stateBus: actBossBus, isBoss: true, rank: 'boss' } const championStats = new UnitStatList(registry) const championBus = new StateBus(championStats, registry) const champion: CombatUnitContext = { id: 'champ', name: 'Champion Fallen', statList: championStats, stateBus: championBus, isChampion: true, rank: 'champion' } const superUniqueStats = new UnitStatList(registry) const superUniqueBus = new StateBus(superUniqueStats, registry) const superUnique: CombatUnitContext = { id: 'rakanishu', name: 'Rakanishu', statList: superUniqueStats, stateBus: superUniqueBus, rank: 'unique' } // Normal non-immune target: const normalStats = new UnitStatList(registry) const normalBus = new StateBus(normalStats, registry) const normalTarget: CombatUnitContext = { id: 'normal', name: 'Fallen', statList: normalStats, stateBus: normalBus, rank: 'normal' } const allTargets = [actBoss, champion, superUnique, normalTarget] // 6.1 Test Howl (130) const howlRec = registry.getSkillById(130)! const evalHowl = evaluateSkill113c({ registry, skill: howlRec, slvl: 5, blvl: 5, statList: heroStats }) executeSkill113c({ registry, skill: howlRec, evalResult: evalHowl, caster: hero, targets: allTargets, targetPositions: new Map(), corpses: [], missileEngine: { spawnMissile: () => ({ name: 'howl' }) } as any, auraScanner: {} as any, summonManager: {} as any, currentTick: 1, targetX: 0, targetY: 0, }) expect(normalBus.hasState('terror')).toBe(true) expect(actBossBus.hasState('terror')).toBe(false) expect(championBus.hasState('terror')).toBe(false) expect(superUniqueBus.hasState('terror')).toBe(false) // 6.2 Test Grim Ward (150) const normalBus2 = new StateBus(normalStats, registry) const normalTarget2: CombatUnitContext = { ...normalTarget, stateBus: normalBus2 } const gwRec = registry.getSkillById(150)! const evalGW = evaluateSkill113c({ registry, skill: gwRec, slvl: 5, blvl: 5, statList: heroStats }) const corpse = { id: 'corpse-1', consumed: false, shattered: false, isBoss: false, baseMaxHp: 500, x: 0, y: 0 } executeSkill113c({ registry, skill: gwRec, evalResult: evalGW, caster: hero, targets: [actBoss, champion, superUnique, normalTarget2], targetPositions: new Map(), corpses: [corpse as any], missileEngine: {} as any, auraScanner: {} as any, summonManager: {} as any, currentTick: 2, targetX: 0, targetY: 0, }) expect(normalBus2.hasState('terror')).toBe(true) expect(actBossBus.hasState('terror')).toBe(false) expect(championBus.hasState('terror')).toBe(false) expect(superUniqueBus.hasState('terror')).toBe(false) // 6.3 Test Taunt (137) const normalBus3 = new StateBus(normalStats, registry) const normalTarget3: CombatUnitContext = { ...normalTarget, stateBus: normalBus3 } const tauntRec = registry.getSkillById(137)! const evalTaunt = evaluateSkill113c({ registry, skill: tauntRec, slvl: 5, blvl: 5, statList: heroStats }) executeSkill113c({ registry, skill: tauntRec, evalResult: evalTaunt, caster: hero, targets: [actBoss, champion, superUnique, normalTarget3], targetPositions: new Map(), corpses: [], missileEngine: { spawnMissile: () => ({ name: 'taunt' }) } as any, auraScanner: {} as any, summonManager: {} as any, currentTick: 3, targetX: 0, targetY: 0, }) expect(normalBus3.hasState('taunt')).toBe(true) expect(actBossBus.hasState('taunt')).toBe(false) expect(championBus.hasState('taunt')).toBe(false) expect(superUniqueBus.hasState('taunt')).toBe(false) }) }) // -------------------------------------------------------------------------- // 7. Find Item & Find Potion Horking Probability // -------------------------------------------------------------------------- describe('7. Find Item & Find Potion Horking Probability and Corpse Consumption', () => { it('verifies failed rolls consume the corpse and emit note "hork_failed", while successful rolls emit "item_found" or "potion_found"', async () => { const registry = await getSharedDataRegistry() registerSkillModule(findPotionModule) registerSkillModule(findItemModule) const heroStats = new UnitStatList(registry) const heroBus = new StateBus(heroStats, registry) const hero: CombatUnitContext = { id: 'hero', name: 'Barbarian', statList: heroStats, stateBus: heroBus } // Find Potion (131) const fpRec = registry.getSkillById(131)! const evalFP = evaluateSkill113c({ registry, skill: fpRec, slvl: 1, blvl: 1, statList: heroStats }) // Find Item (142) const fiRec = registry.getSkillById(142)! const evalFI = evaluateSkill113c({ registry, skill: fiRec, slvl: 1, blvl: 1, statList: heroStats }) // Run 50 trials of each skill and verify invariant: // 1. corpse.consumed is ALWAYS true // 2. corpsesConsumed === 1 // 3. executed === true // 4. exactly one of 'hork_failed' or 'potion_found'/'item_found' is in notes let fpSuccess = 0 let fpFailed = 0 for (let i = 0; i < 50; i++) { const corpse = { id: `corpse-fp-${i}`, consumed: false, shattered: false, isBoss: false, baseMaxHp: 500, x: 0, y: 0 } const outcome = executeSkill113c({ registry, skill: fpRec, evalResult: evalFP, caster: hero, targets: [], targetPositions: new Map(), corpses: [corpse as any], missileEngine: {} as any, auraScanner: {} as any, summonManager: {} as any, currentTick: i, targetX: 0, targetY: 0, }) expect(corpse.consumed).toBe(true) expect(outcome.executed).toBe(true) expect(outcome.corpsesConsumed).toBe(1) if (outcome.notes.includes('potion_found')) { fpSuccess++ expect(outcome.notes.includes('hork_failed')).toBe(false) } else { fpFailed++ expect(outcome.notes.includes('hork_failed')).toBe(true) } } expect(fpSuccess).toBeGreaterThan(0) expect(fpFailed).toBeGreaterThan(0) let fiSuccess = 0 let fiFailed = 0 for (let i = 0; i < 50; i++) { const corpse = { id: `corpse-fi-${i}`, consumed: false, shattered: false, isBoss: false, baseMaxHp: 500, x: 0, y: 0 } const outcome = executeSkill113c({ registry, skill: fiRec, evalResult: evalFI, caster: hero, targets: [], targetPositions: new Map(), corpses: [corpse as any], missileEngine: {} as any, auraScanner: {} as any, summonManager: {} as any, currentTick: i, targetX: 0, targetY: 0, }) expect(corpse.consumed).toBe(true) expect(outcome.executed).toBe(true) expect(outcome.corpsesConsumed).toBe(1) if (outcome.notes.includes('item_found')) { fiSuccess++ expect(outcome.notes.includes('hork_failed')).toBe(false) } else { fiFailed++ expect(outcome.notes.includes('hork_failed')).toBe(true) } } expect(fiSuccess).toBeGreaterThan(0) expect(fiFailed).toBeGreaterThan(0) }) }) })