From 43eda3dfbf45a8f5060aaca3da9b8cad59a1aad8 Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 21 Jul 2009 11:11:05 +0000 Subject: [PATCH] (svn r16896) -Codechange: make station spec allocation and station animation functions work for both stations and waypoints --- src/newgrf_station.cpp | 107 +++++++++++++++++++++-------------------- src/newgrf_station.h | 4 +- src/station_base.h | 16 ++++++ src/station_cmd.cpp | 36 ++++++++++++++ src/waypoint.cpp | 15 ++++++ src/waypoint.h | 2 + 6 files changed, 126 insertions(+), 54 deletions(-) diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 0b195e0fd1..f340123592 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -31,6 +31,48 @@ enum { MAX_SPECLIST = 255, }; +enum TriggerArea { + TA_TILE, + TA_PLATFORM, + TA_WHOLE, +}; + +struct ETileArea : TileArea { + ETileArea(const BaseStation *st, TileIndex tile, TriggerArea ta) + { + switch (ta) { + default: NOT_REACHED(); + + case TA_TILE: + this->tile = tile; + this->w = 1; + this->h = 1; + break; + + case TA_PLATFORM: { + TileIndex start, end; + Axis axis = GetRailStationAxis(tile); + TileIndexDiff delta = TileOffsByDiagDir(AxisToDiagDir(axis)); + + for (end = tile; IsRailwayStationTile(end + delta) && IsCompatibleTrainStationTile(tile, end + delta); end += delta) { /* Nothing */ } + for (start = tile; IsRailwayStationTile(start - delta) && IsCompatibleTrainStationTile(tile, start - delta); start -= delta) { /* Nothing */ } + + this->tile = start; + this->w = TileX(end) - TileX(start) + 1; + this->h = TileY(end) - TileY(start) + 1; + break; + } + + case TA_WHOLE: + st->GetTileArea(this, Station::IsExpected(st) ? STATION_RAIL : STATION_WAYPOINT); + this->w++; + this->h++; + break; + } + } +}; + + /** * Reset station classes to their default state. * This includes initialising the Default and Waypoint classes with an empty @@ -734,7 +776,7 @@ uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, con * @param exec Whether to actually allocate the spec. * @return Index within the Station's spec list, or -1 if the allocation failed. */ -int AllocateSpecToStation(const StationSpec *statspec, Station *st, bool exec) +int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec) { uint i; @@ -784,17 +826,22 @@ int AllocateSpecToStation(const StationSpec *statspec, Station *st, bool exec) * @param specindex Index of the custom station within the Station's spec list. * @return Indicates whether the StationSpec was deallocated. */ -void DeallocateSpecFromStation(Station *st, byte specindex) +void DeallocateSpecFromStation(BaseStation *st, byte specindex) { /* specindex of 0 (default) is never freeable */ if (specindex == 0) return; + ETileArea area = ETileArea(st, INVALID_TILE, TA_WHOLE); /* Check all tiles over the station to check if the specindex is still in use */ - BEGIN_TILE_LOOP(tile, st->trainst_w, st->trainst_h, st->train_tile) { - if (IsRailwayStationTile(tile) && GetStationIndex(tile) == st->index && GetCustomStationSpecIndex(tile) == specindex) { - return; + for (uint y = 0; y < area.h; y++) { + for (uint x = 0; x < area.w; x++) { + if (st->TileBelongsToRailStation(area.tile) && GetCustomStationSpecIndex(area.tile) == specindex) { + return; + } + area.tile += TileDiffXY(1, 0); } - } END_TILE_LOOP(tile, st->trainst_w, st->trainst_h, st->train_tile) + area.tile += TileDiffXY(-area.w, 1); + } /* This specindex is no longer in use, so deallocate it */ st->speclist[specindex].spec = NULL; @@ -1020,51 +1067,6 @@ static void ChangeStationAnimationFrame(const StationSpec *ss, const BaseStation if (GB(callback, 8, 7) != 0) PlayTileSound(ss->grffile, GB(callback, 8, 7), tile); } -enum TriggerArea { - TA_TILE, - TA_PLATFORM, - TA_WHOLE, -}; - -struct TileArea { - TileIndex tile; - uint8 w; - uint8 h; - - TileArea(const Station *st, TileIndex tile, TriggerArea ta) - { - switch (ta) { - default: NOT_REACHED(); - - case TA_TILE: - this->tile = tile; - this->w = 1; - this->h = 1; - break; - - case TA_PLATFORM: { - TileIndex start, end; - Axis axis = GetRailStationAxis(tile); - TileIndexDiff delta = TileOffsByDiagDir(AxisToDiagDir(axis)); - - for (end = tile; IsRailwayStationTile(end + delta) && IsCompatibleTrainStationTile(tile, end + delta); end += delta) { /* Nothing */ } - for (start = tile; IsRailwayStationTile(start - delta) && IsCompatibleTrainStationTile(tile, start - delta); start -= delta) { /* Nothing */ } - - this->tile = start; - this->w = TileX(end) - TileX(start) + 1; - this->h = TileY(end) - TileY(start) + 1; - break; - } - - case TA_WHOLE: - this->tile = st->train_tile; - this->w = st->trainst_w + 1; - this->h = st->trainst_h + 1; - break; - } - } -}; - void StationAnimationTrigger(const BaseStation *st, TileIndex tile, StatAnimTrigger trigger, CargoID cargo_type) { /* List of coverage areas for each animation trigger */ @@ -1080,8 +1082,9 @@ void StationAnimationTrigger(const BaseStation *st, TileIndex tile, StatAnimTrig if (!HasBit(st->cached_anim_triggers, trigger)) return; uint16 random_bits = Random(); - TileArea area = TileArea(Station::From(st), tile, tas[trigger]); + ETileArea area = ETileArea(st, tile, tas[trigger]); + /* Check all tiles over the station to check if the specindex is still in use */ for (uint y = 0; y < area.h; y++) { for (uint x = 0; x < area.w; x++) { if (st->TileBelongsToRailStation(area.tile)) { diff --git a/src/newgrf_station.h b/src/newgrf_station.h index 3031a4ca90..bc84b49838 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -136,10 +136,10 @@ SpriteID GetCustomStationGroundRelocation(const StationSpec *statspec, const Bas 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); +int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exec); /* Deallocate a StationSpec from a Station. Called when removing a single station tile. */ -void DeallocateSpecFromStation(Station *st, byte specindex); +void DeallocateSpecFromStation(BaseStation *st, byte specindex); /* Draw representation of a station tile for GUI purposes. */ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station); diff --git a/src/station_base.h b/src/station_base.h index b68858a59b..18f7c9ca57 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -77,6 +77,13 @@ struct StationRect : public Rect { StationRect& operator = (Rect src); }; +/** Represents the covered area */ +struct TileArea { + TileIndex tile; ///< The base tile of the area + uint8 w; ///< The width of the area + uint8 h; ///< The height of the area +}; + /** Base class for all station-ish types */ struct BaseStation { TileIndex xy; ///< Base tile of the station @@ -125,6 +132,13 @@ struct BaseStation { */ virtual void UpdateVirtCoord() = 0; + /** + * 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; + /** * Get the base station belonging to a specific tile. * @param tile The tile to get the base station from. @@ -258,6 +272,8 @@ public: /* virtual */ uint32 GetNewGRFVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) const; + /* virtual */ void GetTileArea(TileArea *ta, StationType type) const; + /** * Determines whether a station is a buoy only. * @todo Ditch this encoding of buoys diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 877e705b60..f21a2e1e1f 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -368,6 +368,42 @@ static Station *GetClosestDeletedStation(TileIndex tile) return best_station; } + +void Station::GetTileArea(TileArea *ta, StationType type) const +{ + switch (type) { + case STATION_RAIL: + ta->tile = this->train_tile; + ta->w = this->trainst_w; + ta->h = this->trainst_h; + return; + + case STATION_AIRPORT: + ta->tile = this->airport_tile; + ta->w = this->Airport()->size_x; + ta->h = this->Airport()->size_y; + + case STATION_TRUCK: + ta->tile = this->truck_stops != NULL ? this->truck_stops->xy : INVALID_TILE; + break; + + case STATION_BUS: + ta->tile = this->bus_stops != NULL ? this->bus_stops->xy : INVALID_TILE; + break; + + case STATION_DOCK: + case STATION_OILRIG: + case STATION_BUOY: + ta->tile = this->dock_tile; + break; + + default: NOT_REACHED(); + } + + ta->w = 1; + ta->h = 1; +} + /** * Update the virtual coords needed to draw the station sign. */ diff --git a/src/waypoint.cpp b/src/waypoint.cpp index 9e8e7da139..70ec5c3f58 100644 --- a/src/waypoint.cpp +++ b/src/waypoint.cpp @@ -44,6 +44,21 @@ void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype) } } +void Waypoint::GetTileArea(TileArea *ta, StationType type) const +{ + switch (type) { + case STATION_BUOY: + case STATION_WAYPOINT: + break; + + default: NOT_REACHED(); + } + + ta->tile = this->xy; + ta->w = 1; + ta->h = 1; +} + Waypoint::~Waypoint() { if (CleaningPool()) return; diff --git a/src/waypoint.h b/src/waypoint.h index c7d1513500..f6d5a317d8 100644 --- a/src/waypoint.h +++ b/src/waypoint.h @@ -32,6 +32,8 @@ struct Waypoint : WaypointPool::PoolItem<&_waypoint_pool>, SpecializedStation