📃Configs
Config = {}
-- Debug System
Config.Debug = false -- Enable or disable debug messages
-- Locale ( "en" )
Config.Locale = 'en'
-- Framework settings ( "auto", "QBCore", "ESX" )
Config.Framework = "auto"
-- Target settings ( "auto", "qb-target", "ox_target" )
Config.Target = "auto"
-- Inventory settings ( "auto", "qb-inventory", "ox_inventory" )
Config.Inventory = "auto"
-- Progress bar settings ( "auto", "qb-core", "ox_lib", "lation_ui" )
Config.ProgressBar = "auto"
-- Notification settings ( "auto", "qb", "okok", "ox_lib", "lation_ui" )
Config.Notify = "auto"
-- Display settings ( "auto", "ox_lib", "lation_ui" )
Config.Display = "lation_ui"
-- Date Format
Config.DateFormat = "%d/%m/%Y %H:%M"
-- Auto Database
Config.AutoDatabase = true -- Enable or disable automatic database setup
-- Job Sections
Config.JobsAllowed = { "court" } -- Jobs that have access to court system
-- Currency
Config.Currency = "$"
-- Email System ( Only works on lb-phone )
Config.EmailSystem = true -- Enable or disable email notifications
Config.SenderEmail = "court@city.gov"
-- Force payments
Config.ForcePayment = true -- Enable or disable forced fine payments
Config.ForcePaymentDays = 7 -- Days need fine to be paid before forcing payment
-- Judge Elections
Config.VoteJudgeCandidates = true 
-- Tax Systems
Config.TaxSystem = true -- Enable or disable tax system for fines
Config.BusinessTaxDays = 7 -- Days between each tax deduction
Config.TaxSettings = {
    available = { "items", "vehicles", "properties" }, -- Types of assets that can be taxed
    min_tax = 1, -- Minimum tax amount 1%
    max_tax = 5, -- Maximum tax amount 5%
}
-- Name Change
Config.NameChange = {
    enable = true, -- Enable or disable name change feature
    badwords = { "fuck", "shit", "bitch" }, -- List of prohibited words
}
-- Jail System
Config.JailSystem = {
    enable = true, -- Enable or disable jail system
    script = "default", -- Jail script to use (default/ xt-prison / rcore_prison / pickle_prisons / DHS-PrisonSim)
    max_jail_time = 120, -- Maximum jail time in minutes
    coords_enter = vector4(1650.09, 2545.32, 45.56, 49.1), -- Jail entrance coordinates
    coords_release = vector4(1848.52, 2585.98, 45.67, 269.53), -- Jail release coordinates
}
-- Boss Menu
Config.BossMenu = {
    enable = true, -- Enable or disable boss menu
    grade_required = 0, -- Minimum job grade required to access boss menu
    script = "qb-core", -- Boss menu script to use (default/ qb-core / esx / Ricky-BossMenu / vms_bossmenu) 
}
Config.CourtLocations = {
    [1] = {
        name = "Reception", -- Name of the location
        ped_options = { -- Ped options
            enable = true,
            ped_model = "s_f_y_airhostess_01",
            ped_coords = vec4(-1643.94, 177.12, 61.76, 295.92),
        },
        target_options = { -- Target options
            coords = vec3(-1643.94, 177.12, 61.76),
            range = 2.0,
            height = 1.0,
            debug = false,
            options = {
                {
                    icon = "fas fa-gavel",
                    label = "Talk to Receptionist",
                    onSelect = function ()
                        ReceptionistMenu()
                    end,
                    groups = { "all" },
                },
            },
        },
    },
    [2] = {
        name = "Courtroom", -- Name of the location
        ped_options = { -- Ped options
            enable = false,
            ped_model = "s_m_y_hwaycop_01",
            ped_coords = vec4(-1650.86, 180.13, 61.76, 24.02),
        },
        target_options = { -- Target options
            coords = vec3(-1650.86, 180.13, 61.76),
            range = 2.0,
            height = 1.0,
            debug = false,
            options = {
                {
                    icon = "fas fa-gavel",
                    label = "Court Clerk",
                    onSelect = function ()
                        CourtHouseMenu()
                    end,
                    groups = { "judge" },
                },
            },
        },
    },
    [3] = {
        name = "Judge Room",
        ped_options = { -- Ped options
            enable = false,
            ped_model = "s_m_y_hwaycop_01",
            ped_coords = vec4(-1647.56, 186.23, 61.76, 156.54),
        },
        target_options = { -- Target options
            coords = vector3(-1646.17, 170.12, 61.75),
            range = 2.0,
            height = 1.0,
            debug = false,
            options = {
                {
                    icon = "fas fa-gavel",
                    label = "Judge's Clerk",
                    onSelect = function ()
                        JudgeRoomMenu()
                    end,
                    groups = { "judge" },
                },
            },
        },
    }
}
-- Exames to get bar license or mechanic license
Config.MinQuestion = 2 -- Minimum correct answers to pass the exam
Config.Exames = {
    ["Bar"] = {
        item = "bar_license", -- Item given upon passing the exam
        questions = {
            {
                question = "What is the legal drinking age in most countries?",
                options = {
                    { answer = "18 years old", correct = true },
                    { answer = "16 years old", correct = false },
                    { answer = "21 years old", correct = false },
                    { answer = "25 years old", correct = false },
                }
            },
            {
                question = "What should you do if a customer appears intoxicated?",
                options = {
                    { answer = "Refuse to serve them more alcohol", correct = true },
                    { answer = "Serve them water and continue serving alcohol", correct = false },
                    { answer = "Ignore their condition", correct = false },
                    { answer = "Encourage them to drink more slowly", correct = false },
                }
            },
            {
                question = "What is 'binge drinking'?",
                options = {
                    { answer = "Consuming a large amount of alcohol in a short period", correct = true },
                    { answer = "Drinking alcohol with food", correct = false },
                    { answer = "Drinking alcohol socially", correct = false },
                    { answer = "Drinking alcohol at home", correct = false },
                }
            }
        }
    },
    ["Mechanic"] = {
        item = "mechanic_license", -- Item given upon passing the exam
        questions = {
            {
                question = "What is the difference between civil and criminal law?",
                options = {
                    { answer = "Civil law deals with disputes between individuals, while criminal law deals with offenses against the state", correct = true },
                    { answer = "Civil law is more serious than criminal law", correct = false },
                    { answer = "Criminal law only applies to government officials", correct = false },
                    { answer = "There is no difference", correct = false },
                }
            },
            {
                question = "What is 'precedent' in legal terms?",
                options = {
                    { answer = "A previous court decision that influences future cases", correct = true },
                    { answer = "A type of legal document", correct = false },
                    { answer = "A courtroom procedure", correct = false },
                    { answer = "A form of punishment", correct = false },
                }
            },
            {
                question = "What does 'burden of proof' mean?",
                options = {
                    { answer = "The obligation to prove one's assertion in a legal case", correct = true },
                    { answer = "A type of legal document", correct = false },
                    { answer = "A courtroom procedure", correct = false },
                    { answer = "A form of punishment", correct = false },
                }
            }
        }
    },
    ["Attorney"] = {
        item = "attorney_license", -- Item given upon passing the exam
        questions = {
            {
                question = "What is the primary role of an attorney?",
                options = {
                    { answer = "To represent clients in legal matters", correct = true },
                    { answer = "To preside over court proceedings", correct = false },
                    { answer = "To enforce laws", correct = false },
                    { answer = "To create new laws", correct = false },
                }
            },
            {
                question = "What does 'client-attorney privilege' refer to?",
                options = {
                    { answer = "Confidentiality between a lawyer and their client", correct = true },
                    { answer = "A type of legal document", correct = false },
                    { answer = "A courtroom procedure", correct = false },
                    { answer = "A form of punishment", correct = false },
                }
            },
            {
                question = "What is a 'plea bargain'?",
                options = {
                    { answer = "An agreement in a criminal case where the defendant pleads guilty for a lesser charge", correct = true },
                    { answer = "A type of legal document", correct = false },
                    { answer = "A courtroom procedure", correct = false },
                    { answer = "A form of punishment", correct = false },
                }
            }
        }
    },
    ["Judge"] = {
        item = "judge_license",
        questions = {
            {
                question = "What is the main responsibility of a judge?",
                options = {
                    { answer = "To preside over court proceedings and make rulings", correct = true },
                    { answer = "To represent clients in legal matters", correct = false },
                    { answer = "To enforce laws", correct = false },
                    { answer = "To create new laws", correct = false },
                }
            },
            {
                question = "What does 'due process' refer to?",
                options = {
                    { answer = "Fair treatment through the normal judicial system", correct = true },
                    { answer = "A type of legal document", correct = false },
                    { answer = "A courtroom procedure", correct = false },
                    { answer = "A form of punishment", correct = false },
                }
            },
            {
                question = "What is 'judicial review'?",
                options = {
                    { answer = "The power of courts to assess the constitutionality of laws", correct = true },
                    { answer = "A type of legal document", correct = false },
                    { answer = "A courtroom procedure", correct = false },
                    { answer = "A form of punishment", correct = false },
                }
            }
        }
    }
}
if (Config.Framework == "auto" and GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started") or Config.Framework == "QBCore" then
    QBCore = exports['qb-core']:GetCoreObject()
elseif (Config.Framework == "auto" and GetResourceState("es_extended") == "started") or Config.Framework == "ESX" then
    ESX = exports.es_extended:getSharedObject()
end
function Notify(title, text, type)
    if (Config.Notify == "auto" and GetResourceState("qb-core") == "started") or Config.Notify == "qb" then
        QBCore.Functions.Notify(text, type, 5000)
    elseif (Config.Notify == "auto" and GetResourceState("okokNotify") == "started") or Config.Notify == "okok" then
        exports['okokNotify']:Alert(title, text, 5000, type, true)
    elseif (Config.Notify == "auto" and GetResourceState("ox_lib") == "started") or Config.Notify == "ox_lib" then
        lib.notify({ title = title, description = text, type = type })
    elseif (Config.Notify == "auto" and GetResourceState("lation_ui") == "started") or Config.Notify == "lation_ui" then
        exports.lation_ui:notify({ title = title, message = text, type = type })
    end
end
function HasJob()
    if (Config.Framework == "auto" and GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started") or Config.Framework == "QBCore" then
        local playerData = QBCore.Functions.GetPlayerData()
        for _, job in ipairs(Config.JobsAllowed) do
            if playerData.job.name == job then
                return true
            end
        end
    elseif (Config.Framework == "auto" and GetResourceState("es_extended") == "started") or Config.Framework == "ESX" then
        local playerData = ESX.GetPlayerData()
        for _, job in ipairs(Config.JobsAllowed) do
            if playerData.job.name == job then
                return true
            end
        end
    end
    return false
end
function ProgressBar(time, label, animDict, anim, cb)
    if (Config.ProgressBar == "auto" and GetResourceState("qb-core") == "started") or Config.ProgressBar == "qb-core" then
        QBCore.Functions.Progressbar("ProgressBar", label, time, false, true, {
            disableMovement = true,
            disableCarMovement = true,
            disableMouse = false,
            disableCombat = true,
        }, {
            animDict = animDict,
            anim = anim,
            flags = 16,
        }, {}, {}, function()
            if cb then cb(true) end
        end, function()
            if cb then cb(false) end
        end)
    elseif (Config.ProgressBar == "auto" and GetResourceState("ox_lib") == "started") or Config.ProgressBar == "ox_lib" then
        local success = lib.progressBar({
            duration = time,
            label = label,
            useWhileDead = false,
            canCancel = true,
            controlDisables = {
                disableMovement = true,
                disableCarMovement = true,
                disableMouse = false,
                disableCombat = true,
            },
            animation = {
                dict = animDict,
                clip = anim,
            },
        })
        if cb then cb(success) end
    elseif (Config.ProgressBar == "auto" and GetResourceState("lation_ui") == "started") or Config.ProgressBar == "lation_ui" then
        local success = exports['lation_ui']:Progress({
            duration = time,
            label = label,
            useWhileDead = false,
            canCancel = true,
            controlDisables = {
                disableMovement = true,
                disableCarMovement = true,
                disableMouse = false,
                disableCombat = true,
            },
            animation = {
                dict = animDict,
                clip = anim,
            },
        })
        if cb then cb(success) end
    end
end
function RegisterContextMenu(id, title, options)
    if (Config.Display == "auto" and GetResourceState("ox_lib") == "started") or Config.Display == "ox_lib" then
        lib.registerContext({ id = id, title = title, options = options })
        lib.showContext(id)
    elseif (Config.Display == "auto" and GetResourceState("lation_ui") == "started") or Config.Display == "lation_ui" then
        exports.lation_ui:registerMenu({ id = id, title = title, options = options })
        exports.lation_ui:showMenu(id)
    end
end
function ShowContextMenu(id)
    if (Config.Display == "auto" and GetResourceState("ox_lib") == "started") or Config.Display == "ox_lib" then
        lib.showContext(id)
    elseif (Config.Display == "auto" and GetResourceState("lation_ui") == "started") or Config.Display == "lation_ui" then
        exports.lation_ui:showMenu(id)
    end
end
function HideContextMenu()
    if (Config.Display == "auto" and GetResourceState("ox_lib") == "started") or Config.Display == "ox_lib" then
        lib.hideContext()
    elseif (Config.Display == "auto" and GetResourceState("lation_ui") == "started") or Config.Display == "lation_ui" then
        exports.lation_ui:hideMenu()
    end
end
function GetUserInput(title, fields)
    if (Config.Display == "auto" and GetResourceState("ox_lib") == "started") or Config.Display == "ox_lib" then
        return lib.inputDialog(title, fields)
    elseif (Config.Display == "auto" and GetResourceState("lation_ui") == "started") or Config.Display == "lation_ui" then
        return exports.lation_ui:input({
            title = title or "",
            options = fields
        })
    end
end
function ShowAlertDialog(header, content, labels)
    labels = labels or { confirm = "Confirm", cancel = "Cancel" }
    if (Config.Display == "auto" and GetResourceState("ox_lib") == "started") or Config.Display == "ox_lib" then
        return lib.alertDialog({
            header = header,
            content = content,
            centered = true,
            cancel = true,
            labels = labels
        })
    elseif (Config.Display == "auto" and GetResourceState("lation_ui") == "started") or Config.Display == "lation_ui" then
        local result = exports.lation_ui:alert({
            title = header,
            content = content,
            confirmText = labels.confirm,
            cancelText = labels.cancel
        })
        return result == true and "confirm" or "cancel"
    end
end
function ShowTextUI(text)
    if (Config.Display == "auto" and GetResourceState("ox_lib") == "started") or Config.Display == "ox_lib" then
        lib.showTextUI(text)
    elseif (Config.Display == "auto" and GetResourceState("lation_ui") == "started") or Config.Display == "lation_ui" then
        exports.lation_ui:showText({ description = text })
    elseif (Config.Display == "auto" and GetResourceState("okokTextUI") == "started") or Config.Display == "okokTextUI" then
        exports['okokTextUI']:Open('[E] ' .. text, 'lightblue ', 'right', true)
    end
end
function HideTextUI()
    if (Config.Display == "auto" and GetResourceState("ox_lib") == "started") or Config.Display == "ox_lib" then
        lib.hideTextUI()
    elseif (Config.Display == "auto" and GetResourceState("lation_ui") == "started") or Config.Display == "lation_ui" then
        exports.lation_ui:hideText()
    elseif (Config.Display == "auto" and GetResourceState("okokTextUI") == "started") or Config.Display == "okokTextUI" then
        exports['okokTextUI']:Close()
    end
end
function GetImageFromInventory(item)
    if GetResourceState("qb-inventory") == "started" then
        local qbItem = QBCore.Shared.Items[item]
        return qbItem and "nui://qb-inventory/html/images/" .. qbItem.image
    elseif GetResourceState("ox_inventory") == "started" then
        local oxItem = exports.ox_inventory:Items(item)
        return oxItem and oxItem.client and oxItem.client.image
    end
end
function GetItemLabelFromInventory(item)
    if GetResourceState("qb-inventory") == "started" then
        return QBCore.Shared.Items[item] and QBCore.Shared.Items[item].label or item
    elseif GetResourceState("ox_inventory") == "started" then
        local oxItem = exports.ox_inventory:Items(item)
        return oxItem and oxItem.label or item
    end
end
function GetPlayerJob()
    if (Config.Framework == "auto" and GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started") or Config.Framework == "QBCore" then
        return QBCore.Functions.GetPlayerData().job.name
    elseif (Config.Framework == "auto" and GetResourceState("es_extended") == "started") or Config.Framework == "ESX" then
        return ESX.GetPlayerData().job.name
    end
end
function GetPlayerJobGrade()
    if (Config.Framework == "auto" and GetResourceState("qb-core") == "started" or GetResourceState("qbx_core") == "started") or Config.Framework == "QBCore" then
        return QBCore.Functions.GetPlayerData().job.grade.level
    elseif (Config.Framework == "auto" and GetResourceState("es_extended") == "started") or Config.Framework == "ESX" then
        return ESX.GetPlayerData().job.grade
    end
end
function OpenBossMenu()
    if not Config.BossMenu.enable then return end
    local playerJobGrade = GetPlayerJobGrade()
    if playerJobGrade < Config.BossMenu.grade_required then
        Notify("Error", "You do not have permission to access the boss menu.", "error")
        return
    end
    if Config.BossMenu.script == "qb-core" then
       TriggerEvent("qb-bossmenu:client:OpenMenu", "court")
    elseif Config.BossMenu.script == "esx" then
        TriggerEvent('esx_society:openBossMenu', "court", function(data, menu)
        end, {})
    elseif Config.BossMenu.script == "Ricky-BossMenu" then
        exports['Ricky-BossMenu']:OpenBossMenu("court")
    elseif Config.BossMenu.script == "vms_bossmenu" then
        exports['vms_bossmenu']:openBossMenu("court", "job")
    else
        if Config.Debug then
            print("Boss menu script not recognized. Please check your configuration.")
        end
    end
endLast updated
