├── 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 |

Documentation

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) --------------------------------------------------------------------------------