235 lines
7.1 KiB
Lua
235 lines
7.1 KiB
Lua
--- Desencrypted By PrejuicioX
|
|
|
|
-- Framework validation
|
|
if Config.esxSettings.enabled then
|
|
if Config.qbSettings.enabled then
|
|
print("^1BOTH FRAMEWORKS ENABLED!! MAKE SURE TO ONLY ENABLE ONE FRAMEWORK IN THE CONFIG FILE!")
|
|
end
|
|
end
|
|
|
|
-- Global tables (preserve for cross-file usage)
|
|
DB_TAG = "kq_outfitbag:outfit"
|
|
OUTFITS = {}
|
|
PLAYER_BAGS = {}
|
|
DELETE_QUEUE = {}
|
|
|
|
-- Bag despawning system
|
|
if Config.bagDespawning and Config.bagDespawning.enabled then
|
|
Citizen.CreateThread(function()
|
|
while true do
|
|
Citizen.Wait(60000)
|
|
|
|
local queueCopy = json.decode(json.encode(DELETE_QUEUE))
|
|
|
|
for index, bagData in pairs(DELETE_QUEUE) do
|
|
if not DoesEntityExist(bagData.entity) then
|
|
queueCopy[index] = nil
|
|
else
|
|
local currentTime = GetGameTimer()
|
|
local despawnTime = bagData.time + (Config.bagDespawning.time * 1000 * 60)
|
|
|
|
if currentTime > despawnTime then
|
|
DeleteEntity(bagData.entity)
|
|
queueCopy[index] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
DELETE_QUEUE = queueCopy
|
|
end
|
|
end)
|
|
end
|
|
|
|
function GetOrFetchOutfits(playerId, bagTag)
|
|
local identifier = _GetPlayerIdentifier(playerId)
|
|
|
|
if OUTFITS[identifier] and OUTFITS[identifier][bagTag] then
|
|
return OUTFITS[identifier][bagTag]
|
|
end
|
|
|
|
return FetchPlayerOutfits(playerId, bagTag)
|
|
end
|
|
|
|
function FetchPlayerOutfits(playerId, bagTag)
|
|
local identifier = _GetPlayerIdentifier(playerId)
|
|
|
|
OUTFITS[identifier] = {}
|
|
OUTFITS[identifier][bagTag] = nil
|
|
|
|
if not OUTFITS[identifier][bagTag] then
|
|
local savedOutfits = GetSavedPlayerOutfits(playerId)
|
|
|
|
if savedOutfits then
|
|
OUTFITS[identifier][bagTag] = {}
|
|
|
|
for _, outfitRecord in ipairs(savedOutfits) do
|
|
local outfitData = json.decode(outfitRecord.data)
|
|
|
|
-- Filter outfits by bag tag
|
|
if outfitData.bagItem == bagTag or (Config.bagTag == bagTag and not outfitData.bagItem) then
|
|
outfitData.id = outfitRecord.id
|
|
table.insert(OUTFITS[identifier][bagTag], outfitData)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return OUTFITS[identifier][bagTag]
|
|
end
|
|
|
|
function RefreshBagOutfits(playerId, bagTag, bagEntity)
|
|
local outfits = GetOrFetchOutfits(playerId, bagTag)
|
|
local entityState = Entity(bagEntity).state
|
|
entityState:set("kq_ob_outfits", outfits, true)
|
|
|
|
-- Fallback for non-networked entities
|
|
if not bagEntity or bagEntity <= 0 then
|
|
TriggerClientEvent("kq_outfitbag2:client:set_bags", playerId, nil, {
|
|
kq_ob_outfits = outfits
|
|
})
|
|
end
|
|
end
|
|
|
|
function GetBagTagFromNetId(networkId)
|
|
local entity = NetworkGetEntityFromNetworkId(networkId)
|
|
return Entity(entity).state.kq_ob_bag
|
|
end
|
|
|
|
-- Command registration
|
|
if Config.command.enabled then
|
|
RegisterCommand(Config.command.command, function(source)
|
|
TriggerClientEvent("kq_outfitbag2:client:place", source, "kq_outfitbag", false)
|
|
end)
|
|
|
|
RegisterCommand(Config.command.shortCommand, function(source)
|
|
TriggerClientEvent("kq_outfitbag2:client:place", source, "kq_outfitbag", false)
|
|
end)
|
|
end
|
|
|
|
-- Event: Place bag
|
|
RegisterServerEvent("kq_outfitbag2:server:place")
|
|
AddEventHandler("kq_outfitbag2:server:place", function(bagTag, networkId, propEntity, itemName)
|
|
local playerId = source
|
|
PlaceBag(playerId, bagTag, networkId, propEntity, itemName)
|
|
end)
|
|
|
|
function PlaceBag(playerId, bagTag, networkId, propEntity, itemName)
|
|
local identifier = _GetPlayerIdentifier(playerId)
|
|
|
|
-- Handle existing bag on ground
|
|
if PLAYER_BAGS[identifier] and DoesEntityExist(PLAYER_BAGS[identifier]) then
|
|
if Config.onlyAllowOneBagOnGround then
|
|
DeleteEntity(PLAYER_BAGS[identifier])
|
|
PLAYER_BAGS[identifier] = nil
|
|
end
|
|
end
|
|
|
|
local bagEntity = NetworkGetEntityFromNetworkId(networkId)
|
|
|
|
-- Fallback for non-networked entities
|
|
if not bagEntity or bagEntity <= 0 then
|
|
Debug("Could not detect the bag as networked")
|
|
TriggerClientEvent("kq_outfitbag2:client:set_bags", playerId, propEntity, {
|
|
kq_ob = true,
|
|
kq_ob_item = itemName or false,
|
|
kq_ob_bag = bagTag,
|
|
kq_ob_public = false,
|
|
kq_ob_owner = playerId,
|
|
kq_ob_outfits = GetOrFetchOutfits(playerId, bagTag)
|
|
})
|
|
return
|
|
end
|
|
|
|
Debug("Created bag entity", bagEntity)
|
|
|
|
Citizen.Wait(500)
|
|
|
|
PLAYER_BAGS[identifier] = bagEntity
|
|
FreezeEntityPosition(bagEntity, true)
|
|
|
|
Debug("500ms since created bag entity", bagEntity, DoesEntityExist(bagEntity), GetEntityCoords(bagEntity))
|
|
|
|
if bagEntity and bagEntity > 0 then
|
|
Debug("object detected, setting state")
|
|
|
|
EnsureEntityStateBag(bagEntity)
|
|
|
|
local entityState = Entity(bagEntity).state
|
|
entityState:set("kq_ob", true, true)
|
|
entityState:set("kq_ob_item", itemName or false, true)
|
|
entityState:set("kq_ob_bag", bagTag, true)
|
|
entityState:set("kq_ob_public", false, true)
|
|
entityState:set("kq_ob_owner", playerId, true)
|
|
|
|
RefreshBagOutfits(playerId, bagTag, bagEntity)
|
|
|
|
table.insert(DELETE_QUEUE, {
|
|
time = GetGameTimer(),
|
|
entity = bagEntity
|
|
})
|
|
end
|
|
|
|
if itemName then
|
|
RemoveBagItem(playerId, itemName)
|
|
end
|
|
end
|
|
|
|
-- Event: Delete outfit
|
|
RegisterServerEvent("kq_outfitbag2:server:deleteOutfit")
|
|
AddEventHandler("kq_outfitbag2:server:deleteOutfit", function(outfitId, bagNetworkId, fallbackBagTag)
|
|
local bagTag = GetBagTagFromNetId(bagNetworkId) or fallbackBagTag
|
|
local playerId = source
|
|
|
|
DeleteOutfit(playerId, outfitId)
|
|
FetchPlayerOutfits(playerId, bagTag)
|
|
RefreshBagOutfits(playerId, bagTag, NetworkGetEntityFromNetworkId(bagNetworkId))
|
|
end)
|
|
|
|
-- Event: Pickup bag
|
|
RegisterServerEvent("kq_outfitbag2:server:pickup")
|
|
AddEventHandler("kq_outfitbag2:server:pickup", function(bagNetworkId, itemName)
|
|
PickupBag(source, bagNetworkId, itemName)
|
|
end)
|
|
|
|
function PickupBag(playerId, bagNetworkId, itemName)
|
|
local bagEntity = NetworkGetEntityFromNetworkId(bagNetworkId)
|
|
local bagItemName = Entity(bagEntity).state.kq_ob_item
|
|
|
|
if bagItemName or itemName then
|
|
AddPlayerItem(playerId, bagItemName or itemName, 1)
|
|
end
|
|
|
|
DeleteEntity(bagEntity)
|
|
|
|
local identifier = _GetPlayerIdentifier(playerId)
|
|
PLAYER_BAGS[identifier] = nil
|
|
end
|
|
|
|
-- Event: Save outfit
|
|
RegisterServerEvent("kq_outfitbag2:server:saveOutfit")
|
|
AddEventHandler("kq_outfitbag2:server:saveOutfit", function(outfitData, bagNetworkId, fallbackBagTag)
|
|
local bagTag = GetBagTagFromNetId(bagNetworkId) or fallbackBagTag
|
|
local playerId = tonumber(source)
|
|
local identifier = _GetPlayerIdentifier(playerId)
|
|
|
|
-- Check outfit limit
|
|
if OUTFITS[identifier] and OUTFITS[identifier][bagTag] then
|
|
if #OUTFITS[identifier][bagTag] >= Config.maxOutfits then
|
|
return
|
|
end
|
|
end
|
|
|
|
outfitData.bagItem = bagTag
|
|
|
|
SaveOutfit(playerId, outfitData)
|
|
FetchPlayerOutfits(playerId, bagTag)
|
|
RefreshBagOutfits(playerId, bagTag, NetworkGetEntityFromNetworkId(bagNetworkId))
|
|
end)
|
|
|
|
function Debug(...)
|
|
if Config.debug then
|
|
print(...)
|
|
end
|
|
end
|
|
|
|
--- Desencrypted By PrejuicioX |