Skip to content

stationFunctions

extrazi edited this page Jun 26, 2023 · 14 revisions

Instrukcja obsługi m4nfo i raport techniczny

   
EN PL
Korzystanie z funkcji dla stacji kolejowych

Zawartość

Wprowadzenie

W m4nfo stacje wykorzystują cztery rodzaje funkcji:

  • funkcje do definiowania układu płytek z duszków, współrzędnych i informacji 3D,
  • funkcje do uzyskiwania informacji o bieżących (lub sąsiednich) właściwościach kafelka, takich jak liczba lub długość platform, typ terenu, nachylenie terenu itp., A także funkcje uzyskujące dostęp do zmiennych wewnętrznych gry, takich jak bieżąca data, klimat itp. Zobacz funkcje wydajności stacji,
  • funkcje pomocnicze, które są wykorzystywane przez te dwa pierwsze rodzaje funkcji,
  • Funkcje globalne, które są ważne nie tylko dla stacji, ale dla wszystkich funkcji.

Format

W przypadku kafelków stacji układ kafelków określa, jakie duszki powinny być wyświetlane, gdzie mają być wyświetlane i w jakiej kolejności.

Ponieważ w TTD układ kafelków dla stacji jest nieco inny niż dla budynków i obiektów, musi to być również odzwierciedlone przez m4nfo. Głównym powodem tej różnicy jest to, że dla stacji układ kafelków jest oddzielony od prawdziwych sprite'ów zdefiniowanych w spriteblock() i dostępnych za pomocą funkcji spriteset(), a w ten sposób układ może łatwo obsługiwać różne zestawy duszków o tej samej strukturze układu.

layout(<ID>, {<tile>(
[label,] <groundsprite> {<buildingsprite>(<xoffset, yoffset, zoffset> <xextent, yextent, zextent>) |
<buildingsprite>(<xpixeloffset,
ypixeloffset>)}
  }
)

Opis

W przypadku płytek stacji istnieją dwa rodzaje duszków. Pierwszy typ ustanawia nową obwiednię 3D do użycia przez sorter kształtów. Drugi typ współdzieli obwiednię 3D poprzedniego duszka. Nie może być większy od duszka, który ustanowił obwiednię, ani też żadna jego część nie może znajdować się poza tym polem. Dla uproszczenia może mieć dokładnie takie same wymiary jak ikonka, z którą dzieli obwiednię.

Obwiednia 3D jest używana przez sorter sprite'ów TTD do określenia kolejności rysowania duszków, a także do poinformowania go, które duszki mają zostać narysowane, ponieważ te, których obwiednia znajduje się poza aktualnie zaktualizowanym prostokątem ekranu, nie zostaną narysowane. Upewnij się, że obwiednia 3D jest wystarczająco duża, aby pomieścić całego duszka, ale nie tak duża, aby sorter kształtów nie mógł określić, które duszki powinny znajdować się z przodu.

Oznacza to, że kolejność, w jakiej duszki są określone, nie ma znaczenia. Sprite'y zawsze będą losowane od tyłu do przodu, w kolejności, którą sorter duszków uzna za poprawną, z ich obwiedni. Istnieją jednak dwa wyjątki:

  • Sprite'y dzielące tę samą obwiednię będą zawsze rysowane w podanej kolejności.
  • Okno budowy stacji nie korzysta z sortera kształtów. Kafelki, które mogą być wyświetlane w tym oknie, muszą być określone w odpowiedniej kolejności rysowania, od tyłu do przodu.

Podobnie jak w przypadku domów, płytek przemysłowych i obiektów, m4nfo zapewnia te same funkcje pomocnicze, które mają być używane w definicjach układu płytek, ale z nieco inną składnią niż dla wyżej wymienionych funkcji:

Termin układu M4NFO, funkcja
<płytka> tile() | xtile()
<Groundsprite> ziemia() | NOSPRITE
<budynki> regular() | notransparency() | szkło() | recolour() | NOSPRITE
<xoffset, yoffset, zoffset> xyz()
<xoffset, yoffset> xy()
<xextent, yextent, zextent> dxdydz()
<xpixeloffset, ypixeloffset> xyoff()

Ta funkcja konfiguruje układ kafelków dla określonego identyfikatora stacji. Potrzebuje co najmniej dwóch wywołań funkcji tile() (lub jednego z xtile()): jednego dla kafelka w x- i drugiego dla kierunku y. Wywołania tile()/xtile() są kolejno numerowane wewnętrznie, tzn. pierwszy kafelek stacji otrzymuje numery 0/1 (kierunek x/y), drugi otrzymuje 2/3 i tak dalej. Są to numery kafelków, do których odwołuje się CB_LAYOUT wywołania zwrotnego z funkcji makestation() podczas rysowania wszystkich kafelków stacji we właściwy sposób. (Oczywiście możliwe jest użycie "etykiet" zamiast liczb podanych pośrednio, patrz następny akapit.)

Struktury układu mogą być używane wielokrotnie, odwołując się do różnych zestawów sprite'ów graficznych.

Ta funkcja pobiera blok definicji sprite'ów, zarówno dla duszków naziemnych, jak i duszków budynków, patrz poniżej. Kafelek może być oznaczony etykietą, aby odwołać się do niego później, np. w łańcuchu CB_LAYOUT:

Przykład:
layout(_ROOFS,
	...
	tile(__roofs,
		ground(1011)
		regular(21, xyz(0,0,0), dxdydz(5,16,12))
		regular(24, xyz(0,0,0), dxdydz(16,16,35))
   	)
	...
)

... def(3) plt_num( self( reftile(__roofs) if(4) reftile(__roofs+1) if(3) reftile(__roofs+2) if(2) reftile(__roofs+3) if(1) reftile(0) else ) )


Funkcja xtile() może być używana do automatycznego generowania definicji ikonek dla kafelka w kierunku y, pochodzących z kafelka w x-direction. Użycie tej metody wymaga wielu dodatkowych wymagań i jest bardziej ograniczone niż użycie tile(): duszki budowlane muszą być uporządkowane w taki sposób, aby ich numery sprite'ów wynosiły +1 dla płytki w kierunku y, a dla sprite'ów naziemnych różnica musi wynosić -1 dla oryginalnych sprite'ów TTD i +1 dla niestandardowych duszków gruntowych. Współrzędne 3D zostaną odpowiednio zamienione. Sprite'y graficzne skojarzone z kierunkami x i y układu xtile() muszą być symetryczne, aby zapewnić poprawne obwiedni, a nie można użyć funkcji xyoff(), ponieważ współrzędne kształtów graficznych są całkowicie nieznane w układach kafelków.

Ta funkcja definiuje duszka ziemi, który ma być użyty dla danego kafelka. W bloku kafelka może istnieć tylko jeden duszek ziemi zdefiniowany przez metodę ground(). W przypadku wielu (ułożonych) płytek gruntowych muszą one być dostarczone za pomocą funkcji regular() przed zdefiniowaniem jakiejkolwiek obwiedni.

Można zdefiniować oryginalne duszki terenu TTD lub niestandardowe duszki gruntu zdefiniowane w spriteblock(). W takim przypadku potrzebny będzie drugi parametr ustawiony na CUSTOM.

Jeśli nie jest potrzebny sprite, należy użyć makro NOSPRITE zamiast wywoływania funkcji ground(). Może to być przydatne do wyświetlania grafiki ikon lub podczas rysowania niestandardowych fundamentów.

Ta funkcja definiuje "normalnego" duszka budynku (lub dodatkowego duszka gruntowego). Pierwszy parametr to indeks do spriteblock powiązany z bieżącym układem, pozostałe parametry są albo przesunięte od północnego rogu płytki i rozmiaru sprite'a, albo przesunięcia względem poprzedniego sprite'a (patrz zdjęcia poniżej). W tym drugim przypadku ten duszek będzie dzielił swoją obwiednię z bieżącą obwiednią. Ustawienie opcjonalnego parametru "TTD" umożliwia dostęp do oryginalnych duszków TTD.

Ta funkcja działa tak samo jak regular(), tylko gdy jej duszek jest wyświetlany normalnie nawet w trybie "przezroczystych budynków".

Ponownie to samo zachowanie co w przypadku regular(), ale tym razem przy użyciu domyślnej translacji kolorów firmy.

Znowu to samo zachowanie co regular(), ale tym razem z translacją kolorów zdefiniowaną przez tabelę recolor podaną przez ostatni parametr.

To samo zachowanie co w przypadku metody regular(), ale sprite jest rysowany w trybie 'transparent', albo przy użyciu domyślnego trybu 'glass', albo przy użyciu niestandardowego przezroczystego kolorowania, gdy podano dodatkowy parametr. Ten parametr musi być adresem mapy ponownego kolorowania, która ma być użyta do uzyskania efektu szkła.

Ta funkcja definiuje przesunięcia x/y/z bieżącego duszka z północnego rogu kafelka. Zwróć uwagę, że współrzędne są współrzędnymi 3D, gdzie x biegnie od prawego górnego rogu do lewego dolnego rogu i y biegnie od lewego górnego do prawego dolnego rogu (patrz rysunek poniżej), przy czym wymiary kafelków wynoszą 16x16 px dla x i y oraz 8 px dla jednego poziomu wysokości. Oznacza to, że wartości x i y powinny zawsze mieścić się w granicach 0 .. 15.

Ta funkcja definiuje rozmiar bieżącego duszka w kierunku x/y/z. Podane współrzędne są równe powyższym współrzędnym.

Ta funkcja definiuje przesunięcia x/y duszka podrzędnego w stosunku do poprzedniego ustawienia kształtu obwiedni. Współrzędne odnoszą się do lewego górnego rogu poprzedniego sprite'a, tj. nie jest to współrzędna 3D.


W nowszych wersjach OpenTTD obsługiwany jest tak zwany "zaawansowany format układu duszków" (ASL), który umożliwia "dynamiczne" modyfikacje układu za pomocą rejestrów.

Formalna specyfikacja M4NFO dla tego formatu jest jak wyżej, z wyjątkiem dwóch dodatkowych parametrów w funkcjach M4NFO ground(), regular(), recolour() i glass(), a mianowicie <flags> (ustawiane przez funkcję aslflags()) i <registers> (ustawiane przez rejestry funkcji()). Np. ground(<sprite> [,CUSTOM]) otrzymuje ground(<sprite> [,CUSTOM], <flags>, <registers>) lub regular(<tile-id>, (<xyz()>, <dxdydz()>) | <xyoff()> [,TTD]) otrzymuje regular(<tile-id>, (<xyz()>, <dxdydz()>) | (<xyoff()> [,TTD]), <flagi>, <rejestr>.)

Funkcja aslflags() przyjmuje jako parametr cytowaną listę następujących flag:

Flagi w zaawansowanych układach kształtów
Wartość Etykieta duszek macierzysty duszek naziemny/podrzędny rejestr(-y)
1 POMINĄĆ Pomiń obwiednię w tym duszki podrzędne Pomiń duszka 1
2 OFFSET_SPRITE Dodaj przesunięcie do numeru duszka, wyłącz domyślne użycie etapu budowy lub przesunięcia typu szyny 1
4 OFFSET_RCSPRITE Dodaj przesunięcie, aby ponownie pokolorować liczbę ikonek
8 CUSTOM_RCSPRITE Recolor sprite pochodzi z niestandardowego spriteblocka OFFSET_SPRITE może być również użyty N/a
16 OFFSET_XY Dodaj przesunięcie 3D w <x> i <y>   2
32 OFFSET_Z Dodaj przesunięcie 3D w <z>   1
48 PIXOFFSET_XY   Dodaj przesunięcie pikseli w <x> i <y> 2
64 RESOLVE_SPRITE Rozpoznawanie sprite'a za pomocą metody spritetype() o określonej wartości 1
128 RESOLVE_RCSPRITE Rozpoznawanie recolor sprite za pomocą spritetype() o określonej wartości 1

Potrzebne rejestry są ustawiane przez funkcję registers(), również jako listę cytatów. Kolejność rejestrów musi być taka sama jak w przypadku podanych flag (patrz przykłady). W przypadku flag nieużywanych nie określono rejestru. Ponieważ przesunięcia dla <x> i <y> mogą być włączone tylko razem, potrzebne są dwa rejestry. Rejestr dla SKIP używa wartości "1" do narysowania duszka i "0" do pominięcia go. Flaga CUSTOM_RCSPRITE nie używa żadnego rejestru.

Dwie ostatnie flagi (RESOLVE_SPRITE, RESOLVE_RCSPRITE) są ważne tylko dla stacji. W przypadku stacji łańcuch sterowania jest rozwiązywany wiele razy, a sprite'y mogą być częścią różnych bloków duszków (duszki naziemne (0), sprite'y budynku (1), niestandardowe sprite'y fundamentowe (2)) już bez użycia formatu zaawansowanego układu sprite'ów.

W przeciwieństwie do pierwszych 6 flag, oba parametry flagi stacji w rejestrach funkcyjnych () nie są rejestrami, ale reprezentują wartość z zakresu 0 .. 7, do którego dostęp uzyskuje funkcja spritetype() podczas przetwarzania łańcucha sterowania i rozpoznawania odpowiednich duszków.

Pamiętaj, że niektóre wartości mogą być już używane, np. "2" do rozwiązywania niestandardowych duszków fundamentowych. Nawet jeśli duszek nie pochodzi z bloku spriteblock, ale z oryginalnego duszka TTD, wartość nadal określa, który łańcuch kontroli definiuje wartości odniesienia dla funkcji registers().

Aby uzyskać więcej informacji, zobacz przykład 4 poniżej.

Przykłady

W TTD "normalne" płytki stacji (mogą istnieć egzotyczne płytki składające się tylko z duszka naziemnego lub dodatkowego duszka z pojedynczej platformy) są zwykle składane z trzech duszków: podstawy toru (ground sprite), duszka "background" i "pierwszego planu". Te duszki są ułożone tak, aby zbudować płytkę stacji w taki sposób, że pociągi biegną po tle, a duszki naziemne, podczas gdy duszek pierwszego planu pokrywa wszystko. Zobacz zdjęcie poniżej.

W przypadku dodatkowego dachu stacji lub wiaduktu, te duszki zostaną dodane jako ostatnie lub mogą zostać zintegrowane z duszkiem na pierwszym planie.

Ponadto kafelki stacji zawsze muszą być zdefiniowane dwukrotnie (nawet dla ikon menu budynku), tj. w kierunku x i y.

Układ duszków

Przykład 1 (prosty kafelek stacji 2-peronowej, patrz zdjęcie powyżej):
layout(_ROOFS,
  tile(
    ground(1012) // track x
    regular(1, xyz(0,0,0),dxdydz(16,5,8)) 
    regular(3, xyz(0,11,0),dxdydz(16,5,8))
  )
  tile(
    ground(1011) // track y
    regular(2, xyz(0,0,0),dxdydz(5,16,8))
    regular(4, xyz(11,0,0),dxdydz(5,16,8))
  )
  ...
)

W m4nfo można uniknąć konieczności definiowania zarówno x-, jak i y-tile poprzez wymianę funkcji tile() z funkcją xtile(), która automatycznie wygeneruje płytki dla kierunku y, w przypadku, gdy płytki są lustrzanym odbiciem siebie nawzajem, pod względem graficznym. Oznacza to, że w powyższym przykładzie należy podać tylko pierwszy kafelek, a za pomocą xtile() automatycznie zostanie dodany drugi kafelek ze sprite'em #1011 i normalnymi sprite'ami #2 i #4, wraz z odpowiednią zamianą ich współrzędnych.

przezroczystość

Przykład 2 (prosty kafelek stacji 2-peronowej z duszkami podrzędnymi):
layout(_GLASS,
// modern glass 'tinted green'
  tile(
    ground(1012)
    compcol(502, xyz(0,0,0),dxdydz(16,5,11))
    glass(538, xyoff(0,0), GREEN) 
    compcol(504, xyz(0,11,0),dxdydz(16,5,11)) 
    glass(540, xyoff(0,0), GREEN)
  )
  tile(
    ground(1011)
    compcol(503, xyz(0,0,0),dxdydz(5,16,11))
    glass(539, xyoff(0,0), GREEN) 
    compcol(505, xyz(11,0,0),dxdydz(5,16,11)) 
    glass(541, xyoff(0,0), GREEN)
  )

... )

Przykład 2 pokazuje układ kafelków platformy "nowoczesnego szkła" z NewStations. Składa się z pięciu duszków: duszka ziemnego, dwóch duszków platformowych rysowanych w "kolorze firmy", każdy z przezroczystym duszkiem "szklanym", które są zdefiniowane jako "duszki potomne", tj. duszki dzielące swoje pole ograniczające z poprzednimi duszkami za pomocą obwiedni (duszki platformowe).

Detale, które mają być przedstawione w jednym z 8 dostępnych kolorów firmowych, muszą być narysowane specjalnym kolorem, spójrz na palety TTD. Jednak obszary reprezentujące efekt przezroczystego szkła mogą być narysowane w dowolnym kolorze (w tym przykładzie czerwonym). W tym przykładzie pokazano również, jak użyć "efektu szkła niestandardowego" (przyciemniane zielone szkło). Wymaga to skonfigurowania niestandardowej tabeli kolorów, aby uzyskać pożądany efekt.

Wiele duszków naziemnych

Przykład 3 pokazuje, jak używać wielu sprite'ów ziemi dla płytki. Jest to przydatne, jeśli chcesz użyć zwykłego duszka z szyny/trawy/betonu, ale nadal musisz dodać do niego funkcje bez użycia nowej obwiedni. W tym celu używana jest składnia duszków współużytkujących poprzednią obwiednię, ale przed zdefiniowaniem pierwszej definicji obwiedni.

Przykład definiuje dwa typy punktów trasy, pierwszy składa się wyłącznie z duszków naziemnych, a drugi z dodaną duszką budynku.

Przykład 3 (użycie wielu duszków gruntowych):
layout(_WAYP2,
// w/o building
  tile(
      ground(1012) // track
      regular(0, xyoff(0,0)) // overlay 
  )
  tile(
      ground(1011) // track
      regular(1, xyoff(0,0)) // overlay 
  )

// w building tile( ground(1012) // track regular(0, xyoff(0,0)) // overlay regular(2, xyz(0,0,0),dxdydz(16,5,10)) // building ) tile( ground(1011) // track regular(1, xyoff(0,0)) // overlay regular(3, xyz(0,0,0),dxdydz(5,16,10)) // building ) )

Zauważ, że <xpixeloffset> i <ypixeloffset> w OpenTTD odnoszą się do zwykłego miejsca podłoży, ale są ignorowane w TTDPatch i ustawione na zero. Tak więc, w przypadku opracowywania nowego GRF, który musi być kompatybilny z obydwoma programami, należy zawsze zachować <xpixeloffset> i <ypixeloffset> zero, aby uzyskać ten sam efekt w obu.

Zauważ jednak, że ze względu na złą specyfikację w zwykłym nfo, obie implementacje nie uwzględniają ustawienia GROUNDSPRITES w flagach funkcji właściwości (), stąd te "wielokrotne sprite'y gruntowe" muszą być zawsze częścią zestawu sprite'ów budowlanych i nie mogą być częścią innego zestawu sprite'ów dla sprite'ów gruntowych. W związku z tym nie można sprawdzić wielu sprite'ów gruntu za pomocą funkcji spritetype().

fundamenty na zamówienie

W przeciwieństwie do niestandardowych fundamentów domów, płytek przemysłowych i obiektów, fundamenty dla stacji nie wymagają specjalnej obsługi wewnątrz definicji układu płytek.

Zamiast tego potrzebne sprite'y są definiowane w specjalnym sprriteblock i dostępne wewnątrz łańcucha graficznego za pomocą funkcji spritetype(). Należy pamiętać, że musi to ustawić flagę NOFOUNDATION w property function flags().

Zaawansowany układ duszków

Przykład 4 pokazuje, jak skorzystać z "zaawansowanego układu duszków" w przypadku powtarzających się układów stacji. Dobrym przykładem może być układ stacji z koniecznością powtarzania się, tylko dla różnych duszków ładunku, co można przedstawić poprzez ponowne zabarwienie przykładowego sprite'a ładunku. Zaawansowany układ sprite'ów dla stacji daje możliwość po prostu włączenia recolor sprite'ów do ich własnego bloku duszków i łatwego dostępu do nich za pomocą funkcji układu.

Przykład 4 (wykorzystanie rejestrów i zmiana koloru duszków):
asl_on()

layout(ADVTEST, tile( ground(1012) recolour(0, xyz(8,8,0), dxdydz(8,8,8), 0, aslflags({OFFSET_RCSPRITE, CUSTOM_RCSPRITE, RESOLVE_RCSPRITE}), registers({11,4})) ) tile( ... ) )

// building sprites spriteblock( set( sprite(advtest.pcx 10 10 09 22 32 -14 -16) ) )

def(0) spriteset(little(0))

// recolour sprites - orange and blue spriteblock( set( colourtable(DOSMAP, 62 .. 67, C0 .. C5, ) colourtable(DOSMAP, 62 .. 67, 92 .. 97, ) ) )

def(1) spriteset(little(0))

def(2) spritetype( ref(1) if(4) // recolour sprites ref(0) else // building sprites )

def(3) setregisters(11,1,ref(2)) // 2nd recolour entry: blue

def(4) callback( cbr(0) if(CB_LAYOUT) ref(3) else // graphics )

makestation(ADVTEST, default(ref(4)) )

Należy pamiętać, że rejestry używane w zaawansowanym układzie kształtów muszą być ustawione wewnątrz łańcucha grafiki, a nie w łańcuchu wywołania zwrotnego. Odbywa się to w def(3), gdzie funkcja setregisters() ustawia rejestr '11' na wartość '1', tj. drugi wpis recolor sprrite. W def(2) łańcuch grafiki jest podzielony na łańcuch dla duszków budynku, def(0), i dodatkowy łańcuch dla duszków rekolorowych, def(1).

W układzie duszek jest definiowany do ponownego kolorowania za pomocą funkcji recolour(), przy czym pierwszy parametr ustawia duszka budynku, a 4. parametr ustawia duszkę recolor, oba w tym przypadku "0". Parametr 5 określa flagi OFFSET_RCSPRITE, CUSTOM_RCSPRITE i RESOLVE_RCSPRITE, a parametr 6 określa rejestr, który ma być użyty do zdefiniowania przesunięcia duszka recolor oraz łańcuch grafiki do rozpoznawania sprite'ów recolor (4).

Funkcja ta umożliwia skopiowanie definicji układu kafelków. Pierwszy argument to identyfikator stacji, dla którego zdefiniowano układ kafelków, pozostałe argumenty to identyfikatory stacji, do których należy skopiować układ kafelków. Te identyfikatory muszą być zakresem kolejnych identyfikatorów stacji.

Tak samo jak powyżej, ale ta funkcja umożliwia skopiowanie niestandardowej definicji układu kafelka TTD. Pierwszy argument to identyfikator stacji, dla którego zdefiniowano niestandardowy układ kafelków TTD, pozostałe argumenty to identyfikatory stacji, do których należy skopiować niestandardowy układ kafelków. Tak jak poprzednio, identyfikatory te muszą być zakresem następujących po sobie identyfikatorów stacji.

Ta funkcja może być używana do modyfikowania dużych układów w odniesieniu do ponownego kolorowania. Odnosi się do górnych 2 bajtów numeru duszka, który zawiera jego translację recolor, patrz przykłady. W ten sposób można zastosować różne niestandardowe zmiany koloryzacji, w zależności od dostarczonego parametru. Ponadto możliwe byłoby przekształcenie duszka używającego koloru firmowego w duszka, który zostanie ponownie pokolorowany przez niestandardowe ponowne kolorowanie lub odwrotnie.

Pierwszy parametr musi być parametrem grf definiującym liczbę duszków recolor, która ma być użyta, z liczbą płytek do przetworzenia podaną przez parametr 2 i liczbą duszków budynków na płytkę podaną przez parametr 3. Funkcja patchlayout() musi bezpośrednio poprzedzać skojarzoną z nią funkcję layout().

Przykład 1:
define(_COLOUR,4)

setparameter(_COLOUR, 0x314) // TTD recolour sprite ... skipif(1, getowngrfparameter(0), BITSET, _COLOUR) patchlayout(_COLOUR, 90, 1)

layout(LOW_BLOCK, // 0 // F4 03 00 00 00 00 00 10 10 18 45 84 <00 00> 80 tile( ground(1012) compcol(24, xyz(0,0,0), dxdydz(16,16,24)) ) ... // 89 // F3 03 00 00 00 00 00 10 10 18 51 84 <00 00> 80 tile( ground(1011) compcol(36, xyz(0,0,0), dxdydz(16,16,24)) ) )

Spowoduje to ustawienie numeru duszka recolor z parametru 4 dla 90 płytek tego układu.

Przykład 2:
define(_COLOUR,4)

setparameter(_COLOUR, 0x314) // TTD recolour sprite ... skipif(1, getowngrfparameter(0), BITSET, _COLOUR) patchlayout(_COLOUR, 2, 2)

layout(OPASS_LOW, // F4 03 00 00 00 00 00 05 05 08 2D 84 <00 00> // 00 00 00 10 10 18 2E 84 <00 00> 80 // F3 03 00 00 00 00 00 05 05 08 2F 84 <00 00> // 00 00 00 10 10 18 30 84 <00 00> 80 tile( ground(1012) compcol(0, xyz(0,0,0), dxdydz(5,5,8)) compcol(1, xyz(0,0,0), dxdydz(16,16,24)) ) tile( ground(1011) compcol(2, xyz(0,0,0), dxdydz(5,5,8)) compcol(3, xyz(0,0,0), dxdydz(16,16,24)) ) )

Spowoduje to ustawienie numeru duszka recolor z parametru 4 dla 2 płytek tego układu z 2 duszkami budynku każda.

Zauważ, że nie jest możliwe przekolorowanie ani duszków naziemnych, ani duszków "potomnych" (tj. tych, które dzielą obwiednię z poprzedzającym ją duszkiem z własną obwiednią). Zobacz opis funkcji regular(), compcol() i recolour().

Funkcje te służą do oceny zmiennych wewnętrznych gry i udostępniania ich funkcji aktywacji stacji. Typowa aplikacja wykorzystuje wiele tych funkcji połączonych ze sobą w "łańcuch", łącząc sprite'y graficzne stacji z jej funkcją aktywacji. Zobacz tutaj przykład.

Funkcja Opis
anim_frame([<Współrzędne> | ZAREJESTRUJ SIĘ,] <blok>) Pobieranie klatki animacji
anim_trigger(<blok>) Pobierz bieżący wyzwalacz animacji
wywołanie zwrotne(<blok>) Sprawdź typ oddzwaniania
cargohist(<Rodzaj ładunku> | REJESTRACJA, <blok>) Pobierz historię ładunku
cargotrigger(<blok>) Uzyskaj typ ładunku dla wyzwalacza animacji
cargowaiting(<Rodzaj ładunku> | REJESTRACJA, <blok>) Ilość ładunku oczekującego
inaczej To naprawdę puste stwierdzenie
exclusiverights(<block>) Liczba miesięcy wyłączne prawa do transportu będą obowiązywać
iswaypoint(<block>) Stacja punktu trasy nie otrzyma żadnego ładunku
pbsinfo(<blok>) Informacje o sygnalizacji opartej na ścieżce
plt_axis([<maska-przesunięcia>,] <blok>) plt_edges(<blok>) plt_even_length(<blok>) plt_even_num(<blok>) plt_even_numrev(<blok>) plt_even_pos(<blok>) plt_even_posrev<blok>) plt_index(<blok>) plt_indexrev(<blok>)








plt_length([<maska-przesunięcia>, ] <blok>) plt_midnum([<maska-przesunięcia>,] <blok>) plt_midpos([<maska-przesunięcia>,] <blok>) plt_num([<maska-przesunięcia>,] <blok>) plt_numrev([<maska-przesunięcia>,] <blok>) plt_pos([<maska-przesunięcia>,] <blok>) plt_posrev([<maska-przesunięcia>,] <blok>) plt_size(<blok>) plt_tiletype(<blok>)








plt_total([<maska-przesunięcia>,] <blok>)
Informacje o bieżących kafelkach platformy
RandomBits(<block>) Losowe bity z CB_ACONTROL
servicedbytype(<block>) Typ(-y) pojazdu(-ów) obsługującego(-ych) tę stację
SpriteType(<Block>) Sprawdź typ duszka
Stacjonarność (<blok>) Wiek stacji w latach od 1920 roku
test_pos(<blok>) test_posrev(<blok>) test_num(<blok>) test_numrev(<blok>) test_length(<blok>) test_total(<blok>) test_axis(<blok>) test_position(<blok>) test_size(<blok>) test_tiletype([<maska-przesunięcia>,] <blok>)








Sprawdzanie typu kafelka dla CB_TILETYPE
test_pltlength(<blok>) test_plttotal(<blok>) test_pltnum(<blok>) test_pltpos(<blok>)


Sprawdzanie platformy pod kątem CB_SLOPE
test_slope(<blok>) Kontrola nachylenia CB_SLOPE
timesinceload/timesinceunload(<block>) Czasy od ostatniej operacji załadunku ładunku miały miejsce na tej stacji, w 185 tickach (~ 2,5 dnia) jednostkach
tinfo_flatwater(<Współrzędne> | REJESTRACJA, <blok>) Sprawdź, czy płytka jest płaska/pełna płytka wodna
tinfo_grfid(<Współrzędne> | REJESTRACJA, <blok>) Uzyskaj wysokość najniższego rogu płytki
tinfo_height([<Współrzędne> | ZAREJESTRUJ SIĘ,] <blok>) Sprawdź identyfikator grf kafelka stacji
tinfo_lclass(<Współrzędne> | REJESTRACJA, <blok>) Informacje o kafelku: klasa pozioma kafelka
tinfo_slope(<Współrzędne> | REJESTR, [<maska-przesunięcia>,] <blok>) Informacje o kafelku: nachylenie płytki
tinfo_statid(<Współrzędne> | REJESTR, [<maska-przesunięcia>,] <blok>) Informacje o kafelkach: identyfikator stacji i inne informacje
tinfo_terrain([<Współrzędna> | ZAREJESTRUJ SIĘ,] <blok>) Informacje o kafelku: typ terenu
tinfo_trackconnect([<maska-przesunięcia>,] <blok>) Informacje o kafelkach: sprawdzanie połączonych ścieżek
tinfo_trackexist([<maska-przesunięcia>,] <blok>) Informacje o kafelkach: sprawdzanie istniejących ścieżek
tinfo_tracktype(<blok>) Informacje o kafelku: sprawdź typ ścieżki
tinfo_water(<Współrzędne> | REJESTRACJA, <blok>) Sprawdź, czy kafelek jest kafelkiem wody/wybrzeża
tinfo_waterclass(<Współrzędne> | REJESTRACJA, <blok>) Zwraca "klasę" wody
Rok budowy(<blok>) Rok budowy stacji
random(<list::trigger>, <randombit> <list::ref()>) Uzyskaj losowe referencje
randomcb(<label>, <list::trigger>, <randombit>, <list::reference>)rerandom(<label>, <block>)
ponowna randomizacja w łańcuchach wywołań zwrotnych

Opis

Ta funkcja zwraca rzeczywistą wartość licznika animacji bieżącego kafelka, aby zdecydować, która klatka ma być wyświetlana. Wartość zwracana mieści się w przedziale od zera do liczby klatek animacji określonej we właściwości anim_info()) definicji stacji.

Jeśli podany jest dodatkowy parametr współrzędnych, zwracana jest rzeczywista wartość licznika animacji danego kafelka. Należy pamiętać, że współrzędne muszą być podane przez funkcję pomocniczą pos(<x>, <y>,). W przypadku REGISTER jako pierwszego parametru, współrzędna nie jest wyraźnie podana, ale przyjmuje się jako wynik poprzedniego obliczenia.

Ta funkcja zwraca bieżący wyzwalacz animacji podczas wywołania zwrotnego CB_ACONTROL.

Przykład (animacja stacji uchwytu):
def(8) anim_trigger(
	animcontrol(0, SND_HORN) if(BUILT) // start animation on construction
	ref(6) if(NEWCARGO)     // probably start of animation when cargo arrives 
	animcontrol(A_NOP) else // do nothing
)

def(9)callback( ref(8) if(CB_ACONTROL) // animation control ref(7) if(CB_AFRAME) // animation frames ref(1) else // graphics )


Ta funkcja sprawdza występowanie wywołania zwrotnego, a jeśli tak, zwraca typ wywołania zwrotnego. Zobacz przykład powyżej.

Ta funkcja zwraca 4-bitową wartość o historii danego typu ładunku, który został zaakceptowany na stacji w przeszłości:

Bit Wartość Opis
N/a 0 Ładunek nigdy nie był przyjmowany na tej stacji
0 1 Ładunek był kiedykolwiek przyjmowany na tej stacji
1 2 ładunek został przyjęty w zeszłym miesiącu
2 4 ładunek został przyjęty w tym miesiącu
3 8 ładunek został przyjęty od ostatniego okresowego przetwarzania (co 250 tyknięć)

Ta funkcja zwraca typ ładunku dla wyzwalaczy animacji NEWCARGO lub NOCARGO w ustawieniu.

Jeśli newGRF zainstalował tabelę przeliczenia ładunku, typ ładunku będzie indeksem do tej tabeli lub "255" (0xFF), jeśli ładunek nie jest uwzględniony w tabeli. Jeśli nie ma tabeli przeliczenia ładunku, typ ładunku będzie po prostu rodzajem ładunku zależnym od klimatu.

Ta funkcja zwraca liczbę miesięcy, w których wyłączne prawa transportowe, które zostały zakupione w okolicy, będą nadal obowiązywać. Jeśli jest różny od zera, stacja nie otrzyma żadnego ładunku.

Sygnalizacja oparta na trasie (PBS) to funkcja, która umożliwia wielu pociągom współdzielenie bloku sygnałowego, o ile ich trasy nie kolidują. To znacznie poprawia wejścia i wyjścia ze stacji, a także skrzyżowań.

Gdy pociąg zbliża się do skrzyżowania opartego na trasie, zarezerwuje przez nie trasę. Jeśli pożądana trasa innego pociągu przecina trasę tego pociągu, czeka on na sygnał, aby zarezerwować trasę przed wjazdem na skrzyżowanie.

Ta funkcja zwraca następującą wartość:

Wartość Etykieta Opis
7 111 PBSRESERVED Utwór zarezerwowany
4 100 PBSUNRESERVED Utwór bez rezerwacji
2 010 PBSNONE brak PBS

Bity są zdefiniowane w ten sposób, aby umożliwić łatwy powrót do przypadków innych niż PBS. Jeśli potrzebujesz grafiki do pokazania stanu "bez rezerwacji" w przypadkach innych niż PBS, użyj bitu 0, ale jeśli potrzebujesz stanu "zarezerwowany" w przypadkach innych niż PBS, użyj bitu 1. Aby jawnie sprawdzić, czy Usługa książek telefonicznych jest aktywna, użyj bitu 2.

Wszystkie inne bity są zarezerwowane i nie wolno ich używać.

W tej chwili włączanie / wyłączanie PBS odnosi się do ustawienia przełącznika, w przyszłej wersji alfa będzie faktycznie odnosić się do tego, czy przełącznik jest włączony, a bieżący blok faktycznie używa PBS.

Ten zestaw funkcji zwraca informacje o bieżącym kafelku, platformie, na której się znajduje i jak daleko na platformie. Współrzędne są zdefiniowane tak, jak pokazano na poniższym rysunku:

  • Funkcja plt_axis() zwraca kierunek bieżącego kafelka platformy ("0" dla kafelka w kierunku x lub "1" dla kierunku y
  • plt_edges() sprawdza położenie bieżącego kafelka wewnątrz stacji w odniesieniu do krawędzi stacji, patrz poniżej.
  • plt_even_length() zwraca wartość "0" przy parzystej długości platformy
  • plt_even_num() zwraca wartość "0" na parzystych numerach platform
  • Funkcja plt_even_numrev()
    zwraca wartość "0" na parzystych numerach peronów, zaczynając od najbardziej wysuniętej na południe krawędzi stacji
  • plt_even_pos() zwraca wartość "0" na parzystej pozycji na platformie
  • Funkcja plt_even_posrev() zwraca wartość "0" w pozycji parzystej na peronie, zaczynając od najbardziej wysuniętej na południe krawędzi stacji
  • plt_index() zwraca indeks (pozycja na peronie, numer peronu) do stacji, licząc od północnego narożnika (patrz lewy obrazek). Aby uzyskać dostęp do zwracanej wartości, należy użyć funkcji pomocniczej nibble(x,y)
  • Funkcja plt_indexrev() zwraca wartość indeksu zliczanego od południowego rogu (patrz prawy obrazek)
  • Funkcja plt_length() zwraca długość peronu (rozpoczyna liczenie od północy — patrz lewy obrazek)
  • Funkcja plt_midnum() zwraca liczbę aktualnie wylosowanych platform, zaczynając od środkowej
  • Funkcja plt_midpos() zwraca pozycję wzdłuż tej platformy, zaczynając od środka
  • Funkcja plt_num() zwraca aktualnie wylosowaną liczbę platform (patrz lewy obrazek)
  • Funkcja plt_numrev() zwraca liczbę aktualnie wylosowanych peronów, zaczynając od najbardziej wysuniętej na południe krawędzi stacji (patrz prawy rysunek)
  • Funkcja plt_pos() zwraca pozycję wzdłuż tej platformy (patrz lewy obrazek)
  • Funkcja plt_posrev() zwraca pozycję wzdłuż tego peronu, zaczynając od najbardziej wysuniętej na południe krawędzi stacji (patrz prawy rysunek)
  • Funkcja plt_size() zwraca rozmiar (numer peronu i długość peronu) całej stacji lub sekcji
  • plt_tiletype() zwraca typ kafelka TTD bieżącego kafelka platformy
  • Funkcja plt_total() zwraca łączną liczbę platform

W zależności od rodzaju stacji, powyższe funkcje uwzględniają różne sekcje danej stacji. W przypadku stacji regularnych oceniana jest cała stacja; a dla stacji nieregularnych liczona jest cała długość i wszystkie przyległe perony.

Termin "liczenie" odnosi się tutaj do rozpoczęcia od danego kafelka i liczenia płytek we wszystkich czterech kierunkach. Dwa kierunki wyrównane z kierunkiem stacji będą długością stacji, a pozostałe dwa kierunki podają liczbę peronów, patrz rysunek. Dla wszystkich powyższych funkcji liczenie zatrzymuje się na krawędzi stacji, tj. pierwszym kafelku niestacji.

Jak pokazano na powyższym rysunku, funkcje liczą się albo od najbardziej wysuniętej na północ krawędzi stacji, albo od jej najbardziej wysuniętej na południe krawędzi (plt_numrev(), plt_posrev()). Dla funkcji plt_midpos() i plt_midnum() ich format zwracany to pozycje liczone od środka, tj. środkowy kafelek ma "numer platformy" = 0 i "pozycja wzdłuż platformy" = 0. Dla parzystych długości i liczby peronów środkowa płytka znajduje się w pozycji długość/2 lub liczba peronów/2, np. dla długości = 6, jest to płytka 3 (tj. czwarta płytka). Liczenie preferuje dodatkową liczbę ujemną dla liczby parzystej (ponieważ dostępnych jest 8 liczb ujemnych, ale tylko 7 dodatnich):

Hrabia Liczby
1
          0
2
      -1  0
3
      -1  0  1
4
   -2 -1  0  1
5
   -2 -1  0  1  2
6
-3 -2 -1  0  1  2

Dostęp do liczb ujemnych uzyskuje się za pomocą funkcji aux signed() w funkcji if(). Zobacz przykład.

Aby odróżnić liczbę peronów od pozycji na peronach na całej stacji, lub tylko o odcinku kafelków stacji budowanych w połączeniu z bieżącym kafelkiem, m4nfo używa funkcji nawiasu self(). Zobacz przykład poniżej.

Niektóre z powyższych funkcji umożliwiają użycie funkcji shiftmask(). Ponieważ liczba i długość peronów stacji jest ograniczona do 15, parametr przesunięcia jest ograniczony do zakresu 0 .. 3, a parametr mask do zakresu 1 .. 15 (0x0F).

Przykład (sprawdź pozycję platformy i numery):
// single or multi tile?
def(6) plt_total(
	ref(24) if(1) // single
	ref(5) else   // not single
)

// position at platform def(7) plt_pos( ref(6) if(0) // edge back ref(3) else // edge front or middle )

// index of station tiles def(8) plt_index( self( cbr(2) if(nibble(0,0)) // x=0, y=0 cbr(4) if(nibble(0,1)) cbr(6) if(nibble(0,2)) cbr(8) if(nibble(1,0)) cbr(10) if(nibble(1,1)) cbr(12) else ) )

def(9) plt_midpos( self( ref(0x76) if(signed(-2)) ref(0xB0) if(signed(-1)) ref(0xB1) if(0) ref(0x7A) if(1) ref(0x79) else ) )


plt_edges() sprawdza położenie bieżącego kafelka wewnątrz stacji w odniesieniu do krawędzi stacji. Funkcja zwraca nibble z bitami ustawionymi dla każdej krawędzi stacji skojarzonej z bieżącym kafelkiem. Zliczanie bitów odbywa się zgodnie z ruchem wskazówek zegara, zaczynając od północno-wschodniej krawędzi, patrz rysunek:

Przykład (użycie plt_edges do lokalizowania kafelków stacji):
def(2) plt_edges(
	cbr(0) if(0)
	cbr(2) if(1)
	cbr(4) if(2)
	cbr(6) if(3)
	cbr(8) if(4)
	cbr(10) if(5)
	cbr(12) if(6)
	cbr(14) if(7)
	cbr(16) if(8)
	cbr(18) if(9)
	cbr(20) if(10)
	cbr(22) if(11)
	cbr(24) if(12)
	cbr(26) if(13)
	cbr(28) if(14)
	cbr(30) else
)

Ta funkcja zwraca typ(y) pojazdów, które odwiedziły tę stację w przeszłości, POCIĄG, AUTOBUS, CIĘŻARÓWKA, SAMOLOT, STATEK lub dowolna kombinacja:

Przykład (sprawdzić typy pojazdów po wizycie):
def(5) servicedbytype(
	ref(4) if(BUS + TRUCK) // service by rvs
	ref(3) else
)

Ta funkcja zwraca informacje o bieżącym typie duszka, tj. czy jest to duszek gruntu (GROUNDSPRITE), niestandardowy sprite fundamentu (FOUNDATION) czy duszek budynku (BUILDING). Aby to zadziałało, odpowiednie flagi muszą być ustawione w funkcji właściwości flags() stacji.

Przykład (sprawdź nachylenie budynku):
// ground sprite, foundation or building?
def(8) spritetype(
	ref(__groundsprites) if(GROUNDSPRITE) // ground sprite overlays
	ref(__foundations) if(FOUNDATION)     // custom foundations
	ref(__buildingsprites) else           // building sprites
)

def(9) callback( ref(7) if(CB_LAYOUT) ref(8) else )

Podczas korzystania z funkcji Advanced Sprite Layer oprogramowania OpenTTD dozwolony zakres wartości wynosi 0. 7.

Ta funkcja zwraca wiek stacji w latach od 1920 roku. Wynik jest zwracany jako WORD:

Przykład (sprawdź wiek stacji):
def(14) stationage(
	ref(2) if(<40)
	ref(4) if(41 .. 59)
	ref(6) if(60 .. 79)
	ref(10) else
)

Funkcje te zwracają informacje o poszczególnych budowanych sekcjach stacji podczas wywołania zwrotnego CB_TILETYPE. Ten sam format co funkcje plt_* powyżej, ale ponieważ funkcje te dotyczą tylko sekcji stacji, która nie została jeszcze zbudowana, nie byłoby potrzebne wywołanie self() dla "indywidualnie budowanych sekcji".

  • test_pos/posrev() zwraca położenie kafelków stacji do zbudowania, albo z kierunku NE na SW, albo odwrotnie
  • Funkcja test_num/liczba.rev() zwraca numer peronu kafelków stacji do zbudowania, z kierunku NW na SE lub odwrotnie
  • Funkcja test_length() zwraca długość peronów, które mają zostać zbudowane.
  • Funkcja test_total() zwraca łączną liczbę platform do zbudowania
  • Funkcja test_axis() zwraca kierunek kafelków platformy do zbudowania ("0" dla kierunku x lub "1" dla kierunku y
  • test_position() ocenia położenie płytki, która ma zostać zbudowana (numer platformy i pozycja na platformie)
  • Funkcja test_size() zwraca rozmiar (numer platformy i długość peronu) sekcji przeznaczonej do budowy
  • test_tiletype([<shiftmask>]) zwraca typ kafelka do zbudowania

Funkcje test_position() i test_size() wymagają funkcji pomocniczej nibble() w celu wyodrębnienia pojedynczych wartości zwracanych.

Przykład (kafelek uchwytu (0,0) jako kafelek nieścieżkowy):
definestation(
	...
	nontrack(TTD_ROOFBOTH) // TTD tile types 4/5 and 6/7
)

...

def(3) test_position( cbr(4) if(nibble(0,0)) // make tile x=0/y=0 non-track cbfail() else )

// menu def(13) callback( cbr(18) if(CB_LAYOUT) ref(3) if(CB_TILETYPE) ref(ALL_ICON) else )


Funkcje te umożliwiają dostęp do informacji o peronie podczas wywołania zwrotnego w CB_SLOPE, tj. przed zbudowaniem kafelka stacji. Wszystkie funkcje liczą numery peronów i długości od najbardziej wysuniętego na północ rogu stacji, jak pokazano tutaj.

  • test_pltlength() całkowita długość budowanej stacji
  • test_pltnum() aktualny numer platformy
  • test_pltpos() przesunięcie bieżącego kafelka na platformie
  • test_plttotal() całkowita liczba budowanych peronów

Tak jak powyżej, ale ta funkcja ocenia nachylenie płytki, która ma zostać zbudowana, w połączeniu z wywołaniem zwrotnym "kontroli nachylenia terenu" (CB_SLOPE). Zwrócone wartości nachylenia są takie same jak w tinfo_slope().

Przykład (stacja budowy na stokach):
def(45) test_slope(
	ref(44) if(NORTH+WEST, NORTH+EAST) // in x: back + front
	ref(44) if(SOUTH+WEST, SOUTH+EAST) // in y: back + front
	DISALLOW else
)

Ta funkcja zwraca wartość "32", jeśli płytka podana przez <współrzędna> jest płytką płaską/pełną wodą, w przeciwnym razie wartość nachylenia dla tego kafelka jest zwracana w dolnych 5 bitach.

Parametr współrzędnych określa przesunięcie względem bieżącego kafelka. Oba skubnięcia są uważane za podpisane. Przesunięcia ujemne przesuwają się odpowiednio na północ/zachód, dodatnie na południe/wschód. Parametr współrzędnych musi być określony przez funkcję pomocniczą pos(<x>, <y>,).

W przypadku REGISTER jako pierwszego parametru, współrzędne nie są jawnie podawane, ale brane jako wynik poprzedniego obliczenia, patrz calculate(). Oba wymagania wstępne dotyczą również funkcji tinfo_lclass(), tinfo_slope(), tinfo_statid(), tinfo_terrain(), tinfo_water() i tinfo_waterclass().

Ta funkcja zwraca identyfikator grf kafelka stacji podany przez <współrzędne> lub "0", jeśli stacja kafelka jest stacją domyślną, lub "0xFFFFFFFF", jeśli wybrany kafelek nie jest kafelkiem stacji.

Należy zauważyć, że wynik należy sprawdzić za pomocą funkcji pomocniczej label() w funkcji if(). Zobacz przykład.

Ta funkcja zwraca wysokość najniższego rogu płytki na danej współrzędnej. Jeśli parametr współrzędnych zostanie pominięty, zostanie przyjęty kafelek curent.

Ta funkcja zwraca klasę poziomą kafelka na podanej współrzędnej (s.a.):

Wartość Etykieta Opis
0 LC_TERRAIN goła ziemia, trawa, skały, pola
1 LC_RAIL tor kolejowy, z sygnalizacją i bez sygnalizacji, ogrodzenia
2 LC_ROAD drogi, przejazdy kolejowe, zajezdnie
3 LC_HOUSE budynki miejskie
4 LC_TREES drzewa zależne od klimatu
5 LC_STATIONTILE dworzec kolejowy, lotnisko, dworzec samochodowy i autobusowy, dok dla statków
6 LC_WATER woda, wybrzeże, brzeg rzeki, magazyn statków
7 LC_VOID Niewidoczne obramowanie u dolnych krawędzi mapy
8 LC_INDUSTRYTILE Typy płytek branżowych
9 LC_TUNNELBRIDGE tunel kolejowy lub drogowy, most
10 LC_OBJECT nadajnik, latarnia morska, posąg, teren należący do firmy, siedziba główna

Ta funkcja zwraca informacje o nachyleniu wypełnionym bajtami dla kafelka danej stacji. Podana informacja jest w odniesieniu do najniższego rogu płytki, tj. ZACHÓD oznacza, że zachodni narożnik znajduje się powyżej najniższego rogu itp.

Ten rysunek ilustruje, jaki rodzaj nachylenia należy do których podniesionych narożników:

Równie dobrze możesz sprawdzić tak zwane "strome zbocza" (tj. narożnik przeciwny do najniższego jest o dwie jednostki wyższy), używając wartości STEEP wraz z dowolnymi trzema innymi narożnikami, ale pamiętaj, że stacje nie mogą być umieszczone na stromym zboczu.

Dodatkowy parametr <shift-mask> może zostać zastosowany w celu dalszego udoskonalenia wyniku funkcji. Aby to zadziałało, pierwszy parametr funkcji shiftmask() (parametr <shift>) musi być ustawiony na zero (0), tj. w ogóle nie ma przesunięcia. Parametr <mask> powinien być ustawiony na rozsądną wartość, w zależności od celu, jaki ma zostać osiągnięty za pomocą maskowania wyników.

Przykład (sprawdź nachylenie kafelka stacji):
def(11) tinfo_slope(pos(0,0), shiftmask(0, NORTH+WEST+SOUTH+EAST),
	cbr(10) if(0)	// flat: ticket machine left
	cbr(12) if(NORTH+WEST, NORTH+WEST+EAST, NORTH+WEST+SOUTH) // ticket machine left
	cbr(10) if(SOUTH+EAST, SOUTH+EAST+WEST, SOUTH+EAST+NORTH) // fence left
	cbr(40) else	// fence left and right
)

W tym przykładzie zbocza do sprawdzenia są ograniczone do dowolnej kombinacji PÓŁNOC, ZACHÓD, POŁUDNIE i WSCHÓD, tj. STROME zbocza zostaną automatycznie wykluczone z gałęzi "inne".

Ta funkcja zwraca identyfikator stacji na danej współrzędnej kafelka w stosunku do bieżącego kafelka stacji w jej dolnym Bajtie. Ponadto zwraca dodatkowe informacje w swoim wysokim Byte (s.a.):

Bit Wartość Znaczenie
0 .. 1 0x100 / 0x200 _THISGRF / _OTHERGRF Członkostwo w kafelkach (0: oryginalny TTD, 1: zdefiniowany w bieżącym newGRF, 2: zdefiniowany w obcym newGRF)
2 0x400 _THISSTAT Kafelek należy do bieżącej stacji, jeśli jest ustawiony bit
3 0x800 _PROSTOPADŁY Kafelek jest równoległy (bit clear) lub prostopadły (bit set) do bieżącego
4 .. 5 0x1000 / 0x2000 / 0x3000 _TILETYPE2 / _TILETYPE4 / _TILETYPE6 Informacje o peronie typu TTD (0: platforma gładka; 1: platforma z budynkiem; 2: platforma z dachem, lewa strona; 3: platforma z dachem, prawa strona)
6 .. 7   Zarezerwowane, nie używaj

Należy użyć pomocniczej funkcji shiftmask(), aby uzyskać dostęp do potrzebnych bitów. Np. sprawdzając ID kafelka, należy zawsze sprawdzić, czy został on zdefiniowany w bieżącym newGRF, stąd trzeba by sprawdzić nie tylko sam identyfikator, ale także wartość _THISGRF + ID. Jeśli chcesz sprawdzić zagraniczny nowy GRF, powinieneś użyć _OTHERGRF + ID.

Jeśli kafelek w ogóle nie jest kafelkiem stacji, zwracana wartość będzie 0xFFFF, tj. wszystkie bity ustawione.

Należy pamiętać, że pierwszy parametr tej funkcji musi być określony przez funkcję pomocniczą pos(<x>, <y>)

Przykład (sprawdź płytki "dachowe" stacji):
define(ROOFS,0x0E)

def(1) tinfo_statid(pos(0,-1), shiftmask(0,_THISGRF+ROOFS), cbr(1) if(_THISGRF+ROOFS) // station-ID is 0x0E cbr(2) if(0xFFFF) // not station cbr(0) else // other station-ID )

Czasami konieczne jest również sprawdzenie "typu kafelka" kafelka stacji (ponieważ identyfikatory mogą być takie same). Można to również zrobić:

Przykład (sprawdź również typy kafelków stacji):
define(_THISGRF_TT, 0x3100) // mask "tiletype" and "defined in this GRF"

def(17) tinfo_statid(pos(1,0), shiftmask(0,_THISGRF_TT+0xFF), cbr(2) if(0x2100+PTRACK_OPASS) // tiletype for overpass is "4" (2) cbr(6) if(0x3100+PTRACK_OPASS) // tiletype for overpass is "6" (3) cbfail() else )

Ta funkcja zwraca typ terenu dla bieżącego kafelka stacji (s.a.). Zwracane wartości to NORMAL, DESERT, RAINFOREST i SNOW (na lub powyżej linii śniegu).

Jeśli podany jest dodatkowy parametr współrzędnych, zwracany jest typ terenu danego kafelka. Należy pamiętać, że współrzędne muszą być podane przez funkcję pomocniczą pos(<x>, <y>,)

Ta funkcja zwraca informacje kodowane bitowo, czy tory kolejowe są kontynuowane na ośmiu kafelkach sąsiadujących z kafelkiem stacji.

Bit Wartość Ustaw, jeśli szyna biegnie dalej w kierunku:
0 0x01 +Długość
1 0x02 -Długość
2 0x04 +Platformy
3 0x08 -Platformy
4 0x10 +Długość, +Platformy
5 0x20 -Długość, +Platformy
6 0x40 +Długość, -Platformy
7 0x80 -Długość, -Platformy

Na poniższej ilustracji pokazano, które bity reprezentują kafelek dla dwóch możliwych orientacji stacji:

Bity od 0 do 3 są ustawiane, jeśli na danym kafelku znajduje się ścieżka i ma ona połączenie z kafelkiem stacji. Dla bitów 2, 3 stacja oczywiście nie ma połączenia z tymi płytkami, ale nie ma to znaczenia dla tej zmiennej. Bity od 4 do 7 sprawdzają połączenia z sąsiednim kafelkiem platformy, tj. bity 4 i 5 lub 6 i 7 wskazują połączenie z tego kafelka z kafelkiem 2 lub 3.

Dodatkowy parametr <shift-mask> może zostać zastosowany w celu dalszego udoskonalenia bitów wynikowych funkcji. Aby to zadziałało, pierwszy parametr funkcji shiftmask() (parametr <shift>) musi być ustawiony na zero (0), tj. w ogóle nie ma przesunięcia. Parametr <mask> powinien być ustawiony na rozsądną wartość, w zależności od celu, jaki ma zostać osiągnięty za pomocą maskowania bitów.

Przykład (określenie kierunku bufora):
def(24) tinfo_trackconnect(
	ref(21) if(1)   // top
	ref(22) if(2)   // bottom
	ref(25) if(4,8) // sideways - only on (false) slope
	ref(23) else    // double buffer
)

Ta funkcja zwraca bitowo zakodowaną informację, czy na kafelku znajdują się tory szynowe, i pomija to, czy tor jest podłączony do stacji, czy nie całkowicie. Wyniki kodowane bitowo są obsługiwane w taki sam sposób, jak w przypadku tinfo_trackconnect().

Ta funkcja zwraca typ toru kolejowego, gdzie 0 = szyna regularna, 1 = szyna zelektryfikowana, 2 = szyna jednoszynowa, 3 = maglev i każda dodatkowa szyna zgodnie z numerem szczeliny.

Ta funkcja zwraca wartość "1", jeśli kafelek podany przez <współrzędna> jest kafelkiem pełnej wody lub wybrzeża, w przeciwnym razie zwracana jest wartość "0". Ponownie, parametr współrzędnych musi być określony przez funkcję pomocniczą pos(<x>, <y>,)

Przykład (sprawdź wodę w pobliżu stacji):
def(47) tinfo_water(pos(-1,0), // back
	ref(2) if(1)           // is water
	ref(46) else
)

Ta funkcja zwraca "klasę wody" płytki podaną przez <współrzędne>. Wartości klasy wody są następujące:

Wartość Znaczenie
0 WC_LAND Nieokreślony / ląd
1 WC_SEA Morze, ocean
2 WC_CANAL Kanał
3 WC_RIVER Rzeka

W przeciwieństwie do klasy krajobrazu "woda", "klasa wodna" nie zmienia się, gdy dachówka wodna jest zabudowana, np. przez obiekt przedstawiający statek. Użycie tinfo_waterclass() może się w tym przypadku przydać.

Ponownie, parametr współrzędnych musi być określony przez funkcję pomocniczą pos(<x>, <y>)

Ta funkcja zwraca rok budowy stacji. Rokiem bazowym jest 1920.

Przykład (sprawdź lata budowy punktów trasy):
def(4) yearbuilt(
	cbr(2) if(<1940)
	cbr(4) if(1940 .. 1959)
	cbr(6) if(1960 .. 1979)
	cbr(8) if(1980 .. 1999)
	cbr(10) else
)

W przeciwieństwie do powyższych funkcji wydajnościowych, których wyniki są zawsze określane przez przewidywalną decyzję, można również użyć funkcji losowych, aby wybrać jeden z kilku zestawów graficznych lub wyników wywołania zwrotnego.

Opis

<list::trigger>

Spust Znaczenie
ZBUDOWANY po skonstruowaniu (bez wyzwalacza)
NEWCARGO nowy ładunek czeka
NOCARGO Koniec z ładunkiem
PRZYBYĆ przyjeżdża pociąg (rozpoczyna rozładunek/załadunek)
OPUSZCZAĆ odjazdy pociągów (rozładunek i załadunek)
ŁADOWANIA pociąg ładuje lub rozładowuje ładunek
Rezerwa PBSP peron rezerw pociągów (przy użyciu PBS)
WSZYSTKIE WYZWALACZE Ponownie randomizuj tylko wtedy, gdy wystąpiły wszystkie wyzwalacze

Należy również zauważyć, że żaden z powyższych wyzwalaczy nie zostanie faktycznie wywołany, chyba że funkcja właściwości setcargotriggers() ma co najmniej jeden zestaw wyzwalaczy. NEWCARGO zostanie uruchomiony dla dowolnego typu ładunku ustawionego w setcargotriggers(), ale NOCARGO zostanie uruchomiony tylko wtedy, gdy wszystkie te typy ładunków nie będą już oczekiwać. Wyzwalacze ARRIVE, LEAVE i PBSRESERVE są uruchamiane bez względu na rodzaj ładunku przewożonego przez pociąg, o ile ustawiono co najmniej jeden wyzwalacz.

Wyzwalacze ARRIVE, LEAVE, LOADING i PBSRESERVE wpływają tylko na peron, na którym występują, a także na losowe bity stacji, ale nie na inne perony.

Ponieważ już zaistniałe wyzwalacze są przechowywane tylko raz na stację (bez rozróżniania płytek lub typów ładunków), dodawanie ALLTRIGGERS do losowych wyzwalaczy nie ma większego sensu dla stacji.

<bitowy>

Stacje mają 16 losowych bitów (bity 0 .. 15) wspólnych dla całej stacji i 4 losowe bity (bity 16 .. 19) na kafelek stacji. TTDPatch faktycznie implementuje tylko 8 współdzielonych losowych bitów, tj. bity 8 .. 15 to zawsze zero.

Ustawienie randombit określa pierwszy bit do ponownego losowania, a także opiera losową grafikę. Tylko te bity, które faktycznie zostaną uruchomione, zostaną ponownie losowe. Umożliwi to posiadanie niezależnych zestawów bitów dla niezależnych wyzwalaczy. Całkowita liczba użytych bitów jest 2-logarytmem liczby użytych odwołań, np. dla 16 odwołań używane są 4 bity.

Aby uzyskać losowość opartą na kafelkach, należy użyć randombit = 16 i liczby odwołań nie większej niż 16 (ponieważ tylko 4 losowe bity są dostępne na płytkę).

<list::reference>

Liczba zbiorów do wyboru musi wynosić 2, tj. 2, 4, 8, 16 itd.

Przykład (4 różne stany ładunku):
def(13) random(ARRIVE,16,ref(1),ref(2),ref(2),ref(3))

def(13) random({ARRIVE, LEAVE},16,ref(1),ref(2),ref(2),ref(3))


ponowna randomizacja

Należy pamiętać, że ponowna randomizacja, zarówno w TTDPatch, jak i w OpenTTD, odbywa się tylko w łańcuchu graficznym, ale nie w przypadku wywołań zwrotnych. Oznacza to, że jeśli losowa akcja jest używana wewnątrz łańcucha wywołań zwrotnych i powinna ponownie randomizować bity wyzwalające, należy również dodać "fikcyjną" losową akcję do łańcucha graficznego, wyłącznie w celu ponownego losowania bitów.

Dlatego też, aby używać funkcji losowych w łańcuchach wywołań zwrotnych, m4nfo dostarcza dwie specjalne funkcje:

randomcb(<label>, <list::trigger>, <randombit>, <list::reference>)

Ta funkcja jest używana w łańcuchach wywołań zwrotnych, podobnie jak normalna funkcja random() jest używana w łańcuchu graficznym, z tym wyjątkiem, że nigdy nie losowo losuje określonych wyzwalaczy. Zamiast tego odbywa się to za pomocą funkcji

rerandom(<label>, <block>)

który musi być umieszczony w łańcuchu graficznym. Określając różne etykiety, można równolegle stosować różne randomizacje. Zobacz przykład.

Przykład (2 różne ponowne randomizacje):
// top platform
def(6) randomcb(_TOP, ARRIVE, 16, ref(1), ref(2), ref(2), ref(3))

// bottom platform def(7) randomcb(_BOTTOM, {ARRIVE, NOCARGO}, 16, ref(1), ref(2))

def(8) plt_num( self( ref(6) if(0) // top platform ref(7) else // bottom ) )

[...]

def(9) rerandom(_TOP, ref(0) // graphics )

def(10) rerandom(_BOTTOM, ref(0) // graphics )

def(11) plt_num( self( ref(9) if(0) // top platform ref(10) else // bottom ) )

// check callbacks def(12) callback( ref(8) if(CB_LAYOUT) // callback ref(11) else // graphics/re-randomisation )


Funkcje pomocnicze są używane w kontekście niektórych z powyższych funkcji. W związku z tym nie otrzymują def() ani ref() niczego innego. Są one używane głównie do oceny specjalnych parametrów funkcji wydajności.

Ta funkcja dostosowuje wynik funkcji wydajności do bardziej użytecznego zakresu. Pierwszy parametr definiuje wartość, którą należy dodać do wyniku, a drugi parametr określa modulo (pozostałą część dzielenia przez) na sumie wyniku funkcji wydajności i pierwszego parametru.

Przykład (sprawdzanie numeru peronu):
def(10) plt_midnum(addmodulo(1,2),
    self(
	ref(5) if(1)
	ref(6) else
    )
)   

Ta funkcja służy do sprawdzania zwróconej wartości współrzędnych wypełnionych bajtami w zwykłej postaci (<x>, <y>). Zakres parametrów wynosi [-8 ... +7], zarówno dla przesunięć x, jak i y. Przykład można znaleźć tutaj.

Ta funkcja dostarcza podane współrzędne w postaci wypełnionej bajtami do innej funkcji. Zakres parametrów wynosi [-8 ... +7], zarówno dla współrzędnych x, jak i y. Należy pamiętać, że współrzędna (0,0) odnosi się do bieżącego kafelka. Przykład znajduje się poniżej.

Ta funkcja definiuje poziom hierarchii. Zamiast całej stacji, tylko sekcja kafelków stacji budowanych w powiązaniu z bieżącym kafelkiem jest adresowana przez odpowiednią funkcję wydajności, patrz tutaj dla przykładów.

Ta funkcja dostosowuje wynik funkcji wydajności do bardziej użytecznego zakresu. Pierwszy parametr definiuje wartość do przesunięcia w prawo wyniku, a drugi parametr podaje wartość, z którą AND wynik po przesunięciu.

Należy pamiętać, że parametr <maska> może mieć rozmiar WORD w danym kontekście.

Przykład (sprawdzanie własnego nachylenia płytki):
//  (middle)
def(8) tinfo_slope(pos(0,0),shiftmask(0,NORTH+SOUTH),
	ref(5) if(NORTH)
	ref(6) if(SOUTH)
	ref(7) else
)   

Clone this wiki locally