Use bigint for gold (#1000)

## Description:

- Switch gold to bigint.
- Remove unused or untrusted values from event payloads.

## 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
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

---------

Co-authored-by: Scott Anderson <662325+scottanderson@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Scott Anderson
2025-06-02 12:48:45 -07:00
committed by evanpelle
co-authored by Scott Anderson coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
parent 378c8a093f
commit 374504f426
19 changed files with 125 additions and 100 deletions
+60 -47
View File
@@ -262,7 +262,7 @@ export class DefaultConfig implements Config {
return this._gameConfig.infiniteTroops;
}
tradeShipGold(dist: number): Gold {
return 10000 + 150 * Math.pow(dist, 1.1);
return BigInt(Math.floor(10000 + 150 * Math.pow(dist, 1.1)));
}
tradeShipSpawnRate(numberOfPorts: number): number {
return Math.min(50, Math.round(10 * Math.pow(numberOfPorts, 0.6)));
@@ -272,44 +272,49 @@ export class DefaultConfig implements Config {
switch (type) {
case UnitType.TransportShip:
return {
cost: () => 0,
cost: () => 0n,
territoryBound: false,
};
case UnitType.Warship:
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: Math.min(
1_000_000,
(p.unitsIncludingConstruction(UnitType.Warship).length + 1) *
250_000,
? 0n
: BigInt(
Math.min(
1_000_000,
(p.unitsIncludingConstruction(UnitType.Warship).length +
1) *
250_000,
),
),
territoryBound: false,
maxHealth: 1000,
};
case UnitType.Shell:
return {
cost: () => 0,
cost: () => 0n,
territoryBound: false,
damage: 250,
};
case UnitType.SAMMissile:
return {
cost: () => 0,
cost: () => 0n,
territoryBound: false,
};
case UnitType.Port:
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: Math.min(
1_000_000,
Math.pow(
2,
p.unitsIncludingConstruction(UnitType.Port).length,
) * 125_000,
? 0n
: BigInt(
Math.min(
1_000_000,
Math.pow(
2,
p.unitsIncludingConstruction(UnitType.Port).length,
) * 125_000,
),
),
territoryBound: true,
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
@@ -317,41 +322,43 @@ export class DefaultConfig implements Config {
case UnitType.AtomBomb:
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold() ? 0 : 750_000,
p.type() === PlayerType.Human && this.infiniteGold()
? 0n
: 750_000n,
territoryBound: false,
};
case UnitType.HydrogenBomb:
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: 5_000_000,
? 0n
: 5_000_000n,
territoryBound: false,
};
case UnitType.MIRV:
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: 25_000_000,
? 0n
: 25_000_000n,
territoryBound: false,
};
case UnitType.MIRVWarhead:
return {
cost: () => 0,
cost: () => 0n,
territoryBound: false,
};
case UnitType.TradeShip:
return {
cost: () => 0,
cost: () => 0n,
territoryBound: false,
};
case UnitType.MissileSilo:
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: 1_000_000,
? 0n
: 1_000_000n,
territoryBound: true,
constructionDuration: this.instantBuild() ? 0 : 10 * 10,
};
@@ -359,12 +366,14 @@ export class DefaultConfig implements Config {
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: Math.min(
250_000,
(p.unitsIncludingConstruction(UnitType.DefensePost).length +
1) *
50_000,
? 0n
: BigInt(
Math.min(
250_000,
(p.unitsIncludingConstruction(UnitType.DefensePost).length +
1) *
50_000,
),
),
territoryBound: true,
constructionDuration: this.instantBuild() ? 0 : 5 * 10,
@@ -373,12 +382,14 @@ export class DefaultConfig implements Config {
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: Math.min(
3_000_000,
(p.unitsIncludingConstruction(UnitType.SAMLauncher).length +
1) *
1_500_000,
? 0n
: BigInt(
Math.min(
3_000_000,
(p.unitsIncludingConstruction(UnitType.SAMLauncher).length +
1) *
1_500_000,
),
),
territoryBound: true,
constructionDuration: this.instantBuild() ? 0 : 30 * 10,
@@ -387,20 +398,22 @@ export class DefaultConfig implements Config {
return {
cost: (p: Player) =>
p.type() === PlayerType.Human && this.infiniteGold()
? 0
: Math.min(
1_000_000,
Math.pow(
2,
p.unitsIncludingConstruction(UnitType.City).length,
) * 125_000,
? 0n
: BigInt(
Math.min(
1_000_000,
Math.pow(
2,
p.unitsIncludingConstruction(UnitType.City).length,
) * 125_000,
),
),
territoryBound: true,
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
};
case UnitType.Construction:
return {
cost: () => 0,
cost: () => 0n,
territoryBound: true,
};
default:
@@ -676,8 +689,8 @@ export class DefaultConfig implements Config {
return Math.min(player.population() + toAdd, max) - player.population();
}
goldAdditionRate(player: Player): number {
return 0.045 * player.workers() ** 0.7;
goldAdditionRate(player: Player): Gold {
return BigInt(Math.floor(0.045 * player.workers() ** 0.7));
}
troopAdjustmentRate(player: Player): number {