Guest User

W_Points v2.1

a guest
Apr 4th, 2013
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
Advertisement
Add Comment
Please, Sign In to add comment