diff --git a/doc/en/scripting/builtins/libhud.md b/doc/en/scripting/builtins/libhud.md index b823ab50..4beb5d93 100644 --- a/doc/en/scripting/builtins/libhud.md +++ b/doc/en/scripting/builtins/libhud.md @@ -7,7 +7,11 @@ hud.open_inventory() -- Close inventory. hud.close_inventory() --- Open block UI and inventory. +-- Open UI and inventory. +-- Throws an exception if has no UI layout. +hud.open(invid: int, layoutid: str) + +-- Open block UI and inventory. -- Throws an exception if block has no UI layout. -- Returns block inventory ID (if *"inventory-size"=0* a virtual -- inventory will be created), and UI layout ID. diff --git a/doc/en/scripting/builtins/libinventory.md b/doc/en/scripting/builtins/libinventory.md index a719878a..344840f1 100644 --- a/doc/en/scripting/builtins/libinventory.md +++ b/doc/en/scripting/builtins/libinventory.md @@ -40,12 +40,18 @@ inventory.bind_block(invid: int, x: int, y: int, z: int) -- Unbind inventory from the specified block. inventory.unbind_block(x: int, y: int, z: int) + +-- Remove inventory. +inventory.remove(invid: int) ``` > [!WARNING] > Unbound inventories will be deleted on world close. ```lua +-- Create inventory. Returns the created ID. +inventory.create(size: int) -> int + -- Create inventory copy. Returns the created copy ID. inventory.clone(invid: int) -> int diff --git a/doc/ru/scripting/builtins/libhud.md b/doc/ru/scripting/builtins/libhud.md index cba34dee..ae5a69c3 100644 --- a/doc/ru/scripting/builtins/libhud.md +++ b/doc/ru/scripting/builtins/libhud.md @@ -7,7 +7,11 @@ hud.open_inventory() -- Закрывает инвентарь. hud.close_inventory() --- Открывает инвентарь и UI блока. +-- Открывает инвентарь и UI. +-- Если не имеет макета UI - бросается исключение. +hud.open(invid: int, layoutid: str) + +-- Открывает инвентарь и UI блока. -- Если блок не имеет макета UI - бросается исключение. -- Возвращает id инвентаря блока -- (при *"inventory-size"=0* создаётся виртуальный инвентарь, diff --git a/doc/ru/scripting/builtins/libinventory.md b/doc/ru/scripting/builtins/libinventory.md index 4d937358..01ecc5cc 100644 --- a/doc/ru/scripting/builtins/libinventory.md +++ b/doc/ru/scripting/builtins/libinventory.md @@ -23,7 +23,7 @@ inventory.set( count: int ) --- Возращает размер инвентаря (число слотов). +-- Возвращает размер инвентаря (число слотов). -- Если указанного инвентаря не существует, бросает исключение. inventory.size(invid: int) -> int @@ -47,13 +47,19 @@ inventory.bind_block(invid: int, x: int, y: int, z: int) -- Отвязывает инвентарь от блока. inventory.unbind_block(x: int, y: int, z: int) + +-- Удаляет инвентарь. +inventory.remove(invid: int) ``` > [!WARNING] > Инвентари, не привязанные ни к одному из блоков, удаляются при выходе из мира. ```lua --- Создает копию инвентаря и возвращает id копии. +-- Создаёт инвентарь и возвращает id. +inventory.create(size: int) -> int + +-- Создает копию инвентаря и возвращает id копии. -- Если копируемого инвентаря не существует, возвращает 0. inventory.clone(invid: int) -> int @@ -62,5 +68,3 @@ inventory.clone(invid: int) -> int -- slotB будет выбран автоматически, если не указывать явно. inventory.move(invA: int, slotA: int, invB: int, slotB: int) ``` - - diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 0063fd46..fd418d0f 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -388,6 +388,39 @@ void Hud::openInventory() { add(HudElement(hud_element_mode::inventory_bound, nullptr, exchangeSlot, false)); } +void Hud::openInventory( + UiDocument* doc, + std::shared_ptr inv, + bool playerInventory +) { + if (inv == nullptr) { + // why try to open nox-existent inventory?? + return; + } + + if (isInventoryOpen()) { + closeInventory(); + } + auto level = frontend->getLevel(); + auto content = level->content; + secondInvView = std::dynamic_pointer_cast(doc->getRoot()); + if (secondInvView == nullptr) { + throw std::runtime_error("secondary UI root element must be 'inventory'"); + } + secondUI = secondInvView; + + if (playerInventory) { + openInventory(); + } else { + inventoryOpen = true; + } + if (inv == nullptr) { + inv = level->inventories->createVirtual(secondInvView->getSlotsCount()); + } + secondInvView->bind(inv, content); + add(HudElement(hud_element_mode::inventory_bound, doc, secondUI, false)); +} + void Hud::openInventory( glm::ivec3 block, UiDocument* doc, diff --git a/src/frontend/hud.hpp b/src/frontend/hud.hpp index 775681af..b184ddfc 100644 --- a/src/frontend/hud.hpp +++ b/src/frontend/hud.hpp @@ -102,6 +102,8 @@ class Hud : public util::ObjectsKeeper { std::shared_ptr inventoryView = nullptr; /// @brief Block inventory view std::shared_ptr blockUI = nullptr; + /// @brief Secondary inventory view + std::shared_ptr secondInvView = nullptr; /// @brief Position of the block open glm::ivec3 blockPos {}; /// @brief Id of the block open (used to detect block destruction or replacement) @@ -145,6 +147,16 @@ public: /// @brief Show player inventory in inventory-mode void openInventory(); + + /// @brief Show inventory in inventory-mode + /// @param doc ui layout + /// @param inv inventory + /// @param playerInventory show player inventory too + void openInventory( + UiDocument* doc, + std::shared_ptr inv, + bool playerInventory + ); /// @brief Show block inventory in inventory-mode /// @param block block position diff --git a/src/logic/scripting/lua/libs/libhud.cpp b/src/logic/scripting/lua/libs/libhud.cpp index 5df2e08c..17e1211a 100644 --- a/src/logic/scripting/lua/libs/libhud.cpp +++ b/src/logic/scripting/lua/libs/libhud.cpp @@ -36,6 +36,26 @@ static int l_close_inventory(lua::State*) { return 0; } +static int l_open(lua::State* L) { + auto invid = lua::tointeger(L, 1); + auto layoutid = lua::require_string(L, 2); + bool playerInventory = !lua::toboolean(L, 3); + + auto assets = engine->getAssets(); + auto layout = assets->get(layoutid); + if (layout == nullptr) { + throw std::runtime_error("there is no ui layout " + util::quote(layoutid)); + } + + hud->openInventory( + layout, + level->inventories->get(invid), + playerInventory + ); + + return 0; +} + static int l_open_block(lua::State* L) { auto x = lua::tointeger(L, 1); auto y = lua::tointeger(L, 2); @@ -154,6 +174,7 @@ static int l_set_debug_cheats(lua::State* L) { const luaL_Reg hudlib[] = { {"open_inventory", lua::wrap}, {"close_inventory", lua::wrap}, + {"open", lua::wrap}, {"open_block", lua::wrap}, {"open_permanent", lua::wrap}, {"show_overlay", lua::wrap}, diff --git a/src/logic/scripting/lua/libs/libinventory.cpp b/src/logic/scripting/lua/libs/libinventory.cpp index bc5abd47..a705c48b 100644 --- a/src/logic/scripting/lua/libs/libinventory.cpp +++ b/src/logic/scripting/lua/libs/libinventory.cpp @@ -109,6 +109,26 @@ static int l_inventory_unbind_block(lua::State* L) { return 0; } +static int l_inventory_create(lua::State* L) { + auto invsize = lua::tointeger(L, 1); + auto inv = level->inventories->create(invsize); + if (inv == nullptr) { + return lua::pushinteger(L, 0); + } + return lua::pushinteger(L, inv->getId()); +} + +static int l_inventory_remove(lua::State* L) { + auto invid = lua::tointeger(L, 1); + auto inv = get_inventory(invid); + if (inv == nullptr) { + return 0; + } + + level->inventories->remove(invid); + return 0; +} + static int l_inventory_clone(lua::State* L) { auto id = lua::tointeger(L, 1); auto clone = level->inventories->clone(id); @@ -145,5 +165,7 @@ const luaL_Reg inventorylib[] = { {"get_block", lua::wrap}, {"bind_block", lua::wrap}, {"unbind_block", lua::wrap}, + {"create", lua::wrap}, + {"remove", lua::wrap}, {"clone", lua::wrap}, {NULL, NULL}}; diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index 6cbab94c..a32fc8ba 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -13,7 +13,7 @@ Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos) { top = CHUNK_H; } -bool Chunk::isEmpty() { +bool Chunk::isEmpty() const { int id = -1; for (uint i = 0; i < CHUNK_VOL; i++) { if (voxels[i].id != id) { diff --git a/src/voxels/Chunk.hpp b/src/voxels/Chunk.hpp index 1b426c37..94011d40 100644 --- a/src/voxels/Chunk.hpp +++ b/src/voxels/Chunk.hpp @@ -44,7 +44,7 @@ public: Chunk(int x, int z); - bool isEmpty(); + bool isEmpty() const; void updateHeights(); diff --git a/src/window/Window.cpp b/src/window/Window.cpp index 2de948a3..d095778b 100644 --- a/src/window/Window.cpp +++ b/src/window/Window.cpp @@ -72,11 +72,9 @@ bool Window::isFocused() { void window_size_callback(GLFWwindow*, int width, int height) { if (width && height) { - if (Window::isFocused()) { - glViewport(0, 0, width, height); - Window::width = width; - Window::height = height; - } + glViewport(0, 0, width, height); + Window::width = width; + Window::height = height; if (!Window::isFullscreen() && !Window::isMaximized()) { Window::getSettings()->width.set(width);