--[[ require ]] local Utils = require 'modules.utils.client' local Target = require 'modules.target.client' --[[ state ]] Explode = {} local plantModel = 'prop_bomb_01' local ownedAtmObjects = {} local ownedCashPiles = {} --[[ functions ]] local function deleteOwnedCashPile(entity) for key, value in pairs(ownedCashPiles) do if value == entity then if DoesEntityExist(value) then SetEntityAsMissionEntity(value, true, true) DeleteEntity(value) end table.remove(ownedCashPiles, key) return end end end local function deleteOwnedAtmObjects() for key, value in pairs(ownedAtmObjects) do if DoesEntityExist(value) then SetEntityAsMissionEntity(value, true, true) DeleteEntity(value) end end for key, value in pairs(ownedCashPiles) do if DoesEntityExist(value) then SetEntityAsMissionEntity(value, true, true) DeleteEntity(value) end local zoneKey = string.format('atmrobbery_explode_pickup_money_%d', key) Target.removeZone(zoneKey) end ownedAtmObjects = {} ownedCashPiles = {} end local function createMoneyObject(entity) local coords = GetOffsetFromEntityInWorldCoords(entity, 0.0, -.5, 1.0) local rotation = GetEntityRotation(entity) local model = 'bkr_prop_bkr_cashpile_05' local objectCashPile = Utils.CreateObject(model, coords, rotation, true, true, false) table.insert(ownedCashPiles, objectCashPile) lib.waitFor(function() return PlaceObjectOnGroundProperly(objectCashPile) end, nil, 1000) local zoneKey = string.format('atmrobbery_explode_pickup_money_%d', #ownedCashPiles) Target.addBoxZone(zoneKey, { coords = GetEntityCoords(objectCashPile), size = vector3(1.75, 1.75, 1.75), debug = false, options = { { icon = 'fa-solid fa-hand-fist', label = locale('collect'), distance = 1.5, pile = objectCashPile, onSelect = function() client.setBusy(false, 'explode.onCashPileCollected') local playerPedId = cache.ped Target.removeZone(zoneKey) lib.playAnim(playerPedId, 'pickup_object', 'pickup_low', nil, nil, 1000) Citizen.Wait(1000) ClearPedTasks(playerPedId) deleteOwnedCashPile(objectCashPile) lib.callback.await(_e('server:explode:collectAtmCashPile'), false) end } } }) end function Explode.PlantBomb(_, model) Utils.debug('Explode.PlantBomb | Selected ATM Model: ', model) local pedCoords = GetEntityCoords(cache.ped) local entity = GetClosestObjectOfType(pedCoords.x, pedCoords.y, pedCoords.z, 2.0, model, false, false, false) if not DoesEntityExist(entity) then return end local atmCoords = GetEntityCoords(entity) local atmRotation = GetEntityRotation(entity) local atmModel = GetEntityModel(entity) if Entity(entity).state.robbed then return Utils.Notify(locale('atm_can_not_be_rob'), 'error') end if lib.callback.await(_e('server:IsAtmHacked'), false, atmModel, atmCoords) then return Utils.Notify(locale('atm_can_not_be_hack'), 'error') end if not lib.callback.await(_e('server:HasItem'), false, Config.Explode.requiredItem.name) then return Utils.Notify(locale('need_item', Config.Explode.requiredItem.label), 'error') end Utils.TriggerPoliceAlert(atmCoords) client.setHeadingToObject(atmModel) client.setBusy(true, 'explode.plantbomb') local modelOffset = Config.PlantOffset[atmModel] or vector3(0.0, 0.0, 1.0) local playerPedId = cache.ped local animDict = 'anim@heists@ornate_bank@thermal_charge' local animName = 'thermal_charge' lib.requestAnimDict(animDict) local sceneCoord = GetOffsetFromEntityInWorldCoords(entity, modelOffset.x, modelOffset.y, modelOffset.z) local sceneRot = atmRotation local plantScene = NetworkCreateSynchronisedScene(sceneCoord.x, sceneCoord.y, sceneCoord.z, sceneRot.x, sceneRot.y, sceneRot.z, 2, false, false, 1065353216, 0, 1.3) NetworkAddPedToSynchronisedScene(playerPedId, plantScene, animDict, animName, 1.5, -4.0, 1, 16, 1148846080, 0) NetworkStartSynchronisedScene(plantScene) Citizen.Wait(1500) local plantObject = Utils.CreateObject(plantModel, vector3(0.0, 0.0, 0.0), nil, true, false, false) SetEntityCollision(plantObject, false, true) AttachEntityToEntity(plantObject, playerPedId, GetPedBoneIndex(playerPedId, 28422), 0.0, 0.0, 0.0, 0.0, 0.0, 200.0, true, true, false, true, 1, true) Citizen.Wait(2500) local coords = GetEntityCoords(plantObject) local rotation = GetEntityRotation(plantObject) DeleteEntity(plantObject) ClearPedTasks(playerPedId) RemoveAnimDict(animDict) TriggerServerEvent(_e('server:RemoveItem'), Config.Explode.requiredItem.name) local data = { bombCoords = coords, bombRot = rotation, atmCoords = atmCoords, atmModel = atmModel } TriggerServerEvent(_e('server:explode:onBombPlanted'), data) end function Explode.Clear() deleteOwnedAtmObjects() end --[[ events ]] RegisterNetEvent(_e('client:explode:onBombPlanted'), function(data, owner) local atmCoords = data.atmCoords local atmModel = data.atmModel local atmEntity = GetClosestObjectOfType(atmCoords.x, atmCoords.y, atmCoords.z, 2.0, atmModel, false, false, false) if not DoesEntityExist(atmEntity) then return end Entity(atmEntity).state.robbed = true local bombCoords = data.bombCoords local bombRot = data.bombRot local bombObject = Utils.CreateObject(plantModel, bombCoords, bombRot, true, false, false) for i = 7, 1, -1 do PlaySoundFromCoord(-1, 'Beep_Red', bombCoords.x, bombCoords.y, bombCoords.z, 'DLC_HEIST_HACKING_SNAKE_SOUNDS', 0, 0, 0) Citizen.Wait(1000) end AddExplosion(bombCoords.x, bombCoords.y, bombCoords.z, 2, 2.0, true, false, 1.0, false) PlaySoundFromCoord(-1, 'Bomb_Disarmed', bombCoords.x, bombCoords.y, bombCoords.z, 'GTAO_Speed_Convoy_Soundset', 0, 0, 0) DeleteEntity(bombObject) if owner == cache.serverId then createMoneyObject(atmEntity) local ownedAtm = Utils.CreateObject(atmModel, GetEntityCoords(atmEntity), GetEntityRotation(atmEntity), false, true, false) ActivatePhysics(ownedAtm) SetEntityDynamic(ownedAtm, true) table.insert(ownedAtmObjects, ownedAtm) Entity(ownedAtm).state.robbed = true SetEntityAsMissionEntity(atmEntity, true, true) DeleteEntity(atmEntity) local forceDirection = vector3(1.0, 1.0, 1.0) ApplyForceToEntity(ownedAtm, 1, forceDirection.x, forceDirection.y, forceDirection.z, 0, 0, 0, true, true, true, true, false, true) Citizen.CreateThread(function() local ownedAtm = ownedAtm Citizen.Wait(10000) SetEntityAsNoLongerNeeded(ownedAtm) end) else SetEntityAsMissionEntity(atmEntity, true, true) DeleteEntity(atmEntity) end end)