Upload files to "client"
This commit is contained in:
parent
e4c16c876a
commit
fd2c6e0051
|
|
@ -2,6 +2,7 @@
|
||||||
print("^2[turfwar]^7 appearance.lua loaded (client)")
|
print("^2[turfwar]^7 appearance.lua loaded (client)")
|
||||||
|
|
||||||
local appearance = nil
|
local appearance = nil
|
||||||
|
local choosing = false
|
||||||
|
|
||||||
local function IsFreemodeModel(hash)
|
local function IsFreemodeModel(hash)
|
||||||
return hash == GetHashKey("mp_m_freemode_01") or hash == GetHashKey("mp_f_freemode_01")
|
return hash == GetHashKey("mp_m_freemode_01") or hash == GetHashKey("mp_f_freemode_01")
|
||||||
|
|
@ -30,6 +31,74 @@ local function ForcePlayerModel(modelName)
|
||||||
return (GetEntityModel(PlayerPedId()) == model)
|
return (GetEntityModel(PlayerPedId()) == model)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function ApplyDefaultHeadBlend(ped, gender)
|
||||||
|
if gender == "f" then
|
||||||
|
SetPedHeadBlendData(ped,
|
||||||
|
21, 0, 0,
|
||||||
|
21, 0, 0,
|
||||||
|
0.55, 0.0, 0.0,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
else
|
||||||
|
SetPedHeadBlendData(ped,
|
||||||
|
0, 0, 0,
|
||||||
|
0, 0, 0,
|
||||||
|
0.5, 0.5, 0.0,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 0, 19 do
|
||||||
|
SetPedFaceFeature(ped, i, 0.0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clamp(n, a, b)
|
||||||
|
if n < a then return a end
|
||||||
|
if n > b then return b end
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
|
||||||
|
local function SendStateToUI()
|
||||||
|
if not appearance then return end
|
||||||
|
SendNUIMessage({
|
||||||
|
type = "appearance:state",
|
||||||
|
gender = appearance.gender or "m",
|
||||||
|
hair_drawable = tonumber(appearance.hair_drawable) or 0,
|
||||||
|
hair_color = tonumber(appearance.hair_color) or 0
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function OpenChooser()
|
||||||
|
if choosing then return end
|
||||||
|
choosing = true
|
||||||
|
SetNuiFocus(true, true)
|
||||||
|
SetNuiFocusKeepInput(true)
|
||||||
|
SendNUIMessage({ type = "appearance:show" })
|
||||||
|
SendStateToUI()
|
||||||
|
|
||||||
|
-- light input lock so they don't move/shoot while choosing
|
||||||
|
CreateThread(function()
|
||||||
|
while choosing do
|
||||||
|
DisableAllControlActions(0)
|
||||||
|
-- allow looking around / mouse
|
||||||
|
EnableControlAction(0, 1, true) -- LookLeftRight
|
||||||
|
EnableControlAction(0, 2, true) -- LookUpDown
|
||||||
|
EnableControlAction(0, 239, true) -- Cursor X
|
||||||
|
EnableControlAction(0, 240, true) -- Cursor Y
|
||||||
|
Wait(0)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function CloseChooser()
|
||||||
|
if not choosing then return end
|
||||||
|
choosing = false
|
||||||
|
SendNUIMessage({ type = "appearance:hide" })
|
||||||
|
SetNuiFocus(false, false)
|
||||||
|
SetNuiFocusKeepInput(false)
|
||||||
|
end
|
||||||
|
|
||||||
local function ApplyAppearanceNow()
|
local function ApplyAppearanceNow()
|
||||||
if not appearance then return end
|
if not appearance then return end
|
||||||
|
|
||||||
|
|
@ -43,30 +112,9 @@ local function ApplyAppearanceNow()
|
||||||
ped = PlayerPedId()
|
ped = PlayerPedId()
|
||||||
if not ped or ped == 0 then return end
|
if not ped or ped == 0 then return end
|
||||||
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)
|
ApplyDefaultHeadBlend(ped, appearance.gender)
|
||||||
|
|
||||||
-- 2) Ensure freemode
|
-- 2) Ensure freemode
|
||||||
if not IsFreemodeModel(GetEntityModel(ped)) then
|
if not IsFreemodeModel(GetEntityModel(ped)) then
|
||||||
print("^1[turfwar]^7 ApplyAppearanceNow: not freemode even after force (something else is overriding model).")
|
print("^1[turfwar]^7 ApplyAppearanceNow: not freemode even after force (something else is overriding model).")
|
||||||
|
|
@ -79,13 +127,11 @@ end
|
||||||
|
|
||||||
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
|
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
|
||||||
if maxHair > 0 then
|
if maxHair > 0 then
|
||||||
if hairDrawable < 0 then hairDrawable = 0 end
|
hairDrawable = clamp(hairDrawable, 0, maxHair - 1)
|
||||||
if hairDrawable >= maxHair then hairDrawable = maxHair - 1 end
|
|
||||||
|
|
||||||
local maxTex = GetNumberOfPedTextureVariations(ped, 2, hairDrawable)
|
local maxTex = GetNumberOfPedTextureVariations(ped, 2, hairDrawable)
|
||||||
if maxTex <= 0 then maxTex = 1 end
|
if maxTex <= 0 then maxTex = 1 end
|
||||||
if hairTexture < 0 then hairTexture = 0 end
|
hairTexture = clamp(hairTexture, 0, maxTex - 1)
|
||||||
if hairTexture >= maxTex then hairTexture = maxTex - 1 end
|
|
||||||
|
|
||||||
SetPedComponentVariation(ped, 2, hairDrawable, hairTexture, 0)
|
SetPedComponentVariation(ped, 2, hairDrawable, hairTexture, 0)
|
||||||
end
|
end
|
||||||
|
|
@ -97,12 +143,11 @@ end
|
||||||
|
|
||||||
local numColors = GetNumHairColors()
|
local numColors = GetNumHairColors()
|
||||||
if numColors and numColors > 0 then
|
if numColors and numColors > 0 then
|
||||||
c = math.max(0, math.min(c, numColors - 1))
|
c = clamp(c, 0, numColors - 1)
|
||||||
h = math.max(0, math.min(h, numColors - 1))
|
h = clamp(h, 0, numColors - 1)
|
||||||
else
|
else
|
||||||
-- fallback clamp
|
c = clamp(c, 0, 63)
|
||||||
c = math.max(0, math.min(c, 63))
|
h = clamp(h, 0, 63)
|
||||||
h = math.max(0, math.min(h, 63))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
SetPedHairColor(ped, c, h)
|
SetPedHairColor(ped, c, h)
|
||||||
|
|
@ -110,13 +155,22 @@ end
|
||||||
print(("[turfwar] appearance applied: gender=%s hair=%d/%d color=%d/%d")
|
print(("[turfwar] appearance applied: gender=%s hair=%d/%d color=%d/%d")
|
||||||
:format(tostring(appearance.gender), hairDrawable, hairTexture, c, h))
|
:format(tostring(appearance.gender), hairDrawable, hairTexture, c, h))
|
||||||
|
|
||||||
-- Tell main.lua (optional) that appearance has been applied
|
|
||||||
TriggerEvent("turfwar:appearance:applied")
|
TriggerEvent("turfwar:appearance:applied")
|
||||||
end
|
end
|
||||||
|
|
||||||
RegisterNetEvent("turfwar:appearance:update", function(row)
|
RegisterNetEvent("turfwar:appearance:update", function(row)
|
||||||
appearance = row
|
appearance = row
|
||||||
ApplyAppearanceNow()
|
ApplyAppearanceNow()
|
||||||
|
|
||||||
|
-- If server says this was a fresh insert, open chooser
|
||||||
|
if row and row.isNew then
|
||||||
|
OpenChooser()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Keep UI numbers in sync while choosing
|
||||||
|
if choosing then
|
||||||
|
SendStateToUI()
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Request on resource start & spawn
|
-- Request on resource start & spawn
|
||||||
|
|
@ -135,67 +189,83 @@ AddEventHandler("playerSpawned", function()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Commands
|
-- =========================
|
||||||
RegisterCommand("tw_gender", function(_, args)
|
-- NUI callbacks
|
||||||
local g = args[1] and args[1]:lower() or ""
|
-- =========================
|
||||||
if g ~= "m" and g ~= "f" then
|
RegisterNUICallback("appearance:setGender", function(data, cb)
|
||||||
print("^3[turfwar]^7 Usage: /tw_gender m OR /tw_gender f")
|
local g = (data and data.gender) or "m"
|
||||||
return
|
if g ~= "m" and g ~= "f" then g = "m" end
|
||||||
end
|
|
||||||
TriggerServerEvent("turfwar:appearance:setGender", g)
|
TriggerServerEvent("turfwar:appearance:setGender", g)
|
||||||
end, false)
|
cb({ ok = true })
|
||||||
|
end)
|
||||||
|
|
||||||
RegisterCommand("tw_hair_next", function()
|
RegisterNUICallback("appearance:hairNext", function(_, cb)
|
||||||
if not appearance then return end
|
if not appearance then cb({ ok=false }) return end
|
||||||
local ped = PlayerPedId()
|
local ped = PlayerPedId()
|
||||||
if ped == 0 then return end
|
if ped == 0 then cb({ ok=false }) return end
|
||||||
|
|
||||||
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
|
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
|
||||||
if maxHair <= 0 then
|
if maxHair <= 0 then cb({ ok=false }) return end
|
||||||
print("^1[turfwar]^7 No hair variations on this model.")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local cur = GetPedDrawableVariation(ped, 2)
|
local cur = GetPedDrawableVariation(ped, 2)
|
||||||
local nxt = (cur + 1) % maxHair
|
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, 0, appearance.hair_color, appearance.hair_highlight)
|
||||||
TriggerServerEvent("turfwar:appearance:setHair", nxt, tex, appearance.hair_color, appearance.hair_highlight)
|
cb({ ok = true })
|
||||||
end, false)
|
end)
|
||||||
|
|
||||||
RegisterCommand("tw_hair_prev", function()
|
RegisterNUICallback("appearance:hairPrev", function(_, cb)
|
||||||
if not appearance then return end
|
if not appearance then cb({ ok=false }) return end
|
||||||
local ped = PlayerPedId()
|
local ped = PlayerPedId()
|
||||||
if ped == 0 then return end
|
if ped == 0 then cb({ ok=false }) return end
|
||||||
|
|
||||||
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
|
local maxHair = GetNumberOfPedDrawableVariations(ped, 2)
|
||||||
if maxHair <= 0 then return end
|
if maxHair <= 0 then cb({ ok=false }) return end
|
||||||
|
|
||||||
local cur = GetPedDrawableVariation(ped, 2)
|
local cur = GetPedDrawableVariation(ped, 2)
|
||||||
local prv = (cur - 1)
|
local prv = cur - 1
|
||||||
if prv < 0 then prv = maxHair - 1 end
|
if prv < 0 then prv = maxHair - 1 end
|
||||||
|
|
||||||
TriggerServerEvent("turfwar:appearance:setHair", prv, 0, appearance.hair_color, appearance.hair_highlight)
|
TriggerServerEvent("turfwar:appearance:setHair", prv, 0, appearance.hair_color, appearance.hair_highlight)
|
||||||
end, false)
|
cb({ ok = true })
|
||||||
|
end)
|
||||||
|
|
||||||
RegisterCommand("tw_haircolor", function(_, args)
|
RegisterNUICallback("appearance:colorNext", function(_, cb)
|
||||||
if not appearance then return end
|
if not appearance then cb({ ok=false }) 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()
|
local num = GetNumHairColors()
|
||||||
print("^3[turfwar]^7 Commands:")
|
if not num or num <= 0 then num = 64 end
|
||||||
print("^3[turfwar]^7 /tw_gender m|f")
|
|
||||||
print("^3[turfwar]^7 /tw_hair_next (cycle)")
|
local c = tonumber(appearance.hair_color) or 0
|
||||||
print("^3[turfwar]^7 /tw_hair_prev (cycle)")
|
c = (c + 1) % num
|
||||||
print("^3[turfwar]^7 /tw_haircolor <color> [highlight]")
|
|
||||||
|
TriggerServerEvent("turfwar:appearance:setHair", appearance.hair_drawable, appearance.hair_texture, c, c)
|
||||||
|
cb({ ok = true })
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterNUICallback("appearance:colorPrev", function(_, cb)
|
||||||
|
if not appearance then cb({ ok=false }) return end
|
||||||
|
|
||||||
|
local num = GetNumHairColors()
|
||||||
|
if not num or num <= 0 then num = 64 end
|
||||||
|
|
||||||
|
local c = tonumber(appearance.hair_color) or 0
|
||||||
|
c = c - 1
|
||||||
|
if c < 0 then c = num - 1 end
|
||||||
|
|
||||||
|
TriggerServerEvent("turfwar:appearance:setHair", appearance.hair_drawable, appearance.hair_texture, c, c)
|
||||||
|
cb({ ok = true })
|
||||||
|
end)
|
||||||
|
|
||||||
|
RegisterNUICallback("appearance:save", function(_, cb)
|
||||||
|
-- Nothing special needed: we already write to DB on every click
|
||||||
|
CloseChooser()
|
||||||
|
cb({ ok = true })
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- =========================
|
||||||
|
-- Keep your commands too (optional)
|
||||||
|
-- =========================
|
||||||
|
RegisterCommand("tw_appearance_ui", function()
|
||||||
|
OpenChooser()
|
||||||
end, false)
|
end, false)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user