From 0af4c2ba24eecb39756bdb56fea4f3e531e7b9c7 Mon Sep 17 00:00:00 2001 From: ElCeejo Date: Wed, 28 Sep 2022 14:41:56 -0700 Subject: [PATCH] Spawning Improvements --- api.lua | 16 +++++++++------- mob_meta.lua | 10 ++++++---- spawning.lua | 38 +++++++++++++++++++++++++------------- 3 files changed, 40 insertions(+), 24 deletions(-) diff --git a/api.lua b/api.lua index 85b5b0b..3bafc3e 100644 --- a/api.lua +++ b/api.lua @@ -160,21 +160,23 @@ function creatura.get_ground_level(pos, range) end function creatura.is_pos_moveable(pos, width, height) - local pos1 = { + local edge1 = { x = pos.x - (width + 0.2), y = pos.y, z = pos.z - (width + 0.2), } - local pos2 = { + local edge2 = { x = pos.x + (width + 0.2), y = pos.y, z = pos.z + (width + 0.2), } - for z = pos1.z, pos2.z do - for x = pos1.x, pos2.x do - local pos3 = {x = x, y = pos.y + height, z = z} - local pos4 = {x = x, y = pos.y + 0.01, z = z} - local ray = minetest.raycast(pos3, pos4, false, false) + local base_p = {x = pos.x, y = pos.y, z = pos.z} + local top_p = {x = pos.x, y = pos.y + height, z = pos.z} + for z = edge1.z, edge2.z do + for x = edge1.x, edge2.x do + 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 if pointed_thing.type == "node" then local name = get_node(pointed_thing.under).name diff --git a/mob_meta.lua b/mob_meta.lua index 588aeec..c9c464c 100644 --- a/mob_meta.lua +++ b/mob_meta.lua @@ -1156,7 +1156,7 @@ function mob:_vitals() local pos = self.stand_pos local node = self.stand_node 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 on_ground = self.touching_ground local damage @@ -1168,12 +1168,14 @@ function mob:_vitals() damage = fall_start - pos.y if damage < max_fall then damage = nil + else + local resist = self.fall_resistance or 0 + damage = damage - damage * resist + fall_start = nil end - local resist = self.fall_resistance or 0 - damage = damage - damage * resist - self._fall_start = nil end end + self._fall_start = fall_start end if self:timer(1) then local stand_def = creatura.get_node_def(node.name) diff --git a/spawning.lua b/spawning.lua index e320fbc..ad32d42 100644 --- a/spawning.lua +++ b/spawning.lua @@ -336,7 +336,7 @@ minetest.register_on_generated(function(minp, maxp) local mob = #mobs > 0 and mobs[random(#mobs)] if mob then 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 or y < spawn.min_height then break @@ -476,6 +476,21 @@ minetest.register_abm({ 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 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) local chance = def.chance or 3000 local interval = def.interval or 30 @@ -497,12 +512,10 @@ function creatura.register_abm_spawn(mob, def) pos.y = pos.y + 1 end - if spawn_on_load -- Manual checks for LBMs - and (random(chance) > 1 - or not minetest.find_node_near(pos, 1, neighbors) - or pos.y > max_height - or pos.y < min_height) then - return + if spawn_on_load then -- Manual checks for LBMs + if random(chance) > 1 then return end + if not minetest.find_node_near(pos, 1, neighbors) then return end + if pos.y > max_height or pos.y < min_height then return end end 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_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 end @@ -556,7 +569,7 @@ function creatura.register_abm_spawn(mob, def) y = pos.y, z = pos.x + random(-offset, offset), }, 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 end local obj = minetest.add_entity(spawn_pos, mob) @@ -581,7 +594,6 @@ function creatura.register_abm_spawn(mob, def) end end - minetest.log("action", "[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", nodenames = nodes, run_at_every_load = false, - action = function(pos) - spawn_func(pos) + action = function(pos, ...) + spawn_func(pos, ...) end }) else