diff --git a/mods/ENTITIES/mcl_mobs/functions.lua b/mods/ENTITIES/mcl_mobs/functions.lua new file mode 100644 index 000000000..ef47b299d --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/functions.lua @@ -0,0 +1,22 @@ + +function mcl_mobs.check_line_of_sight(origin, target) + local raycast = minetest.raycast(origin, target, false, true) + + local los_blocked = false + for hitpoint in raycast do + if hitpoint.type == "node" then + --TODO type object could block vision, for example chests + local node = minetest.get_node(minetest.get_pointed_thing_position(hitpoint)) + + if node.name ~= "air" then + local nodef = minetest.registered_nodes[node.name] + if nodef and nodef.walkable then + los_blocked = true + break + end + end + end + end + return not los_blocked +end + diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index 81b5fdfe7..99a94944c 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -6,6 +6,9 @@ local modname = minetest.get_current_modname() local path = minetest.get_modpath(modname) local S = minetest.get_translator(modname) mcl_mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt" + +dofile(path .. "/functions.lua") + --api and helpers -- effects: sounds and particles mostly dofile(path .. "/effects.lua") diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua index ff9a38f56..5659c79ef 100644 --- a/mods/ENTITIES/mcl_mobs/movement.lua +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -20,6 +20,7 @@ local function atan(x) return atann(x) end end +local raycast_line_of_sight = mcl_mobs.check_line_of_sight local registered_fallback_node = minetest.registered_nodes[mcl_mobs.fallback_node] @@ -77,28 +78,6 @@ function mob_class:is_node_waterhazard(nodename) end -local function raycast_line_of_sight (origin, target) - local raycast = minetest.raycast(origin, target, false, true) - - local los_blocked = false - - for hitpoint in raycast do - if hitpoint.type == "node" then - --TODO type object could block vision, for example chests - local node = minetest.get_node(minetest.get_pointed_thing_position(hitpoint)) - - if node.name ~= "air" then - local nodef = minetest.registered_nodes[node.name] - if nodef and nodef.walkable then - los_blocked = true - break - end - end - end - end - return not los_blocked -end - function mob_class:target_visible(origin) if not origin then return end diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index a455e7ae9..7e8e08626 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -33,6 +33,7 @@ local vector_floor = vector.floor local table_copy = table.copy local table_remove = table.remove local pairs = pairs +local check_line_of_sight = mcl_mobs.check_line_of_sight local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_spawning", false) local function mcl_log (message, property) @@ -792,26 +793,35 @@ local function spawn_group(p, mob, spawn_on, amount_to_spawn, parent_state) -- spawn in a given spot. local o while amount_to_spawn > 0 and #nn > 0 do + -- Find the next valid group spawn point + local sp + while #nn > 0 and not sp do -- Select the next spawn position - local sp = vector.offset(nn[#nn],0,1,0) - nn[#nn] = nil + sp = vector.offset(nn[#nn],0,1,0) + nn[#nn] = nil + + if spawn_protected and minetest.is_protected(sp, "") then + sp = nil + elseif not check_line_of_sight(p, sp) then + sp = nil + end + end + if not sp then return o end -- Spawning prohibited in protected areas - if not (spawn_protected and minetest.is_protected(sp, "")) then - local state, node = build_state_for_position(sp, parent_state) + local state, node = build_state_for_position(sp, parent_state) - if spawn_check(sp, state, node, mob) then - if mob.type_of_spawning == "water" then - sp = get_water_spawn(sp) - end + if spawn_check(sp, state, node, mob) then + if mob.type_of_spawning == "water" then + sp = get_water_spawn(sp) + end - --minetest.log("Using spawn point "..vector.to_string(sp)) + --minetest.log("Using spawn point "..vector.to_string(sp)) - o = mcl_mobs.spawn(sp,mob.name) - if o then - amount_to_spawn = amount_to_spawn - 1 - dbg_spawn_succ = dbg_spawn_succ + 1 - end + o = mcl_mobs.spawn(sp,mob.name) + if o then + amount_to_spawn = amount_to_spawn - 1 + dbg_spawn_succ = dbg_spawn_succ + 1 end end end