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.
This commit is contained in:
kabou 2022-03-02 14:57:20 +01:00 committed by cora
parent 3f1247d4cf
commit ed9a403d78
2 changed files with 63 additions and 35 deletions

View File

@ -33,6 +33,29 @@ function mcl_burning.get_touching_nodes(obj, nodenames, storage)
return nodes return nodes
end 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) function mcl_burning.set_on_fire(obj, burn_time)
if obj:get_hp() < 0 then if obj:get_hp() < 0 then
return 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 not storage.burn_time or burn_time >= storage.burn_time then
if obj:is_player() then if obj:is_player() then
mcl_burning.channels[obj]:send_all(tostring(mcl_burning.animation_frames)) mcl_burning.update_hud(obj)
mcl_burning.channels[obj]:send_all("start")
end end
storage.burn_time = burn_time storage.burn_time = burn_time
storage.fire_damage_timer = 0 storage.fire_damage_timer = 0
@ -105,7 +127,9 @@ function mcl_burning.extinguish(obj)
if mcl_burning.is_burning(obj) then if mcl_burning.is_burning(obj) then
local storage = mcl_burning.get_storage(obj) local storage = mcl_burning.get_storage(obj)
if obj:is_player() then 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] = {} mcl_burning.storage[obj] = {}
else else
storage.burn_time = nil storage.burn_time = nil

View File

@ -1,14 +1,11 @@
local modpath = minetest.get_modpath(minetest.get_current_modname()) local modpath = minetest.get_modpath(minetest.get_current_modname())
local pairs = pairs local pairs = pairs
local get_connected_players = minetest.get_connected_players local get_connected_players = minetest.get_connected_players
local get_item_group = minetest.get_item_group local get_item_group = minetest.get_item_group
mcl_burning = { mcl_burning = {
storage = {}, storage = {}
channels = {},
animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
} }
dofile(modpath .. "/api.lua") dofile(modpath .. "/api.lua")
@ -44,25 +41,33 @@ minetest.register_on_respawnplayer(function(player)
mcl_burning.extinguish(player) mcl_burning.extinguish(player)
end) end)
function mcl_burning.init_player(player) minetest.register_on_joinplayer(function(player)
local meta = player:get_meta() local storage = {}
-- NOTE: mcl_burning:data may be "return nil" (which deserialize into nil) for reasons unknown. local burn_data = player:get_meta():get_string("mcl_burning:data")
if meta:get_string("mcl_burning:data"):find("return nil", 1, true) then if burn_data ~= "" then
minetest.log("warning", "[mcl_burning] 'mcl_burning:data' player meta field is invalid! Please report this bug") storage = minetest.deserialize(burn_data)
end end
mcl_burning.storage[player] = meta:contains("mcl_burning:data") and minetest.deserialize(meta:get_string("mcl_burning:data")) or {} mcl_burning.storage[player] = storage
mcl_burning.channels[player] = minetest.mod_channel_join("mcl_burning:" .. player:get_player_name()) 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 end
minetest.register_on_joinplayer(function(player)
mcl_burning.init_player(player)
end)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
player:get_meta():set_string("mcl_burning:data", minetest.serialize(mcl_burning.storage[player])) on_leaveplayer(player)
mcl_burning.storage[player] = nil
end) 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", { minetest.register_entity("mcl_burning:fire", {
initial_properties = { initial_properties = {
@ -73,7 +78,7 @@ minetest.register_entity("mcl_burning:fire", {
"mcl_burning_entity_flame_animated.png", "mcl_burning_entity_flame_animated.png",
"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, pointable = false,
glow = -1, glow = -1,
backface_culling = false, backface_culling = false,
@ -81,26 +86,25 @@ minetest.register_entity("mcl_burning:fire", {
animation_frame = 0, animation_frame = 0,
animation_timer = 0, animation_timer = 0,
on_activate = function(self) 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, end,
on_step = function(self) on_step = function(self, dtime)
if not self:sanity_check() then
self.object:remove()
end
end,
sanity_check = function(self)
local parent = self.object:get_attach() local parent = self.object:get_attach()
if not parent then if not parent then
return false self.object:remove()
return
end end
local storage = mcl_burning.get_storage(parent) local storage = mcl_burning.get_storage(parent)
if not storage or not storage.burn_time then 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 end
return true
end, end,
}) })