diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/newgrf_spritegroup.h | 2 | ||||
-rw-r--r-- | src/newgrf_station.cpp | 86 | ||||
-rw-r--r-- | src/newgrf_station.h | 10 | ||||
-rw-r--r-- | src/station.cpp | 5 | ||||
-rw-r--r-- | src/station_base.h | 75 | ||||
-rw-r--r-- | src/station_type.h | 1 |
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; |