Skip to content

Commit cca58fe

Browse files
sofarparamat
authored andcommittedApr 22, 2017
Add on_flood() callback.
This callback is called if a liquid definitely floods a non-air node on the map. The callback arguments are (pos, oldnode, newnode) and can return a `bool` value indicating whether flooding the node should be cancelled (`return true` will prevent the node from flooding). Documentation is added, the callback function was tested with a modified minetest_game. Note that `return true` will likely cause the node's `on_flood()` callback to be called every second until the node gets removed, so care must be taken to prevent many callbacks from using this return value. The current default liquid update interval is 1.0 seconds, which isn't unmanageable. The larger aim of this patch is to remove the lava cooling ABM, which is a significant cost to idle servers that have lava on their map. This callback will be much more efficient.
1 parent 8464da7 commit cca58fe

File tree

6 files changed

+43
-3
lines changed

6 files changed

+43
-3
lines changed
 

‎doc/lua_api.txt

+7
Original file line numberDiff line numberDiff line change
@@ -4002,6 +4002,13 @@ Definition tables
40024002
^ Node destructor; called after removing node
40034003
^ Not called for bulk node placement (i.e. schematics and VoxelManip)
40044004
^ default: nil ]]
4005+
on_flood = func(pos, oldnode, newnode), --[[
4006+
^ Called when a liquid (newnode) is about to flood oldnode, if
4007+
^ it has `floodable = true` in the nodedef. Not called for bulk
4008+
^ node placement (i.e. schematics and VoxelManip) or air nodes. If
4009+
^ return true the node is not flooded, but on_flood callback will
4010+
^ most likely be called over and over again every liquid update
4011+
^ interval. Default: nil ]]
Has conversations. Original line has conversations.
40054012

40064013
after_place_node = func(pos, placer, itemstack, pointed_thing) --[[
40074014
^ Called after constructing node when node was placed using

‎src/map.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
4444
#include "database.h"
4545
#include "database-dummy.h"
4646
#include "database-sqlite3.h"
47+
#include "script/serverscripting.h"
4748
#include <deque>
4849
#include <queue>
4950
#if USE_LEVELDB
@@ -637,7 +638,8 @@ s32 Map::transforming_liquid_size() {
637638
return m_transforming_liquid.size();
638639
}
639640

640-
void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks)
641+
void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
642+
ServerEnvironment *env)
641643
{
642644
DSTACK(FUNCTION_NAME);
643645
//TimeTaker timer("transformLiquids()");
@@ -897,8 +899,16 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks)
897899
// set the liquid level and flow bit to 0
898900
n0.param2 = ~(LIQUID_LEVEL_MASK | LIQUID_FLOW_DOWN_MASK);
899901
}
902+
903+
// change the node.
900904
n0.setContent(new_node_content);
901905

906+
// on_flood() the node
907+
if (floodable_node != CONTENT_AIR) {
908+
if (env->getScriptIface()->node_on_flood(p0, n00, n0))
909+
continue;
910+
}
911+
902912
// Ignore light (because calling voxalgo::update_lighting_nodes)
903913
n0.setLight(LIGHTBANK_DAY, 0, m_nodedef);
904914
n0.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);

‎src/map.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ class Map /*: public NodeContainer*/
266266
// For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
267267
virtual void PrintInfo(std::ostream &out);
268268

269-
void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks);
269+
void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks,
270+
ServerEnvironment *env);
270271

271272
/*
272273
Node metadata

‎src/script/cpp_api/s_node.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,27 @@ void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
178178
lua_pop(L, 1); // Pop error handler
179179
}
180180

181+
bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode)
182+
{
183+
SCRIPTAPI_PRECHECKHEADER
184+
185+
int error_handler = PUSH_ERROR_HANDLER(L);
186+
187+
INodeDefManager *ndef = getServer()->ndef();
188+
189+
// Push callback function on stack
190+
if (!getItemCallback(ndef->get(node).name.c_str(), "on_flood"))
191+
return false;
192+
193+
// Call function
194+
push_v3s16(L, p);
195+
pushnode(L, node, ndef);
196+
pushnode(L, newnode, ndef);
197+
PCALL_RES(lua_pcall(L, 3, 1, error_handler));
198+
lua_remove(L, error_handler);
199+
return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
200+
}
201+
181202
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
182203
{
183204
SCRIPTAPI_PRECHECKHEADER

‎src/script/cpp_api/s_node.h

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ScriptApiNode
4242
ServerActiveObject *digger);
4343
void node_on_construct(v3s16 p, MapNode node);
4444
void node_on_destruct(v3s16 p, MapNode node);
45+
bool node_on_flood(v3s16 p, MapNode node, MapNode newnode);
4546
void node_after_destruct(v3s16 p, MapNode node);
4647
bool node_on_timer(v3s16 p, MapNode node, f32 dtime);
4748
void node_on_receive_fields(v3s16 p,

‎src/server.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ void Server::AsyncRunStep(bool initial_step)
599599
ScopeProfiler sp(g_profiler, "Server: liquid transform");
600600

601601
std::map<v3s16, MapBlock*> modified_blocks;
602-
m_env->getMap().transformLiquids(modified_blocks);
602+
m_env->getMap().transformLiquids(modified_blocks, m_env);
603603
#if 0
604604
/*
605605
Update lighting

0 commit comments

Comments
 (0)
Please sign in to comment.