feedback5 R19B: the round-start banner reads 观战中 to an eliminated player and to a spectator seat instead of 资金已到账 — the server pays round income only to the players still in (startRound runs ps.startRound for alivePlayers(), eliminate() zeroes funds and pendingFunds); phaseBanner takes the viewer { alive, spectator } from the match screen (a spectator seat has no row in m.public); the idea from PR #237 (not merged: it sits on the #189 / #191 stack); GitHub #236; golden: unchanged (client text only)
This commit is contained in:
1 parent
0b306baa49
commit
7d97b80bfd
5 files changed
+54
-4
No files matched your search
@@ -89,6 +89,7 @@
|
||||
- 被淘汰后观战(以及观战席)会一直跟着上次查看的玩家,每回合开始不再跳回自己的空棋盘;没查看过时跟随第一位仍在场的玩家,人机也算(社区反馈;思路来自 PR #189,感谢 @2321Robin)。
|
||||
- 观战领袖回合的休整期时,看到的是领袖战场和站在那里的领袖,不再是没有领袖的普通棋盘(社区反馈)。
|
||||
- 最终攻势和隐秘核心的休整期,像作战时一样把同组两名玩家放在同一个战场上(队友的一半只能看),从回合开始到作战结束,左侧队伍栏用官方的绿框标出同组两人(社区反馈;参考了 PR #191,感谢 @2321Robin)。
|
||||
- 被淘汰后(以及观战席)每回合开始的横幅改为显示「观战中」,不再显示「资金已到账」:回合资金只发给仍在场的玩家(GitHub #236;思路来自 PR #237,感谢 @2321Robin)。
|
||||
|
||||
### 人机
|
||||
|
||||
|
||||
@@ -1856,3 +1856,20 @@ are.
|
||||
intents too (+3 layers, ATK, block). Two NORMAL copies of one item merge (the official rule), so two 空弦 need a normal
|
||||
and an 进阶 set; and the pair counts once toward the 3 members.
|
||||
- Pinned: `test/content/feedback5-cb1-pins.test.js`.
|
||||
|
||||
#### 25.22.2 GitHub #236 「被淘汰后每回合开始横幅仍显示「资金已到账」(观战席同理)」 (@2321Robin, with PR #237): the round-start banner reads 观战中 to an eliminated player and a spectator seat — `ui/gameLogic/phases.js phaseBanner`, `screens/game.js`
|
||||
|
||||
- **Seen** (a real Match with fake battles: three humans and a spectator seat, p_0 out of LP at round 1's settlement):
|
||||
at the round-2 start p_0 (funds 0, pending 0) and the spectator seat (no seat, no funds) got 「第 2 回合 · 资金已到账」,
|
||||
the same as p_1 (funds 5). The sub had been fixed text since 0.1.0.
|
||||
- **Official**: no rule for the banner's text. The money: round income goes only to the players still in.
|
||||
`startRound` runs `ps.startRound` (income + pending coins) for `alivePlayers()` only, and `eliminate()` zeroes
|
||||
`funds` / `pendingFunds` (server/match/match/phases.js, player/round.js). An eliminated player keeps watching
|
||||
(research 09: KEEP_WATCH).
|
||||
- **Now**: `phaseBanner(phase, pub, { alive, spectator })`. The match screen passes its `alive` and `spectator`.
|
||||
`alive` is false for an eliminated player and for a spectator seat. A spectator seat has no row in m.public, so `pub`
|
||||
alone cannot tell. For those viewers ROUND_START's sub is 「观战中」 (en "Spectating", the combat HUD's spectator
|
||||
caption). A player still in keeps 「资金已到账」. The title and the other phases do not change. PR #237 was read for the
|
||||
idea only: its fourth `alive` argument sits on top of the #189 / #191 stack and Match.js changes, so it was not merged.
|
||||
- Golden: unchanged (client text only). Tests: `test/ui/gameLogic.test.js` +1 (a player still in, an eliminated
|
||||
player, a spectator seat, the screen's call). It fails on the parent: 「资金已到账」 where 「观战中」 is expected.
|
||||
@@ -576,7 +576,7 @@ function MatchScreen() {
|
||||
const prev = prevPhase.current;
|
||||
prevPhase.current = phase;
|
||||
if (prev === phase) return;
|
||||
const b = phaseBanner(phase, pub);
|
||||
const b = phaseBanner(phase, pub, { alive, spectator });
|
||||
if (b) setBanner({ ...b, key: phaseKey });
|
||||
if (phase === PHASE.ROUND_START) audio.sfx('roundStart');
|
||||
else if (phase === PHASE.PREP) audio.sfx('rest', { volume: 0.7 });
|
||||
|
||||
@@ -40,12 +40,21 @@ export const isCombatPhase = (phase) => COMBAT_PHASES.has(phase);
|
||||
export const showDeadPill = (alive, phase) => !alive && !COMBAT_PHASES.has(phase) && phase !== PHASE.SETTLE;
|
||||
export const isBossPhase = (phase) => phase === PHASE.FINAL_ASSAULT || phase === PHASE.HIDDEN_CORE;
|
||||
|
||||
/** Banner shown when a phase starts: { title, sub?, tone } or null. */
|
||||
export function phaseBanner(phase, pub) {
|
||||
/**
|
||||
* Banner shown when a phase starts: { title, sub?, tone } or null.
|
||||
* @param {string|null|undefined} phase
|
||||
* @param {any} pub m.public
|
||||
* @param {{ alive?: boolean, spectator?: boolean }} [viewer] the local viewer (screens/game.js): `alive` false for an
|
||||
* eliminated player, `spectator` for a spectator seat — it has no row in m.public, so `pub` cannot tell
|
||||
*/
|
||||
export function phaseBanner(phase, pub, { alive = true, spectator = false } = {}) {
|
||||
const r = int(pub?.round, 0);
|
||||
switch (phase) {
|
||||
case PHASE.BATTLE_CHECK: return { title: t('协议启动'), micro: 'PROTOCOL START', tone: 'mint', sub: t('模拟即将开始'), duration: 2600 };
|
||||
case PHASE.ROUND_START: return { title: t('第 {r} 回合', { r }), micro: `ROUND ${String(r).padStart(2, '0')}`, tone: 'mint', sub: t('资金已到账') };
|
||||
// round income goes to the seats still in only (server/match/match/phases.js startRound; eliminate() zeroes funds
|
||||
// and pendingFunds): an eliminated player or a spectator seat reads 观战中, never 资金已到账 (GitHub #236, PR #237)
|
||||
case PHASE.ROUND_START: return { title: t('第 {r} 回合', { r }), micro: `ROUND ${String(r).padStart(2, '0')}`, tone: 'mint',
|
||||
sub: spectator || alive === false ? t('观战中') : t('资金已到账') };
|
||||
case PHASE.SP_DRAFT: return { title: t('机变阶段'), micro: 'CONTINGENCY', tone: 'gold', sub: t('依次选择机变') };
|
||||
case PHASE.PREP: return { title: t('休整期'), micro: `ROUND ${String(r).padStart(2, '0')} // REST`, tone: 'mint', sub: t('部署干员,准备迎敌') };
|
||||
case PHASE.COMBAT: return { title: t('作战开始'), micro: 'COMBAT', tone: 'orange', sub: t('各自行动阶段') };
|
||||
|
||||
@@ -72,6 +72,29 @@ describe('phases', () => {
|
||||
assert.equal(phaseBanner(PHASE.SETTLE, {}), null);
|
||||
assert.equal(prepCapsuleLabel(PHASE.PREP), '休息一下');
|
||||
});
|
||||
test('the round-start banner says 资金已到账 to a player still in only — 观战中 to an eliminated player and a spectator seat (GitHub #236)', () => {
|
||||
// round 2 after p_0 ran out of LP: p_1 is still in; the spectator seat s_spec has no row in m.public
|
||||
const pub = { round: 2, phase: PHASE.ROUND_START, players: [
|
||||
{ playerId: 'p_0', seat: 0, alive: false }, { playerId: 'p_1', seat: 1, alive: true },
|
||||
] };
|
||||
const round = (viewer) => phaseBanner(PHASE.ROUND_START, pub, viewer);
|
||||
// a player still in (the server paid the round's income)
|
||||
assert.equal(round({ alive: true, spectator: false }).sub, '资金已到账');
|
||||
assert.equal(round().sub, '资金已到账', 'no viewer given: the copy of a player still in');
|
||||
// an eliminated player (eliminate() zeroed funds and pendingFunds; startRound pays the seats still in only)
|
||||
assert.equal(round({ alive: false, spectator: false }).sub, '观战中');
|
||||
// a spectator seat (no seat, no funds), also when only `spectator` is given
|
||||
assert.equal(round({ alive: false, spectator: true }).sub, '观战中');
|
||||
assert.equal(round({ spectator: true }).sub, '观战中');
|
||||
// the title and the other phases' copy are the same for every viewer
|
||||
for (const v of [{ alive: true }, { alive: false }, { alive: false, spectator: true }]) {
|
||||
assert.equal(round(v).title, '第 2 回合');
|
||||
assert.equal(phaseBanner(PHASE.PREP, pub, v).sub, phaseBanner(PHASE.PREP, pub).sub);
|
||||
}
|
||||
// the match screen hands the banner its viewer (screens/game.js `alive` folds a spectator seat in)
|
||||
const src = readFileSync(path.join(ROOT, 'public/js/screens/game.js'), 'utf8');
|
||||
assert.match(src, /phaseBanner\(phase, pub, \{ alive, spectator \}\)/);
|
||||
});
|
||||
});
|
||||
|
||||
describe('countdown', () => {
|
||||
|
||||
Reference in new issue
Block a user