Merge pull request 'Prevent mob conversion code from crashing' (#4421) from teknomunk/MineClone2:fix-conversion-crash into master

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4421
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
This commit is contained in:
the-real-herowl 2024-06-24 03:07:19 +02:00
commit 53802b270d
3 changed files with 42 additions and 8 deletions

View file

@ -150,6 +150,11 @@ function mob_class:mob_activate(staticdata, def, dtime)
local tmp = minetest.deserialize(staticdata) local tmp = minetest.deserialize(staticdata)
if tmp then if tmp then
-- Patch incorrectly converted mobs
if tmp.base_mesh ~= minetest.registered_entities[self.name].mesh then
mcl_mobs.strip_staticdata(tmp)
end
for _,stat in pairs(tmp) do for _,stat in pairs(tmp) do
self[_] = stat self[_] = stat
end end

View file

@ -342,13 +342,33 @@ function mcl_mobs.register_mob(name, def)
minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta)) minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta))
end -- END mcl_mobs.register_mob function end -- END mcl_mobs.register_mob function
local STRIP_FIELDS = { "mesh", "base_size", "textures", "base_mesh", "base_texture" }
function mcl_mobs.strip_staticdata(unpacked_staticdata)
-- Strip select fields from the staticdata to prevent conversion issues
for i = 1,#STRIP_FIELDS do
unpacked_staticdata[STRIP_FIELDS[i]] = nil
end
end
function mcl_mobs.register_conversion(old_name, new_name) function mcl_mobs.register_conversion(old_name, new_name)
minetest.register_entity(old_name, { minetest.register_entity(old_name, {
on_activate = function(self, staticdata, dtime) on_activate = function(self, staticdata, dtime)
local obj = minetest.add_entity(self.object:get_pos(), new_name, staticdata) local unpacked_staticdata = minetest.deserialize(staticdata)
local hook = (obj:get_luaentity() or {})._on_after_convert mcl_mobs.strip_staticdata(unpacked_staticdata)
if hook then hook(obj) end staticdata = minetest.serialize(unpacked_staticdata)
self.object:remove()
local old_object = self.object
if not old_object then return end
local pos = old_object:get_pos()
if not pos then return end
old_object:remove()
local new_object = minetest.add_entity(pos, new_name, staticdata)
if not new_object then return end
local hook = (new_object:get_luaentity() or {})._on_after_convert
if hook then hook(new_object) end
end, end,
_convert_to = new_name, _convert_to = new_name,
}) })
@ -572,7 +592,12 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg
--minetest.log("min light: " .. mob_light_lvl[1]) --minetest.log("min light: " .. mob_light_lvl[1])
--minetest.log("max light: " .. mob_light_lvl[2]) --minetest.log("max light: " .. mob_light_lvl[2])
mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name(), mob_light_lvl[1], mob_light_lvl[2]) -- Handle egg conversion
local mob_name = itemstack:get_name()
local convert_to = (minetest.registered_entities[mob_name] or {})._convert_to
if convert_to then mob_name = convert_to end
mcl_mobspawners.setup_spawner(pointed_thing.under, mob_name, mob_light_lvl[1], mob_light_lvl[2])
if not minetest.is_creative_enabled(name) then if not minetest.is_creative_enabled(name) then
itemstack:take_item() itemstack:take_item()
end end

View file

@ -83,6 +83,13 @@ local function respawn_doll(pos)
local mob = meta:get_string("Mob") local mob = meta:get_string("Mob")
local doll local doll
if mob and mob ~= "" then if mob and mob ~= "" then
-- Handle conversion of mob spawners
local convert_to = (minetest.registered_entities[mob] or {})._convert_to
if convert_to then
mob = convert_to
meta:set_string("Mob", mob)
end
doll = find_doll(pos) doll = find_doll(pos)
if not doll then if not doll then
doll = spawn_doll(pos) doll = spawn_doll(pos)
@ -128,7 +135,6 @@ function mcl_mobspawners.setup_spawner(pos, Mob, MinLight, MaxLight, MaxMobsInAr
end end
set_doll_properties(doll, Mob) set_doll_properties(doll, Mob)
-- Start spawning very soon -- Start spawning very soon
local t = minetest.get_node_timer(pos) local t = minetest.get_node_timer(pos)
t:start(2) t:start(2)
@ -165,7 +171,6 @@ local function spawn_mobs(pos, elapsed)
local count = 0 local count = 0
local ent local ent
local timer = minetest.get_node_timer(pos) local timer = minetest.get_node_timer(pos)
-- spawn mob if player detected and in range -- spawn mob if player detected and in range
@ -367,7 +372,6 @@ doll_def.on_activate = function(self, staticdata, dtime_s)
self.object:set_velocity({x=0, y=0, z=0}) self.object:set_velocity({x=0, y=0, z=0})
self.object:set_acceleration({x=0, y=0, z=0}) self.object:set_acceleration({x=0, y=0, z=0})
self.object:set_armor_groups({immortal=1}) self.object:set_armor_groups({immortal=1})
end end
doll_def.on_step = function(self, dtime) doll_def.on_step = function(self, dtime)