Commands#
Treasure Hunting is driven from its NPC and its items, so it registers a single chat command.
Command | Where | Description |
|---|---|---|
| In game | Leaves your crew, giving up any hunt you are on first. Run by the leader, it disbands the crew. |
There are no admin commands. Staff tools reach the script through the server exports below — for example, starting the legendary chest for an event.
Client Exports#
Called from another resource's client script.
Opening the job panel
exports['qs-treasure-hunter']:openTreasureMenu() -- the full panel: missions, crew, statistics, shop, guideThe statistics, shop and guide are views inside the panel, so there is no export to open one on its own; an NPC manager or a phone app opens the panel. The client event qs-treasureHunter:openTreasureMenu does the same.
Crew
exports['qs-treasure-hunter']:leaveTreasureCrew() -- same as /leavecrewUsable items
These are what an inventory's client.export points at, and can be called from anywhere:
exports['qs-treasure-hunter']:toggleMetalDetector() -- take the detector out or put it away
exports['qs-treasure-hunter']:toggleDivingGear() -- put the gear on or off (only with Config.ManageDivingGear)
exports['qs-treasure-hunter']:useClueMap() -- read a clue_map
exports['qs-treasure-hunter']:useTreasureMap() -- read a treasure_mapUsing a map still takes the item from the bag on the server, so calling it without one does nothing. The client events qs-treasureHunter:toggleMetalDetector, qs-treasureHunter:toggleDivingGear and qs-treasureHunter:useMapItem (with the item name) do the same.
Server Exports#
Called from another resource's server script.
Who is out hunting
exports['qs-treasure-hunter']:IsPlayerOnMission(source) -- true while the server has a hunt to pay this player for
exports['qs-treasure-hunter']:isPlayerOnDuty(source) -- the duty flag, kept for older scripts
exports['qs-treasure-hunter']:getOnDutyCount() -- how many players are on a hunt right nowUse IsPlayerOnMission for anything new: it reads the hunt roster itself. getOnDutyCount is what a scoreboard or a job list shows.
The legendary chest
exports['qs-treasure-hunter']:startLegendaryChestEvent() -- spawn it now for the whole server
exports['qs-treasure-hunter']:endLegendaryChestEvent() -- sink it without a winnerStarting it while one is already running does nothing. It uses Config.LegendaryChestEvent for its place, prize and duration, and ignores its chance.
Checking an item
-- client side, through ox_lib
local count = lib.callback.await('qs-treasureHunter:checkItem', false, 'metal_detector')
-- the amount held, or falseKept for resources that already call it. It counts through the same inventory routing as the rest of the script.
Removed Events#
Earlier versions trusted the client with prices, experience, loot and chest positions. Those events no longer exist, and a script that still triggers one simply does nothing:
Old event | Replaced by |
|---|---|
| The server pays from the task in config when the last chest is opened. |
| Experience comes from the chest actually opened. |
| Loot is rolled on the server when a claim is validated. |
| The server picks the crew, the group id and the chests, and records progress itself. |
| The answer never leaves the server; the code is compared there. |
| The tool handout inside the hunt start, the shop, and props cleaned up locally. |
Everything a client can still send — take a hunt, claim a chest, read a totem, buy, sell, rent — is checked on the server against config, the player's level, their bag and where their ped is standing, and rate-limited per player.



