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 CargoPayment *cargo_payment;
00229
00230
00231 uint32 current_order_time;
00232 int32 lateness_counter;
00233
00234
00235
00236 Rect coord;
00237 Vehicle *next_hash;
00238 Vehicle *next_new_hash;
00239 Vehicle **old_new_hash;
00240
00241 SpriteID colourmap;
00242
00243
00244 Year build_year;
00245 Date age;
00246 Date max_age;
00247 Date date_of_last_service;
00248 Date service_interval;
00249 uint16 reliability;
00250 uint16 reliability_spd_dec;
00251 byte breakdown_ctr;
00252 byte breakdown_delay;
00253 byte breakdowns_since_last_service;
00254 byte breakdown_chance;
00255
00256 int32 x_pos;
00257 int32 y_pos;
00258 byte z_pos;
00259 DirectionByte direction;
00260
00261 OwnerByte owner;
00262 byte spritenum;
00263
00264
00265 uint16 cur_image;
00266 byte x_extent;
00267 byte y_extent;
00268 byte z_extent;
00269 int8 x_offs;
00270 int8 y_offs;
00271 EngineID engine_type;
00272
00273 TextEffectID fill_percent_te_id;
00274 UnitID unitnumber;
00275
00276 uint16 max_speed;
00277 uint16 cur_speed;
00278 byte subspeed;
00279 byte acceleration;
00280 uint32 motion_counter;
00281 byte progress;
00282
00283
00284
00285
00286 byte random_bits;
00287 byte waiting_triggers;
00288
00289 StationID last_station_visited;
00290
00291 CargoID cargo_type;
00292 byte cargo_subtype;
00293 uint16 cargo_cap;
00294 CargoList cargo;
00295
00296 byte day_counter;
00297 byte tick_counter;
00298 byte running_ticks;
00299
00300 byte vehstatus;
00301 Order current_order;
00302 VehicleOrderID cur_order_index;
00303
00304 union {
00305 OrderList *list;
00306 Order *old;
00307 } orders;
00308
00309 byte vehicle_flags;
00310 uint16 load_unload_time_rem;
00311
00312 GroupID group_id;
00313
00314 byte subtype;
00315
00316 union {
00317 VehicleRail rail;
00318 VehicleAir air;
00319 VehicleRoad road;
00320 VehicleEffect effect;
00321 VehicleDisaster disaster;
00322 VehicleShip ship;
00323 } u;
00324
00325
00326 uint8 cache_valid;
00327 uint32 cached_var40;
00328 uint32 cached_var41;
00329 uint32 cached_var42;
00330 uint32 cached_var43;
00331
00338 static bool AllocateList(Vehicle **vl, int num);
00339
00341 Vehicle();
00342
00344 void PreDestructor();
00346 virtual ~Vehicle();
00347
00348 void BeginLoading();
00349 void LeaveStation();
00350
00356 void HandleLoading(bool mode = false);
00357
00362 virtual const char *GetTypeString() const { return "base vehicle"; }
00363
00372 virtual void MarkDirty() {}
00373
00379 virtual void UpdateDeltaXY(Direction direction) {}
00380
00385 virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
00386
00390 virtual void PlayLeaveStationSound() const {}
00391
00395 virtual bool IsPrimaryVehicle() const { return false; }
00396
00402 virtual SpriteID GetImage(Direction direction) const { return 0; }
00403
00408 FORCEINLINE void InvalidateNewGRFCache()
00409 {
00410 this->cache_valid = 0;
00411 }
00412
00417 FORCEINLINE void InvalidateNewGRFCacheOfChain()
00418 {
00419 for (Vehicle *u = this; u != NULL; u = u->Next()) {
00420 u->InvalidateNewGRFCache();
00421 }
00422 }
00423
00428 virtual int GetDisplaySpeed() const { return 0; }
00429
00434 virtual int GetDisplayMaxSpeed() const { return 0; }
00435
00440 virtual Money GetRunningCost() const { return 0; }
00441
00446 virtual bool IsInDepot() const { return false; }
00447
00452 virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
00453
00457 virtual void Tick() {};
00458
00462 virtual void OnNewDay() {};
00463
00468 Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
00469
00474 Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
00475
00480 Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
00481
00486 void SetNext(Vehicle *next);
00487
00493 inline Vehicle *Next() const { return this->next; }
00494
00500 inline Vehicle *Previous() const { return this->previous; }
00501
00506 inline Vehicle *First() const { return this->first; }
00507
00508
00513 inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
00514
00520 void AddToShared(Vehicle *shared_chain);
00521
00525 void RemoveFromShared();
00526
00531 inline Vehicle *NextShared() const { return this->next_shared; }
00532
00537 inline Vehicle *PreviousShared() const { return this->previous_shared; }
00538
00543 inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
00544
00549 inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); }
00550
00555 inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); }
00556
00563 inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
00564 {
00565 this->unitnumber = src->unitnumber;
00566
00567 this->cur_order_index = src->cur_order_index;
00568 this->current_order = src->current_order;
00569 this->dest_tile = src->dest_tile;
00570
00571 this->profit_this_year = src->profit_this_year;
00572 this->profit_last_year = src->profit_last_year;
00573
00574 this->current_order_time = src->current_order_time;
00575 this->lateness_counter = src->lateness_counter;
00576
00577 this->service_interval = src->service_interval;
00578 }
00579
00580 bool NeedsAutorenewing(const Company *c) const;
00581
00588 bool NeedsServicing() const;
00589
00595 bool NeedsAutomaticServicing() const;
00596
00604 virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
00605
00614 virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
00615
00622 CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
00623 };
00624
00633 struct DisasterVehicle : public Vehicle {
00635 DisasterVehicle() { this->type = VEH_DISASTER; }
00636
00638 virtual ~DisasterVehicle() {}
00639
00640 const char *GetTypeString() const { return "disaster vehicle"; }
00641 void UpdateDeltaXY(Direction direction);
00642 void Tick();
00643 };
00644
00653 struct InvalidVehicle : public Vehicle {
00655 InvalidVehicle() { this->type = VEH_INVALID; }
00656
00658 virtual ~InvalidVehicle() {}
00659
00660 const char *GetTypeString() const { return "invalid vehicle"; }
00661 void Tick() {}
00662 };
00663
00664 static inline VehicleID GetMaxVehicleIndex()
00665 {
00666
00667
00668
00669
00670
00671 return GetVehiclePoolSize() - 1;
00672 }
00673
00674 static inline uint GetNumVehicles()
00675 {
00676 return GetVehiclePoolSize();
00677 }
00678
00679 #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())
00680 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
00681
00687 static inline bool IsValidVehicleID(uint index)
00688 {
00689 return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid();
00690 }
00691
00692
00694 struct FreeUnitIDGenerator {
00695 bool *cache;
00696 UnitID maxid;
00697 UnitID curid;
00698
00705 FreeUnitIDGenerator(VehicleType type, CompanyID owner);
00706
00708 UnitID NextID();
00709
00711 ~FreeUnitIDGenerator() { free(this->cache); }
00712 };
00713
00714
00715 static inline Order *GetVehicleOrder(const Vehicle *v, int index) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetOrderAt(index); }
00716
00722 static inline Order *GetLastVehicleOrder(const Vehicle *v) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetLastOrder(); }
00723
00735 Trackdir GetVehicleTrackdir(const Vehicle *v);
00736
00737 void CheckVehicle32Day(Vehicle *v);
00738
00739 static const int32 INVALID_COORD = 0x7fffffff;
00740
00741 #endif