[Tutorial] Save, load and set player position - using y_ini
#1

Introduction
  • I've seen numerous people having trouble with saving, loading and setting player position. This tutorial will teach you how you can save the player position in an ini file, load it and set it when he spawns ( return to the last position you were when you disconnected ).
What do you need
  • y_ini - The fastest and most efficient way to write/read from a file by ******
Download
  • Download YSI Server Includes.
  • Copy/Cut the "YSI" folder into your "..pawno\include" directory.
Starting

Let's include y_ini at the top of our script.

pawn Код:
#include <YSI\y_ini>
The #include directive inserts the contents of the specified file at the current position within the current file. More directives can be found here. In our case it will load all the codes from "..pawno\include\YSI\y_ini.inc" into the script and that's what we need so we can load y_ini features.

Let's declare some variables somewhere at the top of our script:

pawn Код:
new
    Float: PosX[ MAX_PLAYERS ],
    Float: PosY[ MAX_PLAYERS ],
    Float: PosZ[ MAX_PLAYERS ],
    Float: Angle[ MAX_PLAYERS ],
    Interior[ MAX_PLAYERS ],
    VirtualWorld[ MAX_PLAYERS ]
;
The "new" keyword declares a new variable. We used the predefined tag name called "Float" which will enable the floating point support for our variables. We declared 6 arrays. An array is a variable in which you can store multiple pieces of data at once and access them dynamically. Each variable holds a number of cells ( MAX_PLAYERS ). The first one will hold the X coordinates of the player position, the second one will hold the Y coordinates of the player position, the third one will hold the Z coordinates of the player position, the fourth one will hold the Angle coordinates of the player, the fifth one will hold the interior ID of the player and the last one will hold the virtual world ID of the player. Let's create a simple stock function that will return the directory where the player file ( which will contain the position coordinates ) will be saved.

pawn Код:
stock user_ini_file(playerid)
{
    new
        string[ 128 ],
        user_name[ MAX_PLAYER_NAME ]
    ;

    GetPlayerName( playerid, user_name, MAX_PLAYER_NAME );
    format( string, sizeof ( string ), "%s.ini", user_name );
    /* scriptfiles directory */
    return
        string;
}
A stock function is a function that the PAWN parser must plug into the program when it is used and that it may simply "remove" from the program (without warning) when it is not used. To declare a stock function, prefix the function name with the keyword stock. Public functions and native functions cannot be declared 'stock'.

We declare an array called string 128 cells big and another one called user_name MAX_PLAYER_NAME cells big (which means 24(maximum player name lenght in SA:MP )). We get the playerid name using GetPlayerName function and store the player name in the variable called user_name, we format the path and store it in the variable string, at the end we return the string. Since the path is mentioned as "%s.ini", the user file will be saved in your "..scriptfiles" directory.

Let's create a simple public function to load the user data from the file:

pawn Код:
forward @load_user_position( playerid, name[], value[] );

@load_user_position( playerid, name[], value[] )
{
    INI_Float( "PositionX", PosX[ playerid ] );
    INI_Float( "PositionY", PosY[ playerid ] );
    INI_Float( "PositionZ", PosZ[ playerid ] );
    INI_Float( "Angle", Angle[ playerid ] );
    INI_Int( "Interior", Interior[ playerid ] );
    INI_Int( "VirtualWorld", VirtualWorld[ playerid ] );
    return ( 1 );
}
Public functions can be prefixed by either public or @, the @ character, when used, becomes part of the function name. INI_Float saves the passed value as a float if the name matches, INI_Int - the data is passed to the loading callback as a string, this will convert it to an integer. We will save the player position, interior and virtual world when he disconnects so let's scroll down to OnPlayerDisconnect callback.

pawn Код:
public OnPlayerDisconnect( playerid, reason )
{
    GetPlayerPos( playerid, PosX[ playerid ], PosY[ playerid ], PosZ[ playerid ] );
    GetPlayerFacingAngle( playerid, Angle[ playerid ] );
   
    new INI:File = INI_Open( user_ini_file( playerid ) );
    INI_SetTag( File, "position" );
    INI_WriteFloat( File, "PositionX", PosX[ playerid ] );
    INI_WriteFloat( File, "PositionY", PosY[ playerid ] );
    INI_WriteFloat( File, "PositionZ", PosZ[ playerid ] );
    INI_WriteFloat( File, "Angle", Angle[ playerid ] );
    INI_WriteInt( File, "Interior", GetPlayerInterior( playerid ) );
    INI_WriteInt( File, "VirtualWorld", GetPlayerVirtualWorld( playerid ) );
    INI_Close( File );
    return ( 1 );
}
OnPlayerDisconnect callback is called when a player disconnects from the server, playerid is the id of the player who left and reason id of the reason why they left.

We use GetPlayerPos function to get the current player position and save it in the variables "PosX, PosY and PosZ". We use GetPlayerFacingAngle function to get the angle of the direction the player is facing and store it in the variable "Angle". We open/create the user file using INI_Open and our stock as the parameter. We write to the user "PositionX" section the value stored in the variable PosX, we write to the user "PositionY" section the value stored in the variable PosY, to the "PositionZ" section the value stored in the variable "PosZ" and to the "Angle" section the value stored in the Angle variable, to the "Interior" section the value returned by the GetPlayerInterior function, to the "VirtualWorld" section the value returned by GetPlayerVirtualWorld function. After the values has been written we close the user file using INI_Close, we return a true value. We need to load the user position from the file when he connects so let's scroll to OnPlayerConnect callback.

pawn Код:
public OnPlayerConnect( playerid )
{
    PosX[ playerid ] = 0;
    PosY[ playerid ] = 0;
    PosZ[ playerid ] = 0;
    Angle[ playerid ] = 0;
    Interior[ playerid ] = 0;
    VirtualWorld[ playerid ] = 0;
   
    INI_ParseFile( user_ini_file( playerid ), "load_user_%s", .bExtra = true, .extra = playerid );
    return ( 1 );
}
OnPlayerConnect callback is called when a player connects to the server, playerid is the ID of the player that connected. We reset the player variables first, e use INI_ParseFile to parse his ini file (load his data), when he spawns we need to set his position, interior and virtual world so let's scroll down to OnPlayerSpawn callback.

pawn Код:
public OnPlayerSpawn( playerid )
{
    if ( PosX[ playerid ] != 0 && PosY[ playerid ] != 0 && PosZ[ playerid ] != 0 && Angle[ playerid ] != 0 )
    {
        SetPlayerPos( playerid, PosX[ playerid ], PosY[ playerid ], PosZ[ playerid ] );
        SetPlayerFacingAngle( playerid, Angle[ playerid ] );
        SetPlayerInterior( playerid, Interior[ playerid ] );
        SetPlayerVirtualWorld( playerid, VirtualWorld[ playerid ] );
        SendClientMessage( playerid, -1, "welcome to your last position" );
    }
    return ( 1 );
}
OnPlayerSpawn callback is called when a player spawns, playerid is the ID of the player that spawned.

When a player first connects to the server, his PosX, PosY, PosZ and Angle variables will be 0. The operator "!=" means "left is NOT equal to right". We check if our variables are NOT equal to 0, if so we set the player position using SetPlayerPos function, we set his angle using SetPlayerFacingAngle function, we set his interior using SetPlayerInterior function, we set his virtual world using SetPlayerVirtualWorld function and we send him a simple message using SendClientMessage function.

That's all, your script should look something like this:

pawn Код:
#include <a_samp>
#include <YSI\y_ini>

new
    Float: PosX[ MAX_PLAYERS ],
    Float: PosY[ MAX_PLAYERS ],
    Float: PosZ[ MAX_PLAYERS ],
    Float: Angle[ MAX_PLAYERS ],
    Interior[ MAX_PLAYERS ],
    VirtualWorld[ MAX_PLAYERS ]
;

stock user_ini_file(playerid)
{
    new
        string[ 128 ],
        user_name[ MAX_PLAYER_NAME ]
    ;

    GetPlayerName( playerid, user_name, MAX_PLAYER_NAME );
    format( string, sizeof ( string ), "%s.ini", user_name );
    /* scriptfiles directory */
    return
        string;
}

forward @load_user_position( playerid, name[], value[] );

@load_user_position( playerid, name[], value[] )
{
    INI_Float( "PositionX", PosX[ playerid ] );
    INI_Float( "PositionY", PosY[ playerid ] );
    INI_Float( "PositionZ", PosZ[ playerid ] );
    INI_Float( "Angle", Angle[ playerid ] );
    INI_Int( "Interior", Interior[ playerid ] );
    INI_Int( "VirtualWorld", VirtualWorld[ playerid ] );
    return ( 1 );
}

public OnPlayerDisconnect( playerid, reason )
{
    GetPlayerPos( playerid, PosX[ playerid ], PosY[ playerid ], PosZ[ playerid ] );
    GetPlayerFacingAngle( playerid, Angle[ playerid ] );
   
    new INI:File = INI_Open( user_ini_file( playerid ) );
    INI_SetTag( File, "position" );
    INI_WriteFloat( File, "PositionX", PosX[ playerid ] );
    INI_WriteFloat( File, "PositionY", PosY[ playerid ] );
    INI_WriteFloat( File, "PositionZ", PosZ[ playerid ] );
    INI_WriteFloat( File, "Angle", Angle[ playerid ] );
    INI_WriteInt( File, "Interior", GetPlayerInterior( playerid ) );
    INI_WriteInt( File, "VirtualWorld", GetPlayerVirtualWorld( playerid ) );
    INI_Close( File );
    return ( 1 );
}

public OnPlayerConnect( playerid )
{
    PosX[ playerid ] = 0;
    PosY[ playerid ] = 0;
    PosZ[ playerid ] = 0;
    Angle[ playerid ] = 0;
    Interior[ playerid ] = 0;
    VirtualWorld[ playerid ] = 0;
   
    INI_ParseFile( user_ini_file( playerid ), "load_user_%s", .bExtra = true, .extra = playerid );
    return ( 1 );
}


public OnPlayerSpawn( playerid )
{
    if ( PosX[ playerid ] != 0 && PosY[ playerid ] != 0 && PosZ[ playerid ] != 0 )
    {
        SetPlayerPos( playerid, PosX[ playerid ], PosY[ playerid ], PosZ[ playerid ] );
        SetPlayerFacingAngle( playerid, Angle[ playerid ] );
        SetPlayerInterior( playerid, Interior[ playerid ] );
        SetPlayerVirtualWorld( playerid, VirtualWorld[ playerid ] );
        SendClientMessage( playerid, -1, "welcome to your last position" );
    }
    return ( 1 );
}
The user ini file will look something like this:

Код:
[position]
PositionX = 171.252197
PositionY = -72.037948
PositionZ = 2.210306
Angle = 150.401428
Interior = 3
VirtualWorld = 0
Special thanks to
Reply


Messages In This Thread
Save, load and set player position - using y_ini - by SmiT - 27.11.2011, 12:18
Re: Save, load and set player position - using y_ini - by SantarioLeone - 27.11.2011, 18:10
Re: Save, load and set player position - using y_ini - by wups - 27.11.2011, 19:13
Re: Save, load and set player position - using y_ini - by RepzThat - 27.11.2011, 20:05
Re: Save, load and set player position - using y_ini - by SmiT - 28.11.2011, 12:52
Re: Save, load and set player position - using y_ini - by SantarioLeone - 29.11.2011, 17:20
Re: Save, load and set player position - using y_ini - by dmng825 - 31.12.2011, 16:08
Re: Save, load and set player position - using y_ini - by Zom3ie - 31.12.2011, 20:41
Re: Save, load and set player position - using y_ini - by dmng825 - 02.01.2012, 12:16
Re: Save, load and set player position - using y_ini - by maxmax1 - 17.02.2012, 15:22
Re: Save, load and set player position - using y_ini - by Joe Vagos - 15.07.2012, 16:54
Re: Save, load and set player position - using y_ini - by Michael_Cuellar - 02.08.2012, 19:13
Re: Save, load and set player position - using y_ini - by rokasma - 07.11.2012, 14:15
Re: Save, load and set player position - using y_ini - by x96664 - 14.11.2012, 19:04
Re: Save, load and set player position - using y_ini - by Jesseding - 14.11.2012, 20:59
Re: Save, load and set player position - using y_ini - by jstowe96 - 24.11.2012, 01:16
Re: Save, load and set player position - using y_ini - by Crypt - 24.11.2012, 06:04
Re: Save, load and set player position - using y_ini - by jstowe96 - 24.11.2012, 11:38
Re: Save, load and set player position - using y_ini - by Blademaster680 - 15.07.2013, 21:45
Re : Save, load and set player position - using y_ini - by mirou123 - 23.08.2013, 19:29
Re: Save, load and set player position - using y_ini - by Ramms - 07.02.2014, 16:42
Re: Save, load and set player position - using y_ini - by xPirate - 05.04.2014, 12:13
Re: Save, load and set player position - using y_ini - by biker122 - 05.04.2014, 13:18
Re: Save, load and set player position - using y_ini - by xPirate - 05.04.2014, 14:26
Re: Save, load and set player position - using y_ini - by GrandTA - 20.06.2017, 15:39
Re: Save, load and set player position - using y_ini - by 2xRichard - 16.07.2017, 15:46
Re: Save, load and set player position - using y_ini - by beastmaster - 19.07.2018, 07:57
Re: Save, load and set player position - using y_ini - by CodeStyle175 - 19.07.2018, 08:51
Re: Save, load and set player position - using y_ini - by WilliamVN - 21.07.2018, 04:02
Re: Save, load and set player position - using y_ini - by DerickClark - 21.07.2018, 04:19
Re: Save, load and set player position - using y_ini - by beastmaster - 25.07.2018, 08:59
Re: Save, load and set player position - using y_ini - by DerickClark - 26.07.2018, 06:56
Re: Save, load and set player position - using y_ini - by beastmaster - 26.07.2018, 11:38

Forum Jump:


Users browsing this thread: 1 Guest(s)