Advertisement
Guest User

Script liga elso fordulo Basshunter

a guest
Oct 1st, 2016
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 15.59 KB | None | 0 0
  1. /*
  2. very very very very basic!! gps script by Basshunter
  3.  
  4. nah, a lenyeg:
  5. kell egy graf, amit ra tudunk vetiteni a jatek terkepere es a pontjai kb az utak fobb
  6. pontjainal,  keresztezodeseknel vannak.
  7. grafot ugy hatarozzuk meg, h megadjuk a pontjait es h melyik pontbol melyik ponto(ka)t
  8. lehet elerni, azaz, h mik a graf elei.
  9. ahhoz, h a gps script jol menjen minden pontbol kell letesiteni utat minden pontba,
  10. ha a graf nem lenne osszefuggo, akk letezne ket olyan pont,ami kozott nem letesitheto ut,
  11. az meg szopas lenne.
  12. letezik egy Dijkstra nevu matematikusrol elnevezett algoritmus, ami arra jo, h
  13. megkeresi a grafban ket pont kozott a legkisebb koltseggel jaro utat.
  14. ez egy naggyon fasza dolog, utana lehet olvasni pl itt
  15. https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
  16. errol meg reszletesebben az algoritmus kodjanal van iras
  17.  
  18. a script lenyege kb annyi, h a jatekos a mapon kivalaszt egy waypoint-ot
  19. (jobb click a map-on) es a gps automatikusan megjeleniti neki az utvonalat.
  20. a gps lekorlatozodik egy varosreszre, a jatekos poziciojat nezve megkeresi a
  21. hozza legkozelebb levo pontot es onnan navigalja el a waypoint-hoz legkozelebb eso
  22. pontig. tehat ha faszsag van neki megadva, ami kivul esik a varosreszen, a
  23. script mukodese nem lessz kiszamithato es jelentkezhetnek erdekessegek :D
  24. szoval keretik a waypointot lehetoseg szerint kozel rakni az egyik node-hoz...:)
  25.  
  26. node-ok keszitesse:
  27. /node-val letrehozod az elsot, akk megjelenik a 3d cucc es annak segitsegevel latod
  28. az id-jet, igy a /neighbour ID ID ID ID max 6 id-ig letrehoz olyan node-t ami a megadott
  29. node-ok szomszedja igy fogja tudni az algoritmus, h melyikbol melyikbe mehet.
  30. a vegen MENTSD EL, /savenodes :D
  31.  
  32. egyebb:
  33. /closestnode odateleportal a hozzad legkozelebb eso node-hoz
  34.  
  35. ENJOY
  36.  
  37. nagyjabol ennyi :D
  38. */
  39.  
  40. /*
  41. alap nodes.txt (LS nyugati(?) resze /closestnode...):
  42. 1037.941772,-1572.491333,13.066694,2,4,19,-1,-1,-1 NODE #1
  43. 918.464416,-1572.841186,13.062478,1,3,11,-1,-1,-1 NODE #2
  44. 915.921569,-1489.605102,13.055746,2,4,6,8,-1,-1 NODE #3
  45. 1048.655395,-1494.401367,13.066202,1,3,5,-1,-1,-1 NODE #4
  46. 1060.554809,-1400.661376,13.148726,4,6,12,18,-1,-1 NODE #5
  47. 917.615112,-1400.747802,12.944102,3,5,7,14,-1,-1 NODE #6
  48. 796.244567,-1401.111694,13.093589,6,8,15,17,-1,-1 NODE #7
  49. 793.483398,-1480.477294,13.066370,3,7,9,-1,-1,-1 NODE #8
  50. 771.503112,-1586.994018,13.062499,8,10,23,-1,-1,-1 NODE #9
  51. 838.253173,-1613.024658,13.062537,9,11,-1,-1,-1,-1 NODE #10
  52. 874.620117,-1577.971069,13.065388,2,10,-1,-1,-1,-1 NODE #11
  53. 1058.217285,-1324.285644,13.062490,5,13,22,-1,-1,-1 NODE #12
  54. 942.958312,-1323.725463,13.066369,12,14,-1,-1,-1,-1 NODE #13
  55. 917.088256,-1323.538818,13.191036,13,6,15,-1,-1,-1 NODE #14
  56. 797.102722,-1322.802856,13.062549,14,7,16,-1,-1,-1 NODE #15
  57. 632.878356,-1319.955200,13.157868,15,17,-1,-1,-1,-1 NODE #16
  58. 632.589172,-1400.801269,13.012390,7,16,23,-1,-1,-1 NODE #17
  59. 1198.745239,-1401.550781,12.965830,5,19,20,-1,-1,-1 NODE #18
  60. 1196.037719,-1571.765380,13.087066,1,18,-1,-1,-1,-1 NODE #19
  61. 1209.086914,-1281.450927,13.086853,18,21,-1,-1,-1,-1 NODE #20
  62. 1149.150512,-1280.644775,13.321684,20,22,-1,-1,-1,-1 NODE #21
  63. 1058.386230,-1281.693359,13.454155,21,12,-1,-1,-1,-1 NODE #22
  64. 632.233093,-1586.422485,15.230491,17,9,-1,-1,-1,-1 NODE #23
  65. */
  66.  
  67. #include <a_samp>
  68. #include <streamer> // streamer plugint igenyel azt elvileg lehet hasznalni
  69.  
  70. #define MAX_NODES 100
  71. #define MAX_NEIGHBOURS 6
  72. #define INVALID_NEIGHBOUR -1
  73. #define INVALID_NODE 0
  74. #define INITIAL_NODE 1
  75. #define RACE_CP_SIZE 12
  76.  
  77. #define yellow 0xffff00ff
  78. #define red 0xff0000ff
  79.  
  80. enum NodeStruct {
  81.     Float:X,
  82.     Float:Y,
  83.     Float:Z,
  84.     Neighbours[MAX_NEIGHBOURS]
  85. };
  86.  
  87. new NodeCount = INITIAL_NODE;
  88. new Float:Nodes[MAX_NODES][NodeStruct];
  89. new ShortestPath[MAX_PLAYERS][MAX_NODES];
  90. new PlayerPathNode[MAX_PLAYERS];
  91.  
  92. public OnFilterScriptInit()
  93. {
  94.     new File:nodes = fopen("nodes.txt", io_read);
  95.     if (!nodes) {
  96.         printf("A nodes.txt fajl nem talalhato!");
  97.         return 0;
  98.     }
  99.     new buffer[128];
  100.     while (fread(nodes, buffer)) {
  101.         sscanf(buffer, "fffiiiiii", Nodes[NodeCount][X], Nodes[NodeCount][Y], Nodes[NodeCount][Z], Nodes[NodeCount][Neighbours][0], Nodes[NodeCount][Neighbours][1], Nodes[NodeCount][Neighbours][2], Nodes[NodeCount][Neighbours][3], Nodes[NodeCount][Neighbours][4], Nodes[NodeCount][Neighbours][5]);
  102.         new formatstring[128];
  103.         format(formatstring, 128, "Node #{FF0000}%i", NodeCount);
  104.         CreateDynamic3DTextLabel(formatstring, yellow, Nodes[NodeCount][X], Nodes[NodeCount][Y], Nodes[NodeCount][Z], 150);
  105.         //CreateDynamicMapIcon(Nodes[NodeCount][X], Nodes[NodeCount][Y], Nodes[NodeCount][Z], 0, yellow);
  106.         NodeCount++;
  107.     }
  108.     fclose(nodes);
  109.     return 1;
  110. }
  111.  
  112. public OnPlayerClickMap(playerid, Float:fX, Float:fY, Float:fZ)
  113. {
  114.     new Float:x, Float:y, Float:z;
  115.     if (IsPlayerInAnyVehicle(playerid)) GetVehiclePos(GetPlayerVehicleID(playerid), x, y, z);
  116.     else GetPlayerPos(playerid, x, y, z);
  117.     new c_player = GetClosestNodeFromPoint(x,y,z);
  118.     printf("Jatekoshoz kozel eso node: %i", c_player);
  119.     new c_waypoint = GetClosestNodeFromPoint(fX,fY,fZ);
  120.     printf("Waypoint-hoz kozel eso node: %i", c_waypoint);
  121.     printf("Dijkstra: %i-tol %i-ig...", c_player, c_waypoint);
  122.     new PathNodeCount = Dijkstra(c_player, c_waypoint, ShortestPath[playerid]);
  123.     if (PathNodeCount == 0) return 1;
  124.     PlayerPathNode[playerid] = PathNodeCount-1;
  125.     new CurrentNode = ShortestPath[playerid][PlayerPathNode[playerid]];
  126.     if (PathNodeCount == 1) SetPlayerRaceCheckpoint(playerid, 1, Nodes[CurrentNode][X], Nodes[CurrentNode][Y], Nodes[CurrentNode][Z], 0, 0, 0, RACE_CP_SIZE);
  127.     else {
  128.         new NextNode = ShortestPath[playerid][--PlayerPathNode[playerid]];
  129.         SetPlayerRaceCheckpoint(playerid, 0, Nodes[CurrentNode][X], Nodes[CurrentNode][Y], Nodes[CurrentNode][Z], Nodes[NextNode][X], Nodes[NextNode][Y], Nodes[NextNode][Z], RACE_CP_SIZE);
  130.     }
  131.     SendClientMessage(playerid, yellow, "Navigacio elinditva, kovesd a checkpointokat!");
  132.     return 1;
  133. }
  134.  
  135. public OnPlayerEnterRaceCheckpoint(playerid)
  136. {
  137.     if (PlayerPathNode[playerid] == -1) {
  138.         DisablePlayerRaceCheckpoint(playerid);
  139.         SendClientMessage(playerid, yellow, "Megerkeztel!");
  140.         return 1;
  141.     }
  142.     new CurrentNode = ShortestPath[playerid][PlayerPathNode[playerid]];
  143.     if (PlayerPathNode[playerid] == 0) {
  144.         SetPlayerRaceCheckpoint(playerid, 1, Nodes[CurrentNode][X], Nodes[CurrentNode][Y], Nodes[CurrentNode][Z], 0, 0, 0, RACE_CP_SIZE);
  145.         PlayerPathNode[playerid]--;
  146.     } else {
  147.         new NextNode = ShortestPath[playerid][--PlayerPathNode[playerid]];
  148.         SetPlayerRaceCheckpoint(playerid, 0, Nodes[CurrentNode][X], Nodes[CurrentNode][Y], Nodes[CurrentNode][Z], Nodes[NextNode][X], Nodes[NextNode][Y], Nodes[NextNode][Z], RACE_CP_SIZE);
  149.     }
  150.     return 1;
  151. }
  152.  
  153. public OnPlayerCommandText(playerid, cmdtext[])
  154. {
  155.     if (strcmp("/closestnode", cmdtext, true) == 0)
  156.     {
  157.         new Float:x, Float:y, Float:z;
  158.         if (IsPlayerInAnyVehicle(playerid)) GetVehiclePos(GetPlayerVehicleID(playerid), x, y, z);
  159.         else GetPlayerPos(playerid, x, y, z);
  160.         new id = GetClosestNodeFromPoint(x,y,z);
  161.         if (IsPlayerInAnyVehicle(playerid)) SetVehiclePos(GetPlayerVehicleID(playerid), Nodes[id][X], Nodes[id][Y], Nodes[id][Z]);
  162.         else SetPlayerPos(playerid, Nodes[id][X], Nodes[id][Y], Nodes[id][Z]);
  163.         return 1;
  164.     }
  165.    
  166.     if (strcmp("/savenodes", cmdtext, true, 10) == 0)
  167.     {
  168.         new File:nodes = fopen("nodes.txt", io_append);
  169.         new formatstring[128];
  170.         for (new i = INITIAL_NODE; i < NodeCount; i++) {
  171.             format(formatstring, 128, "%f,%f,%f,%i,%i,%i,%i,%i,%i NODE #%i\n", Nodes[i][X], Nodes[i][Y], Nodes[i][Z], Nodes[i][Neighbours][0], Nodes[i][Neighbours][1], Nodes[i][Neighbours][2], Nodes[i][Neighbours][3], Nodes[i][Neighbours][4], Nodes[i][Neighbours][5], i);
  172.             fwrite(nodes, formatstring);
  173.         }
  174.         fclose(nodes);
  175.         SendClientMessage(playerid, yellow, "Node-ok mentve a nodes.txt-be!");
  176.         return 1;
  177.     }
  178.  
  179.     if (strcmp("/node", cmdtext, true, 10) == 0){
  180.         new Float:x, Float:y, Float:z;
  181.         if (IsPlayerInAnyVehicle(playerid)) GetVehiclePos(GetPlayerVehicleID(playerid), x, y, z);
  182.         else GetPlayerPos(playerid, x, y, z);
  183.         Nodes[NodeCount][X] = x;
  184.         Nodes[NodeCount][Y] = y;
  185.         Nodes[NodeCount][Z] = z;
  186.         for (new i = 0; i < MAX_NEIGHBOURS; i++) Nodes[NodeCount][Neighbours][i] = INVALID_NEIGHBOUR;
  187.         new formatstring[128];
  188.         format(formatstring, 128, "Node #{FF0000}%i", NodeCount);
  189.         CreateDynamic3DTextLabel(formatstring, yellow, x, y, z, 150);
  190.         CreateDynamicMapIcon(x, y, z, 0, yellow);
  191.         format(formatstring, 128, "Node #%i elkeszitve", NodeCount);
  192.         SendClientMessage(playerid, yellow, formatstring);
  193.         NodeCount++;
  194.         return 1;
  195.     }
  196.    
  197.     if (strcmp("/neighbour", cmdtext, true, 10) == 0){
  198.         new Float:x, Float:y, Float:z;
  199.         if (IsPlayerInAnyVehicle(playerid)) {
  200.             GetVehiclePos(GetPlayerVehicleID(playerid), x, y, z);
  201.         } else {
  202.             GetPlayerPos(playerid, x, y, z);
  203.         }
  204.         Nodes[NodeCount][X] = x;
  205.         Nodes[NodeCount][Y] = y;
  206.         Nodes[NodeCount][Z] = z;
  207.         for (new i = 0; i < MAX_NEIGHBOURS; i++) Nodes[NodeCount][Neighbours][i] = INVALID_NEIGHBOUR;
  208.         new formatstring[128];
  209.         format(formatstring, 128, "Node #{FF0000}%i", NodeCount);
  210.         CreateDynamic3DTextLabel(formatstring, yellow, x, y, z, 150);
  211.         CreateDynamicMapIcon(x, y, z, 0, yellow);
  212.  
  213.         // baszakodas addig, amig vannak parameterei a parancsnak
  214.         new neighbours[32];
  215.         new params = 0;
  216.         new index = strlen("/neighbour");
  217.         new tmp[32], tmplen = 0;
  218.         while (cmdtext[index] || tmplen) {
  219.             new ch = cmdtext[index];
  220.             if (ch == ' ' || ch == '\0') {
  221.                 if (tmplen) {
  222.                     params++;
  223.                     if (params > MAX_NEIGHBOURS) {
  224.                         SendClientMessage(playerid, red, "Szomszedok felso hatara: 6");
  225.                         return 1;
  226.                     }
  227.                     new nodeid = strval(tmp);
  228.                     format(neighbours, 32, "%s #%i", neighbours, nodeid);
  229.                     new bool:success = false;
  230.                     for (new i = 0; i < MAX_NEIGHBOURS; i++) {
  231.                         if (Nodes[nodeid][Neighbours][i] == INVALID_NEIGHBOUR) {
  232.                             Nodes[nodeid][Neighbours][i] = NodeCount;
  233.                             success = true;
  234.                             break;
  235.                         }
  236.                     }
  237.                     if (!success) {
  238.                         format(formatstring, 128, "A #%i node elerte a szomszedok maximalis szamat!", nodeid);
  239.                         SendClientMessage(playerid, red, formatstring);
  240.                         return 1;
  241.                     } else {
  242.                         for (new i = 0; i < MAX_NEIGHBOURS; i++) {
  243.                             if (Nodes[NodeCount][Neighbours][i] == INVALID_NEIGHBOUR) {
  244.                                 Nodes[NodeCount][Neighbours][i] = nodeid;
  245.                                 success = true;
  246.                                 break;
  247.                             }
  248.                         }
  249.                     }
  250.                     /*format(formatstring, 128, "param: %s", tmp);
  251.                     SendClientMessage(playerid, yellow, formatstring);*/
  252.                     for (new i = 0; tmp[i]; i++) tmp[i] = '\0';
  253.                     tmplen = 0;
  254.                     if (ch == '\0') break;
  255.                 }
  256.             }
  257.             else tmp[tmplen++] = ch;
  258.             index++;
  259.         }
  260.         format(formatstring, 128, "Node #%i letrehozva, szomszedai: %s", NodeCount, neighbours);
  261.         SendClientMessage(playerid, yellow, formatstring);
  262.         NodeCount++;
  263.         return 1;
  264.     }
  265.     return 0;
  266. }
  267.  
  268. // ket pont tavolsagat szamitja ki a Pitagorasz tetel segitsegevel
  269. stock Float:Dist(Float:x1,Float:y1,Float:z1,Float:x2,Float:y2,Float:z2) {
  270.     return floatsqroot(floatpower((x2-x1),2)+floatpower((y2-y1),2)+floatpower((z2-z1),2));
  271. }
  272.  
  273. // megvaltoztatja egy mapicon szinet
  274. stock ChangeDynamicMapIconColor(id, color) {
  275.     return Streamer_SetIntData(STREAMER_TYPE_MAP_ICON, id, E_STREAMER_COLOR, color);
  276. }
  277.  
  278. // megadja a ponthoz legkozelebbi node-ot
  279. stock GetClosestNodeFromPoint(Float:x, Float:y, Float:z) {
  280.     new nodeid = INVALID_NODE, Float:mindist = Float:FLOAT_INFINITY;
  281.     for (new i = 1; i < NodeCount; i++) {
  282.         new Float:dist = Dist(x,y,z, Nodes[i][X], Nodes[i][Y], Nodes[i][Z]);
  283.         if (dist < mindist) {
  284.             mindist = dist;
  285.             nodeid = i;
  286.         }
  287.     }
  288.     return nodeid;
  289. }
  290.  
  291. // Dijkstra algoritmus implementacioja
  292. // a source a kiindulo node, a target pedig a cel node, ezek kozott kell a legjobb ut
  293. // a kod a wikipedian talalhato Pseudocode alapjan lett implementalva
  294. stock Dijkstra(source, target, result[]) {
  295.     new Float:dist[MAX_NODES], prev[MAX_NODES], bool:visited[MAX_NODES], visited_nodes = 0;
  296.     for (new v = INITIAL_NODE; v < NodeCount; v++) { // Initialization
  297.         dist[v] = FLOAT_INFINITY; // Unknown distance from source to v
  298.         prev[v] = INVALID_NODE; // Previous node in optimal path from source
  299.         visited[v] = false; // All nodes initially in Q (unvisited nodes)
  300.     }
  301.     dist[source] = 0; // Distance from source to source
  302.     while (visited_nodes < (NodeCount-1)) {
  303.         new u = INVALID_NODE, Float:mindist = FLOAT_INFINITY;
  304.         for (new v = INITIAL_NODE; v < NodeCount; v++) {
  305.             if (!visited[v] && dist[v] < mindist) { // ez elso alkalommal nyilvanvaloan a kiindulo node-t fogja eredmenyezni, hisz az 0
  306.                 mindist = dist[v];
  307.                 u = v;
  308.             }
  309.         }
  310.         // megjegyezzuk, h ez a node mar meg volt latogatva, igy ne terjunk vissza feleslegessen hozza
  311.         visited[u] = true;
  312.         visited_nodes++;
  313.  
  314.         // ha a node a celallomas, akk meg is van a legjobb utvonal
  315.         if (u == target) {
  316.             new index = 0;
  317.             printf("A Dijkstra utvonalat talalt:");
  318.             while (prev[u] != INVALID_NODE) {
  319.                 result[index] = u;
  320.                 index++;
  321.                 printf("%i", u);
  322.                 u = prev[u];
  323.             }
  324.             result[index] = u;
  325.             printf("%i", u);
  326.             return index+1;
  327.         }
  328.  
  329.         // meg kell nezni u osszes meg nem latogatott v szomszedjat
  330.         for (new i = 0; i < MAX_NEIGHBOURS; i++) {
  331.             new v = Nodes[u][Neighbours][i];
  332.             if (v != INVALID_NEIGHBOUR && !visited[v]) { // where v is still in Q.
  333.                 new Float:alt = dist[u] + Dist(Nodes[u][X], Nodes[u][Y], Nodes[u][Z], Nodes[v][X], Nodes[v][Y], Nodes[v][Z]);
  334.                 if (alt < dist[v]) { // A shorter path to v has been found
  335.                     dist[v] = alt;
  336.                     prev[v] = u;
  337.                 }
  338.             }
  339.         }
  340.     }
  341.     return 0;
  342. }
  343.  
  344. // http://wiki.sa-mp.com/wiki/Sscanf_code
  345. // kicsit minimalizalva lett, csak a szukseges dolgokkal
  346. stock sscanf(string[], format[], {Float,_}:...)
  347. {
  348.     if (string[0] == 0 || (string[0] == 1 && string[1] == 0))return format[0];
  349.     new formatPos = 0,stringPos = 0,paramPos = 2,paramCount = numargs(),delim = ',';
  350.     while (string[stringPos] && string[stringPos] <= ' ')stringPos++;
  351.     while (paramPos < paramCount && string[stringPos])
  352.     {
  353.         switch (format[formatPos++])
  354.         {
  355.             case '\0':return 0;
  356.             case 'i', 'd': {
  357.                 new neg = 1,num = 0,ch = string[stringPos];
  358.                 if (ch == '-'){
  359.                     neg = -1;
  360.                     ch = string[++stringPos];
  361.                 }do{
  362.                     stringPos++;
  363.                     if ('0' <= ch <= '9')num = (num * 10) + (ch - '0');
  364.                     else return -1;
  365.                 }
  366.                 while ((ch = string[stringPos]) > ' ' && ch != delim);
  367.                 setarg(paramPos, 0, num * neg);
  368.             }
  369.             case 'f':{
  370.                 new changestr[16], changepos = 0, strpos = stringPos;
  371.                 while(changepos < 16 && string[strpos] && string[strpos] != delim)
  372.                     changestr[changepos++] = string[strpos++];
  373.                 changestr[changepos] = '\0';
  374.                 setarg(paramPos,0,_:floatstr(changestr));
  375.             }
  376.             case 'p': {
  377.                 delim = format[formatPos++];
  378.                 continue;
  379.             }
  380.             case '\'':{
  381.                 new end = formatPos - 1, ch;
  382.                 while ((ch = format[++end]) && ch != '\'') {}
  383.                 if (!ch)return -1;
  384.                 format[end] = '\0';
  385.                 if ((ch = strfind(string, format[formatPos], false, stringPos)) == -1){
  386.                     if (format[end + 1])return -1;
  387.                     return 0;
  388.                 }
  389.                 format[end] = '\'';
  390.                 stringPos = ch + (end - formatPos);
  391.                 formatPos = end + 1;
  392.             }
  393.             default:continue;
  394.         }
  395.         while (string[stringPos] && string[stringPos] != delim && string[stringPos] > ' ')stringPos++;
  396.         while (string[stringPos] && (string[stringPos] == delim || string[stringPos] <= ' '))stringPos++;
  397.         paramPos++;
  398.     }do{
  399.         if ((delim = format[formatPos++]) > ' '){
  400.             if (delim == '\'')while ((delim = format[formatPos++]) && delim != '\'') {}
  401.             else if (delim != 'z')return delim;
  402.         }
  403.     }
  404.     while (delim > ' ');
  405.     return 0;
  406. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement