Merge pull request 'Massive enderman sight check calculation overhaul' (#1480) from jordan4ibanez/MineClone2-MobTweaks:master into master

Reviewed-on: MineClone2/MineClone2#1480
This commit is contained in:
jordan4ibanez 2021-04-07 01:15:40 +00:00
commit 21334bc49d
1 changed files with 36 additions and 20 deletions

View File

@ -329,29 +329,45 @@ mobs:register_mob("mobs_mc:enderman", {
end end
-- Check to see if people are near by enough to look at us. -- Check to see if people are near by enough to look at us.
for _,obj in pairs(minetest.get_connected_players()) do for _,obj in pairs(minetest.get_connected_players()) do
-- Check if they are looking at us.
--check if they are within radius
local player_pos = obj:get_pos() local player_pos = obj:get_pos()
if player_pos then -- prevent crashing in 1 in a million scenario
local ender_distance = vector.distance(enderpos, player_pos)
if ender_distance <= 64 then
-- Check if they are looking at us.
local look_dir_not_normalized = obj:get_look_dir() local look_dir_not_normalized = obj:get_look_dir()
local look_dir = vector.normalize(look_dir_not_normalized) local look_dir = vector.normalize(look_dir_not_normalized)
local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod. local player_eye_height = obj:get_properties().eye_height
-- Cast up to 64 to see if player is looking at enderman.
for n = 1,64,.25 do --skip player if they have no data - log it
local node = minetest.get_node(look_pos) if not player_eye_height then
if node.name ~= "air" then minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!")
break goto continue
end end
if look_pos.x-1<enderpos.x and look_pos.x+1>enderpos.x and look_pos.y-2.89<enderpos.y and look_pos.y-2>enderpos.y and look_pos.z-1<enderpos.z and look_pos.z+1>enderpos.z then
--calculate very quickly the exact location the player is looking
--within the distance between the two "heads" (player and enderman)
local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z)
local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z)
local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos)
look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player))
--if looking in general head position, turn hostile
if vector.distance(look_pos, ender_eye_pos) <= 0.4 then
self.provoked = "staring" self.provoked = "staring"
self.attack = minetest.get_player_by_name(obj:get_player_name()) self.attack = minetest.get_player_by_name(obj:get_player_name())
break break
else else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez
if self.provoked == "staring" then if self.provoked == "staring" then
self.provoked = "broke_contact" self.provoked = "broke_contact"
end end
end end
look_pos.x = look_pos.x + (.25 * look_dir.x)
look_pos.y = look_pos.y + (.25 * look_dir.y) ::continue:: -- this is a sweep over statement, this can be used to continue even when errors occurred
look_pos.z = look_pos.z + (.25 * look_dir.z) end
end end
end end
-- TAKE AND PLACE STUFF BEHAVIOUR BELOW. -- TAKE AND PLACE STUFF BEHAVIOUR BELOW.