forked from Simnation/Main
354 lines
15 KiB
Lua
354 lines
15 KiB
Lua
![]() |
local ESX = nil
|
||
|
local QBCore = nil
|
||
|
local PlayerData = nil
|
||
|
if GetResourceState('es_extended') == 'started' then
|
||
|
ESX = exports['es_extended']:getSharedObject()
|
||
|
PlayerData = ESX.GetPlayerData()
|
||
|
|
||
|
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
|
||
|
PlayerData = xPlayer
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('esx:setJob', function(job)
|
||
|
PlayerData.job = job
|
||
|
end)
|
||
|
elseif GetResourceState('qb-core') == 'started' then
|
||
|
QBCore = exports['qb-core']:GetCoreObject()
|
||
|
PlayerData = QBCore.Functions.GetPlayerData()
|
||
|
|
||
|
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||
|
PlayerData = QBCore.Functions.GetPlayerData()
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(job)
|
||
|
PlayerData.job = job
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
Functions = {}
|
||
|
|
||
|
-- This function should return the player's job, adjust to your framework if required
|
||
|
Functions.GetPlayerJob = function()
|
||
|
if (GetResourceState('es_extended') == 'started' and PlayerData) then
|
||
|
return PlayerData.job.name
|
||
|
elseif (GetResourceState('qb-core') == 'started' and PlayerData) then
|
||
|
return PlayerData.job.name
|
||
|
end
|
||
|
|
||
|
return 'unemployed'
|
||
|
end
|
||
|
|
||
|
-- A general notification, you can use your own notification system here as well
|
||
|
Functions.Notify = function(message)
|
||
|
if (message == nil or message == '') then return end
|
||
|
BeginTextCommandThefeedPost('STRING')
|
||
|
AddTextComponentSubstringPlayerName(message)
|
||
|
EndTextCommandThefeedPostTicker(false, true)
|
||
|
end
|
||
|
|
||
|
-- This function should return wether the player is dead or not, adjust to your death-system
|
||
|
Functions.IsPlayerDead = function()
|
||
|
-- If wasabi_ambulance is used, this will handle the death check
|
||
|
if GetResourceState('wasabi_ambulance') == 'started' then
|
||
|
return exports.wasabi_ambulance:isPlayerDead()
|
||
|
end
|
||
|
|
||
|
local ped = PlayerPedId()
|
||
|
if (IsPedDeadOrDying(ped, true)) then
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
-- This function should return if the player can interact with third-eye or not, adjust to your needs
|
||
|
Functions.CanInteract = function()
|
||
|
local ped = PlayerPedId()
|
||
|
local isPedInVehicle = IsPedInAnyVehicle(ped, false)
|
||
|
local isPedDead = Functions.IsPlayerDead()
|
||
|
|
||
|
if (isPedInVehicle or isPedDead) then
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
-- This function should return if the vehicle can be interacted with or not, adjust to your needs
|
||
|
Functions.CanInteractWithVehicle = function(entity)
|
||
|
-- Check if the trunk of the vehicle is open
|
||
|
if GetVehicleDoorAngleRatio(entity, 5) > 0 then
|
||
|
return true
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
-- This function adds the required target-option to vehicles, ox-target and qb-target are supported by default but you can add your own target-option if you want to use another target-system
|
||
|
Functions.AddGlobalTargetOptions = function()
|
||
|
-- For the people ussing ox-target
|
||
|
if (GetResourceState('ox_target') == 'started') then
|
||
|
exports.ox_target:addGlobalVehicle({
|
||
|
{
|
||
|
icon = 'fas fa-expand',
|
||
|
label = Config.Target.Trunk.Label,
|
||
|
distance = Config.Target.Trunk.InteractDistance,
|
||
|
groups = Config.Target.Trunk.GlobalJobRequirement.Enabled and Config.Target.Trunk.GlobalJobRequirement.Names or nil,
|
||
|
bones = { 'boot' },
|
||
|
onSelect = function(data)
|
||
|
ViewVehicleTrunk(data.entity)
|
||
|
end,
|
||
|
canInteract = function(entity)
|
||
|
return (Functions.CanInteract() and Functions.CanInteractWithVehicle(entity) and Entity(entity).state.TrunkPropsFromState ~= nil and not isCarryingProp)
|
||
|
end
|
||
|
},
|
||
|
})
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- For the people using qb-target
|
||
|
if (GetResourceState('qb-target') == 'started') then
|
||
|
exports['qb-target']:AddTargetBone('boot', {
|
||
|
options = {
|
||
|
{
|
||
|
icon = 'fas fa-expand',
|
||
|
label = Config.Target.Trunk.Label,
|
||
|
job = Config.Target.Trunk.GlobalJobRequirement.Enabled and Config.Target.Trunk.GlobalJobRequirement.Names or nil,
|
||
|
action = function(entity)
|
||
|
ViewVehicleTrunk(entity)
|
||
|
end,
|
||
|
canInteract = function(entity)
|
||
|
return (Functions.CanInteract() and Functions.CanInteractWithVehicle(entity) and Entity(entity).state.TrunkPropsFromState ~= nil and not isCarryingProp)
|
||
|
end,
|
||
|
},
|
||
|
},
|
||
|
distance = Config.Target.Trunk.InteractDistance,
|
||
|
})
|
||
|
return
|
||
|
end
|
||
|
|
||
|
print('gs_advancedtrunk: [ERROR] No target interaction defined')
|
||
|
end
|
||
|
|
||
|
---
|
||
|
--- All Trunk related bridge functions are defined next
|
||
|
---
|
||
|
|
||
|
-- Add any additional code here that you want to run when the trunk is opened
|
||
|
Functions.OnTrunkOpen = function(vehicle)
|
||
|
-- Removes the radar from the player UI
|
||
|
DisplayRadar(false)
|
||
|
|
||
|
-- Disable targeting when the trunk is open
|
||
|
if (GetResourceState('ox_target') == 'started') then
|
||
|
exports.ox_target:disableTargeting(true)
|
||
|
elseif (GetResourceState('qb-target') == 'started') then
|
||
|
exports['qb-target']:AllowTargeting(false)
|
||
|
end
|
||
|
|
||
|
-- Some help-text is displayed with this export if ox_lib is used
|
||
|
if (GetResourceState('ox_lib') == 'started' and Config.UseKeyboardForSelection) then
|
||
|
exports.ox_lib:showTextUI('[A/D] Move selection - [ENTER] Confirm - [BACKSPACE] Cancel', {
|
||
|
position = "bottom-center",
|
||
|
icon = 'fas fa-up-down-left-right',
|
||
|
style = {
|
||
|
color = 'white'
|
||
|
}
|
||
|
})
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Add any additional code here that you want to run when the trunk is closed
|
||
|
Functions.OnTrunkClose = function(vehicle)
|
||
|
-- Adds back the radar from the player UI
|
||
|
DisplayRadar(true)
|
||
|
|
||
|
-- Enable targeting when the trunk is closed
|
||
|
if (GetResourceState('ox_target') == 'started') then
|
||
|
exports.ox_target:disableTargeting(false)
|
||
|
elseif (GetResourceState('qb-target') == 'started') then
|
||
|
exports['qb-target']:AllowTargeting(true)
|
||
|
end
|
||
|
|
||
|
-- Hides the help-text if ox_lib is used
|
||
|
if (GetResourceState('ox_lib') == 'started' and Config.UseKeyboardForSelection) then
|
||
|
exports.ox_lib:hideTextUI()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- This code runs every frame when the trunk is open, adjust to your needs
|
||
|
Functions.OnTrunkTick = function(vehicle)
|
||
|
-- Disable controls to prevent the player from moving
|
||
|
DisableControlAction(0, 22, true) -- SPACE (Jump)
|
||
|
DisableControlAction(0, 23, true) -- F (Enter vehicle)
|
||
|
DisableControlAction(0, 24, true) -- LMB (Attack)
|
||
|
DisableControlAction(0, 30, true) -- D (INPUT_MOVE_LR)
|
||
|
DisableControlAction(0, 31, true) -- S (INPUT_MOVE_UD)
|
||
|
DisableControlAction(0, 36, true) -- L-CTRL (Duck)
|
||
|
DisableControlAction(0, 44, true) -- Q (Cover)
|
||
|
DisableControlAction(0, 140, true) -- R (INPUT_MELEE_ATTACK_LIGHT)
|
||
|
end
|
||
|
|
||
|
-- This function should return if the trunk should close or not (for instance if the player dies), adjust to your needs
|
||
|
Functions.ShouldTrunkClose = function(vehicle)
|
||
|
-- Check if the trunk is closed
|
||
|
if GetVehicleDoorAngleRatio(vehicle, 5) == 0 then
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
-- Check if the player is dead
|
||
|
local isPedDead = Functions.IsPlayerDead()
|
||
|
if isPedDead then return true end
|
||
|
|
||
|
-- Check if the vehicle is to far away from the player
|
||
|
local ped = PlayerPedId()
|
||
|
local pedCoords = GetEntityCoords(ped)
|
||
|
local vehicleCoords = GetEntityCoords(vehicle)
|
||
|
local distance = #(pedCoords - vehicleCoords)
|
||
|
if (distance > Config.Target.Trunk.InteractDistance + 3.0) then
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
---
|
||
|
--- All Prop walking related bridge functions are defined next
|
||
|
---
|
||
|
|
||
|
-- This function is triggered right before someone starts walking with a prop
|
||
|
Functions.OnWalkWithProp = function(prop, canPlaceProp)
|
||
|
-- Some help-text is displayed with this export if ox_lib is used
|
||
|
if (GetResourceState('ox_lib') == 'started') then
|
||
|
local text = canPlaceProp and '[ENTER] Place - [BACKSPACE] Cancel' or '[BACKSPACE] Cancel'
|
||
|
exports.ox_lib:showTextUI(text, {
|
||
|
position = "bottom-center",
|
||
|
icon = 'fas fa-up-down-left-right',
|
||
|
style = {
|
||
|
color = 'white'
|
||
|
}
|
||
|
})
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- This function is triggered right after someone stops walking with a prop
|
||
|
Functions.OnStopWalkWithProp = function(prop)
|
||
|
-- Hides the help-text if ox_lib is used
|
||
|
if (GetResourceState('ox_lib') == 'started') then
|
||
|
exports.ox_lib:hideTextUI()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- This code runs every frame when the player is walking with a prop, adjust to your needs
|
||
|
Functions.OnWalkWithPropTick = function(prop)
|
||
|
-- Disable certain controls
|
||
|
DisableControlAction(0, 22, true) -- SPACE (Jump)
|
||
|
DisableControlAction(0, 23, true) -- F (Enter vehicle)
|
||
|
DisableControlAction(0, 24, true) -- LMB (Attack)
|
||
|
DisableControlAction(0, 36, true) -- L-CTRL (Duck)
|
||
|
DisableControlAction(0, 44, true) -- Q (Cover)
|
||
|
DisableControlAction(0, 140, true) -- R (INPUT_MELEE_ATTACK_LIGHT)
|
||
|
end
|
||
|
|
||
|
-- This function adds the required target-option to remove a placed object, ox-target and qb-target are supported by default but you can add your own target-option if you want to use another target-system
|
||
|
Functions.AddObjectTargets = function(prop, propName)
|
||
|
-- For the people ussing ox-target
|
||
|
if (GetResourceState('ox_target') == 'started') then
|
||
|
local options = {
|
||
|
{
|
||
|
icon = 'fas fa-trash-can',
|
||
|
label = Config.Target.Object.LabelRemove,
|
||
|
distance = Config.Target.Object.InteractDistance,
|
||
|
groups = RequiredJobsToPickupOrRemove or nil,
|
||
|
onSelect = function(data)
|
||
|
PlayAnimation(Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, Config.WalkWithProp[propName].PickupAnimFlag, Config.WalkWithProp[propName].PickupAnimTime)
|
||
|
while IsEntityPlayingAnim(PlayerPedId(), Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, 3) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
if (not DoesEntityExist(data.entity)) then return end
|
||
|
local propNetId = NetworkGetNetworkIdFromEntity(data.entity)
|
||
|
TriggerServerEvent('gs_advancedtrunk:RemoveProp', propNetId)
|
||
|
end,
|
||
|
canInteract = function(entity)
|
||
|
return (Functions.CanInteract() and not isCarryingProp)
|
||
|
end
|
||
|
},
|
||
|
}
|
||
|
|
||
|
if Config.WalkWithProp[propName].CanPickUp then
|
||
|
table.insert(options, {
|
||
|
icon = 'fas fa-hand-spock',
|
||
|
label = Config.Target.Object.LabelPickup,
|
||
|
distance = Config.Target.Object.InteractDistance,
|
||
|
groups = RequiredJobsToPickupOrRemove or nil,
|
||
|
onSelect = function(data)
|
||
|
PlayAnimation(Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, Config.WalkWithProp[propName].PickupAnimFlag, Config.WalkWithProp[propName].PickupAnimTime)
|
||
|
while IsEntityPlayingAnim(PlayerPedId(), Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, 3) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
if (not DoesEntityExist(data.entity)) then return end
|
||
|
local propNetId = NetworkGetNetworkIdFromEntity(data.entity)
|
||
|
TriggerServerEvent('gs_advancedtrunk:RemoveProp', propNetId)
|
||
|
Actions.WalkWithProp(propName)
|
||
|
end,
|
||
|
canInteract = function(entity)
|
||
|
return (Functions.CanInteract() and not isCarryingProp)
|
||
|
end
|
||
|
})
|
||
|
end
|
||
|
|
||
|
exports.ox_target:addLocalEntity(prop, options)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- For the people using qb-target
|
||
|
if (GetResourceState('qb-target') == 'started') then
|
||
|
local options = {
|
||
|
{
|
||
|
icon = 'fas fa-trash-can',
|
||
|
label = Config.Target.Object.LabelRemove,
|
||
|
job = RequiredJobsToPickupOrRemove or nil,
|
||
|
action = function(entity)
|
||
|
PlayAnimation(Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, Config.WalkWithProp[propName].PickupAnimFlag, Config.WalkWithProp[propName].PickupAnimTime)
|
||
|
while IsEntityPlayingAnim(PlayerPedId(), Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, 3) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
if (not DoesEntityExist(entity)) then return end
|
||
|
local propNetId = NetworkGetNetworkIdFromEntity(entity)
|
||
|
TriggerServerEvent('gs_advancedtrunk:RemoveProp', propNetId)
|
||
|
end,
|
||
|
canInteract = function(entity)
|
||
|
return (Functions.CanInteract() and not isCarryingProp)
|
||
|
end,
|
||
|
},
|
||
|
}
|
||
|
if Config.WalkWithProp[propName].CanPickUp then
|
||
|
table.insert(options, {
|
||
|
icon = 'fas fa-hand-spock',
|
||
|
label = Config.Target.Object.LabelPickup,
|
||
|
job = RequiredJobsToPickupOrRemove or nil,
|
||
|
action = function(entity)
|
||
|
PlayAnimation(Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, Config.WalkWithProp[propName].PickupAnimFlag, Config.WalkWithProp[propName].PickupAnimTime)
|
||
|
while IsEntityPlayingAnim(PlayerPedId(), Config.WalkWithProp[propName].PickupAnimDict, Config.WalkWithProp[propName].PickupAnimName, 3) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
if (not DoesEntityExist(entity)) then return end
|
||
|
local propNetId = NetworkGetNetworkIdFromEntity(entity)
|
||
|
TriggerServerEvent('gs_advancedtrunk:RemoveProp', propNetId)
|
||
|
Actions.WalkWithProp(propName)
|
||
|
end,
|
||
|
canInteract = function(entity)
|
||
|
return (Functions.CanInteract() and not isCarryingProp)
|
||
|
end,
|
||
|
})
|
||
|
end
|
||
|
|
||
|
exports['qb-target']:AddTargetEntity(prop, {
|
||
|
options = options,
|
||
|
distance = Config.Target.Object.InteractDistance,
|
||
|
})
|
||
|
return
|
||
|
end
|
||
|
|
||
|
print('gs_advancedtrunk: [ERROR] No target interaction defined')
|
||
|
end
|