Configuration

config.lua
Config = {Locales = {}}

Config.Framework = '' --  'qb', 'esx', 'custom' -- setup custom in bridges/custom/custom_bridge.lua

--[[
    Only required if Config.Framework = 'esx'
    Options:
        'new' -- v1.8.5-latest
        'old' -- v1 - v.1.8.5
]]
Config.ESXVersion = 'new'

Config.Phone = '' -- options: 'qb-phone', 'quasar', 'gksphone', 'lbphone', 'yflip', 'okokPhone', 'jpr-phonesystem', 'custom' -- for mail -- setup custom in config/sv_customizable_functions.lua

Config.Interface = {
    Menu = 'ox', -- options 'qb', 'ox', 'custom' -- editable in cl_customizable_functions.lua
    Input = 'ox', -- options 'qb', 'ox', 'custom' -- editable in cl_customizable_functions.lua
    Notifications = 'ox', -- options 'esx', 'qb', 'ox', 'custom' -- editable in cl_customizable_functions.lua
    TextUI = 'ox' -- options 'esx', 'qb', 'ox', 'custom' -- editable in cl_customizable_functions.lua
}

Config.Zones = 'ox' -- options 'PolyZone', 'ox', 'custom' -- editable in cl_customizable_functions.lua

Config.Target = false  -- true/false

Config.DeputyVoting = { -- additional setting for deputy voting to allow or prohibit president and chairman from vote on deputy votes
    president = true, -- true if you want to allow the president to vote in deputies votings, false if you don't want to.
    chairman = true -- true if you want to allow the chairman to vote in deputies votings, false if you don't want to.
}

Config.Translation = 'en' -- check in 'locales' folder

Config.TaxSystem = 1 -- option 1 = tax not included in price, option 2 = tax included in price || example for 20% tax: (1 = player will pay 12$ for 10$ product) (2 = player will pay 10$ for 10$ product but shop recieves 8$)

Config.PartyManagement = { -- commands for the politcal parties
    manageParty = "managepp",
    checkMyParty = "pp",
    leaveParty = "leavepp"
}

Config.LawsCommand = { -- command and keybind for opening the laws menu. Keybind can be changed in-game from the FiveM options menu!
    commandName = 'laws',
    keyBind = 'B',
}

Config.Blips = {
    townhall = {
        show = true,
        sprite = 525, -- https://docs.fivem.net/docs/game-references/blips/
        color = 0, -- https://docs.fivem.net/docs/game-references/blips/
        size = 0.8, -- has to be in decimals
        label = 'Town Hall',
        coords = vector3(-556.03, -193.58, 38.23)
    }
}

Config.Icons = { -- check compatible icons depending on what interface (menu/input) you use - default https://fontawesome.com (compatible with ox/qb)
    ['Manage Members'] = 'fas fa-users',
    ['Create Election'] = 'fas fa-users',
    ['End Election'] = 'fas fa-vote-yea',
    ['Ban From Elections'] = 'fas fa-ban',
    ['Unban From Elections'] = 'fas fa-check-square',
    ['Clear Player Votes'] = 'fas fa-eraser',
    ['Announcement'] = 'fas fa-paper-plane',
    ['Hire Deputy'] = 'fas fa-briefcase',
    ['Fire Deputy'] = 'fas fa-sign-out-alt',
    ['Money Management'] = 'fas fa-university',
    ['Money Deposit'] = 'fas fa-donate',
    ['Money Withdraw'] = 'fas fa-money-bill-wave',
    ['Election Options'] = 'fas fa-print',
    ['Political Parties Options'] = 'fas fa-user-slash',
    ['Other Options'] = 'fas fa-paper-plane',
    ['President Menu'] = 'fas fa-flag',
    ['Conference Menu'] = 'fas fa-book-open',
    ['Conference Menu Title'] = 'fas fa-bookmark',
    ['Party Application'] = 'fas fa-book-open',
    ['Party Application Title'] = 'fas fa-bookmark',
    ['Party Applications List'] = 'fas fa-print',
    ['Voting Menu'] = 'fas fa-print',
    ['Party Rename'] = 'fas fa-pen',
    ['Party Disband'] = 'fas fa-trash',
    ['Manage Political Parties'] = 'fas fa-list',
    ['Tax Management'] = 'fas fa-money-bill',
    ['Income Tax'] = 'fas fa-percent',
    ['VAT Tax'] = 'fas fa-percent'
}

Config.Job = {
    jobname = 'politician',
    joblabel = 'Politician',
    grades = { --- do not change keys (president, chairman, deputy), only change numbers of grades (if wanted), and keep the order of numbers from lower perms to higher perms
        president = 2,
        chairman = 1,
        deputy = 0
    }
}

Config.PresidentMenu = {
    targetCoords = vector3(-528.66, -188.68, 42.95),
    pedHeading = 121.93,
}

Config.ConferenceRoom = {
    targetCoords = vector3(-534.69, -178.28, 43.80), -- location of the conference menu
    roomCoords = vector3(-537.2, -179.84, 44.26), -- put the center of the room
    radius = 15, -- the radius from the room coords where deputies can vote ( we don't want someone who is not in the hall to vote so that's why we are using this )
}

Config.Application = {
    ped = {
        pedModel = 'cs_bankman',
        pedCoords = vector3(-542.43, -197.23, 38.24),
        pedHeading = 77.25,
    },
}

Config.VotingLocation = {
    {
        points = { -- acts as points for polyzone/qb-target/ox_target/ox_lib
            vector3(-541.32, -183.47, 37.23),
            vector3(-543.91, -179.28, 37.23),
            vector3(-542.76, -178.18, 37.23),
            vector3(-540.39, -182.63, 37.23)
        },
        label = 'Vote'
    },
    {
        points = { -- acts as points for polyzone/qb-target/ox_target/ox_lib
            vector3(-535.76, -174.53, 37.23),
            vector3(-533.43, -178.4, 37.23),
            vector3(-534.19, -173.66, 37.23),
            vector3(-531.93, -177.52, 37.23)
        },
        label = 'Vote',
        coords = {
            vector3(-542.92, -179.23, 38.23),
            vector3(-542.11, -180.59, 38.23),
            vector3(-541.32, -181.97, 38.23)
        }
    }
}

function Translate(msg, ...)
    if Config.Locales[Config.Translation] then
        if Config.Locales[Config.Translation][msg] then
            return string.format(Config.Locales[Config.Translation][msg], ...)
        elseif Config.Translation ~= 'en' and Config.Locales['en'] and Config.Locales['en'][msg] then
            return string.format(Config.Locales['en'][msg], ...)
        else
            return 'Translation ['.. Config.Translation ..'] ['..msg..'] does not exist.'
        end
    elseif Config.Translation ~= 'en' and Config.Locales['en'] and Config.Locales['en'][msg] then
        return string.format(Config.Locales['en'][msg], ...)
    else
        return 'Translation ['.. Config.Translation .. '] not found.'
    end
end
webhooks.lua
Webhooks = {}

Webhooks.Array = {
    civilian_voting = '',
    deputies_voting = ''
}

Webhooks.BotName = 'Mr. Politics'
Webhooks.Header = 'Political System'
Webhooks.ProfilePicture = 'https://cdn.discordapp.com/attachments/1204869666493829184/1214581454651138088/BK.png?ex=65f9a220&is=65e72d20&hm=614a763e06556de7b8912775e0f5f7b2b18c8d1d9079edb4e5dfb370e206ada9&'

--[[
    blue = 255,
    red = 16711680,
    green = 65280,
    white = 16777215,
    black = 0,
    orange = 16744192,
    yellow = 16776960,
    pink = 16761035,
    lightgreen = 65309,
]]
Webhooks.Color = '255'
cl_customizable_functions.lua
function Notification(msg, type, duration)
    if Config.Interface.Notifications == 'qb' then
        QBCore.Functions.Notify(msg, type, duration)
    elseif Config.Interface.Notifications == 'ox' then
        lib.notify({id = msg, title = Translate('notificationTitle'), description = msg, duration = duration, type = type})
    elseif Config.Interface.Notifications == 'esx' then
        ESX.ShowNotification(msg)
    elseif Config.Interface.Notifications == 'custom' then
        -- your custom function
    end
end

function ShowTextUi(msg)
    if Config.Interface.TextUI == 'qb' then
        exports['qb-core']:DrawText(msg, 'right')
    elseif Config.Interface.TextUI == 'ox' then
        lib.showTextUI(msg)
    elseif Config.Interface.TextUI == 'esx' then
        ESX.TextUI(msg)
    elseif Config.Interface.TextUI == 'custom' then
        -- your custom function
    end
end

function HideTextUi()
    if Config.Interface.TextUI == 'qb' then
        exports['qb-core']:HideText()
    elseif Config.Interface.TextUI == 'ox' then
        lib.hideTextUI()
    elseif Config.Interface.TextUI == 'esx' then
        ESX.HideUI()
    elseif Config.Interface.TextUI == 'custom' then
        -- your custom function
    end
end

function Menu(arg)
    if Config.Interface.Menu == 'qb' then
        return exports['qb-menu']:openMenu(arg)
    elseif Config.Interface.Menu == 'ox' then
        return oxlibMenuHandler(arg)
    elseif Config.Interface.Menu == 'custom' then
        -- your custom function
    end
end

function Input(arg)
    if Config.Interface.Input == 'qb' then
        return exports['qb-input']:ShowInput(arg)
    elseif Config.Interface.Input == 'ox' then
        return oxlibInputHandler(arg)
    elseif Config.Interface.Input == 'custom' then
        -- your custom function
    end
end

function AddCircleZone(name, coords, radius, options1, options2)
    return exports['qb-target']:AddCircleZone(name, coords, radius, options1, options2) --qb-target/ox_target
end

function AddTargetEntity(name, options)
    return exports['qb-target']:AddTargetEntity(name, options) --qb-target/ox_target
end

function AddPolyZone(name, coords, options1, options2)
    return exports['qb-target']:AddPolyZone(name, coords, options1, options2) --qb-target/ox_target
end

function RemoveZone(name)
    pcall(function()
        return exports['qb-target']:RemoveZone(name)
    end) -- qb-target/ox_target
end

function PolyZoneCreation(points, data, playerInsideHandler)
    if Config.Zones == 'PolyZone' then
        local zone = PolyZone:Create(points, data)
        zone:onPlayerInOut(playerInsideHandler)

    elseif Config.Zones == 'ox' then
        local pointsConverted = {}
        for i = 1, #points do
            pointsConverted[i] = vector3(points[i].x, points[i].y, data.minZ + 1)
        end
        lib.zones.poly({
            points = pointsConverted,
            thickness = 4,
            onEnter = function() playerInsideHandler(true) end,
            onExit = function() playerInsideHandler(false) end
        })

    elseif Config.Zones == 'custom' then
        -- your custom zones handler
    end
end

function CircleZoneCreation(coords, radius, data, playerInsideHandler)
    if Config.Zones == 'PolyZone' then
        local zone = CircleZone:Create(coords, radius, data)
        zone:onPlayerInOut(playerInsideHandler)

    elseif Config.Zones == 'ox' then
        lib.zones.sphere({
            coords = coords,
            radius = radius,
            onEnter = function() playerInsideHandler(true) end,
            onExit = function() playerInsideHandler(false) end
        })

    elseif Config.Zones == 'custom' then
        -- your custom zones handler
    end
end
sv_customizable_functions.lua
function SendEMail(target, title, message)
    if Config.Phone == 'qb-phone' then
        QBphoneEmail(target, title, message)

    elseif Config.Phone == 'quasar' then
        TriggerClientEvent('bk_politicalsystem:client:quasarIntegration', target, title, message)

    elseif Config.Phone == 'gksphone' then
        local mailData = {
            sender = Translate('president_mail'),
            image = '/html/static/img/icons/mail.png',
            subject = title,
            message = message
        }
        exports['gksphone']:SendNewMail(target, mailData)

    elseif Config.Phone == 'lbphone' then
        local phoneNumber = exports['lb-phone']:GetEquippedPhoneNumber(target)
        local email = exports['lb-phone']:GetEmailAddress(phoneNumber)
        exports['lb-phone']:SendMail({
            to = email,
            subject = Translate('president')..' - '..title,
            message = message
        })

    elseif Config.Phone == 'yflip' then
        exports['yflip-phone']:SendMail({
            title = title,
            sender = Translate('president_mail'),
            senderDisplayName = Translate('president'),
            content = message
        }, 'source', target)

    elseif Config.Phone == 'okokPhone' then
        local email = exports['okokPhone']:getEmailAddressFromSource(target)

        exports['okokPhone']:sendEmail({
			sender = Translate('president_mail'),
            recipients = {email},
            subject = Translate('president')..' - '..title,
            body = message,
        })

    elseif Config.Phone == 'jpr-phonesystem' then
        TriggerEvent('jpr-phonesystem:server:sendEmail', {
            subject = title,
            message = message,
            sender = Translate('president_mail'),
            event = {},
        }, target)

    elseif Config.Phone == 'custom' then
        -- your custom function
    end
end

function SendDiscordMessage(webhook, title, fields, color)
    if not Webhooks.Array[webhook] then return end

    local webhook = Webhooks.Array[webhook]
    local data = {
        {
            ['title'] = title,
            ['color'] = color or Webhooks.Color,
            ['footer'] = {
                ['text'] = os.date()
            },
            ['fields'] = type(fields) == 'table' and fields or nil,
            ['description'] = type(fields) == 'string' and fields or nil,
            ['author'] = {
                ['name'] = Webhooks.Header,
                ['icon_url'] = Webhooks.ProfilePicture
            }
        }
    }

    PerformHttpRequest(webhook, nil, 'POST', json.encode({
        username = Webhooks.BotName,
        embeds = data
    }), {['Content-Type'] = 'application/json'})
end

Last updated