(svn r14828) -Codechange: move most of save/load-specific code to separate files
parent
e62e12e7f5
commit
91233ea596
@ -0,0 +1,82 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file gamelog_internal.h Declaration shared among gamelog.cpp and saveload/gamelog_sl.cpp */
|
||||
|
||||
#ifndef GAMELOG_INTERNAL_H
|
||||
#define GAMELOG_INTERNAL_H
|
||||
|
||||
#include "network/core/config.h"
|
||||
|
||||
/** Type of logged change */
|
||||
enum GamelogChangeType {
|
||||
GLCT_MODE, ///< Scenario editor x Game, different landscape
|
||||
GLCT_REVISION, ///< Changed game revision string
|
||||
GLCT_OLDVER, ///< Loaded from savegame without logged data
|
||||
GLCT_PATCH, ///< Non-networksafe patch value changed
|
||||
GLCT_GRFADD, ///< Removed GRF
|
||||
GLCT_GRFREM, ///< Added GRF
|
||||
GLCT_GRFCOMPAT, ///< Loading compatible GRF
|
||||
GLCT_GRFPARAM, ///< GRF parameter changed
|
||||
GLCT_GRFMOVE, ///< GRF order changed
|
||||
GLCT_GRFBUG, ///< GRF bug triggered
|
||||
GLCT_END, ///< So we know how many GLCTs are there
|
||||
GLCT_NONE = 0xFF, ///< In savegames, end of list
|
||||
};
|
||||
|
||||
|
||||
/** Contains information about one logged change */
|
||||
struct LoggedChange {
|
||||
GamelogChangeType ct; ///< Type of change logged in this struct
|
||||
union {
|
||||
struct {
|
||||
byte mode; ///< new game mode - Editor x Game
|
||||
byte landscape; ///< landscape (temperate, arctic, ...)
|
||||
} mode;
|
||||
struct {
|
||||
char text[NETWORK_REVISION_LENGTH]; ///< revision string, _openttd_revision
|
||||
uint32 newgrf; ///< _openttd_newgrf_version
|
||||
uint16 slver; ///< _sl_version
|
||||
byte modified; ///< _openttd_revision_modified
|
||||
} revision;
|
||||
struct {
|
||||
uint32 type; ///< type of savegame, @see SavegameType
|
||||
uint32 version; ///< major and minor version OR ttdp version
|
||||
} oldver;
|
||||
GRFIdentifier grfadd; ///< ID and md5sum of added GRF
|
||||
struct {
|
||||
uint32 grfid; ///< ID of removed GRF
|
||||
} grfrem;
|
||||
GRFIdentifier grfcompat; ///< ID and new md5sum of changed GRF
|
||||
struct {
|
||||
uint32 grfid; ///< ID of GRF with changed parameters
|
||||
} grfparam;
|
||||
struct {
|
||||
uint32 grfid; ///< ID of moved GRF
|
||||
int32 offset; ///< offset, positive = move down
|
||||
} grfmove;
|
||||
struct {
|
||||
char *name; ///< name of the patch
|
||||
int32 oldval; ///< old value
|
||||
int32 newval; ///< new value
|
||||
} patch;
|
||||
struct {
|
||||
uint64 data; ///< additional data
|
||||
uint32 grfid; ///< ID of problematic GRF
|
||||
byte bug; ///< type of bug, @see enum GRFBugs
|
||||
} grfbug;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/** Contains information about one logged action that caused at least one logged change */
|
||||
struct LoggedAction {
|
||||
LoggedChange *change; ///< First logged change in this action
|
||||
uint32 changes; ///< Number of changes in this action
|
||||
GamelogActionType at; ///< Type of action
|
||||
uint16 tick; ///< Tick when it happened
|
||||
};
|
||||
|
||||
extern LoggedAction *_gamelog_action;
|
||||
extern uint _gamelog_actions;
|
||||
|
||||
#endif /* GAMELOG_INTERNAL_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,79 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file ai_sl.cpp Code handling saving and loading of old AI + new AI initialisation after game load */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../ai/ai.h"
|
||||
#include "../ai/default/default.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _company_ai_desc[] = {
|
||||
SLE_VAR(CompanyAI, state, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, tick, SLE_UINT8),
|
||||
SLE_CONDVAR(CompanyAI, state_counter, SLE_FILE_U16 | SLE_VAR_U32, 0, 12),
|
||||
SLE_CONDVAR(CompanyAI, state_counter, SLE_UINT32, 13, SL_MAX_VERSION),
|
||||
SLE_VAR(CompanyAI, timeout_counter, SLE_UINT16),
|
||||
|
||||
SLE_VAR(CompanyAI, state_mode, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, banned_tile_count, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, railtype_to_use, SLE_UINT8),
|
||||
|
||||
SLE_VAR(CompanyAI, cargo_type, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, num_wagons, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, build_kind, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, num_build_rec, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, num_loco_to_build, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, num_want_fullload, SLE_UINT8),
|
||||
|
||||
SLE_VAR(CompanyAI, route_type_mask, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(CompanyAI, start_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(CompanyAI, start_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(CompanyAI, cur_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(CompanyAI, cur_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(CompanyAI, start_dir_a, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, cur_dir_a, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(CompanyAI, start_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(CompanyAI, start_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(CompanyAI, cur_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(CompanyAI, cur_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(CompanyAI, start_dir_b, SLE_UINT8),
|
||||
SLE_VAR(CompanyAI, cur_dir_b, SLE_UINT8),
|
||||
|
||||
SLE_REF(CompanyAI, cur_veh, REF_VEHICLE),
|
||||
|
||||
SLE_ARR(CompanyAI, wagon_list, SLE_UINT16, 9),
|
||||
SLE_ARR(CompanyAI, order_list_blocks, SLE_UINT8, 20),
|
||||
SLE_ARR(CompanyAI, banned_tiles, SLE_UINT16, 16),
|
||||
|
||||
SLE_CONDNULL(64, 2, SL_MAX_VERSION),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _company_ai_build_rec_desc[] = {
|
||||
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(AiBuildRec, use_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(AiBuildRec, use_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(AiBuildRec, rand_rng, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, unk6, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, unk7, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, buildcmd_a, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, buildcmd_b, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, direction, SLE_UINT8),
|
||||
SLE_VAR(AiBuildRec, cargo, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
|
||||
void SaveLoad_AI(CompanyID company)
|
||||
{
|
||||
CompanyAI *cai = &_companies_ai[company];
|
||||
SlObject(cai, _company_ai_desc);
|
||||
for (int i = 0; i != cai->num_build_rec; i++) {
|
||||
SlObject(&cai->src + i, _company_ai_build_rec_desc);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../tile_type.h"
|
||||
#include "../core/alloc_func.hpp"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
extern TileIndex *_animated_tile_list;
|
||||
extern uint _animated_tile_count;
|
||||
extern uint _animated_tile_allocated;
|
||||
|
||||
/**
|
||||
* Save the ANIT chunk.
|
||||
*/
|
||||
static void Save_ANIT()
|
||||
{
|
||||
SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
|
||||
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the ANIT chunk; the chunk containing the animated tiles.
|
||||
*/
|
||||
static void Load_ANIT()
|
||||
{
|
||||
/* Before version 80 we did NOT have a variable length animated tile table */
|
||||
if (CheckSavegameVersion(80)) {
|
||||
/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
|
||||
SlArray(_animated_tile_list, 256, CheckSavegameVersion(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
|
||||
|
||||
for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
|
||||
if (_animated_tile_list[_animated_tile_count] == 0) break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
|
||||
|
||||
/* Determine a nice rounded size for the amount of allocated tiles */
|
||||
_animated_tile_allocated = 256;
|
||||
while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
|
||||
|
||||
_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
|
||||
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Definition" imported by the saveload code to be able to load and save
|
||||
* the animated tile table.
|
||||
*/
|
||||
extern const ChunkHandler _animated_tile_chunk_handlers[] = {
|
||||
{ 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
|
||||
};
|
@ -0,0 +1,51 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file autoreplace_sl.cpp Code handling saving and loading of autoreplace rules */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../autoreplace_type.h"
|
||||
#include "../engine_type.h"
|
||||
#include "../group_type.h"
|
||||
#include "../autoreplace_base.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _engine_renew_desc[] = {
|
||||
SLE_VAR(EngineRenew, from, SLE_UINT16),
|
||||
SLE_VAR(EngineRenew, to, SLE_UINT16),
|
||||
|
||||
SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
|
||||
SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_ERNW()
|
||||
{
|
||||
EngineRenew *er;
|
||||
|
||||
FOR_ALL_ENGINE_RENEWS(er) {
|
||||
SlSetArrayIndex(er->index);
|
||||
SlObject(er, _engine_renew_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_ERNW()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
EngineRenew *er = new (index) EngineRenew();
|
||||
SlObject(er, _engine_renew_desc);
|
||||
|
||||
/* Advanced vehicle lists, ungrouped vehicles got added */
|
||||
if (CheckSavegameVersion(60)) {
|
||||
er->group_id = ALL_GROUP;
|
||||
} else if (CheckSavegameVersion(71)) {
|
||||
if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _autoreplace_chunk_handlers[] = {
|
||||
{ 'ERNW', Save_ERNW, Load_ERNW, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,45 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file cargopacket_sl.cpp Code handling saving and loading of cargo packets */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../openttd.h"
|
||||
#include "../cargopacket.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _cargopacket_desc[] = {
|
||||
SLE_VAR(CargoPacket, source, SLE_UINT16),
|
||||
SLE_VAR(CargoPacket, source_xy, SLE_UINT32),
|
||||
SLE_VAR(CargoPacket, loaded_at_xy, SLE_UINT32),
|
||||
SLE_VAR(CargoPacket, count, SLE_UINT16),
|
||||
SLE_VAR(CargoPacket, days_in_transit, SLE_UINT8),
|
||||
SLE_VAR(CargoPacket, feeder_share, SLE_INT64),
|
||||
SLE_VAR(CargoPacket, paid_for, SLE_BOOL),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_CAPA()
|
||||
{
|
||||
CargoPacket *cp;
|
||||
|
||||
FOR_ALL_CARGOPACKETS(cp) {
|
||||
SlSetArrayIndex(cp->index);
|
||||
SlObject(cp, _cargopacket_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_CAPA()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
CargoPacket *cp = new (index) CargoPacket();
|
||||
SlObject(cp, _cargopacket_desc);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _cargopacket_chunk_handlers[] = {
|
||||
{ 'CAPA', Save_CAPA, Load_CAPA, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,37 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file cheat_sl.cpp Code handling saving and loading of cheats */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../cheat_type.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static void Save_CHTS()
|
||||
{
|
||||
/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
|
||||
byte count = sizeof(_cheats) / sizeof(Cheat);
|
||||
Cheat *cht = (Cheat*) &_cheats;
|
||||
Cheat *cht_last = &cht[count];
|
||||
|
||||
SlSetLength(count * 2);
|
||||
for (; cht != cht_last; cht++) {
|
||||
SlWriteByte(cht->been_used);
|
||||
SlWriteByte(cht->value);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_CHTS()
|
||||
{
|
||||
Cheat *cht = (Cheat*)&_cheats;
|
||||
size_t count = SlGetFieldLength() / 2;
|
||||
|
||||
for (uint i = 0; i < count; i++) {
|
||||
cht[i].been_used = (SlReadByte() != 0);
|
||||
cht[i].value = (SlReadByte() != 0);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _cheat_chunk_handlers[] = {
|
||||
{ 'CHTS', Save_CHTS, Load_CHTS, CH_RIFF | CH_LAST}
|
||||
};
|
@ -0,0 +1,240 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file company_sl.cpp Code handling saving and loading of company data */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../company_base.h"
|
||||
#include "../company_func.h"
|
||||
#include "../network/network.h"
|
||||
#include "../ai/ai.h"
|
||||
#include "../ai/trolly/trolly.h"
|
||||
#include "../company_manager_face.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
/**
|
||||
* Converts an old company manager's face format to the new company manager's face format
|
||||
*
|
||||
* Meaning of the bits in the old face (some bits are used in several times):
|
||||
* - 4 and 5: chin
|
||||
* - 6 to 9: eyebrows
|
||||
* - 10 to 13: nose
|
||||
* - 13 to 15: lips (also moustache for males)
|
||||
* - 16 to 19: hair
|
||||
* - 20 to 22: eye color
|
||||
* - 20 to 27: tie, ear rings etc.
|
||||
* - 28 to 30: glasses
|
||||
* - 19, 26 and 27: race (bit 27 set and bit 19 equal to bit 26 = black, otherwise white)
|
||||
* - 31: gender (0 = male, 1 = female)
|
||||
*
|
||||
* @param face the face in the old format
|
||||
* @return the face in the new format
|
||||
*/
|
||||
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face)
|
||||
{
|
||||
CompanyManagerFace cmf = 0;
|
||||
GenderEthnicity ge = GE_WM;
|
||||
|
||||
if (HasBit(face, 31)) SetBit(ge, GENDER_FEMALE);
|
||||
if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) SetBit(ge, ETHNICITY_BLACK);
|
||||
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN, ge, ge);
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_EYE_COLOUR, ge, HasBit(ge, ETHNICITY_BLACK) ? 0 : ClampU(GB(face, 20, 3), 5, 7) - 5);
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_CHIN, ge, ScaleCompanyManagerFaceValue(CMFV_CHIN, ge, GB(face, 4, 2)));
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_EYEBROWS, ge, ScaleCompanyManagerFaceValue(CMFV_EYEBROWS, ge, GB(face, 6, 4)));
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_HAIR, ge, ScaleCompanyManagerFaceValue(CMFV_HAIR, ge, GB(face, 16, 4)));
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_JACKET, ge, ScaleCompanyManagerFaceValue(CMFV_JACKET, ge, GB(face, 20, 2)));
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_COLLAR, ge, ScaleCompanyManagerFaceValue(CMFV_COLLAR, ge, GB(face, 22, 2)));
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_GLASSES, ge, GB(face, 28, 1));
|
||||
|
||||
uint lips = GB(face, 10, 4);
|
||||
if (!HasBit(ge, GENDER_FEMALE) && lips < 4) {
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge, true);
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_MOUSTACHE, ge, max(lips, 1U) - 1);
|
||||
} else {
|
||||
if (!HasBit(ge, GENDER_FEMALE)) {
|
||||
lips = lips * 15 / 16;
|
||||
lips -= 3;
|
||||
if (HasBit(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
|
||||
} else {
|
||||
lips = ScaleCompanyManagerFaceValue(CMFV_LIPS, ge, lips);
|
||||
}
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_LIPS, ge, lips);
|
||||
|
||||
uint nose = GB(face, 13, 3);
|
||||
if (ge == GE_WF) {
|
||||
nose = (nose * 3 >> 3) * 3 >> 2; // There is 'hole' in the nose sprites for females
|
||||
} else {
|
||||
nose = ScaleCompanyManagerFaceValue(CMFV_NOSE, ge, nose);
|
||||
}
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_NOSE, ge, nose);
|
||||
}
|
||||
|
||||
uint tie_earring = GB(face, 24, 4);
|
||||
if (!HasBit(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
|
||||
if (HasBit(ge, GENDER_FEMALE)) SetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge, true);
|
||||
SetCompanyManagerFaceBits(cmf, CMFV_TIE_EARRING, ge, HasBit(ge, GENDER_FEMALE) ? tie_earring : ScaleCompanyManagerFaceValue(CMFV_TIE_EARRING, ge, tie_earring / 2));
|
||||
}
|
||||
|
||||
return cmf;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Save/load of companies */
|
||||
static const SaveLoad _company_desc[] = {
|
||||
SLE_VAR(Company, name_2, SLE_UINT32),
|
||||
SLE_VAR(Company, name_1, SLE_STRINGID),
|
||||
SLE_CONDSTR(Company, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Company, president_name_1, SLE_UINT16),
|
||||
SLE_VAR(Company, president_name_2, SLE_UINT32),
|
||||
SLE_CONDSTR(Company, president_name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Company, face, SLE_UINT32),
|
||||
|
||||
/* money was changed to a 64 bit field in savegame version 1. */
|
||||
SLE_CONDVAR(Company, money, SLE_VAR_I64 | SLE_FILE_I32, 0, 0),
|
||||
SLE_CONDVAR(Company, money, SLE_INT64, 1, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Company, current_loan, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
|
||||
SLE_CONDVAR(Company, current_loan, SLE_INT64, 65, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Company, colour, SLE_UINT8),
|
||||
SLE_VAR(Company, money_fraction, SLE_UINT8),
|
||||
SLE_CONDVAR(Company, avail_railtypes, SLE_UINT8, 0, 57),
|
||||
SLE_VAR(Company, block_preview, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(Company, cargo_types, SLE_FILE_U16 | SLE_VAR_U32, 0, 93),
|
||||
SLE_CONDVAR(Company, cargo_types, SLE_UINT32, 94, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Company, location_of_HQ, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Company, location_of_HQ, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Company, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Company, last_build_coordinate, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Company, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Company, inaugurated_year, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
|
||||
SLE_ARR(Company, share_owners, SLE_UINT8, 4),
|
||||
|
||||
SLE_VAR(Company, num_valid_stat_ent, SLE_UINT8),
|
||||
|
||||
SLE_VAR(Company, quarters_of_bankrupcy, SLE_UINT8),
|
||||
SLE_CONDVAR(Company, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
|
||||
SLE_CONDVAR(Company, bankrupt_asked, SLE_UINT16, 104, SL_MAX_VERSION),
|
||||
SLE_VAR(Company, bankrupt_timeout, SLE_INT16),
|
||||
SLE_CONDVAR(Company, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
|
||||
SLE_CONDVAR(Company, bankrupt_value, SLE_INT64, 65, SL_MAX_VERSION),
|
||||
|
||||
/* yearly expenses was changed to 64-bit in savegame version 2. */
|
||||
SLE_CONDARR(Company, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
|
||||
SLE_CONDARR(Company, yearly_expenses, SLE_INT64, 3 * 13, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Company, is_ai, SLE_BOOL, 2, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(1, 4, 99),
|
||||
|
||||
/* Engine renewal settings */
|
||||
SLE_CONDNULL(512, 16, 18),
|
||||
SLE_CONDREF(Company, engine_renew_list, REF_ENGINE_RENEWS, 19, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Company, engine_renew, SLE_BOOL, 16, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Company, engine_renew_months, SLE_INT16, 16, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Company, engine_renew_money, SLE_UINT32, 16, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Company, renew_keep_length, SLE_BOOL, 2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
|
||||
|
||||
/* reserve extra space in savegame here. (currently 63 bytes) */
|
||||
SLE_CONDNULL(63, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _company_economy_desc[] = {
|
||||
/* these were changed to 64-bit in savegame format 2 */
|
||||
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
|
||||
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_INT64, 2, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
|
||||
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_INT64, 2, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
|
||||
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(CompanyEconomyEntry, delivered_cargo, SLE_INT32),
|
||||
SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _company_livery_desc[] = {
|
||||
SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void SaveLoad_PLYR(Company *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
SlObject(c, _company_desc);
|
||||
|
||||
/* Write AI? */
|
||||
if (!IsHumanCompany(c->index)) {
|
||||
extern void SaveLoad_AI(CompanyID company);
|
||||
SaveLoad_AI(c->index);
|
||||
}
|
||||
|
||||
/* Write economy */
|
||||
SlObject(&c->cur_economy, _company_economy_desc);
|
||||
|
||||
/* Write old economy entries. */
|
||||
for (i = 0; i < c->num_valid_stat_ent; i++) {
|
||||
SlObject(&c->old_economy[i], _company_economy_desc);
|
||||
}
|
||||
|
||||
/* Write each livery entry. */
|
||||
int num_liveries = CheckSavegameVersion(63) ? LS_END - 4 : (CheckSavegameVersion(85) ? LS_END - 2: LS_END);
|
||||
for (i = 0; i < num_liveries; i++) {
|
||||
SlObject(&c->livery[i], _company_livery_desc);
|
||||
}
|
||||
|
||||
if (num_liveries < LS_END) {
|
||||
/* We want to insert some liveries somewhere in between. This means some have to be moved. */
|
||||
memmove(&c->livery[LS_FREIGHT_WAGON], &c->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(c->livery[0]));
|
||||
c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL];
|
||||
c->livery[LS_PASSENGER_WAGON_MAGLEV] = c->livery[LS_MAGLEV];
|
||||
}
|
||||
|
||||
if (num_liveries == LS_END - 4) {
|
||||
/* Copy bus/truck liveries over to trams */
|
||||
c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS];
|
||||
c->livery[LS_FREIGHT_TRAM] = c->livery[LS_TRUCK];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_PLYR()
|
||||
{
|
||||
Company *c;
|
||||
FOR_ALL_COMPANIES(c) {
|
||||
SlSetArrayIndex(c->index);
|
||||
SlAutolength((AutolengthProc*)SaveLoad_PLYR, c);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_PLYR()
|
||||
{
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Company *c = new (index) Company();
|
||||
SaveLoad_PLYR(c);
|
||||
_company_colours[index] = c->colour;
|
||||
|
||||
/* This is needed so an AI is attached to a loaded AI */
|
||||
if (c->is_ai && (!_networking || _network_server) && _ai.enabled) {
|
||||
/* Clear the memory of the new AI, otherwise we might be doing wrong things. */
|
||||
memset(&_companies_ainew[index], 0, sizeof(CompanyAiNew));
|
||||
AI_StartNewAI(c->index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _company_chunk_handlers[] = {
|
||||
{ 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,39 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file depot_sl.cpp Code handling saving and loading of depots */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../depot_base.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _depot_desc[] = {
|
||||
SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Depot, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(Depot, town_index, SLE_UINT16),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_DEPT()
|
||||
{
|
||||
Depot *depot;
|
||||
|
||||
FOR_ALL_DEPOTS(depot) {
|
||||
SlSetArrayIndex(depot->index);
|
||||
SlObject(depot, _depot_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_DEPT()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Depot *depot = new (index) Depot();
|
||||
SlObject(depot, _depot_desc);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _depot_chunk_handlers[] = {
|
||||
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,58 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file economy_sl.cpp Code handling saving and loading of economy data */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../economy_func.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
/** Prices */
|
||||
static void SaveLoad_PRIC()
|
||||
{
|
||||
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
|
||||
SlArray(&_price, NUM_PRICES, vt);
|
||||
SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
|
||||
}
|
||||
|
||||
/** Cargo payment rates */
|
||||
static void SaveLoad_CAPR()
|
||||
{
|
||||
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
|
||||
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
|
||||
SlArray(&_cargo_payment_rates, num_cargo, vt);
|
||||
SlArray(&_cargo_payment_rates_frac, num_cargo, SLE_UINT16);
|
||||
}
|
||||
|
||||
static const SaveLoad _economy_desc[] = {
|
||||
SLE_CONDVAR(Economy, max_loan, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
||||
SLE_CONDVAR(Economy, max_loan, SLE_INT64, 65, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Economy, max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
||||
SLE_CONDVAR(Economy, max_loan_unround, SLE_INT64, 65, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Economy, max_loan_unround_fract, SLE_UINT16, 70, SL_MAX_VERSION),
|
||||
SLE_VAR(Economy, fluct, SLE_INT16),
|
||||
SLE_VAR(Economy, interest_rate, SLE_UINT8),
|
||||
SLE_VAR(Economy, infl_amount, SLE_UINT8),
|
||||
SLE_VAR(Economy, infl_amount_pr, SLE_UINT8),
|
||||
SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32, 102, SL_MAX_VERSION),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
/** Economy variables */
|
||||
static void Save_ECMY()
|
||||
{
|
||||
SlObject(&_economy, _economy_desc);
|
||||
}
|
||||
|
||||
/** Economy variables */
|
||||
static void Load_ECMY()
|
||||
{
|
||||
SlObject(&_economy, _economy_desc);
|
||||
StartupIndustryDailyChanges(CheckSavegameVersion(102)); // old savegames will need to be initialized
|
||||
}
|
||||
|
||||
extern const ChunkHandler _economy_chunk_handlers[] = {
|
||||
{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
|
||||
{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
|
||||
{ 'ECMY', Save_ECMY, Load_ECMY, CH_RIFF | CH_LAST},
|
||||
};
|
@ -0,0 +1,118 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file engine_sl.cpp Code handling saving and loading of engines */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "saveload.h"
|
||||
#include "saveload_internal.h"
|
||||
#include "../engine_base.h"
|
||||
#include <map>
|
||||
|
||||
static const SaveLoad _engine_desc[] = {
|
||||
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Engine, intro_date, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Engine, age, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_VAR(Engine, reliability, SLE_UINT16),
|
||||
SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
|
||||
SLE_VAR(Engine, reliability_start, SLE_UINT16),
|
||||
SLE_VAR(Engine, reliability_max, SLE_UINT16),
|
||||
SLE_VAR(Engine, reliability_final, SLE_UINT16),
|
||||
SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
|
||||
SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
|
||||
SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
|
||||
|
||||
SLE_VAR(Engine, lifelength, SLE_UINT8),
|
||||
SLE_VAR(Engine, flags, SLE_UINT8),
|
||||
SLE_VAR(Engine, preview_company_rank,SLE_UINT8),
|
||||
SLE_VAR(Engine, preview_wait, SLE_UINT8),
|
||||
SLE_CONDNULL(1, 0, 44),
|
||||
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
|
||||
SLE_CONDVAR(Engine, company_avail, SLE_UINT16, 104, SL_MAX_VERSION),
|
||||
SLE_CONDSTR(Engine, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 16 bytes) */
|
||||
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static std::map<EngineID, Engine> _temp_engine;
|
||||
|
||||
Engine *GetTempDataEngine(EngineID index)
|
||||
{
|
||||
return &_temp_engine[index];
|
||||
}
|
||||
|
||||
static void Save_ENGN()
|
||||
{
|
||||
Engine *e;
|
||||
FOR_ALL_ENGINES(e) {
|
||||
SlSetArrayIndex(e->index);
|
||||
SlObject(e, _engine_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_ENGN()
|
||||
{
|
||||
/* As engine data is loaded before engines are initialized we need to load
|
||||
* this information into a temporary array. This is then copied into the
|
||||
* engine pool after processing NewGRFs by CopyTempEngineData(). */
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Engine *e = GetTempDataEngine(index);
|
||||
SlObject(e, _engine_desc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy data from temporary engine array into the real engine pool.
|
||||
*/
|
||||
void CopyTempEngineData()
|
||||
{
|
||||
Engine *e;
|
||||
FOR_ALL_ENGINES(e) {
|
||||
if (e->index >= _temp_engine.size()) break;
|
||||
|
||||
const Engine *se = GetTempDataEngine(e->index);
|
||||
e->intro_date = se->intro_date;
|
||||
e->age = se->age;
|
||||
e->reliability = se->reliability;
|
||||
e->reliability_spd_dec = se->reliability_spd_dec;
|
||||
e->reliability_start = se->reliability_start;
|
||||
e->reliability_max = se->reliability_max;
|
||||
e->reliability_final = se->reliability_final;
|
||||
e->duration_phase_1 = se->duration_phase_1;
|
||||
e->duration_phase_2 = se->duration_phase_2;
|
||||
e->duration_phase_3 = se->duration_phase_3;
|
||||
e->lifelength = se->lifelength;
|
||||
e->flags = se->flags;
|
||||
e->preview_company_rank= se->preview_company_rank;
|
||||
e->preview_wait = se->preview_wait;
|
||||
e->company_avail = se->company_avail;
|
||||
if (se->name != NULL) e->name = strdup(se->name);
|
||||
}
|
||||
|
||||
/* Get rid of temporary data */
|
||||
_temp_engine.clear();
|
||||
}
|
||||
|
||||
static void Load_ENGS()
|
||||
{
|
||||
/* Load old separate String ID list into a temporary array. This
|
||||
* was always 256 entries. */
|
||||
StringID names[256];
|
||||
|
||||
SlArray(names, lengthof(names), SLE_STRINGID);
|
||||
|
||||
/* Copy each string into the temporary engine array. */
|
||||
for (EngineID engine = 0; engine < lengthof(names); engine++) {
|
||||
Engine *e = GetTempDataEngine(engine);
|
||||
e->name = CopyFromOldName(names[engine]);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _engine_chunk_handlers[] = {
|
||||
{ 'ENGN', Save_ENGN, Load_ENGN, CH_ARRAY },
|
||||
{ 'ENGS', NULL, Load_ENGS, CH_RIFF | CH_LAST },
|
||||
};
|
@ -0,0 +1,161 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file gamelog_sl.cpp Code handling saving and loading of gamelog data */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../gamelog.h"
|
||||
#include "../gamelog_internal.h"
|
||||
#include "../core/alloc_func.hpp"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _glog_action_desc[] = {
|
||||
SLE_VAR(LoggedAction, tick, SLE_UINT16),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_mode_desc[] = {
|
||||
SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
|
||||
SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_revision_desc[] = {
|
||||
SLE_ARR(LoggedChange, revision.text, SLE_UINT8, NETWORK_REVISION_LENGTH),
|
||||
SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
|
||||
SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
|
||||
SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_oldver_desc[] = {
|
||||
SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
|
||||
SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_patch_desc[] = {
|
||||
SLE_STR(LoggedChange, patch.name, SLE_STR, 128),
|
||||
SLE_VAR(LoggedChange, patch.oldval, SLE_INT32),
|
||||
SLE_VAR(LoggedChange, patch.newval, SLE_INT32),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_grfadd_desc[] = {
|
||||
SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
|
||||
SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_grfrem_desc[] = {
|
||||
SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_grfcompat_desc[] = {
|
||||
SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
|
||||
SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_grfparam_desc[] = {
|
||||
SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_grfmove_desc[] = {
|
||||
SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
|
||||
SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _glog_grfbug_desc[] = {
|
||||
SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
|
||||
SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
|
||||
SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad *_glog_desc[] = {
|
||||
_glog_mode_desc,
|
||||
_glog_revision_desc,
|
||||
_glog_oldver_desc,
|
||||
_glog_patch_desc,
|
||||
_glog_grfadd_desc,
|
||||
_glog_grfrem_desc,
|
||||
_glog_grfcompat_desc,
|
||||
_glog_grfparam_desc,
|
||||
_glog_grfmove_desc,
|
||||
_glog_grfbug_desc,
|
||||
};
|
||||
|
||||
assert_compile(lengthof(_glog_desc) == GLCT_END);
|
||||
|
||||
static void Load_GLOG()
|
||||
{
|
||||
assert(_gamelog_action == NULL);
|
||||
assert(_gamelog_actions == 0);
|
||||
|
||||
GamelogActionType at;
|
||||
while ((at = (GamelogActionType)SlReadByte()) != GLAT_NONE) {
|
||||
_gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1);
|
||||
LoggedAction *la = &_gamelog_action[_gamelog_actions++];
|
||||
|
||||
la->at = at;
|
||||
|
||||
SlObject(la, _glog_action_desc); // has to be saved after 'DATE'!
|
||||
la->change = NULL;
|
||||
la->changes = 0;
|
||||
|
||||
GamelogChangeType ct;
|
||||
while ((ct = (GamelogChangeType)SlReadByte()) != GLCT_NONE) {
|
||||
la->change = ReallocT(la->change, la->changes + 1);
|
||||
|
||||
LoggedChange *lc = &la->change[la->changes++];
|
||||
/* for SLE_STR, pointer has to be valid! so make it NULL */
|
||||
memset(lc, 0, sizeof(*lc));
|
||||
lc->ct = ct;
|
||||
|
||||
assert((uint)ct < GLCT_END);
|
||||
|
||||
SlObject(lc, _glog_desc[ct]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_GLOG()
|
||||
{
|
||||
const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
|
||||
size_t length = 0;
|
||||
|
||||
for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
|
||||
const LoggedChange *lcend = &la->change[la->changes];
|
||||
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
|
||||
assert((uint)lc->ct < lengthof(_glog_desc));
|
||||
length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
|
||||
}
|
||||
length += 4;
|
||||
}
|
||||
length++;
|
||||
|
||||
SlSetLength(length);
|
||||
|
||||
for (LoggedAction *la = _gamelog_action; la != laend; la++) {
|
||||
SlWriteByte(la->at);
|
||||
SlObject(la, _glog_action_desc);
|
||||
|
||||
const LoggedChange *lcend = &la->change[la->changes];
|
||||
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
|
||||
SlWriteByte(lc->ct);
|
||||
assert((uint)lc->ct < GLCT_END);
|
||||
SlObject(lc, _glog_desc[lc->ct]);
|
||||
}
|
||||
SlWriteByte(GLCT_NONE);
|
||||
}
|
||||
SlWriteByte(GLAT_NONE);
|
||||
}
|
||||
|
||||
|
||||
extern const ChunkHandler _gamelog_chunk_handlers[] = {
|
||||
{ 'GLOG', Save_GLOG, Load_GLOG, CH_RIFF | CH_LAST }
|
||||
};
|
@ -0,0 +1,43 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file group_sl.cpp Code handling saving and loading of economy data */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../group.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _group_desc[] = {
|
||||
SLE_CONDVAR(Group, name, SLE_NAME, 0, 83),
|
||||
SLE_CONDSTR(Group, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
SLE_VAR(Group, num_vehicle, SLE_UINT16),
|
||||
SLE_VAR(Group, owner, SLE_UINT8),
|
||||
SLE_VAR(Group, vehicle_type, SLE_UINT8),
|
||||
SLE_VAR(Group, replace_protection, SLE_BOOL),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_GRPS(void)
|
||||
{
|
||||
Group *g;
|
||||
|
||||
FOR_ALL_GROUPS(g) {
|
||||
SlSetArrayIndex(g->index);
|
||||
SlObject(g, _group_desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Load_GRPS(void)
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Group *g = new (index) Group();
|
||||
SlObject(g, _group_desc);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _group_chunk_handlers[] = {
|
||||
{ 'GRPS', Save_GRPS, Load_GRPS, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,155 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file industry_sl.cpp Code handling saving and loading of industries */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../tile_type.h"
|
||||
#include "../strings_type.h"
|
||||
#include "../company_type.h"
|
||||
#include "../industry.h"
|
||||
#include "../newgrf_commons.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _industry_desc[] = {
|
||||
SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(Industry, width, SLE_UINT8),
|
||||
SLE_VAR(Industry, height, SLE_UINT8),
|
||||
SLE_REF(Industry, town, REF_TOWN),
|
||||
SLE_CONDNULL( 2, 0, 60), ///< used to be industry's produced_cargo
|
||||
SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, SL_MAX_VERSION),
|
||||
SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION),
|
||||
SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2),
|
||||
SLE_ARR(Industry, production_rate, SLE_UINT8, 2),
|
||||
SLE_CONDNULL( 3, 0, 60), ///< used to be industry's accepts_cargo
|
||||
SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, SL_MAX_VERSION),
|
||||
SLE_VAR(Industry, prod_level, SLE_UINT8),
|
||||
SLE_ARR(Industry, this_month_production, SLE_UINT16, 2),
|
||||
SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2),
|
||||
SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2),
|
||||
SLE_ARR(Industry, last_month_production, SLE_UINT16, 2),
|
||||
SLE_ARR(Industry, last_month_transported, SLE_UINT16, 2),
|
||||
|
||||
SLE_VAR(Industry, counter, SLE_UINT16),
|
||||
|
||||
SLE_VAR(Industry, type, SLE_UINT8),
|
||||
SLE_VAR(Industry, owner, SLE_UINT8),
|
||||
SLE_VAR(Industry, random_color, SLE_UINT8),
|
||||
SLE_CONDVAR(Industry, last_prod_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Industry, last_prod_year, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_VAR(Industry, was_cargo_delivered, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(Industry, founder, SLE_UINT8, 70, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Industry, construction_date, SLE_INT32, 70, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Industry, construction_type, SLE_UINT8, 70, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Industry, last_cargo_accepted_at, SLE_INT32, 70, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, 73, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Industry, random_triggers, SLE_UINT8, 82, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Industry, random, SLE_UINT16, 82, SL_MAX_VERSION),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 32 bytes) */
|
||||
SLE_CONDNULL(32, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_INDY()
|
||||
{
|
||||
Industry *ind;
|
||||
|
||||
/* Write the industries */
|
||||
FOR_ALL_INDUSTRIES(ind) {
|
||||
SlSetArrayIndex(ind->index);
|
||||
SlObject(ind, _industry_desc);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save and load the mapping between the industry/tile id on the map, and the grf file
|
||||
* it came from. */
|
||||
static const SaveLoad _industries_id_mapping_desc[] = {
|
||||
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
|
||||
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
|
||||
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_IIDS()
|
||||
{
|
||||
uint i;
|
||||
uint j = _industry_mngr.GetMaxMapping();
|
||||
|
||||
for (i = 0; i < j; i++) {
|
||||
SlSetArrayIndex(i);
|
||||
SlObject(&_industry_mngr.mapping_ID[i], _industries_id_mapping_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_TIDS()
|
||||
{
|
||||
uint i;
|
||||
uint j = _industile_mngr.GetMaxMapping();
|
||||
|
||||
for (i = 0; i < j; i++) {
|
||||
SlSetArrayIndex(i);
|
||||
SlObject(&_industile_mngr.mapping_ID[i], _industries_id_mapping_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_INDY()
|
||||
{
|
||||
int index;
|
||||
|
||||
ResetIndustryCounts();
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Industry *i = new (index) Industry();
|
||||
SlObject(i, _industry_desc);
|
||||
IncIndustryTypeCount(i->type);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_IIDS()
|
||||
{
|
||||
int index;
|
||||
uint max_id;
|
||||
|
||||
/* clear the current mapping stored.
|
||||
* This will create the manager if ever it is not yet done */
|
||||
_industry_mngr.ResetMapping();
|
||||
|
||||
/* get boundary for the temporary map loader NUM_INDUSTRYTYPES? */
|
||||
max_id = _industry_mngr.GetMaxMapping();
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
if ((uint)index >= max_id) break;
|
||||
SlObject(&_industry_mngr.mapping_ID[index], _industries_id_mapping_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_TIDS()
|
||||
{
|
||||
int index;
|
||||
uint max_id;
|
||||
|
||||
/* clear the current mapping stored.
|
||||
* This will create the manager if ever it is not yet done */
|
||||
_industile_mngr.ResetMapping();
|
||||
|
||||
/* get boundary for the temporary map loader NUM_INDUSTILES? */
|
||||
max_id = _industile_mngr.GetMaxMapping();
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
if ((uint)index >= max_id) break;
|
||||
SlObject(&_industile_mngr.mapping_ID[index], _industries_id_mapping_desc);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _industry_chunk_handlers[] = {
|
||||
{ 'INDY', Save_INDY, Load_INDY, CH_ARRAY},
|
||||
{ 'IIDS', Save_IIDS, Load_IIDS, CH_ARRAY},
|
||||
{ 'TIDS', Save_TIDS, Load_TIDS, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,249 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file map_sl.cpp Code handling saving and loading of map */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../tile_type.h"
|
||||
#include "../map_func.h"
|
||||
#include "../core/alloc_type.hpp"
|
||||
#include "../core/bitmath_func.hpp"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static uint32 _map_dim_x;
|
||||
static uint32 _map_dim_y;
|
||||
|
||||
static const SaveLoadGlobVarList _map_dimensions[] = {
|
||||
SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLEG_END()
|
||||
};
|
||||
|
||||
static void Save_MAPS()
|
||||
{
|
||||
_map_dim_x = MapSizeX();
|
||||
_map_dim_y = MapSizeY();
|
||||
SlGlobList(_map_dimensions);
|
||||
}
|
||||
|
||||
static void Load_MAPS()
|
||||
{
|
||||
SlGlobList(_map_dimensions);
|
||||
AllocateMap(_map_dim_x, _map_dim_y);
|
||||
}
|
||||
|
||||
enum {
|
||||
MAP_SL_BUF_SIZE = 4096
|
||||
};
|
||||
|
||||
static void Load_MAPT()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAPT()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP1()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP1()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP2()
|
||||
{
|
||||
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE,
|
||||
/* In those versions the m2 was 8 bits */
|
||||
CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
|
||||
);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP2()
|
||||
{
|
||||
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size * sizeof(uint16));
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP3()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP3()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP4()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP4()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP5()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP5()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP6()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
if (CheckSavegameVersion(42)) {
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
/* 1024, otherwise we overflow on 64x64 maps! */
|
||||
SlArray(buf, 1024, SLE_UINT8);
|
||||
for (uint j = 0; j != 1024; j++) {
|
||||
_m[i++].m6 = GB(buf[j], 0, 2);
|
||||
_m[i++].m6 = GB(buf[j], 2, 2);
|
||||
_m[i++].m6 = GB(buf[j], 4, 2);
|
||||
_m[i++].m6 = GB(buf[j], 6, 2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP6()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP7()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP7()
|
||||
{
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _map_chunk_handlers[] = {
|
||||
{ 'MAPS', Save_MAPS, Load_MAPS, CH_RIFF },
|
||||
{ 'MAPT', Save_MAPT, Load_MAPT, CH_RIFF },
|
||||
{ 'MAPO', Save_MAP1, Load_MAP1, CH_RIFF },
|
||||
{ 'MAP2', Save_MAP2, Load_MAP2, CH_RIFF },
|
||||
{ 'M3LO', Save_MAP3, Load_MAP3, CH_RIFF },
|
||||
{ 'M3HI', Save_MAP4, Load_MAP4, CH_RIFF },
|
||||
{ 'MAP5', Save_MAP5, Load_MAP5, CH_RIFF },
|
||||
{ 'MAPE', Save_MAP6, Load_MAP6, CH_RIFF },
|
||||
{ 'MAP7', Save_MAP7, Load_MAP7, CH_RIFF },
|
||||
};
|
@ -0,0 +1,105 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file misc_sl.cpp Saving and loading of things that didn't fit anywhere else */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../date_func.h"
|
||||
#include "../variables.h"
|
||||
#include "../core/random_func.hpp"
|
||||
#include "../openttd.h"
|
||||
#include "../tile_type.h"
|
||||
#include "../zoom_func.h"
|
||||
#include "../vehicle_func.h"
|
||||
#include "../window_gui.h"
|
||||
#include "../window_func.h"
|
||||
#include "../viewport_func.h"
|
||||
#include "../gfx_func.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
extern TileIndex _cur_tileloop_tile;
|
||||
|
||||
/* Keep track of current game position */
|
||||
int _saved_scrollpos_x;
|
||||
int _saved_scrollpos_y;
|
||||
|
||||
void SaveViewportBeforeSaveGame()
|
||||
{
|
||||
const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
|
||||
if (w != NULL) {
|
||||
_saved_scrollpos_x = w->viewport->scrollpos_x;
|
||||
_saved_scrollpos_y = w->viewport->scrollpos_y;
|
||||
_saved_scrollpos_zoom = w->viewport->zoom;
|
||||
}
|
||||
}
|
||||
|
||||
void ResetViewportAfterLoadGame()
|
||||
{
|
||||
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
|
||||
|
||||
w->viewport->scrollpos_x = _saved_scrollpos_x;
|
||||
w->viewport->scrollpos_y = _saved_scrollpos_y;
|
||||
w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
|
||||
w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
|
||||
|
||||
ViewPort *vp = w->viewport;
|
||||
vp->zoom = min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
|
||||
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
|
||||
vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
|
||||
|
||||
DoZoomInOutWindow(ZOOM_NONE, w); // update button status
|
||||
MarkWholeScreenDirty();
|
||||
}
|
||||
|
||||
|
||||
static const SaveLoadGlobVarList _date_desc[] = {
|
||||
SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLEG_CONDVAR(_date, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLEG_VAR(_date_fract, SLE_UINT16),
|
||||
SLEG_VAR(_tick_counter, SLE_UINT16),
|
||||
SLEG_VAR(_vehicle_id_ctr_day, SLE_UINT16),
|
||||
SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8),
|
||||
SLE_CONDNULL(1, 0, 45),
|
||||
SLEG_CONDVAR(_cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLEG_CONDVAR(_cur_tileloop_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLEG_VAR(_disaster_delay, SLE_UINT16),
|
||||
SLEG_VAR(_station_tick_ctr, SLE_UINT16),
|
||||
SLEG_VAR(_random.state[0], SLE_UINT32),
|
||||
SLEG_VAR(_random.state[1], SLE_UINT32),
|
||||
SLEG_CONDVAR(_cur_town_ctr, SLE_FILE_U8 | SLE_VAR_U32, 0, 9),
|
||||
SLEG_CONDVAR(_cur_town_ctr, SLE_UINT32, 10, SL_MAX_VERSION),
|
||||
SLEG_VAR(_cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
|
||||
SLEG_VAR(_next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32),
|
||||
SLEG_VAR(_trees_tick_ctr, SLE_UINT8),
|
||||
SLEG_CONDVAR(_pause_game, SLE_UINT8, 4, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_cur_town_iter, SLE_UINT32, 11, SL_MAX_VERSION),
|
||||
SLEG_END()
|
||||
};
|
||||
|
||||
/* Save load date related variables as well as persistent tick counters
|
||||
* XXX: currently some unrelated stuff is just put here */
|
||||
static void SaveLoad_DATE()
|
||||
{
|
||||
SlGlobList(_date_desc);
|
||||
}
|
||||
|
||||
|
||||
static const SaveLoadGlobVarList _view_desc[] = {
|
||||
SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
|
||||
SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, 6, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
|
||||
SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, 6, SL_MAX_VERSION),
|
||||
SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
|
||||
SLEG_END()
|
||||
};
|
||||
|
||||
static void SaveLoad_VIEW()
|
||||
{
|
||||
SlGlobList(_view_desc);
|
||||
}
|
||||
|
||||
extern const ChunkHandler _misc_chunk_handlers[] = {
|
||||
{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
|
||||
{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF | CH_LAST},
|
||||
};
|
@ -0,0 +1,52 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file newgrf_sl.cpp Code handling saving and loading of newgrf config */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../newgrf_config.h"
|
||||
#include "../core/bitmath_func.hpp"
|
||||
#include "../core/alloc_func.hpp"
|
||||
#include "../gfx_func.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _grfconfig_desc[] = {
|
||||
SLE_STR(GRFConfig, filename, SLE_STR, 0x40),
|
||||
SLE_VAR(GRFConfig, grfid, SLE_UINT32),
|
||||
SLE_ARR(GRFConfig, md5sum, SLE_UINT8, 16),
|
||||
SLE_ARR(GRFConfig, param, SLE_UINT32, 0x80),
|
||||
SLE_VAR(GRFConfig, num_params, SLE_UINT8),
|
||||
SLE_CONDVAR(GRFConfig, windows_paletted, SLE_BOOL, 101, SL_MAX_VERSION),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
|
||||
static void Save_NGRF()
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
|
||||
if (HasBit(c->flags, GCF_STATIC)) continue;
|
||||
SlSetArrayIndex(index++);
|
||||
SlObject(c, _grfconfig_desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Load_NGRF()
|
||||
{
|
||||
ClearGRFConfigList(&_grfconfig);
|
||||
while (SlIterateArray() != -1) {
|
||||
GRFConfig *c = CallocT<GRFConfig>(1);
|
||||
SlObject(c, _grfconfig_desc);
|
||||
if (CheckSavegameVersion(101)) c->windows_paletted = (_use_palette == PAL_WINDOWS);
|
||||
AppendToGRFConfigList(&_grfconfig, c);
|
||||
}
|
||||
|
||||
/* Append static NewGRF configuration */
|
||||
AppendStaticGRFConfigs(&_grfconfig);
|
||||
}
|
||||
|
||||
extern const ChunkHandler _newgrf_chunk_handlers[] = {
|
||||
{ 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
|
||||
};
|
@ -0,0 +1,203 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file order_sl.cpp Code handling saving and loading of orders */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../order_base.h"
|
||||
#include "../core/alloc_func.hpp"
|
||||
#include "../settings_type.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
void Order::ConvertFromOldSavegame()
|
||||
{
|
||||
uint8 old_flags = this->flags;
|
||||
this->flags = 0;
|
||||
|
||||
/* First handle non-stop */
|
||||
if (_settings_client.gui.sg_new_nonstop) {
|
||||
/* OFB_NON_STOP */
|
||||
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_ANY_STATION : ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
|
||||
} else {
|
||||
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
|
||||
}
|
||||
|
||||
switch (this->GetType()) {
|
||||
/* Only a few types need the other savegame conversions. */
|
||||
case OT_GOTO_DEPOT: case OT_GOTO_STATION: case OT_LOADING: break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if (this->GetType() != OT_GOTO_DEPOT) {
|
||||
/* Then the load flags */
|
||||
if ((old_flags & 2) != 0) { // OFB_UNLOAD
|
||||
this->SetLoadType(OLFB_NO_LOAD);
|
||||
} else if ((old_flags & 4) == 0) { // !OFB_FULL_LOAD
|
||||
this->SetLoadType(OLF_LOAD_IF_POSSIBLE);
|
||||
} else {
|
||||
this->SetLoadType(_settings_client.gui.sg_full_load_any ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
|
||||
}
|
||||
|
||||
/* Finally fix the unload flags */
|
||||
if ((old_flags & 1) != 0) { // OFB_TRANSFER
|
||||
this->SetUnloadType(OUFB_TRANSFER);
|
||||
} else if ((old_flags & 2) != 0) { // OFB_UNLOAD
|
||||
this->SetUnloadType(OUFB_UNLOAD);
|
||||
} else {
|
||||
this->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
|
||||
}
|
||||
} else {
|
||||
/* Then the depot action flags */
|
||||
this->SetDepotActionType(((old_flags & 6) == 4) ? ODATFB_HALT : ODATF_SERVICE_ONLY);
|
||||
|
||||
/* Finally fix the depot type flags */
|
||||
uint t = ((old_flags & 6) == 6) ? ODTFB_SERVICE : ODTF_MANUAL;
|
||||
if ((old_flags & 2) != 0) t |= ODTFB_PART_OF_ORDERS;
|
||||
this->SetDepotOrderType((OrderDepotTypeFlags)t);
|
||||
}
|
||||
}
|
||||
|
||||
/** Unpacks a order from savegames with version 4 and lower
|
||||
* @param packed packed order
|
||||
* @return unpacked order
|
||||
*/
|
||||
static Order UnpackVersion4Order(uint16 packed)
|
||||
{
|
||||
return Order(GB(packed, 8, 8) << 16 | GB(packed, 4, 4) << 8 | GB(packed, 0, 4));
|
||||
}
|
||||
|
||||
/** Unpacks a order from savegames made with TTD(Patch)
|
||||
* @param packed packed order
|
||||
* @return unpacked order
|
||||
*/
|
||||
Order UnpackOldOrder(uint16 packed)
|
||||
{
|
||||
Order order = UnpackVersion4Order(packed);
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
* TTD stores invalid orders as OT_NOTHING with non-zero flags/station
|
||||
*/
|
||||
if (!order.IsValid() && packed != 0) order.MakeDummy();
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
const SaveLoad *GetOrderDescription()
|
||||
{
|
||||
static const SaveLoad _order_desc[] = {
|
||||
SLE_VAR(Order, type, SLE_UINT8),
|
||||
SLE_VAR(Order, flags, SLE_UINT8),
|
||||
SLE_VAR(Order, dest, SLE_UINT16),
|
||||
SLE_REF(Order, next, REF_ORDER),
|
||||
SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, 36, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Order, refit_subtype, SLE_UINT8, 36, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Order, wait_time, SLE_UINT16, 67, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Order, travel_time, SLE_UINT16, 67, SL_MAX_VERSION),
|
||||
|
||||
/* Leftover from the minor savegame version stuff
|
||||
* We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
|
||||
SLE_CONDNULL(10, 5, 35),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
return _order_desc;
|
||||
}
|
||||
|
||||
static void Save_ORDR()
|
||||
{
|
||||
Order *order;
|
||||
|
||||
FOR_ALL_ORDERS(order) {
|
||||
SlSetArrayIndex(order->index);
|
||||
SlObject(order, GetOrderDescription());
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_ORDR()
|
||||
{
|
||||
if (CheckSavegameVersionOldStyle(5, 2)) {
|
||||
/* Version older than 5.2 did not have a ->next pointer. Convert them
|
||||
(in the old days, the orderlist was 5000 items big) */
|
||||
size_t len = SlGetFieldLength();
|
||||
uint i;
|
||||
|
||||
if (CheckSavegameVersion(5)) {
|
||||
/* Pre-version 5 had an other layout for orders
|
||||
(uint16 instead of uint32) */
|
||||
len /= sizeof(uint16);
|
||||
uint16 *orders = MallocT<uint16>(len + 1);
|
||||
|
||||
SlArray(orders, len, SLE_UINT16);
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
Order *order = new (i) Order();
|
||||
order->AssignOrder(UnpackVersion4Order(orders[i]));
|
||||
}
|
||||
|
||||
free(orders);
|
||||
} else if (CheckSavegameVersionOldStyle(5, 2)) {
|
||||
len /= sizeof(uint16);
|
||||
uint16 *orders = MallocT<uint16>(len + 1);
|
||||
|
||||
SlArray(orders, len, SLE_UINT32);
|
||||
|
||||
for (i = 0; i < len; ++i) {
|
||||
new (i) Order(orders[i]);
|
||||
}
|
||||
|
||||
free(orders);
|
||||
}
|
||||
|
||||
/* Update all the next pointer */
|
||||
for (i = 1; i < len; ++i) {
|
||||
/* The orders were built like this:
|
||||
* While the order is valid, set the previous will get it's next pointer set
|
||||
* We start with index 1 because no order will have the first in it's next pointer */
|
||||
if (GetOrder(i)->IsValid())
|
||||
GetOrder(i - 1)->next = GetOrder(i);
|
||||
}
|
||||
} else {
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Order *order = new (index) Order();
|
||||
SlObject(order, GetOrderDescription());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SaveLoad *GetOrderListDescription()
|
||||
{
|
||||
static const SaveLoad _orderlist_desc[] = {
|
||||
SLE_REF(OrderList, first, REF_ORDER),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
return _orderlist_desc;
|
||||
}
|
||||
|
||||
static void Save_ORDL()
|
||||
{
|
||||
OrderList *list;
|
||||
|
||||
FOR_ALL_ORDER_LISTS(list) {
|
||||
SlSetArrayIndex(list->index);
|
||||
SlObject(list, GetOrderListDescription());
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_ORDL()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
OrderList *list = new (index) OrderList();
|
||||
SlObject(list, GetOrderListDescription());
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _order_chunk_handlers[] = {
|
||||
{ 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY},
|
||||
{ 'ORDL', Save_ORDL, Load_ORDL, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,40 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file saveload_internal.h Declaration of functions used in more save/load files */
|
||||
|
||||
#ifndef SAVELOAD_INTERNAL_H
|
||||
#define SAVELOAD_INTERNAL_H
|
||||
|
||||
#include "../strings_type.h"
|
||||
#include "../company_manager_face.h"
|
||||
#include "../order_base.h"
|
||||
|
||||
void InitializeOldNames();
|
||||
StringID RemapOldStringID(StringID s);
|
||||
char *CopyFromOldName(StringID id);
|
||||
void ResetOldNames();
|
||||
|
||||
void FixOldWaypoints();
|
||||
|
||||
void AfterLoadWaypoints();
|
||||
void AfterLoadVehicles(bool part_of_load);
|
||||
void AfterLoadStations();
|
||||
void AfterLoadTown();
|
||||
void UpdateHousesAndTowns();
|
||||
|
||||
void UpdateOldAircraft();
|
||||
|
||||
void SaveViewportBeforeSaveGame();
|
||||
void ResetViewportAfterLoadGame();
|
||||
|
||||
void ConvertOldMultiheadToNew();
|
||||
void ConnectMultiheadedTrains();
|
||||
|
||||
extern int32 _saved_scrollpos_x;
|
||||
extern int32 _saved_scrollpos_y;
|
||||
|
||||
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face);
|
||||
|
||||
Order UnpackOldOrder(uint16 packed);
|
||||
|
||||
#endif /* SAVELOAD_INTERNAL_H */
|
@ -0,0 +1,49 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file signs_sl.cpp Code handling saving and loading of economy data */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../strings_func.h"
|
||||
#include "../company_func.h"
|
||||
#include "../signs_base.h"
|
||||
#include "../signs_func.h"
|
||||
|
||||
#include "saveload_internal.h"
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _sign_desc[] = {
|
||||
SLE_CONDVAR(Sign, name, SLE_NAME, 0, 83),
|
||||
SLE_CONDSTR(Sign, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
|
||||
SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
|
||||
SLE_CONDVAR(Sign, x, SLE_INT32, 5, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Sign, y, SLE_INT32, 5, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Sign, owner, SLE_UINT8, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(Sign, z, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
/** Save all signs */
|
||||
static void Save_SIGN()
|
||||
{
|
||||
Sign *si;
|
||||
|
||||
FOR_ALL_SIGNS(si) {
|
||||
SlSetArrayIndex(si->index);
|
||||
SlObject(si, _sign_desc);
|
||||
}
|
||||
}
|
||||
|
||||
/** Load all signs */
|
||||
static void Load_SIGN()
|
||||
{
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Sign *si = new (index) Sign();
|
||||
SlObject(si, _sign_desc);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _sign_chunk_handlers[] = {
|
||||
{ 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,227 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file station_sl.cpp Code handling saving and loading of economy data */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../station_base.h"
|
||||
#include "../core/bitmath_func.hpp"
|
||||
#include "../core/alloc_func.hpp"
|
||||
#include "../variables.h"
|
||||
#include "../newgrf_station.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
|
||||
void AfterLoadStations()
|
||||
{
|
||||
/* Update the speclists of all stations to point to the currently loaded custom stations. */
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
for (uint i = 0; i < st->num_specs; i++) {
|
||||
if (st->speclist[i].grfid == 0) continue;
|
||||
|
||||
st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx);
|
||||
}
|
||||
|
||||
for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
|
||||
|
||||
StationUpdateAnimTriggers(st);
|
||||
}
|
||||
}
|
||||
|
||||
static const SaveLoad _roadstop_desc[] = {
|
||||
SLE_VAR(RoadStop, xy, SLE_UINT32),
|
||||
SLE_CONDNULL(1, 0, 44),
|
||||
SLE_VAR(RoadStop, status, SLE_UINT8),
|
||||
/* Index was saved in some versions, but this is not needed */
|
||||
SLE_CONDNULL(4, 0, 8),
|
||||
SLE_CONDNULL(2, 0, 44),
|
||||
SLE_CONDNULL(1, 0, 25),
|
||||
|
||||
SLE_REF(RoadStop, next, REF_ROADSTOPS),
|
||||
SLE_CONDNULL(2, 0, 44),
|
||||
|
||||
SLE_CONDNULL(4, 0, 24),
|
||||
SLE_CONDNULL(1, 25, 25),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _station_desc[] = {
|
||||
SLE_CONDVAR(Station, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Station, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(4, 0, 5), ///< bus/lorry tile
|
||||
SLE_CONDVAR(Station, train_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Station, train_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Station, airport_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Station, airport_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Station, dock_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Station, dock_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_REF(Station, town, REF_TOWN),
|
||||
SLE_VAR(Station, trainst_w, SLE_UINT8),
|
||||
SLE_CONDVAR(Station, trainst_h, SLE_UINT8, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDNULL(1, 0, 3), ///< alpha_order
|
||||
|
||||
SLE_VAR(Station, string_id, SLE_STRINGID),
|
||||
SLE_CONDSTR(Station, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Station, indtype, SLE_UINT8, 103, SL_MAX_VERSION),
|
||||
SLE_VAR(Station, had_vehicle_of_type, SLE_UINT16),
|
||||
|
||||
SLE_VAR(Station, time_since_load, SLE_UINT8),
|
||||
SLE_VAR(Station, time_since_unload, SLE_UINT8),
|
||||
SLE_VAR(Station, delete_ctr, SLE_UINT8),
|
||||
SLE_VAR(Station, owner, SLE_UINT8),
|
||||
SLE_VAR(Station, facilities, SLE_UINT8),
|
||||
SLE_VAR(Station, airport_type, SLE_UINT8),
|
||||
|
||||
SLE_CONDNULL(2, 0, 5), ///< Truck/bus stop status
|
||||
SLE_CONDNULL(1, 0, 4), ///< Blocked months
|
||||
|
||||
SLE_CONDVAR(Station, airport_flags, SLE_VAR_U64 | SLE_FILE_U16, 0, 2),
|
||||
SLE_CONDVAR(Station, airport_flags, SLE_VAR_U64 | SLE_FILE_U32, 3, 45),
|
||||
SLE_CONDVAR(Station, airport_flags, SLE_UINT64, 46, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDNULL(2, 0, 25), ///< last-vehicle
|
||||
SLE_CONDVAR(Station, last_vehicle_type, SLE_UINT8, 26, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDNULL(2, 3, 25), ///< custom station class and id
|
||||
SLE_CONDVAR(Station, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
|
||||
SLE_CONDVAR(Station, build_date, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDREF(Station, bus_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
|
||||
SLE_CONDREF(Station, truck_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
|
||||
|
||||
/* Used by newstations for graphic variations */
|
||||
SLE_CONDVAR(Station, random_bits, SLE_UINT16, 27, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, 27, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Station, num_specs, SLE_UINT8, 27, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDLST(Station, loading_vehicles, REF_VEHICLE, 57, SL_MAX_VERSION),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 32 bytes) */
|
||||
SLE_CONDNULL(32, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static uint16 _waiting_acceptance;
|
||||
static uint16 _cargo_source;
|
||||
static uint32 _cargo_source_xy;
|
||||
static uint16 _cargo_days;
|
||||
static Money _cargo_feeder_share;
|
||||
|
||||
static const SaveLoad _station_speclist_desc[] = {
|
||||
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, 27, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, 27, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
|
||||
void SaveLoad_STNS(Station *st)
|
||||
{
|
||||
static const SaveLoad _goods_desc[] = {
|
||||
SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, 0, 67),
|
||||
SLE_CONDVAR(GoodsEntry, acceptance_pickup, SLE_UINT8, 68, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(2, 51, 67),
|
||||
SLE_VAR(GoodsEntry, days_since_pickup, SLE_UINT8),
|
||||
SLE_VAR(GoodsEntry, rating, SLE_UINT8),
|
||||
SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
|
||||
SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
|
||||
SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
|
||||
SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
|
||||
SLE_VAR(GoodsEntry, last_speed, SLE_UINT8),
|
||||
SLE_VAR(GoodsEntry, last_age, SLE_UINT8),
|
||||
SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
|
||||
SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
|
||||
SLE_CONDLST(GoodsEntry, cargo.packets, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
|
||||
SlObject(st, _station_desc);
|
||||
|
||||
_waiting_acceptance = 0;
|
||||
|
||||
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
|
||||
for (CargoID i = 0; i < num_cargo; i++) {
|
||||
GoodsEntry *ge = &st->goods[i];
|
||||
SlObject(ge, _goods_desc);
|
||||
if (CheckSavegameVersion(68)) {
|
||||
SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
|
||||
if (GB(_waiting_acceptance, 0, 12) != 0) {
|
||||
/* Don't construct the packet with station here, because that'll fail with old savegames */
|
||||
CargoPacket *cp = new CargoPacket();
|
||||
/* In old versions, enroute_from used 0xFF as INVALID_STATION */
|
||||
cp->source = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
|
||||
cp->count = GB(_waiting_acceptance, 0, 12);
|
||||
cp->days_in_transit = _cargo_days;
|
||||
cp->feeder_share = _cargo_feeder_share;
|
||||
cp->source_xy = _cargo_source_xy;
|
||||
cp->days_in_transit = _cargo_days;
|
||||
cp->feeder_share = _cargo_feeder_share;
|
||||
SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
|
||||
ge->cargo.Append(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (st->num_specs != 0) {
|
||||
/* Allocate speclist memory when loading a game */
|
||||
if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
|
||||
for (uint i = 0; i < st->num_specs; i++) {
|
||||
SlObject(&st->speclist[i], _station_speclist_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_STNS()
|
||||
{
|
||||
Station *st;
|
||||
/* Write the stations */
|
||||
FOR_ALL_STATIONS(st) {
|
||||
SlSetArrayIndex(st->index);
|
||||
SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_STNS()
|
||||
{
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Station *st = new (index) Station();
|
||||
|
||||
SaveLoad_STNS(st);
|
||||
}
|
||||
|
||||
/* This is to ensure all pointers are within the limits of _stations_size */
|
||||
if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
|
||||
}
|
||||
|
||||
static void Save_ROADSTOP()
|
||||
{
|
||||
RoadStop *rs;
|
||||
|
||||
FOR_ALL_ROADSTOPS(rs) {
|
||||
SlSetArrayIndex(rs->index);
|
||||
SlObject(rs, _roadstop_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_ROADSTOP()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
RoadStop *rs = new (index) RoadStop(INVALID_TILE);
|
||||
|
||||
SlObject(rs, _roadstop_desc);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _station_chunk_handlers[] = {
|
||||
{ 'STNS', Save_STNS, Load_STNS, CH_ARRAY },
|
||||
{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,126 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file strings_sl.cpp Code handling saving and loading of strings */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../strings_type.h"
|
||||
#include "../core/math_func.hpp"
|
||||
#include "../core/bitmath_func.hpp"
|
||||
#include "../core/alloc_func.hpp"
|
||||
#include "../string_func.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
/**
|
||||
* Remap a string ID from the old format to the new format
|
||||
* @param s StringID that requires remapping
|
||||
* @return translated ID
|
||||
*/
|
||||
StringID RemapOldStringID(StringID s)
|
||||
{
|
||||
switch (s) {
|
||||
case 0x0006: return STR_SV_EMPTY;
|
||||
case 0x7000: return STR_SV_UNNAMED;
|
||||
case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
|
||||
case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
|
||||
case 0x8864: return STR_SV_TRAIN_NAME;
|
||||
case 0x902B: return STR_SV_ROADVEH_NAME;
|
||||
case 0x9830: return STR_SV_SHIP_NAME;
|
||||
case 0xA02F: return STR_SV_AIRCRAFT_NAME;
|
||||
|
||||
default:
|
||||
if (IsInsideMM(s, 0x300F, 0x3030)) {
|
||||
return s - 0x300F + STR_SV_STNAME;
|
||||
} else {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Location to load the old names to. */
|
||||
char *_old_name_array = NULL;
|
||||
|
||||
/**
|
||||
* Copy and convert old custom names to UTF-8.
|
||||
* They were all stored in a 512 by 32 long string array and are
|
||||
* now stored with stations, waypoints and other places with names.
|
||||
* @param id the StringID of the custom name to clone.
|
||||
* @return the clones custom name.
|
||||
*/
|
||||
char *CopyFromOldName(StringID id)
|
||||
{
|
||||
/* Is this name an (old) custom name? */
|
||||
if (GB(id, 11, 5) != 15) return NULL;
|
||||
|
||||
if (CheckSavegameVersion(37)) {
|
||||
/* Old names were 32 characters long, so 128 characters should be
|
||||
* plenty to allow for expansion when converted to UTF-8. */
|
||||
char tmp[128];
|
||||
const char *strfrom = &_old_name_array[32 * GB(id, 0, 9)];
|
||||
char *strto = tmp;
|
||||
|
||||
for (; *strfrom != '\0'; strfrom++) {
|
||||
WChar c = (byte)*strfrom;
|
||||
|
||||
/* Map from non-ISO8859-15 characters to UTF-8. */
|
||||
switch (c) {
|
||||
case 0xA4: c = 0x20AC; break; // Euro
|
||||
case 0xA6: c = 0x0160; break; // S with caron
|
||||
case 0xA8: c = 0x0161; break; // s with caron
|
||||
case 0xB4: c = 0x017D; break; // Z with caron
|
||||
case 0xB8: c = 0x017E; break; // z with caron
|
||||
case 0xBC: c = 0x0152; break; // OE ligature
|
||||
case 0xBD: c = 0x0153; break; // oe ligature
|
||||
case 0xBE: c = 0x0178; break; // Y with diaresis
|
||||
default: break;
|
||||
}
|
||||
|
||||
/* Check character will fit into our buffer. */
|
||||
if (strto + Utf8CharLen(c) > lastof(tmp)) break;
|
||||
|
||||
strto += Utf8Encode(strto, c);
|
||||
}
|
||||
|
||||
/* Terminate the new string and copy it back to the name array */
|
||||
*strto = '\0';
|
||||
|
||||
return strdup(tmp);
|
||||
} else {
|
||||
/* Name will already be in UTF-8. */
|
||||
return strdup(&_old_name_array[32 * GB(id, 0, 9)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the memory of the old names array.
|
||||
* Should be called once the old names have all been converted.
|
||||
*/
|
||||
void ResetOldNames()
|
||||
{
|
||||
free(_old_name_array);
|
||||
_old_name_array = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the old names table memory.
|
||||
*/
|
||||
void InitializeOldNames()
|
||||
{
|
||||
free(_old_name_array);
|
||||
_old_name_array = CallocT<char>(512 * 32);
|
||||
}
|
||||
|
||||
static void Load_NAME()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
SlArray(&_old_name_array[32 * index], SlGetFieldLength(), SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _name_chunk_handlers[] = {
|
||||
{ 'NAME', NULL, Load_NAME, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,43 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file subsidy_sl.cpp Code handling saving and loading of subsidies */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../economy_func.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
static const SaveLoad _subsidies_desc[] = {
|
||||
SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
|
||||
SLE_VAR(Subsidy, age, SLE_UINT8),
|
||||
SLE_CONDVAR(Subsidy, from, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
|
||||
SLE_CONDVAR(Subsidy, from, SLE_UINT16, 5, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Subsidy, to, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
|
||||
SLE_CONDVAR(Subsidy, to, SLE_UINT16, 5, SL_MAX_VERSION),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
void Save_SUBS()
|
||||
{
|
||||
int i;
|
||||
Subsidy *s;
|
||||
|
||||
for (i = 0; i != lengthof(_subsidies); i++) {
|
||||
s = &_subsidies[i];
|
||||
if (s->cargo_type != CT_INVALID) {
|
||||
SlSetArrayIndex(i);
|
||||
SlObject(s, _subsidies_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load_SUBS()
|
||||
{
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1)
|
||||
SlObject(&_subsidies[index], _subsidies_desc);
|
||||
}
|
||||
|
||||
extern const ChunkHandler _subsidy_chunk_handlers[] = {
|
||||
{ 'SUBS', Save_SUBS, Load_SUBS, CH_ARRAY},
|
||||
};
|
@ -0,0 +1,210 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file town_sl.cpp Code handling saving and loading of towns and houses */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../town.h"
|
||||
#include "../newgrf_house.h"
|
||||
#include "../newgrf_commons.h"
|
||||
#include "../variables.h"
|
||||
#include "../tile_map.h"
|
||||
#include "../town_map.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
extern uint _total_towns;
|
||||
|
||||
/**
|
||||
* Check and update town and house values.
|
||||
*
|
||||
* Checked are the HouseIDs. Updated are the
|
||||
* town population the number of houses per
|
||||
* town, the town radius and the max passengers
|
||||
* of the town.
|
||||
*/
|
||||
void UpdateHousesAndTowns()
|
||||
{
|
||||
Town *town;
|
||||
InitializeBuildingCounts();
|
||||
|
||||
/* Reset town population and num_houses */
|
||||
FOR_ALL_TOWNS(town) {
|
||||
town->population = 0;
|
||||
town->num_houses = 0;
|
||||
}
|
||||
|
||||
for (TileIndex t = 0; t < MapSize(); t++) {
|
||||
HouseID house_id;
|
||||
|
||||
if (!IsTileType(t, MP_HOUSE)) continue;
|
||||
|
||||
house_id = GetHouseType(t);
|
||||
if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
|
||||
/* The specs for this type of house are not available any more, so
|
||||
* replace it with the substitute original house type. */
|
||||
house_id = _house_mngr.GetSubstituteID(house_id);
|
||||
SetHouseType(t, house_id);
|
||||
}
|
||||
|
||||
town = GetTownByTile(t);
|
||||
IncreaseBuildingCount(town, house_id);
|
||||
if (IsHouseCompleted(t)) town->population += GetHouseSpecs(house_id)->population;
|
||||
|
||||
/* Increase the number of houses for every house, but only once. */
|
||||
if (GetHouseNorthPart(house_id) == 0) town->num_houses++;
|
||||
}
|
||||
|
||||
/* Update the population and num_house dependant values */
|
||||
FOR_ALL_TOWNS(town) {
|
||||
UpdateTownRadius(town);
|
||||
UpdateTownMaxPass(town);
|
||||
}
|
||||
}
|
||||
|
||||
/** Save and load of towns. */
|
||||
static const SaveLoad _town_desc[] = {
|
||||
SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDNULL(2, 0, 2), ///< population, no longer in use
|
||||
SLE_CONDNULL(4, 3, 84), ///< population, no longer in use
|
||||
SLE_CONDNULL(2, 0, 91), ///< num_houses, no longer in use
|
||||
|
||||
SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, 66, SL_MAX_VERSION),
|
||||
SLE_VAR(Town, townnametype, SLE_UINT16),
|
||||
SLE_VAR(Town, townnameparts, SLE_UINT32),
|
||||
SLE_CONDSTR(Town, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Town, flags12, SLE_UINT8),
|
||||
SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
|
||||
SLE_CONDVAR(Town, statues, SLE_UINT16, 104, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDNULL(1, 0, 1), ///< sort_index, no longer in use
|
||||
|
||||
SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
|
||||
SLE_CONDVAR(Town, have_ratings, SLE_UINT16, 104, SL_MAX_VERSION),
|
||||
SLE_CONDARR(Town, ratings, SLE_INT16, 8, 0, 103),
|
||||
SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, 104, SL_MAX_VERSION),
|
||||
/* failed bribe attempts are stored since savegame format 4 */
|
||||
SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4, 103),
|
||||
SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, 104, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Town, max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
SLE_CONDVAR(Town, max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
SLE_CONDVAR(Town, new_max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
SLE_CONDVAR(Town, new_max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
SLE_CONDVAR(Town, act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
SLE_CONDVAR(Town, act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
SLE_CONDVAR(Town, new_act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
SLE_CONDVAR(Town, new_act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
|
||||
|
||||
SLE_CONDVAR(Town, max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, new_max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, new_max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, new_act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, new_act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Town, pct_pass_transported, SLE_UINT8),
|
||||
SLE_VAR(Town, pct_mail_transported, SLE_UINT8),
|
||||
|
||||
SLE_VAR(Town, act_food, SLE_UINT16),
|
||||
SLE_VAR(Town, act_water, SLE_UINT16),
|
||||
SLE_VAR(Town, new_act_food, SLE_UINT16),
|
||||
SLE_VAR(Town, new_act_water, SLE_UINT16),
|
||||
|
||||
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT8, 0, 53),
|
||||
SLE_CONDVAR(Town, grow_counter, SLE_UINT8, 0, 53),
|
||||
SLE_CONDVAR(Town, growth_rate, SLE_UINT8, 0, 53),
|
||||
|
||||
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, 54, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, grow_counter, SLE_UINT16, 54, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, growth_rate, SLE_INT16, 54, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
|
||||
SLE_VAR(Town, road_build_months, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(Town, exclusivity, SLE_UINT8, 2, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Town, exclusive_counter, SLE_UINT8, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Town, larger_town, SLE_BOOL, 56, SL_MAX_VERSION),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 30 bytes) */
|
||||
SLE_CONDNULL(30, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
/* Save and load the mapping between the house id on the map, and the grf file
|
||||
* it came from. */
|
||||
static const SaveLoad _house_id_mapping_desc[] = {
|
||||
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
|
||||
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
|
||||
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_HOUSEIDS()
|
||||
{
|
||||
uint j = _house_mngr.GetMaxMapping();
|
||||
|
||||
for (uint i = 0; i < j; i++) {
|
||||
SlSetArrayIndex(i);
|
||||
SlObject(&_house_mngr.mapping_ID[i], _house_id_mapping_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_HOUSEIDS()
|
||||
{
|
||||
int index;
|
||||
|
||||
_house_mngr.ResetMapping();
|
||||
uint max_id = _house_mngr.GetMaxMapping();
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
if ((uint)index >= max_id) break;
|
||||
SlObject(&_house_mngr.mapping_ID[index], _house_id_mapping_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_TOWN()
|
||||
{
|
||||
Town *t;
|
||||
|
||||
FOR_ALL_TOWNS(t) {
|
||||
SlSetArrayIndex(t->index);
|
||||
SlObject(t, _town_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_TOWN()
|
||||
{
|
||||
int index;
|
||||
|
||||
_total_towns = 0;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Town *t = new (index) Town();
|
||||
SlObject(t, _town_desc);
|
||||
|
||||
_total_towns++;
|
||||
}
|
||||
|
||||
/* This is to ensure all pointers are within the limits of
|
||||
* the size of the TownPool */
|
||||
if (_cur_town_ctr > GetMaxTownIndex())
|
||||
_cur_town_ctr = 0;
|
||||
}
|
||||
|
||||
void AfterLoadTown()
|
||||
{
|
||||
Town *t;
|
||||
FOR_ALL_TOWNS(t) t->InitializeLayout();
|
||||
}
|
||||
|
||||
extern const ChunkHandler _town_chunk_handlers[] = {
|
||||
{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
|
||||
{ 'CITY', Save_TOWN, Load_TOWN, CH_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,670 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file vehicle_sl.cpp Code handling saving and loading of vehicles */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../vehicle_base.h"
|
||||
#include "../vehicle_func.h"
|
||||
#include "../train.h"
|
||||
#include "../roadveh.h"
|
||||
#include "../ship.h"
|
||||
#include "../aircraft.h"
|
||||
#include "../effectvehicle_base.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
/*
|
||||
* Link front and rear multiheaded engines to each other
|
||||
* This is done when loading a savegame
|
||||
*/
|
||||
void ConnectMultiheadedTrains()
|
||||
{
|
||||
Vehicle *v;
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type == VEH_TRAIN) {
|
||||
v->u.rail.other_multiheaded_part = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
|
||||
/* Two ways to associate multiheaded parts to each other:
|
||||
* sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>..
|
||||
* bracket-matching: Free vehicle chains shall be arranged to look like ..<..<..>..<..>..>..
|
||||
*
|
||||
* Note: Old savegames might contain chains which do not comply with these rules, e.g.
|
||||
* - the front and read parts have invalid orders
|
||||
* - different engine types might be combined
|
||||
* - there might be different amounts of front and rear parts.
|
||||
*
|
||||
* Note: The multiheaded parts need to be matched exactly like they are matched on the server, else desyncs will occur.
|
||||
* This is why two matching strategies are needed.
|
||||
*/
|
||||
|
||||
bool sequential_matching = IsFrontEngine(v);
|
||||
|
||||
for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) {
|
||||
if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
|
||||
|
||||
if (IsMultiheaded(u)) {
|
||||
if (!IsTrainEngine(u)) {
|
||||
/* we got a rear car without a front car. We will convert it to a front one */
|
||||
SetTrainEngine(u);
|
||||
u->spritenum--;
|
||||
}
|
||||
|
||||
/* Find a matching back part */
|
||||
EngineID eid = u->engine_type;
|
||||
Vehicle *w;
|
||||
if (sequential_matching) {
|
||||
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
|
||||
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
|
||||
|
||||
/* we found a car to partner with this engine. Now we will make sure it face the right way */
|
||||
if (IsTrainEngine(w)) {
|
||||
ClearTrainEngine(w);
|
||||
w->spritenum++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
uint stack_pos = 0;
|
||||
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
|
||||
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
|
||||
|
||||
if (IsTrainEngine(w)) {
|
||||
stack_pos++;
|
||||
} else {
|
||||
if (stack_pos == 0) break;
|
||||
stack_pos--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (w != NULL) {
|
||||
w->u.rail.other_multiheaded_part = u;
|
||||
u->u.rail.other_multiheaded_part = w;
|
||||
} else {
|
||||
/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
|
||||
ClearMultiheaded(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts all trains to the new subtype format introduced in savegame 16.2
|
||||
* It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
|
||||
*/
|
||||
void ConvertOldMultiheadToNew()
|
||||
{
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type == VEH_TRAIN) {
|
||||
SetBit(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
|
||||
}
|
||||
}
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type == VEH_TRAIN) {
|
||||
if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||
const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
|
||||
|
||||
ClrBit(u->subtype, 7);
|
||||
switch (u->subtype) {
|
||||
case 0: /* TS_Front_Engine */
|
||||
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
|
||||
SetFrontEngine(u);
|
||||
SetTrainEngine(u);
|
||||
break;
|
||||
|
||||
case 1: /* TS_Artic_Part */
|
||||
u->subtype = 0;
|
||||
SetArticulatedPart(u);
|
||||
break;
|
||||
|
||||
case 2: /* TS_Not_First */
|
||||
u->subtype = 0;
|
||||
if (rvi->railveh_type == RAILVEH_WAGON) {
|
||||
// normal wagon
|
||||
SetTrainWagon(u);
|
||||
break;
|
||||
}
|
||||
if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
|
||||
// rear end of a multiheaded engine
|
||||
SetMultiheaded(u);
|
||||
break;
|
||||
}
|
||||
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
|
||||
SetTrainEngine(u);
|
||||
break;
|
||||
|
||||
case 4: /* TS_Free_Car */
|
||||
u->subtype = 0;
|
||||
SetTrainWagon(u);
|
||||
SetFreeWagon(u);
|
||||
break;
|
||||
default: NOT_REACHED(); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** need to be called to load aircraft from old version */
|
||||
void UpdateOldAircraft()
|
||||
{
|
||||
/* set airport_flags to 0 for all airports just to be sure */
|
||||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
st->airport_flags = 0; // reset airport
|
||||
}
|
||||
|
||||
Vehicle *v_oldstyle;
|
||||
FOR_ALL_VEHICLES(v_oldstyle) {
|
||||
/* airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor)
|
||||
* skip those */
|
||||
if (v_oldstyle->type == VEH_AIRCRAFT && IsNormalAircraft(v_oldstyle)) {
|
||||
/* airplane in terminal stopped doesn't hurt anyone, so goto next */
|
||||
if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) {
|
||||
v_oldstyle->u.air.state = HANGAR;
|
||||
continue;
|
||||
}
|
||||
|
||||
AircraftLeaveHangar(v_oldstyle); // make airplane visible if it was in a depot for example
|
||||
v_oldstyle->vehstatus &= ~VS_STOPPED; // make airplane moving
|
||||
v_oldstyle->u.air.state = FLYING;
|
||||
AircraftNextAirportPos_and_Order(v_oldstyle); // move it to the entry point of the airport
|
||||
GetNewVehiclePosResult gp = GetNewVehiclePos(v_oldstyle);
|
||||
v_oldstyle->tile = 0; // aircraft in air is tile=0
|
||||
|
||||
/* correct speed of helicopter-rotors */
|
||||
if (v_oldstyle->subtype == AIR_HELICOPTER) v_oldstyle->Next()->Next()->cur_speed = 32;
|
||||
|
||||
/* set new position x,y,z */
|
||||
SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Called after load to update coordinates */
|
||||
void AfterLoadVehicles(bool part_of_load)
|
||||
{
|
||||
Vehicle *v;
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
/* Reinstate the previous pointer */
|
||||
if (v->Next() != NULL) v->Next()->previous = v;
|
||||
if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
|
||||
|
||||
v->UpdateDeltaXY(v->direction);
|
||||
|
||||
if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
|
||||
v->first = NULL;
|
||||
if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
|
||||
if (v->type == VEH_ROAD) v->u.road.first_engine = INVALID_ENGINE;
|
||||
|
||||
v->cargo.InvalidateCache();
|
||||
}
|
||||
|
||||
/* AfterLoadVehicles may also be called in case of NewGRF reload, in this
|
||||
* case we may not convert orders again. */
|
||||
if (part_of_load) {
|
||||
/* Create shared vehicle chain for very old games (pre 5,2) and create
|
||||
* OrderList from shared vehicle chains. For this to work correctly, the
|
||||
* following conditions must be fulfilled:
|
||||
* a) both next_shared and previous_shared are not set for pre 5,2 games
|
||||
* b) both next_shared and previous_shared are set for later games
|
||||
*/
|
||||
std::map<Order*, OrderList*> mapping;
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->orders.old != NULL) {
|
||||
if (CheckSavegameVersion(105)) { // Pre-105 didn't save an OrderList
|
||||
if (mapping[v->orders.old] == NULL) {
|
||||
/* This adds the whole shared vehicle chain for case b */
|
||||
v->orders.list = mapping[v->orders.old] = new OrderList(v->orders.old, v);
|
||||
} else {
|
||||
v->orders.list = mapping[v->orders.old];
|
||||
/* For old games (case a) we must create the shared vehicle chain */
|
||||
if (CheckSavegameVersionOldStyle(5, 2)) {
|
||||
v->AddToShared(v->orders.list->GetFirstSharedVehicle());
|
||||
}
|
||||
}
|
||||
} else { // OrderList was saved as such, only recalculate not saved values
|
||||
if (v->PreviousShared() == NULL) {
|
||||
new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
/* Fill the first pointers */
|
||||
if (v->Previous() == NULL) {
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||
u->first = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
assert(v->first != NULL);
|
||||
|
||||
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
|
||||
if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed; // update displayed train speed
|
||||
TrainConsistChanged(v, false);
|
||||
} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
|
||||
RoadVehUpdateCache(v);
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop non-front engines */
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type == VEH_TRAIN && IsTrainEngine(v) && !IsFrontEngine(v)) v->vehstatus |= VS_STOPPED;
|
||||
}
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
switch (v->type) {
|
||||
case VEH_ROAD:
|
||||
v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
|
||||
v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
|
||||
/* FALL THROUGH */
|
||||
case VEH_TRAIN:
|
||||
case VEH_SHIP:
|
||||
v->cur_image = v->GetImage(v->direction);
|
||||
break;
|
||||
|
||||
case VEH_AIRCRAFT:
|
||||
if (IsNormalAircraft(v)) {
|
||||
v->cur_image = v->GetImage(v->direction);
|
||||
|
||||
/* The plane's shadow will have the same image as the plane */
|
||||
Vehicle *shadow = v->Next();
|
||||
shadow->cur_image = v->cur_image;
|
||||
|
||||
/* In the case of a helicopter we will update the rotor sprites */
|
||||
if (v->subtype == AIR_HELICOPTER) {
|
||||
Vehicle *rotor = shadow->Next();
|
||||
rotor->cur_image = GetRotorImage(v);
|
||||
}
|
||||
|
||||
UpdateAircraftCache(v);
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
v->left_coord = INVALID_COORD;
|
||||
VehiclePositionChanged(v);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8 _cargo_days;
|
||||
static uint16 _cargo_source;
|
||||
static uint32 _cargo_source_xy;
|
||||
static uint16 _cargo_count;
|
||||
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 */
|
||||
static const SaveLoad _common_veh_desc[] = {
|
||||
SLE_VAR(Vehicle, subtype, SLE_UINT8),
|
||||
|
||||
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
|
||||
SLE_CONDVAR(Vehicle, name, SLE_NAME, 0, 83),
|
||||
SLE_CONDSTR(Vehicle, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, 0, 7),
|
||||
SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, 8, SL_MAX_VERSION),
|
||||
SLE_VAR(Vehicle, owner, SLE_UINT8),
|
||||
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, direction, SLE_UINT8),
|
||||
|
||||
SLE_CONDNULL(2, 0, 57),
|
||||
SLE_VAR(Vehicle, spritenum, SLE_UINT8),
|
||||
SLE_CONDNULL(5, 0, 57),
|
||||
SLE_VAR(Vehicle, engine_type, SLE_UINT16),
|
||||
|
||||
SLE_VAR(Vehicle, max_speed, SLE_UINT16),
|
||||
SLE_VAR(Vehicle, cur_speed, SLE_UINT16),
|
||||
SLE_VAR(Vehicle, subspeed, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, acceleration, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, progress, SLE_UINT8),
|
||||
|
||||
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
|
||||
SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
|
||||
SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, 5, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Vehicle, cargo_type, SLE_UINT8),
|
||||
SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, 35, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
|
||||
SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
|
||||
SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
|
||||
SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
|
||||
SLE_VAR(Vehicle, cargo_cap, SLE_UINT16),
|
||||
SLEG_CONDVAR( _cargo_count, SLE_UINT16, 0, 67),
|
||||
SLE_CONDLST(Vehicle, cargo, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Vehicle, day_counter, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
|
||||
SLE_CONDVAR(Vehicle, running_ticks, SLE_UINT8, 88, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Vehicle, cur_order_index, SLE_UINT8),
|
||||
/* num_orders is now part of OrderList and is not saved but counted */
|
||||
SLE_CONDNULL(1, 0, 104),
|
||||
|
||||
/* 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(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(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(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),
|
||||
|
||||
/* Timetable in current order */
|
||||
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, wait_time), SLE_UINT16, 67, SL_MAX_VERSION),
|
||||
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, travel_time), SLE_UINT16, 67, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDREF(Vehicle, orders, REF_ORDER, 0, 104),
|
||||
SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, 105, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Vehicle, max_age, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Vehicle, service_interval, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_VAR(Vehicle, reliability, SLE_UINT16),
|
||||
SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16),
|
||||
SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8),
|
||||
SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Vehicle, build_year, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
|
||||
SLEG_CONDVAR( _cargo_paid_for, SLE_UINT16, 45, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT8, 40, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
||||
SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, 65, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
||||
SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, 65, SL_MAX_VERSION),
|
||||
SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, 51, 64),
|
||||
SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
|
||||
SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, 51, 67),
|
||||
SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
|
||||
SLE_CONDVAR(Vehicle, value, SLE_INT64, 65, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, 2, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(2, 2, 68),
|
||||
SLE_CONDNULL(4, 69, 100),
|
||||
|
||||
SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, 67, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, 67, SL_MAX_VERSION),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 10 bytes) */
|
||||
SLE_CONDNULL(10, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
|
||||
static const SaveLoad _train_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
|
||||
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),
|
||||
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8),
|
||||
|
||||
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_FILE_U8 | SLE_VAR_U16, 2, 99),
|
||||
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT16, 100, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(2, 2, 59),
|
||||
|
||||
SLE_CONDNULL(2, 2, 19),
|
||||
/* reserve extra space in savegame here. (currently 11 bytes) */
|
||||
SLE_CONDNULL(11, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _roadveh_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
|
||||
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),
|
||||
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(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(1, 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),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _ship_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
|
||||
SLE_VEH_INCLUDEX(),
|
||||
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),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _aircraft_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
|
||||
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),
|
||||
|
||||
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(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8),
|
||||
|
||||
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),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _special_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_EFFECT),
|
||||
|
||||
SLE_VAR(Vehicle, subtype, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
|
||||
|
||||
SLE_VAR(Vehicle, cur_image, SLE_UINT16),
|
||||
SLE_CONDNULL(5, 0, 57),
|
||||
SLE_VAR(Vehicle, progress, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
|
||||
|
||||
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_state), SLE_UINT16),
|
||||
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_substate), SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, 2, SL_MAX_VERSION),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 15 bytes) */
|
||||
SLE_CONDNULL(15, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static const SaveLoad _disaster_desc[] = {
|
||||
SLE_WRITEBYTE(Vehicle, type, VEH_DISASTER),
|
||||
|
||||
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
|
||||
|
||||
SLE_VAR(Vehicle, subtype, SLE_UINT8),
|
||||
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
|
||||
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
|
||||
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, direction, SLE_UINT8),
|
||||
|
||||
SLE_CONDNULL(5, 0, 57),
|
||||
SLE_VAR(Vehicle, owner, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
|
||||
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(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16),
|
||||
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, big_ufo_destroyer_target), SLE_UINT16),
|
||||
|
||||
/* reserve extra space in savegame here. (currently 16 bytes) */
|
||||
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
|
||||
static const SaveLoad *_veh_descs[] = {
|
||||
_train_desc,
|
||||
_roadveh_desc,
|
||||
_ship_desc,
|
||||
_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()
|
||||
{
|
||||
Vehicle *v;
|
||||
/* Write the vehicles */
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
SlSetArrayIndex(v->index);
|
||||
SlObject(v, GetVehicleDescription(v->type));
|
||||
}
|
||||
}
|
||||
|
||||
/** Will be called when vehicles need to be loaded. */
|
||||
void Load_VEHS()
|
||||
{
|
||||
int index;
|
||||
|
||||
_cargo_count = 0;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Vehicle *v;
|
||||
VehicleType vtype = (VehicleType)SlReadByte();
|
||||
|
||||
switch (vtype) {
|
||||
case VEH_TRAIN: v = new (index) Train(); break;
|
||||
case VEH_ROAD: v = new (index) RoadVehicle(); break;
|
||||
case VEH_SHIP: v = new (index) Ship(); break;
|
||||
case VEH_AIRCRAFT: v = new (index) Aircraft(); break;
|
||||
case VEH_EFFECT: v = new (index) EffectVehicle(); break;
|
||||
case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
|
||||
case VEH_INVALID: v = new (index) InvalidVehicle(); break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
SlObject(v, GetVehicleDescription(vtype));
|
||||
|
||||
if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
|
||||
/* Don't construct the packet with station here, because that'll fail with old savegames */
|
||||
CargoPacket *cp = new CargoPacket();
|
||||
cp->source = _cargo_source;
|
||||
cp->source_xy = _cargo_source_xy;
|
||||
cp->count = _cargo_count;
|
||||
cp->days_in_transit = _cargo_days;
|
||||
cp->feeder_share = _cargo_feeder_share;
|
||||
cp->loaded_at_xy = _cargo_loaded_at_xy;
|
||||
v->cargo.Append(cp);
|
||||
}
|
||||
|
||||
/* Old savegames used 'last_station_visited = 0xFF' */
|
||||
if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
|
||||
v->last_station_visited = INVALID_STATION;
|
||||
|
||||
if (CheckSavegameVersion(5)) {
|
||||
/* Convert the current_order.type (which is a mix of type and flags, because
|
||||
* in those versions, they both were 4 bits big) to type and flags */
|
||||
v->current_order.flags = GB(v->current_order.type, 4, 4);
|
||||
v->current_order.type &= 0x0F;
|
||||
}
|
||||
|
||||
/* Advanced vehicle lists got added */
|
||||
if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _veh_chunk_handlers[] = {
|
||||
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
|
||||
};
|
@ -0,0 +1,96 @@
|
||||
/* $Id$ */
|
||||
|
||||
/** @file waypoint_sl.cpp Code handling saving and loading of waypoints */
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../waypoint.h"
|
||||
#include "../newgrf_station.h"
|
||||
#include "../town.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
#include "saveload.h"
|
||||
|
||||
/**
|
||||
* Update waypoint graphics id against saved GRFID/localidx.
|
||||
* This is to ensure the chosen graphics are correct if GRF files are changed.
|
||||
*/
|
||||
void AfterLoadWaypoints()
|
||||
{
|
||||
Waypoint *wp;
|
||||
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
uint i;
|
||||
|
||||
if (wp->grfid == 0) continue;
|
||||
|
||||
for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
|
||||
const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
|
||||
if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
|
||||
wp->stat_id = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix savegames which stored waypoints in their old format
|
||||
*/
|
||||
void FixOldWaypoints()
|
||||
{
|
||||
Waypoint *wp;
|
||||
|
||||
/* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
wp->town_index = ClosestTownFromTile(wp->xy, UINT_MAX)->index;
|
||||
wp->town_cn = 0;
|
||||
if (wp->string & 0xC000) {
|
||||
wp->town_cn = wp->string & 0x3F;
|
||||
wp->string = STR_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const SaveLoad _waypoint_desc[] = {
|
||||
SLE_CONDVAR(Waypoint, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||
SLE_CONDVAR(Waypoint, xy, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, town_index, SLE_UINT16, 12, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, town_cn, SLE_FILE_U8 | SLE_VAR_U16, 12, 88),
|
||||
SLE_CONDVAR(Waypoint, town_cn, SLE_UINT16, 89, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, string, SLE_STRINGID, 0, 83),
|
||||
SLE_CONDSTR(Waypoint, name, SLE_STR, 0, 84, SL_MAX_VERSION),
|
||||
SLE_VAR(Waypoint, deleted, SLE_UINT8),
|
||||
|
||||
SLE_CONDVAR(Waypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
|
||||
SLE_CONDVAR(Waypoint, build_date, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, localidx, SLE_UINT8, 3, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, grfid, SLE_UINT32, 17, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Waypoint, owner, SLE_UINT8, 101, SL_MAX_VERSION),
|
||||
|
||||
SLE_END()
|
||||
};
|
||||
|
||||
static void Save_WAYP()
|
||||
{
|
||||
Waypoint *wp;
|
||||
|
||||
FOR_ALL_WAYPOINTS(wp) {
|
||||
SlSetArrayIndex(wp->index);
|
||||
SlObject(wp, _waypoint_desc);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_WAYP()
|
||||
{
|
||||
int index;
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Waypoint *wp = new (index) Waypoint();
|
||||
SlObject(wp, _waypoint_desc);
|
||||
}
|
||||
}
|
||||
|
||||
extern const ChunkHandler _waypoint_chunk_handlers[] = {
|
||||
{ 'CHKP', Save_WAYP, Load_WAYP, CH_ARRAY | CH_LAST},
|
||||
};
|
Loading…
Reference in New Issue