From e80006f4eaa4cdf7e5e65b47bfdba5c7c64c7c11 Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 2 Mar 2022 16:10:55 +0100 Subject: [PATCH] Do not set fire to objects that are already burning. Changes to mcl_burning.set_on_fire(): * Add logic that only updates the burn time, but skips adding fire entities to objects that are already burning. * Condense code a little, remove single use variables. * Add a comment to a questionable piece of code. * Add comments to the function. --- mods/ENTITIES/mcl_burning/api.lua | 67 ++++++++++++++++++------------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 8cdeb8b942..8cfdded7ef 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -58,13 +58,24 @@ function mcl_burning.update_hud(player) end end +-- Sets and object state as burning and adds a fire animation to the object. +-- +-- Parameters: +-- obj - may be a player or a lua_entity; +-- burn_time - sets the object's burn duration; +-- +-- If obj is a player, adds a fire animation to the HUD, if obj is a +-- lua_entity, adds an animated fire entity to obj. +-- The effective burn duration is modified by obj's armor protection. +-- If obj was already burning, its burn duration is updated if the current +-- duration is less than burn_time. +-- If obj is dead, fireproof or a creative player, this function does nothing. +-- function mcl_burning.set_on_fire(obj, burn_time) if obj:get_hp() < 0 then return end - local storage = mcl_burning.get_storage(obj) - local luaentity = obj:get_luaentity() if luaentity and luaentity.fire_resistant then return @@ -85,42 +96,42 @@ function mcl_burning.set_on_fire(obj, burn_time) end end end - if max_fire_prot_lvl > 0 then burn_time = burn_time - math.floor(burn_time * max_fire_prot_lvl * 0.15) end end - if not storage.burn_time or burn_time >= storage.burn_time then - if obj:is_player() then - mcl_burning.update_hud(obj) + local storage = mcl_burning.get_storage(obj) + if storage.burn_time then + if burn_time > storage.burn_time then + storage.burn_time = burn_time end - storage.burn_time = burn_time - storage.fire_damage_timer = 0 + return + end + storage.burn_time = burn_time + storage.fire_damage_timer = 0 - local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") - local minp, maxp = mcl_burning.get_collisionbox(obj, false, storage) - local obj_size = obj:get_properties().visual_size + local minp, maxp = mcl_burning.get_collisionbox(obj, false, storage) + local size = vector.subtract(maxp, minp) + size = vector.multiply(size, vector.new(1.1, 1.2, 1.1)) + size = vector.divide(size, obj:get_properties().visual_size) - local vertical_grow_factor = 1.2 - local horizontal_grow_factor = 1.1 - local grow_vector = vector.new(horizontal_grow_factor, vertical_grow_factor, horizontal_grow_factor) + local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") + fire_entity:set_properties({visual_size = size}) + fire_entity:set_attach(obj, "", vector.new(0, size.y * 5, 0), vector.new(0, 0, 0)) - local size = vector.subtract(maxp, minp) - size = vector.multiply(size, grow_vector) - size = vector.divide(size, obj_size) - local offset = vector.new(0, size.y * 10 / 2, 0) + if obj:is_player() then + mcl_burning.update_hud(obj) + end - fire_entity:set_properties({visual_size = size}) - fire_entity:set_attach(obj, "", offset, {x = 0, y = 0, z = 0}) - local fire_luaentity = fire_entity:get_luaentity() - - for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do - local other_luaentity = other:get_luaentity() - if other_luaentity and other_luaentity.name == "mcl_burning:fire" and other_luaentity ~= fire_luaentity then - other:remove() - break - end + -- FIXME: does this code make sense? It removes attached fire luaentities from + -- another object that happen to be at the same position. + local fire_luaentity = fire_entity:get_luaentity() + for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do + local other_luaentity = other:get_luaentity() + if other_luaentity and other_luaentity.name == "mcl_burning:fire" and other_luaentity ~= fire_luaentity then + other:remove() + break end end end