SRL Archive - Jr. Member General Help and Discussion

until FindDTM


Lolsen

2014-02-25 04:42:45

Hi guys, so I've started creating my own Charm Sprite script and I've got to the point where I need it to recognise that a lure has been thrown, so this is what I did ( this may be a little unorthodox :P )

Firstly I say my script finds the bushes easy and does throw a lure at them, (haven't distinguished from the shaking bushes atm, and it just throws at all bushes, but I'll get to that), so I wanted a way that my script would recognize a lure has been thrown and for it to move onto the next procedure, so I used a repeat until.

For the until I created a DTM for the Spirit lure that has been thrown.

But my script still just throws the spirit lure then tries to throw again. straight away.

This is my script at the moment!

program LolsenCharmSprite;

{$DEFINE SMART}
{$I SRL-6/SRL.simba}
{$I SPS/lib/sps-rs3.Simba}

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

procedure loadDTMs();
var
lureDTM: integer;
luredDTM: integer;
begin
lureDTM := DTMFromString('mggAAAHicY2NgYGhkZmBoAOJ2IK5ghvBbgfgzIwPDEyD+CsTfgfgPEL8AYiMDA4aO7n4GTXV1BncXFwYne3sG36BIBkkG7IARB4YAANbzDh0=');
luredDTM := DTMFromString('mbQAAAHicY2VgYOAEYhEg5meAAG4g5gFiQSCWAGIBqLipkRGDtJQUg6a6OoOTvT2DkYEBgyQDJmDEgsEAAMa7A1E=');
end;

procedure areWeLoggedIn();
begin

if isLoggedIn() then
writeLn('Well, we are not not logged in, thats a start!');

end;

procedure findNeverBerryBush();
var
luredDTM, x, y, i: integer;
begin
if not isLoggedIn() then
exit;

repeat
mainscreen.findObject(x, y, 1657928, 2, colorSetting(2, 1.29, 6.63), mainscreen.playerPoint, 40, 40, 30, ['arget', 'ush'], MOUSE_LEFT);
wait(randomRange(1000, 2000));
inc(i);

luredDTM := DTMFromString('mbQAAAHicY2VgYOAEYhEg5meAAG4g5gFiQSCWAGIBqLipkRGDtJQUg6a6OoOTvT2DkYEBgyQDJmDEgsEAAMa7A1E=');
until findDTM(luredDTM, x, y, tabBackPack.getBounds());
end;





procedure targetNeverBerry();
begin
//code here
end;

procedure targetLure();
begin
//code here
end;

procedure catchSprite();
begin
//code here
end;




{Main Loop}
begin
clearDebug();
smartEnableDrawing := true;
setupSRL();
declarePlayers();

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

findNeverBerryBush();
targetNeverBerry();
targetLure();
catchSprite();


end.


//I want to create a script that hunts Charm Sprites, it does this by recognizing that it is in the right area,
//It then targets a Neverberry Bush that is shaking, throws a lure to it, targets the lure and catches the
//charm sprites that appear.

Frement

2014-02-25 04:51:53

Does throwing the lure trigger a chat message? If the chat is something like this:
You swing your pick at the rock.
You manage to mine some tin.
then you can use GetLastChatText function to detect it.

Lolsen

2014-02-25 05:00:57

From: Frement
Does throwing the lure trigger a chat message? If the chat is something like this:
You swing your pick at the rock.
You manage to mine some tin.
then you can use GetLastChatText function to detect it.


Never actually used this function haha, first for everything, would definitely be the suitable function for that I need.

Now to try to add it to my script, may have trouble fitting it in since I havent used it before


Is this on the right track?

procedure findNeverBerryBush();
var
x, y, i: integer;
chat: string;
begin
if not isLoggedIn() then
exit;

repeat
mainscreen.findObject(x, y, 1657928, 2, colorSetting(2, 1.29, 6.63), mainscreen.playerPoint, 40, 40, 30, ['arget', 'ush'], MOUSE_LEFT);
wait(randomRange(1000, 2000));
inc(i);

until GetLastChatText(var chat: String): Boolean;
end;

sdf

2014-02-25 05:30:44

until chatbox.findTextOnLines(['whatever the thrown text is here'], [0]);

Pretty sure there isn't a GetLastChatText() in SRL6.

Clarity

2014-02-25 11:11:18

Not going to copy and paste my entire private script over multiple threads but here's a tip :p
Use @waitFunc. Waitfunc constantly calls a function for a specified time until it returns true. For example, say you had a function like
function isLureOnGround: boolean;
which checked for the DTM or a color or chat message, you would use waitFunc later in the script as such:
waitFunc(@isLureOnGround, 50, 10000);
This translates into "call isLureOnGround once every 50ms until 10000ms has elapsed or it returns true."

If you use a repeat until loop instead, make sure you include a failsafe timer to avoid making an endless loop.

Lolsen

2014-02-26 02:30:57

From: Clarity
Not going to copy and paste my entire private script over multiple threads but here's a tip :p
Use @waitFunc. Waitfunc constantly calls a function for a specified time until it returns true. For example, say you had a function like
function isLureOnGround: boolean;
which checked for the DTM or a color or chat message, you would use waitFunc later in the script as such:
waitFunc(@isLureOnGround, 50, 10000);
This translates into "call isLureOnGround once every 50ms until 10000ms has elapsed or it returns true."

If you use a repeat until loop instead, make sure you include a failsafe timer to avoid making an endless loop.



create a function for it using a mainscreen find object?

Clarity

2014-02-26 23:46:29

From: Lolsen
create a function for it using a mainscreen find object?

For better practice consider making your own color search function. Mainscreen findobj is nice for a backup in case your unique function fails. For example I like to use something like this in many of my scripts:
{FUNCTION -- findEsswraith
Purpose: Search for NPC colors, sort them, select siphon option.
Comments: None.}
function findEsswraith: boolean;
var
x, y, i, attempts: integer;
TPA: TPointArray;
ATPA: T2DPointArray;
begin
if not isLoggedIn then exit;
ClarityDebug('FindEsswraith was initiated.');
while attempts < 15 do
begin
if findColorsSpiralTolerance(x, y, TPA, desiredEsswraith.ewColor, mainScreen.getBounds(), desiredEsswraith.ewTolerance, colorSetting(2, desiredEsswraith.ewHue, desiredEsswraith.ewSat)) then
begin
TPA.filterPointsBox(getIslandGeography);
mainscreen.filterPointsPlayer(TPA);
TPAtoATPAWrap(TPA, 40, ATPA);
ATPA.sortFromMidPoint(mainscreen.playerPoint);
if showScriptDebug then
smartImage.debugATPA(ATPA);
for i := 0 to high(ATPA) do
begin
mouse(ATPA[i].getMiddle, MOUSE_MOVE, MOUSE_HUMAN);
if isMouseOverText([desiredEsswraith.ewName], 500) then
begin
if useRightClick then
begin
fastClick(MOUSE_RIGHT);
if not chooseOption.optionsExist(['iphon']) then
begin
ClarityDebug('Siphon option not present.');
scriptStatus('Siphon option not present - retrying.');
chooseOption.close();
continue;
end;
result := chooseOption.select(['iphon', 'raith']);
scriptStatus('Esswraith search and siphon successful.');
{...etc...}
end;

It's nice to make your own in case your script requires a very unique searching method vs. the standard findobj.

You can use the ACA tool to get the information you need for the sprite lure colors.
Also, in my sprites script I specify a certain bush to search around for the lure, defined by a custom TBox variable which is based on the midpoint of the previously targeted bush. This is so it doesn't search the entire mainscreen and possibly find a wrong matching color. It's also a good idea to filter out points from the playerbox via the mainscreen.filterPointsPlayer(TPA); function.

So, in summary, you would use waitfunc to call the color search you made a bunch of times before a certain failsafe time (i.e. if nothing is found for 10-20 seconds something probably messed up and we should do something else).

Sk1nyNerd

2014-02-27 00:07:38

From: Lolsen
Hi guys, so I've started creating my own Charm Sprite script and I've got to the point where I need it to recognise that a lure has been thrown, so this is what I did ( this may be a little unorthodox :P )

Firstly I say my script finds the bushes easy and does throw a lure at them, (haven't distinguished from the shaking bushes atm, and it just throws at all bushes, but I'll get to that), so I wanted a way that my script would recognize a lure has been thrown and for it to move onto the next procedure, so I used a repeat until.

For the until I created a DTM for the Spirit lure that has been thrown.

But my script still just throws the spirit lure then tries to throw again. straight away.

This is my script at the moment!

program LolsenCharmSprite;

{$DEFINE SMART}
{$I SRL-6/SRL.simba}
{$I SPS/lib/sps-rs3.Simba}

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

procedure loadDTMs();
var
lureDTM: integer;
luredDTM: integer;
begin
lureDTM := DTMFromString('mggAAAHicY2NgYGhkZmBoAOJ2IK5ghvBbgfgzIwPDEyD+CsTfgfgPEL8AYiMDA4aO7n4GTXV1BncXFwYne3sG36BIBkkG7IARB4YAANbzDh0=');
luredDTM := DTMFromString('mbQAAAHicY2VgYOAEYhEg5meAAG4g5gFiQSCWAGIBqLipkRGDtJQUg6a6OoOTvT2DkYEBgyQDJmDEgsEAAMa7A1E=');
end;

procedure areWeLoggedIn();
begin

if isLoggedIn() then
writeLn('Well, we are not not logged in, thats a start!');

end;

procedure findNeverBerryBush();
var
luredDTM, x, y, i: integer;
begin
if not isLoggedIn() then
exit;

repeat
mainscreen.findObject(x, y, 1657928, 2, colorSetting(2, 1.29, 6.63), mainscreen.playerPoint, 40, 40, 30, ['arget', 'ush'], MOUSE_LEFT);
wait(randomRange(1000, 2000));
inc(i);

luredDTM := DTMFromString('mbQAAAHicY2VgYOAEYhEg5meAAG4g5gFiQSCWAGIBqLipkRGDtJQUg6a6OoOTvT2DkYEBgyQDJmDEgsEAAMa7A1E=');
until findDTM(luredDTM, x, y, tabBackPack.getBounds());
end;





procedure targetNeverBerry();
begin
//code here
end;

procedure targetLure();
begin
//code here
end;

procedure catchSprite();
begin
//code here
end;




{Main Loop}
begin
clearDebug();
smartEnableDrawing := true;
setupSRL();
declarePlayers();

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

findNeverBerryBush();
targetNeverBerry();
targetLure();
catchSprite();


end.


//I want to create a script that hunts Charm Sprites, it does this by recognizing that it is in the right area,
//It then targets a Neverberry Bush that is shaking, throws a lure to it, targets the lure and catches the
//charm sprites that appear.


1) you did not free your DTMs. WHHYYYYYYYYYYYY :(
2) you have two DTMS of the same name, one is already defined so you do not need to define it again in the procedure
3) when you make the DTM try setting a higher tolerance, 255 is the max. it might not actually be finding the dtm so you are stuck in the loop and thats why it keeps throwing it back out. you could also try making a better DTM or using a color search function to find the object on screen

Clarity

2014-02-27 05:30:00

Another note on chat text, if you decide to use that method, make sure that you include some kind of failsafe that ensures it doesn't think an old message is actually a newly incoming one. Recently with my barrows script I've had some significant difficulty with it trying to detect chat messages accurately, so if you use that I hope you have better luck :)

masterBB

2014-02-27 09:07:42

Sk1nyNerd is right, you need to work on freeing those DTMs.

Imagine highschool lockers. Every locker has its own unique number, starting at one, so you can find your locker back. Every time you call DTMFromString simba will pick a new empty locker, put the DTM in it and returns the locker number to you. That is the integer.

If you keep calling DTMFromString you will use more and more lockers. At a certain moment the locker are all filled with DTMs, which means your RAM is full and simba will crash. If you used a locker(DTM) make sure to return it, so you do not run out of them. Call FreeDTM when you no longer need the memory slot. Like after the findDTM call.

If you call DTMFromSTring in a loop you will just place tons of copies of the same DTM in a lot of lockers. You might start with locker number 10, but if it keeps repeating you might use up to 100000+! This is a waste of your lockers(memory).

Lolsen

2014-03-01 23:38:57

From: masterBB
Sk1nyNerd is right, you need to work on freeing those DTMs.

Imagine highschool lockers. Every locker has its own unique number, starting at one, so you can find your locker back. Every time you call DTMFromString simba will pick a new empty locker, put the DTM in it and returns the locker number to you. That is the integer.

If you keep calling DTMFromString you will use more and more lockers. At a certain moment the locker are all filled with DTMs, which means your RAM is full and simba will crash. If you used a locker(DTM) make sure to return it, so you do not run out of them. Call FreeDTM when you no longer need the memory slot. Like after the findDTM call.

If you call DTMFromSTring in a loop you will just place tons of copies of the same DTM in a lot of lockers. You might start with locker number 10, but if it keeps repeating you might use up to 100000+! This is a waste of your lockers(memory).



That's a good desc of freeing the DTM's, I have freed the DTM's regardless of whether I'll be using them, might be taking them out all together, however in future I will always free the DTM's.

So on topic after all the replies, I will work on creating a function for finding the lure on the ground, probably by as Clarity suggested, placing a Tbox around the bush and only getting it to search for the colour within the Tbox, I can see why Clarity has done it this way, as there is a stone in the middle of the field which shares the same colours as the Lure.

Clarity

2014-03-02 00:52:02

From: Lolsen
I can see why Clarity has done it this way, as there is a stone in the middle of the field which shares the same colours as the Lure.

Exactly :) best of luck man, nice to see ya taking good initiative to learn and make something of your own.