mirror of https://github.com/OpenTTD/OpenTTD
(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)release/1.1
parent
b5bad6aa19
commit
a6750a145e
|
@ -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: 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: 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: 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: 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: 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)
|
- 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)
|
||||||
|
|
|
@ -1269,7 +1269,7 @@ DEF_CONSOLE_CMD(ConRescanNewGRF)
|
||||||
|
|
||||||
TarScanner::DoScan();
|
TarScanner::DoScan();
|
||||||
ScanNewGRFFiles();
|
ScanNewGRFFiles();
|
||||||
InvalidateWindowData(WC_GAME_OPTIONS, 0, 1);
|
InvalidateWindowData(WC_GAME_OPTIONS, 0, GOID_NEWGRF_RESCANNED);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -602,12 +602,22 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
break;
|
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 &&
|
if (mode == GLWM_HEIGHTMAP &&
|
||||||
(this->x * 2 < (1U << _settings_newgame.game_creation.map_x) ||
|
(map_x * 2 < (1U << _settings_newgame.game_creation.map_x) ||
|
||||||
this->x / 2 > (1U << _settings_newgame.game_creation.map_x) ||
|
map_x / 2 > (1U << _settings_newgame.game_creation.map_x) ||
|
||||||
this->y * 2 < (1U << _settings_newgame.game_creation.map_y) ||
|
map_y * 2 < (1U << _settings_newgame.game_creation.map_y) ||
|
||||||
this->y / 2 > (1U << _settings_newgame.game_creation.map_y))) {
|
map_y / 2 > (1U << _settings_newgame.game_creation.map_y))) {
|
||||||
ShowQuery(
|
ShowQuery(
|
||||||
STR_WARNING_HEIGHTMAP_SCALE_CAPTION,
|
STR_WARNING_HEIGHTMAP_SCALE_CAPTION,
|
||||||
STR_WARNING_HEIGHTMAP_SCALE_MESSAGE,
|
STR_WARNING_HEIGHTMAP_SCALE_MESSAGE,
|
||||||
|
@ -617,6 +627,7 @@ struct GenerateLandscapeWindow : public QueryStringBaseWindow {
|
||||||
StartGeneratingLandscape(mode);
|
StartGeneratingLandscape(mode);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GLAND_START_DATE_DOWN:
|
case GLAND_START_DATE_DOWN:
|
||||||
case GLAND_START_DATE_UP: // Year buttons
|
case GLAND_START_DATE_UP: // Year buttons
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
ScanNewGRFFiles();
|
ScanNewGRFFiles();
|
||||||
/* Yes... these are the NewGRF windows */
|
/* Yes... these are the NewGRF windows */
|
||||||
InvalidateWindowClassesData(WC_SAVELOAD);
|
InvalidateWindowClassesData(WC_SAVELOAD);
|
||||||
InvalidateWindowData(WC_GAME_OPTIONS, 0, 1);
|
InvalidateWindowData(WC_GAME_OPTIONS, 0, GOID_NEWGRF_RESCANNED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONTENT_TYPE_SCENARIO:
|
case CONTENT_TYPE_SCENARIO:
|
||||||
|
|
|
@ -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);
|
DEBUG(net, 1, "Closed client connection %d", this->client_id);
|
||||||
|
|
||||||
/* We just lost one client :( */
|
/* We just lost one client :( */
|
||||||
|
|
|
@ -570,7 +570,7 @@ struct NewGRFWindow : public QueryStringBaseWindow {
|
||||||
this->avails.SetFilterFuncs(this->filter_funcs);
|
this->avails.SetFilterFuncs(this->filter_funcs);
|
||||||
this->avails.ForceRebuild();
|
this->avails.ForceRebuild();
|
||||||
|
|
||||||
this->OnInvalidateData(2);
|
this->OnInvalidateData(GOID_NEWGRF_LIST_EDITED);
|
||||||
}
|
}
|
||||||
|
|
||||||
~NewGRFWindow()
|
~NewGRFWindow()
|
||||||
|
@ -882,7 +882,7 @@ struct NewGRFWindow : public QueryStringBaseWindow {
|
||||||
this->avail_pos = -1;
|
this->avail_pos = -1;
|
||||||
this->avail_sel = NULL;
|
this->avail_sel = NULL;
|
||||||
this->avails.ForceRebuild();
|
this->avails.ForceRebuild();
|
||||||
this->InvalidateData(2);
|
this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,7 +922,7 @@ struct NewGRFWindow : public QueryStringBaseWindow {
|
||||||
if (new_pos >= 0) this->avail_sel = this->avails[new_pos];
|
if (new_pos >= 0) this->avail_sel = this->avails[new_pos];
|
||||||
|
|
||||||
this->avails.ForceRebuild();
|
this->avails.ForceRebuild();
|
||||||
this->InvalidateData(2);
|
this->InvalidateData(GOID_NEWGRF_LIST_EDITED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -990,7 +990,7 @@ struct NewGRFWindow : public QueryStringBaseWindow {
|
||||||
this->avail_sel = NULL;
|
this->avail_sel = NULL;
|
||||||
this->avail_pos = -1;
|
this->avail_pos = -1;
|
||||||
this->avails.ForceRebuild();
|
this->avails.ForceRebuild();
|
||||||
this->InvalidateData(1);
|
this->InvalidateData(GOID_NEWGRF_RESCANNED);
|
||||||
this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
|
this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window
|
||||||
InvalidateWindowClassesData(WC_SAVELOAD);
|
InvalidateWindowClassesData(WC_SAVELOAD);
|
||||||
break;
|
break;
|
||||||
|
@ -1011,7 +1011,7 @@ struct NewGRFWindow : public QueryStringBaseWindow {
|
||||||
|
|
||||||
DeleteWindowByClass(WC_GRF_PARAMETERS);
|
DeleteWindowByClass(WC_GRF_PARAMETERS);
|
||||||
this->active_sel = NULL;
|
this->active_sel = NULL;
|
||||||
this->InvalidateData(3);
|
this->InvalidateData(GOID_NEWGRF_PRESET_LOADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnQueryTextFinished(char *str)
|
virtual void OnQueryTextFinished(char *str)
|
||||||
|
@ -1034,24 +1034,18 @@ struct NewGRFWindow : public QueryStringBaseWindow {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some data on this window has become invalid.
|
* Some data on this window has become invalid.
|
||||||
* @param data Information about the changed data.
|
* @param data Information about the changed data. @see GameOptionsInvalidationData
|
||||||
* - 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 gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
|
* @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)
|
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||||
{
|
{
|
||||||
if (!gui_scope) return;
|
if (!gui_scope) return;
|
||||||
switch (data) {
|
switch (data) {
|
||||||
default: NOT_REACHED();
|
default:
|
||||||
case 0:
|
|
||||||
/* Nothing important to do */
|
/* Nothing important to do */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case GOID_NEWGRF_RESCANNED:
|
||||||
/* Search the list for items that are now found and mark them as such. */
|
/* Search the list for items that are now found and mark them as such. */
|
||||||
for (GRFConfig **l = &this->actives; *l != NULL; l = &(*l)->next) {
|
for (GRFConfig **l = &this->actives; *l != NULL; l = &(*l)->next) {
|
||||||
GRFConfig *c = *l;
|
GRFConfig *c = *l;
|
||||||
|
@ -1068,14 +1062,14 @@ struct NewGRFWindow : public QueryStringBaseWindow {
|
||||||
|
|
||||||
delete c;
|
delete c;
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
|
||||||
case 4:
|
|
||||||
this->avails.ForceRebuild();
|
this->avails.ForceRebuild();
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
case 2:
|
case GOID_NEWGRF_LIST_EDITED:
|
||||||
this->preset = -1;
|
this->preset = -1;
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
case 3: {
|
case GOID_NEWGRF_PRESET_LOADED: {
|
||||||
|
/* Update scrollbars */
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) {}
|
for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) {}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event)
|
||||||
{
|
{
|
||||||
const GRFFile *file = GetEngineGRF(v->engine_type);
|
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;
|
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);
|
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 == CALLBACK_FAILED) return false;
|
||||||
|
|
||||||
if (callback >= ORIGINAL_SAMPLE_COUNT) {
|
if (callback >= ORIGINAL_SAMPLE_COUNT) {
|
||||||
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;
|
callback += file->sound_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1009,9 +1009,7 @@ static bool DifficultyChange(int32)
|
||||||
/* If we are a network-client, update the difficult setting (if it is open).
|
/* 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
|
* Use this instead of just dirtying the window because we need to load in
|
||||||
* the new difficulty settings */
|
* the new difficulty settings */
|
||||||
if (_networking && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) {
|
if (_networking) InvalidateWindowClassesData(WC_GAME_OPTIONS, GOID_DIFFICULTY_CHANGED);
|
||||||
ShowGameDifficulty();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,7 +462,7 @@ struct GameOptionsWindow : Window {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some data on this window has become invalid.
|
* 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.
|
* @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)
|
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||||
|
@ -596,9 +596,6 @@ public:
|
||||||
{
|
{
|
||||||
this->InitNested(desc);
|
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
|
/* Setup disabled buttons when creating window
|
||||||
* disable all other difficulty buttons during gameplay except for 'custom' */
|
* disable all other difficulty buttons during gameplay except for 'custom' */
|
||||||
this->SetWidgetsDisabledState(_game_mode != GM_MENU,
|
this->SetWidgetsDisabledState(_game_mode != GM_MENU,
|
||||||
|
@ -609,8 +606,9 @@ public:
|
||||||
WIDGET_LIST_END);
|
WIDGET_LIST_END);
|
||||||
this->SetWidgetDisabledState(GDW_HIGHSCORE, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer
|
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->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
|
virtual void SetStringParameters(int widget) const
|
||||||
|
@ -734,12 +732,23 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some data on this window has become invalid.
|
* 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.
|
* @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)
|
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
|
||||||
{
|
{
|
||||||
if (!gui_scope) return;
|
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;
|
uint i;
|
||||||
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i);
|
const SettingDesc *sd = GetSettingFromName("difficulty.max_no_competitors", &i);
|
||||||
for (i = 0; i < GAME_DIFFICULTY_NUM; i++, sd++) {
|
for (i = 0; i < GAME_DIFFICULTY_NUM; i++, sd++) {
|
||||||
|
|
|
@ -115,6 +115,17 @@ enum WindowClass {
|
||||||
WC_INVALID = 0xFFFF
|
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;
|
struct Window;
|
||||||
|
|
||||||
/** Number to differentiate different windows of the same class */
|
/** Number to differentiate different windows of the same class */
|
||||||
|
|
Loading…
Reference in New Issue