|
|
|
@ -98,8 +98,8 @@ bool IsHangar(TileIndex t)
|
|
|
|
|
* @param st to 'return' the found station
|
|
|
|
|
* @return Succeeded command (if zero or one station found) or failed command (for two or more stations found).
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st)
|
|
|
|
|
template <class T, class F>
|
|
|
|
|
CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st, F filter)
|
|
|
|
|
{
|
|
|
|
|
ta.Expand(1);
|
|
|
|
|
|
|
|
|
@ -107,7 +107,7 @@ CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID c
|
|
|
|
|
for (TileIndex tile_cur : ta) {
|
|
|
|
|
if (IsTileType(tile_cur, MP_STATION)) {
|
|
|
|
|
StationID t = GetStationIndex(tile_cur);
|
|
|
|
|
if (!T::IsValidID(t) || Station::Get(t)->owner != company) continue;
|
|
|
|
|
if (!T::IsValidID(t) || T::Get(t)->owner != company || !filter(T::Get(t))) continue;
|
|
|
|
|
if (closest_station == INVALID_STATION) {
|
|
|
|
|
closest_station = t;
|
|
|
|
|
} else if (closest_station != t) {
|
|
|
|
@ -1068,13 +1068,14 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl
|
|
|
|
|
* @param flags Operation to perform.
|
|
|
|
|
* @param invalid_dirs Prohibited directions (set of DiagDirections).
|
|
|
|
|
* @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 station_type Station type (bus, truck or road waypoint).
|
|
|
|
|
* @param axis Axis of a drive-through road stop.
|
|
|
|
|
* @param station StationID to be queried and returned if available.
|
|
|
|
|
* @param rt Road type to build.
|
|
|
|
|
* @param require_road Is existing road required.
|
|
|
|
|
* @return The cost in case of success, or an error code if it failed.
|
|
|
|
|
*/
|
|
|
|
|
static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, bool is_truck_stop, Axis axis, StationID *station, RoadType rt)
|
|
|
|
|
CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, StationType station_type, Axis axis, StationID *station, RoadType rt, bool require_road)
|
|
|
|
|
{
|
|
|
|
|
CommandCost cost(EXPENSES_CONSTRUCTION);
|
|
|
|
|
int allowed_z = -1;
|
|
|
|
@ -1097,10 +1098,10 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags
|
|
|
|
|
* Station points to INVALID_STATION if we can build on any station.
|
|
|
|
|
* Or it points to a station if we're only allowed to build on exactly that station. */
|
|
|
|
|
if (station != nullptr && IsTileType(cur_tile, MP_STATION)) {
|
|
|
|
|
if (!IsRoadStop(cur_tile)) {
|
|
|
|
|
if (!IsAnyRoadStop(cur_tile)) {
|
|
|
|
|
return ClearTile_Station(cur_tile, DC_AUTO); // Get error message.
|
|
|
|
|
} else {
|
|
|
|
|
if (is_truck_stop != IsTruckStop(cur_tile) ||
|
|
|
|
|
if (station_type != GetStationType(cur_tile) ||
|
|
|
|
|
is_drive_through != IsDriveThroughStopTile(cur_tile)) {
|
|
|
|
|
return ClearTile_Station(cur_tile, DC_AUTO); // Get error message.
|
|
|
|
|
}
|
|
|
|
@ -1147,10 +1148,10 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags
|
|
|
|
|
}
|
|
|
|
|
uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_ROAD));
|
|
|
|
|
|
|
|
|
|
if (RoadTypeIsRoad(rt) && !HasPowerOnRoad(rt, road_rt)) return_cmd_error(STR_ERROR_NO_SUITABLE_ROAD);
|
|
|
|
|
if (rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt) && !HasPowerOnRoad(rt, road_rt)) return_cmd_error(STR_ERROR_NO_SUITABLE_ROAD);
|
|
|
|
|
|
|
|
|
|
cost.AddCost(RoadBuildCost(road_rt) * (2 - num_pieces));
|
|
|
|
|
} else if (RoadTypeIsRoad(rt)) {
|
|
|
|
|
} else if (rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt)) {
|
|
|
|
|
cost.AddCost(RoadBuildCost(rt) * 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1168,12 +1169,14 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags
|
|
|
|
|
}
|
|
|
|
|
uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_TRAM));
|
|
|
|
|
|
|
|
|
|
if (RoadTypeIsTram(rt) && !HasPowerOnRoad(rt, tram_rt)) return_cmd_error(STR_ERROR_NO_SUITABLE_ROAD);
|
|
|
|
|
if (rt != INVALID_ROADTYPE && RoadTypeIsTram(rt) && !HasPowerOnRoad(rt, tram_rt)) return_cmd_error(STR_ERROR_NO_SUITABLE_ROAD);
|
|
|
|
|
|
|
|
|
|
cost.AddCost(RoadBuildCost(tram_rt) * (2 - num_pieces));
|
|
|
|
|
} else if (RoadTypeIsTram(rt)) {
|
|
|
|
|
} else if (rt != INVALID_ROADTYPE && RoadTypeIsTram(rt)) {
|
|
|
|
|
cost.AddCost(RoadBuildCost(rt) * 2);
|
|
|
|
|
}
|
|
|
|
|
} else if (require_road) {
|
|
|
|
|
return_cmd_error(STR_ERROR_THERE_IS_NO_ROAD);
|
|
|
|
|
} else {
|
|
|
|
|
ret = DoCommand(cur_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
|
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
@ -1316,8 +1319,8 @@ void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const Station
|
|
|
|
|
* @param error_message the error message when building a station on top of others
|
|
|
|
|
* @return command cost with the error or 'okay'
|
|
|
|
|
*/
|
|
|
|
|
template <class T>
|
|
|
|
|
CommandCost FindJoiningBaseStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, T **st, StringID error_message)
|
|
|
|
|
template <class T, class F>
|
|
|
|
|
CommandCost FindJoiningBaseStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, T **st, StringID error_message, F filter)
|
|
|
|
|
{
|
|
|
|
|
assert(*st == nullptr);
|
|
|
|
|
bool check_surrounding = true;
|
|
|
|
@ -1331,7 +1334,8 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station
|
|
|
|
|
} else {
|
|
|
|
|
/* Extend the current station, and don't check whether it will
|
|
|
|
|
* be near any other stations. */
|
|
|
|
|
*st = T::GetIfValid(existing_station);
|
|
|
|
|
T *candidate = T::GetIfValid(existing_station);
|
|
|
|
|
if (candidate != nullptr && filter(candidate)) *st = candidate;
|
|
|
|
|
check_surrounding = (*st == nullptr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -1343,7 +1347,7 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station
|
|
|
|
|
|
|
|
|
|
if (check_surrounding) {
|
|
|
|
|
/* Make sure there is no more than one other station around us that is owned by us. */
|
|
|
|
|
CommandCost ret = GetStationAround(ta, existing_station, _current_company, st);
|
|
|
|
|
CommandCost ret = GetStationAround(ta, existing_station, _current_company, st, filter);
|
|
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1365,7 +1369,7 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station
|
|
|
|
|
*/
|
|
|
|
|
static CommandCost FindJoiningStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Station **st, StringID error_message = STR_ERROR_MUST_REMOVE_RAILWAY_STATION_FIRST)
|
|
|
|
|
{
|
|
|
|
|
return FindJoiningBaseStation<Station>(existing_station, station_to_join, adjacent, ta, st, error_message);
|
|
|
|
|
return FindJoiningBaseStation<Station>(existing_station, station_to_join, adjacent, ta, st, error_message, [](Station *st) -> bool { return true; });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1377,9 +1381,11 @@ static CommandCost FindJoiningStation(StationID existing_station, StationID stat
|
|
|
|
|
* @param wp 'return' pointer for the found waypoint
|
|
|
|
|
* @return command cost with the error or 'okay'
|
|
|
|
|
*/
|
|
|
|
|
CommandCost FindJoiningWaypoint(StationID existing_waypoint, StationID waypoint_to_join, bool adjacent, TileArea ta, Waypoint **wp)
|
|
|
|
|
CommandCost FindJoiningWaypoint(StationID existing_waypoint, StationID waypoint_to_join, bool adjacent, TileArea ta, Waypoint **wp, bool is_road)
|
|
|
|
|
{
|
|
|
|
|
return FindJoiningBaseStation<Waypoint>(existing_waypoint, waypoint_to_join, adjacent, ta, wp, STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST);
|
|
|
|
|
return FindJoiningBaseStation<Waypoint>(existing_waypoint, waypoint_to_join, adjacent, ta, wp,
|
|
|
|
|
is_road ? STR_ERROR_MUST_REMOVE_ROADWAYPOINT_FIRST : STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST,
|
|
|
|
|
[is_road](Waypoint *wp) -> bool { return HasBit(wp->waypoint_flags, WPF_ROAD) == is_road; });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -1736,6 +1742,16 @@ static void MakeShipStationAreaSmaller(Station *st)
|
|
|
|
|
UpdateStationDockingTiles(st);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool TileBelongsToRoadWaypointStation(BaseStation *st, TileIndex tile)
|
|
|
|
|
{
|
|
|
|
|
return IsRoadWaypointTile(tile) && GetStationIndex(tile) == st->index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MakeRoadWaypointStationAreaSmaller(BaseStation *st, TileArea &road_waypoint_area)
|
|
|
|
|
{
|
|
|
|
|
road_waypoint_area = MakeStationAreaSmaller(st, road_waypoint_area, TileBelongsToRoadWaypointStation);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove a number of tiles from any rail station within the area.
|
|
|
|
|
* @param ta the area to clear station tile from.
|
|
|
|
@ -2004,7 +2020,7 @@ static RoadStop **FindRoadStopSpot(bool truck_station, Station *st)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags);
|
|
|
|
|
CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Find a nearby station that joins this road stop.
|
|
|
|
@ -2017,7 +2033,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags);
|
|
|
|
|
*/
|
|
|
|
|
static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID station_to_join, bool adjacent, TileArea ta, Station **st)
|
|
|
|
|
{
|
|
|
|
|
return FindJoiningBaseStation<Station>(existing_stop, station_to_join, adjacent, ta, st, STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST);
|
|
|
|
|
return FindJoiningBaseStation<Station>(existing_stop, station_to_join, adjacent, ta, st, STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST, [](Station *st) -> bool { return true; });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -2082,7 +2098,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
|
|
|
|
/* Total road stop cost. */
|
|
|
|
|
CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[type ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]);
|
|
|
|
|
StationID est = INVALID_STATION;
|
|
|
|
|
ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, type, axis, &est, rt);
|
|
|
|
|
ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, type ? STATION_TRUCK : STATION_BUS, axis, &est, rt, false);
|
|
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
|
cost.AddCost(ret);
|
|
|
|
|
|
|
|
|
@ -2106,7 +2122,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
|
|
|
|
Owner tram_owner = tram_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company;
|
|
|
|
|
DisallowedRoadDirections drd = IsNormalRoadTile(cur_tile) ? GetDisallowedRoadDirections(cur_tile) : DRD_NONE;
|
|
|
|
|
|
|
|
|
|
if (IsTileType(cur_tile, MP_STATION) && IsRoadStop(cur_tile)) {
|
|
|
|
|
if (IsTileType(cur_tile, MP_STATION) && IsAnyRoadStop(cur_tile)) {
|
|
|
|
|
RemoveRoadStop(cur_tile, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2141,7 +2157,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
|
|
|
|
UpdateCompanyRoadInfrastructure(road_rt, road_owner, ROAD_STOP_TRACKBIT_FACTOR);
|
|
|
|
|
UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, ROAD_STOP_TRACKBIT_FACTOR);
|
|
|
|
|
|
|
|
|
|
MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, rs_type, road_rt, tram_rt, axis);
|
|
|
|
|
MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, (rs_type == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), road_rt, tram_rt, axis);
|
|
|
|
|
SetDriveThroughStopDisallowedRoadDirections(cur_tile, drd);
|
|
|
|
|
road_stop->MakeDriveThrough();
|
|
|
|
|
} else {
|
|
|
|
@ -2154,10 +2170,10 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
|
|
|
|
|
Company::Get(st->owner)->infrastructure.station++;
|
|
|
|
|
|
|
|
|
|
MarkTileDirtyByTile(cur_tile);
|
|
|
|
|
UpdateRoadCachedOneWayStatesAroundTile(cur_tile);
|
|
|
|
|
}
|
|
|
|
|
ZoningMarkDirtyStationCoverageArea(st);
|
|
|
|
|
NotifyRoadLayoutChanged(true);
|
|
|
|
|
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
|
|
|
|
|
|
|
|
|
if (st != nullptr) {
|
|
|
|
|
st->AfterStationTileSetChange(true, type ? STATION_TRUCK: STATION_BUS);
|
|
|
|
@ -2181,6 +2197,52 @@ static Vehicle *ClearRoadStopStatusEnum(Vehicle *v, void *)
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlag flags)
|
|
|
|
|
{
|
|
|
|
|
Waypoint *wp = Waypoint::GetByTile(tile);
|
|
|
|
|
|
|
|
|
|
if (_current_company != OWNER_WATER) {
|
|
|
|
|
CommandCost ret = CheckOwnership(wp->owner);
|
|
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* don't do the check for drive-through road stops when company bankrupts */
|
|
|
|
|
if (!(flags & DC_BANKRUPT)) {
|
|
|
|
|
CommandCost ret = EnsureNoVehicleOnGround(tile);
|
|
|
|
|
if (ret.Failed()) return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (flags & DC_EXEC) {
|
|
|
|
|
/* Update company infrastructure counts. */
|
|
|
|
|
for (RoadTramType rtt : _roadtramtypes) {
|
|
|
|
|
RoadType rt = GetRoadType(tile, rtt);
|
|
|
|
|
UpdateCompanyRoadInfrastructure(rt, GetRoadOwner(tile, rtt), -static_cast<int>(ROAD_STOP_TRACKBIT_FACTOR));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Company::Get(wp->owner)->infrastructure.station--;
|
|
|
|
|
DirtyCompanyInfrastructureWindows(wp->owner);
|
|
|
|
|
|
|
|
|
|
DoClearSquare(tile);
|
|
|
|
|
|
|
|
|
|
wp->rect.AfterRemoveTile(wp, tile);
|
|
|
|
|
|
|
|
|
|
MakeRoadWaypointStationAreaSmaller(wp, wp->road_waypoint_area);
|
|
|
|
|
|
|
|
|
|
UpdateStationSignCoord(wp);
|
|
|
|
|
|
|
|
|
|
/* if we deleted the whole waypoint, delete the road facility. */
|
|
|
|
|
if (wp->road_waypoint_area.tile == INVALID_TILE) {
|
|
|
|
|
wp->facilities &= ~(FACIL_BUS_STOP | FACIL_TRUCK_STOP);
|
|
|
|
|
SetWindowWidgetDirty(WC_STATION_VIEW, wp->index, WID_SV_ROADVEHS);
|
|
|
|
|
wp->UpdateVirtCoord();
|
|
|
|
|
DeleteStationIfEmpty(wp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NotifyRoadLayoutChanged(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_STATION_TRUCK]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove a bus station/truck stop
|
|
|
|
@ -2188,8 +2250,12 @@ static Vehicle *ClearRoadStopStatusEnum(Vehicle *v, void *)
|
|
|
|
|
* @param flags operation to perform
|
|
|
|
|
* @return cost or failure of operation
|
|
|
|
|
*/
|
|
|
|
|
static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
|
|
|
|
|
CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
|
|
|
|
|
{
|
|
|
|
|
if (IsRoadWaypoint(tile)) {
|
|
|
|
|
return RemoveRoadWaypointStop(tile, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Station *st = Station::GetByTile(tile);
|
|
|
|
|
|
|
|
|
|
if (_current_company != OWNER_WATER) {
|
|
|
|
@ -2289,6 +2355,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
|
|
|
|
|
* bit 8..15: Height of the removal area.
|
|
|
|
|
* @param p2 bit 0: 0 For bus stops, 1 for truck stops.
|
|
|
|
|
* @param p2 bit 1: 0 to keep roads of all drive-through stops, 1 to remove them.
|
|
|
|
|
* @param p2 bit 2: 0 for bus/truck stops, 1 for road waypoints.
|
|
|
|
|
* @param text Unused.
|
|
|
|
|
* @return The cost of this operation or an error.
|
|
|
|
|
*/
|
|
|
|
@ -2296,7 +2363,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
|
|
|
|
|
{
|
|
|
|
|
uint8 width = (uint8)GB(p1, 0, 8);
|
|
|
|
|
uint8 height = (uint8)GB(p1, 8, 8);
|
|
|
|
|
bool keep_drive_through_roads = !HasBit(p2, 1);
|
|
|
|
|
bool keep_drive_through_roads = !HasBit(p2, 1) || HasBit(p2, 2);
|
|
|
|
|
|
|
|
|
|
/* Check for incorrect width / height. */
|
|
|
|
|
if (width == 0 || height == 0) return CMD_ERROR;
|
|
|
|
@ -2312,8 +2379,13 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
|
|
|
|
|
bool had_success = false;
|
|
|
|
|
|
|
|
|
|
for (TileIndex cur_tile : roadstop_area) {
|
|
|
|
|
/* Make sure the specified tile is a road stop of the correct type */
|
|
|
|
|
if (!IsTileType(cur_tile, MP_STATION) || !IsRoadStop(cur_tile) || (uint32)GetRoadStopType(cur_tile) != GB(p2, 0, 1)) continue;
|
|
|
|
|
if (HasBit(p2, 2)) {
|
|
|
|
|
/* Make sure the specified tile is a road waypoint */
|
|
|
|
|
if (!IsTileType(cur_tile, MP_STATION) || !IsRoadWaypoint(cur_tile)) continue;
|
|
|
|
|
} else {
|
|
|
|
|
/* Make sure the specified tile is a road stop of the correct type */
|
|
|
|
|
if (!IsTileType(cur_tile, MP_STATION) || !IsStationRoadStop(cur_tile) || (uint32)GetRoadStopType(cur_tile) != GB(p2, 0, 1)) continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Save information on to-be-restored roads before the stop is removed. */
|
|
|
|
|
RoadBits road_bits = ROAD_NONE;
|
|
|
|
@ -3336,7 +3408,7 @@ draw_default_foundation:
|
|
|
|
|
|
|
|
|
|
if (HasStationRail(ti->tile) && HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti);
|
|
|
|
|
|
|
|
|
|
if (IsRoadStop(ti->tile)) {
|
|
|
|
|
if (IsAnyRoadStop(ti->tile)) {
|
|
|
|
|
RoadType road_rt = GetRoadTypeRoad(ti->tile);
|
|
|
|
|
RoadType tram_rt = GetRoadTypeTram(ti->tile);
|
|
|
|
|
const RoadTypeInfo* road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt);
|
|
|
|
@ -3441,7 +3513,7 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
|
|
|
|
|
{
|
|
|
|
|
td->owner[0] = GetTileOwner(tile);
|
|
|
|
|
|
|
|
|
|
if (IsRoadStopTile(tile)) {
|
|
|
|
|
if (IsAnyRoadStopTile(tile)) {
|
|
|
|
|
RoadType road_rt = GetRoadTypeRoad(tile);
|
|
|
|
|
RoadType tram_rt = GetRoadTypeTram(tile);
|
|
|
|
|
Owner road_owner = INVALID_OWNER;
|
|
|
|
@ -3535,6 +3607,7 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
|
|
|
|
|
case STATION_DOCK: str = STR_LAI_STATION_DESCRIPTION_SHIP_DOCK; break;
|
|
|
|
|
case STATION_BUOY: str = STR_LAI_STATION_DESCRIPTION_BUOY; break;
|
|
|
|
|
case STATION_WAYPOINT: str = STR_LAI_STATION_DESCRIPTION_WAYPOINT; break;
|
|
|
|
|
case STATION_ROADWAYPOINT: str = STR_LAI_STATION_DESCRIPTION_WAYPOINT; break;
|
|
|
|
|
}
|
|
|
|
|
td->str = str;
|
|
|
|
|
}
|
|
|
|
@ -3564,7 +3637,7 @@ static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case TRANSPORT_ROAD:
|
|
|
|
|
if (IsRoadStop(tile)) {
|
|
|
|
|
if (IsAnyRoadStop(tile)) {
|
|
|
|
|
RoadTramType rtt = (RoadTramType)sub_mode;
|
|
|
|
|
if (!HasTileRoadType(tile, rtt)) break;
|
|
|
|
|
|
|
|
|
@ -3733,7 +3806,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i
|
|
|
|
|
} else if (v->type == VEH_ROAD) {
|
|
|
|
|
RoadVehicle *rv = RoadVehicle::From(v);
|
|
|
|
|
if (rv->state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)rv->state) && rv->frame == 0) {
|
|
|
|
|
if (IsRoadStop(tile) && rv->IsFrontEngine()) {
|
|
|
|
|
if (IsStationRoadStop(tile) && rv->IsFrontEngine()) {
|
|
|
|
|
/* Attempt to allocate a parking bay in a road stop */
|
|
|
|
|
return RoadStop::GetByTile(tile, GetRoadStopType(tile))->Enter(rv) ? VETSB_CONTINUE : VETSB_CANNOT_ENTER;
|
|
|
|
|
}
|
|
|
|
@ -4712,7 +4785,7 @@ void DeleteOilRig(TileIndex tile)
|
|
|
|
|
|
|
|
|
|
static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_owner)
|
|
|
|
|
{
|
|
|
|
|
if (IsRoadStopTile(tile)) {
|
|
|
|
|
if (IsAnyRoadStopTile(tile)) {
|
|
|
|
|
for (RoadTramType rtt : _roadtramtypes) {
|
|
|
|
|
/* Update all roadtypes, no matter if they are present */
|
|
|
|
|
if (GetRoadOwner(tile, rtt) == old_owner) {
|
|
|
|
@ -4749,6 +4822,7 @@ static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_o
|
|
|
|
|
|
|
|
|
|
case STATION_BUS:
|
|
|
|
|
case STATION_TRUCK:
|
|
|
|
|
case STATION_ROADWAYPOINT:
|
|
|
|
|
/* Road stops were already handled above. */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
@ -4839,6 +4913,7 @@ CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags)
|
|
|
|
|
default: break;
|
|
|
|
|
case STATION_RAIL: return_cmd_error(STR_ERROR_MUST_DEMOLISH_RAILROAD);
|
|
|
|
|
case STATION_WAYPOINT: return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
|
|
|
|
|
case STATION_ROADWAYPOINT: return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
|
|
|
|
|
case STATION_AIRPORT: return_cmd_error(STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST);
|
|
|
|
|
case STATION_TRUCK: return_cmd_error(HasTileRoadType(tile, RTT_TRAM) ? STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST);
|
|
|
|
|
case STATION_BUS: return_cmd_error(HasTileRoadType(tile, RTT_TRAM) ? STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST);
|
|
|
|
@ -4866,6 +4941,11 @@ CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags)
|
|
|
|
|
return RemoveRoadStopAndUpdateRoadCachedOneWayState(tile, flags);
|
|
|
|
|
case STATION_BUOY: return RemoveBuoy(tile, flags);
|
|
|
|
|
case STATION_DOCK: return RemoveDock(tile, flags);
|
|
|
|
|
case STATION_ROADWAYPOINT:
|
|
|
|
|
if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile, flags)) {
|
|
|
|
|
return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
|
|
|
|
|
}
|
|
|
|
|
return RemoveRoadStopAndUpdateRoadCachedOneWayState(tile, flags);
|
|
|
|
|
default: break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -4892,7 +4972,8 @@ static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, in
|
|
|
|
|
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
|
|
|
|
|
|
|
|
|
|
case STATION_TRUCK:
|
|
|
|
|
case STATION_BUS: {
|
|
|
|
|
case STATION_BUS:
|
|
|
|
|
case STATION_ROADWAYPOINT: {
|
|
|
|
|
DiagDirection direction = GetRoadStopDir(tile);
|
|
|
|
|
if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break;
|
|
|
|
|
if (IsDriveThroughStopTile(tile)) {
|
|
|
|
|