feedback7: merge fb7-dobermann — 教鞭 is the official three-choice (PR #353 by @Sukvii, the owner's decision), the Final Assault / Hidden Core pay a 战术特训 card's perfect coins (guarded by b.progress leaksBy), the bots put zero-range heavy guards on the road first (PR #339 by @IceCodeNew, placement only)
- Conflicts (the branch started atae22335c): spec.js / protocol.js b.progress (resolved from fb7-ui-backlog + leaksBy), gameLogic.js / game.js exports (device tips + normalizePersonalChoice), docs/PLAYING.md / design/network.md lines merged against the base, META.md (画卷 note + 教鞭), test/docs-consistency.test.js pin (both fields). - Grok review: MERGE AFTER FIXES — the HIGH (a forged boss result paid the cards) fixed on the branch (66a228c6), the META wording (1ab12763). - Golden: matches 10 (the 杜宾 bot picks and the guard placement); union: coop3-ABYSS-5 differs from HEAD only in ai_2's dmgDealt (1238011 → 1186269), no outcome change — HEAD's side had moved it, the new placement applies on that path. - Broad node --test 5623 (5621 pass, 0 fail, 2 skipped); lint 0 errors; typecheck; i18n strict clean.
This commit is contained in:
commit
2de2feee3c
57 files changed
+1339
-276
No files matched your search
@@ -11,7 +11,7 @@ import {
|
||||
phaseMode, phaseBanner, isCombatPhase, isBossPhase, countdownState, phaseTotalSeconds, sortBonds, bondTier, nextThreshold,
|
||||
battleOverSfx, ownRoundLoss, uniteResultBox, battleResultBox, roundResultBox, RESULT_BOX_MS,
|
||||
bondMembers, memberHeadCount, bannedPerBond, priceTone, mergeProgress, shopBlockReason, deploySets, indexPieces, placementContext, canPlace,
|
||||
boardTargets, dropIntent, normalizeDraft, normalizeSp, groupEnemies, factionTypes, snapHud, bossFrac, attackInterval, fmtNum,
|
||||
boardTargets, dropIntent, normalizeDraft, normalizeSp, normalizePersonalChoice, groupEnemies, factionTypes, snapHud, bossFrac, attackInterval, fmtNum,
|
||||
rangeGridBox, shortcutFor, sanitizeSettings, DEFAULT_SETTINGS, normalizeResult, cycleField, fieldLabel, homeFieldId,
|
||||
activeBubbles, sortedPlayers, tileKey, prepCapsuleLabel, prepCamera, dropFailureReason, terrainInfo,
|
||||
} from '../../public/js/ui/gameLogic.js';
|
||||
@@ -584,6 +584,32 @@ describe('drafts', () => {
|
||||
assert.equal(normalizeSp(null), null);
|
||||
assert.equal(normalizeSp({ cards: new Array(9).fill({}) }).cards.length, 6, 'at most 6 cards');
|
||||
});
|
||||
test('personal choice: only the living recipient in the current PREP, independent of the public draft', () => {
|
||||
const pub = { phase: PHASE.PREP, round: 14, sp: { family: 'supply', cards: ['global'] } };
|
||||
const priv = { playerId: 'a', alive: true, canReady: false, temp: [], personalChoice: {
|
||||
id: 'seed.choice.3', round: 14, sourceItemId: 'chess_item_6_03_m',
|
||||
cards: [{ id: 'e1', kind: 'bounty', name: '战术特训', coin: 2 }, { id: 'e2', kind: 'bounty' }],
|
||||
} };
|
||||
const before = JSON.stringify({ pub, priv });
|
||||
const sp = normalizePersonalChoice(pub, priv, 'a');
|
||||
assert.equal(sp.id, priv.personalChoice.id);
|
||||
assert.equal(sp.family, 'bounty');
|
||||
assert.equal(sp.name, '教鞭 · 战术特训');
|
||||
assert.equal(sp.turnPid, 'a');
|
||||
assert.equal(sp.pickOf.size, 0);
|
||||
assert.deepEqual(sp.cards.map((c) => c.idx), [0, 1]);
|
||||
assert.ok(sp.cards.every((c) => c.takenBy === null));
|
||||
assert.equal(JSON.stringify({ pub, priv }), before);
|
||||
assert.equal(shopBlockReason('ready', { priv, editable: true }), '请先完成教鞭选择');
|
||||
assert.equal(shopBlockReason('ready', { priv: { ...priv, temp: [{}] }, editable: true }), '请先完成教鞭选择');
|
||||
assert.match(shopBlockReason('ready', { priv: { ...priv, personalChoice: null }, editable: true }), /临时整备区/);
|
||||
for (const phase of [PHASE.SP_DRAFT, PHASE.COMBAT, PHASE.ROUND_START]) assert.equal(normalizePersonalChoice({ ...pub, phase }, priv, 'a'), null);
|
||||
assert.equal(normalizePersonalChoice(pub, null, 'a'), null, 'spectator has no private state');
|
||||
assert.equal(normalizePersonalChoice(pub, priv, 'b'), null);
|
||||
assert.equal(normalizePersonalChoice(pub, { ...priv, alive: false }, 'a'), null);
|
||||
assert.equal(normalizePersonalChoice({ ...pub, round: 15 }, priv, 'a'), null);
|
||||
assert.equal(normalizePersonalChoice(pub, { ...priv, personalChoice: null }, 'a'), null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fields, players, emotes', () => {
|
||||
|
||||
Reference in new issue
Block a user