Appearance
Creating custom compatibility for appearance.
What's needed?
To create custom compatibility for your appearance, you need to firstly get:
table where player skins is saved;
export for opening up appearance menu;
export for setting up player skin;
If you already got this data you're good to go!
Gathering data from database
Headover to /server/functions/characters.lua and find Characters.ConvertSkin
Characters.ConvertSkin = function(convertedIdentifier)
local skin = nil
local startTime = GetGameTimer()
debugPrint("[^2CHARACTERS.CONVERTSKIN^7] Checking player skin [/]")
local appearanceResource = Config.ForceAppereance ~= false and Config.ForceAppereance or (GetResourceState('skinchanger') == 'started' and 'skinchanger' or GetResourceState('skinchanger') == 'fivem-appearance' and 'fivem-appearance' or GetResourceState('illenium-appearance') == 'started' and 'illenium-appearance' or GetResourceState('qb-clothing') == 'started' and 'qb-clothing' or GetResourceState('crm-appearance') == 'started' and 'crm-appearance' or GetResourceState('bl_appearance') == 'started' and 'bl_appearance' or GetResourceState('tgiann-clothing') == 'started' and 'tgiann-clothing' or GetResourceState('rcore_clothing') == 'started' and 'rcore_clothing')
if appearanceResource == 'skinchanger' then
if FrameworkSelected == 'ESX' then
local result = MySQL.query.await("SELECT `skin` FROM `users` WHERE `identifier` = ?", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
elseif FrameworkSelected == 'QBCore' then
local result = MySQL.query.await("SELECT * FROM `playerskins` WHERE `citizenid` = ? AND active = 1", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
end
elseif appearanceResource == 'fivem-appearance' then
if FrameworkSelected == 'ESX' then
local result = MySQL.query.await("SELECT `skin` FROM `users` WHERE `identifier` = ?", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
elseif FrameworkSelected == 'QBCore' then
local result = MySQL.query.await("SELECT * FROM `playerskins` WHERE `citizenid` = ? AND active = 1", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
end
elseif appearanceResource == 'illenium-appearance' then
if FrameworkSelected == 'ESX' then
local result = MySQL.query.await("SELECT `skin` FROM `users` WHERE `identifier` = ?", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
elseif FrameworkSelected == 'QBCore' then
local result = MySQL.query.await("SELECT * FROM `playerskins` WHERE `citizenid` = ? AND active = 1", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
end
elseif appearanceResource == 'qb-clothing' then
if FrameworkSelected == 'ESX' then
debugPrint('Tried to access qb-clothing in ESX. Are you sure you added proper resource to your framework?')
elseif FrameworkSelected == 'QBCore' then
local result = MySQL.query.await("SELECT * FROM `playerskins` WHERE `citizenid` = ? AND active = 1", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
end
elseif appearanceResource == 'crm-appearance' then
if FrameworkSelected == 'ESX' then
local result = MySQL.query.await("SELECT `skin` FROM `users` WHERE `identifier` = ?", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
elseif FrameworkSelected == 'QBCore' then
local result = MySQL.query.await("SELECT * FROM `playerskins` WHERE `citizenid` = ? AND active = 1", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = json.decode(result[1].skin)
end
end
elseif appearanceResource == 'bl_appearance' then
local result = MySQL.query.await("SELECT * FROM `appearance` WHERE `id` = ?", {convertedIdentifier})
if result and result[1] and result[1].skin then
local decodedSkin = json.decode(result[1].skin)
skin = mergeTables(json.decode(result[1].skin), json.decode(result[1].clothes), json.decode(result[1].tattoos))
end
elseif appearanceResource == 'tgiann-clothing' then
local result = MySQL.query.await("SELECT * FROM tgiann_skin WHERE citizenid = ?", { convertedIdentifier })
if result and result[1] and result[1].skin then
skin = {
skin = json.decode(result[1].skin),
model = tonumber(result[1].model)
}
end
elseif appearanceResource == 'rcore_clothing' then
local rcoreSkin = exports["rcore_clothing"]:getSkinByIdentifier(convertedIdentifier)
skin = {
skin = rcoreSkin.skin,
model = rcoreSkin.ped_model,
}
elseif appearanceResource == 'dx_clothing' then
skin = {
skin = false,
tattoos = false
}
if FrameworkSelected == 'ESX' then
local result = MySQL.query.await("SELECT `skin` FROM `users` WHERE `identifier` = ?", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin.skin = json.decode(result[1].skin)
end
elseif FrameworkSelected == 'QBCore' then
local result = MySQL.query.await("SELECT * FROM `playerskins` WHERE `citizenid` = ? AND active = 1", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin.skin = json.decode(result[1].skin)
end
end
skin.tattoos = exports['dx_clothing']:getTattoosByIdentifier(convertedIdentifier)
elseif appearanceResource == 'karma_clothing' then
local result = MySQL.query.await("SELECT * FROM `playerskins` WHERE `citizenid` = ? AND active = 1", {convertedIdentifier})
if result and result[1] and result[1].skin then
skin = {
skin = {
newSkin = json.decode(result[1].skin),
newHead = {
headblend = {},
features = {},
overlays = {},
eyeColor = 0,
fade = 0,
tattoos = {}
}
}
}
local headDataQuery = MySQL.single.await('SELECT citizenid, model, head_blend, head_features, head_overlays, fade, tattoos, eye_color FROM karma_head_clothing WHERE citizenid = ? LIMIT 1', { convertedIdentifier })
if headDataQuery then
skin.skin.newHead = {
headblend = json.decode(headDataQuery.head_blend),
features = json.decode(headDataQuery.head_features),
overlays = json.decode(headDataQuery.head_overlays),
eyeColor = headDataQuery.eye_color,
fade = headDataQuery.fade,
tattoos = json.decode(headDataQuery.tattoos)
}
end
end
end
if GetResourceState('rcore_tattoos') == 'started' then
local rcoreTattooPromise = promise:new()
debugPrint('[^2CHARACTERS.CONVERTSKIN^7] Awaiting rcore tattoo [/]')
TriggerEvent('rcore_tattoos:getPlayerTattoosByIdentifier', convertedIdentifier, function(tattoos)
if not skin then
skin = {}
end
skin.tattoo = tattoos
rcoreTattooPromise:resolve()
debugPrint('[^2CHARACTERS.CONVERTSKIN^7] Rcore tattoo loaded!')
end)
Citizen.CreateThread(function()
Wait(100)
local startTime = GetGameTimer()
local endTime = startTime + 3000
local currentTime = startTime
while rcoreTattooPromise and rcoreTattooPromise.state == 0 do
currentTime = GetGameTimer()
if currentTime >= endTime then
rcoreTattooPromise:resolve()
debugPrint('[RCORE_TATTOO] Force resolved promise.')
break
end
Wait(100)
end
end)
Citizen.Await(rcoreTattooPromise)
end
if Config.DebugTimers then
print('[CHARACTERS.CONVERTSKIN] Took: ^3'..(GetGameTimer() - startTime)..'ms^7')
end
debugPrint("[^2CHARACTERS.CONVERTSKIN^7] Checked player skin.")
return skin
endThis function represents how data should look like, inside that function make sure to add your auto detection for your appearance (Framework.AppearanceResource variable) (not exactly needed though) and apply your custom logic inside the statement to return variable skin after all.
Setting up player skin
Headover to the /client/framework/framework_functions.lua and find Framework.SetSkin function:
Inside that function add your statement for your specific appearance and add event/export for your appearance to set player skin.
Opening up appearance menu
Headover to the /client/framework/framework_functions.lua and find Framework.OpenSkinMenu function:
Here as above you can add auto detection on Framework.ApperanceResource (it's not needed). Create your statement for your appearance and inside of it add your export to toggle up menu
Last updated