From ac08c6991c0ce7f9bb8d9de5880ec64a7882c3e7 Mon Sep 17 00:00:00 2001 From: jordan4ibanez Date: Tue, 20 Apr 2021 16:39:05 -0400 Subject: [PATCH] Add in detect_players_in_area --- .../mcl_mobs/api/mob_functions/ai.lua | 9 ++- .../api/mob_functions/environment.lua | 61 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua index 1c40461889..ae28c8cdbc 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua @@ -597,7 +597,14 @@ mobs.mob_step = function(self, dtime) if self.hostile then - print("I'm a bad boi") + --true for line_of_sight is debug + --10 for radius is debug + --1 for eye height adjust is debug + local attacking = mobs.detect_players_in_area(self,true,10,1) + + if attacking then + print(attacking:get_player_name()) + end end -- can mob be pushed, if so calculate direction -- do this last (overrides everything) diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua index 082e88543f..7935dc7cc1 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/environment.lua @@ -1,3 +1,7 @@ +local minetest_line_of_sight = minetest.line_of_sight + +local vector_new = vector.new + -- default function when mobs are blown up with TNT local do_tnt = function(obj, damage) @@ -9,4 +13,61 @@ local do_tnt = function(obj, damage) return false, true, {} end +--a fast function to be able to detect only players without using objects_in_radius +mobs.detect_players_in_area = function(self, line_of_sight, radius, object_height_adder) + + line_of_sight = line_of_sight or true --fallback line_of_sight + radius = radius or 10 -- fallback radius + object_height_adder = object_height_adder or 0 --fallback entity (y height) addition for line of sight + local pos1 = self.object:get_pos() + local players_in_area = {} + local winner_player = nil + local players_detected = 0 + + --get players in radius + for _,player in pairs(minetest.get_connected_players()) do + if player and player:get_hp() > 0 then + + local pos2 = player:get_pos() + + local distance = vector.distance(pos1,pos2) + + if distance <= radius then + if line_of_sight then + --must add eye height or stuff breaks randomly because of + --seethrough nodes being a blocker (like grass) + if minetest_line_of_sight( + vector_new(pos1.x, pos1.y + object_height_adder, pos1.z), + vector_new(pos2.x, pos2.y + player:get_properties().eye_height, pos2.z) + ) then + players_detected = players_detected + 1 + players_in_area[player] = distance + end + else + players_detected = players_detected + 1 + players_in_area[player] = distance + end + end + end + end + + + --return if there's no one near by + if players_detected <= 0 then --handle negative numbers for some crazy error that could possibly happen + return nil + end + + --do a default radius max + local shortest_disance = radius + 1 + + --sort through players and find the closest player + for player,distance in pairs(players_in_area) do + if distance < shortest_disance then + shortest_disance = distance + winner_player = player + end + end + + return(winner_player) +end