anchor.diff:        else
           Result := True;
     end;
  -var
  -  SquadsAreReady: Boolean;
  +  // Check if are all squads in position and we can continue
  +  function SquadsInPosition(): Boolean;
  +  var
  +    I: Integer;
  +    GT: TGroupType;
  +    Squad: TAISquad;
  +  begin
  +    Result := True;
  +    for GT := Low(TGroupType) to High(TGroupType) do
  +      for I := fSquads[GT].Count - 1 downto 0 do
  +      begin
  +        Squad := fSquads[GT].Items[I];
  +        if (Squad = nil) OR (Squad.Group = nil) OR Squad.Group.IsDead then
  +          fSquads[GT].Delete(I)
  +        else
  +          Result := Result AND Squad.OnPlace;
  +      end;
  +  end;
  +  // Update state of Squads
  +  procedure UpdateSquadsState();
  +  var
  +    I: Integer;
  +    GT: TGroupType;
  +  begin
  +    for GT := Low(TGroupType) to High(TGroupType) do
  +      for I := fSquads[GT].Count - 1 downto 0 do
  +        TAISquad( fSquads[GT].Items[I] ).UpdateState(aTick);
  +  end;
  +var
     I: Integer;
  +  SQRRadius: Single;
     GT: TGroupType;
     HA: TKMHouseArray;
  +  UA: TKMUnitArray;
     UGA: TKMUnitGroupArray;
     ClosestHouse: TKMHouse;
     ClosestUnit: TKMUnit;
  -  Squad: TAISquad;
  -begin
  -  // Check Squads
  -  SquadsAreReady := True;
  -  for GT := Low(TGroupType) to High(TGroupType) do
  -    for I := fSquads[GT].Count - 1 downto 0 do
  -    begin
  -      Squad := fSquads[GT].Items[I];
  -      if (Squad = nil) OR (Squad.Group = nil) OR Squad.Group.IsDead then
  -        fSquads[GT].Delete(I)
  -      else
  -        SquadsAreReady := SquadsAreReady AND Squad.IsReady;
  -    end;
  -
  +begin
     if (SquadCnt = 0) then
       Exit;
   
     // Check target
     ClosestHouse := nil;
     ClosestUnit := nil;
  -  //ClosestHouse := gHands.GetClosestHouse(ScanPosition, fOwner, at_Enemy);
  -  //ClosestUnit := gHands.GetClosestUnit(ScanPosition, fOwner, at_Enemy);
  -  HA := gHands.GetHousesInRadius(ScanPosition, SQR_COMPANY_ATTACK_RAD, fOwner, at_Enemy, TARGET_HOUSES, True);
  -  UGA := gHands.GetGroupsInRadius(ScanPosition, SQR_COMPANY_ATTACK_RAD, fOwner, at_Enemy);
  +
  +  fScanPosition := GetPosition(SQRRadius);
  +  ScanRad := SQR_COMPANY_ATTACK_RAD + Min(SQR_MAXIMAL_ATTACK_VAR_RAD, SQRRadius);
  +  HA := gHands.GetHousesInRadius(ScanPosition, SQR_COMPANY_ATTACK_RAD, fOwner, at_Enemy, SCAN_HOUSES, True);
  +  //UGA := gHands.GetGroupsInRadius(ScanPosition, SQR_COMPANY_ATTACK_RAD, fOwner, at_Enemy);
  +  UA := gHands.GetGroupsMemberInRadius(ScanPosition, ScanRad, fOwner, at_Enemy, UGA);
  +
  +  SetLength(DEBUG_UA_POINTS, Length(UA));
  +  SetLength(DEBUG_UGA_POINTS, Length(UA));
  +  for I := 0 to Length(UA) - 1 do
  +  begin
  +    DEBUG_UA_POINTS[I] := UA[I].GetPosition;
  +    DEBUG_UGA_POINTS[I] := UGA[I].Position;
  +  end;
  +
  +  // Actualize target
     if not CheckPrimaryTarget() then
     begin
  -    if (Length(UGA) > 0) then
  -      ClosestUnit := UGA[0].GetAliveMember;
  +    if (Length(UA) > 0) then
  +      ClosestUnit := UA[0];
       if (Length(HA) > 0) then
         ClosestHouse := HA[0];
       if not SetTarget(ClosestHouse, ClosestUnit) then
  -      Exit;
  +    begin
  +      if ActualizeTarget(fScanPosition, ClosestHouse, ClosestUnit, False) then
  +        SetTarget(ClosestHouse, ClosestUnit);
  +    end;
     end;
   
     // Give new orders
  -  if (Length(UGA) > 0) then
  -    OrderToAttack(ScanPosition, UGA, HA, False)
  -  else if (Length(HA) > 0) then
  -    OrderToAttack(ScanPosition, UGA, HA, True)
  -  else if SquadsAreReady then
  -    OrderMove(PathPosition);
  -
  -  // Update state of Squads
  -  for GT := Low(TGroupType) to High(TGroupType) do
  -    for I := fSquads[GT].Count - 1 downto 0 do
  -    begin
  -      Squad := fSquads[GT].Items[I];
  -      Squad.UpdateState(aTick);
  -    end;
  -end;
  -
  -
  -procedure TAICompany.OrderToAttack(aActualPosition: TKMPoint; UGA: TKMUnitGroupArray; HA: TKMHouseArray; aTargetHouse: Boolean);
  -  //function HouseTypeCnt(aHT: THouseType): Word;
  -  //var
  -  //  I: Integer;
  -  //begin
  -  //  Result := 0;
  -  //  for I := Low(HA) to High(HA) do
  -  //    if (HA[I].HouseType = aHT) then
  -  //      Result := Result + 1;
  -  //end;
  -  //function TargetHouses();
  -  //const
  -  //  IGNORE_TOWER_CNT = 3;
  -  //  ANTI_TOWER_TYPE = gt_Ranged;
  -  //var
  -  //  I: Integer;
  -  //  BestDistSqr, DistSqr: Single;
  -  //  BestSquad,Squad: TAISquad;
  -  //  GT: TGroupType;
  -  //  aGroups: set of TGroupType;
  -  //begin
  -  //  for I := Low(HA) to High(HA) do
  -  //  begin
  -  //    if (HA[I].HouseType = aHT) then
  -  //      aGroups := [ANTI_TOWER_TYPE];
  -  //    for GT in aGroups do
  -  //    begin
  -  //      BestDistSqr := 1000000;
  -  //      for I := 0 to fSquads[GT].Count - 1 do
  -  //      begin
  -  //        Squad := fSquads[GT].Items[I];
  -  //        DistSqr := Squad.TargetUnit := ;
  -  //        Idx := Idx + 1;
  -  //      end;
  -  //    end;
  -  //  end;
  -  //end;
  -var
  -  TowersCnt, BarrackCnt: Word;
  -  I, Idx: Integer;
  -  GT: TGroupType;
  -  Squad: TAISquad;
  -begin
  -  // Attack houses in radius
  -  if aTargetHouse then
  -  begin
  -    //if (HouseTypeCnt(ht_Barracks) > 0) then
  -    //  TargetHouses([gt_Melee, gt_]);
  -    //
  -    //TowersCnt := HouseTypeCnt(ht_WatchTower);
  -    //// Ignore towers in case that
  -    //if (TowersCnt <= IGNORE_TOWER_CNT) OR (fSquads[ANTI_TOWER_TYPE].Count = 0) then
  -    //  OrderMove(ActualPosition);
  +  if not OrderToAttack(ScanPosition, UA, UGA, HA) then
  +  begin
  +    fState := cs_Walking;
  +    if SquadsInPosition() then
  +    begin
  +      if not OrderMove(PathPosition) then
  +        fState := cs_Idle;
  +    end;
  +  end
  +  else
  +    fState := cs_Attack;
  +
  +  UpdateSquadsState();
  +end;
  +
  +
  +function TAICompany.OrderToAttack(aActualPosition: TKMPoint; UA: TKMUnitArray; UGA: TKMUnitGroupArray; HA: TKMHouseArray): Boolean;
  +var
  +  AvaiableSquads: TKMSquadsArray;
  +  //fTargetU: TKMTargetSelection;
  +
  +  procedure FindAvaiableSquads();
  +  var
  +    I: Integer;
  +    GT: TGroupType;
  +    Squad: TAISquad;
  +  begin
  +    for GT := Low(TGroupType) to High(TGroupType) do
  +    begin
  +      AvaiableSquads[GT].Count := 0;
  +      SetLength(AvaiableSquads[GT].Squads, fSquads[GT].Count);
  +    end;
       for GT := Low(TGroupType) to High(TGroupType) do
         for I := 0 to fSquads[GT].Count - 1 do
         begin
           Squad := fSquads[GT].Items[I];
  -        Squad.TargetHouse := HA[ KaMRandom(Length(HA)) ];
  +        if not Squad.InFight then
  +        begin
  +          // Make sure that unit will not hunt target over the whole map and better stay inside company
  +          if (GT <> gt_Ranged) then // ranged units are fixed in Squad class (set / reset target cause that they dont shoot)
  +          begin
  +            Squad.TargetUnit := nil;
  +            //Squad.TargetHouse := nil; // This cause same problem like with archers
  +          end;
  +          AvaiableSquads[GT].Squads[ AvaiableSquads[GT].Count ] := Squad;
  +          AvaiableSquads[GT].Count := AvaiableSquads[GT].Count + 1;
  +        end;
         end;
  -  end
  -  else
  -  begin
  -    Idx := 0;
  +  end;
  +
  +  procedure EvalEnemyGroupsInRadius();
  +  const
  +    INIT_DIST = 1000000;
  +    SQR_MAX_RANGE_INTEREST = 12*12;
  +    SQR_RANGE_OF_PROJECTILES = 11*11; // Sqr(  Max( Max(RANGE_BOWMAN_MAX,RANGE_ARBALETMAN_MAX),RANGE_SLINGSHOT_MAX )  );
  +    SQR_RANGED_PROTECT_RADIUS = 7*7; // Radius around ranged units where requires close combat protection
  +  var
  +    Polygon: Word;
  +    I,K,L: Integer;
  +    SqrDist, SqrClosestDist, SqrClosestDistToRanged: Single;
  +    GT: TGroupType;
  +    Squad: TAISquad;
  +    GroupsInFightArr: TKMUnitGroupArray;
  +  begin
  +    SetLength(fTargetU, Length(UA));
  +    for I := 0 to Length(fTargetU) - 1 do
  +    begin
  +      // Get closest distance to Ranged groups and all groups
  +      SqrClosestDist := INIT_DIST;
  +      SqrClosestDistToRanged := INIT_DIST;
  +      for GT := Low(TGroupType) to High(TGroupType) do
  +        for K := 0 to fSquads[GT].Count - 1 do
  +        begin
  +          Squad := fSquads[GT].Items[K];
  +          L := 0;
  +          while (L < Squad.Group.Count - 1) do
  +          begin
  +            SqrDist := KMDistanceSqr(Squad.Group.Members[L].GetPosition, UA[I].GetPosition);
  +            if (SqrDist < SqrClosestDist) then
  +              SqrClosestDist := SqrDist;
  +            if (GT = gt_Ranged) AND (SqrDist < SqrClosestDistToRanged) then
  +              SqrClosestDistToRanged := SqrDist;
  +            L := L + 3;
  +          end;
  +        end;
  +
  +      // Calculate threat level
  +      with fTargetU[I] do
  +      begin
  +        Index := I;
  +        CenterPoint := UGA[I].Position;
  +        CloseThreat := 0;
  +        DistantThreat := 0;
  +        if (SqrClosestDist < SQR_MAX_RANGE_INTEREST) then
  +        begin
  +          CloseThreat := UGA[I].Count; // Threat level for close combat units
  +          DistantThreat := CloseThreat; // Threat level for ranged group type
  +          if (UGA[I].GroupType = gt_Ranged) then
  +          begin
  +            // Calculate distant threat level (determine whether archers are shooting at our troops)
  +            DistantThreat := DistantThreat * Byte(SQR_RANGE_OF_PROJECTILES > SqrClosestDist);
  +            // Close threat level is computed with using influences
  +            Polygon := gAIFields.NavMesh.KMPoint2Polygon[ UGA[I].Position ];
  +            for GT := Low(TGroupType) to High(TGroupType) do
  +              if (GT <> gt_Ranged) then
  +                CloseThreat := CloseThreat + gAIFields.Influences.EnemyGroupPresence[fOwner, Polygon, GT]; // Tune parameters
  +            if (DistantThreat < CloseThreat) then
  +              CloseThreat := 0
  +            else
  +              DistantThreat := 0;
  +          end
  +          else
  +          begin
  +            // Close combat threat level (in case that group already fight agaist more soldiers there is 0 threat)
  +            // In case that group kills ranged units threat must be increased
  +            CloseThreat := CloseThreat + Byte(SQR_RANGED_PROTECT_RADIUS < SqrClosestDistToRanged) * (SQR_RANGED_PROTECT_RADIUS - SqrClosestDistToRanged);
  +            if UGA[I].InFightAgaistGroups(GroupsInFightArr) then
  +              for K := 0 to Length(GroupsInFightArr) - 1 do
  +                if (GroupsInFightArr[K].GroupType = gt_Ranged) then
  +                  CloseThreat := CloseThreat + GroupsInFightArr[K].Count
  +                else
  +                  CloseThreat := CloseThreat - GroupsInFightArr[K].Count;
  +          end;
  +        end;
  +      end;
  +    end;
  +  end;
  +
  +  function SelectTargetGroups(): Boolean;
  +  const
  +    INIT_THREAT = -1000000;
  +    BEST_TARGET: array[TGroupType] of array[0..3] of TGroupType = (
  +        (gt_Melee, gt_Ranged, gt_Mounted, gt_AntiHorse), // against gt_Melee
  +        (gt_Melee, gt_Ranged, gt_AntiHorse, gt_Mounted), // against gt_AntiHorse
  +        (gt_Mounted, gt_Ranged, gt_Melee, gt_AntiHorse), // against gt_Ranged
  +        (gt_AntiHorse, gt_Ranged, gt_Mounted, gt_Melee)  // against gt_Mounted
  +    );
  +  var
  +    Output: Boolean;
  +    TargetIdx: Word;
  +    I,K,L: Integer;
  +    Threat, HighestThreat, Dist, BestDist: Single;
  +    GT: TGroupType;
  +    Squad: TAISquad;
  +  begin
  +    Output := False;
  +    // Ranged groups view: our ranged unit -> select target => each unit should fire
  +    GT := gt_Ranged;
  +    for I := AvaiableSquads[GT].Count - 1 downto 0 do
  +    begin
  +      Squad := AvaiableSquads[GT].Squads[I];
  +      HighestThreat := INIT_THREAT;
  +      for K := 0 to Length(fTargetU) - 1 do
  +        if (fTargetU[K].DistantThreat > 0) then
  +        begin
  +          Threat := fTargetU[K].DistantThreat - KMDistanceSqr(TAISquad(fSquads[GT].Items[I]).Position, UA[ fTargetU[K].Index ].GetPosition);
  +          if (Threat > HighestThreat) then
  +          begin
  +            HighestThreat := Threat;
  +            TargetIdx := K;
  +          end;
  +        end;
  +      if (HighestThreat <> INIT_THREAT) then
  +      begin
  +        Squad.TargetUnit := UA[ fTargetU[TargetIdx].Index ];
  +        Output := True;
  +        fTargetU[TargetIdx].DistantThreat := fTargetU[TargetIdx].DistantThreat - Squad.Group.Count;
  +        Dec(AvaiableSquads[GT].Count);
  +        AvaiableSquads[GT].Squads[I] := AvaiableSquads[GT].Squads[ AvaiableSquads[GT].Count ];
  +      end
  +      else
  +        Squad.TargetUnit := nil;
  +    end;
  +
  +    // Close combat groups view: enemy units -> select oponent => keep something in reserve
  +    for I := 0 to Length(fTargetU) - 1 do
  +      if (fTargetU[I].CloseThreat > 0) then
  +        for K := 0 to 3 do
  +        begin
  +          GT := BEST_TARGET[  UGA[ fTargetU[I].Index ].GroupType, K  ];
  +          if (GT = gt_Ranged) then // Skip ranged groups
  +            continue;
  +          while (fTargetU[I].CloseThreat > 0) AND (AvaiableSquads[GT].Count > 0) do
  +          begin
  +            BestDist := 100000;
  +            for L := 0 to AvaiableSquads[GT].Count - 1 do
  +            begin
  +              Dist := KMDistanceSqr(AvaiableSquads[GT].Squads[L].Position, UA[ fTargetU[I].Index ].GetPosition);
  +              if (Dist < BestDist) then
  +              begin
  +                BestDist := Dist;
  +                TargetIdx := L;
  +              end;
  +            end;
  +
  +            Squad := AvaiableSquads[GT].Squads[TargetIdx];
  +            Squad.TargetUnit := UGA[ fTargetU[I].Index ].GetAliveMember;
  +            Output := True;
  +            fTargetU[I].CloseThreat := fTargetU[I].CloseThreat - Squad.Group.Count;
  +            Dec(AvaiableSquads[GT].Count);
  +            AvaiableSquads[GT].Squads[TargetIdx] := AvaiableSquads[GT].Squads[ AvaiableSquads[GT].Count ];
  +          end;
  +        end;
  +    Result := Output;
  +  end;
  +
  +  procedure Regroup();
  +  var
  +    Cnt: Word;
  +    I: Integer;
  +    GT: TGroupType;
  +    Squad: TAISquad;
  +    Positions: TKMPointArray;
  +    InitPolygons: TKMWordArray;
  +  begin
  +    Cnt := 0;
       for GT := Low(TGroupType) to High(TGroupType) do
  -      for I := 0 to fSquads[GT].Count - 1 do
  +      Cnt := Cnt + AvaiableSquads[GT].Count;
  +
  +    if (Cnt = 0) then
  +      Exit;
  +
  +    // Get positions around center of scan area
  +    SetLength(InitPolygons,1);
  +    InitPolygons[0] := gAIFields.NavMesh.KMPoint2Polygon[ fScanPosition ];
  +    gAIFields.NavMesh.Positioning.FindPositions(Cnt, InitPolygons, Positions);
  +
  +    Cnt := 0;
  +    for GT := Low(TGroupType) to High(TGroupType) do
  +      for I := 0 to AvaiableSquads[GT].Count - 1 do
         begin
  -        Squad := fSquads[GT].Items[I];
  -        Squad.TargetUnit := UGA[Idx].GetAliveMember;
  -        Idx := Idx + 1;
  -        if (Idx = Length(UGA)) then
  -          Idx := 0;
  +        Squad := AvaiableSquads[GT].Squads[I];
  +        Squad.FinalPosition := KMPointDir(  Positions[Cnt], KMGetDirection( Squad.Position, Positions[Cnt] )  );
  +        //Squads[ClosestIdx].TimeLimit := gGame.GameTickCount + KMDistanceAbs(Position, Squads[ClosestIdx].Position) * TIME_PER_A_TILE;
  +        Cnt := Cnt + 1;
  +        if (Cnt >= Length(Positions)) then
  +          Exit;
         end;
     end;
  -end;
  -
  -
  -procedure TAICompany.OrderMove(aActualPosition: TKMPoint);
  +
  +
  +  function OrderAttackHouse(): Boolean;
  +  const
  +    INIT_THREAT = -1000000;
  +    SQR_CLOSE_COMBAT_DISTANCE_LIMIT = 12*12;
  +    MAX_SOLDIERS_VS_HOUSE = 12;
  +    ATTACK_WATCHTOWER_WITH_CLOSE_COMBAT_DIST = 5;
  +    SQR_MAX_CLOSE_COMBAT_VS_UNIT_DIST = 3*3;
  +  var
  +    Output: Boolean;
  +    TargetIdx: Word;
  +    I,K: Integer;
  +    Dist, BestDist: Single;
  +    GT: TGroupType;
  +    U: TKMUnit;
  +    GroupAttackCnt: TKMWordArray;
  +  begin
  +    Output := False;
  +    SetLength(GroupAttackCnt, Length(HA));
  +    for I := 0 to Length(HA) - 1 do
  +      GroupAttackCnt[I] := 0;
  +
  +    // Target watchtowers with archers
  +    GT := gt_Ranged;
  +    for I := AvaiableSquads[GT].Count - 1 downto 0 do
  +    begin
  +      BestDist := INIT_THREAT;
  +      for K := 0 to Length(HA) - 1 do
  +        if (HA[K].HouseType = ht_WatchTower)
  +          AND (GroupAttackCnt[K] < MAX_SOLDIERS_VS_HOUSE)
  +          AND (HA[K].CheckResIn(wt_Stone) > 1)
  +          AND HA[K].HasOwner then // Ignore towers without stone and without recruit inside
  +        begin
  +          Dist := KMDistanceSqr(AvaiableSquads[GT].Squads[I].Position, HA[K].GetPosition);
  +          if (Dist > BestDist) then
  +          begin
  +            BestDist := Dist;
  +            TargetIdx := K;
  +          end;
  +        end;
  +      if (BestDist <> INIT_THREAT) then
  +      begin
  +        GroupAttackCnt[TargetIdx] := GroupAttackCnt[TargetIdx] + AvaiableSquads[GT].Squads[I].Group.Count;
  +        // Find and kill workers who want to repair house
  +        U := gAIFields.Eye.GetClosestUnitAroundHouse(HA[K].HouseType, HA[K].GetPosition, AvaiableSquads[GT].Squads[I].Position);
  +        if (U <> nil) then
  +          AvaiableSquads[GT].Squads[I].TargetUnit := U
  +        else
  +          AvaiableSquads[GT].Squads[I].TargetHouse := HA[TargetIdx];
  +        Output := True;
  +        Dec(AvaiableSquads[GT].Count);
  +        AvaiableSquads[GT].Squads[I] := AvaiableSquads[GT].Squads[ AvaiableSquads[GT].Count ];
  +      end;
  +    end;
  +
  +    // Target everything else with close combat units
  +    for GT := Low(TGroupType) to High(TGroupType) do
  +    begin
  +      if (GT = gt_Ranged) then
  +        continue;
  +      for I := AvaiableSquads[GT].Count - 1 downto 0 do
  +      begin
  +        BestDist := INIT_THREAT;
  +        for K := 0 to Length(HA) - 1 do
  +          if (
  +               (HA[K].HouseType <> ht_WatchTower)
  +               OR ( KMDistanceAbs(AvaiableSquads[GT].Squads[I].Position, HA[K].GetPosition) < ATTACK_WATCHTOWER_WITH_CLOSE_COMBAT_DIST)
  +             )
  +            AND (GroupAttackCnt[K] < MAX_SOLDIERS_VS_HOUSE) then
  +          begin
  +            Dist := KMDistanceSqr(AvaiableSquads[GT].Squads[I].Position, HA[K].GetPosition);
  +            if (Dist > BestDist) AND (Dist <= SQR_CLOSE_COMBAT_DISTANCE_LIMIT) then
  +            begin
  +              BestDist := Dist;
  +              TargetIdx := K;
  +            end;
  +          end;
  +        if (BestDist <> INIT_THREAT) then
  +        begin
  +          GroupAttackCnt[TargetIdx] := GroupAttackCnt[TargetIdx] + AvaiableSquads[GT].Squads[I].Group.Count;
  +          // Find and kill workers who want to repair house
  +          U := gAIFields.Eye.GetClosestUnitAroundHouse(HA[K].HouseType, HA[K].GetPosition, AvaiableSquads[GT].Squads[I].Position);
  +          if (U <> nil)
  +            AND ((GT = gt_Ranged) OR (KMDistanceSqr(U.GetPosition, AvaiableSquads[GT].Squads[I].Position) < SQR_MAX_CLOSE_COMBAT_VS_UNIT_DIST)) then
  +            AvaiableSquads[GT].Squads[I].TargetUnit := U
  +          else
  +            AvaiableSquads[GT].Squads[I].TargetHouse := HA[TargetIdx];
  +          Output := True;
  +          Dec(AvaiableSquads[GT].Count);
  +          AvaiableSquads[GT].Squads[I] := AvaiableSquads[GT].Squads[ AvaiableSquads[GT].Count ];
  +        end;
  +      end;
  +    end;
  +    Result := Output;
  +  end;
  +
  +
  +
  +var
  +  Output: Boolean;
  +begin
  +  Output := False;
  +
  +  // Find avaiable squads (groups who obey orders / are not in combat)
  +  FindAvaiableSquads();
  +
  +  // Attack hostile units in radius
  +  if (Length(UA) > 0) then
  +  begin
  +    // Calculate threat level of each enemy group in radius
  +    EvalEnemyGroupsInRadius();
  +
  +    // Select targets
  +    Output := SelectTargetGroups();
  +  end;
  +
  +  // Attack houses in radius
  +  if (Length(HA) > 0) then
  +    Output := OrderAttackHouse();
  +
  +  // Move troops in reserve into new center point
  +  if Output then
  +    Regroup();
  +
  +  Result := Output;
  +end;
  +
  +
  +function TAICompany.OrderMove(aActualPosition: TKMPoint): Boolean;
   
     function GetInitPolygons(aCnt: Integer; var aPointPath: TKMPointArray): TKMWordArray;
     const
  
positive.code: end;
  
  
  function TAISquad.PlanPath(var aActualPosition, aTargetPosition: TKMPoint): Boolean;
  const
    SQR_TARGET_REACHED_TOLERANCE = 5*5;
  var
    InitPolygon, ClosestPolygon, Distance: Word;
    I: Integer;
    PointPath: TKMPointArray;
  begin
    Result := False;
    fIsReady := False;
    if (fTimeLimit < gGame.GameTickCount) OR (KMDistanceSqr(aActualPosition, aTargetPosition) < SQR_TARGET_REACHED_TOLERANCE) then
    begin
      fIsReady := True;
      Exit;
    end;
    if gAIFields.NavMesh.Pathfinding.AvoidEnemyRoute(fOwner, Group.GroupType, aActualPosition, aTargetPosition, Distance, PointPath) then
      if (Distance < 6) then
        Exit
      else
      begin
        InitPolygon := gAIFields.NavMesh.Point2Polygon[aActualPosition.Y,aActualPosition.X];
        I := Length(PointPath)-2;
        repeat
          aTargetPosition := PointPath[ Max(0, I) ];
          ClosestPolygon := gAIFields.NavMesh.Point2Polygon[aTargetPosition.Y,aTargetPosition.X];
          I := I - 1;
        until (InitPolygon <> ClosestPolygon) OR (I < 0);
  
        fDEBUGPointPath := PointPath;//  DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
      end;
  
negative.code: var
    I: Integer;
    GT: TGroupType;
  begin
    fTargetUnit := gHands.GetUnitByUID( Cardinal(fTargetUnit) );
    fTargetHouse := gHands.GetHouseByUID( Cardinal(fTargetHouse) );
    for GT := Low(TGroupType) to High(TGroupType) do
      for I := 0 to fSquads[GT].Count - 1 do
        TAISquad( Squads[GT].Items[I] ).SyncLoad();
  end;
  
  
  