373 lines
11 KiB
Lua
373 lines
11 KiB
Lua
--- Desencrypted By PrejuicioX
|
|
|
|
-- ============================================================================
|
|
-- EVENT HANDLERS
|
|
-- ============================================================================
|
|
|
|
RegisterNetEvent("kq_outfitbag2:client:place")
|
|
AddEventHandler("kq_outfitbag2:client:place", function(outfitData, isPublic)
|
|
PlaceDownBag(outfitData, isPublic)
|
|
end)
|
|
|
|
RegisterNetEvent("kq_outfitbag2:client:set_bags")
|
|
AddEventHandler("kq_outfitbag2:client:set_bags", function(bagEntity, stateData)
|
|
if not bagEntity then
|
|
bagEntity = CURRENT_BAG
|
|
end
|
|
|
|
if not DoesEntityExist(bagEntity) then
|
|
Debug("Local fallback object not found")
|
|
return
|
|
end
|
|
|
|
for key, value in pairs(stateData) do
|
|
Entity(bagEntity).state:set(key, value, true)
|
|
end
|
|
end)
|
|
|
|
-- ============================================================================
|
|
-- BAG PLACEMENT
|
|
-- ============================================================================
|
|
|
|
function PlaceDownBag(outfitData, isPublic)
|
|
Citizen.CreateThread(function()
|
|
local playerPed = PlayerPedId()
|
|
|
|
if IsPedInAnyVehicle(playerPed) or IsPedRagdoll(playerPed) or IsEntityDead(playerPed) then
|
|
return
|
|
end
|
|
|
|
RotateTillFree()
|
|
|
|
if Config.bagAnimation.enabled then
|
|
PlayAnim(Config.bagAnimation.dict, Config.bagAnimation.anim, 1)
|
|
Citizen.Wait(1500)
|
|
ClearPedTasks(PlayerPedId())
|
|
end
|
|
|
|
local spawnPosition = CalculateBagSpawnPosition(playerPed)
|
|
if not spawnPosition then
|
|
return
|
|
end
|
|
|
|
local bagObject = CreateBagObject(spawnPosition, playerPed)
|
|
local networkId = WaitForNetworkRegistration(bagObject)
|
|
|
|
if networkId then
|
|
TriggerServerEvent("kq_outfitbag2:server:place", outfitData, networkId, bagObject, isPublic)
|
|
end
|
|
end)
|
|
end
|
|
|
|
function CalculateBagSpawnPosition(playerPed)
|
|
local offsetCoords = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 0.8, 1.0)
|
|
local groundFound, groundZ = GetGroundZFor_3dCoord_2(offsetCoords.x, offsetCoords.y, offsetCoords.z, true)
|
|
local playerCoords = GetEntityCoords(playerPed)
|
|
local targetPosition = vector3(playerCoords.x, playerCoords.y, playerCoords.z - 1.0)
|
|
|
|
if groundFound then
|
|
if groundZ < playerCoords.z + 0.5 and groundZ + 1.5 > playerCoords.z then
|
|
targetPosition = vector3(offsetCoords.x, offsetCoords.y, groundZ)
|
|
end
|
|
end
|
|
|
|
local distanceCheck = #(playerCoords - targetPosition)
|
|
if distanceCheck > 5.0 then
|
|
return nil
|
|
end
|
|
|
|
return targetPosition
|
|
end
|
|
|
|
function CreateBagObject(position, playerPed)
|
|
DoRequestModel(Config.bagObject)
|
|
local bagObject = CreateObject(Config.bagObject, position, 1, 1, 0)
|
|
SetEntityHeading(bagObject, GetEntityHeading(playerPed))
|
|
Citizen.Wait(50)
|
|
return bagObject
|
|
end
|
|
|
|
function WaitForNetworkRegistration(bagObject)
|
|
local retryCount = 2500
|
|
|
|
while not NetworkGetEntityIsNetworked(bagObject) and retryCount > 0 do
|
|
Debug("entity not networked. Retrying")
|
|
NetworkRegisterEntityAsNetworked(bagObject)
|
|
retryCount = retryCount - 50
|
|
Citizen.Wait(50)
|
|
end
|
|
|
|
if NetworkGetEntityIsNetworked(bagObject) then
|
|
return NetworkGetNetworkIdFromEntity(bagObject)
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- BAG STATE QUERIES
|
|
-- ============================================================================
|
|
|
|
function IsEntityOutfitBag(entity)
|
|
return UseCache("IsEntityOutfitBag" .. entity, function()
|
|
if DoesEntityExist(entity) then
|
|
return Entity(entity).state.kq_ob
|
|
end
|
|
end, 2000)
|
|
end
|
|
|
|
function IsPublic(entity)
|
|
return UseCache("IsPublic" .. entity, function()
|
|
if not IsBagObject(entity) then
|
|
return false
|
|
end
|
|
return Entity(entity).state.kq_ob_public
|
|
end, 1000)
|
|
end
|
|
|
|
function OwnsBag(entity)
|
|
return UseCache("OwnsBag" .. entity, function()
|
|
if not IsBagObject(entity) then
|
|
return false
|
|
end
|
|
local ownerServerId = Entity(entity).state.kq_ob_owner
|
|
local playerServerId = GetPlayerServerId(PlayerId())
|
|
return ownerServerId == playerServerId
|
|
end, 1000)
|
|
end
|
|
|
|
function GetBagOutfits(entity)
|
|
return UseCache("GetBagOutfits" .. entity, function()
|
|
if not IsBagObject(entity) then
|
|
local fixedBagData = Config.fixedBags[entity]
|
|
return fixedBagData and fixedBagData.outfits or {}
|
|
end
|
|
return Entity(entity).state.kq_ob_outfits or {}
|
|
end, 1000)
|
|
end
|
|
|
|
function IsBagObject(entity)
|
|
return type(entity) == "number" and DoesEntityExist(entity)
|
|
end
|
|
|
|
function GetBagJobs(entity)
|
|
return UseCache("GetBagJobs" .. entity, function()
|
|
if not IsBagObject(entity) then
|
|
return nil
|
|
end
|
|
return Entity(entity).state.kq_ob_jobs
|
|
end, 5000)
|
|
end
|
|
|
|
function CorrectBagJob(entity)
|
|
return UseCache("CorrectBagJob" .. entity, function()
|
|
if PLAYER_JOB == nil then
|
|
return true
|
|
end
|
|
|
|
local allowedJobs = GetBagJobs(entity)
|
|
if not allowedJobs then
|
|
return true
|
|
end
|
|
|
|
for _, jobName in pairs(allowedJobs) do
|
|
if PLAYER_JOB == jobName then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end, 5000)
|
|
end
|
|
|
|
function FindBagOutfit(outfitId)
|
|
return UseCache("GetBagOutfits" .. CURRENT_BAG .. "_" .. outfitId, function()
|
|
for index, outfit in pairs(GetBagOutfits(CURRENT_BAG)) do
|
|
local matchFound = false
|
|
|
|
if tonumber(outfitId) ~= nil then
|
|
matchFound = tonumber(outfit.id) == tonumber(outfitId)
|
|
else
|
|
matchFound = outfit.id == outfitId
|
|
end
|
|
|
|
if matchFound then
|
|
return outfit, index
|
|
end
|
|
end
|
|
return nil, nil
|
|
end, 1000)
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- BAG INTERACTION
|
|
-- ============================================================================
|
|
|
|
function OpenBag(bagEntity)
|
|
local playerPed = PlayerPedId()
|
|
|
|
if IsPedInAnyVehicle(playerPed) or IsPedRagdoll(playerPed) or IsEntityDead(playerPed) then
|
|
return
|
|
end
|
|
|
|
if Config.bagAnimation.enabled and IsBagObject(bagEntity) then
|
|
PlayAnim(Config.bagAnimation.dict, Config.bagAnimation.anim, 1)
|
|
end
|
|
|
|
CURRENT_BAG = bagEntity
|
|
BAG_OPEN = true
|
|
|
|
if IsBagObject(bagEntity) then
|
|
FaceTheBag(bagEntity)
|
|
end
|
|
|
|
SetBagCam(bagEntity)
|
|
OnBadOpened()
|
|
CreatePreviewPed(bagEntity)
|
|
OpenNuiBag(bagEntity)
|
|
end
|
|
|
|
function CloseBag()
|
|
ResetBagCam()
|
|
|
|
SendNUIMessage({
|
|
event = "show",
|
|
state = false,
|
|
owned = false
|
|
})
|
|
|
|
CURRENT_BAG = nil
|
|
BAG_OPEN = false
|
|
|
|
SetNuiFocus(false, false)
|
|
ClearPedTasks(PlayerPedId())
|
|
DeletePreviewPed()
|
|
OnBagClosed()
|
|
end
|
|
|
|
function PickupBag(bagEntity)
|
|
FaceTheBag(bagEntity)
|
|
|
|
if Config.bagAnimation.enabled and IsBagObject(bagEntity) then
|
|
PlayAnim(Config.bagAnimation.dict, Config.bagAnimation.anim, 1)
|
|
end
|
|
|
|
Citizen.Wait(1500)
|
|
|
|
SetEntityAlpha(bagEntity, 200)
|
|
Citizen.Wait(100)
|
|
SetEntityAlpha(bagEntity, 150)
|
|
Citizen.Wait(100)
|
|
SetEntityAlpha(bagEntity, 100)
|
|
Citizen.Wait(100)
|
|
SetEntityAlpha(bagEntity, 50)
|
|
Citizen.Wait(100)
|
|
|
|
local networkId = NetworkGetNetworkIdFromEntity(bagEntity)
|
|
local itemName = Entity(bagEntity).state.kq_ob_item
|
|
|
|
TriggerServerEvent("kq_outfitbag2:server:pickup", networkId, itemName)
|
|
DeleteEntity(bagEntity)
|
|
ClearPedTasks(PlayerPedId())
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- CAMERA SYSTEM
|
|
-- ============================================================================
|
|
|
|
local bagCamera = nil
|
|
local transitionCamera = nil
|
|
|
|
function SetBagCam(bagEntity)
|
|
local playerPed = PlayerPedId()
|
|
local cameraPosition = GetOffsetFromEntityInWorldCoords(playerPed, vector3(0.0, 1.6, -0.55))
|
|
|
|
if not IsBagObject(CURRENT_BAG) then
|
|
cameraPosition = cameraPosition + vector3(0.0, 0.0, 0.4)
|
|
end
|
|
|
|
bagCamera = CreateCamWithParams(
|
|
"DEFAULT_SCRIPTED_CAMERA",
|
|
cameraPosition,
|
|
5.0,
|
|
0.0,
|
|
GetEntityHeading(PlayerPedId()) - 180.0,
|
|
70.0,
|
|
2,
|
|
2
|
|
)
|
|
|
|
local gameplayCamCoords = GetGameplayCamCoord()
|
|
local gameplayCamRot = GetGameplayCamRot()
|
|
|
|
transitionCamera = CreateCamWithParams(
|
|
"DEFAULT_SCRIPTED_CAMERA",
|
|
gameplayCamCoords.x,
|
|
gameplayCamCoords.y,
|
|
gameplayCamCoords.z,
|
|
gameplayCamRot[1],
|
|
gameplayCamRot[2],
|
|
gameplayCamRot[3],
|
|
GetGameplayCamFov(),
|
|
2,
|
|
2
|
|
)
|
|
|
|
SetCamActive(transitionCamera, true)
|
|
SetCamActiveWithInterp(bagCamera, transitionCamera, 1250, 2, 2)
|
|
RenderScriptCams(true, false, 0, true, false, false)
|
|
end
|
|
|
|
function ResetBagCam()
|
|
SetCamActiveWithInterp(transitionCamera, bagCamera, 1500, 2, 2)
|
|
RenderScriptCams(false, true, 1000, true, false, false)
|
|
|
|
DestroyCam(transitionCamera, true)
|
|
DestroyCam(bagCamera, true)
|
|
|
|
transitionCamera = nil
|
|
bagCamera = nil
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- UTILITY FUNCTIONS
|
|
-- ============================================================================
|
|
|
|
function RotateTillFree()
|
|
local playerPed = PlayerPedId()
|
|
local attemptCount = 8
|
|
|
|
while attemptCount > 0 do
|
|
if IsForwardAreaFree() then
|
|
break
|
|
end
|
|
attemptCount = attemptCount - 1
|
|
SetEntityHeading(playerPed, GetEntityHeading(playerPed) + 45.0)
|
|
end
|
|
end
|
|
|
|
function IsForwardAreaFree()
|
|
local playerPed = PlayerPedId()
|
|
local startPos = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 0.3, 0.0)
|
|
local endPos = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 1.15, -0.2)
|
|
|
|
local shapeTest = StartShapeTestSweptSphere(startPos, endPos, 0.5, 4294967295, playerPed, 1)
|
|
local _, hit = GetShapeTestResult(shapeTest)
|
|
|
|
return not hit or hit == 0
|
|
end
|
|
|
|
function FaceTheBag(bagEntity)
|
|
local playerPed = PlayerPedId()
|
|
local playerCoords = GetEntityCoords(playerPed)
|
|
local bagCoords = GetEntityCoords(bagEntity)
|
|
|
|
local heading = GetHeadingFromVector_2d(
|
|
playerCoords.x - bagCoords.x,
|
|
playerCoords.y - bagCoords.y
|
|
) + 180
|
|
|
|
SetEntityHeading(playerPed, heading)
|
|
end
|
|
|
|
--- Desencrypted By PrejuicioX |