From df5d24104dde611534da8d2cb096c32c6043c60e Mon Sep 17 00:00:00 2001 From: kabou Date: Wed, 2 Mar 2022 14:57:20 +0100 Subject: [PATCH] Make player burning HUD work without csm. * Add update_hud() function. * Remove the client channels. * Unglobalize animation_frames variable. * Fix bug where player state was not stored on shutdown of singleplayer game. * Remove superfluous sanity_check() function, this code could easily be inlined in its only caller. --- mods/ENTITIES/mcl_burning/api.lua | 30 +++++++++++-- mods/ENTITIES/mcl_burning/init.lua | 68 ++++++++++++++++-------------- 2 files changed, 63 insertions(+), 35 deletions(-) diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 969985205..5890d8892 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -33,6 +33,29 @@ function mcl_burning.get_touching_nodes(obj, nodenames, storage) return nodes end +function mcl_burning.update_hud(player) + local animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 + local hud_flame_animated = "mcl_burning_hud_flame_animated.png^[opacity:180^[verticalframe:" .. animation_frames .. ":" + + local storage = mcl_burning.get_storage(player) + if not storage.fire_hud_id then + storage.animation_frame = 1 + storage.fire_hud_id = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -100, y = -100}, + text = hud_flame_animated .. storage.animation_frame, + z_index = 1000, + }) + else + storage.animation_frame = storage.animation_frame + 1 + if storage.animation_frame > animation_frames - 1 then + storage.animation_frame = 0 + end + player:hud_change(storage.fire_hud_id, "text", hud_flame_animated .. storage.animation_frame) + end +end + function mcl_burning.set_on_fire(obj, burn_time) if obj:get_hp() < 0 then return @@ -68,8 +91,7 @@ function mcl_burning.set_on_fire(obj, burn_time) if not storage.burn_time or burn_time >= storage.burn_time then if obj:is_player() then - mcl_burning.channels[obj]:send_all(tostring(mcl_burning.animation_frames)) - mcl_burning.channels[obj]:send_all("start") + mcl_burning.update_hud(obj) end storage.burn_time = burn_time storage.fire_damage_timer = 0 @@ -105,7 +127,9 @@ function mcl_burning.extinguish(obj) if mcl_burning.is_burning(obj) then local storage = mcl_burning.get_storage(obj) if obj:is_player() then - mcl_burning.channels[obj]:send_all("stop") + if storage.fire_hud_id then + obj:hud_remove(storage.fire_hud_id) + end mcl_burning.storage[obj] = {} else storage.burn_time = nil diff --git a/mods/ENTITIES/mcl_burning/init.lua b/mods/ENTITIES/mcl_burning/init.lua index cc82527cc..82410dfdd 100644 --- a/mods/ENTITIES/mcl_burning/init.lua +++ b/mods/ENTITIES/mcl_burning/init.lua @@ -1,14 +1,11 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) local pairs = pairs - local get_connected_players = minetest.get_connected_players local get_item_group = minetest.get_item_group mcl_burning = { - storage = {}, - channels = {}, - animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 + storage = {} } dofile(modpath .. "/api.lua") @@ -44,25 +41,33 @@ minetest.register_on_respawnplayer(function(player) mcl_burning.extinguish(player) end) -function mcl_burning.init_player(player) - local meta = player:get_meta() - -- NOTE: mcl_burning:data may be "return nil" (which deserialize into nil) for reasons unknown. - if meta:get_string("mcl_burning:data"):find("return nil", 1, true) then - minetest.log("warning", "[mcl_burning] 'mcl_burning:data' player meta field is invalid! Please report this bug") +minetest.register_on_joinplayer(function(player) + local storage = {} + local burn_data = player:get_meta():get_string("mcl_burning:data") + if burn_data ~= "" then + storage = minetest.deserialize(burn_data) end - mcl_burning.storage[player] = meta:contains("mcl_burning:data") and minetest.deserialize(meta:get_string("mcl_burning:data")) or {} - mcl_burning.channels[player] = minetest.mod_channel_join("mcl_burning:" .. player:get_player_name()) + mcl_burning.storage[player] = storage +end) + +local function on_leaveplayer(player) + local storage = mcl_burning.storage[player] + storage.fire_hud_id = nil + player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage)) + mcl_burning.storage[player] = nil end -minetest.register_on_joinplayer(function(player) - mcl_burning.init_player(player) -end) - minetest.register_on_leaveplayer(function(player) - player:get_meta():set_string("mcl_burning:data", minetest.serialize(mcl_burning.storage[player])) - mcl_burning.storage[player] = nil + on_leaveplayer(player) end) +minetest.register_on_shutdown(function() + for _,player in ipairs(minetest.get_connected_players()) do + on_leaveplayer(player) + end +end) + +local animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 minetest.register_entity("mcl_burning:fire", { initial_properties = { @@ -73,7 +78,7 @@ minetest.register_entity("mcl_burning:fire", { "mcl_burning_entity_flame_animated.png", "mcl_burning_entity_flame_animated.png" }, - spritediv = {x = 1, y = mcl_burning.animation_frames}, + spritediv = {x = 1, y = animation_frames}, pointable = false, glow = -1, backface_culling = false, @@ -81,26 +86,25 @@ minetest.register_entity("mcl_burning:fire", { animation_frame = 0, animation_timer = 0, on_activate = function(self) - self.object:set_sprite({x = 0, y = 0}, mcl_burning.animation_frames, 1.0 / mcl_burning.animation_frames) + self.object:set_sprite({x = 0, y = 0}, animation_frames, 1.0 / animation_frames) end, - on_step = function(self) - if not self:sanity_check() then - self.object:remove() - end - end, - sanity_check = function(self) + on_step = function(self, dtime) local parent = self.object:get_attach() - if not parent then - return false + self.object:remove() + return end - local storage = mcl_burning.get_storage(parent) - if not storage or not storage.burn_time then - return false + self.object:remove() + return + end + if parent:is_player() then + self.animation_timer = self.animation_timer + dtime + if self.animation_timer >= 0.1 then + self.animation_timer = 0 + mcl_burning.update_hud(parent) + end end - - return true end, })