From 14939a87010ab17425d73b53829aa22c17c96d79 Mon Sep 17 00:00:00 2001 From: LaG1924 Date: Tue, 22 Jun 2021 03:38:08 +0500 Subject: Added Settings UI --- cwd/assets/altcraft/scripts/init.lua | 27 +----- cwd/assets/altcraft/scripts/ui.lua | 138 +++++++++++++++++++++++++++++ cwd/assets/altcraft/ui/main-menu.rml | 3 +- cwd/assets/altcraft/ui/mc-styles.rcss | 6 +- cwd/assets/altcraft/ui/options-styles.rcss | 84 ++++++++++++++++++ cwd/assets/altcraft/ui/options.rml | 61 +++++++++++++ cwd/assets/altcraft/ui/pause.rml | 3 +- src/AssetManager.cpp | 2 - src/Plugin.cpp | 17 ++++ src/Render.cpp | 93 ++++++++++--------- src/Render.hpp | 10 --- 11 files changed, 361 insertions(+), 83 deletions(-) create mode 100644 cwd/assets/altcraft/scripts/ui.lua create mode 100644 cwd/assets/altcraft/ui/options-styles.rcss create mode 100644 cwd/assets/altcraft/ui/options.rml diff --git a/cwd/assets/altcraft/scripts/init.lua b/cwd/assets/altcraft/scripts/init.lua index bf7739e..c626375 100644 --- a/cwd/assets/altcraft/scripts/init.lua +++ b/cwd/assets/altcraft/scripts/init.lua @@ -14,6 +14,7 @@ function plugin.onLoad () con:LoadDocument("altcraft/ui/main-menu"):Show() con:LoadDocument("altcraft/ui/hud") con:LoadDocument("altcraft/ui/pause") + con:LoadDocument("altcraft/ui/options") end function plugin.onChangeState (newState) @@ -41,33 +42,11 @@ function plugin.onUnload () AC.LogInfo("AC Core unloaded") end -local function UpdateHud() - local doc = {} - for i,d in ipairs(rmlui.contexts["default"].documents) do - if d.title == "Playing" then - doc = d - end - end - - local playerEnt = AC.GetGameState():GetPlayer() - doc:GetElementById('dbg-pos').inner_rml = string.format("%.1f %.1f %.1f", playerEnt.pos.x, playerEnt.pos.y, playerEnt.pos.z) - - local selection = AC.GetGameState():GetSelectionStatus() - if selection.isBlockSelected then - doc:GetElementById('dbg-select-pos').inner_rml = tostring(selection.selectedBlock) - else - doc:GetElementById('dbg-select-pos').inner_rml = "" - end - - local player = AC.GetGameState():GetPlayerStatus() - local playerHp = string.format("%.0f", player.health) - doc:GetElementById('status-hp').inner_rml = playerHp - doc:GetElementById('status-hp-bar'):SetAttribute("value", playerHp) -end +require("altcraft/ui") function plugin.onTick (deltaTime) + UpdateUi() if AC.GetGameState() and AC.GetGameState():GetPlayer() and AC.GetGameState():GetTimeStatus().worldAge > 0 then - UpdateHud() -- local player = AC.GetGameState():GetPlayer() -- player.pos.x = player.pos.x + deltaTime * 0.5 diff --git a/cwd/assets/altcraft/scripts/ui.lua b/cwd/assets/altcraft/scripts/ui.lua new file mode 100644 index 0000000..c55436f --- /dev/null +++ b/cwd/assets/altcraft/scripts/ui.lua @@ -0,0 +1,138 @@ +local options = { + brightness = 0.2, + flight = false, + mouseSensetivity = 0.1, + renderDistance = 2, + resolutionScale = 1.0, + targetFps = 60, + vsync = false, + wireframe = false +} + +function OpenOptions(doc) + optionsReturnDocument = doc + local optionsDoc = {} + for i,d in ipairs(rmlui.contexts["default"].documents) do + if d.title == "Options" then + optionsDoc = d + end + end + doc:Hide() + optionsDoc:Show() + optionsDoc.style["background-color"] = doc.style["background-color"] +end + +function CloseOptions(doc) + for i, v in pairs(options) do + local input = doc:GetElementById(i) + if type(v) == "number" then + local val = input:GetAttribute("value") + if i == "targetFps" and val == 301 then + AC.Settings.WriteDouble(i, 10000) + else + AC.Settings.WriteDouble(i, tonumber(val)) + end + elseif type(v) == "boolean" then + local val = input:HasAttribute("checked") + AC.Settings.WriteBool(i, val) + end + end + AC.Settings.Save() + AC.SettingsUpdate() + + optionsReturnDocument:Show() + doc:Hide() +end + +function OptionsDefaultHandler(event) + local input = event.current_element.previous_sibling + local id = input:GetAttribute("id") + if input:GetAttribute("type") == "checkbox" then + if options[id] then + input:SetAttribute("checked", "") + else + input:RemoveAttribute("checked") + end + else + input:SetAttribute("value", options[id]) + end +end + +function UpdateUi() + local doc = {} + local uiDoc = {} + for i,d in ipairs(rmlui.contexts["default"].documents) do + if d.title == "Playing" then + doc = d + elseif d.title == "Options" then + uiDoc = d + end + end + + if AC.GetGameState() and AC.GetGameState():GetPlayer() and AC.GetGameState():GetTimeStatus().worldAge > 0 then + local playerEnt = AC.GetGameState():GetPlayer() + doc:GetElementById('dbg-pos').inner_rml = string.format("%.1f %.1f %.1f", playerEnt.pos.x, playerEnt.pos.y, playerEnt.pos.z) + + local selection = AC.GetGameState():GetSelectionStatus() + if selection.isBlockSelected then + doc:GetElementById('dbg-select-pos').inner_rml = tostring(selection.selectedBlock) + else + doc:GetElementById('dbg-select-pos').inner_rml = "" + end + + local player = AC.GetGameState():GetPlayerStatus() + local playerHp = string.format("%.0f", player.health) + doc:GetElementById('status-hp').inner_rml = playerHp + doc:GetElementById('status-hp-bar'):SetAttribute("value", playerHp) + end + + + local uiInit = optionsListenersAdded == nil + if uiInit then + AC.Settings.Load() + end + + for i,v in pairs(options) do + local input = uiDoc:GetElementById(i) + local span = input.next_sibling + + if uiInit then + span:AddEventListener("click", OptionsDefaultHandler, true) + + if type(v) == "number" then + local val = AC.Settings.ReadDouble(i, v) + input:SetAttribute("value", tostring(val)) + elseif type(v) == "boolean" then + local val = AC.Settings.ReadBool(i, v) + if val then + input:SetAttribute("checked", "") + else + input:RemoveAttribute("checked") + end + end + end + + if type(v) == "number" then + local val = input:GetAttribute("value") + if v == math.floor(v) and i ~= "resolutionScale" then + span.inner_rml = string.format("%d (%d)", math.floor(val), v) + if i == "targetFps" and val == 301 then + span.inner_rml = string.format("∞ (%d)", v) + end + else + span.inner_rml = string.format("%.2f (%.2f)", val, v) + end + elseif type(v) == "boolean" then + if v then + span.inner_rml = "(on)" + else + span.inner_rml = "(off)" + end + end + end + + if uiInit == true then + optionsListenersAdded = true + AC.SettingsUpdate() + end +end diff --git a/cwd/assets/altcraft/ui/main-menu.rml b/cwd/assets/altcraft/ui/main-menu.rml index e796b67..0aaac89 100644 --- a/cwd/assets/altcraft/ui/main-menu.rml +++ b/cwd/assets/altcraft/ui/main-menu.rml @@ -3,6 +3,7 @@ MainMenu + AltCraft @@ -14,7 +15,7 @@ AC.ConnectToServer( document:GetElementById('hostname'):GetAttribute('value'), document:GetElementById('username'):GetAttribute('value'))">Connect - Options... + diff --git a/cwd/assets/altcraft/ui/mc-styles.rcss b/cwd/assets/altcraft/ui/mc-styles.rcss index e6dba35..3549180 100644 --- a/cwd/assets/altcraft/ui/mc-styles.rcss +++ b/cwd/assets/altcraft/ui/mc-styles.rcss @@ -39,8 +39,10 @@ body { .mc-button:hover { background-color: #7e86bc; + color: #cfd69d; } .mc-button:disabled { - background-color: #393939; -} \ No newline at end of file + background-color: #2b2b2b; + color: #848484; +} diff --git a/cwd/assets/altcraft/ui/options-styles.rcss b/cwd/assets/altcraft/ui/options-styles.rcss new file mode 100644 index 0000000..fbfc685 --- /dev/null +++ b/cwd/assets/altcraft/ui/options-styles.rcss @@ -0,0 +1,84 @@ +.body-options { + background-color: transparent; +} + +form { + width: 70%; + display: block; + margin: 5% auto; + background-color: #211710; +} + +.option { + display: block; + background-color: #0f0b07; + margin: 1vh; + padding: 0.5vh; + font-size: 4vh; + text-align: center; +} + +label { + +} + +span { + +} + +span:hover { + color: #cfd69d; +} + +input { + background-color: #2c2c2c; + height: 4vh; + margin-right: 1vh; + margin-left: 1vh; +} + +input.checkbox { + border-width: 1vh; + border-color: #2c2c2c; +} + +input.checkbox:checked { + background-color: #dcdadc; +} + +input.checkbox:hover { + border-color: #6a6b70; +} + +input.range:hover { + background-color: #6a6b70; +} + +input.range sliderbar { + width: 3vh; + background-color: #9c9c9c; +} + +input.range:hover sliderbar { + background-color: #e9e7e8; +} + +input.range sliderbar:active { + background-color: #cfd69d; +} + +input.range sliderarrowdec { + display: none; +} + +input.range sliderarrowinc { + display: none; +} + +#done { + display: block; + width: 45%; + height: 8%; + position: fixed; + margin: 5% auto auto; +} diff --git a/cwd/assets/altcraft/ui/options.rml b/cwd/assets/altcraft/ui/options.rml new file mode 100644 index 0000000..485dcba --- /dev/null +++ b/cwd/assets/altcraft/ui/options.rml @@ -0,0 +1,61 @@ + + + + + + Options + + +
+
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + +
+ +
+ + +
diff --git a/cwd/assets/altcraft/ui/pause.rml b/cwd/assets/altcraft/ui/pause.rml index 2e366f8..5d652f9 100644 --- a/cwd/assets/altcraft/ui/pause.rml +++ b/cwd/assets/altcraft/ui/pause.rml @@ -2,6 +2,7 @@ + Paused @@ -9,7 +10,7 @@ Advancements Statistics - Options... + diff --git a/src/AssetManager.cpp b/src/AssetManager.cpp index 8528a1b..7bcfaae 100644 --- a/src/AssetManager.cpp +++ b/src/AssetManager.cpp @@ -433,8 +433,6 @@ void ParseAssetScript(AssetTreeNode &node) { node.asset = std::make_unique(); AssetScript *asset = dynamic_cast(node.asset.get()); asset->code = std::string((char*)node.data.data(), (char*)node.data.data() + node.data.size()); - node.data.clear(); - node.data.shrink_to_fit(); } void ParseBlockModels() { diff --git a/src/Plugin.cpp b/src/Plugin.cpp index f518957..e3188e6 100644 --- a/src/Plugin.cpp +++ b/src/Plugin.cpp @@ -10,6 +10,7 @@ #include "Game.hpp" #include "Event.hpp" #include "AssetManager.hpp" +#include "Settings.hpp" struct Plugin { @@ -103,6 +104,10 @@ namespace PluginApi { void SetStatePlaying() { SetState(State::Playing); } + + void SettingsUpdate() { + PUSH_EVENT("SettingsUpdate", 0); + } } int LoadFileRequire(lua_State* L) { @@ -233,6 +238,7 @@ void PluginSystem::Init() { "skylight", &Dimension::skylight); sol::table apiTable = lua["AC"].get_or_create(); + sol::table apiSettings = lua["AC"]["Settings"].get_or_create(); apiTable["RegisterPlugin"] = PluginApi::RegisterPlugin; apiTable["LogWarning"] = PluginApi::LogWarning; @@ -245,6 +251,17 @@ void PluginSystem::Init() { apiTable["Exit"] = PluginApi::Exit; apiTable["Disconnect"] = PluginApi::Disconnect; apiTable["SetStatePlaying"] = PluginApi::SetStatePlaying; + apiSettings["Load"] = Settings::Load; + apiSettings["Save"] = Settings::Save; + apiSettings["Read"] = Settings::Read; + apiSettings["Write"] = Settings::Write; + apiSettings["ReadBool"] = Settings::ReadBool; + apiSettings["WriteBool"] = Settings::WriteBool; + apiSettings["ReaIntd"] = Settings::ReadInt; + apiSettings["WriteInt"] = Settings::WriteInt; + apiSettings["ReadDouble"] = Settings::ReadDouble; + apiSettings["WriteDouble"] = Settings::WriteDouble; + apiTable["SettingsUpdate"] = PluginApi::SettingsUpdate; } lua_State* PluginSystem::GetLuaState() { diff --git a/src/Render.cpp b/src/Render.cpp index c0885e3..bee8ffb 100644 --- a/src/Render.cpp +++ b/src/Render.cpp @@ -67,47 +67,11 @@ Render::Render(unsigned int windowWidth, unsigned int windowHeight, AssetManager::InitPostRml(); glCheckError(); - //Read settings - strcpy(fieldUsername, Settings::Read("username", "HelloOne").c_str()); - strcpy(fieldServerAddr, Settings::Read("serverAddr", "127.0.0.1").c_str()); - fieldDistance = Settings::ReadDouble("renderDistance", 2.0); - fieldTargetFps = Settings::ReadDouble("targetFps", 60.0); - fieldSensetivity = Settings::ReadDouble("mouseSensetivity", 0.1); - fieldVsync = Settings::ReadBool("vsync", false); - fieldWireframe = Settings::ReadBool("wireframe", false); - fieldFlight = Settings::ReadBool("flight", false); - fieldBrightness = Settings::ReadDouble("brightness", 0.2f); - fieldResolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); - - //Apply settings - if (fieldSensetivity != sensetivity) - sensetivity = fieldSensetivity; - isWireframe = fieldWireframe; - GetTime()->SetDelayLength(std::chrono::duration(1.0 / fieldTargetFps * 1000.0)); - if (fieldVsync) { - GetTime()->SetDelayLength(std::chrono::milliseconds(0)); - SDL_GL_SetSwapInterval(1); - } - else - SDL_GL_SetSwapInterval(0); - framebuffer->Resize(renderState.WindowWidth * fieldResolutionScale, renderState.WindowHeight * fieldResolutionScale); LOG(INFO) << "Supported threads: " << std::thread::hardware_concurrency(); } Render::~Render() { - Settings::Write("username", fieldUsername); - Settings::Write("serverAddr", fieldServerAddr); - Settings::WriteDouble("renderDistance", fieldDistance); - Settings::WriteDouble("targetFps", fieldTargetFps); - Settings::WriteDouble("mouseSensetivity", fieldSensetivity); - Settings::WriteBool("vsync", fieldVsync); - Settings::WriteBool("wireframe", fieldWireframe); - Settings::WriteBool("flight", fieldFlight); - Settings::WriteDouble("brightness", fieldBrightness); - Settings::WriteDouble("resolutionScale", fieldResolutionScale); - Settings::Save(); - Rml::RemoveContext("default"); rmlRender.reset(); rmlSystem.reset(); @@ -256,7 +220,8 @@ void Render::HandleEvents() { renderState.WindowHeight = height; rmlRender->Update(width, height); rmlContext->SetDimensions(Rml::Vector2i(width, height)); - framebuffer->Resize(width * fieldResolutionScale, height * fieldResolutionScale); + double resolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); + framebuffer->Resize(width * resolutionScale, height * resolutionScale); Framebuffer::GetDefault().Resize(width, height); break; } @@ -463,7 +428,7 @@ void Render::InitEvents() { listener.RegisterHandler("PlayerConnected", [this](const Event&) { stateString = "Loading terrain..."; world = std::make_unique(); - world->MaxRenderingDistance = fieldDistance; + world->MaxRenderingDistance = Settings::ReadDouble("renderDistance", 2.0f); PUSH_EVENT("UpdateSectionsRender", 0); }); @@ -471,9 +436,9 @@ void Render::InitEvents() { stateString = "Playing"; renderWorld = true; SetState(State::Playing); - glClearColor(0, 0, 0, 1.0f); - GetGameState()->GetPlayer()->isFlying = this->fieldFlight; - PUSH_EVENT("SetMinLightLevel", fieldBrightness); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + GetGameState()->GetPlayer()->isFlying = Settings::ReadBool("flight", false); + PUSH_EVENT("SetMinLightLevel", (float)Settings::ReadDouble("brightness", 0.2f)); }); listener.RegisterHandler("ConnectionFailed", [this](const Event& eventData) { @@ -481,7 +446,7 @@ void Render::InitEvents() { renderWorld = false; world.reset(); SetState(State::MainMenu); - glClearColor(0.8, 0.8, 0.8, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); }); listener.RegisterHandler("Disconnected", [this](const Event& eventData) { @@ -489,7 +454,7 @@ void Render::InitEvents() { renderWorld = false; world.reset(); SetState(State::MainMenu); - glClearColor(0.8, 0.8, 0.8, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); }); listener.RegisterHandler("Connecting", [this](const Event&) { @@ -535,6 +500,48 @@ void Render::InitEvents() { break; } }); + + listener.RegisterHandler("SettingsUpdate", [this](const Event& eventData) { + if (world) { + float renderDistance = Settings::ReadDouble("renderDistance", 2.0f); + if (renderDistance != world->MaxRenderingDistance) { + world->MaxRenderingDistance = renderDistance; + PUSH_EVENT("UpdateSectionsRender", 0); + } + } + + + float mouseSensetivity = Settings::ReadDouble("mouseSensetivity", 0.1f); + if (mouseSensetivity != sensetivity) + sensetivity = mouseSensetivity; + + if (GetGameState()) { + bool flight = Settings::ReadBool("flight", false); + GetGameState()->GetPlayer()->isFlying = flight; + } + + bool wireframe = Settings::ReadBool("wireframe", false); + isWireframe = wireframe; + + float targetFps = Settings::ReadDouble("targetFps", 60.0f); + GetTime()->SetDelayLength(std::chrono::duration(1.0 / targetFps * 1000.0)); + + bool vsync = Settings::ReadBool("vsync", false); + if (vsync) { + GetTime()->SetDelayLength(std::chrono::milliseconds(0)); + SDL_GL_SetSwapInterval(1); + } + else + SDL_GL_SetSwapInterval(0); + + float brightness = Settings::ReadDouble("brightness", 0.2f); + PUSH_EVENT("SetMinLightLevel", brightness); + + float resolutionScale = Settings::ReadDouble("resolutionScale", 1.0f); + int width, height; + SDL_GL_GetDrawableSize(window, &width, &height); + framebuffer->Resize(width * resolutionScale, height * resolutionScale); + }); } void Render::InitRml() { diff --git a/src/Render.hpp b/src/Render.hpp index a7b510a..4f993c3 100644 --- a/src/Render.hpp +++ b/src/Render.hpp @@ -40,16 +40,6 @@ class Render { std::vector chatMessages; EventListener listener; std::string stateString; - char fieldUsername[512]; - char fieldServerAddr[512]; - float fieldDistance; - float fieldSensetivity; - float fieldTargetFps; - bool fieldWireframe; - bool fieldVsync; - bool fieldFlight; - float fieldBrightness; - float fieldResolutionScale; std::unique_ptr rmlRender; std::unique_ptr rmlSystem; std::unique_ptr rmlFile; -- cgit v1.2.3