-
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 API function minetest.activate_objects_in_area #11630
Conversation
Does this allow to remove said objects then, as in, they could be listed with get_objects_in_radius and then removed one-by-one?
An object equivalent to accompany the clearing of nodes between two positions would be very nice indeed for loading and unloading various schematic levels in the same worldspace without 'leftover' entities. |
@loffren174 I haven't tested the specific case of removing the objects, but it definitely should work. (I have tested manipulating the activated objects. For example, you can move them to an active mapblock to prevent them from being deactivated again.) |
It is only necessary with PUC Lua, and in this case the handling is better added separately such as in minetest#11664.
This avoids some unnecessary copying.
I don't fully understand all this reference stuff TBH.
Thanks for the contribution! Unfortunately, this feature is not on the roadmap and hasn't received a concept approval. Under the new rules, non-roadmap non-bugfix PRs have 7 days to be concept approved, otherwise they should be closed. If a core dev wants to support this PR, they may reopen it and apply the "Supported by core dev" label. In the future, you can open an issue first to get preapproval before working on something |
Could this be considered for reopening/inclusion in 5.6.0? |
This PR was brought up in today's meeting.
|
My specific use case is my mod area_containers. These containers are nodes which contain physical areas, in which one can put nodes and objects. I don't want people to be able to destroy containers which still have nodes or objects inside. Detecting nodes is easy, but detecting objects in a foolproof way is as yet impossible. My current mostly-working solution is to periodically store the count of objects inside whenever the mapblock representing the inside chamber is active. I could solve this cleanly using the function this PR adds. Since the The problem with #11609 was the potential reentrancy inherent to a synchronous API. There are many times during the activation of a mapblock when Lua callbacks can be called (e.g. ABMs, node timers.) Theoretically any of these callbacks could call the area loading function, with unpredictable results. The activation process was not written to be reentrant AFAICT. A safe solution is to use a "lock" to prevent reentrancy, as is done in this PR. However, if the function activated entire mapblocks, it would then be impossible to use it within node timer callbacks, object activation callbacks, ABMs, or LBMs. A function which only activates objects is only uncallable during object activation (and deactivation.) My main goal in the first place was the activation of objects; I don't see much point of doing the other stuff when you can already access nodes in inactive blocks. |
Someone brought up A function to activate a particular mapblock (not synchronous) sounds generally useful but in the end I think have to give up on solving your usecase directly. Maybe you'd be fine with some creative workarounds like only allowing your nodes to be dug after a short delay during which the relevant blocks are activated... |
Is there evidence that activating objects is especially expensive? Blocks may have to be loaded from the disk, but this is already a possibility with existing synchronous APIs such as The alternative to this PR is forceloading blocks. Besides being asynchronous, this isn't even guaranteed to work, since there is a limit on the number of blocks forceloaded. Given that objects are so important in Minetest, the impossibility of reliably detecting static objects seems like a significant issue. There should at least be a reliable asynchronous API, but I think a synchronous API would be highly preferable. |
Nothing about it is particularly expensive, I'm just wary of adding more sync apis.
Having only a synchronous API can be considered a problem too, then. |
I could rename the function to function core.activate_objects_in_area(pos1, pos2, callback)
assert(type(pos1) == "table" and type(pos2) == "table" and type(callback) == "function", "Invalid invocation of minetest.activate_objects_in_area")
pos1 = vector.copy(pos1)
pos2 = vector.copy(pos2)
core.after(0, function()
core.activate_objects_in_area_sync(pos1, pos2)
callback()
end)
end |
Add compact, short information about your PR for easier understanding:
ServerEnvironment
. The objects are activated like during regular mapblock activation, except that only those within the given area are activated.on_activate
oron_deactivate
. I had to change several places in the code to get this to work. It wouldn't be safe to let mods call the function in these places, since the activation and deactivation procedures are not written to be re-entrant.To do
This PR is Ready for Review.
How to test
/grantme all
.a.
/teleport 0 6001 0
b.
/make_platform (0,6000,0)
c.
/teleport 0 10 0
/check_platform (0,6000,0)
. It should tell you that it activated the area and detected two objects.minetest.activate_objects_in_area
throws an error in the right places, you can uncomment one or both of the latter two calls to the function in the mod'sinit.lua
. These two calls are at the bottom of the file where theon_activate
andon_deactivate
methods of__builtin:item
are overridden.I've also now added a devtest command
test_activate_objects
for activating an arbitrary area.