├── assets
├── carbomb.png
└── bombmirror.png
├── shared
└── config.lua
├── fxmanifest.lua
├── locales
└── en.json
├── server
└── main.lua
├── README.md
└── client
└── main.lua
/assets/carbomb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Viper-Scripts/viper_carbomb/HEAD/assets/carbomb.png
--------------------------------------------------------------------------------
/assets/bombmirror.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Viper-Scripts/viper_carbomb/HEAD/assets/bombmirror.png
--------------------------------------------------------------------------------
/shared/config.lua:
--------------------------------------------------------------------------------
1 | return {
2 | Notify = function(message, type, duration)
3 | lib.notify({
4 | description = message,
5 | type = type,
6 | duration = duration,
7 | })
8 | end,
9 |
10 | detonateType = 2,
11 | timeTakenToArm = 4,
12 | timeUntilDetonation = 10,
13 | triggerKey = 47,
14 | maxSpeed = 50,
15 | speedType = 'mph',
16 |
17 | useCompatInventory = true
18 | }
--------------------------------------------------------------------------------
/fxmanifest.lua:
--------------------------------------------------------------------------------
1 | fx_version 'cerulean'
2 | game 'gta5'
3 |
4 | description 'Car Bomb Script for QBCore and QBox'
5 | author 'xViperAG'
6 | version '1.1.0'
7 |
8 | ox_lib 'locale'
9 |
10 | client_scripts { 'client/cl_*.lua' }
11 | server_scripts { 'server/sv_*.lua' }
12 | shared_scripts { '@ox_lib/init.lua' }
13 |
14 | files { 'shared/*.lua', 'locales/*.json' }
15 |
16 | lua54 'yes'
17 | use_experimental_fxv2_oal 'yes'
18 |
19 | dependencies {
20 | 'ox_inventory',
21 | 'ox_target',
22 | 'ox_lib',
23 | }
24 |
--------------------------------------------------------------------------------
/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "removing_ied": "Removing IED",
3 | "no_bomb_removed": "No bomb was removed",
4 | "bomb_removed": "Bomb removed successfully!",
5 | "canceled": "Cancelled",
6 | "no_vehicle": "No vehicle nearby",
7 | "no_inside_vehicle": "You cannot do this from inside a vehicle!",
8 | "checking_for_ied": "Checking for IED",
9 | "no_bomb_found": "No bomb found on vehicle",
10 | "defuse_bomb": "Defuse Car Bomb",
11 | "bomb_located": "Bomb located under vehicle!",
12 | "arming_ied": "Arming the IED",
13 | "timer_det": "The IED will explode in %s",
14 | "speed_det": "The IED will explode at the speed of %s %s",
15 | "keybind_det": "Make detonate the IED with %s",
16 | "veh_timer_det": "The timer will start as soon as someone gets in the car (%s)",
17 | "veh_enter_det": "The IED will explode as soon as the driver enters the car"
18 | }
--------------------------------------------------------------------------------
/server/main.lua:
--------------------------------------------------------------------------------
1 | local config = require 'shared.config'
2 |
3 | lib.callback.register('mp-carbomb:RemoveBombFromInv', function(source)
4 | local iedCount = exports.ox_inventory:Search(source, 'count', 'car_bomb')
5 | if iedCount > 0 then
6 | exports.ox_inventory:RemoveItem(source, 'car_bomb', 1)
7 | return true
8 | end
9 |
10 | return false
11 | end)
12 |
13 | lib.callback.register('mp-carbomb:GiveDisabledBomb', function(source)
14 | if not exports.ox_inventory:AddItem(source, 'car_bomb_defused', 1) then return false end
15 | end)
16 |
17 | -- Compat Functions
18 |
19 | if config.useCompatInventory then
20 | exports.qbx_core:CreateUseableItem('carbomb', function(source, item),
21 | TriggerClientEvent('mp-carbomb:client:placeBomb', source)
22 | end)
23 |
24 | exports.qbx_core:CreateUseableItem('bombmirror', function(source, item),
25 | TriggerClientEvent('mp-carbomb:client:useBombMirror', source)
26 | end)
27 | end
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # viper_carbomb
2 | Car Bomb Script for QBCore / QBox
3 |
4 |
5 |
6 |
7 | ## Framework
8 |
9 | This script utilizes OverExtended's ox-resources and provides a lot of utilities and functions for the end user.
10 |
11 | The initial use for this script is for any developer/server owner using the QBCore or QBox Framework. However, over time, there may be some added functions to allow for cross platform use.
12 |
13 | Support Provided:
14 |
15 | - QBCore Framework ✅
16 | - QBox Project ✅
17 | - ESX Framework (Legacy or 1.1) ❌ (Will be reimplemented soon)
18 |
19 | ## Preview
20 | - [Planting the Car Bomb](https://medal.tv/games/gta-v/clips/1wxidiQyxTDwVB/d13375k10Dhd?invite=cr-MSxHV04sNDg0MDE5MTIs)
21 | - [Police Action](https://medal.tv/games/gta-v/clips/1wGPcwPTsqEj9t/d1337OebQF4Z?invite=cr-MSxTdkosNDg0MDE5MTIs)
22 |
23 | ## Discord
24 |
25 | Join the Discord here! [Discord](https://discord.gg/3CXrkvQVds)
26 |
27 | # Features
28 | - Fully Configurable
29 | - Checks if vehicle is armed
30 | - Progressbar for implementing car bomb and more
31 |
32 | ## Coming Soon
33 | - Use of Phone for Detonation
34 |
35 | # Dependencies
36 | - [ox_target](https://github.com/overextended/ox_target)
37 | - [ox_inventory](https://github.com/overextended/ox_inventory/releases)
38 | - [ox_lib](https://github.com/overextended/ox_lib/releases)
39 | - [qb-core](https://github.com/qbcore-framework/qb-core) or [qbx_core](https://github.com/QBox-Project/qbx_core)
40 |
41 | # Change Logs
42 | - 1.0 - Inital release
43 |
44 | # Credits
45 | - [Developer-Bear](https://github.com/Developer-Bear/RNG_CarBomb) - Initial Version for ESX
46 |
--------------------------------------------------------------------------------
/client/main.lua:
--------------------------------------------------------------------------------
1 | local config = require 'shared.config'
2 |
3 | local timer = 0
4 |
5 | local function DetonateVehicle(veh)
6 | local vCoords = GetEntityCoords(veh)
7 | if DoesEntityExist(veh) and Entity(veh).state.hasCarBomb then
8 | Entity(veh).state.hasCarBomb = false
9 | AddExplosion(vCoords.x, vCoords.y, vCoords.z, 5, 50.0, true, false, 1)
10 | end
11 | end
12 |
13 | local function RunTimer(veh)
14 | timer = config.timeUntilDetonation
15 |
16 | while timer > 0 do
17 | timer = timer - 1
18 | Wait(1000)
19 | if timer == 0 then
20 | DetonateVehicle(veh)
21 | break
22 | end
23 | end
24 | end
25 |
26 | local function disableCarBomb(entity)
27 | if not Entity(entity).state.hasCarBomb then
28 | return config.Notify(locale('no_bomb_removed'), 'info', 5000)
29 | end
30 |
31 | if lib.progressCircle({
32 | label = locale('removing_ied'),
33 | duration = 10000,
34 | position = 'bottom',
35 | useWhileDead = false,
36 | canCancel = true,
37 | disable = { car = true, combat = true, move = true },
38 | anim = { dict = 'anim@gangops@facility@servers@bodysearch@', clip = 'player_search', flag = 49 }
39 | }) then
40 | ClearPedTasksImmediately(cache.ped)
41 |
42 | Entity(entity).state.hasCarBomb = false
43 | local disableBomb = lib.callback.await('mp-carbomb:GiveDisabledBomb', false)
44 | if not disableBomb then return end
45 |
46 | exports.ox_target:removeGlobalVehicle({ 'yrp_carbomb_removal' })
47 | config.Notify(locale('bomb_removed'), 'success', 5000)
48 | else
49 | ClearPedTasksImmediately(cache.ped)
50 | config.Notify(locale('canceled'), 'error', 5000)
51 | end
52 | end
53 |
54 | ---@param veh number
55 | local function getDetonationType(veh)
56 | if config.detonateType == 0 then
57 | config.Notify(locale('timer_det', config.timeUntilDetonation), 'info', 5000)
58 | RunTimer(veh)
59 | elseif config.detonateType == 1 then
60 | config.Notify(locale('speed_det', config.maxSpeed, config.speedType), 'info', 5000 )
61 | elseif config.detonateType == 2 then
62 | config.Notify(locale("keybind_det", config.triggerKey), 'info', 5000 )
63 | elseif config.detonateType == 3 then
64 | config.Notify(locale('veh_timer_det', config.timeUntilDetonation), 'info', 5000 )
65 | elseif config.detonateType == 4 then
66 | config.Notify(locale('veh_enter_det'), 'info', 5000 )
67 | end
68 | end
69 |
70 | local function detonationLoop(veh)
71 | local hasBomb = Entity(veh).state.hasCarBomb
72 |
73 | while hasBomb do
74 | Wait(0)
75 | if config.detonateType == 1 and hasBomb then
76 | local speed = GetEntitySpeed(veh)
77 | local SpeedKMH = speed * 3.6
78 | local SpeedMPH = speed * 2.236936
79 |
80 | if config.speedType == 'mph' then
81 | if SpeedMPH >= config.maxSpeed then
82 | DetonateVehicle(veh)
83 | end
84 | elseif config.speedType == 'KPH' then
85 | if SpeedKMH >= config.maxSpeed then
86 | DetonateVehicle(veh)
87 | end
88 | end
89 | elseif config.detonateType == 2 and hasBomb then
90 | if IsControlJustReleased(0, config.triggerKey) then
91 | DetonateVehicle(veh)
92 | end
93 | elseif config.detonateType == 3 and hasBomb then
94 | if not IsVehicleSeatFree(veh, -1) then
95 | RunTimer(veh)
96 | elseif not IsVehicleSeatFree(veh, 0) then
97 | RunTimer(veh)
98 | end
99 | elseif config.detonateType == 4 and hasBomb then
100 | if not IsVehicleSeatFree(veh, -1) then
101 | DetonateVehicle(veh)
102 | end
103 | end
104 | end
105 | end
106 |
107 | local function checkItemRequirements()
108 | local veh = lib.getClosestVehicle(GetEntityCoords(cache.ped), 3.0, false)
109 | local animDict = "anim@amb@business@weed@weed_inspecting_lo_med_hi@"
110 | local anim = "weed_spraybottle_crouch_base_inspector"
111 |
112 | if not veh then return config.Notify(locale('no_vehicle'), 'error', 5000) end
113 | if IsPedInAnyVehicle(cache.ped, false) then
114 | return config.Notify(locale('no_inside_vehicle'), 'error', 2500)
115 | end
116 |
117 | lib.requestAnimDict(animDict)
118 | Wait(1000)
119 | TaskPlayAnim(cache.ped, animDict, anim, 3.0, 1.0, -1, 0, 1, false, false, false)
120 |
121 | if lib.progressCircle({
122 | duration = config.timeTakenToArm * 1000,
123 | label = locale('arming_ied'),
124 | position = 'bottom',
125 | useWhileDead = false,
126 | canCancel = true,
127 | disable = { move = true, car = true, combat = true }
128 | }) then
129 | ClearPedTasksImmediately(cache.ped)
130 | local removeBomb = lib.callback.await('mp-carbomb:RemoveBombFromInv', false)
131 | if not removeBomb then return end
132 |
133 | Entity(veh).state.hasCarBomb = true
134 |
135 | getDetonationType(veh)
136 | detonationLoop(veh)
137 | else
138 | ClearPedTasksImmediately(cache.ped)
139 | config.Notify(locale('canceled'), 'error', 5000)
140 | end
141 | end exports('placeBomb', checkItemRequirements)
142 |
143 | RegisterNetEvent('mp-carbomb:client:placeBomb', checkItemRequirements)
144 |
145 | local function createRemovalTarget(entity)
146 | exports.ox_target:addEntity(entity, {
147 | {
148 | name = 'yrp_carbomb_removal',
149 | label = locale('defuse_bomb'),
150 | icon = 'fas fa-cut',
151 | onSelect = function()
152 | disableCarBomb(entity)
153 | end,
154 | canInteract = function(_, distance)
155 | return Entity(entity).state.hasCarBomb and distance <= 2.5
156 | end,
157 | }
158 | })
159 | config.Notify(locale('bomb_located'), 'info', 5000)
160 | end
161 |
162 | local function useBombMirror()
163 | local veh = lib.getClosestVehicle(GetEntityCoords(cache.ped), 3.0, false)
164 |
165 | if not veh then return config.Notify(locale('no_vehicle'), 'error', 5000) end
166 | if IsPedInAnyVehicle(cache.ped, false) then
167 | return config.Notify(locale('no_inside_vehicle'), 'error', 2500)
168 | end
169 |
170 | if lib.progressCircle({
171 | label = locale('checking_for_ied'),
172 | duration = 10000,
173 | position = 'bottom',
174 | useWhileDead = false,
175 | canCancel = true,
176 | disable = { car = true, combat = true, move = true },
177 | anim = { dict = 'mini@golfai', clip = 'wood_idle_a', flag = 49 }
178 | }) then
179 | ClearPedTasksImmediately(cache.ped)
180 | if not Entity(veh).state.hasCarBomb then
181 | config.Notify(locale('no_bomb_found'), 'info', 5000)
182 | end
183 |
184 | createRemovalTarget(veh)
185 | else
186 | ClearPedTasksImmediately(cache.ped)
187 | config.Notify(locale('canceled'), 'error', 5000)
188 | end
189 | end exports('useBombMirror', useBombMirror)
190 |
191 | RegisterNetEvent('mp-carbomb:client:useBombMirror', useBombMirror)
--------------------------------------------------------------------------------