diablo2-web/scripts/browser/checks/act-gameplay.js

91 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// act-gameplay.js — acts.html 上「玩法确实存在」的断言(M6 / issue #21)
//
// 这是 map-save-load.js 退役后,唯一还需要真浏览器的那部分:证明真地图场景里
// 怪物被生成进了世界、能被打死、掉落能被捡起、K/L 存读档走的是引擎的 tick 路径。
// 纯逻辑部分已经在 tests/engine-save-load.test.ts 与 tests/iso-terrain.test.ts 覆盖。
//
// CHROME=/usr/bin/google-chrome
// node scripts/browser/inspect-page.mjs "$CHROME" \
// "http://127.0.0.1:5173/acts.html?act=1" scripts/browser/checks/act-gameplay.js
(async () => {
const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
const press = (code, down) =>
window.dispatchEvent(new KeyboardEvent(down ? 'keydown' : 'keyup', { code, bubbles: true }))
const tap = async (code, ms) => { press(code, true); await sleep(ms); press(code, false); await sleep(60) }
const deadline = Date.now() + 120000
while (Date.now() < deadline) {
const s = window.__d2webAct
if (s && (s.ready || s.error)) break
await sleep(200)
}
const s = window.__d2webAct
if (s === undefined) return { error: 'no scene state' }
if (s.error) return { error: s.error }
await sleep(2000)
const spawned = {
monstersSpawned: s.monstersSpawned ?? null,
monstersAlive: s.monstersAlive ?? null,
npcs: s.npcs ?? null,
walkable: s.walkable,
}
// 追着打:四个方向各走一段并连续挥砍,直到有击杀或超时。
const dirs = ['ArrowRight', 'ArrowDown', 'ArrowLeft', 'ArrowUp']
const fightUntil = Date.now() + 40000
let round = 0
while (Date.now() < fightUntil && (window.__d2webAct?.kills ?? 0) === 0) {
const dir = dirs[round % dirs.length]
press(dir, true)
for (let i = 0; i < 6; i += 1) await tap('Space', 180)
press(dir, false)
await sleep(120)
round += 1
}
await sleep(400)
for (let i = 0; i < 8; i += 1) await tap('KeyE', 120)
await sleep(300)
const fought = {
kills: window.__d2webAct?.kills ?? null,
playerHits: window.__d2webAct?.playerHits ?? null,
dropsRolled: window.__d2webAct?.dropsRolled ?? null,
groundItems: window.__d2webAct?.groundItems ?? null,
pickups: window.__d2webAct?.pickups ?? null,
gold: window.__d2webAct?.gold ?? null,
bagItems: window.__d2webAct?.bagItems ?? null,
playerXp: window.__d2webAct?.playerXp ?? null,
playerHp: window.__d2webAct?.playerHp ?? null,
}
await tap('KeyK', 200)
await sleep(400)
const savedAt = { x: Math.round(window.__d2webAct?.x ?? 0), y: Math.round(window.__d2webAct?.y ?? 0), kills: window.__d2webAct?.kills ?? null }
press('ArrowRight', true); await sleep(2000); press('ArrowRight', false)
await sleep(400)
const drifted = { x: Math.round(window.__d2webAct?.x ?? 0), y: Math.round(window.__d2webAct?.y ?? 0) }
await tap('KeyL', 200)
await sleep(600)
const after = { x: Math.round(window.__d2webAct?.x ?? 0), y: Math.round(window.__d2webAct?.y ?? 0), kills: window.__d2webAct?.kills ?? null }
const gl = document.querySelector('#view')?.getContext('webgl2')
return {
source: s.source,
level: s.level,
spawned,
fought,
savedAt,
drifted,
after,
restored: after.x === savedAt.x && after.y === savedAt.y,
saves: window.__d2webAct?.saves ?? null,
loads: window.__d2webAct?.loads ?? null,
saveError: window.__d2webAct?.saveError ?? null,
tick: window.__d2webAct?.tick ?? null,
glError: gl ? gl.getError() : null,
}
})()