Cette bibliothèque rassemble des scripts FiveM complets, commentés et prêts à l'emploi. Ils fonctionnent sans framework, sauf mention contraire. Chacun tient dans une seule ressource : copiez les fichiers, ajoutez une ligne au server.cfg, redémarrez.
- Créez un dossier dans
resources/[scripts]/, par exempleeso-teleport. - Créez dedans les fichiers indiqués (
fxmanifest.lua,client.lua,server.lua…) avec le gestionnaire de fichiers du panel ou en SFTP. - Ajoutez
ensure eso-teleportà votre server.cfg. - Redémarrez le serveur depuis txAdmin.
Les commandes marquées « admin » sont déclarées avec RegisterCommand(..., true) : seuls les joueurs qui ont le droit ACE correspondant peuvent les utiliser. Ajoutez par exemple add_ace group.admin command allow et add_principal identifier.fivem:VOTRE_ID group.admin à votre server.cfg (voir le guide server.cfg FiveM).
Le manifeste commun
Tous les scripts de cette page utilisent ce manifeste. Retirez les lignes client_script ou server_script si le script n'a pas de fichier correspondant.
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
author 'EsoterHost'
version '1.0.0'
shared_script 'config.lua' -- si le script a un config.lua
client_script 'client.lua'
server_script 'server.lua'1. Téléportation : /tp et /tpm (admin)
Téléporte à des coordonnées (/tp 215 -810 30) ou au point de passage posé sur la carte (/tpm).
local function teleporter(x, y, z)
local ped = PlayerPedId()
local entite = IsPedInAnyVehicle(ped, false) and GetVehiclePedIsIn(ped, false) or ped
DoScreenFadeOut(300)
while not IsScreenFadedOut() do Wait(0) end
-- Cherche le sol : on monte la hauteur jusqu'à trouver une position valide
local sol, zSol = false, z
for hauteur = 0, 1000, 25 do
SetEntityCoordsNoOffset(entite, x, y, hauteur + 0.0, false, false, false)
RequestCollisionAtCoord(x, y, hauteur + 0.0)
Wait(25)
sol, zSol = GetGroundZFor_3dCoord(x, y, hauteur + 0.0, false)
if sol then break end
end
SetEntityCoordsNoOffset(entite, x, y, (sol and zSol or z) + 1.0, false, false, false)
DoScreenFadeIn(300)
end
RegisterCommand('tp', function(_, args)
local x, y, z = tonumber(args[1]), tonumber(args[2]), tonumber(args[3])
if not x or not y then
return TriggerEvent('chat:addMessage', { args = { 'TP', 'Utilisation : /tp x y [z]' } })
end
teleporter(x, y, z or 0.0)
end, true)
RegisterCommand('tpm', function()
local point = GetFirstBlipInfoId(8) -- 8 = point de passage
if not DoesBlipExist(point) then
return TriggerEvent('chat:addMessage', { args = { 'TP', 'Posez un point de passage sur la carte' } })
end
local c = GetBlipInfoIdCoord(point)
teleporter(c.x, c.y, c.z)
end, true)2. Faire apparaître un véhicule : /car (admin)
/car adder fait apparaître une Adder et installe le joueur au volant. /dv supprime le véhicule actuel.
RegisterCommand('car', function(_, args)
local modele = args[1] or 'adder'
local hash = joaat(modele)
if not IsModelInCdimage(hash) or not IsModelAVehicle(hash) then
return TriggerEvent('chat:addMessage', { args = { 'Véhicule', ('Modèle inconnu : %s'):format(modele) } })
end
RequestModel(hash)
local limite = GetGameTimer() + 5000
while not HasModelLoaded(hash) and GetGameTimer() < limite do Wait(10) end
if not HasModelLoaded(hash) then return end
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
-- Supprime l'ancien véhicule du joueur, s'il est dedans
local ancien = GetVehiclePedIsIn(ped, false)
if ancien ~= 0 then DeleteEntity(ancien) end
local vehicule = CreateVehicle(hash, coords.x, coords.y, coords.z, GetEntityHeading(ped), true, false)
SetPedIntoVehicle(ped, vehicule, -1)
SetVehicleNumberPlateText(vehicule, 'ESOTER')
SetVehicleOnGroundProperly(vehicule)
SetEntityAsMissionEntity(vehicule, true, true)
SetModelAsNoLongerNeeded(hash)
end, true)
RegisterCommand('dv', function()
local ped = PlayerPedId()
local vehicule = GetVehiclePedIsIn(ped, false)
if vehicule == 0 then
-- pas dans un véhicule : on prend celui juste devant
local avant = GetOffsetFromEntityInWorldCoords(ped, 0.0, 4.0, 0.0)
vehicule = GetClosestVehicle(avant.x, avant.y, avant.z, 3.0, 0, 70)
end
if vehicule ~= 0 then
SetEntityAsMissionEntity(vehicule, true, true)
DeleteVehicle(vehicule)
end
end, true)3. Réparer et nettoyer : /fix et /clean (admin)
local function vehiculeActuel()
local vehicule = GetVehiclePedIsIn(PlayerPedId(), false)
if vehicule == 0 then
TriggerEvent('chat:addMessage', { args = { 'Garage', 'Montez dans un véhicule' } })
end
return vehicule
end
RegisterCommand('fix', function()
local v = vehiculeActuel()
if v == 0 then return end
SetVehicleFixed(v)
SetVehicleDeformationFixed(v)
SetVehicleEngineHealth(v, 1000.0)
SetVehicleBodyHealth(v, 1000.0)
SetVehiclePetrolTankHealth(v, 1000.0)
SetVehicleUndriveable(v, false)
SetVehicleEngineOn(v, true, true, false)
end, true)
RegisterCommand('clean', function()
local v = vehiculeActuel()
if v == 0 then return end
SetVehicleDirtLevel(v, 0.0)
WashDecalsFromVehicle(v, 1.0)
end, true)4. Soigner et réanimer : /heal et /revive (admin)
RegisterCommand('heal', function()
local ped = PlayerPedId()
SetEntityHealth(ped, GetEntityMaxHealth(ped))
SetPedArmour(ped, 100)
ClearPedBloodDamage(ped)
ResetPedVisibleDamage(ped)
end, true)
RegisterCommand('revive', function()
local ped = PlayerPedId()
local c = GetEntityCoords(ped)
NetworkResurrectLocalPlayer(c.x, c.y, c.z, GetEntityHeading(ped), true, false)
SetEntityHealth(PlayerPedId(), GetEntityMaxHealth(PlayerPedId()))
ClearPedTasksImmediately(PlayerPedId())
end, true)ESX, QBCore et Qbox ont leur propre système de mort et de réanimation (esx_ambulancejob, qb-ambulancejob…). Sur ces serveurs, utilisez leurs commandes plutôt que /revive, pour que l'état du personnage reste cohérent.
5. Annonce à tout le serveur : /annonce (admin)
RegisterCommand('annonce', function(src, args)
local message = table.concat(args, ' ')
if message == '' then return end
TriggerClientEvent('chat:addMessage', -1, {
template = '<div style="padding:8px 12px;margin:4px 0;border-radius:6px;background:rgba(220,60,60,.85)"><b>ANNONCE</b> {0}</div>',
args = { message },
})
print(('[annonce] %s : %s'):format(src == 0 and 'Console' or GetPlayerName(src), message))
end, true)6. Message de bienvenue et nombre de joueurs
AddEventHandler('playerJoining', function()
local src = source
local nom = GetPlayerName(src)
local total = #GetPlayers()
TriggerClientEvent('chat:addMessage', src, {
color = { 0, 200, 255 },
args = { 'Bienvenue', ('Salut %s, tu es le joueur n°%d connecté. Bon jeu !'):format(nom, total) },
})
TriggerClientEvent('chat:addMessage', -1, {
color = { 150, 150, 150 },
args = { 'Serveur', ('%s a rejoint la ville'):format(nom) },
})
end)
RegisterCommand('joueurs', function(src)
local total = #GetPlayers()
local max = GetConvarInt('sv_maxclients', 48)
local texte = ('%d / %d joueurs connectés'):format(total, max)
if src == 0 then return print(texte) end
TriggerClientEvent('chat:addMessage', src, { args = { 'Serveur', texte } })
end, false)7. Liste blanche (whitelist) par identifiant
Seuls les joueurs dont l'identifiant figure dans la liste peuvent entrer. Les autres voient un message pendant la connexion.
Config = {}
Config.Message = "Ce serveur est en liste blanche. Rejoignez notre Discord pour demander l'accès : discord.gg/votre-code"
-- Identifiants autorisés (visibles dans txAdmin, onglet Players)
Config.Autorises = {
['license:0123456789abcdef0123456789abcdef01234567'] = true,
['discord:123456789012345678'] = true,
['fivem:1234567'] = true,
}AddEventHandler('playerConnecting', function(nom, setKickReason, deferrals)
local src = source
deferrals.defer()
Wait(0)
deferrals.update(('Vérification de la liste blanche pour %s…'):format(nom))
for _, identifiant in ipairs(GetPlayerIdentifiers(src)) do
if Config.Autorises[identifiant] then
return deferrals.done() -- accès accordé
end
end
deferrals.done(Config.Message) -- accès refusé, avec le message
end)Pour gérer la liste sans redémarrer, remplacez la table Config.Autorises par une requête : MySQL.scalar.await('SELECT 1 FROM whitelist WHERE identifier = ?', { identifiant }).
8. Blips sur la carte
Affiche des repères sur la carte et la mini-carte. La liste des icônes et des couleurs est sur docs.fivem.net/docs/game-references/blips.
Config = {}
Config.Blips = {
{ nom = 'Commissariat', coords = vector3(428.9, -984.5, 30.7), sprite = 60, couleur = 29, taille = 0.9 },
{ nom = 'Hôpital', coords = vector3(298.6, -584.4, 43.3), sprite = 61, couleur = 2, taille = 0.9 },
{ nom = 'Garage central', coords = vector3(215.8, -810.1, 30.7), sprite = 357, couleur = 3, taille = 0.8 },
{ nom = 'Concessionnaire', coords = vector3(-56.8, -1096.6, 26.4), sprite = 326, couleur = 5, taille = 0.8 },
}CreateThread(function()
for _, b in ipairs(Config.Blips) do
local blip = AddBlipForCoord(b.coords.x, b.coords.y, b.coords.z)
SetBlipSprite(blip, b.sprite)
SetBlipColour(blip, b.couleur)
SetBlipScale(blip, b.taille)
SetBlipAsShortRange(blip, true) -- visible seulement à proximité sur la mini-carte
BeginTextCommandSetBlipName('STRING')
AddTextComponentSubstringPlayerName(b.nom)
EndTextCommandSetBlipName(blip)
end
end)9. Météo et heure synchronisées : /meteo et /heure (admin)
Tous les joueurs voient la même météo et la même heure, gérées par le serveur avec un state bag global.
GlobalState.meteo = GlobalState.meteo or 'CLEAR'
GlobalState.heure = GlobalState.heure or 12
GlobalState.minute = GlobalState.minute or 0
local METEOS = {
CLEAR = true, EXTRASUNNY = true, CLOUDS = true, OVERCAST = true, RAIN = true,
THUNDER = true, FOGGY = true, SMOG = true, CLEARING = true, SNOW = true, XMAS = true,
}
-- L'heure avance d'une minute de jeu toutes les 2 secondes réelles
CreateThread(function()
while true do
Wait(2000)
local m, h = GlobalState.minute + 1, GlobalState.heure
if m >= 60 then m, h = 0, (h + 1) % 24 end
GlobalState.minute, GlobalState.heure = m, h
end
end)
RegisterCommand('meteo', function(src, args)
local m = (args[1] or ''):upper()
if not METEOS[m] then
local msg = 'Météos : CLEAR, EXTRASUNNY, CLOUDS, OVERCAST, RAIN, THUNDER, FOGGY, SMOG, CLEARING, SNOW, XMAS'
if src == 0 then print(msg) else TriggerClientEvent('chat:addMessage', src, { args = { 'Météo', msg } }) end
return
end
GlobalState.meteo = m
end, true)
RegisterCommand('heure', function(_, args)
local h, m = tonumber(args[1]), tonumber(args[2] or 0)
if h and h >= 0 and h < 24 then GlobalState.heure, GlobalState.minute = h, m or 0 end
end, true)local meteoActuelle = nil
CreateThread(function()
while true do
local cible = GlobalState.meteo or 'CLEAR'
if cible ~= meteoActuelle then
SetWeatherTypeOverTime(cible, 15.0) -- transition de 15 secondes
Wait(15000)
meteoActuelle = cible
end
ClearOverrideWeather()
ClearWeatherTypePersist()
SetWeatherTypePersist(meteoActuelle)
SetWeatherTypeNow(meteoActuelle)
SetWeatherTypeNowPersist(meteoActuelle)
SetForceVehicleTrails(meteoActuelle == 'XMAS')
SetForcePedFootstepsTracks(meteoActuelle == 'XMAS')
NetworkOverrideClockTime(GlobalState.heure or 12, GlobalState.minute or 0, 0)
Wait(1000)
end
end)10. Messages automatiques
Diffuse un message différent à intervalle régulier : règlement, Discord, boutique.
local MESSAGES = {
"Rejoignez notre Discord : discord.gg/votre-code",
"Lisez le règlement avant de jouer : /regles",
"Un problème ? Utilisez /report pour contacter l'équipe",
}
local INTERVALLE_MINUTES = 10
CreateThread(function()
local i = 1
while true do
Wait(INTERVALLE_MINUTES * 60 * 1000)
TriggerClientEvent('chat:addMessage', -1, { color = { 255, 200, 0 }, args = { 'Info', MESSAGES[i] } })
i = i % #MESSAGES + 1
end
end)11. Expulsion des joueurs inactifs (anti-AFK)
Un joueur qui ne bouge pas pendant 15 minutes est expulsé, après deux avertissements. Les administrateurs sont épargnés.
local LIMITE = 15 * 60 -- secondes
local AVERTISSEMENTS = { 120, 60 } -- secondes restantes au moment d'avertir
local derniereAction = GetGameTimer()
local dernierePosition = vector3(0, 0, 0)
local averti = {}
CreateThread(function()
while true do
Wait(5000)
local pos = GetEntityCoords(PlayerPedId())
if #(pos - dernierePosition) > 1.0 then
derniereAction = GetGameTimer()
dernierePosition = pos
averti = {}
end
local restant = LIMITE - (GetGameTimer() - derniereAction) // 1000
if restant <= 0 then
TriggerServerEvent('eso-afk:expulser')
else
for _, seuil in ipairs(AVERTISSEMENTS) do
if restant <= seuil and not averti[seuil] then
averti[seuil] = true
TriggerEvent('chat:addMessage', { color = { 255, 120, 0 }, args = { 'AFK', ('Bougez, sinon vous serez expulsé dans %d secondes'):format(restant) } })
end
end
end
end
end)RegisterNetEvent('eso-afk:expulser', function()
local src = source
if IsPlayerAceAllowed(src, 'afk.ignorer') then return end
DropPlayer(src, 'Expulsé pour inactivité. Vous pouvez vous reconnecter.')
end)Pour épargner un groupe : add_ace group.admin afk.ignorer allow dans le server.cfg.
12. Journal des connexions sur Discord
Envoie un message dans un salon Discord à chaque arrivée et départ, avec les identifiants du joueur. Créez un webhook dans les paramètres du salon Discord (Intégrations, Webhooks), puis ajoutez au server.cfg :
set eso_logs_webhook "https://discord.com/api/webhooks/xxxx/yyyy"local WEBHOOK = GetConvar('eso_logs_webhook', '')
local function envoyer(titre, description, couleur)
if WEBHOOK == '' then return end
PerformHttpRequest(WEBHOOK, function() end, 'POST', json.encode({
username = 'Journal du serveur',
embeds = { {
title = titre,
description = description,
color = couleur,
timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ'),
} },
}), { ['Content-Type'] = 'application/json' })
end
local function identifiants(src)
local lignes = {}
for _, id in ipairs(GetPlayerIdentifiers(src)) do
if not id:find('^ip:') then lignes[#lignes + 1] = '`' .. id .. '`' end -- l'adresse IP n'est pas publiée
end
return table.concat(lignes, '\n')
end
AddEventHandler('playerJoining', function()
local src = source
envoyer('Connexion', ('**%s**\n%s'):format(GetPlayerName(src), identifiants(src)), 3066993)
end)
AddEventHandler('playerDropped', function(raison)
local src = source
envoyer('Déconnexion', ('**%s**\nRaison : %s'):format(GetPlayerName(src), raison), 15158332)
end)13. Texte au-dessus du joueur : /me
Affiche une action au-dessus de la tête du joueur pendant 6 secondes, visible par les joueurs proches. Très utilisé en roleplay.
RegisterCommand('me', function(src, args)
local texte = table.concat(args, ' ')
if src == 0 or texte == '' or #texte > 120 then return end
TriggerClientEvent('eso-me:afficher', -1, src, texte)
end, false)local actifs = {}
local function dessinerTexte3D(coords, texte)
local visible, x, y = World3dToScreen2d(coords.x, coords.y, coords.z)
if not visible then return end
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextColour(220, 180, 255, 230)
SetTextCentre(true)
SetTextOutline()
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(texte)
EndTextCommandDisplayText(x, y)
end
RegisterNetEvent('eso-me:afficher', function(serverId, texte)
local joueur = GetPlayerFromServerId(serverId)
if joueur == -1 then return end -- joueur trop loin, pas chargé chez nous
local ped = GetPlayerPed(joueur)
if #(GetEntityCoords(ped) - GetEntityCoords(PlayerPedId())) > 25.0 then return end
local id = {}
actifs[id] = true
local fin = GetGameTimer() + 6000
CreateThread(function()
while GetGameTimer() < fin and actifs[id] do
dessinerTexte3D(GetEntityCoords(ped) + vector3(0.0, 0.0, 1.0), '* ' .. texte .. ' *')
Wait(0)
end
actifs[id] = nil
end)
end)14. Signalement aux administrateurs : /report
Le joueur envoie un message, les administrateurs connectés le reçoivent (avec l'identifiant du joueur pour répondre).
local derniers = {}
RegisterCommand('report', function(src, args)
if src == 0 then return end
local message = table.concat(args, ' ')
if message == '' then
return TriggerClientEvent('chat:addMessage', src, { args = { 'Report', 'Utilisation : /report votre message' } })
end
if derniers[src] and os.time() - derniers[src] < 60 then
return TriggerClientEvent('chat:addMessage', src, { args = { 'Report', 'Patientez une minute entre deux signalements' } })
end
derniers[src] = os.time()
local recus = 0
for _, id in ipairs(GetPlayers()) do
if IsPlayerAceAllowed(id, 'report.recevoir') then
TriggerClientEvent('chat:addMessage', id, {
color = { 255, 80, 80 },
args = { ('Report de %s [%s]'):format(GetPlayerName(src), src), message },
})
recus = recus + 1
end
end
TriggerClientEvent('chat:addMessage', src, {
args = { 'Report', recus > 0 and 'Message transmis à l\'équipe' or 'Aucun membre de l\'équipe connecté, réessayez plus tard' },
})
end, false)
AddEventHandler('playerDropped', function() derniers[source] = nil end)Donnez le droit de recevoir les signalements : add_ace group.admin report.recevoir allow.
15. Zones sûres
Dans une zone sûre, les armes sont rangées et les joueurs ne peuvent ni tirer ni se battre.
Config = {}
Config.Zones = {
{ nom = 'Hôpital', centre = vector3(298.6, -584.4, 43.3), rayon = 40.0 },
{ nom = 'Commissariat', centre = vector3(428.9, -984.5, 30.7), rayon = 35.0 },
}local dansZone = nil
CreateThread(function()
while true do
local pos = GetEntityCoords(PlayerPedId())
local trouvee = nil
for _, z in ipairs(Config.Zones) do
if #(pos - z.centre) < z.rayon then trouvee = z break end
end
if trouvee ~= dansZone then
dansZone = trouvee
local texte = trouvee and ('Zone sûre : %s'):format(trouvee.nom) or 'Vous quittez la zone sûre'
BeginTextCommandThefeedPost('STRING')
AddTextComponentSubstringPlayerName(texte)
EndTextCommandThefeedPostTicker(false, true)
end
Wait(500)
end
end)
CreateThread(function()
while true do
if dansZone then
local ped = PlayerPedId()
SetCurrentPedWeapon(ped, `WEAPON_UNARMED`, true)
DisablePlayerFiring(PlayerId(), true)
DisableControlAction(0, 24, true) -- attaque
DisableControlAction(0, 25, true) -- viser
DisableControlAction(0, 140, true) -- coup léger
DisableControlAction(0, 141, true) -- coup fort
DisableControlAction(0, 142, true) -- coup alternatif
Wait(0)
else
Wait(500)
end
end
end)16. Sauvegarde de la dernière position (sans framework)
À la reconnexion, le joueur réapparaît là où il s'était déconnecté. Nécessite oxmysql.
CREATE TABLE IF NOT EXISTS eso_positions (
identifier VARCHAR(64) PRIMARY KEY,
x FLOAT NOT NULL, y FLOAT NOT NULL, z FLOAT NOT NULL, h FLOAT NOT NULL
);fx_version 'cerulean'
game 'gta5'
lua54 'yes'
dependency 'oxmysql'
client_script 'client.lua'
server_scripts { '@oxmysql/lib/MySQL.lua', 'server.lua' }local function license(src) return GetPlayerIdentifierByType(src, 'license') end
AddEventHandler('playerDropped', function()
local src = source
local id = license(src)
local ped = GetPlayerPed(src)
if not id or ped == 0 then return end
local c = GetEntityCoords(ped)
if #c < 1.0 then return end -- position inconnue, on n'enregistre pas
MySQL.insert('REPLACE INTO eso_positions (identifier, x, y, z, h) VALUES (?, ?, ?, ?, ?)',
{ id, c.x, c.y, c.z, GetEntityHeading(ped) })
end)
RegisterNetEvent('eso-position:demander', function()
local src = source
local row = MySQL.single.await('SELECT x, y, z, h FROM eso_positions WHERE identifier = ?', { license(src) })
if row then TriggerClientEvent('eso-position:placer', src, row) end
end)AddEventHandler('playerSpawned', function()
TriggerServerEvent('eso-position:demander')
end)
RegisterNetEvent('eso-position:placer', function(p)
SetEntityCoordsNoOffset(PlayerPedId(), p.x, p.y, p.z, false, false, false)
SetEntityHeading(PlayerPedId(), p.h)
end)ESX, QBCore et Qbox enregistrent déjà la position du personnage. N'installez ce script que sur un serveur sans framework.
17. Salaire automatique (ESX Legacy et QBCore)
Verse un salaire à chaque joueur connecté toutes les 15 minutes, selon son métier. Les deux frameworks ont déjà un système de paie : ce script montre comment en écrire un sur mesure (bonus de présence, primes de week-end…).
local ESX = exports['es_extended']:getSharedObject()
local INTERVALLE = 15 * 60 * 1000
local BONUS_PRESENCE = 50 -- versé à tous, même sans emploi
CreateThread(function()
while true do
Wait(INTERVALLE)
for _, xPlayer in pairs(ESX.GetExtendedPlayers()) do
local salaire = (xPlayer.job.grade_salary or 0) + BONUS_PRESENCE
if salaire > 0 then
xPlayer.addAccountMoney('bank', salaire, 'Salaire')
xPlayer.showNotification(('Salaire versé : %d $'):format(salaire))
end
end
end
end)local QBCore = exports['qb-core']:GetCoreObject()
local INTERVALLE = 15 * 60 * 1000
local BONUS_PRESENCE = 50
CreateThread(function()
while true do
Wait(INTERVALLE)
for _, Player in pairs(QBCore.Functions.GetQBPlayers()) do
local job = Player.PlayerData.job
local paie = (job.onduty and job.payment or 0) + BONUS_PRESENCE
if paie > 0 then
Player.Functions.AddMoney('bank', paie, 'salaire')
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, ('Salaire versé : %d $'):format(paie), 'success')
end
end
end
end)18. Moins de PNJ et de circulation
Allège la ville : utile pour les gros serveurs roleplay et pour les performances.
Config = {}
Config.Pietons = 0.5 -- 0.0 = aucun, 1.0 = normal
Config.Circulation = 0.4
Config.Stationnes = 0.4
Config.SansPolice = true -- pas de police ni de recherche par l'IACreateThread(function()
while true do
SetPedDensityMultiplierThisFrame(Config.Pietons)
SetScenarioPedDensityMultiplierThisFrame(Config.Pietons, Config.Pietons)
SetVehicleDensityMultiplierThisFrame(Config.Circulation)
SetRandomVehicleDensityMultiplierThisFrame(Config.Circulation)
SetParkedVehicleDensityMultiplierThisFrame(Config.Stationnes)
Wait(0)
end
end)
CreateThread(function()
if not Config.SansPolice then return end
while true do
local joueur = PlayerId()
if GetPlayerWantedLevel(joueur) > 0 then
SetPlayerWantedLevel(joueur, 0, false)
SetPlayerWantedLevelNow(joueur, false)
end
SetMaxWantedLevel(0)
for i = 1, 15 do EnableDispatchService(i, false) end
Wait(1000)
end
end)19. Compteur de vitesse simple
Affiche la vitesse en km/h en bas de l'écran quand le joueur conduit.
local vehicule = 0
CreateThread(function()
while true do
vehicule = GetVehiclePedIsIn(PlayerPedId(), false)
Wait(500)
end
end)
CreateThread(function()
while true do
if vehicule ~= 0 and GetPedInVehicleSeat(vehicule, -1) == PlayerPedId() then
local kmh = math.floor(GetEntitySpeed(vehicule) * 3.6)
SetTextFont(4)
SetTextScale(0.6, 0.6)
SetTextColour(255, 255, 255, 220)
SetTextOutline()
BeginTextCommandDisplayText('STRING')
AddTextComponentSubstringPlayerName(('%d km/h'):format(kmh))
EndTextCommandDisplayText(0.16, 0.92)
Wait(0)
else
Wait(500)
end
end
end)20. Commande /id et liste des joueurs proches
RegisterCommand('id', function()
local monId = GetPlayerServerId(PlayerId())
local proches = {}
local maPos = GetEntityCoords(PlayerPedId())
for _, joueur in ipairs(GetActivePlayers()) do
if joueur ~= PlayerId() then
local d = #(GetEntityCoords(GetPlayerPed(joueur)) - maPos)
if d < 30.0 then
proches[#proches + 1] = ('%s [%d]'):format(GetPlayerName(joueur), GetPlayerServerId(joueur))
end
end
end
TriggerEvent('chat:addMessage', { args = { 'ID', ('Votre ID : %d'):format(monId) } })
if #proches > 0 then
TriggerEvent('chat:addMessage', { args = { 'Proches', table.concat(proches, ', ') } })
end
end, false)Aller plus loin
- Comprendre chaque notion utilisée ici : Créer un script FiveM en Lua.
- Adapter ces scripts à un framework : ESX Legacy, QBCore ou Qbox.
- Vérifier qu'ils restent légers : Optimiser un serveur FiveM.
Ces scripts sont libres : modifiez-les, combinez-les, utilisez-les sur votre serveur.
EsoterHost n'est ni approuvé, ni sponsorisé, ni affilié à Rockstar Games ou à Cfx.re. FiveM et Grand Theft Auto V sont des marques de leurs propriétaires.
