Prezentuję długo oczekiwane na polskiej scenie OMSI objaśnienia dotyczące skryptów w symulatorze. System skryptowy został opisany na bazie informacji od Autorów gry, własnych doświadczeń oraz poparty unikalnymi przykładami.
Poradnik z pewnością będzie udoskonalany i uzupełniany o kolejne fragmenty. Jako główny Autor dołożyłem wszelkich starań, żeby jego treść była rzetelna i jednocześnie łatwo przystępna. W opracowaniu pomagał mi Ekspert Strefy-OMSI
kacper_IK160P. Jeśli zauważyłeś błąd, nieścisłość lub masz pomysły o co uzupełnić poradnik (a co nie zostało w międzyczasie wymienione, że będzie dołączone) - napisz do mnie Prywatną Wiadomość w tej sprawie.
Dla użytkowników niezarejestrowanych dostępny jest tylko pierwszy rozdział, ot, taka wersja demo
Pliki systemu skryptowego
- Pliki *.osc - zawierają właściwy kod wykonywalny skryptów;
- Pliki Varlist i Stringvarlist w katalogu OMSI\program - definiują ogólne zmienne systemu skryptowego;
- Pliki Varlist i Stringvarlist w katalogach dodatków - definiują zmienne użytkownika (mówiąc jaśniej - zmienne dodatku);
- Pliki Constfile - definiują stałe użytkownika i ewentualnie tabele prawd.
To jednak nie wszystko. Aby dany plik był "podpięty" do modelu lub innego dodatku, jego wpis musi być obecny w odpowiednim pliku konfiguracyjnym. Dla pojazdów będzie to *.bus (przykład poniżej):
Kod:
////////////////////////////////////////////////////////
Scripts
////////////////////////////////////////////////////////
[varnamelist]
23
script\AI_varlist.txt
script\Collision_varlist.txt
script\antrieb_varlist.txt
script\engine_varlist.txt
script\elec_varlist.txt
script\bremse_varlist.txt
script\auspuff_varlist.txt
script\lights_varlist.txt
script\door_varlist.txt
script\wiper1_varlist.txt
script\cockpit_varlist.txt
script\klappern_varlist.txt
script\rollband_varlist.txt
script\heizung_varlist.txt
script\rain_varlist.txt
script\dirt_varlist.txt
script\IBIS_varlist.txt
script\Matrix_varlist.txt
script\wimpel_varlist.txt
script\visual_varlist.txt
script\cashdesk_varlist.txt
script\ticketprinter_varlist.txt
script\wiper2_varlist.txt
[stringvarnamelist]
4
script\IBIS_stringvarlist.txt
script\Matrix_stringvarlist.txt
script\ticketprinter_stringvarlist.txt
script\cockpit_stringvarlist.txt
[script]
24
script\man_D92_main.osc
script\man_D86_main_AI.osc
script\collision.osc
script\cockpit.osc
script\antrieb.osc
script\engine.osc
script\elec.osc
script\bremse.osc
script\auspuff.osc
script\lights.osc
script\doordar.osc
script\wiper1.osc
script\klappern.osc
script\forcefeedback.osc
script\rain.osc
script\dirt.osc
script\sound_volume.osc
script\heizung.osc
script\IBIS.osc
script\matrix_D.osc
script\wimpel.osc
script\cashdesk.osc
script\ticketprinter.osc
script\wiper2.osc
[constfile]
19
script\AI_constfile.txt
script\collision_constfile.txt
script\antrieb_constfile_D86.txt
script\engine_constfile_D86.txt
script\elec_constfile.txt
script\bremse_constfile_D86.txt
script\lights_constfile.txt
script\door_constfile_D92.txt
script\auspuff_constfile.txt
script\cockpit_constfile.txt
script\klappern_constfile.txt
script\rollband_constfile.txt
script\forcefeedback_constfile.txt
script\wiper1_constfile.txt
script\dirt_constfile.txt
script\heizung_constfile.txt
script\IBIS_constfile.txt
script\matrix_constfile.txt
script\wiper2_constfile.txt
a np. dla dodatków w postaci scenerii: *.sco:
Kod:
[stringvarnamelist]
1
script\busstopdisplay_stringvarlist.txt
[varnamelist]
1
script\busstopdisplay_varlist.txt
[script]
1
script\busstopdisplay.osc
Łatwo na powyższych przykładach zauważyć, że słowa kluczowe wywołujące deklarację danego pliku to odpowiednio:
[script] - dla *.osc;
[varnamelist] i
[stringvarnamelist] - dla zmiennych
[constfile] - dla stałych
Cyfra po tychże słowach kluczowych to po prostu liczba wpisów.
Podstawy języka skryptowego
Język skryptowy OMSI korzysta z odwrotnej notacji polskiej zwaną czasami notacją postfiksową. Oznacza ona, że operator dotyczący dwóch argumentów stoi za nimi. Prosty przykład arytmetyczny "1+2" w systemie tym powinno zapisać się jako "1 2 +", natomiast wyrażenie "(1 + 2) * (4 + 5)" jako " 1 2 + 4 5 + * ". Ekstremalny przykład: (((a+3)^2-(4+d))/5)*((((a+1)*d))/(e+6)) to w tej notacji: " a 3 + 2 ^ 4 d + 5 / - a 1 + d * e 6 + / * ". Z takimi w OMSI raczej nie będziecie mieli do czynienia, ale w ramach opanowania notacji odsyłam do Google, najprostsza metoda to rozrysowanie drzewka przykładu.
Bardzo ważny jest fakt, że w skryptach i innych plikach tekstowych rozróżniana jest wielkość liter.
Stos i rejestry
Podczas przetwarzania skryptu, OMSI tworzy stos łańcuchowy oraz stos dla liczb zmiennoprzecinkowych. Umówmy się, że "stos" zawsze dotyczy liczb zmiennoprzecinkowych, w przeciwnym razie używany będzie zwrot "stos łańcuchowy". Obydwa stosy zawierają 8 komórek ponumerowanych od 0 do 7. Każda operacja skryptowa może odłożyć jedną bądź większą liczbę wartości na stos (funkcja push), przy czym aktualnie odkładana wartość zawsze przybiera pozycję "0". Poprzednie przenoszą się "wyżej", czyli na kolejne pozycje lub mogą być ściągnięte ze stosu (funkcja pop/pull) albo podejrzane (funkcja peek) - dla sprecyzowania pop/pull i peek dotyczy elementu znajdującego się aktualnie na szczycie stosu.
Tymczasowe przechowywanie liczb realizuje osiem dodatkowych komórek pamięci. Wartości w nich mogą być odczytane lub zapisane bezpośrednio. Znajdują się one w tzw. rejestrze - dla liczb zmiennoprzecinkowych istnieje tylko jeden.
Przykład:
Działanie 1+4, w odwrotnej notacji polskiej: 1 4 +
Tabela pokazuje zachowanie się stosu dla powyższego działania:
Kod:
Operacja
Komórka stosu: 0 1 2 3 4 ...
---------------------------------------------------
przed: 0 0 0 0 0
"1" 1 0 0 0 0
"4" 4 1 0 0 0
"+" 5 0 0 0 0
Wnioskujemy zatem, że w początkowo stos jest "wyzerowany" lub ewentualnie wypełniony jest przypadkowymi wartościami. Pierwsze polecenie "1" odkłada jedynkę w zerowej komórce i niejako "popycha" zera w prawo. Komenda "4" popycha odkłada czwórkę w zerowej i "popycha" pozostałe wartości. Operacja "+" ściąga obydwie wartości ze stosu, sumuje i umieszcza wartość wynikową "5" w komórce zerowej. Wartości "1" i "4" nie będą od tej chwili dostępne.
Drugi przykład:
Działanie (1 + 2) * (4 + 5), w odwrotnej notacji polskiej: 1 2 + 4 5 + *
Stos zachowuje się w następujący sposób:
Kod:
Operacja
Komórka stosu: 0 1 2 3 4 ...
----------------------------------------------------
przed: 0 0 0 0 0
"1" 1 0 0 0 0
"2" 2 1 0 0 0
"+" 3 0 0 0 0
"4" 4 3 0 0 0
"5" 5 4 3 0 0
"+" 9 3 0 0 0
"*" 27 0 0 0 0
Zauważ, że po wykonaniu działania, poprawna wartość zachowywana jest w komórce zerowej.
Liczby zmiennoprzecinkowe i łańcuchy
System skryptowy OMSI działa wyłącznie na liczbach zmiennoprzecinkowych (pojedynczej precyzji ze znakiem) i łańcuchach. Z tego też powodu przetwarzanie liczb i łańcuchów odbywa się właściwie niezależnie. Oczywistym jest jednak, że niektóre operacje (przykładowo konwersja liczb na łańcuchy) powinny mieć dostęp do obydwu wcześniej wymienionych stosów.
Słowa kluczowe w skryptach
Komentarze
Komentarze w kodzie można uzyskać poprzez użycie znaku apostrofu na początku danej linijki:
Kod:
'To jest komentarz
' To także jest komentarz
'Ale to już nie jest komentarz, gdyż apostrof nie znajduje się na początku linijki!
Punkty wejścia/wyjścia, makra i wyzwalacze
Wszystkie polecenia muszą znajdować się pomiędzy wywołaniem komendy wejścia a wywołaniem komendy wyjścia.
Punkty wejścia są oznaczane poprzez:
- {frame} - po dotarciu do każdej "ramki", OMSI wykonuje polecenia w niej zawarte "krok po kroku", o ile takowe się tam znajdują;
- {init} - OMSI wywołuje taki punkt wejścia już podczas inicjalizacji skryptu (czyli na samym początku jego wykonywania);
- {frame_ai} - typ standardowej "ramki" używanej w przypadku pojazdów, które nie są szczególnie ważne podczas rozgrywki, np kierowane przez AI autobusy lub auta. Taki punkt wejścia jest używany wyłącznie jako alternatywa zwykłej "ramki". Dla obiektów scenerii nie ma on zastosowania.
- {macro:nazwa} - ten punkt definiuje makro, czyli właściwy opis działania skryptu, definicja musi stać za wszystkimi wywołaniami
- {trigger:nazwa} - ten punkt wejścia odpowiedzialny jest za skróty klawiszowe lub zdarzenia myszy (mouseventy) wywoływane przez gracza poprzez etykietę nazwa. Istnieją także wyzwalacze obsługiwane bezpośrednio przez OMSI, np. zmiana wyświetlaczy w autobusach AI
{end} jest uniwersalnym punktem wyjścia. Zawsze musi kończyć blok rozpoczęty jednym z wcześniej wymienionych wejść.
Wywołanie makra
Makro można wywołać poprzez polecenie:
(M.L.nazwa_makra)
Wywołanie makra musi koniecznie znajdować się przed jego definicją. W przeciwnym wypadku OMSI po prostu go nie znajdzie i w trakcie ładowania danego skryptu pojawi się błąd.
Podział skryptów na pliki
Dla prostych skryptów (np. dotyczących pojazdów AI lub obiektów scenerii) wystarczy na ogół utworzyć pojedynczy plik złożony z odpowiednich bloków
{frame}...{end} i
{init}...{end}.
Jeśli jednak budujemy złożony skrypt dla pojazdu, to wskazany jest jego podział ze względu na pełnioną przezeń funkcję. Należy trzymać się zasad:
- Istnieje główny plik skryptowy (oznaczany zwykle jako nazwa_autobusu_main.osc) i zestawy pobocznych plików skryptowych (zestaw taki dalej będzie nazywany "podsystemem"). Skrypt główny zawiera bloki {frame} oraz {init}, które z kolei zawierają wywołania makr zdefiniowanych w skryptach pobocznych.
- Dla każdego "podsystemu" istnieje plik *.sco oraz w zależności od potrzeb pliki zawierające stałe (Constfile) lub deklarujące zmienne (Varlist i Stringvarlist). Dzięki temu wyzwalacze dla rozkazów z klawiatury są także uporządkowane.
- Makra powinny być nazwane w następujący sposób:
{macro:podsystem_frame} i {macro:podsystem_init}
W miejscu "podsystem" powinna znaleźć się nazwa podsystemu np. "cockpit" lub "engine".
- Z powyższych warunków dotyczących makr wynika, że aby zachować odpowiednią kolejność wywołanie-definicja makra, w pliku konfiguracyjnym modelu (chodzi o plik *.bus) główny plik skryptowy (gdzie znajdują się wywołania) musi być zadeklarowany przed pozostałymi (gdzie są dopiero definicje wywołanych makr). Kolejność zawsze musi być tak dobrana, by wywołanie następowało przed definicją.
Takie rozwiązanie wywołań i deklaracji makr może być uciążliwe, jednak zwykle zapobiega wykonywaniu nieskończonych pętli przez system skryptowy.
Wyzwalacze
Zgodnie z wcześniejszymi poradami blok
{trigger:name}...{end} może być różnie obsługiwany przez grę. Przykłady:
- Wyzwalanie przez klawiaturę - naciśnięcie klawisza lub kombinacji klawiszy nazwanej:
skrot_usera
wywoła:
Kod:
{trigger:skrot_usera}
a gdy klawisze zostaną zwolnione, wywołany zostanie wyzwalacz:
Kod:
{trigger:skrot_usera_off}
- Wyzwalane przez mysz - jeśli dany element jest kliknięty i w pliku modelowym (*.cfg) znajduje się wpis:
Kod:
[mouseevent]
funkcja_myszy
to po kliknięciu zostanie wywołany wyzwalacz:
Kod:
{trigger:funkcja_myszy}
podczas przytrzymywania przycisku myszy:
Kod:
{trigger:funkcja_myszy_drag}
a po zwolnieniu przycisku:
Kod:
{trigger:funkcja_myszy_off}
Oprócz powyższych warto wspomnieć o wyzwalaczach systemowych. Są to takie wyzwalacze, które nie następują po danym działaniu użytkownika, lecz są uruchamiane automatycznie przez OMSI w odpowiednich warunkach. Poniżej znajduje się ich lista:
- collision - jest wyzwalany podczas każdej kolizji, aby z niego skorzystać, przed pożądaną zmienną trzeba dodać przedrostek coll_ (np. coll_pekajacaszyba);
- int_haltewunsch - żądanie zatrzymania na następnym przystanku, wyzwalacz łączy zachowanie pasażerów ze skryptami autobusów, zwykle następuje wiele "przyciśnięć" STOP-u przed przystankiem lub ewentualnie podczas przedwczesnego zamknięcia drzwi;
- railbond_# - wyzwalacz wspólnych dźwięków pojazdów szynowych;
- ai_scheduled_settarget - żądanie skryptu ustawienia linii i kierunku dla pojazdów AI, skrypt ustawienia linii realizuje się poprzez poprzez zmienną pojazdu SetLineTo, a kierunku poprzez AI_target_index;
- ai_scheduled_setbusstop - żądanie skryptu aktualnego przystanku np. dla wyświetlaczy wewnętrznych, tutaj również korzysta się z odpowiedniej zmiennej pojazdu;
- malfunction_gettime - (od OMSI 2) żądanie wyliczenia czasu wymaganych napraw, wartość jest wrzucana na szczyt stosu;
- malfunction_reset - (od OMSI 2) wymuszenie wykonania wszelkich napraw.
Operacje i operatory
Operacje związane ze stosami
- %stackdump% - wyświetla okno dialogowe z zawartością stosu zawierającego liczby zmiennoprzecinkowe, polecenie używane wyłącznie do debugowania;
- s0, s1, ..., s7 - zapisuje w określonej przez cyfrę komórce rejestru aktualną wartość stosu, wartość pozostaje także w stosie;
- l0, l1, ..., l7 - ładuje wartość ze wskazanej komórki rejestru i odkłada ją na stosie, pozostaje również w rejestrze;
- d - powiela wartość z wierzchołka stosu, obecne wartości wędrują o pozycję niżej każda;
- $msg - zapisuje wierzchołkowy łańcuch stosu łańcuchowego w linii debugowania OMSI;
- $d - operacja analogiczna do d, ale przeprowadzana na stosie łańcuchowym.
Operatory logiczne
Działają na zasadzie: 0 = FAŁSZ, każda inna liczba = PRAWDA.
- && - działa jak "i" (inaczej: koniunkcja, bramka AND), jeśli co najmniej jedna z dwóch szczytowych wartości stosu wynosi 0 - wynik również wynosi "0", w przeciwnym wypadku (a więc gdy obydwie wartości są prawdziwe) "1";
- || - działa jak "lub" (inaczej: alternatywa, bramka OR), jeśli dwie szczytowe wartości wynoszą "0" - wynik również wynosi 0, w przeciwnym wypadku wynikiem jest prawda ("1");
- ! - działa jak "nie" (inaczej: negacja, bramka NOT), neguje, czyli zmienia wartość logiczną na przeciwną.
Operatory porównania
Operatory porównania, jak sama nazwa wskazuje, porównują dwie szczytowe wartości stosu, a następnie, w zależności od wyniku, dodają do szczytowej wartości "0" lub "1". Operatory porównania operują zgodnie z zasadami przedstawionymi wcześniej, czyli:
4 2 > jest prawdą ("1"), gdyż zostało wykonane porównanie
4>2
- = - daje wartość równą "1", gdy szczytowe wartości stosu są identyczne, w przeciwnym przypadku - "0";
- < - daje wartość równą "1", gdy druga wartość stosu (z pozycji pierwszej) jest mniejsza od szczytowej (z pozycji zerowej), w przeciwnym przypadku - "0";
- > - daje wartość równą "1", gdy druga wartość stosu (z pozycji pierwszej) jest większa od szczytowej (z pozycji zerowej), w przeciwnym przypadku - "0";
- <= - daje wartość równą "1", gdy druga wartość stosu (z pozycji pierwszej) jest większa lub równa szczytowej (z pozycji zerowej), w przeciwnym przypadku - "0";
- >= - daje wartość równą "1", gdy druga wartość stosu (z pozycji pierwszej) jest mniejsza lub równa szczytowej (z pozycji zerowej), w przeciwnym przypadku - "0";
- $= - podobne działanie jak =, lecz porównanie dotyczy dwóch szczytowych wartości stosu łańcuchowego;
- $< - mniejszy niż (łańcuch), operacje porównania na łańcuchach przydają się np do układania ich w kolejności alfabetycznej. "A" jest w tym rozumieniu mniejsze od "B";
- $> - większy niż (łańcuch);
- $<= - mniejszy lub równy (łańcuchowi);
- $>= - większy lub równy (łańcuchowi);
Operatory matematyczne
- + - plus (dodawanie);
- - - minus (odejmowanie - od wartości z pozycji pierwszej stosu odejmuje wartość z pozycji zerowej);
- * - razy (mnożenie)
- / - podzielić przez (dzielenie - wartości z pierwszej pozycji stosu przez wartość z pozycji zerowej)
- % - reszta z dzielenia (dla liczb zmiennoprzecinkowych wygląda to następująco: wartość z zerowej pozycji stosu minus trunc(wartość z pierwszej pozycji stosu podzielona przez wartość z zerowej pozycji stosu) razy wartość z pierwszej pozycji stosu, czyli: "Stack0 - trunc(Stack1 / Stack0) * Stack1 )");
- /-/ - zmiana znaku;
- sin - sinus;
- min - wybiera mniejszą wartość z dwóch szczytowych wartości stosu;
- max - wybiera większą wartość z dwóch szczytowych wartości stosu
- exp - funkcja wykładnicza o podstawie e (e do potęgi wartości z zerowej komórki stosu);
- sqrt - pierwiastek kwadaratowy;
- sqr - kwadrat;
- sgn - zwrócenie znaku (wartości "-1", "0" lub "1");
- pi - liczba pi;
- random - zwrócenie losowej liczby całkowitej z przedziału: 0 <= x <= liczba z wierzchołka stosu;
- abs - wartość bezwzględna;
- trunc - zaokrąglenie do najbliższej liczby całkowitej.
Operacje na łańcuchach
- "bla" - wstawienie łańcucha "bla" do wierzchołka stosu łańcuchowego;
- $+ - łączenie dwóch ciągów, Omnibus simulator $+ daje Omnibussimulator ;
- $* - wierzchołkowy łańcuch stosu łańcuchowego jest powtarzany do momentu osiągnięcia danej wartości, przykładowo nu 6 $* daje nununu ;
- $length - zwraca liczbę znaków łańcucha z wierzchołka stosu łańcuchowego;
- $cutBegin - tnie łańcuch z wierzchołka stosu łańcuchowego od początku;
- $cutEnd - tnie łańcuch z wierzchołka stosu łańcuchowego od końca;
- $SetLengthR - ustawia długość łańcucha wierzchołkowego i ewentualnie wyrównuje go do prawej o odległość uzupełniających łańcuch nadmiarowych spacji;
- $SetLengthL - ustawia długość łańcucha wierzchołkowego i ewentualnie wyrównuje go do lewej o odległość uzupełniających łańcuch nadmiarowych spacji;
- $IntToStr - zaokrągla wartość w łańcuchu wierzchołkowym i konwertuje do liczby całkowitej;
- $IntToStrEhn - udoskonalenie $IntToStr, wierzchołek stosu łańcuchowego determinuje format konwersji, pierwszy znak łańcucha jest używany do wypełnienia brakujących miejsc, a kolejne znaki dają liczbę wskazującą na te miejsca. Przykład: 35 " 5" $IntToStrEnh daje " 35", a 123456789 "011" $IntToStrEnh daje 00123456789;
- $StrToFloat - konwertuje wartość z wierzchołka stosu łańcuchowego do liczby zmiennoprzecinkowej (jeśli jest to możliwe), w przeciwnym wypadku wyrzuca wartość "-1".
Dostęp do zmiennych
Wyróżnia się zmienne systemowe i zmienne lokalne. Zmienne systemowe wykorzystuje OMSI, a lokalne obowiązują dla pojazdów lub obiektów. Zmienne lokalne bazują na tych predefiniowanych przez symulator. Ponadto możemy dodawać tyle zmiennych, ile i jakie chcemy, przy użyciu plików
Varlist.
- (L.S.nazwa) - ładuje zmienną systemową nazwa na wierzchołek stosu;
- (L.L.nazwa) - ładuje zmienną lokalną nazwa na wierzchołek stosu;
- (L.$.nazwa) - ładuje lokalną zmienną łańcuchową nazwa na wierzchołek stosu łańcuchowego;
- (S.L.nazwa) - zapisuje wierzchołkową wartość stosu w zmiennej nazwa;
- (S.$.nazwa) - zapisuje wierzchołkową wartość stosu łańcuchowego w zmiennej nazwa;
Szczegółowy wykaz zmiennych pojawi się u nas wkrótce.
Jeszcze raz przypomnijmy sobie, jak wyglądają działania w skryptach OMSI, ale na przykładzie już konkretnych zmiennych. Taki fragment kodu:
Kod:
(L.L.test) 2 * (C.L.summand) + (S.L.result)
oznacza ni mniej ni więcej, tylko: "wczytaj i pomnóż przez "2" zmienną lokalną
test, dodaj stałą
summand i zapisz wynik w zmiennej
result".
Oczywiście, żeby być precyzyjnym, trzeba byłoby uwzględnić w tych działaniach stos, lecz tutaj analizę pozostawiam już Czytelnikowi.
Stałe i funkcje
Stałe lokalne i odcinkowe funkcje liniowe można określić w plikach
constfiles (
~_constfile.txt). Struktura tych plików odpowiada w pewnej mierze strukturze plików konfiguracyjnych (np.
model.cfg). Mogą mieć jednak tylko maksymalnie po trzy słowa dla każdej deklaracji. Uwaga: dla wartości zmiennych należy używać wyłącznie liczb dających zamienić się na liczby zmiennoprzecinkowe (nie należy używać chociażby znaków).
Definicję nowej stałej rozpoczyna słowo kluczowe
[const], struktura jest następująca:
Kod:
[const]
nazwa
wartość
przykładowo:
Kod:
[const]
moc_swiatla
50
Słowo
[newcurve] rozpoczyna natomiast definicję nowej odcinkowo liniowej funkcji:
Słowo [pnt] dodaje parę punktów (X,Y) do zakresu funkcji. Aby funkcja tak naprawdę nią była, wymagane są dwie takie pary. Poniżej tradycyjnie przykład:
Kod:
[newcurve]
Drehzahl_Drehmoment_Kennlinie
[pnt]
50
0
[pnt]
300
400
[pnt]
1000
600
Stałe mogą być ładowane w skrypcie na wierzchołek stosu przez komendę
(C.L.nazwa_stalej)
Funkcje są wywoływane przez polecenia
(F.L.nazwa_funkcji) . Pierwsza wartość, podana na początku stosu, oznaczana jest przez grę jako parametr X, a będąca rezultatem obliczeń wartość Y jest podawana w drugiej kolejności. Wartości definiujemy poprzez dwie zmienne pod wpisem
[pnt]. Muszą być podane po sobie, w takiej postaci:
Wyzwalacze dźwięku
Wyzwalaczy dźwiękowych nie należy mylić z wcześniej opisanymi wyzwalaczami. W skrócie - jest to sposób na bezpośrednie odtwarzanie dźwięków, przy czym istnieją dwie możliwości ich wywołania:
- (T.L.nazwa_wyzwalacza_dzwiekowego) - najprostszy sposób, zadeklarowany dźwięk odtwarzany jest jednokrotnie;
- (T.F.nazwa_wyzwalacza_dzwiekowego) - wyzwalacz dźwiękowy z funkcją podmiany dźwięku, wierzchołek stosu jest używany do odtworzenia pliku dźwiękowego zadeklarowanego przed poleceniem (jeśli znajduje się on w folderze "Sound" obiektu wystarczy podać jedynie jego nazwę i rozszerzenie, w przeciwnym wypadku - adres względny od tej ścieżki)
Przykład:
dzwiek_pixel jest przypisany w dźwiękowym pliku konfiguracyjnym do
sterownikpixel.wav
Umieszczenie w skrypcie:
powoduje odtworzenie
sterownikpixel.wav , natomiast:
Kod:
"innydzwiek.wav" (T.F.dzwiek_pixel)
powoduje odtworzenie pliku
innydzwiek.wav
W razie konieczności, przed
(T.F.dzwiek_pixel) można stosować "pusty" łańcuch:
Kod:
"" (T.F.dzwiek_pixel)
Makra systemowe
Do tej chwili poznaliśmy trzy metody komunikacji skryptów z OMSI:
- odczytywanie zmiennych systemowych i lokalnych;
- zapisywanie powyższych;
- obsługa klawiatury, myszy oraz innych wyzwalaczy.
Istnieje jeszcze jeden sposób - makra systemowe, czasem zwane "funkcjami zwrotnymi". Większa ilość danych (np. informacje z plików *.hof) nie może być obsłużona przez zmienne. W tym właśnie przypadku do gry wkraczają makra systemowe.
Działają one na podobnej zasadzie jak makra lokalne (czyli napisane bezpośrednio w skrypcie). Polecenie
M.V.nazwa_makra_systemowego wywołuje dane makro systemowe. Wykonywanie i zapisywanie ewentualnych danych odbywa się automatycznie w dwóch stosach. Makra te z powodzeniem można stosować i w pojazdach i w obiektach scenerii. Ich lista zostanie wkrótce przetłumaczona i opublikowana na Strefie.
Wyrażenia warunkowe IF
Sterowanie rozkazami programu jest obecnie możliwe tylko poprzez rozkazy IF. Pełny przykład wyrażenia IF:
Kod:
'Tutaj musi stać warunek, np.:
(L.L.zmienna) 1 =
{if}
'Ten fragment jest wykonywany gdy "zmienna" jest równa 1:
2 3 +
{else}
'W przeciwnym wypadku wykonywane są działania po else:
3 4 +
{endif}
(S.L.innazmienna)
{end}
Zatem najpierw należy zapisać warunek, a dopiero później słowo kluczowe {if}. Dzięki temu porównanie warunku ze zmienną może być bezproblemowo przeprowadzone na szczycie stosu.
Warto wspomnieć, że adekwatnie do działań logicznych "0" reprezentuje fałsz, a każda inna liczba - prawdę. W powyższym przykładzie, "innazmienna" będzie wynosić 5, gdyby warunek nie był spełniony przybrałaby wartość 7.
Zagnieżdżanie konstrukcji IF jest podobne do konstrukcji "else if" w różnych językach programowania, ale jednak nieco inne. Wygląda to następująco:
Kod:
'Warunek, np.:
(L.L.zmienna) 1 =
{if}
'Ten fragment wykona się, gdy zmienna = 1:
2 3 +
{else}
(L.L.zmienna) 5 =
{if}
'Ten natomiast gdy zmienna = 5:
3 4 +
{else}
'Poniższa sekcja, gdy nie zostanie spełniony ten warunek:
13
{endif}
{endif}
(S.L.innazmienna)
{end}
Należy zwrócić uwagę na podwójne
{endif}. Powyższy fragment skryptu działa następująco:
gdy
zmienna = 1 to
innazmienna = 5;
gdy
zmienna = 5 to
innazmienna = 7;
gdy żaden z powyższych warunków nie zostanie spełniony to
innazmienna = 5;
Poradnik został napisany wyłącznie dla Forum http://strefa-omsi.pl i nie może być rozpowszechniany we fragmentach lub w całości na innych stronach bez zezwolenia głównego Autora.