Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions resources/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,8 @@
"attack_cancelled_retreat": "Attack cancelled, {troops} soldiers killed during retreat",
"received_gold_from_captured_ship": "Received {gold} gold from ship captured from {name}",
"received_gold_from_trade": "Received {gold} gold from trade with {name}",
"received_gold_from_conquest": "Conquered {name}, received {gold} gold",
"conquered_no_gold": "Conquered {name} (didn't play, no gold awarded)",
"missile_intercepted": "Missile intercepted {unit}",
"mirv_warheads_intercepted": "{count, plural, one {{count} MIRV warhead intercepted} other {{count} MIRV warheads intercepted}}",
"sent_troops_to_player": "Sent {troops} troops to {name}",
Expand Down
49 changes: 36 additions & 13 deletions src/core/game/GameImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { AStarWaterHierarchical } from "../pathfinding/algorithms/AStar.WaterHierarchical";
import { PathFinder } from "../pathfinding/types";
import { AllPlayersStats, ClientID, Winner } from "../Schemas";
import { ATTACK_INDEX_SENT } from "../StatsSchemas";
import { simpleHash } from "../Util";
import { AllianceImpl } from "./AllianceImpl";
import { AllianceRequestImpl } from "./AllianceRequestImpl";
Expand Down Expand Up @@ -1097,26 +1098,48 @@ export class GameImpl implements Game {
}
}

const gold = conquered.gold();
this.displayMessage(
`Conquered ${conquered.displayName()} received ${renderNumber(
// Don't transfer gold when the conquered player didn't play (never attacked anyone)
// This is especially important when starting gold is enabled
const stats = this._stats.getPlayerStats(conquered);
const attacksSent = stats?.attacks?.[ATTACK_INDEX_SENT] ?? 0n;
const skipGoldTransfer =
attacksSent === 0n && conquered.type() === PlayerType.Human;
const gold = skipGoldTransfer ? 0n : conquered.gold();

if (skipGoldTransfer) {
this.displayMessage(
"events_display.conquered_no_gold",
MessageType.CONQUERED_PLAYER,
conqueror.id(),
undefined,
{
name: conquered.displayName(),
},
);
} else {
this.displayMessage(
"events_display.received_gold_from_conquest",
MessageType.CONQUERED_PLAYER,
conqueror.id(),
gold,
)} gold`,
MessageType.CONQUERED_PLAYER,
conqueror.id(),
gold,
);
conqueror.addGold(gold);
conquered.removeGold(gold);
{
gold: renderNumber(gold),
name: conquered.displayName(),
},
);
conqueror.addGold(gold);
conquered.removeGold(gold);

// Record stats
this.stats().goldWar(conqueror, conquered, gold);
}

this.addUpdate({
type: GameUpdateType.ConquestEvent,
conquerorId: conqueror.id(),
conqueredId: conquered.id(),
gold,
});

// Record stats
this.stats().goldWar(conqueror, conquered, gold);
}
}

Expand Down
25 changes: 25 additions & 0 deletions tests/AttackStats.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,36 @@ describe("AttackStats", () => {

test("should increase war gold stat when a player is eliminated", () => {
expect(player1.sharesBorderWith(player2)).toBeTruthy();
// Player2 must attack to be considered active (otherwise gold won't transfer)
game.addExecution(
new AttackExecution(1, player2, game.terraNullius().id()),
);
game.executeNextTick();
performAttack(game, player1, player2);
expectWarGoldStatIsIncreasedAfterKill(game, player1, player2);
});

test("should NOT increase war gold stat when a inactive player is eliminated", () => {
expect(player1.sharesBorderWith(player2)).toBeTruthy();

const attackerStatsBefore = game.stats().stats()[player1.clientID()!];
const warGoldBefore = attackerStatsBefore?.gold?.[GOLD_INDEX_WAR] ?? 0n;

performAttack(game, player1, player2);

const attackerStatsAfter = game.stats().stats()[player1.clientID()!];
const warGoldAfter = attackerStatsAfter?.gold?.[GOLD_INDEX_WAR] ?? 0n;

expect(warGoldAfter).toBe(warGoldBefore);
});

test("should increase war gold stat when elimination occurs via territory annexation", () => {
// Player2 must attack to be considered active (otherwise gold won't transfer)
game.addExecution(
new AttackExecution(1, player2, game.terraNullius().id()),
);
game.executeNextTick();

// Mark every tile on the map as owned by player1
for (let x = 0; x < game.map().width(); x++) {
for (let y = 0; y < game.map().height(); y++) {
Expand Down
Loading