VoxeLibre/mods/ENTITIES/mcl_burning/init.lua
iliekprogrammar 96c4fb60d8
Fix crash on startup during immediate runtime by mcl_burning
The crash occurs if mcl_burning:data is deserialized to nil. The cause of
mcl_burning being set to "return nil" is unknown. Therefore, when it occurs, it
will be logged as warning.
2021-11-13 10:55:24 +08:00

112 lines
3.0 KiB
Lua

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
}
dofile(modpath .. "/api.lua")
minetest.register_globalstep(function(dtime)
for _, player in pairs(get_connected_players()) do
local storage = mcl_burning.storage[player]
if not mcl_burning.tick(player, dtime, storage) and not mcl_burning.is_affected_by_rain(player) then
local nodes = mcl_burning.get_touching_nodes(player, {"group:puts_out_fire", "group:set_on_fire"}, storage)
local burn_time = 0
for _, pos in pairs(nodes) do
local node = minetest.get_node(pos)
if get_item_group(node.name, "puts_out_fire") > 0 then
burn_time = 0
break
end
local value = get_item_group(node.name, "set_on_fire")
if value > burn_time then
burn_time = value
end
end
if burn_time > 0 then
mcl_burning.set_on_fire(player, burn_time)
end
end
end
end)
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")
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())
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
end)
minetest.register_entity("mcl_burning:fire", {
initial_properties = {
physical = false,
collisionbox = {0, 0, 0, 0, 0, 0},
visual = "upright_sprite",
textures = {
name = "mcl_burning_entity_flame_animated.png",
animation = {
type = "vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1.0,
},
},
spritediv = {x = 1, y = mcl_burning.animation_frames},
pointable = false,
glow = -1,
backface_culling = false,
},
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)
end,
on_step = function(self)
if not self:sanity_check() then
self.object:remove()
end
end,
sanity_check = function(self)
local parent = self.object:get_attach()
if not parent then
return false
end
local storage = mcl_burning.get_storage(parent)
if not storage or not storage.burn_time then
return false
end
return true
end,
})