vehicle_base.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef VEHICLE_BASE_H
00013 #define VEHICLE_BASE_H
00014
00015 #include "vehicle_type.h"
00016 #include "track_type.h"
00017 #include "cargo_type.h"
00018 #include "direction_type.h"
00019 #include "gfx_type.h"
00020 #include "command_type.h"
00021 #include "date_type.h"
00022 #include "company_base.h"
00023 #include "company_type.h"
00024 #include "core/pool_type.hpp"
00025 #include "order_base.h"
00026 #include "cargopacket.h"
00027 #include "texteff.hpp"
00028 #include "group_type.h"
00029 #include "engine_type.h"
00030 #include "order_func.h"
00031 #include "transport_type.h"
00032
00033 enum VehStatus {
00034 VS_HIDDEN = 0x01,
00035 VS_STOPPED = 0x02,
00036 VS_UNCLICKABLE = 0x04,
00037 VS_DEFPAL = 0x08,
00038 VS_TRAIN_SLOWING = 0x10,
00039 VS_SHADOW = 0x20,
00040 VS_AIRCRAFT_BROKEN = 0x40,
00041 VS_CRASHED = 0x80,
00042 };
00043
00044 enum VehicleFlags {
00045 VF_LOADING_FINISHED,
00046 VF_CARGO_UNLOADING,
00047 VF_BUILT_AS_PROTOTYPE,
00048 VF_TIMETABLE_STARTED,
00049 VF_AUTOFILL_TIMETABLE,
00050 VF_AUTOFILL_PRES_WAIT_TIME,
00051 };
00052
00054 struct VehicleCache {
00055 uint8 cache_valid;
00056 uint32 cached_var40;
00057 uint32 cached_var41;
00058 uint32 cached_var42;
00059 uint32 cached_var43;
00060 };
00061
00062 typedef Pool<Vehicle, VehicleID, 512, 64000> VehiclePool;
00063 extern VehiclePool _vehicle_pool;
00064
00065
00066 struct SaveLoad;
00067 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
00068 struct LoadgameState;
00069 extern bool LoadOldVehicle(LoadgameState *ls, int num);
00070 extern bool AfterLoadGame();
00071 extern void FixOldVehicles();
00072
00073 struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle {
00074 private:
00075 Vehicle *next;
00076 Vehicle *previous;
00077 Vehicle *first;
00078
00079 Vehicle *next_shared;
00080 Vehicle *previous_shared;
00081 public:
00082 friend const SaveLoad *GetVehicleDescription(VehicleType vt);
00083 friend bool AfterLoadGame();
00084 friend void FixOldVehicles();
00085 friend void AfterLoadVehicles(bool part_of_load);
00086 friend bool LoadOldVehicle(LoadgameState *ls, int num);
00087
00088 char *name;
00089
00090 TileIndex tile;
00091
00097 TileIndex dest_tile;
00098
00099 Money profit_this_year;
00100 Money profit_last_year;
00101 Money value;
00102
00103 CargoPayment *cargo_payment;
00104
00105
00106 uint32 current_order_time;
00107 int32 lateness_counter;
00108 Date timetable_start;
00109
00110
00111
00112 Rect coord;
00113 Vehicle *next_hash, **prev_hash;
00114 Vehicle *next_new_hash, **prev_new_hash;
00115 Vehicle **old_new_hash;
00116
00117 SpriteID colourmap;
00118
00119
00120 Year build_year;
00121 Date age;
00122 Date max_age;
00123 Date date_of_last_service;
00124 Date service_interval;
00125 uint16 reliability;
00126 uint16 reliability_spd_dec;
00127 byte breakdown_ctr;
00128 byte breakdown_delay;
00129 byte breakdowns_since_last_service;
00130 byte breakdown_chance;
00131
00132 int32 x_pos;
00133 int32 y_pos;
00134 byte z_pos;
00135 DirectionByte direction;
00136
00137 OwnerByte owner;
00138 byte spritenum;
00139
00140
00141 uint16 cur_image;
00142 byte x_extent;
00143 byte y_extent;
00144 byte z_extent;
00145 int8 x_offs;
00146 int8 y_offs;
00147 EngineID engine_type;
00148
00149 TextEffectID fill_percent_te_id;
00150 UnitID unitnumber;
00151
00152 uint16 max_speed;
00153 uint16 cur_speed;
00154 byte subspeed;
00155 byte acceleration;
00156 uint32 motion_counter;
00157 byte progress;
00158
00159
00160
00161
00162 byte random_bits;
00163 byte waiting_triggers;
00164
00165 StationID last_station_visited;
00166
00167 CargoID cargo_type;
00168 byte cargo_subtype;
00169 uint16 cargo_cap;
00170 VehicleCargoList cargo;
00171
00172 byte day_counter;
00173 byte tick_counter;
00174 byte running_ticks;
00175
00176 byte vehstatus;
00177 Order current_order;
00178 VehicleOrderID cur_order_index;
00179
00180 union {
00181 OrderList *list;
00182 Order *old;
00183 } orders;
00184
00185 byte vehicle_flags;
00186
00193 uint16 time_counter;
00194
00195 GroupID group_id;
00196
00197 byte subtype;
00198
00199 VehicleCache vcache;
00200
00202 Vehicle(VehicleType type = VEH_INVALID);
00203
00205 void PreDestructor();
00207 virtual ~Vehicle();
00208
00209 void BeginLoading();
00210 void LeaveStation();
00211
00217 void HandleLoading(bool mode = false);
00218
00223 virtual const char *GetTypeString() const { return "base vehicle"; }
00224
00233 virtual void MarkDirty() {}
00234
00240 virtual void UpdateDeltaXY(Direction direction) {}
00241
00246 virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
00247
00251 virtual void PlayLeaveStationSound() const {}
00252
00256 virtual bool IsPrimaryVehicle() const { return false; }
00257
00263 virtual SpriteID GetImage(Direction direction) const { return 0; }
00264
00269 FORCEINLINE void InvalidateNewGRFCache()
00270 {
00271 this->vcache.cache_valid = 0;
00272 }
00273
00278 FORCEINLINE void InvalidateNewGRFCacheOfChain()
00279 {
00280 for (Vehicle *u = this; u != NULL; u = u->Next()) {
00281 u->InvalidateNewGRFCache();
00282 }
00283 }
00284
00289 virtual int GetDisplaySpeed() const { return 0; }
00290
00295 virtual int GetDisplayMaxSpeed() const { return 0; }
00296
00301 virtual Money GetRunningCost() const { return 0; }
00302
00307 virtual bool IsInDepot() const { return false; }
00308
00313 virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
00314
00319 virtual bool Tick() { return true; };
00320
00324 virtual void OnNewDay() {};
00325
00331 virtual uint Crash(bool flooded = false);
00332
00338 inline void UpdateViewport(bool moved, bool turned)
00339 {
00340 extern void VehicleMove(Vehicle *v, bool update_viewport);
00341
00342 if (turned) this->UpdateDeltaXY(this->direction);
00343 SpriteID old_image = this->cur_image;
00344 this->cur_image = this->GetImage(this->direction);
00345 if (moved || this->cur_image != old_image) VehicleMove(this, true);
00346 }
00347
00360 virtual Trackdir GetVehicleTrackdir() const { return INVALID_TRACKDIR; }
00361
00366 Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
00367
00372 Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
00373
00378 Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
00379
00384 void SetNext(Vehicle *next);
00385
00391 inline Vehicle *Next() const { return this->next; }
00392
00398 inline Vehicle *Previous() const { return this->previous; }
00399
00404 inline Vehicle *First() const { return this->first; }
00405
00410 inline Vehicle *Last()
00411 {
00412 Vehicle *v = this;
00413 while (v->Next() != NULL) v = v->Next();
00414 return v;
00415 }
00416
00421 inline const Vehicle *Last() const
00422 {
00423 const Vehicle *v = this;
00424 while (v->Next() != NULL) v = v->Next();
00425 return v;
00426 }
00427
00432 inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
00433
00439 void AddToShared(Vehicle *shared_chain);
00440
00444 void RemoveFromShared();
00445
00450 inline Vehicle *NextShared() const { return this->next_shared; }
00451
00456 inline Vehicle *PreviousShared() const { return this->previous_shared; }
00457
00462 inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
00463
00468 inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); }
00469
00474 inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); }
00475
00482 inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
00483 {
00484 this->unitnumber = src->unitnumber;
00485
00486 this->cur_order_index = src->cur_order_index;
00487 this->current_order = src->current_order;
00488 this->dest_tile = src->dest_tile;
00489
00490 this->profit_this_year = src->profit_this_year;
00491 this->profit_last_year = src->profit_last_year;
00492
00493 this->current_order_time = src->current_order_time;
00494 this->lateness_counter = src->lateness_counter;
00495 this->timetable_start = src->timetable_start;
00496
00497 this->service_interval = src->service_interval;
00498 }
00499
00500 bool NeedsAutorenewing(const Company *c) const;
00501
00508 bool NeedsServicing() const;
00509
00515 bool NeedsAutomaticServicing() const;
00516
00524 virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
00525
00534 virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
00535
00542 CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
00543
00548 void IncrementOrderIndex()
00549 {
00550 this->cur_order_index++;
00551 if (this->cur_order_index >= this->GetNumOrders()) this->cur_order_index = 0;
00552 InvalidateVehicleOrder(this, 0);
00553 }
00554
00560 inline Order *GetOrder(int index) const
00561 {
00562 return (this->orders.list == NULL) ? NULL : this->orders.list->GetOrderAt(index);
00563 }
00564
00569 inline Order *GetLastOrder() const
00570 {
00571 return (this->orders.list == NULL) ? NULL : this->orders.list->GetLastOrder();
00572 }
00573
00574 bool IsEngineCountable() const;
00575 };
00576
00577 #define FOR_ALL_VEHICLES_FROM(var, start) FOR_ALL_ITEMS_FROM(Vehicle, vehicle_index, var, start)
00578 #define FOR_ALL_VEHICLES(var) FOR_ALL_VEHICLES_FROM(var, 0)
00579
00584 template <class T, VehicleType Type>
00585 struct SpecializedVehicle : public Vehicle {
00586 static const VehicleType EXPECTED_TYPE = Type;
00587
00591 FORCEINLINE SpecializedVehicle<T, Type>() : Vehicle(Type) { }
00592
00597 FORCEINLINE T *First() const { return (T *)this->Vehicle::First(); }
00598
00603 FORCEINLINE T *Last() { return (T *)this->Vehicle::Last(); }
00604
00609 FORCEINLINE const T *Last() const { return (const T *)this->Vehicle::Last(); }
00610
00615 FORCEINLINE T *Next() const { return (T *)this->Vehicle::Next(); }
00616
00621 FORCEINLINE T *Previous() const { return (T *)this->Vehicle::Previous(); }
00622
00623
00629 static FORCEINLINE bool IsValidID(size_t index)
00630 {
00631 return Vehicle::IsValidID(index) && Vehicle::Get(index)->type == Type;
00632 }
00633
00638 static FORCEINLINE T *Get(size_t index)
00639 {
00640 return (T *)Vehicle::Get(index);
00641 }
00642
00647 static FORCEINLINE T *GetIfValid(size_t index)
00648 {
00649 return IsValidID(index) ? Get(index) : NULL;
00650 }
00651
00657 static FORCEINLINE T *From(Vehicle *v)
00658 {
00659 assert(v->type == Type);
00660 return (T *)v;
00661 }
00662
00668 static FORCEINLINE const T *From(const Vehicle *v)
00669 {
00670 assert(v->type == Type);
00671 return (const T *)v;
00672 }
00673 };
00674
00675 #define FOR_ALL_VEHICLES_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, vehicle_index, var, 0) if (var->type == name::EXPECTED_TYPE)
00676
00680 struct DisasterVehicle : public SpecializedVehicle<DisasterVehicle, VEH_DISASTER> {
00681 uint16 image_override;
00682 VehicleID big_ufo_destroyer_target;
00683
00685 DisasterVehicle() : SpecializedVehicle<DisasterVehicle, VEH_DISASTER>() {}
00687 virtual ~DisasterVehicle() {}
00688
00689 const char *GetTypeString() const { return "disaster vehicle"; }
00690 void UpdateDeltaXY(Direction direction);
00691 bool Tick();
00692 };
00693
00694 #define FOR_ALL_DISASTERVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(DisasterVehicle, var)
00695
00697 struct FreeUnitIDGenerator {
00698 bool *cache;
00699 UnitID maxid;
00700 UnitID curid;
00701
00708 FreeUnitIDGenerator(VehicleType type, CompanyID owner);
00709
00711 UnitID NextID();
00712
00714 ~FreeUnitIDGenerator() { free(this->cache); }
00715 };
00716
00717 static const int32 INVALID_COORD = 0x7fffffff;
00718
00719 #endif