Index: src/ai/ai_core.cpp
===================================================================
--- src/ai/ai_core.cpp (revision 27551)
+++ src/ai/ai_core.cpp (working copy)
@@ -62,6 +62,7 @@
cur_company.Restore();
InvalidateWindowData(WC_AI_DEBUG, 0, -1);
+ DeleteWindowById(WC_AI_SETTINGS, company);
return;
}
Index: src/ai/ai_gui.cpp
===================================================================
--- src/ai/ai_gui.cpp (revision 27551)
+++ src/ai/ai_gui.cpp (working copy)
@@ -177,7 +177,7 @@
GetConfig(slot)->Change((*it).second->GetName(), (*it).second->GetVersion());
}
InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI);
- InvalidateWindowClassesData(WC_AI_SETTINGS);
+ DeleteWindowByClass(WC_AI_SETTINGS);
DeleteWindowByClass(WC_QUERY_STRING);
}
@@ -276,6 +276,19 @@
}
/**
+* Check whether the currently selected AI/GS is dead.
+* @return true if dead.
+*/
+static bool IsDead(CompanyID slot)
+{
+ if (slot == OWNER_DEITY) {
+ return Game::GetInstance() == NULL || Game::GetInstance()->IsDead();
+ } else {
+ return !Company::IsValidAiID(slot) || Company::Get(slot)->ai_instance->IsDead();
+ }
+}
+
+/**
* Window for settings the parameters of an AI.
*/
struct AISettingsWindow : public Window {
@@ -311,7 +324,7 @@
this->vscroll = this->GetScrollbar(WID_AIS_SCROLLBAR);
this->FinishInitNested(slot); // Initializes 'this->line_height' as side effect.
- this->SetWidgetDisabledState(WID_AIS_RESET, _game_mode != GM_MENU && Company::IsValidID(this->slot));
+ this->SetWidgetDisabledState(WID_AIS_RESET, _game_mode == GM_NORMAL && !IsDead(this->slot));
this->vscroll->SetCount((int)this->visible_settings.size());
}
@@ -375,7 +388,7 @@
for (; this->vscroll->IsVisible(i) && it != visible_settings.end(); i++, it++) {
const ScriptConfigItem &config_item = **it;
int current_value = config->GetSetting((config_item).name);
- bool editable = _game_mode == GM_MENU || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot)) || (config_item.flags & SCRIPTCONFIG_INGAME) != 0;
+ bool editable = _game_mode != GM_NORMAL || IsDead(this->slot) || (config_item.flags & SCRIPTCONFIG_INGAME) != 0;
StringID str;
TextColour colour;
@@ -438,7 +451,7 @@
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
for (int i = 0; i < num; i++) it++;
const ScriptConfigItem config_item = **it;
- if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
+ if (_game_mode == GM_NORMAL && !IsDead(this->slot) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
if (this->clicked_row != num) {
DeleteChildWindows(WC_QUERY_STRING);
@@ -519,7 +532,7 @@
break;
case WID_AIS_RESET:
- if (_game_mode == GM_MENU || !Company::IsValidID(this->slot)) {
+ if (_game_mode != GM_NORMAL || IsDead(this->slot)) {
this->ai_config->ResetSettings();
this->SetDirty();
}
@@ -532,7 +545,7 @@
if (StrEmpty(str)) return;
ScriptConfigItemList::const_iterator it = this->ai_config->GetConfigList()->begin();
for (int i = 0; i < this->clicked_row; i++) it++;
- if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (it->flags & SCRIPTCONFIG_INGAME) == 0) return;
+ if (_game_mode == GM_NORMAL && !IsDead(this->slot) && (it->flags & SCRIPTCONFIG_INGAME) == 0) return;
int32 value = atoi(str);
this->ai_config->SetSetting((*it).name, value);
this->SetDirty();
@@ -543,7 +556,7 @@
assert(this->clicked_dropdown);
ScriptConfigItemList::const_iterator it = this->ai_config->GetConfigList()->begin();
for (int i = 0; i < this->clicked_row; i++) it++;
- if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (it->flags & SCRIPTCONFIG_INGAME) == 0) return;
+ if (_game_mode == GM_NORMAL && !IsDead(this->slot) && (it->flags & SCRIPTCONFIG_INGAME) == 0) return;
this->ai_config->SetSetting((*it).name, index);
this->SetDirty();
}
@@ -779,15 +792,11 @@
if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != NULL;
if (_game_mode != GM_NORMAL) {
- return slot > 0 && slot <= GetGameSettings().difficulty.max_no_competitors;
+ return slot >= 0 && slot < MAX_COMPANIES;
}
- if (Company::IsValidID(slot) || slot < 0) return false;
+ if (Company::IsValidHumanID(slot) || slot < 0) return false;
- int max_slot = GetGameSettings().difficulty.max_no_competitors;
- for (CompanyID cid = COMPANY_FIRST; cid < (CompanyID)max_slot && cid < MAX_COMPANIES; cid++) {
- if (Company::IsValidHumanID(cid)) max_slot++;
- }
- return slot < max_slot;
+ return slot < MAX_COMPANIES;
}
virtual void DrawWidget(const Rect &r, int widget) const
@@ -802,7 +811,7 @@
}
DrawString(r.left + 10, r.right - 10, r.top + WD_MATRIX_TOP, text,
- (this->selected_slot == OWNER_DEITY) ? TC_WHITE : (IsEditable(OWNER_DEITY) ? TC_ORANGE : TC_SILVER));
+ (this->selected_slot == OWNER_DEITY) ? TC_WHITE : (IsEditable(OWNER_DEITY) ? (_game_mode == GM_NORMAL) ? (IsDead(OWNER_DEITY)) ? TC_RED : TC_GREEN : TC_ORANGE : TC_SILVER));
break;
}
@@ -812,7 +821,7 @@
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) {
StringID text;
- if ((_game_mode != GM_NORMAL && i == 0) || (_game_mode == GM_NORMAL && Company::IsValidHumanID(i))) {
+ if (_game_mode == GM_NORMAL && Company::IsValidHumanID(i)) {
text = STR_AI_CONFIG_HUMAN_PLAYER;
} else if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != NULL) {
SetDParamStr(0, AIConfig::GetConfig((CompanyID)i)->GetInfo()->GetName());
@@ -821,7 +830,7 @@
text = STR_AI_CONFIG_RANDOM_AI;
}
DrawString(r.left + 10, r.right - 10, y + WD_MATRIX_TOP, text,
- (this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? TC_ORANGE : TC_SILVER));
+ (this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? Company::IsValidAiID(i) ? IsDead((CompanyID)i) ? TC_RED : TC_GREEN : TC_ORANGE : TC_SILVER));
y += this->line_height;
}
break;
@@ -845,7 +854,7 @@
if (widget == WID_AIC_DECREASE) {
new_value = max(0, GetGameSettings().difficulty.max_no_competitors - 1);
} else {
- new_value = min(MAX_COMPANIES - 1, GetGameSettings().difficulty.max_no_competitors + 1);
+ new_value = min(MAX_COMPANIES, GetGameSettings().difficulty.max_no_competitors + 1);
}
IConsoleSetSetting("difficulty.max_no_competitors", new_value);
this->InvalidateData();
@@ -867,7 +876,7 @@
}
case WID_AIC_MOVE_UP:
- if (IsEditable(this->selected_slot) && IsEditable((CompanyID)(this->selected_slot - 1))) {
+ if (IsEditable(this->selected_slot) && IsDead(this->selected_slot) && IsEditable((CompanyID)(this->selected_slot - 1)) && IsDead((CompanyID)(this->selected_slot - 1))) {
Swap(GetGameSettings().ai_config[this->selected_slot], GetGameSettings().ai_config[this->selected_slot - 1]);
this->selected_slot--;
this->vscroll->ScrollTowards(this->selected_slot);
@@ -876,7 +885,7 @@
break;
case WID_AIC_MOVE_DOWN:
- if (IsEditable(this->selected_slot) && IsEditable((CompanyID)(this->selected_slot + 1))) {
+ if (IsEditable(this->selected_slot) && IsDead(this->selected_slot) && IsEditable((CompanyID)(this->selected_slot + 1)) && IsDead((CompanyID)(this->selected_slot + 1))) {
Swap(GetGameSettings().ai_config[this->selected_slot], GetGameSettings().ai_config[this->selected_slot + 1]);
this->selected_slot++;
this->vscroll->ScrollTowards(this->selected_slot);
@@ -922,12 +931,21 @@
if (!gui_scope) return;
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 == OWNER_DEITY && _game_mode == GM_NORMAL) || this->selected_slot == INVALID_COMPANY);
+ this->SetWidgetDisabledState(WID_AIC_INCREASE, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES);
+ this->SetWidgetDisabledState(WID_AIC_CHANGE, this->selected_slot == INVALID_COMPANY || _game_mode == GM_NORMAL && (this->selected_slot == OWNER_DEITY || !IsDead(this->selected_slot)));
this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot)->GetConfigList()->size() == 0);
- this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == OWNER_DEITY || this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot - 1)));
- this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == OWNER_DEITY || this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot + 1)));
+ /* Display either Settings or Configure button */
+ NWidgetCore *configure_button = this->GetWidget<NWidgetCore>(WID_AIC_CONFIGURE);
+ if (_game_mode == GM_NORMAL && this->selected_slot != INVALID_COMPANY && !IsDead(this->selected_slot)) {
+ configure_button->SetDataTip(STR_AI_DEBUG_SETTINGS, STR_AI_DEBUG_SETTINGS_TOOLTIP);
+ } else {
+ configure_button->SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP);
+ }
+
+ this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == INVALID_COMPANY || this->selected_slot == OWNER_DEITY || !IsDead(this->selected_slot) || !IsEditable((CompanyID)(this->selected_slot - 1)) || !IsDead((CompanyID)(this->selected_slot - 1)));
+ this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == INVALID_COMPANY || this->selected_slot == OWNER_DEITY || !IsDead(this->selected_slot) || !IsEditable((CompanyID)(this->selected_slot + 1)) || !IsDead((CompanyID)(this->selected_slot + 1)));
+
for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) {
this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == NULL));
}
@@ -991,19 +1009,6 @@
}
/**
- * Check whether the currently selected AI/GS is dead.
- * @return true if dead.
- */
- bool IsDead() const
- {
- if (ai_debug_company == OWNER_DEITY) {
- GameInstance *game = Game::GetInstance();
- return game == NULL || game->IsDead();
- }
- return !Company::IsValidAiID(ai_debug_company) || Company::Get(ai_debug_company)->ai_instance->IsDead();
- }
-
- /**
* Check whether a company is a valid AI company or GS.
* @param company Company to check for validity.
* @return true if company is valid for debugging.
@@ -1276,7 +1281,7 @@
case WID_AID_CONTINUE_BTN:
/* Unpause current AI / game script and mark the corresponding script button dirty. */
- if (!this->IsDead()) {
+ if (!IsDead(this->ai_debug_company)) {
if (ai_debug_company == OWNER_DEITY) {
Game::Unpause();
} else {
@@ -1336,7 +1341,7 @@
this->break_string_filter.AddLine(log->lines[log->pos]);
if (this->break_string_filter.GetState()) {
/* Pause execution of script. */
- if (!this->IsDead()) {
+ if (!IsDead(ai_debug_company)) {
if (ai_debug_company == OWNER_DEITY) {
Game::Pause();
} else {
@@ -1375,6 +1380,15 @@
this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check);
this->SetWidgetDisabledState(WID_AID_SETTINGS, ai_debug_company == INVALID_COMPANY);
+
+ /* Display either Settings or Configure button */
+ NWidgetCore *settings_button = this->GetWidget<NWidgetCore>(WID_AID_SETTINGS);
+ if (ai_debug_company == INVALID_COMPANY || !IsDead(this->ai_debug_company)) {
+ settings_button->SetDataTip(STR_AI_DEBUG_SETTINGS, STR_AI_DEBUG_SETTINGS_TOOLTIP);
+ } else {
+ settings_button->SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP);
+ }
+
this->SetWidgetDisabledState(WID_AID_RELOAD_TOGGLE, ai_debug_company == INVALID_COMPANY || ai_debug_company == OWNER_DEITY);
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, ai_debug_company == INVALID_COMPANY ||
(ai_debug_company == OWNER_DEITY ? !Game::IsPaused() : !AI::IsPaused(ai_debug_company)));
Index: src/ai/ai_instance.cpp
===================================================================
--- src/ai/ai_instance.cpp (revision 27551)
+++ src/ai/ai_instance.cpp (working copy)
@@ -81,6 +81,7 @@
#include "../company_base.h"
#include "../company_func.h"
+#include "../window_func.h"
#include "../safeguards.h"
@@ -214,6 +215,7 @@
ScriptInstance::Died();
ShowAIDebugWindow(_current_company);
+ InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI);
const AIInfo *info = AIConfig::GetConfig(_current_company, AIConfig::SSS_FORCE_GAME)->GetInfo();
if (info != NULL) {
Index: src/game/game_instance.cpp
===================================================================
--- src/game/game_instance.cpp (revision 27551)
+++ src/game/game_instance.cpp (working copy)
@@ -85,6 +85,8 @@
#include "../script/api/game/game_waypointlist.hpp.sq"
#include "../script/api/game/game_window.hpp.sq"
+#include "../window_func.h"
+
#include "../safeguards.h"
@@ -232,6 +234,7 @@
ScriptInstance::Died();
ShowAIDebugWindow(OWNER_DEITY);
+ InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI);
const GameInfo *info = Game::GetInfo();
if (info != NULL) {
Index: src/lang/english.txt
===================================================================
--- src/lang/english.txt (revision 27551)
+++ src/lang/english.txt (working copy)
@@ -3979,10 +3979,10 @@
STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Game Script Debug window is only available for the server
# AI configuration window
-STR_AI_CONFIG_CAPTION :{WHITE}AI/Game Script Configuration
-STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}The Game Script that will be loaded in the next game
-STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}The AIs that will be loaded in the next game
-STR_AI_CONFIG_HUMAN_PLAYER :Human player
+STR_AI_CONFIG_CAPTION :{WHITE}AI/Game Script Settings
+STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}The Game Script that is loaded or will be loaded in the next game
+STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}The AIs that are currently loaded or will be loaded next time they start on these Company IDs while in a game
+STR_AI_CONFIG_HUMAN_PLAYER :Human Company
STR_AI_CONFIG_RANDOM_AI :Random AI
STR_AI_CONFIG_NONE :(none)
Index: src/table/settings.ini
===================================================================
--- src/table/settings.ini (revision 27551)
+++ src/table/settings.ini (working copy)
@@ -103,7 +103,7 @@
from = 97
def = 0
min = 0
-max = MAX_COMPANIES - 1
+max = MAX_COMPANIES
interval = 1
proc = MaxNoAIsChange
cat = SC_BASIC