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
+14
-3
@@ -264,7 +264,9 @@ export function uniteLeft(battle) {
|
||||
/**
|
||||
* Progress numbers of a battle for b.progress / the teammates' waiting UI: game time, kills, total, the capsule's
|
||||
* `resolved` (this field's own scheduled enemies knocked out or leaked — Battle.resolved), counted leaks
|
||||
* (normal / unite), the boss pool damage of this field and — unite fields — `left` (uniteLeft: each leaker's enemies
|
||||
* (normal / unite), the boss pool damage of this field, `leaksBy` of a boss / hidden field — per player, the LP the
|
||||
* enemies that reached its goal cost (every leak entry the result will show, × its `lpr`; the field's LP meter minus
|
||||
* their sum is the leader's own "扣除目标生命" effects) — and, unite fields, `left` (uniteLeft: each leaker's enemies
|
||||
* still standing).
|
||||
*/
|
||||
export function battleProgress(battle) {
|
||||
@@ -290,6 +292,11 @@ export function battleProgress(battle) {
|
||||
const left = uniteLeft(battle);
|
||||
if (left) out.left = left;
|
||||
}
|
||||
if (battle && (battle.kind === 'boss' || battle.kind === 'hidden')) {
|
||||
const leaksBy = {};
|
||||
for (const pid of Object.keys(pp).slice(0, 4)) leaksBy[pid] = Math.min(1e6, leakEntries(pp[pid]).reduce((n, l) => n + leakLpr(l), 0));
|
||||
out.leaksBy = leaksBy;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -335,6 +342,10 @@ const cap = (list, n) => (Array.isArray(list) ? list.slice(0, n) : []);
|
||||
const isKey = (v) => typeof v === 'string' && v.length > 0 && v.length <= 64 && /^[A-Za-z0-9_\-.:]+$/.test(v);
|
||||
const uidOr = (v) => (Number.isInteger(v) && v >= 1 && v <= 0x80000000 ? v : null);
|
||||
const keyOr = (v) => (isKey(v) ? v : null);
|
||||
/** A player's leak entries as the b.result carries them (compactResult: a valid enemy key, at most 400). */
|
||||
const leakEntries = (p) => cap(p && p.leaked, 400).filter((l) => l && isKey(l.enemyKey));
|
||||
/** What one leak entry costs the team on the wire: its `lpr` (0 … 1000), 1 when absent. */
|
||||
const leakLpr = (l) => Math.max(0, Math.min(1000, fnum(l && l.lpr, 1)));
|
||||
|
||||
function compactMods(m) {
|
||||
if (!m || typeof m !== 'object') return null;
|
||||
@@ -365,8 +376,8 @@ export function compactResult(res) {
|
||||
// NOT clamped to `total`: the denominator counts only the round's own scheduled enemies (Battle.resolved)
|
||||
killed: Math.max(0, Math.trunc(fnum(p.killed))),
|
||||
total,
|
||||
leaked: cap(p.leaked, 400).filter((l) => l && isKey(l.enemyKey)).map((l) => {
|
||||
const o = { enemyKey: l.enemyKey, mods: compactMods(l.mods), lpr: Math.max(0, Math.min(1000, fnum(l.lpr, 1))), sourcePlayerId: keyOr(l.sourcePlayerId), tag: typeof l.tag === 'string' && l.tag.length <= 16 ? l.tag : null, counted: l.counted !== false };
|
||||
leaked: leakEntries(p).map((l) => {
|
||||
const o = { enemyKey: l.enemyKey, mods: compactMods(l.mods), lpr: leakLpr(l), sourcePlayerId: keyOr(l.sourcePlayerId), tag: typeof l.tag === 'string' && l.tag.length <= 16 ? l.tag : null, counted: l.counted !== false };
|
||||
if (l.boss) o.boss = true;
|
||||
if (l.spawned) o.spawned = true;
|
||||
return o;
|
||||
|
||||
Reference in new issue
Block a user