├── images
├── key1.png
├── token.png
└── cayo_deliverynote.png
├── fxmanifest.lua
├── server
└── server.lua
├── locales
└── en.lua
├── README.md
├── config.lua
├── client
└── client.lua
└── LICENSE
/images/key1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coffeelot/cw-boostjob/HEAD/images/key1.png
--------------------------------------------------------------------------------
/images/token.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coffeelot/cw-boostjob/HEAD/images/token.png
--------------------------------------------------------------------------------
/images/cayo_deliverynote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Coffeelot/cw-boostjob/HEAD/images/cayo_deliverynote.png
--------------------------------------------------------------------------------
/fxmanifest.lua:
--------------------------------------------------------------------------------
1 | fx_version 'cerulean'
2 |
3 | game 'gta5'
4 |
5 | shared_scripts {
6 | '@qb-core/shared/locale.lua',
7 | 'locales/en.lua',
8 | 'config.lua',
9 | }
10 |
11 | client_scripts{
12 | '@PolyZone/client.lua',
13 | '@PolyZone/BoxZone.lua',
14 | 'client/*.lua',
15 | }
16 |
17 | server_scripts{
18 | 'server/*.lua',
19 | }
20 |
21 |
22 | dependency 'qb-target'
23 | dependency 'ps-ui'
--------------------------------------------------------------------------------
/server/server.lua:
--------------------------------------------------------------------------------
1 | local QBCore = exports['qb-core']:GetCoreObject()
2 | local Cooldown = false
3 |
4 |
5 |
6 | RegisterServerEvent('cw-boostjob:server:startr', function(jobId)
7 | local src = source
8 | local Player = QBCore.Functions.GetPlayer(src)
9 |
10 |
11 | if Config.UseTokens then
12 | TriggerEvent('cw-tokens:server:TakeToken', src, Config.Jobs[jobId].token)
13 | TriggerClientEvent('QBCore:Notify', src, Lang:t("success.send_email_right_now"), 'success')
14 | TriggerEvent('cw-boostjob:server:coolout')
15 | TriggerClientEvent('cw-boostjob:client:runactivate', src)
16 |
17 | else
18 | if Player.PlayerData.money['cash'] >= Config.Jobs[jobId].RunCost then
19 | Player.Functions.RemoveMoney('cash', Config.Jobs[jobId].RunCost, "Running Costs")
20 | Player.Functions.RemoveItem('swap_token', 1)
21 | TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items['swap_token'], "remove")
22 | TriggerClientEvent('QBCore:Notify', src, Lang:t("success.send_email_right_now"), 'success')
23 | TriggerEvent('cw-boostjob:server:coolout')
24 | TriggerClientEvent('cw-boostjob:client:runactivate', src)
25 | else
26 | TriggerClientEvent('QBCore:Notify', source, Lang:t("error.you_dont_have_enough_money"), 'error')
27 | end
28 | end
29 | end)
30 |
31 | RegisterServerEvent('cw-boostjob:server:giveSlip', function(model)
32 | local src = source
33 | local Player = QBCore.Functions.GetPlayer(src)
34 | local item = 'swap_slip'
35 | local info = {}
36 | info.vehicle = model
37 |
38 | Player.Functions.AddItem(item, 1, nil, info)
39 | TriggerClientEvent('inventory:client:ItemBox', source, QBCore.Shared.Items[item], "add")
40 |
41 | end)
42 |
43 |
44 | -- cool down for job
45 | RegisterServerEvent('cw-boostjob:server:coolout', function()
46 | Cooldown = true
47 | local timer = Config.Cooldown * 1000
48 | while timer > 0 do
49 | Wait(1000)
50 | timer = timer - 1000
51 | if timer == 0 then
52 | Cooldown = false
53 | end
54 | end
55 | end)
56 |
57 | QBCore.Functions.CreateCallback("cw-boostjob:server:coolc",function(source, cb)
58 |
59 | if Cooldown then
60 | cb(true)
61 | else
62 | cb(false)
63 | end
64 | end)
65 |
--------------------------------------------------------------------------------
/locales/en.lua:
--------------------------------------------------------------------------------
1 | local Translations = {
2 | error = {
3 | ["canceled"] = "Canceled",
4 | ["someone_recently_did_this"] = "Someone recently did this, try again later..",
5 | ["cannot_do_this_right_now"] = "Cannot do this right now...",
6 | ["you_failed"] = "You failed!",
7 | ["you_cannot_do_this"] = "You cannot do this..",
8 | ["you_dont_have_enough_money"] = "You Dont Have Enough Money",
9 | },
10 | success = {
11 | ["case_has_been_unlocked"] = "Security case has been unlocked",
12 | ["you_removed_first_security_case"] = "You removed the the first layer of security on the case",
13 | ["you_got_paid"] = "You got paid",
14 | ["send_email_right_now"] = "I will send you an e-mail right now!",
15 | ["car_beep"] = "There is something beeping??",
16 | ["car_beep_stop"] = "The beeping stopped.",
17 | },
18 | info = {
19 | ["talking_to_boss"] = "Talking to Hector..",
20 | ["unlocking_case"] = "Unlocking case..",
21 | ["checking_quality"] = "Checking Quality",
22 | ["dropoff"] = "Drop off car",
23 | ["paperslip"] = "There was a paper slip layin next to where you left the car."
24 | },
25 | mailstart = {
26 | ["sender"] = "Unknown",
27 | ["subject"] = "Vehicle Location",
28 | ["message"] = "Updated your gps with the location to the vehicle.",
29 | },
30 | mailSecond = {
31 | ["sender"] = "Unknown",
32 | ["subject"] = "Car Collection",
33 | ["message"] = "Looks like you got the Car. There might be a tracker. I'll send you the dropoff location when it's safe.",
34 | },
35 | mailEnd = {
36 | ["sender"] = "Unknown",
37 | ["subject"] = "Goods Delivered",
38 | ["message"] = "Good job. Take the slip to someone who knows what to do",
39 | },
40 | police = {
41 | ["alert"] = " Car Theft In Progress (Tracker active): "
42 | }
43 | }
44 |
45 | Lang = Locale:new({
46 | phrases = Translations,
47 | warnOnMissing = true
48 | })
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # High End Boosting 🚘🚔
2 |
3 | This script adds car boosting jobs. To be able to take these you need an item, a special token (You have to add these to your server circlation yourself but the item is included in the script). The jobs are fairly straight forward: When you got the token, head over to Hector, the guy who gives you the missions. If you have a token you can pick any job, but you need to pay the entry fee. Hector will give you a location of where the car is. Head over there. Some jobs you can sneak and steal without even firing a single bullet, but some might take more brute force. Steal the car and wait for the tracker to turn off. When it's off Hector will give you the GPS location for the dropoff spot. Deliver the car and you will be handed a slip that says Hector owes you some parts. You can take these slips to any [cw-vehicleswap](https://github.com/Coffeelot/cw-vehicleswap) spot that does special jobs, and if you have the correct car you can get it modified.
4 |
5 | Only includes 3 jobs and 3 locations. Up to you to add what you want to add! The slip you get will hold the value of the name of the car you take, so it will work with any type of car you add to this script. All you need to do is add a special swap in [cw-vehicleswap](https://github.com/Coffeelot/cw-vehicleswap) where that model is used, see the special swaps in the bottom of the config for examples.
6 |
7 | This is a companion script for [cw-vehicleswap](https://github.com/Coffeelot/cw-vehicleswap).
8 |
9 | # Preview 📽
10 | [](https://youtu.be/3BmZ8fIAXpg)
11 |
12 | # Links
13 | ### ⭐ Check out our [Tebex store](https://cw-scripts.tebex.io/category/2523396) for some cheap scripts ⭐
14 |
15 |
16 | ### [More free scripts](https://github.com/stars/Coffeelot/lists/cw-scripts) 👈
17 |
18 | ### Support, updates and script previews:
19 |
20 |
21 |
22 |
23 | # Config 🔧
24 | The script has Jobs and Locations split up, and randomizes locations each time you take the job.\
25 |
26 | At the top of the Config you will find `Config.UseTokens = false`. Change `false` to `true` if you want to use [cw-tokens](https://github.com/Coffeelot/cw-tokens).
27 | ## locations object
28 | **Guards**: This holds all the guards. Guards are defined with `model`, `weapon` and (optionally if you add `GuardPositions`) `coords`\
29 | **GuardPositions**: Holds Vector4s of potential positions guards can be placed at\
30 | **Civilians**: Same as guards, but passive NPCs\
31 | **CivilianPositions**: Same as GuardPositions, but passive NPCs\
32 | **GuardCars**: Vehicles that will spawn. Each one is defined by `model` and `coords`\
33 | **VehiclePosition**: Postion of the vehicle you are stealing\
34 |
35 | ## job object
36 | **Model**: Model of the car you are stealing\
37 | **RunCost**: Cost to take the job\
38 | **Timer**: Timer on the tracker (tracker currently isn't working)\
39 | **MissionDescription**: Text that shows up when you interact with Hector\
40 | **Messages**: These are Optional, but if you want to personalize the messages per mission you can add it here. First are sent when you take the job. Second are send when you got the car. Third are sent when you turn it in.\
41 | **MinimumPolice**: Minimum police required to take the job\
42 | **Locations**: Which of the locations can this mission use\
43 |
44 | Don't forget to add the jobs in the Config.Jobs!
45 |
46 | # Add to qb-core ❗
47 | Items to add to qb-core>shared>items.lua
48 | ```
49 | ["swap_slip"] = {["name"] = "swap_slip", ["label"] = "Vehicle Swap Slip", ["weight"] = 100, ["type"] = "item", ["image"] = "cayo_deliverynote.png", ["unique"] = true, ["useable"] = false, ['shouldClose'] = false, ["combinable"] = nil, ["description"] = "Document that proves you can get your car swapped"},
50 | ["swap_token"] = {["name"] = "swap_token", ["label"] = "A weird gold coin", ["weight"] = 100, ["type"] = "item", ["image"] = "token.png", ["unique"] = false, ["useable"] = false, ['shouldClose'] = false, ["combinable"] = nil, ["description"] = "Smells a bit like oil and old farming equipment"},
51 |
52 | ```
53 | ## Making the names show up in to the Inventory 📦
54 | If you want to make the vehicle name show up in QB-Inventory:
55 | Open `app.js` in `qb-inventory`. In the function `FormatItemInfo` you will find several if statements. Head to the bottom of these and add this before the second to last `else` statement (after the `else if` that has `itemData.name == "labkey"`). Then add this between them:
56 | ```
57 | else if (itemData.name == "swap_slip") {
58 | $(".item-info-title").html("
" + itemData.label + "
"); 59 | $(".item-info-description").html("Vehicle: " + itemData.info.vehicle + "
"); 60 | } 61 | ``` 62 | 63 | Also make sure the images are in qb-inventory>html>images 64 | 65 | # Dependencies 66 | 67 | * qb-target - https://github.com/BerkieBb/qb-target 68 | 69 | 70 | ## Developed by Coffeelot#1586 and Wuggie#1683 71 | -------------------------------------------------------------------------------- /config.lua: -------------------------------------------------------------------------------- 1 | Config = {} 2 | 3 | Config.UseTokens = false 4 | 5 | Config.Cooldown = 1 --- Cooldown until next allowed meth run 6 | Config.DefaultValues = { 7 | armor = 10, 8 | accuracy = 40, 9 | } 10 | Config.Choptimer = 20000 11 | Config.ChopEmote = "welding" 12 | 13 | Config.DropoffLocations = { 14 | vector4(447.17, 3523.33, 33.21, 20), 15 | vector4(202.23, 2456.97, 55.71, 20), 16 | vector4(1901.19, 4918.38, 48.71, 158.37), 17 | vector4(2906.07, 4343.47, 50.3, 252.46), 18 | vector4(278.51, -1740.11, 29.38, 137.99), 19 | vector4(1091.85, -789.64, 58.26, 175.75), 20 | vector4(475.37, -1329.48, 29.12, 31.79) 21 | 22 | } 23 | 24 | Config.Boss = { 25 | coords = vector4(-194.01, 6250.71, 31.49, 316.8), 26 | model = 's_m_y_xmech_02', 27 | missionTitle = "Accept ElegyRetro theft job", 28 | animation = 'CODE_HUMAN_MEDIC_KNEEL', -- OPTIONAL https://pastebin.com/6mrYTdQv 29 | } 30 | 31 | local locations = { 32 | lafuenta = { 33 | Guards = { 34 | { model = 'g_m_y_mexgang_01', weapon = 'weapon_pistol' }, 35 | { model = 'g_m_y_mexgang_01', weapon = 'weapon_pistol' }, 36 | }, 37 | GuardPositions = { 38 | vector4(1381.07, 1149.81, 114.33, 87.54), 39 | vector4(1386.84, 1126.88, 114.33, 89.23), 40 | vector4(1414.17, 1138.47, 114.33, 278.73) 41 | }, 42 | Civilians = { 43 | { model = 's_m_m_marine_02', animation = 'WORLD_HUMAN_BINOCULARS' } 44 | }, 45 | CivilianPositions = { 46 | vector4(1415.4, 1161.45, 114.67, 3.26) 47 | }, 48 | GuardCars = { 49 | { model = 'baller4', coords = vector4(1335.64, 1137.98, 110.81, 99.93) }, 50 | { model = 'baller4', coords = vector4(1337.75, 1149.41, 112.36, 167.32) } 51 | }, 52 | VehiclePosition = vector4(1410.11, 1117.26, 114.48, 91.92) 53 | }, 54 | lakevinewood = { 55 | Guards = { 56 | { model = 'g_m_y_armgoon_02', weapon = 'weapon_pistol' }, 57 | { model = 'g_m_y_armgoon_02', weapon = 'weapon_pistol' }, 58 | { model = 'g_m_y_armgoon_02', weapon = 'weapon_machinepistol', accuracy = 5 }, 59 | }, 60 | GuardPositions = { 61 | vector4(-113.27, 983.92, 235.76, 108.41), 62 | vector4(-105.51, 974.53, 235.76, 200.63), 63 | vector4(-102.46, 975.78, 235.76, 199.94), 64 | vector4(-91.7, 944.77, 233.03, 338.29), 65 | vector4(-83.68, 944.54, 233.03, 40.37), 66 | vector4(-103.18, 1011.38, 235.76, 103.97), 67 | vector4(-97.14, 1017.25, 235.82, 289.04) 68 | }, 69 | Civilians = { 70 | { model = 'a_m_o_genstreet_01', animation = 'WORLD_HUMAN_PARTYING' } 71 | }, 72 | CivilianPositions = { 73 | vector4(-122.49, 1008.29, 235.73, 114.33) 74 | }, 75 | GuardCars = { 76 | { model = 'landstalker2', coords = vector4(-136.02, 977.28, 235.27, 219.36) }, 77 | { model = 'landstalker2', coords = vector4(-129.89, 978.94, 235.25, 147.02) }, 78 | { model = 'entityxf', coords = vector4(-123.52, 1007.19, 235.13, 200.9) } 79 | }, 80 | VehiclePosition = vector4(-130.68, 1005.67, 235.13, 197.34) 81 | }, 82 | lakevinewood2 = { 83 | Guards = { 84 | { model = 'mp_m_securoguard_01', weapon = 'weapon_pistol' }, 85 | { model = 'mp_m_securoguard_01', weapon = 'weapon_pistol' }, 86 | }, 87 | GuardPositions = { 88 | vector4(-135.76, 899.35, 235.66, 283.48), 89 | vector4(-139.0, 881.63, 233.48, 133.12), 90 | vector4(-160.7, 925.8, 239.94, 291.47) 91 | }, 92 | Civilians = { 93 | { model = 'a_f_y_beach_01', animation = 'WORLD_HUMAN_DRINKING' } 94 | }, 95 | CivilianPositions = { 96 | vector4(-161.97, 880.79, 237.14, 161.28) 97 | }, 98 | GuardCars = { 99 | { model = 'baller4', coords = vector4(-141.67, 910.2, 235.8, 243.79) }, 100 | { model = 'granger', coords = vector4(-120.49, 910.81, 235.43, 19.1) } 101 | }, 102 | VehiclePosition = vector4(-167.6, 918.7, 234.99, 316.02) 103 | }, 104 | burroHeights = { 105 | Guards = { 106 | { model = 'a_m_m_soucent_01', weapon = 'weapon_pistol' }, 107 | { model = 'g_m_m_armlieut_01', weapon = 'weapon_pistol' }, 108 | { model = 'g_m_importexport_01', weapon = 'weapon_machinepistol', accuracy = 5 }, 109 | }, 110 | GuardPositions = { 111 | vector4(1455.68, -2592.61, 48.63, 308.67), 112 | vector4(1437.89, -2587.03, 48.11, 105.84), 113 | vector4(1425.79, -2581.05, 47.98, 23.34), 114 | vector4(1437.89, -2591.51, 48.13, 67.2), 115 | }, 116 | Civilians = { 117 | { model = 'a_f_y_soucent_02', animation = 'WORLD_HUMAN_AA_COFFEE' }, 118 | { model = 'a_m_m_beach_01', animation = 'WORLD_HUMAN_AA_COFFEE' }, 119 | { model = 'g_m_m_korboss_01', animation = 'WORLD_HUMAN_DRINKING' }, 120 | { model = 'a_f_y_soucent_03', animation = 'WORLD_HUMAN_STAND_MOBILE' }, 121 | { model = 's_m_y_strvend_01', animation = 'WORLD_HUMAN_STAND_MOBILE' }, 122 | { model = 'mp_m_weapexp_01', animation = 'WORLD_HUMAN_AA_SMOKE' }, 123 | { model = 'a_m_y_smartcaspat_01', animation = 'WORLD_HUMAN_LEANING', coords = vector4(1450.54, -2622.54, 48.68, 339.93)}, 124 | }, 125 | CivilianPositions = { 126 | vector4(1450.23, -2615.93, 48.48, 351.78), 127 | vector4(1450.61, -2613.47, 48.47, 169.65), 128 | vector4(1447.17, -2606.22, 48.35, 90.46), 129 | vector4(1445.33, -2606.25, 48.32, 268.93), 130 | vector4(1436.39, -2613.77, 48.21, 184.89), 131 | vector4(1436.69, -2615.56, 48.22, 2.8), 132 | }, 133 | GuardCars = { 134 | { model = 'dominator8', coords = vector4(1440.42, -2610.3, 48.26, 167.29) }, 135 | { model = 'rapidgt3', coords = vector4(1443.48, -2612.07, 48.32, 164.42) }, 136 | { model = 'landstalker2', coords = vector4(1454.43, -2600.34, 48.46, 18.42) }, 137 | { model = 'cavalcade', coords = vector4(1448.66, -2589.8, 48.27, 58.67) }, 138 | { model = 'burrito', coords = vector4(1441.72, -2593.62, 48.0, 86.87) }, 139 | { model = 'sultan', coords = vector4(1434.61, -2605.74, 47.96, 325.5) }, 140 | { model = 'elegy2', coords = vector4(1433.41, -2593.35, 48.09, 137.91) }, 141 | { model = 'jb7002', coords = vector4(1453.71, -2614.1, 48.53, 163.54) } 142 | }, 143 | VehiclePosition = vector4(1446.97, -2612.22, 48.39, 164.47) 144 | }, 145 | sandyDesert = { 146 | Guards = { 147 | { model = 'a_m_m_soucent_01', weapon = 'weapon_pistol', }, 148 | { model = 'g_m_m_armlieut_01', weapon = 'weapon_pistol' }, 149 | { model = 'g_m_importexport_01', weapon = 'weapon_machinepistol', accuracy = 5 }, 150 | }, 151 | GuardPositions = { 152 | vector4(2470.31, 3451.51, 49.83, 30.78), 153 | vector4(2486.22, 3444.64, 51.07, 238.82), 154 | vector4(2485.66, 3447.15, 51.07, 10.14), 155 | vector4(2482.66, 3447.78, 51.07, 108.97), 156 | vector4(2483.65, 3446.7, 51.07, 223.21), 157 | vector4(2486.95, 3446.1, 51.07, 271.15), 158 | vector4(2485.78, 3447.61, 51.07, 330.24), 159 | vector4(2483.16, 3449.77, 51.07, 43.09), 160 | vector4(2483.91, 3448.53, 51.07, 217.75) 161 | }, 162 | GuardCars = { 163 | { model = 'ratloader', coords = vector4(2464.06, 3447.82, 49.77, 27.66) }, 164 | { model = 'dune', coords = vector4(2459.66, 3449.5, 49.02, 229.02) } 165 | }, 166 | VehiclePosition = vector4(2481.28, 3437.69, 49.32 , 225.1) 167 | }, 168 | } 169 | -- ElegyRetro job 170 | 171 | local ElegyRetroJob = { 172 | Model = 'elegy', 173 | token = 'boostelegyr', 174 | RunCost = 1000, 175 | Timer = 30000, 176 | MissionDescription = "Elegy Retro", 177 | Messages = { 178 | First = { 179 | Sender = 'Hector', 180 | Subject = 'Stuff', 181 | Message = "I marked the car n shit " 182 | }, 183 | Second = { 184 | Sender = 'Hector', 185 | Subject = 'Stuff', 186 | Message = "You got the Elegy? Nice.. I'll send you the gps coordinates for the delivery spot once it's safe. If you bring cops you're done." 187 | }, 188 | Third = { 189 | Sender = 'Hector', 190 | Subject = 'Stuff', 191 | Message = "Tight. Enjoy the papers." 192 | } 193 | }, 194 | MinimumPolice = 0, 195 | Locations = { 196 | locations.lafuenta, 197 | locations.lakevinewood 198 | } 199 | } 200 | 201 | local SultanRSJob = { 202 | Model = 'sultanrs', 203 | token = 'boostsultanrs', 204 | RunCost = 1000, 205 | Timer = 20000, 206 | MissionDescription = "Sultan RS", 207 | Messages = { 208 | First = { 209 | Sender = 'Hector', 210 | Subject = 'Stuff', 211 | Message = "I marked the car n shit " 212 | }, 213 | Second = { 214 | Sender = 'Hector', 215 | Subject = 'Stuff', 216 | Message = "You got the car? Wicked.. I'll send you the gps coordinates for the delivery spot once it's safe. If you bring cops you're done." 217 | }, 218 | Third = { 219 | Sender = 'Hector', 220 | Subject = 'Stuff', 221 | Message = "Tight. Enjoy the papers." 222 | } 223 | }, 224 | MinimumPolice = 0, 225 | Locations = { 226 | --locations.lafuenta, 227 | locations.lakevinewood, 228 | locations.burroHeights 229 | } 230 | } 231 | 232 | local BansheeJob = { 233 | Model = 'banshee2', 234 | token = 'boostbanshee', 235 | RunCost = 1000, 236 | Timer = 20000, 237 | MissionDescription = "Banshee 900R", 238 | Messages = { 239 | First = { 240 | Sender = 'Hector', 241 | Subject = 'Stuff', 242 | Message = "I marked the car n shit " 243 | }, 244 | Second = { 245 | Sender = 'Hector', 246 | Subject = 'Stuff', 247 | Message = "You got the Banshee? When it's safe I'll drop you the location of where to leave it. If you bring cops you're done." 248 | }, 249 | Third = { 250 | Sender = 'Hector', 251 | Subject = 'Stuff', 252 | Message = "Tight. Enjoy the papers." 253 | } 254 | }, 255 | MinimumPolice = 0, 256 | Locations = { 257 | locations.lafuenta, 258 | locations.lakevinewood, 259 | locations.lakevinewood2 260 | } 261 | } 262 | 263 | local VoodooJob = { 264 | Model = 'voodoo', 265 | token = 'boostvoodoo', 266 | RunCost = 1000, 267 | Timer = 20000, 268 | MissionDescription = "Voodoo Custom", 269 | Messages = { 270 | First = { 271 | Sender = 'Hector', 272 | Subject = 'Stuff', 273 | Message = "I marked the car n shit " 274 | }, 275 | Second = { 276 | Sender = 'Hector', 277 | Subject = 'Stuff', 278 | Message = "You got the Voodoo?? When it's safe I'll drop you the location of where to leave it. If you bring cops you're done." 279 | }, 280 | Third = { 281 | Sender = 'Hector', 282 | Subject = 'Stuff', 283 | Message = "Tight. Enjoy the papers." 284 | } 285 | }, 286 | MinimumPolice = 0, 287 | Locations = { 288 | locations.sandyDesert 289 | } 290 | } 291 | 292 | Config.Jobs = { 293 | ['ElegyRetroJob'] = ElegyRetroJob, 294 | ['SultanRSJob'] = SultanRSJob, 295 | ['BansheeJob'] = BansheeJob, 296 | ['VoodooJob'] = VoodooJob 297 | } -------------------------------------------------------------------------------- /client/client.lua: -------------------------------------------------------------------------------- 1 | local QBCore = exports['qb-core']:GetCoreObject() 2 | 3 | local isLoggedIn = LocalPlayer.state['isLoggedIn'] 4 | local VehicleCoords = nil 5 | local MissionVehicle = nil 6 | local CurrentCops = 0 7 | local currentJobId = nil 8 | local CurrentJob = nil 9 | local CurrentJobLocation = nil 10 | local DropoffLocation = nil 11 | local onRun = false 12 | local case = nil 13 | local DropoffSpot = nil 14 | local DropoffSpotData = nil 15 | local Entities = {} 16 | local vehicleBlip = nil 17 | local policeBlip = nil 18 | local deliveryBlip = nil 19 | local npcs = { 20 | ['npcguards'] = {}, 21 | ['npccivilians'] = {} 22 | } 23 | 24 | local npcVehicles = {} 25 | 26 | local function cancelEmote() 27 | TriggerEvent('animations:client:EmoteCommandStart', {Config.ChopEmote}) 28 | end 29 | 30 | function dump(o) 31 | if type(o) == 'table' then 32 | local s = '{ ' 33 | for k,v in pairs(o) do 34 | if type(k) ~= 'number' then k = '"'..k..'"' end 35 | s = s .. '['..k..'] = ' .. dump(v) .. ',' 36 | end 37 | return s .. '} ' 38 | else 39 | return tostring(o) 40 | end 41 | end 42 | 43 | local function shallowCopy(original) 44 | local copy = {} 45 | for key, value in pairs(original) do 46 | copy[key] = value 47 | end 48 | return copy 49 | end 50 | 51 | RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() 52 | QBCore.Functions.GetPlayerData(function(PlayerData) 53 | PlayerJob = PlayerData.job 54 | end) 55 | end) 56 | 57 | RegisterNetEvent('QBCore:Client:OnJobUpdate', function(JobInfo) 58 | PlayerJob = JobInfo 59 | end) 60 | 61 | RegisterNetEvent('police:SetCopCount', function(amount) 62 | CurrentCops = amount 63 | end) 64 | 65 | local function canInteract(value) 66 | if onRun then return false end 67 | local itemInPockets = QBCore.Functions.HasItem('swap_token') 68 | if itemInPockets then return true else return false end 69 | end 70 | 71 | --- Create bosses 72 | CreateThread(function() 73 | local boss = Config.Boss 74 | local animation 75 | if boss.animation then 76 | animation = boss.animation 77 | else 78 | animation = "WORLD_HUMAN_STAND_IMPATIENT" 79 | end 80 | 81 | RequestModel(boss.model) 82 | while not HasModelLoaded(boss.model) do 83 | Wait(1) 84 | end 85 | 86 | local options = {} 87 | for i,v in pairs(Config.Jobs) do 88 | local option = { 89 | type = "client", 90 | event = "cw-boostjob:client:start", 91 | jobId = i, 92 | icon = "fas fa-circle", 93 | label = v.MissionDescription, 94 | canInteract = function() 95 | if Config.UseTokens then 96 | local tokens = nil 97 | local res = exports['cw-tokens']:hasToken(v.token) 98 | return res 99 | else 100 | local res= canInteract(v.token) 101 | return res 102 | end 103 | end 104 | } 105 | table.insert(options, option) 106 | end 107 | 108 | exports['qb-target']:SpawnPed({ 109 | model = boss.model, 110 | coords = boss.coords, 111 | minusOne = true, 112 | freeze = true, 113 | invincible = true, 114 | blockevents = true, 115 | scenario = animation, 116 | target = { 117 | options = options, 118 | distance = 3.0 119 | }, 120 | spawnNow = true, 121 | }) 122 | 123 | --TODO add interaction with key box 124 | 125 | end) 126 | 127 | local function CleanUp() 128 | for i,npcType in pairs(npcs) do 129 | for j,v in pairs(npcType) do 130 | DeletePed(v) 131 | end 132 | end 133 | for i,vehicle in pairs(npcVehicles) do 134 | DeleteEntity(vehicle) 135 | end 136 | npcs = { 137 | ['npcguards'] = {}, 138 | ['npccivilians'] = {} 139 | } 140 | 141 | npcVehicles = {} 142 | end 143 | 144 | RegisterCommand("cleanup", function(source) 145 | CleanUp() 146 | end) 147 | 148 | ---Phone msgs 149 | local function RunStart() 150 | Citizen.Wait(2000) 151 | 152 | local sender = Lang:t('mailstart.sender') 153 | local subject = Lang:t('mailstart.subject') 154 | local message = Lang:t('mailstart.message') 155 | 156 | if Config.Jobs[currentJobId].Messages then 157 | if Config.Jobs[currentJobId].Messages.First.Sender then 158 | sender = Config.Jobs[currentJobId].Messages.First.Sender 159 | end 160 | if Config.Jobs[currentJobId].Messages.First.Subject then 161 | subject = Config.Jobs[currentJobId].Messages.First.Subject 162 | end 163 | if Config.Jobs[currentJobId].Messages.First.Message then 164 | message = Config.Jobs[currentJobId].Messages.First.Message 165 | end 166 | end 167 | 168 | TriggerServerEvent('qb-phone:server:sendNewMail', { 169 | sender = sender, 170 | subject = subject, 171 | message = message, 172 | }) 173 | Citizen.Wait(3000) 174 | end 175 | 176 | 177 | local function CarTurnedInMessage() 178 | Citizen.Wait(2000) 179 | local sender = Lang:t('mailEnd.sender') 180 | local subject = Lang:t('mailEnd.subject') 181 | local message = Lang:t('mailEnd.message') 182 | 183 | if Config.Jobs[currentJobId].Messages then 184 | if Config.Jobs[currentJobId].Messages.Third then 185 | if Config.Jobs[currentJobId].Messages.Third.Sender then 186 | sender = Config.Jobs[currentJobId].Messages.Third.Sender 187 | end 188 | if Config.Jobs[currentJobId].Messages.Third.Subject then 189 | subject = Config.Jobs[currentJobId].Messages.Third.Subject 190 | end 191 | if Config.Jobs[currentJobId].Messages.Third.Message then 192 | message = Config.Jobs[currentJobId].Messages.Third.Message 193 | end 194 | end 195 | end 196 | 197 | 198 | TriggerServerEvent('qb-phone:server:sendNewMail', { 199 | sender = sender, 200 | subject = subject, 201 | message = message, 202 | }) 203 | 204 | QBCore.Functions.Notify(Lang:t("info.paperslip"), 'success') 205 | TriggerServerEvent('cw-boostjob:server:giveSlip', CurrentJob.Model) 206 | currentJobId = nil 207 | CurrentJobLocation = nil 208 | CurrentJob = nil 209 | DropoffSpot = nil 210 | DropoffSpotData = nil 211 | end 212 | 213 | 214 | local function carGps() 215 | -- TODO Fix police gps 216 | TriggerEvent('cw-boostjob:client:carTheftCall') 217 | if QBCore.Functions.GetPlayerData().job.name == 'police' then 218 | local vehicleCoords = GetEntityCoords(MissionVehicle) 219 | policeBlip = AddBlipForEntity(MissionVehicle) 220 | SetBlipSprite(policeBlip, 161) 221 | SetBlipScale(policeBlip, 1.4) 222 | PulseBlip(policeBlip) 223 | SetBlipColour(policeBlip, 1) 224 | SetBlipAsShortRange(policeBlip, true) 225 | end 226 | end 227 | 228 | local function TurnInCar(vehicle) 229 | exports['qb-core']:HideText() 230 | QBCore.Functions.DeleteVehicle(vehicle) 231 | RemoveBlip(deliveryBlip) 232 | CleanUp() 233 | CarTurnedInMessage() 234 | onRun = false 235 | end 236 | 237 | local function CheckForKeypress() 238 | if next(DropoffSpotData) then 239 | CreateThread(function() 240 | while next(DropoffSpotData) do 241 | if IsControlJustReleased(0, 38) then 242 | local Player = PlayerPedId() 243 | local vehicle = GetVehiclePedIsUsing(Player) 244 | TaskLeaveVehicle(Player, vehicle, 0) 245 | TaskTurnPedToFaceEntity(Player, vehicle) 246 | Citizen.SetTimeout(4000, function() 247 | TriggerEvent('animations:client:EmoteCommandStart', {Config.ChopEmote}) 248 | QBCore.Functions.Progressbar("boostChop", "Removing parts", Config.Choptimer, false, true, { 249 | disableMovement = true, 250 | disableCarMovement = true, 251 | disableMouse = false, 252 | disableCombat = true, 253 | }, {}, {}, {}, function() 254 | cancelEmote() 255 | TurnInCar(vehicle) 256 | end, function() -- Cancel 257 | QBCore.Functions.Notify("Canceled", "error") 258 | cancelEmote() 259 | end) 260 | end) 261 | return end 262 | Wait(0) 263 | end 264 | end) 265 | end 266 | end 267 | 268 | 269 | local function SetupInteraction() 270 | local ped = PlayerPedId() 271 | if GetVehiclePedIsIn(ped, false) == MissionVehicle then 272 | local text = Lang:t('info.dropoff') 273 | text = '[E] '..text 274 | CheckForKeypress() 275 | exports['qb-core']:DrawText(text, 'left') 276 | end 277 | end 278 | 279 | local function getDropOffLocation() 280 | QBCore.Functions.Notify(Lang:t("success.car_beep_stop"), 'success') 281 | local rand = math.random(1,#Config.DropoffLocations) 282 | DropoffLocation = Config.DropoffLocations[rand] 283 | SetNewWaypoint(DropoffLocation.x, DropoffLocation.y) 284 | deliveryBlip = AddBlipForCoord(DropoffLocation) 285 | SetBlipSprite(deliveryBlip, 357) 286 | 287 | -- Create Dropoff 288 | -- PolyZone + Drawtext + Locations Management 289 | local _name = "dropoff-spot" 290 | DropoffSpot = BoxZone:Create(DropoffLocation, 10, 10, { 291 | name = _name, 292 | -- debugPoly = true, 293 | heading = DropoffLocation.w, 294 | minZ = DropoffLocation.z - 3.0, 295 | maxZ = DropoffLocation.z + 3.0, 296 | }) 297 | DropoffSpot:onPlayerInOut(function(isPointInside, _) 298 | if isPointInside then 299 | -- print('is inside') 300 | DropoffSpotData = { 301 | ['spot'] = _name, 302 | ['coords'] = vector3(DropoffLocation.x, DropoffLocation.y, DropoffLocation.z), 303 | ['drawtextui'] = "Enter Dropoff Spot", 304 | } 305 | SetupInteraction() 306 | else 307 | DropoffSpotData = {} 308 | exports['qb-core']:HideText() 309 | end 310 | end) 311 | end 312 | 313 | local function CarAquiredMessage() 314 | Citizen.Wait(5000) 315 | local sender = Lang:t('mailSecond.sender') 316 | local subject = Lang:t('mailSecond.subject') 317 | local message = Lang:t('mailSecond.message') 318 | 319 | if Config.Jobs[currentJobId].Messages.Second then 320 | if Config.Jobs[currentJobId].Messages.Second.Sender then 321 | sender = Config.Jobs[currentJobId].Messages.Second.Sender 322 | end 323 | if Config.Jobs[currentJobId].Messages.Second.Subject then 324 | subject = Config.Jobs[currentJobId].Messages.Second.Subject 325 | end 326 | if Config.Jobs[currentJobId].Messages.Second.Message then 327 | message = Config.Jobs[currentJobId].Messages.Second.Message 328 | end 329 | end 330 | 331 | TriggerServerEvent('qb-phone:server:sendNewMail', { 332 | sender = sender, 333 | subject = subject, 334 | message = message, 335 | }) 336 | 337 | carGps() 338 | QBCore.Functions.Notify(Lang:t("success.car_beep"), 'success') 339 | Citizen.Wait(CurrentJob.Timer) 340 | RemoveBlip(policeBlip) 341 | getDropOffLocation() 342 | end 343 | 344 | --- 345 | local function SpawnVehicles() 346 | -- Mission car 347 | VehicleCoords = CurrentJobLocation.VehiclePosition 348 | RequestModel(CurrentJob.Model) 349 | while not HasModelLoaded(CurrentJob.Model) do 350 | Citizen.Wait(0) 351 | end 352 | 353 | ClearAreaOfVehicles(VehicleCoords.x, VehicleCoords.y, VehicleCoords.z, 1.0, false, false, false, false, false) 354 | MissionVehicle = CreateVehicle(CurrentJob.Model, VehicleCoords.x, VehicleCoords.y, VehicleCoords.z, VehicleCoords.w, true, true) 355 | SetNewWaypoint(VehicleCoords.x, VehicleCoords.y) 356 | vehicleBlip = AddBlipForEntity(MissionVehicle) 357 | SetBlipSprite(vehicleBlip, 225) 358 | 359 | -- Bad Guys cars 360 | local vehicles = CurrentJobLocation.GuardCars 361 | if vehicles then 362 | for i,v in pairs(vehicles) do 363 | local GuardVehicleCoords = v.coords 364 | RequestModel(v.model) 365 | while not HasModelLoaded(v.model) do 366 | Citizen.Wait(0) 367 | end 368 | 369 | ClearAreaOfVehicles(GuardVehicleCoords.x, GuardVehicleCoords.y, GuardVehicleCoords.z, 1.0, false, false, false, false, false) 370 | local transport = CreateVehicle(v.model, GuardVehicleCoords.x, GuardVehicleCoords.y, GuardVehicleCoords.z, GuardVehicleCoords.w, true, true) 371 | table.insert(npcVehicles,transport) 372 | end 373 | end 374 | end 375 | 376 | -- local function SpawnCase() 377 | -- local caseLocation = Config.Jobs[currentJobId].Items.FetchItemLocation 378 | -- case = CreateObject(Config.Jobs[currentJobId].Items.FetchItemProp, caseLocation.x, caseLocation.y, caseLocation.z, true, true, true) 379 | -- SetNewWaypoint(caseLocation.x, caseLocation.y) 380 | -- SetEntityHeading(case, caseLocation.w) 381 | -- CreateObject(case) 382 | -- FreezeEntityPosition(case, true) 383 | -- SetEntityAsMissionEntity(case) 384 | -- case = AddBlipForEntity(case) 385 | -- SetBlipSprite(case, 457) 386 | -- SetBlipColour(case, 2) 387 | -- SetBlipFlashes(case, false) 388 | -- BeginTextCommandSetBlipName("STRING") 389 | -- AddTextComponentString('Case') 390 | -- EndTextCommandSetBlipName(case) 391 | -- end 392 | 393 | local function loadModel(model) 394 | if type(model) ~= 'number' then 395 | model = GetHashKey(model) 396 | end 397 | 398 | while not HasModelLoaded(model) do 399 | RequestModel(model) 400 | Citizen.Wait(0) 401 | end 402 | end 403 | 404 | local function SpawnGuards() 405 | local ped = PlayerPedId() 406 | SetPedRelationshipGroupHash(ped, 'PLAYER') 407 | AddRelationshipGroup('npcguards') 408 | 409 | local listOfGuardPositions = nil 410 | if CurrentJobLocation.GuardPositions ~= nil then 411 | listOfGuardPositions = shallowCopy(CurrentJobLocation.GuardPositions) -- these are used if random positions 412 | end 413 | 414 | for k, v in pairs(CurrentJobLocation.Guards) do 415 | local guardPosition = v.coords 416 | local animation = nil 417 | if guardPosition == nil then 418 | if listOfGuardPositions == nil then 419 | print('Someone made an oopsie when making guard positions!') 420 | else 421 | local random = math.random(1,#listOfGuardPositions) 422 | guardPosition = listOfGuardPositions[random] 423 | table.remove(listOfGuardPositions,random) 424 | end 425 | end 426 | local accuracy = Config.DefaultValues.accuracy 427 | if v.accuracy then 428 | accuracy = v.accuracy 429 | end 430 | local armor = Config.DefaultValues.armor 431 | if v.armor then 432 | armor = v.armor 433 | end 434 | -- print('Guard location: ', guardPosition) 435 | loadModel(v.model) 436 | npcs['npcguards'][k] = CreatePed(26, GetHashKey(v.model), guardPosition, true, true) 437 | NetworkRegisterEntityAsNetworked(npcs['npcguards'][k]) 438 | local networkID = NetworkGetNetworkIdFromEntity(npcs['npcguards'][k]) 439 | SetNetworkIdCanMigrate(networkID, true) 440 | SetNetworkIdExistsOnAllMachines(networkID, true) 441 | SetPedRandomComponentVariation(npcs['npcguards'][k], 0) 442 | SetPedRandomProps(npcs['npcguards'][k]) 443 | SetEntityAsMissionEntity(npcs['npcguards'][k]) 444 | SetEntityVisible(npcs['npcguards'][k], true) 445 | SetPedRelationshipGroupHash(npcs['npcguards'][k], 'npcguards') 446 | SetPedAccuracy(npcs['npcguards'][k], accuracy) 447 | SetPedArmour(npcs['npcguards'][k], armor) 448 | SetPedCanSwitchWeapon(npcs['npcguards'][k], true) 449 | SetPedDropsWeaponsWhenDead(npcs['npcguards'][k], false) 450 | SetPedFleeAttributes(npcs['npcguards'][k], 0, false) 451 | SetPedCombatAttributes(npcs['npcguards'][k], 46, true) 452 | local weapon = 'WEAPON_PISTOL' 453 | if v.weapon then 454 | weapon = v.weapon 455 | end 456 | GiveWeaponToPed(npcs['npcguards'][k], v.weapon, 255, false, false) 457 | local random = math.random(1, 2) 458 | if random == 2 then 459 | TaskGuardCurrentPosition(npcs['npcguards'][k], 10.0, 10.0, 1) 460 | end 461 | Wait(1000) 462 | end 463 | 464 | SetRelationshipBetweenGroups(0, 'npcguards', 'npcguards') 465 | SetRelationshipBetweenGroups(5, 'npcguards', 'PLAYER') 466 | SetRelationshipBetweenGroups(5, 'PLAYER', 'npcguards') 467 | end 468 | 469 | local function SpawnCivilians() 470 | local ped = PlayerPedId() 471 | SetPedRelationshipGroupHash(ped, 'PLAYER') 472 | AddRelationshipGroup('npccivilians') 473 | 474 | if CurrentJobLocation.Civilians then 475 | 476 | local listOfCivilianPositions = nil 477 | if CurrentJobLocation.CivilianPositions ~= nil then 478 | listOfCivilianPositions = shallowCopy(CurrentJobLocation.CivilianPositions) -- these are used if random positions 479 | end 480 | 481 | for k, v in pairs(CurrentJobLocation.Civilians) do 482 | local civPosition = v.coords 483 | if civPosition == nil then 484 | if listOfCivilianPositions == nil then 485 | print('Someone made an oopsie when making civilian positions!') 486 | else 487 | local random = math.random(1,#listOfCivilianPositions) 488 | civPosition = listOfCivilianPositions[random] 489 | table.remove(listOfCivilianPositions,random) 490 | end 491 | end 492 | -- print('Civ location: ', civPosition) 493 | loadModel(v.model) 494 | npcs['npccivilians'][k] = CreatePed(26, GetHashKey(v.model), civPosition, true, true) 495 | NetworkRegisterEntityAsNetworked(npcs['npccivilians'][k]) 496 | local networkID = NetworkGetNetworkIdFromEntity(npcs['npccivilians'][k]) 497 | SetNetworkIdCanMigrate(networkID, true) 498 | SetNetworkIdExistsOnAllMachines(networkID, true) 499 | SetPedRandomComponentVariation(npcs['npccivilians'][k], 0) 500 | SetPedRandomProps(npcs['npccivilians'][k]) 501 | SetEntityAsMissionEntity(npcs['npccivilians'][k]) 502 | SetEntityVisible(npcs['npccivilians'][k], true) 503 | SetPedRelationshipGroupHash(npcs['npccivilians'][k], 'npccivilians') 504 | SetPedArmour(npcs['npccivilians'][k], 10) 505 | SetPedFleeAttributes(npcs['npccivilians'][k], 0, true) 506 | 507 | local animation = "CODE_HUMAN_COWER" 508 | if v.animation then 509 | animation = v.animation 510 | end 511 | TaskStartScenarioInPlace(npcs['npccivilians'][k], animation, 0, true) 512 | Wait(1000) 513 | end 514 | 515 | SetRelationshipBetweenGroups(3, 'npccivilians', 'npccivilians') 516 | SetRelationshipBetweenGroups(3, 'npccivilians', 'PLAYER') 517 | SetRelationshipBetweenGroups(3, 'PLAYER', 'npccivilians') 518 | end 519 | end 520 | 521 | local function CheckForCar() 522 | local ped = PlayerPedId() 523 | CreateThread(function() 524 | local isInVehicle = false 525 | while not isInVehicle do 526 | Wait(2000) 527 | -- print(GetVehiclePedIsIn(ped, false) == MissionVehicle) 528 | if ped then 529 | if GetVehiclePedIsIn(ped, false) == MissionVehicle then 530 | RemoveBlip(vehicleBlip) 531 | CarAquiredMessage() 532 | isInVehicle = true 533 | end 534 | 535 | end 536 | end 537 | end) 538 | end 539 | 540 | RegisterNetEvent('cw-boostjob:client:runactivate', function() 541 | onRun = true 542 | RunStart() 543 | Citizen.Wait(4) 544 | SpawnGuards() 545 | SpawnCivilians() 546 | -- TODO ADD KEY CASE 547 | -- SpawnCase() 548 | SpawnVehicles() 549 | CheckForCar() 550 | end) 551 | 552 | RegisterNetEvent('cw-boostjob:client:start', function (data) 553 | if CurrentCops >= Config.Jobs[data.jobId].MinimumPolice then 554 | currentJobId = data.jobId 555 | 556 | CurrentJob = Config.Jobs[currentJobId] 557 | local rand = math.random(1, #CurrentJob.Locations) 558 | CurrentJobLocation = CurrentJob.Locations[rand] 559 | 560 | QBCore.Functions.TriggerCallback("cw-boostjob:server:coolc",function(isCooldown) 561 | if not isCooldown then 562 | TriggerEvent('animations:client:EmoteCommandStart', {"idle11"}) 563 | QBCore.Functions.Progressbar("start_job", Lang:t('info.talking_to_boss'), 10000, false, true, { 564 | disableMovement = true, 565 | disableCarMovement = true, 566 | disableMouse = false, 567 | disableCombat = true, 568 | }, { 569 | }, {}, {}, function() -- Done 570 | TriggerEvent('animations:client:EmoteCommandStart', {"c"}) 571 | TriggerServerEvent('cw-boostjob:server:startr', currentJobId) 572 | end, function() -- Cancel 573 | TriggerEvent('animations:client:EmoteCommandStart', {"c"}) 574 | QBCore.Functions.Notify(Lang:t("error.canceled"), 'error') 575 | end) 576 | else 577 | QBCore.Functions.Notify(Lang:t("error.someone_recently_did_this"), 'error') 578 | end 579 | end) 580 | else 581 | QBCore.Functions.Notify(Lang:t("error.cannot_do_this_right_now"), 'error') 582 | end 583 | end) 584 | 585 | local function MinigameSuccess() 586 | TriggerEvent('animations:client:EmoteCommandStart', {"type3"}) 587 | QBCore.Functions.Progressbar("grab_case", "Unlocking case", 10000, false, true, { 588 | disableMovement = true, 589 | disableCarMovement = true, 590 | disableMouse = false, 591 | disableCombat = true, 592 | }, { 593 | }, {}, {}, function() -- Done 594 | TriggerEvent('animations:client:EmoteCommandStart', {"c"}) 595 | RemoveBlip(case) 596 | TriggerServerEvent('cw-boostjob:server:unlock') 597 | 598 | local playerPedPos = GetEntityCoords(PlayerPedId(), true) 599 | local case = GetClosestObjectOfType(playerPedPos, 10.0, Config.Jobs[currentJobId].Items.FetchItemProp, false, false, false) 600 | if (IsPedActiveInScenario(PlayerPedId()) == false) then 601 | SetEntityAsMissionEntity(case, 1, 1) 602 | DeleteEntity(case) 603 | QBCore.Functions.Notify(Lang:t("success.you_removed_first_security_case"), 'success') 604 | Itemtimemsg() 605 | case = nil 606 | end 607 | end, function() 608 | TriggerEvent('animations:client:EmoteCommandStart', {"c"}) 609 | QBCore.Functions.Notify(Lang:t("error.canceled"), 'error') 610 | end) 611 | end 612 | 613 | local function MinigameFailiure() 614 | QBCore.Functions.Notify(Lang:t("error.you_failed"), 'error') 615 | end 616 | 617 | local function StartMinigame() 618 | if Config.Jobs[currentJobId].Items.FetchItemMinigame then 619 | local type = Config.Jobs[currentJobId].Items.FetchItemMinigame.Type 620 | local variables = Config.Jobs[currentJobId].Items.FetchItemMinigame.Variables 621 | if type == "Circle" then 622 | exports['ps-ui']:Circle(function(success) 623 | if success then 624 | MinigameSuccess() 625 | else 626 | MinigameFailiure() 627 | end 628 | end, variables[1], variables[2]) -- NumberOfCircles, MS 629 | elseif type == "Maze" then 630 | exports['ps-ui']:Maze(function(success) 631 | if success then 632 | MinigameSuccess() 633 | else 634 | MinigameFailiure() 635 | end 636 | end, variables[1]) -- Hack Time Limit 637 | elseif type == "VarHack" then 638 | exports['ps-ui']:VarHack(function(success) 639 | if success then 640 | MinigameSuccess() 641 | else 642 | MinigameFailiure() 643 | end 644 | end, variables[1], variables[2]) -- Number of Blocks, Time (seconds) 645 | elseif type == "Thermite" then 646 | exports["ps-ui"]:Thermite(function(success) 647 | if success then 648 | MinigameSuccess() 649 | else 650 | MinigameFailiure() 651 | end 652 | end, variables[1], variables[2], variables[3]) -- Time, Gridsize (5, 6, 7, 8, 9, 10), IncorrectBlocks 653 | elseif type == "Scrambler" then 654 | exports['ps-ui']:Scrambler(function(success) 655 | if success then 656 | MinigameSuccess() 657 | else 658 | MinigameFailiure() 659 | end 660 | end, variables[1], variables[2], variables[3]) -- Type (alphabet, numeric, alphanumeric, greek, braille, runes), Time (Seconds), Mirrored (0: Normal, 1: Normal + Mirrored 2: Mirrored only ) 661 | end 662 | else 663 | exports["ps-ui"]:Thermite(function(success) 664 | if success then 665 | MinigameSuccess() 666 | else 667 | MinigameFailiure() 668 | end 669 | end, 8, 5, 3) -- Success 670 | end 671 | end 672 | 673 | RegisterNetEvent('cw-boostjob:client:carTheftCall', function() 674 | if not isLoggedIn then return end 675 | local PlayerJob = QBCore.Functions.GetPlayerData().job 676 | if PlayerJob.name == "police" and PlayerJob.onduty then 677 | local bank 678 | bank = "Fleeca" 679 | PlaySound(-1, "Lose_1st", "GTAO_FM_Events_Soundset", 0, 0, 1) 680 | local vehicleCoords = GetEntityCoords(MissionVehicle) 681 | local s1, s2 = GetStreetNameAtCoord(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z) 682 | local street1 = GetStreetNameFromHashKey(s1) 683 | local street2 = GetStreetNameFromHashKey(s2) 684 | local streetLabel = street1 685 | if street2 then streetLabel = streetLabel .. " " .. street2 end 686 | local plate = GetVehicleNumberPlateText(MissionVehicle) 687 | TriggerServerEvent('police:server:policeAlert', Lang:t("police.alert")..plate) 688 | end 689 | end) 690 | 691 | 692 | RegisterCommand('swap', function (input) 693 | TriggerEvent('cw-boostjob:client:start', input) 694 | end) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc.