Results 1 to 17 of 17

Thread: TRSBeastOfBurden - new interface include for SRL

  1. #1
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

    Default TRSBeastOfBurden - new interface include for SRL

    We currently don't have an include for the beast of burden interface, which is popular for skilling and combat activities. Here is an include I made for the SRL Library, in addition to borrowing relevant/similar methods from bankscreen.simba. Hope it helps everyone!

    Simba Code:
    ID_INTERFACE_BEAST_OF_BURDEN = 47;



    beastofburden.simba
    Simba Code:
    (*
    BeastOfBurden
    =============

    The BeastofBurden file holds functions and procedures that are used in the
    Runescape beast of burden familiar inventory screen.

    The source for this file can be found `here <https://github.com/SRL/SRL-6/blob/master/lib/interfaces/beastofburden.simba>`_.

    *)


    {$include_once interfaces.simba}
    {$include_once ../core/text.simba}

    {$f-}

    (*
    const Internal
    ~~~~~~~~~~~~~~

    Internal beast of burden screen constants.

    *)

    const
      FAMILIAR_SLOT_LOW = 1;
      PLAYER_SLOT_LOW = 1;
      PLAYER_SLOT_HIGH = 28;
      FAMILIAR_BACKGROUND = 2433824;
      PLAYER_BACKGROUND = 3088905;

    (*
    const Slot & Button Types
    ~~~~~~~~~~~~~~~~~~~~~~~~~

    Integer constants that represent the slot and button types in the beast of burden interface.

    *)

    const
      SLOTS_FAMILIAR   = 0;
      SLOTS_PLAYER     = 1;

    const
      BUTTON_GIVE_ITEMS = 0;
      BUTTON_TAKE_ITEMS = 1;

    (*
    type TRSBeastOfBurden
    ~~~~~~~~~~~~~~~~~~~~~

    A type that stores the collection box interface properties.
    *)

    type
      TRSBeastOfBurden = type TRSInterface;

    (*
    var Internal
    ~~~~~~~~~~~~~~

    Internal beast of burden screen variables.

    *)

    var
      maximumSlots: integer = 30;

    (*
    var beastOfBurden
    ~~~~~~~~~~~~~~~~~

    The variable used to call collect box functions, procedures and attributes.

    Example:

    .. code-block:: pascal

        if (beastOfBurden.isOpen()) then
          writeln('beastOfBurden is open');
    *)

    var
      beastOfBurden: TRSBeastOfBurden;

    {*
    TRSBeastOfBurden.__init
    ~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        procedure TRSBeastOfBurden.__init

    Initializes the TRSBeastOfBurden.

    .. note::

        - by Clarity
        - Last Updated: 03 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        beastOfBurden.__init();

    *}

    {$IFNDEF CODEINSIGHT}
    procedure TRSBeastOfBurden.__init();
    begin
      with (self) do
      begin
        name := 'Beast of Burden';
        ID := ID_INTERFACE_BEASTOFBURDEN;
        parentID := -1;
        static := false;
      end;
    end;
    {$ENDIF}

    (*
    TRSBeastOfBurden.__find
    ~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.__find(): boolean;

    Returns true if the familiar inventory is detected, and sets the bounds of the
    interface.

    .. note::

        - by Ashaman88 & Clarity
        - Last Updated: 03 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        if (beastOfBurden.__find()) then
          writeln('Bounds are set!');
    *)

    function TRSBeastOfBurden.__find(): boolean;
    var
      i: integer;
      bounds: TBox;
      TPA, TPA2 : TPointArray;
      ATPA : T2DPointArray;
    begin
      result := false;

      if (not findColors(TPA, FAMILIAR_BACKGROUND, getClientBounds())) then
        exit();

      ATPA := TPA.cluster(5);
      for i := 0 to high(ATPA) do
        if (length(ATPA[i]) > 3000) then
        begin
          bounds := getTPABounds(ATPA[i]);
          if (getColor(bounds.x2 + 15, bounds.y2 - 5) = PLAYER_BACKGROUND) then
          begin
            self.setBounds([bounds.x1 - 8, bounds.y1 - 29, bounds.x2 + 240, bounds.y2 + 8]);
            exit(true);
          end;
        end;
    end;

    (*
    TRSBeastOfBurden.isOpen
    ~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.isOpen(waitTime: integer = 0): boolean;

    Returns true if the beast of burden screen is open. Includes an optional parameter
    'waitTime' (default 0) which will search for the beast of burden screen until
    'waitTime' is reached.

    .. note::

        - by Olly
        - Last Updated: 03 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        if (beastOfBurden.isOpen()) then
          writeln('The beast of burden screen is open!');

    *)

    function TRSBeastOfBurden.isOpen(waitTime: integer = 0): boolean;
    var
      t: UInt64;
    begin
      t := (getSystemTime() + waitTime);

      repeat
        result := self.__find();
        wait(20 + random(20));
      until (getTickCount64() >= t) or (result);
    end;

    (*
    TRSBeastOfBurden.open
    ~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.open(): boolean;

    Opens the beast of burden interface via the actionbar.

    .. note::

        - by Clarity
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        beastOfBurden.open();
    *)

    function TRSBeastOfBurden.open(): boolean;
    var
      i: integer;
      timer: UInt64;
      options: TOptionArray;
    begin
      if (self.isOpen()) then
        exit(true);

      actionbar.mouseIcon(AB_Bar_SUMMONING, MOUSE_RIGHT);
      wait(randomRange(100, 250));

      if (not chooseOption.optionsExist(['Interact'])) then
      begin
        print('beastOfBurden.open(): chooseOption menu failed to open', TDebug.SUB);
        exit(false);
      end;

      timer := getTickCount64() + randomRange(5000, 7000);

      repeat
        chooseOption.select(['Interact']);
        wait(randomRange(300, 1100));
      until (getTickCount64() >= timer) or (conversationBox.isOpen());

      if (not conversationBox.isOpen()) then
      begin
        print('beastOfBurden.open(): conversation options never appeared', TDebug.SUB);
        exit(false);
      end;

      timer := getTickCount64() + randomRange(5000, 7000);

      repeat
        conversationBox.selectOption(2);
        wait(randomRange(300, 1100));
      until (getTickCount64() >= timer) or (self.isOpen());

      if self.isOpen then exit(true)
        else exit(false);
    end;

    (*
    TRSBeastOfBurden.close
    ~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.close(escape: boolean = true): boolean;

    Closes the beast of burden screen, will return if succesful or not.
    Closes via the Escape key.

    .. note::

        - by Olly
        - Last Updated: 02 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        if (beastOfBurden.close()) then
          writeln('Closed the beastOfBurden screen!');
    *)

    function TRSBeastOfBurden.close(escape: boolean = true): boolean;
    var
      timeOut: UInt64;
    begin
      result := false;

      if (not self.isOpen()) then
        exit(true);

      // try ESC key first
      if escape then
      begin
        timeOut := (getTickCount64() + randomRange(600, 900));
        repeat
          multiType(VK_ESCAPE, randomRange(30, 50), 2);
          wait(100 + random(50));
          result := (not self.isOpen());
        until((getTickCount64() > timeOut) or result);

        if (result) then
          exit();
      end;

      // click the X as a failsafe
      mouseBox(intToBox(self.x2 - 7, self.y1 - 22, self.x2 + 2, self.y1 - 12), MOUSE_MOVE);

      // this is a failsafe in case the beast of burden screen closes (from the ESC key) while moving the mouse
      if (self.isOpen()) then
      begin
        fastClick(MOUSE_LEFT);
        wait(50 + random(50));
      end else
        exit(true);

      // wait for the beast of burden screen to close
      timeOut := (getTickCount64() + randomRange(5000, 6000));
      while (timeOut > getTickCount64()) do
      begin
        if (not self.isOpen()) then
        begin
          result := true;
          break;
        end;

        wait(50 + random(50));
      end;

      print('beastOfBurden.close(): result = '+boolToStr(result), TDebug.SUB);
    end;

    (*
    TRSBeastOfBurden.clickButton
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.clickButton: boolean;

    Selects the take items or give items button in the beast of burden interface,
    withdrawing or depositing all possible items into your backpack or familiar
    inventory, respectively.  Returns true after successful completion.

    .. note::

        - by Clarity
        - Last Updated: 03 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        if (beastOfBurden.clickButton(BUTTON_TAKE_ITEMS) then
          writeln('We withdrew stored items via the take items button!');
    *)

    function TRSBeastOfBurden.clickButton(button: integer): boolean;
    begin
      if (not self.isOpen()) then
        exit;
      case button of
        BUTTON_GIVE_ITEMS: mouseBox([(self.x2 - 60), (self.y2 - 44), (self.x2 - 41), (self.y2 - 29)], MOUSE_LEFT);
        BUTTON_TAKE_ITEMS: mouseBox([(self.x2 - 31), (self.y2 - 44), (self.x2 - 14), (self.y2 - 29)], MOUSE_LEFT);
      end;
      wait(50 + random(50));
      result := true;
    end;

    (*
    TRSBeastOfBurden.getSlotBoxes
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.getSlotBoxes(slotType: Integer): TBoxArray;

    Returns a TBoxArray of all of the item slots in the familiar's or player's
    inventory, specified with SLOTS_FAMILIAR or SLOTS_PLAYER integer constants.

    .. note::

        - by Clarity
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        boxArr := beastOfBurden.getSlotBoxes(SLOTS_FAMILIAR);
        boxArr := beastOfBurden.getSlotBoxes(SLOTS_PLAYER);
    *)

    function TRSBeastOfBurden.getSlotBoxes(slotType: integer): TBoxArray;
    var
      i, maxSlots: integer;
      perceived: TBoxArray;
      TPA: TPointArray;
    begin
      if (not self.isOpen()) then
        exit();

      setLength(result, 0);
      maxSlots := 30;

      case slotType of
        SLOTS_FAMILIAR:
        begin
          perceived := grid(5, 6, 35, 31, 43, 36, point(self.x1 + 28, self.y1 + 44));
          for i := 0 to 29 do
          begin
            findColors(TPA, FAMILIAR_BACKGROUND, perceived[i].x1, perceived[i].y1, perceived[i].x2, perceived[i].y2);
            if (length(TPA) > 500) then
              maxSlots := (maxSlots - 1);
          end;
          for i := 29 downto (maxSlots) do
            perceived.deleteIndex(i);
          setlength(perceived, (maxSlots));
          result := perceived;
          maximumSlots := maxSlots;
        end;
        SLOTS_PLAYER:
        begin
          result := grid(5, 6, 35, 31, 43, 36, point(self.x1 + 263, self.y1 + 44));
          setLength(result, length(result) - 2);
        end;
      end;
    end;

    (*
    TRSBeastOfBurden.getSlotBox
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.getSlotBox(slot, slotType: integer): TBox;

    Returns the TBox of the desired item slot in the beast of burden interface.
    Slots start at the top left at 1 and count across the columns.  Use SLOTS_PLAYER
    or SLOTS_FAMILIAR to specify slotTypes.

    .. note::

        - by Coh3n & Clarity
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        var
          b: TBox;
        begin
          b := beastOfBurden.getSlotBox(1, SLOTS_PLAYER);

    *)

    function TRSBeastOfBurden.getSlotBox(slot, slotType: integer): TBox;
    begin
      if (not self.isOpen()) then
        exit();
      if (slotType = SLOTS_FAMILIAR) then
      begin
        if (not inRange(slot, FAMILIAR_SLOT_LOW, maximumSlots)) then
        begin
          print('beastOfBurden.getSlotBox(): Slot '+toStr(slot)+' is invalid', TDebug.WARNING);
          exit(intToBox(-1, -1, -1, -1));
        end;

        // - 1 because the grid (array) starts at 0.
        result := gridBox(slot -1, 5, 6, 35, 31, 43, 36, point(self.x1 + 28, self.y1 + 44));
      end else
      begin
        if (not inRange(slot, PLAYER_SLOT_LOW, PLAYER_SLOT_HIGH)) then
        begin
          print('beastOfBurden.getSlotBox(): Slot '+toStr(slot)+' is invalid', TDebug.WARNING);
          exit(intToBox(-1, -1, -1, -1));
        end;

        // - 1 because the grid (array) starts at 0.
        result := gridBox(slot -1, 5, 6, 35, 31, 43, 36, point(self.x1 + 263, self.y1 + 44));
      end;
    end;

    (*
    TRSBeastOfBurden.getItemCount
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.getItemCount(slotType: integer): integer;

    Returns the number of items in either the familiar's inventory or the player's.

    .. note::

        - by Coh3n
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        var
          c: integer;
        begin
          c := beastOfBurden.getItemCount();

    *)

    function TRSBeastOfBurden.getItemCount(slotType: integer): integer;
    var
      b: TBoxArray := self.getSlotBoxes(slotType);
      i: integer;
    begin
      for i := 0 to high(b) do
        if (isItemIn(b[i])) then
          inc(result);
    end;

    (*
    TRSBeastOfBurden._isSlotValid
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden._isSlotValid(slot, slotType: integer): boolean;

    Returns true if the familiar or player slot is valid.

    .. note::

        - by Clarity
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        if (beastOfBurden._isSlotValid(25, SLOTS_PLAYER) then
          writeln('Slot 25 is a valid player slot!');

    *)

    function TRSBeastOfBurden._isSlotValid(slot, slotType: integer): boolean;
    begin
      case slotType of
        SLOTS_FAMILIAR: result := inRange(slot, FAMILIAR_SLOT_LOW, maximumSlots);
        SLOTS_PLAYER: result := inRange(slot, PLAYER_SLOT_LOW, PLAYER_SLOT_HIGH);
      end;

      if (not result) then
        print('beastOfBurden._isSlotValid(): Slot '+toStr(slot)+' is invalid', TDebug.WARNING);
    end;


    (*
    TRSBeastOfBurden.isItemInSlot
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.isItemInSlot(slot, slotType: integer): boolean;

    Returns true if an item is in the desired beast of burden slot, works by looking for
    the black outline color in the slot.

    .. note::

        - by Olly
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

       if (beastOfBurden.isItemInSlot(1, SLOTS_FAMILIAR)) then
         writeln('We have an item in familiar slot number 1');
    *)

    function TRSBeastOfBurden.isItemInSlot(slot, slotType: integer): boolean;
    begin
      if (not self.isOpen()) or (not self._isSlotValid(slot, slotType)) then
        exit(false);

      result := isItemIn(self.getSlotBox(slot, slotType));
    end;

    (*
    TRSBeastOfBurden.isFull
    ~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.isFull(slotType: integer): boolean;

    Returns true if either the familiar or player slots are full.

    .. note::

        - by Olly & Clarity
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

       if (beastOfBurden.isFull(SLOTS_FAMILIAR)) then
         writeln('Beast of burden familiar is full!');

    *)

    function TRSBeastOfBurden.isFull(slotType: integer): boolean;
    var
      i, slotLow, slotHigh: integer;
    begin
      if (not self.isOpen()) then
        exit(false);

      case slotType of
        SLOTS_FAMILIAR: begin slotLow := FAMILIAR_SLOT_LOW; slotHigh := maximumSlots; end;
        SLOTS_PLAYER: begin slotLow := PLAYER_SLOT_LOW; slotHigh := PLAYER_SLOT_HIGH; end;
      end;

      for i := slotLow to slotHigh do
        if (not (self.isItemInSlot(i, slotType))) then
          exit(false);

      result := true;
    end;

    (*
    TRSBeastOfBurden.isEmpty
    ~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.isEmpty(slotType: integer): boolean;

    Returns true if our either the familiar or player slots are empty.

    .. note::

        - by Olly & Clarity
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

       if (beastOfBurden.isEmpty(SLOTS_PLAYER)) then
         writeln('our beastOfBurden player pack is empty!');

    *)

    function TRSBeastOfBurden.isEmpty(slotType: integer): boolean;
    var
      searchBox: TBox;
    begin
      if (not self.isOpen()) then
        exit(false);

      case slotType of
        SLOTS_FAMILIAR: searchBox := IntToBox(self.x1 + 15, self.y1 + 31, self.x1 + 217, self.y2);
        SLOTS_PLAYER: searchBox := IntToBox(self.x1 + 249, self.y1 + 31, self.x2, self.y2);
      end;

      result := (not (searchBox.colorExists(ITEM_OUTLINE_BLACK)));
    end;

    (*
    TRSBeastOfBurden.getCountDTM
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.getCountDTM(dtm, slotType: integer): integer;

    Searches for the dtm in each familiar or player slot and will return how many matches it finds.

    .. note::

        - by Olly
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        var
          dtm: integer;
          i: integer;
        begin
          dtm := dtmFromString('lotsofstuffhere');
          i := beastOfBurden.getCountDTM(dtm, SLOTS_FAMILIAR);
          writeln('We counted ' + intToStr(i) + ' items in our familiar pack.');
        end;
    *)

    function TRSBeastOfBurden.getCountDTM(dtm, slotType: integer): integer;
    var
      i, l: integer;
    begin
      result := 0;

      if (not self.isOpen()) then
        exit();

      result := findItem(dtm, self.getSlotBoxes(slotType));

      if (result = 0) then
      begin
        print('beastOfBurden.getCountDTM(): Found no DTM matches', TDebug.SUB);
        exit();
      end;

      print('beastOfBurden.getCountDTM(): Counted ' + intToStr(result) + ' items');
    end;


    (*
    TRSBeastOfBurden.getCountBitmap
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.getCountBitmap(bmp, tolerance, slotType: integer): integer;

    Searches for the bitmap in each familiar or player slot and will return how many matches it finds.

    .. note::

        - by Olly
        - Last Updated: 04 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        var
          bmp: integer;
          i: integer;
        begin
          bmp := bitmapFromString('lotsofstuffhere');
          i := beastOfBurden.getCountBitmap(bmp, tol, SLOTS_PLAYER);
          writeln('We counted ' + intToStr(i) + ' items in our player pack.');
        end;
    *)

    function TRSBeastOfBurden.getCountBitmap(bmp, tolerance, slotType: integer): integer;
    begin
      result := 0;

      if (not self.isOpen()) then
        exit();

      result := findItem(bmp, tolerance, self.getSlotBoxes(slotType));

      if (result = 0) then
      begin
        print('beastOfBurden.getCountBitmap(): Found no bitmap matches', TDebug.SUB);
        exit();
      end;

      print('beastOfBurden.getCountBitmap(): Counted ' + intToStr(result) + ' items');
    end;

    (*
    TRSBeastOfBurden.withdraw
    ~~~~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.withdraw(slot, amount: integer; mouseOverText: TStringArray): boolean;

    Withdraws the the amount 'amount' from the beast of burden slot 'slot', if the mouse-over
    text is correct, mouse-over text can also be skipped.

    Extra valid constants for 'amount' are:

       - WITHDRAW_AMOUNT_ALL = -1;

    .. note::

        - by Olly & Clarity
        - Last Updated: 4 October 2014 by Clarity

    Example:

    .. code-block:: pascal

        // To withdraw 28 items from slot 1 if mouseover text is valid
        beastOfBurden.withdraw(1, 28, ['Death rune']);

        // To withdraw all items from slot 10 if mouseover text is valid
        beastOfBurden.withdraw(10, WITHDRAW_AMOUNT_ALL, ['Death rune']);

        // To withdraw 28 items from slot 1 and will *ignore* mouse-over text
        beastOfBurden.withdraw(1, 28, ['']);

    *)

    function TRSBeastOfBurden.withdraw(slot, amount: integer; mouseOverText: TStringArray): boolean;
    var
      b: TBox;
    begin
      result := false;
      b := self.getSlotBox(slot, SLOTS_FAMILIAR);

      if (b.x1 = -1) then
      begin
        print('beastOfBurden.withdraw(): Invalid slot '+toStr(slot), TDebug.WARNING);
        exit(false);
      end;

      if (not isItemIn(b)) then
      begin
        print('beastOfBurden.withdraw(): No item in slot '+toStr(slot), TDebug.WARNING);
        exit(false);
      end;

      mouseBox(b, MOUSE_MOVE);

      if (length(mouseOverText[0]) > 0) then
        if (not isMouseOverText(mouseOverText, 250)) then
        begin
          print('beastOfBurden.withdraw(): Incorrect Mouse-over text, result = false', TDebug.SUB);
          exit(false);
        end;

      if (amount = 1) then
      begin
        fastClick(MOUSE_LEFT);
        wait(400 + random(300));
        print('beastOfBurden.withdraw(): result = true', TDebug.SUB);
        exit(true);
      end else
        fastClick(MOUSE_RIGHT);

      if (chooseOption.isOpen(2000)) then
      begin
        case (amount) of
          WITHDRAW_AMOUNT_ALL: result := chooseOption.select(['Withdraw-All', '-All']);
          else
          begin
            if (chooseOption.select(['Withdraw-X', '-X'])) then
              result := (bankscreen._enterAmount(amount, 6000));
          end;
        end;
      end else
        print('beastOfBurden.withdraw(): chooseOption menu failed to open', TDebug.SUB);

      print('beastOfBurden.withdraw(): result = ' + boolToStr(result), TDebug.SUB);
    end;

    (*
    TRSBeastOfBurden.store
    ~~~~~~~~~~~~~~~~~~~~~~

    .. code-block:: pascal

        function TRSBeastOfBurden.store(slots: TIntegerArray; amounts: TIntegerArray = []; oneByOne: boolean = false): boolean;

    Stores items from the player pack into the familiar pack.  Has the capability of storing
    all items, storing a specific amount of items, and clicking each item one by one.

        * slots: The slots you want to store.
        * amounts: The amounts of the slots to store.  Set index to -1 to store all.  Stores all of every item by default.
        * oneByOne: Default false.  Will click items one by one to store.

    .. note::

        - by Coh3n
        - Last Updated: 04 October 2014 by Clarity

    Examples:

    .. code-block:: pascal

        beastOfBurden.store([2..28]);
        beastOfBurden.store([1, 2, 3, 4], [-1, 10, 15, 14]);
        beastOfBurden.store([1..28], , true); // one by one
    *)

    function TRSBeastOfBurden.store(slots: TIntegerArray; amounts: TIntegerArray = []; oneByOne: boolean = false): boolean;
    var
      b: TBox;
      t, tt : UInt64;
      i, _x, _y: integer;
    begin
      result := false;

      if (length(slots) < 1) then
      begin
        print('beastOfBurden.store(): No storet slots specified', TDebug.WARNING);
        exit(false);
      end;

      if (not self.isOpen()) then
      begin
        print('beastOfBurden.store(): Unable to store since beast of burden interface isn''t open', TDebug.ERROR);
        exit(false);
      end;

      if ((length(amounts) > 0) and (length(amounts) <> length(slots))) then
      begin
        print('beastOfBurden.store(): Slot and amount arrays are of different length, they need to be the same!', TDebug.WARNING);
        exit(false);
      end;

      // fill the amounts array to avoid errors
      if (length(amounts) = 0) then
      begin
        setLength(amounts, length(slots));

        for i := 0 to high(amounts) do
          amounts[i] := -1;
      end;

      if (not result) then
      begin
        result := true; // will be set to false if it fails to store a slot

        for i := 0 to high(slots) do
        begin
          b := self.getSlotBox(slots[i], SLOTS_PLAYER);

          if (isItemIn(b) = false) then
            continue;

          if (oneByOne = true) then
          begin
            mouseBox(b, MOUSE_LEFT);
            wait(100 + random(200));
          end else begin
            mouseBox(b, MOUSE_RIGHT);

            if (amounts[i] = -1) then
            begin
              if (chooseOption._select(['Store-All', 'ore-All', 'All'], MOUSE_LEFT, false, 1.0, 300) = false) then
                chooseOption.select(['Store', 'tore']); // in case there's only one
            end else begin
              if (chooseOption._select([toStr(amounts[i])], MOUSE_LEFT, false, 1.0, 300) = false) then
                if (chooseOption.select(['Store-X', '-X'])) then
                begin
                  t := (getTickCount64() + 3000);

                  while (getTickCount64() < t) do
                  begin
                    if (findColor(_x, _y, 0, 241, 485, 286, 517)) then // box around the "Enter" text
                    begin
                      wait(100 + random(50));
                      typeSend(toStr(amounts[i]));

                      tt := (getTickCount64() + 3000);
                      while (self.isOpen() = false) and (getTickCount64() < tt) do
                        wait(50);

                      break;
                    end;

                    wait(50 + random(25));
                  end;
                end;
            end;
          end;

          // wait for the item to disappear
          t := (getTickCount64() + 2000);
          while (amounts[i] = -1) and (getTickCount64() < t) do
          begin
            if (isItemIn(b) = false) then
              break;

            wait(50 + random(25));
          end;

          // make sure the item is gone, return false if not
          if (amounts[i] = -1) then
            if (isItemIn(self.getSlotBox(slots[i], SLOTS_PLAYER))) then
            begin
              print('beastOfBurden.store(): Failed to store item in slot '+toStr(i), TDebug.ERROR);
              result := false;
            end;
        end;
      end;

      print('beastOfBurden.store(): '+toStr(result), TDebug.SUB);
    end;

    begin
      beastOfBurden.__init();
    end;

    Test Script
    Simba Code:
    program BeastOfBurdenTest;

    //Test script for Beast of Burden interface include
    //Enjoy! Clarity

    {$DEFINE SMART}
    {$i srl-6/srl.simba}
    var
      slots, slots2:TBoxArray;
      i: Integer;
    begin
      smartEnableDrawing := True;
      setupSRL();

      beastOfBurden.open();
      beastOfBurden.store([2..6]);
      beastOfBurden.withdraw(22, WITHDRAW_AMOUNT_ALL, ['']);
      beastOfBurden.close(false);
      wait(gaussRangeInt(1000, 3000));
      beastOfBurden.open();

      smartImage.drawBox(beastOfBurden.getBounds());

      slots := beastOfBurden.getSlotBoxes(SLOTS_PLAYER);
      for i := 0 to high(slots) do
        smartImage.drawBox(slots[i]);

      slots2 := beastOfBurden.getSlotBoxes(SLOTS_FAMILIAR);
      for i := 0 to high(slots2) do
        smartImage.drawBox(slots2[i]);

      writeln('ARE ITEMS IN PLAYER SLOTS? ======');
      for i := 1 to 30 do
        writeln('Player slot: ' + ToStr(i) + ToStr(beastOfBurden.isItemInSlot(i, SLOTS_PLAYER)));
      writeln('ARE ITEMS IN FAMILIAR SLOTS? ======');
      for i := 1 to 30 do
        writeln('Familiar slot: ' + ToStr(i) + ToStr(beastOfBurden.isItemInSlot(i, SLOTS_FAMILIAR)));
      writeln('VALID VS INVALID PLAYER SLOTS ======');
      for i := 1 to 30 do
        writeln('Player slot: ' + ToStr(i) + ToStr(beastOfBurden._isSlotVaild(i, SLOTS_PLAYER)));
      writeln('VALID VS INVALID FAMILIAR SLOTS ======');
      for i := 1 to 30 do
        writeln('Familiar slot: ' + ToStr(i) + ToStr(beastOfBurden._isSlotVaild(i, SLOTS_FAMILIAR)));
    end.
    Last edited by Clarity; 01-20-2015 at 04:31 PM.

  2. #2
    Join Date
    Jul 2014
    Location
    Europe
    Posts
    182
    Mentioned
    7 Post(s)
    Quoted
    103 Post(s)

    Default

    I've never used anything related to Beast of Burden and I'll probably never will but I really admire your effort for the people who do, nice work!

  3. #3
    Join Date
    Sep 2012
    Location
    Netherlands
    Posts
    2,752
    Mentioned
    193 Post(s)
    Quoted
    1468 Post(s)

    Default

    gj clarity!

    still waiting for dung <3
    Quote Originally Posted by Spaceblow View Post
    I've never used anything related to Beast of Burden and I'll probably never will but I really admire your effort for the people who do, nice work!
    you should, summoning is really useful

  4. #4
    Join Date
    Jul 2014
    Location
    Europe
    Posts
    182
    Mentioned
    7 Post(s)
    Quoted
    103 Post(s)

    Default

    Quote Originally Posted by hoodz View Post
    you should, summoning is really useful
    My summoning level is 1, I never bothered to level up. But your reply changed my mind a little bit, I'll maybe look more into summoning when I become member again.

  5. #5
    Join Date
    Sep 2012
    Location
    Netherlands
    Posts
    2,752
    Mentioned
    193 Post(s)
    Quoted
    1468 Post(s)

    Default

    Quote Originally Posted by Spaceblow View Post
    My summoning level is 1, I never bothered to level up. But your reply changed my mind a little bit, I'll maybe look more into summoning when I become member again.
    just gather every charm you see and put every sof bonus xp thingy on summoning (so you are using less charms)

  6. #6
    Join Date
    Oct 2013
    Location
    East Coast USA
    Posts
    770
    Mentioned
    61 Post(s)
    Quoted
    364 Post(s)

    Default

    Quote Originally Posted by hoodz View Post
    just gather every charm you see and put every sof bonus xp thingy on summoning (so you are using less charms)
    I put all mine on dung; I have like level 60 and have never been to one.

  7. #7
    Join Date
    Jul 2014
    Location
    Europe
    Posts
    182
    Mentioned
    7 Post(s)
    Quoted
    103 Post(s)

    Default

    Quote Originally Posted by hoodz View Post
    just gather every charm you see and put every sof bonus xp thingy on summoning (so you are using less charms)
    Then I guess I'm pretty lucky I saved these.


  8. #8
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

    Default

    Yes, using a beast of burden often times increases XP or GP per hour. Trip lengths of whatever you're doing become much longer!

    Edit: fixed a couple typos/mistakes.
    Last edited by Clarity; 10-04-2014 at 10:43 PM.

  9. #9
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

  10. #10
    Join Date
    Apr 2008
    Location
    Marquette, MI
    Posts
    15,252
    Mentioned
    138 Post(s)
    Quoted
    680 Post(s)

    Default

    Nothing negative jumps out at me. I didn't look at it in depth, though.

    Can you elaborate on what you mean by similar methods to bankscreen.simba? Did you copy/paste some code? One thing we stress is not having repeated code. It clutters the include and is very bad practice. If there's a way to generalize a function and pass arguments to it, it should be done.

    Nice work though.

  11. #11
    Join Date
    Jun 2007
    Location
    The land of the long white cloud.
    Posts
    3,702
    Mentioned
    261 Post(s)
    Quoted
    2006 Post(s)

    Default

    You might want to change your spelling of valid (and yes someone needs to fix the other vailds too) Do you need to have all of those constants global? Some are only used in one method.

  12. #12
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

    Default

    Quote Originally Posted by The Mayor View Post
    You might want to change your spelling of valid Do you need to have all of those constants global? Some are only used in one method.
    Good point, I will move some of them in my pull request, I planned on using them in other functions but ended up not needing to! That wrong spelling of valid is in multiple other SRL includes so I thought it was intentional for some weird lape reason and remained consistent in my include.

    Quote Originally Posted by Coh3n View Post
    Nothing negative jumps out at me. I didn't look at it in depth, though.

    Can you elaborate on what you mean by similar methods to bankscreen.simba? Did you copy/paste some code? One thing we stress is not having repeated code. It clutters the include and is very bad practice. If there's a way to generalize a function and pass arguments to it, it should be done.

    Nice work though.
    Thanks and sure, no problem.
    By similar code, I only meant how BeastOfBurden.store is similar to Bankscreen.deposit, just like they are all similar to depositBox.deposit, etc. Just like what was done for depositBox, I assume, I took the bankscreen.deposit code and modified it for the BoB interface. The BoB interface is different from bankscreen, just like depositBox is different from bankscreen. Yet they all contain similar features.

    So, we could make a generic interface.withdraw/deposit and remove the originals from bankscreen.simba, depositbox.simba, beastOfBurden.simba, and anywhere else I missed where it repeats, to save code repetition, but I feel like that would break every script out there?
    Last edited by Clarity; 10-06-2014 at 04:00 AM.

  13. #13
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

  14. #14
    Join Date
    Jun 2014
    Location
    Lithuania
    Posts
    475
    Mentioned
    27 Post(s)
    Quoted
    200 Post(s)

    Default

    Goodjob, looking forward to addint familiar support along with my porter support for drags skillers. only tho i have 1 account atm which will be using this as others dont have charmf or 68 summ to get tortoise. Also i need to add renewing familier before its dead too and that would do fine like 45 kills per trip

    Got back out of holidays so now have some nice charms. maybe soon release public red eggs spawner or maybe if i get more charms, (need to get like 86 range killing drags for 69 summ charms, so tkes quite awhile) fruit bat spawner. Today on testing red eggs spawner worked 3 hours till he got lost. sps doesnt work where i am using it, need to find other ways to find a bank, gona try ddtms.

  15. #15
    Join Date
    Jun 2007
    Location
    The land of the long white cloud.
    Posts
    3,702
    Mentioned
    261 Post(s)
    Quoted
    2006 Post(s)

    Default

    Quote Originally Posted by Clarity View Post
    Hold on a moment, going to have to update this as a result of the new summoning update!
    You're lucky this didn't happen 1 day after release

  16. #16
    Join Date
    Apr 2008
    Location
    Marquette, MI
    Posts
    15,252
    Mentioned
    138 Post(s)
    Quoted
    680 Post(s)

    Default

    Quote Originally Posted by Clarity View Post
    So, we could make a generic interface.withdraw/deposit and remove the originals from bankscreen.simba, depositbox.simba, beastOfBurden.simba, and anywhere else I missed where it repeats, to save code repetition, but I feel like that would break every script out there?
    It wouldn't break anything if done properly. You'd do something like this:
    Simba Code:
    function someGenericFunction(): boolean;
    begin
    end;

    function TRSBankScreen.deposit(): boolean;
    begin
      someGenericFuntion(arguments required for bankscreen.deposit);
    end;
    Nothing would need to change in scripts.

  17. #17
    Join Date
    Dec 2011
    Posts
    2,147
    Mentioned
    221 Post(s)
    Quoted
    1068 Post(s)

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •