(svn r9754) -Codechange: make classes for all vehicle types, so we can make nicer/better maintainable code, i.e. virtual methods instead of switches.

This commit is contained in:
rubidium 2007-04-29 21:24:08 +00:00
parent 95e48eacac
commit 202009522c
12 changed files with 245 additions and 55 deletions

View File

@ -115,4 +115,22 @@ void UpdateAirplanesOnNewStation(const Station *st);
*/
void UpdateAircraftCache(Vehicle *v);
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool
* and you reinitialize that to a Train using:
* v = new (v) Aircraft();
*
* As side-effect the vehicle type is set correctly.
*/
struct Aircraft : public Vehicle {
/** Initializes the Vehicle to an aircraft */
Aircraft() { this->type = VEH_AIRCRAFT; }
/** We want to 'destruct' the right class. */
virtual ~Aircraft() {}
const char *GetTypeString() { return "aircraft"; }
};
#endif /* AIRCRAFT_H */

View File

@ -269,7 +269,8 @@ int32 CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
Vehicle *u = vl[1]; // shadow
v->unitnumber = unit_num;
v->type = u->type = VEH_AIRCRAFT;
v = new (v) Aircraft();
u = new (u) Aircraft();
v->direction = DIR_SE;
v->owner = u->owner = _current_player;
@ -404,7 +405,7 @@ int32 CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
u->next = w;
w->type = VEH_AIRCRAFT;
w = new (w) Aircraft();
w->direction = DIR_N;
w->owner = _current_player;
w->x_pos = v->x_pos;

View File

@ -121,7 +121,7 @@ static void DisasterVehicleUpdateImage(Vehicle *v)
* and owned by nobody */
static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, Direction direction, byte subtype)
{
v->type = VEH_DISASTER;
v = new (v) DisasterVehicle();
v->x_pos = x;
v->y_pos = y;
v->z_pos = z;

View File

@ -15,6 +15,10 @@
#include "player.h"
#include "engine.h"
#include "vehicle.h"
#include "aircraft.h"
#include "roadveh.h"
#include "ship.h"
#include "train.h"
#include "signs.h"
#include "debug.h"
#include "depot.h"
@ -1070,13 +1074,13 @@ static bool LoadOldVehicleUnion(LoadgameState *ls, int num)
* Basically v->type -= 0x10; would suffice, but play safely */
switch (v->type) {
default: NOT_REACHED();
case 0x00 /*VEH_INVALID */: v->type = VEH_INVALID; res = LoadChunk(ls, NULL, vehicle_empty_chunk); break;
case 0x10 /*VEH_TRAIN */: v->type = VEH_TRAIN; res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break;
case 0x11 /*VEH_ROAD */: v->type = VEH_ROAD; res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break;
case 0x12 /*VEH_SHIP */: v->type = VEH_SHIP; res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break;
case 0x13 /*VEH_AIRCRAFT*/: v->type = VEH_AIRCRAFT; res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break;
case 0x14 /*VEH_SPECIAL */: v->type = VEH_SPECIAL; res = LoadChunk(ls, &v->u.special, vehicle_special_chunk); break;
case 0x15 /*VEH_DISASTER*/: v->type = VEH_DISASTER; res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
case 0x00 /*VEH_INVALID */: v = new (v) InvalidVehicle(); res = LoadChunk(ls, NULL, vehicle_empty_chunk); break;
case 0x10 /*VEH_TRAIN */: v = new (v) Train(); res = LoadChunk(ls, &v->u.rail, vehicle_train_chunk); break;
case 0x11 /*VEH_ROAD */: v = new (v) RoadVehicle(); res = LoadChunk(ls, &v->u.road, vehicle_road_chunk); break;
case 0x12 /*VEH_SHIP */: v = new (v) Ship(); res = LoadChunk(ls, &v->u.ship, vehicle_ship_chunk); break;
case 0x13 /*VEH_AIRCRAFT*/: v = new (v) Aircraft(); res = LoadChunk(ls, &v->u.air, vehicle_air_chunk); break;
case 0x14 /*VEH_SPECIAL */: v = new (v) SpecialVehicle(); res = LoadChunk(ls, &v->u.special, vehicle_special_chunk); break;
case 0x15 /*VEH_DISASTER*/: v = new (v) DisasterVehicle(); res = LoadChunk(ls, &v->u.disaster, vehicle_disaster_chunk); break;
}
/* This chunk size should always be 10 bytes */

View File

@ -22,4 +22,23 @@ static inline bool IsRoadVehInDepotStopped(const Vehicle* v)
void CcBuildRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2);
void CcCloneRoadVeh(bool success, TileIndex tile, uint32 p1, uint32 p2);
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool
* and you reinitialize that to a Train using:
* v = new (v) RoadVehicle();
*
* As side-effect the vehicle type is set correctly.
*/
struct RoadVehicle : public Vehicle {
/** Initializes the Vehicle to a road vehicle */
RoadVehicle() { this->type = VEH_ROAD; }
/** We want to 'destruct' the right class. */
virtual ~RoadVehicle() {}
const char *GetTypeString() { return "road vehicle"; }
};
#endif /* ROADVEH_H */

View File

@ -205,7 +205,7 @@ int32 CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->date_of_last_service = _date;
v->build_year = _cur_year;
v->type = VEH_ROAD;
v = new (v) RoadVehicle();
v->cur_image = 0xC15;
v->random_bits = VehicleRandomBits();

View File

@ -23,4 +23,23 @@ static inline bool IsShipInDepotStopped(const Vehicle* v)
return IsShipInDepot(v) && v->vehstatus & VS_STOPPED;
}
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool
* and you reinitialize that to a Train using:
* v = new (v) Ship();
*
* As side-effect the vehicle type is set correctly.
*/
struct Ship: public Vehicle {
/** Initializes the Vehicle to a ship */
Ship() { this->type = VEH_SHIP; }
/** We want to 'destruct' the right class. */
virtual ~Ship() {}
const char *GetTypeString() { return "ship"; }
};
#endif /* SHIP_H */

View File

@ -910,7 +910,7 @@ int32 CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->date_of_last_service = _date;
v->build_year = _cur_year;
v->cur_image = 0x0E5E;
v->type = VEH_SHIP;
v = new (v) Ship();
v->random_bits = VehicleRandomBits();
v->vehicle_flags = 0;

View File

@ -228,4 +228,22 @@ void CcCloneTrain(bool success, TileIndex tile, uint32 p1, uint32 p2);
byte FreightWagonMult(CargoID cargo);
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool
* and you reinitialize that to a Train using:
* v = new (v) Train();
*
* As side-effect the vehicle type is set correctly.
*/
struct Train : public Vehicle {
/** Initializes the Vehicle to a train */
Train() { this->type = VEH_TRAIN; }
/** We want to 'destruct' the right class. */
virtual ~Train() {}
const char *GetTypeString() { return "train"; }
};
#endif /* TRAIN_H */

View File

@ -552,7 +552,7 @@ static void AddArticulatedParts(Vehicle **vl)
u->max_age = 0;
u->engine_type = engine_type;
u->value = 0;
u->type = VEH_TRAIN;
u = new (u) Train();
u->subtype = 0;
SetArticulatedPart(u);
u->cur_image = 0xAC2;
@ -630,7 +630,7 @@ static int32 CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 flags)
v->u.rail.railtype = rvi->railtype;
v->build_year = _cur_year;
v->type = VEH_TRAIN;
v = new (v) Train();
v->cur_image = 0xAC2;
v->random_bits = VehicleRandomBits();
@ -696,7 +696,7 @@ static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool buildin
u->build_year = v->build_year;
if (building) v->value >>= 1;
u->value = v->value;
u->type = VEH_TRAIN;
u = new (u) Train();
u->cur_image = 0xAC2;
u->random_bits = VehicleRandomBits();
VehiclePositionChanged(u);
@ -789,7 +789,7 @@ int32 CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
v->service_interval = _patches.servint_trains;
v->date_of_last_service = _date;
v->build_year = _cur_year;
v->type = VEH_TRAIN;
v = new (v) Train();
v->cur_image = 0xAC2;
v->random_bits = VehicleRandomBits();

View File

@ -89,7 +89,7 @@ static void VehiclePoolNewBlock(uint start_item)
* TODO - This is just a temporary stage, this will be removed. */
for (v = GetVehicle(start_item); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
v->index = start_item++;
v->type = VEH_INVALID;
v = new (v) InvalidVehicle();
}
}
@ -271,7 +271,7 @@ static Vehicle *InitializeVehicle(Vehicle *v)
assert(v->orders == NULL);
v->type = VEH_INVALID;
v = new (v) InvalidVehicle();
v->left_coord = INVALID_COORD;
v->first = NULL;
v->next = NULL;
@ -1438,7 +1438,7 @@ Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicle type)
v = ForceAllocateSpecialVehicle();
if (v != NULL) {
v->type = VEH_SPECIAL;
v = new (v) SpecialVehicle();
v->subtype = type;
v->x_pos = x;
v->y_pos = y;
@ -2681,17 +2681,17 @@ extern const SaveLoad _common_veh_desc[] = {
/* This next line is for version 4 and prior compatibility.. it temporarily reads
type and flags (which were both 4 bits) into type. Later on this is
converted correctly */
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8, 0, 4),
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
/* Orders for version 5 and on */
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
/* Refit in current order */
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION),
SLE_REF(Vehicle, orders, REF_ORDER),
@ -2738,13 +2738,13 @@ extern const SaveLoad _common_veh_desc[] = {
static const SaveLoad _train_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN, 0), // Train type. VEH_TRAIN in mem, 0 in file.
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, force_proceed), SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, railtype), SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, track), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8),
SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, flags), SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, days_since_order_progr), SLE_UINT16, 2, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, days_since_order_progr), SLE_UINT16, 2, SL_MAX_VERSION),
SLE_CONDNULL(2, 2, 19),
/* reserve extra space in savegame here. (currently 11 bytes) */
@ -2756,17 +2756,17 @@ static const SaveLoad _train_desc[] = {
static const SaveLoad _roadveh_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_ROAD, 1), // Road type. VEH_ROAD in mem, 1 in file.
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, state), SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, frame), SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking), SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, crashed_ctr), SLE_UINT16),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, reverse_ctr), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8),
SLE_CONDREFX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
SLE_CONDNULL(1, 6, SL_MAX_VERSION),
SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
@ -2776,7 +2776,7 @@ static const SaveLoad _roadveh_desc[] = {
static const SaveLoad _ship_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP, 2), // Ship type. VEH_SHIP in mem, 2 in file.
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleShip, state), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
@ -2787,15 +2787,15 @@ static const SaveLoad _ship_desc[] = {
static const SaveLoad _aircraft_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT, 3), // Aircraft type. VEH_AIRCRAFT in mem, 3 in file.
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, crashed_counter), SLE_UINT16),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, pos), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8),
SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, state), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8),
SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 15 bytes) */
SLE_CONDNULL(15, 2, SL_MAX_VERSION),
@ -2826,8 +2826,8 @@ static const SaveLoad _special_desc[] = {
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk0), SLE_UINT16),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk2), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleSpecial, unk0), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleSpecial, unk2), SLE_UINT8),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
@ -2860,16 +2860,16 @@ static const SaveLoad _disaster_desc[] = {
SLE_VAR(Vehicle, z_height, SLE_UINT8),
SLE_VAR(Vehicle, owner, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(offsetof(Vehicle, current_order) + offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VAR(Vehicle, cur_image, SLE_UINT16),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, image_override), SLE_UINT16),
SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, unk2), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, unk2), SLE_UINT16),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
@ -2913,6 +2913,16 @@ static void Load_VEHS()
v = GetVehicle(index);
SlObject(v, (SaveLoad*)_veh_descs[SlReadByte()]);
switch (v->type) {
case VEH_TRAIN: v = new (v) Train(); break;
case VEH_ROAD: v = new (v) RoadVehicle(); break;
case VEH_SHIP: v = new (v) Ship(); break;
case VEH_AIRCRAFT: v = new (v) Aircraft(); break;
case VEH_SPECIAL: v = new (v) SpecialVehicle(); break;
case VEH_DISASTER: v = new (v) DisasterVehicle(); break;
case VEH_INVALID: v = new (v) InvalidVehicle(); break;
}
/* Old savegames used 'last_station_visited = 0xFF' */
if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
v->last_station_visited = INVALID_STATION;

View File

@ -316,6 +316,107 @@ struct Vehicle {
void BeginLoading();
void LeaveStation();
/**
* An overriden version of new, so you can use the vehicle instance
* instead of a newly allocated piece of memory.
* @param size the size of the variable (unused)
* @param v the vehicle to use as 'storage' backend
* @return the memory that is 'allocated'
*/
void* operator new(size_t size, Vehicle *v) { return v; }
/**
* 'Free' the memory allocated by the overriden new.
* @param p the memory to 'free'
* @param v the vehicle that was given to 'new' on creation.
* @note This function isn't used (at the moment) and only added
* to please some compiler.
*/
void operator delete(void *p, Vehicle *v) {}
/**
* 'Free' the memory allocated by the overriden new.
* @param p the memory to 'free'
* @note This function isn't used (at the moment) and only added
* as the above function was needed to please some compiler
* which made it necessary to add this to please yet
* another compiler...
*/
void operator delete(void *p) {}
/** We want to 'destruct' the right class. */
virtual ~Vehicle() {}
/**
* Get a string 'representation' of the vehicle type.
* @return the string representation.
*/
virtual const char* GetTypeString() = 0;
};
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool
* and you reinitialize that to a Train using:
* v = new (v) Train();
*
* As side-effect the vehicle type is set correctly.
*
* A special vehicle is one of the following:
* - smoke
* - electric sparks for trains
* - explosions
* - bulldozer (road works)
* - bubbles (industry)
*/
struct SpecialVehicle : public Vehicle {
/** Initializes the Vehicle to a special vehicle */
SpecialVehicle() { this->type = VEH_SPECIAL; }
/** We want to 'destruct' the right class. */
virtual ~SpecialVehicle() {}
const char *GetTypeString() { return "special vehicle"; }
};
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool
* and you reinitialize that to a Train using:
* v = new (v) Train();
*
* As side-effect the vehicle type is set correctly.
*/
struct DisasterVehicle : public Vehicle {
/** Initializes the Vehicle to a disaster vehicle */
DisasterVehicle() { this->type = VEH_DISASTER; }
/** We want to 'destruct' the right class. */
virtual ~DisasterVehicle() {}
const char *GetTypeString() { return "disaster vehicle"; }
};
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool
* and you reinitialize that to a Train using:
* v = new (v) Train();
*
* As side-effect the vehicle type is set correctly.
*
* An invalid vehicle must never be used; all (virtual) functions from
* Vehicle should assert (NOT_REACHED).
*/
struct InvalidVehicle : public Vehicle {
/** Initializes the Vehicle to a invalid vehicle */
InvalidVehicle() { this->type = VEH_INVALID; }
/** We want to 'destruct' the right class. */
virtual ~InvalidVehicle() {}
const char *GetTypeString() { return "invalid vehicle"; }
};
#define is_custom_sprite(x) (x >= 0xFD)
@ -470,7 +571,7 @@ void DestroyVehicle(Vehicle *v);
static inline void DeleteVehicle(Vehicle *v)
{
DestroyVehicle(v);
v->type = VEH_INVALID;
v = new (v) InvalidVehicle();
}
static inline bool IsPlayerBuildableVehicleType(byte type)