Improving and bugfixing a mysql loading process (Vehicles)
#1

Hello, I have a bug that makes vehicles with an id over 350 mix up their tuning.

Also the process to load vehicle data could be improved in more ways than just fixing that bug.


Vehicles Enum:
pawn Code:
enum vInfo
{
    Model, Float:vX,Float:vY,Float:vZ,Float:A, ColorA, ColorB, Value, Price, Owner[37],
    Type,ID,Cargo1,Cargo2,Cargo3, Ammo1,Ammo2,Ammo3,Shipping, Para, bool:Heal,bool:Armour,
    Mod1, Mod2, Mod3, Mod4, Mod5, Mod6, Mod7, Mod8, Mod9, Mod10, Mod11, Mod12, Mod13,
    Mod14, Mod15,Mod16,Mod17,PaintJob,Interior,World,Home,Lic[33],Protection,bool:Lock,
};
new VehicleInfo[MAX_VEHICLES][vInfo], VehicleCounter=0;

Tuning Functions:
pawn Code:
public OnVehicleSpawn(vehicleid)
{
    TuneCar(VehicleInfo[vehicleid][ID]);
    return 1;
}

TuneCar(vehicleid)
{
    new sveh=(vehicleid-1); // Array assignment fix
    if(VehicleInfo[sveh][PaintJob] != -1) ChangeVehiclePaintjob(vehicleid, VehicleInfo[sveh][PaintJob]);
    if(VehicleInfo[sveh][Mod1] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod1]);
    if(VehicleInfo[sveh][Mod2] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod2]);
    if(VehicleInfo[sveh][Mod3] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod3]);
    if(VehicleInfo[sveh][Mod4] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod4]);
    if(VehicleInfo[sveh][Mod5] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod5]);
    if(VehicleInfo[sveh][Mod6] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod6]);
    if(VehicleInfo[sveh][Mod7] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod7]);
    if(VehicleInfo[sveh][Mod8] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod8]);
    if(VehicleInfo[sveh][Mod9] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod9]);
    if(VehicleInfo[sveh][Mod10] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod10]);
    if(VehicleInfo[sveh][Mod11] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod11]);
    if(VehicleInfo[sveh][Mod12] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod12]);
    if(VehicleInfo[sveh][Mod13] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod13]);
    if(VehicleInfo[sveh][Mod14] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod14]);
    if(VehicleInfo[sveh][Mod15] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod15]);
    if(VehicleInfo[sveh][Mod16] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod16]);
    if(VehicleInfo[sveh][Mod17] != 0) AddVehicleComponent(vehicleid,VehicleInfo[sveh][Mod17]);
    ChangeVehicleColor(vehicleid, VehicleInfo[sveh][ColorA], VehicleInfo[sveh][ColorB]); // Patch paintjob

}
Vehicle load process:
pawn Code:
RetrieveVehicleData(vehicleid)
{
    new query[96], sveh=(vehicleid+1);
    format(query, sizeof(query), "SELECT * FROM `vehicledata` WHERE `ID` = '%d' AND `Type` != '8'", sveh);
    mysql_function_query(SQL_ConnectionHandle, query, false, "ProcessVehicleData", "i", vehicleid);
}

public ProcessVehicleData(vehicleid)
{
    mysql_store_result(); //Stores the result
    if(mysql_num_rows() != 0) // If the vehicle exists in the DB
    {
        new result[512], data[3], str1[37], str2[33], sveh=(vehicleid-1);
        mysql_fetch_row(result);
        mysql_free_result(); //Frees the result
        print(result);
        sscanf(result, "p<|>{i}iffffiiiis[36]iiiiiiiiiiiiiiiiiiiiiis[32]iiiiiiiii", data[0],            VehicleInfo[sveh][vX],
        VehicleInfo[sveh][vY],          VehicleInfo[sveh][vZ],          VehicleInfo[sveh][A],       VehicleInfo[sveh][ColorA],
        VehicleInfo[sveh][ColorB],      VehicleInfo[sveh][Value],       VehicleInfo[sveh][Price],           str1,
        VehicleInfo[sveh][Type],        VehicleInfo[sveh][Mod1],        VehicleInfo[sveh][Mod2],    VehicleInfo[sveh][Mod3],
        VehicleInfo[sveh][Mod4],        VehicleInfo[sveh][Mod5],        VehicleInfo[sveh][Mod6],    VehicleInfo[sveh][Mod7],
        VehicleInfo[sveh][Mod8],        VehicleInfo[sveh][Mod9],        VehicleInfo[sveh][Mod10],   VehicleInfo[sveh][Mod11],
        VehicleInfo[sveh][Mod12],       VehicleInfo[sveh][Mod13],       VehicleInfo[sveh][Mod14],   VehicleInfo[sveh][Mod15],
        VehicleInfo[sveh][Mod16],       VehicleInfo[sveh][Mod17],       VehicleInfo[sveh][PaintJob],    VehicleInfo[sveh][Interior],
        VehicleInfo[sveh][World],       VehicleInfo[sveh][Home],                str2,               VehicleInfo[sveh][Protection],
        VehicleInfo[sveh][Cargo1],      VehicleInfo[sveh][Cargo2],      VehicleInfo[sveh][Cargo3],  VehicleInfo[sveh][Ammo1],
        VehicleInfo[sveh][Ammo2],       VehicleInfo[sveh][Ammo3],               data[1],                    data[2]);
        // Heal & Armour ------------------------------------------------------------// Swap data
        strcpy(VehicleInfo[sveh][Owner], str1, 32); if(data[1] > 0){VehicleInfo[sveh][Heal]=true;}else{VehicleInfo[sveh][Heal]=false;}
        strcpy(VehicleInfo[sveh][Lic], str2, 32); if(data[2] > 0){VehicleInfo[sveh][Armour]=true;}else{VehicleInfo[sveh][Armour]=false;}
        if(VehicleInfo[sveh][Model] < 400) VehicleInfo[sveh][Model]=data[0]+400; // Try to Fix model id if needed
        VehicleCounter++;
        if(VehicleInfo[sveh][Type] < 0 || VehicleInfo[sveh][Type] == VehicleType_Spawned || VehicleInfo[sveh][Type] > 9)
        {   printf("Error: Vehicle %d is of an unsupported Type. Restting Type for vehicle %d to default!.", vehicleid, vehicleid);
            VehicleInfo[sveh][Type]=VehicleType_Default;
        }
        if(VehicleInfo[sveh][vX]==0 && VehicleInfo[sveh][vY]==0 && VehicleInfo[sveh][vZ]==0) return 1;
        if(VehicleInfo[sveh][Model] < 400 || VehicleInfo[sveh][Model] > 611) VehicleInfo[sveh][Model]=550; // Reset vehicle if model is unknown
        VehicleInfo[sveh][ID] = CreateVehicle(VehicleInfo[sveh][Model], VehicleInfo[sveh][vX], VehicleInfo[sveh][vY], VehicleInfo[sveh][vZ], VehicleInfo[sveh][A], 1, 1, -1);
        if(isnull(VehicleInfo[sveh][Lic])){SetLicensePlate(VehicleInfo[sveh][ID]);}else SetVehicleNumberPlate(VehicleInfo[sveh][ID],VehicleInfo[sveh][Lic]);
        if(VehicleInfo[sveh][Interior] > 18) VehicleInfo[sveh][Interior]=0;
        LinkVehicleToInterior(VehicleInfo[sveh][ID], VehicleInfo[sveh][Interior]);
        if(VehicleInfo[sveh][World] > 1000) VehicleInfo[sveh][World]=0;
        SetVehicleVirtualWorld(VehicleInfo[sveh][ID], VehicleInfo[sveh][World]);
        SetVehicleToRespawn(VehicleInfo[sveh][ID]); // Misc Fix
        printf("Vehicle %d Loaded with following data:", vehicleid);
        printf("Model: %i\t\tX: %f Y: %f Z: %f", VehicleInfo[sveh][Model], VehicleInfo[sveh][vX], VehicleInfo[sveh][vY], VehicleInfo[sveh][vZ]);
        printf("R: %f\t\tColorA: %i ColorB: %i",VehicleInfo[sveh][A], VehicleInfo[sveh][ColorA],VehicleInfo[sveh][ColorB]);
        printf("Value: %i Price: %i\t\tOwner: %s", VehicleInfo[sveh][Value], VehicleInfo[sveh][Price], VehicleInfo[sveh][Lic]);
        printf("Type: %i\t\t\tMods:\t###",VehicleInfo[sveh][Type]);
        printf("Mod1: %i Mod2: %i Mod3: %i Mod4:%i Mod5: %i Mod6: %i Mod7: %i", VehicleInfo[sveh][Mod1], VehicleInfo[sveh][Mod2], VehicleInfo[sveh][Mod3],VehicleInfo[sveh][Mod4],VehicleInfo[sveh][Mod5],VehicleInfo[sveh][Mod6],VehicleInfo[sveh][Mod7]);
        printf("Mod8: %i Mod9: %i Mod10: %i Mod11: %i Mod12: %i Mod13:%i", VehicleInfo[sveh][Mod8], VehicleInfo[sveh][Mod9], VehicleInfo[sveh][Mod10], VehicleInfo[sveh][Mod11], VehicleInfo[sveh][Mod12], VehicleInfo[sveh][Mod13]);
        printf("Mod14: %i Mod15: %i Mod16: %i Mod17: %i\t\tPaintJob: %i", VehicleInfo[sveh][Mod14], VehicleInfo[sveh][Mod15], VehicleInfo[sveh][Mod16], VehicleInfo[sveh][Mod17], VehicleInfo[sveh][PaintJob]);
        printf("<|> Int: %i World: %i\t\tLicense Plate: %s", VehicleInfo[sveh][Interior],VehicleInfo[sveh][World],VehicleInfo[sveh][Home],VehicleInfo[sveh][Lic]);
        printf("Protection: %i\t\tCargo: #1: %i #2: %i #3: %i", VehicleInfo[sveh][Protection], VehicleInfo[sveh][Cargo1], VehicleInfo[sveh][Cargo2], VehicleInfo[sveh][Cargo3]);
        printf("Ammo: #1: %i #2: %i #3: %i\t\tHeal: %i Armour: %i",VehicleInfo[sveh][Ammo1],VehicleInfo[sveh][Ammo2], VehicleInfo[sveh][Ammo3], VehicleInfo[sveh][Heal], VehicleInfo[sveh][Armour]);
    }else printf("Error: Tried to load vehicle %i which was not found in th DB!", vehicleid);
    return 1;
}
Current function to load all vehicles:
pawn Code:
for(new id=1; id < MAX_CARS; id++)
{  
    if(id < sizeof(VehicleInfo)) RetrieveVehicleData(id);
}
printf("%d Vehicles got created!", VehicleCounter);
I have two questions:
1. How do i get rid of that bug?
2. How do i load many vehicles in a better way?
(I'm running the R7 version of the mysql plugin)
Reply
#2

Your logic for the TuneCar parameter is plain wrong. But your enumeration is probably far too complex to spot it on the first sight. You see that as soon as you pass the ID value from the enum to TuneCar, the function will subtract 1 from the ID value and then access the enum WITH THE SAME INDEX.

pawn Code:
public OnVehicleSpawn(vehicleid)
{
    TuneCar(vehicleid);
}

stock TuneCar(vehicleid)
{
    new index = vehicleid - 1;
    vehicleid = VehicleInfo[index][ID];
    if(VehicleInfo[index][PaintJob] != -1) ChangeVehiclePaintjob(vehicleid, VehicleInfo[index][PaintJob]);
}
Also, what's very bad, is that you use a query per vehicle. What's wrong with doing
pawn Code:
mysql_function_query(1, "SELECT * FROM vehicledata WHERE Type != 8", true, "OnVehiclesLoad", "");
And you were wondering about how to convert it, so I already started off by passing true as the value for caching, so lets see how it would work with cache:
pawn Code:
forward OnVehiclesLoad();
public OnVehiclesLoad()
{
    new rows, fields;
    cache_get_data(rows, fields);
    for(i = 0; i != rows; i++)
    {
        cache_get_row(i, 0, /* FIRST FIELD */);
    }
    return 1;
}
To simplify your overall working process, why do you store the vehicle ID in the array with some other index, rather keep it as the index itself?

(Overall, I'm just too tired to understand your code)
Reply
#3

I'm aware of the dual subtraction, but fixing that has no effect, I updated the code on the first post so the shown code is still valid.


For loading a few vehicles this isn't bad.
pawn Code:
mysql_function_query(SQL_ConnectionHandle, query, false, "ProcessVehicleData", "i", vehicleid)
But i asked how to improve the loading for many vehicles rather than looping the funtion RetriveVehicleData(vehicleid);


The reason for storing vehicle id's within the enum was mainly to see if it had any effect regarding the tuning mix up.



Will play around with the tuning function and the example to see if i can get around the problem with tuning.


EDIT: Fixed after switching to cached functions.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)