mirror of https://github.com/OpenTTD/OpenTTD
Finally POC
parent
4f332d77ad
commit
924c14b849
|
@ -1,4 +1,5 @@
|
|||
/.vs
|
||||
/.cache/*
|
||||
/build*
|
||||
CMakeSettings.json
|
||||
docs/aidocs/*
|
||||
|
|
Binary file not shown.
|
@ -96,6 +96,7 @@ struct CompanyProperties {
|
|||
uint8_t months_empty = 0; ///< NOSAVE: Number of months this company has not had a client in multiplayer.
|
||||
uint8_t months_of_bankruptcy; ///< Number of months that the company is unable to pay its debts
|
||||
CompanyMask bankrupt_asked; ///< which companies were asked about buying it?
|
||||
uint16_t old_bankrupt_asked;
|
||||
int16_t bankrupt_timeout; ///< If bigger than \c 0, amount of time to wait for an answer on an offer to buy this company.
|
||||
Money bankrupt_value;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "core/pool_type.hpp"
|
||||
#include "newgrf_commons.h"
|
||||
#include "timer/timer_game_calendar.h"
|
||||
#include <cstdint>
|
||||
|
||||
struct WagonOverride {
|
||||
std::vector<EngineID> engines;
|
||||
|
@ -47,11 +48,19 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> {
|
|||
uint16_t duration_phase_2; ///< Second reliability phase in months, keeping #reliability_max.
|
||||
uint16_t duration_phase_3; ///< Third reliability phase in months, decaying to #reliability_final.
|
||||
uint8_t flags; ///< Flags of the engine. @see EngineFlags
|
||||
|
||||
CompanyMask preview_asked; ///< Bit for each company which has already been offered a preview.
|
||||
uint16_t old_preview_asked;
|
||||
|
||||
CompanyID preview_company; ///< Company which is currently being offered a preview \c INVALID_COMPANY means no company.
|
||||
uint8_t preview_wait; ///< Daily countdown timer for timeout of offering the engine to the #preview_company company.
|
||||
|
||||
CompanyMask company_avail; ///< Bit for each company whether the engine is available for that company.
|
||||
uint16_t old_company_avail;
|
||||
|
||||
CompanyMask company_hidden; ///< Bit for each company whether the engine is normally hidden in the build gui for that company.
|
||||
uint16_t old_company_hidden;
|
||||
|
||||
uint8_t original_image_index; ///< Original vehicle image index, thus the image index of the overridden vehicle
|
||||
VehicleType type; ///< %Vehicle type, ie #VEH_ROAD, #VEH_TRAIN, etc.
|
||||
|
||||
|
|
|
@ -63,11 +63,14 @@
|
|||
#include "../timer/timer_game_economy.h"
|
||||
#include "../timer/timer_game_tick.h"
|
||||
|
||||
#include "saveload/saveload.h"
|
||||
#include "saveload_internal.h"
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "../safeguards.h"
|
||||
#include "tile_map.h"
|
||||
#include "tile_type.h"
|
||||
|
||||
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
|
||||
|
||||
|
@ -163,7 +166,7 @@ static void ConvertTownOwner()
|
|||
[[fallthrough]];
|
||||
|
||||
case MP_TUNNELBRIDGE:
|
||||
if (tile.m1() & 0x80) SetTileOwner(tile, OWNER_TOWN);
|
||||
if (tile.m1() & 0x80) OldSetTileOwner(tile, OWNER_TOWN);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
|
@ -421,7 +424,7 @@ static void CDECL HandleSavegameLoadCrash(int signum)
|
|||
*/
|
||||
static void FixOwnerOfRailTrack(Tile t)
|
||||
{
|
||||
assert(!Company::IsValidID(GetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t)));
|
||||
assert(!Company::IsValidID(OldGetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t)));
|
||||
|
||||
/* remove leftover rail piece from crossing (from very old savegames) */
|
||||
Train *v = nullptr;
|
||||
|
@ -434,7 +437,7 @@ static void FixOwnerOfRailTrack(Tile t)
|
|||
|
||||
if (v != nullptr) {
|
||||
/* when there is a train on crossing (it could happen in TTD), set owner of crossing to train owner */
|
||||
SetTileOwner(t, v->owner);
|
||||
OldSetTileOwner(t, v->owner);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -443,15 +446,15 @@ static void FixOwnerOfRailTrack(Tile t)
|
|||
TileIndex tt = t + TileOffsByDiagDir(dd);
|
||||
if (GetTileTrackStatus(t, TRANSPORT_RAIL, 0, dd) != 0 &&
|
||||
GetTileTrackStatus(tt, TRANSPORT_RAIL, 0, ReverseDiagDir(dd)) != 0 &&
|
||||
Company::IsValidID(GetTileOwner(tt))) {
|
||||
SetTileOwner(t, GetTileOwner(tt));
|
||||
Company::IsValidID(OldGetTileOwner(tt))) {
|
||||
OldSetTileOwner(t, OldGetTileOwner(tt));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsLevelCrossingTile(t)) {
|
||||
/* else change the crossing to normal road (road vehicles won't care) */
|
||||
Owner road = GetRoadOwner(t, RTT_ROAD); // TODO: m9
|
||||
Owner road = GetRoadOwner(t, RTT_ROAD);
|
||||
Owner tram = GetRoadOwner(t, RTT_TRAM);
|
||||
RoadBits bits = GetCrossingRoadBits(t);
|
||||
bool hasroad = HasBit(t.m7(), 6);
|
||||
|
@ -459,7 +462,7 @@ static void FixOwnerOfRailTrack(Tile t)
|
|||
|
||||
/* MakeRoadNormal */
|
||||
SetTileType(t, MP_ROAD);
|
||||
SetTileOwner(t, road);
|
||||
OldSetTileOwner(t, road);
|
||||
t.m3() = (hasroad ? bits : 0);
|
||||
t.m5() = (hastram ? bits : 0) | ROAD_TILE_NORMAL << 6;
|
||||
SB(t.m6(), 2, 4, 0);
|
||||
|
@ -471,6 +474,7 @@ static void FixOwnerOfRailTrack(Tile t)
|
|||
MakeClear(t, CLEAR_GRASS, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fixes inclination of a vehicle. Older OpenTTD versions didn't update the bits correctly.
|
||||
* @param v vehicle
|
||||
|
@ -656,8 +660,8 @@ bool AfterLoadGame()
|
|||
* walk through the whole map.. */
|
||||
if (IsSavegameVersionBefore(SLV_4, 3)) {
|
||||
for (auto t : Map::Iterate()) {
|
||||
if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= OLD_MAX_COMPANIES) {
|
||||
SetTileOwner(t, OWNER_WATER);
|
||||
if (IsTileType(t, MP_WATER) && OldGetTileOwner(t) >= OLD_MAX_COMPANIES) {
|
||||
OldSetTileOwner(t, OWNER_WATER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -858,7 +862,7 @@ bool AfterLoadGame()
|
|||
default: break;
|
||||
|
||||
case MP_WATER:
|
||||
if (GetWaterTileType(t) == WATER_TILE_LOCK && GetTileOwner(t) == OWNER_WATER) SetTileOwner(t, OWNER_NONE);
|
||||
if (GetWaterTileType(t) == WATER_TILE_LOCK && OldGetTileOwner(t) == OWNER_WATER) OldSetTileOwner(t, OWNER_NONE);
|
||||
break;
|
||||
|
||||
case MP_STATION: {
|
||||
|
@ -913,7 +917,7 @@ bool AfterLoadGame()
|
|||
BaseStation *bst = BaseStation::GetByTile(t);
|
||||
|
||||
/* Sanity check */
|
||||
if (!IsBuoy(t) && bst->owner != GetTileOwner(t)) SlErrorCorrupt("Wrong owner for station tile");
|
||||
if (!IsBuoy(t) && bst->owner != OldGetTileOwner(t)) SlErrorCorrupt("Wrong owner for station tile");
|
||||
|
||||
/* Set up station spread */
|
||||
bst->rect.BeforeAddTile(t, StationRect::ADD_FORCE);
|
||||
|
@ -986,7 +990,7 @@ bool AfterLoadGame()
|
|||
|
||||
case MP_ROAD:
|
||||
t.m4() |= (t.m2() << 4);
|
||||
if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : GetTileOwner(t)) == OLD_OWNER_TOWN) {
|
||||
if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : OldGetTileOwner(t)) == OLD_OWNER_TOWN) {
|
||||
SetTownIndex(t, CalcClosestTownFromTile(t)->index);
|
||||
} else {
|
||||
SetTownIndex(t, 0);
|
||||
|
@ -1139,7 +1143,7 @@ bool AfterLoadGame()
|
|||
if (!IsRoadStop(t)) break;
|
||||
|
||||
if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3));
|
||||
SB(t.m7(), 0, 5, HasBit(t.m6(), 2) ? OWNER_TOWN : GetTileOwner(t));
|
||||
SB(t.m7(), 0, 5, HasBit(t.m6(), 2) ? OWNER_TOWN : OldGetTileOwner(t));
|
||||
SB(t.m3(), 4, 4, t.m1());
|
||||
t.m4() = 0;
|
||||
break;
|
||||
|
@ -1149,7 +1153,7 @@ bool AfterLoadGame()
|
|||
if (((old_bridge && IsBridge(t)) ? (TransportType)GB(t.m5(), 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) {
|
||||
if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3));
|
||||
|
||||
Owner o = GetTileOwner(t);
|
||||
Owner o = OldGetTileOwner(t);
|
||||
SB(t.m7(), 0, 5, o); // road owner
|
||||
SB(t.m3(), 4, 4, o == OLD_OWNER_NONE ? OWNER_TOWN : o); // tram owner
|
||||
}
|
||||
|
@ -1208,7 +1212,7 @@ bool AfterLoadGame()
|
|||
if (GB(t.m5(), 3, 2) == TRANSPORT_RAIL) {
|
||||
MakeRailNormal(
|
||||
t,
|
||||
GetTileOwner(t),
|
||||
OldGetTileOwner(t),
|
||||
axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X,
|
||||
GetRailType(t)
|
||||
);
|
||||
|
@ -1231,10 +1235,10 @@ bool AfterLoadGame()
|
|||
if (!IsTileFlat(t)) {
|
||||
MakeShore(t);
|
||||
} else {
|
||||
if (GetTileOwner(t) == OWNER_WATER) {
|
||||
if (OldGetTileOwner(t) == OWNER_WATER) {
|
||||
MakeSea(t);
|
||||
} else {
|
||||
MakeCanal(t, GetTileOwner(t), Random());
|
||||
MakeCanal(t, OldGetTileOwner(t), Random());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1568,7 +1572,7 @@ bool AfterLoadGame()
|
|||
* be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */
|
||||
if (IsSavegameVersionBefore(SLV_46)) {
|
||||
for (Waypoint *wp : Waypoint::Iterate()) {
|
||||
if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OLD_OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER);
|
||||
if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OLD_OWNER_NONE) && TileHeight(wp->xy) == 0) OldSetTileOwner(wp->xy, OWNER_WATER);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1678,9 +1682,9 @@ bool AfterLoadGame()
|
|||
for (auto t : Map::Iterate()) {
|
||||
if (IsTileType(t, MP_WATER) &&
|
||||
GetWaterTileType(t) == WATER_TILE_CLEAR &&
|
||||
GetTileOwner(t) == OWNER_WATER &&
|
||||
OldGetTileOwner(t) == OWNER_WATER &&
|
||||
TileHeight(t) != 0) {
|
||||
SetTileOwner(t, OWNER_NONE);
|
||||
OldSetTileOwner(t, OWNER_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1828,7 +1832,7 @@ bool AfterLoadGame()
|
|||
if (IsTileType(t, MP_WATER)) {
|
||||
if (GetWaterClass(t) != WATER_CLASS_RIVER) {
|
||||
if (IsWater(t)) {
|
||||
Owner o = GetTileOwner(t);
|
||||
Owner o = OldGetTileOwner(t);
|
||||
if (o == OWNER_WATER) {
|
||||
MakeSea(t);
|
||||
} else {
|
||||
|
@ -1864,7 +1868,7 @@ bool AfterLoadGame()
|
|||
}
|
||||
|
||||
if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) {
|
||||
Owner o = GetTileOwner(t);
|
||||
Owner o = OldGetTileOwner(t);
|
||||
if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) {
|
||||
Backup<CompanyID> cur_company(_current_company, o);
|
||||
ChangeTileOwner(t, o, INVALID_OWNER);
|
||||
|
@ -1883,10 +1887,10 @@ bool AfterLoadGame()
|
|||
if (o < OLD_MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE);
|
||||
}
|
||||
if (IsLevelCrossing(t)) {
|
||||
if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t);
|
||||
if (!Company::IsValidID(OldGetTileOwner(t))) FixOwnerOfRailTrack(t);
|
||||
}
|
||||
} else if (IsPlainRailTile(t)) {
|
||||
if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t);
|
||||
if (!Company::IsValidID(OldGetTileOwner(t))) FixOwnerOfRailTrack(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2473,7 +2477,7 @@ bool AfterLoadGame()
|
|||
/* Add (random) colour to all objects. */
|
||||
if (IsSavegameVersionBefore(SLV_148)) {
|
||||
for (Object *o : Object::Iterate()) {
|
||||
Owner owner = GetTileOwner(o->location.tile);
|
||||
Owner owner = OldGetTileOwner(o->location.tile);
|
||||
o->colour = (owner == OLD_OWNER_NONE) ? static_cast<Colours>(GB(Random(), 0, 4)) : Company::Get(owner)->livery->colour1;
|
||||
}
|
||||
}
|
||||
|
@ -2841,7 +2845,7 @@ bool AfterLoadGame()
|
|||
if (IsSavegameVersionBefore(SLV_172)) {
|
||||
for (auto t : Map::Iterate()) {
|
||||
if (!IsBayRoadStopTile(t)) continue;
|
||||
Owner o = GetTileOwner(t);
|
||||
Owner o = OldGetTileOwner(t);
|
||||
SetRoadOwner(t, RTT_ROAD, o);
|
||||
SetRoadOwner(t, RTT_TRAM, o);
|
||||
}
|
||||
|
@ -3262,6 +3266,15 @@ bool AfterLoadGame()
|
|||
if (IsSavegameVersionBefore(SLV_SCRIPT_RANDOMIZER)) {
|
||||
ScriptObject::InitializeRandomizers();
|
||||
}
|
||||
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
|
||||
for (auto t : Map::Iterate()) {
|
||||
if (IsValidTile(t)
|
||||
&& !IsTileType(t, MP_HOUSE)
|
||||
&& !IsTileType(t, MP_INDUSTRY)) {
|
||||
SetTileOwner(t, OldGetTileOwner(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Company *c : Company::Iterate()) {
|
||||
UpdateCompanyLiveries(c);
|
||||
|
|
|
@ -475,9 +475,11 @@ static const SaveLoad _company_desc[] = {
|
|||
|
||||
SLE_CONDVAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
|
||||
|
||||
SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8),
|
||||
// MYTODO: Fix all the compat issues
|
||||
SLE_CONDCOMPMASK(CompanyProperties, bankrupt_asked, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION),
|
||||
SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8),
|
||||
SLE_CONDVARNAME(CompanyProperties, old_bankrupt_asked, "bankrupt_asked", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
|
||||
SLE_CONDVARNAME(CompanyProperties, old_bankrupt_asked, "bankrupt_asked", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
|
||||
SLE_CONDCOMPMASK(CompanyProperties, bankrupt_asked, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(CompanyProperties, bankrupt_timeout, SLE_INT16),
|
||||
SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, SL_MIN_VERSION, SLV_65),
|
||||
SLE_CONDVAR(CompanyProperties, bankrupt_value, SLE_INT64, SLV_65, SL_MAX_VERSION),
|
||||
|
@ -520,6 +522,9 @@ struct PLYRChunkHandler : ChunkHandler {
|
|||
Company *c = new (index) Company();
|
||||
SlObject(c, slt);
|
||||
_company_colours[index] = c->colour;
|
||||
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
|
||||
c->bankrupt_asked = owner_from_int(c->old_bankrupt_asked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,24 +20,32 @@
|
|||
#include "../safeguards.h"
|
||||
|
||||
static const SaveLoad _engine_desc[] = {
|
||||
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
|
||||
SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
|
||||
SLE_CONDVAR(Engine, age, SLE_INT32, SLV_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, flags, SLE_UINT8),
|
||||
SLE_CONDCOMPMASK(Engine, preview_asked, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION),
|
||||
SLE_VAR(Engine, preview_wait, SLE_UINT8),
|
||||
// MYTODO: Fix all the compatibility here
|
||||
SLE_CONDCOMPMASK(Engine, company_avail, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
|
||||
SLE_CONDVAR(Engine, intro_date, SLE_INT32, SLV_31, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
|
||||
SLE_CONDVAR(Engine, age, SLE_INT32, SLV_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, flags, SLE_UINT8),
|
||||
|
||||
SLE_CONDVARNAME(Engine, old_preview_asked, "preview_asked", SLE_UINT16, SLV_179, SLV_MORE_COMPANIES),
|
||||
SLE_CONDCOMPMASK(Engine, preview_asked, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDVAR(Engine, preview_company, SLE_UINT8, SLV_179, SL_MAX_VERSION),
|
||||
SLE_VAR(Engine, preview_wait, SLE_UINT8),
|
||||
|
||||
SLE_CONDVARNAME(Engine, old_company_avail, "company_avail", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
|
||||
SLE_CONDVARNAME(Engine, old_company_avail, "company_avail", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
|
||||
SLE_CONDCOMPMASK(Engine, company_avail, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDCOMPMASK(Engine, company_hidden, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(Engine, old_company_hidden, "company_hidden", SLE_UINT16, SLV_193, SLV_MORE_COMPANIES),
|
||||
SLE_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION),
|
||||
};
|
||||
|
||||
|
@ -111,6 +119,11 @@ struct ENGNChunkHandler : ChunkHandler {
|
|||
e->preview_company = INVALID_COMPANY;
|
||||
e->preview_asked = MAX_UVALUE(CompanyMask);
|
||||
}
|
||||
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
|
||||
e->preview_asked = owner_from_int(e->old_preview_asked);
|
||||
e->company_avail = owner_from_int(e->old_company_avail);
|
||||
e->company_hidden = owner_from_int(e->old_company_hidden);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -44,8 +44,10 @@
|
|||
#include "../fios.h"
|
||||
#include "../error.h"
|
||||
#include "company_type.h"
|
||||
#include "core/bitmath_func.hpp"
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
@ -1114,61 +1116,56 @@ static void SlArray(void *array, size_t length, VarType conv)
|
|||
|
||||
|
||||
// MYTODO: Put this somewhere it belongs
|
||||
std::vector<uint8_t> bitset_to_bytes(const CompanyMask& bs)
|
||||
std::vector<uint8_t> bitset_to_bytes(const CompanyMask& mask)
|
||||
{
|
||||
int N = COMPANY_SIZE_BITS;
|
||||
std::vector<unsigned char> result((N + 7) >> 3);
|
||||
for (int j=0; j<int(N); j++)
|
||||
result[j>>3] |= (bs[j] << (j & 7));
|
||||
std::vector<unsigned char> result((MAX_COMPANIES + 7) >> 3);
|
||||
for (int j = 0; j < MAX_COMPANIES; j++)
|
||||
result[j>>3] |= (mask[j] << (j & 7));
|
||||
return result;
|
||||
}
|
||||
|
||||
CompanyMask bitset_from_bytes(const std::vector<uint8_t>& buf)
|
||||
{
|
||||
size_t N = COMPANY_SIZE_BITS;
|
||||
assert(buf.size() == ((N + 7) >> 3));
|
||||
CompanyMask bitset_from_bytes(const std::vector<uint8_t>& buf) {
|
||||
CompanyMask result;
|
||||
for (int j=0; j<int(N); j++)
|
||||
for (int j=0; j < MAX_COMPANIES; j++)
|
||||
result[j] = ((buf[j>>3] >> (j & 7)) & 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
CompanyMask owner_from_int(uint16_t old_owner) {
|
||||
CompanyMask result;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
result[i] = GB(old_owner, i, 1) & 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save/Load the length of the bitset followed by the array of SL_VAR bits.
|
||||
* @param array The array being manipulated
|
||||
* @param length The length of the bitset in bytes,
|
||||
*/
|
||||
static void SlCompanyMask(void *array, size_t length, VarType conv)
|
||||
static void SlCompanyMask(void *array, size_t byte_length, VarType conv)
|
||||
{
|
||||
switch (_sl.action) {
|
||||
case SLA_SAVE: {
|
||||
CompanyMask *bs = static_cast<CompanyMask *>(array);
|
||||
// We don't save the number of bits in the company mask,
|
||||
// because it's incompatible with other versions anyway
|
||||
std::vector<uint8_t> bytes = bitset_to_bytes(*bs);
|
||||
uint8_t *bytes_arr = &bytes[0];
|
||||
|
||||
SlWriteArrayLength(bytes.size());
|
||||
SlArray(bytes_arr, bytes.size(), conv);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
case SLA_LOAD_CHECK:
|
||||
case SLA_LOAD: {
|
||||
assert(byte_length == (MAX_COMPANIES + 7) >> 3);
|
||||
|
||||
std::vector<uint8_t> buff(length);
|
||||
std::vector<uint8_t> buff((MAX_COMPANIES + 7) >> 3);
|
||||
SlArray(&buff[0], byte_length, conv);
|
||||
|
||||
SlArray(&buff[0], length, conv);
|
||||
|
||||
CompanyMask res = bitset_from_bytes(buff);
|
||||
CompanyMask *bs = static_cast<CompanyMask *>(array);
|
||||
for (int i = 0; i < COMPANY_SIZE_BITS; i++) {
|
||||
(*bs)[i] = res[i];
|
||||
}
|
||||
|
||||
*bs = bitset_from_bytes(buff); // we don't want to write direc
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2248,10 +2245,12 @@ static void SlLoadCheckChunks()
|
|||
const ChunkHandler *ch;
|
||||
|
||||
for (id = SlReadUint32(); id != 0; id = SlReadUint32()) {
|
||||
Debug(sl, 2, "Loading chunk {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id);
|
||||
Debug(sl, 2, "Loading chunk (for checking) {:c}{:c}{:c}{:c}", id >> 24, id >> 16, id >> 8, id);
|
||||
|
||||
ch = SlFindChunkHandler(id);
|
||||
if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
|
||||
if (ch == nullptr) {
|
||||
SlErrorCorrupt("Unknown chunk type");
|
||||
}
|
||||
SlLoadCheckChunk(*ch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -381,6 +381,7 @@ enum SaveLoadVersion : uint16_t {
|
|||
|
||||
SLV_COMPANY_ALLOW_LIST, ///< 335 PR#12337 Saving of list of client keys that are allowed to join this company.
|
||||
SLV_GROUP_NUMBERS, ///< 336 PR#12297 Add per-company group numbers.
|
||||
SLV_MORE_COMPANIES, /// Added more companies MYTODO: Fix this comment
|
||||
|
||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||
};
|
||||
|
@ -1003,16 +1004,16 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng
|
|||
*/
|
||||
#define SLE_ARRNAME(base, variable, name, type, length) SLE_CONDARRNAME(base, variable, name, type, length, SL_MIN_VERSION, SL_MAX_VERSION)
|
||||
|
||||
|
||||
/**
|
||||
* Storage of a fixed-size array of #SL_VAR elements in some savegame versions.
|
||||
* @param base Name of the class or struct containing the array.
|
||||
* Storage of a company mask bitset of #MAX_COMPANIES bits in some savegame versions.
|
||||
* @param base Name of the class or struct containing the company mask.
|
||||
* @param variable Name of the variable in the class or struct referenced by \a base.
|
||||
* @param type Storage of the data in memory and in the savegame.
|
||||
* @param length Number of elements in the array.
|
||||
* @param bit_length Number of bits in the serialized form.
|
||||
* @param from First savegame version that has the array.
|
||||
* @param to Last savegame version that has the array.
|
||||
*/
|
||||
#define SLE_CONDCOMPMASK(base, variable, type, length, from, to) SLE_GENERAL(SL_COMPANY_MASK, base, variable, type, length, from, to, 0)
|
||||
#define SLE_CONDCOMPMASK(base, variable, bit_length, from, to) SLE_GENERAL(SL_COMPANY_MASK, base, variable, SLE_CHAR, (bit_length + 7) >> 3, from, to, 0)
|
||||
|
||||
/**
|
||||
* Storage of a \c std::string in every savegame version.
|
||||
|
@ -1313,6 +1314,7 @@ void SlCopy(void *object, size_t length, VarType conv);
|
|||
std::vector<SaveLoad> SlTableHeader(const SaveLoadTable &slt);
|
||||
std::vector<SaveLoad> SlCompatTableHeader(const SaveLoadTable &slt, const SaveLoadCompatTable &slct);
|
||||
void SlObject(void *object, const SaveLoadTable &slt);
|
||||
CompanyMask owner_from_int(uint16_t old_owner);
|
||||
|
||||
bool SaveloadCrashWithMissingNewGRFs();
|
||||
|
||||
|
|
|
@ -215,11 +215,14 @@ static const SaveLoad _town_desc[] = {
|
|||
SLE_CONDSSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, SLV_84, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Town, flags, SLE_UINT8),
|
||||
// MYTODO: Fix all the compat
|
||||
SLE_CONDCOMPMASK(Town, statues, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(Town, old_statues, "statues", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
|
||||
SLE_CONDVARNAME(Town, old_statues, "statues", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
|
||||
SLE_CONDCOMPMASK(Town, statues, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
|
||||
|
||||
SLE_CONDCOMPMASK(Town, have_ratings, MAX_COMPANIES, SLV_MORE_COMPANIES, SL_MAX_VERSION),
|
||||
SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
|
||||
SLE_CONDVARNAME(Town, old_have_ratings, "have_ratings", SLE_UINT16, SLV_104, SLV_MORE_COMPANIES),
|
||||
|
||||
// MYTODO: Fix all the compat
|
||||
SLE_CONDCOMPMASK(Town, have_ratings, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION),
|
||||
SLE_CONDARR(Town, ratings, SLE_INT16, 8, SL_MIN_VERSION, SLV_104),
|
||||
SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, SLV_104, SL_MAX_VERSION),
|
||||
SLE_CONDARR(Town, unwanted, SLE_INT8, 8, SLV_4, SLV_104),
|
||||
|
@ -306,6 +309,10 @@ struct CITYChunkHandler : ChunkHandler {
|
|||
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) {
|
||||
SlErrorCorrupt("Invalid town name generator");
|
||||
}
|
||||
if (IsSavegameVersionBefore(SLV_MORE_COMPANIES)) {
|
||||
t->statues = owner_from_int(t->old_statues);
|
||||
t->have_ratings = owner_from_int(t->old_have_ratings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "subsidy_type.h"
|
||||
#include "newgrf_storage.h"
|
||||
#include "cargotype.h"
|
||||
#include <cstdint>
|
||||
|
||||
template <typename T>
|
||||
struct BuildingCounts {
|
||||
|
@ -68,9 +69,11 @@ struct Town : TownPool::PoolItem<&_town_pool> {
|
|||
uint16_t noise_reached; ///< level of noise that all the airports are generating
|
||||
|
||||
CompanyMask statues; ///< which companies have a statue?
|
||||
uint16_t old_statues;
|
||||
|
||||
/* Company ratings. */
|
||||
CompanyMask have_ratings; ///< which companies have a rating
|
||||
uint16_t old_have_ratings;
|
||||
uint8_t unwanted[MAX_COMPANIES]; ///< how many months companies aren't wanted by towns (bribe)
|
||||
CompanyID exclusivity; ///< which company has exclusivity
|
||||
uint8_t exclusive_counter; ///< months till the exclusivity expires
|
||||
|
|
Loading…
Reference in New Issue