Advertisement
Synchr0

Base Race Script

Nov 16th, 2012
638
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 16.15 KB | None | 0 0
  1. /*----------------------------------------------------------------------------*\
  2.                     Base Race Script - FilterScript
  3. @Description:
  4.     A base of a race-system with player positions.
  5. @Legal:
  6.     This Source Code Form is subject to the terms of the Mozilla Public
  7.     License, v. 2.0. If a copy of the MPL was not distributed with this
  8.     file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9.  
  10.     The Initial Developer of this Code is Lucas "Larceny" Godoy.
  11.     Codes created by the Initial Developer are Copyright (C) 2012
  12.     the Initial Developer.
  13.                                             All Rights Reserved.
  14. @Version:
  15.     1.0 - 19:47 14/11/2012 - lines: 246
  16.     1.1 - 23:57 14/11/2012 - lines: 287
  17.     1.2 - 12:58 15/11/2012 - lines: 315
  18.     1.3 - 14:52 16/11/2012 - lines: 359
  19.     1.4 - 16:36 16/11/2012 - lines: 478
  20. @Change-log:
  21.     1.1:
  22.         Message to all of what position the player finished and bugs fixed.
  23.     1.2:
  24.         Command to reset race.
  25.     1.3:
  26.         MAX_CHECKPOINT_DISTANCE definition, improvements at checkings and
  27.         bonus to the first three winners.
  28.     1.4:
  29.         Show how much time the player took to end the race and
  30.         minor changes.
  31. @Author:
  32.     Lucas "Larceny" Godoy
  33. @Thanks-to:
  34.     Slice, ----------> md-sort and some codes from his post
  35.     Yagu,------------> SetPlayerCheckpoint code
  36.     Y_Less,----------> y_commands and y_timers includes
  37.     Gustavo Araújo, -> Beta-testing and hosting the server to testing
  38.     Lós, ------------> Beta-testing
  39.     Lucas Silva, ----> Beta-testing
  40.     Murilo Sousa, ---> Giving me the idea of making this script
  41.     SA-MP Team ------> (c) SA-MP
  42. \*----------------------------------------------------------------------------*/
  43.  
  44. /*----------------------------------------------------------------------------*\
  45.     This is a filterscript.
  46. \*----------------------------------------------------------------------------*/
  47. #define FILTERSCRIPT
  48.  
  49. /*----------------------------------------------------------------------------*\
  50.     More definitions
  51. \*----------------------------------------------------------------------------*/
  52. static const Airrace        = 0;
  53. static const Float:CPsize   = 3.5;
  54.  
  55. #define IsPlayerInRace(%0) g_ePlayerRaceData[%0][isInRace]
  56.  
  57. // The maximum distance that a checkpoint can be from other one
  58. #define MAX_CHECKPOINT_DISTANCE 1000.0
  59.  
  60. /*----------------------------------------------------------------------------*\
  61.     Variables declarations
  62. \*----------------------------------------------------------------------------*/
  63. new g_players_in_race;
  64. new g_players_win_pos;
  65.  
  66. /*----------------------------------------------------------------------------*\
  67.     Importing inc files...
  68. \*----------------------------------------------------------------------------*/
  69. #include <a_samp>
  70. #include <md-sort>
  71. #include <YSI\y_timers>
  72. #include <YSI\y_iterate>
  73. #include <YSI\y_commands>
  74.  
  75. /*----------------------------------------------------------------------------*\
  76.     Forward declarations
  77. \*----------------------------------------------------------------------------*/
  78. forward SetRaceCheckpoint(playerid, target, next);
  79.  
  80. /*----------------------------------------------------------------------------*\
  81.     Checkpoint positions
  82. \*----------------------------------------------------------------------------*/
  83. new Float:g_fCheckpointPositions[][] = {
  84.     {2045.9878, 1255.0852, 10.3989},
  85.     {2045.6395, 1143.7676, 10.3990},
  86.     {2045.2872, 1022.4197, 10.3990},
  87.     {2045.5452, 874.15550, 6.70830},
  88.     {2066.6753, 869.71150, 6.60710},
  89.     {2068.1384, 990.57460, 10.3970},
  90.     {2069.2429, 1156.9362, 10.4019},
  91.     {2069.7380, 1361.6147, 10.3986},
  92.     {2070.2107, 1587.7080, 10.4068},
  93.     {2128.6960, 1828.0879, 10.3990},
  94.     {2146.8923, 2037.6427, 10.3990},
  95.     {2146.8491, 2213.1565, 10.3990},
  96.     {2179.2429, 2344.7166, 10.3989},
  97.     {2106.0913, 2285.1643, 10.3989},
  98.     {2128.9253, 2082.8274, 10.3990},
  99.     {2083.6333, 1775.9579, 10.3990},
  100.     {2048.1340, 1524.6210, 10.3990},
  101.     {2047.9237, 1390.8652, 10.3990}
  102. };
  103.  
  104. /*----------------------------------------------------------------------------*\
  105.     Player definitions
  106. \*----------------------------------------------------------------------------*/
  107.  enum E_RACE_DATA
  108.  {
  109.     PlayerID,
  110.     PlayerCP,
  111.     isInRace,
  112.     PlayerPos,
  113.     PlayerTime,
  114.     Float:DistanceToFinish
  115.  }
  116.  new g_ePlayerRaceData[MAX_PLAYERS][E_RACE_DATA];
  117.  
  118. /*----------------------------------------------------------------------------*\
  119.     This callback is called when the filterscript is initialized.
  120.    
  121.     Param:
  122.         -
  123. \*----------------------------------------------------------------------------*/
  124. public OnFilterScriptInit()
  125. {
  126.     print   ("\n");
  127.     print   ("|-------------------------------------------|");
  128.     print   ("|                                           |");
  129.     print   ("| Base Race Script Filterscript by (c) Larc'|");
  130.     printf  ("| Running Version: 1.4                      |");
  131.     print   ("|                                           |");
  132.     print   ("|-------------------------------------------|\n");
  133.     return 1;
  134. }
  135.  
  136. /*----------------------------------------------------------------------------*\
  137.     This callback is called when the filterscript is turned off.
  138.    
  139.     Param:
  140.         -
  141. \*----------------------------------------------------------------------------*/
  142. public OnFilterScriptExit()
  143. {
  144.     return 1;
  145. }
  146.  
  147. /*----------------------------------------------------------------------------*\
  148.     This callback is called when a player connects to the server.
  149.    
  150.     Param:
  151.         - playerid: ID of the player that has connected.
  152. \*----------------------------------------------------------------------------*/
  153. public OnPlayerConnect(playerid)
  154. {
  155.     g_ePlayerRaceData[playerid][isInRace] = 0;
  156.     g_ePlayerRaceData[playerid][DistanceToFinish] =
  157.                                             (2147482646.0 + float(playerid));
  158.     return 1;
  159. }
  160.  
  161. /*----------------------------------------------------------------------------*\
  162.     This callback is called when a player disconnects of the server.
  163.    
  164.     Param:
  165.         - playerid: ID of the player that has connected.
  166. \*----------------------------------------------------------------------------*/
  167. public OnPlayerDisconnect(playerid, reason)
  168. {
  169.     if(g_ePlayerRaceData[playerid][isInRace] == 1)
  170.     {
  171.         g_players_in_race--;
  172.         g_ePlayerRaceData[playerid][isInRace] = 0;
  173.         g_ePlayerRaceData[playerid][DistanceToFinish] =
  174.                                             (2147482646.0 + float(playerid));
  175.     }
  176.     return 1;
  177. }
  178.  
  179. /*----------------------------------------------------------------------------*\
  180.     This callback is called every-time a client/player updates the server with
  181.     their status.
  182.    
  183.     Param:
  184.         - playerid: ID of the player whom has been updated.
  185. \*----------------------------------------------------------------------------*/
  186. public OnPlayerUpdate(playerid)
  187. {
  188.     if(g_ePlayerRaceData[playerid][isInRace] == 1)
  189.     {
  190.         new Float:fDistance = GetPlayerDistanceFromPoint(playerid,
  191.             g_fCheckpointPositions[g_ePlayerRaceData[playerid][PlayerCP]][0],
  192.             g_fCheckpointPositions[g_ePlayerRaceData[playerid][PlayerCP]][1],
  193.             g_fCheckpointPositions[g_ePlayerRaceData[playerid][PlayerCP]][2]);
  194.  
  195.         g_ePlayerRaceData[playerid][DistanceToFinish] =
  196.             ( fDistance + MAX_CHECKPOINT_DISTANCE ) +
  197.             ((sizeof(g_fCheckpointPositions) * MAX_CHECKPOINT_DISTANCE) -
  198.             (g_ePlayerRaceData[playerid][PlayerCP] * MAX_CHECKPOINT_DISTANCE));
  199.     }
  200.     return 1;
  201. }
  202.  
  203. /*----------------------------------------------------------------------------*\
  204.     from Yagu's race filterscript, (c) by Yagu
  205.    
  206.     Param:
  207.         -
  208. \*----------------------------------------------------------------------------*/
  209. public SetRaceCheckpoint(playerid, target, next)
  210. {
  211.      if(next == -1 && Airrace == 0)
  212.          SetPlayerRaceCheckpoint(playerid, 1, g_fCheckpointPositions[target][0],
  213.             g_fCheckpointPositions[target][1],g_fCheckpointPositions[target][2],
  214.             0.0, 0.0, 0.0, CPsize);
  215.      else if(next == -1 && Airrace == 1)
  216.          SetPlayerRaceCheckpoint(playerid, 4, g_fCheckpointPositions[target][0],
  217.             g_fCheckpointPositions[target][1],g_fCheckpointPositions[target][2],
  218.             0.0, 0.0, 0.0, CPsize);
  219.      else if(Airrace == 1)
  220.          SetPlayerRaceCheckpoint(playerid, 3, g_fCheckpointPositions[target][0],
  221.             g_fCheckpointPositions[target][1],g_fCheckpointPositions[target][2],
  222.             g_fCheckpointPositions[next][0], g_fCheckpointPositions[next][1],
  223.             g_fCheckpointPositions[next][2], CPsize);
  224.      else
  225.          SetPlayerRaceCheckpoint(playerid, 0, g_fCheckpointPositions[target][0],
  226.             g_fCheckpointPositions[target][1],g_fCheckpointPositions[target][2],
  227.             g_fCheckpointPositions[next][0],g_fCheckpointPositions[next][1],
  228.             g_fCheckpointPositions[next][2], CPsize);
  229. }
  230.  
  231. /*----------------------------------------------------------------------------*\
  232.     This callback is called when a player enter in a race checkpoint.
  233.    
  234.     Param:
  235.         - playerid: ID of the player whom has entered in a r-cp.
  236. \*----------------------------------------------------------------------------*/
  237. public OnPlayerEnterRaceCheckpoint(playerid)
  238. {
  239.     g_ePlayerRaceData[playerid][PlayerCP]++;
  240.     if(g_ePlayerRaceData[playerid][PlayerCP] ==
  241.        sizeof(g_fCheckpointPositions)-1)
  242.     {
  243.         SetRaceCheckpoint(playerid, g_ePlayerRaceData[playerid][PlayerCP], -1);
  244.     }
  245.     else if(g_ePlayerRaceData[playerid][PlayerCP] ==
  246.             sizeof(g_fCheckpointPositions))
  247.     {
  248.         g_players_win_pos++;
  249.         DisablePlayerRaceCheckpoint(playerid);
  250.         g_ePlayerRaceData[playerid][isInRace] = 0;
  251.         g_ePlayerRaceData[playerid][DistanceToFinish] = g_players_win_pos;
  252.  
  253.         new sTextToSend[144], sPlayerName[MAX_PLAYER_NAME], nWinnerBonus;
  254.         GetPlayerName(playerid, sPlayerName, MAX_PLAYER_NAME);
  255.  
  256.         nWinnerBonus = 4000 - (g_players_win_pos * 1000);
  257.  
  258.         if(g_players_win_pos < 4)
  259.         {
  260.             format(sTextToSend, sizeof(sTextToSend),
  261.             "- %s finalizou a corrida em %iº lugar e ganhou $%i. \
  262.             Tempo: %s", sPlayerName, g_players_win_pos, nWinnerBonus,
  263.             convertTime(gettime() - g_ePlayerRaceData[playerid][PlayerTime]));
  264.  
  265.             GivePlayerMoney(playerid, nWinnerBonus);
  266.         }
  267.         else
  268.         {
  269.             format(sTextToSend, sizeof(sTextToSend),
  270.             "- %s finalizou a corrida em %iº lugar.",
  271.             sPlayerName, g_players_win_pos);
  272.         }
  273.  
  274.         SendClientMessageToAll(-1, sTextToSend);
  275.     }
  276.     else
  277.     {
  278.         SetRaceCheckpoint(playerid, g_ePlayerRaceData[playerid][PlayerCP],
  279.             g_ePlayerRaceData[playerid][PlayerCP]+1);
  280.     }
  281.     return 1;
  282. }
  283.  
  284. /*----------------------------------------------------------------------------*\
  285.     from Slice's md-sort post, (c) by Slice
  286.    
  287.     Param:
  288.         -
  289. \*----------------------------------------------------------------------------*/
  290. Comparator:CompareDistanceToFinish(left[E_RACE_DATA], right[E_RACE_DATA])
  291. {
  292.     // Returning negative means "left goes above"
  293.     // Positive means "left goes below"
  294.     // floatcmp returns -1 if right > left, 0 if equal, and 1 if left > right
  295.     return floatcmp(left[DistanceToFinish], right[DistanceToFinish]);
  296. }
  297.  
  298. /*----------------------------------------------------------------------------*\
  299.     This task is called every second.
  300.    
  301.     Param:
  302.         -
  303. \*----------------------------------------------------------------------------*/
  304. task OnClientUpdate[1000]()
  305. {
  306.     new sorted_racers[MAX_PLAYERS];
  307.     SortArrayUsingComparator(g_ePlayerRaceData, CompareDistanceToFinish, SORT_IS_PLAYERS) => sorted_racers;
  308.  
  309.     for (new i = 0; i < sizeof(sorted_racers); i++)
  310.     {
  311.         new playerid = sorted_racers[i];
  312.  
  313.         // All valid player IDs are at the start of the array,
  314.         // so the first invalid one means the rest will be, too.
  315.         if (playerid == INVALID_PLAYER_ID)
  316.             break;
  317.  
  318.         // do stuff with "playerid"
  319.  
  320.         if(g_ePlayerRaceData[playerid][isInRace] == 1)
  321.         {
  322.             new sTextToSend[96];
  323.             format(sTextToSend, sizeof(sTextToSend),
  324.                 "~n~~n~~n~~n~~n~~n~~n~~n~                             \          
  325.                    ~b~~h~%i ~w~/ %i",
  326.                 i+1, g_players_in_race);
  327.  
  328.             GameTextForPlayer(playerid, sTextToSend, 1111, 3);
  329.             g_ePlayerRaceData[playerid][PlayerPos] = i+1;
  330.         }
  331.  
  332.     }
  333. }
  334.  
  335. /*----------------------------------------------------------------------------*\
  336.     This function convert unix time stamp to human-readable date
  337.  
  338.     Params:
  339.         - nTimeStamp: Unixtime to be converted
  340.  
  341.     (c) Larceny
  342. \*----------------------------------------------------------------------------*/
  343. convertTime(nTimeStamp)
  344. {
  345.     new
  346.         nYears  =   0,
  347.         nDays   =   0,
  348.         nMonths =   0,
  349.         nHours  =   0,
  350.         nMins   =   0,
  351.         nSecs   =   0,
  352.         sFormattedString[80];
  353.    
  354.     while(nTimeStamp > 31622400)
  355.     {
  356.         nTimeStamp -= 31536000;
  357.         nYears++;
  358.     }
  359.    
  360.     while(nTimeStamp > 86400)
  361.     {
  362.         nTimeStamp -= 86400;
  363.         nDays++;
  364.         if(nDays == 31) nDays = 0, nMonths++;
  365.     }
  366.    
  367.     while(nTimeStamp > 60)
  368.     {
  369.         nTimeStamp -= 60;
  370.         nMins++;
  371.         if(nMins == 60) nMins = 0, nHours++;
  372.     }
  373.    
  374.     nSecs = nTimeStamp;
  375.    
  376.     if(nYears > 0)
  377.     {
  378.         format(sFormattedString, sizeof sFormattedString, "%02d anos, \
  379.         %02d meses, %02d dias, %02d horas, %02d minutos, %02d segundos",
  380.         nYears, nMonths, nDays, nHours, nMins, nSecs);
  381.     }
  382.     else if(nYears == 0 && nMonths > 0)
  383.     {
  384.         format(sFormattedString, sizeof sFormattedString, "\
  385.         %02d meses, %02d dias, %02d horas, %02d minutos, %02d segundos",
  386.         nMonths, nDays, nHours, nMins, nSecs);
  387.     }
  388.     else if(nYears == 0 && nMonths == 0 && nDays > 0)
  389.     {
  390.         format(sFormattedString, sizeof sFormattedString, "\
  391.         %02d dias, %02d horas, %02d minutos, %02d segundos",
  392.         nDays, nHours, nMins, nSecs);
  393.     }
  394.     else
  395.     {
  396.         format(sFormattedString, sizeof sFormattedString, "\
  397.         %02d horas, %02d minutos, %02d segundos",
  398.         nHours, nMins, nSecs);
  399.     }
  400.  
  401.     return sFormattedString;
  402. }
  403.  
  404. /*----------------------------------------------------------------------------*\
  405.     This command put the player in the race.
  406.    
  407.     Param:
  408.         -
  409. \*----------------------------------------------------------------------------*/
  410. YCMD:entrarcorrida(playerid, params[], help)
  411. {
  412.     if(IsPlayerInRace(playerid))
  413.         return SendClientMessage(playerid, -1, "- Você já está na corrida."), 1;
  414.  
  415.     if(g_ePlayerRaceData[playerid][DistanceToFinish] < MAX_CHECKPOINT_DISTANCE)
  416.         return SendClientMessage(playerid, -1,
  417.                 "- Você não pode mais entrar em corridas."), 1;
  418.  
  419.     g_players_in_race++;
  420.     g_ePlayerRaceData[playerid][PlayerCP]   = 0;
  421.     g_ePlayerRaceData[playerid][PlayerTime] = gettime();
  422.  
  423.     new Float:fDistance = GetPlayerDistanceFromPoint(playerid,
  424.             g_fCheckpointPositions[g_ePlayerRaceData[playerid][PlayerCP]][0],
  425.             g_fCheckpointPositions[g_ePlayerRaceData[playerid][PlayerCP]][1],
  426.             g_fCheckpointPositions[g_ePlayerRaceData[playerid][PlayerCP]][2]);
  427.  
  428.     g_ePlayerRaceData[playerid][DistanceToFinish] =
  429.         (fDistance + MAX_CHECKPOINT_DISTANCE) +
  430.         (sizeof(g_fCheckpointPositions) * MAX_CHECKPOINT_DISTANCE);
  431.  
  432.     g_ePlayerRaceData[playerid][isInRace] = 1;
  433.  
  434.     SetRaceCheckpoint(playerid, g_ePlayerRaceData[playerid][PlayerCP],
  435.         g_ePlayerRaceData[playerid][PlayerCP]+1);
  436.     return 1;
  437. }
  438.  
  439. /*----------------------------------------------------------------------------*\
  440.     This command put the player out of the race.
  441.    
  442.     Param:
  443.         -
  444. \*----------------------------------------------------------------------------*/
  445. YCMD:saircorrida(playerid, params[], help)
  446. {
  447.     g_players_in_race--;
  448.     g_ePlayerRaceData[playerid][isInRace] = 0;
  449.     g_ePlayerRaceData[playerid][DistanceToFinish] =
  450.                                             (2147482646.0 + float(playerid));
  451.     DisablePlayerRaceCheckpoint(playerid);
  452.     return 1;
  453. }
  454.  
  455. /*----------------------------------------------------------------------------*\
  456.     This command reset the race.
  457.    
  458.     Param:
  459.         -
  460. \*----------------------------------------------------------------------------*/
  461. YCMD:resetarcorrida(playerid, params[], help)
  462. {
  463.     g_players_in_race = 0;
  464.     foreach(new i: Player)
  465.     {
  466.         g_ePlayerRaceData[i][isInRace] = 0;
  467.         g_ePlayerRaceData[i][DistanceToFinish] =
  468.                                             (2147482646.0 + float(playerid));
  469.         DisablePlayerRaceCheckpoint(i);
  470.     }
  471.     SendClientMessageToAll(-1,
  472.     "- Corrida reiniciada, /entrarcorrida para entrar.");
  473.     return 1;
  474. }
  475.  
  476. /*----------------------------------------------------------------------------*\
  477.                             END OF FILE - (c) L "S" G
  478. \*----------------------------------------------------------------------------*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement