Parent : [[INDEX-FIVEM-GAMEPLAY]]
FiveM - Native HeadBlendData Manipulation : extraction et restauration via InvokeNative
Problème
Lorsqu'un joueur équipe/retire un masque ou change d'accessoire, les données de blend de la tête (visage, peau, traits) peuvent être perdues ou corrompues par certains natives GTA.
Solution
Extraction des données de blend de tête via Citizen.InvokeNative et PointerValueIntInitialized, stockage temporaire, et restauration manuelle après changement d'accessoires.
local function getHeadBlendData(ped)
local tbl = {
Citizen.InvokeNative(0x2746BD9D88C5C5D0, ped,
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0),
Citizen.PointerValueIntInitialized(0)
)
}
return {
shapeFirst = tbl[1],
shapeSecond = tbl[2],
shapeThird = tbl[3],
skinFirst = tbl[4],
skinSecond = tbl[5],
skinThird = tbl[6],
shapeMix = tbl[7],
skinMix = tbl[8],
thirdMix = tbl[9]
}
end
-- Sauvegarde avant changement
local savedBlendData = nil
RegisterNetEvent('mask:equip')
AddEventHandler('mask:equip', function(maskIndex)
local ped = PlayerPedId()
-- Sauvegarde uniquement si c'est un freemode model
if IsFreemodeModel(ped) then
savedBlendData = getHeadBlendData(ped)
end
-- Application du masque
SetPedComponentVariation(ped, 1, maskIndex, 0, 2)
-- Restauration après un court délai (le native de masque peut écraser)
Wait(100)
if savedBlendData then
SetPedHeadBlendData(ped,
savedBlendData.shapeFirst,
savedBlendData.shapeSecond,
savedBlendData.shapeThird,
savedBlendData.skinFirst,
savedBlendData.skinSecond,
savedBlendData.skinThird,
savedBlendData.shapeMix,
savedBlendData.skinMix,
savedBlendData.thirdMix,
false
)
end
end)
local function IsFreemodeModel(ped)
local model = GetEntityModel(ped)
return model == GetHashKey('mp_m_freemode_01') or model == GetHashKey('mp_f_freemode_01')
end
Pourquoi
SetPedComponentVariationpour le masque peut réinitialiser le blendCitizen.InvokeNative(0x2746BD9D88C5C5D0)estGetPedHeadBlendData(native non exposée en Lua)PointerValueIntInitializedpermet de récupérer les valeurs passées par référence
Quand l'utiliser
- Scripts d'accessoires (masques, lunettes, chapeaux)
- Systèmes de chirurgie esthétique / barbier
- Sauvegarde/restauration d'apparence complète
Quand NE PAS l'utiliser
- Si vous utilisez un système de skins complet (qb-clothing, illenium-appearance) qui gère déjà le blend
Exemples
Correct
-- Wrapper avec timeout pour éviter les boucles infinies
local function safeGetHeadBlendData(ped, maxAttempts)
maxAttempts = maxAttempts or 50
local attempts = 0
local data
repeat
data = getHeadBlendData(ped)
attempts = attempts + 1
Wait(10)
until data.shapeFirst ~= 0 or attempts >= maxAttempts
return data
end
Incorrect
-- Invocation directe sans PointerValue → crash ou valeurs incorrectes
local blend = Citizen.InvokeNative(0x2746BD9D88C5C5D0, ped, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-- Les 0 ne sont pas des pointeurs initialisés → données corrompues
Références
- mask-fix/client.lua L26-58
- GTA V Native DB : GET_PED_HEAD_BLEND_DATA