Merge branch 'master' into jgrpp-beta

# Conflicts:
#	src/lang/spanish.txt
#	src/network/core/tcp_content_type.h
#	src/network/network_content.cpp
#	src/saveload/cheat_sl.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/saveload/station_sl.cpp
#	src/saveload/vehicle_sl.cpp
#	src/settings.cpp
#	src/settings_internal.h
#	src/table/settings.h.preamble
#	src/table/settings/company_settings.ini
#	src/table/settings/currency_settings.ini
#	src/table/settings/gameopt_settings.ini
#	src/table/settings/misc_settings.ini
#	src/table/settings/settings.ini
#	src/table/settings/win32_settings.ini
#	src/table/settings/window_settings.ini
pull/332/head
Jonathan G Rennison 3 years ago
commit 81290df946

@ -189,8 +189,8 @@ static const CheatEntry _cheats_ui[] = {
{CNM_LOCAL_ONLY, SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat },
{CNM_LOCAL_ONLY, SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.map_height_limit, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat },
{CNM_LOCAL_ONLY, SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_date_ymd.year, &_cheats.change_date.been_used, &ClickChangeDateCheat },
{CNM_ALL, SLF_NOT_IN_SAVE, STR_CHEAT_INFLATION_COST, &_economy.inflation_prices, &_extra_cheats.inflation_cost.been_used, nullptr },
{CNM_ALL, SLF_NOT_IN_SAVE, STR_CHEAT_INFLATION_INCOME, &_economy.inflation_payment, &_extra_cheats.inflation_income.been_used, nullptr },
{CNM_ALL, SLF_ALLOW_CONTROL, STR_CHEAT_INFLATION_COST, &_economy.inflation_prices, &_extra_cheats.inflation_cost.been_used, nullptr },
{CNM_ALL, SLF_ALLOW_CONTROL, STR_CHEAT_INFLATION_INCOME, &_economy.inflation_payment, &_extra_cheats.inflation_income.been_used, nullptr },
{CNM_ALL, SLE_BOOL, STR_CHEAT_STATION_RATING, &_extra_cheats.station_rating.value, &_extra_cheats.station_rating.been_used, nullptr },
{CNM_ALL, SLE_BOOL, STR_CHEAT_TOWN_RATING, &_extra_cheats.town_rating.value, &_extra_cheats.town_rating.been_used, nullptr },
};
@ -261,7 +261,7 @@ struct CheatWindow : Window {
DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2);
switch (ce->type) {
case SLF_NOT_IN_SAVE: {
case SLF_ALLOW_CONTROL: {
/* Change inflation factors */
/* Draw [<][>] boxes for settings of an integer-type */
@ -324,7 +324,7 @@ struct CheatWindow : Window {
if (!IsCheatAllowed(ce->mode)) continue;
lines++;
switch (ce->type) {
case SLF_NOT_IN_SAVE:
case SLF_ALLOW_CONTROL:
/* Change inflation factors */
break;
@ -401,7 +401,7 @@ struct CheatWindow : Window {
SetDParam(0, value);
ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MONEY_QUERY_CAPT, 20, this, CS_NUMERAL_SIGNED, QSF_ACCEPT_UNCHANGED);
return;
} else if (ce->type == SLF_NOT_IN_SAVE && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) {
} else if (ce->type == SLF_ALLOW_CONTROL && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) {
clicked_widget = btn;
uint64 val = (uint64)ReadValue(ce->variable, SLE_UINT64);
SetDParam(0, val * 1000 >> 16);
@ -420,7 +420,7 @@ struct CheatWindow : Window {
if (!_networking) *ce->been_used = true;
switch (ce->type) {
case SLF_NOT_IN_SAVE: {
case SLF_ALLOW_CONTROL: {
/* Change inflation factors */
uint64 value = (uint64)ReadValue(ce->variable, SLE_UINT64) + (((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1) << 16);
value = Clamp<uint64>(value, 1 << 16, MAX_INFLATION);
@ -468,7 +468,7 @@ struct CheatWindow : Window {
const CheatEntry *ce = &_cheats_ui[clicked_widget];
if (ce->type == SLF_NOT_IN_SAVE) {
if (ce->type == SLF_ALLOW_CONTROL) {
char tmp_buffer[32];
strecpy(tmp_buffer, str, lastof(tmp_buffer));
str_replace_wchar(tmp_buffer, lastof(tmp_buffer), GetDecimalSeparatorChar(), '.');

@ -28,12 +28,9 @@ struct Cheats {
Cheat switch_company; ///< change to another company
Cheat money; ///< get rich or poor
Cheat crossing_tunnels; ///< allow tunnels that cross each other
Cheat dummy1; ///< empty cheat (build while in pause mode)
Cheat no_jetcrash; ///< no jet will crash on small airports anymore
Cheat dummy2; ///< empty cheat (change the climate of the map)
Cheat change_date; ///< changes date ingame
Cheat setup_prod; ///< setup raw-material production in game
Cheat dummy3; ///< empty cheat (enable running el-engines on normal rail)
Cheat edit_max_hl; ///< edit the maximum heightlevel; this is a cheat because of the fact that it needs to reset NewGRF game state and doing so as a simple configuration breaks the expectation of many
};

@ -1995,7 +1995,7 @@ static void OutputContentState(const ContentInfo *const ci)
char buf[sizeof(ci->md5sum) * 2 + 1];
md5sumToString(buf, lastof(buf), ci->md5sum);
IConsolePrintF(state_to_colour[ci->state], "%d, %s, %s, %s, %08X, %s", ci->id, types[ci->type - 1], states[ci->state], ci->name, ci->unique_id, buf);
IConsolePrintF(state_to_colour[ci->state], "%d, %s, %s, %s, %08X, %s", ci->id, types[ci->type - 1], states[ci->state], ci->name.c_str(), ci->unique_id, buf);
}
DEF_CONSOLE_CMD(ConContent)
@ -2065,7 +2065,7 @@ DEF_CONSOLE_CMD(ConContent)
if (strcasecmp(argv[1], "state") == 0) {
IConsolePrintF(CC_WHITE, "id, type, state, name");
for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) {
if (argc > 2 && strcasestr((*iter)->name, argv[2]) == nullptr) continue;
if (argc > 2 && strcasestr((*iter)->name.c_str(), argv[2]) == nullptr) continue;
OutputContentState(*iter);
}
return true;

@ -2213,7 +2213,7 @@ STR_NETWORK_ERROR_CLIENT_START :{WHITE}No se pu
STR_NETWORK_ERROR_TIMEOUT :{WHITE}Tiempo de espera agotado en conexión #{NUM}
STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Se ha producido un error de protocolo y la conexión ha sido cerrada
STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}No se ha establecido tu nombre de jugador. El nombre se puede establecer en la parte superior de la ventana de Multijugador
STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}No se ha establecido el nombre de tu servidor. El nombre se puede establecer en la parte superior de la ventana de Multijugador
STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}El nombre de tu servidor no se ha definido. El nombre puede definirse al principio de la ventana de Multijugador
STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}La versión de este cliente no corresponde con la versión del servidor
STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Contraseña incorrecta
STR_NETWORK_ERROR_SERVER_FULL :{WHITE}El servidor está completo

@ -67,6 +67,12 @@ static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maxim
static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0'
static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = COMPAT_MTU-3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes)
static const uint NETWORK_CHAT_LENGTH = 900; ///< The maximum length of a chat message, in bytes including '\0'
static const uint NETWORK_CONTENT_FILENAME_LENGTH = 48; ///< The maximum length of a content's filename, in bytes including '\0'.
static const uint NETWORK_CONTENT_NAME_LENGTH = 64; ///< The maximum length of a content's name, in bytes including '\0'.
static const uint NETWORK_CONTENT_VERSION_LENGTH = 16; ///< The maximum length of a content's version, in bytes including '\0'.
static const uint NETWORK_CONTENT_URL_LENGTH = 96; ///< The maximum length of a content's url, in bytes including '\0'.
static const uint NETWORK_CONTENT_DESC_LENGTH = 512; ///< The maximum length of a content's description, in bytes including '\0'.
static const uint NETWORK_CONTENT_TAG_LENGTH = 32; ///< The maximum length of a content's tag, in bytes including '\0'.
static const uint NETWORK_GRF_NAME_LENGTH = 80; ///< Maximum length of the name of a GRF

@ -373,37 +373,6 @@ uint64 Packet::Recv_uint64()
return n;
}
/**
* Reads a string till it finds a '\0' in the stream.
* @param buffer The buffer to put the data into.
* @param size The size of the buffer.
* @param settings The string validation settings.
*/
void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings settings)
{
char *bufp = buffer;
const char *last = buffer + size - 1;
/* Don't allow reading from a closed socket */
if (cs->HasClientQuit()) return;
size_t pos = this->pos;
while (--size > 0 && pos < this->Size() && (*buffer++ = this->buffer[pos++]) != '\0') {}
if (size == 0 || pos == this->Size()) {
*buffer = '\0';
/* If size was sooner to zero then the string in the stream
* skip till the \0, so than packet can be read out correctly for the rest */
while (pos < this->Size() && this->buffer[pos] != '\0') pos++;
pos++;
}
assert(pos <= std::numeric_limits<PacketSize>::max());
this->pos = static_cast<PacketSize>(pos);
StrMakeValidInPlace(bufp, last, settings);
}
/**
* Reads characters (bytes) from the packet until it finds a '\0', or reaches a
* maximum of \c length characters.

@ -87,7 +87,6 @@ public:
uint16 Recv_uint16();
uint32 Recv_uint32();
uint64 Recv_uint64();
void Recv_string(char *buffer, size_t size, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
std::string Recv_string(size_t length, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
void Recv_string(std::string &buffer, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
void Recv_binary(char *buffer, size_t size);

@ -20,50 +20,6 @@
#include "../../safeguards.h"
/** Clear everything in the struct */
ContentInfo::ContentInfo()
{
memset(this, 0, sizeof(*this));
}
/** Free everything allocated */
ContentInfo::~ContentInfo()
{
free(this->dependencies);
free(this->tags);
}
/**
* Copy data from other #ContentInfo and take ownership of allocated stuff.
* @param other Source to copy from. #dependencies and #tags will be NULLed.
*/
void ContentInfo::TransferFrom(ContentInfo *other)
{
if (other != this) {
free(this->dependencies);
free(this->tags);
memcpy(this, other, sizeof(ContentInfo));
other->dependencies = nullptr;
other->tags = nullptr;
}
}
/**
* Get the size of the data as send over the network.
* @return the size.
*/
size_t ContentInfo::Size() const
{
size_t len = 0;
for (uint i = 0; i < this->tag_count; i++) len += strlen(this->tags[i]) + 1;
/* The size is never larger than the content info size plus the size of the
* tags and dependencies */
return sizeof(*this) +
sizeof(this->dependency_count) +
sizeof(*this->dependencies) * this->dependency_count;
}
/**
* Is the state either selected or autoselected?
* @return true iff that's the case

@ -26,6 +26,7 @@ enum ContentType {
CONTENT_TYPE_GAME = 9, ///< The content consists of a game script
CONTENT_TYPE_GAME_LIBRARY = 10, ///< The content consists of a GS library
CONTENT_TYPE_END, ///< Helper to mark the end of the types
INVALID_CONTENT_TYPE = 0xFF, ///< Invalid/uninitialized content
};
/** Enum with all types of TCP content packets. The order MUST not be changed **/
@ -57,29 +58,21 @@ struct ContentInfo {
INVALID, ///< The content's invalid
};
ContentType type; ///< Type of content
ContentID id; ///< Unique (server side) ID for the content
uint32 filesize; ///< Size of the file
char filename[48]; ///< Filename (for the .tar.gz; only valid on download)
char name[64]; ///< Name of the content
char version[16]; ///< Version of the content
char url[96]; ///< URL related to the content
char description[512]; ///< Description of the content
uint32 unique_id; ///< Unique ID; either GRF ID or shortname
byte md5sum[16]; ///< The MD5 checksum
uint8 dependency_count; ///< Number of dependencies
ContentID *dependencies; ///< Malloced array of dependencies (unique server side ids)
uint8 tag_count; ///< Number of tags
char (*tags)[32]; ///< Malloced array of tags (strings)
State state; ///< Whether the content info is selected (for download)
bool upgrade; ///< This item is an upgrade
ContentType type = INVALID_CONTENT_TYPE; ///< Type of content
ContentID id = INVALID_CONTENT_ID; ///< Unique (server side) ID for the content
uint32 filesize = 0; ///< Size of the file
std::string filename; ///< Filename (for the .tar.gz; only valid on download)
std::string name; ///< Name of the content
std::string version; ///< Version of the content
std::string url; ///< URL related to the content
std::string description; ///< Description of the content
uint32 unique_id = 0; ///< Unique ID; either GRF ID or shortname
byte md5sum[16] = {0}; ///< The MD5 checksum
std::vector<ContentID> dependencies; ///< The dependencies (unique server side ids)
StringList tags; ///< Tags associated with the content
State state = State::UNSELECTED; ///< Whether the content info is selected (for download)
bool upgrade = false; ///< This item is an upgrade
ContentInfo();
~ContentInfo();
void TransferFrom(ContentInfo *other);
size_t Size() const;
bool IsSelected() const;
bool IsValid() const;
const char *GetTextfile(TextfileType type) const;

@ -56,26 +56,27 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
ci->id = (ContentID)p->Recv_uint32();
ci->filesize = p->Recv_uint32();
p->Recv_string(ci->name, lengthof(ci->name));
p->Recv_string(ci->version, lengthof(ci->version));
p->Recv_string(ci->url, lengthof(ci->url));
p->Recv_string(ci->description, lengthof(ci->description), SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE);
ci->name = p->Recv_string(NETWORK_CONTENT_NAME_LENGTH);
ci->version = p->Recv_string(NETWORK_CONTENT_VERSION_LENGTH);
ci->url = p->Recv_string(NETWORK_CONTENT_URL_LENGTH);
ci->description = p->Recv_string(NETWORK_CONTENT_DESC_LENGTH, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE);
ci->unique_id = p->Recv_uint32();
for (uint j = 0; j < sizeof(ci->md5sum); j++) {
ci->md5sum[j] = p->Recv_uint8();
}
ci->dependency_count = p->Recv_uint8();
ci->dependencies = MallocT<ContentID>(ci->dependency_count);
for (uint i = 0; i < ci->dependency_count; i++) {
ci->dependencies[i] = (ContentID)p->Recv_uint32();
this->reverse_dependency_map.insert({ ci->dependencies[i], ci->id });
uint dependency_count = p->Recv_uint8();
ci->dependencies.reserve(dependency_count);
for (uint i = 0; i < dependency_count; i++) {
ContentID cid = (ContentID)p->Recv_uint32();
ci->dependencies.push_back(cid);
this->reverse_dependency_map.insert({ cid, ci->id });
}
ci->tag_count = p->Recv_uint8();
ci->tags = MallocT<char[32]>(ci->tag_count);
for (uint i = 0; i < ci->tag_count; i++) p->Recv_string(ci->tags[i], lengthof(*ci->tags));
uint tag_count = p->Recv_uint8();
ci->tags.reserve(tag_count);
for (uint i = 0; i < tag_count; i++) ci->tags.push_back(p->Recv_string(NETWORK_CONTENT_TAG_LENGTH));
if (!ci->IsValid()) {
delete ci;
@ -146,16 +147,15 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
if (ici->type == ci->type && ici->unique_id == ci->unique_id &&
memcmp(ci->md5sum, ici->md5sum, sizeof(ci->md5sum)) == 0) {
/* Preserve the name if possible */
if (StrEmpty(ci->name)) strecpy(ci->name, ici->name, lastof(ci->name));
if (ci->name.empty()) ci->name = ici->name;
if (ici->IsSelected()) ci->state = ici->state;
/*
* As ici might be selected by the content window we cannot delete that.
* However, we want to keep most of the values of ci, except the values
* we (just) already preserved.
* So transfer data and ownership of allocated memory from ci to ici.
*/
ici->TransferFrom(ci);
*ici = *ci;
delete ci;
this->OnReceiveContentInfo(ici);
@ -509,7 +509,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p)
this->curInfo->type = (ContentType)p->Recv_uint8();
this->curInfo->id = (ContentID)p->Recv_uint32();
this->curInfo->filesize = p->Recv_uint32();
p->Recv_string(this->curInfo->filename, lengthof(this->curInfo->filename));
this->curInfo->filename = p->Recv_string(NETWORK_CONTENT_FILENAME_LENGTH);
if (!this->BeforeDownload()) {
this->CloseConnection();
@ -728,7 +728,7 @@ void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t l
}
/* Copy the string, without extension, to the filename. */
strecpy(this->curInfo->filename, tmp, lastof(this->curInfo->filename));
this->curInfo->filename = tmp;
/* Request the next file. */
if (!this->BeforeDownload()) {
@ -988,10 +988,10 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci)
/* Selection is easy; just walk all children and set the
* autoselected state. That way we can see what we automatically
* selected and thus can unselect when a dependency is removed. */
for (uint i = 0; i < ci->dependency_count; i++) {
ContentInfo *c = this->GetContent(ci->dependencies[i]);
for (auto &dependency : ci->dependencies) {
ContentInfo *c = this->GetContent(dependency);
if (c == nullptr) {
this->DownloadContentInfo(ci->dependencies[i]);
this->DownloadContentInfo(dependency);
} else if (c->state == ContentInfo::UNSELECTED) {
c->state = ContentInfo::AUTOSELECTED;
this->CheckDependencyState(c);
@ -1014,10 +1014,10 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci)
this->Unselect(c->id);
}
for (uint i = 0; i < ci->dependency_count; i++) {
const ContentInfo *c = this->GetContent(ci->dependencies[i]);
for (auto &dependency : ci->dependencies) {
const ContentInfo *c = this->GetContent(dependency);
if (c == nullptr) {
DownloadContentInfo(ci->dependencies[i]);
DownloadContentInfo(dependency);
continue;
}
if (c->state != ContentInfo::AUTOSELECTED) continue;

@ -146,7 +146,7 @@ void BaseNetworkContentDownloadStatusWindow::DrawWidget(const Rect &r, int widge
void BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(const ContentInfo *ci, int bytes)
{
if (ci->id != this->cur_id) {
strecpy(this->name, ci->filename, lastof(this->name));
strecpy(this->name, ci->filename.c_str(), lastof(this->name));
this->cur_id = ci->id;
this->downloaded_files++;
}
@ -406,7 +406,7 @@ class NetworkContentListWindow : public Window, ContentCallback {
/** Sort content by name. */
static bool NameSorter(const ContentInfo * const &a, const ContentInfo * const &b)
{
return strnatcmp(a->name, b->name, true) < 0; // Sort by name (natural sorting).
return strnatcmp(a->name.c_str(), b->name.c_str(), true) < 0; // Sort by name (natural sorting).
}
/** Sort content by type. */
@ -441,10 +441,9 @@ class NetworkContentListWindow : public Window, ContentCallback {
static bool CDECL TagNameFilter(const ContentInfo * const *a, ContentListFilterData &filter)
{
filter.string_filter.ResetState();
for (int i = 0; i < (*a)->tag_count; i++) {
filter.string_filter.AddLine((*a)->tags[i]);
}
filter.string_filter.AddLine((*a)->name);
for (auto &tag : (*a)->tags) filter.string_filter.AddLine(tag.c_str());
filter.string_filter.AddLine((*a)->name.c_str());
return filter.string_filter.GetState();
}
@ -702,17 +701,17 @@ public:
SetDParamStr(0, this->selected->name);
y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_NAME);
if (!StrEmpty(this->selected->version)) {
if (!this->selected->version.empty()) {
SetDParamStr(0, this->selected->version);
y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_VERSION);
}
if (!StrEmpty(this->selected->description)) {
if (!this->selected->description.empty()) {
SetDParamStr(0, this->selected->description);
y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DESCRIPTION);
}
if (!StrEmpty(this->selected->url)) {
if (!this->selected->url.empty()) {
SetDParamStr(0, this->selected->url);
y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_URL);
}
@ -724,20 +723,18 @@ public:
SetDParam(0, this->selected->filesize);
y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_FILESIZE);
if (this->selected->dependency_count != 0) {
if (!this->selected->dependencies.empty()) {
/* List dependencies */
char buf[DRAW_STRING_BUFFER] = "";
char *p = buf;
for (uint i = 0; i < this->selected->dependency_count; i++) {
ContentID cid = this->selected->dependencies[i];
for (auto &cid : this->selected->dependencies) {
/* Try to find the dependency */
ConstContentIterator iter = _network_content_client.Begin();
for (; iter != _network_content_client.End(); iter++) {
const ContentInfo *ci = *iter;
if (ci->id != cid) continue;
p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", (*iter)->name);
p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", (*iter)->name.c_str());
break;
}
}
@ -745,12 +742,12 @@ public:
y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DEPENDENCIES);
}
if (this->selected->tag_count != 0) {
if (!this->selected->tags.empty()) {
/* List all tags */
char buf[DRAW_STRING_BUFFER] = "";
char *p = buf;
for (uint i = 0; i < this->selected->tag_count; i++) {
p += seprintf(p, lastof(buf), i == 0 ? "%s" : ", %s", this->selected->tags[i]);
for (auto &tag : this->selected->tags) {
p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", tag.c_str());
}
SetDParamStr(0, buf);
y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TAGS);
@ -766,7 +763,7 @@ public:
for (const ContentInfo *ci : tree) {
if (ci == this->selected || ci->state != ContentInfo::SELECTED) continue;
p += seprintf(p, lastof(buf), buf == p ? "%s" : ", %s", ci->name);
p += seprintf(p, lastof(buf), buf == p ? "%s" : ", %s", ci->name.c_str());
}
if (p != buf) {
SetDParamStr(0, buf);
@ -843,7 +840,7 @@ public:
case WID_NCL_OPEN_URL:
if (this->selected != nullptr) {
extern void OpenBrowser(const char *url);
OpenBrowser(this->selected->url);
OpenBrowser(this->selected->url.c_str());
}
break;
@ -984,7 +981,7 @@ public:
this->SetWidgetDisabledState(WID_NCL_UNSELECT, this->filesize_sum == 0);
this->SetWidgetDisabledState(WID_NCL_SELECT_ALL, !show_select_all);
this->SetWidgetDisabledState(WID_NCL_SELECT_UPDATE, !show_select_upgrade);
this->SetWidgetDisabledState(WID_NCL_OPEN_URL, this->selected == nullptr || StrEmpty(this->selected->url));
this->SetWidgetDisabledState(WID_NCL_OPEN_URL, this->selected == nullptr || this->selected->url.empty());
for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) {
this->SetWidgetDisabledState(WID_NCL_TEXTFILE + tft, this->selected == nullptr || this->selected->state != ContentInfo::ALREADY_HERE || this->selected->GetTextfile(tft) == nullptr);
}

@ -928,13 +928,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char client_revision[NETWORK_REVISION_LENGTH];
p->Recv_string(client_revision, sizeof(client_revision));
std::string client_revision = p->Recv_string(NETWORK_REVISION_LENGTH);
uint32 newgrf_version = p->Recv_uint32();
/* Check if the client has revision control enabled */
if (!IsNetworkCompatibleVersion(client_revision) || _openttd_newgrf_version != newgrf_version) {
if (!IsNetworkCompatibleVersion(client_revision.c_str()) || _openttd_newgrf_version != newgrf_version) {
/* Different revisions!! */
return this->SendError(NETWORK_ERROR_WRONG_REVISION);
}
@ -1048,11 +1046,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SETTINGS_PASSWO
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char password[NETWORK_PASSWORD_LENGTH];
p->Recv_string(password, sizeof(password));
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
/* Check settings password. Deny if no password is set */
if (StrEmpty(password)) {
if (password.empty()) {
if (this->settings_authed) DEBUG(net, 0, "[settings-ctrl] client-id %d deauthed", this->client_id);
this->settings_authed = false;
} else if (_settings_client.network.settings_password.empty() ||

@ -505,15 +505,14 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAdd
if (num_grfs > NETWORK_MAX_GRF_COUNT) return;
for (i = 0; i < num_grfs; i++) {
char name[NETWORK_GRF_NAME_LENGTH];
GRFIdentifier c;
DeserializeGRFIdentifier(p, &c);
p->Recv_string(name, sizeof(name));
std::string name = p->Recv_string(NETWORK_GRF_NAME_LENGTH);
/* An empty name is not possible under normal circumstances
* and causes problems when showing the NewGRF list. */
if (StrEmpty(name)) continue;
if (name.empty()) continue;
/* Try to find the GRFTextWrapper for the name of this GRF ID and MD5sum tuple.
* If it exists and not resolved yet, then name of the fake GRF is

@ -1554,7 +1554,7 @@ void ShowMissingContentWindow(const GRFConfig *list)
ContentInfo *ci = new ContentInfo();
ci->type = CONTENT_TYPE_NEWGRF;
ci->state = ContentInfo::DOES_NOT_EXIST;
strecpy(ci->name, c->GetName(), lastof(ci->name));
ci->name = c->GetName();
ci->unique_id = BSWAP32(c->ident.grfid);
memcpy(ci->md5sum, HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum, sizeof(ci->md5sum));
cv.push_back(ci);

@ -543,10 +543,10 @@ void AddGRFTextToList(GRFTextWrapper &list, byte langid, uint32 grfid, bool allo
* @param list The list where the text should be added to.
* @param text_to_add The text to add to the list.
*/
void AddGRFTextToList(GRFTextWrapper &list, const char *text_to_add)
void AddGRFTextToList(GRFTextWrapper &list, const std::string &text_to_add)
{
if (!list) list.reset(new GRFTextList());
AddGRFTextToList(*list, GRFLX_UNSPECIFIED, std::string(text_to_add));
AddGRFTextToList(*list, GRFLX_UNSPECIFIED, text_to_add);
}
/**

@ -44,7 +44,7 @@ void SetCurrentGrfLangID(byte language_id);
std::string TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const std::string &str, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID);
void AddGRFTextToList(GRFTextList &list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add);
void AddGRFTextToList(GRFTextWrapper &list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add);
void AddGRFTextToList(GRFTextWrapper &list, const char *text_to_add);
void AddGRFTextToList(GRFTextWrapper &list, const std::string &text_to_add);
bool CheckGrfLangID(byte lang_id, byte grf_version);

@ -32,21 +32,38 @@ static ExtraCheatNameDesc _extra_cheat_descs[] = {
{ "town_rating", &_extra_cheats.town_rating },
};
static const SaveLoad _cheats_desc[] = {
SLE_VAR(Cheats, magic_bulldozer.been_used, SLE_BOOL),
SLE_VAR(Cheats, magic_bulldozer.value, SLE_BOOL),
SLE_VAR(Cheats, switch_company.been_used, SLE_BOOL),
SLE_VAR(Cheats, switch_company.value, SLE_BOOL),
SLE_VAR(Cheats, money.been_used, SLE_BOOL),
SLE_VAR(Cheats, money.value, SLE_BOOL),
SLE_VAR(Cheats, crossing_tunnels.been_used, SLE_BOOL),
SLE_VAR(Cheats, crossing_tunnels.value, SLE_BOOL),
SLE_NULL(1),
SLE_NULL(1), // Needs to be two NULL fields. See Load_CHTS().
SLE_VAR(Cheats, no_jetcrash.been_used, SLE_BOOL),
SLE_VAR(Cheats, no_jetcrash.value, SLE_BOOL),
SLE_NULL(1),
SLE_NULL(1), // Needs to be two NULL fields. See Load_CHTS().
SLE_VAR(Cheats, change_date.been_used, SLE_BOOL),
SLE_VAR(Cheats, change_date.value, SLE_BOOL),
SLE_VAR(Cheats, setup_prod.been_used, SLE_BOOL),
SLE_VAR(Cheats, setup_prod.value, SLE_BOOL),
SLE_NULL(1),
SLE_NULL(1), // Needs to be two NULL fields. See Load_CHTS().
SLE_VAR(Cheats, edit_max_hl.been_used, SLE_BOOL),
SLE_VAR(Cheats, edit_max_hl.value, SLE_BOOL),
};
/**
* Save the cheat values.
*/
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);
}
SlSetLength(std::size(_cheats_desc));
SlObject(&_cheats, _cheats_desc);
}
/**
@ -54,15 +71,21 @@ static void Save_CHTS()
*/
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);
size_t count = SlGetFieldLength();
std::vector<SaveLoad> slt;
/* Cheats were added over the years without a savegame bump. They are
* stored as 2 SLE_BOOLs per entry. "count" indicates how many SLE_BOOLs
* are stored for this savegame. So read only "count" SLE_BOOLs (and in
* result "count / 2" cheats). */
for (auto &sld : _cheats_desc) {
count--;
slt.push_back(sld);
if (count == 0) break;
}
SlObject(&_cheats, slt);
}
/**

@ -100,8 +100,8 @@ SaveLoadTable GetLinkGraphJobDesc()
SaveLoadTable GetLinkGraphScheduleDesc()
{
static const SaveLoad schedule_desc[] = {
SLE_LST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
SLE_LST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
SLE_REFLIST(LinkGraphSchedule, schedule, REF_LINK_GRAPH),
SLE_REFLIST(LinkGraphSchedule, running, REF_LINK_GRAPH_JOB),
};
return schedule_desc;
}

@ -691,17 +691,17 @@ static inline uint SlGetArrayLength(size_t length)
static inline uint SlCalcConvMemLen(VarType conv)
{
static const byte conv_mem_size[] = {1, 1, 1, 2, 2, 4, 4, 8, 8, 0};
byte length = GB(conv, 4, 4);
switch (length << 4) {
switch (GetVarMemType(conv)) {
case SLE_VAR_STRB:
case SLE_VAR_STR:
case SLE_VAR_STRQ:
return SlReadArrayLength();
default:
assert(length < lengthof(conv_mem_size));
return conv_mem_size[length];
uint8 type = GetVarMemType(conv) >> 4;
assert(type < lengthof(conv_mem_size));
return conv_mem_size[type];
}
}
@ -713,11 +713,11 @@ static inline uint SlCalcConvMemLen(VarType conv)
*/
static inline byte SlCalcConvFileLen(VarType conv)
{
byte length = GB(conv, 0, 4);
if (length == SLE_FILE_VEHORDERID) return SlXvIsFeaturePresent(XSLFI_MORE_VEHICLE_ORDERS) ? 2 : 1;
uint8 type = GetVarFileType(conv);
if (type == SLE_FILE_VEHORDERID) return SlXvIsFeaturePresent(XSLFI_MORE_VEHICLE_ORDERS) ? 2 : 1;
static const byte conv_file_size[] = {1, 1, 2, 2, 4, 4, 8, 8, 2};
assert(length < lengthof(conv_file_size));
return conv_file_size[length];
assert(type < lengthof(conv_file_size));
return conv_file_size[type];
}
/** Return the size in bytes of a reference (pointer) */
@ -1083,6 +1083,9 @@ static void SlString(void *ptr, size_t length, VarType conv)
switch (GetVarMemType(conv)) {
default: NOT_REACHED();
case SLE_VAR_NULL:
SlSkipBytes(len);
return;
case SLE_VAR_STRB:
if (len >= length) {
DEBUG(sl, 1, "String length in savegame is bigger than buffer, truncating");
@ -1143,6 +1146,11 @@ static void SlStdString(std::string &str, VarType conv)
case SLA_LOAD_CHECK:
case SLA_LOAD: {
size_t len = SlReadArrayLength();
if (GetVarMemType(conv) == SLE_VAR_NULL) {
SlSkipBytes(len);
return;
}
str.resize(len);
SlCopyBytes(str.data(), len);
@ -1345,11 +1353,124 @@ static void *IntToReference(size_t index, SLRefType rt)
}
/**
* Return the size in bytes of a list
* @param list The std::list to find the size of
* Handle conversion for references.
* @param ptr The object being filled/read.
* @param conv VarType type of the current element of the struct.
*/
void SlSaveLoadRef(void *ptr, VarType conv)
{
switch (_sl.action) {
case SLA_SAVE:
SlWriteUint32((uint32)ReferenceToInt(*(void **)ptr, (SLRefType)conv));
break;
case SLA_LOAD_CHECK:
case SLA_LOAD:
*(size_t *)ptr = IsSavegameVersionBefore(SLV_69) ? SlReadUint16() : SlReadUint32();
break;
case SLA_PTRS:
*(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv);
break;
case SLA_NULL:
*(void **)ptr = nullptr;
break;
default: NOT_REACHED();
}
}
/**
* Template class to help with list-like types.
*/
template <template<typename, typename> typename Tstorage, typename Tvar, typename Tallocator = std::allocator<Tvar>>
class SlStorageHelper {
typedef Tstorage<Tvar, Tallocator> SlStorageT;
public:
/**
* Internal templated helper to return the size in bytes of a list-like type.
* @param storage The storage to find the size of
* @param conv VarType type of variable that is used for calculating the size
* @param cmd The SaveLoadType ware are saving/loading.
*/
static size_t SlCalcLen(const void *storage, VarType conv, SaveLoadType cmd = SL_VAR)
{
assert(cmd == SL_VAR || cmd == SL_REF);
const SlStorageT *list = static_cast<const SlStorageT *>(storage);
int type_size = SlCalcConvFileLen(SLE_FILE_U32); // Size of the length of the list.
int item_size = SlCalcConvFileLen(cmd == SL_VAR ? conv : (VarType)SLE_FILE_U32);
return list->size() * item_size + type_size;
}
static void SlSaveLoadMember(SaveLoadType cmd, Tvar *item, VarType conv)
{
switch (cmd) {
case SL_VAR: SlSaveLoadConv(item, conv); break;
case SL_REF: SlSaveLoadRef(item, conv); break;
default:
NOT_REACHED();
}
}
/**
* Internal templated helper to save/load a list-like type.
* @param storage The storage being manipulated.
* @param conv VarType type of variable that is used for calculating the size.
* @param cmd The SaveLoadType ware are saving/loading.
*/
static void SlSaveLoad(void *storage, VarType conv, SaveLoadType cmd = SL_VAR)
{
assert(cmd == SL_VAR || cmd == SL_REF);
SlStorageT *list = static_cast<SlStorageT *>(storage);
switch (_sl.action) {
case SLA_SAVE:
SlWriteUint32((uint32)list->size());
for (auto &item : *list) {
SlSaveLoadMember(cmd, &item, conv);
}
break;
case SLA_LOAD_CHECK:
case SLA_LOAD: {
size_t length;
switch (cmd) {
case SL_VAR: length = SlReadUint32(); break;
case SL_REF: length = IsSavegameVersionBefore(SLV_69) ? SlReadUint16() : SlReadUint32(); break;
default: NOT_REACHED();
}
/* Load each value and push to the end of the storage. */
for (size_t i = 0; i < length; i++) {
Tvar &data = list->emplace_back();
SlSaveLoadMember(cmd, &data, conv);
}
break;
}
case SLA_PTRS:
for (auto &item : *list) {
SlSaveLoadMember(cmd, &item, conv);
}
break;
case SLA_NULL:
list->clear();
break;
default: NOT_REACHED();
}
}
};
/**
* Return the size in bytes of a list.
* @param list The std::list to find the size of.
* @param conv VarType type of variable that is used for calculating the size.
*/
template<typename PtrList>
static inline size_t SlCalcListLen(const void *list)
static inline size_t SlCalcRefListLen(const void *list)
{
const PtrList *l = (const PtrList *) list;
@ -1374,15 +1495,15 @@ static inline size_t SlCalcVarListLen(const void *list, size_t item_size)
/**
* Save/Load a list.
* @param list The list being manipulated
* @param conv SLRefType type of the list (Vehicle *, Station *, etc)
* @param list The list being manipulated.
* @param conv VarType type of variable that is used for calculating the size.
*/
template<typename PtrList>
static void SlList(void *list, SLRefType conv)
static void SlRefList(void *list, SLRefType conv)
{
/* Automatically calculate the length? */
if (_sl.need_length != NL_NONE) {
SlSetLength(SlCalcListLen<PtrList>(list));
SlSetLength(SlCalcRefListLen<PtrList>(list));
}
PtrList *l = (PtrList *)list;
@ -1475,70 +1596,6 @@ static void SlVarList(void *list, VarType conv)
}
}
/**
* Template class to help with std::deque.
*/
template <typename T>
class SlDequeHelper {
typedef std::deque<T> SlDequeT;
public:
/**
* Internal templated helper to return the size in bytes of a std::deque.
* @param deque The std::deque to find the size of
* @param conv VarType type of variable that is used for calculating the size
*/
static size_t SlCalcDequeLen(const void *deque, VarType conv)
{
const SlDequeT *l = (const SlDequeT *)deque;
int type_size = 4;
/* Each entry is saved as type_size bytes, plus type_size bytes are used for the length
* of the list */
return l->size() * SlCalcConvFileLen(conv) + type_size;
}
/**
* Internal templated helper to save/load a std::deque.
* @param deque The std::deque being manipulated
* @param conv VarType type of variable that is used for calculating the size
*/
static void SlDeque(void *deque, VarType conv)
{
SlDequeT *l = (SlDequeT *)deque;
switch (_sl.action) {
case SLA_SAVE: {
SlWriteUint32((uint32)l->size());
typename SlDequeT::iterator iter;
for (iter = l->begin(); iter != l->end(); ++iter) {
SlSaveLoadConv(&(*iter), conv);
}
break;
}
case SLA_LOAD_CHECK:
case SLA_LOAD: {
size_t length = SlReadUint32();
/* Load each value and push to the end of the deque */
for (size_t i = 0; i < length; i++) {
T data;
SlSaveLoadConv(&data, conv);
l->push_back(data);
}
break;
}
case SLA_PTRS:
break;
case SLA_NULL:
l->clear();
break;
default: NOT_REACHED();
}
}
};
/**
* Return the size in bytes of a std::deque.
* @param deque The std::deque to find the size of
@ -1547,25 +1604,19 @@ public:
static inline size_t SlCalcDequeLen(const void *deque, VarType conv)
{
switch (GetVarMemType(conv)) {
case SLE_VAR_BL:
return SlDequeHelper<bool>::SlCalcDequeLen(deque, conv);
case SLE_VAR_I8:
case SLE_VAR_U8:
return SlDequeHelper<uint8>::SlCalcDequeLen(deque, conv);
case SLE_VAR_I16:
case SLE_VAR_U16:
return SlDequeHelper<uint16>::SlCalcDequeLen(deque, conv);
case SLE_VAR_I32:
case SLE_VAR_U32:
return SlDequeHelper<uint32>::SlCalcDequeLen(deque, conv);
case SLE_VAR_I64:
case SLE_VAR_U64:
return SlDequeHelper<uint64>::SlCalcDequeLen(deque, conv);
case SLE_VAR_BL: return SlStorageHelper<std::deque, bool>::SlCalcLen(deque, conv);
case SLE_VAR_I8: return SlStorageHelper<std::deque, int8>::SlCalcLen(deque, conv);
case SLE_VAR_U8: return SlStorageHelper<std::deque, uint8>::SlCalcLen(deque, conv);
case SLE_VAR_I16: return SlStorageHelper<std::deque, int16>::SlCalcLen(deque, conv);
case SLE_VAR_U16: return SlStorageHelper<std::deque, uint16>::SlCalcLen(deque, conv);
case SLE_VAR_I32: return SlStorageHelper<std::deque, int32>::SlCalcLen(deque, conv);
case SLE_VAR_U32: return SlStorageHelper<std::deque, uint32>::SlCalcLen(deque, conv);
case SLE_VAR_I64: return SlStorageHelper<std::deque, int64>::SlCalcLen(deque, conv);
case SLE_VAR_U64: return SlStorageHelper<std::deque, uint64>::SlCalcLen(deque, conv);
default: NOT_REACHED();
}
}
/**
* Save/load a std::deque.
* @param deque The std::deque being manipulated
@ -1574,52 +1625,23 @@ static inline size_t SlCalcDequeLen(const void *deque, VarType conv)
static void SlDeque(void *deque, VarType conv)
{
switch (GetVarMemType(conv)) {
case SLE_VAR_BL:
SlDequeHelper<bool>::SlDeque(deque, conv);
break;
case SLE_VAR_I8:
case SLE_VAR_U8:
SlDequeHelper<uint8>::SlDeque(deque, conv);
break;
case SLE_VAR_I16:
case SLE_VAR_U16:
SlDequeHelper<uint16>::SlDeque(deque, conv);
break;
case SLE_VAR_I32:
case SLE_VAR_U32:
SlDequeHelper<uint32>::SlDeque(deque, conv);
break;
case SLE_VAR_I64:
case SLE_VAR_U64:
SlDequeHelper<uint64>::SlDeque(deque, conv);
break;
case SLE_VAR_BL: SlStorageHelper<std::deque, bool>::SlSaveLoad(deque, conv); break;
case SLE_VAR_I8: SlStorageHelper<std::deque, int8>::SlSaveLoad(deque, conv); break;
case SLE_VAR_U8: SlStorageHelper<std::deque, uint8>::SlSaveLoad(deque, conv); break;
case SLE_VAR_I16: SlStorageHelper<std::deque, int16>::SlSaveLoad(deque, conv); break;
case SLE_VAR_U16: SlStorageHelper<std::deque, uint16>::SlSaveLoad(deque, conv); break;
case SLE_VAR_I32: SlStorageHelper<std::deque, int32>::SlSaveLoad(deque, conv); break;
case SLE_VAR_U32: SlStorageHelper<std::deque, uint32>::SlSaveLoad(deque, conv); break;
case SLE_VAR_I64: SlStorageHelper<std::deque, int64>::SlSaveLoad(deque, conv); break;
case SLE_VAR_U64: SlStorageHelper<std::deque, uint64>::SlSaveLoad(deque, conv); break;
default: NOT_REACHED();
}
}
/** Are we going to save this object or not? */
static inline bool SlIsObjectValidInSavegame(const SaveLoad &sld)
{
if (!sld.ext_feature_test.IsFeaturePresent(_sl_version, sld.version_from, sld.version_to)) return false;
if (sld.conv & SLF_NOT_IN_SAVE) return false;
return true;
}
/**
* Are we going to load this variable when loading a savegame or not?
* @note If the variable is skipped it is skipped in the savegame
* bytestream itself as well, so there is no need to skip it somewhere else
*/
static inline bool SlSkipVariableOnLoad(const SaveLoad &sld)
{
if ((sld.conv & SLF_NO_NETWORK_SYNC) && _sl.action != SLA_SAVE && _networking && !_network_server) {
SlSkipBytes(SlCalcConvMemLen(sld.conv) * sld.length);
return true;
}
return false;
return sld.ext_feature_test.IsFeaturePresent(_sl_version, sld.version_from, sld.version_to);
}
/**
@ -1648,7 +1670,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld)
case SL_REF:
case SL_ARR:
case SL_STR:
case SL_LST:
case SL_REFLIST:
case SL_PTRDEQ:
case SL_VEC:
case SL_DEQUE:
@ -1662,9 +1684,9 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld)
case SL_REF: return SlCalcRefLen();
case SL_ARR: return SlCalcArrayLen(sld.length, sld.conv);
case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld.length, sld.conv);
case SL_LST: return SlCalcListLen<std::list<void *>>(GetVariableAddress(object, sld));
case SL_PTRDEQ: return SlCalcListLen<std::deque<void *>>(GetVariableAddress(object, sld));
case SL_VEC: return SlCalcListLen<std::vector<void *>>(GetVariableAddress(object, sld));
case SL_REFLIST: return SlCalcRefListLen<std::list<void *>>(GetVariableAddress(object, sld));
case SL_PTRDEQ: return SlCalcRefListLen<std::deque<void *>>(GetVariableAddress(object, sld));
case SL_VEC: return SlCalcRefListLen<std::vector<void *>>(GetVariableAddress(object, sld));
case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv);
case SL_VARVEC: {
const size_t size_len = SlCalcConvMemLen(sld.conv);
@ -1695,6 +1717,8 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld)
*/
[[maybe_unused]] static bool IsVariableSizeRight(const SaveLoad &sld)
{
if (GetVarMemType(sld.conv) == SLE_VAR_NULL) return true;
switch (sld.cmd) {
case SL_VAR:
switch (GetVarMemType(sld.conv)) {
@ -1745,7 +1769,7 @@ static void SlFilterObjectMember(const SaveLoad &sld, std::vector<SaveLoad> &sav
case SL_REF:
case SL_ARR:
case SL_STR:
case SL_LST:
case SL_REFLIST:
case SL_PTRDEQ:
case SL_VEC:
case SL_DEQUE:
@ -1753,7 +1777,6 @@ static void SlFilterObjectMember(const SaveLoad &sld, std::vector<SaveLoad> &sav
case SL_VARVEC:
/* CONDITIONAL saveload types depend on the savegame version */
if (!SlIsObjectValidInSavegame(sld)) return;
if (SlSkipVariableOnLoad(sld)) return;
switch (_sl.action) {
case SLA_SAVE:
@ -1764,7 +1787,7 @@ static void SlFilterObjectMember(const SaveLoad &sld, std::vector<SaveLoad> &sav
case SLA_NULL:
switch (sld.cmd) {
case SL_REF:
case SL_LST:
case SL_REFLIST:
case SL_PTRDEQ:
case SL_VEC:
break;
@ -1815,8 +1838,10 @@ std::vector<SaveLoad> SlFilterObject(const SaveLoadTable &slt)
}
template <SaveLoadAction action, bool check_version>
bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld)
bool SlObjectMemberGeneric(void *object, const SaveLoad &sld)
{
void *ptr = GetVariableAddress(object, sld);
if (check_version) assert(IsVariableSizeRight(sld));
VarType conv = GB(sld.conv, 0, 8);
@ -1825,7 +1850,7 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld)
case SL_REF:
case SL_ARR:
case SL_STR:
case SL_LST:
case SL_REFLIST:
case SL_PTRDEQ:
case SL_VEC:
case SL_DEQUE:
@ -1834,7 +1859,6 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld)
/* CONDITIONAL saveload types depend on the savegame version */
if (check_version) {
if (!SlIsObjectValidInSavegame(sld)) return false;
if (SlSkipVariableOnLoad(sld)) return false;
}
switch (sld.cmd) {
@ -1859,9 +1883,9 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld)
break;
case SL_ARR: SlArray(ptr, sld.length, conv); break;
case SL_STR: SlString(ptr, sld.length, sld.conv); break;
case SL_LST: SlList<std::list<void *>>(ptr, (SLRefType)conv); break;
case SL_PTRDEQ: SlList<std::deque<void *>>(ptr, (SLRefType)conv); break;
case SL_VEC: SlList<std::vector<void *>>(ptr, (SLRefType)conv); break;
case SL_REFLIST: SlRefList<std::list<void *>>(ptr, (SLRefType)conv); break;
case SL_PTRDEQ: SlRefList<std::deque<void *>>(ptr, (SLRefType)conv); break;
case SL_VEC: SlRefList<std::vector<void *>>(ptr, (SLRefType)conv); break;
case SL_DEQUE: SlDeque(ptr, conv); break;
case SL_VARVEC: {
const size_t size_len = SlCalcConvMemLen(sld.conv);
@ -1907,18 +1931,18 @@ bool SlObjectMemberGeneric(void *ptr, const SaveLoad &sld)
return true;
}
bool SlObjectMember(void *ptr, const SaveLoad &sld)
bool SlObjectMember(void *object, const SaveLoad &sld)
{
switch (_sl.action) {
case SLA_SAVE:
return SlObjectMemberGeneric<SLA_SAVE, true>(ptr, sld);
return SlObjectMemberGeneric<SLA_SAVE, true>(object, sld);
case SLA_LOAD_CHECK:
case SLA_LOAD:
return SlObjectMemberGeneric<SLA_LOAD, true>(ptr, sld);
return SlObjectMemberGeneric<SLA_LOAD, true>(object, sld);
case SLA_PTRS:
return SlObjectMemberGeneric<SLA_PTRS, true>(ptr, sld);
return SlObjectMemberGeneric<SLA_PTRS, true>(object, sld);
case SLA_NULL:
return SlObjectMemberGeneric<SLA_NULL, true>(ptr, sld);
return SlObjectMemberGeneric<SLA_NULL, true>(object, sld);
default: NOT_REACHED();
}
}
@ -1936,8 +1960,7 @@ void SlObject(void *object, const SaveLoadTable &slt)
}
for (auto &sld : slt) {
void *ptr = GetVariableAddress(object, sld);
SlObjectMember(ptr, sld);
SlObjectMember(object, sld);
}
}
@ -1945,8 +1968,7 @@ template <SaveLoadAction action, bool check_version>
void SlObjectIterateBase(void *object, const SaveLoadTable &slt)
{
for (auto &sld : slt) {
void *ptr = sld.global ? sld.address : GetVariableAddress(object, sld);
SlObjectMemberGeneric<action, check_version>(ptr, sld);
SlObjectMemberGeneric<action, check_version>(object, sld);
}
}

@ -538,11 +538,8 @@ enum VarTypes {
/* 8 bits allocated for a maximum of 8 flags
* Flags directing saving/loading of a variable */
SLF_NOT_IN_SAVE = 1 << 8, ///< do not save with savegame, basically client-based
SLF_NOT_IN_CONFIG = 1 << 9, ///< do not save to config file
SLF_NO_NETWORK_SYNC = 1 << 10, ///< do not synchronize over network (but it is saved if SLF_NOT_IN_SAVE is not set)
SLF_ALLOW_CONTROL = 1 << 11, ///< allow control codes in the strings
SLF_ALLOW_NEWLINE = 1 << 12, ///< allow new lines in the strings
SLF_ALLOW_CONTROL = 1 << 8, ///< Allow control codes in the strings.
SLF_ALLOW_NEWLINE = 1 << 9, ///< Allow new lines in the strings.
};
typedef uint32 VarType;
@ -551,11 +548,11 @@ typedef uint32 VarType;
enum SaveLoadTypes {
SL_VAR = 0, ///< Save/load a variable.
SL_REF = 1, ///< Save/load a reference.
SL_ARR = 2, ///< Save/load an array.
SL_ARR = 2, ///< Save/load a fixed-size array of #SL_VAR elements.
SL_STR = 3, ///< Save/load a string.
SL_LST = 4, ///< Save/load a list.
SL_DEQUE = 5, ///< Save/load a primitive type deque.
SL_VEC = 6, ///< Save/load a vector.
SL_REFLIST = 4, ///< Save/load a list of #SL_REF elements.
SL_DEQUE = 5, ///< Save/load a deque of #SL_VAR elements.
SL_VEC = 6, ///< Save/load a vector of #SL_REF elements.
SL_STDSTR = 7, ///< Save/load a std::string.
/* non-normal save-load types */
@ -563,7 +560,7 @@ enum SaveLoadTypes {
SL_VEH_INCLUDE = 9,
SL_ST_INCLUDE = 10,
SL_PTRDEQ = 13, ///< Save/load a pointer type deque.
SL_PTRDEQ = 13, ///< Save/load a deque of #SL_REF elements.
SL_VARVEC = 14, ///< Save/load a primitive type vector.
};
@ -628,7 +625,7 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLE_CONDREF(base, variable, type, from, to) SLE_CONDREF_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of an array in some savegame versions.
* 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.
@ -666,7 +663,7 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLE_CONDSSTR(base, variable, type, from, to) SLE_GENERAL(SL_STDSTR, base, variable, type, 0, from, to)
/**
* Storage of a list in some savegame versions.
* Storage of a list of #SL_REF elements in some savegame versions.
* @param base Name of the class or struct containing the list.
* @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.
@ -674,8 +671,8 @@ using SaveLoadTable = span<const SaveLoad>;
* @param to Last savegame version that has the list.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLE_CONDLST_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_LST, base, variable, type, 0, from, to, extver)
#define SLE_CONDLST(base, variable, type, from, to) SLE_CONDLST_X(base, variable, type, from, to, SlXvFeatureTest())
#define SLE_CONDREFLIST_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_REFLIST, base, variable, type, 0, from, to, extver)
#define SLE_CONDREFLIST(base, variable, type, from, to) SLE_CONDREFLIST_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a deque in some savegame versions.
@ -714,7 +711,7 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLE_CONDVARVEC(base, variable, type, from, to) SLE_CONDVARVEC_X(base, variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a deque in some savegame versions.
* Storage of a deque of #SL_VAR elements in some savegame versions.
* @param base Name of the class or struct containing the list.
* @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.
@ -742,7 +739,7 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of an array in every version of a savegame.
* Storage of fixed-size array of #SL_VAR elements in every version of a savegame.
* @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.
@ -768,12 +765,12 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLE_SSTR(base, variable, type) SLE_CONDSSTR(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a list in every savegame version.
* Storage of a list of #SL_REF elements in every savegame version.
* @param base Name of the class or struct containing the list.
* @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.
*/
#define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
#define SLE_REFLIST(base, variable, type) SLE_CONDREFLIST(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a deque in every savegame version.
@ -804,7 +801,7 @@ using SaveLoadTable = span<const SaveLoad>;
* @param to Last savegame version that has the empty space.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have empty space
*/
#define SLE_CONDNULL_X(length, from, to, extver) SLE_CONDARR_X(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, extver)
#define SLE_CONDNULL_X(length, from, to, extver) SLE_CONDARR_X(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, extver)
#define SLE_CONDNULL(length, from, to) SLE_CONDNULL_X(length, from, to, SlXvFeatureTest())
/** Translate values ingame to different values in the savegame and vv. */
@ -849,7 +846,7 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLEG_CONDREF(variable, type, from, to) SLEG_CONDREF_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global array in some savegame versions.
* Storage of a global fixed-size array of #SL_VAR elements in some savegame versions.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param length Number of elements in the array.
@ -883,15 +880,15 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLEG_CONDSSTR(variable, type, from, to) SLEG_GENERAL(SL_STDSTR, variable, type, 0, from, to)
/**
* Storage of a global list in some savegame versions.
* Storage of a global reference list in some savegame versions.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
* @param from First savegame version that has the list.
* @param to Last savegame version that has the list.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
*/
#define SLEG_CONDLST_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_LST, variable, type, 0, from, to, extver)
#define SLEG_CONDLST(variable, type, from, to) SLEG_CONDLST_X(variable, type, from, to, SlXvFeatureTest())
#define SLEG_CONDREFLIST_X(variable, type, from, to, extver) SLEG_GENERAL_X(SL_REFLIST, variable, type, 0, from, to, extver)
#define SLEG_CONDREFLIST(variable, type, from, to) SLEG_CONDREFLIST_X(variable, type, from, to, SlXvFeatureTest())
/**
* Storage of a global deque in some savegame versions.
@ -930,7 +927,7 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global array in every savegame version.
* Storage of a global fixed-size array of #SL_VAR elements in every savegame version.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
@ -951,11 +948,11 @@ using SaveLoadTable = span<const SaveLoad>;
#define SLEG_SSTR(variable, type) SLEG_CONDSSTR(variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global list in every savegame version.
* Storage of a global reference list in every savegame version.
* @param variable Name of the global variable.
* @param type Storage of the data in memory and in the savegame.
*/
#define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
#define SLEG_REFLIST(variable, type) SLEG_CONDREFLIST(variable, type, SL_MIN_VERSION, SL_MAX_VERSION)
/**
* Storage of a global deque in every savegame version.
@ -978,7 +975,7 @@ using SaveLoadTable = span<const SaveLoad>;
* @param to Last savegame version that has the empty space.
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have empty space
*/
#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)nullptr, SlXvFeatureTest()}
#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL, length, from, to, (void*)nullptr, SlXvFeatureTest()}
/**
* Checks whether the savegame is below \a major.\a minor.

@ -238,7 +238,7 @@ static const SaveLoad _town_desc[] = {
SLE_CONDVAR(Town, larger_town, SLE_BOOL, SLV_56, SL_MAX_VERSION),
SLE_CONDVAR(Town, layout, SLE_UINT8, SLV_113, SL_MAX_VERSION),
SLE_CONDLST(Town, psa_list, REF_STORAGE, SLV_161, SL_MAX_VERSION),
SLE_CONDREFLIST(Town, psa_list, REF_STORAGE, SLV_161, SL_MAX_VERSION),
SLE_CONDNULL(4, SLV_166, SLV_EXTEND_CARGOTYPES), ///< cargo_produced, no longer in use
SLE_CONDNULL(8, SLV_EXTEND_CARGOTYPES, SLV_REMOVE_TOWN_CARGO_CACHE), ///< cargo_produced, no longer in use

@ -35,7 +35,7 @@
const SettingDesc *sd = GetSettingFromName(setting);
if ((sd->save.conv & SLF_NO_NETWORK_SYNC) != 0) return false;
if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false;
return ScriptObject::DoCommand(0, 0, value, CMD_CHANGE_SETTING, sd->name);
}

@ -596,8 +596,9 @@ bool ScriptInstance::IsPaused()
case SQSL_STRING: {
SlObject(nullptr, _script_byte);
static char buf[256];
static char buf[std::numeric_limits<decltype(_script_sl_byte)>::max()];
SlArray(buf, _script_sl_byte, SLE_CHAR);
StrMakeValidInPlace(buf, buf + _script_sl_byte);
if (vm != nullptr) sq_pushstring(vm, buf, -1);
return true;
}

@ -636,7 +636,7 @@ static void IniSaveSettings(IniFile *ini, const SettingTable &settings_table, co
/* If the setting is not saved to the configuration
* file, just continue with the next setting */
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to, sd->save.ext_feature_test)) continue;
if (sd->save.conv & SLF_NOT_IN_CONFIG) continue;
if (sd->flags & SF_NOT_IN_CONFIG) continue;
if (sd->flags & SF_NO_NEWGAME) continue;
/* XXX - wtf is this?? (group override?) */
@ -787,7 +787,7 @@ void IniSaveWindowSettings(IniFile *ini, const char *grpname, void *desc)
*/
bool SettingDesc::IsEditable(bool do_command) const
{
if (!do_command && !(this->save.conv & SLF_NO_NETWORK_SYNC) && _networking && !(_network_server || _network_settings_access) && !(this->flags & SF_PER_COMPANY)) return false;
if (!do_command && !(this->flags & SF_NO_NETWORK_SYNC) && _networking && !(_network_server || _network_settings_access) && !(this->flags & SF_PER_COMPANY)) return false;
if ((this->flags & SF_NETWORK_ONLY) && !_networking && _game_mode != GM_MENU) return false;
if ((this->flags & SF_NO_NETWORK) && _networking) return false;
if ((this->flags & SF_NEWGAME_ONLY) &&
@ -804,7 +804,7 @@ bool SettingDesc::IsEditable(bool do_command) const
SettingType SettingDesc::GetType() const
{
if (this->flags & SF_PER_COMPANY) return ST_COMPANY;
return (this->save.conv & SLF_NOT_IN_SAVE) ? ST_CLIENT : ST_GAME;
return (this->flags & SF_NOT_IN_SAVE) ? ST_CLIENT : ST_GAME;
}
/**
@ -2331,7 +2331,7 @@ bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame)
* changes its defaults. At least that is the convention we have chosen */
bool no_newgame = setting->flags & SF_NO_NEWGAME;
if (no_newgame && _game_mode == GM_MENU) return false;
if (setting->save.conv & SLF_NO_NETWORK_SYNC) {
if (setting->flags & SF_NO_NETWORK_SYNC) {
if (_game_mode != GM_MENU && !no_newgame) {
setting->ChangeValue(&_settings_newgame, value);
}
@ -2388,7 +2388,7 @@ void SyncCompanySettings()
*/
bool SetSettingValue(const StringSettingDesc *sd, std::string value, bool force_newgame)
{
assert(sd->save.conv & SLF_NO_NETWORK_SYNC);
assert(sd->flags & SF_NO_NETWORK_SYNC);
if (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ && value.compare("(null)") == 0) {
value.clear();
@ -2565,14 +2565,13 @@ static void LoadSettingsXref(const SettingDesc *osd, void *object) {
sld.version_from = osd->save.version_from;
sld.version_to = osd->save.version_to;
sld.ext_feature_test = osd->save.ext_feature_test;
void *ptr = GetVariableAddress(object, sld);
if (!SlObjectMember(ptr, sld)) return;
int64 val = ReadValue(ptr, sld.conv);
if (osd->xref.conv != nullptr) val = osd->xref.conv(val);
if (!SlObjectMember(object, sld)) return;
if (setting_xref->IsIntSetting()) {
const IntSettingDesc *int_setting = setting_xref->AsIntSetting();
int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
int64 val = int_setting->Read(object);
if (osd->xref.conv != nullptr) val = osd->xref.conv(val);
int_setting->MakeValueValidAndWrite(object, val);
}
}
@ -2587,15 +2586,15 @@ static void LoadSettings(const SettingTable &settings, void *object)
extern SaveLoadVersion _sl_version;
for (auto &osd : settings) {
if (osd->flags & SF_NOT_IN_SAVE) continue;
if (osd->patx_name != nullptr) continue;
const SaveLoad &sld = osd->save;
if (osd->xref.target != nullptr) {
if (sld.ext_feature_test.IsFeaturePresent(_sl_version, sld.version_from, sld.version_to)) LoadSettingsXref(osd.get(), object);
continue;
}
void *ptr = GetVariableAddress(object, sld);
if (!SlObjectMember(ptr, osd->save)) continue;
if (!SlObjectMember(object, osd->save)) continue;
if (osd->IsIntSetting()) {
const IntSettingDesc *int_setting = osd->AsIntSetting();
int_setting->MakeValueValidAndWrite(object, int_setting->Read(object));
@ -2615,6 +2614,7 @@ static void SaveSettings(const SettingTable &settings, void *object)
* SlCalcLength() because we have a different format. So do this manually */
size_t length = 0;
for (auto &sd : settings) {
if (sd->flags & SF_NOT_IN_SAVE) continue;
if (sd->patx_name != nullptr) continue;
if (sd->xref.target != nullptr) continue;
length += SlCalcObjMemberLength(object, sd->save);
@ -2622,9 +2622,10 @@ static void SaveSettings(const SettingTable &settings, void *object)
SlSetLength(length);
for (auto &sd : settings) {
if (sd->flags & SF_NOT_IN_SAVE) continue;
if (sd->patx_name != nullptr) continue;
void *ptr = GetVariableAddress(object, sd->save);
SlObjectMember(ptr, sd->save);
if (sd->xref.target != nullptr) continue;
SlObjectMember(object, sd->save);
}
}
@ -2738,8 +2739,7 @@ static void LoadSettingsPatx(const SettingTable &settings, void *object)
const SettingDesc *setting = (*iter);
const SaveLoad &sld = setting->save;
size_t read = SlGetBytesRead();
void *ptr = GetVariableAddress(object, sld);
SlObjectMember(ptr, sld);
SlObjectMember(object, sld);
if (SlGetBytesRead() != read + current_setting.setting_length) {
SlErrorCorruptFmt("PATX chunk: setting read length mismatch for setting: '%s'", current_setting.name);
}
@ -2799,8 +2799,7 @@ static void SaveSettingsPatx(const SettingTable &settings, void *object)
current_setting.name = desc->patx_name;
current_setting.setting_length = settings_to_add[i].setting_length;
SlObject(&current_setting, _settings_ext_save_desc);
void *ptr = GetVariableAddress(object, desc->save);
SlObjectMember(ptr, desc->save);
SlObjectMember(object, desc->save);
}
}
@ -2879,8 +2878,7 @@ void LoadSettingsPlyx(bool skip)
// found setting
const SaveLoad &sld = setting->save;
size_t read = SlGetBytesRead();
void *ptr = GetVariableAddress(&(c->settings), sld);
SlObjectMember(ptr, sld);
SlObjectMember(const_cast<CompanySettings *>(&(c->settings)), sld);
if (SlGetBytesRead() != read + current_setting.setting_length) {
SlErrorCorruptFmt("PLYX chunk: setting read length mismatch for setting: '%s'", current_setting.name);
}
@ -2958,8 +2956,7 @@ void SaveSettingsPlyx()
current_setting.name = sd->patx_name;
current_setting.setting_length = setting_length;
SlObject(&current_setting, _settings_plyx_desc);
void *ptr = GetVariableAddress(&(c->settings), sd->save);
SlObjectMember(ptr, sd->save);
SlObjectMember(&(c->settings), sd->save);
}
}
}

@ -12,22 +12,25 @@
#include "saveload/saveload.h"
enum SettingFlag : uint16 {
enum SettingFlag : uint32 {
SF_NONE = 0,
SF_GUI_0_IS_SPECIAL = 1 << 0, ///< A value of zero is possible and has a custom string (the one after "strval").
SF_GUI_NEGATIVE_IS_SPECIAL = 1 << 1, ///< A negative value has another string (the one after "strval").
SF_GUI_DROPDOWN = 1 << 2, ///< The value represents a limited number of string-options (internally integer) presented as dropdown.
SF_GUI_CURRENCY = 1 << 3, ///< The number represents money, so when reading value multiply by exchange rate.
SF_NETWORK_ONLY = 1 << 4, ///< This setting only applies to network games.
SF_NO_NETWORK = 1 << 5, ///< This setting does not apply to network games; it may not be changed during the game.
SF_NEWGAME_ONLY = 1 << 6, ///< This setting cannot be changed in a game.
SF_SCENEDIT_TOO = 1 << 7, ///< This setting can be changed in the scenario editor (only makes sense when SF_NEWGAME_ONLY is set).
SF_SCENEDIT_ONLY = 1 << 8, ///< This setting can only be changed in the scenario editor.
SF_PER_COMPANY = 1 << 9, ///< This setting can be different for each company (saved in company struct).
SF_DECIMAL1 = 1 << 10,///< display a decimal representation of the setting value divided by 10
SF_ENUM = 1 << 11,///< the setting can take one of the values given by an array of struct SettingDescEnumEntry
SF_NO_NEWGAME = 1 << 12,///< the setting does not apply and is not shown in a new game context
SF_DEC1SCALE = 1 << 13,///< also display a float representation of the scale of a decimal1 scale parameter
SF_GUI_0_IS_SPECIAL = 1 << 0, ///< A value of zero is possible and has a custom string (the one after "strval").
SF_GUI_NEGATIVE_IS_SPECIAL = 1 << 1, ///< A negative value has another string (the one after "strval").
SF_GUI_DROPDOWN = 1 << 2, ///< The value represents a limited number of string-options (internally integer) presented as dropdown.
SF_GUI_CURRENCY = 1 << 3, ///< The number represents money, so when reading value multiply by exchange rate.
SF_NETWORK_ONLY = 1 << 4, ///< This setting only applies to network games.
SF_NO_NETWORK = 1 << 5, ///< This setting does not apply to network games; it may not be changed during the game.
SF_NEWGAME_ONLY = 1 << 6, ///< This setting cannot be changed in a game.
SF_SCENEDIT_TOO = 1 << 7, ///< This setting can be changed in the scenario editor (only makes sense when SF_NEWGAME_ONLY is set).
SF_SCENEDIT_ONLY = 1 << 8, ///< This setting can only be changed in the scenario editor.
SF_PER_COMPANY = 1 << 9, ///< This setting can be different for each company (saved in company struct).
SF_NOT_IN_SAVE = 1 << 10, ///< Do not save with savegame, basically client-based.
SF_NOT_IN_CONFIG = 1 << 11, ///< Do not save to config file.
SF_NO_NETWORK_SYNC = 1 << 12, ///< Do not synchronize over network (but it is saved if SF_NOT_IN_SAVE is not set).
SF_DECIMAL1 = 1 << 13, ///< display a decimal representation of the setting value divided by 10
SF_ENUM = 1 << 14, ///< the setting can take one of the values given by an array of struct SettingDescEnumEntry
SF_NO_NEWGAME = 1 << 15, ///< the setting does not apply and is not shown in a new game context
SF_DEC1SCALE = 1 << 16, ///< also display a float representation of the scale of a decimal1 scale parameter
};
DECLARE_ENUM_AS_BIT_SET(SettingFlag)
@ -326,7 +329,7 @@ struct ListSettingDesc : SettingDesc {
/** Placeholder for settings that have been removed, but might still linger in the savegame. */
struct NullSettingDesc : SettingDesc {
NullSettingDesc(SaveLoad save) :
SettingDesc(save, "", SF_NONE, nullptr, false, nullptr) {}
SettingDesc(save, "", SF_NOT_IN_CONFIG, nullptr, false, nullptr) {}
virtual ~NullSettingDesc() {}
void FormatValue(char *buf, const char *last, const void *object) const override { NOT_REACHED(); }

@ -58,67 +58,67 @@ static size_t ConvertLandscape(const char *value);
/* Macros for various objects to go in the configuration file.
* This section is for global variables */
#define SDTG_VAR(name, type, flags, guiflags, var, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Int, SLEG_GENERAL_X(SL_VAR, var, type | flags, 1, from, to, extver), name, guiflags, guiproc, startup, patxname, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback, nullptr)
#define SDTG_VAR(name, type, flags, var, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Int, SLEG_GENERAL_X(SL_VAR, var, type, 1, from, to, extver), name, flags, guiproc, startup, patxname, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback, nullptr)
#define SDTG_BOOL(name, flags, guiflags, var, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Bool, SLEG_GENERAL_X(SL_VAR, var, SLE_BOOL | flags, 1, from, to, extver), name, guiflags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback)
#define SDTG_BOOL(name, flags, var, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Bool, SLEG_GENERAL_X(SL_VAR, var, SLE_BOOL, 1, from, to, extver), name, flags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback)
#define SDTG_LIST(name, type, flags, guiflags, var, def, length, from, to, extver, cat, guiproc, startup, patxname)\
NSD(List, SLEG_GENERAL_X(SL_ARR, var, type | flags, length, from, to, extver), name, guiflags, guiproc, startup, patxname, def)
#define SDTG_LIST(name, type, flags, var, def, length, from, to, extver, cat, guiproc, startup, patxname)\
NSD(List, SLEG_GENERAL_X(SL_ARR, var, type, length, from, to, extver), name, flags, guiproc, startup, patxname, def)
#define SDTG_SSTR(name, type, flags, guiflags, var, def, max_length, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(String, SLEG_GENERAL_X(SL_STDSTR, var, type | flags, sizeof(var), from, to, extver), name, guiflags, guiproc, startup, patxname, def, max_length, pre_check, post_callback)
#define SDTG_SSTR(name, type, flags, var, def, max_length, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(String, SLEG_GENERAL_X(SL_STDSTR, var, type, sizeof(var), from, to, extver), name, flags, guiproc, startup, patxname, def, max_length, pre_check, post_callback)
#define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(OneOfMany, SLEG_GENERAL_X(SL_VAR, var, type | flags, 1, from, to, extver), name, guiflags, guiproc, startup, patxname, def, max, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr)
#define SDTG_OMANY(name, type, flags, var, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(OneOfMany, SLEG_GENERAL_X(SL_VAR, var, type, 1, from, to, extver), name, flags, guiproc, startup, patxname, def, max, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr)
#define SDTG_MMANY(name, type, flags, guiflags, var, def, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(ManyOfMany, SLEG_GENERAL_X(SL_VAR, var, type | flags, 1, from, to, extver), name, guiflags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr)
#define SDTG_MMANY(name, type, flags, var, def, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(ManyOfMany, SLEG_GENERAL_X(SL_VAR, var, type, 1, from, to, extver), name, flags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr)
#define SDTG_NULL(length, from, to, extver)\
NSD(Null, SLE_CONDNULL_X(length, from, to, extver))
/* Macros for various objects to go in the configuration file.
* This section is for structures where their various members are saved */
#define SDT_VAR(base, var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Int, SLE_GENERAL_X(SL_VAR, base, var, type | flags, 1, from, to, extver), #var, guiflags, guiproc, startup, patxname, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback, nullptr)
#define SDT_VAR(base, var, type, flags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Int, SLE_GENERAL_X(SL_VAR, base, var, type, 1, from, to, extver), #var, flags, guiproc, startup, patxname, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback, nullptr)
#define SDT_ENUM(base, var, type, flags, guiflags, def, str, strhelp, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname, enumlist)\
NSD(Int, SLE_GENERAL_X(SL_VAR, base, var, type | flags, 1, from, to, extver), #var, guiflags | SF_ENUM, guiproc, startup, patxname, def, 0, 0, 0, str, strhelp, STR_NULL, cat, pre_check, post_callback, enumlist)
#define SDT_ENUM(base, var, type, flags, def, str, strhelp, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname, enumlist)\
NSD(Int, SLE_GENERAL_X(SL_VAR, base, var, type, 1, from, to, extver), #var, flags | SF_ENUM, guiproc, startup, patxname, def, 0, 0, 0, str, strhelp, STR_NULL, cat, pre_check, post_callback, enumlist)
#define SDT_BOOL(base, var, flags, guiflags, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Bool, SLE_GENERAL_X(SL_VAR, base, var, SLE_BOOL | flags, 1, from, to, extver), #var, guiflags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback)
#define SDT_BOOL(base, var, flags, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(Bool, SLE_GENERAL_X(SL_VAR, base, var, SLE_BOOL, 1, from, to, extver), #var, flags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback)
#define SDT_LIST(base, var, type, flags, guiflags, def, from, to, extver, cat, guiproc, startup, patxname)\
NSD(List, SLE_GENERAL_X(SL_ARR, base, var, type | flags, lengthof(((base*)8)->var), from, to, extver), #var, guiflags, guiproc, startup, patxname, def)
#define SDT_LIST(base, var, type, flags, def, from, to, extver, cat, guiproc, startup, patxname)\
NSD(List, SLE_GENERAL_X(SL_ARR, base, var, type, lengthof(((base*)8)->var), from, to, extver), #var, flags, guiproc, startup, patxname, def)
#define SDT_SSTR(base, var, type, flags, guiflags, def, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(String, SLE_GENERAL_X(SL_STDSTR, base, var, type | flags, sizeof(((base*)8)->var), from, to, extver), #var, guiflags, guiproc, startup, patxname, def, 0, pre_check, post_callback)
#define SDT_SSTR(base, var, type, flags, def, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
NSD(String, SLE_GENERAL_X(SL_STDSTR, base, var, type, sizeof(((base*)8)->var), from, to, extver), #var, flags, guiproc, startup, patxname, def, 0, pre_check, post_callback)
#define SDT_OMANY(base, var, type, flags, guiflags, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, load, cat, guiproc, startup, patxname)\
NSD(OneOfMany, SLE_GENERAL_X(SL_VAR, base, var, type | flags, 1, from, to, extver), #var, guiflags, guiproc, startup, patxname, def, max, str, strhelp, strval, cat, pre_check, post_callback, full, load)
#define SDT_OMANY(base, var, type, flags, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, load, cat, guiproc, startup, patxname)\
NSD(OneOfMany, SLE_GENERAL_X(SL_VAR, base, var, type, 1, from, to, extver), #var, flags, guiproc, startup, patxname, def, max, str, strhelp, strval, cat, pre_check, post_callback, full, load)
#define SDT_MMANY(base, var, type, flags, guiflags, def, full, str, pre_check, post_callback, strhelp, strval, from, to, extver, cat, guiproc, startup, patxname)\
NSD(ManyOfMany, SLE_GENERAL_X(SL_VAR, base, var, type | flags, 1, from, to, extver), #var, guiflags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr)
#define SDT_MMANY(base, var, type, flags, def, full, str, pre_check, post_callback, strhelp, strval, from, to, extver, cat, guiproc, startup, patxname)\
NSD(ManyOfMany, SLE_GENERAL_X(SL_VAR, base, var, type, 1, from, to, extver), #var, flags, guiproc, startup, patxname, def, str, strhelp, strval, cat, pre_check, post_callback, full, nullptr)
#define SDT_NULL(length, from, to, extver)\
NSD(Null, SLE_CONDNULL_X(length, from, to, extver))
#define SDTC_VAR(var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_VAR(#var, type, flags, guiflags, _settings_client.var, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)
#define SDTC_VAR(var, type, flags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_VAR(#var, type, flags, _settings_client.var, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)
#define SDTC_BOOL(var, flags, guiflags, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_BOOL(#var, flags, guiflags, _settings_client.var, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)
#define SDTC_BOOL(var, flags, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_BOOL(#var, flags, _settings_client.var, def, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)
#define SDTC_LIST(var, type, flags, guiflags, def, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_LIST(#var, type, flags, guiflags, _settings_client.var, def, lengthof(_settings_client.var), from, to, extver, cat, guiproc, startup, patxname)
#define SDTC_LIST(var, type, flags, def, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_LIST(#var, type, flags, _settings_client.var, def, lengthof(_settings_client.var), from, to, extver, cat, guiproc, startup, patxname)
#define SDTC_SSTR(var, type, flags, guiflags, def, max_length, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_SSTR(#var, type, flags, guiflags, _settings_client.var, def, max_length, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
#define SDTC_SSTR(var, type, flags, def, max_length, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_SSTR(#var, type, flags, _settings_client.var, def, max_length, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
#define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_OMANY(#var, type, flags, guiflags, _settings_client.var, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)
#define SDTC_OMANY(var, type, flags, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)\
SDTG_OMANY(#var, type, flags, _settings_client.var, def, max, full, str, strhelp, strval, pre_check, post_callback, from, to, extver, cat, guiproc, startup, patxname)
#define SDT_XREF(from, to, extver, xref, xrefcvt)\
NSD(Xref, SLE_CONDNULL_X(0, from, to, extver), SettingsXref(xref, xrefcvt))

@ -16,16 +16,15 @@ static const SettingTable _company_settings{
[post-amble]
};
[templates]
SDT_BOOL = SDT_BOOL(CompanySettings, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, $patxname),
SDT_VAR = SDT_VAR(CompanySettings, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, $patxname),
SDT_BOOL = SDT_BOOL(CompanySettings, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, $patxname),
SDT_VAR = SDT_VAR(CompanySettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, $patxname),
SDT_NULL = SDT_NULL($length, $from, $to, $extver),
[validation]
SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for CompanySettings.$var exceeds storage size");
[defaults]
flags = 0
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT
@ -53,7 +52,7 @@ cat = SC_BASIC
[SDT_VAR]
var = engine_renew_months
type = SLE_INT16
guiflags = SF_PER_COMPANY | SF_GUI_NEGATIVE_IS_SPECIAL
flags = SF_PER_COMPANY | SF_GUI_NEGATIVE_IS_SPECIAL
def = 6
min = -12
max = 12
@ -64,7 +63,7 @@ strval = STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE
[SDT_VAR]
var = engine_renew_money
type = SLE_UINT
guiflags = SF_PER_COMPANY | SF_GUI_CURRENCY
flags = SF_PER_COMPANY | SF_GUI_CURRENCY
def = 100000
min = 0
max = 2000000
@ -91,7 +90,7 @@ post_cb = UpdateServiceInterval
[SDT_VAR]
var = vehicle.servint_trains
type = SLE_UINT16
guiflags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
def = 150
min = 5
max = 800
@ -104,7 +103,7 @@ post_cb = [](auto new_value) { UpdateServiceInterval(VEH_TRAIN, new_value); }
[SDT_VAR]
var = vehicle.servint_roadveh
type = SLE_UINT16
guiflags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
def = 150
min = 5
max = 800
@ -117,7 +116,7 @@ post_cb = [](auto new_value) { UpdateServiceInterval(VEH_ROAD, new_value); }
[SDT_VAR]
var = vehicle.servint_ships
type = SLE_UINT16
guiflags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
def = 360
min = 5
max = 800
@ -130,7 +129,7 @@ post_cb = [](auto new_value) { UpdateServiceInterval(VEH_SHIP, new_value); }
[SDT_VAR]
var = vehicle.servint_aircraft
type = SLE_UINT16
guiflags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
flags = SF_PER_COMPANY | SF_GUI_0_IS_SPECIAL
def = 100
min = 5
max = 800
@ -143,7 +142,7 @@ post_cb = [](auto new_value) { UpdateServiceInterval(VEH_AIRCRAFT, new_value);
[SDT_BOOL]
base = CompanySettings
var = vehicle.auto_timetable_by_default
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = false
str = STR_CONFIG_SETTING_AUTO_TIMETABLE_BY_DEFAULT
strhelp = STR_CONFIG_SETTING_AUTO_TIMETABLE_BY_DEFAULT_HELPTEXT
@ -152,7 +151,7 @@ patxname = ""vehicle.auto_timetable_by_default""
[SDT_BOOL]
base = CompanySettings
var = vehicle.auto_separation_by_default
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = true
str = STR_CONFIG_SETTING_TIMETABLE_SEPARATION_BY_DEFAULT
strhelp = STR_CONFIG_SETTING_TIMETABLE_SEPARATION_BY_DEFAULT_HELPTEXT
@ -162,7 +161,7 @@ patxname = ""vehicle.auto_separation_by_default""
base = CompanySettings
var = auto_timetable_separation_rate
type = SLE_UINT8
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = 40
min = 0
max = 100
@ -177,7 +176,7 @@ patxname = ""auto_timetable_separation_rate""
base = CompanySettings
var = timetable_autofill_rounding
type = SLE_UINT16
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = 74
min = 1
max = 1000
@ -192,7 +191,7 @@ patxname = ""timetable_autofill_rounding""
base = CompanySettings
var = order_occupancy_smoothness
type = SLE_UINT8
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = 75
min = 0
max = 100
@ -206,7 +205,7 @@ patxname = ""order_occupancy_smoothness""
[SDT_BOOL]
base = CompanySettings
var = infra_others_buy_in_depot[0]
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = false
str = STR_CONFIG_SETTING_INFRA_OTHERS_BUY_IN_DEPOT_RAIL
patxname = ""infra_sharing.infra_others_buy_in_depot.rail""
@ -214,7 +213,7 @@ patxname = ""infra_sharing.infra_others_buy_in_depot.rail""
[SDT_BOOL]
base = CompanySettings
var = infra_others_buy_in_depot[1]
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = false
str = STR_CONFIG_SETTING_INFRA_OTHERS_BUY_IN_DEPOT_ROAD
patxname = ""infra_sharing.infra_others_buy_in_depot.road""
@ -222,7 +221,7 @@ patxname = ""infra_sharing.infra_others_buy_in_depot.road""
[SDT_BOOL]
base = CompanySettings
var = infra_others_buy_in_depot[2]
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = false
str = STR_CONFIG_SETTING_INFRA_OTHERS_BUY_IN_DEPOT_WATER
patxname = ""infra_sharing.infra_others_buy_in_depot.water""
@ -230,7 +229,7 @@ patxname = ""infra_sharing.infra_others_buy_in_depot.water""
[SDT_BOOL]
base = CompanySettings
var = infra_others_buy_in_depot[3]
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = false
str = STR_CONFIG_SETTING_INFRA_OTHERS_BUY_IN_DEPOT_AIR
patxname = ""infra_sharing.infra_others_buy_in_depot.air""
@ -239,7 +238,7 @@ patxname = ""infra_sharing.infra_others_buy_in_depot.air""
[SDT_BOOL]
base = CompanySettings
var = advance_order_on_clone
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = false
str = STR_CONFIG_SETTING_ADVANCE_ORDER_ON_CLONE
strhelp = STR_CONFIG_SETTING_ADVANCE_ORDER_ON_CLONE_HELPTEXT
@ -248,7 +247,7 @@ patxname = ""advance_order_on_clone""
[SDT_BOOL]
base = CompanySettings
var = copy_clone_add_to_group
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = true
str = STR_CONFIG_SETTING_COPY_CLONE_ADD_TO_GROUP
strhelp = STR_CONFIG_SETTING_COPY_CLONE_ADD_TO_GROUP_HELPTEXT
@ -258,7 +257,7 @@ patxname = ""copy_clone_add_to_group""
base = CompanySettings
var = simulated_wormhole_signals
type = SLE_UINT8
guiflags = SF_PER_COMPANY
flags = SF_PER_COMPANY
def = 4
min = 1
max = 16

@ -11,15 +11,14 @@ static const SettingTable _currency_settings{
[post-amble]
};
[templates]
SDT_VAR = SDT_VAR (CurrencySpec, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_SSTR = SDT_SSTR(CurrencySpec, $var, $type, $flags, $guiflags, $def, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_VAR = SDT_VAR (CurrencySpec, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_SSTR = SDT_SSTR(CurrencySpec, $var, $type, $flags, $def, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
[validation]
SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for CurrencySpec.$var exceeds storage size");
[defaults]
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SF_NONE
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT

@ -47,13 +47,13 @@ static const SettingTable _gameopt_settings{
[post-amble]
};
[templates]
SDTG_LIST = SDTG_LIST($name, $type, $flags, $guiflags, $var, $def, $length, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_NULL = SDT_NULL( $length, $from, $to, $extver),
SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $load, $cat, $guiproc, $startup, nullptr),
SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_LIST = SDTG_LIST($name, $type, $flags, $var, $def, $length, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_NULL = SDT_NULL( $length, $from, $to, $extver),
SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $var, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_OMANY = SDT_OMANY(GameSettings, $var, $type, $flags, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $load, $cat, $guiproc, $startup, nullptr),
SDT_VAR = SDT_VAR(GameSettings, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
[validation]
SDTG_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
@ -63,8 +63,7 @@ SDT_OMANY = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$va
SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for GameSettings.$var exceeds storage size");
[defaults]
flags = 0
guiflags = SF_NONE
flags = SF_NONE
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT
@ -86,7 +85,7 @@ name = ""diff_custom""
sdt_cmd = SDT_INTLIST
sle_cmd = SL_ARR
type = SLE_FILE_I16 | SLE_VAR_U16
flags = SLF_NOT_IN_CONFIG
flags = SF_NOT_IN_CONFIG
var = _old_diff_custom
length = 17
def = nullptr
@ -97,19 +96,18 @@ name = ""diff_custom""
sdt_cmd = SDT_INTLIST
sle_cmd = SL_ARR
type = SLE_UINT16
flags = SLF_NOT_IN_CONFIG
flags = SF_NOT_IN_CONFIG
var = _old_diff_custom
length = 18
def = nullptr
full = nullptr
from = SLV_4
##
[SDTG_VAR]
name = ""diff_level""
var = _old_diff_level
type = SLE_UINT8
flags = SLF_NOT_IN_CONFIG
flags = SF_NOT_IN_CONFIG
def = SP_CUSTOM
min = SP_EASY
max = SP_CUSTOM
@ -118,7 +116,7 @@ cat = SC_BASIC
[SDT_OMANY]
var = locale.currency
type = SLE_UINT8
flags = SLF_NO_NETWORK_SYNC
flags = SF_NO_NETWORK_SYNC
def = 0
max = CURRENCY_END - 1
full = _locale_currencies
@ -128,7 +126,7 @@ cat = SC_BASIC
name = ""units""
var = _old_units
type = SLE_UINT8
flags = SLF_NOT_IN_CONFIG
flags = SF_NOT_IN_CONFIG
def = 1
max = 2
full = _locale_units
@ -179,8 +177,7 @@ to = SLV_23
[SDTC_OMANY]
var = gui.autosave
type = SLE_UINT8
from = SLV_23
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
def = 1
max = 4
full = _autosave_interval

@ -25,20 +25,19 @@ static const SettingTable _misc_settings{
[post-amble]
};
[templates]
SDTG_LIST = SDTG_LIST($name, $type, $flags, $guiflags, $var, $def, $length, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $guiflags, $var, $def, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_SSTR = SDTG_SSTR($name, $type, $flags, $guiflags, $var, $def, 0, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_LIST = SDTG_LIST($name, $type, $flags, $var, $def, $length, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $var, $def, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $var, $def, $max, $full, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_SSTR = SDTG_SSTR($name, $type, $flags, $var, $def, 0, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_BOOL = SDTG_BOOL($name, $flags, $var, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
[validation]
SDTG_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
SDTG_OMANY = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
[defaults]
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SF_NONE
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT

File diff suppressed because it is too large Load Diff

@ -17,15 +17,14 @@ static const SettingTable _win32_settings{
};
#endif /* _WIN32 */
[templates]
SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $guiproc, $startup, $extver, nullptr),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $guiproc, $startup, $extver, nullptr),
SDTG_BOOL = SDTG_BOOL($name, $flags, $var, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $guiproc, $startup, $extver, nullptr),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $cat, $guiproc, $startup, $extver, nullptr),
[validation]
SDTG_VAR = static_assert($max <= MAX_$type, "Maximum value for $var exceeds storage size");
[defaults]
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SF_NONE
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT

@ -13,15 +13,14 @@ static const SettingTable _window_settings{
[post-amble]
};
[templates]
SDT_BOOL = SDT_BOOL(WindowDesc, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_VAR = SDT_VAR(WindowDesc, $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_BOOL = SDT_BOOL(WindowDesc, $var, $flags, $def, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
SDT_VAR = SDT_VAR(WindowDesc, $var, $type, $flags, $def, $min, $max, $interval, $str, $strhelp, $strval, $pre_cb, $post_cb, $from, $to, $extver, $cat, $guiproc, $startup, nullptr),
[validation]
SDT_VAR = static_assert($max <= MAX_$type, "Maximum value for WindowDesc.$var exceeds storage size");
[defaults]
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SF_NONE
flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
interval = 0
str = STR_NULL
strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT

Loading…
Cancel
Save