Wert Multicharacter System
You can access the setup information you need about this product
INSTALLATION
1 - Upload the script folder to the location of your resources
2 - Check config and editable file settings. Don’t forget to configure the core settings (like the framework) through the config file to match your setup.
3 - Make sure that the ox_lib
resource is installed and running. (https://github.com/overextended/ox_lib)
4 - You are ready. Restart ur server and use it. For more options, don’t forget to check the configuration files.
5 - Installation successful, have a good funs
INFORMATION
The script comes with default settings. There are many settings in the configuration file, and you can customize all of them to your personal preferences. Below are the configuration files, feel free to check them out.
OPEN FILES
config.lua
Config = {}
Config.Framework = 'qbox' -- 'qb', 'esx', 'qbox'
Config.CameraDuration = 2000
Config.HiddenCoords = vector4(-2173.76, 5203.01, 17.42, 18.64)
Config.ClothingSystem = 'illenium-appearance' -- 'IzzyAppearance' | 'qb-cloting' | 'illenium-appearance' | 'skinchanger'
Config.DefaultNationality = "United States"
Config.UseSpawnSelector = true -- # Default
Config.DefaultSpawn = vector3(-1035.71, -2731.87, 12.86)
Config.NewSpawnPoint = vector4(4474.09, -4476.97, 4.0, 201.98)
Config.CreateCharacterPosition = vector4(-1042.180176, -2745.059326, 21.343628, 334.488190)
Config.LoadQBHouses = false
Config.UseQBApartments = false
Config.UseQBXProperties = false
Config.LoginSystemCinematic = {
vector4(-2169.78, 5197.44, 16.88, 194.08),
vector4(-2168.43, 5192.29, 16.5, 192.35),
vector4(-2167.55, 5186.87, 15.88, 210.05),
vector4(-2166.75, 5185.53, 15.7, 251.47)
}
Config.SkipSelection = false
Config.IsInterior = false
Config.DefaultCharacters = {
male = `mp_m_freemode_01`,
female = `mp_f_freemode_01`,
}
Config.Logout = {
active = true,
-- Command settings
name = 'logout',
description = 'Log out a player (Only Admins)',
group = 'admin', -- Min permission name
-- Arg
paramID = 'playerID',
paramDesc = 'Player ID',
}
Config.SpawnCamAnimation = {
distance = 1.0, -- geri gitme mesafesi (metre)
height = 0.1, -- yukarı çıkma miktarı
duration = 2000 -- kaç ms'de tamamlanacak
}
Config.Characters = {
[1] = {
slotLocked = false, -- # For the default character slot is locked ?
pedPosition = vector4(-2165.85, 5185.25, 15.5, 80.77),
camPosition = vector4(-2166.75, 5185.53, 15.7, 251.47),
defaultGender = 'male',
animation = {
dict = "timetable@maid@couch@",
clip = "base",
flag = 1,
scenario = nil, -- If u want scenario select this
},
spawnAnimation = { -- When click spwan button (If u dont want set nil)
dict = nil,
clip = nil,
flag = nil,
scenario = "WORLD_HUMAN_DRUG_DEALER", -- If u want scenario select this
prop = nil, -- If u want set prop like my other example
waitTime = 3000,
},
cameras = {
['2'] = { -- 1 Character to 2 Character Camera way
vector4(-2166.75, 5185.53, 15.7, 251.47),
vector4(-2167.27, 5183.79, 15.65, 140.26)
},
['3'] = { -- 1 Character to 3 Character Camera way
vector4(-2166.75, 5185.53, 15.7, 251.47),
vector4(-2168.81, 5185.25, 15.94, 149.18)
},
['4'] = { -- 1 Character to 4 Character Camera way
vector4(-2166.75, 5185.53, 15.7, 251.47),
vector4(-2170.84, 5188.22, 16.33, 103.48),
},
['5'] = { -- 1 Character to 5 Character Camera way
vector4(-2166.75, 5185.53, 15.7, 251.47),
vector4(-2164.44, 5189.29, 15.73, 313.52),
},
['6'] = { -- 1 Character to 6 Character Camera way
vector4(-2166.75, 5185.53, 15.7, 251.47),
vector4(-2165.92, 5193.55, 16.42, 12.5),
},
}
},
[2] = {
slotLocked = false, -- # For the default character slot is locked ?
pedPosition = vector4(-2168.25, 5182.7, 15.69, 337.22),
camPosition = vector4(-2167.27, 5183.79, 15.65, 140.26),
defaultGender = 'male',
animation = {
dict = "timetable@ron@ig_3_couch",
clip = "base",
flag = 1,
scenario = nil, -- If u want scenario select this
},
spawnAnimation = { -- When click spwan button (If u dont want set nil)
dict = nil,
clip = nil,
flag = nil,
scenario = "WORLD_HUMAN_DRUG_DEALER", -- If u want scenario select this
prop = nil, -- If u want set prop like my other example
waitTime = 3000,
},
cameras = {
['1'] = { -- 2 Character to 1 Character
vector4(-2167.27, 5183.79, 15.65, 140.26),
vector4(-2166.75, 5185.53, 15.7, 251.47),
},
['3'] = { -- 2 Character to 3 Character
vector4(-2167.27, 5183.79, 15.65, 140.26),
vector4(-2168.81, 5185.25, 15.94, 149.18)
},
['4'] = { -- 2 Character to 4 Character
vector4(-2167.27, 5183.79, 15.65, 140.26),
vector4(-2170.84, 5188.22, 16.33, 103.48),
},
['5'] = { -- 2 Character to 5 Character
vector4(-2167.27, 5183.79, 15.65, 140.26),
vector4(-2164.44, 5189.29, 15.73, 313.52),
},
['6'] = { -- 2 Character to 6 Character
vector4(-2167.27, 5183.79, 15.65, 140.26),
vector4(-2165.92, 5193.55, 16.42, 12.5),
},
},
},
[3] = {
slotLocked = false, -- # For the default character slot is locked ?
pedPosition = vector4(-2169.07, 5183.96, 15.88, 295.52),
camPosition = vector4(-2168.81, 5185.25, 15.94, 149.18),
defaultGender = 'male',
animation = {
dict = "timetable@ron@ig_5_p3",
clip = "ig_5_p3_base",
flag = 1,
scenario = nil, -- If u want scenario select this
},
spawnAnimation = { -- When click spwan button (If u dont want set nil)
dict = nil,
clip = nil,
flag = nil,
scenario = "WORLD_HUMAN_DRUG_DEALER", -- If u want scenario select this
prop = nil, -- If u want set prop like my other example
waitTime = 3000,
},
cameras = {
['1'] = {
vector4(-2168.81, 5185.25, 15.94, 149.18),
vector4(-2166.75, 5185.53, 15.7, 251.47),
},
['2'] = {
vector4(-2168.81, 5185.25, 15.94, 149.18),
vector4(-2167.27, 5183.79, 15.65, 140.26),
},
['4'] = {
vector4(-2168.81, 5185.25, 15.94, 149.18),
vector4(-2170.84, 5188.22, 16.33, 103.48),
},
['5'] = {
vector4(-2168.81, 5185.25, 15.94, 149.18),
vector4(-2164.44, 5189.29, 15.73, 313.52),
},
['6'] = {
vector4(-2168.81, 5185.25, 15.94, 149.18),
vector4(-2165.92, 5193.55, 16.42, 12.5),
},
}
},
[4] = {
slotLocked = false, -- # For the default character slot is locked ?
pedPosition = vector4(-2172.27, 5187.92, 16.47, 280.84),
camPosition = vector4(-2170.84, 5188.22, 16.33, 103.48),
defaultGender = 'male',
animation = {
dict = "amb@world_human_leaning@female@wall@back@holding_elbow@idle_a",
clip = "idle_a",
flag = 1,
scenario = nil, -- If u want scenario select this
},
spawnAnimation = { -- When click spwan button (If u dont want set nil)
dict = nil,
clip = nil,
flag = nil,
scenario = "WORLD_HUMAN_DRUG_DEALER", -- If u want scenario select this
prop = nil, -- If u want set prop like my other example
waitTime = 3000,
},
cameras = {
['1'] = {
vector4(-2170.84, 5188.22, 16.33, 103.48),
vector4(-2166.75, 5185.53, 15.7, 251.47),
},
['2'] = {
vector4(-2170.84, 5188.22, 16.33, 103.48),
vector4(-2167.27, 5183.79, 15.65, 140.26),
},
['3'] = {
vector4(-2170.84, 5188.22, 16.33, 103.48),
vector4(-2168.81, 5185.25, 15.94, 149.18),
},
['5'] = {
vector4(-2170.84, 5188.22, 16.33, 103.48),
vector4(-2164.44, 5189.29, 15.73, 313.52),
},
['6'] = {
vector4(-2170.84, 5188.22, 16.33, 103.48),
vector4(-2165.92, 5193.55, 16.42, 12.5),
},
},
},
[5] = {
slotLocked = true, -- # For the default character slot is locked ?
pedPosition = vector4(-2163.63, 5190.09, 15.7, 126.97),
camPosition = vector4(-2164.44, 5189.29, 15.73, 313.52),
defaultGender = 'male',
animation = {
dict = "timetable@jimmy@mics3_ig_15@",
clip = "mics3_15_base_tracy",
flag = 1,
scenario = nil, -- If u want scenario select this
prop = {
model = `prop_drink_whisky`,
bone = 28422,
pos = {0.01, -0.01, -0.06},
rot = {0.0, 0.0, 0.0},
},
},
spawnAnimation = { -- When click spwan button (If u dont want set nil)
dict = nil,
clip = nil,
flag = nil,
scenario = "WORLD_HUMAN_DRUG_DEALER", -- If u want scenario select this
prop = nil, -- If u want set prop like my other example
waitTime = 3000,
},
cameras = {
['1'] = {
vector4(-2164.44, 5189.29, 15.73, 313.52),
vector4(-2166.75, 5185.53, 15.7, 251.47),
},
['2'] = {
vector4(-2164.44, 5189.29, 15.73, 313.52),
vector4(-2167.27, 5183.79, 15.65, 140.26),
},
['3'] = {
vector4(-2164.44, 5189.29, 15.73, 313.52),
vector4(-2168.81, 5185.25, 15.94, 149.18),
},
['4'] = {
vector4(-2164.44, 5189.29, 15.73, 313.52),
vector4(-2170.84, 5188.22, 16.33, 103.48),
},
['6'] = {
vector4(-2164.44, 5189.29, 15.73, 313.52),
vector4(-2165.92, 5193.55, 16.42, 12.5),
},
},
},
[6] = {
slotLocked = true, -- # For the default character slot is locked ?
pedPosition = vector4(-2166.14, 5194.47, 16.52, 192.08),
camPosition = vector4(-2165.92, 5193.55, 16.42, 12.5),
defaultGender = 'male',
animation = {
dict = "amb@world_human_leaning@male@wall@back@foot_up@idle_a",
clip = "idle_a",
flag = 1,
scenario = nil, -- If u want scenario select this
},
spawnAnimation = { -- When click spwan button (If u dont want set nil)
dict = nil,
clip = nil,
flag = nil,
scenario = "WORLD_HUMAN_DRUG_DEALER", -- If u want scenario select this
prop = nil, -- If u want set prop like my other example
waitTime = 3000,
},
cameras = {
['1'] = {
vector4(-2165.92, 5193.55, 16.42, 12.5),
vector4(-2166.75, 5185.53, 15.7, 251.47),
},
['2'] = {
vector4(-2165.92, 5193.55, 16.42, 12.5),
vector4(-2167.27, 5183.79, 15.65, 140.26),
},
['3'] = {
vector4(-2165.92, 5193.55, 16.42, 12.5),
vector4(-2168.81, 5185.25, 15.94, 149.18),
},
['4'] = {
vector4(-2165.92, 5193.55, 16.42, 12.5),
vector4(-2170.84, 5188.22, 16.33, 103.48),
},
['5'] = {
vector4(-2165.92, 5193.55, 16.42, 12.5),
vector4(-2164.44, 5189.29, 15.73, 313.52),
},
},
},
}
Config.CreatePedOffsetminus = 1.0
-- # Spawn button
Config.AfterClickSpawnButtonWaitTime = 1800 -- 1 Second
-- # Spawn points
-- # Plane And New Spawn UI Settings
Config.UsePlane = false -- # Enable : true | Disable : false
Config.CreateCharacterPlaneIndex = 1 -- # For example this index like order so when player create character player go airport with plane.
Config.UseSpawnCameraEffect = true -- # The camera effect from top to bottom
Config.LastLocationButton = true
Config.newSpawnAreas = {
{
label = 'Los Santos International Airport (LSIA)',
spawnPoint = vector4(-1035.82, -2848.968, 26.404, 62.3), -- # After plane player spawn position
icon = 'fa-solid fa-map-location-dot', -- # In select ui icon | https://fontawesome.com/icons
planeModel = `miljet`, -- # Plane model
planeDriverModel = `csb_reporter`, -- Plane driver model
planeStartLocation = vector4(-464.19, -3454.57, 143.44, 61.38), -- # Plane spawn,
planeEndLocation = vector4(-870.86, -3216.99, 13.94, 61.38), -- # Until this position, the plane will be airborne.
planeLandStartLocation = vector2(-964.98, -3106.51), -- # The plane will be on the ground in this position.
planeTaxiEndLocation = vector4(-1049.77, -3030.56, 13.94, 29.04), -- # It will move on the ground from the `planeLandStartLocation` to this location.
finishLocation = vector4(-1138.08, -2967.45, 13.94, 60.4), -- # "It will start from the planeTaxiEndLocation and come to this location. Once it arrives, a black screen will appear and the player will exit the plane, marking the end of the plane phase and the transition into gameplay.
},
{
label = 'Cayo Perico',
spawnPoint = vector4(4474.09, -4476.97, 4.0, 201.98), -- # After plane player spawn position
icon = 'fa-solid fa-map-location-dot', -- # In select ui icon | https://fontawesome.com/icons
planeModel = `miljet`, -- # Plane model
planeDriverModel = `csb_reporter`, -- Plane driver model
planeStartLocation = vector4(3140.83, -4975.77, 133.67, 290.99), -- # Plane spawn,
planeEndLocation = vector4(3986.2, -4677.65, 4.18, 290.99), -- # Until this position, the plane will be airborne.
planeLandStartLocation = vector2(3991.52, -4678.12), -- # The plane will be on the ground in this position.
planeTaxiEndLocation = vector4(4240.50, -4585.25, 4.18, 287.98), -- # It will move on the ground from the `planeLandStartLocation` to this location.
finishLocation = vector4(4457.52, -4510.99, 4.18, 290.27), -- # "It will start from the planeTaxiEndLocation and come to this location. Once it arrives, a black screen will appear and the player will exit the plane, marking the end of the plane phase and the transition into gameplay.
},
{
label = 'Legion Square',
spawnPoint = vector4(162.34, -990.29, 30.09, 164.5), -- # After plane player spawn position
icon = 'fa-solid fa-map-location-dot', -- # In select ui icon | https://fontawesome.com/icons
planeModel = `miljet`, -- # Plane model
planeDriverModel = `csb_reporter`, -- Plane driver model
planeStartLocation = vector4(-464.19, -3454.57, 143.44, 61.38), -- # Plane spawn,
planeEndLocation = vector4(-870.86, -3216.99, 13.94, 61.38), -- # Until this position, the plane will be airborne.
planeLandStartLocation = vector2(-964.98, -3106.51), -- # The plane will be on the ground in this position.
planeTaxiEndLocation = vector4(-1049.77, -3030.56, 13.94, 29.04), -- # It will move on the ground from the `planeLandStartLocation` to this location.
finishLocation = vector4(-1138.08, -2967.45, 13.94, 60.4), -- # "It will start from the planeTaxiEndLocation and come to this location. Once it arrives, a black screen will appear and the player will exit the plane, marking the end of the plane phase and the transition into gameplay.
},
{
label = 'Sandy Airport',
spawnPoint = vector4(1716.606, 3272.609, 41.151, 173.434), -- # After plane player spawn position
icon = 'fa-solid fa-map-location-dot', -- # In select ui icon | https://fontawesome.com/icons
planeModel = `miljet`, -- # Plane model
planeDriverModel = `csb_reporter`, -- Plane driver model
planeStartLocation = vector4(794.68, 3009.0, 171.21, 283.99), -- # Plane spawn,
planeEndLocation = vector4(1174.4, 3107.88, 40.41, 283.99), -- # Until this position, the plane will be airborne.
planeLandStartLocation = vector2(1216.48, 3119.2), -- # The plane will be on the ground in this position.
planeTaxiEndLocation = vector4(1503.85, 3196.58, 40.41, 283.99), -- # It will move on the ground from the `planeLandStartLocation` to this location.
finishLocation = vector4(1629.85, 3230.5, 40.41, 283.99), -- # "It will start from the planeTaxiEndLocation and come to this location. Once it arrives, a black screen will appear and the player will exit the plane, marking the end of the plane phase and the transition into gameplay.
},
}
Config.StarterItems = {
['phone'] = { amount = 1, item = 'phone' },
['id_card'] = { amount = 1, item = 'id_card' },
['driver_license'] = { amount = 1, item = 'driver_license' },
}
-- # Default skin load for ESX
Config.Default = {
["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,
},
}
lang.lua
LANG = {
invalid_id = 'Invalid Player ID! Please check again ...',
target_not_online = 'Target not online!',
prints = {
charNotFound = 'Character not found!',
},
ui = {
areaMenuLabel = 'Select an Airport',
areaClick = 'Click for play!',
areaLastLocation = 'Last Location',
areaPlay = 'Play!',
selected = 'SELECTED',
createNewChar = 'CREATE NEW CHARACTER',
slotLocked = 'This slot locked for the now!',
clickForCreate = 'Click for create new character!',
selectCharacter = 'SELECT CHARACTER',
slotsUsed = 'SLOTS USED',
firstnameLabel = '* First name',
firstnamePlaceholder = 'John',
lastnameLabel = '* Last name',
lastnamePlaceholder = 'Doe',
returnBack = 'Return Back',
registerCharacter = 'Register Character',
selectGender = 'SELECT GENDER',
male = 'Male',
female = 'Female',
information = 'INFORMATION',
informationText = 'Please Check your information. Edit inapprapriate characters.',
birthdateLabel = '* Birth Date',
height = 'Height',
cmText = 'CM',
informationAboutCharacter = 'INFORMATION ABOUT CHARACTER',
cashLabel = 'Money In Cash',
bankLabel = 'Money In Bank',
nationalityLabel = 'Nationality',
dobLabel = 'Date Of Birth',
genderLabel = 'Gender',
deletePopuiLabel = 'Are you sure you want to delete your character ?',
deletePopuiDesc = 'This character will be permanently deleted from the database and cannot be recovered. Please use the buttons below to confirm or cancel the action.',
deleteConfirm = 'Confirm',
deleteCancel = 'Cancel',
},
}
editable_client.lua
function WeatherSystemControl(disable)
if disable then
TriggerEvent('qb-weathersync:client:DisableSync')
else
TriggerEvent('qb-weathersync:client:EnableSync')
end
end
function BeforeCreateFirstCharacter()
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
TriggerServerEvent('QBCore:Server:OnPlayerLoaded')
TriggerEvent('QBCore:Client:OnPlayerLoaded')
TriggerServerEvent('qb-houses:server:SetInsideMeta', 0, false)
TriggerServerEvent('qb-apartments:server:SetInsideMeta', 0, 0, false)
else
-- ESX
end
end
function OpenCreateFirstCharacter()
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
TriggerEvent('qb-clothes:client:CreateFirstCharacter')
else
-- ESX
end
end
function ApplyPedAppearance(charPed, skin)
if Config.ClothingSystem == 'IzzyAppearance' then
TriggerEvent('sh-creation:client:loadData', skin, charPed)
elseif Config.ClothingSystem == 'qb-cloting' then
TriggerEvent('qb-clothing:client:loadPlayerClothing', skin, charPed)
elseif Config.ClothingSystem == 'illenium-appearance' then
exports['illenium-appearance']:setPedAppearance(charPed, skin)
elseif Config.ClothingSystem == 'skinchanger' then
-- Empty for the now.
ApplySkin(charPed, skin)
end
end
function SpawnTriggers(isNew, citizenid)
-- # This function using when player character spawned!
-- isNew : boolean : If player created new character
if Config.Framework == 'esx' then
-- Empty for the now!
else
TriggerServerEvent('QBCore:Server:OnPlayerLoaded')
TriggerEvent('QBCore:Client:OnPlayerLoaded')
end
end
RegisterNetEvent('wert-multicharacter:client:custom-spawn-selector', function(citizenid)
-- # If u want another spawn selector system u can add trigger / export there
-- citizenid : Player Character citizenid / identifier ( For ESX )
end)
if Config.UseQBApartments then
RegisterNetEvent('apartments:client:WertMulticharacter', function(citizenid)
QBCore.Functions.TriggerCallback('apartments:GetOwnedApartment', function(result)
if not result then
local startApskey = "apartment1" -- # When player spawn player must be spawn in which aps ?
BeforeCreateFirstCharacter()
TriggerServerEvent('apartments:server:CreateApartment', startApskey, Apartments.Locations[startApskey].label, true)
end
end, citizenid)
end)
end
RegisterNetEvent("esx:playerLoaded", function(playerData, isNew, skin)
if Config.ClothingSystem == 'skinchanger' or Config.ClothingSystem == 'illenium-appearance' then
if isNew or not skin or #skin == 1 then
local finished = false
skin = Config.Default[playerData.sex]
skin.sex = playerData.sex == "m" and 0 or 1
local model = skin.sex == 0 and `mp_m_freemode_01` or `mp_m_freemode_01`
RequestModel(model)
while not HasModelLoaded(model) do
RequestModel(model)
Wait(0)
end
SetPlayerModel(PlayerId(), model)
SetModelAsNoLongerNeeded(model)
if isNew then
FreezeEntityPosition(PlayerPedId(), true)
SetEntityCoords(PlayerPedId(), Config.CreateCharacterPosition.x, Config.CreateCharacterPosition.y, Config.CreateCharacterPosition.z)
SetEntityVisible(PlayerPedId(), true)
Wait(500)
DoScreenFadeIn(1500)
TriggerServerEvent('wert-multicharacter:server:reset-bucket-new')
WeatherSystemControl(false)
CreateThread(function()
while true do
local distance = #(GetEntityCoords(PlayerPedId()) - vector3(Config.CreateCharacterPosition.x, Config.CreateCharacterPosition.y, Config.CreateCharacterPosition.z))
if distance <= 1.0 then
break
else
SetEntityCoords(PlayerPedId(), Config.CreateCharacterPosition.x, Config.CreateCharacterPosition.y, Config.CreateCharacterPosition.z)
end
Wait(1000)
end
FreezeEntityPosition(PlayerPedId(), false)
SetEntityHeading(PlayerPedId(), Config.CreateCharacterPosition.w)
DoScreenFadeIn(1500)
end)
end
TriggerEvent("skinchanger:loadSkin", skin, function()
local playerPed = PlayerPedId()
SetPedAoBlobRendering(playerPed, true)
ResetEntityAlpha(playerPed)
TriggerEvent("esx_skin:openSaveableMenu", function()
finished = true
end, function()
finished = true
end)
end)
repeat
Wait(200)
until finished
end
if not isNew then
TriggerEvent("skinchanger:loadSkin", skin)
end
end
Wait(500)
TriggerServerEvent("esx:onPlayerSpawn")
TriggerEvent("esx:onPlayerSpawn")
TriggerEvent("playerSpawned")
TriggerEvent("esx:restoreLoadout")
end)
RegisterNetEvent("wert-multicharacter:esx:setPlayerData", function(data)
--[[ local Identity = {
firstName = formattedFirstName,
lastName = formattedLastName,
dateOfBirth = tostring(data.birthdate),
sex = data.sex,
height = data.height,
nationality = data.nationality,
charSlot = tostring(data.cid),
} ]]
SetTimeout(1, function()
Bridge.framework.SetPlayerData("name", ("%s %s"):format(data.firstName, data.lastName))
Bridge.framework.SetPlayerData("firstName", data.firstName)
Bridge.framework.SetPlayerData("lastName", data.lastName)
Bridge.framework.SetPlayerData("dateofbirth", data.dateOfBirth)
Bridge.framework.SetPlayerData("sex", data.sex)
Bridge.framework.SetPlayerData("height", data.height)
end)
end)
if Config.ClothingSystem == 'skinchanger' then
function ApplySkin(playerPed, skin)
local Character = {}
for k, v in pairs(skin) do
Character[k] = v
end
local face_weight = (Character["face_md_weight"] / 100) + 0.0
local skin_weight = (Character["skin_md_weight"] / 100) + 0.0
SetPedHeadBlendData(playerPed, Character["mom"], Character["dad"], 0, Character["mom"], Character["dad"], 0, face_weight, skin_weight, 0.0, false)
SetPedFaceFeature(playerPed, 0, (Character["nose_1"] / 10) + 0.0) -- Nose Width
SetPedFaceFeature(playerPed, 1, (Character["nose_2"] / 10) + 0.0) -- Nose Peak Height
SetPedFaceFeature(playerPed, 2, (Character["nose_3"] / 10) + 0.0) -- Nose Peak Length
SetPedFaceFeature(playerPed, 3, (Character["nose_4"] / 10) + 0.0) -- Nose Bone Height
SetPedFaceFeature(playerPed, 4, (Character["nose_5"] / 10) + 0.0) -- Nose Peak Lowering
SetPedFaceFeature(playerPed, 5, (Character["nose_6"] / 10) + 0.0) -- Nose Bone Twist
SetPedFaceFeature(playerPed, 6, (Character["eyebrows_5"] / 10) + 0.0) -- Eyebrow height
SetPedFaceFeature(playerPed, 7, (Character["eyebrows_6"] / 10) + 0.0) -- Eyebrow depth
SetPedFaceFeature(playerPed, 8, (Character["cheeks_1"] / 10) + 0.0) -- Cheekbones Height
SetPedFaceFeature(playerPed, 9, (Character["cheeks_2"] / 10) + 0.0) -- Cheekbones Width
SetPedFaceFeature(playerPed, 10, (Character["cheeks_3"] / 10) + 0.0) -- Cheeks Width
SetPedFaceFeature(playerPed, 11, (Character["eye_squint"] / 10) + 0.0) -- Eyes squint
SetPedFaceFeature(playerPed, 12, (Character["lip_thickness"] / 10) + 0.0) -- Lip Fullness
SetPedFaceFeature(playerPed, 13, (Character["jaw_1"] / 10) + 0.0) -- Jaw Bone Width
SetPedFaceFeature(playerPed, 14, (Character["jaw_2"] / 10) + 0.0) -- Jaw Bone Length
SetPedFaceFeature(playerPed, 15, (Character["chin_1"] / 10) + 0.0) -- Chin Height
SetPedFaceFeature(playerPed, 16, (Character["chin_2"] / 10) + 0.0) -- Chin Length
SetPedFaceFeature(playerPed, 17, (Character["chin_3"] / 10) + 0.0) -- Chin Width
SetPedFaceFeature(playerPed, 18, (Character["chin_4"] / 10) + 0.0) -- Chin Hole Size
SetPedFaceFeature(playerPed, 19, (Character["neck_thickness"] / 10) + 0.0) -- Neck Thickness
SetPedHairColor(playerPed, Character["hair_color_1"], Character["hair_color_2"]) -- Hair Color
SetPedHeadOverlay(playerPed, 3, Character["age_1"], (Character["age_2"] / 10) + 0.0) -- Age + opacity
SetPedHeadOverlay(playerPed, 0, Character["blemishes_1"], (Character["blemishes_2"] / 10) + 0.0) -- Blemishes + opacity
SetPedHeadOverlay(playerPed, 1, Character["beard_1"], (Character["beard_2"] / 10) + 0.0) -- Beard + opacity
SetPedEyeColor(playerPed, Character["eye_color"]) -- Eyes color
SetPedHeadOverlay(playerPed, 2, Character["eyebrows_1"], (Character["eyebrows_2"] / 10) + 0.0) -- Eyebrows + opacity
SetPedHeadOverlay(playerPed, 4, Character["makeup_1"], (Character["makeup_2"] / 10) + 0.0) -- Makeup + opacity
SetPedHeadOverlay(playerPed, 8, Character["lipstick_1"], (Character["lipstick_2"] / 10) + 0.0) -- Lipstick + opacity
SetPedComponentVariation(playerPed, 2, Character["hair_1"], Character["hair_2"], 2) -- Hair
SetPedHeadOverlayColor(playerPed, 1, 1, Character["beard_3"], Character["beard_4"]) -- Beard Color
SetPedHeadOverlayColor(playerPed, 2, 1, Character["eyebrows_3"], Character["eyebrows_4"]) -- Eyebrows Color
SetPedHeadOverlayColor(playerPed, 4, 2, Character["makeup_3"], Character["makeup_4"]) -- Makeup Color
SetPedHeadOverlayColor(playerPed, 8, 1, Character["lipstick_3"], Character["lipstick_4"]) -- Lipstick Color
SetPedHeadOverlay(playerPed, 5, Character["blush_1"], (Character["blush_2"] / 10) + 0.0) -- Blush + opacity
SetPedHeadOverlayColor(playerPed, 5, 2, Character["blush_3"]) -- Blush Color
SetPedHeadOverlay(playerPed, 6, Character["complexion_1"], (Character["complexion_2"] / 10) + 0.0) -- Complexion + opacity
SetPedHeadOverlay(playerPed, 7, Character["sun_1"], (Character["sun_2"] / 10) + 0.0) -- Sun Damage + opacity
SetPedHeadOverlay(playerPed, 9, Character["moles_1"], (Character["moles_2"] / 10) + 0.0) -- Moles/Freckles + opacity
SetPedHeadOverlay(playerPed, 10, Character["chest_1"], (Character["chest_2"] / 10) + 0.0) -- Chest Hair + opacity
SetPedHeadOverlayColor(playerPed, 10, 1, Character["chest_3"]) -- Torso Color
if Character["bodyb_1"] == -1 then
SetPedHeadOverlay(playerPed, 11, 255, (Character["bodyb_2"] / 10) + 0.0) -- Body Blemishes + opacity
else
SetPedHeadOverlay(playerPed, 11, Character["bodyb_1"], (Character["bodyb_2"] / 10) + 0.0)
end
if Character["bodyb_3"] == -1 then
SetPedHeadOverlay(playerPed, 12, 255, (Character["bodyb_4"] / 10) + 0.0)
else
SetPedHeadOverlay(playerPed, 12, Character["bodyb_3"], (Character["bodyb_4"] / 10) + 0.0) -- Blemishes 'added body effect' + opacity
end
if Character["ears_1"] == -1 then
ClearPedProp(playerPed, 2)
else
SetPedPropIndex(playerPed, 2, Character["ears_1"], Character["ears_2"], 2) -- Ears Accessories
end
SetPedComponentVariation(playerPed, 8, Character["tshirt_1"], Character["tshirt_2"], 2) -- Tshirt
SetPedComponentVariation(playerPed, 11, Character["torso_1"], Character["torso_2"], 2) -- torso parts
SetPedComponentVariation(playerPed, 3, Character["arms"], Character["arms_2"], 2) -- Arms
SetPedComponentVariation(playerPed, 10, Character["decals_1"], Character["decals_2"], 2) -- decals
SetPedComponentVariation(playerPed, 4, Character["pants_1"], Character["pants_2"], 2) -- pants
SetPedComponentVariation(playerPed, 6, Character["shoes_1"], Character["shoes_2"], 2) -- shoes
SetPedComponentVariation(playerPed, 1, Character["mask_1"], Character["mask_2"], 2) -- mask
SetPedComponentVariation(playerPed, 9, Character["bproof_1"], Character["bproof_2"], 2) -- bulletproof
SetPedComponentVariation(playerPed, 7, Character["chain_1"], Character["chain_2"], 2) -- chain
SetPedComponentVariation(playerPed, 5, Character["bags_1"], Character["bags_2"], 2) -- Bag
if Character["helmet_1"] == -1 then
ClearPedProp(playerPed, 0)
else
SetPedPropIndex(playerPed, 0, Character["helmet_1"], Character["helmet_2"], 2) -- Helmet
end
if Character["glasses_1"] == -1 then
ClearPedProp(playerPed, 1)
else
SetPedPropIndex(playerPed, 1, Character["glasses_1"], Character["glasses_2"], 2) -- Glasses
end
if Character["watches_1"] == -1 then
ClearPedProp(playerPed, 6)
else
SetPedPropIndex(playerPed, 6, Character["watches_1"], Character["watches_2"], 2) -- Watches
end
if Character["bracelets_1"] == -1 then
ClearPedProp(playerPed, 7)
else
SetPedPropIndex(playerPed, 7, Character["bracelets_1"], Character["bracelets_2"], 2) -- Bracelets
end
end
end
editable_server.lua
hasDonePreloading = {}
local discordWebhook = ''
function GiveStarterItems(src)
local Player = Bridge.GetPlayer(src)
if not Player then return end
for _, v in pairs(Config.StarterItems) do
local info = {}
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
if v.item == "id_card" then
info.citizenid = Player.PlayerData.citizenid
info.firstname = Player.PlayerData.charinfo.firstname
info.lastname = Player.PlayerData.charinfo.lastname
info.birthdate = Player.PlayerData.charinfo.birthdate
info.gender = Player.PlayerData.charinfo.gender
info.nationality = Player.PlayerData.charinfo.nationality
elseif v.item == "driver_license" then
info.firstname = Player.PlayerData.charinfo.firstname
info.lastname = Player.PlayerData.charinfo.lastname
info.birthdate = Player.PlayerData.charinfo.birthdate
info.type = "Class C Driver License"
end
else
-- About the esx if u want manage item metadatas
end
Bridge.AddItem(src, { name = v.item, amount = v.amount, slot = false, info = info })
end
end
function loadHouseData(src)
if not Config.LoadQBHouses then return end
local HouseGarages = {}
local Houses = {}
local result = MySQL.query.await('SELECT * FROM houselocations', {})
if result[1] ~= nil then
for _, v in pairs(result) do
local owned = false
if tonumber(v.owned) == 1 then
owned = true
end
local garage = v.garage ~= nil and json.decode(v.garage) or {}
Houses[v.name] = {
coords = json.decode(v.coords),
owned = owned,
price = v.price,
locked = true,
adress = v.label,
tier = v.tier,
garage = garage,
decorations = {},
}
HouseGarages[v.name] = {
label = v.label,
takeVehicle = garage,
}
end
end
TriggerClientEvent("qb-garages:client:houseGarageConfig", src, HouseGarages)
TriggerClientEvent("qb-houses:client:setHouseConfig", src, Houses)
end
function DeleteCharacter(src, identifier)
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
Bridge.framework.Player.DeleteCharacter(src, identifier)
else
-- ESX
local DB_TABLES = { users = "identifier" }
local query = "DELETE FROM `%s` WHERE %s = ?"
local queries = {}
local count = 0
for table, column in pairs(DB_TABLES) do
count = count + 1
queries[count] = { query = query:format(table, column), values = { identifier } }
end
MySQL.transaction(queries, function(result)
if result then
print(("[^2INFO^7] Player ^5%s %s^7 has deleted a character ^5(%s)^7"):format(GetPlayerName(src), src, identifier))
Wait(50)
else
error("\n^1Transaction failed while trying to delete " .. identifier .. "^0")
end
end)
end
TriggerClientEvent('ox_lib:notify', src, { title = 'Character Deleted!', type = 'success' })
end
function DiscordLog(src, new, identifier)
local title = nil
local message = nil
if new then
message = "**".. GetPlayerName(src) .. "** (<@"..(Bridge.GetIdentifier(src, 'discord') and Bridge.GetIdentifier(src, 'discord'):gsub("discord:", "") or "unknown").."> | ||" ..(Bridge.GetIdentifier(src, 'ip') or 'undefined') .. "|| | " ..(Bridge.GetIdentifier(src, 'license') or 'undefined') .." | "..src..") Created new character : .. \n " .. json.encode(new, {indent=true})
else
title = 'Player Loaded ( Joined )'
message = "**".. GetPlayerName(src) .. "** (<@"..(Bridge.GetIdentifier(src, 'discord') and Bridge.GetIdentifier(src, 'discord'):gsub("discord:", "") or "unknown").."> | ||" ..(Bridge.GetIdentifier(src, 'ip') or 'undefined') .. "|| | " ..(Bridge.GetIdentifier(src, 'license') or 'undefined') .." | " ..identifier.." | "..src..") loaded.."
end
local embedData = {
{
['title'] = title,
['color'] = '65280',
['footer'] = { ['text'] = os.date('%c') },
['description'] = message,
['author'] = { ['name'] = "Multicharacter" },
}
}
PerformHttpRequest(discordWebhook, function() end, 'POST', json.encode({ username = 'Multicharacter', embeds = embedData}), { ['Content-Type'] = 'application/json' })
end
local function extractCharNumber(str)
local num = string.match(str, "^char(%d+):")
return tonumber(num)
end
local function containsCharKeyword(str)
return string.find(str, "char") ~= nil
end
local function GetPlayerCitizenIDDatas(src)
local data = {}
local license2, license = GetPlayerIdentifierByType(src, 'license2'), GetPlayerIdentifierByType(src, 'license')
local promise = promise.new()
if Config.Framework ~= 'esx' then
local result = MySQL.query.await('SELECT citizenid, cid, UNIX_TIMESTAMP(last_logged_out) AS lastLoggedOutUnix FROM players WHERE license = ? OR license = ? ORDER BY cid', {license, license2})
for i = 1, #result do
data[#data + 1] = { citizenid = result[i].citizenid, cid = result[i].cid }
end
else
-- Esx
local PREFIX = Config.Prefix or "char"
local identifier = GetIdentifier(src)
local pattern = PREFIX .. "%:" .. identifier
local result = MySQL.query.await([[
SELECT identifier, skin
FROM users
WHERE identifier = ?
OR identifier LIKE ?
]], { identifier, pattern })
for i = 1, #result do
if extractCharNumber(result[i].identifier) then
data[#data + 1] = { citizenid = result[i].identifier, cid = extractCharNumber(result[i].identifier), skin = result[i].skin and json.decode(result[i].skin) or {} }
end
end
end
return data
end
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
Wait(1000) -- 1 second should be enough to do the preloading in other resources
hasDonePreloading[Player.PlayerData.source] = true
end)
AddEventHandler('QBCore:Server:OnPlayerUnload', function(src)
hasDonePreloading[src] = false
end)
-- # Callbacks
lib.callback.register('wert-multicharacter:server:get-player-ui-data', function(source)
local src = source
local license2, license = GetPlayerIdentifierByType(src, 'license2'), GetPlayerIdentifierByType(src, 'license')
local plyChars = {}
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
local result = MySQL.query.await('SELECT citizenid, charinfo, money, job, gang, position, cid, UNIX_TIMESTAMP(last_logged_out) AS lastLoggedOutUnix FROM players WHERE license = ? OR license = ? ORDER BY cid', {license, license2})
for i = 1, #result do
local cid = tostring(result[i].cid)
result[i].charinfo = json.decode(result[i].charinfo)
result[i].money = json.decode(result[i].money)
result[i].job = json.decode(result[i].job)
plyChars[cid] = result[i]
end
else
-- ESX
local function ESXGetJobLabel(name, grade)
local isLabel = MySQL.scalar.await('SELECT `label` FROM `job_grades` WHERE `job_name` = ? AND `grade` = ? LIMIT 1', { name, tonumber(grade) })
if not isLabel then isLabel = 'Unemployed' end
return { grade = { name = isLabel } }
end
local PREFIX = Config.Prefix or "char"
local identifier = GetIdentifier(src)
local pattern = PREFIX .. "%:" .. identifier
local result = MySQL.query.await([[
SELECT identifier, accounts, job, job_grade, firstname, lastname, dateofbirth, sex, nationality
FROM users
WHERE identifier = ?
OR identifier LIKE ?
]], { identifier, pattern })
for i = 1, #result do
if extractCharNumber(result[i].identifier) then
local cid = extractCharNumber(result[i].identifier)
cid = tostring(cid)
local accounts = result[i].accounts and json.decode(result[i].accounts) or {}
plyChars[cid] = {
citizenid = result[i].identifier,
cid = tonumber(cid),
job = ESXGetJobLabel(result[i].job, result[i].job_grade),
money = { cash = accounts.money or 0, bank = accounts.bank or 0 },
charinfo = {
gender = result[i].sex == 'f' and 1 or 0,
birthdate = result[i].dateofbirth,
firstname = result[i].firstname,
lastname = result[i].lastname,
nationality = result[i].nationality or Config.DefaultNationality
}
}
end
end
end
return plyChars
end)
lib.callback.register('wert-multicharacter:server:get-spawn-peds', function(source)
local src = source
if Config.Framework == 'esx' then
Bridge.framework.Players[GetIdentifier(src)] = true
end
local plyChars = GetPlayerCitizenIDDatas(src)
if #plyChars > 0 then
local skins = {}
local citizenTable = {}
local queryTable = {}
for i=1, #plyChars do
queryTable[#queryTable+1] = plyChars[i].citizenid
citizenTable[plyChars[i].citizenid] = plyChars[i].cid
if Config.ClothingSystem == 'skinchanger' then
local selectCid = tostring(plyChars[i].cid)
local model = `mp_m_freemode_01`
if plyChars[i].skin and plyChars[i].skin == 1 then model = `mp_f_freemode_01` end
skins[selectCid] = { model = model, skin = plyChars[i].skin }
end
end
if Config.ClothingSystem ~= 'skinchanger' then
local result = MySQL.query.await('SELECT * FROM playerskins WHERE citizenid IN (?) AND active = 1', { queryTable })
if result then
for _, row in ipairs(result) do
local selectCid = citizenTable[row.citizenid]
selectCid = tostring(selectCid)
if Config.ClothingSystem == 'illenium-appearance' then
local mySkinData = json.decode(row.skin)
skins[selectCid] = {model = mySkinData.model, skin = mySkinData}
else
skins[selectCid] = {model = row.model, skin = json.decode(row.skin)}
end
end
end
end
return skins
else
return {}
end
end)
-- # Logout command
if Config.Logout.active then
lib.addCommand(Config.Logout.name, {
help = Config.Logout.description,
restricted = 'group.' .. Config.Logout.group
}, function(source, args, raw)
local src = source
local ply = Bridge.GetPlayer(src)
if not ply then
TriggerClientEvent('ox_lib:notify', src, { title = LANG.target_not_online, type = 'error' })
return
end
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
Bridge.framework.Player.Logout(src)
else
TriggerEvent("esx:playerLogout", src)
end
TriggerClientEvent('wert-multicharacter:client:chooseChar', src)
end)
end
if Config.Framework == 'esx' then
local PREFIX = Config.Prefix or "char"
local PRIMARY_IDENTIFIER = Bridge.framework.GetConfig().Identifier or GetConvar("sv_lan", "") == "true" and "ip" or "license"
local oneSyncState = GetConvar("onesync", "off")
CreateThread(function()
Wait(1000)
if next(Bridge.framework.Players) then
local players = table.clone(Bridge.framework.Players)
table.wipe(Bridge.framework.Players)
for _, v in pairs(players) do
Bridge.framework.Players[GetIdentifier(v.source)] = true
end
else
Bridge.framework.Players = {}
end
end)
AddEventHandler("playerConnecting", function(_, _, deferrals)
deferrals.defer()
local identifier = GetIdentifier(source)
if oneSyncState == "off" or oneSyncState == "legacy" then
return deferrals.done(("[ESX] ESX Requires Onesync Infinity to work. This server currently has Onesync set to: %s"):format(oneSyncState))
end
if identifier then
if not Bridge.framework.GetConfig().EnableDebug then
if Bridge.framework.Players[identifier] then
deferrals.done(("[Wert Multicharacter] A player is already connected to the server with this identifier.\nYour identifier: %s:%s"):format(PRIMARY_IDENTIFIER, identifier))
else
deferrals.done()
end
else
deferrals.done()
end
else
deferrals.done(("Unable to retrieve player identifier.\nIdentifier type: %s"):format(PRIMARY_IDENTIFIER))
end
end)
MySQL.ready(function()
Wait(1000)
while not next(Bridge.framework.Jobs) do
Wait(500)
Bridge.framework.Jobs = Bridge.framework.GetJobs()
end
end)
AddEventHandler("playerDropped", function()
hasDonePreloading[source] = false
Bridge.framework.Players[GetIdentifier(source)] = nil
end)
function GetIdentifier(source)
local fxDk = GetConvarInt("sv_fxdkMode", 0)
if fxDk == 1 then return "ESX-DEBUG-LICENCE" end
local identifier = GetPlayerIdentifierByType(source, PRIMARY_IDENTIFIER)
return identifier and identifier:gsub(PRIMARY_IDENTIFIER .. ":", "")
end
end
bridge/client.lua
Bridge = {}
-- # Get core
if Config.Framework == 'qb' then
Bridge.framework = exports['qb-core']:GetCoreObject()
elseif Config.Framework == 'qbox' then
Bridge.framework = exports['qb-core']:GetCoreObject()
elseif Config.Framework == 'esx' then
Bridge.framework = exports["es_extended"]:getSharedObject()
end
bridge/server.lua
Bridge = {}
-- # Get core
if Config.Framework == 'qb' then
Bridge.framework = exports['qb-core']:GetCoreObject()
elseif Config.Framework == 'qbox' then
Bridge.framework = exports['qb-core']:GetCoreObject()
elseif Config.Framework == 'esx' then
Bridge.framework = exports["es_extended"]:getSharedObject()
end
function Bridge.GetPlayer(src)
if not src then return nil end
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
return Bridge.framework.Functions.GetPlayer(src)
else
return Bridge.framework.GetPlayerFromId(src)
end
end
function Bridge.GetIdentifier(src, idtype)
if GetConvarInt('sv_fxdkMode', 0) == 1 then return 'license:fxdk' end
return GetPlayerIdentifierByType(src, idtype or 'license')
end
function Bridge.AddItem(src, data)
if not src then return false end
local ply = Bridge.GetPlayer(src)
if not ply then return end
if GetResourceState('ox_inventory') == 'started' then
exports.ox_inventory:AddItem(src, data.name, data.amount, data.info, data.slot)
return
end
if Config.Framework == 'qb' or Config.Framework == 'qbox' then
ply.Functions.AddItem(data.name, data.amount, data.slot, data.info)
else
ply.addInventoryItem(data.name, data.amount)
end
end
Last updated