2026-04-14 17:41:39 +02:00

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