From f6f82644d447756636bdf81a2cc83591c11371ec Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 5 Nov 2024 13:55:07 +0300 Subject: [PATCH] add on_block_interact world event --- doc/en/scripting/events.md | 6 +++ doc/ru/scripting/events.md | 6 +++ src/content/ContentPack.hpp | 1 + src/logic/BlocksController.cpp | 13 ++++--- src/logic/scripting/scripting.cpp | 64 ++++++++++++++++++------------- src/logic/scripting/scripting.hpp | 10 ++--- 6 files changed, 63 insertions(+), 37 deletions(-) diff --git a/doc/en/scripting/events.md b/doc/en/scripting/events.md index 10b9e3f1..ccc61673 100644 --- a/doc/en/scripting/events.md +++ b/doc/en/scripting/events.md @@ -102,6 +102,12 @@ function on_block_broken(blockid, x, y, z, playerid) Called on block broken by player +```lua +function on_block_interact(blockid, x, y, z, playerid) -> bool +``` + +Called on block RMB click interaction. Prevents block placing if **true** returned. + ## Layout events Script *layouts/layout_name.xml.lua* events. diff --git a/doc/ru/scripting/events.md b/doc/ru/scripting/events.md index d7805d60..31c958fc 100644 --- a/doc/ru/scripting/events.md +++ b/doc/ru/scripting/events.md @@ -102,6 +102,12 @@ function on_block_broken(blockid, x, y, z, playerid) Вызывается после разрушения блока игроком +```lua +function on_block_interact(blockid, x, y, z, playerid) -> bool +``` + +Вызывается при нажатии на блок ПКМ. Предотвращает установку блоков, если возвращает `true` + ## События макета События прописываются в файле `layouts/имя_макета.xml.lua`. diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index 082d2eea..5aa1a22b 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -97,6 +97,7 @@ struct ContentPackStats { struct world_funcs_set { bool onblockplaced : 1; bool onblockbroken : 1; + bool onblockinteract : 1; }; class ContentPackRuntime { diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index cad8ae70..b0362fd9 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -64,7 +64,7 @@ void BlocksController::breakBlock( ); chunks->set(x, y, z, 0, {}); lighting->onBlockSet(x, y, z, 0); - scripting::on_block_broken(player, def, x, y, z); + scripting::on_block_broken(player, def, glm::ivec3(x, y, z)); if (def.rt.extended) { updateSides(x, y, z , def.size.x, def.size.y, def.size.z); } else { @@ -80,7 +80,7 @@ void BlocksController::placeBlock( ); chunks->set(x, y, z, def.rt.id, state); lighting->onBlockSet(x, y, z, def.rt.id); - scripting::on_block_placed(player, def, x, y, z); + scripting::on_block_placed(player, def, glm::ivec3(x, y, z)); if (def.rt.extended) { updateSides(x, y, z , def.size.x, def.size.y, def.size.z); } else { @@ -91,7 +91,7 @@ void BlocksController::placeBlock( void BlocksController::updateBlock(int x, int y, int z) { voxel* vox = chunks->get(x, y, z); if (vox == nullptr) return; - auto& def = level->content->getIndices()->blocks.require(vox->id); + const auto& def = level->content->getIndices()->blocks.require(vox->id); if (def.grounded) { const auto& vec = get_ground_direction(def, vox->state.rotation); if (!chunks->isSolidBlock(x + vec.x, y + vec.y, z + vec.z)) { @@ -100,7 +100,7 @@ void BlocksController::updateBlock(int x, int y, int z) { } } if (def.rt.funcsset.update) { - scripting::update_block(def, x, y, z); + scripting::update_block(def, glm::ivec3(x, y, z)); } } @@ -144,7 +144,10 @@ void BlocksController::randomTick( auto& block = indices->blocks.require(vox.id); if (block.rt.funcsset.randupdate) { scripting::random_update_block( - block, chunk.x * CHUNK_W + bx, by, chunk.z * CHUNK_D + bz + block, + glm::ivec3( + chunk.x * CHUNK_W + bx, by, chunk.z * CHUNK_D + bz + ) ); } } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 70a397b4..a573a89b 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -216,82 +216,81 @@ void scripting::on_blocks_tick(const Block& block, int tps) { }); } -void scripting::update_block(const Block& block, int x, int y, int z) { +void scripting::update_block(const Block& block, const glm::ivec3& pos) { std::string name = block.name + ".update"; - lua::emit_event(lua::get_main_state(), name, [x, y, z](auto L) { - return lua::pushivec_stack(L, glm::ivec3(x, y, z)); + lua::emit_event(lua::get_main_state(), name, [pos](auto L) { + return lua::pushivec_stack(L, pos); }); } -void scripting::random_update_block(const Block& block, int x, int y, int z) { +void scripting::random_update_block(const Block& block, const glm::ivec3& pos) { std::string name = block.name + ".randupdate"; - lua::emit_event(lua::get_main_state(), name, [x, y, z](auto L) { - return lua::pushivec_stack(L, glm::ivec3(x, y, z)); + lua::emit_event(lua::get_main_state(), name, [pos](auto L) { + return lua::pushivec_stack(L, pos); }); } +static std::function create_world_block_event_args( + const glm::ivec3& pos, const Block& block, Player* player +) { + return [&](lua::State* L) { + lua::pushinteger(L, block.rt.id); + lua::pushivec_stack(L, pos); + lua::pushinteger(L, player ? player->getId() : -1); + return 5; + }; +} + void scripting::on_block_placed( - Player* player, const Block& block, int x, int y, int z + Player* player, const Block& block, const glm::ivec3& pos ) { if (block.rt.funcsset.onplaced) { std::string name = block.name + ".placed"; - lua::emit_event(lua::get_main_state(), name, [x, y, z, player](auto L) { - lua::pushivec_stack(L, glm::ivec3(x, y, z)); + lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) { + lua::pushivec_stack(L, pos); lua::pushinteger(L, player ? player->getId() : -1); return 4; }); } - auto world_event_args = [&](lua::State* L) { - lua::pushinteger(L, block.rt.id); - lua::pushivec_stack(L, glm::ivec3(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_state(), packid + ":.blockplaced", - world_event_args + create_world_block_event_args(pos, block, player) ); } } } void scripting::on_block_broken( - Player* player, const Block& block, int x, int y, int z + Player* player, const Block& block, const glm::ivec3& pos ) { if (block.rt.funcsset.onbroken) { std::string name = block.name + ".broken"; lua::emit_event( lua::get_main_state(), name, - [x, y, z, player](auto L) { - lua::pushivec_stack(L, glm::ivec3(x, y, z)); + [pos, player](auto L) { + lua::pushivec_stack(L, pos); lua::pushinteger(L, player ? player->getId() : -1); return 4; } ); } - auto world_event_args = [&](lua::State* L) { - lua::pushinteger(L, block.rt.id); - lua::pushivec_stack(L, glm::ivec3(x, y, z)); - 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_state(), packid + ":.blockbroken", - world_event_args + create_world_block_event_args(pos, block, player) ); } } } bool scripting::on_block_interact( - Player* player, const Block& block, glm::ivec3 pos + Player* player, const Block& block, const glm::ivec3& pos ) { std::string name = block.name + ".interact"; return lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) { @@ -299,6 +298,15 @@ bool scripting::on_block_interact( lua::pushinteger(L, player->getId()); return 4; }); + for (auto& [packid, pack] : content->getPacks()) { + if (pack->worldfuncsset.onblockinteract) { + lua::emit_event( + lua::get_main_state(), + packid + ":.blockinteract", + create_world_block_event_args(pos, block, player) + ); + } + } } bool scripting::on_item_use(Player* player, const ItemDef& item) { @@ -697,6 +705,8 @@ void scripting::load_world_script( register_event(env, "on_block_placed", prefix + ":.blockplaced"); funcsset.onblockbroken = register_event(env, "on_block_broken", prefix + ":.blockbroken"); + funcsset.onblockinteract = + register_event(env, "on_block_interact", prefix + ":.blockinteract"); } void scripting::load_layout_script( diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index af9bb4c2..2b3eab90 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -64,15 +64,15 @@ namespace scripting { void on_world_quit(); void cleanup(); void on_blocks_tick(const Block& block, int tps); - void update_block(const Block& block, int x, int y, int z); - void random_update_block(const Block& block, int x, int y, int z); + void update_block(const Block& block, const glm::ivec3& pos); + void random_update_block(const Block& block, const glm::ivec3& pos); void on_block_placed( - Player* player, const Block& block, int x, int y, int z + Player* player, const Block& block, const glm::ivec3& pos ); void on_block_broken( - Player* player, const Block& block, int x, int y, int z + Player* player, const Block& block, const glm::ivec3& pos ); - bool on_block_interact(Player* player, const Block& block, glm::ivec3 pos); + bool on_block_interact(Player* player, const Block& block, const glm::ivec3& pos); /// @brief Called on RMB click with the item selected /// @return true if prevents default action