mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r11004) -Codechange: some reworks of the saveload mechanism to be able to save and load private and protected variables in the vehicle struct.
This commit is contained in:
parent
cb7eaff353
commit
9b65bc430c
|
@ -405,7 +405,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
v->u.air.state = HANGAR;
|
||||
v->u.air.previous_pos = v->u.air.pos;
|
||||
v->u.air.targetairport = GetStationIndex(tile);
|
||||
v->next = u;
|
||||
v->SetNext(u);
|
||||
|
||||
v->service_interval = _patches.servint_aircraft;
|
||||
|
||||
|
@ -429,8 +429,6 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
if (v->subtype == AIR_HELICOPTER) {
|
||||
Vehicle *w = vl[2];
|
||||
|
||||
u->next = w;
|
||||
|
||||
w = new (w) Aircraft();
|
||||
w->direction = DIR_N;
|
||||
w->owner = _current_player;
|
||||
|
@ -445,6 +443,8 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
/* Use rotor's air.state to store the rotor animation frame */
|
||||
w->u.air.state = HRS_ROTOR_STOPPED;
|
||||
w->UpdateDeltaXY(INVALID_DIR);
|
||||
|
||||
u->SetNext(w);
|
||||
VehiclePositionChanged(w);
|
||||
}
|
||||
|
||||
|
|
|
@ -611,7 +611,7 @@ static void DisasterTick_Big_Ufo(Vehicle *v)
|
|||
w = new DisasterVehicle();
|
||||
if (w == NULL) return;
|
||||
|
||||
u->next = w;
|
||||
u->SetNext(w);
|
||||
InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow);
|
||||
w->vehstatus |= VS_SHADOW;
|
||||
} else if (v->current_order.dest == 0) {
|
||||
|
@ -782,7 +782,7 @@ static void Disaster_Zeppeliner_Init()
|
|||
/* Allocate shadow too? */
|
||||
u = new DisasterVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
v->SetNext(u);
|
||||
InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow);
|
||||
u->vehstatus |= VS_SHADOW;
|
||||
}
|
||||
|
@ -807,7 +807,7 @@ static void Disaster_Small_Ufo_Init()
|
|||
/* Allocate shadow too? */
|
||||
u = new DisasterVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
v->SetNext(u);
|
||||
InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow);
|
||||
u->vehstatus |= VS_SHADOW;
|
||||
}
|
||||
|
@ -843,7 +843,7 @@ static void Disaster_Airplane_Init()
|
|||
|
||||
u = new DisasterVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
v->SetNext(u);
|
||||
InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow);
|
||||
u->vehstatus |= VS_SHADOW;
|
||||
}
|
||||
|
@ -878,13 +878,13 @@ static void Disaster_Helicopter_Init()
|
|||
|
||||
u = new DisasterVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
v->SetNext(u);
|
||||
InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow);
|
||||
u->vehstatus |= VS_SHADOW;
|
||||
|
||||
w = new DisasterVehicle();
|
||||
if (w != NULL) {
|
||||
u->next = w;
|
||||
u->SetNext(w);
|
||||
InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors);
|
||||
}
|
||||
}
|
||||
|
@ -910,7 +910,7 @@ static void Disaster_Big_Ufo_Init()
|
|||
/* Allocate shadow too? */
|
||||
u = new DisasterVehicle();
|
||||
if (u != NULL) {
|
||||
v->next = u;
|
||||
v->SetNext(u);
|
||||
InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow);
|
||||
u->vehstatus |= VS_SHADOW;
|
||||
}
|
||||
|
|
|
@ -1206,7 +1206,7 @@ static bool LoadOldVehicle(LoadgameState *ls, int num)
|
|||
default: v->spritenum >>= 1; break;
|
||||
}
|
||||
|
||||
if (_old_next_ptr != 0xFFFF) v->next = GetVehicle(_old_next_ptr);
|
||||
if (_old_next_ptr != 0xFFFF) v->SetNext(GetVehicle(_old_next_ptr));
|
||||
|
||||
v->string_id = RemapOldStringID(_old_string_id);
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ static struct {
|
|||
ReaderProc *read_bytes; ///< savegame loader function
|
||||
|
||||
const ChunkHandler* const *chs; ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
|
||||
const SaveLoad* const *includes; ///< the internal layouf of the given chunk
|
||||
|
||||
/* When saving/loading savegames, they are always saved to a temporary memory-place
|
||||
* to be flushed to file (save) or to final place (load) when full. */
|
||||
|
@ -755,7 +754,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
|||
}
|
||||
break;
|
||||
case SL_WRITEBYTE: return 1; // a byte is logically of size 1
|
||||
case SL_INCLUDE: return SlCalcObjLength(object, _sl.includes[sld->version_from]);
|
||||
case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
return 0;
|
||||
|
@ -804,11 +803,9 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
|||
}
|
||||
break;
|
||||
|
||||
/* SL_INCLUDE loads common code for a type
|
||||
* XXX - variable renaming abuse
|
||||
* include_index: common code to include from _desc_includes[], abused by sld->version_from */
|
||||
case SL_INCLUDE:
|
||||
SlObject(ptr, _sl.includes[sld->version_from]);
|
||||
/* SL_VEH_INCLUDE loads common code for vehicles */
|
||||
case SL_VEH_INCLUDE:
|
||||
SlObject(ptr, GetVehicleDescription(VEH_END));
|
||||
break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
@ -1281,12 +1278,6 @@ static const ChunkHandler * const _chunk_handlers[] = {
|
|||
NULL,
|
||||
};
|
||||
|
||||
/* used to include a vehicle desc in another desc. */
|
||||
extern const SaveLoad _common_veh_desc[];
|
||||
static const SaveLoad* const _desc_includes[] = {
|
||||
_common_veh_desc
|
||||
};
|
||||
|
||||
/**
|
||||
* Pointers cannot be saved to a savegame, so this functions gets
|
||||
* the index of the item, and if not available, it hussles with
|
||||
|
@ -1628,7 +1619,6 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
|
|||
_sl.bufe = _sl.bufp = NULL;
|
||||
_sl.offs_base = 0;
|
||||
_sl.save = (mode != 0);
|
||||
_sl.includes = _desc_includes;
|
||||
_sl.chs = _chunk_handlers;
|
||||
|
||||
/* General tactic is to first save the game to memory, then use an available writer
|
||||
|
|
|
@ -160,15 +160,15 @@ enum VarTypes {
|
|||
typedef uint32 VarType;
|
||||
|
||||
enum SaveLoadTypes {
|
||||
SL_VAR = 0,
|
||||
SL_REF = 1,
|
||||
SL_ARR = 2,
|
||||
SL_STR = 3,
|
||||
SL_LST = 4,
|
||||
SL_VAR = 0,
|
||||
SL_REF = 1,
|
||||
SL_ARR = 2,
|
||||
SL_STR = 3,
|
||||
SL_LST = 4,
|
||||
// non-normal save-load types
|
||||
SL_WRITEBYTE = 8,
|
||||
SL_INCLUDE = 9,
|
||||
SL_END = 15
|
||||
SL_WRITEBYTE = 8,
|
||||
SL_VEH_INCLUDE = 9,
|
||||
SL_END = 15
|
||||
};
|
||||
|
||||
typedef byte SaveLoadType;
|
||||
|
@ -209,8 +209,6 @@ typedef SaveLoad SaveLoadGlobVarList;
|
|||
|
||||
/* Translate values ingame to different values in the savegame and vv */
|
||||
#define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
|
||||
/* Load common code and put it into each struct (currently only for vehicles */
|
||||
#define SLE_INCLUDE(base, variable, include_index) SLE_GENERAL(SL_INCLUDE, base, variable, 0, 0, include_index, 0)
|
||||
|
||||
/* The same as the ones at the top, only the offset is given directly; used for unions */
|
||||
#define SLE_GENERALX(cmd, offset, type, param1, param2) {false, cmd, type, 0, param1, param2, (void*)(offset)}
|
||||
|
@ -221,7 +219,7 @@ typedef SaveLoad SaveLoadGlobVarList;
|
|||
#define SLE_REFX(offset, type) SLE_CONDREFX(offset, type, 0, SL_MAX_VERSION)
|
||||
|
||||
#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, something, 0)
|
||||
#define SLE_INCLUDEX(offset, type) SLE_GENERALX(SL_INCLUDE, offset, type, 0, SL_MAX_VERSION)
|
||||
#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION)
|
||||
|
||||
/* End marker */
|
||||
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
|
||||
|
|
|
@ -558,7 +558,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 fla
|
|||
SetTrainWagon(v);
|
||||
|
||||
if (u != NULL) {
|
||||
u->next = v;
|
||||
u->SetNext(v);
|
||||
} else {
|
||||
SetFreeWagon(v);
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
|
||||
|
@ -636,7 +636,7 @@ static void AddRearEngineToMultiheadedTrain(Vehicle* v, Vehicle* u, bool buildin
|
|||
u->cargo_subtype = v->cargo_subtype;
|
||||
u->cargo_cap = v->cargo_cap;
|
||||
u->u.rail.railtype = v->u.rail.railtype;
|
||||
if (building) v->next = u;
|
||||
if (building) v->SetNext(u);
|
||||
u->engine_type = v->engine_type;
|
||||
u->build_year = v->build_year;
|
||||
if (building) v->value >>= 1;
|
||||
|
@ -840,7 +840,7 @@ static Vehicle *UnlinkWagon(Vehicle *v, Vehicle *first)
|
|||
|
||||
Vehicle *u;
|
||||
for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
|
||||
GetLastEnginePart(u)->next = GetNextVehicle(v);
|
||||
GetLastEnginePart(u)->SetNext(GetNextVehicle(v));
|
||||
v->first = NULL; // we shouldn't point to the old first, since the vehicle isn't in that chain anymore
|
||||
return first;
|
||||
}
|
||||
|
@ -1041,7 +1041,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
|
|||
if (src != src_head) {
|
||||
Vehicle *v = src_head;
|
||||
while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
|
||||
GetLastEnginePart(v)->next = NULL;
|
||||
GetLastEnginePart(v)->SetNext(NULL);
|
||||
} else {
|
||||
InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
|
||||
src_head = NULL;
|
||||
|
@ -1051,7 +1051,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p
|
|||
if (src_head == dst_head) dst_head = NULL;
|
||||
/* unlink single wagon from linked list */
|
||||
src_head = UnlinkWagon(src, src_head);
|
||||
GetLastEnginePart(src)->next = NULL;
|
||||
GetLastEnginePart(src)->SetNext(NULL);
|
||||
}
|
||||
|
||||
if (dst == NULL) {
|
||||
|
|
|
@ -2724,8 +2724,15 @@ static uint16 _cargo_paid_for;
|
|||
static Money _cargo_feeder_share;
|
||||
static uint32 _cargo_loaded_at_xy;
|
||||
|
||||
/**
|
||||
* Make it possible to make the saveload tables "friends" of other classes.
|
||||
* @param vt the vehicle type. Can be VEH_END for the common vehicle description data
|
||||
* @return the saveload description
|
||||
*/
|
||||
const SaveLoad *GetVehicleDescription(VehicleType vt)
|
||||
{
|
||||
/** Save and load of vehicles */
|
||||
extern const SaveLoad _common_veh_desc[] = {
|
||||
static const SaveLoad _common_veh_desc[] = {
|
||||
SLE_VAR(Vehicle, subtype, SLE_UINT8),
|
||||
|
||||
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
|
||||
|
@ -2848,7 +2855,7 @@ extern const SaveLoad _common_veh_desc[] = {
|
|||
|
||||
static const SaveLoad _train_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
|
||||
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
|
||||
SLE_VEH_INCLUDEX(),
|
||||
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),
|
||||
|
@ -2866,7 +2873,7 @@ static const SaveLoad _train_desc[] = {
|
|||
|
||||
static const SaveLoad _roadveh_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
|
||||
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
|
||||
SLE_VEH_INCLUDEX(),
|
||||
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),
|
||||
|
@ -2886,7 +2893,7 @@ static const SaveLoad _roadveh_desc[] = {
|
|||
|
||||
static const SaveLoad _ship_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
|
||||
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
|
||||
SLE_VEH_INCLUDEX(),
|
||||
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 16 bytes) */
|
||||
|
@ -2897,7 +2904,7 @@ static const SaveLoad _ship_desc[] = {
|
|||
|
||||
static const SaveLoad _aircraft_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
|
||||
SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
|
||||
SLE_VEH_INCLUDEX(),
|
||||
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),
|
||||
|
||||
|
@ -2988,8 +2995,12 @@ static const SaveLoad *_veh_descs[] = {
|
|||
_aircraft_desc,
|
||||
_special_desc,
|
||||
_disaster_desc,
|
||||
_common_veh_desc,
|
||||
};
|
||||
|
||||
return _veh_descs[vt];
|
||||
}
|
||||
|
||||
/** Will be called when the vehicles need to be saved. */
|
||||
static void Save_VEHS()
|
||||
{
|
||||
|
@ -2997,7 +3008,7 @@ static void Save_VEHS()
|
|||
/* Write the vehicles */
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
SlSetArrayIndex(v->index);
|
||||
SlObject(v, _veh_descs[v->type]);
|
||||
SlObject(v, GetVehicleDescription(v->type));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3024,7 +3035,7 @@ static void Load_VEHS()
|
|||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
SlObject(v, _veh_descs[vtype]);
|
||||
SlObject(v, GetVehicleDescription(vtype));
|
||||
|
||||
if (_cargo_count != 0 && IsPlayerBuildableVehicleType(v)) {
|
||||
/* Don't construct the packet with station here, because that'll fail with old savegames */
|
||||
|
@ -3157,7 +3168,6 @@ void Vehicle::HandleLoading(bool mode)
|
|||
InvalidateVehicleOrder(this);
|
||||
}
|
||||
|
||||
|
||||
void SpecialVehicle::UpdateDeltaXY(Direction direction)
|
||||
{
|
||||
this->x_offs = 0;
|
||||
|
|
|
@ -218,11 +218,18 @@ struct VehicleShip {
|
|||
struct Vehicle;
|
||||
DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
|
||||
|
||||
struct SaveLoad;
|
||||
extern const SaveLoad *GetVehicleDescription(VehicleType vt);
|
||||
|
||||
struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool> {
|
||||
VehicleTypeByte type; ///< Type of vehicle
|
||||
byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes)
|
||||
|
||||
private:
|
||||
Vehicle *next; // pointer to the next vehicle in the chain
|
||||
public:
|
||||
friend const SaveLoad *GetVehicleDescription(VehicleType vt); // So we can use private/protected variables in the saveload code
|
||||
|
||||
Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain
|
||||
Vehicle *depot_list; // NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace
|
||||
|
||||
|
|
Loading…
Reference in New Issue