tron@2186: /* $Id$ */ tron@2186: belugas@6420: /** @file station.h */ belugas@6420: truelight@0: #ifndef STATION_H truelight@0: #define STATION_H truelight@0: tron@6032: #include "airport.h" matthijs@5216: #include "oldpool.h" darkvater@405: #include "sprite.h" rubidium@8102: #include "road_type.h" peter1138@2963: #include "newgrf_station.h" rubidium@7010: #include "cargopacket.h" rubidium@8119: #include "cargo_type.h" rubidium@8213: #include "town_type.h" rubidium@8121: #include "core/geometry_type.hpp" rubidium@6500: #include rubidium@7891: #include truelight@0: rubidium@7377: struct Station; rubidium@7377: struct RoadStop; rubidium@7377: rubidium@7377: DECLARE_OLD_POOL(Station, Station, 6, 1000) rubidium@7377: DECLARE_OLD_POOL(RoadStop, RoadStop, 5, 2000) rubidium@7377: truelight@6261: static const byte INITIAL_STATION_RATING = 175; tron@5670: rubidium@6248: struct GoodsEntry { rubidium@7474: enum AcceptancePickup { rubidium@7474: ACCEPTANCE, rubidium@7474: PICKUP rubidium@7474: }; rubidium@7474: tron@5670: GoodsEntry() : rubidium@7474: acceptance_pickup(0), rubidium@7013: days_since_pickup(255), truelight@6261: rating(INITIAL_STATION_RATING), tron@5670: last_speed(0), rubidium@7010: last_age(255) tron@5670: {} tron@5670: rubidium@7474: byte acceptance_pickup; truelight@0: byte days_since_pickup; truelight@0: byte rating; truelight@0: byte last_speed; truelight@0: byte last_age; rubidium@7010: CargoList cargo; ///< The cargo packets of cargo waiting in this station rubidium@6248: }; truelight@0: celestar@5836: /** A Stop for a Road Vehicle */ rubidium@7377: struct RoadStop : PoolItem { celestar@5836: /** Types of RoadStops */ celestar@5836: enum Type { celestar@5836: BUS, ///< A standard stop for buses celestar@5836: TRUCK ///< A standard stop for trucks celestar@5836: }; celestar@5708: truelight@7404: static const int cDebugCtorLevel = 5; ///< Debug level on which Contructor / Destructor messages are printed celestar@5837: static const uint LIMIT = 16; ///< The maximum amount of roadstops that are allowed at a single station rubidium@5990: static const uint MAX_BAY_COUNT = 2; ///< The maximum number of loading bays celestar@5836: celestar@5836: TileIndex xy; ///< Position on the map rubidium@5990: byte status; ///< Current status of the Stop. Like which spot is taken. Access using *Bay and *Busy functions. celestar@5836: byte num_vehicles; ///< Number of vehicles currently slotted to this stop celestar@5836: struct RoadStop *next; ///< Next stop of the given type at this station celestar@5708: rubidium@7377: RoadStop(TileIndex tile = 0); rubidium@7377: virtual ~RoadStop(); celestar@5708: rubidium@7496: /** rubidium@7496: * Determines whether a road stop exists rubidium@7496: * @return true if and only is the road stop exists rubidium@7496: */ rubidium@7496: inline bool IsValid() const { return this->xy != 0; } rubidium@5990: rubidium@5990: /* For accessing status */ rubidium@5990: bool HasFreeBay() const; rubidium@6012: bool IsFreeBay(uint nr) const; rubidium@5990: uint AllocateBay(); rubidium@6012: void AllocateDriveThroughBay(uint nr); rubidium@5990: void FreeBay(uint nr); rubidium@5990: bool IsEntranceBusy() const; rubidium@5990: void SetEntranceBusy(bool busy); rubidium@7469: rubidium@7469: RoadStop *GetNextRoadStop(const Vehicle *v) const; celestar@5836: }; celestar@1217: rubidium@6248: struct StationSpecList { peter1138@3587: const StationSpec *spec; belugas@6420: uint32 grfid; ///< GRF ID of this custom station belugas@6420: uint8 localidx; ///< Station ID within GRF of station rubidium@6248: }; peter1138@3587: KUDr@5676: /** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */ KUDr@5676: struct StationRect : public Rect { KUDr@5676: enum StationRectMode KUDr@5676: { KUDr@5676: ADD_TEST = 0, KUDr@5676: ADD_TRY, KUDr@5676: ADD_FORCE KUDr@5676: }; KUDr@5676: KUDr@5676: StationRect(); KUDr@5676: void MakeEmpty(); celestar@5910: bool PtInExtendedRect(int x, int y, int distance = 0) const; KUDr@5676: bool IsEmpty() const; KUDr@5676: bool BeforeAddTile(TileIndex tile, StationRectMode mode); KUDr@5676: bool BeforeAddRect(TileIndex tile, int w, int h, StationRectMode mode); KUDr@5676: bool AfterRemoveTile(Station *st, TileIndex tile); KUDr@5676: bool AfterRemoveRect(Station *st, TileIndex tile, int w, int h); KUDr@5676: KUDr@5676: static bool ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a); KUDr@5676: KUDr@5676: StationRect& operator = (Rect src); KUDr@5676: }; KUDr@5676: rubidium@7377: struct Station : PoolItem { rubidium@7469: public: rubidium@7469: RoadStop *GetPrimaryRoadStop(RoadStop::Type type) const rubidium@7469: { rubidium@7469: return type == RoadStop::BUS ? bus_stops : truck_stops; rubidium@7469: } tron@5876: rubidium@7469: RoadStop *GetPrimaryRoadStop(const Vehicle *v) const; rubidium@7469: rubidium@7469: const AirportFTAClass *Airport() const rubidium@7469: { rubidium@7469: if (airport_tile == 0) return GetAirport(AT_DUMMY); rubidium@7469: return GetAirport(airport_type); rubidium@7469: } tron@6032: truelight@0: TileIndex xy; celestar@1217: RoadStop *bus_stops; celestar@1217: RoadStop *truck_stops; truelight@0: TileIndex train_tile; truelight@0: TileIndex airport_tile; truelight@0: TileIndex dock_tile; truelight@0: Town *town; peter1138@8258: StringID string_id; ///< Default name (town area) of station peter1138@8258: char *name; ///< Custom name truelight@0: truelight@0: ViewportSign sign; truelight@0: truelight@0: uint16 had_vehicle_of_type; truelight@193: truelight@0: byte time_since_load; truelight@0: byte time_since_unload; truelight@0: byte delete_ctr; rubidium@5587: PlayerByte owner; truelight@0: byte facilities; truelight@0: byte airport_type; truelight@0: belugas@6420: /* trainstation width/height */ truelight@0: byte trainst_w, trainst_h; truelight@0: peter1138@3587: /** List of custom stations (StationSpecs) allocated to the station */ peter1138@3786: uint8 num_specs; peter1138@3587: StationSpecList *speclist; peter1138@3587: rubidium@4289: Date build_date; truelight@0: belugas@6420: uint64 airport_flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32 truelight@0: celestar@3580: byte last_vehicle_type; rubidium@6500: std::list loading_vehicles; truelight@0: GoodsEntry goods[NUM_CARGO]; celestar@1217: peter1138@3687: uint16 random_bits; peter1138@3687: byte waiting_triggers; peter1138@3687: KUDr@5676: StationRect rect; ///< Station spread out rectangle (not saved) maintained by StationRect_xxx() functions KUDr@5665: truelight@7404: static const int cDebugCtorLevel = 5; KUDr@5665: KUDr@5665: Station(TileIndex tile = 0); rubidium@7377: virtual ~Station(); rubidium@7376: KUDr@5721: void AddFacility(byte new_facility_bit, TileIndex facil_xy); rubidium@7545: rubidium@7545: /** rubidium@7545: * Mark the sign of a station dirty for repaint. rubidium@7545: * rubidium@7545: * @ingroup dirty rubidium@7545: */ KUDr@5665: void MarkDirty() const; rubidium@7545: rubidium@7545: /** rubidium@7545: * Marks the tiles of the station as dirty. rubidium@7545: * rubidium@7545: * @ingroup dirty rubidium@7545: */ peter1138@6823: void MarkTilesDirty(bool cargo_change) const; KUDr@5665: bool TileBelongsToRailStation(TileIndex tile) const; celestar@5998: uint GetPlatformLength(TileIndex tile, DiagDirection dir) const; celestar@5998: uint GetPlatformLength(TileIndex tile) const; celestar@5896: bool IsBuoy() const; rubidium@7496: rubidium@7496: /** rubidium@7496: * Determines whether a station exists rubidium@7496: * @return true if and only is the station exists rubidium@7496: */ rubidium@7496: inline bool IsValid() const { return this->xy != 0; } truelight@0: }; truelight@0: rubidium@7272: enum StationType { rubidium@7272: STATION_RAIL, rubidium@7272: STATION_AIRPORT, rubidium@7272: STATION_TRUCK, rubidium@7272: STATION_BUS, rubidium@7272: STATION_OILRIG, rubidium@7272: STATION_DOCK, rubidium@7272: STATION_BUOY rubidium@7272: }; rubidium@7272: truelight@0: enum { rubidium@4344: FACIL_TRAIN = 0x01, rubidium@4344: FACIL_TRUCK_STOP = 0x02, rubidium@4344: FACIL_BUS_STOP = 0x04, rubidium@4344: FACIL_AIRPORT = 0x08, rubidium@4344: FACIL_DOCK = 0x10, truelight@0: }; truelight@0: truelight@0: enum { rubidium@4344: // HVOT_PENDING_DELETE = 1 << 0, // not needed anymore belugas@3554: HVOT_TRAIN = 1 << 1, belugas@3554: HVOT_BUS = 1 << 2, belugas@3554: HVOT_TRUCK = 1 << 3, celestar@1217: HVOT_AIRCRAFT = 1 << 4, belugas@3554: HVOT_SHIP = 1 << 5, matthijs@1751: /* This bit is used to mark stations. No, it does not belong here, but what matthijs@1751: * can we do? ;-) */ belugas@3554: HVOT_BUOY = 1 << 6 truelight@0: }; truelight@0: rubidium@6248: enum CatchmentArea { celestar@5601: CA_NONE = 0, rubidium@4344: CA_BUS = 3, rubidium@4344: CA_TRUCK = 3, rubidium@4344: CA_TRAIN = 4, rubidium@7498: CA_DOCK = 5, rubidium@7498: rubidium@7498: MAX_CATCHMENT = 10, ///< Airports have a catchment up to this number. rubidium@6248: }; Celestar@568: tron@2498: void ModifyStationRatingAround(TileIndex tile, PlayerID owner, int amount, uint radius); truelight@0: rubidium@7891: /** A set of stations (\c const \c Station* ) */ rubidium@7891: typedef std::set StationSet; rubidium@7891: rubidium@7891: StationSet FindStationsAroundIndustryTile(TileIndex tile, int w, int h); rubidium@7891: tron@2498: void ShowStationViewWindow(StationID station); rubidium@6247: void UpdateAllStationVirtCoord(); truelight@0: rubidium@6247: static inline StationID GetMaxStationIndex() truelight@4354: { truelight@4354: /* TODO - This isn't the real content of the function, but truelight@4354: * with the new pool-system this will be replaced with one that matthijs@5247: * _really_ returns the highest index. Now it just returns truelight@4354: * the next safe value we are sure about everything is below. truelight@4354: */ matthijs@5247: return GetStationPoolSize() - 1; matthijs@5247: } matthijs@5247: rubidium@6247: static inline uint GetNumStations() matthijs@5247: { truelight@4354: return GetStationPoolSize(); truelight@4354: } truelight@4354: celestar@5996: static inline bool IsValidStationID(StationID index) truelight@4346: { celestar@5996: return index < GetStationPoolSize() && GetStation(index)->IsValid(); truelight@4346: } truelight@4346: celestar@5996: #define FOR_ALL_STATIONS_FROM(st, start) for (st = GetStation(start); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) if (st->IsValid()) truelight@1272: #define FOR_ALL_STATIONS(st) FOR_ALL_STATIONS_FROM(st, 0) truelight@919: truelight@1284: truelight@1284: /* Stuff for ROADSTOPS */ truelight@1284: celestar@5835: #define FOR_ALL_ROADSTOPS_FROM(rs, start) for (rs = GetRoadStop(start); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) if (rs->IsValid()) truelight@1284: #define FOR_ALL_ROADSTOPS(rs) FOR_ALL_ROADSTOPS_FROM(rs, 0) truelight@1284: truelight@1284: /* End of stuff for ROADSTOPS */ truelight@1284: truelight@1284: rubidium@6247: void AfterLoadStations(); tron@1424: void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, int w, int h, int rad); tron@1424: void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, int w, int h, int rad); darkvater@384: darkvater@384: rubidium@7272: const DrawTileSprites *GetStationTileLayout(StationType st, byte gfx); rubidium@7272: void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, RoadType roadtype, int image); tron@2520: celestar@5836: RoadStop * GetRoadStopByTile(TileIndex tile, RoadStop::Type type); celestar@5836: uint GetNumRoadStops(const Station* st, RoadStop::Type type); rubidium@6247: RoadStop * AllocateRoadStop(); celestar@3123: void ClearSlot(Vehicle *v); celestar@1217: smatz@8109: bool HasStationInUse(StationID station, PlayerID player); smatz@8109: tron@5884: void DeleteOilRig(TileIndex t); tron@5884: truelight@0: #endif /* STATION_H */