diff --git a/methods.lua b/methods.lua index 011485d..f4a7105 100644 --- a/methods.lua +++ b/methods.lua @@ -294,6 +294,7 @@ local function get_collision_single(pos, water) end function creatura.get_context_steering(self, goal, range, water) + if not goal then return end local pos, yaw = self.object:get_pos(), self.object:get_yaw() if not pos or not yaw then return end range = range or 8; if range < 2 then range = 2 end @@ -578,7 +579,7 @@ creatura.register_movement_method("creatura:context_based_steering", function(se self:set_gravity(-9.8) local function func(_self, goal, speed_factor) local pos = _self.object:get_pos() - if not pos then return end + if not pos or not goal then return end if vec_dist(pos, goal) < clamp(self.width, 0.5, 1) then _self:halt() return true diff --git a/mob_meta.lua b/mob_meta.lua index 18817c4..e786cf1 100644 --- a/mob_meta.lua +++ b/mob_meta.lua @@ -391,13 +391,13 @@ function mob:get_wander_pos_3d(min_range, max_range, dir, vert_bias) return pos2 end -function mob:is_pos_safe(pos) +function mob:is_pos_safe(pos, ignore_liquid) if not pos then return end - local node = minetest.get_node(pos) - if not node then return false end - if minetest.get_item_group(node.name, "igniter") > 0 - or creatura.get_node_def(node.name).drawtype == "liquid" - or creatura.get_node_def(vec_raise(pos, -1)).drawtype == "liquid" then return false end + local n_def = creatura.get_node_def(pos) + if minetest.get_item_group(n_def.name, "igniter") > 0 + or (not ignore_liquid + and (n_def.drawtype == "liquid" + or creatura.get_node_def(vec_raise(pos, -1)).drawtype == "liquid")) then return false end local fall_safe = false if self.max_fall ~= 0 then for i = 1, self.max_fall or 3 do @@ -1169,16 +1169,16 @@ function mob:_vitals() if max_fall > 0 and not in_liquid then local fall_start = self._fall_start or (not on_ground and pos.y) - if fall_start then - if on_ground then - damage = fall_start - pos.y - if damage < max_fall then - damage = 0 - else - local resist = self.fall_resistance or 0 - damage = damage - damage * resist - fall_start = nil - end + if fall_start + and on_ground then + damage = fall_start - pos.y + if damage < max_fall then + damage = 0 + fall_start = nil + else + local resist = self.fall_resistance or 0 + damage = damage - damage * resist + fall_start = nil end end self._fall_start = fall_start diff --git a/spawning.lua b/spawning.lua index 5e56c2d..62b578a 100644 --- a/spawning.lua +++ b/spawning.lua @@ -19,8 +19,10 @@ end) -- Math -- local abs = math.abs +local ceil = math.ceil local pi = math.pi local random = math.random +local min, max = math.min, math.max local function vec_raise(v, n) return {x = v.x, y = v.y + n, z = v.z} @@ -237,7 +239,7 @@ local function execute_spawns(player) spawn_on) if spawn_y_array[1] then local spawn_pos = spawn_y_array[1] - local dist = vector.distance(pos, spawn_pos) + local dist = vec_dist(pos, spawn_pos) if dist < min_spawn_radius or dist > max_spawn_radius then return end @@ -273,13 +275,14 @@ local function execute_spawns(player) 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 = max(0, mob_def.collisionbox[5] - mob_def.collisionbox[2]) if not creatura.is_pos_moveable(spawn_pos, mob_width, mob_height) then return end local group_size = random(spawn.min_group or 1, spawn.max_group or 1) + group_size = min(spawn.spawn_cap - object_count, group_size) if spawn.spawn_cluster then minetest.add_node(spawn_pos, {name = "creatura:spawn_node"}) @@ -496,8 +499,8 @@ local min_abm_dist = tonumber(minetest.settings:get("creatura_min_abm_dist")) or 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 + local w_iter = width / ceil(width) + for y = 0, height, height / 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} @@ -621,11 +624,11 @@ function creatura.register_abm_spawn(mob, def) if group_size > 1 then for _ = 1, group_size do - local offset = math.ceil(mob_width) + local offset = ceil(mob_width) local spawn_pos = creatura.get_ground_level({ x = pos.x + random(-offset, offset), y = pos.y, - z = pos.x + random(-offset, offset), + z = pos.z + random(-offset, offset) }, 3) if not can_spawn(spawn_pos, mob_width, mob_height) then spawn_pos = pos