-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsps.simba
336 lines (287 loc) · 8.44 KB
/
sps.simba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
(*
SPS ~ SRL Positioning System
============================
Concept and original work done by marpis @ SRL-Forums.
*)
const
// Path where all the SPS files are
SPS_IMG_PATH = IncludePath + 'SPS\img\';
SPS_IMG_FMT = '.png';
// Supported SPS surfaces
RUNESCAPE_SURFACE = 1;
DUNGEON_ESSENCE_MINE = 2;
DWARVEN_MINE = 3;
type
TSPSSurface = record
Name, ImagePath: string;
Constant: integer;
FactorX, FactorY: integer; // used in SPS_LocalToGlobal
TileOffsetX, TileOffSetY: extended; // used for tile <-> SPS conversions
Tolerance: extended;
end;
// SPS Global variables
var
SPS_Loaded, SPS_Debug, SPS_Continue: boolean;
SPS_Areas: TStringArray;
SPS_Surface: TSPSSurface;
SPS_Worldmap: T4DIntegerArray;
// Should be called in scripts to setup SPS
// Needs to be called each time the surface changes (i.e. from runescape_surface to essence_mine)
procedure SPS_Setup(surface: integer; areas: TStringArray);
begin
SPS_Areas := areas;
case surface of
RUNESCAPE_SURFACE:
with SPS_Surface do
begin
Name := 'Runescape Surface';
ImagePath := SPS_IMG_PATH + 'runescape_surface\';
FactorX := 400;
FactorY := 400;
TileOffsetX := 2045.3;
TileOffSetY := 4159.2;
Tolerance := 0.25;
end;
DUNGEON_ESSENCE_MINE:
with SPS_Surface do
begin
Name := 'Essence Mine';
ImagePath := SPS_IMG_PATH + 'essence_mine\';
FactorX := 400;
FactorY := 1;
TileOffsetX := -1;
TileOffSetY := -1;
Tolerance := 0.5;
end;
DWARVEN_MINE:
with SPS_Surface do
begin
Name := 'Dwarven Mine';
ImagePath := SPS_IMG_PATH + 'dwarven_mine\';
FactorX := 400;
FactorY := 1;
TileOffsetX := -1;
TileOffSetY := -1;
Tolerance := 0.2;
end;
end;
SPS_Surface.Constant := surface;
if (SPS_Debug) then
begin
writeln('[SPS] SPS_Surface: ' + SPS_Surface.Name);
writeln('[SPS] SPS_Areas: ' + toStr(SPS_Areas));
end;
SPS_Loaded := false;
end;
// Gets the map pieces that appear on the minimap
function SPS_GatherMinimap: T3DIntegerArray;
var
bmp: TMufasaBitmap;
c: TClient;
begin
try
bmp := TMufasaBitmap.Create;
bmp.SetSize(100, 100);
c := getTClient;
bmp.CopyClientToBitmap(
c.IOManager, false, 0,0, MMCX-50, MMCY-50, MMCX+50, MMCY+50
);
Result := SPS_BitmapToMap(bmp);
finally
bmp.free;
except
Writeln('[ERROR] GATHERMINIMAP:: '+ExceptionToString(ExceptionType, ExceptionParam));
if (not SPS_Continue) then
begin
ShowMessage('SPS: Access Violation ' + #10+#13+#10+#13+
'Please run Simba as an administrator by right clicking and ' + #10+#13+
'choosing "Run as administrator. You may also have to restart ' + #10+#13+
'Simba a few times. ' + #10+#13+#10+#13+'Sorry for the inconvenience.');
TerminateScript();
end;
end;
end;
procedure SPS_GetAreaCoords(Area: string; var x, y: integer);
var
p: integer;
begin
p := pos('_', Area);
if (p <= 0) then
// raise an exception if Area is of wrong format
RaiseException(erCustomError, 'Invalid Area passed: ' + area);
x := StrToIntDef(copy(Area, 1, p-1), -1);
y := StrToIntDef(copy(Area, p+1, Length(Area)-p), -1);
if (SPS_Debug) then
writeln(format('[SPS] Area coords (%d, %d)', [x, y]));
end;
// Converts a point from a map piece to a point on the entire map
function SPS_LocalToGlobal(Area: string; x, y: integer): TPoint;
var
cx, cy: integer;
begin
SPS_GetAreaCoords(Area, cx, cy);
Result.x := cx * SPS_Surface.FactorX + x;
Result.y := cy * SPS_Surface.FactorY + y;
end;
// Gets SPS ready to be used (this doesn't have to be called in scripts)
procedure SPS_Load;
var
L, i, timer : integer;
img: TMufasaBitmap;
begin
timer := getSystemTime;
L := Length(SPS_Areas);
if (L <= 0) then
begin
writeln('[SPS] WARNING: SPS_Areas hasn''t been set');
exit;
end;
if (SPS_Surface.Name = '') then
begin
writeln('[SPS] WARNING: SPS_Surface isn''t set! Using Runescape Surface as default');
SPS_Setup(RUNESCAPE_SURFACE, SPS_Areas);
end;
// clean up the old one just in case, we do not want copies in wrong places.
SetLength(SPS_WorldMap, 0);
SetLength(SPS_Worldmap, L);
for i := L-1 downto 0 do
begin
try
img := TMufasaBitmap.Create;
img.LoadFromFile(SPS_Surface.ImagePath + SPS_Areas[i] + SPS_IMG_FMT);
SPS_Worldmap[i] := SPS_BitmapToMap(img);
finally
img.free;
except
Writeln('[SPS] ERROR: SPS_Load: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;
if (SPS_Debug) then
Writeln('[SPS] Maps loaded in '+ToStr(getSystemTime - timer)+'ms.');
SPS_Loaded := True;
end;
// Returns the SPS position of the player
function SPS_GetMyPos: TPoint;
var
Minimap: T3DIntegerArray;
t, map: integer;
begin
Result := Point(-1, -1);
if not LoggedIn then
Exit;
if not SPS_Loaded then
SPS_Load;
// we should just rotate the minimap according to the minimap angle.
if (rs_GetCompassAngleDegrees <> 0) then
ClickNorth(True);
t := getSystemTime;
Minimap := SPS_GatherMinimap;
if (High(Minimap) < 0) then
begin
if (SPS_Debug) then
WriteLn('[SPS] Did not gather Minimap.');
Exit;
end;
try
map := SPS_FindMapInMapEx(
Result.X, Result.Y, SPS_Worldmap, Minimap, SPS_Surface.Tolerance
);
if ((Result.X > 0) and (Result.Y > 0)) then
begin
Result := SPS_LocalToGlobal(SPS_Areas[map], Result.X, Result.Y);
end;
if (SPS_Debug) then
writeln(format('[SPS] GetMyPos: Finished in %d ms. Location = %s',
[getSystemTime - t, toStr(result)]));
except
Writeln('[SPS] ERROR' + ExceptionToString(ExceptionType, ExceptionParam));
end;
end;
// Converts an SPS pos to a tile
function SPS_PosToTile(pos: TPoint): TPoint;
begin
result.X := round(SPS_Surface.TileOffsetX + (pos.x / 4));
result.Y := round(SPS_Surface.TileOffsetY - (pos.y / 4));
end;
// Converts a tile to and SPS point, or "pos"
function SPS_TileToPos(tile: TPoint): TPoint;
begin
result.X := round((tile.x - SPS_Surface.TileOffsetX) * 4);
result.Y := round((SPS_Surface.TileOffsetY - tile.y) * 4);
end;
// Converts a tile path to an SPS path
function SPS_TilePathToPos(tiles: TPointArray): TPointArray;
var
i: integer;
begin
setLength(result, length(tiles));
for i := 0 to high(result) do
result[i] := SPS_TileToPos(tiles[i]);
end;
// Finds position P in minimap by checking your own location
function SPS_PosToMM(P: TPoint): TPoint;
var
MyPos: TPoint;
begin
if not LoggedIn then Exit;
Result := Point(-1, -1);
MyPos := SPS_GetMyPos;
if Distance(MyPos.X, MyPos.Y, P.X, P.Y) < 72 then
Result := Point(MMCX + P.X - MyPos.X,
MMCY + P.Y - MyPos.Y);
end;
// Walks to position. If walking paths, please use WalkPath.
function SPS_WalkToPos(P: TPoint): boolean;
var
MM: TPoint;
begin
if not LoggedIn then Exit;
MM := SPS_PosToMM(P);
if (MM.X > 0) then
begin
Mouse(MM.X, MM.Y, 0, 0, True);
if WaitFunc(@IsMoving, 1, 3000 + random(500)) then
while IsMoving do
Flag;
Result := True;
end;
end;
// Returns true if the point "Pt" is on the minimap
function SPS_PosOnMM(Pt: TPoint): Boolean;
var
p: TPoint;
begin
p := SPS_PosToMM(Pt);
Result := rs_OnMinimap(p.x, p.y);
end;
// Walks the path "Path"; always walks to the furthest point possible
function SPS_WalkPath(Path: TPointArray): boolean;
var
I, H, T, D: integer;
P, MM: TPoint;
begin
H := High(Path);
T := GetSystemTime + 20000 + Random(5000);
while (not Result) and (GetSystemTime < T) do
begin
RunEnergy(20);
P := SPS_GetMyPos;
for I := H downto 0 do
begin
MM.X := MMCX + Path[I].X - P.X;
MM.Y := MMCY + Path[I].Y - P.Y;
D := Distance(MM.X, MM.Y, MMCX, MMCY);
if (D < 10) then
break
else begin
if (D < 70) then
begin
MouseFlag(MM.X, MM.Y, 0, 0, Integer(I<>H)*15);
T := getSystemTime + 20000 + Random(1000);
Break;
end;
end;
end;
Result := (I = H);
end;
end;