From 83d76e507d3e5416d9411dca0a7513d531182194 Mon Sep 17 00:00:00 2001 From: sganggs Date: Tue, 6 Oct 2026 19:28:04 +0800 Subject: [PATCH] =?UTF-8?q?feedback5:=20a=20=E8=87=AA=E9=80=89=20summoner?= =?UTF-8?q?=20promoted=20in=20place=20on=20the=20board=20(=E5=8D=87?= =?UTF-8?q?=E5=8D=8E=20/=20=E5=8D=9A=E5=A3=AB=E6=8A=95=E5=BD=B1)=20tops=20?= =?UTF-8?q?its=20summon=20stacks=20up=20to=20the=20elite's=20deploy=20limi?= =?UTF-8?q?t,=20like=20an=20elite=20merged=20onto=20a=20tile=20(=E9=BA=A6?= =?UTF-8?q?=E5=93=B2=E4=BC=A6=20/=20=E4=BB=A4=203=20=E2=86=92=204,=20?= =?UTF-8?q?=E6=9C=9B=206=20=E2=86=92=207=20with=20their=20modules;=20found?= =?UTF-8?q?=20by=20the=200.2.0=20interaction=20review,=20round=2017);=20te?= =?UTF-8?q?st=20fails=20without=20the=20fix;=20golden=20unchanged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/match/player/acquire.js | 3 ++ test/match/feedback5-promote-summons.test.js | 40 ++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 test/match/feedback5-promote-summons.test.js diff --git a/server/match/player/acquire.js b/server/match/player/acquire.js index 97371215..49887ed1 100644 --- a/server/match/player/acquire.js +++ b/server/match/player/acquire.js @@ -150,6 +150,9 @@ export class PlayerAcquire { piece.poolCopies = (piece.poolCopies || 0) + this.poolOf(base).take(base, extra); piece.id = goldenId; this.recompute(); + // an elite on the board tops its summon stacks up to the elite's deploy limit, like an elite merged onto a tile + // (_mergeChess → grantTokensFor): 麦哲伦 / 令 3 → 4, 望 6 → 7 with their modules (0.2.0 review round 17) + if ([...this.board.values()].includes(piece)) this.grantTokensFor(piece); return true; } diff --git a/test/match/feedback5-promote-summons.test.js b/test/match/feedback5-promote-summons.test.js new file mode 100644 index 00000000..7660eb6f --- /dev/null +++ b/test/match/feedback5-promote-summons.test.js @@ -0,0 +1,40 @@ +// Promote in place (升华 / 博士投影: PlayerState.promote) of a 自选 summoner standing on the board tops its summon stacks up +// to the ELITE's deploy limit, like an elite merged onto a tile (_mergeChess → grantTokensFor). 0.2.0 review round 17: +// 麦哲伦 with SUM-Y fields 3 drones as a normal piece and 4 as an elite; the promote used to leave the hand at 3. +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { hasGeneratedData } from '../../server/sim/simdata.js'; +import { makeMatch, legalTileFor } from './harness.js'; + +const REAL = { skip: !hasGeneratedData() && 'needs the generated data (npm run build-data)' }; +const T6B = 'chess_char_6_diy2_a'; +const MGLLAN = 'char_248_mgllan'; +const SUM_Y = 'uniequip_003_mgllan'; + +/** Summon copies of `uid` the player holds: placed on the board plus the stacks in the hand and 临时整备区. */ +function summonsOf(ps, uid) { + let n = 0; + for (const p of [...ps.board.values(), ...ps.hand, ...ps.temp]) if (p && p.kind === 'token' && p.ownerUid === uid) n += p.count || 1; + return n; +} + +test('a promoted 自选 summoner on the board gets the elite\'s summon count (麦哲伦 SUM-Y: 3 → 4 drones)', REAL, () => { + const seats = [{ seat: 0, playerId: 'p_0', name: 'P0', isBot: false, connected: true, diy: { [T6B]: { charId: MGLLAN, skillIndex: 0, uniEquipId: SUM_Y } } }]; + const h = makeMatch({ mode: 'solo', seats, seed: 21 }).start(); + try { + h.toPrep(1); + const ps = h.ps('p_0'); + ps.initDiyStock(new Set()); + const piece = ps.acquireChess(T6B, { source: 'buy' }); + assert.ok(piece, 'the 自选 麦哲伦 was gained'); + const tile = legalTileFor(h.m, ps, piece.id); + assert.deepEqual(h.m.handle('p_0', { t: 'g.move', uid: piece.uid, to: { area: 'board', row: tile[0], col: tile[1] }, dir: 'RIGHT' }), { ok: true }); + const limit = (p) => ps.gd.placeableTokens(p.id, ps.loadoutFor(ps.gd.chess(p.id))).reduce((a, t) => a + t.count, 0); + const normal = limit(piece); + assert.equal(summonsOf(ps, piece.uid), normal, 'placing the normal piece brings its own count'); + assert.equal(ps.promote(piece), true); + const elite = limit(piece); + assert.ok(elite > normal, `the elite's limit (${elite}) is above the normal one (${normal})`); + assert.equal(summonsOf(ps, piece.uid), elite, 'the promote tops the stacks up to the elite limit'); + } finally { h.m.dispose(); } +});