Fix betrayals for Nations always 0 on Player Info Panel (#2334)

## Description:

Betrayal count in PlayerUpdates came from stats. But stats are only kept
for players with ClientID aka real humans. So betrayals stayed 0 for
Nations even after betraying others. This PR fixes it by keeping a
seperate betrayal count for PlayerUpdates while stats are still being
kept to go in the database.

See bug report
https://discord.com/channels/1284581928254701718/1432759837560799403

After:
<img width="642" height="337" alt="image"
src="https://github.com/user-attachments/assets/1b8bcfa1-aadd-4bea-8a5f-7fa9f2c9111f"
/>


## 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:

tryout33
This commit is contained in:
VariableVince
2025-10-31 19:31:18 +01:00
committed by GitHub
parent 320a494ff4
commit d9ea9fd432
4 changed files with 12 additions and 9 deletions
+1
View File
@@ -607,6 +607,7 @@ export interface Player {
canSendAllianceRequest(other: Player): boolean;
breakAlliance(alliance: Alliance): void;
createAllianceRequest(recipient: Player): AllianceRequest | null;
betrayals(): number;
// Targeting
canTarget(other: Player): boolean;
+1 -1
View File
@@ -169,7 +169,7 @@ export interface PlayerUpdate {
outgoingAllianceRequests: PlayerID[];
alliances: AllianceView[];
hasSpawned: boolean;
betrayals?: bigint;
betrayals: number;
lastDeleteUnitTick: Tick;
}
+8 -3
View File
@@ -71,6 +71,7 @@ export class PlayerImpl implements Player {
private _troops: bigint;
markedTraitorTick = -1;
private _betrayalCount: number = 0;
private embargoes = new Map<PlayerID, Embargo>();
@@ -123,7 +124,6 @@ export class PlayerImpl implements Player {
const outgoingAllianceRequests = this.outgoingAllianceRequests().map((ar) =>
ar.recipient().id(),
);
const stats = this.mg.stats().getPlayerStats(this);
return {
type: GameUpdateType.Player,
@@ -174,7 +174,7 @@ export class PlayerImpl implements Player {
}) satisfies AllianceView,
),
hasSpawned: this.hasSpawned(),
betrayals: stats?.betrayals,
betrayals: this._betrayalCount,
lastDeleteUnitTick: this.lastDeleteUnitTick,
};
}
@@ -441,11 +441,16 @@ export class PlayerImpl implements Player {
markTraitor(): void {
this.markedTraitorTick = this.mg.ticks();
this._betrayalCount++; // Keep count for FakeHumans too
// Record stats
// Record stats (only for real Humans)
this.mg.stats().betray(this);
}
betrayals(): number {
return this._betrayalCount;
}
createAllianceRequest(recipient: Player): AllianceRequest | null {
if (this.isAlliedWith(recipient)) {
throw new Error(`cannot create alliance request, already allies`);
+2 -5
View File
@@ -74,11 +74,8 @@ export class StatsImpl implements Stats {
private _addBetrayal(player: Player, value: BigIntLike) {
const data = this._makePlayerStats(player);
if (data === undefined) return;
if (data.betrayals === undefined) {
data.betrayals = _bigint(value);
} else {
data.betrayals += _bigint(value);
}
data.betrayals ??= 0n;
data.betrayals += _bigint(value);
}
private _addBoat(