Loading

Revision differences

Old revision #pmshshhudNew revision #pficrqgae
  1/**  
  2 * Window to configure which AIs will start.  
  3 */  
  4struct AIConfigWindow : public Window {  
  5    CompanyID selected_slot; ///< The currently selected AI slot or \c INVALID_COMPANY.  
  6    int line_height;         ///< Height of a single AI-name line.  
  7    uint cid_width;          ///< Width of Company # string.  
  8  
  9    AIConfigWindow() : Window(&_ai_config_desc)  
  10    {  
  11        this->InitNested(WN_GAME_OPTIONS_AI); // Initializes 'this->line_height' as a side effect.  
  12        this->selected_slot = INVALID_COMPANY;  
  13        this->OnInvalidateData(0);  
  14    }  
  15  
  16    ~AIConfigWindow()  
  17    {  
  18        DeleteWindowByClass(WC_AI_LIST);  
  19        if (_game_mode != GM_NORMAL) DeleteWindowByClass(WC_AI_SETTINGS);  
  20    }  
  21  
  22    virtual void SetStringParameters(int widget) const  
  23    {  
  24        switch (widget) {  
  25            case WID_AIC_CAPTION:  
  26                SetDParam(0, (_game_mode != GM_NORMAL) ? STR_AI_CONFIG_CAPTION : STR_AI_CONFIG_CAPTION_INGAME);  
  27                break;  
  28            case WID_AIC_NUMBER:  
  29                SetDParam(0, GetGameSettings().difficulty.max_no_competitors);  
  30                break;  
  31            case WID_AIC_CHANGE:  
  32                switch (selected_slot) {  
  33                    case OWNER_DEITY:  
  34                        SetDParam(0, STR_AI_CONFIG_CHANGE_GAMESCRIPT);  
  35                        break;  
  36  
  37                    case INVALID_COMPANY:  
  38                        SetDParam(0, STR_AI_CONFIG_CHANGE_NONE);  
  39                        break;  
  40  
  41                    default:  
  42                        SetDParam(0, STR_AI_CONFIG_CHANGE_AI);  
  43                        break;  
  44                }  
  45                break;  
  46        }  
  47    }  
  48  
  49    virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)  
  50    {  
  51        switch (widget) {  
  52            case WID_AIC_GAMELIST:  
  53                this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;  
  54                size->height = 1 * this->line_height;  
1                for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {  55                for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {  
2                    StringID cid = STR_AI_CONFIG_AILIST_COMPANY_ID_1 + i;  56                    StringID cid = STR_AI_CONFIG_AILIST_COMPANY_ID_1 + i;  
3                        uint width = GetStringBoundingBox(cid).width;    
4                        this->cid_width = max(GetStringBoundingBox(cid).width, GetStringBoundingBox(cid_width).width);  57                        this->cid_width = max(GetStringBoundingBox(cid).width, GetStringBoundingBox(cid_width).width);  
5                } 58                }
   59                break;
   60
   61            case WID_AIC_LIST:
   62                this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
   63                size->height = 15 * this->line_height;
   64                break;
   65        }
   66    }
   67
   68    /**
   69     * Can the AI config in the given company slot be edited?
   70     * @param slot The slot to query.
   71     * @return True if and only if the given AI Config slot can e edited.
   72     */
   73    static bool IsEditable(CompanyID slot)
   74    {
   75        if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != NULL;
   76
   77        if (_game_mode != GM_NORMAL) {
   78            return slot >= 0 && slot < MAX_COMPANIES;
   79        }
   80        if (Company::IsValidHumanID(slot) || slot < 0) return false;
   81
   82        return slot < MAX_COMPANIES;
   83    }
   84
   85    virtual void DrawWidget(const Rect &r, int widget) const
   86    {
   87        switch (widget) {
   88            case WID_AIC_GAMELIST: {
   89                StringID text = STR_AI_CONFIG_NONE;
   90
   91                if (GameConfig::GetConfig()->GetInfo() != NULL) {
   92                    SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName());
   93                    text = STR_JUST_RAW_STRING;
   94                }
   95
   96                DrawString(r.left + 10, r.right - 10, r.top + WD_MATRIX_TOP, text,
   97                        (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));
   98
   99                break;
   100            }
   101
   102            case WID_AIC_LIST: {
   103                int y = r.top;
   104                for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
   105                    StringID cid = STR_AI_CONFIG_AILIST_COMPANY_ID_1 + i;
   106                    DrawString(r.left + 10, r.left + 90, y + WD_MATRIX_TOP, cid);
   107                    StringID text;
   108
   109                    if (_game_mode == GM_NORMAL && Company::IsValidHumanID(i)) {
   110                        text = STR_AI_CONFIG_HUMAN_PLAYER;
   111                    } else if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != NULL) {
   112                        SetDParamStr(0, AIConfig::GetConfig((CompanyID)i)->GetInfo()->GetName());
   113                        text = STR_JUST_RAW_STRING;
   114                    } else {
   115                        text = STR_AI_CONFIG_RANDOM_AI;
   116                    }
   117                    DrawString(r.left + 10 + 90, r.right - 10, y + WD_MATRIX_TOP, text,
   118                            (this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? Company::IsValidAiID(i) ? IsDead((CompanyID)i) ? TC_RED : TC_GREEN : TC_ORANGE : TC_SILVER));
   119                    y += this->line_height;
   120                }
   121                break;
   122            }
   123        }
   124    }
   125
   126    virtual void OnClick(Point pt, int widget, int click_count)
   127    {
   128        if (widget >= WID_AIC_TEXTFILE && widget < WID_AIC_TEXTFILE + TFT_END) {
   129            if (this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot) == NULL) return;
   130
   131            ShowScriptTextfileWindow((TextfileType)(widget - WID_AIC_TEXTFILE), this->selected_slot);
   132            return;
   133        }
   134
   135        switch (widget) {
   136            case WID_AIC_DECREASE:
   137            case WID_AIC_INCREASE: {
   138                int new_value;
   139                if (widget == WID_AIC_DECREASE) {
   140                    new_value = max(0, GetGameSettings().difficulty.max_no_competitors - 1);
   141                } else {
   142                    new_value = min(MAX_COMPANIES, GetGameSettings().difficulty.max_no_competitors + 1);
   143                }
   144                IConsoleSetSetting("difficulty.max_no_competitors", new_value);
   145                this->InvalidateData();
   146                break;
   147            }
   148
   149            case WID_AIC_GAMELIST: {
   150                this->selected_slot = OWNER_DEITY;
   151                this->InvalidateData();
   152                if (click_count > 1 && this->selected_slot != INVALID_COMPANY && _game_mode != GM_NORMAL) ShowAIListWindow((CompanyID)this->selected_slot);
   153                break;
   154            }
   155
   156            case WID_AIC_LIST: { // Select a slot
   157                this->selected_slot = (CompanyID)this->GetRowFromWidget(pt.y, widget, 0, this->line_height);
   158                this->InvalidateData();
   159                if (click_count > 1 && this->selected_slot != INVALID_COMPANY) ShowAIListWindow((CompanyID)this->selected_slot);
   160                break;
   161            }
   162
   163            case WID_AIC_MOVE_UP:
   164                if (IsEditable(this->selected_slot) && IsDead(this->selected_slot) && IsEditable((CompanyID)(this->selected_slot - 1)) && IsDead((CompanyID)(this->selected_slot - 1))) {
   165                    Swap(GetGameSettings().ai_config[this->selected_slot], GetGameSettings().ai_config[this->selected_slot - 1]);
   166                    this->selected_slot--;
   167                    this->InvalidateData();
   168                }
   169                break;
   170
   171            case WID_AIC_MOVE_DOWN:
   172                if (IsEditable(this->selected_slot) && IsDead(this->selected_slot) && IsEditable((CompanyID)(this->selected_slot + 1)) && IsDead((CompanyID)(this->selected_slot + 1))) {
   173                    Swap(GetGameSettings().ai_config[this->selected_slot], GetGameSettings().ai_config[this->selected_slot + 1]);
   174                    this->selected_slot++;
   175                    this->InvalidateData();
   176                }
   177                break;
   178
   179            case WID_AIC_CHANGE:  // choose other AI
   180                ShowAIListWindow((CompanyID)this->selected_slot);
   181                break;
   182
   183            case WID_AIC_CONFIGURE: // change the settings for an AI
   184                ShowAISettingsWindow((CompanyID)this->selected_slot);
   185                break;
   186
   187            case WID_AIC_CLOSE:
   188                delete this;
   189                break;
   190
   191            case WID_AIC_CONTENT_DOWNLOAD:
   192                if (!_network_available) {
   193                    ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
   194                } else {
   195#if defined(ENABLE_NETWORK)
   196                    ShowNetworkContentListWindow(NULL, CONTENT_TYPE_AI, CONTENT_TYPE_GAME);
   197#endif
   198                }
   199                break;
   200        }
   201    }
   202
   203    /**
   204     * Some data on this window has become invalid.
   205     * @param data Information about the changed data.
   206     * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
   207     */
   208    virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
   209    {
   210        if (!IsEditable(this->selected_slot)) {
   211            this->selected_slot = INVALID_COMPANY;
   212        }
   213
   214        if (!gui_scope) return;
   215
   216        this->SetWidgetDisabledState(WID_AIC_DECREASE, GetGameSettings().difficulty.max_no_competitors == 0);
   217        this->SetWidgetDisabledState(WID_AIC_INCREASE, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES);
   218        this->SetWidgetDisabledState(WID_AIC_CHANGE, this->selected_slot == INVALID_COMPANY || _game_mode == GM_NORMAL && (this->selected_slot == OWNER_DEITY || !IsDead(this->selected_slot)));
   219        this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot)->GetConfigList()->size() == 0);
   220
   221        /* Display either Settings or Configure button */
   222        NWidgetCore *configure_button = this->GetWidget<NWidgetCore>(WID_AIC_CONFIGURE);
   223        if (_game_mode == GM_NORMAL && this->selected_slot != INVALID_COMPANY && !IsDead(this->selected_slot)) {
   224            configure_button->SetDataTip(STR_AI_DEBUG_SETTINGS, STR_AI_DEBUG_SETTINGS_TOOLTIP);
   225        } else {
   226            configure_button->SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP);
   227        }
   228
   229        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)));
   230        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)));
   231
   232        for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) {
   233            this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == NULL));
   234        }
   235    }
   236};