[Include] W_Points
#1

Здравствуйте!


Представляю вашему вниманию "стример" точек.

Что же это такое спросите вы - это быстрое нахождение в какой из созданных точек находится игрок.
Создан специально чтобы искоренить медленную и не рациональную конструкцию вида:
PHP код:
stock IsPlayerIn(playerid)
{
    for(new 
0sizeof(coords); i++)
        if(
IsPlayerInRangeOfPoint(playerid1.0coords[i][0], coords[i][1], coords[i][2]))return 1;
    return 
0;

Основан он на зональной предварительной отсортировки, что придаёт значительную скорость обработки, так как откидывается большая часть лишних проверок.

Область применения:
Quote:

- заменяем пикапы для домов/бизов на точки.
- создание ворот
- место заправки
- возможность создать псевдочекпойнты или мины.
- отслеживание в какой точке находится игрок, для захвата территории, пополнение очков и т.п.

Основные функции:
PHP код:
native IsValidPoint(pointid);// Существует ли точка
native CreatePoint(Float:xFloat:yFloat:zFloat:rworldid=-1interior=-1);// Cоздаёт точку (х, у, z, радиус, вирт.мир, интерьер). Вернёт ид точки, иначе ид ошибки.
native DestroyPoint(pointid);// Удаляет точку
native DestroyAllPoint();// Удаляет все точки
native SetPointPos(pointidFloat:xFloat:yFloat:z);//Переместить точку
native GetPointPos(pointid, &Float:x, &Float:y, &Float:z);//Узнать координаты точки
native SetPointRadius(pointidFloat:r);//Установить радиус точки
native GetPointRadius(pointid, &Float:r);//Узнать радиус точки
native SetPointInterior(pointidinterior);//Установить интерьер точки
native GetPointInterior(pointid);//Узнать интерьер точки
native SetPointVirtualWorld(pointidworldid);//Установить вирт.мир точки
native GetPointVirtualWorld(pointid);//Узнать вирт.мир точки
native GetPlayerPoint(playeridmode=0); //Узнает в какой точке находится игрок. Возвращает ид найденной точки.
native GetPlayerMultiPoint(playeridMP[], Size);//Узнает в каких точках находится игрок. Возвращает количество найденных точек
native GetVehiclePoint(vehicleidmode=0);//Узнает в какой точке находится транспорт (самую близлежащую, самую близлежащую с проверкой радиуса, самую первую которая входит в радиус)
native GetVehicleMultiPoint(vehicleidMP[], Size);//Узнает в каких точках находится транспорт 
Quote:

GetPlayerPoint(playerid, 0); Ищет самую близлежащую точку в которой находится игрок.
GetPlayerPoint(playerid, 1); Ищет самую близлежащую точку даже если игрок не находится в ней.
GetPlayerPoint(playerid, 2); Ищет до первой точки в которой находится игрок.
GetPlayerMultiPoint(playerid, MP[], Size); Ищет все точки в которых находится игрок пока они не закончатся или не достигнут Size.

Небольшой Тест всего 40,000 точек, симуляция 1000 игроков. Ищется самая близлежащая точка. Для правильности теста нужно быть на сервере, возле нулевых координат!

Create W_Points 473 ms
GetW_Point 20 ms

Create StreamerPoints 35 ms
GetStreamerPoint 329 ms

GetClassicPoint 11479 ms

y_areas выдаёт для одного игрока ~5 ms, осталось домножить на 1000.

Внимание!
1) Настоятельно рекомендую не ставить радиус больше MAX_POINTS_SETKA_DLINA, так как при нахождения точки может возникнуть казус: вы входите в радиус но точка не определяется. Связано это с отсутствием ссылки на точку.
2) Поддержка интерьеров и виртуальных миров по умолчанию отключена. Для того чтобы включить выполняем следующие:
PHP код:
#define PointWorld //включаем вирт.мир
#define PointInterior //включаем интерьер
#include <W_PS> //подключаем инклуд 
<<< Примеры >>>
Использование GetPlayerMultiPoint:
PHP код:
new pointarray[32];//создали массив куда пишем иды точек.
new kolichestvo=GetPlayerMultiPoint(playeridpointarraysizeof(pointarray));//поиск точек, вернёт количество найденных точек.
for(kolichestvo=kolichestvo-1kolichestvo > -1kolichestvo--)printf("pointid = %d",pointarray[kolichestvo]); 
Псевдочекпойнт:
PHP код:
new Point[MAX_PLAYERS];//Куда нибудь в начало, хранит ид точки в которой находится игрок.
stock PointUpdate(playerid)//В любой таймер с перебором игроков
{
    new 
newppoint=GetPlayerPoint(playerid);//Ищем самую близлежайшую точку в которой находится игрок
    
if(Point[playerid] != newppoint)//Если точка отличается от старой.
    
{
        if(
Point[playerid] != 0)    OnPlayerLeavePoint(playeridPoint[playerid]);//Если мы были в точке
        
if(newppoint != 0)            OnPlayerEnterPoint(playeridnewppoint);//Если новая точка точка.
        
Point[playerid]=newppoint;//Запомним точку
    
}
    return 
1;
}
stock OnPlayerLeavePoint(playeridpointid)
{
//...
}
stock OnPlayerEnterPoint(playeridpointid)
{
//...

Пример 3:
PHP код:
#include <a_samp>
#define MAX_POINTS (10)
#define MAX_POINTS_TO_STREAM (10)
#define PointWorld
#define PointInterior
#define DeBug
#include <W_PS>
#define Biznes (1)
#define Home (2)
new PointData[3][MAX_POINTS+1 char];
new 
BizKolvo;
new 
HomeKolvo;
new 
Timer;
new 
Point[MAX_PLAYERS];//Куда нибудь в начало, хранит ид точки в которой находится игрок.
//==============================================================================
public OnFilterScriptInit()
{
     
Timer=SetTimer("PointUpdate",100,1);
    return 
1;
}
public 
OnFilterScriptExit()
{
     
KillTimer(Timer);
    return 
1;
}
public 
OnPlayerCommandText(playeridcmdtext[])
{
    if(
strcmp("/biz"cmdtexttrue4) == 0)
    {
        
CreateBiz(playerid);
        return 
1;
    }
    if(
strcmp("/home"cmdtexttrue5) == 0)
    {
        
CreateHome(playerid);
        return 
1;
    }
    if(
strcmp("/del"cmdtexttrue4) == 0)
    {
        
DestroyPoint(MAX_POINTS);
        return 
1;
    }
    if(
strcmp("/pos"cmdtexttrue4) == 0)
    {
        new 
Float:x,Float:y,Float:z;
        
GetPlayerPos(playeridx,y,z);
        
SetPointPos(MAX_POINTSxyz);
        return 
1;
    }
    return 
0;
}
//==============================================================================
forward PointUpdate();
public 
PointUpdate()//В любой таймер с перебором игроков
{
    for(new 
playeridplayerid MAX_PLAYERSplayerid++)
    if(
IsPlayerConnected(playerid))
    {
        new 
newppoint=GetPlayerPoint(playerid);//Ищем самую близлежайшую точку в которой находится игрок
        
if(Point[playerid] != newppoint)//Если точка отличается от старой.
        
{
            if(
Point[playerid] != 0)    OnPlayerLeavePoint(playeridPoint[playerid]);//Если мы были в точке
            
if(newppoint != 0)            OnPlayerEnterPoint(playeridnewppoint);//Если новая точка точка.
            
Point[playerid]=newppoint;//Запомним точку
        
}
    }
    return 
1;
}
stock OnPlayerLeavePoint(playeridpointid)
{
    new 
str[128];
    if(
PointData[0]{pointid} == Homeformat(str,sizeof(str),"Вы покинули дом номер %d, хозяин %d",PointData[1]{pointid},PointData[2]{pointid});
    else 
format(str,sizeof(str),"Вы покинули бизнес номер %d, хозяин %d",PointData[1]{pointid},PointData[2]{pointid});
    return 
SendClientMessage(playerid,-1,str);
}
stock OnPlayerEnterPoint(playeridpointid)
{
    new 
str[128];
    if(
PointData[0]{pointid} == Homeformat(str,sizeof(str),"Вы вошли в дом номер %d, хозяин %d",PointData[1]{pointid},PointData[2]{pointid});
    else 
format(str,sizeof(str),"Вы вошли в бизнес номер %d, хозяин %d",PointData[1]{pointid},PointData[2]{pointid});
    return 
SendClientMessage(playerid,-1,str);
}
stock CreateBiz(playerid)
{
    new 
Float:x,Float:y,Float:z;
    
GetPlayerPos(playeridx,y,z);
    new 
p=CreatePoint(x,y,z10.0);
    if(
1)
    {
        if(
== 0printf("Привышено максимальное количество точек.");
        if(
== -1)printf("Привышено максимальное количество точек в чанке.");
        if(
== -2)printf("Поддержка вирт.миров отключена!");
        if(
== -3)printf("Поддержка интерьеров отключена!");
        return 
0;
    }
    
BizKolvo++;
    
PointData[0]{p}=Biznes;//Запомним тип точки
    
PointData[1]{p}=BizKolvo;//Запомни ид бизнеса
    
PointData[2]{p}=playerid;//Запомним владельца
    
return BizKolvo;
}
stock CreateHome(playerid)
{
    new 
Float:x,Float:y,Float:z;
    
GetPlayerPos(playeridx,y,z);
    new 
p=CreatePoint(x,y,z10.0);
    if(
1)
    {
        if(
== 0printf("Привышено максимальное количество точек.");
        if(
== -1)printf("Привышено максимальное количество точек в чанке.");
        if(
== -2)printf("Поддержка вирт.миров отключена!");
        if(
== -3)printf("Поддержка интерьеров отключена!");
        return 
0;
    }
    
HomeKolvo++;
    
PointData[0]{p}=Home;//Запомним тип точки
    
PointData[1]{p}=HomeKolvo;//Запомни ид дома
    
PointData[2]{p}=playerid;//Запомним владельца
    
return HomeKolvo;

>> Скачать W_Points v2.3: SolidFiles
>> Просмотреть W_Points v2.3: Pastebin

>> Скачать W_Points v2.1: SolidFiles
>> Просмотреть W_Points v2.1: Pastebin

W_Points v2.1:
-Добавлен поиск точек для транспорта.
-Исправлен баг в GetPlayerPoint(playerid, 2); связанный с лишним кодом.
W_Points v2.2:
-Исправлены мелкие ошибки.
-Новый метод поиска предложенный AirKite
W_Points v2.3:
Исправлено перемещение точки SetPointPos.
Reply


Messages In This Thread
W_Points v2.3 - by White_116 - 26.09.2011, 14:46
Re: W_Points - by Stepashka - 26.09.2011, 14:57
Re: W_Points - by White_116 - 26.09.2011, 15:02
Re: W_Points - by Stepashka - 26.09.2011, 15:06
Re: W_Points - by White_116 - 26.09.2011, 15:15
Re: W_Points - by Makar93 - 26.09.2011, 15:50
Re: W_Points - by Stepashka - 26.09.2011, 16:16
Re: W_Points - by Romanius - 26.09.2011, 16:55
Re: W_Points - by OKStyle - 27.09.2011, 01:46
Re: W_Points - by jhonyxakep - 27.09.2011, 05:09
Re: W_Points - by White_116 - 27.09.2011, 16:39
Re: W_Points - by jhonyxakep - 29.09.2011, 03:33
Re: W_Points - by White_116 - 03.04.2013, 17:53
Re: W_Points - by AirKite - 03.04.2013, 22:25
Re: W_Points - by White_116 - 04.04.2013, 09:57
Re: W_Points - by XemyL - 04.04.2013, 10:31
Re: W_Points - by AirKite - 04.04.2013, 12:42
Re: W_Points - by White_116 - 04.04.2013, 13:01
Re: W_Points - by eakwarp - 04.04.2013, 13:39
Re: W_Points - by AirKite - 04.04.2013, 15:21
Re: W_Points - by AirKite - 05.04.2013, 07:33
Re: W_Points - by White_116 - 05.04.2013, 09:07
Re: W_Points - by AirKite - 05.04.2013, 09:18
Re: W_Points - by White_116 - 05.04.2013, 09:31
Re: W_Points - by AirKite - 06.04.2013, 04:14
Re: W_Points - by White_116 - 06.04.2013, 09:53
Re: W_Points - by White_116 - 15.05.2013, 18:04
Re: W_Points - by AirKite - 24.05.2013, 09:38
Re: W_Points - by PT - 08.08.2013, 05:22

Forum Jump:


Users browsing this thread: 11 Guest(s)