diff --git a/mods/default/init.lua b/mods/default/init.lua index a2db93d9..b3679866 100644 --- a/mods/default/init.lua +++ b/mods/default/init.lua @@ -1009,7 +1009,7 @@ minetest.register_node("default:water_flowing", { {image="default_water.png", backface_culling=false}, {image="default_water.png", backface_culling=true}, }, - groups = {water=3, liquid=3}, + groups = {water=3, liquid=3, puts_out_fire=1}, }) minetest.register_node("default:water_source", { @@ -1032,7 +1032,7 @@ minetest.register_node("default:water_source", { -- New-style water source material (mostly unused) {image="default_water.png", backface_culling=false}, }, - groups = {water=3, liquid=3}, + groups = {water=3, liquid=3, puts_out_fire=1}, }) minetest.register_node("default:lava_flowing", { @@ -1056,7 +1056,7 @@ minetest.register_node("default:lava_flowing", { {image="default_lava.png", backface_culling=false}, {image="default_lava.png", backface_culling=true}, }, - groups = {lava=3, liquid=2, hot=3, igniter=3}, + groups = {lava=3, liquid=2, hot=3, igniter=2}, }) minetest.register_node("default:lava_source", { @@ -1080,7 +1080,7 @@ minetest.register_node("default:lava_source", { -- New-style lava source material (mostly unused) {image="default_lava.png", backface_culling=false}, }, - groups = {lava=3, liquid=2, hot=3, igniter=3}, + groups = {lava=3, liquid=2, hot=3, igniter=2}, }) minetest.register_node("default:torch", { @@ -1100,7 +1100,7 @@ minetest.register_node("default:torch", { wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1}, wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1}, }, - groups = {choppy=2,dig_immediate=3}, + groups = {choppy=2,dig_immediate=3,flammable=1}, legacy_wallmounted = true, sounds = default.node_sound_defaults(), }) diff --git a/mods/fire/README.txt b/mods/fire/README.txt new file mode 100644 index 00000000..b240f115 --- /dev/null +++ b/mods/fire/README.txt @@ -0,0 +1,30 @@ +Minetest 0.4 mod: fire +====================== + +License of source code: +----------------------- +Copyright (C) 2012 Perttu Ahola (celeron55) + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +http://www.gnu.org/licenses/gpl-2.0.html + +License of media (textures and sounds) +-------------------------------------- +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +Authors of media files +----------------------- +Everything not listed in here: +Copyright (C) 2012 Perttu Ahola (celeron55) + +fire_small.ogg sampled from: + http://www.freesound.org/people/dobroide/sounds/4211/ + +fire_large.ogg sampled from: + http://www.freesound.org/people/Dynamicell/sounds/17548/ + diff --git a/mods/fire/init.lua b/mods/fire/init.lua new file mode 100644 index 00000000..78f97269 --- /dev/null +++ b/mods/fire/init.lua @@ -0,0 +1,188 @@ +-- minetest/fire/init.lua + +minetest.register_node("fire:basic_flame", { + description = "Fire", + drawtype = "glasslike", + tile_images = {"fire_basic_flame.png"}, + light_source = 14, + groups = {igniter=3,dig_immediate=3}, + drop = '', + walkable = false, +}) + +local fire = {} +fire.D = 6 +-- key: position hash of low corner of area +-- value: {handle=sound handle, name=sound name} +fire.sounds = {} + +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 +end + +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 flames_p = minetest.env: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 + if #flames_p >= 9 then + wanted_sound = {name="fire_large", gain=1.5} + elseif #flames_p > 0 then + wanted_sound = {name="fire_small", gain=1.5} + end + local p0_hash = minetest.hash_node_position(p0) + local sound = fire.sounds[p0_hash] + if not sound then + if should_have_sound then + fire.sounds[p0_hash] = { + handle = minetest.sound_play(wanted_sound, {pos=cp, loop=true}), + name = wanted_sound.name, + } + end + else + if not wanted_sound then + minetest.sound_stop(sound.handle) + fire.sounds[p0_hash] = nil + elseif sound.name ~= wanted_sound.name then + minetest.sound_stop(sound.handle) + fire.sounds[p0_hash] = { + handle = minetest.sound_play(wanted_sound, {pos=cp, loop=true}), + name = wanted_sound.name, + } + end + end +end + +function fire.on_flame_add_at(pos) + --print("flame added at "..minetest.pos_to_string(pos)) + fire.update_sounds_around(pos) +end + +function fire.on_flame_remove_at(pos) + --print("flame removed at "..minetest.pos_to_string(pos)) + fire.update_sounds_around(pos) +end + +function fire.find_pos_for_flame_around(pos) + return minetest.env:find_node_near(pos, 1, {"air"}) +end + +function fire.flame_should_extinguish(pos) + --return minetest.env:find_node_near(pos, 1, {"group:puts_out_fire"}) + local p0 = {x=pos.x-2, y=pos.y, z=pos.z-2} + local p1 = {x=pos.x+2, y=pos.y, z=pos.z+2} + local ps = minetest.env:find_nodes_in_area(p0, p1, {"group:puts_out_fire"}) + return (#ps ~= 0) +end + +minetest.register_on_placenode(function(pos, newnode, placer) + if newnode.name == "fire:basic_flame" then + fire.on_flame_add_at(pos) + end +end) + +minetest.register_on_dignode(function(pos, oldnode, digger) + if oldnode.name == "fire:basic_flame" then + fire.on_flame_remove_at(pos) + end +end) + +-- Ignite neighboring nodes +minetest.register_abm({ + nodenames = {"group:flammable"}, + neighbors = {"group:igniter"}, + interval = 1, + chance = 2, + action = function(p0, node, _, _) + -- If there is water or stuff like that around flame, don't ignite + if fire.flame_should_extinguish(p0) then + return + end + local p = fire.find_pos_for_flame_around(p0) + if p then + minetest.env:set_node(p, {name="fire:basic_flame"}) + fire.on_flame_add_at(p) + end + end, +}) + +-- Rarely ignite things from far +minetest.register_abm({ + nodenames = {"group:igniter"}, + neighbors = {"air"}, + interval = 2, + chance = 10, + action = function(p0, node, _, _) + local reg = minetest.registered_nodes[node.name] + if not reg or not reg.groups.igniter or reg.groups.igniter < 2 then + return + end + local d = reg.groups.igniter + local p = minetest.env:find_node_near(p0, d, {"group:flammable"}) + if p then + -- If there is water or stuff like that around flame, don't ignite + if fire.flame_should_extinguish(p) then + return + end + local p2 = fire.find_pos_for_flame_around(p) + if p2 then + minetest.env:set_node(p2, {name="fire:basic_flame"}) + fire.on_flame_add_at(p2) + end + end + end, +}) + +-- Remove flammable nodes and flame +minetest.register_abm({ + nodenames = {"fire:basic_flame"}, + interval = 1, + chance = 2, + action = function(p0, node, _, _) + -- If there is water or stuff like that around flame, remove flame + if fire.flame_should_extinguish(p0) then + minetest.env:remove_node(p0) + fire.on_flame_remove_at(p0) + return + end + -- Make the following things rarer + if math.random(1,3) == 1 then + return + end + -- If there are no flammable nodes around flame, remove flame + if not minetest.env:find_node_near(p0, 1, {"group:flammable"}) then + minetest.env:remove_node(p0) + fire.on_flame_remove_at(p0) + return + end + if math.random(1,4) == 1 then + -- remove a flammable node around flame + local p = minetest.env:find_node_near(p0, 1, {"group:flammable"}) + if p then + -- If there is water or stuff like that around flame, don't remove + if fire.flame_should_extinguish(p0) then + return + end + minetest.env:remove_node(p) + end + else + -- remove flame + minetest.env:remove_node(p0) + fire.on_flame_remove_at(p0) + end + end, +}) + diff --git a/mods/fire/sounds/fire_large.ogg b/mods/fire/sounds/fire_large.ogg new file mode 100644 index 00000000..fe78e625 Binary files /dev/null and b/mods/fire/sounds/fire_large.ogg differ diff --git a/mods/fire/sounds/fire_small.ogg b/mods/fire/sounds/fire_small.ogg new file mode 100644 index 00000000..5aac595b Binary files /dev/null and b/mods/fire/sounds/fire_small.ogg differ diff --git a/mods/fire/textures/fire_basic_flame.png b/mods/fire/textures/fire_basic_flame.png new file mode 100644 index 00000000..a5c2afda Binary files /dev/null and b/mods/fire/textures/fire_basic_flame.png differ