[Tutorial] Soluciуn a problema de sistemas de vehнculos con Y_INI
#1

Soluciуn a problema de sistemas de vehнculos con Y_INI

Bien, he visto varios sistemas de vehнculos que usan .ini y tienen un problema, el problema es que las ID se mueven a donde no deberнan de estar al eliminar un vehнculo o archivo dentro del juego, y es por que es asн, estбn orientados y basados firmemente a el ID que tienen dentro del juego, en MySQL no pasa esto si se hace bien, la razуn es simple:

Al crear un vehнculo puede hacerse con un AUTO_INCREMENT, al cargar los vehнculos obtiene el ID que tiene cual tomу por el AUTO_INCREMENT todo con simples consultas, sin embargo en Y_INI hay un problema:

si quisiйramos cargar los vehнculos TODOS y uno tiene ID 5232 no se cargarнa, por el simple hecho de que crean un loop con mбximo a mбximos vehнculos permitidos, no crean un loop que sea dirigido a cargar los vehнculos totales en una carpeta, los archivos totales en ella. Guardan los datos en el lugar incorrecto al ser las ID pusheadas por otro vehнculo por ser destruido.

Pensй en una posible soluciуn al problema, con la siguiente funciуn:

PHP код:
stock countFiles(dir[] = '\0'type[] = "ini"get 0)
{
    new 
idxstr[MAX_FILE_NAME], clast gettime()+2n;
    if(
dir[0] != '\0')
    {
        if(
fexist(dir))
        {
            for( ; ; )
            {
                if(
last gettime())
                    break;
                
format(strsizeof(str), "%s/%d.%s"diridxtype);
                if(
fexist(str)){
                    
c++;
                    
last gettime()+2;
                    
idx;
                }
                ++
idx;
            }
        }
    }
    return ((
get == 0) ? (c) : (n));

Al seleccionar el get 0 retornarб la cantidad de vehнculos en una carpeta, al usar el 1 o sea cual sea retornarб el ъltimo ID de vehнculo cargado.

Es un loop infinito, sн, es claro para quй. Asн no se limitan a cargar hasta cierto ID si no hasta en donde ya no hayan mбs archivos a cargar, estoy consciente de la limitaciуn que la funciуn presenta, sin embargo no se darб hasta que haya un vehнculo con ID muy muy extensa.

Un sistema de vehнculos implementando la funciуn serнa por ejemplo:

PHP код:
#include <a_samp>
#include <YSI\Y_INI>
#define MAX_DVEHICLES   400
#define MAX_FILE_NAME   32
#define DIR_COCHES      "Autos"
enum InfoAutos
{
    
V_ID,
    
V_MODEL,
    
V_ORIGINAL,
    
V_COLOR[2],
    
V_EXIST,
    
Float:V_POS[4]
};
new 
InformacionA[MAX_DVEHICLES][InfoAutos],
    
LastVehicle;
forward LoadVehicleFromFile(id,name[],value[]);
public 
LoadVehicleFromFile(id,name[],value[])
{
    
INI_Int("Modelo",InformacionA[id][V_MODEL]);
    
INI_Float("PosX",InformacionA[id][V_POS][0]);
    
INI_Float("PosY",InformacionA[id][V_POS][1]);
    
INI_Float("PosZ",InformacionA[id][V_POS][2]);
    
INI_Float("Rotacion",InformacionA[id][V_POS][3]);
    
INI_Int("Color1",InformacionA[id][V_COLOR][0]);
    
INI_Int("Color2",InformacionA[id][V_COLOR][1]);
    return 
0;
}
stock GetIDVehicle(vehicleid)
{
    for(new 
i!= MAX_DVEHICLESi++)
    {
        if(
InformacionA[i][V_ORIGINAL] != vehicleid)
            continue;
        return 
i;
    }
    return -
1;
}
stock _SaveVehicleID(i)
{
    new 
_DirFile[MAX_FILE_NAME], INI:_File;
    
format(_DirFile,sizeof(_DirFile),DIR_COCHES"/%d.ini"InformacionA[i][V_ID]);
    if(!
fexist(_DirFile))
        return 
0;
    
_File INI_Open(_DirFile);
    
INI_SetTag(_File,"data");
    
INI_WriteInt(_File,"Modelo",InformacionA[i][V_MODEL]);
    
INI_WriteFloat(_File,"PosX",InformacionA[i][V_POS][0]);
    
INI_WriteFloat(_File,"PosY",InformacionA[i][V_POS][1]);
    
INI_WriteFloat(_File,"PosZ",InformacionA[i][V_POS][2]);
    
INI_WriteFloat(_File,"Rotacion",InformacionA[i][V_POS][3]);
    
INI_WriteInt(_File,"Color1",InformacionA[i][V_COLOR][0]);
    
INI_WriteInt(_File,"Color2",InformacionA[i][V_COLOR][1]);
    
INI_Close(_File);
    return 
1;
}
stock CargarAutos()
{
    new
        
_DirFile[MAX_FILE_NAME],
        
_c,
        
load,
        
total
        
;
    
printf("CARGANDO COCHES ...");
    
total countFiles(DIR_COCHES"ini"0);
    
LastVehicle countFiles(DIR_COCHES"ini"1);
    for(new 
i<= LastVehiclei++)
    {
        if(
load MAX_DVEHICLES)
            break;
        
format(_DirFile,sizeof(_DirFile),"%s/%d.ini"DIR_COCHES,i);
        if(
fexist(_DirFile))
        {
            if(
INI_ParseFile(_DirFile,"LoadVehicleFromFile",.bExtra true, .extra _c))
            {
                
InformacionA[_c][V_ID] = i;
                
InformacionA[_c][V_EXIST] = true;
                
InformacionA[_c][V_ORIGINAL] = CreateVehicle(InformacionA[_c][V_MODEL], InformacionA[_c][V_POS][0], InformacionA[_c][V_POS][1], InformacionA[_c][V_POS][2], InformacionA[_c][V_POS][3], InformacionA[_c][V_COLOR][0], InformacionA[_c][V_COLOR][1], -1);
                
load++;
            }
        }
        
_c++;
    }
    
printf("%d fin, %d total"_ctotal);
    
printf("Ultimo cargado > %d & Total cargados: %d"LastVehicleload);
    return 
1;
}
stock CreateVehicleEx(_MODELFloat:_XFloat:_YFloat:_ZFloat:_A_COLOR_TWO_COLOR_ONE)
{
    new 
str[128];
    for(new 
i<= MAX_DVEHICLESi++) if(!InformacionA[i][V_EXIST])
    {
        
InformacionA[i][V_EXIST] = true;
        
InformacionA[i][V_MODEL] = _MODEL;
        
InformacionA[i][V_POS][0] = _X;
        
InformacionA[i][V_POS][1] = _Y;
        
InformacionA[i][V_POS][2] = _Z;
        
InformacionA[i][V_POS][3] = _A;
        
InformacionA[i][V_COLOR][0] = _COLOR_ONE;
        
InformacionA[i][V_COLOR][1] = _COLOR_TWO;
        
InformacionA[i][V_ORIGINAL] = CreateVehicle(_MODEL_X_Y_Z_A_COLOR_ONE_COLOR_TWO, -1);
        
InformacionA[i][V_ID] = ++LastVehicle;
        
format(strsizeof(str), DIR_COCHES"/%i.ini"LastVehicle);
        
CreateFile(str);
        
_SaveVehicleID(i);
        return 
i;
    }
    return -
1;
}
stock CreateFile(filename[])
{
    if (
fexist(filename)){return false;}
    new 
File:fhandle fopen(filename,io_write);
    
fclose(fhandle);
    return 
true;
}
stock countFiles(dir[] = '\0'type[] = "ini"get 0)
{
    new 
idxstr[MAX_FILE_NAME], clast gettime()+2n;
    if(
dir[0] != '\0')
    {
        if(
fexist(dir))
        {
            for( ; ; )
            {
                if(
last gettime())
                    break;
                
format(strsizeof(str), "%s/%d.%s"diridxtype);
                if(
fexist(str)){
                    
c++;
                    
last gettime()+2;
                    
idx;
                }
                ++
idx;
            }
        }
    }
    return ((
get == 0) ? (c) : (n));
}
public 
OnGameModeInit()
{
    
CargarAutos();
    
// Don't use these lines if it's a filterscript
    
SetGameModeText("Blank Script");
    
AddPlayerClass(01958.37831343.157215.3746269.1425000000);
    return 
1;

Ahora, para obtener quй ID Relativa tiene un vehнculo en el servidor por el ID que SA:MP le ha dado serнa con algo como esto:

PHP код:
stock GetIDVehicle(vehicleid)
{
    for(new 
i!= MAX_DVEHICLESi++)
    {
        if(
InformacionA[i][V_ORIGINAL] != vehicleid)
            continue;
        return 
i;
    }
    return -
1;

Y con un comando asн se crearнan normalmente:

PHP код:
#include <a_samp>
#include <sscanf2>
#include <zcmd>
CMD:crearauto(playeridparams[])
{
    new 
_vModel[32];
    if(
sscanf(params"s[32]"_vModel))
        return 
1;
    if ((
_vModel[0] = GetVehicleModelByName(_vModel)) == 0)
        return 
1;
    new
        
Float:_pPos[4],
        
id = -1
        
;
    
GetPlayerPos(playerid_pPos[0], _pPos[1], _pPos[2]);
    
GetPlayerFacingAngle(playerid_pPos[3]);
    if((
id CreateVehicleEx(_vModel[0], _pPos[0], _pPos[1], _pPos[2], _pPos[3], -1, -1)) == -1)
        return 
0// Vehiculo no creado por no haber mas espacio
    #pragma unused id
    // Vehiculo creado
    
SendClientMessage(playerid, -1"Creaste un vehiculo!");
    return 
1;

Hay mбs mйtodos claro y MEJORES, esto no es mбs que una idea por algunos que no ven el problema o otros no tienen idea de como solucionarlo y se pasan a MySQL, MySQL sн es mejor para hacerlo y lograr algo asн, pero este es un mйtodo.
Reply
#2

Me solucionaste todos mis problemas xDD
Gracias.

Una pregunta, їesa funciуn la puedo usar tambiйn para un sistema de casas verdad?
Reply
#3

Sн, pero el sistema de casas es mбs simple (Ya que aquн eliminas una casa y йsta no toma un ID anterior hasta reiniciar, pero es importante que no sea por ID siguiendo el patrуn que le da, sino siguiendo el ID que tiene en su nombre de archivo), si crees necesaria usarla adelante.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)