feedback1 cell: a 突变细胞 transformation gains the new operator into the 整备区 and frees the carrier's tile (pointed out in PR #2)

Official gameplay footage (bilibili BV1vzyVBuEN9 at about 8:24, BV1Qkw1zMEoR at about 7:25) shows the
next prep with the carrier's tile empty, one more deployment left, and the returned equipment plus the
new tier+1 operator on the bench, deployed by hand afterwards. That is the PRTS 备注 read as written
("生效时,原干员销毁,获得一名高一阶的随机初始干员"): a destroy followed by a gain. The closed PR #2 made
the same claim from a playtest.

- PlayerState.transformChess: the carrier is destroyed wherever it stands (board tile freed, summons
  removed, copies back to the pool); its equipment, the cell included, returns to the hand first
  (overflow temp, auto-merge); then the new operator is gained through acquireChess like any gained
  operator (hand, overflow temp, the no-room rule of every gain; no summon card until it is deployed).
  The returnItems option is gone (the cell's built-in was its only caller).
- A merge the gain completes merges like any gained copy: the elite takes a consumed deployed copy's
  tile, else the hand. _mergeChess loses fromKey / fromDir, so the destroyed carrier's tile never
  counts (PR #2 had kept that path; not adopted); audit.js drops its exception for it.
- builtinMeta, ctx.transform, items/meta.js and bot.js comments follow. Bots and AI 托管 deploy the
  gained operator in their normal lineup step (no bot change needed; a real co-op round pins it).
- ITEM_RULES note and implFormula for the item card; data/items.json rebuilt with build-data --offline.
- Tests: facing, merge, playtest6-elite-to-board and items no longer pin the kept tile; feedback1-meta
  covers a deployed and a bench carrier, hand full -> temp, hand and temp full, a merge with and
  without a deployed copy (never the carrier's tile), 商业包装方案's count on the returned item, and bots /
  AI 托管 redeploying; feedback1-cell checks the new note.
This commit is contained in:
sganggs committed 2026-10-03 15:18:42 +08:00
1 parent 842e1e13c4
commit 91c9b21d7f
14 files changed
+400 -178

No files matched your search

+5 -3
View File
@@ -1,6 +1,7 @@
// Player feedback after 0.1.0, #4 (workstream WA): the 突变细胞 item card says what the official text leaves out — the
// cell is not consumed, it returns to the hand with the destroyed operator's other equipment (items.json `note`, built
// by tools/build-data.mjs ITEM_RULES; server: builtinMeta char_chess_transformation_equip).
// cell is not consumed, it returns to the hand with the destroyed operator's other equipment, and the new operator joins
// the 整备区 to be deployed again (official footage; PR #2) (items.json `note`, built by tools/build-data.mjs ITEM_RULES;
// server: builtinMeta char_chess_transformation_equip).
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
@@ -35,7 +36,7 @@ const textOf = (v) => {
};
const hasClass = (v, c) => typeof v?.props?.class === 'string' && v.props.class.split(/\s+/).includes(c);
test('ItemDetail: 突变细胞 (both qualities) says it returns to the hand; an ordinary item has no rule line', async () => {
test('ItemDetail: 突变细胞 (both qualities) says it returns to the hand and the new operator joins the 整备区; an ordinary item has no rule line', async () => {
await data.loadAll('items', 'assets');
const rule = (item) => [...walk(ItemDetail({ item, piece: null, editable: false }))].find((n) => hasClass(n, 'dhint--rule'));
for (const id of ['chess_item_5_08_e_a', 'chess_item_5_08_e_b']) {
@@ -44,6 +45,7 @@ test('ItemDetail: 突变细胞 (both qualities) says it returns to the hand; an
const t = textOf(rule(cell));
assert.match(t, /原干员销毁/);
assert.match(t, /突变细胞与其他装备退回整备区,可再次配发/);
assert.match(t, /高一阶的随机初始干员(最高6阶),进入整备区,需要重新部署/);
}
const plain = data.lookup('items', 'chess_item_1_01_e_a'); // 维式重锤
assert.equal(plain.note, null);