diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 5f690f3d..56480dfb 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -34,6 +34,7 @@ ContentLoader::ContentLoader(ContentPack* pack, ContentBuilder& builder) ); stats = &runtime->getStatsWriteable(); env = runtime->getEnvironment(); + this->runtime = runtime.get(); builder.add(std::move(runtime)); } @@ -408,7 +409,7 @@ void ContentLoader::load() { fs::path scriptFile = folder/fs::path("scripts/world.lua"); if (fs::is_regular_file(scriptFile)) { - scripting::load_world_script(env, pack->id, scriptFile); + scripting::load_world_script(env, pack->id, scriptFile, runtime->worldfuncsset); } if (!fs::is_regular_file(pack->getContentFile())) diff --git a/src/content/ContentLoader.hpp b/src/content/ContentLoader.hpp index 321f2e90..2aa243df 100644 --- a/src/content/ContentLoader.hpp +++ b/src/content/ContentLoader.hpp @@ -14,7 +14,9 @@ struct BlockMaterial; struct ItemDef; struct EntityDef; struct ContentPack; + class ContentBuilder; +class ContentPackRuntime; struct ContentPackStats; namespace dynamic { @@ -24,6 +26,7 @@ namespace dynamic { class ContentLoader { const ContentPack* pack; + ContentPackRuntime* runtime; scriptenv env; ContentBuilder& builder; ContentPackStats* stats; diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index 1dc17521..88c81a4e 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -80,11 +80,18 @@ struct ContentPackStats { } }; +struct world_funcs_set { + bool onblockplaced : 1; + bool onblockbroken : 1; +}; + class ContentPackRuntime { ContentPack info; ContentPackStats stats {}; scriptenv env; public: + world_funcs_set worldfuncsset {}; + ContentPackRuntime( ContentPack info, scriptenv env diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 28f84247..218100c1 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -73,9 +73,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, {}); lighting->onBlockSet(x,y,z, 0); - if (def->rt.funcsset.onbroken) { - scripting::on_block_broken(player, def, x, y, z); - } + scripting::on_block_broken(player, def, x, y, z); updateSides(x, y, z); } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 10a74a71..171ddef0 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -219,15 +219,39 @@ void scripting::on_block_placed(Player* player, const Block* block, int x, int y lua::pushinteger(L, player->getId()); return 4; }); + auto world_event_args = [block, x, y, z, player] (lua::State* L) { + lua::pushinteger(L, block->rt.id); + lua::pushivec3(L, x, y, z); + lua::pushinteger(L, player ? player->getId() : -1); + return 5; + }; + for (auto& [packid, pack] : content->getPacks()) { + if (pack->worldfuncsset.onblockplaced) { + lua::emit_event(lua::get_main_thread(), packid + ".blockplaced", world_event_args); + } + } } void scripting::on_block_broken(Player* player, const Block* block, int x, int y, int z) { std::string name = block->name + ".broken"; - lua::emit_event(lua::get_main_thread(), name, [x, y, z, player] (auto L) { + if (block->rt.funcsset.onbroken) { + lua::emit_event(lua::get_main_thread(), name, [x, y, z, player] (auto L) { + lua::pushivec3(L, x, y, z); + lua::pushinteger(L, player->getId()); + return 4; + }); + } + auto world_event_args = [block, x, y, z, player] (lua::State* L) { + lua::pushinteger(L, block->rt.id); lua::pushivec3(L, x, y, z); - lua::pushinteger(L, player->getId()); - return 4; - }); + lua::pushinteger(L, player ? player->getId() : -1); + return 5; + }; + for (auto& [packid, pack] : content->getPacks()) { + if (pack->worldfuncsset.onblockbroken) { + lua::emit_event(lua::get_main_thread(), packid + ".blockbroken", world_event_args); + } + } } bool scripting::on_block_interact(Player* player, const Block* block, glm::ivec3 pos) { @@ -523,7 +547,10 @@ void scripting::load_entity_component(const std::string& name, const fs::path& f lua::store_in(L, lua::CHUNKS_TABLE, name); } -void scripting::load_world_script(const scriptenv& senv, const std::string& prefix, const fs::path& file) { +void scripting::load_world_script(const scriptenv& senv, + const std::string& prefix, + const fs::path& file, + world_funcs_set& funcsset) { int env = *senv; load_script(env, "world", file); register_event(env, "init", prefix+".init"); @@ -531,6 +558,8 @@ void scripting::load_world_script(const scriptenv& senv, const std::string& pref register_event(env, "on_world_tick", prefix+".worldtick"); register_event(env, "on_world_save", prefix+".worldsave"); register_event(env, "on_world_quit", prefix+".worldquit"); + funcsset.onblockplaced = register_event(env, "on_block_placed", prefix+".blockplaced"); + funcsset.onblockbroken = register_event(env, "on_block_broken", prefix+".blockbroken"); } void scripting::load_layout_script(const scriptenv& senv, const std::string& prefix, const fs::path& file, uidocscript& script) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 50849f66..be06b371 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -27,6 +27,7 @@ class Inventory; class UiDocument; struct block_funcs_set; struct item_funcs_set; +struct world_funcs_set; struct UserComponent; struct uidocscript; class BlocksController; @@ -134,7 +135,7 @@ namespace scripting { /// @param env environment /// @param packid content-pack id /// @param file script file path - void load_world_script(const scriptenv& env, const std::string& packid, const fs::path& file); + void load_world_script(const scriptenv& env, const std::string& packid, const fs::path& file, world_funcs_set& funcsset); /// @brief Load script associated with an UiDocument /// @param env environment