anchor.diff:    SetLength(fForestsInfo.Forests,0);
     fRoadPlanner := TPathFindingCityPlanner.Create(fOwner);
     fRoadShortcutPlanner := TPathFindingShortcutsCityPlanner.Create(fOwner);
  +  fFieldEval := TKMFieldEvaluation.Create(gTerrain.MapX, gTerrain.MapY, fOwner);
   end;
   
   
  
positive.code: {$I KaM_Remake.inc}
  interface
  uses
    Classes, Graphics, KromUtils, Math, SysUtils,
    KM_Defaults, KM_Points, KM_CommonClasses, KM_CommonTypes, KM_CommonUtils,
    KM_TerrainFinder, KM_PerfLog, KM_Houses, KM_ResHouses, KM_ResWares, KM_Sort,
    KM_PathFindingRoad, KM_CityPredictor, KM_Eye,
  
negative.code:         Break;
      end;
    end;
  end;
  }
  
  
  
  procedure TKMCityPlanner.PlanFarmFields(aLoc: TKMPoint; var aNodeList: TKMPointList);
  const
    MAX_DIST = 13;
  var
    Check: Boolean;
    X,Y, X2,Y2: Integer;
    BelowLoc, P, P2: TKMPoint;
    Build: array[-MAX_DIST..MAX_DIST,-MAX_DIST..MAX_DIST] of Boolean;
    Price: TFieldPrice;
    TagList: TKMPointTagList;
    BuildFF: TKMBuildFF;
    {$IFDEF DEBUG_NewAI}
    Time: Cardinal;
    {$ENDIF}
  begin
    {$IFDEF DEBUG_NewAI}
    Time := TimeGet();
    FillChar(DA1, SizeOf(DA1), #0);
    FillChar(DA2, SizeOf(DA2), #0);
    FillChar(DA3, SizeOf(DA3), #0);
    FillChar(DA4, SizeOf(DA4), #0);
  
    FillChar(fFieldPrice, SizeOf(fFieldPrice), #0);
    Price := fFieldPrice;
    {$ENDIF}
  
    BuildFF := gAIFields.Eye.BuildFF;
    BuildFF.UpdateState(); // BuildFF is already updated if Fields are requested in same tick like Farm
    BelowLoc := KMPointBelow(aLoc);
    fFieldEval.EvalField(MAX_DIST,BelowLoc);
  
    // Find build areas
    for Y := -FARM_RADIUS to FARM_RADIUS do
    for X := -FARM_RADIUS to FARM_RADIUS do
    begin
      P := KMPointAdd(KMPoint(X,Y),BelowLoc);
      Build[Y,X] := False;
      if gTerrain.TileInMapCoords(P.X, P.Y) AND (BuildFF.State[P.Y,P.X] in [bsBuild, bsTree] ) then
        Build[Y,X] := True;
    end;
    // Evaluate tpBuild
    with fFieldEval do
      for Y := -FARM_RADIUS+1 to FARM_RADIUS-1 do
      for X := -FARM_RADIUS+1 to FARM_RADIUS-1 do
      begin
        Check := True;
        for Y2 := -1 to 1 do
        for X2 := -1 to 1 do
          if not Check OR not Build[Y+Y2,X+X2] then
          begin
            Check := False;
            break;
          end;
        if Check then
          for Y2 := -1 to 1 do
          for X2 := -1 to 1 do
          begin
            Dec(Price[Y+Y2,X+X2], GA_PLANNER_PlanFarmFields_CanBuild);
          {$IFDEF DEBUG_NewAI}
            P := KMPointAdd(KMPoint(X,Y),BelowLoc);
            if gTerrain.TileInMapCoords(P.X-1, P.Y-1) AND gTerrain.TileInMapCoords(P.X+1, P.Y+1) then
              Inc(DA3[P.Y+Y2,P.X+X2], 40);
          {$ENDIF}
          end;
      end;
  
    //
    with fFieldEval do
      for Y := -FARM_RADIUS to FARM_RADIUS do
      for X := -FARM_RADIUS to FARM_RADIUS do
      begin
        P := KMPointAdd(KMPoint(X,Y),BelowLoc);
        if gTerrain.TileInMapCoords(P.X, P.Y) then
          case FieldEval[Y,X] of
            {$IFDEF DEBUG_NewAI}
            feUnvisitedTile: DA4[P.Y,P.X] := 50;
            feExistingField: DA2[P.Y,P.X] := 100;
            {$ENDIF}
            feFertileTile:
            begin
              Check := false;
              if (Y > -FARM_RADIUS+2) AND (Y < FARM_RADIUS-2) AND (X > -FARM_RADIUS+2) AND (X < FARM_RADIUS-2) then
                for Y2 := -2 to 2 do
                for X2 := -2 to 2 do
                begin
                  P2 := KMPointAdd(KMPoint(X2,Y2),BelowLoc);
                  if Check OR gTerrain.TileInMapCoords(P.X, P.Y) AND (FieldEval[Y+Y2,X+X2] = feFertileTile) then
                  begin
                    Check := True;
                    break;
                  end;
                end;
              Price[Y,X] := Price[Y,X]
                            + GA_PLANNER_PlanFarmFields_Dist * (MAX_DIST - FieldPrice[Y,X])
                            + GA_PLANNER_PlanFarmFields_ExistField * Byte(Check);
            end;
            feObstacle:      begin end;
          end;
      end;
  
    TagList := TKMPointTagList.Create();
    try
      for Y := -FARM_RADIUS to FARM_RADIUS do
      for X := -FARM_RADIUS to FARM_RADIUS do
        if (fFieldEval.FieldEval[Y,X] = feFertileTile) then
        begin
          P := KMPointAdd(KMPoint(X,Y),BelowLoc);
          TagList.Add(P, 20000 + Price[Y,X]);
          {$IFDEF DEBUG_NewAI}
          DA1[P.Y,P.X] := Price[Y,X];
          {$ENDIF}
        end;
      TagList.SortByTag;
      for X := TagList.Count - 1 downto Max(0, TagList.Count - GA_PLANNER_PlanFarmFields_MaxFields) do
        aNodeList.Add(TagList.Items[X]);
    finally
      TagList.Free;
    end;
    {$IFDEF DEBUG_NewAI}
      Time := TimeGet() - Time;
      fTimeSumPlanFields := fTimeSumPlanFields + Time;
      if (Time > fTimePeakPlanFields) then
        fTimePeakPlanFields := Time;
    {$ENDIF}
  end;
  
  
  