How Integrations Work#
Treasure Hunting detects what you run from the resources that are started before it, and reaches each one through a small open file you can read and edit. Nothing has to be configured for a supported resource.
Layer | Supported | Without it |
|---|---|---|
Framework |
| Required. |
Inventory |
| The framework's own items. |
Target |
| Press |
Vehicle keys |
| The rented boat gets no keys; it still starts. |
Progress bar |
| ox_lib's progress bar. |
3D prompts |
| Built-in floating text. |
Fuel |
| The boat keeps the fuel it spawns with. |
Clothing |
| Set |
Job money |
| Hunt payouts go straight to the player's cash. |
Quests |
| No quests. Off by default. |
Every optional integration degrades on its own. A missing target, key system or interface resource never stops a hunt: the script falls back to the plain version and carries on.
Inventories#
ox_inventory and qs-inventory are spoken to directly for every count, add and removal, never through the framework. That matters on ESX with qs-inventory: es_extended only redirects its item functions for ox_inventory, so going through the framework would write to a bag nobody looks at. With any other inventory, the framework is the inventory and is used as it is.
Before giving anything, the script asks the inventory whether the item exists at all. That is how it tells a full bag (the chest stays, nothing is charged) from an unregistered item (named once in the server console and to the player, the progress is kept). If both ox_inventory and qs-inventory are running, ox_inventory is used unless you add Config.InventoryScript = 'qs' to the config.
Diving Resources#
If another resource already handles diving — qbx_divegear and the like — let it own the air:
-- config/config.lua
Config.ManageDivingGear = falseTreasure Hunting then never touches SetEnableScuba, SetPedMaxTimeUnderwater or SetPedDiesInWater, not even on a restart. diving_gear is no longer sold, registered, handed out or required, the tank gauge never appears, the oxygen perk leaves the tooltip, and the guide tells players to bring their own gear.
The Diving Outfit#
With Config.Clothing on, putting the gear on swaps the player into a wetsuit and taking it off restores their skin. The outfit is defined at the top of client/clothing.lua, one table per gender:
local playerClothing = {
male = {
["arms"] = 17,
["tshirt_1"] = 15, ["tshirt_2"] = 0,
["torso_1"] = 243, ["torso_2"] = 0,
["pants_1"] = 94, ["pants_2"] = 0,
["shoes_1"] = 67, ["shoes_2"] = 0,
-- ...
},
female = { --[[ ... ]] },
}On ESX the outfit goes through esx_skin and skinchanger; on QBCore through qb-clothing:client:loadOutfit and qb-clothes:loadPlayerSkin. For illenium-appearance, the reload line is already in the file, commented out. With Config.QuasarInventory on, qs-inventory is locked during the change.
Notifications#
The built-in notifications match the panel. To send them through your own resource instead, turn them off and fill in SendTextMessage in the config:
-- config/config.lua
Config.DefaultNotifications = false
function SendTextMessage(msg, type)
-- type is 'info', 'error' or 'success'
exports['Notify']:Alert(msg, type)
endThe prompts and hints keep using the built-in layer either way.
Discord Logs#
Off by default. Five events can be logged, each with its own colour:
Event | Sent when |
|---|---|
| A leader takes a hunt: its kind, the crew, the pay and the experience. |
| The hunt pays out, with each member's share. |
| Somebody leaves a hunt, from the panel or by disconnecting. |
| A player is paid for a hunt. |
| Any experience is granted, with the level before and after. |
-- config/config.lua
Config.Webhooks = {
Enabled = true,
Url = 'https://discord.com/api/webhooks/...',
Name = 'qs-treasure-hunter',
Avatar = '',
Timestamp = true,
Events = {
MissionStarted = true,
MissionFinished = true,
MissionAbandoned = true,
MoneyPaid = 'https://discord.com/api/webhooks/staff-channel',
ExperienceGiven = false,
},
}Each event is true (the shared Url), false, or a URL of its own — so money can go to a staff channel while missions go somewhere public. Every embed carries the player's name, server id and identifier. Sending never blocks a payout. The format is shared with the other Quasar jobs, so they can all post to one channel.
qs-inventory Quests#
With Config.QuasarInventoryQuests = true and qs-inventory running, three quests are created for each player when they load, and progressed as they play:
Quest | Progresses when |
|---|---|
| A chest is dug up on a metal detector hunt. |
| A crate or an ancient chest is opened. |
| A hunt is completed. |
Titles, descriptions and rewards are in server/missions.lua. A level up also reports level_up_treasure_hunter, for a quest of that name if you create one.
Job Money#
When qs-job-management is started, hunt payouts go through its AddJobMoney export under the treasure_hunter job instead of straight to cash. Shop sales, boat refunds and leaderboard rewards always go to cash.
Adding Your Own Key System#
Each key system is one file in client/vehiclekeys/ that stays inert unless Config.Vehiclekeys names it.
Copy the closest file
Duplicate
none.luaor the system nearest to yours, named after your resource.Write the two functions
lua if Config.Vehiclekeys ~= 'my_keys' then return end function AddVehiclekeys(vehicle, plate) exports['my_keys']:GiveKeys(plate) end function RemoveVehiclekeys(vehicle, plate) exports['my_keys']:RemoveKeys(plate) endRegister it for detection
Add
['my_keys'] = 'my_keys'to thevehicleKeystable at the top ofconfig/config.lua.
The framework bridges in client/framework/ and server/framework/ are open the same way — money, items, names, the progress bar and the blip — for a server whose core has been renamed or changed.



