mirror of https://github.com/OpenTTD/OpenTTD.git
parent
6fcc8727f5
commit
eabb9db0bb
|
@ -1244,6 +1244,59 @@ static void RestoreTrainReservation(Train *v)
|
||||||
if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())), true);
|
if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates cost of new rail stations within the area.
|
||||||
|
* @param tile_area Area to check.
|
||||||
|
* @param flags Operation to perform.
|
||||||
|
* @param axis Rail station axis.
|
||||||
|
* @param station StationID to be queried and returned if available.
|
||||||
|
* @param rt The rail type to check for (overbuilding rail stations over rail).
|
||||||
|
* @param affected_vehicles List of trains with PBS reservations on the tiles
|
||||||
|
* @param spec_class Station class.
|
||||||
|
* @param spec_index Index into the station class.
|
||||||
|
* @param plat_len Platform length.
|
||||||
|
* @param numtracks Number of platforms.
|
||||||
|
* @return The cost in case of success, or an error code if it failed.
|
||||||
|
*/
|
||||||
|
static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, std::vector<Train *> &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks)
|
||||||
|
{
|
||||||
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
||||||
|
bool success = false;
|
||||||
|
bool length_price_ready = true;
|
||||||
|
byte tracknum = 0;
|
||||||
|
for (TileIndex cur_tile : tile_area) {
|
||||||
|
/* Clear the land below the station. */
|
||||||
|
CommandCost ret = CheckFlatLandRailStation(TileArea(cur_tile, 1, 1), flags, axis, station, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks);
|
||||||
|
if (ret.Failed()) return ret;
|
||||||
|
|
||||||
|
/* Only add _price[PR_BUILD_STATION_RAIL_LENGTH] once for each valid plat_len. */
|
||||||
|
if (tracknum == numtracks) {
|
||||||
|
length_price_ready = true;
|
||||||
|
tracknum = 0;
|
||||||
|
} else {
|
||||||
|
tracknum++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* AddCost for new or rotated rail stations. */
|
||||||
|
if (!IsRailStationTile(cur_tile) || (IsRailStationTile(cur_tile) && GetRailStationAxis(cur_tile) != axis)) {
|
||||||
|
|
||||||
|
cost.AddCost(ret);
|
||||||
|
cost.AddCost(_price[PR_BUILD_STATION_RAIL]);
|
||||||
|
cost.AddCost(RailBuildCost(rt));
|
||||||
|
|
||||||
|
if (length_price_ready) {
|
||||||
|
cost.AddCost(_price[PR_BUILD_STATION_RAIL_LENGTH]);
|
||||||
|
length_price_ready = false;
|
||||||
|
}
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) return_cmd_error(STR_ERROR_ALREADY_BUILT);
|
||||||
|
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build rail station
|
* Build rail station
|
||||||
* @param flags operation to perform
|
* @param flags operation to perform
|
||||||
|
@ -1294,12 +1347,9 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp
|
||||||
/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
|
/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
|
||||||
StationID est = INVALID_STATION;
|
StationID est = INVALID_STATION;
|
||||||
std::vector<Train *> affected_vehicles;
|
std::vector<Train *> affected_vehicles;
|
||||||
/* Clear the land below the station. */
|
/* Add construction and clearing expenses. */
|
||||||
CommandCost cost = CheckFlatLandRailStation(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks);
|
CommandCost cost = CalculateRailStationCost(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks);
|
||||||
if (cost.Failed()) return cost;
|
if (cost.Failed()) return cost;
|
||||||
/* Add construction expenses. */
|
|
||||||
cost.AddCost((numtracks * _price[PR_BUILD_STATION_RAIL] + _price[PR_BUILD_STATION_RAIL_LENGTH]) * plat_len);
|
|
||||||
cost.AddCost(numtracks * plat_len * RailBuildCost(rt));
|
|
||||||
|
|
||||||
Station *st = nullptr;
|
Station *st = nullptr;
|
||||||
ret = FindJoiningStation(est, station_to_join, adjacent, new_location, &st);
|
ret = FindJoiningStation(est, station_to_join, adjacent, new_location, &st);
|
||||||
|
@ -1811,6 +1861,54 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio
|
||||||
return FindJoiningBaseStation<Station, STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST>(existing_stop, station_to_join, adjacent, ta, st);
|
return FindJoiningBaseStation<Station, STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST>(existing_stop, station_to_join, adjacent, ta, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates cost of new road stops within the area.
|
||||||
|
* @param tile_area Area to check.
|
||||||
|
* @param flags Operation to perform.
|
||||||
|
* @param is_drive_through True if trying to build a drive-through station.
|
||||||
|
* @param is_truck_stop True when building a truck stop, false otherwise.
|
||||||
|
* @param axis Axis of a drive-through road stop.
|
||||||
|
* @param ddir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops.
|
||||||
|
* @param station StationID to be queried and returned if available.
|
||||||
|
* @param rt Road type to build.
|
||||||
|
* @param unit_cost The cost to build one road stop of the current type.
|
||||||
|
* @return The cost in case of success, or an error code if it failed.
|
||||||
|
*/
|
||||||
|
static CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlag flags, bool is_drive_through, bool is_truck_stop, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost)
|
||||||
|
{
|
||||||
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
||||||
|
bool success = false;
|
||||||
|
/* Check every tile in the area. */
|
||||||
|
for (TileIndex cur_tile : tile_area) {
|
||||||
|
uint invalid_dirs = 0;
|
||||||
|
if (is_drive_through) {
|
||||||
|
SetBit(invalid_dirs, AxisToDiagDir(axis));
|
||||||
|
SetBit(invalid_dirs, ReverseDiagDir(AxisToDiagDir(axis)));
|
||||||
|
} else {
|
||||||
|
SetBit(invalid_dirs, ddir);
|
||||||
|
}
|
||||||
|
CommandCost ret = CheckFlatLandRoadStop(TileArea(cur_tile, cur_tile), flags, invalid_dirs, is_drive_through, is_truck_stop, axis, est, rt);
|
||||||
|
if (ret.Failed()) return ret;
|
||||||
|
|
||||||
|
bool is_preexisting_roadstop = IsTileType(cur_tile, MP_STATION) && IsRoadStop(cur_tile);
|
||||||
|
|
||||||
|
/* Only add costs if a stop doesn't already exist in the location */
|
||||||
|
if (!is_preexisting_roadstop) {
|
||||||
|
cost.AddCost(ret);
|
||||||
|
cost.AddCost(unit_cost);
|
||||||
|
success = true;
|
||||||
|
} else if (is_preexisting_roadstop && !is_drive_through) {
|
||||||
|
/* Allow rotating non-drive through stops for free */
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) return_cmd_error(STR_ERROR_ALREADY_BUILT);
|
||||||
|
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a bus or truck stop.
|
* Build a bus or truck stop.
|
||||||
* @param flags Operation to perform.
|
* @param flags Operation to perform.
|
||||||
|
@ -1874,11 +1972,9 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, u
|
||||||
} else {
|
} else {
|
||||||
unit_cost = _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS];
|
unit_cost = _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS];
|
||||||
}
|
}
|
||||||
CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * unit_cost);
|
|
||||||
StationID est = INVALID_STATION;
|
StationID est = INVALID_STATION;
|
||||||
ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, is_truck_stop, axis, &est, rt);
|
CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, is_drive_through, is_truck_stop, axis, ddir, &est, rt, unit_cost);
|
||||||
if (ret.Failed()) return ret;
|
if (cost.Failed()) return cost;
|
||||||
cost.AddCost(ret);
|
|
||||||
|
|
||||||
Station *st = nullptr;
|
Station *st = nullptr;
|
||||||
ret = FindJoiningRoadStop(est, station_to_join, adjacent, roadstop_area, &st);
|
ret = FindJoiningRoadStop(est, station_to_join, adjacent, roadstop_area, &st);
|
||||||
|
|
|
@ -191,6 +191,21 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis
|
||||||
|
|
||||||
if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
|
if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
|
||||||
|
|
||||||
|
TileArea new_location(start_tile, width, height);
|
||||||
|
|
||||||
|
/* only AddCost for non-existing waypoints */
|
||||||
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
||||||
|
bool success = false;
|
||||||
|
for (TileIndex cur_tile : new_location) {
|
||||||
|
if (!IsRailWaypointTile(cur_tile)) {
|
||||||
|
cost.AddCost(_price[PR_BUILD_WAYPOINT_RAIL]);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!success) {
|
||||||
|
return_cmd_error(STR_ERROR_ALREADY_BUILT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
|
/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
|
||||||
StationID est = INVALID_STATION;
|
StationID est = INVALID_STATION;
|
||||||
|
|
||||||
|
@ -203,7 +218,6 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis
|
||||||
}
|
}
|
||||||
|
|
||||||
Waypoint *wp = nullptr;
|
Waypoint *wp = nullptr;
|
||||||
TileArea new_location(start_tile, width, height);
|
|
||||||
CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, new_location, &wp);
|
CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, new_location, &wp);
|
||||||
if (ret.Failed()) return ret;
|
if (ret.Failed()) return ret;
|
||||||
|
|
||||||
|
@ -279,7 +293,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis
|
||||||
DirtyCompanyInfrastructureWindows(wp->owner);
|
DirtyCompanyInfrastructureWindows(wp->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CommandCost(EXPENSES_CONSTRUCTION, count * _price[PR_BUILD_WAYPOINT_RAIL]);
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue