SA-MP Forums Archive
[AJUDA]Sistema Race Bugadao - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: Non-English (https://sampforum.blast.hk/forumdisplay.php?fid=9)
+--- Forum: Languages (https://sampforum.blast.hk/forumdisplay.php?fid=33)
+---- Forum: Português/Portuguese (https://sampforum.blast.hk/forumdisplay.php?fid=34)
+---- Thread: [AJUDA]Sistema Race Bugadao (/showthread.php?tid=302158)



[AJUDA]Sistema Race Bugadao - [BC]Pegador[KoF] - 07.12.2011

AE TA BUGADO POCO TIPO quando eu crio o race manda da Join e tal ai vai do Join e n me teleporta pro race ou seja pra dentro do veiculo que era pra na hora q usase /join aparecece 1 veiculo lado a lado de cada 1 cada q entra no race os veiculos vai entrando no lado lado a lado veiculos AJUDA PORFAVO PRECISO MUITO

PHP код:
// - Yagu's Race Filterscript v0.4a by Yagu -
// For more information and possible updates, visit: http://forum.sa-mp.com/index.php?topic=20637.0
// Feel free to make modifications to this script, but please give credit where credit is due, and even better,
// inform me of your changes on SA-MP forum so they can be added to the 'official' version if they are good.
//
// Credits out to mabako for the map editor which inspired me to make this one, Jax/Sintax for lvdmod, it
// has worked as a launch pad to PAWN programming, and various chaps out at SA-MP forums for their work,
// especially ****** for all kinds of snippets of code and information, and DracoBlue for dcmd.
//
// Peace out.
//
#define dcmd(%1,%2,%3) if ((strcmp((%3)[1], #%1, true, (%2)) == 0) && ((((%3)[(%2) + 1] == 0) && (dcmd_%1(playerid, "")))||(((%3)[(%2) + 1] == 32) && (dcmd_%1(playerid, (%3)[(%2) + 2]))))) return 1
#include <a_samp>
#include <float>
#include <file>
#include <JunkBusterFS>
#define MAX_RACECHECKPOINTS 64 // Change if you want more room for checkpoints than this
#define MAX_BUILDERS 4 // Change if you want more builderslots than this
#define RACEFILE_VERSION 2 // !!! DO NOT CHANGE !!!
#define MENUSYSTEM // Enable menus, comment to disable, this script uses 11 menus so it might conflict with your stuff
                   // if you are using a lot of menus yourself (global limit for SA-MP: 128)
                   // Do note, however, that I plan on retiring most of the commands that can as of now (v0.4) reached
                   // by menus to make the script more "user friendly" (this is depending on feedback I get on the topic)
//########################################################//
// VARIABLES YOU MIGHT WANT TO MODIFY TO SUIT YOUR TASTES //
//  THESE CAN BE CHANGED VIA MENUS INGAME, BUT SETTINGS   //
//  ARE NOT SAVED (YET), SO YOU MIGHT WANT TO SET DEFAULT //
//  VALUES FROM HERE. < THIS SPACE IS LEFT BLANK >        //
//########################################################//
new MajorityDelay 60// Default delay to wait for other racers once half are ready (can be changed ingame via Admin menu)
new RRotation 1;      // Is automatic Race Rotation enabled by defaul? (can be changed ingame via Admin menu) (-1 = disabled, 0+ = enabled)
new RRotationDelay 90000// How often will we poll for new race start if RRotation is enabled? (Default: 5 minutes, can't be changed IG)
new BuildAdmin 0//Require admin privileges for building races? 1)  yes, 0) no. (Can be changed ingame in Admin menu)
new RaceAdmin 0;  //Require admin privileges for starting races? 1)  yes, 0) no. (Can be changed ingame in Admin menu)
new PrizeMode=0;        //Mode for winnings: 0 - Fixed, 1 - Dynamic, 2 - Entry fee, 3 - EF+F, 4 EF+D [Admin menu ingame]
new Prize=30000;        //Fixed prize sum (15,000$ for winner, 12,5000$ for 2nd and 10,000$ for 3rd) [Admin menu ingame]
new DynaMP=1;           //Dynamic prize multiplier. (Default: 1$/m) [Admin menu ingame]
new JoinFee=1000;
//################################################//
// CHANGE THINGS PAST THIS POINT ON YOUR OWN RISK //
//################################################//
                    
#if defined MENUSYSTEM
forward RefreshMenuHeader(playerid,Menu:menu,text[]);
new 
Menu:MAdminMenu:MPModeMenu:MPrizeMenu:MDynaMenu:MBuildMenu:MLaps;
new 
Menu:MRaceMenu:MRacemodeMenu:MFeeMenu:MCPsizeMenu:MDelay;
#endif
#define COLOR_GREEN 0x33AA33AA
#define COLOR_RED 0xAA3333AA
#define COLOR_YELLOW 0xFFFF00AA
#define COLOR_WHITE 0xFFFFFFAA
forward RaceRotation();
forward LockRacers();
forward UnlockRacers();
forward SaveScores();                   // After race, if new best times have been made, saves them.
forward GetRaceTick(playerid);            // Gets amount of ticks the player was racing
forward GetLapTick(playerid);              // Gets amount of ticks the player spend on the lap
forward ReadyRefresh();                    // Check the /ready status of players and start the race when ready
forward RaceSound(playerid,sound);      // Plays <sound> for <playerid>
forward BActiveCP(playerid,sele);       // Gives the player selected checkpoint
forward endrace();                      // Ends the race, whether it ended normally or by /endrace. Cleans the variables.
forward countdown();                    // Handles the countdown
forward mscountdown();                  //Majority Start countdown handler
forward strtok(const string[],&index);
forward SetNextCheckpoint(playerid);    // Gives the next checkpoint for the player during race
forward CheckBestLap(playeridlaptime);    // Check if <laptime> is better than any of the ones in highscore list, and update.
forward CheckBestRace(playerid,racetime);   // Check if <racetime> is better than any of the ones in highscore list, and update.
forward ChangeLap(playerid);            // Change player's lap, print out time and stuff.
forward SetRaceCheckpoint(playerid,target,next);    // Race-mode checkpoint setter
forward SetBRaceCheckpoint(playerid,target,next);   // Builder-mode checkpoint  setter
forward LoadTimes(playerid,timemode,tmp[]);     // bestlap and bestrace-parameter race loader
forward IsNotAdmin(playerid);          // Is the player admin, if no, return 1 with an error message.
forward GetBuilderSlot(playerid);   // Get next free builderslot, return 0 if none available
forward b(playerid);                // Quick and dirty fix for the BuilderSlots
forward Float:Distance(Float:x1,Float:y1,Float:z1,Float:x2,Float:y2,Float:z2);
forward clearrace(playerid);
forward startrace();
forward LoadRace(tmp[]);
forward CreateRaceMenus();
// General variables
new RotationTimer;
new 
ystring[128];    // ystring
new CBuilder[MAX_PLAYER_NAME], CFile[64], CRaceName[128];        //Creator of the race and the filename, for score changing purposes.
// Racing-related variables
new Pot=0;              //Join fees go here
new Ranking;            //Finishing order for prizes
new PrizeMP;            //Prize multiplier
new Countdown;          //Countdown timer
new cd;                 //Countdown time
new MajStart=0;         //Status of the Majority Start timer
new MajStartTimer;      //Majority Start timer
new mscd;               //Majority Start time
new RaceActive;         //Is a race active?
new RaceStart;          //Has race started?
new Float:RaceCheckpoints[MAX_RACECHECKPOINTS][3];  //Current race CP array
new LCurrentCheckpoint;                             //Current race array pointer
new CurrentCheckpoint[MAX_PLAYERS];                 //Current race array pointer array :V
new CurrentLap[MAX_PLAYERS];                        //Current lap array
new RaceParticipant[MAX_PLAYERS];                   //Has the player /joined the race
  // \_values: 0 - not in race, 1 - joined, 2 - arrived to start CP, 3 - /ready, 4 - racing, 5 - Last CP
new Participants;                                   //Amount of participants
new PlayerVehicles[MAX_PLAYERS];                    //For slapping the player back in their vehicle.
new ORacelapsORacemode;   //Saves the laps/mode from file in case they aren't changed
new OAirraceFloat:OCPsize;
new 
RacelapsRacemode;        //If mode/laps has been changed, the new scores won't be saved.
new ScoreChange;            //Flag for new best times, so they are saved.
new RaceTick;               //Startime of the race
new LastLapTick[MAX_PLAYERS];       //Array that stores the times when players started the lap
new TopRacers[6][MAX_PLAYER_NAME]; // Stores 5 top scores, 6th isn't
new TopRacerTimes[6];              // saved to file, used to simplify
new TopLappers[6][MAX_PLAYER_NAME];// for() loops on CheckBestLap and
new TopLapTimes[6];                // CheckBestRace.
new Float:CPsize;                        // Checkpoint size for the race
new Airrace;                       // Is the race airrace?
new Float:RLenghtFloat:LLenght//Lap lenght and race lenght
// Building-related variables
new BCurrentCheckpoints[MAX_BUILDERS];               //Buildrace array pointers
new BSelectedCheckpoint[MAX_BUILDERS];               //Selected checkpoint during building
new RaceBuilders[MAX_PLAYERS];                       //Who is building a race?
new BuilderSlots[MAX_BUILDERS];                      //Stores the racebuilder pids
new Float:BRaceCheckpoints[MAX_BUILDERS][MAX_RACECHECKPOINTS][3]; //Buildrace CP array
new Bracemode[MAX_BUILDERS];
new 
Blaps[MAX_BUILDERS];
new 
Float:BCPsize[MAX_BUILDERS];
new 
BAirrace[MAX_BUILDERS];
public 
OnFilterScriptInit()
{
    print(
"\n+--------------------------------+");
    print(
"| Yagu's Race Filterscript v0.4a |");
    print(
"+--------------LOADED------------+\n");
    
RaceActive=0;
    
Ranking=1;
    
LCurrentCheckpoint=0;
    
Participants=0;
    for(new 
i;i<MAX_BUILDERS;i++)
    {
        
BuilderSlots[i]=MAX_PLAYERS+1;
    }
    if(
RRotation != -1SetTimer("RaceRotation",RRotationDelay,1);
    
#if defined MENUSYSTEM
        
CreateRaceMenus();
    
#endif
    
return 1;
}
public 
OnFilterScriptExit()
{
    print(
"\n+--------------------------------+");
    print(
"| Yagu's Race Filterscript v0.4a |");
    print(
"+------------UNLOADED------------+\n");
    
#if defined MENUSYSTEM
    
DestroyMenu(MAdmin);
    
DestroyMenu(MPMode);
    
DestroyMenu(MPrize);
    
DestroyMenu(MDyna);
    
DestroyMenu(MBuild);
    
DestroyMenu(MLaps);
    
DestroyMenu(MRace);
    
DestroyMenu(MRacemode);
    
DestroyMenu(MFee);
    
DestroyMenu(MCPsize);
    
DestroyMenu(MDelay);
    
#endif
    
return 1;
}
public 
OnPlayerCommandText(playeridcmdtext[])
{
    
dcmd(racehelp,8,cmdtext);    // Racehelp - there's a lot of commands!
    
dcmd(buildhelp,9,cmdtext);    // Buildhelp - there's a lot of commands!
    
dcmd(buildrace,9,cmdtext);    // Buildrace - Start building a new race (suprising!)
    
dcmd(cp,2,cmdtext);              // cp - Add a checkpoint
    
dcmd(scp,3,cmdtext);        // scp - Select a checkpoint
    
dcmd(rcp,3,cmdtext);        // rcp - Replace the current checkpoint with a new one
    
dcmd(mcp,3,cmdtext);        // mcp - Move the selected checkpoint
    
dcmd(dcp,3,cmdtext);           // dcp - Delete the selected waypoint
    
dcmd(clearrace,9,cmdtext);    // clearrace - Clear the current (new) race.
    
dcmd(editrace,8,cmdtext);    // editrace - Load an existing race into the builder
    
dcmd(saverace,8,cmdtext);    // saverace - Save the current checkpoints to a file
    
dcmd(setlaps,7,cmdtext);    // setlaps - Set amount of laps to drive
    
dcmd(racemode,8,cmdtext);    // racemode - Set the current racemode
    
dcmd(loadrace,8,cmdtext);    // loadrace - Load a race from file and start it
    
dcmd(startrace,9,cmdtext);  // starts the loaded race
    
dcmd(join,4,cmdtext);        // join - Join the announced race.
    
dcmd(leave,5,cmdtext);        // leave - leave the current race.
    
dcmd(endrace,7,cmdtext);    // endrace - Complete the current race, clear tables & variables, stop the timer.
    
dcmd(ready,5,cmdtext);        // ready - Player is ready to start, lock the controls, prepare for CD.
    
dcmd(bestlap,7,cmdtext);    // bestlap - Display the best lap times for the current race
    
dcmd(bestrace,8,cmdtext);    // bestrace - Display the best race times for the current race
    
dcmd(deleterace,10,cmdtext);// deleterace - Remove the race from disk
    
dcmd(airrace,7,cmdtext);    // airrace - Changes the checkpoints to air CPs and back
    
dcmd(cpsize,6,cmdtext);     // cpsize - changes the checkpoint size
    
dcmd(prizemode,9,cmdtext);
    
dcmd(setprize,8,cmdtext);
    
#if defined MENUSYSTEM
    
dcmd(raceadmin,9,cmdtext);
    
dcmd(buildmenu,9,cmdtext);
    
#endif
    
return 0;
}
dcmd_racehelp(playeridparams[])
{
    
#pragma unused params
    
SendClientMessage(playeridCOLOR_GREEN"Yagu's race script racing help:");
    
SendClientMessage(playeridCOLOR_WHITE"/loadrace [name] to load a track and start it. Use /join to jo in, and /ready");
    
SendClientMessage(playeridCOLOR_WHITE"once at start to begin the race once others are ready as well. /leave to leave");
    
SendClientMessage(playeridCOLOR_WHITE"the race./endrace to aborts the race. /bestlap and /bestrace can be used to");
    
SendClientMessage(playeridCOLOR_WHITE"display record times for the races, you can also specify a race to see the");
    
SendClientMessage(playeridCOLOR_WHITE"times for it. For info on building races, see /buildhelp. For additional");
    
SendClientMessage(playeridCOLOR_WHITE"settings, see /raceadmin.");
    return 
1;
}
dcmd_buildhelp(playeridparams[])
{
    
#pragma unused params
    
SendClientMessage(playeridCOLOR_GREEN"Yagu's race script building help:");
    
SendClientMessage(playeridCOLOR_WHITE"/buildrace to start building, /cp for new a checkpoint, /scp to select an old");
    
SendClientMessage(playeridCOLOR_WHITE"checkpoint, /dcp to delete, /mcp to move and /rcp to replace with a new one.");
    
SendClientMessage(playeridCOLOR_WHITE"/editrace to load a race to editor. /saverace [name] to save the race and");
    
SendClientMessage(playeridCOLOR_WHITE"/buildmenu to set racemode/laps/etc. For info on racing itself, see /racehelp");
    
SendClientMessage(playeridCOLOR_WHITE"For additional settings, see /raceadmin.");
    return 
1;
}
dcmd_buildrace(playeridparams[])
{
    
#pragma unused params
    
if(BuildAdmin == && IsNotAdmin(playerid)) return 1;
    if(
RaceBuilders[playerid] != 0)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"You are already building a race, dork.");
    }
    else if(
RaceParticipant[playerid]>0)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"You are participating in a race, can't build a race.");
    }
    else
    {
        new 
slot;
        
slot=GetBuilderSlot(playerid);
        if(
slot == 0)
        {
            
SendClientMessage(playeridCOLOR_YELLOW"No builderslots available!");
            return 
1;
        }
        
format(ystring,sizeof(ystring),"You are now building a race (Slot: %d)",slot);
        
SendClientMessage(playeridCOLOR_GREENystring);
        
RaceBuilders[playerid]=slot;
        
BCurrentCheckpoints[b(playerid)]=0;
        
Bracemode[b(playerid)]=0;
        
Blaps[b(playerid)]=0;
        
BAirrace[b(playerid)] = 0;
        
BCPsize[b(playerid)] = 8.0;
    }
    return 
1;
}
dcmd_cp(playeridparams[])
{
    
#pragma unused params
    
if(RaceBuilders[playerid] != && BCurrentCheckpoints[b(playerid)] < MAX_RACECHECKPOINTS)
    {
        new 
Float:xFloat:yFloat:z;
        
GetPlayerPos(playerid,x,y,z);
        
format(ystring,sizeof(ystring),"Checkpoint %d created: %f,%f,%f.",BCurrentCheckpoints[b(playerid)],x,y,z);
        
SendClientMessage(playeridCOLOR_GREENystring);
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][0]=x;
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][1]=y;
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][2]=z;
        
BSelectedCheckpoint[b(playerid)]=BCurrentCheckpoints[b(playerid)];
        
SetBRaceCheckpoint(playerid,BCurrentCheckpoints[b(playerid)],-1);
        
BCurrentCheckpoints[b(playerid)]++;
    }
    else if(
RaceBuilders[playerid] != && BCurrentCheckpoints[b(playerid)] == MAX_RACECHECKPOINTS)
    {
        
format(ystring,sizeof(ystring),"Sorry, maximum amount of checkpoints reached (%d).",MAX_RACECHECKPOINTS);
        
SendClientMessage(playeridCOLOR_YELLOWystring);
    }
    else
    {
        
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
    }
    return 
1;
}
dcmd_scp(playeridparams[])
{
    new 
seletmp[256], idx;
    
tmp strtok(paramsidx);
    if(!
strlen(tmp)) {
        
SendClientMessage(playeridCOLOR_WHITE"USAGE: /scp [checkpoint]");
        return 
1;
    }
    
sele strval(tmp);
    if(
RaceBuilders[playerid] != 0)
    {
        if(
sele>BCurrentCheckpoints[b(playerid)]-|| BCurrentCheckpoints[b(playerid)] < || sele 0)
        {
            
SendClientMessage(playeridCOLOR_YELLOW"Invalid checkpoint!");
            return 
1;
        }
        
format(ystring,sizeof(ystring),"Selected checkpoint %d.",sele);
        
SendClientMessage(playeridCOLOR_GREENystring);
        
BActiveCP(playerid,sele);
        
BSelectedCheckpoint[b(playerid)]=sele;
    }
    else
    {
        
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
    }
    return 
1;
}
dcmd_rcp(playeridparams[])
{
    
#pragma unused params
    
if(RaceBuilders[playerid] == 0)
    {
        
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
        return 
1;
    }
    else if(
BCurrentCheckpoints[b(playerid)] < 1)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"No checkpoint to replace!");
        return 
1;
    }
    new 
Float:x,Float:y,Float:z;
    
GetPlayerPos(playerid,x,y,z);
    
format(ystring,sizeof(ystring),"Checkpoint %d replaced: %f,%f,%f.",BSelectedCheckpoint[b(playerid)],x,y,z);
    
SendClientMessage(playeridCOLOR_GREENystring);
    
BRaceCheckpoints[b(playerid)][BSelectedCheckpoint[b(playerid)]][0]=x;
    
BRaceCheckpoints[b(playerid)][BSelectedCheckpoint[b(playerid)]][1]=y;
    
BRaceCheckpoints[b(playerid)][BSelectedCheckpoint[b(playerid)]][2]=z;
    
BActiveCP(playerid,BSelectedCheckpoint[b(playerid)]);
    return 
1;
}
dcmd_mcp(playeridparams[])
{
    if(
RaceBuilders[playerid] == 0)
    {
        
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
        return 
1;
    }
    else if(
BCurrentCheckpoints[b(playerid)] < 1)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"No checkpoint to move!");
        return 
1;
    }
    new 
idxdirectiondir[32];
    
dir=strtok(paramsidx);
    new 
Float:amount=floatstr(strtok(params,idx));
    if(
amount == 0.0 || (dir[0] != 'x' && dir[0]!='y' && dir[0]!='z'))
    {
        
SendClientMessage(playeridCOLOR_WHITE"USAGE: /mcp [x,y or z] [amount]");
        return 
1;
    }
    if(
dir[0] == 'x'direction=0;
    else if (
dir[0] == 'y'direction=1;
    else if (
dir[0] == 'z'direction=2;
    
BRaceCheckpoints[b(playerid)][BSelectedCheckpoint[b(playerid)]][direction]=BRaceCheckpoints[b(playerid)][BSelectedCheckpoint[b(playerid)]][direction]+amount;
    
BActiveCP(playerid,BSelectedCheckpoint[b(playerid)]);
    return 
1;
}
dcmd_dcp(playeridparams[])
{
    
#pragma unused params
    
if(RaceBuilders[playerid] == 0)
    {
        
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
        return 
1;
    }
    else if(
BCurrentCheckpoints[b(playerid)] < 1)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"No checkpoint to delete!");
        return 
1;
    }
    for(new 
i=BSelectedCheckpoint[b(playerid)];i<BCurrentCheckpoints[b(playerid)];i++)
    {
        
BRaceCheckpoints[b(playerid)][i][0]=BRaceCheckpoints[b(playerid)][i+1][0];
        
BRaceCheckpoints[b(playerid)][i][1]=BRaceCheckpoints[b(playerid)][i+1][1];
        
BRaceCheckpoints[b(playerid)][i][2]=BRaceCheckpoints[b(playerid)][i+1][2];
    }
    
BCurrentCheckpoints[b(playerid)]--;
    
BSelectedCheckpoint[b(playerid)]--;
    if(
BCurrentCheckpoints[b(playerid)] < 1)
    {
        
DisablePlayerRaceCheckpoint(playerid);
        
BSelectedCheckpoint[b(playerid)]=0;
        return 
1;
    }
    else if(
BSelectedCheckpoint[b(playerid)] < 0)
    {
        
BSelectedCheckpoint[b(playerid)]=0;
    }
    
BActiveCP(playerid,BSelectedCheckpoint[b(playerid)]);
    
SendClientMessage(playerid,COLOR_GREEN,"Checkpoint deleted!");
    return 
1;
}
dcmd_clearrace(playerid,params[])
{
    
#pragma unused params
    
if(RaceBuilders[playerid] != 0clearrace(playerid);
    else 
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
    return 
1;
}
dcmd_editrace(playerid,params[])
{
    if(
RaceBuilders[playerid] == 0)
    {
        
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
        return 
1;
    }
    if(
BCurrentCheckpoints[b(playerid)]>0//Clear the old race if there is such.
    
{
        for(new 
i=0;i<BCurrentCheckpoints[b(playerid)];i++)
        {
            
BRaceCheckpoints[b(playerid)][i][0]=0.0;
            
BRaceCheckpoints[b(playerid)][i][1]=0.0;
            
BRaceCheckpoints[b(playerid)][i][2]=0.0;
        }
        
BCurrentCheckpoints[b(playerid)]=0;
    }
    new 
tmp[256],idx;
    
tmp strtok(paramsidx);
    if(!
strlen(tmp))
    {
        
SendClientMessage(playeridCOLOR_WHITE"USAGE: /editrace [name]");
        return 
1;
    }
    new 
race_name[32],templine[42];
    
format(race_name,sizeof(race_name), "%s.yr",tmp);
    if(!
fexist(race_name))
    {
        
format(ystring,sizeof(ystring), "The race \"%s\" doesn't exist.",tmp);
        
SendClientMessage(playeridCOLOR_REDystring);
        return 
1;
    }
    
BCurrentCheckpoints[b(playerid)]=-1;
    new 
File:fi;
    
fopen(race_nameio_read);
    
fread(f,templine,sizeof(templine));
    if(
templine[0] == 'Y'//Checking if the racefile is v0.2+
    
{
        new 
fileversion;
        
strtok(templine,i); // read off YRACE
        
fileversion strval(strtok(templine,i)); // read off the file version
        
if(fileversion RACEFILE_VERSION// Check if the race is made with a newer version of the racefile format
        
{
            
format(ystring,128,"Race \'%s\' is created with a newer version of YRACE, unable to load.",tmp);
            
SendClientMessage(playerid,COLOR_RED,ystring);
            return 
1;
        }
        
strtok(templine,i); // read off RACEBUILDER
        
Bracemode[b(playerid)] = strval(strtok(templine,i)); // read off racemode
        
Blaps[b(playerid)] = strval(strtok(templine,i)); // read off amount of laps
        
if(fileversion >= 2)
        {
            
BAirrace[b(playerid)] = strval(strtok(templine,i));
            
BCPsize[b(playerid)] = floatstr(strtok(templine,i));
        }
        else
        {
            
BAirrace[b(playerid)] = 0;
            
BCPsize[b(playerid)] = 8.0;
        }
        
fread(f,templine,sizeof(templine)); // read off best race times, not saved due to editing the track
        
fread(f,templine,sizeof(templine)); // read off best lap times,          -||-
    
}
    else 
//Otherwise add the lines as checkpoints, the file is made with v0.1 (or older) version of the script.
    
{
        
BCurrentCheckpoints[b(playerid)]++;
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][0] = floatstr(strtok(templine,i));
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][1] = floatstr(strtok(templine,i));
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][2] = floatstr(strtok(templine,i));
    }
    while(
fread(f,templine,sizeof(templine),false))
    {
        
BCurrentCheckpoints[b(playerid)]++;
        
i=0;
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][0] = floatstr(strtok(templine,i));
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][1] = floatstr(strtok(templine,i));
        
BRaceCheckpoints[b(playerid)][BCurrentCheckpoints[b(playerid)]][2] = floatstr(strtok(templine,i));
    }
    
fclose(f);
    
BCurrentCheckpoints[b(playerid)]++; // # of next CP to be created
    
format(ystring,sizeof(ystring),"Race \"%s\" has been loaded for editing. (%d checkpoints)",tmp,BCurrentCheckpoints[b(playerid)]);
    
SendClientMessage(playeridCOLOR_GREEN,ystring);
    return 
1;
}
dcmd_saverace(playeridparams[])
{
    if(
RaceBuilders[playerid] != 0)
    {
        new 
tmp[256], idx;
        
tmp strtok(paramsidx);
        if(!
strlen(tmp))
        {
            
SendClientMessage(playeridCOLOR_WHITE"USAGE: /saverace [name]");
            return 
1;
        }
        if(
BCurrentCheckpoints[b(playerid)] < 2)
        {
            
SendClientMessage(playeridCOLOR_YELLOW"You need atleast 2 checkpoints to save!");
            return 
1;
        }
        new 
race_name[32],templine[42];
        
format(race_name32"%s.yr",tmp);
        if(
fexist(race_name))
        {
            
format(ystring,sizeof(ystring), "Race \"%s\" already exists.",tmp);
            
SendClientMessage(playeridCOLOR_REDystring);
            return 
1;
        }
        new 
File:f,Float:x,Float:y,Float:zBcreator[MAX_PLAYER_NAME];
        
GetPlayerName(playeridBcreatorMAX_PLAYER_NAME);
        
fopen(race_name,io_write);
        
format(templine,sizeof(templine),"YRACE %d %s %d %d %d %f\n"RACEFILE_VERSIONBcreatorBracemode[b(playerid)], Blaps[b(playerid)], BAirrace[b(playerid)], BCPsize[b(playerid)]);
        
fwrite(f,templine);
        
format(templine,sizeof(templine),"A 0 A 0 A 0 A 0 A 0\n"); //Best complete race times
        
fwrite(f,templine);
        
format(templine,sizeof(templine),"A 0 A 0 A 0 A 0 A 0\n"); //Best lap times
        
fwrite(f,templine);
        for(new 
0BCurrentCheckpoints[b(playerid)];i++)
        {
            
x=BRaceCheckpoints[b(playerid)][i][0];
            
y=BRaceCheckpoints[b(playerid)][i][1];
            
z=BRaceCheckpoints[b(playerid)][i][2];
            
format(templine,sizeof(templine),"%f %f %f\n",x,y,z);
            
fwrite(f,templine);
        }
        
fclose(f);
        
format(ystring,sizeof(ystring),"Your race \"%s\" has been saved.",tmp);
           
SendClientMessage(playeridCOLOR_GREENystring);
    }
    else
    {
        
SendClientMessage(playeridCOLOR_RED"You are not building a race!");
    }
    return 
1;
}
dcmd_setlaps(playerid,params[])
{
    new 
tmp[256], idx;
    
tmp strtok(paramsidx);
    if(!
strlen(tmp) || strval(tmp) <= 0)
    {
        
SendClientMessage(playeridCOLOR_WHITE"USAGE: /setlaps [amount of laps (min: 1)]");
        return 
1;
       }
    if(
RaceBuilders[playerid] != 0)
    {
        
Blaps[b(playerid)] = strval(tmp);
        
format(tmp,sizeof(tmp),"Amount of laps set to %d."Blaps[b(playerid)]);
        
SendClientMessage(playeridCOLOR_GREENtmp);
        return 
1;
    }
    if(
RaceAdmin == && IsNotAdmin(playerid)) return 1;
    if(
RaceActive == || RaceStart == 1SendClientMessage(playeridCOLOR_RED"Race already in progress!");
    else if(
LCurrentCheckpoint == 0SendClientMessage(playeridCOLOR_YELLOW"No race loaded.");
    else
    {
        
Racelaps=strval(tmp);
        
format(tmp,sizeof(tmp),"Amount of laps set to %d for current race."Racelaps);
        
SendClientMessage(playeridCOLOR_GREENtmp);
    }
    return 
1;
}
dcmd_racemode(playerid,params[])
{
    new 
tmp[256], idxtempmode;
    
tmp strtok(paramsidx);
    if(!
strlen(tmp))
    {
        
SendClientMessage(playeridCOLOR_WHITE"USAGE: /racemode [0/1/2/3]");
        return 
1;
       }
    if(
tmp[0] == 'd'tempmode=0;
    else if(
tmp[0] == 'r'tempmode=1;
    else if(
tmp[0] == 'y'tempmode=2;
    else if(
tmp[0] == 'm'tempmode=3;
    else 
tempmode=strval(tmp);
    if (
tempmode || tempmode 3)
       {
           
SendClientMessage(playeridCOLOR_YELLOW"Invalid racemode!");
        return 
1;
       }
    if(
RaceBuilders[playerid] != 0)
    {
        if(
tempmode == && BCurrentCheckpoints[b(playerid)] < 3)
        {
            
SendClientMessage(playeridCOLOR_YELLOW"Can't set racemode 2 on races with only 2 CPs. Changing to mode 1 instead.");
            
Bracemode[b(playerid)] = 1;
            return 
1;
        }
        
Bracemode[b(playerid)] = tempmode;
        
format(tmp,sizeof(tmp),"Racemode set to %d."Bracemode[b(playerid)]);
        
SendClientMessage(playeridCOLOR_GREENtmp);
        return 
1;
    }
    if(
RaceAdmin == && IsNotAdmin(playerid)) return 1;
    if(
RaceActive == || RaceStart == 1SendClientMessage(playeridCOLOR_RED"Race already in progress!");
    else if(
LCurrentCheckpoint == 0SendClientMessage(playeridCOLOR_YELLOW"No race loaded.");
    else
    {
        if(
tempmode == && LCurrentCheckpoint 2)
        {
            
SendClientMessage(playeridCOLOR_YELLOW"Can't set racemode 2 on races with only 2 CPs. Changing to mode 1 instead.");
            
Racemode 1;
            return 
1;
        }
        
Racemode=tempmode;
        
format(tmp,sizeof(tmp),"Racemode set to %d."Racemode);
        
SendClientMessage(playeridCOLOR_GREENtmp);
    }
    return 
1;
}
dcmd_loadrace(playeridparams[])
{
    if(
RaceAdmin == && IsNotAdmin(playerid)) return 1;
    
Racemode 0Racelaps 1;
    new 
tmp[128], idxfback;
    
tmp strtok(paramsidx);
    if(!
strlen(tmp))
    {
        
SendClientMessage(playeridCOLOR_WHITE"USAGE: /loadrace [name]");
        return 
1;
    }
    if(
RaceActive == 1)
    {
        
SendClientMessage(playeridCOLOR_RED"A race is already active!");
        return 
1;
    }
    
fback=LoadRace(tmp);
    if(
fback == -1format(ystring,sizeof(ystring),"Race \'%s\' doesn't exist!",tmp);
    else if (
fback == -2format(ystring,sizeof(ystring),"Race \'%s\' is created with a newer version of YRACE, cannot load.",tmp);
    if(
fback 0)
    {
        
SendClientMessage(playerid,COLOR_RED,ystring);
        return 
1;
    }
    
format(ystring,sizeof(ystring),"Race \'%s\' loaded, /startrace to start it. You can change laps and mode before that.",CRaceName);
    
SendClientMessage(playerid,COLOR_GREEN,ystring);
    if(
LCurrentCheckpoint<&& Racemode == 2)
    {
        
Racemode 1// Racemode 2 doesn't work well with only 2CPs, and mode 1 is just the same when playing with 2 CPs.
    
}                 // Setting racemode 2 is prevented from racebuilder so this shouldn't happen anyways.
#if defined MENUSYSTEM
    
if(!IsValidMenu(MRace)) CreateRaceMenus();
    if(
Airrace == 0SetMenuColumnHeader(MRace,0,"Air race: off");
    else 
SetMenuColumnHeader(MRace,0,"Air race: ON");
    
TogglePlayerControllable(playerid,0);
    
ShowMenuForPlayer(MRace,playerid);
#endif
    
return 1;
}
dcmd_startrace(playeridparams[])
{
    
#pragma unused params
    
if(RaceAdmin == && IsNotAdmin(playerid)) return 1;
    if(
LCurrentCheckpoint == 0SendClientMessage(playerid,COLOR_YELLOW,"No race loaded!");
    else if (
RaceActive == 1SendClientMessage(playerid,COLOR_YELLOW,"Race is already active!");
    else 
startrace();
    return 
1;
}
dcmd_deleterace(playeridparams[])
{
    if((
RaceAdmin == || BuildAdmin == 1) && IsNotAdmin(playerid)) return 1;
    new 
filename[128], idx;
    
filename strtok(params,idx);
    if(!(
strlen(filename)))
    {
        
SendClientMessage(playeridCOLOR_WHITE"USAGE: /deleterace [race]");
        return 
1;
    }
    
format(filename,sizeof(filename),"%s.yr",filename);
    if(!
fexist(filename))
    {
        
format(ystring,sizeof(ystring), "The race \"%s\" doesn't exist.",filename);
        
SendClientMessage(playeridCOLOR_REDystring);
        return 
1;
    }
    
fremove(filename);
    
format(ystring,sizeof(ystring), "The race \"%s\" has been deleted.",filename);
    
SendClientMessage(playeridCOLOR_GREENystring);
    return 
1;
}
dcmd_join(playerid,params[])
{
    
#pragma unused params
    
if(RaceBuilders[playerid] != 0)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"You are currently building a race, can't join. Use /clearrace to exit build mode.");
        return 
1;
    }
    if(
RaceParticipant[playerid]>0)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"You've already joined the race!");
    }
    else if(
RaceActive==&& RaceStart==0)
    {
        if(
PrizeMode >= && GetPlayerMoney(playerid) < JoinFee)
        {
            
format(ystring,sizeof(ystring),"You don't have enough money to join the race! (Join fee: %d$)",JoinFee);
            
SendClientMessage(playeridCOLOR_YELLOWystring);
            return 
1;
        }
        else if (
PrizeMode >= 2)
        {
            new 
tempval;
            
tempval=(-1)*JoinFee;
            
GivePlayerMoney(playerid,tempval);
            
Pot+=JoinFee;
        }
        
CurrentCheckpoint[playerid]=0;
        if(
Racemode == 3)
        {
            
SetRaceCheckpoint(playerid,LCurrentCheckpoint,LCurrentCheckpoint-1);
            
CurrentCheckpoint[playerid]=LCurrentCheckpoint;
        }
        else 
SetRaceCheckpoint(playerid,0,1);
        
RaceParticipant[playerid]=1;
        
CurrentLap[playerid]=0;
        if (
IsPlayerInAnyVehicle(playerid)) {
        
SetVehiclePos(GetPlayerVehicleID(playerid),RaceCheckpoints[CurrentCheckpoint[playerid]][0],RaceCheckpoints[CurrentCheckpoint[playerid]][1],RaceCheckpoints[CurrentCheckpoint[playerid]][2]);
        }
        if (!
IsPlayerInAnyVehicle(playerid)) {
        
SetPlayerPos(playerid,RaceCheckpoints[CurrentCheckpoint[playerid]][0],RaceCheckpoints[CurrentCheckpoint[playerid]][1],RaceCheckpoints[CurrentCheckpoint[playerid]][2]);
        }
        
RaceParticipant[playerid]=3;
        
Participants++;
    }
    else if(
RaceActive==&& RaceStart==1)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"The race has already started, can't join.");
    }
    else
    {
        
SendClientMessage(playeridCOLOR_YELLOW"There is no race you can join.");
    }
    return 
1;
}
dcmd_leave(playerid,params[])
{
    
#pragma unused params
    
if(RaceParticipant[playerid] > 0)
    {
           if(
RaceParticipant[playerid]==&& RaceStart == 1//Countdown in progress, no leaving during it.
        
{
            
SendClientMessage(playerid,COLOR_RED,"Unable to leave at this time: Countdown in progress.");
            return 
1;
        }
        
DisablePlayerRaceCheckpoint(playerid);
        
RaceParticipant[playerid]=0;
        
Participants--;
        
SendClientMessage(playerid,COLOR_YELLOW,"You have left the race.");
        if(
PrizeMode >= && RaceStart == 0)
        {
            
GivePlayerMoney(playerid,JoinFee/2);
            
Pot-=JoinFee/2;
        }
        if(
Participants == 0endrace();
        else if(
RaceStart == 0)SendClientMessage(playeridCOLOR_YELLOW"One participant out of the race.");
    }
    else 
SendClientMessage(playeridCOLOR_YELLOW"You aren't in a race.");
    return 
1;
}
dcmd_endrace(playeridparams[])
{
    
#pragma unused params
    
if(RaceAdmin == && IsNotAdmin(playerid)) return 1;
    if(
RaceActive==0)
    {
        
SendClientMessage(playeridCOLOR_YELLOW"There is no race active.");
        return 
1;
    }
    
endrace();
    return 
1;
}
dcmd_ready(playeridparams[])
{
    
#pragma unused params
    
new PState=GetPlayerState(playerid);
    if(
RaceParticipant[playerid]==&& PState != PLAYER_STATE_PASSENGER)
    {
        
SendClientMessage(playerid,COLOR_GREEN,"You are now ready. Type /ready again to cancel.");
        
RaceParticipant[playerid]=3;
        
ReadyRefresh();
    }
    else if (
RaceParticipant[playerid]==&& RaceStart==0)
    {
        
SendClientMessage(playerid,COLOR_YELLOW,"You are now not ready. Type /ready when you are.");
        
RaceParticipant[playerid]=2;
    }
    else if (
PState == PLAYER_STATE_PASSENGERSendClientMessage(playerid,COLOR_YELLOW,"You need to be driving for yourself!");
    else if(
RaceParticipant[playerid] == 1SendClientMessage(playerid,COLOR_YELLOW,"You must have visited the starting CP to /ready.");
    else 
SendClientMessage(playerid,COLOR_YELLOW,"You have not participated in a race.");
    return 
1;
}
dcmd_bestlap(playerid,params[])
{
    new 
tmp[64], idx;
    
tmp strtok(paramsidx);
    if(
LoadTimes(playerid,1,tmp)) return 1;
    if(
TopLapTimes[0] == 0)
    {
        
SendClientMessage(playerid,COLOR_YELLOW,"No scores available.");
        return 
1;
    }
    else if(
ORacemode == 0)
    {
        
SendClientMessage(playerid,COLOR_YELLOW,"This race doesn't have any laps.");
        return 
1;
    }
    
format(ystring,sizeof(ystring),"%s by %s - Best Laps:",CRaceName,CBuilder);
    
SendClientMessage(playerid,COLOR_GREEN,ystring);
    for(new 
i;i<5;i++)
    {
        if(
TopLapTimes[i] == 0)
        {
            
format(ystring,sizeof(ystring),"%d. None yet",i+1);
            
i=6;
        }
        else
        {
            
format(ystring,sizeof(ystring),"%d. %s - %s",i+1,BeHuman(TopLapTimes[i]),TopLappers[i]);
        }
        
SendClientMessage(playerid,COLOR_GREEN,ystring);
    }
    return 
1;
}
dcmd_bestrace(playerid,params[])
{
    new 
tmp[64], idx;
    
tmp strtok(paramsidx);
    if(
LoadTimes(playerid,0,tmp)) return 1;
    if(
TopRacerTimes[0] == 0)
    {
        
SendClientMessage(playerid,COLOR_YELLOW,"No scores available.");
        return 
1;
    }
    
format(ystring,sizeof(ystring),"%s by %s - Best Race times:",CRaceName,CBuilder);
    
SendClientMessage(playerid,COLOR_GREEN,ystring);
    for(new 
i;i<5;i++)
    {
        if(
TopRacerTimes[i] == 0)
        {
            
format(ystring,sizeof(ystring),"%d. None yet",i+1);
            
i=6;
        }
        else
        {
            
format(ystring,sizeof(ystring),"%d. %s - %s",i+1,BeHuman(TopRacerTimes[i]),TopRacers[i]);
        }
        
SendClientMessage(playerid,COLOR_GREEN,ystring);
    }
    return 
1;
}
dcmd_airrace(playerid,params[])
{
    
#pragma unused params
    
if(RaceBuilders[playerid] != 0)
    {
        if(
BAirrace[b(playerid)] == 0)
        {
            
SendClientMessage(playerid,COLOR_GREEN,"Air race enabled.");
            
BAirrace[b(playerid)]=1;
        }
        else
        {
            
SendClientMessage(playerid,COLOR_GREEN,"Air race disabled.");
            
BAirrace[b(playerid)]=0;
        }
        return 
1;
    }
    if(
RaceAdmin == && IsNotAdmin(playerid)) return 1;
    if(
RaceActive == || RaceStart == 1SendClientMessage(playeridCOLOR_YELLOW"Race is already in progress!");
    else if(
LCurrentCheckpoint == 0SendClientMessage(playeridCOLOR_YELLOW"No race loaded!");
    else if(
Airrace == 0)
    {
        
SendClientMessage(playerid,COLOR_GREEN,"Air race enabled.");
        
Airrace 1;
    }
    else if(
Airrace == 1)
    {
        
SendClientMessage(playerid,COLOR_GREEN,"Air race disabled.");
        
Airrace 0;
    }
    else 
printf("Error in /airrace detected. RaceActive: %d, RaceStart: %d LCurrentCheckpoint: %d, Airrace: %d"RaceActive,RaceStart,LCurrentCheckpoint,Airrace);
    return 
1;
}
dcmd_cpsize(playerid,params[])
{
    new 
idxtmp[32];
    
tmp strtok(params,idx);
    if(!(
strlen(tmp)) || floatstr(tmp) <= 0.0)
    {
        
SendClientMessage(playerid,COLOR_WHITE,"USAGE: /cpsize [size]");
        return 
1;
    }
    if(
RaceBuilders[playerid] != 0)
    {
        
BCPsize[b(playerid)] = floatstr(tmp);
        
format(ystring,sizeof(ystring),"Checkpoint size set to %f",floatstr(tmp));
        
SendClientMessage(playerid,COLOR_GREEN,ystring);
        return 
1;
    }
    if(
RaceAdmin == && IsNotAdmin(playerid)) return 1;
    if(
RaceActive == 1SendClientMessage(playeridCOLOR_YELLOW"Race has already been activated!");
    else if(
LCurrentCheckpoint == 0SendClientMessage(playeridCOLOR_YELLOW"No race loaded!");
    else
    {
        
CPsize floatstr(tmp);
        
format(ystring,sizeof(ystring),"Checkpoint size set to %f",floatstr(tmp));
        
SendClientMessage(playerid,COLOR_GREEN,ystring);
    }
    return 
1;
}
dcmd_prizemode(playerid,params[])
{
    if(
IsNotAdmin(playerid)) return 1;
    new 
idxtmp;
    
tmp=strval(strtok(params,idx));
    if(
tmp || tmp 4SendClientMessage(playerid,COLOR_WHITE,"USAGE: /prizemode [0-4]");
    else if(
RaceActive == 1SendClientMessage(playerid,COLOR_YELLOW,"Race is already active!");
    else
    {
        
PrizeMode tmp;
        
format(ystring,sizeof(ystring),"Prizemode set to %d",PrizeMode);
        
SendClientMessage(playerid,COLOR_GREEN,ystring);
    }
    return 
1;
}
dcmd_setprize(playerid,params[])
{
    if(
IsNotAdmin(playerid)) return 1;
    new 
idxtmp;
    
tmp strval(strtok(paramsidx));
    if(
>= tmpSendClientMessage(playerid,COLOR_WHITE,"USAGE: /setprize [amount]");
    else if(
RaceActive == 1SendClientMessage(playerid,COLOR_YELLOW,"Race is already active!");
    else
    {
        
Prize tmp;
        
format(ystring,sizeof(ystring),"Prize set to %d",Prize);
        
SendClientMessage(playerid,COLOR_GREEN,ystring);
    }
    return 
1;
}
#if defined MENUSYSTEM
dcmd_raceadmin(playerid,params[])
{
    
#pragma unused params
    
if(IsNotAdmin(playerid)) return 1;
    if(!
IsValidMenu(MAdmin)) CreateRaceMenus();
    
TogglePlayerControllable(playerid,0);
    
ShowMenuForPlayer(MAdmin,playerid);
    return 
1;
}
dcmd_buildmenu(playerid,params[])
{
    
#pragma unused params
    
if(BuildAdmin == && IsNotAdmin(playerid)) return 1;
    if(
RaceBuilders[playerid] == 0)
    {
        
SendClientMessage(playerid,COLOR_YELLOW,"You are not building a race!");
        return 
1;
    }
    if(
BAirrace[b(playerid)] == 0SetMenuColumnHeader(MBuild,0,"Air race: off");
    else 
SetMenuColumnHeader(MBuild,0,"Air race: on");
    if(!
IsValidMenu(MBuild)) CreateRaceMenus();
    
TogglePlayerControllable(playerid,0);
    
ShowMenuForPlayer(MBuild,playerid);
    return 
1;
}
#endif
public OnPlayerDisconnect(playerid,reason)
{
    if(
RaceParticipant[playerid]>=1)
    {
        if(
Participants==1//Last participant leaving, ending race.
        
{
            
endrace();
        }
        if(
RaceParticipant[playerid] < && RaceStart == && !(RaceParticipant[playerid]==&& RaceStart == 1)) 
        { 
//Doing readycheck since someone left, but not if they disconnected during countdown.
            
ReadyRefresh();
        }
        
Participants--;
        
RaceParticipant[playerid]=0;
        
DisablePlayerRaceCheckpoint(playerid);
    }
    if(
RaceBuilders[playerid] != 0)
    {
           
DisablePlayerRaceCheckpoint(playerid);
        for(new 
i;i<BCurrentCheckpoints[b(playerid)];i++)
        {
            
BRaceCheckpoints[b(playerid)][i][0]=0.0;
               
BRaceCheckpoints[b(playerid)][i][1]=0.0;
            
BRaceCheckpoints[b(playerid)][i][2]=0.0;
        }
        
BuilderSlots[b(playerid)] = MAX_PLAYERS+1;
        
RaceBuilders[playerid] = 0;
    } 
    return 
1;
}
strtok(const string[], &index)
{
    new 
length strlen(string);
    while ((
index length) && (string[index] <= ' '))
    {
        
index++;
    }
    new 
offset index;
    new 
result[20];
    while ((
index length) && (string[index] > ' ') && ((index offset) < (sizeof(result) - 1)))
    {
        
result[index offset] = string[index];
        
index++;
    }
    
result[index offset] = EOS;
    return 
result;
}
public 
LockRacers()
{
    for(new 
i;i<MAX_PLAYERS;i++)
    {
        if(
RaceParticipant[i] != 0)
        {
            
TogglePlayerControllable(i,0);
            if(
IsPlayerInAnyVehicle(i)) PlayerVehicles[i]=GetPlayerVehicleID(i);
            else 
PlayerVehicles[i]=0;
        }
    }
}
public 
UnlockRacers()
{
    for(new 
i;i<MAX_PLAYERS;i++)
    {
        if(
RaceParticipant[i]>0)
        {
            
TogglePlayerControllable(i,1);
            if(
PlayerVehicles[i] != 0)
            {
                
PutPlayerInVehicle(i,PlayerVehicles[i],0);
                
PlayerVehicles[i]=0;
            }
        }
    }
}
public 
countdown() {
    if(
RaceStart == 0)  // Locking players, setting the reward and
    
{
        
RaceStart=0;
        
LockRacers();
        new 
tmpprizeOPot;
        
OPot=Pot;
        if(
PrizeMode == || PrizeMode == 4)
        {
            if(
Racemode == || Racemode == 3tmpprize floatround(RLenght);
            else if(
Racemode == 1tmpprize floatround(LLenght Racelaps);
            else if(
Racemode == 2tmpprize floatround(RLenght Racelaps);
        }
        
tmpprize *= DynaMP;
        if(
PrizeMode == || PrizeMode == 3Pot += Prize;
        else if(
PrizeMode == || PrizeMode == 4Pot += tmpprize;
        if(
Participants == 1Pot=OPot// Only 1 racer, force reward to entrance fees.
    
}
    if(
cd>0)
    {
        
format(ystringsizeof(ystring), "%d",cd);
        for(new 
i=0;i<MAX_PLAYERS;i++)
        {
            if(
RaceParticipant[i]>1)
            {
                
RaceSound(i,1056);
                
RaceStart=0;
                
GameTextForPlayer(i,ystring,1000,3);
            }
        }
    }
    else if(
cd == 0)
    {
        
format(ystringsizeof(ystring), "~g~GO!~n~~r~~h~GO!~n~~p~GO!",cd);
        
KillTimer(Countdown);
        
RaceStart=1;
        for(new 
i=0;i<MAX_PLAYERS;i++)
        {
            if(
RaceParticipant[i]>1)
            {
                
RaceSound(i,1057);
                
GameTextForPlayer(i,ystring,3000,3);
                
RaceParticipant[i]=4;
                
CurrentLap[i]=1;
                if(
Racemode == 3SetRaceCheckpoint(i,LCurrentCheckpoint,LCurrentCheckpoint-1);
                else 
SetRaceCheckpoint(i,0,1);
            }
        }
        
UnlockRacers();
        
RaceTick=tickcount();
    }
    
cd--;
}
public 
SetNextCheckpoint(playerid)
{
    if(
Racemode == 0// Default Mode
    
{
        
CurrentCheckpoint[playerid]++;
        if(
CurrentCheckpoint[playerid] == LCurrentCheckpoint)
        {
            
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],-1);
            
RaceParticipant[playerid]=6;
        }
        else 
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],CurrentCheckpoint[playerid]+1);
    }
    else if(
Racemode == 1// Ring Mode
    
{
        
CurrentCheckpoint[playerid]++;
        if(
CurrentCheckpoint[playerid] == LCurrentCheckpoint+&& CurrentLap[playerid] == Racelaps)
        {
            
SetRaceCheckpoint(playerid,0,-1);
            
RaceParticipant[playerid]=6;
        }
        else if (
CurrentCheckpoint[playerid] == LCurrentCheckpoint+&& CurrentLap[playerid] != Racelaps)
        {
            
CurrentCheckpoint[playerid]=0;
            
SetRaceCheckpoint(playerid,0,1);
            
RaceParticipant[playerid]=5;
        }
        else if(
CurrentCheckpoint[playerid] == && RaceParticipant[playerid]==5)
        {
            
ChangeLap(playerid);
            if(
LCurrentCheckpoint==1)
            {
                
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],0);
            }
            else
            {
                
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],2);
            }
              
RaceParticipant[playerid]=4;
        }
        else
        {
            if(
LCurrentCheckpoint==|| CurrentCheckpoint[playerid] == LCurrentCheckpointSetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],0);
            else 
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],CurrentCheckpoint[playerid]+1);
        }
    }
    else if(
Racemode == 2// Yoyo-mode
    
{
        if(
RaceParticipant[playerid]==4)
        {
            if(
CurrentCheckpoint[playerid] == LCurrentCheckpoint// @ Last CP, trigger last-1
            
{
                
RaceParticipant[playerid]=5;
                
CurrentCheckpoint[playerid]=LCurrentCheckpoint-1;
                
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],CurrentCheckpoint[playerid]-1);
            }
            else if(
CurrentCheckpoint[playerid] == LCurrentCheckpoint-1// Second last CP, set next accordingly
            
{
                
CurrentCheckpoint[playerid]++;
                
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],CurrentCheckpoint[playerid]-1);
            }
            else
            {
                
CurrentCheckpoint[playerid]++;
                
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],CurrentCheckpoint[playerid]+1);
            }
        }
        else if(
RaceParticipant[playerid]==5)
        {
            if(
CurrentCheckpoint[playerid] == && CurrentLap[playerid] == Racelaps//Set the finish line
            
{
                
SetRaceCheckpoint(playerid,0,-1);
                
RaceParticipant[playerid]=6;
            }
            else if(
CurrentCheckpoint[playerid] == 0//At finish line, change lap.
            
{
                
ChangeLap(playerid);
                if(
LCurrentCheckpoint==1)
                {
                    
SetRaceCheckpoint(playerid,1,0);
                }
                else
                {
                    
SetRaceCheckpoint(playerid,1,2);
                }
                  
RaceParticipant[playerid]=4;
            }
            else if(
CurrentCheckpoint[playerid] == 1)
            {
                
CurrentCheckpoint[playerid]--;
                
SetRaceCheckpoint(playerid,0,1);
            }
            else
            {
                
CurrentCheckpoint[playerid]--;
                
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],CurrentCheckpoint[playerid]-1);
            }
        }
    }
    else if(
Racemode == 3// Mirror Mode
    
{
        
CurrentCheckpoint[playerid]--;
        if(
CurrentCheckpoint[playerid] == 0)
        {
            
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],-1);
            
RaceParticipant[playerid]=6;
        }
        else
        {
             
SetRaceCheckpoint(playerid,CurrentCheckpoint[playerid],CurrentCheckpoint[playerid]-1);
        }
    }
}
public 
SetRaceCheckpoint(playerid,target,next)
{
    if(
next == -&& Airrace == 0SetPlayerRaceCheckpoint(playerid,1,RaceCheckpoints[target][0],RaceCheckpoints[target][1],RaceCheckpoints[target][2],0.0,0.0,0.0,CPsize);
    else if(
next == -&& Airrace == 1SetPlayerRaceCheckpoint(playerid,4,RaceCheckpoints[target][0],RaceCheckpoints[target][1],RaceCheckpoints[target][2],0.0,0.0,0.0,CPsize);
    else if(
Airrace == 1SetPlayerRaceCheckpoint(playerid,3,RaceCheckpoints[target][0],RaceCheckpoints[target][1],RaceCheckpoints[target][2],RaceCheckpoints[next][0],
                            
RaceCheckpoints[next][1],RaceCheckpoints[next][2],CPsize);
    else 
SetPlayerRaceCheckpoint(playerid,0,RaceCheckpoints[target][0],RaceCheckpoints[target][1],RaceCheckpoints[target][2],RaceCheckpoints[next][0],RaceCheckpoints[next][1],
                            
RaceCheckpoints[next][2],CPsize);
}
public 
SetBRaceCheckpoint(playerid,target,next)
{
    new 
ar BAirrace[b(playerid)];
    if(
next == -&& ar == 0SetPlayerRaceCheckpoint(playerid,1,BRaceCheckpoints[b(playerid)][target][0],BRaceCheckpoints[b(playerid)][target][1],
                                
BRaceCheckpoints[b(playerid)][target][2],0.0,0.0,0.0,BCPsize[b(playerid)]);
    else if(
next == -&& ar == 1SetPlayerRaceCheckpoint(playerid,4,BRaceCheckpoints[b(playerid)][target][0],
                
BRaceCheckpoints[b(playerid)][target][1],BRaceCheckpoints[b(playerid)][target][2],0.0,0.0,0.0,
                
BCPsize[b(playerid)]);
    else if(
ar == 1SetPlayerRaceCheckpoint(playerid,3,BRaceCheckpoints[b(playerid)][target][0],BRaceCheckpoints[b(playerid)][target][1],BRaceCheckpoints[b(playerid)][target][2],
                        
BRaceCheckpoints[b(playerid)][next][0],BRaceCheckpoints[b(playerid)][next][1],BRaceCheckpoints[b(playerid)][next][2],BCPsize[b(playerid)]);
    else 
SetPlayerRaceCheckpoint(playerid,0,BRaceCheckpoints[b(playerid)][target][0],BRaceCheckpoints[b(playerid)][target][1],BRaceCheckpoints[b(playerid)][target][2],
            
BRaceCheckpoints[b(playerid)][next][0],BRaceCheckpoints[b(playerid)][next][1],BRaceCheckpoints[b(playerid)][next][2],BCPsize[b(playerid)]);
}
public 
GetLapTick(playerid)
{
    new 
ticklap;
    
tick=tickcount();
    if(
CurrentLap[playerid]==1)
    {
        
lap=tick-RaceTick;
        
LastLapTick[playerid]=tick;
    }
    else
    {
        
lap=tick-LastLapTick[playerid];
        
LastLapTick[playerid]=tick;
    }
    return 
lap;
}
public 
GetRaceTick(playerid)
{
    new 
tickrace;
    
tick=tickcount();
    
race=tick-RaceTick;
    return 
race;
}
public 
OnPlayerEnterRaceCheckpoint(playerid)
{
    if(
RaceParticipant[playerid]>=1// See if the player is participating in a race, allows race builders to do their stuff in peace.
    
{
        if(
RaceParticipant[playerid] == 6// Player reaches the checkered flag.
        
{
            new 
name[MAX_PLAYER_NAME], LapTimeRaceTime;
            
LapTime=GetLapTick(playerid);
            
RaceTime=GetRaceTick(playerid);
            
GetPlayerName(playeridnameMAX_PLAYER_NAME);
            
RaceParticipant[playerid]=0;
            
RaceSound(playerid,1139);
            
format(ystring,sizeof(ystring),"%s has finished the race, position: %d",name,Ranking);
            if (
Ranking 4SendClientMessageToAll(COLOR_GREEN,ystring);
            else 
SendClientMessage(playerid,COLOR_GREEN,ystring);
            if(
Racemode == ORacemode && ORacelaps == Racelaps)
            {
                new    
LapString[10],RaceString[10], laprankracerank;
                
LapString=BeHuman(LapTime);
                
RaceString=BeHuman(RaceTime);
                
format(ystring,sizeof(ystring),"~w~Racetime: %s",RaceString);
                if(
ORacemode!=0format(ystring,sizeof(ystring),"%s~n~Laptime: %s",ystring,LapString);
                
laprank=CheckBestLap(playerid,LapTime);
                if(
laprank == 1)
                {
                    
format(ystring,sizeof(ystring),"%s~n~~y~LAP RECORD!",ystring);
                }
                
racerank=CheckBestRace(playerid,RaceTime);
                if(
racerank == 1)
                {
                    
format(ystring,sizeof(ystring),"%s~n~~y~TRACK RECORD!",ystring);
                }
                
GameTextForPlayer(playerid,ystring,13000,3);
            }
            if(
Ranking<4)
            {
                new 
winrar;
                if(
Ranking == && Participants == 1winrar=Pot// If the player was only participant, give the whole pot.
                
else if(Ranking == && Participants == 2winrar=Pot/6*4// If only 2 participants, give 4/6ths of the pot.
                
else winrar=Pot/6*PrizeMP;  // Otherwise 3/6ths, 2/6ths and 1/6th.
                
GivePlayerMoney(playerid,winrar);
                
format(ystring,sizeof(ystring),"You have earned $%d from the race!",winrar);
                
PrizeMP--;
                
SendClientMessage(playerid,COLOR_GREEN,ystring);
            }
            
Ranking++;
            
Participants--;
            
DisablePlayerRaceCheckpoint(playerid);
            if(
Participants == 0)
            {
                
endrace();
            }
        }
        else if (
RaceStart == && RaceParticipant[playerid]==1// Player arrives to the start CP for 1st time
        
{
            
RaceParticipant[playerid]=2;
        }
        else if (
RaceStart==1// Otherwise switch to the next race CP.
        
{
            
RaceSound(playerid,1138);
            
SetNextCheckpoint(playerid);
        }
    }
    return 
1;
}
public 
endrace()
{
    
SaveScores(); //If the race had already started, and mode & laps are as originally, save the lapscores and racescores.
    
for(new i=0;i<LCurrentCheckpoint;i++)
    {
        
RaceCheckpoints[i][0]=0.0;
        
RaceCheckpoints[i][1]=0.0;
        
RaceCheckpoints[i][2]=0.0;
    }
    
LCurrentCheckpoint=0;
    for(new 
i=0;i<MAX_PLAYERS;i++)
    {
        
LastLapTick[i]=0;
        
DisablePlayerRaceCheckpoint(i);
        if(
RaceParticipant[i]==3//Player was still /ready-locked, unlocking.
        
{
                
TogglePlayerControllable(i,1);
                if(
PlayerVehicles[i] != 0)
                {
                    
PutPlayerInVehicle(i,PlayerVehicles[i],0);
                    
PlayerVehicles[i]=0;
                }
        }
        
RaceParticipant[i]=0;
    }
    
RaceActive=0;
    
RaceStart=0;
    
Participants=0;
    
Pot 0;
    
PrizeMP 3;
    
SendClientMessageToAll(COLOR_YELLOW"The current race has been finished.");
}
public 
BActiveCP(playerid,sele)
{
    if(
BCurrentCheckpoints[b(playerid)]-== seleSetBRaceCheckpoint(playerid,sele,-1);
    else 
SetBRaceCheckpoint(playerid,sele,sele+1);
}
public 
RaceSound(playerid,sound)
{
    new 
Float:x,Float:y,Float:z;
    
GetPlayerPos(playerid,x,y,z);
    
PlayerPlaySound(playerid,sound,x,y,z);
}
public 
ReadyRefresh()
{
format(ystring,sizeof(ystring),"The race will start in %d seconds!"MajorityDelay);
SendClientMessageToAll(COLOR_GREEN,ystring);
format(ystring,sizeof(ystring),"~w~The race will start in ~r~~h~%d ~w~sec    ~g~Type ~y~/join ~g~to join."MajorityDelay);
GameTextForAll(ystring5000);
MajStartTimer SetTimer("mscountdown",10000,1);
mscdMajorityDelay;
}
public 
mscountdown()
{
if(
RaceStart == || MajStart == 0)
    {
        
MajStart=0;
        
KillTimer(MajStartTimer);
    }
    else
    {
        
mscd-=10;
        if(
mscd <= 0)
        {
            for(new 
i;i<MAX_PLAYERS;i++)
            {
                if(
RaceParticipant[i] != && RaceParticipant[i] != 0)
                {
                    
GameTextForPlayer(i,"~r~You didn't make it in time!",6000,3);
                    
DisablePlayerRaceCheckpoint(i);
                    
RaceParticipant[i]=0;
                    
Participants--;
                }
                else if (
RaceParticipant[i]!=0SendClientMessage(i,COLOR_GREEN,"Countdown Begins");
            }
            
KillTimer(MajStartTimer);
            
cd=5;
            
Countdown SetTimer("countdown",1000,1);
        }
        else
        {
            new 
hurry_string[64];
            
format(ystring,sizeof(ystring),"~y~Race starting in ~w~%d~y~ seconds!",mscd);
            for(new 
i;i<MAX_PLAYERS;i++)
            {
                if(
RaceParticipant[i] < && mscd 31GivePlayerMoney(i,0);
                else if(
RaceParticipant[i] > 0GameTextForPlayer(i,ystring,6000,3);
            }
        }
    }
}
public 
CheckBestLap(playerid,laptime)
{
    if(
TopLapTimes[4]<laptime && TopLapTimes[4] != || Racemode == 0)
    {
        return 
0;  // If the laptime is more than the previous 5th on the top list, skip to end
    
}              // Or the race is gamemode 0 where laps don't really apply
    
for(new i;i<5;i++)
    {
        if(
TopLapTimes[i] == 0)
        {
            new 
playername[MAX_PLAYER_NAME];
            
GetPlayerName(playerid,playername,MAX_PLAYER_NAME);
            
TopLappers[i]=playername;
            
TopLapTimes[i]=laptime;
            
ScoreChange=1;
            return 
i+1;
        }
        else if(
TopLapTimes[i] > laptime)
        {
            for(new 
j=4;j>=i;j--)
            {
                
TopLapTimes[j+1]=TopLapTimes[j];
                
TopLappers[j+1]=TopLappers[j];
            }
            new 
playername[MAX_PLAYER_NAME];
            
GetPlayerName(playerid,playername,MAX_PLAYER_NAME);
            
TopLapTimes[i]=laptime;
            
TopLappers[i]=playername;
            
ScoreChange=1;
            return 
i+1;
        }
    }
    return -
1//Shouldn't get here.
}
public 
CheckBestRace(playerid,racetime)
{
    if(
TopRacerTimes[4]<racetime && TopRacerTimes[4] != 0) return 0;
    for(new 
i;i<5;i++)
    {
        if(
TopRacerTimes[i] == 0)
        {
            new 
playername[MAX_PLAYER_NAME];
            
GetPlayerName(playerid,playername,MAX_PLAYER_NAME);
            
TopRacers[i]=playername;
            
TopRacerTimes[i]=racetime;
            
ScoreChange=1;
            return 
i+1;
        }
        else if(
TopRacerTimes[i] > racetime)
        {
            for(new 
j=4;j>=i;j--)
            {
                
TopRacerTimes[j+1]=TopRacerTimes[j];
                
TopRacers[j+1]=TopRacers[j];
            }
            new 
playername[MAX_PLAYER_NAME];
            
GetPlayerName(playerid,playername,MAX_PLAYER_NAME);
            
TopRacerTimes[i]=racetime;
            
TopRacers[i]=playername;
            
ScoreChange=1;
            return 
i+1;
        }
    }
    return -
1//Shouldn't get here.
}
public 
SaveScores()
{
    if(
ScoreChange == 1)
    {
        
fremove(CFile);
        new 
File:f,Float:x,Float:y,Float:ztempline[512];
        
fopen(CFile,io_write);
        
format(templine,sizeof(templine),"YRACE %d %s %d %d %d %f\n"RACEFILE_VERSIONCBuilderORacemodeORacelapsOAirraceOCPsize);
        
fwrite(f,templine);
        
format(templine,sizeof(templine),"%s %d %s %d %s %d %s %d %s %d\n",
                
TopRacers[0],TopRacerTimes[0],TopRacers[1], TopRacerTimes[1], TopRacers[2],TopRacerTimes[2],
                 
TopRacers[3],TopRacerTimes[3],TopRacers[4], TopRacerTimes[4]);
        
fwrite(f,templine);
        
format(templine,sizeof(templine),"%s %d %s %d %s %d %s %d %s %d\n",
                
TopLappers[0],TopLapTimes[0],TopLappers[1], TopLapTimes[1], TopLappers[2],TopLapTimes[2],
                 
TopLappers[3],TopLapTimes[3],TopLappers[4], TopLapTimes[4]);
        
fwrite(f,templine);
        for(new 
0LCurrentCheckpoint+1;i++)
        {
            
x=RaceCheckpoints[i][0];
            
y=RaceCheckpoints[i][1];
            
z=RaceCheckpoints[i][2];
            
format(templine,sizeof(templine),"%f %f %f\n",x,y,z);
            
fwrite(f,templine);
        }
        
fclose(f);
    }
    
ScoreChange=0;
}
public 
ChangeLap(playerid)
{
    new 
LapTimeTimeString[10], checklap;
    
LapTime=GetLapTick(playerid);
    
TimeString=BeHuman(LapTime);
    
format(ystring,sizeof(ystring),"~w~Lap %d/%d - time: %s"CurrentLap[playerid], RacelapsTimeString);
    if(
Racemode == ORacemode && ORacelaps == Racelaps)
    {
        
checklap=CheckBestLap(playerid,LapTime);
        if(
checklap==1format(ystring,sizeof(ystring),"%s~n~~y~LAP RECORD!",ystring);
    }
    
CurrentLap[playerid]++;
    if(
CurrentLap[playerid] == Racelapsformat(ystring,sizeof(ystring),"%s~n~~g~Final lap!",ystring);
    
GameTextForPlayer(playerid,ystring,6000,3);
}
BeHuman(ticks)
{
    new 
HumanTime[10], minutessecondssecstring[2], msecstring[3];
    
minutes=ticks/60000;
    
ticks=ticks-(minutes*60000);
    
seconds=ticks/1000;
    
ticks=ticks-(seconds*1000);
    if(
seconds <10format(secstring,sizeof(secstring),"0%d",seconds);
    else 
format(secstring,sizeof(secstring),"%d",seconds);
    
format(HumanTime,sizeof(HumanTime),"%d:%s",minutes,secstring);
    if(
ticks 10format(msecstring,sizeof(msecstring),"00%d"ticks);
    else if(
ticks 100format(msecstring,sizeof(msecstring),"0%d",ticks);
    else 
format(msecstring,sizeof(msecstring),"%d",ticks);
    
format(HumanTime,sizeof(HumanTime),"%s.%s",HumanTime,msecstring);
    return 
HumanTime;
}
public 
LoadTimes(playerid,timemode,tmp[])
{
    new 
temprace[67], idx;
    
format(temprace,sizeof(temprace),"%s.yr",tmp);
    if(
strlen(tmp))
    {
        if(!
fexist(temprace))
        {
            
format(ystring,sizeof(ystring),"Race \'%s\' doesn't exist!",tmp);
            
SendClientMessage(playerid,COLOR_YELLOW,ystring);
            return 
1;
        }
        else
        {
            new 
File:ftempline[256], TBuilder[MAX_PLAYER_NAME], TempLapper[MAX_PLAYER_NAME], TempLap;
            
idx=0;
            
fopen(tempraceio_read);
            
fread(f,templine,sizeof(templine)); // Read header-line
            
if(templine[0] == 'Y'//Checking if the racefile is v0.2+
            
{
                new 
fileversion;
                
strtok(templine,idx); // read off YRACE
                
fileversion strval(strtok(templine,idx)); // read off the file version
                
if(fileversion RACEFILE_VERSION// Check if the race is made with a newer version of the racefile format
                
{
                    
format(ystring,sizeof(ystring),"Race \'%s\' is created with a newer version of YRACE, unable to load.",tmp);
                    
SendClientMessage(playerid,COLOR_RED,ystring);
                    return 
1;
                }
                
TBuilder=strtok(templine,idx); // read off RACEBUILDER
                
fread(f,templine,sizeof(templine)); // read off best race times
                
if(timemode ==1fread(f,templine,sizeof(templine)); // read off best lap times
                
idx=0;
                if(
timemode == 0format(ystring,sizeof(ystring),"%s by %s - Best race times:",tmp,TBuilder);
                else if(
timemode == 1format(ystring,sizeof(ystring),"%s by %s - Best laps:",tmp,TBuilder);
                else return 
1;
                
SendClientMessage(playerid,COLOR_GREEN,ystring);
                for(new 
i=0;i<5;i++)
                {
                    
TempLapper=strtok(templine,idx);
                    
TempLap=strval(strtok(templine,idx));
                    if(
TempLap == 0)
                    {
                        
format(ystring,sizeof(ystring),"%d. None yet",i+1);
                        
i=6;
                    }
                    else 
format(ystring,sizeof(ystring),"%d. %s - %s",i+1,BeHuman(TempLap),TempLapper);
                    
SendClientMessage(playerid,COLOR_GREEN,ystring);
                }
                return 
1;
            }
            else
            {
                
format(ystring,sizeof(ystring),"Race \'%s\' doesn't contain any time data.",tmp);
                
SendClientMessage(playerid,COLOR_GREEN,ystring);
                return 
1;
            }
        }
    }
    return 
0;
}
public 
IsNotAdmin(playerid)
{
    if (!
IsPlayerAdmin(playerid))
    {
        
SendClientMessage(playeridCOLOR_RED"You need to be an admin to use this command!");
        return 
1;
    }
    return 
0;
}
public 
GetBuilderSlot(playerid)
{
    for(new 
i;MAX_BUILDERSi++)
    {
        if(!(
BuilderSlots[i] < MAX_PLAYERS+1))
        {
            
BuilderSlots[i] = playerid;
            
RaceBuilders[playerid] = i+1;
            return 
i+1;
        }
    }
    return 
0;
}
public 
b(playerid) return RaceBuilders[playerid]-1;
public 
Float:Distance(Float:x1,Float:y1,Float:z1,Float:x2,Float:y2,Float:z2)
{
    new 
Float:temp=floatsqroot((x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) + (z1-z2) * (z1-z2));
    if(
temp 0temp=temp*(-1);
    return 
temp;
}
public 
clearrace(playerid)
{
    for(new 
i=0;i<BCurrentCheckpoints[b(playerid)];i++)
    {
        
BRaceCheckpoints[b(playerid)][i][0]=0.0;
        
BRaceCheckpoints[b(playerid)][i][1]=0.0;
        
BRaceCheckpoints[b(playerid)][i][2]=0.0;
    }
    
BCurrentCheckpoints[b(playerid)]=0;
    
DisablePlayerRaceCheckpoint(playerid);
    
SendClientMessage(playeridCOLOR_GREEN"Your race has been cleared! Use /buildrace to start a new one.");
    
BuilderSlots[b(playerid)] = MAX_PLAYERS+1;
    
RaceBuilders[playerid]=0;
}
public 
startrace()
{
    
format(ystring,128,"Race \'%s\' is about to start, type /join to join!",CRaceName);
    
SendClientMessageToAll(COLOR_GREEN,ystring);
    if(
Racemode == 0format(ystring,sizeof(ystring),"default");
    else if(
Racemode == 1format(ystring,sizeof(ystring),"ring");
    else if(
Racemode == 2format(ystring,sizeof(ystring),"yoyo");
    else if(
Racemode == 3format(ystring,sizeof(ystring),"mirror");
    
format(ystring,sizeof(ystring),"Racemode: %s Laps: %d",ystring,Racelaps);
    if(
PrizeMode >= 2format(ystring,sizeof(ystring),"%s Join fee: %d",ystring,JoinFee);
    if(
Airrace == 1format(ystring,sizeof(ystring),"%s AIR RACE",ystring);
    if(
Racemode == || Racemode == 3format(ystring,sizeof(ystring),"%s Track lenght: %0.2fkm"ystringRLenght/1000);
    else if(
Racemode == 1format(ystring,sizeof(ystring),"%s Lap lenght: %.2fkm, Total: %.2fkm"ystringLLenght/1000LLenght Racelaps 1000);
    
SendClientMessageToAll(COLOR_GREEN,ystring);
    
RaceStart=0;
    
RaceActive=1;
    
ReadyRefresh();
    
ScoreChange=0;
    
Ranking=1;
    
PrizeMP=3;
    
MajStart=1;
}
ReturnModeName(mode)
{
    new 
modename[8];
    if(
mode == 0modename="Default";
    else if(
mode == 1modename="Ring";
    else if(
mode == 2modename="Yoyo";
    else if(
mode == 3modename="Mirror";
    return 
modename;
}
public 
LoadRace(tmp[])
{
    new 
race_name[32],templine[512];
    
format(CRaceName,sizeof(CRaceName), "%s",tmp);
    
format(race_name,sizeof(race_name), "%s.yr",tmp);
    if(!
fexist(race_name)) return -1// File doesn't exist
    
CFile=race_name;
    
LCurrentCheckpoint=-1RLenght=0RLenght=0;
    new 
File:fi;
    
fopen(race_nameio_read);
    
fread(f,templine,sizeof(templine));
    if(
templine[0] == 'Y'//Checking if the racefile is v0.2+
    
{
        new 
fileversion;
        
strtok(templine,i); // read off YRACE
        
fileversion strval(strtok(templine,i)); // read off the file version
        
if(fileversion RACEFILE_VERSION) return -2// Check if the race is made with a newer version of the racefile format
        
CBuilder=strtok(templine,i); // read off RACEBUILDER
        
ORacemode strval(strtok(templine,i)); // read off racemode
        
ORacelaps strval(strtok(templine,i)); // read off amount of laps
        
if(fileversion 1)
        {
            
Airrace strval(strtok(templine,i));   // read off airrace
            
CPsize floatstr(strtok(templine,i));    // read off CP size
        
}
        else 
// v1 file format, set to default
        
{
            
Airrace 0;
            
CPsize 8.0;
        }
        
OAirrace Airrace;
        
OCPsize CPsize;
        
Racemode=ORacemodeRacelaps=ORacelaps//Allows changing the modes, but disables highscores if they've been changed.
        
fread(f,templine,sizeof(templine)); // read off best race times
        
i=0;
        for(new 
j=0;j<5;j++)
        {
            
TopRacers[j]=strtok(templine,i);
            
TopRacerTimes[j]=strval(strtok(templine,i));
        }
        
fread(f,templine,sizeof(templine)); // read off best lap times
        
i=0;
        for(new 
j=0;j<5;j++)
        {
            
TopLappers[j]=strtok(templine,i);
            
TopLapTimes[j]=strval(strtok(templine,i));
        }
    }
    else 
//Otherwise add the lines as checkpoints, the file is made with v0.1 (or older) version of the script.
    
{
        
LCurrentCheckpoint++;
        
RaceCheckpoints[LCurrentCheckpoint][0] = floatstr(strtok(templine,i));
        
RaceCheckpoints[LCurrentCheckpoint][1] = floatstr(strtok(templine,i));
        
RaceCheckpoints[LCurrentCheckpoint][2] = floatstr(strtok(templine,i));
        
Racemode=0ORacemode=0Racelaps=0ORacelaps=0;   //Enables converting old files to new versions
        
CPsize 8.0Airrace 0;              // v2 additions
        
OCPsize CPsizeOAirrace Airrace;   // v2 additions
        
CBuilder="UNKNOWN";
        for(new 
j;j<5;j++)
        {
            
TopLappers[j]="A"TopLapTimes[j]=0TopRacers[j]="A"TopRacerTimes[j]=0;
        }
    }
    while(
fread(f,templine,sizeof(templine),false))
    {
        
LCurrentCheckpoint++;
        
i=0;
        
RaceCheckpoints[LCurrentCheckpoint][0] = floatstr(strtok(templine,i));
        
RaceCheckpoints[LCurrentCheckpoint][1] = floatstr(strtok(templine,i));
        
RaceCheckpoints[LCurrentCheckpoint][2] = floatstr(strtok(templine,i));
        if(
LCurrentCheckpoint >= 1)
        {
            
RLenght+=Distance(RaceCheckpoints[LCurrentCheckpoint][0],RaceCheckpoints[LCurrentCheckpoint][1],
                                
RaceCheckpoints[LCurrentCheckpoint][2],RaceCheckpoints[LCurrentCheckpoint-1][0],
                                
RaceCheckpoints[LCurrentCheckpoint-1][1],RaceCheckpoints[LCurrentCheckpoint-1][2]);
        }
    }
    
LLenght RLenght Distance(RaceCheckpoints[LCurrentCheckpoint][0],RaceCheckpoints[LCurrentCheckpoint][1],
                                
RaceCheckpoints[LCurrentCheckpoint][2],RaceCheckpoints[0][0],RaceCheckpoints[0][1],
                                
RaceCheckpoints[0][2]);
    
fclose(f);
    return 
1;
}
public 
RaceRotation()
{
    if(!
fexist("yrace.rr"))
    {
        
printf("ERROR in  YRACE's Race Rotation (yrace.rr): yrace.rr doesn't exist!");
        return -
1;
    }
    if(
RRotation == -1)
    {
        
KillTimer(RotationTimer);
        return -
1// RRotation has been disabled
    
}
    if(
Participants 0) return 1// A race is still active.
    
new File:ftempline[32], rotfile[]="yrace.rr"rraces=-1rracenames[32][32], idxfback;
    
fopen(rotfileio_read);
    while(
fread(f,templine,sizeof(templine),false))
    {
        
idx 0;
        
rraces++;
        
rracenames[rraces]=strtok(templine,idx);
    }
    
fclose(f);
    
RRotation++;
    if(
RRotation rracesRRotation 0;
    
fback LoadRace(rracenames[RRotation]);
    if(
fback == -1printf("ERROR in YRACE's Race Rotation (yrace.rr): Race \'%s\' doesn't exist!",rracenames[RRotation]);
    else if (
fback == -2printf("ERROR in YRACE's Race Rotation (yrace.rr): Race \'%s\' is created with a newer version of YRACE",rracenames[RRotation]);
    else 
startrace();
    return 
1;
}
#if defined MENUSYSTEM
public OnPlayerExitedMenu(playerid)
{
    if(!
IsValidMenu(GetPlayerMenu(playerid))) return 1;
    
ShowMenuForPlayer(GetPlayerMenu(playerid), playerid);
    return 
1;
}
public 
OnPlayerSelectedMenuRow(playeridrow)
{
    new 
Menu:Current GetPlayerMenu(playerid);
    if(
Current == MAdmin)
    {
        if(
row <=&& RaceActive == 1)
        {
            
SendClientMessage(playerid,COLOR_RED,"Race active, cannot change this setting!");
            
ShowMenuForPlayer(MAdmin,playerid);
            return 
1;
        }
        if(
row == 0ShowMenuForPlayer(MPMode,playerid);
        else if (
row == 1ShowMenuForPlayer(MPrize,playerid);
        else if (
row == 2ShowMenuForPlayer(MDyna,playerid);
        else if (
row == 3ShowMenuForPlayer(MFee,playerid);
        else if (
row == 4ShowMenuForPlayer(MDelay,playerid);
        else if (
row == 5)
        {
            if(
RaceActive == 1endrace();
            else 
SendClientMessage(playerid,COLOR_YELLOW,"No race active!");
            
ShowMenuForPlayer(MAdmin,playerid);
        }
        else if (
row == 9)
        {
            
TogglePlayerControllable(playerid,1);
            
HideMenuForPlayer(MAdmin,playerid);
        }
        else
        {
            if(
row == && RaceAdmin == 1RaceAdmin=0;
            else if(
row == && RaceAdmin == 0RaceAdmin=1;
            else if(
row == && BuildAdmin == 1BuildAdmin=0;
            else if(
row == && BuildAdmin == 0BuildAdmin=1;
            else if(
row == && RRotation >= 0RRotation = -1;
            else 
RRotation 0;
            if(
RaceAdmin == 1format(ystring,sizeof(ystring),"RA: ON");
            else 
format(ystring,sizeof(ystring),"RA: off");
            if(
BuildAdmin == 1format(ystring,sizeof(ystring),"%s BA: ON",ystring);
            else 
format(ystring,sizeof(ystring),"%s BA: off",ystring);
            if(
RRotation >= 0format(ystring,sizeof(ystring),"%s RR: ON",ystring);
            else 
format(ystring,sizeof(ystring),"%s RR: off",ystring);
            if(
RRotation >= && row == 8)  RotationTimer SetTimer("RaceRotation",RRotationDelay,1);
            else if(
RRotation -&& row == 8KillTimer(RotationTimer);
            
RefreshMenuHeader(playerid,MAdmin,ystring);
        }
    }
    else if(
Current == MPMode)
    {
        if(
row == 5)
        {
             
ShowMenuForPlayer(MAdmin,playerid);
             return 
1;
        }
        
PrizeMode row;
        if     (
PrizeMode == 0ystring "Fixed";
        else if(
PrizeMode == 1ystring "Dynamic";
        else if(
PrizeMode == 2ystring "Join Fee";
        else if(
PrizeMode == 3ystring "Join Fee + Fixed";
        else if(
PrizeMode == 4ystring "Join Fee + Dynamic";
        
format(ystring,sizeof(ystring),"Mode: %s",ystring);
        
RefreshMenuHeader(playerid,MPMode,ystring);
    }
    else if(
Current == MPrize)
    {
        if(
row == 6)
        {
            
ShowMenuForPlayer(MAdmin,playerid);
            return 
1;
        }
        if     (
row == 0Prize += 100;
        else if(
row == 1Prize += 1000;
        else if(
row == 2Prize += 10000;
        else if(
row == 3Prize -= 100;
        else if(
row == 4Prize -= 1000;
        else if(
row == 5Prize -= 10000;
        if(
Prize 0Prize 0;
        
format(ystring,sizeof(ystring),"Amount: %d",Prize);
        
RefreshMenuHeader(playerid,MPrize,ystring);
    }
    else if(
Current == MDyna)
    {
        if(
row == 4)
        {
            
ShowMenuForPlayer(MAdmin,playerid);
            return 
1;
        }
        if     (
row == 0DynaMP++;
        else if(
row == 1DynaMP+=5;
        else if(
row == 2DynaMP--;
        else if(
row == 3DynaMP-=5;
        else if(
DynaMP 1DynaMP 1;
        
format(ystring,sizeof(ystring),"Multiplier: %dx",DynaMP);
        
RefreshMenuHeader(playerid,MDyna,ystring);
    }
    else if(
Current == MBuild)
    {
        if (
row == 0)
        {
            
format(ystring,sizeof(ystring),"Laps: %d",Blaps[b(playerid)]);
            
SetMenuColumnHeader(MLaps,0,ystring);
            
ShowMenuForPlayer(MLaps,playerid);
        }
        else if (
row == 1)
        {
            
format(ystring,sizeof(ystring),"Mode: %s",ReturnModeName(Bracemode[b(playerid)]));
            
SetMenuColumnHeader(MRacemode,0,ystring);
            
ShowMenuForPlayer(MRacemode,playerid);
        }
        else if (
row == 2)
        {
            
format(ystring,sizeof(ystring),"Size: %0.2f",BCPsize[b(playerid)]);
            
SetMenuColumnHeader(MCPsize,0,ystring);
            
ShowMenuForPlayer(MCPsize,playerid);
        }
        else if (
row == 3)
        {
            if(
BAirrace[b(playerid)] == 0)
            {
                
BAirrace[b(playerid)] = 1;
                
format(ystring,sizeof(ystring),"Air race: ON");
            }
               else if(
BAirrace[b(playerid)] == 1)
            {
                
BAirrace[b(playerid)] = 0;
                
format(ystring,sizeof(ystring),"Air race: off");
            }
               
RefreshMenuHeader(playerid,MBuild,ystring);
        }
        else if(
row == 4)
        {
            
clearrace(playerid);
            
HideMenuForPlayer(MBuild,playerid);
            
TogglePlayerControllable(playerid,1);
            return 
1;
        }
        else if(
row == 5)
        {
            
HideMenuForPlayer(MBuild,playerid);
            
TogglePlayerControllable(playerid,1);
        }
    }
    else if(
Current == MLaps)
    {
        if(
row == 6)
        {
            if(
RaceBuilders[playerid] != 0ShowMenuForPlayer(MBuild,playerid);
            else 
ShowMenuForPlayer(MRace,playerid);
            return 
1;
        }
        new 
change=0;
        if     (
row == 0change++;
        else if(
row == 1change+=5;
        else if(
row == 2change+=10;
        else if(
row == 3change--;
        else if(
row == 4change-=5;
        else if(
row == 5change-=10;
        if(
RaceBuilders[playerid] != 0)
        {
            
Blaps[b(playerid)] += change;
            if(
Blaps[b(playerid)] < 1Blaps[b(playerid)] = 1;
            
format(ystring,sizeof(ystring),"Laps: %d",Blaps[b(playerid)]);
            
RefreshMenuHeader(playerid,MLaps,ystring);
        }
        else
        {
            
Racelaps += change;
            if(
Racelaps 1Racelaps 1;
            
format(ystring,sizeof(ystring),"Laps: %d",Racelaps);
            
RefreshMenuHeader(playerid,MLaps,ystring);
        }
    }
    else if(
Current == MRacemode)
    {
        if(
row == 4)
        {
            if(
RaceBuilders[playerid] != 0ShowMenuForPlayer(MBuild,playerid);
            else 
ShowMenuForPlayer(MRace,playerid);
            return 
1;
        }
        if(
RaceBuilders[playerid] != 0)
        {
            
Bracemode[b(playerid)]=row;
            if(
Bracemode[b(playerid)] == && BCurrentCheckpoints[b(playerid)] < 3)
            {
                
SendClientMessage(playerid,COLOR_YELLOW,"Cannot set racemode 2 with only 2 CPs!");
                
Bracemode[b(playerid)] = 1;
            }
            
format(ystring,sizeof(ystring),"Mode: %s",ReturnModeName(Bracemode[b(playerid)]));
            
RefreshMenuHeader(playerid,MRacemode,ystring);
            return 
1;
        }
        else
        {
            
Racemode row;
            if(
Racemode == && LCurrentCheckpoint 2)
            {
                
SendClientMessage(playerid,COLOR_YELLOW,"Cannot set racemode 2 with only 2 CPs!");
                
Racemode 1;
            }
            
format(ystring,sizeof(ystring),"Mode: %s",ReturnModeName(Racemode));
            
RefreshMenuHeader(playerid,MRacemode,ystring);
            return 
1;
        }
    }
    else if(
Current == MRace)
    {
        if(
row == 0)
        {
            
format(ystring,sizeof(ystring),"Laps: %d",Racelaps);
            
SetMenuColumnHeader(MLaps,0,ystring);
            
ShowMenuForPlayer(MLaps,playerid);
        }
        else if(
row == 1)
        {
            
format(ystring,sizeof(ystring),"Mode: %s",ReturnModeName(Racemode));
            
SetMenuColumnHeader(MRacemode,0,ystring);
            
ShowMenuForPlayer(MRacemode,playerid);
        }
        else if(
row == 2)
        {
            
format(ystring,sizeof(ystring),"Size: %0.2f",CPsize);
            
SetMenuColumnHeader(MCPsize,0,ystring);
            
ShowMenuForPlayer(MCPsize,playerid);
        }
        else if(
row == 3)
        {
            if(
Airrace == 0)
            {
                
Airrace 1;
                
format(ystring,sizeof(ystring),"Air race: ON");
            }
            else if(
Airrace == 1)
            {
                
Airrace 0;
                
format(ystring,sizeof(ystring),"Air race: off");
            }
            
RefreshMenuHeader(playerid,MRace,ystring);
        }
        else if(
row == 4)
        {
            if(
RaceActive == 0)
            {
                
startrace();
                
HideMenuForPlayer(MRace,playerid);
                
TogglePlayerControllable(playerid,1);
            }
            else
            {
                
SendClientMessage(playerid,COLOR_YELLOW,"Race is already active!");
                
            }
        }
        else if(
row == 5)
        {
            
HideMenuForPlayer(MRace,playerid);
            
TogglePlayerControllable(playerid,1);
        }
    }
    else if(
Current == MFee)
    {
        if(
row == 6)
        {
            
ShowMenuForPlayer(MAdmin,playerid);
            return 
1;
        }
        if(
row == 0JoinFee +=100;
        if(
row == 1JoinFee +=1000;
        if(
row == 2JoinFee +=10000;
        if(
row == 3JoinFee -=100;
        if(
row == 4JoinFee -=1000;
        if(
row == 5JoinFee -=10000;
        if(
JoinFee 0JoinFee 0;
        
format(ystring,sizeof(ystring),"Fee: %d$",JoinFee);
        
RefreshMenuHeader(playerid,MFee,ystring);
    }
    else if(
Current == MCPsize)
    {
        if(
row == 6)
        {
            if(
RaceBuilders[playerid] != 0ShowMenuForPlayer(MBuild,playerid);
            else 
ShowMenuForPlayer(MRace,playerid);
            return 
1;
        }
        new 
Float:change;
        if(
row == 0change +=0.1;
        if(
row == 1change +=1.0;
        if(
row == 2change +=10.0;
        if(
row == 3change -=0.1;
        if(
row == 4change -=1.0;
        if(
row == 5change -=10.0;
        if(
RaceBuilders[playerid] != 0)
        {
            
BCPsize[b(playerid)] += change;
            if(
BCPsize[b(playerid)] < 1.0BCPsize[b(playerid)] = 1.0;
            if(
BCPsize[b(playerid)] > 32.0BCPsize[b(playerid)] = 32.0;
            
format(ystring,sizeof(ystring),"Size %0.2f",BCPsize[b(playerid)]);
            
RefreshMenuHeader(playerid,MCPsize,ystring);
        }
        else
        {
            
CPsize += change;
            if(
CPsize 1.0CPsize 1.0;
            if(
CPsize 32.0CPsize 32.0;
            
format(ystring,sizeof(ystring),"Size %0.2f",CPsize);
            
RefreshMenuHeader(playerid,MCPsize,ystring);
        }
    }
    else if(
Current == MDelay)
    {
        if(
row == 4)
        {
            
ShowMenuForPlayer(MAdmin,playerid);
            return 
1;
        }
        if      (
row == 0MajorityDelay+=10;
        else if (
row == 1MajorityDelay+=60;
        else if (
row == 2MajorityDelay-=10;
        else if (
row == 3MajorityDelay-=60;
        if(
MajorityDelay <= 0)
        {
            
MajorityDelay=0;
            
format(ystring,sizeof(ystring),"Delay: disabled");
        }
        else 
format(ystring,sizeof(ystring),"Delay: %ds",MajorityDelay);
        
RefreshMenuHeader(playerid,MDelay,ystring);
    }
    return 
1;
}
public 
RefreshMenuHeader(playerid,Menu:menu,text[])
{
    
SetMenuColumnHeader(menu,0,text);
    
ShowMenuForPlayer(menu,playerid);
}
public 
CreateRaceMenus()
{
    
//Admin menu
    
MAdmin CreateMenu("Admin menu"12517022025);
    
AddMenuItem(MAdmin,0,"Set prizemode...");
    
AddMenuItem(MAdmin,0,"Set fixed prize...");
    
AddMenuItem(MAdmin,0,"Set dynamic prize...");
    
AddMenuItem(MAdmin,0,"Set entry fees...");
    
AddMenuItem(MAdmin,0,"Majority delay...");
    
AddMenuItem(MAdmin,0,"End current race");
    
AddMenuItem(MAdmin,0,"Toggle Race Admin [RA]");
    
AddMenuItem(MAdmin,0,"Toggle Build Admin [BA]");
    
AddMenuItem(MAdmin,0,"Toggle Race Rotation [RR]");
    
AddMenuItem(MAdmin,0,"Leave");
    if(
RaceAdmin == 1format(ystring,sizeof(ystring),"RA: ON");
    else 
format(ystring,sizeof(ystring),"RA: off");
    if(
BuildAdmin == 1format(ystring,sizeof(ystring),"%s BA: ON",ystring);
    else 
format(ystring,sizeof(ystring),"%s BA: off",ystring);
    if(
RRotation >= 0format(ystring,sizeof(ystring),"%s RR: ON",ystring);
    else 
format(ystring,sizeof(ystring),"%s RR: off",ystring);
    
SetMenuColumnHeader(MAdmin,0,ystring);
    
//Prizemode menu [Admin submenu]
    
MPMode CreateMenu("Set prizemode:"12517022025);
    
AddMenuItem(MPMode,0,"Fixed");
    
AddMenuItem(MPMode,0,"Dynamic");
    
AddMenuItem(MPMode,0,"Entry Fee");
    
AddMenuItem(MPMode,0,"Entry Fee + Fixed");
    
AddMenuItem(MPMode,0,"Entry Fee + Dynamic");
    
AddMenuItem(MPMode,0,"Back");
    
SetMenuColumnHeader(MPMode,0,"Mode: Fixed");
    
//Fixed prize menu
    
MPrize CreateMenu("Fixed prize:"12517022025);
    
AddMenuItem(MPrize,0,"+100$");
    
AddMenuItem(MPrize,0,"+1000$");
    
AddMenuItem(MPrize,0,"+10000$");
    
AddMenuItem(MPrize,0,"-100$");
    
AddMenuItem(MPrize,0,"-1000$");
    
AddMenuItem(MPrize,0,"-10000$");
    
AddMenuItem(MPrize,0,"Back");
    
format(ystring,sizeof(ystring),"Amount: %d",Prize);
    
SetMenuColumnHeader(MPrize,0,ystring);
    
//Dynamic prize menu
    
MDyna CreateMenu("Dynamic Prize:"12517022025);
    
AddMenuItem(MDyna,0,"+1x");
    
AddMenuItem(MDyna,0,"+5x");
    
AddMenuItem(MDyna,0,"-1x");
    
AddMenuItem(MDyna,0,"-5x");
    
AddMenuItem(MDyna,0,"Leave");
    
format(ystring,sizeof(ystring),"Multiplier: %dx",DynaMP);
    
SetMenuColumnHeader(MDyna,0,ystring);
    
//Build Menu
    
MBuild CreateMenu("Build Menu"12517022025);
    
AddMenuItem(MBuild,0,"Set laps...");
    
AddMenuItem(MBuild,0,"Set racemode...");
    
AddMenuItem(MBuild,0,"Checkpoint size...");
    
AddMenuItem(MBuild,0,"Toggle air race");
    
AddMenuItem(MBuild,0,"Clear the race and exit");
    
AddMenuItem(MBuild,0,"Leave");
    
SetMenuColumnHeader(MBuild,0,"Air race: off");
    
//Laps menu
    
MLaps CreateMenu("Set laps"12517022025);
    
AddMenuItem(MLaps,0,"+1");
    
AddMenuItem(MLaps,0,"+5");
    
AddMenuItem(MLaps,0,"+10");
    
AddMenuItem(MLaps,0,"-1");
    
AddMenuItem(MLaps,0,"-5");
    
AddMenuItem(MLaps,0,"-10");
    
AddMenuItem(MLaps,0,"Back");
    
//Racemode menu
    
MRacemode CreateMenu("Racemode"12517022025);
    
AddMenuItem(MRacemode,0,"Default");
    
AddMenuItem(MRacemode,0,"Ring");
    
AddMenuItem(MRacemode,0,"Yoyo");
    
AddMenuItem(MRacemode,0,"Mirror");
    
AddMenuItem(MRacemode,0,"Back");
    
//Race menu
    
MRace CreateMenu("Race Menu"12517022025);
    
AddMenuItem(MRace,0,"Set laps...");
    
AddMenuItem(MRace,0,"Set racemode...");
    
AddMenuItem(MRace,0,"Set checkpoint size...");
    
AddMenuItem(MRace,0,"Toggle air race");
    
AddMenuItem(MRace,0,"Start race");
    
AddMenuItem(MRace,0,"Abort new race");
    
//Entry fee menu
    
MFee CreateMenu("Entry fees"12517022025);
    
AddMenuItem(MFee,0,"+100");
    
AddMenuItem(MFee,0,"+1000");
    
AddMenuItem(MFee,0,"+10000");
    
AddMenuItem(MFee,0,"-100");
    
AddMenuItem(MFee,0,"-1000");
    
AddMenuItem(MFee,0,"-10000");
    
AddMenuItem(MFee,0,"Back");
    
format(ystring,sizeof(ystring),"Fee: %d$",JoinFee);
    
SetMenuColumnHeader(MFee,0,ystring);
    
//CP size menu
    
MCPsize CreateMenu("CP size"12517022025);
    
AddMenuItem(MCPsize,0,"+0.1");
    
AddMenuItem(MCPsize,0,"+1");
    
AddMenuItem(MCPsize,0,"+10");
    
AddMenuItem(MCPsize,0,"-0.1");
    
AddMenuItem(MCPsize,0,"-1");
    
AddMenuItem(MCPsize,0,"-10");
    
AddMenuItem(MCPsize,0,"Back");
    
//Majority Delay menu
    
MDelay CreateMenu("Majority Delay"12517022025);
    
AddMenuItem(MDelay,0,"+10s");
    
AddMenuItem(MDelay,0,"+60s");
    
AddMenuItem(MDelay,0,"-10s");
    
AddMenuItem(MDelay,0,"-60s");
    
AddMenuItem(MDelay,0,"Back");
    if(
MajorityDelay == 0format(ystring,sizeof(ystring),"Delay: disabled");
    else 
format(ystring,sizeof(ystring),"Delay: %ds",MajorityDelay);
    
SetMenuColumnHeader(MDelay,0,ystring);
}
#endif