diff --git a/doc/en/scripting/events.md b/doc/en/scripting/events.md index 8dcd1a06..4b13ec7b 100644 --- a/doc/en/scripting/events.md +++ b/doc/en/scripting/events.md @@ -16,6 +16,12 @@ function on_broken(x, y, z, playerid) Called on block broken by player +```lua +function on_replaced(x, y, z, playerid) +``` + +Called on block replaced with other by player + ```lua function on_interact(x, y, z, playerid) -> bool ``` diff --git a/doc/ru/scripting/events.md b/doc/ru/scripting/events.md index 6d908459..08192cfa 100644 --- a/doc/ru/scripting/events.md +++ b/doc/ru/scripting/events.md @@ -16,6 +16,12 @@ function on_broken(x, y, z, playerid) Вызывается после разрушения блока игроком +```lua +function on_replaced(x, y, z, playerid) +``` + +Вызывается после замены блока игроком + ```lua function on_interact(x, y, z, playerid) -> bool ``` diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index b790d0e7..857f4fe0 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 onblockreplaced : 1; bool onblockbroken : 1; bool onblockinteract : 1; bool onplayertick : 1; diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 01679546..980c8bfe 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -75,6 +75,13 @@ void BlocksController::breakBlock( void BlocksController::placeBlock( Player* player, const Block& def, blockstate state, int x, int y, int z ) { + auto voxel = chunks.get(x, y, z); + if (voxel == nullptr) { + return; + } + const auto& prevDef = level.content->getIndices()->blocks.require(voxel->id); + scripting::on_block_replaced(player, prevDef, {x, y, z}); + onBlockInteraction( player, glm::ivec3(x, y, z), def, BlockInteraction::placing ); diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 0778fd45..055ecf34 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -284,6 +284,32 @@ void scripting::on_block_placed( } } +void scripting::on_block_replaced( + Player* player, const Block& block, const glm::ivec3& pos +) { + if (block.rt.funcsset.onreplaced) { + std::string name = block.name + ".replaced"; + 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 args = [&](lua::State* L) { + lua::pushinteger(L, block.rt.id); + lua::pushivec_stack(L, pos); + lua::pushinteger(L, player ? player->getId() : -1); + return 5; + }; + for (auto& [packid, pack] : content->getPacks()) { + if (pack->worldfuncsset.onblockreplaced) { + lua::emit_event( + lua::get_main_state(), packid + ":.blockreplaced", args + ); + } + } +} + void scripting::on_block_broken( Player* player, const Block& block, const glm::ivec3& pos ) { @@ -701,6 +727,8 @@ void scripting::load_content_script( register_event(env, "on_random_update", prefix + ".randupdate"); funcsset.onbroken = register_event(env, "on_broken", prefix + ".broken"); funcsset.onplaced = register_event(env, "on_placed", prefix + ".placed"); + funcsset.onreplaced = + register_event(env, "on_replaced", prefix + ".replaced"); funcsset.oninteract = register_event(env, "on_interact", prefix + ".interact"); funcsset.onblockstick = @@ -752,6 +780,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.onblockreplaced = + register_event(env, "on_block_replaced", prefix + ":.blockreplaced"); funcsset.onblockinteract = register_event(env, "on_block_interact", prefix + ":.blockinteract"); funcsset.onplayertick = diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 3cd8a022..0ab3c035 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -71,6 +71,9 @@ namespace scripting { void on_block_placed( Player* player, const Block& block, const glm::ivec3& pos ); + void on_block_replaced( + Player* player, const Block& block, const glm::ivec3& pos + ); void on_block_broken( Player* player, const Block& block, const glm::ivec3& pos ); diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 4fe51b0d..95768c88 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -39,6 +39,7 @@ struct block_funcs_set { bool update : 1; bool onplaced : 1; bool onbroken : 1; + bool onreplaced : 1; bool oninteract : 1; bool randupdate : 1; bool onblockstick : 1;