From d8100fe0d03d3ffd6b536dd8f991385cb93dfee0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Jul 2018 14:45:11 +0200 Subject: [PATCH] Greatly improved esx_service (see desc), closes #138 Not being in service means that you can no longer open the F6 menu, or open the armory. You will no longer be able to take out vehicles or receive dispatch calls. Greatly improved support for esx_service and esx_phone when restarting the scripts mentioned above mid-game. All ranks now have proper clothing in, but will still need a redo at some point. Many ranks simply doesn't match USA standard (that's what we'll aim at) Don't forget to update esx_service and esx_phone to support the new things! --- client/main.lua | 532 ++++++++++++++++++++++++++---------------------- config.lua | 56 ++++- locales/en.lua | 27 ++- server/main.lua | 6 + 4 files changed, 360 insertions(+), 261 deletions(-) diff --git a/client/main.lua b/client/main.lua index ec67b6c7..dcdbd6ab 100644 --- a/client/main.lua +++ b/client/main.lua @@ -27,6 +27,7 @@ local hasAlreadyJoined = false local blipsCops = {} local isDead = false local CurrentTask = {} +local playerInService = false ESX = nil @@ -61,134 +62,191 @@ function cleanPlayer(playerPed) end function setUniform(job, playerPed) - TriggerEvent('skinchanger:getSkin', function(skin) - if skin.sex == 0 then - if Config.Uniforms[job].male ~= nil then - TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].male) - else - ESX.ShowNotification(_U('no_outfit')) - end - if job == 'bullet_wear' then - SetPedArmour(playerPed, 100) - end - else - if Config.Uniforms[job].female ~= nil then - TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].female) - else - ESX.ShowNotification(_U('no_outfit')) - end - if job == 'bullet_wear' then - SetPedArmour(playerPed, 100) - end - end + TriggerEvent('skinchanger:getSkin', function(skin) - end) + if skin.sex == 0 then + + if Config.Uniforms[job].male ~= nil then + TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].male) + else + ESX.ShowNotification(_U('no_outfit')) + end + + if job == 'bullet_wear' then + SetPedArmour(playerPed, 100) + end + + else + + if Config.Uniforms[job].female ~= nil then + TriggerEvent('skinchanger:loadClothes', skin, Config.Uniforms[job].female) + else + ESX.ShowNotification(_U('no_outfit')) + end + + if job == 'bullet_wear' then + SetPedArmour(playerPed, 100) + end + + end + + end) end function OpenCloakroomMenu() - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() - local elements = { - { label = _U('citizen_wear'), value = 'citizen_wear' }, - { label = _U('bullet_wear'), value = 'bullet_wear' }, - { label = _U('gilet_wear'), value = 'gilet_wear' } - } + local elements = { + { label = _U('citizen_wear'), value = 'citizen_wear' }, + { label = _U('bullet_wear'), value = 'bullet_wear' }, + { label = _U('gilet_wear'), value = 'gilet_wear' } + } - if PlayerData.job.grade_name == 'recruit' then - table.insert(elements, {label = _U('police_wear'), value = 'cadet_wear'}) - end + if PlayerData.job.grade_name == 'recruit' then + table.insert(elements, {label = _U('police_wear'), value = 'recruit_wear'}) + elseif PlayerData.job.grade_name == 'officer' then + table.insert(elements, {label = _U('police_wear'), value = 'officer_wear'}) + elseif PlayerData.job.grade_name == 'sergeant' then + table.insert(elements, {label = _U('police_wear'), value = 'sergeant_wear'}) + elseif PlayerData.job.grade_name == 'intendent' then + table.insert(elements, {label = _U('police_wear'), value = 'intendent_wear'}) + elseif PlayerData.job.grade_name == 'lieutenant' then + table.insert(elements, {label = _U('police_wear'), value = 'lieutenant_wear'}) + elseif PlayerData.job.grade_name == 'chef' then + table.insert(elements, {label = _U('police_wear'), value = 'chef_wear'}) + elseif PlayerData.job.grade_name == 'boss' then + table.insert(elements, {label = _U('police_wear'), value = 'boss_wear'}) + end - if PlayerData.job.grade_name == 'officer' then - table.insert(elements, {label = _U('police_wear'), value = 'police_wear'}) - end + if Config.EnableNonFreemodePeds then + table.insert(elements, {label = _U('sheriff_wear'), value = 'freemode_ped', maleModel = 's_m_y_sheriff_01', femaleModel = 's_f_y_sheriff_01'}) + table.insert(elements, {label = _U('lieutenant_wear'), value = 'freemode_ped', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'}) + table.insert(elements, {label = _U('commandant_wear'), value = 'freemode_ped', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'}) + end - if PlayerData.job.grade_name == 'sergeant' then - table.insert(elements, {label = _U('police_wear'), value = 'sergeant_wear'}) - end + ESX.UI.Menu.CloseAll() - if PlayerData.job.grade_name == 'lieutenant' then - table.insert(elements, {label = _U('police_wear'), value = 'lieutenant_wear'}) - end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', + { + title = _U('cloakroom'), + align = 'top-left', + elements = elements + }, function(data, menu) - if PlayerData.job.grade_name == 'boss' then - table.insert(elements, {label = _U('police_wear'), value = 'commandant_wear'}) - end + cleanPlayer(playerPed) - if Config.EnableNonFreemodePeds then - table.insert(elements, {label = _U('sheriff_wear'), value = 'sheriff_wear_freemode', maleModel = 's_m_y_sheriff_01', femaleModel = 's_f_y_sheriff_01'}) - table.insert(elements, {label = _U('lieutenant_wear'), value = 'lieutenant_wear_freemode', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'}) - table.insert(elements, {label = _U('commandant_wear'), value = 'commandant_wear_freemode', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'}) - end + if data.current.value == 'citizen_wear' then + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) - ESX.UI.Menu.CloseAll() + if Config.MaxInService ~= -1 then - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'cloakroom', - { - title = _U('cloakroom'), - align = 'top-left', - elements = elements, - }, - function(data, menu) + ESX.TriggerServerCallback('esx_service:isInService', function(isInService) + if isInService then - cleanPlayer(playerPed) + local notification = { + title = _U('service_anonunce'), + subject = '', + msg = _U('service_out_announce', GetPlayerName(PlayerId())), + iconType = 1 + } - if data.current.value == 'citizen_wear' then - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) - TriggerEvent('skinchanger:loadSkin', skin) - end) - end + TriggerServerEvent('esx_service:notifyAllInService', notification, 'police') - if - data.current.value == 'cadet_wear' or - data.current.value == 'police_wear' or - data.current.value == 'sergeant_wear' or - data.current.value == 'lieutenant_wear' or - data.current.value == 'commandant_wear' or - data.current.value == 'bullet_wear' or - data.current.value == 'gilet_wear' - then - setUniform(data.current.value, playerPed) - end + TriggerServerEvent('esx_service:disableService', 'police') + ESX.ShowNotification(_U('service_out')) + playerInService = false + end + end, 'police') + end - if - data.current.value == 'sheriff_wear_freemode' or - data.current.value == 'lieutenant_wear_freemode' or - data.current.value == 'commandant_wear_freemode' - then - local model = nil - ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) - if skin.sex == 0 then - model = GetHashKey(data.current.maleModel) - else - model = GetHashKey(data.current.femaleModel) - end - end) - - RequestModel(model) - while not HasModelLoaded(model) do - RequestModel(model) - Citizen.Wait(1) - end - - SetPlayerModel(PlayerId(), model) - SetModelAsNoLongerNeeded(model) - end + menu.close() + end - CurrentAction = 'menu_cloakroom' - CurrentActionMsg = _U('open_cloackroom') - CurrentActionData = {} + if Config.MaxInService ~= -1 and data.current.value ~= 'citizen_wear' then + local serviceOk = 'waiting' - end, - function(data, menu) - menu.close() - CurrentAction = 'menu_cloakroom' - CurrentActionMsg = _U('open_cloackroom') - CurrentActionData = {} - end - ) + ESX.TriggerServerCallback('esx_service:isInService', function(isInService) + if not isInService then + + ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + if not canTakeService then + ESX.ShowNotification(_U('service_max', inServiceCount, maxInService)) + else + + local notification = { + title = _U('service_anonunce'), + subject = '', + msg = _U('service_in_announce', GetPlayerName(PlayerId())), + iconType = 1 + } + + TriggerServerEvent('esx_service:notifyAllInService', notification, 'police') + ESX.ShowNotification(_U('service_in')) + serviceOk = true + playerInService = true + end + end, 'police') + + else + serviceOk = true + end + end, 'police') + + while type(serviceOk) == 'string' do + Citizen.Wait(5) + end + + -- if we couldn't enter service don't let the player get changed + if not serviceOk then + return + end + end + + if + data.current.value == 'recruit_wear' or + data.current.value == 'officer_wear' or + data.current.value == 'sergeant_wear' or + data.current.value == 'intendent_wear' or + data.current.value == 'lieutenant_wear' or + data.current.value == 'chef_wear' or + data.current.value == 'boss_wear' or + data.current.value == 'bullet_wear' or + data.current.value == 'gilet_wear' + then + setUniform(data.current.value, playerPed) + end + + if data.current.value == 'freemode_ped' then + local model = nil + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + if skin.sex == 0 then + model = GetHashKey(data.current.maleModel) + else + model = GetHashKey(data.current.femaleModel) + end + end) + + ESX.Streaming.RequestModel(model) + SetPlayerModel(PlayerId(), model) + SetModelAsNoLongerNeeded(model) + end + + CurrentAction = 'menu_cloakroom' + CurrentActionMsg = _U('open_cloackroom') + CurrentActionData = {} + + end, function(data, menu) + menu.close() + + CurrentAction = 'menu_cloakroom' + CurrentActionMsg = _U('open_cloackroom') + CurrentActionData = {} + end) end function OpenArmoryMenu(station) @@ -287,140 +345,110 @@ end function OpenVehicleSpawnerMenu(station, partNum) - local vehicles = Config.PoliceStations[station].Vehicles + local vehicles = Config.PoliceStations[station].Vehicles + ESX.UI.Menu.CloseAll() - ESX.UI.Menu.CloseAll() + if Config.EnableSocietyOwnedVehicles then - if Config.EnableSocietyOwnedVehicles then + local elements = {} - local elements = {} + ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(garageVehicles) - ESX.TriggerServerCallback('esx_society:getVehiclesInGarage', function(garageVehicles) + for i=1, #garageVehicles, 1 do + table.insert(elements, {label = GetDisplayNameFromVehicleModel(garageVehicles[i].model) .. ' [' .. garageVehicles[i].plate .. ']', value = garageVehicles[i]}) + end - for i=1, #garageVehicles, 1 do - table.insert(elements, {label = GetDisplayNameFromVehicleModel(garageVehicles[i].model) .. ' [' .. garageVehicles[i].plate .. ']', value = garageVehicles[i]}) - end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', + { + title = _U('vehicle_menu'), + align = 'top-left', + elements = elements + }, function(data, menu) + menu.close() - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'vehicle_spawner', - { - title = _U('vehicle_menu'), - align = 'top-left', - elements = elements, - }, - function(data, menu) + local vehicleProps = data.current.value - menu.close() + ESX.Game.SpawnVehicle(vehicleProps.model, vehicles[partNum].SpawnPoint, vehicles[partNum].Heading, function(vehicle) + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + local playerPed = PlayerPedId() + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) - local vehicleProps = data.current.value + TriggerServerEvent('esx_society:removeVehicleFromGarage', 'police', vehicleProps) + end, function(data, menu) + menu.close() - ESX.Game.SpawnVehicle(vehicleProps.model, vehicles[partNum].SpawnPoint, 270.0, function(vehicle) - ESX.Game.SetVehicleProperties(vehicle, vehicleProps) - local playerPed = PlayerPedId() - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) + CurrentAction = 'menu_vehicle_spawner' + CurrentActionMsg = _U('vehicle_spawner') + CurrentActionData = {station = station, partNum = partNum} + end) - TriggerServerEvent('esx_society:removeVehicleFromGarage', 'police', vehicleProps) + end, 'police') - end, - function(data, menu) + else - menu.close() + local elements = {} - CurrentAction = 'menu_vehicle_spawner' - CurrentActionMsg = _U('vehicle_spawner') - CurrentActionData = {station = station, partNum = partNum} + local sharedVehicles = Config.AuthorizedVehicles.Shared + for i=1, #sharedVehicles, 1 do + table.insert(elements, { label = sharedVehicles[i].label, model = sharedVehicles[i].model}) + end - end - ) + local authorizedVehicles = Config.AuthorizedVehicles[PlayerData.job.grade_name] + for i=1, #authorizedVehicles, 1 do + table.insert(elements, { label = authorizedVehicles[i].label, model = authorizedVehicles[i].model}) + end - end, 'police') + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_spawner', + { + title = _U('vehicle_menu'), + align = 'top-left', + elements = elements + }, function(data, menu) + menu.close() - else + local model = data.current.model + local vehicle = GetClosestVehicle(vehicles[partNum].SpawnPoint.x, vehicles[partNum].SpawnPoint.y, vehicles[partNum].SpawnPoint.z, 3.0, 0, 71) - local elements = {} + if not DoesEntityExist(vehicle) then + + local playerPed = PlayerPedId() + + if Config.MaxInService == -1 then + + ESX.Game.SpawnVehicle(model, vehicles[partNum].SpawnPoint, vehicles[partNum].Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + SetVehicleMaxMods(vehicle) + end) + else + + ESX.TriggerServerCallback('esx_service:isInService', function(isInService) + if isInService then + + ESX.Game.SpawnVehicle(model, vehicles[partNum].SpawnPoint, vehicles[partNum].Heading, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + SetVehicleMaxMods(vehicle) + end) + else + ESX.ShowNotification(_U('service_not')) + end + end, 'police') + end + + else + ESX.ShowNotification(_U('vehicle_out')) + end + + end, function(data, menu) + menu.close() + + CurrentAction = 'menu_vehicle_spawner' + CurrentActionMsg = _U('vehicle_spawner') + CurrentActionData = {station = station, partNum = partNum} + + end) - local sharedVehicles = Config.AuthorizedVehicles.Shared - for i=1, #sharedVehicles, 1 do - table.insert(elements, { label = sharedVehicles[i].label, model = sharedVehicles[i].model}) end - - local authorizedVehicles = Config.AuthorizedVehicles[PlayerData.job.grade_name] - for i=1, #authorizedVehicles, 1 do - table.insert(elements, { label = authorizedVehicles[i].label, model = authorizedVehicles[i].model}) - end - - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'vehicle_spawner', - { - title = _U('vehicle_menu'), - align = 'top-left', - elements = elements, - }, - function(data, menu) - - menu.close() - - local model = data.current.model - - local vehicle = GetClosestVehicle(vehicles[partNum].SpawnPoint.x, vehicles[partNum].SpawnPoint.y, vehicles[partNum].SpawnPoint.z, 3.0, 0, 71) - - if not DoesEntityExist(vehicle) then - - local playerPed = PlayerPedId() - - if Config.MaxInService == -1 then - - ESX.Game.SpawnVehicle(model, { - x = vehicles[partNum].SpawnPoint.x, - y = vehicles[partNum].SpawnPoint.y, - z = vehicles[partNum].SpawnPoint.z - }, vehicles[partNum].Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - SetVehicleMaxMods(vehicle) - end) - - else - - ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) - - if canTakeService then - - ESX.Game.SpawnVehicle(model, { - x = vehicles[partNum].SpawnPoint.x, - y = vehicles[partNum].SpawnPoint.y, - z = vehicles[partNum].SpawnPoint.z - }, vehicles[partNum].Heading, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - SetVehicleMaxMods(vehicle) - end) - - else - ESX.ShowNotification(_U('service_max', inServiceCount, maxInService)) - end - - end, 'police') - - end - - else - ESX.ShowNotification(_U('vehicle_out')) - end - - end, - function(data, menu) - - menu.close() - - CurrentAction = 'menu_vehicle_spawner' - CurrentActionMsg = _U('vehicle_spawner') - CurrentActionData = {station = station, partNum = partNum} - - end - ) - - end - end function OpenPoliceActionsMenu() @@ -1241,17 +1269,27 @@ end) RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + local specialContact = { + name = _U('phone_police'), + number = 'police', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDFGQTJDRkI0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDFGQTJDRkM0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MUZBMkNGOTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MUZBMkNGQTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoW66EYAAAjGSURBVHjapJcLcFTVGcd/u3cfSXaTLEk2j80TCI8ECI9ABCyoiBqhBVQqVG2ppVKBQqUVgUl5OU7HKqNOHUHU0oHamZZWoGkVS6cWAR2JPJuAQBPy2ISEvLN57+v2u2E33e4k6Ngz85+9d++95/zP9/h/39GpqsqiRYsIGz8QZAq28/8PRfC+4HT4fMXFxeiH+GC54NeCbYLLATLpYe/ECx4VnBTsF0wWhM6lXY8VbBE0Ch4IzLcpfDFD2P1TgrdC7nMCZLRxQ9AkiAkQCn77DcH3BC2COoFRkCSIG2JzLwqiQi0RSmCD4JXbmNKh0+kc/X19tLtc9Ll9sk9ZS1yoU71YIk3xsbEx8QaDEc2ttxmaJSKC1ggSKBK8MKwTFQVXRzs3WzpJGjmZgvxcMpMtWIwqsjztvSrlzjYul56jp+46qSmJmMwR+P3+4aZ8TtCprRkk0DvUW7JjmV6lsqoKW/pU1q9YQOE4Nxkx4ladE7zd8ivuVmJQfXZKW5dx5EwPRw4fxNx2g5SUVLw+33AkzoRaQDP9SkFu6OKqz0uF8yaz7vsOL6ycQVLkcSg/BlWNsjuFoKE1knqDSl5aNnmPLmThrE0UvXqQqvJPyMrMGorEHwQfEha57/3P7mXS684GFjy8kreLppPUuBXfyd/ibeoS2kb0mWPANhJdYjb61AxUvx5PdT3+4y+Tb3mTd19ZSebE+VTXVGNQlHAC7w4VhH8TbA36vKq6ilnzlvPSunHw6Trc7XpZ14AyfgYeyz18crGN1Alz6e3qwNNQSv4dZox1h/BW9+O7eIaEsVv41Y4XeHJDG83Nl4mLTwzGhJYtx0PzNTjOB9KMTlc7Nkcem39YAGU7cbeBKVLMPGMVf296nMd2VbBq1wmizHoqqm/wrS1/Zf0+N19YN2PIu1fcIda4Vk66Zx/rVi+jo9eIX9wZGGcFXUMR6BHUa76/2ezioYcXMtpyAl91DSaTfDxlJbtLprHm2ecpObqPuTPzSNV9yKz4a4zJSuLo71/j8Q17ON69EmXiPIlNMe6FoyzOqWPW/MU03Lw5EFcyKghTrNDh7+/vw545mcJcWbTiGKpRdGPMXbx90sGmDaux6sXk+kimjU+BjnMkx3kYP34cXrFuZ+3nrHi6iDMt92JITcPjk3R3naRwZhpuNSqoD93DKaFVU7j2dhcF8+YzNlpErbIBTVh8toVccbaysPB+4pMcuPw25kwSsau7BIlmHpy3guaOPtISYyi/UkaJM5Lpc5agq5Xkcl6gIHkmqaMn0dtylcjIyPThCNyhaXyfR2W0I1our0v6qBii07ih5rDtGSOxNVdk1y4R2SR8jR/g7hQD9l1jUeY/WLJB5m39AlZN4GZyIQ1fFJNsEgt0duBIc5GRkcZF53mNwIzhXPDgQPoZIkiMkbTxtstDMVnmFA4cOsbz2/aKjSQjev4Mp9ZAg+hIpFhB3EH5Yal16+X+Kq3dGfxkzRY+KauBjBzREvGN0kNCTARu94AejBLMHorAQ7cEQMGs2cXvkWshYLDi6e9l728O8P1XW6hKeB2yv42q18tjj+iFTGoSi+X9jJM9RTxS9E+OHT0krhNiZqlbqraoT7RAU5bBGrEknEBhgJks7KXbLS8qERI0ErVqF/Y4K6NHZfLZB+/wzJvncacvFd91oXO3o/O40MfZKJOKu/rne+mRQByXM4lYreb1tUnkizVVA/0SpfpbWaCNBeEE5gb/UH19NLqEgDF+oNDQWcn41Cj0EXFEWqzkOIyYekslFkThsvMxpIyE2hIc6lXGZ6cPyK7Nnk5OipixRdxgUESAYmhq68VsGgy5CYKCUAJTg0+izApXne3CJFmUTwg4L3FProFxU+6krqmXu3MskkhSD2av41jLdzlnfFrSdCZxyqfMnppN6ZUa7pwt0h3fiK9DCt4IO9e7YqisvI7VYgmNv7mhBKKD/9psNi5dOMv5ZjukjsLdr0ffWsyTi6eSlfcA+dmiVyOXs+/sHNZu3M6PdxzgVO9GmDSHsSNqmTz/R6y6Xxqma4fwaS5Mn85n1ZE0Vl3CHBER3lUNEhiURpPJRFdTOcVnpUJnPIhR7cZXfoH5UYc5+E4RzRH3sfSnl9m2dSMjE+Tz9msse+o5dr7UwcQ5T3HwlWUkNuzG3dKFSTbsNs7m/Y8vExOlC29UWkMJlAxKoRQMR3IC7x85zOn6fHS50+U/2Untx2R1voinu5no+DQmz7yPXmMKZnsu0wrm0Oe3YhOVHdm8A09dBQYhTv4T7C+xUPrZh8Qn2MMr4qcDSRfoirWgKAvtgOpv1JI8Zi77X15G7L+fxeOUOiUFxZiULD5fSlNzNM62W+k1yq5gjajGX/ZHvOIyxd+Fkj+P092rWP/si0Qr7VisMaEWuCiYonXFwbAUTWWPYLV245NITnGkUXnpI9butLJn2y6iba+hlp7C09qBcvoN7FYL9mhxo1/y/LoEXK8Pv6qIC8WbBY/xr9YlPLf9dZT+OqKTUwfmDBm/GOw7ws4FWpuUP2gJEZvKqmocuXPZuWYJMzKuSsH+SNwh3bo0p6hao6HeEqwYEZ2M6aKWd3PwTCy7du/D0F1DsmzE6/WGLr5LsDF4LggnYBacCOboQLHQ3FFfR58SR+HCR1iQH8ukhA5s5o5AYZMwUqOp74nl8xvRHDlRTsnxYpJsUjtsceHt2C8Fm0MPJrphTkZvBc4It9RKLOFx91Pf0Igu0k7W2MmkOewS2QYJUJVWVz9VNbXUVVwkyuAmKTFJayrDo/4Jwe/CT0aGYTrWVYEeUfsgXssMRcpyenraQJa0VX9O3ZU+Ma1fax4xGxUsUVFkOUbcama1hf+7+LmA9juHWshwmwOE1iMmCFYEzg1jtIm1BaxW6wCGGoFdewPfvyE4ertTiv4rHC73B855dwp2a23bbd4tC1hvhOCbX7b4VyUQKhxrtSOaYKngasizvwi0RmOS4O1QZf2yYfiaR+73AvhTQEVf+rpn9/8IMAChKDrDzfsdIQAAAABJRU5ErkJggg==' + } - local specialContact = { - name = _U('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 type(PlayerData.job.name) == 'string' and PlayerData.job.name == 'police' and PlayerData.job.name == dispatchNumber then + -- if esx_service is enabled + if Config.MaxInService ~= -1 and not playerInService then + CancelEvent() + end + end +end) + + AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum) if part == 'Cloakroom' then @@ -1278,11 +1316,7 @@ AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNu if not IsAnyVehicleNearPoint(helicopters[partNum].SpawnPoint.x, helicopters[partNum].SpawnPoint.y, helicopters[partNum].SpawnPoint.z, 3.0) then - ESX.Game.SpawnVehicle('polmav', { - x = helicopters[partNum].SpawnPoint.x, - y = helicopters[partNum].SpawnPoint.y, - z = helicopters[partNum].SpawnPoint.z - }, helicopters[partNum].Heading, function(vehicle) + ESX.Game.SpawnVehicle('polmav', helicopters[partNum].SpawnPoint, helicopters[partNum].Heading, function(vehicle) SetVehicleModKit(vehicle, 0) SetVehicleLivery(vehicle, 0) end) @@ -1831,23 +1865,19 @@ Citizen.CreateThread(function() if CurrentAction == 'menu_cloakroom' then OpenCloakroomMenu() elseif CurrentAction == 'menu_armory' then - OpenArmoryMenu(CurrentActionData.station) + if Config.MaxInService == -1 then + OpenArmoryMenu(CurrentActionData.station) + elseif playerInService then + OpenArmoryMenu(CurrentActionData.station) + else + ESX.ShowNotification(_U('service_not')) + end elseif CurrentAction == 'menu_vehicle_spawner' then OpenVehicleSpawnerMenu(CurrentActionData.station, CurrentActionData.partNum) elseif CurrentAction == 'delete_vehicle' then if Config.EnableSocietyOwnedVehicles then local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle) TriggerServerEvent('esx_society:putVehicleInGarage', 'police', vehicleProps) - else - if GetEntityModel(vehicle) == GetHashKey('police') or - GetEntityModel(vehicle) == GetHashKey('police2') or - GetEntityModel(vehicle) == GetHashKey('police3') or - GetEntityModel(vehicle) == GetHashKey('police4') or - GetEntityModel(vehicle) == GetHashKey('policeb') or - GetEntityModel(vehicle) == GetHashKey('policet') - then - TriggerServerEvent('esx_service:disableService', 'police') - end end ESX.Game.DeleteVehicle(CurrentActionData.vehicle) elseif CurrentAction == 'menu_boss_actions' then @@ -1867,7 +1897,13 @@ Citizen.CreateThread(function() end -- CurrentAction end if IsControlJustReleased(0, Keys['F6']) and not isDead and PlayerData.job ~= nil and PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then - OpenPoliceActionsMenu() + if Config.MaxInService == -1 then + OpenPoliceActionsMenu() + elseif playerInService then + OpenPoliceActionsMenu() + else + ESX.ShowNotification(_U('service_not')) + end end if IsControlJustReleased(0, Keys['E']) and CurrentTask.Busy then @@ -1943,6 +1979,8 @@ end) AddEventHandler('onResourceStop', function(resource) if resource == GetCurrentResourceName() then TriggerEvent('esx_policejob:unrestrain') + TriggerEvent('esx_phone:removeSpecialContact', 'police') + TriggerServerEvent('esx_service:disableService', 'police') if Config.EnableHandcuffTimer and HandcuffTimer.Active then ESX.ClearTimeout(HandcuffTimer.Task) diff --git a/config.lua b/config.lua index 7ca7c712..515dcc9a 100644 --- a/config.lua +++ b/config.lua @@ -136,7 +136,7 @@ Config.AuthorizedVehicles = { -- CHECK SKINCHANGER CLIENT MAIN.LUA for matching elements Config.Uniforms = { - cadet_wear = { + recruit_wear = { male = { ['tshirt_1'] = 59, ['tshirt_2'] = 1, ['torso_1'] = 55, ['torso_2'] = 0, @@ -160,7 +160,7 @@ Config.Uniforms = { ['ears_1'] = 2, ['ears_2'] = 0 } }, - police_wear = { + officer_wear = { male = { ['tshirt_1'] = 58, ['tshirt_2'] = 0, ['torso_1'] = 55, ['torso_2'] = 0, @@ -208,7 +208,7 @@ Config.Uniforms = { ['ears_1'] = 2, ['ears_2'] = 0 } }, - lieutenant_wear = { + intendent_wear = { male = { ['tshirt_1'] = 58, ['tshirt_2'] = 0, ['torso_1'] = 55, ['torso_2'] = 0, @@ -232,7 +232,55 @@ Config.Uniforms = { ['ears_1'] = 2, ['ears_2'] = 0 } }, - commandant_wear = { + lieutenant_wear = { -- currently the same as intendent_wear + male = { + ['tshirt_1'] = 58, ['tshirt_2'] = 0, + ['torso_1'] = 55, ['torso_2'] = 0, + ['decals_1'] = 8, ['decals_2'] = 2, + ['arms'] = 41, + ['pants_1'] = 25, ['pants_2'] = 0, + ['shoes_1'] = 25, ['shoes_2'] = 0, + ['helmet_1'] = -1, ['helmet_2'] = 0, + ['chain_1'] = 0, ['chain_2'] = 0, + ['ears_1'] = 2, ['ears_2'] = 0 + }, + female = { + ['tshirt_1'] = 35, ['tshirt_2'] = 0, + ['torso_1'] = 48, ['torso_2'] = 0, + ['decals_1'] = 7, ['decals_2'] = 2, + ['arms'] = 44, + ['pants_1'] = 34, ['pants_2'] = 0, + ['shoes_1'] = 27, ['shoes_2'] = 0, + ['helmet_1'] = -1, ['helmet_2'] = 0, + ['chain_1'] = 0, ['chain_2'] = 0, + ['ears_1'] = 2, ['ears_2'] = 0 + } + }, + chef_wear = { + male = { + ['tshirt_1'] = 58, ['tshirt_2'] = 0, + ['torso_1'] = 55, ['torso_2'] = 0, + ['decals_1'] = 8, ['decals_2'] = 3, + ['arms'] = 41, + ['pants_1'] = 25, ['pants_2'] = 0, + ['shoes_1'] = 25, ['shoes_2'] = 0, + ['helmet_1'] = -1, ['helmet_2'] = 0, + ['chain_1'] = 0, ['chain_2'] = 0, + ['ears_1'] = 2, ['ears_2'] = 0 + }, + female = { + ['tshirt_1'] = 35, ['tshirt_2'] = 0, + ['torso_1'] = 48, ['torso_2'] = 0, + ['decals_1'] = 7, ['decals_2'] = 3, + ['arms'] = 44, + ['pants_1'] = 34, ['pants_2'] = 0, + ['shoes_1'] = 27, ['shoes_2'] = 0, + ['helmet_1'] = -1, ['helmet_2'] = 0, + ['chain_1'] = 0, ['chain_2'] = 0, + ['ears_1'] = 2, ['ears_2'] = 0 + } + }, + boss_wear = { -- currently the same as chef_wear male = { ['tshirt_1'] = 58, ['tshirt_2'] = 0, ['torso_1'] = 55, ['torso_2'] = 0, diff --git a/locales/en.lua b/locales/en.lua index ad6d5b40..c376dd94 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,16 +4,16 @@ Locales['en'] = { ['citizen_wear'] = 'civilian Outfit', ['police_wear'] = 'police Outfit', ['sheriff_wear'] = 'sheriff Outfit', - ['lieutenant_wear'] = 'Swatt outfit ', + ['lieutenant_wear'] = 'swat outfit', ['gilet_wear'] = 'orange reflective jacket', ['bullet_wear'] = 'bulletproof vest', ['no_outfit'] = 'there\'s no uniform that fits you!', ['open_cloackroom'] = 'press ~INPUT_CONTEXT~ to change ~y~clothes~s~.', -- Armory - ['remove_object'] = 'take object', + ['remove_object'] = 'withdraw object', ['deposit_object'] = 'deposit object', - ['get_weapon'] = 'take weapon', - ['put_weapon'] = 'put weapon', + ['get_weapon'] = 'withdraw weapon', + ['put_weapon'] = 'deposit weapon', ['buy_weapons'] = 'buy weapons', ['armory'] = 'armory', ['open_armory'] = 'press ~INPUT_CONTEXT~ to access the armory', @@ -22,16 +22,23 @@ Locales['en'] = { ['vehicle_out'] = 'there is already a car out of the garage', ['vehicle_spawner'] = 'press ~INPUT_CONTEXT~ to take out a vehicle', ['store_vehicle'] = 'press ~INPUT_CONTEXT~ to store the vehicle', - ['service_max'] = 'max officers in service: %s/%s', + -- Service + ['service_max'] = 'you cannot enter service, max officers in service: %s/%s', + ['service_not'] = 'you have not entered service! You\'ll have to get changed first.', + ['service_anonunce'] = 'service information', + ['service_in'] = 'you\'ve entered service, welcome!', + ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!', + ['service_out'] = 'you have left service.', + ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.', -- Action Menu ['citizen_interaction'] = 'citizen Interaction', ['vehicle_interaction'] = 'vehicle Interaction', ['object_spawner'] = 'object Spawner', - ['id_card'] = 'iD Card', + ['id_card'] = 'ID Card', ['search'] = 'search', ['handcuff'] = 'cuff / Uncuff', - ['drag'] = 'drag', + ['drag'] = 'escort', ['put_in_vehicle'] = 'put in Vehicle', ['out_the_vehicle'] = 'drag out from vehicle', ['fine'] = 'fine', @@ -98,8 +105,8 @@ Locales['en'] = { ['owner_unknown'] = 'owner: Unknown', ['owner'] = 'owner: %s', -- Weapons Menus - ['get_weapon_menu'] = 'armory - Take Weapon', - ['put_weapon_menu'] = 'armory - Put Weapon', + ['get_weapon_menu'] = 'armory - Withdraw Weapon', + ['put_weapon_menu'] = 'armory - Deposit Weapon', ['buy_weapon_menu'] = 'armory - Buy Guns', ['not_enough_money'] = 'you do not have enough money', -- Boss Menu @@ -120,6 +127,6 @@ Locales['en'] = { ['map_blip'] = 'police Station', ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.', -- Notifications - ['alert_police'] = 'alert police', + ['alert_police'] = 'police alert', ['phone_police'] = 'police', } diff --git a/server/main.lua b/server/main.lua index afa96d65..59dfb92a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -521,6 +521,12 @@ AddEventHandler('onResourceStart', function(resource) end end) +AddEventHandler('onResourceStop', function(resource) + if resource == GetCurrentResourceName() then + TriggerEvent('esx_phone:removeNumber', 'police') + end +end) + RegisterServerEvent('esx_policejob:message') AddEventHandler('esx_policejob:message', function(target, msg) TriggerClientEvent('esx:showNotification', target, msg)