anchor.diff:  
       function GetCount: Integer; inline;
       function GetPosition(aIndex: Integer): TKMDefencePosition; inline;
  +    function FindGroupsAroundLoc(aMaxCnt: Byte; aLoc: TKMPoint): TKMUnitGroupArray;
     public
       TroopFormations: array [TKMGroupType] of TKMFormation; //Defines how defending troops will be formatted. 0 means leave unchanged.
   
  
positive.code: end;
  
  
  // Scan defence positions in first line and try find hostile groups in specific radius
  procedure TKMArmyDefence.FindEnemyInDefLine(aEnemyGroups: TKMUnitGroupArray);
  
    function IsCompanyAround(aLoc: TKMPoint): Boolean;
    const
      SQR_MAX_DISTANCE = 20*20;
    var
      I: Integer;
      Company: TAICompany;
  
negative.code:     for I := 0 to fAttack.Count - 1 do
      begin
        Company := fAttack.Company[I];
        if (KMDistanceSqr(aLoc, Company.ScanPosition) < SQR_MAX_DISTANCE)
          OR ((Company.CompanyMode = cm_Defence) AND (KMDistanceSqr(aLoc, Company.TargetPoint) < SQR_MAX_DISTANCE)) then
        begin
          // Actualize target point
          if (Company.CompanyMode = cm_Defence) then
            Company.TargetPoint := aLoc;
          if aRestockCompany AND not RestockCompany(Company) then
          begin
            // Company could not be restocked -> false
          end
          else
            Result := True;
          Exit;
        end;
      end;
    end;
  const
    MAX_GROUPS_PER_COMPANY = 8;
  var
    UGA: TKMUnitGroupArray;
  begin
    Result := IsCompanyAround(aTargetPoint);
    if not Result then
    begin
      UGA := FindGroupsAroundLoc(MAX_GROUPS_PER_COMPANY, aTargetPoint);
      if (Length(UGA) > 0) then
      begin
        fAttack.CreateCompany(aTargetPoint, UGA, cm_Defence);
        Result := True;
      end;
    end;
  end;
  
  
  // Scan defence positions in first line and try find hostile groups in specific radius
  procedure TKMArmyDefence.FindEnemyInDefLine(aEnemyGroups: TKMUnitGroupArray; var aDefRequest: TKMDefendRequest);
    // Add point with enemy presence
    procedure AddTargetPoint(aPoint: TKMPoint; var aCnt: Integer; var aTargetPoints: TKMPointArray);
    const
      SQR_MIN_DISTANCE = 10*10;
    var
      I: Integer;
    begin
      for I := 0 to aCnt - 1 do
        if (KMDistanceSqr(aTargetPoints[I],aPoint) < SQR_MIN_DISTANCE) then
          Exit;
      aTargetPoints[aCnt] := aPoint;
      Inc(aCnt);
    end;
    // Add request for help
    procedure AddDefRequest(aLoc: TKMPoint);
    begin
      with aDefRequest do
      begin
        if (PointsCnt >= Length(Points)) then
          SetLength(Points, PointsCnt + 10);
        Points[PointsCnt] := aLoc;
        Inc(PointsCnt);
      end;
    end;
  var
    I, Idx, Cnt: Integer;
    Loc: TKMPoint;
    Group: TKMUnitGroup;
    GT: TKMGroupType;
    TargetPoints: TKMPointArray;
    UGA: TKMUnitGroupArray;
  begin
    aDefRequest.PointsCnt := 0;
    Cnt := 0;
    SetLength(TargetPoints,fFirstLineCnt + Length(aEnemyGroups));
    // Check defensive line
    for I := 0 to fPositions.Count - 1 do
      if (Positions[I].Line = 0) then
      begin
        Loc := Positions[I].Position.Loc;
        Idx := gAIFields.NavMesh.KMPoint2Polygon[Loc];
        for GT := Low(TKMGroupType) to High(TKMGroupType) do
          if (gAIFields.Influences.EnemyGroupPresence[ fOwner, Idx, GT ] > 0) then
          begin
            UGA := gHands.GetGroupsInRadius(Loc, SQR_FIRST_LINE_RADIUS, fOwner, at_Enemy);
            if (Length(UGA) > 0) then
              AddTargetPoint(Loc, Cnt, TargetPoints);
            break;
          end;
      end;
    // Check every group
    for I := 0 to Length(aEnemyGroups) - 1 do
    begin
      Group := aEnemyGroups[I];
      if (Group <> nil) AND not Group.IsDead then
        AddTargetPoint(Group.Position, Cnt, TargetPoints);
    end;
    // Try find existing defensive platoons or create new
    for I := 0 to Cnt - 1 do
      if not DefendPoint(TargetPoints[I], True) then
        AddDefRequest(TargetPoints[I]);
    fCityUnderAttack := (Cnt > 0);
  end;
  
  
  