mirror of
https://github.com/coah80/LegacyVulkEdition.git
synced 2026-07-19 15:08:14 +00:00
489 lines
17 KiB
C++
489 lines
17 KiB
C++
#define NK_INCLUDE_FIXED_TYPES
|
|
#define NK_INCLUDE_STANDARD_IO
|
|
#define NK_INCLUDE_STANDARD_VARARGS
|
|
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
|
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
|
#define NK_INCLUDE_FONT_BAKING
|
|
#define NK_INCLUDE_DEFAULT_FONT
|
|
#include "nuklear.h"
|
|
|
|
#include "NkGameMenus.h"
|
|
#include "NkCommon.h"
|
|
#include "MenuScreens.h"
|
|
#include "NuklearBridge.h"
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
|
|
namespace lve { namespace ui {
|
|
|
|
static const float BASE_W = 1280.0f;
|
|
static const float BASE_H = 720.0f;
|
|
|
|
static const float BUTTON_X = 415.0f;
|
|
static const float BUTTON_W = 450.0f;
|
|
static const float BUTTON_H = 40.0f;
|
|
static const float BUTTON_Y_START = 200.0f;
|
|
static const float BUTTON_Y_STEP = 50.0f;
|
|
|
|
static const float TITLE_Y = 120.0f;
|
|
static const float TITLE_H = 50.0f;
|
|
|
|
static const float CHECKBOX_ROW_H = 40.0f;
|
|
|
|
static const float LIST_ITEM_H = 40.0f;
|
|
static const float FIELD_H = 36.0f;
|
|
|
|
static const float PANEL_X = 290.0f;
|
|
static const float PANEL_W = 700.0f;
|
|
static const float PANEL_Y = 80.0f;
|
|
|
|
static const float SIGN_FIELD_W = 360.0f;
|
|
static const float SIGN_FIELD_H = 32.0f;
|
|
static const float SIGN_FIELD_GAP = 8.0f;
|
|
|
|
GameMenuAction renderHostOptions(nk_context *ctx, int winW, int winH,
|
|
MenuTextures &tex, HostOptionsState &state)
|
|
{
|
|
GameMenuAction result = kGameAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
if (nk_begin(ctx, "HostOptions", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
drawTitle(ctx, "Host Options", winW, winH, TITLE_Y, TITLE_H);
|
|
|
|
float rowW = BUTTON_W * scaleX;
|
|
float rowH = CHECKBOX_ROW_H * scaleY;
|
|
float rowX = BUTTON_X * scaleX;
|
|
float step = BUTTON_Y_STEP * scaleY;
|
|
float baseY = BUTTON_Y_START * scaleY;
|
|
|
|
int row = 0;
|
|
|
|
state.fireSpreads = drawCheckbox(ctx, "Fire Spreads",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.fireSpreads, true, winH, tex);
|
|
row++;
|
|
|
|
state.tntExplodes = drawCheckbox(ctx, "TNT Explodes",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.tntExplodes, true, winH, tex);
|
|
row++;
|
|
|
|
if (state.showTeleport) {
|
|
float btnW = rowW;
|
|
float btnH = BUTTON_H * scaleY;
|
|
|
|
struct nk_rect tpRect = nk_rect(rowX, baseY + step * (float)row, btnW, btnH);
|
|
bool tpHover = nk_input_is_mouse_hovering_rect(&ctx->input, tpRect) != 0;
|
|
if (drawBtn(ctx, "Teleport to Player", rowX, baseY + step * (float)row, btnW, btnH, tpHover, winH, tex)) {
|
|
result = kGameAction_TeleportToPlayer;
|
|
}
|
|
row++;
|
|
|
|
struct nk_rect tmRect = nk_rect(rowX, baseY + step * (float)row, btnW, btnH);
|
|
bool tmHover = nk_input_is_mouse_hovering_rect(&ctx->input, tmRect) != 0;
|
|
if (drawBtn(ctx, "Teleport to Me", rowX, baseY + step * (float)row, btnW, btnH, tmHover, winH, tex)) {
|
|
result = kGameAction_TeleportToMe;
|
|
}
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
GameMenuAction renderPlayerOptions(nk_context *ctx, int winW, int winH,
|
|
MenuTextures &tex, PlayerOptionsState &state)
|
|
{
|
|
GameMenuAction result = kGameAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
if (nk_begin(ctx, "PlayerOptions", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
drawTitle(ctx, state.gamertag, winW, winH, TITLE_Y, TITLE_H);
|
|
|
|
float rowW = BUTTON_W * scaleX;
|
|
float rowH = CHECKBOX_ROW_H * scaleY;
|
|
float rowX = BUTTON_X * scaleX;
|
|
float step = BUTTON_Y_STEP * scaleY;
|
|
float baseY = BUTTON_Y_START * scaleY;
|
|
|
|
int row = 0;
|
|
|
|
if (state.showPermissions) {
|
|
state.canBuildAndMine = drawCheckbox(ctx, "Can Build and Mine",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.canBuildAndMine, true, winH, tex);
|
|
row++;
|
|
|
|
state.canUseDoorsAndSwitches = drawCheckbox(ctx, "Can Use Doors and Switches",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.canUseDoorsAndSwitches, true, winH, tex);
|
|
row++;
|
|
|
|
state.canOpenContainers = drawCheckbox(ctx, "Can Open Containers",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.canOpenContainers, true, winH, tex);
|
|
row++;
|
|
|
|
state.canAttackPlayers = drawCheckbox(ctx, "Can Attack Players",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.canAttackPlayers, true, winH, tex);
|
|
row++;
|
|
|
|
state.canAttackAnimals = drawCheckbox(ctx, "Can Attack Animals",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.canAttackAnimals, true, winH, tex);
|
|
row++;
|
|
}
|
|
|
|
if (state.showModerator) {
|
|
state.moderator = drawCheckbox(ctx, "Moderator",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.moderator, true, winH, tex);
|
|
row++;
|
|
}
|
|
|
|
if (state.showCheats) {
|
|
state.invisible = drawCheckbox(ctx,
|
|
state.editingSelf ? "Invisible" : "Can be Invisible",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.invisible, true, winH, tex);
|
|
row++;
|
|
|
|
state.canFly = drawCheckbox(ctx, "Can Fly",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.canFly, true, winH, tex);
|
|
row++;
|
|
|
|
state.disableExhaustion = drawCheckbox(ctx,
|
|
state.editingSelf ? "Disable Exhaustion" : "Can Disable Exhaustion",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.disableExhaustion, true, winH, tex);
|
|
row++;
|
|
|
|
if (!state.editingSelf) {
|
|
state.enableTeleport = drawCheckbox(ctx, "Enable Teleport",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.enableTeleport, true, winH, tex);
|
|
row++;
|
|
}
|
|
}
|
|
|
|
if (state.showKick) {
|
|
float btnW = rowW;
|
|
float btnH = BUTTON_H * scaleY;
|
|
struct nk_rect kickRect = nk_rect(rowX, baseY + step * (float)row, btnW, btnH);
|
|
bool kickHover = nk_input_is_mouse_hovering_rect(&ctx->input, kickRect) != 0;
|
|
if (drawBtn(ctx, "Kick Player", rowX, baseY + step * (float)row, btnW, btnH, kickHover, winH, tex)) {
|
|
result = kGameAction_KickPlayer;
|
|
}
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
GameMenuAction renderInGameInfo(nk_context *ctx, int winW, int winH,
|
|
MenuTextures &tex, InGameInfoState &state)
|
|
{
|
|
GameMenuAction result = kGameAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
if (nk_begin(ctx, "InGameInfo", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
drawTitle(ctx, "Players", winW, winH, TITLE_Y, TITLE_H);
|
|
|
|
const struct nk_input *input = &ctx->input;
|
|
|
|
float panelX = PANEL_X * scaleX;
|
|
float panelW = PANEL_W * scaleX;
|
|
float curY = PANEL_Y * scaleY + 100.0f * scaleY;
|
|
float itemH = LIST_ITEM_H * scaleY;
|
|
|
|
if (state.showHostOptions) {
|
|
float btnW = BUTTON_W * scaleX;
|
|
float btnH = BUTTON_H * scaleY;
|
|
float btnX = BUTTON_X * scaleX;
|
|
float btnY = PANEL_Y * scaleY + 60.0f * scaleY;
|
|
|
|
struct nk_rect hoRect = nk_rect(btnX, btnY, btnW, btnH);
|
|
bool hoHover = nk_input_is_mouse_hovering_rect(input, hoRect) != 0;
|
|
if (drawBtn(ctx, "Host Options", btnX, btnY, btnW, btnH, hoHover, winH, tex)) {
|
|
result = kGameAction_HostOptions;
|
|
}
|
|
}
|
|
|
|
int visiblePlayers = 8;
|
|
for (int i = 0; i < state.playerCount && i < visiblePlayers; i++) {
|
|
float itemY = curY + (float)i * itemH;
|
|
bool isSelected = (i == state.selectedIndex);
|
|
struct nk_rect itemRect = nk_rect(panelX, itemY, panelW, itemH);
|
|
bool itemHover = nk_input_is_mouse_hovering_rect(input, itemRect) != 0;
|
|
|
|
if (drawListItem(ctx, state.playerNames[i], panelX, itemY, panelW, itemH,
|
|
isSelected, itemHover, winH)) {
|
|
state.selectedIndex = i;
|
|
result = kGameAction_SelectPlayer;
|
|
}
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
GameMenuAction renderSignEntry(nk_context *ctx, int winW, int winH,
|
|
MenuTextures &tex, SignEntryState &state)
|
|
{
|
|
GameMenuAction result = kGameAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
if (nk_begin(ctx, "SignEntry", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
drawTitle(ctx, "Edit Sign Message", winW, winH, TITLE_Y, TITLE_H);
|
|
|
|
float fieldW = SIGN_FIELD_W * scaleX;
|
|
float fieldH = SIGN_FIELD_H * scaleY;
|
|
float gap = SIGN_FIELD_GAP * scaleY;
|
|
float fieldX = ((float)winW - fieldW) * 0.5f;
|
|
float startY = BUTTON_Y_START * scaleY;
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
float fieldY = startY + (float)i * (fieldH + gap);
|
|
bool selected = (i == state.editingLine);
|
|
|
|
if (drawTextInput(ctx, state.lines[i], fieldX, fieldY, fieldW, fieldH, selected, winH)) {
|
|
state.editingLine = i;
|
|
}
|
|
}
|
|
|
|
float btnW = BUTTON_W * scaleX;
|
|
float btnH = BUTTON_H * scaleY;
|
|
float btnX = ((float)winW - btnW) * 0.5f;
|
|
float btnY = startY + 4.0f * (fieldH + gap) + gap * 2.0f;
|
|
|
|
struct nk_rect doneRect = nk_rect(btnX, btnY, btnW, btnH);
|
|
bool doneHover = nk_input_is_mouse_hovering_rect(&ctx->input, doneRect) != 0;
|
|
if (drawBtn(ctx, "Done", btnX, btnY, btnW, btnH, doneHover, winH, tex)) {
|
|
state.confirmed = true;
|
|
result = kGameAction_SignDone;
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
GameMenuAction renderTeleportMenu(nk_context *ctx, int winW, int winH,
|
|
MenuTextures &tex, TeleportMenuState &state)
|
|
{
|
|
GameMenuAction result = kGameAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
const char *title = state.teleportToPlayer
|
|
? "Teleport to Player"
|
|
: "Teleport to Me";
|
|
|
|
if (nk_begin(ctx, "TeleportMenu", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
drawTitle(ctx, title, winW, winH, TITLE_Y, TITLE_H);
|
|
|
|
const struct nk_input *input = &ctx->input;
|
|
|
|
float panelX = PANEL_X * scaleX;
|
|
float panelW = PANEL_W * scaleX;
|
|
float curY = PANEL_Y * scaleY + 100.0f * scaleY;
|
|
float itemH = LIST_ITEM_H * scaleY;
|
|
|
|
int visiblePlayers = 8;
|
|
for (int i = 0; i < state.playerCount && i < visiblePlayers; i++) {
|
|
float itemY = curY + (float)i * itemH;
|
|
bool isSelected = (i == state.selectedIndex);
|
|
struct nk_rect itemRect = nk_rect(panelX, itemY, panelW, itemH);
|
|
bool itemHover = nk_input_is_mouse_hovering_rect(input, itemRect) != 0;
|
|
|
|
if (drawListItem(ctx, state.playerNames[i], panelX, itemY, panelW, itemH,
|
|
isSelected, itemHover, winH)) {
|
|
state.selectedIndex = i;
|
|
result = kGameAction_TeleportSelect;
|
|
}
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
GameMenuAction renderLaunchMoreOptions(nk_context *ctx, int winW, int winH,
|
|
MenuTextures &tex, LaunchMoreOptionsState &state)
|
|
{
|
|
GameMenuAction result = kGameAction_None;
|
|
|
|
float scaleX = (float)winW / BASE_W;
|
|
float scaleY = (float)winH / BASE_H;
|
|
|
|
pushCleanStyle(ctx);
|
|
|
|
const char *tabTitle = (state.tabIndex == 0)
|
|
? "World Options"
|
|
: "Game Options";
|
|
|
|
if (nk_begin(ctx, "LaunchMoreOptions", nk_rect(0, 0, (float)winW, (float)winH),
|
|
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_NO_INPUT | NK_WINDOW_BACKGROUND)) {
|
|
|
|
drawDirtBg(ctx, winW, winH, tex);
|
|
drawTitle(ctx, tabTitle, winW, winH, TITLE_Y, TITLE_H);
|
|
|
|
float rowW = BUTTON_W * scaleX;
|
|
float rowH = CHECKBOX_ROW_H * scaleY;
|
|
float rowX = BUTTON_X * scaleX;
|
|
float step = 44.0f * scaleY;
|
|
float baseY = BUTTON_Y_START * scaleY;
|
|
|
|
if (state.tabIndex == 0) {
|
|
int row = 0;
|
|
|
|
state.onlineGame = drawCheckbox(ctx, "Online Game",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.onlineGame, true, winH, tex);
|
|
row++;
|
|
|
|
state.inviteOnly = drawCheckbox(ctx, "Invite Only",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.inviteOnly, state.onlineGame, winH, tex);
|
|
row++;
|
|
|
|
state.allowFriendsOfFriends = drawCheckbox(ctx, "Allow Friends of Friends",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.allowFriendsOfFriends, state.onlineGame, winH, tex);
|
|
row++;
|
|
|
|
state.pvp = drawCheckbox(ctx, "Player vs Player",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.pvp, true, winH, tex);
|
|
row++;
|
|
|
|
state.trustPlayers = drawCheckbox(ctx, "Trust Players",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.trustPlayers, true, winH, tex);
|
|
row++;
|
|
|
|
state.fireSpreads = drawCheckbox(ctx, "Fire Spreads",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.fireSpreads, true, winH, tex);
|
|
row++;
|
|
|
|
state.tntExplodes = drawCheckbox(ctx, "TNT Explodes",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.tntExplodes, true, winH, tex);
|
|
row++;
|
|
|
|
state.hostPrivileges = drawCheckbox(ctx, "Host Privileges",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.hostPrivileges, true, winH, tex);
|
|
row++;
|
|
|
|
state.resetNether = drawCheckbox(ctx, "Reset Nether",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.resetNether, true, winH, tex);
|
|
row++;
|
|
|
|
state.generateStructures = drawCheckbox(ctx, "Generate Structures",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.generateStructures, true, winH, tex);
|
|
row++;
|
|
|
|
state.superflatWorld = drawCheckbox(ctx, "Superflat World",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.superflatWorld, true, winH, tex);
|
|
row++;
|
|
|
|
state.bonusChest = drawCheckbox(ctx, "Bonus Chest",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.bonusChest, true, winH, tex);
|
|
} else {
|
|
int row = 0;
|
|
|
|
float fieldH = FIELD_H * scaleY;
|
|
|
|
drawLabel(ctx, "Seed for the World Generator", rowX, baseY + step * (float)row, rowW, winH);
|
|
row++;
|
|
|
|
drawTextInput(ctx, state.seed, rowX, baseY + step * (float)row, rowW, fieldH, false, winH);
|
|
row++;
|
|
|
|
char sizeLabel[64];
|
|
snprintf(sizeLabel, sizeof(sizeLabel), "World Size: %s", WORLD_SIZE_LABELS[state.worldSize]);
|
|
state.worldSize = drawSlider(ctx, sizeLabel,
|
|
rowX, baseY + step * (float)row, rowW, BUTTON_H * scaleY,
|
|
state.worldSize, 0, 3, winH, tex);
|
|
row++;
|
|
|
|
state.disableSaving = drawCheckbox(ctx, "Disable Saving",
|
|
rowX, baseY + step * (float)row, rowW, rowH,
|
|
state.disableSaving, true, winH, tex);
|
|
}
|
|
|
|
drawControllerPrompts(ctx, winW, winH, tex);
|
|
}
|
|
nk_end(ctx);
|
|
|
|
popCleanStyle(ctx);
|
|
|
|
return result;
|
|
}
|
|
|
|
}}
|