Record player deaths (#2102)

## Description:

Record player death ticks and "conquests" (when a player has < 100
tiles).
Tournaments would be easier to manage with those information.

Related infra PR: https://github.com/openfrontio/infra/pull/196

Tested locally with docker/infra repo

## 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
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

IngloriousTom
This commit is contained in:
DevelopingTom
2025-09-28 00:52:50 +02:00
committed by GitHub
parent 0843f99b5b
commit c2cf2ce65f
5 changed files with 51 additions and 1 deletions
+2
View File
@@ -99,6 +99,8 @@ export const PlayerStatsSchema = z
.object({
attacks: AtLeastOneNumberSchema.optional(),
betrayals: BigIntStringSchema.optional(),
killedAt: BigIntStringSchema.optional(),
conquests: BigIntStringSchema.optional(),
boats: z.partialRecord(BoatUnitSchema, AtLeastOneNumberSchema).optional(),
bombs: z.partialRecord(BombUnitSchema, AtLeastOneNumberSchema).optional(),
gold: AtLeastOneNumberSchema.optional(),
+1
View File
@@ -55,6 +55,7 @@ export class PlayerExecution implements Execution {
}
});
this.active = false;
this.mg.stats().playerKilled(this.player, ticks);
return;
}
+3
View File
@@ -93,4 +93,7 @@ export interface Stats {
// Player loses a unit of type
unitLose(player: Player, type: OtherUnitType): void;
// player was killed (0 tiles)
playerKilled(player: Player, tick: number): void;
}
+21
View File
@@ -133,6 +133,22 @@ export class StatsImpl implements Stats {
p.units[type][index] += _bigint(value);
}
private _addConquest(player: Player) {
const p = this._makePlayerStats(player);
if (p === undefined) return;
if (p.conquests === undefined) {
p.conquests = _bigint(1);
} else {
p.conquests += _bigint(1);
}
}
private _addPlayerKilled(player: Player, tick: number) {
const p = this._makePlayerStats(player);
if (p === undefined) return;
p.killedAt = _bigint(tick);
}
attack(
player: Player,
target: Player | TerraNullius,
@@ -225,6 +241,7 @@ export class StatsImpl implements Stats {
goldWar(player: Player, captured: Player, gold: BigIntLike): void {
this._addGold(player, GOLD_INDEX_WAR, gold);
this._addConquest(player);
}
unitBuild(player: Player, type: OtherUnitType): void {
@@ -246,4 +263,8 @@ export class StatsImpl implements Stats {
unitLose(player: Player, type: OtherUnitType): void {
this._addOtherUnit(player, type, OTHER_INDEX_LOST, 1);
}
playerKilled(player: Player, tick: number): void {
this._addPlayerKilled(player, tick);
}
}
+24 -1
View File
@@ -160,7 +160,17 @@ describe("Stats", () => {
test("goldWar", () => {
stats.goldWar(player1, player2, 1);
expect(stats.stats()).toStrictEqual({
client1: { gold: [0n, 1n] },
client1: {
gold: [0n, 1n],
conquests: 1n,
},
});
stats.goldWar(player1, player2, 1);
expect(stats.stats()).toStrictEqual({
client1: {
gold: [0n, 2n],
conquests: 2n,
},
});
});
@@ -211,6 +221,19 @@ describe("Stats", () => {
});
});
test("playerKilled", () => {
stats.playerKilled(player1, 10);
stats.playerKilled(player2, 40);
expect(stats.stats()).toStrictEqual({
client1: {
killedAt: 10n,
},
client2: {
killedAt: 40n,
},
});
});
test("stringify", () => {
stats.unitLose(player1, UnitType.Port);
expect(JSON.stringify(stats.stats(), replacer)).toBe(