anchor.diff:    InitQueue(True);
     for I := 0 to Length(InitPointsArr) - 1 do
       with InitPointsArr[I] do
  -    begin
  -      if not CanBeVisited(X,Y,Y*fMapX + X, True) then
  -        FML();
  -      MarkAsVisited(X,Y, InsertInQueue(Y*fMapX + X), 0);
  -    end;
  +      if CanBeVisited(X,Y,Y*fMapX + X, True) then
  +        MarkAsVisited(X,Y, InsertInQueue(Y*fMapX + X), 0);
   
     HouseFF();
   end;
  
positive.code:   for I := 0 to gHands[fOwner].Houses.Count - 1 do
    begin
      H := gHands[fOwner].Houses[I];
      if (H.HouseType in SCANNED_HOUSES) AND not H.IsDestroyed AND H.IsComplete then
      begin
        Result[Cnt] := KMPointBelow(H.Entrance);
        Cnt := Cnt + 1;
  
negative.code:   UNVISITED_TREE_IN_FOREST = 3;
    VISITED_TREE = 4;
    VISITED_TREE_IN_FOREST = 5;
    MAX_SPARE_POINTS = 20;
  var
    PartOfForest: Boolean;
    Ownership, AvoidBulding: Byte;
    RADIUS, MAX_DIST: Word;
    I,X,Y,X2,Y2, Distance, SparePointsCnt: Integer;
    Cnt: Single;
    Point, sumPoint: TKMPoint;
    VisitArr: TKMByte2Array;
    Polygons: TPolygonArray;
  begin
    fBuildFF.UpdateState(); // Mark walkable area in owner's city
    aForests.Clear;
    Polygons := gAIFields.NavMesh.Polygons;
  
    RADIUS := Round(GA_EYE_GetForests_Radius);
    MAX_DIST := RADIUS + 1;
  
    // Init visit array and fill trees
    SetLength(VisitArr, gTerrain.MapY, gTerrain.MapX);
    for Y := 1 to gTerrain.MapY - 1 do
      for X := 1 to gTerrain.MapX - 1 do
      begin
        VisitArr[Y,X] := VISITED_TILE;
        if (BuildFF.VisitIdx = BuildFF.Visited[Y,X])
           AND (BuildFF.State[Y,X] = bsTree) then
        begin
          AvoidBulding := gAIFields.Influences.AvoidBuilding[Y,X];
          if (AvoidBulding < AVOID_BUILDING_FOREST_MINIMUM) then
            VisitArr[Y,X] := UNVISITED_TREE
          else if (AvoidBulding < GA_EYE_GetForests_InflLimit) then
            VisitArr[Y,X] := UNVISITED_TREE_IN_FOREST;
        end;
      end;
  
    for Y := 1 to gTerrain.MapY - 1 do
      for X := 1 to gTerrain.MapX - 1 do
        if ((VisitArr[Y,X] = UNVISITED_TREE) OR (VisitArr[Y,X] = UNVISITED_TREE_IN_FOREST))
           AND (fOwner = gAIFields.Influences.GetBestOwner(X,Y)) then
        begin
          Point := KMPoint(X,Y);
          PartOfForest := False;
          sumPoint := KMPOINT_ZERO;
          Cnt := 0;
          // It is faster to try find points in required radius than find closest points from list of points (when is radius small)
          for Y2 := Max(1, Point.Y-RADIUS) to Min(Point.Y+RADIUS, gTerrain.MapY-1) do
          for X2 := Max(1, Point.X-RADIUS) to Min(Point.X+RADIUS, gTerrain.MapX-1) do
            if (VisitArr[Y2,X2] >= UNVISITED_TREE) then // Detect tree
            begin
              Distance := KMDistanceAbs(Point, KMPoint(X2,Y2));
              if (Distance < MAX_DIST + 1) then // Check distance
              begin
                Cnt := Cnt + 1;
                sumPoint := KMPointAdd(sumPoint, KMPoint(X2,Y2));
                if (VisitArr[Y2,X2] = UNVISITED_TREE) then
                  VisitArr[Y2,X2] := VISITED_TREE
                else if (VisitArr[Y2,X2] = UNVISITED_TREE_IN_FOREST) then
                begin
                  PartOfForest := True;
                  VisitArr[Y2,X2] := VISITED_TREE_IN_FOREST;
                end;
              end;
            end;
          if (Cnt > GA_EYE_GetForests_MinTrees) then
          begin
            Point := KMPoint( Round(sumPoint.X/Cnt), Round(sumPoint.Y/Cnt) );
            aForests.Add( Point, Cardinal(PartOfForest) );
            aForests.Tag2[aForests.Count-1] := Round(Cnt);
          end;
        end;
  
    // Try to find potential forests only in owner's influence areas
    SparePointsCnt := 0;
    for I := 0 to Length(Polygons) - 1 do
    begin
      Ownership := gAIFields.Influences.OwnPoly[fOwner, I];
      if (Ownership > GA_EYE_GetForests_OwnLimit)
         AND (Ownership < GA_EYE_GetForests_RndOwnLim)
         AND (SparePointsCnt < MAX_SPARE_POINTS)
         AND (KaMRandom() > 0.7) then
        begin
          aForests.Add( Polygons[I].CenterPoint, 0 );
          aForests.Tag2[ aForests.Count-1 ] := 0;
          SparePointsCnt := SparePointsCnt + 1;
        end;
    end;
  end;
  
  