Explorer
KNOW-PAT-108

FiveM - Animation Config with Webhooks : placing, group sync, music, Fivemanage SDK

Domaine
fivem
Type
pattern
Priorité
P3

Parent : [[INDEX-FIVEM-GAMEPLAY]]

FiveM - Animation Config with Webhooks : placing, group sync, music, Fivemanage SDK

Problème

Un système d'émotes/animations avancé nécessite : placement précis des props, synchronisation de groupe (danse), musique synchronisée, et logging des événements via Discord ou Fivemanage.

Solution

Configuration d'animations avancée (placing, group sync, music, speed control) avec logging via Fivemanage SDK et webhooks Discord.

-- bablo-animations/config.lua
Config = {}

-- Debug mode
Config.Debug = false

-- Framework auto-detect
Config.Framework = 'auto' -- 'esx', 'qbcore', 'standalone', 'auto'

-- Keybinds
Config.Keybinds = {
    emoteMenu = 'F5',
    cancelEmote = 'X',
    walkStyle = 'Z'
}

-- Placing mode (placer les props manuellement)
Config.Placing = {
    Enabled = true,
    Precision = 0.01, -- Pas de déplacement
    RotationSpeed = 5.0,
    Controls = {
        move = { keys = { 'W', 'A', 'S', 'D' }, mode = 'relative' },
        rotate = { keys = { 'LEFT', 'RIGHT' }, axis = 'z' },
        confirm = 'ENTER',
        cancel = 'BACKSPACE'
    }
}

-- Group sync (danse synchronisée)
Config.GroupSync = {
    Enabled = true,
    MaxDistance = 5.0,
    LeaderElection = 'first' -- 'first', 'random', 'vote'
}

-- Musique synchronisée avec les émotes
Config.Music = {
    Enabled = true,
    MaxDistance = 5.0,
    MaxDuration = 180, -- secondes
    Volume = 0.5,
    Sources = {
        'nui', -- Lecteur NUI interne
        'xsound' -- Resource externe xsound
    }
}

-- Logging
Config.Webhooks = {
    Discord = {
        Enabled = true,
        URL = 'https://discord.com/api/webhooks/...',
        Events = {
            'emote_used',
            'group_dance_started',
            'music_played',
            'prop_placed'
        },
        Colors = {
            emote_used = 3447003,
            group_dance_started = 3066993,
            music_played = 15158332,
            prop_placed = 9807270
        }
    },
    Fivemanage = {
        Enabled = false,
        apiKey = '', -- À configurer
        dataset = 'bablo-animations',
        useSDK = false -- true = SDK Fivemanage, false = HTTP direct
    }
}

-- Fonction de logging
function LogEvent(eventType, playerData, details)
    if not Config.Webhooks.Discord.Enabled then return end
    
    local embed = {
        {
            title = eventType:gsub('_', ' '):upper(),
            description = details,
            color = Config.Webhooks.Discord.Colors[eventType] or 0,
            timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ'),
            footer = { text = 'bablo-animations' },
            fields = {
                { name = 'Joueur', value = playerData.name, inline = true },
                { name = 'ID', value = tostring(playerData.id), inline = true },
                { name = 'Identifier', value = playerData.identifier, inline = false }
            }
        }
    }
    
    PerformHttpRequest(Config.Webhooks.Discord.URL, function() end, 'POST',
        json.encode({ embeds = embed }),
        { ['Content-Type'] = 'application/json' }
    )
end

Pourquoi

  • Placing mode permet aux joueurs de positionner précisément les props
  • Group sync synchronise les animations de danse entre joueurs proches
  • Music avec distance max évite le spam audio sur toute la map
  • Fivemanage SDK pour le logging avancé avec analytics

Quand l'utiliser

  • Systèmes d'émotes premium
  • Events DJ/concerts avec musique synchronisée
  • Systèmes de placement de props décoratifs

Quand NE PAS l'utiliser

  • Émotes simples sans props → overkill

Exemples

Correct

-- Group dance avec leader election
RegisterNetEvent('bablo:joinGroupDance')
AddEventHandler('bablo:joinGroupDance', function(groupId)
    local src = source
    local group = Groups[groupId]
    if not group then return end
    
    -- Vérification distance
    local leaderPed = GetPlayerPed(group.leader)
    local joinerPed = GetPlayerPed(src)
    local dist = #(GetEntityCoords(leaderPed) - GetEntityCoords(joinerPed))
    
    if dist > Config.GroupSync.MaxDistance then
        TriggerClientEvent('ox_lib:notify', src, { type = 'error', description = 'Trop loin du groupe' })
        return
    end
    
    table.insert(group.members, src)
    TriggerClientEvent('bablo:startGroupSync', src, group.currentEmote)
    
    LogEvent('group_dance_started', {
        id = src,
        name = GetPlayerName(src),
        identifier = ESX.GetPlayerFromId(src).getIdentifier()
    }, ('Rejoint le groupe %s (%s membres)'):format(groupId, #group.members))
end)

Incorrect

-- Musique sans distance limit → spam serveur
RegisterNetEvent('emote:playMusic')
AddEventHandler('emote:playMusic', function(soundFile)
    TriggerClientEvent('emote:playSound', -1, soundFile) -- Tout le monde entend
end)

Références

  • bablo-animations/config.lua L1-80
  • bablo-animations/webhooks.lua L1-80