Loading

Revision differences

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