Fix mob spawner crash (#4337)

This fixes #4336 crash at login about mcl_mobspawners. Also adds an API call, `mcl_mobs.register_conversion` for converting one mob into another and updates rovers and stalkers to use this API call.

Reviewed-on: https://git.minetest.land/VoxeLibre/VoxeLibre/pulls/4337
Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
Co-authored-by: teknomunk <teknomunk@protonmail.com>
Co-committed-by: teknomunk <teknomunk@protonmail.com>
This commit is contained in:
teknomunk 2024-05-30 08:29:12 +00:00 committed by the-real-herowl
parent c4f4e7b6fc
commit add9cbe3bc
5 changed files with 57 additions and 33 deletions

View file

@ -671,6 +671,13 @@ mob will spawn e.g.
mobs_animal:sheep_chance 11000 mobs_animal:sheep_chance 11000
mobs_monster:sand_monster_chance 100 mobs_monster:sand_monster_chance 100
Registering Mob Conversion
----------------
Sometimes you need to completely replace one mob with a different version. To do this, use:
mcl_mobs.register_conversion(old_name, new_name)
Rideable Horse Example Mob Rideable Horse Example Mob
-------------------------- --------------------------

View file

@ -342,6 +342,17 @@ 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
function mcl_mobs.register_conversion(old_name, new_name)
minetest.register_entity(old_name, {
on_activate = function(self, staticdata, dtime)
local obj = minetest.add_entity(self.object:get_pos(), new_name, staticdata)
local hook = (obj:get_luaentity() or {})._on_after_convert
if hook then hook(obj) end
self.object:remove()
end,
_convert_to = new_name,
})
end
function mcl_mobs.get_arrow_damage_func(damage, typ) function mcl_mobs.get_arrow_damage_func(damage, typ)
local typ = mcl_damage.types[typ] and typ or "arrow" local typ = mcl_damage.types[typ] and typ or "arrow"

View file

@ -491,20 +491,17 @@ mcl_mobs.register_mob("mobs_mc:rover", {
view_range = 64, view_range = 64,
fear_height = 4, fear_height = 4,
attack_type = "dogfight", attack_type = "dogfight",
}) _on_after_convert = function(obj)
-- compat
minetest.register_entity("mobs_mc:enderman", {
on_activate = function(self, staticdata, dtime)
local obj = minetest.add_entity(self.object:get_pos(), "mobs_mc:rover", staticdata)
obj:set_properties({ obj:set_properties({
mesh = "vl_rover.b3d", mesh = "vl_rover.b3d",
textures = { "vl_mobs_rover.png^vl_mobs_rover_face.png" }, textures = { "vl_mobs_rover.png^vl_mobs_rover_face.png" },
visual_size = {x=10, y=10}, visual_size = {x=10, y=10},
}) })
self.object:remove() end
end, }) -- END mcl_mobs.register_mob("mobs_mc:rover", {
})
-- compat
mcl_mobs.register_conversion("mobs_mc:enderman", "mobs_mc:rover")
-- End spawn -- End spawn
mcl_mobs:spawn_specific( mcl_mobs:spawn_specific(

View file

@ -175,7 +175,18 @@ mcl_mobs.register_mob("mobs_mc:stalker", {
floats = 1, floats = 1,
fear_height = 4, fear_height = 4,
view_range = 16, view_range = 16,
_on_after_convert = function(obj)
obj:set_properties({
visual_size = {x=2, y=2},
mesh = "vl_stalker.b3d",
textures = {
{get_texture({}),
"mobs_mc_empty.png"},
},
}) })
end,
}) -- END mcl_mobs.register_mob("mobs_mc:stalker", {
mcl_mobs.register_mob("mobs_mc:stalker_overloaded", { mcl_mobs.register_mob("mobs_mc:stalker_overloaded", {
description = S("Overloaded Stalker"), description = S("Overloaded Stalker"),
@ -304,26 +315,8 @@ mcl_mobs.register_mob("mobs_mc:stalker_overloaded", {
--Having trouble when fire is placed with lightning --Having trouble when fire is placed with lightning
fire_resistant = true, fire_resistant = true,
glow = 3, glow = 3,
})
-- compat _on_after_convert = function(obj)
minetest.register_entity("mobs_mc:creeper", {
on_activate = function(self, staticdata, dtime)
local obj = minetest.add_entity(self.object:get_pos(), "mobs_mc:stalker", staticdata)
obj:set_properties({
visual_size = {x=2, y=2},
mesh = "vl_stalker.b3d",
textures = {
{get_texture({}),
"mobs_mc_empty.png"},
},
})
self.object:remove()
end,
})
minetest.register_entity("mobs_mc:creeper_charged", {
on_activate = function(self, staticdata, dtime)
local obj = minetest.add_entity(self.object:get_pos(), "mobs_mc:stalker_overloaded", staticdata)
obj:set_properties({ obj:set_properties({
visual_size = {x=2, y=2}, visual_size = {x=2, y=2},
mesh = "vl_stalker.b3d", mesh = "vl_stalker.b3d",
@ -332,9 +325,12 @@ minetest.register_entity("mobs_mc:creeper_charged", {
AURA}, AURA},
}, },
}) })
self.object:remove()
end, end,
}) }) -- END mcl_mobs.register_mob("mobs_mc:stalker_overloaded", {
-- compat
mcl_mobs.register_conversion("mobs_mc:creeper", "mobs_mc:stalker")
mcl_mobs.register_conversion("mobs_mc:creeper_charged", "mobs_mc:stalker_overloaded")
mcl_mobs:spawn_specific( mcl_mobs:spawn_specific(
"mobs_mc:stalker", "mobs_mc:stalker",

View file

@ -63,8 +63,8 @@ local function set_doll_properties(doll, mob)
xs = doll_size_overrides[mob].x xs = doll_size_overrides[mob].x
ys = doll_size_overrides[mob].y ys = doll_size_overrides[mob].y
else else
xs = mobinfo.visual_size.x * 0.33333 xs = (mobinfo.visual_size.x or 0) * 0.33333
ys = mobinfo.visual_size.y * 0.33333 ys = (mobinfo.visual_size.y or 0) * 0.33333
end end
local prop = { local prop = {
mesh = mobinfo.mesh, mesh = mobinfo.mesh,
@ -358,6 +358,11 @@ doll_def.on_activate = function(self, staticdata, dtime_s)
if mob == "" or mob == nil then if mob == "" or mob == nil then
mob = default_mob mob = default_mob
end end
-- Handle conversion of mob spawners
local convert_to = (minetest.registered_entities[mob] or {})._convert_to
if convert_to then mob = convert_to end
set_doll_properties(self.object, mob) set_doll_properties(self.object, mob)
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})
@ -390,3 +395,11 @@ minetest.register_lbm({
respawn_doll(pos) respawn_doll(pos)
end, end,
}) })
minetest.register_on_mods_loaded(function()
for name,mobinfo in pairs(minetest.registered_entities) do
if ( mobinfo.is_mob or name:find("mobs_mc") ) and not ( mobinfo.visual_size or mobinfo._convert_to ) then
minetest.log("warning", "Definition for "..tostring(name).." is missing field 'visual_size', mob spawners will not work properly")
end
end
end)