їComo guardar armas(y otros datos)?
En primer lugar tenemos que tener Y-INI de *****
https://sampforum.blast.hk/showthread.php?tid=175565
Y_INI es un sitema rapido para guardar y cargar datos en forma .txt .ini y demas, estos datos se van a guardar por defecto en scriptfiles pero siempre tenemos que nombrarlos.
їDonde guarda los datos?
En este ejemplo vamos a utilizar guardar armas para el personaje asique definiremos al principio de nuestro script donde queremos guardarlo.
pawn Код:
#define PATH "/Users/%s.ini"
Podemos ver facilmente el primer valor que es define, es decir, definir algo como algo, o x como y(creo que se entiende)
Tambien podemos ver PATH, no te preocupes, puede ser cualquier nombre, es lo definido. Me explico,no queremos tener que estar escribiendo "/Users/%s.ini" asique ponemos PATH y listo.
Luego aсadimos esto
"/Users/ їQue significa?, es la carpeta donde se van a crear los datos guardados (de forma simpleficada ya que samp da por echo que la carpeta va a ser scriptfiles, Ejemplo: C:/Servidor/Scriptfiles
/Users/%s.ini)
Por ultimo tenemos %s.ini, donde %s es el formato(en este caso string, una cadena de caracteres) y .ini que va a ser la extension. (aunque puede ser otra como .txt)
+En caso de querer guardar la informacion en la carpeta scriptfiles їQue hariamos?
-Simplemente eliminar la direccion de la carpeta, en este caso /Users/
+En caso de querer guardar la informacion en una carpeta dentro de una carpeta їQue hariamos?
-Simplemente aсadir las carpetas /Users/lol/marrana/%s.ini (esto lo doy por echo ya que nunca he creado subcarpetas)
Ahora que ya tenemos donde se va a guardar їque tal empezar a hacer algo?
Variables de los datos
Aqui vamos a guardar los datos del .ini en variables
Estas varibles basicamente, una forma de almacenar los datos para su lectura
Los datos que queremos guardar por supuesto que queremos tenerlos de forma ordenada para acordarnos rapidamente de ellos sin tener que subir y bajar de pagina constantemente asique vamos a enumerar
pawn Код:
enum pInfo
{
pArma0,
pArma1,
pArma2,
pArma3,
pArma4,
pArma5,
pArma6,
pArma7,
pArma8,
pArma9,
pArma10,
pArma11,
pArma12,
pBalas0,
pBalas1,
pBalas2,
pBalas3,
pBalas4,
pBalas5,
pBalas6,
pBalas7,
pBalas8,
pBalas9,
pBalas10,
pBalas11,
pBalas12
}
new PlayerInfo[MAX_PLAYERS][pInfo];
Aqui notamos una coincidencia una en enum pInfo y otra en new PlayerInfo[MAX_PLAYERS][pInfo];
Que quiere decir que cualquier valor del enum va a estar en esa posicion
Ejemplo:
pawn Код:
PlayerInfo[MAX_PLAYERS][pArma0];
PlayerInfo[MAX_PLAYERS][pArma1];
PlayerInfo[MAX_PLAYERS][pArma2];
(Porcierto slot de armas hay del 0 al 12, siendo el 0 el puсo y 12 el detonador, aunque no son necesariamente para guardar, las mantengo para tener una vision mas ordenada y reconocer el slot de armas
https://sampwiki.blast.hk/wiki/Weapons)
Tambien podemos ver en la varible creada PlayerInfo, que es el nombre y los dos corchetes[][] son el tamaсo del array en este caso es de dos dimensiones, dato uno[MAXPLAYERS] va a ser el tamaсo(podemos poner numeros como 1,2 ,3, 666, 69, pero MAX_PLAYERS es el numero de jugadores que admite nuestro server, si permitimos 50 solo va a crear 50 y no slots inecesarios, ya que este dato se puede modificar facilmente sin comprometer el codigo, vamos a usarlo)
(Si te has perdido aqui te recomiendo que mires esto
https://sampforum.blast.hk/showthread.php?tid=225796)
Ahora llegados a este punto tenemos un monton de varaibles de acceso rapido para cargar los datos
Dar nombre al archivo .ini
Evidente tenemos que darle un nombre al archivo .ini para leerlo mas tarde y guardar datos mas tarde
En este caso vamos a guardar los datos con el nombre del personaje para no complicarnos vamos a crear una funcion en un stock y asi no la repetimos una y otra vez.
pawn Код:
stock UserPath(playerid)
{
new string[128],playername[MAX_PLAYER_NAME];
GetPlayerName(playerid,playername,sizeof(playername));
format(string,sizeof(string),PATH,playername);//es el PATH podriamos poner ahi "/Users/%s.ini" pero asi es mas facil y a la vista
return string;
}
Esta funcion lo que va a hacer es tomar la id del personaje y transformarla en el nombre del personaje y guardar el .ini con el nombre del personaje.
(Lo usaremos mas adelante)
Cargar, guardar datos
pawn Код:
public OnPlayerConnect(playerid)
{
if(fexist(UserPath(playerid)))
{
//hace algo
}
if(!fexist(UserPath(playerid)))
{
//hace algo
}
return 1;
}
Como ves al conectarse el personaje lo primero que hemos mirado es si tiene cuenta o si no tiene
- if(fexist(UserPath(playerid))) = si el archivo (nombre del personaje en la carpeta Users)existe
- if(!fexist(UserPath(playerid))) = si el archivo (nombre del personaje en la carpeta Users)no existe
Como te he dicho antes no es necesario crear el stock UserPath podiamos haber echo esto:
pawn Код:
public OnPlayerConnect(playerid)
{
new nombre[128],string[128];
GetPlayerName(playerid, nombre, sizeof(nombre));
format(string, sizeof(string), PATH, nombre)
if(fexist(string)
{
//hace algo
}
if(!fexist(string)
{
//hace algo
}
return 1;
}
O podemos no utilizar ni el #define PATH... ni el stock
pawn Код:
public OnPlayerConnect(playerid)
{
new nombre[128],string[128];
GetPlayerName(playerid, nombre, sizeof(nombre));
format(string, sizeof(string), "/Users/%s", nombre)
if(fexist(string)
{
//hace algo
}
if(!fexist(string)
{
//hace algo
}
return 1;
}
Puedes combrobar que es mucho mas facil lo primero
Guardar
Como el personaje no tiene cuenta, no puede tener armas(en caso de un rp normal) asique todas sus armas y balas van a ser 0
pawn Код:
public OnPlayerConnect(playerid)
{
if(fexist(UserPath(playerid)))
{
//hace algo
}
if(!fexist(UserPath(playerid)))
{
new INI:File = INI_Open(UserPath(playerid));
INI_WriteInt(File,"Arma0",0);
INI_WriteInt(File,"Arma1",0);
INI_WriteInt(File,"Arma2",0);
INI_WriteInt(File,"Arma3",0);
INI_WriteInt(File,"Arma4",0);
INI_WriteInt(File,"Arma5",0);
INI_WriteInt(File,"Arma6",0);
INI_WriteInt(File,"Arma7",0);
INI_WriteInt(File,"Arma8",0);
INI_WriteInt(File,"Arma9",0);
INI_WriteInt(File,"Arma10",0);
INI_WriteInt(File,"Arma11",0);
INI_WriteInt(File,"Balas0",0);
INI_WriteInt(File,"Balas1",0);
INI_WriteInt(File,"Balas2",0);
INI_WriteInt(File,"Balas3",0);
INI_WriteInt(File,"Balas4",0);
INI_WriteInt(File,"Balas5",0);
INI_WriteInt(File,"Balas6",0);
INI_WriteInt(File,"Balas7",0);
INI_WriteInt(File,"Balas8",0);
INI_WriteInt(File,"Balas9",0);
INI_WriteInt(File,"Balas10",0);
INI_WriteInt(File,"Balas11",0);
INI_Close(File);
}
return 1;
}
Vamos a despiezar esto:
pawn Код:
new INI:File = INI_Open(UserPath(playerid));//abrimos el archivo con nuestro nombre, como no exite lo va a crear
[PAWN]INI_WriteInt(File,"Arma0",0);[/PAWN
La primera parte dice escribir integer (un numero simple), dentro del parentesis le decimos donde, en este caso File que es igual a UserPath(playerid), es decir nuestro nombre en la carpeta Users, segundo dato del parentesis el nombre en el archivo .ini y el dato que contendra.
Si ponemos
pawn Код:
INI_WriteInt(File,"guarrilla",1);
en el .ini con nuestro nombre pondrб guarrilla = 1 (evidente)
Al final de escribir datos en Y_INI tenemos que cerrar el archivo
Ahora ya tenemos datos guardados
Pensaras, menuda gracia... guarda solo los datos caundo no hay cuenta y pone todo a 0, tranquilo, tranquilo, ahora sabes guardar 0, їque te impide guardar cualquier cosa? Luego te pondre un ejemplo tranquilo
Cargar
Cargar es mas facil de lo que aprece pero tenemos que hacerlo de dos partes, para mi la forma mas comoda con la funcion ini parse file (no te preocupes lo miraremos ahora)
pawn Код:
public OnPlayerConnect(playerid)
{
if(fexist(UserPath(playerid)))
{
INI_ParseFile(UserPath(playerid), "LoadUser_%s", .bExtra = true, .extra = playerid);
}
if(!fexist(UserPath(playerid)))
{
//hace algo
}
return 1;
}
Te habras perdido un poco pero tranquilo ahora hacemos otra cosa y lo explicamos
pawn Код:
forward LoadUser_data(playerid,name[],value[]);
public LoadUser_data(playerid,name[],value[])
{
INI_Int("Arma0",PlayerInfo[playerid][pArma0]);
INI_Int("Arma1",PlayerInfo[playerid][pArma1]);
INI_Int("Arma2",PlayerInfo[playerid][pArma2]);
INI_Int("Arma3",PlayerInfo[playerid][pArma3]);
INI_Int("Arma4",PlayerInfo[playerid][pArma4]);
INI_Int("Arma5",PlayerInfo[playerid][pArma5]);
INI_Int("Arma6",PlayerInfo[playerid][pArma6]);
INI_Int("Arma7",PlayerInfo[playerid][pArma7]);
INI_Int("Arma8",PlayerInfo[playerid][pArma8]);
INI_Int("Arma9",PlayerInfo[playerid][pArma9]);
INI_Int("Arma10",PlayerInfo[playerid][pArma10]);
INI_Int("Arma11",PlayerInfo[playerid][pArma11]);
INI_Int("Arma12",PlayerInfo[playerid][pArma12]);
INI_Int("Balas0",PlayerInfo[playerid][pBalas0]);
INI_Int("Balas1",PlayerInfo[playerid][pBalas1]);
INI_Int("Balas2",PlayerInfo[playerid][pBalas2]);
INI_Int("Balas3",PlayerInfo[playerid][pBalas3]);
INI_Int("Balas4",PlayerInfo[playerid][pBalas4]);
INI_Int("Balas5",PlayerInfo[playerid][pBalas5]);
INI_Int("Balas6",PlayerInfo[playerid][pBalas6]);
INI_Int("Balas7",PlayerInfo[playerid][pBalas7]);
INI_Int("Balas8",PlayerInfo[playerid][pBalas8]);
INI_Int("Balas9",PlayerInfo[playerid][pBalas9]);
INI_Int("Balas10",PlayerInfo[playerid][pBalas10]);
INI_Int("Balas11",PlayerInfo[playerid][pBalas11]);
INI_Int("Balas12",PlayerInfo[playerid][pBalas12]);
return 1;
}
pawn Код:
public LoadUser_data(playerid,name[],value[])//el _data es un tag veras mas tarde
Pensaras їQue ocurre cuadno se carga esta funcion?
Fijate:
INI_Int("Arma0",
PlayerInfo[playerid][pArma0]);
їTe suena de algo? Si es el enum, es decir un monton de news por asi decirlo.
En esta funcion estamos guardando en las variables el dato que hay contenido dentro del .ini
Ejemplo:
En el .ini pone Arma0 = 1
La varaible es igual a lo que contenga Arama0 asique la varible ahora tiene el numero 1
pawn Код:
INI_Int("Arma0",PlayerInfo[playerid][pArma0]);
Ahora el
pawn Код:
INI_ParseFile(UserPath(playerid), "LoadUser_%s", .bExtra = true, .extra = playerid);
es mas compresible verdad?
UserPath(playerid), "LoadUser_%s" Ahi podemos ver el tag %s, que sera el UserPath
Con este codigo hasta ahora hemos conseguido:
- Decir donde guardar los datos(carpeta y con que nombre)
- Crear el .ini con los datos a 0 cuadno el jugador entra por primera vez
- Cargar los datos del personaje cuando se conecta y tiene cuenta
Extra
Ejemplo de guardar armas al desconectarse:
pawn Код:
public OnPlayerDisconnect(playerid, reason)
{
GetPlayerWeaponData(playerid, 0, PlayerInfo[playerid][pArma0], PlayerInfo[playerid][pBalas0]);//guarda en las variables los nuevos datos
GetPlayerWeaponData(playerid, 1, PlayerInfo[playerid][pArma1], PlayerInfo[playerid][pBalas1]);
GetPlayerWeaponData(playerid, 2, PlayerInfo[playerid][pArma2], PlayerInfo[playerid][pBalas2]);
GetPlayerWeaponData(playerid, 3, PlayerInfo[playerid][pArma3], PlayerInfo[playerid][pBalas3]);
GetPlayerWeaponData(playerid, 4, PlayerInfo[playerid][pArma4], PlayerInfo[playerid][pBalas4]);
GetPlayerWeaponData(playerid, 5, PlayerInfo[playerid][pArma5], PlayerInfo[playerid][pBalas5]);
GetPlayerWeaponData(playerid, 6, PlayerInfo[playerid][pArma6], PlayerInfo[playerid][pBalas6]);
GetPlayerWeaponData(playerid, 7, PlayerInfo[playerid][pArma7], PlayerInfo[playerid][pBalas7]);
GetPlayerWeaponData(playerid, 8, PlayerInfo[playerid][pArma8], PlayerInfo[playerid][pBalas8]);
GetPlayerWeaponData(playerid, 9, PlayerInfo[playerid][pArma9], PlayerInfo[playerid][pBalas9]);
GetPlayerWeaponData(playerid, 10, PlayerInfo[playerid][pArma10], PlayerInfo[playerid][pBalas10]);
GetPlayerWeaponData(playerid, 11, PlayerInfo[playerid][pArma11], PlayerInfo[playerid][pBalas11]);
GetPlayerWeaponData(playerid, 12, PlayerInfo[playerid][pArma12], PlayerInfo[playerid][pBalas12]);
new INI:File = INI_Open(UserPath(playerid));
INI_WriteInt(File,"Arma0",PlayerInfo[playerid][pArma0]);//guarda en el archo .ini los datos guardados en el paso anterior
INI_WriteInt(File,"Balas0",PlayerInfo[playerid][pBalas0]);
INI_WriteInt(File,"Arma1",PlayerInfo[playerid][pArma1]);
INI_WriteInt(File,"Balas1",PlayerInfo[playerid][pBalas1]);
INI_WriteInt(File,"Arma2",PlayerInfo[playerid][pArma2]);
INI_WriteInt(File,"Balas2",PlayerInfo[playerid][pBalas2]);
INI_WriteInt(File,"Arma3",PlayerInfo[playerid][pArma3]);
INI_WriteInt(File,"Balas3",PlayerInfo[playerid][pBalas3]);
INI_WriteInt(File,"Arma4",PlayerInfo[playerid][pArma4]);
INI_WriteInt(File,"Balas4",PlayerInfo[playerid][pBalas4]);
INI_WriteInt(File,"Arma5",PlayerInfo[playerid][pArma5]);
INI_WriteInt(File,"Balas5",PlayerInfo[playerid][pBalas5]);
INI_WriteInt(File,"Arma6",PlayerInfo[playerid][pArma6]);
INI_WriteInt(File,"Balas6",PlayerInfo[playerid][pBalas6]);
INI_WriteInt(File,"Arma7",PlayerInfo[playerid][pArma7]);
INI_WriteInt(File,"Balas7",PlayerInfo[playerid][pBalas7]);
INI_WriteInt(File,"Arma8",PlayerInfo[playerid][pArma8]);
INI_WriteInt(File,"Balas8",PlayerInfo[playerid][pBalas8]);
INI_WriteInt(File,"Arma9",PlayerInfo[playerid][pArma9]);
INI_WriteInt(File,"Balas9",PlayerInfo[playerid][pBalas9]);
INI_WriteInt(File,"Arma10",PlayerInfo[playerid][pArma10]);
INI_WriteInt(File,"Balas10",PlayerInfo[playerid][pBalas10]);
INI_WriteInt(File,"Arma11",PlayerInfo[playerid][pArma11]);
INI_WriteInt(File,"Balas11",PlayerInfo[playerid][pBalas11]);
INI_WriteInt(File,"Arma12",PlayerInfo[playerid][pArma12]);
INI_WriteInt(File,"Balas12",PlayerInfo[playerid][pBalas12]);
INI_Close(File);
return 1;
}
Este ejemplo es valido aunque no siempre tiene que ser guardado el dato en las varibles para ser guardado.
Puedes poner caulquier numero ejemplo
pawn Код:
INI_WriteInt(File,"ID",playerid);
O puedes guardar numero decimales con
pawn Код:
Float: healt
GetPlayerHealth(playerid,health);
INI_WriteFloat(File,"Healt",healt);
Atencion: Este tutorial requiere un minimo muy minimo de conocimientos en pawn o programacion general sino mira el tutorial anteriormente expuesto.
PD: Si esta algo mal, acepto criticas y correcciones(ortograficas tambien
)
Muchas gracias