you could count items in inventory, wait 4.5 seconds (cannonbals take 4 secs) and if count1 = count2 then your stuck. You'll ussually get stuck because of lvl up.
This is what i used in my cannonbals script for aerolib... its messy and has lots of stuff it doesent need, but i didnt put much effort into it, check if you get any ideas from it. This one checks for steel every 1.5 secs, so when you've done the full inventory it'll finish.
Simba Code:
function waitBalls: boolean;
var
tries, x, y: integer;
TPA: TPointArray;
T: Timer;
begin
T.start;
repeat
inc(tries);
antiban(1200);
if not isLoggedIn() then
exit;
if not findDTMs(Steel_DTM, TPA, 548, 204, 734, 465) then
break;
wait(randomrange(1000, 1500));
if random(20) = 1 then
report;
if random (10) = 1 then
writeln('Waiting to finish smelting');
if findDTM(level_DTM, x, y, 6, 347, 513, 476) then
begin
writeln('We leveled up');
exit(false);
end;
until false or tries >= 300;
if tries >= 300 then
writeln('Exit Script, something is wrong.');
if tries < 300 then
result:= true;
if result = true then
TripReady := false;
if random (15) = 1 then
wait(randomrange(20000, 60000));
writeln('function waitBalls := ' + tostr(result));
end;