diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -53,7 +53,6 @@ #include "../safeguards.h" static void ShowNetworkStartServerWindow(); -static void ShowNetworkLobbyWindow(NetworkGameList *ngl); static const int NETWORK_LIST_REFRESH_DELAY = 30; ///< Time, in seconds, between updates of the network list. @@ -770,7 +769,7 @@ public: case WID_NG_JOIN: // Join Game if (this->server != nullptr) { - ShowNetworkLobbyWindow(this->server); + NetworkClientConnectGame(this->server->connection_string, COMPANY_SPECTATOR); } break; @@ -990,7 +989,6 @@ static WindowDesc _network_game_window_d void ShowNetworkGameWindow() { static bool first = true; - CloseWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY); CloseWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START); /* Only show once */ @@ -1266,328 +1264,10 @@ static void ShowNetworkStartServerWindow if (!NetworkValidateOurClientName()) return; CloseWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME); - CloseWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY); new NetworkStartServerWindow(&_network_start_server_window_desc); } -struct NetworkLobbyWindow : public Window { - CompanyID company; ///< Selected company - NetworkGameList *server; ///< Selected server - NetworkCompanyInfo company_info[MAX_COMPANIES]; - Scrollbar *vscroll; - - NetworkLobbyWindow(WindowDesc *desc, NetworkGameList *ngl) : - Window(desc), company(INVALID_COMPANY), server(ngl) - { - this->CreateNestedTree(); - this->vscroll = this->GetScrollbar(WID_NL_SCROLLBAR); - this->FinishInitNested(WN_NETWORK_WINDOW_LOBBY); - } - - CompanyID NetworkLobbyFindCompanyIndex(byte pos) const - { - /* Scroll through all this->company_info and get the 'pos' item that is not empty. */ - for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { - if (!this->company_info[i].company_name.empty()) { - if (pos-- == 0) return i; - } - } - - return COMPANY_FIRST; - } - - void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override - { - switch (widget) { - case WID_NL_HEADER: - size->height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM; - break; - - case WID_NL_MATRIX: - resize->height = WD_MATRIX_TOP + std::max(std::max(GetSpriteSize(SPR_LOCK).height, GetSpriteSize(SPR_PROFIT_LOT).height), FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM; - size->height = 10 * resize->height; - break; - - case WID_NL_DETAILS: - size->height = 30 + 11 * FONT_HEIGHT_NORMAL; - break; - } - } - - void SetStringParameters(int widget) const override - { - switch (widget) { - case WID_NL_TEXT: - SetDParamStr(0, this->server->info.server_name); - break; - } - } - - void DrawWidget(const Rect &r, int widget) const override - { - switch (widget) { - case WID_NL_DETAILS: - this->DrawDetails(r); - break; - - case WID_NL_MATRIX: - this->DrawMatrix(r); - break; - } - } - - void OnPaint() override - { - const NetworkGameInfo *gi = &this->server->info; - - /* Join button is disabled when no company is selected and for AI companies. */ - this->SetWidgetDisabledState(WID_NL_JOIN, this->company == INVALID_COMPANY || GetLobbyCompanyInfo(this->company)->ai); - /* Cannot start new company if there are too many. */ - this->SetWidgetDisabledState(WID_NL_NEW, gi->companies_on >= gi->companies_max); - - this->vscroll->SetCount(gi->companies_on); - - /* Draw window widgets */ - this->DrawWidgets(); - } - - void DrawMatrix(const Rect &r) const - { - bool rtl = _current_text_dir == TD_RTL; - uint left = r.left + WD_FRAMERECT_LEFT; - uint right = r.right - WD_FRAMERECT_RIGHT; - uint text_offset = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - FONT_HEIGHT_NORMAL) / 2 + WD_MATRIX_TOP; - - Dimension lock_size = GetSpriteSize(SPR_LOCK); - int lock_width = lock_size.width; - int lock_y_offset = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - lock_size.height) / 2 + WD_MATRIX_TOP; - - Dimension profit_size = GetSpriteSize(SPR_PROFIT_LOT); - int profit_width = lock_size.width; - int profit_y_offset = (this->resize.step_height - WD_MATRIX_TOP - WD_MATRIX_BOTTOM - profit_size.height) / 2 + WD_MATRIX_TOP; - - uint text_left = left + (rtl ? lock_width + profit_width + 4 : 0); - uint text_right = right - (rtl ? 0 : lock_width + profit_width + 4); - uint profit_left = rtl ? left : right - profit_width; - uint lock_left = rtl ? left + profit_width + 2 : right - profit_width - lock_width - 2; - - int y = r.top; - /* Draw company list */ - int pos = this->vscroll->GetPosition(); - while (pos < this->server->info.companies_on) { - byte company = NetworkLobbyFindCompanyIndex(pos); - bool income = false; - if (this->company == company) { - GfxFillRect(r.left + WD_BEVEL_LEFT, y + 1, r.right - WD_BEVEL_RIGHT, y + this->resize.step_height - 2, PC_GREY); // show highlighted item with a different colour - } - - DrawString(text_left, text_right, y + text_offset, this->company_info[company].company_name, TC_BLACK); - if (this->company_info[company].use_password != 0) DrawSprite(SPR_LOCK, PAL_NONE, lock_left, y + lock_y_offset); - - /* If the company's income was positive puts a green dot else a red dot */ - if (this->company_info[company].income >= 0) income = true; - DrawSprite(income ? SPR_PROFIT_LOT : SPR_PROFIT_NEGATIVE, PAL_NONE, profit_left, y + profit_y_offset); - - pos++; - y += this->resize.step_height; - if (pos >= this->vscroll->GetPosition() + this->vscroll->GetCapacity()) break; - } - } - - void DrawDetails(const Rect &r) const - { - const int detail_height = 12 + FONT_HEIGHT_NORMAL + 12; - /* Draw info about selected company when it is selected in the left window. */ - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 12, STR_NETWORK_GAME_LOBBY_COMPANY_INFO, TC_FROMSTRING, SA_HOR_CENTER); - - if (this->company == INVALID_COMPANY || this->company_info[this->company].company_name.empty()) return; - - int y = r.top + detail_height + 4; - const NetworkGameInfo *gi = &this->server->info; - - SetDParam(0, gi->clients_on); - SetDParam(1, gi->clients_max); - SetDParam(2, gi->companies_on); - SetDParam(3, gi->companies_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS); - y += FONT_HEIGHT_NORMAL; - - SetDParamStr(0, this->company_info[this->company].company_name); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_COMPANY_NAME); - y += FONT_HEIGHT_NORMAL; - - SetDParam(0, this->company_info[this->company].inaugurated_year); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_INAUGURATION_YEAR); // inauguration year - y += FONT_HEIGHT_NORMAL; - - SetDParam(0, this->company_info[this->company].company_value); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_VALUE); // company value - y += FONT_HEIGHT_NORMAL; - - SetDParam(0, this->company_info[this->company].money); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_CURRENT_BALANCE); // current balance - y += FONT_HEIGHT_NORMAL; - - SetDParam(0, this->company_info[this->company].income); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_LAST_YEARS_INCOME); // last year's income - y += FONT_HEIGHT_NORMAL; - - SetDParam(0, this->company_info[this->company].performance); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_PERFORMANCE); // performance - y += FONT_HEIGHT_NORMAL; - - SetDParam(0, this->company_info[this->company].num_vehicle[NETWORK_VEH_TRAIN]); - SetDParam(1, this->company_info[this->company].num_vehicle[NETWORK_VEH_LORRY]); - SetDParam(2, this->company_info[this->company].num_vehicle[NETWORK_VEH_BUS]); - SetDParam(3, this->company_info[this->company].num_vehicle[NETWORK_VEH_SHIP]); - SetDParam(4, this->company_info[this->company].num_vehicle[NETWORK_VEH_PLANE]); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_VEHICLES); // vehicles - y += FONT_HEIGHT_NORMAL; - - SetDParam(0, this->company_info[this->company].num_station[NETWORK_VEH_TRAIN]); - SetDParam(1, this->company_info[this->company].num_station[NETWORK_VEH_LORRY]); - SetDParam(2, this->company_info[this->company].num_station[NETWORK_VEH_BUS]); - SetDParam(3, this->company_info[this->company].num_station[NETWORK_VEH_SHIP]); - SetDParam(4, this->company_info[this->company].num_station[NETWORK_VEH_PLANE]); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_STATIONS); // stations - y += FONT_HEIGHT_NORMAL; - - SetDParamStr(0, this->company_info[this->company].clients); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_PLAYERS); // players - } - - void OnClick(Point pt, int widget, int click_count) override - { - switch (widget) { - case WID_NL_CANCEL: // Cancel button - ShowNetworkGameWindow(); - break; - - case WID_NL_MATRIX: { // Company list - uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NL_MATRIX); - this->company = (id_v >= this->server->info.companies_on) ? INVALID_COMPANY : NetworkLobbyFindCompanyIndex(id_v); - this->SetDirty(); - - /* FIXME the disabling should go into some InvalidateData, which is called instead of the SetDirty */ - if (click_count > 1 && !this->IsWidgetDisabled(WID_NL_JOIN)) this->OnClick(pt, WID_NL_JOIN, 1); - break; - } - - case WID_NL_JOIN: // Join company - /* Button can be clicked only when it is enabled. */ - NetworkClientConnectGame(this->server->connection_string, this->company); - break; - - case WID_NL_NEW: // New company - NetworkClientConnectGame(this->server->connection_string, COMPANY_NEW_COMPANY); - break; - - case WID_NL_SPECTATE: // Spectate game - NetworkClientConnectGame(this->server->connection_string, COMPANY_SPECTATOR); - break; - - case WID_NL_REFRESH: // Refresh - /* Clear the information so removed companies don't remain */ - for (auto &company : this->company_info) company = {}; - - NetworkQueryLobbyServer(this->server->connection_string); - break; - } - } - - void OnResize() override - { - this->vscroll->SetCapacityFromWidget(this, WID_NL_MATRIX); - } -}; - -static const NWidgetPart _nested_network_lobby_window_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE), - NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE), SetDataTip(STR_NETWORK_GAME_LOBBY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NL_BACKGROUND), - NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NL_TEXT), SetDataTip(STR_NETWORK_GAME_LOBBY_PREPARE_TO_JOIN, STR_NULL), SetResize(1, 0), SetPadding(10, 10, 0, 10), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), - NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10), - /* Company list. */ - NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_WHITE, WID_NL_HEADER), SetMinimalSize(146, 0), SetResize(1, 0), SetFill(1, 0), EndContainer(), - NWidget(WWT_MATRIX, COLOUR_LIGHT_BLUE, WID_NL_MATRIX), SetMinimalSize(146, 0), SetResize(1, 1), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_NETWORK_GAME_LOBBY_COMPANY_LIST_TOOLTIP), SetScrollbar(WID_NL_SCROLLBAR), - EndContainer(), - NWidget(NWID_VSCROLLBAR, COLOUR_LIGHT_BLUE, WID_NL_SCROLLBAR), - NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetResize(0, 1), - /* Company info. */ - NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NL_DETAILS), SetMinimalSize(232, 0), SetResize(1, 1), SetFill(1, 1), EndContainer(), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 9), - /* Buttons. */ - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 3, 10), - NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 3, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NL_JOIN), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_GAME_LOBBY_JOIN_COMPANY, STR_NETWORK_GAME_LOBBY_JOIN_COMPANY_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NL_NEW), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_GAME_LOBBY_NEW_COMPANY, STR_NETWORK_GAME_LOBBY_NEW_COMPANY_TOOLTIP), - EndContainer(), - NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 3, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NL_SPECTATE), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_GAME_LOBBY_SPECTATE_GAME, STR_NETWORK_GAME_LOBBY_SPECTATE_GAME_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NL_REFRESH), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_NETWORK_SERVER_LIST_REFRESH, STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP), - EndContainer(), - NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 3, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NL_CANCEL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_BUTTON_CANCEL, STR_NULL), - NWidget(NWID_SPACER), SetFill(1, 1), - EndContainer(), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 8), - EndContainer(), -}; - -static WindowDesc _network_lobby_window_desc( - WDP_CENTER, nullptr, 0, 0, - WC_NETWORK_WINDOW, WC_NONE, - 0, - _nested_network_lobby_window_widgets, lengthof(_nested_network_lobby_window_widgets) -); - -/** - * Show the networklobbywindow with the selected server. - * @param ngl Selected game pointer which is passed to the new window. - */ -static void ShowNetworkLobbyWindow(NetworkGameList *ngl) -{ - if (!NetworkValidateOurClientName()) return; - - CloseWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START); - CloseWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME); - - _settings_client.network.last_joined = ngl->connection_string; - - NetworkQueryLobbyServer(ngl->connection_string); - - new NetworkLobbyWindow(&_network_lobby_window_desc, ngl); -} - -/** - * Get the company information of a given company to fill for the lobby. - * @param company the company to get the company info struct from. - * @return the company info struct to write the (downloaded) data to. - */ -NetworkCompanyInfo *GetLobbyCompanyInfo(CompanyID company) -{ - NetworkLobbyWindow *lobby = dynamic_cast(FindWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY)); - return (lobby != nullptr && company < MAX_COMPANIES) ? &lobby->company_info[company] : nullptr; -} - -/** - * Get the game information for the lobby. - * @return the game info struct to write the (downloaded) data to. - */ -NetworkGameList *GetLobbyGameInfo() -{ - NetworkLobbyWindow *lobby = dynamic_cast(FindWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY)); - return lobby != nullptr ? lobby->server : nullptr; -} - /* The window below gives information about the connected clients * and also makes able to kick them (if server) and stuff like that. */