mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-23 22:05:24 +00:00
feat(livestats): per-player killedBy + deathPosition + winner for live standings (#4593)
## Description: Enriches the admin-bot live-stats snapshot (`/api/adminbot/game/:id/stats`) with the per-player fields a semi-live standings board needs, so it can score kills + placement live instead of waiting for the post-game record. Per player in `liveStats.players[]`: - **`killedBy`** — the eliminator's clientID (null while alive / non-client killer). Invert → live kill points. - **`deathPosition`** — finishing place at elimination = non-bot players still standing + 1 (frozen at "last of the then-standing"). Null while alive → live placement. The **full roster** is reported (dead players are retained in the client view), plus top-level **`winner`** (the decided winner's clientID, else null). Deterministic / consensus-safe: `killedBy` (stamped at `recordKill`) and `deathPosition` (stamped in `PlayerExecution`) are pure sim values, so in-sync clients agree on the majority vote; `winner` is added server-side in `GameServer.liveStats()` from the winner vote (like the existing publicID/username/connected enrichment). ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory
This commit is contained in:
@@ -52,6 +52,8 @@ export class LiveStatsController implements Controller {
|
||||
gold: p.gold().toString(),
|
||||
isAlive: p.isAlive(),
|
||||
team: p.team(),
|
||||
killedBy: p.killedBy(),
|
||||
deathPosition: p.deathPosition(),
|
||||
},
|
||||
];
|
||||
})
|
||||
|
||||
@@ -59,6 +59,8 @@ export interface PlayerState {
|
||||
smallID: number;
|
||||
isAlive: boolean;
|
||||
isDisconnected: boolean;
|
||||
killedBy: string | null;
|
||||
deathPosition: number | null;
|
||||
tilesOwned: number;
|
||||
gold: number;
|
||||
troops: number;
|
||||
|
||||
@@ -76,6 +76,8 @@ function stateFromUpdate(pu: PlayerUpdate): PlayerState {
|
||||
smallID: pu.smallID!,
|
||||
isAlive: pu.isAlive!,
|
||||
isDisconnected: pu.isDisconnected!,
|
||||
killedBy: pu.killedBy ?? null,
|
||||
deathPosition: pu.deathPosition ?? null,
|
||||
tilesOwned: pu.tilesOwned!,
|
||||
gold: Number(pu.gold!),
|
||||
troops: pu.troops!,
|
||||
@@ -454,6 +456,12 @@ export class PlayerView {
|
||||
isAlive(): boolean {
|
||||
return this.state.isAlive;
|
||||
}
|
||||
killedBy(): string | null {
|
||||
return this.state.killedBy;
|
||||
}
|
||||
deathPosition(): number | null {
|
||||
return this.state.deathPosition;
|
||||
}
|
||||
isPlayer(): this is PlayerView {
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user