Page cover image

βš™οΈConfiguration

Discover how to config your script.

Event to Open Multicharacter:

TriggerClientEvent('zr-multicharacter:start', src)

Tutorial of how to get the discord token , guild and roles ids :

To ensure you have everything you need, we are constantly updating our config files.

zr_config = {}
zr_config.zr_translation = {}
zr_trans = zr_config.zr_translation

-- We support the following frameworks: 'QB' / 'ESX'
zr_config.framework = 'QB'
zr_config.QB = 'qb-core'
zr_config.ESX = 'es_extended'
zr_config.prefix = 'char' 

zr_config.ToggleInterior = true -- Set this to 'true' if you choose coords inside an interior
zr_config.Interior = vector3(-786.9563, 315.6229, 187.9136) -- Interior location 
zr_config.PlaCoords = vector4(-793.17, 336.83, 187.12, 2.93)-- Hidden ped coords

zr_config.DefaultSpawn = vector3(-1035.71, -2731.87, 12.86) -- Where you want your character to spawn after creating character

zr_config.CamCoords = vector4(-788.46, 343.57, 187.11, 213.7)-- Camera angle from where you want to see your Ped.

zr_config.StartCoords = vector4(-782.38, 343.6, 187.11, 136.04)-- Position where the character spawns and start walking
zr_config.EndCoords = vector4(-787.02, 341.28, 187.11, 23.01)  -- Position where the character goes to do the animation

-- General animations durations :
zr_config.animationDuration = 6000 -- Duration before character stops and does animation (6000 = 6 seconds)

zr_config.DefaultModels = {"mp_m_freemode_01","mp_f_freemode_01"}

zr_config.zr_notify = true

zr_config.clothing = 'qb-clothing' -- 'illenium-appearance' or 'illenium-appearance'
zr_config.spawn = 'zr-locations' --  'ps-housing' or 'qb-spawn'

zr_config.Animslist = {              -- Add here as many animations as you want. 
    "WORLD_HUMAN_HANG_OUT_STREET",
    "WORLD_HUMAN_STAND_IMPATIENT",
    "WORLD_HUMAN_STAND_MOBILE",
    "WORLD_HUMAN_SMOKING_POT",
    "WORLD_HUMAN_LEANING",
    "WORLD_HUMAN_DRUG_DEALER_HARD"
}


zr_config.default_slots = 3 -- Minimum 1
zr_config.discord_enable = true
-- Token transfered to zr-build-s.lua
zr_config.discord_guild = 1000020530499432448
zr_config.discord_roles = {
    ["1000377003704336476"] = 2, -- Add extra 2 slots if player has this role.
    ["1004486369919373392"] = 1, -- Add extra 1 slot if player has this role.
}
zr_config.discord = 'https://discord.gg/FwedjEV6kY'

zr_config.EnableDelete = true
zr_config.EnableDeleteByDiscord = false
zr_config.discord_roles_delete_button = {
    ["1000377003704336476"] = true,
    ["1004486369919373392"] = true, 
}

zr_config.Debug = false

zr_config.locale = 'en-US'

zr_trans.title="Character Selector"
zr_trans.subtitle="Create or choose, then dive into your story."
zr_trans.chinfos = "Character Details"
zr_trans.otinfos = "Other Information."
zr_trans.delete = "Delete character"
zr_trans.deleteconf = "Are you sure you want to delete your character?"
zr_trans.deleteconfbuttondelete = "Delete"
zr_trans.deleteconfbuttoncancel = "Cancel"
zr_trans.play = "Join the City"
zr_trans.create = "Create new character"
zr_trans.name = "Name"
zr_trans.gender = "Gender"
zr_trans.male = 'MALE'
zr_trans.female = 'FEMALE'
zr_trans.dob = "Birthdate"
zr_trans.job = "Job"
zr_trans.cash = "Cash"
zr_trans.bank = "Bank"
zr_trans.symb = "$"
zr_trans.aslots = "Default slots"
zr_trans.dslots = "Discord slots"
zr_trans.slotlocked="Locked Slot"
zr_trans.slotempty="Empty Slot"
zr_trans.slotlockedwarning="Unlock additional character slots by obtaining a Discord role"

zr_trans.noslots = "You don't have any empty slots!"
zr_trans.deleted = "Character Deleted"
zr_trans.deldiscord = "You must have a discord role to delete your character"
zr_trans.join = "Join our discord."

zr_config.DefaultSkins = {
    ["m"] = {
        mom = 43,
        dad = 29,
        face_md_weight = 61,
        skin_md_weight = 27,
        nose_1 = -5,
        nose_2 = 6,
        nose_3 = 5,
        nose_4 = 8,
        nose_5 = 10,
        nose_6 = 0,
        cheeks_1 = 2,
        cheeks_2 = -10,
        cheeks_3 = 6,
        lip_thickness = -2,
        jaw_1 = 0,
        jaw_2 = 0,
        chin_1 = 0,
        chin_2 = 0,
        chin_13 = 0,
        chin_4 = 0,
        neck_thickness = 0,
        hair_1 = 76,
        hair_2 = 0,
        hair_color_1 = 61,
        hair_color_2 = 29,
        tshirt_1 = 4,
        tshirt_2 = 2,
        torso_1 = 23,
        torso_2 = 2,
        decals_1 = 0,
        decals_2 = 0,
        arms = 1,
        arms_2 = 0,
        pants_1 = 28,
        pants_2 = 3,
        shoes_1 = 70,
        shoes_2 = 2,
        mask_1 = 0,
        mask_2 = 0,
        bproof_1 = 0,
        bproof_2 = 0,
        chain_1 = 22,
        chain_2 = 2,
        helmet_1 = -1,
        helmet_2 = 0,
        glasses_1 = 0,
        glasses_2 = 0,
        watches_1 = -1,
        watches_2 = 0,
        bracelets_1 = -1,
        bracelets_2 = 0,
        bags_1 = 0,
        bags_2 = 0,
        eye_color = 0,
        eye_squint = 0,
        eyebrows_2 = 0,
        eyebrows_1 = 0,
        eyebrows_3 = 0,
        eyebrows_4 = 0,
        eyebrows_5 = 0,
        eyebrows_6 = 0,
        makeup_1 = 0,
        makeup_2 = 0,
        makeup_3 = 0,
        makeup_4 = 0,
        lipstick_1 = 0,
        lipstick_2 = 0,
        lipstick_3 = 0,
        lipstick_4 = 0,
        ears_1 = -1,
        ears_2 = 0,
        chest_1 = 0,
        chest_2 = 0,
        chest_3 = 0,
        bodyb_1 = -1,
        bodyb_2 = 0,
        bodyb_3 = -1,
        bodyb_4 = 0,
        age_1 = 0,
        age_2 = 0,
        blemishes_1 = 0,
        blemishes_2 = 0,
        blush_1 = 0,
        blush_2 = 0,
        blush_3 = 0,
        complexion_1 = 0,
        complexion_2 = 0,
        sun_1 = 0,
        sun_2 = 0,
        moles_1 = 0,
        moles_2 = 0,
        beard_1 = 11,
        beard_2 = 10,
        beard_3 = 0,
        beard_4 = 0
    },
    ["f"] = {
        mom = 28,
        dad = 6,
        face_md_weight = 63,
        skin_md_weight = 60,
        nose_1 = -10,
        nose_2 = 4,
        nose_3 = 5,
        nose_4 = 0,
        nose_5 = 0,
        nose_6 = 0,
        cheeks_1 = 0,
        cheeks_2 = 0,
        cheeks_3 = 0,
        lip_thickness = 0,
        jaw_1 = 0,
        jaw_2 = 0,
        chin_1 = -10,
        chin_2 = 10,
        chin_13 = -10,
        chin_4 = 0,
        neck_thickness = -5,
        hair_1 = 43,
        hair_2 = 0,
        hair_color_1 = 29,
        hair_color_2 = 35,
        tshirt_1 = 111,
        tshirt_2 = 5,
        torso_1 = 25,
        torso_2 = 2,
        decals_1 = 0,
        decals_2 = 0,
        arms = 3,
        arms_2 = 0,
        pants_1 = 12,
        pants_2 = 2,
        shoes_1 = 20,
        shoes_2 = 10,
        mask_1 = 0,
        mask_2 = 0,
        bproof_1 = 0,
        bproof_2 = 0,
        chain_1 = 85,
        chain_2 = 0,
        helmet_1 = -1,
        helmet_2 = 0,
        glasses_1 = 33,
        glasses_2 = 12,
        watches_1 = -1,
        watches_2 = 0,
        bracelets_1 = -1,
        bracelets_2 = 0,
        bags_1 = 0,
        bags_2 = 0,
        eye_color = 8,
        eye_squint = -6,
        eyebrows_2 = 7,
        eyebrows_1 = 32,
        eyebrows_3 = 52,
        eyebrows_4 = 9,
        eyebrows_5 = -5,
        eyebrows_6 = -8,
        makeup_1 = 0,
        makeup_2 = 0,
        makeup_3 = 0,
        makeup_4 = 0,
        lipstick_1 = 0,
        lipstick_2 = 0,
        lipstick_3 = 0,
        lipstick_4 = 0,
        ears_1 = -1,
        ears_2 = 0,
        chest_1 = 0,
        chest_2 = 0,
        chest_3 = 0,
        bodyb_1 = -1,
        bodyb_2 = 0,
        bodyb_3 = -1,
        bodyb_4 = 0,
        age_1 = 0,
        age_2 = 0,
        blemishes_1 = 0,
        blemishes_2 = 0,
        blush_1 = 0,
        blush_2 = 0,
        blush_3 = 0,
        complexion_1 = 0,
        complexion_2 = 0,
        sun_1 = 0,
        sun_2 = 0,
        moles_1 = 12,
        moles_2 = 8,
        beard_1 = 0,
        beard_2 = 0,
        beard_3 = 0,
        beard_4 = 0
    }
}
function zr_multichar_show_public()
	-- Trigger Custom Functions/Events when display menu.
	DisplayRadar(false)
end

function zr_multichar_hide_public()
	-- Trigger Custom Functions/Events when hide menu.
	DisplayRadar(true)
end

function zr_setup_skin(zr_data)
    DeleteEntity(zr_current_char)
    if (zr_config.framework=='QB') then -- QBcore
        if zr_data ~= nil then
            QBcore.Functions.TriggerCallback('zr-multicharacter:getSkinData', function(zr_model, zr_skin)
				if (zr_config.clothing=='qb-clothing') then
					zr_model = zr_model ~= nil and tonumber(zr_model) or false
				end
				if zr_model ~= nil then
					CreateThread(function()
						zr_skin = json.decode(zr_skin)
						zr_multichar_loadModel(zr_model)
						zr_current_char = CreatePed(2, zr_model, zr_config.StartCoords.x, zr_config.StartCoords.y, zr_config.StartCoords.z, zr_config.StartCoords.w, false, true)
						if (zr_config.clothing=='qb-clothing') then
							TriggerEvent('qb-clothing:client:loadPlayerClothing', zr_skin, zr_current_char)
						elseif (zr_config.clothing=='illenium-appearance') then
							exports['illenium-appearance']:setPedAppearance(zr_current_char, zr_skin)
						end
						zr_animate_character(zr_current_char)
					end)
				else
					CreateThread(function()				
						zr_model = GetHashKey(zr_config.DefaultModels[math.random(1, #zr_config.DefaultModels)])
						zr_multichar_loadModel(zr_model)
						zr_current_char = CreatePed(2, zr_model, zr_config.StartCoords.x, zr_config.StartCoords.y, zr_config.StartCoords.z, zr_config.StartCoords.w, false, true)	
						zr_animate_character(zr_current_char)
					end)
				end
			end, zr_data.citizenid)
        else
            CreateThread(function()
                local zr_model = GetHashKey(zr_config.DefaultModels[1])
                zr_multichar_loadModel(zr_model)
                zr_current_char = CreatePed(2, zr_model, zr_config.StartCoords.x, zr_config.StartCoords.y, zr_config.StartCoords.z, zr_config.StartCoords.w, false, true)	
				zr_animate_character(zr_current_char)
            end)
        end
    else -- ESX
		if zr_data ~= nil then
			local zr_pedtype = "mp_f_freemode_01"
			local zr_skin = zr_config.DefaultSkins["f"]
			zr_skin.sex = 1
			if zr_data.sex == nil then 
				zr_pedtype = "mp_m_freemode_01"
				if zr_pedtype == "mp_m_freemode_01" then 
					zr_skin = zr_config.DefaultSkins["m"]
					zr_skin.sex = 0
				end
			else
				if zr_data.sex == "m" then 
					zr_pedtype = "mp_m_freemode_01"
					zr_skin = zr_config.DefaultSkins["m"]
					zr_skin.sex = 0
				end  
			end
			zr_model = GetHashKey(zr_pedtype)
			if zr_model ~= nil then
				CreateThread(function()
					exports.spawnmanager:spawnPlayer({x = zr_config.StartCoords.x,y = zr_config.StartCoords.y,z = zr_config.StartCoords.z,heading = zr_config.StartCoords.w,model = ped,skipFade = true
					}, function()
						if zr_data.skin then 
							zr_multichar_loadModel(zr_model)
							SetPlayerModel(PlayerId(), zr_model)
							SetModelAsNoLongerNeeded(zr_model)
							TriggerEvent('skinchanger:loadSkin', zr_data.skin)
						else
							TriggerEvent('skinchanger:loadSkin', zr_skin)
						end
					end)
					Wait(500)
					zr_animate_character(PlayerPedId())
				end)
			end
		end         
    end
end

if (zr_config.framework=='ESX') then
    RegisterNetEvent('esx:playerLoaded')
    AddEventHandler('esx:playerLoaded', function(zr_playerdata, zr_isnew, zr_skin)
        local zr_spawn = zr_playerdata.coords or zr_config.DefaultSpawn
        if zr_isnew or not zr_skin or #zr_skin == 1 then
            local done = false
            local zr_gender = zr_playerdata.sex -- local zr_gender = 'm' (https://github.com/zaphosting/esx_12)
            zr_skin = zr_config.DefaultSkins[zr_gender]
            zr_skin.sex = zr_gender == "m" and 0 or 1 
            if zr_skin.sex == 0 then zr_model = zr_config.DefaultModels[1] else zr_model = zr_config.DefaultModels[2] end
            zr_multichar_loadModel(zr_model)
            SetPlayerModel(PlayerId(), zr_model)
            SetModelAsNoLongerNeeded(zr_model)
            zr_multichar_esx_loops()
            TriggerEvent('skinchanger:loadSkin', zr_skin, function()
                TriggerEvent('esx_skin:openSaveableMenu', function()
                    done = true end, function() done = true
                end)
            end)
            repeat Wait(200) until done
        end
        DoScreenFadeOut(100)
        SetEntityCoordsNoOffset(PlayerPedId(), zr_spawn.x, zr_spawn.y, zr_spawn.z, false, false, false, true)
        SetEntityHeading(PlayerPedId(), zr_spawn.heading)
        if not zr_isnew then TriggerEvent('skinchanger:loadSkin', zr_skin) end
        Wait(400)
        DoScreenFadeIn(400)
        repeat Wait(200) until not IsScreenFadedOut()
        TriggerServerEvent('esx:onPlayerSpawn')
        TriggerEvent('esx:onPlayerSpawn')
        TriggerEvent('playerSpawned')
        TriggerEvent('esx:restoreLoadout')
        FreezeEntityPosition(PlayerPedId(), false)
        zr_multichar_esx_hideplayers = false
        zr_multichar_esx_loops_stop()
    end)
	RegisterNetEvent('esx:onPlayerLogout')
    AddEventHandler('esx:onPlayerLogout', function()
        DoScreenFadeOut(0)
        TriggerEvent('esx_skin:resetFirstSpawn')
    end)
end


function zr_identity_notify(zr_msg)
    if (zr_config.zr_notify) then
        exports['zr-notify']:zr_notify('info', zr_msg, 5000, 'info', 'right')
    else
        if (zr_config.framework=='QB') then
            QBcore.Functions.Notify(zr_msg, "primary")
        else
            ESX.ShowNotification(zr_msg, "info", 3000)
        end
    end
end
zr_config.discord_token = ""

if (zr_config.framework=='QB') then
    QBcore.Functions.CreateCallback("zr-multicharacter:getSkinData", function(_, cb, cid)
        if (zr_config.clothing=='qb-clothing') then
            local zr_data = MySQL.query.await('SELECT * FROM playerskins WHERE citizenid = ? AND active = ?', {cid, 1})
            if zr_data[1] ~= nil then
                cb(zr_data[1].model, zr_data[1].skin)
            else
                cb(nil)
            end
        elseif (zr_config.clothing=='illenium-appearance') then
            local zr_data = MySQL.query.await('SELECT * FROM playerskins WHERE citizenid = ? AND active = ?', {cid, 1})
            if zr_data[1] ~= nil then
                cb(zr_data[1].model, zr_data[1].skin)
            else
                cb(nil)
            end
        end
    end)

    function zr_custom_spawn_menu(zr_source, zr_data)
        if (zr_config.spawn=='ps-housing') then
            TriggerClientEvent('ps-housing:client:setupSpawnUI', zr_source, zr_data)
        else
            TriggerClientEvent('apartments:client:setupSpawnUI', zr_source, zr_data)
        end
    end

    QBcore.Commands.Add("logout", 'logout', {}, false, function(source)
        local src = source
        QBcore.Player.Logout(src)
        TriggerClientEvent('zr-multicharacter:start', src)
    end, "admin")
end


if (zr_config.framework=='ESX') then
    zr_dbtablesesx = {users = 'identifier'}

    function zr_custom_spawn_menu(zr_source)
        -- Spawn menu trigger here! 
    end 

    RegisterCommand('relog', function(source)
        TriggerClientEvent('zr-multicharacter:start', source)
        TriggerEvent('esx:playerLogout', source)
        -- TriggerClientEvent('esx_skin:resetFirstSpawn', source)
    end)
end

Last updated