import { describe, expect, test } from 'vitest' import { readSuperUniques, CANONICAL_SUPERUNIQUES_TABLE, CANONICAL_SUPER_UNIQUE_LANDMARKS, CANONICAL_SUPER_UNIQUES_BY_LEVEL, } from '../src/game/monsters.ts' import { MONSTER_ART_MAP, resolveMonsterArtSpec, } from '../src/game/monster-mapping.ts' import { CANONICAL_LANDMARK_ENTITIES } from '../src/game/wilderness.ts' import { MpqArchive } from '../src/mpq/archive.ts' import { fileSource } from '../src/mpq/file-source.ts' import { MountedArchives } from '../src/mpq/mount.ts' import { parseTable } from '../src/game/acts.ts' describe('SuperUniques Fidelity & Art Packaging (Issue #115)', () => { const d2DataDir = '/usr/local/google/home/taodao/d2-data' test('CANONICAL_SUPER_UNIQUE_LANDMARKS contains valid and corrected minion IDs', () => { // 10 previously mistyped minions must match correct IDs const landmarkMap = new Map(CANONICAL_SUPER_UNIQUE_LANDMARKS.map(l => [l.id, l])) expect(landmarkMap.get('Beetleburst')?.minionMonsterId).toBe('scarab2') expect(landmarkMap.get('Dark Elder')?.minionMonsterId).toBe('zombie5') expect(landmarkMap.get('Bloodwitch the Wild')?.minionMonsterId).toBe('pantherwoman1') expect(landmarkMap.get('Sszark the Burning')?.minionMonsterId).toBe('arach4') expect(landmarkMap.get('Witch Doctor Endugu')?.minionMonsterId).toBe('fetish4') expect(landmarkMap.get('Battlemaid Sarina')?.minionMonsterId).toBe('corruptrogue5') expect(landmarkMap.get('Dac Farren')?.minionMonsterId).toBe('imp3') expect(landmarkMap.get('Shenk the Overseer')?.minionMonsterId).toBe('minion1') expect(landmarkMap.get('Frozenstein')?.minionMonsterId).toBe('snowyeti4') expect(landmarkMap.get('Nihlathak')?.minionMonsterId).toBe('minion6') }) test('CANONICAL_LANDMARK_ENTITIES contains aligned boss and minion IDs', () => { const entityMap = new Map(CANONICAL_LANDMARK_ENTITIES.map(e => [e.id, e])) expect(entityMap.get('Beetleburst')?.monsterId).toBe('scarab2') expect(entityMap.get('Beetleburst')?.minionMonsterId).toBe('scarab2') expect(entityMap.get('Dark Elder')?.monsterId).toBe('zombie5') expect(entityMap.get('Dark Elder')?.minionMonsterId).toBe('zombie5') expect(entityMap.get('Bloodwitch the Wild')?.monsterId).toBe('pantherwoman1') expect(entityMap.get('Bloodwitch the Wild')?.minionMonsterId).toBe('pantherwoman1') expect(entityMap.get('Sszark the Burning')?.monsterId).toBe('arach4') expect(entityMap.get('Sszark the Burning')?.minionMonsterId).toBe('arach4') expect(entityMap.get('Witch Doctor Endugu')?.monsterId).toBe('fetishshaman4') expect(entityMap.get('Witch Doctor Endugu')?.minionMonsterId).toBe('fetish4') expect(entityMap.get('Battlemaid Sarina')?.monsterId).toBe('corruptrogue5') expect(entityMap.get('Battlemaid Sarina')?.minionMonsterId).toBe('corruptrogue5') expect(entityMap.get('Dac Farren')?.monsterId).toBe('imp3') expect(entityMap.get('Dac Farren')?.minionMonsterId).toBe('imp3') expect(entityMap.get('Shenk the Overseer')?.minionMonsterId).toBe('minion1') expect(entityMap.get('Frozenstein')?.monsterId).toBe('snowyeti4') expect(entityMap.get('Frozenstein')?.minionMonsterId).toBe('snowyeti4') expect(entityMap.get('Nihlathak')?.minionMonsterId).toBe('minion6') }) test('CANONICAL_SUPERUNIQUES_TABLE parses with corrected Class entries', () => { const parsed = readSuperUniques(CANONICAL_SUPERUNIQUES_TABLE) const map = new Map(parsed.map(p => [p.id, p])) expect(map.get('Beetleburst')?.monsterId).toBe('scarab2') expect(map.get('Dark Elder')?.monsterId).toBe('zombie5') expect(map.get('Bloodwitch the Wild')?.monsterId).toBe('pantherwoman1') expect(map.get('Sszark the Burning')?.monsterId).toBe('arach4') expect(map.get('Witch Doctor Endugu')?.monsterId).toBe('fetishshaman4') expect(map.get('Battlemaid Sarina')?.monsterId).toBe('corruptrogue5') expect(map.get('Dac Farren')?.monsterId).toBe('imp3') expect(map.get('Frozenstein')?.monsterId).toBe('snowyeti4') }) test('MONSTER_ART_MAP correctly maps critical SuperUnique boss tokens for each Act', () => { // Act 1: Griswold (GZ), The Smith (5P) expect(MONSTER_ART_MAP.griswold?.token).toBe('GZ') expect(MONSTER_ART_MAP.smith?.token).toBe('5P') // Act 2: Radament (RD), Coldworm (MQ), The Summoner (SU) expect(MONSTER_ART_MAP.radament?.token).toBe('RD') expect(MONSTER_ART_MAP.maggotqueen1?.token).toBe('MQ') expect(MONSTER_ART_MAP.summoner?.token).toBe('SU') // Act 3: High Council members (HP) expect(MONSTER_ART_MAP.councilmember1?.token).toBe('HP') expect(MONSTER_ART_MAP.councilmember2?.token).toBe('HP') expect(MONSTER_ART_MAP.councilmember3?.token).toBe('HP') // Act 4: Hephasto the Armorer (5P) expect(MONSTER_ART_MAP.hephasto?.token).toBe('5P') // Act 5: Nihlathak (XU), Baal Subject 5 (43) expect(MONSTER_ART_MAP.nihlathakboss?.token).toBe('XU') expect(MONSTER_ART_MAP.baalminion1?.token).toBe('43') }) test('All 66 SuperUniques in game data verify boss class and minion resolution', async () => { const archives = new MountedArchives() for (const name of ['d2data.mpq', 'd2exp.mpq', 'Patch_D2.mpq']) { try { const archive = await MpqArchive.open(await fileSource(`${d2DataDir}/${name}`)) archives.add(name, archive) } catch { // If data dir unavailable in test runner, skip archive loading portion return } } const suData = await archives.read('data\\global\\excel\\SuperUniques.txt') const suTable = parseTable(suData) const superUniques = readSuperUniques(suTable) expect(superUniques.length).toBe(66) for (const su of superUniques) { expect(su.id).toBeTruthy() expect(su.monsterId).toBeTruthy() // Boss class must resolve to an art spec or return null for dummy 'xx' codes gracefully const bossArt = resolveMonsterArtSpec(su.monsterId) if (su.monsterId === 'minion1') { // minion1 has Code="xx" in MonStats.txt and resolveMonsterArtSpec returns null expect(bossArt).toBeNull() } else { expect(bossArt).not.toBeNull() expect(bossArt?.token).toBeTruthy() expect(bossArt?.token.toLowerCase()).not.toBe('xx') } } }) test('Dummy code xx monsters resolve to null and do not throw in resolveMonsterArtSpec', () => { // minion1..minion11 have Code="xx" in MonStats for (let i = 1; i <= 11; i += 1) { const art = resolveMonsterArtSpec(`minion${i}`) expect(art).toBeNull() } // Unknown or dummy expect(resolveMonsterArtSpec('xx')).toBeNull() expect(resolveMonsterArtSpec('')).toBeNull() }) test('CANONICAL_SUPER_UNIQUES_BY_LEVEL builds without undefined errors', () => { expect(Object.keys(CANONICAL_SUPER_UNIQUES_BY_LEVEL).length).toBeGreaterThan(0) for (const [lvl, specOrSpecs] of Object.entries(CANONICAL_SUPER_UNIQUES_BY_LEVEL)) { const specs = Array.isArray(specOrSpecs) ? specOrSpecs : [specOrSpecs] for (const s of specs) { expect(s.id).toBeTruthy() expect(s.monsterId).toBeTruthy() expect(s.minionMonsterId).toBeTruthy() } } }) })