summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt7
-rw-r--r--src/map.cpp12
-rw-r--r--src/map.h3
-rw-r--r--src/script/cpp_api/s_node.cpp21
-rw-r--r--src/script/cpp_api/s_node.h1
-rw-r--r--src/server.cpp2
6 files changed, 43 insertions, 3 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 4e328ac76..774b1e992 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -4002,6 +4002,13 @@ Definition tables
^ Node destructor; called after removing node
^ Not called for bulk node placement (i.e. schematics and VoxelManip)
^ default: nil ]]
+ on_flood = func(pos, oldnode, newnode), --[[
+ ^ Called when a liquid (newnode) is about to flood oldnode, if
+ ^ it has `floodable = true` in the nodedef. Not called for bulk
+ ^ node placement (i.e. schematics and VoxelManip) or air nodes. If
+ ^ return true the node is not flooded, but on_flood callback will
+ ^ most likely be called over and over again every liquid update
+ ^ interval. Default: nil ]]
after_place_node = func(pos, placer, itemstack, pointed_thing) --[[
^ Called after constructing node when node was placed using
diff --git a/src/map.cpp b/src/map.cpp
index 8754813dd..75dcee350 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -44,6 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "database.h"
#include "database-dummy.h"
#include "database-sqlite3.h"
+#include "script/serverscripting.h"
#include <deque>
#include <queue>
#if USE_LEVELDB
@@ -637,7 +638,8 @@ s32 Map::transforming_liquid_size() {
return m_transforming_liquid.size();
}
-void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks)
+void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
+ ServerEnvironment *env)
{
DSTACK(FUNCTION_NAME);
//TimeTaker timer("transformLiquids()");
@@ -897,8 +899,16 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks)
// set the liquid level and flow bit to 0
n0.param2 = ~(LIQUID_LEVEL_MASK | LIQUID_FLOW_DOWN_MASK);
}
+
+ // change the node.
n0.setContent(new_node_content);
+ // on_flood() the node
+ if (floodable_node != CONTENT_AIR) {
+ if (env->getScriptIface()->node_on_flood(p0, n00, n0))
+ continue;
+ }
+
// Ignore light (because calling voxalgo::update_lighting_nodes)
n0.setLight(LIGHTBANK_DAY, 0, m_nodedef);
n0.setLight(LIGHTBANK_NIGHT, 0, m_nodedef);
diff --git a/src/map.h b/src/map.h
index 739cdb59b..4d7079823 100644
--- a/src/map.h
+++ b/src/map.h
@@ -266,7 +266,8 @@ public:
// For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
virtual void PrintInfo(std::ostream &out);
- void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks);
+ void transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks,
+ ServerEnvironment *env);
/*
Node metadata
diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp
index adad01e45..2723f84e1 100644
--- a/src/script/cpp_api/s_node.cpp
+++ b/src/script/cpp_api/s_node.cpp
@@ -178,6 +178,27 @@ void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
lua_pop(L, 1); // Pop error handler
}
+bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ int error_handler = PUSH_ERROR_HANDLER(L);
+
+ INodeDefManager *ndef = getServer()->ndef();
+
+ // Push callback function on stack
+ if (!getItemCallback(ndef->get(node).name.c_str(), "on_flood"))
+ return false;
+
+ // Call function
+ push_v3s16(L, p);
+ pushnode(L, node, ndef);
+ pushnode(L, newnode, ndef);
+ PCALL_RES(lua_pcall(L, 3, 1, error_handler));
+ lua_remove(L, error_handler);
+ return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
+}
+
void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
{
SCRIPTAPI_PRECHECKHEADER
diff --git a/src/script/cpp_api/s_node.h b/src/script/cpp_api/s_node.h
index fe1180cb3..eb127909d 100644
--- a/src/script/cpp_api/s_node.h
+++ b/src/script/cpp_api/s_node.h
@@ -42,6 +42,7 @@ public:
ServerActiveObject *digger);
void node_on_construct(v3s16 p, MapNode node);
void node_on_destruct(v3s16 p, MapNode node);
+ bool node_on_flood(v3s16 p, MapNode node, MapNode newnode);
void node_after_destruct(v3s16 p, MapNode node);
bool node_on_timer(v3s16 p, MapNode node, f32 dtime);
void node_on_receive_fields(v3s16 p,
diff --git a/src/server.cpp b/src/server.cpp
index a921423d2..ac6265d09 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -599,7 +599,7 @@ void Server::AsyncRunStep(bool initial_step)
ScopeProfiler sp(g_profiler, "Server: liquid transform");
std::map<v3s16, MapBlock*> modified_blocks;
- m_env->getMap().transformLiquids(modified_blocks);
+ m_env->getMap().transformLiquids(modified_blocks, m_env);
#if 0
/*
Update lighting