PDA

View Full Version : TRSBeastOfBurden - new interface include for SRL



Clarity
10-04-2014, 10:09 AM
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! :)

ID_INTERFACE_BEAST_OF_BURDEN = 47;

http://i.gyazo.com/cc3363b623e330381df7d2a40f1f2aa8.png

beastofburden.simba

(*
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

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.

Spaceblow
10-04-2014, 11:02 AM
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! :)

Hoodz
10-04-2014, 12:10 PM
gj clarity!

still waiting for dung <3

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

Spaceblow
10-04-2014, 12:18 PM
you should, summoning is really usefulMy 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. :)

Hoodz
10-04-2014, 01:24 PM
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)

bonsai
10-04-2014, 01:39 PM
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.

Spaceblow
10-04-2014, 01:51 PM
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. :D

http://i.imgur.com/zWLz6DL.jpg?1

Clarity
10-04-2014, 09:17 PM
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.

Clarity
10-06-2014, 12:33 AM
Olly, Ashaman88, Coh3n, any feedback/additions before I submit pull request?
Also, I added ID_INTERFACE_BEAST_OF_BURDEN = 45; and increased the following constants by 1, is that the proper way?

Coh3n
10-06-2014, 02:45 AM
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. :)

The Mayor
10-06-2014, 03:32 AM
You might want to change your spelling of valid (and yes someone needs to fix the other vailds too) :p Do you need to have all of those constants global? Some are only used in one method.

Clarity
10-06-2014, 03:34 AM
You might want to change your spelling of valid :p 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.


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?

Clarity
10-06-2014, 09:49 AM
Hold on a moment, going to have to update this as a result of the new summoning update!

cosmasjdz
10-06-2014, 10:58 AM
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 :D

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.

The Mayor
10-06-2014, 11:22 AM
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 :p

Coh3n
10-06-2014, 11:53 PM
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:

function someGenericFunction(): boolean;
begin
end;

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

Clarity
01-20-2015, 04:30 PM
Updated and tested to account for game changes, submitted to SRL-6 on GitHub, The Mayor. Sorry for the long delay guys, glad to be back in action!