2 minetest,vector,table,pairs,type,math
4 minetest,vector,table,pairs,type,math
6 -- Falling entity ("rewrite"")
9 local param_translation = {
18 minetest.register_entity(":__builtin:falling_node", {
19 initial_properties = {
21 visual_size = {x = 0.667, y = 0.667},
25 collide_with_objects = false,
26 collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
32 set_node = function(self, node, meta)
35 if type(meta.to_table) == "function" then
36 meta = meta:to_table()
38 for _, list in pairs(meta.inventory or {}) do
39 for i, stack in pairs(list) do
40 if type(stack) == "userdata" then
41 list[i] = stack:to_string()
48 self.object:set_properties({
50 textures = {node.name},
54 self.object:set_rotation(vector.new(0,param_translation[node.param2],0))
58 get_staticdata = function(self)
63 return minetest.serialize(ds)
66 on_activate = function(self, staticdata)
67 self.object:set_armor_groups({immortal = 1})
69 local ds = minetest.deserialize(staticdata)
70 if ds and ds.node then
71 self:set_node(ds.node, ds.meta)
74 elseif staticdata ~= "" then
75 self:set_node({name = staticdata})
79 on_step = function(self, dtime)
81 local acceleration = self.object:get_acceleration()
82 if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
83 self.object:set_acceleration({x = 0, y = -10, z = 0})
85 -- Turn to actual node when colliding with ground, or continue to move
86 local pos = self.object:get_pos()
87 -- Position of bottom center point
88 local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
89 -- 'bcn' is nil for unloaded nodes
90 local bcn = minetest.get_node_or_nil(bcp)
91 -- Delete on contact with ignore at world edges
92 if bcn and bcn.name == "ignore" then
96 local bcd = bcn and minetest.registered_nodes[bcn.name]
98 (not bcd or bcd.walkable or
99 (minetest.get_item_group(self.node.name, "float") ~= 0 and
100 bcd.liquidtype ~= "none")) then
101 if bcd and bcd.leveled and
102 bcn.name == self.node.name then
103 local addlevel = self.node.level
104 if not addlevel or addlevel <= 0 then
105 addlevel = bcd.leveled
107 if minetest.add_node_level(bcp, addlevel) == 0 then
111 elseif bcd and bcd.buildable_to and
112 (minetest.get_item_group(self.node.name, "float") == 0 or
113 bcd.liquidtype == "none") then
114 minetest.remove_node(bcp)
117 local np = {x = bcp.x, y = bcp.y + 1, z = bcp.z}
119 local n2 = minetest.get_node(np)
120 local nd = minetest.registered_nodes[n2.name]
121 -- If it's not air or liquid, remove node and replace it with
123 if n2.name ~= "air" and (not nd or nd.liquidtype == "none") then
124 local drops = minetest.get_node_drops(self.node.name, "")
125 if drops and table.getn(drops) > 0 then
126 for _,droppy in pairs(drops) do
127 minetest.throw_item(np,droppy)
130 minetest.throw_item(np,self.node)
135 -- Create node and remove entity
136 local def = minetest.registered_nodes[self.node.name]
138 minetest.add_node(np, self.node)
140 local meta = minetest.get_meta(np)
141 meta:from_table(self.meta)
143 if def.sounds and def.sounds.fall then
144 minetest.sound_play(def.sounds.fall, {pos = np}, true)
148 minetest.check_for_falling(np)
152 local vel = self.object:get_velocity()
153 if vector.equals(vel, {x = 0, y = 0, z = 0}) then
154 local npos = self.object:get_pos()
155 self.object:set_pos(vector.round(npos))