/** * Load the NAME chunk. */ static void Load_NAME() { int index; while ((index = SlIterateArray()) != -1) { if (index >= NUM_OLD_STRINGS) SlErrorCorrupt("Invalid old name index"); if (SlGetFieldLength() > (uint)LEN_OLD_STRINGS) SlErrorCorrupt("Invalid old name length"); SlArray(&_old_name_array[LEN_OLD_STRINGS * index], SlGetFieldLength(), SLE_UINT8); /* Make sure the old name is null terminated */ _old_name_array[LEN_OLD_STRINGS * index + LEN_OLD_STRINGS - 1] = '\0'; } }
static void Load_TOWN() { int index; while ((index = SlIterateArray()) != -1) { Town *t = new (index) Town(); SlObject(t, _town_desc); for (CargoID i = 0; i < NUM_CARGO; i++) { SlObject(&t->supplied[i], _town_supplied_desc); } for (int i = TE_BEGIN; i < TE_END; i++) { SlObject(&t->received[i], _town_received_desc); } if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GB(t->townnametype, 11, 5) != 15) { SlErrorCorrupt("Invalid town name generator"); } if (IsSavegameVersionBefore(166)) continue; SlObject(&t->cargo_accepted, GetTileMatrixDesc()); if (t->cargo_accepted.area.w != 0) { uint arr_len = t->cargo_accepted.area.w / AcceptanceMatrix::GRID * t->cargo_accepted.area.h / AcceptanceMatrix::GRID; t->cargo_accepted.data = MallocT<uint32>(arr_len); SlArray(t->cargo_accepted.data, arr_len, SLE_UINT32); /* Rebuild total cargo acceptance. */ UpdateTownCargoTotal(t); } } }
static void Load_AIPL() { /* Free all current data */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(NULL); } CompanyID index; while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) { if (index >= MAX_COMPANIES) SlErrorCorrupt("Too many AI configs"); _ai_saveload_is_random = 0; _ai_saveload_version = -1; SlObject(NULL, _ai_company); if (_networking && !_network_server) { if (Company::IsValidAiID(index)) AIInstance::LoadEmpty(); continue; } AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME); if (StrEmpty(_ai_saveload_name)) { /* A random AI. */ config->Change(NULL, -1, false, true); } else { config->Change(_ai_saveload_name, _ai_saveload_version, false, _ai_saveload_is_random); if (!config->HasScript()) { /* No version of the AI available that can load the data. Try to load the * latest version of the AI instead. */ config->Change(_ai_saveload_name, -1, false, _ai_saveload_is_random); if (!config->HasScript()) { if (strcmp(_ai_saveload_name, "%_dummy") != 0) { DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name, _ai_saveload_version); DEBUG(script, 0, "A random other AI will be loaded in its place."); } else { DEBUG(script, 0, "The savegame had no AIs available at the time of saving."); DEBUG(script, 0, "A random available AI will be loaded now."); } } else { DEBUG(script, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name, _ai_saveload_version); DEBUG(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible."); } /* Make sure the AI doesn't get the saveload data, as he was not the * writer of the saveload data in the first place */ _ai_saveload_version = -1; } } config->StringToSettings(_ai_saveload_settings); /* Start the AI directly if it was active in the savegame */ if (Company::IsValidAiID(index)) { AI::StartNew(index, false); AI::Load(index, _ai_saveload_version); } } }
/** * Load the cheat values. */ static void Load_CHTS() { Cheat *cht = (Cheat*)&_cheats; size_t count = SlGetFieldLength() / 2; /* Cannot use lengthof because _cheats is of type Cheats, not Cheat */ if (count > sizeof(_cheats) / sizeof(Cheat)) SlErrorCorrupt("Too many cheat values"); for (uint i = 0; i < count; i++) { cht[i].been_used = (SlReadByte() != 0); cht[i].value = (SlReadByte() != 0); } }
/** * 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() { Train *t; FOR_ALL_TRAINS(t) SetBit(t->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop FOR_ALL_TRAINS(t) { if (HasBit(t->subtype, 7) && ((t->subtype & ~0x80) == 0 || (t->subtype & ~0x80) == 4)) { for (Train *u = t; 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) u->SetMultiheaded(); u->SetFrontEngine(); u->SetEngine(); break; case 1: // TS_Artic_Part u->subtype = 0; u->SetArticulatedPart(); break; case 2: // TS_Not_First u->subtype = 0; if (rvi->railveh_type == RAILVEH_WAGON) { /* normal wagon */ u->SetWagon(); break; } if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) { /* rear end of a multiheaded engine */ u->SetMultiheaded(); break; } if (rvi->railveh_type == RAILVEH_MULTIHEAD) u->SetMultiheaded(); u->SetEngine(); break; case 4: // TS_Free_Car u->subtype = 0; u->SetWagon(); u->SetFreeWagon(); break; default: SlErrorCorrupt("Invalid train subtype"); } } } } }
static bool LoadObjects() { SlObject(NULL, _ai_byte); switch (_ai_sl_byte) { case SQSL_INT: { int value; SlArray(&value, 1, SLE_INT32); return true; } case SQSL_STRING: { SlObject(NULL, _ai_byte); static char buf[256]; SlArray(buf, _ai_sl_byte, SLE_CHAR); return true; } case SQSL_ARRAY: while (LoadObjects()) { } return true; case SQSL_TABLE: while (LoadObjects()) { LoadObjects(); } return true; case SQSL_BOOL: SlObject(NULL, _ai_byte); return true; case SQSL_NULL: return true; case SQSL_ARRAY_TABLE_END: return false; default: SlErrorCorrupt("Invalid AI data type"); } }