lordsaturn
2010-09-20 00:18:52
Last updated: 7:21 AM EST Dec 6 2010
program BrimhavenAgility;
{$define smart}
{$i srl/srl.scar}
{$i reflection/reflection.simba}
{$i srl/srl/misc/debug.scar}
procedure SetupPlayers;
begin
NumberOfPlayers(1);
Players[0].Name := '';
Players[0].Pass := '';
Players[0].Active := True;
//Integers[0] = NumTicketsGained;
//Integers[1] = AgiExpGained;
end;
const
Debug = True;
CrapDebug = False; //debug annoying crap
SMART_WORLD = 39;//RECOMMENDED TO SET THIS UP
Save_Stats = True;
Use_Primitive_G_Score = True; //mainly used for testing and gathering unbiased statistics
INI_Path = ScriptPath+'AgilityArenaStats.ini';
TIME_INBETWEEN_PROGGIES = 2; //minutes
/////////////////////////////////////////////////////////////////////////////
//TYPE,CONSTANT,VARIABLE DECLARATION
type //rope, darts, log
obstacle = (Balancing_Ledge, Log_Balance, Rope_Swing, Hand_Holds, Planks,
Pillars, Floor_Spikes, Balancing_Rope, Pressure_Pad, Monkey_Bars, Low_Wall,
Poison_Darts, Spinning_Blade, Blade, None);
obsFunc = function(Tile: TTile): Boolean;
TObstacle = record
Name: obstacle;
level: integer;
exp: integer;
Tile: TTile;
doObstacle: obsFunc;
end;
TNode = record
N, E, S, W: TObstacle;
end;
TColorInfo = record
BestColor: Integer;
ColorArray: TIntegerArray;
HueMod, SatMod: Extended;
BestTolerance: Integer;
MinR, MaxR, MinG, MaxG, MinB, MaxB: Integer;
MinX, MaxX, MinY, MaxY, MinZ, MaxZ: Extended;
MinH, MaxH, MinS, MaxS, MinL, MaxL: Extended;
end;
TStats = record
numPassed, numAttempted: Integer;
totalTime: Integer;
Danger: Integer; //primitive
end;
var
map: array of array of array of TObstacle;
obstacles: array of TObstacle;
autocolors: array of TColorInfo;
bins: array of TStats;
Target_Node: TPoint;
Current_Node: TPoint;
const
DIR_NORTH = 0;
DIR_EAST = 1;
DIR_SOUTH = 2;
DIR_WEST = 3;
const
OBJ_CLIMBING_ROPE_ID = 3610;
ANIM_CLIMBING_ROPE = 828;
OBJ_SWING_ID = 3566;
ANIM_SWING_PASS = 751;
ANIM_SWING_FAIL = 1105;
OBJ_PLANK_FAIL_ID = 3576;
OBJ_PLANK_PASS_ID = 3573; //98% of the time
ANIM_PLANK_FAIL = 768;
OBJ_LOW_WALL_ID = 3565;
ANIM_LOW_WALL_PASS = 1252;
OBJ_BALANCING_ROPE_ID_1 = 3551;//clickable
OBJ_BALANCING_ROPE_ID_2 = 3552;//nonclickable
OBJ_BLADE_STAND_HERE_ID_1 = 35872;
OBJ_BLADE_STAND_HERE_ID_2 = 35873; //type 3
OBJ_BLADE_SAW_UP = 3567; //type 0
OBJ_BLADE_SAW_DOWN_ID_1 = 3568; //type 3
OBJ_BLADE_SAW_DOWN_ID_2 = 3569; //type 3
ANIM_BLADE_FAIL = 2928;
ANIM_LOG_BALANCE_FAIL = 768; //maybe?
ANIM_BALANCING_LEDGE_FAIL = 764;// 753/758 = on/off
OBJ_FLOOR_SPIKES_ID = 3582;
ANIM_FLOOR_SPIKES_PASS = 1115;
ANIM_FLOOR_SPIKES_FAIL = 1114;
OBJ_PILLARS_CLICK_ID = 3578;
ANIM_PILLARS_FAIL = 764;
ANIM_PILLARS_CONTINUE = 741;
OBJ_MONKEY_BARS_CLICK_ID = 3564;
ANIM_MONKEY_BARS_ON = 742;
ANIM_MONKEY_BARS_OFF = 743;
ANIM_MONKEY_BARS_FAIL = 11949;
OBJ_PRESSURE_PAD_ID = 3585;
ANIM_PRESSURE_PAD_PASS = 1115;
ANIM_PRESSURE_PAD_FAIL = 1125;
OBJ_SPINNING_BLADES_ID = 3550;
ANIM_SPINNING_BLADES_PASS = 1115;
ANIM_SPINNING_BLADES_FAIL = 1114;
OBJ_POISON_DARTS_ID = 3550;
ANIM_POISON_DARTS_FAIL = 11942;
ANIM_POISON_DARTS_PASS = 1110;
INV_CAKE_1_ID = 1891; //FULL cake
INV_CAKE_2_ID = 1893; //2/3 cake
INV_CAKE_3_ID = 1895; //1/3 or 'slice of cake'
INV_GOLD_ID = 995;
INV_ARENA_TICKET_ID = 2996;
OBJ_TICKET_DISPENSER_ID = 3608;
OBJ_TICKET_DISPENSER_DARTS_ID = 3581;//also shoots darts
const
nano = -2;
mini = -1;
small = 0;
med = 1;
large = 2;
WAIT_NANO = 100;
WAIT_MINI = 250;
WAIT_SMALL = 350;
WAIT_MED = 700;
WAIT_LARGE = 1050;
TICKET_STATUS_NONE = 3;
TICKET_STATUS_FIRST = 15;
TICKET_STATUS_PENDING = 7;
TICKET_STATUS_GOT_TICKET = 6;
ITEM_TICKET_ID = 2996;
TIME_TO_MOVE = 1500;
BREAK_TIME = 10000;
BREAK_TIME_LONG = 15000;
//times to try each operation
NUM_TRIES = 5;
//time we spend waiting on uptext
OPTION_WAIT_TIME = 300;
OBJ_SEARCH_DISTANCE = 25;
////////////////////////////////////////////////////////////////////////////////
//CONSTRUCTORS
function node(N, E, S, W: obstacle): array of TObstacle;
begin
SetLength(Result, 4);
Result[DIR_NORTH] := obstacles[ord(N)];
Result[DIR_EAST] := obstacles[ord(E)];
Result[DIR_SOUTH] := obstacles[ord(S)];
Result[DIR_WEST] := obstacles[ord(W)];
end;
function obs(Name: obstacle; level, exp: integer; func: obsFunc): TObstacle;
begin
Result.Name := Name;
Result.Level := Level;
Result.Exp := Exp;
Result.doObstacle := func;
Result.Tile := Tile(-1, -1);
end;
////////////////////////////////////////////////////////////////////////////////
//MISC
procedure aDebugTPA(TPA: TPointArray);
begin
if Debug then
DebugTPA(TPA, '');
end;
procedure Write(a: string);
begin
if Debug then
Writeln(a);
end;
procedure CDebug(a: string);
begin
if CrapDebug then
Writeln(a);
end;
function getOrd(a: obstacle): integer;
begin
Result := ord(a);
end;
function GetHP: Integer;
begin
if ValidInterface(748) then
Result := StrToIntDef(GetInterfaceText(748, 8), -1);
end;
{3 red
15 first green
7 green - ticket pending
6 got ticket}
function GetTicketStatus: Integer;
begin
Result := GetSetting(309);
end;
//top floor = floorindex 3
//bottom floor = floorindex 0
function getWait(size: integer): integer;
begin
case size of
nano: Result := WAIT_NANO + Random(WAIT_NANO/(nano+3));
mini: Result := WAIT_MINI + Random(WAIT_MINI/(mini+3));
small: Result := WAIT_SMALL + Random(WAIT_SMALL/(small+3));
med: Result := WAIT_MED + Random(WAIT_MED/(med+3));
large: Result := WAIT_LARGE + Random(WAIT_LARGE/(large+3));
end;
end;
procedure doWait(size: integer);
begin
Wait(getWait(size));
end;
//fixes (exits) when flag gets stuck and when character gets stuck
function WalkTo(Tile: TTile): Boolean;
var
wTile: TPoint;
dist, t, t2: Integer;
begin
Result := False;
wTile := TileToMM(Tile);
if not rs_OnMiniMap(wTile.X, wTile.Y) then
begin
Writeln('Walk to '+ToStr(Tile)+' failed');
Exit;
end;
Mouse(wTile.x, wTile.y, 1, 1, true);
if not WaitToMove(TIME_TO_MOVE) then Exit;
t := GetSystemTime;
while GetSpeed > 0 do //waits for a complete stop
begin
dist := DistanceFromFlag;
if dist > 0 then
begin
t2 := GetSystemTime;
while dist = DistanceFromFlag do
if (GetSystemTime - t) > 2000 then Exit;
end;
end;
Result := (GetSystemTime - t) < 20000;
end;
//GOOD FUCKING IDEA
function WaitTillCameraStopsMoving: Boolean;
var
camX, camY, tmpX, tmpY, a: Integer;
begin
Result := False;
camX := GetCamPosX;
camY := GetCamPosY;
a := GetSystemTime;
while (not(Result)) and (GetSystemTime - a < 20000) do
begin
Wait(50);
tmpX := GetCamPosX;
tmpY := GetCamPosY;
//Writeln('CamX:'+Inttostr(iAbs(tmpX - camX)));
//Writeln('CamY:'+Inttostr(iAbs(tmpY - camY)));
if (iAbs(tmpX - camX) < 30) and (iAbs(tmpY - camY) < 30) then
Result := True
else
begin
camX := tmpX;
camY := tmpY;
end;
end;
end;
//DONT USE THIS IT DOESNT FUCKING WORK!
function SortTilesFrom(TileArr: TTileArray; Tile: TTile): TTileArray;
var
Hi, i: integer;
begin
if Tile.x = -1 then Exit;
Hi := High(TileArr);
SetLength(Result, Hi+1);
for i := 0 to Hi do ;
// QuickTPASort
end;
function SortObjectsFrom(Objects: TRSObjectArray; Tile: TTile): TRSObjectArray;
begin
SetLength(Result, 0);
end;
procedure Eat;
var
Items: TInvItemArray;
Cake: TInvItem;
HP, Timer: Integer;
begin
HP := GetHP;
if (HP > 30) or (HP = -1) then Exit;
if not R_ItemIDExistsEx([INV_CAKE_1_ID, INV_CAKE_2_ID, INV_CAKE_3_ID], Items) then
begin
Writeln('Out of cakes. Terminating');
TerminateScript;
end;
Cake := Items[0];
R_ClickItem(Cake.Slot, True, '');
Timer := GetSystemTime;
while GetSystemTime < Timer + 3000 do
begin
HP := GetHP;
if HP > 30 then Exit;
end;
if (HP <= 30) or (HP = -1) then
begin
Writeln('We somehow failed to heal. Terminating.');
TerminateScript;
end;
end;
////////////////////////////////////////////////////////////////////////////////
//OPTIMAL COLOR METHODS (DYNAMIC)
function GetColorInfo(Colors: TIntegerArray; CTS: integer): TColorInfo;
var
i, Color: Integer;
a, b, c: Integer;
d, e, f: Extended;
begin
if (Length(Colors) < 1) then
Exit;
Result.ColorArray := Colors;
Result.MinR := 500; Result.MaxR := 0;
Result.MinG := 500; Result.MaxG := 0;
Result.MinB := 500; Result.MaxB := 0;
Result.MinH := 500; Result.MaxH := 0;
Result.MinS := 500; Result.MaxS := 0;
Result.MinL := 500; Result.MaxL := 0;
Result.MinX := 500; Result.MaxX := 0;
Result.MinY := 500; Result.MaxY := 0;
Result.MinZ := 500; Result.MaxZ := 0;
for i := 0 to High(Colors) do
begin
Color := Colors[i];
a := (Color and $ff);
b := ((Color and $ff00) shr 8);
c := ((Color and $ff0000) shr 16);
Result.MinR := Min(a, Result.MinR); Result.MaxR := Max(a, Result.MaxR);
Result.MinG := Min(b, Result.MinG); Result.MaxG := Max(b, Result.MaxG);
Result.MinB := Min(c, Result.MinB); Result.MaxB := Max(c, Result.MaxB);
ColorToXYZ(Color, d, e, f);
Result.MinX := MinE(d, Result.MinX); Result.MaxX := MaxE(d, Result.MaxX);
Result.MinY := MinE(e, Result.MinY); Result.MaxY := MaxE(e, Result.MaxY);
Result.MinZ := MinE(f, Result.MinZ); Result.MaxZ := MaxE(f, Result.MaxZ);
ColorToHSL(Color, d, e, f);
Result.MinH := MinE(d, Result.MinH); Result.MaxH := MaxE(d, Result.MaxH);
Result.MinS := MinE(e, Result.MinS); Result.MaxS := MaxE(e, Result.MaxS);
Result.MinL := MinE(f, Result.MinL); Result.MaxL := MaxE(f, Result.MaxL);
end;
case CTS of
0, 1:
begin
a := Ceil((Result.MaxR - Result.MinR) / 2.0);
b := Ceil((Result.MaxG - Result.MinG) / 2.0);
c := Ceil((Result.MaxB - Result.MinB) / 2.0);
Result.BestColor := (a + Result.MinR) + ((b + Result.MinG) shl 8) + ((c + Result.Minb) shl 16);
if (CTS = 0) then
Result.BestTolerance := Max(Max(a, b), c)
else
Result.BestTolerance := Ceil(Sqrt(Sqr(a) + Sqr(b) + Sqr(c)));
end;
2, 3:
begin
d := (Result.MaxH - Result.MinH) / 2.0;
e := (Result.MaxS - Result.MinS) / 2.0;
f := (Result.MaxL - Result.MinL) / 2.0;
Result.BestColor := HSLtoColor(d + Result.MinH, e + Result.MinS, f + Result.MinL);
ColorToHSL(Result.BestColor, d, e, f);
d := MaxE(Abs(Result.MaxH - d), Abs(d - Result.MinH));
e := MaxE(Abs(Result.MaxS - e), Abs(e - Result.MinS));
f := MaxE(Abs(Result.MaxL - f), Abs(f - Result.MinL));
Result.BestTolerance := Ceil(f);
Result.HueMod := d / Max(Result.BestTolerance, 1);
Result.SatMod := e / Max(Result.BestTolerance, 1);
while ((Result.HueMod * Result.BestTolerance) < d) do
Result.HueMod := Result.HueMod + 0.01;
while ((Result.SatMod * Result.BestTolerance) < e) do
Result.SatMod := Result.SatMod + 0.01;
end;
end;
end;
function BestColor(Colors: TIntegerArray): integer;
var
ColorInfo: TColorInfo;
begin
ClearSameIntegers(Colors);
ColorInfo := GetColorInfo(Colors, 1);
Result := ColorInfo.BestColor;
// Result.Tolerance := ColorInfo.BestTolerance;
// Writeln(Result.Color);
// Writeln(Result.Tolerance);
// writeln(colors);
end;
function newColTol(colors: TIntegerArray; CTS: integer): TColorInfo;
begin
ClearSameIntegers(Colors);
Result := GetColorInfo(Colors, CTS);
end;
procedure setNewBestColTol(colors: TIntegerArray; index: integer);
// best: integer;
begin
{algo 1:
best := BestColor(colors);
autocolors[index].Colors := CombineIntArray([best], autocolors[index].Colors);
autocolors[index] := newColTol(autocolors[index].Colors);}
//algo 2
//range check?
Exit; //NOTICE THIS LINE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
autocolors[index] := newColTol(colors, GetToleranceSpeed);
end;
procedure FilterBadPoints(var Pts: TPointArray; var Colors: TIntegerArray; index: integer);
var
tmpColors: TIntegerArray;
tmpPts: TPointArray;
tmpIndex, Hi, i: integer;
H, S, L: Extended;
begin
Hi := High(Colors);
SetLength(tmpColors, Hi+1);
SetLength(tmpPts, Hi+1);
for i := 0 to Hi do
if PointInBox(Pts[i], IntToBox(MSX1, MSY1, MSX2, MSY2))then
begin
tmpColors[tmpIndex] := Colors[i];
tmpPts[tmpIndex] := Pts[i];
Inc(tmpIndex);
end;
SetLength(tmpColors, tmpIndex);
SetLength(tmpPts, tmpIndex);
Pts := tmpPts;
Colors := tmpColors;
Exit; //NOTICE THIS LINE
if (autocolors[index].MaxH = 0) then Exit;
ClearSameIntegersAndTPA(colors, Pts);
Hi := High(Colors);
SetLength(tmpColors, Hi+1);
SetLength(tmpPts, Hi+1);
for i := 0 to Hi do
begin
ColorToHSL(Colors[i], H, S, L);
if (H <= autocolors[index].MaxH) and (H >= autocolors[index].MinH) and
(S <= autocolors[index].MaxS) and (S >= autocolors[index].MinS) and
(L <= autocolors[index].MaxL) and (H >= autocolors[index].MinL) then
begin
tmpPts[tmpIndex] := Pts[i];
tmpColors[tmpIndex] := Colors[i];
Inc(tmpIndex);
end;
end;
Pts := tmpPts;
Colors := tmpColors;
end;
////////////////////////////////////////////////////////////////////////////////
//MOUSE, OPTION, OTHER TPA METHODS
function MyWaitUpTextMulti(Options: TStringArray; Time: integer): Boolean;
begin
Result := WaitUpTextMulti(Options, Time);
if Result then
begin
Wait(120);
Result := IsUpTextMultiCustom(Options);
end;
end;
function R_MyWaitOptionMulti(Options: TStringArray; Time: Integer): Boolean;
var
T: Integer;
begin
Result := False;
T := GetSystemTime + Time;
while (GetSystemTime < T) do
begin
if (R_ChooseOptionMulti(Options)) then
begin
Result := True;
Exit;
end;
//Wait(20 + Random(10));
end;
end;
function R_MyWaitUpTextMulti(Options: TStringArray; Time: Integer): Boolean;
var
T: Integer;
begin
Result := false;
T := GetSystemTime + Time;
while (GetSystemTime < T) do
begin
if (R_IsUpTextMulti(Options)) then
begin
Wait(120);
Result := R_IsUpTextMulti(Options);
Exit;
end;
//Wait(20 + Random(20));
end;
end;
function Clicky(click: TPoint; options: TStringArray): Boolean;
var
x, y: integer;
begin
if (click.x = -1) then Exit;
MMouse(click.x, click.y, 1, 1);
GetMousePos(x, y);
if Random(2) = 1 then
begin
//doWait(nano);
Mouse(x, y, 0, 0, False);
//Result := WaitOptionMulti(options, 1200);
Result := R_MyWaitOptionMulti(options, OPTION_WAIT_TIME);
end else
begin
//Result := MyWaitUpTextMulti(options, 1200);
Result := R_MyWaitUpTextMulti(options, OPTION_WAIT_TIME);
if Result then
Mouse(x, y, 0, 0, True)
else
begin
Mouse(x, y, 0, 0, False);
Result := R_MyWaitOptionMulti(options, OPTION_WAIT_TIME);
end;
end;
end;
function LeftClicky(click: TPoint; options: TStringArray): Boolean;
var
x, y: integer;
begin
if (click.x = -1) then Exit;
MMouse(click.x, click.y, 0, 0);
GetMousePos(x, y);
Result := R_MyWaitUpTextMulti(options, OPTION_WAIT_TIME);
if Result then
Mouse(x, y, 0, 0, True);
end;
function RightClicky(click: TPoint; options: TStringArray): Boolean;
begin
if (click.x = -1) then Exit;
Mouse(click.x, click.y, 0, 0, False);
Result := R_MyWaitOptionMulti(options, OPTION_WAIT_TIME);
end;
function SearchUpText(Pt1, Pt2: TPoint; UpText: TStringArray): Boolean;
var
newX, newY, i, Stops: integer;
newPt, lastPt: TPoint;
begin
Stops := 5;//actually 6
for i := 0 to Stops do
begin
newX := Round(Pt1.x + (Pt2.x-Pt1.x)*i/Stops);
newY := Round(Pt1.y + (Pt2.y-Pt1.y)*i/Stops);
newPt := Point(newX, newY);
if (newPt <> lastPt) then
begin
MMouse(newX, newY, 0, 0);
Result := R_MyWaitUpTextMulti(UpText, OPTION_WAIT_TIME/2);
if Result then
begin
ClickMouse2(True);
Exit;
end;
lastPt := newPt;
end;
end;
end;
function GetBestPoint(P: TPointArray): TPoint;
var
H, i, dist, minDist: integer;
aPoint: TPoint;
begin
aPoint := MiddleTPA(P);
Result := aPoint;
if (not(PointInTPA(Result, P))) then
begin
H := High(P);
for i := 0 to H do
begin
dist := Distance(P[i].x, P[i].y, aPoint.x, aPoint.y);
if (i = 0) or (dist < minDist) then
begin
minDist := Dist;
Result := P[i];
end;
end;
end;
end;
////////////////////////////////////////////////////////////////////////////////
//POSITION FUNCTIONS
function GetProjectedTile(nodeY, nodeX: integer): TTile;
begin
Result := Tile(-1, -1);
if (nodeY < 0) or (nodeY > 4) then Exit;
if (nodeX < 0) or (nodeX > 4) then Exit;
if (map[NodeY][nodeX][DIR_NORTH].Name = None) or
(map[NodeY][nodeX][DIR_NORTH].Name = Hand_Holds) or
(map[NodeY][nodeX][DIR_NORTH].Name = Rope_Swing) then
Result.x := map[nodeY][nodeX][DIR_SOUTH].Tile.x
else
Result.x := map[nodeY][nodeX][DIR_NORTH].Tile.x;
if (map[NodeY][nodeX][DIR_WEST].Name = None) or //only node this will have a problem with is [2,0]
(map[NodeY][nodeX][DIR_WEST].Name = Hand_Holds) or
(map[NodeY][nodeX][DIR_WEST].Name = Rope_Swing) then
Result.y := map[nodeY][nodeX][DIR_EAST].Tile.y
else
begin
Result.y := map[nodeY][nodeX][DIR_WEST].Tile.y;
if (nodeY = 2) and (nodeX = 0) then
Dec(Result.y);
end;
end;
function GetClosestNodeTo(Tile: TTile): TPoint;
var
aTile: TTile;
tmpDist, lowDist, x, y: Integer;
begin
Result := Point(-1, -1);
lowDist := -1;
for y := 0 to 4 do
for x := 0 to 4 do
begin
aTile := GetProjectedTile(y, x);
tmpDist := Distance(Tile.x, Tile.y, aTile.x, aTile.y);
if (tmpDist < lowDist) or (lowDist = -1) then
begin
lowDist := tmpDist;
Result := Point(x, y);
end;
end;
end;
function GetCurrNode: TPoint;
begin
Result := GetClosestNodeTo(GetMyPos);
end;
//MINIMAP MUST BE FACING NORTH
function getTargetNode(currY, currX: Integer): TPoint;
var
Pts: TPointArray;
Hi, i, tmpDist, farDist, Timer: integer;
FurthestPoint: TPoint;
lowDist, x, y, tx, ty, xDev, yDev: integer;
Loc, TheTile: TTile;
aPt: TPoint;
lowDistE, tmpDistE, a, b, c, m, n: Extended;
aTile: TTile;
begin
Result := Point(-1, -1);
//get mm point
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(autocolors[15].HueMod, autocolors[15].SatMod);
Timer := GetSystemTime;
while not
FindColorsPie(Pts, autocolors[15].BestColor, autocolors[15].BestTolerance,
0, 360, 0, 75, MMX1, MMY1, MMX2, MMY2, MMCX, MMCY)
do
begin
if GetSystemTime - Timer > 5000 then
begin
Writeln('Could not find our target.');
Exit;
end;
//Wait(10);
end;
ColorToleranceSpeed(1);
Hi := High(Pts);
for i := 0 to Hi do
begin
tmpDist := Distance(Pts[i].x, Pts[i].y, MMCX, MMCY);
if tmpDist > farDist then
begin
farDist := tmpDist;
FurthestPoint := Pts[i];
end;
end;
//if tile is on mm, get closest using pixels
if (InCircle(FurthestPoint.x, FurthestPoint.y, MMCX, MMCY, 66)) then
begin
for y := -1 to 1 do
for x := -1 to 1 do
begin
aTile := GetProjectedTile(currY+y, currX+x);
aPt := TileToMM(aTile);
if (aPt.x > -1) then
begin
tmpDist := Distance(FurthestPoint.x, FurthestPoint.y, aPt.x, aPt.y);
if (tmpDist < 15) then
begin
Result := Point(currX+x, currY+y);
Exit;
end;
end;
end;
end;
//convert mm point to tile
xDev := (FurthestPoint.x - MMCX)/4;
yDev := (FurthestPoint.y - MMCY)/4;
Loc := GetMyPos;
Loc.x := Loc.x + xDev;
Loc.y := Loc.y - yDev; //runescape y axis is inverted
tx := -11;
for x := -2 to 2 do
for y := -2 to 2 do
begin
aPt := TileToMM(Tile(Loc.x+x, Loc.y+y));
if (aPt.x > -1) then
begin
tmpDist := Distance(aPt.x, aPt.y, FurthestPoint.x, FurthestPoint.y);
if (tmpDist < lowDist) or (lowDist = -1) then
begin
lowDist := tmpDist;
tx := x;
ty := y;
end;
end;
end;
if (tx > -11) then
TheTile := Tile(Loc.x+tx, Loc.y+ty)
else
TheTile := Loc;
//shortest distance from point to line
Loc := GetMyPos;
CDebug(tostr(loc)+'-'+tostr(thetile));
{if (TheTile.y - Loc.y) = 0 then
Slope := 0
else
if (TheTile.x - Loc.x) = 0 then
begin
if (TheTile.y - Loc.y) < 0 then
Slope := -99999999
else
Slope := 99999999;
end else
Slope := (TheTile.y - Loc.y)*1.0/(TheTile.x - Loc.x);
writeln(tostr(TheTile.y - Loc.y)+'/'+tostr(thetile.x-loc.x));
Writeln('slope: '+tostr(slope)); }
// y - y 1 = m(x - x 1 )
//y = Slope*x - Slope*Loc.x + Loc.y;
//http://www.worsleyschool.net/science/files/linepoint/method5.html
//http://bobobobo.wordpress.com/2008/01/07/solving-linear-equations-ax-by-c-0/
{a := Slope;
b := -1;
c := -1*Slope*Loc.x + Loc.y;
write(tostr(a)+';'+tostr(b)+';'+tostr(c));}
a := (TheTile.y - Loc.y);
b := (Loc.x - TheTile.x);
c := (TheTile.x*Loc.y) - Loc.x*TheTile.y;
lowDistE := -1.0;
for y := 0 to 4 do
for x := 0 to 4 do
begin
aTile := GetProjectedTile(y, x);
if (Distance(aTile.x, aTile.y, TheTile.x, TheTile.y) < Distance(aTile.x, aTile.y, Loc.x, Loc.y)) then
begin
m := aTile.x;
n := aTile.y;
tmpDistE := Abs(a*m + b*n + c) / Sqrt(Sqr(a) + Sqr(b));
CDebug(tostr(point(y, x))+':'+tostr(tmpdiste));
if (tmpDistE < lowDistE) or (lowDistE = -1.0) then
begin
lowDistE := tmpDistE;
Result := Point(x, y);
CDebug(ToStr(Result)+'-'+ToStr(aTile));
end;
end;
end;
end;
function GetLocalMMArrowPoint: TPoint;
var
L, a, BigY, i, Hi: Integer;
TPA: TPointArray;
begin
Result := Point(-1, -1);
L := 0;
a := GetSystemTime;
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(0.29, 2.41);
while (L = 0) and (GetSystemTime - a < 1000) do
begin
FindColorsTolerance(TPA, 2641247, MMX1, MMY1, MMX2, MMY2, 2); //outline
L := Length(TPA);
end;
ColorToleranceSpeed(1);
if (L = 0) then
begin
Write('GetLocalMMArrowPoint failed');
Exit;
end;
Hi := High(TPA);
for i := 0 to Hi do
if rs_OnMinimap(TPA[i].x, TPA[i].y) then
if TPA[i].y > BigY then
begin
BigY := TPA[i].y;
Result := TPA[i];
end;
end;
////////////////////////////////////////////////////////////////////////////////
//OBSTACLE FUNCTIONS
//Climb Climbing rope
procedure recover;
var
climbing_rope: TRSObject;
click: TPoint;
a, tries: integer;
Pts: TPointArray;
col, tol: integer;
colors: TIntegerArray;
begin
while (GetAnimation > -1) or (GetSpeed > 0) do ;
doWait(med);
WaitTillCameraStopsMoving;
Eat;
while (not(GetPlaneIndex = 3)) and (tries < NUM_TRIES + 1) do
begin
//get climbing rope object
climbing_rope := GetObjectByID(OBJ_CLIMBING_ROPE_ID, OBJECT_TYPE_INTERACTABLE, OBJ_SEARCH_DISTANCE);
if (climbing_rope.ID <> OBJ_CLIMBING_ROPE_ID) then
begin
Writeln('failed to locate the climbing rope');
end else
begin
//get the MS point to click
click := TileToMS(climbing_rope.Tile, 760);
if (click.x = -1) then
begin
WalkTo(climbing_rope.Tile)
WaitTillCameraStopsMoving;
click := TileToMS(climbing_rope.Tile, 760);
end;
col := autocolors[getOrd(None)].BestColor;
tol := autocolors[getOrd(None)].BestTolerance;
if FindColorsTolerance(Pts, col, click.x-30, click.y-60, click.x+30, click.y+60, tol) then
begin
colors := GetColors(Pts);
FilterBadPoints(Pts, colors, getOrd(None));
click := GetBestPoint(Pts);
aDebugtpa(pts);
end;
//try to click
if (leftClicky(click, ['imb', 'ope'])) then
begin
a := GetSystemTime;
//timeout after 10 seconds
repeat
if (GetPlaneIndex = 3) then
begin
while GetAnimation > -1 do ;
if Length(pts) > 0 then
begin
setNewBestColTol(colors, getOrd(None));
end;
doWait(small);
Exit;
end;
until GetSystemTime - a > BREAK_TIME;
Writeln('failed to climb the rope, timed out');
end;
end;
tries := tries + 1;
end;
if (GetPlaneIndex = 0) then
begin
Writeln('failed to climb the rope '+tostr(NUM_TRIES)+' times, terminating');
TerminateScript;
end;
end;
{ground ground ground
air air air
air air swing- TILE
swing air air
air air air
ground ground ground}
//Swing-on Rope swing
function obsSwing(tile: ttile): Boolean;
var
click: TPoint;
anim, timer, tries: integer;
col, tol: integer;
Pts: TPointArray;
colors: TIntegerArray;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
anim := -1;
// once the rope swing has been used once, the object is erased from the client
// if anyone knows why this happens, PLEASE LET ME KNOW!!!!
//search for obj
{swing := GetObjectByID(OBJ_SWING_ID, OBJECT_TYPE_INTERACTABLE, OBJ_SEARCH_DISTANCE);
if (swing.ID <> OBJ_SWING_ID) then
begin
Writeln('failed to locate the swing');
end else }
begin
//click on obj
click := TileToMS(Tile, 70);
if (click.x = -1) then
begin
WalkTo(Tile);
WaitTillCameraStopsMoving;
doWait(small);
click := TileToMS(Tile, 70);
end;
col := autocolors[getOrd(Rope_Swing)].BestColor;
tol := autocolors[getOrd(Rope_Swing)].BestTolerance;
if FindColorsTolerance(Pts, col, click.x-30, click.y-30, click.x+30, click.y+30, tol) then
begin
colors := GetColors(Pts);
FilterBadPoints(Pts, colors, getOrd(Rope_Swing));
click := GetBestPoint(Pts);
aDebugtpa(pts);
end; //flag-safe
if RightClicky(click, ['wing-on', 'g-on', 'on']) and WaitToMove(TIME_TO_MOVE) then
begin
Inc(bins[GetOrd(Rope_Swing)].numAttempted);
//wait for anim to start
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at swinging, timer 1');
Break;
end;
anim := GetAnimation;
until anim > -1;
//wait for anim to finish
if (anim > -1) then
begin
Result := anim = ANIM_SWING_PASS;
while GetAnimation = anim do ;
doWait(small);
WaitTillCameraStopsMoving;
end;
if Result then
begin
IncEx(bins[GetOrd(Rope_Swing)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Rope_Swing)].numPassed);
end;
//if we failed, restart
if (anim = ANIM_SWING_FAIL) then
begin
recover;
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
//update color
if Length(pts) > 0 then
setNewBestColTol(colors, getOrd(Rope_Swing));
end;
end;
end;
tries := tries + 1;
end;
if Result then
if Length(pts) > 0 then
begin
setNewBestColTol(colors, getOrd(Rope_Swing));
end;
end;
{ground plank
ground plank- TILE
ground plank}
//Walk-on Plank
function obsPlank(tile: ttile): Boolean;
var
click: TPoint;
anim, timer, tries, i, Hi, y: integer;
Plank: TRSObjectArray;
target, loc: TTile;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
anim := -1;
//search for obj
Plank := GetObjectsByID([OBJ_PLANK_FAIL_ID], OBJECT_TYPE_FLOORDECOR, OBJ_SEARCH_DISTANCE);
Hi := High(Plank);
if (Hi < 0) then
begin
Writeln('failed to find a safe plank');
end else
begin
//SortObjectsFrom(Plank, GetMyLoc???????/??????/?//////??);
//get safe plank
for y := Tile.y - 1 to Tile.y + 1 do
begin
Result := True; //for lack of a better variable
for i := 0 to Hi do
if (Plank[i].Tile.y = y) then
Result := False;
if Result then
begin
Target := PointToTile(Point(Tile.x, y));
Break;
end;
end;
Result := False;
//click on obj
click := TileToMS(target, 15);
if (click.x = -1) then
begin
WalkTo(target);
WaitTillCameraStopsMoving;
click := TileToMS(target, 15);
end;
if Clicky(click, ['alk-on', 'k-on', 'on']) and WaitToMove(TIME_TO_MOVE) then
begin
doWait(mini);
Inc(bins[GetOrd(Planks)].numAttempted);
//wait for arr matey to cross the plank arr
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at crossing planks, timer 1');
Break;
end;
anim := GetAnimation;
loc := GetMyPos; //all planks are horizontal, fortunately
Result := iAbs(loc.x-tile.x) = 6;
until (anim > -1) or (Result);
doWait(mini);
WaitTillCameraStopsMoving;
if Result then
begin
IncEx(bins[GetOrd(Planks)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Planks)].numPassed);
end;
if (anim > -1) then
begin
while GetAnimation = anim do ;
doWait(small);
recover;
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
end;
tries := tries + 1;
end;
end;
//first hold - tile
//start: 1117, 1121
//mid: 1118, 1122
//end: 1120, 1124
//fail: 1119, 1123
//Climb-across Hand holds
function obsHolds(tile: ttile): Boolean;
var
click, click2: TPoint;
anim, timer, tries, anim2, i: integer;
Pts: TPointArray;
cols: TIntegerArray;
ATPA: T2DPointArray;
xe, ye: Extended;
begin
doWait(mini);
case Tile of
map[0][2][DIR_EAST].Tile:
begin
xe := 0.6;
ye := 1.0;
end;
map[0][3][DIR_WEST].Tile:
begin
xe := 0.4;
ye := 1.0;
end;
map[2][0][DIR_SOUTH].Tile:
begin
xe := 0.3;
ye := 1.5;
end;
map[3][0][DIR_NORTH].Tile:
begin
xe := 0.3;
ye := 1.0;
end;
map[4][2][DIR_EAST].Tile:
begin
xe := 0.6;
ye := 0.0;
end;
map[4][3][DIR_WEST].Tile:
begin
xe := 0.4;
ye := 0.0;
end;
end;
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
anim := -1;
//click on obj
click := TileToMSEx(Tile, xe, ye, 640);
if (click.x = -1) then
begin
WalkTo(tile);
WaitTillCameraStopsMoving;
click := TileToMSEx(Tile, xe, ye, 640);
end;
//if we cant find the hold using reflection, use color
if (tries > 0) then
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(autocolors[getOrd(Hand_Holds)].HueMod, autocolors[getOrd(Hand_Holds)].SatMod);
if FindColorsTolerance(Pts, autocolors[getOrd(Hand_Holds)].BestColor, click.x-10, click.y-30, click.x+10, click.y+30, autocolors[getOrd(Hand_Holds)].BestTolerance) then
begin
cols := GetColors(Pts);
FilterBadPoints(Pts, cols, getOrd(Hand_Holds));
ATPA := SplitTPA(Pts, 2);
SetLength(Pts, 0);
for i := 0 to High(ATPA) do
if Length(ATPA[i]) > Length(Pts) then
Pts := ATPA[i];
Click2 := GetBestPoint(Pts);
aDebugTPA(pts);
end;
ColorToleranceSpeed(1);
end else
Click2 := click;
if SearchUpText(click2, click, ['limb', 'limb-across', 'b-ac', 'cro', 'oss'])
and WaitToMove(TIME_TO_MOVE) then
begin
//wait for anim
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at crossing hand holds, timer 1');
Break;
end;
anim := GetAnimation;
until (anim > -1);
if (anim > -1) then
begin
Inc(bins[GetOrd(Hand_Holds)].numAttempted);
anim2 := anim;
//get the second animation
while anim2 = anim do
begin
anim2 := GetAnimation;
end;
//wait to finish any animation
while GetAnimation > -1 do ;
//check to see if we pass or fail
Result := (anim2 - anim) = 1; //fail = 2
if Result then
begin
IncEx(bins[GetOrd(Hand_Holds)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Hand_Holds)].numPassed);
end;
//if we failed, recover
if (not(Result)) then
begin
doWait(med);
recover;
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
//update color
if Length(Pts) > 0 then
setNewBestColTol(cols, getOrd(Hand_Holds));
end;
end;
end;
tries := tries + 1;
end;
if Result then
if Length(Pts) > 0 then
setNewBestColTol(cols, getOrd(Hand_Holds));
end;
//ground, wall-tile, wall-tile, ground
//Climb-over Low wall
function obsWall(tile: ttile): Boolean;
var
click, click2: TPoint;
anim, timer, tries: integer;
walls: array of TRSObject;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
anim := -1;
//search for obj
walls := GetObjectsByID([OBJ_LOW_WALL_ID], OBJECT_TYPE_INTERACTABLE, OBJ_SEARCH_DISTANCE);
if (Length(walls) < 2) then
begin
Writeln('failed to find the low wall');
Wait(3000);
end else
begin
//get middle of both wall objects
click := TileToMS(walls[0].Tile, 9);
click2 := TileToMS(Walls[1].Tile, 9);
if (click.x = -1) or (click2.x = -1) then
begin
WalkTo(walls[1].Tile);
WaitTillCameraStopsMoving;
click := TileToMS(walls[0].Tile, 9);
click2 := TileToMS(Walls[1].Tile, 9);
end;
click := MiddleTPA([click, click2]);
//click on obj
if Clicky(click, ['limb', 'limb-over', 'b-o', 'ver']) and WaitToMove(TIME_TO_MOVE) then
begin
//wait to climb
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at climbing low wall, timer 1');
Break;
end;
anim := GetAnimation;
until (anim > -1);
if (anim > -1) then
begin
Inc(bins[GetOrd(Low_Wall)].numAttempted);
while GetAnimation = anim do ;
Result := anim = ANIM_LOW_WALL_PASS;
while GetObjectByID(OBJ_LOW_WALL_ID, OBJECT_TYPE_INTERACTABLE, 5) = NULL_RSOBJECT do
Wait(10);
doWait(small);
if Result then
begin
IncEx(bins[GetOrd(Low_Wall)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Low_Wall)].numPassed);
end;
//never had this happen
if (not(Result)) then
begin
if (GetPlaneIndex = 0) then
Recover;
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
end;
end;
tries := tries + 1;
end;
end;
{rope1 - tile
rope2
rope2}
//Walk-on Balancing rope
function obsBalanceRope(tile: ttile): Boolean;
var
click, click2: TPoint;
timer, tries, i, anim: integer;
rope1, rope2: TRSObject;
Pts: TPointArray;
cols: TIntegerArray;
ATPA: T2DPointArray;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
//search for obj
//rope1 := GetObjectByID(OBJ_BALANCING_ROPE_ID_1, OBJECT_TYPE_FLOORDECOR, OBJ_SEARCH_DISTANCE);
//case of the disappearing object, again.. refer to obsSwing for an explanation
rope1 := NewObject(OBJ_BALANCING_ROPE_ID_1, OBJECT_TYPE_FLOORDECOR, Tile);
rope2 := GetObjectByID(OBJ_BALANCING_ROPE_ID_2, OBJECT_TYPE_FLOORDECOR, OBJ_SEARCH_DISTANCE);
if (rope1.ID <> OBJ_BALANCING_ROPE_ID_1) or (rope2.ID <> OBJ_BALANCING_ROPE_ID_2) then
begin
Writeln('failed to find the balancing rope');
Wait(3000);
end else
begin
//writeln(rope1.Tile);
//writeln(rope2.Tile);
//get middle of both objects
click := TileToMS(rope1.Tile, 9);
click2 := TileToMS(rope2.Tile, 9);
if (click.x = -1) or (click2.x = -1) then
begin
WalkTo(rope2.Tile);
WaitTillCameraStopsMoving;
doWait(med);
click := TileToMS(rope1.Tile, 9);
click2 := TileToMS(rope2.Tile, 9);
end;
//writeln('click b4: '+tostr(click));
//if we cant find the hold using reflection, use color
//if (tries > 0) then
if (click.x > -1) and (click2.x > -1) then
begin
click := MiddleTPA([click, click2]);
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(autocolors[getOrd(Balancing_Rope)].HueMod, autocolors[getOrd(Balancing_Rope)].SatMod);
if FindColorsTolerance(Pts, autocolors[getOrd(Balancing_Rope)].BestColor, click.x-30, click.y-30, click.x+30, click.y+30, autocolors[getOrd(Balancing_Rope)].BestTolerance) then
begin
cols := GetColors(Pts);
//writeln('len b4:'+tostr(length(pts)));
//FilterBadPoints(Pts, cols, getOrd(Balancing_Rope));
//writeln('len after:'+tostr(length(pts)));
ATPA := SplitTPA(Pts, 2);
SetLength(Pts, 0);
for i := 0 to High(ATPA) do
if Length(ATPA[i]) > Length(Pts) then
Pts := ATPA[i];
Click := GetBestPoint(Pts);
aDebugTPA(pts);
end;
ColorToleranceSpeed(1);
end;
//writeln('click after: '+tostr(click));
//click on obj
if (click.x > -1) then
begin
if RightClicky(click, ['alk-on', 'k-on', 'on']) and WaitToMove(TIME_TO_MOVE) then
begin
Inc(bins[GetOrd(Balancing_Rope)].numAttempted);
//wait to move
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at walking balancing rope, timer 1');
Break;
end;
Result := DistanceFrom(Tile) >= 7;
anim := GetAnimation;
until (anim > -1) or Result;
while GetAnimation > -1 do ;
doWait(large);
WaitTillCameraStopsMoving;
Result := DistanceFrom(Tile) >= 7;
if Result then
begin
doWait(mini);
IncEx(bins[GetOrd(Balancing_Rope)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Balancing_Rope)].numPassed);
end;
//assuming failed
if (GetPlaneIndex = 0)then
begin
doWait(small);
recover;
if Length(Pts) > 0 then
setNewBestColTol(cols, getOrd(Balancing_Rope));
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
end;
end;
tries := tries + 1;
end;
if Result then
if Length(Pts) > 0 then
setNewBestColTol(cols, getOrd(Balancing_Rope));
end;
{ground
log - tile
log
log}
//Walk-on Log balance
function obsLog(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries: integer;
colors: TIntegerArray;
TPA: TPointArray;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
click := TileToMS(Tile, 9);
if (click.x = -1) then
begin
WalkTo(Tile);
WaitTillCameraStopsMoving;
click := TileToMS(Tile, 9);
end;
if (tries > 0) then
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(autocolors[getOrd(Log_Balance)].HueMod, autocolors[getOrd(Log_Balance)].SatMod);
if FindColorsTolerance(TPA, autocolors[getOrd(Log_Balance)].BestColor, click.x-30, click.y-30, click.x+30, click.y+30, autocolors[getOrd(Log_Balance)].BestTolerance) then
begin
colors := GetColors(TPA);
FilterBadPoints(TPA, colors, getOrd(Log_Balance));
click := GetBestPoint(TPA);
aDebugtpa(TPA);
end;
ColorToleranceSpeed(1);
end;
if (click.x > -1) and (Clicky(click, ['alk-on', 'k-on', 'on'])) and WaitToMove(TIME_TO_MOVE) then
begin
doWait(small);
Inc(bins[GetOrd(Log_Balance)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at completing log balance obstacle, timer 1');
Break;
end;
until (GetAnimation > -1); //id = 9908
while GetAnimation > -1 do ;
doWait(small);
WaitTillCameraStopsMoving;
Result := DistanceFrom(Tile) >= 6;
if Result then
begin
IncEx(bins[GetOrd(Log_Balance)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Log_Balance)].numPassed);
end;
if GetPlaneIndex = 0 then //assuming failed
begin
Recover;
if Length(TPA) > 0 then
setNewBestColTol(colors, GetOrd(Log_Balance));
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
tries := tries + 1;
end;
if Result and (Length(TPA) > 0) then
setNewBestColTol(colors, GetOrd(Log_Balance));
end;
{ground-tile
saw
saw
ground}
function obsBlade(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, ms, x, y, binTimer: integer;
stand: TRSObject;
//aTile: TTile;
//xDiff, yDiff: Integer;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
if tries > 0 then //will work for this one
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
//search for obj
if (GetMyPos = Tile) then
begin //old getTarget tile
{SetLength(stand, 3);
stand[0] := GetObjectByID(OBJ_BLADE_STAND_HERE_ID_1, OBJECT_TYPE_FLOORDECOR, OBJ_SEARCH_DISTANCE);
stand[1] := GetObjectByID(OBJ_BLADE_STAND_HERE_ID_2, OBJECT_TYPE_FLOORDECOR, OBJ_SEARCH_DISTANCE);
if (stand[0].ID = -1) and (stand[1].ID = -1) then
begin
Writeln('big uh oh in obsBlade, we couldn''t find any objects');
end else
if (stand[0].ID = -1) then
ID := stand[1].ID
else
if (stand[1].ID = -1) then
ID := stand[0].ID
else
begin
//stand[2] := GetObjectByID(OBJ_BLADE_SAW_UP, OBJECT_TYPE_INTERACTABLE, OBJ_SEARCH_DISTANCE)
//if (stand[2].ID = -1) then
// stand[2] := GetObjectByID(OBJ_BLADE_SAW_DOWN_ID_1, OBJECT_TYPE_FLOORDECOR, OBJ_SEARCH_DISTANCE
// sortfrom(^
//if shit goes down use ^
x := DistanceFrom(TileToPoint(stand[0].Tile));
y := DistanceFrom(TileToPoint(stand[1].Tile));
if (x = y) then
begin
Writeln('shit, we have to guess in obsBlade.');
ID := stand[0].ID;
end else
if (x < y) then
ID := stand[0].ID
else
ID := stand[1].ID;
end; }
end else
begin
click := TileToMS(Tile, 9);
if (click.x = -1) then
begin
WalkTo(Tile);
WaitTillCameraStopsMoving;
click := TileToMS(Tile, 9);
end;
Mouse(click.x, click.y, 1, 1, True);
R_Flag;
//WaitTillCameraStopsMoving;
end;
if (not(GetMyPos = Tile)) then
begin
Writeln('Failed to stand in saw spot');
end else
begin
stand := GetObjectByID(OBJ_BLADE_SAW_UP, OBJECT_TYPE_INTERACTABLE, OBJ_SEARCH_DISTANCE);
if (stand.ID = -1) then
stand := GetObjectByID(OBJ_BLADE_SAW_DOWN_ID_1, OBJECT_TYPE_FLOORDECOR, OBJ_SEARCH_DISTANCE);
if (stand.ID = -1) then
begin
Writeln('Failed to find a saw object');
Wait(300);
end else
begin
ms := MouseSpeed;
MouseSpeed := 500;
//get target tile
{aTile := Tile;
xDiff := stand.Tile.x - Tile.x;
yDiff := stand.Tile.y - Tile.y;
for x := 1 to 3 do
begin
aTile.x := aTile.x + xDiff
aTile.y := aTile.y + yDiff;
end; }
//so that if delta = 1, + 3; if delta = 2, + 5
stand.Tile.x := stand.Tile.x + ceil((stand.Tile.x - Tile.x)*2.3);
stand.Tile.y := stand.Tile.y + ceil((stand.Tile.y - Tile.y)*2.3);
click := TileToMS(stand.Tile, 9);
if (click.x = -1) then
begin //half distance
stand.Tile.x := stand.Tile.x - (stand.Tile.x - Tile.x)/2;
stand.Tile.y := stand.Tile.y - (stand.Tile.y - Tile.y)/2;
click := TileToMS(stand.Tile, 9);
end;
Write('blade: from '+tostr(tile)+' to '+tostr(stand.tile));
MMouse(click.x, click.y, 1, 1);
GetMousePos(x, y);
Inc(bins[GetOrd(Blade)].numAttempted);
binTimer := GetSystemTime;
repeat //appear
stand := GetObjectByID(OBJ_BLADE_SAW_UP, OBJECT_TYPE_INTERACTABLE, OBJ_SEARCH_DISTANCE);
until stand.ID > -1;
repeat //disappear
stand := GetInteractableAt(stand.Tile);
until stand.ID = -1;
HoldMouse(x, y, mouse_Left);
Wait(15);
ReleaseMouse(x, y, mouse_Left);
timer := GetSystemTime;
while not IsMoving do
begin
Wait(10);
if (GetSystemTime - timer) > 2000 then
begin
Writeln('failed at completing blade obstacle, timer 1');
Break;
end;
end;
while IsMoving do ;
while GetAnimation > -1 do ;
WaitTillCameraStopsMoving;
Result := DistanceFrom(Tile)>=3;
if Result then
begin
IncEx(bins[GetOrd(Blade)].totalTime, GetSystemTime - binTimer);
Inc(bins[GetOrd(Blade)].numPassed);
end;
Eat;
MouseSpeed := ms;
end;
end;
tries := tries + 1;
end;
end;
{ground, ledge - tile, ledge, ledge,}
//Walk-across Balancing ledge
function obsLedge(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, anim: integer;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
click := TileToMS(Tile, 330);
if (click.x = -1) then
begin
WalkTo(Tile);
WaitTillCameraStopsMoving;
click := TileToMS(Tile, 330);
end;
if (Clicky(click, ['alk-acr', 'k-ac', 'ross', 'os', 'ss'])) and WaitToMove(TIME_TO_MOVE) then
begin
Inc(bins[GetOrd(Balancing_Ledge)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at crossing the balancing ledge, timer 1');
Break;
end;
anim := GetAnimation;
Result := DistanceFrom(Tile) >= 6;
until Result or (anim = ANIM_BALANCING_LEDGE_FAIL);
while GetAnimation > -1 do ;
doWait(small);
if Result then
begin
WaitTillCameraStopsMoving;
IncEx(bins[GetOrd(Balancing_Ledge)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Balancing_Ledge)].numPassed);
end;
if anim = ANIM_BALANCING_LEDGE_FAIL then
begin
doWait(nano);
Recover;
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
tries := tries + 1;
end;
end;
{ground-start
spike
spike
ground-finish-TILE}
function obsSpikes(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, anim: integer;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
Click := TileToMM(RandomizeTile(Tile, 0, 0));
if (Click.x = -1) then
begin
Writeln('Could not pass the floor spikes obstacle');
end else
begin
//WalkToTile(Tile, 0, 0);
Mouse(Click.x, Click.y, 3, 3, True);
if not WaitToMove(TIME_TO_MOVE) then Continue;
Inc(bins[GetOrd(Floor_Spikes)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at crossing the floor spikes, timer 1');
Break;
end;
anim := GetAnimation;
Result := GetMyPos = Tile;
until (Result) or (anim = ANIM_SPINNING_BLADES_FAIL);
while GetAnimation > -1 do ;
doWait(small);
if Result then
begin
WaitTillCameraStopsMoving;
IncEx(bins[GetOrd(Floor_Spikes)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Floor_Spikes)].numPassed);
end;
if anim = ANIM_SPINNING_BLADES_FAIL then
begin
tries := -1;
Eat;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
tries := tries + 1;
end;
end;
{ground
pillar - tile
pillar
pillar}
//Jump-on Pillar
function obsPillars(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, anim: integer;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
click := TileToMS(Tile, 10);
if (click.x = -1) then
begin
WalkTo(Tile);
WaitTillCameraStopsMoving;
click := TileToMS(Tile, 10);
end;
if Clicky(click, ['ump', 'ump-on', 'p-o', 'on']) and WaitToMove(TIME_TO_MOVE) then
begin
doWait(med);
Inc(bins[GetOrd(Pillars)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME_LONG then
begin
Writeln('failed at crossing the pillars, timer 1');
Break;
end;
anim := GetAnimation;
Result := DistanceFrom(Tile) >= 6;
until (Result) or (anim = ANIM_PILLARS_FAIL);
while GetAnimation > -1 do ;
doWait(small);
WaitTillCameraStopsMoving;
Result := DistanceFrom(Tile) >= 6;
if Result then
begin
IncEx(bins[GetOrd(Pillars)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Pillars)].numPassed);
end;
if anim = ANIM_PILLARS_FAIL then
begin
doWait(mini);
Recover;
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
tries := tries + 1;
end;
end;
{ground-start, pad, pad, ground-finish-TILE}
function obsPad(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, anim: integer;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
Click := TileToMM(RandomizeTile(Tile, 0, 0));
if (Click.x = -1) then
begin
Writeln('Could not pass the pressure pad obstacle');
end else
begin
Mouse(Click.x, Click.y, 3, 3, True);
if not WaitToMove(TIME_TO_MOVE) then continue;
Inc(bins[GetOrd(Pressure_Pad)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at crossing the pressure pad, timer 1');
Break;
end;
anim := GetAnimation;
Result := GetMyPos = Tile;
until (Result) or (anim = ANIM_PRESSURE_PAD_FAIL);
while GetAnimation > -1 do ;
doWait(mini);
if Result then
begin
IncEx(bins[GetOrd(Pressure_Pad)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Pressure_Pad)].numPassed);
end;
if anim = ANIM_PRESSURE_PAD_FAIL then
begin
doWait(mini);
tries := -1;
Eat;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
tries := tries + 1;
end;
end;
{bars bars-tile bars
bars
bars}
//Swing-across Monkey bars
function obsBars(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, anim: integer;
obj: TRSObject;
Pts: TPointArray;
Cols: TIntegerArray;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
obj := GetObjectAt(Tile, OBJECT_TYPE_INTERACTABLE);
if (obj.ID <> OBJ_MONKEY_BARS_CLICK_ID) then
begin
Writeln('failed to find the monkey bars');
end else
begin
click := TileToMS(Tile, 900);
if (click.x = -1) then
begin
WalkTo(Tile);
WaitTillCameraStopsMoving;
doWait(small);
click := TileToMS(Tile, 900);
end;
if (click.x > -1) then
begin
ColorToleranceSpeed(2);
SetColorspeed2Modifiers(autocolors[getOrd(Monkey_Bars)].HueMod, autocolors[getOrd(Monkey_Bars)].SatMod);
if FindColorsTolerance(Pts, autocolors[getOrd(Monkey_Bars)].BestColor, click.x-10, click.y-10, click.x+10, click.y+10, autocolors[getOrd(Monkey_Bars)].BestTolerance) then
begin
cols := GetColors(Pts);
FilterBadPoints(Pts, cols, getOrd(Monkey_Bars));
aDebugTPA(pts);
Click := GetBestPoint(Pts);
end;
ColorToleranceSpeed(1);
if RightClicky(click, ['wing', 'ing', 'wing-acro', 'g-a', 'cr', 'os', 'ss']) and WaitToMove(TIME_TO_MOVE) then
begin
Inc(bins[GetOrd(Monkey_Bars)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME_LONG then
begin
Writeln('failed at crossing the monkey bars, timer 1');
Break;
end;
anim := GetAnimation;
Result := DistanceFrom(Tile) >= 8;
until (Result) or (anim = ANIM_MONKEY_BARS_FAIL);
while GetAnimation > -1 do ;
doWait(small);
if Result then
begin
IncEx(bins[GetOrd(Monkey_Bars)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Monkey_Bars)].numPassed);
end;
if anim = ANIM_MONKEY_BARS_FAIL then
begin
Recover;
tries := -1;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
if Length(Pts) > 0 then
setNewBestColTol(Cols, GetOrd(Monkey_Bars));
end;
end;
end;
end;
tries := tries + 1;
end;
if Result then
begin
//doWait(small);
if (Length(Pts) > 0) then
setNewBestColTol(Cols, GetOrd(Monkey_Bars));
end;
end;
{ground-start interact interact ground-finish - TILE}
function obsDarts(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, anim: integer;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
Click := TileToMM(RandomizeTile(Tile, 0, 0));
if (Click.x = -1) then
begin
Writeln('Could not pass the poison darts obstacle');
end else
begin
Mouse(Click.x, Click.y, 3, 3, True);
if not WaitToMove(TIME_TO_MOVE) then continue;
Inc(bins[GetOrd(Poison_Darts)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at crossing the poison darts, timer 1');
Break;
end;
anim := GetAnimation;
Result := GetMyPos = Tile;
until (Result) or (anim = ANIM_POISON_DARTS_FAIL);
while GetAnimation > -1 do ;
doWait(small);
if Result then
begin
WaitTillCameraStopsMoving;
IncEx(bins[GetOrd(Poison_Darts)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Poison_Darts)].numPassed);
end;
if anim = ANIM_POISON_DARTS_FAIL then
begin
tries := -1;
Eat;
if (Target_Node <> getTargetNode(Current_Node.y, Current_Node.x)) or
(R_GetSkillLevel(Skill_Agility) < 40) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
tries := tries + 1;
end;
end;
{ blade
ground-start interact interact interact ground-finish-TILE}
function obsSpinningBlade(Tile: TTile): Boolean;
var
click: TPoint;
timer, tries, anim: integer;
begin
while (not(Result)) and (tries < NUM_TRIES + 1) do
begin
Result := False;
Click := TileToMM(RandomizeTile(Tile, 0, 0));
if (Click.x = -1) then
begin
Writeln('Could not pass the spinning blade obstacle');
end else
begin
//WalkToTile(Tile, 0, 0);
Mouse(Click.x, Click.y, 3, 3, True);
if not WaitToMove(TIME_TO_MOVE) then continue;
Inc(bins[GetOrd(Spinning_Blade)].numAttempted);
timer := GetSystemTime;
repeat
if (GetSystemTime - timer) > BREAK_TIME then
begin
Writeln('failed at crossing the spinning blades, timer 1');
Break;
end;
anim := GetAnimation;
Result := GetMyPos = Tile;
until (Result) or (anim = ANIM_SPINNING_BLADES_FAIL);
write('spnning blade tiles:'+tostr(getmypos)+'~'+tostr(tile));
while GetAnimation > -1 do ;
doWait(small);
if Result then
begin
IncEx(bins[GetOrd(Spinning_Blade)].totalTime, GetSystemTime - timer);
Inc(bins[GetOrd(Spinning_Blade)].numPassed);
end;
if anim = ANIM_SPINNING_BLADES_FAIL then
begin
tries := -1;
Eat;
if Target_Node <> getTargetNode(Current_Node.y, Current_Node.x) then
begin
Current_Node.x := -1;
Result := True;
Exit;
end;
end;
end;
tries := tries + 1;
end;
end;
function obsNone(Tile: TTile): Boolean;
begin
Result := False;
Writeln('This function shouldn''t be called');
Writeln('YOU FUCKED UP');
TerminateScript;
end;
////////////////////////////////////////////////////////////////////////////////
//PATH
function CalculateGScore(obstacle: obstacle): Integer;
var
avgTime, percFail: Extended;
begin
if Use_Primitive_G_Score then
begin
Result := bins[GetOrd(obstacle)].Danger;
Exit;
end;
//numFailed div numAttempted
percFail := (bins[GetOrd(obstacle)].numAttempted-bins[GetOrd(obstacle)].numPassed)*1.0 / bins[GetOrd(obstacle)].numAttempted;
//write('percFail:'+tostr(percfail));
avgTime := bins[GetOrd(obstacle)].totalTime*1.0 / bins[GetOrd(obstacle)].numPassed;
//write('avgTime:'+tostr(Avgtime));
//to seconds
Result := Round((avgTime * (percFail+1.0))); // / 1000);
end;
procedure InvertTIA2(a: TIntegerArray);
var
i, j, L, tmp: Integer;
begin
L := Length(a);
if L < 1 then Exit;
j := L-1;
for i := 0 to L/2 do
begin
tmp := a[i];
a[i] := a[j];
a[j] := tmp;
Dec(j);
end;
end;
function Dijkstra(source, dest: TPoint): TIntegerArray;
var
dist, previous: array[0..4] of array[0..4] of Integer;
y, x, Hi, Index, alt, agi: integer;
Q: TPointArray;
u, v: TPoint;
begin
// Initializations
for y := 0 to 4 do
for x := 0 to 4 do
begin
dist[y][x] := 90000001; // Unknown distance function from source to v
previous[y][x] := -1; // Previous node in optimal path from source
end;
dist[source.y][source.x] := 0; // Distance from source to source
agi := R_GetSkillLevel(Skill_Agility);
// All nodes in the graph are unoptimized - thus are not in Q
Hi := High(Q);
u := source;
while Hi < 24 do // The main loop
begin
if (dist[u.y][u.x] = -1) then
Break;
//writeln(u);
//for each neighbor v of u: where v has not yet been added to Q.
// Relax (u,v,a)
//N
v := Point(u.x, u.y-1);
if (v.y >= 0) and (not(PointInTPA(v, Q))) and
(agi >= map[u.y][u.x][DIR_NORTH].Level) then
begin
alt := dist[u.y][u.x] + CalculateGScore(map[u.y][u.x][DIR_NORTH].Name);
if (alt < dist[v.y][v.x]) then
begin
dist[v.y][v.x] := alt;
previous[v.y][v.x] := DIR_NORTH;
end;
end;
//E
v := Point(u.x+1, u.y);
if (v.x <= 4) and (not(PointInTPA(v, Q))) and
(agi >= map[u.y][u.x][DIR_EAST].Level) then
begin
alt := dist[u.y][u.x] + CalculateGScore(map[u.y][u.x][DIR_EAST].Name);
if (alt < dist[v.y][v.x]) then
begin
dist[v.y][v.x] := alt;
previous[v.y][v.x] := DIR_EAST;
end;
end;
//S
v := Point(u.x, u.y+1);
if (v.y <= 4) and (not(PointInTPA(v, Q))) and
(agi >= map[u.y][u.x][DIR_SOUTH].Level) then
begin
alt := dist[u.y][u.x] + CalculateGScore(map[u.y][u.x][DIR_SOUTH].Name);
if (alt < dist[v.y][v.x]) then
begin
dist[v.y][v.x] := alt;
previous[v.y][v.x] := DIR_SOUTH;
end;
end;
//W
v := Point(u.x-1, u.y);
if (v.x >= 0) and (not(PointInTPA(v, Q))) and
(agi >= map[u.y][u.x][DIR_WEST].Level) then
begin
alt := dist[u.y][u.x] + CalculateGScore(map[u.y][u.x][DIR_WEST].Name);
if (alt < dist[v.y][v.x]) then
begin
dist[v.y][v.x] := alt;
previous[v.y][v.x] := DIR_WEST;
end;
end;
//add u to Q
Inc(Hi);
//if (u = dest) then
//Break;
SetLength(Q, Hi+1);
Q[Hi] := u;
u := Point(-1, -1); //u := vertex not in Q with smallest dist
for x := 0 to 4 do
for y := 0 to 4 do
if not PointInTPA(Point(x, y), Q) then
if (u.x = -1) or (dist[y][x] < dist[u.y][u.x]) then
begin
u := Point(x, y);
end;
end;
u := dest;
SetLength(Result, Hi+1);
Index := 0;
CDebug('distances:'+tostr(dist));
while (previous[u.y][u.x] > -1) do
begin
//writeln('Result['+tostr(index)+'] := '+tostr(previous[u.y][u.x]));
Result[Index] := previous[u.y][u.x];
case Result[index] of
DIR_NORTH: Inc(u.y);
DIR_EAST: Dec(u.x);
DIR_SOUTH: Dec(u.y);
DIR_WEST: Inc(u.x);
end;
Inc(Index);
end;
SetLength(Result, Index);
InvertTIA2(Result);
//another way to think of it
{u := dest;
SetLength(Q, 0);
SetLength(Q, Hi+1);
Index := 0;
while (not(u = source)) do
begin
Q[Index] := previouss[u.y][u.x];
writeln(q[index]);
u := Q[Index];
Inc(Index);
end;
SetLength(Q, Index);
InvertTPA(Q);
Writeln(Q); }
end;
////////////////////////////////////////////////////////////////////////////////
//OBJECTIVE METHODS
//Tag Ticket Dispenser
function GrabTicket: Boolean;
var
Pillar: TRSObjectArray;
OldStatus, Timer: Integer;
Click: TPoint;
begin
Result := False;
Pillar := GetObjectsByID([OBJ_TICKET_DISPENSER_DARTS_ID, OBJ_TICKET_DISPENSER_ID], OBJECT_TYPE_INTERACTABLE, OBJ_SEARCH_DISTANCE);
Click := TileToMS(Pillar[0].Tile, 40);
if (Click.x = -1) then
begin
WalkTo(Pillar[0].Tile);
WaitTillCameraStopsMoving;
Click := TileToMS(Pillar[0].Tile, 40);
end;
OldStatus := GetTicketStatus;
if (OldStatus = TICKET_STATUS_NONE) or (OldStatus = TICKET_STATUS_PENDING) then
begin
Timer := GetSystemTime;
if (Clicky(Click, ['ag', 'Tag'])) then
begin
while GetTicketStatus = OldStatus do
if GetSystemTime - Timer > 4000 then
Exit;
if (GetTicketStatus = TICKET_STATUS_GOT_TICKET) then
begin
Inc(Players[CurrentPlayer].Integers[0]);
Result := True;
end;
end;
end;
end;
///////////////////////////////////////////////////////////////////////////////
//INI/STATS
procedure defaultStats;
begin
SetLength(bins, 14);
//90% success rate, 7 seconds
bins[getOrd(Balancing_Ledge)].numAttempted := 10;
bins[getOrd(Balancing_Ledge)].numPassed := 9;
bins[getOrd(Balancing_Ledge)].totalTime := 63000;
bins[getOrd(Balancing_Ledge)].Danger := 2;
//90% success rate, 7 seconds
bins[getOrd(Log_Balance)].numAttempted := 10;
bins[getOrd(Log_Balance)].numPassed := 9;
bins[getOrd(Log_Balance)].totalTime := 63000;
bins[getOrd(Log_Balance)].Danger := 1;
//60% success rate, 3 seconds
bins[getOrd(Rope_Swing)].numAttempted := 10;
bins[getOrd(Rope_Swing)].numPassed := 6;
bins[getOrd(Rope_Swing)].totalTime := 18000;
bins[getOrd(Rope_Swing)].Danger := 2;
//30% success rate, 8 seconds
bins[getOrd(Hand_Holds)].numAttempted := 10;
bins[getOrd(Hand_Holds)].numPassed := 3;
bins[getOrd(Hand_Holds)].totalTime := 24000;
bins[getOrd(Hand_Holds)].Danger := 4;
//100% success rate, 9 seconds
bins[getOrd(Planks)].numAttempted := 10;
bins[getOrd(Planks)].numPassed := 10;
bins[getOrd(Planks)].totalTime := 90000;
bins[getOrd(Planks)].Danger := 1;
//60% success rate, 9 seconds
bins[getOrd(Pillars)].numAttempted := 10;
bins[getOrd(Pillars)].numPassed := 6;
bins[getOrd(Pillars)].totalTime := 54000;
bins[getOrd(Pillars)].Danger := 2;
//50% success rate, 4 seconds
bins[getOrd(Floor_Spikes)].numAttempted := 10;
bins[getOrd(Floor_Spikes)].numPassed := 5;
bins[getOrd(Floor_Spikes)].totalTime := 20000;
bins[getOrd(Floor_Spikes)].Danger := 2;
//90% success rate, 7 seconds
bins[getOrd(Balancing_Rope)].numAttempted := 10;
bins[getOrd(Balancing_Rope)].numPassed := 9;
bins[getOrd(Balancing_Rope)].totalTime := 63000;
bins[getOrd(Balancing_Rope)].Danger := 1;
//40% success rate, 4 seconds
bins[getOrd(Pressure_Pad)].numAttempted := 10;
bins[getOrd(Pressure_Pad)].numPassed := 4;
bins[getOrd(Pressure_Pad)].totalTime := 16000;
bins[getOrd(Pressure_Pad)].Danger := 2;
//60% success rate, 7 seconds
bins[getOrd(Monkey_Bars)].numAttempted := 10;
bins[getOrd(Monkey_Bars)].numPassed := 6;
bins[getOrd(Monkey_Bars)].totalTime := 42000;
bins[getOrd(Monkey_Bars)].Danger := 1;
//100% success rate, 5 seconds
bins[getOrd(Low_Wall)].numAttempted := 10;
bins[getOrd(Low_Wall)].numPassed := 10;
bins[getOrd(Low_Wall)].totalTime := 50000;
bins[getOrd(Low_Wall)].Danger := 1;
//20% success rate, 3 seconds
bins[getOrd(Poison_Darts)].numAttempted := 10;
bins[getOrd(Poison_Darts)].numPassed := 2;
bins[getOrd(Poison_Darts)].totalTime := 6000;
bins[getOrd(Poison_Darts)].Danger := 4;
//30% success rate, 3 seconds
bins[getOrd(Spinning_Blade)].numAttempted := 10;
bins[getOrd(Spinning_Blade)].numPassed := 3;
bins[getOrd(Spinning_Blade)].totalTime := 9000;
bins[getOrd(Spinning_Blade)].Danger := 3;
//5 seconds, 0% fail
bins[getOrd(Blade)].numAttempted := 10;
bins[getOrd(Blade)].numPassed := 10;
bins[getOrd(Blade)].totalTime := 50000;
bins[getOrd(Blade)].Danger := 1;
end;
procedure _loadStats;
begin
SetLength(bins, 14);
if FileExists(INI_Path) then
begin
bins[getOrd(Balancing_Ledge)].numAttempted := StrToIntDef(ReadINI('Balancing_Ledge', 'numAttempted', INI_Path), 0);
bins[getOrd(Balancing_Ledge)].numPassed := StrToIntDef(ReadINI('Balancing_Ledge', 'numPassed', INI_Path), 0);
bins[getOrd(Balancing_Ledge)].totalTime := StrToIntDef(ReadINI('Balancing_Ledge', 'totalTime', INI_Path), 0);
bins[getOrd(Balancing_Ledge)].Danger := StrToIntDef(ReadINI('Balancing_Ledge', 'Danger', INI_Path), 0);
bins[getOrd(Log_Balance)].numAttempted := StrToIntDef(ReadINI('Log_Balance', 'numAttempted', INI_Path), 0);
bins[getOrd(Log_Balance)].numPassed := StrToIntDef(ReadINI('Log_Balance', 'numPassed', INI_Path), 0);
bins[getOrd(Log_Balance)].totalTime := StrToIntDef(ReadINI('Log_Balance', 'totalTime', INI_Path), 0);
bins[getOrd(Log_Balance)].Danger := StrToIntDef(ReadINI('Log_Balance', 'Danger', INI_Path), 0);
bins[getOrd(Rope_Swing)].numAttempted := StrToIntDef(ReadINI('Rope_Swing', 'numAttempted', INI_Path), 0);
bins[getOrd(Rope_Swing)].numPassed := StrToIntDef(ReadINI('Rope_Swing', 'numPassed', INI_Path), 0);
bins[getOrd(Rope_Swing)].totalTime := StrToIntDef(ReadINI('Rope_Swing', 'totalTime', INI_Path), 0);
bins[getOrd(Rope_Swing)].Danger := StrToIntDef(ReadINI('Rope_Swing', 'Danger', INI_Path), 0);
bins[getOrd(Hand_Holds)].numAttempted := StrToIntDef(ReadINI('Hand_Holds', 'numAttempted', INI_Path), 0);
bins[getOrd(Hand_Holds)].numPassed := StrToIntDef(ReadINI('Hand_Holds', 'numPassed', INI_Path), 0);
bins[getOrd(Hand_Holds)].totalTime := StrToIntDef(ReadINI('Hand_Holds', 'totalTime', INI_Path), 0);
bins[getOrd(Hand_Holds)].Danger := StrToIntDef(ReadINI('Hand_Holds', 'Danger', INI_Path), 0);
bins[getOrd(Planks)].numAttempted := StrToIntDef(ReadINI('Planks', 'numAttempted', INI_Path), 0);
bins[getOrd(Planks)].numPassed := StrToIntDef(ReadINI('Planks', 'numPassed', INI_Path), 0);
bins[getOrd(Planks)].totalTime := StrToIntDef(ReadINI('Planks', 'totalTime', INI_Path), 0);
bins[getOrd(Planks)].Danger := StrToIntDef(ReadINI('Planks', 'Danger', INI_Path), 0);
bins[getOrd(Pillars)].numAttempted := StrToIntDef(ReadINI('Pillars', 'numAttempted', INI_Path), 0);
bins[getOrd(Pillars)].numPassed := StrToIntDef(ReadINI('Pillars', 'numPassed', INI_Path), 0);
bins[getOrd(Pillars)].totalTime := StrToIntDef(ReadINI('Pillars', 'totalTime', INI_Path), 0);
bins[getOrd(Pillars)].Danger := StrToIntDef(ReadINI('Pillars', 'Danger', INI_Path), 0);
bins[getOrd(Floor_Spikes)].numAttempted := StrToIntDef(ReadINI('Floor_Spikes', 'numAttempted', INI_Path), 0);
bins[getOrd(Floor_Spikes)].numPassed := StrToIntDef(ReadINI('Floor_Spikes', 'numPassed', INI_Path), 0);
bins[getOrd(Floor_Spikes)].totalTime :=StrToIntDef(ReadINI('Floor_Spikes', 'totalTime', INI_Path), 0);
bins[getOrd(Floor_Spikes)].Danger := StrToIntDef(ReadINI('Floor_Spikes', 'Danger', INI_Path), 0);
bins[getOrd(Balancing_Rope)].numAttempted := StrToIntDef(ReadINI('Balancing_Rope', 'numAttempted', INI_Path), 0);
bins[getOrd(Balancing_Rope)].numPassed := StrToIntDef(ReadINI('Balancing_Rope', 'numPassed', INI_Path), 0);
bins[getOrd(Balancing_Rope)].totalTime := StrToIntDef(ReadINI('Balancing_Rope', 'totalTime', INI_Path), 0);
bins[getOrd(Balancing_Rope)].Danger := StrToIntDef(ReadINI('Balancing_Rope', 'Danger', INI_Path), 0);
bins[getOrd(Pressure_Pad)].numAttempted := StrToIntDef(ReadINI('Pressure_Pad', 'numAttempted', INI_Path), 0);
bins[getOrd(Pressure_Pad)].numPassed := StrToIntDef(ReadINI('Pressure_Pad', 'numPassed', INI_Path), 0);
bins[getOrd(Pressure_Pad)].totalTime := StrToIntDef(ReadINI('Pressure_Pad', 'totalTime', INI_Path), 0);
bins[getOrd(Pressure_Pad)].Danger := StrToIntDef(ReadINI('Pressure_Pad', 'Danger', INI_Path), 0);
bins[getOrd(Monkey_Bars)].numAttempted := StrToIntDef(ReadINI('Monkey_Bars', 'numAttempted', INI_Path), 0);
bins[getOrd(Monkey_Bars)].numPassed := StrToIntDef(ReadINI('Monkey_Bars', 'numPassed', INI_Path), 0);
bins[getOrd(Monkey_Bars)].totalTime := StrToIntDef(ReadINI('Monkey_Bars', 'totalTime', INI_Path), 0);
bins[getOrd(Monkey_Bars)].Danger := StrToIntDef(ReadINI('Monkey_Bars', 'Danger', INI_Path), 0);
bins[getOrd(Low_Wall)].numAttempted := StrToIntDef(ReadINI('Low_Wall', 'numAttempted', INI_Path), 0);
bins[getOrd(Low_Wall)].numPassed := StrToIntDef(ReadINI('Low_Wall', 'numPassed', INI_Path), 0);
bins[getOrd(Low_Wall)].totalTime := StrToIntDef(ReadINI('Low_Wall', 'totalTime', INI_Path), 0);
bins[getOrd(Low_Wall)].Danger := StrToIntDef(ReadINI('Low_Wall', 'Danger', INI_Path), 0);
bins[getOrd(Poison_Darts)].numAttempted := StrToIntDef(ReadINI('Poison_Darts', 'numAttempted', INI_Path), 0);
bins[getOrd(Poison_Darts)].numPassed := StrToIntDef(ReadINI('Poison_Darts', 'numPassed', INI_Path), 0);
bins[getOrd(Poison_Darts)].totalTime := StrToIntDef(ReadINI('Poison_Darts', 'totalTime', INI_Path), 0);
bins[getOrd(Poison_Darts)].Danger := StrToIntDef(ReadINI('Poison_Darts', 'Danger', INI_Path), 0);
bins[getOrd(Spinning_Blade)].numAttempted := StrToIntDef(ReadINI('Spinning_Blade', 'numAttempted', INI_Path), 0);
bins[getOrd(Spinning_Blade)].numPassed := StrToIntDef(ReadINI('Spinning_Blade', 'numPassed', INI_Path), 0);
bins[getOrd(Spinning_Blade)].totalTime := StrToIntDef(ReadINI('Spinning_Blade', 'totalTime', INI_Path), 0);
bins[getOrd(Spinning_Blade)].Danger := StrToIntDef(ReadINI('Spinning_Blade', 'Danger', INI_Path), 0);
bins[getOrd(Blade)].numAttempted := StrToIntDef(ReadINI('Blade', 'numAttempted', INI_Path), 0);
bins[getOrd(Blade)].numPassed := StrToIntDef(ReadINI('Blade', 'numPassed', INI_Path), 0);
bins[getOrd(Blade)].totalTime := StrToIntDef(ReadINI('Blade', 'totalTime', INI_Path), 0);
bins[getOrd(Blade)].Danger := StrToIntDef(ReadINI('Blade', 'Danger', INI_Path), 0);
end else
defaultStats;
end;
procedure clearStats;
var
i: integer;
begin
for i := 0 to 13 do
begin
bins[i].numAttempted := 0;
bins[i].numPassed := 0;
bins[i].totalTime := 0;
bins[i].Danger := 0;
end;
end;
procedure saveStats;
begin
WriteINI('Balancing_Ledge', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Balancing_Ledge', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Balancing_Ledge', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Balancing_Ledge', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Log_Balance', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Log_Balance', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Log_Balance', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Log_Balance', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Rope_Swing', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Rope_Swing', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Rope_Swing', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Rope_Swing', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Hand_Holds', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Hand_Holds', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Hand_Holds', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Hand_Holds', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Planks', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Planks', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Planks', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Planks', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Pillars', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Pillars', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Pillars', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Pillars', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Floor_Spikes', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Floor_Spikes', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Floor_Spikes', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Floor_Spikes', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Balancing_Rope', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Balancing_Rope', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Balancing_Rope', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Balancing_Rope', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Pressure_Pad', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Pressure_Pad', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Pressure_Pad', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Pressure_Pad', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Monkey_Bars', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Monkey_Bars', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Monkey_Bars', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Monkey_Bars', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Low_Wall', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Low_Wall', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Low_Wall', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Low_Wall', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Poison_Darts', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Poison_Darts', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Poison_Darts', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Poison_Darts', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Spinning_Blade', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Spinning_Blade', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Spinning_Blade', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Spinning_Blade', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
WriteINI('Blade', 'numAttempted', ToStr(bins[getOrd(Balancing_Ledge)].numAttempted), INI_Path);
WriteINI('Blade', 'numPassed', ToStr(bins[getOrd(Balancing_Ledge)].numPassed), INI_Path);
WriteINI('Blade', 'totalTime', ToStr(bins[getOrd(Balancing_Ledge)].totalTime), INI_Path);
WriteINI('Blade', 'Danger', ToStr(bins[getOrd(Balancing_Ledge)].Danger), INI_Path);
end;
////////////////////////////////////////////////////////////////////////////////
//MAIN
procedure _loadMap;
begin
SetLength(map, 5);
SetLength(map[0], 5);
map[0][0] := node(None, Balancing_Ledge, Blade, None);
map[0][1] := node(None, Low_Wall, Pressure_Pad, Balancing_Ledge);
map[0][2] := node(None, Hand_Holds, Balancing_Rope, Low_Wall);
map[0][3] := node(None, Planks, Log_Balance, Hand_Holds);
map[0][4] := node(None, None, Rope_Swing, Planks);
SetLength(map[1], 5);
map[1][0] := node(Blade, Log_Balance, Floor_Spikes, None);
map[1][1] := node(Pressure_Pad, Spinning_Blade, Monkey_Bars, Log_Balance);
map[1][2] := node(Balancing_Rope, Blade, Spinning_Blade, Spinning_Blade);
map[1][3] := node(Log_Balance, Pressure_Pad, Poison_Darts, Blade);
map[1][4] := node(Rope_Swing, None, Pillars, Pressure_Pad); //3608
SetLength(map[2], 5);
map[2][0] := node(Floor_Spikes, Rope_Swing, Hand_Holds, None);
map[2][1] := node(Monkey_Bars, Poison_Darts, Balancing_Rope, Rope_Swing);
map[2][2] := node(Spinning_Blade, Pillars, Low_Wall, Poison_Darts);
map[2][3] := node(Poison_Darts, Floor_Spikes, Monkey_Bars, Pillars);
map[2][4] := node(Pillars, None, Low_Wall, Floor_Spikes); //3608
SetLength(map[3], 5);
map[3][0] := node(Hand_Holds, Planks, Pillars, None);
map[3][1] := node(Balancing_Rope, Spinning_Blade, Floor_Spikes, Planks);
map[3][2] := node(Low_Wall, Poison_Darts, Blade, Spinning_Blade);
map[3][3] := node(Monkey_Bars, Pressure_Pad, Balancing_Rope, Poison_Darts);
map[3][4] := node(Low_Wall, None, Log_Balance, Pressure_Pad); //3608
SetLength(map[4], 5);
map[4][0] := node(Pillars, Balancing_Ledge, None, None);
map[4][1] := node(Floor_Spikes, Monkey_Bars, None, Balancing_Ledge);
map[4][2] := node(Blade, Hand_Holds, None, Monkey_Bars);
map[4][3] := node(Balancing_Rope, Balancing_Ledge, None, Hand_Holds);
map[4][4] := node(Log_Balance, None, None, Balancing_Ledge); //3608
end;
procedure _loadObstacles;
begin
SetLength(obstacles, 15);
obstacles[getOrd(Balancing_Ledge)] := obs(Balancing_Ledge, 1, 16, @obsLedge);
obstacles[getOrd(Log_Balance)] := obs(Log_Balance, 1, 12, @obsLog);
obstacles[getOrd(Rope_Swing)] := obs(Rope_Swing, 1, 20, @obsSwing);
obstacles[getOrd(Hand_Holds)] := obs(Hand_Holds, 20, 22, @obsHolds);
obstacles[getOrd(Planks)] := obs(Planks, 1, 6, @obsPlank);
obstacles[getOrd(Pillars)] := obs(Pillars, 1, 18, @obsPillars);
obstacles[getOrd(Floor_Spikes)] := obs(Floor_Spikes, 20, 24, @obsSpikes);
obstacles[getOrd(Balancing_Rope)] := obs(Balancing_Rope, 1, 10, @obsBalanceRope);
obstacles[getOrd(Pressure_Pad)] := obs(Pressure_Pad, 20, 26, @obsPad);
obstacles[getOrd(Monkey_Bars)] := obs(Monkey_Bars, 1, 14, @obsBars);
obstacles[getOrd(Low_Wall)] := obs(Low_Wall, 1, 8, @obsWall);
obstacles[getOrd(Poison_Darts)] := obs(Poison_Darts, 40, 30, @obsDarts);
obstacles[getOrd(Spinning_Blade)] := obs(Spinning_Blade, 40, 28, @obsSpinningBlade);
obstacles[getOrd(Blade)] := obs(Blade, 1, 0, @obsBlade);
obstacles[getOrd(None)] := obs(None, -1, -1, @obsNone);
end;
procedure _loadAutocolors;
begin
SetLength(autocolors, 16);
autocolors[15].BestColor := 2641247;//outline arrow
autocolors[15].HueMod := 0.29;
autocolors[15].SatMod := 2.41;
autocolors[15].BestTolerance := 2;
autocolors[getOrd(None)].BestColor := 930367; //climbing rope
autocolors[getOrd(None)].BestTolerance := 19;
autocolors[getOrd(Rope_Swing)].BestColor := 795688; //rope swing
autocolors[getOrd(Rope_Swing)].BestTolerance := 13;
autocolors[getOrd(Hand_Holds)].BestColor := 5599103;//holds
autocolors[getOrd(Hand_Holds)].BestTolerance := 6;
autocolors[getOrd(Hand_Holds)].HueMod := 0.08;
autocolors[getOrd(Hand_Holds)].SatMod := 0.13;
autocolors[getOrd(Balancing_Rope)].BestColor := 4808814; //balancing rope
autocolors[getOrd(Balancing_Rope)].BestTolerance := 13;
autocolors[getOrd(Balancing_Rope)].HueMod := 0.06;
autocolors[getOrd(Balancing_Rope)].SatMod := 0.11;
autocolors[getOrd(Log_Balance)].BestColor := 5994633;
autocolors[getOrd(Log_Balance)].BestTolerance := 15;
autocolors[getOrd(Log_Balance)].HueMod := 0.05;
autocolors[getOrd(Log_Balance)].SatMod := 0.19;
autocolors[getOrd(Monkey_Bars)].BestColor := 8161685;
autocolors[getOrd(Monkey_Bars)].BestTolerance := 15;
autocolors[getOrd(Monkey_Bars)].HueMod := 0.09;
autocolors[getOrd(Monkey_Bars)].SatMod := 0.30;
end;
procedure _loadTiles;
begin
//////////////////////////////////////////////////////
//FIRST ROW E->W
map[0][0][DIR_EAST].Tile := Tile(2764, 9590);
map[0][1][DIR_WEST].Tile := Tile(2769, 9590);
map[0][1][DIR_EAST].Tile := Tile(2777, 9590);//obsWall
map[0][2][DIR_WEST].Tile := Tile(2777, 9590);//unused in obsWall, but needed for getprojectedtile
map[0][2][DIR_EAST].Tile := Tile(2785, 9592); //holds, not center
map[0][3][DIR_WEST].Tile := Tile(2792, 9592);
map[0][3][DIR_EAST].Tile := Tile(2797, 9590);
map[0][4][DIR_WEST].Tile := Tile(2802, 9590);
/////////////////////////////////////////////////////
//FIRST ROW S->N
map[0][0][DIR_SOUTH].Tile := Tile(2761, 9586);//saw
map[1][0][DIR_NORTH].Tile := Tile(2761, 9583);
map[0][1][DIR_SOUTH].Tile := Tile(2772, 9583);//obsPad
map[1][1][DIR_NORTH].Tile := Tile(2772, 9586);
map[0][2][DIR_SOUTH].Tile := Tile(2783, 9588);
map[1][2][DIR_NORTH].Tile := Tile(2783, 9581);
map[0][3][DIR_SOUTH].Tile := Tile(2794, 9587);
map[1][3][DIR_NORTH].Tile := Tile(2794, 9582);
map[0][4][DIR_SOUTH].Tile := Tile(2806,9585); //swing, not center
map[1][4][DIR_NORTH].Tile := Tile(2804,9584);
//////////////////////////////////////////////////////
//SECOND ROW E->W
map[1][0][DIR_EAST].Tile := Tile(2764, 9579);
map[1][1][DIR_WEST].Tile := Tile(2769, 9579);
map[1][1][DIR_EAST].Tile := Tile(2780, 9579);//spinning blades
map[1][2][DIR_WEST].Tile := Tile(2776, 9579);
map[1][2][DIR_EAST].Tile := Tile(2787, 9579);
map[1][3][DIR_WEST].Tile := Tile(2790, 9579);
map[1][3][DIR_EAST].Tile := Tile(2801, 9579);//obsPad
map[1][4][DIR_WEST].Tile := Tile(2798, 9579);
////////////////////////////////////////////////////
//SECOND ROW S->N
map[1][0][DIR_SOUTH].Tile := Tile(2761, 9572);
map[2][0][DIR_NORTH].Tile := Tile(2761, 9575);
map[1][1][DIR_SOUTH].Tile := Tile(2772, 9577);
map[2][1][DIR_NORTH].Tile := Tile(2772, 9570);
map[1][2][DIR_SOUTH].Tile := Tile(2783, 9572);//spinning blades
map[2][2][DIR_NORTH].Tile := Tile(2783, 9576);
map[1][3][DIR_SOUTH].Tile := Tile(2794, 9572);//obsDarts
map[2][3][DIR_NORTH].Tile := Tile(2794, 9575);
map[1][4][DIR_SOUTH].Tile := Tile(2805, 9576);
map[2][4][DIR_NORTH].Tile := Tile(2805, 9571);
////////////////////////////////////////////////////
//THIRD ROW E->W
map[2][0][DIR_EAST].Tile := Tile(2766,9569);//swing, not aligned
map[2][1][DIR_WEST].Tile := Tile(2767,9567);
map[2][1][DIR_EAST].Tile := Tile(2779, 9568);//darts
map[2][2][DIR_WEST].Tile := Tile(2776, 9568);
map[2][2][DIR_EAST].Tile := Tile(2786, 9568);
map[2][3][DIR_WEST].Tile := Tile(2791, 9568);
map[2][3][DIR_EAST].Tile := Tile(2801, 9568);//spikes
map[2][4][DIR_WEST].Tile := Tile(2798, 9568);
///////////////////////////////////////////////////
//THIRD ROW S->N
map[2][0][DIR_SOUTH].Tile := Tile(2759, 9566-1);
map[3][0][DIR_NORTH].Tile := Tile(2759, 9559-1);
map[2][1][DIR_SOUTH].Tile := Tile(2772, 9566);
map[3][1][DIR_NORTH].Tile := Tile(2772, 9559);
map[2][2][DIR_SOUTH].Tile := Tile(2783, 9563);//LOW WALL
map[3][2][DIR_NORTH].Tile := Tile(2783, 9562);
map[2][3][DIR_SOUTH].Tile := Tile(2794, 9566);
map[3][3][DIR_NORTH].Tile := Tile(2794, 9559);
map[2][4][DIR_SOUTH].Tile := Tile(2805, 9563);//LOW WALL
map[3][4][DIR_NORTH].Tile := Tile(2805, 9562);
/////////////////////////////////////////////////////
//FOURTH ROW E->W
map[3][0][DIR_EAST].Tile := Tile(2764, 9557);
map[3][1][DIR_WEST].Tile := Tile(2769, 9557);
map[3][1][DIR_EAST].Tile := Tile(2780, 9557);//spinning blade
map[3][2][DIR_WEST].Tile := Tile(2776, 9557);
map[3][2][DIR_EAST].Tile := Tile(2790, 9557);//darts
map[3][3][DIR_WEST].Tile := Tile(2787, 9557);
map[3][3][DIR_EAST].Tile := Tile(2801, 9557);//pressure pad
map[3][4][DIR_WEST].Tile := Tile(2798, 9557);
////////////////////////////////////////////////////////
//FOURTH ROW S->N
map[3][0][DIR_SOUTH].Tile := Tile(2761, 9554);
map[4][0][DIR_NORTH].Tile := Tile(2761, 9549);
map[3][1][DIR_SOUTH].Tile := Tile(2772, 9551);
map[4][1][DIR_NORTH].Tile := Tile(2772, 9553);
map[3][2][DIR_SOUTH].Tile := Tile(2783, 9553);
map[4][2][DIR_NORTH].Tile := Tile(2783, 9550);
map[3][3][DIR_SOUTH].Tile := Tile(2794, 9555);
map[4][3][DIR_NORTH].Tile := Tile(2794, 9548);
map[3][4][DIR_SOUTH].Tile := Tile(2805, 9554);
map[4][4][DIR_NORTH].Tile := Tile(2805, 9549);
//////////////////////////////////////////////////////////
//FIFTH ROW E->W
map[4][0][DIR_EAST].Tile := Tile(2764, 9546);
map[4][1][DIR_WEST].Tile := Tile(2769, 9546);
map[4][1][DIR_EAST].Tile := Tile(2774, 9546);
map[4][2][DIR_WEST].Tile := Tile(2781, 9546);
map[4][2][DIR_EAST].Tile := Tile(2785, 9544);
map[4][3][DIR_WEST].Tile := Tile(2792, 9544);
map[4][3][DIR_EAST].Tile := Tile(2797, 9546);
map[4][4][DIR_WEST].Tile := Tile(2802, 9546);
end;
procedure _Load;
begin
_loadObstacles;
_loadAutocolors;
_loadMap;
_loadTiles;
//_loadStats;
defaultStats;
end;
procedure _Setup;
begin
Smart_Members := True;
Smart_Signed := True;
Smart_Server := SMART_WORLD;
SetupSRL;
SetupPlayers;
SetupReflectionEx(True);
_Load;
MouseSpeed := 40;
ColorToleranceSpeed(1);
AddOnTerminate('Progress');
end;
function isRSReady: Boolean;
begin
Result := RSReady and (GetColor(5, 5) > 0);
end;
procedure Progress;
var
i, Hi, h, m, s: integer;
tph: extended;
begin
Writeln('______________________________________________________');
Writeln(TheTime+' on '+TheDate(Date_Formal));
Writeln('Script ran for '+TimeRunning);
Hi := High(Players);
for i := 0 to Hi do
begin
ConvertTime(Players[i].Worked, h, m, s);
try
tph := Players[i].Integers[0]*1.0/(h*1.0 + m/60.0 + s/60.0/60.0);
// writeln(ToStr(Players[i].Integers[0]*1.0)+'/'+ToStr(h*1.0)+'+'+ToStr(m/60.0)+'+'+tostr(s/60.0/60));
except
tph := -1;
end;
Writeln(Players[i].Name+':'+ToStr(Players[i].Active)+':worked '+MSToTime(Players[i].Worked, Time_Formal)+
':got '+ToStr(Players[i].Integers[0])+' tickets:~'+ToStr(Round(tph))+' TPH:gained '+ToStr(Players[i].Integers[1])+' exp');
end;
Writeln('______________________________________________________');
end;
procedure MainLoop;
var
target, tmp: TPoint;
x, y, i, Hi, a, c, LastReport, ticketStatus, ConsecutiveObstacleFails: Integer;
Path: TIntegerArray;
begin
_Setup;
while not SmartEnabled do ;
while not isRSReady do ;
repeat
LogInPlayer;
Wait(5000);
ClickNorth(True);
SetRun(True);
LastReport := GetSystemTime;
//DECLARE AS X,Y
//ACCESS AS Y,X
tmp := GetCurrNode;
y := tmp.y;
x := tmp.x;
repeat
a := GetSystemTime;
ticketStatus := GetTicketStatus;
if (ticketStatus = TICKET_STATUS_GOT_TICKET) or (ticketStatus = TICKET_STATUS_FIRST) then
begin
while (ticketStatus = TICKET_STATUS_GOT_TICKET) or (ticketStatus = TICKET_STATUS_FIRST) do
begin
Wait(100);
if GetSystemTime - a > 70000 then
begin
Writeln('Something went wrong after getting tickets, continuing anyway..');
Break;
end;
ticketStatus := GetTicketStatus;
end;
Wait(500); //time for arrow to move
end;
Writeln('Starting from: '+tostr(Point(y, x)));
target := getTargetNode(y, x);
if target.x = -1 then
begin
c := c + 1;
if (c = 1) then
begin
Writeln('Failed getting our target node, trying to follow previous path.');
end else
if (c mod 3) = 0 then
begin
Writeln('Failed getting our target node, doing a random obstacle.');
Path := [Random(4)];
while (map[y][x][Path[0]].Name = None) do
Path := [Random(4)];
end else
if c > 15 then
begin
Writeln('Failed getting our target node after 15 tries, terminating.');
TerminateScript;
end else
begin
Writeln('Failed getting our target node, waiting for 5 seconds...');
Wait(5000);
Continue;
end;
end else
begin
c := 0;
Writeln('Going to: '+tostr(point(target.y, target.x)));//look
Path := Dijkstra(Point(x, y), target);
Writeln('Using path: '+tostr(Path));
Writeln('');
end;
if (getTargetNode(y, x) = target) then
begin
Hi := High(Path);
for i := 0 to Hi do
begin
Current_Node := Point(x, y);
Target_Node := target;
Inc(ConsecutiveObstacleFails);
if not map[y][x][Path[i]].doObstacle(map[y][x][Path[i]].Tile) then
begin
tmp := GetCurrNode;
y := tmp.y;
x := tmp.x;
Writeln('Failed obstacle '+ToStr(ConsecutiveObstacleFails)+' time, resetting path to try again');
if ConsecutiveObstacleFails > 5 then
begin
Writeln('Failed obstacle 6 times, setting player to false.');
Players[CurrentPlayer].Active := False;
end;
Break;
end;
if Current_Node.x = -1 then Break;
IncEx(Players[CurrentPlayer].Integers[1], map[y][x][Path[i]].exp);
ConsecutiveObstacleFails := 0;
case Path[i] of
DIR_NORTH: Dec(y);
DIR_EAST: Inc(x);
DIR_SOUTH: Inc(y);
DIR_WEST: Dec(x);
end;
tmp := getTargetNode(y, x);
if (tmp <> target) then
begin
target := tmp;
Break;
end;
end;
end;
tmp := GetLocalMMArrowPoint;
if (tmp.x > -1) and (Distance(tmp.x, tmp.y, MMCX, MMCY) < 35) then
begin
GrabTicket;
end;
//a lot of updates for accurate progress report
Players[CurrentPlayer].Worked := Players[CurrentPlayer].Worked + (GetSystemTime - PlayerStartTime);
PlayerStartTime := GetSystemTime;
if (GetSystemTime - LastReport > 60*1000*TIME_INBETWEEN_PROGGIES) then
begin
Progress;
LastReport := GetSystemTime;
end;
until not Players[CurrentPlayer].Active;
Progress;
Logout;
Inc(CurrentPlayer);
until AllPlayersInactive;
end;
procedure DumpObjects;
var
file1, i, j: integer;
objs: TRSObjectArray;
aTile: TTile;
aPt: TPoint;
begin
file1 := RewriteFile('C:\Users\Tom\Desktop\Simba\Scripts\Brimhaven Agility\debug.txt', true);
for i := 0 to 3 do
begin
objs := GetAllObjects(i);
for j := 0 to high(objs) do
begin
WriteFileString(file1, 'id:'+inttostr(objs[j].ID)+'');
WriteFileString(file1, 'type:'+inttostr(objs[j].objType)+'');
atile := objs[j].Tile;
apt := TileToPoint(atile);
WriteFileString(file1, 'tile:'+inttostr(apt.x)+','+inttostr(apt.y)+'');
WriteFileString(file1, ' ');
end;
end;
CloseFile(file1);
end;
procedure LoopAllObstacles;
var
y, x: integer;
begin
_Setup;
while not isRSReady do ;
LogInPlayer;
Wait(5000);
ClickNorth(True);
//horiz
for y := 4 to 4 do
begin
for x := 0 to 3 do
if not map[y][x][DIR_EAST].doObstacle(map[y][x][DIR_EAST].Tile) then Exit;
for x := 4 downto 1 do
if not map[y][x][DIR_WEST].doObstacle(map[y][x][DIR_WEST].Tile) then Exit;
if (y < 4) then
if not map[y][x][DIR_SOUTH].doObstacle(map[y][x][DIR_SOUTH].Tile) then Exit;
end;
//vert
for x := 0 to 4 do
begin
for y := 4 downto 1 do
if not map[y][x][DIR_NORTH].doObstacle(map[y][x][DIR_NORTH].Tile) then Exit;
for y := 0 to 3 do
if not map[y][x][DIR_SOUTH].doObstacle(map[y][x][DIR_SOUTH].Tile) then Exit;
if (x < 4) then
if not map[y][x][DIR_EAST].doObstacle(map[y][x][DIR_EAST].Tile) then Exit;
end;
end;
begin
MainLoop;
//LoopAllObstacles;
end.