Stop farming on detecting strangers and retreat to a secluded place

Script checks for strangers characters, and if they are found, it stops itself and other windows farm, move to a secluded place, kills agro mobs, and waits until the strangers leave. Then returns to the farm.

uses SysUtils;

var        
  Friends: array of string = ['Vasya', 'Petya', 'Kolya'];  // list of nicknames "friends"
  PathFromSpotToSafe: array of integer = [108869, -173711, -579,
                                          108592, -173446, -579,
                                          108211, -173558, -579 ];  // route from spot to safe point
                                          
  PathFromSafeToSpot: array of integer = [108211, -173558, -579,
                                          108592, -173446, -579,
                                          108869, -173711, -579 ];  // route back to spot
    
function CheckStrangers(R: integer = 2000): boolean;
var i: integer;
begin
  result:= false;
  for i:= 0 to CharList.Count-1 do begin
    // ignore party members and players from the list of "friends" (you can also ignore clan and ally members)
    if (CharList(i).IsMember) or StrInArray(CharList(i).Name, Friends) then continue;

    // if a character is found in our spot (+ alternative check by distance)
    if (CharList(i).InZone) or (User.DistTo(CharList(i)) < R) then begin  
      result:= true;
      break;
    end;
  end;  
end;  

function StrInArray(s: string; a: array of string): boolean;   // checks for a string in an array of strings
var i: integer;
begin
  result:= false;
  for i:= Low(a) to High(a) do begin
    if LowerCase(s) = LowerCase(a[i]) then begin
      result:= true;
      break;
    end;
  end;
end;

function HaveAgroMobs(): boolean;                 // the function checks if mobs hang on us
var i: integer;
begin
  result:= false;
  for i:= 0 to NpcList.Count-1 do begin
    if (IsAgr(NpcList(i))) then begin
      result:= true;
      exit;
    end;
  end;
end;

function IsAgr(Mob: TL2Npc): boolean;
begin
  result:= (Mob.Target = User) and (not Mob.Dead);
end;

// https://adrenalinebot.com/ru/api/example/movement-along-a-linear-route-starting-from-the-closest-to-us-point
function PathMoveTo(path: array of integer): boolean;        // movement function on the specified route
var i, start: integer;
begin
  result:= false;
  if (Length(path) >= 3) and (Length(path) mod 3 = 0) then begin
    start:= 0;
    for i:= 0 to Length(path) do begin
      if (i mod 3 <> 0) then continue;
      if (User.DistTo(path[i], path[i+1], path[i+2]) < User.DistTo(path[start], path[start+1], path[start+2])) then start:= i;
    end;
  end else exit;
  for i:= start to Length(path) do begin
    if (i mod 3 <> 0) then continue;
    if (User.Dead) then exit;
    result:= Engine.MoveTo(path[i], path[i+1], path[i+2]);
  end;
end;

begin  
  while delay(555) do begin
    if (Engine.Status = lsOnline) then begin
      // resort to spot, turn on the interface, etc.
      
      if CheckStrangers() then begin            // if you find strangers on our spot, then 
        Engine.Msg('[CheckStrangers]', 'Strangers detected! Departing to a safe place...', 128);
        Engine.FaceControl(1, false);           // turn off combat in the interface
        PathMoveTo(PathFromSpotToSafe);         // moving to a safe point

        while CheckStrangers() and Delay(555) do begin                  // check in the loop if there are any aliens on our spot, and if so
          if (HaveAgroMobs) then begin                                  // if agro mobs are hanging on us, then
            Engine.Msg('[CheckStrangers]', 'Fighting off mobs', 128);
            Engine.FaceControl(1, true);                                // turn on combaat in the interface 
            while (HaveAgroMobs) do delay(555);                         // while there are agro mobs - wait for the bot to kill them
            Engine.FaceControl(1, false);                               // turn off combat in the interface

            // turn off the same interface to our other windows if required
            GetControl('Nickname1').FaceControl(0, false);            
            GetControl('Nickname2').FaceControl(0, false);
          end;
        end;
        Delay(30*1000);   // wait an additional 30 seconds after the departure of other characters
         
        
        // turn on the interface back on our windows
        GetControl('Nickname1').FaceControl(0, true);            
        GetControl('Nickname2').FaceControl(0, true);
        Delay(30*1000);   // wait an additional 30 seconds for the windows to rebuff, etc.

        PathMoveTo(PathFromSafeToSpot);        // back to the spot
        Engine.FaceControl(0, true);           // turn on the interface on the main window
      
      end;
    end;
  end;

end.