Those are great ideas. I especially like the immovable
In a mod I've been working on, I've been using the following snippet to detect "simple" nodes (in my case, this is defined as cubic nodes that are not only likely to be safe to move around but also safe to set additional metadata on that is unlikely to be overwritten). Note that this code is not 100% reliable and errs on the side of caution at the risk of excluding nodes that should otherwise be safe (this is basically trying to detect "anything that's slightly not normal" i.e. everything except your basic building blocks - my use case was slightly different to yours, however). This code may also break if some internal Minetest behavior changes.
EDIT: Note that this snippet does not check for attached nodes. I did not realise this before I posted it. Attached nodes was not part of my requirements as I wasn't pushing the nodes around. Adding (node_def.groups == nil or not node_def.groups.attached_node) and
should do it but I haven't tested this.
Code: Select all
-- this is a list of checks that should reasonably distinguish most "ordinary" nodes from "special" nodes (NOTE: ideally the formspec and infotext metadata should be checked as well but this is probably ineffecient)
(node_def.walkable == nil or node_def.walkable == true) and -- node must be solid
(node_def.drawtype == nil or node_def.drawtype == "normal") and -- node must be regular shaped
(node_def.light_source == nil or node_def.light_source == 0) and -- node must not be a light source
(node_def.collision_box == nil) and -- node must not have an irregular collision box (NOTE: cannot check selection box because it is overriden by minetest)
(node_def.pointable == nil or node_def.pointable == true) and -- node must be pointable
(node_def.diggable == nil or node_def.diggable == true) and -- node must be diggable
(node_def.climbable == nil or node_def.climbable == false) and -- node must not be climbable
(node_def.on_rightclick == nil and node_def.on_receive_fields == nil) and -- node must not have any interaction callbacks (NOTE: cannot check on_punch because it is overridden by minetest)
(node_def.on_timer == nil) and -- node must not have any timers
(node_def.allow_metadata_inventory_move == nil and node_def.allow_metadata_inventory_put == nil and node_def.allow_metadata_inventory_take == nil and node_def.on_metadata_inventory_move == nil and node_def.on_metadata_inventory_put == nil and node_def.on_metadata_inventory_take == nil) -- node must not have any inventory callbacks (NOTE: ideally the node should not have any inventory but it's impossible to check this efficiently)
-- do stuff
I also had the idea to hook the mesecons mesecons.register_mvps_stopper
function as a lot of mods include mesecons compatibility however this would require my mod to load after mesecons (if mesecons is installed) and require users to install a "dummy" mesecons implementation that provides the hook but fails gracefully if another mod tries to do anything more than register an immovable node (if mesecons isn't installed, so that other mods pick up the mesecons soft dependency and know to call the mesecons.register_mvps_stopper
Perhaps a complex
group is also in order, which not only implies immovable
but also indicates "don't overwrite my metadata/I'll overwrite your metadata/I have rightclick or punch callbacks/I have a formspec or an inventory/etc.". This is what my mod needed rather than just a simple "can I push this around". Any nodes not in the complex
group are safe for other mods to trample over.
Also, but this would require an engine change, it would be useful to have node callbacks for when a node has been moved (similar to the callbacks for node placement and removal) and a Minetest API function to move a node (possibly with a flag to indicate preserving metadata? and a return value indicating whether or not the node was allowed to be moved?). As it is there's no standard between swapping the node at both locations, digging the node at the old location and placing the node at the new location, swapping but copying some of the metadata, digging and placing but copying metadata, or any combination of the above.