diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp index e090303bd9560..6daf667b244f0 100644 --- a/src/ai/ai.hpp +++ b/src/ai/ai.hpp @@ -23,12 +23,11 @@ class AI { * The default months AIs start after each other. */ enum StartNext { - START_NEXT_EASY = DAYS_IN_YEAR * 2, - START_NEXT_MEDIUM = DAYS_IN_YEAR, - START_NEXT_HARD = DAYS_IN_YEAR / 2, - START_NEXT_MIN = 0, - START_NEXT_MAX = 3600, + START_NEXT = DAYS_IN_YEAR * 2, + START_NEXT_MIN = 0, + START_NEXT_MAX = 3600, START_NEXT_DEVIATION = 60, + START_NEXT_STEP_SIZE = 30 }; /** diff --git a/src/ai/ai_config.cpp b/src/ai/ai_config.cpp index 98618feb20eca..09c96258ecf7f 100644 --- a/src/ai/ai_config.cpp +++ b/src/ai/ai_config.cpp @@ -9,39 +9,12 @@ #include "../stdafx.h" #include "../settings_type.h" -#include "../string_func.h" #include "ai.hpp" #include "ai_config.hpp" #include "ai_info.hpp" #include "../safeguards.h" -/** Configuration for AI start date, every AI has this setting. */ -ScriptConfigItem _start_date_config = { - "start_date", - "", // STR_AI_SETTINGS_START_DELAY - AI::START_NEXT_MIN, - AI::START_NEXT_MAX, - AI::START_NEXT_MEDIUM, - AI::START_NEXT_EASY, - AI::START_NEXT_MEDIUM, - AI::START_NEXT_HARD, - AI::START_NEXT_DEVIATION, - 30, - SCRIPTCONFIG_NONE, - nullptr, - false -}; - -AIConfig::AIConfig(const AIConfig *config) : ScriptConfig(config) -{ - /* Override start_date as per AIConfig::AddRandomDeviation(). - * This is necessary because the ScriptConfig constructor will instead call - * ScriptConfig::AddRandomDeviation(). */ - int start_date = config->GetSetting("start_date"); - this->SetSetting("start_date", start_date != 0 ? std::max(1, this->GetSetting("start_date")) : 0); -} - /* static */ AIConfig *AIConfig::GetConfig(CompanyID company, ScriptSettingSource source) { AIConfig **config; @@ -69,70 +42,3 @@ bool AIConfig::ResetInfo(bool force_exact_match) this->info = (ScriptInfo *)AI::FindInfo(this->name, force_exact_match ? this->version : -1, force_exact_match); return this->info != nullptr; } - -void AIConfig::PushExtraConfigList() -{ - this->config_list->push_back(_start_date_config); -} - -void AIConfig::ClearConfigList() -{ - /* The special casing for start_date is here to ensure that the - * start_date setting won't change even if you chose another Script. */ - int start_date = this->GetSetting("start_date"); - - ScriptConfig::ClearConfigList(); - - this->SetSetting("start_date", start_date); -} - -int AIConfig::GetSetting(const char *name) const -{ - if (this->info == nullptr) { - SettingValueList::const_iterator it = this->settings.find(name); - if (it == this->settings.end()) { - assert(strcmp("start_date", name) == 0); - switch (GetGameSettings().script.settings_profile) { - case SP_EASY: return AI::START_NEXT_EASY; - case SP_MEDIUM: return AI::START_NEXT_MEDIUM; - case SP_HARD: return AI::START_NEXT_HARD; - case SP_CUSTOM: return AI::START_NEXT_MEDIUM; - default: NOT_REACHED(); - } - } - - return (*it).second; - } - - return ScriptConfig::GetSetting(name); -} - -void AIConfig::SetSetting(const char *name, int value) -{ - if (this->info == nullptr) { - if (strcmp("start_date", name) != 0) return; - value = Clamp(value, AI::START_NEXT_MIN, AI::START_NEXT_MAX); - - SettingValueList::iterator it = this->settings.find(name); - if (it != this->settings.end()) { - (*it).second = value; - } else { - this->settings[stredup(name)] = value; - } - - return; - } - - ScriptConfig::SetSetting(name, value); -} - -void AIConfig::AddRandomDeviation() -{ - int start_date = this->GetSetting("start_date"); - - ScriptConfig::AddRandomDeviation(); - - /* start_date = 0 is a special case, where random deviation does not occur. - * If start_date was not already 0, then a minimum value of 1 must apply. */ - this->SetSetting("start_date", start_date != 0 ? std::max(1, this->GetSetting("start_date")) : 0); -} diff --git a/src/ai/ai_config.hpp b/src/ai/ai_config.hpp index 6c861126e0484..a0f98d21876d6 100644 --- a/src/ai/ai_config.hpp +++ b/src/ai/ai_config.hpp @@ -24,14 +24,12 @@ class AIConfig : public ScriptConfig { ScriptConfig() {} - AIConfig(const AIConfig *config); + AIConfig(const AIConfig *config) : + ScriptConfig(config) + {} class AIInfo *GetInfo() const; - int GetSetting(const char *name) const override; - void SetSetting(const char *name, int value) override; - void AddRandomDeviation() override; - /** * When ever the AI Scanner is reloaded, all infos become invalid. This * function tells AIConfig about this. @@ -43,8 +41,6 @@ class AIConfig : public ScriptConfig { bool ResetInfo(bool force_exact_match); protected: - void PushExtraConfigList() override; - void ClearConfigList() override; ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match) override; }; diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp index 220e7bdbd2312..d814ddabbe9c1 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -15,6 +15,7 @@ #include "../network/network.h" #include "../window_func.h" #include "../framerate_type.h" +#include "../script/api/script_object.hpp" #include "ai_scanner.hpp" #include "ai_instance.hpp" #include "ai_config.hpp" @@ -291,9 +292,20 @@ /* static */ int AI::GetStartNextTime() { - /* Find the first company which doesn't exist yet */ - for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - if (!Company::IsValidID(c)) return AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->GetSetting("start_date"); + int start_next = _settings_game.ai.ai_start_next; + if (start_next > 0) { + /* Find the first company which doesn't exist yet */ + for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { + if (!Company::IsValidID(c)) { + /* Add random deviation */ + start_next += ScriptObject::GetRandomizer(c).Next(AI::START_NEXT_DEVIATION * 2 + 1) - AI::START_NEXT_DEVIATION; + + /* ai_start_next = 0 is a special case, where random deviation does not occur. + * If ai_start_next was not already 0, then a minimum value of 1 must apply. */ + start_next = Clamp(start_next, 1, AI::START_NEXT_MAX); + return start_next; + } + } } /* Currently no AI can be started, check again in a year. */ diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index da60bb9f98468..bbf311a129b28 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -15,6 +15,7 @@ #include "../settings_func.h" #include "../network/network_content.h" #include "../core/geometry_func.hpp" +#include "../textbuf_gui.h" #include "ai.hpp" #include "ai_gui.hpp" @@ -34,6 +35,12 @@ static const NWidgetPart _nested_ai_config_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIC_BACKGROUND), NWidget(NWID_VERTICAL), SetPIP(4, 4, 4), + NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7), + NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_SN_DECREASE), SetDataTip(AWV_DECREASE, STR_NULL), + NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_SN_INCREASE), SetDataTip(AWV_INCREASE, STR_NULL), + NWidget(NWID_SPACER), SetMinimalSize(6, 0), + NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_START_NEXT), SetDataTip(STR_AI_CONFIG_START_NEXT, STR_AI_CONFIG_START_NEXT_TOOLTIP), SetFill(1, 0), + EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7), NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetDataTip(AWV_DECREASE, STR_NULL), NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetDataTip(AWV_INCREASE, STR_NULL), @@ -79,6 +86,7 @@ static WindowDesc _ai_config_desc( */ struct AIConfigWindow : public Window { CompanyID selected_slot; ///< The currently selected AI slot or \c INVALID_COMPANY. + AIConfigWidgets widget; ///< corresponding widget to setting for which a value-entering window has been opened. int line_height; ///< Height of a single AI-name line. Scrollbar *vscroll; ///< Cache of the vertical scrollbar. @@ -87,6 +95,7 @@ struct AIConfigWindow : public Window { this->InitNested(WN_GAME_OPTIONS_AI); // Initializes 'this->line_height' as a side effect. this->vscroll = this->GetScrollbar(WID_AIC_SCROLLBAR); this->selected_slot = INVALID_COMPANY; + this->widget = WID_AIC_BACKGROUND; NWidgetCore *nwi = this->GetWidget(WID_AIC_LIST); this->vscroll->SetCapacity(nwi->current_y / this->line_height); this->vscroll->SetCount(MAX_COMPANIES); @@ -103,6 +112,11 @@ struct AIConfigWindow : public Window { void SetStringParameters(int widget) const override { switch (widget) { + case WID_AIC_START_NEXT: + SetDParam(0, STR_CONFIG_SETTING_AI_START_NEXT_VALUE); + SetDParam(1, GetGameSettings().ai.ai_start_next); + break; + case WID_AIC_NUMBER: SetDParam(0, GetGameSettings().difficulty.max_no_competitors); break; @@ -112,6 +126,8 @@ struct AIConfigWindow : public Window { void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { + case WID_AIC_SN_DECREASE: + case WID_AIC_SN_INCREASE: case WID_AIC_DECREASE: case WID_AIC_INCREASE: *size = maxdim(*size, NWidgetScrollbar::GetHorizontalDimension()); @@ -179,8 +195,24 @@ struct AIConfigWindow : public Window { } switch (widget) { + case WID_AIC_SN_DECREASE: + case WID_AIC_SN_INCREASE: { + if (this->widget != WID_AIC_START_NEXT) CloseChildWindows(WC_QUERY_STRING); + + int new_value; + if (widget == WID_AIC_SN_DECREASE) { + new_value = std::max((int)AI::START_NEXT_MIN, GetGameSettings().ai.ai_start_next - AI::START_NEXT_STEP_SIZE); + } else { + new_value = std::min((int)AI::START_NEXT_MAX, GetGameSettings().ai.ai_start_next + AI::START_NEXT_STEP_SIZE); + } + IConsoleSetSetting("ai.ai_start_next", new_value); + break; + } + case WID_AIC_DECREASE: case WID_AIC_INCREASE: { + if (this->widget != WID_AIC_NUMBER) CloseChildWindows(WC_QUERY_STRING); + int new_value; if (widget == WID_AIC_DECREASE) { new_value = std::max(0, GetGameSettings().difficulty.max_no_competitors - 1); @@ -191,6 +223,21 @@ struct AIConfigWindow : public Window { break; } + case WID_AIC_START_NEXT: + case WID_AIC_NUMBER: { + /* Display a query box so users can enter a custom value. */ + this->widget = (AIConfigWidgets)widget; + int old_val; + if (widget == WID_AIC_NUMBER) { + old_val = GetGameSettings().difficulty.max_no_competitors; + } else { + old_val = GetGameSettings().ai.ai_start_next; + } + SetDParam(0, old_val); + ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 5, this, CS_NUMERAL, widget == WID_AIC_NUMBER ? QSF_NONE : QSF_ENABLE_DEFAULT); + break; + } + case WID_AIC_LIST: { // Select a slot this->selected_slot = (CompanyID)this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget); this->InvalidateData(); @@ -238,6 +285,22 @@ struct AIConfigWindow : public Window { } } + void OnQueryTextFinished(char *str) override + { + /* The user pressed cancel */ + if (str == nullptr) return; + + int32 value; + if (StrEmpty(str)) { + if (widget == WID_AIC_NUMBER) return; + value = AI::START_NEXT; + } else { + value = atoi(str); + } + IConsoleSetSetting(widget == WID_AIC_NUMBER ? "difficulty.max_no_competitors" : "ai.ai_start_next", value); + this->SetDirty(); + } + /** * Some data on this window has become invalid. * @param data Information about the changed data. @@ -251,6 +314,8 @@ struct AIConfigWindow : public Window { if (!gui_scope) return; + this->SetWidgetDisabledState(WID_AIC_SN_DECREASE, GetGameSettings().ai.ai_start_next == AI::START_NEXT_MIN); + this->SetWidgetDisabledState(WID_AIC_SN_INCREASE, GetGameSettings().ai.ai_start_next == AI::START_NEXT_MAX); this->SetWidgetDisabledState(WID_AIC_DECREASE, GetGameSettings().difficulty.max_no_competitors == 0); this->SetWidgetDisabledState(WID_AIC_INCREASE, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES - 1); this->SetWidgetDisabledState(WID_AIC_CHANGE, this->selected_slot == INVALID_COMPANY); diff --git a/src/ai/ai_info.cpp b/src/ai/ai_info.cpp index b8bc1fb83d93b..7ca897c713d6f 100644 --- a/src/ai/ai_info.cpp +++ b/src/ai/ai_info.cpp @@ -69,11 +69,6 @@ template <> const char *GetClassName() { return "AIInfo"; } SQInteger res = ScriptInfo::Constructor(vm, info); if (res != 0) return res; - ScriptConfigItem config = _start_date_config; - config.name = stredup(config.name); - config.description = stredup(config.description); - info->config_list.push_front(config); - if (info->engine->MethodExists(*info->SQ_instance, "MinVersionToLoad")) { if (!info->engine->CallIntegerMethod(*info->SQ_instance, "MinVersionToLoad", &info->min_loadable_version, MAX_GET_OPS)) return SQ_ERROR; } else { diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 3dcc2bd5702ab..b49870f891504 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -727,13 +727,14 @@ void OnTick_Companies() if (_game_mode != GM_MENU && AI::CanStartNew() && --_next_competitor_start == 0) { /* Allow multiple AIs to possibly start in the same tick. */ - do { + for (;;) { if (!MaybeStartNewCompany()) break; + if (_settings_game.ai.ai_start_next != 0) break; /* In networking mode, we can only send a command to start but it * didn't execute yet, so we cannot loop. */ if (_networking) break; - } while (AI::GetStartNextTime() == 0); + } } _cur_company_tick_index = (_cur_company_tick_index + 1) % MAX_COMPANIES; diff --git a/src/lang/english.txt b/src/lang/english.txt index 0a8a84a3d659b..5fd448e72827d 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1704,6 +1704,10 @@ STR_CONFIG_SETTING_AI_PROFILE_HARD :Hard STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Allow AIs in multiplayer: {STRING2} STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Allow AI computer players to participate in multiplayer games +STR_CONFIG_SETTING_AI_START_NEXT :Start delay between AIs (give or take): {STRING2} +STR_CONFIG_SETTING_AI_START_NEXT_HELPTEXT :Number of days to wait before starting an AI, or subsequent AI(s) after the previous one.{}If the number of days is different than zero, a random deviation of 60 days is added, and the actual value in-game will be 'number_of_days + random(-60 days, 60 days)', with a minimum of 1 day and a maximum of 3600 days +STR_CONFIG_SETTING_AI_START_NEXT_VALUE :{COMMA}{NBSP}day{P 0 "" s} + STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes before scripts are suspended: {STRING2} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximum number of computation steps that a script can take in one turn STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Max memory usage per script: {STRING2} @@ -4585,6 +4589,8 @@ STR_AI_CONFIG_HUMAN_PLAYER :Human player STR_AI_CONFIG_RANDOM_AI :Random AI STR_AI_CONFIG_NONE :(none) STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA} +STR_AI_CONFIG_START_NEXT :{LTBLUE}Start delay between AIs (give or take): {ORANGE}{STRING1} +STR_AI_CONFIG_START_NEXT_TOOLTIP :{BLACK}Number of days to wait before starting an AI, or subsequent AI(s) after the previous one.{}If the number of days is different than zero, a random deviation of 60 days is added, and the actual value in-game will be 'number_of_days + random(-60 days, 60 days)', with a minimum of 1 day and a maximum of 3600 days.{}If the number of days is zero, the AI(s) will start immediately. STR_AI_CONFIG_MOVE_UP :{BLACK}Move Up STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Move selected AI up in the list @@ -4631,7 +4637,6 @@ STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script STR_AI_SETTINGS_CLOSE :{BLACK}Close STR_AI_SETTINGS_RESET :{BLACK}Reset STR_AI_SETTINGS_SETTING :{RAW_STRING}: {ORANGE}{STRING1} -STR_AI_SETTINGS_START_DELAY :Number of days to start this AI after the previous one (give or take): {ORANGE}{STRING1} # Textfile window diff --git a/src/openttd.cpp b/src/openttd.cpp index 010b366632175..3d5ecbd9580d7 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -389,9 +389,6 @@ void MakeNewgameSettingsLive() _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]); - if (!AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->HasScript()) { - AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr); - } } } _settings_game.game_config = nullptr; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 6ebf4ccff1fd5..803d4a6fe22a0 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3203,6 +3203,10 @@ bool AfterLoadGame() } } + if (IsSavegameVersionBefore(SLV_AI_START_NEXT)) { + _settings_game.ai.ai_start_next = AI::START_NEXT; + } + /* Compute station catchment areas. This is needed here in case UpdateStationAcceptance is called below. */ Station::RecomputeCatchmentForAll(); diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 61d4047b152dc..ccad727342cc0 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -345,6 +345,7 @@ enum SaveLoadVersion : uint16 { SLV_MULTITRACK_LEVEL_CROSSINGS, ///< 302 PR#9931 v13.0 Multi-track level crossings. SLV_NEWGRF_ROAD_STOPS, ///< 303 PR#10144 NewGRF road stops. SLV_LINKGRAPH_EDGES, ///< 304 PR#10314 Explicitly store link graph edges destination, PR#10471 int64 instead of uint64 league rating + SLV_AI_START_NEXT, ///< 305 PR#10330 Rework AI "start_date" setting as game setting. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/script/script_config.hpp b/src/script/script_config.hpp index b243f3061f109..b6d73567ff6d8 100644 --- a/src/script/script_config.hpp +++ b/src/script/script_config.hpp @@ -51,8 +51,6 @@ struct ScriptConfigItem { typedef std::list ScriptConfigItemList; ///< List of ScriptConfig items. -extern ScriptConfigItem _start_date_config; - /** * Script settings. */ diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp index 8c9a1abcc79d7..4b68bb301281e 100644 --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -373,14 +373,8 @@ struct ScriptSettingsWindow : public Window { TextColour colour; uint idx = 0; if (StrEmpty(config_item.description)) { - if (this->slot != OWNER_DEITY && !strcmp(config_item.name, "start_date")) { - /* Build-in translation */ - str = STR_AI_SETTINGS_START_DELAY; - colour = TC_LIGHT_BLUE; - } else { - str = STR_JUST_STRING; - colour = TC_ORANGE; - } + str = STR_JUST_STRING; + colour = TC_ORANGE; } else { str = STR_AI_SETTINGS_SETTING; colour = TC_LIGHT_BLUE; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 5d14637e6452d..3088774995c7b 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1880,6 +1880,7 @@ static SettingsContainer &GetSettingsTree() npc->Add(new SettingEntry("script.script_max_memory_megabytes")); npc->Add(new SettingEntry("difficulty.competitor_speed")); npc->Add(new SettingEntry("ai.ai_in_multiplayer")); + npc->Add(new SettingEntry("ai.ai_start_next")); npc->Add(new SettingEntry("ai.ai_disable_veh_train")); npc->Add(new SettingEntry("ai.ai_disable_veh_roadveh")); npc->Add(new SettingEntry("ai.ai_disable_veh_aircraft")); diff --git a/src/settings_type.h b/src/settings_type.h index 2a33d3be0eaba..9e1e3518fef91 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -368,6 +368,7 @@ struct ConstructionSettings { /** Settings related to the AI. */ struct AISettings { bool ai_in_multiplayer; ///< so we allow AIs in multiplayer + uint16 ai_start_next; ///< days AIs start after each other bool ai_disable_veh_train; ///< disable types for AI bool ai_disable_veh_roadveh; ///< disable types for AI bool ai_disable_veh_aircraft; ///< disable types for AI diff --git a/src/table/settings/script_settings.ini b/src/table/settings/script_settings.ini index 6444e4baf2648..6dbb813ca85eb 100644 --- a/src/table/settings/script_settings.ini +++ b/src/table/settings/script_settings.ini @@ -110,3 +110,17 @@ var = ai.ai_disable_veh_ship def = false str = STR_CONFIG_SETTING_AI_BUILDS_SHIPS strhelp = STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT + +[SDT_VAR] +var = ai.ai_start_next +type = SLE_UINT16 +from = SLV_AI_START_NEXT +def = AI::START_NEXT +min = AI::START_NEXT_MIN +max = AI::START_NEXT_MAX +interval = AI::START_NEXT_STEP_SIZE +str = STR_CONFIG_SETTING_AI_START_NEXT +strhelp = STR_CONFIG_SETTING_AI_START_NEXT_HELPTEXT +strval = STR_CONFIG_SETTING_AI_START_NEXT_VALUE +post_cb = [](auto) { InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI); } +cat = SC_BASIC diff --git a/src/widgets/ai_widget.h b/src/widgets/ai_widget.h index f50b6632c8563..62f6188a2a629 100644 --- a/src/widgets/ai_widget.h +++ b/src/widgets/ai_widget.h @@ -15,6 +15,9 @@ /** Widgets of the #AIConfigWindow class. */ enum AIConfigWidgets { WID_AIC_BACKGROUND, ///< Window background. + WID_AIC_SN_DECREASE, ///< Decrease the AI start delay. + WID_AIC_SN_INCREASE, ///< Increase the AI start delay. + WID_AIC_START_NEXT, ///< Days to wait before starting an AI. WID_AIC_DECREASE, ///< Decrease the number of AIs. WID_AIC_INCREASE, ///< Increase the number of AIs. WID_AIC_NUMBER, ///< Number of AIs.