lua: hud library

This commit is contained in:
MihailRis 2024-02-16 13:57:03 +03:00
parent ffed4319da
commit 7e553efdec
14 changed files with 140 additions and 31 deletions

View File

@ -9,7 +9,3 @@ end
function inventory_share_func(invid, slotid) function inventory_share_func(invid, slotid)
inventory.set(invid, slotid, 0, 0) inventory.set(invid, slotid, 0, 0)
end end
function inventory_reposition()
return 10, gui.get_viewport()[2] - document.root.size[2] - 100
end

View File

@ -310,6 +310,11 @@ std::shared_ptr<Inventory> InventoryView::getInventory() const {
return inventory; return inventory;
} }
size_t InventoryView::getSlotsCount() const {
return slots.size();
}
void InventoryView::bind( void InventoryView::bind(
std::shared_ptr<Inventory> inventory, std::shared_ptr<Inventory> inventory,
LevelFrontend* frontend, LevelFrontend* frontend,

View File

@ -117,6 +117,8 @@ public:
std::shared_ptr<Inventory> getInventory() const; std::shared_ptr<Inventory> getInventory() const;
size_t getSlotsCount() const;
static void createReaders(gui::UiXmlReader& reader); static void createReaders(gui::UiXmlReader& reader);
static const int SLOT_INTERVAL = 4; static const int SLOT_INTERVAL = 4;

View File

@ -48,6 +48,7 @@
#include "../core_defs.h" #include "../core_defs.h"
#include "../items/ItemDef.h" #include "../items/ItemDef.h"
#include "../items/Inventory.h" #include "../items/Inventory.h"
#include "../items/Inventories.h"
#include "../logic/scripting/scripting.h" #include "../logic/scripting/scripting.h"
using namespace gui; using namespace gui;
@ -94,7 +95,7 @@ std::shared_ptr<gui::UINode> HudElement::getNode() const {
return node; return node;
} }
std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) { std::shared_ptr<UINode> Hud::createDebugPanel(Engine* engine) {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto panel = std::make_shared<Panel>(glm::vec2(250, 200), glm::vec4(5.0f), 2.0f); auto panel = std::make_shared<Panel>(glm::vec2(250, 200), glm::vec4(5.0f), 2.0f);
@ -204,7 +205,7 @@ std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
return panel; return panel;
} }
std::shared_ptr<InventoryView> HudRenderer::createContentAccess() { std::shared_ptr<InventoryView> Hud::createContentAccess() {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto content = level->content; auto content = level->content;
auto indices = content->getIndices(); auto indices = content->getIndices();
@ -234,7 +235,7 @@ std::shared_ptr<InventoryView> HudRenderer::createContentAccess() {
return view; return view;
} }
std::shared_ptr<InventoryView> HudRenderer::createHotbar() { std::shared_ptr<InventoryView> Hud::createHotbar() {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto player = level->player; auto player = level->player;
auto inventory = player->getInventory(); auto inventory = player->getInventory();
@ -250,7 +251,7 @@ std::shared_ptr<InventoryView> HudRenderer::createHotbar() {
return view; return view;
} }
HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend) Hud::Hud(Engine* engine, LevelFrontend* frontend)
: assets(engine->getAssets()), : assets(engine->getAssets()),
gui(engine->getGUI()), gui(engine->getGUI()),
frontend(frontend) frontend(frontend)
@ -300,7 +301,7 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend)
gui->add(grabbedItemView); gui->add(grabbedItemView);
} }
HudRenderer::~HudRenderer() { Hud::~Hud() {
// removing all controlled ui // removing all controlled ui
gui->remove(grabbedItemView); gui->remove(grabbedItemView);
for (auto& element : elements) { for (auto& element : elements) {
@ -312,13 +313,13 @@ HudRenderer::~HudRenderer() {
gui->remove(debugPanel); gui->remove(debugPanel);
} }
void HudRenderer::drawDebug(int fps){ void Hud::drawDebug(int fps){
this->fps = fps; this->fps = fps;
fpsMin = min(fps, fpsMin); fpsMin = min(fps, fpsMin);
fpsMax = max(fps, fpsMax); fpsMax = max(fps, fpsMax);
} }
void HudRenderer::update(bool visible) { void Hud::update(bool visible) {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto player = level->player; auto player = level->player;
auto menu = gui->getMenu(); auto menu = gui->getMenu();
@ -391,7 +392,7 @@ void HudRenderer::update(bool visible) {
/** /**
* Show inventory on the screen and turn on inventory mode blocking movement * Show inventory on the screen and turn on inventory mode blocking movement
*/ */
void HudRenderer::openInventory() { void Hud::openInventory() {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto player = level->player; auto player = level->player;
auto inventory = player->getInventory(); auto inventory = player->getInventory();
@ -404,17 +405,48 @@ void HudRenderer::openInventory() {
add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false)); add(HudElement(hud_element_mode::inventory_bound, inventoryDocument, inventoryView, false));
} }
/**
* Show player inventory + block UI
* @param block world position of the open block
* @param doc block UI document (root element must be an InventoryView)
* @param blockinv block inventory.
* In case of nullptr a new virtual inventory will be created
*/
void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inventory> blockinv) {
auto level = frontend->getLevel();
blockUI = std::dynamic_pointer_cast<InventoryView>(doc->getRoot());
if (blockUI == nullptr) {
throw std::runtime_error("block UI root element must be 'inventory'");
}
openInventory();
if (blockinv == nullptr) {
blockinv = level->inventories->createVirtual(blockUI->getSlotsCount());
}
blockUI->bind(blockinv, frontend, interaction.get());
add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false));
}
/** /**
* Hide inventory and turn off inventory mode * Hide inventory and turn off inventory mode
*/ */
void HudRenderer::closeInventory() { void Hud::closeInventory() {
auto level = frontend->getLevel();
inventoryOpen = false; inventoryOpen = false;
ItemStack& grabbed = interaction->getGrabbedItem(); ItemStack& grabbed = interaction->getGrabbedItem();
grabbed.clear(); grabbed.clear();
inventoryView = nullptr; inventoryView = nullptr;
if (blockUI) {
auto blockinv = blockUI->getInventory();
// todo: do it automatically
if (blockinv->isVirtual()) {
level->inventories->remove(blockinv->getId());
}
blockUI = nullptr;
}
} }
void HudRenderer::add(HudElement element) { void Hud::add(HudElement element) {
gui->add(element.getNode()); gui->add(element.getNode());
auto invview = std::dynamic_pointer_cast<InventoryView>(element.getNode()); auto invview = std::dynamic_pointer_cast<InventoryView>(element.getNode());
auto document = element.getDocument(); auto document = element.getDocument();
@ -429,7 +461,7 @@ void HudRenderer::add(HudElement element) {
elements.push_back(element); elements.push_back(element);
} }
void HudRenderer::remove(HudElement& element) { void Hud::remove(HudElement& element) {
auto document = element.getDocument(); auto document = element.getDocument();
if (document) { if (document) {
Inventory* inventory = nullptr; Inventory* inventory = nullptr;
@ -442,7 +474,7 @@ void HudRenderer::remove(HudElement& element) {
gui->remove(element.getNode()); gui->remove(element.getNode());
} }
void HudRenderer::draw(const GfxContext& ctx){ void Hud::draw(const GfxContext& ctx){
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto player = level->player; auto player = level->player;
@ -499,24 +531,24 @@ void HudRenderer::draw(const GfxContext& ctx){
contentAccessPanel->setCoord(glm::vec2(width-caWidth, 0)); contentAccessPanel->setCoord(glm::vec2(width-caWidth, 0));
glm::vec2 invSize = inventoryView->getSize(); glm::vec2 invSize = inventoryView->getSize();
//inventoryView->setCoord(glm::vec2( inventoryView->setCoord(glm::vec2(
// glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x), glm::min(width/2-invSize.x/2, width-caWidth-10-invSize.x),
// height/2-invSize.y/2 height/2-invSize.y/2
//)); ));
} }
grabbedItemView->setCoord(glm::vec2(Events::cursor)); grabbedItemView->setCoord(glm::vec2(Events::cursor));
batch->render(); batch->render();
} }
bool HudRenderer::isInventoryOpen() const { bool Hud::isInventoryOpen() const {
return inventoryOpen; return inventoryOpen;
} }
bool HudRenderer::isPause() const { bool Hud::isPause() const {
return pause; return pause;
} }
void HudRenderer::setPause(bool pause) { void Hud::setPause(bool pause) {
if (this->pause == pause) { if (this->pause == pause) {
return; return;
} }

View File

@ -16,6 +16,7 @@ class Player;
class Level; class Level;
class Engine; class Engine;
class SlotView; class SlotView;
class Inventory;
class InventoryView; class InventoryView;
class LevelFrontend; class LevelFrontend;
class UiDocument; class UiDocument;
@ -59,7 +60,7 @@ public:
} }
}; };
class HudRenderer { class Hud {
Assets* assets; Assets* assets;
std::unique_ptr<Camera> uicamera; std::unique_ptr<Camera> uicamera;
@ -83,13 +84,15 @@ class HudRenderer {
std::vector<HudElement> elements; std::vector<HudElement> elements;
std::shared_ptr<InventoryView> inventoryView = nullptr; std::shared_ptr<InventoryView> inventoryView = nullptr;
std::shared_ptr<InventoryView> blockUI = nullptr;
glm::ivec3 currentblock {};
std::shared_ptr<gui::UINode> createDebugPanel(Engine* engine); std::shared_ptr<gui::UINode> createDebugPanel(Engine* engine);
std::shared_ptr<InventoryView> createContentAccess(); std::shared_ptr<InventoryView> createContentAccess();
std::shared_ptr<InventoryView> createHotbar(); std::shared_ptr<InventoryView> createHotbar();
public: public:
HudRenderer(Engine* engine, LevelFrontend* frontend); Hud(Engine* engine, LevelFrontend* frontend);
~HudRenderer(); ~Hud();
void update(bool hudVisible); void update(bool hudVisible);
void draw(const GfxContext& context); void draw(const GfxContext& context);
@ -100,6 +103,7 @@ public:
void setPause(bool pause); void setPause(bool pause);
void openInventory(); void openInventory();
void openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptr<Inventory> blockInv);
void closeInventory(); void closeInventory();
void add(HudElement element); void add(HudElement element);

View File

@ -21,6 +21,7 @@
#include "../objects/Player.h" #include "../objects/Player.h"
#include "../logic/ChunksController.h" #include "../logic/ChunksController.h"
#include "../logic/LevelController.h" #include "../logic/LevelController.h"
#include "../logic/scripting/scripting_frontend.h"
#include "../voxels/Chunks.h" #include "../voxels/Chunks.h"
#include "../voxels/Chunk.h" #include "../voxels/Chunk.h"
#include "../engine.h" #include "../engine.h"
@ -87,7 +88,7 @@ LevelScreen::LevelScreen(Engine* engine, Level* level)
: Screen(engine), : Screen(engine),
level(level), level(level),
frontend(std::make_unique<LevelFrontend>(level, engine->getAssets())), frontend(std::make_unique<LevelFrontend>(level, engine->getAssets())),
hud(std::make_unique<HudRenderer>(engine, frontend.get())), hud(std::make_unique<Hud>(engine, frontend.get())),
worldRenderer(std::make_unique<WorldRenderer>(engine, frontend.get())), worldRenderer(std::make_unique<WorldRenderer>(engine, frontend.get())),
controller(std::make_unique<LevelController>(engine->getSettings(), level)) { controller(std::make_unique<LevelController>(engine->getSettings(), level)) {
@ -96,6 +97,7 @@ LevelScreen::LevelScreen(Engine* engine, Level* level)
animator.reset(new TextureAnimator()); animator.reset(new TextureAnimator());
animator->addAnimations(engine->getAssets()->getAnimations()); animator->addAnimations(engine->getAssets()->getAnimations());
scripting::on_frontend_init(hud.get());
} }
LevelScreen::~LevelScreen() { LevelScreen::~LevelScreen() {

View File

@ -7,7 +7,7 @@
class Assets; class Assets;
class Level; class Level;
class WorldRenderer; class WorldRenderer;
class HudRenderer; class Hud;
class Engine; class Engine;
class Camera; class Camera;
class Batch2D; class Batch2D;
@ -40,7 +40,7 @@ public:
class LevelScreen : public Screen { class LevelScreen : public Screen {
std::unique_ptr<Level> level; std::unique_ptr<Level> level;
std::unique_ptr<LevelFrontend> frontend; std::unique_ptr<LevelFrontend> frontend;
std::unique_ptr<HudRenderer> hud; std::unique_ptr<Hud> hud;
std::unique_ptr<WorldRenderer> worldRenderer; std::unique_ptr<WorldRenderer> worldRenderer;
std::unique_ptr<LevelController> controller; std::unique_ptr<LevelController> controller;
std::unique_ptr<TextureAnimator> animator; std::unique_ptr<TextureAnimator> animator;

View File

@ -33,6 +33,10 @@ void Inventories::store(std::shared_ptr<Inventory> inv) {
map[inv->getId()] = inv; map[inv->getId()] = inv;
} }
void Inventories::remove(int64_t id) {
map.erase(id);
}
std::shared_ptr<Inventory> Inventories::get(int64_t id) { std::shared_ptr<Inventory> Inventories::get(int64_t id) {
auto found = map.find(id); auto found = map.find(id);
if (found == map.end()) if (found == map.end())

View File

@ -30,6 +30,9 @@ public:
/* Store inventory */ /* Store inventory */
void store(std::shared_ptr<Inventory> inv); void store(std::shared_ptr<Inventory> inv);
/* Remove inventory from map */
void remove(int64_t id);
/* Get inventory by id (works with both real and virtual)*/ /* Get inventory by id (works with both real and virtual)*/
std::shared_ptr<Inventory> get(int64_t id); std::shared_ptr<Inventory> get(int64_t id);

View File

@ -0,0 +1,20 @@
#include "libhud.h"
#include <iostream>
#include "../scripting.h"
#include "../../../frontend/hud.h"
namespace scripting {
extern Hud* hud;
}
int l_hud_open_inventory(lua_State* L) {
scripting::hud->openInventory();
return 0;
}
int l_hud_close_inventory(lua_State* L) {
scripting::hud->closeInventory();
return 0;
}

View File

@ -0,0 +1,15 @@
#ifndef LOGIC_SCRIPTING_API_LIBHUD_H_
#define LOGIC_SCRIPTING_API_LIBHUD_H_
#include <lua.hpp>
extern int l_hud_open_inventory(lua_State* L);
extern int l_hud_close_inventory(lua_State* L);
static const luaL_Reg hudlib [] = {
{"open_inventory", l_hud_open_inventory},
{"close_inventory", l_hud_close_inventory},
{NULL, NULL}
};
#endif // LOGIC_SCRIPTING_API_LIBHUD_H_

View File

@ -7,8 +7,6 @@
namespace fs = std::filesystem; namespace fs = std::filesystem;
class LuaState;
class Engine; class Engine;
class Content; class Content;
struct ContentPack; struct ContentPack;

View File

@ -0,0 +1,16 @@
#include "scripting_frontend.h"
#include "scripting.h"
#include "api/libhud.h"
#include "LuaState.h"
namespace scripting {
extern lua::LuaState* state;
}
Hud* scripting::hud = nullptr;
void scripting::on_frontend_init(Hud* hud) {
scripting::hud = hud;
scripting::state->openlib("hud", hudlib, 0);
}

View File

@ -0,0 +1,12 @@
#ifndef LOGIC_SCRIPTING_SCRIPTING_FRONTEND_H_
#define LOGIC_SCRIPTING_SCRIPTING_FRONTEND_H_
class Hud;
namespace scripting {
extern Hud* hud;
void on_frontend_init(Hud* hud);
}
#endif // LOGIC_SCRIPTING_SCRIPTING_FRONTEND_H_