00001
00002
00005 #ifndef VEHICLE_BASE_H
00006 #define VEHICLE_BASE_H
00007
00008 #include "vehicle_type.h"
00009 #include "track_type.h"
00010 #include "rail_type.h"
00011 #include "road_type.h"
00012 #include "cargo_type.h"
00013 #include "direction_type.h"
00014 #include "gfx_type.h"
00015 #include "command_type.h"
00016 #include "date_type.h"
00017 #include "company_base.h"
00018 #include "company_type.h"
00019 #include "oldpool.h"
00020 #include "order_base.h"
00021 #include "cargopacket.h"
00022 #include "texteff.hpp"
00023 #include "group_type.h"
00024 #include "engine_type.h"
00025 #include "order_func.h"
00026 #include "transport_type.h"
00027
00029 enum RoadVehicleStates {
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 RVSB_IN_DEPOT = 0xFE,
00044 RVSB_WORMHOLE = 0xFF,
00045
00046
00047 RVS_USING_SECOND_BAY = 1,
00048 RVS_IS_STOPPING = 2,
00049 RVS_DRIVE_SIDE = 4,
00050 RVS_IN_ROAD_STOP = 5,
00051 RVS_IN_DT_ROAD_STOP = 6,
00052
00053
00054 RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP,
00055 RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END,
00056 RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP,
00057 RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
00058
00059 RVSB_TRACKDIR_MASK = 0x0F,
00060 RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09
00061 };
00062
00063 enum VehStatus {
00064 VS_HIDDEN = 0x01,
00065 VS_STOPPED = 0x02,
00066 VS_UNCLICKABLE = 0x04,
00067 VS_DEFPAL = 0x08,
00068 VS_TRAIN_SLOWING = 0x10,
00069 VS_SHADOW = 0x20,
00070 VS_AIRCRAFT_BROKEN = 0x40,
00071 VS_CRASHED = 0x80,
00072 };
00073
00074 enum VehicleFlags {
00075 VF_LOADING_FINISHED,
00076 VF_CARGO_UNLOADING,
00077 VF_BUILT_AS_PROTOTYPE,
00078 VF_TIMETABLE_STARTED,
00079 VF_AUTOFILL_TIMETABLE,
00080 VF_AUTOFILL_PRES_WAIT_TIME,
00081 };
00082
00083 struct VehicleRail {
00084
00085 Vehicle *other_multiheaded_part;
00086
00087
00088 const struct SpriteGroup *cached_override;
00089
00090 uint16 last_speed;
00091 uint16 crash_anim_pos;
00092
00093
00094 uint32 cached_power;
00095 uint16 cached_max_speed;
00096 uint16 cached_total_length;
00097 uint8 cached_veh_length;
00098 bool cached_tilt;
00099
00100
00101 uint32 cached_weight;
00102 uint32 cached_veh_weight;
00103 uint32 cached_max_te;
00104
00112 byte cached_vis_effect;
00113 byte user_def_data;
00114
00115
00116
00117 EngineID first_engine;
00118
00119 uint16 flags;
00120 TrackBitsByte track;
00121 byte force_proceed;
00122 RailTypeByte railtype;
00123 RailTypes compatible_railtypes;
00124 };
00125
00126 enum VehicleRailFlags {
00127 VRF_REVERSING = 0,
00128
00129
00130 VRF_GOINGUP = 1,
00131 VRF_GOINGDOWN = 2,
00132
00133
00134 VRF_POWEREDWAGON = 3,
00135
00136
00137 VRF_REVERSE_DIRECTION = 4,
00138
00139
00140 VRF_NO_PATH_TO_DESTINATION = 5,
00141
00142
00143 VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
00144
00145
00146 VRF_TOGGLE_REVERSE = 7,
00147
00148
00149 VRF_TRAIN_STUCK = 8,
00150 };
00151
00152 struct VehicleAir {
00153 uint16 crashed_counter;
00154 uint16 cached_max_speed;
00155 byte pos;
00156 byte previous_pos;
00157 StationID targetairport;
00158 byte state;
00159 };
00160
00161 struct VehicleRoad {
00162 byte state;
00163 byte frame;
00164 uint16 blocked_ctr;
00165 byte overtaking;
00166 byte overtaking_ctr;
00167 uint16 crashed_ctr;
00168 byte reverse_ctr;
00169 struct RoadStop *slot;
00170 byte slot_age;
00171 EngineID first_engine;
00172 byte cached_veh_length;
00173
00174 RoadType roadtype;
00175 RoadTypes compatible_roadtypes;
00176 };
00177
00178 struct VehicleEffect {
00179 uint16 animation_state;
00180 byte animation_substate;
00181 };
00182
00183 struct VehicleDisaster {
00184 uint16 image_override;
00185 VehicleID big_ufo_destroyer_target;
00186 };
00187
00188 struct VehicleShip {
00189 TrackBitsByte state;
00190 };
00191
00192 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
00193
00194
00195 struct SaveLoad;
00196 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
00197 struct LoadgameState;
00198 extern bool LoadOldVehicle(LoadgameState *ls, int num);
00199
00200 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool>, BaseVehicle {
00201 private:
00202 Vehicle *next;
00203 Vehicle *previous;
00204 Vehicle *first;
00205
00206 Vehicle *next_shared;
00207 Vehicle *previous_shared;
00208 public:
00209 friend const SaveLoad *GetVehicleDescription(VehicleType vt);
00210 friend void AfterLoadVehicles(bool part_of_load);
00211 friend bool LoadOldVehicle(LoadgameState *ls, int num);
00212
00213 char *name;
00214
00215 TileIndex tile;
00216
00222 TileIndex dest_tile;
00223
00224 Money profit_this_year;
00225 Money profit_last_year;
00226 Money value;
00227
00228
00229 uint32 current_order_time;
00230 int32 lateness_counter;
00231
00232
00233
00234 Rect coord;
00235 Vehicle *next_hash;
00236 Vehicle *next_new_hash;
00237 Vehicle **old_new_hash;
00238
00239 SpriteID colourmap;
00240
00241
00242 Year build_year;
00243 Date age;
00244 Date max_age;
00245 Date date_of_last_service;
00246 Date service_interval;
00247 uint16 reliability;
00248 uint16 reliability_spd_dec;
00249 byte breakdown_ctr;
00250 byte breakdown_delay;
00251 byte breakdowns_since_last_service;
00252 byte breakdown_chance;
00253
00254 int32 x_pos;
00255 int32 y_pos;
00256 byte z_pos;
00257 DirectionByte direction;
00258
00259 OwnerByte owner;
00260 byte spritenum;
00261
00262
00263 uint16 cur_image;
00264 byte x_extent;
00265 byte y_extent;
00266 byte z_extent;
00267 int8 x_offs;
00268 int8 y_offs;
00269 EngineID engine_type;
00270
00271 TextEffectID fill_percent_te_id;
00272 UnitID unitnumber;
00273
00274 uint16 max_speed;
00275 uint16 cur_speed;
00276 byte subspeed;
00277 byte acceleration;
00278 uint32 motion_counter;
00279 byte progress;
00280
00281
00282
00283
00284 byte random_bits;
00285 byte waiting_triggers;
00286
00287 StationID last_station_visited;
00288
00289 CargoID cargo_type;
00290 byte cargo_subtype;
00291 uint16 cargo_cap;
00292 CargoList cargo;
00293
00294 byte day_counter;
00295 byte tick_counter;
00296 byte running_ticks;
00297
00298 byte vehstatus;
00299 Order current_order;
00300 VehicleOrderID cur_order_index;
00301
00302 union {
00303 OrderList *list;
00304 Order *old;
00305 } orders;
00306
00307 byte vehicle_flags;
00308 uint16 load_unload_time_rem;
00309
00310 GroupID group_id;
00311
00312 byte subtype;
00313
00314 union {
00315 VehicleRail rail;
00316 VehicleAir air;
00317 VehicleRoad road;
00318 VehicleEffect effect;
00319 VehicleDisaster disaster;
00320 VehicleShip ship;
00321 } u;
00322
00323
00324 uint8 cache_valid;
00325 uint32 cached_var40;
00326 uint32 cached_var41;
00327 uint32 cached_var42;
00328 uint32 cached_var43;
00329
00336 static bool AllocateList(Vehicle **vl, int num);
00337
00339 Vehicle();
00340
00342 void PreDestructor();
00344 virtual ~Vehicle();
00345
00346 void BeginLoading();
00347 void LeaveStation();
00348
00354 void HandleLoading(bool mode = false);
00355
00360 virtual const char *GetTypeString() const { return "base vehicle"; }
00361
00370 virtual void MarkDirty() {}
00371
00377 virtual void UpdateDeltaXY(Direction direction) {}
00378
00383 virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
00384
00388 virtual void PlayLeaveStationSound() const {}
00389
00393 virtual bool IsPrimaryVehicle() const { return false; }
00394
00400 virtual SpriteID GetImage(Direction direction) const { return 0; }
00401
00406 FORCEINLINE void InvalidateNewGRFCache()
00407 {
00408 this->cache_valid = 0;
00409 }
00410
00415 FORCEINLINE void InvalidateNewGRFCacheOfChain()
00416 {
00417 for (Vehicle *u = this; u != NULL; u = u->Next()) {
00418 u->InvalidateNewGRFCache();
00419 }
00420 }
00421
00426 virtual int GetDisplaySpeed() const { return 0; }
00427
00432 virtual int GetDisplayMaxSpeed() const { return 0; }
00433
00438 virtual Money GetRunningCost() const { return 0; }
00439
00444 virtual bool IsInDepot() const { return false; }
00445
00450 virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
00451
00455 virtual void Tick() {};
00456
00460 virtual void OnNewDay() {};
00461
00466 Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
00467
00472 Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
00473
00478 Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
00479
00484 void SetNext(Vehicle *next);
00485
00491 inline Vehicle *Next() const { return this->next; }
00492
00498 inline Vehicle *Previous() const { return this->previous; }
00499
00504 inline Vehicle *First() const { return this->first; }
00505
00506
00511 inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
00512
00518 void AddToShared(Vehicle *shared_chain);
00519
00523 void RemoveFromShared();
00524
00529 inline Vehicle *NextShared() const { return this->next_shared; }
00530
00535 inline Vehicle *PreviousShared() const { return this->previous_shared; }
00536
00541 inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
00542
00547 inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); }
00548
00553 inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); }
00554
00561 inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
00562 {
00563 this->unitnumber = src->unitnumber;
00564
00565 this->cur_order_index = src->cur_order_index;
00566 this->current_order = src->current_order;
00567 this->dest_tile = src->dest_tile;
00568
00569 this->profit_this_year = src->profit_this_year;
00570 this->profit_last_year = src->profit_last_year;
00571
00572 this->current_order_time = src->current_order_time;
00573 this->lateness_counter = src->lateness_counter;
00574
00575 this->service_interval = src->service_interval;
00576 }
00577
00578 bool NeedsAutorenewing(const Company *c) const;
00579
00586 bool NeedsServicing() const;
00587
00593 bool NeedsAutomaticServicing() const;
00594
00602 virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
00603
00612 virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
00613
00620 CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
00621 };
00622
00631 struct DisasterVehicle : public Vehicle {
00633 DisasterVehicle() { this->type = VEH_DISASTER; }
00634
00636 virtual ~DisasterVehicle() {}
00637
00638 const char *GetTypeString() const { return "disaster vehicle"; }
00639 void UpdateDeltaXY(Direction direction);
00640 void Tick();
00641 };
00642
00651 struct InvalidVehicle : public Vehicle {
00653 InvalidVehicle() { this->type = VEH_INVALID; }
00654
00656 virtual ~InvalidVehicle() {}
00657
00658 const char *GetTypeString() const { return "invalid vehicle"; }
00659 void Tick() {}
00660 };
00661
00662 static inline VehicleID GetMaxVehicleIndex()
00663 {
00664
00665
00666
00667
00668
00669 return GetVehiclePoolSize() - 1;
00670 }
00671
00672 static inline uint GetNumVehicles()
00673 {
00674 return GetVehiclePoolSize();
00675 }
00676
00677 #define FOR_ALL_VEHICLES_FROM(v, start) for (v = GetVehicle(start); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) if (v->IsValid())
00678 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
00679
00685 static inline bool IsValidVehicleID(uint index)
00686 {
00687 return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid();
00688 }
00689
00690
00692 struct FreeUnitIDGenerator {
00693 bool *cache;
00694 UnitID maxid;
00695 UnitID curid;
00696
00703 FreeUnitIDGenerator(VehicleType type, CompanyID owner);
00704
00706 UnitID NextID();
00707
00709 ~FreeUnitIDGenerator() { free(this->cache); }
00710 };
00711
00712
00713 static inline Order *GetVehicleOrder(const Vehicle *v, int index) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetOrderAt(index); }
00714
00720 static inline Order *GetLastVehicleOrder(const Vehicle *v) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetLastOrder(); }
00721
00733 Trackdir GetVehicleTrackdir(const Vehicle *v);
00734
00735 void CheckVehicle32Day(Vehicle *v);
00736
00737 static const int32 INVALID_COORD = 0x7fffffff;
00738
00739 #endif