diff --git a/public/js/render/units.js b/public/js/render/units.js index 457ae5d3..23dd17c4 100644 --- a/public/js/render/units.js +++ b/public/js/render/units.js @@ -1461,6 +1461,9 @@ export class ItemView { if (a?.image) a.image(url).then((img) => { if (!this.destroyed && img && this.info.icon === url) this.plate.texture = itemTexture(String(this.info.defId), img, this.info.color || 0x9aa5a0); }, () => {}); } setWorld(x, y, z = 0) { this.x = x; this.y = y; this.z = z; } + /** A battle snapshot sample (syncBattle syncs every unit of the field): a hand item on a scouted prep board rides + * the units as kind 'item' (Match.prepFieldMeta) — follow its position, there is nothing else to animate. */ + sync(s) { this.x = s.x; this.y = s.y; } update(dt, cam, t) { const lifted = this.lift > 0; const p = cam.project(this.x, this.y, lifted ? this.z : this.z + this.lift + 0.12 + Math.sin(t * 2 + this.bob) * 0.03, this.screen); diff --git a/test/ui/prep-bench.test.js b/test/ui/prep-bench.test.js index 4a00e463..47a4c160 100644 --- a/test/ui/prep-bench.test.js +++ b/test/ui/prep-bench.test.js @@ -41,6 +41,17 @@ describe('the scouted prep board renders the hand like the own bench', () => { assert.match(app, /function scoutItemInfo\(info\)/); }); + test('ItemView syncs battle samples: a hand item rides the scouted field without breaking syncBattle (render layer: source)', () => { + // syncBattle syncs EVERY unit of the field's snapshot (render/app.js `v.sync(s, renderT)`); the ItemView class + // needs a sync of its own or the frame loop throws `v.sync is not a function` on every tick and the scouted + // board's operators never draw (found in playtesting: only teammates with an item in hand / temp broke). + const units = read('public/js/render/units.js'); + const start = units.indexOf('export class ItemView'); + assert.ok(start > 0, 'ItemView exists'); + const body = units.slice(start, units.indexOf('export class ', start + 1)); + assert.match(body, /\bsync\(s\) \{ this\.x = s\.x; this\.y = s\.y; \}/); + }); + test('tapping a held item on the scouted board opens its card (resolveDetail unit → item)', () => { const IT = 'chess_item_1_01_e_a'; const d = resolveDetail({ kind: 'unit', unit: { id: 3, kind: 'item', side: 'ally', ownerId: 'p2', defId: IT } }, new Map());