Guest User

Untitled

a guest
Dec 22nd, 2012
441
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 54.28 KB | None | 0 0
  1. #include <a_samp> //I'm pretty sure we all know what this line does. It adds the sa-mp natives :).
  2. #include <zcmd> //Could be y_cmd or something else. It's not hard to adapt the code but most people currently use ZCMD.
  3. #define MAX_RACES 25 //Maximum races will be 50, the lower the better due to array sizes - Change this higher if you need to
  4. #define MAX_CHECKPOINTS 150 //Maximum checkpoints will be 100, the lower the better due to array sizes - Change this higher if you need to
  5. #define WAIT_RACE 15 //The time in seconds between the opening of the race to the time that it starts
  6.  
  7. enum rInfo
  8. {
  9. //This enum is for anything related to the races themselves.
  10. racetimeout,
  11. //The above varible is the timeout in seconds before a race stops. We
  12. //use this so the lovely people that decide to just sit in a race don't
  13. //cause it to run forever.
  14. Float:checkpointx[MAX_CHECKPOINTS],
  15. Float:checkpointy[MAX_CHECKPOINTS],
  16. Float:checkpointz[MAX_CHECKPOINTS],
  17. //These will be the float positions of the checkpoints in a race.
  18. //All checkpoint positions will load into these arrays on startup.
  19. racename[100 char],
  20. //We use char to lower the array size to make the script more efficient
  21. //and use less memory that the sa-mp server could use for doing other things
  22. //We can use chars on strings because their values do not exceed 255.
  23. //For more information on char visit:
  24. //For example if racename[0] = 'a' then racename[0] would actually
  25. //be racename[0] = 97. This will reduce our array size by 4x. If you are
  26. //going to have race names over 100 characters then you should change
  27. //the 100 to a higher value.
  28. cpnum,
  29. //We need to know how many slots are currently being used in
  30. //the checkpoints array. We could use a loop everytime we
  31. //wanted to add more checkpoints to the array but this would
  32. //be very time wasting and pointless. the cpnum variable
  33. //gives us the amount of checkpoints in a race and the next
  34. //free cell in the checkpoints variable
  35. racevehicle,
  36. //The racevehicle variable isn't really needed but we will add it anyway.
  37. //This variable allows us to specify a specific vehicle for the race
  38. //such as an NRG or a specific boat if you're in a boat race. Later on
  39. //we will make it so that if the variable is 0 then there is no specific
  40. //vehicle needed.
  41. bool:racerunning,
  42. //The above is just a boolean that is true if the race is currently
  43. //running and false if it's not. We set it to true on race start and
  44. //false when the race is stopped.
  45. bool:racejoinable,
  46. //This variable is different to the one above because this is used if the
  47. //race is open but hasn't started yet. If the race hasn't started, this would
  48. //be true and racerunning would be false but if the race had started it would
  49. //be the oppisite.
  50. racetimer,
  51. //This is the timer id for the timeout for the race. This will be dynamic
  52. //and will change whenever the race is given a timer and set to start.
  53. //We need this variable so that we can cancel the timer if there is no
  54. //players before the timeout of the race.
  55. racecount,
  56. //This variable is to show the amount of players that are currently
  57. //in the race so when it hits 0 we can end the race if it hasn't
  58. //already timed out.
  59. originalcount,
  60. //This variable is static from the start to the end of the race because
  61. //it gives us the amount of people in the race when it started. This is used
  62. //for positioning in the race combined with the racecount. It wouldn't be a
  63. //race if we didn't have the race positions at the end :).
  64. racetime
  65. //This variable is just used to determine how long the race has been running
  66. //for and it will allow us to use the timeout timer as a double for the
  67. //time people have spent in the race. The race timer will run at 100ms and
  68. //give us our race time accurate to .1 of a second. When the race timer reaches
  69. //the timeout (if it does) then it will exit. It will be easier to understand
  70. //the code when you see it :P.
  71. };
  72.  
  73. new RaceInfo[MAX_RACES][rInfo];
  74. //The lovely variable that holds all race information required
  75. //For operating the races.
  76.  
  77. new currentraceslot;
  78. //The above variable tells us how many races we have loaded and the
  79. //next avalible slot that we can use in the array. This is very useful
  80. //so we don't have to create a loop to find this information.
  81.  
  82. new VehicleNames[212][] =
  83. {
  84. "Landstalker", "Bravura", "Buffalo", "Linerunner", "Perennial", "Sentinel",
  85. "Dumper", "Firetruck" , "Trashmaster" , "Stretch", "Manana", "Infernus",
  86. "Voodoo", "Pony", "Mule", "Cheetah", "Ambulance", "Leviathan", "Moonbeam",
  87. "Esperanto", "Taxi", "Washington", "Bobcat", "Mr Whoopee", "BF Injection",
  88. "Hunter", "Premier", "Enforcer", "Securicar", "Banshee", "Predator", "Bus",
  89. "Rhino", "Barracks", "Hotknife", "Trailer", "Previon", "Coach", "Cabbie",
  90. "Stallion", "Rumpo", "RC Bandit", "Romero", "Packer", "Monster", "Admiral",
  91. "Squalo", "Seasparrow", "Pizzaboy", "Tram", "Trailer", "Turismo", "Speeder",
  92. "Reefer", "Tropic", "Flatbed","Yankee", "Caddy", "Solair","Berkley's RC Van",
  93. "Skimmer", "PCJ-600", "Faggio", "Freeway", "RC Baron","RC Raider","Glendale",
  94. "Oceanic", "Sanchez", "Sparrow", "Patriot", "Quad", "Coastguard", "Dinghy",
  95. "Hermes", "Sabre", "Rustler", "ZR-350", "Walton", "Regina", "Comet", "BMX",
  96. "Burrito", "Camper", "Marquis", "Baggage", "Dozer","Maverick","News Chopper",
  97. "Rancher", "FBI Rancher", "Virgo", "Greenwood","Jetmax","Hotring","Sandking",
  98. "Blista Compact", "Police Maverick", "Boxville", "Benson","Mesa","RC Goblin",
  99. "Hotring Racer", "Hotring Racer", "Bloodring Banger", "Rancher", "Super GT",
  100. "Elegant", "Journey", "Bike", "Mountain Bike", "Beagle", "Cropdust", "Stunt",
  101. "Tanker", "RoadTrain", "Nebula", "Majestic", "Buccaneer", "Shamal", "Hydra",
  102. "FCR-900","NRG-500","HPV1000","Cement Truck","Tow Truck","Fortune","Cadrona",
  103. "FBI Truck", "Willard", "Forklift","Tractor","Combine","Feltzer","Remington",
  104. "Slamvan", "Blade", "Freight", "Streak","Vortex","Vincent","Bullet","Clover",
  105. "Sadler", "Firetruck", "Hustler", "Intruder", "Primo", "Cargobob", "Tampa",
  106. "Sunrise", "Merit", "Utility Truck", "Nevada", "Yosemite", "Windsor", "Monster",
  107. "Monster","Uranus","Jester","Sultan","Stratum","Elegy","Raindance","RCTiger",
  108. "Flash","Tahoma","Savanna", "Bandito", "Freight", "Trailer", "Kart", "Mower",
  109. "Dune", "Sweeper", "Broadway", "Tornado", "AT-400", "DFT-30", "Huntley",
  110. "Stafford", "BF-400", "Newsvan","Tug","Trailer","Emperor","Wayfarer","Euros",
  111. "Hotdog", "Club", "Trailer", "Trailer","Andromada","Dodo","RC Cam", "Launch",
  112. "Police Car LSPD", "Police Car SFPD","Police Car LVPD","Police Ranger",
  113. "Picador", "S.W.A.T. Van", "Alpha", "Phoenix", "Glendale", "Sadler",
  114. "Luggage Trailer","Luggage Trailer","Stair Trailer", "Boxville", "Farm Plow",
  115. "Utility Trailer"
  116. };
  117. //A lovely array of all vehicle names by ?. This allows us to tell a person what
  118. //vehicle a race requires if it requires one.
  119.  
  120.  
  121. new RaceCheckpoint[MAX_PLAYERS];
  122. //This variable tells us what race checkpoint that the player is currently
  123. //in so that we can send him to the next checkpoint in the array.
  124.  
  125.  
  126. new InRace[MAX_PLAYERS];
  127. //The above will be either "true" or "false" whether the player is
  128. //currently racing or not. This variable is useful also because you
  129. //can integrate it into your script in other ways.
  130.  
  131. stock CreateRace(RaceName[], RaceTimeout, RaceVehicle = -1)
  132. {
  133. //This is the function that we will use to load our race information
  134. //into the variables themselves. We know that our variable currentraceslot
  135. //will give us the next slot that we can use freely. So lets load the
  136. //information that we have used in the function into our variables
  137. //I have put RaceVehicle = -1 so it's the default value which means that
  138. //we don't even need to specify it when creating a race, it's like an extra
  139. //thing like the draw distance of an object. You could just do the following
  140. //CreateRace("DEATH RACE :)", 300) to create a race with a timeout of 5 minutes
  141. //with any vehicle or CreateRace("DEATH RACE :)", 300, 411) for a race with
  142. //a specified vehicle. This will be shown more later on.
  143. format(RaceInfo[currentraceslot][racename], 100, "%s", RaceName);
  144. //We are inserting the function information of RaceName into our array
  145. //RaceInfo with the next avalible race slot. format just transfers one
  146. //string to another with ease. I was having issues with strcat for
  147. //some reason with char.
  148. RaceInfo[currentraceslot][racetimeout] = RaceTimeout;
  149. //The above is pretty much the same as I explained for the name.
  150. //We put the function information into the array. In this case
  151. //it's the timeout information into the timeout variable in the array
  152. RaceInfo[currentraceslot][racevehicle] = RaceVehicle;
  153. //Same as above. Loading the vehicle information into the array.
  154. RaceInfo[currentraceslot][racerunning] = false;
  155. //Sets the race running variable to false
  156. RaceInfo[currentraceslot][racejoinable] = false;
  157. //Sets the race joinable variable to false
  158. return currentraceslot, currentraceslot ++;
  159. //We return the array ID so we can use it to add checkpoints later.
  160. //It's the exact same thing you do with a pickup, you assign a variable
  161. //to the ID of the pickup so that you can identify it later. For example
  162. //new deathrace = CreateRace("DEATH RACE :)", 300); and we will be able to
  163. //add checkpoints using the variable deathrace. currentraceslot++ is just
  164. //adding 1 to the variable because we have used that slot.
  165. }
  166.  
  167. stock AddCheckpointToRace(RaceID, Float:CheckPointX, Float:CheckPointY, Float:CheckPointZ)
  168. {
  169. //This function adds information into the designated array using the race
  170. //id that was returned from the CreateRace function. We just add information
  171. //to the arrays using this function rather than doing it manually because it's far
  172. //easier this way. An example how this would look would be
  173. //new deathrace = CreateRace("Death Race", 300);
  174. //AddCheckpointToRace(deathrace, 1432.13, 312.311, 12.1);
  175. //Pretty straight forward and easy to understand.
  176. new nextcheckpointfree = RaceInfo[RaceID][cpnum];
  177. //The above variable just makes it look cleaner because it gets
  178. //the next free checkpoint slot in the array.
  179. RaceInfo[RaceID][checkpointx][nextcheckpointfree] = CheckPointX;
  180. RaceInfo[RaceID][checkpointy][nextcheckpointfree] = CheckPointY;
  181. RaceInfo[RaceID][checkpointz][nextcheckpointfree] = CheckPointZ;
  182. //Just putting the checkpoint locations from the function
  183. //into the correct race array and into the correct checkpoint array.
  184. //The variables go into the race ID defined and the next free checkpoint
  185. //id in that specific race. It's like inception but less confusing :).
  186. RaceInfo[RaceID][cpnum] ++;
  187. //We add one so that the script knows that we have used that checkpoint
  188. //slot up and to use the next one avalible.
  189. return 1;
  190. //We don't need to return a specific value unless you plan on editing
  191. //the checkpoints location later so we just return 1 :).
  192. }
  193.  
  194. public OnPlayerSpawn(playerid)
  195. {
  196. //This code just resets our player variables (InRace and RaceCheckpoint)
  197. InRace[playerid] = -1;
  198. //InRace is -1 if the player is not in any race or it will be a value > -1
  199. //if the player is actually in a race. This is also quite useful because
  200. //We could return the name of the race a player is in as well by using
  201. //RaceInfo[InRace[playerid]][racename] in a string :).
  202. RaceCheckpoint[playerid] = -1;
  203. //We use RaceCheckpoint = -1 to show no checkpoint at all. We cannot
  204. //have it at zero because in the array the first checkpoint is at 0 on
  205. //the start. When the player is actually in the starting checkpoint
  206. //and heading to the first checkpoint then this can be set to 0. The starting
  207. //checkpoint is #0 and the second one is #1. It will be easier to understand
  208. //when you see the code.
  209. return 1;
  210. }
  211.  
  212. //Before I start the next 6 functions I'll just go into a quick overview of what
  213. //they are in the first place so it's easier for you to understand what I'm trying
  214. //to do here. OpenRace is the first function which opens a race to allow players
  215. //to join to it. This will tell players they have WAIT_RACE amount of time to get
  216. //to the start checkpoint of the race. Start race is when the racing begins and
  217. //the timer starts counting down to the end of the race. OpenRace calls start
  218. //race with a WAIT_RACE seconds on the timer. So the race will start on StartRace
  219. //and end on the StopRace function. However if people drop out of the race by
  220. //death or other means then it will also call the StopRace function. The JoinRace
  221. //function is called when a player requests to join a race. LeaveRace is called
  222. //when a player dies, quits the game, quits the race or teleports if your server
  223. //allows it. The RaceTime timer goes at 100ms so that it can be used to show how
  224. //long the race has been running and also double as the timeout timer. It allows
  225. //us to use 1 timer instead of one for the race time and 1 for the timeout time.
  226.  
  227. stock OpenRace(raceid)
  228. {
  229. new RaceStr[128];
  230. //We create this string to format the string that will be sent to all
  231. //players when the race is joinable.
  232. if(RaceInfo[raceid][racevehicle] == -1) format(RaceStr, sizeof(RaceStr), "[RACE] The Race '%s' will start in %d seconds. Type /joinrace %d to join!", RaceInfo[raceid][racename], WAIT_RACE, raceid);
  233. if(RaceInfo[raceid][racevehicle] > 0) format(RaceStr, sizeof(RaceStr), "[RACE] The Race '%s' will start in %d seconds. Type /joinrace %d to join! A %s is required for this race.", RaceInfo[raceid][racename], WAIT_RACE, raceid, VehicleNames[RaceInfo[raceid][racevehicle]-400]);
  234. if(RaceInfo[raceid][racevehicle] == 0) format(RaceStr, sizeof(RaceStr), "[RACE] The Race '%s' will start in %d seconds. Type /joinrace %d to join! This is a onfoot race only.", RaceInfo[raceid][racename], WAIT_RACE, raceid);
  235. //We all probably know what format is and the above formats the message to
  236. //send a message that the race can be joined by typing /joinrace [raceid]
  237. //an example message would be something like the following:
  238. //[RACE]The Race 'Death Race' will start in 60 seconds. Type /joinrace 1 to join
  239. //Or if it requires a specific vehicle then it will add that on the end too.
  240. SendClientMessageToAll(0xFF00AA, RaceStr);
  241. //Sends the formatted message in yellow. You can easily change that colour =].
  242. RaceInfo[raceid][racejoinable] = true;
  243. //The above allows players to join the race. This will be set to false
  244. //when the race starts.
  245. SetTimerEx("StartRace", WAIT_RACE*1000, false, "d", raceid);
  246. //The above sets the timer for the start race function. There will be 60 seconds
  247. //before this function is actually called. StartRace is the function name,
  248. //we have WAIT_RACE*1000 because WAIT_RACE is in seconds and the timers work
  249. //in milliseconds (1 second = 1000 milliseconds).
  250. //We also pass the raceid to the function 60 seconds later.
  251. return 1;
  252. }
  253.  
  254. stock Float:AngleToPoint(Float:x2, Float:y2, Float:X, Float:Y)
  255. {
  256. //This function by ? is used so that we can face the vehicle in the correct angle
  257. //when we teleport the player to a race. This isn't a real biggie but it looks more
  258. //awesome. Explaining this will be a bit tricky but I'll try to a basic overview.
  259. //If you have ever done basic trig in class you will know that with two lengths
  260. //we can find out an angle of a triangle
  261. // /|
  262. // H / | A (Lets pretend that's a triangle)
  263. // ----
  264. // O
  265. //
  266. //using tan ( O / A) we can find the angle that we are meant to be facing at
  267. //The rest of the function just calculates the angles because we are not just
  268. //in a triangle, we have a circle around us. If you don't understand then it
  269. //is really no big issue. We use this function below.
  270. new Float:DX, Float:DY;
  271. new Float:angle;
  272. DX = floatabs(floatsub(x2,X));
  273. //Get the positive value of x2 - x (finding the length we need for the
  274. //'O' side or the oppisite side to the angle
  275. DY = floatabs(floatsub(y2,Y));
  276. //Get the positive value of y2 - y (finding the length we need for the
  277. //'A' side or the adjasent side to the angle
  278. if (DY == 0.0 || DX == 0.0)
  279. //If for some reason one length is zero then we do not need trig to complete
  280. //the function and we can just find the angle by determining what value is
  281. //the non-zero value. Pretty self explanitory.
  282. {
  283. if(DY == 0 && DX > 0) angle = 0.0;
  284. else if(DY == 0 && DX < 0) angle = 180.0;
  285. else if(DY > 0 && DX == 0) angle = 90.0;
  286. else if(DY < 0 && DX == 0) angle = 270.0;
  287. else if(DY == 0 && DX == 0) angle = 0.0;
  288. }
  289. else
  290. {
  291. angle = atan(DX/DY);
  292. //If we have both values (no zeros) then we have to use the TOA
  293. //tan(oppisite / adjacent) to find the angle required. We also have
  294. //to add to it to find the actual angle as if we where in a circle.
  295. //Sadly I cant fully explain it because it's hard to create a circle
  296. //but think of it as a triangle in a circle and we need to find the
  297. //full angle rather than just the angle of a specific segment.
  298. if(X > x2 && Y <= y2) angle += 90.0;
  299. else if(X <= x2 && Y < y2) angle = floatsub(90.0, angle);
  300. else if(X < x2 && Y >= y2) angle -= 90.0;
  301. else if(X >= x2 && Y > y2) angle = floatsub(270.0, angle);
  302. }
  303. return floatadd(angle, 90.0);
  304. }
  305.  
  306.  
  307.  
  308. stock JoinRace(playerid, raceid)
  309. {
  310. if(RaceInfo[raceid][racejoinable] == false) return SendClientMessage(playerid, 0xAA3333AA, "Race is currently not joinable!");
  311. //If the race isn't joinable then we send a message to the player that the
  312. //race cannot be joined right now and we stop them there.
  313. if(InRace[playerid] != -1) return SendClientMessage(playerid, 0xAA3333AA, "You are currently in a race! /leaverace before joining a new one!");
  314. //If the player is already in a race and trying to join another one it's
  315. //also a bit silly. The player has to first leave his current race before
  316. //going into another one. As you see, /leaverace will be our command
  317. //to leave the race :)
  318. if(GetVehicleModel(GetPlayerVehicleID(playerid)) != RaceInfo[raceid][racevehicle] && RaceInfo[raceid][racevehicle] != -1)
  319. {
  320. if(RaceInfo[raceid][racevehicle] == 0) return SendClientMessage(playerid, 0xAA3333AA, "You are not allowed vehicles in a foot race!");
  321. //If it's a foot race then it will send the player an error and stop here
  322. new RaceStr[75];
  323. //creates the string array
  324. format(RaceStr, sizeof(RaceStr), "You need to be in a %s to join this race!", VehicleNames[RaceInfo[raceid][racevehicle]-400]);
  325. //formats the string
  326. return SendClientMessage(playerid, 0xAA3333AA, RaceStr);
  327. //Or here you could always get rid of the return 1; and give the player
  328. //that specific vehicle that is required or for a running race, take
  329. //the players vehicle away from him/her. It's really up to you on
  330. //what you want to do here. What I have done is just denied enterance
  331. //to the race if the player is not in the required vehicle.
  332. }
  333. if(RaceInfo[raceid][racevehicle] == 0 && IsPlayerInAnyVehicle(playerid)) return SendClientMessage(playerid, 0xAA3333AA, "You are not allowed vehicles in this race!");
  334. //I just made this clause for running races or swimming races, whatever
  335. //floats your boat. Handy little addition and it's easy to add on. Just
  336. //CreateRace("Runnin' Race", 300, 0) to make a running race :).
  337. RaceCheckpoint[playerid] = 0;
  338. //Checkpoint set to 0 - First checkpoint
  339. InRace[playerid] = raceid;
  340. //Players race is set to the race he/she chose to join.
  341. if(IsPlayerInAnyVehicle(playerid))
  342. //We are going to check if the player is in any vehicle so that we can
  343. //then teleport that vehicle to the correct location + world. We do not
  344. //use world 0 as the race world as people would just ram people for the fun
  345. //of it.
  346. {
  347.  
  348. new vehicleid = GetPlayerVehicleID(playerid);
  349. //We fetch the players vehicle ID
  350. SetVehicleVirtualWorld(vehicleid, 1050005 + raceid);
  351. //We set the vehicle to a virtual world with 1050005 + the raceid like
  352. //we are going to do with the player too. I used 1050005 so it doesn't
  353. //overlap any worlds used by your script (hopefully). E.g. Race 20 would
  354. //be in world ID 10050025 etc...
  355. SetPlayerVirtualWorld(playerid, 1050005 + raceid);
  356. //Sets the player to the same virtual world as above
  357. PutPlayerInVehicle(playerid, vehicleid, 0);
  358. //We put the player in the vehicle just in case
  359. SetVehiclePos(vehicleid, RaceInfo[raceid][checkpointx][0], RaceInfo[raceid][checkpointy][0], RaceInfo[raceid][checkpointz][0]);
  360. //We set the vehicles position in the first checkpoint waiting for the race to start
  361. SetVehicleZAngle(vehicleid, AngleToPoint(RaceInfo[raceid][checkpointx][0], RaceInfo[raceid][checkpointy][0], RaceInfo[raceid][checkpointx][1], RaceInfo[raceid][checkpointy][1]));
  362. //The code above sets the angle of the vehicle towards the second checkpoint.
  363.  
  364. }
  365. else
  366. {
  367. SetPlayerVirtualWorld(playerid, 1050005 + raceid);
  368. SetPlayerFacingAngle(playerid, AngleToPoint(RaceInfo[raceid][checkpointx][0], RaceInfo[raceid][checkpointy][0], RaceInfo[raceid][checkpointx][1], RaceInfo[raceid][checkpointy][1]));
  369. SetPlayerPos(playerid, RaceInfo[raceid][checkpointx][0], RaceInfo[raceid][checkpointy][0], RaceInfo[raceid][checkpointz][0]);
  370. //Same as above with the cars. The angle of the player is set to the next
  371. //checkpoint so that they are not facing backwards when the race starts.
  372. //Actually, that would be pretty funny :P.
  373. }
  374. new RaceInfoString[75];
  375. format(RaceInfoString, sizeof(RaceInfoString), "~y~Joined the race! ~b~Please wait %d seconds for the race to start!", WAIT_RACE);
  376. //We have to format the amount of seconds before the race starts because it's
  377. //most likely going to change from 60 seconds that have been set.
  378. GameTextForPlayer(playerid, RaceInfoString, 3000, 3);
  379. //We send the player a nice on screen message telling them
  380. //that they have joined the race :).
  381. SetPlayerRaceCheckpoint(playerid, 0, RaceInfo[raceid][checkpointx][0], RaceInfo[raceid][checkpointy][0], RaceInfo[raceid][checkpointz][0], RaceInfo[raceid][checkpointx][1], RaceInfo[raceid][checkpointy][1], RaceInfo[raceid][checkpointz][1], 6);
  382. //This sets the starting checkpoint and it points to the direction that the
  383. //next checkpoint will be in. The player has to be in this checkpoint when
  384. //the race starts or they won't racing :P. Remember that our array ids start
  385. //at 0 rather than one.
  386. return 1;
  387. }
  388.  
  389. forward StartRace(raceid);
  390. public StartRace(raceid)
  391. {
  392. RaceInfo[raceid][racejoinable] = false;
  393. //We now make it so the race is no longer joinable by anyone else.
  394. for(new i; i<MAX_PLAYERS; i++)
  395. //if you have foreach then foreach (new i : Player) or make your own
  396. //illiterator for players in races. Just loops through everyone currently
  397. //that has tried to join the race
  398. {
  399. if(InRace[i] != raceid) continue;
  400. //skips anyone that isn't in the race that we are looking into.
  401. //continue just skips a certain id. For example if ID 5 wasn't in
  402. //our race so InRace[playerid] = -1 it would skip his ID and not check
  403. //any further.
  404. if(IsPlayerInRaceCheckpoint(i) && (GetVehicleModel(GetPlayerVehicleID(i)) == RaceInfo[raceid][racevehicle] || RaceInfo[raceid][racevehicle] == -1 ))
  405. //If the player is in the race we are looking at + the player is in
  406. //the checkpoint + the vehicle model is correct if there is one.
  407. {
  408. SetPlayerRaceCheckpoint(i, 0, RaceInfo[raceid][checkpointx][1], RaceInfo[raceid][checkpointy][1], RaceInfo[raceid][checkpointz][1], RaceInfo[raceid][checkpointx][2], RaceInfo[raceid][checkpointy][2], RaceInfo[raceid][checkpointz][2], 6);
  409. //The above line sets the players checkpoint from the start point
  410. //to the second checkpoint in the race. It also points to the direction
  411. //Of the third checkpoint RaceInfo[raceid][checkpoint[x][y][z]][2].
  412. //Remember that the first and starting checkpoint was used in the
  413. //Joinrace function with the index of 0. 0 is the first number in
  414. //our array rather than 1.
  415. RaceCheckpoint[i] = 2;
  416. //The players race checkpoint is set to checkpoint #1. As we see
  417. //above the race checkpoint is being set in the array as 1.
  418. RaceInfo[raceid][originalcount] ++;
  419. //We add to the originalcount so that we get the players in the race
  420. //This count does not change throughout the race and will be reset
  421. //at the end of the race on StopRace
  422. RaceInfo[raceid][racecount] ++;
  423. //This racecount variable will change whenever someone leaves the
  424. //race or finishes it. It helps us determine when to stop the race
  425. //and what position someone finishes in a certain race. This variable
  426. //will be changed over the course of the race.
  427. GameTextForPlayer(i, "~r~GO!!!!", 3000, 3);
  428. //We send the player a nice on screen text that tells them that
  429. //the race has started and they better get going :).
  430.  
  431. }
  432. else
  433. //The above code is if we find that the player isn't even in the checkpoint
  434. //when the race has started or the vehicle ID specified isn't the one that
  435. //the race allows.
  436. {
  437. RaceCheckpoint[i] = -1;
  438. //Race checkpoint reset
  439. InRace[i] = -1;
  440. //Player is put out of the race
  441. DisablePlayerRaceCheckpoint(i);
  442. //Players checkpoint is disabled.
  443. if(IsPlayerInAnyVehicle(i))
  444. //If the player was in a car
  445. {
  446. new vehicleid = GetPlayerVehicleID(i);
  447. //We fetch the players vehicle ID
  448. SetVehicleVirtualWorld(vehicleid, 0);
  449. //We reset the vehicles virtual world to 0
  450. SetPlayerVirtualWorld(i, 0);
  451. //Sets the player to virtual world 0 too
  452. PutPlayerInVehicle(i, vehicleid, 0);
  453. //We put the player in the vehicle just in case
  454. }
  455. else
  456. {
  457. SetPlayerVirtualWorld(i, 0);
  458. //If the player was on foot we just put him back to virtual
  459. //world 0.
  460.  
  461. }
  462. }
  463. }
  464. if(RaceInfo[raceid][originalcount] == 0) return 1;
  465. //The above code is executed if it's time for the race to start but we seem
  466. //to have nobody in the race checkpoint with the specified rules. This will
  467. //just stop the function and the race will not be started and that will be
  468. //the end of it.
  469. RaceInfo[raceid][racetimer] = SetTimerEx("RaceTime", 100, true, "d", raceid);
  470. //We set the 100ms timer that acts as our timeout timer and gives us the
  471. //amount of time that the race has gone on for. Some people would use the
  472. //function GetTickCount although if you're server has a long uptime then
  473. //the script would just break itself. The timer is set at 100ms and the raceid
  474. //is carried onto the RaceTime function.
  475. RaceInfo[raceid][racerunning] = true;
  476. //We set the variable of racerunning to true to show that the race is actually
  477. //running so it cant be started.
  478. return 1;
  479. }
  480.  
  481.  
  482. forward RaceTime(raceid);
  483. public RaceTime(raceid)
  484. {
  485. RaceInfo[raceid][racetime] ++;
  486. //The racetime variable holds the current race time in 100ms increments
  487. //This allows us to give accurate race times to players at the end of the
  488. //race to .1 of a second.
  489. if(floatround((RaceInfo[raceid][racetime] / 10), floatround_floor) >= RaceInfo[raceid][racetimeout]) StopRace(raceid);
  490. //The above code does seem slightly confusing but it isn't. The racetimeout
  491. //time is in seconds and the racetime is in 0.1 of a second. We just divide
  492. //the race time by 10 so that we get the total race time in seconds and we
  493. //use the function Floatround to round downwards so we have no chance to get
  494. //errors when we try compare a float like this.
  495. return 1;
  496. }
  497.  
  498. stock StopRace(raceid)
  499. {
  500. KillTimer(RaceInfo[raceid][racetimer]);
  501. //We kill that timer that is going at 100ms/s acting as our timeout timer
  502. //and the race time timer
  503. RaceInfo[raceid][racetime] = 0;
  504. //Race time is reset to 0 for the race.
  505. RaceInfo[raceid][racerunning] = false;
  506. //Race running is set to false for the race
  507. RaceInfo[raceid][originalcount] = 0;
  508. //The originalcount is set to 0 for the race.
  509. if(RaceInfo[raceid][racecount] != 0)
  510. {
  511. //The only case that this would happen is a race timeout. This is if we
  512. //try to stop a race when there is players still in it.
  513. for(new i; i<MAX_PLAYERS; i++)
  514. //if you have foreach then foreach (new i : Player) or make your own
  515. //illiterator for players in races.
  516. {
  517. if(InRace[i] != raceid) continue;
  518. //skips anyone that isn't in the race that we are looking into.
  519. //continue just skips a certain id. For example if ID 5 wasn't in
  520. //our race so InRace[playerid] = -1 it would skip his ID and not check
  521. //any further.
  522. GameTextForPlayer(i, "~r~You have run out of time for this race!", 3000, 3);
  523. //Send the player a message telling them they have ran out of time for
  524. //the race.
  525. LeaveRace(i, raceid);
  526. //Calls LeaveRace for any player that is still in the race.
  527. }
  528. RaceInfo[raceid][racecount] = 0;
  529. //The racecount can now be reset as all the players have been kicked
  530. //from the race if they didn't make it.
  531. }
  532. return 1;
  533. }
  534.  
  535.  
  536. stock LeaveRace(playerid, raceid)
  537. {
  538. RaceCheckpoint[playerid] = -1;
  539. //Race checkpoint reset
  540. InRace[playerid] = -1;
  541. //Player is put out of the race
  542. DisablePlayerRaceCheckpoint(playerid);
  543. //Players checkpoint is disabled.
  544. if(IsPlayerInAnyVehicle(playerid))
  545. //If the player was in a car
  546. {
  547. new vehicleid = GetPlayerVehicleID(playerid);
  548. //We fetch the players vehicle ID
  549. SetVehicleVirtualWorld(vehicleid, 0);
  550. //We reset the vehicles virtual world to 0
  551. SetPlayerVirtualWorld(playerid, 0);
  552. //Sets the player to virtual world 0 too
  553. PutPlayerInVehicle(playerid, vehicleid, 0);
  554. //We put the player in the vehicle just in case
  555. }
  556. else
  557. {
  558. SetPlayerVirtualWorld(playerid, 0);
  559. //If the player was on foot we just put him back to virtual
  560. //world 0.
  561. }
  562. if(RaceInfo[raceid][racerunning] == true)
  563. //If the race has actually started rather than just a player waiting for the
  564. //race to start leaving the race.
  565. {
  566. RaceInfo[raceid][racecount] --;
  567. //removes a player from the racecount.
  568. if(RaceInfo[raceid][racecount] == 0) StopRace(raceid);
  569. //If there is nobody in the race after this person leaves then we have to
  570. //stop the race from running.
  571. }
  572. return 1;
  573. }
  574.  
  575.  
  576. //Now you're thinking sweeeeeeeeeeeet done with that part but you're wrong >:).
  577. //We still have to advance each checkpoint and determine what happens when a
  578. //player wins a race or finishes one. We need the callback OnPlayerEnterRaceCheckpoint.
  579.  
  580. public OnPlayerEnterRaceCheckpoint(playerid)
  581. {
  582. if(InRace[playerid] != -1)
  583. //This just makes sure the player is actually in a race. You may be using
  584. //race checkpoints for something else as well as this race system.
  585. {
  586. if(RaceCheckpoint[playerid] > 0)
  587. //RaceCheckpoint[playerid] = 0 is if the player is in a race but at
  588. //the starting checkpoint rather than actually racing. We check if the
  589. //player is at a checkpoint further than CP 1.
  590. {
  591. new raceid = InRace[playerid], checkpoint = RaceCheckpoint[playerid];
  592. //Above variables just makes it easier for us to use and understand
  593. //the code. We put the raceid that the player is in into the raceid
  594. //variable... YAY :). We also put the checkpoint id into the
  595. //checkpoint variable ;).
  596. if(checkpoint == RaceInfo[raceid][cpnum])
  597. //If we have the same checkpoint value as the race checkpoints before
  598. //we add one to our race checkpoint variable then we have gone through
  599. //the finishing checkpoint which means we should initiate the finish
  600. //race code and stop it there with a return 1;
  601. {
  602. //Player leaves the race.
  603. new str[128], playername[24];
  604. //creates the variables for the string we will format and the
  605. //variable to hold the players name.
  606. format(str, sizeof(str), "~w~Finished the race~n~~g~Position %d/%d - ~b~Time: %s", (RaceInfo[raceid][originalcount] - (RaceInfo[raceid][racecount] - 1)), RaceInfo[raceid][originalcount], ReturnTime(RaceInfo[raceid][racetime]));
  607. //Formats the string that will be sent to the player in a gametext.
  608. //(RaceInfo[raceid][originalcount] - (RaceInfo[raceid][racecount] - 1))
  609. //Starts at the original count minus the players in the race
  610. //minus the player himself (-1).
  611. GameTextForPlayer(playerid, str, 3000, 3);
  612. //Sends the player an on screen text of that formatted text above
  613. GetPlayerName(playerid, playername, sizeof(playername));
  614. //Gets the players name for the message that will be sent to everyone
  615. format(str, sizeof(str), "[RACE RESULTS] %s(%d) finished race %s(ID:%d) in %s in the position %d/%d", playername, playerid, RaceInfo[raceid][racename], raceid, ReturnTime(RaceInfo[raceid][racetime]), (RaceInfo[raceid][originalcount] - (RaceInfo[raceid][racecount]-1)), RaceInfo[raceid][originalcount]);
  616. //Formats a message for everyone with the players race results
  617. //which include his name, id, race name, raceid, time, and
  618. //position.
  619. SendClientMessageToAll(0xFF00AA, str);
  620. //sends everyone the formatted string.
  621. LeaveRace(playerid, InRace[playerid]);
  622. return 1;
  623. }
  624. RaceCheckpoint[playerid] ++;
  625. //Adds one to the players current race checkpoint.
  626. if(checkpoint != RaceInfo[raceid][cpnum]) SetPlayerRaceCheckpoint(playerid, 0, RaceInfo[raceid][checkpointx][checkpoint], RaceInfo[raceid][checkpointy][checkpoint], RaceInfo[raceid][checkpointz][checkpoint], RaceInfo[raceid][checkpointx][checkpoint+1], RaceInfo[raceid][checkpointy][checkpoint+1], RaceInfo[raceid][checkpointz][checkpoint+1], 6);
  627. //Sets the players race checkpoint and the arrow to the next
  628. //race checkpoint. RaceInfo[raceid][checkpointx][checkpoint+1] is the
  629. //next x position of the next checkpoint which is what the current
  630. //checkpoint will point at. if(checkpoint != RaceInfo[raceid][cpnum]
  631. //means that we are not at the last checkpoint yet. The cpnum variable
  632. //was used to show us the last array used for our checkpoints back
  633. //when we were adding checkpoints and it will tell us the last checkpoint.
  634. if(checkpoint+1 == RaceInfo[raceid][cpnum]) SetPlayerRaceCheckpoint(playerid, 1, RaceInfo[raceid][checkpointx][checkpoint], RaceInfo[raceid][checkpointy][checkpoint], RaceInfo[raceid][checkpointz][checkpoint], 0.0, 0.0, 0.0, 6);
  635. //The above is different from the last time we used
  636. //if(checkpoint == RaceInfo[raceid][cpnum]) because this time it's
  637. //after we added 1 to the race checkpoint variable. This now means
  638. //that we are setting the last checkpoint and the call above will
  639. //be called when we enter that checkpoint that we are just setting now.
  640. new RaceInfoString[80];
  641. format(RaceInfoString, sizeof(RaceInfoString), "~b~%d/%d ~n~~g~%s", RaceCheckpoint[playerid]-2, RaceInfo[raceid][cpnum] - 1, ReturnTime(RaceInfo[raceid][racetime]));
  642. //This returns a formatted string with the checkpoint number and the
  643. //current time that they have taken on this course. I have created
  644. //the function ReturnTime because I used the exact same code when
  645. //the player had finished the race as well. We have the cpnum minus
  646. //one because we don't count the starting checkpoint as an actual
  647. //checkpoint that the player goes through. RaceCheckpint[playerid]-2
  648. //is there because of the reason above (we don't count the first
  649. //checkpoint and it shows one before what we actually have so
  650. //that the second to last checkpoint shows 12/13 rather than 13/13
  651. GameTextForPlayer(playerid, RaceInfoString, 3000, 3);
  652. //Sends the gametext that tells the player their checkpoint number
  653. //and the current time it has taken them. You could always add a
  654. //loop here comparing with the checkpoint number to find the players
  655. //position in the race. You could also make a Textdraw that tells
  656. //the player their time and checkpoint rather than having it show
  657. //as a gametext.
  658. }
  659. }
  660. return 1;
  661. }
  662. stock ReturnTime(timevariable)
  663. //Used in the OnPlayerEnterRaceCheckpoint code.
  664. {
  665. new milliseconds = timevariable, seconds, minutes, string[20];
  666. while(milliseconds > 9)
  667. //While we still have 10 or more 100x milliseconds left
  668. {
  669. seconds ++;
  670. //Add to the seconds variable
  671. milliseconds = milliseconds - 10;
  672. //Take away 10 from the ms variable
  673. }
  674. while(seconds > 59)
  675. //while we have 60 or more seconds on the timer
  676. {
  677. minutes ++;
  678. //We add to the minutes variable
  679. seconds = seconds - 60;
  680. //And take the 60 seconds from the seconds variable.
  681. }
  682. format(string, sizeof(string), "%d:%02d.%03d
  683. ", minutes, seconds, milliseconds);
  684. //format the return string the 0 before the first %d makes it so the
  685. //seconds are correct and the zeros after the last %d make it so the
  686. //milliseconds show correctly.
  687. return string;
  688. //return the end result.
  689. }
  690.  
  691. //Now time for the commands. Most of it has already been done in the functions
  692. //so that we can easily just check if the raceid is valid and then Join the
  693. //race. LeaveRace is just straight forward, if you're not in a race, you cant leave
  694. //one. If you're in a race, you will leave it.
  695.  
  696. CMD:joinrace(playerid, params[])
  697. //The joinrace command using ZCMD
  698. {
  699. if(!strlen(params)) return SendClientMessage(playerid, 0xFF0000, "Please enter a race id to join or type /races");
  700. new raceid = strval(params);
  701. if(raceid > currentraceslot-1) return SendClientMessage(playerid, 0xFF0000, "The race ID you have entered is invalid");
  702. //Just basic tests to see if there is a race in the array / the number is
  703. //not too big for the array.
  704. if(RaceInfo[raceid][racejoinable] == false && RaceInfo[raceid][racerunning] == false && InRace[playerid] == -1) OpenRace(raceid);
  705. //If the race is not running or is joinable it is opened and the player
  706. //isn't in a race then it will start the race. If you don't want players
  707. //to be able to start races like this then remove the line and add an admin
  708. //command or a timer that choses a random race every x amount of seconds.
  709. JoinRace(playerid, raceid);
  710. //The above line will just join the player to the race.
  711. return 1;
  712. }
  713.  
  714. CMD:leaverace(playerid, params[])
  715. //The leaverace command using zcmd
  716. {
  717. if(InRace[playerid] == -1) return SendClientMessage(playerid, 0xFF0000, "You are not in a race");
  718. //Checks if a player is in a race or not and errors him if he isn't and
  719. //the code stops there with a return.
  720. LeaveRace(playerid, InRace[playerid]);
  721. //player leaves the race.
  722. GameTextForPlayer(playerid, "~b~You have left the race", 3000, 3);
  723. //On screen text telling them they have left the race
  724. return 1;
  725. }
  726.  
  727. public OnPlayerDeath(playerid, killerid, reason)
  728. {
  729. if(InRace[playerid] != -1) LeaveRace(playerid, InRace[playerid]);
  730. //Checks if the player is in a race and removes him / her from it on death
  731. return 1;
  732. }
  733.  
  734. public OnPlayerDisconnect(playerid, reason)
  735. {
  736. if(InRace[playerid] != -1) LeaveRace(playerid, InRace[playerid]);
  737. //Checks if the player is in a race and removes him from it on disconnect if
  738. //(s)he is in a race.
  739. return 1;
  740. }
  741.  
  742. //The following is just cool to have. It's just a command /races that will
  743. //just popup a dialog that gives you a list of all the races and whether you can
  744. //join the races or not. You don't need it but how else are people going to know
  745. //what ID the races are :P?
  746.  
  747.  
  748. CMD:races(playerid, params[])
  749. {
  750. new RaceInfoString[600];
  751. //Creates the large string for formatting all of this information. If you
  752. //are going to have like 30+ races then you may need to make the string
  753. //slightly larger.
  754. for(new x; x<currentraceslot; x++)
  755. //We are looping through all races up to the last slot used (currentraceslot)
  756. {
  757. if(RaceInfo[x][racejoinable] == true) format(RaceInfoString, sizeof(RaceInfoString), "%s%s(ID:%d) {00FF00}[RACE JOINABLE]{FFFFFF}\n", RaceInfoString, RaceInfo[x][racename], x);
  758. //If the race is currently joinable (still not started) then it will add
  759. //a line to that string that shows the race information with the tag
  760. //[RACE JOINABLE] on the end.
  761. else if(RaceInfo[x][racerunning] == true) format(RaceInfoString, sizeof(RaceInfoString), "%s%s(ID:%d) {FF0000}[RACE RUNNING]{FFFFFF}\n", RaceInfoString, RaceInfo[x][racename], x);
  762. //If the race is not currently joinable it will show the race name + id
  763. //with [RACE RUNNING] tag on it.
  764. else format(RaceInfoString, sizeof(RaceInfoString), "%s%s(ID:%d) \n", RaceInfoString, RaceInfo[x][racename], x);
  765. //If the race is not running or being started at all then it will just
  766. //be added with the race name and id.
  767. }
  768. ShowPlayerDialog(playerid, 13337, DIALOG_STYLE_LIST, "Races", RaceInfoString, "Join", "Cancel");
  769. //Sends the player a dialog which allows them to join races straight off
  770. //that list if they are avalible. The list also shows all races that have
  771. //currently been started and are currently running.
  772. return 1;
  773. }
  774.  
  775. public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
  776. {
  777. if(dialogid == 13337 && response != 0)
  778. //If our dialog is chosen and the player has pressed the join button
  779. //we initiate further code.
  780. {
  781. if(currentraceslot < listitem) return SendClientMessage(playerid, 0xFF0000, "Race ID is not valid");
  782. //Just to prevent the server crashing due to array out of bounds
  783. //if someone manages to manipulate the dialog we just make it so that
  784. //the listitem has a higher value than the array.
  785. if(!strlen(RaceInfo[listitem][racename])) return SendClientMessage(playerid, 0xFF0000, "Race ID is not valid");
  786. //Same as above but it just prevents players from attempting to join
  787. //races that are not being used by checking if they have a name or not.
  788. //Remember the return stops the code there.
  789. if(RaceInfo[listitem][racejoinable] == false && RaceInfo[listitem][racerunning] == false && InRace[playerid] == -1) OpenRace(listitem);
  790. //Same as in the /joinrace command. Starts the race if possible. If you
  791. //don't want players to have this kind of permission then just take it
  792. //off.
  793. JoinRace(playerid, listitem);
  794. //We join the race to the listitem specified. The listitem will be the
  795. //number on the list chosen which will also match up with our RaceInfo
  796. //array.
  797. }
  798. return 0;
  799. }
  800.  
  801.  
  802. //Here are just a few test races that I made up :). You don't need to use
  803. //them it's just for a bit of fun.
  804. public OnFilterScriptInit()
  805. {
  806. new myfirstrace = CreateRace("Drag race", 300);
  807. AddCheckpointToRace(myfirstrace, 2378.034423, -1256.948120, 23.392478);
  808. AddCheckpointToRace(myfirstrace, 2424.435058, -1256.951904, 23.392736);
  809. AddCheckpointToRace(myfirstrace, 2483.459228, -1256.290039, 29.515676);
  810. AddCheckpointToRace(myfirstrace, 2544.722656, -1255.574829, 40.808807);
  811. AddCheckpointToRace(myfirstrace, 2623.192871, -1256.035888, 48.688129);
  812. AddCheckpointToRace(myfirstrace, 2640.677734, -1299.083984, 43.465404);
  813. AddCheckpointToRace(myfirstrace, 2641.805908, -1384.888916, 29.915727);
  814. AddCheckpointToRace(myfirstrace, 2642.633056, -1510.337402, 28.740942);
  815. AddCheckpointToRace(myfirstrace, 2642.414306, -1609.575195, 10.076794);
  816. AddCheckpointToRace(myfirstrace, 2642.405029, -1748.507324, 10.287642);
  817. AddCheckpointToRace(myfirstrace, 2642.405029, -1812.125122, 10.375592);
  818. new race1 = CreateRace("DRAG LOL", 180);
  819. AddCheckpointToRace(race1, 2829.936523, -1794.952880, 10.647988);
  820. AddCheckpointToRace(race1, 2844.200927, -1714.927368, 10.654101);
  821. AddCheckpointToRace(race1, 2882.619628, -1575.671142, 10.650041);
  822. AddCheckpointToRace(race1, 2903.586425, -1443.250488, 10.646242);
  823. AddCheckpointToRace(race1, 2889.312988, -1309.945068, 10.654065);
  824. AddCheckpointToRace(race1, 2871.154785, -1043.372802, 10.646505);
  825. AddCheckpointToRace(race1, 2874.849609, -857.698730, 10.646862);
  826. AddCheckpointToRace(race1, 2884.896484, -675.723999, 10.607203);
  827. AddCheckpointToRace(race1, 2898.247802, -742.455566, 10.612231);
  828. AddCheckpointToRace(race1, 2892.632080, -896.031188, 10.646240);
  829. AddCheckpointToRace(race1, 2889.872314, -1064.333740, 10.646269);
  830. AddCheckpointToRace(race1, 2897.653076, -1222.954711, 10.646265);
  831. AddCheckpointToRace(race1, 2916.691650, -1346.928466, 10.646243);
  832. AddCheckpointToRace(race1, 2916.200683, -1513.697265, 10.649989);
  833. AddCheckpointToRace(race1, 2874.615478, -1659.650390, 10.646264);
  834. new race2 = CreateRace("lolrace", 50, 0);
  835. AddCheckpointToRace(race2, 2915.456787, -1622.428466, 12.435916);
  836. AddCheckpointToRace(race2, 2910.672363, -1637.185913, 12.395952);
  837. AddCheckpointToRace(race2, 2903.093994, -1660.151611, 12.430374);
  838. AddCheckpointToRace(race2, 2898.300048, -1675.741333, 12.457112);
  839. AddCheckpointToRace(race2, 2890.918457, -1702.602905, 12.493884);
  840. new race3 = CreateRace("circles", 300, 422);
  841. AddCheckpointToRace(race3, 2743.795654, -1824.129760, 37.350173);
  842. AddCheckpointToRace(race3, 2785.624511, -1798.400634, 38.007194);
  843. AddCheckpointToRace(race3, 2789.515625, -1730.653320, 38.372951);
  844. AddCheckpointToRace(race3, 2738.261718, -1703.567260, 39.003555);
  845. AddCheckpointToRace(race3, 2684.301513, -1735.715698, 38.545482);
  846. AddCheckpointToRace(race3, 2696.835693, -1801.783691, 38.632278);
  847. AddCheckpointToRace(race3, 2760.039550, -1815.870971, 38.270313);
  848. AddCheckpointToRace(race3, 2798.526611, -1765.682006, 38.073280);
  849. AddCheckpointToRace(race3, 2788.305908, -1731.470947, 38.702461);
  850. AddCheckpointToRace(race3, 2751.104736, -1710.066772, 40.082180);
  851. AddCheckpointToRace(race3, 2685.113037, -1726.660766, 37.719898);
  852. AddCheckpointToRace(race3, 2681.699951, -1785.690185, 37.916439);
  853. AddCheckpointToRace(race3, 2732.258544, -1823.472167, 37.502525);
  854. AddCheckpointToRace(race3, 2787.974121, -1795.875976, 37.903495);
  855. AddCheckpointToRace(race3, 2789.651855, -1734.030151, 38.703849);
  856. AddCheckpointToRace(race3, 2699.944824, -1717.708496, 38.976169);
  857. AddCheckpointToRace(race3, 2682.354736, -1756.922851, 39.295875);
  858. new race4 = CreateRace("DatLongRace", 300);
  859. AddCheckpointToRace(race4, 2633.364990, -1734.128051, 10.525354);
  860. AddCheckpointToRace(race4, 2545.920654, -1733.396240, 13.154250);
  861. AddCheckpointToRace(race4, 2442.343750, -1733.484252, 13.355755);
  862. AddCheckpointToRace(race4, 2431.615478, -1675.185058, 23.190317);
  863. AddCheckpointToRace(race4, 2432.491699, -1583.581542, 24.303165);
  864. AddCheckpointToRace(race4, 2426.228027, -1528.688842, 23.610731);
  865. AddCheckpointToRace(race4, 2358.857177, -1524.946044, 23.599382);
  866. AddCheckpointToRace(race4, 2343.114013, -1438.596801, 23.599653);
  867. AddCheckpointToRace(race4, 2332.898925, -1387.123657, 23.665111);
  868. AddCheckpointToRace(race4, 2267.898437, -1374.233398, 23.599349);
  869. AddCheckpointToRace(race4, 2266.498535, -1303.596435, 23.602481);
  870. AddCheckpointToRace(race4, 2143.897705, -1302.048583, 23.591621);
  871. AddCheckpointToRace(race4, 2076.627197, -1295.328979, 23.590627);
  872. AddCheckpointToRace(race4, 2054.959472, -1258.147949, 23.591150);
  873. AddCheckpointToRace(race4, 1923.316406, -1260.406738, 16.012174);
  874. AddCheckpointToRace(race4, 1817.992553, -1264.200195, 13.243765);
  875. AddCheckpointToRace(race4, 1714.354370, -1297.821655, 13.160857);
  876. AddCheckpointToRace(race4, 1607.921142, -1299.956787, 17.046354);
  877. AddCheckpointToRace(race4, 1467.686523, -1303.289916, 13.193289);
  878. AddCheckpointToRace(race4, 1453.888427, -1381.708862, 13.154219);
  879. AddCheckpointToRace(race4, 1449.449584, -1436.579956, 13.154660);
  880. AddCheckpointToRace(race4, 1405.544921, -1420.086425, 13.945821);
  881. AddCheckpointToRace(race4, 1315.515258, -1405.038818, 13.063317);
  882. AddCheckpointToRace(race4, 1205.709960, -1404.587158, 13.066181);
  883. AddCheckpointToRace(race4, 1041.687133, -1403.934204, 13.045770);
  884. AddCheckpointToRace(race4, 946.428405, -1401.756591, 13.036564);
  885. AddCheckpointToRace(race4, 918.143981, -1382.413818, 13.005650);
  886. AddCheckpointToRace(race4, 916.576599, -1334.884765, 13.273034);
  887. AddCheckpointToRace(race4, 822.389953, -1334.648559, 13.323395);
  888. AddCheckpointToRace(race4, 837.015991, -1343.594848, 7.064631);
  889. AddCheckpointToRace(race4, 830.920715, -1355.182861, 1.802645);
  890. AddCheckpointToRace(race4, 824.963378, -1381.297363, -1.784867);
  891. AddCheckpointToRace(race4, 897.291625, -1450.401733, -1.967725);
  892. AddCheckpointToRace(race4, 968.884155, -1525.094238, -2.687804);
  893. AddCheckpointToRace(race4, 1118.831665, -1692.697875, -4.506172);
  894. AddCheckpointToRace(race4, 1205.780883, -1793.990234, -4.416773);
  895. AddCheckpointToRace(race4, 1327.433471, -1920.372924, 1.110849);
  896. AddCheckpointToRace(race4, 1425.327758, -1953.886962, 12.610272);
  897. AddCheckpointToRace(race4, 1560.160888, -1956.531127, 13.320227);
  898. AddCheckpointToRace(race4, 1714.534423, -1957.219116, 13.322772);
  899. AddCheckpointToRace(race4, 1827.264770, -1956.456542, 13.326131);
  900. AddCheckpointToRace(race4, 1935.426879, -1966.828613, 14.527605);
  901. AddCheckpointToRace(race4, 1984.612304, -1963.229858, 17.639959);
  902. AddCheckpointToRace(race4, 2116.238037, -1956.358520, 13.328435);
  903. AddCheckpointToRace(race4, 2198.640625, -1911.479736, 13.332157);
  904. AddCheckpointToRace(race4, 2218.488037, -1849.738159, 13.029332);
  905. AddCheckpointToRace(race4, 2223.098632, -1751.567504, 13.153687);
  906. AddCheckpointToRace(race4, 2324.993896, -1749.899047, 13.151140);
  907. AddCheckpointToRace(race4, 2405.868164, -1753.348999, 13.153372);
  908. AddCheckpointToRace(race4, 2412.497558, -1804.233764, 13.154181);
  909. AddCheckpointToRace(race4, 2412.224609, -1882.934814, 13.154174);
  910. AddCheckpointToRace(race4, 2412.380615, -1999.624389, 13.132261);
  911. AddCheckpointToRace(race4, 2412.784912, -2109.244384, 13.141799);
  912. AddCheckpointToRace(race4, 2413.450195, -2160.048828, 13.220868);
  913. AddCheckpointToRace(race4, 2324.239990, -2235.036132, 13.146298);
  914. AddCheckpointToRace(race4, 2287.443115, -2302.291992, 13.150836);
  915. AddCheckpointToRace(race4, 2359.932861, -2374.427246, 13.151649);
  916. AddCheckpointToRace(race4, 2429.166992, -2442.671386, 13.238473);
  917. AddCheckpointToRace(race4, 2520.102294, -2380.220703, 13.224400);
  918. AddCheckpointToRace(race4, 2628.054931, -2402.248291, 13.233164);
  919. AddCheckpointToRace(race4, 2736.581298, -2409.763183, 13.258348);
  920. AddCheckpointToRace(race4, 2797.283447, -2416.207763, 13.402585);
  921. new lsrace = CreateRace("LsRace", 300);
  922. AddCheckpointToRace(lsrace, 1706.426391, -611.859863, 38.901790);
  923. AddCheckpointToRace(lsrace, 1692.569946, -723.126037, 48.900508);
  924. AddCheckpointToRace(lsrace, 1652.880004, -817.668334, 57.524845);
  925. AddCheckpointToRace(lsrace, 1605.353881, -881.411804, 53.732391);
  926. AddCheckpointToRace(lsrace, 1539.825439, -922.278015, 43.056083);
  927. AddCheckpointToRace(lsrace, 1461.724975, -940.698120, 35.791889);
  928. AddCheckpointToRace(lsrace, 1403.331054, -941.417907, 34.747589);
  929. AddCheckpointToRace(lsrace, 1392.661621, -882.348999, 39.213245);
  930. AddCheckpointToRace(lsrace, 1465.932739, -865.940429, 55.070766);
  931. AddCheckpointToRace(lsrace, 1512.892944, -797.726623, 73.608940);
  932. AddCheckpointToRace(lsrace, 1476.592773, -764.863769, 91.092216);
  933. AddCheckpointToRace(lsrace, 1457.034545, -720.671813, 91.886367);
  934. AddCheckpointToRace(lsrace, 1338.306518, -698.574401, 91.680290);
  935. AddCheckpointToRace(lsrace, 1155.694335, -762.598022, 107.170852);
  936. AddCheckpointToRace(lsrace, 1037.425781, -782.354858, 103.803581);
  937. AddCheckpointToRace(lsrace, 944.082031, -823.647094, 95.165565);
  938. AddCheckpointToRace(lsrace, 838.899108, -870.125427, 68.854980);
  939. AddCheckpointToRace(lsrace, 782.362426, -907.054016, 56.233585);
  940. AddCheckpointToRace(lsrace, 676.304748, -1057.787963, 49.234329);
  941. AddCheckpointToRace(lsrace, 546.687988, -1158.329833, 54.421894);
  942. AddCheckpointToRace(lsrace, 442.335571, -1189.781250, 67.419334);
  943. AddCheckpointToRace(lsrace, 399.630310, -1174.796752, 78.225868);
  944. AddCheckpointToRace(lsrace, 287.595764, -1227.318481, 74.894096);
  945. AddCheckpointToRace(lsrace, 230.168182, -1276.778564, 64.179939);
  946. AddCheckpointToRace(lsrace, 243.446228, -1327.960083, 52.253746);
  947. AddCheckpointToRace(lsrace, 212.957321, -1365.910888, 49.981910);
  948. AddCheckpointToRace(lsrace, 156.897445, -1428.196655, 39.155746);
  949. AddCheckpointToRace(lsrace, 112.251525, -1485.543457, 14.808308);
  950. AddCheckpointToRace(lsrace, 167.971176, -1530.873657, 11.934063);
  951. AddCheckpointToRace(lsrace, 230.456497, -1443.309692, 12.917514);
  952. AddCheckpointToRace(lsrace, 338.681091, -1381.437988, 13.922136);
  953. AddCheckpointToRace(lsrace, 471.116241, -1298.085449, 15.019657);
  954. AddCheckpointToRace(lsrace, 539.320739, -1241.989990, 16.362131);
  955. AddCheckpointToRace(lsrace, 634.960266, -1259.193481, 16.687885);
  956. AddCheckpointToRace(lsrace, 635.698059, -1334.740722, 13.114221);
  957. AddCheckpointToRace(lsrace, 633.734802, -1491.675170, 14.342875);
  958. AddCheckpointToRace(lsrace, 635.601684, -1616.577270, 15.354584);
  959. AddCheckpointToRace(lsrace, 632.403259, -1718.967895, 13.681066);
  960. AddCheckpointToRace(lsrace, 759.028747, -1766.696166, 12.587768);
  961. AddCheckpointToRace(lsrace, 881.049072, -1770.948730, 13.109845);
  962. AddCheckpointToRace(lsrace, 1008.124572, -1795.744262, 13.775837);
  963. AddCheckpointToRace(lsrace, 1156.595825, -1852.637329, 13.121710);
  964. AddCheckpointToRace(lsrace, 1312.552978, -1831.018432, 13.109981);
  965. AddCheckpointToRace(lsrace, 1311.227416, -1670.582519, 13.109985);
  966. AddCheckpointToRace(lsrace, 1337.795532, -1493.360961, 13.108355);
  967. AddCheckpointToRace(lsrace, 1356.297363, -1256.863037, 13.106974);
  968. AddCheckpointToRace(lsrace, 1363.745239, -1076.934936, 24.951122);
  969. AddCheckpointToRace(lsrace, 1473.232055, -1031.099243, 23.383405);
  970. AddCheckpointToRace(lsrace, 1658.844116, -1026.858276, 23.625595);
  971. AddCheckpointToRace(lsrace, 1894.228637, -1044.847290, 23.408243);
  972. AddCheckpointToRace(lsrace, 2039.885620, -1074.727416, 24.357799);
  973. AddCheckpointToRace(lsrace, 2176.282226, -1143.813720, 24.630598);
  974. AddCheckpointToRace(lsrace, 2168.373535, -1290.851318, 23.547401);
  975. AddCheckpointToRace(lsrace, 2271.814941, -1299.705200, 23.553785);
  976. AddCheckpointToRace(lsrace, 2331.828125, -1299.506225, 23.808448);
  977. AddCheckpointToRace(lsrace, 2371.086181, -1352.059692, 23.562322);
  978. AddCheckpointToRace(lsrace, 2343.587890, -1409.425415, 23.545507);
  979. AddCheckpointToRace(lsrace, 2342.461669, -1513.188110, 23.564939);
  980. AddCheckpointToRace(lsrace, 2300.728759, -1565.118164, 14.730288);
  981. AddCheckpointToRace(lsrace, 2164.391357, -1532.709472, 2.032401);
  982. AddCheckpointToRace(lsrace, 2042.412719, -1503.038574, 3.047770);
  983. AddCheckpointToRace(lsrace, 1948.191284, -1518.647460, 3.063310);
  984. AddCheckpointToRace(lsrace, 1851.070434, -1551.060546, 12.822020);
  985. AddCheckpointToRace(lsrace, 1818.930175, -1665.781372, 13.110196);
  986. AddCheckpointToRace(lsrace, 1907.059204, -1754.055419, 13.109704);
  987. AddCheckpointToRace(lsrace, 2023.382446, -1753.830566, 13.109979);
  988. AddCheckpointToRace(lsrace, 2189.188476, -1699.546752, 13.243209);
  989. AddCheckpointToRace(lsrace, 2245.878662, -1653.323486, 15.011875);
  990. AddCheckpointToRace(lsrace, 2381.359863, -1660.972656, 13.109755);
  991. return 1;
  992. }
Add Comment
Please, Sign In to add comment