775718256d
- Crash due to pos being non-nil but velocity being nil?! - Excessive item merging, i.e. on splitting planks, cancelling out outward item ejection. Items now only merge at low absolute speed (detecting groups with low relative speed is too difficult to do efficiently for now).
100 lines
2.6 KiB
Lua
100 lines
2.6 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local ItemStack, minetest, nodecore, pairs, vector
|
|
= ItemStack, minetest, nodecore, pairs, vector
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
local function addtodict(dict, key, item)
|
|
local entry = dict[key]
|
|
if not entry then
|
|
entry = {}
|
|
dict[key] = entry
|
|
end
|
|
entry[#entry + 1] = item
|
|
end
|
|
|
|
local function removesingles(dict)
|
|
local t = {}
|
|
for k, v in pairs(dict) do
|
|
if #v > 1 then t[k] = v end
|
|
end
|
|
return t
|
|
end
|
|
|
|
minetest.register_globalstep(function()
|
|
local gethash = minetest.hash_node_position
|
|
local round = vector.round
|
|
|
|
local entpos = {}
|
|
local entvel = {}
|
|
|
|
local dict = {}
|
|
for _, ent in pairs(minetest.luaentities) do
|
|
if ent.name == "__builtin:item" then
|
|
local pos = ent.object:get_pos()
|
|
local vel = ent.object:get_velocity()
|
|
if pos and vel and vector.dot(vel, vel) < 4 then
|
|
entpos[ent] = pos
|
|
entvel[ent] = vel
|
|
addtodict(dict, gethash(round(pos)), ent)
|
|
end
|
|
end
|
|
end
|
|
dict = removesingles(dict)
|
|
|
|
for _, ents in pairs(dict) do
|
|
local groups = {}
|
|
for _, ent in pairs(ents) do
|
|
addtodict(groups, nodecore.stack_family(ent.itemstring), ent)
|
|
end
|
|
groups = removesingles(groups)
|
|
for _, grp in pairs(groups) do
|
|
local newpos = {x = 0, y = 0, z = 0}
|
|
local newvel = {x = 0, y = 0, z = 0}
|
|
local samples = 0
|
|
local max = ItemStack(grp[1].itemstring):get_stack_max()
|
|
local stacks = {}
|
|
local partial
|
|
local pqty = 0
|
|
for _, ent in pairs(grp) do
|
|
local stack = ItemStack(ent.itemstring)
|
|
local iqty = stack:get_count()
|
|
newpos = vector.add(newpos, vector.multiply(
|
|
entpos[ent], iqty))
|
|
newvel = vector.add(newvel, vector.multiply(
|
|
entvel[ent], iqty))
|
|
samples = samples + iqty
|
|
if not partial then
|
|
pqty = stack:get_count()
|
|
stack:set_count(max)
|
|
partial = stack:to_string()
|
|
else
|
|
pqty = pqty + iqty
|
|
while pqty >= max do
|
|
stacks[#stacks + 1] = partial
|
|
pqty = pqty - max
|
|
end
|
|
end
|
|
end
|
|
if pqty > 0 then
|
|
partial = ItemStack(partial)
|
|
partial:set_count(pqty)
|
|
stacks[#stacks + 1] = partial:to_string()
|
|
end
|
|
newpos = vector.multiply(newpos, 1 / samples)
|
|
newvel = vector.multiply(newvel, 1 / samples)
|
|
for i = 1, #grp do
|
|
local stack = stacks[i]
|
|
local ent = grp[i]
|
|
if stack then
|
|
ent.itemstring = stack
|
|
ent.object:set_pos(newpos)
|
|
ent.object:set_velocity(newvel)
|
|
else
|
|
ent.itemstring = ""
|
|
ent.object:remove()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|