Server:
g_Root = getRootElement()
ACCURACY = 200 --200ms
POS_UPDATE = 2500 --2500ms
playTimer = nil
tmpPosUpdCount = 1
pRecordingInfo = {}
playbackSettings = { gPed = nil, gVeh = nil, vehModel = nil, lastTick = nil }
addEvent("preparePlaybackForStart", true)
addEventHandler("preparePlaybackForStart", g_Root,
function(info)
pRecordingInfo = info
playbackSettings.gPed = createPed(264, pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ)
playbackSettings.gVeh = createVehicle(pRecordingInfo.vehModel, pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ, pRecordingInfo.startRotX, pRecordingInfo.startRotY, pRecordingInfo.startRotZ)
warpPedIntoVehicle(playbackSettings.gPed, playbackSettings.gVeh)
createBlipAttachedTo(playbackSettings.gVeh, 0, 2.5, 255, 255, 0, 200)
outputDebugString("[starting playback..]")
playTimer = setTimer(startGhostPlayback, ACCURACY, 0)
end
)
function startGhostPlayback()
if pRecordingInfo.pKey[tmpPosUpdCount] then
triggerClientEvent("setControlState", g_Root, playbackSettings.gPed, pRecordingInfo.pKey[tmpPosUpdCount], pRecordingInfo.pKeyState[tmpPosUpdCount])
if not playbackSettings.lastTick then
playbackSettings.lastTick = getTickCount()
end
if getTickCount() - playbackSettings.lastTick > POS_UPDATE then
setElementPosition(playbackSettings.gVeh, pRecordingInfo.posUpdX[tmpPosUpdCount], pRecordingInfo.posUpdY[tmpPosUpdCount], pRecordingInfo.posUpdZ[tmpPosUpdCount])
setElementRotation(playbackSettings.gVeh, pRecordingInfo.posUpdRotX[tmpPosUpdCount], pRecordingInfo.posUpdRotY[tmpPosUpdCount], pRecordingInfo.posUpdRotZ[tmpPosUpdCount])
setElementVelocity(playbackSettings.gVeh, pRecordingInfo.posUpdVelX[tmpPosUpdCount], pRecordingInfo.posUpdVelY[tmpPosUpdCount], pRecordingInfo.posUpdVelZ[tmpPosUpdCount])
setElementHealth(playbackSettings.gVeh, pRecordingInfo.vehHealth[tmpPosUpdCount])
playbackSettings.lastTick = getTickCount()
end
tmpPosUpdCount = tmpPosUpdCount + 1
else
killTimer(playTimer)
tmpPosUpdCount = 1
pRecordingInfo = {}
destroyElement(playbackSettings.gPed)
destroyElement(playbackSettings.gVeh)
outputChatBox"Finished!"
end
end
Client:
g_Root = getRootElement()
g_Me = getLocalPlayer()
keysTimer = nil
ACCURACY = 200 --200ms
POS_UPDATE = 2500 --2500ms
lastKeysChecked = {}
keysState = {}
posTickUpd = nil
keyNames = { "special_control_up", "special_control_down", "special_control_right", "special_control_left", "vehicle_look_right", "vehicle_look_left",
"handbrake", "sub_mission", "horn", "brake_reverse", "accelerate", "steer_back", "steer_forward", "vehicle_right",
"vehicle_left", "vehicle_secondary_fire", "vehicle_fire" } -- 17
local pRecordingInfo =
{
startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {}, vehHealth = {},
posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {}
}
addEvent("startRecording", true)
addEvent("setControlState", true)
addEventHandler("startRecording", g_Root,
function()
--resetRecordInfo()
pRecordingInfo.pVeh = getPedOccupiedVehicle(g_Me)
pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ = getElementPosition(pRecordingInfo.pVeh)
pRecordingInfo.startRotX, pRecordingInfo.startRotY, pRecordingInfo.startRotZ = getElementRotation(pRecordingInfo.pVeh)
pRecordingInfo.vehModel = getElementModel(pRecordingInfo.pVeh)
keysTimer = setTimer(recordKeys, ACCURACY, 0)
outputDebugString("[Recording started]")
end
)
addEventHandler("setControlState", g_Root,
function(ped, key, state)
if key == "continue" or state == "continue" or key == "nothing" or state == "nothing" then
else
setPedControlState(ped, key, state)
end
end
)
addEventHandler("onClientPlayerWasted", g_Root,
function()
resetRecordInfo()
outputDebugString("[Recording stopped]")
end
)
function recordKeys()
local veh = getPedOccupiedVehicle(g_Me)
if veh then
-- Got the hunter
if getElementModel(veh) == 425 then
if isTimer(keysTimer) then
killTimer(keysTimer)
end
posTickUpd = nil
lastKeysChecked = {}
outputDebugString("[Recording finished]")
return
end
-- Record the keys
for i, k in ipairs(keyNames) do
local state = getControlState(k)
if state then
if not lastKeysChecked[k] then
table.insert(pRecordingInfo.pKey, k)
table.insert(pRecordingInfo.pKeyState, state)
lastKeysChecked[k] = true
outputDebugString("getControlState key: " ..k.. " state: true")
keysState[i] = nil
else
table.insert(pRecordingInfo.pKey, "continue")
table.insert(pRecordingInfo.pKeyState, "continue")
outputDebugString("getControlState key: " ..k.. " state: continue")
end
else
if not state then
if lastKeysChecked[k] then
table.insert(pRecordingInfo.pKey, k)
table.insert(pRecordingInfo.pKeyState, false)
outputDebugString("getControlState key: " ..k.. " state: false")
lastKeysChecked[k] = false
else
keysState[i] = true
end
end
end
end
if getPressedKeys() == 17 then
table.insert(pRecordingInfo.pKey, "nothing")
table.insert(pRecordingInfo.pKeyState, "nothing")
outputDebugString("getControlState key: nothing state: nothing")
end
-- Position update
if not posTickUpd then
posTickUpd = getTickCount()
end
if getTickCount() - posTickUpd > POS_UPDATE then
local tmpX, tmpY, tmpZ = getElementPosition(veh)
table.insert(pRecordingInfo.posUpdX, tmpX)
table.insert(pRecordingInfo.posUpdY, tmpY)
table.insert(pRecordingInfo.posUpdZ, tmpZ)
tmpX, tmpY, tmpZ = getElementRotation(veh)
table.insert(pRecordingInfo.posUpdRotX, tmpX)
table.insert(pRecordingInfo.posUpdRotY, tmpY)
table.insert(pRecordingInfo.posUpdRotZ, tmpZ)
tmpX, tmpY, tmpZ = getElementVelocity(veh)
table.insert(pRecordingInfo.posUpdVelX, tmpX)
table.insert(pRecordingInfo.posUpdVelY, tmpY)
table.insert(pRecordingInfo.posUpdVelZ, tmpZ)
table.insert(pRecordingInfo.vehHealth, getElementHealth(veh))
posTickUpd = getTickCount()
outputDebugString("[Pos update]")
end
else
--resetRecordInfo()
outputDebugString("[Error while recording, aborting..]", 0, 255, 0, 0)
end
end
function resetRecordInfo()
if isTimer(keysTimer) then
killTimer(keysTimer)
end
pRecordingInfo = { startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {},
posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {}, vehHealth = {} }
posTickUpd = nil
lastKeysChecked = {}
end
function getPressedKeys()
local count = 0
for i = 1, #keysState do
if keysState[i] then
count = count + 1
end
end
return count
end
addCommandHandler("asd",
function()
triggerServerEvent("preparePlaybackForStart", g_Root, pRecordingInfo)
end
)
addCommandHandler("data",
function()
local cc = 1
local second = 2500
setTimer(
function()
outputChatBox("Second " ..second.. " X: " ..pRecordingInfo.posUpdX[cc].. "Y: " ..pRecordingInfo.posUpdY[cc].. "Z: " ..pRecordingInfo.posUpdZ[cc])
second = second + 2500
cc = cc + 1
end
, 2500, 0)
end
)