Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
local INTERVAL = .1
local function tables_equal(t1, t2)
if type(t1) ~= "table" or type(t2) ~= "table" then
return false
end
for k, v1 in pairs(t1) do
local v2 = t2[k]
if type(v1) == "table" then
if not tables_equal(v1, v2) then
return false
end
elseif v1 ~= v2 then
return false
end
end
for k, v2 in pairs(t2) do
local v1 = t1[k]
if type(v2) == "table" then
if not tables_equal(v2, v1) then
return false
end
elseif v2 ~= v1 then
return false
end
end
return true
end
local function stacks_equal(s1, s2)
if s1 == nil or s2 == nil then
return s1 == s2
end
return tables_equal(s1:to_table(), s2:to_table())
end
local callbacks = { }
local function register_on_stack_change(callback)
callbacks[#callbacks+1] = callback
end
local oldstacks = { }
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer < INTERVAL then return end
timer = 0
for _, p in ipairs(minetest.get_connected_players()) do
local pn = p:get_player_name()
local old = oldstacks[pn]
local news = p:get_wielded_item()
local newi = p:get_wield_index()
if not old then
old = { }
oldstacks[pn] = old
end
if newi ~= old.index or not stacks_equal(news, old.stack) then
-- Call in LIFO order.
local olds, oldi = old.stack, old.index
old.stack, old.index = news, newi
for i = #callbacks, 1, -1 do
callbacks[i](p, news, newi, olds, oldi)
end
end
end
end)
register_on_stack_change(function(player,
new_stack, new_index, old_stack, old_index)
print("change:", player:get_player_name(),
new_stack and new_stack:to_string(), new_index,
old_stack and old_stack:to_string(), old_index)
end)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment