Skip to content

Commit 18fe277

Browse files
committedMay 23, 2014
Item entity stacks merge on the ground.
Add TTL to item entities.
1 parent 94dba66 commit 18fe277

File tree

2 files changed

+103
-34
lines changed

2 files changed

+103
-34
lines changed
 

‎builtin/game/item_entity.lua

+100-34
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,43 @@ function core.spawn_item(pos, item)
88
return obj
99
end
1010

11+
-- If item_entity_ttl is not set, enity will have default life time
12+
-- Setting it to -1 disables the feature
13+
14+
local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
15+
if not time_to_live then
16+
time_to_live = 900
17+
end
18+
1119
core.register_entity(":__builtin:item", {
1220
initial_properties = {
1321
hp_max = 1,
1422
physical = true,
1523
collide_with_objects = false,
16-
collisionbox = {-0.17,-0.17,-0.17, 0.17,0.17,0.17},
17-
visual = "sprite",
18-
visual_size = {x=0.5, y=0.5},
24+
collisionbox = {-0.24, -0.24, -0.24, 0.24, 0.24, 0.24},
25+
visual = "wielditem",
26+
visual_size = {x = 0.3, y = 0.3},
1927
textures = {""},
20-
spritediv = {x=1, y=1},
21-
initial_sprite_basepos = {x=0, y=0},
28+
spritediv = {x = 1, y = 1},
29+
initial_sprite_basepos = {x = 0, y = 0},
2230
is_visible = false,
2331
},
24-
32+
2533
itemstring = '',
2634
physical_state = true,
35+
age = 0,
2736

2837
set_item = function(self, itemstring)
2938
self.itemstring = itemstring
3039
local stack = ItemStack(itemstring)
40+
local count = stack:get_count()
41+
local max_count = stack:get_stack_max()
42+
if count > max_count then
43+
count = max_count
44+
self.itemstring = stack:get_name().." "..max_count
45+
end
46+
local s = 0.15 + 0.15 * (count / max_count)
47+
local c = 0.8 * s
3148
local itemtable = stack:to_table()
3249
local itemname = nil
3350
if itemtable then
@@ -41,69 +58,119 @@ core.register_entity(":__builtin:item", {
4158
end
4259
prop = {
4360
is_visible = true,
44-
visual = "sprite",
45-
textures = {"unknown_item.png"}
61+
visual = "wielditem",
62+
textures = {itemname},
63+
visual_size = {x = s, y = s},
64+
collisionbox = {-c, -c, -c, c, c, c},
65+
automatic_rotate = math.pi * 0.2,
4666
}
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
5767
self.object:set_properties(prop)
5868
end,
5969

6070
get_staticdata = function(self)
61-
--return self.itemstring
6271
return core.serialize({
6372
itemstring = self.itemstring,
6473
always_collect = self.always_collect,
74+
age = self.age
6575
})
6676
end,
6777

68-
on_activate = function(self, staticdata)
78+
on_activate = function(self, staticdata, dtime_s)
6979
if string.sub(staticdata, 1, string.len("return")) == "return" then
7080
local data = core.deserialize(staticdata)
7181
if data and type(data) == "table" then
7282
self.itemstring = data.itemstring
7383
self.always_collect = data.always_collect
84+
if data.age then
85+
self.age = data.age + dtime_s
86+
else
87+
self.age = dtime_s
88+
end
7489
end
7590
else
7691
self.itemstring = staticdata
7792
end
78-
self.object:set_armor_groups({immortal=1})
79-
self.object:setvelocity({x=0, y=2, z=0})
80-
self.object:setacceleration({x=0, y=-10, z=0})
93+
self.object:set_armor_groups({immortal = 1})
94+
self.object:setvelocity({x = 0, y = 2, z = 0})
95+
self.object:setacceleration({x = 0, y = -10, z = 0})
8196
self:set_item(self.itemstring)
8297
end,
8398

8499
on_step = function(self, dtime)
100+
self.age = self.age + dtime
101+
if time_to_live > 0 and self.age > time_to_live then
102+
self.itemstring = ''
103+
self.object:remove()
104+
return
105+
end
85106
local p = self.object:getpos()
86107
p.y = p.y - 0.3
87108
local nn = core.get_node(p).name
88109
-- If node is not registered or node is walkably solid and resting on nodebox
89110
local v = self.object:getvelocity()
90111
if not core.registered_nodes[nn] or core.registered_nodes[nn].walkable and v.y == 0 then
91112
if self.physical_state then
92-
self.object:setvelocity({x=0,y=0,z=0})
93-
self.object:setacceleration({x=0, y=0, z=0})
113+
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
114+
for _,object in ipairs(core.get_objects_inside_radius(p, 0.8)) do
115+
local obj = object:get_luaentity()
116+
if obj and obj.name == "__builtin:item" and obj.physical_state == false then
117+
local stack = ItemStack(obj.itemstring)
118+
if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then
119+
local overflow = false
120+
local count = stack:get_count() + own_stack:get_count()
121+
local max_count = stack:get_stack_max()
122+
if count>max_count then
123+
overflow = true
124+
count = count - max_count
125+
else
126+
self.itemstring = ''
127+
end
128+
local pos=object:getpos()
129+
pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15
130+
object:moveto(pos, false)
131+
local s, c
132+
local max_count = stack:get_stack_max()
133+
local name = stack:get_name()
134+
if not overflow then
135+
obj.itemstring = name.." "..count
136+
s = 0.15 + 0.15 * (count / max_count)
137+
c = 0.8 * s
138+
object:set_properties({
139+
visual_size = {x = s, y = s},
140+
collisionbox = {-c, -c, -c, c, c, c}
141+
})
142+
self.object:remove()
143+
return
144+
else
145+
s = 0.3
146+
c = 0.24
147+
object:set_properties({
148+
visual_size = {x = s, y = s},
149+
collisionbox = {-c, -c, -c, c, c, c}
150+
})
151+
obj.itemstring = name.." "..max_count
152+
s = 0.15 + 0.15 * (count / max_count)
153+
c = 0.8 * s
154+
self.object:set_properties({
155+
visual_size = {x = s, y = s},
156+
collisionbox = {-c, -c, -c, c, c, c}
157+
})
158+
self.itemstring = name.." "..count
159+
end
160+
end
161+
end
162+
end
163+
self.object:setvelocity({x = 0, y = 0, z = 0})
164+
self.object:setacceleration({x = 0, y = 0, z = 0})
94165
self.physical_state = false
95-
self.object:set_properties({
96-
physical = false
97-
})
166+
self.object:set_properties({physical = false})
98167
end
99168
else
100169
if not self.physical_state then
101-
self.object:setvelocity({x=0,y=0,z=0})
102-
self.object:setacceleration({x=0, y=-10, z=0})
170+
self.object:setvelocity({x = 0, y = 0, z = 0})
171+
self.object:setacceleration({x = 0, y = -10, z = 0})
103172
self.physical_state = true
104-
self.object:set_properties({
105-
physical = true
106-
})
173+
self.object:set_properties({physical = true})
107174
end
108175
end
109176
end,
@@ -120,4 +187,3 @@ core.register_entity(":__builtin:item", {
120187
self.object:remove()
121188
end,
122189
})
123-

‎minetest.conf.example

+3
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@
264264
#max_users = 15
265265
# Set to true to disallow old clients from connecting
266266
#strict_protocol_version_checking = false
267+
# Time in seconds for item entity to live. Default value: 900s
268+
# Setting it to -1 disables the feature
269+
#item_entity_ttl = 900
267270
# Set to true to enable creative mode (unlimited inventory)
268271
#creative_mode = false
269272
# Enable players getting damage and dying

0 commit comments

Comments
 (0)
Please sign in to comment.