diablo2-web/tests/scene-drop-preload.test.ts

76 lines
2.5 KiB
TypeScript

import { describe, it, expect, beforeAll } from 'vitest'
import * as fs from 'fs'
import { getSharedDropTables } from '../src/scene/act-scene.ts'
import { GameEngine } from '../src/game/engine.ts'
import { DEMO_EXPERIENCE, DEMO_SKILLS, DEMO_NPCS, DEMO_QUESTS } from '../src/game/demo-data.ts'
import { loadDropTables, type DropTables } from '../src/game/drop-pipeline.ts'
import { MountedArchives } from '../src/mpq/mount.ts'
import { MpqArchive } from '../src/mpq/archive.ts'
import { fileSource } from '../src/mpq/file-source.ts'
const hasD2 = fs.existsSync('samples/d2/d2data.mpq')
describe('Scene DropTables Preload & Decoupling (Issue #117)', () => {
let dropTables: DropTables
beforeAll(async () => {
if (!hasD2) return
const archives = new MountedArchives()
for (const name of ['d2data.mpq', 'd2exp.mpq', 'Patch_D2.mpq']) {
archives.add(name, await MpqArchive.open(await fileSource(`samples/d2/${name}`)))
}
dropTables = await loadDropTables(archives)
})
it('getSharedDropTables caches promise as a singleton to prevent repeated MPQ mounting', () => {
const p1 = getSharedDropTables(['samples/d2'])
const p2 = getSharedDropTables(['samples/d2'])
expect(p1).toBe(p2)
})
it('GameEngine allows starting with dropTables undefined on frame 0 and injecting later via setDropTables', () => {
const dummyTerrain = {
widthPx: 1000,
heightPx: 1000,
overlap: () => 0,
raycast: () => null,
findPath: () => [],
}
// Initialize GameEngine without dropTables (simulating instant frame-0 map display)
const engine = new GameEngine(dummyTerrain, {
spawn: { x: 100, y: 100 },
stats: [],
xpTable: DEMO_EXPERIENCE,
difficulty: 'normal',
skills: DEMO_SKILLS,
npcDefs: DEMO_NPCS,
questDefs: DEMO_QUESTS,
combatOptions: {
playerSpeed: 4,
playerReach: 50,
playerCooldownTicks: 10,
playerDamage: 10,
playerManaPerAttack: 1,
respawnTicks: 100,
disableMonsterAggro: true,
},
talkRadius: 50,
pickupRadius: 50,
inventoryCols: 10,
inventoryRows: 4,
monsterCount: 0,
})
expect(engine.opts.dropTables).toBeUndefined()
expect(engine.opts.monsterKinds).toBeUndefined()
// Simulate background promise resolution
if (dropTables) {
engine.setDropTables(dropTables)
expect(engine.opts.dropTables).toBe(dropTables)
expect(engine.opts.monsterKinds).toBe(dropTables.monsterKinds)
}
})
})