-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add on_flood() callback. #5619
Add on_flood() callback. #5619
Conversation
Parts of this PR came from #4130 |
Will lava still be able to be cooled by water that is below it with this? |
lava flowing on top of water floods the water node below the lava. The water doesn't magically jump up one node. |
Oh, I see, I was only thinking of water doing the flooding. |
src/map.cpp
Outdated
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ServerEnv should be passed as pointer like everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one change, else perfect shipit
A |
@DS-Minetest That wouldn't make sense since there isn't any pointing involved, but I guess the callback could receive a flooder position argument too. |
doc/lua_api.txt
Outdated
@@ -3974,6 +3974,12 @@ 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should make clear it is called only for non-air nodes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps mention 'floodable = true' here, "called for non-air nodes with 'floodable = true'".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
Good to see this being done at last. |
No need for flooder pos, this should be as simple as possible. |
@paramat it causes repeated callbacks, but only 1/s and this is really not that much, except if you really have lots of nodes preventing flooding that way. If we had some nodetimer-based system or something like that based on node updates, it would avoid those repeated callbacks as well as allowing to make the water flow faster as was requested in another issue, for instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise, looks good!
src/map.cpp
Outdated
|
||
// on_flood() the node | ||
if (floodable_node != CONTENT_AIR) { | ||
if (env.getScriptIface()->node_on_flood(p0, n0, new_node_content)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The callback is called after n0.param2
is modified. That means that the param2 of n0 will already be the new param2, which can cause problems with coloured nodes, for instance (like the node dropping with a different colour than it should).
I agree, but it seems to cause a never-ending series of calls, which is a bad idea even if only 1 per second. So i'm wondering if this should not be encouraged / allowed. However there may be a good reason to allow this. |
One reason to allow cancellation is that it could permit a security mod to effectively and retroactively This mopping up requires us to stop the flooding. If we don't stop flooding the node, then the callback here will require hacks like With the return value honored, we can allow protection mods to delete vertical columns of lava or water relatively safely and not cause performance spikes. You could also use this feature to safely change the liquid into a "non-flooding" liquid that just stops right there as well. So even though it won't be used much, or shouldn't be used much, it serves a useful purpose. |
I'm gonna try and see if I can replace n0 with e.g. n00 in the call and get the proper param2 in place here, but it'll have to wait until tonight when I can test (->WIP) |
@sofar For that particular case you could make the on_flood callback be called after the flooding, and then it would be a good time to put the security node back in, so no need for minetest.after. It might cause problems if a node has metadata that should be preserved, though. |
Ok i'm neutral on the return true behaviour. |
@raymoo right, that's why I don't want to wait until the metadata is destroyed. |
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.
Pushed what I feel should be the final update. @Ekdohibs what seems to happen is that the param2 of every node that gets newly flooded is by definition So, per definition the param2 of Because of the ambiguity of the liquid direction, I think it's false to try and include a liquid direction. If one needs to see if the node above equals the liquid in |
@sofar |
@Ekdohibs I think that case only happens if the liquid will be flowing down through the node entirely, like a waterfall. I have not been able to confirm that, and in all my testing of flooding e.g. flowers and other stuff, I was only ever getting |
@sofar well, as long as the param2 given is the one that is used to flood, I think it is ok, regardless of what it is. |
@Ekdohibs right, that's why I'm convinced that this patch is correct as-is. |
@Ekdohibs seems to be +1? |
Docs are ok for me now. |
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 thenode should be cancelled (
return true
will prevent the nodefrom flooding).
Documentation is added, the callback function was tested with a
modified minetest_game.
Note that
return true
will likely cause the node'son_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.