Spawning Improvements

This commit is contained in:
ElCeejo 2022-09-28 14:41:56 -07:00
parent 5f48a07665
commit 0af4c2ba24
3 changed files with 40 additions and 24 deletions

16
api.lua
View file

@ -160,21 +160,23 @@ function creatura.get_ground_level(pos, range)
end end
function creatura.is_pos_moveable(pos, width, height) function creatura.is_pos_moveable(pos, width, height)
local pos1 = { local edge1 = {
x = pos.x - (width + 0.2), x = pos.x - (width + 0.2),
y = pos.y, y = pos.y,
z = pos.z - (width + 0.2), z = pos.z - (width + 0.2),
} }
local pos2 = { local edge2 = {
x = pos.x + (width + 0.2), x = pos.x + (width + 0.2),
y = pos.y, y = pos.y,
z = pos.z + (width + 0.2), z = pos.z + (width + 0.2),
} }
for z = pos1.z, pos2.z do local base_p = {x = pos.x, y = pos.y, z = pos.z}
for x = pos1.x, pos2.x do local top_p = {x = pos.x, y = pos.y + height, z = pos.z}
local pos3 = {x = x, y = pos.y + height, z = z} for z = edge1.z, edge2.z do
local pos4 = {x = x, y = pos.y + 0.01, z = z} for x = edge1.x, edge2.x do
local ray = minetest.raycast(pos3, pos4, false, false) base_p.x, base_p.z = pos.x + x, pos.z + z
top_p.x, top_p.z = pos.x + x, pos.z + z
local ray = minetest.raycast(base_p, top_p, false, false)
for pointed_thing in ray do for pointed_thing in ray do
if pointed_thing.type == "node" then if pointed_thing.type == "node" then
local name = get_node(pointed_thing.under).name local name = get_node(pointed_thing.under).name

View file

@ -1156,7 +1156,7 @@ function mob:_vitals()
local pos = self.stand_pos local pos = self.stand_pos
local node = self.stand_node local node = self.stand_node
if not pos or not node then return end if not pos or not node then return end
local max_fall = self.max_fall or 0 local max_fall = self.max_fall or 3
local in_liquid = self.in_liquid local in_liquid = self.in_liquid
local on_ground = self.touching_ground local on_ground = self.touching_ground
local damage local damage
@ -1168,12 +1168,14 @@ function mob:_vitals()
damage = fall_start - pos.y damage = fall_start - pos.y
if damage < max_fall then if damage < max_fall then
damage = nil damage = nil
else
local resist = self.fall_resistance or 0
damage = damage - damage * resist
fall_start = nil
end end
local resist = self.fall_resistance or 0
damage = damage - damage * resist
self._fall_start = nil
end end
end end
self._fall_start = fall_start
end end
if self:timer(1) then if self:timer(1) then
local stand_def = creatura.get_node_def(node.name) local stand_def = creatura.get_node_def(node.name)

View file

@ -336,7 +336,7 @@ minetest.register_on_generated(function(minp, maxp)
local mob = #mobs > 0 and mobs[random(#mobs)] local mob = #mobs > 0 and mobs[random(#mobs)]
if mob then if mob then
local spawn = creatura.registered_mob_spawns[mob] local spawn = creatura.registered_mob_spawns[mob]
for y = max_y, min_y, -1 do for y = min_y, max_y do
if y > spawn.max_height if y > spawn.max_height
or y < spawn.min_height then or y < spawn.min_height then
break break
@ -476,6 +476,21 @@ minetest.register_abm({
local abr = (tonumber(minetest.get_mapgen_setting("active_block_range")) or 4) * 16 local abr = (tonumber(minetest.get_mapgen_setting("active_block_range")) or 4) * 16
local max_per_block = tonumber(minetest.settings:get("creatura_mapblock_limit")) or 99 local max_per_block = tonumber(minetest.settings:get("creatura_mapblock_limit")) or 99
local function can_spawn(pos, width, height)
local pos2
local w_iter = width / math.ceil(width)
for y = 0, height, height / math.ceil(height) do
for z = -width, width, w_iter do
for x = -width, width, w_iter do
pos2 = {x = pos.x + x, y = pos.y + y, z = pos.z + z}
local def = creatura.get_node_def(pos2)
if def.walkable then return false end
end
end
end
return true
end
function creatura.register_abm_spawn(mob, def) function creatura.register_abm_spawn(mob, def)
local chance = def.chance or 3000 local chance = def.chance or 3000
local interval = def.interval or 30 local interval = def.interval or 30
@ -497,12 +512,10 @@ function creatura.register_abm_spawn(mob, def)
pos.y = pos.y + 1 pos.y = pos.y + 1
end end
if spawn_on_load -- Manual checks for LBMs if spawn_on_load then -- Manual checks for LBMs
and (random(chance) > 1 if random(chance) > 1 then return end
or not minetest.find_node_near(pos, 1, neighbors) if not minetest.find_node_near(pos, 1, neighbors) then return end
or pos.y > max_height if pos.y > max_height or pos.y < min_height then return end
or pos.y < min_height) then
return
end end
local light = minetest.get_node_light(pos) or 7 local light = minetest.get_node_light(pos) or 7
@ -540,9 +553,9 @@ function creatura.register_abm_spawn(mob, def)
local mob_def = minetest.registered_entities[mob] local mob_def = minetest.registered_entities[mob]
local mob_width = mob_def.collisionbox[4] local mob_width = mob_def.collisionbox[4]
local mob_height = math.max(0, mob_def.collisionbox[5] - mob_def.collisionbox[2]) local mob_height = mob_def.collisionbox[5]
if not creatura.is_pos_moveable(pos, mob_width, mob_height) then if not can_spawn(pos, mob_width, mob_height) then
return return
end end
@ -556,7 +569,7 @@ function creatura.register_abm_spawn(mob, def)
y = pos.y, y = pos.y,
z = pos.x + random(-offset, offset), z = pos.x + random(-offset, offset),
}, 3) }, 3)
if not creatura.is_pos_moveable(spawn_pos, mob_width, mob_height) then if not can_spawn(spawn_pos, mob_width, mob_height) then
spawn_pos = pos spawn_pos = pos
end end
local obj = minetest.add_entity(spawn_pos, mob) local obj = minetest.add_entity(spawn_pos, mob)
@ -581,7 +594,6 @@ function creatura.register_abm_spawn(mob, def)
end end
end end
minetest.log("action", minetest.log("action",
"[Creatura] [ABM Spawning] Spawned " .. group_size .. " " .. mob .. " at " .. minetest.pos_to_string(pos)) "[Creatura] [ABM Spawning] Spawned " .. group_size .. " " .. mob .. " at " .. minetest.pos_to_string(pos))
@ -593,8 +605,8 @@ function creatura.register_abm_spawn(mob, def)
label = mob .. " spawning", label = mob .. " spawning",
nodenames = nodes, nodenames = nodes,
run_at_every_load = false, run_at_every_load = false,
action = function(pos) action = function(pos, ...)
spawn_func(pos) spawn_func(pos, ...)
end end
}) })
else else