feedback6 R21D: a consume-on-equip item on a full carrier opens the replace dialog and replaces the picked item first (GitHub #263, PR #264); golden: matches 10 of 18 moved (a targeted consumable on a full carrier now destroys the oldest item), the rest unchanged

PRTS 卫戍协议/帮助 §装备: 「达到上限强行佩戴会改为替换装备:指定一件已佩戴装备替换为将要佩戴的装备,并销毁被指定的装备」,
no exception for the 装备时销毁 items. Before: a normal 博士投影 opened no dialog and its kept item pushed the OLDEST
equipped item out (replaceUid ignored); 盟约之币 and the other consumables kept both items.

- server PlayerState.equip (player/items.js): on a full carrier the consume path takes the pick (replaceUid, else the
  oldest) off before onEquip (_takeReplaced), destroys it (onDestroy reason replace) once the effect went through —
  the normal 博士投影 takes the freed slot —, and puts it back at its index when the effect refuses (博士投影 on an elite:
  nothing destroyed)
- client gameLogic equipReplaces: the replace dialog opens for every item on a full carrier, consumables included,
  except an attaching item that completes an item merge and a 博士投影 on an elite; itemAttaches removed
- bots (itemTarget): a consumable whose effect is the same on anyone goes to a carrier with a free slot first (PR #264)
- docs: design/match.md equipment rules, META §2.5, PLAYING 装备 row, research 04

golden (matches only; each traced equip by equip against the parent — the first change of state is a bot's, or the
AI 托管 human seat's, targeted consumable on a full carrier destroying its oldest item): solo-FUNNY-1 (r9 ai_0 随身身份牌),
solo-FUNNY-2 (r9 ai_0 寻呼模块), solo-HARD-2 (r9 ai_0 随身身份牌, r12 简易通讯机), coop2-NORMAL-3 (r9 ai_1 随身身份牌),
coop3-ABYSS-5 (r11 ai_1 随身身份牌), coop4-FUNNY-6 (r4 ai_1 随身身份牌), solo-HARD-9-boosted (r14 ai_0 随身身份牌),
coop2-ABYSS-10-boosted (r13 ai_0 随身身份牌, r14 ai_1 简易通讯机), coop2-NORMAL-14-standins (r9 ai_0 随身身份牌; now won,
14 rounds), coop2-NORMAL-70-diy (r14 h_0 随身身份牌); the bots' free-slot carrier for target-agnostic consumables moves
no scenario by itself; roster / bonds / fields / standins / diy unchanged
This commit is contained in:
sganggs committed 2026-10-07 18:03:53 +08:00
1 parent 783bd30afd
commit 8cef750e14
14 files changed
+277 -108

No files matched your search

+2 -1
View File
@@ -489,7 +489,8 @@ describe('placement mirror (canPlace)', () => {
const consumable = Object.values(items).find((x) => x.itemType === 'EQUIP' && String(x.kind).startsWith('consume_on_equip'));
const cons = item(consumable.id);
const ctxC = ctxFor(privWith({ board: [b], hand: [{ idx: 3, piece: cons }] }));
assert.equal(dropIntent(ctxC, cons.uid, { area: 'board', row: 9, col: 3 }).confirmReplace, false, 'consumed on equip: nothing is replaced');
// consumed on equip: a full carrier still replaces first (GitHub #263, test/ui/leftovers.test.js)
assert.equal(dropIntent(ctxC, cons.uid, { area: 'board', row: 9, col: 3 }).confirmReplace, true, 'consumed on equip: still replaces on a full carrier');
const ar = dropIntent(ctx, art.uid, { area: 'board', row: 12, col: 6 });
assert.deepEqual(ar, { t: 'g.art', fields: { itemUid: art.uid, row: 12, col: 6 } });
for (const i of [mv, back, eqI, eqH, ar]) assert.equal(validateC2S({ t: i.t, ...i.fields }), null, i.t);