200 RoadType roadtype; |
200 RoadType roadtype; |
201 RoadTypes compatible_roadtypes; |
201 RoadTypes compatible_roadtypes; |
202 }; |
202 }; |
203 |
203 |
204 struct VehicleSpecial { |
204 struct VehicleSpecial { |
205 uint16 unk0; |
205 uint16 animation_state; |
206 byte unk2; |
206 byte animation_substate; |
207 }; |
207 }; |
208 |
208 |
209 struct VehicleDisaster { |
209 struct VehicleDisaster { |
210 uint16 image_override; |
210 uint16 image_override; |
211 uint16 unk2; |
211 VehicleID big_ufo_destroyer_target; |
212 }; |
212 }; |
213 |
213 |
214 struct VehicleShip { |
214 struct VehicleShip { |
215 TrackBitsByte state; |
215 TrackBitsByte state; |
216 }; |
216 }; |
217 |
217 |
218 |
218 struct Vehicle; |
219 struct Vehicle { |
219 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125) |
|
220 |
|
221 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool> { |
220 VehicleTypeByte type; ///< Type of vehicle |
222 VehicleTypeByte type; ///< Type of vehicle |
221 byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes) |
223 byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes) |
222 |
|
223 VehicleID index; // NOSAVE: Index in vehicle array |
|
224 |
224 |
225 Vehicle *next; // next |
225 Vehicle *next; // next |
226 Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain |
226 Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain |
227 Vehicle *depot_list; //NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace |
227 Vehicle *depot_list; //NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace |
228 |
228 |
333 VehicleSpecial special; |
333 VehicleSpecial special; |
334 VehicleDisaster disaster; |
334 VehicleDisaster disaster; |
335 VehicleShip ship; |
335 VehicleShip ship; |
336 } u; |
336 } u; |
337 |
337 |
|
338 |
|
339 /** |
|
340 * Allocates a lot of vehicles. |
|
341 * @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only) |
|
342 * @param num number of vehicles to allocate room for |
|
343 * @return true if there is room to allocate all the vehicles |
|
344 */ |
|
345 static bool AllocateList(Vehicle **vl, int num); |
|
346 |
|
347 /** Create a new vehicle */ |
|
348 Vehicle(); |
|
349 |
|
350 /** We want to 'destruct' the right class. */ |
|
351 virtual ~Vehicle(); |
|
352 |
|
353 void QuickFree(); |
|
354 |
338 void BeginLoading(); |
355 void BeginLoading(); |
339 void LeaveStation(); |
356 void LeaveStation(); |
340 |
357 |
341 /** |
358 /** |
342 * Handle the loading of the vehicle; when not it skips through dummy |
359 * Handle the loading of the vehicle; when not it skips through dummy |
344 * @param mode is the non-first call for this vehicle in this tick? |
361 * @param mode is the non-first call for this vehicle in this tick? |
345 */ |
362 */ |
346 void HandleLoading(bool mode = false); |
363 void HandleLoading(bool mode = false); |
347 |
364 |
348 /** |
365 /** |
349 * An overriden version of new, so you can use the vehicle instance |
|
350 * instead of a newly allocated piece of memory. |
|
351 * @param size the size of the variable (unused) |
|
352 * @param v the vehicle to use as 'storage' backend |
|
353 * @return the memory that is 'allocated' |
|
354 */ |
|
355 void* operator new(size_t size, Vehicle *v) { return v; } |
|
356 |
|
357 /** |
|
358 * 'Free' the memory allocated by the overriden new. |
|
359 * @param p the memory to 'free' |
|
360 * @param v the vehicle that was given to 'new' on creation. |
|
361 * @note This function isn't used (at the moment) and only added |
|
362 * to please some compiler. |
|
363 */ |
|
364 void operator delete(void *p, Vehicle *v) {} |
|
365 |
|
366 /** |
|
367 * 'Free' the memory allocated by the overriden new. |
|
368 * @param p the memory to 'free' |
|
369 * @note This function isn't used (at the moment) and only added |
|
370 * as the above function was needed to please some compiler |
|
371 * which made it necessary to add this to please yet |
|
372 * another compiler... |
|
373 */ |
|
374 void operator delete(void *p) {} |
|
375 |
|
376 /** We want to 'destruct' the right class. */ |
|
377 virtual ~Vehicle() {} |
|
378 |
|
379 /** |
|
380 * Get a string 'representation' of the vehicle type. |
366 * Get a string 'representation' of the vehicle type. |
381 * @return the string representation. |
367 * @return the string representation. |
382 */ |
368 */ |
383 virtual const char* GetTypeString() const = 0; |
369 virtual const char* GetTypeString() const { return "base vehicle"; } |
384 |
370 |
385 /** |
371 /** |
386 * Marks the vehicles to be redrawn and updates cached variables |
372 * Marks the vehicles to be redrawn and updates cached variables |
387 */ |
373 */ |
388 virtual void MarkDirty() {} |
374 virtual void MarkDirty() {} |
429 virtual int GetImage(Direction direction) const { return 0; } |
415 virtual int GetImage(Direction direction) const { return 0; } |
430 |
416 |
431 /** |
417 /** |
432 * Calls the tick handler of the vehicle |
418 * Calls the tick handler of the vehicle |
433 */ |
419 */ |
434 virtual void Tick() = 0; |
420 virtual void Tick() {}; |
|
421 |
|
422 bool IsValid() const { return this->type != VEH_INVALID; } |
435 }; |
423 }; |
436 |
424 |
437 /** |
425 /** |
438 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
426 * This class 'wraps' Vehicle; you do not actually instantiate this class. |
439 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
427 * You create a Vehicle using AllocateVehicle, so it is added to the pool |
505 #define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE) |
493 #define IS_CUSTOM_SECONDHEAD_SPRITE(x) (x == 0xFE) |
506 |
494 |
507 typedef void *VehicleFromPosProc(Vehicle *v, void *data); |
495 typedef void *VehicleFromPosProc(Vehicle *v, void *data); |
508 |
496 |
509 void VehicleServiceInDepot(Vehicle *v); |
497 void VehicleServiceInDepot(Vehicle *v); |
510 Vehicle *AllocateVehicle(); |
|
511 bool AllocateVehicles(Vehicle **vl, int num); |
|
512 Vehicle *ForceAllocateVehicle(); |
|
513 Vehicle *ForceAllocateSpecialVehicle(); |
|
514 void VehiclePositionChanged(Vehicle *v); |
498 void VehiclePositionChanged(Vehicle *v); |
515 void AfterLoadVehicles(); |
499 void AfterLoadVehicles(); |
516 Vehicle *GetLastVehicleInChain(Vehicle *v); |
500 Vehicle *GetLastVehicleInChain(Vehicle *v); |
517 Vehicle *GetPrevVehicleInChain(const Vehicle *v); |
501 Vehicle *GetPrevVehicleInChain(const Vehicle *v); |
518 Vehicle *GetFirstVehicleInChain(const Vehicle *v); |
502 Vehicle *GetFirstVehicleInChain(const Vehicle *v); |
519 uint CountVehiclesInChain(const Vehicle* v); |
503 uint CountVehiclesInChain(const Vehicle *v); |
520 bool IsEngineCountable(const Vehicle *v); |
504 bool IsEngineCountable(const Vehicle *v); |
521 void DeleteVehicleChain(Vehicle *v); |
505 void DeleteVehicleChain(Vehicle *v); |
522 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc); |
506 void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc); |
523 void *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc); |
507 void *VehicleFromPosXY(int x, int y, void *data, VehicleFromPosProc *proc); |
524 void CallVehicleTicks(); |
508 void CallVehicleTicks(); |
610 */ |
594 */ |
611 Trackdir GetVehicleTrackdir(const Vehicle* v); |
595 Trackdir GetVehicleTrackdir(const Vehicle* v); |
612 |
596 |
613 /* returns true if staying in the same tile */ |
597 /* returns true if staying in the same tile */ |
614 GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v); |
598 GetNewVehiclePosResult GetNewVehiclePos(const Vehicle *v); |
615 Direction GetDirectionTowards(const Vehicle* v, int x, int y); |
599 Direction GetDirectionTowards(const Vehicle *v, int x, int y); |
616 |
600 |
617 #define BEGIN_ENUM_WAGONS(v) do { |
601 #define BEGIN_ENUM_WAGONS(v) do { |
618 #define END_ENUM_WAGONS(v) } while ( (v=v->next) != NULL); |
602 #define END_ENUM_WAGONS(v) } while ((v = v->next) != NULL); |
619 |
|
620 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125) |
|
621 |
603 |
622 static inline VehicleID GetMaxVehicleIndex() |
604 static inline VehicleID GetMaxVehicleIndex() |
623 { |
605 { |
624 /* TODO - This isn't the real content of the function, but |
606 /* TODO - This isn't the real content of the function, but |
625 * with the new pool-system this will be replaced with one that |
607 * with the new pool-system this will be replaced with one that |
630 } |
612 } |
631 |
613 |
632 static inline uint GetNumVehicles() |
614 static inline uint GetNumVehicles() |
633 { |
615 { |
634 return GetVehiclePoolSize(); |
616 return GetVehiclePoolSize(); |
635 } |
|
636 |
|
637 /** |
|
638 * Check if a Vehicle really exists. |
|
639 */ |
|
640 static inline bool IsValidVehicle(const Vehicle *v) |
|
641 { |
|
642 return v->type != VEH_INVALID; |
|
643 } |
|
644 |
|
645 void DestroyVehicle(Vehicle *v); |
|
646 |
|
647 static inline void DeleteVehicle(Vehicle *v) |
|
648 { |
|
649 DestroyVehicle(v); |
|
650 v = new (v) InvalidVehicle(); |
|
651 } |
617 } |
652 |
618 |
653 static inline bool IsPlayerBuildableVehicleType(VehicleType type) |
619 static inline bool IsPlayerBuildableVehicleType(VehicleType type) |
654 { |
620 { |
655 switch (type) { |
621 switch (type) { |
666 static inline bool IsPlayerBuildableVehicleType(const Vehicle *v) |
632 static inline bool IsPlayerBuildableVehicleType(const Vehicle *v) |
667 { |
633 { |
668 return IsPlayerBuildableVehicleType(v->type); |
634 return IsPlayerBuildableVehicleType(v->type); |
669 } |
635 } |
670 |
636 |
671 #define FOR_ALL_VEHICLES_FROM(v, start) for (v = GetVehicle(start); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) if (IsValidVehicle(v)) |
637 #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()) |
672 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0) |
638 #define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0) |
673 |
639 |
674 /** |
640 /** |
675 * Check if an index is a vehicle-index (so between 0 and max-vehicles) |
641 * Check if an index is a vehicle-index (so between 0 and max-vehicles) |
676 * @param index of the vehicle to query |
642 * @param index of the vehicle to query |
677 * @return Returns true if the vehicle-id is in range |
643 * @return Returns true if the vehicle-id is in range |
678 */ |
644 */ |
679 static inline bool IsValidVehicleID(uint index) |
645 static inline bool IsValidVehicleID(uint index) |
680 { |
646 { |
681 return index < GetVehiclePoolSize() && IsValidVehicle(GetVehicle(index)); |
647 return index < GetVehiclePoolSize() && GetVehicle(index)->IsValid(); |
682 } |
648 } |
683 |
649 |
684 /* Returns order 'index' of a vehicle or NULL when it doesn't exists */ |
650 /* Returns order 'index' of a vehicle or NULL when it doesn't exists */ |
685 static inline Order *GetVehicleOrder(const Vehicle *v, int index) |
651 static inline Order *GetVehicleOrder(const Vehicle *v, int index) |
686 { |
652 { |