2026-04-14 17:41:39 +02:00

323 lines
10 KiB
Lua

SkinChanger = {}
SkinChanger._index = SkinChanger
SkinChanger.lastSex = -1
SkinChanger.character = {}
SkinChanger.components = Config.Components
function SkinChanger:RequestModel(model)
if type(model) == "string" then
model = joaat(model)
end
RequestModel(model)
while not HasModelLoaded(model) do
Wait(200)
end
return model
end
function SkinChanger:ModelLoaded()
ClearPedProp(PlayerPedId(), 0)
if self.loadSkin ~= nil then
self:ApplySkin(self.loadSkin)
self.loadSkin = nil
end
if self.loadClothes ~= nil then
self:ApplySkin(self.loadClothes.playerSkin, self.loadClothes.clothesSkin)
self.loadClothes = nil
end
end
function SkinChanger:DefaultModel(male, cb)
local characterModel = male and `mp_m_freemode_01` or `mp_f_freemode_01`
if not IsModelInCdimage(characterModel) or not IsModelValid(characterModel) then
return
end
local model = self:RequestModel(characterModel)
SetPlayerModel(PlayerId(), model)
SetPedDefaultComponentVariation(PlayerPedId())
SetModelAsNoLongerNeeded(model)
if cb then
cb()
end
self:ModelLoaded()
end
function SkinChanger:MaxValues()
local playerPed = PlayerPedId()
local data = {}
for i = 1, #self.components, 1 do
local component = self.components[i]
local max = type(component.max) == "function" and component.max(playerPed, self.character) or component.max
data[component.name] = max
end
return data
end
function SkinChanger:DefaultFromSex(sex, cb)
if sex == 0 then
self:DefaultModel(true, cb)
else
self:DefaultModel(false, cb)
end
end
function SkinChanger:LoadSkin(skin, cb)
local sex = skin["sex"]
if sex ~= self.lastSex then
self.loadSkin = skin
self:DefaultFromSex(sex, cb)
self.lastSex = sex
else
self:ApplySkin(skin)
if cb ~= nil then
cb()
else
return
end
end
end
function SkinChanger:ValidClothes(key)
local keys = {["sex"] = true, ["mom"] = true, ["dad"] = true, ["face_md_weight"] = true, ["skin_md_weight"] = true, ["nose_1"] = true, ["nose_2"] = true,
["nose_3"] = true, ["nose_4"] = true, ["nose_5"] = true, ["nose_6"] = true, ["cheeks_1"] = true, ["cheeks_2"] = true, ["cheeks_3"] = true,
["lip_thickness"] = true, ["jaw_1"] = true, ["jaw_2"] = true, ["chin_1"] = true, ["chin_2"] = true, ["chin_3"] = true, ["chin_4"] = true,
["neck_thickness"] = true, ["age_1"] = true, ["age_2"] = true, ["eye_color"] = true, ["eye_squint"] = true, ["beard_1"] = true, ["beard_2"] = true,
["beard_3"] = true, ["beard_4"] = true, ["hair_1"] = true, ["hair_2"] = true, ["hair_color_1"] = true, ["hair_color_2"] = true, ["eyebrows_1"] = true,
["eyebrows_2"] = true, ["eyebrows_3"] = true, ["eyebrows_4"] = true, ["eyebrows_5"] = true, ["eyebrows_6"] = true, ["makeup_1"] = true, ["makeup_2"] = true,
["makeup_3"] = true, ["makeup_4"] = true, ["lipstick_1"] = true, ["lipstick_2"] = true, ["lipstick_3"] = true, ["lipstick_4"] = true, ["blemishes_1"] = true,
["blemishes_2"] = true, ["blemishes_3"] = true, ["blush_1"] = true, ["blush_2"] = true, ["blush_3"] = true, ["complexion_1"] = true, ["complexion_2"] = true,
["sun_1"] = true, ["sun_2"] = true, ["moles_1"] = true, ["moles_2"] = true, ["chest_1"] = true, ["chest_2"] = true, ["chest_3"] = true, ["bodyb_1"] = true,
["bodyb_2"] = true, ["bodyb_3"] = true, ["bodyb_4"] = true}
return keys[key] == nil
end
local function Normalise(weight, divison)
return (weight / divison) + 0.0
end
function SkinChanger:SetHead()
local face_weight = Normalise(self.character["face_md_weight"], 100)
local skin_weight = Normalise(self.character["skin_md_weight"], 100)
if not self.character["face_g_weight"] then
self.character["face_g_weight"] = 0
end
local third_weight = Normalise(self.character["face_g_weight"], 100)
if not self.character["grandparents"] then
self.character["grandparents"] = 0
end
SetPedHeadBlendData(self.playerPed,
self.character["mom"], self.character["dad"], self.character["grandparents"] , self.character["mom"],
self.character["dad"], self.character["grandparents"], face_weight, skin_weight, third_weight, false)
end
function SkinChanger:SetFace()
local features = {"nose_1", "nose_2", "nose_3", "nose_4", "nose_5", "nose_6", "eyebrows_5", "eyebrows_6", "cheeks_1", "cheeks_2", "cheeks_3", "eye_squint", "lip_thickness", "jaw_1", "jaw_2", "chin_1", "chin_2", "chin_3", "chin_4", "neck_thickness"}
for i = 1, #features, 1 do
local feature = features[i]
SetPedFaceFeature(self.playerPed, i - 1, Normalise(self.character[feature], 10))
end
SetPedEyeColor(self.playerPed, self.character["eye_color"]) -- Eyes color
end
function SkinChanger:SetHeadOverlay()
local features = {{"blemishes_1", "blemishes_2"}, {"beard_1", "beard_2"}, {"eyebrows_1", "eyebrows_2"}, {"age_1", "age_2"}, {"makeup_1", "makeup_2"}, {"blush_1", "blush_2"}, {"complexion_1", "complexion_2"}, {"sun_1", "sun_2"}, {"lipstick_1", "lipstick_2"}, {"moles_1", "moles_2"}, {"chest_1", "chest_2"}}
for i = 1, #features, 1 do
local feature = features[i]
SetPedHeadOverlay(self.playerPed, i - 1, self.character[feature[1]], Normalise(self.character[feature[2]], 10))
end
end
function SkinChanger:SetHeadOverlayColour()
local features = {[1] = {"beard_3", "beard_4"}, [2] = {"eyebrows_3", "eyebrows_4"}, [4] = {"makeup_3", "makeup_4"}, [5] = {"blush_3", 0}, [8] = {"lipstick_3", "lipstick_4"}, [10] = {"chest_3", 0}}
for i, feature in pairs(features) do
SetPedHeadOverlayColor(self.playerPed, i, 1, self.character[feature[1]], self.character[feature[2]])
end
if self.character["bodyb_1"] == -1 then
SetPedHeadOverlay(self.playerPed, 11, 255, (self.character["bodyb_2"] / 10) + 0.0) -- Body Blemishes + opacity
else
SetPedHeadOverlay(self.playerPed, 11, self.character["bodyb_1"], (self.character["bodyb_2"] / 10) + 0.0)
end
if self.character["bodyb_3"] == -1 then
SetPedHeadOverlay(self.playerPed, 12, 255, (self.character["bodyb_4"] / 10) + 0.0)
else
SetPedHeadOverlay(self.playerPed, 12, self.character["bodyb_3"], (self.character["bodyb_4"] / 10) + 0.0) -- Blemishes 'added body effect' + opacity
end
end
function SkinChanger:SetHair()
SetPedComponentVariation(self.playerPed, 2, self.character["hair_1"], self.character["hair_2"], 2) -- Hair
SetPedHairColor(self.playerPed, self.character["hair_color_1"], self.character["hair_color_2"]) -- Hair Color
end
function SkinChanger:SetComponents()
local components = {{"tshirt_1", "tshirt_2", 8}, {"torso_1", "torso_2", 11}, {"decals_1", "decals_2", 10}, {"arms", "arms_2", 3}, {"pants_1", "pants_2", 4}, {"shoes_1", "shoes_2", 6}, {"mask_1", "mask_2", 1}, {"bproof_1", "bproof_2", 9}, {"chain_1", "chain_2", 7}, {"bags_1", "bags_2", 5}}
for i = 1, #components, 1 do
local component = components[i]
SetPedComponentVariation(self.playerPed, component[3], self.character[component[1]], self.character[component[2]], 2)
end
end
function SkinChanger:SetProps()
local props = {{"helmet_1", "helmet_2", 0}, {"glasses_1", "glasses_2", 1}, {"ears_1", "ears_2", 2}, {"watches_1", "watches_2", 6}, {"bracelets_1", "bracelets_2", 7}}
for i = 1, #props, 1 do
local prop = props[i]
local propVal = self.character[prop[1]]
if propVal == -1 then
ClearPedProp(self.playerPed, prop[3])
else
SetPedPropIndex(self.playerPed, prop[3], propVal, self.character[prop[2]], true)
end
end
end
function SkinChanger:ApplySkin(skin, clothes)
self.playerPed = PlayerPedId()
for k, v in pairs(skin) do
self.character[k] = v
end
if clothes ~= nil then
for k, v in pairs(clothes) do
if self:ValidClothes(k) then
self.character[k] = v
end
end
end
self:SetHead()
self:SetHair()
self:SetFace()
self:SetHeadOverlay()
self:SetHeadOverlayColour()
self:SetComponents()
self:SetProps()
return true
end
function SkinChanger:LoadClothes(playerSkin, clothesSkin)
local sex = playerSkin["sex"]
if sex ~= self.lastSex then
self.loadClothes = {
playerSkin = playerSkin,
clothesSkin = clothesSkin,
}
self:DefaultFromSex(sex)
self.lastSex = sex
return true
else
return self:ApplySkin(playerSkin, clothesSkin)
end
end
function SkinChanger:Change(key, val)
self.character[key] = val
if key == "sex" then
self:LoadSkin(self.character)
else
self:ApplySkin(self.character)
end
end
function SkinChanger:Init()
for i = 1, #self.components, 1 do
local component = self.components[i]
self.character[component.name] = component.value
end
end
function SkinChanger:GetData(noMax)
local components = SkinChanger.components
for k, v in pairs(SkinChanger.character) do
for i = 1, #components, 1 do
if k == components[i].name then
components[i].value = v
end
end
end
return components, noMax and nil or self:MaxValues()
end
--- exports
exports("GetSkin", function()
return SkinChanger.character
end)
exports("GetMaxVals", function()
return SkinChanger:MaxValues()
end)
exports("LoadSkin", function(skin)
return SkinChanger:LoadSkin(skin)
end)
exports("GetData", function(noMax)
return SkinChanger:GetData(noMax)
end)
exports("LoadClothes", function(playerSkin, clothesSkin)
return SkinChanger:LoadClothes(playerSkin, clothesSkin)
end)
exports("Change", function(key, val)
return SkinChanger:Change(key, val)
end)
--- Events
RegisterNetEvent("skinchanger:loadSkin", function(skin, cb)
SkinChanger:LoadSkin(skin, cb)
end)
RegisterNetEvent("skinchanger:loadClothes", function(playerSkin, clothesSkin)
SkinChanger:LoadClothes(playerSkin, clothesSkin)
end)
AddEventHandler("skinchanger:getSkin", function(cb)
cb(SkinChanger.character)
end)
AddEventHandler("skinchanger:loadDefaultModel", function(loadMale, cb)
SkinChanger:DefaultModel(loadMale, cb)
end)
AddEventHandler("skinchanger:change", function(key, val)
SkinChanger:Change(key, val)
end)
AddEventHandler("skinchanger:modelLoaded", function()
SkinChanger:ModelLoaded()
end)
AddEventHandler("skinchanger:getData", function(cb)
cb(SkinChanger:GetData())
end)
SkinChanger:Init()