mirror of https://github.com/OpenTTD/OpenTTD
Change: Explicitly control whether to add random deviation
Reloading AIs will only add random deviation if they were a Random AI. Random deviation is no longer applied after selecting a script during a running game. "startai" console command applies random deviation depending on the number of arguments: 0 arguments - Only if the slot config is Random AI. 1 argument - Always, no parameters were provided. 2 arguments - Never, user provided parameters.pull/12011/head
parent
67b0fec6ed
commit
f6ced8d616
|
@ -28,8 +28,9 @@ public:
|
|||
* Start a new AI company.
|
||||
* @param company At which slot the AI company should start.
|
||||
* @param rerandomise_ai Whether to rerandomise the configured AI.
|
||||
* @param deviate Whether to add random deviation to settings that allow it.
|
||||
*/
|
||||
static void StartNew(CompanyID company, bool rerandomise_ai = true);
|
||||
static void StartNew(CompanyID company, bool rerandomise_ai = true, bool deviate = true);
|
||||
|
||||
/**
|
||||
* Called every game-tick to let AIs do something.
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
ScriptConfig()
|
||||
{}
|
||||
|
||||
AIConfig(const AIConfig *config) :
|
||||
ScriptConfig(config)
|
||||
AIConfig(const AIConfig *config, bool add_random_deviation) :
|
||||
ScriptConfig(config, add_random_deviation)
|
||||
{}
|
||||
|
||||
class AIInfo *GetInfo() const;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
return !_networking || (_network_server && _settings_game.ai.ai_in_multiplayer);
|
||||
}
|
||||
|
||||
/* static */ void AI::StartNew(CompanyID company, bool rerandomise_ai)
|
||||
/* static */ void AI::StartNew(CompanyID company, bool rerandomise_ai, bool deviate)
|
||||
{
|
||||
assert(Company::IsValidID(company));
|
||||
|
||||
|
@ -46,8 +46,9 @@
|
|||
info = AI::scanner_info->SelectRandomAI();
|
||||
assert(info != nullptr);
|
||||
/* Load default data and store the name in the settings */
|
||||
config->Change(info->GetName(), -1, false, true);
|
||||
config->Change(info->GetName(), -1, false, true, false);
|
||||
}
|
||||
if (deviate) config->AddRandomDeviation();
|
||||
config->AnchorUnchangeableSettings();
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "network/network_base.h"
|
||||
#include "network/network_admin.h"
|
||||
#include "ai/ai.hpp"
|
||||
#include "ai/ai_config.hpp"
|
||||
#include "company_manager_face.h"
|
||||
#include "window_func.h"
|
||||
#include "strings_func.h"
|
||||
|
@ -577,9 +578,10 @@ void ResetCompanyLivery(Company *c)
|
|||
*
|
||||
* @param is_ai is an AI company?
|
||||
* @param company CompanyID to use for the new company
|
||||
* @param deviate whether to add random deviation to settings that allow it, for the AI company
|
||||
* @return the company struct
|
||||
*/
|
||||
Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
||||
Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY, bool deviate = true)
|
||||
{
|
||||
if (!Company::CanAllocateItem()) return nullptr;
|
||||
|
||||
|
@ -625,7 +627,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
|
|||
BuildOwnerLegend();
|
||||
InvalidateWindowData(WC_SMALLMAP, 0, 1);
|
||||
|
||||
if (is_ai && (!_networking || _network_server)) AI::StartNew(c->index);
|
||||
if (is_ai && (!_networking || _network_server)) AI::StartNew(c->index, true, deviate);
|
||||
|
||||
AI::BroadcastNewEvent(new ScriptEventCompanyNew(c->index), c->index);
|
||||
Game::NewEvent(new ScriptEventCompanyNew(c->index));
|
||||
|
@ -646,9 +648,16 @@ TimeoutTimer<TimerGameTick> _new_competitor_timeout(0, []() {
|
|||
|
||||
if (n >= _settings_game.difficulty.max_no_competitors) return;
|
||||
|
||||
CompanyID cid = COMPANY_FIRST;
|
||||
/* Find the next free slot */
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (c->index != cid) break;
|
||||
cid++;
|
||||
}
|
||||
|
||||
/* Send a command to all clients to start up a new AI.
|
||||
* Works fine for Multiplayer and Singleplayer */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, cid, CRR_NONE, INVALID_CLIENT_ID, !AIConfig::GetConfig(cid)->HasScript());
|
||||
});
|
||||
|
||||
/** Start of a new game. */
|
||||
|
@ -760,15 +769,36 @@ void OnTick_Companies()
|
|||
/* If the interval is zero, start as many competitors as needed then check every ~10 minutes if a company went bankrupt and needs replacing. */
|
||||
if (timeout == 0) {
|
||||
/* count number of competitors */
|
||||
uint8_t n = 0;
|
||||
uint8_t n_ais = 0;
|
||||
for (const Company *cc : Company::Iterate()) {
|
||||
if (cc->is_ai) n++;
|
||||
if (cc->is_ai) n_ais++;
|
||||
}
|
||||
|
||||
/* Count number of total existing companies. */
|
||||
auto current_companies = Company::GetNumItems();
|
||||
|
||||
CompanyMask ais_to_start = 0;
|
||||
for (auto i = 0; i < _settings_game.difficulty.max_no_competitors; i++) {
|
||||
if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) break;
|
||||
if (n++ >= _settings_game.difficulty.max_no_competitors) break;
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
|
||||
auto count = CountBits(ais_to_start);
|
||||
if (_networking && current_companies + count >= _settings_client.network.max_companies) break;
|
||||
if (n_ais + count >= _settings_game.difficulty.max_no_competitors) break;
|
||||
if (current_companies + count >= MAX_COMPANIES) break;
|
||||
|
||||
/* Find the first company which doesn't exist yet */
|
||||
CompanyID cid = INVALID_COMPANY;
|
||||
for (cid = COMPANY_FIRST; cid < MAX_COMPANIES; cid++) {
|
||||
if (!Company::IsValidID(cid)) {
|
||||
if (count == 0) break;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
assert(count == 0);
|
||||
assert(!HasBit(ais_to_start, cid));
|
||||
SetBit(ais_to_start, cid);
|
||||
}
|
||||
|
||||
for (auto company : SetBitIterator(ais_to_start)) {
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, (CompanyID)company, CRR_NONE, INVALID_CLIENT_ID, !AIConfig::GetConfig((CompanyID)company)->HasScript());
|
||||
}
|
||||
timeout = 10 * 60 * Ticks::TICKS_PER_SECOND;
|
||||
}
|
||||
|
@ -857,7 +887,7 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason)
|
|||
* @param client_id ClientID
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id)
|
||||
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id, bool deviate)
|
||||
{
|
||||
InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);
|
||||
|
||||
|
@ -921,7 +951,7 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID
|
|||
/* For network game, just assume deletion happened. */
|
||||
assert(company_id == INVALID_COMPANY || !Company::IsValidID(company_id));
|
||||
|
||||
Company *c = DoStartupNewCompany(true, company_id);
|
||||
Company *c = DoStartupNewCompany(true, company_id, deviate);
|
||||
if (c != nullptr) NetworkServerNewCompany(c, nullptr);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
enum ClientID : uint32_t;
|
||||
enum Colours : byte;
|
||||
|
||||
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id);
|
||||
CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID company_id, CompanyRemoveReason reason, ClientID client_id, bool deviate);
|
||||
CommandCost CmdGiveMoney(DoCommandFlag flags, Money money, CompanyID dest_company);
|
||||
CommandCost CmdRenameCompany(DoCommandFlag flags, const std::string &text);
|
||||
CommandCost CmdRenamePresident(DoCommandFlag flags, const std::string &text);
|
||||
|
|
|
@ -1015,7 +1015,7 @@ DEF_CONSOLE_CMD(ConResetCompany)
|
|||
}
|
||||
|
||||
/* It is safe to remove this company */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, index, CRR_MANUAL, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, index, CRR_MANUAL, INVALID_CLIENT_ID, false);
|
||||
IConsolePrint(CC_DEFAULT, "Company deleted.");
|
||||
|
||||
return true;
|
||||
|
@ -1350,16 +1350,20 @@ DEF_CONSOLE_CMD(ConStartAI)
|
|||
return true;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
CompanyID cid = COMPANY_FIRST;
|
||||
/* Find the next free slot */
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (c->index != n) break;
|
||||
n++;
|
||||
if (c->index != cid) break;
|
||||
cid++;
|
||||
}
|
||||
|
||||
AIConfig *config = AIConfig::GetConfig((CompanyID)n);
|
||||
AIConfig *config = AIConfig::GetConfig(cid);
|
||||
bool deviate = argc == 1 ? !config->HasScript() : argc == 2;
|
||||
if (argc >= 2) {
|
||||
config->Change(argv[1], -1, false);
|
||||
auto name = std::string(argv[1]);
|
||||
int version = -1;
|
||||
bool force_exact_match = false;
|
||||
config->Change(name, version, force_exact_match, false, deviate);
|
||||
|
||||
/* If the name is not found, and there is a dot in the name,
|
||||
* try again with the assumption everything right of the dot is
|
||||
|
@ -1370,8 +1374,10 @@ DEF_CONSOLE_CMD(ConStartAI)
|
|||
size_t name_length = e - argv[1];
|
||||
e++;
|
||||
|
||||
int version = atoi(e);
|
||||
config->Change(std::string(argv[1], name_length), version, true);
|
||||
version = atoi(e);
|
||||
name = std::string(argv[1], name_length);
|
||||
force_exact_match = true;
|
||||
config->Change(name, version, force_exact_match, false, deviate);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1385,7 +1391,7 @@ DEF_CONSOLE_CMD(ConStartAI)
|
|||
}
|
||||
|
||||
/* Start a new AI company */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, cid, CRR_NONE, INVALID_CLIENT_ID, deviate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1420,9 +1426,11 @@ DEF_CONSOLE_CMD(ConReloadAI)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool deviate = AIConfig::GetConfig(company_id)->IsRandom();
|
||||
|
||||
/* First kill the company of the AI, then start a new one. This should start the current AI again */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, company_id, CRR_MANUAL, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, company_id, CRR_NONE, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, company_id, CRR_MANUAL, INVALID_CLIENT_ID, false);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, company_id, CRR_NONE, INVALID_CLIENT_ID, deviate);
|
||||
IConsolePrint(CC_DEFAULT, "AI reloaded.");
|
||||
|
||||
return true;
|
||||
|
@ -1459,7 +1467,7 @@ DEF_CONSOLE_CMD(ConStopAI)
|
|||
}
|
||||
|
||||
/* Now kill the company of the AI. */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, company_id, CRR_MANUAL, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, company_id, CRR_MANUAL, INVALID_CLIENT_ID, false);
|
||||
IConsolePrint(CC_DEFAULT, "AI stopped, company deleted.");
|
||||
|
||||
return true;
|
||||
|
|
|
@ -645,7 +645,7 @@ static void CompanyCheckBankrupt(Company *c)
|
|||
* player we are sure (the above check) that we are not the local
|
||||
* company and thus we won't be moved. */
|
||||
if (!_networking || _network_server) {
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_BANKRUPT, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_BANKRUPT, INVALID_CLIENT_ID, false);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -31,8 +31,9 @@ public:
|
|||
|
||||
/**
|
||||
* Start up a new GameScript.
|
||||
* @param deviation Whether to add random deviation to settings that allow it.
|
||||
*/
|
||||
static void StartNew();
|
||||
static void StartNew(bool deviation = true);
|
||||
|
||||
/**
|
||||
* Uninitialize the Game system.
|
||||
|
|
|
@ -23,8 +23,8 @@ public:
|
|||
ScriptConfig()
|
||||
{}
|
||||
|
||||
GameConfig(const GameConfig *config) :
|
||||
ScriptConfig(config)
|
||||
GameConfig(const GameConfig *config, bool add_random_deviation) :
|
||||
ScriptConfig(config, add_random_deviation)
|
||||
{}
|
||||
|
||||
class GameInfo *GetInfo() const;
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
/* static */ void Game::StartNew()
|
||||
/* static */ void Game::StartNew(bool deviation)
|
||||
{
|
||||
if (Game::instance != nullptr) return;
|
||||
|
||||
|
@ -83,6 +83,7 @@
|
|||
GameInfo *info = config->GetInfo();
|
||||
if (info == nullptr) return;
|
||||
|
||||
if (deviation) config->AddRandomDeviation();
|
||||
config->AnchorUnchangeableSettings();
|
||||
|
||||
Backup<CompanyID> cur_company(_current_company, FILE_LINE);
|
||||
|
|
14
src/misc.cpp
14
src/misc.cpp
|
@ -187,18 +187,20 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
|||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
_settings_game.ai_config[c] = nullptr;
|
||||
if (_settings_newgame.ai_config[c] != nullptr) {
|
||||
_settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c]);
|
||||
_settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c], true);
|
||||
}
|
||||
}
|
||||
_settings_game.game_config = nullptr;
|
||||
if (_settings_newgame.game_config != nullptr) {
|
||||
_settings_game.game_config = new GameConfig(_settings_newgame.game_config);
|
||||
_settings_game.game_config = new GameConfig(_settings_newgame.game_config, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set random deviation for scripts. */
|
||||
for (auto &ai_config : _settings_game.ai_config) {
|
||||
if (ai_config != nullptr) ai_config->AddRandomDeviation();
|
||||
if (_switch_mode == SM_RESTARTGAME) {
|
||||
/* Simulate random deviation for scripts to keep the randomizer counters in sync, but don't set the deviated values. */
|
||||
for (auto &ai_config : _settings_game.ai_config) {
|
||||
if (ai_config != nullptr) ai_config->AddRandomDeviation();
|
||||
}
|
||||
if (_settings_game.game_config != nullptr) _settings_game.game_config->AddRandomDeviation();
|
||||
}
|
||||
if (_settings_game.game_config != nullptr) _settings_game.game_config->AddRandomDeviation();
|
||||
}
|
||||
|
|
|
@ -894,7 +894,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
|
|||
Debug(net, 9, "Client::join_status = REGISTERING");
|
||||
_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
|
||||
ShowJoinStatusWindow();
|
||||
Command<CMD_COMPANY_CTRL>::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID, false);
|
||||
}
|
||||
} else {
|
||||
/* take control over an existing company */
|
||||
|
|
|
@ -1346,7 +1346,7 @@ static void AdminCompanyResetCallback(Window *, bool confirmed)
|
|||
{
|
||||
if (confirmed) {
|
||||
if (NetworkCompanyHasClients(_admin_company_id)) return;
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, _admin_company_id, CRR_MANUAL, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, _admin_company_id, CRR_MANUAL, INVALID_CLIENT_ID, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1482,9 +1482,9 @@ private:
|
|||
static void OnClickCompanyNew([[maybe_unused]] NetworkClientListWindow *w, [[maybe_unused]] Point pt, CompanyID)
|
||||
{
|
||||
if (_network_server) {
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW, INVALID_COMPANY, CRR_NONE, _network_own_client_id);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW, INVALID_COMPANY, CRR_NONE, _network_own_client_id, false);
|
||||
} else {
|
||||
Command<CMD_COMPANY_CTRL>::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::SendNet(STR_NULL, _local_company, CCA_NEW, INVALID_COMPANY, CRR_NONE, INVALID_CLIENT_ID, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1590,7 +1590,7 @@ static void NetworkAutoCleanCompanies()
|
|||
/* Is the company empty for autoclean_unprotected-months, and is there no protection? */
|
||||
if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) {
|
||||
/* Shut the company down */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID, false);
|
||||
IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no password.", c->index + 1);
|
||||
}
|
||||
/* Is the company empty for autoclean_protected-months, and there is a protection? */
|
||||
|
@ -1604,7 +1604,7 @@ static void NetworkAutoCleanCompanies()
|
|||
/* Is the company empty for autoclean_novehicles-months, and has no vehicles? */
|
||||
if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && !HasBit(has_vehicles, c->index)) {
|
||||
/* Shut the company down */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, c->index, CRR_AUTOCLEAN, INVALID_CLIENT_ID, false);
|
||||
IConsolePrint(CC_INFO, "Auto-cleaned company #{} with no vehicles.", c->index + 1);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -96,7 +96,7 @@ void CallWindowGameTickEvent();
|
|||
bool HandleBootstrap();
|
||||
|
||||
extern void AfterLoadCompanyStats();
|
||||
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
|
||||
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY, bool deviate = true);
|
||||
extern void OSOpenBrowser(const std::string &url);
|
||||
extern void RebuildTownCaches();
|
||||
extern void ShowOSErrorBox(const char *buf, bool system);
|
||||
|
@ -361,12 +361,12 @@ void MakeNewgameSettingsLive()
|
|||
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
|
||||
_settings_game.ai_config[c] = nullptr;
|
||||
if (_settings_newgame.ai_config[c] != nullptr) {
|
||||
_settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c]);
|
||||
_settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c], false);
|
||||
}
|
||||
}
|
||||
_settings_game.game_config = nullptr;
|
||||
if (_settings_newgame.game_config != nullptr) {
|
||||
_settings_game.game_config = new GameConfig(_settings_newgame.game_config);
|
||||
_settings_game.game_config = new GameConfig(_settings_newgame.game_config, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
|
||||
#include "../safeguards.h"
|
||||
|
||||
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY);
|
||||
extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY, bool deviate = true);
|
||||
|
||||
/**
|
||||
* Makes a tile canal or water depending on the surroundings.
|
||||
|
@ -549,11 +549,11 @@ static void StartScripts()
|
|||
|
||||
/* Start the AIs. */
|
||||
for (const Company *c : Company::Iterate()) {
|
||||
if (Company::IsValidAiID(c->index)) AI::StartNew(c->index, false);
|
||||
if (Company::IsValidAiID(c->index)) AI::StartNew(c->index, false, false);
|
||||
}
|
||||
|
||||
/* Start the GameScript. */
|
||||
Game::StartNew();
|
||||
Game::StartNew(false);
|
||||
|
||||
ShowScriptDebugWindowIfScriptError();
|
||||
}
|
||||
|
|
|
@ -87,11 +87,11 @@ struct AIPLChunkHandler : ChunkHandler {
|
|||
/* A random AI. */
|
||||
config->Change(std::nullopt, -1, false, true);
|
||||
} else {
|
||||
config->Change(_ai_saveload_name, _ai_saveload_version, false, _ai_saveload_is_random);
|
||||
config->Change(_ai_saveload_name, _ai_saveload_version, false, _ai_saveload_is_random, false);
|
||||
if (!config->HasScript()) {
|
||||
/* No version of the AI available that can load the data. Try to load the
|
||||
* latest version of the AI instead. */
|
||||
config->Change(_ai_saveload_name, -1, false, _ai_saveload_is_random);
|
||||
config->Change(_ai_saveload_name, -1, false, _ai_saveload_is_random, false);
|
||||
if (!config->HasScript()) {
|
||||
if (_ai_saveload_name.compare("%_dummy") != 0) {
|
||||
Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version);
|
||||
|
|
|
@ -77,11 +77,11 @@ struct GSDTChunkHandler : ChunkHandler {
|
|||
|
||||
GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
|
||||
if (!_game_saveload_name.empty()) {
|
||||
config->Change(_game_saveload_name, _game_saveload_version, false, _game_saveload_is_random);
|
||||
config->Change(_game_saveload_name, _game_saveload_version, false, _game_saveload_is_random, false);
|
||||
if (!config->HasScript()) {
|
||||
/* No version of the GameScript available that can load the data. Try to load the
|
||||
* latest version of the GameScript instead. */
|
||||
config->Change(_game_saveload_name, -1, false, _game_saveload_is_random);
|
||||
config->Change(_game_saveload_name, -1, false, _game_saveload_is_random, false);
|
||||
if (!config->HasScript()) {
|
||||
if (_game_saveload_name.compare("%_dummy") != 0) {
|
||||
Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version);
|
||||
|
|
|
@ -228,7 +228,9 @@ public:
|
|||
* 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).
|
||||
* The randomisation will happen just before the Script start.
|
||||
* The randomisation will happen in the following cases:
|
||||
* - right before game start, so after the user decided the settings for the script.
|
||||
* - when a random AI starts.
|
||||
* 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.
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "../safeguards.h"
|
||||
|
||||
void ScriptConfig::Change(std::optional<const std::string> name, int version, bool force_exact_match, bool is_random)
|
||||
void ScriptConfig::Change(std::optional<const std::string> name, int version, bool force_exact_match, bool is_random, bool add_random_deviation)
|
||||
{
|
||||
if (name.has_value()) {
|
||||
this->name = std::move(name.value());
|
||||
|
@ -33,12 +33,12 @@ void ScriptConfig::Change(std::optional<const std::string> name, int version, bo
|
|||
|
||||
this->ClearConfigList();
|
||||
|
||||
if (_game_mode == GM_NORMAL && _switch_mode != SM_LOAD_GAME && this->info != nullptr) {
|
||||
if (this->info != nullptr && add_random_deviation) {
|
||||
this->AddRandomDeviation();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptConfig::ScriptConfig(const ScriptConfig *config)
|
||||
ScriptConfig::ScriptConfig(const ScriptConfig *config, bool add_random_deviation)
|
||||
{
|
||||
this->name = config->name;
|
||||
this->info = config->info;
|
||||
|
@ -49,6 +49,8 @@ ScriptConfig::ScriptConfig(const ScriptConfig *config)
|
|||
for (const auto &item : config->settings) {
|
||||
this->settings[item.first] = item.second;
|
||||
}
|
||||
|
||||
if (add_random_deviation) this->AddRandomDeviation();
|
||||
}
|
||||
|
||||
ScriptConfig::~ScriptConfig()
|
||||
|
|
|
@ -63,8 +63,9 @@ public:
|
|||
/**
|
||||
* Create a new Script config that is a copy of an existing config.
|
||||
* @param config The object to copy.
|
||||
* @param add_random_deviation Whether to add random deviation to script settings that allow it.
|
||||
*/
|
||||
ScriptConfig(const ScriptConfig *config);
|
||||
ScriptConfig(const ScriptConfig *config, bool add_random_deviation);
|
||||
|
||||
/** Delete an Script configuration. */
|
||||
virtual ~ScriptConfig();
|
||||
|
@ -76,8 +77,9 @@ public:
|
|||
* @param force_exact_match If true try to find the exact same version
|
||||
* as specified. If false any compatible version is ok.
|
||||
* @param is_random Is the Script chosen randomly?
|
||||
* @param add_random_deviation Apply random deviation to settings that allow it?
|
||||
*/
|
||||
void Change(std::optional<const std::string> name, int version = -1, bool force_exact_match = false, bool is_random = false);
|
||||
void Change(std::optional<const std::string> name, int version = -1, bool force_exact_match = false, bool is_random = false, bool add_random_deviation = true);
|
||||
|
||||
/**
|
||||
* Get the ScriptInfo linked to this ScriptConfig.
|
||||
|
|
|
@ -176,7 +176,7 @@ struct ScriptListWindow : public Window {
|
|||
} else {
|
||||
ScriptInfoList::const_iterator it = this->info_list->cbegin();
|
||||
std::advance(it, this->selected);
|
||||
GetConfig(slot)->Change(it->second->GetName(), it->second->GetVersion());
|
||||
GetConfig(slot)->Change(it->second->GetName(), it->second->GetVersion(), false, false, false);
|
||||
}
|
||||
InvalidateWindowData(WC_GAME_OPTIONS, slot == OWNER_DEITY ? WN_GAME_OPTIONS_GS : WN_GAME_OPTIONS_AI);
|
||||
InvalidateWindowClassesData(WC_SCRIPT_SETTINGS);
|
||||
|
@ -1080,12 +1080,14 @@ struct ScriptDebugWindow : public Window {
|
|||
ChangeToScript(OWNER_DEITY, _ctrl_pressed);
|
||||
break;
|
||||
|
||||
case WID_SCRD_RELOAD_TOGGLE:
|
||||
case WID_SCRD_RELOAD_TOGGLE: {
|
||||
if (this->filter.script_debug_company == OWNER_DEITY) break;
|
||||
bool deviate = AIConfig::GetConfig(this->filter.script_debug_company)->IsRandom();
|
||||
/* First kill the company of the AI, then start a new one. This should start the current AI again */
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, this->filter.script_debug_company, CRR_MANUAL, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, this->filter.script_debug_company, CRR_NONE, INVALID_CLIENT_ID);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_DELETE, this->filter.script_debug_company, CRR_MANUAL, INVALID_CLIENT_ID, false);
|
||||
Command<CMD_COMPANY_CTRL>::Post(CCA_NEW_AI, this->filter.script_debug_company, CRR_NONE, INVALID_CLIENT_ID, deviate);
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_SCRD_SETTINGS:
|
||||
ShowScriptSettingsWindow(this->filter.script_debug_company);
|
||||
|
|
|
@ -953,7 +953,7 @@ static void AILoadConfig(const IniFile &ini, const char *grpname)
|
|||
for (const IniItem &item : group->items) {
|
||||
AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME);
|
||||
|
||||
config->Change(item.name);
|
||||
config->Change(item.name, -1, false, false, false);
|
||||
if (!config->HasScript()) {
|
||||
if (item.name != "none") {
|
||||
Debug(script, 0, "The AI by the name '{}' was no longer found, and removed from the list.", item.name);
|
||||
|
@ -980,7 +980,7 @@ static void GameLoadConfig(const IniFile &ini, const char *grpname)
|
|||
|
||||
GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME);
|
||||
|
||||
config->Change(item.name);
|
||||
config->Change(item.name, -1, false, false, false);
|
||||
if (!config->HasScript()) {
|
||||
if (item.name != "none") {
|
||||
Debug(script, 0, "The GameScript by the name '{}' was no longer found, and removed from the list.", item.name);
|
||||
|
|
Loading…
Reference in New Issue