Merge branch 'master' into jgrpp

# Conflicts:
#	.github/workflows/release-windows.yml
#	src/company_base.h
#	src/company_cmd.cpp
#	src/company_gui.cpp
#	src/console_cmds.cpp
#	src/economy.cpp
#	src/economy_cmd.h
#	src/fios.h
#	src/goal.cpp
#	src/group_gui.cpp
#	src/network/core/config.h
#	src/network/network_admin.cpp
#	src/newgrf_config.cpp
#	src/os/windows/win32.cpp
#	src/saveload/afterload.cpp
#	src/saveload/company_sl.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload_error.hpp
#	src/settings_gui.cpp
#	src/ship_cmd.cpp
#	src/stdafx.h
#	src/story.cpp
#	src/story_base.h
#	src/string.cpp
#	src/table/settings/economy_settings.ini
#	src/tests/CMakeLists.txt
#	src/tests/math_func.cpp
This commit is contained in:
Jonathan G Rennison
2023-05-30 00:49:14 +01:00
156 changed files with 2979 additions and 4098 deletions

View File

@@ -2116,22 +2116,6 @@ bool AfterLoadGame()
}
}
if (IsSavegameVersionBefore(SLV_84)) {
/* Set all share owners to INVALID_COMPANY for
* 1) all inactive companies
* (when inactive companies were stored in the savegame - TTD, TTDP and some
* *really* old revisions of OTTD; else it is already set in InitializeCompanies())
* 2) shares that are owned by inactive companies or self
* (caused by cheating clients in earlier revisions) */
for (Company *c : Company::Iterate()) {
for (uint i = 0; i < 4; i++) {
CompanyID company = c->share_owners[i];
if (company == INVALID_COMPANY) continue;
if (!Company::IsValidID(company) || company == c->index) c->share_owners[i] = INVALID_COMPANY;
}
}
}
/* The water class was moved/unified. */
if (IsSavegameVersionBefore(SLV_146)) {
for (TileIndex t = 0; t < map_size; t++) {

View File

@@ -277,7 +277,7 @@ static const SaveLoad _company_desc[] = {
SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_ARR(CompanyProperties, share_owners, SLE_UINT8, 4),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_NO_COMPANY_SHARES, 0, 0)), // share_owners
SLE_VAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8),

View File

@@ -198,6 +198,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_CONSISTENT_PARTIAL_Z, XSCF_NULL, 1, 1, "consistent_partial_z", nullptr, nullptr, nullptr },
{ XSLFI_MORE_CARGO_AGE, XSCF_NULL, 1, 1, "more_cargo_age", nullptr, nullptr, nullptr },
{ XSLFI_AI_START_DATE, XSCF_NULL, 1, 1, "slv_ai_start_date", nullptr, nullptr, nullptr },
{ XSLFI_NO_COMPANY_SHARES, XSCF_NULL, 1, 1, "no_company_shares", nullptr, nullptr, nullptr },
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
};
@@ -622,7 +623,7 @@ static void Load_SLXI()
int64 args_array[] = { _sl_xv_version_label.empty() ? STR_EMPTY : STR_GAME_SAVELOAD_FROM_VERSION, (int64)(size_t)_sl_xv_version_label.c_str(), (int64)(size_t)feature, p1, p2 };
StringParameters tmp_params(args_array);
GetStringWithArgs(buf, str, &tmp_params, lastof(buf));
SlError(STR_JUST_RAW_STRING, buf, false);
SlError(STR_JUST_RAW_STRING, buf);
};
uint32 item_count = SlReadUint32();

View File

@@ -149,7 +149,8 @@ enum SlXvFeatureIndex {
XSLFI_VELOCITY_NAUTICAL, ///< See: SLV_VELOCITY_NAUTICAL (PR #10594)
XSLFI_CONSISTENT_PARTIAL_Z, ///< See: SLV_CONSISTENT_PARTIAL_Z (PR #10570)
XSLFI_MORE_CARGO_AGE, ///< See: SLV_MORE_CARGO_AGE (PR #10596)
XSLFI_AI_START_DATE, ///< See: SLV_AI_START_DATE (PR PR#10653)
XSLFI_AI_START_DATE, ///< See: SLV_AI_START_DATE (PR #10653)
XSLFI_NO_COMPANY_SHARES, ///< See: PR #10709
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk

View File

@@ -15,12 +15,12 @@
#include "../safeguards.h"
static const SaveLoad _goals_desc[] = {
SLE_VAR(Goal, company, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, type, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, dst, SLE_UINT32),
SLE_STR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_CONDSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION),
SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
SLE_VAR(Goal, company, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, type, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, dst, SLE_UINT32),
SLE_SSTR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL),
SLE_CONDSSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, SLV_182, SL_MAX_VERSION),
SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
};
static void Save_GOAL()

View File

@@ -942,10 +942,8 @@ static const OldChunks _company_chunk[] = {
OCL_CNULL( OC_TTD, 1 ), // Old AI
OCL_CNULL( OC_TTD, 1 ), // avail_railtypes
OCL_SVAR( OC_TILE, Company, location_of_HQ ),
OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[0] ),
OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[1] ),
OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[2] ),
OCL_SVAR( OC_TTD | OC_UINT8, Company, share_owners[3] ),
OCL_NULL( 4 ), // Shares
OCL_CNULL( OC_TTD, 8 ), ///< junk at end of chunk

View File

@@ -241,7 +241,7 @@ struct SaveLoadParams {
LoadFilter *lf; ///< Filter to read the savegame from.
StringID error_str; ///< the translatable error message to show
char *extra_msg; ///< the error message
std::string extra_msg; ///< the error message
bool saveinprogress; ///< Whether there is currently a save in progress.
SaveModeFlags save_flags; ///< Save mode flags
@@ -398,7 +398,7 @@ static void SlNullPointers()
struct ThreadSlErrorException {
StringID string;
const char *extra_msg;
std::string extra_msg;
};
/**
@@ -409,26 +409,19 @@ struct ThreadSlErrorException {
* @note This function does never return as it throws an exception to
* break out of all the saveload code.
*/
void NORETURN SlError(StringID string, const char *extra_msg, bool already_malloced)
void NORETURN SlError(StringID string, std::string extra_msg)
{
char *str = nullptr;
if (extra_msg != nullptr) {
str = already_malloced ? const_cast<char *>(extra_msg) : stredup(extra_msg);
}
if (IsNonMainThread() && IsNonGameThread() && _sl.action != SLA_SAVE) {
throw ThreadSlErrorException{ string, extra_msg };
throw ThreadSlErrorException{ string, std::move(extra_msg) };
}
/* Distinguish between loading into _load_check_data vs. normal save/load. */
if (_sl.action == SLA_LOAD_CHECK) {
_load_check_data.error = string;
free(_load_check_data.error_data);
_load_check_data.error_data = str;
_load_check_data.error_msg = std::move(extra_msg);
} else {
_sl.error_str = string;
free(_sl.extra_msg);
_sl.extra_msg = str;
_sl.extra_msg = std::move(extra_msg);
}
/* We have to nullptr all pointers here; we might be in a state where
@@ -450,9 +443,9 @@ void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...)
{
va_list va;
va_start(va, msg);
char *str = str_vfmt(msg, va);
std::string str = stdstr_vfmt(msg, va);
va_end(va);
SlError(string, str, true);
SlError(string, std::move(str));
}
/**
@@ -462,9 +455,9 @@ void NORETURN CDECL SlErrorFmt(StringID string, const char *msg, ...)
* @note This function does never return as it throws an exception to
* break out of all the saveload code.
*/
void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced)
void NORETURN SlErrorCorrupt(std::string msg)
{
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg, already_malloced);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, std::move(msg));
}
/**
@@ -478,9 +471,9 @@ void NORETURN CDECL SlErrorCorruptFmt(const char *format, ...)
{
va_list va;
va_start(va, format);
char *str = str_vfmt(format, va);
std::string str = stdstr_vfmt(format, va);
va_end(va);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, str, true);
SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, std::move(str));
}
typedef void (*AsyncSaveFinishProc)(); ///< Callback for when the savegame loading is finished.
@@ -2267,7 +2260,7 @@ static void SlLoadCheckChunk(const ChunkHandler *ch)
if (ext_flags & SLCEHF_BIG_RIFF) {
uint64 full_len = len | (static_cast<uint64>(SlReadUint32()) << 28);
if (full_len >= (1LL << 32)) {
SlErrorCorrupt("Chunk size too large: " OTTD_PRINTFHEX64, full_len);
SlErrorCorruptFmt("Chunk size too large: " OTTD_PRINTFHEX64, full_len);
}
len = static_cast<size_t>(full_len);
}
@@ -3391,7 +3384,7 @@ struct ThreadedLoadFilter : LoadFilter {
}
} catch (const ThreadSlErrorException &ex) {
std::unique_lock<std::mutex> lk(self->mutex);
self->caught_exception = ex;
self->caught_exception = std::move(ex);
self->have_exception = true;
self->empty_cv.notify_one();
}
@@ -3815,22 +3808,15 @@ void FileToSaveLoad::SetMode(SaveLoadOperation fop, AbstractFileType aft, Detail
this->abstract_ftype = aft;
}
/**
* Set the name of the file.
* @param name Name of the file.
*/
void FileToSaveLoad::SetName(const char *name)
{
this->name = name;
}
/**
* Set the title of the file.
* @param title Title of the file.
*/
void FileToSaveLoad::SetTitle(const char *title)
void FileToSaveLoad::Set(const FiosItem &item)
{
strecpy(this->title, title, lastof(this->title));
this->SetMode(item.type);
this->name = item.name;
this->title = item.title;
}
bool SaveLoadFileTypeIsScenario()

View File

@@ -30,16 +30,15 @@ enum SaveOrLoadResult {
/** Deals with the type of the savegame, independent of extension */
struct FileToSaveLoad {
SaveLoadOperation file_op; ///< File operation to perform.
SaveLoadOperation file_op; ///< File operation to perform.
DetailedFileType detail_ftype; ///< Concrete file type (PNG, BMP, old save, etc).
AbstractFileType abstract_ftype; ///< Abstract type of file (scenario, heightmap, etc).
std::string name; ///< Name of the file.
char title[255]; ///< Internal name of the game.
std::string title; ///< Internal name of the game.
void SetMode(FiosType ft);
void SetMode(SaveLoadOperation fop, AbstractFileType aft, DetailedFileType dft);
void SetName(const char *name);
void SetTitle(const char *title);
void Set(const FiosItem &item);
};
/** Types of save games. */

View File

@@ -405,8 +405,8 @@ void SlSkipBytes(size_t length);
size_t SlGetBytesRead();
size_t SlGetBytesWritten();
void NORETURN SlError(StringID string, const char *extra_msg = nullptr, bool already_malloced = false);
void NORETURN SlErrorCorrupt(const char *msg, bool already_malloced = false);
void NORETURN SlError(StringID string, std::string extra_msg = {});
void NORETURN SlErrorCorrupt(std::string msg);
void NORETURN CDECL SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2);
bool SaveLoadFileTypeIsScenario();

View File

@@ -33,7 +33,7 @@ static const SaveLoad _story_page_elements_desc[] = {
SLE_CONDVAR(StoryPageElement, type, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32),
SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_SSTR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL),
};
static void Save_STORY_PAGE_ELEMENT()
@@ -67,7 +67,7 @@ static const SaveLoad _story_pages_desc[] = {
SLE_VAR(StoryPage, date, SLE_UINT32),
SLE_CONDVAR(StoryPage, company, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPage, company, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_SSTR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL),
};
static void Save_STORY_PAGE()

View File

@@ -260,8 +260,6 @@ static const SaveLoad _company_desc[] = {
SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31),
SLE_CONDVAR(CompanyProperties, inaugurated_year, SLE_INT32, SLV_31, SL_MAX_VERSION),
SLE_ARR(CompanyProperties, share_owners, SLE_UINT8, 4),
SLE_CONDVAR(CompanyProperties, num_valid_stat_ent, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH),
SLE_VAR(CompanyProperties, months_of_bankruptcy, SLE_UINT8),

View File

@@ -108,7 +108,7 @@ const SaveLoadCompat _company_sl_compat[] = {
SLC_VAR("location_of_HQ"),
SLC_VAR("last_build_coordinate"),
SLC_VAR("inaugurated_year"),
SLC_VAR("share_owners"),
SLC_NULL(4, SL_MIN_VERSION, SLV_TABLE_CHUNKS),
SLC_VAR("num_valid_stat_ent"),
SLC_VAR("months_of_bankruptcy"),
SLC_VAR("bankrupt_asked"),

View File

@@ -156,8 +156,8 @@ const SaveLoadCompat _settings_sl_compat[] = {
SLC_NULL(4, SL_MIN_VERSION, SLV_105),
SLC_VAR("game_creation.ending_year"),
SLC_VAR("economy.type"),
SLC_VAR("economy.allow_shares"),
SLC_VAR("economy.min_years_for_shares"),
SLC_NULL(1, SL_MIN_VERSION, SLV_TABLE_CHUNKS),
SLC_NULL(1, SLV_TRADING_AGE, SLV_TABLE_CHUNKS),
SLC_VAR("economy.feeder_payment_share"),
SLC_VAR("economy.town_growth_rate"),
SLC_VAR("economy.larger_towns"),

View File

@@ -19,12 +19,12 @@
namespace upstream_sl {
static const SaveLoad _goals_desc[] = {
SLE_VAR(Goal, company, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, type, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, dst, SLE_UINT32),
SLE_STR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_CONDSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_182, SL_MAX_VERSION),
SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
SLE_VAR(Goal, company, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, type, SLE_FILE_U16 | SLE_VAR_U8),
SLE_VAR(Goal, dst, SLE_UINT32),
SLE_SSTR(Goal, text, SLE_STR | SLF_ALLOW_CONTROL),
SLE_CONDSSTR(Goal, progress, SLE_STR | SLF_ALLOW_CONTROL, SLV_182, SL_MAX_VERSION),
SLE_CONDVAR(Goal, completed, SLE_BOOL, SLV_182, SL_MAX_VERSION),
};
struct GOALChunkHandler : ChunkHandler {

View File

@@ -25,7 +25,7 @@ static const SaveLoad _story_page_elements_desc[] = {
SLE_CONDVAR(StoryPageElement, type, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPageElement, type, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_VAR(StoryPageElement, referenced_id, SLE_UINT32),
SLE_STR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_SSTR(StoryPageElement, text, SLE_STR | SLF_ALLOW_CONTROL),
};
struct STPEChunkHandler : ChunkHandler {
@@ -67,7 +67,7 @@ static const SaveLoad _story_pages_desc[] = {
SLE_VAR(StoryPage, date, SLE_UINT32),
SLE_CONDVAR(StoryPage, company, SLE_FILE_U16 | SLE_VAR_U8, SL_MIN_VERSION, SLV_185),
SLE_CONDVAR(StoryPage, company, SLE_UINT8, SLV_185, SL_MAX_VERSION),
SLE_STR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL, 0),
SLE_SSTR(StoryPage, title, SLE_STR | SLF_ALLOW_CONTROL),
};
struct STPAChunkHandler : ChunkHandler {