J J
2012-05-25 16:43:34
08-06-2012 edit: I will work on this again from 10/06/2012 and I'm pretty sure I will release this around 13/06/2012 or earlier.
Hey,
I'm looking to make a fast script for the Barbarian Outpost Agility Course. I will be making short blog posts from when I work on this project. I hope to update this daily. Everything will be posted in chronological order.
25/05/2012
I spend some time picking the colors of all the obstacles. After hopping worlds atleast 5-10 times and changing the angles multiple times I've came up with the correct colors/tolerances/hue&sat mods. I've also checked the uptext.
Here is a picture of the actual working on picking the colors: [1920x1080 -> LARGE]
http://img19.imageshack.us/img19/5716/fullscreenh.png
26/05/2012
I started the day with trying the colors I picked at 25/05/2012, as a test to see if they were indeed correct.
After that I started to work out the clickable parts for each obstacle: (This is with Paint not with Simba
I know what needs to be done now, so I can start on the coding. Let's see how this works out and what problems I might run in to!
Later this day I've pretty much worked out a neat idea to click extremely accurate but extremely random at the same time!
Debug Image of my ATPA of the Rope Swing. I also "calculated" the middle myself to check if the middle would actually be a point.
SMART colored the rope swing
Yellow points = TPoints
Cyan boxes = TPA bounds
Green boxes = ATPA[0] & ATPA[1]
Red dot = middle ATPA[0] & middle ATPA[1]
Red boxes = Clickable part of the rope swing
This is a picture when I run the script when someone is using the swing:
I will use this to define which swing to use. If they are both free it will be random, if one is used it will use the other and if they are both being used it will wait until one of them can be used again.
—-
Here is a .gif of letting simba move the mouse to some clickable parts of the rope swing.
Spot #1 is somewhere on rope #1
Spot #2 is somewhere on rope #2
Spot #3 is somwhere between the box north of rope #1
Spot #4 is somwhere between the box north of rope #2

–
Later that day I finished the scripting part. It works well. If one if the swings is being used, it will use the other swing. If someone uses the swing at the same time as you it will click on the swing again after a while. If you fail to pass the swing it will climb out of the hole, and swing the rope again. If you succeed the result will be true.
—
So yeah it is actually nearly the end of the day now but I also maked the functions for the log rather quickly after finishing up the swing. Let's start with some pictures.
Finding the middle of the Log by using Paint and the debug image
Debug image and the log

Purple box is the area that is clickable.
Large yellow rectangle is the log.
Red square is roughly the TPA bounds of the log.
Cyan rectangle is the TPA Bounds of all the brown-ish colors similiar to the log
27/05/2012
I finished all the obstacles now including failsafes. I don't really feel like writing a long story so here some pictures and the code. Also made a video. Pictures non chronological order.. Backwards actually.









I will edit the video soon of the all the functions in action but here is the code:
Video:
Showing the failsafes and object detection, it's pretty advanced!
www.youtube.com/watch?v=Ql9CswKvMhA
[youtube]Ql9CswKvMhA[/youtube]
18/06/2012
It has been some time since I last worked on this, I'm not really sure why because it is actually really interesting to make. I will be finishing this today. The only thing that needs to be made is a good mainloop. And I need to check out if everything still works.

To be continued…
Hey,
I'm looking to make a fast script for the Barbarian Outpost Agility Course. I will be making short blog posts from when I work on this project. I hope to update this daily. Everything will be posted in chronological order.
25/05/2012
I spend some time picking the colors of all the obstacles. After hopping worlds atleast 5-10 times and changing the angles multiple times I've came up with the correct colors/tolerances/hue&sat mods. I've also checked the uptext.
#1
===================
Swing
HueMod: 0.12
SatMod: 0.57
Color: 663074
Tol: 5
Uptext: Swing-on Rope Swing
===================
#2
===================
Log
HueMod: 0.15
SatMod: 0.76
Color: 1777965
Tol: 11
Uptext: Walk-across Log Balance
===================
#3
===================
Inside Net:
HueMod: 0.10
SatMod: 0.58
Color: 5204079
Tol: 7
Uptext: Climb-over Obstacle net
Outside Net:
HueMod: 0.11
SatMod: 0.98
Color: 3298924
Tol: 18
Uptext: Climb-over Obstacle net
===================
#4
===================
Ledge:
HueMod: 0.15
SatMod: 0.49
Color: 1587529
Tol: 10
Uptext: Walk-across Balancing ledge
===================
#5
===================
Ladder Down:
HueMod: 0.14
SatMod: 0.74
Color: 1520451
Tol: 7
Uptext: Climb-down ladder
===================
#6
===================
Crumbled Wall:
HueMod: 0.15
SatMod: 0.16
Color: 6317675
Tol: 24
Uptext: Climb-over Crumbling wall
===================Here is a picture of the actual working on picking the colors: [1920x1080 -> LARGE]
http://img19.imageshack.us/img19/5716/fullscreenh.png
26/05/2012
I started the day with trying the colors I picked at 25/05/2012, as a test to see if they were indeed correct.
After that I started to work out the clickable parts for each obstacle: (This is with Paint not with Simba
I know what needs to be done now, so I can start on the coding. Let's see how this works out and what problems I might run in to!Later this day I've pretty much worked out a neat idea to click extremely accurate but extremely random at the same time!
Debug Image of my ATPA of the Rope Swing. I also "calculated" the middle myself to check if the middle would actually be a point.
SMART colored the rope swing Yellow points = TPoints
Cyan boxes = TPA bounds
Green boxes = ATPA[0] & ATPA[1]
Red dot = middle ATPA[0] & middle ATPA[1]
Red boxes = Clickable part of the rope swing
This is a picture when I run the script when someone is using the swing:
I will use this to define which swing to use. If they are both free it will be random, if one is used it will use the other and if they are both being used it will wait until one of them can be used again.—-
Here is a .gif of letting simba move the mouse to some clickable parts of the rope swing.
Spot #1 is somewhere on rope #1
Spot #2 is somewhere on rope #2
Spot #3 is somwhere between the box north of rope #1
Spot #4 is somwhere between the box north of rope #2

–
Later that day I finished the scripting part. It works well. If one if the swings is being used, it will use the other swing. If someone uses the swing at the same time as you it will click on the swing again after a while. If you fail to pass the swing it will climb out of the hole, and swing the rope again. If you succeed the result will be true.
function RopeFail: Boolean;
var
X, Y, i: Integer;
LadderCl: TPointArray;
LadderClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.12, 1.01);
if FindColorsSpiralTolerance(X, Y, LadderCl, 3030082, MSCX-100, MSCY-50, MSCX, MSCY+50, 11) then
begin
SplitTPAExWrap(LadderCl, 1, 1, LadderClSplit);
SortATPASize(LadderClSplit, True);
for i:=0 to High(LadderClSplit) do
begin
MiddleTPAEx(LadderClSplit[i], X, Y);
MMouse(X, Y, RandomRange(-2, 2), RandomRange(-2, 2));
if WaitUpTextMulti(['limb', 'up', 'adder', 'Climb', 'Ladder'], 500) then
begin
ClickMouse2(1);
Wait(4000 + Random(1000));
Result:=True;
Break;
end;
end;
end;
end;
function RopeCheck: String;
var
t: Integer;
begin
MarkTime(t);
repeat
Wait(50 + Random(50));
until (FindChatBoxText('slip', 8, clBlack)) or (FindChatBoxText('skil', 8, clBlack)) or (FindChatBoxText('used', 8, clBlack)) or (TimeFromMark(t)>2000);
if (TimeFromMark(t)>2000) then
begin
WriteLn('Something has gone wrong, trying again');
Result:='time';
end;
if FindChatBoxText('slip', 8, clBlack) then
begin
WriteLn('We have failed to swing the rope, recovering');
Result:='fail';
end;
if FindChatBoxText('used', 8, clBlack) then
begin
WriteLn('The rope is being used already, trying again soon');
Result:='used';
end;
if FindChatBoxText('skil', 8, clBlack) then
begin
WriteLn('We have succesfully swinged the rope!');
Result:='swing';
end;
end;
function RopeSwing: Boolean;
var
X, Y, P, i: Integer;
RopeLength: Array[0..1] of Integer;
SwingCl: TPointArray;
SwingClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.12, 0.57);
if FindColorsSpiralTolerance(X, Y, SwingCl, 663074, MSX1, MSY1, MSX2, MSY2, 5) then
begin
SplitTPAExWrap(SwingCl, 1, 1, SwingClSplit);
SortATPASize(SwingClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
SMART_DrawDotsEx(True, SwingCl, clYellow); // Both swings
SMART_DrawBoxes(False, [GetTPABounds(SwingCl)], clAqua); // TPA Box
SMART_DrawBoxes(False, [GetTPABounds(SwingClSplit[0]), GetTPABounds(SwingClSplit[1])], clGreen); // ATPA boxes
SMART_DrawCircle(False, MiddleTPA(SwingClSplit[0]), 2, True, clRed); // Left Swing middle
SMART_DrawCircle(False, MiddleTPA(SwingClSplit[1]), 2, True, clRed); // Right Swing middle
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(SwingClSplit[0]).X1, 3 + GetTPABounds(SwingClSplit[0]).Y1, GetTPABounds(SwingClSplit[0]).X2, GetTPABounds(SwingClSplit[0]).Y1 + (GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1)/10)], clRed); // Box on top of swing #1
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(SwingClSplit[1]).X1, 3 + GetTPABounds(SwingClSplit[1]).Y1, GetTPABounds(SwingClSplit[1]).X2, GetTPABounds(SwingClSplit[1]).Y1 + (GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1)/10)], clRed); // Box on top of swing #2
WriteLn('SwingClSplit[0] length: '+IntToStr(High(SwingClSplit[0]))+'');
WriteLn('SwingClSplit[1] length: '+IntToStr(High(SwingClSplit[1]))+'');
WriteLn('Rope #1 length: '+IntToStr((GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1))+'');
WriteLn('Rope #2 length: '+IntToStr((GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1))+'');
end;
RopeLength[0] := (GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1);
RopeLength[1] := (GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1);
if (RopeLength[0] < 100) and (RopeLength[1] < 100) then
begin
case Random(4) of
0: begin
P := RandomRange(Low(SwingClSplit[0]), High(SwingClSplit[0]));
MMouse(SwingClSplit[0][P].X, SwingClSplit[0][P].Y, 0, 0); // Random spot on rope 1
end;
1: begin
P := RandomRange(Low(SwingClSplit[1]), High(SwingClSplit[1]));
MMouse(SwingClSplit[1][P].X, SwingClSplit[1][P].Y, 0, 0); // Random spot on rope 2
end;
2: Mousebox(GetTPABounds(SwingClSplit[0]).X1, 3 + GetTPABounds(SwingClSplit[0]).Y1, GetTPABounds(SwingClSplit[0]).X2, GetTPABounds(SwingClSplit[0]).Y1 + (GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1)/10, 2); // Random spot in the box of rope 1
3: Mousebox(GetTPABounds(SwingClSplit[1]).X1, 3 + GetTPABounds(SwingClSplit[1]).Y1, GetTPABounds(SwingClSplit[1]).X2, GetTPABounds(SwingClSplit[1]).Y1 + (GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1)/10, 2); // Random spot in the box of rope 2
end;
if WaitUpTextMulti(['wing', 'on', 'ope', 'Swing', 'Rope'], 500) then
ClickMouse2(1);
end else
begin
if (RopeLength[0] > 100) and (RopeLength[1] > 100) then
begin
Wait(2000 + Random(2000));
RopeSwing;
end else
begin
for i:=0 to 1 do
begin
if (RopeLength[i] < 100) then
begin
case Random(2) of
0: begin
P := RandomRange(Low(SwingClSplit[i]), High(SwingClSplit[i]));
MMouse(SwingClSplit[i][P].X, SwingClSplit[i][P].Y, 0, 0); // Random spot on rope 1
end;
1: Mousebox(GetTPABounds(SwingClSplit[i]).X1, 3 + GetTPABounds(SwingClSplit[i]).Y1, GetTPABounds(SwingClSplit[i]).X2, GetTPABounds(SwingClSplit[i]).Y1 + (GetTPABounds(SwingClSplit[i]).Y2 - GetTPABounds(SwingClSplit[i]).Y1)/10, 2); // Random spot in the box of rope 1
end;
if WaitUpTextMulti(['wing', 'on', 'ope', 'Swing', 'Rope'], 500) then
ClickMouse2(1);
end;
end;
end;
end;
Wait(3000 + Random(1000));
case RopeCheck of
'swing': Result:=True;
'time': RopeSwing;
'fail': begin
if RopeFail then
RopeSwing;
end;
'used': RopeSwing;
end;
end;
end;—
So yeah it is actually nearly the end of the day now but I also maked the functions for the log rather quickly after finishing up the swing. Let's start with some pictures.
Finding the middle of the Log by using Paint and the debug image
Debug image and the log 
Purple box is the area that is clickable.Large yellow rectangle is the log.
Red square is roughly the TPA bounds of the log.
Cyan rectangle is the TPA Bounds of all the brown-ish colors similiar to the log
// Walking over the log \\
function LogCheck: String;
var
i, t: Integer;
PossibleText: Array of String;
begin
MarkTime(t);
repeat
Wait(50 + Random(50));
until (FindChatBoxText('lose', 8, clBlack)) or (FindChatBoxText('bites', 8, clBlack)) or (FindChatBoxText('safe', 8, clBlack)) or (TimeFromMark(t)>3000);
if TimeFromMark(t) < 3000 then
begin
PossibleText := ['lose', 'bites', 'safe'];
for i:=0 to 2 do
begin
if FindChatBoxText(PossibleText[i], 8, clBlack) then
Result := PossibleText[i];
end;
end else
Result:='time';
end;
function LogWalk: Boolean;
var
X, Y: Integer;
LogCl: TPointArray;
LogClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.15, 0.76);
if FindColorsSpiralTolerance(X, Y, LogCl, 1777965, MSX1, MSY1, MSX2, MSY2, 11) then
begin
SplitTPAExWrap(LogCl, 1, 1, LogClSplit);
SortATPASize(LogClSplit, True);
DebugATPABounds(LogClSplit);
if Debug then
begin
SMART_ClearCanvas;
SMART_DrawDotsEx(True, LogCl, clYellow); // Log
SMART_DrawBoxes(False, [GetTPABounds(LogCl)], clAqua); // TPA Box
SMART_DrawCircle(False, MiddleTPA(LogClSplit[0]), 2, True, clRed); // Middle log
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(LogClSplit[0]).X1, GetTPABounds(LogClSplit[0]).Y1 + 8, GetTPABounds(LogClSplit[0]).X2, GetTPABounds(LogClSplit[0]).Y2 - 4)], clRed); // Box of the log
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(LogClSplit[0]).X2 - 35, GetTPABounds(LogClSplit[0]).Y1 + 8, GetTPABounds(LogClSplit[0]).X2, GetTPABounds(LogClSplit[0]).Y2 - 4)], clPurple); // Box of the clickable part
end;
Mousebox(GetTPABounds(LogClSplit[0]).X2 - 35, GetTPABounds(LogClSplit[0]).Y1 + 8, GetTPABounds(LogClSplit[0]).X2, GetTPABounds(LogClSplit[0]).Y2 - 4, 2);
if WaitUpTextMulti(['alk', 'across', 'alance', 'Walk', 'Log', 'Balance'], 500) then
begin
case Random(7) of
0..4: ClickMouse2(1);
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['alk', 'across', 'alance', 'Walk', 'Log', 'Balance'], 500);
end;
end;
end;
end;
Wait(5000 + Random(1500));
case LogCheck of
'safe': Result:=True;
'time': LogWalk;
'lose': begin
Wait(3000 + Random(1000));
LogWalk;
end;
'bites': begin
Wait(3000 + Random(1000));
LogWalk;
end;
end;
end;============-=-=-=-========================-27/05/2012
I finished all the obstacles now including failsafes. I don't really feel like writing a long story so here some pictures and the code. Also made a video. Pictures non chronological order.. Backwards actually.









I will edit the video soon of the all the functions in action but here is the code:
procedure WaitUntilWalking;
begin
Wait(1000 + Random(1000));
if (IsMoving=True) then
begin
repeat
Wait(100 + Random(100));
until(IsMoving=False);
end;
Wait(500 + Random(500));
end;
// Swinging the rope \\
function RopeFail: Boolean;
var
X, Y, i: Integer;
LadderCl: TPointArray;
LadderClSplit: Array of TPointArray;
begin
Wait(1000 + Random(1000));
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.12, 1.01);
if FindColorsSpiralTolerance(X, Y, LadderCl, 3030082, MSCX-100, MSCY-50, MSCX, MSCY+50, 11) then
begin
SplitTPAExWrap(LadderCl, 1, 1, LadderClSplit);
SortATPASize(LadderClSplit, True);
if Debug then
begin
SMART_DrawDotsEx(False, LadderCl, clYellow); // Ladder
end;
for i:=0 to High(LadderClSplit) do
begin
MiddleTPAEx(LadderClSplit[i], X, Y);
MMouse(X, Y, RandomRange(-2, 2), RandomRange(-2, 2));
if WaitUpTextMulti(['limb', 'up', 'adder', 'Climb', 'Ladder'], 500) then
begin
ClickMouse2(1);
Wait(4000 + Random(1000));
Result:=True;
Break;
end;
end;
end;
end;
function RopeCheck: String;
var
i, t: Integer;
PossibleText: Array of String;
begin
MarkTime(t);
repeat
Wait(50 + Random(50));
until (FindChatBoxText('slip', 8, clBlack)) or (FindChatBoxText('skil', 8, clBlack)) or (FindChatBoxText('used', 8, clBlack)) or (TimeFromMark(t)>2000);
if TimeFromMark(t) < 2000 then
begin
PossibleText := ['slip', 'skil', 'used'];
for i:=0 to 2 do
begin
if FindChatBoxText(PossibleText[i], 8, clBlack) then
Result := PossibleText[i];
end;
end else
Result:='time';
end;
function RopeSwing: Boolean;
var
X, Y, P, i: Integer;
RopeLength: Array[0..1] of Integer;
SwingCl: TPointArray;
SwingClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.12, 0.57);
if FindColorsSpiralTolerance(X, Y, SwingCl, 663074, MSX1, MSY1, MSX2, MSY2, 5) then
begin
SplitTPAExWrap(SwingCl, 1, 1, SwingClSplit);
SortATPASize(SwingClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(SwingClSplit);
SMART_DrawDotsEx(False, SwingCl, clYellow); // Both swings
SMART_DrawBoxes(False, [GetTPABounds(SwingCl)], clAqua); // TPA Box
SMART_DrawBoxes(False, [GetTPABounds(SwingClSplit[0]), GetTPABounds(SwingClSplit[1])], clGreen); // ATPA boxes
SMART_DrawCircle(False, MiddleTPA(SwingClSplit[0]), 2, True, clRed); // Left Swing middle
SMART_DrawCircle(False, MiddleTPA(SwingClSplit[1]), 2, True, clRed); // Right Swing middle
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(SwingClSplit[0]).X1, 3 + GetTPABounds(SwingClSplit[0]).Y1, GetTPABounds(SwingClSplit[0]).X2, GetTPABounds(SwingClSplit[0]).Y1 + (GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1)/10)], clRed); // Box on top of swing #1
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(SwingClSplit[1]).X1, 3 + GetTPABounds(SwingClSplit[1]).Y1, GetTPABounds(SwingClSplit[1]).X2, GetTPABounds(SwingClSplit[1]).Y1 + (GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1)/10)], clRed); // Box on top of swing #2
WriteLn('SwingClSplit[0] length: '+IntToStr(High(SwingClSplit[0]))+'');
WriteLn('SwingClSplit[1] length: '+IntToStr(High(SwingClSplit[1]))+'');
WriteLn('Rope #1 length: '+IntToStr((GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1))+'');
WriteLn('Rope #2 length: '+IntToStr((GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1))+'');
end;
RopeLength[0] := (GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1);
RopeLength[1] := (GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1);
if (RopeLength[0] < 100) and (RopeLength[1] < 100) then
begin
case Random(4) of
0: begin
P := RandomRange(Low(SwingClSplit[0]), High(SwingClSplit[0]));
MMouse(SwingClSplit[0][P].X, SwingClSplit[0][P].Y, 0, 0); // Random spot on rope 1
end;
1: begin
P := RandomRange(Low(SwingClSplit[1]), High(SwingClSplit[1]));
MMouse(SwingClSplit[1][P].X, SwingClSplit[1][P].Y, 0, 0); // Random spot on rope 2
end;
2: Mousebox(GetTPABounds(SwingClSplit[0]).X1, 3 + GetTPABounds(SwingClSplit[0]).Y1, GetTPABounds(SwingClSplit[0]).X2, GetTPABounds(SwingClSplit[0]).Y1 + (GetTPABounds(SwingClSplit[0]).Y2 - GetTPABounds(SwingClSplit[0]).Y1)/10, 2); // Random spot in the box of rope 1
3: Mousebox(GetTPABounds(SwingClSplit[1]).X1, 3 + GetTPABounds(SwingClSplit[1]).Y1, GetTPABounds(SwingClSplit[1]).X2, GetTPABounds(SwingClSplit[1]).Y1 + (GetTPABounds(SwingClSplit[1]).Y2 - GetTPABounds(SwingClSplit[1]).Y1)/10, 2); // Random spot in the box of rope 2
end;
if WaitUpTextMulti(['wing', 'Rope'], 500) then
begin
case Random(7) of
0..4: ClickMouse2(1);
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['wing', 'Rope'], 500);
end;
end;
end;
end else
begin
if (RopeLength[0] > 100) and (RopeLength[1] > 100) then
begin
Wait(2000 + Random(2000));
RopeSwing;
end else
begin
for i:=0 to 1 do
begin
if (RopeLength[i] < 100) then
begin
case Random(2) of
0: begin
P := RandomRange(Low(SwingClSplit[i]), High(SwingClSplit[i]));
MMouse(SwingClSplit[i][P].X, SwingClSplit[i][P].Y, 0, 0); // Random spot on rope 1
end;
1: Mousebox(GetTPABounds(SwingClSplit[i]).X1, 3 + GetTPABounds(SwingClSplit[i]).Y1, GetTPABounds(SwingClSplit[i]).X2, GetTPABounds(SwingClSplit[i]).Y1 + (GetTPABounds(SwingClSplit[i]).Y2 - GetTPABounds(SwingClSplit[i]).Y1)/10, 2); // Random spot in the box of rope 1
end;
if WaitUpTextMulti(['wing', 'Rope'], 500) then
begin
case Random(7) of
0..4: ClickMouse2(1);
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['wing', 'Rope'], 500);
end;
end;
end;
end;
end;
end;
end;
Wait(3000 + Random(1000));
case RopeCheck of
'swing': Result:=True;
'time': RopeSwing;
'slip': begin
if RopeFail then
RopeSwing;
end;
'used': RopeSwing;
end;
end;
end;
// Walking over the log \\
function LogCheck: String;
var
i, t: Integer;
PossibleText: Array of String;
begin
MarkTime(t);
repeat
Wait(50 + Random(50));
until (FindChatBoxText('lose', 8, clBlack)) or (FindChatBoxText('bites', 8, clBlack)) or (FindChatBoxText('safe', 8, clBlack)) or (TimeFromMark(t)>3000);
if TimeFromMark(t) < 3000 then
begin
PossibleText := ['lose', 'bites', 'safe'];
for i:=0 to 2 do
begin
if FindChatBoxText(PossibleText[i], 8, clBlack) then
Result := PossibleText[i];
end;
end else
Result:='time';
end;
function LogWalk: Boolean;
var
X, Y: Integer;
LogCl: TPointArray;
LogClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.15, 0.76);
if FindColorsSpiralTolerance(X, Y, LogCl, 1777965, MSX1, MSY1, MSX2, MSY2, 11) then
begin
SplitTPAExWrap(LogCl, 1, 1, LogClSplit);
SortATPASize(LogClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(LogClSplit);
SMART_DrawDotsEx(False, LogCl, clYellow); // Log
SMART_DrawBoxes(False, [GetTPABounds(LogCl)], clAqua); // TPA Box
SMART_DrawCircle(False, MiddleTPA(LogClSplit[0]), 2, True, clRed); // Middle log
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(LogClSplit[0]).X1, GetTPABounds(LogClSplit[0]).Y1 + 8, GetTPABounds(LogClSplit[0]).X2, GetTPABounds(LogClSplit[0]).Y2 - 4)], clRed); // Box of the log
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(LogClSplit[0]).X2 - 35, GetTPABounds(LogClSplit[0]).Y1 + 8, GetTPABounds(LogClSplit[0]).X2, GetTPABounds(LogClSplit[0]).Y2 - 4)], clPurple); // Box of the clickable part
end;
Mousebox(GetTPABounds(LogClSplit[0]).X2 - 35, GetTPABounds(LogClSplit[0]).Y1 + 8, GetTPABounds(LogClSplit[0]).X2, GetTPABounds(LogClSplit[0]).Y2 - 4, 2);
if WaitUpTextMulti(['alk', 'across'], 500) then
begin
case Random(7) of
0..4: ClickMouse2(1);
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['alk', 'across'], 500);
end;
end;
end;
Wait(5500 + Random(1000));
case LogCheck of
'safe': Result:=True;
'time': LogWalk;
'lose': begin
Wait(3000 + Random(1000));
LogWalk;
end;
'bites': begin
Wait(3000 + Random(1000));
LogWalk;
end;
end;
end;
end;
// Climbing the net \\
function ClimbNet: Boolean;
var
X, Y: Integer;
NetCl: TPointArray;
NetClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.10, 0.58);
if FindColorsSpiralTolerance(X, Y, NetCl, 5204079, MSX1, MSY1, MSX2, MSY2, 7) then
begin
SplitTPAExWrap(NetCl, 3, 3, NetClSplit);
SortATPASize(NetClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(NetClSplit);
SMART_DrawDotsEx(False, NetCl, clYellow); // Net
SMART_DrawBoxes(False, [GetTPABounds(NetCl)], clAqua); // TPA Box
SMART_DrawCircle(False, MiddleTPA(NetClSplit[0]), 2, True, clRed); // Middle net
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(NetClSplit[0]).X1, GetTPABounds(NetClSplit[0]).Y1, GetTPABounds(NetClSplit[0]).X2, GetTPABounds(NetClSplit[0]).Y2)], clRed); // Box of the net
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(NetClSplit[0]).X1, GetTPABounds(NetClSplit[0]).Y1, GetTPABounds(NetClSplit[0]).X2, GetTPABounds(NetClSplit[0]).Y2)], clPurple); // Box of the clickable part
end;
Mousebox(GetTPABounds(NetClSplit[0]).X1, GetTPABounds(NetClSplit[0]).Y1, GetTPABounds(NetClSplit[0]).X2, GetTPABounds(NetClSplit[0]).Y2, 2);
if WaitUpTextMulti(['limb', 'over'], 500) then
begin
case Random(7) of
0..4: ClickMouse2(1);
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['limb', 'over'], 500);
end;
end;
end;
Wait(3250 + Random(750));
Result:=True;
end;
end;
// Walking over the ledge \\
function LedgeCheck: String;
var
i, t: Integer;
PossibleText: Array of String;
begin
MarkTime(t);
repeat
Wait(50 + Random(50));
until (FindChatBoxText('skil', 8, clBlack)) or (FindChatBoxText('slip', 8, clBlack)) or (TimeFromMark(t)>1500);
if TimeFromMark(t) < 3000 then
begin
PossibleText := ['skil', 'slip'];
for i:=0 to 1 do
begin
if FindChatBoxText(PossibleText[i], 8, clBlack) then
Result := PossibleText[i];
end;
end else
Result:='time';
end;
function LedgeFail: Boolean;
var
X, Y: Integer;
NetCl: TPointArray;
NetClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.10, 0.58);
if FindColorsSpiralTolerance(X, Y, NetCl, 5204079, MSX1, MSY1, MSX2, MSY2, 7) then
begin
SplitTPAExWrap(NetCl, 3, 3, NetClSplit);
SortATPASize(NetClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(NetClSplit);
SMART_DrawDotsEx(False, NetCl, clYellow); // Net
SMART_DrawBoxes(False, [GetTPABounds(NetCl)], clAqua); // TPA Box
SMART_DrawCircle(False, MiddleTPA(NetClSplit[0]), 2, True, clRed); // Middle net
end;
MiddleTPAEx(NetClSplit[0], X, Y);
MMouse(X+25, Y, RandomRange(-5, 5), RandomRange(-40, 40));
ClickMouse2(1);
WaitUntilWalking;
Result:=True;
end;
end;
function WalkLedge: Boolean;
var
X, Y: Integer;
LedgeCl: TPointArray;
LedgeClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.15, 0.49);
if FindColorsSpiralTolerance(X, Y, LedgeCl, 1587529, MSCX-200, MSCY-60, MSCX, MSCY, 10) then
begin
SplitTPAExWrap(LedgeCl, 1, 1, LedgeClSplit);
SortATPASize(LedgeClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(LedgeClSplit);
SMART_DrawBoxes(False, [IntToBox(MSCX-200, MSCY-60, MSCX, MSCY)], clWhite); // Search area
SMART_DrawDotsEx(False, LedgeCl, clYellow); // Log
SMART_DrawBoxes(False, [GetTPABounds(LedgeCl)], clAqua); // TPA Box
SMART_DrawCircle(False, MiddleTPA(LedgeClSplit[0]), 2, True, clRed); // Middle net
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(LedgeClSplit[0]).X2 - 25, GetTPABounds(LedgeClSplit[0]).Y1 + 2, GetTPABounds(LedgeClSplit[0]).X2 - 2, GetTPABounds(LedgeClSplit[0]).Y1 + 15)], clRed); // Box of the net
end;
MouseBox(GetTPABounds(LedgeClSplit[0]).X2 - 25, GetTPABounds(LedgeClSplit[0]).Y1 + 2, GetTPABounds(LedgeClSplit[0]).X2 - 2, GetTPABounds(LedgeClSplit[0]).Y1 + 15, 2);
if WaitUpTextMulti(['alk', 'cross'], 500) then
begin
case Random(7) of
0..4: ClickMouse2(1);
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['alk', 'cross'], 500);
end;
end;
end;
Wait(3000 + Random(1000));
case LedgeCheck of
'skil': Result:=True;
'slip': begin
Wait(1500 + Random(1000));
if LedgeFail then
begin
ClimbNet;
WalkLedge;
Result:=True;
end;
end;
'time': WalkLedge;
end;
Wait(1500 + Random(750));
end;
end;
// Climbing the ladder \\
function LadderClimb: Boolean;
var
X, Y, i, Y2: Integer;
X1, Y1, X2: Array[0..1] of Integer;
LadderCl: TPointArray;
LadderClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.14, 0.74);
if FindColorsSpiralTolerance(X, Y, LadderCl, 1520451, MSCX-25, MSCY, MSCX+25, MSCY+50, 7) then
begin
SplitTPAExWrap(LadderCl, 3, 3, LadderClSplit);
SortATPASize(LadderClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(LadderClSplit);
SMART_DrawBoxes(False, [IntToBox(MSCX-25, MSCY, MSCX+25, MSCY+50)], clWhite); // Search area
SMART_DrawDotsEx(False, LadderCl, clYellow); // Ladder
SMART_DrawBoxes(False, [GetTPABounds(LadderCl)], clAqua); // TPA Box
SMART_DrawCircle(False, MiddleTPA(LadderClSplit[0]), 2, True, clRed); // Middle net
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(LadderClSplit[0]).X1, GetTPABounds(LadderClSplit[0]).Y1, GetTPABounds(LadderClSplit[0]).X2, GetTPABounds(LadderClSplit[0]).Y2)], clRed); // Box of the Ladder
end;
for i:=0 to 1 do
begin
X1[i] := GetTPABounds(LadderClSplit[i]).X1;
Y1[i] := GetTPABounds(LadderClSplit[i]).Y1;
X2[i] := GetTPABounds(LadderClSplit[i]).X2;
SortTPAByY(LadderCl, False);
Y2 := LadderCl[i].Y-5;
SortATPASize(LadderClSplit, True);
end;
if Debug then
begin
SMART_DrawBoxes(False, [IntToBox(X1[0], Y1[0], X2[0], Y2)], clPurple); // Left ladder part
SMART_DrawBoxes(False, [IntToBox(X1[1], Y1[1], X2[1], Y2)], clPurple); // Right ladder part
SMART_DrawBoxes(False, [IntToBox(X1[0]+5, Y1[0]+4, X2[1]-5, GetTPABounds(LadderClSplit[1]).Y2+10)], clGreen); // Ladder middle box
end;
case Random(4) of
0: Mousebox(X1[0]+1, Y1[0], X2[0]-1, Y2, 2); // Left ladder part
1: Mousebox(X1[1]+1, Y1[1], X2[1]-1, Y2, 2); // Right ladder part
2..3: Mousebox(X1[0]+5, Y1[0]+4, X2[1]-5, GetTPABounds(LadderClSplit[1]).Y2+10, 2); // Ladder middle box
end;
if WaitUpTextMulti(['limb', 'own'], 500) then
begin
case Random(7) of
0..4: begin
ClickMouse2(1);
Result:=True;
end;
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['limb', 'own'], 500);
Result:=True;
end;
end;
Wait(1500 + Random(1000));
end;
end;
end;
// Climbing wall #1 \\
function ClimbCheck: String;
var
t: Integer;
begin
MarkTime(t);
repeat
Wait(50 + Random(50));
until (FindChatBoxText('low wall', 8, clBlack)) or (TimeFromMark(t)>1500);
if TimeFromMark(t) < 2000 then
begin
Result := 'climbed';
end else
begin
Result:='time';
end;
end;
function ClimbWallI: Boolean;
var
X, Y, P: Integer;
WallCl: TPointArray;
WallClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.15, 0.16);
if FindColorsSpiralTolerance(X, Y, WallCl, 6317675, MSX1, MSY1, MSX2, MSY2, 24) then
begin
SplitTPAExWrap(WallCl, 1, 1, WallClSplit);
SortATPASize(WallClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(WallClSplit);
SMART_DrawDotsEx(False, WallCl, clYellow); // Wall
SMART_DrawBoxes(False, [GetTPABounds(WallCl)], clAqua); // TPA Box
SMART_DrawBoxes(False, [IntToBox(GetTPABounds(WallClSplit[1]).X1, GetTPABounds(WallClSplit[1]).Y1, GetTPABounds(WallClSplit[1]).X2, GetTPABounds(WallClSplit[1]).Y2)], clGreen); // TPA Box of clickable wall
end;
P := RandomRange(Low(WallClSplit[1]), High(WallClSplit[1]));
MMouse(WallClSplit[1][P].X, WallClSplit[1][P].Y, 0, 0); // Random spot on rope 1
if WaitUpTextMulti(['limb', 'own'], 500) then
begin
case Random(7) of
0..4: begin
ClickMouse2(1);
Result:=True;
end;
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['limb', 'own'], 500);
Result:=True;
end;
end;
Wait(3000 + Random(1500));
case ClimbCheck of
'climbed': Result:=True;
'time': ClimbWallI;
end;
Wait(500 + Random(500));
end;
end;
end;
// Climbing wall #2 \\
function ClimbCheckII: String;
var
t: Integer;
begin
MarkTime(t);
repeat
Wait(50 + Random(50));
until (FindChatBoxText('low wall', 7, clBlack)) or (TimeFromMark(t)>1500);
if TimeFromMark(t) < 2000 then
begin
Result := 'climbed';
end else
begin
Result:='time';
end;
end;
function ClimbWallII: Boolean;
var
X, Y: Integer;
WallCl: TPointArray;
WallClSplit: Array of TPointArray;
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.15, 0.16);
if FindColorsSpiralTolerance(X, Y, WallCl, 6317675, MSX1, MSY1, MSX2, MSY2, 24) then
begin
SplitTPAExWrap(WallCl, 1, 1, WallClSplit);
SortATPASize(WallClSplit, True);
if Debug then
begin
SMART_ClearCanvas;
DebugATPABounds(WallClSplit);
SMART_DrawDotsEx(False, WallCl, clYellow); // Wall
SMART_DrawBoxes(False, [GetTPABounds(WallCl)], clAqua); // TPA Box
end;
MiddleTPAEx(WallClSplit[0], X, Y);
if Debug then
begin
SMART_DrawBoxes(False, [IntToBox(X+44, Y-6, X+54, Y+20)], clPurple); // TPA Box
end;
Mousebox(X+44, Y-6, X+54, Y+20, 2);
if WaitUpTextMulti(['limb', 'own'], 500) then
begin
case Random(7) of
0..4: begin
ClickMouse2(1);
Result:=True;
end;
5..6: begin
ClickMouse2(0);
WaitOptionMulti(['limb', 'own'], 500);
Result:=True;
end;
end;
Wait(4000 + Random(2000));
case ClimbCheckII of
'climbed': Result:=True;
'time': ClimbWallI;
end;
Wait(500 + Random(500));
end;
end;
end; Video:
Showing the failsafes and object detection, it's pretty advanced!
www.youtube.com/watch?v=Ql9CswKvMhA
[youtube]Ql9CswKvMhA[/youtube]
18/06/2012
It has been some time since I last worked on this, I'm not really sure why because it is actually really interesting to make. I will be finishing this today. The only thing that needs to be made is a good mainloop. And I need to check out if everything still works.
procedure Mainloop;
var
X, Y, NpcDTM: Integer;
Position: TPoint;
aFound: Extended;
begin
NpcDtm := DTMFromString('mQwAAAHicY2ZgYNjExsCwG4gPALE3EwNDBBB7AfH/r4IMrb2zGKL0ORmUgeokoZgRCQMBAFG5B9E=');
if FindDTMRotated(NpcDTM, X, Y, MMX1, MMY1, MMX2, MMY2, -pi/16, pi/16, pi/64, aFound) then
begin
if Debug then
begin
SMART_ClearCanvas;
SMART_DrawBoxes(False, [IntToBox(X-2, Y-2, X+2, Y+2)], clRed);
end;
Position := Point(X, Y);
WriteLn('Position: '+IntToStr(Position.X)+', '+IntToStr(Position.Y)+'');
end;
FreeDTM(NpcDTM);
end; Returns the position of the DTM and draws a box: Position: 590, 52
To be continued…