534 lines
15 KiB
Lua
534 lines
15 KiB
Lua
|
|
local config = require 'config.client'
|
||
|
|
local isLoggedIn = false
|
||
|
|
local carryPackage = nil
|
||
|
|
local packageCoords = nil
|
||
|
|
local onDuty = false
|
||
|
|
|
||
|
|
-- zone check
|
||
|
|
local entranceTargetID = 'entranceTarget'
|
||
|
|
|
||
|
|
local exitTargetID = 'exitTarget'
|
||
|
|
local exitZone = nil
|
||
|
|
|
||
|
|
local deliveryTargetID = 'deliveryTarget'
|
||
|
|
local deliveryZone = nil
|
||
|
|
|
||
|
|
local dutyTargetID = 'dutyTarget'
|
||
|
|
local dutyZone = nil
|
||
|
|
|
||
|
|
local pickupTargetID = 'pickupTarget'
|
||
|
|
local pickupZone = nil
|
||
|
|
|
||
|
|
-- Functions
|
||
|
|
local function destroyPickupTarget()
|
||
|
|
if not pickupZone then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
exports.ox_target:removeZone(pickupTargetID)
|
||
|
|
pickupZone = nil
|
||
|
|
else
|
||
|
|
pickupZone:remove()
|
||
|
|
pickupZone = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function registerEntranceTarget()
|
||
|
|
local coords = vector3(config.outsideLocation.x, config.outsideLocation.y, config.outsideLocation.z)
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
exports.ox_target:addBoxZone({
|
||
|
|
name = entranceTargetID,
|
||
|
|
coords = coords,
|
||
|
|
rotation = config.outsideLocation.w,
|
||
|
|
size = vec3(4.7, 1.7, 3.75),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
options = {
|
||
|
|
{
|
||
|
|
icon = 'fa-solid fa-house',
|
||
|
|
type = 'client',
|
||
|
|
event = 'qbx_recyclejob:client:target:enterLocation',
|
||
|
|
label = locale("text.enter_warehouse"),
|
||
|
|
distance = 1
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
else
|
||
|
|
lib.zones.box({
|
||
|
|
coords = coords,
|
||
|
|
rotation = config.outsideLocation.w,
|
||
|
|
size = vec3(4.7, 1.7, 3.75),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
onEnter = function()
|
||
|
|
lib.showTextUI(locale("text.point_enter_warehouse"))
|
||
|
|
end,
|
||
|
|
onExit = function()
|
||
|
|
lib.hideTextUI()
|
||
|
|
end,
|
||
|
|
inside = function()
|
||
|
|
if IsControlJustReleased(0, 38) then
|
||
|
|
TriggerEvent('qbx_recyclejob:client:target:enterLocation')
|
||
|
|
lib.hideTextUI()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function registerExitTarget()
|
||
|
|
local coords = vector3(config.insideLocation.x, config.insideLocation.y, config.insideLocation.z)
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
exitZone = exports.ox_target:addBoxZone({
|
||
|
|
name = exitTargetID,
|
||
|
|
coords = coords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(1.7, 4.7, 3.75),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
options = {
|
||
|
|
{
|
||
|
|
icon = 'fa-solid fa-house',
|
||
|
|
type = 'client',
|
||
|
|
event = 'qbx_recyclejob:client:target:exitLocation',
|
||
|
|
label = locale("text.exit_warehouse"),
|
||
|
|
distance = 1
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
else
|
||
|
|
exitZone = lib.zones.box({
|
||
|
|
coords = coords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(1.55, 4.95, 3.75),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
onEnter = function()
|
||
|
|
lib.showTextUI(locale("text.point_exit_warehouse"))
|
||
|
|
end,
|
||
|
|
onExit = function()
|
||
|
|
lib.hideTextUI()
|
||
|
|
end,
|
||
|
|
inside = function()
|
||
|
|
if IsControlJustReleased(0, 38) then
|
||
|
|
TriggerEvent('qbx_recyclejob:client:target:exitLocation')
|
||
|
|
lib.hideTextUI()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function destroyExitTarget()
|
||
|
|
if not exitZone then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
exports.ox_target:removeZone(exitTargetID)
|
||
|
|
exitZone = nil
|
||
|
|
else
|
||
|
|
exitZone:remove()
|
||
|
|
exitZone = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function getDutyTargetText()
|
||
|
|
if config.useTarget then
|
||
|
|
local text = onDuty and locale("text.clock_out") or locale("text.clock_in")
|
||
|
|
return text
|
||
|
|
else
|
||
|
|
local text = onDuty and locale("text.point_clock_out") or locale("text.point_clock_in")
|
||
|
|
return text
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function registerDutyTarget()
|
||
|
|
local coords = vector3(config.dutyLocation.x, config.dutyLocation.y, config.dutyLocation.z)
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
dutyZone = exports.ox_target:addBoxZone({
|
||
|
|
name = dutyTargetID,
|
||
|
|
coords = coords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(1.8, 2.65, 2.0),
|
||
|
|
distance = 1.0,
|
||
|
|
debug = config.debugPoly,
|
||
|
|
options = {
|
||
|
|
{
|
||
|
|
icon = 'fa-solid fa-house',
|
||
|
|
type = 'client',
|
||
|
|
event = 'qbx_recyclejob:client:target:toggleDuty',
|
||
|
|
label = getDutyTargetText(),
|
||
|
|
distance = 1
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
else
|
||
|
|
dutyZone = lib.zones.box({
|
||
|
|
coords = coords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(1.8, 2.65, 2.0),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
onEnter = function()
|
||
|
|
lib.showTextUI(getDutyTargetText())
|
||
|
|
end,
|
||
|
|
onExit = function()
|
||
|
|
lib.hideTextUI()
|
||
|
|
end,
|
||
|
|
inside = function()
|
||
|
|
if IsControlJustReleased(0, 38) then
|
||
|
|
TriggerEvent('qbx_recyclejob:client:target:toggleDuty')
|
||
|
|
lib.hideTextUI()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function destroyDutyTarget()
|
||
|
|
if not dutyZone then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
exports.ox_target:removeZone(dutyTargetID)
|
||
|
|
dutyZone = nil
|
||
|
|
else
|
||
|
|
dutyZone:remove()
|
||
|
|
dutyZone = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function refreshDutyTarget()
|
||
|
|
destroyDutyTarget()
|
||
|
|
registerDutyTarget()
|
||
|
|
end
|
||
|
|
|
||
|
|
local function registerDeliveryTarget()
|
||
|
|
local coords = vector3(config.dropLocation.x, config.dropLocation.y, config.dropLocation.z)
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
deliveryZone = exports.ox_target:addBoxZone({
|
||
|
|
name = deliveryTargetID,
|
||
|
|
coords = coords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(0.95, 1.25, 2.5),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
options = {
|
||
|
|
{
|
||
|
|
icon = 'fa-solid fa-house',
|
||
|
|
type = 'client',
|
||
|
|
event = 'qbx_recyclejob:client:target:dropPackage',
|
||
|
|
label = locale("text.hand_in_package"),
|
||
|
|
distance = 1
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
else
|
||
|
|
deliveryZone = lib.zones.box({
|
||
|
|
coords = coords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(0.95, 1.25, 2.5),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
onEnter = function()
|
||
|
|
lib.showTextUI(locale("text.point_hand_in_package"))
|
||
|
|
end,
|
||
|
|
onExit = function()
|
||
|
|
lib.hideTextUI()
|
||
|
|
end,
|
||
|
|
inside = function()
|
||
|
|
if carryPackage then
|
||
|
|
if IsControlJustReleased(0, 38) then
|
||
|
|
TriggerEvent('qbx_recyclejob:client:target:dropPackage')
|
||
|
|
lib.hideTextUI()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function destroyDeliveryTarget()
|
||
|
|
if not deliveryZone then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
exports.ox_target:removeZone(deliveryTargetID)
|
||
|
|
deliveryZone = nil
|
||
|
|
else
|
||
|
|
deliveryZone:remove()
|
||
|
|
deliveryZone = nil
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function destroyInsideZones()
|
||
|
|
destroyPickupTarget()
|
||
|
|
destroyExitTarget()
|
||
|
|
destroyDutyTarget()
|
||
|
|
destroyDeliveryTarget()
|
||
|
|
end
|
||
|
|
|
||
|
|
local function scrapAnim()
|
||
|
|
local time = 5
|
||
|
|
|
||
|
|
lib.playAnim(cache.ped, 'mp_car_bomb', 'car_bomb_mechanic', 3.0, 3.0, -1, 16, 0, false, false, false)
|
||
|
|
local openingDoor = true
|
||
|
|
|
||
|
|
CreateThread(function()
|
||
|
|
while openingDoor do
|
||
|
|
lib.playAnim(cache.ped, 'mp_car_bomb', 'car_bomb_mechanic', 3.0, 3.0, -1, 16, 0, false, false, false)
|
||
|
|
Wait(1000)
|
||
|
|
time = time - 1
|
||
|
|
if time <= 0 then
|
||
|
|
openingDoor = false
|
||
|
|
StopAnimTask(cache.ped, 'mp_car_bomb', 'car_bomb_mechanic', 1.0)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
local function getRandomPackage()
|
||
|
|
packageCoords = config.pickupLocations[math.random(1, #config.pickupLocations)]
|
||
|
|
RegisterPickupTarget(packageCoords)
|
||
|
|
end
|
||
|
|
|
||
|
|
local function pickupPackage()
|
||
|
|
local pos = GetEntityCoords(cache.ped, true)
|
||
|
|
local boxModel = config.pickupBoxModel
|
||
|
|
lib.requestModel(boxModel, 5000)
|
||
|
|
lib.playAnim(cache.ped, 'anim@heists@box_carry@', 'idle', 5.0, -1, -1, 50, 0, false, false, false)
|
||
|
|
local object = CreateObject(boxModel, pos.x, pos.y, pos.z, true, true, true)
|
||
|
|
SetModelAsNoLongerNeeded(boxModel)
|
||
|
|
AttachEntityToEntity(object, cache.ped, GetPedBoneIndex(cache.ped, 57005), 0.05, 0.1, -0.3, 300.0, 250.0, 20.0, true, true, false, true, 1, true)
|
||
|
|
carryPackage = object
|
||
|
|
end
|
||
|
|
|
||
|
|
local function dropPackage()
|
||
|
|
ClearPedTasks(cache.ped)
|
||
|
|
DetachEntity(carryPackage, true, true)
|
||
|
|
DeleteObject(carryPackage)
|
||
|
|
carryPackage = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
local function setLocationBlip()
|
||
|
|
local RecycleBlip = AddBlipForCoord(config.outsideLocation.x, config.outsideLocation.y, config.outsideLocation.z)
|
||
|
|
SetBlipSprite(RecycleBlip, 365)
|
||
|
|
SetBlipColour(RecycleBlip, 2)
|
||
|
|
SetBlipScale(RecycleBlip, 0.8)
|
||
|
|
SetBlipAsShortRange(RecycleBlip, true)
|
||
|
|
BeginTextCommandSetBlipName('STRING')
|
||
|
|
AddTextComponentString('Recycle Center')
|
||
|
|
EndTextCommandSetBlipName(RecycleBlip)
|
||
|
|
end
|
||
|
|
|
||
|
|
local function buildInteriorDesign()
|
||
|
|
for _, pickuploc in pairs(config.pickupLocations) do
|
||
|
|
local model = GetHashKey(config.warehouseObjects[math.random(1, #config.warehouseObjects)])
|
||
|
|
lib.requestModel(model, 5000)
|
||
|
|
local obj = CreateObject(model, pickuploc.x, pickuploc.y, pickuploc.z, false, true, true)
|
||
|
|
SetModelAsNoLongerNeeded(model)
|
||
|
|
PlaceObjectOnGroundProperly(obj)
|
||
|
|
FreezeEntityPosition(obj, true)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function enterLocation()
|
||
|
|
DoScreenFadeOut(500)
|
||
|
|
|
||
|
|
while not IsScreenFadedOut() do
|
||
|
|
Wait(10)
|
||
|
|
end
|
||
|
|
|
||
|
|
SetEntityCoords(cache.ped, config.insideLocation.x, config.insideLocation.y, config.insideLocation.z)
|
||
|
|
buildInteriorDesign()
|
||
|
|
DoScreenFadeIn(500)
|
||
|
|
|
||
|
|
destroyInsideZones()
|
||
|
|
registerExitTarget()
|
||
|
|
registerDutyTarget()
|
||
|
|
end
|
||
|
|
|
||
|
|
local function exitLocation()
|
||
|
|
DoScreenFadeOut(500)
|
||
|
|
|
||
|
|
while not IsScreenFadedOut() do
|
||
|
|
Wait(10)
|
||
|
|
end
|
||
|
|
|
||
|
|
SetEntityCoords(cache.ped, config.outsideLocation.x, config.outsideLocation.y, config.outsideLocation.z + 1)
|
||
|
|
DoScreenFadeIn(500)
|
||
|
|
|
||
|
|
onDuty = false
|
||
|
|
|
||
|
|
destroyInsideZones()
|
||
|
|
|
||
|
|
if carryPackage then
|
||
|
|
dropPackage()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function RegisterPickupTarget(coords)
|
||
|
|
local targetCoords = vector3(coords.x, coords.y, coords.z)
|
||
|
|
|
||
|
|
if config.useTarget then
|
||
|
|
pickupZone = exports.ox_target:addBoxZone({
|
||
|
|
name = pickupTargetID,
|
||
|
|
coords = targetCoords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(2.4, 2.35, 4.0),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
options = {
|
||
|
|
{
|
||
|
|
icon = 'fa-solid fa-house',
|
||
|
|
type = 'client',
|
||
|
|
event = 'qbx_recyclejob:client:target:pickupPackage',
|
||
|
|
label = locale("text.get_package"),
|
||
|
|
distance = 1
|
||
|
|
},
|
||
|
|
},
|
||
|
|
})
|
||
|
|
else
|
||
|
|
pickupZone = lib.zones.box({
|
||
|
|
coords = targetCoords,
|
||
|
|
rotation = 0.0,
|
||
|
|
size = vec3(2.4, 2.45, 4.0),
|
||
|
|
debug = config.debugPoly,
|
||
|
|
onEnter = function()
|
||
|
|
lib.showTextUI(locale("text.point_get_package"))
|
||
|
|
end,
|
||
|
|
onExit = function()
|
||
|
|
lib.hideTextUI()
|
||
|
|
end,
|
||
|
|
inside = function ()
|
||
|
|
if onDuty then
|
||
|
|
if not carryPackage then
|
||
|
|
if IsControlJustReleased(0, 38) then
|
||
|
|
TriggerEvent('qbx_recyclejob:client:target:pickupPackage')
|
||
|
|
lib.hideTextUI()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
})
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local function DrawPackageLocationBlip()
|
||
|
|
if not config.drawPackageLocationBlip then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
DrawMarker(2, packageCoords.x, packageCoords.y, packageCoords.z + 3, 0, 0, 0, 180.0, 0, 0, 0.5, 0.5, 0.5, 255, 255, 0, 100, false, false, 2, true, nil, nil, false)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Events
|
||
|
|
RegisterNetEvent('qbx_recyclejob:client:target:enterLocation', function()
|
||
|
|
enterLocation()
|
||
|
|
end)
|
||
|
|
|
||
|
|
RegisterNetEvent('qbx_recyclejob:client:target:exitLocation', function()
|
||
|
|
exitLocation()
|
||
|
|
end)
|
||
|
|
|
||
|
|
RegisterNetEvent('qbx_recyclejob:client:target:toggleDuty', function()
|
||
|
|
onDuty = not onDuty
|
||
|
|
|
||
|
|
if onDuty then
|
||
|
|
exports.qbx_core:Notify(locale("success.you_have_been_clocked_in"), 'success')
|
||
|
|
getRandomPackage()
|
||
|
|
else
|
||
|
|
exports.qbx_core:Notify(locale("error.you_have_clocked_out"), 'error')
|
||
|
|
destroyPickupTarget()
|
||
|
|
end
|
||
|
|
|
||
|
|
if carryPackage then
|
||
|
|
dropPackage()
|
||
|
|
end
|
||
|
|
|
||
|
|
refreshDutyTarget()
|
||
|
|
destroyDeliveryTarget()
|
||
|
|
end)
|
||
|
|
|
||
|
|
RegisterNetEvent('qbx_recyclejob:client:target:pickupPackage', function()
|
||
|
|
if not pickupZone or carryPackage then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
scrapAnim()
|
||
|
|
|
||
|
|
if lib.progressBar({
|
||
|
|
duration = config.pickupActionDuration,
|
||
|
|
label = locale("text.picking_up_the_package"),
|
||
|
|
useWhileDead = false,
|
||
|
|
canCancel = true,
|
||
|
|
disable = {
|
||
|
|
move = true,
|
||
|
|
car = true,
|
||
|
|
mouse = true,
|
||
|
|
combat = true
|
||
|
|
},
|
||
|
|
}) then
|
||
|
|
packageCoords = nil
|
||
|
|
StopAnimTask(cache.ped, 'mp_car_bomb', 'car_bomb_mechanic', 1.0)
|
||
|
|
ClearPedTasks(cache.ped)
|
||
|
|
pickupPackage()
|
||
|
|
destroyPickupTarget()
|
||
|
|
registerDeliveryTarget()
|
||
|
|
else
|
||
|
|
exports.qbx_core:Notify(locale('error.canceled'), 'error')
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
RegisterNetEvent('qbx_recyclejob:client:target:dropPackage', function()
|
||
|
|
if not carryPackage or not deliveryZone then
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
dropPackage()
|
||
|
|
scrapAnim()
|
||
|
|
destroyDeliveryTarget()
|
||
|
|
|
||
|
|
if lib.progressBar({
|
||
|
|
duration = config.deliveryActionDuration,
|
||
|
|
label = locale("text.unpacking_the_package"),
|
||
|
|
useWhileDead = false,
|
||
|
|
canCancel = true,
|
||
|
|
disable = {
|
||
|
|
move = true,
|
||
|
|
car = true,
|
||
|
|
mouse = true,
|
||
|
|
combat = true
|
||
|
|
},
|
||
|
|
}) then
|
||
|
|
StopAnimTask(cache.ped, 'mp_car_bomb', 'car_bomb_mechanic', 1.0)
|
||
|
|
TriggerServerEvent('qbx_recycle:server:getItem')
|
||
|
|
getRandomPackage()
|
||
|
|
else
|
||
|
|
exports.qbx_core:Notify(locale('error.canceled'), 'error')
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
local function startPackageBlipDraw()
|
||
|
|
CreateThread(function()
|
||
|
|
while isLoggedIn do
|
||
|
|
if onDuty and packageCoords and not carryPackage and config.drawPackageLocationBlip then
|
||
|
|
DrawPackageLocationBlip()
|
||
|
|
Wait(0)
|
||
|
|
else
|
||
|
|
Wait(500)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
AddStateBagChangeHandler('isLoggedIn', ('player:%s'):format(cache.serverId), function(_, _, loginState)
|
||
|
|
if isLoggedIn == loginState then return end
|
||
|
|
isLoggedIn = loginState
|
||
|
|
startPackageBlipDraw()
|
||
|
|
end)
|
||
|
|
|
||
|
|
CreateThread(function()
|
||
|
|
setLocationBlip()
|
||
|
|
registerEntranceTarget()
|
||
|
|
end)
|