anchor.diff:    TKMScriptStates = class(TKMScriptEntity)
     private
       procedure _AIGroupsFormationGet(aPlayer: Integer; aGroupType: TKMGroupType; out aCount, aColumns: Integer; out aSucceed: Boolean);
  -    function _ClosestGroup(aPlayer, X, Y: Integer; aGroupType: TKMGroupType; aMethodName: String): Integer;
  -    function _ClosestGroupMultipleTypes(aPlayer, X, Y: Integer; aGroupTypes: TKMGroupTypeSet; aMethodName: string): Integer;
  -    function _ClosestHouse(aPlayer, X, Y: Integer; aHouseType: TKMHouseType; aMethodName: string): Integer;
  -    function _ClosestHouseMultipleTypes(aPlayer, X, Y: Integer; aHouseTypes: TKMHouseTypeSet; aMethodName: string): Integer;
  -    function _ClosestUnit(aPlayer, X, Y: Integer; aUnitType: TKMUnitType; aMethodName: string): Integer;
  -    function _ClosestUnitMultipleTypes(aPlayer, X, Y: Integer; aUnitTypes: TKMUnitTypeSet; aMethodName: string): Integer;
  +    function _ClosestGroup(aPlayer, X, Y: Integer; aGroupType: TKMGroupType; out aSucceed: Boolean): Integer;
  +    function _ClosestGroupMultipleTypes(aPlayer, X, Y: Integer; aGroupTypes: TKMGroupTypeSet; out aSucceed: Boolean): Integer;
  +    function _ClosestHouse(aPlayer, X, Y: Integer; aHouseType: TKMHouseType; out aSucceed: Boolean): Integer;
  +    function _ClosestHouseMultipleTypes(aPlayer, X, Y: Integer; aHouseTypes: TKMHouseTypeSet; out aSucceed: Boolean): Integer;
  +    function _ClosestUnit(aPlayer, X, Y: Integer; aUnitType: TKMUnitType; out aSucceed: Boolean): Integer;
  +    function _ClosestUnitMultipleTypes(aPlayer, X, Y: Integer; aUnitTypes: TKMUnitTypeSet; out aSucceed: Boolean): Integer;
     public
       function AIArmyType(aPlayer: Byte): TKMArmyType;
       function AIAutoAttack(aPlayer: Byte): Boolean;
  
positive.code:       Result := G.UID;
        fIDCache.CacheGroup(G, G.UID);
      end;
    end
    else
      LogIntParamWarn(aMethodName, [aPlayer, X, Y, Ord(aGroupType)]);
  end;
  
  
  
negative.code: //* or -1 if no such group was found.
  //* Result: Group ID
  function TKMScriptStates.ClosestGroupEx(aPlayer, X, Y: Integer; aGroupType: TKMGroupType): Integer;
  var
    succeed: Boolean;
  begin
    try
      Result := _ClosestGroup(aPlayer, X, Y, aGroupType, succeed);
      if not succeed then
        LogParamWarn('States.ClosestGroupEx', [aPlayer, X, Y, GetEnumName(TypeInfo(TKMGroupType), Integer(aGroupType))]);
    except
      gScriptEvents.ExceptionOutsideScript := True; //Don't blame script for this exception
      raise;
    end;
  end;
  
  
  function TKMScriptStates._ClosestGroupMultipleTypes(aPlayer, X, Y: Integer; aGroupTypes: TKMGroupTypeSet; out aSucceed: Boolean): Integer;
  var
    G: TKMUnitGroup;
  begin
    Result := -1;
    aSucceed := False;
    if InRange(aPlayer, 0, gHands.Count - 1) and (gHands[aPlayer].Enabled)
      and gTerrain.TileInMapCoords(X, Y) then
    begin
      aGroupTypes := aGroupTypes * GROUP_TYPES_VALID;
      G := gHands[aPlayer].UnitGroups.GetClosestGroup(KMPoint(X,Y), aGroupTypes);
      if G <> nil then
      begin
        Result := G.UID;
        fIDCache.CacheGroup(G, G.UID);
      end;
      aSucceed := True;
    end;
  end;
  
  