mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-26 04:21:07 +01:00
Merge pull request 'Ensure creepers work by raycast line of sight' (#3905) from raycast_creeper_sight into master
Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3905
This commit is contained in:
commit
cb407666a4
3 changed files with 64 additions and 1 deletions
|
@ -853,7 +853,8 @@ function mob_class:do_states_attack (dtime)
|
|||
return
|
||||
end
|
||||
|
||||
local target_line_of_sight = self:line_of_sight(s, p, 2)
|
||||
local target_line_of_sight = self:target_visible(s)
|
||||
|
||||
if not target_line_of_sight then
|
||||
if self.target_time_lost then
|
||||
local time_since_seen = os.time() - self.target_time_lost
|
||||
|
|
|
@ -76,6 +76,67 @@ function mob_class:is_node_waterhazard(nodename)
|
|||
return false
|
||||
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
|
||||
local target_pos = self.attack:get_pos()
|
||||
|
||||
if not target_pos then return end
|
||||
|
||||
local origin_eye_pos = vector.offset(origin, 0, self.head_eye_height, 0)
|
||||
|
||||
--minetest.log("origin: " .. dump(origin))
|
||||
--minetest.log("origin_eye_pos: " .. dump(origin_eye_pos))
|
||||
|
||||
local targ_head_height, targ_feet_height
|
||||
if self.attack:is_player() then
|
||||
local cbox = self.object:get_properties().collisionbox
|
||||
targ_head_height = vector.offset(target_pos, 0, cbox[5], 0)
|
||||
targ_feet_height = target_pos -- Cbox would put feet under ground which interferes with ray
|
||||
else
|
||||
targ_head_height = vector.offset(target_pos, 0, self.collisionbox[5], 0)
|
||||
targ_feet_height = vector.offset(target_pos, 0, self.collisionbox[2], 0)
|
||||
end
|
||||
|
||||
--minetest.log("start targ_head_height: " .. dump(targ_head_height))
|
||||
if raycast_line_of_sight (origin_eye_pos, targ_head_height) then
|
||||
return true
|
||||
end
|
||||
|
||||
--minetest.log("Start targ_feet_height: " .. dump(targ_feet_height))
|
||||
if raycast_line_of_sight (origin_eye_pos, targ_feet_height) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- TODO mid way between feet and head
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- check line of sight (BrunoMine)
|
||||
function mob_class:line_of_sight(pos1, pos2, stepsize)
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ mcl_mobs.register_mob("mobs_mc:creeper", {
|
|||
mesh = "mobs_mc_creeper.b3d",
|
||||
head_swivel = "Head_Control",
|
||||
bone_eye_height = 2.35,
|
||||
head_eye_height = 1.8;
|
||||
curiosity = 2,
|
||||
textures = {
|
||||
{"mobs_mc_creeper.png",
|
||||
|
|
Loading…
Reference in a new issue