← Resources
A complete airdrop system for QBcore framework using ox_lib UI. Players can request airdrops at designated locations with configurable items and cooldown periods.
Resource Specifications
- Framework:
QBCORE - UI Standard:
ox_lib - Language:
LUA
Included Files (4)
fxmanifest.lua
lua
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
name 'qb_airdrop'
description 'Airdrop system for QBcore framework'
version '1.0.0'
author 'FiveM Developer'
shared_script '@ox_lib/init.lua'
client_scripts {
'client/main.lua',
'config.lua'
}
server_scripts {
'@oxmysql/lib/MySQL.lua',
'server/main.lua',
'config.lua'
}
files {
'html/index.html',
'html/style.css',
'html/script.js'
}
ui_page 'html/index.html'
export 'TriggerAirdrop'config.lua
lua
Config = {}
Config.AirdropSettings = {
CooldownTime = 300,
MaxItemsPerDrop = 5,
DropHeight = 100.0,
DropRadius = 50.0,
LandingEffect = true,
SoundEnabled = true,
NotificationType = "advanced"
}
Config.AirdropLocations = {
{ x = 123.45, y = 678.90, z = 123.45 },
{ x = -234.56, y = 789.01, z = 123.45 },
{ x = 345.67, y = -890.12, z = 123.45 }
}
Config.AirdropItems = {
{ item = "weapon_pistol", amount = 1, chance = 10 },
{ item = "ammo_pistol", amount = 50, chance = 20 },
{ item = "bread", amount = 2, chance = 30 },
{ item = "water_bottle", amount = 2, chance = 30 },
{ item = "bandage", amount = 3, chance = 25 },
{ item = "radio", amount = 1, chance = 15 },
{ item = "repairkit", amount = 1, chance = 10 }
}
Config.AirdropVehicles = {
"tug",
"cargoplane",
"luxor",
"maverick"
}
Config.Sounds = {
StartSound = "airdrop_start",
DropSound = "airdrop_drop",
LandingSound = "airdrop_landing"
}
Config.Messages = {
RequestSuccess = "Airdrop requested successfully! Get ready for landing.",
RequestCooldown = "You must wait %s before requesting another airdrop.",
NoLocation = "No available airdrop location found.",
ItemReceived = "You received %s x%s from the airdrop!",
NotEnoughMoney = "You don't have enough money for an airdrop.",
InvalidLocation = "Invalid airdrop location selected."
}client/main.lua
lua
local QBCore = exports["qb-core"]:GetCoreObject()
local PlayerData = QBCore.Functions.GetPlayerData()
local currentCooldown = 0
local isAirdropping = false
AddEventHandler("onResourceStart", function(resourceName)
if resourceName == GetCurrentResourceName() then
print("[AIRDROP] Airdrop system initialized")
end
end)
RegisterCommand("airdrop", function(source, args, rawCommand)
if not IsPedInAnyVehicle(PlayerPedId(), false) then
OpenAirdropMenu()
else
QBCore.Functions.Notify("You cannot request an airdrop while in a vehicle!", "error")
end
end, false)
function OpenAirdropMenu()
if currentCooldown > 0 then
local timeLeft = math.ceil(currentCooldown / 60)
QBCore.Functions.Notify(string.format(Config.Messages.RequestCooldown, timeLeft .. " minute(s)"), "error")
return
end
local locations = {}
for i, loc in ipairs(Config.AirdropLocations) do
table.insert(locations, {
title = "Location " .. i,
description = "Request airdrop here",
value = i
})
end
local options = {
{
title = "Request Airdrop",
description = "Request a supply drop at a location",
icon = "plane",
onSelect = function()
if #locations > 0 then
ox_lib.menu("airdrop_locations", locations)
else
QBCore.Functions.Notify(Config.Messages.NoLocation, "error")
end
end
},
{
title = "Check Cooldown",
description = "See how long until you can request again",
icon = "clock",
onSelect = function()
if currentCooldown > 0 then
local timeLeft = math.ceil(currentCooldown / 60)
QBCore.Functions.Notify("Cooldown: " .. timeLeft .. " minute(s)", "info")
else
QBCore.Functions.Notify("No cooldown active", "success")
end
end
}
}
ox_lib.menu("airdrop_menu", options)
end
AddEventHandler("ox_lib:menuSelected", function(menu, option)
if menu == "airdrop_locations" then
local locationIndex = option.value
if locationIndex and locationIndex >= 1 and locationIndex <= #Config.AirdropLocations then
TriggerServerEvent("qb_airdrop:requestAirdrop", locationIndex)
else
QBCore.Functions.Notify(Config.Messages.InvalidLocation, "error")
end
elseif menu == "airdrop_menu" then
end
end)
RegisterNetEvent("qb_airdrop:response", function(success, message)
if success then
QBCore.Functions.Notify(message, "success")
else
QBCore.Functions.Notify(message, "error")
end
end)
RegisterNetEvent("qb_airdrop:updateCooldown", function(seconds)
currentCooldown = seconds
if seconds > 0 then
CreateThread(function()
while currentCooldown > 0 do
Wait(1000)
currentCooldown = currentCooldown - 1
end
end)
end
end)
RegisterNetEvent("qb_airdrop:startAirdrop", function(locationIndex)
if isAirdropping then return end
isAirdropping = true
local location = Config.AirdropLocations[locationIndex]
if not location then
QBCore.Functions.Notify(Config.Messages.InvalidLocation, "error")
isAirdropping = false
return
end
if Config.AirdropSettings.LandingEffect then
DrawLightWithRange(location.x, location.y, location.z + 10, 255, 255, 255, 100, 100)
end
if Config.AirdropSettings.SoundEnabled then
PlaySoundFrontend(-1, Config.Sounds.StartSound, "DLC_APT_AIRPORT_SOUNDSET", true)
end
local dropPosition = vector3(location.x, location.y, location.z + Config.AirdropSettings.DropHeight)
local groundZ = GetGroundZFor_3dCoord(location.x, location.y, location.z + 100)
local plane = CreateVehicle("cargoplane", dropPosition.x, dropPosition.y, dropPosition.z, 0.0, true, false)
SetEntityHeading(plane, 0.0)
SetEntityVisible(plane, false)
TaskPlaneMission(plane, PlayerPedId(), 0, 0, dropPosition.x, dropPosition.y, dropPosition.z, 0, 0, 0, 0, 0)
Wait(5000)
local dropEffect = CreateParticleFxAssetNextCall("scr_airdrop")
local items = GenerateRandomItems()
for i, item in ipairs(items) do
local dropPos = vector3(location.x + math.random(-Config.AirdropSettings.DropRadius, Config.AirdropSettings.DropRadius),
location.y + math.random(-Config.AirdropSettings.DropRadius, Config.AirdropSettings.DropRadius),
groundZ)
local pickup = CreateObject("prop_weed_01", dropPos.x, dropPos.y, dropPos.z, true, true, false)
SetEntityHeading(pickup, math.random(0, 360))
table.insert(airdropPickups, pickup)
end
DeleteEntity(plane)
QBCore.Functions.Notify("Airdrop has landed! Check around the area.", "success")
isAirdropping = false
end)
function GenerateRandomItems()
local items = {}
local itemCount = math.random(1, Config.AirdropSettings.MaxItemsPerDrop)
for i = 1, itemCount do
local totalChance = 0
for _, item in ipairs(Config.AirdropItems) do
totalChance = totalChance + item.chance
end
local randomValue = math.random(1, totalChance)
local cumulativeChance = 0
for _, item in ipairs(Config.AirdropItems) do
cumulativeChance = cumulativeChance + item.chance
if randomValue <= cumulativeChance then
table.insert(items, {
item = item.item,
amount = item.amount
})
break
end
end
end
return items
end
CreateThread(function()
while true do
Wait(100)
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
for i, pickup in ipairs(airdropPickups or {}) do
local pickupCoords = GetEntityCoords(pickup)
local distance = #(playerCoords - pickupCoords)
if distance < 2.0 then
DrawText3D(pickupCoords.x, pickupCoords.y, pickupCoords.z + 1.0, "Press ~INPUT_CONTEXT~ to collect")
if IsControlJustPressed(0, 51) then
TriggerServerEvent("qb_airdrop:collectItem", i)
DeleteEntity(pickup)
table.remove(airdropPickups, i)
end
end
end
end
end)
function DrawText3D(x, y, z, text)
SetDrawOrigin(x, y, z, 0)
SetTextFont(4)
SetTextProportional(1)
SetTextScale(0.0, 0.20)
SetTextColour(255, 255, 255, 255)
SetTextDropshadow(0, 0, 0, 0, 255)
SetTextEdge(1, 0, 0, 0, 255)
SetTextDropShadow()
SetTextOutline()
SetTextEntry("STRING")
AddTextComponentString(text)
DrawText(0.0, 0.0)
ClearDrawOrigin()
end
function TriggerAirdrop(locationIndex)
if not IsPedInAnyVehicle(PlayerPedId(), false) then
TriggerServerEvent("qb_airdrop:requestAirdrop", locationIndex)
else
QBCore.Functions.Notify("You cannot request an airdrop while in a vehicle!", "error")
end
end
airdropPickups = {}server/main.lua
lua
local QBCore = exports["qb-core"]:GetCoreObject()
local MySQL = require "lib/MySQL"
AddEventHandler("onResourceStart", function(resourceName)
if resourceName == GetCurrentResourceName() then
print("[AIRDROP] Airdrop system initialized on server")
end
end)
RegisterNetEvent("qb_airdrop:requestAirdrop")
AddEventHandler("qb_airdrop:requestAirdrop", function(locationIndex)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local cooldown = GetPlayerCooldown(src)
if cooldown > 0 then
TriggerClientEvent("qb_airdrop:response", src, false, string.format(Config.Messages.RequestCooldown, math.ceil(cooldown / 60) .. " minute(s)"))
return
end
if not Config.AirdropLocations[locationIndex] then
TriggerClientEvent("qb_airdrop:response", src, false, Config.Messages.InvalidLocation)
return
end
SetPlayerCooldown(src, Config.AirdropSettings.CooldownTime)
TriggerClientEvent("qb_airdrop:response", src, true, Config.Messages.RequestSuccess)
TriggerClientEvent("qb_airdrop:startAirdrop", src, locationIndex)
TriggerClientEvent("qb_airdrop:notification", -1, "A new airdrop has been requested!")
end)
RegisterNetEvent("qb_airdrop:collectItem")
AddEventHandler("qb_airdrop:collectItem", function(itemIndex)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
local items = GenerateRandomItems()
for _, item in ipairs(items) do
if Player.Functions.AddItem(item.item, item.amount) then
TriggerClientEvent("qb_airdrop:response", src, true, string.format(Config.Messages.ItemReceived, item.amount, item.item))
else
TriggerClientEvent("qb_airdrop:response", src, false, "Failed to add item to inventory")
end
end
end)
function GetPlayerCooldown(playerId)
local result = MySQL.scalar.await("SELECT cooldown FROM players WHERE citizenid = ?", {QBCore.Functions.GetPlayer(playerId).PlayerData.citizenid})
if result then
return result
else
return 0
end
end
function SetPlayerCooldown(playerId, seconds)
local player = QBCore.Functions.GetPlayer(playerId)
if player then
MySQL.query("UPDATE players SET cooldown = ? WHERE citizenid = ?", {seconds, player.PlayerData.citizenid})
TriggerClientEvent("qb_airdrop:updateCooldown", playerId, seconds)
end
end
function GenerateRandomItems()
local items = {}
local itemCount = math.random(1, Config.AirdropSettings.MaxItemsPerDrop)
for i = 1, itemCount do
local totalChance = 0
for _, item in ipairs(Config.AirdropItems) do
totalChance = totalChance + item.chance
end
local randomValue = math.random(1, totalChance)
local cumulativeChance = 0
for _, item in ipairs(Config.AirdropItems) do
cumulativeChance = cumulativeChance + item.chance
if randomValue <= cumulativeChance then
table.insert(items, {
item = item.item,
amount = item.amount
})
break
end
end
end
return items
end
AddEventHandler("onResourceStop", function(resourceName)
if resourceName == GetCurrentResourceName() then
print("[AIRDROP] Airdrop system stopped")
end
end)