Turfwar/client/appearance.lua

202 lines
6.4 KiB
Lua

-- client/appearance.lua
print("^2[turfwar]^7 appearance.lua loaded (client)")
local appearance = nil
local function IsFreemodeModel(hash)
return hash == GetHashKey("mp_m_freemode_01") or hash == GetHashKey("mp_f_freemode_01")
end
local function ForcePlayerModel(modelName)
local model = GetHashKey(modelName)
if not IsModelInCdimage(model) or not IsModelValid(model) then
print(("^1[turfwar]^7 INVALID model: %s"):format(modelName))
return false
end
RequestModel(model)
local timeout = GetGameTimer() + 8000
while not HasModelLoaded(model) do
Wait(0)
if GetGameTimer() > timeout then
print(("^1[turfwar]^7 TIMEOUT loading model: %s"):format(modelName))
return false
end
end
SetPlayerModel(PlayerId(), model)
SetModelAsNoLongerNeeded(model)
Wait(200)
return (GetEntityModel(PlayerPedId()) == model)
end
local function ApplyAppearanceNow()
if not appearance then return end
local ped = PlayerPedId()
if not ped or ped == 0 then return end
-- 1) Force model
local desired = (appearance.gender == "f") and "mp_f_freemode_01" or "mp_m_freemode_01"
if GetEntityModel(ped) ~= GetHashKey(desired) then
ForcePlayerModel(desired)
ped = PlayerPedId()
if not ped or ped == 0 then return end
end
local function ApplyDefaultHeadBlend(ped, gender)
if gender == "f" then
-- softer defaults for female
SetPedHeadBlendData(ped,
21, 0, 0, -- shape (mother-ish)
21, 0, 0, -- skin
0.55, 0.0, 0.0,
false
)
else
SetPedHeadBlendData(ped,
0, 0, 0,
0, 0, 0,
0.5, 0.5, 0.0,
false
)
end
-- neutralize extreme face features (optional)
for i = 0, 19 do
SetPedFaceFeature(ped, i, 0.0)
end
end
ApplyDefaultHeadBlend(ped, appearance.gender)
-- 2) Ensure freemode
if not IsFreemodeModel(GetEntityModel(ped)) then
print("^1[turfwar]^7 ApplyAppearanceNow: not freemode even after force (something else is overriding model).")
return
end
-- 3) Hair style validation (component 2)
local hairDrawable = tonumber(appearance.hair_drawable) or 0
local hairTexture = tonumber(appearance.hair_texture) or 0
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
if maxHair > 0 then
if hairDrawable < 0 then hairDrawable = 0 end
if hairDrawable >= maxHair then hairDrawable = maxHair - 1 end
local maxTex = GetNumberOfPedTextureVariations(ped, 2, hairDrawable)
if maxTex <= 0 then maxTex = 1 end
if hairTexture < 0 then hairTexture = 0 end
if hairTexture >= maxTex then hairTexture = maxTex - 1 end
SetPedComponentVariation(ped, 2, hairDrawable, hairTexture, 0)
end
-- 4) Hair color
local c = tonumber(appearance.hair_color) or 0
local h = tonumber(appearance.hair_highlight)
if h == nil then h = c end
local numColors = GetNumHairColors()
if numColors and numColors > 0 then
c = math.max(0, math.min(c, numColors - 1))
h = math.max(0, math.min(h, numColors - 1))
else
-- fallback clamp
c = math.max(0, math.min(c, 63))
h = math.max(0, math.min(h, 63))
end
SetPedHairColor(ped, c, h)
print(("[turfwar] appearance applied: gender=%s hair=%d/%d color=%d/%d")
:format(tostring(appearance.gender), hairDrawable, hairTexture, c, h))
-- Tell main.lua (optional) that appearance has been applied
TriggerEvent("turfwar:appearance:applied")
end
RegisterNetEvent("turfwar:appearance:update", function(row)
appearance = row
ApplyAppearanceNow()
end)
-- Request on resource start & spawn
AddEventHandler("onClientResourceStart", function(res)
if res ~= GetCurrentResourceName() then return end
CreateThread(function()
Wait(500)
TriggerServerEvent("turfwar:appearance:request")
end)
end)
AddEventHandler("playerSpawned", function()
CreateThread(function()
Wait(700)
TriggerServerEvent("turfwar:appearance:request")
end)
end)
-- Commands
RegisterCommand("tw_gender", function(_, args)
local g = args[1] and args[1]:lower() or ""
if g ~= "m" and g ~= "f" then
print("^3[turfwar]^7 Usage: /tw_gender m OR /tw_gender f")
return
end
TriggerServerEvent("turfwar:appearance:setGender", g)
end, false)
RegisterCommand("tw_hair_next", function()
if not appearance then return end
local ped = PlayerPedId()
if ped == 0 then return end
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
if maxHair <= 0 then
print("^1[turfwar]^7 No hair variations on this model.")
return
end
local cur = GetPedDrawableVariation(ped, 2)
local nxt = (cur + 1) % maxHair
local maxTex = GetNumberOfPedTextureVariations(ped, 2, nxt)
if maxTex <= 0 then maxTex = 1 end
local tex = 0
TriggerServerEvent("turfwar:appearance:setHair", nxt, tex, appearance.hair_color, appearance.hair_highlight)
end, false)
RegisterCommand("tw_hair_prev", function()
if not appearance then return end
local ped = PlayerPedId()
if ped == 0 then return end
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
if maxHair <= 0 then return end
local cur = GetPedDrawableVariation(ped, 2)
local prv = (cur - 1)
if prv < 0 then prv = maxHair - 1 end
TriggerServerEvent("turfwar:appearance:setHair", prv, 0, appearance.hair_color, appearance.hair_highlight)
end, false)
RegisterCommand("tw_haircolor", function(_, args)
if not appearance then return end
local c = tonumber(args[1])
local h = tonumber(args[2])
if c == nil then
print("^3[turfwar]^7 Usage: /tw_haircolor <color> [highlight]")
return
end
if h == nil then h = c end
TriggerServerEvent("turfwar:appearance:setHair", appearance.hair_drawable, appearance.hair_texture, c, h)
end, false)
RegisterCommand("tw_appearance", function()
print("^3[turfwar]^7 Commands:")
print("^3[turfwar]^7 /tw_gender m|f")
print("^3[turfwar]^7 /tw_hair_next (cycle)")
print("^3[turfwar]^7 /tw_hair_prev (cycle)")
print("^3[turfwar]^7 /tw_haircolor <color> [highlight]")
end, false)