SRL Archive - RS3 Help

First Combat Script


FoxGaming

2014-12-13 14:09:23

Hey everyone,

So I'm definitely not new to botting, but I'm definitely new to the Simba Scene.
Been working on creating a Combat Script to kill Lesser Demons in the Karamja Volcano Resource dungeon.

I'm having trouble though, mostly because I'm a lower level than the lesser demons. So I've not really figured out how to detect when my mouse is over them or not. I was thinking with my ATPA box I could then detect if my mouse was within those bounds? So a conditional wait until the ATPA box around the found demon contained my mouse, which I could then right click and select attack.

I'm also working on my own include library to store functions, like a check for combat, and healthPCT etc. So any tips on that will also be appreciated.

Here is what I have so far…which is basically just following TheMayor's tutorial.

program demonSlayer;

{$DEFINE SMART} // Always have this to load smart
{$I SRL-6/SRL.simba} // To load the SRL include files
{$I SPS/lib/SPS-RS3.Simba} // To load the SPS include files



procedure declarePlayers();
begin
setLength(players, 1);
with players[0] do
begin
loginName := '*******';
password := '*********';
isActive := true;
isMember := true;
end
currentPlayer := 0;
end;

procedure getDemons();
var
x, y, i: integer;
TPA: TPointArray;
ATPA: T2DPointArray;

begin
if not isLoggedIn() then
exit;

findColorsSpiralTolerance(x, y, TPA, 3823248, mainScreen.getBounds(), 9, colorSetting(2, 0.12, 0.03));

if (Length(TPA) < 1) then
exit;
ATPA := TPA.toATPA(30, 30);
ATPA.sortFromMidPoint(mainScreen.playerPoint);
smartImage.debugATPA(ATPA);

end


procedure attackDemon()
begin
if not isLoggedIn() then
exit





end

procedure eatFood()
begin
//eat food
end

procedure useAbilities()
begin
//make this faster.
end

procedure lootItems()
begin
//loot crap
end


// main loop
begin
clearDebug(); // Clear the debug box
smartEnableDrawing := true; // So we can draw on SMART
setupSRL(); // Load the SRL include files
declarePlayers();
// Set up your username/pass

if not isLoggedIn() then // If player isn't logged in then
begin
players[currentPlayer].login(); // Log them in
exitSquealOfFortune(); // Exit squeal if found
minimap.setAngle(MM_DIRECTION_NORTH); // Make compass north and angle high
mainScreen.setAngle(MS_ANGLE_HIGH);
end;
getDemons();
end.

Lipcot

2014-12-13 14:19:36

for combat you could do something like this, which searches for the green bar that appears when you attack a monster. (i look for it in tabbackpack because i moved it there for better detection)

function IsInCombat(): boolean
var
FightDTM, x, y: integer;
begin

FightDTM := DTMFromString('mggAAAHicY2NgYAhhYWDQB2IpIGYF4r/MDAwxQHoSE3as6+KHgtUsHcGYlQE7YMSBIQAATFwJ2A==');
// a dtm of something on the popup infight
if findDTM(FightDTM, x, y, tabbackpack.getbounds()) then
begin
wait(100);
writeLn('=We Are Currently Fighting');
result := true;
end else
begin
writeLn('=We Are NOT Currently Fighting');
result := false;
end;
end;

for HP checking the following function:

function isHPLow(): boolean;
begin
result := actionbar.getHPPercent() < 30; //result true if HP < 30%
end;

so you can do:

if isHPlow then
heal();

for attacking the demons, you could use chooseoptions


if chooseoption.optionsExist(['lesser','demon']) then
begin
chooseoption.select(['ttack','lesser','demon'], 500);
writeLn('we succesfully attacked lesser demon');
end else writeLn('We clicked something that was not a lesser demon');

FoxGaming

2014-12-13 14:26:09

From: undorak7
for combat you could do something like this, which searches for the green bar that appears when you attack a monster. (i look for it in tabbackpack because i moved it there for better detection)

function IsInCombat(): boolean
var
FightDTM, x, y: integer;
begin

FightDTM := DTMFromString('mggAAAHicY2NgYAhhYWDQB2IpIGYF4r/MDAwxQHoSE3as6+KHgtUsHcGYlQE7YMSBIQAATFwJ2A==');
// a dtm of something on the popup infight
if findDTM(FightDTM, x, y, tabbackpack.getbounds()) then
begin
wait(100);
writeLn('=We Are Currently Fighting');
result := true;
end else
begin
writeLn('=We Are NOT Currently Fighting');
result := false;
end;
end;

for HP checking the following function:

function isHPLow(): boolean;
begin
result := actionbar.getHPPercent() < 30; //result true if HP < 30%
end;

so you can do:

if isHPlow then
heal();

for attacking the demons, you could use chooseoptions


if chooseoption.optionsExist(['lesser','demon']) then
begin
chooseoption.select(['ttack','lesser','demon'], 500);
writeLn('we succesfully attacked lesser demon');
end else writeLn('We clicked something that was not a lesser demon');


Thank you for the information, I'm understanding all of that for the most part. But when it comes to right clicking the demon to show the options, is there anyway I would be able to tell if my mouse is actually over the demon? They move quite frequently but pause a lot as well, so if my mouse was to slow than it would just be right clicking the ground.

KeepBotting

2014-12-13 14:31:33

From: FoxGaming
Hey everyone,

So I'm definitely not new to botting, but I'm definitely new to the Simba Scene.
Been working on creating a Combat Script to kill Lesser Demons in the Karamja Volcano Resource dungeon.
Welcome! Glad to see you've made the transition :) & that sounds like a pretty awesome script!

From: FoxGaming

I'm having trouble though, mostly because I'm a lower level than the lesser demons. So I've not really figured out how to detect when my mouse is over them or not. I was thinking with my ATPA box I could then detect if my mouse was within those bounds? So a conditional wait until the ATPA box around the found demon contained my mouse, which I could then right click and select attack.

Well, there are a couple of things you could do to mitigate this.
  • Right click instead of left click, and read the chooseOption menu. Might not be the best solution as right-clicking everywhere is probably pretty bot-like
  • Choose a color so unique as to be positive that every time you mouse to it, you're on a monster
  • Create a DTM of the target information popup and look for it (I believe that popup displays when you hover over a monster, correct me if I'm wrong)
  • Split, resize, filter, append, delete, just generally muck around with your TPAs or ATPAs until you find a combination that give you reliable results

Obviously some of those are less ideal solutions than others, I just thought them up off the top of my head. I'm sure others will have more to add.

I was thinking with my ATPA box I could then detect if my mouse was within those bounds? So a conditional wait until the ATPA box around the found demon contained my mouse, which I could then right click and select attack.


You're overthinking this a bit - there are already functions provided for you to move the mouse to a point :), you could do something like this:


function attack():boolean;
var
tpa:TPointArray;
finalAtpa:T2DPointArray;
i, h:integer;
begin
finalAtpa := getDemons(); //you'd have to turn getDemons into a function and have it output an atpa
//I can show you how to do that if you like

h := high(finalAtpa); //set the high of the final atpa to an integer

for i := 0 to h do //for..to..do #1, for getting click points
insert(finalAtpa[i].centerPoint, tpa); //get the center points of every tpa in the atpa and store them in yet another tpa

tpa.sortFromPoint(mainscreen.playerPoint); //sort em

for i := 0 to h do //for..to..do #2, for mousing the monsters
begin
mouseRandom(tpa[i].randRange(-3, 3), MOUSE_RIGHT); //mouse to the point
if chooseOption.select(['Attack', 'ttac']) then //and the rest, as they say, is history
if didClick(true) then
if minimap.isFlagPresent(randomRange(1500, 3000)) then
begin
minimap.waitPlayerMoving();
exit(true);
end;
end;
end;

From: FoxGaming

I'm also working on my own include library to store functions, like a check for combat, and healthPCT etc. So any tips on that will also be appreciated.

Here is what I have so far…which is basically just following TheMayor's tutorial.

undorak's combat check function is good, but here's how I do mine:

function hasTargeted():boolean;
var
tpa:TPointArray;
i:integer;
begin
result := findColorsTolerance(tpa, redCircle.col, redCircle.area, redCircle.tol, redCircle.cts);
//smartImage.debugTpa(tpa);
end;

I ripped that straight out of my fighting script, so there's some other stuff that needs done to make it work (declaring types and setting CTS2 values) which I can help you with if you decide to use this way.

What it does is looks for the red targeting reticule around the monster you're attacking.
Once you've got that, you could even return the physical location of your fight by doing something like this:


function getFightLocation():TBox;
var
tpa:TPointArray;
begin
if not (hasTargeted()) then
exit;

if findColorsTolerance(tpa, redCircle.col, mainScreen.getBounds(), redCircle.tol, redCircle.cts) then
result := getTpaBounds(tpa);

if not (disableDrawing) then
smartImage.drawBox(result, false, clYellow); //draw it

writeDebug('Player is in combat with NPC at ' + toStr(result));
end;

Again, types and other things would need to be declared to make that work, which I can help you with if you want.

For checking health, actionBar.getHpHercent() will return the percent of HP you've got left, undorak made a good point about making a wrapper for it so you've not got to type all that every time.

Best of luck, let me know if you've any questions :)

Edit:

From: FoxGaming
Thank you for the information, I'm understanding all of that for the most part. But when it comes to right clicking the demon to show the options, is there anyway I would be able to tell if my mouse is actually over the demon? They move quite frequently but pause a lot as well, so if my mouse was to slow than it would just be right clicking the ground.

One thing I noticed in my fighting script is that NPCs move - a lot! (I know, I know, it's crazy but true) and two things can help with this:

  • a faster mouse (you can set your mouse speed to whatever you want with something like mouseSpeed := 50; or mouseSpeed := 100;
  • less looping

The second one is going to take a bit of explaining. Say I've got 10 monsters in a room and they all move around pretty frequently. Once I create my TPA, split it to ATPA, yadda yadda, it becomes static. I'm not longer dynamically recognizing colors on the screen.

This is where NPC movement becomes pretty annoying. My array of 10 TPAs becomes useless after a bit!
The trick I use is to forget some of those TPAs - instead of wasting time mousing to each one. Because if we don't click a monster in the first 3 or 4, it's safe to say that all the others have moved too.

There's an easy way to do that with the function I provided earlier (I've removed the other comments to make my intention clearer)


function attack():boolean;
var
tpa:TPointArray;
finalAtpa:T2DPointArray;
i, h:integer;
begin
finalAtpa := getDemons();

h := high(finalAtpa);

for i := 0 to h do
insert(finalAtpa[i].centerPoint, tpa);

tpa.sortFromPoint(mainscreen.playerPoint);

for i := 0 to 2 do //From zero to two. So for a total of three times.
begin //That means we'll only mouse to three monsters. And if we don't find something, we'll quit.
//And after we quit, you'd be free to call the entire function again and get a brand-new ATPA!
mouseRandom(tpa[i].randRange(-3, 3), MOUSE_RIGHT);
if chooseOption.select(['Attack', 'ttac']) then
if didClick(true) then
if minimap.isFlagPresent(randomRange(1500, 3000)) then
begin
minimap.waitPlayerMoving();
exit(true);
end;
end;
end;

:)

Edit 2:

Derp, I forgot you'll need this to use that attack() function:

function TPointArray.centerPoint():TPoint;
var
tmp:TPointArray;
begin
if (length(self) < 1) then
exit;

tmp := self;
tmp.sortFromPoint(self.getMiddle());
result := tmp[0];
end;

FoxGaming

2014-12-13 15:37:18

From: KeepBotting
Welcome! Glad to see you've made the transition :) & that sounds like a pretty awesome script!


Well, there are a couple of things you could do to mitigate this.
  • Right click instead of left click, and read the chooseOption menu. Might not be the best solution as right-clicking everywhere is probably pretty bot-like
  • Choose a color so unique as to be positive that every time you mouse to it, you're on a monster
  • Create a DTM of the target information popup and look for it (I believe that popup displays when you hover over a monster, correct me if I'm wrong)
  • Split, resize, filter, append, delete, just generally muck around with your TPAs or ATPAs until you find a combination that give you reliable results

Obviously some of those are less ideal solutions than others, I just thought them up off the top of my head. I'm sure others will have more to add.



You're overthinking this a bit - there are already functions provided for you to move the mouse to a point :), you could do something like this:


Code removed for brevity


undorak's combat check function is good, but here's how I do mine:


Code removed for brevity

Again, types and other things would need to be declared to make that work, which I can help you with if you want.

For checking health, actionBar.getHpHercent() will return the percent of HP you've got left, undorak made a good point about making a wrapper for it so you've not got to type all that every time.

Best of luck, let me know if you've any questions :)

Edit:


One thing I noticed in my fighting script is that NPCs move - a lot! (I know, I know, it's crazy but true) and two things can help with this:

  • a faster mouse (you can set your mouse speed to whatever you want with something like mouseSpeed := 50; or mouseSpeed := 100;
  • less looping

The second one is going to take a bit of explaining. Say I've got 10 monsters in a room and they all more around pretty frequently. Once I create my TPA, split it to ATPA, yadda yadda, it becomes static. I'm not longer dynamically recognizing colors on the screen.

This is where NPC movement becomes pretty annoying. My array of 10 TPAs becomes useless after a bit!
The trick I use is to forget some of those TPAs - instead of wasting time mousing to each one. Because if we don't click a monster in the first 3 or 4, it's safe to say that all the others have moved too.

There's an easy way to do that with the function I provided earlier (I've removed the other comments to make my intention clearer)


Code removed for brevity

:)



Thank you for the information! I know I'm still trying to figure out everything in the API so I don't start reinventing the wheel.

I'll have to keep studying the API and your examples and see what I can come up with. Going from the pbot API and my ClientContext to this is so different.

edit: Thank you @KeepBotting finally got the attack portion working!

FoxGaming

2014-12-13 19:56:38

From: KeepBotting
Welcome! Glad to see you've made the transition :) & that sounds like a pretty awesome script!


Well, there are a couple of things you could do to mitigate this.
  • Right click instead of left click, and read the chooseOption menu. Might not be the best solution as right-clicking everywhere is probably pretty bot-like
  • Choose a color so unique as to be positive that every time you mouse to it, you're on a monster
  • Create a DTM of the target information popup and look for it (I believe that popup displays when you hover over a monster, correct me if I'm wrong)
  • Split, resize, filter, append, delete, just generally muck around with your TPAs or ATPAs until you find a combination that give you reliable results

Obviously some of those are less ideal solutions than others, I just thought them up off the top of my head. I'm sure others will have more to add.



You're overthinking this a bit - there are already functions provided for you to move the mouse to a point :), you could do something like this:

Removed for quote


undorak's combat check function is good, but here's how I do mine:

Removed for quote

I ripped that straight out of my fighting script, so there's some other stuff that needs done to make it work (declaring types and setting CTS2 values) which I can help you with if you decide to use this way.

What it does is looks for the red targeting reticule around the monster you're attacking.
Once you've got that, you could even return the physical location of your fight by doing something like this:

Removed for quote

Again, types and other things would need to be declared to make that work, which I can help you with if you want.

For checking health, actionBar.getHpHercent() will return the percent of HP you've got left, undorak made a good point about making a wrapper for it so you've not got to type all that every time.

Best of luck, let me know if you've any questions :)

Edit:


One thing I noticed in my fighting script is that NPCs move - a lot! (I know, I know, it's crazy but true) and two things can help with this:

  • a faster mouse (you can set your mouse speed to whatever you want with something like mouseSpeed := 50; or mouseSpeed := 100;
  • less looping

The second one is going to take a bit of explaining. Say I've got 10 monsters in a room and they all move around pretty frequently. Once I create my TPA, split it to ATPA, yadda yadda, it becomes static. I'm not longer dynamically recognizing colors on the screen.

This is where NPC movement becomes pretty annoying. My array of 10 TPAs becomes useless after a bit!
The trick I use is to forget some of those TPAs - instead of wasting time mousing to each one. Because if we don't click a monster in the first 3 or 4, it's safe to say that all the others have moved too.

There's an easy way to do that with the function I provided earlier (I've removed the other comments to make my intention clearer)

Removed for quote
:)

Edit 2:

Derp, I forgot you'll need this to use that attack() function:

Removed for quote


I guess i accidentally deleted my other post, but thank you for the help. I finally got it to start attacking. So now I'll be starting to figure out the other stuff!

KeepBotting

2014-12-13 20:09:14

From: FoxGaming
I guess i accidentally deleted my other post, but thank you for the help. I finally got it to start attacking. So now I'll be starting to figure out the other stuff!


Awesomeness, glad to hear it. Hit me up with any other questions :)

FoxGaming

2014-12-13 20:16:34

From: KeepBotting
Awesomeness, glad to hear it. Hit me up with any other questions :)


well regarding your hasTargeted() method,

function hasTargeted():boolean;
var
tpa:TPointArray;
i:integer;
begin
result := findColorsTolerance(tpa, redCircle.col, redCircle.area, redCircle.tol, redCircle.cts);
//smartImage.debugTpa(tpa);
end;

so basically, biggest thing I'm confused about is the tpa that is being passed to it. I'm assuming the param2 is color, param3 is the viewport(well the screen), param4 is the tolerance from ACA, and param5 is the cts which is also from ACA depending on your setting?

KeepBotting

2014-12-13 20:29:03

From: FoxGaming
well regarding your hasTargeted() method,

function hasTargeted():boolean;
var
tpa:TPointArray;
i:integer;
begin
result := findColorsTolerance(tpa, redCircle.col, redCircle.area, redCircle.tol, redCircle.cts);
//smartImage.debugTpa(tpa);
end;

so basically, biggest thing I'm confused about is the tpa that is being passed to it. I'm assuming the param2 is color, param3 is the viewport(well the screen), param4 is the tolerance from ACA, and param5 is the cts which is also from ACA depending on your setting?


There's no TPA being passed to it. Other than that, you're exacly right.

It outputs a TPA (in this case, simply named "tpa"), but what's passed to findColorsTolerance() are called CTS2 values (or TColorSettings if you want to be fancy).

Quick lowdown on how I do this:

1. First, declare this type somewhere near the top of your script:

type
colorInfo = record
cts:TColorSettings;
col, tol:integer;
area:TBox;
end;

This creates a new type of record that we'll store (you guessed it) color information in!

2. Next, you'll need to declare some global variables of the type "colorInfo" (makes sense now huh?)

For instance, if I was going to make a colorInfo record of a tree, I'd declare globally a variable like this:

var
tree:colorInfo;

3. Then, create a new procedure, I like to name mine initColors()

procedure initColors();
begin

with tree do //it's a good idea to leave a quick comment stating exactly where you got these colors, in case you forget
begin
cts.cts := 2; //CTS modifier. We're using CTS2 so this will always be 2
cts.modifier.hue := 0.69; //Hue modifier from ACA
cts.modifier.saturation := 4.20; //Saturation modifier from ACA
cts.modifier.sensitivity := 15; //Ignore this, it's never actually used
col := 1234567; //Color from ACA
tol := 5; //Tolerance from ACA
area := mainScreen.getBounds(); //This is your chance to set a predefined search area
end;

writeLn('Colors have been initalized.');
end;

4. Call that procedure before you do any object finding (you only need to call it once, it will setup your colors for the duration of the run)

After that, you're free to use CTS2 color finders with paramaters like tree.col, tree.area, tree.tol, tree.cts

(tree.cts sets TColorSettings and will take care of tree.hue and tree.sat)

FoxGaming

2014-12-13 20:36:02

From: KeepBotting
There's no TPA being passed to it. Other than that, you're exacly right.

It outputs a TPA, but what's passed to findColorsTolerance() are called CTS2 values (or TColorSettings if you want to be fancy).

Quick lowdown on how I do this:

1. First, declare this type somewhere near the top of your script:

type
colorInfo = record
cts:TColorSettings;
col, tol:integer;
area:TBox;
end;

This creates a new type of record that we'll store (you guessed it) color information in!

2. Next, you'll need to declare some global variables of the type "colorInfo" (makes sense now huh?)

For instance, if I was going to make a colorInfo record of a tree, I'd declare globally a variable like this:

var
tree:colorInfo;

3. Then, create a new procedure, I like to name mine initColors()

procedure initColors();
begin

with tree do //it's a good idea to leave a quick comment stating exactly where you got these colors, in case you forget
begin
cts.cts := 2; //CTS modifier. We're using CTS2 so this will always be 2.
cts.modifier.hue := 0.69; //Hue modifier from ACA
cts.modifier.saturation := 4.20; //Saturation modifier from ACA
cts.modifier.sensitivity := 15;//This is never actually used in CTS2, I'm just too lazy to delete it from my template
col := 1234567; //Color from ACA
tol := 5; //Tolerance from ACA
area := mainScreen.getBounds(); //This is your chance to set a predefined search area
end;

writeLn('Colors have been initalized.');
end;

4. Call that procedure before you do any object finding (it will setup your colors)

After that, you're free to use CTS2 color finders with paramaters like tree.col, tree.area, tree.tol, tree.cts

(tree.cts sets TColorSettings and will take care of tree.hue and tree.sat)


That definitely makes sense, I read the tutorial for records I just never really thought about implementing it yet.

Alright last question before I just dive in, are HotKeys configured like they are on PBot? So if I wanted to bind my food to the #9 hot key I would use

SendKeys({VK_9}, 100, 250);
to send the key press?

KeepBotting

2014-12-13 20:40:29

From: FoxGaming
That definitely makes sense, I read the tutorial for records I just never really thought about implementing it yet.

Alright last question before I just dive in, are HotKeys configured like they are on PBot? So if I wanted to bind my food to the #9 hot key I would use

SendKeys({VK_9}, 100, 250);
to send the key press?


I was unaware that RSBot used virtual keys. I know Simba has some like VK_ENTER and VK_SPACE but for SendKeys() you can actually use a string, like so:

SendKeys('Hello World', 100, 250);

SendKeys('9', 100, 250);

FoxGaming

2014-12-14 16:14:49

From: KeepBotting
I was unaware that RSBot used virtual keys. I know Simba has some like VK_ENTER and VK_SPACE but for SendKeys() you can actually use a string, like so:

SendKeys('Hello World', 100, 250);

SendKeys('9', 100, 250);


It will do Virtual keys if you format it correctly for RSBot,

so this is the code I've got so far, However my combat check does not seem to be working. Because I'm always clicking attack instead of waiting once I click attack.


program demonSlayer;

{$DEFINE SMART} // Always have this to load smart
{$I SRL-6/SRL.simba} // To load the SRL include files
{$I SPS/lib/SPS-RS3.Simba} // To load the SPS include files

type
colorInfo = record
cts:TColorSettings;
col, tol:integer;
area:TBox;
end;

var
foodStart : integer;
combatCirc : colorInfo;



function isHPLow(): boolean;
begin
result := actionbar.getHPPercent() < 30; //result true if HP < 30%
end;

function hasTargeted():boolean;
var
tpa:TPointArray;
i:integer;
begin
result := findColorsTolerance(tpa, combatCirc.col, combatCirc.area, combatCirc.tol, combatCirc.cts);
smartImage.debugTpa(tpa);
end;

function mouseRandom(TPoint:TPoint; mouseAction:integer):boolean;
var
mouseStyle: array [0..2] of integer;
begin
mouseStyle := [MOUSE_BREAK, MOUSE_ACCURATE, MOUSE_HUMAN];
mouseSpeed := randomRange(25, 35);
if (mouseAction = MOUSE_MOVE) then
missMouse(TPoint, true);
if (mouseAction <> MOUSE_MOVE) then
mouse(TPoint, mouseAction, mouseStyle[randomRange(0, 2)]);
end;

function getDemons():T2DPointArray;
var
x, y, i: integer;
TPA: TPointArray;
ATPA: T2DPointArray;

begin
if not isLoggedIn() then
exit;

findColorsSpiralTolerance(x, y, TPA, 3823248, mainScreen.getBounds(), 9, colorSetting(2, 0.12, 0.03));

if (Length(TPA) < 1) then
exit;
ATPA := TPA.toATPA(30, 30);
ATPA.sortFromMidPoint(mainScreen.playerPoint);
//smartImage.debugATPA(ATPA);
exit(ATPA);
end

function TPointArray.centerPoint():TPoint;
var
tmp:TPointArray;
begin
if (length(self) < 1) then
exit;

tmp := self;
tmp.sortFromPoint(self.getMiddle());
result := tmp[0];
end;

function attack():boolean;
var
tpa:TPointArray;
finalAtpa:T2DPointArray;
i, h:integer;
begin
finalAtpa := getDemons(); //you'd have to turn getDemons into a function and have it output an atpa
//I can show you how to do that if you like

h := high(finalAtpa); //set the high of the final atpa to an integer

for i := 0 to h do //for..to..do #1, for getting click points
insert(finalAtpa[i].centerPoint, tpa); //get the center points of every tpa in the atpa and store them in yet another tpa

tpa.sortFromPoint(mainscreen.playerPoint); //sort em

for i := 0 to h do //for..to..do #2, for mousing the monsters
begin
mouseRandom(tpa[i].randRange(-3, 3), MOUSE_RIGHT); //mouse to the point
if chooseOption.select(['Attack', 'ttac']) then //and the rest, as they say, is history
if didClick(true) then
if hasTargeted() then
begin
exit(true);
end;
end;
end;


procedure declarePlayers();
begin
setLength(players, 1);
with players[0] do
begin
loginName := '------------';
password := '-----------';
isActive := true;
isMember := true;
end
currentPlayer := 0;
end;

procedure eatFood()
begin
//eat food
while isHPLow() do
begin
PressKey(30);
wait(randomRange(500, 1500));
writeLn('I guess that food was good');
foodStart := foodStart - 1;
end
end

procedure useAbilities()
begin
//make this faster.
end

procedure lootItems()
begin
//loot crap
end


procedure mainLoop;
begin
if not hasTargeted() then
begin
attack();
end;
if isHPLow() then
begin
eatFood();
end ;
end


procedure initColors();
begin
with combatCirc do
begin
cts.cts := 2;
cts.modifier.hue := 0.04;
cts.modifier.saturation := 0.31;
cts.modifier.sensitivity := 0;
col := 2700248;
tol := 2;
area := mainScreen.getBounds();
end;

writeLn('Colors have been initialized.');
end;

// mainish loop
begin
foodStart := 20;
clearDebug(); // Clear the debug box
smartEnableDrawing := true; // So we can draw on SMART
setupSRL(); // Load the SRL include files
declarePlayers();
initColors();
// Set up your username/pass

repeat
if not isLoggedIn() then
begin
players[currentPlayer].login();
exitSquealOfFortune();
mainScreen.setAngle(MS_ANGLE_HIGH);
minimap.setAngle(MM_DIRECTION_NORTH);
end;

mainLoop();
//progressReport();
until(false);
end.

KeepBotting

2014-12-14 16:23:32

From: FoxGaming
It will do Virtual keys if you format it correctly for RSBot,

so this is the code I've got so far, However my combat check does not seem to be working. Because I'm always clicking attack instead of waiting once I click attack.


program demonSlayer;

{$DEFINE SMART} // Always have this to load smart
{$I SRL-6/SRL.simba} // To load the SRL include files
{$I SPS/lib/SPS-RS3.Simba} // To load the SPS include files

type
colorInfo = record
cts:TColorSettings;
col, tol:integer;
area:TBox;
end;

var
foodStart : integer;
combatCirc : colorInfo;



function isHPLow(): boolean;
begin
result := actionbar.getHPPercent() < 30; //result true if HP < 30%
end;

function hasTargeted():boolean;
var
tpa:TPointArray;
i:integer;
begin
result := findColorsTolerance(tpa, combatCirc.col, combatCirc.area, combatCirc.tol, combatCirc.cts);
smartImage.debugTpa(tpa);
end;

function mouseRandom(TPoint:TPoint; mouseAction:integer):boolean;
var
mouseStyle: array [0..2] of integer;
begin
mouseStyle := [MOUSE_BREAK, MOUSE_ACCURATE, MOUSE_HUMAN];
mouseSpeed := randomRange(25, 35);
if (mouseAction = MOUSE_MOVE) then
missMouse(TPoint, true);
if (mouseAction <> MOUSE_MOVE) then
mouse(TPoint, mouseAction, mouseStyle[randomRange(0, 2)]);
end;

function getDemons():T2DPointArray;
var
x, y, i: integer;
TPA: TPointArray;
ATPA: T2DPointArray;

begin
if not isLoggedIn() then
exit;

findColorsSpiralTolerance(x, y, TPA, 3823248, mainScreen.getBounds(), 9, colorSetting(2, 0.12, 0.03));

if (Length(TPA) < 1) then
exit;
ATPA := TPA.toATPA(30, 30);
ATPA.sortFromMidPoint(mainScreen.playerPoint);
//smartImage.debugATPA(ATPA);
exit(ATPA);
end

function TPointArray.centerPoint():TPoint;
var
tmp:TPointArray;
begin
if (length(self) < 1) then
exit;

tmp := self;
tmp.sortFromPoint(self.getMiddle());
result := tmp[0];
end;

function attack():boolean;
var
tpa:TPointArray;
finalAtpa:T2DPointArray;
i, h:integer;
begin
finalAtpa := getDemons(); //you'd have to turn getDemons into a function and have it output an atpa
//I can show you how to do that if you like

h := high(finalAtpa); //set the high of the final atpa to an integer

for i := 0 to h do //for..to..do #1, for getting click points
insert(finalAtpa[i].centerPoint, tpa); //get the center points of every tpa in the atpa and store them in yet another tpa

tpa.sortFromPoint(mainscreen.playerPoint); //sort em

for i := 0 to h do //for..to..do #2, for mousing the monsters
begin
mouseRandom(tpa[i].randRange(-3, 3), MOUSE_RIGHT); //mouse to the point
if chooseOption.select(['Attack', 'ttac']) then //and the rest, as they say, is history
if didClick(true) then
if hasTargeted() then
begin
exit(true);
end;
end;
end;


procedure declarePlayers();
begin
setLength(players, 1);
with players[0] do
begin
loginName := 'username@hotmail.com';
password := 'password';
isActive := true;
isMember := true;
end
currentPlayer := 0;
end;

procedure eatFood()
begin
//eat food
while isHPLow() do
begin
PressKey(30);
wait(randomRange(500, 1500));
writeLn('I guess that food was good');
foodStart := foodStart - 1;
end
end

procedure useAbilities()
begin
//make this faster.
end

procedure lootItems()
begin
//loot crap
end


procedure mainLoop;
begin
if not hasTargeted() then
begin
attack();
end;
if isHPLow() then
begin
eatFood();
end ;
end


procedure initColors();
begin
with combatCirc do
begin
cts.cts := 2;
cts.modifier.hue := 0.04;
cts.modifier.saturation := 0.31;
cts.modifier.sensitivity := 0;
col := 2700248;
tol := 2;
area := mainScreen.getBounds();
end;

writeLn('Colors have been initialized.');
end;

// mainish loop
begin
foodStart := 20;
clearDebug(); // Clear the debug box
smartEnableDrawing := true; // So we can draw on SMART
setupSRL(); // Load the SRL include files
declarePlayers();
initColors();
// Set up your username/pass

repeat
if not isLoggedIn() then
begin
players[currentPlayer].login();
exitSquealOfFortune();
mainScreen.setAngle(MS_ANGLE_HIGH);
minimap.setAngle(MM_DIRECTION_NORTH);
end;

mainLoop();
//progressReport();
until(false);
end.


get your password out of the script dood

I will edit this post with a proper response now.

Edit:

I think the issue of attacking against whilst still in combat stems from how you check combat.

The only time you're calling hasTargeted() is in the mainloop, but only once and it doesn't have a loop of its own.

I prefer to create separate conditional waits for my *-detection functions, something a little like this:

procedure waitWhileFighting();
var
t:TTimeMarker
begin
t.start();
repeat
if (hasTargeted()) or (hasBeenTargeted()) then
begin
case random(2) of
0: wait(randomRange(800, 1200));
1: sleepAndMoveMouse(randomRange(800, 1200));
end;
fightLocation := getFightLocation(); //refresh the fight location continually while in combat
end;
until (not hasTargeted()) or (t.getTime() > (maxWait * 1000)); //timeout failsafe
writeDebug('Player is out of combat');
end;

You can also try debugging hasTargeted()'s tpa onto the smartImage to see what the function is seeing

FoxGaming

2014-12-14 16:25:29

From: KeepBotting
get your password out of the script dood

I will edit this post with a proper response now.


Woops, lol it's been that kind of day so far xD

KeepBotting

2014-12-14 16:36:07

From: FoxGaming
Woops, lol it's been that kind of day so far xD


:P don't worry, I've done it (multiple times) too.

Check my edit on the post above, and as well - look into the SRL Player Manager, Rafiki. Using it will make it so you'll never need to add your username and password to a script again :D