added 'on_map_load' setting to mobs:spawn function to spawn mob in newly loaded areas of map only

This commit is contained in:
TenPlus1 2020-09-04 13:59:14 +01:00
parent 39002cf4e7
commit 499d43a9aa
3 changed files with 192 additions and 162 deletions

92
api.lua
View File

@ -9,7 +9,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = { mobs = {
mod = "redo", mod = "redo",
version = "20200825", version = "20200904",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} invis = minetest.global_exists("invisibility") and invisibility or {}
} }
@ -3699,8 +3699,8 @@ function mobs:spawn_abm_check(pos, node, name)
end end
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval,
interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) chance, aoc, min_height, max_height, day_toggle, on_spawn, map_load)
-- Do mobs spawn at all? -- Do mobs spawn at all?
if not mobs_spawn or not mobs.spawning_mobs[name] then if not mobs_spawn or not mobs.spawning_mobs[name] then
@ -3730,18 +3730,20 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
mobs.spawning_mobs[name].aoc = aoc mobs.spawning_mobs[name].aoc = aoc
minetest.register_abm({ local spawn_action = function(pos, node, active_object_count,
label = name .. " spawning",
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = max(1, (chance * mob_chance_multiplier)),
catch_up = false,
action = function(pos, node, active_object_count,
active_object_count_wider) active_object_count_wider)
-- use instead of abm's chance setting when using lbm
if map_load and random(max(1, (chance * mob_chance_multiplier))) > 1 then
return
end
-- use instead of abm's neighbor setting when using lbm
if map_load and not minetest.find_node_near(pos, 1, neighbors) then
--print("--- lbm neighbors not found")
return
end
-- is mob actually registered? -- is mob actually registered?
if not mobs.spawning_mobs[name] if not mobs.spawning_mobs[name]
or not minetest.registered_entities[name] then or not minetest.registered_entities[name] then
@ -3761,7 +3763,8 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
end end
-- do not spawn if too many entities in area -- do not spawn if too many entities in area
if active_object_count_wider >= max_per_block then if active_object_count_wider
and active_object_count_wider >= max_per_block then
--print("--- too many entities in area", active_object_count_wider) --print("--- too many entities in area", active_object_count_wider)
return return
end end
@ -3826,8 +3829,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
end end
-- only spawn a set distance away from player -- only spawn a set distance away from player
local objs = minetest.get_objects_inside_radius( local objs = minetest.get_objects_inside_radius(pos, mob_nospawn_range)
pos, mob_nospawn_range)
for n = 1, #objs do for n = 1, #objs do
@ -3839,8 +3841,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
-- do we have enough space to spawn mob? (thanks wuzzy) -- do we have enough space to spawn mob? (thanks wuzzy)
local ent = minetest.registered_entities[name] local ent = minetest.registered_entities[name]
local width_x = max(1, local width_x = max(1, ceil(ent.collisionbox[4] - ent.collisionbox[1]))
ceil(ent.collisionbox[4] - ent.collisionbox[1]))
local min_x, max_x local min_x, max_x
if width_x % 2 == 0 then if width_x % 2 == 0 then
@ -3851,8 +3852,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
min_x = -max_x min_x = -max_x
end end
local width_z = max(1, local width_z = max(1, ceil(ent.collisionbox[6] - ent.collisionbox[3]))
ceil(ent.collisionbox[6] - ent.collisionbox[3]))
local min_z, max_z local min_z, max_z
if width_z % 2 == 0 then if width_z % 2 == 0 then
@ -3863,8 +3863,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
min_z = -max_z min_z = -max_z
end end
local max_y = max(0, local max_y = max(0, ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1)
for y = 0, max_y do for y = 0, max_y do
for x = min_x, max_x do for x = min_x, max_x do
@ -3875,8 +3874,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
y = pos.y + y, y = pos.y + y,
z = pos.z + z} z = pos.z + z}
if minetest.registered_nodes[ if minetest.registered_nodes[node_ok(pos2).name].walkable == true then
node_ok(pos2).name].walkable == true then
--print("--- not enough space to spawn", name) --print("--- not enough space to spawn", name)
return return
end end
@ -3898,18 +3896,45 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
local mob = minetest.add_entity(pos, name) local mob = minetest.add_entity(pos, name)
-- print("[mobs] Spawned " .. name .. " at " print("[mobs] Spawned " .. name .. " at "
-- .. minetest.pos_to_string(pos) .. " on " .. minetest.pos_to_string(pos) .. " on "
-- .. node.name .. " near " .. neighbors[1]) .. node.name .. " near " .. neighbors[1])
if on_spawn then if on_spawn then
on_spawn(mob:get_luaentity(), pos)
local ent = mob:get_luaentity()
on_spawn(ent, pos)
end end
end end
-- are we registering an abm or lbm?
if map_load == true then
minetest.register_lbm({
name = name .. "_spawning",
label = name .. " spawning",
nodenames = nodes,
run_at_every_load = false,
action = function(pos, node)
spawn_action(pos, node)
end
}) })
else
minetest.register_abm({
label = name .. " spawning",
nodenames = nodes,
neighbors = neighbors,
interval = interval,
chance = max(1, (chance * mob_chance_multiplier)),
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
spawn_action(pos, node, active_object_count, active_object_count_wider)
end
})
end
end end
@ -3922,7 +3947,7 @@ function mobs:register_spawn(name, nodes, max_light, min_light, chance,
end end
-- MarkBu's spawn function -- MarkBu's spawn function (USE this one please)
function mobs:spawn(def) function mobs:spawn(def)
mobs:spawn_specific( mobs:spawn_specific(
@ -3937,7 +3962,8 @@ function mobs:spawn(def)
def.min_height or -31000, def.min_height or -31000,
def.max_height or 31000, def.max_height or 31000,
def.day_toggle, def.day_toggle,
def.on_spawn) def.on_spawn,
def.on_map_load)
end end

View File

@ -383,6 +383,9 @@ default setting and can be omitted:
anytime anytime
'on_spawn' is a custom function which runs after mob has spawned 'on_spawn' is a custom function which runs after mob has spawned
and gives self and pos values. and gives self and pos values.
'on_map_load' when true mobs will have a chance of spawning only
when new areas of map are loaded, interval will not be
used.
The older spawn functions are still active and working but have no defaults like The older spawn functions are still active and working but have no defaults like
the mobs:spawn, so it is recommended to use the above instead. the mobs:spawn, so it is recommended to use the above instead.

View File

@ -23,7 +23,8 @@ Lucky Blocks: 9
Changelog: Changelog:
- 1.52 - Added 'mob_active_limit' in settings to set number of mobs in game - 1.53 - Added 'on_map_load' settings to mobs:spawn so that mobs will only spawn when new areas of map are loaded.
- 1.52 - Added 'mob_active_limit' in settings to set number of mobs in game,
(default is 0 for unlimited), removed {immortal} from mob armor, fluid viscocity slows mobs (default is 0 for unlimited), removed {immortal} from mob armor, fluid viscocity slows mobs
- 1.51 - Added some node checks for dangerous nodes, jumping and falling tweaks, spawn area check (thx for idea wuzzy), re-enabled mob suffocation, add 'mob_nospawn_range' setting - 1.51 - Added some node checks for dangerous nodes, jumping and falling tweaks, spawn area check (thx for idea wuzzy), re-enabled mob suffocation, add 'mob_nospawn_range' setting
- 1.50 - Added new line_of_sight function that uses raycasting if mt5.0 is found, (thanks Astrobe), dont spawn mobs if world anchor nearby (technic or simple_anchor mods), chinese local added - 1.50 - Added new line_of_sight function that uses raycasting if mt5.0 is found, (thanks Astrobe), dont spawn mobs if world anchor nearby (technic or simple_anchor mods), chinese local added