diff --git a/res/layouts/inventory.xml b/res/layouts/inventory.xml index dd1fe8c6..90279abd 100644 --- a/res/layouts/inventory.xml +++ b/res/layouts/inventory.xml @@ -1,4 +1,4 @@ - + diff --git a/res/layouts/inventory.xml.lua b/res/layouts/inventory.xml.lua new file mode 100644 index 00000000..707a516c --- /dev/null +++ b/res/layouts/inventory.xml.lua @@ -0,0 +1,7 @@ +function on_open() + print("OPEN") +end + +function on_close() + print("CLOSE") +end diff --git a/res/modules/toml.lua b/res/modules/toml.lua new file mode 100644 index 00000000..fb082e75 --- /dev/null +++ b/res/modules/toml.lua @@ -0,0 +1,65 @@ +-- TOML serialization module +local toml = {} + +-- Convert table to TOML +function toml.serialize(tb, isinner) + local text = "" + for k, v in pairs(tb) do + local tp = type(v) + if tp ~= "table" then + text = text..k.." = " + if tp == "string" then + text = text..string.format("%q", v) + else + text = text..tostring(v) + end + text = text.."\n" + end + end + for k, v in pairs(tb) do + local tp = type(v) + if tp == "table" then + if isinner then + error("only one level of subtables supported") + end + text = text.."["..k.."]\n"..toml.serialize(v).."\n" + end + end + return text +end + +-- Parse TOML to new table +function toml.deserialize(s) + local output = {} + local current = output + local lines = {} + for line in string.gmatch(s, "[^\r\n]+") do + line = string.gsub(line, "%s+", "") + table.insert(lines, line) + end + for i = 1,#lines do + local s = lines[i] + if string.sub(s, 1, 1) == "[" then + local section = s.sub(s, 2, #s-1) + current = {} + output[section] = current + else + for k, v in string.gmatch(s, "(%w+)=(.+)" ) do + v = string.gsub(v, "%s+", "") + if v.sub(v, 1, 1) == "\"" then + current[k] = v.sub(v, 2, #v-1) + elseif v == "true" or v == "false" then + current[k] = v == "true" + end + + local num = tonumber(v) + if num ~= nil then + current[k] = num + end + end + end + end + return output +end + +return toml diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 40bc500a..09d28f55 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -53,6 +53,16 @@ function load_script(path, nocache) return result end +function require(path) + local prefix, file = parse_path(path) + return load_script(prefix..":modules/"..file..".lua") +end + +function __reset_scripts_cache() + __cached_scripts = {} + __cached_results = {} +end + function sleep(timesec) local start = time.uptime() while time.uptime() - start < timesec do @@ -78,69 +88,6 @@ function dofile(path) return _dofile(path) end -toml = {} - --- Convert table to TOML -function toml.from_table(tb, isinner) - local text = "" - for k, v in pairs(tb) do - local tp = type(v) - if tp ~= "table" then - text = text..k.." = " - if tp == "string" then - text = text..string.format("%q", v) - else - text = text..tostring(v) - end - text = text.."\n" - end - end - for k, v in pairs(tb) do - local tp = type(v) - if tp == "table" then - if isinner then - error("only one level of subtables supported") - end - text = text.."["..k.."]\n"..toml.from_table(v).."\n" - end - end - return text -end - --- Parse TOML to new table -function toml.parse(s) - local output = {} - local current = output - local lines = {} - for line in string.gmatch(s, "[^\r\n]+") do - line = string.gsub(line, "%s+", "") - table.insert(lines, line) - end - for i = 1,#lines do - local s = lines[i] - if string.sub(s, 1, 1) == "[" then - local section = s.sub(s, 2, #s-1) - current = {} - output[section] = current - else - for k, v in string.gmatch(s, "(%w+)=(.+)" ) do - v = string.gsub(v, "%s+", "") - if v.sub(v, 1, 1) == "\"" then - current[k] = v.sub(v, 2, #v-1) - elseif v == "true" or v == "false" then - current[k] = v == "true" - end - - local num = tonumber(v) - if num ~= nil then - current[k] = num - end - end - end - end - return output -end - function pack.is_installed(packid) return file.isfile(packid..":package.json") end diff --git a/src/assets/Assets.h b/src/assets/Assets.h index fbe976de..87e94380 100644 --- a/src/assets/Assets.h +++ b/src/assets/Assets.h @@ -14,6 +14,12 @@ class Font; class Atlas; class UiDocument; +struct LayoutCfg { + int env; + + LayoutCfg(int env) : env(env) {} +}; + class Assets { std::unordered_map> textures; std::unordered_map> shaders; diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index 35babebc..0877564e 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -8,6 +8,8 @@ #include "../constants.h" #include "../files/engine_paths.h" +#include "../content/Content.h" +#include "../logic/scripting/scripting.h" AssetsLoader::AssetsLoader(Assets* assets, const ResPaths* paths) : assets(assets), paths(paths) { @@ -17,8 +19,8 @@ void AssetsLoader::addLoader(int tag, aloader_func func) { loaders[tag] = func; } -void AssetsLoader::add(int tag, const std::string filename, const std::string alias) { - entries.push(aloader_entry{ tag, filename, alias }); +void AssetsLoader::add(int tag, const std::string filename, const std::string alias, std::shared_ptr settings) { + entries.push(aloader_entry{ tag, filename, alias, settings}); } bool AssetsLoader::hasNext() const { @@ -35,7 +37,7 @@ bool AssetsLoader::loadNext() { return false; } aloader_func loader = found->second; - bool status = loader(assets, paths, entry.filename, entry.alias); + bool status = loader(assets, paths, entry.filename, entry.alias, entry.config); entries.pop(); return status; } @@ -48,7 +50,20 @@ void AssetsLoader::createDefaults(AssetsLoader& loader) { loader.addLoader(ASSET_LAYOUT, assetload::layout); } -void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) { +void addLayouts(int env, const std::string& prefix, const fs::path& folder, AssetsLoader& loader) { + if (!fs::is_directory(folder)) { + return; + } + for (auto& entry : fs::directory_iterator(folder)) { + const fs::path file = entry.path(); + if (file.extension().u8string() != ".xml") + continue; + std::string name = prefix+":"+file.stem().u8string(); + loader.add(ASSET_LAYOUT, file.u8string(), name, std::make_shared(env)); + } +} + +void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) { loader.add(ASSET_FONT, FONTS_FOLDER"/font", "normal"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui", "ui"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/main", "main"); @@ -58,13 +73,20 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) { loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/no_icon.png", "gui/no_icon"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/warning.png", "gui/warning"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/error.png", "gui/error"); - if (world) { + if (content) { loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui3d", "ui3d"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/background", "background"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/sun.png", "misc/sun"); + addLayouts(0, "core", loader.getPaths()->getMainRoot()/fs::path("layouts"), loader); + for (auto& pack : content->getPacks()) { + auto& info = pack->getInfo(); + fs::path folder = info.folder / fs::path("layouts"); + addLayouts(pack->getEnvironment()->getId(), info.id, folder, loader); + } + for (fs::path& file : loader.getPaths()->listdir(LAYOUTS_FOLDER)) { if (file.extension().u8string() != ".xml") continue; @@ -72,7 +94,7 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) { if (packName == "res") { packName = "core"; } - loader.add(ASSET_LAYOUT, file.u8string(), packName+":"+file.stem().u8string()); + //loader.add(ASSET_LAYOUT, file.u8string(), packName+":"+file.stem().u8string()); } } loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks"); diff --git a/src/assets/AssetsLoader.h b/src/assets/AssetsLoader.h index bce21bdf..4cab14be 100644 --- a/src/assets/AssetsLoader.h +++ b/src/assets/AssetsLoader.h @@ -2,6 +2,7 @@ #define ASSETS_ASSETS_LOADER_H #include +#include #include #include #include @@ -14,13 +15,15 @@ const short ASSET_LAYOUT = 5; class ResPaths; class Assets; +class Content; -using aloader_func = std::function; +using aloader_func = std::function)>; struct aloader_entry { int tag; const std::string filename; const std::string alias; + std::shared_ptr config; }; class AssetsLoader { @@ -31,13 +34,18 @@ class AssetsLoader { public: AssetsLoader(Assets* assets, const ResPaths* paths); void addLoader(int tag, aloader_func func); - void add(int tag, const std::string filename, const std::string alias); + void add( + int tag, + const std::string filename, + const std::string alias, + std::shared_ptr settings=nullptr + ); bool hasNext() const; bool loadNext(); static void createDefaults(AssetsLoader& loader); - static void addDefaults(AssetsLoader& loader, bool world); + static void addDefaults(AssetsLoader& loader, const Content* content); const ResPaths* getPaths() const; }; diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 9820d585..90dabcde 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -20,7 +20,9 @@ namespace fs = std::filesystem; bool assetload::texture(Assets* assets, const ResPaths* paths, const std::string filename, - const std::string name) { + const std::string name, + std::shared_ptr +) { std::unique_ptr texture( png::load_texture(paths->find(filename).u8string()) ); @@ -35,7 +37,9 @@ bool assetload::texture(Assets* assets, bool assetload::shader(Assets* assets, const ResPaths* paths, const std::string filename, - const std::string name) { + const std::string name, + std::shared_ptr +) { fs::path vertexFile = paths->find(filename+".glslv"); fs::path fragmentFile = paths->find(filename+".glslf"); @@ -78,7 +82,9 @@ static bool appendAtlas(AtlasBuilder& atlas, const fs::path& file) { bool assetload::atlas(Assets* assets, const ResPaths* paths, const std::string directory, - const std::string name) { + const std::string name, + std::shared_ptr +) { AtlasBuilder builder; for (const auto& file : paths->listdir(directory)) { if (!appendAtlas(builder, file)) continue; @@ -94,7 +100,9 @@ bool assetload::atlas(Assets* assets, bool assetload::font(Assets* assets, const ResPaths* paths, const std::string filename, - const std::string name) { + const std::string name, + std::shared_ptr +) { std::vector> pages; for (size_t i = 0; i <= 4; i++) { std::string name = filename + "_" + std::to_string(i) + ".png"; @@ -113,6 +121,26 @@ bool assetload::font(Assets* assets, return true; } +bool assetload::layout( + Assets* assets, + const ResPaths* paths, + const std::string file, + const std::string name, + std::shared_ptr config +) { + try { + LayoutCfg* cfg = reinterpret_cast(config.get()); + auto document = UiDocument::read(cfg->env, name, file); + assets->store(document.release(), name); + return true; + } catch (const parsing_error& err) { + std::cerr << "failed to parse layout XML '" << file << "'" << std::endl; + std::cerr << err.errorLog() << std::endl; + return false; + } +} + + bool assetload::animation(Assets* assets, const ResPaths* paths, const std::string directory, @@ -206,20 +234,3 @@ bool assetload::animation(Assets* assets, } return true; } - -bool assetload::layout( - Assets* assets, - const ResPaths* paths, - const std::string file, - const std::string name -) { - try { - auto document = UiDocument::read(name, file); - assets->store(document.release(), name); - return true; - } catch (const parsing_error& err) { - std::cerr << "failed to parse layout XML '" << file << "'" << std::endl; - std::cerr << err.errorLog() << std::endl; - return false; - } -} diff --git a/src/assets/assetload_funcs.h b/src/assets/assetload_funcs.h index 830d1d5a..745cadc5 100644 --- a/src/assets/assetload_funcs.h +++ b/src/assets/assetload_funcs.h @@ -2,6 +2,7 @@ #define ASSETS_ASSET_LOADERS_H_ #include +#include class ResPaths; class Assets; @@ -12,26 +13,38 @@ namespace assetload { Assets* assets, const ResPaths* paths, const std::string filename, - const std::string name + const std::string name, + std::shared_ptr settings ); bool shader( Assets* assets, const ResPaths* paths, const std::string filename, - const std::string name + const std::string name, + std::shared_ptr settings ); bool atlas( Assets* assets, const ResPaths* paths, const std::string directory, - const std::string name + const std::string name, + std::shared_ptr settings ); bool font( Assets* assets, const ResPaths* paths, const std::string filename, - const std::string name + const std::string name, + std::shared_ptr settings ); + bool layout( + Assets* assets, + const ResPaths* paths, + const std::string file, + const std::string name, + std::shared_ptr settings + ); + bool animation( Assets* assets, const ResPaths* paths, @@ -39,12 +52,6 @@ namespace assetload { const std::string name, Atlas* dstAtlas ); - bool layout( - Assets* assets, - const ResPaths* paths, - const std::string file, - const std::string name - ); } #endif // ASSETS_ASSET_LOADERS_H_ \ No newline at end of file diff --git a/src/engine.cpp b/src/engine.cpp index 3b1797e5..071dba63 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -56,7 +56,7 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths) assets.reset(new Assets()); AssetsLoader loader(assets.get(), resPaths.get()); AssetsLoader::createDefaults(loader); - AssetsLoader::addDefaults(loader, false); + AssetsLoader::addDefaults(loader, nullptr); Shader::preprocessor->setPaths(resPaths.get()); while (loader.hasNext()) { @@ -164,7 +164,8 @@ void Engine::loadContent() { for (auto& pack : srcPacks) { if(loadedPacks.find(pack.id) != loadedPacks.end()) continue; missingDependency = checkPacks(existingPacks, pack.dependencies); - if(!missingDependency.empty()) throw contentpack_error(pack.id, pack.folder, "missing dependency '"+missingDependency+"'"); + if(!missingDependency.empty()) + throw contentpack_error(pack.id, pack.folder, "missing dependency '"+missingDependency+"'"); if(pack.dependencies.empty() || checkPacks(loadedPacks, pack.dependencies).empty()) { loadedPacks.insert(pack.id); resRoots.push_back(pack.folder); @@ -184,7 +185,7 @@ void Engine::loadContent() { std::cout << "-- loading assets" << std::endl; AssetsLoader loader(new_assets.get(), resPaths.get()); AssetsLoader::createDefaults(loader); - AssetsLoader::addDefaults(loader, true); + AssetsLoader::addDefaults(loader, content.get()); while (loader.hasNext()) { if (!loader.loadNext()) { new_assets.reset(); diff --git a/src/files/engine_paths.cpp b/src/files/engine_paths.cpp index 10157ded..585268dc 100644 --- a/src/files/engine_paths.cpp +++ b/src/files/engine_paths.cpp @@ -159,3 +159,7 @@ std::vector ResPaths::listdir(const std::string& folderName) const { } return entries; } + +const fs::path& ResPaths::getMainRoot() const { + return mainRoot; +} diff --git a/src/files/engine_paths.h b/src/files/engine_paths.h index 760a1ba5..d0411e26 100644 --- a/src/files/engine_paths.h +++ b/src/files/engine_paths.h @@ -42,6 +42,8 @@ public: fs::path find(const std::string& filename) const; std::vector listdir(const std::string& folder) const; + + const fs::path& getMainRoot() const; }; #endif // FILES_ENGINE_PATHS_H_ \ No newline at end of file diff --git a/src/frontend/InventoryView.cpp b/src/frontend/InventoryView.cpp index 1380245b..76eba07b 100644 --- a/src/frontend/InventoryView.cpp +++ b/src/frontend/InventoryView.cpp @@ -296,6 +296,10 @@ std::shared_ptr InventoryView::addSlot(SlotLayout layout) { return slot; } +std::shared_ptr InventoryView::getInventory() const { + return inventory; +} + void InventoryView::bind( std::shared_ptr inventory, LevelFrontend* frontend, diff --git a/src/frontend/InventoryView.h b/src/frontend/InventoryView.h index 22ba1823..0d593d8b 100644 --- a/src/frontend/InventoryView.h +++ b/src/frontend/InventoryView.h @@ -115,6 +115,8 @@ public: std::shared_ptr addSlot(SlotLayout layout); + std::shared_ptr getInventory() const; + static std::shared_ptr readXML( const std::string& src, const std::string& file, diff --git a/src/frontend/UiDocument.cpp b/src/frontend/UiDocument.cpp index cfb769a8..0274d8fa 100644 --- a/src/frontend/UiDocument.cpp +++ b/src/frontend/UiDocument.cpp @@ -8,11 +8,11 @@ #include "../frontend/gui/gui_xml.h" UiDocument::UiDocument( - std::string namesp, + std::string id, uidocscript script, std::shared_ptr root, int env -) : namesp(namesp), script(script), root(root), env(env) { +) : id(id), script(script), root(root), env(env) { collect(map, root); } @@ -21,14 +21,22 @@ const uinodes_map& UiDocument::getMap() const { return map; } -const std::string& UiDocument::getNamespace() const { - return namesp; +const std::string& UiDocument::getId() const { + return id; } const std::shared_ptr UiDocument::getRoot() const { return root; } +const uidocscript& UiDocument::getScript() const { + return script; +} + +int UiDocument::getEnvironment() const { + return env; +} + void UiDocument::collect(uinodes_map& map, std::shared_ptr node) { const std::string& id = node->getId(); if (!id.empty()) { @@ -42,11 +50,10 @@ void UiDocument::collect(uinodes_map& map, std::shared_ptr node) { } } -std::unique_ptr UiDocument::read(std::string namesp, fs::path file) { +std::unique_ptr UiDocument::read(int env, std::string namesp, fs::path file) { const std::string text = files::read_string(file); auto xmldoc = xml::parse(file.u8string(), text); - auto env = scripting::create_environment(); - gui::UiXmlReader reader(*env); + gui::UiXmlReader reader(env); InventoryView::createReaders(reader); auto view = reader.readXML( file.u8string(), xmldoc->getRoot() @@ -54,7 +61,7 @@ std::unique_ptr UiDocument::read(std::string namesp, fs::path file) uidocscript script {}; auto scriptFile = fs::path(file.u8string()+".lua"); if (fs::is_regular_file(scriptFile)) { - scripting::load_layout_script(env->getId(), namesp, scriptFile, script); + scripting::load_layout_script(env, namesp, scriptFile, script); } - return std::make_unique(namesp, script, view, env.release()->getId()); + return std::make_unique(namesp, script, view, env); } diff --git a/src/frontend/UiDocument.h b/src/frontend/UiDocument.h index 45484b01..f5818190 100644 --- a/src/frontend/UiDocument.h +++ b/src/frontend/UiDocument.h @@ -21,26 +21,28 @@ struct uidocscript { using uinodes_map = std::unordered_map>; class UiDocument { - std::string namesp; + std::string id; uidocscript script; uinodes_map map; std::shared_ptr root; int env; public: UiDocument( - std::string namesp, + std::string id, uidocscript script, std::shared_ptr root, - int env); + int env + ); + const std::string& getId() const; const uinodes_map& getMap() const; - const std::string& getNamespace() const; const std::shared_ptr getRoot() const; - + const uidocscript& getScript() const; + int getEnvironment() const; /* Collect map of all uinodes having identifiers */ static void collect(uinodes_map& map, std::shared_ptr node); - static std::unique_ptr read (std::string namesp, fs::path file); + static std::unique_ptr read(int env, std::string namesp, fs::path file); }; #endif // FRONTEND_UI_DOCUMENT_H_ diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index f7ad4a96..6400e82c 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -125,8 +125,8 @@ static std::shared_ptr readButton(UiXmlReader& reader, xml::xmlelement e if (element->has("onclick")) { auto callback = scripting::create_runnable( reader.getEnvironment().getId(), - "", - element->attr("onclick").getText() + element->attr("onclick").getText(), + "" ); button->listenAction([callback](GUI*) { callback(); diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index ef847332..a0d4e235 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -46,6 +46,7 @@ #include "../core_defs.h" #include "../items/ItemDef.h" #include "../items/Inventory.h" +#include "../logic/scripting/scripting.h" using glm::vec2; using glm::vec3; @@ -212,31 +213,6 @@ std::shared_ptr HudRenderer::createHotbar() { return view; } -std::shared_ptr HudRenderer::createInventory() { - auto level = frontend->getLevel(); - auto player = level->player; - auto inventory = player->getInventory(); - - auto layout = assets->getLayout("core:inventory"); - if (layout) { - std::cout << "custom layout used" << std::endl; - auto view = std::dynamic_pointer_cast(layout->getRoot()); - view->bind(inventory, frontend, interaction.get()); - return view; - } else { - std::cout << "generated layout used" << std::endl; - SlotLayout slotLayout(-1, glm::vec2(), true, false, [=](ItemStack& stack) { - stack.clear(); - }, nullptr); - - InventoryBuilder builder; - builder.addGrid(10, inventory->size(), glm::vec2(), 4, true, slotLayout); - auto view = builder.build(); - view->bind(inventory, frontend, interaction.get()); - return view; - } -} - HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend) : assets(engine->getAssets()), gui(engine->getGUI()), @@ -265,8 +241,6 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend) contentAccessPanel->setScrollable(true); hotbarView = createHotbar(); - inventoryView = createInventory(); - darkOverlay = std::make_unique(glm::vec2(4000.0f)); darkOverlay->setColor(glm::vec4(0, 0, 0, 0.5f)); @@ -281,13 +255,14 @@ HudRenderer::HudRenderer(Engine* engine, LevelFrontend* frontend) gui->addBack(hotbarView); gui->add(debugPanel); gui->add(contentAccessPanel); - gui->add(inventoryView); gui->add(grabbedItemView); } HudRenderer::~HudRenderer() { gui->remove(grabbedItemView); - gui->remove(inventoryView); + if (inventoryView) { + gui->remove(inventoryView); + } gui->remove(hotbarView); gui->remove(darkOverlay); gui->remove(contentAccessPanel); @@ -330,7 +305,7 @@ void HudRenderer::update(bool visible) { if (inventoryOpen) { closeInventory(); } else { - inventoryOpen = true; + openInventory(); } } } @@ -339,7 +314,6 @@ void HudRenderer::update(bool visible) { } vec2 invSize = contentAccessPanel->getSize(); - inventoryView->setVisible(inventoryOpen); contentAccessPanel->setVisible(inventoryOpen); contentAccessPanel->setSize(vec2(invSize.x, Window::height)); hotbarView->setVisible(visible); @@ -364,10 +338,31 @@ void HudRenderer::update(bool visible) { darkOverlay->setVisible(pause); } +void HudRenderer::openInventory() { + auto level = frontend->getLevel(); + auto player = level->player; + auto inventory = player->getInventory(); + + inventoryOpen = true; + gui->remove(grabbedItemView); + + inventoryDocument = assets->getLayout("core:inventory"); + inventoryView = std::dynamic_pointer_cast(inventoryDocument->getRoot()); + inventoryView->bind(inventory, frontend, interaction.get()); + scripting::on_ui_open(inventoryDocument, inventory.get()); + + gui->add(inventoryView); + gui->add(grabbedItemView); +} + void HudRenderer::closeInventory() { + scripting::on_ui_close(inventoryDocument, inventoryView->getInventory().get()); inventoryOpen = false; ItemStack& grabbed = interaction->getGrabbedItem(); grabbed.clear(); + gui->remove(inventoryView); + inventoryView = nullptr; + inventoryDocument = nullptr; } void HudRenderer::draw(const GfxContext& ctx){ diff --git a/src/frontend/hud.h b/src/frontend/hud.h index fe2e45a2..f9d12b6a 100644 --- a/src/frontend/hud.h +++ b/src/frontend/hud.h @@ -18,6 +18,7 @@ class Engine; class SlotView; class InventoryView; class LevelFrontend; +class UiDocument; class InventoryInteraction; namespace gui { @@ -40,7 +41,6 @@ class HudRenderer { std::shared_ptr contentAccessPanel; std::shared_ptr contentAccess; std::shared_ptr hotbarView; - std::shared_ptr inventoryView; std::shared_ptr debugPanel; std::shared_ptr darkOverlay; std::unique_ptr interaction; @@ -48,10 +48,12 @@ class HudRenderer { gui::GUI* gui; LevelFrontend* frontend; + std::shared_ptr inventoryView = nullptr; + UiDocument* inventoryDocument = nullptr; + std::shared_ptr createDebugPanel(Engine* engine); std::shared_ptr createContentAccess(); std::shared_ptr createHotbar(); - std::shared_ptr createInventory(); public: HudRenderer(Engine* engine, LevelFrontend* frontend); ~HudRenderer(); @@ -63,6 +65,7 @@ public: bool isInventoryOpen() const; bool isPause() const; + void openInventory(); void closeInventory(); }; diff --git a/src/logic/scripting/LuaState.cpp b/src/logic/scripting/LuaState.cpp index c098ce70..229a1e00 100644 --- a/src/logic/scripting/LuaState.cpp +++ b/src/logic/scripting/LuaState.cpp @@ -16,6 +16,7 @@ lua::LuaState::LuaState() { luaopen_math(L); luaopen_string(L); luaopen_table(L); + luaopen_debug(L); std::cout << LUA_VERSION << std::endl; # ifdef LUAJIT_VERSION diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index b9e27721..52ff33a8 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -60,8 +60,8 @@ void scripting::initialize(Engine* engine) { runnable scripting::create_runnable( int env, - const std::string& file, - const std::string& src + const std::string& src, + const std::string& file ) { return [=](){ state->execute(env, src, file); @@ -170,7 +170,7 @@ void scripting::on_block_broken(Player* player, const Block* block, int x, int y } bool scripting::on_block_interact(Player* player, const Block* block, int x, int y, int z) { - std::string name = block->name+".oninteract"; + std::string name = block->name+".interact"; if (state->getglobal(name)) { state->pushivec3(x, y, z); state->pushinteger(1); // playerid placeholder @@ -205,8 +205,21 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, return false; } +void scripting::on_ui_open(UiDocument* layout, Inventory* inventory) { + std::string name = layout->getId()+".open"; + if (state->getglobal(name)) { + state->callNoThrow(0); + } +} + +void scripting::on_ui_close(UiDocument* layout, Inventory* inventory) { + std::string name = layout->getId()+".close"; + if (state->getglobal(name)) { + state->callNoThrow(0); + } +} + bool register_event(int env, const std::string& name, const std::string& id) { - std::cout << "register " << name << " -> " << id << std::endl; if (state->pushenv(env) == 0) { state->pushglobals(); } diff --git a/src/logic/scripting/scripting.h b/src/logic/scripting/scripting.h index 1606bc30..ffac1dc0 100644 --- a/src/logic/scripting/scripting.h +++ b/src/logic/scripting/scripting.h @@ -14,6 +14,8 @@ class Level; class Block; class Player; class ItemDef; +class Inventory; +class UiDocument; struct block_funcs_set; struct item_funcs_set; struct uidocscript; @@ -39,8 +41,8 @@ namespace scripting { runnable create_runnable( int env, - const std::string& filename, - const std::string& source + const std::string& src, + const std::string& file="" ); wstringconsumer create_wstring_consumer( @@ -62,6 +64,8 @@ namespace scripting { bool on_block_interact(Player* player, const Block* block, int x, int y, int z); bool on_item_use_on_block(Player* player, const ItemDef* item, int x, int y, int z); bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z); + void on_ui_open(UiDocument* layout, Inventory* inventory); + void on_ui_close(UiDocument* layout, Inventory* inventory); void load_block_script(int env, std::string prefix, fs::path file, block_funcs_set& funcsset); void load_item_script(int env, std::string prefix, fs::path file, item_funcs_set& funcsset); void load_world_script(int env, std::string prefix, fs::path file);