mta-resources/[vehicles]/avelocity/client.lua

95 lines
3.9 KiB
Lua

local responses = {}
responses[0] = {
0.5,0.5,0.8,
-0.2,-0.2,0.8
}
responses[80] = {
0.5,0.8,0.6,
0.0,0.0,0.5
}
responses[120] = {
0.5,0.9,0.5,
0.0,0.0,0.6
}
--[[responses[200] = {
0.2,0.2,0.5,
0.2,0.2,0.5
}]]--
function getRatioWithin(v,st,ed)
if ed - st == 0 then return 1.0 end
return (v - st) / (ed - st)
end
function handleVehicle(veh)
local rvx,rvy,rvz = getVehicleTurnVelocity(veh)
if not getElementData(veh,"lastRvx") then
setElementData(veh,"lastRvx",rvx,false)
setElementData(veh,"lastRvy",rvy,false)
setElementData(veh,"lastRvz",rvz,false)
end
local lrvx = getElementData(veh,"lastRvx")
local lrvy = getElementData(veh,"lastRvy")
local lrvz = getElementData(veh,"lastRvz")
local offsetIndexX = 0
local offsetIndexY = 0
local offsetIndexZ = 0
if lrvx < 0 and rvx > lrvx then offsetIndexX = 3 end
if lrvx > 0 and rvx < lrvx then offsetIndexX = 3 end
if lrvy < 0 and rvy > lrvy then offsetIndexY = 3 end
if lrvy > 0 and rvy < lrvy then offsetIndexY = 3 end
if lrvz < 0 and rvz > lrvz then offsetIndexZ = 3 end
if lrvz > 0 and rvz < lrvz then offsetIndexZ = 3 end
local startProfile = false
local endProfile = false
local speed = getElementSpeed(veh,"km/h")
for targetSpeed,_ in pairs(responses) do
if startProfile == false then
if speed >= targetSpeed then startProfile = targetSpeed end
else
endProfile = targetSpeed
break
end
end
if startProfile == false then startProfile = 0 end
if endProfile == false then endProfile = startProfile end
local ratio = getRatioWithin(speed,startProfile,endProfile)
if ratio > 1 then ratio = 1 end
local mvx = responses[startProfile][1 + offsetIndexX] + ((responses[endProfile][1 + offsetIndexX] - responses[startProfile][1 + offsetIndexX])*ratio)
local mvy = responses[startProfile][2 + offsetIndexY] + ((responses[endProfile][2 + offsetIndexY] - responses[startProfile][2 + offsetIndexY])*ratio)
local mvz = responses[startProfile][3 + offsetIndexZ] + ((responses[endProfile][3 + offsetIndexZ] - responses[startProfile][3 + offsetIndexZ])*ratio)
rvx = rvx + ((lrvx - rvx) * mvx)
rvy = rvy + ((lrvy - rvy) * mvy)
rvz = rvz + ((lrvz - rvz) * mvz)
setVehicleTurnVelocity(veh,rvx,rvy,rvz)
setElementData(veh,"lastRvx",rvx,false)
setElementData(veh,"lastRvy",rvy,false)
setElementData(veh,"lastRvz",rvz,false)
end
function loop(ts)
for _,veh in ipairs(getElementsByType("vehicle")) do
handleVehicle(veh)
end
end
addEventHandler("onClientPreRender",root,loop)
function getElementSpeed(theElement, unit)
-- Check arguments for errors
assert(isElement(theElement), "Bad argument 1 @ getElementSpeed (element expected, got " .. type(theElement) .. ")")
local elementType = getElementType(theElement)
assert(elementType == "player" or elementType == "ped" or elementType == "object" or elementType == "vehicle" or elementType == "projectile", "Invalid element type @ getElementSpeed (player/ped/object/vehicle/projectile expected, got " .. elementType .. ")")
assert((unit == nil or type(unit) == "string" or type(unit) == "number") and (unit == nil or (tonumber(unit) and (tonumber(unit) == 0 or tonumber(unit) == 1 or tonumber(unit) == 2)) or unit == "m/s" or unit == "km/h" or unit == "mph"), "Bad argument 2 @ getElementSpeed (invalid speed unit)")
-- Default to m/s if no unit specified and 'ignore' argument type if the string contains a number
unit = unit == nil and 0 or ((not tonumber(unit)) and unit or tonumber(unit))
-- Setup our multiplier to convert the velocity to the specified unit
local mult = (unit == 0 or unit == "m/s") and 50 or ((unit == 1 or unit == "km/h") and 180 or 111.84681456)
-- Return the speed by calculating the length of the velocity vector, after converting the velocity to the specified unit
return (Vector3(getElementVelocity(theElement)) * mult).length
end