View difference between Paste ID: EKL5kFpr and SQ9AHUW7
SHOW: | | - or go back to the newest paste.
1
#if defined _W_PS_included
2
	#endinput
3
#endif
4
#define _W_PS_included
5
#pragma library W_PS
6
/*============================================================================*\
7
=======================|      Points Streamer v2.1	    |=======================
8
=======================|      Created by: White_116     |=======================
9
=======================|      	Date: 04.04.2013     	|=======================
10
================================================================================
11
native IsValidPoint(pointid);// Существует ли точка
12
native CreatePoint(Float:x, Float:y, Float:z, Float:r, worldid=-1, interior=-1);// Cоздаёт точку (х, у, z, радиус, вирт.мир, интерьер)
13
native DestroyPoint(pointid);// Удаляет точку
14
native DestroyAllPoint();// Удаляет все точки
15
native SetPointPos(pointid, Float:x, Float:y, Float:z);//Переместить точку
16
native GetPointPos(pointid, &Float:x, &Float:y, &Float:z);//Узнать координаты точки
17
native SetPointRadius(pointid, Float:r);//Установить радиус точки
18
native GetPointRadius(pointid, &Float:r);//Узнать радиус точки
19
native SetPointInterior(pointid, interior);//Установить интерьер точки
20
native GetPointInterior(pointid);//Узнать интерьер точки
21
native SetPointVirtualWorld(pointid, worldid);//Установить вирт.мир точки
22
native GetPointVirtualWorld(pointid);//Узнать вирт.мир точки
23
native GetPlayerPoint(playerid, mode=0); //Узнает в какой точке находится игрок (самую близлежащую, самую близлежащую с проверкой радиуса, самую первую которая входит в радиус)
24
native GetPlayerMultiPoint(playerid, MP[], Size);//Узнает в каких точках находится игрок
25
native GetVehiclePoint(vehicleid, mode=0);//Узнает в какой точке находится транспорт (самую близлежащую, самую близлежащую с проверкой радиуса, самую первую которая входит в радиус)
26
native GetVehicleMultiPoint(vehicleid, MP[], Size);//Узнает в каких точках находится транспорт
27
\*============================================================================*/
28
#if !defined MAX_POINTS
29
	#define MAX_POINTS (1000)//Максимальное число точек.
30
#endif
31
#if !defined MAX_POINTS_TO_STREAM
32
	#define MAX_POINTS_TO_STREAM (30)//Количество точек в чанке (MAX 256)
33
#endif
34
#if !defined MAX_POINTS_REGION
35
	#define MAX_POINTS_REGION (3000)//Граница
36
#endif
37
#if !defined MAX_POINTS_SETKA_DLINA
38
	#define MAX_POINTS_SETKA_DLINA (60)//Размер чанка
39
#endif
40
#define MAX_POINTS_STORONA_DLINA ((MAX_POINTS_REGION*2)/MAX_POINTS_SETKA_DLINA)
41
42
new	Float:PointX[MAX_POINTS+1],
43
	Float:PointY[MAX_POINTS+1],
44
	Float:PointZ[MAX_POINTS+1],
45
	Float:PointR[MAX_POINTS+1],
46
	PointS[MAX_POINTS+1 char]={0xFFFFFFFF, ...},
47
	PointXX[MAX_POINTS+1 char],
48
	PointYY[MAX_POINTS+1 char];
49
	
50
#if defined PointWorld
51
	new PointW[MAX_POINTS+1];
52
#endif
53
54
#if defined PointInterior
55
	new PointI[MAX_POINTS+1];
56
#endif
57
	
58
new Point_Chunk[MAX_POINTS_STORONA_DLINA][MAX_POINTS_STORONA_DLINA][MAX_POINTS_TO_STREAM],
59
	Point_PointsInChunk[MAX_POINTS_STORONA_DLINA][MAX_POINTS_STORONA_DLINA char],
60
	Point_Created[MAX_POINTS+1],
61
	Point_Points;
62
	
63
new const Okrug[9][2]={{0,0},{0,1},{0,-2},{1,1},{-2,0},{2,1},{0,-2},{-2,2},{0,-2}};
64
65
//==============================================================================
66
//==============================================================================
67
//==============================================================================
68
69
stock GetChunkPosXY(region,dlina,Float:x,Float:y,&x1,&y1,p=1)
70
{
71
	if(p)
72
	{
73
		// создадим искуственную границу дальше которой нельзя находится
74
		if(x<-region)x=-region+1; else if(y>region)y=region-1;
75
		if(y<-region)y=-region+1; else if(x>region)x=region-1;
76
	}
77
	x1=floatround((x+region)/dlina,floatround_floor);
78
	y1=floatround((y+region)/dlina,floatround_floor);
79
	return 1;
80
}
81
82
stock IsValidPoint(P)
83
{
84
	if(!(0 < P <= MAX_POINTS))return 0;
85
	if(PointS{P} == 0xFF)return 0;
86
	return 1;
87
}
88
89
stock CreatePoint(Float:x, Float:y, Float:z, Float:r, w=-1, i=-1)
90
{
91
//==================== Инициализация...
92
	if(Point_Points == 0)
93
	{
94
	    for(new e; e < MAX_POINTS; e++)Point_Created[e]=e+1;
95
		Point_Points=1;
96
	}
97
//==================== проверяем, можно ли добавить точку...
98
	if(Point_Points >= MAX_POINTS)
99
	{
100
		#if defined DeBug
101
	    	printf("W_PS-Ошибка: Количество точек привышает максимально допустимого значения MAX_POINTS =%d=", MAX_POINTS);
102
	    #endif
103
		return 0;
104
	}
105
	new X,Y,P=Point_Created[MAX_POINTS-Point_Points];
106
//==================== проверяем, можно ли добавить точку...
107
	GetChunkPosXY(MAX_POINTS_REGION,MAX_POINTS_SETKA_DLINA, x,y, X,Y);//	узнаём к какому квадрату относится точка
108
	if(Point_PointsInChunk[X]{Y} >= MAX_POINTS_TO_STREAM)
109
	{
110
	    #if defined DeBug
111
	    	printf("W_PS-Ошибка: Чанк =%d-%d= заполнен, придел MAX_POINTS_TO_STREAM =%d=", X,Y, MAX_POINTS_TO_STREAM);
112
	    #endif
113
		return -1;//	если перебор точек на 1 квадрат
114
	}
115
//==================== добовляем данные точки...
116
	#if defined PointWorld
117
	if(w < -1)PointW[P]=-w; else PointW[P]=w;
118
	#else
119
	if(w != -1)
120
	{
121
	    #if defined DeBug
122
			printf("W_PS-Ошибка: Поддержка вирт.миров отключена! Точка =%d=",P);
123
		#endif
124
		return -2;
125
	}
126
	#endif
127
//====================
128
	#if defined PointInterior
129
	if(i < -1)PointI[P]=-i; else PointI[P]=i;
130
	#else
131
	if(i != -1)
132
	{
133
	    #if defined DeBug
134
			printf("W_PS-Ошибка: Поддержка интерьеров отключена! Точка =%d=",P);
135
		#endif
136
		return -3;
137
	}
138
	#endif
139
//====================
140
	if(r < 0.0)PointR[P]=-r; else PointR[P]=r;
141
	PointX[P]=x,
142
	PointY[P]=y,
143
	PointZ[P]=z,
144
    PointXX{P}=X,
145
	PointYY{P}=Y;
146
	PointS{P}=Point_PointsInChunk[X]{Y};
147
	Point_PointsInChunk[X]{Y}++;//	запомним количество точек в квадрате
148
	Point_Chunk[X][Y][PointS{P}]=P;//  запомним ид точки
149
	Point_Created[MAX_POINTS-Point_Points]=0;//	запомним что свободной точки нет
150
	Point_Points++;//	запомним сколько всего точек
151
	return P;//  отправим ид точки
152
}
153
154
stock DestroyPoint(P)
155
{
156
	if(!IsValidPoint(P))
157
	{
158
	    #if defined DeBug
159
	    	printf("W_PS-Ошибка: Точки =%d= не существует. Отмена удаления.", P);
160
	    #endif
161
		return 0;
162
	}
163
	Point_Points--;//											запомним сколько всего точек
164
	Point_Created[MAX_POINTS-Point_Points]=P;
165
	new K=Point_PointsInChunk[PointXX{P}]{PointYY{P}}--;//			Запомним количество точек в квадрате
166
	Point_Chunk[PointXX{P}][PointYY{P}][PointS{P}]=0;// 	Обнулим удалёную точку
167
	new P2=Point_Chunk[PointXX{P}][PointYY{P}][K];// 	Достанем ид крайней точки
168
	if(P2 == 0)PointS{P}=0xFF;//                             Наша точка оказаласть крайней, Запомним что точки не существует
169
	else
170
	{
171
		Point_Chunk[PointXX{P}][PointYY{P}][K]=0;//         	Обнулим Крайнюю точку
172
		Point_Chunk[PointXX{P}][PointYY{P}][PointS{P}]=P2;// Внесём ид крайней точки в удалёную
173
		PointS{P2}=PointS{P};//    	                            Изменим позицию крайней точки
174
		PointS{P}=0xFF;//                                           Запомним что точки не существует
175
	}
176
	return 1;
177
}
178
179
stock DestroyAllPoint()
180
{
181
    Point_Points=0;//	запомним сколько всего точек
182
	for(new j=1; j <= MAX_POINTS; j++)PointS{j}=0xFF;
183
	for(new j; j < MAX_POINTS_STORONA_DLINA; j++)for(new k; k < MAX_POINTS_STORONA_DLINA; k++)Point_PointsInChunk[j]{k}=0;
184
	return 1;
185
}
186
187
stock SetPointPos(P, Float:x, Float:y, Float:z)
188
{
189
    if(!IsValidPoint(P))
190
	{
191
	    #if defined DeBug
192
	    	printf("W_PS-Ошибка: Точки =%d= не существует. Отмена перемещения.", P);
193
	    #endif
194
		return 0;
195
	}
196
    new X,Y;
197
	GetChunkPosXY(MAX_POINTS_REGION, MAX_POINTS_SETKA_DLINA, x,y, X,Y);//	узнаём к какому квадрату будет относиться точка
198
	if(PointXX{P}!=X || PointYY{P}!=Y)
199
	{
200
 		//==================== проверяем, можно ли добавить точку...
201
		if(Point_PointsInChunk[X]{Y} >= MAX_POINTS_TO_STREAM)
202
		{
203
		    #if defined DeBug
204
	    		printf("W_PS-Ошибка: Чанк =%d-%d= заполнен, придел MAX_POINTS_TO_STREAM =%d=. Перемещение точки %d отменено.", X,Y, MAX_POINTS_TO_STREAM, P);
205
	    	#endif
206
			return -1;
207
		}
208
        //==================== перегрупперуем старый квадрат от старой точки
209
		new K=Point_PointsInChunk[PointXX{P}]{PointYY{P}}--;//			Запомним количество точек в квадрате
210
		Point_Chunk[PointXX{P}][PointYY{P}][PointS{P}]=0;// 	Обнулим удалёную точку
211
		new P2=Point_Chunk[PointXX{P}][PointYY{P}][K];// 	Достанем ид крайней точки
212
		if(P2 != 0)
213
		{
214
			Point_Chunk[PointXX{P}][PointYY{P}][K]=0;//         	Обнулим Крайнюю точку
215
			Point_Chunk[PointXX{P}][PointYY{P}][PointS{P}]=P2;// Внесём ид крайней точки в удалёную
216
			PointS{P2}=PointS{P};//									Изменим позицию крайней точки
217
		}
218
		//==================== добовляем данные точки...
219
		Point_Chunk[X][Y][Point_PointsInChunk[X]{Y}]=P;//  запомним ид точки
220
		PointS{P}=Point_PointsInChunk[X]{Y};
221
		Point_PointsInChunk[X]{Y}++;//	запомним количество точек в квадрате
222
		PointXX{P}=X;
223
		PointYY{P}=Y;
224
	}
225
	PointX[P]=x; PointY[P]=y; PointZ[P]=z;
226
	return 1;
227
}
228
229
stock GetPointPos(P, &Float:x, &Float:y, &Float:z)
230
{
231
    if(!IsValidPoint(P))
232
	{
233
	    #if defined DeBug
234
	    	printf("W_PS-Ошибка: Точки =%d= не существует. Не возможно определить позицию.", P);
235
	    #endif
236
		return 0;
237
	}
238
	x=PointX[P]; y=PointY[P]; z=PointZ[P];
239
	return 1;
240
}
241
242
stock SetPointRadius(P,Float:r)
243
{
244
    if(!IsValidPoint(P))
245
	{
246
	    #if defined DeBug
247
	    	printf("W_PS-Ошибка: Точки =%d= не существует. Не возможно установить радиус.", P);
248
	    #endif
249
		return 0;
250
	}
251
	if(r < 0.0)PointR[P]=-r; else PointR[P]=r;
252
	return 1;
253
}
254
255
stock GetPointRadius(P,&Float:r)
256
{
257
    if(!IsValidPoint(P))
258
	{
259
	    #if defined DeBug
260
	    	printf("W_PS-Ошибка: Точки =%d= не существует. Не возможно определить радиус.", P);
261
	    #endif
262
		return 0;
263
	}
264
	r=PointR[P];
265
	return 1;
266
}
267
268
#if defined PointWorld
269
	stock SetPointVirtualWorld(P, w)
270
	{
271
	    if(!IsValidPoint(P))
272
		{
273
		    #if defined DeBug
274
		    	printf("W_PS-Ошибка: Точки =%d= не существует. Не возможно установить радиус.", P);
275
		    #endif
276
			return 0;
277
		}
278
		if(w < -1)PointW[P]=-w; else PointW[P]=w;
279
		return 1;
280
	}
281
282
	stock GetPointVirtualWorld(P)
283
	{
284
	    if(!IsValidPoint(P))
285
		{
286
		    #if defined DeBug
287
		    	printf("W_PS-Ошибка: Точки =%d= не существует. Не возможно определить радиус.", P);
288
		    #endif
289
			return -2;
290
		}
291
		return PointW[P];
292
	}
293
#endif
294
295
#if defined PointInterior
296
	stock SetPointInterior(P, i)
297
	{
298
	    if(!IsValidPoint(P))
299
		{
300
		    #if defined DeBug
301
		    	printf("W_PS-Ошибка: Точки =%d= не существует. Не возможно установить радиус.", P);
302
		    #endif
303
			return 0;
304
		}
305
		if(i < -1)PointI[P]=-i; else PointI[P]=i;
306
		return 1;
307
	}
308
309
	stock GetPointInterior(P)
310
	{
311
	    if(!IsValidPoint(P))
312
		{
313
		    #if defined DeBug
314
		    	printf("W_PS-Ошибка: Точки =%d= не существует. Не возможно определить радиус.", P);
315
		    #endif
316
			return 0;
317
		}
318
		return PointI[P];
319
	}
320
#endif
321
322
//==============================================================================
323
//==============================================================================
324
//==============================================================================
325
326
stock GetPlayerPoint(playerid, r=0)
327
{
328
	new Float:x,Float:y, Float:z, X,Y,P,P2;
329
	GetPlayerPos(playerid,x,y,z);
330
	#if defined PointWorld
331
	new WorldID=GetPlayerVirtualWorld(playerid);
332
	#endif
333
	
334
	#if defined PointInterior
335
	new InteriorID=GetPlayerInterior(playerid);
336
	#endif
337
	z=1000.0;
338
	GetChunkPosXY(MAX_POINTS_REGION-MAX_POINTS_SETKA_DLINA, MAX_POINTS_SETKA_DLINA, x, y, X, Y);//	узнаём к какому квадрату относится точка
339
//--------------------------
340
	if(r == 2) for(new O,OP; O < 9; O++)
341
	{
342
		X+=Okrug[O][0];	Y+=Okrug[O][1];
343
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
344
        {
345
            P=Point_Chunk[X][Y][OP];
346
            #if defined PointWorld
347
			if(WorldID != PointW[P] || PointW[P]!=-1)continue;
348
			#endif
349
			#if defined PointInterior
350
			if(InteriorID != PointI[P] || PointI[P]!=-1)continue;
351
			#endif
352
            if(IsPlayerInRangeOfPoint(playerid, PointR[P], PointX[P], PointY[P], PointZ[P]))return P;
353
		}
354
	}
355
	else if(r == 1) for(new O,OP; O < 9; O++)
356
	{
357
		X+=Okrug[O][0];	Y+=Okrug[O][1];
358
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
359
        {
360
            P=Point_Chunk[X][Y][OP];
361
            #if defined PointWorld
362
			if(WorldID != PointW[P] && PointW[P]!=-1)continue;
363
			#endif
364
			#if defined PointInterior
365
			if(InteriorID != PointI[P] && PointI[P]!=-1)continue;
366
			#endif
367
368
			y=GetPlayerDistanceFromPoint(playerid, PointX[P], PointY[P], PointZ[P]);
369
			if(y < z)
370
			{
371
                z=y; P2=P;
372
			}
373
		}
374
	}
375
	else for(new O,OP; O < 9; O++)
376
	{
377
		X+=Okrug[O][0];	Y+=Okrug[O][1];
378
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
379
        {
380
            P=Point_Chunk[X][Y][OP];
381
            #if defined PointWorld
382
			if(WorldID != PointW[P] && PointW[P]!=-1)continue;
383
			#endif
384
			#if defined PointInterior
385
			if(InteriorID != PointI[P] && PointI[P]!=-1)continue;
386
			#endif
387
            y=GetPlayerDistanceFromPoint(playerid, PointX[P], PointY[P], PointZ[P]);
388
			if(y > PointR[P])continue;
389
			if(y < z)
390
			{
391
                z=y; P2=P;
392
			}
393
		}
394
	}
395
	return P2;
396
}
397
398
stock GetPlayerMultiPoint(playerid, MP[], S)
399
{
400
	new Float:x,Float:y, Float:z, X,Y,P,K;
401
	GetPlayerPos(playerid,x,y,z);
402
	#if defined PointWorld
403
	new WorldID=GetPlayerVirtualWorld(playerid);
404
	#endif
405
406
	#if defined PointInterior
407
	new InteriorID=GetPlayerInterior(playerid);
408
	#endif
409
	z=1000.0;
410
	GetChunkPosXY(MAX_POINTS_REGION-MAX_POINTS_SETKA_DLINA, MAX_POINTS_SETKA_DLINA, x, y, X, Y);//	узнаём к какому квадрату относится точка
411
//--------------------------
412
	for(new O,OP; O < 9; O++)
413
	{
414
		X+=Okrug[O][0];	Y+=Okrug[O][1];
415
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
416
        if(K < S)
417
        {
418
            P=Point_Chunk[X][Y][OP];
419
            #if defined PointWorld
420
			if(WorldID != PointW[P] || PointW[P]!=-1)continue;
421
			#endif
422
			#if defined PointInterior
423
			if(InteriorID != PointI[P] || PointI[P]!=-1)continue;
424
			#endif
425
			
426
            if(IsPlayerInRangeOfPoint(playerid, PointR[P], PointX[P], PointY[P], PointZ[P]))
427
			{
428
				MP[K]=P; K++;
429
			}
430
		}
431
	}
432
	return K;
433
}
434
//==============================================================================
435
stock GetVehiclePoint(vehicleid, r=0)
436
{
437
	new Float:x,Float:y, Float:z, X,Y,P,P2;
438
	GetVehiclePos(vehicleid,x,y,z);
439
	#if defined PointWorld
440
	new WorldID=GetVehicleVirtualWorld(vehicleid);
441
	#endif
442
443
	z=1000.0;
444
	GetChunkPosXY(MAX_POINTS_REGION-MAX_POINTS_SETKA_DLINA, MAX_POINTS_SETKA_DLINA, x, y, X, Y);//	узнаём к какому квадрату относится точка
445
//--------------------------
446
	if(r == 2) for(new O,OP; O < 9; O++)
447
	{
448
		X+=Okrug[O][0];	Y+=Okrug[O][1];
449
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
450
        {
451
            P=Point_Chunk[X][Y][OP];
452
            #if defined PointWorld
453
			if(WorldID != PointW[P] || PointW[P]!=-1)continue;
454
			#endif
455
456
			if(GetVehicleDistanceFromPoint(vehicleid, PointX[P], PointY[P], PointZ[P]) <= PointR[P])return P;
457
		}
458
	}
459
	else if(r == 1) for(new O,OP; O < 9; O++)
460
	{
461
		X+=Okrug[O][0];	Y+=Okrug[O][1];
462
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
463
        {
464
            P=Point_Chunk[X][Y][OP];
465
            #if defined PointWorld
466
			if(WorldID != PointW[P] && PointW[P]!=-1)continue;
467
			#endif
468
469
			y=GetVehicleDistanceFromPoint(vehicleid, PointX[P], PointY[P], PointZ[P]);
470
			if(y < z)
471
			{
472
                z=y; P2=P;
473
			}
474
		}
475
	}
476
	else for(new O,OP; O < 9; O++)
477
	{
478
		X+=Okrug[O][0];	Y+=Okrug[O][1];
479
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
480
        {
481
            P=Point_Chunk[X][Y][OP];
482
            #if defined PointWorld
483
			if(WorldID != PointW[P] && PointW[P]!=-1)continue;
484
			#endif
485
486
            y=GetVehicleDistanceFromPoint(vehicleid, PointX[P], PointY[P], PointZ[P]);
487
			if(y > PointR[P])continue;
488
			if(y < z)
489
			{
490
                z=y; P2=P;
491
			}
492
		}
493
	}
494
	return P2;
495
}
496
497
stock GetVehicleMultiPoint(vehicle, MP[], S)
498
{
499
	new Float:x,Float:y, Float:z, X,Y,P,K;
500
	GetVehiclePos(vehicleid,x,y,z);
501
	#if defined PointWorld
502
	new WorldID=GetVehicleVirtualWorld(vehicleid);
503
	#endif
504
505
	z=1000.0;
506
	GetChunkPosXY(MAX_POINTS_REGION-MAX_POINTS_SETKA_DLINA, MAX_POINTS_SETKA_DLINA, x, y, X, Y);//	узнаём к какому квадрату относится точка
507
//--------------------------
508
	for(new O,OP; O < 9; O++)
509
	{
510
		X+=Okrug[O][0];	Y+=Okrug[O][1];
511
        for(OP=Point_PointsInChunk[X]{Y}-1; OP > -1; OP--)
512
        if(K < S)
513
        {
514
            P=Point_Chunk[X][Y][OP];
515
            #if defined PointWorld
516
			if(WorldID != PointW[P] || PointW[P]!=-1)continue;
517
			#endif
518
519
            if(GetVehicleDistanceFromPoint(vehicleid, PointX[P], PointY[P], PointZ[P]) <= PointR[P])
520
			{
521
				MP[K]=P; K++;
522
			}
523
		}
524
	}
525
	return K;
526
}
527
528
#undef MAX_POINTS_TO_STREAM
529
#undef MAX_POINTS_REGION
530
#undef MAX_POINTS_SETKA_DLINA
531
#undef MAX_POINTS_STORONA_DLINA