Scripts/resources/[qb]/[qb_jobs]/qb-garbagejob/client/main.lua
2024-12-29 21:06:22 +01:00

552 lines
23 KiB
Lua

local QBCore = exports['qb-core']:GetCoreObject()
local garbageVehicle = nil
local hasBag = false
local currentStop = 0
local deliveryBlip = nil
local amountOfBags = 0
local garbageObject = nil
local endBlip = nil
local garbageBlip = nil
local canTakeBag = true
local currentStopNum = 0
local PZone = nil
local listen = false
local finished = false
local continueworking = false
local playerJob = {}
-- Handlers
-- Functions
local function setupClient()
garbageVehicle = nil
hasBag = false
currentStop = 0
deliveryBlip = nil
amountOfBags = 0
garbageObject = nil
endBlip = nil
currentStopNum = 0
if playerJob.name == Config.Jobname then
garbageBlip = AddBlipForCoord(Config.Locations["main"].coords.x, Config.Locations["main"].coords.y, Config.Locations["main"].coords.z)
SetBlipSprite(garbageBlip, 318)
SetBlipDisplay(garbageBlip, 4)
SetBlipScale(garbageBlip, 1.0)
SetBlipAsShortRange(garbageBlip, true)
SetBlipColour(garbageBlip, 39)
BeginTextCommandSetBlipName("STRING")
AddTextComponentSubstringPlayerName(Config.Locations["main"].label)
EndTextCommandSetBlipName(garbageBlip)
end
end
local function LoadAnimation(dict)
RequestAnimDict(dict)
while not HasAnimDictLoaded(dict) do Wait(10) end
end
local function BringBackCar()
DeleteVehicle(garbageVehicle)
if endBlip then
RemoveBlip(endBlip)
end
if deliveryBlip then
RemoveBlip(deliveryBlip)
end
garbageVehicle = nil
hasBag = false
currentStop = 0
deliveryBlip = nil
amountOfBags = 0
garbageObject = nil
endBlip = nil
currentStopNum = 0
end
local function DeleteZone()
listen = false
PZone:destroy()
end
local function SetRouteBack()
local depot = Config.Locations["main"].coords
endBlip = AddBlipForCoord(depot.x, depot.y, depot.z)
SetBlipSprite(endBlip, 1)
SetBlipDisplay(endBlip, 2)
SetBlipScale(endBlip, 1.0)
SetBlipAsShortRange(endBlip, false)
SetBlipColour(endBlip, 3)
BeginTextCommandSetBlipName("STRING")
AddTextComponentSubstringPlayerName(Config.Locations["vehicle"].label)
EndTextCommandSetBlipName(endBlip)
SetBlipRoute(endBlip, true)
DeleteZone()
finished = true
end
local function AnimCheck()
CreateThread(function()
local ped = PlayerPedId()
while hasBag and not IsEntityPlayingAnim(ped, 'missfbi4prepp1', '_bag_throw_garbage_man',3) do
if not IsEntityPlayingAnim(ped, 'missfbi4prepp1', '_bag_walk_garbage_man', 3) then
ClearPedTasksImmediately(ped)
LoadAnimation('missfbi4prepp1')
TaskPlayAnim(ped, 'missfbi4prepp1', '_bag_walk_garbage_man', 6.0, -6.0, -1, 49, 0, 0, 0, 0)
end
Wait(1000)
end
end)
end
local function DeliverAnim()
local ped = PlayerPedId()
LoadAnimation('missfbi4prepp1')
TaskPlayAnim(ped, 'missfbi4prepp1', '_bag_throw_garbage_man', 8.0, 8.0, 1100, 48, 0.0, 0, 0, 0)
FreezeEntityPosition(ped, true)
SetEntityHeading(ped, GetEntityHeading(garbageVehicle))
canTakeBag = false
SetTimeout(1250, function()
DetachEntity(garbageObject, 1, false)
DeleteObject(garbageObject)
TaskPlayAnim(ped, 'missfbi4prepp1', 'exit', 8.0, 8.0, 1100, 48, 0.0, 0, 0, 0)
FreezeEntityPosition(ped, false)
garbageObject = nil
canTakeBag = true
end)
if Config.UseTarget and hasBag then
local CL = Config.Locations["trashcan"][currentStop]
hasBag = false
local pos = GetEntityCoords(ped)
exports['qb-target']:RemoveTargetEntity(garbageVehicle)
if (amountOfBags - 1) <= 0 then
QBCore.Functions.TriggerCallback('garbagejob:server:NextStop', function(hasMoreStops, nextStop, newBagAmount)
if hasMoreStops and nextStop ~= 0 then
-- Here he puts your next location and you are not finished working yet.
currentStop = nextStop
currentStopNum = currentStopNum + 1
amountOfBags = newBagAmount
SetGarbageRoute()
QBCore.Functions.Notify(Lang:t("info.all_bags"))
SetVehicleDoorShut(garbageVehicle, 5, false)
else
if hasMoreStops and nextStop == currentStop then
QBCore.Functions.Notify(Lang:t("info.depot_issue"))
amountOfBags = 0
else
-- You are done with work here.
QBCore.Functions.Notify(Lang:t("info.done_working"))
SetVehicleDoorShut(garbageVehicle, 5, false)
RemoveBlip(deliveryBlip)
SetRouteBack()
amountOfBags = 0
end
end
end, currentStop, currentStopNum, pos)
else
-- You haven't delivered all bags here
amountOfBags = amountOfBags - 1
if amountOfBags > 1 then
QBCore.Functions.Notify(Lang:t("info.bags_left", { value = amountOfBags }))
else
QBCore.Functions.Notify(Lang:t("info.bags_still", { value = amountOfBags }))
end
exports['qb-target']:AddCircleZone('garbagebin', vector3(CL.coords.x, CL.coords.y, CL.coords.z), 2.0,{
name = 'garbagebin', debugPoly = false, useZ=true}, {
options = {{label = Lang:t("target.grab_garbage"),icon = 'fa-solid fa-trash', action = function() TakeAnim() end}},
distance = 2.0
})
end
end
end
function TakeAnim()
local ped = PlayerPedId()
QBCore.Functions.Progressbar("bag_pickup", Lang:t("info.picking_bag"), math.random(3000, 5000), false, true, {
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {
animDict = "anim@amb@clubhouse@tutorial@bkr_tut_ig3@",
anim = "machinic_loop_mechandplayer",
flags = 16,
}, {}, {}, function()
LoadAnimation('missfbi4prepp1')
TaskPlayAnim(ped, 'missfbi4prepp1', '_bag_walk_garbage_man', 6.0, -6.0, -1, 49, 0, 0, 0, 0)
garbageObject = CreateObject(`prop_cs_rub_binbag_01`, 0, 0, 0, true, true, true)
AttachEntityToEntity(garbageObject, ped, GetPedBoneIndex(ped, 57005), 0.12, 0.0, -0.05, 220.0, 120.0, 0.0, true, true, false, true, 1, true)
StopAnimTask(PlayerPedId(), "anim@amb@clubhouse@tutorial@bkr_tut_ig3@", "machinic_loop_mechandplayer", 1.0)
AnimCheck()
if Config.UseTarget and not hasBag then
hasBag = true
exports['qb-target']:RemoveZone("garbagebin")
exports['qb-target']:AddTargetEntity(garbageVehicle, {
options = {
{label = Lang:t("target.dispose_garbage"),icon = 'fa-solid fa-truck',action = function() DeliverAnim() end,canInteract = function() if hasBag then return true end return false end, }
},
distance = 2.0
})
end
end, function()
StopAnimTask(PlayerPedId(), "anim@amb@clubhouse@tutorial@bkr_tut_ig3@", "machinic_loop_mechandplayer", 1.0)
QBCore.Functions.Notify(Lang:t("error.cancled"), "error")
end)
end
local function RunWorkLoop()
CreateThread(function()
local GarbText = false
while listen do
local ped = PlayerPedId()
local pos = GetEntityCoords(ped)
local DeliveryData = Config.Locations["trashcan"][currentStop]
local Distance = #(pos - vector3(DeliveryData.coords.x, DeliveryData.coords.y, DeliveryData.coords.z))
if Distance < 15 or hasBag then
if not hasBag and canTakeBag then
if Distance < 1.5 then
if not GarbText then
GarbText = true
exports['qb-core']:DrawText(Lang:t("info.grab_garbage"), 'top')
end
if IsControlJustPressed(0, 51) then
hasBag = true
exports['qb-core']:HideText()
TakeAnim()
end
elseif Distance < 10 then
if GarbText then
GarbText = false
exports['qb-core']:HideText()
end
end
else
if DoesEntityExist(garbageVehicle) then
local Coords = GetOffsetFromEntityInWorldCoords(garbageVehicle, 0.0, -4.5, 0.0)
local TruckDist = #(pos - Coords)
local TrucText = false
if TruckDist < 2 then
if not TrucText then
TrucText = true
exports['qb-core']:DrawText(Lang:t("info.dispose_garbage"), 'top')
end
if IsControlJustPressed(0, 51) and hasBag then
StopAnimTask(PlayerPedId(), 'missfbi4prepp1', '_bag_walk_garbage_man', 1.0)
DeliverAnim()
QBCore.Functions.Progressbar("deliverbag", Lang:t("info.progressbar"), 2000, false, true, {
disableMovement = true,
disableCarMovement = true,
disableMouse = false,
disableCombat = true,
}, {}, {}, {}, function() -- Done
hasBag = false
canTakeBag = false
DetachEntity(garbageObject, 1, false)
DeleteObject(garbageObject)
FreezeEntityPosition(ped, false)
garbageObject = nil
canTakeBag = true
-- Looks if you have delivered all bags
if (amountOfBags - 1) <= 0 then
QBCore.Functions.TriggerCallback('garbagejob:server:NextStop', function(hasMoreStops, nextStop, newBagAmount)
if hasMoreStops and nextStop ~= 0 then
-- Here he puts your next location and you are not finished working yet.
currentStop = nextStop
currentStopNum = currentStopNum + 1
amountOfBags = newBagAmount
SetGarbageRoute()
QBCore.Functions.Notify(Lang:t("info.all_bags"))
listen = false
SetVehicleDoorShut(garbageVehicle, 5, false)
else
if hasMoreStops and nextStop == currentStop then
QBCore.Functions.Notify(Lang:t("info.depot_issue"))
amountOfBags = 0
else
-- You are done with work here.
QBCore.Functions.Notify(Lang:t("info.done_working"))
SetVehicleDoorShut(garbageVehicle, 5, false)
RemoveBlip(deliveryBlip)
SetRouteBack()
amountOfBags = 0
listen = false
end
end
end, currentStop, currentStopNum, pos)
hasBag = false
else
-- You haven't delivered all bags here
amountOfBags = amountOfBags - 1
if amountOfBags > 1 then
QBCore.Functions.Notify(Lang:t("info.bags_left", { value = amountOfBags }))
else
QBCore.Functions.Notify(Lang:t("info.bags_still", { value = amountOfBags }))
end
hasBag = false
end
Wait(1500)
if TrucText then
exports['qb-core']:HideText()
TrucText = false
end
end, function() -- Cancel
QBCore.Functions.Notify(Lang:t("error.cancled"), "error")
end)
end
end
else
QBCore.Functions.Notify(Lang:t("error.no_truck"), "error")
hasBag = false
end
end
end
Wait(1)
end
end)
end
local function CreateZone(x, y, z)
CreateThread(function()
PZone = CircleZone:Create(vector3(x, y, z), 15.0, {
name = "NewRouteWhoDis",
debugPoly = false,
})
PZone:onPlayerInOut(function(isPointInside)
if isPointInside then
if not Config.UseTarget then
listen = true
RunWorkLoop()
end
SetVehicleDoorOpen(garbageVehicle,5,false,false)
else
if not Config.UseTarget then
exports['qb-core']:HideText()
listen = false
end
SetVehicleDoorShut(garbageVehicle, 5, false)
end
end)
end)
end
function SetGarbageRoute()
local CL = Config.Locations["trashcan"][currentStop]
if deliveryBlip then
RemoveBlip(deliveryBlip)
end
deliveryBlip = AddBlipForCoord(CL.coords.x, CL.coords.y, CL.coords.z)
SetBlipSprite(deliveryBlip, 1)
SetBlipDisplay(deliveryBlip, 2)
SetBlipScale(deliveryBlip, 1.0)
SetBlipAsShortRange(deliveryBlip, false)
SetBlipColour(deliveryBlip, 27)
BeginTextCommandSetBlipName("STRING")
AddTextComponentSubstringPlayerName(Config.Locations["trashcan"][currentStop].name)
EndTextCommandSetBlipName(deliveryBlip)
SetBlipRoute(deliveryBlip, true)
finished = false
if Config.UseTarget and not hasBag then
exports['qb-target']:AddCircleZone('garbagebin', vector3(CL.coords.x, CL.coords.y, CL.coords.z), 2.0,{
name = 'garbagebin', debugPoly = false, useZ=true }, {
options = {{label = Lang:t("target.grab_garbage"), icon = 'fa-solid fa-trash', action = function() TakeAnim() end }},
distance = 2.0
})
end
if PZone then
DeleteZone()
Wait(500)
CreateZone(CL.coords.x, CL.coords.y, CL.coords.z)
else
CreateZone(CL.coords.x, CL.coords.y, CL.coords.z)
end
end
local ControlListen = false
local function Listen4Control()
ControlListen = true
CreateThread(function()
while ControlListen do
if IsControlJustReleased(0, 38) then
TriggerEvent("qb-garbagejob:client:MainMenu")
end
Wait(1)
end
end)
end
local pedsSpawned = false
local function spawnPeds()
if not Config.Peds or not next(Config.Peds) or pedsSpawned then return end
for i = 1, #Config.Peds do
local current = Config.Peds[i]
current.model = type(current.model) == 'string' and GetHashKey(current.model) or current.model
RequestModel(current.model)
while not HasModelLoaded(current.model) do
Wait(0)
end
local ped = CreatePed(0, current.model, current.coords, false, false)
FreezeEntityPosition(ped, true)
SetEntityInvincible(ped, true)
SetBlockingOfNonTemporaryEvents(ped, true)
current.pedHandle = ped
if Config.UseTarget then
exports['qb-target']:AddTargetEntity(ped, {
options = {{type = "client", event = "qb-garbagejob:client:MainMenu", label = Lang:t("target.talk"), icon = 'fa-solid fa-recycle', job = "garbage",}},
distance = 2.0
})
else
local options = current.zoneOptions
if options then
local zone = BoxZone:Create(current.coords.xyz, options.length, options.width, {
name = "zone_cityhall_" .. ped,
heading = current.coords.w,
debugPoly = false
})
zone:onPlayerInOut(function(inside)
if LocalPlayer.state.isLoggedIn then
if inside then
exports['qb-core']:DrawText(Lang:t("info.talk"), 'top')
Listen4Control()
else
ControlListen = false
exports['qb-core']:HideText()
end
end
end)
end
end
end
pedsSpawned = true
end
local function deletePeds()
if not Config.Peds or not next(Config.Peds) or not pedsSpawned then return end
for i = 1, #Config.Peds do
local current = Config.Peds[i]
if current.pedHandle then
DeletePed(current.pedHandle)
end
end
end
-- Events
RegisterNetEvent('garbagejob:client:SetWaypointHome', function()
SetNewWaypoint(Config.Locations["main"].coords.x, Config.Locations["main"].coords.y)
end)
RegisterNetEvent('qb-garbagejob:client:RequestRoute', function()
if garbageVehicle then continueworking = true TriggerServerEvent('garbagejob:server:PayShift', continueworking) end
QBCore.Functions.TriggerCallback('garbagejob:server:NewShift', function(shouldContinue, firstStop, totalBags)
if shouldContinue then
if not garbageVehicle then
local occupied = false
for _,v in pairs(Config.Locations["vehicle"].coords) do
if not IsAnyVehicleNearPoint(vector3(v.x,v.y,v.z), 2.5) then
QBCore.Functions.TriggerCallback('QBCore:Server:SpawnVehicle', function(netId)
local veh = NetToVeh(netId)
SetVehicleEngineOn(veh, false, true)
garbageVehicle = veh
SetVehicleNumberPlateText(veh, "QB-" .. tostring(math.random(1000, 9999)))
SetEntityHeading(veh, v.w)
exports['qb-fuel']:SetFuel(veh, 100.0)
SetVehicleFixed(veh)
SetEntityAsMissionEntity(veh, true, true)
SetVehicleDoorsLocked(veh, 2)
currentStop = firstStop
currentStopNum = 1
amountOfBags = totalBags
SetGarbageRoute()
TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(veh))
QBCore.Functions.Notify(Lang:t("info.deposit_paid", { value = Config.TruckPrice }))
QBCore.Functions.Notify(Lang:t("info.started"))
TriggerServerEvent("qb-garbagejob:server:payDeposit")
end, Config.Vehicle, v, false)
return
else
occupied = true
end
end
if occupied then
QBCore.Functions.Notify(Lang:t("error.all_occupied"))
end
end
currentStop = firstStop
currentStopNum = 1
amountOfBags = totalBags
SetGarbageRoute()
else
QBCore.Functions.Notify(Lang:t("info.not_enough", { value = Config.TruckPrice }))
end
end, continueworking)
end)
RegisterNetEvent('qb-garbagejob:client:RequestPaycheck', function()
if garbageVehicle then
BringBackCar()
QBCore.Functions.Notify(Lang:t("info.truck_returned"))
end
TriggerServerEvent('garbagejob:server:PayShift')
end)
RegisterNetEvent('qb-garbagejob:client:MainMenu', function()
if playerJob.name == Config.Jobname then
local MainMenu = {}
MainMenu[#MainMenu+1] = {isMenuHeader = true,header = Lang:t("menu.header")}
MainMenu[#MainMenu+1] = { header = Lang:t("menu.collect"),txt = Lang:t("menu.return_collect"),params = { event = 'qb-garbagejob:client:RequestPaycheck',}}
if not garbageVehicle or finished then
MainMenu[#MainMenu+1] = { header = Lang:t("menu.route"), txt = Lang:t("menu.request_route"), params = { event = 'qb-garbagejob:client:RequestRoute',}}
end
exports['qb-menu']:openMenu(MainMenu)
else
QBCore.Functions.Notify(Lang:t("error.job"))
end
end)
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
playerJob = QBCore.Functions.GetPlayerData().job
setupClient()
spawnPeds()
end)
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo)
playerJob = JobInfo
if garbageBlip then
RemoveBlip(garbageBlip)
end
if endBlip then
RemoveBlip(endBlip)
end
if deliveryBlip then
RemoveBlip(deliveryBlip)
end
endBlip = nil
deliveryBlip = nil
setupClient()
spawnPeds()
end)
AddEventHandler('onResourceStop', function(resource)
if GetCurrentResourceName() == resource then
if garbageObject then
DeleteEntity(garbageObject)
garbageObject = nil
end
deletePeds()
end
end)
AddEventHandler('onResourceStart', function(resource)
if GetCurrentResourceName() == resource then
playerJob = QBCore.Functions.GetPlayerData().job
setupClient()
spawnPeds()
end
end)