anchor.diff:        FillResource.Free;
       end;
   
  -    MarkEdges(CountArr);
  +    ProtectResourceArea(CountArr);
     end;
     //}
   
     if RMGSettings.Obstacle.Active then
  -    CreateObstacles(Locs, A,  Voronoi,  PointsArr);
  +    CreateObstacles(Locs, A,  Voronoi, CountArr, PointsArr);
   
   end;
   //}
  
positive.code:                + HNST[ TileTempl[Y1,X2] ][ TileTempl[Y2,X2] ]
                 + HNST[ TileTempl[Y2,X1] ][ TileTempl[Y2,X2] ];
          if (sum > 0) then
            TilesPartsArr.Height[Y_1,X_1] := Max(0, H1[Y_1,X_1] + H2[Y_1,X_1] - sum);
        end;
      // Change height of water
      {
        if (A[Y_1,X_1] = Byte(btWater)) then
        begin
          sum :=   Byte(A[Y_2,X_1] = Byte(btWater))
                 + Byte(A[Y_0,X_1] = Byte(btWater))
                 + Byte(A[Y_1,X_2] = Byte(btWater))
                 + Byte(A[Y_1,X_0] = Byte(btWater))
                 + Byte(A[Y_2,X_2] = Byte(btWater))
                 + Byte(A[Y_2,X_0] = Byte(btWater))
                 + Byte(A[Y_0,X_2] = Byte(btWater))
                 + Byte(A[Y_0,X_0] = Byte(btWater));
          TilesPartsArr.Height[Y_1,X_1] := Max(0,TilesPartsArr.Height[Y_1,X_1] - (sum * 2));
        end;
        }
  
      end;
    end;
  end;
  
  
  //procedure TKMRandomMapGenerator.GenerateHeight(aLocs: TKMPointArray; var TilesPartsArr: TTileParts; var A: TKMByte2Array; var TileTempl: TKMByte2Array);
  //const
  //  HeightMix: array [0..23] of Byte = (
  //    //20,18,15,15,15,21,19,22,23,24,25,20,20,19,18,17,18,21,20,20,20,20,20,20
  //    10,10,5,5,3,5,10,1,10,10,20,20,0,5,10,10,15,20,10,20,20,20,20,0
  //  );
  //  //TBiomeType = (
  //  //10,15,0,0,0,10,5,0,15,15,20,20,10,5,btGrassSand1,btGrassSand2,btGrassSand3,btSand,btStone,btGold,btEgold,btIron,btEIron,btDark);
  //
  //  HeightVariance: array [0..23] of Byte = (
  //    10,10,5,5,3,5,10,10,10,10,20,20,0,5,10,10,15,20,10,20,20,0,0,0
  //  );
  //  HNST: array[0..23,0..23] of Byte = ( // Hide Non-Smooth Transition (height fix)
  //    (0,0,0,2,3,5,2,5,1,5,5,5,5,3,1,4,3,4,0,0,0,0,0,0),
  //    (0,0,0,2,3,5,2,5,1,5,5,5,5,3,1,4,3,4,0,0,0,0,0,0),
  //    (0,0,0,2,0,5,2,3,2,5,5,5,5,2,1,2,3,4,0,0,0,0,0,0),
  //    (2,2,2,0,3,5,0,1,2,5,5,5,5,3,3,3,4,5,0,0,0,0,0,0),
  //    (3,3,0,3,0,5,3,3,3,3,5,5,5,3,3,3,3,3,0,0,0,0,0,0),
  //    (5,5,5,5,5,0,2,0,0,5,5,5,5,4,4,4,4,4,0,0,0,0,0,0),
  //    (2,2,2,0,3,2,0,0,0,5,5,5,5,5,5,5,5,3,0,0,0,0,0,0),
  //    (5,5,3,1,3,0,0,0,5,5,5,5,5,4,4,4,4,3,0,0,0,0,0,0),
  //    (1,1,2,2,3,0,0,5,0,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0),
  //    (5,5,5,5,3,5,5,5,5,0,5,5,5,5,5,5,5,5,0,0,0,0,0,0),
  //    (5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,5,0,0,0,0,0,0),
  //    (5,5,5,5,5,5,5,5,5,5,5,0,5,5,5,5,5,5,0,0,0,0,0,0),
  //    (5,5,5,5,5,5,5,5,5,5,5,5,0,3,3,3,3,3,0,0,0,0,0,0),
  //    (3,3,2,3,3,4,5,4,5,5,5,5,3,0,0,0,0,0,0,0,0,0,0,0),
  //    (1,1,1,3,3,4,5,4,5,5,5,5,3,0,0,0,0,0,0,0,0,0,0,0),
  //    (4,4,2,3,3,4,5,4,5,5,5,5,3,0,0,0,0,0,0,0,0,0,0,0),
  //    (3,3,3,4,3,4,5,4,5,5,5,5,3,0,0,0,0,0,0,0,0,0,0,0),
  //    (4,4,4,5,3,4,3,3,5,5,5,5,3,0,0,0,0,0,0,0,0,0,0,0),
  //    (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
  //    (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,100,0),
  //    (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,100,0),
  //    (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,100,0,0,0),
  //    (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,100,0,0,0),
  //    (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  //  );
  //var
  //  X,Y,I,MaxCnt,X_0,Y_0,X_1,Y_1,X_2,Y_2,X0,X1,X2,Y0,Y1,Y2,sum: Integer;
  //  Factor,Probability, ProbabilityReducer: Single;
  //  P: TSingle2Array;
  //  H1,H2, H3,H4: TInteger2Array;
  //  FillHeight: TKMFillBiome;
  //begin
  //
  //// Initialization
  //  SetLength(P, Length(A), Length(A[Low(A)]));
  //  for Y := Low(P) to High(P) do
  //    for X := Low(P[Y]) to High(P[Y]) do
  //      P[Y,X] := 1;
  //
  //  // Create protected radius = array with smaller chance to spawn obstacle near aLocs
  //  if RMGSettings.Locs.Resource.Active then
  //  begin
  //    ProbabilityReducer := (11 - RMGSettings.Obstacle.ProtectedRadius) * 0.02;
  //    MaxCnt := Round(1 / ProbabilityReducer);
  //    for I := Low(aLocs) to High(aLocs) do
  //      for Y := Max(  Low(P), aLocs[I].Y - MaxCnt  ) to Min(  High(P), aLocs[I].Y + MaxCnt  ) do
  //        for X := Max(  Low(P[Y]), aLocs[I].X - MaxCnt  ) to Min(  High(P[Y]), aLocs[I].X + MaxCnt  ) do
  //        begin
  //          Probability := KMLengthDiag(X,Y,aLocs[I]) * ProbabilityReducer;
  //          if (P[Y,X] > Probability) then
  //            P[Y,X] := Probability;
  //        end;
  //  end;
  //
  //  H1 := LinearInterpolation(7,20);
  //  H2 := LinearInterpolation(5,40);
  //  H3 := LinearInterpolation(8,80);
  //  H4 := LinearInterpolation(6,80);
  //	for Y1 := 1 to gTerrain.MapY-1 do
  //    for X1 := 1 to gTerrain.MapX-1 do
  //    begin
  //      //TilesPartsArr.Height[Y1,X1] := Max(0,   H1[Y1,X1] + H2[Y1,X1] + Round((H3[Y1,X1] - H4[Y1,X1]) * P[Y1,X1])  + fRNG.RandomI(HeightVariance[ A[Y1,X1] ])   );
  //      TilesPartsArr.Height[Y1,X1] := H1[Y1,X1] + H2[Y1,X1] + HeightMix[ A[Y1,X1] ]*2 + fRNG.RandomI(HeightVariance[ A[Y1,X1] ]);
  //    end;
  //
  //  //constructor Create(aMinLimit, aMaxLimit: TKMPoint; var aSearchArr: TInteger2Array; var aFillArr: TKMByte2Array; const aScanEightTiles: Boolean = False); reintroduce;
  //  //procedure QuickFlood(aX,aY,aSearch,aNewSearch,aFill: SmallInt); reintroduce;
  //  //FillHeight := TKMFillBiome.Create();
  //  //try
  //
  //  //finally
  //  //  Fillheight.Free;
  //  //end;
  //
  //  for Y_1 := 1 to gTerrain.MapY-1 do
  //  begin
  //    Y2 := Y_1 shl 1;
  //    Y1 := Y2 - 1;
  //    Y_0 := Max(0, Y_1 - 2);
  //    Y_2 := Min(gTerrain.MapY, Y_1 + 1);
  //    for X_1 := 1 to gTerrain.MapX-1 do
  //    begin
  //      X2 := X_1 shl 1;
  //      X1 := X2 - 1;
  //      X_0 := Max(0, X_1 - 2);
  //      X_2 := Min(gTerrain.MapX, X_1 + 1);
  //
  //      // Mountains
  //      if (A[Y_1,X_1] >= Byte(btStone)) then
  //      begin
  //        if A[Y_1,X_1] = Byte(btStone) then
  //          sum := + Byte(A[Y_0,X_0] = A[Y_1,X_1])
  //                 + Byte(A[Y_0,X_1] = A[Y_1,X_1])
  //                 + Byte(A[Y_0,X_2] = A[Y_1,X_1])
  //                 + Byte(A[Y_1,X_2] = A[Y_1,X_1])
  //                 + Byte(A[Y_1,X_0] = A[Y_1,X_1])
  //                 + Byte(A[Y_2,X_0] = A[Y_1,X_1])
  //                 + Byte(A[Y_2,X_1] = A[Y_1,X_1])
  //                 + Byte(A[Y_2,X_2] = A[Y_1,X_1])
  //        else
  //          sum := + Byte(A[Y_0,X_0] >= A[Y_1,X_1])
  //                 + Byte(A[Y_0,X_1] >= A[Y_1,X_1])
  //                 + Byte(A[Y_0,X_2] >= A[Y_1,X_1])
  //                 + Byte(A[Y_1,X_2] >= A[Y_1,X_1])
  //                 + Byte(A[Y_1,X_0] >= A[Y_1,X_1])
  //                 + Byte(A[Y_2,X_0] >= A[Y_1,X_1])
  //                 + Byte(A[Y_2,X_1] >= A[Y_1,X_1])
  //                 + Byte(A[Y_2,X_2] >= A[Y_1,X_1]);
  //        if (sum = 8) then
  //          TilesPartsArr.Height[Y_1,X_1] := fRNG.RandomI(70)+30;
  //      end;
  //      //else if (TilesPartsArr.Obj[Y_1,X_1] = 61) AND (  (A[Y_1,X_1] = Byte(btGroundSnow)) OR (A[Y_1,X_1] = Byte(btSnow1)) OR (A[Y_1,X_1] = Byte(btSnow2))  ) then
  //        //TilesPartsArr.Height[Y_1,X_1] := fRNG.RandomI(30)+60;
  //
  //    // Set lower height to non-smooth transitions (hide it)
  //      if RMGSettings.Height.HideNonSmoothTransition then
  //      begin
  //        sum := + HNST[ TileTempl[Y1,X1] ][ TileTempl[Y2,X1] ]
  //               + HNST[ TileTempl[Y1,X1] ][ TileTempl[Y1,X2] ]
  //               + HNST[ TileTempl[Y1,X2] ][ TileTempl[Y2,X2] ]
  //               + HNST[ TileTempl[Y2,X1] ][ TileTempl[Y2,X2] ];
  //        if (sum > 0) then
  //          TilesPartsArr.Height[Y_1,X_1] := Max(0, H1[Y_1,X_1] + H2[Y_1,X_1] - sum);
  //      end;
  //    // Change height of water
  //    {
  //      if (A[Y_1,X_1] = Byte(btWater)) then
  //      begin
  //        sum :=   Byte(A[Y_2,X_1] = Byte(btWater))
  //               + Byte(A[Y_0,X_1] = Byte(btWater))
  //               + Byte(A[Y_1,X_2] = Byte(btWater))
  //               + Byte(A[Y_1,X_0] = Byte(btWater))
  //               + Byte(A[Y_2,X_2] = Byte(btWater))
  //               + Byte(A[Y_2,X_0] = Byte(btWater))
  //               + Byte(A[Y_0,X_2] = Byte(btWater))
  //               + Byte(A[Y_0,X_0] = Byte(btWater));
  //        TilesPartsArr.Height[Y_1,X_1] := Max(0,TilesPartsArr.Height[Y_1,X_1] - (sum * 2));
  //      end;
  //      }
  //
  //    end;
  //  end;
  //end;
  
  
  
  
negative.code:                  + Byte(A[Y_2,X_1] = A[Y_1,X_1])
                   + Byte(A[Y_2,X_2] = A[Y_1,X_1])
          else
            sum := + Byte(A[Y_0,X_0] >= Byte(btStone))
                   + Byte(A[Y_0,X_1] >= Byte(btStone))
                   + Byte(A[Y_0,X_2] >= Byte(btStone))
                   + Byte(A[Y_1,X_2] >= Byte(btStone))
                   + Byte(A[Y_1,X_0] >= Byte(btStone))
                   + Byte(A[Y_2,X_0] >= Byte(btStone))
                   + Byte(A[Y_2,X_1] >= Byte(btStone))
                   + Byte(A[Y_2,X_2] >= Byte(btStone));
          if (sum = 8) then
            TilesPartsArr.Height[Y_1,X_1] := fRNG.RandomI(70)+30;
        end;
  
      // Set lower height to non-smooth transitions (hide it)
        if RMGSettings.Height.HideNonSmoothTransition then
  