Move raycast_line_of_sight function to mcl_mobs/functions.lua, rework group spawn point selection code, add line of sight check to group origin

This commit is contained in:
teknomunk 2024-07-07 19:17:19 -05:00 committed by the-real-herowl
parent 8c42694ac9
commit 8b13b36a6a
4 changed files with 48 additions and 34 deletions

View file

@ -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

View file

@ -18,6 +18,7 @@ local node_ok = function(pos, fallback)
return minetest.registered_nodes[fallback]
end
mcl_mobs.node_ok = node_ok
dofile(path .. "/functions.lua")
--api and helpers
-- effects: sounds and particles mostly

View file

@ -28,6 +28,7 @@ local vector_zero = vector.zero
local vector_copy = vector.copy
local vector_offset = vector.offset
local vector_distance = vector.distance
local raycast_line_of_sight = mcl_mobs.check_line_of_sight
local registered_fallback_node = minetest.registered_nodes[mcl_mobs.fallback_node]
@ -63,26 +64,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
if not self.attack then return end

View file

@ -35,6 +35,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 = minetest.settings:get_bool("mcl_logging_mobs_spawn", false)
local function mcl_log(message, property)
@ -802,26 +803,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