mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:10:42 +00:00
Allow railroad loops (#1274)
## Description: This change enables loop formation in the station network, allowing for enhanced connectivity. However, it can sometimes result in clustered areas as a trade-off. To mitigate excessive clustering, loops are only permitted when there are at least 5 intermediary stations between the source and destination stations.  Also a few fixes for `.dev` players. ## 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
This commit is contained in:
@@ -246,7 +246,10 @@ export class UnitInfoModal extends LitElement implements Layer {
|
||||
class="upgrade-button"
|
||||
title="${translateText("unit_info_modal.create_station")}"
|
||||
style="width: 100px; height: 32px;
|
||||
display: ${this.unit.hasTrainStation() ? "none" : "block"};"
|
||||
display: ${this.unit.hasTrainStation() ||
|
||||
!this.game.unitInfo(this.unit.type()).canBuildTrainStation
|
||||
? "none"
|
||||
: "block"};"
|
||||
>
|
||||
${translateText("unit_info_modal.create_station")}
|
||||
</button>
|
||||
|
||||
@@ -302,7 +302,7 @@ export class DefaultConfig implements Config {
|
||||
return Math.min(50, Math.round(10 * Math.pow(numberOfPorts, 0.6)));
|
||||
}
|
||||
trainSpawnRate(numberOfStations: number): number {
|
||||
return Math.round(50 * Math.pow(numberOfStations, 0.8));
|
||||
return Math.min(1400, Math.round(60 * Math.pow(numberOfStations, 0.8)));
|
||||
}
|
||||
trainGold(): Gold {
|
||||
return BigInt(10_000);
|
||||
@@ -363,6 +363,7 @@ export class DefaultConfig implements Config {
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
canBuildTrainStation: true,
|
||||
};
|
||||
case UnitType.AtomBomb:
|
||||
return {
|
||||
@@ -452,6 +453,7 @@ export class DefaultConfig implements Config {
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
upgradable: true,
|
||||
canBuildTrainStation: true,
|
||||
};
|
||||
case UnitType.Factory:
|
||||
return {
|
||||
@@ -466,6 +468,7 @@ export class DefaultConfig implements Config {
|
||||
),
|
||||
territoryBound: true,
|
||||
constructionDuration: this.instantBuild() ? 0 : 2 * 10,
|
||||
canBuildTrainStation: true,
|
||||
};
|
||||
case UnitType.Construction:
|
||||
return {
|
||||
|
||||
@@ -132,6 +132,7 @@ export interface UnitInfo {
|
||||
damage?: number;
|
||||
constructionDuration?: number;
|
||||
upgradable?: boolean;
|
||||
canBuildTrainStation?: boolean;
|
||||
}
|
||||
|
||||
export enum UnitType {
|
||||
|
||||
@@ -88,6 +88,8 @@ export function createRailNetwork(game: Game): RailNetwork {
|
||||
}
|
||||
|
||||
export class RailNetworkImpl implements RailNetwork {
|
||||
private maxConnectionDistance: number = 4;
|
||||
|
||||
constructor(
|
||||
private game: Game,
|
||||
private stationManager: StationManager,
|
||||
@@ -142,12 +144,20 @@ export class RailNetworkImpl implements RailNetwork {
|
||||
const neighborStation = this.stationManager.findStation(neighbor.unit);
|
||||
if (!neighborStation) continue;
|
||||
|
||||
const neighborCluster = neighborStation.getCluster();
|
||||
if (!neighborCluster || neighborCluster.has(station)) continue;
|
||||
const distanceToStation = this.distanceFrom(
|
||||
neighborStation,
|
||||
station,
|
||||
this.maxConnectionDistance,
|
||||
);
|
||||
|
||||
const neighborCluster = neighborStation.getCluster();
|
||||
if (neighborCluster === null) continue;
|
||||
const connectionAvailable =
|
||||
distanceToStation > this.maxConnectionDistance ||
|
||||
distanceToStation === -1;
|
||||
if (
|
||||
neighbor.distSquared >
|
||||
this.game.config().trainStationMinRange() ** 2
|
||||
connectionAvailable &&
|
||||
neighbor.distSquared > this.game.config().trainStationMinRange() ** 2
|
||||
) {
|
||||
if (this.connect(station, neighborStation)) {
|
||||
neighborCluster.addStation(station);
|
||||
@@ -196,6 +206,37 @@ export class RailNetworkImpl implements RailNetwork {
|
||||
return false;
|
||||
}
|
||||
|
||||
private distanceFrom(
|
||||
start: TrainStation,
|
||||
dest: TrainStation,
|
||||
maxDistance: number,
|
||||
): number {
|
||||
if (start === dest) return 0;
|
||||
|
||||
const visited = new Set<TrainStation>();
|
||||
const queue: Array<{ station: TrainStation; distance: number }> = [
|
||||
{ station: start, distance: 0 },
|
||||
];
|
||||
|
||||
while (queue.length > 0) {
|
||||
const { station, distance } = queue.shift()!;
|
||||
if (visited.has(station)) continue;
|
||||
visited.add(station);
|
||||
|
||||
if (distance >= maxDistance) continue;
|
||||
|
||||
for (const neighbor of station.neighbors()) {
|
||||
if (neighbor === dest) return distance + 1;
|
||||
if (!visited.has(neighbor)) {
|
||||
queue.push({ station: neighbor, distance: distance + 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If destination not found within maxDistance
|
||||
return -1;
|
||||
}
|
||||
|
||||
private computeCluster(start: TrainStation): Set<TrainStation> {
|
||||
const visited = new Set<TrainStation>();
|
||||
const queue = [start];
|
||||
|
||||
Reference in New Issue
Block a user