I've taken care of that issue and here is my solution:
I used the LS airport runway and mapped 100 of them behind each other above the sea to get a perfectly flat, long straight road. I placed the Infernus at the beginning of the track and ran this code:
pawn Код:
new Float:oldvel;
new Float:startX, Float:startY, Float:startZ;
new Float:endX, Float:endY, Float:endZ;
//This function is called every 250 milliseconds (4 times a second)
public Speedo(playerid)
{
new Float:newX, Float:newY, Float:newZ;
if(IsPlayerInAnyVehicle(playerid)) //Player is inside a vehicle
{
GetVehicleVelocity(GetPlayerVehicleID(playerid), newX, newY, newZ); //Gets the X Y and Z velocity of the vehicle
new Float:newvel = floatsqroot(floatmul(newX, newX) + floatmul(newY, newY) + floatmul(newZ, newZ)); //Calculates the velocity of the vehicle
if(newvel > oldvel) //The newly recorded velocity is bigger than the perviously recorded velocity (At the very beginning oldvel is 0.0 obviously).
{
new msg[128];
format(msg, sizeof(msg), "Velocity: %.4f", newvel);
oldvel = newvel; //The old velocity is new the newly recorded velocity. This is saved to use the value again the next time the velocity is checked
SendClientMessage(playerid, -1, msg);
}
else if(newvel <= oldvel) //The newly recorded velocity is smaller or equal to the previously recorded velocity, which means the vehicle topped out and will not gain any more velocity. It's arrived at it's topspeed
{
KillTimer(timer); //The timer is stopped
timetimer = SetTimerEx("Time", 1000, false, "i", playerid); //Sets up a timer that calls "Time" after 1 second.
GetPlayerPos(playerid, startX, startY, startZ); //Saves the position of the vehicle
SendClientMessage(playerid, -1, "Starting to record");
}
}
return 1;
}
public Time(playerid)
{
GetPlayerPos(playerid, endX, endY, endZ); //Saves the new position of the vehicle (1 second after it was saved the first time)
new Float:distance = floatsub(startX, endX); //Calculates the distance between the 1st and 2nd saved position of the vehicle. I can simply subtract the X coordinates because the vehicle drove perfectly parallel to the X-axis.
//We now have the distance the vehicle travelled in 1 second with topped out speed (max. velocity). The unit is m/s
new Float:speed = floatmul(distance, 3.6); //Converts m/s in km/h
new msg[128];
format(msg, 128, "You travelled %.4f m in 1 second, that makes %.4f km/h", distance, speed);
SendClientMessage(playerid, -1, msg);
KillTimer(timetimer);
return 1;
}
What I basically did is I accelerated the Infernus until it didn't get any faster. I then saved it's position and did it again after 1 second. I can now calculate the distance the vehicle travelled in this second. Since the GTA: SA distance unit is meter, the unit is m/s.
Having this done, the Infernus topped at
247.5km/h.
For the sake of it I also tested the DFT-30 and Rumpo. They topped out at 145km/h and 122km/h, which, to be fair, seems pretty legit to me.
Dividing max. velocity/associated speed gives me ~199, which pretty much confirms previous calculations here.
Which leads to:
Speed in km/h = sqrt(max X velocity^2 + max Y velocity^2 + max Z velocity^2) * 199
To get an accurate value all vehicles should be tested though.