Domas Scripts
v1.0
Page
Code Steps
Category
Label
Link
Separator
Title
Message
Page icon
No icon. This page keeps the plain index row.
orSVG or PNG, square, at least 32×32.
Create new category
What is the title of your new category?
Edit page index title
What is the title of the page index?
Edit category
What is the new title of your category?
Edit link
What is the new title and URL of your link?
Editable Code
Copy Markdown
Open in ChatGPT
Open in Claude
SERVER SIDE CODE
local Framework = nil
if Config.Framework == 'esx' then
Framework = exports['es_extended']:getSharedObject()
elseif Config.Framework == 'qb' then
Framework = exports['qb-core']:GetCoreObject()
end
function GetPlayer(src)
if Config.Framework == 'qb' then
return Framework.Functions.GetPlayer(src)
elseif Config.Framework == 'esx' then
return Framework.GetPlayerFromId(src)
end
end
function GetIdentifier(src)
if Config.Framework == 'qb' then
local xPlayer = Framework.Functions.GetPlayer(src)
return xPlayer.PlayerData.citizenid
elseif Config.Framework == 'esx' then
local xPlayer = Framework.GetPlayerFromId(src)
return xPlayer.getIdentifier()
end
end
function RemoveBank(src, amount)
if Config.Framework == 'qb' then
local xPlayer = Framework.Functions.GetPlayer(src)
xPlayer.Functions.RemoveMoney('bank', amount)
elseif Config.Framework == 'esx' then
local xPlayer = Framework.GetPlayerFromId(src)
xPlayer.removeAccountMoney('bank', amount)
end
end
function GetBank(src)
if Config.Framework == 'qb' then
local xPlayer = Framework.Functions.GetPlayer(src)
return xPlayer.PlayerData.money.bank
elseif Config.Framework == 'esx' then
local xPlayer = Framework.GetPlayerFromId(src)
return xPlayer.getAccount('bank').money
end
end
function AddCash(src, amount)
if Config.Framework == 'qb' then
local xPlayer = Framework.Functions.GetPlayer(src)
xPlayer.Functions.AddMoney('cash', amount)
elseif Config.Framework == 'esx' then
local xPlayer = Framework.GetPlayerFromId(src)
xPlayer.addMoney(amount)
end
end
function GiveItem(src, item, count)
if Config.Framework == 'qb' then
local xPlayer = Framework.Functions.GetPlayer(src)
if xPlayer.Functions.AddItem(item, count) then
return true
else
return false
end
elseif Config.Framework == 'esx' then
local xPlayer = Framework.GetPlayerFromId(src)
if xPlayer.addInventoryItem(item, count) then
return true
else
return false
end
end
end
function RemoveItem(src, item, count)
if Config.Framework == 'qb' then
local xPlayer = Framework.Functions.GetPlayer(src)
if xPlayer.Functions.RemoveItem(item, count) then
return true
else
return false
end
elseif Config.Framework == 'esx' then
local xPlayer = Framework.GetPlayerFromId(src)
if xPlayer.removeInventoryItem(item, count) then
return true
else
return false
end
end
end
function GetItemCount(src, item)
if Config.Framework == 'qb' then
local xPlayer = Framework.Functions.GetPlayer(src)
return xPlayer.Functions.GetItemByName(item) and xPlayer.Functions.GetItemByName(item).amount or 0
elseif Config.Framework == 'esx' then
local xPlayer = Framework.GetPlayerFromId(src)
local inventoryItem = xPlayer.getInventoryItem(item)
return inventoryItem and inventoryItem.count or 0
end
end
function BanPlayer(src, reason)
if not Config.Anticheat.enabled then return end
print("Player with ID: "..src.." was banned for: "..reason)
sendAnticheatToDiscord(src, reason)
end
-- Phone stuff
-- item.label
function LBPhone_PlacedOrder(src, item, quantity, finalPrice, totalShipping, totalPrice)
local phoneNumber = exports["lb-phone"]:GetEquippedPhoneNumber(src)
if Config.LBPhone.useMessages then
local msg = '您好,您的订单已确认,正在发送给您!' -- Hello, your order has been confirmed and is being sent to you.
local result = exports["lb-phone"]:SendMessage("Ali-Boba | 阿里巴巴", phoneNumber, msg, nil)
end
if Config.LBPhone.useMail then
local email = exports["lb-phone"]:GetEmailAddress(phoneNumber)
local msg = '您好,您的订单已确认,正在发送给您!' -- Hello, your order has been confirmed and is being sent to you.
local data = {
to = email,
sender = 'Ali-Boba | 阿里巴巴',
subject = '有关您的列表的信息', -- Information about your listing
message = msg,
attachments = false,
actions = false,
}
local success, id = exports["lb-phone"]:SendMail(data)
end
end
function LBPhone_PlacedListing(src, item, price, count)
local phoneNumber = exports["lb-phone"]:GetEquippedPhoneNumber(src)
if Config.LBPhone.useMessages then
local msg = 'Hi, your listing was listed successfully!'
local result = exports["lb-phone"]:SendMessage("Los Santos Market", phoneNumber, msg, nil)
end
if Config.LBPhone.useMail then
local email = exports["lb-phone"]:GetEmailAddress(phoneNumber)
local msg = 'Hi, your listing was listed successfully!'
local data = {
to = email,
sender = 'Los Santos Market',
subject = 'Information about your listing',
message = msg,
attachments = false,
actions = false,
}
local success, id = exports["lb-phone"]:SendMail(data)
end
end
function LBPhone_RemoveListing(player, listingId)
local phoneNumber = exports["lb-phone"]:GetEquippedPhoneNumber(player)
if Config.LBPhone.useMessages then
local msg = 'Hi, your listing was removed successfully!'
local result = exports["lb-phone"]:SendMessage("Los Santos Market", phoneNumber, msg, nil)
end
if Config.LBPhone.useMail then
local email = exports["lb-phone"]:GetEmailAddress(phoneNumber)
local msg = 'Hi, your listing was removed successfully!'
local data = {
to = email,
sender = 'Los Santos Market',
subject = 'Information about your listing',
message = msg,
attachments = false,
actions = false,
}
local success, id = exports["lb-phone"]:SendMail(data)
end
end
function LBPhone_OrderArived(owner, item, count)
local itemLabel = item
local phoneNumber = exports["lb-phone"]:GetEquippedPhoneNumber(owner)
if Config.LBPhone.useMessages then
local msg = "Hey there! Your order of "..count.."x "..itemLabel..' has arived at Los Santos post office, come by and take your items!'
local result = exports["lb-phone"]:SendMessage("LS Post Office", phoneNumber, msg, nil)
end
if Config.LBPhone.useMail then
local email = exports["lb-phone"]:GetEmailAddress(phoneNumber)
local msg = "Hey there! Your order of "..count.."x "..itemLabel..' has arived at Los Santos post office, come by and take your items!'
local data = {
to = email,
sender = 'LS Post Office',
subject = 'Delivery Awaiting',
message = msg,
attachments = false,
actions = false,
}
local success, id = exports["lb-phone"]:SendMail(data)
end
end
-- Check if order has been delivered
CreateThread(function()
while true do
Wait(60000) -- Check every minute
-- Fetch all active orders
exports.oxmysql:execute('SELECT * FROM dropship_orders WHERE shipping_timeleft > 0', {}, function(orders)
for _, order in pairs(orders) do
local newTimeLeft = order.shipping_timeleft - 60000 -- Decrement by 60 m seconds
if newTimeLeft <= 0 and not order.player_notified then
-- Notify player
local player = nil
local lbl = GetItemLabel(order.item)
if Config.Framework == 'qb' then
player = Framework.Functions.GetPlayerByCitizenId(order.owner)
if player then
TriggerClientEvent('ox_lib:notify', player.PlayerData.source, {
type = 'success',
title = 'Order Delivered',
description = string.format("Your order of %d x %s has arrived!", order.count, lbl)
})
end
elseif Config.Framework == 'esx' then
player = Framework.GetPlayerFromIdentifier(order.owner)
if player then
TriggerClientEvent('ox_lib:notify', player.source, {
type = 'success',
title = 'Order Delivered',
description = string.format("Your order of %d x %s has arrived!", order.count, lbl)
})
end
end
if Config.LBPhone.enabled then
LBPhone_OrderArived(order.owner, lbl, order.count)
end
-- Mark order as notified
exports.oxmysql:update('UPDATE dropship_orders SET shipping_timeleft = 0, player_notified = 1 WHERE id = ?', { order.id })
else
-- Update remaining time
exports.oxmysql:update('UPDATE dropship_orders SET shipping_timeleft = ? WHERE id = ?', { newTimeLeft, order.id })
end
end
end)
end
end)
-- Phone method meeting customers:
RegisterNetEvent('Domas_Dropship:FoundCustomerPhone', function(src, item, price, quantity)
local sourcePhone = exports["lb-phone"]:GetEquippedPhoneNumber(src)
local callId = exports["lb-phone"]:CreateCall({
phoneNumber = "Customer",
source = src
}, sourcePhone, {
requirePhone = false,
hideNumber = false
})
TriggerClientEvent('Domas_Dropship:CheckIfCall', src, item, price, quantity)
end)
RegisterNetEvent('Domas_Dropship:EndCall', function(src)
exports["lb-phone"]:EndCall(src)
end)
›
⌄
⌄
⌄
⌄
⌄
⌄
⌄
⌄
⌄
CLIENT SIDE CODE
function Negotiate(item, price, quantity)
local discountAsk = math.random(1, Config.Negotiate.maxPercent)
local priceAfterDiscount = price - (price * (discountAsk / 100))
local minAcceptablePrice = price - (price * (discountAsk / 200)) -- Half the NPC's discount
-- Define negotiation options
local options = {
{value = "reject", label = "Get Lost!"},
{value = "counter", label = "Best I can do is "..(discountAsk/2).."% off ("..minAcceptablePrice..")"},
{value = "accept", label = "Sure!"}
}
-- Show the input dialog
local input = lib.inputDialog('Hey, man, I`m really low on money right now, can you give me '..discountAsk..'% off? You`ll still get '..priceAfterDiscount..'$', {
{
type = 'select',
label = 'What is your answer?',
options = options,
required = true
}
})
-- Handle the response
if input then
local choice = input[1]
if choice == "reject" then
return 3, 0
elseif choice == "counter" then
local NPCMove = math.random(0, 100)
Debug("NPCMove "..NPCMove)
if NPCMove <= Config.Negotiate.counterAccept then
return 2, minAcceptablePrice
else
return 3, 0
end
elseif choice == "accept" then
return 1, priceAfterDiscount
end
end
end
function LBPhone_PlacedListing(item, price, quantity)
-- Not really requuired but if you want to you can edit here
end
function HandleSale(npcPed, blip, item, price, quantity)
-- Call server callback to process the sale
local success, message, robbing, negotiate = lib.callback.await('Domas_Dropship:CompleteSale', cache.serverId, item, price, quantity)
-- Notify result
local title = success and Config.Text['sale_complete'] or Config.Text['sale_failed']
local notifyType = success and 'success' or 'error'
Notify(title, message, notifyType)
-- Cleanup target and blip
exports.ox_target:removeZone('sell_item')
RemoveBlip(blip)
if not robbing then
if negotiate then
HandleNegotiation(npcPed, item, price, quantity)
else
PerformHandshake(npcPed)
CleanupNPC(npcPed)
end
else
HandleRobbing(npcPed)
end
end
function HandleNegotiation(npcPed, item, price, quantity)
local negoType, newPrice = Negotiate(item, price, quantity)
if negoType == 1 or negoType == 2 then
-- Accept negotiation and finalize sale
TriggerServerEvent('Domas_Dropship:PoDerybu', cache.serverId, newPrice, item, quantity)
PerformHandshake(npcPed)
elseif negoType == 3 then
-- NPC declines and leaves
NPCLeave(npcPed)
end
end
function HandleRobbing(npcPed)
if math.random(1, 2) == 1 then
NPCLeave(npcPed)
else
FreezeEntityPosition(npcPed, false)
TaskCombatPed(npcPed, cache.ped, 0, 16)
GiveWeaponToPed(npcPed, Config.PedRobbingWeapon, Config.PedRobbingAmmo, false, true)
Wait(Config.PedRobbingTime)
DeleteEntity(npcPed)
end
end
function CleanupNPC(npcPed)
FreezeEntityPosition(npcPed, false)
TaskWanderStandard(npcPed, 10.0, 10)
Wait(10000)
DeleteEntity(npcPed)
end
function NPCLeave(npcPed)
FreezeEntityPosition(npcPed, false)
TaskGoToCoordAnyMeans(npcPed, 0.0, 0.0, 0.0, 3.0, 0, 0, 786603, 0)
Wait(10000)
DeleteEntity(npcPed)
end
function PerformHandshake(npcPed)
FreezeEntityPosition(npcPed, false)
Wait(100)
FreezeEntityPosition(cache.ped, true)
if Config.EnableHandshake then StartHandShake(cache.ped, npcPed) end
ClearPedTasksImmediately(npcPed)
FreezeEntityPosition(cache.ped, false)
CleanupNPC(npcPed)
end
function SalesInteraction(npcPed, blip, item, price, quantity, npcCoords)
exports.ox_target:addBoxZone({
coords = npcCoords,
size = vector3(1.5, 1.5, 3.0),
debug = Config.Debug,
name = 'sell_item',
options = {
{
icon = 'fas fa-dollar-sign',
label = Config.Text['sell_items'],
onSelect = function()
HandleSale(npcPed, blip, item, price, quantity)
end
}
}
})
end
function GetInput_PlaceForSale(maxPRC, maxQNT)
-- Show the input dialog
local input = lib.inputDialog(Config.Text['place_for_sale'], {{
type = 'number',
label = Config.Text['enter_price'],
description = Config.Text['enter_price_description'],
required = true,
icon = 'hashtag',
min = 1,
max = maxPRC
}, {
type = 'number',
label = Config.Text['enter_quantity'],
description = Config.Text['enter_quantity_description'],
required = true,
icon = 'hashtag',
min = 1,
max = maxQNT
}})
return input
end
function PurchaseItem_Dialog(minValue, maxValue)
local input = lib.inputDialog(Config.Text['order_quantity'], {
{
type = 'number',
label = Config.Text['enter_quantity'],
min = minValue,
max = maxValue
}
})
return input
end
-- Resource Initialization
CreateThread(function()
if Config.Enable_DropshipPlaces then
for _, dropship in pairs(Config.DropshipPlaces) do
-- Adding a target at the specified location
exports.ox_target:addBoxZone({
coords = dropship.location,
size = dropship.size,
rotation = dropship.rotation,
debug = dropship.debug,
options = {
{
name = 'dropshipping_menu',
event = 'Domas_Dropship:OpenDropshipMenu',
icon = 'fas fa-box',
label = dropship.label,
}
}
})
end
end
end)
CreateThread(function()
if Config.Enable_PostPlaces then
for _, post in pairs(Config.PostPlaces) do
exports.ox_target:addBoxZone({
coords = post.location,
size = post.size,
rotation = post.rotation,
debug = post.debug,
options = {
{
name = 'post_menu',
icon = 'fas fa-box',
label = post.label,
onSelect = function()
TriggerEvent('Domas_Dropship:OpenPostMenu')
end
}
}
})
end
end
end)
-- Notify the player when their items has been ordered
RegisterNetEvent('Domas_Dropship:StartSaleTimer', function(waitTime, item, price, quantity)
local player = PlayerPedId()
local timer = waitTime / 1000 -- Convert from milliseconds to seconds
local label = GetItemLabel(item)
if not Config.LBPhone.enabled then
-- Start the timer
SetTimeout(waitTime, function()
local status, result = pcall(function()
return lib.alertDialog({
header = 'Sale Ready',
content = ('Your sale for %s x%d at $%d is ready! Confirm to spawn the customer NPC and set a waypoint.'):format(label, quantity, price),
cancel = true, -- Enable cancel button
labels = {
confirm = 'Confirm',
cancel = 'Cancel'
}
})
end)
-- Handle error
if not status then
-- Log the error for debugging
print('Error in alertDialog:', result)
-- Notify the player about the issue (if needed)
lib.notify({
title = 'Error',
description = 'There was an issue displaying the dialog. Please try again.',
type = 'error'
})
return
end
-- Logic after alertDialog resolves successfully
if result == 'confirm' then
-- Call the continuation function if confirmed
Cont(item, price, quantity)
else
Debug("Sale was not confirmed.") -- Optional message
end
end)
else
SetTimeout(waitTime, function()
TriggerServerEvent('Domas_Dropship:FoundCustomerPhone', cache.serverId, item, price, quantity)
end)
end
end)
RegisterNetEvent('Domas_Dropship:CheckIfCall', function(item, price, quantity)
local startTime = GetGameTimer() -- Get the current game time in milliseconds
local inCall = false
-- Check the call status for 5 seconds
Citizen.CreateThread(function()
while GetGameTimer() - startTime < 10000 do -- 10000 ms = 10 seconds
inCall = exports["lb-phone"]:IsInCall() -- Check if in a call
if inCall then
-- If in call, break the loop and trigger the appropriate event
Cont(item, price, quantity)
TriggerServerEvent('Domas_Dropship:EndCall', cache.serverId)
return -- Exit the loop early
end
Citizen.Wait(500) -- Wait for 100ms before checking again
end
if not inCall then
TriggerServerEvent('Domas_Dropship:EndCall', cache.serverId)
end
end)
end)
-- Function to create a blip at a specific location
local function createBlip(location, sprite, color, size, name)
local blip = AddBlipForCoord(location.x, location.y, location.z)
SetBlipSprite(blip, sprite)
SetBlipColour(blip, color)
SetBlipScale(blip, size)
BeginTextCommandSetBlipName("STRING")
AddTextComponentString(name)
EndTextCommandSetBlipName(blip)
SetBlipAsShortRange(blip, true)
end
-- Create dropship blips if enabled
if Config.Enable_DropshipPlaces then
for _, dropPlace in pairs(Config.DropshipPlaces) do
if dropPlace.blip then
createBlip(dropPlace.location, dropPlace.blip.sprite, dropPlace.blip.color, dropPlace.blip.size, dropPlace.blip.name)
end
end
end
-- Create post blips if enabled
if Config.Enable_PostPlaces then
for _, postPlace in pairs(Config.PostPlaces) do
if postPlace.blip then
createBlip(postPlace.location, postPlace.blip.sprite, postPlace.blip.color, postPlace.blip.size, postPlace.blip.name)
end
end
end
function DrawText3D(x, y, z, text)
if not Config.Enable3dText then return end
local onScreen, _x, _y = World3dToScreen2d(x, y, z)
local px, py, pz = table.unpack(GetGameplayCamCoords())
local dist = #(vector3(px, py, pz) - vector3(x, y, z))
local scale = (dist / 10)
if onScreen then
SetTextScale(0.7 * scale, 0.7 * scale)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry("STRING")
AddTextComponentString(text)
DrawText(_x, _y)
end
end
function Notify(title, text, type)
lib.notify({
title = title,
description = text,
type = type
})
end
RegisterNetEvent('Domas_Dropship:Notify', function(title, text, type)
Notify(title, text, type)
end)
RegisterNetEvent('Domas_Dropship:ListingRemoved', function(itemName)
Notify(Config.Text['listing_removed'], '', 'success')
end)
RegisterNetEvent('Domas_Dropship:ListingRemoveFailed', function()
Notify(Config.Text['remove_failed'], '', 'success')
end)
›
⌄
⌄
⌄
Last updated on
Was this page helpful?
Next to read:
Domas_VehicleShopnull
Discard Changes
Do you want to discard your current changes and overwrite with the template?
Archive Synced Block
Message
Create new Template
What is this template's title?
Delete Template
Message