SRL Archive - Jr. Member General Help and Discussion

Feedback my herblore script (work in progress)


Thomas

2015-04-13 14:15:03

Hey,

Anyone that might have some spare time: feel free to feedback my herblore script! Once I've tested it some more I'll release it in the Jr members section, and later for public.

Planned updates:
-Managing supplies (wont be releasing this for public)
-Portable well support (at chanty/barb outpost, probably in public version)
-Hover over banking (might release public, will only be for ge/chanty/barb outpost)

Current bugs:
-Sometimes repeats banking procedure before it starts to make items. Most likely solved.

Current status:
-Working well, all current functions seem to work.
-2600 pots/hr

program Herblore;
{$DEFINE SMART}
{$I srl-6/srl.simba}
{$i srl-6/lib/misc/srlplayerform.simba}

var
potionCount: integer;
FailTimer: TTimeMarker;

const
VERSION = 0.9;
TIMEOUT = 20000;
SPF_BREAK = 0;
SPF_BREAK_DURATION = 1;

procedure initPlayerForm();
begin
with playerForm do
begin
name := 'Herblore';
editBoxLabels := ['Break after', 'Break for', 'World'];
editBoxDefaults := ['120', '5', ''];
checkBoxLabels := ['Manage supplies'];
checkBoxDefaults := ['False'];
end;
end;

procedure declarePlayers();
var
i: Integer;
begin
players.setup(playerForm.players);
currentPlayer := 0;
for i := 0 to high(players) do
with players[i] do
begin
players[i].integers[SPF_BREAK] := strToInt(playerForm.players[i].settings[0]) * 60000;
players[i].integers[SPF_BREAK_DURATION] := strToInt(playerForm.players[i].settings[1]) * 60000;
world := strToInt(playerForm.players[i].settings[2]);
players[i].booleans[0] := strToBool(playerForm.players[i].settings[3]);
end;
end;

procedure debugSPFSettings();
var
i: integer;
begin
writeln('');
writeln('Player file: ', playerForm.playerFile);
for i := 0 to high(players) do
begin
writeln('Break After: ', players[i].integers[SPF_BREAK]);
writeln('Break For: ', players[i].integers[1]);
writeln('Manage supplies: ', players[i].booleans[0]);
writeln('');
end;
end;

procedure findNormalrandoms();
begin
claimTicket;
if (not bankScreen.isOpen()) then
closepopup();
tabBackpack.Open;
end;

function loginCheck(): boolean;
begin
if isLoggedIn() then
exit(true);
if not players[currentPlayer].login() then
exit(false);
findNormalrandoms();
mouseSpeed := 35;
wait(gaussRangeInt(1000, 2000));
minimap.clickCompass();
exit(true);
end;

procedure antiban();
begin
case random(2000) of
1..3:
begin
hoverRandomSkill();
end;
4..40: mouseMovingObject;
41..60: sleepAndMoveMouse(randomRange(100, 2000));
61..120:
begin
mouseOffClient(4);
wait(gaussRangeInt(1000, 2000));
end;
121..140: wait(gaussRangeInt(1000, 2000));
141..200: randomMouseSpeed(2, 30, 40);
end;
end;

procedure takeBreak();
begin
if (players[currentPlayer].worked.getTime() > players[currentPlayer].integers[SPF_BREAK]) then
begin
writeLn('Taking a ~' + toStr(players[currentPlayer].integers[SPF_BREAK] / 60000) + ' minute break');
players[currentPlayer].exitToLobby();
mouseOffClient(OFF_CLIENT_RANDOM);
wait(players[currentPlayer].integers[SPF_BREAK_DURATION] + random( - 60000, 180000));
loginCheck;
players[currentPlayer].worked.start();
FailTimer.start();
end;
end;

function banking(preset: integer): Boolean;
begin
if not isLoggedIn then
exit(False);
FailTimer.start();
begin
repeat
if bankscreen.open(BANK_GE) then
break();
minimap.clickCompass();
if (FailTimer.getTime > TIMEOUT) or (not isLoggedIn()) then
exit(False);
until bankScreen.isOpen(2000) or pinscreen.isOpen();
if pinScreen.isOpen() then
pinScreen.enter(players[currentPlayer].bankPin);
repeat
if bankScreen.clickButton(preset) then
exit(True);
until (FailTimer.getTime > TIMEOUT) or (not isLoggedIn());
end;
end;

function makePotions(): boolean;
var
slot: integer;
begin
if not isLoggedIn then
exit;
FailTimer.start();
tabBackpack.Open();
repeat
case random(10) of
0..7: slot := 11;
8..9: slot := 12;
end;
if tabBackpack.mouseSlot(slot, MOUSE_MOVE) and isMouseOverText(['Use Clean']) then
begin
tabBackpack.mouseSlot(slot, MOUSE_LEFT);
wait(gaussRangeInt(100, 200));
case random(10) of
0..7: slot := 16;
8..9: slot := 17;
end;
if tabBackpack.mouseSlot(slot, MOUSE_MOVE) and isMouseOverText(['of water']) then
tabBackpack.mouseSlot(slot, MOUSE_LEFT);
end;
wait(gaussRangeInt(100, 200));
if (not isLoggedIn) or (FailTimer.getTime > TIMEOUT) then
exit;
until productionScreen.IsOpen(2000);
wait(gaussRangeInt(100, 200));
productionScreen.clickStart;
if tabBackpack.waitForShift(randomRange(5000, 7000)) then
exit(True);
end;

procedure progressReport();
var
potsPerHour: Integer;
begin
clearDebug();
potsPerHour := round((potionCount * 60) / (getTimeRunning() / 60000));
writeLn('|=========================================|');
writeLn(PadR('| Love Herblore v' + toStr(VERSION), 42) + '|');
writeLn(PadR('| Time: ' + timeRunning(TIME_ABBREV), 42) + '|');
writeLn(PadR('| Potions Made: ' + toStr(potionCount) + ' (' + toStr(potsPerHour) + ' PH)', 42) + '|');
writeLn(PadR('| Break in: ' + msToTime(players[currentPlayer].integers[SPF_BREAK] - players[currentPlayer].worked.getTime(), TIME_ABBREV), 42) + '|');
writeLn('|=========================================|');
end;

procedure mainloop();
var
FailCount: Integer;
begin
findNormalRandoms();
if banking(BANK_BUTTON_PRESET_1) and (not tabBackpack.isFull()) then
inc(FailCount);
if (FailCount = 4) then
begin
writeln('Failed withdrawing, shutting down');
players[currentPlayer].logout();
terminateScript();
end;
if tabBackpack.isFull() and makePotions() then
repeat
findNormalRandoms();
wait(gaussRangeInt(400, 1000));
antiBan;
if (not isLoggedIn) or (FailTimer.getTime > TIMEOUT) then
exit;
until not (tabBackpack.IsItemInSlot(27));
wait(gaussRangeInt(200, 500));
potionCount := potionCount + 14;
progressReport;
takeBreak;
end;

procedure setup();
begin
clearDebug();
initPlayerForm();
runPlayerForm();
if (not playerForm.isScriptReady) then
terminatescript;
declareplayers();
{$IFDEF SMART}
smartEnableDrawing := True;
smartShowConsole := False;
{$ENDIF}
setupSRL;
disableSRLDebug := true;
FailTimer.start();
players[currentPlayer].worked.start();
end;

begin
setup();
while loginCheck() do
mainLoop();
end.

Thomas

2015-04-13 14:57:18

procedure mainloop();
var
FailCount: Integer;
begin
findNormalRandoms();
if banking(BANK_BUTTON_PRESET_1) then
begin;
findNormalRandoms();
if (not tabBackpack.isFull()) then
inc(FailCount);
if (FailCount = 4) then
begin
writeln('Failed withdrawing, shutting down');
players[currentPlayer].logout();
terminateScript();
end;
if tabBackpack.isFull() and makePotions() then
repeat
findNormalRandoms();
wait(gaussRangeInt(400, 1000));
antiBan;
if (not isLoggedIn) or (FailTimer.getTime > TIMEOUT) then
exit;
until not (tabBackpack.IsItemInSlot(27));
end;

wait(gaussRangeInt(300, 500));
potionCount := potionCount + 14;
progressReport;
takeBreak;
end;

This update to the mainloop seems to have fixed the repeating of banking.

Lucidity

2015-04-13 14:59:40

Unless there's a specific reason you have


case random(10) of
0..7: slot := 11;
8..9: slot := 12;
end;

you could replace that with
slot := random(11, 12);
same with your other slot's.

I.E

if tabBackpack.mouseSlot(random(11,12), MOUSE_MOVE) and isMouseOverText(['Use Clean']) then

Thomas

2015-04-13 15:05:06

From: Bly
Unless there's a specific reason you have


case random(10) of
0..7: slot := 11;
8..9: slot := 12;
end;

you could replace that with
slot := random(11, 12);
same with your other slot's.

I.E

if tabBackpack.mouseSlot(random(11,12), MOUSE_MOVE) and isMouseOverText(['Use Clean']) then


Suppose there isn't, besides the fact that it would be 50/50 between both of them when I use your method. I'm unsure if that matters to botwatch.
It was mainly for randomness. And slot 11 is the one any legit player would use more.
I could request users to put 1 of either in slot 1 and 2 and 13 of each in rest, that way I wouldn't need any of the cases and would even improve speed due to less mouse movement after banking.

masterBB

2015-04-13 15:14:42

Quickly read the code. Now, let's destroy your scripting confidence! (joke ^^ )

You should use an enum type instead of constants if they shouldn't contain a 'changeable' value. Also you should how much better this will scale in a bigger or more complicated script. You could also use these for other indices you use.


const
SPF_BREAK = 0;
SPF_BREAK_DURATION = 1;

to

  
type
SPF_Enum = (SPF_BREAK, SPF_BREAK_DURATION);

...

players[i].integers[Ord(SPF_BREAK_DURATION)] = 100 * 60 * 1000; //works the same
players[i].integers[Ord(SPF_Enum.SPF_BREAK)] = 20 * 60 * 1000; //works aswell

I like how you use parentheses after almost every function call. It is just the almost part which can be improved. If you use {f-) at the top of your script right below the includes simba will force you to use this standard. (internally srl does this)

The lack of comments is the only big mistake in this script. Many scripters and programmers place to few comments. Note that these comments aren't only for others, they are for yourself aswel.

I like the script overal. It is simple but atleast it is not bloated. Standards are pretty okay. Pretty good ^^

Thomas

2015-04-13 15:19:06

From: masterBB
Quickly read the code. Now, let's destroy your scripting confidence! (joke ^^ )

You should use an enum type instead of constants if they shouldn't contain a 'changeable' value. Also you should how much better this will scale in a bigger or more complicated script. You could also use these for other indices you use.


const
SPF_BREAK = 0;
SPF_BREAK_DURATION = 1;

to

  
type
SPF_Enum = (SPF_BREAK, SPF_BREAK_DURATION);

...

players[i].integers[SPF_BREAK_DURATION] = 100 * 60 * 1000; //works the same
players[i].integers[SPF_Enum.SPF_BREAK] = 20 * 60 * 1000; //works aswell

I like how you use parentheses after almost every function call. It is just the almost part which can be improved. If you use {f-) at the top of your script right below the includes simba will force you to use this standard. (internally srl does this)

The lack of comments is the only big mistake in this script. Many scripters and programmers place to few comments. Note that these comments aren't only for others, they are for yourself aswel.

I like the script overal. It is simple but atleast it is not bloated. Standards are pretty okay. Pretty good ^^


I suppose I should add comments for others, I don't need them myself as I know pretty much why all the code is there and what I hope it should do.
Still trying to get my head around your first feedback though…

masterBB

2015-04-13 15:24:16

From: lovebotter
I suppose I should add comments for others, I don't need them myself as I know pretty much why all the code is there and what I hope it should do.
Still trying to get my head around your first feedback though…


Yeah, made a typo, check my edit.

Thomas

2015-04-13 15:26:36

From: masterBB
Yeah, made a typo, check my edit.


Can you explain the {f-) part a little more?
I'll reread it a few times untill I figure it out :)

Does anyone have any clue why this mainloop keeps resetting failcount to 1?
Every single time it just keeps reporting failcount as 1. I'm sure I'm making some nooby mistake though..

procedure mainloop();
var
FailCount: Integer;
begin
findNormalRandoms();
if banking(BANK_BUTTON_PRESET_1) and (not tabBackpack.isFull()) then
failCount := failCount +1;
writeLn(FailCount);
if (FailCount > 3) then
begin
writeLn('Failed withdrawing, shutting down');
players[currentPlayer].logout();
terminateScript();
end;
if tabBackpack.isFull() and makePotions() then
repeat
findNormalRandoms();
wait(gaussRangeInt(400, 1000));
antiBan;
if (not isLoggedIn) or (FailTimer.getTime > TIMEOUT) then
exit;
until not (tabBackpack.IsItemInSlot(27));
wait(gaussRangeInt(300, 500));
potionCount := potionCount + 14;
progressReport;
takeBreak;
end;

masterBB

2015-04-13 15:30:23

From: lovebotter
Can you explain the {f-) part a little more?
I'll reread it a few times untill I figure it out :)


program Herblore;
{$DEFINE SMART}
{$I srl-6/srl.simba}
{$i srl-6/lib/misc/srlplayerform.simba}
{f-}

function calls like these used to work:


progressReport;

but now simba forces you to use:


progressReport();

From: lovebotter
Does anyone have any clue why this mainloop keeps resetting failcount to 1?
Every single time it just keeps reporting failcount as 1. I'm sure I'm making some nooby mistake though..


Yeah, sure. Let's put some manes around your neck and make some noise, let's be simba!

Simba starts at the bottom code entry. It runs Setup();

And then: while loginCheck() do Is the player loggedIn? Yes he is! nice ;).

mainLoop(); Let's go to the mainloop. Create one variable called FailCount. Do loop logic. Throw away FailCount because the function is done.

Back to the while. while loginCheck() do Is the player loggedIn? Yes he is! nice ;).

mainLoop(); Let's go to the mainloop. Create one variable called FailCount. Do loop logic. Throw away FailCount because the function is done.

Back to the while. while loginCheck() do Is the player loggedIn? Yes he is! nice ;).

mainLoop(); Let's go to the mainloop. Create one variable called FailCount. Do loop logic. Throw away FailCount because the function is done.

^you see the problem? We keep creating a variable FailCount and removing it when we leave the function. You should put the while in the mainloop function ;).

Thomas

2015-04-13 15:41:41

From: masterBB
program Herblore;
{$DEFINE SMART}
{$I srl-6/srl.simba}
{$i srl-6/lib/misc/srlplayerform.simba}
{f-}

function calls like these used to work:


progressReport;

but now simba forces you to use:


progressReport();


Thanks, got it working.
Also the enum just numbers them from 0 onwards with the given order?

Ye kinda figured it would have been something like that. So I can either make the failcount global or use while…do?

masterBB

2015-04-13 15:43:39

From: lovebotter
Thanks, got it working.
Also the enum just numbers them from 0 onwards with the given order?


Correct. You can get the Index with Ord(EnumName).

Harrier

2015-04-13 15:46:48

From: masterBB
Snip

{$f-}
Without the $ it's just commenting it out? Isn't it

masterBB

2015-04-13 15:49:17

From: Hawker
{$f-}
Without the $ it's just commenting it out? Isn't it


Ah yeah, I probably was drunk or tired. Nice catch.

Thomas

2015-04-13 15:50:33

From: Hawker
{$f-}
Without the $ it's just commenting it out? Isn't it



Yes, should use {$f-}.

Solved:
procedure mainloop();
var
FailCount: Integer;
begin
findNormalRandoms();
repeat
if banking(BANK_BUTTON_PRESET_1) and (not tabBackpack.isFull()) then
failCount := failCount + 1;
writeLn(FailCount);
if (FailCount > 3) then
begin
writeLn('Failed withdrawing, shutting down');
players[currentPlayer].logout();
terminateScript();
end;
if (not isLoggedIn()) or (FailTimer.getTime() > TIMEOUT) then
exit;
until tabBackpack.isFull();
if makePotions() then
repeat
findNormalRandoms();
wait(gaussRangeInt(400, 1000));
antiBan;
if (not isLoggedIn()) or (FailTimer.getTime() > TIMEOUT) then
exit;
until not (tabBackpack.IsItemInSlot(27));
wait(gaussRangeInt(300, 500));
potionCount := potionCount + 14;
progressReport;
takeBreak;
end;

Do you guys think I should add the failCount failsafe to the banking function or the mainloop?
It's so much cleaner if I add it to the banking function, but quite a bit harder it seems.

Latest version (added portable well support):
program Herblore;
{$DEFINE SMART}
{$I srl-6/srl.simba}
{$i srl-6/lib/misc/srlplayerform.simba}


var
potionCount: integer;
FailTimer: TTimeMarker;

const
VERSION = 0.9;
TIMEOUT = 30000;

type
SPFInteger_Enum = (SPF_BREAK, SPF_BREAK_DURATION) SPFBoolean_Enum = (SPF_MANAGE, SPF_PORTABLE) SPFString_Enum = (SPF_BANK)
procedure initPlayerForm();
begin
with playerForm do
begin
name := 'Herblore';
editBoxLabels := ['Break after', 'Break for', 'World'];
editBoxDefaults := ['120', '5', ''];
checkBoxLabels := ['Manage supplies', 'Portable Wells'];
checkBoxDefaults := ['False', 'False'];
comboBoxLabels := ['Bank Location'];
comboBoxDefaults := ['BANK_CHEST_BARB_OUTPOST'];
setLength(comboBoxItems, length(comboBoxLabels));
comboBoxItems[0] := ['BANK_CHEST_BARB_OUTPOST', 'BANK_CHEST_SHANTAY', 'BANK_GE'];
end;
end;

procedure declarePlayers();
var
i: Integer;
begin
players.setup(playerForm.players);
currentPlayer := 0;
for i := 0 to high(players) do
with players[i] do
begin
players[i].integers[Ord(SPF_BREAK)] := strToInt(playerForm.players[i].settings[0]) * 60 * 1000;
players[i].integers[Ord(SPF_BREAK_DURATION)] := strToInt(playerForm.players[i].settings[1]) * 60 * 1000;
world := strToInt(playerForm.players[i].settings[2]);
players[i].booleans[Ord(SPF_MANAGE)] := strToBool(playerForm.players[i].settings[3]);
players[i].booleans[Ord(SPF_PORTABLE)] := strToBool(playerForm.players[i].settings[3]);
players[i].strings[Ord(SPF_BANK)] := playerForm.players[i].settings[4];
end;
end;

procedure findNormalrandoms();
begin
claimTicket;
if (not bankScreen.isOpen()) then
closepopup();
tabBackpack.Open;
end;

function loginCheck(): boolean;
begin
if isLoggedIn() then
exit(true);
if not players[currentPlayer].login() then
exit(false);
findNormalrandoms();
FailTimer.start();
mouseSpeed := 25;
wait(gaussRangeInt(1000, 2000));
minimap.clickCompass();
exit(true);
end;

procedure antiban();
begin
case random(1000) of
1..3:
begin
hoverRandomSkill();
end;
4..40: mouseMovingObject;
41..60: sleepAndMoveMouse(randomRange(100, 2000));
61..120:
begin
mouseOffClient(4);
wait(gaussRangeInt(1000, 2000));
end;
121..140: wait(gaussRangeInt(1000, 2000));
141..200: randomMouseSpeed(2, 20, 30);
end;
end;

procedure takeBreak();
begin
if (players[currentPlayer].worked.getTime() > players[currentPlayer].integers[SPF_BREAK]) then
begin
writeLn('Taking a ~' + toStr(players[currentPlayer].integers[SPF_BREAK] / 60000) + ' minute break');
players[currentPlayer].exitToLobby();
mouseOffClient(OFF_CLIENT_RANDOM);
wait(players[currentPlayer].integers[SPF_BREAK_DURATION] + random( - 60000, 180000));
loginCheck;
players[currentPlayer].worked.start();
FailTimer.start();
end;
end;

function banking(preset: integer): Boolean;
begin
if (not isLoggedIn()) then
exit(False);
FailTimer.start();
begin
repeat
if bankscreen.open(BANK_GE) then
break();
minimap.clickCompass();
if (FailTimer.getTime() > TIMEOUT) or (not isLoggedIn()) then
exit(False);
until bankScreen.isOpen(5000) or pinscreen.isOpen();
if pinScreen.isOpen() then
pinScreen.enter(players[currentPlayer].bankPin);
repeat
if bankScreen.clickButton(preset) then
exit(True);
until (FailTimer.getTime() > TIMEOUT) or (not isLoggedIn());
end;
end;

function findPortable(): Boolean;
var
i, x, y: integer;
portTPA: TPointArray;
portATPA: T2DPointArray;
begin
if not isLoggedIn() then
exit();
findColorsSpiralTolerance(x, y, portTPA, 3031949, mainScreen.getBounds(), 10, colorSetting(2, 0.3, 1.7));
if length(portTPA) < 1 then
exit();
portATPA := portTPA.toATPA(35, 35);
portATPA.filterBetween(0, 20);
portATPA.sortFromSize(25, true);
if length(portATPA) < 1 then
exit();
smartImage.debugATPA(portATPA);
for i := 0 to high(portATPA) do
begin
middleTPAEx(portATPA[i], x, y);
mouse(x, y, 10, 11, MOUSE_MOVE);
if isMouseOverText(['well', 'ortab'], 2500) then
exit(true);
end;
end;

function renewPortable(): Boolean;
begin
if not isLoggedIn() then
exit();
writeln('Renewing Portable');
wait(gaussRangeInt(500, 2000));
sendKeys('w', 200, 40);
if conversationBox.isOpen(5500) then
begin
conversationBox.selectOption(1);
wait(gaussRangeInt(500, 2500));
end;
result := findPortable();
end;

function makePotions(): boolean;
var
WellCount: integer;
begin
if (not isLoggedIn()) then
exit;
FailTimer.start();
tabBackpack.Open();
if not players[currentPlayer].integers[SPF_PORTABLE] then
repeat
if tabBackpack.mouseSlot(1, MOUSE_MOVE) and isMouseOverText(['Use Clean']) then
begin
tabBackpack.mouseSlot(1, MOUSE_LEFT);
wait(gaussRangeInt(100, 200));
if tabBackpack.mouseSlot(2, MOUSE_MOVE) and isMouseOverText(['of water']) then
tabBackpack.mouseSlot(2, MOUSE_LEFT);
end;
wait(gaussRangeInt(100, 200));
if (not isLoggedIn()) or (FailTimer.getTime() > TIMEOUT) then
exit;
until productionScreen.IsOpen(2000);
if players[currentPlayer].integers[SPF_PORTABLE] then
repeat
while findPortable() do
fastClick(MOUSE_LEFT);
while (not findPortable()) do
begin
findNormalrandoms();
begin
if banking(BANK_BUTTON_PRESET_2) and tabBackpack.isEmpty() then
inc(WellCount);
if (nowell > 4) then
begin
writeln('Failed withdrawing, shutting down');
players[currentPlayer].logout();
terminateScript();
end;
if tabBackpack.isItemInSlot(1) then
begin
findNormalRandoms();
if renewPortable() then
writeLn('renewed portable');
end;
end;
end;
until productionScreen.IsOpen(2000);
wait(gaussRangeInt(100, 200));
productionScreen.clickStart;
if tabBackpack.waitForShift(randomRange(5000, 7000)) then
exit(True);
end;

procedure progressReport();
var
potsPerHour: Integer;
begin
clearDebug();
potsPerHour := round((potionCount * 60) / (getTimeRunning() / 60000));
writeLn('|=========================================|');
writeLn(PadR('| Love Herblore v' + toStr(VERSION), 42) + '|');
writeLn(PadR('| Time: ' + timeRunning(TIME_ABBREV), 42) + '|');
writeLn(PadR('| Potions Made: ' + toStr(potionCount) + ' (' + toStr(potsPerHour) + ' PH)', 42) + '|');
writeLn(PadR('| Break in: ' + msToTime(players[currentPlayer].integers[SPF_BREAK] - players[currentPlayer].worked.getTime(), TIME_ABBREV), 42) + '|');
writeLn('|=========================================|');
end;

procedure mainloop();
var
FailCount: Integer;
begin
findNormalRandoms();
repeat
if banking(BANK_BUTTON_PRESET_1) and (not tabBackpack.isFull()) then
failCount := failCount + 1;
wait(gaussRangeInt(100, 300));
if (FailCount > 4) then
begin
writeLn('Failed withdrawing, shutting down');
players[currentPlayer].logout();
terminateScript();
end;
if (not isLoggedIn()) or (FailTimer.getTime() > TIMEOUT) then
exit;
until tabBackpack.isFull();
if makePotions() then
repeat
findNormalRandoms();
wait(gaussRangeInt(300, 800));
antiBan;
if (not isLoggedIn()) or (FailTimer.getTime() > TIMEOUT) then
exit;
until not (tabBackpack.IsItemInSlot(27));
wait(gaussRangeInt(400, 600));
potionCount := potionCount + 14;
progressReport;
takeBreak;
end;

procedure setup();
begin
clearDebug();
initPlayerForm();
runPlayerForm();
if (not playerForm.isScriptReady) then
terminatescript;
declareplayers();
{$IFDEF SMART}
smartEnableDrawing := True;
smartShowConsole := False;
{$ENDIF}
setupSRL;
disableSRLDebug := true;
FailTimer.start();
players[currentPlayer].worked.start();
end;

begin
setup();
while loginCheck() do
mainLoop();
end.

I'm not happy with the looks of the script, it looks rather messy imo. I'm sure it can be coded with 50-80 lines less then I did.