You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
738 lines
28 KiB
738 lines
28 KiB
|
3 years ago
|
#include "DiabloUI/multi/selgame.h"
|
||
|
7 years ago
|
|
||
|
5 years ago
|
#include <fmt/format.h>
|
||
|
|
|
||
|
7 years ago
|
#include "DiabloUI/diabloui.h"
|
||
|
7 years ago
|
#include "DiabloUI/dialogs.h"
|
||
|
3 years ago
|
#include "DiabloUI/hero/selhero.h"
|
||
|
4 years ago
|
#include "DiabloUI/scrollbar.h"
|
||
|
5 years ago
|
#include "DiabloUI/selok.h"
|
||
|
5 years ago
|
#include "config.h"
|
||
|
|
#include "control.h"
|
||
|
5 years ago
|
#include "menu.h"
|
||
|
5 years ago
|
#include "options.h"
|
||
|
4 years ago
|
#include "storm/storm_net.hpp"
|
||
|
5 years ago
|
#include "utils/language.h"
|
||
|
4 years ago
|
#include "utils/str_cat.hpp"
|
||
|
4 years ago
|
#include "utils/utf8.hpp"
|
||
|
7 years ago
|
|
||
|
5 years ago
|
namespace devilution {
|
||
|
7 years ago
|
|
||
|
7 years ago
|
char selgame_Label[32];
|
||
|
7 years ago
|
char selgame_Ip[129] = "";
|
||
|
|
char selgame_Password[16] = "";
|
||
|
4 years ago
|
char selgame_Description[512];
|
||
|
4 years ago
|
std::string selgame_Title;
|
||
|
7 years ago
|
bool selgame_enteringGame;
|
||
|
|
int selgame_selectedGame;
|
||
|
|
bool selgame_endMenu;
|
||
|
|
int *gdwPlayerId;
|
||
|
5 years ago
|
_difficulty nDifficulty;
|
||
|
5 years ago
|
int nTickRate;
|
||
|
6 years ago
|
int heroLevel;
|
||
|
7 years ago
|
|
||
|
5 years ago
|
static GameData *m_game_data;
|
||
|
7 years ago
|
extern int provider;
|
||
|
7 years ago
|
|
||
|
6 years ago
|
#define DESCRIPTION_WIDTH 205
|
||
|
7 years ago
|
|
||
|
6 years ago
|
namespace {
|
||
|
|
|
||
|
5 years ago
|
const char *title = "";
|
||
|
6 years ago
|
|
||
|
5 years ago
|
std::vector<std::unique_ptr<UiListItem>> vecSelGameDlgItems;
|
||
|
|
std::vector<std::unique_ptr<UiItemBase>> vecSelGameDialog;
|
||
|
4 years ago
|
std::vector<GameInfo> Gamelist;
|
||
|
4 years ago
|
uint32_t firstPublicGameInfoRequestSend = 0;
|
||
|
4 years ago
|
unsigned HighlightedItem;
|
||
|
4 years ago
|
|
||
|
6 years ago
|
void selgame_FreeVectors()
|
||
|
|
{
|
||
|
|
vecSelGameDlgItems.clear();
|
||
|
|
|
||
|
|
vecSelGameDialog.clear();
|
||
|
|
}
|
||
|
|
|
||
|
4 years ago
|
void selgame_Init()
|
||
|
|
{
|
||
|
4 years ago
|
LoadBackgroundArt("ui_art\\selgame");
|
||
|
4 years ago
|
LoadScrollBar();
|
||
|
|
}
|
||
|
|
|
||
|
7 years ago
|
void selgame_Free()
|
||
|
|
{
|
||
|
4 years ago
|
ArtBackground = std::nullopt;
|
||
|
4 years ago
|
UnloadScrollBar();
|
||
|
6 years ago
|
selgame_FreeVectors();
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
4 years ago
|
bool IsGameCompatible(const GameData &data)
|
||
|
|
{
|
||
|
|
return (data.versionMajor == PROJECT_VERSION_MAJOR
|
||
|
|
&& data.versionMinor == PROJECT_VERSION_MINOR
|
||
|
|
&& data.versionPatch == PROJECT_VERSION_PATCH
|
||
|
|
&& data.programid == GAME_ID);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
static std::string GetErrorMessageIncompatibility(const GameData &data)
|
||
|
|
{
|
||
|
|
if (data.programid != GAME_ID) {
|
||
|
4 years ago
|
string_view gameMode;
|
||
|
4 years ago
|
switch (data.programid) {
|
||
|
|
case GameIdDiabloFull:
|
||
|
|
gameMode = _("Diablo");
|
||
|
|
break;
|
||
|
|
case GameIdDiabloSpawn:
|
||
|
|
gameMode = _("Diablo Shareware");
|
||
|
|
break;
|
||
|
|
case GameIdHellfireFull:
|
||
|
|
gameMode = _("Hellfire");
|
||
|
|
break;
|
||
|
|
case GameIdHellfireSpawn:
|
||
|
|
gameMode = _("Hellfire Shareware");
|
||
|
|
break;
|
||
|
|
default:
|
||
|
4 years ago
|
return std::string(_("The host is running a different game than you."));
|
||
|
4 years ago
|
}
|
||
|
4 years ago
|
return fmt::format(fmt::runtime(_("The host is running a different game mode ({:s}) than you.")), gameMode);
|
||
|
4 years ago
|
} else {
|
||
|
4 years ago
|
return fmt::format(fmt::runtime(_(/* TRANSLATORS: Error message when somebody tries to join a game running another version. */ "Your version {:s} does not match the host {:d}.{:d}.{:d}.")), PROJECT_VERSION, data.versionMajor, data.versionMinor, data.versionPatch);
|
||
|
4 years ago
|
}
|
||
|
|
}
|
||
|
|
|
||
|
4 years ago
|
void UiInitGameSelectionList(string_view search)
|
||
|
7 years ago
|
{
|
||
|
|
selgame_enteringGame = false;
|
||
|
|
selgame_selectedGame = 0;
|
||
|
|
|
||
|
7 years ago
|
if (provider == SELCONN_LOOPBACK) {
|
||
|
7 years ago
|
selgame_enteringGame = true;
|
||
|
|
selgame_GameSelection_Select(0);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
4 years ago
|
if (provider == SELCONN_ZT) {
|
||
|
|
CopyUtf8(selgame_Ip, sgOptions.Network.szPreviousZTGame, sizeof(selgame_Ip));
|
||
|
|
} else {
|
||
|
|
CopyUtf8(selgame_Ip, sgOptions.Network.szPreviousHost, sizeof(selgame_Ip));
|
||
|
|
}
|
||
|
6 years ago
|
|
||
|
|
selgame_FreeVectors();
|
||
|
|
|
||
|
|
UiAddBackground(&vecSelGameDialog);
|
||
|
|
UiAddLogo(&vecSelGameDialog);
|
||
|
|
|
||
|
4 years ago
|
const Point uiPosition = GetUIRectangle().position;
|
||
|
|
|
||
|
|
SDL_Rect rectScrollbar = { (Sint16)(uiPosition.x + 590), (Sint16)(uiPosition.y + 244), 25, 178 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiScrollbar>((*ArtScrollBarBackground)[0], (*ArtScrollBarThumb)[0], *ArtScrollBarArrow, rectScrollbar));
|
||
|
4 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect1 = { (Sint16)(uiPosition.x + 24), (Sint16)(uiPosition.y + 161), 590, 35 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_(ConnectionNames[provider]).data(), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect2 = { (Sint16)(uiPosition.x + 35), (Sint16)(uiPosition.y + 211), 205, 192 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Description:").data(), rect2, UiFlags::FontSize24 | UiFlags::ColorUiSilver));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect3 = { (Sint16)(uiPosition.x + 35), (Sint16)(uiPosition.y + 256), DESCRIPTION_WIDTH, 192 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Description, rect3, UiFlags::FontSize12 | UiFlags::ColorUiSilverDark, 1, 16));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect4 = { (Sint16)(uiPosition.x + 300), (Sint16)(uiPosition.y + 211), 295, 33 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Select Action").data(), rect4, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
#ifdef PACKET_ENCRYPTION
|
||
|
4 years ago
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Create Game"), 0, UiFlags::ColorUiGold));
|
||
|
4 years ago
|
#endif
|
||
|
4 years ago
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Create Public Game"), 1, UiFlags::ColorUiGold));
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Join Game"), 2, UiFlags::ColorUiGold));
|
||
|
|
|
||
|
4 years ago
|
if (provider == SELCONN_ZT) {
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>("", -1, UiFlags::ElementDisabled));
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Public Games"), -1, UiFlags::ElementDisabled | UiFlags::ColorWhitegold));
|
||
|
|
|
||
|
|
if (Gamelist.empty()) {
|
||
|
|
// We expect the game list to be received after 3 seconds
|
||
|
|
if (firstPublicGameInfoRequestSend == 0 || (SDL_GetTicks() - firstPublicGameInfoRequestSend) < 2000)
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Loading..."), -1, UiFlags::ElementDisabled | UiFlags::ColorUiSilver));
|
||
|
|
else
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("None"), -1, UiFlags::ElementDisabled | UiFlags::ColorUiSilver));
|
||
|
|
} else {
|
||
|
|
for (unsigned i = 0; i < Gamelist.size(); i++) {
|
||
|
4 years ago
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(Gamelist[i].name, i + 3, UiFlags::ColorUiGold));
|
||
|
4 years ago
|
}
|
||
|
4 years ago
|
}
|
||
|
4 years ago
|
}
|
||
|
|
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiList>(vecSelGameDlgItems, 6, uiPosition.x + 305, (uiPosition.y + 255), 285, 26, UiFlags::AlignCenter | UiFlags::FontSize24));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect5 = { (Sint16)(uiPosition.x + 299), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("OK"), &UiFocusNavigationSelect, rect5, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect6 = { (Sint16)(uiPosition.x + 449), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("CANCEL"), &UiFocusNavigationEsc, rect6, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
auto selectFn = [](int index) {
|
||
|
|
// UiListItem::m_value could be different from
|
||
|
|
// the index if packet encryption is disabled
|
||
|
|
int itemValue = vecSelGameDlgItems[index]->m_value;
|
||
|
|
selgame_GameSelection_Select(itemValue);
|
||
|
|
};
|
||
|
4 years ago
|
|
||
|
4 years ago
|
if (!search.empty()) {
|
||
|
4 years ago
|
for (unsigned i = 0; i < vecSelGameDlgItems.size(); i++) {
|
||
|
|
int gameIndex = vecSelGameDlgItems[i]->m_value - 3;
|
||
|
|
if (gameIndex < 0)
|
||
|
|
continue;
|
||
|
|
if (search == Gamelist[gameIndex].name)
|
||
|
|
HighlightedItem = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (HighlightedItem >= vecSelGameDlgItems.size()) {
|
||
|
|
HighlightedItem = vecSelGameDlgItems.size() - 1;
|
||
|
|
}
|
||
|
|
|
||
|
4 years ago
|
UiInitList(selgame_GameSelection_Focus, selectFn, selgame_GameSelection_Esc, vecSelGameDialog, true, nullptr, nullptr, HighlightedItem);
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
4 years ago
|
} // namespace
|
||
|
|
|
||
|
|
void selgame_GameSelection_Init()
|
||
|
|
{
|
||
|
|
UiInitGameSelectionList("");
|
||
|
|
}
|
||
|
|
|
||
|
7 years ago
|
void selgame_GameSelection_Focus(int value)
|
||
|
|
{
|
||
|
4 years ago
|
const auto index = static_cast<unsigned>(value);
|
||
|
|
HighlightedItem = index;
|
||
|
|
const UiListItem &item = *vecSelGameDlgItems[index];
|
||
|
|
switch (item.m_value) {
|
||
|
7 years ago
|
case 0:
|
||
|
4 years ago
|
CopyUtf8(selgame_Description, _("Create a new game with a difficulty setting of your choice."), sizeof(selgame_Description));
|
||
|
7 years ago
|
break;
|
||
|
|
case 1:
|
||
|
4 years ago
|
CopyUtf8(selgame_Description, _("Create a new public game that anyone can join with a difficulty setting of your choice."), sizeof(selgame_Description));
|
||
|
4 years ago
|
break;
|
||
|
|
case 2:
|
||
|
4 years ago
|
if (provider == SELCONN_ZT) {
|
||
|
4 years ago
|
CopyUtf8(selgame_Description, _("Enter Game ID to join a game already in progress."), sizeof(selgame_Description));
|
||
|
4 years ago
|
} else {
|
||
|
|
CopyUtf8(selgame_Description, _("Enter an IP or a hostname to join a game already in progress."), sizeof(selgame_Description));
|
||
|
|
}
|
||
|
7 years ago
|
break;
|
||
|
4 years ago
|
default:
|
||
|
4 years ago
|
const GameInfo &gameInfo = Gamelist[item.m_value - 3];
|
||
|
4 years ago
|
std::string infoString = std::string(_("Join the public game already in progress."));
|
||
|
4 years ago
|
infoString.append("\n\n");
|
||
|
|
if (IsGameCompatible(gameInfo.gameData)) {
|
||
|
|
string_view difficulty;
|
||
|
|
switch (gameInfo.gameData.nDifficulty) {
|
||
|
|
case DIFF_NORMAL:
|
||
|
|
difficulty = _("Normal");
|
||
|
|
break;
|
||
|
|
case DIFF_NIGHTMARE:
|
||
|
|
difficulty = _("Nightmare");
|
||
|
|
break;
|
||
|
|
case DIFF_HELL:
|
||
|
|
difficulty = _("Hell");
|
||
|
|
break;
|
||
|
|
}
|
||
|
4 years ago
|
infoString.append(fmt::format(fmt::runtime(_(/* TRANSLATORS: {:s} means: Game Difficulty. */ "Difficulty: {:s}")), difficulty));
|
||
|
4 years ago
|
infoString += '\n';
|
||
|
4 years ago
|
switch (gameInfo.gameData.nTickRate) {
|
||
|
|
case 20:
|
||
|
4 years ago
|
AppendStrView(infoString, _("Speed: Normal"));
|
||
|
4 years ago
|
break;
|
||
|
|
case 30:
|
||
|
4 years ago
|
AppendStrView(infoString, _("Speed: Fast"));
|
||
|
4 years ago
|
break;
|
||
|
|
case 40:
|
||
|
4 years ago
|
AppendStrView(infoString, _("Speed: Faster"));
|
||
|
4 years ago
|
break;
|
||
|
|
case 50:
|
||
|
4 years ago
|
AppendStrView(infoString, _("Speed: Fastest"));
|
||
|
4 years ago
|
break;
|
||
|
|
default:
|
||
|
|
// This should not occure, so no translations is needed
|
||
|
4 years ago
|
infoString.append(StrCat("Speed: ", gameInfo.gameData.nTickRate));
|
||
|
4 years ago
|
break;
|
||
|
|
}
|
||
|
4 years ago
|
infoString += '\n';
|
||
|
4 years ago
|
AppendStrView(infoString, _("Players: "));
|
||
|
4 years ago
|
for (auto &playerName : gameInfo.players) {
|
||
|
|
infoString.append(playerName);
|
||
|
4 years ago
|
infoString += ' ';
|
||
|
4 years ago
|
}
|
||
|
|
} else {
|
||
|
|
infoString.append(GetErrorMessageIncompatibility(gameInfo.gameData));
|
||
|
|
}
|
||
|
|
CopyUtf8(selgame_Description, infoString, sizeof(selgame_Description));
|
||
|
4 years ago
|
break;
|
||
|
7 years ago
|
}
|
||
|
4 years ago
|
CopyUtf8(selgame_Description, WordWrapString(selgame_Description, DESCRIPTION_WIDTH), sizeof(selgame_Description));
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
6 years ago
|
/**
|
||
|
|
* @brief Load the current hero level from save file
|
||
|
|
* @param pInfo Hero info
|
||
|
|
* @return always true
|
||
|
|
*/
|
||
|
5 years ago
|
bool UpdateHeroLevel(_uiheroinfo *pInfo)
|
||
|
6 years ago
|
{
|
||
|
5 years ago
|
if (pInfo->saveNumber == gSaveNumber)
|
||
|
6 years ago
|
heroLevel = pInfo->level;
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
7 years ago
|
void selgame_GameSelection_Select(int value)
|
||
|
|
{
|
||
|
|
selgame_enteringGame = true;
|
||
|
|
selgame_selectedGame = value;
|
||
|
|
|
||
|
4 years ago
|
gfnHeroInfo(UpdateHeroLevel);
|
||
|
|
|
||
|
|
selgame_FreeVectors();
|
||
|
|
|
||
|
4 years ago
|
if (value > 2) {
|
||
|
4 years ago
|
CopyUtf8(selgame_Ip, Gamelist[value - 3].name, sizeof(selgame_Ip));
|
||
|
4 years ago
|
selgame_Password_Select(value);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
6 years ago
|
UiAddBackground(&vecSelGameDialog);
|
||
|
|
UiAddLogo(&vecSelGameDialog);
|
||
|
|
|
||
|
4 years ago
|
const Point uiPosition = GetUIRectangle().position;
|
||
|
|
|
||
|
|
SDL_Rect rect1 = { (Sint16)(uiPosition.x + 24), (Sint16)(uiPosition.y + 161), 590, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(&title, rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect2 = { (Sint16)(uiPosition.x + 34), (Sint16)(uiPosition.y + 211), 205, 33 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Label, rect2, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect3 = { (Sint16)(uiPosition.x + 35), (Sint16)(uiPosition.y + 256), DESCRIPTION_WIDTH, 192 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Description, rect3, UiFlags::FontSize12 | UiFlags::ColorUiSilverDark, 1, 16));
|
||
|
6 years ago
|
|
||
|
7 years ago
|
switch (value) {
|
||
|
4 years ago
|
case 0:
|
||
|
|
case 1: {
|
||
|
4 years ago
|
title = _("Create Game").data();
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect4 = { (Sint16)(uiPosition.x + 299), (Sint16)(uiPosition.y + 211), 295, 35 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Select Difficulty").data(), rect4, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
5 years ago
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Normal"), DIFF_NORMAL));
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Nightmare"), DIFF_NIGHTMARE));
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Hell"), DIFF_HELL));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiList>(vecSelGameDlgItems, vecSelGameDlgItems.size(), uiPosition.x + 300, (uiPosition.y + 282), 295, 26, UiFlags::AlignCenter | UiFlags::FontSize24 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect5 = { (Sint16)(uiPosition.x + 299), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("OK"), &UiFocusNavigationSelect, rect5, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect6 = { (Sint16)(uiPosition.x + 449), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("CANCEL"), &UiFocusNavigationEsc, rect6, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
UiInitList(selgame_Diff_Focus, selgame_Diff_Select, selgame_Diff_Esc, vecSelGameDialog, true);
|
||
|
7 years ago
|
break;
|
||
|
6 years ago
|
}
|
||
|
4 years ago
|
case 2: {
|
||
|
4 years ago
|
selgame_Title = fmt::format(fmt::runtime(_("Join {:s} Games")), _(ConnectionNames[provider]));
|
||
|
4 years ago
|
title = selgame_Title.c_str();
|
||
|
|
|
||
|
|
const char *inputHint;
|
||
|
|
if (provider == SELCONN_ZT) {
|
||
|
4 years ago
|
inputHint = _("Enter Game ID").data();
|
||
|
4 years ago
|
} else {
|
||
|
4 years ago
|
inputHint = _("Enter address").data();
|
||
|
4 years ago
|
}
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect4 = { (Sint16)(uiPosition.x + 305), (Sint16)(uiPosition.y + 211), 285, 33 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(inputHint, rect4, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect5 = { (Sint16)(uiPosition.x + 305), (Sint16)(uiPosition.y + 314), 285, 33 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiEdit>(inputHint, selgame_Ip, 128, false, rect5, UiFlags::FontSize24 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect6 = { (Sint16)(uiPosition.x + 299), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("OK"), &UiFocusNavigationSelect, rect6, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect7 = { (Sint16)(uiPosition.x + 449), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("CANCEL"), &UiFocusNavigationEsc, rect7, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
HighlightedItem = 0;
|
||
|
4 years ago
|
|
||
|
|
#ifdef PACKET_ENCRYPTION
|
||
|
4 years ago
|
UiInitList(nullptr, selgame_Password_Init, selgame_GameSelection_Init, vecSelGameDialog);
|
||
|
4 years ago
|
#else
|
||
|
4 years ago
|
UiInitList(nullptr, selgame_Password_Select, selgame_GameSelection_Init, vecSelGameDialog);
|
||
|
4 years ago
|
#endif
|
||
|
7 years ago
|
break;
|
||
|
|
}
|
||
|
6 years ago
|
}
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
|
void selgame_GameSelection_Esc()
|
||
|
|
{
|
||
|
6 years ago
|
UiInitList_clear();
|
||
|
7 years ago
|
selgame_enteringGame = false;
|
||
|
|
selgame_endMenu = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void selgame_Diff_Focus(int value)
|
||
|
|
{
|
||
|
6 years ago
|
switch (vecSelGameDlgItems[value]->m_value) {
|
||
|
7 years ago
|
case DIFF_NORMAL:
|
||
|
4 years ago
|
CopyUtf8(selgame_Label, _("Normal"), sizeof(selgame_Label));
|
||
|
|
CopyUtf8(selgame_Description, _("Normal Difficulty\nThis is where a starting character should begin the quest to defeat Diablo."), sizeof(selgame_Description));
|
||
|
7 years ago
|
break;
|
||
|
|
case DIFF_NIGHTMARE:
|
||
|
4 years ago
|
CopyUtf8(selgame_Label, _("Nightmare"), sizeof(selgame_Label));
|
||
|
|
CopyUtf8(selgame_Description, _("Nightmare Difficulty\nThe denizens of the Labyrinth have been bolstered and will prove to be a greater challenge. This is recommended for experienced characters only."), sizeof(selgame_Description));
|
||
|
7 years ago
|
break;
|
||
|
|
case DIFF_HELL:
|
||
|
4 years ago
|
CopyUtf8(selgame_Label, _("Hell"), sizeof(selgame_Label));
|
||
|
|
CopyUtf8(selgame_Description, _("Hell Difficulty\nThe most powerful of the underworld's creatures lurk at the gateway into Hell. Only the most experienced characters should venture in this realm."), sizeof(selgame_Description));
|
||
|
7 years ago
|
break;
|
||
|
|
}
|
||
|
4 years ago
|
CopyUtf8(selgame_Description, WordWrapString(selgame_Description, DESCRIPTION_WIDTH), sizeof(selgame_Description));
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
6 years ago
|
bool IsDifficultyAllowed(int value)
|
||
|
|
{
|
||
|
6 years ago
|
if (value == 0 || (value == 1 && heroLevel >= 20) || (value == 2 && heroLevel >= 30)) {
|
||
|
6 years ago
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
selgame_Free();
|
||
|
|
|
||
|
|
if (value == 1)
|
||
|
4 years ago
|
UiSelOkDialog(title, _("Your character must reach level 20 before you can enter a multiplayer game of Nightmare difficulty.").data(), false);
|
||
|
6 years ago
|
if (value == 2)
|
||
|
4 years ago
|
UiSelOkDialog(title, _("Your character must reach level 30 before you can enter a multiplayer game of Hell difficulty.").data(), false);
|
||
|
6 years ago
|
|
||
|
4 years ago
|
selgame_Init();
|
||
|
6 years ago
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
7 years ago
|
void selgame_Diff_Select(int value)
|
||
|
|
{
|
||
|
6 years ago
|
if (selhero_isMultiPlayer && !IsDifficultyAllowed(vecSelGameDlgItems[value]->m_value)) {
|
||
|
6 years ago
|
selgame_GameSelection_Select(0);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
5 years ago
|
nDifficulty = (_difficulty)vecSelGameDlgItems[value]->m_value;
|
||
|
7 years ago
|
|
||
|
6 years ago
|
if (!selhero_isMultiPlayer) {
|
||
|
5 years ago
|
// This is part of a dangerous hack to enable difficulty selection in single-player.
|
||
|
|
// FIXME: Dialogs should not refer to each other's variables.
|
||
|
|
|
||
|
|
// We're in the selhero loop instead of the selgame one.
|
||
|
|
// Free the selgame data and flag the end of the selhero loop.
|
||
|
6 years ago
|
selhero_endMenu = true;
|
||
|
5 years ago
|
|
||
|
|
// We only call FreeVectors because ArtBackground.Unload()
|
||
|
|
// will be called by selheroFree().
|
||
|
|
selgame_FreeVectors();
|
||
|
|
|
||
|
|
// We must clear the InitList because selhero's loop will perform
|
||
|
|
// one more iteration after this function exits.
|
||
|
|
UiInitList_clear();
|
||
|
|
|
||
|
6 years ago
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
6 years ago
|
selgame_GameSpeedSelection();
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
|
void selgame_Diff_Esc()
|
||
|
|
{
|
||
|
6 years ago
|
if (!selhero_isMultiPlayer) {
|
||
|
|
selgame_Free();
|
||
|
|
|
||
|
|
selhero_Init();
|
||
|
|
selhero_List_Init();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
7 years ago
|
if (provider == SELCONN_LOOPBACK) {
|
||
|
7 years ago
|
selgame_GameSelection_Esc();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
4 years ago
|
HighlightedItem = 0;
|
||
|
7 years ago
|
selgame_GameSelection_Init();
|
||
|
|
}
|
||
|
|
|
||
|
6 years ago
|
void selgame_GameSpeedSelection()
|
||
|
|
{
|
||
|
|
gfnHeroInfo(UpdateHeroLevel);
|
||
|
|
|
||
|
|
selgame_FreeVectors();
|
||
|
|
|
||
|
|
UiAddBackground(&vecSelGameDialog);
|
||
|
|
UiAddLogo(&vecSelGameDialog);
|
||
|
|
|
||
|
4 years ago
|
const Point uiPosition = GetUIRectangle().position;
|
||
|
|
|
||
|
|
SDL_Rect rect1 = { (Sint16)(uiPosition.x + 24), (Sint16)(uiPosition.y + 161), 590, 35 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Create Game").data(), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect2 = { (Sint16)(uiPosition.x + 34), (Sint16)(uiPosition.y + 211), 205, 33 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Label, rect2, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect3 = { (Sint16)(uiPosition.x + 35), (Sint16)(uiPosition.y + 256), DESCRIPTION_WIDTH, 192 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Description, rect3, UiFlags::FontSize12 | UiFlags::ColorUiSilverDark, 1, 16));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect4 = { (Sint16)(uiPosition.x + 299), (Sint16)(uiPosition.y + 211), 295, 35 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Select Game Speed").data(), rect4, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
5 years ago
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Normal"), 20));
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Fast"), 30));
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Faster"), 40));
|
||
|
|
vecSelGameDlgItems.push_back(std::make_unique<UiListItem>(_("Fastest"), 50));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiList>(vecSelGameDlgItems, vecSelGameDlgItems.size(), uiPosition.x + 300, (uiPosition.y + 279), 295, 26, UiFlags::AlignCenter | UiFlags::FontSize24 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect5 = { (Sint16)(uiPosition.x + 299), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("OK"), &UiFocusNavigationSelect, rect5, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect6 = { (Sint16)(uiPosition.x + 449), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("CANCEL"), &UiFocusNavigationEsc, rect6, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
UiInitList(selgame_Speed_Focus, selgame_Speed_Select, selgame_Speed_Esc, vecSelGameDialog, true);
|
||
|
6 years ago
|
}
|
||
|
|
|
||
|
|
void selgame_Speed_Focus(int value)
|
||
|
|
{
|
||
|
6 years ago
|
switch (vecSelGameDlgItems[value]->m_value) {
|
||
|
|
case 20:
|
||
|
4 years ago
|
CopyUtf8(selgame_Label, _("Normal"), sizeof(selgame_Label));
|
||
|
|
CopyUtf8(selgame_Description, _("Normal Speed\nThis is where a starting character should begin the quest to defeat Diablo."), sizeof(selgame_Description));
|
||
|
6 years ago
|
break;
|
||
|
6 years ago
|
case 30:
|
||
|
4 years ago
|
CopyUtf8(selgame_Label, _("Fast"), sizeof(selgame_Label));
|
||
|
|
CopyUtf8(selgame_Description, _("Fast Speed\nThe denizens of the Labyrinth have been hastened and will prove to be a greater challenge. This is recommended for experienced characters only."), sizeof(selgame_Description));
|
||
|
6 years ago
|
break;
|
||
|
6 years ago
|
case 40:
|
||
|
4 years ago
|
CopyUtf8(selgame_Label, _("Faster"), sizeof(selgame_Label));
|
||
|
|
CopyUtf8(selgame_Description, _("Faster Speed\nMost monsters of the dungeon will seek you out quicker than ever before. Only an experienced champion should try their luck at this speed."), sizeof(selgame_Description));
|
||
|
6 years ago
|
break;
|
||
|
6 years ago
|
case 50:
|
||
|
4 years ago
|
CopyUtf8(selgame_Label, _("Fastest"), sizeof(selgame_Label));
|
||
|
|
CopyUtf8(selgame_Description, _("Fastest Speed\nThe minions of the underworld will rush to attack without hesitation. Only a true speed demon should enter at this pace."), sizeof(selgame_Description));
|
||
|
6 years ago
|
break;
|
||
|
|
}
|
||
|
4 years ago
|
CopyUtf8(selgame_Description, WordWrapString(selgame_Description, DESCRIPTION_WIDTH), sizeof(selgame_Description));
|
||
|
6 years ago
|
}
|
||
|
|
|
||
|
|
void selgame_Speed_Esc()
|
||
|
|
{
|
||
|
|
selgame_GameSelection_Select(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
void selgame_Speed_Select(int value)
|
||
|
|
{
|
||
|
5 years ago
|
nTickRate = vecSelGameDlgItems[value]->m_value;
|
||
|
6 years ago
|
|
||
|
4 years ago
|
if (provider == SELCONN_LOOPBACK || selgame_selectedGame == 1) {
|
||
|
6 years ago
|
selgame_Password_Select(0);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
selgame_Password_Init(0);
|
||
|
|
}
|
||
|
|
|
||
|
5 years ago
|
void selgame_Password_Init(int /*value*/)
|
||
|
7 years ago
|
{
|
||
|
|
memset(&selgame_Password, 0, sizeof(selgame_Password));
|
||
|
6 years ago
|
|
||
|
|
selgame_FreeVectors();
|
||
|
|
|
||
|
|
UiAddBackground(&vecSelGameDialog);
|
||
|
|
UiAddLogo(&vecSelGameDialog);
|
||
|
|
|
||
|
4 years ago
|
const Point uiPosition = GetUIRectangle().position;
|
||
|
|
|
||
|
|
SDL_Rect rect1 = { (Sint16)(uiPosition.x + 24), (Sint16)(uiPosition.y + 161), 590, 35 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_(ConnectionNames[provider]).data(), rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect2 = { (Sint16)(uiPosition.x + 35), (Sint16)(uiPosition.y + 211), 205, 192 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Description:").data(), rect2, UiFlags::FontSize24 | UiFlags::ColorUiSilver));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect3 = { (Sint16)(uiPosition.x + 35), (Sint16)(uiPosition.y + 256), DESCRIPTION_WIDTH, 192 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Description, rect3, UiFlags::FontSize12 | UiFlags::ColorUiSilverDark, 1, 16));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect4 = { (Sint16)(uiPosition.x + 305), (Sint16)(uiPosition.y + 211), 285, 33 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtText>(_("Enter Password").data(), rect4, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
// Allow password to be empty only when joining games
|
||
|
|
bool allowEmpty = selgame_selectedGame == 2;
|
||
|
4 years ago
|
SDL_Rect rect5 = { (Sint16)(uiPosition.x + 305), (Sint16)(uiPosition.y + 314), 285, 33 };
|
||
|
4 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiEdit>(_("Enter Password"), selgame_Password, 15, allowEmpty, rect5, UiFlags::FontSize24 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect6 = { (Sint16)(uiPosition.x + 299), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("OK"), &UiFocusNavigationSelect, rect6, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
SDL_Rect rect7 = { (Sint16)(uiPosition.x + 449), (Sint16)(uiPosition.y + 427), 140, 35 };
|
||
|
5 years ago
|
vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>(_("CANCEL"), &UiFocusNavigationEsc, rect7, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
|
||
|
6 years ago
|
|
||
|
4 years ago
|
UiInitList(nullptr, selgame_Password_Select, selgame_Password_Esc, vecSelGameDialog);
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
4 years ago
|
static bool IsGameCompatibleWithErrorMessage(const GameData &data)
|
||
|
5 years ago
|
{
|
||
|
4 years ago
|
if (IsGameCompatible(data))
|
||
|
4 years ago
|
return IsDifficultyAllowed(data.nDifficulty);
|
||
|
5 years ago
|
|
||
|
|
selgame_Free();
|
||
|
|
|
||
|
4 years ago
|
std::string errorMessage = GetErrorMessageIncompatibility(data);
|
||
|
|
UiSelOkDialog(title, errorMessage.c_str(), false);
|
||
|
5 years ago
|
|
||
|
4 years ago
|
selgame_Init();
|
||
|
5 years ago
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
5 years ago
|
void selgame_Password_Select(int /*value*/)
|
||
|
7 years ago
|
{
|
||
|
4 years ago
|
char *gamePassword = nullptr;
|
||
|
|
if (selgame_selectedGame == 0)
|
||
|
|
gamePassword = selgame_Password;
|
||
|
|
if (selgame_selectedGame == 2 && strlen(selgame_Password) > 0)
|
||
|
|
gamePassword = selgame_Password;
|
||
|
|
|
||
|
4 years ago
|
// If there is an error, the error message won't necessarily be set.
|
||
|
|
// Clear the error so that we display "Unknown network error"
|
||
|
|
// instead of an arbitrary message in that case.
|
||
|
|
SDL_ClearError();
|
||
|
|
|
||
|
4 years ago
|
if (selgame_selectedGame > 1) {
|
||
|
3 years ago
|
bool allowJoin = true;
|
||
|
|
if (selgame_selectedGame > 2)
|
||
|
|
allowJoin = IsGameCompatible(Gamelist[selgame_selectedGame - 3].gameData);
|
||
|
4 years ago
|
if (provider == SELCONN_ZT) {
|
||
|
4 years ago
|
for (unsigned int i = 0; i < (sizeof(selgame_Ip) / sizeof(selgame_Ip[0])); i++) {
|
||
|
|
selgame_Ip[i] = (selgame_Ip[i] >= 'A' && selgame_Ip[i] <= 'Z') ? selgame_Ip[i] + 'a' - 'A' : selgame_Ip[i];
|
||
|
|
}
|
||
|
4 years ago
|
strcpy(sgOptions.Network.szPreviousZTGame, selgame_Ip);
|
||
|
|
} else {
|
||
|
|
strcpy(sgOptions.Network.szPreviousHost, selgame_Ip);
|
||
|
|
}
|
||
|
3 years ago
|
if (allowJoin && SNetJoinGame(selgame_Ip, gamePassword, gdwPlayerId)) {
|
||
|
4 years ago
|
if (!IsGameCompatibleWithErrorMessage(*m_game_data)) {
|
||
|
4 years ago
|
InitGameInfo();
|
||
|
6 years ago
|
selgame_GameSelection_Select(1);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
6 years ago
|
UiInitList_clear();
|
||
|
7 years ago
|
selgame_endMenu = true;
|
||
|
|
} else {
|
||
|
4 years ago
|
InitGameInfo();
|
||
|
6 years ago
|
selgame_Free();
|
||
|
3 years ago
|
std::string error;
|
||
|
|
if (!allowJoin)
|
||
|
|
error = GetErrorMessageIncompatibility(Gamelist[selgame_selectedGame - 3].gameData);
|
||
|
|
else
|
||
|
|
error = SDL_GetError();
|
||
|
4 years ago
|
if (error.empty())
|
||
|
|
error = "Unknown network error";
|
||
|
4 years ago
|
UiSelOkDialog(_("Multi Player Game").data(), error.c_str(), false);
|
||
|
4 years ago
|
selgame_Init();
|
||
|
3 years ago
|
if (selgame_selectedGame == 2)
|
||
|
|
selgame_Password_Init(selgame_selectedGame);
|
||
|
|
else
|
||
|
|
UiInitGameSelectionList("");
|
||
|
7 years ago
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
5 years ago
|
m_game_data->nDifficulty = nDifficulty;
|
||
|
|
m_game_data->nTickRate = nTickRate;
|
||
|
4 years ago
|
m_game_data->bRunInTown = *sgOptions.Gameplay.runInTown ? 1 : 0;
|
||
|
4 years ago
|
m_game_data->bTheoQuest = *sgOptions.Gameplay.theoQuest ? 1 : 0;
|
||
|
4 years ago
|
m_game_data->bCowQuest = *sgOptions.Gameplay.cowQuest ? 1 : 0;
|
||
|
7 years ago
|
|
||
|
4 years ago
|
if (SNetCreateGame(nullptr, gamePassword, (char *)m_game_data, sizeof(*m_game_data), gdwPlayerId)) {
|
||
|
6 years ago
|
UiInitList_clear();
|
||
|
7 years ago
|
selgame_endMenu = true;
|
||
|
|
} else {
|
||
|
6 years ago
|
selgame_Free();
|
||
|
4 years ago
|
std::string error = SDL_GetError();
|
||
|
|
if (error.empty())
|
||
|
|
error = "Unknown network error";
|
||
|
4 years ago
|
UiSelOkDialog(_("Multi Player Game").data(), error.c_str(), false);
|
||
|
4 years ago
|
selgame_Init();
|
||
|
7 years ago
|
selgame_Password_Init(0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void selgame_Password_Esc()
|
||
|
|
{
|
||
|
4 years ago
|
if (selgame_selectedGame == 2)
|
||
|
|
selgame_GameSelection_Select(2);
|
||
|
6 years ago
|
else
|
||
|
|
selgame_GameSpeedSelection();
|
||
|
7 years ago
|
}
|
||
|
|
|
||
|
4 years ago
|
void RefreshGameList()
|
||
|
|
{
|
||
|
|
static uint32_t lastRequest = 0;
|
||
|
|
static uint32_t lastUpdate = 0;
|
||
|
|
|
||
|
|
if (selgame_enteringGame)
|
||
|
|
return;
|
||
|
|
|
||
|
|
uint32_t currentTime = SDL_GetTicks();
|
||
|
|
|
||
|
4 years ago
|
if ((lastRequest == 0 || currentTime - lastRequest > 30000) && DvlNet_SendInfoRequest()) {
|
||
|
4 years ago
|
lastRequest = currentTime;
|
||
|
|
lastUpdate = currentTime - 3000; // Give 2 sec for responses, but don't wait 5
|
||
|
4 years ago
|
if (firstPublicGameInfoRequestSend == 0)
|
||
|
|
firstPublicGameInfoRequestSend = currentTime;
|
||
|
4 years ago
|
}
|
||
|
|
|
||
|
|
if (lastUpdate == 0 || currentTime - lastUpdate > 5000) {
|
||
|
4 years ago
|
int gameIndex = vecSelGameDlgItems[HighlightedItem]->m_value - 3;
|
||
|
|
std::string gameSearch = gameIndex >= 0 ? Gamelist[gameIndex].name : "";
|
||
|
4 years ago
|
std::vector<GameInfo> gamelist = DvlNet_GetGamelist();
|
||
|
4 years ago
|
Gamelist.clear();
|
||
|
|
for (unsigned i = 0; i < gamelist.size(); i++) {
|
||
|
|
Gamelist.push_back(gamelist[i]);
|
||
|
|
}
|
||
|
4 years ago
|
UiInitGameSelectionList(gameSearch);
|
||
|
4 years ago
|
lastUpdate = currentTime;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
5 years ago
|
bool UiSelectGame(GameData *gameData, int *playerId)
|
||
|
7 years ago
|
{
|
||
|
4 years ago
|
firstPublicGameInfoRequestSend = 0;
|
||
|
7 years ago
|
gdwPlayerId = playerId;
|
||
|
5 years ago
|
m_game_data = gameData;
|
||
|
4 years ago
|
selgame_Init();
|
||
|
4 years ago
|
HighlightedItem = 0;
|
||
|
7 years ago
|
selgame_GameSelection_Init();
|
||
|
|
|
||
|
|
selgame_endMenu = false;
|
||
|
4 years ago
|
|
||
|
4 years ago
|
DvlNet_ClearPassword();
|
||
|
4 years ago
|
DvlNet_ClearGamelist();
|
||
|
|
|
||
|
7 years ago
|
while (!selgame_endMenu) {
|
||
|
6 years ago
|
UiClearScreen();
|
||
|
7 years ago
|
UiPollAndRender();
|
||
|
4 years ago
|
if (provider == SELCONN_ZT)
|
||
|
|
RefreshGameList();
|
||
|
7 years ago
|
}
|
||
|
|
selgame_Free();
|
||
|
|
|
||
|
|
return selgame_enteringGame;
|
||
|
|
}
|
||
|
5 years ago
|
} // namespace devilution
|