[Tutorial] Position saver and loader [With pictures & video]
#1

What will I learn in this tutorial?
You will be shown how to make a system that is able to save and load multiple player positions.

I am going to assume you are a complete newbie at pawn and will try to explain as much as possible.

Let's start by creating a new script in the pawno editor. Click on the new icon.


Once you have created a new script you should see a pre-made template for scripts. This might confuse you, but don't worry, you won't have to understand all of this.
Now it's time to start working on the system (Yay!)

Go ahead and create three 'float' variables called position1x, position1y and position1z.



What does this mean? The new in these lines means that we are creating new variables to store information in.
The 'Float:' means that we the type of variable we are creating is a 'float'. A float is a number with fractional parts, so basically a decimal (e.g. 1.00, 3.21)
We need to have these variables as floats because we are going to store coordinates in them, and coordinates are floats.
I called them position1x, position1y and position1z because it's easy to memorize.
The [MAX_PLAYERS] basically means that every player on the server will have their own variable. This is so that multiple players can use the script

Now you might have noticed that these variables alone already take up 3 lines of code(!)
We can change this by defining all the variables in one line, this looks much cleaner!


(Don't forget the ; at the end of the line or you may get errors!)

Okay so now that we have three x, y and z variables, this means we can store 1 position of the player.
But let's make our script more advanced and cool by adding the ability to save more positions.
We can do this by defining these same Floats but with different names.
Take a look at this picture if you are having trouble understanding



As you can see we now have a total of 9 variables! This means we can store 3 positions of the player because a coordinate consists of an x, y and z coordinate

We also need to define DIALOG_SAVE, this is not important right now but will be needed later on in our script!



Now that we have these variables done, we can go ahead and create the command that the player will execute to save a position.
Scroll down in your script until you find the OnPlayerCommandText callback, it looks like this:



Now we will start by changing the command the player needs to use. For this tutorial I will pick the command /savepos



Now you might ask, what does this all mean?
Well the public OnPlayerCommandText(playerid, cmdtext[]) basically means that when a player enters any command, this callback will run any code in it.
Now to make sure this only happens when the player types our command, we have to compare the command the player typed to our command, which is /savepos
We do this by using a function called strcmp, this stands for 'string compare' and once the command that the player typed and /savepos match, the code will be ran.



Now, in the strcmp function there is also a number, you need to change this number to the the length of your command. In this case /savepos is 8 characters long.



Go ahead and remove the // Do something here
Now that the command is ready to be executed, we have to start working on the code that will handle our saving of positions.
Because we have the option to save upto 3 positions, we have to show the player a dialog to choose in which position slot he wants to save his current position.
We can show the player a dialog by using the ShowPlayerDialog function.



The 'playerid' in the function indicates that we are showing the dialog to the player that just typed that command.
The DIALOG_SAVE is the ID we will use for the dialog, this is to prevent dialogs from interfering with each other. (Remember when we defined the DIALOG_SAVE? )
It also says DIALOG_STYLE_LIST, this means we are creating a dialog with a 'list' to choose from. Here is an example of a list dialog:


Credits to wiki.sa-mp.com

As you can see it also says "Position saver" this is the title of your dialog, it can be anything you want it to be. Change it if you want to
Then we have:
"Save to position 1\nSave to position 2\nSave to position 3"
These are the options the player will see in the list dialog. The \n here means that we are going down a line, thus creating a new list item.
In total our dialog will have 3 list items, that looks like this:
Save to position 1
Save to position 2
Save to position 3


Then we have "Save!" and "Cancel", these are the two buttons on our list dialog.
The first one (Save!) is the one on the left and the second one (Cancel) is the one on the right.
Of course you have the option to change the text on the buttons

Cool! The dialog will now be shown to the player, but wait! We still need to save the positions :O
Let's go ahead and find the OnDialogResponse callback in the script, it looks like this:



This is the callback that runs when a player interacts with any dialog.
To make sure we are working with our dialog (DIALOG_SAVE) we will make an if statement to check if the dialogid is DIALOG_SAVE.



In this if statement we will make another if statement to check if the player clicked "Save!" (first button)
In the callback 'response' means the first button and '!response' is the second button. So in this case we will check for 'response'.


(Make sure you get your tabs and spaces right to not get confused with your own code!)

Now that we have made sure it's our dialog, we can check which option the player chose.
This is done by checking the so called 'listitem'
I will create an if statement to check if the listitem is 0, 1 or 2
0 = Save to position 1
1 = Save to position 1
2 = Save to position 1

(In programming/scripting counting often starts at 0 so don't get confused with that!)


(I am also using comments, this is so that I can read my own code easier. Comments are made with //)

Now I will create three temporary variables and use the GetPlayerPos function to get the player's current position!

Код:
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
The position of the player is now saved in the floats x, y and z.
The next step is to save the position into the correct position slot.

In each if statement you can copy and paste the same code, just edit the names of the variables accordingly.

Image: http://i.imgur.com/X37wRqQ.png
(Image limit reached so I will have to post links now)

This code basically sets the position variables to the player's current coordinates.
We are also using [playerid] after the variables to indicate that we are doing it for this player only!

Now we can also send the player a message in the chat to let him know the position was saved.
This is done with the SendClientMessage function.

PHP код:
SendClientMessage(playerid, -1"Your position was saved to slot 1"); 
The playerid here means sending a message to that specific player only.
-1 is the color, in this case I used -1, this is white. After this comes the string you want to send to the player.
Make sure to change the message for every slot.

Image: http://i.imgur.com/LFx9hGe.png

We've come a long way! The position saving is completely done but now we need to load the positions.
We will go up to the OnPlayerCommandText callback again and add 3 more commands.
/pos1 /pos2 and /pos3.

Make sure to use your else if statements and to change the number to the command length!

Image: http://i.imgur.com/ALGeTfX.png

In these commands we will teleport the player to the position.
This is very easily achieved by using the SetPlayerPos function.

PHP код:
SetPlayerPos(playeridposition1x[playerid], position1y[playerid], position1z[playerid]); 
We use playerid again and for the x, y and z variables we will use the player specific variables we made.

Together with this we will send the player another message saying that he was teleported to the position.

PHP код:
SendClientMessage(playerid, -1"You were teleported to position 1"); 
Do the same for every else if statement but change the variables and text.

Image: http://i.imgur.com/ryZ4OTG.png

Dude! You are done. Now compile your script using F5, it should compile without errors. Do you have errors? Post them in a reply and I will help you resolve them.

You can download the script via the attachment or view it on the pastebin link.

Video of finished script:
[ame]http://www.youtube.com/watch?v=IctxkzpbWeI[/ame]
Reply
#2

Well done, but still you could've done it with ZCMD.
Reply
#3

The tutorial is neatly structured and very well written but quite outdated and very hard to maintain.

Use a three dimensional array instead.

pawn Код:
enum { x, y, z } // just for convenience
new Float:position[MAX_PLAYERS][3][3];
pawn Код:
GetPlayerPos(playerid, position[playerid][0][x], position[playerid][0][y], position[playerid][0][y]);
You could then also create your list ("Save to position x") with a loop and use the corresponding response directly. This means that if you were to add more positions you would only have to change one (1) single number instead of altering code in three or four different places.
Reply
#4

Quote:
Originally Posted by biker122
Посмотреть сообщение
Well done, but still you could've done it with ZCMD.
Indeed but I've kind of aimed this towards new scripters and didn't want to get into includes and stuff.

Quote:
Originally Posted by Vince
Посмотреть сообщение
The tutorial is neatly structured and very well written but quite outdated and very hard to maintain.

Use a three dimensional array instead.

pawn Код:
enum { x, y, z } // just for convenience
new Float:position[MAX_PLAYERS][3][3];
pawn Код:
GetPlayerPos(playerid, position[playerid][0][x], position[playerid][0][y], position[playerid][0][y]);
You could then also create your list ("Save to position x") with a loop and use the corresponding response directly. This means that if you were to add more positions you would only have to change one (1) single number instead of altering code in three or four different places.
You're right I could have done this in a much more convenient way by the method you showed and also other things but I chose not to since that propably be too much to explain to a newbie.
Also another flaw in the script is that you could use the /pos[1-3] command without even having saved a position there and you would (propably) be teleported to 0, 0, 0.
These problems could all be fixed easily but would overwhelm a junior scripter.

Thanks for your feedback, both!
Reply
#5

Quote:
Originally Posted by Sellize
Посмотреть сообщение
to a newbie.
Sigh. Why should a newbie have to learn a worse method if you can teach them the better method instead? I'm really getting quite tired of all this "this is for newbies" shit. Apparently that justifies writing poor code.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)