[Tutorial] Vehicle Data
#1

Vehicle Data

Ever wanted to store data for a vehicle? It's very simple. If you know how to store player data, you know how to store vehicle data.

Basics

Let's take a look at 2 key terms:

playerid and vehicleid

Both these terms represent integers, which is why it's possible to create "for" loops starting at zero and passing "i" as a playerid.

What We Know

Let's look at a simple player data table:

pawn Code:
enum playerdata
{
    pass[24],
    money,
    score
}
new pInfo[MAX_PLAYERS][playerdata];
From what we know, if we wanted to set a player's money, all we would need to do is change pInfo[playerid][money].

This same concept can be applied to vehicles:

pawn Code:
enum vehicledata
{
    owner[24],
    engine,
    tires
}
new vInfo[MAX_VEHICLES][vehicledata];
To use this data, all we need is a vehicleid.

Applications

To get a vehicleid, the easiest way would be to assign a vehicle with a custom variable:

pawn Code:
new WorldCar[10];

//Under OnGameModeInIt
WorldCar[0] = CreateVehicle...
WorldCar[1] = CreateVehicle...
To access and change the data, all we would have to do is use vInfo[WorldCar[0]][owner], or whatever you may choose for your variables. WorldCar[0] is a placeholder for an integer, the same way playerid is a placeholder for an integer.

The reason I chose to assign WorldCar to an array would be to easily loop all selected vehicles to detect a specific one easier, or to change 1 variable for all cars at once:

pawn Code:
for(new i=0; i<MAX_VEHICLES; i++)
{
     vInfo[WorldCar[i]][owner] = "Rental";
}
To test the data, you can set up a command to show vehicle data for a vehicle you entered.

pawn Code:
CMD:test(playerid, params[])
{
    for(new i=0; i<MAX_VEHICLES; i++)
    {
        if(IsPlayerInVehicle(playerid, WorldCar[i], 0))
        {
            PrintF("VDATA: owner: %s engine: %i tires: %i", vInfo[WorldCar[i]][owner], vInfo[WorldCar[i]][engine], vInfo[WorldCar[i]][tires]);
        }
    }
    return 1;
}
After testing to make sure that data is working per vehicle, you can display vehicle data using chat, textdraws, 3dtextlabels, or anywhere you can place text.

I hope this tutorial was somewhat informative, thanks for reading.
Reply
#2

Shouldn't
pawn Code:
for(new i=0; i<MAX_PLAYERS; i++)
{
     vInfo[WorldCar[i]][owner] = "Rental";
}
loop through MAX_VEHICLES instead?
Reply
#3

Quote:
Originally Posted by Luis-
View Post
Shouldn't
pawn Code:
for(new i=0; i<MAX_PLAYERS; i++)
{
     vInfo[WorldCar[i]][owner] = "Rental";
}
loop through MAX_VEHICLES instead?
You would be correct. Wrote this up at 6 am without sleep, expect errors.
Reply
#4

Haha, fair enough! Good tutorial though
Reply
#5

You also don't need to store a vehicleid anywhere.
Just use GetPlayerVehicleID to get the ID.
Or use the vehicleid parameter from a callback that relates to vehicles, like OnPlayerEnterVehicle.

You could add this info to your tutorial.
Reply
#6

Quote:
Originally Posted by PowerPC603
View Post
You also don't need to store a vehicleid anywhere.
Just use GetPlayerVehicleID to get the ID.
Or use the vehicleid parameter from a callback that relates to vehicles, like OnPlayerEnterVehicle.

You could add this info to your tutorial.
While that's true, the vehicle you want to be saving data for is usually specific.

When you want to use GetPlayerVehicleID(playerid) you still have to check if they are in WorldCar[i].

What you're saying is possible, but would not work in this case.
Reply
#7

I would just add a field in the vehicledata enum that holds a bool to indicate if it's a worldvehicle or not.
Then you can check it easily as well, and this way all your data about a vehicle is combined into a single enum.

Otherwise you have multiple arrays, each one holding different data:
- vehicleinfo
- worldinfo
- copcar
- admincars
- whatever else

When you enter a vehicle and you want to know if this entered vehicle is a worldcar, you need to loop through all worldcar indices and see if you find a match.
If you found a match, it's a worldcar.
If you can't find a match, it's not a worldcar.

Putting all that data in one enum (vehicleinfo), removed that loop, speeding up your script as it doesn't need to search for a vehicleid.
The OnPlayerEnterVehicle callback already gives you the vehicleid.
You could easily check if this vehicle is a worldcar:
pawn Code:
if (vehicleinfo[vehicleid][IsWorldCar] == true)
You don't need a loop to check this.

Or if you use another callback that doesn't give you a vehicleid, just use GetPlayerVehicleID to get the vehicleid you need to access ALL data about that vehicle, as it's all stored into one single enum.

And to make a worldcar, you only need a short function:
pawn Code:
CreateWorldCar()
{
new vehicleid = CreateVehicle(...
vehicleinfo[vehicleid][IsWorldCar] = true;
return vehicleid;
}
This is how my data is stored about every vehicle in my own scripts and it works perfectly.


Your solution works fine too, except you need loops to find data inside arrays, and you use less memory.
But memory is less of an issue these days because computers have more and more memory (mine has 12GB of RAM), a few extra kilobytes won't hurt a true server.
Reply
#8

Quote:
Originally Posted by PowerPC603
View Post
I would just add a field in the vehicledata enum that holds a bool to indicate if it's a worldvehicle or not.
Then you can check it easily as well, and this way all your data about a vehicle is combined into a single enum.

Otherwise you have multiple arrays, each one holding different data:
- vehicleinfo
- worldinfo
- copcar
- admincars
- whatever else

When you enter a vehicle and you want to know if this entered vehicle is a worldcar, you need to loop through all worldcar indices and see if you find a match.
If you found a match, it's a worldcar.
If you can't find a match, it's not a worldcar.

Putting all that data in one enum (vehicleinfo), removed that loop, speeding up your script as it doesn't need to search for a vehicleid.
The OnPlayerEnterVehicle callback already gives you the vehicleid.
You could easily check if this vehicle is a worldcar:
pawn Code:
if (vehicleinfo[vehicleid][IsWorldCar] == true)
You don't need a loop to check this.

Or if you use another callback that doesn't give you a vehicleid, just use GetPlayerVehicleID to get the vehicleid you need to access ALL data about that vehicle, as it's all stored into one single enum.

And to make a worldcar, you only need a short function:
pawn Code:
CreateWorldCar()
{
new vehicleid = CreateVehicle(...
vehicleinfo[vehicleid][IsWorldCar] = true;
return vehicleid;
}
This is how my data is stored about every vehicle in my own scripts and it works perfectly.


Your solution works fine too, except you need loops to find data inside arrays, and you use less memory.
But memory is less of an issue these days because computers have more and more memory (mine has 12GB of RAM), a few extra kilobytes won't hurt a true server.
Ah, I see. Memory is not an issue on my end, although I haven't worked extensively with vehicle data. I can only think of 2 scripts I used vehicle data for, and they used the method that I used in the tutorial. I'll definitely consider adding your method to the tutorial when I get back to my desktop computer.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)