mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r15216) -Feature: native support for Transport Tycoon (Original) savegames. Based on SVXConverter's source code and documentation by Roman Vetter
This commit is contained in:
parent
83e1288c6a
commit
6dffd8ae82
|
@ -2075,6 +2075,10 @@
|
|||
RelativePath=".\..\src\saveload\oldloader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\oldloader_sl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\order_sl.cpp"
|
||||
>
|
||||
|
@ -2111,10 +2115,6 @@
|
|||
RelativePath=".\..\src\saveload\town_sl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\ttdloader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\vehicle_sl.cpp"
|
||||
>
|
||||
|
|
|
@ -2072,6 +2072,10 @@
|
|||
RelativePath=".\..\src\saveload\oldloader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\oldloader_sl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\order_sl.cpp"
|
||||
>
|
||||
|
@ -2108,10 +2112,6 @@
|
|||
RelativePath=".\..\src\saveload\town_sl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\ttdloader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\saveload\vehicle_sl.cpp"
|
||||
>
|
||||
|
|
|
@ -468,6 +468,7 @@ saveload/misc_sl.cpp
|
|||
saveload/newgrf_sl.cpp
|
||||
saveload/oldloader.cpp
|
||||
saveload/oldloader.h
|
||||
saveload/oldloader_sl.cpp
|
||||
saveload/order_sl.cpp
|
||||
saveload/saveload.cpp
|
||||
saveload/saveload.h
|
||||
|
@ -477,7 +478,6 @@ saveload/station_sl.cpp
|
|||
saveload/strings_sl.cpp
|
||||
saveload/subsidy_sl.cpp
|
||||
saveload/town_sl.cpp
|
||||
saveload/ttdloader.cpp
|
||||
saveload/vehicle_sl.cpp
|
||||
saveload/waypoint_sl.cpp
|
||||
|
||||
|
|
|
@ -252,6 +252,49 @@ void SetYearEngineAgingStops()
|
|||
}
|
||||
}
|
||||
|
||||
void StartupOneEngine(Engine *e, Date aging_date)
|
||||
{
|
||||
const EngineInfo *ei = &e->info;
|
||||
uint32 r;
|
||||
|
||||
e->age = 0;
|
||||
e->flags = 0;
|
||||
e->company_avail = 0;
|
||||
|
||||
/* The magic value of 729 days below comes from the NewGRF spec. If the
|
||||
* base intro date is before 1922 then the random number of days is not
|
||||
* added. */
|
||||
r = Random();
|
||||
e->intro_date = ei->base_intro <= ConvertYMDToDate(1922, 0, 1) ? ei->base_intro : (Date)GB(r, 0, 9) + ei->base_intro;
|
||||
if (e->intro_date <= _date) {
|
||||
e->age = (aging_date - e->intro_date) >> 5;
|
||||
e->company_avail = (CompanyMask)-1;
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
}
|
||||
|
||||
e->reliability_start = GB(r, 16, 14) + 0x7AE0;
|
||||
r = Random();
|
||||
e->reliability_max = GB(r, 0, 14) + 0xBFFF;
|
||||
e->reliability_final = GB(r, 16, 14) + 0x3FFF;
|
||||
|
||||
r = Random();
|
||||
e->duration_phase_1 = GB(r, 0, 5) + 7;
|
||||
e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96;
|
||||
e->duration_phase_3 = GB(r, 9, 7) + 120;
|
||||
|
||||
e->reliability_spd_dec = ei->decay_speed << 2;
|
||||
|
||||
CalcEngineReliability(e);
|
||||
|
||||
e->lifelength = ei->lifelength + _settings_game.vehicle.extend_vehicle_life;
|
||||
|
||||
/* prevent certain engines from ever appearing. */
|
||||
if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) {
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
e->company_avail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void StartupEngines()
|
||||
{
|
||||
Engine *e;
|
||||
|
@ -259,45 +302,7 @@ void StartupEngines()
|
|||
const Date aging_date = min(_date, ConvertYMDToDate(_year_engine_aging_stops, 0, 1));
|
||||
|
||||
FOR_ALL_ENGINES(e) {
|
||||
const EngineInfo *ei = &e->info;
|
||||
uint32 r;
|
||||
|
||||
e->age = 0;
|
||||
e->flags = 0;
|
||||
e->company_avail = 0;
|
||||
|
||||
/* The magic value of 729 days below comes from the NewGRF spec. If the
|
||||
* base intro date is before 1922 then the random number of days is not
|
||||
* added. */
|
||||
r = Random();
|
||||
e->intro_date = ei->base_intro <= ConvertYMDToDate(1922, 0, 1) ? ei->base_intro : (Date)GB(r, 0, 9) + ei->base_intro;
|
||||
if (e->intro_date <= _date) {
|
||||
e->age = (aging_date - e->intro_date) >> 5;
|
||||
e->company_avail = (CompanyMask)-1;
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
}
|
||||
|
||||
e->reliability_start = GB(r, 16, 14) + 0x7AE0;
|
||||
r = Random();
|
||||
e->reliability_max = GB(r, 0, 14) + 0xBFFF;
|
||||
e->reliability_final = GB(r, 16, 14) + 0x3FFF;
|
||||
|
||||
r = Random();
|
||||
e->duration_phase_1 = GB(r, 0, 5) + 7;
|
||||
e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96;
|
||||
e->duration_phase_3 = GB(r, 9, 7) + 120;
|
||||
|
||||
e->reliability_spd_dec = ei->decay_speed << 2;
|
||||
|
||||
CalcEngineReliability(e);
|
||||
|
||||
e->lifelength = ei->lifelength + _settings_game.vehicle.extend_vehicle_life;
|
||||
|
||||
/* prevent certain engines from ever appearing. */
|
||||
if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) {
|
||||
e->flags |= ENGINE_AVAILABLE;
|
||||
e->company_avail = 0;
|
||||
}
|
||||
StartupOneEngine(e, aging_date);
|
||||
}
|
||||
|
||||
/* Update the bitmasks for the vehicle lists */
|
||||
|
|
|
@ -27,5 +27,6 @@ bool IsEngineRefittable(EngineID engine);
|
|||
CargoID GetEngineCargoType(EngineID engine);
|
||||
void SetCachedEngineCounts();
|
||||
void SetYearEngineAgingStops();
|
||||
void StartupOneEngine(Engine *e, Date aging_date);
|
||||
|
||||
#endif /* ENGINE_H */
|
||||
|
|
|
@ -195,6 +195,10 @@ void GamelogPrint(GamelogPrintProc *proc)
|
|||
GB(lc->oldver.version, 8, 16), GB(lc->oldver.version, 0, 8));
|
||||
break;
|
||||
|
||||
case SGT_TTO:
|
||||
AddDebugText(buf, "TTO savegame");
|
||||
break;
|
||||
|
||||
case SGT_TTD:
|
||||
AddDebugText(buf, "TTD savegame");
|
||||
break;
|
||||
|
|
|
@ -327,7 +327,7 @@ static void FixOwnerOfRailTrack(TileIndex t)
|
|||
if (IsLevelCrossingTile(t)) {
|
||||
/* else change the crossing to normal road (road vehicles won't care) */
|
||||
MakeRoadNormal(t, GetCrossingRoadBits(t), GetRoadTypes(t), GetTownIndex(t),
|
||||
GetRoadOwner(t, ROADTYPE_ROAD), GetRoadOwner(t, ROADTYPE_TRAM), GetRoadOwner(t, ROADTYPE_HWAY));
|
||||
GetRoadOwner(t, ROADTYPE_ROAD), GetRoadOwner(t, ROADTYPE_TRAM), GetRoadOwner(t, ROADTYPE_HWAY));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,6 @@ bool AfterLoadGame()
|
|||
Station *st;
|
||||
FOR_ALL_STATIONS(st) {
|
||||
if (st->train_tile != 0 && st->trainst_h == 0) {
|
||||
extern SavegameType _savegame_type;
|
||||
uint n = _savegame_type == SGT_OTTD ? 4 : 3; // OTTD uses 4 bits per dimensions, TTD 3 bits
|
||||
uint w = GB(st->trainst_w, n, n);
|
||||
uint h = GB(st->trainst_w, 0, n);
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
#include "oldloader.h"
|
||||
|
||||
enum {
|
||||
HEADER_SIZE = 49,
|
||||
TTO_HEADER_SIZE = 41,
|
||||
TTD_HEADER_SIZE = 49,
|
||||
};
|
||||
|
||||
uint32 _bump_assert_value;
|
||||
|
||||
static inline OldChunkType GetOldChunkType(OldChunkType type) {return (OldChunkType)GB(type, 0, 8);}
|
||||
static inline OldChunkType GetOldChunkType(OldChunkType type) {return (OldChunkType)GB(type, 0, 4);}
|
||||
static inline OldChunkType GetOldChunkVarType(OldChunkType type) {return (OldChunkType)(GB(type, 8, 8) << 8);}
|
||||
static inline OldChunkType GetOldChunkFileType(OldChunkType type) {return (OldChunkType)(GB(type, 16, 8) << 16);}
|
||||
|
||||
|
@ -101,12 +102,17 @@ byte ReadByte(LoadgameState *ls)
|
|||
*/
|
||||
bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
|
||||
{
|
||||
const OldChunks *chunk = chunks;
|
||||
byte *base_ptr = (byte*)base;
|
||||
|
||||
while (chunk->type != OC_END) {
|
||||
for (const OldChunks *chunk = chunks; chunk->type != OC_END; chunk++) {
|
||||
if (((chunk->type & OC_TTD) && (_savegame_type == SGT_TTO)) ||
|
||||
((chunk->type & OC_TTO) && (_savegame_type != SGT_TTO))) {
|
||||
/* TTD(P)-only chunk, but TTO savegame || TTO-only chunk, but TTD/TTDP savegame */
|
||||
continue;
|
||||
}
|
||||
|
||||
byte *ptr = (byte*)chunk->ptr;
|
||||
if ((chunk->type & OC_DEREFERENCE_POINTER) != 0) ptr = *(byte**)ptr;
|
||||
if (chunk->type & OC_DEREFERENCE_POINTER) ptr = *(byte**)ptr;
|
||||
|
||||
for (uint i = 0; i < chunk->amount; i++) {
|
||||
if (ls->failed) return false;
|
||||
|
@ -164,8 +170,6 @@ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks)
|
|||
if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type);
|
||||
}
|
||||
}
|
||||
|
||||
chunk++;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -194,30 +198,72 @@ static void InitLoading(LoadgameState *ls)
|
|||
_settings_game.construction.freeform_edges = false; // disable so we can convert map array (SetTileType is still used)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Verifies the title has a valid checksum
|
||||
* @param title title and checksum
|
||||
* @return true iff the title is valid
|
||||
* @note the title (incl. checksum) has to be at least 49 (HEADER_SIZE) bytes long!
|
||||
* @note the title (incl. checksum) has to be at least 41/49 (HEADER_SIZE) bytes long!
|
||||
*/
|
||||
static bool VerifyOldNameChecksum(char *title)
|
||||
static bool VerifyOldNameChecksum(char *title, uint len)
|
||||
{
|
||||
uint16 sum = 0;
|
||||
for (uint i = 0; i < HEADER_SIZE - 2; i++) {
|
||||
for (uint i = 0; i < len - 2; i++) {
|
||||
sum += title[i];
|
||||
sum = ROL(sum, 1);
|
||||
}
|
||||
|
||||
sum ^= 0xAAAA; // computed checksum
|
||||
|
||||
uint16 sum2 = title[HEADER_SIZE - 2]; // checksum in file
|
||||
SB(sum2, 8, 8, title[HEADER_SIZE - 1]);
|
||||
uint16 sum2 = title[len - 2]; // checksum in file
|
||||
SB(sum2, 8, 8, title[len - 1]);
|
||||
|
||||
return sum == sum2;
|
||||
}
|
||||
|
||||
static inline bool CheckOldSavegameType(FILE *f, char *temp, const char *last, uint len)
|
||||
{
|
||||
assert(last - temp + 1 >= len);
|
||||
|
||||
fseek(f, 0, SEEK_SET);
|
||||
if (fread(temp, 1, len, f) != len) {
|
||||
temp[0] = '\0'; // if reading failed, make the name empty
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ret = VerifyOldNameChecksum(temp, len);
|
||||
temp[len - 2] = '\0'; // name is nul-terminated in savegame, but it's better to be sure
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert_compile(TTD_HEADER_SIZE >= TTO_HEADER_SIZE);
|
||||
static SavegameType DetermineOldSavegameType(FILE *f, char *title, const char *last)
|
||||
{
|
||||
char temp[TTD_HEADER_SIZE];
|
||||
|
||||
SavegameType type = SGT_TTO;
|
||||
|
||||
if (!CheckOldSavegameType(f, temp, lastof(temp), TTO_HEADER_SIZE)) {
|
||||
type = SGT_TTD;
|
||||
if (!CheckOldSavegameType(f, temp, lastof(temp), TTD_HEADER_SIZE)) {
|
||||
type = SGT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
if (title != NULL) {
|
||||
switch (type) {
|
||||
case SGT_TTO: title = strecpy(title, "(TTO) ", last); break;
|
||||
case SGT_TTD: title = strecpy(title, "(TTD) ", last); break;
|
||||
default: title = strecpy(title, "(broken) ", last); break;
|
||||
}
|
||||
title = strecpy(title, temp, last);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
typedef bool LoadOldMainProc(LoadgameState *ls);
|
||||
|
||||
bool LoadOldSaveGame(const char *file)
|
||||
{
|
||||
LoadgameState ls;
|
||||
|
@ -234,8 +280,19 @@ bool LoadOldSaveGame(const char *file)
|
|||
return false;
|
||||
}
|
||||
|
||||
char temp[HEADER_SIZE];
|
||||
if (fread(temp, 1, HEADER_SIZE, ls.file) != HEADER_SIZE || !VerifyOldNameChecksum(temp) || !LoadOldMain(&ls)) {
|
||||
SavegameType type = DetermineOldSavegameType(ls.file, NULL, NULL);
|
||||
|
||||
LoadOldMainProc *proc = NULL;
|
||||
|
||||
switch (type) {
|
||||
case SGT_TTO: proc = &LoadTTOMain; break;
|
||||
case SGT_TTD: proc = &LoadTTDMain; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
_savegame_type = type;
|
||||
|
||||
if (proc == NULL || !proc(&ls)) {
|
||||
SetSaveLoadError(STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED);
|
||||
fclose(ls.file);
|
||||
return false;
|
||||
|
@ -249,23 +306,16 @@ bool LoadOldSaveGame(const char *file)
|
|||
void GetOldSaveGameName(const char *path, const char *file, char *title, const char *last)
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
char temp[HEADER_SIZE];
|
||||
|
||||
snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, file);
|
||||
FILE *f = fopen(filename, "rb");
|
||||
temp[0] = '\0'; // name is nul-terminated in savegame ...
|
||||
|
||||
if (f == NULL) {
|
||||
*title = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
bool broken = (fread(temp, 1, HEADER_SIZE, f) != HEADER_SIZE || !VerifyOldNameChecksum(temp));
|
||||
|
||||
temp[HEADER_SIZE - 2] = '\0'; // ... but it's better to be sure
|
||||
|
||||
if (broken) title = strecpy(title, "(broken) ", last);
|
||||
title = strecpy(title, temp, last);
|
||||
DetermineOldSavegameType(f, title, last);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,11 @@ enum OldChunkType {
|
|||
OC_NULL = 1,
|
||||
OC_CHUNK = 2,
|
||||
OC_ASSERT = 3,
|
||||
/* 8 bits allocated (256 max) */
|
||||
/* 4 bits allocated (16 max) */
|
||||
|
||||
OC_TTD = 1 << 4, ///< chunk is valid ONLY for TTD savegames
|
||||
OC_TTO = 1 << 5, ///< -//- TTO (default in neither of these)
|
||||
/* 4 bits allocated */
|
||||
|
||||
OC_VAR_I8 = 1 << 8,
|
||||
OC_VAR_U8 = 2 << 8,
|
||||
|
@ -91,7 +95,8 @@ extern uint _bump_assert_value;
|
|||
byte ReadByte(LoadgameState *ls);
|
||||
bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks);
|
||||
|
||||
bool LoadOldMain(LoadgameState *ls);
|
||||
bool LoadTTDMain(LoadgameState *ls);
|
||||
bool LoadTTOMain(LoadgameState *ls);
|
||||
|
||||
static inline uint16 ReadUint16(LoadgameState *ls)
|
||||
{
|
||||
|
@ -114,11 +119,13 @@ static inline uint32 ReadUint32(LoadgameState *ls)
|
|||
* - OCL_CHUNK: load an other proc to load a part of the savegame, 'amount' times
|
||||
* - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;)
|
||||
*/
|
||||
#define OCL_SVAR(type, base, offset) { type, 1, NULL, (uint)cpp_offsetof(base, offset), NULL }
|
||||
#define OCL_VAR(type, amount, pointer) { type, amount, pointer, 0, NULL }
|
||||
#define OCL_END() { OC_END, 0, NULL, 0, NULL }
|
||||
#define OCL_NULL(amount) { OC_NULL, amount, NULL, 0, NULL }
|
||||
#define OCL_CHUNK(amount, proc) { OC_CHUNK, amount, NULL, 0, proc }
|
||||
#define OCL_ASSERT(size) { OC_ASSERT, 1, NULL, size, NULL }
|
||||
#define OCL_SVAR(type, base, offset) { type, 1, NULL, (uint)cpp_offsetof(base, offset), NULL }
|
||||
#define OCL_VAR(type, amount, pointer) { type, amount, pointer, 0, NULL }
|
||||
#define OCL_END() { OC_END, 0, NULL, 0, NULL }
|
||||
#define OCL_CNULL(type, amount) { OC_NULL | type, amount, NULL, 0, NULL }
|
||||
#define OCL_CCHUNK(type, amount, proc) { OC_CHUNK | type, amount, NULL, 0, proc }
|
||||
#define OCL_ASSERT(type, size) { OC_ASSERT | type, 1, NULL, size, NULL }
|
||||
#define OCL_NULL(amount) OCL_CNULL((OldChunkType)0, amount)
|
||||
#define OCL_CHUNK(amount, proc) OCL_CCHUNK((OldChunkType)0, amount, proc)
|
||||
|
||||
#endif /* OLDLOADER_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -32,7 +32,9 @@ enum SavegameType {
|
|||
SGT_TTD, ///< TTD savegame (can be detected incorrectly)
|
||||
SGT_TTDP1, ///< TTDP savegame ( -//- ) (data at NW border)
|
||||
SGT_TTDP2, ///< TTDP savegame in new format (data at SE border)
|
||||
SGT_OTTD ///< OTTD savegame
|
||||
SGT_OTTD, ///< OTTD savegame
|
||||
SGT_TTO, ///< TTO savegame
|
||||
SGT_INVALID = 0xFF ///< broken savegame (used internally)
|
||||
};
|
||||
|
||||
void GenerateDefaultSaveName(char *buf, const char *last);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../company_manager_face.h"
|
||||
#include "../order_base.h"
|
||||
#include "../engine_type.h"
|
||||
#include "saveload.h"
|
||||
|
||||
void InitializeOldNames();
|
||||
StringID RemapOldStringID(StringID s);
|
||||
|
@ -37,6 +38,9 @@ void CopyTempEngineData();
|
|||
extern int32 _saved_scrollpos_x;
|
||||
extern int32 _saved_scrollpos_y;
|
||||
|
||||
extern SavegameType _savegame_type;
|
||||
extern uint32 _ttdp_version;
|
||||
|
||||
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face);
|
||||
|
||||
Order UnpackOldOrder(uint16 packed);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../core/bitmath_func.hpp"
|
||||
#include "../core/alloc_func.hpp"
|
||||
#include "../string_func.h"
|
||||
#include "saveload_internal.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
|
@ -44,8 +45,8 @@ 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.
|
||||
* They were all stored in a 512 by 32 (200 by 24 for TTO) 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.
|
||||
*/
|
||||
|
@ -55,10 +56,11 @@ char *CopyFromOldName(StringID id)
|
|||
if (GB(id, 11, 5) != 15) return NULL;
|
||||
|
||||
if (CheckSavegameVersion(37)) {
|
||||
/* Old names were 32 characters long, so 128 characters should be
|
||||
/* Old names were 24/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)];
|
||||
uint offs = _savegame_type == SGT_TTO ? 24 * GB(id, 0, 8) : 32 * GB(id, 0, 9);
|
||||
const char *strfrom = &_old_name_array[offs];
|
||||
char *strto = tmp;
|
||||
|
||||
for (; *strfrom != '\0'; strfrom++) {
|
||||
|
@ -109,7 +111,7 @@ void ResetOldNames()
|
|||
void InitializeOldNames()
|
||||
{
|
||||
free(_old_name_array);
|
||||
_old_name_array = CallocT<char>(512 * 32);
|
||||
_old_name_array = CallocT<char>(512 * 32); // 200 * 24 would be enough for TTO savegames
|
||||
}
|
||||
|
||||
static void Load_NAME()
|
||||
|
|
|
@ -207,7 +207,7 @@ private:
|
|||
Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain
|
||||
public:
|
||||
friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code
|
||||
friend void AfterLoadVehicles(bool part_of_load); ///< So we can set the previous and first pointers while loading
|
||||
friend void AfterLoadVehicles(bool part_of_load); ///< So we can set the previous and first pointers while loading
|
||||
friend bool LoadOldVehicle(LoadgameState *ls, int num); ///< So we can set the proper next pointer while loading
|
||||
|
||||
char *name; ///< Name of vehicle
|
||||
|
|
Loading…
Reference in New Issue