# [QUESTION] How to record distance travelled by vehicle?

## Recommended Posts

Hello people. Few days ago I started creating a new PlayerStats panel mainly focused on racing. I added the following things so far and they all work perfectly:

-Cars destroyed

-Bikes destroyed

-Boats destroyed

-Planes & Helicopters destroyed

-Race starts

-Race finishes

-Race wins

-Toptimes set

-Checkpoints collected

-Total earnings

-Money spent

-Current balance

But I also wanted to add these things:

*Distance travelled by car

*Distance travelled by motorbike

*Distance travelled by boat

*Distance travelled by aircraft

*Distance travelled by bicycle

So my question is, how can I record the distance travelled and save it as account data like all other stats above? I saw this and although I found the code responsible for recording the distance it's done in a pretty hard way (at least for me). Is there an easy way to record distance travelled by each of the above vehicles (in KMh)?

Posted (edited)
```local totalDis
local lastX, lastY, lastZ

function startJourney()
if not lastX then -- if there is no previous position save the current
lastX, lastY, lastZ = getElementPosition(vehElement)
end
setTimer(function()
local currX, currY, currZ = getElementPosition(vehElement) -- get the current position of the vehicle
totalDis = getDistanceBetweenPoints3D(currX, currY, currZ, lastX, lastY, lastZ ) -- calculate the distance between the current and the last and add it to the totalDistance
lastX, lastY, lastZ = currX, currY, currZ -- update the last position with the current
end, 2000, 0) -- 2 sec infinite timer, could be increased/decreased, the smaller it is the more accurate results you get
end```

I used something like that in one of my projects, not saying it's the best solution, but it was working fine for me.

Edited by pa3ck
• 1

Posted (edited)

I guess that's server-side right? And I'll be able to check if it's a car, bike, etc by doing an "if getElementModel(vehElement) == 411 then". Timer set to 50 sounds the most accurate.

Edited by koragg
Or it would be better if I add an "onClientRender" and make it client-side?

Posted (edited)

Doesn't have to be server side, it's fine on client side with something like getTickCount() so you only update the element data every couple of seconds, like 5-8-10 secs or so, depending if you need to display it on HUD, that would be a bit choppy. Regarding the timer tick, 50 would be the most accurate, yea, but I don't think it's that important to get as accurate result as you can. See when you drive 150m forward, then 50m backward between 2 ticks, it will only update 100, not 200 (as a real car would), but you can't really change much on the outcome under 1-2 second time span.

Edited by pa3ck

Posted (edited)

You could use this.

```local total_km, partial_km, tick_km = 0, 0, 0

function handleSpeed()
if ( getPedOccupiedVehicle( localPlayer ) and getVehicleOccupant( getPedOccupiedVehicle( localPlayer ), 0 ) == localPlayer ) then
local theVehicle = getPedOccupiedVehicle( localPlayer )

if ( tick_km <= 0 ) and ( getVehicleEngineState( vehicle ) ) then
tick_km = getTickCount()
end

if ( getTickCount() - tick_km >= 1000 ) then
local sx, sy, sz = getElementVelocity ( theVehicle )
local kms = ( ( ( sx * sx ) + ( sy * sy ) + ( sz * sz ) ) ^ ( 0.5 ) ) * 1000 / 3600 -- This would be the most realistic way but it add's up very fastly so better up the number that is dividing.

if ( partial_km + kms >= 1 ) then
partial_km = ( partial_km + kms ) - 1

total_km = total_km + 1
else
partial_km = partial_km + kms
end

tick_km = getTickCount()
end
end
end

Edited by Simple01
• 1

Posted (edited)

Thanks to both of you, I used @Simple01's code as I did something similar when recording total drift score some time ago and was more familiar with it being client side.

1. Recorded the distance client-side

2. Sent it to server-side with events (those things are priceless)

Client:

```-- Used to record distance passed with the specific vehicle category.
local totalAircraft_km = 0
local partialAircraft_km = 0
local tickAircraft_km = 0

local totalBoat_km = 0
local partialBoat_km = 0
local tickBoat_km = 0

local totalBike_km = 0
local partialBike_km = 0
local tickBike_km = 0

local totalCar_km = 0
local partialCar_km = 0
local tickCar_km = 0

local totalBicycle_km = 0
local partialBicycle_km = 0
local tickBicycle_km = 0

function handleSpeed()
local car = getPedOccupiedVehicle(localPlayer)
local id
if car then
id = getElementModel(car)
end

-- distanceByAircraft
if id == 592 or id == 577 or id == 511 or id == 512 or id == 593 or id == 520 or id == 553 or id == 476 or id == 519
or id == 460 or id == 513 or id == 548 or id == 425 or id == 417 or id == 487 or id == 488 or id == 497 or id == 563
or id == 447 or id == 469 then
if car and getVehicleOccupant(car, 0) == localPlayer then
if tickAircraft_km <= 0 and getVehicleEngineState(car) then
tickAircraft_km = getTickCount()
end
if getTickCount() - tickAircraft_km >= 1000 then
local sx, sy, sz = getElementVelocity(car)
local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650
if partialAircraft_km + kms >= 1 then
partialAircraft_km = partialAircraft_km + kms - 1
totalAircraft_km = totalAircraft_km + 1
triggerServerEvent("distanceByAircraft", localPlayer, totalAircraft_km)
else
partialAircraft_km = partialAircraft_km + kms
end
tickAircraft_km = getTickCount()
end
end

-- distanceByBoat
elseif id == 472 or id == 473 or id == 493 or id == 595 or id == 484 or id == 430 or id == 453 or id == 452 or
id == 446 or id == 454 then
if car and getVehicleOccupant(car, 0) == localPlayer then
if tickBoat_km <= 0 and getVehicleEngineState(car) then
tickBoat_km = getTickCount()
end
if getTickCount() - tickBoat_km >= 1000 then
local sx, sy, sz = getElementVelocity(car)
local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650
if partialBoat_km + kms >= 1 then
partialBoat_km = partialBoat_km + kms - 1
totalBoat_km = totalBoat_km + 1
triggerServerEvent("distanceByBoat", localPlayer, totalBoat_km)
else
partialBoat_km = partialBoat_km + kms
end
tickBoat_km = getTickCount()
end
end

-- distanceByBike
elseif id == 581 or id == 509 or id == 481 or id == 462 or id == 521 or id == 463 or id == 510 or id == 522 or
id == 461 or id == 448 or id == 468 or id == 586 then
if car and getVehicleOccupant(car, 0) == localPlayer then
if tickBike_km <= 0 and getVehicleEngineState(car) then
tickBike_km = getTickCount()
end
if getTickCount() - tickBike_km >= 1000 then
local sx, sy, sz = getElementVelocity(car)
local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650
if partialBike_km + kms >= 1 then
partialBike_km = partialBike_km + kms - 1
totalBike_km = totalBike_km + 1
triggerServerEvent("distanceByBike", localPlayer, totalBike_km)
else
partialBike_km = partialBike_km + kms
end
tickBike_km = getTickCount()
end
end

-- distanceByCar
elseif id == 602 or id == 496 or id == 401 or id == 518 or id == 527 or id == 589 or id == 419 or id == 587 or
id == 533 or id == 526 or id == 474 or id == 545 or id == 517 or id == 410 or id == 600 or id == 436 or id == 439 or
id == 549 or id == 491 or id == 485 or id == 431 or id == 438 or id == 437 or id == 574 or id == 420 or id == 525 or
id == 408 or id == 552 or id == 416 or id == 433 or id == 427 or id == 490 or id == 528 or id == 407 or id == 544 or
id == 523 or id == 470 or id == 596 or id == 598 or id == 599 or id == 597 or id == 432 or id == 601 or id == 428 or
id == 499 or id == 609 or id == 498 or id == 524 or id == 532 or id == 578 or id == 486 or id == 406 or id == 573 or
id == 455 or id == 588 or id == 403 or id == 423 or id == 414 or id == 443 or id == 515 or id == 514 or id == 531 or
id == 456 or id == 459 or id == 422 or id == 482 or id == 605 or id == 530 or id == 418 or id == 572 or id == 582 or
id == 413 or id == 440 or id == 543 or id == 583 or id == 478 or id == 554 or id == 579 or id == 400 or id == 404 or
id == 489 or id == 505 or id == 479 or id == 442 or id == 458 or id == 536 or id == 575 or id == 534 or id == 567 or
id == 535 or id == 576 or id == 412 or id == 402 or id == 542 or id == 603 or id == 475 or id == 429 or id == 541 or
id == 415 or id == 480 or id == 562 or id == 565 or id == 434 or id == 494 or id == 502 or id == 503 or id == 411 or
id == 559 or id == 561 or id == 560 or id == 506 or id == 451 or id == 558 or id == 555 or id == 477 or id == 441 or
id == 464 or id == 594 or id == 501 or id == 465 or id == 564 or id == 606 or id == 607 or id == 610 or id == 584 or
id == 611 or id == 608 or id == 435 or id == 450 or id == 591 or id == 590 or id == 538 or id == 570 or id == 569 or
id == 537 or id == 449 or id == 568 or id == 424 or id == 504 or id == 457 or id == 483 or id == 508 or id == 571 or
id == 500 or id == 444 or id == 556 or id == 557 or id == 471 or id == 495 or id == 539 then
if car and getVehicleOccupant(car, 0) == localPlayer then
if tickCar_km <= 0 and getVehicleEngineState(car) then
tickCar_km = getTickCount()
end
if getTickCount() - tickCar_km >= 1000 then
local sx, sy, sz = getElementVelocity(car)
local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650
if partialCar_km + kms >= 1 then
partialCar_km = partialCar_km + kms - 1
totalCar_km = totalCar_km + 1
triggerServerEvent("distanceByCar", localPlayer, totalCar_km)
else
partialCar_km = partialCar_km + kms
end
tickCar_km = getTickCount()
end
end

-- distanceByBicycle
elseif id == 509 or id == 481 or id == 510 then
if car and getVehicleOccupant(car, 0) == localPlayer then
if tickBicycle_km <= 0 and getVehicleEngineState(car) then
tickBicycle_km = getTickCount()
end
if getTickCount() - tickBicycle_km >= 1000 then
local sx, sy, sz = getElementVelocity(car)
local kms = ((sx * sx + sy * sy + sz * sz)^(0.5) * 1000) / 20650
if partialBicycle_km + kms >= 1 then
partialBicycle_km = partialBicycle_km + kms - 1
totalBicycle_km = totalBicycle_km + 1
triggerServerEvent("distanceByBicycle", localPlayer, totalBicycle_km)
else
partialBicycle_km = partialBicycle_km + kms
end
tickBicycle_km = getTickCount()
end
end
end
end

Server:

```-- distanceByAircraft
function distanceByAircraft(currentDistance)
local playeraccount = getPlayerAccount(source)
if isGuestAccount(playeraccount) then
return
end

local prevDistance = tonumber(getAccountData(playeraccount, "distanceByAircraft") or 0)
local newDistance = prevDistance + tonumber(currentDistance)
setAccountData(playeraccount, "distanceByAircraft", newDistance)
setElementData(source, "distanceByAircraft", newDistance)
end

-- distanceByBoat
function distanceByBoat(currentDistance)
local playeraccount = getPlayerAccount(source)
if isGuestAccount(playeraccount) then
return
end

local prevDistance = tonumber(getAccountData(playeraccount, "distanceByBoat") or 0)
local newDistance = prevDistance + tonumber(currentDistance)
setAccountData(playeraccount, "distanceByBoat", newDistance)
setElementData(source, "distanceByBoat", newDistance)
end

-- distanceByBike
function distanceByBike(currentDistance)
local playeraccount = getPlayerAccount(source)
if isGuestAccount(playeraccount) then
return
end

local prevDistance = tonumber(getAccountData(playeraccount, "distanceByBike") or 0)
local newDistance = prevDistance + tonumber(currentDistance)
setAccountData(playeraccount, "distanceByBike", newDistance)
setElementData(source, "distanceByBike", newDistance)
end

-- distanceByCar
function distanceByCar(currentDistance)
local playeraccount = getPlayerAccount(source)
if isGuestAccount(playeraccount) then
return
end

local prevDistance = tonumber(getAccountData(playeraccount, "distanceByCar") or 0)
local newDistance = prevDistance + tonumber(currentDistance)
setAccountData(playeraccount, "distanceByCar", newDistance)
setElementData(source, "distanceByCar", newDistance)
end

-- distanceByBicycle
function distanceByBicycle(currentDistance)
local playeraccount = getPlayerAccount(source)
if isGuestAccount(playeraccount) then
return
end

local prevDistance = tonumber(getAccountData(playeraccount, "distanceByBicycle") or 0)
local newDistance = prevDistance + tonumber(currentDistance)
setAccountData(playeraccount, "distanceByBicycle", newDistance)
setElementData(source, "distanceByBicycle", newDistance)
end

And then used the element data to show the correct info on the GUI.

PS: I'm pretty sure I could have avoided like 70% of the code as it's the same but I prefer to play it safe

Edited by koragg
• 1

Quality approved!

Ops, made a small typo and can't edit my previous post :\

The total distance needs to be set to 0 after the event gets triggered so:

```totalAircraft_km = totalAircraft_km + 1
triggerServerEvent("distanceByAircraft", localPlayer, totalAircraft_km)
totalAircraft_km = 0```

And like that^ for each vehicle category (totalCar_km = 0, totalBike_km = 0, etc.)

Otherwise it recorded huge numbers as passed KMh

```	elseif id == 602 or id == 496 or id == 401 or id == 518 or id == 527 or id == 589 or id == 419 or id == 587 or
id == 533 or id == 526 or id == 474 or id == 545 or id == 517 or id == 410 or id == 600 or id == 436 or id == 439 or
id == 549 or id == 491 or id == 485 or id == 431 or id == 438 or id == 437 or id == 574 or id == 420 or id == 525 or
id == 408 or id == 552 or id == 416 or id == 433 or id == 427 or id == 490 or id == 528 or id == 407 or id == 544 or
id == 523 or id == 470 or id == 596 or id == 598 or id == 599 or id == 597 or id == 432 or id == 601 or id == 428 or
id == 499 or id == 609 or id == 498 or id == 524 or id == 532 or id == 578 or id == 486 or id == 406 or id == 573 or
id == 455 or id == 588 or id == 403 or id == 423 or id == 414 or id == 443 or id == 515 or id == 514 or id == 531 or
id == 456 or id == 459 or id == 422 or id == 482 or id == 605 or id == 530 or id == 418 or id == 572 or id == 582 or
id == 413 or id == 440 or id == 543 or id == 583 or id == 478 or id == 554 or id == 579 or id == 400 or id == 404 or
id == 489 or id == 505 or id == 479 or id == 442 or id == 458 or id == 536 or id == 575 or id == 534 or id == 567 or
id == 535 or id == 576 or id == 412 or id == 402 or id == 542 or id == 603 or id == 475 or id == 429 or id == 541 or
id == 415 or id == 480 or id == 562 or id == 565 or id == 434 or id == 494 or id == 502 or id == 503 or id == 411 or
id == 559 or id == 561 or id == 560 or id == 506 or id == 451 or id == 558 or id == 555 or id == 477 or id == 441 or
id == 464 or id == 594 or id == 501 or id == 465 or id == 564 or id == 606 or id == 607 or id == 610 or id == 584 or
id == 611 or id == 608 or id == 435 or id == 450 or id == 591 or id == 590 or id == 538 or id == 570 or id == 569 or
id == 537 or id == 449 or id == 568 or id == 424 or id == 504 or id == 457 or id == 483 or id == 508 or id == 571 or
id == 500 or id == 444 or id == 556 or id == 557 or id == 471 or id == 495 or id == 539 then```

Woow, this very very very inefficient. O_o

+ > onClientRender <

I suggest to follow a table tutorial.

```local vehicleIDs = {
car = {
[501] = true,
[465] = true,
[607] = true,
[571] = true
}
boat = {
-- etc.
}
}```

```elseif vehicleIDs.car[id] then

elseif vehicleIDs.boat[id] then

and you might want to consider using: https://wiki.multitheftauto.com/wiki/TriggerLatentServerEvent

Since you trigger it every second, you have to take in account that not everybody has great internet. I would strongly recommend to send it every 10 or even 20 seconds. What does 10 seconds matter when they are an hour in the server?

• 1

Yep that's what i meant

I will try out what you said when i get some free time. I used onClientRender because i wanted it to be as accurate as possible but i see it's not really needed.

Posted (edited)

onClientRender is fine, just the id check and communication between the server can be optimised.

Update time to check the distance

You also increase (~50ms) the update time with getTickCount as you did before. (that gives you somehow less lagg than a 50 ms timer)

Edited by IIYAMA
• 1