Skip to content
Open
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
# Offset finder for FiveM

supports Player offsets and Object offsets
Supports Player offsets and Object offsets

## Commands Available:

`findoffsets`

`findoffsets:object`
`offsets`

## Links

[Co-Authored by Zoo](https://github.com/Renewed-Scripts) - I am very much so brain dead so Zoo helped me get the offsets working correctly
[Reworked by xT](https://github.com/xT-Development)

[preview](https://streamable.com/my3fd6)
[preview](https://streamable.com/ereyap)

## Warning

Expand Down
258 changes: 93 additions & 165 deletions client/main.lua
Original file line number Diff line number Diff line change
@@ -1,206 +1,134 @@
local shellHandle = nil
local objectHandle = nil
local oldCoords = nil
local UTILS = lib.require('client.utils')

local controlsString = '[E] - Copy Offset \n [Q] - Remove Shell'
local testingShell = false
local inObjectPreview = false
local placedPreviews = {}

local function Notify(msg)
lib.notify({
title = 'Offset Finder',
description = msg,
type = 'success'
})
end

local function removePlaceholderObjects()
for i = 1, #placedPreviews do
local preview = placedPreviews[i]

if DoesEntityExist(preview) then
DeleteEntity(preview)
end
end
local tempObject, tempObjectModel, tempObjectSnapToGround, tempCoords

placedPreviews = {}
local function __resetControlsString()
controlsString = '[E] - Copy Offset \n [Q] - Remove Shell'
UTILS.showControls(controlsString)
end

local function RemoveShell()
if not shellHandle then
return
end

testingShell = false
lib.hideTextUI()
DeleteEntity(shellHandle)
shellHandle = nil

if objectHandle and DoesEntityExist(objectHandle) then
inObjectPreview = false
DeleteEntity(objectHandle)
objectHandle = nil
end

removePlaceholderObjects()

SetEntityCoordsNoOffset(cache.ped, oldCoords)
oldCoords = nil

Notify("Deleted shell")
end

RegisterNetEvent("qw-offset:client:testShell", function(shellName)
local shellModel = shellName and GetHashKey(shellName)

if not shellName then
return Notify(("No such shell \"%s\"."):format(shellName or ""))
elseif not IsModelInCdimage(shellModel) then
return Notify(("The shell \"%s\" is not in cd image, did you start the shell?"):format(shellName))
end

if DoesEntityExist(shellHandle) then
DeleteEntity(shellHandle)
shellHandle = nil
else
oldCoords = GetEntityCoords(cache.ped)
end
RegisterNetEvent("qw-offset:client:offsetFinder", function()
if GetInvokingResource() then return end

local input = lib.inputDialog('Shell Z Coord', {
{
type = 'number',
label = 'Z Coord Offset',
description = 'How High or Low to Spawn the Shell',
icon = 'hashtag',
required = true,
default = 0.0
},
})

if not input then
return
end

shellHandle = CreateObject(shellModel, oldCoords + vec3(0.0, 0.0, input[1]), true, true)
FreezeEntityPosition(shellHandle, true)
SetEntityHeading(shellHandle, 0.0)

SetEntityCoordsNoOffset(cache.ped, GetEntityCoords(shellHandle))

testingShell = true

lib.showTextUI('[E] - Copy Offset \n [Q] - Remove Shell', {
position = "left-center",
})

CreateThread(function()
while testingShell do
Wait(0)

if IsControlJustPressed(0, 44) then RemoveShell() end

if IsControlJustPressed(0, 38) then
if not shellHandle then
return
end

local coords = GetEntityCoords(PlayerPedId())

local coordsToCompare = inObjectPreview and GetEntityCoords(objectHandle) or coords

local offset = GetOffsetFromEntityGivenWorldCoords(shellHandle, coordsToCompare)

lib.setClipboard(('vec4(%f, %f, %f, %f)'):format(offset.x, offset.y, offset.z,
GetEntityHeading(inObjectPreview and objectHandle or cache.ped)))
Notify("Copied offset to clipboard.")
end
if not testingShell then
local selectedShell = UTILS.selectShell()
if not selectedShell then
return
end
end)
end)

RegisterNetEvent('qw-offset:client:objectOffsetMode', function()

if not testingShell then return end
if not inObjectPreview then
local createdShell = UTILS.createShell(selectedShell)
if not createdShell then
return
end

local input = lib.inputDialog('Object Model Preview', {
testingShell = true
else
local objectModel = lib.inputDialog('Object Model Preview', {
{
type = 'input',
label = 'Object Name',
required = true,
},
{
type = 'checkbox',
label = 'Snap To Ground?'
}
})

if not input then
if not objectModel or not objectModel[1] then
UTILS.notify('No object model provided', 'error')
return
end

local object = tostring(input[1])

local objectModel = object and GetHashKey(object)
tempObjectModel = objectModel[1]
tempObjectSnapToGround = objectModel[2]

if not IsModelInCdimage(objectModel) then
return Notify(("The object \"%s\" is not in cd image, are you sure this exists?"):format(objectModel))
if tempObject and DoesEntityExist(tempObject) then
DeleteEntity(tempObject)
end

controlsString = controlsString .. ' \n[L/R Arrow] Rotate Object \n[Z] Place Object \n[X] Cancel Object Offset Finder'

local coords = GetEntityCoords(cache.ped)

tempObject = UTILS.createObject(tempObjectModel, coords)

SetEntityAlpha(tempObject, 150, false)
SetEntityCollision(tempObject, false, false)

inObjectPreview = true
end

lib.requestModel(objectModel, 1000)
UTILS.showControls(controlsString)

CreateThread(function()
while testingShell do
Wait(0)

objectHandle = CreateObject(objectModel, GetEntityCoords(cache.ped), true, true, false)
-- press Q to remove shell
if IsControlJustPressed(0, 44) then
UTILS.removeShell()
testingShell = false
inObjectPreview = false
tempObjectModel = nil
tempObjectSnapToGround = nil
end

SetEntityAlpha(objectHandle, 150, false)
SetEntityCollision(objectHandle, false, false)
FreezeEntityPosition(objectHandle, true)
-- press E to copy offset off current object or current coords
if IsControlJustPressed(0, 38) then
local coords = GetEntityCoords(cache.ped)
local coordsToCompare = inObjectPreview and GetEntityCoords(tempObject) or coords
local heading = GetEntityHeading(inObjectPreview and tempObject or cache.ped)

lib.hideTextUI()
lib.showTextUI('[E] - Copy Offset \n [Q] - Remove Shell \n [L/R Arrow] Rotate Object', {
position = "left-center",
})
UTILS.copyOffset(coordsToCompare, heading)
end

CreateThread(function()
while inObjectPreview do
local hit, _, coords, _, _ = lib.raycast.cam(1, 4)
if inObjectPreview then
local hit, _, tempCoords, _, _ = lib.raycast.cam(1, 4)
if hit then
SetEntityCoords(objectHandle, coords.x, coords.y, coords.z)
PlaceObjectOnGroundProperly(objectHandle)
SetEntityCoords(tempObject, tempCoords.x, tempCoords.y, tempCoords.z, false, false, false, false)
if tempObjectSnapToGround then
PlaceObjectOnGroundProperly(tempObject)
end

-- left and right arrows for temp object heading changes
if IsControlPressed(0, 174) then
SetEntityHeading(objectHandle, GetEntityHeading(objectHandle) - 1.0)
SetEntityHeading(tempObject, GetEntityHeading(tempObject) - 1.0)
end

if IsControlPressed(0, 175) then
SetEntityHeading(objectHandle, GetEntityHeading(objectHandle) + 1.0)
SetEntityHeading(tempObject, GetEntityHeading(tempObject) + 1.0)
end
end

if IsControlJustPressed(0, 38) then
local placeholderObject = CreateObject(objectModel, coords.x, coords.y, coords.z, true, true, false)
SetEntityHeading(placeholderObject, GetEntityHeading(objectHandle))

PlaceObjectOnGroundProperly(placeholderObject)
SetEntityAlpha(placeholderObject, 150, false)
SetEntityCollision(placeholderObject, false, false)
FreezeEntityPosition(placeholderObject, true)
SetEntityDrawOutline(placeholderObject, true)
SetEntityDrawOutlineColor(0, 255, 0, 150)

if IsControlJustPressed(0, 73) then -- press X to cancel object offset finder
UTILS.removeObject(tempObject)
inObjectPreview = false
tempObjectModel = nil

placedPreviews[#placedPreviews+1] = placeholderObject
end
__resetControlsString()
end

Wait(0)
if IsControlJustPressed(0, 20) then -- press Z to create temp objects
local vec4Coords = vec4(tempCoords.x, tempCoords.y, tempCoords.z, GetEntityHeading(tempObject))

UTILS.removeObject(tempObject)
UTILS.createTempObject(tempObjectModel, vec4Coords)
inObjectPreview = false
tempObjectModel = nil

__resetControlsString()
end
end
end)
else
if objectHandle and DoesEntityExist(objectHandle) then
inObjectPreview = false
DeleteEntity(objectHandle)
objectHandle = nil
end

lib.hideTextUI()
lib.showTextUI('[E] - Copy Offset \n [Q] - Remove Shell', {
position = "left-center",
})
end
end)
end)

-- remove shell on stop
AddEventHandler('onResourceStop', function(resource)
if resource ~= GetCurrentResourceName() then return end

UTILS.removeShell()
end)
Loading