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 virtual int GetDisplaySpeed() const { return 0; }
00407
00412 virtual int GetDisplayMaxSpeed() const { return 0; }
00413
00418 virtual Money GetRunningCost() const { return 0; }
00419
00424 virtual bool IsInDepot() const { return false; }
00425
00430 virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
00431
00435 virtual void Tick() {};
00436
00440 virtual void OnNewDay() {};
00441
00446 Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
00447
00452 Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
00453
00458 Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
00459
00464 void SetNext(Vehicle *next);
00465
00471 inline Vehicle *Next() const { return this->next; }
00472
00478 inline Vehicle *Previous() const { return this->previous; }
00479
00484 inline Vehicle *First() const { return this->first; }
00485
00486
00491 inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
00492
00498 void AddToShared(Vehicle *shared_chain);
00499
00503 void RemoveFromShared();
00504
00509 inline Vehicle *NextShared() const { return this->next_shared; }
00510
00515 inline Vehicle *PreviousShared() const { return this->previous_shared; }
00516
00521 inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); }
00522
00527 inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); }
00528
00533 inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); }
00534
00541 inline void CopyVehicleConfigAndStatistics(const Vehicle *src)
00542 {
00543 this->unitnumber = src->unitnumber;
00544
00545 this->cur_order_index = src->cur_order_index;
00546 this->current_order = src->current_order;
00547 this->dest_tile = src->dest_tile;
00548
00549 this->profit_this_year = src->profit_this_year;
00550 this->profit_last_year = src->profit_last_year;
00551
00552 this->current_order_time = src->current_order_time;
00553 this->lateness_counter = src->lateness_counter;
00554
00555 this->service_interval = src->service_interval;
00556 }
00557
00558 bool NeedsAutorenewing(const Company *c) const;
00559
00566 bool NeedsServicing() const;
00567
00573 bool NeedsAutomaticServicing() const;
00574
00582 virtual TileIndex GetOrderStationLocation(StationID station) { return INVALID_TILE; }
00583
00592 virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; }
00593
00600 CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command);
00601 };
00602
00611 struct DisasterVehicle : public Vehicle {
00613 DisasterVehicle() { this->type = VEH_DISASTER; }
00614
00616 virtual ~DisasterVehicle() {}
00617
00618 const char *GetTypeString() const { return "disaster vehicle"; }
00619 void UpdateDeltaXY(Direction direction);
00620 void Tick();
00621 };
00622
00631 struct InvalidVehicle : public Vehicle {
00633 InvalidVehicle() { this->type = VEH_INVALID; }
00634
00636 virtual ~InvalidVehicle() {}
00637
00638 const char *GetTypeString() const { return "invalid vehicle"; }
00639 void Tick() {}
00640 };
00641
00642 static inline VehicleID GetMaxVehicleIndex()
00643 {
00644
00645
00646
00647
00648
00649 return GetVehiclePoolSize() - 1;
00650 }
00651
00652 static inline uint GetNumVehicles()
00653 {
00654 return GetVehiclePoolSize();
00655 }
00656
00657 #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())
00658 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
00659
00665 static inline bool IsValidVehicleID(uint index)
00666 {
00667 return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid();
00668 }
00669
00670
00672 struct FreeUnitIDGenerator {
00673 bool *cache;
00674 UnitID maxid;
00675 UnitID curid;
00676
00683 FreeUnitIDGenerator(VehicleType type, CompanyID owner);
00684
00686 UnitID NextID();
00687
00689 ~FreeUnitIDGenerator() { free(this->cache); }
00690 };
00691
00692
00693 static inline Order *GetVehicleOrder(const Vehicle *v, int index) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetOrderAt(index); }
00694
00700 static inline Order *GetLastVehicleOrder(const Vehicle *v) { return (v->orders.list == NULL) ? NULL : v->orders.list->GetLastOrder(); }
00701
00713 Trackdir GetVehicleTrackdir(const Vehicle *v);
00714
00715 void CheckVehicle32Day(Vehicle *v);
00716
00717 static const int32 INVALID_COORD = 0x7fffffff;
00718
00719 #endif