21 changed files with 694 additions and 21 deletions
Binary file not shown.
@ -0,0 +1,141 @@
|
||||
#include "DiabloUI/hub/chat.h" |
||||
|
||||
#include "DiabloUI/hub/hub.h" |
||||
#include "DiabloUI/scrollbar.h" |
||||
#include "engine/load_pcx.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
namespace { |
||||
|
||||
char ChatMessage[129]; |
||||
|
||||
OptionalOwnedClxSpriteList MainButton; |
||||
std::vector<PlayerInfo> PlayerList; |
||||
|
||||
struct ColoredText { |
||||
std::string text; |
||||
UiFlags color; |
||||
}; |
||||
|
||||
struct MultiColoredText { |
||||
std::string text; |
||||
std::vector<ColoredText> colors; |
||||
int offset = 0; |
||||
}; |
||||
|
||||
std::vector<MultiColoredText> ChatLogLines; |
||||
|
||||
void BuildFixtures() |
||||
{ |
||||
PlayerList.emplace_back(PlayerInfo { "KPhoenix", HeroClass::Warrior, 35, 2, GameIdDiabloFull, 50 }); |
||||
PlayerList.emplace_back(PlayerInfo { "AJenbo", HeroClass::Rogue, 23, 1, GameIdHellfireFull, 320 }); |
||||
PlayerList.emplace_back(PlayerInfo { "FireIceTalon", HeroClass::Sorcerer, 50, 3, GameIdDiabloFull, 150 }); |
||||
PlayerList.emplace_back(PlayerInfo { "glebm", HeroClass::Monk, 12, 0, GameIdHellfireFull, 1400 }); |
||||
PlayerList.emplace_back(PlayerInfo { "qndel", HeroClass::Warrior, 1, 0, GameIdDiabloSpawn, 450 }); |
||||
|
||||
ChatLogLines.emplace_back(MultiColoredText { "{0}", { { "KPhoenix has appeared on the network", UiFlags::ColorUiGreen } } }); |
||||
ChatLogLines.emplace_back(MultiColoredText { "{0} {1}", { { "<KPhoenix>", UiFlags::ColorYellow }, { "Hello", UiFlags::ColorDialogWhite } } }); |
||||
ChatLogLines.emplace_back(MultiColoredText { "{0} {1}", { { "<AJenbo>", UiFlags::ColorBlue }, { "Ready?", UiFlags::ColorUiSilverDark } } }); |
||||
ChatLogLines.emplace_back(MultiColoredText { "{0}", { { "FireIceTalon started a new game", UiFlags::ColorRed } } }); |
||||
} |
||||
|
||||
void hubmain_Free() |
||||
{ |
||||
PlayerList.clear(); |
||||
ChatLogLines.clear(); |
||||
} |
||||
|
||||
void DialogActionOK() |
||||
{ |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
void hubmain_Init() |
||||
{ |
||||
Layout = LoadPcx("ui_art\\chat_bkg", /*transparentColor=*/0); |
||||
MainButton = LoadPcxSpriteList("ui_art\\bnbuttns", -71); |
||||
|
||||
BuildFixtures(); |
||||
} |
||||
|
||||
void UiHubInitPlayerList() |
||||
{ |
||||
const Point uiPosition = GetUIRectangle().position + Displacement { 460, 200 }; |
||||
int yOffset = 0; |
||||
|
||||
for (const PlayerInfo &player : PlayerList) { |
||||
UiHubPlacePlayerIcon({ uiPosition.x, uiPosition.y + yOffset }, player.gameMode, player); |
||||
|
||||
const SDL_Rect rect3 = MakeSdlRect(uiPosition.x + 30, uiPosition.y + yOffset - 6, 89, 20); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(player.name.data(), rect3, UiFlags::FontSizeDialog | UiFlags::ColorYellow, -1)); |
||||
|
||||
UiHubPlaceLatencyMeter(player.latency, { uiPosition.x + 121, uiPosition.y + yOffset + 2 }); |
||||
|
||||
yOffset += 16; |
||||
} |
||||
} |
||||
|
||||
void hubmain_GameSelection_Init() |
||||
{ |
||||
const Point uiPosition = GetUIRectangle().position; |
||||
|
||||
const SDL_Rect rect2 = MakeSdlRect(uiPosition.x + 445, uiPosition.y + 148, 179, 28); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Global Chat").data(), rect2, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter | UiFlags::VerticalCenter, -1)); |
||||
|
||||
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*MainButton)[0], MakeSdlRect(uiPosition.x + 10, uiPosition.y + 140, 85, 71))); |
||||
const SDL_Rect rect3 = MakeSdlRect(uiPosition.x + 10, uiPosition.y + 140 + 43, 85, 71); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Friends").data(), rect3, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -1)); |
||||
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*MainButton)[5], MakeSdlRect(uiPosition.x + 10, uiPosition.y + 227, 85, 71))); |
||||
const SDL_Rect rect4 = MakeSdlRect(uiPosition.x + 10, uiPosition.y + 227 + 43, 85, 71); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Create").data(), rect4, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -1)); |
||||
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*MainButton)[10], MakeSdlRect(uiPosition.x + 10, uiPosition.y + 315, 85, 71))); |
||||
const SDL_Rect rect5 = MakeSdlRect(uiPosition.x + 10, uiPosition.y + 315 + 43, 85, 71); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Join").data(), rect5, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -1)); |
||||
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*MainButton)[15], MakeSdlRect(uiPosition.x + 10, uiPosition.y + 402, 85, 71))); |
||||
const SDL_Rect rect6 = MakeSdlRect(uiPosition.x + 10, uiPosition.y + 402 + 43, 85, 71); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Quit").data(), rect6, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -1)); |
||||
|
||||
UiHubInitPlayerList(); |
||||
|
||||
const SDL_Rect rectScrollbar1 = MakeSdlRect(uiPosition.x + 402, uiPosition.y + 158, 17, 251); |
||||
vecHubMainDialog.push_back(std::make_unique<UiScrollbar>((*ArtScrollBarBackground)[0], (*ArtScrollBarThumb)[0], *ArtScrollBarArrow, rectScrollbar1)); |
||||
|
||||
const SDL_Rect rectScrollbar2 = MakeSdlRect(uiPosition.x + 602, uiPosition.y + 199, 17, 209); |
||||
vecHubMainDialog.push_back(std::make_unique<UiScrollbar>((*ArtScrollBarBackground)[0], (*ArtScrollBarThumb)[0], *ArtScrollBarArrow, rectScrollbar2)); |
||||
|
||||
const SDL_Rect rect7 = MakeSdlRect(uiPosition.x + 264 + 188, uiPosition.y + 335 + 103, 85, 35); |
||||
vecHubMainDialog.push_back(std::make_unique<UiButton>(_("Send"), &DialogActionOK, rect7)); |
||||
|
||||
const SDL_Rect rect8 = MakeSdlRect(uiPosition.x + 264 + 283, uiPosition.y + 335 + 103, 85, 35); |
||||
vecHubMainDialog.push_back(std::make_unique<UiButton>(_("Whisper"), &DialogActionOK, rect8)); |
||||
|
||||
const SDL_Rect rect9 = MakeSdlRect(uiPosition.x + 117, uiPosition.y + 433, 306, 30); |
||||
vecHubMainDialog.push_back(std::make_unique<UiEdit>(_("Enter chat message"), ChatMessage, 128, false, rect9, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite)); |
||||
} |
||||
|
||||
void DrawChat() |
||||
{ |
||||
const Point uiPosition = GetUIRectangle().position + Displacement { 116, 161 }; |
||||
|
||||
const Surface &out = Surface(DiabloUiSurface()); |
||||
int displayLines = ChatLogLines.size(); |
||||
displayLines = std::min(100, displayLines); |
||||
int SkipLines = 0; |
||||
int lineHeight = 22; |
||||
for (int i = 0; i < displayLines; i++) { |
||||
if (i + SkipLines >= ChatLogLines.size()) |
||||
break; |
||||
MultiColoredText &text = ChatLogLines[ChatLogLines.size() - (i + SkipLines + 1)]; |
||||
const string_view line = text.text; |
||||
|
||||
std::vector<DrawStringFormatArg> args; |
||||
for (auto &x : text.colors) { |
||||
args.emplace_back(DrawStringFormatArg { x.text, x.color }); |
||||
} |
||||
DrawStringWithColors(out, line, args, { { (uiPosition.x + text.offset), uiPosition.y + i * lineHeight }, { 280 - text.offset * 2, lineHeight } }, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, /*spacing=*/1, lineHeight); |
||||
} |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,9 @@
|
||||
#pragma once |
||||
|
||||
namespace devilution { |
||||
|
||||
void hubmain_Init(); |
||||
void hubmain_GameSelection_Init(); |
||||
void DrawChat(); |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,51 @@
|
||||
#include "DiabloUI/hub/create.h" |
||||
|
||||
#include "DiabloUI/hub/hub.h" |
||||
#include "engine/load_pcx.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
namespace { |
||||
|
||||
OptionalOwnedClxSpriteList CreateButton; |
||||
|
||||
void DialogActionOK() |
||||
{ |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
void HubLoadCreate() |
||||
{ |
||||
Layout = LoadPcx("ui_art\\creat_bg", /*transparentColor=*/0); |
||||
CreateButton = LoadPcxSpriteList("ui_art\\diffbtns", -68); |
||||
} |
||||
|
||||
void HubInitCreate() |
||||
{ |
||||
const Point uiPosition = GetUIRectangle().position; |
||||
|
||||
const SDL_Rect rect0 = MakeSdlRect(uiPosition.x + 17, uiPosition.y + 154, 274, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Difficulty").data(), rect0, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -1)); |
||||
|
||||
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*CreateButton)[1], MakeSdlRect(uiPosition.x + 115, uiPosition.y + 187, 85, 68))); |
||||
const SDL_Rect rect1 = MakeSdlRect(uiPosition.x + 115, uiPosition.y + 227, 85, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Normal").data(), rect1, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -2)); |
||||
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*CreateButton)[2], MakeSdlRect(uiPosition.x + 62, uiPosition.y + 263, 85, 68))); |
||||
const SDL_Rect rect2 = MakeSdlRect(uiPosition.x + 62, uiPosition.y + 303, 85, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Nightmare").data(), rect2, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -2)); |
||||
vecHubMainDialog.push_back(std::make_unique<UiImageClx>((*CreateButton)[4], MakeSdlRect(uiPosition.x + 167, uiPosition.y + 263, 85, 68))); |
||||
const SDL_Rect rect3 = MakeSdlRect(uiPosition.x + 167, uiPosition.y + 303, 85, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Hell").data(), rect3, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -2)); |
||||
|
||||
const SDL_Rect rect4 = MakeSdlRect(uiPosition.x + 26, uiPosition.y + 340, 262, 110); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Normal Difficulty\nThis is where a starting\ncharacter should begin the quest\nto defeat Diablo.").data(), rect4, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1, 19)); |
||||
|
||||
const SDL_Rect rect7 = MakeSdlRect(uiPosition.x + 264 + 188, uiPosition.y + 335 + 103, 85, 35); |
||||
vecHubMainDialog.push_back(std::make_unique<UiButton>(_("OK"), &DialogActionOK, rect7)); |
||||
|
||||
const SDL_Rect rect8 = MakeSdlRect(uiPosition.x + 264 + 283, uiPosition.y + 335 + 103, 85, 35); |
||||
vecHubMainDialog.push_back(std::make_unique<UiButton>(_("Cancel"), &DialogActionOK, rect8)); |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,8 @@
|
||||
#pragma once |
||||
|
||||
namespace devilution { |
||||
|
||||
void HubLoadCreate(); |
||||
void HubInitCreate(); |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,22 @@
|
||||
#include "DiabloUI/hub/friends.h" |
||||
|
||||
#include "DiabloUI/hub/hub.h" |
||||
#include "engine/load_pcx.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
namespace { |
||||
|
||||
} // namespace
|
||||
|
||||
void HubLoadFriends() |
||||
{ |
||||
Layout = LoadPcx("ui_art\\bnselchn", /*transparentColor=*/0); |
||||
} |
||||
|
||||
void HubInitFriends() |
||||
{ |
||||
const Point uiPosition = GetUIRectangle().position; |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,8 @@
|
||||
#pragma once |
||||
|
||||
namespace devilution { |
||||
|
||||
void HubLoadFriends(); |
||||
void HubInitFriends(); |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,221 @@
|
||||
#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
|
||||
@ -0,0 +1,31 @@
|
||||
#pragma once |
||||
|
||||
#include <memory> |
||||
#include <vector> |
||||
|
||||
#include "DiabloUI/diabloui.h" |
||||
#include "engine/point.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
struct PlayerInfo { |
||||
std::string name; |
||||
HeroClass heroClass; |
||||
uint8_t level; |
||||
uint8_t diabloKillLevel; |
||||
uint32_t gameMode; |
||||
int latency; |
||||
}; |
||||
|
||||
extern std::vector<std::unique_ptr<UiItemBase>> vecHubMainDialog; |
||||
extern OptionalOwnedClxSpriteList Layout; |
||||
|
||||
void selgame_GameSelection_Init(); |
||||
void selgame_GameSelection_Focus(int value); |
||||
void selgame_GameSelection_Esc(); |
||||
void selgame_Diff_Select(int value); |
||||
void LoadHubScrollBar(); |
||||
void UiHubPlacePlayerIcon(Point position, uint32_t gameMode, const PlayerInfo &player); |
||||
void UiHubPlaceLatencyMeter(int latency, Point position); |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,135 @@
|
||||
#include "DiabloUI/hub/join.h" |
||||
|
||||
#include "DiabloUI/hub/hub.h" |
||||
#include "DiabloUI/scrollbar.h" |
||||
#include "engine/load_pcx.hpp" |
||||
|
||||
namespace devilution { |
||||
|
||||
namespace { |
||||
|
||||
void DialogActionOK() |
||||
{ |
||||
} |
||||
|
||||
std::vector<PlayerInfo> PlayerList; |
||||
|
||||
std::string relativeTime; |
||||
std::string difficultyString; |
||||
std::string GetDifficultyString(int difficulty) |
||||
{ |
||||
constexpr std::array<const char *, 3> DifficultyStrs = { N_("Normal"), N_("Nightmare"), N_("Hell") }; |
||||
const string_view difficultyStr = _(DifficultyStrs[difficulty]); |
||||
return fmt::format(fmt::runtime(_(/* TRANSLATORS: "Nightmare Difficulty" */ "{:s} Difficulty")), difficultyStr); |
||||
} |
||||
|
||||
char GameNameInput[32]; |
||||
char GamePasswordInput[32]; |
||||
|
||||
} // namespace
|
||||
|
||||
void HubLoadJoin() |
||||
{ |
||||
Layout = LoadPcx("ui_art\\bnjoinbg", /*transparentColor=*/0); |
||||
} |
||||
|
||||
void HubInitJoin() |
||||
{ |
||||
const Point uiPosition = GetUIRectangle().position; |
||||
|
||||
const SDL_Rect rect0 = MakeSdlRect(uiPosition.x + 17, uiPosition.y + 150, 274, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Matching Public Games").data(), rect0, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignCenter, -1)); |
||||
|
||||
const SDL_Rect rect1 = MakeSdlRect(uiPosition.x + 312, uiPosition.y + 150, 311, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Join Game").data(), rect1, UiFlags::FontSizeDialog | UiFlags::ColorYellow | UiFlags::AlignCenter, -1)); |
||||
|
||||
const SDL_Rect rect2 = MakeSdlRect(uiPosition.x + 326, uiPosition.y + 185, 274, 26 * 2); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("To Join a game, enter the game\ninfomration below.").data(), rect2, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
|
||||
const SDL_Rect rect3 = MakeSdlRect(uiPosition.x + 326, uiPosition.y + 249, 86, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Name:").data(), rect3, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignRight, -1)); |
||||
const SDL_Rect rect4 = MakeSdlRect(uiPosition.x + 421, uiPosition.y + 250, 192, 29); |
||||
vecHubMainDialog.push_back(std::make_unique<UiEdit>(_("Enter game name"), GameNameInput, 32, false, rect4, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite)); |
||||
|
||||
const SDL_Rect rect5 = MakeSdlRect(uiPosition.x + 326, uiPosition.y + 294, 86, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Password:").data(), rect5, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite | UiFlags::AlignRight, -1)); |
||||
const SDL_Rect rect6 = MakeSdlRect(uiPosition.x + 421, uiPosition.y + 295, 192, 29); |
||||
vecHubMainDialog.push_back(std::make_unique<UiEdit>(_("Enter game password"), GamePasswordInput, 32, false, rect6, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite)); |
||||
|
||||
const SDL_Rect rectScrollbar = MakeSdlRect(uiPosition.x + 269, uiPosition.y + 189, 17, 274); |
||||
vecHubMainDialog.push_back(std::make_unique<UiScrollbar>((*ArtScrollBarBackground)[0], (*ArtScrollBarThumb)[0], *ArtScrollBarArrow, rectScrollbar)); |
||||
|
||||
UiHubPlaceLatencyMeter(75, { uiPosition.x + 245, uiPosition.y + 195 }); |
||||
|
||||
const SDL_Rect rect7 = MakeSdlRect(uiPosition.x + 27, uiPosition.y + 186, 218, 26); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>("CWEJZ", rect7, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
|
||||
const Point detailsPosition = uiPosition + Displacement { 326, 342 }; |
||||
int yOffset = 0; |
||||
|
||||
difficultyString = GetDifficultyString(1); |
||||
const SDL_Rect rect8 = MakeSdlRect(detailsPosition.x, detailsPosition.y + yOffset - 6, 149, 18); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(difficultyString.data(), rect8, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
yOffset += 16; |
||||
|
||||
int seconds = 76 * 60; |
||||
int hours = seconds / 3600; |
||||
int minutes = (seconds % 3600) / 60; |
||||
relativeTime = fmt::format(fmt::runtime(ngettext("{:d} minute", "{:d} minutes", minutes)), minutes); |
||||
if (hours > 0) { |
||||
if (minutes > 0) { |
||||
relativeTime = fmt::format(fmt::runtime(ngettext("{:d} minute", "{:d} minutes", minutes)), minutes); |
||||
relativeTime = fmt::format(fmt::runtime(ngettext( |
||||
/* TRANSLATORS: {:s} the translated minuts (3 minuts).*/ |
||||
"Time: {:d} hour and {:s}", |
||||
"Time: {:d} hours and {:s}", |
||||
hours)), |
||||
hours, relativeTime); |
||||
} else { |
||||
relativeTime = fmt::format(fmt::runtime(ngettext("Time: {:d} hour", "Time: {:d} hours", hours)), hours); |
||||
} |
||||
} else { |
||||
relativeTime = fmt::format(fmt::runtime(_("Time: {:s}")), relativeTime); |
||||
} |
||||
const SDL_Rect rect9 = MakeSdlRect(detailsPosition.x, detailsPosition.y + yOffset - 6, 149, 18); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(relativeTime.data(), rect9, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
yOffset += 16; |
||||
|
||||
const SDL_Rect rect10 = MakeSdlRect(detailsPosition.x, detailsPosition.y + yOffset - 6, 51, 18); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Players:").data(), rect10, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
|
||||
PlayerList.emplace_back(PlayerInfo { "KPhoenix", HeroClass::Warrior, 35, 2, GameIdDiabloFull, 0 }); |
||||
PlayerList.emplace_back(PlayerInfo { "AJenbo", HeroClass::Rogue, 23, 1, GameIdDiabloFull, 0 }); |
||||
PlayerList.emplace_back(PlayerInfo { "glebm", HeroClass::Sorcerer, 19, 0, GameIdDiabloFull, 0 }); |
||||
|
||||
for (auto &player : PlayerList) { |
||||
UiHubPlacePlayerIcon({ detailsPosition.x + 52, detailsPosition.y + yOffset }, GameIdDiabloFull, player); |
||||
const SDL_Rect rect = MakeSdlRect(detailsPosition.x + 52 + 30, detailsPosition.y + yOffset - 6, 149 - 30, 18); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(player.name.data(), rect, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
|
||||
yOffset += 16; |
||||
} |
||||
|
||||
const Point detailsPosition2 = detailsPosition + Displacement { 184, 0 }; |
||||
yOffset = 0; |
||||
|
||||
const SDL_Rect rect11 = MakeSdlRect(detailsPosition2.x, detailsPosition2.y + yOffset - 6, 149, 18); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Run in Town").data(), rect11, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
yOffset += 16; |
||||
|
||||
const SDL_Rect rect12 = MakeSdlRect(detailsPosition2.x, detailsPosition2.y + yOffset - 6, 149, 18); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Theo Quest").data(), rect12, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
yOffset += 16; |
||||
|
||||
const SDL_Rect rect13 = MakeSdlRect(detailsPosition2.x, detailsPosition2.y + yOffset - 6, 149, 18); |
||||
vecHubMainDialog.push_back(std::make_unique<UiArtText>(_("Friendly Fire").data(), rect13, UiFlags::FontSizeDialog | UiFlags::ColorDialogWhite, -1)); |
||||
yOffset += 16; |
||||
|
||||
const SDL_Rect rect14 = MakeSdlRect(uiPosition.x + 264 + 188, uiPosition.y + 335 + 103, 85, 35); |
||||
vecHubMainDialog.push_back(std::make_unique<UiButton>(_("OK"), &DialogActionOK, rect14)); |
||||
|
||||
const SDL_Rect rect15 = MakeSdlRect(uiPosition.x + 264 + 283, uiPosition.y + 335 + 103, 85, 35); |
||||
vecHubMainDialog.push_back(std::make_unique<UiButton>(_("Cancel"), &DialogActionOK, rect15)); |
||||
} |
||||
|
||||
} // namespace devilution
|
||||
@ -0,0 +1,8 @@
|
||||
#pragma once |
||||
|
||||
namespace devilution { |
||||
|
||||
void HubLoadJoin(); |
||||
void HubInitJoin(); |
||||
|
||||
} // namespace devilution
|
||||
Loading…
Reference in new issue