From cea6d159659407445786e9b166f223567b863927 Mon Sep 17 00:00:00 2001 From: Jordan Leppert Date: Mon, 14 Feb 2022 16:18:07 +0000 Subject: [PATCH 1/7] Spawning fixes: 1. Spawning radius fixed, we now have a cubic max radius mobs will spawn within, and a spherical min radius mobs won't spawn within. 2. Node light check fixed - we need to check the node above the spawn node, otherwise it always returns zero. --- spawning.lua | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/spawning.lua b/spawning.lua index 20c6cb0..949733a 100644 --- a/spawning.lua +++ b/spawning.lua @@ -66,7 +66,7 @@ end function creatura.register_mob_spawn(name, def) local spawn = { chance = def.chance or 5, - min_radius = def.min_height or nil, + min_radius = def.min_radius or nil, max_radius = def.max_radius or nil, min_height = def.min_height or 0, max_height = def.max_height or 128, @@ -132,7 +132,7 @@ local spawn_queue = {} local min_spawn_radius = 16 -local min_spawn_radius = 64 +local max_spawn_radius = 64 function execute_spawns(player) if not player:get_pos() then return end @@ -144,11 +144,16 @@ function execute_spawns(player) local spawn = creatura.registered_mob_spawns[mob] if not spawn or random(spawn.chance) > 1 then return end + local max_radius = spawn.max_radius or max_spawn_radius + local min_radius = spawn.min_radius or min_spawn_radius local spawn_pos_center = { - x = pos.x + random(-min_spawn_radius, spawn.min_radius or min_spawn_radius), + x = pos.x + random(-max_radius, max_radius), y = pos.y, - z = pos.z + random(-min_spawn_radius, spawn.max_radius or min_spawn_radius) + z = pos.z + random(-max_radius, max_radius) } + if vector.distance(pos, spawn_pos_center) < min_radius then + return + end local index_func if spawn.spawn_in_nodes then index_func = minetest.find_nodes_in_area @@ -159,7 +164,7 @@ function execute_spawns(player) if type(spawn_on) == "string" then spawn_on = {spawn_on} end - local spawn_y_array = index_func(vec_raise(spawn_pos_center, -8), vec_raise(spawn_pos_center, 8), spawn_on) + local spawn_y_array = index_func(vec_raise(spawn_pos_center, -max_radius), vec_raise(spawn_pos_center, max_radius), spawn_on) if spawn_y_array[1] then local spawn_pos = spawn_y_array[1] @@ -168,7 +173,7 @@ function execute_spawns(player) return end - local light = minetest.get_node_light(spawn_pos) or 7 + local light = minetest.get_node_light(vec_raise(spawn_pos, 1)) or 7 if light > spawn.max_light or light < spawn.min_light then From d7b880da1ee80e797f169fa46d76c8a54a5411d1 Mon Sep 17 00:00:00 2001 From: Jordan Leppert Date: Tue, 15 Feb 2022 10:45:50 +0000 Subject: [PATCH 2/7] Spawning light check - only check node above when spawn_in_nodes is false --- spawning.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spawning.lua b/spawning.lua index 949733a..340828f 100644 --- a/spawning.lua +++ b/spawning.lua @@ -173,7 +173,11 @@ function execute_spawns(player) return end - local light = minetest.get_node_light(vec_raise(spawn_pos, 1)) or 7 + local light_pos = spawn_pos + if not spawn.spawn_in_nodes then + light_pos = vec_raise(spawn_pos, 1) + end + local light = minetest.get_node_light(light_pos) or 7 if light > spawn.max_light or light < spawn.min_light then From fe4f065bfc651abc7cf21cba79c1b7162bf1e448 Mon Sep 17 00:00:00 2001 From: Jordan Leppert Date: Tue, 15 Feb 2022 21:16:31 +0000 Subject: [PATCH 3/7] Spawn cap: Limit spawning of animals to 5 (default) of each type within spawn radius --- spawning.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spawning.lua b/spawning.lua index 340828f..f0ffdfe 100644 --- a/spawning.lua +++ b/spawning.lua @@ -78,6 +78,7 @@ function creatura.register_mob_spawn(name, def) biomes = def.biomes or nil, spawn_cluster = def.spawn_cluster or false, spawn_in_nodes = def.spawn_in_nodes or false, + spawn_cap = def.spawn_cap or 5, send_debug = def.send_debug or false } creatura.registered_mob_spawns[name] = spawn @@ -146,6 +147,21 @@ function execute_spawns(player) or random(spawn.chance) > 1 then return end local max_radius = spawn.max_radius or max_spawn_radius local min_radius = spawn.min_radius or min_spawn_radius + + -- Spawn cap check + local objects = minetest.get_objects_inside_radius(pos, max_radius) + local object_count = 0 + for _, object in ipairs(objects) do + if creatura.is_alive(object) + and not object:is_player() + and object:get_luaentity().name == mob then + object_count = object_count + 1 + end + end + if object_count >= spawn.spawn_cap then + return + end + local spawn_pos_center = { x = pos.x + random(-max_radius, max_radius), y = pos.y, From c99837fbded5f7f2c3a1afbe5a23aa95fef6c843 Mon Sep 17 00:00:00 2001 From: Jordan Leppert Date: Wed, 16 Feb 2022 09:51:22 +0000 Subject: [PATCH 4/7] Fixing max spawn radius to also be spherical, like the spawn cap check --- spawning.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spawning.lua b/spawning.lua index f0ffdfe..f7e3e41 100644 --- a/spawning.lua +++ b/spawning.lua @@ -167,9 +167,11 @@ function execute_spawns(player) y = pos.y, z = pos.z + random(-max_radius, max_radius) } - if vector.distance(pos, spawn_pos_center) < min_radius then + local dist = vector.distance(pos, spawn_pos_center) + if dist < min_radius or dist > max_radius then return end + local index_func if spawn.spawn_in_nodes then index_func = minetest.find_nodes_in_area From 9a623fa47c1ab2e92dc822643c25bce9e16b30e3 Mon Sep 17 00:00:00 2001 From: Jordan Leppert Date: Wed, 16 Feb 2022 12:20:52 +0000 Subject: [PATCH 5/7] Increasing min/max spawn radius to 32/128. Fixing spawn pos distance check - we now check after we have the actual Y coord. --- spawning.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spawning.lua b/spawning.lua index f7e3e41..452f869 100644 --- a/spawning.lua +++ b/spawning.lua @@ -131,9 +131,9 @@ end local spawn_queue = {} -local min_spawn_radius = 16 +local min_spawn_radius = 32 -local max_spawn_radius = 64 +local max_spawn_radius = 128 function execute_spawns(player) if not player:get_pos() then return end @@ -167,10 +167,6 @@ function execute_spawns(player) y = pos.y, z = pos.z + random(-max_radius, max_radius) } - local dist = vector.distance(pos, spawn_pos_center) - if dist < min_radius or dist > max_radius then - return - end local index_func if spawn.spawn_in_nodes then @@ -185,6 +181,10 @@ function execute_spawns(player) local spawn_y_array = index_func(vec_raise(spawn_pos_center, -max_radius), vec_raise(spawn_pos_center, max_radius), spawn_on) if spawn_y_array[1] then local spawn_pos = spawn_y_array[1] + local dist = vector.distance(pos, spawn_pos) + if dist < min_radius or dist > max_radius then + return + end if spawn_pos.y > spawn.max_height or spawn_pos.y < spawn.min_height then From 7f3d4cc77a4d171997644e1af2bb5702405eac83 Mon Sep 17 00:00:00 2001 From: Jordan Leppert Date: Wed, 16 Feb 2022 13:10:41 +0000 Subject: [PATCH 6/7] Biome check is done on the spawn position, not the player's position. This fixes mobs spawning in the wrong biome, and eg no forest mobs spawning if you're in grasslands just outside a forest. This means we can't (easily) use mob-specific spawn min/max radius, so it is currently removed. --- spawning.lua | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/spawning.lua b/spawning.lua index 452f869..1f61dff 100644 --- a/spawning.lua +++ b/spawning.lua @@ -66,8 +66,6 @@ end function creatura.register_mob_spawn(name, def) local spawn = { chance = def.chance or 5, - min_radius = def.min_radius or nil, - max_radius = def.max_radius or nil, min_height = def.min_height or 0, max_height = def.max_height or 128, min_light = def.min_light or 6, @@ -132,24 +130,28 @@ end local spawn_queue = {} local min_spawn_radius = 32 - local max_spawn_radius = 128 function execute_spawns(player) if not player:get_pos() then return end local pos = player:get_pos() - local spawnable_mobs = get_spawnable_mobs(pos) + + local spawn_pos_center = { + x = pos.x + random(-max_spawn_radius, max_spawn_radius), + y = pos.y, + z = pos.z + random(-max_spawn_radius, max_spawn_radius) + } + + local spawnable_mobs = get_spawnable_mobs(spawn_pos_center) if spawnable_mobs and #spawnable_mobs > 0 then local mob = spawnable_mobs[random(#spawnable_mobs)] local spawn = creatura.registered_mob_spawns[mob] if not spawn or random(spawn.chance) > 1 then return end - local max_radius = spawn.max_radius or max_spawn_radius - local min_radius = spawn.min_radius or min_spawn_radius -- Spawn cap check - local objects = minetest.get_objects_inside_radius(pos, max_radius) + local objects = minetest.get_objects_inside_radius(pos, max_spawn_radius) local object_count = 0 for _, object in ipairs(objects) do if creatura.is_alive(object) @@ -162,12 +164,6 @@ function execute_spawns(player) return end - local spawn_pos_center = { - x = pos.x + random(-max_radius, max_radius), - y = pos.y, - z = pos.z + random(-max_radius, max_radius) - } - local index_func if spawn.spawn_in_nodes then index_func = minetest.find_nodes_in_area @@ -178,13 +174,13 @@ function execute_spawns(player) if type(spawn_on) == "string" then spawn_on = {spawn_on} end - local spawn_y_array = index_func(vec_raise(spawn_pos_center, -max_radius), vec_raise(spawn_pos_center, max_radius), spawn_on) + local spawn_y_array = index_func(vec_raise(spawn_pos_center, -max_spawn_radius), vec_raise(spawn_pos_center, max_spawn_radius), spawn_on) if spawn_y_array[1] then local spawn_pos = spawn_y_array[1] - local dist = vector.distance(pos, spawn_pos) - if dist < min_radius or dist > max_radius then - return - end + local dist = vector.distance(pos, spawn_pos) + if dist < min_spawn_radius or dist > max_spawn_radius then + return + end if spawn_pos.y > spawn.max_height or spawn_pos.y < spawn.min_height then From 10d250fdbfd9303df7cf0ca7b2b4bfd0c3a9f45b Mon Sep 17 00:00:00 2001 From: Jordan Leppert Date: Wed, 16 Feb 2022 15:34:17 +0000 Subject: [PATCH 7/7] Mob despawn_after defaults to never --- mob_meta.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mob_meta.lua b/mob_meta.lua index 3179e77..9d8b2d6 100644 --- a/mob_meta.lua +++ b/mob_meta.lua @@ -123,7 +123,7 @@ local mob = { damage = 2, speed = 4, tracking_range = 16, - despawn_after = 100, + despawn_after = nil, -- Physics max_fall = 3, stepheight = 1.1, @@ -1241,4 +1241,4 @@ function creatura.register_mob(name, def) end minetest.register_entity(name, setmetatable(def, mob_meta)) -end \ No newline at end of file +end