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"
|
|
|
|
|
|
|
|
typedef Pool<BaseStation, StationID, 32, 64000> StationPool;
|
|
|
|
extern StationPool _station_pool;
|
|
|
|
|
|
|
|
struct StationSpecList {
|
|
|
|
const StationSpec *spec;
|
|
|
|
uint32 grfid; ///< GRF ID of this custom station
|
|
|
|
uint8 localidx; ///< Station ID within GRF of station
|
|
|
|
};
|
|
|
|
|
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
|
|
|
|
|
|
|
uint8 num_specs; ///< Number of specs in the speclist
|
|
|
|
StationSpecList *speclist; ///< List of station specs of this station
|
|
|
|
|
|
|
|
Date build_date; ///< Date of construction
|
|
|
|
|
|
|
|
uint16 random_bits; ///< Random bits assigned to this station
|
|
|
|
byte waiting_triggers; ///< Waiting triggers (NewGRF) for this station
|
|
|
|
uint8 cached_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen.
|
2018-05-21 21:08:39 +00:00
|
|
|
CargoTypes cached_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask
|
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
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2013-11-24 14:41:19 +00:00
|
|
|
virtual uint32 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;
|
|
|
|
|
2020-01-06 20:40:31 +00:00
|
|
|
inline const char *GetCachedName() const
|
|
|
|
{
|
2020-05-17 21:31:59 +00:00
|
|
|
if (!this->name.empty()) return this->name.c_str();
|
2020-01-06 20:40:31 +00:00
|
|
|
if (this->cached_name.empty()) this->FillCachedName();
|
|
|
|
return this->cached_name.c_str();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
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 */
|