2 minetest,vector,table,pairs,type
4 minetest,vector,table,pairs,type
6 -- Falling entity ("rewrite"")
9 minetest.register_entity(":__builtin:falling_node", {
10 initial_properties = {
12 visual_size = {x = 0.667, y = 0.667},
16 collide_with_objects = false,
17 collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
23 set_node = function(self, node, meta)
26 if type(meta.to_table) == "function" then
27 meta = meta:to_table()
29 for _, list in pairs(meta.inventory or {}) do
30 for i, stack in pairs(list) do
31 if type(stack) == "userdata" then
32 list[i] = stack:to_string()
37 self.object:set_properties({
39 textures = {node.name},
43 get_staticdata = function(self)
48 return minetest.serialize(ds)
51 on_activate = function(self, staticdata)
52 self.object:set_armor_groups({immortal = 1})
54 local ds = minetest.deserialize(staticdata)
55 if ds and ds.node then
56 self:set_node(ds.node, ds.meta)
59 elseif staticdata ~= "" then
60 self:set_node({name = staticdata})
64 on_step = function(self, dtime)
66 local acceleration = self.object:get_acceleration()
67 if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
68 self.object:set_acceleration({x = 0, y = -10, z = 0})
70 -- Turn to actual node when colliding with ground, or continue to move
71 local pos = self.object:get_pos()
72 -- Position of bottom center point
73 local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
74 -- 'bcn' is nil for unloaded nodes
75 local bcn = minetest.get_node_or_nil(bcp)
76 -- Delete on contact with ignore at world edges
77 if bcn and bcn.name == "ignore" then
81 local bcd = bcn and minetest.registered_nodes[bcn.name]
83 (not bcd or bcd.walkable or
84 (minetest.get_item_group(self.node.name, "float") ~= 0 and
85 bcd.liquidtype ~= "none")) then
86 if bcd and bcd.leveled and
87 bcn.name == self.node.name then
88 local addlevel = self.node.level
89 if not addlevel or addlevel <= 0 then
90 addlevel = bcd.leveled
92 if minetest.add_node_level(bcp, addlevel) == 0 then
96 elseif bcd and bcd.buildable_to and
97 (minetest.get_item_group(self.node.name, "float") == 0 or
98 bcd.liquidtype == "none") then
99 minetest.remove_node(bcp)
102 local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
104 local n2 = minetest.get_node(np)
105 local nd = minetest.registered_nodes[n2.name]
106 -- If it's not air or liquid, remove node and replace it with
108 if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
109 local drops = minetest.get_node_drops(self.node.name, "")
110 if drops and table.getn(drops) > 0 then
111 for _,droppy in pairs(drops) do
112 minetest.throw_item(np,droppy)
115 minetest.throw_item(np,self.node)
120 -- Create node and remove entity
121 local def = minetest.registered_nodes[self.node.name]
123 minetest.add_node(np, self.node)
125 local meta = minetest.get_meta(np)
126 meta:from_table(self.meta)
128 if def.sounds and def.sounds.fall then
129 minetest.sound_play(def.sounds.fall, {pos = np}, true)
133 minetest.check_for_falling(np)
137 local vel = self.object:get_velocity()
138 if vector.equals(vel, {x = 0, y = 0, z = 0}) then
139 local npos = self.object:get_pos()
140 self.object:set_pos(vector.round(npos))