More flexible burning API.

Stone, lode, and lux tools now all have their handles burn, and
eject the non-flammable portions of the tool.

Now using a unified on_ignite hook for when flammable things catch
fire.  The call is made BEFORE the node is replaced, and has an
opportunity to look at node metadata and eject anything
non-flammable.

It can be a function, e.g. for shelves, or a static value in the
same format that the function would return (e.g. for lode tools
which need string values for temper substitutions).

If it returns a string or itemstack, it will eject that from the
position where the node burned.  If it returns a table it will
eject all the values of that table.
This commit is contained in:
Aaron Suen 2019-09-07 11:28:51 -04:00
parent 6385ce9843
commit 9a75f4c87a
5 changed files with 35 additions and 17 deletions

View File

@ -9,10 +9,6 @@ ISSUES: Bugs, Cleanup and Refinements
# # # # # # # # # # # #
#### # #### # ###### ###### # # ####
- Burning consistency.
- Add burns_to hook. Make stone tools burn to stone chip,
make lode/lux tools burn to lode prills.
- Stone doors don't necessarily dig right. Probably leftover junk
being inherited in the cloning; need to dig through the properties
and remove the ones we don't want inherited.

View File

@ -1,6 +1,6 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, math, minetest, nodecore, pairs, vector
= ipairs, math, minetest, nodecore, pairs, vector
local ItemStack, ipairs, math, minetest, nodecore, pairs, type, vector
= ItemStack, ipairs, math, minetest, nodecore, pairs, type, vector
local math_floor, math_pow, math_random
= math.floor, math.pow, math.random
-- LUALOCALS > ---------------------------------------------------------
@ -15,7 +15,7 @@ do
minetest.after(0, function()
for k, v in pairs(minetest.registered_items) do
if v.groups.flammable and not v.groups.fire_fuel
or v.groups.flame or v.name == "air" then
and not v.on_ignite or v.groups.flame or v.name == "air" then
ventitems[k] = v.groups.flame or 0
end
end
@ -50,24 +50,41 @@ do
end
end
local function burneject(pos, stack)
if type(stack) == "table" then
for _, v in pairs(stack) do
burneject(pos, v)
end
return
end
if type(stack) == "string" then stack = ItemStack(stack) end
if not stack.is_empty then return end
if stack and (not stack:is_empty()) then
local p = nodecore.scan_flood(pos, 2, nodecore.buildable_to)
nodecore.item_eject(p or pos, stack, 1)
end
end
function nodecore.fire_ignite(pos, node)
node = node or minetest.get_node(pos)
minetest.chat_send_all(node.name)
local def = minetest.registered_items[node.name]
if def and def.on_ignite then
local ign = def.on_ignite
if type(ign) == "function" then ign = ign(pos, node) end
burneject(pos, ign)
end
local fuel = nodecore.node_group("fire_fuel", pos, node) or 0
if fuel < 0 then fuel = 0 end
if fuel > nodecore.fire_max then fuel = nodecore.fire_max end
fuel = math_floor(fuel)
local stack
if nodecore.node_group("eject_inv_on_burn", pos, node) then
stack = nodecore.stack_get(pos)
if stack and (not stack:is_empty()) then
local p = nodecore.scan_flood(pos, 2, nodecore.buildable_to)
nodecore.item_eject(p or pos, stack, 1)
end
end
if fuel > 0 then
minetest.set_node(pos, {name = modname .. ":ember" .. fuel})
else
minetest.set_node(pos, {name = modname .. ":fire"})
end
minetest.sound_play("nc_fire_ignite", {gain = 1, pos = pos})
minetest.sound_play("nc_fire_flamy", {gain = 3, pos = pos})
minetest.after(0, function() minetest.check_for_falling(pos) end)

View File

@ -36,8 +36,10 @@ local function toolhead(name, groups, prills)
d.tool_capabilities = toolcap(5)
end
end,
groups = { flammable = 4 },
metal_alt_hot = modname .. ":prill_hot " .. prills,
tool_wears_to = modname .. ":prill_# " .. prills
tool_wears_to = modname .. ":prill_# " .. prills,
on_ignite = modname .. ":prill_# " .. prills
})
for _, t in pairs({"annealed", "tempered"}) do

View File

@ -54,6 +54,7 @@ local function tooltip(name, group)
uses = 0.25,
[group] = 3
}),
on_ignite = modname .. ":chip",
sounds = nodecore.sounds("nc_terrain_stony")
})
nodecore.register_stone_tip_tool({from = wood, to = tool})

View File

@ -28,7 +28,6 @@ minetest.register_node(modname .. ":shelf", {
visinv = 1,
flammable = 2,
fire_fuel = 3,
eject_inv_on_burn = 1,
container = 1,
totable = 1
},
@ -60,6 +59,9 @@ minetest.register_node(modname .. ":shelf", {
return minetest.node_dig(pos, node, digger, ...)
end
end,
on_ignite = function(pos)
return nodecore.stack_get(pos)
end,
stack_allow = function(_, _, stack)
local def = minetest.registered_items[stack:get_name()] or {}
if def.groups and def.groups.container then return false end