Files
ark-stronghold-protocol/test/render/feedback1f-down-tile.test.js
T
sganggs 8de9002d1a feedback1f WV: the client draws a knocked-out operator on the tile it lies on
render/interp.js keeps the body tile of a b.snap `down` entry (row, col; only
when both are integers, so a 4-element entry is unchanged) and
render/units.js setDown moves the knocked-down view and its ring there: an
operator that fell on another piece's home lies on its own home (PRTS
卫戍协议/帮助 "…尝试返回其自身的初始位置"), and a view built from the unit's
deploy info (a field joined mid-battle) no longer stays on its first tile.

Tests: test/render/feedback1f-down-tile.test.js (fake PIXI, the sim's own
snapshot); opt-in test/render/feedback1f-down-tile.browser.test.js (real sim
frames in headless Chrome: drawn, picked and redeployed on its own home).
2026-10-03 07:16:34 +08:00

65 lines
3.6 KiB
JavaScript

// Player report F5 after the 0.1.0 release, client side: b.snap `down` entries carry the tile a knocked-out operator
// lies on ([id, respawnAt, respawnTime, state, row, col] — where it fell, or its own home when it fell on another board
// piece's home: PRTS 卫戍协议/帮助 "若干员被击倒的位置为其他干员或召唤物的初始位置,则在被击倒后,尝试返回其自身的初始
// 位置"; sim Battle._layBody). render/interp.js keeps them and render/units.js draws the knocked-down view on that tile
// (headless fake PIXI, test/render/fakepixi.js); older 4-element entries keep the view where it is.
import { test, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { installFakePixi, fakeViewCtx } from './fakepixi.js';
import { presetCamera } from '../../public/js/render/projection.js';
import { SnapshotBuffer, normalizeSnapshot } from '../../public/js/render/interp.js';
import { makeBattle, chessRec } from '../helpers/battleHarness.js';
let fake, UnitView, DOWN_STATE, groundZ;
before(async () => {
fake = installFakePixi();
({ UnitView, DOWN_STATE, groundZ } = await import('../../public/js/render/units.js'));
});
after(() => fake.restore());
const cam = () => presetCamera('normal', { width: 1280, height: 720 });
const view = (info = {}) => new UnitView(fakeViewCtx(fake.P, { cam }), { id: 1, side: 'ally', kind: 'chess', defId: 'char_x', tier: 3, x: 5, y: 10, maxHp: 1000, dir: 'RIGHT', ...info });
const frames = (v, n) => { for (let i = 0; i < n; i++) v.update(1 / 60, cam(), i / 60); };
test('interp keeps the body tile of a `down` entry (integers only); a 4-element entry stays as it was', () => {
const s = normalizeSnapshot({ t: 2, units: [], down: [[7, 20, 18, 0, 9, 8], [8, 21, 18, 0], [9, 22, 18, 0, 9.5, 'x']] });
assert.deepEqual(s.down, [[7, 20, 18, 0, 9, 8], [8, 21, 18, 0], [9, 22, 18, 0]]);
const buf = new SnapshotBuffer({ delay: 0 });
buf.push({ t: 1, units: [], down: [[7, 20, 18, 0, 10, 3]] }, 0);
assert.deepEqual(buf.downAt(1), [[7, 20, 18, 0, 10, 3]]);
});
test('the knocked-down view is drawn on the tile the entry names: a body back on its home moves there', () => {
const v = view({ x: 6, y: 12 }); // fell on another piece's home (12,6)
frames(v, 2);
v.setDown([1, 30, 20, DOWN_STATE.COUNTING, 10, 3], 10); // it lies on its own home (10,3)
assert.equal(v.alive, false);
assert.deepEqual([v.x, v.y], [3, 10]);
frames(v, 30);
assert.equal(v.z, groundZ(v.ctx, 3, 10), 'on that tile\'s ground');
assert.ok(v._downRing.root.visible, 'its ring follows');
// a 4-element entry (an older feed) leaves it where it is
const w = view({ id: 2, x: 4, y: 11 });
frames(w, 2);
w.setDown([2, 30, 20, DOWN_STATE.COUNTING], 10);
assert.deepEqual([w.x, w.y], [4, 11]);
});
test('end to end: the sim\'s snapshot names the tile the body lies on, the view follows it', () => {
const op = (id) => chessRec({ id, profession: 'WARRIOR', skill: null });
const h = makeBattle({ defs: { chess: { e_a: op('e_a'), e_b: op('e_b') } }, units: [{ chessId: 'e_a', row: 12, col: 3 }, { chessId: 'e_b', row: 10, col: 3 }], content: 'none', autoFinish: false });
h.step();
const b = h.b, A = h.unit('e_a'), B = h.unit('e_b');
b.retreat(A, { reason: 'raid' });
b.redeploy(A, { free: true, tile: [11, 6] });
b.retreat(B, { reason: 'raid' });
b.redeploy(B, { free: true, tile: [12, 3] }); // on A's home
const v = view({ id: B.id, x: B.x, y: B.y });
frames(v, 2);
b.kill(B);
const d = normalizeSnapshot(b.snapshot()).down.find((e) => e[0] === B.id);
assert.deepEqual(d.slice(4), [10, 3], 'back on its own home');
v.setDown(d, b.time);
assert.deepEqual([v.x, v.y], [3, 10]);
});