├── .gitignore ├── LICENSE ├── README.md └── cas-dispatch ├── cfg.lua ├── client.lua ├── fxmanifest.lua ├── server.lua ├── server_hook.lua └── ui ├── Satoshi-Bold.otf ├── Satoshi-Regular.otf ├── cas.js ├── index.html └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Lua sources 2 | luac.out 3 | 4 | # luarocks build files 5 | *.src.rock 6 | *.zip 7 | *.tar.gz 8 | 9 | # Object files 10 | *.o 11 | *.os 12 | *.ko 13 | *.obj 14 | *.elf 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | *.def 26 | *.exp 27 | 28 | # Shared objects (inc. Windows DLLs) 29 | *.dll 30 | *.so 31 | *.so.* 32 | *.dylib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.i*86 39 | *.x86_64 40 | *.hex 41 | 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Fatih 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CAS-Dispatch 2 | 3 | 4 | Usage; 5 | 6 | Some Infos about script; 7 | 8 | 9 | Press "Z" For waypoint. 10 | 11 | 12 | This script working with ESX And QBCore Frameworks. 13 | 14 | 15 | Resmon Values - None (0.00ms) 16 | 17 | 18 | Preview 19 | 20 |  21 | 22 | 23 | ```lua 24 | 25 | GetStreetName = function(coords) 26 | local hashKey = GetStreetNameAtCoord(coords.x, coords.y, coords.z) 27 | local streetName = GetStreetNameFromHashKey(hashKey) 28 | return streetName 29 | end 30 | 31 | 32 | CAS = { 33 | DispatchInfo = { 34 | header = "POLICE ALERT", -- Dispatch Header 35 | event = "Fleeca Bank Robbery", -- Dispatch footer 36 | callsign = "Unknown", -- Event Code 37 | forwho = "ambulance", -- For who? police or ems or law etc. 38 | blips = { 39 | blipText = "Fleeca Bank Robbery", -- Blip Name 40 | blipSprite = 153, -- Blip icon 41 | blipColour = 71, -- Blip colour 42 | blipScale = 0.7, -- Blip scale 43 | blipTime = 2, -- minute 44 | } 45 | } 46 | } 47 | 48 | RegisterCommand("sign14" ,function() -- example 49 | local coords = GetEntityCoords(PlayerPedId()) 50 | TriggerServerEvent("cas-sendDispatch",coords, CAS.DispatchInfo, GetStreetName(coords)) 51 | end) 52 | ``` 53 | -------------------------------------------------------------------------------- /cas-dispatch/cfg.lua: -------------------------------------------------------------------------------- 1 | Config = {} 2 | Config.Framework = "qb" 3 | 4 | Config.AmbulancePerm = "ambulance" 5 | Config.PolicePerm = "police" 6 | Config.UnknownName = "Unknown" 7 | 8 | Config.SetWaypoint = "Z" 9 | 10 | Config.DriveByHeader = "Drive By Shooting" 11 | Config.ShotAlert = { 12 | header = "Gun Shot", 13 | event = "Weapon Model", 14 | callsign = "33-50", 15 | forwho = "police", 16 | blips = { 17 | blipText = "Gun Shot", 18 | blipSprite = 153, 19 | blipColour = 71, 20 | blipScale = 0.7, 21 | blipTime = 2, 22 | } 23 | } 24 | 25 | Config.CarJackingAlert = { 26 | header = "Car Jacking", 27 | event = "", 28 | callsign = "21-49", 29 | forwho = "police", 30 | blips = { 31 | blipText = "Car Jacking", 32 | blipSprite = 153, 33 | blipColour = 71, 34 | blipScale = 0.7, 35 | blipTime = 2, 36 | } 37 | } 38 | 39 | 40 | Config.CivDown = { 41 | header = "Person Down", 42 | event = "", 43 | callsign = "55-88", 44 | forwho = {"police", "ems"}, 45 | blips = { 46 | blipText = "Shutdown", 47 | blipSprite = 153, 48 | blipColour = 71, 49 | blipScale = 0.7, 50 | blipTime = 2, 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /cas-dispatch/client.lua: -------------------------------------------------------------------------------- 1 | local weaponNames = { 2 | [584646201] = "AP-Pistol", 3 | [453432689] = "Baretta", 4 | [3219281620] = "Pistol MK2", 5 | [1593441988] = "Combat Pistol", 6 | [-1716589765] = "Heavy Pistol", 7 | [-1076751822] = "SNS-Pistol", 8 | [-771403250] = "Desert Eagle", 9 | [137902532] = "Vintage Pistol", 10 | [-598887786] = "Marksman Pistol", 11 | [-1045183535] = "Revolver", 12 | [911657153] = "Taser", 13 | [324215364] = "Micro-SMG", 14 | [-619010992] = "Machine-Pistol", 15 | [736523883] = "SMG", 16 | [2024373456] = "SMG MK2", 17 | [-270015777] = "Assault SMG", 18 | [171789620] = "Combat PDW", 19 | [-1660422300] = "Combat MG", 20 | [3686625920] = "Combat MG MK2", 21 | [1627465347] = "Gusenberg", 22 | [-1121678507] = "Mini SMG", 23 | [-1074790547] = "Assaultrifle", 24 | [961495388] = "Assaultrifle MK2", 25 | [-2084633992] = "Carbinerifle", 26 | [4208062921] = "Carbinerifle MK2", 27 | [-1357824103] = "Advancedrifle", 28 | [-1063057011] = "Specialcarbine", 29 | [2132975508] = "Bulluprifle", 30 | [1649403952] = "Compactrifle", 31 | [100416529] = "Sniperrifle", 32 | [205991906] = "Heavy Sniper", 33 | [177293209] = "Heavy Sniper MK2", 34 | [-952879014] = "Marksmanrifle", 35 | [487013001] = "Pumpshotgun", 36 | [2017895192] = "Sawnoff Shotgun", 37 | [-1654528753] = "Bullupshotgun", 38 | [-494615257] = "Assaultshotgun", 39 | [-1466123874] = "Musket", 40 | [984333226] = "Heavyshotgun", 41 | [-275439685] = "Doublebarrel Shotgun", 42 | [317205821] = "Autoshotgun", 43 | [-1568386805] = "GRENADE LAUNCHER", 44 | [-1312131151] = "RPG", 45 | [125959754] = "Compactlauncher", 46 | [-1768145561] = "Scar-L" 47 | } 48 | 49 | 50 | local lastDispatch = nil 51 | RegisterNetEvent("cas-sendDispatchToClient") 52 | AddEventHandler("cas-sendDispatchToClient",function(info,coords) 53 | PlaySound(-1, "Lose_1st", "GTAO_FM_Events_Soundset", 0, 0, 1) 54 | SendNUIMessage({ 55 | action = "show", 56 | info = info 57 | }) 58 | lastDispatch = coords 59 | for i,j in pairs(info) do 60 | CreateDispatchBlip(coords, j.blips) 61 | break 62 | end 63 | end) 64 | 65 | CreateThread(function() 66 | RegisterKeyMapping("waypointDispatch", "Dispatch Waypoint", "keyboard", Config.SetWaypoint) 67 | end) 68 | 69 | RegisterCommand("waypointDispatch",function() 70 | if lastDispatch then 71 | SetNewWaypoint(lastDispatch.x, lastDispatch.y) 72 | end 73 | end) 74 | 75 | 76 | CreateDispatchBlip = function(coords,settings) 77 | local alpha = 150 78 | local blip = AddBlipForCoord(coords) 79 | SetBlipSprite(blip, settings.blipSprite) 80 | SetBlipColour(blip, settings.blipColour) 81 | SetBlipScale(blip, settings.blipScale) 82 | SetBlipAsShortRange(blip, true) 83 | BeginTextCommandSetBlipName("STRING") 84 | AddTextComponentString(settings.blipText) 85 | EndTextCommandSetBlipName(blip) 86 | while alpha ~= 0 do 87 | Citizen.Wait(120 * 4) 88 | alpha = alpha - 1 89 | SetBlipAlpha(blip, alpha) 90 | if alpha == 0 then 91 | RemoveBlip(blip) 92 | return 93 | end 94 | end 95 | end 96 | 97 | 98 | 99 | 100 | GetStreetName = function(coords) 101 | local hashKey = GetStreetNameAtCoord(coords.x, coords.y, coords.z) 102 | local streetName = GetStreetNameFromHashKey(hashKey) 103 | return streetName 104 | end 105 | 106 | 107 | local isShooting = false 108 | local dispatchCooldown = 15000 109 | 110 | Citizen.CreateThread(function() 111 | while true do 112 | Citizen.Wait(0) 113 | if IsPedShooting(PlayerPedId()) then 114 | if not isShooting then 115 | isShooting = true 116 | local coords = GetEntityCoords(PlayerPedId()) 117 | Config.ShotAlert.event = "" 118 | local weaponHash = GetSelectedPedWeapon(PlayerPedId()) 119 | print(weaponHash, GetHashKey(weaponHash)) 120 | local weaponName = weaponNames[weaponHash] 121 | if IsPedDoingDriveby(PlayerPedId()) then 122 | Config.ShotAlert.event = Config.DriveByHeader 123 | else 124 | Config.ShotAlert.event = Config.ShotAlert.event.." "..weaponName 125 | end 126 | TriggerServerEvent("cas-sendDispatch",coords, Config.ShotAlert, GetStreetName(coords)) 127 | Citizen.Wait(dispatchCooldown) 128 | isShooting = false 129 | end 130 | else 131 | isShooting = false 132 | end 133 | end 134 | end) 135 | 136 | 137 | local isHotwiring = false 138 | Citizen.CreateThread(function() 139 | while true do 140 | Citizen.Wait(0) 141 | local playerPed = PlayerPedId() 142 | local coords = GetEntityCoords(playerPed) 143 | if IsPedTryingToEnterALockedVehicle(playerPed) then 144 | local vehicle = GetVehiclePedIsTryingToEnter(playerPed) 145 | if DoesEntityExist(vehicle) and not isHotwiring then 146 | Config.CarJackingAlert.event = "" 147 | local vehicleModel = GetEntityModel(vehicle) 148 | local vehicleName = GetDisplayNameFromVehicleModel(vehicleModel) 149 | isHotwiring = true 150 | Config.CarJackingAlert.event = Config.CarJackingAlert.event.. " Car Model: " ..vehicleName 151 | TriggerServerEvent("cas-sendDispatch",coords, Config.CarJackingAlert, GetStreetName(coords)) 152 | Citizen.Wait(5000) 153 | isHotwiring = false 154 | end 155 | else 156 | isHotwiring = false 157 | end 158 | end 159 | end) 160 | 161 | 162 | RegisterNetEvent("civDown") 163 | AddEventHandler("civDown",function(job,name) 164 | local coords = GetEntityCoords(GetPlayerPed(-1)) 165 | Config.CivDown.event = name.. " is down!" 166 | TriggerServerEvent("cas-sendDispatch",coords, Config.CivDown, GetStreetName(coords)) 167 | end) 168 | -------------------------------------------------------------------------------- /cas-dispatch/fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version "cerulean" 2 | game "gta5" 3 | lua54 "yes" 4 | 5 | client_scripts { 6 | "cfg.lua", 7 | "client.lua" 8 | } 9 | 10 | server_scripts { 11 | "server.lua", 12 | "cfg.lua", 13 | "server_hook.lua" 14 | } 15 | 16 | 17 | 18 | ui_page "ui/index.html" 19 | 20 | 21 | files { 22 | "ui/index.html", 23 | "ui/cas.js", 24 | "ui/style.css", 25 | "ui/Satoshi-Bold.otf", 26 | "ui/Satoshi-Regular.otf", 27 | } -------------------------------------------------------------------------------- /cas-dispatch/server.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | GetPlayerNameByCoords = function(coords) 4 | local players = GetFwPlayers() 5 | local playerName = "Unknown" 6 | local closestPlayer = nil 7 | local closestDistance = -1 8 | for _, player in ipairs(players) do 9 | local playerCoords = GetEntityCoords(GetPlayerPed(player)) 10 | local distance = #(playerCoords - coords) 11 | 12 | if closestPlayer == nil or distance < closestDistance then 13 | closestPlayer = player 14 | closestDistance = distance 15 | end 16 | end 17 | if closestPlayer ~= nil then 18 | local player = GetPlayerById(closestPlayer) 19 | 20 | if player ~= nil and player.PlayerData ~= nil and player.PlayerData.charinfo ~= nil then 21 | playerName = player.PlayerData.charinfo.firstname .. " " .. player.PlayerData.charinfo.lastname 22 | end 23 | end 24 | return { 25 | name = playerName, 26 | nEms = GetClosestJobPerson(coords, Config.AmbulancePerm) or Config.UnknownName, 27 | nPolice = GetClosestJobPerson(coords, Config.PolicePerm) or Config.UnknownName 28 | } 29 | end 30 | 31 | 32 | 33 | 34 | GetClosestJobPerson = function(coords, job) 35 | local closestDistance = math.huge 36 | local closestPlayer = nil 37 | 38 | local players = GetFwPlayers() 39 | for _, player in ipairs(players) do 40 | local xPlayer = GetPlayerById(player) 41 | if GetJobOfPlayer(xPlayer) == job then 42 | local ped = GetPlayerPed(player) 43 | local playerCoords = GetEntityCoords(ped) 44 | local distance = #(coords - playerCoords) 45 | 46 | if distance < closestDistance then 47 | closestDistance = distance 48 | closestPlayer = GetNameOfPlayer(xPlayer) 49 | end 50 | end 51 | end 52 | return closestPlayer 53 | end 54 | 55 | 56 | 57 | RegisterServerEvent("cas-sendDispatch") 58 | AddEventHandler("cas-sendDispatch",function(coords, prmtwo,street) 59 | local dispatchInfos = {} 60 | local playerInfos = GetPlayerNameByCoords(coords) 61 | table.insert(dispatchInfos, { 62 | nPolice = playerInfos.nPolice, 63 | nEms = playerInfos.nEms, 64 | header = prmtwo.header, 65 | street = street, 66 | callsign = prmtwo.callsign, 67 | event = prmtwo.event, 68 | victimName = playerInfos.name, 69 | blips = prmtwo.blips 70 | }) 71 | local players = GetFwPlayers() 72 | for _, player in ipairs(players) do 73 | local xPlayer = GetPlayerById(player) 74 | print(type(prmtwo.forwho)) 75 | if type(prmtwo.forwho) == "table" then 76 | for key,value in pairs(prmtwo.forwho) do 77 | if GetJobOfPlayer(xPlayer) == value then 78 | local source = GetSource(xPlayer) 79 | TriggerClientEvent("cas-sendDispatchToClient",source, dispatchInfos,coords) 80 | end 81 | end 82 | else 83 | if GetJobOfPlayer(xPlayer) == prmtwo.forwho then 84 | local source = GetSource(xPlayer) 85 | TriggerClientEvent("cas-sendDispatchToClient",source, dispatchInfos,coords) 86 | else 87 | print("none") 88 | end 89 | end 90 | end 91 | end) 92 | 93 | RegisterServerEvent("baseevents:onPlayerKilled") 94 | AddEventHandler("baseevents:onPlayerKilled",function() 95 | local src = source 96 | local player = GetPlayerById(src) 97 | if player then 98 | if GetJobOfPlayer(player) == Config.AmbulancePerm or GetJobOfPlayer(player) == Config.PolicePerm then 99 | TriggerClientEvent("civDown", src, GetJobOfPlayer(player), GetNameOfPlayer(player)) 100 | end 101 | end 102 | end) 103 | -------------------------------------------------------------------------------- /cas-dispatch/server_hook.lua: -------------------------------------------------------------------------------- 1 | if Config.Framework == "qb" then 2 | QBCore = exports["qb-core"]:GetCoreObject() 3 | else 4 | ESX = export["es_extended"]:getSharedObject() 5 | end 6 | GetFwPlayers = function() 7 | if Config.Framework == "qb" then 8 | return QBCore.Functions.GetPlayers() 9 | else 10 | return ESX.GetPlayers() 11 | end 12 | end 13 | 14 | GetPlayerById = function(playerId) 15 | if Config.Framework == "qb" then 16 | return QBCore.Functions.GetPlayer(playerId) 17 | else 18 | return ESX.GetPlayerFromId(playerId) 19 | end 20 | end 21 | 22 | 23 | GetNameOfPlayer = function(xPlayer) 24 | if Config.Framework == "qb" then 25 | return xPlayer.PlayerData.charinfo.firstname .. " " .. xPlayer.PlayerData.charinfo.lastname 26 | else 27 | return xPlayer.getName() 28 | end 29 | end 30 | 31 | GetJobOfPlayer = function(xPlayer) 32 | if Config.Framework == "qb" then 33 | return xPlayer.PlayerData.job.name 34 | else 35 | return xPlayer.job.name 36 | end 37 | end 38 | 39 | GetSource = function(xPlayer) 40 | if Config.Framework == "qb" then 41 | return xPlayer.PlayerData.source 42 | else 43 | return xPlayer.source 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /cas-dispatch/ui/Satoshi-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mb-later/CAS-Dispatch/35f25b217d5c4e0fc4c6d4eb758deb83e6dbb383/cas-dispatch/ui/Satoshi-Bold.otf -------------------------------------------------------------------------------- /cas-dispatch/ui/Satoshi-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mb-later/CAS-Dispatch/35f25b217d5c4e0fc4c6d4eb758deb83e6dbb383/cas-dispatch/ui/Satoshi-Regular.otf -------------------------------------------------------------------------------- /cas-dispatch/ui/cas.js: -------------------------------------------------------------------------------- 1 | window.addEventListener("message",function(event){ 2 | let data = event.data 3 | if (data.action == "show") { 4 | Dispatch(data.info) 5 | } 6 | }) 7 | 8 | const Dispatch = function(data) { 9 | const activeContainers = $(".d-container:visible"); 10 | $.each(data, function(key, value) { 11 | var content = ` 12 |
 18 |
18 |                 ${value.nPolice}
21 |${value.event}.
26 | 29 |
29 |                 ${value.nEms}
32 | 58 |
58 |