diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index d6cdc984..49305281 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -51,6 +51,14 @@ #include "../items/Inventories.h" #include "../logic/scripting/scripting.h" + +// implemented in debug_panel.cpp +extern std::shared_ptr create_debug_panel( + Engine* engine, + Level* level, + Player* player +); + HudElement::HudElement( hud_element_mode mode, UiDocument* document, @@ -130,12 +138,6 @@ std::shared_ptr Hud::createHotbar() { return view; } -extern std::shared_ptr create_debug_panel( - Engine* engine, - Level* level, - Player* player -); - Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player) : engine(engine), assets(engine->getAssets()), @@ -320,6 +322,7 @@ void Hud::openInventory( if (blockUI == nullptr) { throw std::runtime_error("block UI root element must be 'inventory'"); } + secondUI = blockUI; if (playerInventory) { openInventory(); } else { @@ -334,7 +337,20 @@ void Hud::openInventory( currentblockid = level->chunks->get(block.x, block.y, block.z)->id; add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false)); } - + +void Hud::showOverlay(UiDocument* doc, bool playerInventory) { + if (isInventoryOpen()) { + closeInventory(); + } + secondUI = doc->getRoot(); + if (playerInventory) { + openInventory(); + } else { + inventoryOpen = true; + } + add(HudElement(hud_element_mode::inventory_bound, doc, secondUI, false)); +} + /// @brief Add element as permanent overlay /// @param doc element layout document void Hud::openPermanent(UiDocument* doc) { @@ -365,6 +381,7 @@ void Hud::closeInventory() { } blockUI = nullptr; } + secondUI = nullptr; } void Hud::add(HudElement element) { @@ -471,7 +488,7 @@ void Hud::draw(const GfxContext& ctx){ contentAccessPanel->setCoord(glm::vec2(width-caWidth, 0)); glm::vec2 invSize = inventoryView ? inventoryView->getSize() : glm::vec2(); - if (blockUI == nullptr) { + if (secondUI == nullptr) { if (inventoryView) { inventoryView->setCoord(glm::vec2( glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x), @@ -479,7 +496,7 @@ void Hud::draw(const GfxContext& ctx){ )); } } else { - glm::vec2 blockInvSize = blockUI->getSize(); + glm::vec2 blockInvSize = secondUI->getSize(); float invwidth = glm::max(invSize.x, blockInvSize.x); int interval = invSize.y > 0.0 ? 5 : 0; float totalHeight = invSize.y + blockInvSize.y + interval; @@ -489,7 +506,7 @@ void Hud::draw(const GfxContext& ctx){ height/2+totalHeight/2-invSize.y )); } - blockUI->setCoord(glm::vec2( + secondUI->setCoord(glm::vec2( glm::min(width/2-invwidth/2, width-caWidth-10-invwidth), height/2-totalHeight/2 )); diff --git a/src/frontend/hud.h b/src/frontend/hud.h index 3940f0fb..1cae1c5c 100644 --- a/src/frontend/hud.h +++ b/src/frontend/hud.h @@ -70,22 +70,39 @@ class Hud { LevelFrontend* frontend; Player* player; + /// @brief Is any overlay/inventory open bool inventoryOpen = false; + /// @brief Is pause mode on bool pause = false; + /// @brief Content access panel scroll container std::shared_ptr contentAccessPanel; + /// @brief Content access panel itself std::shared_ptr contentAccess; + /// @brief Player inventory hotbar std::shared_ptr hotbarView; + /// @brief Debug info and control panel (F3 key) std::shared_ptr debugPanel; + /// @brief Overlay used in pause mode std::shared_ptr darkOverlay; + /// @brief Inventories interaction agent (grabbed item and other info) std::unique_ptr interaction; + /// @brief Grabbed item visual element std::shared_ptr grabbedItemView; + /// @brief List of all controlled hud elements std::vector elements; + /// @brief Player inventory view std::shared_ptr inventoryView = nullptr; + /// @brief Block inventory view std::shared_ptr blockUI = nullptr; + /// @brief Position of the block open glm::ivec3 currentblock {}; + /// @brief Id of the block open (used to detect block destruction or replacement) blockid_t currentblockid = 0; + + /// @brief UI element will be dynamicly positioned near to inventory or in screen center + std::shared_ptr secondUI = nullptr; std::shared_ptr createContentAccess(); std::shared_ptr createHotbar(); @@ -98,13 +115,35 @@ public: void update(bool hudVisible); void draw(const GfxContext& context); + /// @brief Check if inventory mode on bool isInventoryOpen() const; + + /// @brief Check if pause mode on bool isPause() const; + + /// @brief Enable/disable pause mode void setPause(bool pause); + /// @brief Show player inventory in inventory-mode void openInventory(); + + /// @brief Show block inventory in inventory-mode + /// @param block block position + /// @param doc block ui layout + /// @param blockInv block inventory + /// @param playerInventory show player inventory too void openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr blockInv, bool playerInventory); + + /// @brief Show element in inventory-mode + /// @param doc element layout + /// @param playerInventory show player inventory too + void showOverlay(UiDocument* doc, bool playerInventory); + + /// @brief Close all open inventories and overlay void closeInventory(); + + /// @brief Add element will be visible until removed + /// @param doc element layout void openPermanent(UiDocument* doc); void add(HudElement element); @@ -114,4 +153,4 @@ public: Player* getPlayer() const; }; -#endif /* SRC_HUD_H_ */ +#endif // SRC_HUD_H_ diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index 85567d75..971b4931 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -65,6 +65,19 @@ static int l_hud_open_block(lua_State* L) { return 2; } +static int l_hud_show_overlay(lua_State* L) { + const char* name = lua_tostring(L, 1); + bool playerInventory = lua_toboolean(L, 2); + + auto assets = scripting::engine->getAssets(); + auto layout = assets->getLayout(name); + if (layout == nullptr) { + luaL_error(L, "there is no ui layout '%s'", name); + } + scripting::hud->showOverlay(layout, playerInventory); + return 0; +} + static UiDocument* require_layout(lua_State* L, const char* name) { auto assets = scripting::engine->getAssets(); auto layout = assets->getLayout(name); @@ -91,6 +104,7 @@ const luaL_Reg hudlib [] = { {"close_inventory", lua_wrap_errors}, {"open_block", lua_wrap_errors}, {"open_permanent", lua_wrap_errors}, + {"show_overlay", lua_wrap_errors}, {"close", lua_wrap_errors}, {NULL, NULL} };