Feature: Allow stations and roadstops under bridges.

Bridges above stations will have pillars excluded if they conflict with the station layout.

Partly based on the system implemented in JGRPP.

Co-authored-by: <su@angel-island.zone>
This commit is contained in:
Peter Nelson
2025-08-14 19:35:33 +01:00
committed by Peter Nelson
parent 6d6e64b1f0
commit 9a294ab2ed
6 changed files with 244 additions and 31 deletions

View File

@@ -175,14 +175,14 @@ static CommandCost IsValidTileForWaypoint(TileIndex tile, Axis axis, StationID *
return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
}
if (IsBridgeAbove(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
return CommandCost();
}
extern CommandCost FindJoiningWaypoint(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Waypoint **wp, bool is_road);
extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta);
extern CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost);
extern CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, const RoadStopSpec *roadstopspec, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost);
extern CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *spec, StationType type, StationGfx layout);
extern CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlags flags, int replacement_spec_index);
/**
@@ -231,12 +231,19 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
StationID est = StationID::Invalid();
const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index);
RailStationTileLayout stl{spec, count, 1};
auto it = stl.begin();
/* Check whether the tiles we're building on are valid rail or not. */
TileIndexDiff offset = TileOffsByAxis(OtherAxis(axis));
for (int i = 0; i < count; i++) {
TileIndex tile = start_tile + i * offset;
CommandCost ret = IsValidTileForWaypoint(tile, axis, &est);
if (ret.Failed()) return ret;
ret = IsRailStationBridgeAboveOk(tile, spec, StationType::RailWaypoint, *it++);
if (ret.Failed()) return ret;
}
Waypoint *wp = nullptr;
@@ -264,7 +271,6 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
if (!Waypoint::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_STATIONS_LOADING);
}
const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index);
auto specindex = AllocateSpecToStation(spec, wp, flags.Test(DoCommandFlag::Execute));
if (!specindex.has_value()) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS);
@@ -289,7 +295,6 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
wp->UpdateVirtCoord();
RailStationTileLayout stl{spec, count, 1};
auto it = stl.begin();
Company *c = Company::Get(wp->owner);
@@ -363,7 +368,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
unit_cost = _price[PR_BUILD_STATION_TRUCK];
}
StationID est = StationID::Invalid();
CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, true, StationType::RoadWaypoint, axis, AxisToDiagDir(axis), &est, INVALID_ROADTYPE, unit_cost);
CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, true, StationType::RoadWaypoint, roadstopspec, axis, AxisToDiagDir(axis), &est, INVALID_ROADTYPE, unit_cost);
if (cost.Failed()) return cost;
Waypoint *wp = nullptr;