Files
Elite-Gaming-FiveM/resources/SmartHose/cl_utils.lua
T
2025-06-04 19:16:07 -07:00

398 lines
16 KiB
Lua

vRP = nil
ESX = nil
if ConfigHose.Notifications.Enabled and ConfigHose.Notifications.Framework.vRP then
local Tunnel = module("vrp", "lib/Tunnel")
local Proxy = module("vrp", "lib/Proxy")
vRP = Proxy.getInterface("vRP")
end
if ConfigHose.Notifications.Enabled and ConfigHose.Notifications.Framework.ESX then
ESX = exports["es_extended"]:getSharedObject()
end
if ConfigHose.EnablePositioningCommand then
TriggerEvent('chat:addSuggestion', '/'.."findhosepositioning", "Find positioning of the hose/supply line on your fire truck")
RegisterCommand("findhosepositioning", function(source, args)
local ped = PlayerPedId()
local targetVehicle = GetVehiclePedIsIn(ped, false)
if targetVehicle == nil or targetVehicle == 0 then
Notify("No vehicle found!")
else
local model = `p_ld_soc_ball_01`
SetEntityAlpha(targetVehicle, 150, false)
RequestModel(model)
while not HasModelLoaded(model) do Wait(0) end
local ballProp = CreateObject(model, coords, false, false, false)
while not DoesEntityExist(ballProp) do Wait(0) end
SetModelAsNoLongerNeeded(model)
local offSet = {0.0, 0.0, 0.0}
local rotation = {0.0, 0.0, 0.0}
local offSetComplete = false
while not offSetComplete do
if targetVehicle ~= nil and targetVehicle ~= 0 then
DetachEntity(ballProp, true, false)
AttachEntityToEntity(ballProp, targetVehicle, -1, offSet[1], offSet[2], offSet[3], rotation[1], rotation[2], rotation[3], true, false, true, false, 1, true)
if not IsControlReleased(0, 207) then --page down
offSet = {offSet[1], offSet[2], offSet[3] - 0.01}
end
if not IsControlReleased(0, 208) then --page up
offSet = {offSet[1], offSet[2], offSet[3] + 0.01}
end
if not IsControlReleased(0, 173) then --arrow down
offSet = {offSet[1], offSet[2] - 0.01, offSet[3]}
end
if not IsControlReleased(0, 172) then --arrow up
offSet = {offSet[1], offSet[2] + 0.01, offSet[3]}
end
if not IsControlReleased(0, 174) then --arrow left
offSet = {offSet[1] - 0.01, offSet[2], offSet[3]}
end
if not IsControlReleased(0, 175) then --arrow right
offSet = {offSet[1] + 0.01, offSet[2], offSet[3]}
end
if IsControlJustPressed(0, 191) then -- enter - finish
offSetComplete = true
end
end
Wait(0)
end
Notify("OffSet Values are now printed in your console")
print("OffSet: {"..offSet[1]..", "..offSet[2]..", "..offSet[3].."}")
DeleteEntity(ballProp)
ResetEntityAlpha(targetVehicle)
end
end, false)
end
function Notify(text)
if not ConfigHose.Notifications.Enabled then
return
end
if ConfigHose.Notifications.Framework.ESX then
if ESX ~= nil then
ESX.ShowNotification(text)
end
elseif ConfigHose.Notifications.Framework.QBCore then
TriggerEvent('QBCore:Notify', text, 'primary')
elseif ConfigHose.Notifications.Framework.QBX then
exports.qbx_core:Notify(text, 'primary')
elseif ConfigHose.Notifications.Framework.vRP then
vRP.notify(source, {text})
elseif ConfigHose.Notifications.Framework.okok then
exports['okokNotify']:Alert("Smart Hose", text, 2000, 'info', true)
else
showBaseNotification(text)
end
end
function showBaseNotification(message)
-- Base game notifications
SetNotificationTextEntry("STRING")
AddTextComponentString(message)
DrawNotification(0,1)
end
-- General Functions @GeneralFunctions
function DisplayHelpText(text)
SetTextComponentFormat("STRING")
AddTextComponentString(text)
DisplayHelpTextFromStringLabel(0, 0, ConfigHose.Notifications.HelpTextSound, -1)
end
function drawInstructionalText(msg, coords)
AddTextEntry('instructionalText', msg)
SetFloatingHelpTextWorldPosition(1, coords)
SetFloatingHelpTextStyle(1, 1, 2, -1, 3, 0)
BeginTextCommandDisplayHelp('instructionalText')
AddTextComponentSubstringPlayerName(msg)
EndTextCommandDisplayHelp(2, false, false, -1)
end
function IsFireHoseEnabled()
return (HoseManager.nozzle and not HoseManager.nozzleDropped)
end
exports("IsFireHoseEnabled", IsFireHoseEnabled)
function IsFireHoseShooting()
return HoseManager.pressed
end
exports("IsFireHoseShooting", IsFireHoseShooting)
function IsFireHoseShootingWater()
return ParticleManager.isWaterDecal
end
exports("IsFireHoseShootingWater", IsFireHoseShootingWater)
function GetCurrentDecalCoords()
return ParticleManager.CurrentDecalCoords
end
exports("GetCurrentDecalCoords", GetCurrentDecalCoords)
function GetCurrentHosePressure()
return ParticleManager.particleScale
end
exports("GetCurrentHosePressure", GetCurrentHosePressure)
local vehicleModels = getVehicleModelsFromCapacities()
local interactionId = "menuId"
if ConfigHose.InteractType.TruckInteraction.Drawtext or ConfigHose.InteractType.TruckInteraction.ScreenPrompt then
CreateThread(function()
while true do
Wait(1)
local pos = GetEntityCoords(PlayerPedId())
local vehicle = GetClosestVehicle(pos)
local inRange = false
if vehicle and DoesEntityExist(vehicle) and IsVehicleDriveable(vehicle, false) then
local vehicleModel = GetEntityModel(vehicle)
local vehicleSettings = ConfigHose.Rope.VehicleSettings[vehicleModel] or {}
local useBone = vehicleSettings.useBone or false
local bones = vehicleSettings.bones or {}
local offsets = vehicleSettings.offsets or {{x = 0.0, y = 0.0, z = 0.0}}
local attachmentPoints = {}
if useBone then
for _, boneName in ipairs(bones) do
local boneIndex = GetEntityBoneIndexByName(vehicle, boneName)
if boneIndex ~= -1 then
local bonePos = GetWorldPositionOfEntityBone(vehicle, boneIndex)
table.insert(attachmentPoints, bonePos)
else
print("Bone " .. boneName .. " not found in vehicle model.")
end
end
else
for _, offset in ipairs(offsets) do
local offsetWorldPos = GetOffsetFromEntityInWorldCoords(vehicle, offset.x, offset.y, offset.z)
table.insert(attachmentPoints, offsetWorldPos)
end
end
local closestPoint = attachmentPoints[1]
local minDistance = #(pos - closestPoint)
for _, point in ipairs(attachmentPoints) do
local distance = #(pos - point)
if distance < minDistance then
closestPoint = point
minDistance = distance
end
end
local promptCoords = closestPoint
local vehicleDistance = #(pos - promptCoords)
if not IsPedInAnyVehicle(PlayerPedId(), false) and vehicleDistance < 3.0 then
inRange = true
local text = HoseManager.nozzle and ConfigHose.Translations.storeHoseMessage or ConfigHose.Translations.grabHoseMessage
if ConfigHose.InteractType.TruckInteraction.Drawtext then
drawInstructionalText(text, promptCoords)
elseif ConfigHose.InteractType.TruckInteraction.ScreenPrompt then
DisplayHelpText(text)
end
if IsControlJustReleased(0, ConfigHose.Keys.Interact) then
if not HoseManager.nozzle and isPermissionAllowed() then
InitializeFireHose()
AttachRopeToProp()
else
UnequipFireHose()
end
end
end
end
if not inRange then
Wait(2500)
end
end
end)
elseif ConfigHose.InteractType.TruckInteraction.ThirdEye.enabled then
if ConfigHose.InteractType.TruckInteraction.ThirdEye.oxTarget then
local VehicleOptions = {
{
label = ConfigHose.Translations.thirdEyeMessage,
icon = "fa-solid fa-water",
onSelect = function()
if not HoseManager.nozzle and isPermissionAllowed() then
InitializeFireHose()
AttachRopeToProp()
else
UnequipFireHose()
end
end,
}
}
exports.ox_target:addModel(vehicleModels, VehicleOptions)
end
if ConfigHose.InteractType.TruckInteraction.ThirdEye.qbTarget then
exports['qb-target']:AddTargetModel(vehicleModels, {
options = {
{
label = ConfigHose.Translations.thirdEyeMessage,
icon = "fa-solid fa-water",
action = function()
if not HoseManager.nozzle and isPermissionAllowed() then
InitializeFireHose()
AttachRopeToProp()
else
UnequipFireHose()
end
end,
},
},
distance = 3.0
})
end
elseif ConfigHose.InteractType.TruckInteraction.WorldInteraction then
CreateThread(function()
local interactionActive = false
local idleWait = 1000
while true do
Wait(idleWait)
if IsPedInAnyVehicle(PlayerPedId(), false) then
if interactionActive then
for _, model in ipairs(vehicleModels) do
exports.interact:RemoveModelInteraction(model, interactionId)
end
interactionActive = false
end
idleWait = 1500
else
local pos = GetEntityCoords(PlayerPedId())
local vehicle = GetClosestVehicle(pos)
if vehicle and DoesEntityExist(vehicle) then
local vehicleModel = GetEntityModel(vehicle)
local isAllowedModel = false
for _, model in ipairs(vehicleModels) do
if model == vehicleModel then
isAllowedModel = true
break
end
end
if isAllowedModel then
local vehicleSettings = ConfigHose.Rope.VehicleSettings[vehicleModel] or {}
local useBone = vehicleSettings.useBone or false
local bones = vehicleSettings.bones or {}
local offsets = vehicleSettings.offsets or {{x = 0.0, y = 0.0, z = 0.0}}
local attachmentPoints = {}
if useBone then
for _, boneName in ipairs(bones) do
local boneIndex = GetEntityBoneIndexByName(vehicle, boneName)
if boneIndex ~= -1 then
local bonePos = GetWorldPositionOfEntityBone(vehicle, boneIndex)
table.insert(attachmentPoints, bonePos)
else
print("Bone " .. boneName .. " not found in vehicle model.")
end
end
else
for _, offset in ipairs(offsets) do
local offsetWorldPos = GetOffsetFromEntityInWorldCoords(vehicle, offset.x, offset.y, offset.z)
table.insert(attachmentPoints, offsetWorldPos)
end
end
local closestPoint = attachmentPoints[1]
local minDistance = #(pos - closestPoint)
for _, point in ipairs(attachmentPoints) do
local distance = #(pos - point)
if distance < minDistance then
closestPoint = point
minDistance = distance
end
end
local promptCoords = closestPoint
local vehicleDistance = #(pos - promptCoords)
if vehicleDistance < 4.0 then
if not interactionActive then
exports.interact:AddModelInteraction({
model = vehicleModel,
offset = promptCoords - GetEntityCoords(vehicle),
name = 'Menu',
id = interactionId,
distance = 8.0,
interactDst = 2.5,
ignoreLos = true,
bone = 'bodyshell',
options = {
{
label = ConfigHose.Translations.grabHoseWorldInteraction,
action = function()
if not HoseManager.nozzle then
InitializeFireHose()
AttachRopeToProp()
else
UnequipFireHose()
end
end,
},
}
})
interactionActive = true
end
idleWait = 0
else
if interactionActive then
exports.interact:RemoveModelInteraction(vehicleModel, interactionId)
interactionActive = false
end
idleWait = 500
end
else
if interactionActive then
exports.interact:RemoveModelInteraction(vehicleModel, interactionId)
interactionActive = false
end
idleWait = 1000
end
else
if interactionActive then
for _, model in ipairs(vehicleModels) do
exports.interact:RemoveModelInteraction(model, interactionId)
end
interactionActive = false
end
idleWait = 1500
end
end
end
end)
else
warn('Invalid interaction configuration')
end