SRL Archive - OSR Help

Help with Combat Scripting


koryperson

2013-11-30 02:58:54

So I've been testing my beginner skills at scripting combat on RSPS's I play and I've run into another issue, my last thread asked how to repeat looking for an hpbar until it finds it, blah blah blah.

This time I have a different question, so I've gotten my incombat portions of my script to work flawlessly, but there is just one minor bug I'd like to fix. I still haven't figured out how to begin the script with a click, such as on a monster, then never go through that procedure again. I'd like to use said procedure to initiate a fight with a monster, then never run through it again because my InCombat procedure would click the next one once it finds the empty HP bar.

I'd also like to know how to make it so if it searches for something using a repeat until(blahblah) and it can't find it after x amount of time, it does a different procedure/function. This part right here would be the most helpful to my combat scripts.

Thanks a ton!

koryperson

2013-11-30 03:33:25

Hmm I think by going through a ton of basic fighters in the RSPS section I've found a solution to my own question…

A simple function detecting if it isn't in combat…
function Fighting: boolean;
begin
if findcolor(x, y, 255, 5, 5, 512, 340) then
begin
result := true
end
else
begin
result := false
end;
end;

bonsai

2013-11-30 06:40:23

From: koryperson
Hmm I think by going through a ton of basic fighters in the RSPS section I've found a solution to my own question…

A simple function detecting if it isn't in combat…


I think it's cleaner code-wise to have the clicking and waiting in the same procedure rather than one find/click outside then calling it repeatedly from the inside of your other function.

Anyway, here's my attack function. I used two loops like you describe. After it clicks on the npc, it waits in a loop until it detects a fight. That covers the time it takes to run across the room and get it going. Then the second loop waits until the end of fight is detected so the function can exit back to its caller.

Both loops have timers so they dont accidentally run forever.


function Tnpc.attack(waitTilDead: boolean; foodProc: procedure; mouseStyle: integer = MOUSE_RIGHT): boolean;

var
t: integer;
found, found2: boolean;

begin
result := self._objFind.choose(self._uptext, [''], mouseStyle, ['ttack'], true);
if (result and waitTilDead) then
begin
{$IFDEF DEBUG_ON} writeln('***** Fight initiated'); {$ENDIF}
found := false;
found2 := false;

// give it time to run over and get into the fight
// if a smaller value is used it gets more kills/hr but
// sometimes it does take that long to run around

t := getSystemTime() + randomRange(3200,3900);
repeat
wait(150);
found := self.isInFight();
until (found or (getSystemTime() >= t));

t := getSystemTime() + (self._maxFightSeconds * 1000);
while self.isInFight() do
begin
found2 := true;
wait(250);
foodProc();
if (getSystemTime() >= t) then
begin
{$IFDEF DEBUG_ON} writeln('****** Something wrong... in fight too long'); {$ENDIF}
terminateScript();
end;
end;

if not (found or found2) then
begin
{$IFDEF DEBUG_ON} writeln('****** Probable miss, did not detect start of fight'); {$ENDIF}
result := false;
end
else
begin
{$IFDEF DEBUG_ON} writeln('***** End of fight detected'); {$ENDIF}
end;
end;
end;

Hoodz

2013-11-30 06:46:41

From: bonsai
I think it's cleaner code-wise to have the clicking and waiting in the same procedure rather than one find/click outside then calling it repeatedly from the inside of your other function.

Anyway, here's my attack function. I used two loops like you describe. After it clicks on the npc, it waits in a loop until it detects a fight. That covers the time it takes to run across the room and get it going. Then the second loop waits until the end of fight is detected so the function can exit back to its caller.

Both loops have timers so they dont accidentally run forever.


function Tnpc.attack(waitTilDead: boolean; foodProc: procedure; mouseStyle: integer = MOUSE_RIGHT): boolean;

var
t: integer;
found, found2: boolean;

begin
result := self._objFind.choose(self._uptext, [''], mouseStyle, ['ttack'], true);
if (result and waitTilDead) then
begin
{$IFDEF DEBUG_ON} writeln('***** Fight initiated'); {$ENDIF}
found := false;
found2 := false;

// give it time to run over and get into the fight
// if a smaller value is used it gets more kills/hr but
// sometimes it does take that long to run around

t := getSystemTime() + randomRange(3200,3900);
repeat
wait(150);
found := self.isInFight();
until (found or (getSystemTime() >= t));

t := getSystemTime() + (self._maxFightSeconds * 1000);
while self.isInFight() do
begin
found2 := true;
wait(250);
foodProc();
if (getSystemTime() >= t) then
begin
{$IFDEF DEBUG_ON} writeln('****** Something wrong... in fight too long'); {$ENDIF}
terminateScript();
end;
end;

if not (found or found2) then
begin
{$IFDEF DEBUG_ON} writeln('****** Probable miss, did not detect start of fight'); {$ENDIF}
result := false;
end
else
begin
{$IFDEF DEBUG_ON} writeln('***** End of fight detected'); {$ENDIF}
end;
end;
end;

try to keep it easy he's new :p
what he made is perfect for starters

koryperson

2013-11-30 08:59:48

Haha what he said x) I've tried reading over that snippet you gave me and it just seems overwhelming, I can understand the general concept of what's being done in each line though.

bonsai

2013-11-30 09:35:34

From: koryperson
Haha what he said x) I've tried reading over that snippet you gave me and it just seems overwhelming, I can understand the general concept of what's being done in each line though.


Sorry! Is it easier to grok cleaned up like this? isInFight() would be your routine to detect if a fight is in progress.

It clicks the NPC, waits a few seconds until the fight is detected (repeat/until loop), then waits (up to two minutes) while it detects the fight is still in progress (while loop).

function attack(): boolean;

var
t: integer;
found, found2: boolean;

begin
if clickOnNpc() then
begin
writeln('***** Fight initiated');

// give it time to run over and get into the fight

found := false;
t := getSystemTime() + randomRange(3200,3900);
repeat
wait(150);
found := isInFight();
until (found or (getSystemTime() >= t));

// wait up to two minutes for the fight to end

found2 := false;
t := getSystemTime() + (120 * 1000);
while isInFight() do
begin
found2 := true;
wait(250);
if (getSystemTime() >= t) then
begin
writeln('****** Something wrong... in fight too long');
terminateScript();
end;
end;

if not (found or found2) then
begin
writeln('****** Probable miss, did not detect start of fight');
result := false;
end
else
begin
writeln('***** End of fight detected');
result := true;
end;
end;
end;

koryperson

2013-12-01 15:29:11

Yeah, that's much simpler :) I'll be using this for a lot of my scripts now, pretty helpful for this imp catcher i'm working on for an RSPS.


Hmmm every time I try to use this line, I get a type mismatch error and can't find a fix

t := getSystemTime() + (120 * 1000); 

bonsai

2013-12-01 17:28:16

A type mismatch would be if you do something like assign a string to an integer.

Is 't' an integer?

koryperson

2013-12-02 01:34:46

From: bonsai
A type mismatch would be if you do something like assign a string to an integer.

Is 't' an integer?


Nah, still doesn't work, I pasted that entire snippet into my script and just tried compiling, same error. I as well get the same error when compiling this, not sure what I'm doing wrong, probably just a simple beginner mistake :P

Procedure WaitUntilCaught;
var
found, found2: boolean;
Begin
ClickImp
repeat
Wait(50);
Found := FindColorTolerance(x, y, 3381759, 405, 76, 511, 143, 3)
Found2 := Wait(10000);
until(found)
IncEx(Caught, 1);
Proggy
End;

What I'm trying to do is have my script either find the color it's looking for, or wait 10 seconds, whichever comes first. I'm trying to catch implings and the waiting 10 seconds part is just in case the imp I'm trying to catch gets stolen, then it just waits 10 seconds to find another, repeat. Thanks for all the help btw.

EDIT:

I've solved my issue! So happy :) all I did was go into the scripting help section and try learning a few new things and I came across something close to my situation, I changed it to this and it works perfect, thanks for all your help mate

Procedure WaitUntilCaught;
var
t:integer;
found, found2: boolean;
Begin
ClickImp
MarkTime(t);
repeat
Wait(50);
Found := FindColorTolerance(x, y, 3381759, 405, 76, 511, 143, 3)
until(found) or ((TimeFromMark(t) > 8000));
IncEx(Caught, 1);
Proggy
End;

bonsai

2013-12-02 03:16:22

You're missing ';' on some of the lines you posted. That will trip you up and sometimes the line reported as an issue will not be the same as the one with the problem.