Scripts/resources/[qb]/[qb_crimes]/qb-blackmarket/client/client.lua

459 lines
15 KiB
Lua
Raw Permalink Normal View History

2024-12-29 20:03:28 +00:00
local QBCore = exports['qb-core']:GetCoreObject()
local PlayerData = QBCore.Functions.GetPlayerData()
local marketItems, orderLocation, tabletProp, currentMoney
local targetZones = {}
local displayingUI = false
local function removeTargetZones()
for i=1, #targetZones do
exports['qb-target']:RemoveZone(targetZones[i])
end
end
local function tabletAnim(state)
local ped = PlayerPedId()
if state then
local tabletHash = joaat(Config.tabletAnim.prop)
loadModel(tabletHash)
loadAnimDict(Config.tabletAnim.dict)
tabletProp = CreateObject(tabletHash, GetEntityCoords(ped), true, true, false)
AttachEntityToEntity(tabletProp, ped, GetPedBoneIndex(ped, 28422), -0.05, 0.0, 0.0, 0.0, 0.0, 0.0, true, true, false, true, 1, true)
SetModelAsNoLongerNeeded(tabletHash)
TaskPlayAnim(ped, Config.tabletAnim.dict, Config.tabletAnim.anim, 1.0, 1.0, -1, 51, 0, 0, 0, 0)
else
DeleteObject(tabletProp)
ClearPedTasks(ped)
end
end
local function displayUI(state)
displayingUI = state
tabletAnim(state)
if state then
SendNUIMessage({
action = "setVisible",
data = true,
})
else
SendNUIMessage({
action = "setVisible",
data = false,
})
end
SetNuiFocus(state, state)
end
local function tabletNotification(text, notifType)
SendNUIMessage({
action = "notification",
data = {
text = text,
notifType = notifType,
}
})
end
local function doContainerAnim(index, containerNetId, lockNetId, collisionNetId)
local container = NetworkGetEntityFromNetworkId(containerNetId)
local lock = NetworkGetEntityFromNetworkId(lockNetId)
local collision = NetworkGetEntityFromNetworkId(collisionNetId)
NetworkRequestControlOfEntity(container)
NetworkRequestControlOfEntity(lock)
local timer = GetGameTimer()
while not NetworkHasControlOfEntity(container) or not NetworkHasControlOfEntity(lock) do
Wait(0)
if GetGameTimer() - timer > 5000 then
printError("Failed to get control of object")
break
end
end
loadAnimDict(Config.containerAnim.dict)
loadPtfx(Config.containerAnim.ptfx)
loadAudio(Config.containerAnim.audioBank)
local grinderHash = joaat(Config.props.grinder)
local bagHash = joaat(Config.props.bag)
loadModel(grinderHash)
loadModel(bagHash)
local ped = PlayerPedId()
local containerCoords = GetEntityCoords(container)
local containerRot = GetEntityRotation(container)
local playerCoords = GetEntityCoords(ped)
local grinder = CreateObject(grinderHash, playerCoords, true, true, false)
local bag = CreateObject(bagHash, playerCoords, true, true, false)
SetEntityCollision(bag, false, false)
FreezeEntityPosition(ped, true)
local containerScene = NetworkCreateSynchronisedScene(containerCoords, containerRot, 2, true, false, 1.0, 0.0, 1.0)
NetworkAddPedToSynchronisedScene(ped, containerScene, Config.containerAnim.dict, Config.containerAnim.player, 10.0, 10.0, 0, 0, 1000.0, 0)
NetworkAddEntityToSynchronisedScene(lock, containerScene, Config.containerAnim.dict, Config.containerAnim.lock, 2.0, -4.0, 134149)
NetworkAddEntityToSynchronisedScene(grinder, containerScene, Config.containerAnim.dict, Config.containerAnim.grinder, 2.0, -4.0, 134149)
NetworkAddEntityToSynchronisedScene(bag, containerScene, Config.containerAnim.dict, Config.containerAnim.bag, 2.0, -4.0, 134149)
NetworkStartSynchronisedScene(containerScene)
PlayEntityAnim(container, Config.containerAnim.container, Config.containerAnim.dict, 8.0, false, true, false, 0, 0)
CreateThread(function()
while NetworkGetLocalSceneFromNetworkId(containerScene) == -1 do Wait(0) end
local localScene = NetworkGetLocalSceneFromNetworkId(containerScene)
local ptfx
while IsSynchronizedSceneRunning(localScene) do
if HasAnimEventFired(ped, -1953940906) then
UseParticleFxAsset("scr_tn_tr")
ptfx = StartNetworkedParticleFxLoopedOnEntity("scr_tn_tr_angle_grinder_sparks", grinder, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, false, false, false, 1065353216, 1065353216, 1065353216, 1)
elseif HasAnimEventFired(ped, -258875766) then
StopParticleFxLooped(ptfx, false)
end
Wait(0)
end
end)
Wait(GetAnimDuration(Config.containerAnim.dict, Config.containerAnim.container) * 1000)
FreezeEntityPosition(ped, false)
NetworkStopSynchronisedScene(containerScene)
DeleteObject(grinder)
DeleteObject(lock)
DeleteObject(bag)
ClearPedTasks(ped)
TriggerServerEvent("qb-blackmarket_sv:openContainer", index)
DisposeSynchronizedScene(containerScene)
RemoveNamedPtfxAsset(Config.containerAnim.ptfx)
ReleaseNamedScriptAudioBank(Config.containerAnim.audioBank)
RemoveAnimDict(Config.containerAnim.dict)
end
local function spawnObject(model, coords)
local propHash = type(model) == 'string' and joaat(model) or model
loadModel(propHash)
local object = CreateObject(propHash, coords.xyz, true, true, false)
while not DoesEntityExist(object) do
Wait(10)
end
SetEntityAsMissionEntity(object, true, true)
FreezeEntityPosition(object, true)
SetEntityHeading(object, coords.w)
SetModelAsNoLongerNeeded(propHash)
return object
end
local function spawnContainer(coords)
loadAnimDict(Config.containerAnim.dict)
local container = spawnObject(Config.props.container, vector4(coords.x, coords.y, coords.z - 1, coords.w - 180))
local containerCoords = GetEntityCoords(container)
local lockCoords = GetAnimInitialOffsetPosition(Config.containerAnim.dict, Config.containerAnim.lock, GetEntityCoords(container), GetEntityRotation(container), 0.0, 0)
local lock = spawnObject(Config.props.lock, vector4(lockCoords, coords.w - 180))
SetEntityCoords(lock, lockCoords)
local crateCoords = GetObjectOffsetFromCoords(coords, 0.0, -0.6, -0.8)
local crate = spawnObject(Config.props.crate, vector4(crateCoords, coords.w + 90))
local collision = spawnObject(Config.props.containerCollison, vector4(containerCoords, coords.w - 180))
SetEntityCoords(collision, containerCoords, false, false, false)
SetEntityCollision(collision, false, false)
local props = {
container = container,
lock = lock,
crate = crate,
collision = collision,
}
return props
end
RegisterNetEvent("qb-blackmarket_cl:openUI", function()
displayUI(true)
end)
RegisterNetEvent("qb-blackmarket_cl:updateMarketItems", function(items)
marketItems = items
SendNUIMessage({
action = "updateMarketItems",
data = items
})
end)
RegisterNetEvent("qb-blackmarket_cl:updateStock", function(items, orderSrc)
marketItems = items
if displayingUI then
local isOwner = false
if orderSrc == GetPlayerServerId(PlayerId()) then
isOwner = true
end
SendNUIMessage({
action = "updateStock",
data = {
items = items,
notif = Config.notifText.stockUpdate,
isOwner = isOwner,
},
})
end
end)
RegisterNetEvent("qb-blackmarket_cl:orderReady", function(index, coords)
orderLocation = coords
local props = spawnContainer(orderLocation)
local netIds = {}
for k, v in pairs(props) do
netIds[k] = NetworkGetNetworkIdFromEntity(v)
end
TriggerServerEvent("qb-blackmarket_sv:propsSpawned", netIds, index)
if not displayingUI then
QBCore.Functions.Notify(Config.notifText.orderReady, "success")
else
tabletNotification(Config.notifText.orderReady, "success")
end
SendNUIMessage({
action = "orderReady",
})
if math.random() <= Config.policeNotifChance then
Config.policeNotify(orderLocation)
end
end)
RegisterNetEvent("qb-blackmarket_cl:addLockTarget", function(index, coords)
local zoneName = "bm_lock_"..index
for i=1, #targetZones do
if targetZones[i] == zoneName then print("lock exists") return end
end
local min, max = GetModelDimensions(joaat(Config.props.lock))
local lockDimensions = max - min
exports["qb-target"]:AddBoxZone(zoneName, coords.xyz, lockDimensions.y, lockDimensions.x, {
name = zoneName,
heading = coords.w,
debugPoly = false,
minZ = coords.z - lockDimensions.z/2,
maxZ = coords.z + lockDimensions.z/2,
}, {
options = {
{
icon = "fa-solid fa-unlock",
label = "Åben",
action = function()
TriggerServerEvent("qb-blackmarket_sv:attemptContainer", index)
end
}
},
distance = 2.0
})
targetZones[#targetZones + 1] = zoneName
end)
RegisterNetEvent("qb-blackmarket_cl:openContainer", function(index, propIds)
doContainerAnim(index, propIds.container, propIds.lock, propIds.collision)
end)
RegisterNetEvent("qb-blackmarket_cl:updateOpenContainer", function(index, containerNetId, collisionNetId, crateCoords, removeLockTarget)
local container = NetworkGetEntityFromNetworkId(containerNetId)
local collision = NetworkGetEntityFromNetworkId(collisionNetId)
SetEntityCollision(collision, true, true)
SetEntityCompletelyDisableCollision(container, false, false)
if removeLockTarget then
exports['qb-target']:RemoveZone("bm_lock_"..index)
for i=1, #targetZones do
if targetZones[i] == "bm_lock_"..index then
table.remove(targetZones, i)
break
end
end
end
local zoneName = "bm_crate_"..index
local min, max = GetModelDimensions(joaat(Config.props.crate))
local crateDimensions = max - min
exports["qb-target"]:AddBoxZone(zoneName, crateCoords.xyz, crateDimensions.y, crateDimensions.x, {
name = zoneName,
heading = crateCoords.w,
debugPoly = false,
minZ = crateCoords.z,
maxZ = crateCoords.z + crateDimensions.z,
}, {
options = {
{
icon = "fa-solid fa-boxes-stacked",
label = "Tag",
action = function()
TriggerServerEvent("qb-blackmarket_sv:attemptLoot", index)
end
}
},
distance = 2.0
})
targetZones[#targetZones + 1] = zoneName
end)
RegisterNetEvent("qb-blackmarket_cl:removeLockTarget", function(index)
print("removing lock target ", index)
exports['qb-target']:RemoveZone("bm_lock_"..index)
for i=1, #targetZones do
if targetZones[i] == "bm_lock_"..index then
table.remove(targetZones, i)
break
end
end
end)
RegisterNetEvent("qb-blackmarket_cl:removeLootTarget", function(index)
exports['qb-target']:RemoveZone("bm_crate_"..index)
for i=1, #targetZones do
if targetZones[i] == "bm_crate_"..index then
table.remove(targetZones, i)
break
end
end
end)
RegisterNetEvent("qb-blackmarket_cl:lootContainer", function(index)
local ped = PlayerPedId()
loadAnimDict(Config.lootAnim.dict)
TaskPlayAnim(ped, Config.lootAnim.dict, Config.lootAnim.anim, 1.0, 1.0, -1, 1, 0, 0, 0, 0)
QBCore.Functions.Progressbar("looting_crate", "Tager ting..", Config.lootTime, false, true, {
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true
}, {}, {}, {}, function() -- Done
TriggerServerEvent("qb-blackmarket_sv:finishLooting", index)
end, function() -- Cancel
TriggerServerEvent("qb-blackmarket_sv:cancelLooting", index)
QBCore.Functions.Notify("Annulleret", "error")
end)
end)
RegisterNetEvent("qb-blackmarket_cl:orderComplete", function()
SendNUIMessage({
action = "clearOrder"
})
end)
RegisterNetEvent("qb-blackmarket_cl:hasPendingOrder", function(items, order, epochTime)
SendNUIMessage({
action = "loadPendingOrder",
data = {
marketItems = items,
order = order,
epochTime = epochTime,
}
})
end)
RegisterNetEvent("qb-blackmarket_cl:enableLocateButton", function(index)
orderLocation = Config.deliveryLocations[index]
SendNUIMessage({
action = "orderReady",
})
end)
RegisterNUICallback("getClientData", function(data, cb)
currentMoney = PlayerData.money[Config.paymentType]
if not marketItems then
QBCore.Functions.TriggerCallback("qb-blackmarket_sv:getMarketItems", function(items)
marketItems = items
cb({ marketItems = marketItems, currencyAmt = currentMoney })
end)
else
cb({ marketItems = marketItems, currencyAmt = currentMoney })
end
end)
RegisterNUICallback("submitOrder", function(data, cb)
QBCore.Functions.TriggerCallback("qb-blackmarket_sv:attemptOrder", function(result)
cb(result)
if result.notif then
if result.success then
tabletNotification(result.notif, "success")
else
tabletNotification(result.notif, "error")
end
end
if result.error then
printError(result.error)
end
end, (data))
end)
RegisterNUICallback("deliveryLocation", function(data, cb)
if orderLocation then
SetNewWaypoint(orderLocation.x, orderLocation.y)
tabletNotification(Config.notifText.gpsSet, "success")
end
cb({})
end)
RegisterNUICallback("close", function(data, cb)
displayUI(false)
cb({})
end)
RegisterNUICallback("fetchConfig", function(data, cb)
cb({
configData = {
inventory = Config.inventory,
paymentType = Config.paymentType,
acronym = Config.cryptoAcronym,
cryptoIcon = Config.cryptoIcon,
estDeliveryTime = tostring(math.floor((Config.deliveryTime.min + Config.deliveryTime.max)/2)),
tabletColour = Config.tabletColour,
},
notifData = Config.notifs,
})
end)
RegisterNetEvent('QBCore:Player:SetPlayerData', function(val)
PlayerData = val
if displayingUI then
if PlayerData.money[Config.paymentType] ~= currentMoney then
SendNUIMessage({
action = "updateCash",
data = PlayerData.money[Config.paymentType]
})
end
end
end)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
PlayerData = QBCore.Functions.GetPlayerData()
TriggerServerEvent("qb-blackmarket_sv:initPendingOrders")
end)
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
PlayerData = nil
removeTargetZones()
targetZones = {}
SendNUIMessage({
SendNUIMessage({
action = "clearOrder"
})
})
end)
AddEventHandler('onResourceStop', function(resourceName)
if resourceName ~= GetCurrentResourceName() then return end
for i=1, #targetZones do
exports['qb-target']:RemoveZone(targetZones[i])
end
targetZones = {}
end)