
PVP
System PvP ze strefami FFA, strefami Only i drużynowymi meczami w lobby. Każda strefa i każdy mecz działa we własnym wymiarze. Do tego dochodzi ranking i panel meczu. Tabelę skrypt tworzy sam.
- ESX Legacy (
es_extended, testowane z 1.14) - oxmysql
- OneSync
- W ESX musi być ustawione
Config.EnablePVP = true(domyślnie) - Do menu garażu na mapach z pojazdami: esxmenudefault (lub własne menu przez
ClientVehicleMenu)
Funkcje
- Strefy FFA: Każdy na każdego. W każdej strefie stałe bronie albo własne bronie gracza. Respawn z kamizelką i krótką ochroną po spawnie.
- Strefy Only: Wszyscy mają te same bronie, opcjonalnie z pojazdem (np. BF 400) przy każdym spawnie.
- Lobby: Drużyna A przeciw drużynie B w trybie best-of z rundą decydującą. Do wyboru są mapa, tryb (pieszo lub pojazd), rundy, do 3 broni i opcjonalne hasło. Właściciel może wyrzucać, mieszać i rozwiązać lobby.
- Obserwowanie: Kto odpadnie w rundzie, obserwuje żywych kolegów z drużyny i przełącza ich ← →.
- Panel meczu u góry pośrodku i Ranking z filtrami FFA, Only i Lobby (łącznie z wygranymi i przegranymi).
- Ochrona broni: Stałe bronie istnieją tylko w PvP. Prawdziwe bronie i ich amunicja pozostają chronione.
- Logi na Discordzie, eksporty i własne funkcje do podłączania innych skryptów.
Instalacja
- Wrzuć folder
off_pvpdo swojego folderuresources. - Dodaj do
server.cfg, po oxmysql i ESX:
ensure oxmysql
ensure es_extended
ensure off_pvp- Dostosuj punkty PvP, strefy i mapy w
config/do swojego serwera.
Tabela off_pvp_stats tworzy się automatycznie przy pierwszym starcie.
Strefy w config/settings/config.ffa.lua i config/settings/config.only.lua oraz mapy w config/settings/config.lobby.lua to tylko przykłady. Sprawdź wszystkie pozycje w grze i wpisz własne.
Konfiguracja
Ustawienia są w config/settings/: config.lua dla wszystkiego, co ogólne, config.ffa.lua, config.only.lua i config.lobby.lua dla trzech trybów.
config/settings/config.lua
| Opcja | Domyślnie | Opis |
|---|---|---|
serverInfo.name | 'OFF SCRIPTS' | Nazwa serwera, widoczna w interfejsie zamiast „OFF SCRIPTS” |
serverInfo.locale | 'de' | Język: de, en, pl, fr, es lub it |
serverInfo.color | { 155, 89, 255 } | Kolor UI (RGB) |
serverInfo.design | 3 | Wygląd interfejsu: 1 = Klasyczny, 2 = Paragon, 3 = Storefront |
blur | true | Rozmyte tło, dopóki menu jest otwarte |
quitCommand | 'quitffa' | Komenda do opuszczania FFA, Only, lobby i trwających meczów |
defaultPed | 's_m_y_valet_01' | NPC dla punktów bez prawidłowego ped |
points | 1 przykład | Punkty PvP, w których E otwiera menu (patrz niżej) |
marker | patrz plik | Wygląd punktów z markerem: type, size, alpha, drawDistance |
respawn.seconds | 3 | Czas oczekiwania na respawn w FFA i Only |
respawn.protection | 3 | Sekundy nieśmiertelności po spawnie |
respawn.armour | 100 | Kamizelka po spawnie |
killHeal | true | Po każdym zabójstwie pełne życie i pełna kamizelka (FFA, Only i Lobby) |
leaderboardSize | 50 | Tylu graczy pokazuje ranking dla każdego trybu (3–500) |
Punkty PvP (points):
| Pole | Opis |
|---|---|
id | Unikalna nazwa punktu |
label | Nazwa w tekście pomocy i na blipie |
position | vec4(x, y, z, heading) |
interaction | 'ped' = NPC, 'marker' = marker na ziemi |
ped | Model NPC, bez prawidłowego modelu używany jest defaultPed |
scenario | Animacja NPC (opcjonalnie) |
blip | { sprite, color, scale }, false = brak blipa |
config/settings/config.ffa.lua i config/settings/config.only.lua
Config.ffa i Config.only zawierają strefy. Każda strefa ma:
| Pole | Opis |
|---|---|
id | Unikalna nazwa, jednocześnie nazwa obrazka: web/dist/assets/maps/<id>.png |
label | Nazwa w menu |
center | Środek strefy, vec3 |
radius | Promień w metrach. Kto go opuści, trafia na losowy spawn |
maxPlayers | Liczba graczy jednocześnie |
spawns | Lista vec4. Przy respawnie wybierany jest spawn najdalej od innych graczy |
weapons | { name, ammo }. FFA: opcjonalnie, bez listy walczy się własnymi broniami i zużywa prawdziwą amunicję. Only: wymagane |
vehicle | Tylko Only, opcjonalnie: { model, label }. Gracz spawnuje się na tym pojeździe |
config/settings/config.lobby.lua
Config.lobby zawiera ustawienia lobby:
| Opcja | Domyślnie | Opis |
|---|---|---|
maxPlayers | 10 | Gracze na lobby, na drużynę maksymalnie połowa |
maxLobbies | 8 | Liczba lobby jednocześnie |
maxWeapons | 3 | Bronie, które można wybrać przy tworzeniu |
rounds | 1 / 15 / 5 | Rundy: min, max i default |
prepareSeconds | 3 | Przygotowanie przed każdą rundą (zamrożenie, bez broni), w pierwszej rundzie 3 sekundy dłużej |
roundEndSeconds | 1 | Przerwa po rundzie |
resultSeconds | 1 | Wyświetlanie wyniku, potem powrót |
roundMinutes | 5 | Limit czasu na rundę, 0 = bez limitu |
spectateDelay | 3 | Sekundy od śmierci do obserwowania |
startRange | 50.0 | Tak blisko punktu PvP muszą być wszyscy członkowie przy starcie |
overtimeRounds | 1 | Rundy decydujące przy remisie, 0 = remis |
armour | 100 | Kamizelka na początku każdej rundy |
weapons | 10 broni | Bronie do wyboru przy tworzeniu: { name, ammo } |
vehicles | 3 pojazdy | Domyślne pojazdy dla map z pojazdami bez własnej listy: { model, label } |
Config.maps zawiera mapy dla lobby:
| Pole | Opis |
|---|---|
id / label | Unikalna nazwa (= nazwa obrazka jak przy strefach) i nazwa wyświetlana |
mode | 'foot' = pieszo, 'vehicle' = mapa z pojazdami |
center / radius | Kula wyświetlana w meczu (vec3 i metry). Służy tylko do wyświetlania, nie ma granicy |
vehicles | Opcjonalnie, własna lista pojazdów { model, label }. Bez listy obowiązuje Config.lobby.vehicles |
teams.a / teams.b | Na drużynę jeden spawn (vec4). Wszyscy gracze drużyny zaczynają tam każdą rundę |
garage / vehicleSpawn | Tylko mapy z pojazdami, na drużynę: marker garażu (vec3) i punkt wyjazdu (vec4) |
config/functions.lua
Tutaj podłączasz własne skrypty. Błędy w nich trafiają do konsoli, skrypt działa dalej. kind to zawsze 'ffa', 'only' lub 'lobby'.
| Funkcja | Strona | Do czego |
|---|---|---|
ServerCanJoin(source, kind, id) | Serwer | return false, 'Text' blokuje dołączenie i start lobby, np. w więzieniu |
ServerKill(killer, victim, kind, id) | Serwer | Zaliczone zabójstwo, np. pieniądze jako nagroda |
ServerDeath(victim, killer, kind, id, teamkill) | Serwer | Każda śmierć, killer może być nil |
ServerMatchEnded(lobbyId, result) | Serwer | Mecz zakończony: { winner, score, map, teams }, winner = 'a', 'b' lub nil |
ServerJoined(source, kind, id) | Serwer | Gracz wchodzi do strefy lub meczu |
ServerLeft(source, kind, id, reason) | Serwer | reason = 'quit', 'drop', 'end', 'kick' lub 'stop' |
Notify(message, type) / HelpNotify(text) | Klient | Powiadomienie i tekst pomocy · Serwer: Notify(source, message, type) |
ClientRevive(position) | Klient | Ożywianie, np. własny skrypt ambulance |
ClientDeath(kind) / ClientRespawn(kind) | Klient | Śmierć i respawn w PvP, np. ukryj ekran śmierci |
ClientGiveLoadout(loadout) | Klient | Dawanie i oddawanie broni |
ClientSetFuel(vehicle, fuel) | Klient | Skrypt paliwa |
ClientVehicleSpawned(vehicle, plate, kind) | Klient | Pojazd PvP zespawnowany, np. daj kluczyki |
ClientVehicleMenu(vehicles, onSelect) | Klient | Menu garażu na mapach z pojazdami (domyślnie: menu ESX Default) |
ClientStateChanged(state) | Klient | { kind, id, team } przy wejściu, nil przy wyjściu, np. zablokuj telefon lub własny HUD |
config/settings/config.server.lua i języki
Webhooki Discorda dla lobby (lobby utworzone, mecz rozpoczęty, mecz zakończony, lobby rozwiązane) i zones (wejście do strefy i wyjście). '' wyłącza log. Wszystkie teksty są w config/locales/ (jeden plik na język).
W grze
- Menu: E w punkcie PvP. Działa tylko, gdy żyjesz, jesteś pieszo, w normalnym wymiarze i nie w gangwarze.
- FFA i Only: Dołącz teleportuje cię do strefy. Po śmierci po
respawn.secondsgrasz dalej na spawnie. Na górze widzisz zabójstwa, śmierci i graczy w strefie. - Wychodzenie:
/quitffa(lub twójquitCommand) przenosi cię z powrotem w miejsce, w którym dołączyłeś. Życie i kamizelka są jak wcześniej, własne bronie wracają. Komenda opuszcza też czekające lobby. - Utwórz lobby: Wybierz mapę, tryb, rundy, bronie i opcjonalnie hasło. Nowi gracze trafiają do mniejszej drużyny. Zmiana drużyny działa, dopóki druga drużyna nie jest pełna. Po 5 błędnych hasłach lobby jest dla ciebie zablokowane na 60 sekund.
- Właściciel: startuje, miesza, wyrzuca i rozwiązuje. Gdy właściciel wyjdzie, przejmuje następny członek.
- Start: Kto jest martwy, w innym wymiarze, w gangwarze lub dalej niż
startRangeod punktu PvP, wylatuje z lobby. Każda drużyna potrzebuje co najmniej jednego gracza. - Mecz:
- Każda runda zaczyna się od przygotowania (zamrożenie, bez broni), potem są bronie i kamizelka.
- Rundę wygrywa ten, kto wyeliminuje całą drużynę przeciwną. W trakcie rundy nie ma respawnu. Jeśli dwaj ostatni zginą jednocześnie, nikt nie dostaje punktu.
- Gdy skończy się limit czasu, wygrywa drużyna z większą liczbą żywych graczy, przy remisie nikt nie dostaje punktu.
- Mecz wygrywa ten, kto pierwszy zdobędzie ponad połowę rund. Gdy wszystkie rundy są rozegrane, wygrywa wyższy wynik. Przy remisie są rundy decydujące (
overtimeRounds), potem remis. - Friendly fire jest włączony. Teamkill liczy się jako śmierć, nie jako zabójstwo.
- Kto opuści trwający mecz, dostaje porażkę. Jeśli drużyna jest potem pusta, druga od razu wygrywa.
- Potem wszyscy wracają do miejsca startu, lobby zostaje otwarte i znów czeka.
- Obserwowanie: Po
spectateDelaysekundach obserwujesz żywego kolegę z drużyny. Na dole pośrodku są jego nazwa i strzałki. ← i → przełączają. - Garaż (mapy z pojazdami): W trakcie rundy E przy markerze garażu twojej drużyny otwiera listę pojazdów. Każdy gracz ma jeden pojazd, nowy zastępuje stary.
- Ranking: Najlepsi gracze w każdym trybie (liczba przez
leaderboardSize), posortowani według zabójstw. Nowe wartości pojawiają się najpóźniej po minucie, po meczu od razu.
Dla deweloperów
-- Serwer
local inPvp = exports.off_pvp:IsInPvp(source) -- FFA, Only lub trwający mecz
local ffa = exports.off_pvp:IsFFA(source)
local only = exports.off_pvp:IsOnly(source)
local lobby = exports.off_pvp:IsLobby(source) -- w trwającym meczu
local inLobby = exports.off_pvp:IsInLobby(source) -- członek lobby, czeka lub jest w meczu
local info = exports.off_pvp:GetPvp(source) -- { kind, id, team, alive, kills, deaths } lub nil
local removed = exports.off_pvp:RemoveFromPvp(source) -- zabiera gracza ze strefy, meczu lub czekającego lobby, true/false
local stats = exports.off_pvp:GetStats(source) -- { ffa = { kills, deaths }, only = { ... }, lobby = { kills, deaths, wins, losses } } lub nil
-- Klient
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 } lub nil- Statebag
offPvp:'ffa','only'lub'lobby', dopóki gracz jest w strefie lub meczu. - offinventory:
canOpen()woff_inventory/config/functions.luablokuje ekwipunek i bagażnik w PvP, gdy tylko offpvp działa.
Częste problemy
Przy starcie skrypt zgłasza błędy i wskazówki w konsoli serwera. Błędne strefy i mapy są tam wymienione i pomijane.
| Problem | Rozwiązanie |
|---|---|
| „To teraz niemożliwe.” przy otwieraniu | Jesteś martwy, w innym wymiarze lub w gangwarze. |
| Brak strefy lub mapy w menu | Sprawdź konsolę, wpis ma błąd (np. brak spawnów). |
| Brak obrazka strefy lub mapy | Brakuje web/dist/assets/maps/<id>.png. |
| Garaż nie otwiera menu | Uruchom esxmenudefault lub dostosuj ClientVehicleMenu. |
| Gracze nie zadają sobie obrażeń | Ustaw w ESX Config.EnablePVP = true. |
| Skrypt ambulance pokazuje w PvP ekran śmierci | Ukryj go w ClientDeath i pokaż z powrotem w ClientRespawn. |
| Po crashu w złym miejscu | Przy następnym logowaniu wracasz automatycznie do miejsca startu. |
| Restart zasobu w trakcie meczu | Wszyscy wracają, mecz nie jest liczony. Lepiej nie restartować w trakcie meczów. |
Jeszcze nie kupiony?
Zobacz PVP w sklepie