Aaron Suen fdd881ae53 Active ItemStack Modifier overhaul.
AISM's now tick against stacks, including in piles, shelves,
and player inventories, (hopefully) efficiently compared to
the old way with separate ABMs.  Item entity support is also
possible, but not necessary yet.

This started out as a bugfix for being able to put a torch inside a
shelf, which didn't make much sense gameplay-wise.  It ended up
going quite a bit further.

- Aggregate now gets wet in stack form.  Swimming with dry
  concrete now has consequences.
- Lux reactions, radiation, and infusion should now behave more
  consistently.
- Sponges can now wet or dry in stack form, including inside
  containers.
- Torch ignition, quenching, and extinguishing is now more
  consistent regardless of context, and torches are now more
  dangerous, and can ignite things in more contexts.
2019-10-29 20:03:18 -04:00

102 lines
3.0 KiB
Lua

-- LUALOCALS < ---------------------------------------------------------
local minetest, nodecore, pairs
= minetest, nodecore, pairs
-- LUALOCALS > ---------------------------------------------------------
local modname = minetest.get_current_modname()
local function findwater(pos)
return minetest.find_nodes_in_area(
{x = pos.x - 1, y = pos.y - 1, z = pos.z - 1},
{x = pos.x + 1, y = pos.y + 1, z = pos.z + 1},
{"group:water"})
end
local function soakup(pos)
local any
for _, p in pairs(findwater(pos)) do
nodecore.node_sound(p, "dig")
minetest.remove_node(p)
any = true
end
return any
end
nodecore.register_limited_abm({
label = "Sponge Wettening",
interval = 1,
chance = 10,
limited_max = 100,
nodenames = {modname .. ":sponge"},
neighbors = {"group:water"},
action = function(pos)
if soakup(pos) then
minetest.set_node(pos, {name = modname .. ":sponge_wet"})
nodecore.node_sound(pos, "place")
end
end
})
nodecore.register_aism({
label = "Sponge Stack Wettening",
interval = 1,
chance = 10,
itemnames = {modname .. ":sponge"},
action = function(stack, data)
if data.pos and soakup(data.pos) then
local taken = stack:take_item(1)
taken:set_name(modname .. ":sponge_wet")
if data.inv then taken = data.inv:add_item("main", taken) end
if not taken:is_empty() then nodecore.item_eject(data.pos, taken) end
return stack
end
end
})
nodecore.register_limited_abm({
label = "Sponge Drying in Sunlight",
interval = 1,
chance = 100,
limited_max = 100,
nodenames = {modname .. ":sponge_wet", modname .. ":sponge_living"},
action = function(pos)
if minetest.get_node_light(pos) >= 15 and #findwater(pos) < 1 then
minetest.sound_play("nc_api_craft_hiss", {gain = 0.02, pos = pos})
return minetest.set_node(pos, {name = modname .. ":sponge"})
end
end
})
nodecore.register_aism({
label = "Sponge Stack Drying in Sunlight",
interval = 1,
chance = 100,
itemnames = {modname .. ":sponge_wet", modname .. ":sponge_living"},
action = function(stack, data)
if data.player and (data.list ~= "main"
or data.slot ~= data.player:get_wield_index()) then return end
local ll = data.pos and minetest.get_node_light(data.pos)
if ll and ll >= 15 and #findwater(data.pos) < 1 then
minetest.sound_play("nc_api_craft_hiss", {gain = 0.02, pos = data.pos})
local taken = stack:take_item(1)
taken:set_name(modname .. ":sponge")
if data.inv then taken = data.inv:add_item("main", taken) end
if not taken:is_empty() then nodecore.item_eject(data.pos, taken) end
return stack
end
end
})
nodecore.register_limited_abm({
label = "Sponge Drying near Fire",
interval = 1,
chance = 20,
limited_max = 100,
nodenames = {modname .. ":sponge_wet", modname .. ":sponge_living"},
neighbors = {"group:igniter"},
action = function(pos)
minetest.sound_play("nc_api_craft_hiss", {gain = 0.02, pos = pos})
return minetest.set_node(pos, {name = modname .. ":sponge"})
end
})