2009-08-21 20:21:05 +00:00
/*
* This file is part of OpenTTD .
* OpenTTD is free software ; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , version 2.
* OpenTTD is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details . You should have received a copy of the GNU General Public License along with OpenTTD . If not , see < http : //www.gnu.org/licenses/>.
*/
2009-07-22 11:35:35 +00:00
/** @file base_station_base.h Base classes/functions for base stations. */
# ifndef BASE_STATION_BASE_H
# define BASE_STATION_BASE_H
# include "core/pool_type.hpp"
2010-03-06 12:15:03 +00:00
# include "command_type.h"
2009-07-22 11:35:35 +00:00
# include "viewport_type.h"
# include "station_map.h"
2023-04-24 18:33:18 +00:00
# include "timer/timer_game_calendar.h"
2009-07-22 11:35:35 +00:00
typedef Pool < BaseStation , StationID , 32 , 64000 > StationPool ;
extern StationPool _station_pool ;
struct StationSpecList {
const StationSpec * spec ;
2023-05-08 17:01:06 +00:00
uint32_t grfid ; ///< GRF ID of this custom station
2023-04-17 22:19:30 +00:00
uint16_t localidx ; ///< Station ID within GRF of station
2009-07-22 11:35:35 +00:00
} ;
2022-11-06 15:01:27 +00:00
struct RoadStopSpecList {
const RoadStopSpec * spec ;
2023-05-08 17:01:06 +00:00
uint32_t grfid ; ///< GRF ID of this custom road stop
2023-04-17 22:19:30 +00:00
uint16_t localidx ; ///< Station ID within GRF of road stop
2022-11-06 15:01:27 +00:00
} ;
struct RoadStopTileData {
TileIndex tile ;
2023-05-08 17:01:06 +00:00
uint8_t random_bits ;
uint8_t animation_frame ;
2022-11-06 15:01:27 +00:00
} ;
2009-07-26 16:17:49 +00:00
/** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */
struct StationRect : public Rect {
enum StationRectMode
{
ADD_TEST = 0 ,
ADD_TRY ,
ADD_FORCE
} ;
StationRect ( ) ;
void MakeEmpty ( ) ;
bool PtInExtendedRect ( int x , int y , int distance = 0 ) const ;
bool IsEmpty ( ) const ;
2010-03-06 12:15:03 +00:00
CommandCost BeforeAddTile ( TileIndex tile , StationRectMode mode ) ;
2010-03-06 13:23:33 +00:00
CommandCost BeforeAddRect ( TileIndex tile , int w , int h , StationRectMode mode ) ;
2009-07-26 16:17:49 +00:00
bool AfterRemoveTile ( BaseStation * st , TileIndex tile ) ;
2010-03-06 13:38:46 +00:00
bool AfterRemoveRect ( BaseStation * st , TileArea ta ) ;
2009-07-26 16:17:49 +00:00
static bool ScanForStationTiles ( StationID st_id , int left_a , int top_a , int right_a , int bottom_a ) ;
2010-03-06 11:54:59 +00:00
StationRect & operator = ( const Rect & src ) ;
2009-07-26 16:17:49 +00:00
} ;
2009-07-22 11:35:35 +00:00
/** Base class for all station-ish types */
struct BaseStation : StationPool : : PoolItem < & _station_pool > {
TileIndex xy ; ///< Base tile of the station
2019-12-01 22:17:33 +00:00
TrackedViewportSign sign ; ///< NOSAVE: Dimensions of sign
2009-07-22 11:35:35 +00:00
byte delete_ctr ; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
2020-05-17 21:31:59 +00:00
std : : string name ; ///< Custom name
2009-07-22 11:35:35 +00:00
StringID string_id ; ///< Default name (town area) of station
2020-01-06 20:40:31 +00:00
mutable std : : string cached_name ; ///< NOSAVE: Cache of the resolved name of the station, if not using a custom name
2009-07-22 11:35:35 +00:00
Town * town ; ///< The town this station is associated with
2019-04-22 08:10:04 +00:00
Owner owner ; ///< The owner of this station
2019-04-21 22:01:29 +00:00
StationFacility facilities ; ///< The facilities that this station has
2009-07-22 11:35:35 +00:00
2022-11-06 15:01:27 +00:00
std : : vector < StationSpecList > speclist ; ///< List of rail station specs of this station.
std : : vector < RoadStopSpecList > roadstop_speclist ; ///< List of road stop specs of this station
2009-07-22 11:35:35 +00:00
2023-04-24 18:33:18 +00:00
TimerGameCalendar : : Date build_date ; ///< Date of construction
2009-07-22 11:35:35 +00:00
2023-05-08 17:01:06 +00:00
uint16_t random_bits ; ///< Random bits assigned to this station
2009-07-22 11:35:35 +00:00
byte waiting_triggers ; ///< Waiting triggers (NewGRF) for this station
2023-05-08 17:01:06 +00:00
uint8_t cached_anim_triggers ; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen.
uint8_t cached_roadstop_anim_triggers ; ///< NOSAVE: Combined animation trigger bitmask for road stops, used to determine if trigger processing should happen.
2022-11-06 15:01:27 +00:00
CargoTypes cached_cargo_triggers ; ///< NOSAVE: Combined cargo trigger bitmask
CargoTypes cached_roadstop_cargo_triggers ; ///< NOSAVE: Combined cargo trigger bitmask for road stops
2009-07-22 11:35:35 +00:00
2009-07-26 16:17:49 +00:00
TileArea train_station ; ///< Tile area the train 'station' part covers
StationRect rect ; ///< NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions
2022-11-06 15:01:27 +00:00
std : : vector < RoadStopTileData > custom_roadstop_tile_data ; ///< List of custom road stop tile data
2009-07-26 16:17:49 +00:00
/**
* Initialize the base station .
* @ param tile The location of the station sign
*/
BaseStation ( TileIndex tile ) :
xy ( tile ) ,
train_station ( INVALID_TILE , 0 , 0 )
{
}
2009-07-22 11:35:35 +00:00
virtual ~ BaseStation ( ) ;
/**
* Check whether a specific tile belongs to this station .
* @ param tile the tile to check
* @ return true if the tile belongs to this station
*/
virtual bool TileBelongsToRailStation ( TileIndex tile ) const = 0 ;
/**
* Helper function to get a NewGRF variable that isn ' t implemented by the base class .
* @ param object the resolver object related to this query
* @ param variable that is queried
* @ param parameter parameter for that variable
* @ param available will return false if ever the variable asked for does not exist
* @ return the value stored in the corresponding variable
*/
2023-05-08 17:01:06 +00:00
virtual uint32_t GetNewGRFVariable ( const struct ResolverObject & object , byte variable , byte parameter , bool * available ) const = 0 ;
2009-07-22 11:35:35 +00:00
/**
* Update the coordinated of the sign ( as shown in the viewport ) .
*/
virtual void UpdateVirtCoord ( ) = 0 ;
2023-11-10 00:17:36 +00:00
inline const std : : string & GetCachedName ( ) const
2020-01-06 20:40:31 +00:00
{
2023-11-10 00:17:36 +00:00
if ( ! this - > name . empty ( ) ) return this - > name ;
2020-01-06 20:40:31 +00:00
if ( this - > cached_name . empty ( ) ) this - > FillCachedName ( ) ;
2023-11-10 00:17:36 +00:00
return this - > cached_name ;
2020-01-06 20:40:31 +00:00
}
2019-03-23 11:39:13 +00:00
virtual void MoveSign ( TileIndex new_xy )
{
this - > xy = new_xy ;
this - > UpdateVirtCoord ( ) ;
}
2009-07-22 11:35:35 +00:00
/**
* Get the tile area for a given station type .
* @ param ta tile area to fill .
* @ param type the type of the area
*/
virtual void GetTileArea ( TileArea * ta , StationType type ) const = 0 ;
2009-07-24 15:18:25 +00:00
/**
* Obtain the length of a platform
* @ pre tile must be a rail station tile
* @ param tile A tile that contains the platform in question
* @ return The length of the platform
*/
2009-07-24 19:17:45 +00:00
virtual uint GetPlatformLength ( TileIndex tile ) const = 0 ;
2009-07-24 15:18:25 +00:00
/**
* Determines the REMAINING length of a platform , starting at ( and including )
* the given tile .
* @ param tile the tile from which to start searching . Must be a rail station tile
* @ param dir The direction in which to search .
* @ return The platform length
*/
2009-07-24 19:17:45 +00:00
virtual uint GetPlatformLength ( TileIndex tile , DiagDirection dir ) const = 0 ;
2009-07-24 15:18:25 +00:00
2009-07-22 11:35:35 +00:00
/**
* Get the base station belonging to a specific tile .
* @ param tile The tile to get the base station from .
* @ return the station associated with that tile .
*/
2011-12-20 17:57:56 +00:00
static inline BaseStation * GetByTile ( TileIndex tile )
2009-07-22 11:35:35 +00:00
{
return BaseStation : : Get ( GetStationIndex ( tile ) ) ;
}
2009-07-24 07:38:10 +00:00
/**
* Check whether the base station currently is in use ; in use means
* that it is not scheduled for deletion and that it still has some
* facilities left .
* @ return true if still in use
*/
2011-12-20 17:57:56 +00:00
inline bool IsInUse ( ) const
2009-07-24 07:38:10 +00:00
{
return ( this - > facilities & ~ FACIL_WAYPOINT ) ! = 0 ;
}
2009-09-12 12:56:49 +00:00
2022-11-06 15:01:27 +00:00
inline byte GetRoadStopRandomBits ( TileIndex tile ) const
{
for ( const RoadStopTileData & tile_data : this - > custom_roadstop_tile_data ) {
if ( tile_data . tile = = tile ) return tile_data . random_bits ;
}
return 0 ;
}
inline byte GetRoadStopAnimationFrame ( TileIndex tile ) const
{
for ( const RoadStopTileData & tile_data : this - > custom_roadstop_tile_data ) {
if ( tile_data . tile = = tile ) return tile_data . animation_frame ;
}
return 0 ;
}
private :
void SetRoadStopTileData ( TileIndex tile , byte data , bool animation ) ;
public :
inline void SetRoadStopRandomBits ( TileIndex tile , byte random_bits ) { this - > SetRoadStopTileData ( tile , random_bits , false ) ; }
inline void SetRoadStopAnimationFrame ( TileIndex tile , byte frame ) { this - > SetRoadStopTileData ( tile , frame , true ) ; }
void RemoveRoadStopTileData ( TileIndex tile ) ;
2009-09-12 12:56:49 +00:00
static void PostDestructor ( size_t index ) ;
2020-01-06 20:40:31 +00:00
private :
void FillCachedName ( ) const ;
2009-07-22 11:35:35 +00:00
} ;
/**
* Class defining several overloaded accessors so we don ' t
* have to cast base stations that often
*/
template < class T , bool Tis_waypoint >
struct SpecializedStation : public BaseStation {
static const StationFacility EXPECTED_FACIL = Tis_waypoint ? FACIL_WAYPOINT : FACIL_NONE ; ///< Specialized type
/**
* Set station type correctly
* @ param tile The base tile of the station .
*/
2011-12-20 17:57:56 +00:00
inline SpecializedStation < T , Tis_waypoint > ( TileIndex tile ) :
2009-07-22 11:35:35 +00:00
BaseStation ( tile )
{
this - > facilities = EXPECTED_FACIL ;
}
/**
* Helper for checking whether the given station is of this type .
* @ param st the station to check .
* @ return true if the station is the type we expect it to be .
*/
2011-12-20 17:57:56 +00:00
static inline bool IsExpected ( const BaseStation * st )
2009-07-22 11:35:35 +00:00
{
return ( st - > facilities & FACIL_WAYPOINT ) = = EXPECTED_FACIL ;
}
/**
* Tests whether given index is a valid index for station of this type
* @ param index tested index
* @ return is this index valid index of T ?
*/
2011-12-20 17:57:56 +00:00
static inline bool IsValidID ( size_t index )
2009-07-22 11:35:35 +00:00
{
return BaseStation : : IsValidID ( index ) & & IsExpected ( BaseStation : : Get ( index ) ) ;
}
/**
* Gets station with given index
* @ return pointer to station with given index casted to T *
*/
2011-12-20 17:57:56 +00:00
static inline T * Get ( size_t index )
2009-07-22 11:35:35 +00:00
{
return ( T * ) BaseStation : : Get ( index ) ;
}
/**
* Returns station if the index is a valid index for this station type
* @ return pointer to station with given index if it ' s a station of this type
*/
2011-12-20 17:57:56 +00:00
static inline T * GetIfValid ( size_t index )
2009-07-22 11:35:35 +00:00
{
2019-04-10 21:07:06 +00:00
return IsValidID ( index ) ? Get ( index ) : nullptr ;
2009-07-22 11:35:35 +00:00
}
/**
* Get the station belonging to a specific tile .
* @ param tile The tile to get the station from .
* @ return the station associated with that tile .
*/
2011-12-20 17:57:56 +00:00
static inline T * GetByTile ( TileIndex tile )
2009-07-22 11:35:35 +00:00
{
return GetIfValid ( GetStationIndex ( tile ) ) ;
}
/**
* Converts a BaseStation to SpecializedStation with type checking .
* @ param st BaseStation pointer
* @ return pointer to SpecializedStation
*/
2011-12-20 17:57:56 +00:00
static inline T * From ( BaseStation * st )
2009-07-22 11:35:35 +00:00
{
assert ( IsExpected ( st ) ) ;
return ( T * ) st ;
}
/**
* Converts a const BaseStation to const SpecializedStation with type checking .
* @ param st BaseStation pointer
* @ return pointer to SpecializedStation
*/
2011-12-20 17:57:56 +00:00
static inline const T * From ( const BaseStation * st )
2009-07-22 11:35:35 +00:00
{
assert ( IsExpected ( st ) ) ;
return ( const T * ) st ;
}
2019-12-15 04:55:59 +00:00
/**
* Returns an iterable ensemble of all valid stations of type T
* @ param from index of the first station to consider
* @ return an iterable ensemble of all valid stations of type T
*/
static Pool : : IterateWrapper < T > Iterate ( size_t from = 0 ) { return Pool : : IterateWrapper < T > ( from ) ; }
} ;
2009-07-22 11:35:35 +00:00
2010-12-22 10:50:32 +00:00
# endif /* BASE_STATION_BASE_H */