499 lines
14 KiB
Lua
499 lines
14 KiB
Lua
local Blips, JobBlips, isInMarker, hintToDisplay, onDuty, spawner, myPlate, vehicleObjInCaseofDrop, vehicleInCaseofDrop, vehicleMaxHealth =
|
|
{}, {}, false, "no hint to display", false, 0, {}, nil, nil, nil
|
|
|
|
local PlayerPedId = PlayerPedId
|
|
local IsPedInAnyVehicle = IsPedInAnyVehicle
|
|
local GetVehiclePedIsIn = GetVehiclePedIsIn
|
|
local GetVehicleNumberPlateText = GetVehicleNumberPlateText
|
|
local GetPedInVehicleSeat = GetPedInVehicleSeat
|
|
local GetVehicleEngineHealth = GetVehicleEngineHealth
|
|
|
|
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
|
|
ESX.PlayerLoaded = true
|
|
refreshBlips()
|
|
end)
|
|
|
|
RegisterNetEvent('esx:onPlayerLogout', function()
|
|
ESX.PlayerLoaded = false
|
|
end)
|
|
|
|
function OpenMenu()
|
|
local elements = {
|
|
{ unselectable = true, icon = "fas fa-shirt", title = TranslateCap('cloakroom') },
|
|
{ icon = "fas fa-shirt", title = TranslateCap('job_wear'), value = "job_wear" },
|
|
{ icon = "fas fa-shirt", title = TranslateCap('citizen_wear'), value = "citizen_wear" },
|
|
}
|
|
|
|
ESX.OpenContext("right", elements, function(menu, element)
|
|
if element.value == "citizen_wear" then
|
|
onDuty = false
|
|
ESX.ShowNotification(TranslateCap('offduty'), "success")
|
|
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
|
|
local isMale = skin.sex == 0
|
|
|
|
TriggerEvent('skinchanger:loadDefaultModel', isMale, function()
|
|
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
|
|
TriggerEvent('skinchanger:loadSkin', skin)
|
|
end)
|
|
end)
|
|
end)
|
|
elseif element.value == "job_wear" then
|
|
onDuty = true
|
|
ESX.ShowNotification(TranslateCap('onduty'), "success")
|
|
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
|
|
if skin.sex == 0 then
|
|
if ESX.Table.SizeOf(jobSkin.skin_male) >= 1 then
|
|
TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male)
|
|
else
|
|
ESX.ShowNotification(TranslateCap('no_male_clothing'), "error")
|
|
end
|
|
else
|
|
if ESX.Table.SizeOf(jobSkin.skin_female) >= 1 then
|
|
TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female)
|
|
else
|
|
ESX.ShowNotification(TranslateCap('no_female_clothing'), "error")
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
end)
|
|
end
|
|
|
|
AddEventHandler('esx_jobs:action', function(job, zone, zoneKey)
|
|
menuIsShowed = true
|
|
local playerJob = ESX.PlayerData.job.name
|
|
if zone.Type == "cloakroom" then
|
|
OpenMenu()
|
|
elseif zone.Type == "work" then
|
|
local playerPed = PlayerPedId()
|
|
|
|
if IsPedInAnyVehicle(playerPed, false) then
|
|
ESX.ShowNotification(TranslateCap('foot_work'))
|
|
else
|
|
TriggerServerEvent('esx_jobs:startWork', zone.Item, zoneKey)
|
|
end
|
|
elseif zone.Type == "vehspawner" then
|
|
local spawnPoint = nil
|
|
local vehicle = nil
|
|
|
|
for k, v in pairs(Config.Jobs) do
|
|
if playerJob == k then
|
|
for l, w in pairs(v.Zones) do
|
|
if w.Type == "vehspawnpt" and w.Spawner == zone.Spawner then
|
|
spawnPoint = w
|
|
spawner = w.Spawner
|
|
end
|
|
end
|
|
|
|
for m, x in pairs(v.Vehicles) do
|
|
if x.Spawner == zone.Spawner then
|
|
vehicle = x
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if ESX.Game.IsSpawnPointClear(spawnPoint.Pos, 5.0) then
|
|
spawnVehicle(spawnPoint, vehicle, zone.Caution)
|
|
else
|
|
ESX.ShowNotification(TranslateCap('spawn_blocked'))
|
|
end
|
|
elseif zone.Type == "vehdelete" then
|
|
local looping = true
|
|
|
|
for k, v in pairs(Config.Jobs) do
|
|
if playerJob == k then
|
|
for l, w in pairs(v.Zones) do
|
|
if w.Type == "vehdelete" and w.Spawner == zone.Spawner then
|
|
local playerPed = PlayerPedId()
|
|
|
|
if IsPedInAnyVehicle(playerPed, false) then
|
|
local vehicle = GetVehiclePedIsIn(playerPed, false)
|
|
local plate = GetVehicleNumberPlateText(vehicle)
|
|
plate = string.gsub(plate, " ", "")
|
|
local driverPed = GetPedInVehicleSeat(vehicle, -1)
|
|
local vehicleMaxHealth = GetVehicleEngineHealth(vehicle)
|
|
|
|
if playerPed == driverPed then
|
|
for i = 1, #myPlate, 1 do
|
|
if myPlate[i] == plate then
|
|
local vehicleHealth = GetVehicleEngineHealth(vehicleInCaseofDrop)
|
|
local giveBack = ESX.Math.Round(vehicleHealth / vehicleMaxHealth, 2)
|
|
|
|
TriggerServerEvent('esx_jobs:caution', "give_back", giveBack, 0, 0)
|
|
DeleteVehicle(GetVehiclePedIsIn(playerPed, false))
|
|
|
|
if w.Teleport ~= 0 then
|
|
ESX.Game.Teleport(playerPed, w.Teleport)
|
|
end
|
|
|
|
table.remove(myPlate, i)
|
|
|
|
if vehicleObjInCaseofDrop.HasCaution then
|
|
vehicleInCaseofDrop = nil
|
|
vehicleObjInCaseofDrop = nil
|
|
vehicleMaxHealth = nil
|
|
end
|
|
|
|
break
|
|
end
|
|
end
|
|
else
|
|
ESX.ShowNotification(TranslateCap('not_your_vehicle'))
|
|
end
|
|
end
|
|
|
|
looping = false
|
|
break
|
|
end
|
|
|
|
if looping == false then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
if looping == false then
|
|
break
|
|
end
|
|
end
|
|
elseif zone.Type == "delivery" then
|
|
if Blips['delivery'] ~= nil then
|
|
RemoveBlip(Blips['delivery'])
|
|
Blips['delivery'] = nil
|
|
end
|
|
TriggerServerEvent('esx_jobs:startWork', zone.Item, zoneKey)
|
|
end
|
|
--nextStep(zone.GPS)
|
|
end)
|
|
|
|
function nextStep(gps)
|
|
if gps == 0 then return end
|
|
if Blips['delivery'] ~= nil then
|
|
RemoveBlip(Blips['delivery'])
|
|
Blips['delivery'] = nil
|
|
end
|
|
|
|
Blips['delivery'] = AddBlipForCoord(gps.x, gps.y, gps.z)
|
|
SetBlipRoute(Blips['delivery'], true)
|
|
ESX.ShowNotification(TranslateCap('next_point'))
|
|
end
|
|
|
|
AddEventHandler('esx_jobs:hasExitedMarker', function(zone)
|
|
TriggerServerEvent('esx_jobs:stopWork')
|
|
menuIsShowed = false
|
|
isInMarker = false
|
|
end)
|
|
|
|
RegisterNetEvent('esx:setJob', function(job)
|
|
ESX.PlayerData.job = job
|
|
onDuty = false
|
|
myPlate = {} -- loosing vehicle caution in case player changes job.
|
|
spawner = 0
|
|
deleteBlips()
|
|
refreshBlips()
|
|
end)
|
|
|
|
function deleteBlips()
|
|
if JobBlips[1] ~= nil then
|
|
for i = 1, #JobBlips, 1 do
|
|
RemoveBlip(JobBlips[i])
|
|
JobBlips[i] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
function refreshBlips()
|
|
local zones = {}
|
|
local blipInfo = {}
|
|
|
|
while not ESX.PlayerLoaded do
|
|
Wait(500)
|
|
end
|
|
|
|
local playerJob = ESX.PlayerData.job?.name
|
|
|
|
for jobKey, jobValues in pairs(Config.Jobs) do
|
|
if jobKey == playerJob then
|
|
for zoneKey, zoneValues in pairs(jobValues.Zones) do
|
|
if not zoneValues.Blip then goto continue end
|
|
local _Pos = {}
|
|
if not (zoneValues.Zone) then
|
|
_Pos = zoneValues.Pos
|
|
end
|
|
TriggerEvent("izone:getZoneCenter", zoneValues.Zone, function(_center)
|
|
if (_center) then
|
|
_Pos = _center
|
|
end
|
|
end)
|
|
local blip = AddBlipForCoord(_Pos.x, _Pos.y, _Pos.z)
|
|
SetBlipSprite(blip, jobValues.BlipInfos.Sprite)
|
|
SetBlipDisplay(blip, 4)
|
|
SetBlipScale(blip, 0.8)
|
|
SetBlipCategory(blip, 3)
|
|
SetBlipColour(blip, jobValues.BlipInfos.Color)
|
|
SetBlipAsShortRange(blip, true)
|
|
|
|
BeginTextCommandSetBlipName("STRING")
|
|
AddTextComponentSubstringPlayerName(zoneValues.Name)
|
|
EndTextCommandSetBlipName(blip)
|
|
table.insert(JobBlips, blip)
|
|
|
|
::continue::
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function spawnVehicle(spawnPoint, vehicle, vehicleCaution)
|
|
hintIsShowed = false
|
|
TriggerServerEvent('esx_jobs:caution', 'take', vehicleCaution, spawnPoint, vehicle)
|
|
end
|
|
|
|
RegisterNetEvent('esx_jobs:spawnJobVehicle', function(spawnPoint, vehicle)
|
|
local playerPed = PlayerPedId()
|
|
|
|
ESX.Game.SpawnVehicle(vehicle.Hash, spawnPoint.Pos, spawnPoint.Heading, function(spawnedVehicle)
|
|
if vehicle.Trailer ~= "none" then
|
|
ESX.Game.SpawnVehicle(vehicle.Trailer, spawnPoint.Pos, spawnPoint.Heading, function(trailer)
|
|
AttachVehicleToTrailer(spawnedVehicle, trailer, 1.1)
|
|
end)
|
|
end
|
|
|
|
-- save & set plate
|
|
local plate = 'WORK' .. math.random(100, 900)
|
|
SetVehicleNumberPlateText(spawnedVehicle, plate)
|
|
table.insert(myPlate, plate)
|
|
plate = string.gsub(plate, " ", "")
|
|
|
|
TaskWarpPedIntoVehicle(playerPed, spawnedVehicle, -1)
|
|
|
|
if not vehicle.HasCaution then return end
|
|
vehicleInCaseofDrop = spawnedVehicle
|
|
vehicleObjInCaseofDrop = vehicle
|
|
vehicleMaxHealth = GetVehicleEngineHealth(spawnedVehicle)
|
|
end)
|
|
end)
|
|
|
|
-- Display markers (only if on duty and the player's job ones)
|
|
CreateThread(function()
|
|
while true do
|
|
local Sleep = 1500
|
|
local zones = {}
|
|
|
|
if ESX.PlayerLoaded then
|
|
local playerJob = ESX.PlayerData.job.name
|
|
|
|
if playerJob then
|
|
for k, v in pairs(Config.Jobs) do
|
|
if playerJob == k then
|
|
Sleep = 0
|
|
zones = v.Zones
|
|
end
|
|
end
|
|
|
|
local coords = GetEntityCoords(PlayerPedId())
|
|
for k, v in pairs(zones) do
|
|
if onDuty or v.Type == "cloakroom" then
|
|
if (v.Zone) then
|
|
TriggerEvent("izone:getZoneCenter", v.Zone, function(center)
|
|
if (not (center == nil)) then
|
|
if (v.Marker ~= -1 and #(coords - center) < Config.DrawDistance) then
|
|
Sleep = 0
|
|
DrawMarker(v.Marker, center.x, center.y, center.z - 1, 0.0, 0.0, 0.0, 0, 0.0, 0.0,
|
|
v.Size.x, v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false,
|
|
true,
|
|
2, false, false, false, false)
|
|
end
|
|
end
|
|
end)
|
|
else
|
|
local Pos = vector3(v.Pos.x, v.Pos.y, v.Pos.z)
|
|
if (v.Marker ~= -1 and #(coords - Pos) < Config.DrawDistance) then
|
|
Sleep = 0
|
|
DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x,
|
|
v.Size.y, v.Size.z, v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false,
|
|
false,
|
|
false, false)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
Wait(Sleep)
|
|
end
|
|
end)
|
|
|
|
-- Display public markers
|
|
CreateThread(function()
|
|
while true do
|
|
local Sleep = 1500
|
|
local coords = GetEntityCoords(PlayerPedId())
|
|
for k, v in pairs(Config.PublicZones) do
|
|
if (v.Marker ~= -1 and #(coords - v.Pos) < Config.DrawDistance) then
|
|
Sleep = 0
|
|
DrawMarker(v.Marker, v.Pos.x, v.Pos.y, v.Pos.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z,
|
|
v.Color.r, v.Color.g, v.Color.b, 100, false, true, 2, false, false, false, false)
|
|
end
|
|
end
|
|
Wait(Sleep)
|
|
end
|
|
end)
|
|
|
|
-- Activate public marker
|
|
CreateThread(function()
|
|
while true do
|
|
local Sleep = 1500
|
|
local coords = GetEntityCoords(PlayerPedId())
|
|
|
|
for k, v in pairs(Config.PublicZones) do
|
|
if #(coords - v.Pos) < v.Size.x / 2 then
|
|
Sleep = 0
|
|
ESX.ShowHelpNotification(v.Hint)
|
|
hintIsShowed = true
|
|
if IsControlJustReleased(0, 38) then
|
|
ESX.Game.Teleport(PlayerPedId(), v.Teleport)
|
|
end
|
|
end
|
|
end
|
|
|
|
Wait(Sleep)
|
|
end
|
|
end)
|
|
|
|
-- Activate menu when player is inside marker
|
|
CreateThread(function()
|
|
while true do
|
|
local Sleep = 500
|
|
|
|
if ESX.PlayerLoaded then
|
|
local playerJob = ESX.PlayerData.job.name
|
|
|
|
if playerJob and playerJob ~= 'unemployed' then
|
|
local zones = nil
|
|
local job = nil
|
|
|
|
for k, v in pairs(Config.Jobs) do
|
|
if playerJob == k then
|
|
Sleep = 0
|
|
job = v
|
|
zones = v.Zones
|
|
end
|
|
end
|
|
|
|
if zones then
|
|
local coords = GetEntityCoords(PlayerPedId())
|
|
local currentZone = nil
|
|
local zone = nil
|
|
local lastZone = nil
|
|
|
|
for k, v in pairs(zones) do
|
|
-- If we defined a zone from iZone
|
|
if v.Zone then
|
|
TriggerEvent("izone:isPlayerInZone", v.Zone, function(isIn)
|
|
if isIn then
|
|
Sleep = 0
|
|
isInMarker = true
|
|
currentZone = k
|
|
zone = v
|
|
return
|
|
else
|
|
isInMarker = false
|
|
end
|
|
end)
|
|
-- Because we were in a routine
|
|
if isInMarker then
|
|
break
|
|
end
|
|
-- Else use radius defined from center
|
|
else
|
|
local Pos = vector3(v.Pos.x, v.Pos.y, v.Pos.z)
|
|
if #(coords - Pos) < v.Size.x then
|
|
Sleep = 0
|
|
isInMarker = true
|
|
currentZone = k
|
|
zone = v
|
|
break
|
|
else
|
|
isInMarker = false
|
|
end
|
|
end
|
|
end
|
|
|
|
if IsControlJustReleased(0, 38) and not menuIsShowed and isInMarker then
|
|
if onDuty or zone.Type == "cloakroom" then
|
|
TriggerEvent('esx_jobs:action', job, zone, currentZone)
|
|
end
|
|
end
|
|
|
|
-- hide or show top left zone hints
|
|
if isInMarker and not menuIsShowed then
|
|
hintIsShowed = true
|
|
if (onDuty or zone.Type == "cloakroom") and zone.Type ~= "vehdelete" then
|
|
if zone.Hint then
|
|
hintToDisplay = zone.Hint
|
|
ESX.ShowHelpNotification(hintToDisplay)
|
|
end
|
|
elseif zone.Type == "vehdelete" and (onDuty) then
|
|
local playerPed = PlayerPedId()
|
|
|
|
if IsPedInAnyVehicle(playerPed, false) then
|
|
local vehicle = GetVehiclePedIsIn(playerPed, false)
|
|
local driverPed = GetPedInVehicleSeat(vehicle, -1)
|
|
local plate = GetVehicleNumberPlateText(vehicle)
|
|
plate = string.gsub(plate, " ", "")
|
|
|
|
if playerPed == driverPed then
|
|
for i = 1, #myPlate, 1 do
|
|
if myPlate[i] == plate then
|
|
hintToDisplay = zone.Hint
|
|
break
|
|
end
|
|
end
|
|
else
|
|
hintToDisplay = TranslateCap('not_your_vehicle')
|
|
ESX.ShowHelpNotification(hintToDisplay)
|
|
end
|
|
else
|
|
hintToDisplay = TranslateCap('in_vehicle')
|
|
ESX.ShowHelpNotification(hintToDisplay)
|
|
end
|
|
hintIsShowed = true
|
|
elseif onDuty and zone.Spawner ~= spawner then
|
|
hintToDisplay = TranslateCap('wrong_point')
|
|
ESX.ShowHelpNotification(hintToDisplay)
|
|
end
|
|
end
|
|
|
|
if isInMarker and not hasAlreadyEnteredMarker then
|
|
hasAlreadyEnteredMarker = true
|
|
end
|
|
|
|
if not isInMarker and hasAlreadyEnteredMarker then
|
|
hasAlreadyEnteredMarker = false
|
|
TriggerEvent('esx_jobs:hasExitedMarker', zone)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
Wait(Sleep)
|
|
end
|
|
end)
|
|
|
|
if Config.RequestIPL then
|
|
CreateThread(function()
|
|
-- Slaughterer
|
|
RemoveIpl("CS1_02_cf_offmission")
|
|
RequestIpl("CS1_02_cf_onmission1")
|
|
RequestIpl("CS1_02_cf_onmission2")
|
|
RequestIpl("CS1_02_cf_onmission3")
|
|
RequestIpl("CS1_02_cf_onmission4")
|
|
-- Tailor
|
|
RequestIpl("id2_14_during_door")
|
|
RequestIpl("id2_14_during1")
|
|
end)
|
|
end
|
|
|
|
if ESX.PlayerLoaded then refreshBlips() end
|