diff --git a/init.lua b/init.lua index 57dcc1b..d8101c1 100644 --- a/init.lua +++ b/init.lua @@ -7,10 +7,14 @@ fire = { -- 'Enable fire' setting local fire_enabled = minetest.settings:get_bool("enable_fire") + if fire_enabled == nil then + -- enable_fire setting not specified, check for disable_fire local fire_disabled = minetest.settings:get_bool("disable_fire") + if fire_disabled == nil then + -- Neither setting specified, check whether singleplayer fire_enabled = minetest.is_singleplayer() else @@ -35,20 +39,21 @@ local function add_effect(pos) maxexptime = 3, minsize = 2, maxsize = 5, - texture = "tnt_smoke.png", + texture = "tnt_smoke.png" }) end -- Flood flame function local function flood_flame(pos, oldnode, newnode) + -- Play flame extinguish sound if liquid is not an 'igniter' - local nodedef = minetest.registered_items[newnode.name] - if not (nodedef and nodedef.groups and - nodedef.groups.igniter and nodedef.groups.igniter > 0) then - minetest.sound_play("fire_extinguish_flame", - {pos = pos, max_hear_distance = 16, gain = 0.15}) + if minetest.get_item_group(newnode.name, "igniter") == 0 then + + minetest.sound_play("fire_extinguish_flame", { + pos = pos, max_hear_distance = 16, gain = 0.15}, true) end + -- Remove the flame return false end @@ -76,20 +81,26 @@ minetest.register_node("fire:basic_flame", { sunlight_propagates = true, floodable = true, damage_per_second = 4, - groups = {igniter = 2, dig_immediate = 3, not_in_creative_inventory = 1}, + groups = {igniter = 2, dig_immediate = 3, fire = 1, not_in_creative_inventory = 1}, drop = {}, + on_timer = function(pos) + local f = minetest.find_node_near(pos, 1, {"group:flammable"}) + if not fire_enabled or not f then - --minetest.remove_node(pos) + minetest.swap_node(pos, {name = "air"}) + return end + -- Restart timer return true end, on_construct = function(pos) + if not fire_enabled then minetest.remove_node(pos) else @@ -97,7 +108,7 @@ minetest.register_node("fire:basic_flame", { end end, - on_flood = flood_flame, + on_flood = flood_flame }) minetest.register_node("fire:permanent_flame", { @@ -122,10 +133,10 @@ minetest.register_node("fire:permanent_flame", { sunlight_propagates = true, floodable = true, damage_per_second = 4, - groups = {igniter = 2, dig_immediate = 3}, + groups = {igniter = 2, fire = 1, dig_immediate = 3}, drop = {}, - on_flood = flood_flame, + on_flood = flood_flame }) -- Flint and steel @@ -136,38 +147,55 @@ minetest.register_tool("fire:flint_and_steel", { sound = {breaks = "default_tool_breaks"}, on_use = function(itemstack, user, pointed_thing) + local sound_pos = pointed_thing.above or user:get_pos() - minetest.sound_play( - "fire_flint_and_steel", - {pos = sound_pos, gain = 0.5, max_hear_distance = 8} - ) + + minetest.sound_play("fire_flint_and_steel", + {pos = sound_pos, gain = 0.5, max_hear_distance = 8}, true) + local player_name = user:get_player_name() + if pointed_thing.type == "node" then + local node_under = minetest.get_node(pointed_thing.under).name local nodedef = minetest.registered_nodes[node_under] + if not nodedef then return end + if minetest.is_protected(pointed_thing.under, player_name) then + minetest.chat_send_player(player_name, "This area is protected") + return end + if nodedef.on_ignite then nodedef.on_ignite(pointed_thing.under, user) + elseif minetest.get_item_group(node_under, "flammable") >= 1 - and minetest.get_node(pointed_thing.above).name == "air" then + and minetest.get_node(pointed_thing.above).name == "air" then + minetest.set_node(pointed_thing.above, {name = "fire:basic_flame"}) end end + if not (creative and creative.is_enabled_for and creative.is_enabled_for(player_name)) then + -- Wear tool local wdef = itemstack:get_definition() + itemstack:add_wear(1000) + -- Tool break sound if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then - minetest.sound_play(wdef.sound.breaks, {pos = sound_pos, gain = 0.5}) + + minetest.sound_play(wdef.sound.breaks, + {pos = sound_pos, gain = 0.5}, true) end + return itemstack end end @@ -184,16 +212,21 @@ minetest.register_craft({ -- Coalblock is non-flammable to avoid unwanted basic_flame nodes minetest.override_item("default:coalblock", { + after_destruct = function(pos, oldnode) + pos.y = pos.y + 1 + if minetest.get_node(pos).name == "fire:permanent_flame" then minetest.remove_node(pos) end end, + on_ignite = function(pos, igniter) + local flame_pos = {x = pos.x, y = pos.y + 1, z = pos.z} + if minetest.get_node(flame_pos).name == "air" then - --minetest.set_node(flame_pos, {name = "fire:permanent_flame"}) minetest.swap_node(flame_pos, {name = "fire:permanent_flame"}) end end, @@ -217,11 +250,16 @@ if fire_enabled then interval = 7, chance = 12, catch_up = false, + action = function(pos, node, active_object_count, active_object_count_wider) - if fire.spread == false then + + if fire.spread == false + or minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) then return end + local p = minetest.find_node_near(pos, 1, {"air"}) + if p then minetest.set_node(p, {name = "fire:basic_flame"}) end @@ -237,36 +275,52 @@ if fire_enabled then interval = 5, chance = 18, catch_up = false, + action = function(pos, node, active_object_count, active_object_count_wider) - if fire.spread == false then + + if fire.spread == false + or minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) then + minetest.remove_node(pos) + return end + local p = minetest.find_node_near(pos, 1, {"group:flammable"}) + if p then + local flammable_node = minetest.get_node(p) local def = minetest.registered_nodes[flammable_node.name] + if def.on_burn then def.on_burn(p) else minetest.remove_node(p) + add_effect(p) + minetest.check_for_falling(p) end end - end, + end }) - end -- used to drop items inside a chest or container + function fire.drop_items(pos, invstring) + local meta = minetest.get_meta(pos) local inv = meta:get_inventory() + for i = 1, inv:get_size(invstring) do + local m_stack = inv:get_stack(invstring, i) local obj = minetest.add_item(pos, m_stack) + if obj then + obj:set_velocity({ x = math.random(-10, 10) / 9, y = 1, @@ -281,15 +335,19 @@ end if minetest.registered_nodes["default:chest"] then local groups = minetest.registered_nodes["default:chest"].groups + groups.flammable = 3 minetest.override_item("default:chest", { groups = groups, + on_burn = function(p) + fire.drop_items(p, "main") - fire.drop_items(p, "default:chest") + minetest.add_item(p, {name = "default:chest"}) + minetest.remove_node(p) - end, + end }) end @@ -302,16 +360,20 @@ minetest.register_chatcommand("fire", { func = function (name, param) - if not param - or param == "" then + if not param or param == "" then return false, "No paramater set, use /fire (on|off)" end if param == "on" or param == "ON" then + fire.spread = true + return false, "fire spreading is ON" + elseif param == "off" or param == "OFF" then + fire.spread = false + return false, "fire spreading is OFF" end end