0.0.1
This commit is contained in:
322
resources/[core]/skinchanger/client/main.lua
Normal file
322
resources/[core]/skinchanger/client/main.lua
Normal file
@@ -0,0 +1,322 @@
|
||||
|
||||
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()
|
||||
Reference in New Issue
Block a user