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 "window_type.h"
00015 #include "gfx_type.h"
00016 #include "command_type.h"
00017 #include "date_type.h"
00018 #include "player_type.h"
00019 #include "oldpool.h"
00020 #include "order.h"
00021 #include "cargopacket.h"
00022 #include "texteff.hpp"
00023
00025 enum RoadVehicleStates {
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 RVSB_IN_DEPOT = 0xFE,
00040 RVSB_WORMHOLE = 0xFF,
00041
00042
00043 RVS_USING_SECOND_BAY = 1,
00044 RVS_IS_STOPPING = 2,
00045 RVS_DRIVE_SIDE = 4,
00046 RVS_IN_ROAD_STOP = 5,
00047 RVS_IN_DT_ROAD_STOP = 6,
00048
00049
00050 RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP,
00051 RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END,
00052 RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP,
00053 RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
00054
00055 RVSB_TRACKDIR_MASK = 0x0F,
00056 RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09
00057 };
00058
00059 enum VehStatus {
00060 VS_HIDDEN = 0x01,
00061 VS_STOPPED = 0x02,
00062 VS_UNCLICKABLE = 0x04,
00063 VS_DEFPAL = 0x08,
00064 VS_TRAIN_SLOWING = 0x10,
00065 VS_SHADOW = 0x20,
00066 VS_AIRCRAFT_BROKEN = 0x40,
00067 VS_CRASHED = 0x80,
00068 };
00069
00070 enum VehicleFlags {
00071 VF_LOADING_FINISHED,
00072 VF_CARGO_UNLOADING,
00073 VF_BUILT_AS_PROTOTYPE,
00074 VF_TIMETABLE_STARTED,
00075 VF_AUTOFILL_TIMETABLE,
00076 };
00077
00078 struct VehicleRail {
00079 uint16 last_speed;
00080 uint16 crash_anim_pos;
00081
00082
00083 uint16 cached_max_speed;
00084 uint32 cached_power;
00085 bool cached_tilt;
00086 uint8 cached_veh_length;
00087 uint16 cached_total_length;
00088
00089
00090 uint32 cached_weight;
00091 uint32 cached_veh_weight;
00092 uint32 cached_max_te;
00100 byte cached_vis_effect;
00101 byte user_def_data;
00102
00103
00104
00105 EngineID first_engine;
00106
00107 TrackBitsByte track;
00108 byte force_proceed;
00109 RailTypeByte railtype;
00110 RailTypes compatible_railtypes;
00111
00112 byte flags;
00113
00114
00115 Vehicle *other_multiheaded_part;
00116
00117
00118 const struct SpriteGroup *cached_override;
00119 };
00120
00121 enum VehicleRailFlags {
00122 VRF_REVERSING = 0,
00123
00124
00125 VRF_GOINGUP = 1,
00126 VRF_GOINGDOWN = 2,
00127
00128
00129 VRF_POWEREDWAGON = 3,
00130
00131
00132 VRF_REVERSE_DIRECTION = 4,
00133
00134
00135 VRF_NO_PATH_TO_DESTINATION = 5,
00136
00137
00138 VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
00139
00140
00141 VRF_TOGGLE_REVERSE = 7,
00142 };
00143
00144 struct VehicleAir {
00145 uint16 crashed_counter;
00146 uint16 cached_max_speed;
00147 byte pos;
00148 byte previous_pos;
00149 StationID targetairport;
00150 byte state;
00151 };
00152
00153 struct VehicleRoad {
00154 byte state;
00155 byte frame;
00156 uint16 blocked_ctr;
00157 byte overtaking;
00158 byte overtaking_ctr;
00159 uint16 crashed_ctr;
00160 byte reverse_ctr;
00161 struct RoadStop *slot;
00162 byte slot_age;
00163 EngineID first_engine;
00164 byte cached_veh_length;
00165
00166 RoadType roadtype;
00167 RoadTypes compatible_roadtypes;
00168 };
00169
00170 struct VehicleSpecial {
00171 uint16 animation_state;
00172 byte animation_substate;
00173 };
00174
00175 struct VehicleDisaster {
00176 uint16 image_override;
00177 VehicleID big_ufo_destroyer_target;
00178 };
00179
00180 struct VehicleShip {
00181 TrackBitsByte state;
00182 };
00183
00184 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
00185
00186
00187 struct SaveLoad;
00188 extern const SaveLoad *GetVehicleDescription(VehicleType vt);
00189 extern void AfterLoadVehicles(bool clear_te_id);
00190 struct LoadgameState;
00191 extern bool LoadOldVehicle(LoadgameState *ls, int num);
00192
00193 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool>, BaseVehicle {
00194 byte subtype;
00195
00196 private:
00197 Vehicle *next;
00198 Vehicle *previous;
00199 Vehicle *first;
00200 public:
00201 friend const SaveLoad *GetVehicleDescription(VehicleType vt);
00202 friend void AfterLoadVehicles(bool clear_te_id);
00203 friend bool LoadOldVehicle(LoadgameState *ls, int num);
00204
00205 Vehicle *depot_list;
00206
00207 char *name;
00208
00209 UnitID unitnumber;
00210 PlayerByte owner;
00211
00212 TileIndex tile;
00213 TileIndex dest_tile;
00214
00215 int32 x_pos;
00216 int32 y_pos;
00217 byte z_pos;
00218 DirectionByte direction;
00219
00220 byte spritenum;
00221
00222
00223 uint16 cur_image;
00224 byte sprite_width;
00225 byte sprite_height;
00226 byte z_height;
00227 int8 x_offs;
00228 int8 y_offs;
00229 EngineID engine_type;
00230
00231 TextEffectID fill_percent_te_id;
00232
00233
00234
00235
00236 byte random_bits;
00237 byte waiting_triggers;
00238
00239 uint16 max_speed;
00240 uint16 cur_speed;
00241 byte subspeed;
00242 byte acceleration;
00243 byte progress;
00244 uint32 motion_counter;
00245
00246 byte vehstatus;
00247 StationID last_station_visited;
00248
00249 CargoID cargo_type;
00250 uint16 cargo_cap;
00251 byte cargo_subtype;
00252 CargoList cargo;
00253
00254
00255 byte day_counter;
00256 byte tick_counter;
00257 byte running_ticks;
00258
00259
00260 Order current_order;
00261 VehicleOrderID cur_order_index;
00262
00263 Order *orders;
00264 VehicleOrderID num_orders;
00265
00266 Vehicle *next_shared;
00267 Vehicle *prev_shared;
00268
00269
00270
00271
00272 int32 left_coord;
00273 int32 top_coord;
00274 int32 right_coord;
00275 int32 bottom_coord;
00276 Vehicle *next_hash;
00277 Vehicle *next_new_hash;
00278 Vehicle **old_new_hash;
00279
00280
00281 Date age;
00282 Date max_age;
00283 Date date_of_last_service;
00284 Date service_interval;
00285 uint16 reliability;
00286 uint16 reliability_spd_dec;
00287 byte breakdown_ctr;
00288 byte breakdown_delay;
00289 byte breakdowns_since_last_service;
00290 byte breakdown_chance;
00291 Year build_year;
00292
00293 bool leave_depot_instantly;
00294
00295 uint16 load_unload_time_rem;
00296 byte vehicle_flags;
00297
00298 Money profit_this_year;
00299 Money profit_last_year;
00300 Money value;
00301
00302 GroupID group_id;
00303
00304
00305 uint32 current_order_time;
00306 int32 lateness_counter;
00307
00308 SpriteID colormap;
00309
00310 union {
00311 VehicleRail rail;
00312 VehicleAir air;
00313 VehicleRoad road;
00314 VehicleSpecial special;
00315 VehicleDisaster disaster;
00316 VehicleShip ship;
00317 } u;
00318
00319
00326 static bool AllocateList(Vehicle **vl, int num);
00327
00329 Vehicle();
00330
00332 void PreDestructor();
00334 virtual ~Vehicle();
00335
00336 void BeginLoading();
00337 void LeaveStation();
00338
00344 void HandleLoading(bool mode = false);
00345
00350 virtual const char* GetTypeString() const { return "base vehicle"; }
00351
00360 virtual void MarkDirty() {}
00361
00367 virtual void UpdateDeltaXY(Direction direction) {}
00368
00373 virtual ExpensesType GetExpenseType(bool income) const { return EXPENSES_OTHER; }
00374
00378 virtual WindowClass GetVehicleListWindowClass() const { return WC_NONE; }
00379
00383 virtual void PlayLeaveStationSound() const {}
00384
00388 virtual bool IsPrimaryVehicle() const { return false; }
00389
00395 virtual int GetImage(Direction direction) const { return 0; }
00396
00401 virtual int GetDisplaySpeed() const { return 0; }
00402
00407 virtual int GetDisplayMaxSpeed() const { return 0; }
00408
00413 virtual Money GetRunningCost() const { return 0; }
00414
00419 virtual bool IsInDepot() const { return false; }
00420
00425 virtual bool IsStoppedInDepot() const { return this->IsInDepot() && (this->vehstatus & VS_STOPPED) != 0; }
00426
00430 virtual void Tick() {};
00431
00435 virtual void OnNewDay() {};
00436
00441 Money GetDisplayRunningCost() const { return (this->GetRunningCost() >> 8); }
00442
00447 Money GetDisplayProfitThisYear() const { return (this->profit_this_year >> 8); }
00448
00453 Money GetDisplayProfitLastYear() const { return (this->profit_last_year >> 8); }
00454
00459 void SetNext(Vehicle *next);
00460
00466 inline Vehicle *Next() const { return this->next; }
00467
00473 inline Vehicle *Previous() const { return this->previous; }
00474
00479 inline Vehicle *First() const { return this->first; }
00480
00486 inline bool IsOrderListShared() const { return this->next_shared != NULL || this->prev_shared != NULL; };
00487
00488 bool NeedsAutorenewing(const Player *p) const;
00489
00496 bool NeedsServicing() const;
00497
00503 bool NeedsAutomaticServicing() const;
00504 };
00505
00521 struct SpecialVehicle : public Vehicle {
00523 SpecialVehicle() { this->type = VEH_SPECIAL; }
00524
00526 virtual ~SpecialVehicle() {}
00527
00528 const char *GetTypeString() const { return "special vehicle"; }
00529 void UpdateDeltaXY(Direction direction);
00530 void Tick();
00531 };
00532
00541 struct DisasterVehicle : public Vehicle {
00543 DisasterVehicle() { this->type = VEH_DISASTER; }
00544
00546 virtual ~DisasterVehicle() {}
00547
00548 const char *GetTypeString() const { return "disaster vehicle"; }
00549 void UpdateDeltaXY(Direction direction);
00550 void Tick();
00551 };
00552
00561 struct InvalidVehicle : public Vehicle {
00563 InvalidVehicle() { this->type = VEH_INVALID; }
00564
00566 virtual ~InvalidVehicle() {}
00567
00568 const char *GetTypeString() const { return "invalid vehicle"; }
00569 void Tick() {}
00570 };
00571
00572 #define BEGIN_ENUM_WAGONS(v) do {
00573 #define END_ENUM_WAGONS(v) } while ((v = v->Next()) != NULL);
00574
00575 static inline VehicleID GetMaxVehicleIndex()
00576 {
00577
00578
00579
00580
00581
00582 return GetVehiclePoolSize() - 1;
00583 }
00584
00585 static inline uint GetNumVehicles()
00586 {
00587 return GetVehiclePoolSize();
00588 }
00589
00590 #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())
00591 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
00592
00598 static inline bool IsValidVehicleID(uint index)
00599 {
00600 return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid();
00601 }
00602
00603
00604 static inline Order *GetVehicleOrder(const Vehicle *v, int index)
00605 {
00606 Order *order = v->orders;
00607
00608 if (index < 0) return NULL;
00609
00610 while (order != NULL && index-- > 0)
00611 order = order->next;
00612
00613 return order;
00614 }
00615
00621 static inline Order *GetLastVehicleOrder(const Vehicle *v)
00622 {
00623 Order *order = v->orders;
00624
00625 if (order == NULL) return NULL;
00626
00627 while (order->next != NULL)
00628 order = order->next;
00629
00630 return order;
00631 }
00632
00637 static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v)
00638 {
00639 Vehicle *u = (Vehicle *)v;
00640 while (u->prev_shared != NULL) u = u->prev_shared;
00641
00642 return u;
00643 }
00644
00656 Trackdir GetVehicleTrackdir(const Vehicle* v);
00657
00658 void CheckVehicle32Day(Vehicle *v);
00659
00660 #endif