Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add API for mods to hook liquid transformation events (#11405)
Add API for mods to hook liquid transformation events

Without this API, there is no reliable way for mods to be
notified when liquid transform modifies nodes and mods are
forced to poll for changes.  This allows mods to detect
changes to flowing liquid nodes and liquid renewal using
event-driven logic.
  • Loading branch information
Warr1024 committed Jul 9, 2021
1 parent e9bc59e commit 52128ae
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions builtin/game/register.lua
Expand Up @@ -610,6 +610,7 @@ core.registered_on_modchannel_message, core.register_on_modchannel_message = mak
core.registered_on_player_inventory_actions, core.register_on_player_inventory_action = make_registration()
core.registered_allow_player_inventory_actions, core.register_allow_player_inventory_action = make_registration()
core.registered_on_rightclickplayers, core.register_on_rightclickplayer = make_registration()
core.registered_on_liquid_transformed, core.register_on_liquid_transformed = make_registration()

--
-- Compatibility for on_mapgen_init()
Expand Down
6 changes: 6 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -4859,6 +4859,12 @@ Call these functions only at load time!
* Called when an incoming mod channel message is received
* You should have joined some channels to receive events.
* If message comes from a server mod, `sender` field is an empty string.
* `minetest.register_on_liquid_transformed(function(post_list, node_list))`
* Called after liquid nodes are modified by the engine's liquid transformation
process.
* `pos_list` is an array of all modified positions.
* `node_list` is an array of the old node that was previously at the position
with the corresponding index in pos_list.

Setting-related
---------------
Expand Down
2 changes: 1 addition & 1 deletion src/map.cpp
Expand Up @@ -829,7 +829,7 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
m_transforming_liquid.push_back(iter);

voxalgo::update_lighting_nodes(this, changed_nodes, modified_blocks);

env->getScriptIface()->on_liquid_transformed(changed_nodes);

/* ----------------------------------------------------------------------
* Manage the queue so that it does not grow indefinately
Expand Down
34 changes: 34 additions & 0 deletions src/script/cpp_api/s_env.cpp
Expand Up @@ -25,6 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen/mapgen.h"
#include "lua_api/l_env.h"
#include "server.h"
#include "script/common/c_content.h"


void ScriptApiEnv::environment_OnGenerated(v3s16 minp, v3s16 maxp,
u32 blockseed)
Expand Down Expand Up @@ -267,3 +269,35 @@ void ScriptApiEnv::on_emerge_area_completion(
luaL_unref(L, LUA_REGISTRYINDEX, state->args_ref);
}
}

void ScriptApiEnv::on_liquid_transformed(
const std::vector<std::pair<v3s16, MapNode>> &list)
{
SCRIPTAPI_PRECHECKHEADER

// Get core.registered_on_liquid_transformed
lua_getglobal(L, "core");
lua_getfield(L, -1, "registered_on_liquid_transformed");
luaL_checktype(L, -1, LUA_TTABLE);
lua_remove(L, -2);

// Skip converting list and calling hook if there are
// no registered callbacks.
if(lua_objlen(L, -1) < 1) return;

// Convert the list to a pos array and a node array for lua
int index = 1;
const NodeDefManager *ndef = getEnv()->getGameDef()->ndef();
lua_createtable(L, list.size(), 0);
lua_createtable(L, list.size(), 0);
for(std::pair<v3s16, MapNode> p : list) {
lua_pushnumber(L, index);
push_v3s16(L, p.first);
lua_rawset(L, -4);
lua_pushnumber(L, index++);
pushnode(L, p.second, ndef);
lua_rawset(L, -3);
}

runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
}
5 changes: 5 additions & 0 deletions src/script/cpp_api/s_env.h
Expand Up @@ -21,6 +21,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,

#include "cpp_api/s_base.h"
#include "irr_v3d.h"
#include "mapnode.h"
#include <vector>

class ServerEnvironment;
struct ScriptCallbackState;
Expand All @@ -41,5 +43,8 @@ class ScriptApiEnv : virtual public ScriptApiBase
void on_emerge_area_completion(v3s16 blockpos, int action,
ScriptCallbackState *state);

// Called after liquid transform changes
void on_liquid_transformed(const std::vector<std::pair<v3s16, MapNode>> &list);

void initializeEnvironment(ServerEnvironment *env);
};

0 comments on commit 52128ae

Please sign in to comment.