> For the complete documentation index, see [llms.txt](https://unknown-development.gitbook.io/unknown-development/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unknown-development.gitbook.io/unknown-development/scripts/unknown_dumpsters.md).

# unknown\_dumpsters

*<mark style="color:$info;">Looking for a realistic and engaging civilian activity for your FiveM server? You’re in the right place!</mark>*\
*<mark style="color:$info;">Our Dumpster Searching system brings a modern, immersive scavenging experience that fits perfectly into street RP and server economy.</mark>*

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>Buy yours now</td><td><a href="https://mjwvf0ib8.fragmentor.site/resources/cargoheist">https://mjwvf0ib8.fragmentor.site/resources/cargoheist</a></td></tr><tr><td>Checkout all our scripts</td><td><a href="https://mjwvf0ib8.fragmentor.site/resources">https://mjwvf0ib8.fragmentor.site/resources</a></td></tr></tbody></table>

## Showcase

YT video here

## Config

{% tabs %}
{% tab title="config.lua" %}

```lua
Config = {}

-- Framework
Config.Framework = 'qb' -- 'esx', 'qb', 'qbox'

-- Inventory
Config.Inventory = 'ox_inventory' -- 'ox_inventory', 'qb-inventory', or 'esx' (ESX native inventory)

-- Target
Config.Target = 'ox_target' -- 'ox_target', 'qb-target'

-- Minigame (OPTIONAL, only if Config.UseMinigames = true)
Config.Minigame = 'unknown_skillBar' -- 'bl_ui', 'devhub_hackingMinigames', 'devhub_minigames', 'ox_lib', 'ps-ui', 'unknown_skillBar' (DON'T FORGET TO CONFIGURE MINIGAME SETTINGS IN SHARED/MINIGAMES.LUA)

-- Progress bar
Config.ProgressBar = 'ox_lib_circle' -- 'ox_lib_bar', 'ox_lib_circle', 'qb-core', 'unknown_ui' (UNRELEASED...), 'progressBars'

-- Notification
Config.Notify = 'ox_lib' -- 'ox_lib', 'qb-core', 'esx', 'unknown_ui' (UNRELEASED...), 'okokNotify'

-- TextUI
Config.TextUI = 'ox_lib' -- 'ox_lib', 'qb-core', 'esx', 'cd_drawtextui'

-- Locale
Config.Locale = 'en' -- 'en', 'lt'

-- Dispatch
Config.Dispatch = 'cd_dispatch' -- 'ps-dispatch', 'cd_dispatch', 'tk_dispatch', 'rcore_dispatch', or 'none'


-- TRASH SETTINGS
Config.TrashCooldown = 10 -- Time (in minutes) before a trash can can be searched again
-- Config.ClearDumpstersOnRestart = false -- If true, all dumpster data will be cleared on server restart (SOON...)
Config.HideInDumpsters = true -- If true, players can hide in dumpsters
Config.MaxItemsPerSearch = 3 -- Maximum number of different items a player can find in one search

-- JOB CHECKER SETTINGS
Config.AllowJobsToCheckHider = true -- If true, allowed jobs can check if someone is hiding in a dumpster
Config.AllowedJobsToCheckHider = {'police', 'burgershot'} -- Jobs that can check if someone is hiding in a dumpster

-- FAIL SETTINGS
Config.Fails = {
    EnableFail = true, -- Enable fail events
    EnableRatEvent = true, -- Enable rat events
    EnableNeedleEvent = true, -- Enable dirty needle events
    FailChancePercent = 25, -- Fail chance %
    DirtyNeedlesChancePercent = 30, -- Dirty needles chance %
    DirtyNeedlesEffectTime = 90, -- Dirty Needle effect duration (seconds)
    DirtyNeedlesHealthLoss = 20, -- Health damage that will be applied when the player is stabbed with a needle
    RatChancePercent = 40, -- Rat bite chance %
    RatHealthLoss = 5, -- Health damage that will be applied when a rat bites a player
    HealthLoss = 0, -- Health damage that will be applied when the player finds nothing in the trash (Recommended to keep it at 0)
}


-- REWARDS
Config.BeachItems = {
    -- Luxury items (low chance)
    {item = 'diamond_ring', min = 1, max = 1, chance = 0.1},
    {item = 'gold_chain', min = 1, max = 2, chance = 0.12},
    {item = 'goldbar', min = 1, max = 3, chance = 0.12},
    {item = 'diamond', min = 1, max = 3, chance = 0.15},
    {item = 'trojan_usb', min = 1, max = 1, chance = 0.04},
    
    -- Tools and beach items (medium chance)
    {item = 'lockpick', min = 1, max = 2, chance = 0.25},
    {item = 'ziplock_bag', min = 1, max = 4, chance = 0.4},
    {item = 'lighter', min = 1, max = 2, chance = 0.45},
    {item = 'sunscreen', min = 1, max = 3, chance = 0.35},
    {item = 'snorkel_gear', min = 1, max = 1, chance = 0.2},
    
    -- Food and drinks (high chance)
    {item = 'water_bottle', min = 1, max = 4, chance = 0.7},
    {item = 'cola', min = 1, max = 2, chance = 0.65},
    {item = 'beer', min = 1, max = 2, chance = 0.55},
    {item = 'juice', min = 1, max = 2, chance = 0.6},
    {item = 'ice_cream', min = 1, max = 2, chance = 0.5},
    {item = 'sandwich', min = 1, max = 2, chance = 0.55},
    {item = 'pizza_slice', min = 1, max = 3, chance = 0.6},
    {item = 'apple', min = 1, max = 3, chance = 0.7},
    {item = 'banana', min = 1, max = 3, chance = 0.7},
    {item = 'watermelon_slice', min = 1, max = 2, chance = 0.5},
    
    -- Money (high chance)
    {item = 'cash', min = 50, max = 300, chance = 0.85},
}

Config.DumpsterItems = {
    -- Luxury items (low chance)
    {item = 'rolex_watch', min = 1, max = 1, chance = 0.08},
    {item = 'diamond_ring', min = 1, max = 1, chance = 0.1},
    {item = 'gold_chain', min = 1, max = 2, chance = 0.12},
    {item = 'goldbar', min = 1, max = 5, chance = 0.15},
    {item = 'diamond', min = 2, max = 8, chance = 0.18},
    {item = 'trojan_usb', min = 1, max = 1, chance = 0.05},
    
    -- Tools and items (medium chance)
    {item = 'advancedlockpick', min = 1, max = 3, chance = 0.25},
    {item = 'lockpick', min = 1, max = 2, chance = 0.3},
    {item = 'ziplock_bag', min = 1, max = 5, chance = 0.35},
    {item = 'lighter', min = 1, max = 2, chance = 0.4},
    {item = 'keypads', min = 1, max = 1, chance = 0.2},
    {item = 'thermite', min = 1, max = 1, chance = 0.15},
    
    -- Food and drinks (high chance)
    {item = 'water_bottle', min = 1, max = 3, chance = 0.6},
    {item = 'cola', min = 1, max = 2, chance = 0.55},
    {item = 'beer', min = 1, max = 2, chance = 0.45},
    {item = 'vodka', min = 1, max = 1, chance = 0.35},
    {item = 'whiskey', min = 1, max = 1, chance = 0.3},
    {item = 'sandwich', min = 1, max = 2, chance = 0.5},
    {item = 'pizza_slice', min = 2, max = 4, chance = 0.55},
    {item = 'apple', min = 1, max = 3, chance = 0.65},
    {item = 'banana', min = 1, max = 3, chance = 0.65},
    
    -- Money (high chance)
    {item = 'cash', min = 100, max = 500, chance = 0.8},
}

Config.GarbageItems = {
    -- Luxury items (very low chance)
    {item = 'goldbar', min = 1, max = 2, chance = 0.08},
    {item = 'diamond', min = 1, max = 2, chance = 0.1},
    {item = 'trojan_usb', min = 1, max = 1, chance = 0.03},
    
    -- Tools and items (medium-low chance)
    {item = 'lockpick', min = 1, max = 2, chance = 0.2},
    {item = 'advancedlockpick', min = 1, max = 1, chance = 0.12},
    {item = 'ziplock_bag', min = 1, max = 3, chance = 0.35},
    {item = 'lighter', min = 1, max = 2, chance = 0.3},
    {item = 'lighter_cigarette', min = 1, max = 3, chance = 0.25},
    
    -- Food and drinks (high chance)
    {item = 'water_bottle', min = 1, max = 2, chance = 0.5},
    {item = 'cola', min = 1, max = 1, chance = 0.4},
    {item = 'beer', min = 1, max = 1, chance = 0.25},
    {item = 'burgershot_burger', min = 1, max = 1, chance = 0.35},
    {item = 'pizza_slice', min = 1, max = 2, chance = 0.4},
    {item = 'fries', min = 1, max = 2, chance = 0.45},
    {item = 'apple', min = 1, max = 2, chance = 0.55},
    {item = 'banana', min = 1, max = 2, chance = 0.55},
    {item = 'sandwich', min = 1, max = 1, chance = 0.35},
    {item = 'donut', min = 1, max = 2, chance = 0.4},
    
    -- Money (medium chance)
    {item = 'cash', min = 10, max = 100, chance = 0.6},
}

Config.OtherSeachablesItems = {
    -- Luxury items (low chance)
    {item = 'diamond', min = 1, max = 3, chance = 0.15},
    {item = 'goldbar', min = 1, max = 2, chance = 0.12},
    {item = 'trojan_usb', min = 1, max = 1, chance = 0.06},
    {item = 'stolen_necklace', min = 1, max = 1, chance = 0.1},
    
    -- Tools and items (medium chance)
    {item = 'lockpick', min = 1, max = 3, chance = 0.3},
    {item = 'advancedlockpick', min = 1, max = 2, chance = 0.2},
    {item = 'ziplock_bag', min = 1, max = 4, chance = 0.4},
    {item = 'lighter', min = 1, max = 2, chance = 0.35},
    {item = 'duct_tape', min = 1, max = 2, chance = 0.25},
    {item = 'rope', min = 1, max = 1, chance = 0.2},
    {item = 'empty_evidence_bag', min = 1, max = 2, chance = 0.3},
    
    -- Food and drinks (high chance)
    {item = 'water_bottle', min = 1, max = 3, chance = 0.65},
    {item = 'cola', min = 1, max = 2, chance = 0.6},
    {item = 'beer', min = 1, max = 2, chance = 0.5},
    {item = 'vodka', min = 1, max = 1, chance = 0.3},
    {item = 'sandwich', min = 1, max = 2, chance = 0.55},
    {item = 'pizza_slice', min = 1, max = 3, chance = 0.6},
    {item = 'apple', min = 1, max = 3, chance = 0.65},
    {item = 'banana', min = 1, max = 3, chance = 0.65},
    {item = 'protein_bar', min = 1, max = 2, chance = 0.4},
    {item = 'energy_drink', min = 1, max = 1, chance = 0.35},
    
    -- Money (high chance)
    {item = 'cash', min = 50, max = 200, chance = 0.75},
}

-- EXCLUSIVE ITEM ZONES

Config.ExclusiveItemZones = {
    {name = "Burgershot",  -- Unique zone identifier
    coords = vector3(-1179.7351, -904.6566, 13.5210),
    radius = 50.0,
    chance = 75, -- Item spawn chance %
    restrictedZone = true, -- Alert police on search
    snitchChance = 100, -- Snitch call chance %
    jobsToInform = {'police', 'burgershot'}, -- Jobs to alert
    items = {

           {name = "bs_burger", metadata = { quality = 10 }, min = 1, max = 1},
           {name = "bs_fries", metadata = { quality = 10 }, min = 1, max = 1},
           {name = "bs_drink", metadata = { quality = 10 }, min = 1, max = 1},
            {name = "lettuce", metadata = { quality = 10 }, min = 1, max = 1},
            {name = "tomato",  metadata = { quality = 10 }, min = 1, max = 1},
            {name = "potato", metadata = {}, min = 1, max = 1},
            {name = "empty_weed_bag", metadata = {}, min = 1, max = 1},
            -- Add more items
        },
    },

    {name = "Industrial",  -- Unique zone identifier
    coords = vector3(722.1307, -729.4524, 26.1094),
    radius = 100.0,
    chance = 30, -- Item spawn chance %
    restrictedZone = false, -- Alert police on search
    snitchChance = false, -- Snitch call chance %
    jobsToInform = {}, -- Jobs to alert
    items = {
           {name = "steel", metadata = {}, min = 1, max = 7},
           {name = "plastic", metadata = {}, min = 1, max = 7},
           {name = "aluminum", metadata = {}, min = 1, max = 7},
           {name = "copper", metadata = {}, min = 1, max = 7},
           {name = "iron", metadata = {}, min = 1, max = 7},
           {name = "steel", metadata = {}, min = 1, max = 7},
           {name = "glass", metadata = {}, min = 1, max = 7},
           {name = "rubber", metadata = {}, min = 1, max = 7},
           {name = "wood", metadata = {}, min = 1, max = 7},
            -- Add more items
        },
    },


    {name = "Hood",  -- Unique zone identifier
    coords = vector3(107.2442, -1941.9656, 20.8037),
    radius = 50.0,
    chance = 10, -- Item spawn chance %
    restrictedZone = false, -- Alert police on search
    snitchChance = false, -- Snitch call chance %
    jobsToInform = {'police'}, -- Jobs to alert
    items = {
           {name = "lockpick", metadata = {}, min = 1, max = 1},
           {name = "empty_weed_bag", metadata = {}, min = 1, max = 1},
           {name = "coke_baggy", metadata = {}, min = 1, max = 1},
           {name = "weapon_knife", metadata = {}, min = 1, max = 1},
           {name = "pistol_ammo", metadata = {}, min = 1, max = 1},
           {name = "glass", metadata = {}, min = 1, max = 1},
           {name = "weed_joint", metadata = {}, min = 1, max = 1},
           {name = "phone", metadata = {}, min = 1, max = 1},
            -- Add more items
        },
    },


    {name = "Homeless",  -- Unique zone identifier
    coords = vector3(169.5135, -1224.2314, 29.3662),
    radius = 10.0,
    chance = 5, -- Item spawn chance %
    restrictedZone = false, -- Alert police on search
    snitchChance = false, -- Snitch call chance %
    jobsToInform = {}, -- Jobs to alert
    items = {
           {name = "buzz_saw", metadata = {}, min = 1, max = 1},
           {name = "impact_driver", metadata = {}, min = 1, max = 1},
           {name = "weapon_smg", metadata = {}, min = 1, max = 1},
           {name = "smg_ammo", metadata = {}, min = 1, max = 1},
           {name = "meth_1oz", metadata = {}, min = 1, max = 1},
           {name = "coke_1oz", metadata = {}, min = 1, max = 1},
            -- Add more items
        },
    },

    -- ADD AS MANY ZONES AS YOU LIKE

}


-- PROPS
Config.Props = {
    beach = {
        "prop_bin_beach_01a",
        "prop_bin_beach_01d",
        "prop_bin_delpiero",
        "prop_bin_delpiero_b",
    },
    
    dumpsters = {
        "prop_cs_dumpster_01a",
        "p_dumpster_t",
        "prop_dumpster_01a",
        "prop_dumpster_02a",
        "prop_dumpster_02b",
        "prop_dumpster_3a",
        "prop_dumpster_4a",
        "prop_dumpster_4b",
    },
    
    garbageCans = {
        "prop_bin_01a",
        "prop_bin_02a",
        "prop_bin_03a",
        "prop_bin_04a",
        "prop_bin_05a",
        "prop_bin_06a",
        "prop_bin_07a",
        "prop_bin_07b",
        "prop_bin_07c",
        "prop_bin_07d",
        "prop_bin_08a",
        "prop_bin_08open",
        "prop_bin_09a",
        "prop_bin_10a",
        "prop_bin_10b",
        "prop_bin_11a",
        "prop_bin_11b",
        "prop_bin_12a",
        "zprop_bin_01a_old",
    },
    
    otherSearchables = {
        "prop_skid_tent_01",
        "prop_skid_tent_01b",
        "prop_skid_tent_03",
    },
}


-- ANIMATIONS
Config.Animations = {
    ratFail = {'misscarsteal2_bin', 'trev_sink_exit'},
    needle = {'misscarsteal2_bin', 'trev_sink_exit'},
    genericFail = {'move_p_m_two_idles@generic', 'fidget_sniff_fingers'},
    
    beach = {
        {'anim@gangops@van@drive_grab@', 'grab_drive'},
        {'amb@code_human_in_car_mp_actions@arse_pick@std@ps@base', 'enter'},
        {'rcmepsilonism8', 'bag_handler_grab_walk_left'},
        {'anim@scripted@player@freemode@gen_grab@heeled@', 'low_multi'},
        {'anim@move_m@trash', 'pickup'},
        {'anim@heists@prison_heiststation@heels', 'pickup_bus_schedule'},
    },
    
    dumpster = {
        {'weapons@first_person@aim_idle@generic@melee@knife@shared@core', 'fidget_low_loop'},
        {'anim@gangops@facility@servers@bodysearch@', 'player_search'},
        {'anim@gangops@morgue@table@', 'player_search'},
        {'missexile3', 'ex03_dingy_search_case_a_michael'},
        {'anim@amb@inspect@crouch@male_a@base', 'base'},
    },
    
    garbage = {
        {'switch@trevor@garbage_food', 'loop_trevor'},
        {'amb@prop_human_bum_bin@base', 'base'},
        {'amb@prop_human_bum_bin@idle_b', 'idle_d'},
        {'anim@heists@money_grab@briefcase', 'enter'},
    },
    
    hideInDumpster = {
        {'anim@veh@apc@ds@enter_exit_front', 'climb_up'},
    },
    
    kickedOutDumpster = {
        {'anim@veh@truck@squaddie@rps@enter_exit', 'jump_out'},
    },
}

Config.UseMinigames = true

-- Debug
Config.Debug = false
```

{% endtab %}

{% tab title="shared/framework.lua" %}

```lua
Framework = {}

function Framework:GetCurrent()
    if Config.Framework == 'esx' and GetResourceState('es_extended') == 'started' then
        return 'esx'
    elseif Config.Framework == 'qb' and GetResourceState('qb-core') == 'started' then
        return 'qb'
    elseif Config.Framework == 'qbox' and GetResourceState('qbx_core') == 'started' then
        return 'qbox'
    end
    return nil
end

function Framework:GetPlayerData(source)
    local framework = self:GetCurrent()
    
    if framework == 'esx' then
        local ESX = exports['es_extended']:getSharedObject()
        local xPlayer = ESX.GetPlayerFromId(source)
        return {
            source = source,
            identifier = xPlayer.identifier,
            inventory = xPlayer.inventory
        }
    elseif framework == 'qb' then
        local QBCore = exports['qb-core']:GetCoreObject()
        local Player = QBCore.Functions.GetPlayer(source)
        return {
            source = source,
            identifier = Player.PlayerData.citizenid,
            inventory = Player.PlayerData.items
        }
    elseif framework == 'qbox' then
        local Player = exports['qbx_core']:GetPlayer(source)
        return {
            source = source,
            identifier = Player.PlayerData.citizenid,
            inventory = Player.PlayerData.items
        }
    end
    return nil
end

function Framework:HasItem(source, itemName, amount)
    amount = amount or 1
    
    if Config.Inventory == 'ox_inventory' then
        local count = exports.ox_inventory:Search(source, 'count', itemName)
        return count >= amount, count
    elseif Config.Inventory == 'qb-inventory' then
        return exports['qb-inventory']:HasItem(source, itemName, amount)
    elseif Config.Inventory == 'esx' then
        local ESX = exports['es_extended']:getSharedObject()
        local xPlayer = ESX.GetPlayerFromId(source)
        local item = xPlayer.getInventoryItem(itemName)
        if item and item.count >= amount then
            return true, item.count
        end
    end
    
    return false, 0
end

function Framework:RemoveItem(source, itemName, amount)
    if Config.Inventory == 'ox_inventory' then
        return exports.ox_inventory:RemoveItem(source, itemName, amount)
    elseif Config.Inventory == 'qb-inventory' then
        return exports['qb-inventory']:RemoveItem(source, itemName, amount, false, false, 'unknown_recycle:RemoveSortedItem')
    elseif Config.Inventory == 'esx' then
        local ESX = exports['es_extended']:getSharedObject()
        local xPlayer = ESX.GetPlayerFromId(source)
        return xPlayer.removeInventoryItem(itemName, amount)
    end
end

function Framework:AddItem(source, itemName, amount)
    if Config.Inventory == 'ox_inventory' then
        return exports.ox_inventory:AddItem(source, itemName, amount)
    elseif Config.Inventory == 'qb-inventory' then
        return exports['qb-inventory']:AddItem(source, itemName, amount, false, false, 'unknown_recycle:GiveSortedItem')
    elseif Config.Inventory == 'esx' then
        local ESX = exports['es_extended']:getSharedObject()
        local xPlayer = ESX.GetPlayerFromId(source)
        return xPlayer.addInventoryItem(itemName, amount)
    end

end

function Framework:CanCarryItem(source, itemName, amount)
    if Config.Inventory == 'ox_inventory' then
        return exports.ox_inventory:CanCarryItem(source, itemName, amount)
    elseif Config.Inventory == 'qb-inventory' then
        return exports['qb-inventory']:CanAddItem(source, itemName, amount)
    elseif Config.Inventory == 'esx' then
        local ESX = exports['es_extended']:getSharedObject()
        local xPlayer = ESX.GetPlayerFromId(source)
        return xPlayer.CanCarryItem(itemName, amount)
    end
    return true
end

function Framework:GetPlayerJob(source)
    local framework = self:GetCurrent()
    
    if framework == 'esx' then
        local ESX = exports['es_extended']:getSharedObject()
        local xPlayer = ESX.GetPlayerFromId(source)
        if xPlayer then
            return xPlayer.job.name
        end
    elseif framework == 'qb' then
        local QBCore = exports['qb-core']:GetCoreObject()
        local Player = QBCore.Functions.GetPlayer(source)
        if Player then
            return Player.PlayerData.job.name
        end
    elseif framework == 'qbox' then
        local Player = exports['qbx_core']:GetPlayer(source)
        if Player then
            return Player.PlayerData.job.name
        end
    end
    return nil
end

return Framework
```

{% endtab %}

{% tab title="shared/minigames.lua" %}

```lua
function StartMinigame(callback)
    if Config.Minigame == 'ox_lib' and GetResourceState('ox_lib') == 'started' then
        local success = lib.skillCheck({'easy', 'easy', 'easy'}, {'w', 'a', 's', 'd'})
        if callback then callback(success) end
        return success
        
    elseif Config.Minigame == 'bl_ui' and GetResourceState('bl_ui') == 'started' then
        local success = exports['bl_ui']:RapidLines(2, 70, 3)
        if callback then callback(success) end
        return success
        
    elseif Config.Minigame == 'devhub_hackingMinigames' and GetResourceState('devhub_hackingMinigames') == 'started' then
        local success = exports['devhub_hackingMinigames']:startMinigame('morse', 60)
        if callback then callback(success) end
        return success

    elseif Config.Minigame == 'devhub_minigames' and GetResourceState('devhub_minigames') == 'started' then
        local success = exports['devhub_minigames']:startMinigame("minigame_2", "medium")
        if callback then callback(success) end
        return success
    
    elseif Config.Minigame == 'ps-ui' and GetResourceState('ps-ui') == 'started' then
        local success = exports['ps-ui']:Thermite(10, 5, 3) -- Time, Gridsize, IncorrectBlocks
        if callback then callback(success) end
        return success

    elseif Config.Minigame == 'unknown_skillBar' and GetResourceState('unknown_skillBar') == 'started' then
        local success = exports['unknown_skillBar']:skillBar(50, 3) -- Difficulty, Iterations
        if callback then callback(success) end
        return success
    end

end
```

{% endtab %}

{% tab title="shared/notify.lua" %}

```lua
function Notify(source, message, type)
    if not source or source == 0 then
        -- Client-side
        if Config.Notify == 'ox_lib' and GetResourceState('ox_lib') == 'started' then
            lib.notify({
                title = 'Dumpsters',
                description = message,
                type = type or 'inform'
            })
        elseif Config.Notify == 'qb-core' and GetResourceState('qb-core') == 'started' then
            local QBCore = exports['qb-core']:GetCoreObject()
            if type == 'error' then
                QBCore.Functions.Notify(message, 'error')
            elseif type == 'success' then
                QBCore.Functions.Notify(message, 'success')
            else
                QBCore.Functions.Notify(message, 'primary')
            end
        elseif Config.Notify == 'esx' and GetResourceState('es_extended') == 'started' then
            local ESX = exports['es_extended']:getSharedObject()
            ESX.ShowNotification(message)
        elseif Config.Notify == 'unknown_ui' and GetResourceState('unknown_ui') == 'started' then
            exports['unknown_ui']:showNotify(type, 'Dumpsters', message, 5000, "#4CAF50", "fa-solid fa-recycle")
        elseif Config.Notify == 'okokNotify' and GetResourceState('okokNotify') == 'started' then
            exports['okokNotify']:Alert('Dumpsters', message, 5000, type or 'info', true)
        else
            -- Fallback GTA notification
            BeginTextCommandThefeedPost('STRING')
            AddTextComponentSubstringPlayerName(message)
            EndTextCommandThefeedPostTicker(true, true)
        end
    else
        -- Server-side
        if Config.Notify == 'ox_lib' then
            TriggerClientEvent('ox_lib:notify', source, {
                description = message,
                type = type or 'inform'
            })
        elseif Config.Notify == 'qb-core' then
            TriggerClientEvent('QBCore:Notify', source, message, type or 'primary')
        elseif Config.Notify == 'esx' then
            TriggerClientEvent('esx:showNotification', source, message)
        elseif Config.Notify == 'unknown_ui' then
            TriggerClientEvent('unknown_ui:notify:show', source, type, 'Dumpsters', message, 5000, "#4CAF50", "fa-solid fa-recycle")
        elseif Config.Notify == 'okokNotify' then
            TriggerClientEvent('okokNotify:Alert', source, 'Dumpsters', message, 5000, type or 'info', true)
        end
    end
end
```

{% endtab %}

{% tab title="shared/progressbar.lua" %}

```lua
function ProgressBar(source, label, duration, options)
    options = options or {}
        -- Client-side
        if Config.ProgressBar == 'ox_lib_bar' and GetResourceState('ox_lib') == 'started' then
            if lib.progressBar({
                duration = duration,
                label = label,
                useWhileDead = options.useWhileDead or false,
                canCancel = options.canCancel or true,
                disable = options.disable or {
                    car = true,
                    move = true,
                    combat = true
                },
                anim = options.anim or {},
                onCancel = options.onCancel,
                onFinish = options.onFinish
            }) then
                return true
            else
                if options.onCancel then options.onCancel() end
                return false
            end
        elseif Config.ProgressBar == 'ox_lib_circle' and GetResourceState('ox_lib') == 'started' then
            if lib.progressCircle({
                duration = duration,
                position = 'bottom',
                label = label,
                useWhileDead = options.useWhileDead or false,
                canCancel = options.canCancel or true,
                disable = options.disable or {
                    car = true,
                    move = true,
                    combat = true
                },
                anim = options.anim or {},
                onCancel = options.onCancel,
                onFinish = options.onFinish
            }) then
                return true
            else
                if options.onCancel then options.onCancel() end
                return false
            end
            
        elseif Config.ProgressBar == 'qb-core' and GetResourceState('qb-core') == 'started' then
            local QBCore = exports['qb-core']:GetCoreObject()
            QBCore.Functions.Progressbar('dumpster_progress', label, duration, false, true, {
                disableMovement = true,
                disableCarMovement = true,
                disableMouse = false,
                disableCombat = true,
            }, options.anim or {}, {}, {}, function()
                if options.onFinish then options.onFinish() end
            end, function()
                if options.onCancel then options.onCancel() end
            end)
            return true

        elseif Config.ProgressBar == 'unknown_ui' and GetResourceState('unknown_ui') == 'started' then
            exports['unknown_ui']:showProgress({
                icon = "fa-solid fa-spinner fa-spin",
                duration = duration,
                label = label,
                canCancel = true,
                disable = {
                    move = true,
                    attack = true
                },
                anim = options.anim or {},
            })
            Wait(duration)
            return true
            
        elseif Config.ProgressBar == 'progressBars' and GetResourceState('progressBars') == 'started' then
            exports['progressBars']:startUI(duration, label)
            Wait(duration)
            return true
            
        else
            -- Fallback progress bar
            local startTime = GetGameTimer()
            while GetGameTimer() - startTime < duration do
                Wait(0)
                local elapsed = GetGameTimer() - startTime
                local progress = elapsed / duration
                
                SetTextFont(4)
                SetTextScale(0.5, 0.5)
                SetTextColour(255, 255, 255, 255)
                SetTextOutline()
                BeginTextCommandDisplayText("STRING")
                AddTextComponentSubstringPlayerName(label)
                EndTextCommandDisplayText(0.5, 0.9)
                
                DrawRect(0.5, 0.95, 0.2, 0.03, 0, 0, 0, 150)
                DrawRect(0.5, 0.95, 0.2 * progress, 0.025, 255, 255, 255, 200)
                
                if IsControlJustPressed(0, 200) then -- ESC pressed
                    return false
                end
            end
        return true
    end
end
```

{% endtab %}

{% tab title="shared/minigames.lua" %}

```lua
function StartMinigame(callback)
    if Config.Minigame == 'ox_lib' and GetResourceState('ox_lib') == 'started' then
        local success = lib.skillCheck({'easy', 'easy', 'easy'}, {'e', 'e', 'e', 'e'})
        if callback then callback(success) end
        return success
        
    elseif Config.Minigame == 'bl_ui' and GetResourceState('bl_ui') == 'started' then
        local success = exports['bl_ui']:RapidLines(2, 70, 3)
        if callback then callback(success) end
        return success
        
    elseif Config.Minigame == 'devhub_hackingMinigames' and GetResourceState('devhub_hackingMinigames') == 'started' then
        local success = exports['devhub_hackingMinigames']:startMinigame('morse', 60)
        if callback then callback(success) end
        return success

    elseif Config.Minigame == 'devhub_minigames' and GetResourceState('devhub_minigames') == 'started' then
        local success = exports['devhub_minigames']:startMinigame("minigame_2", "medium")
        if callback then callback(success) end
        return success
    
    elseif Config.Minigame == 'ps-ui' and GetResourceState('ps-ui') == 'started' then
        local success = exports['ps-ui']:Thermite(10, 5, 3) -- Time, Gridsize, IncorrectBlocks
        if callback then callback(success) end
        return success
        
    elseif Config.Minigame == 'unknown_skillBar' and GetResourceState('unknown_skillBar') == 'started' then
        local success = exports['unknown_skillBar']:skillBar(70, 3) -- Difficulty, Iterations
        if callback then callback(success) end
        return success
    end

end


```

{% endtab %}

{% tab title="shared/target.lua" %}

```lua
function AddEntity(entity, options)
    if Config.Target == 'ox_target' and GetResourceState('ox_target') == 'started' then
        exports.ox_target:addLocalEntity(entity, options)
    elseif Config.Target == 'qb-target' and GetResourceState('qb-target') == 'started' then
        exports['qb-target']:AddTargetEntity(entity, {
            options = {
                {
                    type = "client",
                    event = options.onSelect,
                    icon = options.icon,
                    label = options.label,
                }
            },
            distance = options.distance or 2.0
        })
    end
end

function RemoveEntity(entity)
    if Config.Target == 'ox_target' and GetResourceState('ox_target') == 'started' then
        exports.ox_target:removeLocalEntity(entity)
    elseif Config.Target == 'qb-target' and GetResourceState('qb-target') == 'started' then
        exports['qb-target']:RemoveTargetEntity(entity)
    end
end

function AddModel(model, options)
    if Config.Target == 'ox_target' and GetResourceState('ox_target') == 'started' then
        exports.ox_target:addModel(model, options)
    elseif Config.Target == 'qb-target' and GetResourceState('qb-target') == 'started' then
        exports['qb-target']:AddTargetModel(model, {
            options = {
                {
                    type = "client",
                    event = options.onSelect,
                    icon = options.icon,
                    label = options.label,
                }
            },
            distance = options.distance or 2.0
        })
    end
end

function AddBoxZone(name, coords, size, rotation, options)
    if Config.Target == 'ox_target' and GetResourceState('ox_target') == 'started' then
        exports.ox_target:addBoxZone({
            coords = coords,
            size = size,
            rotation = rotation,
            debug = Config.Debug,
            options = options
        })
    elseif Config.Target == 'qb-target' and GetResourceState('qb-target') == 'started' then
        exports['qb-target']:AddBoxZone(name, coords, size.x, size.y, {
            name = name,
            heading = rotation,
            debugPoly = Config.Debug,
            minZ = coords.z - 1.0,
            maxZ = coords.z + 1.0,
        }, {
            options = options,
            distance = options.distance or 2.0
        })
    end
end
```

{% endtab %}

{% tab title="shared/textui.lua" %}

```lua
local TextUIConfig = {
    ox_lib = {
        position = 'top-center',
        icon = 'fa-solid fa-truck',
        iconColor = '#3FB1FF'
    },
    
    qbcore = {
        position = 'bottom',
        icon = 'fas fa-truck',
        style = {}
    },
    
    esx = {
        position = 'bottom',
        style = {}
    },
    
    cd_drawtextui = {
        position = 'right'
    },
}

function TextUIShow(text, options)
    options = options or {}
    local config = TextUIConfig[Config.TextUI or 'none'] or {}
    
    if Config.TextUI == 'ox_lib' and GetResourceState('ox_lib') == 'started' then
        lib.showTextUI(text, {
            position = options.position or config.position or 'top-center',
            icon = options.icon or config.icon or 'fa-solid fa-circle-info',
            iconColor = options.iconColor or config.iconColor or '#3FB1FF',
            style = options.style or {}
        })
        
    elseif Config.TextUI == 'qb-core' and GetResourceState('qb-core') == 'started' then
        exports['qb-core']:DrawText(text, options.position or config.position or 'bottom')
        
    elseif Config.TextUI == 'esx' and GetResourceState('es_extended') == 'started' then
        exports['esx_textui']:Show(text, options.position or config.position or 'bottom')
        
    elseif Config.TextUI == 'cd_drawtextui' and GetResourceState('cd_drawtextui') == 'started' then
        exports['cd_drawtextui']:Show(text, options.position or config.position or 'right')

    else
        print("No TextUI system available to show.")
    end
    
    return true
end


function TextUIHide()

    if Config.TextUI == 'ox_lib' and GetResourceState('ox_lib') == 'started' then
        lib.hideTextUI()
        
    elseif Config.TextUI == 'qb-core' and GetResourceState('qb-core') == 'started' then
        exports['qb-core']:HideText()
        
    elseif Config.TextUI == 'esx' and GetResourceState('es_extended') == 'started' then
        if GetResourceState('esx_textui') == 'started' then
            exports['esx_textui']:Hide()
        end
        
    elseif Config.TextUI == 'cd_drawtextui' and GetResourceState('cd_drawtextui') == 'started' then
        exports['cd_drawtextui']:Hide()

    else
        print("No TextUI system available to hide.")
    end
    
    return true
end
```

{% endtab %}

{% tab title="shared/dispatch.lua" %}

```lua
function SendDispatchAlert(coords, message, jobs, zoneName)
    local locale = Locales[Config.Locale] or Locales['en']
    local dispatchMessage = message or (zoneName and string.format(locale['police_alert'] or 'Person rummaging through suspicious dumpster at %s!', zoneName) or locale['dispatch_message']) or 'Person rummaging through suspicious dumpster!'
    local alertJobs = jobs or 'police'
    
    if Config.Dispatch == 'cd_dispatch' and GetResourceState('cd_dispatch') == 'started' then
        TriggerServerEvent('cd_dispatch:AddNotification', {
            job_table = alertJobs,
            coords = coords,
            title = '10-34 - Dumpster Alert',
            message = dispatchMessage,
            flash = 0,
            uniqueId = 'dumpster_alert_' .. GetGameTimer(),
            sound = 1,
            blip = {
                sprite = 66,
                scale = 1.0,
                colour = 1,
                flashes = true,
                text = '10-34 - Dumpster Alert',
                time = 10,
                radius = 0
            }
        })
        
    elseif Config.Dispatch == 'tk_dispatch' and GetResourceState('tk_dispatch') == 'started' then
        exports['tk_dispatch']:addCall({
            jobs = alertJobs,
            coords = coords,
            title = 'Dumpster Alert',
            priority = 'Priority 3',
            message = dispatchMessage,
            removeTime = 1000 * 60 * 10,
            code = '10-34',
            blip = {
                sprite = 66,
                color = 1,
                scale = 1.0,
            }
        })
        
    elseif Config.Dispatch == 'ps-dispatch' and GetResourceState('ps-dispatch') == 'started' then
        exports['ps-dispatch']:DumpsterAlert()

            -- ADD THIS TO YOUR PS-DISPATCH CONFIG (MORE: https://github.com/Project-Sloth/ps-dispatch/blob/main/README.md)

            -- ['dumpsterAlert'] = { -- Need to match the codeName in alerts.lua
            --     radius = 0,
            --     sprite = 66,
            --     color = 1,
            --     scale = 1.0,
            --     length = 300,
            --     sound = 'Lose_1st',
            --     sound2 = 'GTAO_FM_Events_Soundset',
            --     offset = false,
            --     flash = true
            -- },

            -- ADD THIS TO YOUR PS-DISPATCH CLIENT/ALERTS.LUA

            -- local function DumpsterAlert(alertJobs)
            --     local coords = GetEntityCoords(cache.ped)
            --     local dispatchData = {
            --         message = 'Dumpster alert!', -- add this into your locale
            --         codeName = 'dumpsterAlert', -- this should be the same as in config.lua
            --         code = '10-34',
            --         icon = 'fa-solid fa-box',
            --         priority = 3,
            --         coords = coords,
            --         jobs = alertJobs,
            --     }

            --     TriggerServerEvent('ps-dispatch:server:notify', dispatchData)
            -- end
            -- exports('DumpsterAlert', DumpsterAlert)
        
    elseif Config.Dispatch == 'rcore_dispatch' and GetResourceState('rcore_dispatch') == 'started' then
        local alertData = {
            code = '10-34',                         -- Alert code
            default_priority = 'low',              -- 'low', 'medium', or 'high'
            coords = coords,                        -- Alert location
            job = alertJobs,                        -- Job(s) to receive alert (string or table)
            text = dispatchMessage,                 -- Alert description
            type = 'alerts',                        -- Alert type for statistics
            blip_time = 500,                        -- Optional: Blip fade time (seconds)
            -- image = 'url_to_image.jpg',          -- Optional: Image URL
            -- custom_sound = 'url_to_sound.mp3',   -- Optional: Custom sound URL
            blip = {                                -- Optional: Custom blip settings
                sprite = 66,
                colour = 1,
                scale = 1.0,
                text = '10-34 Dumpster Alert',
                flashes = false,
                radius = 0,
            }
        }

        TriggerServerEvent('rcore_dispatch:server:sendAlert', alertData)
        
    else
        Notify(0, dispatchMessage, 'info')
    end
end
```

{% endtab %}
{% endtabs %}

## Locales

{% tabs %}
{% tab title="locales/locales.lua" %}

```lua
Locales = {
    ['en'] = {
        -- Notifications
        ['dumpster_not_found'] = 'Dumpster not found!',
        ['already_searched'] = 'This dumpster has already been searched. Wait %s more minutes.',
        ['minigame_failed'] = 'Failed to find anything valuable!',
        ['search_cancelled'] = 'Search cancelled',
        ['needle_stab'] = 'Stabbed by a dirty needle!',
        ['rat_bite'] = 'A rat bit you!',
        ['found_nothing'] = 'Found nothing valuable!',
        ['found_items'] = 'Found something in the dumpster!',
        ['error'] = 'Error!',
        ['already_hiding'] = 'Already hiding!',
        ['hiding_in_container'] = 'Hiding in container',
        ['exit_container_text'] = '[E] - Exit container',
        ['exited_container'] = 'Exited container',
        ['already_searched_server'] = 'This dumpster has already been searched!',
        ['checking_container'] = 'Checking container...',
        ['someone_hiding'] = 'Someone is hiding in the container!',
        ['no_one_hiding'] = 'No one is hiding in the container',
        ['kicked_out'] = 'You were kicked out of the container!',
        
        -- Police alerts
        ['police_alert'] = 'Person rummaging through suspicious dumpster at %s!',
        ['dispatch_message'] = '10-34 - Person rummaging through suspicious dumpster!',
        
        -- Target labels
        ['search_dumpster'] = 'Search Dumpster',
        ['hide_in_dumpster'] = 'Hide in Container',
        ['check_dumpster'] = 'Check Container',
        ['search_garbage_can'] = 'Search Garbage Can',
        ['search_beach_can'] = 'Search Beach Can',
        ['search_other'] = 'Search',
        
        -- Progress bar
        ['searching_progress'] = 'Searching...',
    },
    
    ['lt'] = {
        -- Notifications
        ['dumpster_not_found'] = 'Šiukšlinė nerasta!',
        ['already_searched'] = 'Šioje šiukšlinėje jau ieškota. Laukite dar %s min.',
        ['minigame_failed'] = 'Nepavyko rasti nieko vertingo!',
        ['search_cancelled'] = 'Ieškojimas atšauktas',
        ['needle_stab'] = 'Persidūrei nešvaria adata!',
        ['rat_bite'] = 'Žiurkė įkando!',
        ['found_nothing'] = 'Nieko vertingo neradai!',
        ['found_items'] = 'Radai kai ką šiukšlinėje!',
        ['error'] = 'Klaida!',
        ['already_hiding'] = 'Jau slapstaisi!',
        ['hiding_in_container'] = 'Slapstaisi konteineryje',
        ['exit_container_text'] = '[E] - Išlipti iš konteinerio',
        ['exited_container'] = 'Išlipai iš konteinerio',
        ['already_searched_server'] = 'Šioje šiukšlinėje jau ieškota!',
        ['checking_container'] = 'Tikrinate konteinerį...',
        ['someone_hiding'] = 'Kažkas slepiasi konteineryje!',
        ['no_one_hiding'] = 'Konteineryje niekas nesislepia',
        ['kicked_out'] = 'Buvote išmestas iš konteinerio!',
        
        -- Police alerts
        ['police_alert'] = 'Asmuo rausiasi įtartinoje šiukšlinėje vietoje %s!',
        ['dispatch_message'] = '10-34 - Asmuo rausiasi įtartinoje šiukšlinėje!',
        
        -- Target labels
        ['search_dumpster'] = 'Ieškoti šiukšlinėje',
        ['hide_in_dumpster'] = 'Slėptis konteineryje',
        ['check_dumpster'] = 'Patikrinti konteinerį',
        ['search_garbage_can'] = 'Ieškoti šiukšliadėžėje',
        ['search_beach_can'] = 'Ieškoti paplūdimio šiukšlinėje',
        ['search_other'] = 'Ieškoti',
        
        -- Progress bar
        ['searching_progress'] = 'Ieškote...',
    }
}

function Locale(key, ...)
    local locale = Config.Locale or 'en'
    local translation = Locales[locale] and Locales[locale][key] or Locales['en'][key] or key
    
    if ... then
        return string.format(translation, ...)
    end
    
    return translation
end

```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unknown-development.gitbook.io/unknown-development/scripts/unknown_dumpsters.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
