Merge branch 'feat-inventory-enhancements' into feat-inventory-enhancements-p2

This commit is contained in:
neveix 2026-08-14 01:18:31 +05:00
commit 871326555d
20 changed files with 114 additions and 123 deletions

View file

@ -174,6 +174,15 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
gui,
"<container size='4000' color='#00000080' z-index='-1' visible='false'/>"
);
inventoryDropArea = guiutil::create(
gui,
R"(<container size='4000' color='#00000000' z-index='-1' visible='false'
onclick='events.emit(\"core:drop_outside_inventory\", 0)'
onrightclick='events.emit(\"core:drop_outside_inventory\", 1)'
onmiddleclick='events.emit(\"core:drop_outside_inventory\", 2)'
/>)"
);
uicamera = std::make_unique<Camera>(glm::vec3(), 1);
uicamera->perspective = false;
@ -188,6 +197,7 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
gui.add(debugPanel);
gui.add(darkOverlay);
gui.add(inventoryDropArea);
gui.add(hotbarView);
gui.add(contentAccessPanel);
@ -213,6 +223,7 @@ Hud::~Hud() {
}
gui.remove(hotbarView);
gui.remove(darkOverlay);
gui.remove(inventoryDropArea);
gui.remove(contentAccessPanel);
gui.remove(debugPanel);
}
@ -358,6 +369,7 @@ void Hud::update(bool visible) {
contentAccess->setMinSize(glm::vec2(1, windowSize.y));
hotbarView->setVisible(visible && !(secondUI && !inventoryView));
darkOverlay->setVisible(isMenuOpen);
inventoryDropArea->setVisible(inventoryOpen);
menu.setVisible(isMenuOpen);
if (visible) {
@ -739,6 +751,10 @@ std::shared_ptr<Inventory> Hud::getSecondInventory() {
return nullptr;
}
std::shared_ptr<Inventory> Hud::getExchangeInventory() {
return exchangeSlotInv;
}
bool Hud::isContentAccess() const {
return showContentPanel;
}

View file

@ -93,6 +93,8 @@ class Hud : public util::ObjectsKeeper {
std::shared_ptr<gui::UINode> debugPanel;
/// @brief Overlay used in pause mode
std::shared_ptr<gui::UINode> darkOverlay;
/// @brief Overlay used in inventory
std::shared_ptr<gui::UINode> inventoryDropArea;
/// @brief Inventories interaction agent (grabbed item)
std::shared_ptr<gui::SlotView> exchangeSlot;
/// @brief Exchange slot inventory (1 slot only)
@ -207,6 +209,8 @@ public:
std::shared_ptr<Inventory> getSecondInventory();
std::shared_ptr<Inventory> getExchangeInventory();
bool isContentAccess() const;
void setContentAccess(bool flag);

View file

@ -178,8 +178,6 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) {
}
it = mouseOver.erase(it);
}
bool focusHappened = false;
if (input.jclicked(Mousecode::BUTTON_1)) {
if (pressed == nullptr && this->hover) {
@ -197,10 +195,10 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) {
if (focus != pressed) {
focus = pressed;
focus->onFocus();
focusHappened = true;
return;
}
}
if (this->hover == nullptr && focus && !focusHappened) {
if (this->hover == nullptr && focus) {
focus->defocus();
focus = nullptr;
}
@ -209,44 +207,13 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) {
pressed = nullptr;
}
if (hover && !focusHappened) {
if (hover) {
for (Mousecode code : MOUSECODES_ALL) {
if (input.jclicked(code)) {
hover->clicked(code);
}
}
}
performClickOutside(frame, delta, cursorPos);
}
void GUI::performClickOutside(Frame& frame, float delta, glm::vec2 cursorPos) {
auto nodes = frame.getNodes();
std::vector<std::shared_ptr<UINode>> activeNodes;
for (const auto& node : nodes) {
if (node && node->isVisible() && node->isInteractive()) {
activeNodes.push_back(node);
}
}
for (Mousecode code : {Mousecode::BUTTON_1, Mousecode::BUTTON_2, Mousecode::BUTTON_3}) {
if (input.jclicked(code)) {
bool isOverAnyNode = false;
for (const auto& node : activeNodes) {
if (node && node->isInside(cursorPos)) {
isOverAnyNode = true;
break;
}
}
if (!isOverAnyNode) {
for (const auto& node : activeNodes) {
if (node) {
node->clickedOutside(code);
}
}
}
}
}
}
void GUI::actFocused() {

View file

@ -2,6 +2,7 @@
#include "delegates.hpp"
#include <set>
#include <queue>
#include <memory>
#include <vector>
@ -92,7 +93,6 @@ namespace gui {
bool debug = false;
void actMouse(Frame& frame, float delta, const CursorState& cursor);
void performClickOutside(Frame& frame, float delta, glm::vec2 cursorPos);
void actFocused();
void updateTooltip(float delta);
void resetTooltip();

View file

@ -18,7 +18,6 @@
#include "graphics/ui/GUI.hpp"
#include "items/Inventory.hpp"
#include "items/ItemDef.hpp"
#include "items/ItemStack.hpp"
#include "logic/scripting/scripting.hpp"
#include "maths/voxmaths.hpp"
#include "objects/Player.hpp"
@ -615,33 +614,6 @@ void InventoryView::setPos(const glm::vec2& pos) {
Container::setPos(pos - origin);
}
void InventoryView::clickedOutside(Mousecode button) {
// root is the id of the main inventory
if (getId() != "root") {
return;
}
int mode;
if (button == Mousecode::BUTTON_1) {
mode = 0;
} else if (button == Mousecode::BUTTON_2) {
mode = 1;
} else if (button == Mousecode::BUTTON_3) {
mode = 2;
} else {
return;
};
auto exchangeSlot = std::dynamic_pointer_cast<SlotView>(
gui.get(SlotView::EXCHANGE_SLOT_NAME));
if (exchangeSlot == nullptr) {
return;
}
ItemStack& grabbed = exchangeSlot->getStack();
if (grabbed.isEmpty()) {
return;
}
scripting::on_inventory_clicked_outside(exchangeSlot->getInventoryId(), 0, mode);
}
void InventoryView::setOrigin(const glm::vec2& origin) {
this->origin = origin;
}

View file

@ -143,8 +143,6 @@ namespace gui {
void setSelected(int index);
void clickedOutside(Mousecode button) override;
void bind(
const std::shared_ptr<Inventory>& inventory,
const Content* content

View file

@ -13,6 +13,7 @@
#include "window/Window.hpp"
#include "../GUI.hpp"
// TODO: remove
// TODO: remove
#include <GL/glew.h>
@ -24,8 +25,7 @@ ModelViewer::ModelViewer(
: Container(gui, size),
modelName(modelName),
camera(),
batch(std::make_unique<Batch3D>(1024)),
fbo(std::make_unique<Framebuffer>(size.x, size.y)) {
batch(std::make_unique<Batch3D>(1024)) {
camera.perspective = true;
camera.position = glm::vec3(2, 2, 2);
}
@ -115,7 +115,13 @@ void ModelViewer::draw(const DrawContext& pctx, const Assets& assets) {
return;
}
auto& prevShader = Shader::getUsed();
if (!fbo) {
if (size.x <= 0 || size.y <= 0) {
return;
}
fbo = std::make_unique<Framebuffer>(size.x, size.y);
}
fbo->resize(size.x, size.y);
{
glDisable(GL_SCISSOR_TEST);
@ -154,6 +160,13 @@ void ModelViewer::draw(const DrawContext& pctx, const Assets& assets) {
Container::draw(pctx, assets);
}
void ModelViewer::setVisible(bool flag) {
if (!flag && fbo) {
fbo.reset();
}
Container::setVisible(flag);
}
void ModelViewer::setCenter(const glm::vec3& center) {
this->center = center;
}

View file

@ -23,7 +23,6 @@ namespace gui {
bool grabbing = false;
public:
ModelViewer(GUI& gui, const glm::vec2& size, const std::string& modelName);
~ModelViewer();
void setModel(const std::string& modelName);
@ -34,6 +33,7 @@ namespace gui {
void act(float delta) override;
void draw(const DrawContext& pctx, const Assets& assets) override;
void setVisible(bool flag) override;
void setRotation(const glm::vec3& euler);
void setCenter(const glm::vec3& center);

View file

@ -79,6 +79,8 @@ void UINode::click(int, int) {
void UINode::clicked(Mousecode button) {
if (button == Mousecode::BUTTON_2) {
actions.notify(UIAction::RIGHT_CLICK, gui);
} else if (button == Mousecode::BUTTON_3) {
actions.notify(UIAction::MIDDLE_CLICK, gui);
}
}

View file

@ -58,6 +58,7 @@ namespace gui {
FOCUS,
DEFOCUS,
RIGHT_CLICK,
MIDDLE_CLICK,
MOUSE_OVER,
MOUSE_OUT,
MOUSE_ENTER,
@ -207,9 +208,6 @@ namespace gui {
virtual void onFocus();
virtual void doubleClick(int x, int y);
virtual void click(int x, int y);
virtual void clickedOutside(Mousecode button) {
// Empty for all UINodes, except InventoryView
}
virtual void clicked(Mousecode button);
virtual void mouseMove(int x, int y) {};
virtual void mouseRelease(int x, int y);

View file

@ -181,6 +181,7 @@ static void read_uinode(
register_action(node, reader, element, "onclick", UIAction::CLICK);
register_action(node, reader, element, "onrightclick", UIAction::RIGHT_CLICK);
register_action(node, reader, element, "onmiddleclick", UIAction::MIDDLE_CLICK);
register_action(node, reader, element, "onfocus", UIAction::FOCUS);
register_action(node, reader, element, "ondefocus", UIAction::DEFOCUS);
register_action(node, reader, element, "ondoubleclick", UIAction::DOUBLE_CLICK);

View file

@ -1127,6 +1127,7 @@ static int l_gui_load_document(lua::State* L) {
}
auto env = scripting::create_doc_environment(parentEnv, alias);
auto envId = *env;
// namespace extension
if (lua::istable(L, 4)) {
if (lua::get_from(L, "table", "extend")) {
@ -1148,7 +1149,7 @@ static int l_gui_load_document(lua::State* L) {
engine->requireAssets().store(std::move(documentPtr), alias);
scripting::on_ui_open(*document, {args});
return 0;
return lua::pushenv(L, envId);
}
static int l_set_syntax_styles(lua::State* L) {

View file

@ -149,6 +149,15 @@ static int l_get_second_inventory(lua::State* L) {
}
}
static int l_get_exchange_inventory(lua::State* L) {
auto inventory = hud->getExchangeInventory();
if (inventory == nullptr) {
return lua::pushinteger(L, 0);
} else {
return lua::pushinteger(L, inventory->getId());
}
}
static int l_get_player(lua::State* L) {
auto player = hud->getPlayer();
return lua::pushinteger(L, player->getId());
@ -216,6 +225,7 @@ const luaL_Reg hudlib[] = {
{"show_overlay", wrap_hud<l_show_overlay>},
{"get_block_inventory", wrap_hud<l_get_block_inventory>},
{"get_second_inventory", wrap_hud<l_get_second_inventory>},
{"get_exchange_inventory", wrap_hud<l_get_exchange_inventory>},
{"close", wrap_hud<l_close>},
{"pause", wrap_hud<l_pause>},
{"resume", wrap_hud<l_resume>},