[STANDALONE] Dumpster Search

Standalone Dumpster Serach Minigame

This script offers an engaging dumpster diving minigame, inspired by Hobo: Tough Life. Perfect for servers looking to add immersive scavenging mechanics.

Features:

  • Intuitive Gameplay: Simple grid-based searching system
  • Custom Configuration: Adjust dumpster sizes and item rates
  • Optimized Performance: Lightweight and resource-friendly
  • Easy Framework Adaptation: Works with any framework

Config

Config.Interaction = 'textui' -- textui | interaction
Config.InteractDistance = 1.0
Config.CloseMinigameOnDeath = true

Config.SearchDumpsterButton = 38        -- E, only if you using textui interaction | https://docs.fivem.net/docs/game-references/controls/

Config.ClickCooldown = 2 * (1000)       -- sec
Config.SearchCooldown = 5 * (60 * 1000) -- min

Config.DefaultSearchTime = 1000

Config.DumpsterSizes = {
    small = { 3, 3 },
    medium = { 5, 5 },
    big = { 7, 7 },
    huge = { 9, 9 },
}

Config.Dumpsters = {
    --big
    {
        model = 'prop_dumpster_01a',
        dumpsterSize = 'big',
        dumpsterIndex = 1,
    },
    {
        model = 'prop_dumpster_02a',
        dumpsterSize = 'big',
        dumpsterIndex = 1,
    },
    {
        model = 'prop_dumpster_02b',
        dumpsterSize = 'big',
        dumpsterIndex = 1,
    },
    {
        model = 'prop_dumpster_3a',
        dumpsterSize = 'big',
        dumpsterIndex = { 1, 2 },
    },
    {
        model = 'prop_dumpster_4a',
        dumpsterSize = 'huge',
        dumpsterIndex = { 1, 2 },
    },
    {
        model = 'prop_dumpster_4b',
        dumpsterSize = 'huge',
        dumpsterIndex = { 1, 2 },
    },

    --small
    {
        model = 'prop_bin_01a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_02a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_03a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_04a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_05a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_06a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_07a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_07b',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_07c',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_07d',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_08a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_08open',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_09a',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_delpiero',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'prop_bin_delpiero_b',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
    {
        model = 'zprop_bin_01a_old',
        dumpsterSize = 'small',
        dumpsterIndex = 3,
    },
}

Config.Difficulties = {
    easy = {
        speed = 3,
        label = 'Easy',
        points = 8,
        maxAttempts = 5,
        color = '#689f38',
    },
    medium = {
        speed = 4,
        label = 'Medium',
        points = 3,
        maxAttempts = 3,
        color = '#f57336',
    },
    hard = {
        speed = 6,
        label = 'Hard',
        points = 1,
        maxAttempts = 2,
        color = '#e53935',
    },
    insane = {
        speed = 10,
        label = 'Insane',
        points = 1,
        maxAttempts = 1,
        color = '#440505',
    },
}

--[[ params for DumpstersItems
    grabbable = true | false -- If true you allow player to grab revealed item (optional)
    minigame = easy | medium | hard | insane -- You can choose difficulty of minigame necessary to reveal item (optional)
    rare = true | false -- If true you mark item as rare, to fully work is necessary to add "mingame" param (optional)
    harming = true | false -- If true you mark item as harmful, basically that only set red item background. Yoy can refer to this variable in OnItemReveal(itemData) [hooks.c.lua] and add new functions
    chance = 0-100 -- Set a chance in % for spawn item in minigame
    count = number | table -- Set an amount of item has been added to player inventory on grab, variable can by a number like 1,2,3 or random range like {1, 5}
--]]

Config.DumpstersItems = {
    [1] = {
        {
            item = 'trash',
            chance = 30,
        },
        {
            item = 'trash-broken',
            chance = 10,
        },
        {
            item = 'money',
            count = { 5, 10000 },
            chance = 15,
            rare = true,
            minigame = 'easy',
            grabbable = true,
        },
        {
            item = 'money',
            count = { 50, 100000 },
            chance = 15,
            rare = true,
            minigame = 'hard',
            grabbable = true,
        },
        {
            item = 'broken-bottle',
            chance = 20,
            harming = true,
            grabbable = true,
        },
    },
    [2] = {
        {
            item = 'trash',
            chance = 20,
        },
        {
            item = 'trash-broken',
            chance = 20,
        },
    },
    [3] = {
        {
            item = 'money',
            count = { 5, 10 },
            chance = 30,
            -- rare = true,
            minigame = 'medium',
            grabbable = true,
        },
        {
            item = 'trash',
            chance = 20,
        },
        {
            item = 'broken-bottle',
            chance = 10,
            harming = true,
        },
        {
            item = 'trash-broken',
            chance = 20,
        },
    },
}

Open LUA files

-----------------
-- CLIENT SIDE --
-----------------

--  add your notifications here
--- @param notificationType 'cooldown'
RegisterNetEvent('bl-dumpstersearch:notification', function(notificationType)
    if notificationType == 'cooldown' then
        print('cooldown is here')
    end
end)

--- @param data { item: string }
RegisterNUICallback('getItemImageUrl', function(data, cb)
    -- here is an example of resolving item imageUrl from item name

    -- our codebase has module called Inventory and function for getting registered item informations
    -- this function returns for us an object with imageUrl which is url to image  (eg. 'https://cms.example.com/images/item.png')
    -- if you have some sort of static item images in your inventory resource you can transform item name like for example:
    -- https://cfx-nui-your-inventory/nui/itemimages/item.png

    -- image from inventory resource
    -- cb('https://cfx-nui-your-inventory/nui/items/' + data.item + '.png')

    -- image from cms or other static file server
    -- cb('https://cms.example.com/images/' + data.item + '.png')

    -- also you can put item images into /images folder in root of this resource
    -- and resolve it like this:
    -- cb(string.format('/images/%s.png', data.item))


    cb(string.format('/images/%s.png', data.item))
    -- cb(Inventory.Items:GetRegisteredItem(data.item).imageUrl)
end)

--- Prevent using script for some reason
--- @return boolean isDisabled
function IsScriptDisabled()
    local playerPed = PlayerPedId()

    if IsPedInAnyVehicle(playerPed, false) then return true end
    if LocalPlayer.state.isDead then return true end

    return false
end

--- Function is triggered when player reveal item in minigame
--- @param itemData { count?: integer[], item: string, chance: integer, grabbable: boolean, minigame: 'easy' | 'medium' | 'hard' | 'insane', harming?: boolean }
function OnItemReveal(itemData)
    -- example: give player damage when reveal harming item
    if itemData.harming then
        local playerPed = PlayerPedId()
        local playerHealth = GetEntityHealth(playerPed) - 5

        SetEntityHealth(playerPed, playerHealth)
    end
end

--- Config.Interaction must be set to 'interaction'
--- @param models string[]
function AddTargetForModels(models)
    exports.ox_target:addModel(models, {
        label = 'Search Dumpster',
        icon = 'fas fa-dumpster',
        distance = Config.InteractDistance,
        canInteract = function(entity, distance, coords, name, bone)
            if NUI.activ then return false end

            local playerPed = PlayerPedId()
            if IsPedRagdoll(playerPed) then return false end
            if IsPedInAnyVehicle(playerPed) then return false end

            return IsValidObjectPosition(entity)
        end,
        onSelect = function(data)
            RequestSearch(data.entity)
        end
    })
end


-----------------
-- SERVER SIDE --
-----------------

function GiveItem(source, itemData)
    local itemCount = (type(itemData.count) == 'table' and math.random(table.unpack(itemData.count)) or itemData.count) or
        1

    print('[bl-dumpstersearch] Give item', itemData.item, itemCount)

    -- ox_inventory - uncomment line below if you use ox_inventory
    -- exports.ox_inventory:AddItem(source, itemData.item, itemCount)
end

Minigame:

More screenshots


Preview video :movie_camera:

Any questions? Contact us on our Discord

Price: $15 + TAX

BUY NOW (TEBEX)

Take your roleplay experience to the next level with this unique scavenging feature!

Code is accessible No
Subscription-based No
Lines 354 LUA + 1000+ NUI
Requirements none
Support Yes
1 Like