Playtest #6 fixes: summons placed by hand, boss pool stall, bounties, 联防 leak counter, distinct offers, 机变 card text, phone buy tap, skill triggers, blocking, push force, 孤立, enemies, element bar

- #1 #2 skill / device summons (赫默's drone, 巫恋's doll, 凯瑟琳's devices) are hand cards placed by the player;
  placed summons deploy once at battle start, then a skill summon re-appears at its tile on each cast (the user's call)
- #3 叙拉古 隐匿 ends on time (32 + 0.4 × layers s); 忍冬 S3 迷彩 lasts until her next cast (official), kept apart from 隐匿
- #4 multi-round bounty cards last two battles (the user's call; MULTI_ROUND_BOUNTY_BATTLES), blue / red card text
- #5 the shared boss pool's float dust (≈3.6e-12 HP) stalled Final Assault leaders at 0 %; < 1 HP now clears the pool,
  and the team LP reaching 0 first is a defeat (PRTS)
- #6 #10 机变 cards show their official effect text; an invisible 详情 button no longer swallows the confirming tap on phones
- #7 live ×N counter of a leaker's enemies still on the 联防 field (LP loss stays capped at 10)
- #8 #15 #16 skill triggers per 技能策略: skill-range triggers, injured-ally heals (古米, 塞雷娅), tank take-damage
  triggers with a 3 s cooldown; 新约能天使 S2 shields the highest-aggro operator in range
- #9 official per-enemy model scales (威龙)
- #11 element bar under the unit's HP bar (white = 元素值 left, element-coloured refill after a burst), floor rounding
- #12 枯朽战车 kit per PRTS; every ranged enemy reaches its target's 0.25 collider
- #13 恐惧 wander (萨科塔之翼 at half HP, operator fears make enemies flee) with re-planning after pushes
- #14 push / pull distance by 力度 − 重量 (PRTS table); #17 every blocker attacks what it blocks; ASPD floor 20
- #18 炎佑 is 孤立: no heals or ally buffs
- #19 every free pick-one chess offer (promotion reward, 信标, 寻呼模块) shows different operators
- DESIGN §20 and the normative lines, SIM / META / DATA / PLAYING updated; 2747 unit tests and all 27 browser suites
  green; dev recordings regenerated
This commit is contained in:
sganggs committed 2026-10-01 19:08:23 +08:00
1 parent e6628f0cfe
commit 6464e4b46a
138 files changed
+7946 -1379

No files matched your search

+7 -5
View File
@@ -269,15 +269,17 @@ test('co-op keeps its guards: INFO_CHECK 25 s, prep timer, transition deadlines'
// ---- review fixes -----------------------------------------------------------------------------------------------------------
test('a skill summon is never a hand card (user playtest #4): 赫默 on any skill gets no 医疗无人机 token in the prep phase', async () => {
test('a skill summon is a hand card only with that skill (user playtest #6): 赫默 on S2 gets her 医疗探机, on S1 none', async () => {
const { give } = await import('./harness.js');
const SILENCE = 'chess_char_2_02_a';
const DRONE = 'token_10000_silent_healrb';
assert.equal(chess(SILENCE).skills.find((s) => s.overrideTokenKey === DRONE)?.isDefault, true, 'fixture: the drone is the default S2 summon');
// "获得一个医疗无人机": the drone appears in battle when S2 fires (test/content/tokens_devices.test.js), never before
// the drone is placed by hand (PRTS 卫戍协议/帮助 "可手动部署的附属召唤物…加入手牌区"); in battle it takes its tile when S2
// fires (test/content/playtest6_summons.test.js) — only S2 (index 1, the default) makes it
const tokensIn = (ps, id = DRONE) => [...ps.hand, ...ps.temp, ...ps.board.values()].filter((p) => p && p.kind === 'token' && p.id === id);
assert.equal(DATA.tokens[DRONE].placeable, false, 'tokens.json: a skill summon is not placeable');
assert.equal(DATA.tokens[DRONE].placeable, true, 'tokens.json: a manually deployable summon');
for (const skill of [null, 0, 1]) {
const want = skill === 0 ? 0 : 1;
const lo = skill == null ? null : checkLoadout({ [SILENCE]: { skill } }, chess).loadout;
const h = makeMatch({ mode: 'solo', seats: seatsWith(lo), seed: 5 }).start();
h.toPrep(1);
@@ -286,11 +288,11 @@ test('a skill summon is never a hand card (user playtest #4): 赫默 on any skil
ps.board.clear();
ps.hand.fill(null);
give(h.m, ps, SILENCE, 'board', [9, 3]);
assert.equal(tokensIn(ps).length, 0, `normal 赫默, skill ${skill ?? 'default'}`);
assert.equal(tokensIn(ps).length, want, `normal 赫默, skill ${skill ?? 'default'}`);
ps.board.clear();
ps.hand.fill(null);
give(h.m, ps, chess(SILENCE).goldenId, 'board', [9, 4]);
assert.equal(tokensIn(ps).length, 0, `elite 赫默, skill ${skill ?? 'default'}`);
assert.equal(tokensIn(ps).length, want, `elite 赫默, skill ${skill ?? 'default'}`);
// a talent summon still is a hand card: 伺夜 → 狼群
ps.board.clear();
ps.hand.fill(null);