From a6750a145e788a03591d022a93c281407b15f3d9 Mon Sep 17 00:00:00 2001 From: rubidium Date: Sun, 10 Jul 2011 20:17:56 +0000 Subject: [PATCH] (svn r22650) [1.1] -Backport from trunk: - Fix: When changing difficulty settings over the network, do not just reopen the difficulty window if any game options window is opened; instead invalidate them properly [FS#4653] (r22618, r22617) - Fix: [NewGRF] If callback 33 returns a value out of range, no sound effect shall be played [FS#4656] (r22614) - Fix: Use rotated heightmap sizes for reporting scaling problems [FS#4663] (r22608) - Fix: No client error packet was sent to the admin bots [FS#4585] (r22384) --- changelog.txt | 1 - src/console_cmds.cpp | 2 +- src/genworld_gui.cpp | 21 +++++++++++++++----- src/network/network_content_gui.cpp | 2 +- src/network/network_server.cpp | 1 + src/newgrf_gui.cpp | 30 ++++++++++++----------------- src/newgrf_sound.cpp | 13 ++++++++++++- src/settings.cpp | 4 +--- src/settings_gui.cpp | 23 +++++++++++++++------- src/window_type.h | 11 +++++++++++ 10 files changed, 71 insertions(+), 37 deletions(-) diff --git a/changelog.txt b/changelog.txt index f1680b9aa4..bc06e2d71d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -27,7 +27,6 @@ - Fix: When a game uses a lot of NewGRFs the buffer for storing that information in the PNG is too small (r22388) - Fix: Windows' recv seems to return 'graceful closed' before having passed the remaining buffer which causes OpenTTD to think all connections are 'incorrectly' terminated, i.e. without the 'I am leaving' packet from the client. So let the client wait a tiny bit after sending the 'I am leaving' packet and before gracefully closing the connection [FS#4601] (r22387) - Fix: When the last AI company gets removed, the 'dead' state was not reset in the AI debug window [FS#4602] (r22386) -- Fix: No client error packet was sent to the admin bots [FS#4585] (r22384) - Fix: Recolouring of silicon bridge was done incorrectly (r22380, r22379, r22378) - Fix: Crash when clicking a removed company in the vehicle list dropdowns [FS#4592] (r22373) - Fix: Keep better accounting of the order in which clients joined; client cannot be starved from joining and they get shown the amount of clients waiting in front of them (r22372, r22370, r22369, r22368, r22367, r22366, r22365, r22364, r22363, r22362, r22361) diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 330bb46910..cbe8976c7a 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1269,7 +1269,7 @@ DEF_CONSOLE_CMD(ConRescanNewGRF) TarScanner::DoScan(); ScanNewGRFFiles(); - InvalidateWindowData(WC_GAME_OPTIONS, 0, 1); + InvalidateWindowData(WC_GAME_OPTIONS, 0, GOID_NEWGRF_RESCANNED); return true; } diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 4ceedb78db..1a20297279 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -602,12 +602,22 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow { this->SetDirty(); break; - case GLAND_GENERATE_BUTTON: // Generate + case GLAND_GENERATE_BUTTON: { // Generate + /* Get rotated map size. */ + uint map_x; + uint map_y; + if (_settings_newgame.game_creation.heightmap_rotation == HM_CLOCKWISE) { + map_x = this->y; + map_y = this->x; + } else { + map_x = this->x; + map_y = this->y; + } if (mode == GLWM_HEIGHTMAP && - (this->x * 2 < (1U << _settings_newgame.game_creation.map_x) || - this->x / 2 > (1U << _settings_newgame.game_creation.map_x) || - this->y * 2 < (1U << _settings_newgame.game_creation.map_y) || - this->y / 2 > (1U << _settings_newgame.game_creation.map_y))) { + (map_x * 2 < (1U << _settings_newgame.game_creation.map_x) || + map_x / 2 > (1U << _settings_newgame.game_creation.map_x) || + map_y * 2 < (1U << _settings_newgame.game_creation.map_y) || + map_y / 2 > (1U << _settings_newgame.game_creation.map_y))) { ShowQuery( STR_WARNING_HEIGHTMAP_SCALE_CAPTION, STR_WARNING_HEIGHTMAP_SCALE_MESSAGE, @@ -617,6 +627,7 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow { StartGeneratingLandscape(mode); } break; + } case GLAND_START_DATE_DOWN: case GLAND_START_DATE_UP: // Year buttons diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 13e0b5d59c..1e4cef8c15 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -118,7 +118,7 @@ public: ScanNewGRFFiles(); /* Yes... these are the NewGRF windows */ InvalidateWindowClassesData(WC_SAVELOAD); - InvalidateWindowData(WC_GAME_OPTIONS, 0, 1); + InvalidateWindowData(WC_GAME_OPTIONS, 0, GOID_NEWGRF_RESCANNED); break; case CONTENT_TYPE_SCENARIO: diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index ab10f8b223..5ddfca723c 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -240,6 +240,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta } } + NetworkAdminClientError(this->client_id, NETWORK_ERROR_CONNECTION_LOST); DEBUG(net, 1, "Closed client connection %d", this->client_id); /* We just lost one client :( */ diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 37f644dbc0..8484bb5e84 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -570,7 +570,7 @@ struct NewGRFWindow : public QueryStringBaseWindow { this->avails.SetFilterFuncs(this->filter_funcs); this->avails.ForceRebuild(); - this->OnInvalidateData(2); + this->OnInvalidateData(GOID_NEWGRF_LIST_EDITED); } ~NewGRFWindow() @@ -882,7 +882,7 @@ struct NewGRFWindow : public QueryStringBaseWindow { this->avail_pos = -1; this->avail_sel = NULL; this->avails.ForceRebuild(); - this->InvalidateData(2); + this->InvalidateData(GOID_NEWGRF_LIST_EDITED); break; } @@ -922,7 +922,7 @@ struct NewGRFWindow : public QueryStringBaseWindow { if (new_pos >= 0) this->avail_sel = this->avails[new_pos]; this->avails.ForceRebuild(); - this->InvalidateData(2); + this->InvalidateData(GOID_NEWGRF_LIST_EDITED); break; } @@ -990,7 +990,7 @@ struct NewGRFWindow : public QueryStringBaseWindow { this->avail_sel = NULL; this->avail_pos = -1; this->avails.ForceRebuild(); - this->InvalidateData(1); + this->InvalidateData(GOID_NEWGRF_RESCANNED); this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window InvalidateWindowClassesData(WC_SAVELOAD); break; @@ -1011,7 +1011,7 @@ struct NewGRFWindow : public QueryStringBaseWindow { DeleteWindowByClass(WC_GRF_PARAMETERS); this->active_sel = NULL; - this->InvalidateData(3); + this->InvalidateData(GOID_NEWGRF_PRESET_LOADED); } virtual void OnQueryTextFinished(char *str) @@ -1034,24 +1034,18 @@ struct NewGRFWindow : public QueryStringBaseWindow { /** * Some data on this window has become invalid. - * @param data Information about the changed data. - * - 0: (optionally) build availables, update button status. - * - 1: build availables, Add newly found grfs, update button status. - * - 2: (optionally) build availables, Reset preset, + 3 - * - 3: (optionally) build availables, Update active scrollbar, update button status. - * - 4: Force a rebuild of the availables, + 2 + * @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; switch (data) { - default: NOT_REACHED(); - case 0: + default: /* Nothing important to do */ break; - case 1: + case GOID_NEWGRF_RESCANNED: /* Search the list for items that are now found and mark them as such. */ for (GRFConfig **l = &this->actives; *l != NULL; l = &(*l)->next) { GRFConfig *c = *l; @@ -1068,14 +1062,14 @@ struct NewGRFWindow : public QueryStringBaseWindow { delete c; } - /* FALL THROUGH */ - case 4: + this->avails.ForceRebuild(); /* FALL THROUGH */ - case 2: + case GOID_NEWGRF_LIST_EDITED: this->preset = -1; /* FALL THROUGH */ - case 3: { + case GOID_NEWGRF_PRESET_LOADED: { + /* Update scrollbars */ int i = 0; for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) {} diff --git a/src/newgrf_sound.cpp b/src/newgrf_sound.cpp index cbb6d512f5..e5ab65d90b 100644 --- a/src/newgrf_sound.cpp +++ b/src/newgrf_sound.cpp @@ -51,6 +51,12 @@ uint GetNumSounds() } +/** + * Checks whether a NewGRF wants to play a different vehicle sound effect. + * @param v Vehicle to play sound effect for. + * @param event Trigger for the sound effect. + * @return false if the default sound effect shall be played instead. + */ bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event) { const GRFFile *file = GetEngineGRF(v->engine_type); @@ -63,10 +69,15 @@ bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event) if (!HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_SOUND_EFFECT)) return false; callback = GetVehicleCallback(CBID_VEHICLE_SOUND_EFFECT, event, 0, v->engine_type, v); + /* Play default sound if callback fails */ if (callback == CALLBACK_FAILED) return false; + if (callback >= ORIGINAL_SAMPLE_COUNT) { callback -= ORIGINAL_SAMPLE_COUNT; - if (callback > file->num_sounds) return false; + + /* Play no sound if result is out of range */ + if (callback > file->num_sounds) return true; + callback += file->sound_offset; } diff --git a/src/settings.cpp b/src/settings.cpp index c1ee7efb2a..275be0a9c5 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1009,9 +1009,7 @@ static bool DifficultyChange(int32) /* If we are a network-client, update the difficult setting (if it is open). * Use this instead of just dirtying the window because we need to load in * the new difficulty settings */ - if (_networking && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) { - ShowGameDifficulty(); - } + if (_networking) InvalidateWindowClassesData(WC_GAME_OPTIONS, GOID_DIFFICULTY_CHANGED); return true; } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 2a7477afcb..58eda3f056 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -462,7 +462,7 @@ struct GameOptionsWindow : Window { /** * Some data on this window has become invalid. - * @param data Information about the changed data. + * @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) @@ -596,9 +596,6 @@ public: { this->InitNested(desc); - /* Copy current settings (ingame or in intro) to temporary holding place - * change that when setting stuff, copy back on clicking 'OK' */ - this->opt_mod_temp = GetGameSettings(); /* Setup disabled buttons when creating window * disable all other difficulty buttons during gameplay except for 'custom' */ this->SetWidgetsDisabledState(_game_mode != GM_MENU, @@ -609,8 +606,9 @@ public: WIDGET_LIST_END); this->SetWidgetDisabledState(GDW_HIGHSCORE, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer this->SetWidgetDisabledState(GDW_ACCEPT, _networking && !_network_server); // Save-button in multiplayer (and if client) - this->LowerWidget(GDW_LVL_EASY + this->opt_mod_temp.difficulty.diff_level); - this->OnInvalidateData(); + + /* Read data */ + this->OnInvalidateData(GOID_DIFFICULTY_CHANGED); } virtual void SetStringParameters(int widget) const @@ -734,12 +732,23 @@ public: /** * Some data on this window has become invalid. - * @param data Information about the changed data. + * @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; + + if (data == GOID_DIFFICULTY_CHANGED) { + /* Window was created or settings were changed on server. Reread everything. */ + + /* Copy current settings (ingame or in intro) to temporary holding place + * change that when setting stuff, copy back on clicking 'OK' */ + this->opt_mod_temp = GetGameSettings(); + + this->LowerWidget(GDW_LVL_EASY + this->opt_mod_temp.difficulty.diff_level); + } + uint i; const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i); for (i = 0; i < GAME_DIFFICULTY_NUM; i++, sd++) { diff --git a/src/window_type.h b/src/window_type.h index b456b9f4bc..d6ac42d0d3 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -115,6 +115,17 @@ enum WindowClass { WC_INVALID = 0xFFFF }; +/** + * Data value for #Window::OnInvalidateData() of windows with class #WC_GAME_OPTIONS. + */ +enum GameOptionsInvalidationData { + GOID_DEFAULT = 0, + GOID_NEWGRF_RESCANNED, ///< NewGRFs were just rescanned. + GOID_NEWGRF_LIST_EDITED, ///< List of active NewGRFs is being edited. + GOID_NEWGRF_PRESET_LOADED, ///< A NewGRF preset was picked. + GOID_DIFFICULTY_CHANGED, ///< Difficulty settings were changed. +}; + struct Window; /** Number to differentiate different windows of the same class */