From 1749712318b0b71969cb77921e13de21780c882f Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Thu, 31 Aug 2023 23:12:30 +0100 Subject: [PATCH 1/2] Change creepers line of sight check to raycast and do it from eyes to targets feet and head --- mods/ENTITIES/mcl_mobs/combat.lua | 3 +- mods/ENTITIES/mcl_mobs/movement.lua | 76 +++++++++++++++++++++++++++++ mods/ENTITIES/mobs_mc/creeper.lua | 1 + 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/combat.lua b/mods/ENTITIES/mcl_mobs/combat.lua index 836f53753..4b3393e36 100644 --- a/mods/ENTITIES/mcl_mobs/combat.lua +++ b/mods/ENTITIES/mcl_mobs/combat.lua @@ -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 diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua index 317ac9f28..46c470a15 100644 --- a/mods/ENTITIES/mcl_mobs/movement.lua +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -76,6 +76,82 @@ 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 + --minetest.log(dump(hitpoint.type)) + + local node = minetest.get_node(minetest.get_pointed_thing_position(hitpoint)) + + --minetest.log("ray node:" .. node.name) + + if node.name ~= "air" then + local nodef = minetest.registered_nodes[node.name] + if nodef and nodef.walkable then + --minetest.log("walkable:" .. tostring(nodef.walkable)) + los_blocked = true + break + end + end + end + end + --minetest.log("los_blocked: " .. tostring(los_blocked)) + --minetest.log("visible: " .. tostring(not los_blocked)) + + 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 + + --local target_line_of_sight = self:line_of_sight(origin_eye_pos, targ_head_height, 2) + --local target_line_of_sight_feet = self:line_of_sight(origin_eye_pos, targ_feet_height, 2) + + --minetest.log("target_line_of_sight: " .. tostring(target_line_of_sight)) + --minetest.log("target_line_of_sight_feet: " .. tostring(target_line_of_sight_feet)) + + --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 + + --minetest.log("target is not visible so return false") + return false +end + -- check line of sight (BrunoMine) function mob_class:line_of_sight(pos1, pos2, stepsize) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index f751b1240..72661971e 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -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", From 969a08b7befe801e0d3d8658b5307f3917bc4a9a Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Thu, 31 Aug 2023 23:15:36 +0100 Subject: [PATCH 2/2] Clean up --- mods/ENTITIES/mcl_mobs/movement.lua | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua index 46c470a15..ff9a38f56 100644 --- a/mods/ENTITIES/mcl_mobs/movement.lua +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -85,25 +85,17 @@ local function raycast_line_of_sight (origin, target) for hitpoint in raycast do if hitpoint.type == "node" then --TODO type object could block vision, for example chests - --minetest.log(dump(hitpoint.type)) - local node = minetest.get_node(minetest.get_pointed_thing_position(hitpoint)) - --minetest.log("ray node:" .. node.name) - if node.name ~= "air" then local nodef = minetest.registered_nodes[node.name] if nodef and nodef.walkable then - --minetest.log("walkable:" .. tostring(nodef.walkable)) los_blocked = true break end end end end - --minetest.log("los_blocked: " .. tostring(los_blocked)) - --minetest.log("visible: " .. tostring(not los_blocked)) - return not los_blocked end @@ -130,12 +122,6 @@ function mob_class:target_visible(origin) targ_feet_height = vector.offset(target_pos, 0, self.collisionbox[2], 0) end - --local target_line_of_sight = self:line_of_sight(origin_eye_pos, targ_head_height, 2) - --local target_line_of_sight_feet = self:line_of_sight(origin_eye_pos, targ_feet_height, 2) - - --minetest.log("target_line_of_sight: " .. tostring(target_line_of_sight)) - --minetest.log("target_line_of_sight_feet: " .. tostring(target_line_of_sight_feet)) - --minetest.log("start targ_head_height: " .. dump(targ_head_height)) if raycast_line_of_sight (origin_eye_pos, targ_head_height) then return true @@ -148,7 +134,6 @@ function mob_class:target_visible(origin) -- TODO mid way between feet and head - --minetest.log("target is not visible so return false") return false end