diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index 53d8a6e9..e5d69447 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -96,11 +96,12 @@ struct ContentPackStats { }; struct WorldFuncsSet { - bool onblockplaced : 1; - bool onblockreplaced : 1; - bool onblockbroken : 1; - bool onblockinteract : 1; - bool onplayertick : 1; + bool onblockplaced; + bool onblockreplaced; + bool onblockbreaking; + bool onblockbroken; + bool onblockinteract; + bool onplayertick; }; class ContentPackRuntime { diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index d9bc0065..92face2b 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -544,6 +544,7 @@ void PlayerController::updateInteraction(float delta) { } auto& target = indices->blocks.require(vox->id); if (lclick) { + scripting::on_block_breaking(&player, target, iend); if (player.isInstantDestruction() && target.breakable) { blocksController.breakBlock( &player, target, iend.x, iend.y, iend.z diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index d330eebf..96e9f06e 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -336,16 +336,24 @@ void scripting::random_update_block(const Block& block, const glm::ivec3& pos) { }); } -void scripting::on_block_placed( - Player* player, const Block& block, const glm::ivec3& pos +/// TODO: replace template with index +template +static bool on_block_common( + const std::string& suffix, + bool blockfunc, + 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, [pos, player](auto L) { - lua::pushivec_stack(L, pos); - lua::pushinteger(L, player ? player->getId() : -1); - return 4; - }); + bool result = false; + if (blockfunc) { + std::string name = block.name + "." + suffix; + result = + lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) { + lua::pushivec_stack(L, pos); + lua::pushinteger(L, player->getId()); + return 4; + }); } auto args = [&](lua::State* L) { lua::pushinteger(L, block.rt.id); @@ -354,93 +362,53 @@ void scripting::on_block_placed( return 5; }; for (auto& [packid, pack] : content->getPacks()) { - if (pack->worldfuncsset.onblockplaced) { + if (pack->worldfuncsset.*worldfunc) { lua::emit_event( - lua::get_main_state(), packid + ":.blockplaced", args + lua::get_main_state(), packid + ":.block" + suffix, args ); } } + return result; +} + +void scripting::on_block_placed( + Player* player, const Block& block, const glm::ivec3& pos +) { + on_block_common<&WorldFuncsSet::onblockplaced>( + "placed", block.rt.funcsset.onplaced, player, block, pos + ); } 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 - ); - } - } + on_block_common<&WorldFuncsSet::onblockreplaced>( + "replaced", block.rt.funcsset.onreplaced, player, block, pos + ); +} + +void scripting::on_block_breaking( + Player* player, const Block& block, const glm::ivec3& pos +) { + on_block_common<&WorldFuncsSet::onblockbreaking>( + "breaking", block.rt.funcsset.onbreaking, player, block, pos + ); } void scripting::on_block_broken( 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, - [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.onblockbroken) { - lua::emit_event( - lua::get_main_state(), packid + ":.blockbroken", args - ); - } - } + on_block_common<&WorldFuncsSet::onblockbroken>( + "broken", block.rt.funcsset.onbroken, player, block, pos + ); } bool scripting::on_block_interact( Player* player, const Block& block, const glm::ivec3& pos ) { - std::string name = block.name + ".interact"; - auto result = lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) { - lua::pushivec_stack(L, pos); - lua::pushinteger(L, player->getId()); - 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.onblockinteract) { - lua::emit_event( - lua::get_main_state(), packid + ":.blockinteract", args - ); - } - } - return result; + return on_block_common<&WorldFuncsSet::onblockinteract>( + "interact", block.rt.funcsset.oninteract, player, block, pos + ); } void scripting::on_player_tick(Player* player, int tps) { @@ -804,6 +772,8 @@ void scripting::load_content_script( funcsset.update = register_event(env, "on_update", prefix + ".update"); funcsset.randupdate = register_event(env, "on_random_update", prefix + ".randupdate"); + funcsset.onbreaking = + register_event(env, "on_breaking", prefix + ".breaking"); funcsset.onbroken = register_event(env, "on_broken", prefix + ".broken"); funcsset.onplaced = register_event(env, "on_placed", prefix + ".placed"); funcsset.onreplaced = @@ -857,6 +827,8 @@ void scripting::load_world_script( register_event(env, "on_world_quit", prefix + ":.worldquit"); funcsset.onblockplaced = register_event(env, "on_block_placed", prefix + ":.blockplaced"); + funcsset.onblockbreaking = + register_event(env, "on_block_breaking", prefix + ":.blockbreaking"); funcsset.onblockbroken = register_event(env, "on_block_broken", prefix + ":.blockbroken"); funcsset.onblockreplaced = diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 6bb31355..fb552f66 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -77,6 +77,9 @@ namespace scripting { void on_block_replaced( Player* player, const Block& block, const glm::ivec3& pos ); + void on_block_breaking( + 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 8ea11bee..83dafa47 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -38,6 +38,7 @@ struct BlockFuncsSet { bool init : 1; bool update : 1; bool onplaced : 1; + bool onbreaking : 1; bool onbroken : 1; bool onreplaced : 1; bool oninteract : 1;