Character Creation

The utils.character_creation module contains most of the functions you would need to developer a character creation system, clothing stores, tattoo stores, etc etc.

All of these functions are currently being used for the character creation process within the boii_core multicharacter.

Functions

get_clothing_and_prop_values()

Gets all clothing and prop values for specified sex.

Function

local function get_clothing_and_prop_values(sex)
    if not sex == 'm' or not sex == 'f' then  
        debug_log('err', "Function: get_clothing_and_prop_values failed | Reason: Invalid parameters for sex. - Use 'm' or 'f' only.") 
        return
    end
    local data = utils.shared.style[sex]
    local values = {
        hair = GetNumberOfPedDrawableVariations(PlayerPedId(), 2) - 1,
        fade = GetNumberOfPedTextureVariations(PlayerPedId(), 2, tonumber(data.barber.hair)) - 1,
        eyebrow = GetPedHeadOverlayNum(2) - 1,
        mask = GetNumberOfPedDrawableVariations(PlayerPedId(), 1) - 1,
        mask_texture = GetNumberOfPedTextureVariations(PlayerPedId(), 1, tonumber(data.clothing.mask_style) - 1)
    }
    return values
end

exports('character_creation_get_clothing_and_prop_values', get_clothing_and_prop_values)
utils.character_creation.get_clothing_and_prop_values = get_clothing_and_prop_values

Example

--- Return all values for the 'm' sex.
local values = utils.character_creation.get_clothing_and_prop_values('m')

set_ped_appearance()

Sets all appearance options to the current player ped model.

Function

local function set_ped_appearance(player, data)
    if not player or not data then 
        debug_log('err', 'Function: set_ped_appearance failed | Reason: Missing one or more required parameters. - player and data are required.') 
        return
    end
    SetPedHeadBlendData(player, tonumber(data.genetics.mother), tonumber(data.genetics.father), nil, tonumber(data.genetics.mother), tonumber(data.genetics.father), nil, tonumber(data.genetics.resemblence), tonumber(data.genetics.skin), nil, true)
    SetPedEyeColor(player, data.genetics.eye_colour)
    SetPedComponentVariation(player, 2, tonumber(data.barber.hair), 0, 0)
    SetPedHairColor(player, tonumber(data.barber.hair_colour), tonumber(data.barber.highlight_colour))
    for _, feature in ipairs(FACIAL_FEATURES) do
        SetPedFaceFeature(player, feature.index, tonumber(data.genetics[feature.value]))
    end
    for _, overlay in ipairs(OVERLAYS) do
        local style = tonumber(data.barber[overlay.style])
        local opacity = tonumber(data.barber[overlay.opacity])
        if opacity then
            opacity = opacity / 100
        end
        SetPedHeadOverlay(player, overlay.index, style, opacity)
        if overlay.colour and data.barber[overlay.colour] then
            local colour = tonumber(data.barber[overlay.colour])
            if colour then
                SetPedHeadOverlayColor(player, overlay.index, 1, colour, colour)
            else
                debug_log('err', 'Function: set_ped_appearance failed | Reason: Invalid overlay colour for ' .. overlay.style) 
            end
        end
    end
    for _, item in ipairs(CLOTHING_ITEMS) do
        local style = tonumber(data.clothing[item.style])
        local texture = tonumber(data.clothing[item.texture])
        if style and style >= 0 then
            if item.is_prop then
                SetPedPropIndex(player, item.index, style, texture, true)
            else 
                SetPedComponentVariation(player, item.index, style, texture, 0)
            end
        end
    end
    ClearPedDecorations(player)
    if data.tattoos then
        for zone, tattoo_info in pairs(data.tattoos) do
            if tattoo_info and tattoo_info.name and tattoo_info.name ~= 'none' then
                local tattoo_hash = data.sex == 'm' and GetHashKey(tattoo_info.hash_m) or GetHashKey(tattoo_info.hash_f)
                if tattoo_hash and tattoo_info.collection then
                    SetPedDecoration(player, GetHashKey(tattoo_info.collection), tattoo_hash)
                else
                    debug_log('err', 'Function: set_ped_appearance failed | Reason: Invalid tattoo hash or collection for tattoo in zone: ' .. zone) 
                end
            end
        end
    else
        debug_log('err', 'Function: set_ped_appearance failed | Reason: No tattoo data found in character data.') 
    end
    debug_log('info', 'Function: set_ped_appearance | Note: Success!')
end

exports('character_creation_set_ped_appearance', set_ped_appearance)
utils.character_creation.set_ped_appearance = set_ped_appearance

Example

--- Set player ped back to utils shared styles.
utils.character_creation.set_ped_appearance(PlayerPedId(), utils.shared.style['m'])

update_ped_data()

Updates utils shared player styles with new values.

Function

local function update_ped_data(sex, category, id, value)
    if not sex or not category or not id or not value then  debug_log('err', 'Function: update_ped_data failed | Reason: Missing one or more required parameters. - sex, category, id, or value.')  return end
    if id == 'resemblance' or id == 'skin' then
        value = value / 100
    end
    if type(utils.shared.style[sex][category][id]) == 'table' then -- 198
        for k, _ in pairs(utils.shared.style[sex][category][id]) do
            utils.shared.style[sex][category][id][k] = value[k]
        end
    else
        utils.shared.style[sex][category][id] = value
    end
    current_sex = sex
    preview_ped = (sex == 'm') and 'mp_m_freemode_01' or 'mp_f_freemode_01'
    set_ped_appearance(PlayerPedId(), utils.shared.style[sex])
end

exports('character_creation_update_ped_data', update_ped_data)
utils.character_creation.update_ped_data = update_ped_data

Example

--- Updates mother genetics for 'm' to 1.
utils.character_creation.update_ped_data('m', 'genetics', 'mother', 1)

change_player_ped()

Used to change the players current ped between default freemode peds..

Function

local function change_player_ped(sex)
    if not sex then
        debug_log('err', 'Function: change_player_ped failed. | Reason: Player sex was not provided.')
        return
    end
    current_sex = sex
    preview_ped = (sex == 'm') and 'mp_m_freemode_01' or 'mp_f_freemode_01'
    local model = GetHashKey(preview_ped)
    utils.requests.model(model)
    SetPlayerModel(PlayerId(), model)
    set_ped_appearance(PlayerPedId(), utils.shared.style[sex])
end

exports('character_creation_change_player_ped', change_player_ped)
utils.character_creation.change_player_ped = change_player_ped

Example

--- Changed player to ped for 'm' sex.
utils.character_creation.change_player_ped(current_sex)

rotate_ped()

Rotates the players ped in a specified direction.

Function

local function rotate_ped(direction)
    if not direction then
        debug_log('err', 'Function: rotate_ped failed. | Reason: Direction parameter is missing.')
        return
    end
    local player_ped = PlayerPedId()
    local current_heading = GetEntityHeading(player_ped)
    local new_heading
    if original_heading == nil then
        original_heading = current_heading
    end
    if direction == 'rotate_ped_right' then
        new_heading = current_heading + 45
    elseif direction == 'rotate_ped_left' then
        new_heading = current_heading - 45
    elseif direction == 'rotate_ped_180' then
        new_heading = original_heading + 180
    elseif direction == 'rotate_ped_reset' then
        new_heading = original_heading
        original_heading = nil
    else
        debug_log('err', "Function: rotate_ped failed. | Reason: Invalid direction parameter - Use 'rotate_ped_right', 'rotate_ped_left', 'rotate_ped_180' or 'rotate_ped_reset'.")
        return
    end
    new_heading = new_heading % 360
    SetEntityHeading(player_ped, new_heading)
end

exports('character_creation_rotate_ped', rotate_ped)
utils.character_creation.rotate_ped = rotate_ped

Example

--- Rotates the player ped right 45 degrees.
utils.character_creation.rotate_ped('rotate_ped_right')

load_character_model()

Loads and applies a character model with specified data.

You need to make sure you are sending through the chosen sex within your data otherwise utils.shared cannot set the correct style options.

Function

local function load_character_model(data)
    if not data.identity or not data.style.genetics or not data.style.barber or not data.style.clothing or not data.style.tattoos then
        debug_log('err', 'Function: load_character_model failed. | Reason: One or more required parameters are missing.')
        return
    end

    current_sex = data.identity.sex -- THIS WILL NEED TO BE UPDATED TO YOUR OWN METHOD OF GETTING THE PLAYERS SEX
    
    local model = GetHashKey(preview_ped)
    if not utils.requests.model(model) then
        debug_log('err', "Function: load_character_model failed. | Reason: Failed to request model: " .. preview_ped)
        return
    end
    local player_id = PlayerId()
    local player_ped = PlayerPedId()
    SetPlayerModel(player_id, model)
    SetPedComponentVariation(player_ped, 0, 0, 0, 1)
    utils.shared.style[current_sex].genetics = data.style.genetics
    utils.shared.style[current_sex].barber = data.style.barber
    utils.shared.style[current_sex].clothing = data.style.clothing
    utils.shared.style[current_sex].tattoos = data.style.tattoos
    set_ped_appearance(player_ped, utils.shared.style[current_sex])
end

exports('character_creation_load_character_model', load_character_model)
utils.character_creation.load_character_model = load_character_model

Example

--- Load character from incoming data.
utils.character_creation.load_character_model(data)

Last updated