232 lines
		
	
	
	
		
			7.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			232 lines
		
	
	
	
		
			7.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| --[[ 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)
 | 
