forked from Mineclonia/Mineclonia
replace laggy mcl fire with mtg abms
This commit is contained in:
parent
22ec7a65d8
commit
7375cc0706
|
@ -124,82 +124,6 @@ minetest.register_node("mcl_fire:fire", {
|
||||||
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
|
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_timer = function(pos)
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
-- Age is a number from 0 to 15 and is increased every timer step.
|
|
||||||
-- "old" fire is more likely to be extinguished
|
|
||||||
local age = node.param2
|
|
||||||
local flammables = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"})
|
|
||||||
local below = minetest.get_node({x=pos.x, y=pos.z-1, z=pos.z})
|
|
||||||
local below_is_flammable = minetest.get_item_group(below.name, "flammable") > 0
|
|
||||||
-- Extinguish fire
|
|
||||||
if (not fire_enabled) and (math.random(1,3) == 1) then
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if age == 15 and not below_is_flammable then
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
return
|
|
||||||
elseif age > 3 and #flammables == 0 and not below_is_flammable and math.random(1,4) == 1 then
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local age_add = 1
|
|
||||||
-- If fire spread is disabled, we have to skip the "destructive" code
|
|
||||||
if (not fire_enabled) then
|
|
||||||
if age + age_add <= 15 then
|
|
||||||
node.param2 = age + age_add
|
|
||||||
minetest.set_node(pos, node)
|
|
||||||
end
|
|
||||||
-- Restart timer
|
|
||||||
fire_timer(pos)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- Spawn fire to nearby flammable nodes
|
|
||||||
local is_next_to_flammable = minetest.find_node_near(pos, 2, {"group:flammable"}) ~= nil
|
|
||||||
if is_next_to_flammable and math.random(1,2) == 1 then
|
|
||||||
-- The fire we spawn copies the age of this fire.
|
|
||||||
-- This prevents fire from spreading infinitely far as the fire fire dies off
|
|
||||||
-- quicker the further it has spreaded.
|
|
||||||
local age_next = math.min(15, age + math.random(0, 1))
|
|
||||||
-- Select random type of fire spread
|
|
||||||
local burntype = math.random(1,2)
|
|
||||||
if burntype == 1 then
|
|
||||||
-- Spawn fire in air
|
|
||||||
local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"})
|
|
||||||
while #nodes > 0 do
|
|
||||||
local r = math.random(1, #nodes)
|
|
||||||
if minetest.find_node_near(nodes[r], 1, {"group:flammable"}) then
|
|
||||||
spawn_fire(nodes[r], age_next)
|
|
||||||
break
|
|
||||||
else
|
|
||||||
table.remove(nodes, r)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Burn flammable block
|
|
||||||
local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"})
|
|
||||||
if #nodes > 0 then
|
|
||||||
local r = math.random(1, #nodes)
|
|
||||||
local nn = minetest.get_node(nodes[r]).name
|
|
||||||
local ndef = minetest.registered_nodes[nn]
|
|
||||||
local fgroup = minetest.get_item_group(nn, "flammable")
|
|
||||||
if ndef and ndef._on_burn then
|
|
||||||
ndef._on_burn(nodes[r])
|
|
||||||
elseif fgroup ~= -1 then
|
|
||||||
spawn_fire(nodes[r], age_next)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Regular age increase
|
|
||||||
if age + age_add <= 15 then
|
|
||||||
node.param2 = age + age_add
|
|
||||||
minetest.set_node(pos, node)
|
|
||||||
end
|
|
||||||
-- Restart timer
|
|
||||||
fire_timer(pos)
|
|
||||||
end,
|
|
||||||
drop = "",
|
drop = "",
|
||||||
sounds = {},
|
sounds = {},
|
||||||
-- Turn into eternal fire on special blocks, light Nether portal (if possible), start burning timer
|
-- Turn into eternal fire on special blocks, light Nether portal (if possible), start burning timer
|
||||||
|
@ -255,29 +179,7 @@ minetest.register_node("mcl_fire:eternal_fire", {
|
||||||
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
|
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
on_timer = function(pos)
|
|
||||||
if fire_enabled then
|
|
||||||
local airs = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"})
|
|
||||||
while #airs > 0 do
|
|
||||||
local r = math.random(1, #airs)
|
|
||||||
if minetest.find_node_near(airs[r], 1, {"group:flammable"}) then
|
|
||||||
local node = minetest.get_node(airs[r])
|
|
||||||
local age = node.param2
|
|
||||||
local age_next = math.min(15, age + math.random(0, 1))
|
|
||||||
spawn_fire(airs[r], age_next)
|
|
||||||
break
|
|
||||||
else
|
|
||||||
table.remove(airs, r)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Restart timer
|
|
||||||
fire_timer(pos)
|
|
||||||
end,
|
|
||||||
-- Start burning timer and light Nether portal (if possible)
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
fire_timer(pos)
|
|
||||||
|
|
||||||
if minetest.get_modpath("mcl_portals") then
|
if minetest.get_modpath("mcl_portals") then
|
||||||
mcl_portals.light_nether_portal(pos)
|
mcl_portals.light_nether_portal(pos)
|
||||||
end
|
end
|
||||||
|
@ -402,6 +304,31 @@ if flame_sound then
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Set pointed_thing on (normal) fire.
|
||||||
|
-- * pointed_thing: Pointed thing to ignite
|
||||||
|
-- * player: Player who sets fire or nil if nobody
|
||||||
|
-- * allow_on_fire: If false, can't ignite fire on fire (default: true)
|
||||||
|
mcl_fire.set_fire = function(pointed_thing, player, allow_on_fire)
|
||||||
|
local pname
|
||||||
|
if player == nil then
|
||||||
|
pname = ""
|
||||||
|
else
|
||||||
|
pname = player:get_player_name()
|
||||||
|
end
|
||||||
|
local n = minetest.get_node(pointed_thing.above)
|
||||||
|
local nu = minetest.get_node(pointed_thing.under)
|
||||||
|
if allow_on_fire == false and minetest.get_item_group(nu.name, "fire") ~= 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if minetest.is_protected(pointed_thing.above, pname) then
|
||||||
|
minetest.record_protection_violation(pointed_thing.above, pname)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if n.name == "air" then
|
||||||
|
minetest.add_node(pointed_thing.above, {name="mcl_fire:fire"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- ABMs
|
-- ABMs
|
||||||
--
|
--
|
||||||
|
@ -508,31 +435,45 @@ else -- Fire enabled
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
end
|
-- Ignite neighboring nodes, add basic flames
|
||||||
|
minetest.register_abm({
|
||||||
|
label = "Ignite flame",
|
||||||
|
nodenames = {"group:flammable"},
|
||||||
|
neighbors = {"mcl_fire:fire","mcl_fire:eternal_fire","mcl_core:lava_source","mcl_core:lava_flowing","mcl_nether:nether_lava_source","mcl_nether:nether_lava_flowing",},
|
||||||
|
interval = 7,
|
||||||
|
chance = 12,
|
||||||
|
catch_up = false,
|
||||||
|
action = function(pos)
|
||||||
|
local p = minetest.find_node_near(pos, 1, {"air"})
|
||||||
|
if p then
|
||||||
|
minetest.set_node(p, {name = "mcl_fire:fire"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
-- Set pointed_thing on (normal) fire.
|
-- Remove flammable nodes around basic flame
|
||||||
-- * pointed_thing: Pointed thing to ignite
|
minetest.register_abm({
|
||||||
-- * player: Player who sets fire or nil if nobody
|
label = "Remove flammable nodes",
|
||||||
-- * allow_on_fire: If false, can't ignite fire on fire (default: true)
|
nodenames = {"mc_fire:fire"},
|
||||||
mcl_fire.set_fire = function(pointed_thing, player, allow_on_fire)
|
neighbors = "group:flammable",
|
||||||
local pname
|
interval = 5,
|
||||||
if player == nil then
|
chance = 18,
|
||||||
pname = ""
|
catch_up = false,
|
||||||
else
|
action = function(pos)
|
||||||
pname = player:get_player_name()
|
local p = minetest.find_node_near(pos, 1, {"group:flammable"})
|
||||||
end
|
if not p then
|
||||||
local n = minetest.get_node(pointed_thing.above)
|
return
|
||||||
local nu = minetest.get_node(pointed_thing.under)
|
end
|
||||||
if allow_on_fire == false and minetest.get_item_group(nu.name, "fire") ~= 0 then
|
local flammable_node = minetest.get_node(p)
|
||||||
return
|
local def = minetest.registered_nodes[flammable_node.name]
|
||||||
end
|
if def.on_burn then
|
||||||
if minetest.is_protected(pointed_thing.above, pname) then
|
def.on_burn(p)
|
||||||
minetest.record_protection_violation(pointed_thing.above, pname)
|
else
|
||||||
return
|
minetest.remove_node(p)
|
||||||
end
|
minetest.check_for_falling(p)
|
||||||
if n.name == "air" then
|
end
|
||||||
minetest.add_node(pointed_thing.above, {name="mcl_fire:fire"})
|
end
|
||||||
end
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_lbm({
|
minetest.register_lbm({
|
||||||
|
|
Loading…
Reference in New Issue