SRL Archive - RS has been updated.

Compilation of changes needed to SRL include


riwu

2012-11-20 05:45:02

This would be a full list of changes/additions needed to be made for the SRL include. While some changes may be obvious, there are not so obvious ones so if you notice any please report it.

Major
-Combat tab rework
~Retaliate
~GetCombatLevel
(fixed)

-Magic tab rework
~Abilities
~Magic spell casting/teleport

-Action bar

Minor
-Equipment tab graphical changes Seems like no changes to coordinates
-HpPercent calculation since MM hp increased drastically (Ashaman88 has come up with something)
-TypeSendEx will be affected as 'enter' has to be pressed to type (if action bar is active) (fixed)
-Function keys are disabled (i.e. FTab doesn't work) when action bar is inactive. (fixed)

Things that are changed but currently not related to SRL include (mention it too so that scripters are aware of changes needed to their scripts)
-Prayer tab graphical/coordinate changes
-Skill confirmation screens (crafting, fletching etc) moved to center of MS. (Thanks Le Jingle!)


Please raise any other differences that you have spotted!


Some functions that i've come up with: (https://github.com/SRL/SRL-5/pull/113)

Ability constants: http://villavu.com/forum/showpost.php?p=1131633&postcount=36


function ActionBarActive: Boolean; //returns true if Action Bar is active
var
BmpIcons: TIntegerArray;
i, l, x, y: Integer;
begin //standards ruin by Simba tag
BmpIcons := [BitmapFromString(9, 11, 'meJwTUzESltYBISW98OU7gSSUK60' + //trash icon
'jKqcvBpQFiwtIqUBkxVSMgVJA8bDlO4EoHBUBZYFSQMWYCCIVBjYq' +
'DGYghCQo5TcXxIWQ/jASIuUyAcSFkK4wElkKGUGkIJ617tgJRDYwB' +
'BThFpIGSvGKKQL1ApGoshHYHGOgOBABAAu4TYk='),

BitmapFromString(12, 10, 'meJyTkZaWIQJJSkiIi4mJiogICw' + //down arrow
'nBkYiwsJioqIS4OEQNUJZPQIiLl5+Dh4+VgxeC2NnYeLi5gSohaoA' +
'MPhlVt7m7LHr2KCQs4LFs4TGu4tbJZOWVEhIUhKgBmgnUopPR5rXm' +
'hkHzUUGfxQJOU7i14jk5OODmAC0VFBBg5xV2XXzBduZVsbCNwl6zW' +
'XikBPj5ge6EqJGSlAQaxc3FJese57rslljERm6tOKAhQHcCpSBqpK' +
'WkgF4D+gXoZvPWTeJB84BmAk0Gmg+UglgEMQpoLD8fn5CmObe6Jy8' +
'PD9BkoCBEjTDYVRCjgOJA7UBnAG0BciEKgAgAILwyWQ==')];

l:= High(BmpIcons);

for i:=0 to l do
begin
if not Result then
Result:= FindBitmapToleranceIn(BmpIcons[i], x, y, MSX1, 264, MSX2, MSY2, 20);
FreeBitmap(BmpIcons[i]);
end;
end; [/simba]

[simba]
function ToggleActionbar(ToggleOn: Boolean): Boolean; //Toggle action bar, returns true on success
var
tWait: Integer;
begin
if (ToggleOn xor ActionBarActive) then
begin
if ToggleOn then
MouseBox(499, 326, 516, 338, mouse_Left)
else
MouseBox(499, 264, 516, 277, mouse_Left);

tWait:= GetSystemTime + RandomRange(2444, 2777);
while tWait > GetSystemTime do
begin
Result:= not (ToggleOn xor ActionBarActive);
if Result then
Break;
wait(RandomRange(5, 20));
end;
end else
Result:= True;
end;
[/simba]

[simba]
//Combat tab changes
function GetCombatLevel: Integer;
begin
Result := -1;
if not FTab(tab_Combat) then
exit;

Result := StrToIntDef(ExtractFromStr(GetTextAtExWrap(556, 316, 584, 333, 0,
3, 4, 3111603, 0, UpChars), Numbers), -1);
end;

procedure Retaliate(RetTrue: Boolean);
begin
if not FTab(tab_Combat) then
Exit;

if (RetTrue) xor FindTextTPA(3111603, 0, 558, 437, 682, 455, 'On', UpChars, nothing) then
MouseBox(558, 437, 682, 455, mouse_left);
end;


function ChatActive: Boolean; //checks whether you are already typing
begin
Result:= not FindChatBoxText('Press Enter to Chat', 9, clBlack);
end;

Feel free to comment/improve on them.

Le Jingle

2012-11-20 05:51:37

I noticed the cooking screen / fletch screens /etc. that used to be in the chat box got moved to the MS.

l6bustank

2012-11-20 06:17:53

It is currently faster to manually click "done" and then bank, than to wait for the skill screen to disappear itself. Might need to review the angles of my scripts in order to bank faster in one-click banking spots :/

xtrapsp

2012-11-20 06:22:52

Surely this will work for typesend?

(*
TypeSendEx
~~~~~~~~~~

.. code-block:: pascal

procedure TypeSendEx(Text : string; PressEnter : Boolean);

Types text in a human-like way.

.. note::

by SKy Scripter

Example:

.. code-block:: pascal

*)
procedure TypeSendEx(Text: string; PressEnter: Boolean);
var
I: Integer;
begin
for i := 1 to Length(Text) do
begin
PressKey(13); // Press enter
{$IFDEF SIMBAMAJOR980}
SendKeys(Text[i], 40 + Random(40));
{$ELSE}
SendKeys(Text[i], 30 + Random(30), 30 + Random(30));
{$ENDIF}
Wait(40 + Random(40));
end;

if (PressEnter) then
TypeByte(VK_ENTER);
end;

just add the PressKey(13);

riwu

2012-11-20 06:53:18

From: xtrapsp
Surely this will work for typesend?

just add the PressKey(13);

Need to check if Action Bar is active first. Give me a moment.

xtrapsp

2012-11-20 07:43:49

From: riwu
Need to check if Action Bar is active first. Give me a moment.


Function SkillMenu: Boolean;
Var
CTS: Integer;
Begin
CTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);

SetColorSpeed2Modifiers(0.02, 0.36);

If CountColorTolerance(8280838,398,361-50,480,369-50,11) > 500 Then
Result:=True;

ColorToleranceSpeed(CTS);
SetColorSpeed2Modifiers(0.2, 0.2);
End;

if SkillMenu(False) then
bla bla bla


like that?

Ashaman88

2012-11-20 08:00:22

Also wrote a couple of functions for the new skill interfaces - in that same thread

P1ng

2012-11-20 08:14:07

There are no longer any damage splashes (blue/red splashes to indicate damage dealt) there is now only text. While the include didn't rely on this I know some scripts out there did.

superbuster4

2012-11-20 08:17:52

skilling interface redon, were looking at new things for crafting etc.

Ian

2012-11-20 08:32:49

From: P1ng
There are no longer any damage splashes (blue/red splashes to indicate damage dealt) there is now only text. While the include didn't rely on this I know some scripts out there did.


Mine :(. Also will the mainscreen coordinates need to be changed because of the action bar?

Flight

2012-11-20 08:53:59

For switching between modes in the Ability tab:

Const
status_Melee = 0;
status_Ranged = 1;
status_Magic = 2;
status_Defence = 3;

Function AbilityBook(Status: Integer): Boolean;
var
X,Y,xVal,tmpCTS,Col: Integer;
begin
GameTab(tab_Magic);
tmpCTS := GetToleranceSpeed;
SetColorToleranceSpeed(1);

case Status of
status_Melee:
begin
Col := 2265794;
xVal := 571;
end;
status_Ranged:
begin
Col := 3439164;
xVal := 618;
end;
status_Magic:
begin
Col := 8934432;
xVal := 665;
end;
status_Defence:
begin
Col := 2898337;
xVal := 712;
end;
end;

Result := FindColorTolerance(X,Y,Col,550,240,553,285,10);

if not Result then
begin
AL_BrakeMMouse(Point(xVal,222),10,10,True);
AL_FastClick(mouse_left);
Result := FindColorTolerance(X,Y,Col,550,240,553,285,10);
end;

SetColorToleranceSpeed(tmpCTS);
end;

Primitive, but there you go incase anyone else needs it.

J J

2012-11-20 09:01:16

World switcher is broken, atleast for me. Can anyone else try to let simba login to world 61?

riwu

2012-11-20 09:11:45

From: J J
World switcher is broken, atleast for me. Can anyone else try to let simba login to world 61?

Works for me :S
  SetupSRL;
if OpenWorldScreen then
SelectWorld(61);

World: 61, Players: 68, Members: False, PvP: False
World 61 selected.


Also sent a pull request
https://github.com/SRL/SRL-5/pull/113
to fix some of the functions that's not working properly.

Flight

2012-11-20 09:44:02

Also, here's a better "UsingActionBar":

Function UsingActionBar: Boolean;
var
X,Y,i: Integer;
begin
Result := False;

for i:=1 to 5 do
if FindText(x, y, ToStr(i), UpChars, 490, 300, 505, 315) then
begin
Result := True;
Exit;
end;
end;

Much cleaner, no?

Le Jingle

2012-11-20 15:39:52

I noticed another way (since I didn't bother with BETA earlier before release much) that the update speeds up skilling:

Instead of having to deal with a chat interface (ex. the mainscreen one I noted earlier), in the instance of cooking raw food, I can simply use my raw food and choose an option to cook right away, saving the hassle of clicking the 'click chat to cook,' or 'click mainscreen to cook' :)

riwu

2012-11-20 18:27:37

From: Flight
Also, here's a better "UsingActionBar":

Function UsingActionBar: Boolean;
var
X,Y,i: Integer;
begin
Result := False;

for i:=1 to 5 do
if FindText(x, y, ToStr(i), UpChars, 490, 300, 505, 315) then
begin
Result := True;
Exit;
end;
end;

Much cleaner, no?

There's a chance that it gets blocked if right clicking is performed at somewhere near it before it is called:


Which is why i decided to check for 2 far apart icons such that it is impossible that both are blocked.

Quite a few different ways to do this though, guess we have to experiment and find out the most accurate & fastest method? ;)

x[Warrior]x3500

2012-11-20 18:30:29

just so its not overlooked:

the makecompass (rs_getCompassAngleRadians…) color changed to 0 from 65565. manually changed it and it works well again.

KingKong

2012-11-20 18:36:36

From: riwu
There's a chance that it gets blocked if right clicking is performed at somewhere near it before it is called:


Which is why i decided to check for 2 far apart icons such that it is impossible that both are blocked.

Quite a few different ways to do this though, guess we have to experiment and find out the most accurate & fastest method? ;)


get the color of action bar(13224393) and countcolor of the line when its maximized.

riwu

2012-11-20 18:38:36

From: x[Warrior]x3500
just so its not overlooked:

the makecompass (rs_getCompassAngleRadians…) color changed to 0 from 65565. manually changed it and it works well again.

Uhm which color in which function?

Lalaji

2012-11-20 19:01:52

From: Le Jingle
I noticed another way (since I didn't bother with BETA earlier before release much) that the update speeds up skilling:

Instead of having to deal with a chat interface (ex. the mainscreen one I noted earlier), in the instance of cooking raw food, I can simply use my raw food and choose an option to cook right away, saving the hassle of clicking the 'click chat to cook,' or 'click mainscreen to cook' :)


Can you elaborate how to "simply use my raw food and choose an option to cook right away." You still have to use food -> with fire, and then select cook on the mainscreen, right?

Le Jingle

2012-11-20 19:14:32

Err I can't replicate it now that you say it, I think I'm pretty sure I had something as the raw food in my action bar and could cook it simply with choosing this right click (as it's never previously been there/available in a right click before);


euphemism

2012-11-20 20:01:46

Submitted a pull request for an 'IsActionBarOpen' function, and a 'ToggleActionBar' function. So far, they seem to be the cleanest implementation for checking/toggling the bar.


(*

Action Bar
----------

Action Bar related functions

*)

(*
IsActionBarOpen
~~~~~~~~~~~~~~~

.. code-block:: pascal

function IsActionBarOpen(): Boolean;

Results True if the Action Bar is showing.

.. note::

by euphemism

*)

function IsActionBarOpen(): Boolean;
begin
Result := ((GetColor(45, 283) = 2697663) or (GetColor(473, 283) = 2697663));
end;

(*
ToggleActionBar
~~~~~~~~~~~~~~~

.. code-block:: pascal

function ToggleActionBar(Open: Boolean): Boolean;

Opens or closes the Action Bar, true if had to toggle.

.. note::
by euphemism, modelled after ToggleXPBarEx by Narcle & IceFire908

*)

function ToggleActionBar(Open: Boolean): Boolean;
var
T: Integer;
MBox: TBox;
begin
if (Open xor IsActionBarOpen()) then
begin
if Open then
MouseBox(500, 327, 515, 337, MOUSE_LEFT)
else
MouseBox(500, 265, 515, 275, MOUSE_LEFT);
T := GetSystemTime + 300;
repeat
wait(1);
Result := (Open = IsActionBarOpen());
until Result or (GetSystemTime > t);
end else
Result := true;
end;

Le Jingle

2012-11-20 21:12:49

Here's something that might also work for Fixed mode -> finding out open/closed action bar…

Basically looks for 3 border colors and if it finds 1 good match it'll be closed: but if it finds 2 good matches, it'll think it's open.

Seems to work good, I usually like TPAs over Bmps but if Bmps work better then I can live with that :)
source;

{$i srl/srl.simba}
{$i srl/srl/misc/debug.simba}

function isActionClosed: boolean;
var
i: integer;
abox: TBox;
colors: TIntegerArray;
ATPA: T2DPointArray;
begin
colors := [13224393, 3421236, 2566184]; // colors that seem static and will be measured.
SetLength(ATPA, length(colors));
for i := 0 to High(colors) do
FindColorsTolerance(ATPA[i], colors[i], MSX1, 260, MSX2, MSY2, 5); // gathers the 3 colors we want

SortATPASize(ATPA, true);
//may want to check here, for least size/lengths of index 0 and 1 so we're not comparing 2 bad results?
if (InRange(Length(ATPA[0]), Length(ATPA[1])-15, Length(ATPA[1])+15)) then
begin
writeln('we have 2 good results that means there should be 2 indicators for open bar');
result := false;
exit;
end;

aBox := GetTPABounds(ATPA[0]);
result := (MiddleBox(aBox).y - MCY1) < 20; // could probably be measured better, I ball parked it

DebugATPA(ATPA, 'Deletetete');
end;

*** I kind of condensed two functions into 1, so it's probably necessary to parse the code to work more efficiently?

x[Warrior]x3500

2012-11-20 21:41:25

From: riwu
Uhm which color in which function?

sry, i just ctrl+clicked till i got to the root color finding function of makecompass(); this is it. as you can see, it has findcolorsspiraltolerance changed already to the color 0, which i did so i can get my advanced barb agility script runnin. (its the color of the "N" in the compass)

Function rs_GetCompassAngleRadians: Extended;
var
TPA: TPointArray;
T: TPoint;
B: TBox;
begin
B := IntToBox(524, 5, 562, 43);
with B do
FindColorsSpiralTolerance(T.x, T.y, TPA, 0, x1, y1, x2, y2, 0);
if Length(TPA) < 1 then
Exit;
T := MiddleTPA(TPA);
Result := ArcTan2(-(T.Y - 24), T.X - 543) + Radians(90);
Result := fixRad(Result - Pi);
end;

edit: the N keeps changing color. so im guessing the tolerance of 0 was the original issue with this, not the color. just find a suitable tolerance in aca or something. im gunna do that in a bit and see what i come up with

riwu

2012-11-20 21:48:52

From: x[Warrior]x3500
sry, i just ctrl+clicked till i got to the root color finding function of makecompass(); this is it. as you can see, it has findcolorsspiraltolerance changed already to the color 0, which i did so i can get my advanced barb agility script runnin. (its the color of the "N" in the compass)

Function rs_GetCompassAngleRadians: Extended;
var
TPA: TPointArray;
T: TPoint;
B: TBox;
begin
B := IntToBox(524, 5, 562, 43);
with B do
FindColorsSpiralTolerance(T.x, T.y, TPA, 0, x1, y1, x2, y2, 0);
if Length(TPA) < 1 then
Exit;
T := MiddleTPA(TPA);
Result := ArcTan2(-(T.Y - 24), T.X - 543) + Radians(90);
Result := fixRad(Result - Pi);
end;

Are you using Smart/on safe mode/highest brightness etc?
The original color is 65536, not 65565.
65536 works for me, my compass can't be detected when I change it to 0 o.o

EDIT: try 65536..

x[Warrior]x3500

2012-11-20 22:17:33

From: riwu
Are you using Smart/on safe mode/highest brightness etc?
The original color is 65536, not 65565.
65536 works for me, my compass can't be detected when I change it to 0 o.o

EDIT: try 65536..


well for some reason, every now and then it will switch to 0 :/ maybe im in software instead of safemode (i thought i checked that earlier though)… idk. either way, im keepin my tolerance to 1 because according to aca, that should work for both colors :). thanks for helpin me out.

riwu

2012-11-21 01:58:49

Can someone test these 2 functions?

program new;
{$DEFINE SMART} //comment out if not using smart
{$I SRL/SRL.simba}

function GetCombatLevel2: Integer;
begin
Result := -1;
if not FTab(tab_Combat) then
exit;

Result := StrToIntDef(ExtractFromStr(GetTextAtExWrap(556, 316, 584, 333, 0,
3, 4, 3111603, 0, UpChars), Numbers), -1);
end;

procedure Retaliate2(RetTrue: Boolean);
begin
if not FTab(tab_Combat) then
Exit;

if (RetTrue) xor FindTextTPA(3111603, 0, 558, 437, 682, 455, 'On', UpChars, nothing) then
MouseBox(558, 437, 682, 455, mouse_left);
end;

begin
SetupSRL;
writeln('Your combat level is: ' + ToStr(GetCombatLevel2));

writeln('Turning retaliation off...');
Retaliate2(false);
wait(RandomRange(1500, 2000));
writeln('Turning retaliation on...');
Retaliate2(true);
end.

euphemism

2012-11-21 02:32:38

Writing comprehensive set of procedures/functions for the ability book, should be finished tomorrow.

riwu

2012-11-21 02:37:07

From: euphemism
Writing comprehensive set of procedures/functions for the ability book, should be finished tomorrow.

Alright, i won't work on that then.
The biggest challenge now is how to detect whether an ability on the ability bar is in cooldown? I've yet to figure out any unique colors…

KingKong

2012-11-21 05:13:24

From: riwu
Alright, i won't work on that then.
The biggest challenge now is how to detect whether an ability on the ability bar is in cooldown? I've yet to figure out any unique colors…


countcolor/percentcolor the dark timer/clock thing that comes up when ability is in cooldown?

riwu

2012-11-21 06:11:28

From: KingKong
countcolor/percentcolor the dark timer/clock thing that comes up when ability is in cooldown?

It doesn't have any unique color, it seems as if they just 'darken' part of it. Not sure how this can be done due to all the abilities having different colors.

euphemism

2012-11-21 11:16:01

From: riwu
It doesn't have any unique color, it seems as if they just 'darken' part of it. Not sure how this can be done due to all the abilities having different colors.


Don't worry, I got this. ;)

Though, I probably won't have a cooldown check done by tonight, but the activating of everything should be done.

riwu

2012-11-21 18:52:46

From: euphemism
Don't worry, I got this. ;)

Though, I probably won't have a cooldown check done by tonight, but the activating of everything should be done.

I guess you'll autocolor/make a dynamic bitmap of the abilities? The problem is that some abilities only get 'lit up' when you have enough adrenaline…
Unless you manually make bitmaps of them when they are lit up…

euphemism

2012-11-21 21:29:43

So. Family is in town, and I had work today. As a result, I have only completed the code to set the ability book to any one of the nine tabs. Will update this post as I add more functionality. If anyone would like to test it, copy the following code into a script and call SetAbilityBook() and pass one of the constants as the parameter.


const
AB_ATTACK = 0;
AB_STRENGTH = 1;
AB_RANGED = 2;
AB_ABILITIES = 3;
AB_COMBAT_SPELLS = 4;
AB_TELEPORT_SPELLS = 5;
AB_SKILLING_SPELLS = 6;
AB_DEFENSE = 7;
AB_CONSTITUTION = 8;

function ActiveMainTab(): Integer;
var
Color: Integer;
TabColorArray: TIntegerArray;
begin
SetLength(TabColorArray, 4);
TabColorArray := [1996449, 2315049, 7225628, 2370692];
Color := GetColor(551, 282);
for Result := 0 to 3 do
if (Color = TabColorArray[Result]) then
Exit;
end;

function ActiveSubTab(): Integer;
var
H, S, L: Extended;
XVals: TIntegerArray;
begin
SetLength(XVals, 4);
XVals := [555, 601, 648, 695];
if (ActiveMainTab = 0) then
XVals[1] := 602;
for Result := 0 to 3 do
begin
ColorToHSL(GetColor(XVals[Result], 262), H, S, L);
if (L > 10) then
Exit;
end;
end;

function SetAbilityBook(Tab: Integer): Boolean;
var
ActiveMain, I, TabCompare, TimeOut, X, Y: Integer;
CompareFunc: Function(): Integer;
BoxCoords, TabLocations, TabLoop: T2DIntegerArray;
begin
if (not GameTab(TAB_MAGIC)) then
Exit;
SetLength(TabLocations, 4);
TabLocations[0] := [AB_ATTACK, AB_STRENGTH]; //First dimension is main tab, second dimension is sub tab position.
TabLocations[1] := [AB_RANGED];
TabLocations[2] := [AB_ABILITIES, AB_COMBAT_SPELLS, AB_TELEPORT_SPELLS, AB_SKILLING_SPELLS];
TabLocations[3] := [AB_DEFENSE, AB_CONSTITUTION];
SetLength(BoxCoords, 2);
BoxCoords[0] := [548, 205, 594, 237, 47]; //Main tab size and spacing
BoxCoords[1] := [557, 248, 586, 277, 46]; //Sub tab size and spacing
for X := 0 to 3 do //Converts tab constant into X Y pair, where X is the main tab, and Y is the sub tab.
begin
for Y := 0 to High(TabLocations[X]) do
begin
if (TabLocations[X][Y] = Tab) then
begin
Result := True;
Break;
end;
end;
if (Result) then
Break;
end;
ActiveMain := ActiveMainTab; //Stores the current active main tab to reduce redundancy.
SetLength(TabLoop, 2);
TabLoop[0] := [ActiveMain, X]; //Holds the active main tab, and the target main tab.
TabLoop[1] := [ActiveSubTab, Y]; //Holds the active sub tab to 0, and the target sub tab.
Result := ((TabLoop[0][0] = TabLoop[0][1]) and (TabLoop[1][0] = TabLoop[1][1]));
if (Result) then
Exit;
Wait(Random(300));
for I := 0 to 1 do //This loop sets the main tab and sub tab to to the target tab.
begin
if (I = 1) then
TabLoop[i][0] := ActiveSubTab; //Updates the stored active sub tab to account for switching the main tab.
if (TabLoop[i][0] <> TabLoop[i][1]) then
begin
MouseBox((BoxCoords[i][0] + (BoxCoords[i][4] * TabLoop[i][1])), BoxCoords[i][1], (BoxCoords[i][2] + (BoxCoords[i][4] * TabLoop[i][1])), BoxCoords[i][3], MOUSE_LEFT); //Clicks the target tab.
TimeOut := (GetSystemTime + RandomRange(800, 1200)); //Sets timeout fail-safe.
if (I = 0) then //Points the CompareFunc function to check either the active main tab or sub tab based on the value of the looping variable.
CompareFunc := @ActiveMainTab
else
CompareFunc := @ActiveSubTab;
while ((GetSystemTime < TimeOut) and (CompareFunc() <> TabLoop[i][1])) do //Fail-safe and state check for the tab.
Wait(16);
end;
if (I = 0) then //Sets the TabCompare variable to either the active main tab or active sub tab based on the value of the looping variable.
TabCompare := ActiveMainTab
else
TabCompare := ActiveSubTab;
Result := (TabCompare <> TabLoop[i][1]); //If the tab failed to change to the target tab, function returns false and exit.
if (Result) then
Exit;
if (I = 0) then //Determines whether to wait between setting the main tab and sub tab, or to check the final result.
Wait(400 + Random(300))
else
Result := ((ActiveMainTab = TabLoop[0][1]) and (ActiveSubTab = TabLoop[1][1]));
end;
end;

Le Jingle

2012-11-23 22:53:07

Nice work euphemism ^

I also think there may be new fonts worth adding into simba?
(Ex interface pop up has 2 that I know of)

riwu

2012-11-24 00:28:51

This is a video of me attempting to cook a skeleton and failed miserably a function that i've been developing to detect abilities cool down accurately.

http://www.youtube.com/watch?v=LlGDo_cfuQY (view it at youtube at 480p for a better view)

[YOUTUBE]LlGDo_cfuQY[/YOUTUBE]

We will need some standardized basic functions before i can add this to include though.

Also i've made the ability constants which my functions rely on so i hope we can standardize this:
(the = should align when copy pasted to Simba)
Order is of increasing level requirement.

Const
//Attack
AB_SLICE = 1;
AB_SLAUGHTER = 2;
AB_OVERPOWER = 3;
AB_HAVOC = 4;
AB_BACKHAND = 5;
AB_SMASH = 6;
AB_BARGE = 7;
AB_FLURRY = 8;
AB_SEVER = 9;
AB_HURRICANE = 10;
AB_MASSACRE = 11;
AB_METEOR_STRIKE = 12;

//Strength
AB_KICK = 13;
AB_PUNISH = 14;
AB_DISMEMBER = 15;
AB_FURY = 16;
AB_DESTROY = 17;
AB_QUAKE = 18;
AB_BERSERK = 19;
AB_CLEAVE = 20;
AB_ASSAULT = 21;
AB_DECIMATE = 22;
AB_PULVERISE = 23;
AB_FRENZY = 24;

//Ranged
AB_PIERCING_SHOT = 25;
AB_SNAP_SHOT = 26;
AB_DEADSHOT = 27;
AB_SNIPE = 28;
AB_BINDING_SHOT = 29;
AB_FRAGMENTATION_SHOT = 30;
AB_ESCAPE = 31;
AB_RAPID_FIRE = 32;
AB_RICOCHET = 33;
AB_BOMBARDMENT = 34;
AB_INCENDIARY_SHOT = 35;
AB_UNLOAD = 36;

//Magic
AB_WRACK = 37;
AB_ASPHYXIATE = 38;
AB_OMNIPOWER = 39;
AB_DRAGON_BREATH = 40;
AB_IMPACT = 41;
AB_COMBUST = 42;
AB_SURGE = 43;
AB_DETONATE = 44;
AB_CHAIN = 45;
AB_WILD_MAGIC = 46;
AB_METAMORPHOSIS = 47;
AB_TSUNAMI = 48;

//Defence
AB_ANTICIPATION = 49;
AB_BASH = 50;
AB_REVENGE = 51;
AB_PROVOKE = 52;
AB_IMMORTALITY = 53;
AB_FREEDOM = 54;
AB_REFLECT = 55;
AB_RESONANCE = 56;
AB_REJUVENATE = 57;
AB_DEBILITATE = 58;
AB_PREPARATION = 59;
AB_BARRICADE = 60;

//Constitution
AB_REGENERATE = 61;
AB_MOMENTUM = 62;
AB_INCITE = 63;
AB_SINGLE_WAY_WILDERNESS = 64;



(*
GetCoolDown
~~~~~~~~~~~

.. code-block:: pascal

function GetCoolDown(Ability: Integer; UseActionBar: Boolean): Integer;

Gets the cool down of an ability, using the action bar inteference if
UseActionBar is true, otherwise the ability book inteference.
Returns as a percentage, where 100 indicates ability ready to use.

.. note::

by riwu

Example:

.. code-block:: pascal

if GetCoolDown(AB_SURGE, true) then
writeln('Ready to use Surge!');

*)
function GetCoolDown(Ability: Integer; UseActionBar: Boolean): Integer;
var
bmpAbilities: T2DStringArray;
bmpAbility, x, y, AbilityTab, AbilityPos: Integer;
accBmp: Extended;
Boxes: TBoxArray;
sBox: TBox;
begin
Result:= -1;
if not InRange(Ability, 1, 64) then
begin
srl_Warn('GetCoolDown', 'Ability invalid!', warn_AllVersions);
Exit;
end;

AbilityTab:= Ability / 12;
AbilityPos:= Ability - (AbilityTab * 12) - 1;

bmpAbilities:= [TStringArray(['meJxNkY1ygyAQhM9OOmm0iRrFHxQIJFoNWk3f/+G6SCatwzBwu98ec1LbE1ZtgiQPooTqjvSd5EhxtUtYq292Xl0dlW6lrIGNmoEyRcecC/VYl5/tIyYpbpwH+Kam52Ky1qs4dFdDZqZx2QzNe1wZY7z6PU926G9aiYY7Q2/RJWOVD8du7yNwLbjkpfPU6nAur93XK7zvQEtIWDWXeDb2P3zoHa6kx/HsizZSCI8jHLjvDgPnTwOvy90+fCzTs/uWjyKSYdAXxRijfUKfJVTf2uN51TqD4Gl8cobCYMKQXirjBjiuh7gAHoQnKi4YDpD/hjxLg4+IohzDx794C484/AJXLi+M', 'meJw9ketygyAQhb2gRqFYV0XQeKmxNiYT0/j+D9cz3WmZ82NxP84e0J23splZxn4WNLN4y+qnG6Rp1HpAi4v/LQuYdSsKlfVp0oiAWLFq0lOHj3yEW4F4i9OirK0uuyirokSHQnphhhZI1KowbT+6fjmv98f36ziOZb0jUkEGMDBZd8PXE3Lrk9o5Nx3gtn0tV9buSVJ2kXZKqQGMOsqtF+uPywZDuA3zfjIdAD/JvN8FJnVXITVGYyoYqJ0fKifvb6W5UdPNl+9149gHL0N2RQAG/DCEJxj4IC3CYCKEa+ZuicjGmjgPMJEpvAliV+0Gq6oZPUFReUEMAMpMQRTXVYnr7/vOf+EHnkwmHg==', 'meJwlkIFugkAQRPcCB4RTqFchKGARLKHYovL/H9e3kmw2w9y7vWWMy92pLvpRogSRdd8mTotp0cK0ERVkfjtCH6bH8fFCR5lPyrdprATWZMcgPeznJ59JP+uV9ka39RdCGUY5L4kLh8WkWViP4quwGrgYNb31lQQxOwCo6P/k1Mt1lrKVZoQXfzbuQ4+s01GBjccFU7HiIpcf43IGqsMEGC7GaXRfOZK8YpTyea1w2fKoMs0ADEOFb4Buu5uKsmFziTIEf7FbVpakUzib5mfpbA5JFMRCSvvpjgAAQ2xFAhRZnV+rpj0tiKQa5LPeTPVbfXfXzc2vxgszPFf0ruyK64ymeOUf7zQkDw==', 'meJw9kItygjAQReOAIkjDJNIo4SXhVYtF5f8/rocy05mdzN27h33wfj21dX55l7pOTKevA6G0I8Vs+3FZlvnn8X49pawO8eUYG7DENAhSTEoAt8ZBdsMkjvoQKkrEPkoJTErOuc/0zIvOyk74OpQ5gSD9B2SiM5NuWHqp6UYgSMdxtNklTvQ6N9FoHPww1gRrTN/3MrfyD4hUwau0qcryMU0EPeFJAdgKgCt40fS01m5nIsLw5EVqAwh+BRcJL6DU3Op5nukjdntMec5X4JzHygj/I7MVOzACjMWKshVexI10gEGn1wK/b90plqyBYCIm3zJO7AIWBpi+BqU0vOefcIZ+/T9rh13wC6EMKsM=', 'meJxj9Upjdo4AIlavNFZjLzYrbyDJLK/FIizZtPrpslM/G9b/YAWrYYmqRKixCGLSsGLiFYqt3gdXA0RANSyxTUBZkJkWUcxGjkBzxCy8chc/zZl6CSSbNxGE4rsgZjIGFAENZBRSZZCyBCoAKmOqnw9EIDVAxVGVQAUsTikg63iFdP0KgRahqMmdBUKxTUA1zJJKXEaOyw88BzobqAYozly7DqiMOX8REIHUaDsB/QVUAERAuzJazzJO2Mjcvx+EateBzHFKAXqqZc1VoILGeVeACoC+Y55+EYKARjH41QBdApQCKgAqgxiSXLKOaeU1IAKaBlQARBATpiy5Bjekf+omqC3xXcKF84CyO059ByqDKwAasm4t2A1RleaTtwBlgQjoEYgVYdXngAoaW2csnzMdAOP1s04=', 'meJxNjg1vgyAQhs0Gro1WLRaGX10pjihOW/3/P27vyZYteUKAe+69q+prKbWUMs7ES/GeVyZXDc81v/Xt19q7qaqv1e5kuWCFjIQGMEHkprazxo444ZyFSnNBQtkQoibGOXYeVTgQkjTjQgOm2lf1EZlPhESqi/2cyOaYiqTrD9qiBJi20vh02bBSkBEFjUrGoxECa1w/LOfhUZYKmRiHn9Owl7qRwqEZz+yPE3rhFI+VHONP/okRWCCetsPdY8nQC97cAhOXC2T8GM/dhijiNlMOwKUbMRH54QnnT/sF4y47lGkXblfS7PpfOA5PVLEPNJwhh8wdVOF8A8tVK6Q=', 'meJwlkIlugzAQRJeQALGDwQYTzhxOStu0Uar+/8f1UaSVtbLfzs5Y8tr34fT+krKR4WNXtNYF487ZoSmaa9Hd+/CUOIW5/fxuyiPYobm4dlZ2XAE7ftbjLEm21YZB0bXkNTe8VscACUMf6ZLxyNQ0MEV39dcHUjSmGormHisrRbvJrbhW/AknfXisxbhy552qJTEwC1BNkuWYLKdv9H2YV9L1QfshUoZXiXfbVDG4N4s+GK6ocf7q5henpArbqhq0vyOeHI7ARAAmlJ8elGSaXKRAZC3IJUKWw9NzI5uYvejzJ+u6SBfSvRF2Gf/3AIAmjbI3bC8O/UmaiZPg/AO72LsCyd4yKNWwfLjrqcQ4nPvL8w9fbSBU', 'meJxNkIFygjAMhlMnQglQEbpKOWUylW2wOd//5fxD1bPX67X9krT5tGbfuPHrfP2/TON4PHT73W7rHCbu66rUmv9+J9BhGIC899baJ2VmeoswkRhubF1hg4nNg8YUp4pNWW6QC7T3rnmvszRZRCuKmJJcpQVWWiWoDxoqq4QpXpPZUl4LVRHNQ2hWKF5T5si0EoAwJd/APZ7APyVFUCsxyxyvAOHbp88+tIOVqg65qKNNZV3T9z0MXC8TVuxhAnX0xgGhO1EEQz/f59MxWAptopFXJKT19zHT0hRwePjowvHpNigCXcZpUCT2rEVMoEB3RQiYFcHhDWPWIwM=', 'meJxdkdkOgjAQRauASEGRRkQaN4hLFMTl/z/O0070weamaTuHO7clr4/a7Cf5JtJLNYpVoFGSpOfT8ScBVFapqXGAn9u2vXwHjEqXTpTihQpnLLLc9F0ngmkOe1cVxncZhzNKw71H3e26227Zqsk80IULAzOKDk37ej7QMAw4QLL2pRjhUNvd2w/OxUG2+IBF8bwwK3H4Axzjo+piQ4ktLQBI8jNMMoMPXSgJYK0lgwDd/Ym/dJFgXHNdVTjIpQgvIWkkAP62dgACJpurCjM1nJRlSQt5VT7nR7gWPgMzz/IBbnItRg==', 'meJxNj4kOgjAQRJciFKmoEImGxIuojXJ4/P/H+ZpV42ZDyvbtzNR7fzmf+q7j27Yt3+52pb33v8Nuu6VhxnF8Pu70OPShtYYezDnXNM3xsA+/w4OxriupOhInymCkEwry9VcwE5vXdQ3JLabKqClbXJkkFRE3m5NWAyupXsEoMgITJ9OpK8sKKRw1PwVAhtRak2ZCi3BmEoy+aVlBH4XI5kFKTGD2O64Iqa8mCbsSW8kLpACYqA5eKsIQEQBBh4OJkd2s1+QBmy0qlIMCMYpSMsfT5osKHW4xQucDZE6yIlqu3mnVL4s=', 'meJxV0OtygjAUBOADBiwIZLgUwiWiQQQL1pL3f7husMPQnf3BTD6SnCilqqqiMON1r7Wues3FS83rR37zojrIp7OUSqlS3p4/C0wzL1j9CHJa4/jZedSiKN4MoL3esQN+p11i8fh+zijM5aqCOHd5Q//z2eot2A11jhGRvfYvrheX3bK85j07sNOe4Wg/Hf2kncY7JA6FwZg7ZtPBp6CgU+ZwMQzD9PUArtZszAXgArUiwzDXsAbDBjwhyzGFTCWltRspM1Equ96YvlM2C8k6vhkTnVeO5lbpCEksxJU8nptrGGMaNxqvjU2YL4klMGZ162p+Ac7qIaI=', 'meJxFj4FSgzAMhnsnk3lOp8dENoQVq93WDUp5/4fzC3Ebl8uF5sufP8uyfq7sq/1db7v3YyS+Lqk9xMs0UZsuGH/Oiuah3GeVy2q/8NNLGGllXeB39x3cOG1iMu1JANsDPJ4l3mIi537Y+gjDRy0KLimzGmRwlyRTw/djEtnmpEA+KzOLGd0CtrJBFs0MgSYKdA9JgpopHIphGJcyN1AsK5d/7oER2czGmOWum45iKKtzfVHGrCuVUlKv+1ew/dNRdhmk1NUVuwceeLc/C3SuGINyKSvoUs+rTWnNR2uKWphb1P6ei+YPs8Mx8Q==']), TStringArray(['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']), TStringArray(['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']), TStringArray(['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']), TStringArray(['meJyTkpIMCg7s7mjeduJm/7rDjGCwatOeC8++60e12SfVRrXtMTIyCgyLTEpOKikuWrznpKSqBVCNla3T8a9/w6qWKdhnexRNVlJS0tLSAhpVVJgNVKPrkcnKqQBEQHb5koM8su5LFi+SkpKMjo4CmlNVWTx7xUagRhkdV6BpNUvPOyRNTUrPObJxIVAB0DFAi1atXA7UC1QjbxSia+4e0bbRMiT3zNGdQPWNjVW7du48ePnW+x9/5h28D1HjWbcqsm351vk9QKcCRYAK7n//u+/pj+nXfgL1AhUAtWcvvz9j4RqgRT4ZLUDHA2XbDr1PWva09dwfoF6grvwll4EiKdN2AJ0ElF1y5tHaF3+mHv9Yu/MBEAEFGzZe3HX7644rr5Ze+wpE+YtORU7eBdQLFASGGFAcyIBo7N9zB+g2oBagAqCBQMOB4QmUAqoBGgIUByoAagciYPhA1EACCii15NRbiMkQBUApIALaAkQA6VjoXQ==', 'meJwlkeuSgyAMRrvt9m5tHW/VykVRQAQXeP+H28/pDD8y5OQkAekCc1GFuCxGCc4ZHVknJ2EktyEiNaxb9t3POZ1x45dJq+0g8N5TE7JWSBfewgLL3n1BpTRLDC6uGk6uHYBusr0JFddgECc5+bDRORtjHPWS5A0KkSLK11xChb417ZM0k3qO0Tdt98wKqCpuwJxuL6gwGJyH040QAs/heK7pBAlGuqbl8fK4v8ovBhXKRyGujwxA2VuQP4dLI+bdblfQEZdgOsrGST2LFiU4+2MK/lsOeVaTvGy2vaKHKsk/aV6hC932Mo+qB88YA2CNmrXC+n+rvd7T/W+BjpgZAPoCwOsJMUAi5YRHsG49JS1UhHzEwLfswLEUpx2+AyRi/Ijcivg/Bm82xQ==', 'meJwlketygyAQhafTJjZJUdQAigpqFG9IhPd/uJ5WfuzA8p3dsxBCWFb7VEM52m71rLPFyx7buMyTXILegzTverThfy3OI+ZqSUUT/A5MqQZa0RrGi6JbzLqNm/+TvLbgZhyx7yuW/USPe9SqOqFJKetKD7XSkAPg5gDz9uHtrN0dpbSq5DyNgKdXi0ZRIuOyT5oFlc3u1erzPNdaIwrByydNZTesDqWsD5P/s4deRVGQOM5onIqybJpJC2hxCwba7+hyI+kD6x7lT7bvtnch5s1q2uM4BiViQjAUXF2vl5wz688HCMDQDqNxWcMJMtYdD0JOAHtEOPn4TFlG635CHkPBXjvO5wOiJiKG+rqx653CJ474gnbez6uT4e0K5pbJLMtoQlAKeW3sL44cONE=', 'meJw9kIFugyAURdcSKYXB3JyZla3aJXZW1CX+/8ftAF2TFyTvHe69T32U+ij3u6e31/Lneh3Hcdu2EIL3XilViJ2UBV+YohBG62EYHsyp/aRLXycRSkkB/H253KYJZlnmpmkAsoLRB2MUJ7Jd14VwZ+q6FmIPgJd9VhQMkXiLC8zvuhIPBp3MRB2jYKqqYgozL6u1FmWYu11i6Djnss5tmpWKIelnF4pLCq/yXvwEGTc9WKsjZjXlrAHDmvVh+r4nTIz6z0QgnSx7Pn/BeN/CPPovzmSeC0zbnmA+6ne84ii5lKWFzDArMIUhPBaMMvMHfvMfBQ==', 'meJxNkIsOgjAMRRcMhEDAOURQlM1HEJkPsv//OE+sJjZLs3Wn7W2dc5fzua5rpVSaplmWJUkSx/Hia5FSsff+OgxlWeZ5DoAXRnwURWAA4zi2bbvvrTFGMAr+kwAhhL4/YEVR8EuQvvxyl37UgcHvdtvT8cgFzx1ASFK01oghjnLvp9fzGT6GTr7AqMPTmGq51FR4PO7hZzwRiTaY2zRJhEOdeZ55EqyqqqnXYHTB0+jT5U4jRgBztnfOMQgkwhgHDI8eGL4QzLPrOr1asQqYptkQJ51eXKy1sh9Ww/5k86RzRC0YKbJJ2Q+Tc95XmSel', 'meJwlkDFPwlAUhX+HjB07dqxxsJNhEzfZykAsLBSW1qmwkDQOZTCRDhowIRASonWBAUOIDsa46GBiZJPFzcmAg19ykpuX8+797rnvvrjdatT90zCIovDz7fHv9+t+doPYbn763TPTNHO5ne/16vlhSp7IJiOuBIwEJcKyrDCoU1Ue0bvsXvd7qhI4n5RLanx5WgrAUM5c43aL/Gg44JqmKZgABCcl4uP9FZJA00gJHgxxcZ6AAXB6ngdDCUYkGoAT8i67rfiBmGx8tZjPtJqEeD4EwK9VWIpGWjQXXp4MdcvVwtFhPn9AF84sq8fAyI2PdUtusXhs2/b+3m6SxNq000m0JppBjuPgw6k3N5sRVvo9MoyGwcEwDJh/0i0V4w==', 'meJxNj4sOgyAMRb9hyZYlU4EpLxGZ4/8/bgcazZqGlHJ6e0ne5Gi3LdVaj+PIKcR5DPrpp7tVT++WNYZPyTzVM7jC2NftP+mgw5PoJG8QsfqUet0opOZJFglz9MBADA6ReXgACyMAI035W/c9kzFGUeNV3HKSuN16AATv0Wn1PMp3MIYCW/jOmtrpnEOBJvrNav8s5vNeGEQBgA5X4Oatp1Hjp5Rri12W+f1eUwaHBGCR1ppZrMoWEGOM68EUJDaYUmpC6hIxPSjBaJKQwzAwQgcGWaPVD0MVP8Q=', 'meJxdkdlugzAQRU0QFiFlCY7ZXPayhEQE8f8f19Mi5SGWhdBw5s69wzSO8TW6/J9U3+ZpuM/Ta13vyyKECKOwqso0TVzXDYLgg5nnGYb2sjRSyiiKID3PezPbtnVtC5Mk2piCT3Vdl2WJ2pvZ990YA5PnGacocmR5+WD0TZ0sgUiWpXj76XsYR0rqMLQwC33Xc1HTWjdNMwwDs6LQ/y4ymMdjodGyT/iEUUr5vg+Gw6au+q7p++61PqkISxxOII9cFGG449Dv+6ZUbDs2ImB+EBxYHCuk2u6PYZYjHTYGQ/Yv/4JhMBximFnPZWIVmGEKF0H3fJ74F3FMcJ6YgWHhtJCC5aBGul8O7imc', 'meJwljouOgyAURPtItS2KIgoK1YKtCmpf/v/H7biSyc3NYWbgHJ6ylKZJjFlkacHopipPZZGDgJ+D47bQmGRRmDJGRU2rVmt9L/M1yNYr2KTgUgom6+G33Lr51g5KVSDOOa0VCGZr7dD3/v2bpql9L/Ccjvvdbkfi2I+zd0PT1MfDIcS5XPf7QGojTX8OT+iHbS0UPKEEBLGIsuCailLFwoZJcyEUPyxyBk/VzazuCCHL/6HKXbiFjRcVFwW46VymOvCk9vibcR8svPHri9rcHhPE7Uv03/IxY8IJwZA3PSaysulwVdi5Hr6IA24NIOAQGsCDSCm/YBFmRMPaZsbS+k3d9ENPmCgsTzdFuVX9596vWczn+AbHjhLoD3wOK1c=', 'meJw9kItugzAMRdchKCTjMdLwLCUFsgUG3eP/P26HIQ1ZyHaOr28yL8v11uui6vt+su+EGabJfby5mSiqRul6Xhb6MtPDaD+/fwD6+0hOc15Wxs+RIKG8mYFgnLJurjB1XeWvib4oKcODMdbxT7PUWts0dVFomOfTU/wSSiGYdc4hwvbA9+Ik2eFEsiXLqJJI7p318VVVJcZo5rnCFbv4KH3vJKTkOjAog+Go6zpKsEPW9z2kuq5lClfoc1OAwyGJ1homDH06SqWMI962LSXJrrY9mEWKQJZ1UpzVRa9/KyCncYxjQYgo4AjZbVvpG2MOEd6HZ+HiKMAQaJZlgWEM/G/BJ8wBBIH/C/GULtc=', 'meJwlkG2zgiAQhWdiJJJ8KSVFAkkDFa1u/v8fd0+6H3Zgec5Zds8Jr5QtzfNcaClr25p1XT/fVTb3yrhMT6nsfJhxjnNZGv90A4BxHI3RorwUpajMw7oRRRO+d7fIfoJWKcXjmB1pXdeVKJfwU+FVD3/D90dCNY3Ds++v12ue51rrz/sN5pg1aXG7VFK6BX3XLZxzcEPerzTOKaOEHHiS7JV5CxazLMtfr2UK4dEZxiISEYBKNTuGLnwLxhilFFOAzFIeAaSREAIA6k0j8Zl5DuhorUWGZ5Km9CeK2OkEw7ZtYYg6Rhi8x96Aee9gvLfAXPDfdwUGzrDaxly0VocDAUMIgRbMFBZr7qIssNW+72AFFT4Zc04jCisw3vXJmf0DkBQwtA==', 'meJxNkIsOgjAMRRWiUZKRJYg8lgGKCMhD5P8/zoNNFhvSdN3Z7S1huEUQBGTf9739zvO84/EQnE9KKZpaK2tNUVhj8ixL4zjWWifJNc8zY4y1lquqLOi7ZlmW9KuqInNM0zSKolCpur6/57l/vaZppFjX9f1Z2+fz0bRN08An8QWFYRgAJC/LQu66jldklLFxv92oRUR0xmmT5QlqMheAK2EQ2WbNM4DoPOoaKYrlLxwjAYkxPFM7EUIsOQbn+JHpbi8YNwtLMGS3lOz1+xUjTN9ve2Ebho/jT2d0fmjK7gz6ArYTPWk=']), TStringArray(['meJyFkNsOgjAQREuy3BWNgEWEIIKgFKv0/z/OQY0YJWlysmlmz85Dg1AGofRWneU3y+hSN7ITihdjCPy1wAo8Hy2AhrnJeyQfkDiLRovtVVost9Ri2oUWZnAy92Tl/2CLyVjsePlbm4OxkFyODzEondEogYASCFKosup/tVGIkVQnMdxVtpOYUxslrwaDEtzKqzoehpT3XaumNpx/CUV220bnB06+IG8=', 'meJw9kIFuhCAQBU2aNk3vqlZEQUVRBD299P7/7zqU9pIJWdnZB5JlZRap4OVVlG1fKQNCj5HOQhLofqmxsVvdz2hPko/w9l5L4xBYgc1Sql902XSYOLUJ2p10CSEt7kud1yoXLWYh9UfeDtuDELo43bJTf1YyB9GyUi/hIET01obDH9/7/UFNJuNwLcWlqBCa0U/rvh33BFHrfiIYt3MuOSQP60EauHCjC+F2NmahGOx6KSSx/RwYIWr2kSSz4vApWs3pnKWtx4zy4icXIv8j7MQn7eIlMdXo9OSibz2tp59eg4fC5N+Bm8CfPzmhhh/0GS3G', 'meJxdj9uSgjAQRJMAQYxEgUASCFflskppxf//uG3Xt63qh6mZk+6OKl7O+lzfmMxvy3N9vO20aX3v2g1zO3tlflKxGe0rtcVl7a57097HxWfnel08GGnXUs9gKuWH/t24FUtI2+XAS3jW0+ukOmd3mADo3MO086nuu/lhqjFgadHNMLF27ZyHMIiwwvOiv0aZ4ZGUZ4NobG7jWxU7Iuy88ihPhEFb1YwQTBjlMEQEGD1c9bID+15z00PJxRDC0HwaPMrAP0wrdEOfQvWpagBgQwhPpRon/PHjQ3lKY4mTyD46yBIMJYckPiILPrp/hokOA4H9l4lOeZhkATsGLP4yebsDoIRHmfnHUHLEl13j/2yjgEkMSEEHMEgPiWBUoCGsfgFr1Cdi', 'meJzr7Zs2d97Cp08ehrsH25hc0VCaLMhjJS8VZWm0AygCFF++fJWllllv3zQg4+7NG0BBR8srmkqN+pozgWygCFAcKOtudwiu7PSp404WzkBlBmomWzZtAJoPFAeyFaQDHS2WwpVBLJ3Q21dX1wxEQHEX61NC3E7iQl5WRm26atq9MLcBZUtLSpSk5DzttytIJXOzOgKVAZG10SSIaRBlEEs1laqBJgAtMtJp8nZc5mXhCbQLqB2ibN++Q0BlQN8BlQFtB1oEUQCUys7JA1oBtAvIXbN6N9AoIAKqr0ophDjYxtQSGERAR3KycUUEhgFFgCRQEEgCwwFogpMryAHAkJESDtJU6gIqNjQyBooDZaOiw4BuAKmxcAaGlQi/Iw+HNpBkYmQCmgAUB8pOX7ILaFR8QhLQUqCrgMEFVAO0C8gGini4eAENAQDKaLSe'])];
bmpAbility:= BitmapFromString(12, 12, bmpAbilities[AbilityTab][AbilityPos]);

Boxes:= Grid(4, 3, 29, 29, 44, 36, IntToPoint(575, 304));

if UseActionBar then
sBox:=IntToBox(54, 304, 465, 319)
else
begin
//a function to check that we are on the correct ability book here
sBox:= IntToBox(Boxes[AbilityPos].X1 + 9, Boxes[AbilityPos].Y1 + 9, Boxes[AbilityPos].X2 - 9, Boxes[AbilityPos].Y2 - 9);
end;

FindDeformedBitmapToleranceIn(bmpAbility, x, y, sBox.X1, sBox.Y1, sBox.X2, sBox.Y2, 10, 0, true, accBmp);
FreeBitmap(bmpAbility);

if not InIntArray(TIntegerArray([AB_BACKHAND, AB_KICK, AB_WRACK, AB_IMPACT, AB_COMBUST, AB_CHAIN,
AB_ANTICIPATION, AB_FREEDOM, AB_SINGLE_WAY_WILDERNESS]), Ability) then
Result:= 100 - Round(accBmp * 100)
else
Result:= Round(accBmp * 100);
end;

superuser

2012-11-24 00:59:32

From: euphemism
So. Family is in town, and I had work today. As a result, I have only completed the code to set the ability book to any one of the nine tabs. Will update this post as I add more functionality. If anyone would like to test it, copy the following code into a script and call SetAbilityBook() and pass one of the constants as the parameter.


const
AB_ATTACK = 0;
AB_STRENGTH = 1;
AB_RANGED = 2;
AB_ABILITIES = 3;
AB_COMBAT_SPELLS = 4;
AB_TELEPORT_SPELLS = 5;
AB_SKILLING_SPELLS = 6;
AB_DEFENSE = 7;
AB_CONSTITUTION = 8;

function ActiveMainTab(): Integer;
var
Color: Integer;
TabColorArray: TIntegerArray;
begin
SetLength(TabColorArray, 4);
TabColorArray := [1996449, 2315049, 7225628, 2370692];
Color := GetColor(551, 282);
for Result := 0 to 3 do
if (Color = TabColorArray[Result]) then
Exit;
end;

function ActiveSubTab(): Integer;
var
H, S, L: Extended;
XVals: TIntegerArray;
begin
SetLength(XVals, 4);
XVals := [555, 601, 648, 695];
if (ActiveMainTab = 0) then
XVals[1] := 602;
for Result := 0 to 3 do
begin
ColorToHSL(GetColor(XVals[Result], 262), H, S, L);
if (L > 10) then
Exit;
end;
end;

function SetAbilityBook(Tab: Integer): Boolean;
var
ActiveMain, I, TabCompare, TimeOut, X, Y: Integer;
CompareFunc: Function(): Integer;
BoxCoords, TabLocations, TabLoop: T2DIntegerArray;
begin
if (not GameTab(TAB_MAGIC)) then
Exit;
SetLength(TabLocations, 4);
TabLocations[0] := [AB_ATTACK, AB_STRENGTH]; //First dimension is main tab, second dimension is sub tab position.
TabLocations[1] := [AB_RANGED];
TabLocations[2] := [AB_ABILITIES, AB_COMBAT_SPELLS, AB_TELEPORT_SPELLS, AB_SKILLING_SPELLS];
TabLocations[3] := [AB_DEFENSE, AB_CONSTITUTION];
SetLength(BoxCoords, 2);
BoxCoords[0] := [548, 205, 594, 237, 47]; //Main tab size and spacing
BoxCoords[1] := [557, 248, 586, 277, 46]; //Sub tab size and spacing
for X := 0 to 3 do //Converts tab constant into X Y pair, where X is the main tab, and Y is the sub tab.
begin
for Y := 0 to High(TabLocations[X]) do
begin
if (TabLocations[X][Y] = Tab) then
begin
Result := True;
Break;
end;
end;
if (Result) then
Break;
end;
ActiveMain := ActiveMainTab; //Stores the current active main tab to reduce redundancy.
SetLength(TabLoop, 2);
TabLoop[0] := [ActiveMain, X]; //Holds the active main tab, and the target main tab.
TabLoop[1] := [ActiveSubTab, Y]; //Holds the active sub tab to 0, and the target sub tab.
Result := ((TabLoop[0][0] = TabLoop[0][1]) and (TabLoop[1][0] = TabLoop[1][1]));
if (Result) then
Exit;
Wait(Random(300));
for I := 0 to 1 do //This loop sets the main tab and sub tab to to the target tab.
begin
if (I = 1) then
TabLoop[i][0] := ActiveSubTab; //Updates the stored active sub tab to account for switching the main tab.
if (TabLoop[i][0] <> TabLoop[i][1]) then
begin
MouseBox((BoxCoords[i][0] + (BoxCoords[i][4] * TabLoop[i][1])), BoxCoords[i][1], (BoxCoords[i][2] + (BoxCoords[i][4] * TabLoop[i][1])), BoxCoords[i][3], MOUSE_LEFT); //Clicks the target tab.
TimeOut := (GetSystemTime + RandomRange(800, 1200)); //Sets timeout fail-safe.
if (I = 0) then //Points the CompareFunc function to check either the active main tab or sub tab based on the value of the looping variable.
CompareFunc := @ActiveMainTab
else
CompareFunc := @ActiveSubTab;
while ((GetSystemTime < TimeOut) and (CompareFunc() <> TabLoop[i][1])) do //Fail-safe and state check for the tab.
Wait(16);
end;
if (I = 0) then //Sets the TabCompare variable to either the active main tab or active sub tab based on the value of the looping variable.
TabCompare := ActiveMainTab
else
TabCompare := ActiveSubTab;
Result := (TabCompare <> TabLoop[i][1]); //If the tab failed to change to the target tab, function returns false and exit.
if (Result) then
Exit;
if (I = 0) then //Determines whether to wait between setting the main tab and sub tab, or to check the final result.
Wait(400 + Random(300))
else
Result := ((ActiveMainTab = TabLoop[0][1]) and (ActiveSubTab = TabLoop[1][1]));
end;
end;


Hi. You should always free your 'dynamic' arrays. If you don't explicitly set their sizes to 0 after use, you create a memory leak.

Le Jingle

2012-11-24 01:15:44

Here's some cooking interface functions that could probably use reworking;

work fine for me, but test/review would help me/others interested in working with the cooking interface.


{*******************************************************************************
Function to return true if the Cooking Interface pop up is open.
*******************************************************************************}
function Cook_Screen: boolean;
var
x,y,bmp: integer;
begin
Bmp := BitmapFromString(75, 25, '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');
result := FindBitmapToleranceIn(bmp, x, y, MSX1, MSY1, MSX2, MSY2, 15);
freebitmap(bmp);
end;

{*******************************************************************************
Function to return true if the bmp created for the Overviewed item/main item being
investigated in the Cook_Screen is changed after TimeOut milliseconds.
*******************************************************************************}
function WaitCookItemChange(TimeOut: integer): boolean;
var
t, x, y, bmp: integer;
aBox: TBox;
begin
result := false;
aBox := IntToBox(247, 50, 282, 85);
CopyClientToBitmap(bmp, aBox.x1, aBox.y1, aBox.x2, aBox.y2);
MarkTime(t);
while (FindBitmapToleranceIn(bmp, x, y, aBox.x1, aBox.y1, aBox.x2, aBox.y2, 15)) do
begin
Wait(Round(TimeOut/10)+random(Round(TimeOut/15)));
if (TimeFromMark(t)>=TimeOut) then
exit;
end;
result := true;
end;

{*******************************************************************************
Function to return true after Selecting one of the 8 Lists in the Drop-Down
cooking interface menu. (See valid string parameters to pass to function)
Valid string arguements:
- 'Meat'
- 'Fish'
- 'Bread'
- 'Pies'
- 'Cake'
- 'Stew'
- 'Baked Potatoes'
- 'Other Recipes'
*******************************************************************************}
function FoodList(category: string): boolean;
var
i: integer;
TxtShow: string;
begin
result := false;

if not Cook_Screen then
exit;

TxtShow := GetTextAtExWrap(20, 45, 115, 58, 0, 5, 2, 6533359, 15, 'upchars'); // as far as the longest option goes... can be extended to the box shown after else;

if (TxtShow = category) then
begin
result := true;
exit;
end else
begin
MouseBox(18, 43, 235, 61, mouse_left);
for i := 0 to 7 do // currently 8 options shown in the drop down Combo Box, also currently 8 options for food categories too.
begin
TxtShow := GetTextAtExWrap(21, 69+(i*15), 118, 80+(i*15), 0, 5, 2, 6533359, 15, 'upchars');
if (TxTShow = category) then
begin
MouseBox(21, 69+(i*15), 118, 80+(i*15), mouse_left);
result := WaitCookItemChange(1500);
break;
end;
end;
end;
end;

{*******************************************************************************
Function to return true after finding the specific item name in one of
the 8 food lists. MUST ALREADY HAVE DESIRED ITEM IN INVENTORY.
See function details for valid food names.
*******************************************************************************}
function FoodFindEx(name: string): boolean;
var
i: integer;
aBox: TBox;
TPA: TPointArray;
boxCols: TIntegerArray;
overview: TStringArray;
list: Array[0..7] of Array of String;
begin
result := false;
overview := ['Meat', 'Fish', 'Bread', 'Pies', 'Cake', 'Stew', 'Baked Potatoes', 'Other Recipes'];
list[0] := ['Cooked chicken', 'Cooked undead chicken', 'Cooked meat', 'Cooked undead meat', 'Sinew', 'Poorly-cooked bird meat', 'Cooked rabbit', 'Poorly-cooked beast meat', 'Ugthanki meat', 'Cooked turkey', 'Cooked turkey drumstick', 'Thin snail meat', 'Lean snal meat', 'Cooked crab meat', 'Fat snail meat', 'Cooked oomlie wrap'];
list[1] := ['Crayfish', 'Shrimps', 'Karambwanji', 'Sardine', 'Anchovies', 'Poison karambwan', 'Herring', 'Mackerel', 'Trout', 'Cod', 'Pike', 'Salmon', 'Cooked slimy eel', 'Tuna', 'Cooked karambwan', 'Rainbow fish', 'Cave eel', 'Lobster', 'Bass', 'Swordfish', 'Lava eel', 'Monkfish', 'Shark', 'Baron shark', 'Sea turtle', 'Cavefish', 'Manta ray', 'Rocktail', 'Tiger shark'];
list[2] := ['Bread', 'Plain pizza', 'Pitta bread'];
list[3] := ['Redberry pie', 'Meat pie', 'Mud pie', 'Apple pie', 'Garden pie', 'Fish pie', 'Admiral pie', 'Wild pie', 'Summer pie'];
list[4] := ['Cooked fishcake', 'Cake'];
list[5] := ['Stew', 'Curry'];
list[6] := ['Baked Potato', 'Scrambled egg', 'Fried onions', 'Fried mushrooms'];
list[7] := ['Burnt meat', 'Burnt chicken', 'Soda ash', 'Barley malt', 'Bowl of hot water', 'Nettle tea', 'Cooked sweetcorn'];
boxCols := [1290732, 1269431];

for i := 0 to High(list) do
begin
if StrInArr(name, list[i]) then
if FoodList(overview[i]) then
begin
MMouse(240, 0, 500, 500); // don't want text hover hints to obstruct TPA finding
for i := 0 to High(boxCols) do

if FindColorsTolerance(TPA, boxCols[i], 18, 65, 220, 305, 15) then
begin
// AFAIK if you have the item, upon food list switch, you will auto-go to
// the item if the options (ex in fish list) has scroll-able amount of options.
// hence - won't need to change to add in scroll-to-find-item unless RS updates.
aBox := GetTPABounds(TPA);
MouseBox(aBox.x1, aBox.y1, aBox.x2, aBox.y2, mouse_left);
result := true;
writeln('Result = ' + BoolToStr(result) + ' ...');
exit;
end;
end;
end;
SetLength(TPA, 0);
SetLength(list, 0);
end;

{*******************************************************************************
Function to find an item and cook it all. *May want to add a second param,
in which is variant: all (bool) to cook all, or 1-28/x integer and grab
interface text to confirm amount of x-integer to cook.
item: string = the name of item to cook.
amount: variant = True to cook all, or integers 1-28.
*******************************************************************************}
function FoodMake(item: string): boolean;
var
i,x,y: integer;
aBox: TBox;
redX: TIntegerArray;
begin
result := false;
if FoodFindEx(item) then
begin
redX := [254,263108,328874];
for i := 0 to 2 do
if FindColorTolerance(x, y, redX[i], 445, 175, 480, 315-50, 10) then
exit; // can't proceed if we don't meet requirements / have materials.
GetMousePos(x,y);
aBox := IntToBox(260, 305, 480, 325);
if PointInBox(Point(x,y), aBox) then
ClickMouse2(Mouse_left)
else
MouseTBox(aBox, mouse_left);
result := true;
end;
end;

Cheers,
Lj

superuser

2012-11-24 01:25:25

From: Le Jingle
Here's some cooking interface functions that could probably use reworking;

work fine for me, but test/review would help me/others interested in working with the cooking interface.


{*******************************************************************************
Function to return true if the Cooking Interface pop up is open.
*******************************************************************************}
function Cook_Screen: boolean;
var
x,y,bmp: integer;
begin
Bmp := BitmapFromString(75, 25.

...
Lj


Same thing to you. You have two, one bigger memory leak there…

Le Jingle

2012-11-24 01:33:08

From: superuser
Same thing to you. You have two, one bigger memory leak there…


Oh did you mean the TPA and list T2DStringArray? I set their lengths just now to 0's at the end of the function.

(I usually don't worry about setting length's to zero inside my scripts functions, as I add wrappers for all func's at the top, bad habit as of lately)