d0e6dcc410
This freezes many things that normally happen automatically in the world, including most ABMs and AISMs, and a few other custom step logic items like the player "hot potato" logic. This can be used for "creative mode" purposes to setup a complex build without it running itself away from you, and for texture pack authors, to have time to see things that are normally transient or difficult to observe because of the effects they have on nearby things or players.
131 lines
3.3 KiB
Lua
131 lines
3.3 KiB
Lua
-- LUALOCALS < ---------------------------------------------------------
|
|
local ItemStack, math, minetest, nodecore, pairs, string
|
|
= ItemStack, math, minetest, nodecore, pairs, string
|
|
local math_random, string_format
|
|
= math.random, string.format
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
-- Active ItemStack Modifiers
|
|
|
|
-- Definition:
|
|
--- itemnames: {"mod:itemname", "group:name"}
|
|
--- interval: integer,
|
|
--- chance: integer,
|
|
--- func: function(stack, data) end
|
|
-- Data:
|
|
--- {pos, node}
|
|
--- {player, inv, list, slot}
|
|
|
|
nodecore.register_aism,
|
|
nodecore.registered_aisms
|
|
= nodecore.mkreg()
|
|
|
|
local aismidx = {}
|
|
local function defadd(key, def)
|
|
aismidx[key] = aismidx[key] or {}
|
|
aismidx[key][def] = true
|
|
end
|
|
minetest.after(0, function()
|
|
for _, def in pairs(nodecore.registered_aisms) do
|
|
for _, name in pairs(def.itemnames) do
|
|
if name:sub(1, 6) == "group:" then
|
|
for k, v in pairs(minetest.registered_items) do
|
|
if v and v.groups and v.groups[name:sub(7)] then
|
|
defadd(k, def)
|
|
end
|
|
end
|
|
else
|
|
defadd(name, def)
|
|
end
|
|
end
|
|
end
|
|
local keys = 0
|
|
local defs = 0
|
|
local peak = 0
|
|
for _, v in pairs(aismidx) do
|
|
keys = keys + 1
|
|
local n = 0
|
|
for _ in pairs(v) do n = n + 1 end
|
|
defs = defs + n
|
|
if n > peak then peak = n end
|
|
end
|
|
minetest.log(string_format("register_aism: %d keys, %d defs, %d peak", keys, defs, peak))
|
|
end)
|
|
|
|
local function checkrun(def, stack, data)
|
|
if nodecore.stasis and not def.ignore_stasis then return end
|
|
if def.chance and def.chance > 1 and math_random(1, def.chance) ~= 1 then return end
|
|
if def.interval and def.interval > 1 and (minetest.get_gametime() % def.interval) ~= 0 then return end
|
|
stack = def.action(stack, data)
|
|
if stack and data.set then data.set(ItemStack(stack)) end
|
|
end
|
|
|
|
local function checkstack(stack, data)
|
|
if (not stack) or stack:is_empty() then return end
|
|
local name = stack:get_name()
|
|
local defs = aismidx[name]
|
|
if not defs then return end
|
|
for def in pairs(defs) do
|
|
checkrun(def, stack, data)
|
|
end
|
|
end
|
|
nodecore.aism_check_stack = checkstack
|
|
|
|
nodecore.register_limited_abm({
|
|
label = "AISM Scheduler",
|
|
nodenames = {"group:visinv"},
|
|
interval = 1,
|
|
chance = 1,
|
|
ignore_stasis = true,
|
|
action = function(pos, node)
|
|
return checkstack(nodecore.stack_get(pos), {
|
|
pos = pos,
|
|
node = node,
|
|
set = function(s)
|
|
return nodecore.stack_set(pos, s)
|
|
end
|
|
})
|
|
end
|
|
})
|
|
|
|
local function invtick()
|
|
minetest.after(1, invtick)
|
|
for _, player in pairs(minetest.get_connected_players()) do
|
|
local pos = player:get_pos()
|
|
pos.y = pos.y + player:get_properties().eye_height
|
|
local inv = player:get_inventory()
|
|
for lname, list in pairs(inv:get_lists()) do
|
|
for slot, stack in pairs(list) do
|
|
checkstack(stack, {
|
|
pos = pos,
|
|
player = player,
|
|
inv = inv,
|
|
list = lname,
|
|
slot = slot,
|
|
set = function(s)
|
|
return inv:set_stack(lname, slot, s)
|
|
end
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
invtick()
|
|
|
|
nodecore.register_item_entity_step(function(self, dtime)
|
|
local t = (self.aismtimer or 0) + dtime
|
|
while t >= 1 do
|
|
t = t - 1
|
|
checkstack(ItemStack(self.itemstring), {
|
|
pos = self.object:get_pos(),
|
|
obj = self.object,
|
|
ent = self,
|
|
set = function(s)
|
|
if s:is_empty() then return self.object:remove() end
|
|
self.itemstring = s:to_string()
|
|
end
|
|
})
|
|
end
|
|
self.aismtimer = t
|
|
end)
|