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.
222 lines
5.9 KiB
222 lines
5.9 KiB
|
3 years ago
|
#include "DiabloUI/hub/hub.h"
|
||
|
|
|
||
|
|
#include <fmt/format.h>
|
||
|
|
|
||
|
|
#include "DiabloUI/button.h"
|
||
|
|
#include "DiabloUI/diabloui.h"
|
||
|
|
#include "DiabloUI/dialogs.h"
|
||
|
|
#include "DiabloUI/hero/selhero.h"
|
||
|
|
#include "DiabloUI/hub/chat.h"
|
||
|
|
#include "DiabloUI/hub/create.h"
|
||
|
|
#include "DiabloUI/hub/friends.h"
|
||
|
|
#include "DiabloUI/hub/join.h"
|
||
|
|
#include "DiabloUI/scrollbar.h"
|
||
|
|
#include "DiabloUI/selok.h"
|
||
|
|
#include "config.h"
|
||
|
|
#include "control.h"
|
||
|
|
#include "engine/assets.hpp"
|
||
|
|
#include "engine/load_clx.hpp"
|
||
|
|
#include "menu.h"
|
||
|
|
#include "options.h"
|
||
|
|
#include "storm/storm_net.hpp"
|
||
|
|
#include "utils/language.h"
|
||
|
|
#include "utils/str_cat.hpp"
|
||
|
|
#include "utils/utf8.hpp"
|
||
|
|
|
||
|
|
namespace devilution {
|
||
|
|
|
||
|
|
bool hubmain_endMenu;
|
||
|
|
std::vector<std::unique_ptr<UiItemBase>> vecHubMainDialog;
|
||
|
|
OptionalOwnedClxSpriteList Layout;
|
||
|
|
|
||
|
|
namespace {
|
||
|
|
|
||
|
|
enum class HubPanels : uint8_t {
|
||
|
|
Chat,
|
||
|
|
Friends,
|
||
|
|
Create,
|
||
|
|
Join,
|
||
|
|
};
|
||
|
|
|
||
|
|
HubPanels HubPanel = HubPanels::Join;
|
||
|
|
|
||
|
|
OptionalOwnedClxSpriteList PlayerIcons;
|
||
|
|
OptionalOwnedClxSpriteList PlayerSpawnIcon;
|
||
|
|
OptionalOwnedClxSpriteList PlayerLevelFont;
|
||
|
|
OptionalOwnedClxSpriteList LagGreen;
|
||
|
|
OptionalOwnedClxSpriteList LagYellow;
|
||
|
|
OptionalOwnedClxSpriteList LagRed;
|
||
|
|
|
||
|
|
void LoadHubPlayerGraphics()
|
||
|
|
{
|
||
|
|
PlayerIcons = LoadPcxSpriteList("ui_art\\heroport", -14);
|
||
|
|
PlayerSpawnIcon = LoadPcx("ui_art\\spwnport");
|
||
|
|
PlayerLevelFont = LoadPcxSpriteList("ui_art\\heronum", 10);
|
||
|
|
LagGreen = LoadPcx("ui_art\\greenlag");
|
||
|
|
LagYellow = LoadPcx("ui_art\\yellolag");
|
||
|
|
LagRed = LoadPcx("ui_art\\redlag");
|
||
|
|
}
|
||
|
|
|
||
|
|
std::vector<std::unique_ptr<UiItemBase>> vecHubBackground;
|
||
|
|
|
||
|
|
void hub_Init()
|
||
|
|
{
|
||
|
|
LoadDialogButtonGraphics();
|
||
|
|
LoadHubScrollBar();
|
||
|
|
|
||
|
|
LoadBackgroundArt("ui_art\\bnconnbg");
|
||
|
|
ArtBackgroundWidescreen = LoadOptionalClx("ui_art\\bnconnbgw.clx");
|
||
|
|
|
||
|
|
uint8_t transparentColor = 250;
|
||
|
|
AssetRef ref = FindAsset("ui_art\\xsmlogo");
|
||
|
|
if (ref.ok() && ref.size() == 167723)
|
||
|
|
transparentColor = 32;
|
||
|
|
ArtLogo = LoadPcxSpriteList("ui_art\\xsmlogo", /*numFrames=*/15, transparentColor);
|
||
|
|
|
||
|
|
switch (HubPanel) {
|
||
|
|
case HubPanels::Chat:
|
||
|
|
hubmain_Init();
|
||
|
|
break;
|
||
|
|
case HubPanels::Friends:
|
||
|
|
break;
|
||
|
|
case HubPanels::Create:
|
||
|
|
HubLoadCreate();
|
||
|
|
break;
|
||
|
|
case HubPanels::Join:
|
||
|
|
HubLoadJoin();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
LoadHubPlayerGraphics();
|
||
|
|
}
|
||
|
|
|
||
|
|
void hubmain_Free()
|
||
|
|
{
|
||
|
|
FreeDialogButtonGraphics();
|
||
|
|
ArtBackground = std::nullopt;
|
||
|
|
ArtBackgroundWidescreen = std::nullopt;
|
||
|
|
Layout = std::nullopt;
|
||
|
|
vecHubMainDialog.clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool IsKnownHeroType(uint32_t gameMode, HeroClass heroClass)
|
||
|
|
{
|
||
|
|
if (gameMode != GameIdDiabloFull && gameMode != GameIdHellfireFull)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
return heroClass == HeroClass::Warrior
|
||
|
|
|| heroClass == HeroClass::Rogue
|
||
|
|
|| heroClass == HeroClass::Sorcerer;
|
||
|
|
}
|
||
|
|
|
||
|
|
} // namespace
|
||
|
|
|
||
|
|
void LoadHubScrollBar()
|
||
|
|
{
|
||
|
|
ScrollBarWidth = 17;
|
||
|
|
ScrollBarArrowFrame_UP_ACTIVE = 2;
|
||
|
|
ScrollBarArrowFrame_UP = 0;
|
||
|
|
ScrollBarArrowFrame_DOWN_ACTIVE = 3;
|
||
|
|
ScrollBarArrowFrame_DOWN = 1;
|
||
|
|
ArtScrollBarArrow = LoadPcxSpriteList("ui_art\\scrlarrw", 4);
|
||
|
|
ArtScrollBarBackground = LoadPcx("ui_art\\scrlbar");
|
||
|
|
ArtScrollBarThumb = LoadPcx("ui_art\\scrlthmb");
|
||
|
|
}
|
||
|
|
|
||
|
|
void UiHubPlacePlayerIcon(Point position, uint32_t gameMode, const PlayerInfo &player)
|
||
|
|
{
|
||
|
|
ClxSprite sprite = (*PlayerSpawnIcon)[0];
|
||
|
|
if (IsKnownHeroType(gameMode, player.heroClass)) {
|
||
|
|
int level = player.diabloKillLevel * 3;
|
||
|
|
sprite = (*PlayerIcons)[level + static_cast<uint8_t>(player.heroClass)];
|
||
|
|
}
|
||
|
|
const SDL_Rect rect0 = MakeSdlRect(position.x, position.y, 0, 0);
|
||
|
|
vecHubMainDialog.push_back(std::make_unique<UiImageClx>(sprite, rect0));
|
||
|
|
|
||
|
|
const SDL_Rect rect1 = MakeSdlRect(position.x + 20, position.y + 5, 0, 0);
|
||
|
|
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*PlayerLevelFont)[player.level % 10], rect1));
|
||
|
|
if (player.level > 9) {
|
||
|
|
const SDL_Rect rect2 = MakeSdlRect(position.x + 14, position.y + 5, 0, 0);
|
||
|
|
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*PlayerLevelFont)[player.level / 10], rect2));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void UiHubPlaceLatencyMeter(int latency, Point position)
|
||
|
|
{
|
||
|
|
int bars = latency / 50 + 1;
|
||
|
|
bars = std::min(bars, 6);
|
||
|
|
|
||
|
|
ClxSprite lagSprite = (*LagRed)[0];
|
||
|
|
if (bars <= 2)
|
||
|
|
lagSprite = (*LagGreen)[0];
|
||
|
|
else if (bars <= 4)
|
||
|
|
lagSprite = (*LagYellow)[0];
|
||
|
|
|
||
|
|
const SDL_Rect rect4 = MakeSdlRect(position.x, position.y, 3 * bars, 11);
|
||
|
|
vecHubMainDialog.push_back(std::make_unique<UiImageClx>(lagSprite, rect4));
|
||
|
|
}
|
||
|
|
|
||
|
|
void hubmain_GameSelection_Focus(int value)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void hubmain_Diff_Select(int value)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void hubmain_GameSelection_Esc()
|
||
|
|
{
|
||
|
|
UiInitList_clear();
|
||
|
|
hubmain_endMenu = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void hub_GameSelection_Init()
|
||
|
|
{
|
||
|
|
const Point uiPosition = GetUIRectangle().position;
|
||
|
|
|
||
|
|
const SDL_Rect rect0 = MakeSdlRect(0, uiPosition.y, 0, 0);
|
||
|
|
vecHubBackground.push_back(std::make_unique<UiImageClx>((*ArtBackground)[0], rect0, UiFlags::AlignCenter));
|
||
|
|
vecHubBackground.push_back(std::make_unique<UiImageClx>((*ArtBackgroundWidescreen)[0], rect0, UiFlags::AlignCenter));
|
||
|
|
|
||
|
|
vecHubBackground.push_back(std::make_unique<UiImageAnimatedClx>(*ArtLogo, MakeSdlRect(uiPosition.x, uiPosition.y, 0, 0)));
|
||
|
|
|
||
|
|
const SDL_Rect rect1 = MakeSdlRect(uiPosition.x, uiPosition.y + (*ArtBackground)[0].height() - (*Layout)[0].height(), (*Layout)[0].width(), (*Layout)[0].height());
|
||
|
|
vecHubBackground.push_back(std::make_unique<UiImageClx>((*Layout)[0], rect1, UiFlags::AlignCenter));
|
||
|
|
|
||
|
|
switch (HubPanel) {
|
||
|
|
case HubPanels::Chat:
|
||
|
|
hubmain_GameSelection_Init();
|
||
|
|
break;
|
||
|
|
case HubPanels::Friends:
|
||
|
|
break;
|
||
|
|
case HubPanels::Create:
|
||
|
|
HubInitCreate();
|
||
|
|
break;
|
||
|
|
case HubPanels::Join:
|
||
|
|
HubInitJoin();
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
UiInitList(hubmain_GameSelection_Focus, hubmain_Diff_Select, hubmain_GameSelection_Esc, vecHubMainDialog, true);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool UiHubMain()
|
||
|
|
{
|
||
|
|
hub_Init();
|
||
|
|
hub_GameSelection_Init();
|
||
|
|
|
||
|
|
hubmain_endMenu = false;
|
||
|
|
|
||
|
|
while (!hubmain_endMenu) {
|
||
|
|
UiClearScreen();
|
||
|
|
UiRenderItems(vecHubBackground);
|
||
|
|
if (HubPanel == HubPanels::Chat)
|
||
|
|
DrawChat();
|
||
|
|
UiPollAndRender();
|
||
|
|
}
|
||
|
|
hubmain_Free();
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
} // namespace devilution
|