require 'lib.moonloader'
require 'lib.sampfuncs'
local se = require 'lib.samp.events'
local teleport = false
local teleport_cpm = false
function main()
while not isSampAvailable() do wait(100) end
sampRegisterChatCommand('_tp', function(arg)
if arg == 'cpm' then
teleport_cpm = true
elseif arg == '' then
teleport = true
end
end)
while true do
wait(0)
if teleport_cpm then
if isCharOnFoot(PLAYER_PED) then
onfoot_cpm()
else
incar_cpm()
end
elseif teleport then
if isCharOnFoot(PLAYER_PED) then
onfoot()
else
incar()
end
end
end
end
function onfoot()
local _, x, y, z = getTargetBlipCoordinatesFixed()
if _ then
lua_thread.create(function()
wait(500)
setCharCoordinates(PLAYER_PED, x, y, z)
local data = samp_create_sync_data('spectator')
data.position = { x, y, z }
data.send()
wait(500)
teleport = false
printStringNow('~r~finished', 2000)
end)
else
printStringNow('~y~blip not found', 2000)
end
end
function incar()
local _, x, y, z = getTargetBlipCoordinatesFixed()
if _ then
lua_thread.create(function()
wait(500)
sampForceOnfootSync()
wait(500)
setCharCoordinates(PLAYER_PED, x, y, z)
wait(500)
teleport = false
printStringNow('~r~finished', 2000)
end)
else
printStringNow('~y~blip not found', 2000)
end
end
function onfoot_cpm()
local px, py, pz = getCharCoordinates(PLAYER_PED)
local _, x, y, z = SearchMarker(px, py, pz, 10000, true)
if _ then
if isCharOnFoot(PLAYER_PED) then
lua_thread.create(function()
wait(500)
setCharCoordinates(PLAYER_PED, x, y, z)
local data = samp_create_sync_data('spectator')
data.position = { x, y, z }
data.send()
wait(500)
teleport_cpm = false
printStringNow('~r~finished', 2000)
end)
end
else
printStringNow('~y~checkpoint not found', 2000)
end
end
function incar_cpm()
local px, py, pz = getCharCoordinates(PLAYER_PED)
local _, x, y, z = SearchMarker(px, py, pz, 10000, true)
lua_thread.create(function()
wait(500)
sampForceOnfootSync()
wait(500)
setCharCoordinates(PLAYER_PED, x, y, z)
wait(500)
teleport_cpm = false
printStringNow('~r~finished', 2000)
end)
end
function se.onSendVehicleSync(data)
if teleport or teleport_cpm then return false end
end
function se.onSendPlayerSync(data)
if teleport or teleport_cpm then return false end
end
function se.onSetPlayerPos(p)
if teleport or teleport_cpm then return false end
end
function se.onSetVehiclePosition(p)
if teleport or teleport_cpm then return false end
end
function getTargetBlipCoordinatesFixed()
local blip, x, y, z = getTargetBlipCoordinates();
if not blip then return false end
requestCollision(x, y)
loadScene(x, y, z)
local blip, x, y, z = getTargetBlipCoordinates()
return blip, x, y, z
end
function SearchMarker(posX, posY, posZ, radius, isRace)
local ret_posX = 0.0
local ret_posY = 0.0
local ret_posZ = 0.0
local isFind = false
for id = 0, 31 do
local MarkerStruct = 0
if isRace then MarkerStruct = 0xC7F168 + id * 56
else MarkerStruct = 0xC7DD88 + id * 160 end
local MarkerPosX = representIntAsFloat(readMemory(MarkerStruct + 0, 4, false))
local MarkerPosY = representIntAsFloat(readMemory(MarkerStruct + 4, 4, false))
local MarkerPosZ = representIntAsFloat(readMemory(MarkerStruct + 8, 4, false))
if MarkerPosX ~= 0.0 or MarkerPosY ~= 0.0 or MarkerPosZ ~= 0.0 then
if getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ, posX, posY, posZ) < radius then
ret_posX = MarkerPosX
ret_posY = MarkerPosY
ret_posZ = MarkerPosZ
isFind = true
radius = getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ, posX, posY, posZ)
end
end
end
return isFind, ret_posX, ret_posY, ret_posZ
end
function samp_create_sync_data(sync_type, copy_from_player)
local ffi = require 'ffi'
local sampfuncs = require 'sampfuncs'
local raknet = require 'samp.raknet'
copy_from_player = copy_from_player or true
local sync_traits = {
player = {"PlayerSyncData", raknet.PACKET.PLAYER_SYNC, sampStorePlayerOnfootData},
vehicle = {"VehicleSyncData", raknet.PACKET.VEHICLE_SYNC, sampStorePlayerIncarData},
passenger = {"PassengerSyncData", raknet.PACKET.PASSENGER_SYNC, sampStorePlayerPassengerData},
aim = {"AimSyncData", raknet.PACKET.AIM_SYNC, sampStorePlayerAimData},
trailer = {"TrailerSyncData", raknet.PACKET.TRAILER_SYNC, sampStorePlayerTrailerData},
unoccupied = {"UnoccupiedSyncData", raknet.PACKET.UNOCCUPIED_SYNC, nil},
bullet = {"BulletSyncData", raknet.PACKET.BULLET_SYNC, nil},
spectator = {"SpectatorSyncData", raknet.PACKET.SPECTATOR_SYNC, nil}
}
local sync_info = sync_traits[sync_type]
local data_type = 'struct ' .. sync_info[1]
local data = ffi.new(data_type, {})
local raw_data_ptr = tonumber(ffi.cast("uintptr_t", ffi.new(data_type .. "*", data)))
if copy_from_player then
local copy_func = sync_info[3]
if copy_func then
local _, player_id
if copy_from_player == true then
_, player_id = sampGetPlayerIdByCharHandle(playerPed)
else
player_id = tonumber(copy_from_player)
end
copy_func(player_id, raw_data_ptr)
end
end
local func_send = function()
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, sync_info[2])
raknetBitStreamWriteBuffer(bs, raw_data_ptr, ffi.sizeof(data))
raknetSendBitStreamEx(bs, sampfuncs.HIGH_PRIORITY, sampfuncs.UNRELIABLE_SEQUENCED, 1)
raknetDeleteBitStream(bs)
end
local mt = {
__index = function(t, index)
return data[index]
end,
__newindex = function(t, index, value)
data[index] = value
end
}
return setmetatable({send = func_send}, mt)
end