From 1f9d2396f05145a145a021ff6e981e88e4dff293 Mon Sep 17 00:00:00 2001
From: bitpredator <67551273+bitpredator@users.noreply.github.com>
Date: Tue, 17 Dec 2024 20:32:26 +0100
Subject: [PATCH] refactor: armory work reconstruction
---
.../[bpt_addons]/bpt_ammujob/bpt_ammujob.sql | 2 +-
.../[bpt_addons]/bpt_ammujob/client/main.lua | 1304 +++++++++++++----
.../bpt_ammujob/client/vehicle.lua | 320 ++++
.../[bpt_addons]/bpt_ammujob/config.lua | 113 +-
.../[bpt_addons]/bpt_ammujob/fxmanifest.lua | 29 +-
.../[bpt_addons]/bpt_ammujob/locales/en.lua | 178 ++-
.../[bpt_addons]/bpt_ammujob/locales/it.lua | 177 ++-
.../localization/bpt_ammujob_it.sql | 2 +-
.../[bpt_addons]/bpt_ammujob/server/main.lua | 418 +++++-
9 files changed, 2120 insertions(+), 423 deletions(-)
create mode 100644 server-data/resources/[bpt_addons]/bpt_ammujob/client/vehicle.lua
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/bpt_ammujob.sql b/server-data/resources/[bpt_addons]/bpt_ammujob/bpt_ammujob.sql
index c95753506..a35152c03 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/bpt_ammujob.sql
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/bpt_ammujob.sql
@@ -20,4 +20,4 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_
('ammu',2,'armorychief','Armory Chief',60,'{}','{}'),
('ammu',3,'deputydirector','Deputy Director',85,'{}','{}'),
('ammu',4,'boss','Boss',100,'{}','{}')
-;
+;
\ No newline at end of file
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 7d8112936..2191b7c78 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/client/main.lua
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/client/main.lua
@@ -1,378 +1,1174 @@
-local HasAlreadyEnteredMarker
-local CurrentAction, CurrentActionMsg, CurrentActionData = nil, "", {}
-local LastZone
-
-RegisterNetEvent("esx:playerLoaded")
-AddEventHandler("esx:playerLoaded", function(xPlayer)
- ESX.PlayerData = xPlayer
- ESX.PlayerLoaded = true
-end)
-
-RegisterNetEvent("esx:onPlayerLogout")
-AddEventHandler("esx:onPlayerLogout", function()
- ESX.PlayerLoaded = false
- ESX.PlayerData = {}
-end)
+---@diagnostic disable: undefined-global
-RegisterNetEvent("esx:setJob")
-AddEventHandler("esx:setJob", function(job)
- ESX.PlayerData.job = job
-end)
+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
-function DrawSub(msg, time)
- ClearPrints()
- BeginTextCommandPrint("STRING")
- AddTextComponentSubstringPlayerName(msg)
- EndTextCommandPrint(time, true)
+function CleanPlayer(playerPed)
+ SetPedArmour(playerPed, 0)
+ ClearPedBloodDamage(playerPed)
+ ResetPedVisibleDamage(playerPed)
+ ClearPedLastWeaponDamage(playerPed)
+ ResetPedMovementClipset(playerPed, 0)
end
-function ShowLoadingPromt(msg, time, type)
- CreateThread(function()
- Wait(0)
+function OpenArmoryMenu(station)
+ local elements
+ if Config.OxInventory then
+ exports.ox_inventory:openInventory("stash", { id = "society_ammu", 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" },
+ }
- BeginTextCommandBusyspinnerOn("STRING")
- AddTextComponentSubstringPlayerName(msg)
- EndTextCommandBusyspinnerOn(type)
- Wait(time)
+ 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
- BusyspinnerOff()
+ 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 == "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 OpenCloakroom()
+function OpenAmmuActionsMenu()
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-ammu", 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" },
}
- ESX.OpenContext("right", elements, function(_, element)
- if element.value == "wear_citizen" then
- ESX.TriggerServerCallback("esx_skin:getPlayerSkin", function(skin)
- TriggerEvent("skinchanger:loadSkin", skin)
+ 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("weapon"), value = "weapon" },
+ }
+
+ 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_cuffanimation:startArrest", GetPlayerServerId(closestPlayer))
+ Citizen.Wait(3100)
+ TriggerServerEvent("bpt_ammujob:handcuff", GetPlayerServerId(closestPlayer))
+ elseif action == "drag" then
+ TriggerServerEvent("bpt_ammujob:drag", GetPlayerServerId(closestPlayer))
+ elseif action == "put_in_vehicle" then
+ TriggerServerEvent("bpt_ammujob:putInVehicle", GetPlayerServerId(closestPlayer))
+ elseif action == "out_the_vehicle" then
+ TriggerServerEvent("bpt_ammujob:OutVehicle", GetPlayerServerId(closestPlayer))
+ elseif action == "fine" then
+ OpenFineMenu(closestPlayer)
+ elseif action == "weapon" then
+ TriggerServerEvent("esx_license:addLicense", GetPlayerServerId(closestPlayer), "weapon")
+ ESX.ShowNotification(TranslateCap("released_gun_licence"))
+ TriggerServerEvent("bpt_ammujob:message", GetPlayerServerId(closestDistance), TranslateCap("received_firearms_license"))
+ elseif action == "license" then
+ ShowPlayerLicense(closestPlayer)
+ end
+ else
+ ESX.ShowNotification(TranslateCap("no_players_nearby"))
+ end
+ end, function()
+ OpenAmmuActionsMenu()
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)
+ 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()
+ local 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
- TriggerEvent("skinchanger:loadClothes", skin, jobSkin.skin_female)
+ ESX.ShowNotification(TranslateCap("no_vehicles_nearby"))
end
+ end, function()
+ OpenAmmuActionsMenu()
+ end)
+ elseif data.current.value == "object_spawner" then
+
+ 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()
+ OpenAmmuActionsMenu()
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") },
- }
+function OpenIdentityCardMenu(player)
+ ESX.TriggerServerCallback("bpt_ammujob: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.EnableSocietyOwnedVehicles then
- ESX.TriggerServerCallback("bpt_society:getVehiclesInGarage", function(vehicles)
- if #vehicles == 0 then
- ESX.ShowNotification(TranslateCap("empty_garage"))
- return
- end
+ 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
- for i = 1, #vehicles, 1 do
- elements[#elements + 1] = {
- icon = "fas fa-car",
- title = GetDisplayNameFromVehicleModel(vehicles[i].model) .. " [" .. vehicles[i].plate .. "]",
- value = vehicles[i],
- }
+ 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, function(_, element)
- if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then
- ESX.ShowNotification(TranslateCap("spawnpoint_blocked"))
- return
- end
+ ESX.OpenContext("right", elements, nil, function(menu)
+ OpenAmmuActionsMenu()
+ end)
+ end, GetPlayerServerId(player))
+end
- if element.value == nil then
- print("ERROR: Context menu clicked item value is nil!")
- return
- end
+function OpenBodySearchMenu(player)
+ if Config.OxInventory then
+ ESX.CloseContext()
+ exports.ox_inventory:openInventory("player", GetPlayerServerId(player))
+ return
+ end
- local vehicleProps = element.value
- ESX.TriggerServerCallback("bpt_ammujob:SpawnVehicle", function()
- return
- end, vehicleProps.model, vehicleProps)
- TriggerServerEvent("bpt_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
+ ESX.TriggerServerCallback("bpt_ammujob: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
- for i = 1, #Config.AuthorizedVehicles, 1 do
+ table.insert(elements, { label = TranslateCap("guns_label") })
+
+ for i = 1, #data.weapons, 1 do
elements[#elements + 1] = {
- icon = "fas fa-car",
- title = Config.AuthorizedVehicles[i].label,
- value = Config.AuthorizedVehicles[i].model,
+ 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
- ESX.OpenContext("right", elements, function(_, element)
- if not ESX.Game.IsSpawnPointClear(Config.Zones.VehicleSpawnPoint.Pos, 5.0) then
- ESX.ShowNotification(TranslateCap("spawnpoint_blocked"))
- return
+ 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
- if element.value == nil then
- print("ERROR: Context menu clicked item value is nil!")
- return
+ ESX.OpenContext("right", elements, function(_, element)
+ data = { current = element }
+ if data.current.value then
+ TriggerServerEvent("bpt_ammujob:confiscatePlayerItem", GetPlayerServerId(player), data.current.itemType, data.current.value, data.current.amount)
+ OpenBodySearchMenu(player)
end
+ end)
+ end, GetPlayerServerId(player))
+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 = {}
+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(_, element)
+ local data = { current = element }
+ OpenFineCategoryMenu(player, data.current.value)
end)
+ else
+ ESX.CloseContext()
+ ESX.CloseContext()
+ OpenFineTextInput(player)
end
end
-function DeleteJobVehicle()
- if Config.EnableSocietyOwnedVehicles then
- local vehicleProps = ESX.Game.GetVehicleProperties(CurrentActionData.vehicle)
- TriggerServerEvent("bpt_society:putVehicleInGarage", "ammu", vehicleProps)
- ESX.Game.DeleteVehicle(CurrentActionData.vehicle)
- else
- if IsInAuthorizedVehicle() then
- ESX.Game.DeleteVehicle(CurrentActionData.vehicle)
+local fineList = {}
+function OpenFineCategoryMenu(player, category)
+ if not fineList[category] then
+ local p = promise.new()
- if Config.MaxInService ~= -1 then
- TriggerServerEvent("esx_service:disableService", "ammu")
- end
- else
- ESX.ShowNotification(TranslateCap("only_ammu"))
- end
+ ESX.TriggerServerCallback("bpt_ammujob:getFineList", function(fines)
+ p:resolve(fines)
+ end, category)
+
+ fineList[category] = Citizen.Await(p)
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" },
+ { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("fine") },
}
- if Config.EnablePlayerManagement and ESX.PlayerData.job ~= nil and ESX.PlayerData.job.grade_name == "boss" then
+ for _, fine in ipairs(fineList[category]) do
elements[#elements + 1] = {
- icon = "fas fa-wallet",
- title = TranslateCap("boss_actions"),
- value = "boss_actions",
+ 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(_, 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("bpt_society:openBossMenu", "ammu", function(_, menu)
- menu.close()
+ ESX.OpenContext("right", elements, function(menu, element)
+ local data = { current = element }
+ if Config.EnablePlayerManagement then
+ TriggerServerEvent("bpt_billing:sendBill", GetPlayerServerId(player), "society_ammu", 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("bpt_billing:sendBill", GetPlayerServerId(player), "society_ammu", reason, amount)
+ OpenAmmuActionsMenu()
+ 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("bpt_ammujob:getVehicleInfos", function(retrivedInfo)
+ 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()
+ OpenAmmuActionsMenu()
+ end)
+ end, data.value)
+ end
+ end)
+end
+
+function ShowPlayerLicense(player)
+ local elements = {
+ { unselectable = true, icon = "fas fa-scroll", title = TranslateCap("license_revoke") },
+ }
+
+ ESX.TriggerServerCallback("bpt_ammujob: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("bpt_ammujob: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 OpenVehicleInfosMenu(vehicleData)
+ ESX.TriggerServerCallback("bpt_ammujob: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
- end, function()
- CurrentAction = "ammu_actions_menu"
- CurrentActionMsg = TranslateCap("press_to_open")
- CurrentActionData = {}
+
+ ESX.OpenContext("right", elements, nil, nil)
+ end, vehicleData.plate)
+end
+
+function OpenGetWeaponMenu()
+ ESX.TriggerServerCallback("bpt_ammujob: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("bpt_ammujob:removeArmoryWeapon", function()
+ ESX.CloseContext()
+ OpenGetWeaponMenu()
+ end, data.current.value)
+ end)
end)
end
-function OpenMobileAmmuActionsMenu()
+function OpenPutWeaponMenu()
local elements = {
- { unselectable = true, icon = "fas fa-ammu", title = TranslateCap("ammu") },
- { icon = "fas fa-scroll", title = TranslateCap("billing"), value = "billing" },
+ { 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("bpt_ammujob:addArmoryWeapon", function()
+ ESX.CloseContext()
+ OpenPutWeaponMenu()
+ end, data.current.value, true)
+ end)
+end
+
+function OpenGetStocksMenu()
+ ESX.TriggerServerCallback("bpt_ammujob:getStockItems", function(items)
+ local elements = {
+ { unselectable = true, icon = "fas fa-box", title = TranslateCap("ammu_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
- ESX.OpenContext("right", elements, function(_, element)
- if element.value == "billing" then
local elements2 = {
- { unselectable = true, icon = "fas fa-ammu", title = element.title },
+ { unselectable = true, icon = "fas fa-box", title = element.title },
{
- title = TranslateCap("amount"),
+ title = TranslateCap("quantity"),
input = true,
inputType = "number",
inputMin = 1,
- inputMax = 10000000,
- inputPlaceholder = TranslateCap("bill_amount"),
+ inputMax = 150,
+ inputPlaceholder = TranslateCap("quantity_placeholder"),
},
{ 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"))
+ 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()
- 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
+ TriggerServerEvent("bpt_ammujob:getStockItem", itemName, count)
+
+ Wait(300)
+ OpenGetStocksMenu()
end
end)
+ end)
+ end)
+end
+
+function OpenPutStocksMenu()
+ ESX.TriggerServerCallback("bpt_ammujob: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("bpt_ammujob:putStockItems", itemName, count)
+
+ Wait(300)
+ OpenPutStocksMenu()
+ end
+ end)
+ end)
end)
end
-function IsInAuthorizedVehicle()
+AddEventHandler("bpt_ammujob:hasEnteredMarker", function(station, part, partNum)
+ if 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 == "BossActions" then
+ CurrentAction = "menu_boss_actions"
+ CurrentActionMsg = TranslateCap("open_bossmenu")
+ CurrentActionData = {}
+ end
+end)
+
+AddEventHandler("bpt_ammujob:hasExitedMarker", function(station, part, partNum)
+ if not IsInShopMenu then
+ ESX.CloseContext()
+ end
+
+ CurrentAction = nil
+end)
+
+AddEventHandler("bpt_ammujob:hasEnteredEntityZone", function(entity)
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
+ if ESX.PlayerData.job and ESX.PlayerData.job.name == "ammu" and IsPedOnFoot(playerPed) then
+ CurrentAction = "remove_entity"
+ CurrentActionMsg = TranslateCap("remove_prop")
+ CurrentActionData = { entity = entity }
+ end
+
+ if GetEntityModel(entity) == `p_ld_stinger_s` then
+ playerPed = PlayerPedId()
+ local _ = 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)
- return false
-end
+AddEventHandler("bpt_ammujob:hasExitedEntityZone", function(entity)
+ if CurrentAction == "remove_entity" then
+ CurrentAction = nil
+ end
+end)
-AddEventHandler("bpt_ammujob:hasEnteredMarker", function(zone)
- if zone == "VehicleSpawner" then
- CurrentAction = "vehicle_spawner"
- CurrentActionMsg = TranslateCap("spawner_prompt")
- CurrentActionData = {}
- elseif zone == "VehicleDeleter" then
+RegisterNetEvent("bpt_ammujob:handcuff")
+AddEventHandler("bpt_ammujob: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
+end)
+
+RegisterNetEvent("bpt_ammujob:unrestrain")
+AddEventHandler("bpt_ammujob:unrestrain", function()
+ if isHandcuffed then
local playerPed = PlayerPedId()
- local vehicle = GetVehiclePedIsIn(playerPed, false)
+ isHandcuffed = false
- if IsPedInAnyVehicle(playerPed, false) and GetPedInVehicleSeat(vehicle, -1) == playerPed then
- CurrentAction = "delete_vehicle"
- CurrentActionMsg = TranslateCap("store_veh")
- CurrentActionData = {
- vehicle = vehicle,
- }
+ 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
- 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
+RegisterNetEvent("bpt_ammujob:drag")
+AddEventHandler("bpt_ammujob:drag", function(copId)
+ 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
+end)
+
+RegisterNetEvent("bpt_ammujob:putInVehicle")
+AddEventHandler("bpt_ammujob: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
+end)
+
+RegisterNetEvent("bpt_ammujob:OutVehicle")
+AddEventHandler("bpt_ammujob: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
+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
end)
--- Create Blips
+-- Create blips
CreateThread(function()
- local blip = AddBlipForCoord(Config.Zones.AmmuActions.Pos.x, Config.Zones.AmmuActions.Pos.y, Config.Zones.AmmuActions.Pos.z)
+ for _, v in pairs(Config.Ammu) do
+ local blip = AddBlipForCoord(v.Blip.Coords)
- SetBlipSprite(blip, 156)
- SetBlipDisplay(blip, 4)
- SetBlipScale(blip, 1.0)
- SetBlipColour(blip, 5)
- SetBlipAsShortRange(blip, true)
+ 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("blip_ammu"))
- EndTextCommandSetBlipName(blip)
+ BeginTextCommandSetBlipName("STRING")
+ AddTextComponentSubstringPlayerName(TranslateCap("map_blip"))
+ EndTextCommandSetBlipName(blip)
+ end
end)
--- Enter / Exit marker events, and draw markers
+-- Draw markers and more
CreateThread(function()
while true do
- local sleep = 1500
+ 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(), 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 == "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)
+ Sleep = 500
+ local playerPed = PlayerPedId()
+ local playerCoords = GetEntityCoords(playerPed)
+ local isInMarker, hasExited = false, false
+ local currentStation, currentPart, currentPartNum
+
+ for k, v in pairs(Config.Ammu) do
+
+ 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
- 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
+ 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 LastZone ~= currentZone) then
- HasAlreadyEnteredMarker, LastZone = true, currentZone
- TriggerEvent("bpt_ammujob:hasEnteredMarker", currentZone)
+ 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("bpt_ammujob:hasExitedMarker", LastStation, LastPart, LastPartNum)
+ hasExited = true
+ end
+
+ HasAlreadyEnteredMarker = true
+ LastStation = currentStation
+ LastPart = currentPart
+ LastPartNum = currentPartNum
+
+ TriggerEvent("bpt_ammujob:hasEnteredMarker", currentStation, currentPart, currentPartNum)
end
- if not isInMarker and HasAlreadyEnteredMarker then
+ if not hasExited and not isInMarker and HasAlreadyEnteredMarker then
HasAlreadyEnteredMarker = false
- TriggerEvent("bpt_ammujob:hasExitedMarker", LastZone)
+ TriggerEvent("bpt_ammujob:hasExitedMarker", LastStation, LastPart, LastPartNum)
end
end
- Wait(sleep)
+ Wait(Sleep)
end
end)
--- Key Controls
+-- 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
- if CurrentAction and not ESX.PlayerData.dead then
- sleep = 0
- ESX.ShowHelpNotification(CurrentActionMsg)
+ local Sleep = 1500
- 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()
+ 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
- CurrentAction = nil
+ if closestDistance ~= -1 and closestDistance <= 3.0 then
+ if LastEntity ~= closestEntity then
+ TriggerEvent("bpt_ammujob:hasEnteredEntityZone", closestEntity)
+ LastEntity = closestEntity
+ end
+ else
+ if LastEntity then
+ TriggerEvent("bpt_ammujob:hasExitedEntityZone", LastEntity)
+ LastEntity = nil
end
end
- Wait(sleep)
+ 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()
+ESX.RegisterInput("ammu:interact", "(BPT AmmuJob) " .. TranslateCap("interaction"), "keyboard", "E", function()
+ if not CurrentAction then
+ return
+ end
+
+ if not ESX.PlayerData.job or (ESX.PlayerData.job and not ESX.PlayerData.job.name == "ammu") then
+ return
end
-end, false)
+ if 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 == "delete_vehicle" then
+ ESX.Game.DeleteVehicle(CurrentActionData.vehicle)
+ elseif CurrentAction == "menu_boss_actions" then
+ ESX.CloseContext()
+ TriggerEvent("bpt_society:openBossMenu", "ammu", function(data, menu)
+ ESX.CloseContext()
-RegisterKeyMapping("ammumenu", "Open Ammu Menu", "keyboard", "f6")
+ CurrentAction = "menu_boss_actions"
+ CurrentActionMsg = TranslateCap("open_bossmenu")
+ CurrentActionData = {}
+ end)
+ elseif CurrentAction == "remove_entity" then
+ DeleteEntity(CurrentActionData.entity)
+ end
+
+ CurrentAction = nil
+end)
+
+ESX.RegisterInput("ammu:quickactions", "(BPT AmmuJob) " .. TranslateCap("quick_actions"), "keyboard", "F6", function()
+ if not ESX.PlayerData.job or (ESX.PlayerData.job.name ~= "ammu") or isDead then
+ return
+ end
+
+ if not Config.EnableESXService then
+ OpenAmmuActionsMenu()
+ elseif playerInService then
+ OpenAmmuActionsMenu()
+ 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
+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
+
+AddEventHandler("esx:onPlayerSpawn", function(spawn)
+ isDead = false
+ TriggerEvent("bpt_ammujob:unrestrain")
+
+ if not hasAlreadyJoined then
+ TriggerServerEvent("bpt_ammujob:spawned")
+ end
+ hasAlreadyJoined = true
+end)
+
+AddEventHandler("esx:onPlayerDeath", function(data)
+ isDead = true
+end)
+
+AddEventHandler("onResourceStop", function(resource)
+ if resource == GetCurrentResourceName() then
+ TriggerEvent("bpt_ammujob:unrestrain")
+
+ if Config.EnableESXService then
+ TriggerServerEvent("esx_service:disableService", "ammu")
+ 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(TranslateCap("unrestrained_timer"))
+ TriggerEvent("bpt_ammujob: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(TranslateCap("impound_successful"))
+ currentTask.busy = false
+end
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/client/vehicle.lua b/server-data/resources/[bpt_addons]/bpt_ammujob/client/vehicle.lua
new file mode 100644
index 000000000..646a2cea2
--- /dev/null
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/client/vehicle.lua
@@ -0,0 +1,320 @@
+---@diagnostic disable: undefined-global
+
+local spawnedVehicles = {}
+
+function OpenVehicleSpawnerMenu(type, station, part, partNum)
+ local playerCoords = GetEntityCoords(PlayerPedId())
+ local elements = {
+ { unselectable = true, icon = "fas fa-car", title = TranslateCap("garage_title") },
+ { icon = "fas fa-car", title = TranslateCap("garage_storeditem"), action = "garage" },
+ { icon = "fas fa-car", title = TranslateCap("garage_storeitem"), action = "store_garage" },
+ { icon = "fas fa-car", title = TranslateCap("garage_buyitem"), action = "buy_vehicle" },
+ }
+
+ ESX.OpenContext("right", elements, function(menu, element)
+ if element.action == "buy_vehicle" then
+ local shopElements = {}
+ local shopCoords = Config.Ammu[station][part][partNum].InsideShop
+ local authorizedVehicles = Config.AuthorizedVehicles[type][ESX.PlayerData.job.grade_name]
+
+ if authorizedVehicles then
+ if #authorizedVehicles > 0 then
+ for _, vehicle in ipairs(authorizedVehicles) do
+ if IsModelInCdimage(vehicle.model) then
+ local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model))
+
+ shopElements[#shopElements + 1] = {
+ icon = "fas fa-car",
+ title = ('%s - %s'):format(vehicleLabel, TranslateCap("shop_item", ESX.Math.GroupDigits(vehicle.price))),
+ name = vehicleLabel,
+ model = vehicle.model,
+ price = vehicle.price,
+ props = vehicle.props,
+ type = type,
+ }
+ end
+ end
+
+ if #shopElements > 0 then
+ OpenShopMenu(shopElements, playerCoords, shopCoords)
+ else
+ ESX.ShowNotification(TranslateCap("garage_notauthorized"))
+ end
+ else
+ ESX.ShowNotification(TranslateCap("garage_notauthorized"))
+ end
+ else
+ ESX.ShowNotification(TranslateCap("garage_notauthorized"))
+ end
+ elseif element.action == "garage" then
+ local garage = {
+ { unselectable = true, icon = "fas fa-car", title = "Garage" },
+ }
+
+ ESX.TriggerServerCallback("esx_vehicleshop:retrieveJobVehicles", function(jobVehicles)
+ if #jobVehicles > 0 then
+ local allVehicleProps = {}
+
+ for _, v in ipairs(jobVehicles) do
+ local props = json.decode(v.vehicle)
+
+ if IsModelInCdimage(props.model) then
+ local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model))
+ local label = ('%s - %s: '):format(vehicleName, props.plate)
+
+ if v.stored == 1 or v.stored == true then
+ label = label .. ('%s'):format(TranslateCap("garage_stored"))
+ elseif v.stored == 0 or v.stored == false then
+ label = label .. ('%s'):format(TranslateCap("garage_notstored"))
+ end
+
+ garage[#garage + 1] = {
+ icon = "fas fa-car",
+ title = label,
+ stored = v.stored,
+ model = props.model,
+ plate = props.plate,
+ }
+
+ allVehicleProps[props.plate] = props
+ end
+ end
+
+ if #garage > 0 then
+ ESX.OpenContext("right", garage, function(menuG, elementG)
+ if elementG.stored == 1 or elementG.stored == true then
+ local foundSpawn, spawnPoint = GetAvailableVehicleSpawnPoint(station, part, partNum)
+
+ if foundSpawn then
+ ESX.CloseContext()
+
+ ESX.Game.SpawnVehicle(elementG.model, spawnPoint.coords, spawnPoint.heading, function(vehicle)
+ local vehicleProps = allVehicleProps[elementG.plate]
+ ESX.Game.SetVehicleProperties(vehicle, vehicleProps)
+
+ TriggerServerEvent("esx_vehicleshop:setJobVehicleState", elementG.plate, false)
+ ESX.ShowNotification(TranslateCap("garage_released"))
+ end)
+ end
+ else
+ ESX.ShowNotification(TranslateCap("garage_notavailable"))
+ end
+ end)
+ else
+ ESX.ShowNotification(TranslateCap("garage_empty"))
+ end
+ else
+ ESX.ShowNotification(TranslateCap("garage_empty"))
+ end
+ end, type)
+ elseif element.action == "store_garage" then
+ StoreNearbyVehicle(playerCoords)
+ end
+ end)
+end
+
+function StoreNearbyVehicle(playerCoords)
+ local vehicles, plates, index = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {}, {}
+
+ if next(vehicles) then
+ for i = 1, #vehicles do
+ local vehicle = vehicles[i]
+
+ -- Make sure the vehicle we're saving is empty, or else it won't be deleted
+ if GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) then
+ local plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle))
+ plates[#plates + 1] = plate
+ index[plate] = vehicle
+ end
+ end
+ else
+ ESX.ShowNotification(TranslateCap("garage_store_nearby"))
+ return
+ end
+
+ ESX.TriggerServerCallback("bpt_ammujob:storeNearbyVehicle", function(plate)
+ if plate then
+ local vehicleId = index[plate]
+ local attempts = 0
+ ESX.Game.DeleteVehicle(vehicleId)
+ local isBusy = true
+
+ CreateThread(function()
+ BeginTextCommandBusyspinnerOn("STRING")
+ AddTextComponentSubstringPlayerName(TranslateCap("garage_storing"))
+ EndTextCommandBusyspinnerOn(4)
+
+ while isBusy do
+ Wait(100)
+ end
+
+ BusyspinnerOff()
+ end)
+
+ -- Workaround for vehicle not deleting when other players are near it.
+ while DoesEntityExist(vehicleId) do
+ Wait(500)
+ attempts = attempts + 1
+
+ -- Give up
+ if attempts > 30 then
+ break
+ end
+
+ vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0)
+ if #vehicles > 0 then
+ for i = 1, #vehicles do
+ local vehicle = vehicles[i]
+ if ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)) == plate then
+ ESX.Game.DeleteVehicle(vehicle)
+ break
+ end
+ end
+ end
+ end
+
+ isBusy = false
+ ESX.ShowNotification(TranslateCap("garage_has_stored"))
+ else
+ ESX.ShowNotification(TranslateCap("garage_has_notstored"))
+ end
+ end, plates)
+end
+
+function GetAvailableVehicleSpawnPoint(station, part, partNum)
+ local spawnPoints = Config.Ammu[station][part][partNum].SpawnPoints
+ local found, foundSpawnPoint = false, nil
+
+ for i = 1, #spawnPoints, 1 do
+ if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then
+ found, foundSpawnPoint = true, spawnPoints[i]
+ break
+ end
+ end
+
+ if found then
+ return true, foundSpawnPoint
+ else
+ ESX.ShowNotification(TranslateCap("vehicle_blocked"))
+ return false
+ end
+end
+
+function OpenShopMenu(elements, restoreCoords, shopCoords)
+ local playerPed = PlayerPedId()
+ IsInShopMenu = true
+ ESX.OpenContext("right", elements, function(menu, element)
+ local elements2 = {
+ { unselectable = true, icon = "fas fa-car", title = element.title },
+ { icon = "fas fa-eye", title = TranslateCap("view"), value = "view" },
+ }
+
+ ESX.OpenContext("right", elements2, function(menu2, element2)
+ if element2.value == "view" then
+ DeleteSpawnedVehicles()
+ WaitForVehicleToLoad(element.model)
+
+ ESX.Game.SpawnLocalVehicle(element.model, shopCoords, 0.0, function(vehicle)
+ table.insert(spawnedVehicles, vehicle)
+ TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
+ FreezeEntityPosition(vehicle, true)
+ SetModelAsNoLongerNeeded(element.model)
+
+ if element.props then
+ ESX.Game.SetVehicleProperties(vehicle, element.props)
+ end
+ end)
+
+ local elements3 = {
+ { unselectable = true, icon = "fas fa-car", title = element.title },
+ { icon = "fas fa-check-double", title = TranslateCap("buy_car"), value = "buy" },
+ { icon = "fas fa-eye", title = TranslateCap("stop_view"), value = "stop" },
+ }
+
+ ESX.OpenContext("right", elements3, function(menu3, element3)
+ if element3.value == "stop" then
+ IsInShopMenu = false
+ ESX.CloseContext()
+
+ DeleteSpawnedVehicles()
+ FreezeEntityPosition(playerPed, false)
+ SetEntityVisible(PlayerPedId(), true, true)
+
+ ESX.Game.Teleport(playerPed, restoreCoords)
+ elseif element3.value == "buy" then
+ local newPlate = exports["esx_vehicleshop"]:GeneratePlate()
+ local vehicle = GetVehiclePedIsIn(playerPed, false)
+ local props = ESX.Game.GetVehicleProperties(vehicle)
+ props.plate = newPlate
+
+ ESX.TriggerServerCallback("bpt_ammujob:buyJobVehicle", function(bought)
+ if bought then
+ ESX.ShowNotification(TranslateCap("vehicleshop_bought", element.name, ESX.Math.GroupDigits(element.price)))
+
+ IsInShopMenu = false
+ ESX.CloseContext()
+ DeleteSpawnedVehicles()
+ FreezeEntityPosition(playerPed, false)
+ SetEntityVisible(PlayerPedId(), true, true)
+
+ ESX.Game.Teleport(playerPed, restoreCoords)
+ else
+ ESX.ShowNotification(TranslateCap("vehicleshop_money"))
+ ESX.CloseContext()
+ end
+ end, props, element.type)
+ end
+ end, function()
+ IsInShopMenu = false
+ ESX.CloseContext()
+
+ DeleteSpawnedVehicles()
+ FreezeEntityPosition(playerPed, false)
+ SetEntityVisible(PlayerPedId(), true, true)
+
+ ESX.Game.Teleport(playerPed, restoreCoords)
+ end)
+ end
+ end)
+ end)
+end
+
+CreateThread(function()
+ while true do
+ Wait(0)
+
+ if IsInShopMenu then
+ DisableControlAction(0, 75, true) -- Disable exit vehicle
+ DisableControlAction(27, 75, true) -- Disable exit vehicle
+ else
+ Wait(500)
+ end
+ end
+end)
+
+function DeleteSpawnedVehicles()
+ while #spawnedVehicles > 0 do
+ local vehicle = spawnedVehicles[1]
+ ESX.Game.DeleteVehicle(vehicle)
+ table.remove(spawnedVehicles, 1)
+ end
+end
+
+function WaitForVehicleToLoad(modelHash)
+ modelHash = (type(modelHash) == "number" and modelHash or joaat(modelHash))
+
+ if not HasModelLoaded(modelHash) then
+ RequestModel(modelHash)
+
+ BeginTextCommandBusyspinnerOn("STRING")
+ AddTextComponentSubstringPlayerName(TranslateCap("vehicleshop_awaiting_model"))
+ EndTextCommandBusyspinnerOn(4)
+
+ while not HasModelLoaded(modelHash) do
+ Wait(0)
+ DisableAllControlActions(0)
+ end
+
+ BusyspinnerOff()
+ end
+end
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/config.lua b/server-data/resources/[bpt_addons]/bpt_ammujob/config.lua
index 8975d374e..286cff102 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/config.lua
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/config.lua
@@ -1,54 +1,85 @@
+---@diagnostic disable: undefined-global
Config = {}
+
Config.DrawDistance = 10.0 -- How close do you need to be for the markers to be drawn (in GTA units).
-Config.MaxInService = -1 -- How much people can be in service at once?
-Config.EnablePlayerManagement = true -- Enable society managing.
-Config.EnableSocietyOwnedVehicles = false
-Config.Locale = "it"
+Config.MarkerType = { Armories = 21, BossActions = 22, Vehicles = 36 }
+Config.MarkerSize = { x = 1.5, y = 1.5, z = 0.5 }
+Config.MarkerColor = { r = 50, g = 50, b = 204 }
+Config.EnablePlayerManagement = true -- Enable if you want society managing.
+Config.EnableArmoryManagement = false
+Config.EnableESXIdentity = true -- Enable if you're using esx_identity.
+Config.EnableESXOptionalneeds = false -- Enable if you're using esx_optionalneeds
+Config.EnableLicenses = true -- Enable if you're using esx_license.
+Config.EnableHandcuffTimer = true -- Enable handcuff timer? will unrestrain player after the time ends.
+Config.HandcuffTimer = 10 * 60000 -- 10 minutes.
+Config.EnableESXService = false -- Enable esx service?
+Config.MaxInService = -1 -- How many people can be in service at once? Set as -1 to have no limit
+Config.EnableFinePresets = false -- Set to false to use a custom input fields for fines
+Config.Locale = GetConvar("esx:locale", "it")
Config.OxInventory = ESX.GetConfig().OxInventory
-Config.AuthorizedVehicles = {
- { model = "rumpo", label = "Rumpo" },
-}
+Config.Ammu = {
-Config.Zones = {
+ AMMU = {
- VehicleSpawner = {
- Pos = { x = 821.340637, y = -2146.417480, z = 28.706909 },
- Size = { x = 1.0, y = 1.0, z = 1.0 },
- Color = { r = 145, g = 30, b = 30 },
- Type = 36,
- Rotate = true,
- },
+ Blip = {
+ Coords = vector3(425.1, -979.5, 30.7),
+ Sprite = 60,
+ Display = 4,
+ Scale = 1.2,
+ Colour = 29,
+ },
- VehicleSpawnPoint = {
- Pos = { x = 822.540649, y = -2134.575928, z = 29.279907 },
- Size = { x = 1.5, y = 1.5, z = 1.0 },
- Type = -1,
- Rotate = false,
- Heading = 225.0,
- },
+ Armories = {
+ vector3(487.239563, -996.949463, 30.678345),
+ },
- VehicleDeleter = {
- Pos = { x = 822.540649, y = -2134.575928, z = 28.279907 },
- Size = { x = 3.0, y = 3.0, z = 0.25 },
- Color = { r = 255, g = 0, b = 0 },
- Type = 1,
- Rotate = false,
- },
+ Vehicles = {
+ {
+ Spawner = vector3(454.6, -1017.4, 28.4),
+ InsideShop = vector3(444.553833, -1019.498901, 28.605835),
+ SpawnPoints = {
+ { coords = vector3(438.4, -1018.3, 27.7), heading = 90.0, radius = 6.0 },
+ { coords = vector3(441.0, -1024.2, 28.3), heading = 90.0, radius = 6.0 },
+ { coords = vector3(453.5, -1022.2, 28.0), heading = 90.0, radius = 6.0 },
+ { coords = vector3(450.9, -1016.5, 28.1), heading = 90.0, radius = 6.0 },
+ },
+ },
+
+ {
+ Spawner = vector3(473.3, -1018.8, 28.0),
+ InsideShop = vector3(228.5, -993.5, -99.0),
+ SpawnPoints = {
+ { coords = vector3(475.9, -1021.6, 28.0), heading = 276.1, radius = 6.0 },
+ { coords = vector3(484.1, -1023.1, 27.5), heading = 302.5, radius = 6.0 },
+ },
+ },
+ },
- AmmuActions = {
- Pos = { x = 812.479126, y = -2159.182373, z = 29.616821 },
- Size = { x = 0.5, y = 0.5, z = 0.5 },
- Color = { r = 204, g = 204, b = 0 },
- Type = 20,
- Rotate = true,
+ BossActions = {
+ vector3(824.742859, -2150.386719, 29.616821),
+ },
},
+}
+
+Config.AuthorizedVehicles = {
+ car = {
+ apprentice = {},
+
+ gunsmith = {
+ { model = "police3", price = 20000 },
+ },
+
+ armorychief = {
+ { model = "policet", price = 18500 },
+ },
+
+ deputydirector = {
+ { model = "riot", price = 70000 },
+ },
- Cloakroom = {
- Pos = { x = 810.065918, y = -2162.439453, z = 29.616821 },
- Size = { x = 0.5, y = 0.5, z = 0.5 },
- Color = { r = 204, g = 204, b = 0 },
- Type = 21,
- Rotate = true,
+ boss = {
+ { model = "riot", price = 70000 },
+ },
},
}
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/fxmanifest.lua b/server-data/resources/[bpt_addons]/bpt_ammujob/fxmanifest.lua
index 1b2df0471..d568bbd57 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/fxmanifest.lua
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/fxmanifest.lua
@@ -1,25 +1,24 @@
fx_version("adamant")
+
game("gta5")
-description("bpt_ammunation job")
-author("bitpredator")
+description("bpt_ammunation job RP server")
lua54("yes")
-version("1.0.2")
+version("1.0.3")
shared_script("@es_extended/imports.lua")
-client_scripts({
- "@es_extended/locale.lua",
- "locales/*.lua",
- "config.lua",
- "client/*.lua",
-})
-
server_scripts({
- "@es_extended/locale.lua",
- "locales/*.lua",
- "config.lua",
- "server/*.lua",
+ "@oxmysql/lib/MySQL.lua",
+ "@es_extended/locale.lua",
+ "locales/*.lua",
+ "config.lua",
+ "server/*.lua",
})
-dependency("es_extended")
+client_scripts({
+ "@es_extended/locale.lua",
+ "locales/*.lua",
+ "config.lua",
+ "client/*.lua",
+})
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/locales/en.lua b/server-data/resources/[bpt_addons]/bpt_ammujob/locales/en.lua
index 748409dcf..0653a8c1f 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/locales/en.lua
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/locales/en.lua
@@ -1,34 +1,150 @@
Locales["en"] = {
- -- cloakroom
- ["cloakroom_menu"] = "cloakroom",
- ["cloakroom_prompt"] = "press [E] to access the cloakroom.",
- ["wear_citizen"] = "civilian clothing",
- ["wear_work"] = "work clothes",
- -- Inventory
- ["deposit_stock"] = "Deposit stock",
- ["take_stock"] = "Take stock",
- ["have_deposited"] = "Have deposited",
- ["quantity_invalid"] = "Quantity invelid",
- -- garage
- ["spawner_prompt"] = "press [E] to access the garage.",
- ["vehicle_spawned"] = "vehicle spawned successfully!",
- ["store_veh"] = "press [E] to deposit the vehicle",
- ["spawn_veh"] = "spawn vehicle",
- ["spawnpoint_blocked"] = "vehicle blocks the spawnpoint!",
- ["only_ammu"] = "you can only deposit company vehicles.",
- ["empty_garage"] = "no vehicles in the garage!",
- ["taking_service"] = "Take service: Gunsmith",
- ["full_service"] = "complete service: ",
- ["amount_invalid"] = "invalid amount",
- ["press_to_open"] = "press [E] to access the menu",
- ["billing"] = "billing",
- ["billing_sent"] = "the invoice has been posted!",
- ["invoice_amount"] = "invoice amount",
- ["no_players_near"] = "no players nearby",
- ["boss_actions"] = "Boss actions",
- ["blip_ammu"] = "Armory.",
- ["ammu"] = "ammu",
- -- billing
- ["bill_amount"] = "Amount to bill..",
+ -- Armory
+ ["remove_object"] = "withdraw object",
+ ["deposit_object"] = "deposit object",
+ ["get_weapon"] = "withdraw weapon from armory",
+ ["put_weapon"] = "store weapon in armory",
+ ["buy_weapons"] = "buy weapons",
+ ["armory"] = "armory",
+ ["open_armory"] = "press [E] to access the Armory.",
+ ["armory_owned"] = "owned",
+ ["armory_free"] = "free",
+ ["armory_item"] = "$%s",
+ ["armory_weapontitle"] = "armory - Buy weapon",
+ ["armory_componenttitle"] = "armory - Weapon attatchments",
+ ["armory_bought"] = "you bought an %s for $%s",
+ ["armory_money"] = "you cannot afford that weapon",
+ ["armory_hascomponent"] = "you have that attatchment equiped!",
+ ["get_weapon_menu"] = "armory - Withdraw Weapon",
+ ["put_weapon_menu"] = "armory - Store Weapon",
["confirm"] = "Confirm",
+ -- Vehicles
+ ["vehicle_menu"] = "vehicle",
+ ["vehicle_blocked"] = "all available spawn points are currently blocked!",
+ ["garage_prompt"] = "press [E] to access the Vehicle Actions.",
+ ["garage_title"] = "vehicle Actions",
+ ["garage_stored"] = "stored",
+ ["garage_notstored"] = "not in garage",
+ ["garage_storing"] = "we're attempting to remove the vehicle, make sure no players are around it.",
+ ["garage_has_stored"] = "the vehicle has been stored in your garage",
+ ["garage_has_notstored"] = "no nearby owned vehicles were found",
+ ["garage_notavailable"] = "your vehicle is not stored in the garage.",
+ ["garage_blocked"] = "there's no available spawn points!",
+ ["garage_empty"] = "you don't have any vehicles in your garage.",
+ ["garage_released"] = "your vehicle has been released from the garage.",
+ ["garage_store_nearby"] = "there is no nearby vehicles.",
+ ["garage_storeditem"] = "open garage",
+ ["garage_storeitem"] = "store vehicle in garage",
+ ["garage_buyitem"] = "vehicle shop",
+ ["garage_notauthorized"] = "you're not authorized to buy this kind of vehicles.",
+ ["shop_item"] = "$%s",
+ ["vehicleshop_title"] = "vehicle Shop",
+ ["vehicleshop_confirm"] = "do you want to buy this vehicle?",
+ ["vehicleshop_bought"] = "you have bought %s for ~r~$%s",
+ ["vehicleshop_money"] = "you cannot afford that vehicle",
+ ["vehicleshop_awaiting_model"] = "the vehicle is currently DOWNLOADING & LOADING please wait",
+ ["confirm_no"] = "no",
+ ["confirm_yes"] = "yes",
+ ["view"] = "View",
+ ["buy_car"] = "Buy",
+ ["stop_view"] = "Stop Viewing",
+ -- 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 %s has entered service!",
+ ["service_out"] = "you have left service.",
+ ["service_out_announce"] = "operator %s has left their service.",
+ -- Action Menu
+ ["menu_title"] = "Ammu",
+ ["citizen_interaction"] = "citizen Interaction",
+ ["vehicle_interaction"] = "vehicle Interaction",
+ ["id_card"] = "ID Card",
+ ["search"] = "search",
+ ["handcuff"] = "cuff / Uncuff",
+ ["drag"] = "escort",
+ ["put_in_vehicle"] = "put in Vehicle",
+ ["out_the_vehicle"] = "drag out from vehicle",
+ ["fine"] = "fine",
+ ["license_check"] = "manage license",
+ ["license_revoke"] = "revoke license",
+ ["license_revoked"] = "your %s has been revoked!",
+ ["licence_you_revoked"] = "you revoked a %s which belonged to %s",
+ ["no_players_nearby"] = "there is no player(s) nearby!",
+ ["being_searched"] = "you are being searched by the Ammu",
+ -- Vehicle interaction
+ ["vehicle_info"] = "vehicle Info",
+ ["pick_lock"] = "lockpick Vehicle",
+ ["vehicle_unlocked"] = "vehicle Unlocked",
+ ["no_vehicles_nearby"] = "there is no vehicles nearby",
+ ["impound"] = "impound vehicle",
+ ["impound_prompt"] = "press [E] to cancel the impound",
+ ["impound_canceled"] = "you canceled the impound",
+ ["impound_canceled_moved"] = "the impound has been canceled because the vehicle moved",
+ ["impound_successful"] = "you have impounded the vehicle",
+ ["search_database"] = "vehicle information",
+ ["search_database_title"] = "vehicle information - search with registration number",
+ ["search_database_error_invalid"] = "that is ~r~not a valid registration number",
+ ["search_plate"] = "Enter Plate",
+ ["lookup_plate"] = "Lookup Plate",
+ -- ID Card Menu
+ ["name"] = "name: %s",
+ ["job"] = "job: %s",
+ ["sex"] = "sex: %s",
+ ["dob"] = "DOB: %s",
+ ["height"] = "height: %s",
+ ["bac"] = "BAC: %s",
+ ["unknown"] = "unknown",
+ ["male"] = "male",
+ ["female"] = "female",
+ -- Body Search Menu
+ ["guns_label"] = "--- Guns ---",
+ ["inventory_label"] = "--- Inventory ---",
+ ["license_label"] = " --- Licenses ---",
+ ["confiscate"] = "confiscate %s",
+ ["confiscate_weapon"] = "confiscate %s with %s bullets",
+ ["confiscate_inv"] = "confiscate %sx %s",
+ ["confiscate_dirty"] = 'confiscate dirty money: $%s',
+ ["you_confiscated"] = "you confiscated %sx %s from %s",
+ ["got_confiscated"] = "%sx %s were confiscated by %s",
+ ["you_confiscated_account"] = "you confiscated $%s (%s) from %s",
+ ["got_confiscated_account"] = "$%s (%s) was confiscated by %s",
+ ["you_confiscated_weapon"] = "you confiscated %s from %s with ~o~%s bullets",
+ ["got_confiscated_weapon"] = "your %s with ~o~%s bullets was confiscated by %s",
+ ["traffic_offense"] = "traffic Offense",
+ ["minor_offense"] = "minor Offense",
+ ["average_offense"] = "average Offense",
+ ["major_offense"] = "major Offense",
+ ["fine_total"] = "fine: %s",
+ ["fine_enter_amount"] = "Enter the amount of the fine",
+ ["fine_enter_text"] = "Enter the reason for the fine",
+ ["invalid_amount"] = "Error: Amount was not a number or invalid",
+ -- Vehicle Info Menu
+ ["plate"] = "plate: %s",
+ ["owner_unknown"] = "owner: Unknown",
+ ["owner"] = "owner: %s",
+ -- Boss Menu
+ ["open_bossmenu"] = "press [E] to open the menu",
+ ["quantity_invalid"] = "invalid quantity",
+ ["have_withdrawn"] = "you have withdrawn %sx %s",
+ ["have_deposited"] = "you have deposited %sx %s",
+ ["quantity"] = "quantity",
+ ["quantity_placeholder"] = "Amount to withdraw..",
+ ["inventory"] = "inventory",
+ ["ammu_stock"] = "Ammu Stock",
+ -- Misc
+ ["remove_prop"] = "press [E] to delete the object",
+ ["map_blip"] = "Ammu Station",
+ ["unrestrained_timer"] = "you feel your handcuffs slowly losing grip and fading away.",
+ -- Notifications
+ ["alert_ammu"] = "Ammu alert",
+ ["phone_ammu"] = "Ammu",
+ -- Keybind
+ ["interaction"] = "Interact",
+ ["quick_actions"] = "Quick Actions",
+ -- Other
+ ["society_ammu"] = "Ammu",
+ ["received_firearms_license"] = "You have received your firearms license",
+ ["released_gun_licence"] = "you have issued your gun licence",
}
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/locales/it.lua b/server-data/resources/[bpt_addons]/bpt_ammujob/locales/it.lua
index 4fe3d8de4..5450ebe03 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/locales/it.lua
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/locales/it.lua
@@ -1,35 +1,148 @@
Locales["it"] = {
- -- cloakroom
- ["cloakroom_menu"] = "guardaroba",
- ["cloakroom_prompt"] = "premi [E] per accedere al guardaroba.",
- ["wear_citizen"] = "abbigliamento civile",
- ["wear_work"] = "abiti da lavoro",
- -- Inventory
- ["deposit_stock"] = "Depositare",
- ["take_stock"] = "Prendi",
- ["have_deposited"] = "Hai depositato",
- ["quantity_invalid"] = "Qunatità non valida",
- -- garage
- ["spawner_prompt"] = "premi [E] per accedere al garage.",
- ["vehicle_spawned"] = "veicolo generato con successo!",
- ["store_veh"] = "premi [E] per depositare il veicolo",
- ["spawn_veh"] = "genera veicolo",
- ["spawnpoint_blocked"] = "un veicolo blocca lo spawnpoint!",
- ["only_ammu"] = "puoi depositare solo veicoli aziendali.",
- ["empty_garage"] = "nessun veicolo nel garage!",
- ["taking_service"] = "prendi servizio: Armaiolo",
- ["full_service"] = "servizio completo: ",
- ["amount_invalid"] = "importo non valido",
- ["press_to_open"] = "premi [E] per accedere al menu",
- ["billing"] = "fattura",
- ["billing_sent"] = "la fattura è stata registrata!",
- ["invoice_amount"] = "importo fattura",
- ["no_players_near"] = "nessun giocatore nelle vicinanze",
- ["boss_actions"] = "Azioni del capo",
- ["blip_ammu"] = "Armeria.",
- ["ammu"] = "ammu",
- -- billing
- ["bill_amount"] = "importo della fattura",
+ -- Armeria
+ ["remove_object"] = "Prendi oggetto",
+ ["deposit_object"] = "Deposita oggetto",
+ ["get_weapon"] = "Prendi arma dall'armeria",
+ ["put_weapon"] = "Deposita arma nell'armeria",
+ ["buy_weapons"] = "Acquista armi",
+ ["armory"] = "armeria",
+ ["open_armory"] = "Premi [E] per accedere all'Armeria.",
+ ["armory_owned"] = "posseduto",
+ ["armory_free"] = "gratuito",
+ ["armory_item"] = "$%s",
+ ["armory_weapontitle"] = "armeria - Acquista arma",
+ ["armory_componenttitle"] = "armeria - Accessori arma",
+ ["armory_bought"] = "Hai comprato un %s per $%s",
+ ["armory_money"] = "Non puoi permetterti quell'arma",
+ ["armory_hascomponent"] = "Hai già quel accessorio equipaggiato!",
+ ["get_weapon_menu"] = "armeria - Prendi arma",
+ ["put_weapon_menu"] = "armeria - Deposita arma",
["confirm"] = "Conferma",
- ["amount"] = "importo",
+ -- Veicoli
+ ["vehicle_menu"] = "veicolo",
+ ["vehicle_blocked"] = "tutti i punti di spawn disponibili sono attualmente bloccati!",
+ ["garage_prompt"] = "Premi [E] per accedere alle Azioni sul Veicolo.",
+ ["garage_title"] = "Azioni sul Veicolo",
+ ["garage_stored"] = "nella rimessa",
+ ["garage_notstored"] = "non in rimessa",
+ ["garage_storing"] = "Stiamo cercando di rimuovere il veicolo, assicurati che nessun giocatore sia intorno ad esso.",
+ ["garage_has_stored"] = "il veicolo è stato riposto in rimessa",
+ ["garage_has_notstored"] = "nessun veicolo di proprietà è stato trovato nelle vicinanze",
+ ["garage_notavailable"] = "il tuo veicolo non è riposto in rimessa.",
+ ["garage_blocked"] = "non ci sono punti di spawn disponibili!",
+ ["garage_empty"] = "non hai veicoli in rimessa.",
+ ["garage_released"] = "il tuo veicolo è stato rilasciato dalla rimessa.",
+ ["garage_store_nearby"] = "non ci sono veicoli nelle vicinanze.",
+ ["garage_storeditem"] = "apri rimessa",
+ ["garage_storeitem"] = "riponi veicolo in rimessa",
+ ["garage_buyitem"] = "concessionario veicoli",
+ ["garage_notauthorized"] = "non sei autorizzato ad acquistare questo tipo di veicoli.",
+ ["shop_item"] = "$%s",
+ ["vehicleshop_title"] = "concessionario veicoli",
+ ["vehicleshop_confirm"] = "vuoi comprare questo veicolo?",
+ ["vehicleshop_bought"] = "hai comprato %s per ~r~$%s",
+ ["vehicleshop_money"] = "non puoi permetterti quel veicolo",
+ ["vehicleshop_awaiting_model"] = "il veicolo è attualmente in DOWNLOAD & LOADING, per favore attendi",
+ ["confirm_no"] = "no",
+ ["confirm_yes"] = "si",
+ ["view"] = "Visualizza",
+ ["buy_car"] = "Compra",
+ ["stop_view"] = "Interrompi la visualizzazione",
+ -- Servizio
+ ["service_max"] = "non puoi entrare in servizio, numero massimo di agenti in servizio: %s/%s",
+ ["service_not"] = "non sei in servizio! Devi cambiarti prima.",
+ ["service_anonunce"] = "informazioni servizio",
+ ["service_in"] = "sei entrato in servizio, benvenuto!",
+ ["service_in_announce"] = "l'operatore %s è entrato in servizio!",
+ ["service_out"] = "hai lasciato il servizio.",
+ ["service_out_announce"] = "l'operatore %s ha lasciato il servizio.",
+ -- Menu Azioni
+ ["menu_title"] = "Armeria",
+ ["citizen_interaction"] = "Interazione con cittadino",
+ ["vehicle_interaction"] = "Interazione con veicolo",
+ ["id_card"] = "Carta d'identità",
+ ["search"] = "perquisisci",
+ ["handcuff"] = "ammanetta / smanetta",
+ ["drag"] = "scorta",
+ ["put_in_vehicle"] = "metti in veicolo",
+ ["out_the_vehicle"] = "trascina fuori dal veicolo",
+ ["fine"] = "multa",
+ ["license_check"] = "gestisci licenze",
+ ["license_revoke"] = "revoca licenza",
+ ["license_revoked"] = "la tua %s è stata revocata!",
+ ["licence_you_revoked"] = "hai revocato una %s che apparteneva a %s",
+ ["no_players_nearby"] = "non ci sono giocatori nelle vicinanze!",
+ ["being_searched"] = "perquisizione in corso",
+ ["fine_enter_amount"] = "Inserisci l'importo della sanzione",
+ ["fine_enter_text"] = "Inserisci il motivo della multa",
+ ["invalid_amount"] = "Errore: l'importo non era un numero o non era valido",
+ -- Interazione veicolo
+ ["vehicle_info"] = "informazioni sul veicolo",
+ ["pick_lock"] = "forza la serratura del veicolo",
+ ["vehicle_unlocked"] = "veicolo sbloccato",
+ ["no_vehicles_nearby"] = "non ci sono veicoli nelle vicinanze",
+ ["impound"] = "recupera veicolo",
+ ["impound_prompt"] = "Premi [E] per annullare il recupero",
+ ["impound_canceled"] = "hai annullato il recupero",
+ ["impound_canceled_moved"] = "il recupero è stato annullato perché il veicolo si è mosso",
+ ["impound_successful"] = "hai confiscato il veicolo",
+ ["search_database"] = "informazioni sul veicolo",
+ ["search_database_title"] = "informazioni sul veicolo - cerca con numero di targa",
+ ["search_database_error_invalid"] = "quello non è un numero di targa valido",
+ ["search_plate"] = "Inserisci targa",
+ ["lookup_plate"] = "Cerca targa",
+ -- Menu Carta d'identità
+ ["name"] = "nome: %s",
+ ["job"] = "lavoro: %s",
+ ["sex"] = "sesso: %s",
+ ["dob"] = "DOB: %s",
+ ["height"] = "altezza: %s",
+ ["bac"] = "BAC: %s",
+ ["unknown"] = "sconosciuto",
+ ["male"] = "maschio",
+ ["female"] = "femmina",
+ -- Menu Perquisizione corpo
+ ["guns_label"] = "--- Armi ---",
+ ["inventory_label"] = "--- Inventario ---",
+ ["license_label"] = " --- Licenze ---",
+ ["confiscate"] = "confisca %s",
+ ["confiscate_weapon"] = "confisca %s con %s proiettili",
+ ["confiscate_inv"] = "confisca %sx %s",
+ ["confiscate_dirty"] = 'confisca denaro sporco: $%s',
+ ["you_confiscated"] = "hai confiscato %sx %s da %s",
+ ["got_confiscated"] = "%sx %s sono stati confiscati da %s",
+ ["you_confiscated_account"] = "hai confiscato $%s (%s) da %s",
+ ["got_confiscated_account"] = "$%s (%s) sono stati confiscati da %s",
+ ["you_confiscated_weapon"] = "hai confiscato %s da %s con ~o~%s proiettili",
+ ["got_confiscated_weapon"] = "la tua %s con ~o~%s proiettili è stata confiscata da %s",
+ ["traffic_offense"] = "infrazione del traffico",
+ ["minor_offense"] = "infrazione minore",
+ ["average_offense"] = "infrazione media",
+ ["major_offense"] = "infrazione grave",
+ ["fine_total"] = "multa: %s",
+ -- Menu Informazioni Veicolo
+ ["plate"] = "targa: %s",
+ ["owner_unknown"] = "proprietario: sconosciuto",
+ ["owner"] = "proprietario: %s",
+ -- Menu Boss
+ ["open_bossmenu"] = "premi [E] per aprire il menu",
+ ["quantity_invalid"] = "quantità non valida",
+ ["have_withdrawn"] = "hai prelevato %sx %s",
+ ["have_deposited"] = "hai depositato %sx %s",
+ ["quantity"] = "quantità",
+ ["quantity_placeholder"] = "Importo da prelevare..",
+ ["inventory"] = "inventario",
+ ["ammu_stock"] = "Deposito armeria",
+ -- Varie
+ ["remove_prop"] = "premi [E] per eliminare l'oggetto",
+ ["map_blip"] = "Armeria",
+ ["unrestrained_timer"] = "senti le manette che si allentano lentamente e svaniscono.",
+ -- Pulsante
+ ["interaction"] = "Interagisci",
+ ["quick_actions"] = "Azioni rapide",
+ -- Altro
+ ["society_ammu"] = "Armeria",
+ ["weapon"] = "Porto D'armi",
+ ["received_firearms_license"] = "Hai ricevuto il porto d'armi",
+ ["released_gun_licence"] = "Hai rilasciato il porto d'armi",
}
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/localization/bpt_ammujob_it.sql b/server-data/resources/[bpt_addons]/bpt_ammujob/localization/bpt_ammujob_it.sql
index dd7fa6599..e312eadc2 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/localization/bpt_ammujob_it.sql
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/localization/bpt_ammujob_it.sql
@@ -20,4 +20,4 @@ INSERT INTO `job_grades` (job_name, grade, name, label, salary, skin_male, skin_
('ammu',2,'armorychief','Capo Armeria',60,'{}','{}'),
('ammu',3,'deputydirector','Vice direttore',85,'{}','{}'),
('ammu',4,'boss','Direttore',100,'{}','{}')
-;
+;
\ No newline at end of file
diff --git a/server-data/resources/[bpt_addons]/bpt_ammujob/server/main.lua b/server-data/resources/[bpt_addons]/bpt_ammujob/server/main.lua
index caaced1b5..d354694d1 100644
--- a/server-data/resources/[bpt_addons]/bpt_ammujob/server/main.lua
+++ b/server-data/resources/[bpt_addons]/bpt_ammujob/server/main.lua
@@ -1,82 +1,404 @@
-local netId
+---@diagnostic disable: undefined-global
-TriggerEvent("bpt_society:registerSociety", "ammu", "Ammu", "society_ammu", "society_ammu", "society_ammu", {
+if Config.EnableESXService then
+ if Config.MaxInService ~= -1 then
+ TriggerEvent("esx_service:activateService", "ammu", Config.MaxInService)
+ end
+end
+
+TriggerEvent("bpt_society:registerSociety", "ammu", TranslateCap("society_ammu"), "society_ammu", "society_ammu", "society_ammu", {
type = "public",
})
-if Config.MaxInService ~= -1 then
- TriggerEvent("esx_service:activateService", "ammu", Config.MaxInService)
-end
-
-ESX.RegisterServerCallback("bpt_ammujob:SpawnVehicle", function(source, cb, model, props)
- local xPlayer = ESX.GetPlayerFromId(source)
+RegisterNetEvent("bpt_ammujob:confiscatePlayerItem")
+AddEventHandler("bpt_ammujob:confiscatePlayerItem", function(target, itemType, itemName, amount)
+ local source = source
+ local sourceXPlayer = ESX.GetPlayerFromId(source)
+ local targetXPlayer = ESX.GetPlayerFromId(target)
- if xPlayer.job.name ~= "ammu" then
- print(("[^3WARNING^7] Player ^5%s^7 attempted to Exploit Vehicle Spawing!!"):format(source))
+ if sourceXPlayer.job.name ~= "ammu" then
+ print(("[^3WARNING^7] Player ^5%s^7 Attempted To Exploit The Confuscation System!"):format(sourceXPlayer.source))
return
end
- local SpawnPoint = vector3(Config.Zones.VehicleSpawnPoint.Pos.x, Config.Zones.VehicleSpawnPoint.Pos.y, Config.Zones.VehicleSpawnPoint.Pos.z)
- ESX.OneSync.SpawnVehicle(joaat(model), SpawnPoint, Config.Zones.VehicleSpawnPoint.Heading, props, function()
- local vehicle = NetworkGetEntityFromNetworkId(netId)
- while GetVehicleNumberPlateText(vehicle) ~= props.plate do
- Wait(0)
+
+ if itemType == "item_standard" then
+ local targetItem = targetXPlayer.getInventoryItem(itemName)
+ local sourceItem = sourceXPlayer.getInventoryItem(itemName)
+
+ -- does the target player have enough in their inventory?
+ if targetItem.count > 0 and targetItem.count <= amount then
+ -- can the player carry the said amount of x item?
+ if sourceXPlayer.canCarryItem(itemName, sourceItem.count) then
+ targetXPlayer.removeInventoryItem(itemName, amount)
+ sourceXPlayer.addInventoryItem(itemName, amount)
+ sourceXPlayer.showNotification(TranslateCap("you_confiscated", amount, sourceItem.label, targetXPlayer.name))
+ targetXPlayer.showNotification(TranslateCap("got_confiscated", amount, sourceItem.label, sourceXPlayer.name))
+ else
+ sourceXPlayer.showNotification(TranslateCap("quantity_invalid"))
+ end
+ else
+ sourceXPlayer.showNotification(TranslateCap("quantity_invalid"))
end
- TaskWarpPedIntoVehicle(GetPlayerPed(source), vehicle, -1)
- end)
- cb()
+ elseif itemType == "item_account" then
+ local targetAccount = targetXPlayer.getAccount(itemName)
+
+ -- does the target player have enough money?
+ if targetAccount.money >= amount then
+ targetXPlayer.removeAccountMoney(itemName, amount, "Confiscated")
+ sourceXPlayer.addAccountMoney(itemName, amount, "Confiscated")
+
+ sourceXPlayer.showNotification(TranslateCap("you_confiscated_account", amount, itemName, targetXPlayer.name))
+ targetXPlayer.showNotification(TranslateCap("got_confiscated_account", amount, itemName, sourceXPlayer.name))
+ else
+ sourceXPlayer.showNotification(TranslateCap("quantity_invalid"))
+ end
+ elseif itemType == "item_weapon" then
+ if amount == nil then
+ amount = 0
+ end
+
+ -- does the target player have weapon?
+ if targetXPlayer.hasWeapon(itemName) then
+ targetXPlayer.removeWeapon(itemName)
+ sourceXPlayer.addWeapon(itemName, amount)
+
+ sourceXPlayer.showNotification(TranslateCap("you_confiscated_weapon", ESX.GetWeaponLabel(itemName), targetXPlayer.name, amount))
+ targetXPlayer.showNotification(TranslateCap("got_confiscated_weapon", ESX.GetWeaponLabel(itemName), amount, sourceXPlayer.name))
+ else
+ sourceXPlayer.showNotification(TranslateCap("quantity_invalid"))
+ end
+ end
+end)
+
+RegisterNetEvent("bpt_ammujob:handcuff")
+AddEventHandler("bpt_ammujob:handcuff", function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == "ammu" then
+ TriggerClientEvent("bpt_ammujob:handcuff", target)
+ else
+ print(("[^3WARNING^7] Player ^5%s^7 Attempted To Exploit Handcuffs!"):format(xPlayer.source))
+ end
+end)
+
+RegisterNetEvent("bpt_ammujob:drag")
+AddEventHandler("bpt_ammujob:drag", function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == "ammu" then
+ TriggerClientEvent("bpt_ammujob:drag", target, source)
+ else
+ print(("[^3WARNING^7] Player ^5%s^7 Attempted To Exploit Dragging!"):format(xPlayer.source))
+ end
+end)
+
+RegisterNetEvent("bpt_ammujob:putInVehicle")
+AddEventHandler("bpt_ammujob:putInVehicle", function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == "ammu" then
+ TriggerClientEvent("bpt_ammujob:putInVehicle", target)
+ else
+ print(("[^3WARNING^7] Player ^5%s^7 Attempted To Exploit Garage!"):format(xPlayer.source))
+ end
+end)
+
+RegisterNetEvent("bpt_ammujob:OutVehicle")
+AddEventHandler("bpt_ammujob:OutVehicle", function(target)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer.job.name == "ammu" then
+ TriggerClientEvent("bpt_ammujob:OutVehicle", target)
+ else
+ print(("[^3WARNING^7] Player ^5%s^7 Attempted To Exploit Dragging Out Of Vehicle!"):format(xPlayer.source))
+ end
end)
RegisterNetEvent("bpt_ammujob:getStockItem")
AddEventHandler("bpt_ammujob:getStockItem", function(itemName, count)
+ local source = source
local xPlayer = ESX.GetPlayerFromId(source)
- if xPlayer.job.name == "ammu" then
- TriggerEvent("bpt_addoninventory:getSharedInventory", "society_ammu", function(inventory)
- local item = inventory.getItem(itemName)
-
- -- is there enough in the society?
- if count > 0 and item.count >= count then
- -- can the player carry the said amount of x item?
- if xPlayer.canCarryItem(itemName, count) then
- inventory.removeItem(itemName, count)
- xPlayer.addInventoryItem(itemName, count)
- xPlayer.showNotification(TranslateCap("have_withdrawn", count, item.label))
- else
- xPlayer.showNotification(TranslateCap("player_cannot_hold"))
- end
+ TriggerEvent("bpt_addoninventory:getSharedInventory", "society_ammu", function(inventory)
+ local inventoryItem = inventory.getItem(itemName)
+
+ -- is there enough in the society?
+ if count > 0 and inventoryItem.count >= count then
+ -- can the player carry the said amount of x item?
+ if xPlayer.canCarryItem(itemName, count) then
+ inventory.removeItem(itemName, count)
+ xPlayer.addInventoryItem(itemName, count)
+ xPlayer.showNotification(TranslateCap("have_withdrawn", count, inventoryItem.name))
else
xPlayer.showNotification(TranslateCap("quantity_invalid"))
end
+ else
+ xPlayer.showNotification(TranslateCap("quantity_invalid"))
+ end
+ end)
+end)
+
+RegisterNetEvent("bpt_ammujob:putStockItems")
+AddEventHandler("bpt_ammujob:putStockItems", function(itemName, count)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local sourceItem = xPlayer.getInventoryItem(itemName)
+
+ TriggerEvent("bpt_addoninventory:getSharedInventory", "society_ammu", function(inventory)
+ local inventoryItem = inventory.getItem(itemName)
+
+ -- does the player have enough of the item?
+ if sourceItem.count >= count and count > 0 then
+ xPlayer.removeInventoryItem(itemName, count)
+ inventory.addItem(itemName, count)
+ xPlayer.showNotification(TranslateCap("have_deposited", count, inventoryItem.name))
+ else
+ xPlayer.showNotification(TranslateCap("quantity_invalid"))
+ end
+ end)
+end)
+
+ESX.RegisterServerCallback("bpt_ammujob:getOtherPlayerData", function(source, cb, target, notify)
+ local xPlayer = ESX.GetPlayerFromId(target)
+
+ if notify then
+ xPlayer.showNotification(TranslateCap("being_searched"))
+ end
+
+ if xPlayer then
+ local data = {
+ name = xPlayer.getName(),
+ job = xPlayer.job.label,
+ grade = xPlayer.job.grade_label,
+ inventory = xPlayer.getInventory(),
+ accounts = xPlayer.getAccounts(),
+ weapons = xPlayer.getLoadout(),
+ }
+
+ if Config.EnableESXIdentity then
+ data.dob = xPlayer.get("dateofbirth")
+ data.height = xPlayer.get("height")
+
+ if xPlayer.get("sex") == "m" then
+ data.sex = "male"
+ else
+ data.sex = "female"
+ end
+ end
+
+ TriggerEvent("bpt_status:getStatus", target, "drunk", function(status)
+ if status then
+ data.drunk = ESX.Math.Round(status.percent)
+ end
+ end)
+
+ if Config.EnableLicenses then
+ TriggerEvent("esx_license:getLicenses", target, function(licenses)
+ data.licenses = licenses
+ cb(data)
+ end)
+ else
+ cb(data)
+ end
+ end
+end)
+
+local fineList = {}
+ESX.RegisterServerCallback("bpt_ammujob:getFineList", function(source, cb, category)
+ if not fineList[category] then
+ MySQL.query("SELECT * FROM fine_types WHERE category = ?", { category }, function(fines)
+ fineList[category] = fines
+
+ cb(fines)
end)
else
- print(("[^3WARNING^7] Player ^5%s^7 attempted ^5bpt_ammujob:getStockItem^7 (cheating)"):format(source))
+ cb(fineList[category])
end
end)
-ESX.RegisterServerCallback("bpt_ammujob:getStockItems", function(_, cb)
- TriggerEvent("bpt_addoninventory:getSharedInventory", "society_ammu", function(inventory)
- cb(inventory.items)
+ESX.RegisterServerCallback("bpt_ammujob:getVehicleInfos", function(source, cb, plate)
+ local retrivedInfo = {
+ plate = plate,
+ }
+ if Config.EnableESXIdentity then
+ MySQL.single("SELECT users.firstname, users.lastname FROM owned_vehicles JOIN users ON owned_vehicles.owner = users.identifier WHERE plate = ?", { plate }, function(result)
+ if result then
+ retrivedInfo.owner = ("%s %s"):format(result.firstname, result.lastname)
+ end
+ cb(retrivedInfo)
+ end)
+ else
+ MySQL.scalar("SELECT owner FROM owned_vehicles WHERE plate = ?", { plate }, function(owner)
+ if owner then
+ local xPlayer = ESX.GetPlayerFromIdentifier(owner)
+ if xPlayer then
+ retrivedInfo.owner = xPlayer.getName()
+ end
+ end
+ cb(retrivedInfo)
+ end)
+ end
+end)
+
+ESX.RegisterServerCallback("bpt_ammujob:getArmoryWeapons", function(source, cb)
+ TriggerEvent("bpt_datastore:getSharedDataStore", "society_ammu", function(store)
+ local weapons = store.get("weapons")
+
+ if weapons == nil then
+ weapons = {}
+ end
+
+ cb(weapons)
end)
end)
-RegisterNetEvent("bpt_ammujob:putStockItems")
-AddEventHandler("bpt_ammujob:putStockItems", function(itemName, count)
+ESX.RegisterServerCallback("bpt_ammujob:addArmoryWeapon", function(source, cb, weaponName, removeWeapon)
local xPlayer = ESX.GetPlayerFromId(source)
- local sourceItem = xPlayer.getInventoryItem(itemName)
- if xPlayer.job.name == "ammu" then
- TriggerEvent("bpt_addoninventory:getSharedInventory", "society_ammu", function(inventory)
- local item = inventory.getItem(itemName)
+ if removeWeapon then
+ xPlayer.removeWeapon(weaponName)
+ end
+
+ TriggerEvent("bpt_datastore:getSharedDataStore", "society_ammu", function(store)
+ local weapons = store.get("weapons") or {}
+ local foundWeapon = false
+
+ for i = 1, #weapons, 1 do
+ if weapons[i].name == weaponName then
+ weapons[i].count = weapons[i].count + 1
+ foundWeapon = true
+ break
+ end
+ end
+
+ if not foundWeapon then
+ table.insert(weapons, {
+ name = weaponName,
+ count = 1,
+ })
+ end
+
+ store.set("weapons", weapons)
+ cb()
+ end)
+end)
+
+ESX.RegisterServerCallback("bpt_ammujob:removeArmoryWeapon", function(source, cb, weaponName)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ xPlayer.addWeapon(weaponName, 500)
+
+ TriggerEvent("bpt_datastore:getSharedDataStore", "society_ammu", function(store)
+ local weapons = store.get("weapons") or {}
+
+ local foundWeapon = false
+
+ for i = 1, #weapons, 1 do
+ if weapons[i].name == weaponName then
+ weapons[i].count = (weapons[i].count > 0 and weapons[i].count - 1 or 0)
+ foundWeapon = true
+ break
+ end
+ end
+
+ if not foundWeapon then
+ table.insert(weapons, {
+ name = weaponName,
+ count = 0,
+ })
+ end
+
+ store.set("weapons", weapons)
+ cb()
+ end)
+end)
+
+ESX.RegisterServerCallback("bpt_ammujob:buyJobVehicle", function(source, cb, vehicleProps, type)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local price = GetPriceFromHash(vehicleProps.model, xPlayer.job.grade_name, type)
+
+ -- vehicle model not found
+ if price == 0 then
+ print(("[^3WARNING^7] Player ^5%s^7 Attempted To Buy Invalid Vehicle - ^5%s^7!"):format(source, vehicleProps.model))
+ cb(false)
+ else
+ if xPlayer.getMoney() >= price then
+ xPlayer.removeMoney(price, "Job Vehicle Bought")
+
+ MySQL.insert("INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (?, ?, ?, ?, ?, ?)", { xPlayer.identifier, json.encode(vehicleProps), vehicleProps.plate, type, xPlayer.job.name, true }, function(rowsChanged)
+ cb(true)
+ end)
+ else
+ cb(false)
+ end
+ end
+end)
- if sourceItem.count >= count and count > 0 then
- xPlayer.removeInventoryItem(itemName, count)
- inventory.addItem(itemName, count)
- xPlayer.showNotification(TranslateCap("have_deposited", count, item.label))
+ESX.RegisterServerCallback("bpt_ammujob:storeNearbyVehicle", function(source, cb, plates)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ local plate = MySQL.scalar.await("SELECT plate FROM owned_vehicles WHERE owner = ? AND plate IN (?) AND job = ?", { xPlayer.identifier, plates, xPlayer.job.name })
+
+ if plate then
+ MySQL.update("UPDATE owned_vehicles SET `stored` = true WHERE owner = ? AND plate = ? AND job = ?", { xPlayer.identifier, plate, xPlayer.job.name }, function(rowsChanged)
+ if rowsChanged == 0 then
+ cb(false)
else
- xPlayer.showNotification(TranslateCap("quantity_invalid"))
+ cb(plate)
end
end)
else
- print(("[^3WARNING^7] Player ^5%s^7 attempted ^5bpt_ammujob:putStockItems^7 (cheating)"):format(source))
+ cb(false)
+ end
+end)
+
+function GetPriceFromHash(vehicleHash, jobGrade, type)
+ local vehicles = Config.AuthorizedVehicles[type][jobGrade]
+
+ for i = 1, #vehicles do
+ local vehicle = vehicles[i]
+ if GetHashKey(vehicle.model) == vehicleHash then
+ return vehicle.price
+ end
+ end
+
+ return 0
+end
+
+ESX.RegisterServerCallback("bpt_ammujob:getStockItems", function(source, cb)
+ TriggerEvent("bpt_addoninventory:getSharedInventory", "society_ammu", function(inventory)
+ cb(inventory.items)
+ end)
+end)
+
+ESX.RegisterServerCallback("bpt_ammujob:getPlayerInventory", function(source, cb)
+ local xPlayer = ESX.GetPlayerFromId(source)
+ local items = xPlayer.inventory
+
+ cb({ items = items })
+end)
+
+RegisterNetEvent("bpt_ammujob:spawned")
+AddEventHandler("bpt_ammujob:spawned", function()
+ local playerId = source
+ local xPlayer = ESX.GetPlayerFromId(playerId)
+
+ if xPlayer and xPlayer.job.name == "ammu" then
+ Wait(5000)
+ TriggerClientEvent("bpt_ammujob:updateBlip", -1)
+ end
+end)
+
+RegisterNetEvent("bpt_ammujob:forceBlip")
+AddEventHandler("bpt_ammujob:forceBlip", function()
+ for _, xPlayer in pairs(ESX.GetExtendedPlayers("job", "ammu")) do
+ TriggerClientEvent("bpt_ammujob:updateBlip", xPlayer.source)
+ end
+end)
+
+AddEventHandler("onResourceStart", function(resource)
+ if resource == GetCurrentResourceName() then
+ Wait(5000)
+ for _, xPlayer in pairs(ESX.GetExtendedPlayers("job", "ammu")) do
+ TriggerClientEvent("bpt_ammujob:updateBlip", xPlayer.source)
+ end
end
end)