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 "vehicle_base.h"
|
||||
#include "viewport_kdtree.h"
|
||||
#include "platform_func.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
|
@ -212,6 +213,30 @@ void Depot::AfterAddRemove(TileArea ta, bool adding)
|
|||
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.
|
||||
* Updates the tiles of the depot and its railtypes/roadtypes...
|
||||
|
@ -225,7 +250,7 @@ void Depot::RescanDepotTiles()
|
|||
for (TileIndex tile : this->ta) {
|
||||
if (!IsDepotTile(tile)) 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) {
|
||||
case VEH_ROAD:
|
||||
this->r_types.road_types |= GetPresentRoadTypes(tile);
|
||||
|
@ -268,8 +293,12 @@ void UpdateExtendedDepotReservation(Vehicle *v, bool reserve)
|
|||
SetDepotReservation(v->tile, res_type);
|
||||
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;
|
||||
}
|
||||
|
||||
case VEH_AIRCRAFT:
|
||||
break;
|
||||
|
|
|
@ -47,7 +47,8 @@ struct CFollowTrackT
|
|||
bool m_is_tunnel; ///< last turn passed tunnel
|
||||
bool m_is_bridge; ///< last turn passed bridge ramp
|
||||
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;
|
||||
RailTypes m_railtypes;
|
||||
|
||||
|
@ -81,7 +82,7 @@ struct CFollowTrackT
|
|||
m_new_tile = INVALID_TILE;
|
||||
m_new_td_bits = TRACKDIR_BIT_NONE;
|
||||
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_err = EC_NONE;
|
||||
m_railtypes = railtype_override;
|
||||
|
@ -171,11 +172,11 @@ struct CFollowTrackT
|
|||
{
|
||||
if (!DoTrackMasking()) return true;
|
||||
|
||||
if (m_is_station) {
|
||||
/* Check skipped station tiles as well. */
|
||||
if (m_is_station || m_is_extended_depot) {
|
||||
/* Check skipped station and depot tiles as well. */
|
||||
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
|
||||
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_err = EC_RESERVED;
|
||||
return false;
|
||||
|
@ -201,7 +202,7 @@ protected:
|
|||
/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
|
||||
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;
|
||||
|
||||
/* extra handling for tunnels and bridges in our direction */
|
||||
|
@ -225,9 +226,13 @@ protected:
|
|||
/* normal or station tile, do one step */
|
||||
m_new_tile = TileAddByDiagDir(m_old_tile, m_exitdir);
|
||||
|
||||
/* special handling for stations */
|
||||
if (IsRailTT() && HasStationTileRail(m_new_tile)) {
|
||||
m_is_station = true;
|
||||
/* special handling for stations and multi-tile depots */
|
||||
if (IsRailTT()) {
|
||||
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)) {
|
||||
m_is_station = true;
|
||||
}
|
||||
|
@ -369,13 +374,14 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
/* special handling for rail stations - get to the end of platform */
|
||||
if (IsRailTT() && m_is_station) {
|
||||
/* special handling for rail platforms - get to the end of platform */
|
||||
if (IsRailTT() && (m_is_station || m_is_extended_depot)) {
|
||||
/* 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? */
|
||||
m_tiles_skipped = GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td)) - 1;
|
||||
/* Move to the platform end. */
|
||||
|
||||
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
|
||||
diff *= m_tiles_skipped;
|
||||
m_new_tile = TileAdd(m_new_tile, diff);
|
||||
|
@ -390,14 +396,27 @@ protected:
|
|||
{
|
||||
/* rail and road depots cause reversing */
|
||||
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) {
|
||||
/* reverse */
|
||||
m_new_tile = m_old_tile;
|
||||
m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
|
||||
m_exitdir = exitdir;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
end_segment_reason |= ESRB_WAYPOINT;
|
||||
|
||||
} else if (tf->m_is_station) {
|
||||
} else if (tf->m_is_station || tf->m_is_extended_depot) {
|
||||
/* Station penalties. */
|
||||
uint platform_length = tf->m_tiles_skipped + 1;
|
||||
/* 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. */
|
||||
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())));
|
||||
/* 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;
|
||||
|
|
22
src/pbs.cpp
22
src/pbs.cpp
|
@ -12,6 +12,8 @@
|
|||
#include "vehicle_func.h"
|
||||
#include "newgrf_station.h"
|
||||
#include "pathfinder/follow_track.hpp"
|
||||
#include "platform_func.h"
|
||||
#include "depot_map.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
|
@ -180,12 +182,12 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
|
|||
|
||||
/* No reservation --> path end found */
|
||||
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. */
|
||||
TileIndexDiff diff = TileOffsByDiagDir(ft.m_exitdir);
|
||||
while (ft.m_tiles_skipped-- > 0) {
|
||||
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;
|
||||
trackdir = DiagDirToDiagTrackdir(ft.m_exitdir);
|
||||
break;
|
||||
|
@ -278,14 +280,14 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
|
|||
if (train_on_res != nullptr) {
|
||||
FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
|
||||
if (ftoti.best != nullptr) *train_on_res = ftoti.best->First();
|
||||
if (*train_on_res == nullptr && IsRailStationTile(ftoti.res.tile)) {
|
||||
/* The target tile is a rail station. The track follower
|
||||
if (*train_on_res == nullptr && (IsRailStationTile(ftoti.res.tile) || IsExtendedRailDepotTile(ftoti.res.tile))) {
|
||||
/* The target tile is a rail station or extended depot. The track follower
|
||||
* has stopped on the last platform tile where we haven't
|
||||
* found a train. Also check all previous platform tiles
|
||||
* for a possible train. */
|
||||
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) {
|
||||
FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum);
|
||||
for (TileIndex pt_tile = ftoti.res.tile + diff; *train_on_res == nullptr && IsCompatiblePlatformTile(pt_tile, ftoti.res.tile); pt_tile += diff) {
|
||||
FindVehicleOnPos(pt_tile, &ftoti, FindTrainOnTrackEnum);
|
||||
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);
|
||||
if (ftoti.best != nullptr) return ftoti.best;
|
||||
|
||||
/* Special case for stations: check the whole platform for a vehicle. */
|
||||
if (IsRailStationTile(ftoti.res.tile)) {
|
||||
/* Special case for stations and extended depots: check the whole platform for a vehicle. */
|
||||
if (IsRailStationTile(ftoti.res.tile) || IsExtendedRailDepotTile(ftoti.res.tile)) {
|
||||
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) {
|
||||
FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum);
|
||||
for (TileIndex pt_tile = ftoti.res.tile + diff; IsCompatiblePlatformTile(pt_tile, ftoti.res.tile); pt_tile += diff) {
|
||||
FindVehicleOnPos(pt_tile, &ftoti, FindTrainOnTrackEnum);
|
||||
if (ftoti.best != nullptr) return ftoti.best;
|
||||
}
|
||||
}
|
||||
|
|
205
src/platform.cpp
205
src/platform.cpp
|
@ -11,6 +11,9 @@
|
|||
#include "station_map.h"
|
||||
#include "platform_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.
|
||||
|
@ -34,6 +37,29 @@ void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool
|
|||
} 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.
|
||||
* @param start starting tile of the platform
|
||||
|
@ -49,6 +75,32 @@ void SetPlatformReservation(TileIndex start, DiagDirection dir, bool b)
|
|||
case PT_RAIL_WAYPOINT:
|
||||
SetRailStationReservation(start, b);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +155,57 @@ uint GetRailStationPlatformLength(TileIndex tile, DiagDirection dir)
|
|||
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.
|
||||
* @param tile Tile to check
|
||||
|
@ -115,6 +218,8 @@ uint GetPlatformLength(TileIndex tile)
|
|||
return GetRailStationPlatformLength(tile);
|
||||
case PT_RAIL_WAYPOINT:
|
||||
return 1;
|
||||
case PT_RAIL_DEPOT:
|
||||
return GetRailDepotPlatformLength(tile);
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
@ -133,6 +238,106 @@ uint GetPlatformLength(TileIndex tile, DiagDirection dir)
|
|||
return GetRailStationPlatformLength(tile, dir);
|
||||
case PT_RAIL_WAYPOINT:
|
||||
return 1;
|
||||
case PT_RAIL_DEPOT:
|
||||
return GetRailDepotPlatformLength(tile, dir);
|
||||
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
|
||||
|
||||
#include "station_map.h"
|
||||
#include "depot_map.h"
|
||||
#include "platform_type.h"
|
||||
|
||||
/**
|
||||
|
@ -35,6 +36,27 @@ static inline bool IsCompatibleTrainStationTile(TileIndex test_tile, TileIndex s
|
|||
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.
|
||||
* @param tile Tile to check
|
||||
|
@ -47,6 +69,9 @@ static inline PlatformType GetPlatformType(TileIndex tile)
|
|||
if (IsRailStation(tile)) return PT_RAIL_STATION;
|
||||
if (IsRailWaypoint(tile)) return PT_RAIL_WAYPOINT;
|
||||
break;
|
||||
case MP_RAILWAY:
|
||||
if (IsExtendedRailDepotTile(tile)) return PT_RAIL_DEPOT;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -74,6 +99,8 @@ static inline bool HasPlatformReservation(TileIndex tile)
|
|||
case PT_RAIL_STATION:
|
||||
case PT_RAIL_WAYPOINT:
|
||||
return HasStationReservation(tile);
|
||||
case PT_RAIL_DEPOT:
|
||||
return HasDepotReservation(tile);
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
@ -92,13 +119,21 @@ static inline bool IsCompatiblePlatformTile(TileIndex test_tile, TileIndex orig_
|
|||
return IsCompatibleTrainStationTile(test_tile, orig_tile);
|
||||
case PT_RAIL_WAYPOINT:
|
||||
return test_tile == orig_tile;
|
||||
case PT_RAIL_DEPOT:
|
||||
return IsCompatibleTrainDepotTile(test_tile, orig_tile);
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
void SetPlatformReservation(TileIndex start, DiagDirection dir, bool b);
|
||||
void SetPlatformReservation(TileIndex start, bool b);
|
||||
|
||||
uint GetPlatformLength(TileIndex tile);
|
||||
uint GetPlatformLength(TileIndex tile, DiagDirection dir);
|
||||
|
||||
TileIndex GetPlatformExtremeTile(TileIndex tile, DiagDirection dir);
|
||||
TileArea GetPlatformTileArea(TileIndex tile);
|
||||
|
||||
bool IsAnyStartPlatformTile(TileIndex tile);
|
||||
|
||||
#endif /* PLATFORM_FUNC_H */
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
enum PlatformType {
|
||||
PT_RAIL_STATION,
|
||||
PT_RAIL_WAYPOINT,
|
||||
PT_RAIL_DEPOT,
|
||||
PT_END,
|
||||
INVALID_PLATFORM_TYPE = PT_END,
|
||||
};
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "timer/timer_game_economy.h"
|
||||
#include "depot_base.h"
|
||||
#include "platform_func.h"
|
||||
#include "depot_map.h"
|
||||
|
||||
#include "table/strings.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 */
|
||||
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 */
|
||||
|
@ -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);
|
||||
/* If the new tile is not a further tile of the same station, we
|
||||
* clear the reservation for the whole platform. */
|
||||
|
@ -2546,8 +2547,9 @@ void FreeTrainTrackReservation(const Train *v)
|
|||
|
||||
TileIndex tile = v->tile;
|
||||
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;
|
||||
DepotID depot_id = IsExtendedRailDepotTile(v->tile) ? GetDepotIndex(v->tile) : INVALID_DEPOT;
|
||||
|
||||
/* Can't be holding a reservation if we enter a depot. */
|
||||
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. */
|
||||
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;
|
||||
}
|
||||
|
@ -2649,7 +2651,7 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks,
|
|||
}
|
||||
|
||||
/* 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) {
|
||||
/* Choice found or possible target encountered.
|
||||
* 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->track == TRACK_BIT_DEPOT) {
|
||||
if (this->IsInDepot()) {
|
||||
/* 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) {
|
||||
|
|
Loading…
Reference in New Issue