1 local minetest,math,vector = minetest,math,vector
2 minetest.register_node("fire:fire", {
9 type = "vertical_frames",
16 --inventory_image = "fire.png",
17 groups = {dig_immediate = 1,fire=1,hurt_inside=1},
18 sounds = main.stoneSound(),
22 is_ground_content = false,
23 light_source = 11, --debugging
24 on_construct = function(pos)
25 local under = minetest.get_node(vector.new(pos.x,pos.y-1,pos.z)).name
27 if under == "nether:obsidian" then
28 minetest.remove_node(pos)
29 create_nether_portal(pos)
30 --fire lasts forever on netherrack
31 elseif under ~= "nether:netherrack" then
32 local timer = minetest.get_node_timer(pos)
33 timer:start(math.random(0,2)+math.random())
36 on_timer = function(pos, elapsed)
37 local find_flammable = minetest.find_nodes_in_area(vector.subtract(pos,1), vector.add(pos,1), {"group:flammable"})
38 --print(dump(find_flammable))
40 for _,p_pos in pairs(find_flammable) do
41 if math.random() > 0.9 then
42 minetest.set_node(p_pos,{name="fire:fire"})
43 local timer = minetest.get_node_timer(p_pos)
44 timer:start(math.random(0,2)+math.random())
48 if math.random() > 0.85 then
49 minetest.remove_node(pos)
51 local timer = minetest.get_node_timer(pos)
52 timer:start(math.random(0,2)+math.random())
58 minetest.register_tool("fire:flint_and_steel", {
59 description = "Flint and Steel",
60 inventory_image = "flint_and_steel.png",
61 on_place = function(itemstack, placer, pointed_thing)
62 if pointed_thing.type ~= "node" then
65 if minetest.get_node(pointed_thing.above).name ~= "air" then
66 minetest.sound_play("flint_failed", {pos=pointed_thing.above})
70 --can't make fire in the aether
71 if pointed_thing.above.y >= 20000 then
72 minetest.sound_play("flint_failed", {pos=pointed_thing.above,pitch=math.random(75,95)/100})
76 minetest.add_node(pointed_thing.above,{name="fire:fire"})
77 minetest.sound_play("flint_and_steel", {pos=pointed_thing.above})
78 itemstack:add_wear(100)
83 _namespace_reserved = {times={[1]=5555}, uses=0, maxlevel=1},
87 sound = {breaks = {name="tool_break",gain=0.4}},
90 minetest.register_craft({
92 output = "fire:flint_and_steel",
93 recipe = {"main:flint","main:iron"},
101 fire.initial_properties = {
104 collide_with_objects = false,
105 collisionbox = {0, 0, 0, 0, 0, 0},
107 textures = {"nothing.png","nothing.png","fire.png","fire.png","fire.png","fire.png"},
108 visual_size = {x = 1, y = 1, z = 1},
109 --textures = {"nothing.png","nothing.png","fire.png","fire.png","fire.png","fire.png"},--, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=8.0}},
114 fire.on_activate = function(self)
115 local texture_list = {
118 "fire.png^[opacity:180^[verticalframe:8:0",
119 "fire.png^[opacity:180^[verticalframe:8:0",
120 "fire.png^[opacity:180^[verticalframe:8:0",
121 "fire.png^[opacity:180^[verticalframe:8:0",
123 self.object:set_properties({textures=texture_list})
128 fire.frame_update = function(self)
129 self.frame = self.frame + 1
130 if self.frame > 7 then
133 local texture_list = {
136 "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
137 "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
138 "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
139 "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
141 self.object:set_properties({textures=texture_list})
146 fire.on_step = function(self,dtime)
147 --master is the flag of the entity that controls the hurt
148 --owner is the flag that tells the entity who to hurt
149 if self.owner and (self.owner:is_player() or self.owner:get_luaentity()) then
151 self.timer = self.timer + dtime
152 self.life = self.life + dtime
154 if self.life >= 7 then
155 put_fire_out(self.owner)
160 if self.timer >= 1 then
162 if self.owner:is_player() then
163 self.owner:set_hp(self.owner:get_hp()-1)
164 elseif self.owner and self.owner:get_luaentity() then
165 self.owner:punch(self.object, 2,
167 full_punch_interval=0,
168 damage_groups = {damage=2},
176 self.frame_timer = self.frame_timer + dtime
177 if self.frame_timer >= 0.015 then
179 self.frame_update(self)
182 minetest.register_entity("fire:fire",fire)
186 --this is the handling part
188 local fire_channels = {}
190 minetest.register_on_joinplayer(function(player)
191 local name = player:get_player_name()
192 fire_channels[name] = minetest.mod_channel_join(name..":fire_state")
194 minetest.after(4,function()
195 if not player:is_player() then return end
196 local meta = player:get_meta()
197 if meta:get_int("on_fire") > 0 then
203 function start_fire(object)
204 if object:is_player() then
205 local name = object:get_player_name()
206 if not fire_table[name] then
207 local obj = minetest.add_entity(object:get_pos(),"fire:fire")
208 obj:get_luaentity().master = true
209 obj:get_luaentity().owner = object
210 obj:set_attach(object, "", vector.new(0,11,0),vector.new(0,0,0))
211 obj:set_properties({visual_size=vector.new(1,2,1)})
212 fire_table[name] = obj
214 local meta = object:get_meta()
215 fire_channels[name]:send_all("1")
216 meta:set_int("on_fire", 1)
218 elseif object and object:get_luaentity() then
219 object:get_luaentity().on_fire = true
220 local divisor = object:get_properties().visual_size.y
221 local obj = minetest.add_entity(object:get_pos(),"fire:fire")
223 obj:get_luaentity().master = true
224 obj:get_luaentity().owner = object
226 local fire_table = object:get_luaentity().fire_table
227 obj:set_attach(object, "", fire_table.position,vector.new(0,0,0))
228 obj:set_properties({visual_size=fire_table.visual_size})
230 object:get_luaentity().fire_entity = obj
234 function put_fire_out(object)
235 if object:is_player() then
236 local name = object:get_player_name()
237 if fire_table[name] then
238 local obj = fire_table[name]
239 if obj:get_luaentity() then
242 fire_table[name] = nil
244 local meta = object:get_meta()
245 fire_channels[name]:send_all("0")
246 meta:set_int("on_fire", 0)
248 elseif object and object:get_luaentity() then
249 object:get_luaentity().on_fire = false
250 object:get_luaentity().fire_entity = nil
254 minetest.register_on_respawnplayer(function(player)