PoisonCode Docs
TebexDiscordYoutube
  • SCRIPTS
    • 💡pc_collections
      • ✨Features
      • 🖥️Installation & dependencies
      • 🛠️Exports & events
      • ⚙️Open files preview
      • 🔧Tutorials
      • 📥Updates
        • 🤔How to update
        • 🔌Version compatibility
    • 💎pc_organizations
      • ✨Features
      • 🖥️Installation & dependencies
      • 🛠️Exports & events
      • ⚙️Open files preview
      • 🔧Tutorials
      • 📥Updates
        • 🤔How to update
        • 🔌Version compatibility
    • 💡pc_skills
      • ✨Features
      • 🖥️Installation & dependencies
      • 🛠️Exports & events
      • ⚙️Open files preview
      • 🔧Tutorials
      • 📥Updates
        • 🤔How to update
    • 📦pc_airdrop
      • ✨Features
      • 🖥️Installation & dependencies
      • ⚙️Open files preview
      • 🔧Tutorials
      • 📥Updates
        • 🤔How to update
    • 💬pc_notifications
      • ✨Features
      • 🖥️Installation & dependencies
      • 🕹️Usage
Powered by GitBook
On this page
  • config/config.lua
  • config/translations.lua
  • client/utils.lua
  • server/utils.lua

Was this helpful?

  1. SCRIPTS
  2. pc_airdrop

Open files preview

Config & Utils files preview, these files are ignored by the escrow system and can be modified.

This script is highly customizable, there is a total of 4 files accessible for you.

config/config.lua

Click here to see a preview config.lua
Config = {} 
-- _____                          _____          _      
-- |  __ \    (_)                / ____|        | |     
-- | |__) |__  _ ___  ___  _ __ | |     ___   __| | ___ 
-- |  ___/ _ \| / __|/ _ \| '_ \| |    / _ \ / _` |/ _ \
-- | |  | (_) | \__ \ (_) | | | | |___| (_) | (_| |  __/
-- |_|   \___/|_|___/\___/|_| |_|\_____\___/ \__,_|\___|
-- © PoisonCode 
-- Discord: https://discord.gg/rNJ8cHXCsN
-- Tebex: https://poisoncode.tebex.io


----- This script is highly customizable, plase take your time and adjust it to your needs! ------
--------------------------------------------------------------------------------------------------
--  --------------- If you encounter any bugs, please report it on our discord ---------------- --
-- Documentation available at: https://poisoncode.gitbook.io/poisoncode-docs/scripts/pc_airdrop --
--------------------------------------------------------------------------------------------------

-- BY DEFAULT REWARD ITEMS ARE GIVEN USING ESX OR QBCORE FUNCTION. 
-- SEE utils/server.lua TO MODIFY FUNCTION RESPONSIBLE FOR ADDING ITEMS TO INVENTORY!

Config.UseExperimentalFeatures = false -- If you want to use experimental features, set this to true. (Experimental features are not fully tested and may not work as expected)

Config.ClientDebugMessages = false -- Enables additional debug messages on the client side console (F8), we recommend turning this off while not debugging 
Config.ServerDebugMessages = true -- Enables additional debug messages on the server side console, you can keep it on if these messages don't bother you
-- ^^ (Errors and warnings will always be displayed) ^^


--   Technical  --
Config.Framework = "NEW-ESX"      -- "NEW-ESX" - "ESX" - "QBCore"
Config.UseCollision2 = false       -- If you're experiencing an error where the airdrop gets stuck in the air, set this to true, otherwise it's not recommended


--    Basic     --
Config.CaptureTime = 15             -- Time (in seconds) required to capture an airdrop
Config.CaptureDistance = 10         -- How far can you go before airdrop capture is canceled
Config.AirdropFallSpeed = 1       -- How quick should the airdrop fall. Default 1 (Slowest setting) (Used only when Config.AirdropGroundSpawn is false)
Config.AirdropGroundSpawn = false   -- Should the airdrop spawn directly on the ground (Without falling down from the sky)
Config.LocationNotification = true  -- If set to true, notification will contain airdrop name and location name


-- Discord logs --
Config.DiscordLogs = false         -- Set to true if you want to recieve discord logs. (set your webhook in server utils)


-- Integrations --
Config.Use_Target = false           -- If you set this option to true, collecting the airdrop will be possible only using qTarget or ox_target
Config.Target = "ox_target"         -- "qtarget" or "ox_target" or "qb-target"
Config.Use_OxInventory = false      -- Turns on ox_inventory integration
Config.RemoveWhenEmpty = false      -- When using ox_inventory, should the airdrop crate be removed when players take all the items
Config.Use_pcnotifications = GetResourceState('pc_notifications') == 'started' or false -- Automatically turns the pc_notification on or off


--  Advanced    --
Config.Plane = {
    enable = true,                 -- Should there be a plane flying by and dropping the airdrop
    distance = 500,                -- How far should the plane spawn (bigger value = longer fly time)
    speed = 50,                    -- How fast should the plane travel
}


Config.AirdropRemove = {
    enable = true,                 -- Removes the airdrop after a period of time. Especially recommended if you're using ox_inventory integration
    time = 1200,                   -- Time (in seconds) after the airdrop is automatically removed from the map (example 1200 sec = 20 min)
}


Config.AirdropLock = {
    enable = true,                 -- After falling/spawning, should the airdrop be locked
    showtext = true,               -- Should there be 3D/Helpnotification/custom text showed when the airdrop is locked AirdropLock.enable should be set to true
    time = 15,                     -- How long should the airdrop be locked for after falling/spawning
}


Config.Models = {
    -- You can change crate and/or parachute prop model. List of all props: https://gta-objects.xyz/objects/
    -- Warning: some models might not work or have different physics. Change at your own risk
    crate = "xm_prop_rsply_crate04a",
    parachute = "p_parachute1_mp_dec",

    -- Plane model
    plane = "titan",

    -- Ped model for pilot. List of all peds: https://docs.fivem.net/docs/game-references/ped-models/ 
    npc_pilot = "s_m_m_pilot_02",
}


Config.ShowFlares = {
    [1] = true, -- Should there be a "flare effect" on the ground when the airdrop is falling ? (true/false)
    [2] = true, -- Should there be a "flare + smoke effect" on the airdrop crate when it lands on the ground ? (true/false)
}


-- Basic methods of spawning an airdrop
Config.AirdropSpawnMethod = {
    event_enabled = false, -- Creates a custom server event for calling an airdrop (customize in utils/server.lua)

    command_enabled = true, -- Should you be able to call command /airdrop (customize in utils/server.lua) WARNING: BY DEFAULT COMMAND IS AVAILABLE FOR EVERYONE

    auto_enabled = false, -- Should there be an airdrop every X minutes (Set cooldown below)
    auto_delay = 10, -- After server/script restart, first airdrop will be called in after this delay (in minutes) DEFAULT: 10 MINUTE DELAY
    auto_timer = 60, -- Time in minutes between airdrops. DEFAULT: AIRDROP EVERY 60 MINUTES
}


-- If you want your airdrop to be called in a random spot within provided coords and radius set Config.AirDropInRadius to true.
-- If you set Config.AirDropInRadius to false, the airdrop will always land on provided coords, and radius will be ignored (we suggest to disable radius blip if in that case).
-- Airdrop location will be choosen at random from coords provided below, unless a forced location will be provided with a command or through event.
-- Bear in mind that this script does not check if location is safe, it is possible that the airdrop falls in water. Be cautious when setting spawn radius
Config.AirDropInRadius = true 
Config.Locations = {
    {label = "Location1", coords = vector3(3678.45, 4983.75, 15.83), radius = 50},
    {label = "Location2", coords = vector3(1450.03, 4408.11, 46.77), radius = 50},
    {label = "Location3", coords = vector3(112.3445, 6827.7622, 17.0759), radius = 80},
    {label = "Location4", coords = vector3(2504.6265, 3264.5303, 52.1214), radius = 50},
    {label = "Location5", coords = vector3(1573.6575, 3196.3611, 40.5308), radius = 70},
    {label = "Location6", coords = vector3(334.0565, 2849.8423, 43.4093), radius = 60},
    {label = "Location7", coords = vector3(-2171.0454, 3063.4260, 32.9654), radius = 60},
    {label = "Location8", coords = vector3(-1334.5094, -3040.9614, 13.9444), radius = 100},
    {label = "Location9", coords = vector3(1373.5991, -745.4987, 67.2328), radius = 60},
}


-- Configure airdrops and their loot, type of spawned airdrop is random.
-- ItemName is the name used to give the item to the player.
-- ItemAmount OR ItemAmountMin & ItemAmountMax is the amount of this item that should be awarded to player.
-- If using ItemAmountMin & ItemAmountMax the amount will be chosen at random between these two values
-- Chance is the chance (1-100) that the player recieves this item. If set to 100, player will always recieve this reward.
-- Type "item" or "weapon" (will be ignored if using ox_inventory), used when you DONT use "weapons as items" (you can only have one weapon of given type for example).
Config.AirDrops = {
    [1] = { -- Airdrop id number (has to bee different for each airdrop)
        ['name'] = "Medical", -- Name of the airdrop that will be shown in notifications
        ['items'] = { -- Loot table
            {ItemName = "bandage", ItemAmountMin = 5, ItemAmountMax = 10, Chance = 100, Type = "item"}, -- items, amount and chance
            {ItemName = "medikit", ItemAmount = 1, Chance = 90, Type = "item"},
        },
        },
    [2] = {
        ['name'] = "Weapons", -- Name of the airdrop that will be shown in notifications
        ['items'] = { -- Loot table
            {ItemName = "weapon_pistol", ItemAmount = 1, Chance = 100, Type = "item"}, -- <- if not using ox_inventory or other "weapons as items" script, change type to "weapon"
            {ItemName = "weapon_pistol50", ItemAmount = 1, Chance = 10, Type = "item"},
        },
        },
    [3] = {
        ['name'] = "Drugs", -- Name of the airdrop that will be shown in notifications
        ['items'] = { -- Loot table
            {ItemName = "weed", ItemAmount = 10, Chance = 100, Type = "item"},
            {ItemName = "coke", ItemAmountMin = 5, ItemAmountMax = 15, Chance = 50, Type = "item"},
        },
    },
}


-- List of blip IDs and colors - https://docs.fivem.net/docs/game-references/blips/
Config.blips = {
    main = { 
    ['enabled'] = true, -- Should the main blip be on ? (true/false)
    ['scale'] = 1.2, -- Scale of the main blip
    ['blipId'] = 568, -- Blip (See link above for reference)
    ['color'] = 81, -- Blip color (See link above for reference)
    ['type'] = 6, -- For blip types, please reference: https://docs.fivem.net/natives/?_0x9029B2F3DA924928
    ['name'] = "Airdrop", -- Label of the main blip on the map
    },

    radius = {
    ['enabled'] = true, -- Should the radius blip be on ? (true/false)
    ['color'] = 81, -- Radius blip color (See link above for reference)
    ['alpha'] = 100, -- Radius blip transparency (higher number = lower transparency)
    },
}


Config.Marker = {
    enabled = true, -- Should there be a circle marker showing how far can you go when capturing an airdrop
    red = 0, green = 125, blue = 255, -- You can customize the color of the marker by adjusting RGB (0-255)
}


-- How should "collect" text be showed. Available types:
-- 0 - No 3D Text or notification will be displayed
-- 1 - 3D text is being displayed on the airdrop crate (This option is slightly less efficient, if you care about performance use another type)
-- 2 - Help notofication is being displayed in the top left corner.
-- 3 - Will run code from CustomCaptureFuntion in utils/client.lua.
-- See https://poisoncode.gitbook.io/poisoncode-docs/scripts/pc_airdrop for reference
Config.captureTextType =  1


-- [[Notifications functions has been moved to: utils/client.lua]]
-- [[Custom event has been moved to utils/client.lua]]

config/translations.lua

Click here to see a preview translations.lua
-- _____                          _____          _      
-- |  __ \    (_)                / ____|        | |     
-- | |__) |__  _ ___  ___  _ __ | |     ___   __| | ___ 
-- |  ___/ _ \| / __|/ _ \| '_ \| |    / _ \ / _` |/ _ \
-- | |  | (_) | \__ \ (_) | | | | |___| (_) | (_| |  __/
-- |_|   \___/|_|___/\___/|_| |_|\_____\___/ \__,_|\___|
-- © PoisonCode 
-- Discord: https://discord.gg/rNJ8cHXCsN
-- Tebex: https://poisoncode.tebex.io
 
Translations = {
    base = {
        -- Text showed during airdrop capture
        ["collect"] = "Press ~y~E ~w~to capture the airdrop", -- Text shown before player started capturing the airdrop
        ["collecting"] = "Airdrop is being captured. Remaining: ~b~%s ~w~sec",

        -- Used only when Config.AirdropGroundTextLabel is true
        ["airdrop_locked"] = "~r~Airdrop locked for: ~y~%s ~w~sec",

        -- Notifications text
        ["notification_inbound"] = "Airdrop has been called!",
        ["notification_inbound_2"] = "%s airdrop was called to %s!",
        ["notification_startcapture"] = "You are capturing the airdrop!",
        ["notification_captured"] = "You captured the airdrop!",
        ["notification_capturecanceled"] = "You cancelled airdrop capture!",
        ["notification_someonecaptured"] = "Someone captured the airdrop!",
        ["notification_cantcapture"] = "This airdrop is already being captured!",

        -- Target event label
        ["TargetText"] = "Capture the airdrop", 

        -- Ox_inventory stash label
        ["oxinv_label"] = "Airdrop",
    },

    -- Discord logs
    discord = {
        -- Titles
        ["title_auto"] = "Airdrop called automatically",
        ["title_command"] = "Airdrop called by command",
        ["title_event"] = "Airdrop called by event",
        ["title_captured"] = "Airdrop captured",
        ["title_remove"] = "Airdrop removed",

        -- Desc
        ["call_auto"] = "Airdrop was called in automatically!",
        ["call_command"] = "called an airdrop using a command!",
        ["call_event"] = "Airdrop was called in by event!",
        ["captured_by"] = "Airdrop was captured by: ",
        ["type"] = "Type",
        ["location"] = "Location",
        ["airdrop_remove"] = "Airdrop crate was automatically removed.",
        ["airdrop_remove_items"] = "Airdrop crate was removed because all items were taken.",
    }

}

client/utils.lua

Click here to see a preview client.lua
-- [1. Main functions]
-- a) Function responsible for sending the notifications
function SendNotification(text, type)
    local time = 5000 -- how long should notification be on screen (in ms)
    if Config.Use_pcnotifications then
        exports['pc_notifications']:Notify(type, 'Airdrop', text, time, true)
    else
        -- Other notification system
    end
end


-- b) Joining player sync -- EXPERIMENTAL - only works when Config.UseExperimentalFeatures is set to true
AddEventHandler('playerJoinedEvent',function()
    TriggerServerEvent('pc_airdrop:server:requestAirdropSync')
end)



-- [2. Event functions]
-- a) This function is triggered when the airdrop is called
function onAirdropCall(type, location)
    if Config.LocationNotification and location then
        SendNotification((Translations.base["notification_inbound_2"]):format(type, location), 'info')
    else
        SendNotification(Translations.base["notification_inbound"], 'info')
    end
    -- *CUSTOM CODE*
    -- *EVENT TRIGGER* 
    -- ETC.
end

-- b) This function is triggered when the airdrop hits the ground (Does not trigger if Config.AirdropGroundSpawn is on)
function onAirdropHit()
    --SendNotification("Airdrop hit the ground!", 'info')
end

-- c) This function is triggered when the airdrop unlocks (Only when airdrop lock is enabled in Config)
function onAirdropUnlock()
    --SendNotification("Airdrop has been unlocked!", 'info')
end

-- d) This function is triggered when you start capturing the airdrop
function onCaptureStart() 
    SendNotification(Translations.base["notification_startcapture"], 'info')
end

-- e) This function is triggered when you successfully capture the airdrop
function onAirdropCapture() 
    SendNotification(Translations.base["notification_captured"], 'success')
end
 
-- f) This function is triggered when someone else successfully captures the airdrop
function onCaptureSomeone()
    SendNotification(Translations.base["notification_someonecaptured"], 'info')
end 

-- g) This function is triggered when you cancel capturing the airdrop
function onCaptureCancel()
    SendNotification(Translations.base["notification_capturecanceled"], 'error')
end

-- h) This function is triggered when you try to capture the airdrop but you can't
function onCaptureTryFail()
    SendNotification(Translations.base["notification_cantcapture"], 'error')
end


-- [3. Integration/technical functions]
-- a) 3D Text function, you can customize font, size etc.
function Draw3DText(x, y, z, scl_factor, text)
    local onScreen, _x, _y = World3dToScreen2d(x, y, z + 1.0)
    local p = GetGameplayCamCoords()
    local distance = GetDistanceBetweenCoords(p.x, p.y, p.z, x, y, z + 1.0, 1)
    local scale = (1 / distance) * 2
    local fov = (1 / GetGameplayCamFov()) * 100
    local scale = scale * fov * scl_factor
    if onScreen then
        SetTextScale(0.0, scale)
        SetTextFont(4)
        SetTextProportional(1)
        SetTextColour(255, 255, 255, 215)
        SetTextDropshadow(0, 0, 0, 0, 255)
        SetTextEdge(2, 0, 0, 0, 150)
        SetTextDropShadow()
        SetTextOutline()
        SetTextEntry("STRING")
        SetTextCentre(1)
        AddTextComponentString(text)
        DrawText(_x, _y)
    end
end

-- b) Help Notification function, not much to customize
function ShowHelpNotification(text)
    SetTextComponentFormat("STRING")
    AddTextComponentString(text)
    DisplayHelpTextFromStringLabel(0, 0, 1, -1)
end

-- c) Custom function that should be ran when Config.captureTextType is set to 3
function CustomCaptureFuntion(text)
    print(text) -- EXAMPLE
     -- You can add custom code here to for example: trigger a progress bar
end

-- d) Blips customization
function CreateBlips(coords, radius)
    -- Main blip
	if Config.blips.main['enabled'] then
		blips[1] = AddBlipForCoord(coords)
		SetBlipScale(blips[1], Config.blips.main['scale'])
		SetBlipSprite(blips[1], Config.blips.main['blipId'])
		SetBlipHighDetail(blips[1], true)
		SetBlipColour(blips[1], Config.blips.main['color'])
		SetBlipDisplay(blips[1], Config.blips.main['type'])
		BeginTextCommandSetBlipName("STRING")
		AddTextComponentString(Config.blips.main['name'])
		EndTextCommandSetBlipName(blips[1])
	end

    -- Radius blip
	if Config.blips.radius['enabled'] and radius then
		blips[2] = AddBlipForRadius(coords, radius + 10.0)
		SetBlipSprite(blips[2], 9)
		SetBlipColour(blips[2], Config.blips.radius['color'])
		SetBlipAlpha(blips[2], Config.blips.radius['alpha'])
	end
end

-- [4. Targeting system integration]
if Config.Use_Target then
	if Config.Target == "qtarget" then
		exports.qtarget:AddTargetModel({GetHashKey(Config.Models.crate)}, {
			options = {
				{	
					event = "pc_airdrop:client:targetcollect",
					icon = "fas fa-hand",
					label = Translations.base["TargetText"],
					canInteract = function()
						return not capturing_me and not capturing_someone and lock_timer <= 0
					end
				},
			},
			distance = 5.0,
		})
	elseif Config.Target == "ox_target" then
		exports.ox_target:addModel({GetHashKey(Config.Models.crate)}, {
			name = 'Airdrop',
			label = Translations.base["TargetText"],
			icon = "fas fa-hand",
			event = "pc_airdrop:client:targetcollect",  
			canInteract = function()
				return not capturing_me and not capturing_someone and lock_timer <= 0
			end,
			distance = 5.0,    
		})
	elseif Config.Target == "qb-target" then
        exports['qb-target']:AddTargetModel(GetHashKey(Config.Models.crate), {
            options = {
                {
                    type = "client",
                    event = "pc_airdrop:client:targetcollect",
					icon = "fas fa-hand",
                    label = Translations.base["TargetText"],
					canInteract = function()
						return not capturing_me and not capturing_someone and lock_timer <= 0
					end
                },
            },
            distance = 5.0,
        })
	end
end

server/utils.lua

Click here to see a preview server.lua
-- [1. Framework + integrations]
Framework = nil

if Config.Framework == "NEW-ESX" then
    Framework = exports["es_extended"]:getSharedObject()
elseif Config.Framework == "ESX" then
    TriggerEvent('esx:getSharedObject', function(library) 
        Framework = library 
    end)
elseif Config.Framework == "QBCore" then
    Framework = exports["qb-core"]:GetCoreObject()
end
                           
function RewardItems(src, item, amount, type)
    -- If you're using esx:
    if Config.Framework == "NEW-ESX" or Config.Framework == "ESX" then
        local xPlayer = Framework.GetPlayerFromId(src)
        if xPlayer then
            if type ~= "weapon" then -- adding an item
                xPlayer.addInventoryItem(item, amount)
                -- You can add notifications here if you'd like
            else -- adding a weapon
                xPlayer.addWeapon(item, amount)
                -- You can add notifications here if you'd like
            end
        end

    -- if you're using qb-core:
    elseif Config.Framework == "QBCore" then
        local xPlayer = Framework.Functions.GetPlayer(src)
        if xPlayer then
            xPlayer.Functions.AddItem(item, amount)
            -- You can add notifications here if you'd like
        end
    end
end

-- ox_inventory integration (if you're using other grid based inventory system, you can modify this part of the code) 
-- don't touch it if you don't know what you're doing
if Config.Use_OxInventory then

    local ox_inventory = exports.ox_inventory

    ox_inventory:RegisterStash('airdrop', Translations.base["oxinv_label"], 50, 100000, false)

    function oxinvAddItem(itemName, itemCount)
        local inventory = ox_inventory:GetInventory({id = 'airdrop'})
        ox_inventory:AddItem(inventory.id, itemName, itemCount)
    end

    function oxinvClearInv()
        local inventory = ox_inventory:GetInventory({id = 'airdrop'})
        ox_inventory:ClearInventory(inventory)
    end

end


-- [2. Airdrop spawning]
-- COMMAND
-- WARNING: THIS COMMAND IS AVAILABLE FOR EVERYONE BY DEFAULT, CHANGE THE CODE BELOW TO ONLY ALLOW CERATIN PEOPLE TO CALL THE AIRDROP!
if Config.AirdropSpawnMethod['command_enabled'] then
    RegisterCommand("airdrop", function(source, args, rawCommand)
        createNewAirdrop({type = "command", src = source, arg = args})
    end)
end


-- EVENT
-- IF SET TO TRUE IN CONFIG "pc_airdrop:server:createNewAirdrop" SERVER EVENT WILL BE CREATED
-- YOU CAN CREATE YOUR OWN WAY OF CALLING AN AIRDROP USING THIS EVENT
if Config.AirdropSpawnMethod['event_enabled'] then
    RegisterNetEvent("pc_airdrop:server:createNewAirdrop", function(args)
        createNewAirdrop({type = "event", src = source, arg = args})
    end)
end
 

-- [3. Discord logs]
if Config.DiscordLogs then 

    WebhookURL = "" -- INSERT YOU DISCORD WEBHOOK HERE

    function DiscordLog(title,desc,color)
        PerformHttpRequest(WebhookURL, function(err, text, headers) end, 'POST', json.encode({
            username = "Airdrop - Logs", 
            embeds = {{
                ["color"] = color, 
                ["title"] = title,
                ["description"] = desc,
                ["footer"] = {
                    ["text"] = "PoisonCode Airdrop  •  "..os.date("%x %X %p")
                },
            }} 
        }), { 
            ['Content-Type'] = 'application/json' 
        })
    end
end

If you encounter any problems during configuration, you can create a support ticket on our discord.

PreviousInstallation & dependenciesNextTutorials

Last updated 2 months ago

Was this helpful?

📦
⚙️