Summary
Provides a variety of exports and importable modules to utilise in other resources, using the lib
global (Lua) or with JS modules. Modules are loaded into the environment of the invoking resource, rather than being called by reference.
Some code is loaded internally and may be accessible through exports (such as the UI), or used by modules to listen to events or call function references.
Usage
Add the following to your server.cfg
.
add_ace resource.ox_lib command.add_ace allow
add_ace resource.ox_lib command.remove_ace allow
add_ace resource.ox_lib command.add_principal allow
add_ace resource.ox_lib command.remove_principal allow
Load into your desired resources by adding the following to fxmanifest.lua
.
lua54 'yes'
shared_script '@ox_lib/init.lua'
- Should be included above other script files. Can use server_script or client_script when applicable.
Features
Not a comprehensive list; refer to the documentation for more features and explanations.
Modules
AddCommand
Register a server command and assign permissions to a group (principal).
---@param commandName string | string[]
---@param properties table false
---@param cb fun(source: number, args: table, raw: string)
lib.addCommand(commandName, properties, cb)
lib.addCommand('giveitem', {
help = 'Gives an item to a player',
params = {
{
name = 'target',
type = 'playerId',
help = 'Target player\'s server id', },
{
name = 'item',
type = 'string',
help = 'Name of the item to give',
},
{
name = 'count',
type = 'number',
help = 'Amount of the item to give, or blank to give 1',
optional = true,
},
{
name = 'metatype',
help = 'Sets the item\'s "metadata.type"',
optional = true,
},
},
restricted = 'group.admin'
}, function(source, args, raw)
local item = Items(args.item)
if item then
Inventory.AddItem(args.target, item.name, args.count or 1, args.metatype)
end
end)
Callback
Server callback events to send data to the server and receive a response. Includes a simple timer to prevent unintentional event spam. Client callback events are also available.
Server
-- name: string
-- cb: function
lib.callback.register(name, cb)
lib.callback.register('ox_inventory:getItemCount', function(source, item, metadata, target)
local inventory = target and Inventory(target) or Inventory(source)
return (inventory and Inventory.GetItem(inventory, item, metadata, true)) or 0
end)
Client
-- name: string
-- delay: number or false
-- cb: function
lib.callback(name, delay, cb, ...)
lib.callback('ox_inventory:getItemCount', false, function(count)
print(count)
end, 'water', {type = 'fresh'})
-- name: string
-- delay: number or false
lib.callback.await(name, delay, ...)
local count = lib.callback.await('ox_inventory:getItemCount', false, 'water', {type = 'fresh'})
print(count)
Points
Wrapper around distance checks. Works similarly to lib.zones.sphere.
Any arbitrary data can be included in the table for easy reference.
local point = lib.points.new({
coords = vec3(442.5363, -1017.666, 28.65637),
distance = 8,
dunak = 'nerd'
})
function point:onEnter()
print('entered range of point', self.id)
end
function point:onExit()
print('left range of point', self.id)
end
function point:nearby()
DrawMarker(2, self.coords.x, self.coords.y, self.coords.z, 0.0, 0.0, 0.0, 0.0, 180.0, 0.0, 1.0, 1.0, 1.0, 200, 20, 20, 50, false, true, 2, nil, nil, false)
if self.currentDistance < 1 and IsControlJustReleased(0, 38) then
print('dunak is a '..self.dunak)
end
end
Zones
Similar to PolyZone, but utilises the GLM library. API is not, and will never be, 1:1.
Box
local box = lib.zones.box({
coords = vec3(442.5363, -1017.666, 28.65637),
size = vec3(1, 1, 1),
rotation = 45,
debug = true
})
function box:onEnter()
print('entered zone', self.id)
end
function box:onExit()
print('exited zone', self.id)
end
function box:inside()
print('you are inside zone ' .. self.id)
end
Poly
local poly = lib.zones.poly({
points = {
vec(413.8, -1026.1, 29),
vec(411.6, -1023.1, 29),
vec(412.2, -1018.0, 29),
vec(417.2, -1016.3, 29),
vec(422.3, -1020.0, 29),
vec(426.8, -1015.9, 29),
vec(431.8, -1013.0, 29),
vec(437.3, -1018.4, 29),
vec(432.4, -1027.2, 29),
vec(424.7, -1023.5, 29),
vec(420.0, -1030.2, 29),
vec(409.8, -1028.4, 29),
},
thickness = 2,
debug = true
})
function poly:onEnter()
print('entered zone', self.id)
end
function poly:onExit()
print('exited zone', self.id)
end
function poly:inside()
print('you are inside zone ' .. self.id)
end
Sphere
Just a distance check under the hood. Almost 1:1 with the points module.
local sphere = lib.zones.sphere({
coords = vec3(442.5363, -1017.666, 28.65637),
radius = 1,
debug = true
})
function sphere:onEnter()
print('entered zone', self.id)
end
function sphere:onExit()
print('exited zone', self.id)
end
function sphere:inside()
print('you are inside zone ' .. self.id)
end
UI
Context menu
RegisterCommand('testcontext', function()
lib.registerContext({
id = 'example_menu',
title = 'Example Context',
options = {
{title = 'Empty button'},
{
title = 'Example button',
description = 'Example button description',
metadata = {
{label = 'Value 1', value = 'Some value'},
{label = 'Value 2', value = 300},
}
},
{
title = 'Menu button',
menu = 'other_example_menu',
description = 'Takes you to another menu!',
metadata = {'It also has metadata support'}
},
{
title = 'Event button',
description = 'Open a menu and send event data',
arrow = true,
event = 'some_event',
args = {value1 = 300, value2 = 'Other value'}
}
},
{
id = 'other_example_menu',
title = 'Other Context Menu',
menu = 'example_menu',
options = {
['Nothing here'] = {}
}
}
})
lib.showContext('example_menu')
end)
Input
local input = lib.inputDialog('Police locker', {
{ type = "input", label = "Locker number" },
{ type = "checkbox", label = "Some checkbox" },
{ type = "input", label = "Locker PIN", password = true, icon = 'lock' },
{ type = "checkbox", label = "Some other checkbox" },
{ type = 'select', label = 'Value select', options = {
{ value = 'option1', label = 'Option 1' },
{ value = 'option2', label = 'Option 2' },
{ value = 'option3', label = 'Option 3'},
}}
})
print(json.encode(input, {indent=true}))
Notifications
lib.notify({
title = 'Notification title',
description = 'Notification description',
type = 'success'
})
Progress bar/circle
local success = lib.progressBar({
duration = 2000,
label = 'Drinking water',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
},
anim = {
dict = 'mp_player_intdrink',
clip = 'loop_bottle'
},
prop = {
model = `prop_ld_flow_bottle`,
pos = vec3(0.03, 0.03, 0.02),
rot = vec3(0.0, 0.0, -1.5)
},
})
if success then
print('Do stuff when complete')
else
print('Do stuff when cancelled')
end
local success = lib.progressCircle({
duration = 2000,
position = 'bottom',
useWhileDead = false,
canCancel = true,
disable = {
car = true,
},
anim = {
dict = 'mp_player_intdrink',
clip = 'loop_bottle'
},
prop = {
model = `prop_ld_flow_bottle`,
pos = vec3(0.03, 0.03, 0.02),
rot = vec3(0.0, 0.0, -1.5)
},
})
if success then
print('Do stuff when complete')
else
print('Do stuff when cancelled')
end
Skill check
local success = lib.skillCheck({'easy', 'easy', {areaSize = 60, speedMultiplier = 2}, 'hard'}, {'w', 'a', 's', 'd'})