Hey,
Ich benötige Hilfe bei dem Police Job da möchte ich ein Eigene Rechnung Buttom hinzufügen der die Funktion hat eigene Rechnungsbeträge zu erstellen
Ich hab ein problem wenn ich auf Zivilistenaktionen buttom gehe öffnet sich sofort das fenster kann man nicht irgendwie eine abfrage machen das es sich erst öffnet wenn ich auf eigene Rechnung gehe?
Youtube Link wie es ingame aussieht
ihr Findet den Code unter
Codezeile: 273
Code
local CurrentActionData, handcuffTimer, dragStatus, blipsCops, currentTask = {}, {}, {}, {}, {}
local HasAlreadyEnteredMarker, isDead, isHandcuffed, hasAlreadyJoined, playerInService = false, false, false, false, false
local LastStation, LastPart, LastPartNum, LastEntity, CurrentAction, CurrentActionMsg
dragStatus.isDragged, isInShopMenu = false, false
ESX = nil
Citizen.CreateThread(function()
while ESX == nil do
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
Citizen.Wait(0)
end
while ESX.GetPlayerData().job == nil do
Citizen.Wait(10)
end
ESX.PlayerData = ESX.GetPlayerData()
end)
function cleanPlayer(playerPed)
SetPedArmour(playerPed, 0)
ClearPedBloodDamage(playerPed)
ResetPedVisibleDamage(playerPed)
ClearPedLastWeaponDamage(playerPed)
ResetPedMovementClipset(playerPed, 0)
end
local coordinate = {
{ 462.46, -983.88, 25.79, nil, 88.0, nil, 1581098148}, -- Autos
{ 484.61, -1003.67, 25.73, nil, 1.07, nil, 1581098148}, -- Waffenkammer
{ 471.9, -991.49, 25.73, nil, 3.36, nil, 1581098148}, -- Umkleide
{ 464.95, -986.23, 43.69, nil, 174.0, nil, 1581098148} -- Helicopter
}
Citizen.CreateThread(function()
for _,v in pairs(coordinate) do
RequestModel(v[7])
while not HasModelLoaded(v[7]) do
Wait(1)
end
ped = CreatePed(4, v[7],v[1],v[2],v[3]-1, 3374176, false, true)
SetEntityHeading(ped, v[5])
FreezeEntityPosition(ped, true)
SetEntityInvincible(ped, true)
SetBlockingOfNonTemporaryEvents(ped, true)
end
end)
function setUniform(uniform, playerPed)
TriggerEvent('skinchanger:getSkin', function(skin)
local uniformObject
if skin.sex == 0 then
uniformObject = Config.Uniforms[uniform].male
else
uniformObject = Config.Uniforms[uniform].female
end
if uniformObject then
TriggerEvent('skinchanger:loadClothes', skin, uniformObject)
if uniform == 'bullet_wear' then
SetPedArmour(playerPed, 100)
end
else
ESX.ShowNotification(_U('no_outfit'))
end
end)
end
function OpenCloakroomMenu()
local playerPed = PlayerPedId()
local grade = ESX.PlayerData.job.grade_name
local elements = {
{label = _U('citizen_wear'), value = 'citizen_wear'},
{label = _U('bullet_wear'), uniform = 'bullet_wear'},
{label = _U('gilet_wear'), uniform = 'gilet_wear'},
{label = _U('police_wear'), uniform = grade}
}
if Config.EnableCustomPeds then
for k,v in ipairs(Config.CustomPeds.shared) do
table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel})
end
for k,v in ipairs(Config.CustomPeds[grade]) do
table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel})
end
end
ESX.UI.Menu.CloseAll()
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', {
title = _U('cloakroom'),
align = 'top-left',
elements = elements
}, function(data, menu)
cleanPlayer(playerPed)
if data.current.value == 'citizen_wear' then
if Config.EnableNonFreemodePeds 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 = _U('service_anonunce'),
subject = '',
msg = _U('service_out_announce', GetPlayerName(PlayerId())),
iconType = 1
}
TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')
TriggerServerEvent('esx_service:disableService', 'police')
TriggerEvent('esx_policejob:updateBlip')
ESX.ShowNotification(_U('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
ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount)
if not canTakeService then
ESX.ShowNotification(_U('service_max', inServiceCount, maxInService))
else
awaitService = true
playerInService = true
local notification = {
title = _U('service_anonunce'),
subject = '',
msg = _U('service_in_announce', GetPlayerName(PlayerId())),
iconType = 1
}
TriggerServerEvent('esx_service:notifyAllInService', notification, 'police')
TriggerEvent('esx_policejob:updateBlip')
ESX.ShowNotification(_U('service_in'))
end
end, 'police')
else
awaitService = true
end
end, 'police')
while awaitService == nil do
Citizen.Wait(5)
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 = GetHashKey(data.current.maleModel)
else
modelHash = GetHashKey(data.current.femaleModel)
end
ESX.Streaming.RequestModel(modelHash, function()
SetPlayerModel(PlayerId(), modelHash)
SetModelAsNoLongerNeeded(modelHash)
SetPedDefaultComponentVariation(PlayerPedId())
TriggerEvent('esx:restoreLoadout')
end)
end)
end
end, function(data, menu)
menu.close()
CurrentAction = 'menu_cloakroom'
CurrentActionMsg = _U('open_cloackroom')
CurrentActionData = {}
end)
end
function OpenArmoryMenu(station)
local elements = {
{label = _U('buy_weapons'), value = 'buy_weapons'}
}
if Config.EnableArmoryManagement then
table.insert(elements, {label = _U('get_weapon'), value = 'get_weapon'})
table.insert(elements, {label = _U('put_weapon'), value = 'put_weapon'})
table.insert(elements, {label = _U('remove_object'), value = 'get_stock'})
table.insert(elements, {label = _U('deposit_object'), value = 'put_stock'})
end
ESX.UI.Menu.CloseAll()
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory', {
title = _U('armory'),
align = 'top-left',
elements = elements
}, function(data, menu)
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(data, menu)
menu.close()
CurrentAction = 'menu_armory'
CurrentActionMsg = _U('open_armory')
CurrentActionData = {station = station}
end)
end
function OpenPoliceActionsMenu()
ESX.UI.Menu.CloseAll()
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'police_actions', {
title = 'Police',
align = 'top-left',
elements = {
{label = _U('citizen_interaction'), value = 'citizen_interaction'},
{label = _U('vehicle_interaction'), value = 'vehicle_interaction'},
{label = _U('object_spawner'), value = 'object_spawner'}
}}, function(data, menu)
if data.current.value == 'citizen_interaction' then
local elements = {
{label = _U('billing'), value = 'billing'},
{label = _U('id_card'), value = 'identity_card'},
{label = _U('search'), value = 'search'},
{label = _U('handcuff'), value = 'handcuff'},
{label = _U('drag'), value = 'drag'},
{label = _U('put_in_vehicle'), value = 'put_in_vehicle'},
{label = _U('out_the_vehicle'), value = 'out_the_vehicle'},
{label = _U('fine'), value = 'fine'},
{label = _U('unpaid_bills'), value = 'unpaid_bills'}
}
if Config.EnableLicenses then
table.insert(elements, {label = _U('license_check'), value = 'license'})
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
title = _U('citizen_interaction'),
align = 'top-left',
elements = elements
}, function(data2, menu2)
local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
if closestPlayer ~= -1 and closestDistance <= 3.0 then
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 == 'bills' then
OpenBillsMenu(closestPlayer)
elseif action == 'unpaid_bills' then
OpenUnpaidBillsMenu(closestPlayer)
end
else
ESX.ShowNotification(_U('no_players_nearby'))
end
end, function(data2, menu2)
menu2.close()
end)
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'billing', {
title = _U('invoice_amount')
}, function(data, menu)
local amount = tonumber(data.value)
if amount == nil or amount < 0 then
ESX.ShowNotification(_U('amount_invalid'))
else
local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
if closestPlayer == -1 or closestDistance > 3.0 then
ESX.ShowNotification(_U('no_players_nearby'))
else
menu.close()
TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(closestPlayer), 'society_police', _U('police'), amount)
end
end
end, function(data, menu)
menu.close()
end)
elseif data.current.value == 'vehicle_interaction' then
local elements = {}
local playerPed = PlayerPedId()
local vehicle = ESX.Game.GetVehicleInDirection()
if DoesEntityExist(vehicle) then
table.insert(elements, {label = _U('vehicle_info'), value = 'vehicle_infos'})
table.insert(elements, {label = _U('pick_lock'), value = 'hijack_vehicle'})
table.insert(elements, {label = _U('impound'), value = 'impound'})
end
table.insert(elements, {label = _U('search_database'), value = 'search_database'})
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_interaction', {
title = _U('vehicle_interaction'),
align = 'top-left',
elements = elements
}, function(data2, menu2)
local coords = GetEntityCoords(playerPed)
vehicle = ESX.Game.GetVehicleInDirection()
action = data2.current.value
if action == 'search_database' then
LookupVehicle()
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)
Citizen.Wait(20000)
ClearPedTasksImmediately(playerPed)
SetVehicleDoorsLocked(vehicle, 1)
SetVehicleDoorsLockedForAllPlayers(vehicle, false)
ESX.ShowNotification(_U('vehicle_unlocked'))
end
elseif action == 'impound' then
-- is the script busy?
if currentTask.busy then
return
end
ESX.ShowHelpNotification(_U('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)
Citizen.Wait(100) -- sleep the entire script to let stuff sink back to reality
end)
-- keep track of that vehicle!
Citizen.CreateThread(function()
while currentTask.busy do
Citizen.Wait(1000)
vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71)
if not DoesEntityExist(vehicle) and currentTask.busy then
ESX.ShowNotification(_U('impound_canceled_moved'))
ESX.ClearTimeout(currentTask.task)
ClearPedTasks(playerPed)
currentTask.busy = false
break
end
end
end)
end
else
ESX.ShowNotification(_U('no_vehicles_nearby'))
end
end, function(data2, menu2)
menu2.close()
end)
elseif data.current.value == 'object_spawner' then
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
title = _U('traffic_interaction'),
align = 'top-left',
elements = {
{label = _U('cone'), model = 'prop_roadcone02a'},
{label = _U('barrier'), model = 'prop_barrier_work05'},
{label = _U('betonbarrier'), model = 'prop_mp_barrier_01'},
{label = _U('spikestrips'), model = 'p_ld_stinger_s'},
}}, function(data2, menu2)
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)
SetEntityHeading(obj, GetEntityHeading(playerPed))
PlaceObjectOnGroundProperly(obj)
end)
end, function(data2, menu2)
menu2.close()
end)
end
end, function(data, menu)
menu.close()
end)
end
function OpenIdentityCardMenu(player)
ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data)
local elements = {
{label = _U('name', data.name)},
{label = _U('job', ('%s - %s'):format(data.job, data.grade))}
}
if Config.EnableESXIdentity then
table.insert(elements, {label = _U('sex', _U(data.sex))})
table.insert(elements, {label = _U('dob', data.dob)})
table.insert(elements, {label = _U('height', data.height)})
end
if data.drunk then
table.insert(elements, {label = _U('bac', data.drunk)})
end
if data.licenses then
table.insert(elements, {label = _U('license_label')})
for i=1, #data.licenses, 1 do
table.insert(elements, {label = data.licenses[i].label})
end
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', {
title = _U('citizen_interaction'),
align = 'top-left',
elements = elements
}, nil, function(data, menu)
menu.close()
end)
end, GetPlayerServerId(player))
end
function OpenBodySearchMenu(player)
ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data)
local elements = {}
for i=1, #data.accounts, 1 do
if data.accounts[i].name == 'black_money' and data.accounts[i].money > 0 then
table.insert(elements, {
label = _U('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 = _U('guns_label')})
for i=1, #data.weapons, 1 do
table.insert(elements, {
label = _U('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
table.insert(elements, {label = _U('inventory_label')})
for i=1, #data.inventory, 1 do
if data.inventory[i].count > 0 then
table.insert(elements, {
label = _U('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.UI.Menu.Open('default', GetCurrentResourceName(), 'body_search', {
title = _U('search'),
align = 'top-left',
elements = elements
}, function(data, menu)
if data.current.value then
TriggerServerEvent('esx_policejob:confiscatePlayerItem', GetPlayerServerId(player), data.current.itemType, data.current.value, data.current.amount)
OpenBodySearchMenu(player)
end
end, function(data, menu)
menu.close()
end)
end, GetPlayerServerId(player))
end
function OpenFineMenu(player)
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine', {
title = _U('fine'),
align = 'top-left',
elements = {
{label = _U('traffic_offense'), value = 0},
{label = _U('minor_offense'), value = 1},
{label = _U('average_offense'), value = 2},
{label = _U('major_offense'), value = 3}
}}, function(data, menu)
OpenFineCategoryMenu(player, data.current.value)
end, function(data, menu)
menu.close()
end)
end
function OpenFineCategoryMenu(player, category)
ESX.TriggerServerCallback('esx_policejob:getFineList', function(fines)
local elements = {}
for k,fine in ipairs(fines) do
table.insert(elements, {
label = ('%s <span style="color:green;">%s</span>'):format(fine.label, _U('armory_item', ESX.Math.GroupDigits(fine.amount))),
value = fine.id,
amount = fine.amount,
fineLabel = fine.label
})
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine_category', {
title = _U('fine'),
align = 'top-left',
elements = elements
}, function(data, menu)
menu.close()
if Config.EnablePlayerManagement then
TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', _U('fine_total', data.current.fineLabel), data.current.amount)
else
TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', _U('fine_total', data.current.fineLabel), data.current.amount)
end
ESX.SetTimeout(300, function()
OpenFineCategoryMenu(player, category)
end)
end, function(data, menu)
menu.close()
end)
end, category)
end
function LookupVehicle()
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'lookup_vehicle', {
title = _U('search_database_title'),
}, function(data, menu)
local length = string.len(data.value)
if not data.value or length < 2 or length > 8 then
ESX.ShowNotification(_U('search_database_error_invalid'))
else
ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo)
local elements = {{label = _U('plate', retrivedInfo.plate)}}
menu.close()
if not retrivedInfo.owner then
table.insert(elements, {label = _U('owner_unknown')})
else
table.insert(elements, {label = _U('owner', retrivedInfo.owner)})
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', {
title = _U('vehicle_info'),
align = 'top-left',
elements = elements
}, nil, function(data2, menu2)
menu2.close()
end)
end, data.value)
end
end, function(data, menu)
menu.close()
end)
end
function ShowPlayerLicense(player)
local elements = {}
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
table.insert(elements, {
label = playerData.licenses[i].label,
type = playerData.licenses[i].type
})
end
end
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', {
title = _U('license_revoke'),
align = 'top-left',
elements = elements,
}, function(data, menu)
ESX.ShowNotification(_U('licence_you_revoked', data.current.label, playerData.name))
TriggerServerEvent('esx_policejob:message', GetPlayerServerId(player), _U('license_revoked', data.current.label))
TriggerServerEvent('esx_license:removeLicense', GetPlayerServerId(player), data.current.type)
ESX.SetTimeout(300, function()
ShowPlayerLicense(player)
end)
end, function(data, menu)
menu.close()
end)
end, GetPlayerServerId(player))
end
function OpenUnpaidBillsMenu(player)
local elements = {}
ESX.TriggerServerCallback('esx_billing:getTargetBills', function(bills)
for k,bill in ipairs(bills) do
table.insert(elements, {
label = ('%s - <span style="color:red;">%s</span>'):format(bill.label, _U('armory_item', ESX.Math.GroupDigits(bill.amount))),
billId = bill.id
})
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', {
title = _U('unpaid_bills'),
align = 'top-left',
elements = elements
}, nil, function(data, menu)
menu.close()
end)
end, GetPlayerServerId(player))
end
function OpenVehicleInfosMenu(vehicleData)
ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo)
local elements = {{label = _U('plate', retrivedInfo.plate)}}
if not retrivedInfo.owner then
table.insert(elements, {label = _U('owner_unknown')})
else
table.insert(elements, {label = _U('owner', retrivedInfo.owner)})
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', {
title = _U('vehicle_info'),
align = 'top-left',
elements = elements
}, nil, function(data, menu)
menu.close()
end)
end, vehicleData.plate)
end
function OpenGetWeaponMenu()
ESX.TriggerServerCallback('esx_policejob:getArmoryWeapons', function(weapons)
local elements = {}
for i=1, #weapons, 1 do
if weapons[i].count > 0 then
table.insert(elements, {
label = 'x' .. weapons[i].count .. ' ' .. ESX.GetWeaponLabel(weapons[i].name),
value = weapons[i].name
})
end
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_get_weapon', {
title = _U('get_weapon_menu'),
align = 'top-left',
elements = elements
}, function(data, menu)
menu.close()
ESX.TriggerServerCallback('esx_policejob:removeArmoryWeapon', function()
OpenGetWeaponMenu()
end, data.current.value)
end, function(data, menu)
menu.close()
end)
end)
end
function OpenPutWeaponMenu()
local elements = {}
local playerPed = PlayerPedId()
local weaponList = ESX.GetWeaponList()
for i=1, #weaponList, 1 do
local weaponHash = GetHashKey(weaponList[i].name)
if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then
table.insert(elements, {
label = weaponList[i].label,
value = weaponList[i].name
})
end
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_put_weapon', {
title = _U('put_weapon_menu'),
align = 'top-left',
elements = elements
}, function(data, menu)
menu.close()
ESX.TriggerServerCallback('esx_policejob:addArmoryWeapon', function()
OpenPutWeaponMenu()
end, data.current.value, true)
end, function(data, menu)
menu.close()
end)
end
function OpenBuyWeaponsMenu()
local elements = {}
local playerPed = PlayerPedId()
for k,v in ipairs(Config.AuthorizedWeapons[ESX.PlayerData.job.grade_name]) do
local weaponNum, weapon = ESX.GetWeapon(v.weapon)
local components, label = {}
local hasWeapon = HasPedGotWeapon(playerPed, GetHashKey(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, GetHashKey(v.weapon), component.hash)
if hasComponent then
label = ('%s: <span style="color:green;">%s</span>'):format(component.label, _U('armory_owned'))
else
if v.components[i] > 0 then
label = ('%s: <span style="color:green;">%s</span>'):format(component.label, _U('armory_item', ESX.Math.GroupDigits(v.components[i])))
else
label = ('%s: <span style="color:green;">%s</span>'):format(component.label, _U('armory_free'))
end
end
table.insert(components, {
label = 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: <span style="color:green;">></span>'):format(weapon.label)
elseif hasWeapon and not v.components then
label = ('%s: <span style="color:green;">%s</span>'):format(weapon.label, _U('armory_owned'))
else
if v.price > 0 then
label = ('%s: <span style="color:green;">%s</span>'):format(weapon.label, _U('armory_item', ESX.Math.GroupDigits(v.price)))
else
label = ('%s: <span style="color:green;">%s</span>'):format(weapon.label, _U('armory_free'))
end
end
table.insert(elements, {
label = label,
weaponLabel = weapon.label,
name = weapon.name,
components = components,
price = v.price,
hasWeapon = hasWeapon
})
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons', {
title = _U('armory_weapontitle'),
align = 'top-left',
elements = elements
}, function(data, menu)
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(_U('armory_bought', data.current.weaponLabel, ESX.Math.GroupDigits(data.current.price)))
end
menu.close()
OpenBuyWeaponsMenu()
else
ESX.ShowNotification(_U('armory_money'))
end
end, data.current.name, 1)
end
end, function(data, menu)
menu.close()
end)
end
function OpenWeaponComponentShop(components, weaponName, parentShop)
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons_components', {
title = _U('armory_componenttitle'),
align = 'top-left',
elements = components
}, function(data, menu)
if data.current.hasComponent then
ESX.ShowNotification(_U('armory_hascomponent'))
else
ESX.TriggerServerCallback('esx_policejob:buyWeapon', function(bought)
if bought then
if data.current.price > 0 then
ESX.ShowNotification(_U('armory_bought', data.current.componentLabel, ESX.Math.GroupDigits(data.current.price)))
end
menu.close()
parentShop.close()
OpenBuyWeaponsMenu()
else
ESX.ShowNotification(_U('armory_money'))
end
end, weaponName, 2, data.current.componentNum)
end
end, function(data, menu)
menu.close()
end)
end
function OpenGetStocksMenu()
ESX.TriggerServerCallback('esx_policejob:getStockItems', function(items)
local elements = {}
for i=1, #items, 1 do
table.insert(elements, {
label = 'x' .. items[i].count .. ' ' .. items[i].label,
value = items[i].name
})
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', {
title = _U('police_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 = _U('quantity')
}, function(data2, menu2)
local count = tonumber(data2.value)
if not count then
ESX.ShowNotification(_U('quantity_invalid'))
else
menu2.close()
menu.close()
TriggerServerEvent('esx_policejob:getStockItem', itemName, count)
Citizen.Wait(300)
OpenGetStocksMenu()
end
end, function(data2, menu2)
menu2.close()
end)
end, function(data, menu)
menu.close()
end)
end)
end
function OpenPutStocksMenu()
ESX.TriggerServerCallback('esx_policejob:getPlayerInventory', function(inventory)
local elements = {}
for i=1, #inventory.items, 1 do
local item = inventory.items[i]
if item.count > 0 then
table.insert(elements, {
label = item.label .. ' x' .. item.count,
type = 'item_standard',
value = item.name
})
end
end
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', {
title = _U('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 = _U('quantity')
}, function(data2, menu2)
local count = tonumber(data2.value)
if not count then
ESX.ShowNotification(_U('quantity_invalid'))
else
menu2.close()
menu.close()
TriggerServerEvent('esx_policejob:putStockItems', itemName, count)
Citizen.Wait(300)
OpenPutStocksMenu()
end
end, function(data2, menu2)
menu2.close()
end)
end, function(data, menu)
menu.close()
end)
end)
end
RegisterNetEvent('esx:setJob')
AddEventHandler('esx:setJob', function(job)
ESX.PlayerData.job = job
Citizen.Wait(5000)
TriggerServerEvent('esx_policejob:forceBlip')
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/PoW66EYAAAjGSURBVHjapJcLcFTV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'
}
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
end)
AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum)
if part == 'Cloakroom' then
CurrentAction = 'menu_cloakroom'
CurrentActionMsg = _U('open_cloackroom')
CurrentActionData = {}
elseif part == 'Armory' then
CurrentAction = 'menu_armory'
CurrentActionMsg = _U('open_armory')
CurrentActionData = {station = station}
elseif part == 'Vehicles' then
CurrentAction = 'menu_vehicle_spawner'
CurrentActionMsg = _U('garage_prompt')
CurrentActionData = {station = station, part = part, partNum = partNum}
elseif part == 'Helicopters' then
CurrentAction = 'Helicopters'
CurrentActionMsg = _U('helicopter_prompt')
CurrentActionData = {station = station, part = part, partNum = partNum}
elseif part == 'BossActions' then
CurrentAction = 'menu_boss_actions'
CurrentActionMsg = _U('open_bossmenu')
CurrentActionData = {}
end
end)
AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum)
if not isInShopMenu then
ESX.UI.Menu.CloseAll()
end
CurrentAction = nil
end)
AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity)
local playerPed = PlayerPedId()
if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then
CurrentAction = 'remove_entity'
CurrentActionMsg = _U('remove_prop')
CurrentActionData = {entity = entity}
end
if GetEntityModel(entity) == GetHashKey('p_ld_stinger_s') then
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
if IsPedInAnyVehicle(playerPed, false) then
local vehicle = GetVehiclePedIsIn(playerPed)
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
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
Citizen.Wait(100)
end
TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0)
SetEnableHandcuffs(playerPed, true)
DisablePlayerFiring(playerPed, true)
SetCurrentPedWeapon(playerPed, GetHashKey('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
end)
RegisterNetEvent('esx_policejob:drag')
AddEventHandler('esx_policejob:drag', function(copId)
if isHandcuffed then
dragStatus.isDragged = not dragStatus.isDragged
dragStatus.CopId = copId
end
end)
Citizen.CreateThread(function()
local wasDragged
while true do
Citizen.Wait(0)
local playerPed = PlayerPedId()
if isHandcuffed and dragStatus.isDragged then
local targetPed = GetPlayerPed(GetPlayerFromServerId(dragStatus.CopId))
if DoesEntityExist(targetPed) and IsPedOnFoot(targetPed) and not IsPedDeadOrDying(targetPed, true) then
if not wasDragged then
AttachEntityToEntity(playerPed, targetPed, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true)
wasDragged = true
else
Citizen.Wait(1000)
end
else
wasDragged = false
dragStatus.isDragged = false
DetachEntity(playerPed, true, false)
end
elseif wasDragged then
wasDragged = false
DetachEntity(playerPed, true, false)
else
Citizen.Wait(500)
end
end
end)
RegisterNetEvent('esx_policejob:putInVehicle')
AddEventHandler('esx_policejob:putInVehicle', function()
if isHandcuffed then
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
if IsAnyVehicleNearPoint(coords, 5.0) then
local vehicle = GetClosestVehicle(coords, 5.0, 0, 71)
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)
dragStatus.isDragged = false
end
end
end
end
end)
RegisterNetEvent('esx_policejob:OutVehicle')
AddEventHandler('esx_policejob:OutVehicle', function()
local playerPed = PlayerPedId()
if IsPedSittingInAnyVehicle(playerPed) then
local vehicle = GetVehiclePedIsIn(playerPed, false)
TaskLeaveVehicle(playerPed, vehicle, 16)
end
end)
-- Handcuff
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
local playerPed = PlayerPedId()
if isHandcuffed then
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(playerPed, 'mp_arresting', 'idle', 3) ~= 1 then
ESX.Streaming.RequestAnimDict('mp_arresting', function()
TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0.0, false, false, false)
end)
end
else
Citizen.Wait(500)
end
end
end)
-- Create blips
Citizen.CreateThread(function()
for k,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(_U('map_blip'))
EndTextCommandSetBlipName(blip)
end
end)
-- Draw markers and more
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local isInMarker, hasExited, letSleep = false, false, true
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(20, 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)
letSleep = false
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(21, 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)
letSleep = false
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(36, 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)
letSleep = false
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(34, 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)
letSleep = false
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(22, 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)
letSleep = false
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
if letSleep then
Citizen.Wait(500)
end
else
Citizen.Wait(500)
end
end
end)
-- Enter / Exit entity zone events
Citizen.CreateThread(function()
local trackedEntities = {
'prop_roadcone02a',
'prop_barrier_work05',
'p_ld_stinger_s',
'prop_mp_barrier_01',
}
while true do
Citizen.Wait(500)
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
local closestDistance = -1
local closestEntity = nil
for i=1, #trackedEntities, 1 do
local object = GetClosestObjectOfType(playerCoords, 3.0, GetHashKey(trackedEntities[i]), false, false, false)
if DoesEntityExist(object) then
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
end
end)
-- Key Controls
Citizen.CreateThread(function()
while true do
Citizen.Wait(0)
if CurrentAction then
ESX.ShowHelpNotification(CurrentActionMsg)
if IsControlJustReleased(0, 38) and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then
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(_U('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(_U('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(_U('service_not'))
end
elseif CurrentAction == 'delete_vehicle' then
ESX.Game.DeleteVehicle(CurrentActionData.vehicle)
elseif CurrentAction == 'menu_boss_actions' then
ESX.UI.Menu.CloseAll()
TriggerEvent('esx_society:openBossMenu', 'police', function(data, menu)
menu.close()
CurrentAction = 'menu_boss_actions'
CurrentActionMsg = _U('open_bossmenu')
CurrentActionData = {}
end, { wash = false }) -- disable washing money
elseif CurrentAction == 'remove_entity' then
DeleteEntity(CurrentActionData.entity)
end
CurrentAction = nil
end
end -- CurrentAction end
if IsControlJustReleased(0, 167) and not isDead and ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions') then
if not Config.EnableESXService then
OpenPoliceActionsMenu()
elseif playerInService then
OpenPoliceActionsMenu()
else
ESX.ShowNotification(_U('service_not'))
end
end
if IsControlJustReleased(0, 38) and currentTask.busy then
ESX.ShowNotification(_U('impound_canceled'))
ESX.ClearTimeout(currentTask.task)
ClearPedTasks(PlayerPedId())
currentTask.busy = false
end
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
end
RegisterNetEvent('esx_policejob:updateBlip')
AddEventHandler('esx_policejob:updateBlip', function()
-- Refresh all blips
for k, 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('playerSpawned', function(spawn)
isDead = false
TriggerEvent('esx_policejob:unrestrain')
if not hasAlreadyJoined then
TriggerServerEvent('esx_policejob:spawned')
end
hasAlreadyJoined = true
end)
AddEventHandler('esx:onPlayerDeath', function(data)
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
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
handcuffTimer.active = true
handcuffTimer.task = ESX.SetTimeout(Config.HandcuffTimer, function()
ESX.ShowNotification(_U('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)
--local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(vehicle)))
ESX.Game.DeleteVehicle(vehicle)
ESX.ShowNotification(_U('impound_successful'))
currentTask.busy = false
end
Alles anzeigen