]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/fire/init.lua
Fix repeated player death when in lava or fire
[Crafter.git] / mods / fire / init.lua
index c69d871f51c33db69b74a5f557ddc7143f61b2b0..6ce93d12fddd892b1ed73fbfa867518f0b56168e 100644 (file)
@@ -1,3 +1,4 @@
+local minetest,math,vector = minetest,math,vector
 minetest.register_node("fire:fire", {
     description = "Fire",
     drawtype = "firelike",
@@ -12,8 +13,8 @@ minetest.register_node("fire:fire", {
                        },
                },
        },
-       inventory_image = "fire.png",
-    groups = {dig_immediate = 1,fire=1},
+       --inventory_image = "fire.png",
+    groups = {dig_immediate = 1,fire=1,hurt_inside=1},
     sounds = main.stoneSound(),
     floodable = true,
     drop = "",
@@ -92,72 +93,169 @@ minetest.register_craft({
        recipe = {"main:flint","main:iron"},
 })
 
+----------------------------------------------------------------------------------------------------------------------------------------
 
-fire_table = {}
-
+--fire object
 local fire = {}
-
 fire.initial_properties = {
        hp_max = 1,
        physical = false,
        collide_with_objects = false,
-       collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2},
-       visual = "sprite",
+       collisionbox = {0, 0, 0, 0, 0, 0},
+       visual = "cube",
+       textures = {"nothing.png","nothing.png","fire.png","fire.png","fire.png","fire.png"},
        visual_size = {x = 1, y = 1, z = 1},
-       textures = {name="fire.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=8.0}},
-       spritediv = {x = 1, y = 8},
-       initial_sprite_basepos = {x = 0, y = 0},
+       --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}},
        is_visible = true,
        pointable = false,
 }
 
 fire.on_activate = function(self)
-       self.object:set_sprite({x=1,y=math.random(1,8)}, 8, 0.05, false)
+       local texture_list = {
+               "nothing.png",
+               "nothing.png",
+               "fire.png^[opacity:180^[verticalframe:8:0",
+               "fire.png^[opacity:180^[verticalframe:8:0",
+               "fire.png^[opacity:180^[verticalframe:8:0",
+               "fire.png^[opacity:180^[verticalframe:8:0",
+       }
+       self.object:set_properties({textures=texture_list})
 end
-fire.timer = 0
-fire.on_step = function(self,dtime)
-       if not self.player or (self.player and not self.player:is_player()) then
-               self.object:remove()
+--animation stuff
+fire.frame = 0
+fire.frame_timer = 0
+fire.frame_update = function(self)
+       self.frame = self.frame + 1
+       if self.frame > 7 then
+               self.frame = 0
        end
-       if self.master then
+       local texture_list = {
+               "nothing.png",
+               "nothing.png",
+               "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
+               "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
+               "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
+               "fire.png^[opacity:180^[verticalframe:8:"..self.frame,
+       }
+       self.object:set_properties({textures=texture_list})
+end
+fire.glow = -1
+fire.timer = 0
+fire.life = 0
+fire.on_step = function(self,dtime)    
+       if self.owner and (self.owner:is_player() or self.owner:get_luaentity()) then
+               if self.owner:is_player() and self.owner:get_hp() <= 0 then
+                       put_fire_out(self.owner)
+               end
                self.timer = self.timer + dtime
-               if self.timer >= 0.5 then
+               self.life = self.life + dtime
+               if self.life >= 7 then
+                       put_fire_out(self.owner)
+                       self.object:remove()
+                       return
+               end
+               
+               if self.timer >= 1 then
                        self.timer = 0
-                       self.player:set_hp(self.player:get_hp()-1)
+                       if self.owner:is_player() then
+                               self.owner:set_hp(self.owner:get_hp()-1)
+                       elseif self.owner:get_luaentity() then
+                               self.owner:punch(self.object, 2, 
+                                       {
+                                       full_punch_interval=0,
+                                       damage_groups = {damage=2},
+                               })
+                       end
                end
+       else
+               self.object:remove()
+       end
+       self.frame_timer = self.frame_timer + dtime
+       if self.frame_timer >= 0.015 then
+               self.frame_timer = 0
+               self.frame_update(self)
        end
 end
 minetest.register_entity("fire:fire",fire)
 
-function start_fire(player)
-       local name = player:get_player_name()
-       if not fire_table[name] then
-               local object_table = {}
-               for i = 1,3 do
-                       local obj = minetest.add_entity(player:get_pos(),"fire:fire")
-                       if i == 1 then
-                               obj:get_luaentity().master = true
-                       end
-                       obj:get_luaentity().player = player
-                       obj:set_attach(player, "", vector.new(0,i*5,0),vector.new(0,0,0))
-                       table.insert(object_table,obj)
+
+--fire handling
+
+local pool = {}
+
+local fire_channels = {}
+
+local name
+minetest.register_on_joinplayer(function(player)
+       name = player:get_player_name()
+       fire_channels[name] = minetest.mod_channel_join(name..":fire_state")
+end)
+
+local name
+function is_player_on_fire(player)
+       return(pool[player:get_player_name()] ~= nil)
+end
+
+function is_entity_on_fire(object)
+       return(pool[object] ~= nil)
+end
+
+local name
+local fire_obj
+function start_fire(object)
+       if object:is_player() then
+               name = object:get_player_name()
+               if not pool[name] or pool[name] and not pool[name]:get_luaentity() then
+                       fire_obj = minetest.add_entity(object:get_pos(),"fire:fire")
+                       fire_obj:get_luaentity().owner = object
+                       fire_obj:set_attach(object, "", vector.new(0,11,0),vector.new(0,0,0))
+                       fire_obj:set_properties({visual_size=vector.new(1,2,1)})
+                       pool[name] = fire_obj
+                       fire_channels[name]:send_all("1")
+               elseif pool[name]:get_luaentity() then
+                       pool[name]:get_luaentity().life = 0
+               end
+       elseif object and object:get_luaentity() then
+               if not object:get_luaentity().fire_entity or
+       object:get_luaentity().fire_entity and not object:get_luaentity().fire_entity:get_luaentity() then
+                       object:get_luaentity().on_fire = true
+
+                       fire_obj = minetest.add_entity(object:get_pos(),"fire:fire")
+                       fire_obj:get_luaentity().owner = object
+
+                       local entity_fire_def = object:get_luaentity().fire_table
+                       fire_obj:set_attach(object, "", entity_fire_def.position,vector.new(0,0,0))
+                       fire_obj:set_properties({visual_size=entity_fire_def.visual_size})
+
+                       object:get_luaentity().fire_entity = fire_obj
+               else
+                       object:get_luaentity().fire_entity:get_luaentity().life = 0
                end
-               fire_table[name] = object_table
-               local meta = player:get_meta()
-               meta:set_int("on_fire", 1)
        end
 end
 
-function put_fire_out(player)
-       local name = player:get_player_name()
-       if fire_table[name] then
-               for _,object in pairs(fire_table[name]) do
-                       object:remove()
+local name
+local fire_obj
+function put_fire_out(object)
+       if object:is_player() then
+               name = object:get_player_name()
+               if pool[name] then
+                       fire_obj = pool[name]
+                       if fire_obj:get_luaentity() then
+                               fire_obj:remove()
+                       end
+                       pool[name] = nil
+                       fire_channels[name]:send_all("0")
+                       minetest.sound_play("fire_extinguish", {object=object,gain=0.3,pitch=math.random(80,100)/100})
                end
-               fire_table[name] = nil
-
-               local meta = player:get_meta()
-               meta:set_int("on_fire", 0)
+       elseif object and object:get_luaentity() then
+               if object:get_luaentity().fire_entity and object:get_luaentity().fire_entity:get_luaentity() then
+                       object:get_luaentity().fire_entity:remove()
+               end
+               object:get_luaentity().on_fire = false
+               object:get_luaentity().fire_entity = nil
+               
+               --minetest.sound_play("fire_extinguish", {object=object,gain=0.3,pitch=math.random(80,100)/100})
        end
 end