Inside the GTAV Ped drawable components and props are stored in named groups called collections. However, collections were previously unavailable for FiveM users. The drawable components and props were indexed through global index. On every TU (Title Update) the global index of custom drawable components and props would change (see below for more details on why it happens). This complicates migration to the latest game build.
The new set of natives allows accessing drawable components and props through collections. The collection-based indexes remain stable after TUs. So using these natives will simplify all future TU updates for a server.
Note: The new natives are currently available for GTAV and on client side only.
Note: Drawable components and props are stored in Ped in the same way. Below we will refer to drawable components / drawables only.
You can think of collections in Ped as list of buckets placed one after another. Each collection is named and contains multiple drawables.
Global index is an index of drawable starting from the beginning of the set. Local index is an index of drawable starting from the beginning of each collection.
E.g.:
Official GTAV collections | Custom collections | |||||||||||||
Collection names | "" | "female_freemode_beach" | "female_xmas" | "custom_collection_1" | "custom_collection_2" | |||||||||
Local indexes | 0 | 1 | 0 | 1 | 2 | 3 | 0 | 1 | 2 | 0 | 1 | 2 | 0 | 1 |
Global indexes | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
The first collection corresponds to the base game (without any DLCs). After the base game collection follow collection that correspond to official DLCs. Custom collections are added to the end.
After TU is released and new official DLC collection is added - all custom collections are shifted. So, the global indexes that correspond to custom collections shift and must be updated on every TU. While the indexes that are relative to the beginning of a collection will remain stable after TU.
The base game name collection is an empty string. Names of other collections are set by <CPedVariationInfo name="...">
tag of the corresponding .ymt
file. E.g. see Grand Theft Auto V\update\x64\dlcpacks\mp2024_01\dlc.rpf\x64\models\cdimages\mp2024_01_female.rpf\mp_f_freemode_01_mp_f_2024_01.ymt
base game file.
There are three groups of new natives:
Below are some example lua scripts that illustrate usage of the new natives.
Listing all collections available for ped and number of component and prop drawable variations available in each collection:
function printFullCollectionInfo(ped, collectionName)
print(string.format(" Name: \"%s\"", collectionName))
print(" Number of drawable variations per component number:")
-- See https://docs.fivem.net/natives/?_0x262B14F48D29DE80 for the list of all components.
for i = 0, 12 do
local drawableVariationsCount = GetNumberOfPedCollectionDrawableVariations(ped, i, collectionName)
print(string.format(" For component %d: %d", i, drawableVariationsCount))
end
print(" Number of drawable variations per anchor point:")
-- See https://docs.fivem.net/natives/?_0x93376B65A266EB5F for the list of all anchor points.
for i = 0, 12 do
local drawablePropVariationsCount = GetNumberOfPedCollectionPropDrawableVariations(ped, i, collectionName)
print(string.format(" For anchor %d: %d", i, drawablePropVariationsCount))
end
end
function printFullCollectionsInfo(ped)
local collectionsCount = GetPedCollectionsCount(ped)
print(string.format("Found %d collections", collectionsCount))
for i = 0, collectionsCount - 1 do
local collectionName = GetPedCollectionName(ped, i)
print(string.format("Collection %d", i))
printFullCollectionInfo(ped, collectionName)
end
end
RegisterCommand('PrintFullPlayerPedCollectionsInfo', function(source)
local playerPed = PlayerPedId()
printFullCollectionsInfo(playerPed)
end, true)
Set new ped look (for mp_f_freemode_01
ped model, see https://docs.fivem.net/docs/game-references/ped-models/, other models may have less drawable variations available):
function setLook(ped)
-- Use head (component id 0) from base game collection (empty string) and local index 27.
-- Base game collection indexes and global indexes are the same (see documentation above).
-- Same as SetPedComponentVariation(ped, 0, 27, 0, 0)
SetPedCollectionComponentVariation(ped, 0, '', 27, 0, 0)
-- Use pants (component id 4) from mpHeist DLC collection ("female_heist"), local index 9 and texture number 3.
-- Same as SetPedComponentVariation(ped, 4, 41, 3, 0)
SetPedCollectionComponentVariation(ped, 4, 'female_heist', 9, 3, 0)
-- Use hat (anchor point 0) from mpBiker DLC collection ("mp_f_bikerdlc_01"), local index 0 and texture number 0.
-- Same as SetPedPropIndex(ped, 0, 82, 0, 0)
SetPedCollectionPropIndex(ped, 0, 'mp_f_bikerdlc_01', 0, 0, false)
end
function testInvalidComponentVariation(ped)
-- Attempt to set shirt (component id 11) from mpBeach DLC collection ("female_freemode_beach") but invalid (out of bounds) local index 999999.
-- The component drawable variation will not be set since the variation is invalid.
SetPedCollectionComponentVariation(ped, 11, 'female_freemode_beach', 999999, 0, 0)
-- Confirm that previously requested drawable variation is indeed invalid.
-- Same as IsPedComponentVariationValid(ped, 11, 999999 + 16, 0, 0)
-- +16 because there are 16 drawable variations in the base game collection that go before the mpBeach DLC collection.
if not IsPedCollectionComponentVariationValid(ped, 11, 'female_freemode_beach', 999999, 0, 0) then
print("Invalid component drawable variation was requested.")
end
end
RegisterCommand('SetPlayerPedLook', function(source)
local playerPed = PlayerPedId()
setLook(playerPed)
testInvalidComponentVariation(playerPed)
end, true)
Print information about drawable variations that are set for the ped:
function printPedLookInfo(ped, componentId)
print(string.format("For component id %d, the following drawable is used:", componentId))
local collectionName = GetPedDrawableVariationCollectionName(ped, componentId)
local collectionLocalIndex = GetPedDrawableVariationCollectionLocalIndex(ped, componentId)
print(string.format(" Collection name: \"%s\"", collectionName))
print(string.format(" Local drawable index: %d", collectionLocalIndex))
-- Will get the same result as if we called GetPedDrawableVariation(ped, componentId)
local globalDrawableIndex = GetPedDrawableGlobalIndexFromCollection(ped, componentId, collectionName, collectionLocalIndex)
print(string.format(" Which corresponds to global drawable index: %d", globalDrawableIndex))
end
RegisterCommand('PrintPlayerPantsInfo', function(source)
local playerPed = PlayerPedId()
-- Print info about drawable variation that is set as pants (component id 4).
printPedLookInfo(playerPed, 4)
end, true)