Modul-Objekte

  • Das Prinzip der Modul-Objekte bietet die Möglichkeit, komplexe Objekte im Fahrzeug, die einerseits austauschbar sind und andererseits in verschiedenen Fahrzeugtypen eingebaut sind, als unabhängiges, autark verscriptetes und "versoundetes" Modul-Objekt zu erstellen.

    Innerhalb des eigentlichen Fahrzeuges müssen dann nur noch "Slots" definiert werden, die LOTUS mitteilen, wo welches Modul installiert werden soll, und einige zusätzliche nötige Parameter übergeben. Welches Modul auf welchen Slot gesetzt wird, kann auf verschiedene Weisen gesteuert werden - momentan geht das über die Konfiguration des User-Fahrzeuges und über das Script-System.

    1 Module

    Ein Modul ist z.B. ein IBIS-Gerät oder eine Anzeige. Jedes Modul ist ein komplett unabhängiges Objekt, welches im Object & Vehicle Tool getrennt vom Fahrzeug aufgebaut und konfiguriert wird. Es kann über Scripts, Sounds, Animationen usw. verfügen.


    Um ein neues Modul anzulegen, wird als Objektklasse "Modul" (statt Szenerie-Objekt oder Fahrzeug) ausgewählt. Das eigentliche (sichtbare) Objekt soll beim Bauen dabei nicht so platziert werden, wie es später im Fahrzeug positioniert ist, sondern zentriert und nicht-gedreht. Die genaue Position und Rotation wird dagegen im Fahrzeug festgelegt.

    1.1 Modul-Klasse

    Jedem Modul wird mit einer sogenannte Modul-Klasse versehen. (Einstellbar in den Objekteinstellungen.) Die Modul-Klasse ist ein String, der beschreibt, um welche Art von Modul es sich handelt. Jeder Modul-Slot wird ebenfalls mit einer Modul-Klasse versehen. Infolgedessen kann der Spieler später nur solche Module auf einen Modul-Slot setzen, die auch dieselbe Modul-Klasse haben. Damit wird verhindert, dass ein IBIS-Gerät oben im Zielanzeigenkasten platziert wird - oder umgekehrt ein Rollband direkt vor der Nase des Users dort, wo eigentlich das IBIS angebracht ist... Wichtig ist, dass die Modul-Klassen stets identisch sein müssen.


    Das scriptseitige Platzieren von Modulen ist davon unbetroffen. Hier kann das Modul frei gewählt werden.

    2 Modul-Slots

    Jedes Fahrzeug, aber auch jedes Modul selbst kann mit sog. Modul-Slots versehen werden, welche dann nach Wunsch und wahlweise per Script oder per Auswahl des Users bei Konfiguration seines Zuges mit entsprechenden Modulen ausgestattet werden können.


    Konfiguriert werden die Modul-Slots in den Objekteinstellungen. Dort befindet sich der Abschnitt "Module", in welchem beliebig viele Modul-Slots hinzugefügt werden können.


    ACHTUNG: Momentan erscheint nach dem Hinzufügen eines neuen Slots eine Fehlermeldung. Diese bitte ignorieren, das Fenster mit "OK" schließen und neu öffnen - dann geht's weiter! :-)


    Jeder Slot verfügt über die folgenden Parameter:

    • Name: Dieser Name erscheint im Fahrzeug-Konfigurationsfenster im Simulator
    • Modul-Klasse: Nur Module mit derselben Modulklasse (Groß- und Kleinschreibung wird beachtet!) können vom User auf diesen Slot gesetzt werden.
    • Index innerhalb der Modul-Klasse: Angenommen, es handelt sich um einen Zweirichtungs-Triebwagen, der an beiden Enden über ein IBIS verfügen soll. Es werden dann zwei Slots eingerichtet. Erhalten die Scripts der IBIS-Geräte nun eine Message (s.u.) vom Fahrzeug, dann wird hierbei dieser Index mitgeschickt und das Script weiß, ob es selbst das IBIS des vorderen Fahrerraums ist oder des hinteren.
    • Position und Drehung: Mit diesen Werten wird bestimmt, wo und wie genau das Modul platziert werden soll.
    • In der Fahrzeugkonfiguration im Simulator unsichtbar: Wenn ein Slot ggf. nur scriptseitig bestückt werden soll und daher der Spieler darauf keinen Einfluss darauf haben soll, dann kann der Slot mit diesem Parameter "versteckt" werden.
    • Verwendet diesen Lichtraum: So wie bei allen anderen Meshs und Materialien auch, muss festgelegt werden, zu welchem Lichtraum das Modul gehört und demzufolge von welchen Lichtquellen es beleuchtet werden soll.
    • Übergeordnete Animation: Damit das Modul an einem beweglichen Objekt befestigt sein kann, muss diese Animation hier ausgewählt werden.
    • Standard-Modul: Solange der Spieler nichts anderes auswählt, wird jeder Modul-Slot mit einem Standard-Modul ausgerüstet. Welches dies sein soll, wird über diesen Parameter festgelegt.

    3 Scripts

    Die Kommunikation zwischen den untergeordneten Objekten (Modulen) und den übergeordneten Objekten (Fahrzeug) findet mittels Prozedur-Aufrufen statt, den sogenannten "Messages" und "Broadcasts".

    3.1 Messages

    Messages senden Daten gezielt an bestimmte Module bzw. gezielt an das übergeordnete Objekt:

    • procedure SendMessageToChildInteger(self: integer; slotindex: integer; messageId: string; value: integer);: Mit diesem Prozeduraufruf wird die GetMessageFromParentInteger-Prozedur (s.u.) in jenem Modul-Script aufgerufen, welches sich im Slot mit dem Index slotindex befindet. Übergeben wird eine Message-ID und ein Integer-Wert value. Analog gibt es noch SendMessageToChildSingle und SendMessageToChildString mit jeweils einem Single- und einem String-Wert.
    • procedure SendMessageToParentInteger(self: integer; id: string; value: integer);: Mit diesem Prozeduraufruf wird die GetMessageFromChildInteger-Prozedur (s.u.) im übergeordneten Script. Übergeben wird eine Message-ID und ein Integer-Wert value. Analog gibt es noch SendMessageToParentSingle und SendMessageToParentString mit jeweils einem Single- und einem String-Wert.

    Innerhalb der jeweiligen Script kann eine der folgenden Prozeduren deklariert werden, die dann LOTUS-seitig aufgerufen wird, wenn vom jeweiligen "Partner" eine der oben beschriebenen Prozeduren aufgerufen wird:

    • procedure ReceiveMessageFromChildInteger(slotindex: integer; id: string; value: integer);: Wird aufgerufen, wenn ein (untergeordnetes) Modul-Script die Prozedur SendMessageToParentInteger aufruft. slotindex identifiziert den Slot desjenigen Moduls, welches diese Prozedur aufgerufen hat. Analog gibt es noch ReceiveMessageFromChildSingle und ReceiveMessageFromChildString
    • procedure ReceiveMessageFromParentInteger(indexOfClass: integer; id: string; value: integer);: Wird aufgerufen wenn ein (übergeordnetes) Objekt-Script (z.B. Fahrzeug) SendMessageToChildInteger aufruft. indexOfClass ist der Wert "Index innerhalb der Modulklasse" des Slots, worin sich das Modul-Objekt des Scripts befindet. Analog gibt es noch ReceiveMessageFromParentSingle und ReceiveMessageFromParentString.

    3.2 Broadcasts

    Broadcasts werden genauso wie Messages programmiert, arbeiten aber anders: Während Messages gezielt bestimmte Module oder das übergeordnete Fahrzeug/Objekt ansprechen, werden im Falle von Broadcasts die Receive-Prozeduren sämtlicher Scripts aller Module und des Elternobjektes angesprochen. Auf diese Weise können bspw. Module wie das IBIS mit allen anderen Modulen, z.B. den Anzeigen kommunizieren, ohne dass bekannt sein muss, wieviele Anzeigen angekoppelt sind. Außerdem ist der Umweg über das übergeordnete Fahrzeug nicht nötig. Zusätzlich zur eigentlichen ID gibt es hier noch eine (Daten-)Bus-ID, d.h. es wird simuliert, dass die Broadcast-Befehle gruppenweise über bestimmte Datenleitungen ("Datenbusse") geleitet werden. Dagegen ist es hierbei nicht mehr möglich, die Herkunft des Broadcasts zu ermitteln.


    Die Broadcast-Prozeduren lauten:

    • procedure SendBroadcastInteger(self: integer; busId: string; id: string; value: integer); (wahlweise auch ~Single oder ~String
    • procedure ReceiveBroadcastInteger(busId: string; id: string; value: integer); (wahlweise auch ~Single oder ~String

    Wie gesagt – die Funktionsweise ist dieselbe wie bei den Messages (siehe oben).

    3.2.1 Broadcasts über Kupplungen weiterleiten

    Broadcasts haben aber noch eine ganz besondere Funktion gegenüber dem normalen Message-System: Sie sind nicht unbedingt auf den eigenen Wagen begrenzt! Es ist möglich, den Kupplungen des Wagens mitzuteilen, dass sie Broadcasts einer bestimmten Bus-ID in die Nachbarfahrzeuge übermitteln. Sie stellen also – ganz unabhängig vom Modulsystem – eine weitere Variante dar, mit der Fahrzeuge über ihr Kupplungen hinweg kommunizieren können!


    Für diese Funktionalität gibt es die folgenden Script-Prozeduren:

    • procedure CoupleBroadcastBus(self: integer; busID: string; couplingindex: byte); – schaltet die Übertragung von Broadcasts mit der angegebenen Bus-ID über die Kupplung mit dem Index couplingindex frei.
    • procedure UncoupleBroadcastBus(self: integer; busID: string; couplingindex: byte); – deaktiviert die Übertragung von Broadcasts mit der angegebenen Bus-ID über die angegebene Kupplung.

    Natürlich werden die Broadcasts jeweils nur dann übertragen, wenn beide Fahrzeuge den entsprechenden Bus freigeschaltet haben. Und natürlich nur, wenn auch erfolgreich gekuppelt wurde... ;-)

    3.3 Script-Performance

    Wichtig ist zu wissen, dass die Message-Befehle performancemäßig nicht völlig "egal" sind! Insofern sollten auch wirklich nur dann Message-Prozeduren aufgerufen werden, wenn es auch wirklich nötig ist. So muss z.B. die im IBIS eingestellte Liniennummer nicht bei jedem Frame an das Fahrzeug übertragen werden, sondern nur, wenn sie auch geändert wurde!