mirror of https://github.com/OpenTTD/OpenTTD
Add: Code dealing with extended rail depot platforms.
parent
4854685bec
commit
7ab28f6045
|
@ -18,6 +18,7 @@
|
||||||
#include "command_func.h"
|
#include "command_func.h"
|
||||||
#include "vehicle_base.h"
|
#include "vehicle_base.h"
|
||||||
#include "viewport_kdtree.h"
|
#include "viewport_kdtree.h"
|
||||||
|
#include "platform_func.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
@ -212,6 +213,30 @@ void Depot::AfterAddRemove(TileArea ta, bool adding)
|
||||||
InvalidateWindowData(WC_SELECT_DEPOT, veh_type);
|
InvalidateWindowData(WC_SELECT_DEPOT, veh_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a tile is a destination tile, such as the starting tiles of
|
||||||
|
* rail platforms (and not the middle tiles of the platforms).
|
||||||
|
* @param dep The depot being checked
|
||||||
|
* @param tile The tile being checked
|
||||||
|
* @return Whether the tile is of the given depot.
|
||||||
|
*/
|
||||||
|
bool IsDepotDestTile(Depot *dep, TileIndex tile)
|
||||||
|
{
|
||||||
|
assert(IsDepotTile(tile));
|
||||||
|
assert(GetDepotIndex(tile) == dep->index);
|
||||||
|
|
||||||
|
switch (dep->veh_type) {
|
||||||
|
case VEH_TRAIN:
|
||||||
|
assert(IsRailDepotTile(tile));
|
||||||
|
return !IsExtendedRailDepot(tile) || IsAnyStartPlatformTile(tile);
|
||||||
|
case VEH_ROAD:
|
||||||
|
case VEH_SHIP:
|
||||||
|
case VEH_AIRCRAFT:
|
||||||
|
return true;
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rescan depot_tiles. Done after AfterAddRemove and SaveLoad.
|
* Rescan depot_tiles. Done after AfterAddRemove and SaveLoad.
|
||||||
* Updates the tiles of the depot and its railtypes/roadtypes...
|
* Updates the tiles of the depot and its railtypes/roadtypes...
|
||||||
|
@ -225,7 +250,7 @@ void Depot::RescanDepotTiles()
|
||||||
for (TileIndex tile : this->ta) {
|
for (TileIndex tile : this->ta) {
|
||||||
if (!IsDepotTile(tile)) continue;
|
if (!IsDepotTile(tile)) continue;
|
||||||
if (GetDepotIndex(tile) != this->index) continue;
|
if (GetDepotIndex(tile) != this->index) continue;
|
||||||
this->depot_tiles.push_back(tile);
|
if (IsDepotDestTile(this, tile)) this->depot_tiles.push_back(tile);
|
||||||
switch (veh_type) {
|
switch (veh_type) {
|
||||||
case VEH_ROAD:
|
case VEH_ROAD:
|
||||||
this->r_types.road_types |= GetPresentRoadTypes(tile);
|
this->r_types.road_types |= GetPresentRoadTypes(tile);
|
||||||
|
@ -268,8 +293,12 @@ void UpdateExtendedDepotReservation(Vehicle *v, bool reserve)
|
||||||
SetDepotReservation(v->tile, res_type);
|
SetDepotReservation(v->tile, res_type);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VEH_TRAIN:
|
case VEH_TRAIN: {
|
||||||
|
DiagDirection dir = GetRailDepotDirection(v->tile);
|
||||||
|
SetDepotReservation(GetPlatformExtremeTile(v->tile, dir), res_type);
|
||||||
|
SetDepotReservation(GetPlatformExtremeTile(v->tile, ReverseDiagDir(dir)), res_type);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case VEH_AIRCRAFT:
|
case VEH_AIRCRAFT:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -47,7 +47,8 @@ struct CFollowTrackT
|
||||||
bool m_is_tunnel; ///< last turn passed tunnel
|
bool m_is_tunnel; ///< last turn passed tunnel
|
||||||
bool m_is_bridge; ///< last turn passed bridge ramp
|
bool m_is_bridge; ///< last turn passed bridge ramp
|
||||||
bool m_is_station; ///< last turn passed station
|
bool m_is_station; ///< last turn passed station
|
||||||
int m_tiles_skipped; ///< number of skipped tunnel or station tiles
|
bool m_is_extended_depot; ///< last turn passed depot
|
||||||
|
int m_tiles_skipped; ///< number of skipped tunnel, depot or station tiles
|
||||||
ErrorCode m_err;
|
ErrorCode m_err;
|
||||||
RailTypes m_railtypes;
|
RailTypes m_railtypes;
|
||||||
|
|
||||||
|
@ -81,7 +82,7 @@ struct CFollowTrackT
|
||||||
m_new_tile = INVALID_TILE;
|
m_new_tile = INVALID_TILE;
|
||||||
m_new_td_bits = TRACKDIR_BIT_NONE;
|
m_new_td_bits = TRACKDIR_BIT_NONE;
|
||||||
m_exitdir = INVALID_DIAGDIR;
|
m_exitdir = INVALID_DIAGDIR;
|
||||||
m_is_station = m_is_bridge = m_is_tunnel = false;
|
m_is_station = m_is_bridge = m_is_tunnel = m_is_extended_depot = false;
|
||||||
m_tiles_skipped = 0;
|
m_tiles_skipped = 0;
|
||||||
m_err = EC_NONE;
|
m_err = EC_NONE;
|
||||||
m_railtypes = railtype_override;
|
m_railtypes = railtype_override;
|
||||||
|
@ -171,11 +172,11 @@ struct CFollowTrackT
|
||||||
{
|
{
|
||||||
if (!DoTrackMasking()) return true;
|
if (!DoTrackMasking()) return true;
|
||||||
|
|
||||||
if (m_is_station) {
|
if (m_is_station || m_is_extended_depot) {
|
||||||
/* Check skipped station tiles as well. */
|
/* Check skipped station and depot tiles as well. */
|
||||||
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
|
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
|
||||||
for (TileIndex tile = m_new_tile - diff * m_tiles_skipped; tile != m_new_tile; tile += diff) {
|
for (TileIndex tile = m_new_tile - diff * m_tiles_skipped; tile != m_new_tile; tile += diff) {
|
||||||
if (HasStationReservation(tile)) {
|
if ((m_is_station && HasStationReservation(tile)) || (m_is_extended_depot && HasDepotReservation(tile))) {
|
||||||
m_new_td_bits = TRACKDIR_BIT_NONE;
|
m_new_td_bits = TRACKDIR_BIT_NONE;
|
||||||
m_err = EC_RESERVED;
|
m_err = EC_RESERVED;
|
||||||
return false;
|
return false;
|
||||||
|
@ -201,7 +202,7 @@ protected:
|
||||||
/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
|
/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
|
||||||
inline void FollowTileExit()
|
inline void FollowTileExit()
|
||||||
{
|
{
|
||||||
m_is_station = m_is_bridge = m_is_tunnel = false;
|
m_is_station = m_is_bridge = m_is_tunnel = m_is_extended_depot = false;
|
||||||
m_tiles_skipped = 0;
|
m_tiles_skipped = 0;
|
||||||
|
|
||||||
/* extra handling for tunnels and bridges in our direction */
|
/* extra handling for tunnels and bridges in our direction */
|
||||||
|
@ -225,9 +226,13 @@ protected:
|
||||||
/* normal or station tile, do one step */
|
/* normal or station tile, do one step */
|
||||||
m_new_tile = TileAddByDiagDir(m_old_tile, m_exitdir);
|
m_new_tile = TileAddByDiagDir(m_old_tile, m_exitdir);
|
||||||
|
|
||||||
/* special handling for stations */
|
/* special handling for stations and multi-tile depots */
|
||||||
if (IsRailTT() && HasStationTileRail(m_new_tile)) {
|
if (IsRailTT()) {
|
||||||
m_is_station = true;
|
if (HasStationTileRail(m_new_tile)) {
|
||||||
|
m_is_station = true;
|
||||||
|
} else if (IsExtendedRailDepotTile(m_new_tile)) {
|
||||||
|
m_is_extended_depot = true;
|
||||||
|
}
|
||||||
} else if (IsRoadTT() && IsStationRoadStopTile(m_new_tile)) {
|
} else if (IsRoadTT() && IsStationRoadStopTile(m_new_tile)) {
|
||||||
m_is_station = true;
|
m_is_station = true;
|
||||||
}
|
}
|
||||||
|
@ -369,13 +374,14 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* special handling for rail stations - get to the end of platform */
|
/* special handling for rail platforms - get to the end of platform */
|
||||||
if (IsRailTT() && m_is_station) {
|
if (IsRailTT() && (m_is_station || m_is_extended_depot)) {
|
||||||
/* Entered a platform. */
|
/* Entered a platform. */
|
||||||
assert(HasStationTileRail(m_new_tile));
|
assert(HasStationTileRail(m_new_tile) || IsExtendedRailDepotTile(m_new_tile));
|
||||||
/* How big step we must do to get to the last platform tile? */
|
/* How big step we must do to get to the last platform tile? */
|
||||||
m_tiles_skipped = GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td)) - 1;
|
m_tiles_skipped = GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td)) - 1;
|
||||||
/* Move to the platform end. */
|
/* Move to the platform end. */
|
||||||
|
|
||||||
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
|
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
|
||||||
diff *= m_tiles_skipped;
|
diff *= m_tiles_skipped;
|
||||||
m_new_tile = TileAdd(m_new_tile, diff);
|
m_new_tile = TileAdd(m_new_tile, diff);
|
||||||
|
@ -390,14 +396,27 @@ protected:
|
||||||
{
|
{
|
||||||
/* rail and road depots cause reversing */
|
/* rail and road depots cause reversing */
|
||||||
if (!IsWaterTT() && IsDepotTypeTile(m_old_tile, TT())) {
|
if (!IsWaterTT() && IsDepotTypeTile(m_old_tile, TT())) {
|
||||||
DiagDirection exitdir = IsRailTT() ? GetRailDepotDirection(m_old_tile) : GetRoadDepotDirection(m_old_tile);
|
DiagDirection exitdir;
|
||||||
|
switch (TT()) {
|
||||||
|
case TRANSPORT_AIR:
|
||||||
|
return false;
|
||||||
|
case TRANSPORT_RAIL:
|
||||||
|
if (IsExtendedRailDepot(m_old_tile)) return false;
|
||||||
|
exitdir = GetRailDepotDirection(m_old_tile);
|
||||||
|
break;
|
||||||
|
case TRANSPORT_ROAD:
|
||||||
|
exitdir = GetRoadDepotDirection(m_old_tile);
|
||||||
|
break;
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
if (exitdir != m_exitdir) {
|
if (exitdir != m_exitdir) {
|
||||||
/* reverse */
|
/* reverse */
|
||||||
m_new_tile = m_old_tile;
|
m_new_tile = m_old_tile;
|
||||||
m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
|
m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
|
||||||
m_exitdir = exitdir;
|
m_exitdir = exitdir;
|
||||||
m_tiles_skipped = 0;
|
m_tiles_skipped = 0;
|
||||||
m_is_tunnel = m_is_bridge = m_is_station = false;
|
m_is_tunnel = m_is_bridge = m_is_station = m_is_extended_depot = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,7 +439,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
|
||||||
/* Waypoint is also a good reason to finish. */
|
/* Waypoint is also a good reason to finish. */
|
||||||
end_segment_reason |= ESRB_WAYPOINT;
|
end_segment_reason |= ESRB_WAYPOINT;
|
||||||
|
|
||||||
} else if (tf->m_is_station) {
|
} else if (tf->m_is_station || tf->m_is_extended_depot) {
|
||||||
/* Station penalties. */
|
/* Station penalties. */
|
||||||
uint platform_length = tf->m_tiles_skipped + 1;
|
uint platform_length = tf->m_tiles_skipped + 1;
|
||||||
/* We don't know yet if the station is our target or not. Act like
|
/* We don't know yet if the station is our target or not. Act like
|
||||||
|
@ -592,7 +592,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
|
||||||
|
|
||||||
/* Platform-length penalty. */
|
/* Platform-length penalty. */
|
||||||
if ((end_segment_reason & ESRB_STATION) != ESRB_NONE) {
|
if ((end_segment_reason & ESRB_STATION) != ESRB_NONE) {
|
||||||
assert(HasStationTileRail(n.GetLastTile()));
|
assert(HasStationTileRail(n.GetLastTile()) || IsExtendedRailDepotTile(n.GetLastTile()));
|
||||||
uint platform_length = GetPlatformLength(n.GetLastTile(), ReverseDiagDir(TrackdirToExitdir(n.GetLastTrackdir())));
|
uint platform_length = GetPlatformLength(n.GetLastTile(), ReverseDiagDir(TrackdirToExitdir(n.GetLastTrackdir())));
|
||||||
/* Reduce the extra cost caused by passing-platform penalty (each platform receives it in the segment cost). */
|
/* Reduce the extra cost caused by passing-platform penalty (each platform receives it in the segment cost). */
|
||||||
extra_cost -= Yapf().PfGetSettings().rail_station_penalty * platform_length;
|
extra_cost -= Yapf().PfGetSettings().rail_station_penalty * platform_length;
|
||||||
|
|
22
src/pbs.cpp
22
src/pbs.cpp
|
@ -12,6 +12,8 @@
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "newgrf_station.h"
|
#include "newgrf_station.h"
|
||||||
#include "pathfinder/follow_track.hpp"
|
#include "pathfinder/follow_track.hpp"
|
||||||
|
#include "platform_func.h"
|
||||||
|
#include "depot_map.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
@ -180,12 +182,12 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
|
||||||
|
|
||||||
/* No reservation --> path end found */
|
/* No reservation --> path end found */
|
||||||
if (reserved == TRACKDIR_BIT_NONE) {
|
if (reserved == TRACKDIR_BIT_NONE) {
|
||||||
if (ft.m_is_station) {
|
if (ft.m_is_station || ft.m_is_extended_depot) {
|
||||||
/* Check skipped station tiles as well, maybe our reservation ends inside the station. */
|
/* Check skipped station tiles as well, maybe our reservation ends inside the station. */
|
||||||
TileIndexDiff diff = TileOffsByDiagDir(ft.m_exitdir);
|
TileIndexDiff diff = TileOffsByDiagDir(ft.m_exitdir);
|
||||||
while (ft.m_tiles_skipped-- > 0) {
|
while (ft.m_tiles_skipped-- > 0) {
|
||||||
ft.m_new_tile -= diff;
|
ft.m_new_tile -= diff;
|
||||||
if (HasStationReservation(ft.m_new_tile)) {
|
if ((ft.m_is_station && HasStationReservation(ft.m_new_tile)) || (ft.m_is_extended_depot && HasDepotReservation(ft.m_new_tile))) {
|
||||||
tile = ft.m_new_tile;
|
tile = ft.m_new_tile;
|
||||||
trackdir = DiagDirToDiagTrackdir(ft.m_exitdir);
|
trackdir = DiagDirToDiagTrackdir(ft.m_exitdir);
|
||||||
break;
|
break;
|
||||||
|
@ -278,14 +280,14 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
|
||||||
if (train_on_res != nullptr) {
|
if (train_on_res != nullptr) {
|
||||||
FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
|
FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
|
||||||
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
|
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
|
||||||
if (*train_on_res == nullptr && IsRailStationTile(ftoti.res.tile)) {
|
if (*train_on_res == nullptr && (IsRailStationTile(ftoti.res.tile) || IsExtendedRailDepotTile(ftoti.res.tile))) {
|
||||||
/* The target tile is a rail station. The track follower
|
/* The target tile is a rail station or extended depot. The track follower
|
||||||
* has stopped on the last platform tile where we haven't
|
* has stopped on the last platform tile where we haven't
|
||||||
* found a train. Also check all previous platform tiles
|
* found a train. Also check all previous platform tiles
|
||||||
* for a possible train. */
|
* for a possible train. */
|
||||||
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir)));
|
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir)));
|
||||||
for (TileIndex st_tile = ftoti.res.tile + diff; *train_on_res == nullptr && IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) {
|
for (TileIndex pt_tile = ftoti.res.tile + diff; *train_on_res == nullptr && IsCompatiblePlatformTile(pt_tile, ftoti.res.tile); pt_tile += diff) {
|
||||||
FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum);
|
FindVehicleOnPos(pt_tile, &ftoti, FindTrainOnTrackEnum);
|
||||||
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
|
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,11 +328,11 @@ Train *GetTrainForReservation(TileIndex tile, Track track)
|
||||||
FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
|
FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
|
||||||
if (ftoti.best != nullptr) return ftoti.best;
|
if (ftoti.best != nullptr) return ftoti.best;
|
||||||
|
|
||||||
/* Special case for stations: check the whole platform for a vehicle. */
|
/* Special case for stations and extended depots: check the whole platform for a vehicle. */
|
||||||
if (IsRailStationTile(ftoti.res.tile)) {
|
if (IsRailStationTile(ftoti.res.tile) || IsExtendedRailDepotTile(ftoti.res.tile)) {
|
||||||
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir)));
|
TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir)));
|
||||||
for (TileIndex st_tile = ftoti.res.tile + diff; IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) {
|
for (TileIndex pt_tile = ftoti.res.tile + diff; IsCompatiblePlatformTile(pt_tile, ftoti.res.tile); pt_tile += diff) {
|
||||||
FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum);
|
FindVehicleOnPos(pt_tile, &ftoti, FindTrainOnTrackEnum);
|
||||||
if (ftoti.best != nullptr) return ftoti.best;
|
if (ftoti.best != nullptr) return ftoti.best;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
205
src/platform.cpp
205
src/platform.cpp
|
@ -11,6 +11,9 @@
|
||||||
#include "station_map.h"
|
#include "station_map.h"
|
||||||
#include "platform_func.h"
|
#include "platform_func.h"
|
||||||
#include "viewport_func.h"
|
#include "viewport_func.h"
|
||||||
|
#include "depot_base.h"
|
||||||
|
#include "vehicle_base.h"
|
||||||
|
#include "engine_base.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the reservation for a complete station platform.
|
* Set the reservation for a complete station platform.
|
||||||
|
@ -34,6 +37,29 @@ void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool
|
||||||
} while (IsCompatibleTrainStationTile(tile, start));
|
} while (IsCompatibleTrainStationTile(tile, start));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the reservation for a complete depot platform.
|
||||||
|
* @pre IsExtendedRailDepotTile(start)
|
||||||
|
* @param start starting tile of the platform
|
||||||
|
* @param dir the direction in which to follow the platform
|
||||||
|
* @param b the state the reservation should be set to
|
||||||
|
*/
|
||||||
|
void SetRailDepotPlatformReservation(TileIndex start, DiagDirection dir, bool b)
|
||||||
|
{
|
||||||
|
TileIndex tile = start;
|
||||||
|
TileIndexDiff diff = TileOffsByDiagDir(dir);
|
||||||
|
|
||||||
|
assert(IsExtendedRailDepotTile(start));
|
||||||
|
assert(GetRailDepotTrack(start) == DiagDirToDiagTrack(dir));
|
||||||
|
|
||||||
|
do {
|
||||||
|
SetDepotReservation(tile, b);
|
||||||
|
MarkTileDirtyByTile(tile);
|
||||||
|
tile = TileAdd(tile, diff);
|
||||||
|
} while (IsCompatibleTrainDepotTile(tile, start));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the reservation for a complete platform in a given direction.
|
* Set the reservation for a complete platform in a given direction.
|
||||||
* @param start starting tile of the platform
|
* @param start starting tile of the platform
|
||||||
|
@ -49,6 +75,32 @@ void SetPlatformReservation(TileIndex start, DiagDirection dir, bool b)
|
||||||
case PT_RAIL_WAYPOINT:
|
case PT_RAIL_WAYPOINT:
|
||||||
SetRailStationReservation(start, b);
|
SetRailStationReservation(start, b);
|
||||||
return;
|
return;
|
||||||
|
case PT_RAIL_DEPOT:
|
||||||
|
SetRailDepotPlatformReservation(start, dir, b);
|
||||||
|
return;
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the reservation for a complete platform.
|
||||||
|
* @param start A tile of the platform
|
||||||
|
* @param b the state the reservation should be set to
|
||||||
|
*/
|
||||||
|
void SetPlatformReservation(TileIndex start, bool b)
|
||||||
|
{
|
||||||
|
DiagDirection dir;
|
||||||
|
switch (GetPlatformType(start)) {
|
||||||
|
case PT_RAIL_STATION:
|
||||||
|
NOT_REACHED();
|
||||||
|
case PT_RAIL_WAYPOINT:
|
||||||
|
NOT_REACHED();
|
||||||
|
case PT_RAIL_DEPOT:
|
||||||
|
assert(IsExtendedRailDepotTile(start));
|
||||||
|
dir = GetRailDepotDirection(start);
|
||||||
|
SetRailDepotPlatformReservation(start, dir, b);
|
||||||
|
SetRailDepotPlatformReservation(start, ReverseDiagDir(dir), b);
|
||||||
|
return;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +155,57 @@ uint GetRailStationPlatformLength(TileIndex tile, DiagDirection dir)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the length of a rail depot platform.
|
||||||
|
* @pre IsDepotTypeTile(tile, TRANSPORT_RAIL)
|
||||||
|
* @param tile Tile to check
|
||||||
|
* @return The length of the platform in tile length.
|
||||||
|
*/
|
||||||
|
uint GetRailDepotPlatformLength(TileIndex tile)
|
||||||
|
{
|
||||||
|
assert(IsExtendedRailDepotTile(tile));
|
||||||
|
|
||||||
|
TileIndexDiff delta = (GetRailDepotTrack(tile) == TRACK_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
|
||||||
|
|
||||||
|
TileIndex t = tile;
|
||||||
|
uint len = 0;
|
||||||
|
do {
|
||||||
|
t -= delta;
|
||||||
|
len++;
|
||||||
|
} while (IsCompatibleTrainDepotTile(t, tile));
|
||||||
|
|
||||||
|
t = tile;
|
||||||
|
do {
|
||||||
|
t += delta;
|
||||||
|
len++;
|
||||||
|
} while (IsCompatibleTrainDepotTile(t, tile));
|
||||||
|
|
||||||
|
return len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the length of a rail depot platform in a given direction.
|
||||||
|
* @pre IsRailDepotTile(tile)
|
||||||
|
* @param tile Tile to check
|
||||||
|
* @param dir Direction to check
|
||||||
|
* @return The length of the platform in tile length in the given direction.
|
||||||
|
*/
|
||||||
|
uint GetRailDepotPlatformLength(TileIndex tile, DiagDirection dir)
|
||||||
|
{
|
||||||
|
TileIndex start_tile = tile;
|
||||||
|
uint length = 0;
|
||||||
|
assert(IsExtendedRailDepotTile(tile));
|
||||||
|
assert(dir < DIAGDIR_END);
|
||||||
|
|
||||||
|
do {
|
||||||
|
length++;
|
||||||
|
tile += TileOffsByDiagDir(dir);
|
||||||
|
} while (IsCompatibleTrainDepotTile(tile, start_tile));
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the length of a platform.
|
* Get the length of a platform.
|
||||||
* @param tile Tile to check
|
* @param tile Tile to check
|
||||||
|
@ -115,6 +218,8 @@ uint GetPlatformLength(TileIndex tile)
|
||||||
return GetRailStationPlatformLength(tile);
|
return GetRailStationPlatformLength(tile);
|
||||||
case PT_RAIL_WAYPOINT:
|
case PT_RAIL_WAYPOINT:
|
||||||
return 1;
|
return 1;
|
||||||
|
case PT_RAIL_DEPOT:
|
||||||
|
return GetRailDepotPlatformLength(tile);
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,6 +238,106 @@ uint GetPlatformLength(TileIndex tile, DiagDirection dir)
|
||||||
return GetRailStationPlatformLength(tile, dir);
|
return GetRailStationPlatformLength(tile, dir);
|
||||||
case PT_RAIL_WAYPOINT:
|
case PT_RAIL_WAYPOINT:
|
||||||
return 1;
|
return 1;
|
||||||
|
case PT_RAIL_DEPOT:
|
||||||
|
return GetRailDepotPlatformLength(tile, dir);
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a tile where a rail station platform begins or ends.
|
||||||
|
* @pre IsRailStationTile(tile)
|
||||||
|
* @param tile Tile to check
|
||||||
|
* @param dir The diagonal direction to check
|
||||||
|
* @return The last tile of the platform seen from tile with direction dir.
|
||||||
|
*/
|
||||||
|
TileIndex GetRailStationExtreme(TileIndex tile, DiagDirection dir)
|
||||||
|
{
|
||||||
|
assert(IsRailStationTile(tile));
|
||||||
|
assert(GetRailStationAxis(tile) == DiagDirToAxis(dir));
|
||||||
|
TileIndexDiff delta = TileOffsByDiagDir(dir);
|
||||||
|
|
||||||
|
TileIndex t = tile;
|
||||||
|
do {
|
||||||
|
t -= delta;
|
||||||
|
} while (IsCompatibleTrainStationTile(t, tile));
|
||||||
|
|
||||||
|
return t + delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a tile where a depot platform begins or ends.
|
||||||
|
* @pre IsExtendedDepotTile(tile)
|
||||||
|
* @param tile Tile to check
|
||||||
|
* @param dir The diagonal direction to check
|
||||||
|
* @return The last tile of the platform seen from tile with direction dir.
|
||||||
|
*/
|
||||||
|
TileIndex GetRailDepotExtreme(TileIndex tile, DiagDirection dir)
|
||||||
|
{
|
||||||
|
assert(IsExtendedDepotTile(tile));
|
||||||
|
assert(GetRailDepotTrack(tile) == DiagDirToDiagTrack(dir));
|
||||||
|
TileIndexDiff delta = TileOffsByDiagDir(dir);
|
||||||
|
|
||||||
|
TileIndex t = tile;
|
||||||
|
do {
|
||||||
|
t -= delta;
|
||||||
|
} while (IsCompatibleTrainDepotTile(t, tile));
|
||||||
|
|
||||||
|
return t + delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a tile where a platform begins or ends.
|
||||||
|
* @param tile Tile to check
|
||||||
|
* @param dir Direction to check
|
||||||
|
* @return The last tile of the platform seen from tile with direction dir.
|
||||||
|
*/
|
||||||
|
TileIndex GetPlatformExtremeTile(TileIndex tile, DiagDirection dir)
|
||||||
|
{
|
||||||
|
switch (GetPlatformType(tile)) {
|
||||||
|
case PT_RAIL_STATION:
|
||||||
|
return GetRailStationExtreme(tile, dir);
|
||||||
|
case PT_RAIL_WAYPOINT:
|
||||||
|
return tile;
|
||||||
|
case PT_RAIL_DEPOT:
|
||||||
|
return GetRailDepotExtreme(tile, dir);
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the tiles belonging to a platform.
|
||||||
|
* @param tile Tile of a platform
|
||||||
|
* @return the tile area of the platform
|
||||||
|
*/
|
||||||
|
TileArea GetPlatformTileArea(TileIndex tile)
|
||||||
|
{
|
||||||
|
switch (GetPlatformType(tile)) {
|
||||||
|
case PT_RAIL_STATION: {
|
||||||
|
assert(IsRailStationTile(tile));
|
||||||
|
DiagDirection dir = AxisToDiagDir(GetRailStationAxis(tile));
|
||||||
|
return TileArea(GetRailStationExtreme(tile, dir), GetRailStationExtreme(tile, ReverseDiagDir(dir)));
|
||||||
|
}
|
||||||
|
case PT_RAIL_WAYPOINT:
|
||||||
|
return TileArea(tile);
|
||||||
|
case PT_RAIL_DEPOT: {
|
||||||
|
assert(IsExtendedRailDepotTile(tile));
|
||||||
|
DiagDirection dir = GetRailDepotDirection(tile);
|
||||||
|
return TileArea(GetRailDepotExtreme(tile, dir), GetRailDepotExtreme(tile, ReverseDiagDir(dir)));
|
||||||
|
}
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether this tile is an extreme of a platform.
|
||||||
|
* @param tile Tile to check
|
||||||
|
* @return Whether the tile is the extreme of a platform.
|
||||||
|
*/
|
||||||
|
bool IsAnyStartPlatformTile(TileIndex tile)
|
||||||
|
{
|
||||||
|
assert(IsExtendedRailDepotTile(tile));
|
||||||
|
DiagDirection dir = GetRailDepotDirection(tile);
|
||||||
|
return tile == GetPlatformExtremeTile(tile, dir) || tile == GetPlatformExtremeTile(tile, ReverseDiagDir(dir));
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define PLATFORM_FUNC_H
|
#define PLATFORM_FUNC_H
|
||||||
|
|
||||||
#include "station_map.h"
|
#include "station_map.h"
|
||||||
|
#include "depot_map.h"
|
||||||
#include "platform_type.h"
|
#include "platform_type.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,6 +36,27 @@ static inline bool IsCompatibleTrainStationTile(TileIndex test_tile, TileIndex s
|
||||||
GetStationIndex(test_tile) == GetStationIndex(station_tile);
|
GetStationIndex(test_tile) == GetStationIndex(station_tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a tile is a valid continuation to an extended rail depot tile.
|
||||||
|
* The tile \a test_tile is a valid continuation to \a depot_tile, if all of the following are true:
|
||||||
|
* \li \a test_tile is an extended depot tile
|
||||||
|
* \li \a test_tile and \a depot_tile have the same rail type
|
||||||
|
* \li the tracks on \a test_tile and \a depot_tile are in the same direction
|
||||||
|
* \li both tiles belong to the same depot
|
||||||
|
* @param test_tile Tile to test
|
||||||
|
* @param depot_tile Depot tile to compare with
|
||||||
|
* @pre IsExtendedRailDepotTile(depot_tile)
|
||||||
|
* @return true if the two tiles are compatible
|
||||||
|
*/
|
||||||
|
static inline bool IsCompatibleTrainDepotTile(TileIndex test_tile, TileIndex depot_tile)
|
||||||
|
{
|
||||||
|
assert(IsExtendedRailDepotTile(depot_tile));
|
||||||
|
return IsExtendedRailDepotTile(test_tile) &&
|
||||||
|
GetRailType(test_tile) == GetRailType(depot_tile) &&
|
||||||
|
GetRailDepotTrack(test_tile) == GetRailDepotTrack(depot_tile) &&
|
||||||
|
GetDepotIndex(test_tile) == GetDepotIndex(depot_tile);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type of platform of a given tile.
|
* Returns the type of platform of a given tile.
|
||||||
* @param tile Tile to check
|
* @param tile Tile to check
|
||||||
|
@ -47,6 +69,9 @@ static inline PlatformType GetPlatformType(TileIndex tile)
|
||||||
if (IsRailStation(tile)) return PT_RAIL_STATION;
|
if (IsRailStation(tile)) return PT_RAIL_STATION;
|
||||||
if (IsRailWaypoint(tile)) return PT_RAIL_WAYPOINT;
|
if (IsRailWaypoint(tile)) return PT_RAIL_WAYPOINT;
|
||||||
break;
|
break;
|
||||||
|
case MP_RAILWAY:
|
||||||
|
if (IsExtendedRailDepotTile(tile)) return PT_RAIL_DEPOT;
|
||||||
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +99,8 @@ static inline bool HasPlatformReservation(TileIndex tile)
|
||||||
case PT_RAIL_STATION:
|
case PT_RAIL_STATION:
|
||||||
case PT_RAIL_WAYPOINT:
|
case PT_RAIL_WAYPOINT:
|
||||||
return HasStationReservation(tile);
|
return HasStationReservation(tile);
|
||||||
|
case PT_RAIL_DEPOT:
|
||||||
|
return HasDepotReservation(tile);
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,13 +119,21 @@ static inline bool IsCompatiblePlatformTile(TileIndex test_tile, TileIndex orig_
|
||||||
return IsCompatibleTrainStationTile(test_tile, orig_tile);
|
return IsCompatibleTrainStationTile(test_tile, orig_tile);
|
||||||
case PT_RAIL_WAYPOINT:
|
case PT_RAIL_WAYPOINT:
|
||||||
return test_tile == orig_tile;
|
return test_tile == orig_tile;
|
||||||
|
case PT_RAIL_DEPOT:
|
||||||
|
return IsCompatibleTrainDepotTile(test_tile, orig_tile);
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPlatformReservation(TileIndex start, DiagDirection dir, bool b);
|
void SetPlatformReservation(TileIndex start, DiagDirection dir, bool b);
|
||||||
|
void SetPlatformReservation(TileIndex start, bool b);
|
||||||
|
|
||||||
uint GetPlatformLength(TileIndex tile);
|
uint GetPlatformLength(TileIndex tile);
|
||||||
uint GetPlatformLength(TileIndex tile, DiagDirection dir);
|
uint GetPlatformLength(TileIndex tile, DiagDirection dir);
|
||||||
|
|
||||||
|
TileIndex GetPlatformExtremeTile(TileIndex tile, DiagDirection dir);
|
||||||
|
TileArea GetPlatformTileArea(TileIndex tile);
|
||||||
|
|
||||||
|
bool IsAnyStartPlatformTile(TileIndex tile);
|
||||||
|
|
||||||
#endif /* PLATFORM_FUNC_H */
|
#endif /* PLATFORM_FUNC_H */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
enum PlatformType {
|
enum PlatformType {
|
||||||
PT_RAIL_STATION,
|
PT_RAIL_STATION,
|
||||||
PT_RAIL_WAYPOINT,
|
PT_RAIL_WAYPOINT,
|
||||||
|
PT_RAIL_DEPOT,
|
||||||
PT_END,
|
PT_END,
|
||||||
INVALID_PLATFORM_TYPE = PT_END,
|
INVALID_PLATFORM_TYPE = PT_END,
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "timer/timer_game_economy.h"
|
#include "timer/timer_game_economy.h"
|
||||||
#include "depot_base.h"
|
#include "depot_base.h"
|
||||||
#include "platform_func.h"
|
#include "platform_func.h"
|
||||||
|
#include "depot_map.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/train_sprites.h"
|
#include "table/train_sprites.h"
|
||||||
|
@ -2419,7 +2420,7 @@ static bool CheckTrainStayInDepot(Train *v)
|
||||||
{
|
{
|
||||||
/* bail out if not all wagons are in the same depot or not in a depot at all */
|
/* bail out if not all wagons are in the same depot or not in a depot at all */
|
||||||
for (const Train *u = v; u != nullptr; u = u->Next()) {
|
for (const Train *u = v; u != nullptr; u = u->Next()) {
|
||||||
if (u->track != TRACK_BIT_DEPOT || u->tile != v->tile) return false;
|
if (!u->IsInDepot() || u->tile != v->tile) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the train got no power, then keep it in the depot */
|
/* if the train got no power, then keep it in the depot */
|
||||||
|
@ -2523,7 +2524,7 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (IsRailStationTile(tile)) {
|
} else if (IsRailStationTile(tile) || IsExtendedRailDepotTile(tile)) {
|
||||||
TileIndex new_tile = TileAddByDiagDir(tile, dir);
|
TileIndex new_tile = TileAddByDiagDir(tile, dir);
|
||||||
/* If the new tile is not a further tile of the same station, we
|
/* If the new tile is not a further tile of the same station, we
|
||||||
* clear the reservation for the whole platform. */
|
* clear the reservation for the whole platform. */
|
||||||
|
@ -2546,8 +2547,9 @@ void FreeTrainTrackReservation(const Train *v)
|
||||||
|
|
||||||
TileIndex tile = v->tile;
|
TileIndex tile = v->tile;
|
||||||
Trackdir td = v->GetVehicleTrackdir();
|
Trackdir td = v->GetVehicleTrackdir();
|
||||||
bool free_tile = !(IsRailStationTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE));
|
bool free_tile = !(IsRailStationTile(v->tile) || IsExtendedRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE));
|
||||||
StationID station_id = IsRailStationTile(v->tile) ? GetStationIndex(v->tile) : INVALID_STATION;
|
StationID station_id = IsRailStationTile(v->tile) ? GetStationIndex(v->tile) : INVALID_STATION;
|
||||||
|
DepotID depot_id = IsExtendedRailDepotTile(v->tile) ? GetDepotIndex(v->tile) : INVALID_DEPOT;
|
||||||
|
|
||||||
/* Can't be holding a reservation if we enter a depot. */
|
/* Can't be holding a reservation if we enter a depot. */
|
||||||
if (IsStandardRailDepotTile(tile) && TrackdirToExitdir(td) != GetRailDepotDirection(tile)) return;
|
if (IsStandardRailDepotTile(tile) && TrackdirToExitdir(td) != GetRailDepotDirection(tile)) return;
|
||||||
|
@ -2590,7 +2592,7 @@ void FreeTrainTrackReservation(const Train *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't free first station/bridge/tunnel if we are on it. */
|
/* Don't free first station/bridge/tunnel if we are on it. */
|
||||||
if (free_tile || (!(ft.m_is_station && GetStationIndex(ft.m_new_tile) == station_id) && !ft.m_is_tunnel && !ft.m_is_bridge)) ClearPathReservation(v, tile, td);
|
if (free_tile || (!(ft.m_is_station && GetStationIndex(ft.m_new_tile) == station_id) && !(ft.m_is_extended_depot && GetDepotIndex(ft.m_new_tile) == depot_id) && !ft.m_is_tunnel && !ft.m_is_bridge)) ClearPathReservation(v, tile, td);
|
||||||
|
|
||||||
free_tile = true;
|
free_tile = true;
|
||||||
}
|
}
|
||||||
|
@ -2649,7 +2651,7 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Station, depot or waypoint are a possible target. */
|
/* Station, depot or waypoint are a possible target. */
|
||||||
bool target_seen = ft.m_is_station || (IsTileType(ft.m_new_tile, MP_RAILWAY) && !IsPlainRail(ft.m_new_tile));
|
bool target_seen = ft.m_is_station || ft.m_is_extended_depot || (IsTileType(ft.m_new_tile, MP_RAILWAY) && !IsPlainRail(ft.m_new_tile));
|
||||||
if (target_seen || KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) {
|
if (target_seen || KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) {
|
||||||
/* Choice found or possible target encountered.
|
/* Choice found or possible target encountered.
|
||||||
* On finding a possible target, we need to stop and let the pathfinder handle the
|
* On finding a possible target, we need to stop and let the pathfinder handle the
|
||||||
|
@ -4358,9 +4360,13 @@ Trackdir Train::GetVehicleTrackdir() const
|
||||||
{
|
{
|
||||||
if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
|
if (this->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
|
||||||
|
|
||||||
if (this->track == TRACK_BIT_DEPOT) {
|
if (this->IsInDepot()) {
|
||||||
/* We'll assume the train is facing outwards */
|
/* We'll assume the train is facing outwards */
|
||||||
return DiagDirToDiagTrackdir(GetRailDepotDirection(this->tile)); // Train in depot
|
if (this->track == TRACK_BIT_DEPOT)
|
||||||
|
return DiagDirToDiagTrackdir(DirToDiagDir(this->direction)); // Train in depot
|
||||||
|
Track track = FindFirstTrack(this->track & ~TRACK_BIT_DEPOT);
|
||||||
|
assert(IsValidTrack(track));
|
||||||
|
return TrackDirectionToTrackdir(track, this->direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->track == TRACK_BIT_WORMHOLE) {
|
if (this->track == TRACK_BIT_WORMHOLE) {
|
||||||
|
|
Loading…
Reference in New Issue