feedback7 UIBACK: the top-bar capsule counts like the official — resolved = killed + leaked among the enemies the round scheduled (opening 0/3, a leak 1/3, a kill 2/3, the splitter 3/3); a split child, a summon and a boss summon are in neither number but still cost LP and break 完美作战 (PR #308 by @xcdoge, the capsule half of PR #157 — authored by them: the sim / protocol / HUD hunks applied as reviewed): inTotal / killedInTotal / leakedInTotal / resolved, b.snap / BattleResult / b.progress (optional field) / m.public progress carry resolved, killed may exceed total (validation bounds it by the content-spawn allowance); dropped the PR's stray design-doc line — it had replaced the S→C b.end bullet of docs/design/network.md, which is back; the 联防 live-counter change mark follows the enemy list now that a spawn no longer moves total (uniteLeftMark + test); golden: only total / players.*.total / snaps move, outcomes bit-identical — roster 23 (roster-002 003 007 008 009 010 011 012 013 015 017 018 020 023 024 025 026 027 037 045 047 048 049), bonds 2 (bond-maniShip-low, bond-soloShip-high), fields 11 (boss-boss_1 3 5 pair+solo, boss-boss_6-solo, hidden-boss_8 10 pair+solo), diy 11 (diy-036 040 056 062 068 073 083 091 095 114 115), matches 12 (solo-FUNNY-1 NORMAL-1 HARD-1 ABYSS-1 ABYSS-2, coop2-NORMAL-3 coop2-HARD-4 coop3-ABYSS-5 coop4-ABYSS-7 coop2-NORMAL-8-serverrun solo-HARD-9-boosted coop2-NORMAL-70-diy: the total column of 36 round rows), standins unchanged

This commit is contained in:
xcdoge authored and sganggs committed 2026-10-08 19:30:36 +08:00
1 parent d7c665dbf6
commit b4bc89ad4e
39 files changed
+836 -252

No files matched your search

+5 -2
View File
@@ -121,7 +121,7 @@ export class BattleLifecycle {
this.finished = true;
this.reason = reason === 'timeout' ? 'timeout' : 'forced';
this._endReq = null;
try { this._result = this._buildResult(); } catch { this._result = { time: this.time, reason: this.reason, perPlayer: {}, killed: this.killed, total: this.total, errors: this.errorCount }; }
try { this._result = this._buildResult(); } catch { this._result = { time: this.time, reason: this.reason, perPlayer: {}, killed: this.killed, total: this.total, resolved: this.resolved, errors: this.errorCount }; }
this.projectiles.clear();
}
@@ -209,6 +209,9 @@ export class BattleLifecycle {
for (const ps of this.players) {
const pp = this._perPlayer[ps.playerId];
pp.perfect = !pp.leaked.some((l) => l.counted !== false);
// the HUD capsule's numerator of this field (DESIGN §14): this player's own scheduled enemies resolved — knocked
// down or leaked (`counted` keeps the LP / 完美作战 reading, runtime splits and summons included)
pp.resolved = Math.min(pp.total, pp.killedInTotal + pp.leakedInTotal);
// the operators and the board's summon pieces (a board uid): 联防 carries an operator's HP ratio and SP, a summon's
// SP only (match/unite.js). `sp` is the official 技力 — stored charges included (PRTS 技能 "可充能X次…当前技力上限等于该
// 技能技力需求的X倍"); a running skill spent its SP at activation, so it reports what was left (0 for one charge).
@@ -226,7 +229,7 @@ export class BattleLifecycle {
}));
perPlayer[ps.playerId] = pp;
}
const res = { time: Math.round(this.time * 1000) / 1000, reason: this.reason, perPlayer, killed: this.killed, total: this.total, errors: this.errorCount };
const res = { time: Math.round(this.time * 1000) / 1000, reason: this.reason, perPlayer, killed: this.killed, total: this.total, resolved: this.resolved, errors: this.errorCount };
if (this.unspawned && this.unspawned.length) res.unspawned = this.unspawned;
if (this.sharedBoss) res.bossHpLeft = Math.max(0, this.sharedBoss.hp);
return res;