diff --git a/server-data/resources/[bpt_addons]/bpt_ambulancejob/client/job.lua b/server-data/resources/[bpt_addons]/bpt_ambulancejob/client/job.lua index 6e0a1859d..fc42b586a 100644 --- a/server-data/resources/[bpt_addons]/bpt_ambulancejob/client/job.lua +++ b/server-data/resources/[bpt_addons]/bpt_ambulancejob/client/job.lua @@ -4,562 +4,472 @@ local isBusy, deadPlayers, deadPlayerBlips, isOnDuty, vehicle = false, {}, {}, f local isInShopMenu = false function OpenAmbulanceActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = "Ambulance Actions" }, - { icon = "fas fa-shirt", title = TranslateCap("cloakroom"), value = "cloakroom" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-ambulance", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "cloakroom" then - OpenCloakroomMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "ambulance", function(_, menu) - menu.close() - end, { wash = false }) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = "Ambulance Actions" }, + { icon = "fas fa-shirt", title = TranslateCap("cloakroom"), value = "cloakroom" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-ambulance", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "cloakroom" then + OpenCloakroomMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "ambulance", function(_, menu) + menu.close() + end, { wash = false }) + end + end) end function OpenMobileAmbulanceActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-ambulance", title = TranslateCap("ambulance") }, - { icon = "fas fa-ambulance", title = TranslateCap("ems_menu"), value = "citizen_interaction" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "citizen_interaction" then - local elements2 = { - { unselectable = true, icon = "fas fa-ambulance", title = element.title }, - { icon = "fas fa-syringe", title = TranslateCap("ems_menu_revive"), value = "revive" }, - { icon = "fas fa-bandage", title = TranslateCap("ems_menu_small"), value = "small" }, - { icon = "fas fa-bandage", title = TranslateCap("ems_menu_big"), value = "big" }, - { icon = "fas fa-car", title = TranslateCap("ems_menu_putincar"), value = "put_in_vehicle" }, - { icon = "fas fa-syringe", title = TranslateCap("ems_menu_search"), value = "search" }, - { icon = "fas fa-syringe", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements2, function(_, element2) - if isBusy then - return - end - - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if element2.value == "search" then - TriggerServerEvent("bpt_ambulancejob:svsearch") - elseif closestPlayer == -1 or closestDistance > 1.0 then - ESX.ShowNotification(TranslateCap("no_players")) - else - if element2.value == "revive" then - revivePlayer(closestPlayer) - elseif element2.value == "small" then - ESX.TriggerServerCallback("bpt_ambulancejob:getItemAmount", function(quantity) - if quantity > 0 then - local closestPlayerPed = GetPlayerPed(closestPlayer) - local health = GetEntityHealth(closestPlayerPed) - - if health > 0 then - local playerPed = PlayerPedId() - - isBusy = true - ESX.ShowNotification(TranslateCap("heal_inprogress")) - TaskStartScenarioInPlace(playerPed, "CODE_HUMAN_MEDIC_TEND_TO_DEAD", 0, true) - Wait(10000) - ClearPedTasks(playerPed) - - TriggerServerEvent("bpt_ambulancejob:removeItem", "bandage") - TriggerServerEvent("bpt_ambulancejob:heal", GetPlayerServerId(closestPlayer), "small") - ESX.ShowNotification(TranslateCap("heal_complete", GetPlayerName(closestPlayer))) - isBusy = false - else - ESX.ShowNotification(TranslateCap("player_not_conscious")) - end - else - ESX.ShowNotification(TranslateCap("not_enough_bandage")) - end - end, "bandage") - elseif element2.value == "big" then - ESX.TriggerServerCallback("bpt_ambulancejob:getItemAmount", function(quantity) - if quantity > 0 then - local closestPlayerPed = GetPlayerPed(closestPlayer) - local health = GetEntityHealth(closestPlayerPed) - - if health > 0 then - local playerPed = PlayerPedId() - - isBusy = true - ESX.ShowNotification(TranslateCap("heal_inprogress")) - TaskStartScenarioInPlace(playerPed, "CODE_HUMAN_MEDIC_TEND_TO_DEAD", 0, true) - Wait(10000) - ClearPedTasks(playerPed) - - TriggerServerEvent("bpt_ambulancejob:removeItem", "medikit") - TriggerServerEvent("bpt_ambulancejob:heal", GetPlayerServerId(closestPlayer), "big") - ESX.ShowNotification(TranslateCap("heal_complete", GetPlayerName(closestPlayer))) - isBusy = false - else - ESX.ShowNotification(TranslateCap("player_not_conscious")) - end - else - ESX.ShowNotification(TranslateCap("not_enough_medikit")) - end - end, "medikit") - elseif element2.value == "put_in_vehicle" then - TriggerServerEvent("bpt_ambulancejob:putInVehicle", GetPlayerServerId(closestPlayer)) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-ambulance", title = TranslateCap("ambulance") }, + { icon = "fas fa-ambulance", title = TranslateCap("ems_menu"), value = "citizen_interaction" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "citizen_interaction" then + local elements2 = { + { unselectable = true, icon = "fas fa-ambulance", title = element.title }, + { icon = "fas fa-syringe", title = TranslateCap("ems_menu_revive"), value = "revive" }, + { icon = "fas fa-bandage", title = TranslateCap("ems_menu_small"), value = "small" }, + { icon = "fas fa-bandage", title = TranslateCap("ems_menu_big"), value = "big" }, + { icon = "fas fa-car", title = TranslateCap("ems_menu_putincar"), value = "put_in_vehicle" }, + { icon = "fas fa-syringe", title = TranslateCap("ems_menu_search"), value = "search" }, + { icon = "fas fa-syringe", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements2, function(_, element2) + if isBusy then + return + end + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if element2.value == "search" then + TriggerServerEvent("bpt_ambulancejob:svsearch") + elseif closestPlayer == -1 or closestDistance > 1.0 then + ESX.ShowNotification(TranslateCap("no_players")) + else + if element2.value == "revive" then + revivePlayer(closestPlayer) + elseif element2.value == "small" then + ESX.TriggerServerCallback("bpt_ambulancejob:getItemAmount", function(quantity) + if quantity > 0 then + local closestPlayerPed = GetPlayerPed(closestPlayer) + local health = GetEntityHealth(closestPlayerPed) + + if health > 0 then + local playerPed = PlayerPedId() + + isBusy = true + ESX.ShowNotification(TranslateCap("heal_inprogress")) + TaskStartScenarioInPlace(playerPed, "CODE_HUMAN_MEDIC_TEND_TO_DEAD", 0, true) + Wait(10000) + ClearPedTasks(playerPed) + + TriggerServerEvent("bpt_ambulancejob:removeItem", "bandage") + TriggerServerEvent("bpt_ambulancejob:heal", GetPlayerServerId(closestPlayer), "small") + ESX.ShowNotification(TranslateCap("heal_complete", GetPlayerName(closestPlayer))) + isBusy = false + else + ESX.ShowNotification(TranslateCap("player_not_conscious")) + end + else + ESX.ShowNotification(TranslateCap("not_enough_bandage")) + end + end, "bandage") + elseif element2.value == "big" then + ESX.TriggerServerCallback("bpt_ambulancejob:getItemAmount", function(quantity) + if quantity > 0 then + local closestPlayerPed = GetPlayerPed(closestPlayer) + local health = GetEntityHealth(closestPlayerPed) + + if health > 0 then + local playerPed = PlayerPedId() + + isBusy = true + ESX.ShowNotification(TranslateCap("heal_inprogress")) + TaskStartScenarioInPlace(playerPed, "CODE_HUMAN_MEDIC_TEND_TO_DEAD", 0, true) + Wait(10000) + ClearPedTasks(playerPed) + + TriggerServerEvent("bpt_ambulancejob:removeItem", "medikit") + TriggerServerEvent("bpt_ambulancejob:heal", GetPlayerServerId(closestPlayer), "big") + ESX.ShowNotification(TranslateCap("heal_complete", GetPlayerName(closestPlayer))) + isBusy = false + else + ESX.ShowNotification(TranslateCap("player_not_conscious")) + end + else + ESX.ShowNotification(TranslateCap("not_enough_medikit")) + end + end, "medikit") + elseif element2.value == "put_in_vehicle" then + TriggerServerEvent("bpt_ambulancejob:putInVehicle", GetPlayerServerId(closestPlayer)) + end + end + end) + end + end) end -- billing if billing == "billing" then - ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "billing", { - title = TranslateCap("invoice_amount"), - }, function(data, menu) - local amount = tonumber(data.value) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - menu.close() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent("esx_billing:sendBill", GetPlayerServerId(closestPlayer), "society_ambulance", - "Ambulance", amount) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end, function(_, menu) - menu.close() - end) + ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "billing", { + title = TranslateCap("invoice_amount"), + }, function(data, menu) + local amount = tonumber(data.value) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + menu.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_ambulance", "Ambulance", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end, function(_, menu) + menu.close() + end) end -- end billing function revivePlayer(closestPlayer) - isBusy = true - - ESX.TriggerServerCallback("bpt_ambulancejob:getItemAmount", function(quantity) - if quantity > 0 then - local closestPlayerPed = GetPlayerPed(closestPlayer) - - if IsPedDeadOrDying(closestPlayerPed, 1) then - local playerPed = PlayerPedId() - local lib, anim = "mini@cpr@char_a@cpr_str", "cpr_pumpchest" - ESX.ShowNotification(TranslateCap("revive_inprogress")) - - for _ = 1, 15 do - Wait(900) - - ESX.Streaming.RequestAnimDict(lib, function() - TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0.0, false, false, false) - end) - end - - TriggerServerEvent("bpt_ambulancejob:removeItem", "medikit") - TriggerServerEvent("bpt_ambulancejob:revive", GetPlayerServerId(closestPlayer)) - else - ESX.ShowNotification(TranslateCap("player_notTranslateCapnconscious")) - end - else - ESX.ShowNotification(TranslateCap("not_enough_medikit")) - end - isBusy = false - end, "medikit") + isBusy = true + + ESX.TriggerServerCallback("bpt_ambulancejob:getItemAmount", function(quantity) + if quantity > 0 then + local closestPlayerPed = GetPlayerPed(closestPlayer) + + if IsPedDeadOrDying(closestPlayerPed, 1) then + local playerPed = PlayerPedId() + local lib, anim = "mini@cpr@char_a@cpr_str", "cpr_pumpchest" + ESX.ShowNotification(TranslateCap("revive_inprogress")) + + for _ = 1, 15 do + Wait(900) + + ESX.Streaming.RequestAnimDict(lib, function() + TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0.0, false, false, false) + end) + end + + TriggerServerEvent("bpt_ambulancejob:removeItem", "medikit") + TriggerServerEvent("bpt_ambulancejob:revive", GetPlayerServerId(closestPlayer)) + else + ESX.ShowNotification(TranslateCap("player_notTranslateCapnconscious")) + end + else + ESX.ShowNotification(TranslateCap("not_enough_medikit")) + end + isBusy = false + end, "medikit") end function FastTravel(coords, heading) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() - DoScreenFadeOut(800) + DoScreenFadeOut(800) - while not IsScreenFadedOut() do - Wait(500) - end + while not IsScreenFadedOut() do + Wait(500) + end - ESX.Game.Teleport(playerPed, coords, function() - DoScreenFadeIn(800) + ESX.Game.Teleport(playerPed, coords, function() + DoScreenFadeIn(800) - if heading then - SetEntityHeading(playerPed, heading) - end - end) + if heading then + SetEntityHeading(playerPed, heading) + end + end) end -- Draw markers & Marker logic CreateThread(function() - while true do - Wait(0) - - if ESX.PlayerData.job and ESX.PlayerData.job.name == "ambulance" then - local playerCoords = GetEntityCoords(PlayerPedId()) - local letSleep, isInMarker, hasExited = true, false, false - local currentHospital, currentPart, currentPartNum - - for hospitalNum, hospital in pairs(Config.Hospitals) do - -- Ambulance Actions - for k, v in ipairs(hospital.AmbulanceActions) do - local distance = #(playerCoords - v) - - if distance < Config.DrawDistance then - DrawMarker( - Config.Marker.type, - v, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - Config.Marker.x, - Config.Marker.y, - Config.Marker.z, - Config.Marker.r, - Config.Marker.g, - Config.Marker.b, - Config.Marker.a, - false, - false, - 2, - Config.Marker.rotate, - nil, - nil, - false - ) - letSleep = false - - if distance < Config.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = - true, hospitalNum, "AmbulanceActions", k - end - end - end - - -- Vehicle Spawners - for k, v in ipairs(hospital.Vehicles) do - local distance = #(playerCoords - v.Spawner) - - if distance < Config.DrawDistance then - DrawMarker( - v.Marker.type, - v.Spawner, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - v.Marker.x, - v.Marker.y, - v.Marker.z, - v.Marker.r, - v.Marker.g, - v.Marker.b, - v.Marker.a, - false, - false, - 2, - v.Marker.rotate, - nil, - nil, - false - ) - letSleep = false - - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, "Vehicles", k - end - end - end - - -- Helicopter Spawners - for k, v in ipairs(hospital.Helicopters) do - local distance = #(playerCoords - v.Spawner) - - if distance < Config.DrawDistance then - DrawMarker( - v.Marker.type, - v.Spawner, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - v.Marker.x, - v.Marker.y, - v.Marker.z, - v.Marker.r, - v.Marker.g, - v.Marker.b, - v.Marker.a, - false, - false, - 2, - v.Marker.rotate, - nil, - nil, - false - ) - letSleep = false - - if distance < v.Marker.x then - isInMarker, currentHospital, currentPart, currentPartNum = - true, hospitalNum, "Helicopters", k - end - end - end - end - - -- Logic for exiting & entering markers - if - isInMarker and not HasAlreadyEnteredMarker - or ( - isInMarker - and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) - ) - then - if - (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) - and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) - then - TriggerEvent("bpt_ambulancejob:hasExitedMarker", LastHospital, LastPart, LastPartNum) - hasExited = true - end - - HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = - true, currentHospital, currentPart, currentPartNum - - TriggerEvent("bpt_ambulancejob:hasEnteredMarker", currentHospital, currentPart, currentPartNum) - end - - if not hasExited and not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_ambulancejob:hasExitedMarker", LastHospital, LastPart, LastPartNum) - end - - if letSleep then - Wait(500) - end - else - Wait(500) - end - end + while true do + Wait(0) + + if ESX.PlayerData.job and ESX.PlayerData.job.name == "ambulance" then + local playerCoords = GetEntityCoords(PlayerPedId()) + local letSleep, isInMarker, hasExited = true, false, false + local currentHospital, currentPart, currentPartNum + + for hospitalNum, hospital in pairs(Config.Hospitals) do + -- Ambulance Actions + for k, v in ipairs(hospital.AmbulanceActions) do + local distance = #(playerCoords - v) + + if distance < Config.DrawDistance then + DrawMarker(Config.Marker.type, v, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, Config.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < Config.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, "AmbulanceActions", k + end + end + end + + -- Vehicle Spawners + for k, v in ipairs(hospital.Vehicles) do + local distance = #(playerCoords - v.Spawner) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, "Vehicles", k + end + end + end + + -- Helicopter Spawners + for k, v in ipairs(hospital.Helicopters) do + local distance = #(playerCoords - v.Spawner) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < v.Marker.x then + isInMarker, currentHospital, currentPart, currentPartNum = true, hospitalNum, "Helicopters", k + end + end + end + end + + -- Logic for exiting & entering markers + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then + if (LastHospital ~= nil and LastPart ~= nil and LastPartNum ~= nil) and (LastHospital ~= currentHospital or LastPart ~= currentPart or LastPartNum ~= currentPartNum) then + TriggerEvent("bpt_ambulancejob:hasExitedMarker", LastHospital, LastPart, LastPartNum) + hasExited = true + end + + HasAlreadyEnteredMarker, LastHospital, LastPart, LastPartNum = true, currentHospital, currentPart, currentPartNum + + TriggerEvent("bpt_ambulancejob:hasEnteredMarker", currentHospital, currentPart, currentPartNum) + end + + if not hasExited and not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_ambulancejob:hasExitedMarker", LastHospital, LastPart, LastPartNum) + end + + if letSleep then + Wait(500) + end + else + Wait(500) + end + end end) -- Fast travels CreateThread(function() - while true do - Wait(0) - local playerCoords, letSleep = GetEntityCoords(PlayerPedId()), true - - for _, hospital in pairs(Config.Hospitals) do - -- Fast Travels - for _, v in ipairs(hospital.FastTravels) do - local distance = #(playerCoords - v.From) - - if distance < Config.DrawDistance then - DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, - v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, - v.Marker.rotate, nil, nil, false) - letSleep = false - - if distance < v.Marker.x then - FastTravel(v.To.coords, v.To.heading) - end - end - end - end - - if letSleep then - Wait(500) - end - end + while true do + Wait(0) + local playerCoords, letSleep = GetEntityCoords(PlayerPedId()), true + + for _, hospital in pairs(Config.Hospitals) do + -- Fast Travels + for _, v in ipairs(hospital.FastTravels) do + local distance = #(playerCoords - v.From) + + if distance < Config.DrawDistance then + DrawMarker(v.Marker.type, v.From, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Marker.x, v.Marker.y, v.Marker.z, v.Marker.r, v.Marker.g, v.Marker.b, v.Marker.a, false, false, 2, v.Marker.rotate, nil, nil, false) + letSleep = false + + if distance < v.Marker.x then + FastTravel(v.To.coords, v.To.heading) + end + end + end + end + + if letSleep then + Wait(500) + end + end end) AddEventHandler("bpt_ambulancejob:hasEnteredMarker", function(hospital, part, partNum) - if part == "AmbulanceActions" then - CurrentAction = part - CurrentActionMsg = TranslateCap("actions_prompt") - CurrentActionData = {} - elseif part == "Vehicles" then - CurrentAction = part - CurrentActionMsg = TranslateCap("garage_prompt") - CurrentActionData = { hospital = hospital, partNum = partNum } - elseif part == "Helicopters" then - CurrentAction = part - CurrentActionMsg = TranslateCap("helicopter_prompt") - CurrentActionData = { hospital = hospital, partNum = partNum } - end + if part == "AmbulanceActions" then + CurrentAction = part + CurrentActionMsg = TranslateCap("actions_prompt") + CurrentActionData = {} + elseif part == "Vehicles" then + CurrentAction = part + CurrentActionMsg = TranslateCap("garage_prompt") + CurrentActionData = { hospital = hospital, partNum = partNum } + elseif part == "Helicopters" then + CurrentAction = part + CurrentActionMsg = TranslateCap("helicopter_prompt") + CurrentActionData = { hospital = hospital, partNum = partNum } + end end) AddEventHandler("bpt_ambulancejob:hasExitedMarker", function() - if not isInShopMenu then - ESX.CloseContext() - end + if not isInShopMenu then + ESX.CloseContext() + end - CurrentAction = nil + CurrentAction = nil end) -- Key Controls CreateThread(function() - while true do - Wait(0) - - if CurrentAction then - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) then - if CurrentAction == "AmbulanceActions" then - OpenAmbulanceActionsMenu() - elseif CurrentAction == "Vehicles" then - OpenVehicleSpawnerMenu("car", CurrentActionData.hospital, CurrentAction, CurrentActionData.partNum) - elseif CurrentAction == "Helicopters" then - OpenVehicleSpawnerMenu( - "helicopter", - CurrentActionData.hospital, - CurrentAction, - CurrentActionData.partNum - ) - end - - CurrentAction = nil - end - elseif ESX.PlayerData.job and ESX.PlayerData.job.name == "ambulance" and not isDead then - if IsControlJustReleased(0, 167) then - OpenMobileAmbulanceActionsMenu() - end - else - Wait(500) - end - end + while true do + Wait(0) + + if CurrentAction then + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) then + if CurrentAction == "AmbulanceActions" then + OpenAmbulanceActionsMenu() + elseif CurrentAction == "Vehicles" then + OpenVehicleSpawnerMenu("car", CurrentActionData.hospital, CurrentAction, CurrentActionData.partNum) + elseif CurrentAction == "Helicopters" then + OpenVehicleSpawnerMenu("helicopter", CurrentActionData.hospital, CurrentAction, CurrentActionData.partNum) + end + + CurrentAction = nil + end + elseif ESX.PlayerData.job and ESX.PlayerData.job.name == "ambulance" and not isDead then + if IsControlJustReleased(0, 167) then + OpenMobileAmbulanceActionsMenu() + end + else + Wait(500) + end + end end) RegisterNetEvent("bpt_ambulancejob:putInVehicle") AddEventHandler("bpt_ambulancejob:putInVehicle", function() - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords, 5.0) then - vehicle = ESX.Game.GetClosestVehicle(coords) - - if DoesEntityExist(vehicle) then - local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) - - for i = maxSeats - 1, 0, -1 do - if IsVehicleSeatFree(vehicle, i) then - freeSeat = i - break - end - end - - if freeSeat then - TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) - end - end - end + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords, 5.0) then + vehicle = ESX.Game.GetClosestVehicle(coords) + + if DoesEntityExist(vehicle) then + local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) + + for i = maxSeats - 1, 0, -1 do + if IsVehicleSeatFree(vehicle, i) then + freeSeat = i + break + end + end + + if freeSeat then + TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) + end + end + end end) function OpenCloakroomMenu() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom") }, - { icon = "fas fa-shirt", title = TranslateCap("ems_clothes_civil"), value = "citizen_wear" }, - { icon = "fas fa-shirt", title = TranslateCap("ems_clothes_ems"), value = "ambulance_wear" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "citizen_wear" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - isOnDuty = false - - for playerId, v in pairs(deadPlayerBlips) do - RemoveBlip(v) - deadPlayerBlips[playerId] = nil - end - end) - elseif element.value == "ambulance_wear" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) - else - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) - end - - isOnDuty = true - TriggerEvent("bpt_ambulancejob:setDeadPlayers", deadPlayers) - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom") }, + { icon = "fas fa-shirt", title = TranslateCap("ems_clothes_civil"), value = "citizen_wear" }, + { icon = "fas fa-shirt", title = TranslateCap("ems_clothes_ems"), value = "ambulance_wear" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "citizen_wear" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + isOnDuty = false + + for playerId, v in pairs(deadPlayerBlips) do + RemoveBlip(v) + deadPlayerBlips[playerId] = nil + end + end) + elseif element.value == "ambulance_wear" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + + isOnDuty = true + TriggerEvent("bpt_ambulancejob:setDeadPlayers", deadPlayers) + end) + end + end) end RegisterNetEvent("bpt_ambulancejob:heal") AddEventHandler("bpt_ambulancejob:heal", function(healType, quiet) - local playerPed = PlayerPedId() - local maxHealth = GetEntityMaxHealth(playerPed) - - if healType == "small" then - local health = GetEntityHealth(playerPed) - local newHealth = math.min(maxHealth, math.floor(health + maxHealth / 8)) - SetEntityHealth(playerPed, newHealth) - elseif healType == "big" then - SetEntityHealth(playerPed, maxHealth) - end - - if not quiet then - ESX.ShowNotification(TranslateCap("healed")) - end + local playerPed = PlayerPedId() + local maxHealth = GetEntityMaxHealth(playerPed) + + if healType == "small" then + local health = GetEntityHealth(playerPed) + local newHealth = math.min(maxHealth, math.floor(health + maxHealth / 8)) + SetEntityHealth(playerPed, newHealth) + elseif healType == "big" then + SetEntityHealth(playerPed, maxHealth) + end + + if not quiet then + ESX.ShowNotification(TranslateCap("healed")) + end end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - if isOnDuty and job ~= "ambulance" then - for playerId, v in pairs(deadPlayerBlips) do - RemoveBlip(v) - deadPlayerBlips[playerId] = nil - end - - isOnDuty = false - end + if isOnDuty and job ~= "ambulance" then + for playerId, v in pairs(deadPlayerBlips) do + RemoveBlip(v) + deadPlayerBlips[playerId] = nil + end + + isOnDuty = false + end end) RegisterNetEvent("bpt_ambulancejob:setDeadPlayers") AddEventHandler("bpt_ambulancejob:setDeadPlayers", function() - if isOnDuty then - for playerId, v in pairs(deadPlayerBlips) do - RemoveBlip(v) - deadPlayerBlips[playerId] = nil - end - - for playerId, status in pairs(deadPlayers) do - if status == "distress" then - local player = GetPlayerFromServerId(playerId) - local playerPed = GetPlayerPed(player) - local blip = AddBlipForEntity(playerPed) - - SetBlipSprite(blip, 303) - SetBlipColour(blip, 1) - SetBlipFlashes(blip, true) - SetBlipCategory(blip, 7) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blip_dead")) - EndTextCommandSetBlipName(blip) - - deadPlayerBlips[playerId] = blip - end - end - end + if isOnDuty then + for playerId, v in pairs(deadPlayerBlips) do + RemoveBlip(v) + deadPlayerBlips[playerId] = nil + end + + for playerId, status in pairs(deadPlayers) do + if status == "distress" then + local player = GetPlayerFromServerId(playerId) + local playerPed = GetPlayerPed(player) + local blip = AddBlipForEntity(playerPed) + + SetBlipSprite(blip, 303) + SetBlipColour(blip, 1) + SetBlipFlashes(blip, true) + SetBlipCategory(blip, 7) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_dead")) + EndTextCommandSetBlipName(blip) + + deadPlayerBlips[playerId] = blip + end + end + end end) diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/client/main.lua b/server-data/resources/[bpt_addons]/bpt_ammujob/client/main.lua index 16124d2ba..8a2d27abc 100644 --- a/server-data/resources/[bpt_addons]/bpt_ammujob/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_ammujob/client/main.lua @@ -4,437 +4,375 @@ local LastZone RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) RegisterNetEvent("esx:onPlayerLogout") AddEventHandler("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} + ESX.PlayerLoaded = false + ESX.PlayerData = {} end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) function DrawSub(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, 1) + ClearPrints() + BeginTextCommandPrint("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) - CreateThread(function() - Wait(0) + CreateThread(function() + Wait(0) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyspinnerOn(type) - Wait(time) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandBusyspinnerOn(type) + Wait(time) - BusyspinnerOff() - end) + BusyspinnerOff() + end) end function OpenCloakroom() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, - { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, - { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "wear_citizen" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - elseif element.value == "wear_work" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) - else - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) - end - end) - end - ESX.CloseContext() - end, function() - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, + { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, + { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "wear_citizen" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + elseif element.value == "wear_work" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + end) + end + ESX.CloseContext() + end, function() + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end) end function OpenVehicleSpawnerMenu() - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, - } - - if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) - if #vehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #vehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", - value = vehicles[i], - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - local vehicleProps = element.value - ESX.TriggerServerCallback("bpt_ammujob:SpawnVehicle", function() - return - end, vehicleProps.model, vehicleProps) - TriggerServerEvent("esx_society:removeVehicleFromGarage", "ammu", vehicleProps) - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end, "ammu") - else -- not society vehicles - if #Config.AuthorizedVehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #Config.AuthorizedVehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = Config.AuthorizedVehicles[i].label, - value = Config.AuthorizedVehicles[i].model, - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - ESX.TriggerServerCallback("bpt_ammujob:SpawnVehicle", function() - ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") - end, element.value, { plate = "AMMU JOB" }) - ESX.CloseContext() - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, + } + + if Config.EnableSocietyOwnedVehicles then + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) + if #vehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #vehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + local vehicleProps = element.value + ESX.TriggerServerCallback("bpt_ammujob:SpawnVehicle", function() + return + end, vehicleProps.model, vehicleProps) + TriggerServerEvent("esx_society:removeVehicleFromGarage", "ammu", vehicleProps) + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end, "ammu") + else -- not society vehicles + if #Config.AuthorizedVehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #Config.AuthorizedVehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = Config.AuthorizedVehicles[i].label, + value = Config.AuthorizedVehicles[i].model, + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + ESX.TriggerServerCallback("bpt_ammujob:SpawnVehicle", function() + ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") + end, element.value, { plate = "AMMU JOB" }) + ESX.CloseContext() + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end end function DeleteJobVehicle() - if Config.EnableSocietyOwnedVehicles then - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent("esx_society:putVehicleInGarage", "ammu", vehicleProps) - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - if IsInAuthorizedVehicle() then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - - if Config.MaxInService ~= -1 then - TriggerServerEvent("esx_service:disableService", "ammu") - end - else - ESX.ShowNotification(TranslateCap("only_ammu")) - end - end + if Config.EnableSocietyOwnedVehicles then + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent("esx_society:putVehicleInGarage", "ammu", vehicleProps) + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + if IsInAuthorizedVehicle() then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + + if Config.MaxInService ~= -1 then + TriggerServerEvent("esx_service:disableService", "ammu") + end + else + ESX.ShowNotification(TranslateCap("only_ammu")) + end + end end function OpenAmmuActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-ammu", title = TranslateCap("ammu") }, - { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, - { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-wallet", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_ammu") - return ESX.CloseContext() - elseif element.value == "put_stock" then - OpenPutStocksMenu() - elseif element.value == "get_stock" then - OpenGetStocksMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "ammu", function(_, menu) - menu.close() - end) - end - end, function() - CurrentAction = "ammu_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-ammu", title = TranslateCap("ammu") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-wallet", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_ammu") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "ammu", function(_, menu) + menu.close() + end) + end + end, function() + CurrentAction = "ammu_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end) end function OpenMobileAmmuActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-ammu", title = TranslateCap("ammu") }, - { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "billing" then - local elements2 = { - { unselectable = true, icon = "fas fa-ammu", title = element.title }, - { - title = TranslateCap("amount"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 250000, - inputPlaceholder = TranslateCap("bill_amount"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2) - local amount = tonumber(menu2.eles[2].inputValue) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "society_ammu", - "Ammu", - amount - ) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-ammu", title = TranslateCap("ammu") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-ammu", title = element.title }, + { + title = TranslateCap("amount"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 250000, + inputPlaceholder = TranslateCap("bill_amount"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2) + local amount = tonumber(menu2.eles[2].inputValue) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_ammu", "Ammu", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end) + end + end) end function IsInAuthorizedVehicle() - local playerPed = PlayerPedId() - local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) + local playerPed = PlayerPedId() + local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) - for i = 1, #Config.AuthorizedVehicles, 1 do - if vehModel == joaat(Config.AuthorizedVehicles[i].model) then - return true - end - end + for i = 1, #Config.AuthorizedVehicles, 1 do + if vehModel == joaat(Config.AuthorizedVehicles[i].model) then + return true + end + end - return false + return false end AddEventHandler("bpt_ammujob:hasEnteredMarker", function(zone) - if zone == "VehicleSpawner" then - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - elseif zone == "VehicleDeleter" then - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then - CurrentAction = "delete_vehicle" - CurrentActionMsg = TranslateCap("store_veh") - CurrentActionData = { - vehicle = vehicle, - } - end - elseif zone == "AmmuActions" then - CurrentAction = "ammu_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - elseif zone == "Cloakroom" then - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end + if zone == "VehicleSpawner" then + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + elseif zone == "VehicleDeleter" then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("store_veh") + CurrentActionData = { + vehicle = vehicle, + } + end + elseif zone == "AmmuActions" then + CurrentAction = "ammu_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + elseif zone == "Cloakroom" then + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end end) AddEventHandler("bpt_ammujob:hasExitedMarker", function() - ESX.CloseContext() - CurrentAction = nil + ESX.CloseContext() + CurrentAction = nil end) -- Create Blips CreateThread(function() - local blip = - AddBlipForCoord(Config.Zones.AmmuActions.Pos.x, Config.Zones.AmmuActions.Pos.y, Config.Zones.AmmuActions.Pos.z) - - SetBlipSprite(blip, 156) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 1.0) - SetBlipColour(blip, 5) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blip_ammu")) - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Zones.AmmuActions.Pos.x, Config.Zones.AmmuActions.Pos.y, Config.Zones.AmmuActions.Pos.z) + + SetBlipSprite(blip, 156) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 5) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_ammu")) + EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers CreateThread(function() - while true do - local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "ammu" then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false - local inVeh = IsPedInAnyVehicle(PlayerPedId()) - - for k, v in pairs(Config.Zones) do - local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - local distance = #(coords - zonePos) - - if v.Type ~= -1 and distance < Config.DrawDistance then - sleep = 0 - if k == "VehicleDeleter" then - if inVeh then - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - else - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent("bpt_ammujob:hasEnteredMarker", currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_ammujob:hasExitedMarker", LastZone) - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "ammu" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker, currentZone = false + local inVeh = IsPedInAnyVehicle(PlayerPedId()) + + for k, v in pairs(Config.Zones) do + local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) + local distance = #(coords - zonePos) + + if v.Type ~= -1 and distance < Config.DrawDistance then + sleep = 0 + if k == "VehicleDeleter" then + if inVeh then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + else + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + TriggerEvent("bpt_ammujob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_ammujob:hasExitedMarker", LastZone) + end + end + Wait(sleep) + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 1500 - if CurrentAction and not ESX.PlayerData.dead then - sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "ammu" then - if CurrentAction == "ammu_actions_menu" then - OpenAmmuActionsMenu() - elseif CurrentAction == "cloakroom" then - OpenCloakroom() - elseif CurrentAction == "vehicle_spawner" then - OpenVehicleSpawnerMenu() - elseif CurrentAction == "delete_vehicle" then - DeleteJobVehicle() - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if CurrentAction and not ESX.PlayerData.dead then + sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "ammu" then + if CurrentAction == "ammu_actions_menu" then + OpenAmmuActionsMenu() + elseif CurrentAction == "cloakroom" then + OpenCloakroom() + elseif CurrentAction == "vehicle_spawner" then + OpenVehicleSpawnerMenu() + elseif CurrentAction == "delete_vehicle" then + DeleteJobVehicle() + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) RegisterCommand("ammumenu", function() - if - not ESX.PlayerData.dead - and Config.EnablePlayerManagement - and ESX.PlayerData.job - and ESX.PlayerData.job.name == "ammu" - then - OpenMobileAmmuActionsMenu() - end + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "ammu" then + OpenMobileAmmuActionsMenu() + end end, false) RegisterKeyMapping("ammumenu", "Open Ammu Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_bakerjob/client/main.lua b/server-data/resources/[bpt_addons]/bpt_bakerjob/client/main.lua index 76d2dc013..41970f869 100644 --- a/server-data/resources/[bpt_addons]/bpt_bakerjob/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_bakerjob/client/main.lua @@ -4,436 +4,371 @@ local LastZone RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) RegisterNetEvent("esx:onPlayerLogout") AddEventHandler("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} + ESX.PlayerLoaded = false + ESX.PlayerData = {} end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) function DrawSub(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, 1) + ClearPrints() + BeginTextCommandPrint("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) - CreateThread(function() - Wait(0) + CreateThread(function() + Wait(0) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyspinnerOn(type) - Wait(time) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandBusyspinnerOn(type) + Wait(time) - BusyspinnerOff() - end) + BusyspinnerOff() + end) end function OpenCloakroom() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, - { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, - { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "wear_citizen" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - elseif element.value == "wear_work" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) - else - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) - end - end) - end - ESX.CloseContext() - end, function() - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, + { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, + { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "wear_citizen" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + elseif element.value == "wear_work" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + end) + end + ESX.CloseContext() + end, function() + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end) end function OpenVehicleSpawnerMenu() - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, - } - - if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) - if #vehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #vehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", - value = vehicles[i], - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - local vehicleProps = element.value - ESX.TriggerServerCallback("bpt_bakerjob:SpawnVehicle", function() - return - end, vehicleProps.model, vehicleProps) - TriggerServerEvent("esx_society:removeVehicleFromGarage", "baker", vehicleProps) - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end, "baker") - else -- not society vehicles - if #Config.AuthorizedVehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #Config.AuthorizedVehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = Config.AuthorizedVehicles[i].label, - value = Config.AuthorizedVehicles[i].model, - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - ESX.TriggerServerCallback("bpt_bakerjob:SpawnVehicle", function() - ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") - end, element.value, { plate = "BAKE JOB" }) - ESX.CloseContext() - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, + } + + if Config.EnableSocietyOwnedVehicles then + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) + if #vehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #vehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + local vehicleProps = element.value + ESX.TriggerServerCallback("bpt_bakerjob:SpawnVehicle", function() + return + end, vehicleProps.model, vehicleProps) + TriggerServerEvent("esx_society:removeVehicleFromGarage", "baker", vehicleProps) + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end, "baker") + else -- not society vehicles + if #Config.AuthorizedVehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #Config.AuthorizedVehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = Config.AuthorizedVehicles[i].label, + value = Config.AuthorizedVehicles[i].model, + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + ESX.TriggerServerCallback("bpt_bakerjob:SpawnVehicle", function() + ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") + end, element.value, { plate = "BAKE JOB" }) + ESX.CloseContext() + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end end function DeleteJobVehicle() - if Config.EnableSocietyOwnedVehicles then - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent("esx_society:putVehicleInGarage", "baker", vehicleProps) - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - if IsInAuthorizedVehicle() then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - ESX.ShowNotification(TranslateCap("only_baker")) - end - end + if Config.EnableSocietyOwnedVehicles then + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent("esx_society:putVehicleInGarage", "baker", vehicleProps) + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + if IsInAuthorizedVehicle() then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + ESX.ShowNotification(TranslateCap("only_baker")) + end + end end function OpenbakerActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-baker", title = TranslateCap("baker") }, - { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, - { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-wallet", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_baker") - return ESX.CloseContext() - elseif element.value == "put_stock" then - OpenPutStocksMenu() - elseif element.value == "get_stock" then - OpenGetStocksMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "baker", function(_, menu) - menu.close() - end) - end - end, function() - CurrentAction = "baker_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-baker", title = TranslateCap("baker") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-wallet", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_baker") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "baker", function(_, menu) + menu.close() + end) + end + end, function() + CurrentAction = "baker_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end) end function OpenMobileBakerActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-baker", title = TranslateCap("baker") }, - { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "billing" then - local elements2 = { - { unselectable = true, icon = "fas fa-baker", title = element.title }, - { - title = TranslateCap("amount"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 250000, - inputPlaceholder = TranslateCap("bill_amount"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2) - local amount = tonumber(menu2.eles[2].inputValue) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "society_baker", - "Baker", - amount - ) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-baker", title = TranslateCap("baker") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-baker", title = element.title }, + { + title = TranslateCap("amount"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 250000, + inputPlaceholder = TranslateCap("bill_amount"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2) + local amount = tonumber(menu2.eles[2].inputValue) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_baker", "Baker", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end) + end + end) end function IsInAuthorizedVehicle() - local playerPed = PlayerPedId() - local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) + local playerPed = PlayerPedId() + local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) - for i = 1, #Config.AuthorizedVehicles, 1 do - if vehModel == joaat(Config.AuthorizedVehicles[i].model) then - return true - end - end + for i = 1, #Config.AuthorizedVehicles, 1 do + if vehModel == joaat(Config.AuthorizedVehicles[i].model) then + return true + end + end - return false + return false end AddEventHandler("bpt_bakerjob:hasEnteredMarker", function(zone) - if zone == "VehicleSpawner" then - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - elseif zone == "VehicleDeleter" then - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then - CurrentAction = "delete_vehicle" - CurrentActionMsg = TranslateCap("store_veh") - CurrentActionData = { - vehicle = vehicle, - } - end - elseif zone == "BakerActions" then - CurrentAction = "baker_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - elseif zone == "Cloakroom" then - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end + if zone == "VehicleSpawner" then + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + elseif zone == "VehicleDeleter" then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("store_veh") + CurrentActionData = { + vehicle = vehicle, + } + end + elseif zone == "BakerActions" then + CurrentAction = "baker_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + elseif zone == "Cloakroom" then + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end end) AddEventHandler("bpt_bakerjob:hasExitedMarker", function() - ESX.CloseContext() - CurrentAction = nil + ESX.CloseContext() + CurrentAction = nil end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord( - Config.Zones.BakerActions.Pos.x, - Config.Zones.BakerActions.Pos.y, - Config.Zones.BakerActions.Pos.z - ) - - SetBlipSprite(blip, 88) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 1.0) - SetBlipColour(blip, 0) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blip_baker")) - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Zones.BakerActions.Pos.x, Config.Zones.BakerActions.Pos.y, Config.Zones.BakerActions.Pos.z) + + SetBlipSprite(blip, 88) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 0) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_baker")) + EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers CreateThread(function() - while true do - local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "baker" then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false - local inVeh = IsPedInAnyVehicle(PlayerPedId()) - - for k, v in pairs(Config.Zones) do - local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - local distance = #(coords - zonePos) - - if v.Type ~= -1 and distance < Config.DrawDistance then - sleep = 0 - if k == "VehicleDeleter" then - if inVeh then - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - else - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent("bpt_bakerjob:hasEnteredMarker", currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_bakerjob:hasExitedMarker", LastZone) - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "baker" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker, currentZone = false + local inVeh = IsPedInAnyVehicle(PlayerPedId()) + + for k, v in pairs(Config.Zones) do + local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) + local distance = #(coords - zonePos) + + if v.Type ~= -1 and distance < Config.DrawDistance then + sleep = 0 + if k == "VehicleDeleter" then + if inVeh then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + else + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + TriggerEvent("bpt_bakerjob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_bakerjob:hasExitedMarker", LastZone) + end + end + Wait(sleep) + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 1500 - if CurrentAction and not ESX.PlayerData.dead then - sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "baker" then - if CurrentAction == "baker_actions_menu" then - OpenbakerActionsMenu() - elseif CurrentAction == "cloakroom" then - OpenCloakroom() - elseif CurrentAction == "vehicle_spawner" then - OpenVehicleSpawnerMenu() - elseif CurrentAction == "delete_vehicle" then - DeleteJobVehicle() - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if CurrentAction and not ESX.PlayerData.dead then + sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "baker" then + if CurrentAction == "baker_actions_menu" then + OpenbakerActionsMenu() + elseif CurrentAction == "cloakroom" then + OpenCloakroom() + elseif CurrentAction == "vehicle_spawner" then + OpenVehicleSpawnerMenu() + elseif CurrentAction == "delete_vehicle" then + DeleteJobVehicle() + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) RegisterCommand("bakermenu", function() - if - not ESX.PlayerData.dead - and Config.EnablePlayerManagement - and ESX.PlayerData.job - and ESX.PlayerData.job.name == "baker" - then - OpenMobileBakerActionsMenu() - end + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "baker" then + OpenMobileBakerActionsMenu() + end end, false) RegisterKeyMapping("bakermenu", "Open Baker Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_ballasjob/client/main.lua b/server-data/resources/[bpt_addons]/bpt_ballasjob/client/main.lua index 4e3304954..31b789a08 100644 --- a/server-data/resources/[bpt_addons]/bpt_ballasjob/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_ballasjob/client/main.lua @@ -4,275 +4,210 @@ local LastZone RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) RegisterNetEvent("esx:onPlayerLogout") AddEventHandler("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} + ESX.PlayerLoaded = false + ESX.PlayerData = {} end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) function DrawSub(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, 1) + ClearPrints() + BeginTextCommandPrint("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) - CreateThread(function() - Wait(0) + CreateThread(function() + Wait(0) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyspinnerOn(type) - Wait(time) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandBusyspinnerOn(type) + Wait(time) - BusyspinnerOff() - end) + BusyspinnerOff() + end) end function OpenballasActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-ballas", title = TranslateCap("ballas") }, - { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, - { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-wallet", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_ballas") - return ESX.CloseContext() - elseif element.value == "put_stock" then - OpenPutStocksMenu() - elseif element.value == "get_stock" then - OpenGetStocksMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "ballas", function(_, menu) - menu.close() - end) - end - end, function() - CurrentAction = "ballas_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-ballas", title = TranslateCap("ballas") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-wallet", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_ballas") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "ballas", function(_, menu) + menu.close() + end) + end + end, function() + CurrentAction = "ballas_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end) end function OpenMobileBallasActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-ballas", title = TranslateCap("ballas") }, - { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "billing" then - local elements2 = { - { unselectable = true, icon = "fas fa-ballas", title = element.title }, - { - title = TranslateCap("amount"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 250000, - inputPlaceholder = TranslateCap("bill_amount"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2) - local amount = tonumber(menu2.eles[2].inputValue) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "society_ballas", - "Ballas", - amount - ) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-ballas", title = TranslateCap("ballas") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-ballas", title = element.title }, + { + title = TranslateCap("amount"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 250000, + inputPlaceholder = TranslateCap("bill_amount"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2) + local amount = tonumber(menu2.eles[2].inputValue) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_ballas", "Ballas", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end) + end + end) end AddEventHandler("bpt_ballasjob:hasEnteredMarker", function(zone) - if zone == "BallasActions" then - CurrentAction = "ballas_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end + if zone == "BallasActions" then + CurrentAction = "ballas_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end end) AddEventHandler("bpt_ballasjob:hasExitedMarker", function() - ESX.CloseContext() - CurrentAction = nil + ESX.CloseContext() + CurrentAction = nil end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord( - Config.Zones.BallasActions.Pos.x, - Config.Zones.BallasActions.Pos.y, - Config.Zones.BallasActions.Pos.z - ) + local blip = AddBlipForCoord(Config.Zones.BallasActions.Pos.x, Config.Zones.BallasActions.Pos.y, Config.Zones.BallasActions.Pos.z) - SetBlipSprite(blip, 106) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 1.0) - SetBlipColour(blip, 27) - SetBlipAsShortRange(blip, true) + SetBlipSprite(blip, 106) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 27) + SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blip_ballas")) - EndTextCommandSetBlipName(blip) + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_ballas")) + EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers CreateThread(function() - while true do - local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "ballas" then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false - - for k, v in pairs(Config.Zones) do - local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - local distance = #(coords - zonePos) - - if v.Type ~= -1 and distance < Config.DrawDistance then - sleep = 0 - if k == "" then - if k == "" then - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - else - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent("bpt_ballasjob:hasEnteredMarker", currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_ballasjob:hasExitedMarker", LastZone) - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "ballas" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker, currentZone = false + + for k, v in pairs(Config.Zones) do + local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) + local distance = #(coords - zonePos) + + if v.Type ~= -1 and distance < Config.DrawDistance then + sleep = 0 + if k == "" then + if k == "" then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + else + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + TriggerEvent("bpt_ballasjob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_ballasjob:hasExitedMarker", LastZone) + end + end + Wait(sleep) + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 1500 - if CurrentAction and not ESX.PlayerData.dead then - sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "ballas" then - if CurrentAction == "ballas_actions_menu" then - OpenballasActionsMenu() - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if CurrentAction and not ESX.PlayerData.dead then + sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "ballas" then + if CurrentAction == "ballas_actions_menu" then + OpenballasActionsMenu() + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) RegisterCommand("ballasmenu", function() - if - not ESX.PlayerData.dead - and Config.EnablePlayerManagement - and ESX.PlayerData.job - and ESX.PlayerData.job.name == "ballas" - then - OpenMobileBallasActionsMenu() - end + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "ballas" then + OpenMobileBallasActionsMenu() + end end, false) RegisterKeyMapping("ballasmenu", "Open Ballas Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_basicneeds/client/main.lua b/server-data/resources/[bpt_addons]/bpt_basicneeds/client/main.lua index bf6859fa7..2f59bb3c2 100644 --- a/server-data/resources/[bpt_addons]/bpt_basicneeds/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_basicneeds/client/main.lua @@ -30,7 +30,7 @@ AddEventHandler("esx:onPlayerSpawn", function(spawn) end) AddEventHandler("bpt_status:loaded", function(status) - TriggerEvent("bpt_status:registerStatus", "hunger", 1000000, "#CFAD0F", function() + TriggerEvent("bpt_status:registerStatus", "hunger", 1000000, "#CFAD0F", function(status) return Config.Visible end, function() status.remove(100) diff --git a/server-data/resources/[esx_addons]/esx_billing/LICENSE b/server-data/resources/[bpt_addons]/bpt_billing/LICENSE similarity index 98% rename from server-data/resources/[esx_addons]/esx_billing/LICENSE rename to server-data/resources/[bpt_addons]/bpt_billing/LICENSE index 9794a0600..62f066311 100644 --- a/server-data/resources/[esx_addons]/esx_billing/LICENSE +++ b/server-data/resources/[bpt_addons]/bpt_billing/LICENSE @@ -1,7 +1,7 @@ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - fxserver-esx_billing - Copyright (C) 2015-2023 + + Copyright (C) 2024 bitpredator This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -645,14 +645,14 @@ the "copyright" line and a pointer to where the full notice is found. GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - fxserver-esx_billing Copyright (C) 2015-2023 + Copyright (C) 2024 bitpredator This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see -. +. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read -. \ No newline at end of file +. diff --git a/server-data/resources/[bpt_addons]/bpt_billing/README.md b/server-data/resources/[bpt_addons]/bpt_billing/README.md new file mode 100644 index 000000000..e7d91c560 --- /dev/null +++ b/server-data/resources/[bpt_addons]/bpt_billing/README.md @@ -0,0 +1,19 @@ +

bpt_billing

+

Discord + +Copyright (C) 2024 bitpredator + +This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. + +This program Is distributed In the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty Of MERCHANTABILITY Or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License For more details. + +ATTENTION: +You are not authorized to change the name of the resource and the resources within it. + +If you want to contribute you can open a pull request. + +You are not authorized to sell this software (this is free project). + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. \ No newline at end of file diff --git a/server-data/resources/[esx_addons]/esx_billing/esx_billing.sql b/server-data/resources/[bpt_addons]/bpt_billing/bpt_billing.sql similarity index 99% rename from server-data/resources/[esx_addons]/esx_billing/esx_billing.sql rename to server-data/resources/[bpt_addons]/bpt_billing/bpt_billing.sql index 63fb743f1..731a3d3f7 100644 --- a/server-data/resources/[esx_addons]/esx_billing/esx_billing.sql +++ b/server-data/resources/[bpt_addons]/bpt_billing/bpt_billing.sql @@ -9,4 +9,3 @@ CREATE TABLE `billing` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - diff --git a/server-data/resources/[esx_addons]/esx_billing/client/main.lua b/server-data/resources/[bpt_addons]/bpt_billing/client/main.lua similarity index 60% rename from server-data/resources/[esx_addons]/esx_billing/client/main.lua rename to server-data/resources/[bpt_addons]/bpt_billing/client/main.lua index fbe03be5f..145f48678 100644 --- a/server-data/resources/[esx_addons]/esx_billing/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_billing/client/main.lua @@ -1,27 +1,27 @@ local isDead = false function ShowBillsMenu() - ESX.TriggerServerCallback("esx_billing:getBills", function(bills) + ESX.TriggerServerCallback("bpt_billing:getBills", function(bills) if #bills > 0 then local elements = { - { unselectable = true, icon = "fas fa-scroll", title = _U("invoices") }, + { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("invoices") }, } for _, v in ipairs(bills) do elements[#elements + 1] = { icon = "fas fa-scroll", - title = ('%s - %s'):format(v.label, _U("invoices_item", ESX.Math.GroupDigits(v.amount))), + title = ('%s - %s'):format(v.label, TranslateCap("invoices_item", ESX.Math.GroupDigits(v.amount))), billId = v.id, } end - ESX.OpenContext("right", elements, function(_, element) - ESX.TriggerServerCallback("esx_billing:payBill", function() + ESX.OpenContext("right", elements, function(menu, element) + ESX.TriggerServerCallback("bpt_billing:payBill", function() ShowBillsMenu() end, element.billId) end) else - ESX.ShowNotification(_U("no_invoices")) + ESX.ShowNotification(TranslateCap("no_invoices")) end end) end @@ -32,11 +32,11 @@ RegisterCommand("showbills", function() end end, false) -RegisterKeyMapping("showbills", _U("keymap_showbills"), "keyboard", "F7") +RegisterKeyMapping("showbills", TranslateCap("keymap_showbills"), "keyboard", "F7") AddEventHandler("esx:onPlayerDeath", function() isDead = true end) -AddEventHandler("esx:onPlayerSpawn", function() +AddEventHandler("esx:onPlayerSpawn", function(spawn) isDead = false end) diff --git a/server-data/resources/[esx_addons]/esx_billing/config.lua b/server-data/resources/[bpt_addons]/bpt_billing/config.lua similarity index 100% rename from server-data/resources/[esx_addons]/esx_billing/config.lua rename to server-data/resources/[bpt_addons]/bpt_billing/config.lua diff --git a/server-data/resources/[esx_addons]/esx_billing/fxmanifest.lua b/server-data/resources/[bpt_addons]/bpt_billing/fxmanifest.lua similarity index 87% rename from server-data/resources/[esx_addons]/esx_billing/fxmanifest.lua rename to server-data/resources/[bpt_addons]/bpt_billing/fxmanifest.lua index 392d876d4..2bb4f02eb 100644 --- a/server-data/resources/[esx_addons]/esx_billing/fxmanifest.lua +++ b/server-data/resources/[bpt_addons]/bpt_billing/fxmanifest.lua @@ -2,7 +2,7 @@ fx_version("adamant") game("gta5") -description("ESX Billing") +description("Allows Players to recieve and Send Bills") lua54("yes") version("1.0.0") diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/en.lua b/server-data/resources/[bpt_addons]/bpt_billing/locales/en.lua similarity index 100% rename from server-data/resources/[esx_addons]/esx_billing/locales/en.lua rename to server-data/resources/[bpt_addons]/bpt_billing/locales/en.lua diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/it.lua b/server-data/resources/[bpt_addons]/bpt_billing/locales/it.lua similarity index 100% rename from server-data/resources/[esx_addons]/esx_billing/locales/it.lua rename to server-data/resources/[bpt_addons]/bpt_billing/locales/it.lua diff --git a/server-data/resources/[esx_addons]/esx_billing/server/main.lua b/server-data/resources/[bpt_addons]/bpt_billing/server/main.lua similarity index 70% rename from server-data/resources/[esx_addons]/esx_billing/server/main.lua rename to server-data/resources/[bpt_addons]/bpt_billing/server/main.lua index 6ae75ea07..3458cc6c1 100644 --- a/server-data/resources/[esx_addons]/esx_billing/server/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_billing/server/main.lua @@ -1,135 +1,135 @@ -RegisterNetEvent("esx_billing:sendBill", function(playerId, sharedAccountName, label, amount) - local xPlayer = ESX.GetPlayerFromId(source) - local xTarget = ESX.GetPlayerFromId(playerId) - amount = ESX.Math.Round(amount) - - if amount > 0 and xTarget then - if string.match(sharedAccountName, "society_") then - local jobName = string.gsub(sharedAccountName, "society_", "") - if xPlayer.job.name ~= jobName then - print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from a society (^5%s^7), but does not have the correct Job - Possibly Cheats"):format(xPlayer.source, sharedAccountName)) - return - end - TriggerEvent("bpt_addonaccount:getSharedAccount", sharedAccountName, function(account) - if account then - MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { xTarget.identifier, xPlayer.identifier, "society", sharedAccountName, label, amount }, function() - xTarget.showNotification(_U("received_invoice")) - end) - else - print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from invalid society - ^5%s^7"):format(xPlayer.source, sharedAccountName)) - end - end) - else - MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { xTarget.identifier, xPlayer.identifier, "player", xPlayer.identifier, label, amount }, function() - xTarget.showNotification(_U("received_invoice")) - end) - end - end -end) - -ESX.RegisterServerCallback("esx_billing:getBills", function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) - - MySQL.query("SELECT amount, id, label FROM billing WHERE identifier = ?", { xPlayer.identifier }, function(result) - cb(result) - end) -end) - -ESX.RegisterServerCallback("esx_billing:getTargetBills", function(_, cb, target) - local xPlayer = ESX.GetPlayerFromId(target) - - if xPlayer then - MySQL.query("SELECT amount, id, label FROM billing WHERE identifier = ?", { xPlayer.identifier }, function(result) - cb(result) - end) - else - cb({}) - end -end) - -ESX.RegisterServerCallback("esx_billing:payBill", function(source, cb, billId) - local xPlayer = ESX.GetPlayerFromId(source) - - MySQL.single("SELECT sender, target_type, target, amount FROM billing WHERE id = ?", { billId }, function(result) - if result then - local amount = result.amount - local xTarget = ESX.GetPlayerFromIdentifier(result.sender) - - if result.target_type == "player" then - if xTarget then - if xPlayer.getMoney() >= amount then - MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) - if rowsChanged == 1 then - xPlayer.removeMoney(amount, "Bill Paid") - xTarget.addMoney(amount, "Paid bill") - - xPlayer.showNotification(_U("paid_invoice", ESX.Math.GroupDigits(amount))) - xTarget.showNotification(_U("received_payment", ESX.Math.GroupDigits(amount))) - end - - cb() - end) - elseif xPlayer.getAccount("bank").money >= amount then - MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) - if rowsChanged == 1 then - xPlayer.removeAccountMoney("bank", amount, "Bill Paid") - xTarget.addAccountMoney("bank", amount, "Paid bill") - - xPlayer.showNotification(_U("paid_invoice", ESX.Math.GroupDigits(amount))) - xTarget.showNotification(_U("received_payment", ESX.Math.GroupDigits(amount))) - end - - cb() - end) - else - xTarget.showNotification(_U("target_no_money")) - xPlayer.showNotification(_U("no_money")) - cb() - end - else - xPlayer.showNotification(_U("player_not_online")) - cb() - end - else - TriggerEvent("bpt_addonaccount:getSharedAccount", result.target, function(account) - if xPlayer.getMoney() >= amount then - MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) - if rowsChanged == 1 then - xPlayer.removeMoney(amount, "Bill Paid") - account.addMoney(amount) - - xPlayer.showNotification(_U("paid_invoice", ESX.Math.GroupDigits(amount))) - if xTarget then - xTarget.showNotification(_U("received_payment", ESX.Math.GroupDigits(amount))) - end - end - - cb() - end) - elseif xPlayer.getAccount("bank").money >= amount then - MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) - if rowsChanged == 1 then - xPlayer.removeAccountMoney("bank", amount, "Bill Paid") - account.addMoney(amount) - xPlayer.showNotification(_U("paid_invoice", ESX.Math.GroupDigits(amount))) - - if xTarget then - xTarget.showNotification(_U("received_payment", ESX.Math.GroupDigits(amount))) - end - end - - cb() - end) - else - if xTarget then - xTarget.showNotification(_U("target_no_money")) - end - - xPlayer.showNotification(_U("no_money")) - cb() - end - end) - end - end - end) -end) +RegisterNetEvent("bpt_billing:sendBill", function(playerId, sharedAccountName, label, amount) + local xPlayer = ESX.GetPlayerFromId(source) + local xTarget = ESX.GetPlayerFromId(playerId) + amount = ESX.Math.Round(amount) + + if amount > 0 and xTarget then + if string.match(sharedAccountName, "society_") then + local jobName = string.gsub(sharedAccountName, "society_", "") + if xPlayer.job.name ~= jobName then + print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from a society (^5%s^7), but does not have the correct Job - Possibly Cheats"):format(xPlayer.source, sharedAccountName)) + return + end + TriggerEvent("bpt_addonaccount:getSharedAccount", sharedAccountName, function(account) + if account then + MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { xTarget.identifier, xPlayer.identifier, "society", sharedAccountName, label, amount }, function(rowsChanged) + xTarget.showNotification(TranslateCap("received_invoice")) + end) + else + print(("[^2ERROR^7] Player ^5%s^7 Attempted to Send bill from invalid society - ^5%s^7"):format(xPlayer.source, sharedAccountName)) + end + end) + else + MySQL.insert("INSERT INTO billing (identifier, sender, target_type, target, label, amount) VALUES (?, ?, ?, ?, ?, ?)", { xTarget.identifier, xPlayer.identifier, "player", xPlayer.identifier, label, amount }, function(rowsChanged) + xTarget.showNotification(TranslateCap("received_invoice")) + end) + end + end +end) + +ESX.RegisterServerCallback("bpt_billing:getBills", function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.query("SELECT amount, id, label FROM billing WHERE identifier = ?", { xPlayer.identifier }, function(result) + cb(result) + end) +end) + +ESX.RegisterServerCallback("bpt_billing:getTargetBills", function(source, cb, target) + local xPlayer = ESX.GetPlayerFromId(target) + + if xPlayer then + MySQL.query("SELECT amount, id, label FROM billing WHERE identifier = ?", { xPlayer.identifier }, function(result) + cb(result) + end) + else + cb({}) + end +end) + +ESX.RegisterServerCallback("bpt_billing:payBill", function(source, cb, billId) + local xPlayer = ESX.GetPlayerFromId(source) + + MySQL.single("SELECT sender, target_type, target, amount FROM billing WHERE id = ?", { billId }, function(result) + if result then + local amount = result.amount + local xTarget = ESX.GetPlayerFromIdentifier(result.sender) + + if result.target_type == "player" then + if xTarget then + if xPlayer.getMoney() >= amount then + MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) + if rowsChanged == 1 then + xPlayer.removeMoney(amount, "Bill Paid") + xTarget.addMoney(amount, "Paid bill") + + xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) + xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) + end + + cb() + end) + elseif xPlayer.getAccount("bank").money >= amount then + MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) + if rowsChanged == 1 then + xPlayer.removeAccountMoney("bank", amount, "Bill Paid") + xTarget.addAccountMoney("bank", amount, "Paid bill") + + xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) + xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) + end + + cb() + end) + else + xTarget.showNotification(TranslateCap("target_no_money")) + xPlayer.showNotification(TranslateCap("no_money")) + cb() + end + else + xPlayer.showNotification(TranslateCap("player_not_online")) + cb() + end + else + TriggerEvent("bpt_addonaccount:getSharedAccount", result.target, function(account) + if xPlayer.getMoney() >= amount then + MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) + if rowsChanged == 1 then + xPlayer.removeMoney(amount, "Bill Paid") + account.addMoney(amount) + + xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) + if xTarget then + xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) + end + end + + cb() + end) + elseif xPlayer.getAccount("bank").money >= amount then + MySQL.update("DELETE FROM billing WHERE id = ?", { billId }, function(rowsChanged) + if rowsChanged == 1 then + xPlayer.removeAccountMoney("bank", amount, "Bill Paid") + account.addMoney(amount) + xPlayer.showNotification(TranslateCap("paid_invoice", ESX.Math.GroupDigits(amount))) + + if xTarget then + xTarget.showNotification(TranslateCap("received_payment", ESX.Math.GroupDigits(amount))) + end + end + + cb() + end) + else + if xTarget then + xTarget.showNotification(TranslateCap("target_no_money")) + end + + xPlayer.showNotification(TranslateCap("no_money")) + cb() + end + end) + end + end + end) +end) diff --git a/server-data/resources/[bpt_addons]/bpt_dustman/client/main.lua b/server-data/resources/[bpt_addons]/bpt_dustman/client/main.lua index c5abef28b..e64feb87b 100644 --- a/server-data/resources/[bpt_addons]/bpt_dustman/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_dustman/client/main.lua @@ -4,440 +4,375 @@ local LastZone RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) RegisterNetEvent("esx:onPlayerLogout") AddEventHandler("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} + ESX.PlayerLoaded = false + ESX.PlayerData = {} end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) function DrawSub(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, 1) + ClearPrints() + BeginTextCommandPrint("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) - CreateThread(function() - Wait(0) + CreateThread(function() + Wait(0) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyspinnerOn(type) - Wait(time) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandBusyspinnerOn(type) + Wait(time) - BusyspinnerOff() - end) + BusyspinnerOff() + end) end function OpenCloakroom() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, - { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, - { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "wear_citizen" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - elseif element.value == "wear_work" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) - else - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) - end - end) - end - ESX.CloseContext() - end, function() - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, + { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, + { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "wear_citizen" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + elseif element.value == "wear_work" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + end) + end + ESX.CloseContext() + end, function() + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end) end function OpenVehicleSpawnerMenu() - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, - } - - if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) - if #vehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #vehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", - value = vehicles[i], - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - local vehicleProps = element.value - ESX.TriggerServerCallback("bpt_dustmanjob:SpawnVehicle", function() - return - end, vehicleProps.model, vehicleProps) - TriggerServerEvent("esx_society:removeVehicleFromGarage", "dustman", vehicleProps) - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end, "dustman") - else -- not society vehicles - if #Config.AuthorizedVehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #Config.AuthorizedVehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = Config.AuthorizedVehicles[i].label, - value = Config.AuthorizedVehicles[i].model, - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - ESX.TriggerServerCallback("bpt_dustmanjob:SpawnVehicle", function() - ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") - end, element.value, { plate = "DUSTMAN" }) - ESX.CloseContext() - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, + } + + if Config.EnableSocietyOwnedVehicles then + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) + if #vehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #vehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + local vehicleProps = element.value + ESX.TriggerServerCallback("bpt_dustmanjob:SpawnVehicle", function() + return + end, vehicleProps.model, vehicleProps) + TriggerServerEvent("esx_society:removeVehicleFromGarage", "dustman", vehicleProps) + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end, "dustman") + else -- not society vehicles + if #Config.AuthorizedVehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #Config.AuthorizedVehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = Config.AuthorizedVehicles[i].label, + value = Config.AuthorizedVehicles[i].model, + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + ESX.TriggerServerCallback("bpt_dustmanjob:SpawnVehicle", function() + ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") + end, element.value, { plate = "DUSTMAN" }) + ESX.CloseContext() + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end end function DeleteJobVehicle() - if Config.EnableSocietyOwnedVehicles then - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent("esx_society:putVehicleInGarage", "dustman", vehicleProps) - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - if IsInAuthorizedVehicle() then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - - if Config.MaxInService ~= -1 then - TriggerServerEvent("esx_service:disableService", "dustman") - end - else - ESX.ShowNotification(TranslateCap("only_dustman")) - end - end + if Config.EnableSocietyOwnedVehicles then + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent("esx_society:putVehicleInGarage", "dustman", vehicleProps) + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + if IsInAuthorizedVehicle() then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + + if Config.MaxInService ~= -1 then + TriggerServerEvent("esx_service:disableService", "dustman") + end + else + ESX.ShowNotification(TranslateCap("only_dustman")) + end + end end function OpenDustmanActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-dustman", title = TranslateCap("dustman") }, - { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, - { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-wallet", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_dustman") - return ESX.CloseContext() - elseif element.value == "put_stock" then - OpenPutStocksMenu() - elseif element.value == "get_stock" then - OpenGetStocksMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "dustman", function(_, menu) - menu.close() - end) - end - end, function() - CurrentAction = "dustman_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-dustman", title = TranslateCap("dustman") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-wallet", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_dustman") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "dustman", function(_, menu) + menu.close() + end) + end + end, function() + CurrentAction = "dustman_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end) end function OpenMobileDustmanActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-dustman", title = TranslateCap("dustman") }, - { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "billing" then - local elements2 = { - { unselectable = true, icon = "fas fa-dustman", title = element.title }, - { - title = TranslateCap("amount"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 250000, - inputPlaceholder = TranslateCap("bill_amount"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2) - local amount = tonumber(menu2.eles[2].inputValue) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "society_dustman", - "Dustman", - amount - ) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-dustman", title = TranslateCap("dustman") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-dustman", title = element.title }, + { + title = TranslateCap("amount"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 250000, + inputPlaceholder = TranslateCap("bill_amount"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2) + local amount = tonumber(menu2.eles[2].inputValue) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_dustman", "Dustman", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end) + end + end) end function IsInAuthorizedVehicle() - local playerPed = PlayerPedId() - local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) + local playerPed = PlayerPedId() + local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) - for i = 1, #Config.AuthorizedVehicles, 1 do - if vehModel == joaat(Config.AuthorizedVehicles[i].model) then - return true - end - end + for i = 1, #Config.AuthorizedVehicles, 1 do + if vehModel == joaat(Config.AuthorizedVehicles[i].model) then + return true + end + end - return false + return false end AddEventHandler("bpt_dustmanjob:hasEnteredMarker", function(zone) - if zone == "VehicleSpawner" then - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - elseif zone == "VehicleDeleter" then - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then - CurrentAction = "delete_vehicle" - CurrentActionMsg = TranslateCap("store_veh") - CurrentActionData = { - vehicle = vehicle, - } - end - elseif zone == "DustmanActions" then - CurrentAction = "dustman_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - elseif zone == "Cloakroom" then - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end + if zone == "VehicleSpawner" then + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + elseif zone == "VehicleDeleter" then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("store_veh") + CurrentActionData = { + vehicle = vehicle, + } + end + elseif zone == "DustmanActions" then + CurrentAction = "dustman_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + elseif zone == "Cloakroom" then + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end end) AddEventHandler("bpt_dustmanjob:hasExitedMarker", function() - ESX.CloseContext() - CurrentAction = nil + ESX.CloseContext() + CurrentAction = nil end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord( - Config.Zones.DustmanActions.Pos.x, - Config.Zones.DustmanActions.Pos.y, - Config.Zones.DustmanActions.Pos.z - ) - - SetBlipSprite(blip, 67) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 1.0) - SetBlipColour(blip, 21) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blip_dustman")) - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Zones.DustmanActions.Pos.x, Config.Zones.DustmanActions.Pos.y, Config.Zones.DustmanActions.Pos.z) + + SetBlipSprite(blip, 67) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 21) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_dustman")) + EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers CreateThread(function() - while true do - local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "dustman" then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false - local inVeh = IsPedInAnyVehicle(PlayerPedId()) - - for k, v in pairs(Config.Zones) do - local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - local distance = #(coords - zonePos) - - if v.Type ~= -1 and distance < Config.DrawDistance then - sleep = 0 - if k == "VehicleDeleter" then - if inVeh then - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - else - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent("bpt_dustmanjob:hasEnteredMarker", currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_dustmanjob:hasExitedMarker", LastZone) - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "dustman" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker, currentZone = false + local inVeh = IsPedInAnyVehicle(PlayerPedId()) + + for k, v in pairs(Config.Zones) do + local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) + local distance = #(coords - zonePos) + + if v.Type ~= -1 and distance < Config.DrawDistance then + sleep = 0 + if k == "VehicleDeleter" then + if inVeh then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + else + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + TriggerEvent("bpt_dustmanjob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_dustmanjob:hasExitedMarker", LastZone) + end + end + Wait(sleep) + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 1500 - if CurrentAction and not ESX.PlayerData.dead then - sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "dustman" then - if CurrentAction == "dustman_actions_menu" then - OpenDustmanActionsMenu() - elseif CurrentAction == "cloakroom" then - OpenCloakroom() - elseif CurrentAction == "vehicle_spawner" then - OpenVehicleSpawnerMenu() - elseif CurrentAction == "delete_vehicle" then - DeleteJobVehicle() - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if CurrentAction and not ESX.PlayerData.dead then + sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "dustman" then + if CurrentAction == "dustman_actions_menu" then + OpenDustmanActionsMenu() + elseif CurrentAction == "cloakroom" then + OpenCloakroom() + elseif CurrentAction == "vehicle_spawner" then + OpenVehicleSpawnerMenu() + elseif CurrentAction == "delete_vehicle" then + DeleteJobVehicle() + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) RegisterCommand("dustmanmenu", function() - if - not ESX.PlayerData.dead - and Config.EnablePlayerManagement - and ESX.PlayerData.job - and ESX.PlayerData.job.name == "dustman" - then - OpenMobileDustmanActionsMenu() - end + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "dustman" then + OpenMobileDustmanActionsMenu() + end end, false) RegisterKeyMapping("dustmanmenu", "Open Dustman Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_fisherman/client/main.lua b/server-data/resources/[bpt_addons]/bpt_fisherman/client/main.lua index 7a1df1af3..6f57833d3 100644 --- a/server-data/resources/[bpt_addons]/bpt_fisherman/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_fisherman/client/main.lua @@ -4,436 +4,371 @@ local LastZone RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) RegisterNetEvent("esx:onPlayerLogout") AddEventHandler("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} + ESX.PlayerLoaded = false + ESX.PlayerData = {} end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) function DrawSub(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, 1) + ClearPrints() + BeginTextCommandPrint("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) - CreateThread(function() - Wait(0) + CreateThread(function() + Wait(0) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyspinnerOn(type) - Wait(time) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandBusyspinnerOn(type) + Wait(time) - BusyspinnerOff() - end) + BusyspinnerOff() + end) end function OpenCloakroom() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, - { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, - { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "wear_citizen" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - elseif element.value == "wear_work" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) - else - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) - end - end) - end - ESX.CloseContext() - end, function() - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, + { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, + { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "wear_citizen" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + elseif element.value == "wear_work" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + end) + end + ESX.CloseContext() + end, function() + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end) end function OpenVehicleSpawnerMenu() - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, - } - - if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) - if #vehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #vehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", - value = vehicles[i], - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - local vehicleProps = element.value - ESX.TriggerServerCallback("bpt_fishermanjob:SpawnVehicle", function() - return - end, vehicleProps.model, vehicleProps) - TriggerServerEvent("esx_society:removeVehicleFromGarage", "fisherman", vehicleProps) - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end, "fisherman") - else -- not society vehicles - if #Config.AuthorizedVehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #Config.AuthorizedVehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = Config.AuthorizedVehicles[i].label, - value = Config.AuthorizedVehicles[i].model, - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - ESX.TriggerServerCallback("bpt_fishermanjob:SpawnVehicle", function() - ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") - end, element.value, { plate = "FISH JOB" }) - ESX.CloseContext() - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, + } + + if Config.EnableSocietyOwnedVehicles then + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) + if #vehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #vehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + local vehicleProps = element.value + ESX.TriggerServerCallback("bpt_fishermanjob:SpawnVehicle", function() + return + end, vehicleProps.model, vehicleProps) + TriggerServerEvent("esx_society:removeVehicleFromGarage", "fisherman", vehicleProps) + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end, "fisherman") + else -- not society vehicles + if #Config.AuthorizedVehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #Config.AuthorizedVehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = Config.AuthorizedVehicles[i].label, + value = Config.AuthorizedVehicles[i].model, + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + ESX.TriggerServerCallback("bpt_fishermanjob:SpawnVehicle", function() + ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") + end, element.value, { plate = "FISH JOB" }) + ESX.CloseContext() + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end end function DeleteJobVehicle() - if Config.EnableSocietyOwnedVehicles then - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent("esx_society:putVehicleInGarage", "fisherman", vehicleProps) - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - if IsInAuthorizedVehicle() then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - ESX.ShowNotification(TranslateCap("only_fisherman")) - end - end + if Config.EnableSocietyOwnedVehicles then + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent("esx_society:putVehicleInGarage", "fisherman", vehicleProps) + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + if IsInAuthorizedVehicle() then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + ESX.ShowNotification(TranslateCap("only_fisherman")) + end + end end function OpenFishermanActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-fisherman", title = TranslateCap("fisherman") }, - { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, - { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-wallet", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_fisherman") - return ESX.CloseContext() - elseif element.value == "put_stock" then - OpenPutStocksMenu() - elseif element.value == "get_stock" then - OpenGetStocksMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "fisherman", function(_, menu) - menu.close() - end) - end - end, function() - CurrentAction = "fisherman_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-fisherman", title = TranslateCap("fisherman") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-wallet", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_fisherman") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "fisherman", function(_, menu) + menu.close() + end) + end + end, function() + CurrentAction = "fisherman_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end) end function OpenMobileFishermanActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-fisherman", title = TranslateCap("fisherman") }, - { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "billing" then - local elements2 = { - { unselectable = true, icon = "fas fa-fisherman", title = element.title }, - { - title = TranslateCap("amount"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 250000, - inputPlaceholder = TranslateCap("bill_amount"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2) - local amount = tonumber(menu2.eles[2].inputValue) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "society_fisherman", - "Fisherman", - amount - ) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-fisherman", title = TranslateCap("fisherman") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-fisherman", title = element.title }, + { + title = TranslateCap("amount"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 250000, + inputPlaceholder = TranslateCap("bill_amount"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2) + local amount = tonumber(menu2.eles[2].inputValue) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_fisherman", "Fisherman", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end) + end + end) end function IsInAuthorizedVehicle() - local playerPed = PlayerPedId() - local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) + local playerPed = PlayerPedId() + local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) - for i = 1, #Config.AuthorizedVehicles, 1 do - if vehModel == joaat(Config.AuthorizedVehicles[i].model) then - return true - end - end + for i = 1, #Config.AuthorizedVehicles, 1 do + if vehModel == joaat(Config.AuthorizedVehicles[i].model) then + return true + end + end - return false + return false end AddEventHandler("bpt_fishermanjob:hasEnteredMarker", function(zone) - if zone == "VehicleSpawner" then - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - elseif zone == "VehicleDeleter" then - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then - CurrentAction = "delete_vehicle" - CurrentActionMsg = TranslateCap("store_veh") - CurrentActionData = { - vehicle = vehicle, - } - end - elseif zone == "FishermanActions" then - CurrentAction = "fisherman_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - elseif zone == "Cloakroom" then - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end + if zone == "VehicleSpawner" then + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + elseif zone == "VehicleDeleter" then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("store_veh") + CurrentActionData = { + vehicle = vehicle, + } + end + elseif zone == "FishermanActions" then + CurrentAction = "fisherman_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + elseif zone == "Cloakroom" then + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end end) AddEventHandler("bpt_fishermanjob:hasExitedMarker", function() - ESX.CloseContext() - CurrentAction = nil + ESX.CloseContext() + CurrentAction = nil end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord( - Config.Zones.FishermanActions.Pos.x, - Config.Zones.FishermanActions.Pos.y, - Config.Zones.FishermanActions.Pos.z - ) - - SetBlipSprite(blip, 478) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 1.0) - SetBlipColour(blip, 21) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blip_fisherman")) - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Zones.FishermanActions.Pos.x, Config.Zones.FishermanActions.Pos.y, Config.Zones.FishermanActions.Pos.z) + + SetBlipSprite(blip, 478) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 21) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_fisherman")) + EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers CreateThread(function() - while true do - local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "fisherman" then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false - local inVeh = IsPedInAnyVehicle(PlayerPedId()) - - for k, v in pairs(Config.Zones) do - local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - local distance = #(coords - zonePos) - - if v.Type ~= -1 and distance < Config.DrawDistance then - sleep = 0 - if k == "VehicleDeleter" then - if inVeh then - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - else - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent("bpt_fishermanjob:hasEnteredMarker", currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_fishermanjob:hasExitedMarker", LastZone) - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "fisherman" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker, currentZone = false + local inVeh = IsPedInAnyVehicle(PlayerPedId()) + + for k, v in pairs(Config.Zones) do + local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) + local distance = #(coords - zonePos) + + if v.Type ~= -1 and distance < Config.DrawDistance then + sleep = 0 + if k == "VehicleDeleter" then + if inVeh then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + else + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + TriggerEvent("bpt_fishermanjob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_fishermanjob:hasExitedMarker", LastZone) + end + end + Wait(sleep) + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 1500 - if CurrentAction and not ESX.PlayerData.dead then - sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "fisherman" then - if CurrentAction == "fisherman_actions_menu" then - OpenFishermanActionsMenu() - elseif CurrentAction == "cloakroom" then - OpenCloakroom() - elseif CurrentAction == "vehicle_spawner" then - OpenVehicleSpawnerMenu() - elseif CurrentAction == "delete_vehicle" then - DeleteJobVehicle() - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if CurrentAction and not ESX.PlayerData.dead then + sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "fisherman" then + if CurrentAction == "fisherman_actions_menu" then + OpenFishermanActionsMenu() + elseif CurrentAction == "cloakroom" then + OpenCloakroom() + elseif CurrentAction == "vehicle_spawner" then + OpenVehicleSpawnerMenu() + elseif CurrentAction == "delete_vehicle" then + DeleteJobVehicle() + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) RegisterCommand("fishermanmenu", function() - if - not ESX.PlayerData.dead - and Config.EnablePlayerManagement - and ESX.PlayerData.job - and ESX.PlayerData.job.name == "fisherman" - then - OpenMobileFishermanActionsMenu() - end + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "fisherman" then + OpenMobileFishermanActionsMenu() + end end, false) RegisterKeyMapping("fishermanmenu", "Open Fisherman Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_importjob/client/main.lua b/server-data/resources/[bpt_addons]/bpt_importjob/client/main.lua index 3f0f105ce..e5066328d 100644 --- a/server-data/resources/[bpt_addons]/bpt_importjob/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_importjob/client/main.lua @@ -4,440 +4,375 @@ local LastZone RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) RegisterNetEvent("esx:onPlayerLogout") AddEventHandler("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} + ESX.PlayerLoaded = false + ESX.PlayerData = {} end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) function DrawSub(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, 1) + ClearPrints() + BeginTextCommandPrint("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) - CreateThread(function() - Wait(0) + CreateThread(function() + Wait(0) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyspinnerOn(type) - Wait(time) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandBusyspinnerOn(type) + Wait(time) - BusyspinnerOff() - end) + BusyspinnerOff() + end) end function OpenCloakroom() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, - { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, - { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "wear_citizen" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - elseif element.value == "wear_work" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) - else - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) - end - end) - end - ESX.CloseContext() - end, function() - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, + { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, + { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "wear_citizen" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + elseif element.value == "wear_work" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + end) + end + ESX.CloseContext() + end, function() + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end) end function OpenVehicleSpawnerMenu() - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, - } - - if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) - if #vehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #vehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", - value = vehicles[i], - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - local vehicleProps = element.value - ESX.TriggerServerCallback("bpt_importjob:SpawnVehicle", function() - return - end, vehicleProps.model, vehicleProps) - TriggerServerEvent("esx_society:removeVehicleFromGarage", "import", vehicleProps) - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end, "import") - else -- not society vehicles - if #Config.AuthorizedVehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #Config.AuthorizedVehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = Config.AuthorizedVehicles[i].label, - value = Config.AuthorizedVehicles[i].model, - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - ESX.TriggerServerCallback("bpt_importjob:SpawnVehicle", function() - ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") - end, element.value, { plate = "IMPO JOB" }) - ESX.CloseContext() - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, + } + + if Config.EnableSocietyOwnedVehicles then + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) + if #vehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #vehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + local vehicleProps = element.value + ESX.TriggerServerCallback("bpt_importjob:SpawnVehicle", function() + return + end, vehicleProps.model, vehicleProps) + TriggerServerEvent("esx_society:removeVehicleFromGarage", "import", vehicleProps) + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end, "import") + else -- not society vehicles + if #Config.AuthorizedVehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #Config.AuthorizedVehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = Config.AuthorizedVehicles[i].label, + value = Config.AuthorizedVehicles[i].model, + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + ESX.TriggerServerCallback("bpt_importjob:SpawnVehicle", function() + ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") + end, element.value, { plate = "IMPO JOB" }) + ESX.CloseContext() + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end end function DeleteJobVehicle() - if Config.EnableSocietyOwnedVehicles then - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent("esx_society:putVehicleInGarage", "import", vehicleProps) - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - if IsInAuthorizedVehicle() then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - - if Config.MaxInService ~= -1 then - TriggerServerEvent("esx_service:disableService", "import") - end - else - ESX.ShowNotification(TranslateCap("only_import")) - end - end + if Config.EnableSocietyOwnedVehicles then + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent("esx_society:putVehicleInGarage", "import", vehicleProps) + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + if IsInAuthorizedVehicle() then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + + if Config.MaxInService ~= -1 then + TriggerServerEvent("esx_service:disableService", "import") + end + else + ESX.ShowNotification(TranslateCap("only_import")) + end + end end function OpenImportActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-import", title = TranslateCap("import") }, - { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, - { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-wallet", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_import") - return ESX.CloseContext() - elseif element.value == "put_stock" then - OpenPutStocksMenu() - elseif element.value == "get_stock" then - OpenGetStocksMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "import", function(_, menu) - menu.close() - end) - end - end, function() - CurrentAction = "import_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-import", title = TranslateCap("import") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-wallet", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_import") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "import", function(_, menu) + menu.close() + end) + end + end, function() + CurrentAction = "import_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end) end function OpenMobileImportActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-import", title = TranslateCap("import") }, - { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "billing" then - local elements2 = { - { unselectable = true, icon = "fas fa-import", title = element.title }, - { - title = TranslateCap("amount"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 250000, - inputPlaceholder = TranslateCap("bill_amount"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2) - local amount = tonumber(menu2.eles[2].inputValue) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "society_import", - "Import", - amount - ) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-import", title = TranslateCap("import") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-import", title = element.title }, + { + title = TranslateCap("amount"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 250000, + inputPlaceholder = TranslateCap("bill_amount"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2) + local amount = tonumber(menu2.eles[2].inputValue) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_import", "Import", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end) + end + end) end function IsInAuthorizedVehicle() - local playerPed = PlayerPedId() - local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) + local playerPed = PlayerPedId() + local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) - for i = 1, #Config.AuthorizedVehicles, 1 do - if vehModel == joaat(Config.AuthorizedVehicles[i].model) then - return true - end - end + for i = 1, #Config.AuthorizedVehicles, 1 do + if vehModel == joaat(Config.AuthorizedVehicles[i].model) then + return true + end + end - return false + return false end AddEventHandler("bpt_importjob:hasEnteredMarker", function(zone) - if zone == "VehicleSpawner" then - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - elseif zone == "VehicleDeleter" then - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then - CurrentAction = "delete_vehicle" - CurrentActionMsg = TranslateCap("store_veh") - CurrentActionData = { - vehicle = vehicle, - } - end - elseif zone == "ImportActions" then - CurrentAction = "import_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - elseif zone == "Cloakroom" then - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end + if zone == "VehicleSpawner" then + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + elseif zone == "VehicleDeleter" then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("store_veh") + CurrentActionData = { + vehicle = vehicle, + } + end + elseif zone == "ImportActions" then + CurrentAction = "import_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + elseif zone == "Cloakroom" then + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end end) AddEventHandler("bpt_importjob:hasExitedMarker", function() - ESX.CloseContext() - CurrentAction = nil + ESX.CloseContext() + CurrentAction = nil end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord( - Config.Zones.ImportActions.Pos.x, - Config.Zones.ImportActions.Pos.y, - Config.Zones.ImportActions.Pos.z - ) - - SetBlipSprite(blip, 478) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 1.0) - SetBlipColour(blip, 21) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blip_import")) - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Zones.ImportActions.Pos.x, Config.Zones.ImportActions.Pos.y, Config.Zones.ImportActions.Pos.z) + + SetBlipSprite(blip, 478) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 21) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_import")) + EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers CreateThread(function() - while true do - local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "import" then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false - local inVeh = IsPedInAnyVehicle(PlayerPedId()) - - for k, v in pairs(Config.Zones) do - local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - local distance = #(coords - zonePos) - - if v.Type ~= -1 and distance < Config.DrawDistance then - sleep = 0 - if k == "VehicleDeleter" then - if inVeh then - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - else - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent("bpt_importjob:hasEnteredMarker", currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_importjob:hasExitedMarker", LastZone) - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "import" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker, currentZone = false + local inVeh = IsPedInAnyVehicle(PlayerPedId()) + + for k, v in pairs(Config.Zones) do + local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) + local distance = #(coords - zonePos) + + if v.Type ~= -1 and distance < Config.DrawDistance then + sleep = 0 + if k == "VehicleDeleter" then + if inVeh then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + else + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + TriggerEvent("bpt_importjob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_importjob:hasExitedMarker", LastZone) + end + end + Wait(sleep) + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 1500 - if CurrentAction and not ESX.PlayerData.dead then - sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "import" then - if CurrentAction == "import_actions_menu" then - OpenImportActionsMenu() - elseif CurrentAction == "cloakroom" then - OpenCloakroom() - elseif CurrentAction == "vehicle_spawner" then - OpenVehicleSpawnerMenu() - elseif CurrentAction == "delete_vehicle" then - DeleteJobVehicle() - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if CurrentAction and not ESX.PlayerData.dead then + sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "import" then + if CurrentAction == "import_actions_menu" then + OpenImportActionsMenu() + elseif CurrentAction == "cloakroom" then + OpenCloakroom() + elseif CurrentAction == "vehicle_spawner" then + OpenVehicleSpawnerMenu() + elseif CurrentAction == "delete_vehicle" then + DeleteJobVehicle() + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) RegisterCommand("importmenu", function() - if - not ESX.PlayerData.dead - and Config.EnablePlayerManagement - and ESX.PlayerData.job - and ESX.PlayerData.job.name == "import" - then - OpenMobileImportActionsMenu() - end + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "import" then + OpenMobileImportActionsMenu() + end end, false) RegisterKeyMapping("importmenu", "Open Import Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_taxijob/client/main.lua b/server-data/resources/[bpt_addons]/bpt_taxijob/client/main.lua index 61bd59d32..92a8a019a 100644 --- a/server-data/resources/[bpt_addons]/bpt_taxijob/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_taxijob/client/main.lua @@ -1,27 +1,26 @@ -local HasAlreadyEnteredMarker, OnJob, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, -CurrentActionData = false, false, false, false, false, {} +local HasAlreadyEnteredMarker, OnJob, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, CurrentActionData = false, false, false, false, false, {} local CurrentCustomer, CurrentCustomerBlip, DestinationBlip, targetCoords, LastZone, CurrentAction, CurrentActionMsg -RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function(xPlayer) +RegisterNetEvent("esx:playerLoaded") +AddEventHandler("esx:playerLoaded", function(xPlayer) ESX.PlayerData = xPlayer ESX.PlayerLoaded = true end) -RegisterNetEvent('esx:onPlayerLogout') -AddEventHandler('esx:onPlayerLogout', function() +RegisterNetEvent("esx:onPlayerLogout") +AddEventHandler("esx:onPlayerLogout", function() ESX.PlayerLoaded = false ESX.PlayerData = {} end) -RegisterNetEvent('esx:setJob') -AddEventHandler('esx:setJob', function(job) +RegisterNetEvent("esx:setJob") +AddEventHandler("esx:setJob", function(job) ESX.PlayerData.job = job end) function DrawSub(msg, time) ClearPrints() - BeginTextCommandPrint('STRING') + BeginTextCommandPrint("STRING") AddTextComponentSubstringPlayerName(msg) EndTextCommandPrint(time, 1) end @@ -30,7 +29,7 @@ function ShowLoadingPromt(msg, time, type) CreateThread(function() Wait(0) - BeginTextCommandBusyspinnerOn('STRING') + BeginTextCommandBusyspinnerOn("STRING") AddTextComponentSubstringPlayerName(msg) EndTextCommandBusyspinnerOn(type) Wait(time) @@ -73,7 +72,7 @@ function ClearCurrentMission() end function StartTaxiJob() - ShowLoadingPromt(TranslateCap('taking_service'), 5000, 3) + ShowLoadingPromt(TranslateCap("taking_service"), 5000, 3) ClearCurrentMission() OnJob = true @@ -93,55 +92,55 @@ function StopTaxiJob() ClearCurrentMission() OnJob = false - DrawSub(TranslateCap('mission_complete'), 5000) + DrawSub(TranslateCap("mission_complete"), 5000) end function OpenCloakroom() local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap('cloakroom_menu') }, - { icon = "fas fa-shirt", title = TranslateCap('wear_citizen'), value = "wear_citizen" }, - { icon = "fas fa-shirt", title = TranslateCap('wear_work'), value = "wear_work" }, + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, + { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, + { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, } ESX.OpenContext("right", elements, function(menu, element) if element.value == "wear_citizen" then - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) end) elseif element.value == "wear_work" then - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) if skin.sex == 0 then - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) else - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) end end) end end, function(menu) - CurrentAction = 'cloakroom' - CurrentActionMsg = TranslateCap('cloakroom_prompt') + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") CurrentActionData = {} end) end function OpenVehicleSpawnerMenu() local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap('spawn_veh') } + { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, } if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(vehicles) + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) for i = 1, #vehicles, 1 do elements[#elements + 1] = { icon = "fas fa-car", - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', - value = vehicles[i] + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], } end ESX.OpenContext("right", elements, function(menu, element) if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap('spawnpoint_blocked')) + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) return end @@ -149,35 +148,35 @@ function OpenVehicleSpawnerMenu() ESX.TriggerServerCallback("bpt_taxijob:SpawnVehicle", function() return end, vehicleProps.model, vehicleProps) - TriggerServerEvent('esx_society:removeVehicleFromGarage', 'taxi', vehicleProps) + TriggerServerEvent("esx_society:removeVehicleFromGarage", "taxi", vehicleProps) ESX.CloseContext() end, function(menu) - CurrentAction = 'vehicle_spawner' - CurrentActionMsg = TranslateCap('spawner_prompt') + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") CurrentActionData = {} end) - end, 'taxi') + end, "taxi") else -- not society vehicles if #Config.AuthorizedVehicles == 0 then - ESX.ShowNotification(TranslateCap('empty_authorized_vehicles_table'), "error") + ESX.ShowNotification(TranslateCap("empty_authorized_vehicles_table"), "error") return end ESX.OpenContext("right", Config.AuthorizedVehicles, function(menu, element) if not element.model or string.len(element.model) == 0 then - ESX.ShowNotification(TranslateCap('unknow_model'), "error") + ESX.ShowNotification(TranslateCap("unknow_model"), "error") return end if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap('spawnpoint_blocked')) + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) return end ESX.TriggerServerCallback("bpt_taxijob:SpawnVehicle", function() - ESX.ShowNotification(TranslateCap('vehicle_spawned', element.title), "success") + ESX.ShowNotification(TranslateCap("vehicle_spawned", element.title), "success") end, element.model, { plate = "TAXI JOB" }) ESX.CloseContext() end, function(menu) - CurrentAction = 'vehicle_spawner' - CurrentActionMsg = TranslateCap('spawner_prompt') + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") CurrentActionData = {} end) end @@ -188,84 +187,83 @@ function DeleteJobVehicle() if Config.EnableSocietyOwnedVehicles then local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent('esx_society:putVehicleInGarage', 'taxi', vehicleProps) + TriggerServerEvent("esx_society:putVehicleInGarage", "taxi", vehicleProps) ESX.Game.DeleteVehicle(CurrentActionData.vehicle) else if IsInAuthorizedVehicle() then ESX.Game.DeleteVehicle(CurrentActionData.vehicle) if Config.MaxInService ~= -1 then - TriggerServerEvent('esx_service:disableService', 'taxi') + TriggerServerEvent("esx_service:disableService", "taxi") end else - ESX.ShowNotification(TranslateCap('only_taxi')) + ESX.ShowNotification(TranslateCap("only_taxi")) end end end function OpenTaxiActionsMenu() local elements = { - { unselectable = true, icon = "fas fa-taxi", title = TranslateCap('taxi') }, - { icon = "fas fa-box", title = TranslateCap('deposit_stock'), value = 'put_stock' }, - { icon = "fas fa-box", title = TranslateCap('take_stock'), value = 'get_stock' } + { unselectable = true, icon = "fas fa-taxi", title = TranslateCap("taxi") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, } - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == 'boss' then + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then elements[#elements + 1] = { icon = "fas fa-wallet", - title = TranslateCap('boss_actions'), - value = "boss_actions" + title = TranslateCap("boss_actions"), + value = "boss_actions", } end ESX.OpenContext("right", elements, function(menu, element) - if Config.OxInventory and (element.value == 'put_stock' or element.value == 'get_stock') then - exports.ox_inventory:openInventory('stash', 'society_taxi') + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_taxi") return ESX.CloseContext() - elseif element.value == 'put_stock' then + elseif element.value == "put_stock" then OpenPutStocksMenu() - elseif element.value == 'get_stock' then + elseif element.value == "get_stock" then OpenGetStocksMenu() - elseif element.value == 'boss_actions' then - TriggerEvent('esx_society:openBossMenu', 'taxi', function() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "taxi", function() menu.close() end) end end, function(menu) - CurrentAction = 'taxi_actions_menu' - CurrentActionMsg = TranslateCap('press_to_open') + CurrentAction = "taxi_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") CurrentActionData = {} end) end function OpenMobileTaxiActionsMenu() local elements = { - { unselectable = true, icon = "fas fa-taxi", title = TranslateCap('taxi') }, - { icon = "fas fa-scroll", title = TranslateCap('billing'), value = "billing" }, - { icon = "fas fa-taxi", title = TranslateCap('start_job'), value = "start_job" }, + { unselectable = true, icon = "fas fa-taxi", title = TranslateCap("taxi") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + { icon = "fas fa-taxi", title = TranslateCap("start_job"), value = "start_job" }, } ESX.OpenContext("right", elements, function(menu, element) if element.value == "billing" then local elements2 = { - { unselectable = true, icon = "fas fa-taxi", title = element.title }, - { title = TranslateCap('amount'), input = true, inputType = "number", inputMin = 1, inputMax = 250000, inputPlaceholder = TranslateCap('bill_amount') }, - { icon = "fas fa-check-double", title = TranslateCap('confirm'), value = "confirm" } + { unselectable = true, icon = "fas fa-taxi", title = element.title }, + { title = TranslateCap("amount"), input = true, inputType = "number", inputMin = 1, inputMax = 250000, inputPlaceholder = TranslateCap("bill_amount") }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, } ESX.OpenContext("right", elements2, function(menu2, element2) local amount = tonumber(menu2.eles[2].inputValue) if amount == nil then - ESX.ShowNotification(TranslateCap('amount_invalid')) + ESX.ShowNotification(TranslateCap("amount_invalid")) else ESX.CloseContext() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap('no_players_near')) + ESX.ShowNotification(TranslateCap("no_players_near")) else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_taxi', - 'Taxi', amount) - ESX.ShowNotification(TranslateCap('billing_sent')) + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_taxi", "Taxi", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) end end end) @@ -274,7 +272,7 @@ function OpenMobileTaxiActionsMenu() ESX.CloseContext() StopTaxiJob() else - if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == 'taxi' then + if ESX.PlayerData.job ~= nil and ESX.PlayerData.job.name == "taxi" then local playerPed = PlayerPedId() local vehicle = GetVehiclePedIsIn(playerPed, false) @@ -287,14 +285,14 @@ function OpenMobileTaxiActionsMenu() ESX.CloseContext() StartTaxiJob() else - ESX.ShowNotification(TranslateCap('must_in_taxi')) + ESX.ShowNotification(TranslateCap("must_in_taxi")) end end else if tonumber(ESX.PlayerData.job.grade) >= 3 then - ESX.ShowNotification(TranslateCap('must_in_vehicle')) + ESX.ShowNotification(TranslateCap("must_in_vehicle")) else - ESX.ShowNotification(TranslateCap('must_in_taxi')) + ESX.ShowNotification(TranslateCap("must_in_taxi")) end end end @@ -317,35 +315,35 @@ function IsInAuthorizedVehicle() end function OpenGetStocksMenu() - ESX.TriggerServerCallback('bpt_taxijob:getStockItems', function(items) + ESX.TriggerServerCallback("bpt_taxijob:getStockItems", function(items) local elements = { - { unselectable = true, icon = "fas fa-box", title = TranslateCap('taxi_stock') } + { unselectable = true, icon = "fas fa-box", title = TranslateCap("taxi_stock") }, } for i = 1, #items, 1 do elements[#elements + 1] = { icon = "fas fa-box", - title = 'x' .. items[i].count .. ' ' .. items[i].label, - value = items[i].name + title = "x" .. items[i].count .. " " .. items[i].label, + value = items[i].name, } end ESX.OpenContext("right", elements, function(menu, element) local itemName = element.value local elements2 = { - { unselectable = true, icon = "fas fa-box", title = element.title }, - { title = TranslateCap('amount'), input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = TranslateCap('withdraw_amount') }, - { icon = "fas fa-check-double", title = TranslateCap('confirm'), value = "confirm" } + { unselectable = true, icon = "fas fa-box", title = element.title }, + { title = TranslateCap("amount"), input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = TranslateCap("withdraw_amount") }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, } ESX.OpenContext("right", elements2, function(menu2, element2) local count = tonumber(menu2.eles[2].inputValue) if count == nil then - ESX.ShowNotification(TranslateCap('quantity_invalid')) + ESX.ShowNotification(TranslateCap("quantity_invalid")) else ESX.CloseContext() - TriggerServerEvent('bpt_taxijob:getStockItem', itemName, count) + TriggerServerEvent("bpt_taxijob:getStockItem", itemName, count) Wait(1000) OpenGetStocksMenu() @@ -353,16 +351,16 @@ function OpenGetStocksMenu() end) end) end, function(menu) - CurrentAction = 'taxi_actions_menu' - CurrentActionMsg = TranslateCap('press_to_open') + CurrentAction = "taxi_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") CurrentActionData = {} end) end function OpenPutStocksMenu() - ESX.TriggerServerCallback('bpt_taxijob:getPlayerInventory', function(inventory) + ESX.TriggerServerCallback("bpt_taxijob:getPlayerInventory", function(inventory) local elements = { - { unselectable = true, icon = "fas fa-box", title = TranslateCap('inventory') } + { unselectable = true, icon = "fas fa-box", title = TranslateCap("inventory") }, } for i = 1, #inventory.items, 1 do @@ -370,9 +368,9 @@ function OpenPutStocksMenu() if item.count > 0 then elements[#elements + 1] = { icon = "fas fa-box", - title = item.label .. ' x' .. item.count, - type = 'item_standard', - value = item.name + title = item.label .. " x" .. item.count, + type = "item_standard", + value = item.name, } end end @@ -381,80 +379,78 @@ function OpenPutStocksMenu() local itemName = element.value local elements2 = { - { unselectable = true, icon = "fas fa-box", title = element.title }, - { title = TranslateCap('amount'), input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = TranslateCap('deposit_amount') }, - { icon = "fas fa-check-double", title = "Confirm", value = "confirm" } + { unselectable = true, icon = "fas fa-box", title = element.title }, + { title = TranslateCap("amount"), input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = TranslateCap("deposit_amount") }, + { icon = "fas fa-check-double", title = "Confirm", value = "confirm" }, } ESX.OpenContext("right", elements2, function(menu2, element2) local count = tonumber(menu2.eles[2].inputValue) if count == nil then - ESX.ShowNotification(TranslateCap('quantity_invalid')) + ESX.ShowNotification(TranslateCap("quantity_invalid")) else ESX.CloseContext() -- todo: refresh on callback - TriggerServerEvent('bpt_taxijob:putStockItems', itemName, count) + TriggerServerEvent("bpt_taxijob:putStockItems", itemName, count) Wait(1000) OpenPutStocksMenu() end end) end) end, function(menu) - CurrentAction = 'taxi_actions_menu' - CurrentActionMsg = TranslateCap('press_to_open') + CurrentAction = "taxi_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") CurrentActionData = {} end) end -AddEventHandler('bpt_taxijob:hasEnteredMarker', function(zone) - if zone == 'VehicleSpawner' then - CurrentAction = 'vehicle_spawner' - CurrentActionMsg = TranslateCap('spawner_prompt') +AddEventHandler("bpt_taxijob:hasEnteredMarker", function(zone) + if zone == "VehicleSpawner" then + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") CurrentActionData = {} - elseif zone == 'VehicleDeleter' then + elseif zone == "VehicleDeleter" then local playerPed = PlayerPedId() local vehicle = GetVehiclePedIsIn(playerPed, false) if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then - CurrentAction = 'delete_vehicle' - CurrentActionMsg = TranslateCap('store_veh') + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("store_veh") CurrentActionData = { - vehicle = vehicle + vehicle = vehicle, } end - elseif zone == 'TaxiActions' then - CurrentAction = 'taxi_actions_menu' - CurrentActionMsg = TranslateCap('press_to_open') + elseif zone == "TaxiActions" then + CurrentAction = "taxi_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") CurrentActionData = {} - elseif zone == 'Cloakroom' then - CurrentAction = 'cloakroom' - CurrentActionMsg = TranslateCap('cloakroom_prompt') + elseif zone == "Cloakroom" then + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") CurrentActionData = {} end end) -AddEventHandler('bpt_taxijob:hasExitedMarker', function(zone) +AddEventHandler("bpt_taxijob:hasExitedMarker", function(zone) ESX.CloseContext() CurrentAction = nil end) -RegisterNetEvent('esx_phone:loaded') -AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) +RegisterNetEvent("esx_phone:loaded") +AddEventHandler("esx_phone:loaded", function(phoneNumber, contacts) local specialContact = { - name = TranslateCap('phone_taxi'), - number = 'taxi', - base64Icon = - 'data:image/png;base64,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' + name = TranslateCap("phone_taxi"), + number = "taxi", + base64Icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAGGElEQVR4XsWWW2gd1xWGv7Vn5pyRj47ut8iOYlmyWxw1KSZN4riOW6eFuCYldaBtIL1Ag4NNmt5ICORCaNKXlF6oCy0hpSoJKW4bp7Sk6YNb01RuLq4d0pQ0kWQrshVJ1uX46HJ0zpy5rCKfQYgjCUs4kA+GtTd786+ftW8jqsqHibB6TLZn2zeq09ZTWAIWCxACoTI1E+6v+eSpXwHRqkVZPcmqlBzCApLQ8dk3IWVKMQlYcHG81OODNmD6D7d9VQrTSbwsH73lFKePtvOxXSfn48U+Xpb58fl5gPmgl6DiR19PZN4+G7iODY4liIAACqiCHyp+AFvb7ML3uot1QP5yDUim292RtIqfU6Lr8wFVDVV8AsPKRDAxzYkKm2kj5sSFuUT3+v2FXkDXakD6f+7c1NGS7Ml0Pkah6jq8mhvwUy7Cyijg5Aoks6/hTp+k7vRjDJ73dmw8WHxlJRM2y5Nsb3GPDuzsZURbGMsUmRkoUPByCMrKCG7SobJiO01X7OKq6utoe3XX34BaoLDaCljj3faTcu3j3z3T+iADwzNYEmKIWcGAIAtqqkKAxZa2Sja/tY+59/7y48aveQ8A4Woq4Fa3bj7Q1/EgwWRAZ52NMTYCWAZEwIhBUEQgUiVQ8IpKvqj4kVJCyGRCRrb+hvap+gPAo0DuUhWQfx2q29u+t/vPmarbCLwII7qQTEQRLbUtBJ2PAkZARBADqkLBV/I+BGrhpoSN577FWz3P3XbTvRMvAlpuwC4crv5jwtK9RAFSu46+G8cRwESxQ+K2gESAgCiIASHuA8YCBdSUohdCKGCF0H6iGc3MgrEphvKi+6Wp24HABioSjuxFARGobyJ5OMXEiGHW6iLR0EmifhPJDddj3CoqtuwEZSkCc73/RAvTeEOvU5w8gz/Zj2TfoLFFibZvQrI5EOFiPqgAZmzApTINKKgPiW20ffkXtPXfA9Ysmf5/kHn/T0z8e5rpCS5JVQNUN1ayfn2a+qvT2JWboOOXMPg0ms6C2IAAWTc2ACPeupdbm5yb8XNQczOM90DOB0uoa01Ttz5FZ6IL3Ctg9DUIg7Lto2DZ0HIDFEbAz4AaiBRyxZJe9U7kQg84KYbH/JeJESANXPXwXdWffvzu1p+x5VE4/ST4EyAOoEAI6WsAhdx/AYulhJDqAgRm/hPPEVAfnAboeAB6v88jTw/f98SzU8eAwbgC5IGRg3vsW3E7YewYzJwF4wAhikJURGqvBO8ouAFIxBI0gqgPEp9B86+ASSAIEEHhbEnX7eTgnrFbn3iW5+K82EAA+M2V+d2EeRj9K/izIBYgJZGwCO4Gzm/uRQOwDEsI41PSfPZ+xJsBKwFo6dOwpJvezMU84Md5sSmRCM51uacGbUKvHWEjAKIelXaGJqePyopjzFTdx6Ef/gDbjo3FKEoQKN+8/yEqRt8jf67IaNDBnF9FZFwERRGspMM20+XC64nym9AMhSE1G7fjbb0bCQsISi6vFCdPMPzuUwR9AcmOKQ7cew+WZcq3IGEYMZeb4p13sjjmU4TX7Cfdtp0oDAFBbZfk/37N0MALAKbcAKaY4yPeuwy3t2J8MAKDIxDVd1Lz8Ts599vb8Wameen532GspRWIQmXPHV8k0BquvPP3TOSgsRmiCFRAHWh9420Gi7nl34JaBen7O7UWRMD740AQ7yEf8nW78TIeN+7+PCIsOYaqMJHxqKtpJ++D+DA5ARsawEmASqzv1Cz7FjRpbt951tUAOcAHdNEUC7C5NAJo7Dws03CAFMxlkdSRZmCMxaq8ejKuVwSqIJfzA61LmyIgBoxZfgmYmQazKLGumHitRso0ZVkD0aE/FI7UrYv2WUYXjo0ihNhEatA1GBEUIxEWAcKCHhHCVMG8AETlda0ENn3hrm+/6Zh47RBCtXn+mZ/sAXzWjnPHV77zkiXBgl6gFkee+em1wBlgdnEF8sCF5moLI7KwlSIMwABwgbVT21htMNjleheAfPkShEBh/PzQccexdxBT9IPjQAYYZ+3o2OjQ8cQiPb+kVwBCliENXA3sAm6Zj3E/zaq4fD07HmwEmuKYXsUFcDl6Hz7/B1RGfEbPim/bAAAAAElFTkSuQmCC", } - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + TriggerEvent("esx_phone:addSpecialContact", specialContact.name, specialContact.number, specialContact.base64Icon) end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord(Config.Zones.TaxiActions.Pos.x, Config.Zones.TaxiActions.Pos.y, - Config.Zones.TaxiActions.Pos.z) + local blip = AddBlipForCoord(Config.Zones.TaxiActions.Pos.x, Config.Zones.TaxiActions.Pos.y, Config.Zones.TaxiActions.Pos.z) SetBlipSprite(blip, 198) SetBlipDisplay(blip, 4) @@ -462,8 +458,8 @@ CreateThread(function() SetBlipColour(blip, 5) SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName('STRING') - AddTextComponentSubstringPlayerName(TranslateCap('blip_taxi')) + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blip_taxi")) EndTextCommandSetBlipName(blip) end) @@ -471,7 +467,7 @@ end) CreateThread(function() while true do local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then + if ESX.PlayerData.job and ESX.PlayerData.job.name == "taxi" then local coords = GetEntityCoords(PlayerPedId()) local isInMarker, currentZone = false @@ -481,8 +477,7 @@ CreateThread(function() if v.Type ~= -1 and distance < Config.DrawDistance then sleep = 0 - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) end if distance < v.Size.x then @@ -492,12 +487,12 @@ CreateThread(function() if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent('bpt_taxijob:hasEnteredMarker', currentZone) + TriggerEvent("bpt_taxijob:hasEnteredMarker", currentZone) end if not isInMarker and HasAlreadyEnteredMarker then HasAlreadyEnteredMarker = false - TriggerEvent('bpt_taxijob:hasExitedMarker', LastZone) + TriggerEvent("bpt_taxijob:hasExitedMarker", LastZone) end end Wait(sleep) @@ -513,7 +508,7 @@ CreateThread(function() Sleep = 0 local playerPed = PlayerPedId() if CurrentCustomer == nil then - DrawSub(TranslateCap('drive_search_pass'), 5000) + DrawSub(TranslateCap("drive_search_pass"), 5000) if IsPedInAnyVehicle(playerPed, false) and OnJob then Wait(5000) @@ -534,12 +529,12 @@ CreateThread(function() local standTime = GetRandomIntInRange(60000, 180000) TaskStandStill(CurrentCustomer, standTime) - ESX.ShowNotification(TranslateCap('customer_found')) + ESX.ShowNotification(TranslateCap("customer_found")) end end else if IsPedFatallyInjured(CurrentCustomer) then - ESX.ShowNotification(TranslateCap('client_unconcious')) + ESX.ShowNotification(TranslateCap("client_unconcious")) if DoesBlipExist(CurrentCustomerBlip) then RemoveBlip(CurrentCustomerBlip) @@ -551,8 +546,7 @@ CreateThread(function() SetEntityAsMissionEntity(CurrentCustomer, false, true) - CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = - nil, nil, nil, false, false, false, nil + CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = nil, nil, nil, false, false, false, nil end if IsPedInAnyVehicle(playerPed, false) then @@ -568,12 +562,11 @@ CreateThread(function() if targetDistance <= 10.0 then TaskLeaveVehicle(CurrentCustomer, vehicle, 0) - ESX.ShowNotification(TranslateCap('arrive_dest')) + ESX.ShowNotification(TranslateCap("arrive_dest")) - TaskGoStraightToCoord(CurrentCustomer, targetCoords.x, targetCoords.y, targetCoords.z, - 1.0, -1, 0.0, 0.0) + TaskGoStraightToCoord(CurrentCustomer, targetCoords.x, targetCoords.y, targetCoords.z, 1.0, -1, 0.0, 0.0) SetEntityAsMissionEntity(CurrentCustomer, false, true) - TriggerServerEvent('bpt_taxijob:success') + TriggerServerEvent("bpt_taxijob:success") RemoveBlip(DestinationBlip) local function scope(customer) @@ -584,13 +577,11 @@ CreateThread(function() scope(CurrentCustomer) - CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = - nil, nil, nil, false, false, false, nil + CurrentCustomer, CurrentCustomerBlip, DestinationBlip, IsNearCustomer, CustomerIsEnteringVehicle, CustomerEnteredVehicle, targetCoords = nil, nil, nil, false, false, false, nil end if targetCoords then - DrawMarker(36, targetCoords.x, targetCoords.y, targetCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) + DrawMarker(36, targetCoords.x, targetCoords.y, targetCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) end else RemoveBlip(CurrentCustomerBlip) @@ -604,36 +595,33 @@ CreateThread(function() distance = #(playerCoords - targetCoords) end - local street = table.pack(GetStreetNameAtCoord(targetCoords.x, targetCoords.y, - targetCoords.z)) + local street = table.pack(GetStreetNameAtCoord(targetCoords.x, targetCoords.y, targetCoords.z)) local msg = nil if street[2] ~= 0 and street[2] ~= nil then - msg = string.format(TranslateCap('take_me_to_near', GetStreetNameFromHashKey(street[1]), - GetStreetNameFromHashKey(street[2]))) + msg = string.format(TranslateCap("take_me_to_near", GetStreetNameFromHashKey(street[1]), GetStreetNameFromHashKey(street[2]))) else - msg = string.format(TranslateCap('take_me_to', GetStreetNameFromHashKey(street[1]))) + msg = string.format(TranslateCap("take_me_to", GetStreetNameFromHashKey(street[1]))) end ESX.ShowNotification(msg) DestinationBlip = AddBlipForCoord(targetCoords.x, targetCoords.y, targetCoords.z) - BeginTextCommandSetBlipName('STRING') - AddTextComponentSubstringPlayerName('Destination') + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName("Destination") EndTextCommandSetBlipName(DestinationBlip) SetBlipRoute(DestinationBlip, true) CustomerEnteredVehicle = true end else - DrawMarker(36, customerCoords.x, customerCoords.y, customerCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) + DrawMarker(36, customerCoords.x, customerCoords.y, customerCoords.z + 1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 234, 223, 72, 155, false, false, 2, true, nil, nil, false) if not CustomerEnteredVehicle then if customerDistance <= 40.0 then if not IsNearCustomer then - ESX.ShowNotification(TranslateCap('close_to_client')) + ESX.ShowNotification(TranslateCap("close_to_client")) IsNearCustomer = true end end @@ -660,7 +648,7 @@ CreateThread(function() end end else - DrawSub(TranslateCap('return_to_veh'), 5000) + DrawSub(TranslateCap("return_to_veh"), 5000) end end end @@ -675,7 +663,7 @@ CreateThread(function() if not IsInAuthorizedVehicle() then ClearCurrentMission() OnJob = false - ESX.ShowNotification(TranslateCap('not_in_taxi')) + ESX.ShowNotification(TranslateCap("not_in_taxi")) end end end @@ -689,14 +677,14 @@ CreateThread(function() sleep = 0 ESX.ShowHelpNotification(CurrentActionMsg) - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then - if CurrentAction == 'taxi_actions_menu' then + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "taxi" then + if CurrentAction == "taxi_actions_menu" then OpenTaxiActionsMenu() - elseif CurrentAction == 'cloakroom' then + elseif CurrentAction == "cloakroom" then OpenCloakroom() - elseif CurrentAction == 'vehicle_spawner' then + elseif CurrentAction == "vehicle_spawner" then OpenVehicleSpawnerMenu() - elseif CurrentAction == 'delete_vehicle' then + elseif CurrentAction == "delete_vehicle" then DeleteJobVehicle() end @@ -707,11 +695,10 @@ CreateThread(function() end end) -RegisterCommand('taximenu', function() - if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == - 'taxi' then +RegisterCommand("taximenu", function() + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "taxi" then OpenMobileTaxiActionsMenu() end end, false) -RegisterKeyMapping('taximenu', 'Open Taxi Menu', 'keyboard', 'f6') +RegisterKeyMapping("taximenu", "Open Taxi Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_unicornjob/client/main.lua b/server-data/resources/[bpt_addons]/bpt_unicornjob/client/main.lua index 43ed87d72..42a35d08a 100644 --- a/server-data/resources/[bpt_addons]/bpt_unicornjob/client/main.lua +++ b/server-data/resources/[bpt_addons]/bpt_unicornjob/client/main.lua @@ -4,440 +4,375 @@ local LastZone RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) RegisterNetEvent("esx:onPlayerLogout") AddEventHandler("esx:onPlayerLogout", function() - ESX.PlayerLoaded = false - ESX.PlayerData = {} + ESX.PlayerLoaded = false + ESX.PlayerData = {} end) RegisterNetEvent("esx:setJob") AddEventHandler("esx:setJob", function(job) - ESX.PlayerData.job = job + ESX.PlayerData.job = job end) function DrawSub(msg, time) - ClearPrints() - BeginTextCommandPrint("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandPrint(time, 1) + ClearPrints() + BeginTextCommandPrint("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandPrint(time, 1) end function ShowLoadingPromt(msg, time, type) - CreateThread(function() - Wait(0) + CreateThread(function() + Wait(0) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandBusyspinnerOn(type) - Wait(time) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(msg) + EndTextCommandBusyspinnerOn(type) + Wait(time) - BusyspinnerOff() - end) + BusyspinnerOff() + end) end function OpenCloakroom() - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, - { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, - { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "wear_citizen" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - elseif element.value == "wear_work" then - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) - else - TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) - end - end) - end - ESX.CloseContext() - end, function() - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom_menu") }, + { icon = "fas fa-shirt", title = TranslateCap("wear_citizen"), value = "wear_citizen" }, + { icon = "fas fa-shirt", title = TranslateCap("wear_work"), value = "wear_work" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "wear_citizen" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + elseif element.value == "wear_work" then + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + end) + end + ESX.CloseContext() + end, function() + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end) end function OpenVehicleSpawnerMenu() - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, - } - - if Config.EnableSocietyOwnedVehicles then - ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) - if #vehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #vehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", - value = vehicles[i], - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - local vehicleProps = element.value - ESX.TriggerServerCallback("bpt_unicornjob:SpawnVehicle", function() - return - end, vehicleProps.model, vehicleProps) - TriggerServerEvent("esx_society:removeVehicleFromGarage", "unicorn", vehicleProps) - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end, "unicorn") - else -- not society vehicles - if #Config.AuthorizedVehicles == 0 then - ESX.ShowNotification(TranslateCap("empty_garage")) - return - end - - for i = 1, #Config.AuthorizedVehicles, 1 do - elements[#elements + 1] = { - icon = "fas fa-car", - title = Config.AuthorizedVehicles[i].label, - value = Config.AuthorizedVehicles[i].model, - } - end - - ESX.OpenContext("right", elements, function(_, element) - if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then - ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) - return - end - - if element.value == nil then - print("ERROR: Context menu clicked item value is nil!") - return - end - - ESX.TriggerServerCallback("bpt_unicornjob:SpawnVehicle", function() - ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") - end, element.value, { plate = "CORN JOB" }) - ESX.CloseContext() - end, function() - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - end) - end + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("spawn_veh") }, + } + + if Config.EnableSocietyOwnedVehicles then + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) + if #vehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #vehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + local vehicleProps = element.value + ESX.TriggerServerCallback("bpt_unicornjob:SpawnVehicle", function() + return + end, vehicleProps.model, vehicleProps) + TriggerServerEvent("esx_society:removeVehicleFromGarage", "unicorn", vehicleProps) + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end, "unicorn") + else -- not society vehicles + if #Config.AuthorizedVehicles == 0 then + ESX.ShowNotification(TranslateCap("empty_garage")) + return + end + + for i = 1, #Config.AuthorizedVehicles, 1 do + elements[#elements + 1] = { + icon = "fas fa-car", + title = Config.AuthorizedVehicles[i].label, + value = Config.AuthorizedVehicles[i].model, + } + end + + ESX.OpenContext("right", elements, function(_, element) + if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then + ESX.ShowNotification(TranslateCap("spawnpoint_blocked")) + return + end + + if element.value == nil then + print("ERROR: Context menu clicked item value is nil!") + return + end + + ESX.TriggerServerCallback("bpt_unicornjob:SpawnVehicle", function() + ESX.ShowNotification(TranslateCap("vehicle_spawned"), "success") + end, element.value, { plate = "CORN JOB" }) + ESX.CloseContext() + end, function() + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + end) + end end function DeleteJobVehicle() - if Config.EnableSocietyOwnedVehicles then - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent("esx_society:putVehicleInGarage", "unicorn", vehicleProps) - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - else - if IsInAuthorizedVehicle() then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - - if Config.MaxInService ~= -1 then - TriggerServerEvent("esx_service:disableService", "unicorn") - end - else - ESX.ShowNotification(TranslateCap("onlyTranslateCapnicorn")) - end - end + if Config.EnableSocietyOwnedVehicles then + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent("esx_society:putVehicleInGarage", "unicorn", vehicleProps) + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + else + if IsInAuthorizedVehicle() then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + + if Config.MaxInService ~= -1 then + TriggerServerEvent("esx_service:disableService", "unicorn") + end + else + ESX.ShowNotification(TranslateCap("onlyTranslateCapnicorn")) + end + end end function OpenUnicornActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-unicorn", title = TranslateCap("unicorn") }, - { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, - { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then - elements[#elements + 1] = { - icon = "fas fa-wallet", - title = TranslateCap("boss_actions"), - value = "boss_actions", - } - end - - ESX.OpenContext("right", elements, function(_, element) - if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_unicorn") - return ESX.CloseContext() - elseif element.value == "put_stock" then - OpenPutStocksMenu() - elseif element.value == "get_stock" then - OpenGetStocksMenu() - elseif element.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "unicorn", function(_, menu) - menu.close() - end) - end - end, function() - CurrentAction = "unicorn_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-unicorn", title = TranslateCap("unicorn") }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("take_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-wallet", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(_, element) + if Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_unicorn") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "unicorn", function(_, menu) + menu.close() + end) + end + end, function() + CurrentAction = "unicorn_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + end) end function OpenMobileUnicornActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-unicorn", title = TranslateCap("unicorn") }, - { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, - } - - ESX.OpenContext("right", elements, function(_, element) - if element.value == "billing" then - local elements2 = { - { unselectable = true, icon = "fas fa-unicorn", title = element.title }, - { - title = TranslateCap("amount"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 250000, - inputPlaceholder = TranslateCap("bill_amount"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2) - local amount = tonumber(menu2.eles[2].inputValue) - if amount == nil then - ESX.ShowNotification(TranslateCap("amount_invalid")) - else - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players_near")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "societyTranslateCapnicorn", - "Unicorn", - amount - ) - ESX.ShowNotification(TranslateCap("billing_sent")) - end - end - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-unicorn", title = TranslateCap("unicorn") }, + { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" }, + } + + ESX.OpenContext("right", elements, function(_, element) + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-unicorn", title = element.title }, + { + title = TranslateCap("amount"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 250000, + inputPlaceholder = TranslateCap("bill_amount"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2) + local amount = tonumber(menu2.eles[2].inputValue) + if amount == nil then + ESX.ShowNotification(TranslateCap("amount_invalid")) + else + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_near")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "societyTranslateCapnicorn", "Unicorn", amount) + ESX.ShowNotification(TranslateCap("billing_sent")) + end + end + end) + end + end) end function IsInAuthorizedVehicle() - local playerPed = PlayerPedId() - local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) + local playerPed = PlayerPedId() + local vehModel = GetEntityModel(GetVehiclePedIsIn(playerPed, false)) - for i = 1, #Config.AuthorizedVehicles, 1 do - if vehModel == joaat(Config.AuthorizedVehicles[i].model) then - return true - end - end + for i = 1, #Config.AuthorizedVehicles, 1 do + if vehModel == joaat(Config.AuthorizedVehicles[i].model) then + return true + end + end - return false + return false end AddEventHandler("bpt_unicornjob:hasEnteredMarker", function(zone) - if zone == "VehicleSpawner" then - CurrentAction = "vehicle_spawner" - CurrentActionMsg = TranslateCap("spawner_prompt") - CurrentActionData = {} - elseif zone == "VehicleDeleter" then - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then - CurrentAction = "delete_vehicle" - CurrentActionMsg = TranslateCap("store_veh") - CurrentActionData = { - vehicle = vehicle, - } - end - elseif zone == "UnicornActions" then - CurrentAction = "unicorn_actions_menu" - CurrentActionMsg = TranslateCap("press_to_open") - CurrentActionData = {} - elseif zone == "Cloakroom" then - CurrentAction = "cloakroom" - CurrentActionMsg = TranslateCap("cloakroom_prompt") - CurrentActionData = {} - end + if zone == "VehicleSpawner" then + CurrentAction = "vehicle_spawner" + CurrentActionMsg = TranslateCap("spawner_prompt") + CurrentActionData = {} + elseif zone == "VehicleDeleter" then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("store_veh") + CurrentActionData = { + vehicle = vehicle, + } + end + elseif zone == "UnicornActions" then + CurrentAction = "unicorn_actions_menu" + CurrentActionMsg = TranslateCap("press_to_open") + CurrentActionData = {} + elseif zone == "Cloakroom" then + CurrentAction = "cloakroom" + CurrentActionMsg = TranslateCap("cloakroom_prompt") + CurrentActionData = {} + end end) AddEventHandler("bpt_unicornjob:hasExitedMarker", function() - ESX.CloseContext() - CurrentAction = nil + ESX.CloseContext() + CurrentAction = nil end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord( - Config.Zones.UnicornActions.Pos.x, - Config.Zones.UnicornActions.Pos.y, - Config.Zones.UnicornActions.Pos.z - ) - - SetBlipSprite(blip, 121) - SetBlipDisplay(blip, 4) - SetBlipScale(blip, 1.0) - SetBlipColour(blip, 27) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("blipTranslateCapnicorn")) - EndTextCommandSetBlipName(blip) + local blip = AddBlipForCoord(Config.Zones.UnicornActions.Pos.x, Config.Zones.UnicornActions.Pos.y, Config.Zones.UnicornActions.Pos.z) + + SetBlipSprite(blip, 121) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 27) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("blipTranslateCapnicorn")) + EndTextCommandSetBlipName(blip) end) -- Enter / Exit marker events, and draw markers CreateThread(function() - while true do - local sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "unicorn" then - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker, currentZone = false - local inVeh = IsPedInAnyVehicle(PlayerPedId()) - - for k, v in pairs(Config.Zones) do - local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - local distance = #(coords - zonePos) - - if v.Type ~= -1 and distance < Config.DrawDistance then - sleep = 0 - if k == "VehicleDeleter" then - if inVeh then - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - else - DrawMarker( - v.Type, - v.Pos.x, - v.Pos.y, - v.Pos.z, - 0.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, - false, - 2, - v.Rotate, - nil, - nil, - false - ) - end - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - TriggerEvent("bpt_unicornjob:hasEnteredMarker", currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("bpt_unicornjob:hasExitedMarker", LastZone) - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "unicorn" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker, currentZone = false + local inVeh = IsPedInAnyVehicle(PlayerPedId()) + + for k, v in pairs(Config.Zones) do + local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) + local distance = #(coords - zonePos) + + if v.Type ~= -1 and distance < Config.DrawDistance then + sleep = 0 + if k == "VehicleDeleter" then + if inVeh then + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + else + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, false, 2, v.Rotate, nil, nil, false) + end + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + TriggerEvent("bpt_unicornjob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("bpt_unicornjob:hasExitedMarker", LastZone) + end + end + Wait(sleep) + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 1500 - if CurrentAction and not ESX.PlayerData.dead then - sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "unicorn" then - if CurrentAction == "unicorn_actions_menu" then - OpenUnicornActionsMenu() - elseif CurrentAction == "cloakroom" then - OpenCloakroom() - elseif CurrentAction == "vehicle_spawner" then - OpenVehicleSpawnerMenu() - elseif CurrentAction == "delete_vehicle" then - DeleteJobVehicle() - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 1500 + if CurrentAction and not ESX.PlayerData.dead then + sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "unicorn" then + if CurrentAction == "unicorn_actions_menu" then + OpenUnicornActionsMenu() + elseif CurrentAction == "cloakroom" then + OpenCloakroom() + elseif CurrentAction == "vehicle_spawner" then + OpenVehicleSpawnerMenu() + elseif CurrentAction == "delete_vehicle" then + DeleteJobVehicle() + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) RegisterCommand("unicornmenu", function() - if - not ESX.PlayerData.dead - and Config.EnablePlayerManagement - and ESX.PlayerData.job - and ESX.PlayerData.job.name == "unicorn" - then - OpenMobileUnicornActionsMenu() - end + if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == "unicorn" then + OpenMobileUnicornActionsMenu() + end end, false) RegisterKeyMapping("unicornmenu", "Open Unicorn Menu", "keyboard", "f6") diff --git a/server-data/resources/[bpt_addons]/bpt_vehicletax/server/server.lua b/server-data/resources/[bpt_addons]/bpt_vehicletax/server/server.lua index ae4b37ac3..f723d7a2d 100644 --- a/server-data/resources/[bpt_addons]/bpt_vehicletax/server/server.lua +++ b/server-data/resources/[bpt_addons]/bpt_vehicletax/server/server.lua @@ -3,43 +3,40 @@ local percentage = 1 ESX = exports["es_extended"]:getSharedObject() MySQL.ready(function() - local result = MySQL.Sync.fetchAll("SELECT * FROM vehicles") - for i = 1, #result, 1 do - if vehicleprices[(GetHashKey(result[i].model))] == nil then - table.insert(vehicleprices, { model = GetHashKey(result[i].model), price = result[i].price }) - end - end + local result = MySQL.Sync.fetchAll("SELECT * FROM vehicles") + for i = 1, #result, 1 do + if vehicleprices[(GetHashKey(result[i].model))] == nil then + table.insert(vehicleprices, { model = GetHashKey(result[i].model), price = result[i].price }) + end + end end) function Tax() - local result = MySQL.Sync.fetchAll("SELECT * FROM owned_vehicles") - local xPlayers = ESX.GetPlayers() + local result = MySQL.Sync.fetchAll("SELECT * FROM owned_vehicles") + local xPlayers = ESX.GetPlayers() - for i = 1, #result, 1 do - if result[i].job == "" or result[i].job == nil then - local sqlplayer = ESX.GetPlayerFromIdentifier(result[i].owner) + for i = 1, #result, 1 do + if result[i].job == "" or result[i].job == nil then + local sqlplayer = ESX.GetPlayerFromIdentifier(result[i].owner) - if sqlplayer ~= nil then - for j = 1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[j]) + if sqlplayer ~= nil then + for j = 1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[j]) - if xPlayer.identifier == result[i].owner then - local model = json.decode(result[i].vehicle).model + if xPlayer.identifier == result[i].owner then + local model = json.decode(result[i].vehicle).model - for m = 1, #vehicleprices, 1 do - if vehicleprices[m].model == model then - TriggerEvent("esx_billing:sendBill", xPlayer[j], "society_cardealer", - TranslateCap("vehicle_tax") .. result[i].plate, - ((vehicleprices[m].price * percentage) / 100), 1 - ) - break - end - end - end - end - end - end - end + for m = 1, #vehicleprices, 1 do + if vehicleprices[m].model == model then + TriggerEvent("bpt_billing:sendBill", xPlayer[j], "society_cardealer", TranslateCap("vehicle_tax") .. result[i].plate, ((vehicleprices[m].price * percentage) / 100), 1) + break + end + end + end + end + end + end + end end TriggerEvent("cron", 24, 0, Tax) diff --git a/server-data/resources/[esx_addons]/esx_billing/README.md b/server-data/resources/[esx_addons]/esx_billing/README.md deleted file mode 100644 index 65b38b761..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# esx_billing - -## Usage -Press `[F7]` To show the billing menu - -When payment trigger is called , pass a boolean at the end to convert payment into split payment. -```lua -TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_mechanic', _U('mechanic'), amount, true) -``` - -```lua -local amount = 100 -local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - -if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('There\'s no players nearby!') -else - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_taxi', 'Taxi', amount) -end -``` \ No newline at end of file diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/br.lua b/server-data/resources/[esx_addons]/esx_billing/locales/br.lua deleted file mode 100644 index 09c61d70a..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/br.lua +++ /dev/null @@ -1,10 +0,0 @@ -Locales["br"] = { - ["invoices"] = "faturas", - ["invoices_item"] = "$%s", - ["received_invoice"] = "você ~r~recebeu~s~ uma fatura", - ["paid_invoice"] = "você ~g~pagou~s~ uma fatura de ~r~$%s~s~", - ["received_payment"] = "você ~g~recebeu~s~ um pagamento de ~r~$%s~s~", - ["player_not_online"] = "o jogador não está logado", - ["no_money"] = "you do not have enough money to pay this bill", - ["target_no_money"] = "the player ~r~does not~s~ have enough money to pay the bill!", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/cs.lua b/server-data/resources/[esx_addons]/esx_billing/locales/cs.lua deleted file mode 100644 index 58b9062eb..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/cs.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["cs"] = { - ["invoices"] = "faktury", - ["invoices_item"] = "$%s", - ["received_invoice"] = "právě jsi ~r~obdrzel fakturu", - ["paid_invoice"] = "zaplatil jsi fakturu za ~r~$%s", - ["no_invoices"] = "momentalne nemas zadnou fatkuru k zaplaceni", - ["received_payment"] = "obdržel jsi platbu za ~r~$%s", - ["player_not_online"] = "hráč není přihlášen", - ["no_money"] = "nemáš dostatek peněz na zaplacení této faktury", - ["target_no_money"] = "hráč ~r~nemá dostatek peněz na zaplacení faktury!", - ["keymap_showbills"] = "otevrit menu faktur", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/da.lua b/server-data/resources/[esx_addons]/esx_billing/locales/da.lua deleted file mode 100644 index c20317ae0..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/da.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["da"] = { - ["invoices"] = "regninger", - ["invoices_item"] = "DKK%s", - ["received_invoice"] = "du har lige ~r~modtaget en faktura", - ["paid_invoice"] = "du har betalt en faktura på ~r~DKK%s", - ["no_invoices"] = "du har ingen regninger at betale i øjeblikket", - ["received_payment"] = "du har modtaget en betaling på ~r~DKK%s", - ["player_not_online"] = "spilleren er ikke online", - ["no_money"] = "du har ikke penge nok til at betale denne regning", - ["target_no_money"] = "spilleren ~r~har ikke penge nok til at betale regningen!", - ["keymap_showbills"] = "åbne regninger menu", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/de.lua b/server-data/resources/[esx_addons]/esx_billing/locales/de.lua deleted file mode 100644 index b1af181ed..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/de.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["de"] = { - ["invoices"] = "Rechnungen", - ["invoices_item"] = "%s€", - ["received_invoice"] = "Du hast eine ~r~Rechnung~r~ erhalten!", - ["paid_invoice"] = "Du bezahlst eine Rechung in der Höhe von ~r~%s€", - ["no_invoices"] = "Du hast derzeit keine Rechnung!", - ["received_payment"] = "Du bekommst eine bezahlung von ~r~%s€", - ["player_not_online"] = "Dieser Spieler ist nicht Online!", - ["no_money"] = "Du hast nicht genügend Geld um diese Rechung zu zahlen", - ["target_no_money"] = "Diese Person ~r~hat nicht genug Geld um die Rechnung zu zahlen!", - ["keymap_showbills"] = "Rechnungen Menü Öffnen", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/el.lua b/server-data/resources/[esx_addons]/esx_billing/locales/el.lua deleted file mode 100644 index 847330efd..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/el.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["el"] = { - ["invoices"] = "Αποδείξεις", - ["invoices_item"] = "$%s", - ["received_invoice"] = "Μόλις λάβατε μια απόδειξη", - ["paid_invoice"] = "Πληρώσατε μια απόδειξη αξίας ~r~$%s", - ["no_invoices"] = "Δεν έχετε καμία απόδειξη να πληρώσετε αυτήν τη στιγμή", - ["received_payment"] = "Λάβατε μια πληρωμή αξίας ~r~$%s", - ["player_not_online"] = "Ο παίκτης δεν είναι συνδεδεμένος", - ["no_money"] = "Δεν έχετε αρκετά χρήματα για να πληρώσετε αυτή την απόδειξη", - ["target_no_money"] = "Ο παίκτης ~r~δεν έχει αρκετά χρήματα για να πληρώσει την απόδειξη!", - ["keymap_showbills"] = "Ανοίξτε το μενού αποδείξεων", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/es.lua b/server-data/resources/[esx_addons]/esx_billing/locales/es.lua deleted file mode 100644 index 624e98d34..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/es.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["es"] = { - ["invoices"] = "Facturas", - ["invoices_item"] = "%s$", - ["received_invoice"] = "Has ~r~recibido una multa", - ["paid_invoice"] = "Has pagado una multa de ~r~%s$", - ["no_invoices"] = "No dispones de factuas para pagar ahora mismo", - ["received_payment"] = "Has recibido un pago de %s$", - ["player_not_online"] = "El jugador no está en linea", - ["no_money"] = "No tienes suficiente dinero para pagar la factura", - ["target_no_money"] = "¡El jugador ~r~no tiene suficiente dinero para pagar la factura!", - ["keymap_showbills"] = "Abrir menú de facturas", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/fi.lua b/server-data/resources/[esx_addons]/esx_billing/locales/fi.lua deleted file mode 100644 index 981186acd..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/fi.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["fi"] = { - ["invoices"] = "laskut", - ["invoices_item"] = "$%s", - ["received_invoice"] = "sinä ~r~sait laskun", - ["paid_invoice"] = "sinä maksoit laskun suuruudelta ~r~$%s", - ["no_invoices"] = "you do not have any bills to pay at this moment", - ["received_payment"] = "sinä sait maksun suuruudelta ~r~$%s", - ["player_not_online"] = "pelaaja ei ole sisäänkirjautuneena", - ["no_money"] = "sinulla ei ole tarpeeksi rahaa maksaaksesi tätä laskua.", - ["target_no_money"] = "pelaajalla ~r~ei ole tarpeeksi rahaa maksaakseentätä laskua", - ["keymap_showbills"] = "open bills menu", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/fr.lua b/server-data/resources/[esx_addons]/esx_billing/locales/fr.lua deleted file mode 100644 index 07f9d4730..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/fr.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["fr"] = { - ["invoices"] = "factures", - ["invoices_item"] = "$%s", - ["received_invoice"] = "vous avez ~r~reçu une facture", - ["paid_invoice"] = "vous avez payé une facture de ~r~$%s", - ["no_invoices"] = "vous n'avez aucune facture à payer en ce moment", - ["received_payment"] = "vous avez reçu un paiement de $%s", - ["player_not_online"] = "le joueur n'est pas connecté", - ["no_money"] = "vous n'avez pas assez d'argent pour payer cette facture", - ["target_no_money"] = "le joueur ~r~n'a pas assez d'argent pour payer la facture!", - ["keymap_showbills"] = "ouvrir le menu des factures", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/hu.lua b/server-data/resources/[esx_addons]/esx_billing/locales/hu.lua deleted file mode 100644 index 3774e1f81..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/hu.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["hu"] = { - ["invoices"] = "Számlák", - ["invoices_item"] = "$%s", - ["received_invoice"] = "Kaptál egy számlát", - ["paid_invoice"] = "Befizettél egy számlát ( ~r~$%s )", - ["no_invoices"] = "Nincsen számlád amit kifizethetnél", - ["received_payment"] = "Fizetést kaptál: ~r~$%s", - ["player_not_online"] = "A játékos nem elérhető", - ["no_money"] = "Nincsen elég pénzed, hogy kifizesd ezt a számlát", - ["target_no_money"] = "A játékosnak nincsen annyi pénze, hogy befizesse a számlát", - ["keymap_showbills"] = "Számlák megnézése", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/nl.lua b/server-data/resources/[esx_addons]/esx_billing/locales/nl.lua deleted file mode 100644 index ca887496d..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/nl.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["nl"] = { - ["invoices"] = "Facturen", - ["invoices_item"] = "€%s", - ["received_invoice"] = "Je hebt zojuist een ~r~factuur ontvangen", - ["paid_invoice"] = "Je hebt een factuur betaald van ~r~€%s", - ["no_invoices"] = "Je hoeft momenteel geen facturen te betalen", - ["received_payment"] = "je hebt een bedrag ontvangen van ~r~€%s", - ["player_not_online"] = "de speler is niet online", - ["no_money"] = "je hebt niet genoeg geld om deze factuur te betalen", - ["target_no_money"] = "de speler ~r~heeft niet genoeg geld om te betalen!", - ["keymap_showbills"] = "open factuur menu", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/pl.lua b/server-data/resources/[esx_addons]/esx_billing/locales/pl.lua deleted file mode 100644 index d84bc045b..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/pl.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["pl"] = { - ["invoices"] = "faktury", - ["invoices_item"] = "$%s", - ["received_invoice"] = "właśnie ~r~dostałeś/aś fakture", - ["paid_invoice"] = "Zapłaciłeś/aś fakture: ~r~$%s", - ["no_invoices"] = "you do not have any bills to pay at this moment", - ["received_payment"] = "Otrzymałeś/aś zapłate: ~r~$%s", - ["player_not_online"] = "gracz nie jest zalogowany", - ["no_money"] = "nie masz wystarczająco pieniędzy aby zapłacić tą fakture", - ["target_no_money"] = "gracz ~r~nie posiada wystarczająco pieniędzy aby zapłacić tą fakture!", - ["keymap_showbills"] = "open bills menu", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/sl.lua b/server-data/resources/[esx_addons]/esx_billing/locales/sl.lua deleted file mode 100644 index 5197553c2..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/sl.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["sl"] = { - ["invoices"] = "Položnice", - ["invoices_item"] = "$%s", - ["received_invoice"] = "pravkar ste ~r~prejeli račun", - ["paid_invoice"] = "plačali ste račun v višini ~r~$%s", - ["no_invoices"] = "v tem trenutku nimate nobenih računov za plačilo", - ["received_payment"] = "prejeli ste plačilo ~r~$%s", - ["player_not_online"] = "igralec ni prijavljen", - ["no_money"] = "nimate dovolj denarja za plačilo tega računa", - ["target_no_money"] = "igralec ~r~nima dovolj denarja za plačilo računa!", - ["keymap_showbills"] = "Odpri Položnice", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/sr.lua b/server-data/resources/[esx_addons]/esx_billing/locales/sr.lua deleted file mode 100644 index cda4a14e4..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/sr.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["sr"] = { - ["invoices"] = "Računi", - ["invoices_item"] = "$%s", - ["received_invoice"] = "Vi ste ~r~dobili novi račun", - ["paid_invoice"] = "Platili ste račun od ~r~$%s", - ["no_invoices"] = "Nemate računa za plaćanje trenutno", - ["received_payment"] = "Primili ste uplatu u iznosu od ~r~$%s", - ["player_not_online"] = "Osoba nije tu", - ["no_money"] = "Nemate dovoljno novca da platite račun", - ["target_no_money"] = "Osoba ~r~nema dovoljno novca da plati račun!", - ["keymap_showbills"] = "Otvori Račune", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/sv.lua b/server-data/resources/[esx_addons]/esx_billing/locales/sv.lua deleted file mode 100644 index 0adeca80e..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/sv.lua +++ /dev/null @@ -1,10 +0,0 @@ -Locales["sv"] = { - ["invoices"] = "räkningar", - ["invoices_item"] = "%s SEK", - ["received_invoice"] = "du har ~y~mottagit~s~ en räkning", - ["paid_invoice"] = "du ~y~betalade~s~ precis en räkning på ~g~%s SEK~s~", - ["received_payment"] = "du har ~y~mottagit~s~ en räkning på ~g~%s SEK~s~", - ["player_not_online"] = "personen är inte online", - ["no_money"] = "du har ~r~inte råd~s~ för att kunna betala räkningen", - ["target_no_money"] = "personen har ~r~inte råd~s~ för att betala räkningen", -} diff --git a/server-data/resources/[esx_addons]/esx_billing/locales/zh-cn.lua b/server-data/resources/[esx_addons]/esx_billing/locales/zh-cn.lua deleted file mode 100644 index 0be1096ad..000000000 --- a/server-data/resources/[esx_addons]/esx_billing/locales/zh-cn.lua +++ /dev/null @@ -1,12 +0,0 @@ -Locales["zh-cn"] = { - ["invoices"] = "账单", - ["invoices_item"] = "$%s", - ["received_invoice"] = "新增一笔~r~新的账单! 请及时支付!", - ["paid_invoice"] = "已支付一笔~r~$%s元的账单", - ["no_invoices"] = "当前账户尚无可供支付的账单", - ["received_payment"] = "已收到~r~$%s元的账单支付", - ["player_not_online"] = "指定的玩家尚未登录!", - ["no_money"] = "您没有足够的钱支付此账单", - ["target_no_money"] = "此人暂无~r~足够资金可支付账单!", - ["keymap_showbills"] = "打开我的账单", -} diff --git a/server-data/resources/[esx_addons]/esx_mechanicjob/client/main.lua b/server-data/resources/[esx_addons]/esx_mechanicjob/client/main.lua index fc3268128..2e5ad8dac 100644 --- a/server-data/resources/[esx_addons]/esx_mechanicjob/client/main.lua +++ b/server-data/resources/[esx_addons]/esx_mechanicjob/client/main.lua @@ -1,950 +1,949 @@ local HasAlreadyEnteredMarker, LastZone = false, nil -local CurrentAction, CurrentActionMsg, CurrentActionData = nil, '', {} +local CurrentAction, CurrentActionMsg, CurrentActionData = nil, "", {} local CurrentlyTowedVehicle, Blips, NPCOnJob, NPCTargetTowable, NPCTargetTowableZone = nil, {}, false, nil, nil local NPCHasSpawnedTowable, NPCLastCancel, NPCHasBeenNextToTowable, NPCTargetDeleterZone = false, GetGameTimer() - 5 * 60000, false, false local isDead, isBusy = false, false function SelectRandomTowable() - local index = GetRandomIntInRange(1, #Config.Towables) + local index = GetRandomIntInRange(1, #Config.Towables) - for k,v in pairs(Config.Zones) do - if v.Pos.x == Config.Towables[index].x and v.Pos.y == Config.Towables[index].y and v.Pos.z == Config.Towables[index].z then - return k - end - end + for k, v in pairs(Config.Zones) do + if v.Pos.x == Config.Towables[index].x and v.Pos.y == Config.Towables[index].y and v.Pos.z == Config.Towables[index].z then + return k + end + end end function StartNPCJob() - NPCOnJob = true + NPCOnJob = true - NPCTargetTowableZone = SelectRandomTowable() - local zone = Config.Zones[NPCTargetTowableZone] + NPCTargetTowableZone = SelectRandomTowable() + local zone = Config.Zones[NPCTargetTowableZone] - Blips['NPCTargetTowableZone'] = AddBlipForCoord(zone.Pos.x, zone.Pos.y, zone.Pos.z) - SetBlipRoute(Blips['NPCTargetTowableZone'], true) + Blips["NPCTargetTowableZone"] = AddBlipForCoord(zone.Pos.x, zone.Pos.y, zone.Pos.z) + SetBlipRoute(Blips["NPCTargetTowableZone"], true) - ESX.ShowNotification(TranslateCap('drive_to_indicated')) + ESX.ShowNotification(TranslateCap("drive_to_indicated")) end function StopNPCJob(cancel) - if Blips['NPCTargetTowableZone'] then - RemoveBlip(Blips['NPCTargetTowableZone']) - Blips['NPCTargetTowableZone'] = nil - end - - if Blips['NPCDelivery'] then - RemoveBlip(Blips['NPCDelivery']) - Blips['NPCDelivery'] = nil - end - - Config.Zones.VehicleDelivery.Type = -1 - - NPCOnJob = false - NPCTargetTowable = nil - NPCTargetTowableZone = nil - NPCHasSpawnedTowable = false - NPCHasBeenNextToTowable = false - - if cancel then - ESX.ShowNotification(TranslateCap('mission_canceled'), "error") - end + if Blips["NPCTargetTowableZone"] then + RemoveBlip(Blips["NPCTargetTowableZone"]) + Blips["NPCTargetTowableZone"] = nil + end + + if Blips["NPCDelivery"] then + RemoveBlip(Blips["NPCDelivery"]) + Blips["NPCDelivery"] = nil + end + + Config.Zones.VehicleDelivery.Type = -1 + + NPCOnJob = false + NPCTargetTowable = nil + NPCTargetTowableZone = nil + NPCHasSpawnedTowable = false + NPCHasBeenNextToTowable = false + + if cancel then + ESX.ShowNotification(TranslateCap("mission_canceled"), "error") + end end function OpenMechanicActionsMenu() - local elements = { - {unselectable = true, icon = "fas fa-gear", title = TranslateCap('mechanic')}, - {icon = "fas fa-car", title = TranslateCap('vehicle_list'), value = 'vehicle_list'}, - {icon = "fas fa-shirt", title = TranslateCap('work_wear'), value = 'cloakroom'}, - {icon = "fas fa-shirt", title = TranslateCap('civ_wear'), value = 'cloakroom2'}, - {icon = "fas fa-box", title = TranslateCap('deposit_stock'), value = 'put_stock'}, - {icon = "fas fa-box", title = TranslateCap('withdraw_stock'), value = 'get_stock'} - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name == 'boss' then - elements[#elements+1] = { - icon = 'fas fa-boss', - title = TranslateCap('boss_actions'), - value = 'boss_actions' - } - end - - ESX.OpenContext("right", elements, function(menu,element) - if element.value == 'vehicle_list' then - if Config.EnableSocietyOwnedVehicles then - local elements2 = { - {unselectable = true, icon = "fas fa-car", title = TranslateCap('service_vehicle')} - } - - ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(vehicles) - for i=1, #vehicles, 1 do - elements2[#elements2+1] = { - icon = 'fas fa-car', - title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. ' [' .. vehicles[i].plate .. ']', - value = vehicles[i] - } - end - - ESX.OpenContext("right", elements2, function(menu2,element2) - ESX.CloseContext() - local vehicleProps = element2.value - - ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, 270.0, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - local playerPed = PlayerPedId() - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - - TriggerServerEvent('esx_society:removeVehicleFromGarage', 'mechanic', vehicleProps) - end) - end, 'mechanic') - else - local elements2 = { - {unselectable = true, icon = "fas fa-car", title = TranslateCap('service_vehicle')}, - {icon = "fas fa-truck", title = TranslateCap('flat_bed'), value = 'flatbed'}, - {icon = "fas fa-truck", title = TranslateCap('tow_truck'), value = 'towtruck2'} - } - - if Config.EnablePlayerManagement and ESX.PlayerData.job and (ESX.PlayerData.job.grade_name == 'boss' or ESX.PlayerData.job.grade_name == 'chief' or ESX.PlayerData.job.grade_name == 'experimente') then - elements2[#elements2+1] = { - icon = 'fas fa-truck', - title = 'Slamvan', - value = 'slamvan3' - } - end - - ESX.OpenContext("right", elements2, function(menu2,element2) - if Config.MaxInService == -1 then - ESX.CloseContext() - ESX.Game.SpawnVehicle(element2.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) - local playerPed = PlayerPedId() - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - else - ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) - if canTakeService then - ESX.CloseContext() - ESX.Game.SpawnVehicle(element2.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) - local playerPed = PlayerPedId() - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - else - ESX.ShowNotification(TranslateCap('service_full') .. inServiceCount .. '/' .. maxInService) - end - end, 'mechanic') - end - end) - end - elseif element.value == 'cloakroom' then - ESX.CloseContext() - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - if skin.sex == 0 then - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_male) - else - TriggerEvent('skinchanger:loadClothes', skin, jobSkin.skin_female) - end - end) - elseif element.value == 'cloakroom2' then - ESX.CloseContext() - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - TriggerEvent('skinchanger:loadSkin', skin) - end) - elseif Config.OxInventory and (element.value == 'put_stock' or element.value == 'get_stock') then - exports.ox_inventory:openInventory('stash', 'society_mechanic') - return ESX.CloseContext() - elseif element.value == 'put_stock' then - OpenPutStocksMenu() - elseif element.value == 'get_stock' then - OpenGetStocksMenu() - elseif element.value == 'boss_actions' then - TriggerEvent('esx_society:openBossMenu', 'mechanic', function(data, menu) - ESX.CloseContext() - end) - end - end, function(menu) - CurrentAction = 'mechanic_actions_menu' - CurrentActionMsg = TranslateCap('open_actions') - CurrentActionData = {} - end) + local elements = { + { unselectable = true, icon = "fas fa-gear", title = TranslateCap("mechanic") }, + { icon = "fas fa-car", title = TranslateCap("vehicle_list"), value = "vehicle_list" }, + { icon = "fas fa-shirt", title = TranslateCap("work_wear"), value = "cloakroom" }, + { icon = "fas fa-shirt", title = TranslateCap("civ_wear"), value = "cloakroom2" }, + { icon = "fas fa-box", title = TranslateCap("deposit_stock"), value = "put_stock" }, + { icon = "fas fa-box", title = TranslateCap("withdraw_stock"), value = "get_stock" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name == "boss" then + elements[#elements + 1] = { + icon = "fas fa-boss", + title = TranslateCap("boss_actions"), + value = "boss_actions", + } + end + + ESX.OpenContext("right", elements, function(menu, element) + if element.value == "vehicle_list" then + if Config.EnableSocietyOwnedVehicles then + local elements2 = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("service_vehicle") }, + } + + ESX.TriggerServerCallback("esx_society:getVehiclesInGarage", function(vehicles) + for i = 1, #vehicles, 1 do + elements2[#elements2 + 1] = { + icon = "fas fa-car", + title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]", + value = vehicles[i], + } + end + + ESX.OpenContext("right", elements2, function(menu2, element2) + ESX.CloseContext() + local vehicleProps = element2.value + + ESX.Game.SpawnVehicle(vehicleProps.model, Config.Zones.VehicleSpawnPoint.Pos, 270.0, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + + TriggerServerEvent("esx_society:removeVehicleFromGarage", "mechanic", vehicleProps) + end) + end, "mechanic") + else + local elements2 = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("service_vehicle") }, + { icon = "fas fa-truck", title = TranslateCap("flat_bed"), value = "flatbed" }, + { icon = "fas fa-truck", title = TranslateCap("tow_truck"), value = "towtruck2" }, + } + + if Config.EnablePlayerManagement and ESX.PlayerData.job and (ESX.PlayerData.job.grade_name == "boss" or ESX.PlayerData.job.grade_name == "chief" or ESX.PlayerData.job.grade_name == "experimente") then + elements2[#elements2 + 1] = { + icon = "fas fa-truck", + title = "Slamvan", + value = "slamvan3", + } + end + + ESX.OpenContext("right", elements2, function(menu2, element2) + if Config.MaxInService == -1 then + ESX.CloseContext() + ESX.Game.SpawnVehicle(element2.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + else + ESX.TriggerServerCallback("esx_service:enableService", function(canTakeService, maxInService, inServiceCount) + if canTakeService then + ESX.CloseContext() + ESX.Game.SpawnVehicle(element2.value, Config.Zones.VehicleSpawnPoint.Pos, 90.0, function(vehicle) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) + else + ESX.ShowNotification(TranslateCap("service_full") .. inServiceCount .. "/" .. maxInService) + end + end, "mechanic") + end + end) + end + elseif element.value == "cloakroom" then + ESX.CloseContext() + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_male) + else + TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female) + end + end) + elseif element.value == "cloakroom2" then + ESX.CloseContext() + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + elseif Config.OxInventory and (element.value == "put_stock" or element.value == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_mechanic") + return ESX.CloseContext() + elseif element.value == "put_stock" then + OpenPutStocksMenu() + elseif element.value == "get_stock" then + OpenGetStocksMenu() + elseif element.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "mechanic", function(data, menu) + ESX.CloseContext() + end) + end + end, function(menu) + CurrentAction = "mechanic_actions_menu" + CurrentActionMsg = TranslateCap("open_actions") + CurrentActionData = {} + end) end function OpenMechanicHarvestMenu() - if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name ~= 'recrue' then - local elements = { - {unselectable = true, icon = "fas fa-gear", title = "Mechanic Harvest Menu"}, - {icon = "fas fa-gear", title = TranslateCap('gas_can'), value = 'gaz_bottle'}, - {icon = "fas fa-gear", title = TranslateCap('repair_tools'), value = 'fix_tool'}, - {icon = "fas fa-gear", title = TranslateCap('body_work_tools'), value = 'caro_tool'} - } - - ESX.OpenContext("right", elements, function(menu,element) - if element.value == 'gaz_bottle' then - TriggerServerEvent('esx_mechanicjob:startHarvest') - elseif element.value == 'fix_tool' then - TriggerServerEvent('esx_mechanicjob:startHarvest2') - elseif element.value == 'caro_tool' then - TriggerServerEvent('esx_mechanicjob:startHarvest3') - end - end, function(menu) - CurrentAction = 'mechanic_harvest_menu' - CurrentActionMsg = TranslateCap('harvest_menu') - CurrentActionData = {} - end) - else - ESX.ShowNotification(TranslateCap('not_experienced_enough')) - end + if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name ~= "recrue" then + local elements = { + { unselectable = true, icon = "fas fa-gear", title = "Mechanic Harvest Menu" }, + { icon = "fas fa-gear", title = TranslateCap("gas_can"), value = "gaz_bottle" }, + { icon = "fas fa-gear", title = TranslateCap("repair_tools"), value = "fix_tool" }, + { icon = "fas fa-gear", title = TranslateCap("body_work_tools"), value = "caro_tool" }, + } + + ESX.OpenContext("right", elements, function(menu, element) + if element.value == "gaz_bottle" then + TriggerServerEvent("esx_mechanicjob:startHarvest") + elseif element.value == "fix_tool" then + TriggerServerEvent("esx_mechanicjob:startHarvest2") + elseif element.value == "caro_tool" then + TriggerServerEvent("esx_mechanicjob:startHarvest3") + end + end, function(menu) + CurrentAction = "mechanic_harvest_menu" + CurrentActionMsg = TranslateCap("harvest_menu") + CurrentActionData = {} + end) + else + ESX.ShowNotification(TranslateCap("not_experienced_enough")) + end end function OpenMechanicCraftMenu() - if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name ~= 'recrue' then - local elements = { - {unselectable = true, icon = "fas fa-gear", title = "Mechanic Craft Menu"}, - {icon = "fas fa-gear", title = TranslateCap('blowtorch'), value = 'blow_pipe'}, - {icon = "fas fa-gear", title = TranslateCap('repair_kit'), value = 'fix_kit'}, - {icon = "fas fa-gear", title = TranslateCap('body_kit'), value = 'caro_kit'} - } - - ESX.OpenContext("right", elements, function(menu,element) - if element.value == 'blow_pipe' then - TriggerServerEvent('esx_mechanicjob:startCraft') - elseif element.value == 'fix_kit' then - TriggerServerEvent('esx_mechanicjob:startCraft2') - elseif element.value == 'caro_kit' then - TriggerServerEvent('esx_mechanicjob:startCraft3') - end - end, function(menu) - CurrentAction = 'mechanic_craft_menu' - CurrentActionMsg = TranslateCap('craft_menu') - CurrentActionData = {} - end) - else - ESX.ShowNotification(TranslateCap('not_experienced_enough')) - end + if Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.grade_name ~= "recrue" then + local elements = { + { unselectable = true, icon = "fas fa-gear", title = "Mechanic Craft Menu" }, + { icon = "fas fa-gear", title = TranslateCap("blowtorch"), value = "blow_pipe" }, + { icon = "fas fa-gear", title = TranslateCap("repair_kit"), value = "fix_kit" }, + { icon = "fas fa-gear", title = TranslateCap("body_kit"), value = "caro_kit" }, + } + + ESX.OpenContext("right", elements, function(menu, element) + if element.value == "blow_pipe" then + TriggerServerEvent("esx_mechanicjob:startCraft") + elseif element.value == "fix_kit" then + TriggerServerEvent("esx_mechanicjob:startCraft2") + elseif element.value == "caro_kit" then + TriggerServerEvent("esx_mechanicjob:startCraft3") + end + end, function(menu) + CurrentAction = "mechanic_craft_menu" + CurrentActionMsg = TranslateCap("craft_menu") + CurrentActionData = {} + end) + else + ESX.ShowNotification(TranslateCap("not_experienced_enough")) + end end function OpenMobileMechanicActionsMenu() - local elements = { - {unselectable = true, icon = "fas fa-gear", title = TranslateCap('mechanic')}, - {icon = "fas fa-gear", title = TranslateCap('billing'), value = 'billing'}, - {icon = "fas fa-gear", title = TranslateCap('hijack'), value = 'hijack_vehicle'}, - {icon = "fas fa-gear", title = TranslateCap('repair'), value = 'fix_vehicle'}, - {icon = "fas fa-gear", title = TranslateCap('clean'), value = 'clean_vehicle'}, - {icon = "fas fa-gear", title = TranslateCap('imp_veh'), value = 'del_vehicle'}, - {icon = "fas fa-gear", title = TranslateCap('flat_bed'), value = 'dep_vehicle'}, - {icon = "fas fa-gear", title = TranslateCap('place_objects'), value = 'object_spawner'} - } - - ESX.OpenContext("right", elements, function(menu,element) - if isBusy then return end - - if element.value == "billing" then - local elements2 = { - {unselectable = true, icon = "fas fa-scroll", title = element.title}, - {title = "Amount", input = true, inputType = "number", inputMin = 1, inputMax = 250000, inputPlaceholder = "Amount to bill.."}, - {icon = "fas fa-check-double", title = "Confirm", value = "confirm"} - } - - ESX.OpenContext("right", elements2, function(menu2,element2) - local amount = tonumber(menu2.eles[2].inputValue) - - if amount == nil or amount < 0 then - ESX.ShowNotification(TranslateCap('amount_invalid'), "error") - else - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap('no_players_nearby'), "error") - else - ESX.CloseContext() - TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_mechanic', TranslateCap('mechanic'), amount) - end - end - end) - elseif element.value == "hijack_vehicle" then - local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - local coords = GetEntityCoords(playerPed) - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(TranslateCap('inside_vehicle')) - return - end - - if DoesEntityExist(vehicle) then - isBusy = true - TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true) - CreateThread(function() - Wait(10000) - - SetVehicleDoorsLocked(vehicle, 1) - SetVehicleDoorsLockedForAllPlayers(vehicle, false) - ClearPedTasksImmediately(playerPed) - - ESX.ShowNotification(TranslateCap('vehicle_unlocked')) - isBusy = false - end) - else - ESX.ShowNotification(TranslateCap('no_vehicle_nearby')) - end - elseif element.value == "fix_vehicle" then - local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - local coords = GetEntityCoords(playerPed) - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(TranslateCap('inside_vehicle')) - return - end - - if DoesEntityExist(vehicle) then - isBusy = true - TaskStartScenarioInPlace(playerPed, 'PROP_HUMAN_BUM_BIN', 0, true) - CreateThread(function() - Wait(20000) - - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - SetVehicleUndriveable(vehicle, false) - SetVehicleEngineOn(vehicle, true, true) - ClearPedTasksImmediately(playerPed) - - ESX.ShowNotification(TranslateCap('vehicle_repaired')) - isBusy = false - end) - else - ESX.ShowNotification(TranslateCap('no_vehicle_nearby')) - end - elseif element.value == "clean_vehicle" then - local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - local coords = GetEntityCoords(playerPed) - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(TranslateCap('inside_vehicle')) - return - end - - if DoesEntityExist(vehicle) then - isBusy = true - TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_MAID_CLEAN', 0, true) - CreateThread(function() - Wait(10000) - - SetVehicleDirtLevel(vehicle, 0) - ClearPedTasksImmediately(playerPed) - - ESX.ShowNotification(TranslateCap('vehicle_cleaned')) - isBusy = false - end) - else - ESX.ShowNotification(TranslateCap('no_vehicle_nearby')) - end - elseif element.value == "del_vehicle" then - local playerPed = PlayerPedId() - - if IsPedSittingInAnyVehicle(playerPed) then - local vehicle = GetVehiclePedIsIn(playerPed, false) - - if GetPedInVehicleSeat(vehicle, -1) == playerPed then - ESX.ShowNotification(TranslateCap('vehicle_impounded')) - ESX.Game.DeleteVehicle(vehicle) - else - ESX.ShowNotification(TranslateCap('must_seat_driver')) - end - else - local vehicle = ESX.Game.GetVehicleInDirection() - - if DoesEntityExist(vehicle) then - ESX.ShowNotification(TranslateCap('vehicle_impounded')) - ESX.Game.DeleteVehicle(vehicle) - else - ESX.ShowNotification(TranslateCap('must_near')) - end - end - elseif element.value == "dep_vehicle" then - local playerPed = PlayerPedId() - local vehicle = GetVehiclePedIsIn(playerPed, true) - - local towmodel = `flatbed` - local isVehicleTow = IsVehicleModel(vehicle, towmodel) - - if isVehicleTow then - local targetVehicle = ESX.Game.GetVehicleInDirection() - - if CurrentlyTowedVehicle == nil then - if targetVehicle ~= 0 then - if not IsPedInAnyVehicle(playerPed, true) then - if vehicle ~= targetVehicle then - AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - CurrentlyTowedVehicle = targetVehicle - ESX.ShowNotification(TranslateCap('vehicle_success_attached')) - - if NPCOnJob then - if NPCTargetTowable == targetVehicle then - ESX.ShowNotification(TranslateCap('please_drop_off')) - Config.Zones.VehicleDelivery.Type = 1 - - if Blips['NPCTargetTowableZone'] then - RemoveBlip(Blips['NPCTargetTowableZone']) - Blips['NPCTargetTowableZone'] = nil - end - - Blips['NPCDelivery'] = AddBlipForCoord(Config.Zones.VehicleDelivery.Pos.x, Config.Zones.VehicleDelivery.Pos.y, Config.Zones.VehicleDelivery.Pos.z) - SetBlipRoute(Blips['NPCDelivery'], true) - end - end - else - ESX.ShowNotification(TranslateCap('cant_attach_own_tt')) - end - end - else - ESX.ShowNotification(TranslateCap('no_veh_att')) - end - else - AttachEntityToEntity(CurrentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) - DetachEntity(CurrentlyTowedVehicle, true, true) - - if NPCOnJob then - if NPCTargetDeleterZone then - - if CurrentlyTowedVehicle == NPCTargetTowable then - ESX.Game.DeleteVehicle(NPCTargetTowable) - TriggerServerEvent('esx_mechanicjob:onNPCJobMissionCompleted') - StopNPCJob() - NPCTargetDeleterZone = false - else - ESX.ShowNotification(TranslateCap('not_right_veh')) - end - - else - ESX.ShowNotification(TranslateCap('not_right_place')) - end - end - - CurrentlyTowedVehicle = nil - ESX.ShowNotification(TranslateCap('veh_det_succ')) - end - else - ESX.ShowNotification(TranslateCap('imp_flatbed')) - end - elseif element.value == "object_spawner" then - local playerPed = PlayerPedId() - - if IsPedSittingInAnyVehicle(playerPed) then - ESX.ShowNotification(TranslateCap('inside_vehicle')) - return - end - - local elements2 = { - {unselectable= true, icon = "fas fa-object", title = TranslateCap('objects')}, - {icon = "fas fa-object", title = TranslateCap('roadcone'), value = 'prop_roadcone02a'}, - {icon = "fas fa-object", title = TranslateCap('toolbox'), value = 'prop_toolchest_01'} - } - - ESX.OpenContext("right", elements2, function(menuObj,elementObj) - local model = elementObj.value - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - if model == 'prop_roadcone02a' then - z = z - 2.0 - elseif model == 'prop_toolchest_01' then - z = z - 2.0 - end - - ESX.Game.SpawnObject(model, {x = x, y = y, z = z}, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-gear", title = TranslateCap("mechanic") }, + { icon = "fas fa-gear", title = TranslateCap("billing"), value = "billing" }, + { icon = "fas fa-gear", title = TranslateCap("hijack"), value = "hijack_vehicle" }, + { icon = "fas fa-gear", title = TranslateCap("repair"), value = "fix_vehicle" }, + { icon = "fas fa-gear", title = TranslateCap("clean"), value = "clean_vehicle" }, + { icon = "fas fa-gear", title = TranslateCap("imp_veh"), value = "del_vehicle" }, + { icon = "fas fa-gear", title = TranslateCap("flat_bed"), value = "dep_vehicle" }, + { icon = "fas fa-gear", title = TranslateCap("place_objects"), value = "object_spawner" }, + } + + ESX.OpenContext("right", elements, function(menu, element) + if isBusy then + return + end + + if element.value == "billing" then + local elements2 = { + { unselectable = true, icon = "fas fa-scroll", title = element.title }, + { title = "Amount", input = true, inputType = "number", inputMin = 1, inputMax = 250000, inputPlaceholder = "Amount to bill.." }, + { icon = "fas fa-check-double", title = "Confirm", value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2, element2) + local amount = tonumber(menu2.eles[2].inputValue) + + if amount == nil or amount < 0 then + ESX.ShowNotification(TranslateCap("amount_invalid"), "error") + else + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players_nearby"), "error") + else + ESX.CloseContext() + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_mechanic", TranslateCap("mechanic"), amount) + end + end + end) + elseif element.value == "hijack_vehicle" then + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + local coords = GetEntityCoords(playerPed) + + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(TranslateCap("inside_vehicle")) + return + end + + if DoesEntityExist(vehicle) then + isBusy = true + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + CreateThread(function() + Wait(10000) + + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + + ESX.ShowNotification(TranslateCap("vehicle_unlocked")) + isBusy = false + end) + else + ESX.ShowNotification(TranslateCap("no_vehicle_nearby")) + end + elseif element.value == "fix_vehicle" then + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + local coords = GetEntityCoords(playerPed) + + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(TranslateCap("inside_vehicle")) + return + end + + if DoesEntityExist(vehicle) then + isBusy = true + TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) + CreateThread(function() + Wait(20000) + + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + SetVehicleEngineOn(vehicle, true, true) + ClearPedTasksImmediately(playerPed) + + ESX.ShowNotification(TranslateCap("vehicle_repaired")) + isBusy = false + end) + else + ESX.ShowNotification(TranslateCap("no_vehicle_nearby")) + end + elseif element.value == "clean_vehicle" then + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + local coords = GetEntityCoords(playerPed) + + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(TranslateCap("inside_vehicle")) + return + end + + if DoesEntityExist(vehicle) then + isBusy = true + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_MAID_CLEAN", 0, true) + CreateThread(function() + Wait(10000) + + SetVehicleDirtLevel(vehicle, 0) + ClearPedTasksImmediately(playerPed) + + ESX.ShowNotification(TranslateCap("vehicle_cleaned")) + isBusy = false + end) + else + ESX.ShowNotification(TranslateCap("no_vehicle_nearby")) + end + elseif element.value == "del_vehicle" then + local playerPed = PlayerPedId() + + if IsPedSittingInAnyVehicle(playerPed) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + + if GetPedInVehicleSeat(vehicle, -1) == playerPed then + ESX.ShowNotification(TranslateCap("vehicle_impounded")) + ESX.Game.DeleteVehicle(vehicle) + else + ESX.ShowNotification(TranslateCap("must_seat_driver")) + end + else + local vehicle = ESX.Game.GetVehicleInDirection() + + if DoesEntityExist(vehicle) then + ESX.ShowNotification(TranslateCap("vehicle_impounded")) + ESX.Game.DeleteVehicle(vehicle) + else + ESX.ShowNotification(TranslateCap("must_near")) + end + end + elseif element.value == "dep_vehicle" then + local playerPed = PlayerPedId() + local vehicle = GetVehiclePedIsIn(playerPed, true) + + local towmodel = `flatbed` + local isVehicleTow = IsVehicleModel(vehicle, towmodel) + + if isVehicleTow then + local targetVehicle = ESX.Game.GetVehicleInDirection() + + if CurrentlyTowedVehicle == nil then + if targetVehicle ~= 0 then + if not IsPedInAnyVehicle(playerPed, true) then + if vehicle ~= targetVehicle then + AttachEntityToEntity(targetVehicle, vehicle, 20, -0.5, -5.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + CurrentlyTowedVehicle = targetVehicle + ESX.ShowNotification(TranslateCap("vehicle_success_attached")) + + if NPCOnJob then + if NPCTargetTowable == targetVehicle then + ESX.ShowNotification(TranslateCap("please_drop_off")) + Config.Zones.VehicleDelivery.Type = 1 + + if Blips["NPCTargetTowableZone"] then + RemoveBlip(Blips["NPCTargetTowableZone"]) + Blips["NPCTargetTowableZone"] = nil + end + + Blips["NPCDelivery"] = AddBlipForCoord(Config.Zones.VehicleDelivery.Pos.x, Config.Zones.VehicleDelivery.Pos.y, Config.Zones.VehicleDelivery.Pos.z) + SetBlipRoute(Blips["NPCDelivery"], true) + end + end + else + ESX.ShowNotification(TranslateCap("cant_attach_own_tt")) + end + end + else + ESX.ShowNotification(TranslateCap("no_veh_att")) + end + else + AttachEntityToEntity(CurrentlyTowedVehicle, vehicle, 20, -0.5, -12.0, 1.0, 0.0, 0.0, 0.0, false, false, false, false, 20, true) + DetachEntity(CurrentlyTowedVehicle, true, true) + + if NPCOnJob then + if NPCTargetDeleterZone then + if CurrentlyTowedVehicle == NPCTargetTowable then + ESX.Game.DeleteVehicle(NPCTargetTowable) + TriggerServerEvent("esx_mechanicjob:onNPCJobMissionCompleted") + StopNPCJob() + NPCTargetDeleterZone = false + else + ESX.ShowNotification(TranslateCap("not_right_veh")) + end + else + ESX.ShowNotification(TranslateCap("not_right_place")) + end + end + + CurrentlyTowedVehicle = nil + ESX.ShowNotification(TranslateCap("veh_det_succ")) + end + else + ESX.ShowNotification(TranslateCap("imp_flatbed")) + end + elseif element.value == "object_spawner" then + local playerPed = PlayerPedId() + + if IsPedSittingInAnyVehicle(playerPed) then + ESX.ShowNotification(TranslateCap("inside_vehicle")) + return + end + + local elements2 = { + { unselectable = true, icon = "fas fa-object", title = TranslateCap("objects") }, + { icon = "fas fa-object", title = TranslateCap("roadcone"), value = "prop_roadcone02a" }, + { icon = "fas fa-object", title = TranslateCap("toolbox"), value = "prop_toolchest_01" }, + } + + ESX.OpenContext("right", elements2, function(menuObj, elementObj) + local model = elementObj.value + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + if model == "prop_roadcone02a" then + z = z - 2.0 + elseif model == "prop_toolchest_01" then + z = z - 2.0 + end + + ESX.Game.SpawnObject(model, { x = x, y = y, z = z }, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + end) + end + end) end function OpenGetStocksMenu() - ESX.TriggerServerCallback('esx_mechanicjob:getStockItems', function(items) - local elements = { - {unselectable = true, icon = "fas fa-box", title = TranslateCap('mechanic_stock')} - } - - for i=1, #items, 1 do - elements[#elements+1] = { - icon = 'fas fa-box', - title = 'x' .. items[i].count .. ' ' .. items[i].label, - value = items[i].name - } - end - - ESX.OpenContext("right", elements, function(menu,element) - local itemName = element.value - - local elements2 = { - {unselectable = true, icon = "fas fa-box", title = element.title}, - {title = "Amount", input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = "Amount to withdraw.."}, - {icon = "fas fa-check-double", title = "Confirm", value = "confirm"} - } - - ESX.OpenContext("right", elements2, function(menu2,element2) - local count = tonumber(menu2.eles[2].inputValue) - - if count == nil then - ESX.ShowNotification(TranslateCap('invalid_quantity')) - else - ESX.CloseContext() - TriggerServerEvent('esx_mechanicjob:getStockItem', itemName, count) - - Wait(1000) - OpenGetStocksMenu() - end - end) - end) - end) + ESX.TriggerServerCallback("esx_mechanicjob:getStockItems", function(items) + local elements = { + { unselectable = true, icon = "fas fa-box", title = TranslateCap("mechanic_stock") }, + } + + for i = 1, #items, 1 do + elements[#elements + 1] = { + icon = "fas fa-box", + title = "x" .. items[i].count .. " " .. items[i].label, + value = items[i].name, + } + end + + ESX.OpenContext("right", elements, function(menu, element) + local itemName = element.value + + local elements2 = { + { unselectable = true, icon = "fas fa-box", title = element.title }, + { title = "Amount", input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = "Amount to withdraw.." }, + { icon = "fas fa-check-double", title = "Confirm", value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2, element2) + local count = tonumber(menu2.eles[2].inputValue) + + if count == nil then + ESX.ShowNotification(TranslateCap("invalid_quantity")) + else + ESX.CloseContext() + TriggerServerEvent("esx_mechanicjob:getStockItem", itemName, count) + + Wait(1000) + OpenGetStocksMenu() + end + end) + end) + end) end function OpenPutStocksMenu() - ESX.TriggerServerCallback('esx_mechanicjob:getPlayerInventory', function(inventory) - local elements = { - {unselectable = true, icon = "fas fa-box", title = TranslateCap('inventory')} - } - - for i=1, #inventory.items, 1 do - local item = inventory.items[i] - - if item.count > 0 then - elements[#elements+1] = { - icon = 'fas fa-box', - title = item.label .. ' x' .. item.count, - type = 'item_standard', - value = item.name - } - end - end - - ESX.OpenContext("right", elements, function(menu,element) - local itemName = element.value - - local elements2 = { - {unselectable = true, icon = "fas fa-box", title = element.title}, - {title = "Amount", input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = "Amount to deposit.."}, - {icon = "fas fa-check-double", title = "Confirm", value = "confirm"} - } - - ESX.OpenContext("right", elements2, function(menu2,element2) - local count = tonumber(menu2.eles[2].inputValue) - - if count == nil then - ESX.ShowNotification(TranslateCap('invalid_quantity')) - else - ESX.CloseContext() - TriggerServerEvent('esx_mechanicjob:putStockItems', itemName, count) - - Wait(1000) - OpenPutStocksMenu() - end - end) - end) - end) + ESX.TriggerServerCallback("esx_mechanicjob:getPlayerInventory", function(inventory) + local elements = { + { unselectable = true, icon = "fas fa-box", title = TranslateCap("inventory") }, + } + + for i = 1, #inventory.items, 1 do + local item = inventory.items[i] + + if item.count > 0 then + elements[#elements + 1] = { + icon = "fas fa-box", + title = item.label .. " x" .. item.count, + type = "item_standard", + value = item.name, + } + end + end + + ESX.OpenContext("right", elements, function(menu, element) + local itemName = element.value + + local elements2 = { + { unselectable = true, icon = "fas fa-box", title = element.title }, + { title = "Amount", input = true, inputType = "number", inputMin = 1, inputMax = 100, inputPlaceholder = "Amount to deposit.." }, + { icon = "fas fa-check-double", title = "Confirm", value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2, element2) + local count = tonumber(menu2.eles[2].inputValue) + + if count == nil then + ESX.ShowNotification(TranslateCap("invalid_quantity")) + else + ESX.CloseContext() + TriggerServerEvent("esx_mechanicjob:putStockItems", itemName, count) + + Wait(1000) + OpenPutStocksMenu() + end + end) + end) + end) end -RegisterNetEvent('esx_mechanicjob:onHijack') -AddEventHandler('esx_mechanicjob:onHijack', function() - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = ESX.Game.GetClosestVehicle(coords) - end - - local chance = math.random(100) - local alarm = math.random(100) - - if DoesEntityExist(vehicle) then - if alarm <= 33 then - SetVehicleAlarm(vehicle, true) - StartVehicleAlarm(vehicle) - end - - TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true) - - CreateThread(function() - Wait(10000) - if chance <= 66 then - SetVehicleDoorsLocked(vehicle, 1) - SetVehicleDoorsLockedForAllPlayers(vehicle, false) - ClearPedTasksImmediately(playerPed) - ESX.ShowNotification(TranslateCap('veh_unlocked')) - else - ESX.ShowNotification(TranslateCap('hijack_failed')) - ClearPedTasksImmediately(playerPed) - end - end) - end - end +RegisterNetEvent("esx_mechanicjob:onHijack") +AddEventHandler("esx_mechanicjob:onHijack", function() + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + local vehicle + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = ESX.Game.GetClosestVehicle(coords) + end + + local chance = math.random(100) + local alarm = math.random(100) + + if DoesEntityExist(vehicle) then + if alarm <= 33 then + SetVehicleAlarm(vehicle, true) + StartVehicleAlarm(vehicle) + end + + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + + CreateThread(function() + Wait(10000) + if chance <= 66 then + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ClearPedTasksImmediately(playerPed) + ESX.ShowNotification(TranslateCap("veh_unlocked")) + else + ESX.ShowNotification(TranslateCap("hijack_failed")) + ClearPedTasksImmediately(playerPed) + end + end) + end + end end) -RegisterNetEvent('esx_mechanicjob:onCarokit') -AddEventHandler('esx_mechanicjob:onCarokit', function() - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = ESX.Game.GetClosestVehicle(coords) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_HAMMERING', 0, true) - CreateThread(function() - Wait(10000) - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - ClearPedTasksImmediately(playerPed) - ESX.ShowNotification(TranslateCap('body_repaired')) - end) - end - end +RegisterNetEvent("esx_mechanicjob:onCarokit") +AddEventHandler("esx_mechanicjob:onCarokit", function() + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + local vehicle + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = ESX.Game.GetClosestVehicle(coords) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_HAMMERING", 0, true) + CreateThread(function() + Wait(10000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + ClearPedTasksImmediately(playerPed) + ESX.ShowNotification(TranslateCap("body_repaired")) + end) + end + end end) -RegisterNetEvent('esx_mechanicjob:onFixkit') -AddEventHandler('esx_mechanicjob:onFixkit', function() - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - local vehicle - - if IsPedInAnyVehicle(playerPed, false) then - vehicle = GetVehiclePedIsIn(playerPed, false) - else - vehicle = ESX.Game.GetClosestVehicle(coords) - end - - if DoesEntityExist(vehicle) then - TaskStartScenarioInPlace(playerPed, 'PROP_HUMAN_BUM_BIN', 0, true) - CreateThread(function() - Wait(20000) - SetVehicleFixed(vehicle) - SetVehicleDeformationFixed(vehicle) - SetVehicleUndriveable(vehicle, false) - ClearPedTasksImmediately(playerPed) - ESX.ShowNotification(TranslateCap('veh_repaired')) - end) - end - end +RegisterNetEvent("esx_mechanicjob:onFixkit") +AddEventHandler("esx_mechanicjob:onFixkit", function() + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + local vehicle + + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + else + vehicle = ESX.Game.GetClosestVehicle(coords) + end + + if DoesEntityExist(vehicle) then + TaskStartScenarioInPlace(playerPed, "PROP_HUMAN_BUM_BIN", 0, true) + CreateThread(function() + Wait(20000) + SetVehicleFixed(vehicle) + SetVehicleDeformationFixed(vehicle) + SetVehicleUndriveable(vehicle, false) + ClearPedTasksImmediately(playerPed) + ESX.ShowNotification(TranslateCap("veh_repaired")) + end) + end + end end) -RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function(xPlayer) - ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true +RegisterNetEvent("esx:playerLoaded") +AddEventHandler("esx:playerLoaded", function(xPlayer) + ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true end) -RegisterNetEvent('esx:setJob') -AddEventHandler('esx:setJob', function(job) - ESX.PlayerData.job = job +RegisterNetEvent("esx:setJob") +AddEventHandler("esx:setJob", function(job) + ESX.PlayerData.job = job end) -AddEventHandler('esx_mechanicjob:hasEnteredMarker', function(zone) - if zone == 'NPCJobTargetTowable' then - - elseif zone =='VehicleDelivery' then - NPCTargetDeleterZone = true - elseif zone == 'MechanicActions' then - CurrentAction = 'mechanic_actions_menu' - CurrentActionMsg = TranslateCap('open_actions') - CurrentActionData = {} - elseif zone == 'Garage' then - CurrentAction = 'mechanic_harvest_menu' - CurrentActionMsg = TranslateCap('harvest_menu') - CurrentActionData = {} - elseif zone == 'Craft' then - CurrentAction = 'mechanic_craft_menu' - CurrentActionMsg = TranslateCap('craft_menu') - CurrentActionData = {} - elseif zone == 'VehicleDeleter' then - local playerPed = PlayerPedId() - - if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) - - CurrentAction = 'delete_vehicle' - CurrentActionMsg = TranslateCap('veh_stored') - CurrentActionData = {vehicle = vehicle} - end - end - ESX.TextUI(CurrentActionMsg) +AddEventHandler("esx_mechanicjob:hasEnteredMarker", function(zone) + if zone == "NPCJobTargetTowable" then + elseif zone == "VehicleDelivery" then + NPCTargetDeleterZone = true + elseif zone == "MechanicActions" then + CurrentAction = "mechanic_actions_menu" + CurrentActionMsg = TranslateCap("open_actions") + CurrentActionData = {} + elseif zone == "Garage" then + CurrentAction = "mechanic_harvest_menu" + CurrentActionMsg = TranslateCap("harvest_menu") + CurrentActionData = {} + elseif zone == "Craft" then + CurrentAction = "mechanic_craft_menu" + CurrentActionMsg = TranslateCap("craft_menu") + CurrentActionData = {} + elseif zone == "VehicleDeleter" then + local playerPed = PlayerPedId() + + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + + CurrentAction = "delete_vehicle" + CurrentActionMsg = TranslateCap("veh_stored") + CurrentActionData = { vehicle = vehicle } + end + end + ESX.TextUI(CurrentActionMsg) end) -AddEventHandler('esx_mechanicjob:hasExitedMarker', function(zone) - if zone =='VehicleDelivery' then - NPCTargetDeleterZone = false - elseif zone == 'Craft' then - TriggerServerEvent('esx_mechanicjob:stopCraft') - TriggerServerEvent('esx_mechanicjob:stopCraft2') - TriggerServerEvent('esx_mechanicjob:stopCraft3') - elseif zone == 'Garage' then - TriggerServerEvent('esx_mechanicjob:stopHarvest') - TriggerServerEvent('esx_mechanicjob:stopHarvest2') - TriggerServerEvent('esx_mechanicjob:stopHarvest3') - end - - CurrentAction = nil - ESX.CloseContext() - ESX.HideUI() +AddEventHandler("esx_mechanicjob:hasExitedMarker", function(zone) + if zone == "VehicleDelivery" then + NPCTargetDeleterZone = false + elseif zone == "Craft" then + TriggerServerEvent("esx_mechanicjob:stopCraft") + TriggerServerEvent("esx_mechanicjob:stopCraft2") + TriggerServerEvent("esx_mechanicjob:stopCraft3") + elseif zone == "Garage" then + TriggerServerEvent("esx_mechanicjob:stopHarvest") + TriggerServerEvent("esx_mechanicjob:stopHarvest2") + TriggerServerEvent("esx_mechanicjob:stopHarvest3") + end + + CurrentAction = nil + ESX.CloseContext() + ESX.HideUI() end) -AddEventHandler('esx_mechanicjob:hasEnteredEntityZone', function(entity) - local playerPed = PlayerPedId() +AddEventHandler("esx_mechanicjob:hasEnteredEntityZone", function(entity) + local playerPed = PlayerPedId() - if ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' and not IsPedInAnyVehicle(playerPed, false) then - CurrentAction = 'remove_entity' - CurrentActionMsg = TranslateCap('press_remove_obj') - CurrentActionData = {entity = entity} - ESX.TextUI(CurrentActionMsg) - end + if ESX.PlayerData.job and ESX.PlayerData.job.name == "mechanic" and not IsPedInAnyVehicle(playerPed, false) then + CurrentAction = "remove_entity" + CurrentActionMsg = TranslateCap("press_remove_obj") + CurrentActionData = { entity = entity } + ESX.TextUI(CurrentActionMsg) + end end) -AddEventHandler('esx_mechanicjob:hasExitedEntityZone', function(entity) - if CurrentAction == 'remove_entity' then - CurrentAction = nil - end - ESX.HideUI() +AddEventHandler("esx_mechanicjob:hasExitedEntityZone", function(entity) + if CurrentAction == "remove_entity" then + CurrentAction = nil + end + ESX.HideUI() end) -RegisterNetEvent('esx_phone:loaded') -AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) - local specialContact = { - name = TranslateCap('mechanic'), - number = 'mechanic', - base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAA4BJREFUWIXtll9oU3cUx7/nJA02aSSlFouWMnXVB0ejU3wcRteHjv1puoc9rA978cUi2IqgRYWIZkMwrahUGfgkFMEZUdg6C+u21z1o3fbgqigVi7NzUtNcmsac40Npltz7S3rvUHzxQODec87vfD+/e0/O/QFv7Q0beV3QeXqmgV74/7H7fZJvuLwv8q/Xeux1gUrNBpN/nmtavdaqDqBK8VT2RDyV2VHmF1lvLERSBtCVynzYmcp+A9WqT9kcVKX4gHUehF0CEVY+1jYTTIwvt7YSIQnCTvsSUYz6gX5uDt7MP7KOKuQAgxmqQ+neUA+I1B1AiXi5X6ZAvKrabirmVYFwAMRT2RMg7F9SyKspvk73hfrtbkMPyIhA5FVqi0iBiEZMMQdAui/8E4GPv0oAJkpc6Q3+6goAAGpWBxNQmTLFmgL3jSJNgQdGv4pMts2EKm7ICJB/aG0xNdz74VEk13UYCx1/twPR8JjDT8wttyLZtkoAxSb8ZDCz0gdfKxWkFURf2v9qTYH7SK7rQIDn0P3nA0ehixvfwZwE0X9vBE/mW8piohhl1WH18UQBhYnre8N/L8b8xQvlx4ACbB4NnzaeRYDnKm0EALCMLXy84hwuTCXL/ExoB1E7qcK/8NCLIq5HcTT0i6u8TYbXUM1cAyyveVq8Xls7XhYrvY/4n3gC8C+dsmAzL1YUiyfWxvHzsy/w/dNd+KjhW2yvv/RfXr7x9QDcmo1he2RBiCCI1Q8jVj9szPNixVfgz+UiIGyDSrcoRu2J16d3I6e1VYvNSQjXpnucAcEPUOkGYZs/l4uUhowt/3kqu1UIv9n90fAY9jT3YBlbRvFTD4fw++wHjhiTRL/bG75t0jI2ITcHb5om4Xgmhv57xpGOg3d/NIqryOR7z+r+MC6qBJB/ZB2t9Om1D5lFm843G/3E3HI7Yh1xDRAfzLQr5EClBf/HBHK462TG2J0OABXeyWDPZ8VqxmBWYscpyghwtTd4EKpDTjCZdCNmzFM9k+4LHXIFACJN94Z6FiFEpKDQw9HndWsEuhnADVMhAUaYJBp9XrcGQKJ4qFE9k+6r2+MG3k5N8VQ22TVglbX2ZwOzX2VvNKr91zmY6S7N6zqZicVT2WNLyVSehESaBhxnOALfMeYX+K/S2yv7wmMAlvwyuR7FxQUyf0fgc/jztfkJr7XeGgC8BJJgWNV8ImT+AAAAAElFTkSuQmCC' - } +RegisterNetEvent("esx_phone:loaded") +AddEventHandler("esx_phone:loaded", function(phoneNumber, contacts) + local specialContact = { + name = TranslateCap("mechanic"), + number = "mechanic", + base64Icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAA4BJREFUWIXtll9oU3cUx7/nJA02aSSlFouWMnXVB0ejU3wcRteHjv1puoc9rA978cUi2IqgRYWIZkMwrahUGfgkFMEZUdg6C+u21z1o3fbgqigVi7NzUtNcmsac40Npltz7S3rvUHzxQODec87vfD+/e0/O/QFv7Q0beV3QeXqmgV74/7H7fZJvuLwv8q/Xeux1gUrNBpN/nmtavdaqDqBK8VT2RDyV2VHmF1lvLERSBtCVynzYmcp+A9WqT9kcVKX4gHUehF0CEVY+1jYTTIwvt7YSIQnCTvsSUYz6gX5uDt7MP7KOKuQAgxmqQ+neUA+I1B1AiXi5X6ZAvKrabirmVYFwAMRT2RMg7F9SyKspvk73hfrtbkMPyIhA5FVqi0iBiEZMMQdAui/8E4GPv0oAJkpc6Q3+6goAAGpWBxNQmTLFmgL3jSJNgQdGv4pMts2EKm7ICJB/aG0xNdz74VEk13UYCx1/twPR8JjDT8wttyLZtkoAxSb8ZDCz0gdfKxWkFURf2v9qTYH7SK7rQIDn0P3nA0ehixvfwZwE0X9vBE/mW8piohhl1WH18UQBhYnre8N/L8b8xQvlx4ACbB4NnzaeRYDnKm0EALCMLXy84hwuTCXL/ExoB1E7qcK/8NCLIq5HcTT0i6u8TYbXUM1cAyyveVq8Xls7XhYrvY/4n3gC8C+dsmAzL1YUiyfWxvHzsy/w/dNd+KjhW2yvv/RfXr7x9QDcmo1he2RBiCCI1Q8jVj9szPNixVfgz+UiIGyDSrcoRu2J16d3I6e1VYvNSQjXpnucAcEPUOkGYZs/l4uUhowt/3kqu1UIv9n90fAY9jT3YBlbRvFTD4fw++wHjhiTRL/bG75t0jI2ITcHb5om4Xgmhv57xpGOg3d/NIqryOR7z+r+MC6qBJB/ZB2t9Om1D5lFm843G/3E3HI7Yh1xDRAfzLQr5EClBf/HBHK462TG2J0OABXeyWDPZ8VqxmBWYscpyghwtTd4EKpDTjCZdCNmzFM9k+4LHXIFACJN94Z6FiFEpKDQw9HndWsEuhnADVMhAUaYJBp9XrcGQKJ4qFE9k+6r2+MG3k5N8VQ22TVglbX2ZwOzX2VvNKr91zmY6S7N6zqZicVT2WNLyVSehESaBhxnOALfMeYX+K/S2yv7wmMAlvwyuR7FxQUyf0fgc/jztfkJr7XeGgC8BJJgWNV8ImT+AAAAAElFTkSuQmCC", + } - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + TriggerEvent("esx_phone:addSpecialContact", specialContact.name, specialContact.number, specialContact.base64Icon) end) -- Pop NPC mission vehicle when inside area CreateThread(function() - while true do - local Sleep = 1500 - - if NPCTargetTowableZone and not NPCHasSpawnedTowable then - Sleep = 0 - local coords = GetEntityCoords(PlayerPedId()) - local zone = Config.Zones[NPCTargetTowableZone] - - if #(coords - zone.Pos) < Config.NPCSpawnDistance then - local model = Config.Vehicles[GetRandomIntInRange(1, #Config.Vehicles)] - - ESX.Game.SpawnVehicle(model, zone.Pos, 0, function(vehicle) - NPCTargetTowable = vehicle - end) - - NPCHasSpawnedTowable = true - end - end - - if NPCTargetTowableZone and NPCHasSpawnedTowable and not NPCHasBeenNextToTowable then - Sleep = 500 - local coords = GetEntityCoords(PlayerPedId()) - local zone = Config.Zones[NPCTargetTowableZone] - - if #(coords - zone.Pos) < Config.NPCNextToDistance then - Sleep = 0 - ESX.ShowNotification(TranslateCap('please_tow')) - NPCHasBeenNextToTowable = true - end - end - Wait(Sleep) - end + while true do + local Sleep = 1500 + + if NPCTargetTowableZone and not NPCHasSpawnedTowable then + Sleep = 0 + local coords = GetEntityCoords(PlayerPedId()) + local zone = Config.Zones[NPCTargetTowableZone] + + if #(coords - zone.Pos) < Config.NPCSpawnDistance then + local model = Config.Vehicles[GetRandomIntInRange(1, #Config.Vehicles)] + + ESX.Game.SpawnVehicle(model, zone.Pos, 0, function(vehicle) + NPCTargetTowable = vehicle + end) + + NPCHasSpawnedTowable = true + end + end + + if NPCTargetTowableZone and NPCHasSpawnedTowable and not NPCHasBeenNextToTowable then + Sleep = 500 + local coords = GetEntityCoords(PlayerPedId()) + local zone = Config.Zones[NPCTargetTowableZone] + + if #(coords - zone.Pos) < Config.NPCNextToDistance then + Sleep = 0 + ESX.ShowNotification(TranslateCap("please_tow")) + NPCHasBeenNextToTowable = true + end + end + Wait(Sleep) + end end) -- Create Blips CreateThread(function() - local blip = AddBlipForCoord(Config.Zones.MechanicActions.Pos.x, Config.Zones.MechanicActions.Pos.y, Config.Zones.MechanicActions.Pos.z) + local blip = AddBlipForCoord(Config.Zones.MechanicActions.Pos.x, Config.Zones.MechanicActions.Pos.y, Config.Zones.MechanicActions.Pos.z) - SetBlipSprite (blip, 446) - SetBlipDisplay(blip, 4) - SetBlipScale (blip, 1.0) - SetBlipColour (blip, 5) - SetBlipAsShortRange(blip, true) + SetBlipSprite(blip, 446) + SetBlipDisplay(blip, 4) + SetBlipScale(blip, 1.0) + SetBlipColour(blip, 5) + SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName('STRING') - AddTextComponentSubstringPlayerName(TranslateCap('mechanic')) - EndTextCommandSetBlipName(blip) + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("mechanic")) + EndTextCommandSetBlipName(blip) end) -- Display markers CreateThread(function() - while true do - local Sleep = 2000 - - if ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then - Sleep = 500 - local coords, letSleep = GetEntityCoords(PlayerPedId()), true - - for k,v in pairs(Config.Zones) do - if v.Type ~= -1 and #(coords - v.Pos) < Config.DrawDistance then - Sleep = 0 - DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, true, true, 2, true, nil, nil, false) - letSleep = false - end - end - end - Wait(Sleep) - end + while true do + local Sleep = 2000 + + if ESX.PlayerData.job and ESX.PlayerData.job.name == "mechanic" then + Sleep = 500 + local coords, letSleep = GetEntityCoords(PlayerPedId()), true + + for k, v in pairs(Config.Zones) do + if v.Type ~= -1 and #(coords - v.Pos) < Config.DrawDistance then + Sleep = 0 + DrawMarker(v.Type, v.Pos.x, v.Pos.y, v.Pos.z, 0.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, true, true, 2, true, nil, nil, false) + letSleep = false + end + end + end + Wait(Sleep) + end end) -- Enter / Exit marker events CreateThread(function() - while true do - local Sleep = 500 - - if ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then - - local coords = GetEntityCoords(PlayerPedId()) - local isInMarker = false - local currentZone = nil - - for k,v in pairs(Config.Zones) do - if(#(coords - v.Pos) < v.Size.x) then - Sleep = 0 - isInMarker = true - currentZone = k - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker = true - LastZone = currentZone - TriggerEvent('esx_mechanicjob:hasEnteredMarker', currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent('esx_mechanicjob:hasExitedMarker', LastZone) - end - end - Wait(Sleep) - end + while true do + local Sleep = 500 + + if ESX.PlayerData.job and ESX.PlayerData.job.name == "mechanic" then + local coords = GetEntityCoords(PlayerPedId()) + local isInMarker = false + local currentZone = nil + + for k, v in pairs(Config.Zones) do + if #(coords - v.Pos) < v.Size.x then + Sleep = 0 + isInMarker = true + currentZone = k + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker = true + LastZone = currentZone + TriggerEvent("esx_mechanicjob:hasEnteredMarker", currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("esx_mechanicjob:hasExitedMarker", LastZone) + end + end + Wait(Sleep) + end end) CreateThread(function() - local trackedEntities = { - 'prop_roadcone02a', - 'prop_toolchest_01' - } - - while true do - Wait(500) - - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - local closestDistance = -1 - local closestEntity = nil - - for i=1, #trackedEntities, 1 do - local object = GetClosestObjectOfType(coords, 3.0, joaat(trackedEntities[i]), false, false, false) - - if DoesEntityExist(object) then - local objCoords = GetEntityCoords(object) - local distance = #(coords - objCoords) - - if closestDistance == -1 or closestDistance > distance then - closestDistance = distance - closestEntity = object - end - end - end - - if closestDistance ~= -1 and closestDistance <= 3.0 then - if LastEntity ~= closestEntity then - TriggerEvent('esx_mechanicjob:hasEnteredEntityZone', closestEntity) - LastEntity = closestEntity - end - else - if LastEntity then - TriggerEvent('esx_mechanicjob:hasExitedEntityZone', LastEntity) - LastEntity = nil - end - end - end + local trackedEntities = { + "prop_roadcone02a", + "prop_toolchest_01", + } + + while true do + Wait(500) + + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + local closestDistance = -1 + local closestEntity = nil + + for i = 1, #trackedEntities, 1 do + local object = GetClosestObjectOfType(coords, 3.0, joaat(trackedEntities[i]), false, false, false) + + if DoesEntityExist(object) then + local objCoords = GetEntityCoords(object) + local distance = #(coords - objCoords) + + if closestDistance == -1 or closestDistance > distance then + closestDistance = distance + closestEntity = object + end + end + end + + if closestDistance ~= -1 and closestDistance <= 3.0 then + if LastEntity ~= closestEntity then + TriggerEvent("esx_mechanicjob:hasEnteredEntityZone", closestEntity) + LastEntity = closestEntity + end + else + if LastEntity then + TriggerEvent("esx_mechanicjob:hasExitedEntityZone", LastEntity) + LastEntity = nil + end + end + end end) -- Key Controls CreateThread(function() - while true do - local sleep = 500 - if CurrentAction then - sleep = 0 - if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then - if CurrentAction == 'mechanic_actions_menu' then - OpenMechanicActionsMenu() - elseif CurrentAction == 'mechanic_harvest_menu' then - OpenMechanicHarvestMenu() - elseif CurrentAction == 'mechanic_craft_menu' then - OpenMechanicCraftMenu() - elseif CurrentAction == 'delete_vehicle' then - if Config.EnableSocietyOwnedVehicles then - - local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) - TriggerServerEvent('esx_society:putVehicleInGarage', 'mechanic', vehicleProps) - else - local entityModel = GetEntityModel(CurrentActionData.vehicle) - - if entityModel == `flatbed` or entityModel == `towtruck2` or entityModel == `slamvan3` then - TriggerServerEvent('esx_service:disableService', 'mechanic') - end - end - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - elseif CurrentAction == 'remove_entity' then - DeleteEntity(CurrentActionData.entity) - end - - CurrentAction = nil - end - end - Wait(sleep) - end + while true do + local sleep = 500 + if CurrentAction then + sleep = 0 + if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == "mechanic" then + if CurrentAction == "mechanic_actions_menu" then + OpenMechanicActionsMenu() + elseif CurrentAction == "mechanic_harvest_menu" then + OpenMechanicHarvestMenu() + elseif CurrentAction == "mechanic_craft_menu" then + OpenMechanicCraftMenu() + elseif CurrentAction == "delete_vehicle" then + if Config.EnableSocietyOwnedVehicles then + local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) + TriggerServerEvent("esx_society:putVehicleInGarage", "mechanic", vehicleProps) + else + local entityModel = GetEntityModel(CurrentActionData.vehicle) + + if entityModel == `flatbed` or entityModel == `towtruck2` or entityModel == `slamvan3` then + TriggerServerEvent("esx_service:disableService", "mechanic") + end + end + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + elseif CurrentAction == "remove_entity" then + DeleteEntity(CurrentActionData.entity) + end + + CurrentAction = nil + end + end + Wait(sleep) + end end) -RegisterCommand('mechanicMenu', function() - if ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then - OpenMobileMechanicActionsMenu() - end +RegisterCommand("mechanicMenu", function() + if ESX.PlayerData.job and ESX.PlayerData.job.name == "mechanic" then + OpenMobileMechanicActionsMenu() + end end, false) - - -RegisterCommand('mechanicjob', function() - local playerPed = PlayerPedId() - if ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic' then - if NPCOnJob then - if GetGameTimer() - NPCLastCancel > 5 * 60000 then - StopNPCJob(true) - NPCLastCancel = GetGameTimer() - else - ESX.ShowNotification(TranslateCap('wait_five'), "error") - end - else - if IsPedInAnyVehicle(playerPed, false) and IsVehicleModel(GetVehiclePedIsIn(playerPed, false), `flatbed`) then - StartNPCJob() - else - ESX.ShowNotification(TranslateCap('must_in_flatbed'), "error") - end - end - end +RegisterCommand("mechanicjob", function() + local playerPed = PlayerPedId() + if ESX.PlayerData.job and ESX.PlayerData.job.name == "mechanic" then + if NPCOnJob then + if GetGameTimer() - NPCLastCancel > 5 * 60000 then + StopNPCJob(true) + NPCLastCancel = GetGameTimer() + else + ESX.ShowNotification(TranslateCap("wait_five"), "error") + end + else + if IsPedInAnyVehicle(playerPed, false) and IsVehicleModel(GetVehiclePedIsIn(playerPed, false), `flatbed`) then + StartNPCJob() + else + ESX.ShowNotification(TranslateCap("must_in_flatbed"), "error") + end + end + end end, false) -RegisterKeyMapping('mechanicMenu', 'Open Mechanic Menu', 'keyboard', Config.Controls.mechanicMenu) -RegisterKeyMapping('mechanicjob', 'Togggle NPC Job', 'keyboard', Config.Controls.toggleNPCJob) +RegisterKeyMapping("mechanicMenu", "Open Mechanic Menu", "keyboard", Config.Controls.mechanicMenu) +RegisterKeyMapping("mechanicjob", "Togggle NPC Job", "keyboard", Config.Controls.toggleNPCJob) -AddEventHandler('esx:onPlayerDeath', function(data) isDead = true end) -AddEventHandler('esx:onPlayerSpawn', function(spawn) isDead = false end) +AddEventHandler("esx:onPlayerDeath", function(data) + isDead = true +end) +AddEventHandler("esx:onPlayerSpawn", function(spawn) + isDead = false +end) diff --git a/server-data/resources/[esx_addons]/esx_mechanicjob/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_mechanicjob/fxmanifest.lua index b7a5535c6..f4e210ddb 100644 --- a/server-data/resources/[esx_addons]/esx_mechanicjob/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx_mechanicjob/fxmanifest.lua @@ -1,29 +1,29 @@ -fx_version 'adamant' +fx_version("adamant") -game 'gta5' +game("gta5") -description 'Allows players to RP as a mechanic (repair and modify vehicles)' -lua54 'yes' -version '1.0.1' +description("Allows players to RP as a mechanic (repair and modify vehicles)") +lua54("yes") +version("1.0.1") -shared_script '@es_extended/imports.lua' +shared_script("@es_extended/imports.lua") -client_scripts { - '@es_extended/locale.lua', - 'locales/*.lua', - 'config.lua', - 'client/main.lua' -} +client_scripts({ + "@es_extended/locale.lua", + "locales/*.lua", + "config.lua", + "client/main.lua", +}) -server_scripts { - '@es_extended/locale.lua', - 'locales/*.lua', - 'config.lua', - 'server/main.lua' -} +server_scripts({ + "@es_extended/locale.lua", + "locales/*.lua", + "config.lua", + "server/main.lua", +}) -dependencies { - 'es_extended', - 'esx_society', - 'esx_billing' -} +dependencies({ + "es_extended", + "esx_society", + "bpt_billing", +}) diff --git a/server-data/resources/[esx_addons]/esx_policejob/README.md b/server-data/resources/[esx_addons]/esx_policejob/README.md index 21a7a79bd..f8974f415 100644 --- a/server-data/resources/[esx_addons]/esx_policejob/README.md +++ b/server-data/resources/[esx_addons]/esx_policejob/README.md @@ -4,7 +4,6 @@ This resource for ESX adds police armories, vehicle garages and ability for cops ### Requirements * Auto mode - * [esx_billing](https://github.com/esx-framework/esx_billing) * [esx_vehicleshop](https://github.com/esx-framework/esx_vehicleshop) * Player management (boss actions and armory with buyable weapons) diff --git a/server-data/resources/[esx_addons]/esx_policejob/client/main.lua b/server-data/resources/[esx_addons]/esx_policejob/client/main.lua index 88072a59a..396b2b8ab 100644 --- a/server-data/resources/[esx_addons]/esx_policejob/client/main.lua +++ b/server-data/resources/[esx_addons]/esx_policejob/client/main.lua @@ -1,1826 +1,1603 @@ local CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask, sex, action = {}, {}, {}, {}, {}, {}, {} -local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService = - false, false, false, false, false +local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService = false, false, false, false, false local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg dragStatus.isDragged, isInShopMenu = false, false function cleanPlayer(playerPed) - SetPedArmour(playerPed, 0) - ClearPedBloodDamage(playerPed) - ResetPedVisibleDamage(playerPed) - ClearPedLastWeaponDamage(playerPed) - ResetPedMovementClipset(playerPed, 0) + SetPedArmour(playerPed, 0) + ClearPedBloodDamage(playerPed) + ResetPedVisibleDamage(playerPed) + ClearPedLastWeaponDamage(playerPed) + ResetPedMovementClipset(playerPed, 0) end function setUniform(uniform, playerPed) - TriggerEvent("skinchanger:getSkin", function(skin) - local uniformObject + TriggerEvent("skinchanger:getSkin", function(skin) + local uniformObject - sex = (skin.sex == 0) and "male" or "female" + sex = (skin.sex == 0) and "male" or "female" - uniformObject = Config.Uniforms[uniform][sex] + uniformObject = Config.Uniforms[uniform][sex] - if uniformObject then - TriggerEvent("skinchanger:loadClothes", skin, uniformObject) + if uniformObject then + TriggerEvent("skinchanger:loadClothes", skin, uniformObject) - if uniform == "bullet_wear" then - SetPedArmour(playerPed, 100) - end - else - ESX.ShowNotification(TranslateCap("no_outfit")) - end - end) + if uniform == "bullet_wear" then + SetPedArmour(playerPed, 100) + end + else + ESX.ShowNotification(TranslateCap("no_outfit")) + end + end) end function OpenCloakroomMenu() - local playerPed = PlayerPedId() - local grade = ESX.PlayerData.job.grade_name - - local elements = { - { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom") }, - { icon = "fas fa-shirt", title = TranslateCap("citizen_wear"), value = "citizen_wear" }, - { icon = "fas fa-shirt", title = TranslateCap("bullet_wear"), uniform = "bullet_wear" }, - { icon = "fas fa-shirt", title = TranslateCap("gilet_wear"), uniform = "gilet_wear" }, - { icon = "fas fa-shirt", title = TranslateCap("police_wear"), uniform = grade }, - } - - if Config.EnableCustomPeds then - for _, v in ipairs(Config.CustomPeds.shared) do - elements[#elements + 1] = { - icon = "fas fa-shirt", - title = v.label, - value = "freemode_ped", - maleModel = v.maleModel, - femaleModel = v.femaleModel, - } - end - - for _, v in ipairs(Config.CustomPeds[grade]) do - elements[#elements + 1] = { - icon = "fas fa-shirt", - title = v.label, - value = "freemode_ped", - maleModel = v.maleModel, - femaleModel = v.femaleModel, - } - end - end - - ESX.OpenContext("right", elements, function(menu, element) - cleanPlayer(playerPed) - local data = { current = element } - - if data.current.value == "citizen_wear" then - if Config.EnableCustomPeds then - 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) - TriggerEvent("esx:restoreLoadout") - end) - end) - end) - else - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) - TriggerEvent("skinchanger:loadSkin", skin) - end) - end - - if Config.EnableESXService then - ESX.TriggerServerCallback("esx_service:isInService", function(isInService) - if isInService then - playerInService = false - - local notification = { - title = TranslateCap("service_anonunce"), - subject = "", - msg = TranslateCap("service_out_announce", GetPlayerName(PlayerId())), - iconType = 1, - } - - TriggerServerEvent("esx_service:notifyAllInService", notification, "police") - - TriggerServerEvent("esx_service:disableService", "police") - TriggerEvent("esx_policejob:updateBlip") - ESX.ShowNotification(TranslateCap("service_out")) - end - end, "police") - end - end - - if Config.EnableESXService and data.current.value ~= "citizen_wear" then - local awaitService - - ESX.TriggerServerCallback("esx_service:isInService", function(isInService) - if not isInService then - if Config.MaxInService ~= -1 then - ESX.TriggerServerCallback( - "esx_service:enableService", - function(canTakeService, maxInService, inServiceCount) - if not canTakeService then - ESX.ShowNotification(TranslateCap("service_max", inServiceCount, maxInService)) - else - awaitService = true - playerInService = true - - local notification = { - title = TranslateCap("service_anonunce"), - subject = "", - msg = TranslateCap("service_in_announce", GetPlayerName(PlayerId())), - iconType = 1, - } - - TriggerServerEvent("esx_service:notifyAllInService", notification, "police") - TriggerEvent("esx_policejob:updateBlip") - ESX.ShowNotification(TranslateCap("service_in")) - end - end, - "police" - ) - else - awaitService = true - playerInService = true - - local notification = { - title = TranslateCap("service_anonunce"), - subject = "", - msg = TranslateCap("service_in_announce", GetPlayerName(PlayerId())), - iconType = 1, - } - - TriggerServerEvent("esx_service:notifyAllInService", notification, "police") - TriggerEvent("esx_policejob:updateBlip") - ESX.ShowNotification(TranslateCap("service_in")) - end - else - awaitService = true - end - end, "police") - - while awaitService == nil do - Wait(0) - end - - -- if we couldn't enter service don't let the player get changed - if not awaitService then - return - end - end - - if data.current.uniform then - setUniform(data.current.uniform, playerPed) - elseif data.current.value == "freemode_ped" then - local modelHash - - ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) - if skin.sex == 0 then - modelHash = joaat(data.current.maleModel) - else - modelHash = joaat(data.current.femaleModel) - end - - ESX.Streaming.RequestModel(modelHash, function() - SetPlayerModel(PlayerId(), modelHash) - SetModelAsNoLongerNeeded(modelHash) - SetPedDefaultComponentVariation(PlayerPedId()) - - TriggerEvent("esx:restoreLoadout") - end) - end) - end - end, function(menu) - CurrentAction = "menu_cloakroom" - CurrentActionMsg = TranslateCap("open_cloackroom") - CurrentActionData = {} - end) + local playerPed = PlayerPedId() + local grade = ESX.PlayerData.job.grade_name + + local elements = { + { unselectable = true, icon = "fas fa-shirt", title = TranslateCap("cloakroom") }, + { icon = "fas fa-shirt", title = TranslateCap("citizen_wear"), value = "citizen_wear" }, + { icon = "fas fa-shirt", title = TranslateCap("bullet_wear"), uniform = "bullet_wear" }, + { icon = "fas fa-shirt", title = TranslateCap("gilet_wear"), uniform = "gilet_wear" }, + { icon = "fas fa-shirt", title = TranslateCap("police_wear"), uniform = grade }, + } + + if Config.EnableCustomPeds then + for _, v in ipairs(Config.CustomPeds.shared) do + elements[#elements + 1] = { + icon = "fas fa-shirt", + title = v.label, + value = "freemode_ped", + maleModel = v.maleModel, + femaleModel = v.femaleModel, + } + end + + for _, v in ipairs(Config.CustomPeds[grade]) do + elements[#elements + 1] = { + icon = "fas fa-shirt", + title = v.label, + value = "freemode_ped", + maleModel = v.maleModel, + femaleModel = v.femaleModel, + } + end + end + + ESX.OpenContext("right", elements, function(menu, element) + cleanPlayer(playerPed) + local data = { current = element } + + if data.current.value == "citizen_wear" then + if Config.EnableCustomPeds then + 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) + TriggerEvent("esx:restoreLoadout") + end) + end) + end) + else + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin) + TriggerEvent("skinchanger:loadSkin", skin) + end) + end + + if Config.EnableESXService then + ESX.TriggerServerCallback("esx_service:isInService", function(isInService) + if isInService then + playerInService = false + + local notification = { + title = TranslateCap("service_anonunce"), + subject = "", + msg = TranslateCap("service_out_announce", GetPlayerName(PlayerId())), + iconType = 1, + } + + TriggerServerEvent("esx_service:notifyAllInService", notification, "police") + + TriggerServerEvent("esx_service:disableService", "police") + TriggerEvent("esx_policejob:updateBlip") + ESX.ShowNotification(TranslateCap("service_out")) + end + end, "police") + end + end + + if Config.EnableESXService and data.current.value ~= "citizen_wear" then + local awaitService + + ESX.TriggerServerCallback("esx_service:isInService", function(isInService) + if not isInService then + if Config.MaxInService ~= -1 then + ESX.TriggerServerCallback("esx_service:enableService", function(canTakeService, maxInService, inServiceCount) + if not canTakeService then + ESX.ShowNotification(TranslateCap("service_max", inServiceCount, maxInService)) + else + awaitService = true + playerInService = true + + local notification = { + title = TranslateCap("service_anonunce"), + subject = "", + msg = TranslateCap("service_in_announce", GetPlayerName(PlayerId())), + iconType = 1, + } + + TriggerServerEvent("esx_service:notifyAllInService", notification, "police") + TriggerEvent("esx_policejob:updateBlip") + ESX.ShowNotification(TranslateCap("service_in")) + end + end, "police") + else + awaitService = true + playerInService = true + + local notification = { + title = TranslateCap("service_anonunce"), + subject = "", + msg = TranslateCap("service_in_announce", GetPlayerName(PlayerId())), + iconType = 1, + } + + TriggerServerEvent("esx_service:notifyAllInService", notification, "police") + TriggerEvent("esx_policejob:updateBlip") + ESX.ShowNotification(TranslateCap("service_in")) + end + else + awaitService = true + end + end, "police") + + while awaitService == nil do + Wait(0) + end + + -- if we couldn't enter service don't let the player get changed + if not awaitService then + return + end + end + + if data.current.uniform then + setUniform(data.current.uniform, playerPed) + elseif data.current.value == "freemode_ped" then + local modelHash + + ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin, jobSkin) + if skin.sex == 0 then + modelHash = joaat(data.current.maleModel) + else + modelHash = joaat(data.current.femaleModel) + end + + ESX.Streaming.RequestModel(modelHash, function() + SetPlayerModel(PlayerId(), modelHash) + SetModelAsNoLongerNeeded(modelHash) + SetPedDefaultComponentVariation(PlayerPedId()) + + TriggerEvent("esx:restoreLoadout") + end) + end) + end + end, function(menu) + CurrentAction = "menu_cloakroom" + CurrentActionMsg = TranslateCap("open_cloackroom") + CurrentActionData = {} + end) end function OpenArmoryMenu(station) - local elements - if Config.OxInventory then - exports.ox_inventory:openInventory("stash", { id = "society_police", owner = station }) - return ESX.CloseContext() - else - elements = { - { unselectable = true, icon = "fas fa-gun", title = TranslateCap("armory") }, - { icon = "fas fa-gun", title = TranslateCap("buy_weapons"), value = "buy_weapons" }, - } - - if Config.EnableArmoryManagement then - table.insert(elements, { icon = "fas fa-gun", title = TranslateCap("get_weapon"), value = "get_weapon" }) - table.insert(elements, { icon = "fas fa-gun", title = TranslateCap("put_weapon"), value = "put_weapon" }) - table.insert(elements, { icon = "fas fa-box", title = TranslateCap("remove_object"), value = "get_stock" }) - table.insert(elements, { icon = "fas fa-box", title = TranslateCap("deposit_object"), value = "put_stock" }) - end - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - if data.current.value == "get_weapon" then - OpenGetWeaponMenu() - elseif data.current.value == "put_weapon" then - OpenPutWeaponMenu() - elseif data.current.value == "buy_weapons" then - OpenBuyWeaponsMenu() - elseif data.current.value == "put_stock" then - OpenPutStocksMenu() - elseif data.current.value == "get_stock" then - OpenGetStocksMenu() - end - end, function(menu) - CurrentAction = "menu_armory" - CurrentActionMsg = TranslateCap("open_armory") - CurrentActionData = { station = station } - end) + local elements + if Config.OxInventory then + exports.ox_inventory:openInventory("stash", { id = "society_police", owner = station }) + return ESX.CloseContext() + else + elements = { + { unselectable = true, icon = "fas fa-gun", title = TranslateCap("armory") }, + { icon = "fas fa-gun", title = TranslateCap("buy_weapons"), value = "buy_weapons" }, + } + + if Config.EnableArmoryManagement then + table.insert(elements, { icon = "fas fa-gun", title = TranslateCap("get_weapon"), value = "get_weapon" }) + table.insert(elements, { icon = "fas fa-gun", title = TranslateCap("put_weapon"), value = "put_weapon" }) + table.insert(elements, { icon = "fas fa-box", title = TranslateCap("remove_object"), value = "get_stock" }) + table.insert(elements, { icon = "fas fa-box", title = TranslateCap("deposit_object"), value = "put_stock" }) + end + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + if data.current.value == "get_weapon" then + OpenGetWeaponMenu() + elseif data.current.value == "put_weapon" then + OpenPutWeaponMenu() + elseif data.current.value == "buy_weapons" then + OpenBuyWeaponsMenu() + elseif data.current.value == "put_stock" then + OpenPutStocksMenu() + elseif data.current.value == "get_stock" then + OpenGetStocksMenu() + end + end, function(menu) + CurrentAction = "menu_armory" + CurrentActionMsg = TranslateCap("open_armory") + CurrentActionData = { station = station } + end) end function OpenPoliceActionsMenu() - local elements = { - { unselectable = true, icon = "fas fa-police", title = TranslateCap("menu_title") }, - { icon = "fas fa-user", title = TranslateCap("citizen_interaction"), value = "citizen_interaction" }, - { icon = "fas fa-car", title = TranslateCap("vehicle_interaction"), value = "vehicle_interaction" }, - { icon = "fas fa-object", title = TranslateCap("object_spawner"), value = "object_spawner" }, - } - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - - if data.current.value == "citizen_interaction" then - local elements2 = { - { unselectable = true, icon = "fas fa-user", title = element.title }, - { icon = "fas fa-idkyet", title = TranslateCap("id_card"), value = "identity_card" }, - { icon = "fas fa-idkyet", title = TranslateCap("search"), value = "search" }, - { icon = "fas fa-idkyet", title = TranslateCap("handcuff"), value = "handcuff" }, - { icon = "fas fa-idkyet", title = TranslateCap("drag"), value = "drag" }, - { icon = "fas fa-idkyet", title = TranslateCap("put_in_vehicle"), value = "put_in_vehicle" }, - { icon = "fas fa-idkyet", title = TranslateCap("out_the_vehicle"), value = "out_the_vehicle" }, - { icon = "fas fa-idkyet", title = TranslateCap("fine"), value = "fine" }, - { icon = "fas fa-idkyet", title = TranslateCap("unpaid_bills"), value = "unpaid_bills" }, - } - - if Config.EnableLicenses then - elements2[#elements2 + 1] = { - icon = "fas fa-scroll", - title = TranslateCap("license_check"), - value = "license", - } - end - - ESX.OpenContext("right", elements2, function(menu2, element2) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer ~= -1 and closestDistance <= 3.0 then - local data2 = { current = element2 } - local action = data2.current.value - - if action == "identity_card" then - OpenIdentityCardMenu(closestPlayer) - elseif action == "search" then - OpenBodySearchMenu(closestPlayer) - elseif action == "handcuff" then - TriggerServerEvent("esx_policejob:handcuff", GetPlayerServerId(closestPlayer)) - elseif action == "drag" then - TriggerServerEvent("esx_policejob:drag", GetPlayerServerId(closestPlayer)) - elseif action == "put_in_vehicle" then - TriggerServerEvent("esx_policejob:putInVehicle", GetPlayerServerId(closestPlayer)) - elseif action == "out_the_vehicle" then - TriggerServerEvent("esx_policejob:OutVehicle", GetPlayerServerId(closestPlayer)) - elseif action == "fine" then - OpenFineMenu(closestPlayer) - elseif action == "license" then - ShowPlayerLicense(closestPlayer) - elseif action == "unpaid_bills" then - OpenUnpaidBillsMenu(closestPlayer) - end - else - ESX.ShowNotification(TranslateCap("no_players_nearby")) - end - end, function(menu) - OpenPoliceActionsMenu() - end) - elseif data.current.value == "vehicle_interaction" then - local elements3 = { - { unselectable = true, icon = "fas fa-car", title = element.title }, - } - local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - - if DoesEntityExist(vehicle) then - elements3[#elements3 + 1] = - { icon = "fas fa-car", title = TranslateCap("vehicle_info"), value = "vehicle_infos" } - elements3[#elements3 + 1] = - { icon = "fas fa-car", title = TranslateCap("pick_lock"), value = "hijack_vehicle" } - elements3[#elements3 + 1] = { icon = "fas fa-car", title = TranslateCap("impound"), value = "impound" } - end - - elements3[#elements3 + 1] = { - icon = "fas fa-scroll", - title = TranslateCap("search_database"), - value = "search_database", - } - - ESX.OpenContext("right", elements3, function(menu3, element3) - local data2 = { current = element3 } - local coords = GetEntityCoords(playerPed) - vehicle = ESX.Game.GetVehicleInDirection() - action = data2.current.value - - if action == "search_database" then - LookupVehicle(element3) - elseif DoesEntityExist(vehicle) then - if action == "vehicle_infos" then - local vehicleData = ESX.Game.GetVehicleProperties(vehicle) - OpenVehicleInfosMenu(vehicleData) - elseif action == "hijack_vehicle" then - if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 3.0) then - TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) - Wait(20000) - ClearPedTasksImmediately(playerPed) - - SetVehicleDoorsLocked(vehicle, 1) - SetVehicleDoorsLockedForAllPlayers(vehicle, false) - ESX.ShowNotification(TranslateCap("vehicle_unlocked")) - end - elseif action == "impound" then - if currentTask.busy then - return - end - - ESX.ShowHelpNotification(TranslateCap("impound_prompt")) - TaskStartScenarioInPlace(playerPed, "CODE_HUMAN_MEDIC_TEND_TO_DEAD", 0, true) - - currentTask.busy = true - currentTask.task = ESX.SetTimeout(10000, function() - ClearPedTasks(playerPed) - ImpoundVehicle(vehicle) - Wait(100) - end) - - CreateThread(function() - while currentTask.busy do - Wait(1000) - - vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) - if not DoesEntityExist(vehicle) and currentTask.busy then - ESX.ShowNotification(TranslateCap("impound_canceled_moved")) - ESX.ClearTimeout(currentTask.task) - ClearPedTasks(playerPed) - currentTask.busy = false - break - end - end - end) - end - else - ESX.ShowNotification(TranslateCap("no_vehicles_nearby")) - end - end, function(menu) - OpenPoliceActionsMenu() - end) - elseif data.current.value == "object_spawner" then - local elements4 = { - { unselectable = true, icon = "fas fa-object", title = element.title }, - { icon = "fas fa-cone", title = TranslateCap("cone"), model = "prop_roadcone02a" }, - { icon = "fas fa-cone", title = TranslateCap("barrier"), model = "prop_barrier_work05" }, - { icon = "fas fa-cone", title = TranslateCap("spikestrips"), model = "p_ld_stinger_s" }, - { icon = "fas fa-cone", title = TranslateCap("box"), model = "prop_boxpile_07d" }, - { icon = "fas fa-cone", title = TranslateCap("cash"), model = "hei_prop_cash_crate_half_full" }, - } - - ESX.OpenContext("right", elements4, function(menu4, element4) - local data2 = { current = element4 } - local playerPed = PlayerPedId() - local coords, forward = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) - local objectCoords = (coords + forward * 1.0) - - ESX.Game.SpawnObject(data2.current.model, objectCoords, function(obj) - Wait(100) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) - end, function(menu) - OpenPoliceActionsMenu() - end) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-police", title = TranslateCap("menu_title") }, + { icon = "fas fa-user", title = TranslateCap("citizen_interaction"), value = "citizen_interaction" }, + { icon = "fas fa-car", title = TranslateCap("vehicle_interaction"), value = "vehicle_interaction" }, + { icon = "fas fa-object", title = TranslateCap("object_spawner"), value = "object_spawner" }, + } + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + + if data.current.value == "citizen_interaction" then + local elements2 = { + { unselectable = true, icon = "fas fa-user", title = element.title }, + { icon = "fas fa-idkyet", title = TranslateCap("id_card"), value = "identity_card" }, + { icon = "fas fa-idkyet", title = TranslateCap("search"), value = "search" }, + { icon = "fas fa-idkyet", title = TranslateCap("handcuff"), value = "handcuff" }, + { icon = "fas fa-idkyet", title = TranslateCap("drag"), value = "drag" }, + { icon = "fas fa-idkyet", title = TranslateCap("put_in_vehicle"), value = "put_in_vehicle" }, + { icon = "fas fa-idkyet", title = TranslateCap("out_the_vehicle"), value = "out_the_vehicle" }, + { icon = "fas fa-idkyet", title = TranslateCap("fine"), value = "fine" }, + { icon = "fas fa-idkyet", title = TranslateCap("unpaid_bills"), value = "unpaid_bills" }, + } + + if Config.EnableLicenses then + elements2[#elements2 + 1] = { + icon = "fas fa-scroll", + title = TranslateCap("license_check"), + value = "license", + } + end + + ESX.OpenContext("right", elements2, function(menu2, element2) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer ~= -1 and closestDistance <= 3.0 then + local data2 = { current = element2 } + local action = data2.current.value + + if action == "identity_card" then + OpenIdentityCardMenu(closestPlayer) + elseif action == "search" then + OpenBodySearchMenu(closestPlayer) + elseif action == "handcuff" then + TriggerServerEvent("esx_policejob:handcuff", GetPlayerServerId(closestPlayer)) + elseif action == "drag" then + TriggerServerEvent("esx_policejob:drag", GetPlayerServerId(closestPlayer)) + elseif action == "put_in_vehicle" then + TriggerServerEvent("esx_policejob:putInVehicle", GetPlayerServerId(closestPlayer)) + elseif action == "out_the_vehicle" then + TriggerServerEvent("esx_policejob:OutVehicle", GetPlayerServerId(closestPlayer)) + elseif action == "fine" then + OpenFineMenu(closestPlayer) + elseif action == "license" then + ShowPlayerLicense(closestPlayer) + elseif action == "unpaid_bills" then + OpenUnpaidBillsMenu(closestPlayer) + end + else + ESX.ShowNotification(TranslateCap("no_players_nearby")) + end + end, function(menu) + OpenPoliceActionsMenu() + end) + elseif data.current.value == "vehicle_interaction" then + local elements3 = { + { unselectable = true, icon = "fas fa-car", title = element.title }, + } + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + + if DoesEntityExist(vehicle) then + elements3[#elements3 + 1] = { icon = "fas fa-car", title = TranslateCap("vehicle_info"), value = "vehicle_infos" } + elements3[#elements3 + 1] = { icon = "fas fa-car", title = TranslateCap("pick_lock"), value = "hijack_vehicle" } + elements3[#elements3 + 1] = { icon = "fas fa-car", title = TranslateCap("impound"), value = "impound" } + end + + elements3[#elements3 + 1] = { + icon = "fas fa-scroll", + title = TranslateCap("search_database"), + value = "search_database", + } + + ESX.OpenContext("right", elements3, function(menu3, element3) + local data2 = { current = element3 } + local coords = GetEntityCoords(playerPed) + vehicle = ESX.Game.GetVehicleInDirection() + action = data2.current.value + + if action == "search_database" then + LookupVehicle(element3) + elseif DoesEntityExist(vehicle) then + if action == "vehicle_infos" then + local vehicleData = ESX.Game.GetVehicleProperties(vehicle) + OpenVehicleInfosMenu(vehicleData) + elseif action == "hijack_vehicle" then + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 3.0) then + TaskStartScenarioInPlace(playerPed, "WORLD_HUMAN_WELDING", 0, true) + Wait(20000) + ClearPedTasksImmediately(playerPed) + + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ESX.ShowNotification(TranslateCap("vehicle_unlocked")) + end + elseif action == "impound" then + if currentTask.busy then + return + end + + ESX.ShowHelpNotification(TranslateCap("impound_prompt")) + TaskStartScenarioInPlace(playerPed, "CODE_HUMAN_MEDIC_TEND_TO_DEAD", 0, true) + + currentTask.busy = true + currentTask.task = ESX.SetTimeout(10000, function() + ClearPedTasks(playerPed) + ImpoundVehicle(vehicle) + Wait(100) + end) + + CreateThread(function() + while currentTask.busy do + Wait(1000) + + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) + if not DoesEntityExist(vehicle) and currentTask.busy then + ESX.ShowNotification(TranslateCap("impound_canceled_moved")) + ESX.ClearTimeout(currentTask.task) + ClearPedTasks(playerPed) + currentTask.busy = false + break + end + end + end) + end + else + ESX.ShowNotification(TranslateCap("no_vehicles_nearby")) + end + end, function(menu) + OpenPoliceActionsMenu() + end) + elseif data.current.value == "object_spawner" then + local elements4 = { + { unselectable = true, icon = "fas fa-object", title = element.title }, + { icon = "fas fa-cone", title = TranslateCap("cone"), model = "prop_roadcone02a" }, + { icon = "fas fa-cone", title = TranslateCap("barrier"), model = "prop_barrier_work05" }, + { icon = "fas fa-cone", title = TranslateCap("spikestrips"), model = "p_ld_stinger_s" }, + { icon = "fas fa-cone", title = TranslateCap("box"), model = "prop_boxpile_07d" }, + { icon = "fas fa-cone", title = TranslateCap("cash"), model = "hei_prop_cash_crate_half_full" }, + } + + ESX.OpenContext("right", elements4, function(menu4, element4) + local data2 = { current = element4 } + local playerPed = PlayerPedId() + local coords, forward = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (coords + forward * 1.0) + + ESX.Game.SpawnObject(data2.current.model, objectCoords, function(obj) + Wait(100) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + end, function(menu) + OpenPoliceActionsMenu() + end) + end + end) end function OpenIdentityCardMenu(player) - ESX.TriggerServerCallback("esx_policejob:getOtherPlayerData", function(data) - local elements = { - { icon = "fas fa-user", title = TranslateCap("name", data.name) }, - { icon = "fas fa-user", title = TranslateCap("job", ("%s - %s"):format(data.job, data.grade)) }, - } - - if Config.EnableESXIdentity then - elements[#elements + 1] = { icon = "fas fa-user", title = TranslateCap("sex", TranslateCap(data.sex)) } - elements[#elements + 1] = { icon = "fas fa-user", title = TranslateCap("sex", TranslateCap(data.sex)) } - elements[#elements + 1] = { icon = "fas fa-user", title = TranslateCap("height", data.height) } - end - - if Config.EnableESXOptionalneeds and data.drunk then - elements[#elements + 1] = { title = TranslateCap("bac", data.drunk) } - end - - if data.licenses then - elements[#elements + 1] = { title = TranslateCap("license_label") } - - for i = 1, #data.licenses, 1 do - elements[#elements + 1] = { title = data.licenses[i].label } - end - end - - ESX.OpenContext("right", elements, nil, function(menu) - OpenPoliceActionsMenu() - end) - end, GetPlayerServerId(player)) + ESX.TriggerServerCallback("esx_policejob:getOtherPlayerData", function(data) + local elements = { + { icon = "fas fa-user", title = TranslateCap("name", data.name) }, + { icon = "fas fa-user", title = TranslateCap("job", ("%s - %s"):format(data.job, data.grade)) }, + } + + if Config.EnableESXIdentity then + elements[#elements + 1] = { icon = "fas fa-user", title = TranslateCap("sex", TranslateCap(data.sex)) } + elements[#elements + 1] = { icon = "fas fa-user", title = TranslateCap("sex", TranslateCap(data.sex)) } + elements[#elements + 1] = { icon = "fas fa-user", title = TranslateCap("height", data.height) } + end + + if Config.EnableESXOptionalneeds and data.drunk then + elements[#elements + 1] = { title = TranslateCap("bac", data.drunk) } + end + + if data.licenses then + elements[#elements + 1] = { title = TranslateCap("license_label") } + + for i = 1, #data.licenses, 1 do + elements[#elements + 1] = { title = data.licenses[i].label } + end + end + + ESX.OpenContext("right", elements, nil, function(menu) + OpenPoliceActionsMenu() + end) + end, GetPlayerServerId(player)) end function OpenBodySearchMenu(player) - if Config.OxInventory then - ESX.CloseContext() - exports.ox_inventory:openInventory("player", GetPlayerServerId(player)) - return - end - - ESX.TriggerServerCallback("esx_policejob:getOtherPlayerData", function(data) - local elements = { - { unselectable = true, icon = "fas fa-user", title = TranslateCap("search") }, - } - - for i = 1, #data.accounts, 1 do - if data.accounts[i].name == "black_money" and data.accounts[i].money > 0 then - elements[#elements + 1] = { - icon = "fas fa-money", - title = TranslateCap("confiscate_dirty", ESX.Math.Round(data.accounts[i].money)), - value = "black_money", - itemType = "item_account", - amount = data.accounts[i].money, - } - break - end - end - - table.insert(elements, { label = TranslateCap("guns_label") }) - - for i = 1, #data.weapons, 1 do - elements[#elements + 1] = { - icon = "fas fa-gun", - title = TranslateCap( - "confiscate_weapon", - ESX.GetWeaponLabel(data.weapons[i].name), - data.weapons[i].ammo - ), - value = data.weapons[i].name, - itemType = "item_weapon", - amount = data.weapons[i].ammo, - } - end - - elements[#elements + 1] = { title = TranslateCap("inventory_label") } - - for i = 1, #data.inventory, 1 do - if data.inventory[i].count > 0 then - elements[#elements + 1] = { - icon = "fas fa-box", - title = TranslateCap("confiscate_inv", data.inventory[i].count, data.inventory[i].label), - value = data.inventory[i].name, - itemType = "item_standard", - amount = data.inventory[i].count, - } - end - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - if data.current.value then - TriggerServerEvent( - "esx_policejob:confiscatePlayerItem", - GetPlayerServerId(player), - data.current.itemType, - data.current.value, - data.current.amount - ) - OpenBodySearchMenu(player) - end - end) - end, GetPlayerServerId(player)) + if Config.OxInventory then + ESX.CloseContext() + exports.ox_inventory:openInventory("player", GetPlayerServerId(player)) + return + end + + ESX.TriggerServerCallback("esx_policejob:getOtherPlayerData", function(data) + local elements = { + { unselectable = true, icon = "fas fa-user", title = TranslateCap("search") }, + } + + for i = 1, #data.accounts, 1 do + if data.accounts[i].name == "black_money" and data.accounts[i].money > 0 then + elements[#elements + 1] = { + icon = "fas fa-money", + title = TranslateCap("confiscate_dirty", ESX.Math.Round(data.accounts[i].money)), + value = "black_money", + itemType = "item_account", + amount = data.accounts[i].money, + } + break + end + end + + table.insert(elements, { label = TranslateCap("guns_label") }) + + for i = 1, #data.weapons, 1 do + elements[#elements + 1] = { + icon = "fas fa-gun", + title = TranslateCap("confiscate_weapon", ESX.GetWeaponLabel(data.weapons[i].name), data.weapons[i].ammo), + value = data.weapons[i].name, + itemType = "item_weapon", + amount = data.weapons[i].ammo, + } + end + + elements[#elements + 1] = { title = TranslateCap("inventory_label") } + + for i = 1, #data.inventory, 1 do + if data.inventory[i].count > 0 then + elements[#elements + 1] = { + icon = "fas fa-box", + title = TranslateCap("confiscate_inv", data.inventory[i].count, data.inventory[i].label), + value = data.inventory[i].name, + itemType = "item_standard", + amount = data.inventory[i].count, + } + end + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + if data.current.value then + TriggerServerEvent("esx_policejob:confiscatePlayerItem", GetPlayerServerId(player), data.current.itemType, data.current.value, data.current.amount) + OpenBodySearchMenu(player) + end + end) + end, GetPlayerServerId(player)) end function OpenFineMenu(player) - if Config.EnableFinePresets then - local elements = { - { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("fine") }, - { icon = "fas fa-scroll", title = TranslateCap("traffic_offense"), value = 0 }, - { icon = "fas fa-scroll", title = TranslateCap("minor_offense"), value = 1 }, - { icon = "fas fa-scroll", title = TranslateCap("average_offense"), value = 2 }, - { icon = "fas fa-scroll", title = TranslateCap("major_offense"), value = 3 }, - } - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - OpenFineCategoryMenu(player, data.current.value) - end) - else - ESX.CloseContext() - ESX.CloseContext() - OpenFineTextInput(player) - end + if Config.EnableFinePresets then + local elements = { + { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("fine") }, + { icon = "fas fa-scroll", title = TranslateCap("traffic_offense"), value = 0 }, + { icon = "fas fa-scroll", title = TranslateCap("minor_offense"), value = 1 }, + { icon = "fas fa-scroll", title = TranslateCap("average_offense"), value = 2 }, + { icon = "fas fa-scroll", title = TranslateCap("major_offense"), value = 3 }, + } + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + OpenFineCategoryMenu(player, data.current.value) + end) + else + ESX.CloseContext() + ESX.CloseContext() + OpenFineTextInput(player) + end end local fineList = {} function OpenFineCategoryMenu(player, category) - if not fineList[category] then - local p = promise.new() - - ESX.TriggerServerCallback("esx_policejob:getFineList", function(fines) - p:resolve(fines) - end, category) - - fineList[category] = Citizen.Await(p) - end - - local elements = { - { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("fine") }, - } - - for k, fine in ipairs(fineList[category]) do - elements[#elements + 1] = { - icon = "fas fa-scroll", - title = ('%s %s'):format( - fine.label, - TranslateCap("armory_item", ESX.Math.GroupDigits(fine.amount)) - ), - value = fine.id, - amount = fine.amount, - fineLabel = fine.label, - } - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - if Config.EnablePlayerManagement then - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(player), - "society_police", - TranslateCap("fine_total", data.current.fineLabel), - data.current.amount - ) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(player), - "", - TranslateCap("fine_total", data.current.fineLabel), - data.current.amount - ) - end - - ESX.SetTimeout(300, function() - OpenFineCategoryMenu(player, category) - end) - end) + if not fineList[category] then + local p = promise.new() + + ESX.TriggerServerCallback("esx_policejob:getFineList", function(fines) + p:resolve(fines) + end, category) + + fineList[category] = Citizen.Await(p) + end + + local elements = { + { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("fine") }, + } + + for k, fine in ipairs(fineList[category]) do + elements[#elements + 1] = { + icon = "fas fa-scroll", + title = ('%s %s'):format(fine.label, TranslateCap("armory_item", ESX.Math.GroupDigits(fine.amount))), + value = fine.id, + amount = fine.amount, + fineLabel = fine.label, + } + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + if Config.EnablePlayerManagement then + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(player), "society_police", TranslateCap("fine_total", data.current.fineLabel), data.current.amount) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(player), "", TranslateCap("fine_total", data.current.fineLabel), data.current.amount) + end + + ESX.SetTimeout(300, function() + OpenFineCategoryMenu(player, category) + end) + end) end function OpenFineTextInput(player) - Citizen.CreateThread(function() - local amount = 0 - local reason = "" - AddTextEntry("FMMC_KEY_TIP1", TranslateCap("fine_enter_amount")) - Citizen.Wait(0) - DisplayOnscreenKeyboard(1, "FMMC_KEY_TIP1", "", "", "", "", "", 30) - while UpdateOnscreenKeyboard() ~= 1 and UpdateOnscreenKeyboard() ~= 2 do - Citizen.Wait(0) - end - if UpdateOnscreenKeyboard() ~= 2 then - amount = tonumber(GetOnscreenKeyboardResult()) - if amount == nil or amount <= 0 then - ESX.ShowNotification(TranslateCap("invalid_amount")) - return - end - end - AddTextEntry("FMMC_KEY_TIP1", TranslateCap("fine_enter_text")) - Citizen.Wait(0) - DisplayOnscreenKeyboard(1, "FMMC_KEY_TIP1", "", "", "", "", "", 120) - while UpdateOnscreenKeyboard() ~= 1 and UpdateOnscreenKeyboard() ~= 2 do - Citizen.Wait(0) - end - if UpdateOnscreenKeyboard() ~= 2 then - reason = GetOnscreenKeyboardResult() - end - Citizen.Wait(500) - TriggerServerEvent("esx_billing:sendBill", GetPlayerServerId(player), "society_police", reason, amount) - OpenPoliceActionsMenu() - end) + Citizen.CreateThread(function() + local amount = 0 + local reason = "" + AddTextEntry("FMMC_KEY_TIP1", TranslateCap("fine_enter_amount")) + Citizen.Wait(0) + DisplayOnscreenKeyboard(1, "FMMC_KEY_TIP1", "", "", "", "", "", 30) + while UpdateOnscreenKeyboard() ~= 1 and UpdateOnscreenKeyboard() ~= 2 do + Citizen.Wait(0) + end + if UpdateOnscreenKeyboard() ~= 2 then + amount = tonumber(GetOnscreenKeyboardResult()) + if amount == nil or amount <= 0 then + ESX.ShowNotification(TranslateCap("invalid_amount")) + return + end + end + AddTextEntry("FMMC_KEY_TIP1", TranslateCap("fine_enter_text")) + Citizen.Wait(0) + DisplayOnscreenKeyboard(1, "FMMC_KEY_TIP1", "", "", "", "", "", 120) + while UpdateOnscreenKeyboard() ~= 1 and UpdateOnscreenKeyboard() ~= 2 do + Citizen.Wait(0) + end + if UpdateOnscreenKeyboard() ~= 2 then + reason = GetOnscreenKeyboardResult() + end + Citizen.Wait(500) + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(player), "society_police", reason, amount) + OpenPoliceActionsMenu() + end) end function LookupVehicle(elementF) - local elements = { - { unselectable = true, icon = "fas fa-car", title = elementF.title }, - { title = TranslateCap("search_plate"), input = true, inputType = "text", inputPlaceholder = "ABC 123" }, - { icon = "fas fa-check-double", title = TranslateCap("lookup_plate"), value = "lookup" }, - } - - ESX.OpenContext("right", elements, function(menu, element) - local data = { value = menu.eles[2].inputValue } - local length = string.len(data.value) - if not data.value or length < 2 or length > 8 then - ESX.ShowNotification(TranslateCap("search_database_error_invalid")) - else - ESX.TriggerServerCallback("esx_policejob:getVehicleInfos", function(retrivedInfo) - local elements = { - { unselectable = true, icon = "fas fa-car", title = element.title }, - { unselectable = true, icon = "fas fa-car", title = TranslateCap("plate", retrivedInfo.plate) }, - } - - if not retrivedInfo.owner then - elements[#elements + 1] = - { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner_unknown") } - else - elements[#elements + 1] = - { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner", retrivedInfo.owner) } - end - - ESX.OpenContext("right", elements, nil, function(menu) - OpenPoliceActionsMenu() - end) - end, data.value) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-car", title = elementF.title }, + { title = TranslateCap("search_plate"), input = true, inputType = "text", inputPlaceholder = "ABC 123" }, + { icon = "fas fa-check-double", title = TranslateCap("lookup_plate"), value = "lookup" }, + } + + ESX.OpenContext("right", elements, function(menu, element) + local data = { value = menu.eles[2].inputValue } + local length = string.len(data.value) + if not data.value or length < 2 or length > 8 then + ESX.ShowNotification(TranslateCap("search_database_error_invalid")) + else + ESX.TriggerServerCallback("esx_policejob:getVehicleInfos", function(retrivedInfo) + local elements = { + { unselectable = true, icon = "fas fa-car", title = element.title }, + { unselectable = true, icon = "fas fa-car", title = TranslateCap("plate", retrivedInfo.plate) }, + } + + if not retrivedInfo.owner then + elements[#elements + 1] = { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner_unknown") } + else + elements[#elements + 1] = { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner", retrivedInfo.owner) } + end + + ESX.OpenContext("right", elements, nil, function(menu) + OpenPoliceActionsMenu() + end) + end, data.value) + end + end) end function ShowPlayerLicense(player) - local elements = { - { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("license_revoke") }, - } - - ESX.TriggerServerCallback("esx_policejob:getOtherPlayerData", function(playerData) - if playerData.licenses then - for i = 1, #playerData.licenses, 1 do - if playerData.licenses[i].label and playerData.licenses[i].type then - elements[#elements + 1] = { - icon = "fas fa-scroll", - title = playerData.licenses[i].label, - type = playerData.licenses[i].type, - } - end - end - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - ESX.ShowNotification(TranslateCap("licence_you_revoked", data.current.label, playerData.name)) - TriggerServerEvent( - "esx_policejob:message", - GetPlayerServerId(player), - TranslateCap("license_revoked", data.current.label) - ) - - TriggerServerEvent("esx_license:removeLicense", GetPlayerServerId(player), data.current.type) - - ESX.SetTimeout(300, function() - ShowPlayerLicense(player) - end) - end) - end, GetPlayerServerId(player)) + local elements = { + { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("license_revoke") }, + } + + ESX.TriggerServerCallback("esx_policejob:getOtherPlayerData", function(playerData) + if playerData.licenses then + for i = 1, #playerData.licenses, 1 do + if playerData.licenses[i].label and playerData.licenses[i].type then + elements[#elements + 1] = { + icon = "fas fa-scroll", + title = playerData.licenses[i].label, + type = playerData.licenses[i].type, + } + end + end + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + ESX.ShowNotification(TranslateCap("licence_you_revoked", data.current.label, playerData.name)) + TriggerServerEvent("esx_policejob:message", GetPlayerServerId(player), TranslateCap("license_revoked", data.current.label)) + + TriggerServerEvent("esx_license:removeLicense", GetPlayerServerId(player), data.current.type) + + ESX.SetTimeout(300, function() + ShowPlayerLicense(player) + end) + end) + end, GetPlayerServerId(player)) end function OpenUnpaidBillsMenu(player) - local elements = { - { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("unpaid_bills") }, - } - - ESX.TriggerServerCallback("esx_billing:getTargetBills", function(bills) - for _, bill in ipairs(bills) do - elements[#elements + 1] = { - unselectable = true, - icon = "fas fa-scroll", - title = ('%s - %s'):format( - bill.label, - TranslateCap("armory_item", ESX.Math.GroupDigits(bill.amount)) - ), - billId = bill.id, - } - end - - ESX.OpenContext("right", elements, nil, nil) - end, GetPlayerServerId(player)) + local elements = { + { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("unpaid_bills") }, + } + + ESX.TriggerServerCallback("bpt:getTargetBills", function(bills) + for _, bill in ipairs(bills) do + elements[#elements + 1] = { + unselectable = true, + icon = "fas fa-scroll", + title = ('%s - %s'):format(bill.label, TranslateCap("armory_item", ESX.Math.GroupDigits(bill.amount))), + billId = bill.id, + } + end + + ESX.OpenContext("right", elements, nil, nil) + end, GetPlayerServerId(player)) end function OpenVehicleInfosMenu(vehicleData) - ESX.TriggerServerCallback("esx_policejob:getVehicleInfos", function(retrivedInfo) - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("vehicle_info") }, - { icon = "fas fa-car", title = TranslateCap("plate", retrivedInfo.plate) }, - } - - if not retrivedInfo.owner then - elements[#elements + 1] = - { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner_unknown") } - else - elements[#elements + 1] = - { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner", retrivedInfo.owner) } - end - - ESX.OpenContext("right", elements, nil, nil) - end, vehicleData.plate) + ESX.TriggerServerCallback("esx_policejob:getVehicleInfos", function(retrivedInfo) + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("vehicle_info") }, + { icon = "fas fa-car", title = TranslateCap("plate", retrivedInfo.plate) }, + } + + if not retrivedInfo.owner then + elements[#elements + 1] = { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner_unknown") } + else + elements[#elements + 1] = { unselectable = true, icon = "fas fa-user", title = TranslateCap("owner", retrivedInfo.owner) } + end + + ESX.OpenContext("right", elements, nil, nil) + end, vehicleData.plate) end function OpenGetWeaponMenu() - ESX.TriggerServerCallback("esx_policejob:getArmoryWeapons", function(weapons) - local elements = { - { unselectable = true, icon = "fas fa-gun", title = TranslateCap("get_weapon_menu") }, - } - - for i = 1, #weapons, 1 do - if weapons[i].count > 0 then - elements[#elements + 1] = { - icon = "fas fa-gun", - title = "x" .. weapons[i].count .. " " .. ESX.GetWeaponLabel(weapons[i].name), - value = weapons[i].name, - } - end - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - ESX.TriggerServerCallback("esx_policejob:removeArmoryWeapon", function() - ESX.CloseContext() - OpenGetWeaponMenu() - end, data.current.value) - end) - end) + ESX.TriggerServerCallback("esx_policejob:getArmoryWeapons", function(weapons) + local elements = { + { unselectable = true, icon = "fas fa-gun", title = TranslateCap("get_weapon_menu") }, + } + + for i = 1, #weapons, 1 do + if weapons[i].count > 0 then + elements[#elements + 1] = { + icon = "fas fa-gun", + title = "x" .. weapons[i].count .. " " .. ESX.GetWeaponLabel(weapons[i].name), + value = weapons[i].name, + } + end + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + ESX.TriggerServerCallback("esx_policejob:removeArmoryWeapon", function() + ESX.CloseContext() + OpenGetWeaponMenu() + end, data.current.value) + end) + end) end function OpenPutWeaponMenu() - local elements = { - { unselectable = true, icon = "fas fa-gun", title = TranslateCap("put_weapon_menu") }, - } - local playerPed = PlayerPedId() - local weaponList = ESX.GetWeaponList() - - for i = 1, #weaponList, 1 do - local weaponHash = joaat(weaponList[i].name) - - if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= "WEAPON_UNARMED" then - elements[#elements + 1] = { - icon = "fas fa-gun", - title = weaponList[i].label, - value = weaponList[i].name, - } - end - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - ESX.TriggerServerCallback("esx_policejob:addArmoryWeapon", function() - ESX.CloseContext() - OpenPutWeaponMenu() - end, data.current.value, true) - end) + local elements = { + { unselectable = true, icon = "fas fa-gun", title = TranslateCap("put_weapon_menu") }, + } + local playerPed = PlayerPedId() + local weaponList = ESX.GetWeaponList() + + for i = 1, #weaponList, 1 do + local weaponHash = joaat(weaponList[i].name) + + if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= "WEAPON_UNARMED" then + elements[#elements + 1] = { + icon = "fas fa-gun", + title = weaponList[i].label, + value = weaponList[i].name, + } + end + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + ESX.TriggerServerCallback("esx_policejob:addArmoryWeapon", function() + ESX.CloseContext() + OpenPutWeaponMenu() + end, data.current.value, true) + end) end function OpenBuyWeaponsMenu() - local elements = { - { unselectable = true, icon = "fas fa-gun", title = TranslateCap("armory_weapontitle") }, - } - local playerPed = PlayerPedId() - - for _, v in ipairs(Config.AuthorizedWeapons[ESX.PlayerData.job.grade_name]) do - local _, weapon = ESX.GetWeapon(v.weapon) - local components, label = {} - local hasWeapon = HasPedGotWeapon(playerPed, joaat(v.weapon), false) - - if v.components then - for i = 1, #v.components do - if v.components[i] then - local component = weapon.components[i] - local hasComponent = HasPedGotWeaponComponent(playerPed, joaat(v.weapon), component.hash) - - if hasComponent then - label = ('%s: %s'):format( - component.label, - TranslateCap("armory_owned") - ) - else - if v.components[i] > 0 then - label = ('%s: %s'):format( - component.label, - TranslateCap("armory_item", ESX.Math.GroupDigits(v.components[i])) - ) - else - label = ('%s: %s'):format( - component.label, - TranslateCap("armory_free") - ) - end - end - - components[#components + 1] = { - icon = "fas fa-gun", - title = label, - componentLabel = component.label, - hash = component.hash, - name = component.name, - price = v.components[i], - hasComponent = hasComponent, - componentNum = i, - } - end - end - end - - if hasWeapon and v.components then - label = ('%s: >'):format(weapon.label) - elseif hasWeapon and not v.components then - label = ('%s: %s'):format(weapon.label, TranslateCap("armory_owned")) - else - if v.price > 0 then - label = ('%s: %s'):format( - weapon.label, - TranslateCap("armory_item", ESX.Math.GroupDigits(v.price)) - ) - else - label = ('%s: %s'):format(weapon.label, TranslateCap("armory_free")) - end - end - - elements[#elements + 1] = { - icon = "fas fa-gun", - title = label, - weaponLabel = weapon.label, - name = weapon.name, - components = components, - price = v.price, - hasWeapon = hasWeapon, - } - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - if data.current.hasWeapon then - if #data.current.components > 0 then - OpenWeaponComponentShop(data.current.components, data.current.name, menu) - end - else - ESX.TriggerServerCallback("esx_policejob:buyWeapon", function(bought) - if bought then - if data.current.price > 0 then - ESX.ShowNotification( - TranslateCap( - "armory_bought", - data.current.weaponLabel, - ESX.Math.GroupDigits(data.current.price) - ) - ) - end - - ESX.CloseContext() - OpenBuyWeaponsMenu() - else - ESX.ShowNotification(TranslateCap("armory_money")) - end - end, data.current.name, 1) - end - end) + local elements = { + { unselectable = true, icon = "fas fa-gun", title = TranslateCap("armory_weapontitle") }, + } + local playerPed = PlayerPedId() + + for _, v in ipairs(Config.AuthorizedWeapons[ESX.PlayerData.job.grade_name]) do + local _, weapon = ESX.GetWeapon(v.weapon) + local components, label = {} + local hasWeapon = HasPedGotWeapon(playerPed, joaat(v.weapon), false) + + if v.components then + for i = 1, #v.components do + if v.components[i] then + local component = weapon.components[i] + local hasComponent = HasPedGotWeaponComponent(playerPed, joaat(v.weapon), component.hash) + + if hasComponent then + label = ('%s: %s'):format(component.label, TranslateCap("armory_owned")) + else + if v.components[i] > 0 then + label = ('%s: %s'):format(component.label, TranslateCap("armory_item", ESX.Math.GroupDigits(v.components[i]))) + else + label = ('%s: %s'):format(component.label, TranslateCap("armory_free")) + end + end + + components[#components + 1] = { + icon = "fas fa-gun", + title = label, + componentLabel = component.label, + hash = component.hash, + name = component.name, + price = v.components[i], + hasComponent = hasComponent, + componentNum = i, + } + end + end + end + + if hasWeapon and v.components then + label = ('%s: >'):format(weapon.label) + elseif hasWeapon and not v.components then + label = ('%s: %s'):format(weapon.label, TranslateCap("armory_owned")) + else + if v.price > 0 then + label = ('%s: %s'):format(weapon.label, TranslateCap("armory_item", ESX.Math.GroupDigits(v.price))) + else + label = ('%s: %s'):format(weapon.label, TranslateCap("armory_free")) + end + end + + elements[#elements + 1] = { + icon = "fas fa-gun", + title = label, + weaponLabel = weapon.label, + name = weapon.name, + components = components, + price = v.price, + hasWeapon = hasWeapon, + } + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + if data.current.hasWeapon then + if #data.current.components > 0 then + OpenWeaponComponentShop(data.current.components, data.current.name, menu) + end + else + ESX.TriggerServerCallback("esx_policejob:buyWeapon", function(bought) + if bought then + if data.current.price > 0 then + ESX.ShowNotification(TranslateCap("armory_bought", data.current.weaponLabel, ESX.Math.GroupDigits(data.current.price))) + end + + ESX.CloseContext() + OpenBuyWeaponsMenu() + else + ESX.ShowNotification(TranslateCap("armory_money")) + end + end, data.current.name, 1) + end + end) end function OpenWeaponComponentShop(components, weaponName, parentShop) - ESX.OpenContext("right", components, function(menu, element) - local data = { current = element } - if data.current.hasComponent then - ESX.ShowNotification(TranslateCap("armory_hascomponent")) - else - ESX.TriggerServerCallback("esx_policejob:buyWeapon", function(bought) - if bought then - if data.current.price > 0 then - ESX.ShowNotification( - TranslateCap( - "armory_bought", - data.current.componentLabel, - ESX.Math.GroupDigits(data.current.price) - ) - ) - end - - ESX.CloseContext() - parentShop.close() - OpenBuyWeaponsMenu() - else - ESX.ShowNotification(TranslateCap("armory_money")) - end - end, weaponName, 2, data.current.componentNum) - end - end) + ESX.OpenContext("right", components, function(menu, element) + local data = { current = element } + if data.current.hasComponent then + ESX.ShowNotification(TranslateCap("armory_hascomponent")) + else + ESX.TriggerServerCallback("esx_policejob:buyWeapon", function(bought) + if bought then + if data.current.price > 0 then + ESX.ShowNotification(TranslateCap("armory_bought", data.current.componentLabel, ESX.Math.GroupDigits(data.current.price))) + end + + ESX.CloseContext() + parentShop.close() + OpenBuyWeaponsMenu() + else + ESX.ShowNotification(TranslateCap("armory_money")) + end + end, weaponName, 2, data.current.componentNum) + end + end) end function OpenGetStocksMenu() - ESX.TriggerServerCallback("esx_policejob:getStockItems", function(items) - local elements = { - { unselectable = true, icon = "fas fa-box", title = TranslateCap("police_stock") }, - } - - for i = 1, #items, 1 do - elements[#elements + 1] = { - icon = "fas fa-box", - title = "x" .. items[i].count .. " " .. items[i].label, - value = items[i].name, - } - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - local itemName = data.current.value - - local elements2 = { - { unselectable = true, icon = "fas fa-box", title = element.title }, - { - title = TranslateCap("quantity"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 150, - inputPlaceholder = TranslateCap("quantity_placeholder"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2, element2) - local data2 = { value = menu2.eles[2].inputValue } - local count = tonumber(data2.value) - - if not count then - ESX.ShowNotification(TranslateCap("quantity_invalid")) - else - ESX.CloseContext() - TriggerServerEvent("esx_policejob:getStockItem", itemName, count) - - Wait(300) - OpenGetStocksMenu() - end - end) - end) - end) + ESX.TriggerServerCallback("esx_policejob:getStockItems", function(items) + local elements = { + { unselectable = true, icon = "fas fa-box", title = TranslateCap("police_stock") }, + } + + for i = 1, #items, 1 do + elements[#elements + 1] = { + icon = "fas fa-box", + title = "x" .. items[i].count .. " " .. items[i].label, + value = items[i].name, + } + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + local itemName = data.current.value + + local elements2 = { + { unselectable = true, icon = "fas fa-box", title = element.title }, + { + title = TranslateCap("quantity"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 150, + inputPlaceholder = TranslateCap("quantity_placeholder"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2, element2) + local data2 = { value = menu2.eles[2].inputValue } + local count = tonumber(data2.value) + + if not count then + ESX.ShowNotification(TranslateCap("quantity_invalid")) + else + ESX.CloseContext() + TriggerServerEvent("esx_policejob:getStockItem", itemName, count) + + Wait(300) + OpenGetStocksMenu() + end + end) + end) + end) end function OpenPutStocksMenu() - ESX.TriggerServerCallback("esx_policejob:getPlayerInventory", function(inventory) - local elements = { - { unselectable = true, icon = "fas fa-box", title = TranslateCap("inventory") }, - } - - for i = 1, #inventory.items, 1 do - local item = inventory.items[i] - - if item.count > 0 then - elements[#elements + 1] = { - icon = "fas fa-box", - title = item.label .. " x" .. item.count, - type = "item_standard", - value = item.name, - } - end - end - - ESX.OpenContext("right", elements, function(menu, element) - local data = { current = element } - local itemName = data.current.value - - local elements2 = { - { unselectable = true, icon = "fas fa-box", title = element.title }, - { - title = TranslateCap("quantity"), - input = true, - inputType = "number", - inputMin = 1, - inputMax = 150, - inputPlaceholder = TranslateCap("quantity_placeholder"), - }, - { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, - } - - ESX.OpenContext("right", elements2, function(menu2, element2) - local data2 = { value = menu2.eles[2].inputValue } - local count = tonumber(data2.value) - - if not count then - ESX.ShowNotification(TranslateCap("quantity_invalid")) - else - ESX.CloseContext() - TriggerServerEvent("esx_policejob:putStockItems", itemName, count) - - Wait(300) - OpenPutStocksMenu() - end - end) - end) - end) + ESX.TriggerServerCallback("esx_policejob:getPlayerInventory", function(inventory) + local elements = { + { unselectable = true, icon = "fas fa-box", title = TranslateCap("inventory") }, + } + + for i = 1, #inventory.items, 1 do + local item = inventory.items[i] + + if item.count > 0 then + elements[#elements + 1] = { + icon = "fas fa-box", + title = item.label .. " x" .. item.count, + type = "item_standard", + value = item.name, + } + end + end + + ESX.OpenContext("right", elements, function(menu, element) + local data = { current = element } + local itemName = data.current.value + + local elements2 = { + { unselectable = true, icon = "fas fa-box", title = element.title }, + { + title = TranslateCap("quantity"), + input = true, + inputType = "number", + inputMin = 1, + inputMax = 150, + inputPlaceholder = TranslateCap("quantity_placeholder"), + }, + { icon = "fas fa-check-double", title = TranslateCap("confirm"), value = "confirm" }, + } + + ESX.OpenContext("right", elements2, function(menu2, element2) + local data2 = { value = menu2.eles[2].inputValue } + local count = tonumber(data2.value) + + if not count then + ESX.ShowNotification(TranslateCap("quantity_invalid")) + else + ESX.CloseContext() + TriggerServerEvent("esx_policejob:putStockItems", itemName, count) + + Wait(300) + OpenPutStocksMenu() + end + end) + end) + end) end function OnPlayerData(k, v) - if k ~= "job" then - return - end - if v.name == "police" then - Wait(1000) - TriggerServerEvent("esx_policejob:forceBlip") - end + if k ~= "job" then + return + end + if v.name == "police" then + Wait(1000) + TriggerServerEvent("esx_policejob:forceBlip") + end end RegisterNetEvent("esx_phone:loaded") AddEventHandler("esx_phone:loaded", function(phoneNumber, contacts) - local specialContact = { - name = TranslateCap("phone_police"), - number = "police", - base64Icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDFGQTJDRkI0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDFGQTJDRkM0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MUZBMkNGOTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MUZBMkNGQTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoW66EYAAAjGSURBVHjapJcLcFTV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", - } + local specialContact = { + name = TranslateCap("phone_police"), + number = "police", + base64Icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDFGQTJDRkI0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDFGQTJDRkM0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MUZBMkNGOTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MUZBMkNGQTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoW66EYAAAjGSURBVHjapJcLcFTV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", + } - TriggerEvent("esx_phone:addSpecialContact", specialContact.name, specialContact.number, specialContact.base64Icon) + TriggerEvent("esx_phone:addSpecialContact", specialContact.name, specialContact.number, specialContact.base64Icon) end) -- don't show dispatches if the player isn't in service AddEventHandler("esx_phone:cancelMessage", function(dispatchNumber) - if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" and ESX.PlayerData.job.name == dispatchNumber then - -- if esx_service is enabled - if Config.EnableESXService and not playerInService then - CancelEvent() - end - end + if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" and ESX.PlayerData.job.name == dispatchNumber then + -- if esx_service is enabled + if Config.EnableESXService and not playerInService then + CancelEvent() + end + end end) AddEventHandler("esx_policejob:hasEnteredMarker", function(station, part, partNum) - if part == "Cloakroom" then - CurrentAction = "menu_cloakroom" - CurrentActionMsg = TranslateCap("open_cloackroom") - CurrentActionData = {} - elseif part == "Armory" then - CurrentAction = "menu_armory" - CurrentActionMsg = TranslateCap("open_armory") - CurrentActionData = { station = station } - elseif part == "Vehicles" then - CurrentAction = "menu_vehicle_spawner" - CurrentActionMsg = TranslateCap("garage_prompt") - CurrentActionData = { station = station, part = part, partNum = partNum } - elseif part == "Helicopters" then - CurrentAction = "Helicopters" - CurrentActionMsg = TranslateCap("helicopter_prompt") - CurrentActionData = { station = station, part = part, partNum = partNum } - elseif part == "BossActions" then - CurrentAction = "menu_boss_actions" - CurrentActionMsg = TranslateCap("open_bossmenu") - CurrentActionData = {} - end + if part == "Cloakroom" then + CurrentAction = "menu_cloakroom" + CurrentActionMsg = TranslateCap("open_cloackroom") + CurrentActionData = {} + elseif part == "Armory" then + CurrentAction = "menu_armory" + CurrentActionMsg = TranslateCap("open_armory") + CurrentActionData = { station = station } + elseif part == "Vehicles" then + CurrentAction = "menu_vehicle_spawner" + CurrentActionMsg = TranslateCap("garage_prompt") + CurrentActionData = { station = station, part = part, partNum = partNum } + elseif part == "Helicopters" then + CurrentAction = "Helicopters" + CurrentActionMsg = TranslateCap("helicopter_prompt") + CurrentActionData = { station = station, part = part, partNum = partNum } + elseif part == "BossActions" then + CurrentAction = "menu_boss_actions" + CurrentActionMsg = TranslateCap("open_bossmenu") + CurrentActionData = {} + end end) AddEventHandler("esx_policejob:hasExitedMarker", function(station, part, partNum) - if not isInShopMenu then - ESX.CloseContext() - end + if not isInShopMenu then + ESX.CloseContext() + end - CurrentAction = nil + CurrentAction = nil end) AddEventHandler("esx_policejob:hasEnteredEntityZone", function(entity) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() - if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" and IsPedOnFoot(playerPed) then - CurrentAction = "remove_entity" - CurrentActionMsg = TranslateCap("remove_prop") - CurrentActionData = { entity = entity } - end + if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" and IsPedOnFoot(playerPed) then + CurrentAction = "remove_entity" + CurrentActionMsg = TranslateCap("remove_prop") + CurrentActionData = { entity = entity } + end - if GetEntityModel(entity) == `p_ld_stinger_s` then - local _ = GetEntityCoords(playerPed) + if GetEntityModel(entity) == `p_ld_stinger_s` then + local _ = GetEntityCoords(playerPed) - if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed) + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed) - for i = 0, 7, 1 do - SetVehicleTyreBurst(vehicle, i, true, 1000) - end - end - end + for i = 0, 7, 1 do + SetVehicleTyreBurst(vehicle, i, true, 1000) + end + end + end end) AddEventHandler("esx_policejob:hasExitedEntityZone", function(entity) - if CurrentAction == "remove_entity" then - CurrentAction = nil - end + if CurrentAction == "remove_entity" then + CurrentAction = nil + end end) RegisterNetEvent("esx_policejob:handcuff") AddEventHandler("esx_policejob:handcuff", function() - isHandcuffed = not isHandcuffed - local playerPed = PlayerPedId() - - if isHandcuffed then - RequestAnimDict("mp_arresting") - while not HasAnimDictLoaded("mp_arresting") do - Wait(100) - end - - TaskPlayAnim(playerPed, "mp_arresting", "idle", 8.0, -8, -1, 49, 0, 0, 0, 0) - RemoveAnimDict("mp_arresting") - - SetEnableHandcuffs(playerPed, true) - DisablePlayerFiring(playerPed, true) - SetCurrentPedWeapon(playerPed, `WEAPON_UNARMED`, true) -- unarm player - SetPedCanPlayGestureAnims(playerPed, false) - FreezeEntityPosition(playerPed, true) - DisplayRadar(false) - - if Config.EnableHandcuffTimer then - if handcuffTimer.active then - ESX.ClearTimeout(handcuffTimer.task) - end - - StartHandcuffTimer() - end - else - if Config.EnableHandcuffTimer and handcuffTimer.active then - ESX.ClearTimeout(handcuffTimer.task) - end - - ClearPedSecondaryTask(playerPed) - SetEnableHandcuffs(playerPed, false) - DisablePlayerFiring(playerPed, false) - SetPedCanPlayGestureAnims(playerPed, true) - FreezeEntityPosition(playerPed, false) - DisplayRadar(true) - end + isHandcuffed = not isHandcuffed + local playerPed = PlayerPedId() + + if isHandcuffed then + RequestAnimDict("mp_arresting") + while not HasAnimDictLoaded("mp_arresting") do + Wait(100) + end + + TaskPlayAnim(playerPed, "mp_arresting", "idle", 8.0, -8, -1, 49, 0, 0, 0, 0) + RemoveAnimDict("mp_arresting") + + SetEnableHandcuffs(playerPed, true) + DisablePlayerFiring(playerPed, true) + SetCurrentPedWeapon(playerPed, `WEAPON_UNARMED`, true) -- unarm player + SetPedCanPlayGestureAnims(playerPed, false) + FreezeEntityPosition(playerPed, true) + DisplayRadar(false) + + if Config.EnableHandcuffTimer then + if handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + + StartHandcuffTimer() + end + else + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + + ClearPedSecondaryTask(playerPed) + SetEnableHandcuffs(playerPed, false) + DisablePlayerFiring(playerPed, false) + SetPedCanPlayGestureAnims(playerPed, true) + FreezeEntityPosition(playerPed, false) + DisplayRadar(true) + end end) RegisterNetEvent("esx_policejob:unrestrain") AddEventHandler("esx_policejob:unrestrain", function() - if isHandcuffed then - local playerPed = PlayerPedId() - isHandcuffed = false - - ClearPedSecondaryTask(playerPed) - SetEnableHandcuffs(playerPed, false) - DisablePlayerFiring(playerPed, false) - SetPedCanPlayGestureAnims(playerPed, true) - FreezeEntityPosition(playerPed, false) - DisplayRadar(true) - - -- end timer - if Config.EnableHandcuffTimer and handcuffTimer.active then - ESX.ClearTimeout(handcuffTimer.task) - end - end + if isHandcuffed then + local playerPed = PlayerPedId() + isHandcuffed = false + + ClearPedSecondaryTask(playerPed) + SetEnableHandcuffs(playerPed, false) + DisablePlayerFiring(playerPed, false) + SetPedCanPlayGestureAnims(playerPed, true) + FreezeEntityPosition(playerPed, false) + DisplayRadar(true) + + -- end timer + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + end end) RegisterNetEvent("esx_policejob:drag") AddEventHandler("esx_policejob:drag", function(copId) - if isHandcuffed then - dragStatus.isDragged = not dragStatus.isDragged - dragStatus.CopId = copId - end + if isHandcuffed then + dragStatus.isDragged = not dragStatus.isDragged + dragStatus.CopId = copId + end end) CreateThread(function() - local wasDragged - - while true do - local Sleep = 1500 - - if isHandcuffed and dragStatus.isDragged then - Sleep = 50 - local targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId)) - - if DoesEntityExist(targetPed) and IsPedOnFoot(targetPed) and not IsPedDeadOrDying(targetPed, true) then - if not wasDragged then - AttachEntityToEntity( - ESX.PlayerData.ped, - targetPed, - 11816, - 0.54, - 0.54, - 0.0, - 0.0, - 0.0, - 0.0, - false, - false, - false, - false, - 2, - true - ) - wasDragged = true - else - Wait(1000) - end - else - wasDragged = false - dragStatus.isDragged = false - DetachEntity(ESX.PlayerData.ped, true, false) - end - elseif wasDragged then - wasDragged = false - DetachEntity(ESX.PlayerData.ped, true, false) - end - Wait(Sleep) - end + local wasDragged + + while true do + local Sleep = 1500 + + if isHandcuffed and dragStatus.isDragged then + Sleep = 50 + local targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId)) + + if DoesEntityExist(targetPed) and IsPedOnFoot(targetPed) and not IsPedDeadOrDying(targetPed, true) then + if not wasDragged then + AttachEntityToEntity(ESX.PlayerData.ped, targetPed, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) + wasDragged = true + else + Wait(1000) + end + else + wasDragged = false + dragStatus.isDragged = false + DetachEntity(ESX.PlayerData.ped, true, false) + end + elseif wasDragged then + wasDragged = false + DetachEntity(ESX.PlayerData.ped, true, false) + end + Wait(Sleep) + end end) RegisterNetEvent("esx_policejob:putInVehicle") AddEventHandler("esx_policejob:putInVehicle", function() - if isHandcuffed then - local playerPed = PlayerPedId() - local vehicle, distance = ESX.Game.GetClosestVehicle() - - if vehicle and distance < 5 then - local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) - - for i = maxSeats - 1, 0, -1 do - if IsVehicleSeatFree(vehicle, i) then - freeSeat = i - break - end - end - - if freeSeat then - TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) - dragStatus.isDragged = false - end - end - end + if isHandcuffed then + local playerPed = PlayerPedId() + local vehicle, distance = ESX.Game.GetClosestVehicle() + + if vehicle and distance < 5 then + local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) + + for i = maxSeats - 1, 0, -1 do + if IsVehicleSeatFree(vehicle, i) then + freeSeat = i + break + end + end + + if freeSeat then + TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) + dragStatus.isDragged = false + end + end + end end) RegisterNetEvent("esx_policejob:OutVehicle") AddEventHandler("esx_policejob:OutVehicle", function() - local GetVehiclePedIsIn = GetVehiclePedIsIn - local IsPedSittingInAnyVehicle = IsPedSittingInAnyVehicle - local TaskLeaveVehicle = TaskLeaveVehicle - if IsPedSittingInAnyVehicle(ESX.PlayerData.ped) then - local vehicle = GetVehiclePedIsIn(ESX.PlayerData.ped, false) - TaskLeaveVehicle(ESX.PlayerData.ped, vehicle, 64) - end + local GetVehiclePedIsIn = GetVehiclePedIsIn + local IsPedSittingInAnyVehicle = IsPedSittingInAnyVehicle + local TaskLeaveVehicle = TaskLeaveVehicle + if IsPedSittingInAnyVehicle(ESX.PlayerData.ped) then + local vehicle = GetVehiclePedIsIn(ESX.PlayerData.ped, false) + TaskLeaveVehicle(ESX.PlayerData.ped, vehicle, 64) + end end) -- Handcuff CreateThread(function() - local DisableControlAction = DisableControlAction - local IsEntityPlayingAnim = IsEntityPlayingAnim - while true do - local Sleep = 1000 - - if isHandcuffed then - Sleep = 0 - DisableControlAction(0, 1, true) -- Disable pan - DisableControlAction(0, 2, true) -- Disable tilt - DisableControlAction(0, 24, true) -- Attack - DisableControlAction(0, 257, true) -- Attack 2 - DisableControlAction(0, 25, true) -- Aim - DisableControlAction(0, 263, true) -- Melee Attack 1 - DisableControlAction(0, 32, true) -- W - DisableControlAction(0, 34, true) -- A - DisableControlAction(0, 31, true) -- S - DisableControlAction(0, 30, true) -- D - - DisableControlAction(0, 45, true) -- Reload - DisableControlAction(0, 22, true) -- Jump - DisableControlAction(0, 44, true) -- Cover - DisableControlAction(0, 37, true) -- Select Weapon - DisableControlAction(0, 23, true) -- Also 'enter'? - - DisableControlAction(0, 288, true) -- Disable phone - DisableControlAction(0, 289, true) -- Inventory - DisableControlAction(0, 170, true) -- Animations - DisableControlAction(0, 167, true) -- Job - - DisableControlAction(0, 0, true) -- Disable changing view - DisableControlAction(0, 26, true) -- Disable looking behind - DisableControlAction(0, 73, true) -- Disable clearing animation - DisableControlAction(2, 199, true) -- Disable pause screen - - DisableControlAction(0, 59, true) -- Disable steering in vehicle - DisableControlAction(0, 71, true) -- Disable driving forward in vehicle - DisableControlAction(0, 72, true) -- Disable reversing in vehicle - - DisableControlAction(2, 36, true) -- Disable going stealth - - DisableControlAction(0, 47, true) -- Disable weapon - DisableControlAction(0, 264, true) -- Disable melee - DisableControlAction(0, 257, true) -- Disable melee - DisableControlAction(0, 140, true) -- Disable melee - DisableControlAction(0, 141, true) -- Disable melee - DisableControlAction(0, 142, true) -- Disable melee - DisableControlAction(0, 143, true) -- Disable melee - DisableControlAction(0, 75, true) -- Disable exit vehicle - DisableControlAction(27, 75, true) -- Disable exit vehicle - - if IsEntityPlayingAnim(ESX.PlayerData.ped, "mp_arresting", "idle", 3) ~= 1 then - ESX.Streaming.RequestAnimDict("mp_arresting", function() - TaskPlayAnim(ESX.PlayerData.ped, "mp_arresting", "idle", 8.0, -8, -1, 49, 0.0, false, false, false) - RemoveAnimDict("mp_arresting") - end) - end - end - Wait(Sleep) - end + local DisableControlAction = DisableControlAction + local IsEntityPlayingAnim = IsEntityPlayingAnim + while true do + local Sleep = 1000 + + if isHandcuffed then + Sleep = 0 + DisableControlAction(0, 1, true) -- Disable pan + DisableControlAction(0, 2, true) -- Disable tilt + DisableControlAction(0, 24, true) -- Attack + DisableControlAction(0, 257, true) -- Attack 2 + DisableControlAction(0, 25, true) -- Aim + DisableControlAction(0, 263, true) -- Melee Attack 1 + DisableControlAction(0, 32, true) -- W + DisableControlAction(0, 34, true) -- A + DisableControlAction(0, 31, true) -- S + DisableControlAction(0, 30, true) -- D + + DisableControlAction(0, 45, true) -- Reload + DisableControlAction(0, 22, true) -- Jump + DisableControlAction(0, 44, true) -- Cover + DisableControlAction(0, 37, true) -- Select Weapon + DisableControlAction(0, 23, true) -- Also 'enter'? + + DisableControlAction(0, 288, true) -- Disable phone + DisableControlAction(0, 289, true) -- Inventory + DisableControlAction(0, 170, true) -- Animations + DisableControlAction(0, 167, true) -- Job + + DisableControlAction(0, 0, true) -- Disable changing view + DisableControlAction(0, 26, true) -- Disable looking behind + DisableControlAction(0, 73, true) -- Disable clearing animation + DisableControlAction(2, 199, true) -- Disable pause screen + + DisableControlAction(0, 59, true) -- Disable steering in vehicle + DisableControlAction(0, 71, true) -- Disable driving forward in vehicle + DisableControlAction(0, 72, true) -- Disable reversing in vehicle + + DisableControlAction(2, 36, true) -- Disable going stealth + + DisableControlAction(0, 47, true) -- Disable weapon + DisableControlAction(0, 264, true) -- Disable melee + DisableControlAction(0, 257, true) -- Disable melee + DisableControlAction(0, 140, true) -- Disable melee + DisableControlAction(0, 141, true) -- Disable melee + DisableControlAction(0, 142, true) -- Disable melee + DisableControlAction(0, 143, true) -- Disable melee + DisableControlAction(0, 75, true) -- Disable exit vehicle + DisableControlAction(27, 75, true) -- Disable exit vehicle + + if IsEntityPlayingAnim(ESX.PlayerData.ped, "mp_arresting", "idle", 3) ~= 1 then + ESX.Streaming.RequestAnimDict("mp_arresting", function() + TaskPlayAnim(ESX.PlayerData.ped, "mp_arresting", "idle", 8.0, -8, -1, 49, 0.0, false, false, false) + RemoveAnimDict("mp_arresting") + end) + end + end + Wait(Sleep) + end end) -- Create blips CreateThread(function() - for _, v in pairs(Config.PoliceStations) do - local blip = AddBlipForCoord(v.Blip.Coords) - - SetBlipSprite(blip, v.Blip.Sprite) - SetBlipDisplay(blip, v.Blip.Display) - SetBlipScale(blip, v.Blip.Scale) - SetBlipColour(blip, v.Blip.Colour) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("map_blip")) - EndTextCommandSetBlipName(blip) - end + for _, v in pairs(Config.PoliceStations) do + local blip = AddBlipForCoord(v.Blip.Coords) + + SetBlipSprite(blip, v.Blip.Sprite) + SetBlipDisplay(blip, v.Blip.Display) + SetBlipScale(blip, v.Blip.Scale) + SetBlipColour(blip, v.Blip.Colour) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("map_blip")) + EndTextCommandSetBlipName(blip) + end end) -- Draw markers and more CreateThread(function() - while true do - local Sleep = 1500 - if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" then - Sleep = 500 - local playerPed = PlayerPedId() - local playerCoords = GetEntityCoords(playerPed) - local isInMarker, hasExited = false, false - local currentStation, currentPart, currentPartNum - - for k, v in pairs(Config.PoliceStations) do - for i = 1, #v.Cloakrooms, 1 do - local distance = #(playerCoords - v.Cloakrooms[i]) - - if distance < Config.DrawDistance then - DrawMarker( - Config.MarkerType.Cloakrooms, - v.Cloakrooms[i], - 0.0, - 0.0, - 0.0, - 0, - 0.0, - 0.0, - 1.0, - 1.0, - 1.0, - Config.MarkerColor.r, - Config.MarkerColor.g, - Config.MarkerColor.b, - 100, - false, - true, - 2, - true, - false, - false, - false - ) - Sleep = 0 - - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, "Cloakroom", i - end - end - end - - for i = 1, #v.Armories, 1 do - local distance = #(playerCoords - v.Armories[i]) - - if distance < Config.DrawDistance then - DrawMarker( - Config.MarkerType.Armories, - v.Armories[i], - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.5, - 0.5, - 0.5, - Config.MarkerColor.r, - Config.MarkerColor.g, - Config.MarkerColor.b, - 100, - false, - true, - 2, - true, - false, - false, - false - ) - Sleep = 0 - - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, "Armory", i - end - end - end - - for i = 1, #v.Vehicles, 1 do - local distance = #(playerCoords - v.Vehicles[i].Spawner) - - if distance < Config.DrawDistance then - DrawMarker( - Config.MarkerType.Vehicles, - v.Vehicles[i].Spawner, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 1.0, - 1.0, - Config.MarkerColor.r, - Config.MarkerColor.g, - Config.MarkerColor.b, - 100, - false, - true, - 2, - true, - false, - false, - false - ) - Sleep = 0 - - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, "Vehicles", i - end - end - end - - for i = 1, #v.Helicopters, 1 do - local distance = #(playerCoords - v.Helicopters[i].Spawner) - - if distance < Config.DrawDistance then - DrawMarker( - Config.MarkerType.Helicopters, - v.Helicopters[i].Spawner, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 1.0, - 1.0, - Config.MarkerColor.r, - Config.MarkerColor.g, - Config.MarkerColor.b, - 100, - false, - true, - 2, - true, - false, - false, - false - ) - Sleep = 0 - - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, "Helicopters", i - end - end - end - - if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == "boss" then - for i = 1, #v.BossActions, 1 do - local distance = #(playerCoords - v.BossActions[i]) - - if distance < Config.DrawDistance then - DrawMarker( - Config.MarkerType.BossActions, - v.BossActions[i], - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 1.0, - 1.0, - 1.0, - Config.MarkerColor.r, - Config.MarkerColor.g, - Config.MarkerColor.b, - 100, - false, - true, - 2, - true, - false, - false, - false - ) - Sleep = 0 - - if distance < Config.MarkerSize.x then - isInMarker, currentStation, currentPart, currentPartNum = true, k, "BossActions", i - end - end - end - end - end - - if - isInMarker and not HasAlreadyEnteredMarker - or ( - isInMarker - and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum) - ) - then - if - (LastStation and LastPart and LastPartNum) - and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum) - then - TriggerEvent("esx_policejob:hasExitedMarker", LastStation, LastPart, LastPartNum) - hasExited = true - end - - HasAlreadyEnteredMarker = true - LastStation = currentStation - LastPart = currentPart - LastPartNum = currentPartNum - - TriggerEvent("esx_policejob:hasEnteredMarker", currentStation, currentPart, currentPartNum) - end - - if not hasExited and not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - TriggerEvent("esx_policejob:hasExitedMarker", LastStation, LastPart, LastPartNum) - end - end - Wait(Sleep) - end + while true do + local Sleep = 1500 + if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" then + Sleep = 500 + local playerPed = PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) + local isInMarker, hasExited = false, false + local currentStation, currentPart, currentPartNum + + for k, v in pairs(Config.PoliceStations) do + for i = 1, #v.Cloakrooms, 1 do + local distance = #(playerCoords - v.Cloakrooms[i]) + + if distance < Config.DrawDistance then + DrawMarker(Config.MarkerType.Cloakrooms, v.Cloakrooms[i], 0.0, 0.0, 0.0, 0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) + Sleep = 0 + + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, "Cloakroom", i + end + end + end + + for i = 1, #v.Armories, 1 do + local distance = #(playerCoords - v.Armories[i]) + + if distance < Config.DrawDistance then + DrawMarker(Config.MarkerType.Armories, v.Armories[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) + Sleep = 0 + + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, "Armory", i + end + end + end + + for i = 1, #v.Vehicles, 1 do + local distance = #(playerCoords - v.Vehicles[i].Spawner) + + if distance < Config.DrawDistance then + DrawMarker(Config.MarkerType.Vehicles, v.Vehicles[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) + Sleep = 0 + + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, "Vehicles", i + end + end + end + + for i = 1, #v.Helicopters, 1 do + local distance = #(playerCoords - v.Helicopters[i].Spawner) + + if distance < Config.DrawDistance then + DrawMarker(Config.MarkerType.Helicopters, v.Helicopters[i].Spawner, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) + Sleep = 0 + + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, "Helicopters", i + end + end + end + + if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == "boss" then + for i = 1, #v.BossActions, 1 do + local distance = #(playerCoords - v.BossActions[i]) + + if distance < Config.DrawDistance then + DrawMarker(Config.MarkerType.BossActions, v.BossActions[i], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, true, false, false, false) + Sleep = 0 + + if distance < Config.MarkerSize.x then + isInMarker, currentStation, currentPart, currentPartNum = true, k, "BossActions", i + end + end + end + end + end + + if isInMarker and not HasAlreadyEnteredMarker or (isInMarker and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum)) then + if (LastStation and LastPart and LastPartNum) and (LastStation ~= currentStation or LastPart ~= currentPart or LastPartNum ~= currentPartNum) then + TriggerEvent("esx_policejob:hasExitedMarker", LastStation, LastPart, LastPartNum) + hasExited = true + end + + HasAlreadyEnteredMarker = true + LastStation = currentStation + LastPart = currentPart + LastPartNum = currentPartNum + + TriggerEvent("esx_policejob:hasEnteredMarker", currentStation, currentPart, currentPartNum) + end + + if not hasExited and not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + TriggerEvent("esx_policejob:hasExitedMarker", LastStation, LastPart, LastPartNum) + end + end + Wait(Sleep) + end end) -- Enter / Exit entity zone events CreateThread(function() - local trackedEntities = { - `prop_roadcone02a`, - `prop_barrier_work05`, - `p_ld_stinger_s`, - `prop_boxpile_07d`, - `hei_prop_cash_crate_half_full`, - } - - while true do - local Sleep = 1500 - - local GetEntityCoords = GetEntityCoords - local GetClosestObjectOfType = GetClosestObjectOfType - local DoesEntityExist = DoesEntityExist - local playerCoords = GetEntityCoords(ESX.PlayerData.ped) - - local closestDistance = -1 - local closestEntity = nil - - for i = 1, #trackedEntities, 1 do - local object = GetClosestObjectOfType(playerCoords, 3.0, trackedEntities[i], false, false, false) - - if DoesEntityExist(object) then - Sleep = 500 - local objCoords = GetEntityCoords(object) - local distance = #(playerCoords - objCoords) - - if closestDistance == -1 or closestDistance > distance then - closestDistance = distance - closestEntity = object - end - end - end - - if closestDistance ~= -1 and closestDistance <= 3.0 then - if LastEntity ~= closestEntity then - TriggerEvent("esx_policejob:hasEnteredEntityZone", closestEntity) - LastEntity = closestEntity - end - else - if LastEntity then - TriggerEvent("esx_policejob:hasExitedEntityZone", LastEntity) - LastEntity = nil - end - end - Wait(Sleep) - end + local trackedEntities = { + `prop_roadcone02a`, + `prop_barrier_work05`, + `p_ld_stinger_s`, + `prop_boxpile_07d`, + `hei_prop_cash_crate_half_full`, + } + + while true do + local Sleep = 1500 + + local GetEntityCoords = GetEntityCoords + local GetClosestObjectOfType = GetClosestObjectOfType + local DoesEntityExist = DoesEntityExist + local playerCoords = GetEntityCoords(ESX.PlayerData.ped) + + local closestDistance = -1 + local closestEntity = nil + + for i = 1, #trackedEntities, 1 do + local object = GetClosestObjectOfType(playerCoords, 3.0, trackedEntities[i], false, false, false) + + if DoesEntityExist(object) then + Sleep = 500 + local objCoords = GetEntityCoords(object) + local distance = #(playerCoords - objCoords) + + if closestDistance == -1 or closestDistance > distance then + closestDistance = distance + closestEntity = object + end + end + end + + if closestDistance ~= -1 and closestDistance <= 3.0 then + if LastEntity ~= closestEntity then + TriggerEvent("esx_policejob:hasEnteredEntityZone", closestEntity) + LastEntity = closestEntity + end + else + if LastEntity then + TriggerEvent("esx_policejob:hasExitedEntityZone", LastEntity) + LastEntity = nil + end + end + Wait(Sleep) + end end) ESX.RegisterInput("police:interact", "(ESX PoliceJob) " .. TranslateCap("interaction"), "keyboard", "E", function() - if not CurrentAction then - return - end - - if CurrentAction == "menu_cloakroom" then - OpenCloakroomMenu() - elseif CurrentAction == "menu_armory" then - if not Config.EnableESXService then - OpenArmoryMenu(CurrentActionData.station) - elseif playerInService then - OpenArmoryMenu(CurrentActionData.station) - else - ESX.ShowNotification(TranslateCap("service_not")) - end - elseif CurrentAction == "menu_vehicle_spawner" then - if not Config.EnableESXService then - OpenVehicleSpawnerMenu("car", CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) - elseif playerInService then - OpenVehicleSpawnerMenu("car", CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) - else - ESX.ShowNotification(TranslateCap("service_not")) - end - elseif CurrentAction == "Helicopters" then - if not Config.EnableESXService then - OpenVehicleSpawnerMenu( - "helicopter", - CurrentActionData.station, - CurrentActionData.part, - CurrentActionData.partNum - ) - elseif playerInService then - OpenVehicleSpawnerMenu( - "helicopter", - CurrentActionData.station, - CurrentActionData.part, - CurrentActionData.partNum - ) - else - ESX.ShowNotification(TranslateCap("service_not")) - end - elseif CurrentAction == "delete_vehicle" then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - elseif CurrentAction == "menu_boss_actions" then - ESX.CloseContext() - TriggerEvent("esx_society:openBossMenu", "police", function(data, menu) - ESX.CloseContext() - - CurrentAction = "menu_boss_actions" - CurrentActionMsg = TranslateCap("open_bossmenu") - CurrentActionData = {} - end, { wash = false }) -- disable washing money - elseif CurrentAction == "remove_entity" then - DeleteEntity(CurrentActionData.entity) - end - - if not ESX.PlayerData.job or (ESX.PlayerData.job and not ESX.PlayerData.job.name == "police") then - return - end - - CurrentAction = nil + if not CurrentAction then + return + end + + if CurrentAction == "menu_cloakroom" then + OpenCloakroomMenu() + elseif CurrentAction == "menu_armory" then + if not Config.EnableESXService then + OpenArmoryMenu(CurrentActionData.station) + elseif playerInService then + OpenArmoryMenu(CurrentActionData.station) + else + ESX.ShowNotification(TranslateCap("service_not")) + end + elseif CurrentAction == "menu_vehicle_spawner" then + if not Config.EnableESXService then + OpenVehicleSpawnerMenu("car", CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) + elseif playerInService then + OpenVehicleSpawnerMenu("car", CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) + else + ESX.ShowNotification(TranslateCap("service_not")) + end + elseif CurrentAction == "Helicopters" then + if not Config.EnableESXService then + OpenVehicleSpawnerMenu("helicopter", CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) + elseif playerInService then + OpenVehicleSpawnerMenu("helicopter", CurrentActionData.station, CurrentActionData.part, CurrentActionData.partNum) + else + ESX.ShowNotification(TranslateCap("service_not")) + end + elseif CurrentAction == "delete_vehicle" then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + elseif CurrentAction == "menu_boss_actions" then + ESX.CloseContext() + TriggerEvent("esx_society:openBossMenu", "police", function(data, menu) + ESX.CloseContext() + + CurrentAction = "menu_boss_actions" + CurrentActionMsg = TranslateCap("open_bossmenu") + CurrentActionData = {} + end, { wash = false }) -- disable washing money + elseif CurrentAction == "remove_entity" then + DeleteEntity(CurrentActionData.entity) + end + + if not ESX.PlayerData.job or (ESX.PlayerData.job and not ESX.PlayerData.job.name == "police") then + return + end + + CurrentAction = nil end) -ESX.RegisterInput( - "police:quickactions", - "(ESX PoliceJob) " .. TranslateCap("quick_actions"), - "keyboard", - "F6", - function() - if not ESX.PlayerData.job or (ESX.PlayerData.job.name ~= "police") or isDead then - return - end - - if not Config.EnableESXService then - OpenPoliceActionsMenu() - elseif playerInService then - OpenPoliceActionsMenu() - else - ESX.ShowNotification(TranslateCap("service_not")) - end - end -) +ESX.RegisterInput("police:quickactions", "(ESX PoliceJob) " .. TranslateCap("quick_actions"), "keyboard", "F6", function() + if not ESX.PlayerData.job or (ESX.PlayerData.job.name ~= "police") or isDead then + return + end + + if not Config.EnableESXService then + OpenPoliceActionsMenu() + elseif playerInService then + OpenPoliceActionsMenu() + else + ESX.ShowNotification(TranslateCap("service_not")) + end +end) CreateThread(function() - while true do - local Sleep = 1000 - - if CurrentAction then - Sleep = 0 - ESX.ShowHelpNotification(CurrentActionMsg) - end - Wait(Sleep) - end + while true do + local Sleep = 1000 + + if CurrentAction then + Sleep = 0 + ESX.ShowHelpNotification(CurrentActionMsg) + end + Wait(Sleep) + end end) -- Create blip for colleagues function createBlip(id) - local ped = GetPlayerPed(id) - local blip = GetBlipFromEntity(ped) - - if not DoesBlipExist(blip) then -- Add blip and create head display on player - blip = AddBlipForEntity(ped) - SetBlipSprite(blip, 1) - ShowHeadingIndicatorOnBlip(blip, true) -- Player Blip indicator - SetBlipRotation(blip, math.ceil(GetEntityHeading(ped))) -- update rotation - SetBlipNameToPlayerName(blip, id) -- update blip name - SetBlipScale(blip, 0.85) -- set scale - SetBlipAsShortRange(blip, true) - - table.insert(blipsCops, blip) -- add blip to array so we can remove it later - end + local ped = GetPlayerPed(id) + local blip = GetBlipFromEntity(ped) + + if not DoesBlipExist(blip) then -- Add blip and create head display on player + blip = AddBlipForEntity(ped) + SetBlipSprite(blip, 1) + ShowHeadingIndicatorOnBlip(blip, true) -- Player Blip indicator + SetBlipRotation(blip, math.ceil(GetEntityHeading(ped))) -- update rotation + SetBlipNameToPlayerName(blip, id) -- update blip name + SetBlipScale(blip, 0.85) -- set scale + SetBlipAsShortRange(blip, true) + + table.insert(blipsCops, blip) -- add blip to array so we can remove it later + end end RegisterNetEvent("esx_policejob:updateBlip") AddEventHandler("esx_policejob:updateBlip", function() - -- Refresh all blips - for _, existingBlip in pairs(blipsCops) do - RemoveBlip(existingBlip) - end - - -- Clean the blip table - blipsCops = {} - - -- Enable blip? - if Config.EnableESXService and not playerInService then - return - end - - if not Config.EnableJobBlip then - return - end - - -- Is the player a cop? In that case show all the blips for other cops - if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" then - ESX.TriggerServerCallback("esx_society:getOnlinePlayers", function(players) - for i = 1, #players, 1 do - if players[i].job.name == "police" then - local id = GetPlayerFromServerId(players[i].source) - if NetworkIsPlayerActive(id) and GetPlayerPed(id) ~= PlayerPedId() then - createBlip(id) - end - end - end - end) - end + -- Refresh all blips + for _, existingBlip in pairs(blipsCops) do + RemoveBlip(existingBlip) + end + + -- Clean the blip table + blipsCops = {} + + -- Enable blip? + if Config.EnableESXService and not playerInService then + return + end + + if not Config.EnableJobBlip then + return + end + + -- Is the player a cop? In that case show all the blips for other cops + if ESX.PlayerData.job and ESX.PlayerData.job.name == "police" then + ESX.TriggerServerCallback("esx_society:getOnlinePlayers", function(players) + for i = 1, #players, 1 do + if players[i].job.name == "police" then + local id = GetPlayerFromServerId(players[i].source) + if NetworkIsPlayerActive(id) and GetPlayerPed(id) ~= PlayerPedId() then + createBlip(id) + end + end + end + end) + end end) AddEventHandler("esx:onPlayerSpawn", function(spawn) - isDead = false - TriggerEvent("esx_policejob:unrestrain") + isDead = false + TriggerEvent("esx_policejob:unrestrain") - if not hasAlreadyJoined then - TriggerServerEvent("esx_policejob:spawned") - end - hasAlreadyJoined = true + if not hasAlreadyJoined then + TriggerServerEvent("esx_policejob:spawned") + end + hasAlreadyJoined = true end) AddEventHandler("esx:onPlayerDeath", function(data) - isDead = true + isDead = true end) AddEventHandler("onResourceStop", function(resource) - if resource == GetCurrentResourceName() then - TriggerEvent("esx_policejob:unrestrain") - TriggerEvent("esx_phone:removeSpecialContact", "police") - - if Config.EnableESXService then - TriggerServerEvent("esx_service:disableService", "police") - end - - if Config.EnableHandcuffTimer and handcuffTimer.active then - ESX.ClearTimeout(handcuffTimer.task) - end - end + if resource == GetCurrentResourceName() then + TriggerEvent("esx_policejob:unrestrain") + TriggerEvent("esx_phone:removeSpecialContact", "police") + + if Config.EnableESXService then + TriggerServerEvent("esx_service:disableService", "police") + end + + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + end end) -- handcuff timer, unrestrain the player after an certain amount of time function StartHandcuffTimer() - if Config.EnableHandcuffTimer and handcuffTimer.active then - ESX.ClearTimeout(handcuffTimer.task) - end + if Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end - handcuffTimer.active = true + handcuffTimer.active = true - handcuffTimer.task = ESX.SetTimeout(Config.HandcuffTimer, function() - ESX.ShowNotification(TranslateCap("unrestrained_timer")) - TriggerEvent("esx_policejob:unrestrain") - handcuffTimer.active = false - end) + handcuffTimer.task = ESX.SetTimeout(Config.HandcuffTimer, function() + ESX.ShowNotification(TranslateCap("unrestrained_timer")) + TriggerEvent("esx_policejob:unrestrain") + handcuffTimer.active = false + end) end -- TODO -- - return to garage if owned -- - message owner that his vehicle has been impounded function ImpoundVehicle(vehicle) - ESX.Game.DeleteVehicle(vehicle) - ESX.ShowNotification(TranslateCap("impound_successful")) - currentTask.busy = false + ESX.Game.DeleteVehicle(vehicle) + ESX.ShowNotification(TranslateCap("impound_successful")) + currentTask.busy = false end if ESX.PlayerLoaded and ESX.PlayerData.job == "police" then - SetTimeout(1000, function() - TriggerServerEvent("esx_policejob:forceBlip") - end) + SetTimeout(1000, function() + TriggerServerEvent("esx_policejob:forceBlip") + end) end diff --git a/server-data/resources/[esx_addons]/esx_policejob/fxmanifest.lua b/server-data/resources/[esx_addons]/esx_policejob/fxmanifest.lua index bc56d6a6b..f399db01c 100644 --- a/server-data/resources/[esx_addons]/esx_policejob/fxmanifest.lua +++ b/server-data/resources/[esx_addons]/esx_policejob/fxmanifest.lua @@ -25,6 +25,6 @@ client_scripts { dependencies { 'es_extended', - 'esx_billing', + 'bpt_billing', 'esx_vehicleshop' } diff --git a/server-data/resources/[esx_addons]/esx_vehicleshop/README.md b/server-data/resources/[esx_addons]/esx_vehicleshop/README.md index 121be8cf8..4597dc5be 100644 --- a/server-data/resources/[esx_addons]/esx_vehicleshop/README.md +++ b/server-data/resources/[esx_addons]/esx_vehicleshop/README.md @@ -9,7 +9,6 @@ ESX Vehicle Shop adds an vehicle shop to the game, where employeed players can s * Player management (the car dealer job): billing, boss actions and more! * [esx_society] - * [esx_billing] * [cron] ### Installation diff --git a/server-data/resources/[esx_addons]/esx_vehicleshop/client/main.lua b/server-data/resources/[esx_addons]/esx_vehicleshop/client/main.lua index 10f424736..62059119d 100644 --- a/server-data/resources/[esx_addons]/esx_vehicleshop/client/main.lua +++ b/server-data/resources/[esx_addons]/esx_vehicleshop/client/main.lua @@ -1,19 +1,9 @@ local Config = Config local HasAlreadyEnteredMarker, IsInShopMenu = false, false local CurrentAction, CurrentActionMsg, LastZone, currentDisplayVehicle, CurrentVehicleData -local CurrentActionData, Vehicles, Categories, VehiclesByModel, vehiclesByCategory, soldVehicles, cardealerVehicles, rentedVehicles = - {}, {}, {}, {}, {}, {}, {}, {} +local CurrentActionData, Vehicles, Categories, VehiclesByModel, vehiclesByCategory, soldVehicles, cardealerVehicles, rentedVehicles = {}, {}, {}, {}, {}, {}, {}, {} local DoesEntityExist, NetworkRequestControlOfEntity, NetworkHasControlOfEntity, DisableControlAction, HasModelLoaded, RequestModel, DisableAllControlActions, FreezeEntityPosition, SetEntityCoords, SetEntityVisible = - DoesEntityExist, - NetworkRequestControlOfEntity, - NetworkHasControlOfEntity, - DisableControlAction, - HasModelLoaded, - RequestModel, - DisableAllControlActions, - FreezeEntityPosition, - SetEntityCoords, - SetEntityVisible + DoesEntityExist, NetworkRequestControlOfEntity, NetworkHasControlOfEntity, DisableControlAction, HasModelLoaded, RequestModel, DisableAllControlActions, FreezeEntityPosition, SetEntityCoords, SetEntityVisible Vehicles = GlobalState.vehicleShop.vehicles Categories = GlobalState.vehicleShop.categories @@ -23,954 +13,858 @@ cardealerVehicles = GlobalState.vehicleShop.cardealerVehicles rentedVehicles = GlobalState.vehicleShop.rentedVehicles AddStateBagChangeHandler("vehicleShop", "global", function(bagName, key, value) - Vehicles = value.vehicles - Categories = value.categories - VehiclesByModel = value.vehiclesByModel - soldVehicles = value.soldVehicles - cardealerVehicles = value.cardealerVehicles - rentedVehicles = value.rentedVehicles + Vehicles = value.vehicles + Categories = value.categories + VehiclesByModel = value.vehiclesByModel + soldVehicles = value.soldVehicles + cardealerVehicles = value.cardealerVehicles + rentedVehicles = value.rentedVehicles end) CreateThread(function() - while true do - Wait(60000) - collectgarbage("collect") - end + while true do + Wait(60000) + collectgarbage("collect") + end end) local function getVehicleFromModel(model) - return VehiclesByModel[model] + return VehiclesByModel[model] end local function Init() - TriggerEvent("esx_vehicleshop:updateTables") - - Wait(500) - - table.sort(Vehicles, function(a, b) - return a.name < b.name - end) - - for i = 1, #Vehicles, 1 do - local vehicle = Vehicles[i] - if IsModelInCdimage(joaat(vehicle.model)) then - local category = vehicle.category - - if not vehiclesByCategory[category] then - vehiclesByCategory[category] = {} - end - - table.insert(vehiclesByCategory[category], vehicle) - else - print(("[^3WARNING^7] Ignoring vehicle ^5%s^7 due to invalid Model"):format(vehicle.model)) - end - end - - if Config.EnablePlayerManagement then - RegisterNetEvent("esx_phone:loaded") - AddEventHandler("esx_phone:loaded", function(phoneNumber, contacts) - local specialContact = { - name = TranslateCap("dealership"), - number = "cardealer", - base64Icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAADMzMzszM0M0M0w0M1Q1M101M2U2M242M3Y3M383Moc4MpA4Mpg5MqE5Mqk6MrI6Mro7Mrw8Mr89M71DML5EO8I+NMU/NcBMLshANctBNs5CN8RULMddKsheKs9YLtBCONZEOdlFOtxGO99HPNhMNsplKM1nKM1uJtRhLddiLt5kMNJwJ9B2JNR/IeNIPeVJPehKPuRQOuhSO+lZOOlhNuloM+p3Lep/KupwMMFORsVYUcplXc1waNJ7delUSepgVexrYe12bdeHH9iIH9qQHd2YG+udH+OEJeuGJ+uOJeuVIuChGeSpF+aqGOykHOysGeeyFeuzFuyzFuq6E+27FO+Cee3CEdaGgdqTjvCNhfKYkvOkngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJezdycAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAQGElEQVR4Xt2d+WMUtxXHbS6bEGMPMcQQ04aEUnqYo9xJWvC6kAKmQLM2rdn//9+g0uir2Tl0PElPszP7+cnH7Fj6rPTeG2lmvfKld2azk8lk/36L/cnkZDbDIT3Sp4DZ8QS9dTI57tNDTwJOOu+4j/0TvDQz+QXMSG+7mUn+sZBZQELnNROcKhMZBXx+gS4k8+IzTpmBXAJOnqPxTDzPFRKyCODuvSKPgwwC2EZ+lxf4E4xwCzhBU7PBPQx4BWR88+fwDgNGAbMsM9/Ec8bygE3A5966L3nOlhiZBGSf+l2YggGLgBna1DMsE4FBQH9zvw1HLEgX0Evkt5GeEVIFMFztpJF6rZQm4DNasVDSEkKSgIVN/ibP0ZwoEgQsfPTPSZgH8QIG8vYr4gdBrIABvf2K2EEQKWBQb78ichBECRhE8O8SlQ5iBAQvcffFPhoYQoSAAQ5/TcQ0CBYw0OGvCZ4GoQIGF/3bhGaDQAELvfKhERgIwgQMePrPCQsEQQLwFwYPmksiQMCC1n1iCFgooQtYwLJfPPQFQ7KAUfU/wABVwMj6TzdAFDDY6tcOMR3SBIyw/1QDJAGj7D/RAEXA6Oa/hhIHCAJG23+SAb+AEfefYsArYET1nwlvTegVgBONFnTDik8ATjNi0BEbHgGjuP5147k6dgsYaQHQxF0OOAUMfv2LhnOVzCVg4OufdFwrpS4BePkSgA6ZcAhYggCocQRCu4ClCIAaeyC0CliaAKCwhgGrALxwaUC3OtgELFEAUNjCgEXAklQAdSzVgEUAXrRUoGstzAKWbgJIzJPAKGAJJ4DEOAmMAvCCpQPda2ASsJQTQGKa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", - } - - TriggerEvent( - "esx_phone:addSpecialContact", - specialContact.name, - specialContact.number, - specialContact.base64Icon - ) - end) - end - - if Config.Blip.show then - CreateThread(function() - local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos) - - SetBlipSprite(blip, Config.Blip.Sprite) - SetBlipDisplay(blip, Config.Blip.Display) - SetBlipScale(blip, Config.Blip.Scale) - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("car_dealer")) - EndTextCommandSetBlipName(blip) - end) - end - - return true + TriggerEvent("esx_vehicleshop:updateTables") + + Wait(500) + + table.sort(Vehicles, function(a, b) + return a.name < b.name + end) + + for i = 1, #Vehicles, 1 do + local vehicle = Vehicles[i] + if IsModelInCdimage(joaat(vehicle.model)) then + local category = vehicle.category + + if not vehiclesByCategory[category] then + vehiclesByCategory[category] = {} + end + + table.insert(vehiclesByCategory[category], vehicle) + else + print(("[^3WARNING^7] Ignoring vehicle ^5%s^7 due to invalid Model"):format(vehicle.model)) + end + end + + if Config.EnablePlayerManagement then + RegisterNetEvent("esx_phone:loaded") + AddEventHandler("esx_phone:loaded", function(phoneNumber, contacts) + local specialContact = { + name = TranslateCap("dealership"), + number = "cardealer", + base64Icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAADMzMzszM0M0M0w0M1Q1M101M2U2M242M3Y3M383Moc4MpA4Mpg5MqE5Mqk6MrI6Mro7Mrw8Mr89M71DML5EO8I+NMU/NcBMLshANctBNs5CN8RULMddKsheKs9YLtBCONZEOdlFOtxGO99HPNhMNsplKM1nKM1uJtRhLddiLt5kMNJwJ9B2JNR/IeNIPeVJPehKPuRQOuhSO+lZOOlhNuloM+p3Lep/KupwMMFORsVYUcplXc1waNJ7delUSepgVexrYe12bdeHH9iIH9qQHd2YG+udH+OEJeuGJ+uOJeuVIuChGeSpF+aqGOykHOysGeeyFeuzFuyzFuq6E+27FO+Cee3CEdaGgdqTjvCNhfKYkvOkngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJezdycAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjb9TgnoAAAQGElEQVR4Xt2d+WMUtxXHbS6bEGMPMcQQ04aEUnqYo9xJWvC6kAKmQLM2rdn//9+g0uir2Tl0PElPszP7+cnH7Fj6rPTeG2lmvfKld2azk8lk/36L/cnkZDbDIT3Sp4DZ8QS9dTI57tNDTwJOOu+4j/0TvDQz+QXMSG+7mUn+sZBZQELnNROcKhMZBXx+gS4k8+IzTpmBXAJOnqPxTDzPFRKyCODuvSKPgwwC2EZ+lxf4E4xwCzhBU7PBPQx4BWR88+fwDgNGAbMsM9/Ec8bygE3A5966L3nOlhiZBGSf+l2YggGLgBna1DMsE4FBQH9zvw1HLEgX0Evkt5GeEVIFMFztpJF6rZQm4DNasVDSEkKSgIVN/ibP0ZwoEgQsfPTPSZgH8QIG8vYr4gdBrIABvf2K2EEQKWBQb78ichBECRhE8O8SlQ5iBAQvcffFPhoYQoSAAQ5/TcQ0CBYw0OGvCZ4GoQIGF/3bhGaDQAELvfKhERgIwgQMePrPCQsEQQLwFwYPmksiQMCC1n1iCFgooQtYwLJfPPQFQ7KAUfU/wABVwMj6TzdAFDDY6tcOMR3SBIyw/1QDJAGj7D/RAEXA6Oa/hhIHCAJG23+SAb+AEfefYsArYET1nwlvTegVgBONFnTDik8ATjNi0BEbHgGjuP5147k6dgsYaQHQxF0OOAUMfv2LhnOVzCVg4OufdFwrpS4BePkSgA6ZcAhYggCocQRCu4ClCIAaeyC0CliaAKCwhgGrALxwaUC3OtgELFEAUNjCgEXAklQAdSzVgEUAXrRUoGstzAKWbgJIzJPAKGAJJ4DEOAmMAvCCpQPda2ASsJQTQGKa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", + } + + TriggerEvent("esx_phone:addSpecialContact", specialContact.name, specialContact.number, specialContact.base64Icon) + end) + end + + if Config.Blip.show then + CreateThread(function() + local blip = AddBlipForCoord(Config.Zones.ShopEntering.Pos) + + SetBlipSprite(blip, Config.Blip.Sprite) + SetBlipDisplay(blip, Config.Blip.Display) + SetBlipScale(blip, Config.Blip.Scale) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("car_dealer")) + EndTextCommandSetBlipName(blip) + end) + end + + return true end local function PlayerManagement() - if not Config.EnablePlayerManagement then - return true - end - - if LocalPlayer.state.job ~= "cardealer" then - Config.Zones.ShopEntering.Type = -1 - Config.Zones.BossActions.Type = -1 - Config.Zones.ResellVehicle.Type = -1 - return true - end - Config.Zones.ShopEntering.Type = 1 - - if LocalPlayer.state.job.grade_name == "boss" then - Config.Zones.BossActions.Type = 1 - end - return true + if not Config.EnablePlayerManagement then + return true + end + + if LocalPlayer.state.job ~= "cardealer" then + Config.Zones.ShopEntering.Type = -1 + Config.Zones.BossActions.Type = -1 + Config.Zones.ResellVehicle.Type = -1 + return true + end + Config.Zones.ShopEntering.Type = 1 + + if LocalPlayer.state.job.grade_name == "boss" then + Config.Zones.BossActions.Type = 1 + end + return true end local function loadIpl() - RequestIpl("shr_int") + RequestIpl("shr_int") - local interiorID = 7170 - PinInteriorInMemory(interiorID) - ActivateInteriorEntitySet(interiorID, "csr_beforeMission") - RefreshInterior(interiorID) + local interiorID = 7170 + PinInteriorInMemory(interiorID) + ActivateInteriorEntitySet(interiorID, "csr_beforeMission") + RefreshInterior(interiorID) end RegisterNetEvent("esx:playerLoaded") AddEventHandler("esx:playerLoaded", function(xPlayer) - Init() - PlayerManagement() - CreateThread(loadIpl) + Init() + PlayerManagement() + CreateThread(loadIpl) end) RegisterNetEvent("esx:setJob", PlayerManagement) local function DeleteDisplayVehicleInsideShop() - local attempt = 0 - - if currentDisplayVehicle and DoesEntityExist(currentDisplayVehicle) then - while - DoesEntityExist(currentDisplayVehicle) - and not NetworkHasControlOfEntity(currentDisplayVehicle) - and attempt < 100 - do - Wait(100) - NetworkRequestControlOfEntity(currentDisplayVehicle) - attempt = attempt + 1 - end - - if DoesEntityExist(currentDisplayVehicle) and NetworkHasControlOfEntity(currentDisplayVehicle) then - ESX.Game.DeleteVehicle(currentDisplayVehicle) - end - end + local attempt = 0 + + if currentDisplayVehicle and DoesEntityExist(currentDisplayVehicle) then + while DoesEntityExist(currentDisplayVehicle) and not NetworkHasControlOfEntity(currentDisplayVehicle) and attempt < 100 do + Wait(100) + NetworkRequestControlOfEntity(currentDisplayVehicle) + attempt = attempt + 1 + end + + if DoesEntityExist(currentDisplayVehicle) and NetworkHasControlOfEntity(currentDisplayVehicle) then + ESX.Game.DeleteVehicle(currentDisplayVehicle) + end + end end local function ReturnVehicleProvider() - local elements = { - { - unselectable = true, - icon = "fas fa-car", - title = TranslateCap("car_dealer"), - }, - } - - for k, v in ipairs(cardealerVehicles) do - local returnPrice = ESX.Math.Round(v.price * 0.75) - local vehicleLabel = getVehicleFromModel(v.vehicle).label - - TableInsert(elements, { - title = ('%s [%s]'):format( - vehicleLabel, - TranslateCap("generic_shopitem", ESX.Math.GroupDigits(returnPrice)) - ), - name = v.vehicle, - }) - end - - ESX.OpenContext("right", elements, function(menu, element) - if not element.name then - return ESX.CloseContext() - end - TriggerServerEvent("esx_vehicleshop:returnProvider", element.name) - Wait(500) - ESX.CloseContext() - ReturnVehicleProvider() - end, function(menu) end) + local elements = { + { + unselectable = true, + icon = "fas fa-car", + title = TranslateCap("car_dealer"), + }, + } + + for k, v in ipairs(cardealerVehicles) do + local returnPrice = ESX.Math.Round(v.price * 0.75) + local vehicleLabel = getVehicleFromModel(v.vehicle).label + + TableInsert(elements, { + title = ('%s [%s]'):format(vehicleLabel, TranslateCap("generic_shopitem", ESX.Math.GroupDigits(returnPrice))), + name = v.vehicle, + }) + end + + ESX.OpenContext("right", elements, function(menu, element) + if not element.name then + return ESX.CloseContext() + end + TriggerServerEvent("esx_vehicleshop:returnProvider", element.name) + Wait(500) + ESX.CloseContext() + ReturnVehicleProvider() + end, function(menu) end) end local function StartShopRestriction() - while IsInShopMenu do - Wait(0) + while IsInShopMenu do + Wait(0) - DisableControlAction(0, 75, true) -- Disable exit vehicle - DisableControlAction(27, 75, true) -- Disable exit vehicle - end + DisableControlAction(0, 75, true) -- Disable exit vehicle + DisableControlAction(27, 75, true) -- Disable exit vehicle + end end local function WaitForVehicleToLoad(modelHash) - modelHash = (type(modelHash) == "number" and modelHash or joaat(modelHash)) + modelHash = (type(modelHash) == "number" and modelHash or joaat(modelHash)) - if not HasModelLoaded(modelHash) then - RequestModel(modelHash) + if not HasModelLoaded(modelHash) then + RequestModel(modelHash) - BeginTextCommandBusyspinnerOn("STRING") - AddTextComponentSubstringPlayerName(TranslateCap("shop_awaiting_model")) - EndTextCommandBusyspinnerOn(4) + BeginTextCommandBusyspinnerOn("STRING") + AddTextComponentSubstringPlayerName(TranslateCap("shop_awaiting_model")) + EndTextCommandBusyspinnerOn(4) - while not HasModelLoaded(modelHash) do - Wait(0) - DisableAllControlActions(0) - end + while not HasModelLoaded(modelHash) do + Wait(0) + DisableAllControlActions(0) + end - BusyspinnerOff() - end + BusyspinnerOff() + end end local function OpenShopMenu() - if #Vehicles == 0 then - print("[^3ERROR^7] Vehicleshop has ^50^7 vehicles, please add some!") - return - end - - IsInShopMenu = true - - CreateThread(StartShopRestriction) - ESX.UI.Menu.CloseAll() - ESX.CloseContext() - - local playerPed = ESX.PlayerData.ped - - FreezeEntityPosition(playerPed, true) - SetEntityVisible(playerPed, false) - SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos) - - local elements = {} - local firstVehicleData = nil - - for i = 1, #Categories, 1 do - local category = Categories[i] - local categoryVehicles = vehiclesByCategory[category.name] - local options = {} - - for j = 1, #categoryVehicles, 1 do - local vehicle = categoryVehicles[j] - - if i == 1 and j == 1 then - firstVehicleData = vehicle - end - - TableInsert( - options, - ('%s %s'):format( - vehicle.name, - TranslateCap("generic_shopitem", ESX.Math.GroupDigits(vehicle.price)) - ) - ) - end - - table.sort(options) - - TableInsert(elements, { - name = category.name, - label = category.label, - value = 0, - type = "slider", - max = #Categories[i], - options = options, - }) - end - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "vehicle_shop", { - title = TranslateCap("car_dealer"), - align = "top-left", - elements = elements, - }, function(data, menu) - local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "shop_confirm", { - title = TranslateCap("buy_vehicle_shop", vehicleData.name, ESX.Math.GroupDigits(vehicleData.price)), - align = "top-left", - elements = { - { label = TranslateCap("no"), value = "no" }, - { label = TranslateCap("yes"), value = "yes" }, - }, - }, function(data2, menu2) - if data2.current.value == "yes" then - if Config.EnablePlayerManagement then - ESX.TriggerServerCallback("esx_vehicleshop:buyCarDealerVehicle", function(success) - if success then - IsInShopMenu = false - DeleteDisplayVehicleInsideShop() - - CurrentAction = "shop_menu" - CurrentActionMsg = TranslateCap("shop_menu") - CurrentActionData = {} - - local playerPed = ESX.PlayerData.ped - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) - - menu2.close() - menu.close() - ESX.ShowNotification(TranslateCap("vehicle_purchased")) - else - ESX.ShowNotification(TranslateCap("broke_company")) - end - end, vehicleData.model) - else - local generatedPlate = GeneratePlate() - - ESX.TriggerServerCallback("esx_vehicleshop:buyVehicle", function(success) - if success then - IsInShopMenu = false - menu2.close() - menu.close() - DeleteDisplayVehicleInsideShop() - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - else - ESX.ShowNotification(TranslateCap("not_enough_money")) - end - end, vehicleData.model, generatedPlate) - end - else - menu2.close() - end - end, function(data2, menu2) - menu2.close() - end) - end, function(data, menu) - menu.close() - DeleteDisplayVehicleInsideShop() - local playerPed = ESX.PlayerData.ped - - CurrentAction = "shop_menu" - CurrentActionMsg = TranslateCap("shop_menu") - CurrentActionData = {} - - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) - - IsInShopMenu = false - end, function(data, menu) - local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] - local playerPed = ESX.PlayerData.ped - - DeleteDisplayVehicleInsideShop() - WaitForVehicleToLoad(vehicleData.model) - - ESX.Game.SpawnLocalVehicle( - vehicleData.model, - Config.Zones.ShopInside.Pos, - Config.Zones.ShopInside.Heading, - function(vehicle) - currentDisplayVehicle = vehicle - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - SetModelAsNoLongerNeeded(vehicleData.model) - end - ) - end) - - DeleteDisplayVehicleInsideShop() - WaitForVehicleToLoad(firstVehicleData.model) - - ESX.Game.SpawnLocalVehicle( - firstVehicleData.model, - Config.Zones.ShopInside.Pos, - Config.Zones.ShopInside.Heading, - function(vehicle) - currentDisplayVehicle = vehicle - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - FreezeEntityPosition(vehicle, true) - SetModelAsNoLongerNeeded(firstVehicleData.model) - end - ) + if #Vehicles == 0 then + print("[^3ERROR^7] Vehicleshop has ^50^7 vehicles, please add some!") + return + end + + IsInShopMenu = true + + CreateThread(StartShopRestriction) + ESX.UI.Menu.CloseAll() + ESX.CloseContext() + + local playerPed = ESX.PlayerData.ped + + FreezeEntityPosition(playerPed, true) + SetEntityVisible(playerPed, false) + SetEntityCoords(playerPed, Config.Zones.ShopInside.Pos) + + local elements = {} + local firstVehicleData = nil + + for i = 1, #Categories, 1 do + local category = Categories[i] + local categoryVehicles = vehiclesByCategory[category.name] + local options = {} + + for j = 1, #categoryVehicles, 1 do + local vehicle = categoryVehicles[j] + + if i == 1 and j == 1 then + firstVehicleData = vehicle + end + + TableInsert(options, ('%s %s'):format(vehicle.name, TranslateCap("generic_shopitem", ESX.Math.GroupDigits(vehicle.price)))) + end + + table.sort(options) + + TableInsert(elements, { + name = category.name, + label = category.label, + value = 0, + type = "slider", + max = #Categories[i], + options = options, + }) + end + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "vehicle_shop", { + title = TranslateCap("car_dealer"), + align = "top-left", + elements = elements, + }, function(data, menu) + local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "shop_confirm", { + title = TranslateCap("buy_vehicle_shop", vehicleData.name, ESX.Math.GroupDigits(vehicleData.price)), + align = "top-left", + elements = { + { label = TranslateCap("no"), value = "no" }, + { label = TranslateCap("yes"), value = "yes" }, + }, + }, function(data2, menu2) + if data2.current.value == "yes" then + if Config.EnablePlayerManagement then + ESX.TriggerServerCallback("esx_vehicleshop:buyCarDealerVehicle", function(success) + if success then + IsInShopMenu = false + DeleteDisplayVehicleInsideShop() + + CurrentAction = "shop_menu" + CurrentActionMsg = TranslateCap("shop_menu") + CurrentActionData = {} + + local playerPed = ESX.PlayerData.ped + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) + + menu2.close() + menu.close() + ESX.ShowNotification(TranslateCap("vehicle_purchased")) + else + ESX.ShowNotification(TranslateCap("broke_company")) + end + end, vehicleData.model) + else + local generatedPlate = GeneratePlate() + + ESX.TriggerServerCallback("esx_vehicleshop:buyVehicle", function(success) + if success then + IsInShopMenu = false + menu2.close() + menu.close() + DeleteDisplayVehicleInsideShop() + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + else + ESX.ShowNotification(TranslateCap("not_enough_money")) + end + end, vehicleData.model, generatedPlate) + end + else + menu2.close() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + menu.close() + DeleteDisplayVehicleInsideShop() + local playerPed = ESX.PlayerData.ped + + CurrentAction = "shop_menu" + CurrentActionMsg = TranslateCap("shop_menu") + CurrentActionData = {} + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) + + IsInShopMenu = false + end, function(data, menu) + local vehicleData = vehiclesByCategory[data.current.name][data.current.value + 1] + local playerPed = ESX.PlayerData.ped + + DeleteDisplayVehicleInsideShop() + WaitForVehicleToLoad(vehicleData.model) + + ESX.Game.SpawnLocalVehicle(vehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) + currentDisplayVehicle = vehicle + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(vehicleData.model) + end) + end) + + DeleteDisplayVehicleInsideShop() + WaitForVehicleToLoad(firstVehicleData.model) + + ESX.Game.SpawnLocalVehicle(firstVehicleData.model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) + currentDisplayVehicle = vehicle + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + FreezeEntityPosition(vehicle, true) + SetModelAsNoLongerNeeded(firstVehicleData.model) + end) end function OpenResellerMenu() - ESX.UI.Menu.CloseAll() - ESX.CloseContext() - - local elements = { - { unselectable = true, icon = "fas fa-car", title = TranslateCap("car_dealer") }, - { title = TranslateCap("buy_vehicle"), name = "buy_vehicle" }, - { title = TranslateCap("pop_vehicle"), name = "pop_vehicle" }, - { title = TranslateCap("depop_vehicle"), name = "depop_vehicle" }, - { title = TranslateCap("return_provider"), name = "return_provider" }, - { title = TranslateCap("create_bill"), name = "create_bill" }, - { title = TranslateCap("get_rented_vehicles"), name = "get_rented_vehicles" }, - { title = TranslateCap("set_vehicle_owner_sell"), name = "set_vehicle_owner_sell" }, - { title = TranslateCap("set_vehicle_owner_rent"), name = "set_vehicle_owner_rent" }, - { title = TranslateCap("deposit_stock"), name = "put_stock" }, - { title = TranslateCap("take_stock"), name = "get_stock" }, - } - - ESX.OpenContext("right", elements, function(menu, element) - local action = element.name - - if Config.OxInventory and (action == "put_stock" or action == "get_stock") then - exports.ox_inventory:openInventory("stash", "society_cardealer") - elseif action == "buy_vehicle" then - OpenShopMenu() - elseif action == "put_stock" then - OpenPutStocksMenu() - elseif action == "get_stock" then - OpenGetStocksMenu() - elseif action == "pop_vehicle" then - OpenPopVehicleMenu() - elseif action == "depop_vehicle" then - if currentDisplayVehicle then - DeleteDisplayVehicleInsideShop() - else - ESX.ShowNotification(TranslateCap("no_current_vehicle")) - end - elseif action == "return_provider" then - ReturnVehicleProvider() - elseif action == "create_bill" then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer ~= -1 and closestDistance < 3 then - ESX.CloseContext() - ESX.OpenContext( - "right", - { - { - title = TranslateCap("invoice_amount"), - input = true, - inputType = "number", - inputValue = 0, - inputMin = 0, - name = "invoice_amount", - }, - }, - function(menu2, element2) - if element2.name == "invoice_amount" then - local amount = tonumber(element2.inputValue) - if amount ~= nil then - ESX.CloseContext() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(TranslateCap("no_players")) - else - TriggerServerEvent( - "esx_billing:sendBill", - GetPlayerServerId(closestPlayer), - "society_cardealer", - TranslateCap("car_dealer"), - amount - ) - end - end - end - end, - function(menu) end - ) - else - ESX.ShowNotification(TranslateCap("no_players")) - end - elseif action == "get_rented_vehicles" then - OpenRentedVehiclesMenu() - elseif action == "set_vehicle_owner_sell" then - if currentDisplayVehicle then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer ~= -1 and closestDistance < 3 then - local newPlate = GeneratePlate() - local vehicleProps = ESX.Game.GetVehicleProperties(currentDisplayVehicle) - vehicleProps.plate = newPlate - SetVehicleNumberPlateText(currentDisplayVehicle, newPlate) - TriggerServerEvent( - "esx_vehicleshop:setVehicleOwnedPlayerId", - GetPlayerServerId(closestPlayer), - vehicleProps, - CurrentVehicleData.model, - CurrentVehicleData.name - ) - currentDisplayVehicle = nil - else - ESX.ShowNotification(TranslateCap("no_players")) - end - else - ESX.ShowNotification(TranslateCap("no_current_vehicle")) - end - elseif action == "set_vehicle_owner_rent" then - if currentDisplayVehicle then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer ~= -1 and closestDistance < 3 then - ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "set_vehicle_owner_rent_amount", { - title = TranslateCap("rental_amount"), - }, function(data2, menu2) - local amount = tonumber(data2.value) - - if not amount then - ESX.ShowNotification(TranslateCap("invalid_amount")) - else - menu2.close() - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer ~= -1 and closestDistance < 3 then - local newPlate = "RENT" .. string.upper(ESX.GetRandomString(4)) - local model = CurrentVehicleData.model - SetVehicleNumberPlateText(currentDisplayVehicle, newPlate) - TriggerServerEvent( - "esx_vehicleshop:rentVehicle", - model, - newPlate, - amount, - GetPlayerServerId(closestPlayer) - ) - currentDisplayVehicle = nil - else - ESX.ShowNotification(TranslateCap("no_players")) - end - end - end, function(data2, menu2) - menu2.close() - end) - else - ESX.ShowNotification(TranslateCap("no_players")) - end - else - ESX.ShowNotification(TranslateCap("no_current_vehicle")) - end - end - end, function(menu) - CurrentAction = "reseller_menu" - CurrentActionMsg = TranslateCap("shop_menu") - CurrentActionData = {} - end) + ESX.UI.Menu.CloseAll() + ESX.CloseContext() + + local elements = { + { unselectable = true, icon = "fas fa-car", title = TranslateCap("car_dealer") }, + { title = TranslateCap("buy_vehicle"), name = "buy_vehicle" }, + { title = TranslateCap("pop_vehicle"), name = "pop_vehicle" }, + { title = TranslateCap("depop_vehicle"), name = "depop_vehicle" }, + { title = TranslateCap("return_provider"), name = "return_provider" }, + { title = TranslateCap("create_bill"), name = "create_bill" }, + { title = TranslateCap("get_rented_vehicles"), name = "get_rented_vehicles" }, + { title = TranslateCap("set_vehicle_owner_sell"), name = "set_vehicle_owner_sell" }, + { title = TranslateCap("set_vehicle_owner_rent"), name = "set_vehicle_owner_rent" }, + { title = TranslateCap("deposit_stock"), name = "put_stock" }, + { title = TranslateCap("take_stock"), name = "get_stock" }, + } + + ESX.OpenContext("right", elements, function(menu, element) + local action = element.name + + if Config.OxInventory and (action == "put_stock" or action == "get_stock") then + exports.ox_inventory:openInventory("stash", "society_cardealer") + elseif action == "buy_vehicle" then + OpenShopMenu() + elseif action == "put_stock" then + OpenPutStocksMenu() + elseif action == "get_stock" then + OpenGetStocksMenu() + elseif action == "pop_vehicle" then + OpenPopVehicleMenu() + elseif action == "depop_vehicle" then + if currentDisplayVehicle then + DeleteDisplayVehicleInsideShop() + else + ESX.ShowNotification(TranslateCap("no_current_vehicle")) + end + elseif action == "return_provider" then + ReturnVehicleProvider() + elseif action == "create_bill" then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer ~= -1 and closestDistance < 3 then + ESX.CloseContext() + ESX.OpenContext("right", { + { + title = TranslateCap("invoice_amount"), + input = true, + inputType = "number", + inputValue = 0, + inputMin = 0, + name = "invoice_amount", + }, + }, function(menu2, element2) + if element2.name == "invoice_amount" then + local amount = tonumber(element2.inputValue) + if amount ~= nil then + ESX.CloseContext() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(TranslateCap("no_players")) + else + TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(closestPlayer), "society_cardealer", TranslateCap("car_dealer"), amount) + end + end + end + end, function(menu) end) + else + ESX.ShowNotification(TranslateCap("no_players")) + end + elseif action == "get_rented_vehicles" then + OpenRentedVehiclesMenu() + elseif action == "set_vehicle_owner_sell" then + if currentDisplayVehicle then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer ~= -1 and closestDistance < 3 then + local newPlate = GeneratePlate() + local vehicleProps = ESX.Game.GetVehicleProperties(currentDisplayVehicle) + vehicleProps.plate = newPlate + SetVehicleNumberPlateText(currentDisplayVehicle, newPlate) + TriggerServerEvent("esx_vehicleshop:setVehicleOwnedPlayerId", GetPlayerServerId(closestPlayer), vehicleProps, CurrentVehicleData.model, CurrentVehicleData.name) + currentDisplayVehicle = nil + else + ESX.ShowNotification(TranslateCap("no_players")) + end + else + ESX.ShowNotification(TranslateCap("no_current_vehicle")) + end + elseif action == "set_vehicle_owner_rent" then + if currentDisplayVehicle then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer ~= -1 and closestDistance < 3 then + ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "set_vehicle_owner_rent_amount", { + title = TranslateCap("rental_amount"), + }, function(data2, menu2) + local amount = tonumber(data2.value) + + if not amount then + ESX.ShowNotification(TranslateCap("invalid_amount")) + else + menu2.close() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer ~= -1 and closestDistance < 3 then + local newPlate = "RENT" .. string.upper(ESX.GetRandomString(4)) + local model = CurrentVehicleData.model + SetVehicleNumberPlateText(currentDisplayVehicle, newPlate) + TriggerServerEvent("esx_vehicleshop:rentVehicle", model, newPlate, amount, GetPlayerServerId(closestPlayer)) + currentDisplayVehicle = nil + else + ESX.ShowNotification(TranslateCap("no_players")) + end + end + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(TranslateCap("no_players")) + end + else + ESX.ShowNotification(TranslateCap("no_current_vehicle")) + end + end + end, function(menu) + CurrentAction = "reseller_menu" + CurrentActionMsg = TranslateCap("shop_menu") + CurrentActionData = {} + end) end function OpenPopVehicleMenu() - local elements = {} - - for k, v in ipairs(cardealerVehicles) do - local vehicleLabel = getVehicleFromModel(v.vehicle).label - - TableInsert(elements, { - label = ('%s [%s]'):format( - vehicleLabel, - TranslateCap("generic_shopitem", ESX.Math.GroupDigits(v.price)) - ), - value = v.vehicle, - }) - end - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "commercial_vehicles", { - title = TranslateCap("vehicle_dealer"), - align = "top-left", - elements = elements, - }, function(data, menu) - local model = data.current.value - DeleteDisplayVehicleInsideShop() - - ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) - currentDisplayVehicle = vehicle - - for i = 1, #Vehicles, 1 do - if model == Vehicles[i].model then - CurrentVehicleData = Vehicles[i] - break - end - end - end) - end, function(data, menu) - menu.close() - end) + local elements = {} + + for k, v in ipairs(cardealerVehicles) do + local vehicleLabel = getVehicleFromModel(v.vehicle).label + + TableInsert(elements, { + label = ('%s [%s]'):format(vehicleLabel, TranslateCap("generic_shopitem", ESX.Math.GroupDigits(v.price))), + value = v.vehicle, + }) + end + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "commercial_vehicles", { + title = TranslateCap("vehicle_dealer"), + align = "top-left", + elements = elements, + }, function(data, menu) + local model = data.current.value + DeleteDisplayVehicleInsideShop() + + ESX.Game.SpawnVehicle(model, Config.Zones.ShopInside.Pos, Config.Zones.ShopInside.Heading, function(vehicle) + currentDisplayVehicle = vehicle + + for i = 1, #Vehicles, 1 do + if model == Vehicles[i].model then + CurrentVehicleData = Vehicles[i] + break + end + end + end) + end, function(data, menu) + menu.close() + end) end function OpenRentedVehiclesMenu() - local elements = {} - - for k, v in ipairs(rentedVehicles) do - local vehicleLabel = getVehicleFromModel(v.name).label - - TableInsert(elements, { - label = ('%s: %s - %s'):format(v.playerName, vehicleLabel, v.plate), - value = v.name, - }) - end - - ESX.UI.Menu.Open( - "default", - GetCurrentResourceName(), - "rented_vehicles", - { - title = TranslateCap("rent_vehicle"), - align = "top-left", - elements = elements, - }, - nil, - function(data, menu) - menu.close() - end - ) + local elements = {} + + for k, v in ipairs(rentedVehicles) do + local vehicleLabel = getVehicleFromModel(v.name).label + + TableInsert(elements, { + label = ('%s: %s - %s'):format(v.playerName, vehicleLabel, v.plate), + value = v.name, + }) + end + + ESX.UI.Menu.Open( + "default", + GetCurrentResourceName(), + "rented_vehicles", + { + title = TranslateCap("rent_vehicle"), + align = "top-left", + elements = elements, + }, + nil, + function(data, menu) + menu.close() + end + ) end local function OpenBossActionsMenu() - ESX.UI.Menu.CloseAll() - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "reseller", { - title = TranslateCap("dealer_boss"), - align = "top-left", - elements = { - { label = TranslateCap("boss_actions"), value = "boss_actions" }, - { label = TranslateCap("boss_sold"), value = "sold_vehicles" }, - }, - }, function(data, menu) - if data.current.value == "boss_actions" then - TriggerEvent("esx_society:openBossMenu", "cardealer", function(data2, menu2) - menu2.close() - end) - elseif data.current.value == "sold_vehicles" then - local elements = { - head = { - TranslateCap("customer_client"), - TranslateCap("customer_model"), - TranslateCap("customer_plate"), - TranslateCap("customer_soldby"), - TranslateCap("customer_date"), - }, - rows = {}, - } - - for i = 1, #soldVehicles, 1 do - TableInsert(elements.rows, { - data = soldVehicles[i], - cols = { - soldVehicles[i].client, - soldVehicles[i].model, - soldVehicles[i].plate, - soldVehicles[i].soldby, - soldVehicles[i].date, - }, - }) - end - - ESX.UI.Menu.Open( - "list", - GetCurrentResourceName(), - "sold_vehicles", - elements, - function(data2, menu2) end, - function(data2, menu2) - menu2.close() - end - ) - end - end, function(data, menu) - menu.close() - - CurrentAction = "boss_actions_menu" - CurrentActionMsg = TranslateCap("shop_menu") - CurrentActionData = {} - end) + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "reseller", { + title = TranslateCap("dealer_boss"), + align = "top-left", + elements = { + { label = TranslateCap("boss_actions"), value = "boss_actions" }, + { label = TranslateCap("boss_sold"), value = "sold_vehicles" }, + }, + }, function(data, menu) + if data.current.value == "boss_actions" then + TriggerEvent("esx_society:openBossMenu", "cardealer", function(data2, menu2) + menu2.close() + end) + elseif data.current.value == "sold_vehicles" then + local elements = { + head = { + TranslateCap("customer_client"), + TranslateCap("customer_model"), + TranslateCap("customer_plate"), + TranslateCap("customer_soldby"), + TranslateCap("customer_date"), + }, + rows = {}, + } + + for i = 1, #soldVehicles, 1 do + TableInsert(elements.rows, { + data = soldVehicles[i], + cols = { + soldVehicles[i].client, + soldVehicles[i].model, + soldVehicles[i].plate, + soldVehicles[i].soldby, + soldVehicles[i].date, + }, + }) + end + + ESX.UI.Menu.Open("list", GetCurrentResourceName(), "sold_vehicles", elements, function(data2, menu2) end, function(data2, menu2) + menu2.close() + end) + end + end, function(data, menu) + menu.close() + + CurrentAction = "boss_actions_menu" + CurrentActionMsg = TranslateCap("shop_menu") + CurrentActionData = {} + end) end function OpenGetStocksMenu() - ESX.TriggerServerCallback("esx_vehicleshop:getStockItems", function(items) - local elements = {} - - for i = 1, #items, 1 do - if items[i].count > 0 then - TableInsert(elements, { - label = "x" .. items[i].count .. " " .. items[i].label, - value = items[i].name, - }) - end - end - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "stocks_menu", { - title = TranslateCap("dealership_stock"), - align = "top-left", - elements = elements, - }, function(data, menu) - local itemName = data.current.value - - ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "stocks_menu_get_item_count", { - title = TranslateCap("amount"), - }, function(data2, menu2) - local count = tonumber(data2.value) - - if count == nil then - ESX.ShowNotification(TranslateCap("quantity_invalid")) - else - TriggerServerEvent("esx_vehicleshop:getStockItem", itemName, count) - menu2.close() - menu.close() - OpenGetStocksMenu() - end - end, function(data2, menu2) - menu2.close() - end) - end, function(data, menu) - menu.close() - end) - end) + ESX.TriggerServerCallback("esx_vehicleshop:getStockItems", function(items) + local elements = {} + + for i = 1, #items, 1 do + if items[i].count > 0 then + TableInsert(elements, { + label = "x" .. items[i].count .. " " .. items[i].label, + value = items[i].name, + }) + end + end + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "stocks_menu", { + title = TranslateCap("dealership_stock"), + align = "top-left", + elements = elements, + }, function(data, menu) + local itemName = data.current.value + + ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "stocks_menu_get_item_count", { + title = TranslateCap("amount"), + }, function(data2, menu2) + local count = tonumber(data2.value) + + if count == nil then + ESX.ShowNotification(TranslateCap("quantity_invalid")) + else + TriggerServerEvent("esx_vehicleshop:getStockItem", itemName, count) + menu2.close() + menu.close() + OpenGetStocksMenu() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + menu.close() + end) + end) end function OpenPutStocksMenu() - ESX.TriggerServerCallback("esx_vehicleshop:getPlayerInventory", function(inventory) - local elements = {} - - for i = 1, #inventory.items, 1 do - local item = inventory.items[i] - - if item.count > 0 then - TableInsert(elements, { - label = item.label .. " x" .. item.count, - type = "item_standard", - value = item.name, - }) - end - end - - ESX.UI.Menu.Open("default", GetCurrentResourceName(), "stocks_menu", { - title = TranslateCap("inventory"), - align = "top-left", - elements = elements, - }, function(data, menu) - local itemName = data.current.value - - ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "stocks_menu_put_item_count", { - title = TranslateCap("amount"), - }, function(data2, menu2) - local count = tonumber(data2.value) - - if count == nil then - ESX.ShowNotification(TranslateCap("quantity_invalid")) - else - TriggerServerEvent("esx_vehicleshop:putStockItems", itemName, count) - menu2.close() - menu.close() - OpenPutStocksMenu() - end - end, function(data2, menu2) - menu2.close() - end) - end, function(data, menu) - menu.close() - end) - end) + ESX.TriggerServerCallback("esx_vehicleshop:getPlayerInventory", function(inventory) + local elements = {} + + for i = 1, #inventory.items, 1 do + local item = inventory.items[i] + + if item.count > 0 then + TableInsert(elements, { + label = item.label .. " x" .. item.count, + type = "item_standard", + value = item.name, + }) + end + end + + ESX.UI.Menu.Open("default", GetCurrentResourceName(), "stocks_menu", { + title = TranslateCap("inventory"), + align = "top-left", + elements = elements, + }, function(data, menu) + local itemName = data.current.value + + ESX.UI.Menu.Open("dialog", GetCurrentResourceName(), "stocks_menu_put_item_count", { + title = TranslateCap("amount"), + }, function(data2, menu2) + local count = tonumber(data2.value) + + if count == nil then + ESX.ShowNotification(TranslateCap("quantity_invalid")) + else + TriggerServerEvent("esx_vehicleshop:putStockItems", itemName, count) + menu2.close() + menu.close() + OpenPutStocksMenu() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + menu.close() + end) + end) end local function hasEnteredMarker(zone) - if zone == "ShopEntering" then - if not Config.EnablePlayerManagement then - CurrentAction = "shop_menu" - CurrentActionMsg = TranslateCap("shop_menu") - CurrentActionData = {} - end - if LocalPlayer.state.job ~= nil and LocalPlayer.state.job.name == "cardealer" then - CurrentAction = "reseller_menu" - CurrentActionMsg = TranslateCap("shop_menu") - CurrentActionData = {} - end - elseif zone == "GiveBackVehicle" and Config.EnablePlayerManagement then - local playerPed = ESX.PlayerData.ped - - if IsPedInAnyVehicle(playerPed, false) then - local vehicle = GetVehiclePedIsIn(playerPed, false) - - CurrentAction = "give_back_vehicle" - CurrentActionMsg = TranslateCap("vehicle_menu") - CurrentActionData = { vehicle = vehicle } - end - elseif zone == "ResellVehicle" then - local playerPed = ESX.PlayerData.ped - - if IsPedSittingInAnyVehicle(playerPed) then - local vehicle = GetVehiclePedIsIn(playerPed, false) - local vehicleData, model, resellPrice, plate - - if GetPedInVehicleSeat(vehicle, -1) == playerPed then - for i = 1, #Vehicles, 1 do - if joaat(Vehicles[i].model) == GetEntityModel(vehicle) then - vehicleData = Vehicles[i] - break - end - end - - if vehicleData then - resellPrice = ESX.Math.Round(vehicleData.price / 100 * Config.ResellPercentage) - model = GetEntityModel(vehicle) - plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) - - CurrentAction = "resell_vehicle" - CurrentActionMsg = TranslateCap("sell_menu", vehicleData.name, ESX.Math.GroupDigits(resellPrice)) - - CurrentActionData = { - vehicle = vehicle, - label = vehicleData.name, - price = resellPrice, - model = model, - plate = plate, - } - else - ESX.ShowNotification(TranslateCap("invalid_vehicle")) - end - end - end - elseif - zone == "BossActions" - and Config.EnablePlayerManagement - and LocalPlayer.state.job ~= nil - and LocalPlayer.state.job.name == "cardealer" - and LocalPlayer.state.job.grade_name == "boss" - then - CurrentAction = "boss_actions_menu" - CurrentActionMsg = TranslateCap("shop_menu") - CurrentActionData = {} - end + if zone == "ShopEntering" then + if not Config.EnablePlayerManagement then + CurrentAction = "shop_menu" + CurrentActionMsg = TranslateCap("shop_menu") + CurrentActionData = {} + end + if LocalPlayer.state.job ~= nil and LocalPlayer.state.job.name == "cardealer" then + CurrentAction = "reseller_menu" + CurrentActionMsg = TranslateCap("shop_menu") + CurrentActionData = {} + end + elseif zone == "GiveBackVehicle" and Config.EnablePlayerManagement then + local playerPed = ESX.PlayerData.ped + + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + + CurrentAction = "give_back_vehicle" + CurrentActionMsg = TranslateCap("vehicle_menu") + CurrentActionData = { vehicle = vehicle } + end + elseif zone == "ResellVehicle" then + local playerPed = ESX.PlayerData.ped + + if IsPedSittingInAnyVehicle(playerPed) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + local vehicleData, model, resellPrice, plate + + if GetPedInVehicleSeat(vehicle, -1) == playerPed then + for i = 1, #Vehicles, 1 do + if joaat(Vehicles[i].model) == GetEntityModel(vehicle) then + vehicleData = Vehicles[i] + break + end + end + + if vehicleData then + resellPrice = ESX.Math.Round(vehicleData.price / 100 * Config.ResellPercentage) + model = GetEntityModel(vehicle) + plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) + + CurrentAction = "resell_vehicle" + CurrentActionMsg = TranslateCap("sell_menu", vehicleData.name, ESX.Math.GroupDigits(resellPrice)) + + CurrentActionData = { + vehicle = vehicle, + label = vehicleData.name, + price = resellPrice, + model = model, + plate = plate, + } + else + ESX.ShowNotification(TranslateCap("invalid_vehicle")) + end + end + end + elseif zone == "BossActions" and Config.EnablePlayerManagement and LocalPlayer.state.job ~= nil and LocalPlayer.state.job.name == "cardealer" and LocalPlayer.state.job.grade_name == "boss" then + CurrentAction = "boss_actions_menu" + CurrentActionMsg = TranslateCap("shop_menu") + CurrentActionData = {} + end end local function hasExitedMarker(zone) - if not IsInShopMenu then - ESX.UI.Menu.CloseAll() - ESX.CloseContext() - end - ESX.HideUI() - CurrentAction = nil + if not IsInShopMenu then + ESX.UI.Menu.CloseAll() + ESX.CloseContext() + end + ESX.HideUI() + CurrentAction = nil end AddEventHandler("onResourceStop", function(resource) - if resource ~= GetCurrentResourceName() then - return - end - if IsInShopMenu then - ESX.UI.Menu.CloseAll() - ESX.CloseContext() - - local playerPed = ESX.PlayerData.ped - - FreezeEntityPosition(playerPed, false) - SetEntityVisible(playerPed, true) - SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) - end - - ESX.HideUI() - DeleteDisplayVehicleInsideShop() + if resource ~= GetCurrentResourceName() then + return + end + if IsInShopMenu then + ESX.UI.Menu.CloseAll() + ESX.CloseContext() + + local playerPed = ESX.PlayerData.ped + + FreezeEntityPosition(playerPed, false) + SetEntityVisible(playerPed, true) + SetEntityCoords(playerPed, Config.Zones.ShopEntering.Pos) + end + + ESX.HideUI() + DeleteDisplayVehicleInsideShop() end) -- Enter / Exit marker events & Draw Markers CreateThread(function() - while true do - Wait(0) - local playerCoords = GetEntityCoords(ESX.PlayerData.ped) - local isInMarker, letSleep, currentZone = false, true - - for k, v in pairs(Config.Zones) do - local distance = #(playerCoords - v.Pos) - - if distance < Config.DrawDistance then - letSleep = false - - if v.Type ~= -1 then - DrawMarker( - v.Type, - v.Pos, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - v.Size.x, - v.Size.y, - v.Size.z, - Config.MarkerColor.r, - Config.MarkerColor.g, - Config.MarkerColor.b, - 100, - false, - true, - 2, - false, - nil, - nil, - false - ) - end - - if distance < v.Size.x then - isInMarker, currentZone = true, k - end - end - end - - if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then - HasAlreadyEnteredMarker, LastZone = true, currentZone - LastZone = currentZone - hasEnteredMarker(currentZone) - end - - if not isInMarker and HasAlreadyEnteredMarker then - HasAlreadyEnteredMarker = false - hasExitedMarker(LastZone) - end - - if letSleep then - Wait(1000) - end - end + while true do + Wait(0) + local playerCoords = GetEntityCoords(ESX.PlayerData.ped) + local isInMarker, letSleep, currentZone = false, true + + for k, v in pairs(Config.Zones) do + local distance = #(playerCoords - v.Pos) + + if distance < Config.DrawDistance then + letSleep = false + + if v.Type ~= -1 then + DrawMarker(v.Type, v.Pos, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, v.Size.x, v.Size.y, v.Size.z, Config.MarkerColor.r, Config.MarkerColor.g, Config.MarkerColor.b, 100, false, true, 2, false, nil, nil, false) + end + + if distance < v.Size.x then + isInMarker, currentZone = true, k + end + end + end + + if (isInMarker and not HasAlreadyEnteredMarker) or (isInMarker and LastZone ~= currentZone) then + HasAlreadyEnteredMarker, LastZone = true, currentZone + LastZone = currentZone + hasEnteredMarker(currentZone) + end + + if not isInMarker and HasAlreadyEnteredMarker then + HasAlreadyEnteredMarker = false + hasExitedMarker(LastZone) + end + + if letSleep then + Wait(1000) + end + end end) -- Key controls CreateThread(function() - while true do - Wait(0) - - if CurrentAction then - ESX.TextUI(CurrentActionMsg) - - if IsControlJustReleased(0, 38) then - if CurrentAction == "shop_menu" then - if Config.LicenseEnable then - ESX.TriggerServerCallback("esx_license:checkLicense", function(hasDriversLicense) - if hasDriversLicense then - OpenShopMenu() - else - ESX.ShowNotification(TranslateCap("license_missing")) - end - end, GetPlayerServerId(PlayerId()), "drive") - else - OpenShopMenu() - end - elseif CurrentAction == "reseller_menu" then - OpenResellerMenu() - elseif CurrentAction == "give_back_vehicle" then - ESX.TriggerServerCallback("esx_vehicleshop:giveBackVehicle", function(isRentedVehicle) - if isRentedVehicle then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - ESX.ShowNotification(TranslateCap("delivered")) - else - ESX.ShowNotification(TranslateCap("not_rental")) - end - end, ESX.Math.Trim(GetVehicleNumberPlateText(CurrentActionData.vehicle))) - elseif CurrentAction == "resell_vehicle" then - ESX.TriggerServerCallback("esx_vehicleshop:resellVehicle", function(vehicleSold) - if vehicleSold then - ESX.Game.DeleteVehicle(CurrentActionData.vehicle) - ESX.ShowNotification( - TranslateCap( - "vehicle_sold_for", - CurrentActionData.label, - ESX.Math.GroupDigits(CurrentActionData.price) - ) - ) - else - ESX.ShowNotification(TranslateCap("not_yours")) - end - end, CurrentActionData.plate, CurrentActionData.model) - elseif CurrentAction == "boss_actions_menu" then - OpenBossActionsMenu() - end - ESX.HideUI() - CurrentAction = nil - end - else - Wait(1000) - end - end + while true do + Wait(0) + + if CurrentAction then + ESX.TextUI(CurrentActionMsg) + + if IsControlJustReleased(0, 38) then + if CurrentAction == "shop_menu" then + if Config.LicenseEnable then + ESX.TriggerServerCallback("esx_license:checkLicense", function(hasDriversLicense) + if hasDriversLicense then + OpenShopMenu() + else + ESX.ShowNotification(TranslateCap("license_missing")) + end + end, GetPlayerServerId(PlayerId()), "drive") + else + OpenShopMenu() + end + elseif CurrentAction == "reseller_menu" then + OpenResellerMenu() + elseif CurrentAction == "give_back_vehicle" then + ESX.TriggerServerCallback("esx_vehicleshop:giveBackVehicle", function(isRentedVehicle) + if isRentedVehicle then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + ESX.ShowNotification(TranslateCap("delivered")) + else + ESX.ShowNotification(TranslateCap("not_rental")) + end + end, ESX.Math.Trim(GetVehicleNumberPlateText(CurrentActionData.vehicle))) + elseif CurrentAction == "resell_vehicle" then + ESX.TriggerServerCallback("esx_vehicleshop:resellVehicle", function(vehicleSold) + if vehicleSold then + ESX.Game.DeleteVehicle(CurrentActionData.vehicle) + ESX.ShowNotification(TranslateCap("vehicle_sold_for", CurrentActionData.label, ESX.Math.GroupDigits(CurrentActionData.price))) + else + ESX.ShowNotification(TranslateCap("not_yours")) + end + end, CurrentActionData.plate, CurrentActionData.model) + elseif CurrentAction == "boss_actions_menu" then + OpenBossActionsMenu() + end + ESX.HideUI() + CurrentAction = nil + end + else + Wait(1000) + end + end end) if ESX.PlayerLoaded then - PlayerManagement() + PlayerManagement() end