Merge branch 'master' into jgrpp

# Conflicts:
#	src/cheat_gui.cpp
#	src/command.cpp
#	src/command_func.h
#	src/company_base.h
#	src/debug.cpp
#	src/debug.h
#	src/economy.cpp
#	src/engine_type.h
#	src/graph_gui.cpp
#	src/misc_cmd.cpp
#	src/misc_cmd.h
#	src/network/core/os_abstraction.cpp
#	src/openttd.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/settings_type.h
#	src/ship_cmd.cpp
#	src/stdafx.h
#	src/tests/bitmath_func.cpp
#	src/town_cmd.cpp
#	src/town_gui.cpp
This commit is contained in:
Jonathan G Rennison
2024-02-17 11:53:23 +00:00
66 changed files with 554 additions and 234 deletions

View File

@@ -24,6 +24,7 @@
*
* API removals:
* \li AIError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
* \li AIInfo::CONFIG_RANDOM, no longer used.
*
* Other changes:
* \li AIGroupList accepts an optional filter function

View File

@@ -47,6 +47,8 @@
* \li GSCompany::SetAutoRenewStatus
* \li GSCompany::SetAutoRenewMonths
* \li GSCompany::SetAutoRenewMoney
* \li GSCompany::SetMaxLoanAmountForCompany
* \li GSCompany::ResetMaxLoanAmountForCompany
* \li GSGameSettings::IsDisabledVehicleType
* \li GSGroup::GroupID
* \li GSGroup::IsValidGroup
@@ -88,6 +90,7 @@
*
* API removals:
* \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
* \li AIInfo::CONFIG_RANDOM, no longer used.
*
* Other changes:
* \li GSGroupList accepts an optional filter function

View File

@@ -186,7 +186,7 @@
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return -1;
return ::Company::Get(company)->money;
return GetAvailableMoney((::CompanyID)company);
}
/* static */ Money ScriptCompany::GetLoanAmount()
@@ -199,7 +199,32 @@
/* static */ Money ScriptCompany::GetMaxLoanAmount()
{
return _economy.max_loan;
if (ScriptCompanyMode::IsDeity()) return _economy.max_loan;
ScriptCompany::CompanyID company = ResolveCompanyID(COMPANY_SELF);
if (company == COMPANY_INVALID) return -1;
return ::Company::Get(company)->GetMaxLoan();
}
/* static */ bool ScriptCompany::SetMaxLoanAmountForCompany(CompanyID company, Money amount)
{
EnforceDeityMode(false);
EnforcePrecondition(false, amount >= 0 && amount <= (Money)MAX_LOAN_LIMIT);
company = ResolveCompanyID(company);
EnforcePrecondition(false, company != COMPANY_INVALID);
return ScriptObject::DoCommandEx(0, company, 0, (uint64_t)amount, CMD_SET_COMPANY_MAX_LOAN);
}
/* static */ bool ScriptCompany::ResetMaxLoanAmountForCompany(CompanyID company)
{
EnforceDeityMode(false);
company = ResolveCompanyID(company);
EnforcePrecondition(false, company != COMPANY_INVALID);
return ScriptObject::DoCommandEx(0, company, 0, (uint64_t)COMPANY_MAX_LOAN_DEFAULT, CMD_SET_COMPANY_MAX_LOAN);
}
/* static */ Money ScriptCompany::GetLoanInterval()

View File

@@ -219,12 +219,38 @@ public:
static Money GetLoanAmount();
/**
* Gets the maximum amount your company can loan.
* Gets the maximum amount your company can loan. In deity mode returns the global max loan.
* @return The maximum amount your company can loan.
* @post GetLoanInterval() is always a multiplier of the return value.
*/
static Money GetMaxLoanAmount();
/**
* Sets the max amount of money company can loan.
* @param company The company ID.
* @param amount Max loan amount. Will be rounded down to a multiple of GetLoanInterval().
* @return True, if the max loan was changed.
* @pre ScriptCompanyMode::IsDeity().
* @pre amount >= 0.
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
* @note You need to create your own news message to inform about max loan change.
* @note Max loan value set with this method is not affected by inflation.
* @api -ai
*/
static bool SetMaxLoanAmountForCompany(CompanyID company, Money amount);
/**
* Makes the max amount of money company can loan follow the global max loan setting.
* @param company The company ID.
* @return True, if the max loan was reset.
* @pre ScriptCompanyMode::IsDeity().
* @pre amount >= 0 && amount <= MAX_LOAN_LIMIT.
* @pre ResolveCompanyID(company) != COMPANY_INVALID.
* @note You need to create your own news message to inform about max loan change.
* @api -ai
*/
static bool ResetMaxLoanAmountForCompany(CompanyID company);
/**
* Gets the interval/loan step.
* @return The loan step.

View File

@@ -203,7 +203,6 @@ public:
/** Miscellaneous flags for Script settings. */
enum ScriptConfigFlags {
CONFIG_NONE, ///< Normal setting.
CONFIG_RANDOM, ///< When randomizing the Script, pick any value between min_value and max_value (inclusive).
CONFIG_BOOLEAN, ///< This value is a boolean (either 0 (false) or 1 (true) ).
CONFIG_INGAME, ///< This setting can be changed while the Script is running.
CONFIG_DEVELOPER, ///< This setting will only be visible when the Script development tools are active.
@@ -236,10 +235,11 @@ public:
* is selected. Required. The value will be clamped in the range
* [MIN(int32_t), MAX(int32_t)] (inclusive).
* - random_deviation If this property has a nonzero value, then the
* actual value of the setting in game will be randomized in the range
* actual value of the setting in game will be randomised in the range
* [user_configured_value - random_deviation, user_configured_value + random_deviation] (inclusive).
* random_deviation sign is ignored and the value is clamped in the range [0, MAX(int32_t)] (inclusive).
* Not allowed if the CONFIG_RANDOM flag is set, otherwise optional.
* The randomisation will happen just before the Script start.
* Not allowed if the CONFIG_BOOLEAN flag is set, otherwise optional.
* - step_size The increase/decrease of the value every time the user
* clicks one of the up/down arrow buttons. Optional, default is 1.
* - flags Bitmask of some flags, see ScriptConfigFlags. Required.

View File

@@ -33,18 +33,6 @@ void ScriptConfig::Change(std::optional<const std::string> name, int version, bo
this->to_load_data.reset();
this->ClearConfigList();
if (_game_mode == GM_NORMAL && this->info != nullptr) {
/* If we're in an existing game and the Script is changed, set all settings
* for the Script that have the random flag to a random value. */
for (const auto &item : *this->info->GetConfigList()) {
if (item.flags & SCRIPTCONFIG_RANDOM) {
this->SetSetting(item.name, ScriptObject::GetRandomizer(OWNER_NONE).Next(item.max_value + 1 - item.min_value) + item.min_value);
}
}
this->AddRandomDeviation();
}
}
ScriptConfig::ScriptConfig(const ScriptConfig *config)
@@ -58,9 +46,6 @@ ScriptConfig::ScriptConfig(const ScriptConfig *config)
for (const auto &item : config->settings) {
this->settings[item.first] = item.second;
}
/* Virtual functions get called statically in constructors, so make it explicit to remove any confusion. */
this->ScriptConfig::AddRandomDeviation();
}
ScriptConfig::~ScriptConfig()

View File

@@ -23,7 +23,7 @@ static const int INT32_DIGITS_WITH_SIGN_AND_TERMINATION = 10 + 1 + 1;
/** Bitmask of flags for Script settings. */
enum ScriptConfigFlags {
SCRIPTCONFIG_NONE = 0x0, ///< No flags set.
SCRIPTCONFIG_RANDOM = 0x1, ///< When randomizing the Script, pick any value between min_value and max_value when on custom difficulty setting.
// Unused flag 0x1.
SCRIPTCONFIG_BOOLEAN = 0x2, ///< This value is a boolean (either 0 (false) or 1 (true) ).
SCRIPTCONFIG_INGAME = 0x4, ///< This setting can be changed while the Script is running.
SCRIPTCONFIG_DEVELOPER = 0x8, ///< This setting will only be visible when the Script development tools are active.

View File

@@ -395,10 +395,18 @@ struct ScriptSettingsWindow : public Window {
TextColour colour;
uint idx = 0;
if (config_item.description.empty()) {
str = STR_JUST_STRING1;
if (this->slot != OWNER_DEITY && !Company::IsValidID(this->slot) && config_item.random_deviation != 0) {
str = STR_AI_SETTINGS_JUST_DEVIATION;
} else {
str = STR_JUST_STRING1;
}
colour = TC_ORANGE;
} else {
str = STR_AI_SETTINGS_SETTING;
if (this->slot != OWNER_DEITY && !Company::IsValidID(this->slot) && config_item.random_deviation != 0) {
str = STR_AI_SETTINGS_SETTING_DEVIATION;
} else {
str = STR_AI_SETTINGS_SETTING;
}
colour = TC_LIGHT_BLUE;
SetDParamStr(idx++, config_item.description);
}
@@ -413,13 +421,35 @@ struct ScriptSettingsWindow : public Window {
DrawArrowButtons(br.left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value);
}
auto config_iterator = config_item.labels.find(current_value);
if (config_iterator != config_item.labels.end()) {
SetDParam(idx++, STR_JUST_RAW_STRING);
SetDParamStr(idx++, config_iterator->second);
if (this->slot == OWNER_DEITY || Company::IsValidID(this->slot) || config_item.random_deviation == 0) {
auto config_iterator = config_item.labels.find(current_value);
if (config_iterator != config_item.labels.end()) {
SetDParam(idx++, STR_JUST_RAW_STRING);
SetDParamStr(idx++, config_iterator->second);
} else {
SetDParam(idx++, STR_JUST_INT);
SetDParam(idx++, current_value);
}
} else {
SetDParam(idx++, STR_JUST_INT);
SetDParam(idx++, current_value);
int min_deviated = std::max(config_item.min_value, current_value - config_item.random_deviation);
auto config_iterator = config_item.labels.find(min_deviated);
if (config_iterator != config_item.labels.end()) {
SetDParam(idx++, STR_JUST_RAW_STRING);
SetDParamStr(idx++, config_iterator->second);
} else {
SetDParam(idx++, STR_JUST_INT);
SetDParam(idx++, min_deviated);
}
int max_deviated = std::min(config_item.max_value, current_value + config_item.random_deviation);
config_iterator = config_item.labels.find(max_deviated);
if (config_iterator != config_item.labels.end()) {
SetDParam(idx++, STR_JUST_RAW_STRING);
SetDParamStr(idx++, config_iterator->second);
} else {
SetDParam(idx++, STR_JUST_INT);
SetDParam(idx++, max_deviated);
}
}
}

View File

@@ -162,12 +162,13 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
}
sq_pop(vm, 1);
/* Don't allow both random_deviation and SCRIPTCONFIG_RANDOM to
/* Don't allow both random_deviation and SCRIPTCONFIG_BOOLEAN to
* be set for the same config item. */
if ((items & 0x200) != 0 && (config.flags & SCRIPTCONFIG_RANDOM) != 0) {
this->engine->ThrowError("Setting both random_deviation and SCRIPTCONFIG_RANDOM is not allowed");
if ((items & 0x200) != 0 && (config.flags & SCRIPTCONFIG_BOOLEAN) != 0) {
this->engine->ThrowError("setting both random_deviation and CONFIG_BOOLEAN is not allowed");
return SQ_ERROR;
}
/* Reset the bit for random_deviation as it's optional. */
items &= ~0x200;