|
|
|
@ -682,238 +682,6 @@ void ShowGameOptions()
|
|
|
|
|
new GameOptionsWindow(&_game_options_desc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern void StartupEconomy();
|
|
|
|
|
|
|
|
|
|
void SetDifficultyLevel(int mode, DifficultySettings *gm_opt);
|
|
|
|
|
|
|
|
|
|
class GameDifficultyWindow : public Window {
|
|
|
|
|
private:
|
|
|
|
|
/* Temporary holding place of values in the difficulty window until 'Save' is clicked */
|
|
|
|
|
GameSettings opt_mod_temp;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/** The number of difficulty settings */
|
|
|
|
|
static const uint GAME_DIFFICULTY_NUM = 18;
|
|
|
|
|
/** The number of widgets per difficulty setting */
|
|
|
|
|
static const uint WIDGETS_PER_DIFFICULTY = 3;
|
|
|
|
|
|
|
|
|
|
GameDifficultyWindow(const WindowDesc *desc) : Window()
|
|
|
|
|
{
|
|
|
|
|
this->InitNested(desc, WN_GAME_OPTIONS_GAME_DIFFICULTY);
|
|
|
|
|
|
|
|
|
|
this->SetWidgetDisabledState(WID_GD_HIGHSCORE, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer
|
|
|
|
|
this->SetWidgetDisabledState(WID_GD_ACCEPT, _networking && !_network_server); // Save-button in multiplayer (and if client)
|
|
|
|
|
|
|
|
|
|
/* Read data */
|
|
|
|
|
this->opt_mod_temp = GetGameSettings();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void SetStringParameters(int widget) const
|
|
|
|
|
{
|
|
|
|
|
widget -= WID_GD_OPTIONS_START;
|
|
|
|
|
if (widget < 0 || (widget % 3) != 2) return;
|
|
|
|
|
|
|
|
|
|
widget /= 3;
|
|
|
|
|
|
|
|
|
|
uint i;
|
|
|
|
|
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i) + widget;
|
|
|
|
|
int32 value = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv);
|
|
|
|
|
SetDParam(0, sd->desc.str_val + value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
|
|
|
|
|
{
|
|
|
|
|
/* Only for the 'descriptions' */
|
|
|
|
|
int index = widget - WID_GD_OPTIONS_START;
|
|
|
|
|
if (index < 0 || (index % 3) != 2) return;
|
|
|
|
|
|
|
|
|
|
index /= 3;
|
|
|
|
|
|
|
|
|
|
uint i;
|
|
|
|
|
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i) + index;
|
|
|
|
|
const SettingDescBase *sdb = &sd->desc;
|
|
|
|
|
|
|
|
|
|
/* Get the string and try all strings from the smallest to the highest value */
|
|
|
|
|
StringID str = this->GetWidget<NWidgetCore>(widget)->widget_data;
|
|
|
|
|
for (int32 value = sdb->min; (uint32)value <= sdb->max; value += sdb->interval) {
|
|
|
|
|
SetDParam(0, sdb->str_val + value);
|
|
|
|
|
*size = maxdim(*size, GetStringBoundingBox(str));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void OnClick(Point pt, int widget, int click_count)
|
|
|
|
|
{
|
|
|
|
|
if (widget >= WID_GD_OPTIONS_START) {
|
|
|
|
|
widget -= WID_GD_OPTIONS_START;
|
|
|
|
|
if ((widget % 3) == 2) return;
|
|
|
|
|
|
|
|
|
|
/* Don't allow clients to make any changes */
|
|
|
|
|
if (_networking && !_network_server) return;
|
|
|
|
|
|
|
|
|
|
uint i;
|
|
|
|
|
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i) + (widget / 3);
|
|
|
|
|
const SettingDescBase *sdb = &sd->desc;
|
|
|
|
|
|
|
|
|
|
int32 val = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv);
|
|
|
|
|
if (widget % 3 == 1) {
|
|
|
|
|
/* Increase button clicked */
|
|
|
|
|
val = min(val + sdb->interval, (int32)sdb->max);
|
|
|
|
|
} else {
|
|
|
|
|
/* Decrease button clicked */
|
|
|
|
|
val -= sdb->interval;
|
|
|
|
|
val = max(val, sdb->min);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* save value in temporary variable */
|
|
|
|
|
WriteValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv, val);
|
|
|
|
|
this->InvalidateData();
|
|
|
|
|
|
|
|
|
|
if (widget / 3 == 0 &&
|
|
|
|
|
AI::GetInfoList()->size() == 0 &&
|
|
|
|
|
this->opt_mod_temp.difficulty.max_no_competitors != 0) {
|
|
|
|
|
ShowErrorMessage(STR_WARNING_NO_SUITABLE_AI, INVALID_STRING_ID, WL_CRITICAL);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (widget) {
|
|
|
|
|
case WID_GD_HIGHSCORE: // Highscore Table
|
|
|
|
|
ShowHighscoreTable();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WID_GD_ACCEPT: { // Save button - save changes
|
|
|
|
|
GameSettings *opt_ptr = &GetGameSettings();
|
|
|
|
|
|
|
|
|
|
uint i;
|
|
|
|
|
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i);
|
|
|
|
|
for (uint btn = 0; btn != GAME_DIFFICULTY_NUM; btn++, sd++) {
|
|
|
|
|
int32 new_val = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv);
|
|
|
|
|
int32 cur_val = (int32)ReadValue(GetVariableAddress(opt_ptr, &sd->save), sd->save.conv);
|
|
|
|
|
/* if setting has changed, change it */
|
|
|
|
|
if (new_val != cur_val) {
|
|
|
|
|
DoCommandP(0, i + btn, new_val, CMD_CHANGE_SETTING);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete this;
|
|
|
|
|
/* If we are in the editor, we should reload the economy.
|
|
|
|
|
* This way when you load a game, the max loan and interest rate
|
|
|
|
|
* are loaded correctly. */
|
|
|
|
|
if (_game_mode == GM_EDITOR) StartupEconomy();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case WID_GD_CANCEL: // Cancel button - close window, abandon changes
|
|
|
|
|
delete this;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Some data on this window has become invalid.
|
|
|
|
|
* @param data Information about the changed data. @see GameOptionsInvalidationData
|
|
|
|
|
* @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.
|
|
|
|
|
*/
|
|
|
|
|
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
|
|
|
|
{
|
|
|
|
|
if (!gui_scope) return;
|
|
|
|
|
|
|
|
|
|
uint i;
|
|
|
|
|
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i);
|
|
|
|
|
for (i = 0; i < GAME_DIFFICULTY_NUM; i++, sd++) {
|
|
|
|
|
const SettingDescBase *sdb = &sd->desc;
|
|
|
|
|
/* skip deprecated difficulty options */
|
|
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
|
|
int32 value = (int32)ReadValue(GetVariableAddress(&this->opt_mod_temp, &sd->save), sd->save.conv);
|
|
|
|
|
bool disable = !sd->IsEditable();
|
|
|
|
|
this->SetWidgetDisabledState(WID_GD_OPTIONS_START + i * 3 + 0, disable || sdb->min == value);
|
|
|
|
|
this->SetWidgetDisabledState(WID_GD_OPTIONS_START + i * 3 + 1, disable || sdb->max == (uint32)value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static NWidgetBase *MakeDifficultyOptionsWidgets(int *biggest_index)
|
|
|
|
|
{
|
|
|
|
|
NWidgetVertical *vert_desc = new NWidgetVertical;
|
|
|
|
|
|
|
|
|
|
int widnum = WID_GD_OPTIONS_START;
|
|
|
|
|
uint i, j;
|
|
|
|
|
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i);
|
|
|
|
|
|
|
|
|
|
for (i = 0, j = 0; i < GameDifficultyWindow::GAME_DIFFICULTY_NUM; i++, sd++, widnum += GameDifficultyWindow::WIDGETS_PER_DIFFICULTY) {
|
|
|
|
|
if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
|
|
|
|
|
|
|
|
|
|
NWidgetHorizontal *hor = new NWidgetHorizontal;
|
|
|
|
|
|
|
|
|
|
/* [<] button. */
|
|
|
|
|
NWidgetLeaf *leaf = new NWidgetLeaf(WWT_PUSHARROWBTN, COLOUR_YELLOW, widnum, AWV_DECREASE, STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST);
|
|
|
|
|
hor->Add(leaf);
|
|
|
|
|
|
|
|
|
|
/* [>] button. */
|
|
|
|
|
leaf = new NWidgetLeaf(WWT_PUSHARROWBTN, COLOUR_YELLOW, widnum + 1, AWV_INCREASE, STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST);
|
|
|
|
|
hor->Add(leaf);
|
|
|
|
|
|
|
|
|
|
/* Some spacing between the text and the description */
|
|
|
|
|
NWidgetSpacer *spacer = new NWidgetSpacer(5, 0);
|
|
|
|
|
hor->Add(spacer);
|
|
|
|
|
|
|
|
|
|
/* Descriptive text. */
|
|
|
|
|
leaf = new NWidgetLeaf(WWT_TEXT, COLOUR_YELLOW, widnum + 2, STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS + (j++), STR_NULL);
|
|
|
|
|
leaf->SetFill(1, 0);
|
|
|
|
|
hor->Add(leaf);
|
|
|
|
|
vert_desc->Add(hor);
|
|
|
|
|
|
|
|
|
|
/* Space vertically */
|
|
|
|
|
vert_desc->Add(new NWidgetSpacer(0, 2));
|
|
|
|
|
}
|
|
|
|
|
*biggest_index = widnum - 1;
|
|
|
|
|
return vert_desc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Widget definition for the game difficulty settings window */
|
|
|
|
|
static const NWidgetPart _nested_game_difficulty_widgets[] = {
|
|
|
|
|
NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_DIFFICULTY_LEVEL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
|
|
|
|
|
NWidget(WWT_PANEL, COLOUR_MAUVE),
|
|
|
|
|
NWidget(NWID_VERTICAL), SetPIP(2, 0, 2),
|
|
|
|
|
NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10),
|
|
|
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GD_HIGHSCORE), SetDataTip(STR_DIFFICULTY_LEVEL_HIGH_SCORE_BUTTON, STR_NULL), SetFill(1, 0),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
NWidget(WWT_PANEL, COLOUR_MAUVE),
|
|
|
|
|
NWidget(NWID_VERTICAL), SetPIP(3, 0, 1),
|
|
|
|
|
NWidget(NWID_HORIZONTAL), SetPIP(5, 0, 5),
|
|
|
|
|
NWidgetFunction(MakeDifficultyOptionsWidgets),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
NWidget(WWT_PANEL, COLOUR_MAUVE),
|
|
|
|
|
NWidget(NWID_VERTICAL), SetPIP(2, 0, 2),
|
|
|
|
|
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10),
|
|
|
|
|
NWidget(NWID_SPACER), SetFill(1, 0),
|
|
|
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GD_ACCEPT), SetDataTip(STR_DIFFICULTY_LEVEL_SAVE, STR_NULL), SetFill(1, 0),
|
|
|
|
|
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GD_CANCEL), SetDataTip(STR_BUTTON_CANCEL, STR_NULL), SetFill(1, 0),
|
|
|
|
|
NWidget(NWID_SPACER), SetFill(1, 0),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
EndContainer(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Window definition for the game difficulty settings window */
|
|
|
|
|
static const WindowDesc _game_difficulty_desc(
|
|
|
|
|
WDP_CENTER, 0, 0,
|
|
|
|
|
WC_GAME_OPTIONS, WC_NONE,
|
|
|
|
|
0,
|
|
|
|
|
_nested_game_difficulty_widgets, lengthof(_nested_game_difficulty_widgets)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/** Open the game-difficulty window. */
|
|
|
|
|
void ShowGameDifficulty()
|
|
|
|
|
{
|
|
|
|
|
DeleteWindowByClass(WC_GAME_OPTIONS);
|
|
|
|
|
new GameDifficultyWindow(&_game_difficulty_desc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int SETTING_HEIGHT = 11; ///< Height of a single setting in the tree view in pixels
|
|
|
|
|
static const int LEVEL_WIDTH = 15; ///< Indenting width of a sub-page in pixels
|
|
|
|
|
|
|
|
|
|