2 -- Falling entity ("rewrite"")
5 minetest.register_entity(":__builtin:falling_node", {
8 visual_size = {x = 0.667, y = 0.667},
12 collide_with_objects = false,
13 collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
19 set_node = function(self, node, meta)
22 if type(meta.to_table) == "function" then
23 meta = meta:to_table()
25 for _, list in pairs(meta.inventory or {}) do
26 for i, stack in pairs(list) do
27 if type(stack) == "userdata" then
28 list[i] = stack:to_string()
33 self.object:set_properties({
35 textures = {node.name},
39 get_staticdata = function(self)
44 return minetest.serialize(ds)
47 on_activate = function(self, staticdata)
48 self.object:set_armor_groups({immortal = 1})
50 local ds = minetest.deserialize(staticdata)
51 if ds and ds.node then
52 self:set_node(ds.node, ds.meta)
55 elseif staticdata ~= "" then
56 self:set_node({name = staticdata})
60 on_step = function(self, dtime)
62 local acceleration = self.object:get_acceleration()
63 if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
64 self.object:set_acceleration({x = 0, y = -10, z = 0})
66 -- Turn to actual node when colliding with ground, or continue to move
67 local pos = self.object:get_pos()
68 -- Position of bottom center point
69 local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
70 -- 'bcn' is nil for unloaded nodes
71 local bcn = minetest.get_node_or_nil(bcp)
72 -- Delete on contact with ignore at world edges
73 if bcn and bcn.name == "ignore" then
77 local bcd = bcn and minetest.registered_nodes[bcn.name]
79 (not bcd or bcd.walkable or
80 (minetest.get_item_group(self.node.name, "float") ~= 0 and
81 bcd.liquidtype ~= "none")) then
82 if bcd and bcd.leveled and
83 bcn.name == self.node.name then
84 local addlevel = self.node.level
85 if not addlevel or addlevel <= 0 then
86 addlevel = bcd.leveled
88 if minetest.add_node_level(bcp, addlevel) == 0 then
92 elseif bcd and bcd.buildable_to and
93 (minetest.get_item_group(self.node.name, "float") == 0 or
94 bcd.liquidtype == "none") then
95 minetest.remove_node(bcp)
98 local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
100 local n2 = minetest.get_node(np)
101 local nd = minetest.registered_nodes[n2.name]
102 -- If it's not air or liquid, remove node and replace it with
104 if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
105 minetest.remove_node(np)
106 if nd and nd.buildable_to == false then
108 local drops = minetest.get_node_drops(n2, "")
109 for _, dropped_item in pairs(drops) do
110 minetest.add_item(np, dropped_item)
114 for _, callback in pairs(minetest.registered_on_dignodes) do
118 -- Create node and remove entity
119 local def = minetest.registered_nodes[self.node.name]
121 minetest.add_node(np, self.node)
123 local meta = minetest.get_meta(np)
124 meta:from_table(self.meta)
126 if def.sounds and def.sounds.fall then
127 minetest.sound_play(def.sounds.fall, {pos = np}, true)
131 minetest.check_for_falling(np)
134 local vel = self.object:get_velocity()
135 if vector.equals(vel, {x = 0, y = 0, z = 0}) then
136 local npos = self.object:get_pos()
137 self.object:set_pos(vector.round(npos))