summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/newgrf_spritegroup.h2
-rw-r--r--src/newgrf_station.cpp86
-rw-r--r--src/newgrf_station.h10
-rw-r--r--src/station.cpp5
-rw-r--r--src/station_base.h75
-rw-r--r--src/station_type.h1
6 files changed, 118 insertions, 61 deletions
diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h
index 20ad65ead..eac8d5cf8 100644
--- a/src/newgrf_spritegroup.h
+++ b/src/newgrf_spritegroup.h
@@ -307,7 +307,7 @@ struct ResolverObject {
} canal;
struct {
TileIndex tile;
- const struct Station *st;
+ const struct BaseStation *st;
const struct StationSpec *statspec;
CargoID cargo_type;
} station;
diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp
index 483bf28c3..01c3bd988 100644
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -321,7 +321,7 @@ static uint32 GetRailContinuationInfo(TileIndex tile)
/* Station Resolver Functions */
static uint32 StationGetRandomBits(const ResolverObject *object)
{
- const Station *st = object->u.station.st;
+ const BaseStation *st = object->u.station.st;
const TileIndex tile = object->u.station.tile;
return (st == NULL ? 0 : st->random_bits) | (tile == INVALID_TILE ? 0 : GetStationTileRandomBits(tile) << 16);
}
@@ -329,14 +329,14 @@ static uint32 StationGetRandomBits(const ResolverObject *object)
static uint32 StationGetTriggers(const ResolverObject *object)
{
- const Station *st = object->u.station.st;
+ const BaseStation *st = object->u.station.st;
return st == NULL ? 0 : st->waiting_triggers;
}
static void StationSetTriggers(const ResolverObject *object, int triggers)
{
- Station *st = const_cast<Station *>(object->u.station.st);
+ BaseStation *st = const_cast<BaseStation *>(object->u.station.st);
assert(st != NULL);
st->waiting_triggers = triggers;
}
@@ -358,7 +358,7 @@ static struct {
static uint32 StationGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
{
- const Station *st = object->u.station.st;
+ const BaseStation *st = object->u.station.st;
TileIndex tile = object->u.station.tile;
if (object->scope == VSG_SCOPE_PARENT) {
@@ -425,15 +425,6 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
if (!HasBit(_svc.valid, 4)) { _svc.v47 = GetPlatformInfoHelper(tile, true, false, true); SetBit(_svc.valid, 4); }
return _svc.v47;
- case 0x48: { // Accepted cargo types
- CargoID cargo_type;
- uint32 value = 0;
-
- for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
- if (HasBit(st->goods[cargo_type].acceptance_pickup, GoodsEntry::PICKUP)) SetBit(value, cargo_type);
- }
- return value;
- }
case 0x49:
if (!HasBit(_svc.valid, 5)) { _svc.v49 = GetPlatformInfoHelper(tile, false, true, false); SetBit(_svc.valid, 5); }
return _svc.v49;
@@ -469,7 +460,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
uint32 res = GB(GetStationGfx(nearby_tile), 1, 2) << 12 | !!perpendicular << 11 | !!same_station << 10;
if (IsCustomStationSpecIndex(nearby_tile)) {
- const StationSpecList ssl = Station::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)];
+ const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)];
res |= 1 << (ssl.grfid != grfid ? 9 : 8) | ssl.localidx;
}
return res;
@@ -479,22 +470,40 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
case 0x82: return 50;
case 0x84: return st->string_id;
case 0x86: return 0;
- case 0x8A: return st->had_vehicle_of_type;
case 0xF0: return st->facilities;
- case 0xF1: return st->airport_type;
- case 0xF2: return st->truck_stops->status;
- case 0xF3: return st->bus_stops->status;
- case 0xF6: return st->airport_flags;
- case 0xF7: return GB(st->airport_flags, 8, 8);
case 0xFA: return Clamp(st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
}
+ return st->GetNewGRFVariable(object, variable, parameter, available);
+}
+
+uint32 Station::GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const
+{
+ switch (variable) {
+ case 0x48: { // Accepted cargo types
+ CargoID cargo_type;
+ uint32 value = 0;
+
+ for (cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
+ if (HasBit(this->goods[cargo_type].acceptance_pickup, GoodsEntry::PICKUP)) SetBit(value, cargo_type);
+ }
+ return value;
+ }
+
+ case 0x8A: return this->had_vehicle_of_type;
+ case 0xF1: return this->airport_type;
+ case 0xF2: return this->truck_stops->status;
+ case 0xF3: return this->bus_stops->status;
+ case 0xF6: return this->airport_flags;
+ case 0xF7: return GB(this->airport_flags, 8, 8);
+ }
+
/* Handle cargo variables with parameter, 0x60 to 0x65 */
if (variable >= 0x60 && variable <= 0x65) {
CargoID c = GetCargoTranslation(parameter, object->u.station.statspec->grffile);
if (c == CT_INVALID) return 0;
- const GoodsEntry *ge = &st->goods[c];
+ const GoodsEntry *ge = &this->goods[c];
switch (variable) {
case 0x60: return min(ge->cargo.Count(), 4095);
@@ -508,7 +517,7 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
/* Handle cargo variables (deprecated) */
if (variable >= 0x8C && variable <= 0xEC) {
- const GoodsEntry *g = &st->goods[GB(variable - 0x8C, 3, 4)];
+ const GoodsEntry *g = &this->goods[GB(variable - 0x8C, 3, 4)];
switch (GB(variable - 0x8C, 0, 3)) {
case 0: return g->cargo.Count();
case 1: return GB(min(g->cargo.Count(), 4095), 0, 4) | (GB(g->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1) << 7);
@@ -530,17 +539,19 @@ static uint32 StationGetVariable(const ResolverObject *object, byte variable, by
static const SpriteGroup *StationResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
{
- const Station *st = object->u.station.st;
+ const BaseStation *bst = object->u.station.st;
const StationSpec *statspec = object->u.station.statspec;
uint set;
uint cargo = 0;
CargoID cargo_type = object->u.station.cargo_type;
- if (st == NULL || statspec->sclass == STAT_CLASS_WAYP) {
+ if (bst == NULL || statspec->sclass == STAT_CLASS_WAYP) {
return group->loading[0];
}
+ const Station *st = Station::From(bst);
+
switch (cargo_type) {
case CT_INVALID:
case CT_DEFAULT_NA:
@@ -578,7 +589,7 @@ static const SpriteGroup *StationResolveReal(const ResolverObject *object, const
}
-static void NewStationResolver(ResolverObject *res, const StationSpec *statspec, const Station *st, TileIndex tile)
+static void NewStationResolver(ResolverObject *res, const StationSpec *statspec, const BaseStation *st, TileIndex tile)
{
res->GetRandomBits = StationGetRandomBits;
res->GetTriggers = StationGetTriggers;
@@ -609,11 +620,12 @@ static const SpriteGroup *ResolveStation(ResolverObject *object)
/* No station, so we are in a purchase list */
ctype = CT_PURCHASE;
} else {
+ const Station *st = Station::From(object->u.station.st);
/* Pick the first cargo that we have waiting */
const CargoSpec *cs;
FOR_ALL_CARGOSPECS(cs) {
if (object->u.station.statspec->spritegroup[cs->Index()] != NULL &&
- !object->u.station.st->goods[cs->Index()].cargo.Empty()) {
+ !st->goods[cs->Index()].cargo.Empty()) {
ctype = cs->Index();
break;
}
@@ -637,7 +649,7 @@ static const SpriteGroup *ResolveStation(ResolverObject *object)
return SpriteGroup::Resolve(group, object);
}
-SpriteID GetCustomStationRelocation(const StationSpec *statspec, const Station *st, TileIndex tile)
+SpriteID GetCustomStationRelocation(const StationSpec *statspec, const BaseStation *st, TileIndex tile)
{
const SpriteGroup *group;
ResolverObject object;
@@ -650,7 +662,7 @@ SpriteID GetCustomStationRelocation(const StationSpec *statspec, const Station *
}
-SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Station *st, TileIndex tile)
+SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const BaseStation *st, TileIndex tile)
{
const SpriteGroup *group;
ResolverObject object;
@@ -666,7 +678,7 @@ SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Sta
}
-uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, const Station *st, TileIndex tile)
+uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, const BaseStation *st, TileIndex tile)
{
const SpriteGroup *group;
ResolverObject object;
@@ -853,12 +865,12 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID
const StationSpec *GetStationSpec(TileIndex t)
{
- const Station *st;
+ const BaseStation *st;
uint specindex;
if (!IsCustomStationSpecIndex(t)) return NULL;
- st = Station::GetByTile(t);
+ st = BaseStation::GetByTile(t);
specindex = GetCustomStationSpecIndex(t);
return specindex < st->num_specs ? st->speclist[specindex].spec : NULL;
}
@@ -890,7 +902,7 @@ void AnimateStationTile(TileIndex tile)
const StationSpec *ss = GetStationSpec(tile);
if (ss == NULL) return;
- const Station *st = Station::GetByTile(tile);
+ const BaseStation *st = BaseStation::GetByTile(tile);
uint8 animation_speed = ss->anim_speed;
@@ -950,7 +962,7 @@ void AnimateStationTile(TileIndex tile)
}
-static void ChangeStationAnimationFrame(const StationSpec *ss, const Station *st, TileIndex tile, uint16 random_bits, StatAnimTrigger trigger, CargoID cargo_type)
+static void ChangeStationAnimationFrame(const StationSpec *ss, const BaseStation *st, TileIndex tile, uint16 random_bits, StatAnimTrigger trigger, CargoID cargo_type)
{
uint16 callback = GetStationCallback(CBID_STATION_ANIM_START_STOP, (random_bits << 16) | Random(), (uint8)trigger | (cargo_type << 8), ss, st, tile);
if (callback == CALLBACK_FAILED) return;
@@ -1015,7 +1027,7 @@ struct TileArea {
}
};
-void StationAnimationTrigger(const Station *st, TileIndex tile, StatAnimTrigger trigger, CargoID cargo_type)
+void StationAnimationTrigger(const BaseStation *st, TileIndex tile, StatAnimTrigger trigger, CargoID cargo_type)
{
/* List of coverage areas for each animation trigger */
static const TriggerArea tas[] = {
@@ -1023,14 +1035,14 @@ void StationAnimationTrigger(const Station *st, TileIndex tile, StatAnimTrigger
};
/* Get Station if it wasn't supplied */
- if (st == NULL) st = Station::GetByTile(tile);
+ if (st == NULL) st = BaseStation::GetByTile(tile);
/* Check the cached animation trigger bitmask to see if we need
* to bother with any further processing. */
if (!HasBit(st->cached_anim_triggers, trigger)) return;
uint16 random_bits = Random();
- TileArea area = TileArea(st, tile, tas[trigger]);
+ TileArea area = TileArea(Station::From(st), tile, tas[trigger]);
for (uint y = 0; y < area.h; y++) {
for (uint x = 0; x < area.w; x++) {
@@ -1056,7 +1068,7 @@ void StationAnimationTrigger(const Station *st, TileIndex tile, StatAnimTrigger
* Update the cached animation trigger bitmask for a station.
* @param st Station to update.
*/
-void StationUpdateAnimTriggers(Station *st)
+void StationUpdateAnimTriggers(BaseStation *st)
{
st->cached_anim_triggers = 0;
diff --git a/src/newgrf_station.h b/src/newgrf_station.h
index fa88c4064..3031a4ca9 100644
--- a/src/newgrf_station.h
+++ b/src/newgrf_station.h
@@ -131,9 +131,9 @@ uint32 GetPlatformInfo(Axis axis, byte tile, int platforms, int length, int x, i
/* Get sprite offset for a given custom station and station structure (may be
* NULL - that means we are in a build dialog). The station structure is used
* for variational sprite groups. */
-SpriteID GetCustomStationRelocation(const StationSpec *statspec, const Station *st, TileIndex tile);
-SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Station *st, TileIndex tile);
-uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, const Station *st, TileIndex tile);
+SpriteID GetCustomStationRelocation(const StationSpec *statspec, const BaseStation *st, TileIndex tile);
+SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const BaseStation *st, TileIndex tile);
+uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, const BaseStation *st, TileIndex tile);
/* Allocate a StationSpec to a Station. This is called once per build operation. */
int AllocateSpecToStation(const StationSpec *statspec, Station *st, bool exec);
@@ -155,7 +155,7 @@ enum StatAnimTrigger {
};
void AnimateStationTile(TileIndex tile);
-void StationAnimationTrigger(const Station *st, TileIndex tile, StatAnimTrigger trigger, CargoID cargo_type = CT_INVALID);
-void StationUpdateAnimTriggers(Station *st);
+void StationAnimationTrigger(const BaseStation *st, TileIndex tile, StatAnimTrigger trigger, CargoID cargo_type = CT_INVALID);
+void StationUpdateAnimTriggers(BaseStation *st);
#endif /* NEWGRF_STATION_H */
diff --git a/src/station.cpp b/src/station.cpp
index 8cb1a8cc4..6b583a07c 100644
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -44,6 +44,11 @@ Station::Station(TileIndex tile) :
/* this->random_bits is set in Station::AddFacility() */
}
+/* static */ BaseStation *BaseStation::GetByTile(TileIndex tile)
+{
+ return Station::GetByTile(tile);
+}
+
/**
* Clean up a station by clearing vehicle orders and invalidating windows.
* Aircraft-Hangar orders need special treatment here, as the hangars are
diff --git a/src/station_base.h b/src/station_base.h
index 1af0a067a..821ed1dd6 100644
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -77,10 +77,53 @@ struct StationRect : public Rect {
StationRect& operator = (Rect src);
};
+/** Base class for all station-ish types */
+struct BaseStation {
+ char *name; ///< Custom name
+ StringID string_id; ///< Default name (town area) of station
+
+ Town *town; ///< The town this station is associated with
+ OwnerByte owner; ///< The owner of this station
+ StationFacilityByte facilities; ///< The facilities that this station has
+
+ uint8 num_specs; ///< NOSAVE: Number of specs in the speclist
+ StationSpecList *speclist; ///< NOSAVE: 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.
+
+ /**
+ * 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
+ */
+ virtual uint32 GetNewGRFVariable(const struct ResolverObject *object, byte variable, byte parameter, bool *available) const = 0;
+
+ /**
+ * 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.
+ */
+ static BaseStation *GetByTile(TileIndex tile);
+};
+
typedef SmallVector<Industry *, 2> IndustryVector;
/** Station data structure */
-struct Station : StationPool::PoolItem<&_station_pool> {
+struct Station : StationPool::PoolItem<&_station_pool>, BaseStation {
public:
RoadStop *GetPrimaryRoadStop(RoadStopType type) const
{
@@ -101,12 +144,8 @@ public:
TileIndex train_tile;
TileIndex airport_tile;
TileIndex dock_tile;
- Town *town;
- /* Place to get a name from, in order of importance: */
- char *name; ///< Custom name
IndustryType indtype; ///< Industry type to get the name from
- StringID string_id; ///< Default name (town area) of station
ViewportSign sign;
@@ -115,19 +154,11 @@ public:
byte time_since_load;
byte time_since_unload;
byte delete_ctr;
- OwnerByte owner;
- StationFacilityByte facilities;
byte airport_type;
/* trainstation width/height */
byte trainst_w, trainst_h;
- /** List of custom stations (StationSpecs) allocated to the station */
- uint8 num_specs;
- StationSpecList *speclist;
-
- Date build_date; ///< Date of construction
-
uint64 airport_flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32
byte last_vehicle_type;
@@ -136,10 +167,6 @@ public:
IndustryVector industries_near; ///< Cached list of industries near the station that can accept cargo, @see DeliverGoodsToIndustry()
- uint16 random_bits;
- byte waiting_triggers;
- uint8 cached_anim_triggers; ///< Combined animation trigger bitmask, used to determine if trigger processing should happen.
-
StationRect rect; ///< Station spread out rectangle (not saved) maintained by StationRect_xxx() functions
Station(TileIndex tile = INVALID_TILE);
@@ -163,11 +190,13 @@ public:
uint GetCatchmentRadius() const;
- FORCEINLINE bool TileBelongsToRailStation(TileIndex tile) const
+ /* virtual */ FORCEINLINE bool TileBelongsToRailStation(TileIndex tile) const
{
return IsRailwayStationTile(tile) && GetStationIndex(tile) == this->index;
}
+ /* virtual */ uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const;
+
/**
* Determines whether a station is a buoy only.
* @todo Ditch this encoding of buoys
@@ -183,6 +212,16 @@ public:
}
static void PostDestructor(size_t index);
+
+ static FORCEINLINE Station *From(BaseStation *st)
+ {
+ return (Station *)st;
+ }
+
+ static FORCEINLINE const Station *From(const BaseStation *st)
+ {
+ return (const Station *)st;
+ }
};
#define FOR_ALL_STATIONS_FROM(var, start) FOR_ALL_ITEMS_FROM(Station, station_index, var, start)
diff --git a/src/station_type.h b/src/station_type.h
index 7d6342935..feb5ad42c 100644
--- a/src/station_type.h
+++ b/src/station_type.h
@@ -10,6 +10,7 @@
typedef uint16 StationID;
typedef uint16 RoadStopID;
+struct BaseStation;
struct Station;
struct RoadStop;
struct StationSpec;