diff --git a/game_api.txt b/game_api.txt index 7395f3b4..6f4af4a8 100644 --- a/game_api.txt +++ b/game_api.txt @@ -175,6 +175,10 @@ farming.register_plant(name, Plant definition) maxlight = default.LIGHT_MAX -- Maximum light to grow } +Fire API +---------- +Add group flammable when registering a node to make fire seek for it. + Screwdriver API --------------- The screwdriver API allows you to control a node's behaviour when a screwdriver is used on it. diff --git a/mods/fire/init.lua b/mods/fire/init.lua index a5566628..cc49ae70 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -7,43 +7,7 @@ fire = {} -- Register flame nodes -minetest.register_node("fire:basic_flame", { - description = "Basic Flame", - drawtype = "firelike", - tiles = { - { - name = "fire_basic_flame_animated.png", - animation = { - type = "vertical_frames", - aspect_w = 16, - aspect_h = 16, - length = 1 - }, - }, - }, - inventory_image = "fire_basic_flame.png", - paramtype = "light", - light_source = 14, - walkable = false, - buildable_to = true, - sunlight_propagates = true, - damage_per_second = 4, - groups = {igniter = 2, dig_immediate = 3}, - drop = "", - - on_construct = function(pos) - minetest.after(0, fire.on_flame_add_at, pos) - end, - - on_destruct = function(pos) - minetest.after(0, fire.on_flame_remove_at, pos) - end, - - on_blast = function() - end, -- unaffected by explosions -}) - -minetest.register_node("fire:permanent_flame", { +local flamedef = { description = "Permanent Flame", drawtype = "firelike", tiles = { @@ -68,26 +32,32 @@ minetest.register_node("fire:permanent_flame", { drop = "", on_blast = function() - end, -}) + end, -- unaffected by explosions +} +minetest.register_node("fire:permanent_flame", table.copy(flamedef)) + +flamedef.description = "Basic Flame" +flamedef.on_construct = function(pos) + minetest.after(0, fire.on_flame_add_at, pos) +end +flamedef.on_destruct = function(pos) + minetest.after(0, fire.on_flame_remove_at, pos) +end + +minetest.register_node("fire:basic_flame", flamedef) -- Get sound area of position fire.D = 6 -- size of sound areas +local function floor_coord(c) + return c - c%fire.D +end + function fire.get_area_p0p1(pos) - local p0 = { - x = math.floor(pos.x / fire.D) * fire.D, - y = math.floor(pos.y / fire.D) * fire.D, - z = math.floor(pos.z / fire.D) * fire.D, - } - local p1 = { - x = p0.x + fire.D - 1, - y = p0.y + fire.D - 1, - z = p0.z + fire.D - 1 - } - return p0, p1 + local p0 = vector.apply(pos, floor_coord) + return p0, vector.add(p0, fire.D - 1) end @@ -101,15 +71,15 @@ fire.sounds = {} function fire.update_sounds_around(pos) local p0, p1 = fire.get_area_p0p1(pos) - local cp = {x = (p0.x + p1.x) / 2, y = (p0.y + p1.y) / 2, z = (p0.z + p1.z) / 2} + local cp = vector.divide(vector.add(p0, p1), 2) local flames_p = minetest.find_nodes_in_area(p0, p1, {"fire:basic_flame"}) --print("number of flames at "..minetest.pos_to_string(p0).."/" -- ..minetest.pos_to_string(p1)..": "..#flames_p) - local should_have_sound = (#flames_p > 0) - local wanted_sound = nil + local should_have_sound = #flames_p > 0 + local wanted_sound if #flames_p >= 9 then wanted_sound = {name = "fire_large", gain = 0.7} - elseif #flames_p > 0 then + elseif should_have_sound then wanted_sound = {name = "fire_small", gain = 0.9} end local p0_hash = minetest.hash_node_position(p0) @@ -172,7 +142,7 @@ minetest.register_abm({ interval = 3, chance = 1, catch_up = false, - action = function(p0, node, _, _) + action = function(p0) minetest.remove_node(p0) minetest.sound_play("fire_extinguish_flame", {pos = p0, max_hear_distance = 16, gain = 0.25}) @@ -191,9 +161,7 @@ if minetest.setting_getbool("disable_fire") then interval = 7, chance = 1, catch_up = false, - action = function(p0, node, _, _) - minetest.remove_node(p0) - end, + action = minetest.remove_node, }) else @@ -206,7 +174,7 @@ else interval = 7, chance = 16, catch_up = false, - action = function(p0, node, _, _) + action = function(p0) -- If there is water or stuff like that around node, don't ignite if fire.flame_should_extinguish(p0) then return @@ -225,20 +193,22 @@ else interval = 5, chance = 16, catch_up = false, - action = function(p0, node, _, _) + action = function(p0) -- If there are no flammable nodes around flame, remove flame if not minetest.find_node_near(p0, 1, {"group:flammable"}) then minetest.remove_node(p0) return end - if math.random(1, 4) == 1 then - -- remove flammable nodes around flame - local p = minetest.find_node_near(p0, 1, {"group:flammable"}) - if p then - minetest.remove_node(p) - nodeupdate(p) - end + if math.random(1, 4) ~= 1 then + return end + -- remove flammable nodes around flame + local p = minetest.find_node_near(p0, 1, {"group:flammable"}) + if not p then + return + end + minetest.remove_node(p) + nodeupdate(p) end, })