SRL Archive - SRL Archives

ScapeRune-Island-Solver!


King of Knives

2007-10-20 11:34:13

I got the ScapeRune-island random after using Wizzup?'s essence miner. I was bored at a LAN-party (my computer couldn't play the game the others played), and I wanted to script. I logged in and found it at the island and I though: "Why not?". I started it and didn't get very far that day. Then I continued today, and finally it's finished.

Now I need testers.

1) I'm not sure if you need to talk to Evil Bob before talking to his servant. (I haven't scripted it to talk with Evil Bob)
2) I not sure I got all from the Servant-conversation , meaning it can have some problems with that.

Else, I tested everything pretty much.

A quick summary of what the script contains:
> Automatic retry on fuck-up's
> Good statue detection by DTM :D
Only scripted to work with eastern and western statue. Finds the eastern statue nearly every time, and the western about every third time.

> Very good fishing-net-pick-up'er
> Full autocolor

It has it's own little progress report, I just added it after I completed the random :duh:

I don't know why, but it doesn't really make the compass north or make it HighestAngle as it should.

If you have a ScapeRune account, just run this when you ARE on the island (Preferably after having been logged out).

Thanks in advance!

PS: I don't know how to detect if you ARE on the island. I tried DTM's and it didn't work, so I'm lost :P

CODE:
program ScapeRune;
{.include SRL/SRL.scar}

var
TalkTries: Integer;
Direction: String;
GotNet: Boolean;

Function FindScapeRuneIsland: Boolean;
begin
// I need some help on this one. I don't see any reliable way
// to see if it is ScapeRune island, or just a normal place.
Result:= True;
end;

Procedure FlagNWait;
begin
Wait(20+random(30))
FFlag(0)
Wait(200+random(300))
end;

Function WaitUntilText(Text: String; MaxTime: Integer): Boolean;
var
a,b,Timer: Integer;
begin
MarkTime(Timer)
repeat
Wait(100+random(100))
if TimeFromMark(Timer) > MaxTime then
begin
Result:= False;
Exit;
end;
until FindText(a,b,Text,NPCChars,MCx1,MCy1,MCx2,MCy2)
Result:= True;
end;

Function RadialWalkMinRadius(TheColor,StartRadial,EndRadial,StartRadius,EndRadius: Integer): Boolean;
var a,b,I,R,Sx,Sy: Integer;
begin
if StartRadial > EndRadial then
begin
for R:= StartRadius downto EndRadius do
begin
for I:= StartRadial Downto EndRadial do
begin
Sx:= Round(R*Cose(I))+MMCx
Sy:= Round(-R*Sine(I))+MMCy
if FindColor(a,b,TheColor,Sx,Sy,Sx+1,Sy+1) then
begin
MouseFindNoFlag(a,b,random(2),random(2))
Result:= True;
Exit;
end;
end;
end;
end;
if StartRadial < EndRadial then
begin
for R:= StartRadius to EndRadius do
begin
for I:= StartRadial Downto EndRadial do
begin
Sx:= Round(R*Cose(I))+MMCx
Sy:= Round(-R*Sine(I))+MMCy
if FindColor(a,b,TheColor,Sx,Sy,Sx+1,Sy+1) then
begin
MouseFindNoFlag(a,b,random(2),random(2))
Result:= True;
Exit;
end;
end;
end;
end;
end;

Procedure GotoMiddle;
var
NPCs,a,b,I: Integer;
E: Extended;
begin
NPCs := DTMFromString('78DA63AC656260086740017FFE30318800694' +
'6289FB113A82612B79AFF400000EBB809D7');
if FindDTMRotated(NPCs,a,b,MMx1,MMy1,MMx2,MMy2,-45,45,0.01,E) then
begin
Mouse(a,b-3,8,6,true)
FlagNWait;
end else
begin
for I:= 0 to 20 do
begin
if FindColorTolerance(a,b,195836,MMx1,MMy1,MMx2,MMy2,I) then
begin
Mouse(a,b,3,3,true)
FlagNWait;
Break;
end;
end;
end;
FreeDTM(NPCs)
end;

Procedure FindTheCat;
var
a,b,Cat,I: Integer;
E: Extended;
begin
Cat := DTMFromString('78DA637CC8C8C0D008C44840454989410448C' +
'344199F00593DA86AE4656551D53C00B23A50D5880A0AA2AA790A' +
'6435A1AA9192904055F39008731EE177CF7F200000236F0ED7');
repeat
if FindDTMRotated(Cat,a,b,MSx1,MSy1,MSx2,MSy2,-45,45,0.01,E) then
begin
MMouse(a,b,3,3)
Wait(100+random(100))
If IsUpText('vil') then
begin
GetMousePos(a,b)
Mouse(a,b,0,0,true)
FreeDTM(Cat)
FFlag(0)
Exit;
end;
end else Wait(1000+random(1000))
until(I = 4)
for I:= 0 to 1 do
begin
if FindObj(a,b,'vil',2500136,10) then
begin
GetMousePos(a,b)
Mouse(a,b,0,0,true)
FreeDTM(Cat)
FFlag(0)
Exit;
end else Wait(20000)
end;
FreeDTM(Cat)
end;

Function FindTheServant: Boolean;
var
a,b,I: Integer;
Boxes: Array [1..5] of TBox;
begin
repeat
Inc(I)
if FindColorSkipboxArrayTolerance(a,b,1211030,MSx1,MSy1,MSx2,MSy2,20,Boxes) then
begin
MMouse(a,b,3,5)
Wait(100+random(50))
if IsUpText('alk-to') then
begin
GetMousePos(a,b)
Mouse(a,b,0,0,true)
Result:= True;
FlagNWait;
Exit;
end else Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
end else Wait(5000+random(5000))
until(I = 5)
if FindObj(a,b,'alk-to',1211030,20) then
begin
GetMousePos(a,b)
Mouse(a,b,0,0,true)
Result:= True;
FlagNWait;
Exit;
end;
end;

Procedure DoServantTalk; Forward;

Procedure ContinueServantTalk(Word: String);
begin
if WaitUntilText(Word,10000) then ClickToContinue
else
begin
if TalkTries >= 4 then TerminateScript;
Inc(TalkTries)
FindTheServant;
DoServantTalk;
end;
end;

Procedure DoServantTalk;
begin
ContinueServantTalk('kidnapped')
ContinueServantTalk('rrr')
ContinueServantTalk('listen')
ContinueServantTalk('asleep')
ContinueServantTalk('fishing')
end;

Procedure GetEastStatue;
var
a,b,Statue: Integer;
E: Extended;
begin
Statue := DTMFromString('78DA639CCCC8C0F08701059C5BEFCDC005A41' +
'9A17CC61940D6175435C75778A2AAE903B23EA1AAB9BECD0F554D' +
'1B90F50F55CDBE052EA86ABA812C3646FCEE990064F1A1AA797E3' +
'40255CD54204B0D55CDCB53F97035FF8100006293194F');
if FindDTMRotated(Statue,a,b,MSx1,MSy1,MSx2,MSy2,-10,10,0.01,E) then
begin
Direction:= 'East'
end;
FreeDTM(Statue)
end;

Procedure GetWestStatue;
var
a,b,Statue: Integer;
E: Extended;
begin
Statue := DTMFromString('78DA634C60646028056224B066A21D033F908' +
'68932A661AAA9CDD24555930A64A5A2AAF17690465593026445A3' +
'AAE92A35C454D382AAA62C451B554D1290558DAA66FD14074C73D' +
'0D4A486AAA2AAC903B22612B02B1CC89A833B7CFE030100035516' +
'C3');
if FindDTMRotated(Statue,a,b,MSx1,MSy1,MSx2,MSy2,-10,10,0.01,E) then
begin
Direction:= 'West'
end;
FreeDTM(Statue)
end;

Procedure AskServant;
begin
FindTheServant;
ContinueServantTalk('fishing')
end;

Procedure GetDirection;
var Timer,Tries: Integer;
begin
Direction:= '';
repeat
Inc(Tries)
AskServant;
MarkTime(Timer)
repeat
GetEastStatue;
GetWestStatue;
until(TimeFromMark(Timer) > 7000)
until((Direction = '')=False) or (Tries >= 20)
Writeln('* '+Direction+'ern statue detected')
end;

Procedure PickUpNet;
var a,b: Integer;
begin
if FindObj(a,b,'ake',2503230,10) then
begin
GetMousePos(a,b)
Mouse(a,b,0,0,true)
FlagNWait;
end;
end;

Procedure ToFishSpots;
var a,b,SandColor,Sand: Integer;
begin
Sand := DTMFromString('78DA630C636260886140011BA707318800694' +
'6289F11A4268A809A1022CC8900AA8925A0261CA8269E809A6022' +
'D44462BA67FD94404C3787E3370700F02C131A');
if FindDTM(Sand,a,b,MMx1,MMy1,MMx2,MMy2) then SandColor:= GetColor(a,b)
else
begin
if FindColorTolerance(a,b,6988222,MMx1,MMy1,MMx2,MMy2,10) then SandColor:= GetColor(a,b)
else if FindColorTolerance(a,b,6988222,MMx1,MMy1,MMx2,MMy2,15) then SandColor:= GetColor(a,b)
else if FindColorTolerance(a,b,6988222,MMx1,MMy1,MMx2,MMy2,20) then SandColor:= GetColor(a,b)
else if FindColorTolerance(a,b,6988222,MMx1,MMy1,MMx2,MMy2,25) then SandColor:= GetColor(a,b)
end;
case Lowercase(Direction) of
'east': if RadialWalkMinRadius(SandColor,80,100,65,55) then FlagNWait
else
begin
Mouse(695, 90,5,5,true)
FlagNWait;
end;
'west': if RadialWalkMinRadius(SandColor,280,260,65,55) then FlagNWait
else
begin
Mouse(587, 76,5,5,true)
FlagNWait;
end;
end;
end;

Procedure GoEast;
var a,b,Nets,Tol: Integer;
begin
for Tol:= 0 to 20 do
begin
if FindColorTolerance(a,b,241,MMx1,MMy1,MMx2,MMy2,Tol) then
begin
Nets:= GetColor(a,b)
Break;
end;
end;
if not GotNet then
begin
if RadialWalk(Nets,80,10,65,1,1) then
begin
FlagNWait;
PickUpNet;
GotoMiddle;
end else
begin
Mouse(a+2,b+2,2,2,true)
FlagNWait;
Wait(200+random(300))
GotoMiddle;
end;
end;
ToFishSpots;
end;

Procedure GoWest;
var a,b,Nets,Tol: Integer;
begin
for Tol:= 0 to 20 do
begin
if FindColorTolerance(a,b,241,MMx1,MMy1,MMx2,MMy2,Tol) then
begin
Nets:= GetColor(a,b)
Break;
end;
end;
if not GotNet then
begin
if RadialWalk(Nets,285,350,65,1,1) then
begin
FlagNWait;
PickUpNet;
GotoMiddle;
end else
begin
Mouse(a+2,b+2,2,2,true)
FlagNWait;
PickUpNet;
GotoMiddle;
end;
end;
ToFishSpots;
end;

Procedure GetToFish;
begin
GetDirection;
case LowerCase(Direction) of
'east': GoEast;
'west': GoWest;
end;
end;

Function FishTheFish: Boolean;
var
a,b,c,d,e,f,I,FishLikeThing: Integer;
Boxes: Array [0..29] of TBox;
Fishing: Boolean;
begin
FishLikeThing := DTMFromString('78DA63EC67626078CC80020A834C18FE03694' +
'620FE0F048C93806AEE31A00146241248F702D53C20A0A613A8E6' +
'0901351D4035AF09A8E903AA794740CD1422D4CC02AA794940CD4' +
'2A09AA704D42C22C2EFD309872100FDAE1656');
GameTab(4)
repeat
if FindColorSkipboxArrayTolerance(a,b,13946838,85, 45,MSx2,MSy2,20,Boxes) then
begin
if FindColorTolerance(c,d,1775637,a-30,b-30,a+30,b+30,20) then
begin
if FindColorTolerance(e,f,10714989,a-30,b-30,a+30,b+30,20) then
begin
MMouse(a,b,3,3)
Wait(100+random(100))
if IsUpText('et') then
begin
GetMousePos(e,f)
Mouse(e,f,0,0,true)
FlagNWait;
Fishing:= True;
Break;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
until(I >= 30)
if Fishing then
begin
MarkTime(I)
repeat
Wait(100+random(100))
if FindDTM(FishLikeThing,a,b,MIx1,MIy1,MIx2,MIy2) then
begin
Writeln('* Got the fish')
Result:= True;
Break;
end;
if FindText(a,b,'servants',NPCChars,MCx1,MCy1,MCx2,MCy2) then
begin
Writeln('* We weren'#39't fishing on the right spot.')
Result:= False;
Break;
end;
until(TimeFromMark(I) > 25000)
end else Result:= False;
end;

Procedure ClickUnCookingPot;
var
a,b,c,d,e,f,I: Integer;
Boxes: Array [0..29] of TBox;
begin
repeat
if FindColorSkipboxArrayTolerance(a,b,7498603,85, 45,MSx2,MSy2,20,Boxes) then
begin
if FindColorTolerance(c,d,802899,a-50,b-50,a+50,b+50,20) then
begin
if FindColorTolerance(e,f,9919301,a-50,b-50,a+50,b+50,20) then
begin
MMouse(a,b,3,3)
Wait(100+random(100))
if IsUpText('se') then
begin
GetMousePos(e,f)
Mouse(e,f,0,0,true)
FlagNWait;
Break;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
end else
begin
Boxes[I]:= IntToBox(a-15,b-15,a+15,b+15)
Inc(I)
end;
until(I >= 30)
end;

Procedure UnCookAndAll;
var FishLikeThing,a,b,I: Integer;
begin
FishLikeThing := DTMFromString('78DA63EC67626078CC80020A834C18FE03694' +
'620FE0F048C93806AEE31A00146241248F702D53C20A0A613A8E6' +
'0901351D4035AF09A8E903AA794740CD1422D4CC02AA794940CD4' +
'2A09AA704D42C22C2EFD309872100FDAE1656');
GotoMiddle;
if FindDTM(FishLikeThing,a,b,MIx1,MIy1,MIx2,MIy2)then
begin
Mouse(a,b,7,7,false)
Wait(200+random(300))
ChooseOption('Use')
Wait(500+random(500))
ClickUnCookingPot;
repeat
Wait(500+random(500))
Inc(I)
until(SimilarColors(GetColor(a,b),13136920,20)) or (I >= 15)
Wait(300+random(500))
Mouse(a,b,5,5,true)
Wait(500+random(500))
FindTheCat;
if WaitUntilText('delicious',10000) then ClickToContinue;
end;
end;

Procedure PortalAway;
var a,b,I: Integer;
begin
repeat
if FindObj(a,b,'ortal',8701894,15) then
begin
GetMousePos(a,b)
Mouse(a,b,0,0,true)
FlagNWait;
Wait(2000+random(1000))
Exit;
end;
Wait(100+random(100))
Inc(I)
until(I >= 50)
end;

Function SolveScapeRuneIsland: Boolean;
var
Tries: Integer;
Label
Redo;
begin
Tries:= 1;
if FindScapeRuneIsland then
Writeln('******** FOUND SCAPERUNE-ISLAND ********')
else Exit;
HighestAngle;
MakeCompass('N')
Redo:
if Tries > 5 then
begin
Result:= False;
LogOut;
end;
Writeln('** Try number '+IntToStr(Tries))
Writeln('---')
GotoMiddle;
FindTheServant;
DoServantTalk;
GetToFish;
if not FishTheFish then
begin
Inc(Tries)
Writeln('---')
Goto Redo
end;
UnCookAndAll;
PortalAway;
if WaitUntilText('strangest',10000) ClickToContinue;
if WaitUntilText('become',10000) ClickToContinue;
Writeln('******** SOLVED SCAPERUNE-ISLAND ********')
Result:= True;
end;

begin
SetupSRL;
SolveScapeRuneIsland;
end.

-Knives

n3ss3s

2007-10-20 11:55:44

Woah, looks good, though shame I dont have any accs in scape rune so I could test. How it worked for you or have you got chance to try yet?

King of Knives

2007-10-20 12:06:56

I didn't know you could only talk with the servant once (the whole conversation), so I didn't get that tested, but I believe it should work.
The Statue-detection, getting to fish, fishing and uncooking part worked flawlessly about 5 times.

-Knives

Markus

2007-10-20 12:37:28

Nice, another one :)
I made mine a while ago, it isn't finished, as I don't have any chars in the evil bob random:
http://www.villavu.com/forum/showthread.php?t=15599
Detects the north and south statue too ;)

King of Knives

2007-10-20 12:45:22

I thought that one statue only would be too detectable, and 4 were too many to do :P I chose 2 :D

-Knives

R0b0t1

2007-10-20 12:47:35

Labels are pretty much deprecated… And I don't think I saw a failsafe there either.

Like So:


If not (FishTheFish) and (TriesToRedo < 10) then
goto Redo;

King of Knives

2007-10-20 13:06:55

  Redo:
if Tries > 5 then
begin
Result:= False;
LogOut;
end;

There is a failsafe.

-Knives

Smartzkid

2007-10-20 13:33:04

Never gotten this random, so I can't comment much, but any new random solvers are great achievements. Good Job!

Negaal

2007-10-21 07:37:57

failed… talked to serv… it talked until statue, closed window, and slept some 20 sec, tryed to talk servent again, but everytime it clicked on serv and text showed up on bottom then become laggy, had to abort

RudeBoiAlex

2007-10-21 07:46:04

Next time i get one illl give it a go :)

The Claw

2007-10-21 08:37:29

Could you explain how you detect which statue? Have you just made DTM's of the east and west statue and use them, or is it something different? Looks pretty good though. I'm not sure if the position of the statues is constant though…they might change positions.

Tim0suprem0

2007-10-21 11:55:31

Nice job Knives, I'll test when I get and let you know how it does.

Wizzup?

2007-10-21 13:45:31

Knifes, don't worry about detection if you are on the Island.
Next SRL will have full Random Recognition.

EDIT: There are only 4 statues?
Like, they never change?

Bramble

2007-10-21 14:03:52

well the statues themself never change, as there are 4 types of the statues, but there position on the island does change, and the one that evil bob likes the fish from changes.

n3ss3s

2007-10-21 14:06:33

Like, they never change?


Statues stay the same ;)

One with the cat like "attacking", one with umm is "stretching" the right word - towards the sky, etc..

*In Wizzy's mind: "No shit, - and I thought they were just random stances, great job guys, there goes research and development of solving the formulas the cats statues change of few years!" *

King of Knives

2007-10-21 14:24:37

Do their position on the island change?! Dang, I didn't know that.

@ Wizzup: Knives :P

@ The Claw: I didn't know that they changed places on the island. Kinda destroys it all.

-Knives

Wizzup?

2007-10-21 15:48:29

From: n3ss3s
*In Wizzy's mind: "No shit, - and I thought they were just random stances, great job guys, there goes research and development of solving the formulas the cats statues change of few years!" *


Yea.. Sort of… :redface:

From: King of Knives
Do their position on the island change?! Dang, I didn't know that.

@ Wizzup: Knives :P


-Knives


Sorry.. Typo.
Would be nice if you get this to work 100%. :)

The Claw

2007-10-21 17:31:19

From: King of Knives
Do their position on the island change?! Dang, I didn't know that.

@ Wizzup: Knives :P

@ The Claw: I didn't know that they changed places on the island. Kinda destroys it all.

-Knives


I'm not sure, thats what I was asking :) Nice work anyhow, it would be great to get it to work 100%. If they do change, once you know what statue to choose you could walk to each one and check, perhaps?

King of Knives

2007-10-22 07:18:03

I think that recognizing the statues on the REAL mainscreen would be pretty hard. I would have to use some time on making DTMs :D My favourite tool.

-Knives

Markus

2007-10-22 12:28:23

The island is 100% static, nothing changes :p
My old (unfinished) solver still works after 4 months :D

King of Knives

2007-10-22 15:32:31

Nice to know that it doesn't change. Then my script works after all. Or not, 'cause I haven't tried it since my char had it…

-Knives