Loading

Paste #pcv1bqqoa

  1. /**
  2.  * Window to configure which AIs will start.
  3.  */
  4. struct 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.  
  8.     AIConfigWindow() : Window(&_ai_config_desc)
  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;
  27.             case WID_AIC_NUMBER:
  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, max(GetSpriteSize(SPR_SQUARE).height, max(GetSpriteSize(SPR_WARNING_SIGN).height, GetSpriteSize(SPR_RANDOM_AI).height))) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
  53.                 size->height = 1 * this->line_height;
  54.                 break;
  55.             }
  56.  
  57.             case WID_AIC_LIST: {
  58.                 this->line_height = max((uint)FONT_HEIGHT_NORMAL, max(GetSpriteSize(SPR_SQUARE).height, max(GetSpriteSize(SPR_WARNING_SIGN).height, GetSpriteSize(SPR_RANDOM_AI).height))) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
  59.                 size->height = 15 * this->line_height;
  60.                 break;
  61.             }
  62.  
  63.             case WID_AIC_CHANGE: {
  64.                 uint change_width = 0;
  65.                 static const StringID params[] = {STR_AI_CONFIG_GAMESCRIPT, STR_AI_CONFIG_NONE, STR_AI_CONFIG_AI};
  66.                 for (int i = 0; i < lengthof(params); i++) {
  67.                     SetDParam(0, params[i]);
  68.                     change_width = max(change_width, GetStringBoundingBox(STR_AI_CONFIG_CHANGE).width);
  69.                 }
  70.                 size->width = change_width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
  71.                 break;
  72.             }
  73.  
  74.             case WID_AIC_CONFIGURE: {
  75.                 size->width = max(GetStringBoundingBox(STR_AI_CONFIG_CONFIGURE).width, GetStringBoundingBox(STR_AI_DEBUG_SETTINGS).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
  76.                 break;
  77.             }
  78.         }
  79.     }
  80.  
  81.     /**
  82.      * Can the AI config in the given company slot be selected?
  83.      * @param slot The slot to query.
  84.      * @return True if and only if the given AI Config slot can be selected.
  85.      */
  86.     static bool IsSelectable(CompanyID slot)
  87.     {
  88.         if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != NULL;
  89.  
  90.         if (_game_mode != GM_NORMAL) {
  91.             return slot >= 0 && slot < MAX_COMPANIES;
  92.         }
  93.         if (/*Company::IsValidHumanID(slot) || */slot < 0) return false;
  94.  
  95.         return slot < MAX_COMPANIES;
  96.     }
  97.  
  98.     /**
  99.     * Is the AI or GS config in the given slot eligible to start?
  100.     * @param slot The slot to query.
  101.     * @return True if and only if the given AI or GS Config slot can start.
  102.     */
  103.     static bool IsEligible(CompanyID slot)
  104.     {
  105.         if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || false;
  106.  
  107.         if (Company::IsValidID(slot) || slot < 0 || slot == OWNER_DEITY) return false;
  108.  
  109.         int max_slot = GetGameSettings().difficulty.max_no_competitors;
  110.         for (CompanyID cid = COMPANY_FIRST; cid < (CompanyID)max_slot && cid < MAX_COMPANIES; cid++) {
  111.             if (Company::IsValidHumanID(cid)) max_slot++;
  112.         }
  113.         return slot < max_slot;
  114.     }
  115.  
  116.     virtual void DrawWidget(const Rect &r, int widget) const
  117.     {
  118.         switch (widget) {
  119.             case WID_AIC_GAMELIST: {
  120.                 Dimension square = GetSpriteSize(SPR_SQUARE);
  121.                 uint square_y_offset = (line_height - square.height) / 2;
  122.  
  123.                 bool rtl = _current_text_dir == TD_RTL;
  124.                 uint square_left = rtl ? r.right - WD_MATRIX_RIGHT - square.width : r.left + WD_MATRIX_LEFT;
  125.                 DrawSprite(SPR_SQUARE,
  126.                     IsEligible(OWNER_DEITY) ? PALETTE_TO_BLUE : IsDead(OWNER_DEITY) ? _game_mode == GM_NORMAL ? PALETTE_TO_GREY : PALETTE_TO_RED : PALETTE_TO_GREEN,
  127.                         square_left, r.top + square_y_offset);
  128.  
  129.                 uint widest_cid = 0;
  130.                 for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
  131.                     SetDParam(0, i + 1);
  132.                     widest_cid = max(GetStringBoundingBox(STR_JUST_INT).width, widest_cid);
  133.                 }
  134.                 StringID text = STR_AI_CONFIG_NONE;
  135.                 if (GameConfig::GetConfig()->GetInfo() != NULL) {
  136.                     SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName());
  137.                     text = STR_JUST_RAW_STRING;
  138.                 }
  139.                 uint text_width = GetStringBoundingBox(text).width;
  140.  
  141.                 uint cid_left = rtl ? square_left - 10 - widest_cid : square_left + square.width + 10;
  142.                 uint cid_right = rtl ? cid_left + widest_cid : cid_left + widest_cid;
  143.                 uint text_left = rtl ? cid_left - 10 - text_width : cid_right + 10;
  144.                 uint text_right = rtl ? text_left + text_width : text_left + text_width;
  145.                 DrawString(text_left, text_right, r.top + WD_MATRIX_TOP, text,
  146.                         (this->selected_slot == OWNER_DEITY) ? TC_WHITE : IsSelectable(OWNER_DEITY) ? TC_ORANGE : TC_SILVER);
  147.  
  148.                 break;
  149.             }
  150.  
  151.             case WID_AIC_LIST: {
  152.                 int y = r.top;
  153.  
  154.                 uint widest_cid = 0;
  155.                 for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
  156.                     SetDParam(0, i + 1);
  157.                     widest_cid = max(GetStringBoundingBox(STR_JUST_INT).width, widest_cid);
  158.                 }
  159.  
  160.                 Dimension square = GetSpriteSize(SPR_SQUARE);
  161.                 uint square_y_offset = (line_height - square.height) / 2;
  162.  
  163.                 Dimension rai = GetSpriteSize(SPR_RANDOM_AI);
  164.                 uint rai_y_offset = (line_height - rai.height) / 2;
  165.  
  166.                 Dimension warning = GetSpriteSize(SPR_WARNING_SIGN);
  167.                 uint warning_y_offset = (line_height - warning.height) / 2;
  168.                
  169.                 for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
  170.                     bool rtl = _current_text_dir == TD_RTL;
  171.                     uint square_left = rtl ? r.right - WD_MATRIX_RIGHT - square.width : r.left + WD_MATRIX_LEFT;
  172.                     DrawSprite(SPR_SQUARE, IsEligible((CompanyID)i) ? _game_mode != GM_NORMAL ? PALETTE_TO_BLUE : PALETTE_TO_ORANGE :
  173.                         Company::IsValidAiID(i) ? IsDead((CompanyID)i) ? PALETTE_TO_RED : PALETTE_TO_GREEN : PALETTE_TO_GREY,
  174.                             square_left, y + square_y_offset);
  175.  
  176.                     uint cid_left = rtl ? square_left - 10 - widest_cid : square_left + square.width + 10;
  177.                     uint cid_right = rtl ? cid_left + widest_cid : cid_left + widest_cid;
  178.                     SetDParam(0, i + 1);
  179.                     DrawString(cid_left, cid_right, y + WD_MATRIX_TOP, STR_JUST_INT, TC_LIGHT_BLUE);
  180.  
  181.                     StringID text;
  182.                     if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != NULL) {
  183.                         SetDParamStr(0, AIConfig::GetConfig((CompanyID)i)->GetInfo()->GetName());
  184.                         text = STR_JUST_RAW_STRING;
  185.                     } else {
  186.                         text = STR_AI_CONFIG_RANDOM_AI;
  187.                     }
  188.                     uint text_width = GetStringBoundingBox(text).width;
  189.                    
  190.                     uint text_left = rtl ? cid_left - 10 - text_width : cid_right + 10;
  191.                     uint text_right = rtl ? cid_left - 10 : text_left + text_width;
  192.                     DrawString(text_left, text_right, y + WD_MATRIX_TOP, text, (this->selected_slot == i) ? TC_WHITE : TC_ORANGE);
  193.  
  194.                     uint rai_left = rtl ? text_left - 10 - rai.width : text_right + 10;
  195.                     uint warning_left = rtl ? text_left - 10 - warning.width : text_right + 10;
  196.                     if (_game_mode == GM_NORMAL && Company::IsValidAiID(i) && AIConfig::GetConfig((CompanyID)i)->IsRandom()) {
  197.                         DrawSprite(SPR_RANDOM_AI, PAL_NONE, rai_left, y + rai_y_offset);
  198.                     } else if (Company::IsValidHumanID(i)) {
  199.                         DrawSprite(SPR_WARNING_SIGN, PAL_NONE, warning_left, y + warning_y_offset);
  200.                     }
  201.                     y += this->line_height;
  202.                 }
  203.                 break;
  204.             }
  205.         }
  206.     }
  207.  
  208.     virtual void OnClick(Point pt, int widget, int click_count)
  209.     {
  210.         if (widget >= WID_AIC_TEXTFILE && widget < WID_AIC_TEXTFILE + TFT_END) {
  211.             if (this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot) == NULL) return;
  212.  
  213.             ShowScriptTextfileWindow((TextfileType)(widget - WID_AIC_TEXTFILE), this->selected_slot);
  214.             return;
  215.         }
  216.  
  217.         switch (widget) {
  218.             case WID_AIC_DECREASE:
  219.             case WID_AIC_INCREASE: {
  220.                 int new_value;
  221.                 if (widget == WID_AIC_DECREASE) {
  222.                     new_value = max(0, GetGameSettings().difficulty.max_no_competitors - 1);
  223.                 } else {
  224.                     new_value = min(MAX_COMPANIES, GetGameSettings().difficulty.max_no_competitors + 1);
  225.                 }
  226.                 IConsoleSetSetting("difficulty.max_no_competitors", new_value);
  227.                 this->InvalidateData();
  228.                 break;
  229.             }
  230.  
  231.             case WID_AIC_GAMELIST: {
  232.                 this->selected_slot = OWNER_DEITY;
  233.                 this->InvalidateData();
  234.                 if (click_count > 1 && this->selected_slot != INVALID_COMPANY && _game_mode != GM_NORMAL) ShowAIListWindow((CompanyID)this->selected_slot);
  235.                 break;
  236.             }
  237.  
  238.             case WID_AIC_LIST: { // Select a slot
  239.                 this->selected_slot = (CompanyID)this->GetRowFromWidget(pt.y, widget, 0, this->line_height);
  240.                 this->InvalidateData();
  241.                 if (click_count > 1 && this->selected_slot != INVALID_COMPANY) ShowAIListWindow((CompanyID)this->selected_slot);
  242.                 break;
  243.             }
  244.  
  245.             case WID_AIC_MOVE_UP:
  246.                 if (IsSelectable(this->selected_slot) && IsDead(this->selected_slot) && IsSelectable((CompanyID)(this->selected_slot - 1)) && IsDead((CompanyID)(this->selected_slot - 1))) {
  247.                     Swap(GetGameSettings().ai_config[this->selected_slot], GetGameSettings().ai_config[this->selected_slot - 1]);
  248.                     this->selected_slot--;
  249.                     this->InvalidateData();
  250.                 }
  251.                 break;
  252.  
  253.             case WID_AIC_MOVE_DOWN:
  254.                 if (IsSelectable(this->selected_slot) && IsDead(this->selected_slot) && IsSelectable((CompanyID)(this->selected_slot + 1)) && IsDead((CompanyID)(this->selected_slot + 1))) {
  255.                     Swap(GetGameSettings().ai_config[this->selected_slot], GetGameSettings().ai_config[this->selected_slot + 1]);
  256.                     this->selected_slot++;
  257.                     this->InvalidateData();
  258.                 }
  259.                 break;
  260.  
  261.             case WID_AIC_CHANGE:  // choose other AI
  262.                 ShowAIListWindow((CompanyID)this->selected_slot);
  263.                 break;
  264.  
  265.             case WID_AIC_CONFIGURE: // change the settings for an AI
  266.                 ShowAISettingsWindow((CompanyID)this->selected_slot);
  267.                 break;
  268.  
  269.             case WID_AIC_CLOSE:
  270.                 delete this;
  271.                 break;
  272.  
  273.             case WID_AIC_CONTENT_DOWNLOAD:
  274.                 if (!_network_available) {
  275.                     ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
  276.                 } else {
  277. #if defined(ENABLE_NETWORK)
  278.                     ShowNetworkContentListWindow(NULL, CONTENT_TYPE_AI, CONTENT_TYPE_GAME);
  279. #endif
  280.                 }
  281.                 break;
  282.         }
  283.     }

Comments