Aller au contenu
Toute la documentation

PVP

Système PvP avec zones FFA, zones Only et matchs de lobby en équipes. Chaque zone et chaque match tourne dans sa propre dimension. En plus, il y a un classement et un affichage de match. Le script crée lui-même la table.

Prérequis
  • ESX Legacy (es_extended, testé avec 1.14)
  • oxmysql
  • OneSync
  • Dans ESX, Config.EnablePVP = true doit être activé (par défaut)
  • Pour le menu du garage sur les maps véhicule : esxmenudefault (ou ton propre menu via ClientVehicleMenu)

Fonctionnalités

  • Zones FFA : chacun pour soi. Par zone, des armes fixes ou les propres armes du joueur. Respawn avec gilet et courte protection au spawn.
  • Zones Only : tout le monde a les mêmes armes, en option avec un véhicule (p. ex. BF 400) à chaque spawn.
  • Lobbys : équipe A contre équipe B en mode best-of avec manche décisive. Map, mode (à pied ou véhicule), manches, jusqu'à 3 armes et un mot de passe optionnel au choix. Le propriétaire peut expulser, mélanger et dissoudre.
  • Spectateur : celui qui est éliminé pendant une manche regarde ses coéquipiers encore en vie et change avec ← →.
  • Affichage de match en haut au centre et Classement avec les filtres FFA, Only et Lobby (victoires et défaites comprises).
  • Protection des armes : les armes fixes n'existent qu'en PvP. Les vraies armes et leurs munitions restent protégées.
  • Logs Discord, exports et tes propres fonctions pour brancher d'autres scripts.

Installation

  1. Place le dossier off_pvp dans ton dossier resources.
  2. Ajoute dans le server.cfg, après oxmysql et ESX :
cfg
ensure oxmysql
ensure es_extended
ensure off_pvp
  1. Adapte les points PvP, les zones et les maps dans config/ à ton serveur.

La table off_pvp_stats est créée automatiquement au premier démarrage.

Coordonnées d'exemple

Les zones dans config/settings/config.ffa.lua et config/settings/config.only.lua et les maps dans config/settings/config.lobby.lua ne sont que des exemples. Vérifie toutes les positions en jeu et mets les tiennes.

Configuration

Les réglages se trouvent dans config/settings/ : config.lua pour tout ce qui est général, config.ffa.lua, config.only.lua et config.lobby.lua pour les trois modes.

config/settings/config.lua

OptionPar défautDescription
serverInfo.name'OFF SCRIPTS'Nom du serveur, affiché dans l'interface à la place de « OFF SCRIPTS »
serverInfo.locale'de'Langue : de, en, pl, fr, es ou it
serverInfo.color{ 155, 89, 255 }Couleur de l'UI (RGB)
serverInfo.design3Design de l'interface : 1 = Classique, 2 = Ticket, 3 = Storefront
blurtrueFond flou tant que le menu est ouvert
quitCommand'quitffa'Commande pour quitter le FFA, le Only, les lobbys et les matchs en cours
defaultPed's_m_y_valet_01'PNJ pour les points sans ped valide
points1 exemplePoints PvP où E ouvre le menu (voir plus bas)
markervoir fichierApparence des points marker : type, size, alpha, drawDistance
respawn.seconds3Temps d'attente avant le respawn en FFA et Only
respawn.protection3Secondes d'invulnérabilité après le spawn
respawn.armour100Gilet après le spawn
killHealtrueVie et gilet au maximum après chaque kill (FFA, Only et Lobby)
leaderboardSize50Nombre de joueurs affichés par mode dans le classement (3–500)

Points PvP (points) :

ChampDescription
idNom unique du point
labelNom dans le texte d'aide et sur le blip
positionvec4(x, y, z, heading)
interaction'ped' = PNJ, 'marker' = marker au sol
pedModèle du PNJ, sans modèle valide defaultPed s'applique
scenarioAnimation du PNJ (optionnel)
blip{ sprite, color, scale }, false = pas de blip

config/settings/config.ffa.lua et config/settings/config.only.lua

Config.ffa et Config.only contiennent les zones. Chaque zone a :

ChampDescription
idNom unique, c'est aussi le nom de l'image : web/dist/assets/maps/<id>.png
labelNom dans le menu
centerCentre de la zone, vec3
radiusRayon en mètres. Celui qui en sort est placé sur un spawn aléatoire
maxPlayersJoueurs en même temps
spawnsListe de vec4. Au respawn, le spawn le plus éloigné des autres joueurs est choisi
weapons{ name, ammo }. FFA : optionnel, sans liste on se bat avec ses propres armes et on utilise de vraies munitions. Only : obligatoire
vehicleSeulement Only, optionnel : { model, label }. On spawne sur ce véhicule

config/settings/config.lobby.lua

Config.lobby contient les réglages des lobbys :

OptionPar défautDescription
maxPlayers10Joueurs par lobby, au maximum la moitié par équipe
maxLobbies8Lobbys en même temps
maxWeapons3Armes qu'on peut choisir à la création
rounds1 / 15 / 5Manches : min, max et default
prepareSeconds3Préparation avant chaque manche (figé, sans armes), 3 secondes de plus à la première manche
roundEndSeconds1Pause après une manche
resultSeconds1Affichage du résultat, ensuite on revient
roundMinutes5Limite de temps par manche, 0 = pas de limite
spectateDelay3Secondes après la mort avant de passer spectateur
startRange50.0Distance maximale de tous les membres à un point PvP au lancement
overtimeRounds1Manches décisives en cas d'égalité, 0 = match nul
armour100Gilet au début de chaque manche
weapons10 armesArmes au choix à la création : { name, ammo }
vehicles3 véhiculesVéhicules par défaut pour les maps véhicule sans liste propre : { model, label }

Config.maps contient les maps des lobbys :

ChampDescription
id / labelNom unique (= nom de l'image, comme pour les zones) et nom affiché
mode'foot' = à pied, 'vehicle' = map véhicule
center / radiusSphère affichée pendant le match (vec3 et mètres). Elle sert seulement à l'affichage, il n'y a pas de limite
vehiclesOptionnel, liste de véhicules propre { model, label }. Sans liste, Config.lobby.vehicles s'applique
teams.a / teams.bUn spawn (vec4) par équipe. Tous les joueurs de l'équipe démarrent chaque manche à cet endroit
garage / vehicleSpawnSeulement les maps véhicule, par équipe : marker du garage (vec3) et point de sortie (vec4)

config/functions.lua

C'est ici que tu branches tes propres scripts. Les erreurs qu'elles contiennent arrivent dans la console, le script continue de tourner. kind vaut toujours 'ffa', 'only' ou 'lobby'.

FonctionCôtéUtilité
ServerCanJoin(source, kind, id)Serveurreturn false, 'Text' empêche de rejoindre et de lancer le lobby, p. ex. en prison
ServerKill(killer, victim, kind, id)ServeurKill compté, p. ex. de l'argent en récompense
ServerDeath(victim, killer, kind, id, teamkill)ServeurChaque mort, killer peut être nil
ServerMatchEnded(lobbyId, result)ServeurMatch terminé : { winner, score, map, teams }, winner = 'a', 'b' ou nil
ServerJoined(source, kind, id)ServeurLe joueur entre dans une zone ou un match
ServerLeft(source, kind, id, reason)Serveurreason = 'quit', 'drop', 'end', 'kick' ou 'stop'
Notify(message, type) / HelpNotify(text)ClientNotification et texte d'aide · Serveur : Notify(source, message, type)
ClientRevive(position)ClientRéanimer, p. ex. ton propre script ambulance
ClientDeath(kind) / ClientRespawn(kind)ClientMort et respawn en PvP, p. ex. masquer l'écran de mort
ClientGiveLoadout(loadout)ClientDonner et rendre les armes
ClientSetFuel(vehicle, fuel)ClientScript d'essence
ClientVehicleSpawned(vehicle, plate, kind)ClientVéhicule PvP apparu, p. ex. donner les clés
ClientVehicleMenu(vehicles, onSelect)ClientMenu du garage sur les maps véhicule (par défaut : menu ESX Default)
ClientStateChanged(state)Client{ kind, id, team } en entrant, nil en sortant, p. ex. bloquer le téléphone ou ton propre HUD

config/settings/config.server.lua et langues

Webhooks Discord pour lobby (lobby créé, match lancé, match terminé, lobby dissous) et zones (entrée et sortie de zone). '' désactive un log. Tous les textes se trouvent dans config/locales/ (un fichier par langue).

En jeu

  • Menu : E à un point PvP. Ça ne marche que vivant, à pied, dans la dimension normale et pas en gangwar.
  • FFA et Only : Rejoindre te téléporte dans la zone. Après la mort, tu reprends sur un spawn après respawn.seconds. En haut, tu vois les kills, les morts et les joueurs dans la zone.
  • Quitter : /quitffa (ou ton quitCommand) te ramène à l'endroit où tu as rejoint. Vie et gilet sont comme avant, tes propres armes reviennent. La commande quitte aussi un lobby en attente.
  • Créer un lobby : choisis la map, le mode, les manches, les armes et, en option, un mot de passe. Les nouveaux joueurs vont dans l'équipe la plus petite. Changer d'équipe est possible tant que l'autre équipe n'est pas pleine. Après 5 mauvais mots de passe, le lobby est bloqué pour toi pendant 60 secondes.
  • Propriétaire : lance, mélange, expulse et dissout. Si le propriétaire part, le membre suivant prend le relais.
  • Lancement : celui qui est mort, dans une autre dimension, en gangwar ou plus loin que startRange d'un point PvP est retiré du lobby. Chaque équipe a besoin d'au moins un joueur.
  • Match :
  • Chaque manche commence par la préparation (figé, sans armes), ensuite il y a les armes et le gilet.
  • Une manche est gagnée par l'équipe qui élimine toute l'équipe adverse. Pas de respawn pendant une manche. Si les deux derniers tombent en même temps, personne ne marque.
  • Si la limite de temps est atteinte, l'équipe avec le plus de joueurs en vie gagne, en cas d'égalité personne ne marque.
  • Le match est gagné par l'équipe qui remporte en premier plus de la moitié des manches. Quand toutes les manches sont jouées, le meilleur score gagne. En cas d'égalité, il y a des manches décisives (overtimeRounds), puis un match nul.
  • Le tir allié est activé. Un teamkill compte comme une mort, pas comme un kill.
  • Celui qui quitte un match en cours prend une défaite. Si une équipe est vide ensuite, l'autre gagne tout de suite.
  • Ensuite, tout le monde revient à son point de départ, le lobby reste ouvert et attend à nouveau.
  • Spectateur : après spectateDelay secondes, tu regardes un coéquipier en vie. En bas au centre s'affichent son nom et les flèches. ← et → changent de joueur.
  • Garage (maps véhicule) : pendant la manche, E au marker du garage de ton équipe ouvre la liste des véhicules. Chaque joueur a un véhicule, un nouveau remplace l'ancien.
  • Classement : les meilleurs joueurs par mode (nombre via leaderboardSize), triés par kills. Les nouvelles valeurs apparaissent au plus tard après une minute, tout de suite après un match.

Pour les développeurs

lua
-- Serveur
local inPvp = exports.off_pvp:IsInPvp(source)        -- FFA, Only ou match en cours
local ffa = exports.off_pvp:IsFFA(source)
local only = exports.off_pvp:IsOnly(source)
local lobby = exports.off_pvp:IsLobby(source)        -- dans un match en cours
local inLobby = exports.off_pvp:IsInLobby(source)    -- membre d'un lobby, en attente ou en match
local info = exports.off_pvp:GetPvp(source)          -- { kind, id, team, alive, kills, deaths } ou nil
local removed = exports.off_pvp:RemoveFromPvp(source) -- sort le joueur d'une zone, d'un match ou d'un lobby en attente, true/false
local stats = exports.off_pvp:GetStats(source)       -- { ffa = { kills, deaths }, only = { ... }, lobby = { kills, deaths, wins, losses } } ou nil

-- Client
local inPvp = exports.off_pvp:IsInPvp()
local ffa = exports.off_pvp:IsFFA()
local only = exports.off_pvp:IsOnly()
local lobby = exports.off_pvp:IsLobby()
local spectating = exports.off_pvp:IsSpectating()
local info = exports.off_pvp:GetPvp()                -- { kind, id, team, phase } ou nil
  • Statebag offPvp : 'ffa', 'only' ou 'lobby' tant que le joueur est dans une zone ou un match.
  • offinventory : canOpen() dans off_inventory/config/functions.lua bloque l'inventaire et le coffre du véhicule en PvP dès que offpvp tourne.

Problèmes fréquents

Au démarrage, le script signale les erreurs et les remarques dans la console du serveur. Les zones et maps erronées y sont indiquées et ignorées.

ProblèmeSolution
« Ce n'est pas possible pour le moment. » à l'ouvertureTu es mort, dans une autre dimension ou en gangwar.
Une zone ou une map manque dans le menuVérifie la console, l'entrée contient une erreur (p. ex. pas de spawns).
Pas d'image pour la zone ou la mapweb/dist/assets/maps/<id>.png manque.
Le garage n'ouvre aucun menuDémarre esxmenudefault ou adapte ClientVehicleMenu.
Les joueurs ne se font pas de dégâtsMets Config.EnablePVP = true dans ESX.
Le script ambulance affiche l'écran de mort en PvPMasque-le dans ClientDeath et réaffiche-le dans ClientRespawn.
Au mauvais endroit après un crashÀ la prochaine connexion, tu reviens automatiquement à ton point de départ.
Redémarrage de la resource pendant un matchTout le monde revient, le match n'est pas compté. Mieux vaut ne pas redémarrer pendant les matchs.

Pas encore acheté ?

Voir PVP dans la boutique