The general logic of using GPS is as follows: you once (usually at the beginning of the script) load a map (a database of points with links — a graph) —and then you have the opportunity to move around the world using this map with just one line of code. Instead of huge canvases of code with a sequential call to Engine.MoveTo, you will have only one line of code in the script indicating the final coordinate.
The base of points is a graph - a list of points, some of which are connected, and some are not. Our character will run along it. It looks like this:
It is important to note that in the example below the movement implies only the foot, i.e. You cannot force a character to move from the conditional Dion to Giran using the GK.
uses SysUtils;
function GPS_MoveTo(x, y, z: integer): boolean; overload; // GPS coordinate movement
var dist: single; i: integer;
begin
result:= false;
// first we calculate the route between our current location and the point where we need
// calling this function writes points to GPS.Items, and to dist we assign the length of the constructed route
dist:= GPS.GetPath(User.X, User.Y, User.Z, x, y, z);
if (GPS.Count > 0) then begin // if the route is built then
Print(Format('[GPS] Run to the point (x=%d, y=%d, z=%d), distance: %n m, %d points total', [x, y, z, dist, GPS.Count]));
// for each point of the constructed route...
for i:= 0 to GPS.Count-1 do begin
// check exceptional situations, and if something is interrupted by the movement, you can add your conditions
if (User.Dead) then begin
Print('[GPS] Died while moving...');
exit;
end;
// we try to move to the next point of the route, and if we fail, we can take some measures
if (not Engine.MoveTo(Round(GPS.Items(i).X), Round(GPS.Items(i).Y), Round(GPS.Items(i).Z))) then begin
Print(Format('[GPS] Error when moving to a point #%d (x=%d, y=%d, z=%d)', [i, x, y, z]));
// here you can try to move to the previous point, or use SOE and restart the script
exit;
end;
end;
result:= Engine.MoveTo(x, y, z) or (User.DistTo(x, y, z) < 150);
end else Print('[GPS] Could not find the desired route'); // if the route is not built, then we write about it
end;
function GPS_MoveTo(spot_name: string): boolean; overload; // GPS movement by point name
var dist: single; i, last: integer;
begin
result:= false;
// the only difference between this function and the previous one is only in calling another function to build a route
dist:= GPS.GetPathByName(User.X, User.Y, User.Z, spot_name);
if (GPS.Count > 0) then begin
Print(Format('[GPS] Run to the point <%s>, distance: %d m, %d points total', [spot_name, dist, GPS.Count]));
for i:= 0 to GPS.Count-1 do begin
if (User.Dead) then begin
Print('[GPS] Died while moving...');
exit;
end;
if (not Engine.MoveTo(Round(GPS.Items(i).X), Round(GPS.Items(i).Y), Round(GPS.Items(i).Z))) then begin
Print(Format('[GPS] Error when moving to a point #%d (x=%d, y=%d, z=%d)', [i, GPS.Items(i).X, GPS.Items(i).Y, GPS.Items(i).Z]));
// here you can try to move to the previous point, or use SOE and restart the script
exit;
end;
end;
last:= GPS.Count-1;
result:= Engine.MoveTo(Round(GPS.Items(last).X), Round(GPS.Items(last).Y), Round(GPS.Items(last).Z))
or (User.DistTo(Round(GPS.Items(last).X), Round(GPS.Items(last).Y), Round(GPS.Items(last).Z)) < 150);
end else Print('[GPS] Could not find the desired route');
end;
procedure GPS_LoadMap(path: string); // wrap function for loading GPS maps
var count: integer;
begin
if FileExists(path) then begin
count:= GPS.LoadBase(path);
Print('[GPS] Loaded: '+IntToStr(count)+' points');
end else begin
Print('[GPS] Could not find the map! Stop script');
Print('[GPS] Check its availability: '+path);
Script.Stop;
end;
end;
begin
GPS_LoadMap(ExePath+'\gps_map.db3'); // Load the map during the initialization of the script
// code..
// and further in the code we call the necessary conditions
GPS_MoveTo(-91036, 248044, -3560);
// или
GPS_MoveTo('Elf_Newbie_Helper');
end.