271 lines
12 KiB
Lua
271 lines
12 KiB
Lua
|
local QBCore = exports[Config.CoreName]:GetCoreObject()
|
||
|
|
||
|
local pilot, aircraft, parachute, crate, soundID
|
||
|
|
||
|
local crate = nil
|
||
|
|
||
|
-- Clear crate variable on cooldown end.
|
||
|
RegisterNetEvent('qb-gunheist:crate:clearcrate', function()
|
||
|
crate = nil
|
||
|
end)
|
||
|
|
||
|
-- reward on open crate
|
||
|
function OpenCrate(entity, crate, item, amount)
|
||
|
local ped = PlayerPedId()
|
||
|
RequestAnimDict("pickup_object")
|
||
|
while not HasAnimDictLoaded("pickup_object") do Wait(10) end
|
||
|
TaskPlayAnim(ped, "pickup_object", "pickup_low", 8.0, -8.0, -1, 1, 0, false, false, false)
|
||
|
|
||
|
local netId = NetworkGetNetworkIdFromEntity(entity)
|
||
|
TriggerServerEvent('qb-gunheist:crate:deleteCrate', netId)
|
||
|
|
||
|
TriggerServerEvent("qb-gunheist:server:ItemHandler", "add", item, amount)
|
||
|
QBCore.Functions.Notify(Config.Lang["item_recieved"])
|
||
|
-- Finish
|
||
|
Wait(1000)
|
||
|
ClearPedTasks(ped)
|
||
|
end
|
||
|
|
||
|
-- Apply Natives
|
||
|
RegisterNetEvent("qb-gunheist:crate:applyNatives")
|
||
|
AddEventHandler("qb-gunheist:crate:applyNatives", function(netId)
|
||
|
crate = NetworkGetEntityFromNetworkId(netId)
|
||
|
SetEntityLodDist(crate, 1000)
|
||
|
ActivatePhysics(crate)
|
||
|
SetEntityVelocity(crate, 0.0, 0.0, -0.2)
|
||
|
end)
|
||
|
|
||
|
-- Crate Drop function
|
||
|
function CrateDrop(item, amount, planeSpawnDistance, dropCoords)
|
||
|
CreateThread(function()
|
||
|
QBCore.Functions.Notify(Config.Lang["pilot_dropping_soon"], "success", 15000) -- Notify the pilot that we are preparing the crate with the plane
|
||
|
SetTimeout(Config.TimeUntilDrop * 60 * 1000, function()
|
||
|
for i = 1, #Config.LoadModels do
|
||
|
RequestModel(GetHashKey(Config.LoadModels[i]))
|
||
|
while not HasModelLoaded(GetHashKey(Config.LoadModels[i])) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
end
|
||
|
RequestAnimDict(Config.ParachuteModel)
|
||
|
while not HasAnimDictLoaded(Config.ParachuteModel) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
RequestWeaponAsset(GetHashKey(Config.FlareName))
|
||
|
while not HasWeaponAssetLoaded(GetHashKey(Config.FlareName)) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
local rHeading = math.random(0, 360) + 0.0
|
||
|
local planeSpawnDistance = (planeSpawnDistance and tonumber(planeSpawnDistance) + 0.0) or 400.0
|
||
|
local theta = (rHeading / 180.0) * 3.14
|
||
|
local rPlaneSpawn = vector3(dropCoords.x, dropCoords.y, dropCoords.z) - vector3(math.cos(theta) * planeSpawnDistance, math.sin(theta) * planeSpawnDistance, -500.0)
|
||
|
local dx = dropCoords.x - rPlaneSpawn.x
|
||
|
local dy = dropCoords.y - rPlaneSpawn.y
|
||
|
local heading = GetHeadingFromVector_2d(dx, dy)
|
||
|
aircraft = CreateVehicle(GetHashKey(Config.PlaneModel), rPlaneSpawn, heading, true, true)
|
||
|
SetEntityHeading(aircraft, heading)
|
||
|
SetVehicleDoorsLocked(aircraft, 2)
|
||
|
SetEntityDynamic(aircraft, true)
|
||
|
ActivatePhysics(aircraft)
|
||
|
SetVehicleForwardSpeed(aircraft, 60.0)
|
||
|
SetHeliBladesFullSpeed(aircraft)
|
||
|
SetVehicleEngineOn(aircraft, true, true, false)
|
||
|
ControlLandingGear(aircraft, 3)
|
||
|
OpenBombBayDoors(aircraft)
|
||
|
SetEntityProofs(aircraft, true, false, true, false, false, false, false, false)
|
||
|
pilot = CreatePedInsideVehicle(aircraft, 1, GetHashKey(Config.PlanePilotModel), -1, true, true)
|
||
|
SetBlockingOfNonTemporaryEvents(pilot, true)
|
||
|
SetPedRandomComponentVariation(pilot, false)
|
||
|
SetPedKeepTask(pilot, true)
|
||
|
SetPlaneMinHeightAboveTerrain(aircraft, 50)
|
||
|
TaskVehicleDriveToCoord(pilot, aircraft, vector3(dropCoords.x, dropCoords.y, dropCoords.z) + vector3(0.0, 0.0, 500.0), 60.0, 0, GetHashKey(Config.PlaneModel), 262144, 15.0, -1.0) -- to the dropsite, could be replaced with a task sequence
|
||
|
local droparea = vector2(dropCoords.x, dropCoords.y)
|
||
|
local planeLocation = vector2(GetEntityCoords(aircraft).x, GetEntityCoords(aircraft).y)
|
||
|
while not IsEntityDead(pilot) and #(planeLocation - droparea) > 5.0 do
|
||
|
Wait(100)
|
||
|
planeLocation = vector2(GetEntityCoords(aircraft).x, GetEntityCoords(aircraft).y)
|
||
|
end
|
||
|
if IsEntityDead(pilot) then
|
||
|
QBCore.Functions.Notify(Config.Lang["pilot_crashed"], "error") -- Notify the pilot that the plane has crashed
|
||
|
return
|
||
|
end
|
||
|
TaskVehicleDriveToCoord(pilot, aircraft, 0.0, 0.0, 500.0, 60.0, 0, GetHashKey(Config.PlaneModel), 262144, -1.0, -1.0)
|
||
|
SetEntityAsNoLongerNeeded(pilot)
|
||
|
SetEntityAsNoLongerNeeded(aircraft)
|
||
|
QBCore.Functions.Notify(Config.Lang["crate_dropping"], "success") -- Notify the pilot that we are preparing the crate with the plane
|
||
|
local crateSpawn = vector3(dropCoords.x, dropCoords.y, GetEntityCoords(aircraft).z - 5.0)
|
||
|
TriggerServerEvent("qb-gunheist:crate:spawnCrate", crateSpawn, item, amount)
|
||
|
while crate == nil do
|
||
|
Wait(250)
|
||
|
end
|
||
|
parachute = CreateObject(GetHashKey(Config.ParachuteModel), crateSpawn, true, true, true)
|
||
|
AttachEntityToEntity(parachute, crate, 0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, false, false, false, false, 2, true)
|
||
|
SetEntityLodDist(parachute, 1000)
|
||
|
SetEntityVelocity(parachute, 0.0, 0.0, -0.2)
|
||
|
AttachEntityToEntity(parachute, crate, 0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, false, false, false, false, 2, true)
|
||
|
-- Sound
|
||
|
soundID = GetSoundId()
|
||
|
PlaySoundFromEntity(soundID, "Crate_Beeps", parachute, "MP_CRATE_DROP_SOUNDS", true, 0)
|
||
|
|
||
|
-- Checks when the crate is at the dropsite and delete the parachute
|
||
|
local parachuteCoords = vector3(GetEntityCoords(parachute))
|
||
|
while #(parachuteCoords - dropCoords) > 5.0 do
|
||
|
Wait(250)
|
||
|
parachuteCoords = vector3(GetEntityCoords(parachute))
|
||
|
end
|
||
|
ShootSingleBulletBetweenCoords(dropCoords, dropCoords - vector3(0.0001, 0.0001, 0.0001), 0, false, GetHashKey(Config.FlareName), 0, true, false, -1.0)
|
||
|
DetachEntity(parachute, true, true)
|
||
|
DeleteEntity(parachute)
|
||
|
StopSound(soundID)
|
||
|
ReleaseSoundId(soundID)
|
||
|
for i = 1, #Config.LoadModels do
|
||
|
Wait(0)
|
||
|
SetModelAsNoLongerNeeded(GetHashKey(Config.LoadModels[i]))
|
||
|
end
|
||
|
RemoveWeaponAsset(GetHashKey(Config.FlareName))
|
||
|
end)
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
RegisterNetEvent("qb-gunheist:crate:createQbTarget")
|
||
|
AddEventHandler("qb-gunheist:crate:createQbTarget", function(crate, item, amount)
|
||
|
exports[Config.TargetName]:AddTargetModel('ex_prop_adv_case_sm', {
|
||
|
options = {
|
||
|
{
|
||
|
icon = Config.TargetIcon,
|
||
|
label = Config.TargetLabel,
|
||
|
action = function(entity)
|
||
|
OpenCrate(entity, crate, item, amount)
|
||
|
end,
|
||
|
}
|
||
|
},
|
||
|
distance = 2.5,
|
||
|
})
|
||
|
end)
|
||
|
|
||
|
-- notify police functions
|
||
|
function PoliceAlert()
|
||
|
-- exports['ps-dispatch']:AirDrop()
|
||
|
end
|
||
|
|
||
|
-- Give random item from given list of the item used
|
||
|
function GetRandomItemData(item)
|
||
|
if Config.ItemDrops[item] then
|
||
|
local Items = Config.ItemDrops[item]
|
||
|
local randomItem = Items[math.random(#Items)]
|
||
|
return randomItem["name"], randomItem["amount"]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Start the AirDrop
|
||
|
RegisterNetEvent("qb-gunheist:client:StartDrop", function(item, amount, roofCheck, planeSpawnDistance, dropCoords)
|
||
|
CreateThread(function()
|
||
|
if dropCoords.x and dropCoords.y and dropCoords.z and tonumber(dropCoords.x) and tonumber(dropCoords.y) and tonumber(dropCoords.z) then
|
||
|
else
|
||
|
dropCoords = {0.0, 0.0, 72.0}
|
||
|
end
|
||
|
RequestWeaponAsset(GetHashKey(Config.FlareName))
|
||
|
while not HasWeaponAssetLoaded(GetHashKey(Config.FlareName)) do
|
||
|
Wait(0)
|
||
|
end
|
||
|
ShootSingleBulletBetweenCoords(GetEntityCoords(PlayerPedId()), GetEntityCoords(PlayerPedId()) - vector3(0.0001, 0.0001, 0.0001), 0, false, GetHashKey(Config.FlareName), 0, true, false, -1.0)
|
||
|
|
||
|
TriggerServerEvent('dropCoords:server:setPoly', dropCoords)
|
||
|
if roofCheck and roofCheck ~= "false" then
|
||
|
local ray = StartShapeTestRay(vector3(dropCoords.x, dropCoords.y, dropCoords.z) + vector3(0.0, 0.0, 500.0), vector3(dropCoords.x, dropCoords.y, dropCoords.z), -1, -1, 0)
|
||
|
local _, hit, impactCoords = GetShapeTestResult(ray)
|
||
|
if hit == 0 or (hit == 1 and #(vector3(dropCoords.x, dropCoords.y, dropCoords.z) - vector3(impactCoords)) < 10.0) then
|
||
|
CrateDrop(item, amount, planeSpawnDistance, dropCoords)
|
||
|
else
|
||
|
return
|
||
|
end
|
||
|
else
|
||
|
CrateDrop(item, amount, planeSpawnDistance, dropCoords)
|
||
|
end
|
||
|
|
||
|
end)
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('dropCoords:client:setPoly', function(dropCoords)
|
||
|
local radiusBlipSize = 175.0
|
||
|
|
||
|
-- Create blip at dropCoords
|
||
|
dropBlip = AddBlipForCoord(dropCoords.x, dropCoords.y, dropCoords.z)
|
||
|
SetBlipSprite(dropBlip, 94)
|
||
|
SetBlipColour(dropBlip, 1)
|
||
|
SetBlipAsShortRange(dropBlip, true)
|
||
|
BeginTextCommandSetBlipName("STRING")
|
||
|
AddTextComponentString("Airdrop")
|
||
|
EndTextCommandSetBlipName(dropBlip)
|
||
|
|
||
|
-- Create radius blip around dropCoords
|
||
|
radiusBlip = AddBlipForRadius(dropCoords.x, dropCoords.y, dropCoords.z, radiusBlipSize)
|
||
|
SetBlipColour(radiusBlip, 1)
|
||
|
SetBlipAlpha(radiusBlip, 80)
|
||
|
|
||
|
DropZone = BoxZone:Create(vector3(dropCoords.x, dropCoords.y, dropCoords.z), 175.0, 175.0, {
|
||
|
name="AtDrop",
|
||
|
heading=335.31,
|
||
|
minZ=dropCoords.z-10,
|
||
|
maxZ=dropCoords.z+100,
|
||
|
debugPoly = false
|
||
|
})
|
||
|
DropZone:onPlayerInOut(function(isPointInside)
|
||
|
if isPointInside then
|
||
|
QBCore.Functions.Notify("Du er i dropzonen. Hver mand for sig selv.", "error")
|
||
|
else
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
end)
|
||
|
|
||
|
RegisterNetEvent('qb-gunheist:crate:destroyzone', function()
|
||
|
SetTimeout(200000, function()
|
||
|
DropZone:destroy()
|
||
|
RemoveBlip(dropBlip)
|
||
|
RemoveBlip(radiusBlip)
|
||
|
end)
|
||
|
end)
|
||
|
|
||
|
-- Create the AirDrop
|
||
|
RegisterNetEvent("qb-gunheist:client:CreateDrop", function(useditem, roofCheck, planeSpawnDistance)
|
||
|
local playerCoords = GetOffsetFromEntityInWorldCoords(PlayerPedId(), 0.0, 10.0, 0.0)
|
||
|
local item, amount = GetRandomItemData(useditem)
|
||
|
QBCore.Functions.TriggerCallback("qb-gunheist:server:cooldown", function(cooldown)
|
||
|
if not cooldown then
|
||
|
QBCore.Functions.TriggerCallback("qb-gunheist:server:getCops", function(CurrentCops)
|
||
|
if CurrentCops >= Config.RequiredCops then
|
||
|
TriggerServerEvent('qb-gunheist:server:startCooldown')
|
||
|
QBCore.Functions.Notify(Config.Lang["pilot_contact"], "success", 10000)
|
||
|
PoliceAlert()
|
||
|
TriggerServerEvent("qb-gunheist:server:ItemHandler", "remove", useditem, 1)
|
||
|
TriggerEvent("qb-gunheist:client:StartDrop", item, amount, roofCheck or false, planeSpawnDistance or 400.0, vector3(playerCoords.x, playerCoords.y, playerCoords.z))
|
||
|
else
|
||
|
QBCore.Functions.Notify(Config.Lang["no_cops"], "error")
|
||
|
end
|
||
|
end)
|
||
|
else
|
||
|
QBCore.Functions.Notify("Der er for mange ting i luftrummet.", "error")
|
||
|
end
|
||
|
end)
|
||
|
end)
|
||
|
|
||
|
-- On resource stop do things
|
||
|
AddEventHandler("onResourceStop", function(resource)
|
||
|
if resource == GetCurrentResourceName() then
|
||
|
SetEntityAsMissionEntity(pilot, false, true)
|
||
|
DeleteEntity(pilot)
|
||
|
SetEntityAsMissionEntity(aircraft, false, true)
|
||
|
DeleteEntity(aircraft)
|
||
|
DeleteEntity(parachute)
|
||
|
DeleteEntity(crate)
|
||
|
RemovePickup(pickup)
|
||
|
RemoveBlip(blip)
|
||
|
StopSound(soundID)
|
||
|
ReleaseSoundId(soundID)
|
||
|
for i = 1, #Config.LoadModels do
|
||
|
Wait(0)
|
||
|
SetModelAsNoLongerNeeded(GetHashKey(Config.LoadModels[i]))
|
||
|
end
|
||
|
end
|
||
|
end)
|