Coh3n
2011-01-17 00:25:30
[INDENT]
Introduction
Hello! :)
I managed to finish this up tonight, and I can honestly say I'm proud at how well it's worked so far. I've automatically generated paths from VE bank to the mine and VE bank to the trees, and so far, they work perfectly. :) If anyone can think of a cool name to call this utility, I will love you forever. :p
Description
This is a scripting utility that automatically generates color walking points based off of reflection tiles. It uses the type that was created from Camaro's TPA walking function. The user simply loads a reflection path (with both endpoints included) and calls the proper procedures.
Specifics
How to use
Conclusion
All forms of feedback is appreciated. If you have any issues, don't be afraid to ask. :) If you're unsure about something, read the comments, I did comment quite a bit. :) If you'd like to test the two paths I've generated, download the attached text file to your includes folder and run the commented ColorWalks in the mainloop.
Enjoy,
Coh3n
[/INDENT]
Introduction
Hello! :)
I managed to finish this up tonight, and I can honestly say I'm proud at how well it's worked so far. I've automatically generated paths from VE bank to the mine and VE bank to the trees, and so far, they work perfectly. :) If anyone can think of a cool name to call this utility, I will love you forever. :p
Description
This is a scripting utility that automatically generates color walking points based off of reflection tiles. It uses the type that was created from Camaro's TPA walking function. The user simply loads a reflection path (with both endpoints included) and calls the proper procedures.
Specifics
- It's very, very simple actually. The most complicated part is generating the RadialWalkTolerance parameters, which is done using cosine law to determine the radials.
- Saves the points generated to a file (WalkPoints.txt) in your includes folder. File path can be changed by changing the constant at the top of the script. File is saved after both paths (to and from the location) have been generated.
- Loads all walk points saved in the file on start up so they can be easily accessed. Newly generated paths will be added to the file (doesn't delete old ones, just continues to add).
- Testing the generated points is easily available with the ColorWalk function.
How to use
- This was written in the assumption that you know how to script, otherwise you may have some trouble with it; however, I still think it's pretty easy.
- Get a reflection path by whatever means available. Set the path in DeclareTilePath(); Make sure you include both end points of the path, other wise you will get an error! What I mean by this is if you're making a path from Varrock East Bank to Varrock East Mine, the first point in your global path will be a tile that's IN the bank, and the last point in your path will be a tile that's IN the mine.
- Call CompletePath(); in the mainloop to generate both the path and it's inverse (both directions). It will Writeln() and save the end result. Comment/uncomment the path/inverse if you only want to generate one way (you'll need to do this if you want the naming to be correct).
- Call ColorWalk(); in the mainloop to test out your generated points. It will walk both directions. The parameters are the start and ending indexes (i.e. the section in the INI file).
Conclusion
All forms of feedback is appreciated. If you have any issues, don't be afraid to ask. :) If you're unsure about something, read the comments, I did comment quite a bit. :) If you'd like to test the two paths I've generated, download the attached text file to your includes folder and run the commented ColorWalks in the mainloop.
Enjoy,
Coh3n
program AutoGenColorWalking;
{$i srl/srl/misc/smart.scar}
{$i srl/srl.scar}
{$i reflection/reflection.simba}
const
MOUSE_TOL_X = 0;
MOUSE_TOL_Y = 0;
PATH_RECORD_WALKPOINT = IncludePath + 'WalkPoints.txt';
PATH_NAME = 'VE Trees to Bank ';
type
TWalkPoint = record
Name : string;
Color : Integer;
Tolerance : Integer;
SortFrom : TPoint;
RWalkParams : TIntegerArray;
end;
TWalkPointArray = array of TWalkPoint;
var
gbl_WalkPoints: array of TWalkPoint;
gbl_TilePath: TPointArray;
procedure DeclareTilePath();
begin
{
// VE Bank to Mine
gbl_TilePath := [
Point(3254, 3421), Point(3265, 3429),
Point(3279, 3429), Point(3288, 3418),
Point(3292, 3406), Point(3292, 3393),
Point(3294, 3381), Point(3288, 3368)
];
}
// VE Bank to Trees
gbl_TilePath := [
Point(3253, 3421), Point(3265, 3428),
Point(3275, 3429), Point(3280, 3439),
Point(3276, 3450)
];
end;
// Converts a string to an integer array; for example, StrToIntArr([1, 2, 3, 4]) will result [1, 2, 3, 4]
function StrToIntArr(Str: string): TIntegerArray;
var
i: Integer;
s: TStringArray;
begin
if (Str = '') then
Exit;
s := Explode(', ', Str);
for i := 0 to High(s) do
try
SetLength(Result, Length(Result) + 1);
Result[High(Result)] := StrToInt(s[i]);
except
end;
end;
function IntArrToStr(Int: TIntegerArray): string;
var
i: Integer;
begin
if (Length(Int) <= 0) then
begin
Result := '';
Exit;
end;
for i := 0 to High(Int) do
if (i = High(Int)) then
Result := Result + IntToStr(Int[i])
else
Result := Result + IntToStr(Int[i]) + ', ';
end;
procedure ClearFile(FilePath: string);
var
f: Integer;
begin
try
f := RewriteFile(FilePath, False);
CloseFile(f);
except
end;
end;
// Loads all the walk points from the WalkPoints.txt file
procedure LoadAllWalkPoints();
var
i: Integer;
begin
if (not FileExists(PATH_RECORD_WALKPOINT)) then
Exit;
SetLength(gbl_WalkPoints, StrToInt(ReadINI('POINT_COUNT', 'PointCount', PATH_RECORD_WALKPOINT)));
for i := 0 to High(gbl_WalkPoints) do
with gbl_WalkPoints[i] do
begin
Name := ReadINI(IntToStr(i), 'Name', PATH_RECORD_WALKPOINT);
Color := StrToInt(ReadINI(IntToStr(i), 'Color', PATH_RECORD_WALKPOINT));
Tolerance := StrToInt(ReadINI(IntToStr(i), 'Tolerance', PATH_RECORD_WALKPOINT));
SortFrom.x := StrToInt(ReadINI(IntToStr(i), 'SortFrom.x', PATH_RECORD_WALKPOINT));
SortFrom.y := StrToInt(ReadINI(IntToStr(i), 'SortFrom.y', PATH_RECORD_WALKPOINT));
RWalkParams := StrToIntArr(ReadINI(IntToStr(i), 'RWalkParams', PATH_RECORD_WALKPOINT));
end;
end;
// Saves all the points to a file
procedure SaveAllWalkPoints();
var
i: Integer;
begin
ClearFile(PATH_RECORD_WALKPOINT);
WriteINI('POINT_COUNT', 'PointCount', IntToStr(Length(gbl_WalkPoints)), PATH_RECORD_WALKPOINT);
for i := 0 to High(gbl_WalkPoints) do
with gbl_WalkPoints[i] do
begin
WriteINI(IntToStr(i), 'Name', Name, PATH_RECORD_WALKPOINT);
WriteINI(IntToStr(i), 'Color', IntToStr(Color), PATH_RECORD_WALKPOINT);
WriteINI(IntToStr(i), 'Tolerance', IntToStr(Tolerance), PATH_RECORD_WALKPOINT);
WriteINI(IntToStr(i), 'SortFrom.x', IntToStr(SortFrom.x), PATH_RECORD_WALKPOINT);
WriteINI(IntToStr(i), 'SortFrom.y', IntToStr(SortFrom.y), PATH_RECORD_WALKPOINT);
WriteINI(IntToStr(i), 'RWalkParams', IntArrToStr(RWalkParams), PATH_RECORD_WALKPOINT);
end;
end;
// Works like DeleteValueInIntArr, except for a TWalkPointArray
// Used to delete the first point in a reflection path as that's where your player is
procedure RemoveIndex(var Arr: TWalkPointArray; Index: Integer);
var
arrLen, i: Integer;
begin
arrLen := High(Arr);
for i := Index to (arrLen - 1) do
Swap(Arr[i], Arr[i + 1]);
SetLength(Arr, arrLen);
end;
// Simple wait for the flag and yes it's supposed to wait until it's completely gone
// it ensures the walk point data is colleted accurately
procedure WaitFlag();
begin
while (WaitFunc(@CharacterMoving, 50, 1500)) do
begin
Wait(100 + Random(50));
if (not FlagPresent) then
Break;
end;
Wait(1000 + Random(500));
end;
// Returns the quadrant the point 'p' is in on the minimap
function GetQuadrant(p: TPoint): Integer;
var
i : Integer;
quadrants: array[1..4] of TBox;
begin
// Initiate the 4 differen quadrants
quadrants[1] := IntToBox(MMCX, MMY1, MMX2, MMCY); // Top Right
quadrants[2] := IntToBox(MMX1, MMY1, MMCX, MMCY); // Top Left
quadrants[3] := IntToBox(MMX1, MMCY, MMCX, MMY2); // Bottom Left
quadrants[4] := IntToBox(MMCX, MMCY, MMX2, MMY2); // Bottom Right
// Get the quadrant the point 'p' is in; set it as 'quad'
for i := 1 to 4 do
if (PointInBox(p, quadrants[i])) then
begin
Result := i;
Break;
end;
end;
// Gets the radial for any point 'p' on the minimap using Cosine Law
function GetRadial(p: TPoint): Integer;
var
sides: array[1..3] of Integer;
radCos: Extended;
begin
sides[1] := 30;
sides[2] := Distance(MMCX, MMCY, p.x, p.y);
sides[3] := Distance(MMCX, MMCY - sides[1], p.x, p.y);
radCos := (Sqr(sides[1]) + Sqr(sides[2]) - Sqr(sides[3])) / (2 * sides[1] * sides[2]);
Result := Round(Degrees(ArcCos(radCos)));
case GetQuadrant(p) of
2, 3: Result := 360 - Result;
1, 4: Result := Result;
end;
Writeln('Radial: ' + IntToStr(Result) + ' degrees');
end;
// Creates the actual TWalkPoint basied on the tile 'Tile'
function GenerateWalkPoint(Tile: TPoint): TWalkPoint;
var
mm_Point: TPoint;
mm_Radial: Integer;
begin
mm_Point := TileToMM(Tile);
if (not rs_OnMinimap(mm_Point.x, mm_Point.y)) then
begin
Writeln('GenerateWalkPoint: Point not on minimap');
Exit;
end;
mm_Radial := GetRadial(Point(mm_Point.x, mm_Point.y));
with Result do
begin
Name := PATH_NAME;
Color := GetColor(mm_Point.x, mm_Point.y);
Tolerance := 20;
SortFrom := Point(mm_Point.x, mm_Point.y);
RWalkParams := [
Color, // Color
mm_Radial - 10, // Start Radial
mm_Radial + 10, // End Radial
Distance(MMCX, MMCY, mm_Point.x, mm_Point.y) + 10, // Radius
RandomRange(-2, 2), // Mod X
RandomRange(-2, 2), // Mod Y
10 // Tolerance
];
// If the start radial is less than 0
if (RWalkParams[1] < 0) then
RWalkParams[1] := 360 + RWalkParams[1];
// If the end radial is greater than 360
if (RWalkParams[2] > 360) then
RWalkParams[2] := RWalkParams[2] - 360;
end;
Writeln('GenerateWalkPoint: Point Generated!');
end;
// Generates a TWalkPointArray based on the reflection path (Tiles)
function GeneratePath(Tiles: TPointArray): TWalkPointArray;
var
i: Integer;
mm_Point: TPoint;
begin
SetLength(Result, Length(Tiles));
for i := 1 to High(Tiles) do
begin
Result[i] := GenerateWalkPoint(Tiles[i]);
Result[i].Name := Result[i].Name + IntToStr(i);
mm_Point := TileToMM(Tiles[i]);
Mouse(mm_Point.x, mm_Point.y, MOUSE_TOL_X, MOUSE_TOL_Y, True);
WaitFlag();
end;
RemoveIndex(Result, 0);
end;
// Prints the path to the debug box
procedure PrintPath(WalkPoints: TWalkPointArray);
var
i: Integer;
begin
Writeln('case Index of');
for i := 0 to High(WalkPoints) do
with WalkPoints[i] do
begin
Writeln(' ' + IntToStr(i) + ':');
Writeln(' with gbl_WalkPoints[Index] do');
Writeln(' begin');
Writeln(' Name := ' + Name + ''''';');
Writeln(' Color := ' + IntToStr(Color) + ';');
Writeln(' Tolerance := ' + IntToStr(Tolerance) + ';');
Writeln(' SortFrom := Point(' + IntToStr(SortFrom.x) + ', ' + IntToStr(SortFrom.y) + ');');
Writeln(' RWalkParams := ' + ToStr(RWalkParams) + ';');
Writeln(' end;');
Writeln('');
end;
Writeln('end;');
end;
// Camaro's TPA function
function GetWalkCoords(WalkPoint: TWalkPoint): TPoint;
var
i, x, y: Integer;
TPA: TPointArray;
begin
Result := Point(-1, -1);
with WalkPoint do
begin
FindColorsSpiralTolerance(MMCX, MMCY, TPA, Color, MMX1, MMY1, MMX2, MMY2, Tolerance);
SortTPAFrom(TPA, SortFrom);
for i := 0 to High(TPA) do
begin
x := TPA[i].x;
y := TPA[i].y;
if (not rs_OnMinimap(x, y)) then
Continue;
Result := Point(x, y);
Break;
end;
end;
end;
// Walks from StartIndex to EndIndex
function ColorWalk(StartIndex, EndIndex: Integer): Boolean;
var
i: Integer;
mm_Point: TPoint;
begin
for i := StartIndex to EndIndex do
begin
mm_Point := GetWalkCoords(gbl_WalkPoints[i]);
if ((mm_Point.x <> -1) and (mm_Point.y <> -1)) then
begin
Mouse(mm_Point.x, mm_Point.y, 3, 3, True);
WaitFlag;
Result := (i = EndIndex);
end else begin
Writeln('Failed to walk to point: ' + IntToStr(i));
if (RadialWalkTolerance(gbl_WalkPoints[i].RWalkParams[0],
gbl_WalkPoints[i].RWalkParams[1],
gbl_WalkPoints[i].RWalkParams[2],
gbl_WalkPoints[i].RWalkParams[3],
gbl_WalkPoints[i].RWalkParams[4],
gbl_WalkPoints[i].RWalkParams[5],
gbl_WalkPoints[i].RWalkParams[6])) then
Result := (i = EndIndex);
end;
end;
end;
// Reverses the TPA so the same reflection path can be used to generate both color paths
// Taken straight from MSI
function MirrorTPA(TPA: TPointArray): TPointArray;
var
i, h: integer;
begin
h := 0;
SetLength(Result, Length(TPA));
for i:= High(TPA) DownTo 0 do
begin
Result[h] := TPA[i];
Inc(h);
end;
end;
// Adds 'Points' to the global array gbl_WalkPoints
procedure AddToGlobal(Points: TWalkPointArray);
var
i: Integer;
begin
for i := 0 to High(Points) do
begin
SetLength(gbl_WalkPoints, Length(gbl_WalkPoints) + 1);
gbl_WalkPoints[High(gbl_WalkPoints)] := Points[i];
end;
end;
// Generates and prints the path/reverse path of the relfection tiles
procedure CompletePath();
begin
AddToGlobal(GeneratePath(gbl_TilePath));
AddToGlobal(GeneratePath(MirrorTPA(gbl_TilePath)));
PrintPath(gbl_WalkPoints);
SaveAllWalkPoints();
end;
begin
Smart_Server := 152;
Smart_Members := False;
Smart_Signed := True;
Smart_SuperDetail := False;
ActivateClient;
SetupSRL;
SetupReflection;
ClearDebug;
DeclareTilePath();
LoadAllWalkPoints();
CompletePath();
//ColorWalk(0, 3); // VE Bank to Trees
//ColorWalk(4, 7); // VE Trees to Bank
end.
[/INDENT]