diff --git a/builtin/client/register.lua b/builtin/client/register.lua index c932fb9f8..c8a5ddbda 100644 --- a/builtin/client/register.lua +++ b/builtin/client/register.lua @@ -66,5 +66,6 @@ core.registered_on_death, core.register_on_death = make_registration() core.registered_on_hp_modification, core.register_on_hp_modification = make_registration() core.registered_on_damage_taken, core.register_on_damage_taken = make_registration() core.registered_on_formspec_input, core.register_on_formspec_input = make_registration() +core.registered_on_dignode, core.register_on_dignode = make_registration() diff --git a/clientmods/preview/init.lua b/clientmods/preview/init.lua index f03e8e112..3085eda24 100644 --- a/clientmods/preview/init.lua +++ b/clientmods/preview/init.lua @@ -42,3 +42,9 @@ core.register_chatcommand("dump", { core.after(2, function() print("[PREVIEW] loaded " .. modname .. " mod") end) + +core.register_on_dignode(function(pos, node) + print("pos:" .. dump(pos)) + print("node:" .. dump(node)) + return false +end) \ No newline at end of file diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index 3170f4c84..886dbc6e1 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -703,6 +703,10 @@ Call these functions only at load time! * Called when a button is pressed in player's inventory form * Newest functions are called first * If function returns `true`, remaining functions are not called +* `minetest.register_on_dignode(func(pos, node))` + * Called when a player digs a node + * Newest functions are called first + * If any function returns true, the node isn't dug ### Sounds * `minetest.sound_play(spec, parameters)`: returns a handle * `spec` is a `SimpleSoundSpec` diff --git a/src/game.cpp b/src/game.cpp index c84e08b01..66c8859c8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3967,20 +3967,8 @@ void Game::handleDigging(GameRunData *runData, client->setCrack(runData->dig_index, nodepos); } else { infostream << "Digging completed" << std::endl; - client->interact(2, pointed); client->setCrack(-1, v3s16(0, 0, 0)); - bool is_valid_position; - MapNode wasnode = map.getNodeNoEx(nodepos, &is_valid_position); - if (is_valid_position) - client->removeNode(nodepos); - - if (m_cache_enable_particles) { - const ContentFeatures &features = - client->getNodeDefManager()->get(wasnode); - client->getParticleManager()->addDiggingParticles(client, smgr, - player, nodepos, wasnode, features); - } - + runData->dig_time = 0; runData->digging = false; @@ -3999,6 +3987,26 @@ void Game::handleDigging(GameRunData *runData, if (runData->nodig_delay_timer < mindelay) runData->nodig_delay_timer = mindelay; + bool is_valid_position; + MapNode wasnode = map.getNodeNoEx(nodepos, &is_valid_position); + if (is_valid_position) { + bool block = client->getScript()->on_dignode(nodepos, wasnode); + if (block) { + return; + } + client->removeNode(nodepos); + } + + client->interact(2, pointed); + + if (m_cache_enable_particles) { + const ContentFeatures &features = + client->getNodeDefManager()->get(wasnode); + client->getParticleManager()->addDiggingParticles(client, smgr, + player, nodepos, wasnode, features); + } + + // Send event to trigger sound MtEvent *e = new NodeDugEvent(nodepos, wasnode); client->event()->put(e); diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp index 1827d483b..2c8fee334 100644 --- a/src/script/cpp_api/s_client.cpp +++ b/src/script/cpp_api/s_client.cpp @@ -21,6 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "s_client.h" #include "s_internal.h" #include "client.h" +#include "common/c_converter.h" +#include "common/c_content.h" void ScriptApiClient::on_shutdown() { @@ -136,3 +138,23 @@ void ScriptApiClient::on_formspec_input(const std::string &formname, } runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC); } + +bool ScriptApiClient::on_dignode(v3s16 p, MapNode node) +{ + SCRIPTAPI_PRECHECKHEADER + + INodeDefManager *ndef = getClient()->ndef(); + + // Get core.registered_on_dignode + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_dignode"); + + // Push data + push_v3s16(L, p); + pushnode(L, node, ndef); + + // Call functions + runCallbacks(2, RUN_CALLBACKS_MODE_OR); + bool blocked = lua_toboolean(L, -1); + return blocked; +} \ No newline at end of file diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h index 42c41f8a4..09fd3a691 100644 --- a/src/script/cpp_api/s_client.h +++ b/src/script/cpp_api/s_client.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "cpp_api/s_base.h" #include "util/string.h" +#include "mapnode.h" #ifdef _CRT_MSVCP_CURRENT #include @@ -43,5 +44,7 @@ public: void on_death(); void environment_step(float dtime); void on_formspec_input(const std::string &formname, const StringMap &fields); + + bool on_dignode(v3s16 p, MapNode node); }; #endif