Aaron Suen 1b0a506633 Fix tote AISM over-modification
Carrying a tote with an infused tool inside would
cause the tote to repeatedly animate item
switching because the infused tool's soaking AISM
would keep returning a new item stack, causing
the tote to detect a "dirty" state, reserialize its
data, and thus keep changing metadata.

Detect if we're setting an item string to the same
string it already was, and don't mark it as dirty
if so, fixing this.
2021-08-09 07:26:26 -04:00

66 lines
1.7 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local ItemStack, minetest, nodecore, pairs
= ItemStack, minetest, nodecore, pairs
-- LUALOCALS > ---------------------------------------------------------
nodecore.register_aism({
label = "Packed Tote AISMs",
interval = 1,
chance = 1,
itemnames = {"group:tote"},
action = function(stack, data)
local stackmeta = stack:get_meta()
local raw = stackmeta:get_string("carrying")
local inv = raw and (raw ~= "") and minetest.deserialize(raw)
if not inv then return end
local dirty
for _, slot in pairs(inv) do
-- Modern format
local ncitem = slot and slot.m and slot.m.fields
and slot.m.fields.ncitem
if ncitem then
local istack = ItemStack(ncitem)
if not istack:is_empty() then
local sdata = {
pos = data.pos,
toteslot = slot,
set = function(s)
local ss = s:to_string()
if ss ~= ncitem then
slot.m.fields.ncitem = ss
dirty = true
end
end
}
nodecore.aism_check_stack(istack, sdata)
end
end
-- Legacy format
for lname, list in pairs(slot and slot.m and slot.m.inventory or {}) do
for sub, item in pairs(list) do
local istack = ItemStack(item)
if not istack:is_empty() then
local sdata = {
pos = data.pos,
toteslot = slot,
totelistname = lname,
totelist = list,
totesubslot = sub,
set = function(s)
list[sub] = s:to_string()
dirty = true
end
}
nodecore.aism_check_stack(istack, sdata)
end
end
end
end
if not dirty then return end
stackmeta:set_string("carrying", minetest.serialize(inv))
return stack
end
})