forked from luanti-org/minetest_game
		
	Add fire. Lava can cause it, and you can /giveme fire:basic_flame.
This commit is contained in:
		
							
								
								
									
										30
									
								
								mods/fire/README.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								mods/fire/README.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| Minetest 0.4 mod: fire | ||||
| ====================== | ||||
|  | ||||
| License of source code: | ||||
| ----------------------- | ||||
| Copyright (C) 2012 Perttu Ahola (celeron55) <celeron55@gmail.com> | ||||
|  | ||||
| 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) <celeron55@gmail.com> | ||||
|  | ||||
| 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/ | ||||
|  | ||||
							
								
								
									
										188
									
								
								mods/fire/init.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								mods/fire/init.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -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, | ||||
| }) | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								mods/fire/sounds/fire_large.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								mods/fire/sounds/fire_large.ogg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								mods/fire/sounds/fire_small.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								mods/fire/sounds/fire_small.ogg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								mods/fire/textures/fire_basic_flame.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								mods/fire/textures/fire_basic_flame.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 847 B | 
		Reference in New Issue
	
	Block a user