SRL Archive - General Botting Help

Exception in Script: Cannot break out of this statement


Spaceblow

2014-08-14 17:24:16

I'm adjusting a procedure to make it better but now I don't know what to do. It's the 2 break; lines I have problems with (I commented them out so it would be clear what I'm talking about). When I try to run the script the following shows up:

Exception in Script: Cannot break out of this statement at line 93, column 7

This happens also for the second break;. I really don't know what I'm doing wrong here, why couldn't it break out of that? This is my procedure:

procedure bankRedberries();
var
bankTimer: TTimeMarker;
pathFail: TPointArray;
begin
if not isLoggedIn() then
exit;

if not tabBackpack.isFull() then
exit;

minimap.setAngle(MM_DIRECTION_SOUTH);
mainScreen.setAngle(MS_ANGLE_HIGH);

bankScreen.open(BANK_NPC_BLUE);
wait(randomRange(750, 1250));

if bankScreen.isOpen() then
begin
bankTimer.start();
writeLn('--------------------------------------------------------------------------- Succesfully opened the bank');
repeat
begin
wait(randomRange(600, 900));
bankScreen.quickDeposit(QUICK_DEPOSIT_INVENTORY);
wait(randomRange(600, 900));
bankScreen.close();
writeLn('--------------------------------------------------------------------------- Succesfully closed the bank.');
end;
until(tabBackpack.isEmpty()) or (not isLoggedIn()) or (bankTimer.getTime() > 7000);
if tabBackpack.isEmpty() then
begin
writeLn('--------------------------------------------------------------------------- Succesfully banked Redberries.');
inc(loadsDone);
wait(randomRange(750, 1250));
writeLn('--------------------------------------------------------------------------- Running to redberries.');
end;
end else
begin
writeLn('--------------------------------------------------------------------------- Could not open bank, trying to find it.');
wait(randomRange(750, 1000));

pathFail:= [Point(118, 133), Point(118, 169)]; //in case the player somehow didn't got in the bank, but outside of it
if SPS.walkPath(pathFail) then
minimap.waitPlayerMoving();

wait(randomRange(750, 1000));
//break; //so when the player got in the bank, it needs to break so it would try to open the bankscreen again
end;

if tabBackpack.isEmpty() then
begin
exit;
end else
//break; //so it would restart to try to open the bankscreen again in case the backpack somehow isn't empty

end;

And a second question: would it somehow be possible to terminate the script after like 2 minutes of running the procedure? Yes, I'm aware of timer.start() and timer.getTime() but if I would want to use that, I would have to put the whole procedure in a 'repeat … until timer.getTime()', right? But if I would want to use break;, it would go to the beginning of the procedure, so the timer.start() would constantly just start over and it would never reach the 2 minutes, is that correct? Thanks in advance!

Turpinator

2014-08-14 18:06:31

break; leaves a for/while/repeat/etc loop.
exit; leaves the function.

since you are not in any sort of loop, you cannot break from it.

Spaceblow

2014-08-14 19:43:30

From: Turpinator
break; leaves a for/while/repeat/etc loop.
exit; leaves the function.

since you are not in any sort of loop, you cannot break from it.
Ohh I understand it now I think. Thank you very much for your reply, I appreciate it! :) I replaced the 'break;' with 'bankRedberries();' (the name of my procedure. Is that the way to restart your procedure or am I doing something wrong? So this is what I have now:

procedure bankRedberries();
var
bankTimer: TTimeMarker;
pathFail: TPointArray;
begin
if not isLoggedIn() then
exit;

if not tabBackpack.isFull() then
exit;

minimap.setAngle(MM_DIRECTION_SOUTH);
mainScreen.setAngle(MS_ANGLE_HIGH);

bankScreen.open(BANK_NPC_BLUE);
wait(randomRange(750, 1250));

if bankScreen.isOpen() then
begin
bankTimer.start();
writeLn('--------------------------------------------------------------------------- Succesfully opened the bank');
repeat
begin
wait(randomRange(600, 900));
bankScreen.quickDeposit(QUICK_DEPOSIT_INVENTORY);
wait(randomRange(600, 900));
bankScreen.close();
writeLn('--------------------------------------------------------------------------- Succesfully closed the bank.');
end;
until(tabBackpack.isEmpty()) or (not isLoggedIn()) or (bankTimer.getTime() > 7000);
if tabBackpack.isEmpty() then
begin
writeLn('--------------------------------------------------------------------------- Succesfully banked Redberries.');
inc(loadsDone);
wait(randomRange(750, 1250));
writeLn('--------------------------------------------------------------------------- Running to redberries.');
end;
end else
begin
writeLn('--------------------------------------------------------------------------- Could not open bank, trying to find it.');
wait(randomRange(750, 1000));

pathFail:= [Point(118, 133), Point(118, 169)]; //in case the player somehow didn't got in the bank, but outside of it
if SPS.walkPath(pathFail) then
minimap.waitPlayerMoving();

wait(randomRange(750, 1000));
bankRedberries(); //edited this
end;

if tabBackpack.isEmpty() then
begin
exit;
end else
bankRedberries(); //and this
end;


And I hope somebody could answer my second question too: would it somehow be possible to terminate the script after like 2 minutes of running the procedure? Yes, I'm aware of timer.start() and timer.getTime() but if I would want to use that, I would have to put the whole procedure in a 'repeat … until timer.getTime()', right? But if I would want to restart the procedure (by using the procedure name in the procedure itself, it would go to the beginning of the procedure, so the timer.start() would constantly just start over and it would never reach the 2 minutes, is that correct? Thanks in advance!

Turpinator

2014-08-14 22:37:51

From: Spaceblow
Ohh I understand it now I think. Thank you very much for your reply, I appreciate it! :) I replaced the 'break;' with 'bankRedberries();' (the name of my procedure. Is that the way to restart your procedure or am I doing something wrong? So this is what I have now:

procedure bankRedberries();
var
bankTimer: TTimeMarker;
pathFail: TPointArray;
begin
if not isLoggedIn() then
exit;

if not tabBackpack.isFull() then
exit;

minimap.setAngle(MM_DIRECTION_SOUTH);
mainScreen.setAngle(MS_ANGLE_HIGH);

bankScreen.open(BANK_NPC_BLUE);
wait(randomRange(750, 1250));

if bankScreen.isOpen() then
begin
bankTimer.start();
writeLn('--------------------------------------------------------------------------- Succesfully opened the bank');
repeat
begin
wait(randomRange(600, 900));
bankScreen.quickDeposit(QUICK_DEPOSIT_INVENTORY);
wait(randomRange(600, 900));
bankScreen.close();
writeLn('--------------------------------------------------------------------------- Succesfully closed the bank.');
end;
until(tabBackpack.isEmpty()) or (not isLoggedIn()) or (bankTimer.getTime() > 7000);
if tabBackpack.isEmpty() then
begin
writeLn('--------------------------------------------------------------------------- Succesfully banked Redberries.');
inc(loadsDone);
wait(randomRange(750, 1250));
writeLn('--------------------------------------------------------------------------- Running to redberries.');
end;
end else
begin
writeLn('--------------------------------------------------------------------------- Could not open bank, trying to find it.');
wait(randomRange(750, 1000));

pathFail:= [Point(118, 133), Point(118, 169)]; //in case the player somehow didn't got in the bank, but outside of it
if SPS.walkPath(pathFail) then
minimap.waitPlayerMoving();

wait(randomRange(750, 1000));
bankRedberries(); //edited this
end;

if tabBackpack.isEmpty() then
begin
exit;
end else
bankRedberries(); //and this
end;


And I hope somebody could answer my second question too: would it somehow be possible to terminate the script after like 2 minutes of running the procedure? Yes, I'm aware of timer.start() and timer.getTime() but if I would want to use that, I would have to put the whole procedure in a 'repeat … until timer.getTime()', right? But if I would want to restart the procedure (by using the procedure name in the procedure itself, it would go to the beginning of the procedure, so the timer.start() would constantly just start over and it would never reach the 2 minutes, is that correct? Thanks in advance!


well. if you do it this way theres a possibility for an infinite loop due to recursion. bankRedBerries() could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could keep calling bankRedBerries() indefinitely.

so. recursion in this case is gonna be bad probably.

Spaceblow

2014-08-15 06:46:53

From: Turpinator
well. if you do it this way theres a possibility for an infinite loop due to recursion. bankRedBerries() could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could call bankRedBerries(), which could keep calling bankRedBerries() indefinitely.

so. recursion in this case is gonna be bad probably.
Hmm I see. Then the solution would be to use timer.start() and timer.getTime(). But I'm wondering if the timer also gets restarted when I go back to the beginning of the procedure, or does it just continue?

riwu

2014-08-15 20:18:38

From: Spaceblow
Hmm I see. Then the solution would be to use timer.start() and timer.getTime(). But I'm wondering if the timer also gets restarted when I go back to the beginning of the procedure, or does it just continue?

if you have to repeat your procedure several times if failed, you could use a structure sth like this:

repeat //could use a for loop too if you have knowledge of it
//do your things
//if these things succeeded, exit/break!
//if failed, then
Inc(failed);
if failed > 5 then
TerminateScript or something? //now you wont have to worry about infinite loop
until false;

As for your timer question, it depends on the scope and how you 'go back to the beginning of the procedure'? if you declare the variable locally but repeat the procedure from an external call then it will be reset, if you use a label to go back (which is not quite recommended) or an inner loop (like what i did above) which result in it never exiting the procedure then it wont be reset.

Also it's never recommended to call a method itself within it (recursive call)

Spaceblow

2014-08-15 20:57:23

From: riwu
if you have to repeat your procedure several times if failed, you could use a structure sth like this:

repeat //could use a for loop too if you have knowledge of it
//do your things
//if these things succeeded, exit/break!
//if failed, then
Inc(failed);
if failed > 5 then
TerminateScript or something? //now you wont have to worry about infinite loop
until false;

As for your timer question, it depends on the scope and how you 'go back to the beginning of the procedure'? if you declare the variable locally but repeat the procedure from an external call then it will be reset, if you use a label to go back (which is not quite recommended) or an inner loop (like what i did above) which result in it never exiting the procedure then it wont be reset.

Also it's never recommended to call a method itself within it (recursive call)
Alright I think I fully understand it now. Whenever I'm in the same situation again, I'll look back at your post and I'll try to do what you've recommended me, thank you very much!