1
0
Fork 0

IT WORKS (somewhat)

pull/12767/head
Andrii Dokhniak 2024-05-31 21:35:39 +02:00
parent 143581b9e0
commit da726f6d29
22 changed files with 264 additions and 32 deletions

View File

@ -12,6 +12,7 @@
#include "cargo_type.h"
#include "company_func.h"
#include "company_type.h"
#include "industry.h"
#include "town.h"
#include "core/overflowsafe_type.hpp"
@ -24,12 +25,12 @@ struct Station;
* - bits 0-15 town or industry number
* - bit 16 is set if it is an industry number (else it is a town number).
* - bits 19-23 Cargo type.
* - bits 24-31 %Company number.
* - bits 24-COMPANY_BIT_SIZE %Company number.
*/
typedef uint32_t CargoMonitorID; ///< Type of the cargo monitor number.
typedef uint64_t CargoMonitorID; ///< Type of the cargo monitor number.
/** Map type for storing and updating active cargo monitor numbers and their amounts. */
typedef std::map<CargoMonitorID, OverflowSafeInt32> CargoMonitorMap;
typedef std::map<CargoMonitorID, OverflowSafeInt64> CargoMonitorMap;
extern CargoMonitorMap _cargo_pickups;
extern CargoMonitorMap _cargo_deliveries;
@ -44,9 +45,11 @@ enum CargoCompanyBits {
CCB_CARGO_TYPE_START = 19, ///< Start bit of the cargo type field.
CCB_CARGO_TYPE_LENGTH = 6, ///< Number of bits of the cargo type field.
CCB_COMPANY_START = 25, ///< Start bit of the company field.
CCB_COMPANY_LENGTH = 8, ///< Number of bits of the company field.
CCB_COMPANY_LENGTH = COMPANY_SIZE_BITS, ///< Number of bits of the company field.
};
static_assert(CCB_COMPANY_LENGTH <= (1 << 30)); // This should never be a limiting factor
static_assert(NUM_CARGO <= (1 << CCB_CARGO_TYPE_LENGTH));
static_assert(MAX_COMPANIES <= (1 << CCB_COMPANY_LENGTH));
@ -63,7 +66,7 @@ inline CargoMonitorID EncodeCargoIndustryMonitor(CompanyID company, CargoID ctyp
assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH));
assert(company < (1 << CCB_COMPANY_LENGTH));
uint32_t ret = 0;
uint64_t ret = 0;
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, ind);
SetBit(ret, CCB_IS_INDUSTRY_BIT);
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype);
@ -83,7 +86,7 @@ inline CargoMonitorID EncodeCargoTownMonitor(CompanyID company, CargoID ctype, T
assert(ctype < (1 << CCB_CARGO_TYPE_LENGTH));
assert(company < (1 << CCB_COMPANY_LENGTH));
uint32_t ret = 0;
uint64_t ret = 0;
SB(ret, CCB_TOWN_IND_NUMBER_START, CCB_TOWN_IND_NUMBER_LENGTH, town);
SB(ret, CCB_CARGO_TYPE_START, CCB_CARGO_TYPE_LENGTH, ctype);
SB(ret, CCB_COMPANY_START, CCB_COMPANY_LENGTH, company);

View File

@ -260,7 +260,6 @@ inline void MakeClear(Tile t, ClearGround g, uint density)
{
SetTileType(t, MP_CLEAR);
t.m1() = 0;
SetTileOwner(t, OWNER_NONE);
t.m2() = 0;
t.m3() = 0;
t.m4() = 0 << 5 | 0 << 2;
@ -268,6 +267,8 @@ inline void MakeClear(Tile t, ClearGround g, uint density)
t.m6() = 0;
t.m7() = 0;
t.m8() = 0;
t.m9() = 0;
SetTileOwner(t, OWNER_NONE);
}
@ -281,7 +282,6 @@ inline void MakeField(Tile t, uint field_type, IndustryID industry)
{
SetTileType(t, MP_CLEAR);
t.m1() = 0;
SetTileOwner(t, OWNER_NONE);
t.m2() = industry;
t.m3() = field_type;
t.m4() = 0 << 5 | 0 << 2;
@ -289,6 +289,8 @@ inline void MakeField(Tile t, uint field_type, IndustryID industry)
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
t.m8() = 0;
t.m9() = 0;
SetTileOwner(t, OWNER_NONE);
}
/**

View File

@ -7,6 +7,7 @@
/** @file company_cmd.cpp Handling of companies. */
#include "company_type.h"
#include "gfx_type.h"
#include "stdafx.h"
#include "company_base.h"

View File

@ -11,6 +11,7 @@
#define COMPANY_TYPE_H
#include "core/enum_type.hpp"
#include <bitset>
/**
* Enum for all companies/owners.
@ -40,6 +41,15 @@ enum Owner : uint8_t {
COMPANY_NEW_COMPANY = 0xF8, ///< The client wants a new company
COMPANY_SPECTATOR = 0xF9, ///< The client is spectating
};
const uint8_t COMPANY_SIZE_BITS = 8; /// Size of the company id in bits
static_assert(COMPANY_SIZE_BITS <= 10); /// 32bit m9 can only fit 3 owners of size 10
static_assert(MAX_COMPANIES <= (1U << COMPANY_SIZE_BITS) - 1); /// Checking that MAX_COMPANIES is in bounds
static_assert(OWNER_END <= (1U << COMPANY_SIZE_BITS) - 1);
static_assert(INVALID_OWNER <= (1U << COMPANY_SIZE_BITS) - 1);
static_assert(INVALID_COMPANY <= (1U << COMPANY_SIZE_BITS) - 1);
DECLARE_POSTFIX_INCREMENT(Owner)
DECLARE_ENUM_AS_ADDABLE(Owner)
@ -53,7 +63,7 @@ static const uint MAX_COMPETITORS_INTERVAL = 500; ///< The maximum interval (in
typedef Owner CompanyID;
typedef uint16_t CompanyMask;
typedef std::bitset<MAX_COMPANIES> CompanyMask;
struct Company;
typedef uint32_t CompanyManagerFace; ///< Company manager face bits, info see in company_manager_face.h

View File

@ -940,7 +940,7 @@ static IntervalTimer<TimerGameCalendar> _calendar_engines_daily({TimerGameCalend
CloseWindowById(WC_ENGINE_PREVIEW, i);
e->preview_company = INVALID_COMPANY;
}
} else if (CountBits(e->preview_asked) < MAX_COMPANIES) {
} else if (e->preview_asked.count() < MAX_COMPANIES) {
e->preview_company = GetPreviewCompany(e);
if (e->preview_company == INVALID_COMPANY) {
@ -969,7 +969,7 @@ static IntervalTimer<TimerGameCalendar> _calendar_engines_daily({TimerGameCalend
void ClearEnginesHiddenFlagOfCompany(CompanyID cid)
{
for (Engine *e : Engine::Iterate()) {
SB(e->company_hidden, cid, 1, 0);
e->company_hidden.reset(cid);
}
}
@ -987,7 +987,7 @@ CommandCost CmdSetVehicleVisibility(DoCommandFlag flags, EngineID engine_id, boo
if (!IsEngineBuildable(e->index, e->type, _current_company)) return CMD_ERROR;
if ((flags & DC_EXEC) != 0) {
SB(e->company_hidden, _current_company, 1, hide ? 1 : 0);
e->company_hidden.set(_current_company, hide ? 1 : 0);
AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
}

View File

@ -7,6 +7,7 @@
/** @file graph_gui.cpp GUI that shows performance graphs. */
#include "company_type.h"
#include "stdafx.h"
#include "graph_gui.h"
#include "window_gui.h"
@ -182,7 +183,7 @@ protected:
static const int MIN_GRAPH_NUM_LINES_Y = 9; ///< Minimal number of horizontal lines to draw.
static const int MIN_GRID_PIXEL_SIZE = 20; ///< Minimum distance between graph lines.
uint64_t excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
CompanyMask excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
uint8_t num_dataset;
uint8_t num_on_x_axis;
uint8_t num_vert_lines;

View File

@ -10,6 +10,8 @@
#ifndef MAP_FUNC_H
#define MAP_FUNC_H
#include "company_type.h"
#include "core/bitmath_func.hpp"
#include "core/math_func.hpp"
#include "tile_type.h"
#include "map_type.h"
@ -33,7 +35,7 @@ private:
uint8_t type; ///< The type (bits 4..7), bridges (2..3), rainforest/desert (0..1)
uint8_t height; ///< The height of the northern corner.
uint16_t m2; ///< Primarily used for indices to towns, industries and stations
uint8_t m1; ///< Primarily used for ownership information
uint8_t m1; ///< Primarily used for ownership information (In old versions)
uint8_t m3; ///< General purpose
uint8_t m4; ///< General purpose
uint8_t m5; ///< General purpose
@ -49,6 +51,7 @@ private:
uint8_t m6; ///< General purpose
uint8_t m7; ///< Primarily used for newgrf support
uint16_t m8; ///< General purpose
uint32_t m9; ///< Stores the actuall ownership information
};
static TileBase *base_tiles; ///< Pointer to the tile-array.
@ -198,6 +201,18 @@ public:
{
return extended_tiles[tile.base()].m8;
}
/**
* Primarily used for ownership information
* TODO: Add more docs
* Look at docs/landscape.html for the exact meaning of the data.
* @param tile The tile to get the data for.
* @return reference to the byte holding the data.
*/
debug_inline uint32_t &m9()
{
return extended_tiles[tile.base()].m9;
}
};
/**

View File

@ -129,6 +129,7 @@ public:
Debug(misc, LANDINFOD_LEVEL, "m6 = 0x{:x}", tile.m6());
Debug(misc, LANDINFOD_LEVEL, "m7 = 0x{:x}", tile.m7());
Debug(misc, LANDINFOD_LEVEL, "m8 = 0x{:x}", tile.m8());
Debug(misc, LANDINFOD_LEVEL, "m9 = 0x{:x}", tile.m9());
PrintWaterRegionDebugInfo(tile);
#undef LANDINFOD_LEVEL

View File

@ -83,8 +83,9 @@
case 0xAB: return GB(this->t->ratings[6], 8, 8);
case 0xAC: return this->t->ratings[7];
case 0xAD: return GB(this->t->ratings[7], 8, 8);
case 0xAE: return this->t->have_ratings;
case 0xB2: return this->t->statues;
// MYTODO: Fix this crap later
//case 0xAE: return this->t->have_ratings;
//case 0xB2: return this->t->statues;
case 0xB6: return ClampTo<uint16_t>(this->t->cache.num_houses);
case 0xB9: return this->t->growth_rate / Ticks::TOWN_GROWTH_TICKS;
case 0xBA: cid = GetCargoIDByLabel(CT_PASSENGERS); return IsValidCargoID(cid) ? ClampTo<uint16_t>(this->t->supplied[cid].new_max) : 0;

View File

@ -528,6 +528,7 @@ inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r)
SB(t.m6(), 2, 4, 0);
t.m7() = 0;
t.m8() = r;
t.m9() = 0;
}
/**
@ -561,6 +562,7 @@ inline void MakeRailDepot(Tile tile, Owner owner, DepotID depot_id, DiagDirectio
SB(tile.m6(), 2, 4, 0);
tile.m7() = 0;
tile.m8() = rail_type;
tile.m9() = 0;
}
#endif /* RAIL_MAP_H */

View File

@ -10,6 +10,7 @@
#ifndef ROAD_MAP_H
#define ROAD_MAP_H
#include "company_type.h"
#include "track_func.h"
#include "depot_type.h"
#include "rail_type.h"
@ -231,7 +232,7 @@ inline bool HasTileAnyRoadType(Tile t, RoadTypes rts)
* @param rtt RoadTramType.
* @return Owner of the given road type.
*/
inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
inline Owner OldGetRoadOwner(Tile t, RoadTramType rtt)
{
assert(MayHaveRoad(t));
if (rtt == RTT_ROAD) return (Owner)GB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5);
@ -242,6 +243,21 @@ inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
return o == OWNER_TOWN ? OWNER_NONE : o;
}
/**
* Get the owner of a specific road type.
* @param t The tile to query.
* @param rtt RoadTramType.
* @return Owner of the given road type.
*/
inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
{
assert(MayHaveRoad(t));
if (rtt == RTT_ROAD) return (Owner)GB(t.m9(), IsNormalRoadTile(t) ? 0 : COMPANY_SIZE_BITS * 2, COMPANY_SIZE_BITS);
Owner o = (Owner)GB(t.m9(), COMPANY_SIZE_BITS, COMPANY_SIZE_BITS);
return o == OWNER_TOWN ? OWNER_NONE : o;
}
/**
* Set the owner of a specific road type.
* @param t The tile to change.
@ -249,6 +265,21 @@ inline Owner GetRoadOwner(Tile t, RoadTramType rtt)
* @param o New owner of the given road type.
*/
inline void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
{
if (rtt == RTT_ROAD) {
SB(t.m9(), IsNormalRoadTile(t) ? 0 : COMPANY_SIZE_BITS * 2, COMPANY_SIZE_BITS, o);
} else {
SB(t.m9(), COMPANY_SIZE_BITS, COMPANY_SIZE_BITS, o==OWNER_NONE ? OWNER_TOWN : o);
}
}
/**
* Set the owner of a specific road type.
* @param t The tile to change.
* @param rtt RoadTramType.
* @param o New owner of the given road type.
*/
inline void OldSetRoadOwner(Tile t, RoadTramType rtt, Owner o)
{
if (rtt == RTT_ROAD) {
SB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5, o);

View File

@ -451,7 +451,7 @@ static void FixOwnerOfRailTrack(Tile t)
if (IsLevelCrossingTile(t)) {
/* else change the crossing to normal road (road vehicles won't care) */
Owner road = GetRoadOwner(t, RTT_ROAD);
Owner road = GetRoadOwner(t, RTT_ROAD); // TODO: m9
Owner tram = GetRoadOwner(t, RTT_TRAM);
RoadBits bits = GetCrossingRoadBits(t);
bool hasroad = HasBit(t.m7(), 6);

View File

@ -24,7 +24,7 @@ struct TempStorage {
/** Description of the #TempStorage structure for the purpose of load and save. */
static const SaveLoad _cargomonitor_pair_desc[] = {
SLE_VAR(TempStorage, number, SLE_UINT32),
SLE_VAR(TempStorage, number, SLE_UINT64),
SLE_VAR(TempStorage, amount, SLE_UINT32),
};

View File

@ -476,8 +476,8 @@ 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),
SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(CompanyProperties, bankrupt_asked, SLE_UINT16, SLV_104, SL_MAX_VERSION),
// MYTODO: Fix all the compat issues
SLE_CONDCOMPMASK(CompanyProperties, bankrupt_asked, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, 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),

View File

@ -9,6 +9,7 @@
#include "../stdafx.h"
#include "company_type.h"
#include "saveload.h"
#include "compat/engine_sl_compat.h"
@ -32,12 +33,11 @@ static const SaveLoad _engine_desc[] = {
SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
SLE_VAR(Engine, flags, SLE_UINT8),
SLE_CONDVAR(Engine, preview_asked, SLE_UINT16, SLV_179, SL_MAX_VERSION),
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),
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Engine, company_avail, SLE_UINT16, SLV_104, SL_MAX_VERSION),
SLE_CONDVAR(Engine, company_hidden, SLE_UINT16, SLV_193, 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_CONDSSTR(Engine, name, SLE_STR, SLV_84, SL_MAX_VERSION),
};

View File

@ -352,6 +352,33 @@ struct MAP8ChunkHandler : ChunkHandler {
}
};
struct MAP9ChunkHandler : ChunkHandler {
MAP9ChunkHandler() : ChunkHandler('MAP9', CH_RIFF) {}
void Load() const override
{
std::array<uint32_t, MAP_SL_BUF_SIZE> buf;
uint size = Map::Size();
for (TileIndex i = 0; i != size;) {
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m8() = buf[j];
}
}
void Save() const override
{
std::array<uint32_t, MAP_SL_BUF_SIZE> buf;
uint size = Map::Size();
SlSetLength(static_cast<uint32_t>(size) * sizeof(uint32_t));
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m8();
SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT32);
}
}
};
static const MAPSChunkHandler MAPS;
static const MAPTChunkHandler MAPT;
static const MAPHChunkHandler MAPH;
@ -363,6 +390,7 @@ static const MAP5ChunkHandler MAP5;
static const MAPEChunkHandler MAPE;
static const MAP7ChunkHandler MAP7;
static const MAP8ChunkHandler MAP8;
static const MAP8ChunkHandler MAP9;
static const ChunkHandlerRef map_chunk_handlers[] = {
MAPS,
MAPT,
@ -375,6 +403,7 @@ static const ChunkHandlerRef map_chunk_handlers[] = {
MAPE,
MAP7,
MAP8,
MAP9,
};
extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers);

View File

@ -253,6 +253,7 @@ static bool FixTTOMapArray()
break;
case 1: // ROAD_TILE_CROSSING (there aren't monorail crossings in TTO)
tile.m3() = tile.m1(); // set owner of road = owner of rail
// TODO: Fix this
break;
case 2: // ROAD_TILE_DEPOT
break;

View File

@ -20,6 +20,7 @@
* </ol>
*/
#include "saveload/saveload.h"
#include "../stdafx.h"
#include "../debug.h"
#include "../station_base.h"
@ -42,7 +43,11 @@
#include "../string_func.h"
#include "../fios.h"
#include "../error.h"
#include "company_type.h"
#include <atomic>
#include <bitset>
#include <cstdint>
#include <vector>
#ifdef __EMSCRIPTEN__
# include <emscripten.h>
#endif
@ -1105,6 +1110,76 @@ 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)
{
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));
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 result;
for (int j=0; j<int(N); j++)
result[j] = ((buf[j>>3] >> (j & 7)) & 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)
{
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: {
std::vector<uint8_t> buff(length);
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];
}
return;
}
case SLA_PTRS:
case SLA_NULL:
return;
default:
NOT_REACHED();
}
}
/**
* Pointers cannot be saved to a savegame, so this functions gets
* the index of the item, and if not available, it hussles with
@ -1513,6 +1588,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld)
case SL_VAR: return SlCalcConvFileLen(sld.conv);
case SL_REF: return SlCalcRefLen();
case SL_ARR: return SlCalcArrayLen(sld.length, sld.conv);
case SL_COMPANY_MASK: return SlCalcArrayLen(sld.length, sld.conv);
case SL_REFLIST: return SlCalcRefListLen(GetVariableAddress(object, sld), sld.conv);
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv);
case SL_VECTOR: return SlCalcVectorLen(GetVariableAddress(object, sld), sld.conv);
@ -1568,6 +1644,7 @@ static bool SlObjectMember(void *object, const SaveLoad &sld)
case SL_VAR: SlSaveLoadConv(ptr, conv); break;
case SL_REF: SlSaveLoadRef(ptr, conv); break;
case SL_ARR: SlArray(ptr, sld.length, conv); break;
case SL_COMPANY_MASK: SlCompanyMask(ptr, sld.length, conv); break;
case SL_REFLIST: SlRefList(ptr, conv); break;
case SL_DEQUE: SlDeque(ptr, conv); break;
case SL_VECTOR: SlVector(ptr, conv); break;

View File

@ -690,9 +690,10 @@ enum SaveLoadType : uint8_t {
SL_VECTOR = 7, ///< Save/load a vector of #SL_VAR elements.
SL_REFLIST = 8, ///< Save/load a list of #SL_REF elements.
SL_STRUCTLIST = 9, ///< Save/load a list of structs.
SL_COMPANY_MASK = 10, ///< Save/load a fixed-size bitset of #SL_VAR bits.
SL_SAVEBYTE = 10, ///< Save (but not load) a byte.
SL_NULL = 11, ///< Save null-bytes and load to nowhere.
SL_SAVEBYTE = 11, ///< Save (but not load) a byte.
SL_NULL = 12, ///< Save null-bytes and load to nowhere.
};
typedef void *SaveLoadAddrProc(void *base, size_t extra);
@ -799,6 +800,7 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng
case SL_REF: return sizeof(void *) == size;
case SL_STDSTR: return SlVarSize(type) == size;
case SL_ARR: return SlVarSize(type) * length <= size; // Partial load of array is permitted.
case SL_COMPANY_MASK: return SlVarSize(type) * length <= size; // Partial load of array is permitted.
case SL_DEQUE: return sizeof(std::deque<void *>) == size;
case SL_VECTOR: return sizeof(std::vector<void *>) == size;
case SL_REFLIST: return sizeof(std::list<void *>) == size;
@ -1001,6 +1003,17 @@ 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.
* @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 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)
/**
* Storage of a \c std::string in every savegame version.
* @param base Name of the class or struct containing the string.

View File

@ -215,11 +215,11 @@ 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),
SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Town, statues, SLE_UINT16, SLV_104, SL_MAX_VERSION),
// MYTODO: Fix all the compat
SLE_CONDCOMPMASK(Town, statues, SLE_UINT8, COMPANY_SIZE_BITS, SLV_179, SL_MAX_VERSION),
SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Town, have_ratings, SLE_UINT16, SLV_104, SL_MAX_VERSION),
// 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),

View File

@ -10,6 +10,7 @@
#ifndef TILE_MAP_H
#define TILE_MAP_H
#include "company_type.h"
#include "slope_type.h"
#include "map_func.h"
#include "core/bitmath_func.hpp"
@ -181,6 +182,27 @@ inline Owner GetTileOwner(Tile tile)
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
return (Owner)GB(tile.m9(), 0, COMPANY_SIZE_BITS);
}
/**
* Returns the owner of a tile. Only used for legacy code
*
* This function returns the owner of a tile. This cannot used
* for tiles which type is one of MP_HOUSE, MP_VOID and MP_INDUSTRY
* as no company owned any of these buildings.
*
* @param tile The tile to check
* @return The owner of the tile
* @pre IsValidTile(tile)
* @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY
*/
inline Owner OldGetTileOwner(Tile tile)
{
assert(IsValidTile(tile));
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
return (Owner)GB(tile.m1(), 0, 5);
}
@ -201,9 +223,30 @@ inline void SetTileOwner(Tile tile, Owner owner)
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
SB(tile.m9(), 0, COMPANY_SIZE_BITS, owner);
}
/**
* Sets the owner of a tile (Only for old formats)
*
* This function sets the owner status of a tile. Note that you cannot
* set a owner for tiles of type MP_HOUSE, MP_VOID and MP_INDUSTRY.
*
* @param tile The tile to change the owner status.
* @param owner The new owner.
* @pre IsValidTile(tile)
* @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY
*/
inline void OldSetTileOwner(Tile tile, Owner owner)
{
assert(IsValidTile(tile));
assert(!IsTileType(tile, MP_HOUSE));
assert(!IsTileType(tile, MP_INDUSTRY));
SB(tile.m1(), 0, 5, owner);
}
/**
* Checks if a tile belongs to the given owner
*

View File

@ -27,6 +27,8 @@ inline void MakeVoid(Tile t)
t.m5() = 0;
t.m6() = 0;
t.m7() = 0;
t.m8() = 0;
t.m9() = 0;
}
#endif /* VOID_MAP_H */