Mieszkania i apartamenty w FiveM: shell'e, instancje, sejfy i klucze

Jak działa system mieszkań w FiveM: wnętrza shell i MLO, instancjowanie za pomocą routing buckets, sejf dla każdego domu, klucze i uprawnienia, oraz zapisywanie właścicielstwa w bazie danych.

Objaw: dwaj gracze wchodzą do dwóch różnych apartamentów i widzą się nawzajem, sejf jest dzielony między wszystkie domy, lub właścicielstwo znika po restarcie serwera.

System mieszkań to cztery rzeczy pracujące razem: wnętrze, sposób na oddzielenie graczy, miejsce do przechowywania przedmiotów i rejestr tego, kto może wejść. Ten artykuł wyjaśnia każdą część i jak się ze sobą łączą.

Shell lub wnętrze MLO

Masz dwa sposoby na stworzenie wnętrza domu:

Typ Jak działa Dobre dla
Shell Prop spawowany w współrzędnych, usuwany przy wyjściu Apartamenty, wiele identycznych domów
MLO Stałe wnętrze na mapie Unikalne domy i rezydencje

Shell to model, który ładujesz, umieszczasz w stałej lokalizacji (często wysoko na niebie lub daleko, pod mapą), i usuwasz, gdy gracz wyjdzie. Ponieważ ten sam shell może być spawany dla dowolnej liczby domów, shell'e to sposób, w jaki robisz budynki apartamentów. MLO pozostaje na mapie, więc jest ograniczone do jednego miejsca. Aby je zainstalować, zobacz instalacja MLO, a jeśli psuje mapę wokół, konflikty map MLO.

Instancjowanie za pomocą routing buckets

Jeśli każdy apartament używa tego samego shell'a w tych samych współrzędnych, to wszyscy, którzy wchodzą, stoją w tym samym pokoju. Rozwiązaniem jest danie każdemu domowi jego własnego routing bucketa, izolowanej kopii świata na serwerze. Gracze w różnych bucketach nie mogą widzieć się nawzajem ani się nawzajem. Pomysł w jednym zdaniu: dom numer 12 używa bucketa 12 (plus przesunięcie, aby nigdy się nie zderzał z innymi użyciami).

lua
-- server
local HOUSE_BUCKET_OFFSET = 1000

RegisterNetEvent('housing:enter', function(houseId)
    local src = source
    if not canEnter(src, houseId) then return end   -- ownership or key check

    SetPlayerRoutingBucket(src, HOUSE_BUCKET_OFFSET + houseId)
    TriggerClientEvent('housing:spawnShell', src, houseId)
end)

RegisterNetEvent('housing:leave', function()
    local src = source
    SetPlayerRoutingBucket(src, 0)
    TriggerClientEvent('housing:removeShell', src)
end)

Wszyscy, którzy odwiedzają ten dom, muszą być umieszczeni w tym samym buckecie, a każde wyjście musi ustawić bucket z powrotem na 0. Obsługuj także rozłączenia i restarty skryptów, aby żaden gracz nie pozostał w buckecie, do którego nikt inny nie może dotrzeć. Wszystkie native'y są wyjaśnione w routing buckets.

Wskazówka: jeśli spawujesz prop shell'a na kliencie, tylko ten gracz go widzi. Dla shell'a, który widzą także goście, każdy gość spawuje go dla siebie, lub serwer tworzy go w tym samym buckecie.

Sejf dla każdego domu

Każdy dom potrzebuje własnego magazynu. Z ox_inventory zarejestruj sejf dla każdego domu, z identyfikatorem, który zawiera identyfikator domu:

lua
-- server
exports.ox_inventory:RegisterStash('house_' .. houseId, 'House storage', 50, 100000, ownerId)

Następnie otwórz go z tym samym identyfikatorem na kliencie:

lua
exports.ox_inventory:openInventory('stash', 'house_' .. houseId)

Jeśli identyfikator jest taki sam dla każdego domu, każdy dom dzieli jeden sejf, co jest objawem od początku tego artykułu. Dodaj sprawdzenie uprawnień na serwerze przed otwarciem sejfu i zobacz ox_inventory sejfy aby dowiedzieć się o slotach, wadze i tym, kto może otworzyć jeden.

Klucze i uprawnienia

Właścicielstwo to nie jedyny sposób, aby wejść. Zaplanuj na te przypadki:

  • Właściciel: zawsze wchodzi, może sprzedać dom i dać klucze.
  • Posiadacze kluczy: przyjaciele lub najemcy, którzy mogą wejść i używać sejfu, ale nie mogą sprzedawać.
  • Goście: odwiedzają, gdy właściciel jest w środku i ich wpuszcza (dzwonek do drzwi).
  • Policja: nalot lub oficjalny wjazd, jeśli Twój serwer taki posiada.

Przechowuj klucze jako dane, a nie jako przedmiot, który możesz upuścić: listę identyfikatorów postaci dla każdego domu. Sprawdzaj listę na serwerze za każdym razem, gdy ktoś próbuje wejść lub otworzyć sejf.

Zapisywanie właścicielstwa w bazie danych

Wszystko, co musi przetrwać restart, trafia do bazy danych. Prosta struktura to jedna tabela dla domów i jedna dla kluczy:

sql
CREATE TABLE IF NOT EXISTS houses (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(64) NOT NULL,
  owner VARCHAR(64) DEFAULT NULL,
  price INT NOT NULL DEFAULT 0
);

CREATE TABLE IF NOT EXISTS house_keys (
  house_id INT NOT NULL,
  holder VARCHAR(64) NOT NULL,
  PRIMARY KEY (house_id, holder)
);

Przechowuj identyfikator postaci, który używa Twój framework (na przykład identyfikator postaci, a nie licencję gracza), aby właścicielstwo śledziło postać. Załaduj dane, gdy zasób się uruchamia i przechowuj kopię w tabeli serwera dla szybkich sprawdzeń, zapisując z powrotem do bazy danych przy każdej zmianie. Zapytania z Lua są w oxmysql queries.

Przepływy pieniędzy są także ważne: zakup, czynsz i zwrot sprzedaży powinny być obsługiwane na serwerze, i działają jako sink pieniędzy, jak opisano w balancing your server economy.

Częste błędy

  • Nie resetowanie bucketa przy wyjściu, śmierci, rozłączeniu lub restarcie.
  • Taki sam identyfikator sejfu dla wszystkich domów.
  • Sprawdzanie właścicielstwa na kliencie tylko.
  • Właścicielstwo przechowywane w pamięci i tracone przy restarcie.
  • Spawanie shell'a więcej niż raz gdy gracz szybko wraca, zostawiając zduplikowane propsy.

Checklist

Objaw Rozwiązanie
Gracze w różnych domach widzą się nawzajem Daj każdemu domowi jego własny routing bucket
Gracz utknął w pustym świecie Resetuj bucket na 0 przy wyjściu, śmierci i rozłączeniu
Każdy dom dzieli jeden sejf Użyj identyfikatora sejfu, który zawiera identyfikator domu
Właścicielstwo tracone przy restarcie Zapisz to w bazie danych
Każdy może wejść Sprawdzaj właściciela lub klucz na serwerze
Zduplikowane propsy shell'a Usuń shell przy wyjściu i chrań przed podwójnymi spawami

Szybkie odpowiedzi

Jaka jest różnica między shell'em a wnętrzem MLO?

MLO to wnętrze rzeczywiste umieszczone na mapie w stałych współrzędnych. Shell to prop, który spawujesz na żądanie, zwykle daleko od mapy, i usuwasz, gdy gracz wyjdzie.

Dlaczego gracze mogą widzieć się nawzajem w domach?

Każde wnętrze domu używa tych samych współrzędnych, więc gracze w różnych domach stoją w tej samej przestrzeni. Umieść każdy dom w swoim routing bucketcie, aby je oddzielić.

Gdzie należy zapisywać właścicielstwo domu?

W bazie danych, wraz z identyfikatorem domu i identyfikatorem postaci właściciela, oraz w osobnej tabeli lub kolumnie dla osób, które posiadają klucze. Nigdy nie przechowuj właścicielstwa tylko w pamięci.

Skrypty bez tego problemu

CCTV Security CamerasKamery do rozstawienia, tablet z podglądem wielu kamer na żywo i drukowane zdjęcia jako dowody.Zobacz skrypt →Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →

Czytaj dalej