2019-01-17 00:01:00 -05:00
|
|
|
-- LUALOCALS < ---------------------------------------------------------
|
2022-01-22 15:30:41 -05:00
|
|
|
local ItemStack, ipairs, math, minetest, nodecore, pairs, string, type,
|
|
|
|
vector
|
|
|
|
= ItemStack, ipairs, math, minetest, nodecore, pairs, string, type,
|
|
|
|
vector
|
|
|
|
local math_floor, math_pow, math_random, string_format
|
|
|
|
= math.floor, math.pow, math.random, string.format
|
2019-01-17 00:01:00 -05:00
|
|
|
-- LUALOCALS > ---------------------------------------------------------
|
|
|
|
|
|
|
|
local modname = minetest.get_current_modname()
|
|
|
|
|
2019-03-31 20:54:38 -04:00
|
|
|
nodecore.fire_max = 8
|
|
|
|
|
|
|
|
do
|
|
|
|
local flamedirs = nodecore.dirs()
|
|
|
|
local ventitems = {}
|
|
|
|
minetest.after(0, function()
|
|
|
|
for k, v in pairs(minetest.registered_items) do
|
|
|
|
if v.groups.flammable and not v.groups.fire_fuel
|
2019-09-07 11:28:51 -04:00
|
|
|
and not v.on_ignite or v.groups.flame or v.name == "air" then
|
2019-03-31 20:54:38 -04:00
|
|
|
ventitems[k] = v.groups.flame or 0
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
local stackonly = {}
|
|
|
|
minetest.after(0, function()
|
|
|
|
for k, v in pairs(minetest.registered_items) do
|
|
|
|
if v.groups.is_stack_only then
|
|
|
|
stackonly[k] = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
function nodecore.fire_vents(pos)
|
|
|
|
local found = {}
|
|
|
|
for _, dp in ipairs(flamedirs) do
|
|
|
|
local npos = vector.add(pos, dp)
|
|
|
|
local node = minetest.get_node_or_nil(npos)
|
|
|
|
if not node then return end
|
|
|
|
|
|
|
|
local q
|
|
|
|
if stackonly[node.name] then
|
|
|
|
q = ventitems[nodecore.stack_get(npos):get_name()]
|
|
|
|
else
|
|
|
|
q = ventitems[node.name]
|
|
|
|
end
|
|
|
|
if q then
|
|
|
|
npos.q = q
|
2019-08-27 19:14:51 -04:00
|
|
|
found[#found + 1] = npos
|
2019-03-31 20:54:38 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
return found
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-09-07 11:28:51 -04:00
|
|
|
local function burneject(pos, stack)
|
2019-12-01 16:54:15 -05:00
|
|
|
if not stack then return end
|
2019-09-07 11:28:51 -04:00
|
|
|
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
|
|
|
|
|
2019-03-31 20:54:38 -04:00
|
|
|
function nodecore.fire_ignite(pos, node)
|
2019-09-07 11:28:51 -04:00
|
|
|
node = node or minetest.get_node(pos)
|
2022-01-22 15:30:41 -05:00
|
|
|
nodecore.log("action", string_format("ignite %s at %s", node.name,
|
|
|
|
minetest.pos_to_string(pos)))
|
2019-09-07 11:28:51 -04:00
|
|
|
local def = minetest.registered_items[node.name]
|
|
|
|
if def and def.on_ignite then
|
|
|
|
local ign = def.on_ignite
|
2019-10-01 18:26:29 -04:00
|
|
|
if type(ign) == "function" then
|
|
|
|
ign = ign(pos, node)
|
|
|
|
if ign == true then return end
|
|
|
|
end
|
2019-09-07 11:28:51 -04:00
|
|
|
burneject(pos, ign)
|
|
|
|
end
|
2019-11-28 11:18:03 -05:00
|
|
|
if node and node.count and node.count > 1 then
|
2022-01-04 06:28:35 -05:00
|
|
|
nodecore.item_disperse(pos, node.name, node.count - 1)
|
2019-11-28 11:18:03 -05:00
|
|
|
end
|
2019-09-07 11:28:51 -04:00
|
|
|
|
2019-01-17 00:01:00 -05:00
|
|
|
local fuel = nodecore.node_group("fire_fuel", pos, node) or 0
|
|
|
|
if fuel < 0 then fuel = 0 end
|
2019-03-31 20:54:38 -04:00
|
|
|
if fuel > nodecore.fire_max then fuel = nodecore.fire_max end
|
2019-01-17 00:01:00 -05:00
|
|
|
fuel = math_floor(fuel)
|
2019-03-24 21:08:39 -04:00
|
|
|
if fuel > 0 then
|
2022-08-24 20:43:54 -04:00
|
|
|
nodecore.set_node_check(pos, {name = modname .. ":ember" .. fuel})
|
2019-03-24 21:08:39 -04:00
|
|
|
else
|
2022-08-24 20:43:54 -04:00
|
|
|
nodecore.set_node_check(pos, {name = modname .. ":fire"})
|
2019-03-24 21:08:39 -04:00
|
|
|
end
|
2019-09-07 11:28:51 -04:00
|
|
|
|
2020-04-05 21:22:51 -04:00
|
|
|
nodecore.sound_play("nc_fire_ignite", {gain = 1, pos = pos})
|
|
|
|
nodecore.sound_play("nc_fire_flamy", {gain = 3, pos = pos})
|
2019-09-09 07:05:01 -04:00
|
|
|
nodecore.fallcheck(pos)
|
2019-03-31 20:54:38 -04:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function nodecore.fire_check_ignite(pos, node, force, ...)
|
|
|
|
if not force then
|
|
|
|
node = node or minetest.get_node(pos)
|
|
|
|
local def = minetest.registered_items[node.name] or {}
|
|
|
|
local flam = def.groups and def.groups.flammable
|
|
|
|
if not flam then return end
|
|
|
|
if math_random(1, flam) ~= 1 then return end
|
|
|
|
end
|
|
|
|
|
2019-11-28 13:04:35 -05:00
|
|
|
local vents = nodecore.fire_vents(pos)
|
|
|
|
if (not vents) or #vents < 1 then return end
|
|
|
|
|
|
|
|
if nodecore.quenched(pos) then return end
|
|
|
|
|
2019-03-31 20:54:38 -04:00
|
|
|
return nodecore.fire_ignite(pos, node, ...)
|
2019-01-17 00:01:00 -05:00
|
|
|
end
|
|
|
|
|
2019-04-03 07:40:19 -04:00
|
|
|
local function snuff(cons, coal, pos, node, ember)
|
|
|
|
ember = ember or nodecore.node_group("ember", pos, node)
|
2019-01-17 00:01:00 -05:00
|
|
|
if not ember then return end
|
2019-03-31 20:54:38 -04:00
|
|
|
ember = ember - cons
|
2019-03-24 21:08:39 -04:00
|
|
|
if ember > 0 then
|
2019-03-31 20:54:38 -04:00
|
|
|
if coal then
|
2022-08-24 20:43:54 -04:00
|
|
|
nodecore.set_node_check(pos, {name = modname .. ":coal" .. ember})
|
2020-04-05 21:22:51 -04:00
|
|
|
nodecore.sound_play("nc_fire_snuff", {gain = 1, pos = pos})
|
2019-03-31 20:54:38 -04:00
|
|
|
else
|
2022-08-24 20:43:54 -04:00
|
|
|
nodecore.set_node_check(pos, {name = modname .. ":ember" .. ember})
|
2019-03-31 20:54:38 -04:00
|
|
|
end
|
2019-03-24 21:08:39 -04:00
|
|
|
else
|
2022-08-24 20:43:54 -04:00
|
|
|
nodecore.set_node_check(pos, {name = modname .. ":ash"})
|
2020-04-05 21:22:51 -04:00
|
|
|
nodecore.sound_play("nc_fire_snuff", {gain = 1, pos = pos})
|
2019-03-24 21:08:39 -04:00
|
|
|
end
|
2019-09-09 07:05:01 -04:00
|
|
|
nodecore.fallcheck(pos)
|
2019-03-31 20:54:38 -04:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function nodecore.fire_snuff(...) return snuff(1, true, ...) end
|
|
|
|
function nodecore.fire_expend(...) return snuff(1, false, ...) end
|
|
|
|
|
|
|
|
function nodecore.fire_check_expend(pos, node)
|
2019-04-03 07:40:19 -04:00
|
|
|
local ember = nodecore.node_group("ember", pos, node)
|
|
|
|
if not ember then return end
|
|
|
|
local r = math_random(1, 16 * math_pow(2, ember))
|
|
|
|
if r == 1 then return nodecore.fire_expend(pos, node, ember) end
|
2019-03-31 20:54:38 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
local function snuffcheck(pos, node)
|
|
|
|
if nodecore.quenched(pos) then return true end
|
|
|
|
local vents = nodecore.fire_vents(pos, node)
|
|
|
|
if not vents then return end
|
|
|
|
if #vents < 1 then return true end
|
|
|
|
return false, vents
|
|
|
|
end
|
|
|
|
|
|
|
|
function nodecore.fire_check_snuff(pos, node)
|
|
|
|
local res, vents = snuffcheck(pos, node)
|
|
|
|
res = res and nodecore.fire_snuff(pos)
|
|
|
|
return res, vents
|
2019-01-17 00:01:00 -05:00
|
|
|
end
|
2020-09-28 22:17:22 -04:00
|
|
|
|
|
|
|
minetest.register_chatcommand("ignite", {
|
|
|
|
description = "Set fire to all nearby flammables",
|
|
|
|
privs = {["debug"] = true},
|
|
|
|
func = function(pname)
|
|
|
|
local player = minetest.get_player_by_name(pname)
|
|
|
|
if not player then return end
|
|
|
|
local pos = player:get_pos()
|
|
|
|
for _, p in pairs(nodecore.find_nodes_around(pos, "group:flammable", 5)) do
|
|
|
|
nodecore.fire_check_ignite(p, nil, true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
})
|
|
|
|
minetest.register_chatcommand("snuff", {
|
|
|
|
description = "Extinguish all nearby embers",
|
|
|
|
privs = {["debug"] = true},
|
|
|
|
func = function(pname)
|
|
|
|
local player = minetest.get_player_by_name(pname)
|
|
|
|
if not player then return end
|
|
|
|
local pos = player:get_pos()
|
|
|
|
for _, p in pairs(nodecore.find_nodes_around(pos, "group:ember", 5)) do
|
|
|
|
snuff(0, true, p)
|
|
|
|
end
|
|
|
|
for _, p in pairs(nodecore.find_nodes_around(pos, modname .. ":fire", 5)) do
|
|
|
|
minetest.remove_node(p)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
})
|