diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index c5a657dd6d..5370cfd293 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -82,6 +82,7 @@ enum SaveLoadWindowWidgets { SLWW_DETAILS, ///< Panel with game details SLWW_NEWGRF_INFO, ///< Button to open NewGgrf configuration SLWW_LOAD_BUTTON, ///< Button to load game/scenario + SLWW_MISSING_NEWGRFS, ///< Button to find missing NewGRFs online }; /** Load game/scenario with optional content download */ @@ -114,6 +115,7 @@ static const NWidgetPart _nested_load_dialog_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EMPTY, INVALID_COLOUR, SLWW_DETAILS), SetResize(1, 1), SetFill(1, 1), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_MISSING_NEWGRFS), SetDataTip(STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON, STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP), SetFill(1, 0), SetResize(1, 0), NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SLWW_NEWGRF_INFO), SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_NULL), SetFill(1, 0), SetResize(1, 0), @@ -554,6 +556,16 @@ public: } break; + case SLWW_MISSING_NEWGRFS: + if (!_network_available) { + ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR); + } else { +#if defined(ENABLE_NETWORK) + ShowMissingContentWindow(_load_check_data.grfconfig); +#endif + } + break; + case SLWW_DRIVES_DIRECTORIES_LIST: { // Click the listbox int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, SLWW_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP); if (y == INT_MAX) return; @@ -699,6 +711,8 @@ public: this->selected == NULL || _load_check_data.HasErrors() || !(_load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs())); this->SetWidgetDisabledState(SLWW_NEWGRF_INFO, !_load_check_data.HasNewGrfs()); + this->SetWidgetDisabledState(SLWW_MISSING_NEWGRFS, + !_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility == GLC_ALL_GOOD); } break; case 2: diff --git a/src/network/network_content.h b/src/network/network_content.h index f9a7fdca1d..ce369cdaef 100644 --- a/src/network/network_content.h +++ b/src/network/network_content.h @@ -151,6 +151,8 @@ extern ClientNetworkContentSocketHandler _network_content_client; void ShowNetworkContentListWindow(ContentVector *cv = NULL, ContentType type = CONTENT_TYPE_END); +void ShowMissingContentWindow(const struct GRFConfig *list); + #else static inline void ShowNetworkContentListWindow() {} #endif /* ENABLE_NETWORK */ diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 03901e295a..42b89813c7 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -19,6 +19,7 @@ #include "network_gamelist.h" #include "network.h" #include "network_base.h" +#include "network_content.h" #include "../gui.h" #include "network_udp.h" #include "../window_func.h" @@ -105,6 +106,8 @@ enum NetworkGameWindowWidgets { NGWW_REFRESH, ///< 'Refresh server' button NGWW_NEWGRF, ///< 'NewGRF Settings' button NGWW_NEWGRF_SEL, ///< Selection 'widget' to hide the NewGRF settings + NGWW_NEWGRF_MISSING, ///< 'Find missing NewGRF online' button + NGWW_NEWGRF_MISSING_SEL, ///< Selection widget for the above button NGWW_FIND, ///< 'Find server' button NGWW_ADD, ///< 'Add server' button @@ -603,6 +606,7 @@ public: /* 'NewGRF Settings' button invisible if no NewGRF is used */ this->GetWidget(NGWW_NEWGRF_SEL)->SetDisplayedPlane(sel == NULL || !sel->online || sel->info.grfconfig == NULL); + this->GetWidget(NGWW_NEWGRF_MISSING_SEL)->SetDisplayedPlane(sel == NULL || !sel->online || sel->info.grfconfig == NULL || !sel->info.version_compatible || sel->info.compatible); this->DrawWidgets(); /* Edit box to set client name */ @@ -776,6 +780,10 @@ public: case NGWW_NEWGRF: // NewGRF Settings if (this->server != NULL) ShowNewGRFSettings(false, false, false, &this->server->info.grfconfig); break; + + case NGWW_NEWGRF_MISSING: // Find missing content online + if (this->server != NULL) ShowMissingContentWindow(this->server->info.grfconfig); + break; } } @@ -960,6 +968,12 @@ static const NWidgetPart _nested_network_game_widgets[] = { NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, NGWW_DETAILS), NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(5, 5, 5), NWidget(WWT_EMPTY, INVALID_COLOUR, NGWW_DETAILS_SPACER), SetMinimalSize(140, 155), SetResize(0, 1), SetFill(1, 1), // Make sure it's at least this wide + NWidget(NWID_HORIZONTAL, NC_NONE), SetPIP(5, 5, 5), + NWidget(NWID_SELECTION, INVALID_COLOUR, NGWW_NEWGRF_MISSING_SEL), + NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, NGWW_NEWGRF_MISSING), SetFill(1, 0), SetDataTip(STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON, STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(5, 5, 5), NWidget(NWID_SPACER), SetFill(1, 0), NWidget(NWID_SELECTION, INVALID_COLOUR, NGWW_NEWGRF_SEL), diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 6607f4ca7f..7b3604157f 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -1196,20 +1196,7 @@ struct NewGRFWindow : public QueryStringBaseWindow, NewGRFScanCallback { #if defined(ENABLE_NETWORK) this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window - /* Only show the things in the current list, or everything when nothing's selected */ - ContentVector cv; - for (const GRFConfig *c = this->actives; c != NULL; c = c->next) { - if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue; - - ContentInfo *ci = new ContentInfo(); - ci->type = CONTENT_TYPE_NEWGRF; - ci->state = ContentInfo::DOES_NOT_EXIST; - ttd_strlcpy(ci->name, c->GetName(), lengthof(ci->name)); - ci->unique_id = BSWAP32(c->ident.grfid); - memcpy(ci->md5sum, HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum, sizeof(ci->md5sum)); - *cv.Append() = ci; - } - ShowNetworkContentListWindow(cv.Length() == 0 ? NULL : &cv, CONTENT_TYPE_NEWGRF); + ShowMissingContentWindow(this->actives); #endif } break; @@ -1506,6 +1493,30 @@ private: } }; +#if defined(ENABLE_NETWORK) +/** + * Show the content list window with all missing grfs from the given list. + * @param list The list of grfs to check for missings / not exactly matching ones. + */ +void ShowMissingContentWindow(const GRFConfig *list) +{ + /* Only show the things in the current list, or everything when nothing's selected */ + ContentVector cv; + for (const GRFConfig *c = list; c != NULL; c = c->next) { + if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue; + + ContentInfo *ci = new ContentInfo(); + ci->type = CONTENT_TYPE_NEWGRF; + ci->state = ContentInfo::DOES_NOT_EXIST; + ttd_strlcpy(ci->name, c->GetName(), lengthof(ci->name)); + ci->unique_id = BSWAP32(c->ident.grfid); + memcpy(ci->md5sum, HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum, sizeof(ci->md5sum)); + *cv.Append() = ci; + } + ShowNetworkContentListWindow(cv.Length() == 0 ? NULL : &cv, CONTENT_TYPE_NEWGRF); +} +#endif + Listing NewGRFWindow::last_sorting = {false, 0}; Filtering NewGRFWindow::last_filtering = {false, 0};