sdzen
2013-08-07 df644d7f7736fce4e92a75d53f44b3df6671ceeb
commit | author | age
e139ff 1 -- Minetest: builtin/item_entity.lua
R 2
3 function minetest.spawn_item(pos, item)
4     -- Take item in any format
5     local stack = ItemStack(item)
6     local obj = minetest.env:add_entity(pos, "__builtin:item")
7     obj:get_luaentity():set_item(stack:to_string())
8     return obj
9 end
10
11 minetest.register_entity(":__builtin:item", {
12     initial_properties = {
13         hp_max = 1,
14         physical = true,
15         collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17},
16         visual = "sprite",
17         visual_size = {x=0.5, y=0.5},
18         textures = {""},
19         spritediv = {x=1, y=1},
20         initial_sprite_basepos = {x=0, y=0},
21         is_visible = false,
22     },
23     
24     itemstring = '',
25     physical_state = true,
26     timer = 0,
3a3700 27
e139ff 28     set_item = function(self, itemstring)
R 29         self.itemstring = itemstring
30         local stack = ItemStack(itemstring)
31         local itemtable = stack:to_table()
32         local itemname = nil
33         if itemtable then
34             itemname = stack:to_table().name
35         end
36         local item_texture = nil
37         local item_type = ""
38         if minetest.registered_items[itemname] then
39             item_texture = minetest.registered_items[itemname].inventory_image
40             item_type = minetest.registered_items[itemname].type
41         end
42         prop = {
43             is_visible = true,
44             visual = "sprite",
45             textures = {"unknown_item.png"}
46         }
47         if item_texture and item_texture ~= "" then
48             prop.visual = "sprite"
49             prop.textures = {item_texture}
50             prop.visual_size = {x=0.50, y=0.50}
51         else
52             prop.visual = "wielditem"
53             prop.textures = {itemname}
54             prop.visual_size = {x=0.20, y=0.20}
55             prop.automatic_rotate = math.pi * 0.25
56         end
57         self.object:set_properties(prop)
58     end,
59
60     get_staticdata = function(self)
61         --return self.itemstring
62         return minetest.serialize({
63             itemstring = self.itemstring,
64             always_collect = self.always_collect,
3a3700 65             timer = self.timer,
e139ff 66         })
R 67     end,
68
3a3700 69     on_activate = function(self, staticdata, dtime_s)
e139ff 70         if string.sub(staticdata, 1, string.len("return")) == "return" then
R 71             local data = minetest.deserialize(staticdata)
72             if data and type(data) == "table" then
73                 self.itemstring = data.itemstring
74                 self.always_collect = data.always_collect
3a3700 75                 self.timer = data.timer
R 76                 if not self.timer then
77                     self.timer = 0
78                 end
79                 self.timer = self.timer+dtime_s
e139ff 80             end
R 81         else
82             self.itemstring = staticdata
83         end
84         self.object:set_armor_groups({immortal=1})
85         self.object:setvelocity({x=0, y=2, z=0})
86         self.object:setacceleration({x=0, y=-10, z=0})
87         self:set_item(self.itemstring)
88     end,
3a3700 89     
e139ff 90     on_step = function(self, dtime)
17f3ce 91         local time = tonumber(minetest.setting_get("remove_items"))
3a3700 92         if not time then
R 93             time = 300
94         end
95         if not self.timer then
96             self.timer = 0
97         end
e139ff 98         self.timer = self.timer + dtime
3a3700 99         if time ~= 0 and (self.timer > time) then
e139ff 100             self.object:remove()
R 101         end
3a3700 102         
e139ff 103         local p = self.object:getpos()
3a3700 104         
R 105         local name = minetest.env:get_node(p).name
106         if name == "default:lava_flowing" or name == "default:lava_source" then
107             minetest.sound_play("builtin_item_lava", {pos=self.object:getpos(),gain = 1.0, max_hear_distance = 10})
108             self.object:remove()
109             return
110         end
111         
112         if minetest.registered_nodes[name] and minetest.registered_nodes[name].liquidtype == "flowing" then
113             get_flowing_dir = function(self)
114                 local pos = self.object:getpos()
115                 local param2 = minetest.env:get_node(pos).param2
116                 for i,d in ipairs({-1, 1, -1, 1}) do
117                     if i<3 then
118                         pos.x = pos.x+d
119                     else
120                         pos.z = pos.z+d
121                     end
122                     
123                     local name = minetest.env:get_node(pos).name
124                     local par2 = minetest.env:get_node(pos).param2
125                     if name == "default:water_flowing" and par2 < param2 then
126                         return pos
127                     end
128                     
129                     if i<3 then
130                         pos.x = pos.x-d
131                     else
132                         pos.z = pos.z-d
133                     end
134                 end
135             end
136             
137             local vec = get_flowing_dir(self)
138             if vec then
139                 local v = self.object:getvelocity()
140                 if vec and vec.x-p.x > 0 then
141                     self.object:setvelocity({x=0.5,y=v.y,z=0})
142                 elseif vec and vec.x-p.x < 0 then
143                     self.object:setvelocity({x=-0.5,y=v.y,z=0})
144                 elseif vec and vec.z-p.z > 0 then
145                     self.object:setvelocity({x=0,y=v.y,z=0.5})
146                 elseif vec and vec.z-p.z < 0 then
147                     self.object:setvelocity({x=0,y=v.y,z=-0.5})
148                 end
149                 self.object:setacceleration({x=0, y=-10, z=0})
150                 self.physical_state = true
151                 self.object:set_properties({
152                     physical = true
153                 })
154                 return
155             end
156         end
157         
e139ff 158         p.y = p.y - 0.3
R 159         local nn = minetest.env:get_node(p).name
3a3700 160         -- If node is not registered or node is walkably solid
R 161         if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable then
e139ff 162             if self.physical_state then
R 163                 self.object:setvelocity({x=0,y=0,z=0})
164                 self.object:setacceleration({x=0, y=0, z=0})
165                 self.physical_state = false
166                 self.object:set_properties({
167                     physical = false
168                 })
169             end
170         else
171             if not self.physical_state then
172                 self.object:setvelocity({x=0,y=0,z=0})
173                 self.object:setacceleration({x=0, y=-10, z=0})
174                 self.physical_state = true
175                 self.object:set_properties({
176                     physical = true
177                 })
178             end
179         end
180     end,
181
182     on_punch = function(self, hitter)
183         if self.itemstring ~= '' then
3a3700 184             hitter:get_inventory():add_item("main", self.itemstring)
e139ff 185         end
R 186         self.object:remove()
187     end,
188 })
3a3700 189
R 190 if minetest.setting_get("log_mods") then
191     minetest.log("action", "builtin_item loaded")
192 end