diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua index f9eb93184..045171a79 100644 --- a/builtin/game/item_entity.lua +++ b/builtin/game/item_entity.lua @@ -96,6 +96,56 @@ core.register_entity(":__builtin:item", { self:set_item(self.itemstring) end, + try_merge_with = function(self, own_stack, object, obj) + local stack = ItemStack(obj.itemstring) + if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then + local overflow = false + local count = stack:get_count() + own_stack:get_count() + local max_count = stack:get_stack_max() + if count > max_count then + overflow = true + count = count - max_count + else + self.itemstring = '' + end + local pos = object:getpos() + pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15 + object:moveto(pos, false) + local s, c + local max_count = stack:get_stack_max() + local name = stack:get_name() + if not overflow then + obj.itemstring = name .. " " .. count + s = 0.2 + 0.1 * (count / max_count) + c = s + object:set_properties({ + visual_size = {x = s, y = s}, + collisionbox = {-c, -c, -c, c, c, c} + }) + self.object:remove() + -- merging succeeded + return true + else + s = 0.4 + c = 0.3 + object:set_properties({ + visual_size = {x = s, y = s}, + collisionbox = {-c, -c, -c, c, c, c} + }) + obj.itemstring = name .. " " .. max_count + s = 0.2 + 0.1 * (count / max_count) + c = s + self.object:set_properties({ + visual_size = {x = s, y = s}, + collisionbox = {-c, -c, -c, c, c, c} + }) + self.itemstring = name .. " " .. count + end + end + -- merging didn't succeed + return false + end, + on_step = function(self, dtime) self.age = self.age + dtime if time_to_live > 0 and self.age > time_to_live then @@ -111,52 +161,13 @@ core.register_entity(":__builtin:item", { if not core.registered_nodes[nn] or (core.registered_nodes[nn].walkable and core.get_item_group(nn, "slippery")==0) and v.y == 0 then if self.physical_state then local own_stack = ItemStack(self.object:get_luaentity().itemstring) - for _,object in ipairs(core.get_objects_inside_radius(p, 0.8)) do + -- Merge with close entities of the same item + for _, object in ipairs(core.get_objects_inside_radius(p, 0.8)) do local obj = object:get_luaentity() - if obj and obj.name == "__builtin:item" and obj.physical_state == false then - local stack = ItemStack(obj.itemstring) - if own_stack:get_name() == stack:get_name() and stack:get_free_space() > 0 then - local overflow = false - local count = stack:get_count() + own_stack:get_count() - local max_count = stack:get_stack_max() - if count>max_count then - overflow = true - count = count - max_count - else - self.itemstring = '' - end - local pos=object:getpos() - pos.y = pos.y + (count - stack:get_count()) / max_count * 0.15 - object:moveto(pos, false) - local s, c - local max_count = stack:get_stack_max() - local name = stack:get_name() - if not overflow then - obj.itemstring = name.." "..count - s = 0.2 + 0.1 * (count / max_count) - c = s - object:set_properties({ - visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c} - }) - self.object:remove() - return - else - s = 0.4 - c = 0.3 - object:set_properties({ - visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c} - }) - obj.itemstring = name.." "..max_count - s = 0.2 + 0.1 * (count / max_count) - c = s - self.object:set_properties({ - visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c} - }) - self.itemstring = name.." "..count - end + if obj and obj.name == "__builtin:item" + and obj.physical_state == false then + if self:try_merge_with(own_stack, object, obj) then + return end end end