ConsumablesNewFree

Consumables: Exports & Events

Start eating from your own resources, read the remaining amount and expiry of a food, hook hunger and thirst into a standalone HUD and work with the item metadata.

v1.0.0Open sourceFreeQBox · QBCore · ESX · Standalone

Resource name

Exports are called through the resource name, so keep the folder named hype-consumables. Because the name contains a hyphen, call exports as exports["hype-consumables"] rather than exports.hype-consumables.

ExportSidePurpose
useFoodClientStart eating the food in a slot, or take the next bite
giveFoodClientOpen the nearby player list for the food in a slot
dropFoodClientPut the food in a slot on the ground
GetFoodInfoServerRemaining amount, expiry and more of the food in a slot
IsFoodServerWhether an item is handled by this resource
GetModulesBothThe inventory, notify and target modules

Client exports

useFood

Uses the food in a slot, exactly as if the player used the item. If nothing is being eaten, eating starts (with the first bite when Consume.biteOnStart is on). If the same food is already being eaten, the next bite is taken. A different food gives the You are already eating something error.

ox_inventory calls it through client.export in the item definition. You can call it yourself, for example from a radial menu or a hotbar, with any supported inventory. The server reads the slot and validates everything.

client.lua
exports["hype-consumables"]:useFood(nil, { name = "burger", slot = 3 })

Prop

Type

giveFood

Closes ox_inventory and opens the nearby player list for the food in a slot. Pressing H again selects the next player, Y sends the offer and N cancels. It is used by the Give to someone button in the ox_inventory item definitions.

client.lua
exports["hype-consumables"]:giveFood(3)

Prop

Type

dropFood

Closes ox_inventory and puts the food in a slot on the ground in front of the player. It is used by the Put on the ground button. Nothing happens when Drops.enabled is false, and it is refused inside a vehicle.

client.lua
exports["hype-consumables"]:dropFood(3)

Prop

Type

ox_inventory only

giveFood and dropFood close ox_inventory before they run, so they are meant for ox_inventory. On qb style inventories, players give and drop food with H and Q while eating.

Server exports

GetFoodInfo

Returns a summary of the food in a player's slot, or nil when the slot holds no food. If the item has no food metadata yet (for example an item from before the script was installed), the metadata is written first.

server.lua
local info = exports["hype-consumables"]:GetFoodInfo(source, 3)

if info and not info.spoiled then
    print(("%s: %s of %s %s left, %s bites"):format(info.label, info.amount, info.initialAmount, info.unit, info.bitesLeft))
end

Prop

Type

Returns table? with these fields:

Prop

Type

IsFood

Returns true when the item is defined in config/foods.lua. It does not check whether the item exists in your inventory.

server.lua
if exports["hype-consumables"]:IsFood(itemName) then
    -- leave it to hype-consumables
end

Prop

Type

Events

hype-consumables:server:addStatus

Triggered on the server only in standalone mode, on every bite. Standalone servers have no built-in hunger and thirst, so apply the values from your own status or HUD resource. On QBox, QBCore and ESX the values are applied through the framework and this event is not triggered.

server.lua
AddEventHandler("hype-consumables:server:addStatus", function(playerId, hunger, thirst)
    -- hunger / thirst are on a 0-100 scale, negative values remove
    exports["my-status"]:Add(playerId, "hunger", hunger)
    exports["my-status"]:Add(playerId, "thirst", thirst)
end)

Prop

Type

my-status stands for your own resource.

hype-consumables:client:player-loaded

A local client event the framework bridges trigger when a character is loaded. It checks the player's food on the server (missing metadata, spoiled items) and reloads the food on the ground. The script also does this once when the player joins. On a standalone server with a custom character selection, trigger it after a character is picked:

client.lua
TriggerEvent("hype-consumables:client:player-loaded")

hype-consumables:client:useFood

The server triggers it on qb style inventories when a food item is used. Trigger it yourself to start eating from a server script:

server.lua
TriggerClientEvent("hype-consumables:client:useFood", source, { name = "burger", slot = 3 })

Internal events

hype-consumables:server:addStatus is a local server event; never trigger it from the client. The other hype-consumables:* events and callbacks are internal and validated on the server; do not call them yourself.

Item metadata

Food is a normal inventory item. Shops, crafting and jobs add it as usual, and the metadata is written by the script: right away through the createItem hook on ox_inventory, on first use or when the player joins on qb style inventories. On qb style inventories the fields are in the item info.

FieldDescription
amount / initialAmountRemaining / starting grams or ml
createdAt / expiresAtReal time (os.time). Giving, dropping and picking up never change them
isPerishable / foodCategoryPerishability and category
foodIdUnique id given on the first bite. Sealed packages have none, so they stack
spoiledSet once the food is marked as spoiled
weight / durabilityox_inventory: weight of the remaining amount and the remaining percentage bar
description / labelRemaining amount, expiry date and the (Spoiled) suffix shown in the inventory

Do not write the metadata yourself

Every value is calculated on the server and the client never sends metadata. Read it with GetFoodInfo instead of changing the fields from other resources.

Bridges and modules

The framework bridges in frameworks/ and the modules in modules/ are open source. If your status or HUD system is customized, change Framework.Server.AddStatus in your framework's sv-main.lua; it receives hunger and thirst on a 0-100 scale.

main.lua
main.lua
FunctionSidePurpose
Framework.Server.GetPlayerIdentifier(id)Servercitizenid on QBox / QBCore, identifier on ESX, license2 / license standalone
Framework.Server.GetCharacterName(id)ServerCharacter name, used when Transfer.showNames is on
Framework.Server.AddStatus(id, hunger, thirst)ServerApplies hunger and thirst

GetModules

Returns the module table of the side it is called on. With a name, only that module: "Inventory" on the server, "Notify" or "Target" on the client.

client.lua
local notify = exports["hype-consumables"]:GetModules("Notify")
notify.SendNotify("Food", "Enjoy your meal!", 5000, "success")
server.lua
local inventory = exports["hype-consumables"]:GetModules("Inventory")
print(inventory.Name) -- "ox_inventory"

Prop

Type

ModuleSideFunctions
InventoryServerName, GetSlot, FindByMetadata, GetItems, SetMetadata, RemoveFromSlot, AddItem, CanCarry, ItemExists, ItemLabel
NotifyClientSendNotify(title, message, time?, type?), time defaults to 5000 and type to "inform"
TargetClientAddLocalEntity(entity, options), RemoveLocalEntity(entity)

On this page