-
Notifications
You must be signed in to change notification settings - Fork 0
basiConcepts
EN PL |
Introduction |
Opis |
- dodawanie nowych pojazdów z nowatorskimi funkcjami i grafiką w zależności od zmiennych gry,
- dodawanie nowych budynków i/lub gałęzi przemysłu z nowatorskimi funkcjami, takimi jak animacje graficzne i/lub właściwości i mechanika produkcji/obsługi ładunku,
- dodawanie nowych stacji i/lub nowych rodzajów torów, w tym niestandardowych sygnałów i tuneli,
- graficzne zamienniki kafli krajobrazowych, dróg, mostów, kanałów i/lub rzek,
- dodawanie wszelkiego rodzaju 'nowych obiektów' , zarówno wodnych, jak i/lub lądowych,
- modyfikacja cen i/lub kosztów,
- etc, pp.
W m4nfo numer wersji GRF jest automatycznie określany w grf_init() funkcji zestawu. Ponieważ m4nfo r96, domyślną wersją GRF jest 8, tj. Podczas kodowania zestawu dla TTDPatch należy go ustawić na wersję 7, za pomocą funkcji setgrfversion() przed grfinit(). W przypadku rozproszonych plików źródłowych należy również użyć setgrfversion() w każdym pliku źródłowym, dla różnych wersji GRF niż wersja 8.
Język programowania 'pseudo sprite'ów' newGRF nazywa się nfo. Typowa instrukcja nfo jest zbudowana z kolejnego 'numeru sprite' , liczby określającej długość 'sprite' i samego pseudo 'sprite' , w tym etykiety dla bieżącej funkcji (lub feature ) i określonego numeru, 'c-ID' , używanego jako odniesienie cele. Ten pseudo 'sprite' jest podawany jako zwykły strumień bajtów, który wygląda bardziej czytelnie maszynowo niż przyjemnie dla ludzkiego oka.
Słownik nfo podzielony jest na tak zwane 'actions' , z których każda odpowiada za określone zadania, takie jak inicjalizacja obiektów (akcja0), deklaracja prawdziwych 'sprites' (akcja1), zarządzanie zestawami 'sprites' (akcja2), obsługa wariacji na podstawie zmiennych i parametry (varaction2), łączenie identyfikatorów cech z odpowiednimi łańcuchami wariacji i zestawami sprite (akcja3), administrowanie ciągami tekstowymi (akcja4), obsługa rozgałęzień (akcja7 i akcja9), obsługa błędów (akcjaB) itp., str.
Pełną specyfikację nfo można znaleźć tutaj . Jest to lektura obowiązkowa dla udanego kodowania newGRF przy użyciu zwykłego nfo i cenne źródło informacji dla pomyślnego kodowania newGRF przy użyciu m4nfo.
Zarówno w TTDPatch, jak i OpenTTD, wersja NFO definiuje format plików nfo, czyli wejście / wyjście GRFCodec i nforenum. Obecny numer wersji to 7. Ponieważ nowsze wersje OpenTTD obsługują grafikę 32bpp z wyraźnymi poziomami powiększenia, istnieje inna wersja NFO 32, która również obsługuje/wymaga nowego formatu pliku GRF (wersja kontenera 2.0).
W m4nfo obsługiwane są wszystkie wersje GRF i NFO. Głównymi cechami m4nfo są koncepcje ' bloków ' i ' łańcuchów ' . Obie są dziedziczone z nfo. 'Blok' w m4nfo odpowiada ocenie 'pseudosprite' nfo, a 'łańcuchowanie' (reprezentujące przepływ kontroli) przez nfo za pomocą tak zwanych 'c-ID' jest realizowane przy użyciu 'referencji' .
W przypadku, gdy funkcja m4nfo jest częścią 'łańcucha', musi zadeklarować odniesienie, aby stała się dostępna i zawierać jedno lub więcej odniesień, aby uzyskać dostęp do innych funkcji m4nfo. To znaczy.:
def(<reference>, <m4nfo-function>({<parameter>},{<reference>}>)
Dla lepszej czytelności, w m4nfo początkowe odniesienie do funkcji jest wizualnie oddzielone od funkcji:
def(<reference>) <m4nfo-function({<parameter>},{<reference>}>
Więc,
Format (function chaining): def(<Byte>[, <Label>]) - defines a reference for a function ref(<Byte> | <Label>) - references a function
W poniższym przykładzie istnieją dwa łańcuchy kontroli, jeden jest podświetlony na niebiesko, a drugi na żółto. Niebieska łączy def(5)
<- ref(5)
<- def(6)
<- ref(6)
<- def(8) <- ref(8), a żółta łączy def(7) <- ref(7) <- def(8) <- ref(8).
Należy odnotować, że przepływ kontroli, zarówno w nfo, jak i m4nfo, jest zawsze 'do góry nogami' , tj. Jego źródłem (w tym przykładzie) jest funkcja makevehicle() , łącząca ID-pojazdu z powiązanymi ikonkami graficznymi za pomocą tego zilustrowanego 'łańcucha kontroli' . Potraktuj to jako drzewo 'odwrócone' , w którym liście muszą być zdefiniowane przed pniem.
W ten sposób w przypadku wywołania zwrotnego CB_POWR
wykonywane są efekty steam w def(7) ('effect
()' zwraca wynik callback), podczas gdy w gałęzi graphics w def (8) łańcuch punktów kontrolnych do def(6)
i - poprzez gałąź 'else' - wskazuje na funkcję animacji (def(5)
).
Przykład (chaining): // graphics def(5) animation( ref(0) if(3) ref(1) if(2) ref(2) if(1) ref(3) else ) def(6) flipped( ref(4) if(FORWARD) // offsets, animation and lights "forwards" ref(5) else // offsets, animation and lights "backwards" ) // effect def(7) flipped( effect(steam(4)) if(FORWARD) effect(steam(8)) else ) // callbacks engine def(8) callback( ref(7) if(CB_POWR) // steam position ref(LIGHTS) if(CB_RCOL) // switch lights ref(6) else // graphics ) makevehicle(_030TRAMWAY, link(ref(1),MENU) // purchase menu default(ref(8)) // locomotive override(_MSP,ref(4)) // tramway coach )
Blok stanowi wewnętrzną część funkcji, chociaż technicznie rzecz biorąc jest jednym z parametrów funkcji (chociaż nie jest ograniczony do wartości liczbowej, ciągu tekstowego lub funkcji). Blok ( 'podświetlony' na żółto) zawiera jedną lub więcej funkcji if() i dokładnie jedną 'else':
Przykład (block): def(20) veh_cargotype( ref(1) if(FERT) // fertilizer (ECS) ref(2) if(FMSP) // farm supplies (FIRS) ref(3) if(CERE, GRAI) // cereals (ECS), grain ref(4) if(IORE) // iron ore ref(5) else ) |
Nie każda funkcja w m4nfo potrzebuje lub może używać bloku. Blok jest potrzebny tylko dla funkcji zwracających wartość, na podstawie której musi zostać podjęta decyzja, przez większość czasu powodując powiązanie z inną funkcją. Na przykład funkcje losowe lub spriteset nie mają bloku:
Przykład (functions w/o a block): def(5) randomrel(LOAD,0,ref(1),ref(2),ref(3),ref(4)) def(2) spriteset(move(1,23,25,27,5),load(1,23,25,27,5)) // blue
W rzeczywistości m4nfo używa całkiem różnych typów funkcji, które zostaną szczegółowo wyjaśnione, a mianowicie:
- funkcje właściwości - do definiowania właściwości w różnych funkcjach określających cechy (np. w definevehicle() ),
- funkcje układu - w celu zdefiniowania układu sprite'ów na podstawie ich grafiki, współrzędnych i informacji 3D, jak np. spriteset() powyżej,
- funkcje wydajności - aby uzyskać szczegółowe informacje o danej funkcji (np. aktualna prędkość pociągu), a także uzyskać dostęp do zmiennych związanych z grą, takich jak aktualna data, klimat itp.
- funkcje pomocnicze - z których korzystają te dwa poprzednie typy funkcji,
- funkcje globalne - funkcje, które mogą być używane przez wiele funkcji, np. funkcje losowe,
- funkcje ogólne - są niezależne od funkcji, np. obsługa błędów lub rozgałęzianie wewnątrz newGRF.
Pojęcie 'features' w m4nfo jest 'dziedziczone' z nfo (lub link action0 feature ), ponieważ całkiem dobrze pasuje do jego modułowego podejścia. Aby obsłużyć funkcję w m4nfo, należy załadować skojarzony z nią plik biblioteki M4, a odpowiednią funkcję należy wypowiedzieć, wywołując funkcję setfeature() z odpowiednim parametrem (patrz tabela poniżej).
Funkcje obecnie obsługiwane przez m4nfo to:
Feature | keyword | support | module |
---|---|---|---|
trains | _TRAIN | trains.m4 | |
road vehicles | _ROADVEHICLE | roadvehs.m4 | |
ships | _SHIP | ships.m4 | |
stations | _STATION | stations.m4 | |
canals | _CANAL | canals.m4 | |
bridges | _BRIDGE | bridges.m4 | |
houses | _HOUSE | houses.m4 | |
global variables | header.m4 | ||
cargoes | _CARGO | cargos.m4 | |
sound effects | _SOUND | ||
newobjects | _OBJECT | objects.m4 | |
rail types | _RAILTYPE | railtypes.m4 | |
aircraft | _AIRCRAFT | ||
industry tiles | _INDUSTRYTILE | ||
industries | _INDUSTRY | ||
airports | _AIRPORT | ||
signals | _SIGNAL | ||
airport tiles | _AIRPORTTILE |
Typy danych, stałe i funkcje używane wspólnie przez którąkolwiek z tych funkcji są zawarte w module 'header.m4' . Musi to być zawsze dołączone do modułu określonej funkcji:
Przykład (ustawienie i używanie funkcji): // start of file include(names.m4) // local stuff setfeature(_TRAIN) ... definevehicle(...) ... makevehicle(...)
Odnotowując, że gdy używane "prekompilowanego" modułu, np. m4nfo_trains.m4 , nie musisz dołączać ani tego, ani nagłówka m4nfo, ani pliku funkcji, ale tylko "prywatne" pliki dołączane (np. names.m4 powyżej).
Introduction |
Jednak drugie ograniczenie jest trudne. Istnieje kilka przyczyn tego 'ograniczenia', z których najważniejsze to fakt, że m4nfo nie musi sprawdzać rzeczywistej funkcji dla każdej funkcji i nie musi sprawdzać poprawności funkcji dla określonej funkcji : moduły funkcji zawierają tylko funkcje, które są gwarantowane dla wstępnie ustawionej funkcji.
Zaleca się podzielenie dużego projektu na kilka plików źródłowych, aby ułatwić obsługę całego projektu. Na przykład w przypadku dużego zestawu pociągów te pliki mogą być:
- plik 'ogólny' , odpowiedzialny za sprawdzanie takich rzeczy, jak wersja TTDPatch/OTTD, klimat lub różne flagi TTDPatch (np. newtrains ), w tym inicjalizacja newGRF, w tym specjalne grafiki, takie jak sprite void, set basecosts, tablice tracktype , translacja ładunku tabele , ciągi tekstowe dla przyrostków tekstowych ładunku, ciągi tekstowe dla komunikatów o błędach, ciągi dla tekstów pomocy lokomotywy i tabele zmiany koloru,
- plik z definicjami dla wszystkich lokomotyw i wagonów,
- plik zawierający grafikę i kod dla 'wagony pas.',
- plik zawierający grafikę i kod dla lokomotyw
- plik z definicjami dla wszystkich wagonów towarowych,
- plik zawierający grafikę i kod dla wagonów towarowych,
- plik z dodatkowymi udogodnieniami takimi jak bramki czy ... ,