From 42483d14f4b03e9e5e56dc4b03dcdd6bc0d2afe8 Mon Sep 17 00:00:00 2001 From: oilboi <47129783+oilboi@users.noreply.github.com> Date: Tue, 9 Jun 2020 10:41:57 -0400 Subject: [PATCH] Overhaul fire --- README.md | 1 + mods/fire/init.lua | 165 ++++++++++++++++++++++----------- mods/mob/api/api_hook.lua | 4 + mods/mob/api/data_handling.lua | 7 +- mods/mob/api/interaction.lua | 10 ++ mods/mob/api/movement.lua | 2 +- mods/mob/init.lua | 73 ++++++++++++++- 7 files changed, 203 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 5377c97..0f11315 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ enable_mod_channels = true - Added in capes - Overhauled client mod version checking - Overhauled mob pathfinding AI +- Overhauled fire --- diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 31c4e13..1fead38 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -12,7 +12,7 @@ minetest.register_node("fire:fire", { }, }, }, - inventory_image = "fire.png", + --inventory_image = "fire.png", groups = {dig_immediate = 1,fire=1,hurt_inside=1}, sounds = main.stoneSound(), floodable = true, @@ -101,36 +101,81 @@ 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 +--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 + 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.timer = 0 fire.life = 0 -fire.on_step = function(self,dtime) - if not self.player or (self.player and not self.player:is_player()) then +fire.on_step = function(self,dtime) + --master is the flag of the entity that controls the hurt + --owner is the flag that tells the entity who to hurt + if self.owner and (self.owner:is_player() or self.owner:get_luaentity()) then + if self.master then + self.timer = self.timer + dtime + 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 + if self.owner:is_player() then + self.owner:set_hp(self.owner:get_hp()-1) + elseif self.owner and self.owner:get_luaentity() then + self.owner:punch(self.object, 2, + { + full_punch_interval=0, + damage_groups = {damage=2}, + }) + end + end + end + else self.object:remove() end - if self.master then - self.timer = self.timer + dtime - self.life = self.life + dtime - if self.life >= 7 then - put_fire_out(self.master) - return - end - if self.timer >= 1 then - self.timer = 0 - self.player:set_hp(self.player:get_hp()-1) - 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) @@ -145,46 +190,62 @@ minetest.register_on_joinplayer(function(player) local name = player:get_player_name() fire_channels[name] = minetest.mod_channel_join(name..":fire_state") - local meta = player:get_meta() - if meta:get_int("on_fire") > 0 then - minetest.after(2,function() + minetest.after(4,function() + local meta = player:get_meta() + if meta:get_int("on_fire") > 0 then start_fire(player) - end) - end + end + end) end) -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 = player - 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) +function start_fire(object) + if object:is_player() then + local name = object:get_player_name() + if not fire_table[name] then + local obj = minetest.add_entity(object:get_pos(),"fire:fire") + obj:get_luaentity().master = true + obj:get_luaentity().owner = object + obj:set_attach(object, "", vector.new(0,11,0),vector.new(0,0,0)) + obj:set_properties({visual_size=vector.new(1,2,1)}) + fire_table[name] = obj + + local meta = object:get_meta() + fire_channels[name]:send_all("1") + meta:set_int("on_fire", 1) end - fire_table[name] = object_table - local meta = player:get_meta() - - fire_channels[name]:send_all("1") - meta:set_int("on_fire", 1) + elseif object and object:get_luaentity() then + object:get_luaentity().on_fire = true + local divisor = object:get_properties().visual_size.y + local obj = minetest.add_entity(object:get_pos(),"fire:fire") + --obj:set_properties + obj:get_luaentity().master = true + obj:get_luaentity().owner = object + + local fire_table = object:get_luaentity().fire_table + obj:set_attach(object, "", fire_table.position,vector.new(0,0,0)) + obj:set_properties({visual_size=fire_table.visual_size}) + + object:get_luaentity().fire_entity = obj 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() - end - fire_table[name] = nil +function put_fire_out(object) + if object:is_player() then + local name = object:get_player_name() + if fire_table[name] then + local obj = fire_table[name] + if obj:get_luaentity() then + obj:remove() + end + fire_table[name] = nil - local meta = player:get_meta() - fire_channels[name]:send_all("0") - meta:set_int("on_fire", 0) + local meta = object:get_meta() + fire_channels[name]:send_all("0") + meta:set_int("on_fire", 0) + end + elseif object and object:get_luaentity() then + object:get_luaentity().on_fire = false + object:get_luaentity().fire_entity = nil end end diff --git a/mods/mob/api/api_hook.lua b/mods/mob/api/api_hook.lua index e3cca77..d1e1e94 100644 --- a/mods/mob/api/api_hook.lua +++ b/mods/mob/api/api_hook.lua @@ -139,6 +139,10 @@ mob_register.c_mob_data = def.c_mob_data mob_register.deactivating = false +mob_register.on_fire = false + +mob_register.fire_table = def.fire_table + if def.pathfinds then --mob_register.path = {} mob_register.pathfinding_timer = 0 diff --git a/mods/mob/api/data_handling.lua b/mods/mob/api/data_handling.lua index 2a92786..e40d0fd 100644 --- a/mods/mob/api/data_handling.lua +++ b/mods/mob/api/data_handling.lua @@ -29,6 +29,7 @@ mobs.create_data_handling_functions = function(def,mob_register) scared = self.scared, scared_timer = self.scared_timer, c_mob_data = self.c_mob_data, + on_fire = self.on_fire, }) end @@ -55,6 +56,7 @@ mobs.create_data_handling_functions = function(def,mob_register) self.scared = data.scared self.scared_timer = data.scared_timer self.c_mob_data = data.c_mob_data + self.on_fire = data.on_fire end end @@ -75,7 +77,10 @@ mobs.create_data_handling_functions = function(def,mob_register) if self.custom_on_activate then self.custom_on_activate(self) end - --self.object:set_yaw(math.pi*math.random(-1,1)*math.random()) + + if self.on_fire == true then + start_fire(self.object) + end --use this to handle the global mob table minetest.after(0,function() diff --git a/mods/mob/api/interaction.lua b/mods/mob/api/interaction.lua index 06b1702..dfe54ec 100644 --- a/mods/mob/api/interaction.lua +++ b/mods/mob/api/interaction.lua @@ -94,8 +94,14 @@ mobs.create_interaction_functions = function(def,mob_register) if object:is_player() then object:add_player_velocity(vel2) + if self.on_fire then + start_fire(object) + end else object:add_velocity(vel2) + if self.on_fire and not object:get_luaentity().on_fire then + start_fire(object) + end end end end @@ -330,6 +336,10 @@ mobs.create_interaction_functions = function(def,mob_register) full_punch_interval=1.5, damage_groups = {damage=self.attack_damage}, },vector.direction(pos,pos2)) + --light the player on fire + if self.on_fire then + start_fire(object) + end end end end diff --git a/mods/mob/api/movement.lua b/mods/mob/api/movement.lua index 09786ba..97ae747 100644 --- a/mods/mob/api/movement.lua +++ b/mods/mob/api/movement.lua @@ -36,7 +36,7 @@ mobs.create_movement_functions = function(def,mob_register) }) end local firey = get_group(noder, "fire") - if firey > 0 then + if not self.on_fire and firey > 0 then start_fire(self.object) end self.hurt_inside_timer = 0.25 diff --git a/mods/mob/init.lua b/mods/mob/init.lua index bbeb7cf..8676235 100644 --- a/mods/mob/init.lua +++ b/mods/mob/init.lua @@ -67,9 +67,15 @@ mobs.register_mob( attacked_hostile = false, attack_type = "punch", group_attack = true, + + --explosion_radius = 4, -- how far away the mob has to be to initialize the explosion --explosion_power = 7, -- how big the explosion has to be --explosion_time = 3, -- how long it takes for a mob to explode + fire_table = { + visual_size = vector.new(1/3,2/3,1/3), + position = vector.new(0,3,0), + } } ) @@ -147,8 +153,13 @@ mobs.register_mob( pos.y = pos.y + 0.5 minetest.throw_item(pos,{name="weather:snow_block"}) end - end + end, + fire_table = { + visual_size = vector.new(1/3,2/3,1/3), + position = vector.new(0,3,0), } + } + ) mobs.register_mob( @@ -212,6 +223,10 @@ mobs.register_mob( --explosion_radius = 4, -- how far away the mob has to be to initialize the explosion --explosion_power = 7, -- how big the explosion has to be --explosion_time = 3, -- how long it takes for a mob to explode + fire_table = { + visual_size = vector.new(1/6,1/2.2,1/6), + position = vector.new(0,2.3,0), + } } ) @@ -295,6 +310,10 @@ mobs.register_mob( }) end end, + fire_table = { + visual_size = vector.new(1/4,2/3,1/4), + position = vector.new(0,3.3,0), + } } ) @@ -362,6 +381,10 @@ mobs.register_mob( --explosion_radius = 4, -- how far away the mob has to be to initialize the explosion --explosion_power = 7, -- how big the explosion has to be --explosion_time = 3, -- how long it takes for a mob to explode + fire_table = { + visual_size = vector.new(1/3,2/3,1/3), + position = vector.new(0,3,0), + } } ) @@ -400,9 +423,17 @@ mobs.register_mob( custom_on_death = function(self) local pos = self.object:get_pos() for i = 1,4 do - minetest.add_entity(pos,"mob:medium_slime") + local obj = minetest.add_entity(pos,"mob:medium_slime") + if self.on_fire then + start_fire(obj) + end end end, + --this is used to properly position fire when the mob catches on fire + fire_table = { + visual_size = vector.new(1/5.8,1/3.3,1/5.8), + position = vector.new(0,1.5,0), + } } ) @@ -440,9 +471,16 @@ mobs.register_mob( local pos = self.object:get_pos() pos.y = pos.y + 0.2 for i = 1,4 do - minetest.add_entity(pos,"mob:small_slime") + local obj = minetest.add_entity(pos,"mob:small_slime") + if self.on_fire then + start_fire(obj) + end end end, + fire_table = { + visual_size = vector.new(1/5.8,1/3.3,1/5.8), + position = vector.new(0,1.5,0), + } } ) @@ -476,7 +514,11 @@ mobs.register_mob( die_sound = "slime_die", attack_damage = 1, attack_type = "punch", - item_drop = "mob:slimeball" + item_drop = "mob:slimeball", + fire_table = { + visual_size = vector.new(1/5.8,1/3.3,1/5.8), + position = vector.new(0,1.5,0), + } } ) @@ -602,6 +644,10 @@ mobs.register_mob( die_in_light = false, --die_in_light_level = 12, + fire_table = { + visual_size = vector.new(1/4,2/3,1/4), + position = vector.new(0,3.3,0), + } } ) @@ -668,6 +714,10 @@ mobs.register_mob( die_in_light = false, --die_in_light_level = 12, + fire_table = { + visual_size = vector.new(1/4,2/3,1/4), + position = vector.new(0,3.3,0), + } } ) @@ -736,6 +786,10 @@ mobs.register_mob( die_in_light = false, --die_in_light_level = 12, + fire_table = { + visual_size = vector.new(1/4,2/3,1/4), + position = vector.new(0,3.3,0), + } } ) @@ -838,10 +892,15 @@ mobs.register_mob( obj:set_properties({visual_size={x=1,y=1}}) obj2:set_properties({visual_size={x=1/3,y=1/3}}) end - end + end, --explosion_radius = 4, -- how far away the mob has to be to initialize the explosion --explosion_power = 7, -- how big the explosion has to be --explosion_time = 3, -- how long it takes for a mob to explode + --this is used to properly position fire when the mob catches on fire + fire_table = { + visual_size = vector.new(1.3/3,2/3,1.3/3), + position = vector.new(0,4,0), + } } ) @@ -907,5 +966,9 @@ mobs.register_mob( --explosion_radius = 4, -- how far away the mob has to be to initialize the explosion --explosion_power = 7, -- how big the explosion has to be --explosion_time = 3, -- how long it takes for a mob to explode + fire_table = { + visual_size = vector.new(1.3/3,2/3,1.3/3), + position = vector.new(0,4,0), + } } ) -- 2.44.0