From f9998f0a93189a35c9ab627ff118c03593e9bf48 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 14 Mar 2025 17:07:10 +0300 Subject: [PATCH] feat: world script reloading --- res/layouts/console.xml | 3 ++- res/layouts/console.xml.lua | 7 +++++- res/preload.json | 3 ++- res/textures/gui/world.png | Bin 0 -> 178 bytes src/content/Content.cpp | 8 +++++++ src/content/Content.hpp | 1 + src/content/ContentLoader.cpp | 27 ++++++++++++++-------- src/content/ContentLoader.hpp | 1 + src/logic/scripting/lua/libs/libworld.cpp | 13 +++++++++++ src/logic/scripting/scripting.cpp | 6 +++++ 10 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 res/textures/gui/world.png diff --git a/res/layouts/console.xml b/res/layouts/console.xml index 7b9bad3f..bc5fb343 100644 --- a/res/layouts/console.xml +++ b/res/layouts/console.xml @@ -39,7 +39,8 @@ - + -TA|cv8l2=nGryeNl~{+a*%AwM__qaqP3^ilaLf-yW>sDx5m?>ARP_KQ6n(*bA%A d^blo|KlbhN#~1qke}Rr*@O1TaS?83{1OS@*M*IK( literal 0 HcmV?d00001 diff --git a/src/content/Content.cpp b/src/content/Content.cpp index 1cc2fdd7..ce92be18 100644 --- a/src/content/Content.cpp +++ b/src/content/Content.cpp @@ -79,6 +79,14 @@ const ContentPackRuntime* Content::getPackRuntime(const std::string& id) const { return found->second.get(); } +ContentPackRuntime* Content::getPackRuntime(const std::string& id) { + auto found = packs.find(id); + if (found == packs.end()) { + return nullptr; + } + return found->second.get(); +} + const UptrsMap& Content::getBlockMaterials() const { return blockMaterials; } diff --git a/src/content/Content.hpp b/src/content/Content.hpp index a7f56b56..94650b25 100644 --- a/src/content/Content.hpp +++ b/src/content/Content.hpp @@ -248,6 +248,7 @@ public: const rigging::SkeletonConfig* getSkeleton(const std::string& id) const; const BlockMaterial* findBlockMaterial(const std::string& id) const; const ContentPackRuntime* getPackRuntime(const std::string& id) const; + ContentPackRuntime* getPackRuntime(const std::string& id); const UptrsMap& getBlockMaterials() const; const UptrsMap& getPacks() const; diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 47fca715..3fb2b8f6 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -889,6 +889,21 @@ void ContentLoader::reloadScript(const Content& content, ItemDef& item) { load_script(content, item); } +void ContentLoader::loadWorldScript(ContentPackRuntime& runtime) { + const auto& pack = runtime.getInfo(); + const auto& folder = pack.folder; + io::path scriptFile = folder / "scripts/world.lua"; + if (io::is_regular_file(scriptFile)) { + scripting::load_world_script( + runtime.getEnvironment(), + pack.id, + scriptFile, + pack.id + ":scripts/world.lua", + runtime.worldfuncsset + ); + } +} + void ContentLoader::loadScripts(Content& content) { load_scripts(content, content.blocks); load_scripts(content, content.items); @@ -898,16 +913,8 @@ void ContentLoader::loadScripts(Content& content) { const auto& folder = pack.folder; // Load main world script - io::path scriptFile = folder / "scripts/world.lua"; - if (io::is_regular_file(scriptFile)) { - scripting::load_world_script( - runtime->getEnvironment(), - pack.id, - scriptFile, - pack.id + ":scripts/world.lua", - runtime->worldfuncsset - ); - } + loadWorldScript(*runtime); + // Load entity components io::path componentsDir = folder / "scripts/components"; foreach_file(componentsDir, [&pack](const io::path& file) { diff --git a/src/content/ContentLoader.hpp b/src/content/ContentLoader.hpp index 8860cc77..eeedf11b 100644 --- a/src/content/ContentLoader.hpp +++ b/src/content/ContentLoader.hpp @@ -77,6 +77,7 @@ public: void load(); static void loadScripts(Content& content); + static void loadWorldScript(ContentPackRuntime& pack); static void reloadScript(const Content& content, Block& block); static void reloadScript(const Content& content, ItemDef& item); }; diff --git a/src/logic/scripting/lua/libs/libworld.cpp b/src/logic/scripting/lua/libs/libworld.cpp index f54ce4e3..acf9bf64 100644 --- a/src/logic/scripting/lua/libs/libworld.cpp +++ b/src/logic/scripting/lua/libs/libworld.cpp @@ -6,6 +6,7 @@ #include "assets/AssetsLoader.hpp" #include "coders/json.hpp" #include "content/Content.hpp" +#include "content/ContentLoader.hpp" #include "engine/Engine.hpp" #include "world/files/WorldFiles.hpp" #include "io/engine_paths.hpp" @@ -213,6 +214,17 @@ static int l_count_chunks(lua::State* L) { return lua::pushinteger(L, level->chunks->size()); } +static int l_reload_script(lua::State* L) { + auto packid = lua::require_string(L, 1); + if (content == nullptr) { + throw std::runtime_error("content is not initialized"); + } + auto& writeableContent = *engine->getWriteableContent(); + auto pack = writeableContent.getPackRuntime(packid); + ContentLoader::loadWorldScript(*pack); + return 0; +} + const luaL_Reg worldlib[] = { {"is_open", lua::wrap}, {"get_list", lua::wrap}, @@ -230,5 +242,6 @@ const luaL_Reg worldlib[] = { {"set_chunk_data", lua::wrap}, {"save_chunk_data", lua::wrap}, {"count_chunks", lua::wrap}, + {"reload_script", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 4e7b37e0..eabbd392 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -836,6 +836,8 @@ void scripting::load_content_script( ) { int env = *senv; lua::pop(lua::get_main_state(), load_script(env, "block", file, fileName)); + + funcsset = {}; funcsset.init = register_event(env, "init", prefix + ".init"); funcsset.update = register_event(env, "on_update", prefix + ".update"); funcsset.randupdate = @@ -861,6 +863,8 @@ void scripting::load_content_script( ) { int env = *senv; lua::pop(lua::get_main_state(), load_script(env, "item", file, fileName)); + + funcsset = {}; funcsset.init = register_event(env, "init", prefix + ".init"); funcsset.on_use = register_event(env, "on_use", prefix + ".use"); funcsset.on_use_on_block = @@ -888,6 +892,8 @@ void scripting::load_world_script( ) { int env = *senv; lua::pop(lua::get_main_state(), load_script(env, "world", file, fileName)); + + funcsset = {}; register_event(env, "init", prefix + ".init"); register_event(env, "on_world_open", prefix + ":.worldopen"); register_event(env, "on_world_tick", prefix + ":.worldtick");