Script: Ein Haltewunsch-Summer

Aus wiki.3d-modell.design
Wechseln zu: Navigation, Suche

Ich selbst habe erst vor zwei Tagen begonnen, mich mit dem OMSI-Skriptsystem näher auseinanderzusetzen, als die Dokumentation hier in der OMSI-Wiki erschien. Ich habe sogleich begonnen, ein bisschen zu experimentieren, um mir die Skriptsprache selber ein wenig beizubringen. Als eines der ersten Projekte ist ein Haltewunsch-Summer herausgekommen.

Mir ist bewusst, dass dies skripttechnisch kein "Wunderwerk" ist - aber ich denke, für den Einsteiger ist es das ideale Projekt, denn es zeigt die Verwendung von Macros, Soundtriggern usw., ist aber gleichzeitig nicht sonderlich umfangreich. Ich entschied mich daher, hier ein Tutorial zu verfassen, um einigen Skriptern den Einstieg zu erleichtern.


Wie fangen wir an?

Bedingungen für das Abspielen des Sounds

Am Anfang müssen wir uns natürlich fragen, was wir überhaupt umsetzen wollen. Ich mache jetzt mal eine Art "Monolog-Brainstorming".

Wir wollen, dass ein Summer ertönt, wenn die Haltewunsch-Lampe beim Fahrer angeht. Allerdings soll dies nur einmal geschehen und nicht jedes Mal, wenn ein Fahrgast den Stopknopf drückt. Des Weiteren wollen wir den Ton nicht hören, wenn wir den Kinderwagenschalter umlegen (dies ist ja auch eine Art Stopknopf). Wenn die Türen offen sind, soll der Sound ebenfalls nicht abgespielt werden.

Außerdem ist es so, dass die Fahrgäste beim Aussteigen in OMSI permanent den Stopknopf drücken (bzw. über das Trittbrett laufen), denn so weiß OMSI, dass die hintere Tür noch nicht geschlossen werden darf! Wenn wir dies nicht berücksichtigen würden, würde ein Dauerton erklingen, wenn Leute aussteigen - eine der Stolperfallen, auf die ich gestoßen bin.

Also kurz und knapp, welche Bedingungen für das Abspielen des Summers soll OMSI prüfen, wenn ein Haltewunsch registriert wird?

  • Es hat noch keiner vorher den Stopknopf gedrückt, es liegt also noch kein Haltewunsch vor.
  • Alle Türen müssen geschlossen sein.
  • Es wurde entweder ein normaler Stopknopf oder ein Stopknopf an der Tür gedrückt, der Kinderwagenschalter aber wird ignoriert.

Jetzt wissen wir, was wir umsetzen wollen - aber noch nicht, wie wir das denn machen.


Was brauchen wir?

Okay, die Abspielbedingungen sind geklärt. Spätestens jetzt sollte man sich den Artikel Scriptsystem genauer ansehen - ich werde die meisten Informationen, die hier benötigt werden, aber nochmal erläutern.

Um die Übersicht zu wahren, werden wir eine neue Skriptdatei für dieses Projekt anlegen. Skriptdateien haben die Endung *.osc. Diese Datei wird den Code enthalten, der überprüft, ob der Sound abgespielt werden darf und falls ja, den Sound auch tatsächlich abspielt.

Des Weiteren müssen wir für jeden Bus, der diesen Summer abspielen soll, die Skriptdatei in der jeweiligen *.bus-Datei registrieren. Die BUS-Datei enthält alle grundlegenden Informationen zum Bus und darüber hinaus auch die Verweise auf Variablenlisten, Skripts usw. - hier müssen wir OMSI also sagen, wo sich die neue Skriptdatei befindet.

Außerdem müssen wir noch den abzuspielenden Sound definieren. Dies geschieht in der Soundkonfigurationsdatei (Endung *.cfg) jedes betroffenen Busses.

Damit haben wir uns einen Überblick verschafft. Wir benötigen also:

  • Eine neue Skriptdatei mit dem Code zum Abspielen des Sounds
  • Ändern der *.bus-Datei, um die neue Skriptdatei bei OMSI anzumelden
  • Ändern der Soundkonfigurationsdatei (*.cfg), um den abzuspielenden Sound zu definieren

Jetzt haben wir unser ganzes Handwerkszeug beisammen, und im nächsten Schritt geht's Stück für Stück an die Umsetzung.


Die Umsetzung

Den Sound dem Bus hinzufügen

Die Datei "sound_XXX.cfg" im Unterverzeichnis "Sound" eines Bustyps enthält alle Sounds, die für den jeweiligen Bus verwendet werden. Hier müssen wir also unseren Sound auch hinzufügen, damit OMSI ihn erkennt.

Kopiere als erstes den Summer-Sound (eine WAV-Datei) in das Unterverzeichnis "Sound" zu den anderen Sounddateien. Der Dateiname sollte natürlich aussagekräftig sein, wir wählen in diesem Fall einfach "summer.wav".


Jetzt öffne die "sound_XXX.cfg" des gewünschten Busses. Ich nehme als Beispiel den D92, das geht aber mit jedem anderen Bus auch. In diesem Fall öffne ich also die "sound_D92.cfg".

Scrolle bis ans Ende der Datei und füge folgenden Code hinzu, im Anschluss wird er erläutert:

[sound]
summer.wav
0.6


[3d]
-0.65
5.35
1.6
0.5

[trigger]
haltewunsch_summer

Nach dem Schlüsselwort [sound] folgt der Dateiname (ggf. anpassen!) und die Lautstärke (von 0 bis 1). Mit der Lautstärke musst du je nach Lautstärke der Sounddatei ein wenig experimentieren, bis der Summer laut/leise genug ist.

Das Schlüsselwort [3d] definiert die Position des Sounds. Mit dem dargestellten Code befindet er sich direkt im Cockpit. Im Heck des Busses nimmt man den Summer also kaum noch wahr.

Das letzte Schlüsselwort [trigger] ist extrem wichtig: Mit diesem Trigger wird später der Sound abgespielt, der Name sollte also eindeutig gewählt sein! Im Beispiel "haltewunsch_summer".

Speichere die Datei und OMSI weiß, dass der neue Sound existiert, aber noch nicht, wann und wie er abgespielt werden soll - das kommt im nächsten Schritt.


Die neue Skriptdatei anlegen

Die eigene Skriptdatei enthält den Code, der ausgeführt wird, wenn ein Fahrgast den Haltewunschknopf drückt. Zwar hätte man diese Routine auch direkt in die anderen Skripte schreiben können, aber so wird das System klarer verständlich und man trennt zudem "Eigenproduktion" und "Originalproduktion".

Öffne also den Windows-Editor (Notepad), um die neue Datei zu erstellen. Füge folgenden Code ein, er wird wiederum im Anschluss erläutert.

'Spielt einen Summer-Ton ab, wenn ein Haltewunschknopf gedrückt wird.

{macro:summer_abspielen}

        (L.L.haltewunsch) 1 = !
	(L.L.door_0) 0.1 < &&
	(L.L.door_1) 0.1 < &&
	(L.L.door_2) 0.1 < &&
	{if}
		(T.L.haltewunsch_summer)	
	{endif}

{end}

Zuerst definieren wir den Namen der Prozedur, in OMSI heißen diese Prozeduren einfach "Macros". Später kann man dieses Macro an geeigneter Stelle aufrufen und so den Code immer dann ausführen, wenn er benötigt wird. Hierzu empfehle ich noch diese Lektüre: Einstiegs- und Ausstiegspunkte, Makros und Trigger

Alles, was also zwischen {macro:...} und {end} steht, wird immer durchlaufen, wenn das Macro aufgerufen wird. Jetzt zur Erläuterung des enthaltenen Codes.


Der Code besteht eigentlich nur aus einer IF-Anweisung und dem Abspielen des Sounds, falls die Bedingungen alle zutreffen. Der Einfachheit halber werde ich die Zeilen einzeln erläutern.

(L.L.haltewunsch) 1 = !

Wenn ein Haltewunsch registriert wurde, wird die Variable "haltewunsch" auf 1 gesetzt, sonst ist sie 0. Man kann also einfach abfragen, ob die Variable ungleich 1 ist, denn der Sound soll ja nur abgespielt werden, wenn die Haltewunschlampe noch nicht leuchtet. Der Code "(L.L.haltewunsch) 1 =" würde also TRUE zurückgeben, wenn schon ein Haltewunsch existiert, das Gegenteil wollen wir aber erreichen. "!" ist in OMSI die Verneinung, sie kehrt also TRUE zu FALSE um und umgekehrt. Das bedeutet für uns, die Bedingung ist dann wahr, wenn noch kein Haltewunsch vorliegt - genau das, was wir erreichen wollen.

(L.L.door_0) 0.1 < &&
(L.L.door_1) 0.1 < &&
(L.L.door_2) 0.1 < &&

Hier prüfen wir einfach, ob alle Türen geschlossen sind. Ob eine Tür offen ist, wird über die Variable "door_X" festgelegt. 0 bedeutet "ganz geschlossen", 1 dagegen "ganz geöffnet". Wir wollen nicht so streng sein und sagen: Für uns ist die Tür schon zu, wenn sie nur 10% geöffnet ist (das entspricht ja 0.1). Die "&&" bedeuten "AND", d.h. damit die IF-Anweisung ausgeführt wird, müssen ALLE Bedingungen TRUE sein.

(T.L.haltewunsch_summer)

Dieser Befehl schließlich führt den Soundtrigger "haltewunsch_summer" aus. Dieser Name entspricht dem, den wir vorhin in der Soundkonfigurationsdatei unter [trigger] angegeben haben. OMSI spielt den Sound einfach jedes Mal ab, wenn dieser Trigger augerufen wird.

So weit so gut, das Skript steht. Speichere es jetzt z.B. als "summer.osc" ab - OMSI kann es jetzt aber noch nicht finden. Damit OMSI weiß, wo es sich befindet, müssen wir im folgenden Schritt noch eine Kleinigkeit ändern.


Die Skriptdatei dem Bus hinzufügen

Welche Skripts ein Bus verwendet, wird in der entsprechenden *.bus-Datei des Busses festgelegt. Damit OMSI also das oben definierte Makro überhaupt finden kann, öffnen wir jetzt die entsprechende *.bus-Datei mit dem Editor. Beim D92 wäre das logischerweise die "MAN_D92.bus".

Wir scrollen nun herunter bis zum Abschnitt [script]. Hier folgen zunächst die Zahl der von OMSI zu lesenden Zeilen und dann die relativen Pfade zu den Skriptdateien. Wir fügen unsere Skriptdatei hinten an und erhöhen die auszulesende Zeilenzahl um 1, sodass es etwa so aussehen sollte:

[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\door.osc
script\wiper.osc
script\klappern.osc
script\forcefeedback.osc
script\rain.osc
script\dirt.osc
script\sound_volume.osc
script\heizung.osc
script\IBIS-2.osc
script\matrix_D.osc
script\wimpel.osc
script\cashdesk.osc
script\ticketprinter.osc
script\summer.osc

Falls schon vorhergehend Modifikation installiert worden sein sollten, kann die Liste natürlich variieren. Wichtig ist nur, penibel genau auf die korrekte Zeilenanzahl zu achten.

Damit haben wir das Gröbste geschafft und können kurz durchatmen ;-) Was jetzt noch fehlt, ist, dass OMSI dieses Makro an den geeigneten Stellen aufruft - also immer dann, wenn ein Haltewunsch von OMSI bemerkt wird. Das kommt im vierten und letzten Schritt an die Reihe.

Das Makro an geeigneter Stelle aufrufen

Der Code für den Haltewunsch steht bei den mitgelieferten Doppeldeckern in der Skriptdatei "door.osc". Für den OMSI-Türmod funktioniert die Anleitung genauso, dort müssen eben entsprechend die anderen Dateien bearbeitet werden.

Öffne also die "door.osc" und suche die Sektion {trigger:int_haltewunsch}. Hier müssen wir unser oben definiertes Macro aufrufen.

Dieser Trigger wird von OMSI aufgerufen, wenn ein Fahrgast den Stopknof drückt. Direkt unter dieser Zeile fügen wir also den Macroaufruf ein, sodass die ganze Sektion so aussieht:

{trigger:int_haltewunsch}
	
        (M.L.summer_abspielen)
	1 (S.L.haltewunsch)
	
{end}

Wir rufen einfach zuerst das oben selbst geschriebene Macro auf, und danach setzt OMSI die Variable "haltewunsch" auf 1. Würden wir die umgekehrte Reihenfolge wählen, wäre die 1. Bedingung innerhalb des Macros (s.o.) immer FALSE und der Sound würde nie abgespielt!

Den gleichen Makroaufruf fügst du auch unter {trigger:door_haltewunsch} ein - dieser Trigger repräsentiert die Tür-Stopknöpfe bzw. das Trittbrett an der hinteren Tür. Und falls gewünscht, kannst du den Code darunter auch für den Kinderwagenschalter einfügen. Wie das geht, kannst du selbst ausprobieren - nur ein Tipp: (T.L.ev_kippschalter_ein) spielt den Sound ab, der das Einschalten des Kinderwagenschalters repräsentiert. Irgendwo dort sollte also der Macroaufruf stehen ;)


Speichere die Änderungen dann noch ab und probiere das Ergebnis aus - es sollte funktionieren.

Viel Spaß beim weiteren Erkunden der Skriptsprache ;-)