So many grandexchange functions seem to be broken
Have you gotten some time to work on the include? Because I don't have much time to make changes currently...
@Thomas
I believe most of the grand exchange library is fixed now. I've added a function that returns the confirmbox. Besides that, I've changed almost all the functions. If you want the complete list of changes pm me. Although I've tested for a few hours, you should test it too.
Simba Code:(*
Grand Exchange
==============
The grandexchange file holds functions and procedures that are used to interact with the runescape Grand Exchange.
The source for this file can be found `here <https://github.com/SRL/SRL-6/blob/master/lib/interfaces/grandexchange.simba>`_.
*)
{$f-}
(*
Consts, Types, Vars
~~~~~~~~~~~~~~~~~~~
The following constants, types and variables are used throughout the collectBox methods.
**const Grand Exchange Tabs**
Constants that represent the two grandExchange tabs
* GE_TAB_EXCHANGE
* GE_TAB_HISTORY
*)
const
GE_TAB_EXCHANGE = 0;
GE_TAB_HISTORY = 1;
GE_TAB_SETS = 2;
(*
**type TRSGrandExchange**
.. code-block:: pascal
type
TRSGrandExchange = type TRSInterface;
A type that stores the Grand Exchange interface properties.
*)
type
TRSGrandExchange = record(TRSInterface)
tabBoxes: TBoxArray;
confirmBox: TBox;
end;
(*
**var grandExchange**
.. code-block:: pascal
var
grandExchange: TRSGrandExchange;
A variable through which scripters can access the TRSGrandExchange type methods.
*)
var
grandExchange: TRSGrandExchange;
(*
TRSGrandExchange methods
~~~~~~~~~~~~~~~~~~~~~~~~~
The following methods should be called through the **grandExchange** variable.
Example:
.. code-block:: pascal
if grandExchange.isOpen() then
writeln('It''s open');
*)
{*
__init
------
.. code-block:: pascal
procedure TRSGrandExchange.__init();
Initializes the TRSGrandExchange.
.. note::
- by The Mayor
- Last Updated: 9th October 2014 by Clarity
Example:
.. code-block:: pascal
grandExchange.__init();
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__init();
begin
with self do
begin
name := 'Grand Exchange';
ID := ID_INTERFACE_GRANDEXCHANGE;
parentID := -1;
static := false;
end;
end;
{$ENDIF}
{*
__find
------
.. code-block:: pascal
function TRSGrandExchange.__find(): boolean;
Returns true if the grandExchange interface is detected and its bounds are set.
Scripters should use grandExchange.isOpen() below.
.. note::
- by The Mayor
- Last Updated: 6 July 2015 by The Mayor
Example:
.. code-block:: pascal
if grandExchange.__find() then
writeln('The grandExchange is open, and the bounds are set!');
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__find(): boolean;
const
PINK_COLOR = [14581920, 0]; // [Col, Tol] pink item in the balance scale.
var
i: Integer;
TPA: TPointArray;
ATPA: T2DPointArray;
b: TBox;
begin
findColorsTolerance(TPA, PINK_COLOR[0], getClientBounds(), PINK_COLOR[1]);
if length(TPA) < 10 then
begin
print('TRSGrandExchange.__find(): Didn''t find enough PINK_COLOR', TDebug.WARNING);
exit(false);
end;
ATPA := TPA.cluster(5);
ATPA.sortBySize(true);
for i := 0 to high(ATPA) do
begin
b := ATPA[i].getBounds();
if inRange(b.getWidth(), 10, 20) and (b.getHeight() < 20) then
begin
b.edit(21, -10, 114, 12);
if (pos('GRAND', upperCase(tesseract_GetText(b, TESS_FILTER_SMALL_CHARS))) > 0) then
begin
self.setBounds([b.x1 - 88, b.y1 - 8, b.x2 + 570, b.y2 + 515]);
self.tabBoxes := grid(3, 1, 60, 22, 107, 0, point(x1 + 92, y1 + 113));
self.confirmBox := [self.x1 + 218, self.y1 + 511, self.x1 + 340, self.y1 + 524];
exit(true);
end;
end;
end;
end;
{$ENDIF}
(*
isOpen
------
.. code-block:: pascal
function TRSGrandExchange.isOpen(waitTime: integer = 0): boolean;
Returns true if the grandExchange is open. The optional **waitTime** parameter
*(default = 0)* is the maximum time (in milliseconds) it will keep looking.
.. note::
- by The Mayor
- Last Updated: 14 January 2015 by The Mayor
Example:
.. code-block:: pascal
if grandExchange.isOpen() then
writeln('The grandExchange is open!');
*)
function TRSGrandExchange.isOpen(waitTime: integer = 0): boolean;
var
t: UInt64;
begin
t := (getTickCount64() + waitTime);
repeat
if self.__find() then
begin
result := true;
break();
end;
until (getSystemTime() >= t);
print('TRSGrandExchange.isOpen(): Result = ' + boolToStr(result));
end;
(*
close
-----
.. code-block:: pascal
function TRSGrandExchange.close(escape: boolean = true): boolean;
Returns true if the grandExchange is successfully closed. It uses the ESC key
by default, but the **escape** parameter can be set to false to close via the mouse.
.. note::
- by The Mayor
- Last Updated: 6 July 2015 by The Mayor
Example:
.. code-block:: pascal
if grandExchange.close() then
writeln('Closed the grandExchange');
*)
function TRSGrandExchange.close(escape: boolean = true): boolean;
const
__CLOSE_OFFSET: TPoint = [756, 22]; // From self(x1, y1) to middle of 'X'
var
timeOut: UInt64;
begin
if (not self.isOpen()) then
exit(true);
if escape then // Try the escape button first if possible
begin
timeOut := (getTickCount64() + randomRange(600, 900));
repeat
typeByte(VK_ESCAPE);
wait(300 + random(50));
until (not self.isOpen()) or (getTickCount64() > timeOut);
if (not self.isOpen()) then
exit(true);
end;
if self.isOpen(100 + random(50)) then // Wait a bit in case it closes
begin
mouse(point(self.x1 + __CLOSE_OFFSET.x, self.y1 + __CLOSE_OFFSET.y).rand(3), MOUSE_LEFT);
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;
end else
result := true;
print('TRSGrandExchange.close(): result = ' + boolToStr(result), TDebug.SUB);
end;
{*
__getActiveTab
--------------
.. code-block:: pascal
function TRSGrandExchange.__getActiveTab(): Integer;
Returns the current tab number (0 - Grand Exchange | 1 - Sale History).
.. note::
- by The Mayor
- Last Updated: 9 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__getActiveTab());
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getActiveTab(): Integer;
var
i: Integer;
begin
for i := 0 to high(self.tabBoxes) do
if (not (getColor(self.tabBoxes[i].X2, self.tabBoxes[i].Y2) = 9078134)) then
exit(i);
end;
{$ENDIF}
(*
openTab
-------
.. code-block:: pascal
function TRSGrandExchange.openTab(tab: Integer): Boolean;
Opens the grandExchange tab **tab** . The **tab** parameter should be one of the
two tab constants at the top of this page.
.. note::
- by The Mayor
- Last Updated: 9 July 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.openTab(GE_TAB_HISTORY);
*)
function TRSGrandExchange.openTab(tab: Integer): Boolean;
begin
if (not self.isOpen()) then
exit(false);
if (self.__getActiveTab() = tab) then
exit(true);
for 0 to 3 do
begin
multiClick(self.tabBoxes[tab].getGaussPoint(), 30, 3);
wait(random(800, 1200));
if (self.__getActiveTab() = tab) then exit(true);
end;
end;
(*
getPackSlotBox
--------------
.. code-block:: pascal
function TRSGrandExchange.getPackSlotBox(slot: integer): TBox;
Returns a TBox of the pack slot **slot** in the grandExchange interface.
.. note::
- by The Mayor
- Last Updated: 6 July 2015 by The Mayor
Example:
.. code-block:: pascal
var
b: TBox;
begin
b := grandExchange.getPackSlotBox(1);
mouseBox(b, MOUSE_MOVE);
end;
*)
function TRSGrandExchange.getPackSlotBox(slot: integer): TBox;
const
__PACK_OFFSET: TPoint = [582, 174]; // From self(x1, y1) to middle of first pack slot
begin
result := gridBox(slot - 1, 4, 7, 36, 32, 46, 36, point(self.x1 + __PACK_OFFSET.x, self.y1 + __PACK_OFFSET.y));
end;
{*
__getSlotBoxes
--------------
.. code-block:: pascal
function TRSGrandExchange.__getSlotBoxes(): TBoxArray;
Returns a TBoxArray of the 8 Grand Exchange slots.
.. note::
- by The Mayor
- Last Updated: 19 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
tba := grandExchange.__getSlotBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getSlotBoxes(): TBoxArray;
const
__GE_SLOT_OFFSET: TPoint = [104, 203]; // From self(x1, y1) to middle of first GE slot
var
tba: TBoxArray;
begin
tba := grid(3, 3, 169, 121, 177, 128, point(self.x1 + __GE_SLOT_OFFSET.x, self.y1 + __GE_SLOT_OFFSET.y));
tba.deleteIndex(8);
result := tba;
end;
{$ENDIF}
{*
__getBuyBoxes
-------------
.. code-block:: pascal
function TRSGrandExchange.__getBuyBoxes(): TBoxArray;
Returns a TBoxArray of the Grand Exchange buy boxes.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
tba := grandExchange.__getBuyBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getBuyBoxes(): TBoxArray;
const
__BUY_OFFSET: TPoint = [74, 213]; // From self(x1, y1) to middle of first buy button
var
tba: TBoxArray;
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.__getBuyBoxes(): Cannot click a buy box as the GE is not open', TDebug.ERROR);
exit();
end;
tba := grid(3, 3, 44, 44, 177, 128, point(self.x1 + __BUY_OFFSET.x, self.y1 + __BUY_OFFSET.y));
tba.deleteIndex(8);
result := tba;
end;
{$ENDIF}
{*
__getSellBoxes
--------------
.. code-block:: pascal
function TRSGrandExchange.__getSellBoxes(): TBoxArray;
Returns a TBoxArray of the Grand Exchange sell boxes.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
tba := grandExchange.__getSellBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getSellBoxes(): TBoxArray;
const
__SELL_OFFSET: TPoint = [134, 213]; // From self(x1, y1) to middle of first sell button
var
tba: TBoxArray;
begin
tba := grid(3, 3, 44, 44, 177, 128, point(self.x1 + __SELL_OFFSET.x, self.y1 + __SELL_OFFSET.y));
tba.deleteIndex(8);
result := tba;
end;
{$ENDIF}
{*
__getInputBoxes
---------------
.. code-block:: pascal
function TRSGrandExchange.__getInputBoxes(): TBoxArray;
Returns a TBoxArray of the Grand Exchange input boxes, where you can type.
.. note::
- by Clarity
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
tba := grandExchange.__getInputBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getInputBoxes(): TBoxArray;
var
TPA: TPointArray;
ATPA: T2DPointArray;
i: integer;
begin
grandExchange.__find;
if findColors(TPA, 1388125, self.getBounds()) then
begin
ATPA := TPA.cluster(1);
ATPA.sortFromFirstPoint(Point(233, 261)); //changed this
result := ATPA.getEachBounds();
end;
writeLn(result);
end;
{$ENDIF}
{*
__isOfferOpen
-------------
.. code-block:: pascal
function TRSGrandExchange.__isOfferOpen(waitTime: integer = 500): boolean;
Returns true if the buy or sell offer screen is open.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
writeLn(grandExchange.__isOfferOpen());
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isOfferOpen(waitTime: integer = 500): boolean;
var
timeOut: UInt64;
TPA: TPointArray;
begin
timeOut := getTickCount64() + waitTime;
while (getTickCount64() < timeOut) do
if findColors(TPA, 6247745, self.getBounds()) then
begin
if (length(TPA) = 2862) then
exit(true);
end;
end;
{$ENDIF}
{*
__isProgressOpen
----------------
.. code-block:: pascal
function TRSGrandExchange._isProgressOpen(waitTime: integer = 500): boolean;
Returns true if the offer in progress screen is open.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
writeLn(grandExchange.__isProgressOpen());
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isProgressOpen(waitTime: integer = 500): boolean;
var
timeOut: integer;
TPA: TPointArray;
begin
timeOut := getTickCount64() + waitTime;
while (getTickCount64() < timeOut) do
if findColors(TPA, 6247745, self.getBounds()) then
begin
if (length(TPA) = 3501) then
exit(true);
end;
end;
{$ENDIF}
{*
__isSlotActive
--------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotActive(geSlot: integer): boolean;
Returns true if the slot **geSlot** is active. This is necessary
because slots 3 to 8 are inactive when you are not a member.
.. note::
- by The Mayor
- Last Updated: 10 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotActive(1));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotActive(geSlot: integer): boolean;
var
TPA: TPointArray;
TBA : TBoxArray := self.__getSlotBoxes();
begin
findColors(TPA, 5063989, TBA[geSlot - 1]);
result := length(TPA) < 5000;
end;
{$ENDIF}
{*
__isSlotEmpty
-------------
.. code-block:: pascal
function TRSGrandExchange._isSlotEmpty(geSlot: integer): boolean;
Returns true if the offer slot **geSlot** is empty and avaliable to use.
.. note::
- by The Mayor
- Last Updated: 10 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotEmpty(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotEmpty(geSlot: integer): boolean;
var
TPA: TPointArray;
TBA : TBoxArray := self.__getSlotBoxes();
begin
if self.__isSlotActive(geSlot) then
begin
findColors(TPA, 2694922, TBA[geSlot - 1]);
result := length(TPA) > 10000;
end;
print('TRSGrandExchange._isSlotEmpty(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotComplete
----------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotComplete(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is complete.
.. note::
- by The Mayor
- Last Updated: 15 January 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotComplete(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotComplete(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
begin
result := (countColorTolerance(1799224, TBA[geSlot - 1], 17) > 1700);
print('TRSGrandExchange.isSlotComplete(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotAborted
---------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotAborted(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is aborted.
.. note::
- by The Mayor
- Last Updated: 15 January 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotAborted(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotAborted(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
begin
result := (countColorTolerance(983163, TBA[geSlot - 1], 16) > 1700);
print('TRSGrandExchange.isSlotAborted(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotBuying
--------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotBuying(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is currently buying.
.. note::
- by The Mayor
- Last Updated: 31 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotBuying(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotBuying(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
TPA, TPA2: TPointArray;
begin
if self.__isSlotAborted(geSlot) or self.__isSlotComplete(geSlot)
then exit(false);
findColors(TPA, 2433824, TBA[geSlot - 1]);
findColors(TPA2, 3815734, TBA[geSlot - 1]); // If hovering the box
TPA.combine(TPA2);
result := (length(TPA) > 10000);
print('TRSGrandExchange.isSlotBuying(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotSelling
---------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotSelling(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is currently selling.
.. note::
- by The Mayor
- Last Updated: 31 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange._isSlotSelling(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotSelling(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
TPA, TPA2: TPointArray;
begin
if self.__isSlotAborted(geSlot) or self.__isSlotComplete(geSlot)
then exit(false);
findColors(TPA, 3287837, TBA[geSlot - 1]);
findColors(TPA2, 4603955, TBA[geSlot - 1]); // If hovering the box
TPA.combine(TPA2);
result := (length(TPA) > 10000);
print('TRSGrandExchange.isSlotSelling(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__findInsertionCursor
---------------------
.. code-block:: pascal
TRSGrandExchange.__findInsertionCursor(searchBox: TBox; waitTime: integer = 4000): boolean;
Returns true is the insertion cursor is found inside **searchBox** within the **waitTime**
*(default = 4000)* .
.. note::
- by Clarity
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
writeLn(grandExchange.__findInsertionCursor(b));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__findInsertionCursor(searchBox: TBox; waitTime: integer = 4000): boolean;
var
timeOut: UInt64;
TPA: TPointArray;
begin
timeOut := getTickCount64() + waitTime;
while getTickCount64() < timeOut do
begin
findColors(TPA, 14606050, searchBox);
if length(TPA) > 0 then
exit(true);
end;
end;
{$ENDIF}
{*
__enterQuantity
---------------
.. code-block:: pascal
procedure TRSGrandExchange.__enterQuantity(quantity: string);
Returns true if it successfully enters the desired item quantity **quantity**
into the input box.
.. note::
- by The Mayor
- Last Updated: 19 November 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.__enterQuantity('1500'); // To buy/sell 1500 of an item
grandExchange.__enterQuantity('all'); // To SELL all of the item
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__enterQuantity(quantity: string);
var
i: integer;
strArr : TStringArray;
inputBox: TBoxArray;
amountBox: TBoxArray := grid(4, 1, 34, 24, 44, 0, point(self.x1 + 84, self.y1 + 298));
begin
strArr := ['1', '10', '100', 'all'];
i := strArr.returnInArray(lowercase(quantity));
if inRange(i, 0, 3) then
mouseBox(amountBox[i], MOUSE_LEFT)
else
begin
inputBox := self.__getInputBoxes();
mouseBox(inputBox[0], MOUSE_LEFT);
if self.__findInsertionCursor(inputBox[0]) then
begin
typeSend(toStr(quantity), true);
wait(randomRange(1000, 1500));
end;
end;
end;
{$ENDIF}
{*
__enterPrice
------------
.. code-block:: pascal
procedure TRSGrandExchange.__enterPrice(price: string);
Returns true if it successfully enters the desired item price **price**
into the input box.
.. note::
- by The Mayor
- Last Updated: 19 November 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.__enterPrice('+5'); // Will click the +5% button
grandExchange.__enterPrice('mid'); // Will leave at mid price
grandExchange.__enterPrice('32500'); // Will type in 32500
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__enterPrice(price: string);
var
i: integer;
b: TBox;
strArr : TStringArray;
priceBox, inputBox: TBoxArray;
begin
priceBox := grid(3, 1, 34, 24, 45, 0, point(self.x1 + 367, self.y1 + 298));
strArr := ['-5', 'mid', '+5'];
i := strArr.returnInArray(lowercase(price));
if (i = 0) or (i = 2) then
mouseBox(priceBox[i], MOUSE_LEFT)
else if (i <> 1) then // Don't click mid button as it's set by default
begin
inputBox := self.__getInputBoxes();
mouseBox(inputBox[1], MOUSE_LEFT);
if self.__findInsertionCursor(inputBox[1]) then
begin
typeSend(toStr(price), true);
wait(randomRange(1000, 1500));
end;
end;
end;
{$ENDIF}
{*
__enterName
-----------
.. code-block:: pascal
procedure TRSGrandExchange.__enterName(itemName: string)
Returns true if it successfully types the item name **itemName** into the search
box and clicks it.
.. note::
- by The Mayor
- Last Updated: 24 Decenber 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.__enterName('Swamp toad');
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__enterName(itemName: string): boolean;
const
TESS_FILTER_GE_CHARS: TTesseractFilter = [4, 4, [False, 20, TM_Mean]];
var
i: integer;
timeOut: UInt64;
resultsBox: TBoxArray := grid(3, 2, 166, 49, 172, 55, point(self.x1 + 104, self.y1 + 405));
resultsTextBox: TBoxArray := grid(3, 2, 122, 16, 172, 55, point(self.x1 + 121, self.y1 + 396));
inputBox: TBoxArray;
begin
timeOut := getTickCount64() + randomRange(3000, 4000);
inputBox := self.__getInputBoxes();
if not self.__findInsertionCursor(inputBox[2]) then
mouseBox(inputBox[2], MOUSE_LEFT);
if self.__findInsertionCursor(inputBox[2]) then
typeSend(itemName, false);
if waitColorCountRange(9214319, 10, resultsTextBox[0], 5000, 10) then
for i := 0 to 5 do
if stringMatch(trim(tesseractGetText(resultsTextBox[i], TESS_FILTER_GE_CHARS)), itemName) >= 0.7 then
begin
mouseBox(resultsBox[i], MOUSE_LEFT);
waitColorCountRange(16777215, 3, inputBox[2], 5000, 507, 509);
exit(true);
end;
print('TRSGrandExchange.__enterName(): Found no matches for item: ' + itemName, TDebug.SUB);
end;
{$ENDIF}
{*
__returnToSummary
-----------------
.. code-block:: pascal
procedure TRSGrandExchange._returnToSummary();
If the GE offer screen or GE progress screen is currently open, it will click
the back arrow to return to the summary screen.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.__returnToSummary();
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__returnToSummary();
var
backButton: TPoint := [self.x1 + 33, self.y1 + 515];
timeOut: UInt64;
begin
if self.__isOfferOpen() or self.__isProgressOpen() then
begin
print('TRSGrandExchange._returnToSummary(): returning to summary screen', TDebug.SUB);
multiClick(backButton.rand(5), 30, 3);
timeOut := getTickCount64() + randomRange(2500, 3500);
while getTickCount64() < timeOut do
begin
if ((not self.__isOfferOpen()) and (not self.__isProgressOpen())) then
break();
end;
end;
end;
{$ENDIF}
(*
collectSlot
-----------
.. code-block:: pascal
function TRSGrandExchange.collectSlot(geSlot: integer): boolean;
Returns true if it collects coins and/or items from the completed or aborted slot
**geSlot** .
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.collectSlot(2);
*)
function TRSGrandExchange.collectSlot(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
collectBox: TBoxArray := grid(2, 1, 37, 32, 49, 0, point(self.x1 + 463, self.y1 + 385));
timeOut: UInt64;
i: integer;
begin
if not self.__isProgressOpen() then
begin
self.__returnToSummary();
if (not self.__isSlotActive(geSlot)) or self.__isSlotEmpty(geSlot) then
begin
print('TRSGrandExchange.collectSlot(): Cannot collect as offer slot ' + toStr(geSlot) + ' is empty', TDebug.ERROR);
exit(false);
end;
timeOut := getTickCount64() + randomRange(3000, 4000);
repeat
mouseBox(TBA[geSlot - 1], MOUSE_LEFT);
if self.__isProgressOpen(2000 + random(500)) then
break();
until (getTickCount64() < timeOut);
end;
for i := high(collectBox) downto 0 do
for 0 to 2 do // Attempt up to 3 times in case of lag
if isItemIn(collectBox[i]) then
begin
mouseBox(collectBox[i], MOUSE_LEFT);
wait(randomRange(750, 1250));
if not self.__isProgressOpen() then
begin
result := true;
break(1);
end;
end;
self.__returnToSummary();
print('TRSGrandExchange.collectSlot(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result));
end;
(*
waitCollectSlot
---------------
.. code-block:: pascal
function TRSGrandExchange.waitCollectSlot(geSlot, maxTime: integer): boolean;
Returns true if it collects coins and/or items from the completed or aborted slot
**geSlot** . Waits up to **maxTime** for **geSlot** to finish selling.
.. note::
- by The Mayor
- Last Updated: 12 March 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.waitCollectSlot(2, 60000); // Wait up to 1 minute to collect slot 2
*)
function TRSGrandExchange.waitCollectSlot(geSlot, maxTime: Integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
timeOut: UInt64;
begin
self.__returnToSummary();
if (not self.__isSlotActive(geSlot)) or self.__isSlotEmpty(geSlot) then
begin
print('TRSGrandExchange.waitCollectSlot(): Cannot collect as offer slot ' + toStr(geSlot) + ' is empty', TDebug.ERROR);
exit(false);
end;
timeOut := getTickCount64() + maxTime;
while (getTickCount64() < timeOut) do
if self.__isSlotComplete(geSlot) then
begin
if self.collectSlot(geSlot) then
begin
result := true;
break();
end;
end else
wait(500);
print('TRSGrandExchange.waitCollectSlot(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
(*
collectAllSlots
---------------
.. code-block:: pascal
procedure TRSGrandExchange.collectAllSlots(toInventory: boolean = true): boolean;
Collects all coins and items to either the inventory or the bank depending on the
**toInventory** paramter *(default = true)* via the collect buttons.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.collectAllSlots(false); // Collect all to bank
*)
procedure TRSGrandExchange.collectAllSlots(toInventory: boolean = true);
const
_OFFSET: TPoint = [653, 481];
var
TBA: TBoxArray;
begin
TBA := grid(1, 2, 180, 20, 0, 36, point(self.x1 + _OFFSET.x, self.y1 + _OFFSET.y));
case ToInventory of
true: multiClick(TBA[0].getMiddle().rand(5), 25, 3);
false: multiClick(TBA[1].getMiddle().rand(5), 25, 3);
end;
end;
(*
abortSlot
---------
.. code-block:: pascal
function TRSGrandExchange.abortSlot(geSlot: integer; collect: boolean = true): boolean;
Returns true if it aborts the slot **geSlot**. If the **collect** parameter is
set to true it will also collect the items and gold from the aborted offer.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.abortSlot(2);
grandExchange.abortSlot(2, false); // To leave items in the aborted offer slot
*)
function TRSGrandExchange.abortSlot(geSlot: integer; collect: boolean = true): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
abortButton: TPoint := [self.x1 + 402, self.y1 + 383];
redBox: TBox := [self.x1 + 29, self.y1 + 404, self.x1 + 423, self.y1 + 410];
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.abortSlot(): Cannot abort as the GE is not open', TDebug.ERROR);
exit(false);
end;
self.__returnToSummary();
if self.__isSlotEmpty(geSlot) or (not self.__isSlotActive(geSlot)) then
begin
print('TRSGrandExchange.abortSlot(): Cannot abort as offer slot ' + toStr(geSlot) + ' is empty', TDebug.ERROR);
exit(false);
end;
if self.__isSlotAborted(geSlot) then
begin
print('TRSGrandExchange.abortSlot(): Offer slot ' + toStr(geSlot) + ' is already aborted');
exit(true);
end;
if self.__isSlotComplete(geSlot) then
begin
print('TRSGrandExchange.abortSlot(): Cannot abort as offer slot ' + toStr(geSlot) + ' is already completed', TDebug.ERROR);
exit(false);
end;
mouseBox(TBA[geSlot - 1], MOUSE_LEFT, MOUSE_ACCURATE);
if self.__isProgressOpen(3000) then
begin
multiClick(abortButton.rand(5), 30, 3);
waitColorCountRange(1048714, 5, redBox, 4000, 2000);
if collect then
result := self.collectSlot(geSlot)
else
begin
result := self.__isSlotAborted(geSlot);
self.__returnToSummary();
end;
end;
print('TRSGrandExchange.abortSlot(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result));
end;
(*
abortAllSlots
-------------
.. code-block:: pascal
procedure TRSGrandExchange.abortAllSlots(collect: boolean);
Aborts all slots that are not currently empty. If the **collect** parameter is
set to true, it will also collect all items and gold.
.. note::
- by The Mayor
- Last Updated: 12 March 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.abortAllSlots();
*)
procedure TRSGrandExchange.abortAllSlots(collect: boolean = true);
var
i: integer;
TBA: TBoxArray := self.__getSlotBoxes();
begin
for i := 1 to length(TBA) do
if (not self.__isSlotEmpty(i)) and self.__isSlotActive(i) then
self.abortSlot(i, collect);
end;
(*
getPercentDone
--------------
.. code-block:: pascal
function TRSGrandExchange.getPercentDone(geSlot: integer): integer;
Returns the percentage toward completion for the offer in **geSlot** .
.. note::
- by turpinator
- Last Updated: 19 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
var
per: Integer;
begin
per := grandExchange.getPercentDone(2);
writeLn('Slot 2 is ' + toStr(per) + ' percent complete!');
end;
*)
function TRSGrandExchange.getPercentDone(geSlot: integer): integer;
const
BG_COLORS = [2565929, 2039584, 2237482, 1776673];
var
i, x, y: integer;
TBA: TBoxArray := self.__getSlotBoxes();
begin
if self.__isSlotEmpty(geSlot) or (not self.__isSlotActive(geSlot)) then exit(-1);
x := TBA[geSlot -1].x1 + 8;
y := TBA[geSlot -1].y1 + 100;
for result := 153 downto 1 do
if (getColor(x + result, y) <> BG_COLORS[0]) and (getColor(x + result, y) <> BG_COLORS[1]) then
exit(round(0.6897 * result));
end;
(*
confirmBox
--------------
.. code-block:: pascal
function TRSGrandExchange.confirmBox(): TBox;
Returns the confirm TBox in the Grand Exchange screen.
.. note::
- by SlipperyPickle
- Last Updated: 05 June 2016 by SlipperyPickle
Example:
.. code-block:: pascal
var
confirm: TBox;
begin
mouseBox(grandExchange.confirmBox(), MOUSE_LEFT);
end;
*)
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.confirmBox(): TBox;
var
x, y, i: integer;
TPA: TPointArray;
ATPA: T2DPointArray;
b: TBox;
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.confirmBox(): Cannot abort as the GE is not open', TDebug.ERROR);
exit();
end;
findColorsSpiralTolerance(x, y, TPA, 1942256, grandExchange.getBounds(), 23, colorSetting(2, 0.11, 0.49));
if (Length(TPA) < 1) then
exit;
ATPA := TPA.cluster(20);
ATPA.filterBetween(0, 500);
ATPA.sortFromMidPoint(Point(145, 525));
b := ATPA[0].getBounds();
result := IntToBox(b.X1 + 5, b.Y1 + 3, b.X2 - 5, b.Y2 - 3);
end;
{$ENDIF}
(*
sellItem
--------
.. code-block:: pascal
function TRSGrandExchange.sellItem(packSlot: integer; price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
Returns true if it sells the item in backpack slot **packSlot** . If **waitCollect**
is set to true, it will wait the specified waitTime for the offer to complete
before collecting the resulting gold.
The **price** parameter is a string - valid options are:
* 'mid' : GE mid price button
* '-5' : 5% below mid price button
* '+5' : 5% above mid price button
* Any other number : It will enter the price
The **quantity** parameter is a string - valid options are:
* '1' : '1' button
* '10' : '10' button
* '100' : '100' button
* 'all' : 'All' button (Selling ONLY)
* Any other number : It will enter the quantity
.. note::
- by The Mayor
- Last Updated: 13 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
// Sell all of item in backPack slot 1 for mid price
grandExchange.sellItem(1, 'mid', 'all');
// To sell 100 of the item in backPack slot 1, for 1500gp each
grandExchange.sellItem(1, '1500', '100');
// As above, but waits up to 20 seconds for completion before collecting the coins
grandExchange.sellItem(1, '1500', '100', true, 20000);
*)
function TRSGrandExchange.sellItem(packSlot: integer; price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
var
i, nextSlot: integer;
confirm: TBox := [self.x1 + 218, self.y1 + 508, self.x1 + 345, self.y1 + 526];
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.sellItem(): Cannot abort as the GE is not open', TDebug.ERROR);
exit(false);
end;
self.__returnToSummary();
for i := 1 to 8 do
if self.__isSlotEmpty(i) and self.__isSlotActive(i) then
begin
nextSlot := i;
break();
end;
if nextSlot < 1 then
begin
print('TRSGrandExchange.sellItem(): Cannot sell item as there are no empty offer slots', TDebug.ERROR);
exit(false);
end;
if isItemIn(self.getPackSlotBox(packSlot)) then
mouseBox(self.getPackSlotBox(packSlot), MOUSE_LEFT, MOUSE_ACCURATE)
else
begin
print('TRSGrandExchange.sellItem(): No item in pack slot: ' + intToStr(packSlot), TDebug.ERROR);
exit(false);
end;
if self.__isOfferOpen(3000) then
begin
self.__enterQuantity(quantity);
self.__enterPrice(price);
//confirm := self.confirmBox() ;
mouseBox(confirm, MOUSE_LEFT, MOUSE_ACCURATE);
wait(randomRange(1000, 1500));
end;
result:= self.__isSlotSelling(nextSlot);
print('TRSGrandExchange.sellItem(): ' + boolToStr(result), TDebug.SUB);
if waitCollect then
self.waitCollectSlot(nextSlot, waitTime);
end;
(*
buyItem
-------
.. code-block:: pascal
function TRSGrandExchange.buyItem(itemName, price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
Returns true if it buys the item **itemName** . If **waitCollect** is set to true,
it will wait the specified waitTime for the offer to complete before collecting
the resulting gold and items.
The **price** parameter is a string - valid options are:
* 'mid' : GE mid price button
* '-5' : 5% below mid price button
* '+5' : 5% above mid price button
* Any other number : It will enter the price
The **quantity** parameter is a string - valid options are:
* '1' : '1' button
* '10' : '10' button
* '100' : '100' button
* Any other number : It will enter the quantity
.. note::
- by The Mayor
- Last Updated: 13 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
// To buy 10000 oak logs at 5% over the mid price
grandExchange.buyItem('Oak log', '+5', '10000');
// To buy 10000 oak logs for 150gp each
grandExchange.buyItem('Oak log', '150', '10000');
// As above, but waits up to 20 seconds for completion before collecting items
grandExchange.buyItem('Oak log', '150', '10000', true, 20000);
*)
function TRSGrandExchange.buyItem(itemName, price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
var
i, nextSlot, x, y: integer;
b: TBox;
p: TPoint;
TBA : TBoxArray := self.__getBuyBoxes();
confirm: TBox := [self.x1 + 218, self.y1 + 508, self.x1 + 345, self.y1 + 526];
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.sellItem(): Cannot abort as the GE is not open', TDebug.ERROR);
exit(false);
end;
self.__returnToSummary();
for i := 1 to 8 do
if self.__isSlotEmpty(i) and self.__isSlotActive(i) then
begin
nextSlot := i;
break();
end;
if nextSlot < 1 then
begin
print('TRSGrandExchange.sellItem(): Cannot sell item as there are no empty offer slots', TDebug.ERROR);
exit(false);
end;
mouseBox(TBA[nextSlot - 1], MOUSE_LEFT, MOUSE_ACCURATE);
if self.__isOfferOpen(3000) then
begin
self.__enterName(itemName);
self.__enterQuantity(quantity);
self.__enterPrice(price);
mouseBox(confirm, MOUSE_LEFT);
wait(randomRange(1000, 1500));
end else
self.__returnToSummary();
result := self.__isSlotBuying(nextSlot);
print('TRSGrandExchange.buyItem(): ' + boolToStr(result), TDebug.SUB);
if waitCollect then
self.waitCollectSlot(nextSlot, waitTime);
end;
(*
getPrice
--------
.. code-block:: pascal
TRSGrandExchange.getPrice(item: integer): integer;
Returns the current market price of any item in the Grand Exchange. The **item**
parameter must be the item's ID number.
IDs can be found on the Grand Exchange website at the end of the URL. For example,
the ID in the below URL is 2150 (Swamp toad)
http://services.runescape.com/m=itemdb_rs/viewitem.ws?obj=2150
.. note::
- by The Mayor
- Last Updated: 16 July 2015 by The Mayor
Example:
.. code-block:: pascal
var
toadPrice: Integer;
begin
toadPrice := grandExchange.getPrice(2150); // The ID for Swamp toads
profit := (toadPrice * toadsCollected);
end;
*)
function TRSGrandExchange.getPrice(ID: integer): integer;
var
webPage: string;
TSA: TStringArray;
begin
webPage := getPage('http://services.runescape.com/m=itemdb_rs/viewitem.ws?obj=' + toStr(ID));
TSA := multiBetween(webPage, 'average30.push([new Date(',']);');
if length(TSA) < 1 then
begin
print('TRSGrandExchange.getPrice(): Unable to retrieve price for ID: ' + toStr(ID), TDebug.ERROR);
exit(-1);
end;
result := strToInt(Between('), ', ',', TSA[High(TSA)]));
print('TRSGrandExchange.getPrice(' + toStr(ID) + '): ' + toStr(result));
end;
begin
grandExchange.__init();
end;
{$f+}
Last edited by SlipperyPickle; 06-06-2016 at 11:08 PM.
I hope I can find some free time soon to test this. Perhaps next weekend
I've updated the code, check my previous post. Most of it is working except for the confirm button (sometimes it misclicks). Could you check whats wrong? If I've got some spare time in the next few days, I'll do my best to fix the rest.
EDIT: Long night, but I believe most is fixed now. Should be tested tough.
Last edited by SlipperyPickle; 06-06-2016 at 11:09 PM.
This project is currently on hold, postponed until my holiday. Was getting headaches from such a big project. I think I'm about 75% done with this project, and it's already almost 1000 lines long.
Currently am working on a farming script (tree runner), it's almost finished. Even made it save everything to a file, so you can pause and restart the script. Thinking about releasing this script as soon as it's stable. My first goal with this script is a 2 week proggy. Should be possible since it just have to make the run once every 6 hours.
Had some time to work on the grand exchange library. Updated it yesterday to the github, but today I saw there were still a few minor bugs. I'm not really familiar with github so I'll upload it here. This version works like a charm. Perhaps the library can be updated after testing.
This project is going pretty good right now. The grand exchange library is fixed. I rewrote the entire script. It's now much simpler and the script hasn't failed as of jet. For now this is an example of the script output:
Here is the code for the grand exchange library:Code:fishing bait buy price: 5 sell price: 4 Profit for fishing bait: 1 willow logs buy price: 23 sell price: 22 Profit for willow logs: 1 raw herring buy price: 31 sell price: 17 Profit for raw herring: 14 feather buy price: 42 sell price: 41 Profit for feather: 1 maple logs buy price: 26 sell price: 24 Profit for maple logs: 2
Simba Code:(*
Grand Exchange
==============
The grandexchange file holds functions and procedures that are used to interact with the runescape Grand Exchange.
The source for this file can be found `here <https://github.com/SRL/SRL-6/blob/master/lib/interfaces/grandexchange.simba>`_.
*)
{$f-}
(*
Consts, Types, Vars
~~~~~~~~~~~~~~~~~~~
The following constants, types and variables are used throughout the collectBox methods.
**const Grand Exchange Tabs**
Constants that represent the two grandExchange tabs
* GE_TAB_EXCHANGE
* GE_TAB_HISTORY
*)
const
GE_TAB_EXCHANGE = 0;
GE_TAB_HISTORY = 1;
GE_TAB_SETS = 2;
(*
**type TRSGrandExchange**
.. code-block:: pascal
type
TRSGrandExchange = type TRSInterface;
A type that stores the Grand Exchange interface properties.
*)
type
TRSGrandExchange = record(TRSInterface)
tabBoxes: TBoxArray;
confirmBox: TBox;
end;
(*
**var grandExchange**
.. code-block:: pascal
var
grandExchange: TRSGrandExchange;
A variable through which scripters can access the TRSGrandExchange type methods.
*)
var
grandExchange: TRSGrandExchange;
(*
TRSGrandExchange methods
~~~~~~~~~~~~~~~~~~~~~~~~~
The following methods should be called through the **grandExchange** variable.
Example:
.. code-block:: pascal
if grandExchange.isOpen() then
writeln('It''s open');
*)
{*
__init
------
.. code-block:: pascal
procedure TRSGrandExchange.__init();
Initializes the TRSGrandExchange.
.. note::
- by The Mayor
- Last Updated: 9th October 2014 by Clarity
Example:
.. code-block:: pascal
grandExchange.__init();
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__init();
begin
with self do
begin
name := 'Grand Exchange';
ID := ID_INTERFACE_GRANDEXCHANGE;
parentID := -1;
static := false;
end;
end;
{$ENDIF}
{*
__find
------
.. code-block:: pascal
function TRSGrandExchange.__find(): boolean;
Returns true if the grandExchange interface is detected and its bounds are set.
Scripters should use grandExchange.isOpen() below.
.. note::
- by The Mayor
- Last Updated: 6 July 2015 by The Mayor
Example:
.. code-block:: pascal
if grandExchange.__find() then
writeln('The grandExchange is open, and the bounds are set!');
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__find(): boolean;
const
PINK_COLOR = [14581920, 0]; // [Col, Tol] pink item in the balance scale.
var
i: Integer;
TPA: TPointArray;
ATPA: T2DPointArray;
b: TBox;
begin
findColorsTolerance(TPA, PINK_COLOR[0], getClientBounds(), PINK_COLOR[1]);
if length(TPA) < 10 then
begin
print('TRSGrandExchange.__find(): Didn''t find enough PINK_COLOR', TDebug.WARNING);
exit(false);
end;
ATPA := TPA.cluster(5);
ATPA.sortBySize(true);
for i := 0 to high(ATPA) do
begin
b := ATPA[i].getBounds();
if inRange(b.getWidth(), 10, 20) and (b.getHeight() < 20) then
begin
b.edit(21, -10, 114, 12);
if (pos('GRAND', upperCase(tesseract_GetText(b, TESS_FILTER_SMALL_CHARS))) > 0) then
begin
self.setBounds([b.x1 - 88, b.y1 - 8, b.x2 + 570, b.y2 + 515]);
self.tabBoxes := grid(3, 1, 60, 22, 107, 0, point(x1 + 92, y1 + 113));
self.confirmBox := [self.x1 + 218, self.y1 + 511, self.x1 + 340, self.y1 + 524];
exit(true);
end;
end;
end;
end;
{$ENDIF}
(*
isOpen
------
.. code-block:: pascal
function TRSGrandExchange.isOpen(waitTime: integer = 0): boolean;
Returns true if the grandExchange is open. The optional **waitTime** parameter
*(default = 0)* is the maximum time (in milliseconds) it will keep looking.
.. note::
- by The Mayor
- Last Updated: 14 January 2015 by The Mayor
Example:
.. code-block:: pascal
if grandExchange.isOpen() then
writeln('The grandExchange is open!');
*)
function TRSGrandExchange.isOpen(waitTime: integer = 0): boolean;
var
t: UInt64;
begin
t := (getTickCount64() + waitTime);
repeat
if self.__find() then
begin
result := true;
break();
end;
until (getSystemTime() >= t);
print('TRSGrandExchange.isOpen(): Result = ' + boolToStr(result));
end;
(*
close
-----
.. code-block:: pascal
function TRSGrandExchange.close(escape: boolean = true): boolean;
Returns true if the grandExchange is successfully closed. It uses the ESC key
by default, but the **escape** parameter can be set to false to close via the mouse.
.. note::
- by The Mayor
- Last Updated: 6 July 2015 by The Mayor
Example:
.. code-block:: pascal
if grandExchange.close() then
writeln('Closed the grandExchange');
*)
function TRSGrandExchange.close(escape: boolean = true): boolean;
const
__CLOSE_OFFSET: TPoint = [756, 22]; // From self(x1, y1) to middle of 'X'
var
timeOut: UInt64;
begin
if (not self.isOpen()) then
exit(true);
if escape then // Try the escape button first if possible
begin
timeOut := (getTickCount64() + randomRange(600, 900));
repeat
typeByte(VK_ESCAPE);
wait(300 + random(50));
until (not self.isOpen()) or (getTickCount64() > timeOut);
if (not self.isOpen()) then
exit(true);
end;
if self.isOpen(100 + random(50)) then // Wait a bit in case it closes
begin
mouse(point(self.x1 + __CLOSE_OFFSET.x, self.y1 + __CLOSE_OFFSET.y).rand(3), MOUSE_LEFT);
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;
end else
result := true;
print('TRSGrandExchange.close(): result = ' + boolToStr(result), TDebug.SUB);
end;
{*
__getActiveTab
--------------
.. code-block:: pascal
function TRSGrandExchange.__getActiveTab(): Integer;
Returns the current tab number (0 - Grand Exchange | 1 - Sale History).
.. note::
- by The Mayor
- Last Updated: 9 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__getActiveTab());
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getActiveTab(): Integer;
var
i: Integer;
begin
for i := 0 to high(self.tabBoxes) do
if (not (getColor(self.tabBoxes[i].X2, self.tabBoxes[i].Y2) = 9078134)) then
exit(i);
end;
{$ENDIF}
(*
openTab
-------
.. code-block:: pascal
function TRSGrandExchange.openTab(tab: Integer): Boolean;
Opens the grandExchange tab **tab** . The **tab** parameter should be one of the
two tab constants at the top of this page.
.. note::
- by The Mayor
- Last Updated: 9 July 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.openTab(GE_TAB_HISTORY);
*)
function TRSGrandExchange.openTab(tab: Integer): Boolean;
begin
if (not self.isOpen()) then
exit(false);
if (self.__getActiveTab() = tab) then
exit(true);
for 0 to 3 do
begin
multiClick(self.tabBoxes[tab].getGaussPoint(), 30, 3);
wait(random(800, 1200));
if (self.__getActiveTab() = tab) then exit(true);
end;
end;
(*
getPackSlotBox
--------------
.. code-block:: pascal
function TRSGrandExchange.getPackSlotBox(slot: integer): TBox;
Returns a TBox of the pack slot **slot** in the grandExchange interface.
.. note::
- by The Mayor
- Last Updated: 6 July 2015 by The Mayor
Example:
.. code-block:: pascal
var
b: TBox;
begin
b := grandExchange.getPackSlotBox(1);
mouseBox(b, MOUSE_MOVE);
end;
*)
function TRSGrandExchange.getPackSlotBox(slot: integer): TBox;
const
__PACK_OFFSET: TPoint = [582, 174]; // From self(x1, y1) to middle of first pack slot
begin
result := gridBox(slot - 1, 4, 7, 36, 32, 46, 36, point(self.x1 + __PACK_OFFSET.x, self.y1 + __PACK_OFFSET.y));
end;
{*
__getSlotBoxes
--------------
.. code-block:: pascal
function TRSGrandExchange.__getSlotBoxes(): TBoxArray;
Returns a TBoxArray of the 8 Grand Exchange slots.
.. note::
- by The Mayor
- Last Updated: 19 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
tba := grandExchange.__getSlotBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getSlotBoxes(): TBoxArray;
const
__GE_SLOT_OFFSET: TPoint = [104, 203]; // From self(x1, y1) to middle of first GE slot
var
tba: TBoxArray;
begin
tba := grid(3, 3, 169, 121, 177, 128, point(self.x1 + __GE_SLOT_OFFSET.x, self.y1 + __GE_SLOT_OFFSET.y));
tba.deleteIndex(8);
result := tba;
end;
{$ENDIF}
{*
__getBuyBoxes
-------------
.. code-block:: pascal
function TRSGrandExchange.__getBuyBoxes(): TBoxArray;
Returns a TBoxArray of the Grand Exchange buy boxes.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
tba := grandExchange.__getBuyBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getBuyBoxes(): TBoxArray;
const
__BUY_OFFSET: TPoint = [74, 213]; // From self(x1, y1) to middle of first buy button
var
tba: TBoxArray;
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.__getBuyBoxes(): Cannot click a buy box as the GE is not open', TDebug.ERROR);
exit();
end;
tba := grid(3, 3, 44, 44, 177, 128, point(self.x1 + __BUY_OFFSET.x, self.y1 + __BUY_OFFSET.y));
tba.deleteIndex(8);
result := tba;
end;
{$ENDIF}
{*
__getSellBoxes
--------------
.. code-block:: pascal
function TRSGrandExchange.__getSellBoxes(): TBoxArray;
Returns a TBoxArray of the Grand Exchange sell boxes.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
tba := grandExchange.__getSellBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getSellBoxes(): TBoxArray;
const
__SELL_OFFSET: TPoint = [134, 213]; // From self(x1, y1) to middle of first sell button
var
tba: TBoxArray;
begin
tba := grid(3, 3, 44, 44, 177, 128, point(self.x1 + __SELL_OFFSET.x, self.y1 + __SELL_OFFSET.y));
tba.deleteIndex(8);
result := tba;
end;
{$ENDIF}
{*
__getInputBoxes
---------------
.. code-block:: pascal
function TRSGrandExchange.__getInputBoxes(): TBoxArray;
Returns a TBoxArray of the Grand Exchange input boxes, where you can type.
.. note::
- by Clarity
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
tba := grandExchange.__getInputBoxes();
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__getInputBoxes(): TBoxArray;
var
TPA: TPointArray;
ATPA: T2DPointArray;
i: integer;
begin
grandExchange.__find;
if findColors(TPA, 1388125, self.getBounds()) then
begin
ATPA := TPA.cluster(1);
ATPA.sortFromFirstPoint(Point(233, 261)); //changed this
result := ATPA.getEachBounds();
end;
end;
{$ENDIF}
{*
__isOfferOpen
-------------
.. code-block:: pascal
function TRSGrandExchange.__isOfferOpen(waitTime: integer = 500): boolean;
Returns true if the buy or sell offer screen is open.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
writeLn(grandExchange.__isOfferOpen());
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isOfferOpen(waitTime: integer = 500): boolean;
var
timeOut: UInt64;
TPA: TPointArray;
begin
timeOut := getTickCount64() + waitTime;
while (getTickCount64() < timeOut) do
if findColors(TPA, 1388125, self.getBounds()) then
begin
if (length(TPA) = 1532) or (length(TPA) = 492) then
exit(true);
end;
end;
{$ENDIF}
{*
__isProgressOpen
----------------
.. code-block:: pascal
function TRSGrandExchange._isProgressOpen(waitTime: integer = 500): boolean;
Returns true if the offer in progress screen is open.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
writeLn(grandExchange.__isProgressOpen());
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isProgressOpen(waitTime: integer = 500): boolean;
var
timeOut: integer;
TPA: TPointArray;
begin
timeOut := getTickCount64() + waitTime;
while (getTickCount64() < timeOut) do
if findColors(TPA, 6247745, self.getBounds()) then
begin
if (length(TPA) = 3501) then
exit(true);
end;
end;
{$ENDIF}
{*
__isSlotActive
--------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotActive(geSlot: integer): boolean;
Returns true if the slot **geSlot** is active. This is necessary
because slots 3 to 8 are inactive when you are not a member.
.. note::
- by The Mayor
- Last Updated: 10 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotActive(1));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotActive(geSlot: integer): boolean;
var
TPA: TPointArray;
TBA : TBoxArray := self.__getSlotBoxes();
begin
findColors(TPA, 5063989, TBA[geSlot - 1]);
result := length(TPA) < 5000;
end;
{$ENDIF}
{*
__isSlotEmpty
-------------
.. code-block:: pascal
function TRSGrandExchange._isSlotEmpty(geSlot: integer): boolean;
Returns true if the offer slot **geSlot** is empty and avaliable to use.
.. note::
- by The Mayor
- Last Updated: 10 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotEmpty(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotEmpty(geSlot: integer): boolean;
var
TPA: TPointArray;
TBA : TBoxArray := self.__getSlotBoxes();
begin
if self.__isSlotActive(geSlot) then
begin
findColors(TPA, 2694922, TBA[geSlot - 1]);
result := length(TPA) > 10000;
end;
print('TRSGrandExchange._isSlotEmpty(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotComplete
----------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotComplete(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is complete.
.. note::
- by The Mayor
- Last Updated: 15 January 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotComplete(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotComplete(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
begin
result := (countColorTolerance(1999423, TBA[geSlot - 1], 17) > 1450);
print('TRSGrandExchange.isSlotComplete(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotAborted
---------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotAborted(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is aborted.
.. note::
- by The Mayor
- Last Updated: 15 January 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotAborted(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotAborted(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
begin
result := (countColorTolerance(983163, TBA[geSlot - 1], 16) > 1700);
print('TRSGrandExchange.isSlotAborted(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotBuying
--------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotBuying(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is currently buying.
.. note::
- by The Mayor
- Last Updated: 31 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange.__isSlotBuying(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotBuying(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
TPA, TPA2: TPointArray;
begin
if self.__isSlotAborted(geSlot) or self.__isSlotComplete(geSlot)
then exit(false);
findColors(TPA, 2433824, TBA[geSlot - 1]);
findColors(TPA2, 3815734, TBA[geSlot - 1]); // If hovering the box
TPA.combine(TPA2);
result := (length(TPA) > 10000);
print('TRSGrandExchange.isSlotBuying(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__isSlotSelling
---------------
.. code-block:: pascal
function TRSGrandExchange.__isSlotSelling(geSlot: integer): boolean;
Returns true if the offer is slot **geSlot** is currently selling.
.. note::
- by The Mayor
- Last Updated: 31 July 2015 by The Mayor
Example:
.. code-block:: pascal
writeLn(grandExchange._isSlotSelling(2));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__isSlotSelling(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
TPA, TPA2: TPointArray;
begin
if self.__isSlotAborted(geSlot) or self.__isSlotComplete(geSlot)
then exit(false);
findColors(TPA, 3287837, TBA[geSlot - 1]);
findColors(TPA2, 4603955, TBA[geSlot - 1]); // If hovering the box
TPA.combine(TPA2);
result := (length(TPA) > 10000);
print('TRSGrandExchange.isSlotSelling(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
{$ENDIF}
{*
__findInsertionCursor
---------------------
.. code-block:: pascal
TRSGrandExchange.__findInsertionCursor(searchBox: TBox; waitTime: integer = 4000): boolean;
Returns true is the insertion cursor is found inside **searchBox** within the **waitTime**
*(default = 4000)* .
.. note::
- by Clarity
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
writeLn(grandExchange.__findInsertionCursor(b));
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__findInsertionCursor(searchBox: TBox; waitTime: integer = 4000): boolean;
var
timeOut: UInt64;
TPA: TPointArray;
begin
timeOut := getTickCount64() + waitTime;
while getTickCount64() < timeOut do
begin
findColors(TPA, 14606050, searchBox);
if length(TPA) > 0 then
exit(true);
end;
end;
{$ENDIF}
{*
__enterQuantity
---------------
.. code-block:: pascal
procedure TRSGrandExchange.__enterQuantity(quantity: string);
Returns true if it successfully enters the desired item quantity **quantity**
into the input box.
.. note::
- by The Mayor
- Last Updated: 19 November 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.__enterQuantity('1500'); // To buy/sell 1500 of an item
grandExchange.__enterQuantity('all'); // To SELL all of the item
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__enterQuantity(quantity: string);
var
i: integer;
strArr : TStringArray;
inputBox: TBoxArray;
amountBox: TBoxArray := grid(4, 1, 34, 24, 44, 0, point(self.x1 + 84, self.y1 + 298));
begin
strArr := ['1', '10', '100', 'all'];
i := strArr.returnInArray(lowercase(quantity));
if inRange(i, 0, 3) then
mouseBox(amountBox[i], MOUSE_LEFT)
else
begin
inputBox := self.__getInputBoxes();
mouseBox(inputBox[0], MOUSE_LEFT);
if self.__findInsertionCursor(inputBox[0]) then
begin
typeSend(toStr(quantity), true);
wait(randomRange(1000, 1500));
end;
end;
end;
{$ENDIF}
{*
__enterPrice
------------
.. code-block:: pascal
procedure TRSGrandExchange.__enterPrice(price: string);
Returns true if it successfully enters the desired item price **price**
into the input box.
.. note::
- by The Mayor
- Last Updated: 19 November 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.__enterPrice('+5'); // Will click the +5% button
grandExchange.__enterPrice('mid'); // Will leave at mid price
grandExchange.__enterPrice('32500'); // Will type in 32500
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__enterPrice(price: string);
var
i: integer;
b: TBox;
strArr : TStringArray;
priceBox, inputBox: TBoxArray;
begin
priceBox := grid(3, 1, 34, 24, 45, 0, point(self.x1 + 367, self.y1 + 298));
strArr := ['-5', 'mid', '+5'];
i := strArr.returnInArray(lowercase(price));
if (i = 0) or (i = 2) then
mouseBox(priceBox[i], MOUSE_LEFT)
else if (i <> 1) then // Don't click mid button as it's set by default
begin
inputBox := self.__getInputBoxes();
mouseBox(inputBox[1], MOUSE_LEFT);
if self.__findInsertionCursor(inputBox[1]) then
begin
typeSend(toStr(price), true);
wait(randomRange(1000, 1500));
end;
end;
end;
{$ENDIF}
{*
__enterName
-----------
.. code-block:: pascal
procedure TRSGrandExchange.__enterName(itemName: string)
Returns true if it successfully types the item name **itemName** into the search
box and clicks it.
.. note::
- by The Mayor
- Last Updated: 24 Decenber 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.__enterName('Swamp toad');
*}
{$IFNDEF CODEINSIGHT}
function TRSGrandExchange.__enterName(itemName: string): boolean;
const
TESS_FILTER_GE_CHARS: TTesseractFilter = [4, 4, [False, 20, TM_Mean]];
var
i: integer;
timeOut: UInt64;
resultsBox: TBoxArray := grid(3, 2, 166, 49, 172, 55, point(self.x1 + 104, self.y1 + 405));
resultsTextBox: TBoxArray := grid(3, 2, 122, 16, 172, 55, point(self.x1 + 121, self.y1 + 396));
inputBox: TBoxArray;
begin
timeOut := getTickCount64() + randomRange(3000, 4000);
inputBox := self.__getInputBoxes();
if not self.__findInsertionCursor(inputBox[2]) then
mouseBox(inputBox[2], MOUSE_LEFT);
if self.__findInsertionCursor(inputBox[2]) then
typeSend(itemName, false);
if waitColorCountRange(9214319, 10, resultsTextBox[0], 5000, 10) then
for i := 0 to 5 do
if stringMatch(trim(tesseractGetText(resultsTextBox[i], TESS_FILTER_GE_CHARS)), itemName) >= 0.7 then
begin
mouseBox(resultsBox[i], MOUSE_LEFT);
waitColorCountRange(16777215, 3, inputBox[2], 5000, 507, 509);
exit(true);
end;
print('TRSGrandExchange.__enterName(): Found no matches for item: ' + itemName, TDebug.SUB);
end;
{$ENDIF}
{*
__returnToSummary
-----------------
.. code-block:: pascal
procedure TRSGrandExchange._returnToSummary();
If the GE offer screen or GE progress screen is currently open, it will click
the back arrow to return to the summary screen.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.__returnToSummary();
*}
{$IFNDEF CODEINSIGHT}
procedure TRSGrandExchange.__returnToSummary();
var
backButton: TPoint := [self.x1 + 33, self.y1 + 515];
timeOut: UInt64;
begin
if self.__isOfferOpen() or self.__isProgressOpen() then
begin
print('TRSGrandExchange._returnToSummary(): returning to summary screen', TDebug.SUB);
multiClick(backButton.rand(5), 30, 3);
timeOut := getTickCount64() + randomRange(2500, 3500);
while getTickCount64() < timeOut do
begin
if ((not self.__isOfferOpen()) and (not self.__isProgressOpen())) then
break();
end;
end;
end;
{$ENDIF}
(*
collectSlot
-----------
.. code-block:: pascal
function TRSGrandExchange.collectSlot(geSlot: integer): boolean;
Returns true if it collects coins and/or items from the completed or aborted slot
**geSlot** .
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.collectSlot(2);
*)
function TRSGrandExchange.collectSlot(geSlot: integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
collectBox: TBoxArray := grid(2, 1, 37, 32, 49, 0, point(self.x1 + 463, self.y1 + 385));
timeOut: UInt64;
i: integer;
begin
if not self.__isProgressOpen() then
begin
self.__returnToSummary();
if (not self.__isSlotActive(geSlot)) or self.__isSlotEmpty(geSlot) then
begin
print('TRSGrandExchange.collectSlot(): Cannot collect as offer slot ' + toStr(geSlot) + ' is empty', TDebug.ERROR);
exit(false);
end;
timeOut := getTickCount64() + randomRange(3000, 4000);
repeat
mouseBox(TBA[geSlot - 1], MOUSE_LEFT);
if self.__isProgressOpen(2000 + random(500)) then
break();
until (getTickCount64() < timeOut);
end;
for i := high(collectBox) downto 0 do
for 0 to 2 do // Attempt up to 3 times in case of lag
if isItemIn(collectBox[i]) then
begin
mouseBox(collectBox[i], MOUSE_LEFT);
wait(randomRange(750, 1250));
if not self.__isProgressOpen() then
begin
result := true;
break(1);
end;
end;
self.__returnToSummary();
print('TRSGrandExchange.collectSlot(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result));
end;
(*
waitCollectSlot
---------------
.. code-block:: pascal
function TRSGrandExchange.waitCollectSlot(geSlot, maxTime: integer): boolean;
Returns true if it collects coins and/or items from the completed or aborted slot
**geSlot** . Waits up to **maxTime** for **geSlot** to finish selling.
.. note::
- by The Mayor
- Last Updated: 12 March 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.waitCollectSlot(2, 60000); // Wait up to 1 minute to collect slot 2
*)
function TRSGrandExchange.waitCollectSlot(geSlot, maxTime: Integer): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
timeOut: UInt64;
begin
self.__returnToSummary();
if (not self.__isSlotActive(geSlot)) or self.__isSlotEmpty(geSlot) then
begin
print('TRSGrandExchange.waitCollectSlot(): Cannot collect as offer slot ' + toStr(geSlot) + ' is empty', TDebug.ERROR);
exit(false);
end;
timeOut := getTickCount64() + maxTime;
while (getTickCount64() < timeOut) do
if self.__isSlotComplete(geSlot) then
begin
if self.collectSlot(geSlot) then
begin
result := true;
break();
end;
end else
wait(500);
print('TRSGrandExchange.waitCollectSlot(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result), TDebug.SUB);
end;
(*
collectAllSlots
---------------
.. code-block:: pascal
procedure TRSGrandExchange.collectAllSlots(toInventory: boolean = true): boolean;
Collects all coins and items to either the inventory or the bank depending on the
**toInventory** paramter *(default = true)* via the collect buttons.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.collectAllSlots(false); // Collect all to bank
*)
procedure TRSGrandExchange.collectAllSlots(toInventory: boolean = true);
const
_OFFSET: TPoint = [653, 481];
var
TBA: TBoxArray;
begin
TBA := grid(1, 2, 180, 20, 0, 36, point(self.x1 + _OFFSET.x, self.y1 + _OFFSET.y));
case ToInventory of
true: multiClick(TBA[0].getMiddle().rand(5), 25, 3);
false: multiClick(TBA[1].getMiddle().rand(5), 25, 3);
end;
end;
(*
abortSlot
---------
.. code-block:: pascal
function TRSGrandExchange.abortSlot(geSlot: integer; collect: boolean = true): boolean;
Returns true if it aborts the slot **geSlot**. If the **collect** parameter is
set to true it will also collect the items and gold from the aborted offer.
.. note::
- by The Mayor
- Last Updated: 27 July 2015 by Clarity
Example:
.. code-block:: pascal
grandExchange.abortSlot(2);
grandExchange.abortSlot(2, false); // To leave items in the aborted offer slot
*)
function TRSGrandExchange.abortSlot(geSlot: integer; collect: boolean = true): boolean;
var
TBA: TBoxArray := self.__getSlotBoxes();
abortButton: TPoint := [self.x1 + 402, self.y1 + 383];
redBox: TBox := [self.x1 + 29, self.y1 + 404, self.x1 + 423, self.y1 + 410];
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.abortSlot(): Cannot abort as the GE is not open', TDebug.ERROR);
exit(false);
end;
self.__returnToSummary();
if self.__isSlotEmpty(geSlot) or (not self.__isSlotActive(geSlot)) then
begin
print('TRSGrandExchange.abortSlot(): Cannot abort as offer slot ' + toStr(geSlot) + ' is empty', TDebug.ERROR);
exit(false);
end;
if self.__isSlotAborted(geSlot) then
begin
print('TRSGrandExchange.abortSlot(): Offer slot ' + toStr(geSlot) + ' is already aborted');
exit(true);
end;
if self.__isSlotComplete(geSlot) then
begin
print('TRSGrandExchange.abortSlot(): Cannot abort as offer slot ' + toStr(geSlot) + ' is already completed', TDebug.ERROR);
exit(false);
end;
mouseBox(TBA[geSlot - 1], MOUSE_LEFT, MOUSE_ACCURATE);
if self.__isProgressOpen(3000) then
begin
multiClick(abortButton.rand(5), 30, 3);
waitColorCountRange(1048714, 5, redBox, 4000, 2000);
if collect then
result := self.collectSlot(geSlot)
else
begin
result := self.__isSlotAborted(geSlot);
self.__returnToSummary();
end;
end;
print('TRSGrandExchange.abortSlot(): Slot ' + toStr(geSlot) + ' = ' + boolToStr(result));
end;
(*
abortAllSlots
-------------
.. code-block:: pascal
procedure TRSGrandExchange.abortAllSlots(collect: boolean);
Aborts all slots that are not currently empty. If the **collect** parameter is
set to true, it will also collect all items and gold.
.. note::
- by The Mayor
- Last Updated: 12 March 2015 by The Mayor
Example:
.. code-block:: pascal
grandExchange.abortAllSlots();
*)
procedure TRSGrandExchange.abortAllSlots(collect: boolean = true);
var
i: integer;
TBA: TBoxArray := self.__getSlotBoxes();
begin
for i := 1 to length(TBA) do
if (not self.__isSlotEmpty(i)) and self.__isSlotActive(i) then
self.abortSlot(i, collect);
end;
(*
getPercentDone
--------------
.. code-block:: pascal
function TRSGrandExchange.getPercentDone(geSlot: integer): integer;
Returns the percentage toward completion for the offer in **geSlot** .
.. note::
- by turpinator
- Last Updated: 19 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
var
per: Integer;
begin
per := grandExchange.getPercentDone(2);
writeLn('Slot 2 is ' + toStr(per) + ' percent complete!');
end;
*)
function TRSGrandExchange.getPercentDone(geSlot: integer): integer;
const
BG_COLORS = [2565929, 2039584, 2237482, 1776673];
var
i, x, y: integer;
TBA: TBoxArray := self.__getSlotBoxes();
begin
if self.__isSlotEmpty(geSlot) or (not self.__isSlotActive(geSlot)) then exit(-1);
x := TBA[geSlot -1].x1 + 8;
y := TBA[geSlot -1].y1 + 100;
for result := 153 downto 1 do
if (getColor(x + result, y) <> BG_COLORS[0]) and (getColor(x + result, y) <> BG_COLORS[1]) then
exit(round(0.6897 * result));
end;
(*
sellItem
--------
.. code-block:: pascal
function TRSGrandExchange.sellItem(packSlot: integer; price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
Returns true if it sells the item in backpack slot **packSlot** . If **waitCollect**
is set to true, it will wait the specified waitTime for the offer to complete
before collecting the resulting gold.
The **price** parameter is a string - valid options are:
* 'mid' : GE mid price button
* '-5' : 5% below mid price button
* '+5' : 5% above mid price button
* Any other number : It will enter the price
The **quantity** parameter is a string - valid options are:
* '1' : '1' button
* '10' : '10' button
* '100' : '100' button
* 'all' : 'All' button (Selling ONLY)
* Any other number : It will enter the quantity
.. note::
- by The Mayor
- Last Updated: 13 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
// Sell all of item in backPack slot 1 for mid price
grandExchange.sellItem(1, 'mid', 'all');
// To sell 100 of the item in backPack slot 1, for 1500gp each
grandExchange.sellItem(1, '1500', '100');
// As above, but waits up to 20 seconds for completion before collecting the coins
grandExchange.sellItem(1, '1500', '100', true, 20000);
*)
function TRSGrandExchange.sellItem(packSlot: integer; price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
var
i, nextSlot: integer;
confirm: TBox := [self.x1 + 218, self.y1 + 508, self.x1 + 345, self.y1 + 526];
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.sellItem(): Cannot abort as the GE is not open', TDebug.ERROR);
exit(false);
end;
self.__returnToSummary();
for i := 1 to 8 do
if self.__isSlotEmpty(i) and self.__isSlotActive(i) then
begin
nextSlot := i;
break();
end;
if nextSlot < 1 then
begin
print('TRSGrandExchange.sellItem(): Cannot sell item as there are no empty offer slots', TDebug.ERROR);
exit(false);
end;
if isItemIn(self.getPackSlotBox(packSlot)) then
mouseBox(self.getPackSlotBox(packSlot), MOUSE_LEFT, MOUSE_ACCURATE)
else
begin
print('TRSGrandExchange.sellItem(): No item in pack slot: ' + intToStr(packSlot), TDebug.ERROR);
exit(false);
end;
if self.__isOfferOpen(3000) then
begin
self.__enterQuantity(quantity);
self.__enterPrice(price);
mouseBox(confirm, MOUSE_LEFT, MOUSE_ACCURATE);
wait(randomRange(1000, 1500));
end;
result:= self.__isSlotSelling(nextSlot);
print('TRSGrandExchange.sellItem(): ' + boolToStr(result), TDebug.SUB);
if waitCollect then
self.waitCollectSlot(nextSlot, waitTime);
end;
(*
buyItem
-------
.. code-block:: pascal
function TRSGrandExchange.buyItem(itemName, price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
Returns true if it buys the item **itemName** . If **waitCollect** is set to true,
it will wait the specified waitTime for the offer to complete before collecting
the resulting gold and items.
The **price** parameter is a string - valid options are:
* 'mid' : GE mid price button
* '-5' : 5% below mid price button
* '+5' : 5% above mid price button
* Any other number : It will enter the price
The **quantity** parameter is a string - valid options are:
* '1' : '1' button
* '10' : '10' button
* '100' : '100' button
* Any other number : It will enter the quantity
.. note::
- by The Mayor
- Last Updated: 13 November 2015 by SlipperyPickle
Example:
.. code-block:: pascal
// To buy 10000 oak logs at 5% over the mid price
grandExchange.buyItem('Oak log', '+5', '10000');
// To buy 10000 oak logs for 150gp each
grandExchange.buyItem('Oak log', '150', '10000');
// As above, but waits up to 20 seconds for completion before collecting items
grandExchange.buyItem('Oak log', '150', '10000', true, 20000);
*)
function TRSGrandExchange.buyItem(itemName, price, quantity: string; waitCollect: boolean = false; waitTime: integer = 10000): boolean;
var
i, nextSlot, x, y: integer;
b: TBox;
p: TPoint;
TBA : TBoxArray := self.__getBuyBoxes();
confirm: TBox := [self.x1 + 218, self.y1 + 508, self.x1 + 345, self.y1 + 526];
begin
if not self.isOpen() then
begin
print('TRSGrandExchange.sellItem(): Cannot abort as the GE is not open', TDebug.ERROR);
exit(false);
end;
self.__returnToSummary();
for i := 1 to 8 do
if self.__isSlotEmpty(i) and self.__isSlotActive(i) then
begin
nextSlot := i;
break();
end;
if nextSlot < 1 then
begin
print('TRSGrandExchange.sellItem(): Cannot sell item as there are no empty offer slots', TDebug.ERROR);
exit(false);
end;
mouseBox(TBA[nextSlot - 1], MOUSE_LEFT, MOUSE_ACCURATE);
if self.__isOfferOpen(3000) then
if self.__enterName(itemName) then
begin
self.__enterQuantity(quantity);
self.__enterPrice(price);
mouseBox(confirm, MOUSE_LEFT);
wait(randomRange(1000, 1500));
end else
self.__returnToSummary();
result := self.__isSlotBuying(nextSlot);
print('TRSGrandExchange.buyItem(): ' + boolToStr(result), TDebug.SUB);
if waitCollect then
self.waitCollectSlot(nextSlot, waitTime);
end;
(*
getPrice
--------
.. code-block:: pascal
TRSGrandExchange.getPrice(item: integer): integer;
Returns the current market price of any item in the Grand Exchange. The **item**
parameter must be the item's ID number.
IDs can be found on the Grand Exchange website at the end of the URL. For example,
the ID in the below URL is 2150 (Swamp toad)
http://services.runescape.com/m=itemdb_rs/viewitem.ws?obj=2150
.. note::
- by The Mayor
- Last Updated: 16 July 2015 by The Mayor
Example:
.. code-block:: pascal
var
toadPrice: Integer;
begin
toadPrice := grandExchange.getPrice(2150); // The ID for Swamp toads
profit := (toadPrice * toadsCollected);
end;
*)
function TRSGrandExchange.getPrice(ID: integer): integer;
var
webPage: string;
TSA: TStringArray;
begin
webPage := getPage('http://services.runescape.com/m=itemdb_rs/viewitem.ws?obj=' + toStr(ID));
TSA := multiBetween(webPage, 'average30.push([new Date(',']);');
if length(TSA) < 1 then
begin
print('TRSGrandExchange.getPrice(): Unable to retrieve price for ID: ' + toStr(ID), TDebug.ERROR);
exit(-1);
end;
result := strToInt(Between('), ', ',', TSA[High(TSA)]));
print('TRSGrandExchange.getPrice(' + toStr(ID) + '): ' + toStr(result));
end;
begin
grandExchange.__init();
end;
{$f+}
oh my, this is neat.
You should make sure you change the 'updated date', so all the other users know if something has been worked on since an RS update (as all this is displayed in the docs: http://docs.villavu.com/srl-6/grandexchange.html). If you fix all that up, then send in a pull request, or post it here and I will forward it on.
Update:
This project is now about 80% complete. I have made some great progress this week. The only part of the script that I can't get to work is the form to add items. But that's reserved for after my four week holiday.
Current functions/procedures in my include for this project:
Simba Code:{ ============================================================================ }
{ FUNCTIONS: > TItems }
{ > TItems.create() }
{ > TItems.buyCheck() }
{ > TItems.getLimit() }
{ > TItemArray }
{ > TItemArray.checkSelling() }
{ > TItemArray.takeBreak() }
{ > TItemArray.append() }
{ > TItemArray.returnInArray() }
{ > TItemArray.buyList() }
{ > TItemArray.saveData() }
{ > TItemArray.loadData() }
{ > TItemArray.updateItem }
{ > TItemArray.deleteIndex() }
{ > TItemArray.addIndex() }
{ > TItemArray.swap() }
{ > TItemArray.compare() }
{ > TItemArray.quickSort() }
{ > TItemArray.checkAll() }
{ > TRSGrandExchange }
{ > TRSGrandExchange.open() }
{ > TRSGrandExchange.getCurrentPrice() }
{ > TRSGrandExchange.openBox() }
{ > TRSGrandExchange.getMoney() }
{ ============================================================================ }
Current TODO list:
- Main loop;
- Form to choose items;
- Paint;
- Whatever I haven't thought about.
Show us some prog screens (if there's any) :P
As a lazy person that really dislike sitting at GE that script sounds like heaven.
Any progress?
Hey Pickle, any updates on this? I've been keeping an eye out for a release as I love flipping/merching but don't have time to do it all day.
There are currently 3 users browsing this thread. (0 members and 3 guests)