inventory script, modules
This commit is contained in:
parent
bb1743105d
commit
8e529eb63b
@ -1,4 +1,4 @@
|
||||
<inventory color="#00000080" size="400,0">
|
||||
<inventory color="#1F1F1FE0" size="400,0">
|
||||
<slots-grid cols="4" count="40"/>
|
||||
<button padding="10,10,10,10" coord="300,10">Test</button>
|
||||
</inventory>
|
||||
|
||||
7
res/layouts/inventory.xml.lua
Normal file
7
res/layouts/inventory.xml.lua
Normal file
@ -0,0 +1,7 @@
|
||||
function on_open()
|
||||
print("OPEN")
|
||||
end
|
||||
|
||||
function on_close()
|
||||
print("CLOSE")
|
||||
end
|
||||
65
res/modules/toml.lua
Normal file
65
res/modules/toml.lua
Normal file
@ -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
|
||||
@ -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
|
||||
|
||||
@ -14,6 +14,12 @@ class Font;
|
||||
class Atlas;
|
||||
class UiDocument;
|
||||
|
||||
struct LayoutCfg {
|
||||
int env;
|
||||
|
||||
LayoutCfg(int env) : env(env) {}
|
||||
};
|
||||
|
||||
class Assets {
|
||||
std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
|
||||
std::unordered_map<std::string, std::shared_ptr<Shader>> shaders;
|
||||
|
||||
@ -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<void> 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<LayoutCfg>(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");
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define ASSETS_ASSETS_LOADER_H
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
@ -14,13 +15,15 @@ const short ASSET_LAYOUT = 5;
|
||||
|
||||
class ResPaths;
|
||||
class Assets;
|
||||
class Content;
|
||||
|
||||
using aloader_func = std::function<bool(Assets*, const ResPaths*, const std::string&, const std::string&)>;
|
||||
using aloader_func = std::function<bool(Assets*, const ResPaths*, const std::string&, const std::string&, std::shared_ptr<void>)>;
|
||||
|
||||
struct aloader_entry {
|
||||
int tag;
|
||||
const std::string filename;
|
||||
const std::string alias;
|
||||
std::shared_ptr<void> 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<void> 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;
|
||||
};
|
||||
|
||||
@ -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<void>
|
||||
) {
|
||||
std::unique_ptr<Texture> 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<void>
|
||||
) {
|
||||
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<void>
|
||||
) {
|
||||
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<void>
|
||||
) {
|
||||
std::vector<std::unique_ptr<Texture>> 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<void> config
|
||||
) {
|
||||
try {
|
||||
LayoutCfg* cfg = reinterpret_cast<LayoutCfg*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define ASSETS_ASSET_LOADERS_H_
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
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<void> settings
|
||||
);
|
||||
bool shader(
|
||||
Assets* assets,
|
||||
const ResPaths* paths,
|
||||
const std::string filename,
|
||||
const std::string name
|
||||
const std::string name,
|
||||
std::shared_ptr<void> settings
|
||||
);
|
||||
bool atlas(
|
||||
Assets* assets,
|
||||
const ResPaths* paths,
|
||||
const std::string directory,
|
||||
const std::string name
|
||||
const std::string name,
|
||||
std::shared_ptr<void> settings
|
||||
);
|
||||
bool font(
|
||||
Assets* assets,
|
||||
const ResPaths* paths,
|
||||
const std::string filename,
|
||||
const std::string name
|
||||
const std::string name,
|
||||
std::shared_ptr<void> settings
|
||||
);
|
||||
bool layout(
|
||||
Assets* assets,
|
||||
const ResPaths* paths,
|
||||
const std::string file,
|
||||
const std::string name,
|
||||
std::shared_ptr<void> 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_
|
||||
@ -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();
|
||||
|
||||
@ -159,3 +159,7 @@ std::vector<fs::path> ResPaths::listdir(const std::string& folderName) const {
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
const fs::path& ResPaths::getMainRoot() const {
|
||||
return mainRoot;
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ public:
|
||||
|
||||
fs::path find(const std::string& filename) const;
|
||||
std::vector<fs::path> listdir(const std::string& folder) const;
|
||||
|
||||
const fs::path& getMainRoot() const;
|
||||
};
|
||||
|
||||
#endif // FILES_ENGINE_PATHS_H_
|
||||
@ -296,6 +296,10 @@ std::shared_ptr<SlotView> InventoryView::addSlot(SlotLayout layout) {
|
||||
return slot;
|
||||
}
|
||||
|
||||
std::shared_ptr<Inventory> InventoryView::getInventory() const {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
void InventoryView::bind(
|
||||
std::shared_ptr<Inventory> inventory,
|
||||
LevelFrontend* frontend,
|
||||
|
||||
@ -115,6 +115,8 @@ public:
|
||||
|
||||
std::shared_ptr<SlotView> addSlot(SlotLayout layout);
|
||||
|
||||
std::shared_ptr<Inventory> getInventory() const;
|
||||
|
||||
static std::shared_ptr<InventoryView> readXML(
|
||||
const std::string& src,
|
||||
const std::string& file,
|
||||
|
||||
@ -8,11 +8,11 @@
|
||||
#include "../frontend/gui/gui_xml.h"
|
||||
|
||||
UiDocument::UiDocument(
|
||||
std::string namesp,
|
||||
std::string id,
|
||||
uidocscript script,
|
||||
std::shared_ptr<gui::UINode> 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<gui::UINode> 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<gui::UINode> node) {
|
||||
const std::string& id = node->getId();
|
||||
if (!id.empty()) {
|
||||
@ -42,11 +50,10 @@ void UiDocument::collect(uinodes_map& map, std::shared_ptr<gui::UINode> node) {
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<UiDocument> UiDocument::read(std::string namesp, fs::path file) {
|
||||
std::unique_ptr<UiDocument> 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> 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<UiDocument>(namesp, script, view, env.release()->getId());
|
||||
return std::make_unique<UiDocument>(namesp, script, view, env);
|
||||
}
|
||||
|
||||
@ -21,26 +21,28 @@ struct uidocscript {
|
||||
using uinodes_map = std::unordered_map<std::string, std::shared_ptr<gui::UINode>>;
|
||||
|
||||
class UiDocument {
|
||||
std::string namesp;
|
||||
std::string id;
|
||||
uidocscript script;
|
||||
uinodes_map map;
|
||||
std::shared_ptr<gui::UINode> root;
|
||||
int env;
|
||||
public:
|
||||
UiDocument(
|
||||
std::string namesp,
|
||||
std::string id,
|
||||
uidocscript script,
|
||||
std::shared_ptr<gui::UINode> root,
|
||||
int env);
|
||||
int env
|
||||
);
|
||||
|
||||
const std::string& getId() const;
|
||||
const uinodes_map& getMap() const;
|
||||
const std::string& getNamespace() const;
|
||||
const std::shared_ptr<gui::UINode> 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<gui::UINode> node);
|
||||
|
||||
static std::unique_ptr<UiDocument> read (std::string namesp, fs::path file);
|
||||
static std::unique_ptr<UiDocument> read(int env, std::string namesp, fs::path file);
|
||||
};
|
||||
|
||||
#endif // FRONTEND_UI_DOCUMENT_H_
|
||||
|
||||
@ -125,8 +125,8 @@ static std::shared_ptr<UINode> readButton(UiXmlReader& reader, xml::xmlelement e
|
||||
if (element->has("onclick")) {
|
||||
auto callback = scripting::create_runnable(
|
||||
reader.getEnvironment().getId(),
|
||||
"<onclick>",
|
||||
element->attr("onclick").getText()
|
||||
element->attr("onclick").getText(),
|
||||
"<onclick>"
|
||||
);
|
||||
button->listenAction([callback](GUI*) {
|
||||
callback();
|
||||
|
||||
@ -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<InventoryView> HudRenderer::createHotbar() {
|
||||
return view;
|
||||
}
|
||||
|
||||
std::shared_ptr<InventoryView> 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<InventoryView>(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<Panel>(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<InventoryView>(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){
|
||||
|
||||
@ -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<gui::Panel> contentAccessPanel;
|
||||
std::shared_ptr<InventoryView> contentAccess;
|
||||
std::shared_ptr<InventoryView> hotbarView;
|
||||
std::shared_ptr<InventoryView> inventoryView;
|
||||
std::shared_ptr<gui::UINode> debugPanel;
|
||||
std::shared_ptr<gui::Panel> darkOverlay;
|
||||
std::unique_ptr<InventoryInteraction> interaction;
|
||||
@ -48,10 +48,12 @@ class HudRenderer {
|
||||
gui::GUI* gui;
|
||||
LevelFrontend* frontend;
|
||||
|
||||
std::shared_ptr<InventoryView> inventoryView = nullptr;
|
||||
UiDocument* inventoryDocument = nullptr;
|
||||
|
||||
std::shared_ptr<gui::UINode> createDebugPanel(Engine* engine);
|
||||
std::shared_ptr<InventoryView> createContentAccess();
|
||||
std::shared_ptr<InventoryView> createHotbar();
|
||||
std::shared_ptr<InventoryView> createInventory();
|
||||
public:
|
||||
HudRenderer(Engine* engine, LevelFrontend* frontend);
|
||||
~HudRenderer();
|
||||
@ -63,6 +65,7 @@ public:
|
||||
bool isInventoryOpen() const;
|
||||
bool isPause() const;
|
||||
|
||||
void openInventory();
|
||||
void closeInventory();
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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="<string>"
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user