Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
This documentation covers everything you need to get your script set up and working as intended. Please make sure to read it carefully—most issues can be avoided by following the steps provided. If all dependencies are installed correctly and you follow the instructions, your script will work as expected.
If you've followed the documentation and are still having issues, head over to our Discord and open a support ticket. The link is in the sidebar (bottom left). We’ll help you out once you’ve confirmed you've run through the docs.
Looking for something more tailored to your server? We offer:
⚙️ Script optimisations and performance tweaks
⚒️ Creation of scripts from idea to production.
🎨 UI creation, edits, and complete redesigns
🧱 Custom features or systems built to your spec
If you’re after something beyond what's available out-of-the-box, open a ticket in Discord to discuss your requirements.
Here we will guide you through the basics from downloading the asset from your keymaster to where to put the folder, more specific instructions will be found on the left under resource name.
After purchasing one of our scripts, head over to keymaster.fivem.net — this is where all of your purchased assets are managed.
From there, hit Download to grab the latest version.
If this is your first time installing a DirkScripts resource, we recommend creating a folder named:
[dirk]
Place all DirkScripts scripts and their dependencies inside this folder. This keeps everything organised and ensures proper start order.
Example structure:
resources/
└── [dirk]/
├── dirk_inventory
├── dirk_traphouse
└── dirk_dependencies
Add the following to your server.cfg
:
The best location is somewhere after your framework and it's dependencies start.
ensure [dirk]
This approach helps avoid loading issues and makes updates easier down the line.
To get started, simply ensure dirk_lib
is started after your framework, inventory, and targeting resources.
There’s no complex setup—dirk_lib
will automatically detect supported resources and apply the correct bridging logic for your setup.
No extra config needed—just ensure the dependencies are started before dirk_lib
.
You can customize the behaviour of dirk_lib
by setting server variables (ConVars). These can be placed in your server.cfg
or follow the tip below for a cleaner way.
To get started with lib, include the shared script within your resource's fxmanifest.lua
You are able to select modules to be loaded, however they will also dynamically import. This can be done via the dirk_libs
manifest option
This is a list of all the resources that this lib will bridge for, add your own by making a PR or contacting me on discord.
# Example Start Order
ensure qb-core
ensure ox_inventory
ensure ox_target
ensure dirk_lib
# The theme below will apply to all UI created by DirkScripts utilising the lib themes.
# Theme starts at 0 and goes to 9
# 0 is the lightest color and 9 is the darkest
# You can set the primary color to custom and set the customTheme to your own colors
# Use this generator in order to make your own custom color palettes https://mantine.dev/colors-generator/?color=7b36b5
# Default mantine colors can be found here https://mantine.dev/theming/colors/#default-colors
setr dirk_lib:primaryColor dirk # Set to custom to use customTheme
setr dirk_lib:primaryShade 9 # 0-9
setr dirk_lib:customTheme [
"#e5f8ff",
"#d0ecff",
"#a0d7fc",
"#6dc1fa",
"#47aef9",
"#32a2f9",
"#259cfa",
"#1888df",
"#0179c8",
"#0068b1"
]
setr dirk_lib:language en
setr dirk_lib:debug true
setr dirk_lib:currency $
setr dirk_lib:serverName DirkRP
setr dirk_lib:logo https://via.placeholder.com/150
# Configure the resources you want to use will autodetect otherwise [OPTIONAL]
setr dirk_lib:framework qbx_core
setr dirk_lib:inventory dirk_inventory
setr dirk_lib:itemImgPath nui://dirk_inventory/web/images/
setr dirk_lib:primaryIdentifier license
setr dirk_lib:target ox_target
setr dirk_lib:interact sleepless_interact
setr dirk_lib:time dirk_weather
setr dirk_lib:phone lb-phone
setr dirk_lib:keys dirk_keys
setr dirk_lib:garage dirk_vehicles
setr dirk_lib:fuel dirk_fuel
setr dirk_lib:ambulance dirk_ambulance
setr dirk_lib:prison dirk_prison
setr dirk_lib:dispatch dirk_dispatch
# NOTIFICATIONS
setr dirk_lib:notify dirk_lib
setr dirk_lib:notifyPosition top-right
setr dirk_lib:notifyAudio true
# Context Menu
setr dirk_lib:contextMenu dirk_lib
setr dirk_lib:contextClickSounds true
setr dirk_lib:contextHoverSounds true
# Dialog
setr dirk_lib:dialog dirk_lib
setr dirk_lib:dialogClickSounds true
setr dirk_lib:dialogHoverSounds true
# showTextUI
setr dirk_lib:showTextUI dirk_lib
setr dirk_lib:showTextPosition bottom-center
# progressBar
setr dirk_lib:progress dirk_lib
setr dirk_lib:progBarPosition bottom-center
# Groups
setr dirk_groups:maxMembers 5
setr dirk_groups:maxDistanceInvite 5
setr dirk_groups:inviteValidTime 5
setr dirk_groups:maxLogOffTime 5
shared_scripts {
'@dirk_lib/init.lua'
}
dirk_libs {
'math',
'objects'
}
Helpful functions for the player data structure and functions
System for creating player groups and managing them. Used in clean_pause and other clean jobs.
Helpful functions for the player data structure and functions
All configuration will be done via the files within the settings folder.
Some useful commands that are locked to admin only by default. All of these commands will list the arguments required if you type them in the chat.
Will delete the nearest projectCar entirely from the database and the world.
Will complete the nearest projectCar requiring the player to just get in and start it
This will give you an engine with the correct metadata dependant on the class you supply.
Will give you all the items you need to complete a car.
Used to register and remove object spawning, from peds to vehicles.
Create a new object
Get information regarding an object
Completely remove an object
This is the data structure of an object and the valid options
lib.objects.register(name, new_data)
name
Unique reference for object
new_data
Options for the object, refer to Data Structure
local obj = lib.objects.get(name)
id
Unique reference for the object
lib.object.destroy(id)
id
Unique reference for the object
{
type = "ped", -- This can be: ped, vehicle or object
model = `a_f_m_bevhills_01`, -- Model to be spawned, must be the model hash
pos = vector4(0, 0, 0, 0), -- Position of the object
-- This also can be a polyzone for a set render area
renderDist = 50, -- When to render the object
}
lib.print(_type, ...)
-- Example
lib.print("debug", "Example print")
_type
Type of print - info, warn, error or debug
...
Debug info
lib.addPrintType(_type, prefix, condition)
_type
Unique print type
prefix
What should be prefixed in front of the debug
condition
Callback to check if it should print
Used to request models and textures
Used to quickly copy a table, useful for global state values
local copiedTable = lib.table.deepClone(table)
table
Table to be copied
Check through a table for a set key
local foundData = lib.table.findKeyInTable(tbls, key)
tbls
Table to be searched
key
Key to be found
Check if a value is present in a table
local found = lib.table.includes(table, value, recursive)
table
Table to be searched
value
Value to be found
recursive
Check sub tables too
Convert data to different formats
local data = lib.table.convert(_type, data)
_type
Type of data - vectors, items_sql, string, item_ox, convert_idexes
data
Data to be converted
Count a table and sub tables
local count = lib.table.count(table)
table
Table to be counted
Please follow these instructions carefully if you do so you should have no issues, if you do still experience issues after reading through all of this then please make a ticket in discord.
DEPENDENCIES
You will need the following resources installed to be able to use this script properly, please ensure this is possible before buying the script My Library dirk_lib
Please grab your old projectCars.json
and place it in the root directory of dirk_projectCars. The script will auto-detect it on startup and convert any old vehicles to the new SQL table.
In order for this to work you will need to add all the data in INSTALLATION/itemsToAdd/ox_items.lua
to ox_inventory/data/items.lua
['windscreen'] = {
['weight'] = 1000,
['label'] = 'Windscreen',
},
For all QB based inventory systems you can find the items in the following folder
INSTALLATION/itemsToAdd/qb_items.lua
should you wish to manually add them
['windscreen'] = {
['description'] = 'Vehicle Part',
['useable'] = true,
['weight'] = 1000,
['shouldClose'] = false,
['type'] = 'item',
['label'] = 'Windscreen',
['unique'] = false,
['name'] = 'windscreen',
},
Used to request models and textures
Load a model with timeout checks
local success = lib.request.model(model, timeout)
model
Model(s) to load
timeout
Timeout for the model loads, default 20s
Request texture dictionary
local success = lib.request.streamedTextureDict(txd, timeout)
txd
Texture(s) to load
timeout
Timeout for the texture loads, default 20s
Helpful functions for the player data structure and functions
Used for GTA map location blips, for example a fuel station location
Register a new blip to be shown on the map
lib.blip.register(id, data)
id
Unique reference for the blip
data
Options for the blip, see
Get a blip's data via it's id
local blip = lib.blip.get(id)
id
Unique reference for the blip
Remove a blip from the map and cache
lib.blip.delete(id)
id
Unique reference for the blip
This is the data structure of a blip and the valid options
{
-- Required
pos = vector2(150.0, 100.0), -- Used as the location on the map
name = "Example Blip", -- Label displayed on the map key
sprite = 1, -- Sprite to be displayed
display = 4, -- Display options
scale = 1.0, -- Size of the blip
color = 1, -- Color of the blip
-- Not Required
shortRange = false, -- Is the blip short range
category = 1, -- Category of the blip
alpha = 255, -- Alpha (opacity) of the blip
rotation = 0, -- Rotation
route = false, -- Should the blip be routed to
canSee = function() -- Should the blip render
return true
end,
}
FiveM Blip Sprites Reference: https://docs.fivem.net/docs/game-references/blips/#blips
FiveM Native SetBlipDisplay Reference: https://docs.fivem.net/natives/?_0x9029B2F3DA924928
Fivem Blip Colour Reference: https://docs.fivem.net/docs/game-references/blips/#blip-colors
FiveM Native SetBlipCategory Reference: https://docs.fivem.net/natives/?_0x234CDD44D996FD9A
For the supported clothingSystems/Frameworks this will be drag and drop for most users, with no effect to players characters etc.
DEPENDENCIES
You will need the following resources installed to be able to use this script properly, please ensure this is possible before buying the script My Library
The cache is used to store frequent information that scripts will use, this reduces the load of scripts overall as the core library is the only resource gathering these variables.
The cache is simple to access, once you've followed the Getting Started steps, you will be able to access the following values:
ped
The players ped id
vehicle
Current vehicle entityId if there is one or false
driver
true or false for if the player is driving
seat
The seat the player is in if any
weapon
The weapon the player is holding if any
dead
Is the player dead, this is based off of framework specific death metadata and IsEntityDead()
cuffed
Again this is framework specific.
job
This is in the format of dirk_lib/types/job
playerId
The players PlayerId()
citizenId
The players unique character identifier if they have one
serverId
The players serverId
playerLoaded
Whether or not the player has loaded and selected a character
You can simple called cache.x with whichever type you wish anywhere in your code, so long as dirk_lib is imported.
All of the above cache types can be used with lib.onCache, this is essentially a listener that will trigger upon change of the value and at initial set.
-- We can replace 'cuffed' with any of the values from above.
lib.onCache('cuffed', function(isCuffed, oldValue)
print(('Player is now cuffed: %s\nPlayer was cuffed before: %s'):format(isCuffed, oldValue))
end)
-- OR IF YOU REALLY WANTED--
AddEventHandler("dirk_lib:cache:cuffed", function(isCuffed, oldValue)
print(('Player is now cuffed: %s\nPlayer was cuffed before: %s'):format(isCuffed, oldValue))
end)
Follow this guide to install the resource.
Dependencies
dirk_lib (REQUIRED)
There is a folder within the script called 'install' within that is another folder called 'itemsToAdd' please choose the format you require for your framework/inventory
These are all the properties available per category for your store, you can disable categories for a store by removing the categories table entirely.
id
string
Unique identifier for the store.
type
'buy'
Each tool is defined as a key in the tools table with a structured value. Here's a breakdown of the expected fields:
label
string
✅
Display name of the item.
weight
integer
✅
Weight in grams (e.g. 1000 = 1kg).
description
string
✅
Description text shown in item UI.
chanceOfBreak
integer
❌
Percent chance (0–100) the tool breaks on use.
holdRotation
vector3
❌
Adjusts the rotation of the held object.
holdOffset
vector3
❌
Adjusts the position offset when held.
model
string
❌
Model name of the object to hold (e.g. "prop_tool_box_04"
).
useable
function
❌
Function to execute when the item is used.
strength
integer
❌
Max supported vehicle weight (in grams). Limits what vehicles this item works on.
tools = {
wrench = {
label = "Wrench",
weight = 1000,
description = "A sturdy wrench for basic repairs.",
chanceOfBreak = 25, -- 25% chance of breaking
holdRotation = vector3(90.0, 0.0, 0.0),
holdOffset = vector3(0.0, -0.15, -0.02),
model = "prop_tool_wrench",
strength = 2000,
useable = function(src)
-- custom usage logic here
end
}
}
Used to create target zones (Third Eye)
Create a simple box zone
lib.target.box(id, data)
id
Unique zone reference
data
Zone options
Create a polrzone
This documentation isn't confirmed / is not implimented yet
lib.target.polyzone(id, data)
id
Unique zone reference
data
Zone options
Remove a created zone
lib.target.removeZone(id)
id
Unique zone reference
Create an entity and allow targeting
lib.target.entity(entity, data)
entity
Unique zone reference
data
Zone options
Remove an entity zone
lib.target.removeEntity(entity, net)
id
Unique zone reference
net
Is the entity networked
A free, simple, and flexible store system for FiveM, styled natively and designed to be themed easily to fit your server’s aesthetic.
Default Stores Has most if not all of the default stores configured with basic items from major inventories/frameworks but is fully adjustable.
Categories Optionally have categories for your stores for easier navigation.
Metadata Generators Supports adding unique metadata to specific items, even if your inventory system doesn’t handle it natively.
Group/License Locking Lock the entire store or certain items to different groups or licenses within your city.
Payment Methods Easily add new payment methods to use in any store via the settings/paymentMethods.lua. Here you can define an add and a remove function to implement any sort of currency you wish.
Dynamic Store Creation Register new stores at runtime from the server, giving you complete control over when and where stores appear.
Theming Change the color scheme globally or per store. Don't like green? Pick something that matches your vibe. To set a new global theme for all dirk_scripts see dirk_lib convars
Helpful functions for the player data structure and functions
Get the player's information
Returns the identifier (CitizenID) of the player
Returns the name of the character
Return the phone number of the character
Return the gender of the character
Check if a player is online by their CitizenID
Send a player to jail
Add money to a player
Remove money to a player
Add item to a player
Remove an item for a player
Edit the metadata of an item
Returns the inventory of the player
Example Return:
Used to create and manage polyzones
Create a new zone
Get zone information
Remove a created zone
Check whether a position lies inside a zone(s)
This is the data structure of a blip and the valid options
Some zones have different requirements, see below:
Game Zones:
DEPENDENCIES
You will need the following resources installed to be able to use this script properly. My Library
local player = lib.player.get(source)
src
Source of the target
local citizenid = lib.player.identifier(src)
src
Source of the target
local firstName, lastName = lib.player.name(src)
src
Source of the target
local phoneNumber = lib.player.phone_number(src)
src
Source of the target
local gender = lib.player.gender(src)
src
Source of the target
local isOnline = lib.player.checkOnline(identifier)
identifier
Identifier to be checked for
lib.player.jail(trg, data)
trg
Source to be targeted
data
Data to be used, for example time
lib.player.addMoney(src, acc, amount, reason)
src
Source to be targeted
acc
Account to be deposited in
amount
Amount to be moved
reason
Transaction reason
lib.player.removeMoney(src, acc, amount, reason)
src
Source to be targeted
acc
Account to be removed
amount
Amount to be moved
reason
Transaction reason
lib.player.addItem(src, item, amount, md, slot)
src
Source to be targeted
item
Item spawncode
amount
Quantity
md
Metadata for the item
slot
Slot to be placed in, default is next available
lib.player.removeItem(src, item, amount, md, slot)
src
Source to be targeted
item
Item spawncode
amount
Quantity
md
Metadata for the item
slot
Slot to be placed in, default is next available
lib.player.editItem(src, slot, new_data)
src
Source to be targeted
slot
Item slot to be targeted
new_data
Data to be set
local inventory = lib.player.getInventory(src)
{
{
name = "example",
label = "Example Item",
count = 10,
info = {
metadata = true,
},
slot = 1
}
}
src
Source to be targeted
Each part is defined as an entry in your parts table with configurable fields for how it behaves during installation, usage, and interaction with vehicles.
label
string
✅
The display name of the part.
searchChance
number
✅
Chance this item is found in a search. Set to 0
to make it unsearchable. Think of it like names in a hat—more entries = higher odds.
weight
number
✅
Weight of the part in the inventory (e.g., 1000 = 1kg).
tools
table
❌
Tools required to fit this part. Format: { itemName = quantity }
.
consumables
table
❌
Items that will be consumed when installing this part. Same format as tools.
anim
table
❌
Animation config when applying the part.
→ dict
string
⚠️
Animation dictionary. Must specify either dict
or scenario
.
→ clip
string
✅
Animation clip name.
→ flag
number
❌
Optional animation flags.
→ time
number
❌
Time in seconds to complete the install animation.
reqParts
array
❌
Names of other parts required before this one can be installed.
model
string
❌
Prop model name shown in hand or placed during install (e.g. "prop_oilcan_01a"
).
applyRange
number
❌
Max distance from the vehicle to allow this part to be installed.
applyAtBone
string
❌
The bone name where this part applies (e.g., "engine"
).
canStart
function
❌
Function run to check if the car can start based on this part. Parameters:<br/>→ itemExists
: boolean
(is part installed?)<br/>→ _type
: string
(part name)<br/>Should return: boolean, message
.
removePart
function
❌
Function triggered when removing the part. Parameters:<br/>→ self
: vehicle object<br/>→ entity
: number
(vehicle entity ID)<br/>→ _type
: string
(part name).
addPart
function
❌
Function triggered when adding the part. Same parameters as removePart
.
luaCopyEditparts = {
oil_filter = {
label = "Oil Filter",
searchChance = 15,
weight = 250,
tools = { wrench = 1 },
consumables = { oil = 1 },
anim = {
dict = "anim@amb@clubhouse@tutorial@bkr_tut_ig3@",
clip = "machinic_loop_mechandplayer",
flag = 16,
time = 5
},
reqParts = { "engine_cover" },
model = "prop_oilcan_01a",
applyRange = 2.0,
applyAtBone = "engine",
canStart = function(installed, part)
return installed, installed and "" or "Engine won't start without oil filter."
end,
removePart = function(self, entity, part)
-- custom logic to clean up or detach
end,
addPart = function(self, entity, part)
-- apply tuning or set vars
end
}
}
lib.zones.register(id, data)
name
Unique zone reference
data
Zone options, refer to Data Structure
local polyPoints = {
vector2(0, 0),
vector2(10, 10),
vector2(20, 20),
vector2(0, 30),
vector2(-10, 15),
}
lib.zone.register("exampleZone", {
type = "poly",
pos = polyPoints,
onEnter = function(data)
lib.print("debug", "Entered Zone")
end,
onExit = function(data)
lib.print("debug", "Exited Zone")
end,
})
lib.zone.register("exampleZone", {
type = "box",
pos = vector4(0, 0, 0, 0),
size = vector3(0, 0, 0),
onEnter = function(data)
lib.print("debug", "Entered Zone")
end,
onExit = function(data)
lib.print("debug", "Exited Zone")
end,
})
lib.zone.register("exampleZone", {
type = "game_zone",
gameZone = "ALTA"
onEnter = function(data)
lib.print("debug", "Entered Zone")
end,
onExit = function(data)
lib.print("debug", "Exited Zone")
end,
})
local zone = lib.zones.get(name)
name
Unique zone reference
lib.zones.delete(name)
name
Unique zone reference
local isInside, zoneName = lib.zones.isInsideZone(name, pos)
name
Unique zone reference(s)
pos
Position to be checked
{
-- Required
type = "circle", -- Type of zone: circle, circle2D, poly, box, game_zone
-- Not Required
onEnter = function(data)
-- Callback for entering the zone
end,
onExit = function(data)
-- Callback for exiting the zone
end,
}
{
pos = vector3(0, 0, 0), -- Position of the zone
radius = 5.0, -- Size of the zone radially from the point
}
{
pos = vector2(0, 0), -- Position of the zone
radius = 5.0, -- Size of the zone radially from the point
}
{
points = { -- Boundy marks for the polyzone
vector2(0, 0),
vector2(2, 1),
vector2(3, 3),
}
}
{
pos = vector4(0,0,0,0), -- Position of the zone, x, y, z, heading
size = vector3(0,0,0) -- Size of the zone from the center point
}
{
gameZone = "ALTA"
}
Used to register and control any player interaction
Create a new player interaction
lib.interact.register(name, data)
name
Unique reference for the interaction
data
Options for the interact, refer to
Get information regarding an interaction
local interaction = lib.interact.get(name)
name
Unique reference for the interaction
Completely remove an interaction
lib.interact.destroy(name)
name
Unique reference for the interaction
This is the data structure of an interaction and the valid options
There are multiple different interactions seen below:
{
zone_type = "circle",
pos = vector4(10, 10, 20, 10),
radius = 10
}
{
zone_type = "poly",
polygon = {
vector3(0, 0, 0),
vector3(0, 0, 0),
vector3(0, 0, 0),
},
}
{
zone_type = "box",
pos = vector4(10, 10, 20, 10),
size = vector3(1, 1, 1)
}
{
zone_type = "marker",
pos = vector4(10, 10, 20, 10),
color = vector4(255, 255, 255, 255), -- RGBA
scale = vector3(1, 1, 1),
-- Not Required
dir = vector3(0, 0, 0),
rot = vector3(0, 0, 0),
bob = false,
face = false,
txd = false,
txn = false,
drawEnts = false
}
This documentation is pending confirmation
{
zone_type = "text",
text = "Hello World"
pos = vector4(10, 10, 20, 10),
size = vector3(1, 1, 1)
}
This defines the structure for creating a store, either via your config or dynamically through an export. Stores support job/role restrictions, time-based spawning, custom themes, and more.
id
string
✅
Unique identifier for the store.
type
'buy'
or 'sell'
✅
Determines whether the store is for buying or selling.
name
string
✅
Store display name (e.g. "24/7 Store"
).
description
string
✅
Short UI description shown at the top of the store interface.
icon
string (FontAwesomeIcon)
✅
Icon shown in the UI (FontAwesome class name).
modelType
'ped'
| 'vehicle'
| 'object'
❌
Type of entity used to spawn the store.
models
string[]
✅
Array of model names (e.g. "s_m_m_storeclerk_01"
).
locations
vector4[]
✅
Array of spawn locations with heading.
paymentMethods
string[]
✅
IDs referencing valid payment methods.
categories
category[]
❌
List of item categories shown in the UI.
stock
stockItem[]
✅
Inventory for the store.
openingHours
[number, number]
❌
Time range when store is available (e.g. {6, 22}
for 6AM–10PM).
groups
string
| string[]
| Record<string, number>
❌
Job, gang, or grade restrictions.
licenses
string
| string[]
❌
Player must have these licenses to access the store.
discordRoles
string
| string[]
❌
Discord roles required to open the store.
canOpen
function(src: number)
❌
Server-side function to determine if the player can open the store.
theme
themeObject
❌
Optional override for this store’s visual theme.
onExchange
function(src, items, totalPrice)
❌
Called on attempted transaction. Return false
to cancel. Return a second param as reason.
BaseStores = BaseStores or {}
BaseStore.gunshop = {
id = "gunshop",
type = "buy",
name = "Ammu-Nation",
description = "Everything you need to stay protected.",
icon = "fa-solid fa-gun",
modelType = "ped",
models = { "s_m_m_ammucountry" },
locations = {
vec4(17.8, -1108.6, 29.8, 160.0)
},
paymentMethods = { "cash", "bank" },
categories = {
{
}
},
stock = {
{ item = "pistol", price = 2500 },
{ item = "pistol_ammo", price = 100 }
},
openingHours = { 9, 21 },
groups = { police = 0, sheriff = 0 },
licenses = { "weapon_license" },
canOpen = function(src)
return true
end,
onExchange = function(src, items, price)
if price > 10000 then
return false, "Transaction limit exceeded"
end
return true
end
}
Dynamically creates a store at runtime, syncing to all clients for use straight away, when the resource that creates it is stopped the store will be deleted and unregistered from all clients.
The storeData
parameter is based upon the StoreProps.
This will spawn a very basic shop with a store clerk at the coordinates listed.
local storeData = {
id = 'myNewTestStore',
type = 'buy',
name = 'My Test Store',
description = 'My Short Test Description',
icon = 'fas fa-store',
modelType = 'ped',
models = {'mp_m_shopkeep_01'},
locations = {
vector4(0,0,0,0),
},
paymentMethods = {'cash', 'bank'},
stock = {
{
name = 'bread',
price = 100,
}
},
}
exports.dirk_stores:registerStore(storeData)
lib.zone.register("exampleZone", {
type = "circle",
pos = vector3(0, 0, 0),
radius = 5.0,
onEnter = function(data)
lib.print("debug", "Entered Zone")
end,
onExit = function(data)
lib.print("debug", "Exited Zone")
end,
})
lib.zone.register("exampleZone", {
type = "circle2D",
pos = vector2(0, 0),
radius = 5.0,
onEnter = function(data)
lib.print("debug", "Entered Zone")
end,
onExit = function(data)
lib.print("debug", "Exited Zone")
end,
})
All the properties of a stock item within your stock table for a store.
id
string
Unique identifier for the store.
type
'buy'
You can allow players to purchase labs via tebex instead of in-game for some labs should you wish players can join the server after purchase and use the Config.RedeemCommand (/ClaimLab) in order to claim their new lab this will give them keys into their inventory and ownership.
First you will need to ensure you have linked your tebex to your FiveM server there are many guides for this on Google. You will then need to make a new package with the deliverable product being a Game Server command setup like so: The name of this package you create must be the name of the index of the lab in the config. So in the example below it would have to be "Downtown Cocaine Lab"
['Downtown Cocaine Lab'] = { --## Private Owned
Door = vector4(184.57171630859,-1514.0261230469,29.318643569946,225.4059753418),
Shell = "Cocaine High End Shell", -- Can be false or can be model name of a shell
TebexPackage = 'https://www.dirkscripts.com/category/resources', --## This will not be useable until claimed. Please read the documentation provided on how to setup tebex packages. --- Access.Ownable must be a number but it doesnt matter which number it is if this is a tebex package you can set this to the link to the package see docs
TeamWorkMode = false, --## If this is true required items will come from the shared stockpile and reward items will also go here
KeyItem = nil, --## This could be a name of an item if you wanted a different item to be the key for this lab :thinking: It'll still need metadata attached via the script
Access = {
Ownable = 50000, --## Will make this buyable and have key access -- Probably leave Gangs, Jobs and Public as false. Can be false also
KeyCode = false, --## Do you want a keycode to access this? -- This will overwrite everything else
Public = false,
Gangs = false, --## Gangs can access this lab
Jobs = false, --## Gangs can access this lab
},
IngOrders = {
Price = 5000,
DropPoint = vector4(171.79383850098,-1517.9276123047,29.141628265381,135.28630065918),
Items = {
rawcocaine = 50,
bakingsoda = 50,
actionfigure = 25,
},
},
Blip = { --## Delete this blip table if you don't want a blip
Scale = 0.75,
Sprite = 497,
Color = 45,
Display = 4,
Close = true, --## Will only show this on the minimap when you are close to the lab forcing players to drive around and try find it.
},
Stages = {
[1] = {
Position = vector4(4.825562, -3.003174, -2.673802, 179.7306060791),
Label = "Cut Cocaine",
Icon = "fa-solid fa-scissors",
FancyScene = "Cut Cocaine", --# This can be one of the scenes from Config.Scenes or it can be false and you can use a regular animation
NormalAnim = false, --## Can be false or can be a table like so {anim = "anim_b", dict = "dict_a", time = 15000}
RequiredItems = {
rawcocaine = 3,
bakingsoda = 2,
},
RewardItems = {
cutcocaine = 2,
},
},
[2] = {
Position = vector4(3.890869, -0.5727539, -2.673793,359.83615112305),
Label = "Cut Cocaine",
Icon = "fa-solid fa-scissors",
FancyScene = "Cut Cocaine", --# This can be one of the scenes from Config.Scenes or it can be false and you can use a regular animation
NormalAnim = false, --## Can be false or can be a table like so {anim = "anim_b", dict = "dict_a", time = 15000}
RequiredItems = {
rawcocaine = 3,
bakingsoda = 2,
},
RewardItems = {
cutcocaine = 2,
},
},
[3] = {
Position = vector4(4.125854, 3.231079, -2.673817,0.0),
Label = "Package Cocaine",
Icon = "fa-solid fa-box-archive",
FancyScene = "Package Cocaine", --# This can be one of the scenes from Config.Scenes or it can be false and you can use a regular animation
NormalAnim = false, --## Can be false or can be a table like so {anim = "anim_b", dict = "dict_a", time = 15000}
RequiredItems = {
cutcocaine = 1,
actionfigure = 1,
},
RewardItems = {
cocainepackage = 1,
},
},
},
},
Fixed issue with qbx_core not picking up license2 natively, resulting in no characters being shown.
Consolidated and reworked all logic for clothing/appearance menus to dirk_lib for simpler adding of more.
With illenium and all major clothing including rcore_clothing the characters will now properly display.
Added ability to use existing character_slots table from es_extended for vipSlots
Added better support for finding player cars/houses including for qs-housing.
Added ability to disable deleting of characters.
Fixed loadEvent stuff from preventing peoples HUDs showing up.
Added group/license/discordRole support for both the entire store or per individual product.
Fixed the scrolling issue. BurningLight127
Payment Methods
Added 'black_money' as a payment method instead of placeholder 'crypto'
Added documentation for this script, feel free to let me know if anything is missing.
Add metadata field to stock instead of having to use metadataGenerators.lua.
Use to easily communicate between both client and server
Call and await for a response of a server callback
-- Client
lib.callback.await(event, ...)
-- Server
lib.callback.await(event, playerId, ...)
event
Server defined event name
playerId
Server Only - source to send request to
cb
Callback function, there must be at least one defined
Register a client callback, this can be used to easily request data from a client from the server
lib.callback.register(event, cb)
event
Event name to be called from the server
cb
Callback function, should return values for the callback