mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-21 06:25:56 +00:00
reduce train gold after each city (#3400)
## Description: Now that cities snap to existing rails, it's possible to line up dozens of cities in a row, producing way too much gold. This PR reduces the gold after each stop to prevent that. Gold only starts decreasing after the 3rd city. ## 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: evan
This commit is contained in:
@@ -132,7 +132,10 @@ export interface Config {
|
||||
tradeShipSpawnRejections: number,
|
||||
numTradeShips: number,
|
||||
): number;
|
||||
trainGold(rel: "self" | "team" | "ally" | "other"): Gold;
|
||||
trainGold(
|
||||
rel: "self" | "team" | "ally" | "other",
|
||||
citiesVisited: number,
|
||||
): Gold;
|
||||
trainSpawnRate(numPlayerFactories: number): number;
|
||||
trainStationMinRange(): number;
|
||||
trainStationMaxRange(): number;
|
||||
|
||||
@@ -20,7 +20,7 @@ import { PlayerView } from "../game/GameView";
|
||||
import { UserSettings } from "../game/UserSettings";
|
||||
import { GameConfig, GameID, TeamCountConfig } from "../Schemas";
|
||||
import { NukeType } from "../StatsSchemas";
|
||||
import { assertNever, sigmoid, simpleHash, within } from "../Util";
|
||||
import { assertNever, sigmoid, simpleHash, toInt, within } from "../Util";
|
||||
import { Config, GameEnv, NukeMagnitude, ServerConfig, Theme } from "./Config";
|
||||
import { Env } from "./Env";
|
||||
import { PastelTheme } from "./PastelTheme";
|
||||
@@ -273,22 +273,28 @@ export class DefaultConfig implements Config {
|
||||
// expected number of trains = numPlayerFactories / trainSpawnRate(numPlayerFactories)
|
||||
return (numPlayerFactories + 10) * 18;
|
||||
}
|
||||
trainGold(rel: "self" | "team" | "ally" | "other"): Gold {
|
||||
const multiplier = this.goldMultiplier();
|
||||
let baseGold: bigint;
|
||||
trainGold(
|
||||
rel: "self" | "team" | "ally" | "other",
|
||||
citiesVisited: number,
|
||||
): Gold {
|
||||
// No penalty for the first 3 cities.
|
||||
citiesVisited = Math.max(0, citiesVisited - 2);
|
||||
let baseGold: number;
|
||||
switch (rel) {
|
||||
case "ally":
|
||||
baseGold = 35_000n;
|
||||
baseGold = 35_000;
|
||||
break;
|
||||
case "team":
|
||||
case "other":
|
||||
baseGold = 25_000n;
|
||||
baseGold = 25_000;
|
||||
break;
|
||||
case "self":
|
||||
baseGold = 10_000n;
|
||||
baseGold = 10_000;
|
||||
break;
|
||||
}
|
||||
return BigInt(Math.floor(Number(baseGold) * multiplier));
|
||||
const distPenalty = citiesVisited * 5_000;
|
||||
const gold = Math.max(5000, baseGold - distPenalty);
|
||||
return toInt(gold * this.goldMultiplier());
|
||||
}
|
||||
|
||||
trainStationMinRange(): number {
|
||||
|
||||
@@ -24,6 +24,7 @@ export class TrainExecution implements Execution {
|
||||
private stations: TrainStation[] = [];
|
||||
private currentRailroad: OrientedRailroad | null = null;
|
||||
private speed: number = 2;
|
||||
private _tradeStopsVisited: number = 0;
|
||||
|
||||
constructor(
|
||||
private railNetwork: RailNetwork,
|
||||
@@ -37,6 +38,10 @@ export class TrainExecution implements Execution {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public tradeStopsVisited(): number {
|
||||
return this._tradeStopsVisited;
|
||||
}
|
||||
|
||||
init(mg: Game, ticks: number): void {
|
||||
this.mg = mg;
|
||||
const stations = this.railNetwork.findStationsPath(
|
||||
@@ -261,6 +266,10 @@ export class TrainExecution implements Execution {
|
||||
throw new Error("Not initialized");
|
||||
}
|
||||
this.stations[1].onTrainStop(this);
|
||||
const stationType = this.stations[1].unit.type();
|
||||
if (stationType === UnitType.City || stationType === UnitType.Port) {
|
||||
this._tradeStopsVisited++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -697,7 +697,10 @@ export class NationStructureBehavior {
|
||||
unitToCluster.set(station.unit, station.getCluster());
|
||||
}
|
||||
|
||||
const maxTradeGold = Math.max(Number(game.config().trainGold("ally")), 1);
|
||||
const maxTradeGold = Math.max(
|
||||
Number(game.config().trainGold("ally", 0)),
|
||||
1,
|
||||
);
|
||||
const result: Array<{
|
||||
tile: TileRef;
|
||||
cluster: Cluster | null;
|
||||
@@ -705,7 +708,8 @@ export class NationStructureBehavior {
|
||||
}> = [];
|
||||
|
||||
// Own structures — weighted by "self" trade gold.
|
||||
const selfWeight = Number(game.config().trainGold("self")) / maxTradeGold;
|
||||
const selfWeight =
|
||||
Number(game.config().trainGold("self", 0)) / maxTradeGold;
|
||||
for (const unit of player.units(
|
||||
UnitType.City,
|
||||
UnitType.Port,
|
||||
@@ -730,7 +734,7 @@ export class NationStructureBehavior {
|
||||
: player.isAlliedWith(neighbor)
|
||||
? "ally"
|
||||
: "other";
|
||||
const weight = Number(game.config().trainGold(relType)) / maxTradeGold;
|
||||
const weight = Number(game.config().trainGold(relType, 0)) / maxTradeGold;
|
||||
for (const unit of neighbor.units(
|
||||
UnitType.City,
|
||||
UnitType.Port,
|
||||
|
||||
@@ -20,7 +20,12 @@ class TradeStationStopHandler implements TrainStopHandler {
|
||||
): void {
|
||||
const stationOwner = station.unit.owner();
|
||||
const trainOwner = trainExecution.owner();
|
||||
const gold = mg.config().trainGold(rel(trainOwner, stationOwner));
|
||||
const gold = mg
|
||||
.config()
|
||||
.trainGold(
|
||||
rel(trainOwner, stationOwner),
|
||||
trainExecution.tradeStopsVisited(),
|
||||
);
|
||||
// Share revenue with the station owner if it's not the current player
|
||||
if (trainOwner !== stationOwner) {
|
||||
stationOwner.addGold(gold, station.tile());
|
||||
|
||||
Reference in New Issue
Block a user