-
Notifications
You must be signed in to change notification settings - Fork 4
/
OPA.inc
374 lines (303 loc) · 9.1 KB
/
OPA.inc
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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
/*
OnPlayerAirbreak(playerid);
This include is one of the only accurate airbreak detecting
methods developed in SA-MP.
I do not guarantee positive results with this include.
There could be many false flags.
Created by Emmet on Wednesday, November 6, 2013.
Updated by Kar (bug fixes). Last update: February 12th, 2016.
*/
#if defined ac_OnPlayerAirbreak
#endinput
#else
#define ac_OnPlayerAirbreak
#endif
// How many times should airbreak be detected before OnPlayerAirbreak is finally called?
#if !defined MAX_FLAGGED_DETECTIONS
#define MAX_FLAGGED_DETECTIONS 3
#endif
// Maximum distance a player must travel in less than a second before being flagged for airbreak (onfoot).
#if !defined ONFOOT_DISTANCE
#define ONFOOT_DISTANCE 75.0
#endif
// Maximum distance a player must travel in less than a second before being flagged for airbreak (driver).
#if !defined VEHICLE_DISTANCE
#define VEHICLE_DISTANCE 50.0
#endif
static
// Last known coordinates of the player.
Float:s_AirbreakLastCoords[MAX_PLAYERS][3],
// Timestamp used to store the next second in a timestamp.
s_AirbreakUpdateTick[MAX_PLAYERS],
// Timestamp containing the next time to check for airbreak.
s_AirbreakDetectImmunity[MAX_PLAYERS],
// Timestamp containing the last detection.
s_AirbreakLastDetection[MAX_PLAYERS],
// Number of detections in the last 60 seconds.
s_AirbreakDetections[MAX_PLAYERS]
;
forward OnPlayerAirbreak(playerid);
static AB_IsVehicleMoving(vehicleid)
{
new
Float:x,
Float:y,
Float:z;
GetVehicleVelocity(vehicleid, x, y, z);
return (!(floatabs(x) <= 0.001 && floatabs(y) <= 0.001 && floatabs(z) <= 0.005));
}
static AB_OnAirbreakDetected(playerid)
{
// Called when the player is presumably airbreaking.
// If the amount of detections exceeds MAX_FLAGGED_DETECTIONS, they are most likely airbreaking.
new
timestamp = gettime();
if((++ s_AirbreakDetections[playerid]) >= MAX_FLAGGED_DETECTIONS && (timestamp - s_AirbreakLastDetection[playerid]) < 60)
{
CallLocalFunction("OnPlayerAirbreak", "i", playerid);
}
s_AirbreakLastDetection[playerid] = timestamp;
}
public OnFilterScriptInit()
{
for(new i = 0; i < MAX_PLAYERS; i ++)
{
if(IsPlayerConnected(i) && GetPlayerState(i) == PLAYER_STATE_ONFOOT)
{
s_AirbreakDetectImmunity[i] = gettime() + 3;
s_AirbreakUpdateTick[i] = gettime();
}
}
#if defined AB_OnFilterScriptInit
return AB_OnFilterScriptInit();
#else
return 1;
#endif
}
public OnPlayerConnect(playerid)
{
s_AirbreakDetections[playerid] = 0;
s_AirbreakLastDetection[playerid] = 0;
s_AirbreakDetectImmunity[playerid] = 0;
s_AirbreakUpdateTick[playerid] = gettime();
#if defined AB_OnPlayerConnect
return AB_OnPlayerConnect(playerid);
#else
return 1;
#endif
}
public OnPlayerSpawn(playerid)
{
s_AirbreakDetectImmunity[playerid] = gettime() + 3;
GetPlayerPos(playerid, s_AirbreakLastCoords[playerid][0], s_AirbreakLastCoords[playerid][1], s_AirbreakLastCoords[playerid][2]);
#if defined AB_OnPlayerSpawn
return AB_OnPlayerSpawn(playerid);
#else
return 1;
#endif
}
public OnPlayerDeath(playerid, killerid, reason)
{
s_AirbreakDetectImmunity[playerid] = gettime() + 3;
#if defined AB_OnPlayerDeath
return AB_OnPlayerDeath(playerid, killerid, reason);
#else
return 1;
#endif
}
public OnPlayerUpdate(playerid)
{
if(!IsPlayerNPC(playerid))
{
new
vehicleid = GetPlayerVehicleID(playerid),
timestamp = gettime(),
Float:x,
Float:y,
Float:z,
Float:distance;
if(timestamp > s_AirbreakUpdateTick[playerid])
{
if(timestamp > s_AirbreakDetectImmunity[playerid] && GetPlayerSurfingVehicleID(playerid) == INVALID_VEHICLE_ID && GetPlayerSurfingObjectID(playerid) == INVALID_OBJECT_ID && GetPlayerSpecialAction(playerid) != SPECIAL_ACTION_ENTER_VEHICLE && GetPlayerSpecialAction(playerid) != SPECIAL_ACTION_EXIT_VEHICLE)
{
if(GetPlayerState(playerid) == PLAYER_STATE_ONFOOT)
{
distance = GetPlayerDistanceFromPoint(playerid, s_AirbreakLastCoords[playerid][0], s_AirbreakLastCoords[playerid][1], s_AirbreakLastCoords[playerid][2]);
GetPlayerPos(playerid, x, y, z);
if((floatabs(s_AirbreakLastCoords[playerid][2] - z) < 1.0 && floatabs(distance) >= ONFOOT_DISTANCE) && (floatabs(s_AirbreakLastCoords[playerid][1] - y) >= 50.0 || floatabs(s_AirbreakLastCoords[playerid][0] - x) >= 50.0))
{
AB_OnAirbreakDetected(playerid);
}
}
else if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
distance = GetVehicleDistanceFromPoint(vehicleid, s_AirbreakLastCoords[playerid][0], s_AirbreakLastCoords[playerid][1], s_AirbreakLastCoords[playerid][2]);
GetVehiclePos(vehicleid, x, y, z);
if((!AB_IsVehicleMoving(vehicleid) && floatabs(distance) >= VEHICLE_DISTANCE) && (floatabs(s_AirbreakLastCoords[playerid][1] - y) >= 40.0 || floatabs(s_AirbreakLastCoords[playerid][0] - x) >= 40.0))
{
AB_OnAirbreakDetected(playerid);
}
}
}
if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
GetVehiclePos(vehicleid, s_AirbreakLastCoords[playerid][0], s_AirbreakLastCoords[playerid][1], s_AirbreakLastCoords[playerid][2]);
}
else
{
GetPlayerPos(playerid, s_AirbreakLastCoords[playerid][0], s_AirbreakLastCoords[playerid][1], s_AirbreakLastCoords[playerid][2]);
}
s_AirbreakUpdateTick[playerid] = timestamp;
}
}
#if defined AB_OnPlayerUpdate
return AB_OnPlayerUpdate(playerid);
#else
return 1;
#endif
}
stock AB_SetSpawnInfo(playerid, team, skin, Float:x, Float:y, Float:z, Float:rotation, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo)
{
new
ret = SetSpawnInfo(playerid, team, skin, x, y, z, rotation, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo);
if(ret)
{
switch(GetPlayerState(playerid))
{
case PLAYER_STATE_NONE, PLAYER_STATE_WASTED:
{
s_AirbreakDetectImmunity[playerid] = gettime() + 3;
s_AirbreakLastCoords[playerid][0] = x;
s_AirbreakLastCoords[playerid][1] = y;
s_AirbreakLastCoords[playerid][2] = z;
}
}
}
return ret;
}
stock AB_SetPlayerPos(playerid, Float:x, Float:y, Float:z)
{
new
ret = SetPlayerPos(playerid, x, y, z);
if(ret)
{
s_AirbreakDetectImmunity[playerid] = gettime() + 3;
s_AirbreakLastCoords[playerid][0] = x;
s_AirbreakLastCoords[playerid][1] = y;
s_AirbreakLastCoords[playerid][2] = z;
}
return ret;
}
stock AB_SetPlayerPosFindZ(playerid, Float:x, Float:y, Float:z)
{
new
ret = SetPlayerPosFindZ(playerid, x, y, z);
if(ret)
{
s_AirbreakDetectImmunity[playerid] = gettime() + 3;
s_AirbreakLastCoords[playerid][0] = x;
s_AirbreakLastCoords[playerid][1] = y;
s_AirbreakLastCoords[playerid][2] = z;
}
return ret;
}
stock AB_PutPlayerInVehicle(playerid, vehicleid, seatid)
{
new
ret = PutPlayerInVehicle(playerid, vehicleid, seatid);
if(ret)
{
s_AirbreakDetectImmunity[playerid] = gettime() + 3;
}
return ret;
}
stock AB_SetVehiclePos(vehicleid, Float:x, Float:y, Float:z)
{
for(new i = 0; i < MAX_PLAYERS; i ++)
{
if(GetPlayerState(i) == PLAYER_STATE_DRIVER && IsPlayerInVehicle(i, vehicleid))
{
s_AirbreakDetectImmunity[i] = gettime() + 3;
s_AirbreakLastCoords[i][0] = x;
s_AirbreakLastCoords[i][1] = y;
s_AirbreakLastCoords[i][2] = z;
break;
}
}
return SetVehiclePos(vehicleid, x, y, z);
}
#if defined _ALS_OnPlayerConnect
#undef OnPlayerConnect
#else
#define _ALS_OnPlayerConnect
#endif
#if defined _ALS_OnPlayerSpawn
#undef OnPlayerSpawn
#else
#define _ALS_OnPlayerSpawn
#endif
#if defined _ALS_OnPlayerDeath
#undef OnPlayerDeath
#else
#define _ALS_OnPlayerDeath
#endif
#if defined _ALS_OnPlayerUpdate
#undef OnPlayerUpdate
#else
#define _ALS_OnPlayerUpdate
#endif
#if defined _ALS_OnFilterScriptInit
#undef OnFilterScriptInit
#else
#define _ALS_OnFilterScriptInit
#endif
#if defined _ALS_SetSpawnInfo
#undef SetSpawnInfo
#else
#define _ALS_SetSpawnInfo
#endif
#if defined _ALS_SetPlayerPos
#undef SetPlayerPos
#else
#define _ALS_SetPlayerPos
#endif
#if defined _ALS_SetVehiclePos
#undef SetVehiclePos
#else
#define _ALS_SetVehiclePos
#endif
#if defined _ALS_SetPlayerPosFindZ
#undef SetPlayerPosFindZ
#else
#define _ALS_SetPlayerPosFindZ
#endif
#if defined _ALS_PutPlayerInVehicle
#undef PutPlayerInVehicle
#else
#define _ALS_PutPlayerInVehicle
#endif
#define OnPlayerConnect AB_OnPlayerConnect
#define OnPlayerSpawn AB_OnPlayerSpawn
#define OnPlayerDeath AB_OnPlayerDeath
#define OnPlayerUpdate AB_OnPlayerUpdate
#define OnFilterScriptInit AB_OnFilterScriptInit
#define SetSpawnInfo AB_SetSpawnInfo
#define SetPlayerPos AB_SetPlayerPos
#define SetPlayerPosFindZ AB_SetPlayerPosFindZ
#define PutPlayerInVehicle AB_PutPlayerInVehicle
#define SetVehiclePos AB_SetVehiclePos
#if defined AB_OnFilterScriptInit
forward AB_OnFilterScriptInit();
#endif
#if defined AB_OnPlayerConnect
forward AB_OnPlayerConnect(playerid);
#endif
#if defined AB_OnPlayerSpawn
forward AB_OnPlayerSpawn(playerid);
#endif
#if defined AB_OnPlayerUpdate
forward AB_OnPlayerUpdate(playerid);
#endif
#if defined AB_OnPlayerDeath
forward AB_OnPlayerDeath(playerid, killerid, reason);
#endif