From 535c7d8326887b54711a45789c838ac48729fd4d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 18 May 2024 16:57:04 +0300 Subject: [PATCH 01/97] small fixes --- res/scripts/stdcmd.lua | 2 +- src/graphics/ui/elements/TextBox.cpp | 4 ++-- src/graphics/ui/elements/TextBox.hpp | 2 +- src/logic/scripting/lua/libgui.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/res/scripts/stdcmd.lua b/res/scripts/stdcmd.lua index 48741102..0db4d208 100644 --- a/res/scripts/stdcmd.lua +++ b/res/scripts/stdcmd.lua @@ -51,7 +51,7 @@ console.add_command( ) console.add_command( - "obj.tp obj:sel=$obj.id x:num~pos.x y:num~pos.y z:num~pos.z", + "tp obj:sel=$obj.id x:num~pos.x y:num~pos.y z:num~pos.z", "Teleport object", function (args, kwargs) player.set_pos(unpack(args)) diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 2240acee..8b012b8a 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -369,7 +369,7 @@ void TextBox::click(GUI*, int x, int y) { } void TextBox::mouseMove(GUI*, int x, int y) { - ssize_t index = calcIndexAt(x, y); + ptrdiff_t index = calcIndexAt(x, y); setCaret(index); extendSelection(index); resetMaxLocalCaret(); @@ -656,7 +656,7 @@ void TextBox::setCaret(size_t position) { } } -void TextBox::setCaret(ssize_t position) { +void TextBox::setCaret(ptrdiff_t position) { if (position < 0) { setCaret(static_cast(input.length() + position + 1)); } else { diff --git a/src/graphics/ui/elements/TextBox.hpp b/src/graphics/ui/elements/TextBox.hpp index 183a5ec7..ee59b778 100644 --- a/src/graphics/ui/elements/TextBox.hpp +++ b/src/graphics/ui/elements/TextBox.hpp @@ -120,7 +120,7 @@ namespace gui { /// @brief Set caret position in the text /// @param position integer in range [-text.length(), text.length()] - virtual void setCaret(ssize_t position); + virtual void setCaret(ptrdiff_t position); /// @brief Select part of the text /// @param start index of the first selected character diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index d2e72d8a..ffcd55ac 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -363,7 +363,7 @@ static void p_set_text(UINode* node, int idx) { } static void p_set_caret(UINode* node, int idx) { if (auto box = dynamic_cast(node)) { - box->setCaret(static_cast(state->tointeger(idx))); + box->setCaret(static_cast(state->tointeger(idx))); } } static void p_set_editable(UINode* node, int idx) { From 35fdd475ee034738ea00ece38f3bb72ec75f6b2c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 18 May 2024 22:13:53 +0300 Subject: [PATCH 02/97] msvc build fix --- src/data/dynamic.hpp | 1 + src/graphics/ui/elements/TextBox.cpp | 2 +- src/logic/CommandsInterpreter.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index a9dc81c1..93e87b4b 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 8b012b8a..091b944c 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -652,7 +652,7 @@ void TextBox::setCaret(size_t position) { if (realoffset-width > 0) { setTextOffset(textOffset + realoffset-width); } else if (realoffset < 0) { - setTextOffset(std::max(textOffset + realoffset, 0LU)); + setTextOffset(std::max(textOffset + realoffset, static_cast(0))); } } diff --git a/src/logic/CommandsInterpreter.cpp b/src/logic/CommandsInterpreter.cpp index 54a99901..e157cbb4 100644 --- a/src/logic/CommandsInterpreter.cpp +++ b/src/logic/CommandsInterpreter.cpp @@ -320,7 +320,7 @@ public: dynamic::Value value = dynamic::NONE; if (peek() == '~') { relative = true; - value = 0L; + value = static_cast(0); nextChar(); } From f47c7d00a217e5be58273113489c3654a711ea34 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 18 May 2024 22:17:02 +0300 Subject: [PATCH 03/97] again --- src/graphics/ui/elements/TextBox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 091b944c..43b6304e 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -452,7 +452,7 @@ void TextBox::stepDefaultUp(bool shiftPressed, bool breakSelection) { uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine-1)-1); setCaret(label->getTextLineOffset(caretLine-1) + offset); } else { - setCaret(0UL); + setCaret(static_cast(0)); } if (shiftPressed) { if (selectionStart == selectionEnd) { From c5f663b7cbdb85959cb816fc8b99d88a03241e6a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 19 May 2024 07:09:58 +0300 Subject: [PATCH 04/97] memory-related refactor --- src/assets/AssetsLoader.cpp | 3 +- src/audio/AL/ALAudio.cpp | 4 +- src/audio/AL/ALAudio.hpp | 5 +- src/audio/NoAudio.cpp | 4 +- src/audio/NoAudio.hpp | 2 +- src/audio/audio.cpp | 6 +- src/content/Content.cpp | 149 ++-------------------------- src/content/Content.hpp | 49 +++------ src/content/ContentBuilder.cpp | 109 ++++++++++++++++++++ src/content/ContentBuilder.hpp | 37 +++++++ src/content/ContentLoader.cpp | 27 ++--- src/content/ContentLoader.hpp | 6 +- src/content/ContentPack.hpp | 8 +- src/core_defs.cpp | 1 + src/engine.cpp | 3 +- src/frontend/screens/MenuScreen.cpp | 1 + 16 files changed, 205 insertions(+), 209 deletions(-) create mode 100644 src/content/ContentBuilder.cpp create mode 100644 src/content/ContentBuilder.hpp diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index 8d9119ee..b9fcc1e3 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -11,6 +11,7 @@ #include "../files/engine_paths.hpp" #include "../content/Content.hpp" #include "../content/ContentPack.hpp" +#include "../voxels/Block.hpp" #include "../graphics/core/Texture.hpp" #include "../logic/scripting/scripting.hpp" @@ -187,7 +188,7 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) { loader.processPreloadConfigs(content); for (auto& entry : content->getBlockMaterials()) { - auto& material = entry.second; + auto& material = *entry.second; loader.tryAddSound(material.stepsSound); loader.tryAddSound(material.placeSound); loader.tryAddSound(material.breakSound); diff --git a/src/audio/AL/ALAudio.cpp b/src/audio/AL/ALAudio.cpp index bf5f7f13..939aa4ad 100644 --- a/src/audio/AL/ALAudio.cpp +++ b/src/audio/AL/ALAudio.cpp @@ -389,7 +389,7 @@ std::unique_ptr ALAudio::openStream(std::shared_ptr stream, b return std::make_unique(this, stream, keepSource); } -ALAudio* ALAudio::create() { +std::unique_ptr ALAudio::create() { ALCdevice* device = alcOpenDevice(nullptr); if (device == nullptr) return nullptr; @@ -400,7 +400,7 @@ ALAudio* ALAudio::create() { } AL_CHECK(); logger.info() << "initialized"; - return new ALAudio(device, context); + return std::make_unique(device, context); } uint ALAudio::getFreeSource(){ diff --git a/src/audio/AL/ALAudio.hpp b/src/audio/AL/ALAudio.hpp index 294b0224..f0a22dde 100644 --- a/src/audio/AL/ALAudio.hpp +++ b/src/audio/AL/ALAudio.hpp @@ -136,9 +136,8 @@ namespace audio { std::vector freebuffers; uint maxSources = 256; - - ALAudio(ALCdevice* device, ALCcontext* context); public: + ALAudio(ALCdevice* device, ALCcontext* context); ~ALAudio(); uint getFreeSource(); @@ -164,7 +163,7 @@ namespace audio { return false; } - static ALAudio* create(); + static std::unique_ptr create(); }; } diff --git a/src/audio/NoAudio.cpp b/src/audio/NoAudio.cpp index 3000b891..04dd2b77 100644 --- a/src/audio/NoAudio.cpp +++ b/src/audio/NoAudio.cpp @@ -17,6 +17,6 @@ std::unique_ptr NoAudio::openStream(std::shared_ptr stream, b return std::make_unique(stream, keepSource); } -NoAudio* NoAudio::create() { - return new NoAudio(); +std::unique_ptr NoAudio::create() { + return std::make_unique(); } diff --git a/src/audio/NoAudio.hpp b/src/audio/NoAudio.hpp index e24fb5c6..bc105139 100644 --- a/src/audio/NoAudio.hpp +++ b/src/audio/NoAudio.hpp @@ -81,7 +81,7 @@ namespace audio { return true; } - static NoAudio* create(); + static std::unique_ptr create(); }; } diff --git a/src/audio/audio.cpp b/src/audio/audio.cpp index 3829c16a..9fe62de0 100644 --- a/src/audio/audio.cpp +++ b/src/audio/audio.cpp @@ -147,11 +147,11 @@ public: void audio::initialize(bool enabled) { if (enabled) { - backend = ALAudio::create(); + backend = ALAudio::create().release(); } if (backend == nullptr) { std::cerr << "could not to initialize audio" << std::endl; - backend = NoAudio::create(); + backend = NoAudio::create().release(); } create_channel("master"); } @@ -333,7 +333,7 @@ int audio::create_channel(const std::string& name) { if (index != -1) { return index; } - channels.emplace_back(new Channel(name)); + channels.emplace_back(std::make_unique(name)); return channels.size()-1; } diff --git a/src/content/Content.cpp b/src/content/Content.cpp index 4ba19fe3..4de7367c 100644 --- a/src/content/Content.cpp +++ b/src/content/Content.cpp @@ -10,127 +10,6 @@ #include "ContentPack.hpp" #include "../logic/scripting/scripting.hpp" -ContentBuilder::~ContentBuilder() {} - -void ContentBuilder::add(Block* def) { - checkIdentifier(def->name); - blockDefs[def->name] = def; - blockIds.push_back(def->name); -} - -void ContentBuilder::add(ItemDef* def) { - checkIdentifier(def->name); - itemDefs[def->name] = def; - itemIds.push_back(def->name); -} - -void ContentBuilder::add(ContentPackRuntime* pack) { - packs.emplace(pack->getId(), pack); -} - -void ContentBuilder::add(BlockMaterial material) { - blockMaterials.emplace(material.name, material); -} - -Block& ContentBuilder::createBlock(std::string id) { - auto found = blockDefs.find(id); - if (found != blockDefs.end()) { - return *found->second; - // throw namereuse_error("name "+id+" is already used", contenttype::item); - } - Block* block = new Block(id); - add(block); - return *block; -} - -ItemDef& ContentBuilder::createItem(std::string id) { - auto found = itemDefs.find(id); - if (found != itemDefs.end()) { - // if (found->second->generated) { - return *found->second; - // } - // throw namereuse_error("name "+id+" is already used", contenttype::item); - } - ItemDef* item = new ItemDef(id); - add(item); - return *item; -} - -void ContentBuilder::checkIdentifier(std::string id) { - contenttype result; - if (((result = checkContentType(id)) != contenttype::none)) { - throw namereuse_error("name "+id+" is already used", result); - } -} - -contenttype ContentBuilder::checkContentType(std::string id) { - if (blockDefs.find(id) != blockDefs.end()) { - return contenttype::block; - } - if (itemDefs.find(id) != itemDefs.end()) { - return contenttype::item; - } - return contenttype::none; -} - -Content* ContentBuilder::build() { - std::vector blockDefsIndices; - auto groups = std::make_unique(); - for (const std::string& name : blockIds) { - Block* def = blockDefs[name]; - - // Generating runtime info - def->rt.id = blockDefsIndices.size(); - def->rt.emissive = *reinterpret_cast(def->emission); - def->rt.solid = def->model == BlockModel::block; - - if (def->rotatable) { - for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) { - def->rt.hitboxes[i].reserve(def->hitboxes.size()); - for (AABB aabb : def->hitboxes) { - def->rotations.variants[i].transform(aabb); - def->rt.hitboxes[i].push_back(aabb); - } - } - } - - blockDefsIndices.push_back(def); - groups->insert(def->drawGroup); - } - - std::vector itemDefsIndices; - for (const std::string& name : itemIds) { - ItemDef* def = itemDefs[name]; - - // Generating runtime info - def->rt.id = itemDefsIndices.size(); - def->rt.emissive = *reinterpret_cast(def->emission); - itemDefsIndices.push_back(def); - } - - auto indices = new ContentIndices(blockDefsIndices, itemDefsIndices); - - auto content = std::make_unique( - indices, - std::move(groups), - blockDefs, - itemDefs, - std::move(packs), - std::move(blockMaterials) - ); - - // Now, it's time to resolve foreign keys - for (Block* def : blockDefsIndices) { - def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id; - } - - for (ItemDef* def : itemDefsIndices) { - def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id; - } - - return content.release(); -} - ContentIndices::ContentIndices( std::vector blockDefs, std::vector itemDefs @@ -139,27 +18,21 @@ ContentIndices::ContentIndices( {} Content::Content( - ContentIndices* indices, + std::unique_ptr indices, std::unique_ptr drawGroups, - std::unordered_map blockDefs, - std::unordered_map itemDefs, + std::unordered_map> blockDefs, + std::unordered_map> itemDefs, std::unordered_map> packs, - std::unordered_map blockMaterials -) : blockDefs(blockDefs), - itemDefs(itemDefs), - indices(indices), + std::unordered_map> blockMaterials +) : blockDefs(std::move(blockDefs)), + itemDefs(std::move(itemDefs)), + indices(std::move(indices)), packs(std::move(packs)), blockMaterials(std::move(blockMaterials)), drawGroups(std::move(drawGroups)) {} Content::~Content() { - for (auto& entry : blockDefs) { - delete entry.second; - } - for (auto& entry : itemDefs) { - delete entry.second; - } } Block* Content::findBlock(std::string id) const { @@ -167,7 +40,7 @@ Block* Content::findBlock(std::string id) const { if (found == blockDefs.end()) { return nullptr; } - return found->second; + return found->second.get(); } Block& Content::requireBlock(std::string id) const { @@ -183,7 +56,7 @@ ItemDef* Content::findItem(std::string id) const { if (found == itemDefs.end()) { return nullptr; } - return found->second; + return found->second.get(); } ItemDef& Content::requireItem(std::string id) const { @@ -199,7 +72,7 @@ const BlockMaterial* Content::findBlockMaterial(std::string id) const { if (found == blockMaterials.end()) { return nullptr; } - return &found->second; + return found->second.get(); } const ContentPackRuntime* Content::getPackRuntime(std::string id) const { @@ -210,7 +83,7 @@ const ContentPackRuntime* Content::getPackRuntime(std::string id) const { return found->second.get(); } -const std::unordered_map& Content::getBlockMaterials() const { +const std::unordered_map>& Content::getBlockMaterials() const { return blockMaterials; } diff --git a/src/content/Content.hpp b/src/content/Content.hpp index dcf3c56f..c9df8417 100644 --- a/src/content/Content.hpp +++ b/src/content/Content.hpp @@ -1,17 +1,19 @@ #ifndef CONTENT_CONTENT_HPP_ #define CONTENT_CONTENT_HPP_ +#include "../typedefs.hpp" + #include #include #include #include #include #include -#include "../typedefs.hpp" -#include "../voxels/Block.hpp" using DrawGroups = std::set; +class Block; +struct BlockMaterial; class ItemDef; class Content; class ContentPackRuntime; @@ -41,33 +43,6 @@ public: } }; -class ContentBuilder { - std::unordered_map blockDefs; - std::vector blockIds; - - std::unordered_map itemDefs; - std::vector itemIds; - - std::unordered_map blockMaterials; - - std::unordered_map> packs; -public: - ~ContentBuilder(); - - void add(Block* def); - void add(ItemDef* def); - void add(ContentPackRuntime* pack); - void add(BlockMaterial material); - - Block& createBlock(std::string id); - ItemDef& createItem(std::string id); - - void checkIdentifier(std::string id); - contenttype checkContentType(std::string id); - - Content* build(); -}; - /// @brief Runtime defs cache: indices class ContentIndices { std::vector blockDefs; @@ -110,21 +85,21 @@ public: /* Content is a definitions repository */ class Content { - std::unordered_map blockDefs; - std::unordered_map itemDefs; + std::unordered_map> blockDefs; + std::unordered_map> itemDefs; std::unique_ptr indices; std::unordered_map> packs; - std::unordered_map blockMaterials; + std::unordered_map> blockMaterials; public: std::unique_ptr const drawGroups; Content( - ContentIndices* indices, + std::unique_ptr indices, std::unique_ptr drawGroups, - std::unordered_map blockDefs, - std::unordered_map itemDefs, + std::unordered_map> blockDefs, + std::unordered_map> itemDefs, std::unordered_map> packs, - std::unordered_map blockMaterials + std::unordered_map> blockMaterials ); ~Content(); @@ -142,7 +117,7 @@ public: const ContentPackRuntime* getPackRuntime(std::string id) const; - const std::unordered_map& getBlockMaterials() const; + const std::unordered_map>& getBlockMaterials() const; const std::unordered_map>& getPacks() const; }; diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp new file mode 100644 index 00000000..16ec0a85 --- /dev/null +++ b/src/content/ContentBuilder.cpp @@ -0,0 +1,109 @@ +#include "ContentBuilder.hpp" + +ContentBuilder::~ContentBuilder() {} + +void ContentBuilder::add(std::unique_ptr pack) { + packs[pack->getId()] = std::move(pack); +} + +Block& ContentBuilder::createBlock(std::string id) { + auto found = blockDefs.find(id); + if (found != blockDefs.end()) { + return *found->second; + } + checkIdentifier(id); + blockIds.push_back(id); + blockDefs[id] = std::make_unique(id); + return *blockDefs[id]; +} + +ItemDef& ContentBuilder::createItem(std::string id) { + auto found = itemDefs.find(id); + if (found != itemDefs.end()) { + return *found->second; + } + checkIdentifier(id); + itemIds.push_back(id); + itemDefs[id] = std::make_unique(id); + return *itemDefs[id]; +} + +BlockMaterial& ContentBuilder::createBlockMaterial(std::string id) { + blockMaterials[id] = std::make_unique(); + auto& material = *blockMaterials[id]; + material.name = id; + return material; +} + +void ContentBuilder::checkIdentifier(std::string id) { + contenttype result; + if (((result = checkContentType(id)) != contenttype::none)) { + throw namereuse_error("name "+id+" is already used", result); + } +} + +contenttype ContentBuilder::checkContentType(std::string id) { + if (blockDefs.find(id) != blockDefs.end()) { + return contenttype::block; + } + if (itemDefs.find(id) != itemDefs.end()) { + return contenttype::item; + } + return contenttype::none; +} + +std::unique_ptr ContentBuilder::build() { + std::vector blockDefsIndices; + auto groups = std::make_unique(); + for (const std::string& name : blockIds) { + Block& def = *blockDefs[name]; + + // Generating runtime info + def.rt.id = blockDefsIndices.size(); + def.rt.emissive = *reinterpret_cast(def.emission); + def.rt.solid = def.model == BlockModel::block; + + if (def.rotatable) { + for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) { + def.rt.hitboxes[i].reserve(def.hitboxes.size()); + for (AABB& aabb : def.hitboxes) { + def.rotations.variants[i].transform(aabb); + def.rt.hitboxes[i].push_back(aabb); + } + } + } + + blockDefsIndices.push_back(&def); + groups->insert(def.drawGroup); + } + + std::vector itemDefsIndices; + for (const std::string& name : itemIds) { + ItemDef& def = *itemDefs[name]; + + // Generating runtime info + def.rt.id = itemDefsIndices.size(); + def.rt.emissive = *reinterpret_cast(def.emission); + itemDefsIndices.push_back(&def); + } + + auto content = std::make_unique( + std::make_unique(blockDefsIndices, itemDefsIndices), + std::move(groups), + std::move(blockDefs), + std::move(itemDefs), + std::move(packs), + std::move(blockMaterials) + ); + + // Now, it's time to resolve foreign keys + for (Block* def : blockDefsIndices) { + def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id; + } + + for (ItemDef* def : itemDefsIndices) { + def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id; + } + + return content; +} diff --git a/src/content/ContentBuilder.hpp b/src/content/ContentBuilder.hpp new file mode 100644 index 00000000..f6bcbd5e --- /dev/null +++ b/src/content/ContentBuilder.hpp @@ -0,0 +1,37 @@ +#ifndef CONTENT_CONTENT_BUILDER_HPP_ +#define CONTENT_CONTENT_BUILDER_HPP_ + +#include "../items/ItemDef.hpp" +#include "../voxels/Block.hpp" +#include "../content/Content.hpp" +#include "../content/ContentPack.hpp" + +#include +#include +#include + +class ContentBuilder { + std::unordered_map> blockDefs; + std::vector blockIds; + + std::unordered_map> itemDefs; + std::vector itemIds; + + std::unordered_map> blockMaterials; + std::unordered_map> packs; +public: + ~ContentBuilder(); + + void add(std::unique_ptr pack); + + Block& createBlock(std::string id); + ItemDef& createItem(std::string id); + BlockMaterial& createBlockMaterial(std::string id); + + void checkIdentifier(std::string id); + contenttype checkContentType(std::string id); + + std::unique_ptr build(); +}; + +#endif // CONTENT_CONTENT_BUILDER_HPP_ diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 9878d9ef..36a7efa8 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -2,6 +2,7 @@ #include "Content.hpp" #include "ContentPack.hpp" +#include "ContentBuilder.hpp" #include "../coders/json.hpp" #include "../core_defs.hpp" #include "../data/dynamic.hpp" @@ -26,9 +27,11 @@ static debug::Logger logger("content-loader"); ContentLoader::ContentLoader(ContentPack* pack) : pack(pack) { } -bool ContentLoader::fixPackIndices(fs::path folder, - dynamic::Map* indicesRoot, - std::string contentSection) { +bool ContentLoader::fixPackIndices( + fs::path folder, + dynamic::Map* indicesRoot, + std::string contentSection +) { std::vector detected; std::vector indexed; if (fs::is_directory(folder)) { @@ -312,22 +315,22 @@ void ContentLoader::loadItem(ItemDef& def, std::string full, std::string name) { } } -BlockMaterial ContentLoader::loadBlockMaterial(fs::path file, std::string full) { +void ContentLoader::loadBlockMaterial(BlockMaterial& def, fs::path file) { auto root = files::read_json(file); - BlockMaterial material {full}; - root->str("steps-sound", material.stepsSound); - root->str("place-sound", material.placeSound); - root->str("break-sound", material.breakSound); - return material; + root->str("steps-sound", def.stepsSound); + root->str("place-sound", def.placeSound); + root->str("break-sound", def.breakSound); } void ContentLoader::load(ContentBuilder& builder) { logger.info() << "loading pack [" << pack->id << "]"; - auto runtime = new ContentPackRuntime(*pack, scripting::create_pack_environment(*pack)); - builder.add(runtime); + auto runtime = std::make_unique( + *pack, scripting::create_pack_environment(*pack) + ); env = runtime->getEnvironment(); ContentPackStats& stats = runtime->getStatsWriteable(); + builder.add(std::move(runtime)); fixPackIndices(); @@ -388,7 +391,7 @@ void ContentLoader::load(ContentBuilder& builder) { for (auto entry : fs::directory_iterator(materialsDir)) { fs::path file = entry.path(); std::string name = pack->id+":"+file.stem().u8string(); - builder.add(loadBlockMaterial(file, name)); + loadBlockMaterial(builder.createBlockMaterial(name), file); } } } diff --git a/src/content/ContentLoader.hpp b/src/content/ContentLoader.hpp index d709f0d0..515d742a 100644 --- a/src/content/ContentLoader.hpp +++ b/src/content/ContentLoader.hpp @@ -1,13 +1,15 @@ #ifndef CONTENT_CONTENT_LOADER_HPP_ #define CONTENT_CONTENT_LOADER_HPP_ -#include "../voxels/Block.hpp" +#include "../typedefs.hpp" #include #include namespace fs = std::filesystem; +class Block; +struct BlockMaterial; class ItemDef; struct ContentPack; class ContentBuilder; @@ -23,7 +25,7 @@ class ContentLoader { void loadBlock(Block& def, std::string full, std::string name); void loadCustomBlockModel(Block& def, dynamic::Map* primitives); void loadItem(ItemDef& def, std::string full, std::string name); - BlockMaterial loadBlockMaterial(fs::path file, std::string full); + void loadBlockMaterial(BlockMaterial& def, fs::path file); public: ContentLoader(ContentPack* pack); diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index d8790b8b..e58fbd84 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -12,17 +12,11 @@ class EnginePaths; namespace fs = std::filesystem; -namespace scripting { - class Environment; -} - class contentpack_error : public std::runtime_error { std::string packId; fs::path folder; public: - contentpack_error(std::string packId, - fs::path folder, - std::string message); + contentpack_error(std::string packId, fs::path folder, std::string message); std::string getPackId() const; fs::path getFolder() const; diff --git a/src/core_defs.cpp b/src/core_defs.cpp index 12e840b4..e0a4e6b0 100644 --- a/src/core_defs.cpp +++ b/src/core_defs.cpp @@ -2,6 +2,7 @@ #include "items/ItemDef.hpp" #include "content/Content.hpp" +#include "content/ContentBuilder.hpp" #include "window/Window.hpp" #include "window/Events.hpp" #include "window/input.hpp" diff --git a/src/engine.cpp b/src/engine.cpp index a903453e..a4b9f5bf 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -9,6 +9,7 @@ #include "coders/imageio.hpp" #include "coders/json.hpp" #include "coders/toml.hpp" +#include "content/ContentBuilder.hpp" #include "content/ContentLoader.hpp" #include "core_defs.hpp" #include "files/files.hpp" @@ -273,7 +274,7 @@ void Engine::loadContent() { ContentLoader loader(&pack); loader.load(contentBuilder); } - content.reset(contentBuilder.build()); + content = contentBuilder.build(); resPaths = std::make_unique(resdir, resRoots); langs::setup(resdir, langs::current->getId(), contentPacks); diff --git a/src/frontend/screens/MenuScreen.cpp b/src/frontend/screens/MenuScreen.cpp index 08d4f8a4..96b7656c 100644 --- a/src/frontend/screens/MenuScreen.cpp +++ b/src/frontend/screens/MenuScreen.cpp @@ -5,6 +5,7 @@ #include "../../graphics/core/Batch2D.hpp" #include "../../graphics/core/Shader.hpp" #include "../../graphics/core/Texture.hpp" +#include "../../maths/UVRegion.hpp" #include "../../window/Window.hpp" #include "../../window/Camera.hpp" #include "../../engine.hpp" From 47c6e35a0b4e0237ff32b4a8ba36b26490cb07f0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 19 May 2024 08:40:43 +0300 Subject: [PATCH 05/97] fix --- src/content/ContentBuilder.cpp | 2 +- src/content/ContentLoader.cpp | 4 ++- src/physics/Hitbox.cpp | 10 +++---- src/physics/Hitbox.hpp | 2 +- src/physics/PhysicsSolver.cpp | 48 +++++++++++++++++----------------- src/physics/PhysicsSolver.hpp | 36 +++++++++++++------------ 6 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/content/ContentBuilder.cpp b/src/content/ContentBuilder.cpp index 16ec0a85..c95f5e5a 100644 --- a/src/content/ContentBuilder.cpp +++ b/src/content/ContentBuilder.cpp @@ -66,7 +66,7 @@ std::unique_ptr ContentBuilder::build() { if (def.rotatable) { for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) { def.rt.hitboxes[i].reserve(def.hitboxes.size()); - for (AABB& aabb : def.hitboxes) { + for (AABB aabb : def.hitboxes) { def.rotations.variants[i].transform(aabb); def.rt.hitboxes[i].push_back(aabb); } diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 36a7efa8..f3c47b6b 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -353,7 +353,9 @@ void ContentLoader::load(ContentBuilder& builder) { std::string full = colon == std::string::npos ? pack->id + ":" + name : name; if (colon != std::string::npos) name[colon] = '/'; auto& def = builder.createBlock(full); - if (colon != std::string::npos) def.scriptName = name.substr(0, colon) + '/' + def.scriptName; + if (colon != std::string::npos) { + def.scriptName = name.substr(0, colon) + '/' + def.scriptName; + } loadBlock(def, full, name); stats.totalBlocks++; if (!def.hidden) { diff --git a/src/physics/Hitbox.cpp b/src/physics/Hitbox.cpp index 4e6c5ba3..df94d9f6 100644 --- a/src/physics/Hitbox.cpp +++ b/src/physics/Hitbox.cpp @@ -1,8 +1,8 @@ #include "Hitbox.hpp" Hitbox::Hitbox(glm::vec3 position, glm::vec3 halfsize) - : position(position), - halfsize(halfsize), - velocity(0.0f,0.0f,0.0f), - linear_damping(0.1f) { -} + : position(position), + halfsize(halfsize), + velocity(0.0f,0.0f,0.0f), + linear_damping(0.1f) +{} diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index 0334e807..a32b0ada 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -14,4 +14,4 @@ public: Hitbox(glm::vec3 position, glm::vec3 halfsize); }; -#endif /* PHYSICS_HITBOX_HPP_ */ +#endif // PHYSICS_HITBOX_HPP_ diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 1c0f9cf1..7c704196 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -6,21 +6,21 @@ #include "../voxels/Chunks.hpp" #include "../voxels/voxel.hpp" -const double E = 0.03; -const double MAX_FIX = 0.1; +const float E = 0.03f; +const float MAX_FIX = 0.1f; PhysicsSolver::PhysicsSolver(glm::vec3 gravity) : gravity(gravity) { } void PhysicsSolver::step( - Chunks* chunks, - Hitbox* hitbox, - float delta, - uint substeps, - bool shifting, - float gravityScale, - bool collisions) -{ + Chunks* chunks, + Hitbox* hitbox, + float delta, + uint substeps, + bool shifting, + float gravityScale, + bool collisions +) { float dt = delta / float(substeps); float linear_damping = hitbox->linear_damping; float s = 2.0f/BLOCK_AABB_GRID; @@ -103,7 +103,7 @@ void PhysicsSolver::colisionCalc( for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ float x = (pos.x-half.x-E); if ((aabb = chunks->isObstacleAt(x,y,z))){ - vel.x *= 0.0f; + vel.x = 0.0f; float newx = floor(x) + aabb->max().x + half.x + E; if (glm::abs(newx-pos.x) <= MAX_FIX) { pos.x = newx; @@ -118,7 +118,7 @@ void PhysicsSolver::colisionCalc( for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ float x = (pos.x+half.x+E); if ((aabb = chunks->isObstacleAt(x,y,z))){ - vel.x *= 0.0f; + vel.x = 0.0f; float newx = floor(x) - half.x + aabb->min().x - E; if (glm::abs(newx-pos.x) <= MAX_FIX) { pos.x = newx; @@ -134,7 +134,7 @@ void PhysicsSolver::colisionCalc( for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ float z = (pos.z-half.z-E); if ((aabb = chunks->isObstacleAt(x,y,z))){ - vel.z *= 0.0f; + vel.z = 0.0f; float newz = floor(z) + aabb->max().z + half.z + E; if (glm::abs(newz-pos.z) <= MAX_FIX) { pos.z = newz; @@ -150,7 +150,7 @@ void PhysicsSolver::colisionCalc( for (float x = (pos.x-half.x+E); x <= (pos.x+half.x-E); x+=s){ float z = (pos.z+half.z+E); if ((aabb = chunks->isObstacleAt(x,y,z))){ - vel.z *= 0.0f; + vel.z = 0.0f; float newz = floor(z) - half.z + aabb->min().z - E; if (glm::abs(newz-pos.z) <= MAX_FIX) { pos.z = newz; @@ -166,7 +166,7 @@ void PhysicsSolver::colisionCalc( for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ float y = (pos.y-half.y-E); if ((aabb = chunks->isObstacleAt(x,y,z))){ - vel.y *= 0.0f; + vel.y = 0.0f; float newy = floor(y) + aabb->max().y + half.y; if (glm::abs(newy-pos.y) <= MAX_FIX) { pos.y = newy; @@ -182,7 +182,7 @@ void PhysicsSolver::colisionCalc( for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ float y = (pos.y-half.y+E); if ((aabb = chunks->isObstacleAt(x,y,z))){ - vel.y *= 0.0f; + vel.y = 0.0f; float newy = floor(y) + aabb->max().y + half.y; if (glm::abs(newy-pos.y) <= MAX_FIX+stepHeight) { pos.y = newy; @@ -197,7 +197,7 @@ void PhysicsSolver::colisionCalc( for (float z = (pos.z-half.z+E); z <= (pos.z+half.z-E); z+=s){ float y = (pos.y+half.y+E); if ((aabb = chunks->isObstacleAt(x,y,z))){ - vel.y *= 0.0f; + vel.y = 0.0f; float newy = floor(y) - half.y + aabb->min().y - E; if (glm::abs(newy-pos.y) <= MAX_FIX) { pos.y = newy; @@ -213,8 +213,8 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) { const glm::vec3& pos = hitbox->position; const glm::vec3& half = hitbox->halfsize; return x >= floor(pos.x-half.x) && x <= floor(pos.x+half.x) && - z >= floor(pos.z-half.z) && z <= floor(pos.z+half.z) && - y >= floor(pos.y-half.y) && y <= floor(pos.y+half.y); + z >= floor(pos.z-half.z) && z <= floor(pos.z+half.z) && + y >= floor(pos.y-half.y) && y <= floor(pos.y+half.y); } bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate_t states, Hitbox* hitbox) { @@ -223,15 +223,15 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate_t voxel v {}; v.states = states; const auto& boxes = def->rotatable - ? def->rt.hitboxes[v.rotation()] - : def->hitboxes; + ? def->rt.hitboxes[v.rotation()] + : def->hitboxes; for (const auto& block_hitbox : boxes) { glm::vec3 min = block_hitbox.min(); glm::vec3 max = block_hitbox.max(); // 0.00001 - inaccuracy - if (min.x < pos.x+half.x-x-0.00001 && max.x > pos.x-half.x-x+0.00001 && - min.z < pos.z+half.z-z-0.00001 && max.z > pos.z-half.z-z+0.00001 && - min.y < pos.y+half.y-y-0.00001 && max.y > pos.y-half.y-y+0.00001) + if (min.x < pos.x+half.x-x-0.00001f && max.x > pos.x-half.x-x+0.00001f && + min.z < pos.z+half.z-z-0.00001f && max.z > pos.z-half.z-z+0.00001f && + min.y < pos.y+half.y-y-0.00001f && max.y > pos.y-half.y-y+0.00001f) return true; } return false; diff --git a/src/physics/PhysicsSolver.hpp b/src/physics/PhysicsSolver.hpp index d1b91dbf..e35f364c 100644 --- a/src/physics/PhysicsSolver.hpp +++ b/src/physics/PhysicsSolver.hpp @@ -1,10 +1,11 @@ #ifndef PHYSICS_PHYSICSSOLVER_HPP_ #define PHYSICS_PHYSICSSOLVER_HPP_ -#include #include "../typedefs.hpp" -#include "../voxels/Block.hpp" +#include + +class Block; class Hitbox; class Chunks; @@ -12,22 +13,25 @@ class PhysicsSolver { glm::vec3 gravity; public: PhysicsSolver(glm::vec3 gravity); - void step(Chunks* chunks, - Hitbox* hitbox, - float delta, - uint substeps, - bool shifting, - float gravityScale, - bool collisions); + void step( + Chunks* chunks, + Hitbox* hitbox, + float delta, + uint substeps, + bool shifting, + float gravityScale, + bool collisions + ); void colisionCalc( - Chunks* chunks, - Hitbox* hitbox, - glm::vec3& vel, - glm::vec3& pos, - const glm::vec3 half, - float stepHeight); + Chunks* chunks, + Hitbox* hitbox, + glm::vec3& vel, + glm::vec3& pos, + const glm::vec3 half, + float stepHeight + ); bool isBlockInside(int x, int y, int z, Hitbox* hitbox); bool isBlockInside(int x, int y, int z, Block* def, blockstate_t states, Hitbox* hitbox); }; -#endif /* PHYSICS_PHYSICSSOLVER_HPP_ */ +#endif // PHYSICS_PHYSICSSOLVER_HPP_ From 997cff04d164963fa0e07ba1934938eb92dc76f0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 19 May 2024 09:17:43 +0300 Subject: [PATCH 06/97] physics-related fixes --- src/objects/Player.cpp | 13 +++++++------ src/physics/PhysicsSolver.cpp | 12 +++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index edd8acec..ba8ccce5 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -35,9 +35,10 @@ Player::~Player() { } void Player::updateInput( - Level* level, - PlayerInput& input, - float delta) { + Level* level, + PlayerInput& input, + float delta +) { bool crouch = input.shift && hitbox->grounded && !input.sprint; float speed = this->speed; if (flight){ @@ -76,9 +77,9 @@ void Player::updateInput( hitbox->velocity.z += dir.z * speed * delta * 9; } - float vel = std::max(glm::length(hitbox->velocity * 0.25f), 1.0f); - int substeps = int(delta * vel * 1000); - substeps = std::min(100, std::max(1, substeps)); + float vel = glm::length(hitbox->velocity); + int substeps = int(delta * vel * 20); + substeps = std::min(100, std::max(2, substeps)); level->physics->step( level->chunks.get(), hitbox.get(), diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 7c704196..6760aa89 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -21,16 +21,17 @@ void PhysicsSolver::step( float gravityScale, bool collisions ) { - float dt = delta / float(substeps); + float dt = delta / static_cast(substeps); float linear_damping = hitbox->linear_damping; float s = 2.0f/BLOCK_AABB_GRID; + + const glm::vec3& half = hitbox->halfsize; + glm::vec3& pos = hitbox->position; + glm::vec3& vel = hitbox->velocity; bool prevGrounded = hitbox->grounded; hitbox->grounded = false; for (uint i = 0; i < substeps; i++) { - glm::vec3& pos = hitbox->position; - glm::vec3& half = hitbox->halfsize; - glm::vec3& vel = hitbox->velocity; float px = pos.x; float pz = pos.z; @@ -41,7 +42,8 @@ void PhysicsSolver::step( } vel.x *= glm::max(0.0f, 1.0f - dt * linear_damping); vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping); - pos += vel * dt; + + pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f; if (shifting && hitbox->grounded){ float y = (pos.y-half.y-E); From ffdeac5c1fb69ce149d22b5e55f9926faa0ae852 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 19 May 2024 10:38:30 +0300 Subject: [PATCH 07/97] main menu glitch fix + refactor --- src/frontend/screens/LevelScreen.cpp | 5 +- src/voxels/VoxelsVolume.cpp | 37 +++++------- src/voxels/VoxelsVolume.hpp | 88 ++++++++++++++-------------- src/voxels/voxel.hpp | 18 +++--- 4 files changed, 72 insertions(+), 76 deletions(-) diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 7f805e27..bed9de27 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -83,8 +83,11 @@ void LevelScreen::saveWorldPreview() { // camera special copy for world preview Camera camera = *player->camera; camera.setFov(glm::radians(70.0f)); + + DrawContext pctx(nullptr, {Window::width, Window::height}, batch.get()); + Viewport viewport(previewSize * 1.5, previewSize); - DrawContext ctx(nullptr, viewport, batch.get()); + DrawContext ctx(&pctx, viewport, batch.get()); worldRenderer->draw(ctx, &camera, false, postProcessing.get()); auto image = postProcessing->toImage(); diff --git a/src/voxels/VoxelsVolume.cpp b/src/voxels/VoxelsVolume.cpp index 73bff62c..5da88add 100644 --- a/src/voxels/VoxelsVolume.cpp +++ b/src/voxels/VoxelsVolume.cpp @@ -1,30 +1,23 @@ #include "VoxelsVolume.hpp" -VoxelsVolume::VoxelsVolume(int x, int y, int z, int w, int h, int d) - : x(x), y(y), z(z), w(w), h(h), d(d) { - voxels = new voxel[w * h * d]; - for (int i = 0; i < w * h * d; i++) { - voxels[i].id = BLOCK_VOID; - } - lights = new light_t[w * h * d]; +VoxelsVolume::VoxelsVolume( + int x, int y, int z, int w, int h, int d +) : x(x), y(y), z(z), w(w), h(h), d(d), + voxels(std::make_unique(w * h * d)), + lights(std::make_unique(w * h * d)) +{ + for (int i = 0; i < w * h * d; i++) { + voxels[i].id = BLOCK_VOID; + } } -VoxelsVolume::VoxelsVolume(int w, int h, int d) - : x(0), y(0), z(0), w(w), h(h), d(d) { - voxels = new voxel[w * h * d]; - for (int i = 0; i < w * h * d; i++) { - voxels[i].id = BLOCK_VOID; - } - lights = new light_t[w * h * d]; -} +VoxelsVolume::VoxelsVolume(int w, int h, int d) : VoxelsVolume(0, 0, 0, w, h, d) +{} -VoxelsVolume::~VoxelsVolume() { - delete[] lights; - delete[] voxels; -} +VoxelsVolume::~VoxelsVolume() {} void VoxelsVolume::setPosition(int x, int y, int z) { - this->x = x; - this->y = y; - this->z = z; + this->x = x; + this->y = y; + this->z = z; } diff --git a/src/voxels/VoxelsVolume.hpp b/src/voxels/VoxelsVolume.hpp index 30406891..d6e6474a 100644 --- a/src/voxels/VoxelsVolume.hpp +++ b/src/voxels/VoxelsVolume.hpp @@ -6,62 +6,62 @@ #include "voxel.hpp" class VoxelsVolume { - int x, y, z; - int w, h, d; - voxel* voxels; - light_t* lights; + int x, y, z; + int w, h, d; + std::unique_ptr voxels; + std::unique_ptr lights; public: - VoxelsVolume(int w, int h, int d); - VoxelsVolume(int x, int y, int z, int w, int h, int d); - virtual ~VoxelsVolume(); + VoxelsVolume(int w, int h, int d); + VoxelsVolume(int x, int y, int z, int w, int h, int d); + virtual ~VoxelsVolume(); - void setPosition(int x, int y, int z); + void setPosition(int x, int y, int z); - int getX() const { - return x; - } + int getX() const { + return x; + } - int getY() const { - return y; - } + int getY() const { + return y; + } - int getZ() const { - return z; - } + int getZ() const { + return z; + } - int getW() const { - return w; - } + int getW() const { + return w; + } - int getH() const { - return h; - } + int getH() const { + return h; + } - int getD() const { - return d; - } + int getD() const { + return d; + } - voxel* getVoxels() const { - return voxels; - } + voxel* getVoxels() const { + return voxels.get(); + } - light_t* getLights() const { - return lights; - } + light_t* getLights() const { + return lights.get(); + } - inline blockid_t pickBlockId(int bx, int by, int bz) const { - if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h || bz >= z + d) { - return BLOCK_VOID; - } - return voxels[vox_index(bx - x, by - y, bz - z, w, d)].id; - } + inline blockid_t pickBlockId(int bx, int by, int bz) const { + if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h || bz >= z + d) { + return BLOCK_VOID; + } + return voxels[vox_index(bx - x, by - y, bz - z, w, d)].id; + } - inline light_t pickLight(int bx, int by, int bz) const { - if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h || bz >= z + d) { - return 0; - } - return lights[vox_index(bx - x, by - y, bz - z, w, d)]; - } + inline light_t pickLight(int bx, int by, int bz) const { + if (bx < x || by < y || bz < z || bx >= x + w || by >= y + h || bz >= z + d) { + return 0; + } + return lights[vox_index(bx - x, by - y, bz - z, w, d)]; + } }; #endif // VOXELS_VOXELSVOLUME_HPP_ diff --git a/src/voxels/voxel.hpp b/src/voxels/voxel.hpp index a39e6305..db2c8138 100644 --- a/src/voxels/voxel.hpp +++ b/src/voxels/voxel.hpp @@ -3,17 +3,17 @@ #include "../typedefs.hpp" -const int BLOCK_DIR_NORTH = 0x0; -const int BLOCK_DIR_WEST = 0x1; -const int BLOCK_DIR_SOUTH = 0x2; -const int BLOCK_DIR_EAST = 0x3; -const int BLOCK_DIR_UP = 0x4; -const int BLOCK_DIR_DOWN = 0x5; +inline constexpr int BLOCK_DIR_NORTH = 0x0; +inline constexpr int BLOCK_DIR_WEST = 0x1; +inline constexpr int BLOCK_DIR_SOUTH = 0x2; +inline constexpr int BLOCK_DIR_EAST = 0x3; +inline constexpr int BLOCK_DIR_UP = 0x4; +inline constexpr int BLOCK_DIR_DOWN = 0x5; // limited to 8 block orientations -const int BLOCK_ROT_MASK = 0b0000'0111; +inline constexpr int BLOCK_ROT_MASK = 0b0000'0111; // reserved bits -const int BLOCK_RESERVED_MASK = 0b1111'1000; +inline constexpr int BLOCK_RESERVED_MASK = 0b1111'1000; struct voxel { blockid_t id; @@ -28,4 +28,4 @@ struct voxel { } }; -#endif /* VOXELS_VOXEL_HPP_ */ +#endif // VOXELS_VOXEL_HPP_ From c94d40ab02963116466e71f9b25b3978ae270491 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 20 May 2024 01:28:42 +0300 Subject: [PATCH 08/97] toml parser update + 'toml' module is built-in now --- res/modules/toml.lua | 65 +------------- src/coders/toml.cpp | 121 ++++++++++++++++++--------- src/coders/toml.hpp | 7 +- src/data/dynamic.hpp | 3 + src/frontend/screens/LevelScreen.cpp | 32 +++---- src/frontend/screens/LevelScreen.hpp | 2 + src/logic/scripting/lua/LuaState.cpp | 120 ++++++++++++++------------ src/logic/scripting/lua/LuaState.hpp | 2 + src/logic/scripting/lua/api_lua.hpp | 7 +- src/logic/scripting/lua/libinput.cpp | 4 +- src/logic/scripting/lua/libtoml.cpp | 37 ++++++++ src/util/stringutil.cpp | 11 +++ src/util/stringutil.hpp | 2 + src/window/input.cpp | 14 ++++ src/window/input.hpp | 3 + 15 files changed, 252 insertions(+), 178 deletions(-) create mode 100644 src/logic/scripting/lua/libtoml.cpp diff --git a/res/modules/toml.lua b/res/modules/toml.lua index fb082e75..33c8faf1 100644 --- a/res/modules/toml.lua +++ b/res/modules/toml.lua @@ -1,65 +1,2 @@ --- 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 - +print("WARNING: toml is replaced with built-in library, just remove 'require \"core:toml\"'") return toml diff --git a/src/coders/toml.cpp b/src/coders/toml.cpp index dfa0e467..740c2733 100644 --- a/src/coders/toml.cpp +++ b/src/coders/toml.cpp @@ -7,15 +7,14 @@ #include "../files/settings_io.hpp" #include -#include #include #include #include using namespace toml; -class Reader : BasicParser { - SettingsHandler& handler; +class TomlReader : BasicParser { + dynamic::Map_sptr root; void skipWhitespace() override { BasicParser::skipWhitespace(); @@ -26,7 +25,34 @@ class Reader : BasicParser { } } } - void readSection(const std::string& section) { + + dynamic::Map& getSection(const std::string& section) { + if (section.empty()) { + return *root; + } + size_t offset = 0; + auto& rootMap = *root; + do { + size_t index = section.find('.', offset); + if (index == std::string::npos) { + auto map = rootMap.map(section); + if (map == nullptr) { + return rootMap.putMap(section); + } + return *map; + } + auto subsection = section.substr(offset, index); + auto map = rootMap.map(subsection); + if (map == nullptr) { + rootMap = rootMap.putMap(subsection); + } else { + rootMap = *map; + } + offset = index+1; + } while (true); + } + + void readSection(const std::string& section, dynamic::Map& map) { while (hasNext()) { skipWhitespace(); if (!hasNext()) { @@ -36,43 +62,31 @@ class Reader : BasicParser { if (c == '[') { std::string name = parseName(); pos++; - readSection(name); + readSection(name, getSection(name)); return; } pos--; - std::string name = section+"."+parseName(); + std::string name = parseName(); expect('='); c = peek(); if (is_digit(c)) { - auto num = parseNumber(1); - if (handler.has(name)) { - handler.setValue(name, num); - } + map.put(name, parseNumber(1)); } else if (c == '-' || c == '+') { int sign = c == '-' ? -1 : 1; pos++; - auto num = parseNumber(sign); - if (handler.has(name)) { - handler.setValue(name, num); - } + map.put(name, parseNumber(sign)); } else if (is_identifier_start(c)) { std::string identifier = parseName(); - if (handler.has(name)) { - if (identifier == "true" || identifier == "false") { - bool flag = identifier == "true"; - handler.setValue(name, flag); - } else if (identifier == "inf") { - handler.setValue(name, INFINITY); - } else if (identifier == "nan") { - handler.setValue(name, NAN); - } + if (identifier == "true" || identifier == "false") { + map.put(name, identifier == "true"); + } else if (identifier == "inf") { + map.put(name, INFINITY); + } else if (identifier == "nan") { + map.put(name, NAN); } } else if (c == '"' || c == '\'') { pos++; - std::string str = parseString(c); - if (handler.has(name)) { - handler.setValue(name, str); - } + map.put(name, parseString(c)); } else { throw error("feature is not supported"); } @@ -81,29 +95,60 @@ class Reader : BasicParser { } public: - Reader( - SettingsHandler& handler, + TomlReader( std::string_view file, std::string_view source) - : BasicParser(file, source), handler(handler) { + : BasicParser(file, source) { + root = dynamic::create_map(); } - void read() { + dynamic::Map_sptr read() { skipWhitespace(); if (!hasNext()) { - return; + return root; } - readSection(""); + readSection("", *root); + return root; } }; +dynamic::Map_sptr toml::parse(std::string_view file, std::string_view source) { + return TomlReader(file, source).read(); +} + void toml::parse( - SettingsHandler& handler, - const std::string& file, - const std::string& source + SettingsHandler& handler, std::string_view file, std::string_view source ) { - Reader reader(handler, file, source); - reader.read(); + auto map = parse(file, source); + for (auto& entry : map->values) { + const auto& sectionName = entry.first; + auto sectionMap = std::get_if(&entry.second); + if (sectionMap == nullptr) { + continue; + } + for (auto& sectionEntry : (*sectionMap)->values) { + const auto& name = sectionEntry.first; + auto& value = sectionEntry.second; + auto fullname = sectionName+"."+name; + if (handler.has(fullname)) { + handler.setValue(fullname, value); + } + } + } +} + +std::string toml::stringify(dynamic::Map& root) { + std::stringstream ss; + for (auto& sectionEntry : root.values) { + ss << "[" << sectionEntry.first << "]\n"; + auto sectionMap = std::get_if(§ionEntry.second); + for (auto& entry : (*sectionMap)->values) { + ss << entry.first << " = "; + ss << entry.second << "\n"; + } + ss << "\n"; + } + return ss.str(); } std::string toml::stringify(SettingsHandler& handler) { diff --git a/src/coders/toml.hpp b/src/coders/toml.hpp index 4574e468..b4b5d356 100644 --- a/src/coders/toml.hpp +++ b/src/coders/toml.hpp @@ -1,6 +1,7 @@ #ifndef CODERS_TOML_HPP_ #define CODERS_TOML_HPP_ +#include "../data/dynamic.hpp" #include "commons.hpp" #include @@ -9,11 +10,13 @@ class SettingsHandler; namespace toml { std::string stringify(SettingsHandler& handler); + std::string stringify(dynamic::Map& root); + dynamic::Map_sptr parse(std::string_view file, std::string_view source); void parse( SettingsHandler& handler, - const std::string& file, - const std::string& source + std::string_view file, + std::string_view source ); } diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index 93e87b4b..4c5b602c 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -152,6 +152,9 @@ namespace dynamic { Map& put(std::string key, bool value) { return put(key, Value(static_cast(value))); } + Map& put(std::string key, const char* value) { + return put(key, Value(value)); + } Map& put(std::string key, const Value& value); void remove(const std::string& key); diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index bed9de27..fea96193 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -2,26 +2,26 @@ #include "../hud.hpp" #include "../LevelFrontend.hpp" -#include "../../debug/Logger.hpp" #include "../../audio/audio.hpp" #include "../../coders/imageio.hpp" -#include "../../graphics/core/PostProcessing.hpp" +#include "../../debug/Logger.hpp" +#include "../../engine.hpp" #include "../../graphics/core/DrawContext.hpp" -#include "../../graphics/core/Viewport.hpp" #include "../../graphics/core/ImageData.hpp" -#include "../../graphics/ui/GUI.hpp" -#include "../../graphics/ui/elements/Menu.hpp" +#include "../../graphics/core/PostProcessing.hpp" +#include "../../graphics/core/Viewport.hpp" #include "../../graphics/render/WorldRenderer.hpp" +#include "../../graphics/ui/elements/Menu.hpp" +#include "../../graphics/ui/GUI.hpp" #include "../../logic/LevelController.hpp" #include "../../logic/scripting/scripting_hud.hpp" #include "../../physics/Hitbox.hpp" #include "../../voxels/Chunks.hpp" -#include "../../world/Level.hpp" -#include "../../world/World.hpp" #include "../../window/Camera.hpp" #include "../../window/Events.hpp" #include "../../window/Window.hpp" -#include "../../engine.hpp" +#include "../../world/Level.hpp" +#include "../../world/World.hpp" static debug::Logger logger("level-screen"); @@ -55,16 +55,20 @@ LevelScreen::LevelScreen(Engine* engine, std::unique_ptr level) void LevelScreen::initializeContent() { auto content = controller->getLevel()->content; for (auto& entry : content->getPacks()) { - auto pack = entry.second.get(); - const ContentPack& info = pack->getInfo(); - fs::path scriptFile = info.folder/fs::path("scripts/hud.lua"); - if (fs::is_regular_file(scriptFile)) { - scripting::load_hud_script(pack->getEnvironment(), info.id, scriptFile); - } + initializePack(entry.second.get()); } scripting::on_frontend_init(hud.get()); } +void LevelScreen::initializePack(ContentPackRuntime* pack) { + const ContentPack& info = pack->getInfo(); + fs::path scriptFile = info.folder/fs::path("scripts/hud.lua"); + if (fs::is_regular_file(scriptFile)) { + scripting::load_hud_script(pack->getEnvironment(), info.id, scriptFile); + } + auto configFolder = info.folder/fs::path("config"); +} + LevelScreen::~LevelScreen() { saveWorldPreview(); scripting::on_frontend_close(); diff --git a/src/frontend/screens/LevelScreen.hpp b/src/frontend/screens/LevelScreen.hpp index 8548c06c..2b5f3527 100644 --- a/src/frontend/screens/LevelScreen.hpp +++ b/src/frontend/screens/LevelScreen.hpp @@ -12,6 +12,7 @@ class LevelController; class WorldRenderer; class TextureAnimator; class PostProcessing; +class ContentPackRuntime; class Level; class LevelScreen : public Screen { @@ -27,6 +28,7 @@ class LevelScreen : public Screen { bool hudVisible = true; void updateHotkeys(); void initializeContent(); + void initializePack(ContentPackRuntime* pack); public: LevelScreen(Engine* engine, std::unique_ptr level); ~LevelScreen(); diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index 902e9bf3..1a860670 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -12,14 +12,16 @@ inline std::string LAMBDAS_TABLE = "$L"; static debug::Logger logger("lua-state"); +using namespace lua; + namespace scripting { - extern lua::LuaState* state; + extern LuaState* state; } -lua::luaerror::luaerror(const std::string& message) : std::runtime_error(message) { +luaerror::luaerror(const std::string& message) : std::runtime_error(message) { } -void lua::LuaState::removeLibFuncs(const char* libname, const char* funcs[]) { +void LuaState::removeLibFuncs(const char* libname, const char* funcs[]) { if (getglobal(libname)) { for (uint i = 0; funcs[i]; i++) { pushnil(); @@ -28,13 +30,13 @@ void lua::LuaState::removeLibFuncs(const char* libname, const char* funcs[]) { } } -lua::LuaState::LuaState() { +LuaState::LuaState() { logger.info() << LUA_VERSION; logger.info() << LUAJIT_VERSION; L = luaL_newstate(); if (L == nullptr) { - throw lua::luaerror("could not to initialize Lua"); + throw luaerror("could not to initialize Lua"); } // Allowed standard libraries luaopen_base(L); @@ -66,24 +68,24 @@ lua::LuaState::LuaState() { setglobal(LAMBDAS_TABLE); } -const std::string lua::LuaState::envName(int env) { +const std::string LuaState::envName(int env) { return "_ENV"+util::mangleid(env); } -lua::LuaState::~LuaState() { +LuaState::~LuaState() { lua_close(L); } -void lua::LuaState::logError(const std::string& text) { +void LuaState::logError(const std::string& text) { logger.error() << text; } -void lua::LuaState::addfunc(const std::string& name, lua_CFunction func) { +void LuaState::addfunc(const std::string& name, lua_CFunction func) { lua_pushcfunction(L, func); lua_setglobal(L, name.c_str()); } -bool lua::LuaState::getglobal(const std::string& name) { +bool LuaState::getglobal(const std::string& name) { lua_getglobal(L, name.c_str()); if (lua_isnil(L, lua_gettop(L))) { lua_pop(L, lua_gettop(L)); @@ -92,7 +94,7 @@ bool lua::LuaState::getglobal(const std::string& name) { return true; } -bool lua::LuaState::hasglobal(const std::string& name) { +bool LuaState::hasglobal(const std::string& name) { lua_getglobal(L, name.c_str()); if (lua_isnil(L, lua_gettop(L))) { lua_pop(L, lua_gettop(L)); @@ -102,11 +104,11 @@ bool lua::LuaState::hasglobal(const std::string& name) { return true; } -void lua::LuaState::setglobal(const std::string& name) { +void LuaState::setglobal(const std::string& name) { lua_setglobal(L, name.c_str()); } -bool lua::LuaState::rename(const std::string& from, const std::string& to) { +bool LuaState::rename(const std::string& from, const std::string& to) { const char* src = from.c_str(); lua_getglobal(L, src); if (lua_isnil(L, lua_gettop(L))) { @@ -121,12 +123,12 @@ bool lua::LuaState::rename(const std::string& from, const std::string& to) { return true; } -void lua::LuaState::remove(const std::string& name) { +void LuaState::remove(const std::string& name) { lua_pushnil(L); lua_setglobal(L, name.c_str()); } -void lua::LuaState::createLibs() { +void LuaState::createLibs() { openlib("audio", audiolib); openlib("block", blocklib); openlib("console", consolelib); @@ -140,28 +142,29 @@ void lua::LuaState::createLibs() { openlib("pack", packlib); openlib("player", playerlib); openlib("time", timelib); + openlib("toml", tomllib); openlib("world", worldlib); addfunc("print", lua_wrap_errors); } -void lua::LuaState::loadbuffer(int env, const std::string& src, const std::string& file) { +void LuaState::loadbuffer(int env, const std::string& src, const std::string& file) { if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) { - throw lua::luaerror(lua_tostring(L, -1)); + throw luaerror(lua_tostring(L, -1)); } if (env && getglobal(envName(env))) { lua_setfenv(L, -2); } } -int lua::LuaState::call(int argc, int nresults) { +int LuaState::call(int argc, int nresults) { if (lua_pcall(L, argc, nresults, 0)) { - throw lua::luaerror(lua_tostring(L, -1)); + throw luaerror(lua_tostring(L, -1)); } return 1; } -int lua::LuaState::callNoThrow(int argc) { +int LuaState::callNoThrow(int argc) { if (lua_pcall(L, argc, LUA_MULTRET, 0)) { logError(lua_tostring(L, -1)); return 0; @@ -169,59 +172,59 @@ int lua::LuaState::callNoThrow(int argc) { return 1; } -int lua::LuaState::eval(int env, const std::string& src, const std::string& file) { +int LuaState::eval(int env, const std::string& src, const std::string& file) { auto srcText = "return "+src; loadbuffer(env, srcText, file); return call(0); } -int lua::LuaState::execute(int env, const std::string& src, const std::string& file) { +int LuaState::execute(int env, const std::string& src, const std::string& file) { loadbuffer(env, src, file); return callNoThrow(0); } -int lua::LuaState::gettop() const { +int LuaState::gettop() const { return lua_gettop(L); } -int lua::LuaState::pushinteger(luaint x) { +int LuaState::pushinteger(luaint x) { lua_pushinteger(L, x); return 1; } -int lua::LuaState::pushnumber(luanumber x) { +int LuaState::pushnumber(luanumber x) { lua_pushnumber(L, x); return 1; } -int lua::LuaState::pushboolean(bool x) { +int LuaState::pushboolean(bool x) { lua_pushboolean(L, x); return 1; } -int lua::LuaState::pushivec3(luaint x, luaint y, luaint z) { +int LuaState::pushivec3(luaint x, luaint y, luaint z) { lua::pushivec3(L, x, y, z); return 3; } -int lua::LuaState::pushstring(const std::string& str) { +int LuaState::pushstring(const std::string& str) { lua_pushstring(L, str.c_str()); return 1; } -int lua::LuaState::pushenv(int env) { +int LuaState::pushenv(int env) { if (getglobal(envName(env))) { return 1; } return 0; } -int lua::LuaState::pushvalue(int idx) { +int LuaState::pushvalue(int idx) { lua_pushvalue(L, idx); return 1; } -int lua::LuaState::pushvalue(const dynamic::Value& value) { +int LuaState::pushvalue(const dynamic::Value& value) { using namespace dynamic; if (auto* flag = std::get_if(&value)) { @@ -252,26 +255,26 @@ int lua::LuaState::pushvalue(const dynamic::Value& value) { return 1; } -int lua::LuaState::pushglobals() { +int LuaState::pushglobals() { lua_pushvalue(L, LUA_GLOBALSINDEX); return 1; } -int lua::LuaState::pushcfunction(lua_CFunction function) { +int LuaState::pushcfunction(lua_CFunction function) { lua_pushcfunction(L, function); return 1; } -void lua::LuaState::pop(int n) { +void LuaState::pop(int n) { lua_pop(L, n); } -int lua::LuaState::pushnil() { +int LuaState::pushnil() { lua_pushnil(L); return 1; } -bool lua::LuaState::getfield(const std::string& name, int idx) { +bool LuaState::getfield(const std::string& name, int idx) { lua_getfield(L, idx, name.c_str()); if (lua_isnil(L, -1)) { lua_pop(L, -1); @@ -280,35 +283,35 @@ bool lua::LuaState::getfield(const std::string& name, int idx) { return true; } -void lua::LuaState::setfield(const std::string& name, int idx) { +void LuaState::setfield(const std::string& name, int idx) { lua_setfield(L, idx, name.c_str()); } -bool lua::LuaState::toboolean(int idx) { +bool LuaState::toboolean(int idx) { return lua_toboolean(L, idx); } -lua::luaint lua::LuaState::tointeger(int idx) { +luaint LuaState::tointeger(int idx) { return lua_tointeger(L, idx); } -lua::luanumber lua::LuaState::tonumber(int idx) { +luanumber LuaState::tonumber(int idx) { return lua_tonumber(L, idx); } -glm::vec2 lua::LuaState::tovec2(int idx) { +glm::vec2 LuaState::tovec2(int idx) { return lua::tovec2(L, idx); } -glm::vec4 lua::LuaState::tocolor(int idx) { +glm::vec4 LuaState::tocolor(int idx) { return lua::tocolor(L, idx); } -const char* lua::LuaState::tostring(int idx) { +const char* LuaState::tostring(int idx) { return lua_tostring(L, idx); } -dynamic::Value lua::LuaState::tovalue(int idx) { +dynamic::Value LuaState::tovalue(int idx) { using namespace dynamic; auto type = lua_type(L, idx); switch (type) { @@ -361,21 +364,21 @@ dynamic::Value lua::LuaState::tovalue(int idx) { } } -bool lua::LuaState::isstring(int idx) { +bool LuaState::isstring(int idx) { return lua_isstring(L, idx); } -bool lua::LuaState::isfunction(int idx) { +bool LuaState::isfunction(int idx) { return lua_isfunction(L, idx); } -void lua::LuaState::openlib(const std::string& name, const luaL_Reg* libfuncs) { +void LuaState::openlib(const std::string& name, const luaL_Reg* libfuncs) { lua_newtable(L); luaL_setfuncs(L, libfuncs, 0); lua_setglobal(L, name.c_str()); } -std::shared_ptr lua::LuaState::createLambdaHandler() { +std::shared_ptr LuaState::createLambdaHandler() { auto ptr = reinterpret_cast(lua_topointer(L, -1)); auto name = util::mangleid(ptr); lua_getglobal(L, LAMBDAS_TABLE.c_str()); @@ -392,7 +395,7 @@ std::shared_ptr lua::LuaState::createLambdaHandler() { }); } -runnable lua::LuaState::createRunnable() { +runnable LuaState::createRunnable() { auto funcptr = createLambdaHandler(); return [=]() { lua_getglobal(L, LAMBDAS_TABLE.c_str()); @@ -401,7 +404,7 @@ runnable lua::LuaState::createRunnable() { }; } -scripting::common_func lua::LuaState::createLambda() { +scripting::common_func LuaState::createLambda() { auto funcptr = createLambdaHandler(); return [=](const std::vector& args) { lua_getglobal(L, LAMBDAS_TABLE.c_str()); @@ -418,7 +421,14 @@ scripting::common_func lua::LuaState::createLambda() { }; } -int lua::LuaState::createEnvironment(int parent) { +const char* LuaState::requireString(int idx) { + if (!lua_isstring(L, idx)) { + throw luaerror("string expected at "+std::to_string(idx)); + } + return lua_tostring(L, idx); +} + +int LuaState::createEnvironment(int parent) { int id = nextEnvironment++; // local env = {} @@ -442,7 +452,7 @@ int lua::LuaState::createEnvironment(int parent) { } -void lua::LuaState::removeEnvironment(int id) { +void LuaState::removeEnvironment(int id) { if (id == 0) { return; } @@ -450,7 +460,7 @@ void lua::LuaState::removeEnvironment(int id) { setglobal(envName(id)); } -bool lua::LuaState::emit_event(const std::string &name, std::function args) { +bool LuaState::emit_event(const std::string &name, std::function args) { getglobal("events"); getfield("emit"); pushstring(name); @@ -461,7 +471,7 @@ bool lua::LuaState::emit_event(const std::string &name, std::function args=[](auto*){return 0;}); diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index 4d798d82..69526057 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -8,19 +8,20 @@ // Libraries extern const luaL_Reg audiolib []; extern const luaL_Reg blocklib []; +extern const luaL_Reg consolelib []; extern const luaL_Reg corelib []; extern const luaL_Reg filelib []; extern const luaL_Reg guilib []; extern const luaL_Reg hudlib []; +extern const luaL_Reg inputlib []; extern const luaL_Reg inventorylib []; extern const luaL_Reg itemlib []; +extern const luaL_Reg jsonlib []; extern const luaL_Reg packlib []; extern const luaL_Reg playerlib []; extern const luaL_Reg timelib []; +extern const luaL_Reg tomllib []; extern const luaL_Reg worldlib []; -extern const luaL_Reg jsonlib []; -extern const luaL_Reg inputlib []; -extern const luaL_Reg consolelib []; // Lua Overrides extern int l_print(lua_State* L); diff --git a/src/logic/scripting/lua/libinput.cpp b/src/logic/scripting/lua/libinput.cpp index 7f3fbc20..beb2c5de 100644 --- a/src/logic/scripting/lua/libinput.cpp +++ b/src/logic/scripting/lua/libinput.cpp @@ -20,13 +20,13 @@ namespace scripting { using namespace scripting; static int l_keycode(lua_State* L) { - const char* name = lua_tostring(L, 1); + const char* name = state->requireString(1); lua_pushinteger(L, static_cast(input_util::keycode_from(name))); return 1; } static int l_add_callback(lua_State* L) { - auto bindname = lua_tostring(L, 1); + auto bindname = state->requireString(1); const auto& bind = Events::bindings.find(bindname); if (bind == Events::bindings.end()) { throw std::runtime_error("unknown binding "+util::quote(bindname)); diff --git a/src/logic/scripting/lua/libtoml.cpp b/src/logic/scripting/lua/libtoml.cpp new file mode 100644 index 00000000..4bb4a123 --- /dev/null +++ b/src/logic/scripting/lua/libtoml.cpp @@ -0,0 +1,37 @@ +#include "api_lua.hpp" +#include "lua_commons.hpp" +#include "LuaState.hpp" + +#include "../../../coders/toml.hpp" +#include "../../../data/dynamic.hpp" + +namespace scripting { + extern lua::LuaState* state; +} +using namespace scripting; + +static int l_toml_stringify(lua_State* L) { + auto value = state->tovalue(1); + + if (auto mapptr = std::get_if(&value)) { + auto string = toml::stringify(**mapptr); + lua_pushstring(L, string.c_str()); + return 1; + } else { + throw std::runtime_error("table expected"); + } +} + +static int l_toml_parse(lua_State*) { + auto string = state->requireString(1); + auto element = toml::parse("", string); + auto value = std::make_unique(element); + state->pushvalue(*value); + return 1; +} + +const luaL_Reg tomllib [] = { + {"serialize", lua_wrap_errors}, + {"deserialize", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index 9480af4c..804d9a99 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -443,3 +443,14 @@ std::string util::format_data_size(size_t size) { std::to_string(static_cast(round(remainder/1024.0f)))+ postfixes[group]; } + +std::pair util::split_at(std::string_view view, char c) { + size_t idx = view.find(c); + if (idx == std::string::npos) { + throw std::runtime_error(util::quote(std::string({c}))+" not found"); + } + return std::make_pair( + std::string(view.substr(0, idx)), + std::string(view.substr(idx+1)) + ); +} diff --git a/src/util/stringutil.hpp b/src/util/stringutil.hpp index 3270c92e..ffac1eab 100644 --- a/src/util/stringutil.hpp +++ b/src/util/stringutil.hpp @@ -57,6 +57,8 @@ namespace util { std::vector split(const std::wstring& str, char delimiter); std::string format_data_size(size_t size); + + std::pair split_at(std::string_view view, char c); } #endif // UTIL_STRINGUTIL_HPP_ diff --git a/src/window/input.cpp b/src/window/input.cpp index 2d1d7c65..bdb8bbcd 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -32,6 +32,12 @@ static std::unordered_map keycodes { {"up", GLFW_KEY_UP}, }; +static std::unordered_map mousecodes { + {"left", GLFW_MOUSE_BUTTON_1}, + {"right", GLFW_MOUSE_BUTTON_2}, + {"middle", GLFW_MOUSE_BUTTON_3}, +}; + void Binding::reset(inputtype type, int code) { this->type = type; this->code = code; @@ -65,6 +71,14 @@ keycode input_util::keycode_from(const std::string& name) { return static_cast(found->second); } +mousecode input_util::mousecode_from(const std::string& name) { + const auto& found = mousecodes.find(name); + if (found == mousecodes.end()) { + return mousecode::UNKNOWN; + } + return static_cast(found->second); +} + std::string input_util::to_string(keycode code) { int icode_repr = static_cast(code); #ifdef _WIN32 diff --git a/src/window/input.hpp b/src/window/input.hpp index 72aedb95..21ca63c1 100644 --- a/src/window/input.hpp +++ b/src/window/input.hpp @@ -103,6 +103,7 @@ enum class mousecode : int { BUTTON_1 = 0, // Left mouse button BUTTON_2 = 1, // Right mouse button BUTTON_3 = 2, // Middle mouse button + UNKNOWN = -1, }; inline mousecode MOUSECODES_ALL[] { @@ -115,6 +116,8 @@ namespace input_util { void initialize(); keycode keycode_from(const std::string& name); + mousecode mousecode_from(const std::string& name); + /// @return Key label by keycode std::string to_string(keycode code); /// @return Mouse button label by keycode From 45862269e7d97d8f6d72e459f7e84fa62da0327d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 20 May 2024 02:09:01 +0300 Subject: [PATCH 09/97] toml: nested maps support --- src/coders/toml.cpp | 19 +++++++++++++------ src/coders/toml.hpp | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/coders/toml.cpp b/src/coders/toml.cpp index 740c2733..e20a0875 100644 --- a/src/coders/toml.cpp +++ b/src/coders/toml.cpp @@ -137,16 +137,23 @@ void toml::parse( } } -std::string toml::stringify(dynamic::Map& root) { +std::string toml::stringify(dynamic::Map& root, const std::string& name) { std::stringstream ss; - for (auto& sectionEntry : root.values) { - ss << "[" << sectionEntry.first << "]\n"; - auto sectionMap = std::get_if(§ionEntry.second); - for (auto& entry : (*sectionMap)->values) { + if (!name.empty()) { + ss << "[" << name << "]\n"; + } + for (auto& entry : root.values) { + if (!std::holds_alternative(entry.second)) { ss << entry.first << " = "; ss << entry.second << "\n"; } - ss << "\n"; + } + for (auto& entry : root.values) { + if (auto submap = std::get_if(&entry.second)) { + ss << "\n" << toml::stringify( + **submap, name.empty() ? entry.first : name+"."+entry.first + ); + } } return ss.str(); } diff --git a/src/coders/toml.hpp b/src/coders/toml.hpp index b4b5d356..d658eb20 100644 --- a/src/coders/toml.hpp +++ b/src/coders/toml.hpp @@ -10,7 +10,7 @@ class SettingsHandler; namespace toml { std::string stringify(SettingsHandler& handler); - std::string stringify(dynamic::Map& root); + std::string stringify(dynamic::Map& root, const std::string& name=""); dynamic::Map_sptr parse(std::string_view file, std::string_view source); void parse( From 7fdacffe53c7735a0c2eaf4c2fc4e96337975b24 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 20 May 2024 03:06:26 +0300 Subject: [PATCH 10/97] json-related refactor --- src/assets/assetload_funcs.cpp | 1 + src/coders/binary_json.hpp | 28 ++++++++++++++-------------- src/coders/json.cpp | 6 ++++-- src/coders/json.hpp | 13 ++++--------- src/files/files.cpp | 4 ++-- src/logic/scripting/lua/libjson.cpp | 5 +---- src/window/input.cpp | 8 ++++---- 7 files changed, 30 insertions(+), 35 deletions(-) diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index ea4560b5..9dae4c78 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -6,6 +6,7 @@ #include "../audio/audio.hpp" #include "../files/files.hpp" #include "../files/engine_paths.hpp" +#include "../coders/commons.hpp" #include "../coders/imageio.hpp" #include "../coders/json.hpp" #include "../coders/GLSLExtension.hpp" diff --git a/src/coders/binary_json.hpp b/src/coders/binary_json.hpp index ba7531bc..c79a7d4d 100644 --- a/src/coders/binary_json.hpp +++ b/src/coders/binary_json.hpp @@ -11,20 +11,20 @@ namespace dynamic { } namespace json { - const int BJSON_END = 0x0; - const int BJSON_TYPE_DOCUMENT = 0x1; - const int BJSON_TYPE_LIST = 0x2; - const int BJSON_TYPE_BYTE = 0x3; - const int BJSON_TYPE_INT16 = 0x4; - const int BJSON_TYPE_INT32 = 0x5; - const int BJSON_TYPE_INT64 = 0x6; - const int BJSON_TYPE_NUMBER = 0x7; - const int BJSON_TYPE_STRING = 0x8; - const int BJSON_TYPE_BYTES = 0x9; - const int BJSON_TYPE_FALSE = 0xA; - const int BJSON_TYPE_TRUE = 0xB; - const int BJSON_TYPE_NULL = 0xC; - const int BJSON_TYPE_CDOCUMENT = 0x1F; + inline constexpr int BJSON_END = 0x0; + inline constexpr int BJSON_TYPE_DOCUMENT = 0x1; + inline constexpr int BJSON_TYPE_LIST = 0x2; + inline constexpr int BJSON_TYPE_BYTE = 0x3; + inline constexpr int BJSON_TYPE_INT16 = 0x4; + inline constexpr int BJSON_TYPE_INT32 = 0x5; + inline constexpr int BJSON_TYPE_INT64 = 0x6; + inline constexpr int BJSON_TYPE_NUMBER = 0x7; + inline constexpr int BJSON_TYPE_STRING = 0x8; + inline constexpr int BJSON_TYPE_BYTES = 0x9; + inline constexpr int BJSON_TYPE_FALSE = 0xA; + inline constexpr int BJSON_TYPE_TRUE = 0xB; + inline constexpr int BJSON_TYPE_NULL = 0xC; + inline constexpr int BJSON_TYPE_CDOCUMENT = 0x1F; extern std::vector to_binary(const dynamic::Map* obj, bool compress=false); extern std::shared_ptr from_binary(const ubyte* src, size_t size); diff --git a/src/coders/json.cpp b/src/coders/json.cpp index 89f06354..19b59726 100644 --- a/src/coders/json.cpp +++ b/src/coders/json.cpp @@ -1,5 +1,7 @@ #include "json.hpp" +#include "commons.hpp" + #include "../data/dynamic.hpp" #include "../util/stringutil.hpp" @@ -240,11 +242,11 @@ Value Parser::parseValue() { throw error("unexpected character '"+std::string({next})+"'"); } -std::unique_ptr json::parse(const std::string& filename, const std::string& source) { +dynamic::Map_sptr json::parse(const std::string& filename, const std::string& source) { Parser parser(filename, source); return parser.parse(); } -std::unique_ptr json::parse(const std::string& source) { +dynamic::Map_sptr json::parse(const std::string& source) { return parse("", source); } diff --git a/src/coders/json.hpp b/src/coders/json.hpp index 692117d5..f4379fdc 100644 --- a/src/coders/json.hpp +++ b/src/coders/json.hpp @@ -1,25 +1,20 @@ #ifndef CODERS_JSON_HPP_ #define CODERS_JSON_HPP_ -#include "commons.hpp" #include "binary_json.hpp" #include "../data/dynamic.hpp" #include "../typedefs.hpp" -#include #include -#include -#include -#include namespace json { - std::unique_ptr parse(const std::string& filename, const std::string& source); - std::unique_ptr parse(const std::string& source); + dynamic::Map_sptr parse(const std::string& filename, const std::string& source); + dynamic::Map_sptr parse(const std::string& source); std::string stringify( - const dynamic::Map* obj, - bool nice, + const dynamic::Map* obj, + bool nice, const std::string& indent ); diff --git a/src/files/files.cpp b/src/files/files.cpp index d1ec0ffb..104f21b5 100644 --- a/src/files/files.cpp +++ b/src/files/files.cpp @@ -1,5 +1,6 @@ #include "files.hpp" +#include "../coders/commons.hpp" #include "../coders/json.hpp" #include "../coders/gzip.hpp" #include "../util/stringutil.hpp" @@ -107,8 +108,7 @@ bool files::write_binary_json(fs::path filename, const dynamic::Map* obj, bool c std::shared_ptr files::read_json(fs::path filename) { std::string text = files::read_string(filename); try { - auto obj = json::parse(filename.string(), text); - return obj; + return json::parse(filename.string(), text);; } catch (const parsing_error& error) { std::cerr << error.errorLog() << std::endl; throw std::runtime_error("could not to parse "+filename.string()); diff --git a/src/logic/scripting/lua/libjson.cpp b/src/logic/scripting/lua/libjson.cpp index 2c72a75e..d868d2da 100644 --- a/src/logic/scripting/lua/libjson.cpp +++ b/src/logic/scripting/lua/libjson.cpp @@ -25,10 +25,7 @@ static int l_json_stringify(lua_State* L) { static int l_json_parse(lua_State* L) { auto string = lua_tostring(L, 1); auto element = json::parse("", string); - auto value = std::make_unique( - dynamic::Map_sptr(element.release()) - ); - scripting::state->pushvalue(*value); + scripting::state->pushvalue(element); return 1; } diff --git a/src/window/input.cpp b/src/window/input.cpp index bdb8bbcd..50825047 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -140,9 +140,9 @@ std::string input_util::to_string(keycode code) { std::string input_util::to_string(mousecode code) { switch (code) { - case mousecode::BUTTON_1: return "LMB"; - case mousecode::BUTTON_2: return "RMB"; - case mousecode::BUTTON_3: return "MMB"; + case mousecode::BUTTON_1: return "LMB"; + case mousecode::BUTTON_2: return "RMB"; + case mousecode::BUTTON_3: return "MMB"; + default: return "unknown button"; } - return "unknown button"; } From 66476ee64281cfaf22f18587db2067d762beed17 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 20 May 2024 04:06:49 +0300 Subject: [PATCH 11/97] bindings.toml, config/bindings.toml file --- res/bindings.toml | 17 ++++++++++++ res/layouts/pages/settings_controls.xml.lua | 1 + src/core_defs.cpp | 29 +++++++-------------- src/core_defs.hpp | 4 +-- src/engine.cpp | 11 ++++++-- src/files/files.cpp | 5 ++++ src/files/files.hpp | 6 ++--- src/frontend/screens/LevelScreen.cpp | 3 ++- src/window/Events.cpp | 27 +++++++++++++++++++ src/window/Events.hpp | 3 ++- src/window/input.cpp | 4 ++- 11 files changed, 79 insertions(+), 31 deletions(-) create mode 100644 res/bindings.toml diff --git a/res/bindings.toml b/res/bindings.toml new file mode 100644 index 00000000..d0a7e1e9 --- /dev/null +++ b/res/bindings.toml @@ -0,0 +1,17 @@ +devtools.console="key:grave-accent" +movement.forward="key:w" +movement.back="key:s" +movement.left="key:a" +movement.right="key:d" +movement.jump="key:space" +movement.sprint="key:left-ctrl" +movement.crouch="key:left-shift" +movement.cheat="key:r" +camera.zoom="key:c" +camera.mode="key:f4" +player.noclip="key:n" +player.flight="key:f" +player.attack="mouse:left" +player.build="mouse:right" +player.pick="mouse:middle" +hud.inventory="key:tab" diff --git a/res/layouts/pages/settings_controls.xml.lua b/res/layouts/pages/settings_controls.xml.lua index a66e17e3..879f21e5 100644 --- a/res/layouts/pages/settings_controls.xml.lua +++ b/res/layouts/pages/settings_controls.xml.lua @@ -17,6 +17,7 @@ function on_open() local panel = document.bindings_panel local bindings = core.get_bindings() + table.sort(bindings, function(a, b) return a > b end) for i,name in ipairs(bindings) do panel:add(gui.template("binding", { id=name, name=gui.str(name) diff --git a/src/core_defs.cpp b/src/core_defs.cpp index e0a4e6b0..39c70991 100644 --- a/src/core_defs.cpp +++ b/src/core_defs.cpp @@ -3,13 +3,15 @@ #include "items/ItemDef.hpp" #include "content/Content.hpp" #include "content/ContentBuilder.hpp" +#include "files/files.hpp" +#include "files/engine_paths.hpp" #include "window/Window.hpp" #include "window/Events.hpp" #include "window/input.hpp" #include "voxels/Block.hpp" // All in-game definitions (blocks, items, etc..) -void corecontent::setup(ContentBuilder* builder) { +void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) { Block& block = builder->createBlock("core:air"); block.replaceable = true; block.drawGroup = 1; @@ -22,24 +24,11 @@ void corecontent::setup(ContentBuilder* builder) { ItemDef& item = builder->createItem("core:empty"); item.iconType = item_icon_type::none; -} -void corecontent::setup_bindings() { - Events::bind(BIND_DEVTOOLS_CONSOLE, inputtype::keyboard, keycode::GRAVE_ACCENT); - Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W); - Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S); - Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D); - Events::bind(BIND_MOVE_LEFT, inputtype::keyboard, keycode::A); - Events::bind(BIND_MOVE_JUMP, inputtype::keyboard, keycode::SPACE); - Events::bind(BIND_MOVE_SPRINT, inputtype::keyboard, keycode::LEFT_CONTROL); - Events::bind(BIND_MOVE_CROUCH, inputtype::keyboard, keycode::LEFT_SHIFT); - Events::bind(BIND_MOVE_CHEAT, inputtype::keyboard, keycode::R); - Events::bind(BIND_CAM_ZOOM, inputtype::keyboard, keycode::C); - Events::bind(BIND_CAM_MODE, inputtype::keyboard, keycode::F4); - Events::bind(BIND_PLAYER_NOCLIP, inputtype::keyboard, keycode::N); - Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F); - Events::bind(BIND_PLAYER_ATTACK, inputtype::mouse, mousecode::BUTTON_1); - Events::bind(BIND_PLAYER_BUILD, inputtype::mouse, mousecode::BUTTON_2); - Events::bind(BIND_PLAYER_PICK, inputtype::mouse, mousecode::BUTTON_3); - Events::bind(BIND_HUD_INVENTORY, inputtype::keyboard, keycode::TAB); + auto bindsFile = paths->getResources()/fs::path("bindings.toml"); + if (fs::is_regular_file(bindsFile)) { + Events::loadBindingsToml( + bindsFile.u8string(), files::read_string(bindsFile) + ); + } } diff --git a/src/core_defs.hpp b/src/core_defs.hpp index 1a2b0a9f..884cda26 100644 --- a/src/core_defs.hpp +++ b/src/core_defs.hpp @@ -27,11 +27,11 @@ inline const std::string BIND_PLAYER_BUILD = "player.build"; inline const std::string BIND_PLAYER_PICK = "player.pick"; inline const std::string BIND_HUD_INVENTORY = "hud.inventory"; +class EnginePaths; class ContentBuilder; namespace corecontent { - void setup_bindings(); - void setup(ContentBuilder* builder); + void setup(EnginePaths* paths, ContentBuilder* builder); } #endif // CORE_DEFS_HPP_ diff --git a/src/engine.cpp b/src/engine.cpp index a4b9f5bf..0810d004 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -64,7 +64,6 @@ Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, Engin : settings(settings), settingsHandler(settingsHandler), paths(paths), interpreter(std::make_unique()) { - corecontent::setup_bindings(); loadSettings(); controller = std::make_unique(this); @@ -255,7 +254,7 @@ void Engine::loadAssets() { void Engine::loadContent() { auto resdir = paths->getResources(); ContentBuilder contentBuilder; - corecontent::setup(&contentBuilder); + corecontent::setup(paths, &contentBuilder); paths->setContentPacks(&contentPacks); std::vector names; @@ -273,6 +272,14 @@ void Engine::loadContent() { ContentLoader loader(&pack); loader.load(contentBuilder); + + auto configFolder = pack.folder/fs::path("config"); + auto bindsFile = configFolder/fs::path("bindings.toml"); + if (fs::is_regular_file(bindsFile)) { + Events::loadBindingsToml( + bindsFile.u8string(), files::read_string(bindsFile) + ); + } } content = contentBuilder.build(); resPaths = std::make_unique(resdir, resRoots); diff --git a/src/files/files.cpp b/src/files/files.cpp index 104f21b5..bd9e1716 100644 --- a/src/files/files.cpp +++ b/src/files/files.cpp @@ -2,6 +2,7 @@ #include "../coders/commons.hpp" #include "../coders/json.hpp" +#include "../coders/toml.hpp" #include "../coders/gzip.hpp" #include "../util/stringutil.hpp" #include "../data/dynamic.hpp" @@ -121,6 +122,10 @@ std::shared_ptr files::read_binary_json(fs::path file) { return json::from_binary(bytes.get(), size); } +std::shared_ptr files::read_toml(fs::path file) { + return toml::parse(file.u8string(), files::read_string(file)); +} + std::vector files::read_list(fs::path filename) { std::ifstream file(filename); if (!file) { diff --git a/src/files/files.hpp b/src/files/files.hpp index 1270d6eb..560d5e1f 100644 --- a/src/files/files.hpp +++ b/src/files/files.hpp @@ -44,10 +44,7 @@ namespace files { /// @brief Write dynamic data to the JSON file /// @param nice if true, human readable format will be used, otherwise minimal - bool write_json( - fs::path filename, - const dynamic::Map* obj, - bool nice=true); + bool write_json(fs::path filename, const dynamic::Map* obj, bool nice=true); /// @brief Write dynamic data to the binary JSON file /// (see src/coders/binary_json_spec.md) @@ -66,6 +63,7 @@ namespace files { /// @param file *.json or *.bjson file std::shared_ptr read_json(fs::path file); std::shared_ptr read_binary_json(fs::path file); + std::shared_ptr read_toml(fs::path file); std::vector read_list(fs::path file); } diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index fea96193..93c60169 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -6,6 +6,7 @@ #include "../../coders/imageio.hpp" #include "../../debug/Logger.hpp" #include "../../engine.hpp" +#include "../../files/files.hpp" #include "../../graphics/core/DrawContext.hpp" #include "../../graphics/core/ImageData.hpp" #include "../../graphics/core/PostProcessing.hpp" @@ -15,6 +16,7 @@ #include "../../graphics/ui/GUI.hpp" #include "../../logic/LevelController.hpp" #include "../../logic/scripting/scripting_hud.hpp" +#include "../../util/stringutil.hpp" #include "../../physics/Hitbox.hpp" #include "../../voxels/Chunks.hpp" #include "../../window/Camera.hpp" @@ -66,7 +68,6 @@ void LevelScreen::initializePack(ContentPackRuntime* pack) { if (fs::is_regular_file(scriptFile)) { scripting::load_hud_script(pack->getEnvironment(), info.id, scriptFile); } - auto configFolder = info.folder/fs::path("config"); } LevelScreen::~LevelScreen() { diff --git a/src/window/Events.cpp b/src/window/Events.cpp index 8ac783fd..76158230 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -1,6 +1,7 @@ #include "Events.hpp" #include "Window.hpp" #include "../debug/Logger.hpp" +#include "../util/stringutil.hpp" #include #include @@ -148,6 +149,7 @@ void Events::setPosition(float xpos, float ypos) { #include "../data/dynamic.hpp" #include "../coders/json.hpp" +#include "../coders/toml.hpp" std::string Events::writeBindings() { dynamic::Map obj; @@ -189,3 +191,28 @@ void Events::loadBindings(const std::string& filename, const std::string& source jentry->num("code", binding.code); } } + +void Events::loadBindingsToml(const std::string& filename, const std::string& source) { + auto map = toml::parse(filename, source); + for (auto& entry : map->values) { + if (auto value = std::get_if(&entry.second)) { + auto [prefix, codename] = util::split_at(*value, ':'); + inputtype type; + int code; + if (prefix == "key") { + type = inputtype::keyboard; + code = static_cast(input_util::keycode_from(codename)); + } else if (prefix == "mouse") { + type = inputtype::mouse; + code = static_cast(input_util::mousecode_from(codename)); + } else { + logger.error() << "unknown input type: " << prefix + << " (binding " << util::quote(entry.first) << ")"; + continue; + } + Events::bind(entry.first, type, code); + } else { + logger.error() << "invalid binding entry: " << entry.first; + } + } +} diff --git a/src/window/Events.hpp b/src/window/Events.hpp index 36544c2a..c8d354d3 100644 --- a/src/window/Events.hpp +++ b/src/window/Events.hpp @@ -2,11 +2,11 @@ #define WINDOW_EVENTS_HPP_ #include "input.hpp" +#include "../typedefs.hpp" #include #include #include -#include "../typedefs.hpp" inline constexpr short KEYS_BUFFER_SIZE = 1036; @@ -51,6 +51,7 @@ public: static std::string writeBindings(); static void loadBindings(const std::string& filename, const std::string& source); + static void loadBindingsToml(const std::string& filename, const std::string& source); }; #endif // WINDOW_EVENTS_HPP_ diff --git a/src/window/input.cpp b/src/window/input.cpp index 50825047..33621f70 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -15,6 +15,7 @@ static std::unordered_map keycodes { {"delete", GLFW_KEY_DELETE}, {"home", GLFW_KEY_HOME}, {"end", GLFW_KEY_END}, + {"tab", GLFW_KEY_TAB}, {"insert", GLFW_KEY_INSERT}, {"page-down", GLFW_KEY_PAGE_DOWN}, {"page-up", GLFW_KEY_PAGE_UP}, @@ -26,6 +27,7 @@ static std::unordered_map keycodes { {"right-alt", GLFW_KEY_RIGHT_ALT}, {"left-super", GLFW_KEY_LEFT_SUPER}, {"right-super", GLFW_KEY_RIGHT_SUPER}, + {"grave-accent", GLFW_KEY_GRAVE_ACCENT}, {"left", GLFW_KEY_LEFT}, {"right", GLFW_KEY_RIGHT}, {"down", GLFW_KEY_DOWN}, @@ -59,7 +61,7 @@ void input_util::initialize() { keycodes["f"+std::to_string(i)] = GLFW_KEY_F1+i; } for (char i = 'a'; i <= 'z'; i++) { - keycodes[std::to_string(i)] = GLFW_KEY_A-'a'+i; + keycodes[std::string({i})] = GLFW_KEY_A-'a'+i; } } From fad9dc85ada3d8f4697e13aaafe690db2a4f33c0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 22 May 2024 22:37:17 +0300 Subject: [PATCH 12/97] added image.src property --- src/graphics/ui/elements/Image.cpp | 8 ++++++++ src/graphics/ui/elements/Image.hpp | 2 ++ src/logic/scripting/lua/libgui.cpp | 15 +++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/graphics/ui/elements/Image.cpp b/src/graphics/ui/elements/Image.cpp index f350ca0d..ffc00491 100644 --- a/src/graphics/ui/elements/Image.cpp +++ b/src/graphics/ui/elements/Image.cpp @@ -33,3 +33,11 @@ void Image::setAutoResize(bool flag) { bool Image::isAutoResize() const { return autoresize; } + +const std::string& Image::getTexture() const { + return texture; +} + +void Image::setTexture(const std::string& name) { + texture = name; +} diff --git a/src/graphics/ui/elements/Image.hpp b/src/graphics/ui/elements/Image.hpp index 66781ef0..06bab69d 100644 --- a/src/graphics/ui/elements/Image.hpp +++ b/src/graphics/ui/elements/Image.hpp @@ -15,6 +15,8 @@ namespace gui { virtual void setAutoResize(bool flag); virtual bool isAutoResize() const; + virtual const std::string& getTexture() const; + virtual void setTexture(const std::string& name); }; } diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index ffcd55ac..34b01e1e 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -10,6 +10,7 @@ #include "../../../graphics/ui/gui_util.hpp" #include "../../../graphics/ui/elements/UINode.hpp" #include "../../../graphics/ui/elements/Button.hpp" +#include "../../../graphics/ui/elements/Image.hpp" #include "../../../graphics/ui/elements/CheckBox.hpp" #include "../../../graphics/ui/elements/TextBox.hpp" #include "../../../graphics/ui/elements/TrackBar.hpp" @@ -233,6 +234,13 @@ static int p_get_editable(UINode* node) { return 0; } +static int p_get_src(UINode* node) { + if (auto image = dynamic_cast(node)) { + return state->pushstring(image->getTexture()); + } + return 0; +} + static int p_get_add(UINode* node) { if (dynamic_cast(node)) { return state->pushcfunction(l_container_add); @@ -302,6 +310,7 @@ static int l_gui_getattr(lua_State* L) { {"caret", p_get_caret}, {"text", p_get_text}, {"editable", p_get_editable}, + {"src", p_get_src}, {"value", p_get_value}, {"min", p_get_min}, {"max", p_get_max}, @@ -371,6 +380,11 @@ static void p_set_editable(UINode* node, int idx) { box->setEditable(state->toboolean(idx)); } } +static void p_set_src(UINode* node, int idx) { + if (auto image = dynamic_cast(node)) { + image->setTexture(state->requireString(idx)); + } +} static void p_set_value(UINode* node, int idx) { if (auto bar = dynamic_cast(node)) { bar->setValue(state->tonumber(idx)); @@ -451,6 +465,7 @@ static int l_gui_setattr(lua_State* L) { {"placeholder", p_set_placeholder}, {"text", p_set_text}, {"editable", p_set_editable}, + {"src", p_set_src}, {"caret", p_set_caret}, {"value", p_set_value}, {"min", p_set_min}, From 41ef80e93875df746cf673e638e8dc23b8e791be Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 22 May 2024 22:39:27 +0300 Subject: [PATCH 13/97] checkbox fix --- src/graphics/ui/elements/CheckBox.cpp | 3 ++- src/graphics/ui/elements/CheckBox.hpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/ui/elements/CheckBox.cpp b/src/graphics/ui/elements/CheckBox.cpp index 16a2d9e6..eb9aa233 100644 --- a/src/graphics/ui/elements/CheckBox.cpp +++ b/src/graphics/ui/elements/CheckBox.cpp @@ -7,7 +7,8 @@ using namespace gui; CheckBox::CheckBox(bool checked) : UINode(glm::vec2(32.0f)), checked(checked) { - setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f)); + setColor({0.0f, 0.0f, 0.0f, 0.5f}); + setHoverColor({0.05f, 0.1f, 0.2f, 0.75f}); } void CheckBox::draw(const DrawContext* pctx, Assets*) { diff --git a/src/graphics/ui/elements/CheckBox.hpp b/src/graphics/ui/elements/CheckBox.hpp index 41e9c61f..e366768e 100644 --- a/src/graphics/ui/elements/CheckBox.hpp +++ b/src/graphics/ui/elements/CheckBox.hpp @@ -6,7 +6,6 @@ namespace gui { class CheckBox : public UINode { protected: - glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f}; glm::vec4 checkColor {1.0f, 1.0f, 1.0f, 0.4f}; boolsupplier supplier = nullptr; boolconsumer consumer = nullptr; From 0ad3dd7ab853770490ca74d65cbc847f54ebf48d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 23 May 2024 02:05:08 +0300 Subject: [PATCH 14/97] build time decreased --- src/engine.cpp | 1 + src/engine.hpp | 2 +- src/files/WorldFiles.cpp | 1 + src/files/WorldFiles.hpp | 2 +- src/frontend/debug_panel.cpp | 1 + src/logic/LevelController.cpp | 2 ++ src/logic/LevelController.hpp | 2 +- src/logic/PlayerController.cpp | 1 + src/logic/PlayerController.hpp | 3 ++- src/objects/Player.hpp | 34 ++++++++++++++++------------------ src/voxel_engine.cpp | 3 +++ src/world/Level.cpp | 1 + src/world/Level.hpp | 2 +- src/world/World.cpp | 1 + src/world/World.hpp | 2 +- 15 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 0810d004..fa34c3c7 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -35,6 +35,7 @@ #include "window/input.hpp" #include "window/Window.hpp" #include "world/WorldGenerators.hpp" +#include "settings.hpp" #include #include diff --git a/src/engine.hpp b/src/engine.hpp index 61066143..878b1e54 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -2,7 +2,6 @@ #define ENGINE_HPP_ #include "delegates.hpp" -#include "settings.hpp" #include "typedefs.hpp" #include "assets/Assets.hpp" @@ -27,6 +26,7 @@ class ResPaths; class Batch2D; class EngineController; class SettingsHandler; +struct EngineSettings; namespace fs = std::filesystem; diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index ff9b2663..b5d68c85 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -13,6 +13,7 @@ #include "../objects/Player.hpp" #include "../physics/Hitbox.hpp" #include "../typedefs.hpp" +#include "../settings.hpp" #include "../util/data_io.hpp" #include "../voxels/Block.hpp" #include "../voxels/Chunk.hpp" diff --git a/src/files/WorldFiles.hpp b/src/files/WorldFiles.hpp index 7247b246..f2938416 100644 --- a/src/files/WorldFiles.hpp +++ b/src/files/WorldFiles.hpp @@ -5,7 +5,6 @@ #include "files.hpp" #include "../typedefs.hpp" -#include "../settings.hpp" #include "../content/ContentPack.hpp" #include "../voxels/Chunk.hpp" @@ -24,6 +23,7 @@ class Player; class Content; class ContentIndices; class World; +struct DebugSettings; namespace fs = std::filesystem; diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index a967ccad..014af2f0 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -1,6 +1,7 @@ #include "../audio/audio.hpp" #include "../delegates.hpp" #include "../engine.hpp" +#include "../settings.hpp" #include "../graphics/core/Mesh.hpp" #include "../graphics/ui/elements/CheckBox.hpp" #include "../graphics/ui/elements/TextBox.hpp" diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index 5e0cb198..479eff16 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -1,4 +1,6 @@ #include "LevelController.hpp" + +#include "../settings.hpp" #include "../files/WorldFiles.hpp" #include "../debug/Logger.hpp" #include "../world/Level.hpp" diff --git a/src/logic/LevelController.hpp b/src/logic/LevelController.hpp index 4c23ad77..3530df68 100644 --- a/src/logic/LevelController.hpp +++ b/src/logic/LevelController.hpp @@ -2,7 +2,6 @@ #define LOGIC_LEVEL_CONTROLLER_HPP_ #include -#include "../settings.hpp" #include "PlayerController.hpp" #include "BlocksController.hpp" @@ -10,6 +9,7 @@ class Level; class Player; +struct EngineSettings; /// @brief LevelController manages other controllers class LevelController { diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 91bda4e8..fe5cfe75 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -22,6 +22,7 @@ #include "../items/ItemStack.hpp" #include "../items/Inventory.hpp" #include "../core_defs.hpp" +#include "../settings.hpp" const float CAM_SHAKE_OFFSET = 0.025f; const float CAM_SHAKE_OFFSET_Y = 0.031f; diff --git a/src/logic/PlayerController.hpp b/src/logic/PlayerController.hpp index bc2d1fb7..d48a3a51 100644 --- a/src/logic/PlayerController.hpp +++ b/src/logic/PlayerController.hpp @@ -1,7 +1,6 @@ #ifndef PLAYER_CONTROL_HPP_ #define PLAYER_CONTROL_HPP_ -#include "../settings.hpp" #include "../objects/Player.hpp" #include @@ -12,7 +11,9 @@ class Camera; class Level; class Block; +class Chunks; class BlocksController; +struct CameraSettings; class CameraControl { std::shared_ptr player; diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index 18b9cb13..54aa4b12 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -1,9 +1,9 @@ #ifndef SRC_OBJECTS_PLAYER_HPP_ #define SRC_OBJECTS_PLAYER_HPP_ +#include "../settings.hpp" #include "../data/dynamic.hpp" #include "../voxels/voxel.hpp" -#include "../settings.hpp" #include "../interfaces/Serializable.hpp" #include "../interfaces/Object.hpp" @@ -14,23 +14,22 @@ class Camera; class Hitbox; class Inventory; class ContentLUT; -class PhysicsSolver; -class Chunks; class Level; +struct EngineSettings; struct PlayerInput { - bool zoom; - bool cameraMode; - bool moveForward; - bool moveBack; - bool moveRight; - bool moveLeft; - bool sprint; - bool shift; - bool cheat; - bool jump; - bool noclip; - bool flight; + bool zoom : 1; + bool cameraMode : 1; + bool moveForward : 1; + bool moveBack : 1; + bool moveRight : 1; + bool moveLeft : 1; + bool sprint : 1; + bool shift : 1; + bool cheat : 1; + bool jump : 1; + bool noclip : 1; + bool flight : 1; }; class Player : public Object, public Serializable { @@ -46,8 +45,7 @@ public: bool noclip = false; bool debug = false; voxel selectedVoxel {0, 0}; - - glm::vec2 cam = {}; + glm::vec2 cam {}; Player(glm::vec3 position, float speed, std::shared_ptr inv); ~Player(); @@ -77,4 +75,4 @@ public: } }; -#endif /* SRC_OBJECTS_PLAYER_HPP_ */ +#endif // SRC_OBJECTS_PLAYER_HPP_ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index eac242c5..33d18c0e 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -1,9 +1,11 @@ #include "engine.hpp" +#include "settings.hpp" #include "files/settings_io.hpp" #include "files/engine_paths.hpp" #include "util/platform.hpp" #include "util/command_line.hpp" #include "debug/Logger.hpp" +#include "objects/Player.hpp" #include @@ -11,6 +13,7 @@ static debug::Logger logger("main"); int main(int argc, char** argv) { debug::Logger::init("latest.log"); + std::cout << sizeof(PlayerInput) << std::endl; EnginePaths paths; if (!parse_cmdline(argc, argv, paths)) diff --git a/src/world/Level.cpp b/src/world/Level.cpp index 36f75e30..1df81c74 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -1,6 +1,7 @@ #include "Level.hpp" #include "World.hpp" #include "LevelEvents.hpp" +#include "../settings.hpp" #include "../content/Content.hpp" #include "../lighting/Lighting.hpp" #include "../voxels/Chunk.hpp" diff --git a/src/world/Level.hpp b/src/world/Level.hpp index 6b8f35c4..7b18f06f 100644 --- a/src/world/Level.hpp +++ b/src/world/Level.hpp @@ -1,7 +1,6 @@ #ifndef WORLD_LEVEL_HPP_ #define WORLD_LEVEL_HPP_ -#include "../settings.hpp" #include "../interfaces/Object.hpp" #include @@ -21,6 +20,7 @@ class LevelEvents; class Lighting; class PhysicsSolver; class ChunksStorage; +struct EngineSettings; /// @brief A level, contains chunks and objects class Level { diff --git a/src/world/World.cpp b/src/world/World.cpp index 6fb17b1e..a7bcab92 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -2,6 +2,7 @@ #include "Level.hpp" +#include "../settings.hpp" #include "../content/Content.hpp" #include "../content/ContentLUT.hpp" #include "../debug/Logger.hpp" diff --git a/src/world/World.hpp b/src/world/World.hpp index 57d94956..7d9e9748 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -2,7 +2,6 @@ #define WORLD_WORLD_HPP_ #include "../typedefs.hpp" -#include "../settings.hpp" #include "../util/timeutil.hpp" #include "../data/dynamic.hpp" #include "../interfaces/Serializable.hpp" @@ -17,6 +16,7 @@ class Content; class WorldFiles; class Level; class ContentLUT; +struct EngineSettings; namespace fs = std::filesystem; From 1917cbba8be74c1df0025d71a14a4444c20c07f3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 01:38:39 +0300 Subject: [PATCH 15/97] new player.* functions --- doc/en/8.Scripting.md | 14 +++ doc/ru/8.Скриптинг.md | 14 +++ src/logic/scripting/lua/LuaState.cpp | 10 +- src/logic/scripting/lua/LuaState.hpp | 14 +-- src/logic/scripting/lua/libaudio.cpp | 116 ++++++++----------- src/logic/scripting/lua/libblock.cpp | 107 ++++++++--------- src/logic/scripting/lua/libconsole.cpp | 18 +-- src/logic/scripting/lua/libhud.cpp | 8 +- src/logic/scripting/lua/libinventory.cpp | 52 +++++---- src/logic/scripting/lua/libitem.cpp | 15 ++- src/logic/scripting/lua/libplayer.cpp | 105 ++++++++++++----- src/logic/scripting/lua/lua_commons.hpp | 10 +- src/logic/scripting/lua/lua_util.hpp | 14 +-- src/logic/scripting/scripting_functional.cpp | 7 +- src/objects/Player.cpp | 16 +++ src/objects/Player.hpp | 10 +- 16 files changed, 306 insertions(+), 224 deletions(-) diff --git a/doc/en/8.Scripting.md b/doc/en/8.Scripting.md index e18ab0ad..b0fb326f 100644 --- a/doc/en/8.Scripting.md +++ b/doc/en/8.Scripting.md @@ -69,6 +69,20 @@ player.get_inventory(playerid: int) -> int, int Returns player inventory ID and selected slot index (0-9) +```python +player.is_flight() -> bool +player.set_flight(bool) +``` + +Getter and setter for player flight mode + +```python +player.is_noclip() -> bool +player.set_noclip(bool) +``` + +Getter and setter for player noclip mode (physics disabled) + ## *world* library ```python diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index 82f27159..1b1c7f83 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -63,6 +63,20 @@ player.get_inventory(playerid: int) -> int, int Возвращает id инвентаря игрока и индекс выбранного слота (от 0 до 9) +```python +player.is_flight() -> bool +player.set_flight(bool) +``` + +Геттер и сеттер режима полета + +```python +player.is_noclip() -> bool +player.set_noclip(bool) +``` + +Геттер и сеттер noclip режима (выключенная физика игрока) + ## Библиотека world ```python diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index 1a860670..49f83439 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -187,12 +187,12 @@ int LuaState::gettop() const { return lua_gettop(L); } -int LuaState::pushinteger(luaint x) { +int LuaState::pushinteger(lua_Integer x) { lua_pushinteger(L, x); return 1; } -int LuaState::pushnumber(luanumber x) { +int LuaState::pushnumber(lua_Number x) { lua_pushnumber(L, x); return 1; } @@ -202,7 +202,7 @@ int LuaState::pushboolean(bool x) { return 1; } -int LuaState::pushivec3(luaint x, luaint y, luaint z) { +int LuaState::pushivec3(lua_Integer x, lua_Integer y, lua_Integer z) { lua::pushivec3(L, x, y, z); return 3; } @@ -291,11 +291,11 @@ bool LuaState::toboolean(int idx) { return lua_toboolean(L, idx); } -luaint LuaState::tointeger(int idx) { +lua_Integer LuaState::tointeger(int idx) { return lua_tointeger(L, idx); } -luanumber LuaState::tonumber(int idx) { +lua_Number LuaState::tonumber(int idx) { return lua_tonumber(L, idx); } diff --git a/src/logic/scripting/lua/LuaState.hpp b/src/logic/scripting/lua/LuaState.hpp index bac4c8aa..58c538bd 100644 --- a/src/logic/scripting/lua/LuaState.hpp +++ b/src/logic/scripting/lua/LuaState.hpp @@ -7,10 +7,6 @@ #include "../../../data/dynamic.hpp" #include "../../../delegates.hpp" -#ifndef LUAJIT_VERSION -#error LuaJIT required -#endif - #include #include @@ -36,9 +32,9 @@ namespace lua { static const std::string envName(int env); void loadbuffer(int env, const std::string& src, const std::string& file); int gettop() const; - int pushivec3(luaint x, luaint y, luaint z); - int pushinteger(luaint x); - int pushnumber(luanumber x); + int pushivec3(lua_Integer x, lua_Integer y, lua_Integer z); + int pushinteger(lua_Integer x); + int pushnumber(lua_Number x); int pushboolean(bool x); int pushstring(const std::string& str); int pushenv(int env); @@ -51,8 +47,8 @@ namespace lua { bool getfield(const std::string& name, int idx = -1); void setfield(const std::string& name, int idx = -2); bool toboolean(int idx); - luaint tointeger(int idx); - luanumber tonumber(int idx); + lua_Integer tointeger(int idx); + lua_Number tonumber(int idx); glm::vec2 tovec2(int idx); glm::vec4 tocolor(int idx); dynamic::Value tovalue(int idx); diff --git a/src/logic/scripting/lua/libaudio.cpp b/src/logic/scripting/lua/libaudio.cpp index 8f19d20e..833b00ae 100644 --- a/src/logic/scripting/lua/libaudio.cpp +++ b/src/logic/scripting/lua/libaudio.cpp @@ -23,22 +23,22 @@ inline int extract_channel_index(lua_State* L, int idx) { inline audio::speakerid_t play_sound( const char* name, bool relative, - lua::luanumber x, - lua::luanumber y, - lua::luanumber z, - lua::luanumber volume, - lua::luanumber pitch, + lua_Number x, + lua_Number y, + lua_Number z, + lua_Number volume, + lua_Number pitch, bool loop, int channel ) { - if (channel == -1) + if (channel == -1) { return 0; + } auto assets = scripting::engine->getAssets(); auto sound = assets->getSound(name); if (sound == nullptr) { return 0; } - return audio::play( sound, glm::vec3( @@ -58,20 +58,20 @@ inline audio::speakerid_t play_sound( inline audio::speakerid_t play_stream( const char* filename, bool relative, - lua::luanumber x, - lua::luanumber y, - lua::luanumber z, - lua::luanumber volume, - lua::luanumber pitch, + lua_Number x, + lua_Number y, + lua_Number z, + lua_Number volume, + lua_Number pitch, bool loop, int channel ) { - if (channel == -1) + if (channel == -1) { return 0; + } auto paths = scripting::engine->getResPaths(); - fs::path file = paths->find(filename); return audio::play_stream( - file, + paths->find(filename), glm::vec3( static_cast(x), static_cast(y), @@ -95,7 +95,7 @@ inline audio::speakerid_t play_stream( /// channel: string = "regular", /// loop: bool = false) static int l_audio_play_stream(lua_State* L) { - lua_pushinteger(L, static_cast( + lua_pushinteger(L, static_cast( play_stream( lua_tostring(L, 1), false, @@ -118,7 +118,7 @@ static int l_audio_play_stream(lua_State* L) { /// channel: string = "regular", /// loop: bool = false) static int l_audio_play_stream_2d(lua_State* L) { - lua_pushinteger(L, static_cast( + lua_pushinteger(L, static_cast( play_stream( lua_tostring(L, 1), true, @@ -142,7 +142,7 @@ static int l_audio_play_stream_2d(lua_State* L) { /// channel: string = "regular", /// loop: bool = false) static int l_audio_play_sound(lua_State* L) { - lua_pushinteger(L, static_cast( + lua_pushinteger(L, static_cast( play_sound( lua_tostring(L, 1), false, @@ -165,7 +165,7 @@ static int l_audio_play_sound(lua_State* L) { /// channel: string = "regular", /// loop: bool = false) static int l_audio_play_sound_2d(lua_State* L) { - lua_pushinteger(L, static_cast( + lua_pushinteger(L, static_cast( play_sound( lua_tostring(L, 1), true, @@ -181,8 +181,7 @@ static int l_audio_play_sound_2d(lua_State* L) { /// @brief audio.stop(speakerid: integer) -> nil static int l_audio_stop(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { speaker->stop(); } @@ -191,8 +190,7 @@ static int l_audio_stop(lua_State* L) { /// @brief audio.pause(speakerid: integer) -> nil static int l_audio_pause(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { speaker->pause(); } @@ -201,8 +199,7 @@ static int l_audio_pause(lua_State* L) { /// @brief audio.resume(speakerid: integer) -> nil static int l_audio_resume(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr && speaker->isPaused()) { speaker->play(); } @@ -211,8 +208,7 @@ static int l_audio_resume(lua_State* L) { /// @brief audio.set_loop(speakerid: integer, value: bool) -> nil static int l_audio_set_loop(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { bool value = lua_toboolean(L, 2); speaker->setLoop(value); @@ -222,45 +218,38 @@ static int l_audio_set_loop(lua_State* L) { /// @brief audio.set_volume(speakerid: integer, value: number) -> nil static int l_audio_set_volume(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { - lua::luanumber value = lua_tonumber(L, 2); - speaker->setVolume(static_cast(value)); + speaker->setVolume(static_cast(lua_tonumber(L, 2))); } return 0; } /// @brief audio.set_pitch(speakerid: integer, value: number) -> nil static int l_audio_set_pitch(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { - lua::luanumber value = lua_tonumber(L, 2); - speaker->setPitch(static_cast(value)); + speaker->setPitch(static_cast(lua_tonumber(L, 2))); } return 0; } /// @brief audio.set_time(speakerid: integer, value: number) -> nil static int l_audio_set_time(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { - lua::luanumber value = lua_tonumber(L, 2); - speaker->setTime(static_cast(value)); + speaker->setTime(static_cast(lua_tonumber(L, 2))); } return 0; } /// @brief audio.set_position(speakerid: integer, x: number, y: number, z: number) -> nil static int l_audio_set_position(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - lua::luanumber z = lua_tonumber(L, 4); + auto x = lua_tonumber(L, 2); + auto y = lua_tonumber(L, 3); + auto z = lua_tonumber(L, 4); speaker->setPosition(glm::vec3( static_cast(x), static_cast(y), @@ -272,12 +261,11 @@ static int l_audio_set_position(lua_State* L) { /// @brief audio.set_velocity(speakerid: integer, x: number, y: number, z: number) -> nil static int l_audio_set_velocity(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - lua::luanumber z = lua_tonumber(L, 4); + auto x = lua_tonumber(L, 2); + auto y = lua_tonumber(L, 3); + auto z = lua_tonumber(L, 4); speaker->setVelocity(glm::vec3( static_cast(x), static_cast(y), @@ -289,8 +277,7 @@ static int l_audio_set_velocity(lua_State* L) { /// @brief audio.is_playing(speakerid: integer) -> bool static int l_audio_is_playing(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { lua_pushboolean(L, speaker->isPlaying()); return 1; @@ -301,8 +288,7 @@ static int l_audio_is_playing(lua_State* L) { /// @brief audio.is_paused(speakerid: integer) -> bool static int l_audio_is_paused(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { lua_pushboolean(L, speaker->isPaused()); return 1; @@ -313,8 +299,7 @@ static int l_audio_is_paused(lua_State* L) { /// @brief audio.is_loop(speakerid: integer) -> bool static int l_audio_is_loop(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { lua_pushboolean(L, speaker->isLoop()); return 1; @@ -325,8 +310,7 @@ static int l_audio_is_loop(lua_State* L) { /// @brief audio.get_volume(speakerid: integer) -> number static int l_audio_get_volume(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { lua_pushnumber(L, speaker->getVolume()); return 1; @@ -337,8 +321,7 @@ static int l_audio_get_volume(lua_State* L) { /// @brief audio.get_pitch(speakerid: integer) -> number static int l_audio_get_pitch(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { lua_pushnumber(L, speaker->getPitch()); return 1; @@ -349,8 +332,7 @@ static int l_audio_get_pitch(lua_State* L) { /// @brief audio.get_time(speakerid: integer) -> number static int l_audio_get_time(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { lua_pushnumber(L, speaker->getTime()); return 1; @@ -361,8 +343,7 @@ static int l_audio_get_time(lua_State* L) { /// @brief audio.get_duration(speakerid: integer) -> number static int l_audio_get_duration(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { lua_pushnumber(L, speaker->getDuration()); return 1; @@ -373,11 +354,9 @@ static int l_audio_get_duration(lua_State* L) { /// @brief audio.get_position(speakerid: integer) -> number, number, number static int l_audio_get_position(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { - auto vec = speaker->getPosition(); - lua::pushvec3(L, vec); + lua::pushvec3(L, speaker->getPosition()); return 1; } return 0; @@ -385,8 +364,7 @@ static int l_audio_get_position(lua_State* L) { /// @brief audio.get_velocity(speakerid: integer) -> number, number, number static int l_audio_get_velocity(lua_State* L) { - lua::luaint id = lua_tonumber(L, 1); - auto speaker = audio::get_speaker(id); + auto speaker = audio::get_speaker(lua_tointeger(L, 1)); if (speaker != nullptr) { auto vec = speaker->getVelocity(); lua::pushvec3(L, vec); diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 2de58401..695d8e36 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -1,7 +1,9 @@ #include "lua_commons.hpp" + #include "api_lua.hpp" #include "lua_util.hpp" #include "../scripting.hpp" + #include "../../../world/Level.hpp" #include "../../../voxels/Chunks.hpp" #include "../../../voxels/Chunk.hpp" @@ -13,7 +15,7 @@ int l_block_name(lua_State* L) { auto indices = scripting::content->getIndices(); - lua::luaint id = lua_tointeger(L, 1); + lua_Integer id = lua_tointeger(L, 1); if (id < 0 || size_t(id) >= indices->countBlockDefs()) { return 0; } @@ -22,10 +24,9 @@ int l_block_name(lua_State* L) { return 1; } - int l_block_material(lua_State* L) { auto indices = scripting::content->getIndices(); - lua::luaint id = lua_tointeger(L, 1); + lua_Integer id = lua_tointeger(L, 1); if (id < 0 || size_t(id) >= indices->countBlockDefs()) { return 0; } @@ -35,9 +36,9 @@ int l_block_material(lua_State* L) { } int l_is_solid_at(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); lua_pushboolean(L, scripting::level->chunks->isSolidBlock(x, y, z)); return 1; @@ -49,17 +50,17 @@ int l_blocks_count(lua_State* L) { } int l_block_index(lua_State* L) { - auto name = lua_tostring(L, 1); + std::string name = lua_tostring(L, 1); lua_pushinteger(L, scripting::content->requireBlock(name).rt.id); return 1; } int l_set_block(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint id = lua_tointeger(L, 4); - lua::luaint states = lua_tointeger(L, 5); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); + lua_Integer id = lua_tointeger(L, 4); + lua_Integer states = lua_tointeger(L, 5); bool noupdate = lua_toboolean(L, 6); if (id < 0 || size_t(id) >= scripting::indices->countBlockDefs()) { return 0; @@ -75,9 +76,9 @@ int l_set_block(lua_State* L) { } int l_get_block(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); int id = vox == nullptr ? -1 : vox->id; lua_pushinteger(L, id); @@ -85,9 +86,9 @@ int l_get_block(lua_State* L) { } int l_get_block_x(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return lua::pushivec3(L, 1, 0, 0); @@ -102,9 +103,9 @@ int l_get_block_x(lua_State* L) { } int l_get_block_y(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return lua::pushivec3(L, 0, 1, 0); @@ -119,9 +120,9 @@ int l_get_block_y(lua_State* L) { } int l_get_block_z(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return lua::pushivec3(L, 0, 0, 1); @@ -136,9 +137,9 @@ int l_get_block_z(lua_State* L) { } int l_get_block_rotation(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); int rotation = vox == nullptr ? 0 : vox->rotation(); lua_pushinteger(L, rotation); @@ -146,10 +147,10 @@ int l_get_block_rotation(lua_State* L) { } int l_set_block_rotation(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint value = lua_tointeger(L, 4); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); + lua_Integer value = lua_tointeger(L, 4); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return 0; @@ -160,9 +161,9 @@ int l_set_block_rotation(lua_State* L) { } int l_get_block_states(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); int states = vox == nullptr ? 0 : vox->states; lua_pushinteger(L, states); @@ -170,10 +171,10 @@ int l_get_block_states(lua_State* L) { } int l_set_block_states(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint states = lua_tointeger(L, 4); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); + lua_Integer states = lua_tointeger(L, 4); Chunk* chunk = scripting::level->chunks->getChunkByVoxel(x, y, z); if (chunk == nullptr) { @@ -186,11 +187,11 @@ int l_set_block_states(lua_State* L) { } int l_get_block_user_bits(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; - lua::luaint bits = lua_tointeger(L, 5); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); + lua_Integer offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; + lua_Integer bits = lua_tointeger(L, 5); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { @@ -204,14 +205,14 @@ int l_get_block_user_bits(lua_State* L) { } int l_set_block_user_bits(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; - lua::luaint bits = lua_tointeger(L, 5); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); + lua_Integer offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; + lua_Integer bits = lua_tointeger(L, 5); - uint mask = ((1 << bits) - 1) << offset; - lua::luaint value = (lua_tointeger(L, 6) << offset) & mask; + size_t mask = ((1 << bits) - 1) << offset; + lua_Integer value = (lua_tointeger(L, 6) << offset) & mask; voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { @@ -222,9 +223,9 @@ int l_set_block_user_bits(lua_State* L) { } int l_is_replaceable_at(lua_State* L) { - int x = lua_tointeger(L, 1); - int y = lua_tointeger(L, 2); - int z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); lua_pushboolean(L, scripting::level->chunks->isReplaceableBlock(x, y, z)); return 1; diff --git a/src/logic/scripting/lua/libconsole.cpp b/src/logic/scripting/lua/libconsole.cpp index 52b1010d..88238f65 100644 --- a/src/logic/scripting/lua/libconsole.cpp +++ b/src/logic/scripting/lua/libconsole.cpp @@ -14,11 +14,11 @@ namespace scripting { using namespace scripting; static int l_add_command(lua_State* L) { - if (!lua_isstring(L, 1) || !lua_isstring(L, 2) || !lua_isfunction(L, 3)) { - throw std::runtime_error("invalid argument type"); + if (!lua_isfunction(L, 3)) { + throw std::runtime_error("invalid callback"); } - auto scheme = lua_tostring(L, 1); - auto description = lua_tostring(L, 2); + auto scheme = state->requireString(1); + auto description = state->requireString(2); lua_pushvalue(L, 3); auto func = state->createLambda(); try { @@ -33,15 +33,15 @@ static int l_add_command(lua_State* L) { return 0; } -static int l_execute(lua_State* L) { - auto prompt = lua_tostring(L, 1); +static int l_execute(lua_State*) { + auto prompt = state->requireString(1); auto result = engine->getCommandsInterpreter()->execute(prompt); state->pushvalue(result); return 1; } -static int l_set(lua_State* L) { - auto name = lua_tostring(L, 1); +static int l_set(lua_State*) { + auto name = state->requireString(1); auto value = state->tovalue(2); (*engine->getCommandsInterpreter())[name] = value; return 0; @@ -62,7 +62,7 @@ static int l_get_commands_list(lua_State* L) { } static int l_get_command_info(lua_State* L) { - auto name = lua_tostring(L, 1); + auto name = state->requireString(1); auto interpreter = engine->getCommandsInterpreter(); auto repo = interpreter->getRepository(); auto command = repo->get(name); diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index b7c023f5..93d3505b 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -40,14 +40,14 @@ static int l_hud_close_inventory(lua_State*) { } static int l_hud_open_block(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + auto x = lua_tointeger(L, 1); + auto y = lua_tointeger(L, 2); + auto z = lua_tointeger(L, 3); bool playerInventory = !lua_toboolean(L, 4); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { - throw std::runtime_error("block does not exists at "+ + throw std::runtime_error("block does not exists at " + std::to_string(x) + " " + std::to_string(y) + " " + std::to_string(z) ); } diff --git a/src/logic/scripting/lua/libinventory.cpp b/src/logic/scripting/lua/libinventory.cpp index 067c7943..f6d164e1 100644 --- a/src/logic/scripting/lua/libinventory.cpp +++ b/src/logic/scripting/lua/libinventory.cpp @@ -1,6 +1,8 @@ #include "lua_commons.hpp" + #include "api_lua.hpp" #include "lua_util.hpp" + #include "../scripting.hpp" #include "../../../content/Content.hpp" #include "../../../world/Level.hpp" @@ -38,8 +40,8 @@ static void validate_slotid(int slotid, Inventory* inv) { } static int l_inventory_get(lua_State* L) { - lua::luaint invid = lua_tointeger(L, 1); - lua::luaint slotid = lua_tointeger(L, 2); + lua_Integer invid = lua_tointeger(L, 1); + lua_Integer slotid = lua_tointeger(L, 2); auto inv = get_inventory(invid); validate_slotid(slotid, inv.get()); const ItemStack& item = inv->getSlot(slotid); @@ -49,10 +51,10 @@ static int l_inventory_get(lua_State* L) { } static int l_inventory_set(lua_State* L) { - lua::luaint invid = lua_tointeger(L, 1); - lua::luaint slotid = lua_tointeger(L, 2); - lua::luaint itemid = lua_tointeger(L, 3); - lua::luaint count = lua_tointeger(L, 4); + lua_Integer invid = lua_tointeger(L, 1); + lua_Integer slotid = lua_tointeger(L, 2); + lua_Integer itemid = lua_tointeger(L, 3); + lua_Integer count = lua_tointeger(L, 4); validate_itemid(itemid); auto inv = get_inventory(invid); @@ -64,16 +66,16 @@ static int l_inventory_set(lua_State* L) { } static int l_inventory_size(lua_State* L) { - lua::luaint invid = lua_tointeger(L, 1); + lua_Integer invid = lua_tointeger(L, 1); auto inv = get_inventory(invid); lua_pushinteger(L, inv->size()); return 1; } static int l_inventory_add(lua_State* L) { - lua::luaint invid = lua_tointeger(L, 1); - lua::luaint itemid = lua_tointeger(L, 2); - lua::luaint count = lua_tointeger(L, 3); + lua_Integer invid = lua_tointeger(L, 1); + lua_Integer itemid = lua_tointeger(L, 2); + lua_Integer count = lua_tointeger(L, 3); validate_itemid(itemid); auto inv = get_inventory(invid); @@ -84,33 +86,33 @@ static int l_inventory_add(lua_State* L) { } static int l_inventory_get_block(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); int64_t id = scripting::blocks->createBlockInventory(x, y, z); lua_pushinteger(L, id); return 1; } static int l_inventory_bind_block(lua_State* L) { - lua::luaint id = lua_tointeger(L, 1); - lua::luaint x = lua_tointeger(L, 2); - lua::luaint y = lua_tointeger(L, 3); - lua::luaint z = lua_tointeger(L, 4); + lua_Integer id = lua_tointeger(L, 1); + lua_Integer x = lua_tointeger(L, 2); + lua_Integer y = lua_tointeger(L, 3); + lua_Integer z = lua_tointeger(L, 4); scripting::blocks->bindInventory(id, x, y, z); return 0; } static int l_inventory_unbind_block(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); + lua_Integer x = lua_tointeger(L, 1); + lua_Integer y = lua_tointeger(L, 2); + lua_Integer z = lua_tointeger(L, 3); scripting::blocks->unbindInventory(x, y, z); return 0; } static int l_inventory_clone(lua_State* L) { - lua::luaint id = lua_tointeger(L, 1); + lua_Integer id = lua_tointeger(L, 1); auto clone = scripting::level->inventories->clone(id); if (clone == nullptr) { lua_pushinteger(L, 0); @@ -121,13 +123,13 @@ static int l_inventory_clone(lua_State* L) { } static int l_inventory_move(lua_State* L) { - lua::luaint invAid = lua_tointeger(L, 1); - lua::luaint slotAid = lua_tointeger(L, 2); + lua_Integer invAid = lua_tointeger(L, 1); + lua_Integer slotAid = lua_tointeger(L, 2); auto invA = get_inventory(invAid, 1); validate_slotid(slotAid, invA.get()); - lua::luaint invBid = lua_tointeger(L, 3); - lua::luaint slotBid = lua_isnil(L, 4) ? -1 : lua_tointeger(L, 4); + lua_Integer invBid = lua_tointeger(L, 3); + lua_Integer slotBid = lua_isnil(L, 4) ? -1 : lua_tointeger(L, 4); auto invB = get_inventory(invBid, 3); auto& slot = invA->getSlot(slotAid); if (slotBid == -1) { diff --git a/src/logic/scripting/lua/libitem.cpp b/src/logic/scripting/lua/libitem.cpp index 62760099..c8d6c11a 100644 --- a/src/logic/scripting/lua/libitem.cpp +++ b/src/logic/scripting/lua/libitem.cpp @@ -1,13 +1,20 @@ #include "lua_commons.hpp" #include "api_lua.hpp" +#include "LuaState.hpp" #include "../scripting.hpp" #include "../../../content/Content.hpp" #include "../../../items/ItemDef.hpp" +namespace scripting { + extern lua::LuaState* state; +} + +using namespace scripting; + static int l_item_name(lua_State* L) { auto indices = scripting::content->getIndices(); - lua::luaint id = lua_tointeger(L, 1); - if (id < 0 || size_t(id) >= indices->countItemDefs()) { + lua_Number id = lua_tointeger(L, 1); + if (static_cast(id) >= indices->countItemDefs()) { return 0; } auto def = indices->getItemDef(id); @@ -16,14 +23,14 @@ static int l_item_name(lua_State* L) { } static int l_item_index(lua_State* L) { - auto name = lua_tostring(L, 1); + auto name = scripting::state->requireString(1); lua_pushinteger(L, scripting::content->requireItem(name).rt.id); return 1; } static int l_item_stack_size(lua_State* L) { auto indices = scripting::content->getIndices(); - lua::luaint id = lua_tointeger(L, 1); + lua_Integer id = lua_tointeger(L, 1); if (id < 0 || size_t(id) >= indices->countItemDefs()) { return 0; } diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp index f5f168106..5c27d954 100644 --- a/src/logic/scripting/lua/libplayer.cpp +++ b/src/logic/scripting/lua/libplayer.cpp @@ -9,10 +9,15 @@ #include +inline std::shared_ptr get_player(lua_State* L, int idx) { + return scripting::level->getObject(lua_tointeger(L, idx)); +} + static int l_player_get_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - auto player = scripting::level->getObject(playerid); - if (!player) return 0; + auto player = get_player(L, 1); + if (!player) { + return 0; + } glm::vec3 pos = player->hitbox->position; lua_pushnumber(L, pos.x); lua_pushnumber(L, pos.y); @@ -21,19 +26,22 @@ static int l_player_get_pos(lua_State* L) { } static int l_player_set_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - lua::luanumber z = lua_tonumber(L, 4); - auto player = scripting::level->getObject(playerid); - if (player) player->hitbox->position = glm::vec3(x, y, z); + auto player = get_player(L, 1); + if (!player) { + return 0; + } + auto x = lua_tonumber(L, 2); + auto y = lua_tonumber(L, 3); + auto z = lua_tonumber(L, 4); + player->hitbox->position = glm::vec3(x, y, z); return 0; } static int l_player_get_vel(lua_State* L) { - int playerid = lua_tointeger(L, 1); - auto player = scripting::level->getObject(playerid); - if (!player) return 0; + auto player = get_player(L, 1); + if (!player) { + return 0; + } glm::vec3 vel = player->hitbox->velocity; lua_pushnumber(L, vel.x); lua_pushnumber(L, vel.y); @@ -42,19 +50,22 @@ static int l_player_get_vel(lua_State* L) { } static int l_player_set_vel(lua_State* L) { - int playerid = lua_tointeger(L, 1); - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - lua::luanumber z = lua_tonumber(L, 4); - auto player = scripting::level->getObject(playerid); - if (player) player->hitbox->velocity = glm::vec3(x, y, z); + auto player = get_player(L, 1); + if (!player) { + return 0; + } + auto x = lua_tonumber(L, 2); + auto y = lua_tonumber(L, 3); + auto z = lua_tonumber(L, 4); + player->hitbox->velocity = glm::vec3(x, y, z); return 0; } static int l_player_get_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - auto player = scripting::level->getObject(playerid); - if (!player) return 0; + auto player = get_player(L, 1); + if (!player) { + return 0; + } glm::vec2 rot = player->cam; lua_pushnumber(L, rot.x); lua_pushnumber(L, rot.y); @@ -62,11 +73,12 @@ static int l_player_get_rot(lua_State* L) { } static int l_player_set_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - auto player = scripting::level->getObject(playerid); - if (!player) return 0; - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); + auto player = get_player(L, 1); + if (!player) { + return 0; + } + auto x = lua_tonumber(L, 2); + auto y = lua_tonumber(L, 3); glm::vec2& cam = player->cam; cam.x = x; cam.y = y; @@ -74,14 +86,45 @@ static int l_player_set_rot(lua_State* L) { } static int l_player_get_inv(lua_State* L) { - int playerid = lua_tointeger(L, 1); - auto player = scripting::level->getObject(playerid); - if (!player) return 0; + auto player = get_player(L, 1); + if (!player) { + return 0; + } lua_pushinteger(L, player->getInventory()->getId()); lua_pushinteger(L, player->getChosenSlot()); return 2; } +static int l_player_is_flight(lua_State* L) { + if (auto player = get_player(L, 1)) { + lua_pushboolean(L, player->isFlight()); + return 1; + } + return 0; +} + +static int l_player_set_flight(lua_State* L) { + if (auto player = get_player(L, 1)) { + player->setFlight(lua_toboolean(L, 2)); + } + return 0; +} + +static int l_player_is_noclip(lua_State* L) { + if (auto player = get_player(L, 1)) { + lua_pushboolean(L, player->isNoclip()); + return 1; + } + return 0; +} + +static int l_player_set_noclip(lua_State* L) { + if (auto player = get_player(L, 1)) { + player->setNoclip(lua_toboolean(L, 2)); + } + return 0; +} + const luaL_Reg playerlib [] = { {"get_pos", lua_wrap_errors}, {"set_pos", lua_wrap_errors}, @@ -90,5 +133,9 @@ const luaL_Reg playerlib [] = { {"get_rot", lua_wrap_errors}, {"set_rot", lua_wrap_errors}, {"get_inventory", lua_wrap_errors}, + {"is_flight", lua_wrap_errors}, + {"set_flight", lua_wrap_errors}, + {"is_noclip", lua_wrap_errors}, + {"set_noclip", lua_wrap_errors}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/lua_commons.hpp b/src/logic/scripting/lua/lua_commons.hpp index 38d17ebc..f51b7aac 100644 --- a/src/logic/scripting/lua/lua_commons.hpp +++ b/src/logic/scripting/lua/lua_commons.hpp @@ -7,14 +7,14 @@ #else #include #endif + +#ifndef LUAJIT_VERSION +#error LuaJIT required +#endif + #include #include -namespace lua { - using luaint = lua_Integer; - using luanumber = lua_Number; -} - template int lua_wrap_errors(lua_State *L) { int result = 0; try { diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index 4d9e37bf..0c4de9f3 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -14,7 +14,7 @@ #include namespace lua { - inline int pushivec3(lua_State* L, luaint x, luaint y, luaint z) { + inline int pushivec3(lua_State* L, lua_Integer x, lua_Integer y, lua_Integer z) { lua_pushinteger(L, x); lua_pushinteger(L, y); lua_pushinteger(L, z); @@ -100,9 +100,9 @@ namespace lua { throw std::runtime_error("value must be an array of two numbers"); } lua_rawgeti(L, -1, 1); - lua::luanumber x = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number x = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); - lua::luanumber y = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number y = lua_tonumber(L, -1); lua_pop(L, 1); lua_pop(L, 1); return glm::vec2(x, y); } @@ -113,13 +113,13 @@ namespace lua { throw std::runtime_error("RGBA array required"); } lua_rawgeti(L, -1, 1); - lua::luanumber r = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number r = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); - lua::luanumber g = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number g = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 3); - lua::luanumber b = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number b = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 4); - lua::luanumber a = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number a = lua_tonumber(L, -1); lua_pop(L, 1); lua_pop(L, 1); return glm::vec4(r/255, g/255, b/255, a/255); } diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index 7597ce66..644b2b95 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -137,7 +137,8 @@ doublesupplier scripting::create_number_supplier( if (state->isfunction(-1)) { state->callNoThrow(0); } - lua::luanumber x = state->tonumber(-1); state->pop(); + auto x = state->tonumber(-1); + state->pop(); return x; } return 0.0; @@ -169,8 +170,8 @@ vec2supplier scripting::create_vec2_supplier( if (state->isfunction(-1)) { state->callNoThrow(0); } - lua::luanumber y = state->tonumber(-1); state->pop(); - lua::luanumber x = state->tonumber(-1); state->pop(); + auto y = state->tonumber(-1); state->pop(); + auto x = state->tonumber(-1); state->pop(); return glm::vec2(x, y); } return glm::vec2(0, 0); diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index ba8ccce5..331c1f60 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -167,6 +167,22 @@ float Player::getSpeed() const { return speed; } +bool Player::isFlight() const { + return flight; +} + +void Player::setFlight(bool flag) { + this->flight = flag; +} + +bool Player::isNoclip() const { + return noclip; +} + +void Player::setNoclip(bool flag) { + this->noclip = flag; +} + std::shared_ptr Player::getInventory() const { return inventory; } diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index 54aa4b12..24825e4a 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -37,12 +37,12 @@ class Player : public Object, public Serializable { int chosenSlot; glm::vec3 spawnpoint {}; std::shared_ptr inventory; + bool flight = false; + bool noclip = false; public: std::shared_ptr camera, spCamera, tpCamera; std::shared_ptr currentCamera; std::unique_ptr hitbox; - bool flight = false; - bool noclip = false; bool debug = false; voxel selectedVoxel {0, 0}; glm::vec2 cam {}; @@ -59,6 +59,12 @@ public: int getChosenSlot() const; float getSpeed() const; + + bool isFlight() const; + void setFlight(bool flag); + + bool isNoclip() const; + void setNoclip(bool flag); std::shared_ptr getInventory() const; From 0eba793d634fb8fa59545b4bfc68b3dc7ff27552 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 01:58:34 +0300 Subject: [PATCH 16/97] added player camera rotation z axis --- src/logic/PlayerController.cpp | 10 ++++++---- src/logic/scripting/lua/libplayer.cpp | 17 ++++++++++++----- src/objects/Player.cpp | 4 ++++ src/objects/Player.hpp | 2 +- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index fe5cfe75..44e73512 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -47,14 +47,16 @@ void CameraControl::refresh() { } void CameraControl::updateMouse(PlayerInput& input) { - glm::vec2& cam = player->cam; + glm::vec3& cam = player->cam; float sensitivity = (input.zoom ? settings.sensitivity.get() / 4.f : settings.sensitivity.get()); - cam -= glm::degrees(Events::delta / (float)Window::height * sensitivity); - + auto d = glm::degrees(Events::delta / (float)Window::height * sensitivity); + cam.x -= d.x; + cam.y -= d.y; + if (cam.y < -89.9f) { cam.y = -89.9f; } @@ -69,7 +71,7 @@ void CameraControl::updateMouse(PlayerInput& input) { } camera->rotation = glm::mat4(1.0f); - camera->rotate(glm::radians(cam.y), glm::radians(cam.x), 0); + camera->rotate(glm::radians(cam.y), glm::radians(cam.x), glm::radians(cam.z)); } glm::vec3 CameraControl::updateCameraShaking(float delta) { diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp index 5c27d954..3ce71759 100644 --- a/src/logic/scripting/lua/libplayer.cpp +++ b/src/logic/scripting/lua/libplayer.cpp @@ -66,10 +66,11 @@ static int l_player_get_rot(lua_State* L) { if (!player) { return 0; } - glm::vec2 rot = player->cam; + const glm::vec3& rot = player->cam; lua_pushnumber(L, rot.x); lua_pushnumber(L, rot.y); - return 2; + lua_pushnumber(L, rot.z); + return 3; } static int l_player_set_rot(lua_State* L) { @@ -77,11 +78,17 @@ static int l_player_set_rot(lua_State* L) { if (!player) { return 0; } - auto x = lua_tonumber(L, 2); - auto y = lua_tonumber(L, 3); - glm::vec2& cam = player->cam; + glm::vec3& cam = player->cam; + + lua_Number x = lua_tonumber(L, 2); + lua_Number y = lua_tonumber(L, 3); + lua_Number z = cam.z; + if (lua_isnumber(L, 4)) { + z = lua_tonumber(L, 4); + } cam.x = x; cam.y = y; + cam.z = z; return 0; } diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 331c1f60..c441eff0 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -206,6 +206,7 @@ std::unique_ptr Player::serialize() const { auto& rotarr = root->putList("rotation"); rotarr.put(cam.x); rotarr.put(cam.y); + rotarr.put(cam.z); auto& sparr = root->putList("spawnpoint"); sparr.put(spawnpoint.x); @@ -230,6 +231,9 @@ void Player::deserialize(dynamic::Map *src) { auto rotarr = src->list("rotation"); cam.x = rotarr->num(0); cam.y = rotarr->num(1); + if (rotarr->size() > 2) { + cam.z = rotarr->num(2); + } if (src->has("spawnpoint")) { auto sparr = src->list("spawnpoint"); diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index 24825e4a..3dd9e4be 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -45,7 +45,7 @@ public: std::unique_ptr hitbox; bool debug = false; voxel selectedVoxel {0, 0}; - glm::vec2 cam {}; + glm::vec3 cam {}; Player(glm::vec3 position, float speed, std::shared_ptr inv); ~Player(); From acac22d9c91558bab7b4ebdaa59f03cab74dace0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 01:59:38 +0300 Subject: [PATCH 17/97] player.set_noclip docs fix --- doc/en/8.Scripting.md | 2 +- doc/ru/8.Скриптинг.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/en/8.Scripting.md b/doc/en/8.Scripting.md index b0fb326f..c10878d0 100644 --- a/doc/en/8.Scripting.md +++ b/doc/en/8.Scripting.md @@ -81,7 +81,7 @@ player.is_noclip() -> bool player.set_noclip(bool) ``` -Getter and setter for player noclip mode (physics disabled) +Getter and setter for player noclip mode (collisions disabled) ## *world* library diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index 1b1c7f83..91e5cdb4 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -75,7 +75,7 @@ player.is_noclip() -> bool player.set_noclip(bool) ``` -Геттер и сеттер noclip режима (выключенная физика игрока) +Геттер и сеттер noclip режима (выключенная коллизия игрока) ## Библиотека world From 5ac51a6fa444a515484f8eba0f9b9b81cfe7ea6e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 02:01:06 +0300 Subject: [PATCH 18/97] player.get_rot docs fix --- doc/en/8.Scripting.md | 4 ++-- doc/ru/8.Скриптинг.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/en/8.Scripting.md b/doc/en/8.Scripting.md index c10878d0..5aa1f8cb 100644 --- a/doc/en/8.Scripting.md +++ b/doc/en/8.Scripting.md @@ -52,10 +52,10 @@ player.set_pos(playerid: int, x: number, y: number, z: number) Set player position ```python -player.get_rot(playerid: int) -> number, number +player.get_rot(playerid: int) -> number, number, number ``` -Returns x, y of camera rotation (radians) +Returns x, y, z of camera rotation (radians) ```python player.set_rot(playerid: int, x: number, y: number, z: number) diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index 91e5cdb4..e68ea1a4 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -46,10 +46,10 @@ player.set_pos(playerid: int, x: number, y: number, z: number) Устанавливает x, y, z координаты игрока ```python -player.get_rot(playerid: int) -> number, number +player.get_rot(playerid: int) -> number, number, number ``` -Возвращает x, y вращения камеры (в радианах) +Возвращает x, y, z вращения камеры (в радианах) ```python player.set_rot(playerid: int, x: number, y: number, z: number) From a1776e015e170e5ab5575343f0b01836b4554107 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 05:22:14 +0300 Subject: [PATCH 19/97] fixes --- src/window/Camera.cpp | 3 +-- src/world/Level.hpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/window/Camera.cpp b/src/window/Camera.cpp index 0dc486b5..80b16af2 100644 --- a/src/window/Camera.cpp +++ b/src/window/Camera.cpp @@ -21,10 +21,9 @@ void Camera::updateVectors(){ } void Camera::rotate(float x, float y, float z){ - rotation = glm::rotate(rotation, z, glm::vec3(0,0,1)); rotation = glm::rotate(rotation, y, glm::vec3(0,1,0)); rotation = glm::rotate(rotation, x, glm::vec3(1,0,0)); - + rotation = glm::rotate(rotation, z, glm::vec3(0,0,1)); updateVectors(); } diff --git a/src/world/Level.hpp b/src/world/Level.hpp index 7b18f06f..e64871ab 100644 --- a/src/world/Level.hpp +++ b/src/world/Level.hpp @@ -58,8 +58,8 @@ public: std::shared_ptr tObj = std::make_shared(args...); std::shared_ptr obj = std::dynamic_pointer_cast(tObj); - obj->objectUID = objects.size(); objects.push_back(obj); + obj->objectUID = objects.size(); obj->spawned(); return tObj; } From 1c45236693ec1337d3c58e8c1f3b70811c7594a5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 05:33:31 +0300 Subject: [PATCH 20/97] added wpos property (window position) --- src/logic/scripting/lua/libgui.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 34b01e1e..a72f91c7 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -101,7 +101,7 @@ static int l_container_clear(lua_State* L) { return 0; } -static int l_uinode_move_into(lua_State* L) { +static int l_move_into(lua_State* L) { auto node = getDocumentNode(L, 1); auto dest = getDocumentNode(L, 2); UINode::moveInto(node.node, std::dynamic_pointer_cast(dest.node)); @@ -267,6 +267,9 @@ static int p_get_pressed_color(UINode* node) { static int p_get_pos(UINode* node) { return lua::pushvec2_arr(state->getLua(), node->getPos()); } +static int p_get_wpos(UINode* node) { + return lua::pushvec2_arr(state->getLua(), node->calcPos()); +} static int p_get_size(UINode* node) { return lua::pushvec2_arr(state->getLua(), node->getSize()); } @@ -280,7 +283,7 @@ static int p_is_enabled(UINode* node) { return state->pushboolean(node->isEnabled()); } static int p_move_into(UINode*) { - return state->pushcfunction(l_uinode_move_into); + return state->pushcfunction(l_move_into); } static int p_get_focused(UINode* node) { return state->pushboolean(node->isFocused()); @@ -298,6 +301,7 @@ static int l_gui_getattr(lua_State* L) { {"hoverColor", p_get_hover_color}, {"pressedColor", p_get_pressed_color}, {"pos", p_get_pos}, + {"wpos", p_get_wpos}, {"size", p_get_size}, {"interactive", p_is_interactive}, {"visible", p_is_visible}, @@ -344,6 +348,9 @@ static void p_set_pressed_color(UINode* node, int idx) { static void p_set_pos(UINode* node, int idx) { node->setPos(state->tovec2(idx)); } +static void p_set_wpos(UINode* node, int idx) { + node->setPos(state->tovec2(idx)-node->calcPos()); +} static void p_set_size(UINode* node, int idx) { node->setSize(state->tovec2(idx)); } @@ -458,6 +465,7 @@ static int l_gui_setattr(lua_State* L) { {"hoverColor", p_set_hover_color}, {"pressedColor", p_set_pressed_color}, {"pos", p_set_pos}, + {"wpos", p_set_wpos}, {"size", p_set_size}, {"interactive", p_set_interactive}, {"visible", p_set_visible}, From eb1090406941a243e710b5cae29b8625ca8bdbbd Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 08:03:05 +0300 Subject: [PATCH 21/97] added tooltips --- src/graphics/ui/GUI.cpp | 40 +++++++++++++++++++++- src/graphics/ui/GUI.hpp | 10 ++++-- src/graphics/ui/elements/InventoryView.cpp | 14 +++++++- src/graphics/ui/elements/InventoryView.hpp | 1 + src/graphics/ui/elements/Label.cpp | 31 ++++++++++++++--- src/graphics/ui/elements/Label.hpp | 8 +++++ src/graphics/ui/elements/UINode.cpp | 26 +++++++++++++- src/graphics/ui/elements/UINode.hpp | 12 ++++++- src/graphics/ui/gui_xml.cpp | 7 ++++ src/logic/scripting/lua/libgui.cpp | 8 +++++ 10 files changed, 146 insertions(+), 11 deletions(-) diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index cdff6fc5..0fc17f8c 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -1,9 +1,14 @@ #include "GUI.hpp" + +#include "gui_util.hpp" + #include "elements/UINode.hpp" +#include "elements/Label.hpp" #include "elements/Menu.hpp" #include "../../assets/Assets.hpp" #include "../../frontend/UiDocument.hpp" +#include "../../frontend/locale.hpp" #include "../../graphics/core/Batch2D.hpp" #include "../../graphics/core/Shader.hpp" #include "../../graphics/core/DrawContext.hpp" @@ -27,6 +32,15 @@ GUI::GUI() { menu->setId("menu"); container->add(menu); container->setScrollable(false); + + tooltip = guiutil::create( + "" + "" + "" + ); + store("tooltip", tooltip); + store("tooltip.label", UINode::find(tooltip, "tooltip.label")); + container->add(tooltip); } GUI::~GUI() { @@ -45,10 +59,34 @@ void GUI::onAssetsLoad(Assets* assets) { ), "core:root"); } +void GUI::updateTooltip(float delta) { + float mouseDelta = glm::length(Events::delta); + if ((hover && mouseDelta < 1.0f) || + (hover && hover->isInside(Events::cursor) && tooltipTimer >= tooltipDelay)) { + if (tooltipTimer + delta >= tooltipDelay) { + auto label = std::dynamic_pointer_cast(get("tooltip.label")); + const auto& text = hover->getTooltip(); + if (label && !text.empty()) { + tooltip->setVisible(true); + tooltip->setPos(Events::cursor+glm::vec2(10.0f)); + label->setText(langs::get(text)); + tooltip->setSize(label->getSize()+glm::vec2(4.0f)); + } + } + tooltipTimer += delta; + } else { + tooltipTimer = 0.0f; + tooltip->setVisible(false); + } +} + /// @brief Mouse related input and logic handling void GUI::actMouse(float delta) { + updateTooltip(delta); + + float mouseDelta = glm::length(Events::delta); doubleClicked = false; - doubleClickTimer += delta + glm::length(Events::delta) * 0.1f; + doubleClickTimer += delta + mouseDelta * 0.1f; auto hover = container->getAt(Events::cursor, nullptr); if (this->hover && this->hover != hover) { diff --git a/src/graphics/ui/GUI.hpp b/src/graphics/ui/GUI.hpp index e88a3ea1..cb1dc4ff 100644 --- a/src/graphics/ui/GUI.hpp +++ b/src/graphics/ui/GUI.hpp @@ -54,21 +54,25 @@ namespace gui { /// @brief The main UI controller class GUI { std::shared_ptr container; - std::shared_ptr hover = nullptr; - std::shared_ptr pressed = nullptr; - std::shared_ptr focus = nullptr; + std::shared_ptr hover; + std::shared_ptr pressed; + std::shared_ptr focus; + std::shared_ptr tooltip; std::unordered_map> storage; std::unique_ptr uicamera; std::shared_ptr menu; std::queue postRunnables; + float tooltipTimer = 0.0f; + float tooltipDelay = 0.5f; float doubleClickTimer = 0.0f; float doubleClickDelay = 0.5f; bool doubleClicked = false; void actMouse(float delta); void actFocused(); + void updateTooltip(float delta); public: GUI(); ~GUI(); diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 1ca82a72..7995a583 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -1,7 +1,9 @@ #include "InventoryView.hpp" + #include "../../../assets/Assets.hpp" #include "../../../content/Content.hpp" #include "../../../frontend/LevelFrontend.hpp" +#include "../../../frontend/locale.hpp" #include "../../../items/Inventories.hpp" #include "../../../items/Inventory.hpp" #include "../../../items/ItemDef.hpp" @@ -22,7 +24,6 @@ #include "../../render/BlocksPreview.hpp" #include "../GUI.hpp" -#include #include using namespace gui; @@ -270,6 +271,17 @@ void SlotView::onFocus(gui::GUI* gui) { clicked(gui, mousecode::BUTTON_1); } +const std::wstring SlotView::getTooltip() const { + const auto str = UINode::getTooltip(); + if (!str.empty() || bound->isEmpty()) { + return str; + } + auto def = content->getIndices()->getItemDef(bound->getItemId()); + return util::capitalized( + langs::get(util::str2wstr_utf8(def->caption)) + ); // TODO: cache +} + void SlotView::bind( int64_t inventoryid, ItemStack& stack, diff --git a/src/graphics/ui/elements/InventoryView.hpp b/src/graphics/ui/elements/InventoryView.hpp index 8e3006d7..5bb5629c 100644 --- a/src/graphics/ui/elements/InventoryView.hpp +++ b/src/graphics/ui/elements/InventoryView.hpp @@ -63,6 +63,7 @@ namespace gui { virtual void clicked(gui::GUI*, mousecode) override; virtual void onFocus(gui::GUI*) override; + virtual const std::wstring getTooltip() const override; void bind( int64_t inventoryid, diff --git a/src/graphics/ui/elements/Label.cpp b/src/graphics/ui/elements/Label.cpp index a7bb198d..f8e9fa07 100644 --- a/src/graphics/ui/elements/Label.cpp +++ b/src/graphics/ui/elements/Label.cpp @@ -64,12 +64,28 @@ Label::Label(std::wstring text, std::string fontName) cache.update(this->text, multiline, textWrap); } +glm::vec2 Label::calcSize() { + auto font = cache.font; + uint lineHeight = font->getLineHeight(); + if (cache.lines.size() > 1) { + lineHeight *= lineInterval; + } + return glm::vec2 ( + cache.font->calcWidth(text), + lineHeight * cache.lines.size() + font->getYOffset() + ); +} + void Label::setText(std::wstring text) { if (text == this->text && !cache.resetFlag) { return; } this->text = text; cache.update(this->text, multiline, textWrap); + + if (cache.font) { + setSize(calcSize()); + } } const std::wstring& Label::getText() const { @@ -156,10 +172,10 @@ void Label::draw(const DrawContext* pctx, Assets* assets) { lineHeight *= lineInterval; } glm::vec2 size = getSize(); - glm::vec2 newsize ( - font->calcWidth(text), - lineHeight * cache.lines.size() + font->getYOffset() - ); + glm::vec2 newsize = calcSize(); + if (autoresize) { + setSize(newsize); + } glm::vec2 pos = calcPos(); switch (align) { @@ -194,6 +210,13 @@ void Label::textSupplier(wstringsupplier supplier) { this->supplier = supplier; } +void Label::setAutoResize(bool flag) { + this->autoresize = flag; +} + +bool Label::isAutoResize() const { + return autoresize; +} void Label::setMultiline(bool multiline) { if (multiline != this->multiline) { diff --git a/src/graphics/ui/elements/Label.hpp b/src/graphics/ui/elements/Label.hpp index b7615ad5..87e82e72 100644 --- a/src/graphics/ui/elements/Label.hpp +++ b/src/graphics/ui/elements/Label.hpp @@ -24,6 +24,8 @@ namespace gui { class Label : public UINode { LabelCache cache; + + glm::vec2 calcSize(); protected: std::wstring text; std::string fontName; @@ -47,6 +49,9 @@ namespace gui { /// @brief Text line height multiplied by line interval int totalLineHeight = 1; + + /// @brief Auto resize label to fit text + bool autoresize = false; public: Label(std::string text, std::string fontName="normal"); Label(std::wstring text, std::string fontName="normal"); @@ -95,6 +100,9 @@ namespace gui { virtual void textSupplier(wstringsupplier supplier); + virtual void setAutoResize(bool flag); + virtual bool isAutoResize() const; + virtual void setMultiline(bool multiline); virtual bool isMultiline() const; diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index de1ced1c..be2cf9f8 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -129,6 +129,14 @@ bool UINode::isResizing() const { return resizing; } +void UINode::setTooltip(const std::wstring& text) { + this->tooltip = text; +} + +const std::wstring UINode::getTooltip() const { + return tooltip; +} + glm::vec2 UINode::calcPos() const { if (parent) { return pos + parent->calcPos() + parent->contentOffset(); @@ -316,7 +324,7 @@ void UINode::setGravity(Gravity gravity) { } void UINode::getIndices( - std::shared_ptr node, + const std::shared_ptr node, std::unordered_map>& map ) { const std::string& id = node->getId(); @@ -330,3 +338,19 @@ void UINode::getIndices( } } } +std::shared_ptr UINode::find( + const std::shared_ptr node, + const std::string& id +) { + if (node->getId() == id) { + return node; + } + if (auto container = std::dynamic_pointer_cast(node)) { + for (auto subnode : container->getNodes()) { + if (auto found = UINode::find(subnode, id)) { + return found; + } + } + } + return nullptr; +} diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index b4667acd..37a3b1b8 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -109,6 +109,8 @@ namespace gui { ActionsSet actions; /// @brief 'ondoubleclick' callbacks ActionsSet doubleClickCallbacks; + /// @brief element tooltip text + std::wstring tooltip; UINode(glm::vec2 size); public: @@ -197,6 +199,9 @@ namespace gui { virtual void setResizing(bool flag); virtual bool isResizing() const; + virtual void setTooltip(const std::wstring& text); + virtual const std::wstring getTooltip() const; + virtual glm::vec4 calcColor() const; /// @brief Get inner content offset. Used for scroll @@ -237,9 +242,14 @@ namespace gui { /// @brief collect all nodes having id static void getIndices( - std::shared_ptr node, + const std::shared_ptr node, std::unordered_map>& map ); + + static std::shared_ptr find( + const std::shared_ptr node, + const std::string& id + ); }; } diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index 50ba1bb2..cd3a9de7 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -143,6 +143,10 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no )); } + if (element->has("tooltip")) { + node.setTooltip(util::str2wstr_utf8(element->attr("tooltip").getText())); + } + if (auto onclick = create_action(reader, element, "onclick")) { node.listenAction(onclick); } @@ -245,6 +249,9 @@ static std::shared_ptr readLabel(UiXmlReader& reader, xml::xmlelement el reader.getFilename() )); } + if (element->has("autoresize")) { + label->setAutoResize(element->attr("autoresize").asBool()); + } if (element->has("multiline")) { label->setMultiline(element->attr("multiline").asBool()); if (!element->has("valign")) { diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index a72f91c7..de823455 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -264,6 +264,9 @@ static int p_get_hover_color(UINode* node) { static int p_get_pressed_color(UINode* node) { return lua::pushcolor_arr(state->getLua(), node->getPressedColor()); } +static int p_get_tooltip(UINode* node) { + return state->pushstring(util::wstr2str_utf8(node->getTooltip())); +} static int p_get_pos(UINode* node) { return lua::pushvec2_arr(state->getLua(), node->getPos()); } @@ -300,6 +303,7 @@ static int l_gui_getattr(lua_State* L) { {"color", p_get_color}, {"hoverColor", p_get_hover_color}, {"pressedColor", p_get_pressed_color}, + {"tooltip", p_get_tooltip}, {"pos", p_get_pos}, {"wpos", p_get_wpos}, {"size", p_get_size}, @@ -345,6 +349,9 @@ static void p_set_hover_color(UINode* node, int idx) { static void p_set_pressed_color(UINode* node, int idx) { node->setPressedColor(state->tocolor(idx)); } +static void p_set_tooltip(UINode* node, int idx) { + node->setTooltip(util::str2wstr_utf8(state->tostring(idx))); +} static void p_set_pos(UINode* node, int idx) { node->setPos(state->tovec2(idx)); } @@ -464,6 +471,7 @@ static int l_gui_setattr(lua_State* L) { {"color", p_set_color}, {"hoverColor", p_set_hover_color}, {"pressedColor", p_set_pressed_color}, + {"tooltip", p_set_tooltip}, {"pos", p_set_pos}, {"wpos", p_set_wpos}, {"size", p_set_size}, From fa985138c4976383b93813462a4d6f3d20ca6c80 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 09:07:11 +0300 Subject: [PATCH 22/97] fix: tooltip getting out of the root container --- src/graphics/ui/GUI.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 0fc17f8c..bb958450 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -68,9 +68,14 @@ void GUI::updateTooltip(float delta) { const auto& text = hover->getTooltip(); if (label && !text.empty()) { tooltip->setVisible(true); - tooltip->setPos(Events::cursor+glm::vec2(10.0f)); label->setText(langs::get(text)); - tooltip->setSize(label->getSize()+glm::vec2(4.0f)); + auto size = label->getSize()+glm::vec2(4.0f); + auto pos = Events::cursor+glm::vec2(10.0f); + auto rootSize = container->getSize(); + pos.x = glm::min(pos.x, rootSize.x-size.x); + pos.y = glm::min(pos.y, rootSize.y-size.y); + tooltip->setSize(size); + tooltip->setPos(pos); } } tooltipTimer += delta; From 4400efae337a348b8f527d6a2889e43f9005906c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 09:23:26 +0300 Subject: [PATCH 23/97] item captions format update --- src/graphics/ui/elements/InventoryView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 7995a583..181b8bd7 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -277,7 +277,7 @@ const std::wstring SlotView::getTooltip() const { return str; } auto def = content->getIndices()->getItemDef(bound->getItemId()); - return util::capitalized( + return util::pascal_case( langs::get(util::str2wstr_utf8(def->caption)) ); // TODO: cache } From e3989cb178172c81d49240dfa40680d59ba32e7b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 24 May 2024 13:18:20 +0300 Subject: [PATCH 24/97] added 'tooltip-delay' property --- src/graphics/ui/GUI.cpp | 4 ++-- src/graphics/ui/GUI.hpp | 1 - src/graphics/ui/elements/InventoryView.cpp | 1 + src/graphics/ui/elements/UINode.cpp | 9 +++++++++ src/graphics/ui/elements/UINode.hpp | 5 +++++ src/graphics/ui/gui_xml.cpp | 3 +++ src/logic/scripting/lua/libgui.cpp | 8 ++++++++ 7 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index bb958450..eb83529d 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -62,8 +62,8 @@ void GUI::onAssetsLoad(Assets* assets) { void GUI::updateTooltip(float delta) { float mouseDelta = glm::length(Events::delta); if ((hover && mouseDelta < 1.0f) || - (hover && hover->isInside(Events::cursor) && tooltipTimer >= tooltipDelay)) { - if (tooltipTimer + delta >= tooltipDelay) { + (hover && hover->isInside(Events::cursor) && tooltipTimer >= hover->getTooltipDelay())) { + if (tooltipTimer + delta >= hover->getTooltipDelay()) { auto label = std::dynamic_pointer_cast(get("tooltip.label")); const auto& text = hover->getTooltip(); if (label && !text.empty()) { diff --git a/src/graphics/ui/GUI.hpp b/src/graphics/ui/GUI.hpp index cb1dc4ff..8975533b 100644 --- a/src/graphics/ui/GUI.hpp +++ b/src/graphics/ui/GUI.hpp @@ -65,7 +65,6 @@ namespace gui { std::queue postRunnables; float tooltipTimer = 0.0f; - float tooltipDelay = 0.5f; float doubleClickTimer = 0.0f; float doubleClickDelay = 0.5f; bool doubleClicked = false; diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 181b8bd7..bcfea371 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -109,6 +109,7 @@ SlotView::SlotView( layout(layout) { setColor(glm::vec4(0, 0, 0, 0.2f)); + setTooltipDelay(0.05f); } void SlotView::draw(const DrawContext* pctx, Assets* assets) { diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index be2cf9f8..ddae4ea8 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -137,6 +137,15 @@ const std::wstring UINode::getTooltip() const { return tooltip; } +void UINode::setTooltipDelay(float delay) { + tooltipDelay = delay; +} + +float UINode::getTooltipDelay() const { + return tooltipDelay; +} + + glm::vec2 UINode::calcPos() const { if (parent) { return pos + parent->calcPos() + parent->contentOffset(); diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index 37a3b1b8..073bd43f 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -111,6 +111,8 @@ namespace gui { ActionsSet doubleClickCallbacks; /// @brief element tooltip text std::wstring tooltip; + /// @brief element tooltip delay + float tooltipDelay = 0.5f; UINode(glm::vec2 size); public: @@ -202,6 +204,9 @@ namespace gui { virtual void setTooltip(const std::wstring& text); virtual const std::wstring getTooltip() const; + virtual void setTooltipDelay(float delay); + virtual float getTooltipDelay() const; + virtual glm::vec4 calcColor() const; /// @brief Get inner content offset. Used for scroll diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index cd3a9de7..3ef8a09d 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -146,6 +146,9 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no if (element->has("tooltip")) { node.setTooltip(util::str2wstr_utf8(element->attr("tooltip").getText())); } + if (element->has("tooltip-delay")) { + node.setTooltipDelay(element->attr("tooltip-delay").asFloat()); + } if (auto onclick = create_action(reader, element, "onclick")) { node.listenAction(onclick); diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index de823455..fa2cb93e 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -267,6 +267,9 @@ static int p_get_pressed_color(UINode* node) { static int p_get_tooltip(UINode* node) { return state->pushstring(util::wstr2str_utf8(node->getTooltip())); } +static int p_get_tooltip_delay(UINode* node) { + return state->pushnumber(node->getTooltipDelay()); +} static int p_get_pos(UINode* node) { return lua::pushvec2_arr(state->getLua(), node->getPos()); } @@ -304,6 +307,7 @@ static int l_gui_getattr(lua_State* L) { {"hoverColor", p_get_hover_color}, {"pressedColor", p_get_pressed_color}, {"tooltip", p_get_tooltip}, + {"tooltipDelay", p_get_tooltip_delay}, {"pos", p_get_pos}, {"wpos", p_get_wpos}, {"size", p_get_size}, @@ -352,6 +356,9 @@ static void p_set_pressed_color(UINode* node, int idx) { static void p_set_tooltip(UINode* node, int idx) { node->setTooltip(util::str2wstr_utf8(state->tostring(idx))); } +static void p_set_tooltip_delay(UINode* node, int idx) { + node->setTooltipDelay(state->tonumber(idx)); +} static void p_set_pos(UINode* node, int idx) { node->setPos(state->tovec2(idx)); } @@ -472,6 +479,7 @@ static int l_gui_setattr(lua_State* L) { {"hoverColor", p_set_hover_color}, {"pressedColor", p_set_pressed_color}, {"tooltip", p_set_tooltip}, + {"tooltipDelay", p_set_tooltip_delay}, {"pos", p_set_pos}, {"wpos", p_set_wpos}, {"size", p_set_size}, From cc27e4b224e68a3a85e22b0a12e4c477f00d2b19 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 25 May 2024 06:24:54 +0300 Subject: [PATCH 25/97] fix: tooltip visibility when cursor is hidden --- src/graphics/ui/GUI.cpp | 8 ++++++-- src/graphics/ui/elements/Container.cpp | 2 +- src/graphics/ui/elements/UINode.cpp | 16 ++++++++++++++-- src/graphics/ui/elements/UINode.hpp | 2 ++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index eb83529d..27a58444 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -87,8 +87,6 @@ void GUI::updateTooltip(float delta) { /// @brief Mouse related input and logic handling void GUI::actMouse(float delta) { - updateTooltip(delta); - float mouseDelta = glm::length(Events::delta); doubleClicked = false; doubleClickTimer += delta + mouseDelta * 0.1f; @@ -177,8 +175,14 @@ void GUI::act(float delta, const Viewport& vp) { container->act(delta); auto prevfocus = focus; + updateTooltip(delta); if (!Events::_cursor_locked) { actMouse(delta); + } else { + if (hover) { + hover->setHover(false); + hover = nullptr; + } } if (focus) { diff --git a/src/graphics/ui/elements/Container.cpp b/src/graphics/ui/elements/Container.cpp index 51341aa3..fe8d77ba 100644 --- a/src/graphics/ui/elements/Container.cpp +++ b/src/graphics/ui/elements/Container.cpp @@ -13,7 +13,7 @@ Container::Container(glm::vec2 size) : UINode(size) { } std::shared_ptr Container::getAt(glm::vec2 pos, std::shared_ptr self) { - if (!interactive || !isEnabled()) { + if (!isInteractive() || !isEnabled()) { return nullptr; } if (!isInside(pos)) return nullptr; diff --git a/src/graphics/ui/elements/UINode.cpp b/src/graphics/ui/elements/UINode.cpp index ddae4ea8..76297154 100644 --- a/src/graphics/ui/elements/UINode.cpp +++ b/src/graphics/ui/elements/UINode.cpp @@ -13,6 +13,9 @@ UINode::~UINode() { } bool UINode::isVisible() const { + if (visible && parent) { + return parent->isVisible(); + } return visible; } @@ -107,7 +110,7 @@ bool UINode::isInside(glm::vec2 point) { } std::shared_ptr UINode::getAt(glm::vec2 point, std::shared_ptr self) { - if (!interactive || !enabled) { + if (!isInteractive() || !enabled) { return nullptr; } return isInside(point) ? self : nullptr; @@ -145,7 +148,6 @@ float UINode::getTooltipDelay() const { return tooltipDelay; } - glm::vec2 UINode::calcPos() const { if (parent) { return pos + parent->calcPos() + parent->contentOffset(); @@ -332,6 +334,16 @@ void UINode::setGravity(Gravity gravity) { } } +bool UINode::isSubnodeOf(const UINode* node) { + if (parent == nullptr) { + return false; + } + if (parent == node) { + return true; + } + return parent->isSubnodeOf(node); +} + void UINode::getIndices( const std::shared_ptr node, std::unordered_map>& map diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index 073bd43f..74977b57 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -245,6 +245,8 @@ namespace gui { virtual void setGravity(Gravity gravity); + bool isSubnodeOf(const UINode* node); + /// @brief collect all nodes having id static void getIndices( const std::shared_ptr node, From d437b67580fc549f3efe67ad0344b1cc3c7a3611 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 25 May 2024 09:09:31 +0300 Subject: [PATCH 26/97] minor refactor --- src/graphics/ui/GUI.cpp | 14 ++++++++++---- src/graphics/ui/GUI.hpp | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 27a58444..9ec6754d 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -59,10 +59,17 @@ void GUI::onAssetsLoad(Assets* assets) { ), "core:root"); } +void GUI::resetTooltip() { + tooltipTimer = 0.0f; + tooltip->setVisible(false); +} + void GUI::updateTooltip(float delta) { + if (hover == nullptr || !hover->isInside(Events::cursor)) { + return resetTooltip(); + } float mouseDelta = glm::length(Events::delta); - if ((hover && mouseDelta < 1.0f) || - (hover && hover->isInside(Events::cursor) && tooltipTimer >= hover->getTooltipDelay())) { + if (mouseDelta < 1.0f || tooltipTimer >= hover->getTooltipDelay()) { if (tooltipTimer + delta >= hover->getTooltipDelay()) { auto label = std::dynamic_pointer_cast(get("tooltip.label")); const auto& text = hover->getTooltip(); @@ -80,8 +87,7 @@ void GUI::updateTooltip(float delta) { } tooltipTimer += delta; } else { - tooltipTimer = 0.0f; - tooltip->setVisible(false); + resetTooltip(); } } diff --git a/src/graphics/ui/GUI.hpp b/src/graphics/ui/GUI.hpp index 8975533b..c28e5d58 100644 --- a/src/graphics/ui/GUI.hpp +++ b/src/graphics/ui/GUI.hpp @@ -72,6 +72,7 @@ namespace gui { void actMouse(float delta); void actFocused(); void updateTooltip(float delta); + void resetTooltip(); public: GUI(); ~GUI(); From 43903bb378e3ac83b1841aefcd62b74daa299663 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 25 May 2024 09:26:21 +0300 Subject: [PATCH 27/97] memory-related refactor --- src/assets/Assets.cpp | 24 ++++++++++++------------ src/assets/Assets.hpp | 12 ++++++------ src/assets/AssetsLoader.cpp | 2 +- src/assets/assetload_funcs.cpp | 13 ++++++------- src/frontend/LevelFrontend.cpp | 2 +- src/frontend/menu.cpp | 15 ++++++++++----- src/graphics/core/Shader.cpp | 4 ++-- src/graphics/core/Shader.hpp | 3 ++- src/graphics/ui/GUI.cpp | 2 +- 9 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/assets/Assets.cpp b/src/assets/Assets.cpp index d1c93360..12a3db65 100644 --- a/src/assets/Assets.cpp +++ b/src/assets/Assets.cpp @@ -18,8 +18,8 @@ Texture* Assets::getTexture(std::string name) const { return found->second.get(); } -void Assets::store(Texture* texture, std::string name){ - textures.emplace(name, texture); +void Assets::store(std::unique_ptr texture, std::string name){ + textures.emplace(name, std::move(texture)); } @@ -30,8 +30,8 @@ Shader* Assets::getShader(std::string name) const{ return found->second.get(); } -void Assets::store(Shader* shader, std::string name){ - shaders.emplace(name, shader); +void Assets::store(std::unique_ptr shader, std::string name){ + shaders.emplace(name, std::move(shader)); } Font* Assets::getFont(std::string name) const { @@ -41,8 +41,8 @@ Font* Assets::getFont(std::string name) const { return found->second.get(); } -void Assets::store(Font* font, std::string name){ - fonts.emplace(name, font); +void Assets::store(std::unique_ptr font, std::string name){ + fonts.emplace(name, std::move(font)); } Atlas* Assets::getAtlas(std::string name) const { @@ -52,8 +52,8 @@ Atlas* Assets::getAtlas(std::string name) const { return found->second.get(); } -void Assets::store(Atlas* atlas, std::string name){ - atlases.emplace(name, atlas); +void Assets::store(std::unique_ptr atlas, std::string name){ + atlases.emplace(name, std::move(atlas)); } audio::Sound* Assets::getSound(std::string name) const { @@ -63,8 +63,8 @@ audio::Sound* Assets::getSound(std::string name) const { return found->second.get(); } -void Assets::store(audio::Sound* sound, std::string name) { - sounds.emplace(name, sound); +void Assets::store(std::unique_ptr sound, std::string name) { + sounds.emplace(name, std::move(sound)); } const std::vector& Assets::getAnimations() { @@ -82,6 +82,6 @@ UiDocument* Assets::getLayout(std::string name) const { return found->second.get(); } -void Assets::store(UiDocument* layout, std::string name) { - layouts[name] = std::shared_ptr(layout); +void Assets::store(std::unique_ptr layout, std::string name) { + layouts[name] = std::shared_ptr(std::move(layout)); } diff --git a/src/assets/Assets.hpp b/src/assets/Assets.hpp index a9d4b927..c06e764f 100644 --- a/src/assets/Assets.hpp +++ b/src/assets/Assets.hpp @@ -39,25 +39,25 @@ public: ~Assets(); Texture* getTexture(std::string name) const; - void store(Texture* texture, std::string name); + void store(std::unique_ptr texture, std::string name); Shader* getShader(std::string name) const; - void store(Shader* shader, std::string name); + void store(std::unique_ptr shader, std::string name); Font* getFont(std::string name) const; - void store(Font* font, std::string name); + void store(std::unique_ptr font, std::string name); Atlas* getAtlas(std::string name) const; - void store(Atlas* atlas, std::string name); + void store(std::unique_ptr atlas, std::string name); audio::Sound* getSound(std::string name) const; - void store(audio::Sound* sound, std::string name); + void store(std::unique_ptr sound, std::string name); const std::vector& getAnimations(); void store(const TextureAnimation& animation); UiDocument* getLayout(std::string name) const; - void store(UiDocument* layout, std::string name); + void store(std::unique_ptr layout, std::string name); }; #endif // ASSETS_ASSETS_HPP_ diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index b9fcc1e3..1f194c21 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -218,7 +218,7 @@ bool AssetsLoader::loadExternalTexture( if (fs::exists(path)) { try { auto image = imageio::read(path.string()); - assets->store(Texture::from(image.get()).release(), name); + assets->store(Texture::from(image.get()), name); return true; } catch (const std::exception& err) { logger.error() << "error while loading external " diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index 9dae4c78..bfe799bb 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -44,7 +44,7 @@ assetload::postfunc assetload::texture( imageio::read(paths->find(filename+".png").u8string()).release() ); return [name, image](auto assets) { - assets->store(Texture::from(image.get()).release(), name); + assets->store(Texture::from(image.get()), name); }; } @@ -103,7 +103,7 @@ assetload::postfunc assetload::atlas( Atlas* atlas = builder.build(2, false).release(); return [=](auto assets) { atlas->prepare(); - assets->store(atlas, name); + assets->store(std::unique_ptr(atlas), name); for (const auto& file : names) { animation(assets, paths, name, directory, file, atlas); } @@ -129,7 +129,7 @@ assetload::postfunc assetload::font( for (auto& page : *pages) { textures.emplace_back(Texture::from(page.get())); } - assets->store(new Font(std::move(textures), res, 4), name); + assets->store(std::make_unique(std::move(textures), res, 4), name); }; } @@ -143,8 +143,7 @@ assetload::postfunc assetload::layout( return [=](auto assets) { try { auto cfg = std::dynamic_pointer_cast(config); - auto document = UiDocument::read(cfg->env, name, file); - assets->store(document.release(), name); + assets->store(UiDocument::read(cfg->env, name, file), name); } catch (const parsing_error& err) { throw std::runtime_error( "failed to parse layout XML '"+file+"':\n"+err.errorLog() @@ -190,7 +189,7 @@ assetload::postfunc assetload::sound( } auto sound = baseSound.release(); return [=](auto assets) { - assets->store(sound, name); + assets->store(std::unique_ptr(sound), name); }; } @@ -305,7 +304,7 @@ static bool animation( auto animation = create_animation( srcAtlas.get(), dstAtlas, name, builder.getNames(), frameList ); - assets->store(srcAtlas.release(), atlasName + "/" + name + "_animation"); + assets->store(std::move(srcAtlas), atlasName + "/" + name + "_animation"); assets->store(animation); return true; } diff --git a/src/frontend/LevelFrontend.cpp b/src/frontend/LevelFrontend.cpp index d44df1d1..7a62ca50 100644 --- a/src/frontend/LevelFrontend.cpp +++ b/src/frontend/LevelFrontend.cpp @@ -19,7 +19,7 @@ LevelFrontend::LevelFrontend(LevelController* controller, Assets* assets) contentCache(std::make_unique(level->content, assets)) { assets->store( - BlocksPreview::build(contentCache.get(), assets, level->content).release(), + BlocksPreview::build(contentCache.get(), assets, level->content), "block-previews" ); controller->getPlayerController()->listenBlockInteraction( diff --git a/src/frontend/menu.cpp b/src/frontend/menu.cpp index 4c89aeaa..2abc23ac 100644 --- a/src/frontend/menu.cpp +++ b/src/frontend/menu.cpp @@ -62,9 +62,11 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) { auto file = engine->getResPaths()->find("layouts/pages/"+name+".xml"); auto fullname = "core:pages/"+name; - auto document = UiDocument::read(scripting::get_root_environment(), fullname, file).release(); - engine->getAssets()->store(document, fullname); - + auto document_ptr = UiDocument::read( + scripting::get_root_environment(), fullname, file + ); + auto document = document_ptr.get(); + engine->getAssets()->store(std::move(document_ptr), fullname); scripting::on_ui_open(document, std::move(args)); return document->getRoot(); }; @@ -75,8 +77,11 @@ UiDocument* menus::show(Engine* engine, const std::string& name, std::vectorgetResPaths()->find("layouts/"+name+".xml"); auto fullname = "core:layouts/"+name; - auto document = UiDocument::read(scripting::get_root_environment(), fullname, file).release(); - engine->getAssets()->store(document, fullname); + auto document_ptr = UiDocument::read( + scripting::get_root_environment(), fullname, file + ); + auto document = document_ptr.get(); + engine->getAssets()->store(std::move(document_ptr), fullname); scripting::on_ui_open(document, std::move(args)); menu->addPage(name, document->getRoot()); menu->setPage(name); diff --git a/src/graphics/core/Shader.cpp b/src/graphics/core/Shader.cpp index b6bb6802..62d82ee3 100644 --- a/src/graphics/core/Shader.cpp +++ b/src/graphics/core/Shader.cpp @@ -98,7 +98,7 @@ glshader compile_shader(GLenum type, const GLchar* source, const std::string& fi return glshader(new GLuint(shader), shader_deleter); } -Shader* Shader::create( +std::unique_ptr Shader::create( const std::string& vertexFile, const std::string& fragmentFile, const std::string& vertexCode, @@ -125,5 +125,5 @@ Shader* Shader::create( "shader program linking failed:\n"+std::string(infoLog) ); } - return new Shader(id); + return std::make_unique(id); } diff --git a/src/graphics/core/Shader.hpp b/src/graphics/core/Shader.hpp index 64b4cc83..25d182a5 100644 --- a/src/graphics/core/Shader.hpp +++ b/src/graphics/core/Shader.hpp @@ -4,6 +4,7 @@ #include "../../typedefs.hpp" #include +#include #include #include @@ -36,7 +37,7 @@ public: /// @param vertexSource vertex shader source code /// @param fragmentSource fragment shader source code /// @return linked shader program containing vertex and fragment shaders - static Shader* create( + static std::unique_ptr create( const std::string& vertexFile, const std::string& fragmentFile, const std::string& vertexSource, diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 9ec6754d..63576877 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -51,7 +51,7 @@ std::shared_ptr GUI::getMenu() { } void GUI::onAssetsLoad(Assets* assets) { - assets->store(new UiDocument( + assets->store(std::make_unique( "core:root", uidocscript {}, std::dynamic_pointer_cast(container), From e8a703f814467e015f01ab3a71460634c10530c6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 25 May 2024 10:17:55 +0300 Subject: [PATCH 28/97] LeveController delta time limited to 200 ms --- src/frontend/screens/LevelScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 93c60169..5814f3bf 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -146,7 +146,7 @@ void LevelScreen::update(float delta) { controller->getLevel()->getWorld()->updateTimers(delta); animator->update(delta); } - controller->update(delta, !inputLocked, hud->isPause()); + controller->update(glm::min(delta, 0.2f), !inputLocked, hud->isPause()); hud->update(hudVisible); } From 030c9ca0859f09f54f901a74f1b93c6ff74656a8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 27 May 2024 07:19:13 +0300 Subject: [PATCH 29/97] right click item increment fix with stack --- src/graphics/ui/elements/InventoryView.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index bcfea371..a50f45df 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -253,11 +253,12 @@ void SlotView::clicked(gui::GUI* gui, mousecode button) { stack.setCount(halfremain); } } else { + auto stackDef = content->getIndices()->getItemDef(stack.getItemId()); if (stack.isEmpty()) { stack.set(grabbed); stack.setCount(1); grabbed.setCount(grabbed.getCount()-1); - } else if (stack.accepts(grabbed)){ + } else if (stack.accepts(grabbed) && stack.getCount() < stackDef->stackSize){ stack.setCount(stack.getCount()+1); grabbed.setCount(grabbed.getCount()-1); } From 9fce00ae450a776032242cd4ec03dbf3aed58fb8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 27 May 2024 11:09:21 +0300 Subject: [PATCH 30/97] minor reformat --- src/voxels/ChunksStorage.hpp | 20 +++++++++----------- src/voxels/DefaultWorldGenerator.hpp | 6 +++--- src/voxels/FlatWorldGenerator.hpp | 6 +++--- src/voxels/WorldGenerator.hpp | 2 +- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/voxels/ChunksStorage.hpp b/src/voxels/ChunksStorage.hpp index 2f671ee7..ed9f6342 100644 --- a/src/voxels/ChunksStorage.hpp +++ b/src/voxels/ChunksStorage.hpp @@ -14,19 +14,17 @@ class Level; class VoxelsVolume; class ChunksStorage { - Level* level; - std::unordered_map> chunksMap; + Level* level; + std::unordered_map> chunksMap; public: - ChunksStorage(Level* level); - ~ChunksStorage() = default; + ChunksStorage(Level* level); + ~ChunksStorage() = default; - std::shared_ptr get(int x, int z) const; - void store(std::shared_ptr chunk); - void remove(int x, int y); - void getVoxels(VoxelsVolume* volume, bool backlight=false) const; - std::shared_ptr create(int x, int z); - - light_t getLight(int x, int y, int z, ubyte channel) const; + std::shared_ptr get(int x, int z) const; + void store(std::shared_ptr chunk); + void remove(int x, int y); + void getVoxels(VoxelsVolume* volume, bool backlight=false) const; + std::shared_ptr create(int x, int z); }; diff --git a/src/voxels/DefaultWorldGenerator.hpp b/src/voxels/DefaultWorldGenerator.hpp index 84daabb9..d42e2749 100644 --- a/src/voxels/DefaultWorldGenerator.hpp +++ b/src/voxels/DefaultWorldGenerator.hpp @@ -10,9 +10,9 @@ class Content; class DefaultWorldGenerator : WorldGenerator { public: - DefaultWorldGenerator(const Content* content) : WorldGenerator(content) {} + DefaultWorldGenerator(const Content* content) : WorldGenerator(content) {} - void generate(voxel* voxels, int x, int z, int seed); + void generate(voxel* voxels, int x, int z, int seed); }; -#endif /* VOXELS_DEFAULTWORLDGENERATOR_HPP_ */ +#endif // VOXELS_DEFAULTWORLDGENERATOR_HPP_ diff --git a/src/voxels/FlatWorldGenerator.hpp b/src/voxels/FlatWorldGenerator.hpp index 67189119..c9a2d25f 100644 --- a/src/voxels/FlatWorldGenerator.hpp +++ b/src/voxels/FlatWorldGenerator.hpp @@ -10,9 +10,9 @@ class Content; class FlatWorldGenerator : WorldGenerator { public: - FlatWorldGenerator(const Content* content) : WorldGenerator(content) {} + FlatWorldGenerator(const Content* content) : WorldGenerator(content) {} - void generate(voxel* voxels, int x, int z, int seed); + void generate(voxel* voxels, int x, int z, int seed); }; -#endif /* VOXELS_FLATWORLDGENERATOR_HPP_ */ +#endif // VOXELS_FLATWORLDGENERATOR_HPP_ diff --git a/src/voxels/WorldGenerator.hpp b/src/voxels/WorldGenerator.hpp index 10b92da6..5b8839ac 100644 --- a/src/voxels/WorldGenerator.hpp +++ b/src/voxels/WorldGenerator.hpp @@ -26,4 +26,4 @@ public: virtual void generate(voxel* voxels, int x, int z, int seed) = 0; }; -#endif /* VOXELS_WORLDGENERATOR_HPP_ */ +#endif // VOXELS_WORLDGENERATOR_HPP_ From bc8420079850d27c09afb54d7710c58830f0b454 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 27 May 2024 13:33:14 +0300 Subject: [PATCH 31/97] gui errors handling update + fix --- src/frontend/screens/LevelScreen.hpp | 2 +- src/logic/scripting/lua/libgui.cpp | 42 ++++++++++++++-------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/frontend/screens/LevelScreen.hpp b/src/frontend/screens/LevelScreen.hpp index 2b5f3527..2da4cbec 100644 --- a/src/frontend/screens/LevelScreen.hpp +++ b/src/frontend/screens/LevelScreen.hpp @@ -17,11 +17,11 @@ class Level; class LevelScreen : public Screen { std::unique_ptr frontend; - std::unique_ptr hud; std::unique_ptr controller; std::unique_ptr worldRenderer; std::unique_ptr animator; std::unique_ptr postProcessing; + std::unique_ptr hud; void saveWorldPreview(); diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index fa2cb93e..b4f4d9c3 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -50,8 +50,8 @@ static DocumentNode getDocumentNode(lua_State*, const std::string& name, const s static DocumentNode getDocumentNode(lua_State* L, int idx=1) { lua_getfield(L, idx, "docname"); lua_getfield(L, idx, "name"); - auto docname = lua_tostring(L, -2); - auto name = lua_tostring(L, -1); + auto docname = state->requireString(-2); + auto name = state->requireString(-1); auto node = getDocumentNode(L, docname, name); lua_pop(L, 2); return node; @@ -74,7 +74,7 @@ static int l_menu_reset(lua_State* L) { static int l_textbox_paste(lua_State* L) { auto node = getDocumentNode(L); auto box = dynamic_cast(node.node.get()); - auto text = lua_tostring(L, 2); + auto text = state->requireString(2); box->paste(util::str2wstr_utf8(text)); return 0; } @@ -82,7 +82,7 @@ static int l_textbox_paste(lua_State* L) { static int l_container_add(lua_State* L) { auto docnode = getDocumentNode(L); auto node = dynamic_cast(docnode.node.get()); - auto xmlsrc = lua_tostring(L, 2); + auto xmlsrc = state->requireString(2); try { auto subnode = guiutil::create(xmlsrc, docnode.document->getEnvironment()); node->add(subnode); @@ -296,9 +296,9 @@ static int p_get_focused(UINode* node) { } static int l_gui_getattr(lua_State* L) { - auto docname = lua_tostring(L, 1); - auto element = lua_tostring(L, 2); - auto attr = lua_tostring(L, 3); + auto docname = state->requireString(1); + auto element = state->requireString(2); + auto attr = state->requireString(3); auto docnode = getDocumentNode(L, docname, element); auto node = docnode.node; @@ -354,7 +354,7 @@ static void p_set_pressed_color(UINode* node, int idx) { node->setPressedColor(state->tocolor(idx)); } static void p_set_tooltip(UINode* node, int idx) { - node->setTooltip(util::str2wstr_utf8(state->tostring(idx))); + node->setTooltip(util::str2wstr_utf8(state->requireString(idx))); } static void p_set_tooltip_delay(UINode* node, int idx) { node->setTooltipDelay(state->tonumber(idx)); @@ -379,16 +379,16 @@ static void p_set_enabled(UINode* node, int idx) { } static void p_set_placeholder(UINode* node, int idx) { if (auto box = dynamic_cast(node)) { - box->setPlaceholder(util::str2wstr_utf8(state->tostring(idx))); + box->setPlaceholder(util::str2wstr_utf8(state->requireString(idx))); } } static void p_set_text(UINode* node, int idx) { if (auto label = dynamic_cast(node)) { - label->setText(util::str2wstr_utf8(state->tostring(idx))); + label->setText(util::str2wstr_utf8(state->requireString(idx))); } else if (auto button = dynamic_cast(node)) { - button->setText(util::str2wstr_utf8(state->tostring(idx))); + button->setText(util::str2wstr_utf8(state->requireString(idx))); } else if (auto box = dynamic_cast(node)) { - box->setText(util::str2wstr_utf8(state->tostring(idx))); + box->setText(util::str2wstr_utf8(state->requireString(idx))); } } static void p_set_caret(UINode* node, int idx) { @@ -445,7 +445,7 @@ static void p_set_checked(UINode* node, int idx) { } static void p_set_page(UINode* node, int idx) { if (auto menu = dynamic_cast(node)) { - menu->setPage(state->tostring(idx)); + menu->setPage(state->requireString(idx)); } } static void p_set_inventory(UINode* node, int idx) { @@ -467,9 +467,9 @@ static void p_set_focused(std::shared_ptr node, int idx) { } static int l_gui_setattr(lua_State* L) { - auto docname = lua_tostring(L, 1); - auto element = lua_tostring(L, 2); - auto attr = lua_tostring(L, 3); + auto docname = state->requireString(1); + auto element = state->requireString(2); + auto attr = state->requireString(3); auto docnode = getDocumentNode(L, docname, element); auto node = docnode.node; @@ -516,7 +516,7 @@ static int l_gui_setattr(lua_State* L) { } static int l_gui_get_env(lua_State* L) { - auto name = lua_tostring(L, 1); + auto name = state->requireString(1); auto doc = scripting::engine->getAssets()->getLayout(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); @@ -526,9 +526,9 @@ static int l_gui_get_env(lua_State* L) { } static int l_gui_str(lua_State* L) { - auto text = util::str2wstr_utf8(lua_tostring(L, 1)); + auto text = util::str2wstr_utf8(state->requireString(1)); if (!lua_isnoneornil(L, 2)) { - auto context = util::str2wstr_utf8(lua_tostring(L, 2)); + auto context = util::str2wstr_utf8(state->requireString(2)); lua_pushstring(L, util::wstr2str_utf8(langs::get(text, context)).c_str()); } else { lua_pushstring(L, util::wstr2str_utf8(langs::get(text)).c_str()); @@ -537,7 +537,7 @@ static int l_gui_str(lua_State* L) { } static int l_gui_reindex(lua_State* L) { - auto name = lua_tostring(L, 1); + auto name = state->requireString(1); auto doc = scripting::engine->getAssets()->getLayout(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); @@ -569,7 +569,7 @@ const luaL_Reg guilib [] = { {"setattr", lua_wrap_errors}, {"get_env", lua_wrap_errors}, {"str", lua_wrap_errors}, - {"reindex", lua_wrap_errors}, {"get_locales_info", lua_wrap_errors}, + {"__reindex", lua_wrap_errors}, {NULL, NULL} }; From 2d27e5662a226f816d8621e6c5779483598b9d02 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 28 May 2024 04:02:35 +0300 Subject: [PATCH 32/97] label size fix --- src/graphics/ui/elements/Label.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphics/ui/elements/Label.cpp b/src/graphics/ui/elements/Label.cpp index f8e9fa07..9e355e86 100644 --- a/src/graphics/ui/elements/Label.cpp +++ b/src/graphics/ui/elements/Label.cpp @@ -83,7 +83,7 @@ void Label::setText(std::wstring text) { this->text = text; cache.update(this->text, multiline, textWrap); - if (cache.font) { + if (cache.font && autoresize) { setSize(calcSize()); } } From c9fb33132f9fe3e0dedf362fa351098bc9d5c5e4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 30 May 2024 16:02:01 +0300 Subject: [PATCH 33/97] weather is saving now --- src/frontend/debug_panel.cpp | 4 ++-- src/graphics/render/WorldRenderer.cpp | 7 +++---- src/graphics/render/WorldRenderer.hpp | 2 -- src/world/World.cpp | 14 +++++++++----- src/world/World.hpp | 3 +++ 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 014af2f0..17213e4c 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -139,8 +139,8 @@ std::shared_ptr create_debug_panel( } { auto bar = std::make_shared(0.0f, 1.0f, 0.0f, 0.005f, 8); - bar->setSupplier([=]() {return WorldRenderer::fog;}); - bar->setConsumer([=](double val) {WorldRenderer::fog = val;}); + bar->setSupplier([=]() {return level->getWorld()->fog;}); + bar->setConsumer([=](double val) {level->getWorld()->fog = val;}); panel->add(bar); } { diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 6e5888ce..4c523e8c 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -274,11 +274,12 @@ void WorldRenderer::draw( bool hudVisible, PostProcessing* postProcessing ){ + auto world = level->getWorld(); const Viewport& vp = pctx.getViewport(); camera->aspect = vp.getWidth() / static_cast(vp.getHeight()); const EngineSettings& settings = engine->getSettings(); - skybox->refresh(pctx, level->getWorld()->daytime, 1.0f+fog*2.0f, 4); + skybox->refresh(pctx, world->daytime, 1.0f+world->fog*2.0f, 4); Assets* assets = engine->getAssets(); Shader* linesShader = assets->getShader("lines"); @@ -291,7 +292,7 @@ void WorldRenderer::draw( Window::clearDepth(); // Drawing background sky plane - skybox->draw(pctx, camera, assets, level->getWorld()->daytime, fog); + skybox->draw(pctx, camera, assets, world->daytime, world->fog); // Actually world render with depth buffer on { @@ -355,5 +356,3 @@ void WorldRenderer::drawBorders(int sx, int sy, int sz, int ex, int ey, int ez) } lineBatch->render(); } - -float WorldRenderer::fog = 0.0f; diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index b99be9ae..bb5e6c42 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -76,8 +76,6 @@ public: Camera* camera, const EngineSettings& settings ); - - static float fog; }; diff --git a/src/world/World.cpp b/src/world/World.cpp index a7bcab92..9770e504 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -194,19 +194,20 @@ void World::deserialize(dynamic::Map* root) { if (generator == "") { generator = WorldGenerators::getDefaultGeneratorID(); } - auto verobj = root->map("version"); - if (verobj) { + if (auto verobj = root->map("version")) { int major=0, minor=-1; verobj->num("major", major); verobj->num("minor", minor); - std::cout << "world version: " << major << "." << minor << std::endl; + logger.info() << "world version: " << major << "." << minor; } - auto timeobj = root->map("time"); - if (timeobj) { + if (auto timeobj = root->map("time")) { timeobj->num("day-time", daytime); timeobj->num("day-time-speed", daytimeSpeed); timeobj->num("total-time", totalTime); } + if (auto weatherobj = root->map("weather")) { + weatherobj->num("fog", fog); + } nextInventoryId = root->get("next-inventory-id", 2); } @@ -226,6 +227,9 @@ std::unique_ptr World::serialize() const { timeobj.put("day-time-speed", daytimeSpeed); timeobj.put("total-time", totalTime); + auto& weatherobj = root->putMap("weather"); + weatherobj.put("fog", fog); + root->put("next-inventory-id", nextInventoryId); return root; } diff --git a/src/world/World.hpp b/src/world/World.hpp index 7d9e9748..e720473c 100644 --- a/src/world/World.hpp +++ b/src/world/World.hpp @@ -49,6 +49,9 @@ public: /// @brief total time passed in the world (not depending on daytimeSpeed) double totalTime = 0.0; + /// @brief will be replaced with weather in future + float fog = 0.0f; + World( std::string name, std::string generator, From 29ca6e969c973bfe1fefccbc4149bcdb10ad8cc8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 30 May 2024 18:17:21 +0300 Subject: [PATCH 34/97] fix: block states cause crash for rotatable blocks --- src/graphics/render/WorldRenderer.cpp | 2 +- src/logic/PlayerController.cpp | 8 ++++---- src/logic/PlayerController.hpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 4c523e8c..77c348d5 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -199,7 +199,7 @@ void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) { const glm::vec3 norm = PlayerController::selectedBlockNormal; const std::vector& hitboxes = block->rotatable - ? block->rt.hitboxes[PlayerController::selectedBlockStates] + ? block->rt.hitboxes[PlayerController::selectedBlockRotation] : block->hitboxes; linesShader->use(); diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 44e73512..668edb4e 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -170,7 +170,7 @@ glm::vec3 PlayerController::selectedBlockPosition; glm::vec3 PlayerController::selectedPointPosition; glm::ivec3 PlayerController::selectedBlockNormal; int PlayerController::selectedBlockId = -1; -int PlayerController::selectedBlockStates = 0; +int PlayerController::selectedBlockRotation = 0; PlayerController::PlayerController( Level* level, @@ -250,7 +250,7 @@ void PlayerController::update(float delta, bool input, bool pause) { updateInteraction(); } else { selectedBlockId = -1; - selectedBlockStates = 0; + selectedBlockRotation = 0; } } @@ -365,7 +365,7 @@ void PlayerController::updateInteraction(){ if (vox != nullptr){ player->selectedVoxel = *vox; selectedBlockId = vox->id; - selectedBlockStates = vox->states; + selectedBlockRotation = vox->rotation(); selectedBlockPosition = iend; selectedPointPosition = end; selectedBlockNormal = norm; @@ -442,7 +442,7 @@ void PlayerController::updateInteraction(){ } } else { selectedBlockId = -1; - selectedBlockStates = 0; + selectedBlockRotation = 0; } if (rclick) { if (item->rt.funcsset.on_use) { diff --git a/src/logic/PlayerController.hpp b/src/logic/PlayerController.hpp index d48a3a51..210ca2c3 100644 --- a/src/logic/PlayerController.hpp +++ b/src/logic/PlayerController.hpp @@ -81,7 +81,7 @@ public: static glm::ivec3 selectedBlockNormal; static glm::vec3 selectedPointPosition; static int selectedBlockId; - static int selectedBlockStates; + static int selectedBlockRotation; PlayerController( Level* level, From 74042b5c2a291ae7dd4d273ebbfc4d45bceb9646 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 08:33:37 +0300 Subject: [PATCH 35/97] player.get_selected_block --- src/coders/toml.hpp | 2 -- src/content/ContentPack.hpp | 4 ++-- src/debug/Logger.cpp | 2 +- src/files/files.hpp | 2 +- src/frontend/debug_panel.cpp | 8 ++++++-- src/graphics/core/Texture.hpp | 1 - src/graphics/render/WorldRenderer.cpp | 4 ++-- src/logic/PlayerController.cpp | 6 +++--- src/logic/PlayerController.hpp | 1 - src/logic/scripting/lua/libplayer.cpp | 15 +++++++++++++++ src/objects/Player.hpp | 1 + src/settings.hpp | 2 +- src/world/World.cpp | 2 -- 13 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/coders/toml.hpp b/src/coders/toml.hpp index d658eb20..e695a298 100644 --- a/src/coders/toml.hpp +++ b/src/coders/toml.hpp @@ -2,8 +2,6 @@ #define CODERS_TOML_HPP_ #include "../data/dynamic.hpp" -#include "commons.hpp" - #include class SettingsHandler; diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index e58fbd84..7ff4b972 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -25,11 +25,11 @@ public: enum class DependencyLevel { required, // dependency must be installed optional, // dependency will be installed if found - weak, // dependency will not be installed automatically + weak, // only affects packs order }; -/// @brief Content-pack that should be installed before the dependent +/// @brief Content-pack that should be installed earlier the dependent struct DependencyPack { DependencyLevel level; std::string id; diff --git a/src/debug/Logger.cpp b/src/debug/Logger.cpp index 75582642..1649b9a0 100644 --- a/src/debug/Logger.cpp +++ b/src/debug/Logger.cpp @@ -44,7 +44,7 @@ void Logger::log(LogLevel level, const std::string& name, std::string message) { auto ms = duration_cast(system_clock::now().time_since_epoch()) % 1000; ss << " " << std::put_time(std::localtime(&tm), "%Y/%m/%d %T"); ss << '.' << std::setfill('0') << std::setw(3) << ms.count(); - ss << utcOffset << " (" << std::setfill(' ') << std::setw(moduleLen) << name << ") "; + ss << utcOffset << " [" << std::setfill(' ') << std::setw(moduleLen) << name << "] "; ss << message; { std::lock_guard lock(mutex); diff --git a/src/files/files.hpp b/src/files/files.hpp index 560d5e1f..142deb25 100644 --- a/src/files/files.hpp +++ b/src/files/files.hpp @@ -20,7 +20,7 @@ namespace files { std::ifstream file; size_t filelength; public: - rafile(std::filesystem::path filename); + rafile(fs::path filename); void seekg(std::streampos pos); void read(char* buffer, std::streamsize size); diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 17213e4c..c281903c 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -79,8 +79,12 @@ std::shared_ptr create_debug_panel( if (def) { stream << L" (" << util::str2wstr_utf8(def->name) << L")"; } - return L"block: "+std::to_wstring(player->selectedVoxel.id)+ - L" "+stream.str(); + if (player->selectedVoxel.id == BLOCK_VOID) { + return std::wstring {L"block: none"}; + } else { + return L"block: "+std::to_wstring(player->selectedVoxel.id)+ + L" "+stream.str(); + } })); panel->add(create_label([=](){ return L"seed: "+std::to_wstring(level->getWorld()->getSeed()); diff --git a/src/graphics/core/Texture.hpp b/src/graphics/core/Texture.hpp index b5d28617..c95bab27 100644 --- a/src/graphics/core/Texture.hpp +++ b/src/graphics/core/Texture.hpp @@ -4,7 +4,6 @@ #include "../../typedefs.hpp" #include "ImageData.hpp" -#include #include class Texture { diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 77c348d5..d52b0be4 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -194,7 +194,7 @@ void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) { auto indices = level->content->getIndices(); blockid_t id = PlayerController::selectedBlockId; auto block = indices->getBlockDef(id); - const glm::vec3 pos = PlayerController::selectedBlockPosition; + const glm::ivec3 pos = player->selectedBlockPosition; const glm::vec3 point = PlayerController::selectedPointPosition; const glm::vec3 norm = PlayerController::selectedBlockNormal; @@ -206,7 +206,7 @@ void WorldRenderer::renderBlockSelection(Camera* camera, Shader* linesShader) { linesShader->uniformMatrix("u_projview", camera->getProjView()); lineBatch->lineWidth(2.0f); for (auto& hitbox: hitboxes) { - const glm::vec3 center = pos + hitbox.center(); + const glm::vec3 center = glm::vec3(pos) + hitbox.center(); const glm::vec3 size = hitbox.size(); lineBatch->box(center, size + glm::vec3(0.02), glm::vec4(0.f, 0.f, 0.f, 0.5f)); if (player->debug) { diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 668edb4e..06f884aa 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -166,7 +166,6 @@ void CameraControl::update(const PlayerInput& input, float delta, Chunks* chunks } } -glm::vec3 PlayerController::selectedBlockPosition; glm::vec3 PlayerController::selectedPointPosition; glm::ivec3 PlayerController::selectedBlockNormal; int PlayerController::selectedBlockId = -1; @@ -362,11 +361,11 @@ void PlayerController::updateInteraction(){ maxDistance, end, norm, iend ); - if (vox != nullptr){ + if (vox != nullptr) { player->selectedVoxel = *vox; selectedBlockId = vox->id; selectedBlockRotation = vox->rotation(); - selectedBlockPosition = iend; + player->selectedBlockPosition = iend; selectedPointPosition = end; selectedBlockNormal = norm; int x = iend.x; @@ -443,6 +442,7 @@ void PlayerController::updateInteraction(){ } else { selectedBlockId = -1; selectedBlockRotation = 0; + player->selectedVoxel.id = BLOCK_VOID; } if (rclick) { if (item->rt.funcsset.on_use) { diff --git a/src/logic/PlayerController.hpp b/src/logic/PlayerController.hpp index 210ca2c3..46e5cbca 100644 --- a/src/logic/PlayerController.hpp +++ b/src/logic/PlayerController.hpp @@ -77,7 +77,6 @@ class PlayerController { void onFootstep(); void updateFootsteps(float delta); public: - static glm::vec3 selectedBlockPosition; static glm::ivec3 selectedBlockNormal; static glm::vec3 selectedPointPosition; static int selectedBlockId; diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp index 3ce71759..045aae37 100644 --- a/src/logic/scripting/lua/libplayer.cpp +++ b/src/logic/scripting/lua/libplayer.cpp @@ -132,6 +132,20 @@ static int l_player_set_noclip(lua_State* L) { return 0; } +static int l_player_get_selected_block(lua_State* L) { + if (auto player = get_player(L, 1)) { + if (player->selectedVoxel.id == BLOCK_VOID) { + return 0; + } + const glm::ivec3 pos = player->selectedBlockPosition; + lua_pushinteger(L, pos.x); + lua_pushinteger(L, pos.y); + lua_pushinteger(L, pos.z); + return 3; + } + return 0; +} + const luaL_Reg playerlib [] = { {"get_pos", lua_wrap_errors}, {"set_pos", lua_wrap_errors}, @@ -144,5 +158,6 @@ const luaL_Reg playerlib [] = { {"set_flight", lua_wrap_errors}, {"is_noclip", lua_wrap_errors}, {"set_noclip", lua_wrap_errors}, + {"get_selected_block", lua_wrap_errors}, {NULL, NULL} }; diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index 3dd9e4be..3d9e8fd6 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -46,6 +46,7 @@ public: bool debug = false; voxel selectedVoxel {0, 0}; glm::vec3 cam {}; + glm::ivec3 selectedBlockPosition {}; Player(glm::vec3 position, float speed, std::shared_ptr inv); ~Player(); diff --git a/src/settings.hpp b/src/settings.hpp index 165dcbec..250d0e4b 100644 --- a/src/settings.hpp +++ b/src/settings.hpp @@ -57,7 +57,7 @@ struct GraphicsSettings { /// 1.0 is linear, 2.0 is quadratic NumberSetting fogCurve {1.6f, 1.0f, 6.0f}; /// @brief Lighting gamma - NumberSetting gamma {1.0f, 0.5f, 2.0f}; + NumberSetting gamma {1.0f, 0.4f, 1.0f}; /// @brief Enable blocks backlight to prevent complete darkness FlagSetting backlight {true}; /// @brief Enable chunks frustum culling diff --git a/src/world/World.cpp b/src/world/World.cpp index 9770e504..fdd60446 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -12,7 +12,6 @@ #include "../voxels/Chunk.hpp" #include "../voxels/Chunks.hpp" #include "../voxels/ChunksStorage.hpp" -#include "../window/Camera.hpp" #include "../world/WorldGenerators.hpp" #include @@ -135,7 +134,6 @@ std::unique_ptr World::load( } } } - (void)world.release(); return level; } From 5dd06b233efba08622f9dcf541dbc55255ed0792 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 08:46:05 +0300 Subject: [PATCH 36/97] u_timer in the main shader --- src/graphics/render/WorldRenderer.cpp | 4 ++++ src/graphics/render/WorldRenderer.hpp | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index d52b0be4..ad7030a2 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -37,6 +37,9 @@ #include #include +#include +#include + bool WorldRenderer::showChunkBorders = false; WorldRenderer::WorldRenderer(Engine* engine, LevelFrontend* frontend, Player* player) @@ -160,6 +163,7 @@ void WorldRenderer::renderLevel( shader->use(); shader->uniformMatrix("u_proj", camera->getProjection()); shader->uniformMatrix("u_view", camera->getView()); + shader->uniform1f("u_timer", Window::time()); shader->uniform1f("u_gamma", settings.graphics.gamma.get()); shader->uniform1f("u_fogFactor", fogFactor); shader->uniform1f("u_fogCurve", settings.graphics.fogCurve.get()); diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index bb5e6c42..27d1a569 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -8,8 +8,6 @@ #include #include -#include -#include class Level; class Player; From 6d933ac263c88f8afecb16422ee791af68d68163 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 11:13:36 +0300 Subject: [PATCH 37/97] converting block states to a bitfield --- src/frontend/debug_panel.cpp | 5 +- src/graphics/render/BlocksRenderer.cpp | 31 ++++---- src/graphics/render/BlocksRenderer.hpp | 37 +++++++--- src/logic/BlocksController.cpp | 2 +- src/logic/PlayerController.cpp | 11 +-- src/logic/scripting/lua/libblock.cpp | 24 +++---- src/objects/Player.hpp | 2 +- src/physics/PhysicsSolver.cpp | 6 +- src/physics/PhysicsSolver.hpp | 3 +- src/voxel_engine.cpp | 2 - src/voxels/Chunk.cpp | 98 +++++++++++++------------- src/voxels/Chunk.hpp | 76 ++++++++++---------- src/voxels/Chunks.cpp | 10 +-- src/voxels/Chunks.hpp | 5 +- src/voxels/DefaultWorldGenerator.cpp | 8 +-- src/voxels/FlatWorldGenerator.cpp | 4 +- src/voxels/voxel.hpp | 37 ++++++---- 17 files changed, 197 insertions(+), 164 deletions(-) diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index c281903c..106f8322 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -20,6 +20,7 @@ #include #include #include +#include using namespace gui; @@ -75,7 +76,9 @@ std::shared_ptr create_debug_panel( auto* indices = level->content->getIndices(); auto def = indices->getBlockDef(player->selectedVoxel.id); std::wstringstream stream; - stream << std::hex << player->selectedVoxel.states; + stream << "r:" << player->selectedVoxel.state.rotation << " s:" + << player->selectedVoxel.state.segment << " u:" + << std::bitset<8>(player->selectedVoxel.state.userbits); if (def) { stream << L" (" << util::str2wstr_utf8(def->name) << L")"; } diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index 4b1779d4..9420d070 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -219,10 +219,13 @@ void BlocksRenderer::blockXSprite(int x, int y, int z, // HINT: texture faces order: {east, west, bottom, top, south, north} /* AABB blocks render method */ -void BlocksRenderer::blockAABB(const ivec3& icoord, - const UVRegion(&texfaces)[6], - const Block* block, ubyte rotation, - bool lights) { +void BlocksRenderer::blockAABB( + const ivec3& icoord, + const UVRegion(&texfaces)[6], + const Block* block, + ubyte rotation, + bool lights +) { if (block->hitboxes.empty()) { return; } @@ -301,11 +304,13 @@ void BlocksRenderer::blockCustomModel(const ivec3& icoord, } /* Fastest solid shaded blocks render method */ -void BlocksRenderer::blockCube(int x, int y, int z, - const UVRegion(&texfaces)[6], - const Block* block, - ubyte states, - bool lights) { +void BlocksRenderer::blockCube( + int x, int y, int z, + const UVRegion(&texfaces)[6], + const Block* block, + blockstate states, + bool lights +) { ubyte group = block->drawGroup; vec3 X(1, 0, 0); @@ -314,7 +319,7 @@ void BlocksRenderer::blockCube(int x, int y, int z, vec3 coord(x, y, z); if (block->rotatable) { auto& rotations = block->rotations; - auto& orient = rotations.variants[states & BLOCK_ROT_MASK]; + auto& orient = rotations.variants[states.rotation]; X = orient.axisX; Y = orient.axisY; Z = orient.axisZ; @@ -423,7 +428,7 @@ void BlocksRenderer::render(const voxel* voxels) { int z = (i / CHUNK_D) % CHUNK_W; switch (def.model) { case BlockModel::block: - blockCube(x, y, z, texfaces, &def, vox.states, !def.rt.emissive); + blockCube(x, y, z, texfaces, &def, vox.state, !def.rt.emissive); break; case BlockModel::xsprite: { blockXSprite(x, y, z, vec3(1.0f), @@ -431,11 +436,11 @@ void BlocksRenderer::render(const voxel* voxels) { break; } case BlockModel::aabb: { - blockAABB(ivec3(x,y,z), texfaces, &def, vox.rotation(), !def.rt.emissive); + blockAABB(ivec3(x,y,z), texfaces, &def, vox.state.rotation, !def.rt.emissive); break; } case BlockModel::custom: { - blockCustomModel(ivec3(x, y, z), &def, vox.rotation(), !def.rt.emissive); + blockCustomModel(ivec3(x, y, z), &def, vox.state.rotation, !def.rt.emissive); break; } default: diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index 23b6d625..244d4674 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -70,16 +70,33 @@ class BlocksRenderer { const UVRegion& texreg, bool lights); - void blockCube(int x, int y, int z, const UVRegion(&faces)[6], const Block* block, ubyte states, bool lights); - void blockAABB(const glm::ivec3& coord, - const UVRegion(&faces)[6], - const Block* block, - ubyte rotation, - bool lights); - void blockXSprite(int x, int y, int z, const glm::vec3& size, const UVRegion& face1, const UVRegion& face2, float spread); - void blockCustomModel(const glm::ivec3& icoord, - const Block* block, ubyte rotation, - bool lights); + void blockCube( + int x, int y, int z, + const UVRegion(&faces)[6], + const Block* block, + blockstate states, + bool lights + ); + void blockAABB( + const glm::ivec3& coord, + const UVRegion(&faces)[6], + const Block* block, + ubyte rotation, + bool lights + ); + void blockXSprite( + int x, int y, int z, + const glm::vec3& size, + const UVRegion& face1, + const UVRegion& face2, + float spread + ); + void blockCustomModel( + const glm::ivec3& icoord, + const Block* block, + ubyte rotation, + bool lights + ); bool isOpenForLight(int x, int y, int z) const; bool isOpen(int x, int y, int z, ubyte group) const; diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 6cbb4aba..8d1cbebb 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -71,7 +71,7 @@ void BlocksController::updateSides(int x, int y, int z) { } void BlocksController::breakBlock(Player* player, const Block* def, int x, int y, int z) { - chunks->set(x,y,z, 0, 0); + chunks->set(x,y,z, 0, {}); lighting->onBlockSet(x,y,z, 0); if (def->rt.funcsset.onbroken) { scripting::on_block_broken(player, def, x, y, z); diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 06f884aa..4547a4da 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -364,7 +364,7 @@ void PlayerController::updateInteraction(){ if (vox != nullptr) { player->selectedVoxel = *vox; selectedBlockId = vox->id; - selectedBlockRotation = vox->rotation(); + selectedBlockRotation = vox->state.rotation; player->selectedBlockPosition = iend; selectedPointPosition = end; selectedBlockNormal = norm; @@ -373,7 +373,8 @@ void PlayerController::updateInteraction(){ int z = iend.z; Block* def = indices->getBlockDef(item->rt.placingBlock); - uint8_t states = determine_rotation(def, norm, camera->dir); + blockstate state {}; + state.rotation = determine_rotation(def, norm, camera->dir); if (lclick && !input.shift && item->rt.funcsset.on_block_break_by) { if (scripting::on_item_break_block(player.get(), item, x, y, z)) @@ -410,13 +411,13 @@ void PlayerController::updateInteraction(){ z = (iend.z)+(norm.z); } else { if (def->rotations.name == "pipe") { - states = BLOCK_DIR_UP; + state.rotation = BLOCK_DIR_UP; } } vox = chunks->get(x, y, z); blockid_t chosenBlock = def->rt.id; if (vox && (target = indices->getBlockDef(vox->id))->replaceable) { - if (!level->physics->isBlockInside(x,y,z,def,states, player->hitbox.get()) + if (!level->physics->isBlockInside(x,y,z,def,state, player->hitbox.get()) || !def->obstacle){ if (def->grounded && !chunks->isSolidBlock(x, y-1, z)) { chosenBlock = 0; @@ -426,7 +427,7 @@ void PlayerController::updateInteraction(){ glm::ivec3(x, y, z), def, BlockInteraction::placing ); - chunks->set(x, y, z, chosenBlock, states); + chunks->set(x, y, z, chosenBlock, state); lighting->onBlockSet(x,y,z, chosenBlock); if (def->rt.funcsset.onplaced) { scripting::on_block_placed(player.get(), def, x, y, z); diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 695d8e36..a4380751 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -60,7 +60,7 @@ int l_set_block(lua_State* L) { lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_Integer id = lua_tointeger(L, 4); - lua_Integer states = lua_tointeger(L, 5); + lua_Integer state = lua_tointeger(L, 5); bool noupdate = lua_toboolean(L, 6); if (id < 0 || size_t(id) >= scripting::indices->countBlockDefs()) { return 0; @@ -68,7 +68,7 @@ int l_set_block(lua_State* L) { if (!scripting::level->chunks->get(x, y, z)) { return 0; } - scripting::level->chunks->set(x, y, z, id, states); + scripting::level->chunks->set(x, y, z, id, int2blockstate(state)); scripting::level->lighting->onBlockSet(x,y,z, id); if (!noupdate) scripting::blocks->updateSides(x, y, z); @@ -97,7 +97,7 @@ int l_get_block_x(lua_State* L) { if (!def->rotatable) { return lua::pushivec3(L, 1, 0, 0); } else { - const CoordSystem& rot = def->rotations.variants[vox->rotation()]; + const CoordSystem& rot = def->rotations.variants[vox->state.rotation]; return lua::pushivec3(L, rot.axisX.x, rot.axisX.y, rot.axisX.z); } } @@ -114,7 +114,7 @@ int l_get_block_y(lua_State* L) { if (!def->rotatable) { return lua::pushivec3(L, 0, 1, 0); } else { - const CoordSystem& rot = def->rotations.variants[vox->rotation()]; + const CoordSystem& rot = def->rotations.variants[vox->state.rotation]; return lua::pushivec3(L, rot.axisY.x, rot.axisY.y, rot.axisY.z); } } @@ -131,7 +131,7 @@ int l_get_block_z(lua_State* L) { if (!def->rotatable) { return lua::pushivec3(L, 0, 0, 1); } else { - const CoordSystem& rot = def->rotations.variants[vox->rotation()]; + const CoordSystem& rot = def->rotations.variants[vox->state.rotation]; return lua::pushivec3(L, rot.axisZ.x, rot.axisZ.y, rot.axisZ.z); } } @@ -141,7 +141,7 @@ int l_get_block_rotation(lua_State* L) { lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); - int rotation = vox == nullptr ? 0 : vox->rotation(); + int rotation = vox == nullptr ? 0 : vox->state.rotation; lua_pushinteger(L, rotation); return 1; } @@ -155,7 +155,7 @@ int l_set_block_rotation(lua_State* L) { if (vox == nullptr) { return 0; } - vox->setRotation(value); + vox->state.rotation = value; scripting::level->chunks->getChunkByVoxel(x, y, z)->setModified(true); return 0; } @@ -165,7 +165,7 @@ int l_get_block_states(lua_State* L) { lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); - int states = vox == nullptr ? 0 : vox->states; + int states = vox == nullptr ? 0 : blockstate2int(vox->state); lua_pushinteger(L, states); return 1; } @@ -181,7 +181,7 @@ int l_set_block_states(lua_State* L) { return 0; } voxel* vox = scripting::level->chunks->get(x, y, z); - vox->states = states; + vox->state = int2blockstate(states); chunk->setModified(true); return 0; } @@ -199,7 +199,7 @@ int l_get_block_user_bits(lua_State* L) { return 1; } uint mask = ((1 << bits) - 1) << offset; - uint data = (vox->states & mask) >> offset; + uint data = (blockstate2int(vox->state) & mask) >> offset; lua_pushinteger(L, data); return 1; } @@ -208,7 +208,7 @@ int l_set_block_user_bits(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); - lua_Integer offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; + lua_Integer offset = lua_tointeger(L, 4); lua_Integer bits = lua_tointeger(L, 5); size_t mask = ((1 << bits) - 1) << offset; @@ -218,7 +218,7 @@ int l_set_block_user_bits(lua_State* L) { if (vox == nullptr) { return 0; } - vox->states = (vox->states & (~mask)) | value; + vox->state.userbits = (vox->state.userbits & (~mask)) | value; return 0; } diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index 3d9e8fd6..0afeda5c 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -44,7 +44,7 @@ public: std::shared_ptr currentCamera; std::unique_ptr hitbox; bool debug = false; - voxel selectedVoxel {0, 0}; + voxel selectedVoxel {0, {}}; glm::vec3 cam {}; glm::ivec3 selectedBlockPosition {}; diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index 6760aa89..f3c5963a 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -219,13 +219,11 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) { y >= floor(pos.y-half.y) && y <= floor(pos.y+half.y); } -bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate_t states, Hitbox* hitbox) { +bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate state, Hitbox* hitbox) { const glm::vec3& pos = hitbox->position; const glm::vec3& half = hitbox->halfsize; - voxel v {}; - v.states = states; const auto& boxes = def->rotatable - ? def->rt.hitboxes[v.rotation()] + ? def->rt.hitboxes[state.rotation] : def->hitboxes; for (const auto& block_hitbox : boxes) { glm::vec3 min = block_hitbox.min(); diff --git a/src/physics/PhysicsSolver.hpp b/src/physics/PhysicsSolver.hpp index e35f364c..6e940f99 100644 --- a/src/physics/PhysicsSolver.hpp +++ b/src/physics/PhysicsSolver.hpp @@ -2,6 +2,7 @@ #define PHYSICS_PHYSICSSOLVER_HPP_ #include "../typedefs.hpp" +#include "../voxels/voxel.hpp" #include @@ -31,7 +32,7 @@ public: float stepHeight ); bool isBlockInside(int x, int y, int z, Hitbox* hitbox); - bool isBlockInside(int x, int y, int z, Block* def, blockstate_t states, Hitbox* hitbox); + bool isBlockInside(int x, int y, int z, Block* def, blockstate state, Hitbox* hitbox); }; #endif // PHYSICS_PHYSICSSOLVER_HPP_ diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index 33d18c0e..c6a2ec7e 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -5,7 +5,6 @@ #include "util/platform.hpp" #include "util/command_line.hpp" #include "debug/Logger.hpp" -#include "objects/Player.hpp" #include @@ -13,7 +12,6 @@ static debug::Logger logger("main"); int main(int argc, char** argv) { debug::Logger::init("latest.log"); - std::cout << sizeof(PlayerInput) << std::endl; EnginePaths paths; if (!parse_cmdline(argc, argv, paths)) diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index bfd79cda..94100e16 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -7,40 +7,36 @@ #include "../lighting/Lightmap.hpp" Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos){ - bottom = 0; - top = CHUNK_H; - for (uint i = 0; i < CHUNK_VOL; i++) { - voxels[i].id = 2; - voxels[i].states = 0; - } + bottom = 0; + top = CHUNK_H; } bool Chunk::isEmpty(){ - int id = -1; - for (uint i = 0; i < CHUNK_VOL; i++){ - if (voxels[i].id != id){ - if (id != -1) - return false; - else - id = voxels[i].id; - } - } - return true; + int id = -1; + for (uint i = 0; i < CHUNK_VOL; i++){ + if (voxels[i].id != id){ + if (id != -1) + return false; + else + id = voxels[i].id; + } + } + return true; } void Chunk::updateHeights() { - for (uint i = 0; i < CHUNK_VOL; i++) { - if (voxels[i].id != 0) { - bottom = i / (CHUNK_D * CHUNK_W); - break; - } - } - for (int i = CHUNK_VOL - 1; i >= 0; i--) { - if (voxels[i].id != 0) { - top = i / (CHUNK_D * CHUNK_W) + 1; - break; - } - } + for (uint i = 0; i < CHUNK_VOL; i++) { + if (voxels[i].id != 0) { + bottom = i / (CHUNK_D * CHUNK_W); + break; + } + } + for (int i = CHUNK_VOL - 1; i >= 0; i--) { + if (voxels[i].id != 0) { + top = i / (CHUNK_D * CHUNK_W) + 1; + break; + } + } } void Chunk::addBlockInventory(std::shared_ptr inventory, @@ -50,13 +46,13 @@ void Chunk::addBlockInventory(std::shared_ptr inventory, } void Chunk::removeBlockInventory(uint x, uint y, uint z) { - if (inventories.erase(vox_index(x, y, z))) { - setUnsaved(true); - } + if (inventories.erase(vox_index(x, y, z))) { + setUnsaved(true); + } } void Chunk::setBlockInventories(chunk_inventories_map map) { - inventories = map; + inventories = map; } std::shared_ptr Chunk::getBlockInventory(uint x, uint y, uint z) const { @@ -70,12 +66,12 @@ std::shared_ptr Chunk::getBlockInventory(uint x, uint y, uint z) cons } std::unique_ptr Chunk::clone() const { - auto other = std::make_unique(x,z); - for (uint i = 0; i < CHUNK_VOL; i++) { - other->voxels[i] = voxels[i]; + auto other = std::make_unique(x,z); + for (uint i = 0; i < CHUNK_VOL; i++) { + other->voxels[i] = voxels[i]; } - other->lightmap.set(&lightmap); - return other; + other->lightmap.set(&lightmap); + return other; } /** @@ -93,19 +89,21 @@ std::unique_ptr Chunk::clone() const { Total size: (CHUNK_VOL * 4) bytes */ std::unique_ptr Chunk::encode() const { - auto buffer = std::make_unique(CHUNK_DATA_LEN); - for (uint i = 0; i < CHUNK_VOL; i++) { - buffer[i] = voxels[i].id >> 8; + auto buffer = std::make_unique(CHUNK_DATA_LEN); + for (uint i = 0; i < CHUNK_VOL; i++) { + buffer[i] = voxels[i].id >> 8; buffer[CHUNK_VOL+i] = voxels[i].id & 0xFF; - buffer[CHUNK_VOL*2 + i] = voxels[i].states >> 8; - buffer[CHUNK_VOL*3 + i] = voxels[i].states & 0xFF; - } - return buffer; + + blockstate_t state = blockstate2int(voxels[i].state); + buffer[CHUNK_VOL*2 + i] = state >> 8; + buffer[CHUNK_VOL*3 + i] = state & 0xFF; + } + return buffer; } bool Chunk::decode(const ubyte* data) { - for (uint i = 0; i < CHUNK_VOL; i++) { - voxel& vox = voxels[i]; + for (uint i = 0; i < CHUNK_VOL; i++) { + voxel& vox = voxels[i]; ubyte bid1 = data[i]; ubyte bid2 = data[CHUNK_VOL + i]; @@ -113,10 +111,10 @@ bool Chunk::decode(const ubyte* data) { ubyte bst1 = data[CHUNK_VOL*2 + i]; ubyte bst2 = data[CHUNK_VOL*3 + i]; - vox.id = (blockid_t(bid1) << 8) | (blockid_t(bid2)); - vox.states = (blockstate_t(bst1) << 8) | (blockstate_t(bst2)); - } - return true; + vox.id = (blockid_t(bid1) << 8) | (blockid_t(bid2)); + vox.state = int2blockstate((blockstate_t(bst1) << 8) | (blockstate_t(bst2))); + } + return true; } void Chunk::convert(ubyte* data, const ContentLUT* lut) { diff --git a/src/voxels/Chunk.hpp b/src/voxels/Chunk.hpp index 019b4f09..0cab4025 100644 --- a/src/voxels/Chunk.hpp +++ b/src/voxels/Chunk.hpp @@ -10,12 +10,12 @@ #include "../lighting/Lightmap.hpp" struct ChunkFlag { - static const int MODIFIED = 0x1; - static const int READY = 0x2; - static const int LOADED = 0x4; - static const int LIGHTED = 0x8; - static const int UNSAVED = 0x10; - static const int LOADED_LIGHTS = 0x20; + static const int MODIFIED = 0x1; + static const int READY = 0x2; + static const int LOADED = 0x4; + static const int LIGHTED = 0x8; + static const int UNSAVED = 0x10; + static const int LOADED_LIGHTS = 0x20; }; inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4; @@ -27,72 +27,72 @@ using chunk_inventories_map = std::unordered_map clone() const; + std::unique_ptr clone() const; - // flags getters/setters below - inline void setFlags(int mask, bool value){ - if (value) - flags |= mask; - else - flags &= ~(mask); - } + // flags getters/setters below + inline void setFlags(int mask, bool value){ + if (value) + flags |= mask; + else + flags &= ~(mask); + } /* Creates new block inventory given size @return inventory id or 0 if block does not exists */ void addBlockInventory(std::shared_ptr inventory, uint x, uint y, uint z); - void removeBlockInventory(uint x, uint y, uint z); - void setBlockInventories(chunk_inventories_map map); + void removeBlockInventory(uint x, uint y, uint z); + void setBlockInventories(chunk_inventories_map map); /* @return inventory bound to the given block or nullptr */ std::shared_ptr getBlockInventory(uint x, uint y, uint z) const; - inline bool isUnsaved() const {return flags & ChunkFlag::UNSAVED;} + inline bool isUnsaved() const {return flags & ChunkFlag::UNSAVED;} - inline bool isModified() const {return flags & ChunkFlag::MODIFIED;} + inline bool isModified() const {return flags & ChunkFlag::MODIFIED;} - inline bool isLighted() const {return flags & ChunkFlag::LIGHTED;} + inline bool isLighted() const {return flags & ChunkFlag::LIGHTED;} - inline bool isLoaded() const {return flags & ChunkFlag::LOADED;} + inline bool isLoaded() const {return flags & ChunkFlag::LOADED;} - inline bool isLoadedLights() const {return flags & ChunkFlag::LOADED_LIGHTS;} + inline bool isLoadedLights() const {return flags & ChunkFlag::LOADED_LIGHTS;} - inline bool isReady() const {return flags & ChunkFlag::READY;} + inline bool isReady() const {return flags & ChunkFlag::READY;} - inline void setUnsaved(bool newState) {setFlags(ChunkFlag::UNSAVED, newState);} + inline void setUnsaved(bool newState) {setFlags(ChunkFlag::UNSAVED, newState);} - inline void setModified(bool newState) {setFlags(ChunkFlag::MODIFIED, newState);} + inline void setModified(bool newState) {setFlags(ChunkFlag::MODIFIED, newState);} - inline void setLoaded(bool newState) {setFlags(ChunkFlag::LOADED, newState);} + inline void setLoaded(bool newState) {setFlags(ChunkFlag::LOADED, newState);} - inline void setLoadedLights(bool newState) {setFlags(ChunkFlag::LOADED_LIGHTS, newState);} + inline void setLoadedLights(bool newState) {setFlags(ChunkFlag::LOADED_LIGHTS, newState);} - inline void setLighted(bool newState) {setFlags(ChunkFlag::LIGHTED, newState);} + inline void setLighted(bool newState) {setFlags(ChunkFlag::LIGHTED, newState);} - inline void setReady(bool newState) {setFlags(ChunkFlag::READY, newState);} + inline void setReady(bool newState) {setFlags(ChunkFlag::READY, newState);} - std::unique_ptr encode() const; + std::unique_ptr encode() const; /** * @return true if all is fine **/ - bool decode(const ubyte* data); + bool decode(const ubyte* data); static void convert(ubyte* data, const ContentLUT* lut); }; diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 63919499..2504e0b1 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -68,7 +68,7 @@ const AABB* Chunks::isObstacleAt(float x, float y, float z){ const Block* def = contentIds->getBlockDef(v->id); if (def->obstacle) { const auto& boxes = def->rotatable - ? def->rt.hitboxes[v->rotation()] + ? def->rt.hitboxes[v->state.rotation] : def->hitboxes; for (const auto& hitbox : boxes) { if (hitbox.contains({x - ix, y - iy, z - iz})) { @@ -158,7 +158,7 @@ Chunk* Chunks::getChunk(int x, int z){ return chunks[z * w + x].get(); } -void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, uint8_t states) { +void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state) { if (y < 0 || y >= CHUNK_H) return; x -= ox * CHUNK_W; @@ -178,7 +178,7 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, uint8_t states) { if (def->inventorySize == 0) chunk->removeBlockInventory(lx, y, lz); vox.id = id; - vox.states = states; + vox.state = state; chunk->setUnsaved(true); chunk->setModified(true); @@ -255,7 +255,7 @@ voxel* Chunks::rayCast( if (!def->rt.solid) { const std::vector& hitboxes = def->rotatable - ? def->rt.hitboxes[voxel->rotation()] + ? def->rt.hitboxes[voxel->state.rotation] : def->hitboxes; scalar_t distance = maxDist; @@ -365,7 +365,7 @@ glm::vec3 Chunks::rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDis if (def->obstacle) { if (!def->rt.solid) { const std::vector& hitboxes = def->rotatable - ? def->rt.hitboxes[voxel->rotation()] + ? def->rt.hitboxes[voxel->state.rotation] : def->modelBoxes; scalar_t distance; diff --git a/src/voxels/Chunks.hpp b/src/voxels/Chunks.hpp index d2eb8cea..7dd4312d 100644 --- a/src/voxels/Chunks.hpp +++ b/src/voxels/Chunks.hpp @@ -5,6 +5,8 @@ #include #include #include + +#include "voxel.hpp" #include "../typedefs.hpp" class VoxelRenderer; @@ -13,7 +15,6 @@ struct AABB; class Content; class ContentIndices; class Chunk; -struct voxel; class WorldFiles; class LevelEvents; @@ -42,7 +43,7 @@ public: voxel* get(int32_t x, int32_t y, int32_t z); light_t getLight(int32_t x, int32_t y, int32_t z); ubyte getLight(int32_t x, int32_t y, int32_t z, int channel); - void set(int32_t x, int32_t y, int32_t z, uint32_t id, uint8_t states); + void set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state); voxel* rayCast( glm::vec3 start, diff --git a/src/voxels/DefaultWorldGenerator.cpp b/src/voxels/DefaultWorldGenerator.cpp index b0c8561b..49747519 100644 --- a/src/voxels/DefaultWorldGenerator.cpp +++ b/src/voxels/DefaultWorldGenerator.cpp @@ -163,7 +163,7 @@ void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){ for (int cur_y = 0; cur_y < CHUNK_H; cur_y++){ // int cur_y = y; int id = cur_y < SEA_LEVEL ? idWater : BLOCK_AIR; - int states = 0; + blockstate state {}; if ((cur_y == (int)height) && (SEA_LEVEL-2 < cur_y)) { id = idGrassBlock; } else if (cur_y < (height - 6)){ @@ -177,7 +177,7 @@ void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){ treesTile, idWood, idLeaves); if (tree) { id = tree; - states = BLOCK_DIR_UP; + state.rotation = BLOCK_DIR_UP; } } float sand = fmax(heights.get(MAPS::SAND, cur_x, cur_z), heights.get(MAPS::CLIFF, cur_x, cur_z)); @@ -198,10 +198,10 @@ void DefaultWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed){ } if ((height > SEA_LEVEL+1) && ((int)(height + 1) == cur_y) && ((unsigned short)randomgrass.rand() > 65533)){ id = idWood; - states = BLOCK_DIR_UP; + state.rotation = BLOCK_DIR_UP; } voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].id = id; - voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].states = states; + voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].state = state; } } } diff --git a/src/voxels/FlatWorldGenerator.cpp b/src/voxels/FlatWorldGenerator.cpp index 8e5c440e..f729d32b 100644 --- a/src/voxels/FlatWorldGenerator.cpp +++ b/src/voxels/FlatWorldGenerator.cpp @@ -10,7 +10,7 @@ void FlatWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed) { for (int x = 0; x < CHUNK_W; x++) { for (int cur_y = 0; cur_y < CHUNK_H; cur_y++){ int id = BLOCK_AIR; - int states = 0; + blockstate state {}; if(cur_y == 2) { id = idBazalt; @@ -21,7 +21,7 @@ void FlatWorldGenerator::generate(voxel* voxels, int cx, int cz, int seed) { } voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].id = id; - voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].states = states; + voxels[(cur_y * CHUNK_D + z) * CHUNK_W + x].state = state; } } } diff --git a/src/voxels/voxel.hpp b/src/voxels/voxel.hpp index db2c8138..03647727 100644 --- a/src/voxels/voxel.hpp +++ b/src/voxels/voxel.hpp @@ -10,22 +10,33 @@ inline constexpr int BLOCK_DIR_EAST = 0x3; inline constexpr int BLOCK_DIR_UP = 0x4; inline constexpr int BLOCK_DIR_DOWN = 0x5; -// limited to 8 block orientations -inline constexpr int BLOCK_ROT_MASK = 0b0000'0111; -// reserved bits -inline constexpr int BLOCK_RESERVED_MASK = 0b1111'1000; +struct blockstate { + uint8_t rotation : 3; + uint8_t segment : 2; + uint8_t reserved : 3; + uint8_t userbits : 8; +}; +static_assert (sizeof(blockstate) == 2); + +inline constexpr blockstate_t blockstate2int(blockstate b) { + return b.rotation | + (b.segment << 3) | + (b.reserved << 5) | + (b.userbits << 8); +} + +inline constexpr blockstate int2blockstate(blockstate_t i) { + return { + static_cast(i & 0b111), + static_cast((i >> 3) & 0b11), + static_cast((i >> 5) & 0b111), + static_cast((i >> 8) & 0xFF) + }; +} struct voxel { blockid_t id; - blockstate_t states; - - inline uint8_t rotation() const { - return states & BLOCK_ROT_MASK; - } - - inline void setRotation(uint8_t rotation) { - states = (states & (~BLOCK_ROT_MASK)) | (rotation & BLOCK_ROT_MASK); - } + blockstate state; }; #endif // VOXELS_VOXEL_HPP_ From 86dd6562de4f621ed5671a8a2859ce7e8a647fb2 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 11:26:16 +0300 Subject: [PATCH 38/97] fix: user bits and manually set rotation not saving --- src/logic/scripting/lua/libblock.cpp | 11 ++++++++--- src/voxels/Chunk.hpp | 5 +++++ src/voxels/Chunks.cpp | 4 +--- src/voxels/voxel.hpp | 8 ++++---- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index a4380751..0bc509fc 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -156,7 +156,7 @@ int l_set_block_rotation(lua_State* L) { return 0; } vox->state.rotation = value; - scripting::level->chunks->getChunkByVoxel(x, y, z)->setModified(true); + scripting::level->chunks->getChunkByVoxel(x, y, z)->setModifiedAndUnsaved(); return 0; } @@ -182,7 +182,7 @@ int l_set_block_states(lua_State* L) { } voxel* vox = scripting::level->chunks->get(x, y, z); vox->state = int2blockstate(states); - chunk->setModified(true); + chunk->setModifiedAndUnsaved(); return 0; } @@ -214,12 +214,17 @@ int l_set_block_user_bits(lua_State* L) { size_t mask = ((1 << bits) - 1) << offset; lua_Integer value = (lua_tointeger(L, 6) << offset) & mask; + Chunk* chunk = scripting::level->chunks->getChunkByVoxel(x, y, z); + if (chunk == nullptr) { + return 0; + } voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return 0; } vox->state.userbits = (vox->state.userbits & (~mask)) | value; - return 0; + chunk->setModifiedAndUnsaved(); + return 0; } int l_is_replaceable_at(lua_State* L) { diff --git a/src/voxels/Chunk.hpp b/src/voxels/Chunk.hpp index 0cab4025..29b4916c 100644 --- a/src/voxels/Chunk.hpp +++ b/src/voxels/Chunk.hpp @@ -79,6 +79,11 @@ public: inline void setModified(bool newState) {setFlags(ChunkFlag::MODIFIED, newState);} + inline void setModifiedAndUnsaved() { + setModified(true); + setUnsaved(true); + } + inline void setLoaded(bool newState) {setFlags(ChunkFlag::LOADED, newState);} inline void setLoadedLights(bool newState) {setFlags(ChunkFlag::LOADED_LIGHTS, newState);} diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 2504e0b1..9b1dbc73 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -179,9 +179,7 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state) chunk->removeBlockInventory(lx, y, lz); vox.id = id; vox.state = state; - - chunk->setUnsaved(true); - chunk->setModified(true); + chunk->setModifiedAndUnsaved(); if (y < chunk->bottom) chunk->bottom = y; else if (y + 1 > chunk->top) chunk->top = y + 1; diff --git a/src/voxels/voxel.hpp b/src/voxels/voxel.hpp index 03647727..d7062b36 100644 --- a/src/voxels/voxel.hpp +++ b/src/voxels/voxel.hpp @@ -19,10 +19,10 @@ struct blockstate { static_assert (sizeof(blockstate) == 2); inline constexpr blockstate_t blockstate2int(blockstate b) { - return b.rotation | - (b.segment << 3) | - (b.reserved << 5) | - (b.userbits << 8); + return static_cast(b.rotation) | + static_cast(b.segment) << 3 | + static_cast(b.reserved) << 5 | + static_cast(b.userbits) << 8; } inline constexpr blockstate int2blockstate(blockstate_t i) { From 3e0455358a0c009c72b4b6fdb7946c14385a84fb Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 11:42:09 +0300 Subject: [PATCH 39/97] fix: debug panel - block name out of panel --- src/frontend/debug_panel.cpp | 14 +++++++++----- src/voxels/voxel.hpp | 3 ++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index 106f8322..b854fce4 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -74,21 +74,25 @@ std::shared_ptr create_debug_panel( })); panel->add(create_label([=](){ auto* indices = level->content->getIndices(); - auto def = indices->getBlockDef(player->selectedVoxel.id); std::wstringstream stream; stream << "r:" << player->selectedVoxel.state.rotation << " s:" << player->selectedVoxel.state.segment << " u:" << std::bitset<8>(player->selectedVoxel.state.userbits); - if (def) { - stream << L" (" << util::str2wstr_utf8(def->name) << L")"; - } if (player->selectedVoxel.id == BLOCK_VOID) { - return std::wstring {L"block: none"}; + return std::wstring {L"block: -"}; } else { return L"block: "+std::to_wstring(player->selectedVoxel.id)+ L" "+stream.str(); } })); + panel->add(create_label([=](){ + auto* indices = level->content->getIndices(); + if (auto def = indices->getBlockDef(player->selectedVoxel.id)) { + return L"name: " + util::str2wstr_utf8(def->name); + } else { + return std::wstring {L"name: void"}; + } + })); panel->add(create_label([=](){ return L"seed: "+std::to_wstring(level->getWorld()->getSeed()); })); diff --git a/src/voxels/voxel.hpp b/src/voxels/voxel.hpp index d7062b36..9cfaf698 100644 --- a/src/voxels/voxel.hpp +++ b/src/voxels/voxel.hpp @@ -12,7 +12,7 @@ inline constexpr int BLOCK_DIR_DOWN = 0x5; struct blockstate { uint8_t rotation : 3; - uint8_t segment : 2; + uint8_t segment : 2; // planned to 0.22 uint8_t reserved : 3; uint8_t userbits : 8; }; @@ -38,5 +38,6 @@ struct voxel { blockid_t id; blockstate state; }; +static_assert(sizeof(voxel) == 4); #endif // VOXELS_VOXEL_HPP_ From 300338667099f2805ffb23f105250c58c262b96b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 11:59:12 +0300 Subject: [PATCH 40/97] chunk flags converted to a bitfield --- src/files/WorldRegions.cpp | 2 +- src/frontend/hud.cpp | 2 +- src/graphics/render/ChunksRenderer.cpp | 7 +--- src/graphics/render/WorldRenderer.cpp | 2 +- src/lighting/LightSolver.cpp | 6 +-- src/logic/BlocksController.cpp | 2 +- src/logic/ChunksController.cpp | 16 ++++---- src/voxels/Chunk.cpp | 4 +- src/voxels/Chunk.hpp | 53 +++++--------------------- src/voxels/Chunks.cpp | 14 +++---- src/voxels/ChunksStorage.cpp | 4 +- src/world/World.cpp | 6 +-- 12 files changed, 41 insertions(+), 77 deletions(-) diff --git a/src/files/WorldRegions.cpp b/src/files/WorldRegions.cpp index 55f3b3d2..af3aadd4 100644 --- a/src/files/WorldRegions.cpp +++ b/src/files/WorldRegions.cpp @@ -374,7 +374,7 @@ void WorldRegions::put(Chunk* chunk){ chunk->encode(), CHUNK_DATA_LEN, true); // Writing lights cache - if (doWriteLights && chunk->isLighted()) { + if (doWriteLights && chunk->flags.lighted) { put(chunk->x, chunk->z, REGION_LAYER_LIGHTS, chunk->lightmap.encode(), LIGHTMAP_DATA_LEN, true); } diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 95aa69f7..ba6546f8 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -333,7 +333,7 @@ void Hud::openInventory( if (blockinv == nullptr) { blockinv = level->inventories->createVirtual(blockUI->getSlotsCount()); } - level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true); + level->chunks->getChunkByVoxel(block.x, block.y, block.z)->flags.unsaved; blockUI->bind(blockinv, content); blockPos = block; currentblockid = level->chunks->get(block.x, block.y, block.z)->id; diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index 7f3f3959..d1011a10 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -56,19 +56,16 @@ ChunksRenderer::~ChunksRenderer() { } std::shared_ptr ChunksRenderer::render(std::shared_ptr chunk, bool important) { - chunk->setModified(false); - + chunk->flags.modified = false; if (important) { auto mesh = renderer->render(chunk.get(), level->chunksStorage.get()); meshes[glm::ivec2(chunk->x, chunk->z)] = mesh; return mesh; } - glm::ivec2 key(chunk->x, chunk->z); if (inwork.find(key) != inwork.end()) { return nullptr; } - inwork[key] = true; threadPool.enqueueJob(chunk); return nullptr; @@ -86,7 +83,7 @@ std::shared_ptr ChunksRenderer::getOrRender(std::shared_ptr chunk, if (found == meshes.end()) { return render(chunk, important); } - if (chunk->isModified()) { + if (chunk->flags.modified) { render(chunk, important); } return found->second; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index ad7030a2..8d02a750 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -79,7 +79,7 @@ bool WorldRenderer::drawChunk( bool culling ){ auto chunk = level->chunks->chunks[index]; - if (!chunk->isLighted()) { + if (!chunk->flags.lighted) { return false; } float distance = glm::distance( diff --git a/src/lighting/LightSolver.cpp b/src/lighting/LightSolver.cpp index 0656ee53..f9865956 100644 --- a/src/lighting/LightSolver.cpp +++ b/src/lighting/LightSolver.cpp @@ -21,7 +21,7 @@ void LightSolver::add(int x, int y, int z, int emission) { addqueue.push(lightentry {x, y, z, ubyte(emission)}); Chunk* chunk = chunks->getChunkByVoxel(x, y, z); - chunk->setModified(true); + chunk->flags.modified = true; chunk->lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission); } @@ -67,7 +67,7 @@ void LightSolver::solve(){ if (chunk) { int lx = x - chunk->x * CHUNK_W; int lz = z - chunk->z * CHUNK_D; - chunk->setModified(true); + chunk->flags.modified = true; ubyte light = chunk->lightmap.get(lx,y,lz, channel); if (light != 0 && light == entry.light-1){ @@ -96,7 +96,7 @@ void LightSolver::solve(){ if (chunk) { int lx = x - chunk->x * CHUNK_W; int lz = z - chunk->z * CHUNK_D; - chunk->setModified(true); + chunk->flags.modified = true; ubyte light = chunk->lightmap.get(lx, y, lz, channel); voxel& v = chunk->voxels[vox_index(lx, y, lz)]; diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 8d1cbebb..8a8f58a8 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -132,7 +132,7 @@ void BlocksController::randomTick(int tickid, int parts) { if ((index + tickid) % parts != 0) continue; auto& chunk = chunks->chunks[index]; - if (chunk == nullptr || !chunk->isLighted()) + if (chunk == nullptr || !chunk->flags.lighted) continue; for (int s = 0; s < segments; s++) { for (int i = 0; i < 4; i++) { diff --git a/src/logic/ChunksController.cpp b/src/logic/ChunksController.cpp index 1c039a14..56eab88c 100644 --- a/src/logic/ChunksController.cpp +++ b/src/logic/ChunksController.cpp @@ -61,7 +61,7 @@ bool ChunksController::loadVisible(){ int index = z * w + x; auto& chunk = chunks->chunks[index]; if (chunk != nullptr){ - if (chunk->isLoaded() && !chunk->isLighted()) { + if (chunk->flags.loaded && !chunk->flags.lighted) { if (buildLights(chunk)) { return true; } @@ -99,12 +99,12 @@ bool ChunksController::buildLights(std::shared_ptr chunk) { } } if (surrounding == MIN_SURROUNDING) { - bool lightsCache = chunk->isLoadedLights(); + bool lightsCache = chunk->flags.loadedLights; if (!lightsCache) { lighting->buildSkyLight(chunk->x, chunk->z); } lighting->onChunkLoaded(chunk->x, chunk->z, !lightsCache); - chunk->setLighted(true); + chunk->flags.lighted = true; return true; } return false; @@ -114,20 +114,20 @@ void ChunksController::createChunk(int x, int z) { auto chunk = level->chunksStorage->create(x, z); chunks->putChunk(chunk); - if (!chunk->isLoaded()) { + if (!chunk->flags.loaded) { generator->generate( chunk->voxels, x, z, level->getWorld()->getSeed() ); - chunk->setUnsaved(true); + chunk->flags.unsaved = true; } chunk->updateHeights(); - if (!chunk->isLoadedLights()) { + if (!chunk->flags.loadedLights) { Lighting::prebuildSkyLight( chunk.get(), level->content->getIndices() ); } - chunk->setLoaded(true); - chunk->setReady(true); + chunk->flags.loaded = true; + chunk->flags.ready = true; } diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index 94100e16..18dabec2 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -42,12 +42,12 @@ void Chunk::updateHeights() { void Chunk::addBlockInventory(std::shared_ptr inventory, uint x, uint y, uint z) { inventories[vox_index(x, y, z)] = inventory; - setUnsaved(true); + flags.unsaved = true; } void Chunk::removeBlockInventory(uint x, uint y, uint z) { if (inventories.erase(vox_index(x, y, z))) { - setUnsaved(true); + flags.unsaved = true; } } diff --git a/src/voxels/Chunk.hpp b/src/voxels/Chunk.hpp index 29b4916c..535b6125 100644 --- a/src/voxels/Chunk.hpp +++ b/src/voxels/Chunk.hpp @@ -9,14 +9,6 @@ #include "voxel.hpp" #include "../lighting/Lightmap.hpp" -struct ChunkFlag { - static const int MODIFIED = 0x1; - static const int READY = 0x2; - static const int LOADED = 0x4; - static const int LIGHTED = 0x8; - static const int UNSAVED = 0x10; - static const int LOADED_LIGHTS = 0x20; -}; inline constexpr int CHUNK_DATA_LEN = CHUNK_VOL*4; class Lightmap; @@ -31,7 +23,14 @@ public: int bottom, top; voxel voxels[CHUNK_VOL] {}; Lightmap lightmap; - int flags = 0; + struct { + bool modified: 1; + bool ready: 1; + bool loaded: 1; + bool lighted: 1; + bool unsaved: 1; + bool loadedLights: 1; + } flags {}; /* Block inventories map where key is index of block in voxels array */ chunk_inventories_map inventories; @@ -45,14 +44,6 @@ public: // unused std::unique_ptr clone() const; - // flags getters/setters below - inline void setFlags(int mask, bool value){ - if (value) - flags |= mask; - else - flags &= ~(mask); - } - /* Creates new block inventory given size @return inventory id or 0 if block does not exists */ void addBlockInventory(std::shared_ptr inventory, @@ -63,35 +54,11 @@ public: /* @return inventory bound to the given block or nullptr */ std::shared_ptr getBlockInventory(uint x, uint y, uint z) const; - inline bool isUnsaved() const {return flags & ChunkFlag::UNSAVED;} - - inline bool isModified() const {return flags & ChunkFlag::MODIFIED;} - - inline bool isLighted() const {return flags & ChunkFlag::LIGHTED;} - - inline bool isLoaded() const {return flags & ChunkFlag::LOADED;} - - inline bool isLoadedLights() const {return flags & ChunkFlag::LOADED_LIGHTS;} - - inline bool isReady() const {return flags & ChunkFlag::READY;} - - inline void setUnsaved(bool newState) {setFlags(ChunkFlag::UNSAVED, newState);} - - inline void setModified(bool newState) {setFlags(ChunkFlag::MODIFIED, newState);} - inline void setModifiedAndUnsaved() { - setModified(true); - setUnsaved(true); + flags.modified = true; + flags.unsaved = true; } - inline void setLoaded(bool newState) {setFlags(ChunkFlag::LOADED, newState);} - - inline void setLoadedLights(bool newState) {setFlags(ChunkFlag::LOADED_LIGHTS, newState);} - - inline void setLighted(bool newState) {setFlags(ChunkFlag::LIGHTED, newState);} - - inline void setReady(bool newState) {setFlags(ChunkFlag::READY, newState);} - std::unique_ptr encode() const; /** diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 9b1dbc73..b9a63e9e 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -186,14 +186,14 @@ void Chunks::set(int32_t x, int32_t y, int32_t z, uint32_t id, blockstate state) else if (id == 0) chunk->updateHeights(); if (lx == 0 && (chunk = getChunk(cx+ox-1, cz+oz))) - chunk->setModified(true); + chunk->flags.modified = true; if (lz == 0 && (chunk = getChunk(cx+ox, cz+oz-1))) - chunk->setModified(true); + chunk->flags.modified = true; if (lx == CHUNK_W-1 && (chunk = getChunk(cx+ox+1, cz+oz))) - chunk->setModified(true); + chunk->flags.modified = true; if (lz == CHUNK_D-1 && (chunk = getChunk(cx+ox, cz+oz+1))) - chunk->setModified(true); + chunk->flags.modified = true; } voxel* Chunks::rayCast( @@ -497,12 +497,12 @@ void Chunks::saveAndClear(){ for (size_t i = 0; i < volume; i++){ Chunk* chunk = chunks[i].get(); chunks[i] = nullptr; - if (chunk == nullptr || !chunk->isLighted()) + if (chunk == nullptr || !chunk->flags.lighted) continue; - bool lightsUnsaved = !chunk->isLoadedLights() && + bool lightsUnsaved = !chunk->flags.loadedLights && worldFiles->doesWriteLights(); - if (!chunk->isUnsaved() && !lightsUnsaved) + if (!chunk->flags.unsaved && !lightsUnsaved) continue; regions.put(chunk); } diff --git a/src/voxels/ChunksStorage.cpp b/src/voxels/ChunksStorage.cpp index fa28f4f6..8a9c97b4 100644 --- a/src/voxels/ChunksStorage.cpp +++ b/src/voxels/ChunksStorage.cpp @@ -61,7 +61,7 @@ std::shared_ptr ChunksStorage::create(int x, int z) { chunk->decode(data.get()); auto invs = regions.fetchInventories(chunk->x, chunk->z); chunk->setBlockInventories(std::move(invs)); - chunk->setLoaded(true); + chunk->flags.loaded = true; for(auto& entry : chunk->inventories) { level->inventories->store(entry.second); } @@ -71,7 +71,7 @@ std::shared_ptr ChunksStorage::create(int x, int z) { auto lights = regions.getLights(chunk->x, chunk->z); if (lights) { chunk->lightmap.set(lights.get()); - chunk->setLoadedLights(true); + chunk->flags.loadedLights = true; } return chunk; } diff --git a/src/world/World.cpp b/src/world/World.cpp index fdd60446..380e2f48 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -57,11 +57,11 @@ void World::write(Level* level) { for (size_t i = 0; i < chunks->volume; i++) { auto chunk = chunks->chunks[i]; - if (chunk == nullptr || !chunk->isLighted()) + if (chunk == nullptr || !chunk->flags.lighted) continue; - bool lightsUnsaved = !chunk->isLoadedLights() && + bool lightsUnsaved = !chunk->flags.loadedLights && settings.debug.doWriteLights.get(); - if (!chunk->isUnsaved() && !lightsUnsaved) + if (!chunk->flags.unsaved && !lightsUnsaved) continue; regions.put(chunk.get()); } From 949f18e757408ddeaa9d5d624e11fb6b788ba0ed Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 13:23:13 +0300 Subject: [PATCH 41/97] -Og optimizations level for Debug configuration (GCC and Clang) --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b4e4bfd..8340b928 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,9 @@ else() -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wundef -Wwrite-strings -Wno-unused-parameter) + if (CMAKE_BUILD_TYPE MATCHES "Debug") + target_compile_options(${PROJECT_NAME} PRIVATE -Og) + endif() endif() if(VOXELENGINE_BUILD_WINDOWS_VCPKG AND WIN32) From 3abe8075ad9e7db4b4daef4b7e178299a4940c74 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 15:06:36 +0300 Subject: [PATCH 42/97] aabb blocks preview fix --- src/graphics/render/BlocksPreview.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index 96a8a718..eb7e72cf 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -44,13 +44,18 @@ std::unique_ptr BlocksPreview::draw( break; case BlockModel::aabb: { - glm::vec3 hitbox = glm::vec3(); - for (const auto& box : def->hitboxes) + glm::vec3 hitbox {}; + for (const auto& box : def->hitboxes) { hitbox = glm::max(hitbox, box.size()); - offset.y += (1.0f - hitbox).y * 0.5f; + } + offset = glm::vec3(1, 1, 0.0f); shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); - batch->blockCube(hitbox * glm::vec3(size * 0.63f), - texfaces, glm::vec4(1.0f), !def->rt.emissive); + batch->cube( + -hitbox * glm::vec3(size * 0.63f)*0.5f * glm::vec3(1,1,-1), + hitbox * glm::vec3(size * 0.63f), + texfaces, glm::vec4(1.0f), + !def->rt.emissive + ); } batch->flush(); break; @@ -138,7 +143,7 @@ std::unique_ptr BlocksPreview::build( shader->uniformMatrix("u_projview", glm::ortho(0.0f, float(iconSize), 0.0f, float(iconSize), -100.0f, 100.0f) * - glm::lookAt(glm::vec3(2, 2, 2), + glm::lookAt(glm::vec3(0.57735f), glm::vec3(0.0f), glm::vec3(0, 1, 0))); From 0bfa717b710805849ff7f6722934b402a4d142bd Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 17:45:16 +0300 Subject: [PATCH 43/97] Block.hpp tabs -> spaces --- src/voxels/Block.hpp | 166 +++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 0c4b3b68..c9db52cb 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -25,8 +25,8 @@ inline constexpr uint BLOCK_AABB_GRID = 16; inline std::string DEFAULT_MATERIAL = "base:stone"; struct block_funcs_set { - bool init: 1; - bool update: 1; + bool init: 1; + bool update: 1; bool onplaced: 1; bool onbroken: 1; bool oninteract: 1; @@ -35,46 +35,46 @@ struct block_funcs_set { }; struct CoordSystem { - glm::ivec3 axisX; - glm::ivec3 axisY; - glm::ivec3 axisZ; + glm::ivec3 axisX; + glm::ivec3 axisY; + glm::ivec3 axisZ; - /// @brief Grid 3d position fix offset (for negative vectors) - glm::ivec3 fix; + /// @brief Grid 3d position fix offset (for negative vectors) + glm::ivec3 fix; - CoordSystem() = default; - CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ); + CoordSystem() = default; + CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ); - void transform(AABB& aabb) const; + void transform(AABB& aabb) const; - inline bool isVectorHasNegatives(glm::ivec3 vec) { - return (vec.x < 0 || vec.y < 0 || vec.z < 0); - } + inline bool isVectorHasNegatives(glm::ivec3 vec) { + return (vec.x < 0 || vec.y < 0 || vec.z < 0); + } }; struct BlockRotProfile { - static const int MAX_COUNT = 8; - std::string name; - CoordSystem variants[MAX_COUNT]; + static const int MAX_COUNT = 8; + std::string name; + CoordSystem variants[MAX_COUNT]; - /// @brief Wood logs, pillars, pipes - static const BlockRotProfile PIPE; + /// @brief Wood logs, pillars, pipes + static const BlockRotProfile PIPE; - /// @brief Doors, signs and other panes - static const BlockRotProfile PANE; + /// @brief Doors, signs and other panes + static const BlockRotProfile PANE; }; enum class BlockModel { - /// @brief invisible - none, - /// @brief default cube shape - block, - /// @brief X-shape (grass) - xsprite, - /// @brief box shape sized as block hitbox - aabb, - /// @brief custom model defined in json - custom + /// @brief invisible + none, + /// @brief default cube shape + block, + /// @brief X-shape (grass) + xsprite, + /// @brief box shape sized as block hitbox + aabb, + /// @brief custom model defined in json + custom }; using BoxModel = AABB; @@ -82,61 +82,61 @@ using BoxModel = AABB; /// @brief Common kit of block properties applied to groups of blocks struct BlockMaterial { - std::string name; - std::string stepsSound {""}; - std::string placeSound {""}; - std::string breakSound {""}; + std::string name; + std::string stepsSound {""}; + std::string placeSound {""}; + std::string breakSound {""}; }; /// @brief Block properties definition class Block { public: - /// @brief Block string id (with prefix included) - std::string const name; + /// @brief Block string id (with prefix included) + std::string const name; - std::string caption; - + std::string caption; + /// @brief Textures set applied to block sides - std::string textureFaces[6]; // -x,x, -y,y, -z,z - - std::vector modelTextures = {}; - std::vector modelBoxes = {}; - std::vector modelExtraPoints = {}; //initially made for tetragons - std::vector modelUVs = {}; // boxes' tex-UVs also there + std::string textureFaces[6]; // -x,x, -y,y, -z,z + + std::vector modelTextures = {}; + std::vector modelBoxes = {}; + std::vector modelExtraPoints = {}; //initially made for tetragons + std::vector modelUVs = {}; // boxes' tex-UVs also there /// @brief id of used BlockMaterial, may specify non-existing material std::string material = DEFAULT_MATERIAL; - /// @brief Light emission R, G, B, S (sky lights: sun, moon, radioactive clouds) - uint8_t emission[4] {0, 0, 0, 0}; + /// @brief Light emission R, G, B, S (sky lights: sun, moon, radioactive clouds) + uint8_t emission[4] {0, 0, 0, 0}; - /// @brief Influences visible block sides for transparent blocks - uint8_t drawGroup = 0; - + /// @brief Influences visible block sides for transparent blocks + uint8_t drawGroup = 0; + /// @brief Block model type - BlockModel model = BlockModel::block; - + BlockModel model = BlockModel::block; + /// @brief Does the block passing lights into itself - bool lightPassing = false; - + bool lightPassing = false; + /// @brief Does the block passing top-down sky lights into itself - bool skyLightPassing = false; - + bool skyLightPassing = false; + /// @brief Is the block a physical obstacle - bool obstacle = true; - + bool obstacle = true; + /// @brief Can the block be selected - bool selectable = true; - + bool selectable = true; + /// @brief Can the block be replaced with other. - /// Examples of replaceable blocks: air, flower, water - bool replaceable = false; - + /// Examples of replaceable blocks: air, flower, water + bool replaceable = false; + /// @brief Can player destroy the block - bool breakable = true; - + bool breakable = true; + /// @brief Can the block be oriented different ways - bool rotatable = false; + bool rotatable = false; /// @brief Can the block exist without physical support be a solid block below bool grounded = false; @@ -146,46 +146,46 @@ public: /// @brief Set of block physical hitboxes std::vector hitboxes; - + /// @brief Set of available block rotations (coord-systems) - BlockRotProfile rotations; + BlockRotProfile rotations; /// @brief Item will be picked on MMB click on the block std::string pickingItem = name+BLOCK_ITEM_SUFFIX; /// @brief Block script name in blocks/ without extension std::string scriptName = name.substr(name.find(':')+1); - + /// @brief Default block layout will be used by hud.open_block(...) - std::string uiLayout = name; + std::string uiLayout = name; /// @brief Block inventory size. 0 - no inventory uint inventorySize = 0; - /// @brief Runtime indices (content indexing results) - struct { - /// @brief block runtime integer id - blockid_t id; - + /// @brief Runtime indices (content indexing results) + struct { + /// @brief block runtime integer id + blockid_t id; + /// @brief is the block completely opaque for render and raycast - bool solid = true; - + bool solid = true; + /// @brief does the block emit any lights - bool emissive = false; + bool emissive = false; /// @brief set of hitboxes sets with all coord-systems precalculated std::vector hitboxes[BlockRotProfile::MAX_COUNT]; - + /// @brief set of block callbacks flags - block_funcs_set funcsset {}; + block_funcs_set funcsset {}; /// @brief picking item integer id itemid_t pickingItem = 0; - } rt; + } rt; - Block(std::string name); - Block(std::string name, std::string texture); - Block(const Block&) = delete; + Block(std::string name); + Block(std::string name, std::string texture); + Block(const Block&) = delete; }; #endif /* VOXELS_BLOCK_HPP_ */ From e969d4fea2b3a6a7bf16db9d3b52ede5607cd909 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 17:47:39 +0300 Subject: [PATCH 44/97] BlocksController.hpp tabs -> spaces --- src/logic/BlocksController.cpp | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 8a8f58a8..8496bd30 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -53,8 +53,8 @@ int Clock::getTickId() const { BlocksController::BlocksController(Level* level, uint padding) : level(level), - chunks(level->chunks.get()), - lighting(level->lighting.get()), + chunks(level->chunks.get()), + lighting(level->lighting.get()), randTickClock(20, 3), blocksTickClock(20, 1), worldTickClock(20, 1), @@ -150,49 +150,49 @@ void BlocksController::randomTick(int tickid, int parts) { } } } - } + } } int64_t BlocksController::createBlockInventory(int x, int y, int z) { - auto chunk = chunks->getChunkByVoxel(x, y, z); - if (chunk == nullptr) { - return 0; - } - int lx = x - chunk->x * CHUNK_W; - int lz = z - chunk->z * CHUNK_D; - auto inv = chunk->getBlockInventory(lx, y, lz); - if (inv == nullptr) { + auto chunk = chunks->getChunkByVoxel(x, y, z); + if (chunk == nullptr) { + return 0; + } + int lx = x - chunk->x * CHUNK_W; + int lz = z - chunk->z * CHUNK_D; + auto inv = chunk->getBlockInventory(lx, y, lz); + if (inv == nullptr) { auto indices = level->content->getIndices(); auto def = indices->getBlockDef(chunk->voxels[vox_index(lx, y, lz)].id); int invsize = def->inventorySize; if (invsize == 0) { return 0; } - inv = level->inventories->create(invsize); + inv = level->inventories->create(invsize); chunk->addBlockInventory(inv, lx, y, lz); - } + } return inv->getId(); } void BlocksController::bindInventory(int64_t invid, int x, int y, int z) { auto chunk = chunks->getChunkByVoxel(x, y, z); - if (chunk == nullptr) { - throw std::runtime_error("block does not exists"); - } + if (chunk == nullptr) { + throw std::runtime_error("block does not exists"); + } if (invid <= 0) { throw std::runtime_error("unable to bind virtual inventory"); } - int lx = x - chunk->x * CHUNK_W; - int lz = z - chunk->z * CHUNK_D; + int lx = x - chunk->x * CHUNK_W; + int lz = z - chunk->z * CHUNK_D; chunk->addBlockInventory(level->inventories->get(invid), lx, y, lz); } void BlocksController::unbindInventory(int x, int y, int z) { auto chunk = chunks->getChunkByVoxel(x, y, z); - if (chunk == nullptr) { - throw std::runtime_error("block does not exists"); - } + if (chunk == nullptr) { + throw std::runtime_error("block does not exists"); + } int lx = x - chunk->x * CHUNK_W; - int lz = z - chunk->z * CHUNK_D; + int lz = z - chunk->z * CHUNK_D; chunk->removeBlockInventory(lx, y, lz); } From 7b0e31951bd81c4cb31bd1426d95478790beb8d8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 18:14:50 +0300 Subject: [PATCH 45/97] block tick interval --- src/content/ContentLoader.cpp | 4 ++++ src/logic/BlocksController.cpp | 5 +++-- src/voxels/Block.hpp | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index f3c47b6b..5b7e30b3 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -212,6 +212,10 @@ void ContentLoader::loadBlock(Block& def, std::string name, fs::path file) { root->str("script-name", def.scriptName); root->str("ui-layout", def.uiLayout); root->num("inventory-size", def.inventorySize); + root->num("tick-interval", def.tickInterval); + if (def.tickInterval == 0) { + def.tickInterval = 1; + } if (def.hidden && def.pickingItem == def.name+BLOCK_ITEM_SUFFIX) { def.pickingItem = CORE_EMPTY; diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 8496bd30..9ddf12b8 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -113,8 +113,9 @@ void BlocksController::onBlocksTick(int tickid, int parts) { if ((id + tickid) % parts != 0) continue; auto def = indices->getBlockDef(id); - if (def->rt.funcsset.onblockstick) { - scripting::on_blocks_tick(def, tickRate); + auto interval = def->tickInterval; + if (def->rt.funcsset.onblockstick && tickid / parts % interval == 0) { + scripting::on_blocks_tick(def, tickRate / interval); } } } diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index c9db52cb..4628dd0e 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -162,6 +162,9 @@ public: /// @brief Block inventory size. 0 - no inventory uint inventorySize = 0; + // @brief Block tick interval (1 - 20tps, 2 - 10tps) + uint tickInterval = 1; + /// @brief Runtime indices (content indexing results) struct { /// @brief block runtime integer id From 0f4b6911a6afa85732707945926af4245bf5d4b0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 31 May 2024 20:38:50 +0300 Subject: [PATCH 46/97] small fix --- src/frontend/debug_panel.cpp | 1 - src/frontend/hud.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/frontend/debug_panel.cpp b/src/frontend/debug_panel.cpp index b854fce4..4362b189 100644 --- a/src/frontend/debug_panel.cpp +++ b/src/frontend/debug_panel.cpp @@ -73,7 +73,6 @@ std::shared_ptr create_debug_panel( L" visible: "+std::to_wstring(level->chunks->visible); })); panel->add(create_label([=](){ - auto* indices = level->content->getIndices(); std::wstringstream stream; stream << "r:" << player->selectedVoxel.state.rotation << " s:" << player->selectedVoxel.state.segment << " u:" diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index ba6546f8..42be78f9 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -333,7 +333,7 @@ void Hud::openInventory( if (blockinv == nullptr) { blockinv = level->inventories->createVirtual(blockUI->getSlotsCount()); } - level->chunks->getChunkByVoxel(block.x, block.y, block.z)->flags.unsaved; + level->chunks->getChunkByVoxel(block.x, block.y, block.z)->flags.unsaved = true; blockUI->bind(blockinv, content); blockPos = block; currentblockid = level->chunks->get(block.x, block.y, block.z)->id; From 9597879eff12d4ff6c66d5b7d29a20221c8b3ba0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 1 Jun 2024 07:28:35 +0300 Subject: [PATCH 47/97] small fix --- src/world/Level.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/Level.hpp b/src/world/Level.hpp index e64871ab..7b18f06f 100644 --- a/src/world/Level.hpp +++ b/src/world/Level.hpp @@ -58,8 +58,8 @@ public: std::shared_ptr tObj = std::make_shared(args...); std::shared_ptr obj = std::dynamic_pointer_cast(tObj); - objects.push_back(obj); obj->objectUID = objects.size(); + objects.push_back(obj); obj->spawned(); return tObj; } From 731d43ff63bb480e1bf322d236a0047d888b1a29 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 1 Jun 2024 12:25:53 +0300 Subject: [PATCH 48/97] container:setInterval --- src/logic/scripting/lua/libgui.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index b4f4d9c3..1152b0a0 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -101,6 +101,17 @@ static int l_container_clear(lua_State* L) { return 0; } +static int l_container_set_interval(lua_State* L) { + auto node = getDocumentNode(L, 1); + auto interval = state->tointeger(2) / 1000.0f; + if (auto container = std::dynamic_pointer_cast(node.node)) { + state->pushvalue(3); + auto runnable = state->createRunnable(); + container->listenInterval(interval, runnable); + } + return 0; +} + static int l_move_into(lua_State* L) { auto node = getDocumentNode(L, 1); auto dest = getDocumentNode(L, 2); @@ -255,6 +266,13 @@ static int p_get_clear(UINode* node) { return 0; } +static int p_set_interval(UINode* node) { + if (dynamic_cast(node)) { + return state->pushcfunction(l_container_set_interval); + } + return 0; +} + static int p_get_color(UINode* node) { return lua::pushcolor_arr(state->getLua(), node->getColor()); } @@ -317,6 +335,7 @@ static int l_gui_getattr(lua_State* L) { {"move_into", p_move_into}, {"add", p_get_add}, {"clear", p_get_clear}, + {"setInterval", p_set_interval}, {"placeholder", p_get_placeholder}, {"valid", p_is_valid}, {"caret", p_get_caret}, From 3a6fa5763018a2a596b7ab0ef41582fc1aa6e7e5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 1 Jun 2024 12:57:10 +0300 Subject: [PATCH 49/97] item on_use double call fix --- src/logic/PlayerController.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 4547a4da..beb452f6 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -444,11 +444,11 @@ void PlayerController::updateInteraction(){ selectedBlockId = -1; selectedBlockRotation = 0; player->selectedVoxel.id = BLOCK_VOID; - } - if (rclick) { - if (item->rt.funcsset.on_use) { - scripting::on_item_use(player.get(), item); - } + if (rclick) { + if (item->rt.funcsset.on_use) { + scripting::on_item_use(player.get(), item); + } + } } } From d3e34741e0922d5ee306db20155118188ea014bb Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 2 Jun 2024 21:42:51 +0300 Subject: [PATCH 50/97] res/bindings.toml moved to res/config --- res/{ => config}/bindings.toml | 0 src/engine.cpp | 22 ++++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) rename res/{ => config}/bindings.toml (100%) diff --git a/res/bindings.toml b/res/config/bindings.toml similarity index 100% rename from res/bindings.toml rename to res/config/bindings.toml diff --git a/src/engine.cpp b/src/engine.cpp index fa34c3c7..4df8a123 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -252,6 +252,16 @@ void Engine::loadAssets() { assets.reset(new_assets.release()); } +static void load_configs(const fs::path& root) { + auto configFolder = root/fs::path("config"); + auto bindsFile = configFolder/fs::path("bindings.toml"); + if (fs::is_regular_file(bindsFile)) { + Events::loadBindingsToml( + bindsFile.u8string(), files::read_string(bindsFile) + ); + } +} + void Engine::loadContent() { auto resdir = paths->getResources(); ContentBuilder contentBuilder; @@ -274,14 +284,10 @@ void Engine::loadContent() { ContentLoader loader(&pack); loader.load(contentBuilder); - auto configFolder = pack.folder/fs::path("config"); - auto bindsFile = configFolder/fs::path("bindings.toml"); - if (fs::is_regular_file(bindsFile)) { - Events::loadBindingsToml( - bindsFile.u8string(), files::read_string(bindsFile) - ); - } - } + load_configs(pack.folder); + } + load_configs(paths->getResources()); + content = contentBuilder.build(); resPaths = std::make_unique(resdir, resRoots); From 4e2ba865f35c5ff020d8f034d638904e4a726f3f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 2 Jun 2024 22:10:39 +0300 Subject: [PATCH 51/97] controls.json -> controls.toml --- src/core_defs.cpp | 2 +- src/engine.cpp | 14 +++++++++++++- src/engine.hpp | 1 + src/files/engine_paths.cpp | 6 +++++- src/files/engine_paths.hpp | 1 + src/window/Events.cpp | 23 +++++++++++++++-------- src/window/Events.hpp | 3 ++- src/window/input.cpp | 22 ++++++++++++++++++++++ src/window/input.hpp | 5 +++++ 9 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/core_defs.cpp b/src/core_defs.cpp index 39c70991..57c85bbc 100644 --- a/src/core_defs.cpp +++ b/src/core_defs.cpp @@ -27,7 +27,7 @@ void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) { auto bindsFile = paths->getResources()/fs::path("bindings.toml"); if (fs::is_regular_file(bindsFile)) { - Events::loadBindingsToml( + Events::loadBindings( bindsFile.u8string(), files::read_string(bindsFile) ); } diff --git a/src/engine.cpp b/src/engine.cpp index 4df8a123..7aaf5e21 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -71,6 +71,7 @@ Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, Engin if (Window::initialize(&this->settings.display)){ throw initialize_error("could not initialize window"); } + loadControls(); audio::initialize(settings.audio.enabled.get()); create_channel(this, "master", settings.audio.volumeMaster); create_channel(this, "regular", settings.audio.volumeRegular); @@ -103,11 +104,22 @@ void Engine::loadSettings() { std::string text = files::read_string(settings_file); toml::parse(settingsHandler, settings_file.string(), text); } +} + +void Engine::loadControls() { fs::path controls_file = paths->getControlsFile(); if (fs::is_regular_file(controls_file)) { logger.info() << "loading controls"; std::string text = files::read_string(controls_file); Events::loadBindings(controls_file.u8string(), text); + } else { + controls_file = paths->getControlsFileOld(); + if (fs::is_regular_file(controls_file)) { + logger.info() << "loading controls (old)"; + std::string text = files::read_string(controls_file); + Events::loadBindingsOld(controls_file.u8string(), text); + fs::remove(controls_file); + } } } @@ -256,7 +268,7 @@ static void load_configs(const fs::path& root) { auto configFolder = root/fs::path("config"); auto bindsFile = configFolder/fs::path("bindings.toml"); if (fs::is_regular_file(bindsFile)) { - Events::loadBindingsToml( + Events::loadBindings( bindsFile.u8string(), files::read_string(bindsFile) ); } diff --git a/src/engine.hpp b/src/engine.hpp index 878b1e54..d7897c92 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -65,6 +65,7 @@ class Engine : public util::ObjectsKeeper { std::unique_ptr gui; + void loadControls(); void loadSettings(); void saveSettings(); void updateTimers(); diff --git a/src/files/engine_paths.cpp b/src/files/engine_paths.cpp index 509c4055..0df0afec 100644 --- a/src/files/engine_paths.cpp +++ b/src/files/engine_paths.cpp @@ -10,7 +10,7 @@ #include "WorldFiles.hpp" const fs::path SCREENSHOTS_FOLDER {"screenshots"}; -const fs::path CONTROLS_FILE {"controls.json"}; +const fs::path CONTROLS_FILE {"controls.toml"}; const fs::path SETTINGS_FILE {"settings.toml"}; fs::path EnginePaths::getUserfiles() const { @@ -60,6 +60,10 @@ fs::path EnginePaths::getControlsFile() { return userfiles/fs::path(CONTROLS_FILE); } +fs::path EnginePaths::getControlsFileOld() { + return userfiles/fs::path("controls.json"); +} + fs::path EnginePaths::getSettingsFile() { return userfiles/fs::path(SETTINGS_FILE); } diff --git a/src/files/engine_paths.hpp b/src/files/engine_paths.hpp index ac1ed5a8..f507aebf 100644 --- a/src/files/engine_paths.hpp +++ b/src/files/engine_paths.hpp @@ -29,6 +29,7 @@ public: fs::path getWorldFolder(); fs::path getWorldFolder(const std::string& name); fs::path getControlsFile(); + fs::path getControlsFileOld(); // TODO: remove in 0.22 fs::path getSettingsFile(); bool isWorldNameUsed(std::string name); diff --git a/src/window/Events.cpp b/src/window/Events.cpp index 76158230..f2c47a29 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -110,6 +110,10 @@ void Events::bind(const std::string& name, inputtype type, int code) { bindings.emplace(name, Binding(type, code)); } +void Events::rebind(const std::string& name, inputtype type, int code) { + bindings[name] = Binding(type, code); +} + bool Events::active(const std::string& name) { const auto& found = bindings.find(name); if (found == bindings.end()) { @@ -155,19 +159,22 @@ std::string Events::writeBindings() { dynamic::Map obj; for (auto& entry : Events::bindings) { const auto& binding = entry.second; - - auto& jentry = obj.putMap(entry.first); + std::string value; switch (binding.type) { - case inputtype::keyboard: jentry.put("type", "keyboard"); break; - case inputtype::mouse: jentry.put("type", "mouse"); break; + case inputtype::keyboard: + value = "key:"+input_util::get_name(static_cast(binding.code)); + break; + case inputtype::mouse: + value = "mouse:"+input_util::get_name(static_cast(binding.code)); + break; default: throw std::runtime_error("unsupported control type"); } - jentry.put("code", binding.code); + obj.put(entry.first, value); } - return json::stringify(&obj, true, " "); + return toml::stringify(obj); } -void Events::loadBindings(const std::string& filename, const std::string& source) { +void Events::loadBindingsOld(const std::string& filename, const std::string& source) { auto obj = json::parse(filename, source); for (auto& entry : Events::bindings) { auto& binding = entry.second; @@ -192,7 +199,7 @@ void Events::loadBindings(const std::string& filename, const std::string& source } } -void Events::loadBindingsToml(const std::string& filename, const std::string& source) { +void Events::loadBindings(const std::string& filename, const std::string& source) { auto map = toml::parse(filename, source); for (auto& entry : map->values) { if (auto value = std::get_if(&entry.second)) { diff --git a/src/window/Events.hpp b/src/window/Events.hpp index c8d354d3..04bdcfe0 100644 --- a/src/window/Events.hpp +++ b/src/window/Events.hpp @@ -41,6 +41,7 @@ public: static void bind(const std::string& name, inputtype type, keycode code); static void bind(const std::string& name, inputtype type, mousecode code); static void bind(const std::string& name, inputtype type, int code); + static void rebind(const std::string& name, inputtype type, int code); static bool active(const std::string& name); static bool jactive(const std::string& name); @@ -51,7 +52,7 @@ public: static std::string writeBindings(); static void loadBindings(const std::string& filename, const std::string& source); - static void loadBindingsToml(const std::string& filename, const std::string& source); + static void loadBindingsOld(const std::string& filename, const std::string& source); // TODO: remove in 0.22 }; #endif // WINDOW_EVENTS_HPP_ diff --git a/src/window/input.cpp b/src/window/input.cpp index 33621f70..481e4a79 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -40,6 +40,25 @@ static std::unordered_map mousecodes { {"middle", GLFW_MOUSE_BUTTON_3}, }; +static std::unordered_map keynames {}; + +std::string input_util::get_name(mousecode code) { + switch (code) { + case mousecode::BUTTON_1: return "left"; + case mousecode::BUTTON_2: return "right"; + case mousecode::BUTTON_3: return "middle"; + default: return "unknown"; + } +} + +std::string input_util::get_name(keycode code) { + auto found = keynames.find(static_cast(code)); + if (found == keynames.end()) { + return "unknown"; + } + return found->second; +} + void Binding::reset(inputtype type, int code) { this->type = type; this->code = code; @@ -63,6 +82,9 @@ void input_util::initialize() { for (char i = 'a'; i <= 'z'; i++) { keycodes[std::string({i})] = GLFW_KEY_A-'a'+i; } + for (const auto& entry : keycodes) { + keynames[entry.second] = entry.first; + } } keycode input_util::keycode_from(const std::string& name) { diff --git a/src/window/input.hpp b/src/window/input.hpp index 21ca63c1..50e26446 100644 --- a/src/window/input.hpp +++ b/src/window/input.hpp @@ -122,6 +122,11 @@ namespace input_util { std::string to_string(keycode code); /// @return Mouse button label by keycode std::string to_string(mousecode code); + + /// @return Key name by keycode + std::string get_name(keycode code); + /// @return Mouse button name by keycode + std::string get_name(mousecode code); } enum class inputtype { From b571179c8a4de24ac84cb72d4ecbad2399ce2b32 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 08:37:34 +0300 Subject: [PATCH 52/97] res/config/builtins.list --- res/config/builtins.list | 1 + src/engine.cpp | 3 +++ src/engine.hpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 res/config/builtins.list diff --git a/res/config/builtins.list b/res/config/builtins.list new file mode 100644 index 00000000..df967b96 --- /dev/null +++ b/res/config/builtins.list @@ -0,0 +1 @@ +base diff --git a/src/engine.cpp b/src/engine.cpp index 7aaf5e21..8b57a237 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -95,6 +95,9 @@ Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, Engin addWorldGenerators(); scripting::initialize(this); + + auto resdir = paths->getResources(); + basePacks = files::read_list(resdir/fs::path("config/builtins.list")); } void Engine::loadSettings() { diff --git a/src/engine.hpp b/src/engine.hpp index d7897c92..e9ebeb8a 100644 --- a/src/engine.hpp +++ b/src/engine.hpp @@ -57,7 +57,7 @@ class Engine : public util::ObjectsKeeper { std::recursive_mutex postRunnablesMutex; std::unique_ptr controller; std::unique_ptr interpreter; - std::vector basePacks {"base"}; + std::vector basePacks; uint64_t frame = 0; double lastTime = 0.0; From c59973505e3651456a23273ce60ffd8c684c0081 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 09:50:48 +0300 Subject: [PATCH 53/97] added node:destruct() --- src/graphics/ui/elements/Container.cpp | 8 ++++++++ src/graphics/ui/elements/Container.hpp | 1 + src/logic/scripting/lua/libgui.cpp | 25 +++++++++++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/graphics/ui/elements/Container.cpp b/src/graphics/ui/elements/Container.cpp index fe8d77ba..e31cde11 100644 --- a/src/graphics/ui/elements/Container.cpp +++ b/src/graphics/ui/elements/Container.cpp @@ -127,6 +127,14 @@ void Container::remove(std::shared_ptr selected) { refresh(); } +void Container::remove(const std::string& id) { + for (auto& node : nodes) { + if (node->getId() == id) { + return remove(node); + } + } +} + void Container::clear() { for (auto node : nodes) { node->setParent(nullptr); diff --git a/src/graphics/ui/elements/Container.hpp b/src/graphics/ui/elements/Container.hpp index 8aa38b2f..be385f35 100644 --- a/src/graphics/ui/elements/Container.hpp +++ b/src/graphics/ui/elements/Container.hpp @@ -26,6 +26,7 @@ namespace gui { virtual void add(std::shared_ptr node, glm::vec2 pos); virtual void clear(); virtual void remove(std::shared_ptr node); + virtual void remove(const std::string& id); virtual void scrolled(int value) override; virtual void setScrollable(bool flag); void listenInterval(float interval, ontimeout callback, int repeat=-1); diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 1152b0a0..3c738dde 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -93,6 +93,18 @@ static int l_container_add(lua_State* L) { return 0; } +static int l_node_destruct(lua_State* L) { + auto docnode = getDocumentNode(L); + auto node = std::dynamic_pointer_cast(docnode.node); + engine->getGUI()->postRunnable([node]() { + auto parent = node->getParent(); + if (auto container = dynamic_cast(parent)) { + container->remove(node); + } + }); + return 0; +} + static int l_container_clear(lua_State* L) { auto node = getDocumentNode(L, 1); if (auto container = std::dynamic_pointer_cast(node.node)) { @@ -254,21 +266,25 @@ static int p_get_src(UINode* node) { static int p_get_add(UINode* node) { if (dynamic_cast(node)) { - return state->pushcfunction(l_container_add); + return state->pushcfunction(lua_wrap_errors); } return 0; } +static int p_get_destruct(UINode*) { + return state->pushcfunction(lua_wrap_errors); +} + static int p_get_clear(UINode* node) { if (dynamic_cast(node)) { - return state->pushcfunction(l_container_clear); + return state->pushcfunction(lua_wrap_errors); } return 0; } static int p_set_interval(UINode* node) { if (dynamic_cast(node)) { - return state->pushcfunction(l_container_set_interval); + return state->pushcfunction(lua_wrap_errors); } return 0; } @@ -331,9 +347,10 @@ static int l_gui_getattr(lua_State* L) { {"size", p_get_size}, {"interactive", p_is_interactive}, {"visible", p_is_visible}, - {"enabled", p_is_enabled}, + {"enabled", p_is_enabled}, {"move_into", p_move_into}, {"add", p_get_add}, + {"destruct", p_get_destruct}, {"clear", p_get_clear}, {"setInterval", p_set_interval}, {"placeholder", p_get_placeholder}, From cf94a6629a89f83e6adf1c6926eeede2ba9ad394 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 11:23:20 +0300 Subject: [PATCH 54/97] =?UTF-8?q?added=20=D0=A4=D0=B0=D0=B9=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=8F-=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B0-?= =?UTF-8?q?=D0=B8-=D1=81=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/8.Скриптинг.md | 75 -------------- doc/ru/Файловая-система-и-сериализация.md | 120 ++++++++++++++++++++++ 2 files changed, 120 insertions(+), 75 deletions(-) create mode 100644 doc/ru/Файловая-система-и-сериализация.md diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index e68ea1a4..ce3db1aa 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -497,81 +497,6 @@ function on_hud_close(playerid: int) ## Библиотеки движка -### file - -Библиотека функций для работы с файлами - -```python -file.resolve(путь: str) -> str -``` - -Функция приводит запись `точка_входа:путь` (например `user:worlds/house1`) к обычному пути. (например `C://Users/user/.voxeng/worlds/house1`) - -> [!NOTE] -> Функцию не нужно использовать в сочетании с другими функциями из библиотеки, так как они делают это автоматически - -Возвращаемый путь не является каноническим и может быть как абсолютным, так и относительным. - -```python -file.read(путь: str) -> str -``` - -Читает весь текстовый файл и возвращает в виде строки - -```python -file.read_bytes(путь: str) -> array of integers -``` - -Читает файл в массив байт. - -```python -file.write(путь: str, текст: str) -> nil -``` - -Записывает текст в файл (с перезаписью) - -```python -file.write_bytes(путь: str, data: array of integers) -``` - -Записывает массив байт в файл (с перезаписью) - -```python -file.length(путь: str) -> int -``` - -Возвращает размер файла в байтах, либо -1, если файл не найден - -```python -file.exists(путь: str) -> bool -``` - -Проверяет, существует ли по данному пути файл или директория - -```python -file.isfile(путь: str) -> bool -``` - -Проверяет, существует ли по данному пути файл - -```python -file.isdir(путь: str) -> bool -``` - -Проверяет, существует ли по данному пути директория - -```python -file.mkdir(путь: str) -> bool -``` - -Создает директорию. Возвращает true если была создана новая директория - -```python -file.mkdirs(путь: str) -> bool -``` - -Создает всю цепочку директорий. Возвращает true если были созданы директории. - ### time ```python diff --git a/doc/ru/Файловая-система-и-сериализация.md b/doc/ru/Файловая-система-и-сериализация.md new file mode 100644 index 00000000..2ef8842b --- /dev/null +++ b/doc/ru/Файловая-система-и-сериализация.md @@ -0,0 +1,120 @@ +## Библиотека *file* + +Библиотека функций для работы с файлами + +```python +file.resolve(путь: str) -> str +``` + +Функция приводит запись `точка_входа:путь` (например `user:worlds/house1`) к обычному пути. (например `C://Users/user/.voxeng/worlds/house1`) + +> [!NOTE] + +> Функцию не нужно использовать в сочетании с другими функциями из библиотеки, так как они делают это автоматически + +Возвращаемый путь не является каноническим и может быть как абсолютным, так и относительным. + +```python +file.read(путь: str) -> str +``` + +Читает весь текстовый файл и возвращает в виде строки + +```python +file.read_bytes(путь: str) -> array of integers +``` + +Читает файл в массив байт. + +```python +file.write(путь: str, текст: str) -> nil +``` + +Записывает текст в файл (с перезаписью) + +```python +file.write_bytes(путь: str, data: array of integers) +``` + +Записывает массив байт в файл (с перезаписью) + +```python +file.length(путь: str) -> int +``` + +Возвращает размер файла в байтах, либо -1, если файл не найден + +```python +file.exists(путь: str) -> bool +``` + +Проверяет, существует ли по данному пути файл или директория + +```python +file.isfile(путь: str) -> bool +``` + +Проверяет, существует ли по данному пути файл + +```python +file.isdir(путь: str) -> bool +``` + +Проверяет, существует ли по данному пути директория + +```python +file.mkdir(путь: str) -> bool +``` + +Создает директорию. Возвращает true если была создана новая директория + +```python +file.mkdirs(путь: str) -> bool +``` + +Создает всю цепочку директорий. Возвращает true если были созданы директории. + +## Библиотека json + +Библиотека содержит функции для сериализации и десериализации таблиц: + +```python +json.stringify(object: table, human_readable: bool=false) -> str +``` + +Сериализует объект в JSON строку. При значении второго параметра **true** будет использовано многострочное форматирование, удобное для чтения человеком, а не компактное, использующееся по-умолчанию. + +```python +json.parse(code: str) -> table +``` + +Парсит JSON строку в таблицу. + +## Библиотека toml + +Библиотека содержит функции для сериализации и десериализации таблиц: + +```python +toml.stringify(object: table) -> str +``` + +Сериализует объект в TOML строку. + +```python +toml.parse(code: str) -> table +``` + +Парсит TOML строку в таблицу. + +## Сохранение данных в мире + +При сохранении данных пака в мире следует использовать функцию +```python +pack.data_file(packid: str, filename: str) -> str +``` + +Функция возвращает путь к файлу данных по типу: `world:data/packid/filename` + +и создает недостающие директории в пути. + +При использовании путей не соответствующим `data/{packid}/...` возможна потеря данных при перезаписи мира. From ee8cc4cb7c192d7080db1f464db799f1b1408bf7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 11:25:05 +0300 Subject: [PATCH 55/97] github --- doc/ru/Файловая-система-и-сериализация.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/ru/Файловая-система-и-сериализация.md b/doc/ru/Файловая-система-и-сериализация.md index 2ef8842b..9cbe10b8 100644 --- a/doc/ru/Файловая-система-и-сериализация.md +++ b/doc/ru/Файловая-система-и-сериализация.md @@ -9,7 +9,6 @@ file.resolve(путь: str) -> str Функция приводит запись `точка_входа:путь` (например `user:worlds/house1`) к обычному пути. (например `C://Users/user/.voxeng/worlds/house1`) > [!NOTE] - > Функцию не нужно использовать в сочетании с другими функциями из библиотеки, так как они делают это автоматически Возвращаемый путь не является каноническим и может быть как абсолютным, так и относительным. From 538a74c56d32b31c386c08c745be7477d58f99b1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 14:50:36 +0300 Subject: [PATCH 56/97] languages list: template used --- res/layouts/pages/languages.xml.lua | 7 +++---- res/layouts/templates/language.xml | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 res/layouts/templates/language.xml diff --git a/res/layouts/pages/languages.xml.lua b/res/layouts/pages/languages.xml.lua index a064c68c..2e3710e9 100644 --- a/res/layouts/pages/languages.xml.lua +++ b/res/layouts/pages/languages.xml.lua @@ -9,10 +9,9 @@ function on_open() table.sort(names) local panel = document.root - for _,k in ipairs(names) do - panel:add(string.format( - "", - string.format("core.set_setting('ui.language', %q) menu:back()", invlocales[k]), k + for _,name in ipairs(names) do + panel:add(gui.template( + "language", {id=invlocales[name], name=name} )) end panel:add("") diff --git a/res/layouts/templates/language.xml b/res/layouts/templates/language.xml new file mode 100644 index 00000000..fea34b31 --- /dev/null +++ b/res/layouts/templates/language.xml @@ -0,0 +1,4 @@ + From 64f8d842aff4facc332026fa8b7d1e60982bd76e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 16:16:48 +0300 Subject: [PATCH 57/97] =?UTF-8?q?added=20docs/=D0=A1=D0=BE=D0=B1=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D1=8F-=D0=B4=D0=B2=D0=B8=D0=B6=D0=BA=D0=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/8.Скриптинг.md | 142 --------------------------------------- doc/ru/События-движка.md | 126 ++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 142 deletions(-) create mode 100644 doc/ru/События-движка.md diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index ce3db1aa..ec066f4a 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -375,126 +375,6 @@ hud.get_block_inventory() -> int Получить ID инвентаря открытого блока или 0 -## События блоков - -```lua -function on_placed(x, y, z, playerid) -``` - -Вызывается после установки блока игроком - -```lua -function on_broken(x, y, z, playerid) -``` - -Вызывается после разрушения блока игроком - -```lua -function on_interact(x, y, z, playerid) -> bool -``` - -Вызывается при нажатии на блок ПКМ. Предотвращает установку блоков, если возвращает `true` - -```lua -function on_update(x, y, z) -``` - -Вызывается при обновлении блока (если изменился соседний блок) - -```lua -function on_random_update(x, y, z) -``` - -Вызывается в случайные моменты времени (рост травы на блоках земли) - -```lua -function on_blocks_tick(tps: int) -``` - -Вызывается tps (20) раз в секунду - -## События предметов - -```lua -function on_use(playerid: int) -``` - -Вызывается при нажатии ПКМ не на блок. - -```lua -function on_use_on_block(x: int, y: int, z: int, playerid: int) -``` - -Вызывается при нажатии ПКМ на блок. Предотвращает установку блока, прописанного в `placing-block` если возвращает `true` - -```lua -function on_block_break_by(x: int, y: int, z: int, playerid: int) -``` - -Вызывается при нажатии ЛКМ на блок (в т.ч неразрушимый). Предотвращает разрушение блока, если возвращает `true` - -## События мира - -События мира для контент-пака прописываются в `scripts/world.lua` - -```lua -function on_world_open() -``` - -Вызывается при загрузке мира - -```lua -function on_world_save() -``` - -Вызывается перед сохранением мира - -```lua -function on_world_tick() -``` - -Вызывается 20 раз в секунду - -```lua -function on_world_quit() -``` - -Вызывается при выходе из мира (после сохранения) - -## События макета - -События прописываются в файле `layouts/имя_макета.xml.lua`. - -```lua -function on_open(invid: int, x: int, y: int, z: int) -``` - -Вызывается при добавлении элемента на экран. -При отсутствии привязки к инвентарю invid будет равен 0. -При отсутствии привязки к блоку x, y, z так же будут равны 0. - -```lua -function on_close(invid: int) -``` - -Вызывается при удалении элемента с экрана. - -## События HUD - -События связанные с игровым интерфейсом прописываются в файле `scripts/hud.lua` - -```lua -function on_hud_open(playerid: int) -``` - -Вызывается после входа в мир, когда становится доступна библиотека hud. Здесь на экран добавляются постоянные элементы. - -```lua -function on_hud_close(playerid: int) -``` - -Вызывается при выходе из мира, перед его сохранением. - ## Библиотеки движка ### time @@ -504,25 +384,3 @@ time.uptime() -> float ``` Возвращает время с момента запуска движка в секундах - -## Доступные модули - -### TOML сериализация/десериализация - -```lua -local toml = require "core:toml" - -local t = {a=53, b=42, s="test", sub={x=1, y=6}} -local s = toml.serialize(t) -print(s) -local t2 = toml.deserialize(s) -``` -вывод: -```toml -b = 42 -s = "test" -a = 53 -[sub] -y = 6 -x = 1 -``` diff --git a/doc/ru/События-движка.md b/doc/ru/События-движка.md new file mode 100644 index 00000000..ecfd2db9 --- /dev/null +++ b/doc/ru/События-движка.md @@ -0,0 +1,126 @@ +# События движка + +## События блоков + +Функции для обработки событий, прописываемые в скрипте блока. + +```lua +function on_placed(x, y, z, playerid) +``` + +Вызывается после установки блока игроком + +```lua +function on_broken(x, y, z, playerid) +``` + +Вызывается после разрушения блока игроком + +```lua +function on_interact(x, y, z, playerid) -> bool +``` + +Вызывается при нажатии на блок ПКМ. Предотвращает установку блоков, если возвращает `true` + +```lua +function on_update(x, y, z) +``` + +Вызывается при обновлении блока (если изменился соседний блок) + +```lua +function on_random_update(x, y, z) +``` + +Вызывается в случайные моменты времени (рост травы на блоках земли) + +```lua +function on_blocks_tick(tps: int) +``` + +Вызывается tps (20) раз в секунду + +## События предметов + +Функции для обработки событий, прописываемые в скрипте предмета. + +```lua +function on_use(playerid: int) +``` + +Вызывается при нажатии ПКМ не на блок. + +```lua + +function on_use_on_block(x: int, y: int, z: int, playerid: int) + +``` + +Вызывается при нажатии ПКМ на блок. Предотвращает установку блока, прописанного в `placing-block` если возвращает `true` + +```lua +function on_block_break_by(x: int, y: int, z: int, playerid: int) +``` + +Вызывается при нажатии ЛКМ на блок (в т.ч неразрушимый). Предотвращает разрушение блока, если возвращает `true` + +## События мира + +События мира для контент-пака прописываются в `scripts/world.lua` + +```lua +function on_world_open() +``` + +Вызывается при загрузке мира + +```lua +function on_world_save() +``` + +Вызывается перед сохранением мира + +```lua +function on_world_tick() +``` + +Вызывается 20 раз в секунду + +```lua +function on_world_quit() +``` + +Вызывается при выходе из мира (после сохранения) +## События макета + +События прописываются в файле `layouts/имя_макета.xml.lua`. + +```lua +function on_open(invid: int, x: int, y: int, z: int) +``` + +Вызывается при добавлении элемента на экран. +- При отсутствии привязки к инвентарю invid будет равен 0. +- При отсутствии привязки к блоку x, y, z так же будут равны 0. + +```lua +function on_close(invid: int) +``` + +Вызывается при удалении элемента с экрана. + +## События HUD + +События связанные с игровым интерфейсом прописываются в файле `scripts/hud.lua` + +```lua +function on_hud_open(playerid: int) +``` + +Вызывается после входа в мир, когда становится доступна библиотека hud. Здесь на экран добавляются постоянные элементы. + +```lua +function on_hud_close(playerid: int) +``` + +Вызывается при выходе из мира, перед его сохранением. From e8982353ccb47d5ceea618b9979e06f2643b1997 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 16:32:56 +0300 Subject: [PATCH 58/97] added block.caption(blockid) -> str --- src/logic/scripting/lua/libblock.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 0bc509fc..08543d7e 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -16,7 +16,7 @@ int l_block_name(lua_State* L) { auto indices = scripting::content->getIndices(); lua_Integer id = lua_tointeger(L, 1); - if (id < 0 || size_t(id) >= indices->countBlockDefs()) { + if (static_cast(id) >= indices->countBlockDefs()) { return 0; } auto def = indices->getBlockDef(id); @@ -27,7 +27,7 @@ int l_block_name(lua_State* L) { int l_block_material(lua_State* L) { auto indices = scripting::content->getIndices(); lua_Integer id = lua_tointeger(L, 1); - if (id < 0 || size_t(id) >= indices->countBlockDefs()) { + if (static_cast(id) >= indices->countBlockDefs()) { return 0; } auto def = indices->getBlockDef(id); @@ -62,7 +62,7 @@ int l_set_block(lua_State* L) { lua_Integer id = lua_tointeger(L, 4); lua_Integer state = lua_tointeger(L, 5); bool noupdate = lua_toboolean(L, 6); - if (id < 0 || size_t(id) >= scripting::indices->countBlockDefs()) { + if (static_cast(id) >= scripting::indices->countBlockDefs()) { return 0; } if (!scripting::level->chunks->get(x, y, z)) { @@ -70,8 +70,9 @@ int l_set_block(lua_State* L) { } scripting::level->chunks->set(x, y, z, id, int2blockstate(state)); scripting::level->lighting->onBlockSet(x,y,z, id); - if (!noupdate) + if (!noupdate) { scripting::blocks->updateSides(x, y, z); + } return 0; } @@ -236,6 +237,17 @@ int l_is_replaceable_at(lua_State* L) { return 1; } +int l_get_caption(lua_State* L) { + auto indices = scripting::content->getIndices(); + lua_Integer id = lua_tointeger(L, 1); + if (static_cast(id) >= indices->countBlockDefs()) { + return 0; + } + auto def = indices->getBlockDef(id); + lua_pushstring(L, def->caption.c_str()); + return 1; +} + const luaL_Reg blocklib [] = { {"index", lua_wrap_errors}, {"name", lua_wrap_errors}, From 3650e33f4c1f2a454ce5b29bc8836367192491bd Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 16:33:15 +0300 Subject: [PATCH 59/97] fix --- src/logic/scripting/lua/libblock.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 08543d7e..22e76b84 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -237,7 +237,7 @@ int l_is_replaceable_at(lua_State* L) { return 1; } -int l_get_caption(lua_State* L) { +int l_block_caption(lua_State* L) { auto indices = scripting::content->getIndices(); lua_Integer id = lua_tointeger(L, 1); if (static_cast(id) >= indices->countBlockDefs()) { @@ -252,6 +252,7 @@ const luaL_Reg blocklib [] = { {"index", lua_wrap_errors}, {"name", lua_wrap_errors}, {"material", lua_wrap_errors}, + {"caption", lua_wrap_errors}, {"defs_count", lua_wrap_errors}, {"is_solid_at", lua_wrap_errors}, {"is_replaceable_at", lua_wrap_errors}, From 55815a53f01cb002a2eebb864c1e6c06153994cf Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 16:54:03 +0300 Subject: [PATCH 60/97] =?UTF-8?q?update=20doc/ru/8.=D0=A1=D0=BA=D1=80?= =?UTF-8?q?=D0=B8=D0=BF=D1=82=D0=B8=D0=BD=D0=B3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/8.Скриптинг.md | 103 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 7 deletions(-) diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index ec066f4a..91e1159b 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -2,11 +2,7 @@ В качестве языка сценариев используется LuaJIT -## Функции, доступные в скриптах - ```lua -load_script("контентпак:scripts/имя_скрипта.lua") -- загружает скрипт, если ещё не загружен -load_script("контентпак:scripts/имя_скрипта.lua", true) -- перезагружает скрипт require "контентпак:имя_модуля" -- загружает lua модуль из папки modules (расширение не указывается) ``` @@ -77,8 +73,23 @@ player.set_noclip(bool) Геттер и сеттер noclip режима (выключенная коллизия игрока) +```python +player.get_selected_block(playerid: int) -> x,y,z +``` + +Возвращает координаты выделенного блока, либо nil + ## Библиотека world +```python +world.get_list() -> массив таблиц { + name: str, + icon: str +} +``` + +Возвращает информацию о мирах: название и предпросмотр (автоматически загружаемая текстура). + ```python world.get_day_time() -> number ``` @@ -103,6 +114,12 @@ world.get_seed() -> int Возвращает зерно мира. +```python +world.exists() -> bool +``` + +Проверяет существование мира по имени. + ## Библиотека pack ```python @@ -123,6 +140,38 @@ pack.get_installed() -> массив строк Возращает id всех установленных в мире контент-паков +```python +pack.get_available() -> массив строк +``` + +Возвращает id всех доступных, но не установленных в мире контент-паков + +```python +pack.get_base_packs() -> массив строк +``` + +Возвращает id всех базовых паков (неудаляемых) + +```python +pack.get_info(packid: str) -> { + id: str, + title: str, + creator: str, + description: str, + version: str, + icon: str, + dependencies: опциональный массив строк +} +``` + +Возвращает информацию о паке (не обязательно установленном). +- icon - название текстуры предпросмотра (загружается автоматически) +- dependencies - строки в формате `{lvl}{id}`, где lvl: + - `!` - required + - `?` - optional + - `~` - weak + например `!teal` + ## Библиотека gui Библиотека содержит функции для доступа к свойствам UI элементов. Вместо gui следует использовать объектную обертку, предоставляющую доступ к свойствам через мета-методы __index, __newindex: @@ -134,6 +183,12 @@ indentory_doc.some_button.text = "new text" В скрипте макета `layouts/файл_макета.xml` - `layouts/файл_макета.xml.lua` уже доступна переменная **document** содержащая объект класса Document +```python +gui.str(text: str, context: str) -> str +``` + +Возращает переведенный текст. + ## Библиотека inventory Библиотека функций для работы с инвентарем. @@ -211,6 +266,18 @@ block.index(name: str) -> int Возвращает числовой id блока, принимая в качестве агрумента строковый +```python +block.material(blockid: int) -> str +``` + +Возвращает id материала блока. + +```python +block.caption(blockid: int) -> str +``` + +Возвращает название блока, отображаемое в интерфейсе. + ```python block.get(x: int, y: int, z: int) -> int ``` @@ -373,14 +440,36 @@ hud.close(layoutid: str) hud.get_block_inventory() -> int ``` -Получить ID инвентаря открытого блока или 0 +Дает ID инвентаря открытого блока или 0 -## Библиотеки движка +```python +hud.get_player() -> int +``` -### time +Дает ID игрока, к которому привязан пользовательский интерфейс + +```python +hud.pause() +``` + +Открывает меню паузы + +```python +hud.resume() +``` + +Закрывает меню паузы. + +## Библиотека time ```python time.uptime() -> float ``` Возвращает время с момента запуска движка в секундах + +```python +time.delta() -> float +``` + +Возвращает дельту времени (время прошедшее с предыдущего кадра) From 7f58a38454a2e17dff3d6f5c346a010fc8012993 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 17:06:44 +0300 Subject: [PATCH 61/97] =?UTF-8?q?update=20doc/ru/8.=D0=A1=D0=BA=D1=80?= =?UTF-8?q?=D0=B8=D0=BF=D1=82=D0=B8=D0=BD=D0=B3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/8.Скриптинг.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/doc/ru/8.Скриптинг.md b/doc/ru/8.Скриптинг.md index 91e1159b..f5ba82c2 100644 --- a/doc/ru/8.Скриптинг.md +++ b/doc/ru/8.Скриптинг.md @@ -189,6 +189,27 @@ gui.str(text: str, context: str) -> str Возращает переведенный текст. +```python +gui.get_viewport() -> {int, int} +``` + +Возвращает размер главного контейнера (окна). + +```python +gui.get_env(document: str) -> table +``` + +Возвращает окружение (таблица глобальных переменных) указанного документа. + +```python +get_locales_info() -> таблица таблиц где + ключ - id локали в формате isolangcode_ISOCOUNTRYCODE + значение - таблица { + name: str # название локали на её языке + } +``` + +Возвращает информацию о всех загруженных локалях (res/texts/\*). ## Библиотека inventory Библиотека функций для работы с инвентарем. From fdd9ede9d5fa10b832d2ae095c59c7fcd5c5a896 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 17:33:55 +0300 Subject: [PATCH 62/97] serialization functions naming update --- doc/ru/Файловая-система-и-сериализация.md | 4 ++-- res/scripts/stdlib.lua | 2 ++ src/logic/scripting/lua/libjson.cpp | 4 ++-- src/logic/scripting/lua/libtoml.cpp | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/ru/Файловая-система-и-сериализация.md b/doc/ru/Файловая-система-и-сериализация.md index 9cbe10b8..ec403a80 100644 --- a/doc/ru/Файловая-система-и-сериализация.md +++ b/doc/ru/Файловая-система-и-сериализация.md @@ -78,7 +78,7 @@ file.mkdirs(путь: str) -> bool Библиотека содержит функции для сериализации и десериализации таблиц: ```python -json.stringify(object: table, human_readable: bool=false) -> str +json.tostring(object: table, human_readable: bool=false) -> str ``` Сериализует объект в JSON строку. При значении второго параметра **true** будет использовано многострочное форматирование, удобное для чтения человеком, а не компактное, использующееся по-умолчанию. @@ -94,7 +94,7 @@ json.parse(code: str) -> table Библиотека содержит функции для сериализации и десериализации таблиц: ```python -toml.stringify(object: table) -> str +toml.tostring(object: table) -> str ``` Сериализует объект в TOML строку. diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 877d38a4..4a631ae1 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -302,3 +302,5 @@ get_block_rotation = block.get_rotation set_block_rotation = block.set_rotation get_block_user_bits = block.get_user_bits set_block_user_bits = block.set_user_bits +toml.serialize = toml.tostring +toml.deserialize = toml.parse diff --git a/src/logic/scripting/lua/libjson.cpp b/src/logic/scripting/lua/libjson.cpp index d868d2da..7d3be119 100644 --- a/src/logic/scripting/lua/libjson.cpp +++ b/src/logic/scripting/lua/libjson.cpp @@ -23,14 +23,14 @@ static int l_json_stringify(lua_State* L) { } static int l_json_parse(lua_State* L) { - auto string = lua_tostring(L, 1); + auto string = scripting::state->requireString(1); auto element = json::parse("", string); scripting::state->pushvalue(element); return 1; } const luaL_Reg jsonlib [] = { - {"stringify", lua_wrap_errors}, + {"tostring", lua_wrap_errors}, {"parse", lua_wrap_errors}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libtoml.cpp b/src/logic/scripting/lua/libtoml.cpp index 4bb4a123..86411d42 100644 --- a/src/logic/scripting/lua/libtoml.cpp +++ b/src/logic/scripting/lua/libtoml.cpp @@ -31,7 +31,7 @@ static int l_toml_parse(lua_State*) { } const luaL_Reg tomllib [] = { - {"serialize", lua_wrap_errors}, - {"deserialize", lua_wrap_errors}, + {"tostring", lua_wrap_errors}, + {"parse", lua_wrap_errors}, {NULL, NULL} }; From eca050123dfc3e21e59b3d57937a5aabbcc6d769 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 17:44:57 +0300 Subject: [PATCH 63/97] file.find fix + input.mousecode --- src/logic/scripting/lua/libfile.cpp | 8 ++++++-- src/logic/scripting/lua/libinput.cpp | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index b14a15b4..f462928e 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -17,8 +17,12 @@ static fs::path resolve_path(lua_State*, const std::string& path) { static int l_file_find(lua_State* L) { std::string path = lua_tostring(L, 1); - lua_pushstring(L, scripting::engine->getResPaths()->findRaw(path).c_str()); - return 1; + try { + lua_pushstring(L, scripting::engine->getResPaths()->findRaw(path).c_str()); + return 1; + } catch (const std::runtime_error& err) { + return 0; + } } static int l_file_resolve(lua_State* L) { diff --git a/src/logic/scripting/lua/libinput.cpp b/src/logic/scripting/lua/libinput.cpp index beb2c5de..ed415a16 100644 --- a/src/logic/scripting/lua/libinput.cpp +++ b/src/logic/scripting/lua/libinput.cpp @@ -25,6 +25,12 @@ static int l_keycode(lua_State* L) { return 1; } +static int l_mousecode(lua_State* L) { + const char* name = state->requireString(1); + lua_pushinteger(L, static_cast(input_util::mousecode_from(name))); + return 1; +} + static int l_add_callback(lua_State* L) { auto bindname = state->requireString(1); const auto& bind = Events::bindings.find(bindname); @@ -51,6 +57,7 @@ static int l_get_mouse_pos(lua_State* L) { const luaL_Reg inputlib [] = { {"keycode", lua_wrap_errors}, + {"mousecode", lua_wrap_errors}, {"add_callback", lua_wrap_errors}, {"get_mouse_pos", lua_wrap_errors}, {NULL, NULL} From b7887fa1ca2b0bc5b2d394ae5bbfe351b63b728f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 17:51:32 +0300 Subject: [PATCH 64/97] file library error handling update --- src/logic/scripting/lua/libfile.cpp | 45 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index f462928e..b4ea5c19 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -1,5 +1,6 @@ #include "lua_commons.hpp" #include "api_lua.hpp" +#include "LuaState.hpp" #include "../scripting.hpp" #include "../../../engine.hpp" #include "../../../files/files.hpp" @@ -11,14 +12,20 @@ namespace fs = std::filesystem; +namespace scripting { + extern lua::LuaState* state; +} + +using namespace scripting; + static fs::path resolve_path(lua_State*, const std::string& path) { - return scripting::engine->getPaths()->resolve(path); + return engine->getPaths()->resolve(path); } static int l_file_find(lua_State* L) { - std::string path = lua_tostring(L, 1); + std::string path = state->requireString(1); try { - lua_pushstring(L, scripting::engine->getResPaths()->findRaw(path).c_str()); + lua_pushstring(L, engine->getResPaths()->findRaw(path).c_str()); return 1; } catch (const std::runtime_error& err) { return 0; @@ -26,13 +33,13 @@ static int l_file_find(lua_State* L) { } static int l_file_resolve(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); lua_pushstring(L, path.u8string().c_str()); return 1; } static int l_file_read(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); if (fs::is_regular_file(path)) { lua_pushstring(L, files::read_string(path).c_str()); return 1; @@ -41,14 +48,14 @@ static int l_file_read(lua_State* L) { } static int l_file_write(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - const char* text = lua_tostring(L, 2); + fs::path path = resolve_path(L, state->requireString(1)); + auto text = state->requireString(2); files::write_string(path, text); return 1; } static int l_file_remove(lua_State* L) { - std::string rawpath = lua_tostring(L, 1); + std::string rawpath = state->requireString(1); fs::path path = resolve_path(L, rawpath); auto entryPoint = rawpath.substr(0, rawpath.find(':')); if (entryPoint != "world") { @@ -59,7 +66,7 @@ static int l_file_remove(lua_State* L) { } static int l_file_remove_tree(lua_State* L) { - std::string rawpath = lua_tostring(L, 1); + std::string rawpath = state->requireString(1); fs::path path = resolve_path(L, rawpath); auto entryPoint = rawpath.substr(0, rawpath.find(':')); if (entryPoint != "world") { @@ -70,25 +77,25 @@ static int l_file_remove_tree(lua_State* L) { } static int l_file_exists(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); lua_pushboolean(L, fs::exists(path)); return 1; } static int l_file_isfile(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); lua_pushboolean(L, fs::is_regular_file(path)); return 1; } static int l_file_isdir(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); lua_pushboolean(L, fs::is_directory(path)); return 1; } static int l_file_length(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); if (fs::exists(path)){ lua_pushinteger(L, fs::file_size(path)); } else { @@ -98,19 +105,19 @@ static int l_file_length(lua_State* L) { } static int l_file_mkdir(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); lua_pushboolean(L, fs::create_directory(path)); return 1; } static int l_file_mkdirs(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); lua_pushboolean(L, fs::create_directories(path)); return 1; } static int l_file_read_bytes(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); + fs::path path = resolve_path(L, state->requireString(1)); if (fs::is_regular_file(path)) { size_t length = static_cast(fs::file_size(path)); @@ -152,7 +159,7 @@ static int l_file_write_bytes(lua_State* L) { throw std::runtime_error("string expected"); } - fs::path path = resolve_path(L, lua_tostring(L, pathIndex)); + fs::path path = resolve_path(L, state->requireString(pathIndex)); std::vector bytes; @@ -167,7 +174,7 @@ static int l_file_write_bytes(lua_State* L) { } static int l_file_list_all_res(lua_State* L, const std::string& path) { - auto files = scripting::engine->getResPaths()->listdirRaw(path); + auto files = engine->getResPaths()->listdirRaw(path); lua_createtable(L, files.size(), 0); for (size_t i = 0; i < files.size(); i++) { lua_pushstring(L, files[i].c_str()); @@ -177,7 +184,7 @@ static int l_file_list_all_res(lua_State* L, const std::string& path) { } static int l_file_list(lua_State* L) { - std::string dirname = lua_tostring(L, 1); + std::string dirname = state->requireString(1); if (dirname.find(':') == std::string::npos) { return l_file_list_all_res(L, dirname); } From 06e9d60bae86d6aafc08455fa697eab149e47db4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 17:56:29 +0300 Subject: [PATCH 65/97] =?UTF-8?q?update=20doc/ru/=D0=A4=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=8F-=D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC?= =?UTF-8?q?=D0=B0-=D0=B8-=D1=81=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/Файловая-система-и-сериализация.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/ru/Файловая-система-и-сериализация.md b/doc/ru/Файловая-система-и-сериализация.md index ec403a80..ed350048 100644 --- a/doc/ru/Файловая-система-и-сериализация.md +++ b/doc/ru/Файловая-система-и-сериализация.md @@ -73,6 +73,24 @@ file.mkdirs(путь: str) -> bool Создает всю цепочку директорий. Возвращает true если были созданы директории. +```python +file.find(путь: str) -> str +``` + +Ищет файл от последнего пака до res. Путь указывается без префикса. Возвращает путь с нужным префиксом. Если файл не найден, возвращает nil. + +```python +file.remove(путь: str) -> bool +``` + +Удаляет файл. Возращает **true** если файл существовал. Бросает исключение при нарушении доступа. + +```python +file.remove_tree(путь: str) -> int +``` + +Рекурсивно удаляет файлы. Возвращает число удаленных файлов. + ## Библиотека json Библиотека содержит функции для сериализации и десериализации таблиц: From db074b13be3c9350c012660fddca1bb7fc954df8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 18:06:09 +0300 Subject: [PATCH 66/97] core.get_bindings moved to input.get_bindings --- res/layouts/pages/settings_controls.xml.lua | 2 +- src/logic/scripting/lua/libcore.cpp | 14 -------------- src/logic/scripting/lua/libinput.cpp | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/res/layouts/pages/settings_controls.xml.lua b/res/layouts/pages/settings_controls.xml.lua index 879f21e5..c7c8632c 100644 --- a/res/layouts/pages/settings_controls.xml.lua +++ b/res/layouts/pages/settings_controls.xml.lua @@ -16,7 +16,7 @@ function on_open() refresh_sensitivity() local panel = document.bindings_panel - local bindings = core.get_bindings() + local bindings = input.get_bindings() table.sort(bindings, function(a, b) return a > b end) for i,name in ipairs(bindings) do panel:add(gui.template("binding", { diff --git a/src/logic/scripting/lua/libcore.cpp b/src/logic/scripting/lua/libcore.cpp index 86b4e9f6..b9df74f2 100644 --- a/src/logic/scripting/lua/libcore.cpp +++ b/src/logic/scripting/lua/libcore.cpp @@ -100,19 +100,6 @@ static int l_reconfig_packs(lua_State* L) { return 0; } -static int l_get_bindings(lua_State* L) { - auto& bindings = Events::bindings; - lua_createtable(L, bindings.size(), 0); - - int i = 0; - for (auto& entry : bindings) { - lua_pushstring(L, entry.first.c_str()); - lua_rawseti(L, -2, i + 1); - i++; - } - return 1; -} - static int l_get_setting(lua_State* L) { auto name = lua_tostring(L, 1); const auto value = scripting::engine->getSettingsHandler().getValue(name); @@ -186,7 +173,6 @@ const luaL_Reg corelib [] = { {"close_world", lua_wrap_errors}, {"delete_world", lua_wrap_errors}, {"reconfig_packs", lua_wrap_errors}, - {"get_bindings", lua_wrap_errors}, {"get_setting", lua_wrap_errors}, {"set_setting", lua_wrap_errors}, {"str_setting", lua_wrap_errors}, diff --git a/src/logic/scripting/lua/libinput.cpp b/src/logic/scripting/lua/libinput.cpp index ed415a16..d870509c 100644 --- a/src/logic/scripting/lua/libinput.cpp +++ b/src/logic/scripting/lua/libinput.cpp @@ -55,11 +55,25 @@ static int l_get_mouse_pos(lua_State* L) { return lua::pushvec2_arr(L, Events::cursor); } +static int l_get_bindings(lua_State* L) { + auto& bindings = Events::bindings; + lua_createtable(L, bindings.size(), 0); + + int i = 0; + for (auto& entry : bindings) { + lua_pushstring(L, entry.first.c_str()); + lua_rawseti(L, -2, i + 1); + i++; + } + return 1; +} + const luaL_Reg inputlib [] = { {"keycode", lua_wrap_errors}, {"mousecode", lua_wrap_errors}, {"add_callback", lua_wrap_errors}, {"get_mouse_pos", lua_wrap_errors}, + {"get_bindings", lua_wrap_errors}, {NULL, NULL} }; From 5f00cf0d5b3b9d984fbe6b7a596d4fcb272c51a7 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 18:16:20 +0300 Subject: [PATCH 67/97] file.exists, file.isfile, file.isdir nothrow now --- src/logic/scripting/lua/libfile.cpp | 64 +++++++++++++++-------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index b4ea5c19..23193857 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -18,10 +18,17 @@ namespace scripting { using namespace scripting; -static fs::path resolve_path(lua_State*, const std::string& path) { +static fs::path resolve_path(const std::string& path) { return engine->getPaths()->resolve(path); } +static fs::path resolve_path_soft(const std::string& path) { + if (path.find(':') == std::string::npos) { + return path; + } + return resolve_path(path); +} + static int l_file_find(lua_State* L) { std::string path = state->requireString(1); try { @@ -33,13 +40,13 @@ static int l_file_find(lua_State* L) { } static int l_file_resolve(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); + fs::path path = resolve_path(state->requireString(1)); lua_pushstring(L, path.u8string().c_str()); return 1; } static int l_file_read(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); + fs::path path = resolve_path(state->requireString(1)); if (fs::is_regular_file(path)) { lua_pushstring(L, files::read_string(path).c_str()); return 1; @@ -47,55 +54,50 @@ static int l_file_read(lua_State* L) { throw std::runtime_error("file does not exists "+util::quote(path.u8string())); } -static int l_file_write(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); +static int l_file_write(lua_State*) { + fs::path path = resolve_path(state->requireString(1)); auto text = state->requireString(2); files::write_string(path, text); return 1; } -static int l_file_remove(lua_State* L) { +static int l_file_remove(lua_State*) { std::string rawpath = state->requireString(1); - fs::path path = resolve_path(L, rawpath); + fs::path path = resolve_path(rawpath); auto entryPoint = rawpath.substr(0, rawpath.find(':')); if (entryPoint != "world") { throw std::runtime_error("access denied"); } - lua_pushboolean(L, fs::remove(path)); - return 1; + return state->pushboolean(fs::remove(path)); } -static int l_file_remove_tree(lua_State* L) { +static int l_file_remove_tree(lua_State*) { std::string rawpath = state->requireString(1); - fs::path path = resolve_path(L, rawpath); + fs::path path = resolve_path(rawpath); auto entryPoint = rawpath.substr(0, rawpath.find(':')); if (entryPoint != "world") { throw std::runtime_error("access denied"); } - lua_pushinteger(L, fs::remove_all(path)); - return 1; + return state->pushinteger(fs::remove_all(path)); } -static int l_file_exists(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); - lua_pushboolean(L, fs::exists(path)); - return 1; +static int l_file_exists(lua_State*) { + fs::path path = resolve_path_soft(state->requireString(1)); + return state->pushboolean(fs::exists(path)); } -static int l_file_isfile(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); - lua_pushboolean(L, fs::is_regular_file(path)); - return 1; +static int l_file_isfile(lua_State*) { + fs::path path = resolve_path_soft(state->requireString(1)); + return state->pushboolean(fs::is_regular_file(path)); } -static int l_file_isdir(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); - lua_pushboolean(L, fs::is_directory(path)); - return 1; +static int l_file_isdir(lua_State*) { + fs::path path = resolve_path_soft(state->requireString(1)); + return state->pushboolean(fs::is_directory(path)); } static int l_file_length(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); + fs::path path = resolve_path(state->requireString(1)); if (fs::exists(path)){ lua_pushinteger(L, fs::file_size(path)); } else { @@ -105,19 +107,19 @@ static int l_file_length(lua_State* L) { } static int l_file_mkdir(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); + fs::path path = resolve_path(state->requireString(1)); lua_pushboolean(L, fs::create_directory(path)); return 1; } static int l_file_mkdirs(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); + fs::path path = resolve_path(state->requireString(1)); lua_pushboolean(L, fs::create_directories(path)); return 1; } static int l_file_read_bytes(lua_State* L) { - fs::path path = resolve_path(L, state->requireString(1)); + fs::path path = resolve_path(state->requireString(1)); if (fs::is_regular_file(path)) { size_t length = static_cast(fs::file_size(path)); @@ -159,7 +161,7 @@ static int l_file_write_bytes(lua_State* L) { throw std::runtime_error("string expected"); } - fs::path path = resolve_path(L, state->requireString(pathIndex)); + fs::path path = resolve_path(state->requireString(pathIndex)); std::vector bytes; @@ -188,7 +190,7 @@ static int l_file_list(lua_State* L) { if (dirname.find(':') == std::string::npos) { return l_file_list_all_res(L, dirname); } - fs::path path = resolve_path(L, dirname); + fs::path path = resolve_path(dirname); if (!fs::is_directory(path)) { throw std::runtime_error(util::quote(path.u8string())+" is not a directory"); } From 57fd91b4175123a0186a5dfbdf40da1fbb08df4d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 18:23:00 +0300 Subject: [PATCH 68/97] file.exists, ... completely nothrow --- src/files/engine_paths.cpp | 7 +++++-- src/files/engine_paths.hpp | 2 +- src/logic/scripting/lua/libfile.cpp | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/files/engine_paths.cpp b/src/files/engine_paths.cpp index 0df0afec..15e80325 100644 --- a/src/files/engine_paths.cpp +++ b/src/files/engine_paths.cpp @@ -139,7 +139,7 @@ static fs::path toCanonic(fs::path path) { return path; } -fs::path EnginePaths::resolve(std::string path) { +fs::path EnginePaths::resolve(std::string path, bool throwErr) { size_t separator = path.find(':'); if (separator == std::string::npos) { throw files_access_error("no entry point specified"); @@ -165,7 +165,10 @@ fs::path EnginePaths::resolve(std::string path) { } } } - throw files_access_error("unknown entry point '"+prefix+"'"); + if (throwErr) { + throw files_access_error("unknown entry point '"+prefix+"'"); + } + return fs::path(filename); } ResPaths::ResPaths(fs::path mainRoot, std::vector roots) diff --git a/src/files/engine_paths.hpp b/src/files/engine_paths.hpp index f507aebf..92353e65 100644 --- a/src/files/engine_paths.hpp +++ b/src/files/engine_paths.hpp @@ -40,7 +40,7 @@ public: std::vector scanForWorlds(); - fs::path resolve(std::string path); + fs::path resolve(std::string path, bool throwErr=true); }; struct PathsRoot { diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index 23193857..6b97da3c 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -26,7 +26,7 @@ static fs::path resolve_path_soft(const std::string& path) { if (path.find(':') == std::string::npos) { return path; } - return resolve_path(path); + return engine->getPaths()->resolve(path, false); } static int l_file_find(lua_State* L) { From 15bb6d998d026cb1e3f379ef60472ce992578fb1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 19:04:34 +0300 Subject: [PATCH 69/97] =?UTF-8?q?added=20doc/ru/=D0=9F=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D0=BA?= =?UTF-8?q?=D0=B8=D0=B9-=D0=B2=D0=B2=D0=BE=D0=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/Пользовательский-ввод.md | 59 +++++++++++++++++++++++++++++++++ src/window/input.md | 9 ----- 2 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 doc/ru/Пользовательский-ввод.md delete mode 100644 src/window/input.md diff --git a/doc/ru/Пользовательский-ввод.md b/doc/ru/Пользовательский-ввод.md new file mode 100644 index 00000000..b2397478 --- /dev/null +++ b/doc/ru/Пользовательский-ввод.md @@ -0,0 +1,59 @@ +# Пользовательский ввод + +Обработка нажатий клавиш и кнопок мыши обрабатываются через привязки (bindings), которые назначаются в паке, в файле `config/bindings.toml` в формате: + +```toml +packid.binding.name="inputtype:codename" +``` + +- packid - опционально, но желательно +- inputtype - key или mouse +- codename - имя клавиши или кнопки мыши (left/right/middle) + +## Имена клавиш + +- space, backspace, tab, enter, caps-lock, escape +- left-ctrl, left-shift, left-alt, left-super +- right-ctrl, right-shift, right-alt, right-alt +- delete, home, end, insert, page-up, page-down +- left, right, down, up +- a..z +- 0..9 +- f1..f25 + +## Библиотека input + +```python +input.keycode(keyname: str) -> int +``` + +Возвращает код клавиши по имени, либо -1 + +```python +input.mousecode(mousename: str) -> int +``` + +Возвращает код кнопки мыши по имени, либо -1 + +```python +input.add_callback(bindname: str, callback: function) +``` + +Назначает функцию, которая будет вызываться при активации привязки. Пример: +```lua +input.add_callback("hud.inventory", function () + print("Inventory open key pressed") +end) +``` + +```python +input.get_mouse_pos() -> {int, int} +``` + +Возвращает позицию курсора на экране. + +```python +input.get_bindings() -> массив строк +``` + +Возвращает названия всех доступных привязок. diff --git a/src/window/input.md b/src/window/input.md deleted file mode 100644 index aa1829bd..00000000 --- a/src/window/input.md +++ /dev/null @@ -1,9 +0,0 @@ -## Key Names -- space, backspace, tab, enter, caps-lock, escape -- left-ctrl, left-shift, left-alt, left-super -- right-ctrl, right-shift, right-alt, right-alt -- delete, home, end, insert, page-up, page-down -- left, right, down, up -- a..z -- 0..9 -- f1..f25 From 7097136cd33f067086cb81132abab333f5329120 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 19:25:08 +0300 Subject: [PATCH 70/97] grass_block.lua update to new api --- res/content/base/scripts/grass_block.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/res/content/base/scripts/grass_block.lua b/res/content/base/scripts/grass_block.lua index d92813c4..e58597cc 100644 --- a/res/content/base/scripts/grass_block.lua +++ b/res/content/base/scripts/grass_block.lua @@ -1,15 +1,15 @@ function on_random_update(x, y, z) - local dirtid = block_index('base:dirt'); - if is_solid_at(x, y+1, z) then - set_block(x, y, z, dirtid, 0) + local dirtid = block.index('base:dirt'); + if block.is_solid_at(x, y+1, z) then + block.set(x, y, z, dirtid, 0) else - local grassblockid = block_index('base:grass_block') + local grassblockid = block.index('base:grass_block') for lx=-1,1 do for ly=-1,1 do for lz=-1,1 do - if get_block(x + lx, y + ly, z + lz) == dirtid then - if not is_solid_at(x + lx, y + ly + 1, z + lz) then - set_block(x + lx, y + ly, z + lz, grassblockid, 0) + if block.get(x + lx, y + ly, z + lz) == dirtid then + if not block.is_solid_at(x + lx, y + ly + 1, z + lz) then + block.set(x + lx, y + ly, z + lz, grassblockid, 0) return end end From 1935b3099af909c0aab8569d165393fc7e9fb62b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 19:33:14 +0300 Subject: [PATCH 71/97] =?UTF-8?q?Update=20=D0=9F=D0=BE=D0=BB=D1=8C=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D0=BA=D0=B8?= =?UTF-8?q?=D0=B9-=D0=B2=D0=B2=D0=BE=D0=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/Пользовательский-ввод.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ru/Пользовательский-ввод.md b/doc/ru/Пользовательский-ввод.md index b2397478..e113b3b1 100644 --- a/doc/ru/Пользовательский-ввод.md +++ b/doc/ru/Пользовательский-ввод.md @@ -14,7 +14,7 @@ packid.binding.name="inputtype:codename" - space, backspace, tab, enter, caps-lock, escape - left-ctrl, left-shift, left-alt, left-super -- right-ctrl, right-shift, right-alt, right-alt +- right-ctrl, right-shift, right-alt, right-super - delete, home, end, insert, page-up, page-down - left, right, down, up - a..z From fd939940307b9df3b2bd0b3cb6872c1d04bcab2a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 3 Jun 2024 22:54:05 +0300 Subject: [PATCH 72/97] 0.20 compatibility fix --- res/modules/toml.lua | 2 ++ res/scripts/stdlib.lua | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/modules/toml.lua b/res/modules/toml.lua index 33c8faf1..3b66790c 100644 --- a/res/modules/toml.lua +++ b/res/modules/toml.lua @@ -1,2 +1,4 @@ print("WARNING: toml is replaced with built-in library, just remove 'require \"core:toml\"'") +toml.serialize = toml.tostring +toml.deserialize = toml.parse return toml diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 4a631ae1..877d38a4 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -302,5 +302,3 @@ get_block_rotation = block.get_rotation set_block_rotation = block.set_rotation get_block_user_bits = block.get_user_bits set_block_user_bits = block.set_user_bits -toml.serialize = toml.tostring -toml.deserialize = toml.parse From 5e4dab1b6b887550e03638ec1b3604ff3890874c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Jun 2024 10:49:46 +0300 Subject: [PATCH 73/97] =?UTF-8?q?added=20doc/ru/=D0=9A=D0=BE=D0=BD=D1=81?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/Консоль.md | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 doc/ru/Консоль.md diff --git a/doc/ru/Консоль.md b/doc/ru/Консоль.md new file mode 100644 index 00000000..a279be61 --- /dev/null +++ b/doc/ru/Консоль.md @@ -0,0 +1,109 @@ +# Консоль + +Для работы с командным интерпретатором предоставляется библиотека **console** + +## Создание команд + +Для создания команды консоли используется следующая функция: + +```python +console.add_command(схема: str, исполнитель: function) +``` + +Схема имеет следующий синтаксис: + +``` +название позиционные параметры {именованные параметры} +``` + +Название может содержать: +- латинницу +- цифры (кроме первого символа) +- `.`, `_`, `-` + +Позиционные параметры разделяются пробелами и имеют следующий синтаксис: + +``` +название:тип (вариант 1) +название:тип=по-умолчанию (вариант 2) +название:тип~центральное-значение (вариант 3) +название:тип=по-умолчанию~центральное-значение (вариант 4) +``` + +Доступные типы: +- **int** - целое число +- **num** - дробное число +- **str** - строка +- **sel** - селектор (id объекта представленный целым числом) +- **enum** - перечисление + +На вариантах 3 и 4 показан оператор `~` позволяющий использовать относительные значения. *Центральное значение* - значение, относительно которого будет указываться пользовательское. Например позиция игрока. + +Относительный оператор работает только с числами (num или int) + +В качестве центральных значений могут указываться переменные, назначаемые через **console.set**. + +Пример: + +```python +x:num~pos.x +``` + +Переменные можно указывать и в качестве значений по-умолчанию, при использовании префикса `$`: + +```python +t:int=$time +``` + +Перечисления указывазываются в формате: + +```python +mode:[replace|destruct|none] +``` + +Либо через переменную: + +```python +mode:enum $modes +``` + +Селекторы указываются с префиксом `@`. На данный момент являются заглушкой, по причине отсутствия объектной модели. Следует делать опциональными и использовать переменные: + +```python +obj:sel=$obj.id # obj.id - id игрока +``` + +Именованные аргументы указываются в специальном блоке, ограниченном фигурными скобками `{ }` по той же схеме. + +Пример: + +```python +eval name:str="World" {greeting:str='Hello'} +``` + +## Примеры схем команд + +Схемы существующих команд можно найти в файле `res/script/stdcmd.lua`. + +Пример - команда **tp**: + +```python +tp obj:sel=$obj.id x:num~pos.x y:num~pos.y z:num~pos.z +``` + +Полный lua код создания команды: + +```lua +console.add_command( + "tp obj:sel=$obj.id x:num~pos.x y:num~pos.y z:num~pos.z", + "Teleport object", + function (args, kwargs) + player.set_pos(unpack(args)) + end +) +``` + +- В args передаются готовые значения позиционных аргументов. +- В kwargs передается таблица значений именованных аргументов. + +Проверку и приведение типов интерпретатор команд производит автоматически. From df2c024a3e5729ca52493d45a16076a2ccb83b4a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Jun 2024 12:44:33 +0300 Subject: [PATCH 74/97] settings tooltips --- res/layouts/pages/settings_graphics.xml.lua | 17 ++++++++++------- res/layouts/templates/track_setting.xml | 2 +- res/texts/en_US.txt | 4 ++++ res/texts/ru_RU.txt | 4 ++++ src/graphics/ui/elements/CheckBox.hpp | 4 ++++ 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/res/layouts/pages/settings_graphics.xml.lua b/res/layouts/pages/settings_graphics.xml.lua index 835b3746..179d8df8 100644 --- a/res/layouts/pages/settings_graphics.xml.lua +++ b/res/layouts/pages/settings_graphics.xml.lua @@ -1,6 +1,7 @@ -function create_setting(id, name, step, postfix) +function create_setting(id, name, step, postfix, tooltip) local info = core.get_setting_info(id) postfix = postfix or "" + tooltip = tooltip or "" document.root:add(gui.template("track_setting", { id=id, name=gui.str(name, "settings"), @@ -8,7 +9,8 @@ function create_setting(id, name, step, postfix) min=info.min, max=info.max, step=step, - postfix=postfix + postfix=postfix, + tooltip=tooltip })) update_setting(core.get_setting(id), id, name, postfix) end @@ -24,10 +26,11 @@ function update_setting(x, id, name, postfix) ) end -function create_checkbox(id, name) +function create_checkbox(id, name, tooltip) + tooltip = tooltip or '' document.root:add(string.format( - "%s", - id, core.str_setting(id), gui.str(name, "settings") + "%s", + id, core.str_setting(id), gui.str(tooltip, "settings"), gui.str(name, "settings") )) end @@ -35,10 +38,10 @@ function on_open() create_setting("chunks.load-distance", "Load Distance", 1) create_setting("chunks.load-speed", "Load Speed", 1) create_setting("graphics.fog-curve", "Fog Curve", 0.1) - create_setting("graphics.gamma", "Gamma", 0.05) + create_setting("graphics.gamma", "Gamma", 0.05, "", "graphics.gamma.tooltip") create_setting("camera.fov", "FOV", 1, "°") create_checkbox("display.fullscreen", "Fullscreen") create_checkbox("display.vsync", "V-Sync") - create_checkbox("graphics.backlight", "Backlight") + create_checkbox("graphics.backlight", "Backlight", "graphics.backlight.tooltip") create_checkbox("camera.shaking", "Camera Shaking") end diff --git a/res/layouts/templates/track_setting.xml b/res/layouts/templates/track_setting.xml index 994e5bb3..82ee81c1 100644 --- a/res/layouts/templates/track_setting.xml +++ b/res/layouts/templates/track_setting.xml @@ -1,6 +1,6 @@ diff --git a/res/texts/en_US.txt b/res/texts/en_US.txt index 979c7330..8681a069 100644 --- a/res/texts/en_US.txt +++ b/res/texts/en_US.txt @@ -8,6 +8,10 @@ world.delete-confirm=Do you want to delete world forever? world.generators.default=Default world.generators.flat=Flat +# Tooltips +graphics.gamma.tooltip=Lighting brightness curve +graphics.backlight.tooltip=Backlight to prevent total darkness + # Bindings devtools.console=Console movement.forward=Forward diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index ec2946ef..a1b7f3be 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -12,6 +12,10 @@ error.pack-not-found=Не удалось найти пакет error.dependency-not-found=Используемая зависимость не найдена pack.remove-confirm=Удалить весь поставляемый паком/паками контент из мира (безвозвратно)? +# Подсказки +graphics.gamma.tooltip=Кривая яркости освещения +graphics.backlight.tooltip=Подсветка, предотвращающая полную темноту + # Меню menu.Apply=Применить menu.Audio=Звук diff --git a/src/graphics/ui/elements/CheckBox.hpp b/src/graphics/ui/elements/CheckBox.hpp index e366768e..74172337 100644 --- a/src/graphics/ui/elements/CheckBox.hpp +++ b/src/graphics/ui/elements/CheckBox.hpp @@ -50,6 +50,10 @@ namespace gui { virtual bool isChecked() const { return checkbox->isChecked(); } + + virtual void setTooltip(const std::wstring& text) override { + checkbox->setTooltip(text); + } }; } From 98abbfd838e6fa74fb3a167a0fc5348cfd7e2bc1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Jun 2024 12:47:16 +0300 Subject: [PATCH 75/97] checkbox tooltips fix --- src/graphics/ui/elements/CheckBox.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/ui/elements/CheckBox.hpp b/src/graphics/ui/elements/CheckBox.hpp index 74172337..cc0593c8 100644 --- a/src/graphics/ui/elements/CheckBox.hpp +++ b/src/graphics/ui/elements/CheckBox.hpp @@ -52,6 +52,7 @@ namespace gui { } virtual void setTooltip(const std::wstring& text) override { + Panel::setTooltip(text); checkbox->setTooltip(text); } }; From bfd726ae7b8c51b431ae5678d4661c9d98893999 Mon Sep 17 00:00:00 2001 From: Danila Artyukhov Date: Tue, 4 Jun 2024 14:23:49 +0300 Subject: [PATCH 76/97] MacOs app build workflow --- .github/workflows/macos.yml | 62 +++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 12 +++++++ 2 files changed, 74 insertions(+) create mode 100644 .github/workflows/macos.yml diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 00000000..89968a25 --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,62 @@ +name: MacOs DMG + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build-dmg: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + + - name: Install dependencies from brew + run: | + brew install glfw3 glew libpng openal-soft luajit libvorbis + + - name: Install specific version of GLM + run: | + curl -O https://raw.githubusercontent.com/Homebrew/homebrew-core/5c7655a866646aa4b857c002b8ae5465b9d26f65/Formula/g/glm.rb + brew install --formula glm.rb + + - name: Configure + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_APPDIR=1 + + - name: Build + run: cmake --build build -t install + + - name: Create macOS app structure + run: | + mkdir -p VoxelEngine.app/Contents/MacOS + mkdir -p VoxelEngine.app/Contents/Resources + cp build/VoxelEngine VoxelEngine.app/Contents/MacOS/ + cp -r res VoxelEngine.app/Contents/Resources/ + echo "" > VoxelEngine.app/Contents/Info.plist + echo "" >> VoxelEngine.app/Contents/Info.plist + echo "" >> VoxelEngine.app/Contents/Info.plist + echo "" >> VoxelEngine.app/Contents/Info.plist + echo " CFBundleExecutable" >> VoxelEngine.app/Contents/Info.plist + echo " VoxelEngine" >> VoxelEngine.app/Contents/Info.plist + echo " CFBundleIdentifier" >> VoxelEngine.app/Contents/Info.plist + echo " com.yourcompany.VoxelEngine" >> VoxelEngine.app/Contents/Info.plist + echo " CFBundleName" >> VoxelEngine.app/Contents/Info.plist + echo " VoxelEngine" >> VoxelEngine.app/Contents/Info.plist + echo " CFBundleVersion" >> VoxelEngine.app/Contents/Info.plist + echo " 1.0" >> VoxelEngine.app/Contents/Info.plist + echo "" >> VoxelEngine.app/Contents/Info.plist + echo "" >> VoxelEngine.app/Contents/Info.plist + + - name: Create DMG + run: | + hdiutil create VoxelEngine.dmg -volname "VoxelEngine" -srcfolder VoxelEngine.app -ov -format UDZO + + - name: Upload DMG + uses: actions/upload-artifact@v2 + with: + name: VoxelEngineMacOs + path: VoxelEngine.dmg diff --git a/CMakeLists.txt b/CMakeLists.txt index 8340b928..2ec2faab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,6 +101,18 @@ if (WIN32) set(VORBISLIB vorbis vorbisfile) # not tested add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/glfw) endif() +elseif(APPLE) + find_package(PkgConfig) + pkg_check_modules(LUAJIT REQUIRED luajit) + pkg_check_modules(VORBIS REQUIRED vorbis vorbisfile) + set(LUA_INCLUDE_DIR "/opt/homebrew/include/luajit-2.1") + set(LUA_LIBRARIES "/opt/homebrew/lib/libluajit-5.1.a") + message(STATUS "LUA Libraries: ${LUA_LIBRARIES}") + message(STATUS "LUA Include Dir: ${LUA_INCLUDE_DIR}") + find_package(PNG REQUIRED) + set(PNGLIB PNG::PNG) + set(VORBISLIB ${VORBIS_LDFLAGS}) + message(STATUS "Vorbis Lib: ${VORBIS_LDFLAGS}") else() find_package(PkgConfig) pkg_check_modules(LUAJIT REQUIRED luajit) From a5907302e57e4e1ffc83b3701dce35558084138e Mon Sep 17 00:00:00 2001 From: Danila Artyukhov Date: Tue, 4 Jun 2024 14:36:43 +0300 Subject: [PATCH 77/97] Update macos dmg build --- .github/workflows/macos.yml | 42 +++++++++++++---------------------- .github/workflows/release.yml | 20 ++++++++++++++++- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 89968a25..85b4b203 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,10 +1,16 @@ -name: MacOs DMG +name: Macos Build on: push: branches: [ "main" ] pull_request: branches: [ "main" ] + workflow_call: + inputs: + upload_artifacts: + description: Should upload artifacts or not + type: boolean + default: false jobs: build-dmg: @@ -30,33 +36,17 @@ jobs: - name: Build run: cmake --build build -t install - - name: Create macOS app structure - run: | - mkdir -p VoxelEngine.app/Contents/MacOS - mkdir -p VoxelEngine.app/Contents/Resources - cp build/VoxelEngine VoxelEngine.app/Contents/MacOS/ - cp -r res VoxelEngine.app/Contents/Resources/ - echo "" > VoxelEngine.app/Contents/Info.plist - echo "" >> VoxelEngine.app/Contents/Info.plist - echo "" >> VoxelEngine.app/Contents/Info.plist - echo "" >> VoxelEngine.app/Contents/Info.plist - echo " CFBundleExecutable" >> VoxelEngine.app/Contents/Info.plist - echo " VoxelEngine" >> VoxelEngine.app/Contents/Info.plist - echo " CFBundleIdentifier" >> VoxelEngine.app/Contents/Info.plist - echo " com.yourcompany.VoxelEngine" >> VoxelEngine.app/Contents/Info.plist - echo " CFBundleName" >> VoxelEngine.app/Contents/Info.plist - echo " VoxelEngine" >> VoxelEngine.app/Contents/Info.plist - echo " CFBundleVersion" >> VoxelEngine.app/Contents/Info.plist - echo " 1.0" >> VoxelEngine.app/Contents/Info.plist - echo "" >> VoxelEngine.app/Contents/Info.plist - echo "" >> VoxelEngine.app/Contents/Info.plist - - name: Create DMG + if: ${{ inputs.upload_artifacts }} run: | - hdiutil create VoxelEngine.dmg -volname "VoxelEngine" -srcfolder VoxelEngine.app -ov -format UDZO + mkdir VoxelEngineDmgContent + cp -r build/res VoxelEngineDmgContent/ + cp -r build/VoxelEngine VoxelEngineDmgContent/ + hdiutil create VoxelEngineMacApp.dmg -volname "VoxelEngine" -srcfolder VoxelEngineDmgContent -ov -format UDZO - - name: Upload DMG - uses: actions/upload-artifact@v2 + - name: Upload artifacts + if: ${{ inputs.upload_artifacts }} + uses: actions/upload-artifact@v4 with: name: VoxelEngineMacOs - path: VoxelEngine.dmg + path: VoxelEngineMacApp.dmg \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a1186ce3..1863467a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,18 +14,35 @@ jobs: build_type: Release upload_artifacts: true + build_release_macos: + name: Build Release MacOS + uses: ./.github/workflows/macos.yml + with: + upload_artifacts: true + create_release: - needs: build_release + needs: [build_release, build_release_macos] runs-on: ubuntu-latest steps: - name: Download artifacts uses: actions/download-artifact@v4 with: name: VoxelEngine + + - name: Download artifacts (MacOS) + uses: actions/download-artifact@v4 + with: + name: VoxelEngineMacOs + - name: Pack artifacts run: | chmod +x VoxelEngine zip -r VoxelEngine.zip res VoxelEngine + + - name: Pack artifacts (MacOS DMG) + run: | + cp VoxelEngineMacApp.dmg VoxelEngine.dmg + - name: Grab and store version run: | tag_name=$(echo ${{ github.ref }} | grep -oE "v[^/]+$") @@ -41,3 +58,4 @@ jobs: prerelease: false files: | VoxelEngine.zip + VoxelEngine.dmg From db729cbfbb2ad28749c6689dddcbd14627583922 Mon Sep 17 00:00:00 2001 From: Danila Artyukhov Date: Tue, 4 Jun 2024 19:19:10 +0300 Subject: [PATCH 78/97] Enable macos artifact's default --- .github/workflows/macos.yml | 8 -------- .github/workflows/release.yml | 20 +------------------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 85b4b203..68f6acc2 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -5,12 +5,6 @@ on: branches: [ "main" ] pull_request: branches: [ "main" ] - workflow_call: - inputs: - upload_artifacts: - description: Should upload artifacts or not - type: boolean - default: false jobs: build-dmg: @@ -37,7 +31,6 @@ jobs: run: cmake --build build -t install - name: Create DMG - if: ${{ inputs.upload_artifacts }} run: | mkdir VoxelEngineDmgContent cp -r build/res VoxelEngineDmgContent/ @@ -45,7 +38,6 @@ jobs: hdiutil create VoxelEngineMacApp.dmg -volname "VoxelEngine" -srcfolder VoxelEngineDmgContent -ov -format UDZO - name: Upload artifacts - if: ${{ inputs.upload_artifacts }} uses: actions/upload-artifact@v4 with: name: VoxelEngineMacOs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1863467a..a1186ce3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,35 +14,18 @@ jobs: build_type: Release upload_artifacts: true - build_release_macos: - name: Build Release MacOS - uses: ./.github/workflows/macos.yml - with: - upload_artifacts: true - create_release: - needs: [build_release, build_release_macos] + needs: build_release runs-on: ubuntu-latest steps: - name: Download artifacts uses: actions/download-artifact@v4 with: name: VoxelEngine - - - name: Download artifacts (MacOS) - uses: actions/download-artifact@v4 - with: - name: VoxelEngineMacOs - - name: Pack artifacts run: | chmod +x VoxelEngine zip -r VoxelEngine.zip res VoxelEngine - - - name: Pack artifacts (MacOS DMG) - run: | - cp VoxelEngineMacApp.dmg VoxelEngine.dmg - - name: Grab and store version run: | tag_name=$(echo ${{ github.ref }} | grep -oE "v[^/]+$") @@ -58,4 +41,3 @@ jobs: prerelease: false files: | VoxelEngine.zip - VoxelEngine.dmg From 2ee2ca7a38aece73ca4efd27f349de24f79ed01f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 4 Jun 2024 23:20:22 +0300 Subject: [PATCH 79/97] fix: empty textbox double click causes fatal error --- src/graphics/ui/elements/TextBox.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 43b6304e..ac454c42 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -337,6 +337,9 @@ inline std::wstring get_alphabet(wchar_t c) { } void TextBox::tokenSelectAt(int index) { + if (input.empty()) { + return; + } int left = index; int right = index; From 95a817c648fb059f1aaa0d5535250a08d46270d3 Mon Sep 17 00:00:00 2001 From: rekvizitt <58174945+rekvizitt@users.noreply.github.com> Date: Tue, 4 Jun 2024 23:25:51 +0300 Subject: [PATCH 80/97] Update be_BY.txt --- res/texts/be_BY.txt | 54 ++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/res/texts/be_BY.txt b/res/texts/be_BY.txt index c208eeaf..318a95ff 100644 --- a/res/texts/be_BY.txt +++ b/res/texts/be_BY.txt @@ -12,47 +12,55 @@ error.pack-not-found=Не ўдалося знайсці пакет error.dependency-not-found=Выкарыстоўваная залежнасць не знойдзена pack.remove-confirm=Выдаліць увесь кантэнт які пастаўляецца пакам са свету (беззваротна)? +# Подсказки +graphics.gamma.tooltip=Крывая яркасці асвятлення +graphics.backlight.tooltip=Падсветка, якая прадухіляе поўную цемру + # Меню -menu.New World=Новы Свет -menu.Quit=Выхад -menu.Continue=Працягнуть -menu.Save and Quit to Menu=Захаваць і Выйсці ў Меню -menu.missing-content=Адсутнічае Кантэнт! -menu.Content Error=Памылка Кантэнту -menu.Controls=Кіраванне -menu.Back to Main Menu=Вярнуцца ў Меню -menu.Settings=Налады -menu.Content=Кантэнт +menu.Apply=Ужыць menu.Audio=Гук +menu.Back to Main Menu=Вярнуцца ў Меню +menu.Content Error=Памылка Кантэнту +menu.Content=Кантэнт +menu.Continue=Працягнуть +menu.Controls=Кіраванне +menu.Graphics=Графіка +menu.missing-content=Адсутнічае Кантэнт! +menu.New World=Новы Свет +menu.Page not found=Старонка не знойдзена +menu.Quit=Выхад +menu.Save and Quit to Menu=Захаваць і Выйсці ў Меню +menu.Settings=Налады + world.Seed=Зерне world.Name=Назва - world.World generator=Генератар свету world.generators.default=Звычайны world.generators.flat=Плоскі -menu.Create World=Стварыць Свет - +world.Create World=Стварыць Свет world.convert-request=Ёсць змены ў індэксах! Канвертаваць свет? world.delete-confirm=Выдаліць свет незваротна? # Настройки +settings.Ambient=Фон +settings.Backlight=Падсветка +settings.Camera Shaking=Труска Камеры +settings.Fog Curve=Крывая Туману +settings.FOV=Поле Зроку +settings.Fullscreen=Поўны экран +settings.Gamma=Гама +settings.Language=Мова settings.Load Distance=Дыстанцыя Загрузкі settings.Load Speed=Хуткасць Загрузкі -settings.Fog Curve=Крывая Туману -settings.Backlight=Падсветка -settings.V-Sync=Вертыкальная Сінхранізацыя -settings.Camera Shaking=Труска Камеры settings.Master Volume=Агульная Гучнасць +settings.Mouse Sensitivity=Адчувальнасць Мышы +settings.Music=Музыка settings.Regular Sounds=Звычайныя Гукі settings.UI Sounds=Гукі Інтэрфейсу -settings.Ambient=Фон -settings.Music=Музыка - -settings.FOV=Поле Зроку -settings.Mouse Sensitivity=Адчувальнасць Мышы -settings.Language=Мова +settings.V-Sync=Вертыкальная Сінхранізацыя # Управление +devtools.console=Кансоль movement.forward=Уперад movement.back=Назад movement.left=Улева From 2bb8075c2ef88d7330780db36a98eb37a798c472 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Jun 2024 09:09:56 +0300 Subject: [PATCH 81/97] console log caret fix --- res/layouts/console.xml.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/res/layouts/console.xml.lua b/res/layouts/console.xml.lua index 7ed29c1f..31314ca5 100644 --- a/res/layouts/console.xml.lua +++ b/res/layouts/console.xml.lua @@ -35,6 +35,7 @@ function submit(text) add_to_history(text) setup_variables() + document.log.caret = -1 local status, result = pcall(function() return console.execute(text) end) if result ~= nil then local prevtext = document.log.text From 9dadae6e347d539910ebdfe656f8330a08d6d9d4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Jun 2024 09:41:06 +0300 Subject: [PATCH 82/97] world convert fatal error fix --- src/data/dynamic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/dynamic.cpp b/src/data/dynamic.cpp index 4d60d2a5..6b87f97c 100644 --- a/src/data/dynamic.cpp +++ b/src/data/dynamic.cpp @@ -214,7 +214,7 @@ void Map::flag(const std::string& key, bool& dst) const { } Map& Map::put(std::string key, const Value& value) { - values.emplace(key, value); + values[key] = value; return *this; } From 9211e835db5b91ec534ab2c07f690bd2a6124990 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Jun 2024 18:32:43 +0300 Subject: [PATCH 83/97] fix: input.add_callback and blocks placing when shift pressed --- src/logic/scripting/lua/libinput.cpp | 5 +++-- src/physics/PhysicsSolver.cpp | 12 ++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/logic/scripting/lua/libinput.cpp b/src/logic/scripting/lua/libinput.cpp index d870509c..309cc26b 100644 --- a/src/logic/scripting/lua/libinput.cpp +++ b/src/logic/scripting/lua/libinput.cpp @@ -31,16 +31,17 @@ static int l_mousecode(lua_State* L) { return 1; } -static int l_add_callback(lua_State* L) { +static int l_add_callback(lua_State*) { auto bindname = state->requireString(1); const auto& bind = Events::bindings.find(bindname); if (bind == Events::bindings.end()) { throw std::runtime_error("unknown binding "+util::quote(bindname)); } state->pushvalue(2); + runnable actual_callback = state->createRunnable(); runnable callback = [=]() { if (!scripting::engine->getGUI()->isFocusCaught()) { - state->createRunnable(); + actual_callback(); } }; if (hud) { diff --git a/src/physics/PhysicsSolver.cpp b/src/physics/PhysicsSolver.cpp index f3c5963a..4370be30 100644 --- a/src/physics/PhysicsSolver.cpp +++ b/src/physics/PhysicsSolver.cpp @@ -33,6 +33,7 @@ void PhysicsSolver::step( hitbox->grounded = false; for (uint i = 0; i < substeps; i++) { float px = pos.x; + float py = pos.y; float pz = pos.z; vel += gravity * dt * gravityScale; @@ -44,6 +45,9 @@ void PhysicsSolver::step( vel.z *= glm::max(0.0f, 1.0f - dt * linear_damping); pos += vel * dt + gravity * gravityScale * dt * dt * 0.5f; + if (hitbox->grounded) { + pos.y = py; + } if (shifting && hitbox->grounded){ float y = (pos.y-half.y-E); @@ -220,6 +224,7 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Hitbox* hitbox) { } bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate state, Hitbox* hitbox) { + const float E = 0.001f; // inaccuracy const glm::vec3& pos = hitbox->position; const glm::vec3& half = hitbox->halfsize; const auto& boxes = def->rotatable @@ -228,10 +233,9 @@ bool PhysicsSolver::isBlockInside(int x, int y, int z, Block* def, blockstate st for (const auto& block_hitbox : boxes) { glm::vec3 min = block_hitbox.min(); glm::vec3 max = block_hitbox.max(); - // 0.00001 - inaccuracy - if (min.x < pos.x+half.x-x-0.00001f && max.x > pos.x-half.x-x+0.00001f && - min.z < pos.z+half.z-z-0.00001f && max.z > pos.z-half.z-z+0.00001f && - min.y < pos.y+half.y-y-0.00001f && max.y > pos.y-half.y-y+0.00001f) + if (min.x < pos.x+half.x-x-E && max.x > pos.x-half.x-x+E && + min.z < pos.z+half.z-z-E && max.z > pos.z-half.z-z+E && + min.y < pos.y+half.y-y-E && max.y > pos.y-half.y-y+E) return true; } return false; From 04c27ca800e47802e011a0bf9f03afb675b7657b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Jun 2024 19:05:23 +0300 Subject: [PATCH 84/97] fix: logger not flushing after every line --- src/debug/Logger.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/debug/Logger.cpp b/src/debug/Logger.cpp index 1649b9a0..b14d441b 100644 --- a/src/debug/Logger.cpp +++ b/src/debug/Logger.cpp @@ -51,6 +51,7 @@ void Logger::log(LogLevel level, const std::string& name, std::string message) { auto string = ss.str(); if (file.good()) { file << string << '\n'; + file.flush(); } std::cout << string << std::endl; } From d316a5f8189e6d1083b72e07d5f8f273753c3d13 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Jun 2024 19:10:24 +0300 Subject: [PATCH 85/97] fix: empty tooltip does not trigger reset --- src/graphics/ui/GUI.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 63576877..ac32af78 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -73,6 +73,9 @@ void GUI::updateTooltip(float delta) { if (tooltipTimer + delta >= hover->getTooltipDelay()) { auto label = std::dynamic_pointer_cast(get("tooltip.label")); const auto& text = hover->getTooltip(); + if (text.empty() && tooltip->isVisible()) { + return resetTooltip(); + } if (label && !text.empty()) { tooltip->setVisible(true); label->setText(langs::get(text)); From ad62b759fb68615580c2915b1ac120f1be1a90ad Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Jun 2024 19:29:35 +0300 Subject: [PATCH 86/97] fix: input F1..F25 key codes & add binding 'chunks.reload' --- res/config/bindings.toml | 1 + res/texts/en_US.txt | 1 + res/texts/ru_RU.txt | 1 + src/core_defs.hpp | 1 + src/frontend/screens/LevelScreen.cpp | 7 ++++--- src/window/Events.cpp | 8 ++++++++ src/window/Events.hpp | 1 + src/window/input.cpp | 2 +- 8 files changed, 18 insertions(+), 4 deletions(-) diff --git a/res/config/bindings.toml b/res/config/bindings.toml index d0a7e1e9..e13be068 100644 --- a/res/config/bindings.toml +++ b/res/config/bindings.toml @@ -1,4 +1,5 @@ devtools.console="key:grave-accent" +chunks.reload="key:f5" movement.forward="key:w" movement.back="key:s" movement.left="key:a" diff --git a/res/texts/en_US.txt b/res/texts/en_US.txt index 8681a069..4b8d5e5e 100644 --- a/res/texts/en_US.txt +++ b/res/texts/en_US.txt @@ -13,6 +13,7 @@ graphics.gamma.tooltip=Lighting brightness curve graphics.backlight.tooltip=Backlight to prevent total darkness # Bindings +chunks.reload=Reload Chunks devtools.console=Console movement.forward=Forward movement.back=Back diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index a1b7f3be..f4cdfbc0 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -60,6 +60,7 @@ settings.UI Sounds=Звуки Интерфейса settings.V-Sync=Вертикальная Синхронизация # Управление +chunks.reload=Перезагрузить Чанки devtools.console=Консоль movement.forward=Вперёд movement.back=Назад diff --git a/src/core_defs.hpp b/src/core_defs.hpp index 884cda26..d57435ad 100644 --- a/src/core_defs.hpp +++ b/src/core_defs.hpp @@ -10,6 +10,7 @@ inline const std::string TEXTURE_NOTFOUND = "notfound"; // built-in bindings inline const std::string BIND_DEVTOOLS_CONSOLE = "devtools.console"; +inline const std::string BIND_CHUNKS_RELOAD = "chunks.reload"; inline const std::string BIND_MOVE_FORWARD = "movement.forward"; inline const std::string BIND_MOVE_BACK = "movement.back"; inline const std::string BIND_MOVE_LEFT = "movement.left"; diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 5814f3bf..d740ce19 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -1,5 +1,6 @@ #include "LevelScreen.hpp" +#include "../../core_defs.hpp" #include "../hud.hpp" #include "../LevelFrontend.hpp" #include "../../audio/audio.hpp" @@ -47,6 +48,9 @@ LevelScreen::LevelScreen(Engine* engine, std::unique_ptr level) keepAlive(settings.camera.fov.observe([=](double value) { controller->getPlayer()->camera->setFov(glm::radians(value)); })); + keepAlive(Events::getBinding(BIND_CHUNKS_RELOAD).onactived.add([=](){ + controller->getLevel()->chunks->saveAndClear(); + })); animator = std::make_unique(); animator->addAnimations(assets->getAnimations()); @@ -114,9 +118,6 @@ void LevelScreen::updateHotkeys() { if (Events::jpressed(keycode::F3)) { controller->getPlayer()->debug = !controller->getPlayer()->debug; } - if (Events::jpressed(keycode::F5)) { - controller->getLevel()->chunks->saveAndClear(); - } } void LevelScreen::update(float delta) { diff --git a/src/window/Events.cpp b/src/window/Events.cpp index f2c47a29..1aab7881 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -98,6 +98,14 @@ void Events::pollEvents() { } } +Binding& Events::getBinding(const std::string& name) { + auto found = bindings.find(name); + if (found == bindings.end()) { + throw std::runtime_error("binding '"+name+"' does not exists"); + } + return found->second; +} + void Events::bind(const std::string& name, inputtype type, keycode code) { bind(name, type, static_cast(code)); } diff --git a/src/window/Events.hpp b/src/window/Events.hpp index 04bdcfe0..97405d2c 100644 --- a/src/window/Events.hpp +++ b/src/window/Events.hpp @@ -38,6 +38,7 @@ public: static void toggleCursor(); + static Binding& getBinding(const std::string& name); static void bind(const std::string& name, inputtype type, keycode code); static void bind(const std::string& name, inputtype type, mousecode code); static void bind(const std::string& name, inputtype type, int code); diff --git a/src/window/input.cpp b/src/window/input.cpp index 481e4a79..cfb06e84 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -77,7 +77,7 @@ void input_util::initialize() { keycodes[std::to_string(i)] = GLFW_KEY_0+i; } for (int i = 0; i < 25; i++) { - keycodes["f"+std::to_string(i)] = GLFW_KEY_F1+i; + keycodes["f"+std::to_string(i+1)] = GLFW_KEY_F1+i; } for (char i = 'a'; i <= 'z'; i++) { keycodes[std::string({i})] = GLFW_KEY_A-'a'+i; From 6744b592b2f6a2e6f2b1971bbe28aa481eb838fb Mon Sep 17 00:00:00 2001 From: LumperBumper <130532332+callfishxt@users.noreply.github.com> Date: Wed, 5 Jun 2024 23:15:14 +0500 Subject: [PATCH 87/97] Create windows --- .github/workflows/windows | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/windows diff --git a/.github/workflows/windows b/.github/workflows/windows new file mode 100644 index 00000000..46fe7122 --- /dev/null +++ b/.github/workflows/windows @@ -0,0 +1,48 @@ +name: Windows Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build-windows: + + strategy: + matrix: + include: + - os: windows-latest + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + + - name: Set up vcpkg + run: | + git clone https://github.com/microsoft/vcpkg.git + cd vcpkg + .\bootstrap-vcpkg.bat + .\vcpkg integrate install + cd .. + - name: Configure and build project with CMake and vcpkg + run: | + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. + Remove-Item -Path CMakeFiles -Recurse -Force + cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. + cmake --build . --config Release + - name: Package for Windows + run: | + mkdir packaged + cp -r build/* packaged/ + working-directory: ${{ github.workspace }} + + - uses: actions/upload-artifact@v2 + with: + name: Windows-Build + path: 'packaged/Release/*' From b549023bdaf6684fcfcf789eab322e1ed9649a6b Mon Sep 17 00:00:00 2001 From: LumperBumper <130532332+callfishxt@users.noreply.github.com> Date: Wed, 5 Jun 2024 23:15:34 +0500 Subject: [PATCH 88/97] Delete .github/workflows/windows --- .github/workflows/windows | 48 --------------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 .github/workflows/windows diff --git a/.github/workflows/windows b/.github/workflows/windows deleted file mode 100644 index 46fe7122..00000000 --- a/.github/workflows/windows +++ /dev/null @@ -1,48 +0,0 @@ -name: Windows Build - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build-windows: - - strategy: - matrix: - include: - - os: windows-latest - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - - name: Set up vcpkg - run: | - git clone https://github.com/microsoft/vcpkg.git - cd vcpkg - .\bootstrap-vcpkg.bat - .\vcpkg integrate install - cd .. - - name: Configure and build project with CMake and vcpkg - run: | - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. - Remove-Item -Path CMakeFiles -Recurse -Force - cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. - cmake --build . --config Release - - name: Package for Windows - run: | - mkdir packaged - cp -r build/* packaged/ - working-directory: ${{ github.workspace }} - - - uses: actions/upload-artifact@v2 - with: - name: Windows-Build - path: 'packaged/Release/*' From 6e4c6b63e91c3f60c62506176154054765ca8684 Mon Sep 17 00:00:00 2001 From: LumperBumper <130532332+callfishxt@users.noreply.github.com> Date: Wed, 5 Jun 2024 23:15:50 +0500 Subject: [PATCH 89/97] Create windows.yml --- .github/workflows/windows.yml | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 00000000..46fe7122 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,48 @@ +name: Windows Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build-windows: + + strategy: + matrix: + include: + - os: windows-latest + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + + - name: Set up vcpkg + run: | + git clone https://github.com/microsoft/vcpkg.git + cd vcpkg + .\bootstrap-vcpkg.bat + .\vcpkg integrate install + cd .. + - name: Configure and build project with CMake and vcpkg + run: | + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. + Remove-Item -Path CMakeFiles -Recurse -Force + cmake -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_WINDOWS_VCPKG=ON .. + cmake --build . --config Release + - name: Package for Windows + run: | + mkdir packaged + cp -r build/* packaged/ + working-directory: ${{ github.workspace }} + + - uses: actions/upload-artifact@v2 + with: + name: Windows-Build + path: 'packaged/Release/*' From 8700f892c655bff2773fe4b143447f1996e95df0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 5 Jun 2024 22:52:13 +0300 Subject: [PATCH 90/97] fix: audio volume setting not applied on load --- src/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine.cpp b/src/engine.cpp index 8b57a237..4720f909 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -58,7 +58,7 @@ inline void create_channel(Engine* engine, std::string name, NumberSetting& sett } engine->keepAlive(setting.observe([=](auto value) { audio::get_channel(name)->setVolume(value*value); - })); + }, true)); } Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, EnginePaths* paths) From 7db76a0e6acf92ee2f5ac075320a240088481644 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 6 Jun 2024 11:24:16 +0300 Subject: [PATCH 91/97] refactor: Batch2D and Batch3D --- src/graphics/core/Batch2D.cpp | 21 +++++++++--------- src/graphics/core/Batch2D.hpp | 4 ++-- src/graphics/core/Batch3D.cpp | 41 ++++++++++++++++++++--------------- src/graphics/core/Batch3D.hpp | 33 +++++++++++++++++----------- 4 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/graphics/core/Batch2D.cpp b/src/graphics/core/Batch2D.cpp index c07c6632..6e80af51 100644 --- a/src/graphics/core/Batch2D.cpp +++ b/src/graphics/core/Batch2D.cpp @@ -13,19 +13,18 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), color(1.0f){ {2}, {2}, {4}, {0} }; - buffer = new float[capacity * B2D_VERTEX_SIZE]; - mesh = std::make_unique(buffer, 0, attrs); + buffer = std::make_unique(capacity * B2D_VERTEX_SIZE); + mesh = std::make_unique(buffer.get(), 0, attrs); index = 0; ubyte pixels[] = { 0xFF, 0xFF, 0xFF, 0xFF }; blank = std::make_unique(pixels, 1, 1, ImageFormat::rgba8888); - _texture = nullptr; + currentTexture = nullptr; } Batch2D::~Batch2D(){ - delete[] buffer; } void Batch2D::setPrimitive(DrawPrimitive primitive) { @@ -37,7 +36,7 @@ void Batch2D::setPrimitive(DrawPrimitive primitive) { } void Batch2D::begin(){ - _texture = nullptr; + currentTexture = nullptr; blank->bind(); color = glm::vec4(1.0f); primitive = DrawPrimitive::triangle; @@ -73,14 +72,16 @@ void Batch2D::vertex( } void Batch2D::texture(Texture* new_texture){ - if (_texture == new_texture) + if (currentTexture == new_texture) { return; + } flush(); - _texture = new_texture; - if (new_texture == nullptr) + currentTexture = new_texture; + if (new_texture == nullptr) { blank->bind(); - else + } else { new_texture->bind(); + } } void Batch2D::untexture() { @@ -327,7 +328,7 @@ void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index void Batch2D::flush() { if (index == 0) return; - mesh->reload(buffer, index / B2D_VERTEX_SIZE); + mesh->reload(buffer.get(), index / B2D_VERTEX_SIZE); mesh->draw(gl::to_glenum(primitive)); index = 0; } diff --git a/src/graphics/core/Batch2D.hpp b/src/graphics/core/Batch2D.hpp index cbd56908..18095cff 100644 --- a/src/graphics/core/Batch2D.hpp +++ b/src/graphics/core/Batch2D.hpp @@ -12,13 +12,13 @@ class Texture; struct UVRegion; class Batch2D { - float* buffer; + std::unique_ptr buffer; size_t capacity; std::unique_ptr mesh; std::unique_ptr blank; size_t index; glm::vec4 color; - Texture* _texture; + Texture* currentTexture; DrawPrimitive primitive = DrawPrimitive::triangle; void setPrimitive(DrawPrimitive primitive); diff --git a/src/graphics/core/Batch3D.cpp b/src/graphics/core/Batch3D.cpp index 105c8623..7481ec6f 100644 --- a/src/graphics/core/Batch3D.cpp +++ b/src/graphics/core/Batch3D.cpp @@ -14,28 +14,29 @@ Batch3D::Batch3D(size_t capacity) {3}, {2}, {4}, {0} }; - buffer = new float[capacity * B3D_VERTEX_SIZE]; - mesh = std::make_unique(buffer, 0, attrs); + buffer = std::make_unique(capacity * B3D_VERTEX_SIZE); + mesh = std::make_unique(buffer.get(), 0, attrs); index = 0; ubyte pixels[] = { 255, 255, 255, 255, }; blank = std::make_unique(pixels, 1, 1, ImageFormat::rgba8888); - _texture = nullptr; + currentTexture = nullptr; } Batch3D::~Batch3D(){ - delete[] buffer; } void Batch3D::begin(){ - _texture = nullptr; + currentTexture = nullptr; blank->bind(); } -void Batch3D::vertex(float x, float y, float z, float u, float v, - float r, float g, float b, float a) { +void Batch3D::vertex( + float x, float y, float z, float u, float v, + float r, float g, float b, float a +) { buffer[index++] = x; buffer[index++] = y; buffer[index++] = z; @@ -46,8 +47,10 @@ void Batch3D::vertex(float x, float y, float z, float u, float v, buffer[index++] = b; buffer[index++] = a; } -void Batch3D::vertex(glm::vec3 coord, float u, float v, - float r, float g, float b, float a) { +void Batch3D::vertex( + glm::vec3 coord, float u, float v, + float r, float g, float b, float a +) { buffer[index++] = coord.x; buffer[index++] = coord.y; buffer[index++] = coord.z; @@ -58,9 +61,11 @@ void Batch3D::vertex(glm::vec3 coord, float u, float v, buffer[index++] = b; buffer[index++] = a; } -void Batch3D::vertex(glm::vec3 point, - glm::vec2 uvpoint, - float r, float g, float b, float a) { +void Batch3D::vertex( + glm::vec3 point, + glm::vec2 uvpoint, + float r, float g, float b, float a +) { buffer[index++] = point.x; buffer[index++] = point.y; buffer[index++] = point.z; @@ -99,10 +104,10 @@ void Batch3D::face( } void Batch3D::texture(Texture* new_texture){ - if (_texture == new_texture) + if (currentTexture == new_texture) return; flush(); - _texture = new_texture; + currentTexture = new_texture; if (new_texture == nullptr) blank->bind(); else @@ -166,7 +171,9 @@ inline glm::vec4 do_tint(float value) { return glm::vec4(value, value, value, 1.0f); } -void Batch3D::xSprite(float w, float h, const UVRegion& uv, const glm::vec4 tint, bool shading) { +void Batch3D::xSprite( + float w, float h, const UVRegion& uv, const glm::vec4 tint, bool shading +) { face( glm::vec3(-w * 0.25f, 0.0f, -w * 0.25f), w, h, @@ -244,13 +251,13 @@ void Batch3D::point(glm::vec3 coord, glm::vec4 tint) { } void Batch3D::flush() { - mesh->reload(buffer, index / B3D_VERTEX_SIZE); + mesh->reload(buffer.get(), index / B3D_VERTEX_SIZE); mesh->draw(); index = 0; } void Batch3D::flushPoints() { - mesh->reload(buffer, index / B3D_VERTEX_SIZE); + mesh->reload(buffer.get(), index / B3D_VERTEX_SIZE); mesh->draw(GL_POINTS); index = 0; } diff --git a/src/graphics/core/Batch3D.hpp b/src/graphics/core/Batch3D.hpp index d6cda86b..6ff42caa 100644 --- a/src/graphics/core/Batch3D.hpp +++ b/src/graphics/core/Batch3D.hpp @@ -12,28 +12,35 @@ class Mesh; class Texture; class Batch3D { - float* buffer; + std::unique_ptr buffer; size_t capacity; std::unique_ptr mesh; std::unique_ptr blank; size_t index; - Texture* _texture; + Texture* currentTexture; - void vertex(float x, float y, float z, - float u, float v, - float r, float g, float b, float a); - void vertex(glm::vec3 coord, - float u, float v, - float r, float g, float b, float a); - void vertex(glm::vec3 point, glm::vec2 uvpoint, - float r, float g, float b, float a); - - void face(const glm::vec3& coord, float w, float h, + void vertex( + float x, float y, float z, + float u, float v, + float r, float g, float b, float a + ); + void vertex( + glm::vec3 coord, + float u, float v, + float r, float g, float b, float a + ); + void vertex( + glm::vec3 point, glm::vec2 uvpoint, + float r, float g, float b, float a + ); + void face( + const glm::vec3& coord, float w, float h, const glm::vec3& axisX, const glm::vec3& axisY, const UVRegion& region, - const glm::vec4& tint); + const glm::vec4& tint + ); public: Batch3D(size_t capacity); From a57f8f41bb145f2af5f2d9e2b706ebbe88875d2d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 6 Jun 2024 11:29:30 +0300 Subject: [PATCH 92/97] update: tooltip conditions --- src/graphics/ui/GUI.cpp | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index ac32af78..c7ef8a1f 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -68,30 +68,25 @@ void GUI::updateTooltip(float delta) { if (hover == nullptr || !hover->isInside(Events::cursor)) { return resetTooltip(); } - float mouseDelta = glm::length(Events::delta); - if (mouseDelta < 1.0f || tooltipTimer >= hover->getTooltipDelay()) { - if (tooltipTimer + delta >= hover->getTooltipDelay()) { - auto label = std::dynamic_pointer_cast(get("tooltip.label")); - const auto& text = hover->getTooltip(); - if (text.empty() && tooltip->isVisible()) { - return resetTooltip(); - } - if (label && !text.empty()) { - tooltip->setVisible(true); - label->setText(langs::get(text)); - auto size = label->getSize()+glm::vec2(4.0f); - auto pos = Events::cursor+glm::vec2(10.0f); - auto rootSize = container->getSize(); - pos.x = glm::min(pos.x, rootSize.x-size.x); - pos.y = glm::min(pos.y, rootSize.y-size.y); - tooltip->setSize(size); - tooltip->setPos(pos); - } + if (tooltipTimer + delta >= hover->getTooltipDelay()) { + auto label = std::dynamic_pointer_cast(get("tooltip.label")); + const auto& text = hover->getTooltip(); + if (text.empty() && tooltip->isVisible()) { + return resetTooltip(); + } + if (label && !text.empty()) { + tooltip->setVisible(true); + label->setText(langs::get(text)); + auto size = label->getSize()+glm::vec2(4.0f); + auto pos = Events::cursor+glm::vec2(10.0f); + auto rootSize = container->getSize(); + pos.x = glm::min(pos.x, rootSize.x-size.x); + pos.y = glm::min(pos.y, rootSize.y-size.y); + tooltip->setSize(size); + tooltip->setPos(pos); } - tooltipTimer += delta; - } else { - resetTooltip(); } + tooltipTimer += delta; } /// @brief Mouse related input and logic handling From 587098193330b42f9b6ea82967944002d3752025 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 6 Jun 2024 14:00:00 +0300 Subject: [PATCH 93/97] fix: player physics when chunks reload --- src/logic/LevelController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index 479eff16..4e965f72 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -22,12 +22,12 @@ LevelController::LevelController(EngineSettings& settings, std::unique_ptrupdate(delta, input, pause); glm::vec3 position = player->getPlayer()->hitbox->position; level->loadMatrix(position.x, position.z, settings.chunks.loadDistance.get() + settings.chunks.padding.get() * 2); chunks->update(settings.chunks.loadSpeed.get()); + player->update(delta, input, pause); // erease null pointers level->objects.erase( From 7cbacba0c60d4ac2d83ea1e197bc2334c68a35b6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 6 Jun 2024 14:15:50 +0300 Subject: [PATCH 94/97] fix: EngineController::reconfigPacks --- src/logic/EngineController.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index 8a2be95e..b9f36bb2 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -223,7 +223,8 @@ void EngineController::reconfigPacks( std::stringstream ss; for (const auto& id : packsToRemove) { - if (content->getPackRuntime(id)->getStats().hasSavingContent()) { + auto runtime = content->getPackRuntime(id); + if (runtime && runtime->getStats().hasSavingContent()) { if (hasIndices) { ss << ", "; } @@ -234,13 +235,22 @@ void EngineController::reconfigPacks( runnable removeFunc = [=]() { if (controller == nullptr) { - auto manager = engine->createPacksManager(fs::path("")); - manager.scan(); - std::vector names = engine->getBasePacks(); - for (auto& name : packsToAdd) { - names.push_back(name); + try { + auto manager = engine->createPacksManager(fs::path("")); + manager.scan(); + std::vector names = PacksManager::getNames(engine->getContentPacks()); + for (const auto& id : packsToAdd) { + names.push_back(id); + } + for (const auto& id : packsToRemove) { + manager.exclude(id); + names.erase(std::find(names.begin(), names.end(), id)); + } + names = manager.assembly(names); + engine->getContentPacks() = manager.getAll(names); + } catch (const contentpack_error& err) { + throw std::runtime_error(std::string(err.what())+" ["+err.getPackId()+"]"); } - engine->getContentPacks() = manager.getAll(names); } else { auto world = controller->getLevel()->getWorld(); auto wfile = world->wfile.get(); From 87082c2cb63330868fbb46632768f8bdf39e1be1 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 6 Jun 2024 15:19:45 +0300 Subject: [PATCH 95/97] =?UTF-8?q?update=20doc/ru/5.XML-=D1=80=D0=B0=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BA=D0=B0-=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D1=84=D0=B5=D0=B9=D1=81=D0=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/ru/5.XML-разметка-интерфейса.md | 59 ++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/doc/ru/5.XML-разметка-интерфейса.md b/doc/ru/5.XML-разметка-интерфейса.md index 17f4e701..93c23c93 100644 --- a/doc/ru/5.XML-разметка-интерфейса.md +++ b/doc/ru/5.XML-разметка-интерфейса.md @@ -26,14 +26,31 @@ # Общие атрибуты элементов +- `enabled` - при значении false блокирует элемент, в отличие от interactive, обозначая это состояние визуально. - `id` - идентификатор элемента. Тип: строка. - `pos` - позиция элемента. Тип: 2D вектор. - `size` - размер элемента. Тип: 2D вектор. +- `context` - указывает контекст перевода для `@`-строк. - `color` - цвет элемента. Тип: RGBA цвет. +- `hover-color` - цвет элемента при наведении курсора. Тип: RGBA цвет. +- `pressed-color` - цвет элемента при нажатии на элемент. Тип: RGBA цвет. - `margin` - внешний отступ элемента. Тип: 4D вектор. Порядок: `"left,top,right,bottom"` - `visible` - видимость элемента. Тип: логический ("true"/"false"). - `position-func` - поставщик позиции элемента (два числа), вызываемый при изменении размера контейнера, в котором находится элемент, либо при добавлении элемента в контейнер. Может быть вызван до вызова on_hud_open. +- `size-func` - поставщик размера элемента (два числа), вызываемый при изменении размера контейнера, в котором находится элемент, либо при добавлении элемента в контейнер. Может быть вызван до вызова on_hud_open. +- `onclick` - lua функция вызываемая при нажатии на элемент. +- `ondoubleclick` - lua функция вызываемая при двойном нажатии на элемент. +- `tooltip` - текст всплывающей подсказки +- `tooltip-delay` - задержка появления всплывающей подсказки +- `gravity` - автоматическое позиционирование элемента в контейнере. (Не работает в автоматических контейнерах, как panel). Значения: *top-left, top-center, top-right, center-left, center-center, center-right, bottom-left, bottom-center, bottom-right*. +- `z-index` - определяет порядок элементов, при большем значении будет перекрывать элементы с меньшим. +- `interactive` - при значении false наведение на элемент и все под-элементы будет игнорироваться. + +# Атрибуты шаблонов + +- `if` при значениях ('', 'false', 'nil') элемент будет проигнорирован, включая под-элементы. +- `ifnot` то же, что и `if`, но с обратным условием. # Общие атрибуты контейнеров @@ -46,47 +63,69 @@ В число панелей также входят кнопки. - `max-length` - максимальная длина, на которую растягивается панель до начала скроллинга (если scrollable = true). Тип: число +- `orientation` - ориентация панели: horizontal/vertical. # Основные элементы -## Кнопка `button` +## Кнопка - *button* Внутренний текст - текст кнопки. - `text-align` - выравнивание текста ("left", "center" или "right"). Тип: строка. -- `onclick` - lua функция вызываемая при нажатии на кнопку. -## Изображение `image` +## Флажок - *checkbox* + +- `checked` - определяет состояние отметки. +- `supplier` - поставщик состояния отметки (вызывается каждый кадр) +- `consumer` - lua функция-приемник состояния отметки. Вызывается только при завершении ввода +## Метка - *label* + +- `valign` - вертикальное выравнивание текста: top/center/bottom +- `supplier` - поставщик текста (вызывается каждый кадр) +- `autoresize` - автоматическое изменение размера элемента (по-умолчанию - false). Не влияет на размер шрифта. +- `multiline` - разрешает отображение многострочного текста. +- `text-wrap` - разрешает автоматический перенос текста (работает только при multiline: "true") + +## Изображение - *image* - `src` - имя изображения в папке textures без указания расширения. Тип: строка. Например `gui/error` -# Текстовое поле `textbox` +## Текстовое поле - *textbox* Внутренний текст - изначально введенный текст - `placeholder` - текст подстановки (используется текстовое поле пусто) +- `supplier` - поставщик текста (вызывается каждый кадр) - `consumer` - lua функция-приемник введенного текста. Вызывается только при завершении ввода - -## Ползунок `trackbar` +- `autoresize` - автоматическое изменение размера элемента (по-умолчанию - false). Не влияет на размер шрифта. +- `multiline` - разрешает отображение многострочного текста. +- `text-wrap` - разрешает автоматический перенос текста (работает только при multiline: "true") +- `editable`- определяет возможность редактирования текста. +- `error-color` - цвет при вводе некорректных данных (текст не проходит проверку валидатора). Тип: RGBA цвет. +- `validator` - lua функция, проверяющая текст на корректность. Принимает на вход строку, возвращает true если текст корректен. +- `onup` - lua функция вызываемая при нажатии стрелки вверх. +- `ondown` - lua функция вызываемая при нажатии стрелки вниз. +## Ползунок - *trackbar* - `min` - минимальное значение. Тип: число. По-умолчанию: 0 - `max` - максимальное значение. Тип: число. По-умолчанию: 1 - `value` - изначальное значение. Тип: число. По-умолчанию: 0 - `step` - размер деления ползунка. Тип: число. По-умолчанию: 1 -- `track-width` - ширина указателя (в делениях). Тип: число. По-умолчанию: 1 +- `track-width` - ширина указателя (в пикселях). Тип: число. По-умолчанию: 12 +- `track-color` - цвет указателя при наведении курсора. Тип: RGBA цвет. - `consumer` - lua функция-приемник установленного значения - `supplier` - lua функция-поставщик значения # Элементы инвентаря -## Инвентарь `inventory` +## Инвентарь - *inventory* Элемент является контейнером. На данный момент не имеет специфических атрибутов. > [!WARNING] > Расположение инвентарей управляется движком и не может быть изменено свойствами pos, margin и т.д. -## Одиночный слот `slot` +## Одиночный слот - *slot* Элемент должен находиться внутри `inventory` элемента, без посредников. - `index` - индекс слота инвентаря. (Нумерация с 0) @@ -95,7 +134,7 @@ - `updatefunc` - lua событие вызываемое при изменении содержимого слота - `onrightclick` - lua событие вызываемое при использовании ПКМ. Передается id инвентаря и индекс слота -## Решетка слотов `slots-grid` +## Сетка слотов - *slots-grid* Элемент должен находиться внутри `inventory` элемента, без посредников. - `start-index` - индекс первого слота From d818cec7bb6316ae331ebd350a5768d7f447dbb2 Mon Sep 17 00:00:00 2001 From: Danila Artyukhov Date: Thu, 6 Jun 2024 15:57:34 +0300 Subject: [PATCH 96/97] Apple bundle with dylib's --- .github/workflows/macos.yml | 7 +++ CMakeLists.txt | 120 ++++++++++++++++++------------------ fix_dylibs.sh | 24 ++++++++ 3 files changed, 91 insertions(+), 60 deletions(-) create mode 100755 fix_dylibs.sh diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 68f6acc2..371e1ac1 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -30,11 +30,18 @@ jobs: - name: Build run: cmake --build build -t install + - name: Make fix_dylibs.sh executable + run: chmod +x fix_dylibs.sh + + - name: Fix dylibs + run: ./fix_dylibs.sh VoxelEngine Release build + - name: Create DMG run: | mkdir VoxelEngineDmgContent cp -r build/res VoxelEngineDmgContent/ cp -r build/VoxelEngine VoxelEngineDmgContent/ + cp -r build/libs VoxelEngineDmgContent/libs hdiutil create VoxelEngineMacApp.dmg -volname "VoxelEngine" -srcfolder VoxelEngineDmgContent -ov -format UDZO - name: Upload artifacts diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ec2faab..254ed621 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ option(VOXELENGINE_BUILD_WINDOWS_VCPKG OFF) if(VOXELENGINE_BUILD_WINDOWS_VCPKG AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake") - set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") endif() cmake_minimum_required(VERSION 3.15) @@ -16,68 +16,68 @@ file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES}) if(VOXELENGINE_BUILD_APPDIR) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/.dirIcon) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) - install(TARGETS VoxelEngine DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/.dirIcon) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) + install(TARGETS VoxelEngine DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) endif() if(MSVC) if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) endif() if((CMAKE_BUILD_TYPE EQUAL "Release") OR (CMAKE_BUILD_TYPE EQUAL "RelWithDebInfo")) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Release>") - target_compile_options(${PROJECT_NAME} PRIVATE /W4 /MT /O2) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Release>") + target_compile_options(${PROJECT_NAME} PRIVATE /W4 /MT /O2) else() - target_compile_options(${PROJECT_NAME} PRIVATE /W4) + target_compile_options(${PROJECT_NAME} PRIVATE /W4) endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /source-charset:UTF-8") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /source-charset:UTF-8") else() - target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra - # additional warnings - -Wformat-nonliteral -Wcast-align - -Wpointer-arith -Wundef - -Wwrite-strings -Wno-unused-parameter) - if (CMAKE_BUILD_TYPE MATCHES "Debug") - target_compile_options(${PROJECT_NAME} PRIVATE -Og) - endif() + target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra + # additional warnings + -Wformat-nonliteral -Wcast-align + -Wpointer-arith -Wundef + -Wwrite-strings -Wno-unused-parameter) + if (CMAKE_BUILD_TYPE MATCHES "Debug") + target_compile_options(${PROJECT_NAME} PRIVATE -Og) + endif() endif() if(VOXELENGINE_BUILD_WINDOWS_VCPKG AND WIN32) - if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") - find_package(Git QUIET) - if(GIT_FOUND) - message(STATUS "Adding vcpkg as a git submodule...") - execute_process(COMMAND ${GIT_EXECUTABLE} submodule add https://github.com/microsoft/vcpkg.git vcpkg WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - else() - message(FATAL_ERROR "Git not found, cannot add vcpkg submodule.") + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") + find_package(Git QUIET) + if(GIT_FOUND) + message(STATUS "Adding vcpkg as a git submodule...") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule add https://github.com/microsoft/vcpkg.git vcpkg WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + else() + message(FATAL_ERROR "Git not found, cannot add vcpkg submodule.") + endif() endif() - endif() - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") - message(STATUS "Initializing and updating vcpkg submodule...") - execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - execute_process(COMMAND ${CMAKE_COMMAND} -E chdir vcpkg ./bootstrap-vcpkg.bat WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - endif() + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") + message(STATUS "Initializing and updating vcpkg submodule...") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + execute_process(COMMAND ${CMAKE_COMMAND} -E chdir vcpkg ./bootstrap-vcpkg.bat WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + endif() - foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES}) - string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE_UPPER) - add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_SOURCE_DIR}/res ${CMAKE_BINARY_DIR}/${CONFIG_TYPE_UPPER}/res) - endforeach() + foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE_UPPER) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/res ${CMAKE_BINARY_DIR}/${CONFIG_TYPE_UPPER}/res) + endforeach() endif() find_package(OpenGL REQUIRED) @@ -87,19 +87,19 @@ find_package(ZLIB REQUIRED) if (WIN32) if(VOXELENGINE_BUILD_WINDOWS_VCPKG) - set(LUA_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/lib/lua51.lib") - set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/include/luajit") - find_package(glfw3 REQUIRED) - find_package(spng REQUIRED) - find_package(glm REQUIRED) - find_package(vorbis REQUIRED) - set(PNGLIB spng::spng) - set(VORBISLIB Vorbis::vorbis Vorbis::vorbisfile) + set(LUA_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/lib/lua51.lib") + set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/include/luajit") + find_package(glfw3 REQUIRED) + find_package(spng REQUIRED) + find_package(glm REQUIRED) + find_package(vorbis REQUIRED) + set(PNGLIB spng::spng) + set(VORBISLIB Vorbis::vorbis Vorbis::vorbisfile) else() - find_package(Lua REQUIRED) - set(PNGLIB spng) - set(VORBISLIB vorbis vorbisfile) # not tested - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/glfw) + find_package(Lua REQUIRED) + set(PNGLIB spng) + set(VORBISLIB vorbis vorbisfile) # not tested + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/glfw) endif() elseif(APPLE) find_package(PkgConfig) diff --git a/fix_dylibs.sh b/fix_dylibs.sh new file mode 100755 index 00000000..779336b3 --- /dev/null +++ b/fix_dylibs.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +PROJECT_NAME=$1 +CONFIG=$2 +OUTPUT_DIR=$3 +LIBS_DIR="$OUTPUT_DIR/libs" + +mkdir -p "$LIBS_DIR" + +TMP_BINARY="$OUTPUT_DIR/tmp_$PROJECT_NAME" +BINARY="$OUTPUT_DIR/$PROJECT_NAME" + +cp "$BINARY" "$TMP_BINARY" + +otool -L "$TMP_BINARY" | grep -o '/.*dylib' | while read -r dylib; do + if [[ "$dylib" == /usr/lib/* || "$dylib" == /System/Library/* ]]; then + continue + fi + + cp "$dylib" "$LIBS_DIR" + install_name_tool -change "$dylib" "@executable_path/libs/$(basename "$dylib")" "$TMP_BINARY" +done + +mv "$TMP_BINARY" "$BINARY" From e6745d4b6426df8772880911a5fa62a0bf1f5a81 Mon Sep 17 00:00:00 2001 From: Danila Artyukhov Date: Thu, 6 Jun 2024 17:43:43 +0300 Subject: [PATCH 97/97] Revert CMakeList --- CMakeLists.txt | 120 ++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 254ed621..2ec2faab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ option(VOXELENGINE_BUILD_WINDOWS_VCPKG OFF) if(VOXELENGINE_BUILD_WINDOWS_VCPKG AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake") - set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") + set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") endif() cmake_minimum_required(VERSION 3.15) @@ -16,68 +16,68 @@ file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES}) if(VOXELENGINE_BUILD_APPDIR) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/.dirIcon) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) - install(TARGETS VoxelEngine DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/res DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/VoxelEngine) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/icons/hicolor/256x256) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.png DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/.dirIcon) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/share/applications) + file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/dev/VoxelEngine.desktop DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/lib) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) + install(TARGETS VoxelEngine DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/AppDir/usr/bin) endif() if(MSVC) if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) endif() if((CMAKE_BUILD_TYPE EQUAL "Release") OR (CMAKE_BUILD_TYPE EQUAL "RelWithDebInfo")) - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Release>") - target_compile_options(${PROJECT_NAME} PRIVATE /W4 /MT /O2) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Release>") + target_compile_options(${PROJECT_NAME} PRIVATE /W4 /MT /O2) else() - target_compile_options(${PROJECT_NAME} PRIVATE /W4) + target_compile_options(${PROJECT_NAME} PRIVATE /W4) endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /source-charset:UTF-8") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /source-charset:UTF-8") else() - target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra - # additional warnings - -Wformat-nonliteral -Wcast-align - -Wpointer-arith -Wundef - -Wwrite-strings -Wno-unused-parameter) - if (CMAKE_BUILD_TYPE MATCHES "Debug") - target_compile_options(${PROJECT_NAME} PRIVATE -Og) - endif() + target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra + # additional warnings + -Wformat-nonliteral -Wcast-align + -Wpointer-arith -Wundef + -Wwrite-strings -Wno-unused-parameter) + if (CMAKE_BUILD_TYPE MATCHES "Debug") + target_compile_options(${PROJECT_NAME} PRIVATE -Og) + endif() endif() if(VOXELENGINE_BUILD_WINDOWS_VCPKG AND WIN32) - if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") - find_package(Git QUIET) - if(GIT_FOUND) - message(STATUS "Adding vcpkg as a git submodule...") - execute_process(COMMAND ${GIT_EXECUTABLE} submodule add https://github.com/microsoft/vcpkg.git vcpkg WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - else() - message(FATAL_ERROR "Git not found, cannot add vcpkg submodule.") - endif() + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") + find_package(Git QUIET) + if(GIT_FOUND) + message(STATUS "Adding vcpkg as a git submodule...") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule add https://github.com/microsoft/vcpkg.git vcpkg WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + else() + message(FATAL_ERROR "Git not found, cannot add vcpkg submodule.") endif() + endif() - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") - message(STATUS "Initializing and updating vcpkg submodule...") - execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - execute_process(COMMAND ${CMAKE_COMMAND} -E chdir vcpkg ./bootstrap-vcpkg.bat WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - endif() + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/.git") + message(STATUS "Initializing and updating vcpkg submodule...") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + execute_process(COMMAND ${CMAKE_COMMAND} -E chdir vcpkg ./bootstrap-vcpkg.bat WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + endif() - foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES}) - string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE_UPPER) - add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_SOURCE_DIR}/res ${CMAKE_BINARY_DIR}/${CONFIG_TYPE_UPPER}/res) - endforeach() + foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE_UPPER) + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/res ${CMAKE_BINARY_DIR}/${CONFIG_TYPE_UPPER}/res) + endforeach() endif() find_package(OpenGL REQUIRED) @@ -87,19 +87,19 @@ find_package(ZLIB REQUIRED) if (WIN32) if(VOXELENGINE_BUILD_WINDOWS_VCPKG) - set(LUA_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/lib/lua51.lib") - set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/include/luajit") - find_package(glfw3 REQUIRED) - find_package(spng REQUIRED) - find_package(glm REQUIRED) - find_package(vorbis REQUIRED) - set(PNGLIB spng::spng) - set(VORBISLIB Vorbis::vorbis Vorbis::vorbisfile) + set(LUA_LIBRARIES "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/lib/lua51.lib") + set(LUA_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/packages/luajit_x64-windows/include/luajit") + find_package(glfw3 REQUIRED) + find_package(spng REQUIRED) + find_package(glm REQUIRED) + find_package(vorbis REQUIRED) + set(PNGLIB spng::spng) + set(VORBISLIB Vorbis::vorbis Vorbis::vorbisfile) else() - find_package(Lua REQUIRED) - set(PNGLIB spng) - set(VORBISLIB vorbis vorbisfile) # not tested - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/glfw) + find_package(Lua REQUIRED) + set(PNGLIB spng) + set(VORBISLIB vorbis vorbisfile) # not tested + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/libs/glfw) endif() elseif(APPLE) find_package(PkgConfig)