ngd-propstorage(QB/ESX)

ngd-propstorage is an efficient prop based stash script that allows server owners to place stash props in front of people's houses or businesses.

Installation Instructions:

  • Add the ngd-propstorage folder into your server's resource folder.

  • Open server.cfg and add ensure ngd-propstorage

  • Open config.lua and customize to your needs.

Dependencies:

  • QBCore/ESX

  • Target System

  • QB/LJ/OX - Inventory or ESX OX Inventory

  • Polyzone

Features:

  • Custom stash props.

  • Optional animations with custom positions.

  • Global spawn or polyzone spawn

  • 0.00 resmon

  • Police can open locked stashes

Utilities Config Variables:

  • Config.debug = true/false (This turns on debug mode that adds various prints to debug prop spawning despawning. This also adds the command /spawnstashboxes so you can spawn them in when Config.GlobalSpawn = true.

  • Config.GlobalSpawn = true/false (This makes it so mailboxes are all spawned in on player load. This adds a slight load on client. If it is set to false, it uses polyzones to spawn the props in.)

Config.Stashes Variables (All versions):

  • house = 'Whatever' - This is the registered name of the stash. It needs to be unique, and is usually named to identify the location.

  • model = 'PropName' - This is the name of the prop spawned in. See below for examples of included props.

  • coords = vector4() - This is the location of the spawned in prop

  • spawnzone = 25 - This is the polyzone radius of the spawned in prop if using Config.GlobalSpawn = false.

  • pin = 1234 - This is the configurable pincode set if you want to lock a stash. If you don't want a stash locked delete the entire pin = 1234 line.

  • position = vector4() - This is the position that the player gets teleported to when using animations

  • animDict = 'animationdictionary' - This is the animation dictionary for the animation used

  • anim = 'animation' - Animation of the dictionary above.

  • ProgBarText = 'Progress Bar Text' - Text shown on progress bar if enabled.

  • ProgBarTime = 3700 - Time in MS that the progressbar is shown.

Config.Stashes Variables (QB-Core)

  • UseAnim = true/false - Used to enable or disable animations and qbcore progressbar.

Config.Stashes Variables (ESX)

  • AnimType = 'none/animations/progressbar' - This support three different options. none = No animations or progressbar. animations = Uses animations (no dependencies). progressbar = Uses animations and progressbar (esx_progressbar) is a dependency.

Click to view included props

Model: letter_box_1

Model: box_new_2

Model: letter_box_6

Model: letter_box_7

Model: box_new_1

Click to view QB Config
Config = {}
local QBCore = exports['qb-core']:GetCoreObject()

--Utilities
Config.debug = false        --Leave off unless needed. (see docs for usage)
Config.GlobalSpawn = true   --This will spawn ALL mailbox props on player load instead of using PolyZones.  (Adds more client load by a small amount)
Config.Target = 'qb-target' --Target used
Config.Inventory = 'ox'     --ox, qb or custom
Config.Notifications = 'qb' --qb, okok or custom (If custom, change export below)
Config.PoliceJob = 'police' --Police job allowed to force open stashes (Leave blank if you don't want police to be able to open stashes)
Config.Stashes = {
    [1] = {
        house = 'House1',                                --Stash name
        model = "safe_lb",                               --Prop model (see docs for included props)
        coords = vector4(247.98, -797.91, 30.32, 69),    --Location of spawned prop
        spawnzone = 25,                                  --Polyzone range if Config.GlobalSpawn = false
        --Below is for animations--
        UseAnim = true,                                  --Progress bar and animations
        position = vector4(246.97, -797.60, 30.34, 254), --Position to teleport player to infront of box for prop animation
        animDict = "amb@medic@standing@kneel@enter",     --Animation dictionary
        anim = "enter",                                  --Animation
        ProgBarText = "Opening Safe",                    --Progressbar text
        ProgBarTime = 3700,                              --Progressbar time / time until stash opens
        --End animations--
        --OX Inventory:--
        InvSlots = 20,     --OX Inventory Slots
        InvWeight = 20000, --OX Inventory Weight
        --END OX Inventory--
        pin = 1234,        --PIN code.  This is optional.  Delete it if you don't want to use a prop.
    },
    [2] = {
        house = 'House2',
        model = "letter_box_2",
        coords = vector4(248.84, -796.78, 31.33, 67),
        spawnzone = 5,
        UseAnim = true,
        position = vector4(247.98, -796.45, 30.34, 256),
        animDict = "amb@prop_human_parking_meter@male@idle_a",
        anim = "idle_b",
        ProgBarText = "Rummaging through mailbox",
        ProgBarTime = 3700,
        InvSlots = 20,
        InvWeight = 20000,
    },
    [3] = {
        house = 'House3',
        model = "box_new_3",
        coords = vector4(248.85, -795.64, 30.35, 69),
        spawnzone = 5,
        UseAnim = false,
        position = vector4(-1663.89, -3185.82, 13.96, 325),
        animDict = "amb@prop_human_parking_meter@male@idle_a",
        anim = "idle_b",
        ProgBarText = "Checking Mailbox",
        ProgBarTime = 3700,
        InvSlots = 20,
        InvWeight = 20000,
    },
}

--This is for the notification system.  It comes preconfigured for OKOKNotify or QB Notify.  If Config.Notifications = custom, you can set your custom export below.
if Config.Notifications == 'qb' then
    function Notify(title, message, time, type) --qb notify
        if type == "primary" then
            QBCore.Functions.Notify(message, "primary", time)
        end
        if type == "success" then
            QBCore.Functions.Notify(message, "success", time)
        end
        if type == "error" then
            QBCore.Functions.Notify(message, "error", time)
        end
    end
elseif Config.Notifications == 'custom' then
    function Notify(title, message, time, type)
        exports['sd-notify']:Notify(title, message, time, type) --modify for custom notify
    end
elseif Config.Notifications == 'okok' then
    function Notify(Title, Message, Time, type)
        exports['okokNotify']:Alert(Title, Message, Time, type) --okok notify
    end
end

--Translate Below
Config.Lang = {
    Icon = "fa-regular fa-envelope",          --Icon to check mail
    PoliceIcon = "fa-solid fa-lock-open",     --Icon shown to police
    TargetText = "Check Stash",               --Text shown when targeting mailbox.
    PoliceTargetText = "Police: Force Open",  --Text show to police on target
    OpenBoxPolice = "Forcing open stash",     --Text shown when police are opening stash
    ErrorTitle = "Pin Code",                  --Title on wrong pin notify
    ErrorMessage = "Wrong PIN code entered.", --Message on wrong pin notify.
}
Click to view ESX Config
Config = {}

--Utilities
Config.debug = false                   --leave off unless needed.
Config.Target = 'qtarget'              --Target used
Config.Icon = 'fa-regular fa-envelope' --Font Awesome icon for target
Config.GlobalSpawn = false             --This will spawn ALL mailbox props on player load instead of using PolyZones.  (Adds more client load by a small amount)
Config.PoliceJob = 'police'            --Police job allowed to force open stashes (Leave blank if you don't want police to be able to open stashes)
Config.Notifications = "esx"           --esx, okok, custom

--This is for the notification system.  It comes preconfigured for OKOKNotify or ESX Notify.  If Config.Notifications = custom, you can set your custom export below.
if Config.Notifications == 'esx' then
    function Notify(title, message, time, type)
        exports["esx_notify"]:Notify(type, time, message)
    end
elseif Config.Notifications == 'custom' then
    function Notify(title, message, time, type)
        exports['sd-notify']:Notify(title, message, time, type) --modify for custom notify
    end
elseif Config.Notifications == 'okok' then
    function Notify(Title, Message, Time, type)
        exports['okokNotify']:Alert(Title, Message, Time, type) --okok notify
    end
end


Config.Stashes = {
    [1] = {
        house = 'House1',                                --Stash Name
        model = "letter_box_6",                          --Prop Name(See docs for examples)
        coords = vector4(247.98, -797.91, 30.32, 69),    --Coords for props
        InvSlots = 20,                                   --Stash slots
        InvWeight = 20000,                               --Stash weight
        spawnzone = 5,                                   --Radius for spawnzone (Only matters if Config.GlobalSpawn = false)
        --Below is for animations--
        AnimType = 'none',                               --Options are: ("animations", "progressbar", "none") - animations = use animations; progressbar = use esx_progressbar; none = just open stash
        position = vector4(246.97, -797.60, 30.34, 254), --Position of player for animations
        animDict = "amb@medic@standing@kneel@enter",     --Animation dictionary
        anim = "enter",                                  --Animation
        ProgBarText = "Opening Safe",                    --Text on progress bar
        AnimTime = 3700,                                 --Animation time
        --End animations--
        pin = 1234,                                      --Pincode to open stash.  Delete entire line if you don't want a pincode.
    },
}



Config.Lang = {
    Icon = "fa-regular fa-envelope",          --Icon to check mail
    PoliceIcon = "fa-solid fa-lock-open",     --Icon shown to police
    TargetText = "Check Stash",               --Text shown when targeting mailbox.
    PoliceTargetText = "Police: Force Open",  --Text show to police on target
    ErrorTitle = "Pin Code",                  --Title on wrong pin notify
    ErrorMessage = "Wrong PIN code entered.", --Message on wrong pin notify.
}

--Inventory:
Config.OpenStash = function(stash)
    exports.ox_inventory:openInventory('stash', { id = stash })
end

Script can be restarted live without any issues!

If you have any problems - Join our Discord for support!

Last updated