[Tutorial] How to use checkpoints
#1

Introduction:
First of all, this is my first tutorial. If i do anything wrong, or can something be better, tell me. I'm not the best scripter, so please, dont get angry about anything if i do something wrong.
I've noticed that there weren't any tutorials about checkpoints. Thats why i made this one. I had problems with checkpoints in the begin aswell, but some people helped me understand the basic things about checkpoints.

Explenation of the functions
SetPlayerCheckpoint:
This is the function to create a checkpoint. There is just one problem, you can only have 1 checkpoint at the same time. If you want more checkpoints, you need a streamer. I'm not gonna tell anything about multiple checkpoints YET, at the moment im just explaining 1 checkpoint.

pawn Код:
SetPlayerCheckpoint(playerid, Float:x, Float:y, Float:z, Float:size);
Код:
Playerid - This is the ID for who the checkpoint will be
Float:x – The X position
Float:y – The Y position
Float:z – The Z position
Float:size – This will be the size of the checkpoint (normal checkpoint is around the 2-3)
SetPlayerRaceCheckpoint:
This is the function to create a race checkpoint. This is used for races, thats why it’s called “Race Checkpoint”. Also you can only have 1 racecheckpoint at the same time.
pawn Код:
SetPlayerRaceCheckpoint(playerid, type, Float:x, Float:y, Float:z, Float:nextx, Float:nexty, Float:nextz, Float:size)
Код:
Playerid – This is the ID for who the checkpoint will be
Type – You got 4 different types. 0 = normal checkpoint (arrow inside), 1 = finish checkpoint, 2 = checkpoint without an arrow inside, 3 = checkpoint in the air (circle), 4 = finish checkpoin for in the air.
Float:x – The X position
Float:y –  The Y position
Float:z – The Z position
Float:nextx – This is the X position, for the next checkpoint. This is just for the arrow, so it knows which direction it needs to point at.
Float:nexty – This is the Y position, for the next checkpoint. This is just for the arrow, so it knows which direction it needs to point at.
Float:nextz – This is the Z position, for the next checkpoint. This is just for the arrow, so it knows which direction it needs to point at.
Float:size – This willb e the size of the checkpoint. Also, a normal size is around the 2-3.
DisablePlayerCheckpoint:
This will disable a checkpoint, if it is active.
pawn Код:
DisablePlayerCheckpoint(playerid);
DisablePlayerRaceCheckpoint:
This will disable a racecheckpoint i fit is active.
pawn Код:
DisablePlayerRaceCheckpoint(playerid);
Let's get started:
Okay, now we are gonna make a simple trucker mission as an example.
I’m gonna explain it, with a command.
First of all, add this line above your GM/FS
pawn Код:
new Ccp[MAX_PLAYERS];  // This creates a variable, which we will use later
Now we got the variable, we’re gonna make a command which makes a checkpoint.
Note: I’m just using ZCMD, but it can be done with anything, STRCMP, DCMD
Note: Download link of ZCMD is down at the credits
pawn Код:
COMMAND:work(playerid, cmdtext)
{
    Ccp[playerid] = 1; // This will change the variable, so we can use it later on with OnPlayerEnterCheckpoint
    SetPlayerCheckpoint(playerid, -269.1287,2610.6057,63.2069, 3.0); // This creates a checkpoint at the coцrdinates: "-269.1287,2610.6057,63.2069"
    SendClientMessage(playerid, 0xFFFFFFFF, "You started your first mission. Please follow the checkpoints");
    return 1;
}
Okay, now we got a working command, let's move on to the next part. Now we want if you enter the checkpoint, a new checkpoints appear, at a different location. We're using this callback: OnPlayerEnterCheckpoint
pawn Код:
public OnPlayerEnterCheckpoint(playerid)
{
    if(Ccp[playerid] == 1) // This checks if our variable equals to 1, if so: it continues
    {
        DisablePlayerCheckpoint(playerid); // This makes sure that there will be a new checkpoint
        Ccp[playerid] = 2; // Changes the variable, so we can use it later again with OnPlayerEnterCheckpoint
        SetPlayerCheckpoint(playerid, -1051.4005,-655.8729,31.7361, 3.0); // Creates a new checkpoint at a different position
        SendClientMessage(playerid, 0xFFFFFFFF, "You loaded your goods, go to the next checkpoint to continue.");
        return 1;
    }
    return 1;
}
Okay. So far we got: If you type "/work", it will make a checkpoint and gives you a message. When you enter the first checkpoint, it gives you a message, and a new checkpoint will be made.
Now lets make the last checkpoint work. We'll continue in the callback, and just adding the new things under the existing lines.

pawn Код:
public OnPlayerEnterCheckpoint(playerid)
{
    if(Ccp[playerid] == 1) // This checks if our variable equals to 1, if so: it continues
    {
        DisablePlayerCheckpoint(playerid); // This makes sure that there will be a new checkpoint
        Ccp[playerid] = 2; // Changes the variable, so we can use it later again with OnPlayerEnterCheckpoint
        SetPlayerCheckpoint(playerid, -1051.4005,-655.8729,31.7361, 3.0); // Creates a new checkpoint at a different position
        SendClientMessage(playerid, 0xFFFFFFFF, "You loaded your goods, go to the next checkpoint to continue.");
        return 1;
    }
    if(Ccp[playerid] == 2) // This checks if our variable equals to 2, if so: it continues
    {
        new reward, string[128]; // This will create 2 new variables, a reward: so we can print the reward later on. string[128]: This creates a variable, with the size "128", we'll use this one to make a message.
        DisablePlayerCheckpoint(playerid); // This will destroy the checkpoint, so you only get your reward once
        Ccp[playerid] = 0; // This resets the variable, so if you enter a checkpoint right now, nothing will happen
        reward = GivePlayerMoney(playerid, GetPlayerMoney(playerid) + random(5000) + 1000);
        /*
        With this it will change the money.
        What does the random function: This will get a random number, between 0 - 5000. After he gets a random number, he will add 1000 to it, and then add that amount of cash to your current amount
        */

        format(string, sizeof(string), "You entered the last checkpoint. Reward: $%i", reward);
        /*
        If the reward is 3676 (example), this will print: You entered the last checkpoint. Reward: $3676
        What is the %i? The %i stands for "Integer", also known as a number. If the %i was %s, it only would have print letters, because %s = string
        */

        SendClientMessage(playerid, 0xFFFFFFFF, string); // This sends the string to the player
    }
    return 1;
}
So now we got a working Trucker mission!

Multiple places
Now we are going to make different locations. For that, the easiest thing to work with, are dialogs.

ShowPlayerDialog
This function makes a dialog pop up.
pawn Код:
ShowPlayerDialog(playerid, dialogid, style, caption[], info[], button1[], button2[])
Код:
Playerid - This is the ID for who the dialog will be
Dialogid - The id for the dialog. This is so we can give it a response (Max ID = 32767)
Style - There are 3 different styles: DIALOG_STYLE_MSGBOX, DIALOG_STYLE_INPUT, DIALOG_STYLE_LIST. MSGBOX = just a messagebox, INPUT = inputbox, LIST = dialog with listitems
Caption[] - This will be the "title" of the dialog. Max = 64 characters
Info[] - This will be the text (info), with \n you can make a new line (Used to make listitems for LIST)
Button1[] - This will be the text of the first button
Button2[] - This will be the text on the second button
Instead of making a new command, we will use the last command, but remove everything. Then add a new dialog in it.
pawn Код:
COMMAND:work(playerid, cmdtext)
{
    ShowPlayerDialog(playerid, 50, DIALOG_STYLE_LIST, "Choose any of those locations", "From --- to --- /*(listitem 0)*/ \nFrom --- to --- /*(listitem 1)*/ \nFrom --- to ---/*(listitem 2)*/", "Ok", "Cancel");
    /*
    As you can see, im using "\n" to make a new line. In a messagebox it is just a new line, but with DIALOG_STYLE_LIST, it is a new listitem.
    Please NOTE: Anything always start couting from 0, not from 1.
    You can change the dialogid to anything, and an usefull thing to do, is to give the dialog an name.
    Example:
    #define MISSIONDIALOG   50
    ShowPlayerDialog(playerid, MISSIONDIALOG, DIALOG_STYLE_LIST, "Choose any of those locations", "From --- to ---  \nFrom --- to ---  \nFrom --- to ---", "Ok", "Cancel");
    So if you need to change the dialogs, because you're already using the dialogid, you just need to change 1 number, instead of the whole dialogid's
    */

    return 1;
}
Now when you type /work, it will show you a dialog with 3 listitems. You can change those things to anything.
We're gonna use a callback called "OnDialogResponse".

OnDialogResponse
This callback will be used when some-one press one of the buttons in a dialog.
pawn Код:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
Now we're gonna make the response, so if you press the first listitem, it will creates a checkpoint at a specific location, and when you press the second listitem, it creates a checkpoint at a different location.

pawn Код:
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    if(dialogid == 50 || dialogid == MISSIONDIALOG) // This checks if the dialog equals to 50, OR ( || = or , && = and ) MISSIONDIALOG. Just change it to what ever you use. You can use a switch aswell, but i just prefer just to see the whole line
    {
        if(!response) return 0; // If you press the second button (cancel), the dialog dissapears and nothing happens
        if(resposne) // if there is a response (first button( ok )) it continues
        {
            if(listitem == 0) // If you choose the first listitem, this happens
            {
                Ccp[playerid] = 1; // This will change the variable, so we can use it later on with OnPlayerEnterCheckpoint
                SetPlayerCheckpoint(playerid, -269.1287,2610.6057,63.2069, 3.0); // This creates a checkpoint at the coцrdinates: "-269.1287,2610.6057,63.2069"
                SendClientMessage(playerid, 0xFFFFFFFF, "You started your first mission. Please follow the checkpoints");
                return 1;
            }
            if(listitem == 1) // If you choose the second listitem
            {
                Ccp[playerid] = 3; // Why do we make this one 3, and not just 1? That is because 1 is already in use. If you look at your current OnPlayerEnterCheckpoint, you see that there already is a "if(Ccp[playerid] == 1)"
                SetPlayerCheckpoint(playerid, -1051.4005,-655.8729,31.7361, 3.0); // This creates a checkpoint at the coцrdinates: "-1051.4005,-655.8729,31.7361"
                SendClientMessage(playerid, 0xFFFFFFFF, "You started your first mission. Please follow the checkpoints");
                return 1;          
            }
            if(listitem == 2) // If you choose the third listitem
            {
                Ccp[playerid] = 5; // Same for this, 1, 2, 3 and 4 are already in use, so thats why we use 5
                SetPlayerCheckpoint(playerid, -2286.7529,2282.9390,5.9015, 3.0); // This creates a checkpoint at the coцrdinates: "-2286.7529,2282.9390,5.9015"
                SendClientMessage(playerid, 0xFFFFFFFF, "You started your first mission. Please follow the checkpoints");
                return 1;          
            }
        }
    }
    return 1/0 // If you're using this in your GM, then return to 1. If you're using a FS, return to 0 PLEASE NOTE: Take a good look at this, if you're returning to 1 in a FS, it will NOT work
}
Now we got the dialogresponse. Now we need to change the callback, OnPlayerEnterCheckpoint. Otherwise it won't do anything if you enter the checkpoint. We'll be using the existing OnPlayerEnterCheckpoint, and just add the things under it.

pawn Код:
public OnPlayerEnterCheckpoint(playerid)
{
    if(Ccp[playerid] == 1) // This checks if our variable equals to 1, if so: it continues
    {
        DisablePlayerCheckpoint(playerid); // This makes sure that there will be a new checkpoint
        Ccp[playerid] = 2; // Changes the variable, so we can use it later again with OnPlayerEnterCheckpoint
        SetPlayerCheckpoint(playerid, -1051.4005,-655.8729,31.7361, 3.0); // Creates a new checkpoint at a different position
        SendClientMessage(playerid, 0xFFFFFFFF, "You loaded your goods, go to the next checkpoint to continue.");
        return 1;
    }
    if(Ccp[playerid] == 2) // This checks if our variable equals to 2, if so: it continues
    {
        new reward, string[128]; // This will create 2 new variables, a reward: so we can print the reward later on. string[128]: This creates a variable, with the size "128", we'll use this one to make a message.
        DisablePlayerCheckpoint(playerid); // This will destroy the checkpoint, so you only get your reward once
        Ccp[playerid] = 0; // This resets the variable, so if you enter a checkpoint right now, nothing will happen
        reward = GivePlayerMoney(playerid, GetPlayerMoney(playerid) + random(5000) + 1000);
        /*
        With this it will change the money.
        What does the random function: This will get a random number, between 0 - 5000. After he gets a random number, he will add 1000 to it, and then add that amount of cash to your current amount
        */

        format(string, sizeof(string), "You entered the last checkpoint. Reward: $%i", reward);
        /*
        If the reward is 3676 (example), this will print: You entered the last checkpoint. Reward: $3676
        What is the %i? The %i stands for "Integer", also known as a number. If the %i was %s, it only would have print letters, because %s = string
        */

        SendClientMessage(playerid, 0xFFFFFFFF, string); // This sends the string to the player
        return 1;
    }
    if(Ccp[playerid] == 3) // This checks if our variable equals to 3, if so: it continues
    {
        // This is the same as "if(Ccp[playerid] == 1)", didn't understand something from this? Please look back
        DisablePlayerCheckpoint(playerid);
        Ccp[playerid] = 4;
        SetPlayerCheckpoint(playerid, 2791.8650,1231.7740,10.7663, 3.0);
        SendClientMessage(playerid, 0xFFFFFFFF, "You loaded your goods, go to the next checkpoint to continue.");
        return 1;
    }
    if(Ccp[playerid] == 4) // This checks if our variable equals to 4, if so: it continues
    {
        // This is all the same as with "if(Ccp[playerid] == 2)", so if you still didn't understand anything from it, please, look back at the Ccp[playerid] == 2
        new reward, string[128];
        DisablePlayerCheckpoint(playerid);
        Ccp[playerid] = 0;
        reward = GivePlayerMoney(playerid, GetPlayerMoney(playerid) + random(5000) + 1000);
        format(string, sizeof(string), "You entered the last checkpoint. Reward: $%i", reward);
        SendClientMessage(playerid, 0xFFFFFFFF, string);
        return 1;
    }
    if(Ccp[playerid] == 5) // This checks if our variable equals to 5, if so: it continues
    {
        // This is the same as "if(Ccp[playerid] == 1 || Ccp[playeird] == 3)", didn't understand something from this? Please look back
        DisablePlayerCheckpoint(playerid);
        Ccp[playerid] = 6;
        SetPlayerCheckpoint(playerid, -1573.3285,-2730.4099,49.2886, 3.0);
        SendClientMessage(playerid, 0xFFFFFFFF, "You loaded your goods, go to the next checkpoint to continue.");
        return 1;
    }
    if(Ccp[playerid] == 6) // This checks if our variable equals to 6, if so: it continues
    {
        // This is all the same as with "if(Ccp[playerid] == 2 || Ccp[playerid] == 4)", so if you still didn't understand anything from it, please, look back at the Ccp[playerid] == 2 || Ccp[playerid] == 4
        new reward, string[128];
        DisablePlayerCheckpoint(playerid);
        Ccp[playerid] = 0;
        reward = GivePlayerMoney(playerid, GetPlayerMoney(playerid) + random(5000) + 1000);
        format(string, sizeof(string), "You entered the last checkpoint. Reward: $%i", reward);
        SendClientMessage(playerid, 0xFFFFFFFF, string);
        return 1;
    }
    return 1;
}
Congratulations, you now got multiple missions for truckers! If you want to add extra missions, just continue how i did it.

Multiple checkpoints
In this part i'm gonna tell you how you would use multiple checkpoints. If you read the first part of my tutorial, i've said the normal checkpoint limit was 1. But now we want to have multiple checkpoints at a time. Therefore you need a streamer. In this tutorial im gonna use Incognito's streamer. The download link of Incognito’s streamer can be found down the credits.
The functions:
Normal checkpoints:
Код:
CreateDynamicCP(Float:x, Float:y, Float:z, Float:size, worldid = -1, interiorid = -1, playerid = -1, Float:distance = 100.0);

Those are the new things that have been added, i’ll explain those, and the rest you would know if you read the tutorial above

Worldid – This is the VirtualWorld where the checkpoint will be. If this one is -1, then it will be shown in EVERY VirtualWorld
InteriorID – This is the Interior where the checkpoint will be. If this one is -1, then it will be shown in EVERY interior
Playerid – Again, this will be the player for who the checkpoint will be, most likely is to leave this at -1 so it is for everyone.
Float:distance – This will be the distance from where you will see the checkpoint. If it’s 100 (recommed), then you will see the checkpoint if youre 100 meter (not sure if it’s in meters) away from it. 
DestroyDynamicCP(checkpointid);
Race checkpoints:
This one is like the same as CreateDynamicCP, just with nextx, nexty, nextz. If you want to know what they mean, scroll up and read the "CreatePlayerRaceCheckpoint"
Код:
CreateDynamicRaceCP(type, Float:x, Float:y, Float:z, Float:nextx, Float:nexty, Float:nextz, Float:size, worldid = -1, interiorid = -1, playerid = -1, Float:distance = 100.0);
DestroyDynamicRaceCP(checkpointid);
Since it's not usefull to get the id of a checkpoint by counting them (first checkpoint = id 0, second = id 1, etc) we'll use variables. You can name it anything you want. But here imma call the variable Checkpoint.
Multiple Checkpoints on spawn
pawn Код:
new Checkpoint[2];
/*
Put this above your script out of any callback. This will create a variable that you will use to create the checkpoints.
Also, change the number between the [ ] to the amount of checkpoints you have. But don't forget to add 1 extra to it! Otherwise you get this error:
error 032: array index out of bounds (variable "Checkpoint")
*/


public OnPlayerSpawn(playerid)
{  
    Checkpoint[0] = CreateDynamicCP(-2112.7422,-753.4459,32.1719, 4, -1, -1, -1, 100); // Creates a checkpoint at -2112.7422,-753.4459,32.1719 with a range of 4, in any virtualworld, interior and for every player
    Checkpoint[1] = CreateDynamicCP(-2112.9177,-760.9539,32.1719, 4, 5, -1, -1, 100); // Creates a checkpoint at -2112.9177,-760.9539,32.1719 with a range of 4, in virtualworld 5, any interior, and for every player
    return 1;
}
Now we got the checkpoints, but if you enter them nothing happens yet. Thats why we need to use the callback "OnPlayerEnterDynamicCP". If you using racecheckpoints, the callback is "OnPlayerEnterDynamicRaceCP".
Код:
public OnPlayerEnterDynamicCP(playerid, checkpointid)
public OnPlayerEnterDynamicRaceCP(playerid, checkpointid)
playerid - This is the action what the player gets when he enters the CP
checkpointid - This is the checkpoint id, this will be the variable we used above
pawn Код:
public OnPlayerEnterDynamicCP(playeird, checkpointid)
{
    if(checkpointid == Checkpoint[0]) // Checks if the checkpointid equals to Checkpoint[0]
    {  
        SendClientMessage(playerid, 0xFFFFFFFF, "This is \"Checkpoint[0]\"");
        /*
        NOTE: The " \ " is needed before the ", otherwise it will give you an error!
        You wont see the " \ " though, so dont worry about that
        */

        GivePlayerMoney(playerid, + 100);
    }
    if(checkpointid == Checkpoint[1]) // Checks if the checkpointid equals to Checkpoint[1]
    {
        SendClientMessage(playerid, 0xFFFFFFFF, "This is \"Checkpoint[1]\"");
        GivePlayerMoney(playerid, + 200);
    }
    return 1;
}
Now if you enter Checkpoint[0], it will give you a message " This is "Checkpoint[0]" " and give you $100. If you enter Checkpoint[1], it will give you a message " This is "Checkpoint[1]" ", and give you $200.

Well, this was my tutorial! I hope you guys liked it, and most important, learned something from it. Please rate and comment. If there are any suggestions, please post them aswell so i can add them later
If there is anything that's not clear, anything that can be done better, tell me and i'll take a look at it

~Wesley

Credits:
Wesley221 - Making this tutorial
Zeex - Making ZCMD
Incognito - Making the streamer plugin

Download links:
ZCMD
Incognito Streamer
Reply
#2

The tutorial looks good, and you have explained a lot
(I was the first to post)
Reply
#3

Well done!
Reply
#4

Well done mate. You just helped people thanks very much.
Reply
#5

Quote:
Originally Posted by Max_Coldheart
Посмотреть сообщение
The tutorial looks good, and you have explained a lot
(I was the first to post)
Quote:
Originally Posted by Markx
Посмотреть сообщение
Well done!
Quote:
Originally Posted by Davz*|*Criss
Посмотреть сообщение
Well done mate. You just helped people thanks very much.
Thanks, thanks and thanks

Just updated the post, added multiple trucker missions!
Reply
#6

Nice guide, good for newbies (like me). I already know this, but it is good for new people trying to script.
Reply
#7

wow,nice You have so much explanation
Reply
#8

Quote:
Originally Posted by DaRealz
Посмотреть сообщение
Nice guide, good for newbies (like me). I already know this, but it is good for new people trying to script.
Quote:
Originally Posted by Skaizo
Посмотреть сообщение
wow,nice You have so much explanation
Thanks and thanks

Any suggestions?
Reply
#9

Quote:
Originally Posted by Wesley221
Посмотреть сообщение
Thanks and thanks

Any suggestions?
Make more tutorials, thats my suggestion! You are awesome in tutorial making, everything is awesome explained!
Reply
#10

Quote:
Originally Posted by Markx
Посмотреть сообщение
Make more tutorials, thats my suggestion! You are awesome in tutorial making, everything is awesome explained!
Tutorial about what? Currencly almost done with this one, but no idea about what my next will be
Reply
#11

Quote:
Originally Posted by Wesley221
View Post
Tutorial about what? Currencly almost done with this one, but no idea about what my next will be
Maybe a register system with y_ini, didnt see one around Saving score money etc... would help me understand it better.
Reply
#12

respect^^

very nice tutorial, now make a tutorial for race but to see checkpoint players in range of I don't now maybe 10 meters?
Reply
#13

Quote:
Originally Posted by Markx
View Post
Maybe a register system with y_ini, didnt see one around Saving score money etc... would help me understand it better.
Might try y_ini soon, never used before so imma try fool around a bit with it

Quote:
Originally Posted by System64
View Post
respect^^

very nice tutorial, now make a tutorial for race but to see checkpoint players in range of I don't now maybe 10 meters?
So you mean just a tutorial how to make a single race, and it can only be seen by players that participating?
Reply
#14

Nice, make a racing CP tut
Reply
#15

yes just player who participate
Reply
#16

Alrighty, imma make that after i finished streamed checkpoints! Gnight
Reply
#17

Updated tutorial, added Streamed Checkpoints
Reply
#18

How would it be done if I wanted a little waiting time before going to the next checkpoint? Like freezing the player and sending a message "Loading goods, please wait.."
Reply
#19

I'm gonna use this for my cop missions.
Reply
#20

Quote:
Originally Posted by NiZ
View Post
How would it be done if I wanted a little waiting time before going to the next checkpoint? Like freezing the player and sending a message "Loading goods, please wait.."
When the player enters a checkpoint, freeze him. Then set a timer, that will unfreeze him after ~5 seconds.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)