
PVP
PvP-System mit FFA-Zonen, Only-Zonen und Lobby-Matches in Teams. Jede Zone und jedes Match läuft in einer eigenen Dimension. Dazu gibt es ein Leaderboard und eine Match-Anzeige. Die Tabelle legt das Script selbst an.
- ESX Legacy (
es_extended, getestet mit 1.14) - oxmysql
- OneSync
- In ESX muss
Config.EnablePVP = truesein (Standard) - Für das Garagenmenü auf Fahrzeug-Maps: esxmenudefault (oder ein eigenes Menü über
ClientVehicleMenu)
Funktionen
- FFA-Zonen: Jeder gegen jeden. Pro Zone feste Waffen oder die eigenen Waffen des Spielers. Respawn mit Weste und kurzem Spawnschutz.
- Only-Zonen: Alle haben dieselben Waffen, optional mit Fahrzeug (z. B. BF 400) bei jedem Spawn.
- Lobbys: Team A gegen Team B im Best-of-Modus mit Entscheidungsrunde. Map, Modus (zu Fuß oder Fahrzeug), Runden, bis zu 3 Waffen und ein optionales Passwort sind wählbar. Der Owner kann kicken, mischen und auflösen.
- Zuschauen: Wer in einer Runde ausscheidet, schaut den lebenden Teamkameraden zu und wechselt mit ← →.
- Match-Anzeige oben in der Mitte und Leaderboard mit Filter FFA, Only und Lobby (inklusive Siege und Niederlagen).
- Waffenschutz: Feste Waffen gibt es nur im PvP. Die echten Waffen und ihre Munition bleiben geschützt.
- Discord-Logs, Exports und eigene Funktionen zum Anbinden anderer Scripts.
Installation
- Ordner
off_pvpin deinenresources-Ordner legen. - In die
server.cfg, nach oxmysql und ESX:
ensure oxmysql
ensure es_extended
ensure off_pvp- PvP-Punkte, Zonen und Maps in
config/an deinen Server anpassen.
Die Tabelle off_pvp_stats wird beim ersten Start automatisch angelegt.
Die Zonen in config/settings/config.ffa.lua und config/settings/config.only.lua und die Maps in config/settings/config.lobby.lua sind nur Beispiele. Prüfe alle Positionen im Spiel und trag deine eigenen ein.
Konfiguration
Die Einstellungen liegen in config/settings/: config.lua für alles Allgemeine, config.ffa.lua, config.only.lua und config.lobby.lua für die drei Modi.
config/settings/config.lua
| Option | Standard | Beschreibung |
|---|---|---|
serverInfo.name | 'OFF SCRIPTS' | Servername, steht in der Oberfläche statt „OFF SCRIPTS“ |
serverInfo.locale | 'de' | Sprache: de, en, pl, fr, es oder it |
serverInfo.color | { 155, 89, 255 } | Farbe der UI (RGB) |
serverInfo.design | 3 | Design der Oberfläche: 1 = Klassisch, 2 = Kassenbon, 3 = Storefront |
blur | true | Hintergrund unscharf, solange das Menü offen ist |
quitCommand | 'quitffa' | Befehl zum Verlassen von FFA, Only, Lobbys und laufenden Matches |
defaultPed | 's_m_y_valet_01' | NPC für Punkte ohne gültiges ped |
points | 1 Beispiel | PvP-Punkte, an denen E das Menü öffnet (siehe unten) |
marker | siehe Datei | Aussehen der Marker-Punkte: type, size, alpha, drawDistance |
respawn.seconds | 3 | Wartezeit bis zum Respawn in FFA und Only |
respawn.protection | 3 | Sekunden unverwundbar nach dem Spawn |
respawn.armour | 100 | Weste nach dem Spawn |
killHeal | true | Nach jedem Kill volles Leben und volle Weste (FFA, Only und Lobby) |
leaderboardSize | 50 | So viele Spieler zeigt das Leaderboard pro Modus (3–500) |
PvP-Punkte (points):
| Feld | Beschreibung |
|---|---|
id | Eindeutiger Name des Punkts |
label | Name im Hinweistext und auf dem Blip |
position | vec4(x, y, z, heading) |
interaction | 'ped' = NPC, 'marker' = Marker am Boden |
ped | Modell des NPCs, ohne gültiges Modell gilt defaultPed |
scenario | Animation des NPCs (optional) |
blip | { sprite, color, scale }, false = kein Blip |
config/settings/config.ffa.lua und config/settings/config.only.lua
Config.ffa und Config.only enthalten die Zonen. Jede Zone hat:
| Feld | Beschreibung |
|---|---|
id | Eindeutiger Name, gleichzeitig der Bildname: web/dist/assets/maps/<id>.png |
label | Name im Menü |
center | Mitte der Zone, vec3 |
radius | Radius in Metern. Wer ihn verlässt, wird an einen zufälligen Spawn gesetzt |
maxPlayers | Spieler gleichzeitig |
spawns | Liste aus vec4. Beim Respawn wird der Spawn mit dem größten Abstand zu anderen Spielern genommen |
weapons | { name, ammo }. FFA: optional, ohne Liste kämpft man mit den eigenen Waffen und verbraucht echte Munition. Only: Pflicht |
vehicle | Nur Only, optional: { model, label }. Man spawnt auf diesem Fahrzeug |
config/settings/config.lobby.lua
Config.lobby enthält die Einstellungen für Lobbys:
| Option | Standard | Beschreibung |
|---|---|---|
maxPlayers | 10 | Spieler pro Lobby, pro Team höchstens die Hälfte |
maxLobbies | 8 | Lobbys gleichzeitig |
maxWeapons | 3 | Waffen, die man beim Erstellen wählen kann |
rounds | 1 / 15 / 5 | Runden: min, max und default |
prepareSeconds | 3 | Vorbereitung vor jeder Runde (eingefroren, ohne Waffen), in der ersten Runde 3 Sekunden länger |
roundEndSeconds | 1 | Pause nach einer Runde |
resultSeconds | 1 | Anzeige des Ergebnisses, danach geht es zurück |
roundMinutes | 5 | Zeitlimit pro Runde, 0 = kein Limit |
spectateDelay | 3 | Sekunden nach dem Tod bis zum Zuschauen |
startRange | 50.0 | So nah müssen alle Mitglieder beim Start an einem PvP-Punkt sein |
overtimeRounds | 1 | Entscheidungsrunden bei Gleichstand, 0 = Unentschieden |
armour | 100 | Weste zu Beginn jeder Runde |
weapons | 10 Waffen | Waffen zur Auswahl beim Erstellen: { name, ammo } |
vehicles | 3 Fahrzeuge | Standard-Fahrzeuge für Fahrzeug-Maps ohne eigene Liste: { model, label } |
Config.maps enthält die Maps für Lobbys:
| Feld | Beschreibung |
|---|---|
id / label | Eindeutiger Name (= Bildname wie bei den Zonen) und Anzeigename |
mode | 'foot' = zu Fuß, 'vehicle' = Fahrzeug-Map |
center / radius | Kugel, die im Match angezeigt wird (vec3 und Meter). Sie ist nur zur Anzeige, es gibt keine Grenze |
vehicles | Optional, eigene Fahrzeugliste { model, label }. Ohne Liste gilt Config.lobby.vehicles |
teams.a / teams.b | Pro Team ein spawn (vec4). Alle Spieler des Teams starten jede Runde dort |
garage / vehicleSpawn | Nur Fahrzeug-Maps, pro Team: Garagen-Marker (vec3) und Ausparkpunkt (vec4) |
config/functions.lua
Hier bindest du eigene Scripts an. Fehler darin landen in der Konsole, das Script läuft weiter. kind ist immer 'ffa', 'only' oder 'lobby'.
| Funktion | Seite | Wofür |
|---|---|---|
ServerCanJoin(source, kind, id) | Server | return false, 'Text' verhindert Beitritt und Lobby-Start, z. B. im Knast |
ServerKill(killer, victim, kind, id) | Server | Gewerteter Kill, z. B. Geld als Belohnung |
ServerDeath(victim, killer, kind, id, teamkill) | Server | Jeder Tod, killer kann nil sein |
ServerMatchEnded(lobbyId, result) | Server | Match beendet: { winner, score, map, teams }, winner = 'a', 'b' oder nil |
ServerJoined(source, kind, id) | Server | Spieler betritt eine Zone oder ein Match |
ServerLeft(source, kind, id, reason) | Server | reason = 'quit', 'drop', 'end', 'kick' oder 'stop' |
Notify(message, type) / HelpNotify(text) | Client | Notify und Hinweistext · Server: Notify(source, message, type) |
ClientRevive(position) | Client | Wiederbeleben, z. B. eigenes Ambulance-Script |
ClientDeath(kind) / ClientRespawn(kind) | Client | Tod und Respawn im PvP, z. B. Todesbildschirm ausblenden |
ClientGiveLoadout(loadout) | Client | Waffen geben und zurückgeben |
ClientSetFuel(vehicle, fuel) | Client | Tank-Script |
ClientVehicleSpawned(vehicle, plate, kind) | Client | PvP-Fahrzeug gespawnt, z. B. Schlüssel geben |
ClientVehicleMenu(vehicles, onSelect) | Client | Garagenmenü auf Fahrzeug-Maps (Standard: ESX-Default-Menü) |
ClientStateChanged(state) | Client | { kind, id, team } beim Betreten, nil beim Verlassen, z. B. Handy oder eigenes HUD sperren |
config/settings/config.server.lua und Sprachen
Discord-Webhooks für lobby (Lobby erstellt, Match gestartet, Match beendet, Lobby aufgelöst) und zones (Zone betreten und verlassen). '' schaltet einen Log aus. Alle Texte stehen in config/locales/ (eine Datei pro Sprache).
Im Spiel
- Menü: E an einem PvP-Punkt. Das geht nur lebend, zu Fuß, in der normalen Dimension und nicht im Gangwar.
- FFA und Only: Beitreten teleportiert dich in die Zone. Nach dem Tod geht es nach
respawn.secondsan einem Spawn weiter. Oben siehst du Kills, Tode und die Spieler in der Zone. - Verlassen:
/quitffa(oder deinquitCommand) bringt dich an den Ort zurück, an dem du beigetreten bist. Leben und Weste sind wie vorher, die eigenen Waffen kommen zurück. Der Befehl verlässt auch eine wartende Lobby. - Lobby erstellen: Map, Modus, Runden, Waffen und optional ein Passwort wählen. Neue Spieler kommen ins kleinere Team. Wechseln geht, solange das andere Team nicht voll ist. Nach 5 falschen Passwörtern ist die Lobby für dich 60 Sekunden gesperrt.
- Owner: startet, mischt, kickt und löst auf. Geht der Owner, übernimmt das nächste Mitglied.
- Start: Wer tot ist, in einer anderen Dimension, im Gangwar oder weiter als
startRangevon einem PvP-Punkt entfernt, fliegt aus der Lobby. Jedes Team braucht mindestens einen Spieler. - Match:
- Jede Runde beginnt mit der Vorbereitung (eingefroren, ohne Waffen), danach gibt es Waffen und Weste.
- Eine Runde gewinnt, wer das ganze Gegnerteam ausschaltet. Innerhalb einer Runde gibt es keinen Respawn. Fallen die letzten beiden gleichzeitig, gibt es keinen Punkt.
- Läuft das Zeitlimit ab, gewinnt das Team mit mehr lebenden Spielern, bei Gleichstand gibt es keinen Punkt.
- Das Match gewinnt, wer zuerst mehr als die Hälfte der Runden holt. Sind alle Runden gespielt, gewinnt der höhere Stand. Bei Gleichstand gibt es Entscheidungsrunden (
overtimeRounds), danach ein Unentschieden. - Friendly Fire ist an. Ein Teamkill zählt als Tod, nicht als Kill.
- Wer ein laufendes Match verlässt, bekommt eine Niederlage. Ist ein Team danach leer, gewinnt das andere sofort.
- Danach kommen alle an ihren Ausgangsort zurück, die Lobby bleibt offen und wartet wieder.
- Zuschauen: Nach
spectateDelaySekunden schaust du einem lebenden Teamkameraden zu. Unten in der Mitte stehen sein Name und die Pfeile. ← und → wechseln. - Garage (Fahrzeug-Maps): Während der Runde öffnet E am Garagen-Marker deines Teams die Fahrzeugliste. Jeder Spieler hat ein Fahrzeug, ein neues ersetzt das alte.
- Leaderboard: Die besten Spieler pro Modus (Anzahl über
leaderboardSize), sortiert nach Kills. Neue Werte erscheinen spätestens nach einer Minute, nach einem Match sofort.
Für Entwickler
-- Server
local inPvp = exports.off_pvp:IsInPvp(source) -- FFA, Only oder laufendes Match
local ffa = exports.off_pvp:IsFFA(source)
local only = exports.off_pvp:IsOnly(source)
local lobby = exports.off_pvp:IsLobby(source) -- in einem laufenden Match
local inLobby = exports.off_pvp:IsInLobby(source) -- Mitglied einer Lobby, wartend oder im Match
local info = exports.off_pvp:GetPvp(source) -- { kind, id, team, alive, kills, deaths } oder nil
local removed = exports.off_pvp:RemoveFromPvp(source) -- holt den Spieler aus Zone, Match oder wartender Lobby, true/false
local stats = exports.off_pvp:GetStats(source) -- { ffa = { kills, deaths }, only = { ... }, lobby = { kills, deaths, wins, losses } } oder 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 } oder nil- Statebag
offPvp:'ffa','only'oder'lobby', solange der Spieler in einer Zone oder einem Match ist. - offinventory:
canOpen()inoff_inventory/config/functions.luasperrt Inventar und Kofferraum im PvP, sobald offpvp läuft.
Häufige Fehler
Beim Start meldet das Script Fehler und Hinweise in der Server-Konsole. Fehlerhafte Zonen und Maps werden dort genannt und ignoriert.
| Problem | Lösung |
|---|---|
| „Das geht gerade nicht.“ beim Öffnen | Du bist tot, in einer anderen Dimension oder im Gangwar. |
| Zone oder Map fehlt im Menü | Konsole prüfen, der Eintrag hat einen Fehler (z. B. keine Spawns). |
| Kein Bild in der Zone oder Map | web/dist/assets/maps/<id>.png fehlt. |
| Garage öffnet kein Menü | esxmenudefault starten oder ClientVehicleMenu anpassen. |
| Spieler machen sich keinen Schaden | In ESX Config.EnablePVP = true setzen. |
| Ambulance-Script zeigt im PvP den Todesbildschirm | In ClientDeath ausblenden und in ClientRespawn wieder einblenden. |
| Nach einem Absturz am falschen Ort | Beim nächsten Login geht es automatisch zurück zum Ausgangsort. |
| Resource-Neustart während eines Matches | Alle kommen zurück, das Match wird nicht gewertet. Besser nicht während Matches neu starten. |
Noch nicht gekauft?
PVP im Shop ansehen