├── README.md ├── client.lua ├── fxmanifest.lua ├── interface ├── interface.css ├── interface.html └── interface.js └── settings.lua /README.md: -------------------------------------------------------------------------------- 1 | # fs-spawnselector 2 | 3 | Dont Not Replace qb-spawn with this ⚠⚠⚠⚠⚠ 4 | 5 | ```My Discord``` 6 | - [Discord](https://discord.gg/UFng7DWnWP) 7 | 8 | 9 | * 10 | ![showcase](https://cdn.discordapp.com/attachments/784243374269661195/990042002550829097/unknown.png) 11 | 12 | * 13 | # Manual Installation 14 | This Is How It Works. 15 | 16 | Ok Go To [qb-apartments/client/main.lua] Then Go To The Event `apartments:client:setupSpawnUI` And Replace It With This 17 | 18 | ``` 19 | RegisterNetEvent('apartments:client:setupSpawnUI', function(cData) 20 | QBCore.Functions.TriggerCallback('apartments:GetOwnedApartment', function(result) 21 | if result then 22 | TriggerEvent('qb-spawn:client:setupSpawns', cData, false, nil) 23 | TriggerEvent("apartments:client:SetHomeBlip", result.type) 24 | else 25 | if Apartments.Starting then 26 | TriggerEvent('qb-spawn:client:setupSpawns', cData, true, Apartments.Locations) 27 | TriggerEvent('qb-spawn:client:openUI', true) 28 | else 29 | TriggerEvent('qb-spawn:client:setupSpawns', cData, false, nil) 30 | TriggerEvent('qb-spawn:client:openUI', true) 31 | end 32 | end 33 | end, cData.citizenid) 34 | end) 35 | ``` 36 | 37 | * 38 | 39 | Then Go To [qb-spawn/client.lua] Then Go To The Event `qb-spawn:client:setupSpawns` And Replace It With This 40 | 41 | ``` 42 | RegisterNetEvent('qb-spawn:client:setupSpawns', function(cData, new, apps) 43 | if not new then 44 | TriggerEvent('fs-spawnselector:set') 45 | elseif new then 46 | SendNUIMessage({ 47 | action = "setupAppartements", 48 | locations = apps, 49 | }) 50 | end 51 | end) 52 | ``` 53 | * 54 | To Change The Logo Go To `interface.css` In Line 7 55 | * 56 | If You Want The Locations To Not Be By Jobs Go To `fs-spawnselector/settings.lua` And Comment -- On The Jobs 57 | * 58 | # Here Is The Original Fork 59 | 60 | [qb-spawnselector](https://github.com/arabcodingteam/qb-spawnselector) 61 | -------------------------------------------------------------------------------- /client.lua: -------------------------------------------------------------------------------- 1 | local hasFocus, locations, fading, current = false, false, {}; 2 | local QBCore = exports['qb-core']:GetCoreObject() 3 | 4 | function BuildSelector(data) 5 | locations, playerData, hasFocus = BuildLocations(data), data, true; 6 | BuildCamera(1); 7 | SetNuiFocus(true, true); 8 | SendNUIMessage({ 9 | event = "show", 10 | }) 11 | end 12 | 13 | 14 | RegisterNetEvent("fs:selector:show", function(data) 15 | if data then 16 | BuildSelector(data); 17 | else 18 | TriggerServerEvent("fs:selector:show") 19 | end 20 | end) 21 | 22 | 23 | PlayerJob = {} 24 | 25 | RegisterNetEvent('QBCore:Client:OnPlayerLoaded') 26 | AddEventHandler('QBCore:Client:OnPlayerLoaded', function() 27 | PlayerJob = QBCore.Functions.GetPlayerData().job 28 | end) 29 | 30 | RegisterNetEvent('QBCore:Client:OnJobUpdate') 31 | AddEventHandler('QBCore:Client:OnJobUpdate', function(JobInfo) 32 | PlayerJob = JobInfo 33 | end) 34 | 35 | function BuildCamera(index) 36 | current = index and locations[index]; 37 | if current then 38 | current.index, fading, ped = index, true, PlayerPedId() 39 | DoScreenFadeOut(0); 40 | RequestCollisionAtCoord(current.spawn.x, current.spawn.y, current.spawn.z); 41 | RequestCollisionAtCoord(current.coords.x, current.coords.y, current.coords.z); 42 | SetEntityVisible(ped, false) 43 | SetEntityCoords(ped, current.spawn.x, current.spawn.y, current.spawn.z); 44 | SetEntityHeading(ped, current.spawn.w); 45 | FreezeEntityPosition(ped, true); 46 | SetEntityCollision(ped, false, false); 47 | 48 | if current.camera then 49 | SetCamActive(current.camera, false) 50 | end 51 | 52 | current.camera = CreateCameraWithParams("DEFAULT_SCRIPTED_CAMERA", current.coords.x, current.coords.y, current.coords.z, current.rot.x, current.rot.y, current.rot.z, 60.00, false, 0); 53 | SetCamActive(current.camera, true); 54 | RenderScriptCams(true, false, 1, true, true); 55 | 56 | SendNUIMessage({ 57 | event = "update", 58 | name = current.name, 59 | label = current.label 60 | }) 61 | local timeout = 500; 62 | while not HasCollisionLoadedAroundEntity(ped) and timeout ~= 0 do 63 | timeout = timeout - 1 64 | Wait(10) 65 | end 66 | 67 | Wait(500) 68 | 69 | DoScreenFadeIn(1000); 70 | fading = false; 71 | end 72 | end 73 | 74 | function Spawn() 75 | SetGameplayCamRelativeRotation(0.0, 0.0, 0.0); 76 | local ped, coord = PlayerPedId(), GetGameplayCamCoord(); 77 | SetCamActive(current.camera, false) 78 | 79 | if current.name == "prison" and playerData.jail then 80 | TriggerEvent("prison:client:Enter", playerData.jail); 81 | RenderScriptCams(false, false, 0, true, true); 82 | else 83 | RenderScriptCams(false, true, 1000, true, true); 84 | Wait(200) 85 | end 86 | 87 | SetEntityVisible(ped, true); 88 | FreezeEntityPosition(ped, false); 89 | SetEntityCollision(ped, true, true); 90 | SendNUIMessage({ event = "hide" }); 91 | SetNuiFocus(false, false); 92 | Wait(800); 93 | DestroyCam(current.camera, true); 94 | locations, playerData, hasFocus, current = nil; 95 | TriggerEvent('QBCore:Client:OnPlayerLoaded') 96 | end 97 | 98 | function spawnplayer() 99 | local PlayerData = QBCore.Functions.GetPlayerData() 100 | local ped = PlayerPedId() 101 | SetCamActive(current.camera, false) 102 | 103 | if current.name == "prison" and playerData.jail then 104 | TriggerEvent("prison:client:Enter", playerData.jail); 105 | RenderScriptCams(false, false, 0, true, true); 106 | else 107 | DoScreenFadeOut(250) 108 | Wait(500) 109 | RenderScriptCams(false, true, 2000, true, true); 110 | SetEntityVisible(ped, true) 111 | SetEntityCollision(ped, true, true) 112 | SendNUIMessage({ event = "hide" }) 113 | SetNuiFocus(false, false) 114 | DestroyCam(current.camera, true) 115 | Wait(5000) 116 | DoScreenFadeIn(1000) 117 | TriggerScreenblurFadeIn(1000) 118 | SetEntityCoords(PlayerPedId(), PlayerData.position.x, PlayerData.position.y, PlayerData.position.z - 0.9, 0, 0, 0, false) 119 | SetCamParams(Cam, PlayerData.position.x, PlayerData.position.y, PlayerData.position.z + 300, -85.0, 0.00, 0.00, 100.0, 7200, 0, 0, 2) 120 | SetCamParams(Cam, PlayerData.position.x, PlayerData.position.y, PlayerData.position.z + 10, -40.0, 0.00, 0.00, 100.0, 5000, 0, 0, 2) 121 | FreezeEntityPosition(ped, false) 122 | TriggerEvent('QBCore:Client:OnPlayerLoaded') 123 | Wait(700) 124 | TriggerScreenblurFadeOut(1000.0) 125 | print('spawned') 126 | end 127 | end 128 | 129 | RegisterNUICallback("spawn", Spawn); 130 | RegisterNUICallback("lastloc", spawnplayer); 131 | 132 | function BuildLocations(data) 133 | local results = {}; 134 | 135 | if data then 136 | if data.position and not data.jail then 137 | local coords, rot = BuildCameraProperties(vector3(data.position.x, data.position.y, data.position.z)); 138 | results[1] = { name = "last", label = "Last Location", coords = coords, rot = rot, spawn = vector4(data.position.x, data.position.y, data.position.z, 100) }; 139 | end 140 | 141 | 142 | for i=1, #Settings.Locations do 143 | local location = Settings.Locations[i]; 144 | if (location.name == "prison" and data.jail) or (not location.job or location.job == PlayerJob.name) and not data.jail then 145 | results[#results+1] = location; 146 | end 147 | end 148 | end 149 | 150 | return results; 151 | end 152 | 153 | function BuildCameraProperties(vector) 154 | return vector-vector3(-26.334, -4.58, -17.80), vector3(-32.76, 4.26, 100.72) 155 | end 156 | 157 | RegisterNUICallback("forward", function(data) 158 | if not fading then 159 | BuildCamera(locations[current.index+1] ~= nil and current.index+1 or 1); 160 | end 161 | end) 162 | 163 | RegisterNUICallback("backward", function(data) 164 | if not fading then 165 | BuildCamera(current.index-1 > 0 and current.index-1 or #locations); 166 | end 167 | end) 168 | 169 | RegisterNetEvent("fs-spawnselector:set") 170 | AddEventHandler("fs-spawnselector:set" , function() 171 | BuildSelector(''); 172 | end) 173 | -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'bodacious' 2 | games { 'rdr3', 'gta5' } 3 | version '1.0.0' 4 | 5 | client_script 'client.lua' 6 | client_script 'settings.lua' 7 | 8 | ui_page('interface/interface.html') 9 | 10 | files { 11 | 'interface/interface.html', 12 | 'interface/*', 13 | } 14 | 15 | -------------------------------------------------------------------------------- /interface/interface.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Heebo&display=swap'); 2 | @import url('https://fonts.googleapis.com/css?family=Poppins:900i'); 3 | 4 | body { 5 | display: none; 6 | margin: 0%; 7 | background-image: url("https://cdn.discordapp.com/attachments/784243374269661195/990038298124750909/fb67f1973ee599961d884fb5933b0356263b7e2a_1.png"); /* change this to change the logo */ 8 | background-repeat: no-repeat; 9 | background-size: 27%; 10 | font-family: 'Heebo', sans-serif; 11 | color: white; 12 | user-select: none; 13 | font-weight: 600; 14 | } 15 | 16 | .shadow { 17 | position: fixed; 18 | box-shadow:100px 100px 800px 200px rgb(0 0 0 / 46%) inset; 19 | width: 100%; 20 | height: 100%; 21 | } 22 | 23 | .location { 24 | z-index: 999; 25 | position: absolute; 26 | left: 68%; 27 | bottom: 20%; 28 | } 29 | 30 | .location .name { 31 | font-size: 3.5vh; 32 | font-family: 'Poppins', sans-serif; 33 | text-shadow: -2px 2px 0px #0d6efd, 34 | -4px 4px 0px #000000, 35 | -6px 6px 0px #0d6efd; 36 | } 37 | 38 | .location .hr { 39 | margin: 1vh 0vh 1vh 0vh; 40 | filter: blur(0.1vh); 41 | -webkit-filter: blur(0.1vh); 42 | background-color: RGBA(0,0,0, 0.3); 43 | width: 50vh; 44 | padding: 0.3vh 0.2vh 0.3vh 0.2vh; 45 | border-radius: 1vh; 46 | } 47 | 48 | .location .spawn { 49 | font-size: 1.40vh; 50 | text-align: right; 51 | float: right; 52 | padding: 3vh 10vh 3vh 10vh; 53 | font-family: 'Poppins', sans-serif; 54 | background-color: #363636; 55 | color: rgb(255, 255, 255); 56 | transition: color 200ms; 57 | box-shadow: inset 0px 15px 10px -15px #0d6efd, inset 15px 0px 10px -15px #0d6efd; 58 | transform: skewX(-15deg); 59 | transition: ease-in 0.8s; 60 | } 61 | 62 | .location .spawn:hover { 63 | box-shadow: inset 0 30vh 0 0 #007bff; 64 | color: black; 65 | } 66 | 67 | .location .lastloc { 68 | font-size: 1.40vh; 69 | text-align: right; 70 | float: right; 71 | padding: 3vh 7vh 3vh 7vh; 72 | background-color: #363636; 73 | font-family: 'Poppins', sans-serif; 74 | color: rgb(255, 255, 255); 75 | transition: color 200ms; 76 | box-shadow: inset 0px -15px 10px -15px #0d6efd, inset -15px 0px 10px -15px #0d6efd; 77 | transform: skewX(-15deg); 78 | transition: ease-in 0.8s; 79 | } 80 | 81 | .location .lastloc:hover { 82 | box-shadow: inset 0 -30vh 0 0 #0d6efd; 83 | color: black; 84 | } 85 | 86 | .buttons { 87 | z-index: 999; 88 | position: absolute; 89 | right: 4%; 90 | bottom: 13%; 91 | display: flex; 92 | } 93 | 94 | .buttons .button { 95 | font-size: 1.70vh; 96 | text-align: right; 97 | float: right; 98 | padding: 3vh 7vh 3vh 7vh; 99 | font-family: 'Poppins', sans-serif; 100 | background-color: #363636; 101 | color: rgb(255 255 255); 102 | transition: color 200ms; 103 | box-shadow: inset 0px 15px 10px -15px #007bff, inset 15px 0px 10px -15px #0d6efd; 104 | transform: skewX(-15deg); 105 | transition: ease-in 0.8s; 106 | } 107 | 108 | .buttons .button1 { 109 | font-size: 1.40vh; 110 | text-align: right; 111 | float: right; 112 | padding: 3vh 7vh 3vh 7vh; 113 | background-color: rgba(50, 50, 50, 0.35); 114 | font-family: 'Poppins', sans-serif; 115 | color: rgb(255, 255, 255); 116 | transition: color 200ms; 117 | box-shadow: inset 0px -15px 10px -15px #0d6efd, inset -15px 0px 10px -15px #0d6efd; 118 | transform: skewX(-15deg); 119 | transition: ease-in 0.8s; 120 | } 121 | 122 | .buttons .button i { 123 | position: absolute; 124 | left: 50%; 125 | top: 53%; 126 | transform: translate(-50%, -50%); 127 | } 128 | 129 | .buttons .button:hover { 130 | box-shadow: inset 0 30vh 0 0 #003584; 131 | color: white; 132 | } 133 | 134 | .buttons .button1 i { 135 | position: absolute; 136 | left: 50%; 137 | top: 50%; 138 | transform: translate(-50%, -50%); 139 | } 140 | 141 | .buttons .button1:hover { 142 | box-shadow: inset 0 -30vh 0 0 #0d6efd; 143 | color: black; -------------------------------------------------------------------------------- /interface/interface.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
HOSPITAL
16 |
17 |
SPAWN
18 |
LAST LOCATION
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /interface/interface.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('message', function(event) { 2 | let data = event.data; 3 | 4 | switch (data.event) { 5 | case 'show': 6 | $("body").show(); 7 | break; 8 | 9 | case 'hide': 10 | $("body").hide(); 11 | break; 12 | 13 | case 'update': 14 | $(".name").html(data.label); 15 | break; 16 | } 17 | }); 18 | 19 | $(".button").click(function() { 20 | let el = $(this), type = el.attr("type"); 21 | if (type) { 22 | $.post(`https://fs-spawnselector/${type}`); 23 | } 24 | }); 25 | 26 | $(".spawn").click(function() { 27 | $.post(`https://fs-spawnselector/spawn`); 28 | }); 29 | 30 | $(".lastloc").click(function() { 31 | $.post(`https://fs-spawnselector/lastloc`); 32 | }); 33 | -------------------------------------------------------------------------------- /settings.lua: -------------------------------------------------------------------------------- 1 | Settings = {} 2 | 3 | Settings.Locations = { 4 | ---Ems 5 | { name = "hospital", 6 | label = "Pillbox Hospital", 7 | job = "ambulance", 8 | coords = vector3(270.32, -564.83, 53.52), 9 | rot = vector3(-29.46, -0.0, -123.25), 10 | spawn = vector4(299.64801, -575.1514, 43.260845, 76.685317) }, 11 | ---Police 12 | { name = "prison", 13 | job = "police", 14 | label = "Prison", 15 | coords = vector3(1875.56, 2561.128, 55.37), 16 | rot = vector3(-18.36, 1.70, 47.65), 17 | spawn = vector4(1847.7116, 2585.9758, 45.67237, 100.0) }, 18 | 19 | { name = "lspd", 20 | job = "police", 21 | label = "Los Santos Police Department", 22 | coords = vector3(401.63, -978.86, 45.244), 23 | rot = vector3(-26.97, -0.0, -105.56), 24 | spawn = vector4(428.26644, -984.8966, 30.712158, 1.9879124) }, 25 | 26 | { name = "sspd", 27 | job = "police" , 28 | label = "Sandy Police Department", 29 | coords = vector3(1854.272, 3662.382, 38.67), 30 | rot = vector3(-13.88, 2.1344, -13.59), 31 | spawn = vector4(1853.7364, 3680.9487, 34.26662, 209.94386) }, 32 | 33 | { name = "vcpd", 34 | job = "police" , 35 | label = "Vespucci Police Department", 36 | coords = vector3(-1103.89, -787.24, 29.41), 37 | rot = vector3(-25.67, -4.26, -176.77), 38 | spawn = vector4(-1094.611, -811.1005, 19.287847, 39.936511) }, 39 | 40 | { name = "ppd", 41 | job = "police" , 42 | label = "PaletoBay Police Department", 43 | coords = vector3(-400.59, 6016.4, 39.85), 44 | rot = vector3(-14.85577, -0.0, 101.91), 45 | spawn = vector4(-446.12, 6024.19, 31.49, 319.81) }, 46 | 47 | ---Mechanics 48 | { name = "lossantoscustoms", 49 | job = "mechanic" , 50 | label = "Los Santos Customs", 51 | coords = vector3(-395.61, -120.27, 46.16), 52 | rot = vector3(-13.88, 2.1344, 277.22), 53 | spawn = vector4(-362.56, -127.52, 38.7, 69.98) }, 54 | 55 | { name = "paletobaycustoms", 56 | job = "mechanic" , 57 | label = "Paleto Bay Customs", 58 | coords = vector3(131.26, 6607.07, 36.26), 59 | rot = vector3(-13.88, 2.1344, 43.37), 60 | spawn = vector4(123.43, 6626.36, 31.93, 227.06) }, 61 | 62 | { name = "bennys", 63 | job = "mechanic" , 64 | label = "Bennys Customs", 65 | coords = vector3(-216.92, -1291.07, 35.89), 66 | rot = vector3(-13.88, 2.1344, 207.35), 67 | spawn = vector4(-209.95, -1308.53, 31.29, 350.86) }, 68 | 69 | ---Civilians 70 | { name = "pinkcage", 71 | label = "Pink Cage Motel", 72 | coords = vector3(320.82, -254.77, 72.66), 73 | rot = vector3(-29.28, -0.0, 1.53), 74 | spawn = vector4(313.76745, -230.6358, 53.990818, 153.79005) }, 75 | 76 | { name = "cityhall", 77 | label = "City Hall", 78 | coords = vector3(-532.52, -237.43, 49.22), 79 | rot = vector3(-23.58, -0.0, 17.22), 80 | spawn = vector4(-536.2222, -226.3347, 37.666244, 212.51023) }, 81 | 82 | { name = "fishing", 83 | label = "Fishing Yard", 84 | coords = vector3(-1879.11, -1254.358, 15.033), 85 | rot = vector3(-14.85577, -0.0, -67.75), 86 | spawn = vector4(-1850.43, -1232.158, 13.01728, 141.12789) }, 87 | 88 | { name = "legionsquare", 89 | label = "LegionSquare", 90 | coords = vector3(106.96, -1023.1, 67.55), 91 | rot = vector3(-14.85577, -0.0, -67.75), 92 | spawn = vector4(200.26, -929.81, 30.69, 328.29) }, 93 | 94 | { name = "mirrorpark", 95 | label = "MirrorPark", 96 | coords = vector3(903.91, -744.56, 111.59), 97 | rot = vector3(-14.85577, -0.0, -67.75), 98 | spawn = vector4(1079.03, -705.42, 57.68, 134.61) }, 99 | 100 | { name = "paletobay", 101 | label = "PaletoBay", 102 | coords = vector3(-38.93, 6314.08, 47.71), 103 | rot = vector3(-23.58, -0.0, 64.73), 104 | spawn = vector4(-92.61, 6325.49, 31.49, 276.6) }, 105 | 106 | { name = "vehicleshop", 107 | label = "PDM", 108 | coords = vector3(-74.46, -1118.379, 32.82), 109 | rot = vector3(-15.45, 4.26, -64.80), 110 | spawn = vector4(-42.1563, -1108.702, 26.438091, 162.17939) }, 111 | 112 | { name = "impound", 113 | label = "Impound", 114 | coords = vector3(433.26, -1619.97, 39.57), 115 | rot = vector3(-15.45, -0.0, 111.41), 116 | spawn = vector4(412.42, -1615.29, 29.29, 317.9) }, 117 | 118 | } 119 | --------------------------------------------------------------------------------