Benutzerdefinierte Funktionen

Aus Starcraft Wiki

Wechseln zu: Navigation, Suche

Der Auslöser-Editor erlaubt das Definieren von eigenen Funktionen, Aktionen, Bedingungen und sogar Ereignissen (allerdings ist die Unterstützung für eigene Ereignisse sehr gering, sodass deren Nutzung gewöhnlich einen Work-Around benötigt). Innerhalb einer Map kann das Zusammenfassen mehrerer Aktionen in einer selbsterstellten Aktion praktisch sein, um oft verwendete Abfolgen von Aktionen zusammenzufassen, sodass nur noch die eigene Aktion aufgerufen werden muss. Innerhalb eines Mods, der für die Allgemeinheit zugänglich sein soll (z. B. eine Engine, die bei der Erstellung von Maps mit einem bestimmten Genre hilft), kann die Benutzerfreundlichkeit durch Nutzung aller vier Typen von benutzerdefinierten Funktionen stark erhöht werden.

Inhaltsverzeichnis

Erstellen einer neuen benutzerdefinierten Funktion

Es gibt drei Möglichkeiten, eine neue benutzerdefinierte Funktion zu erstellen:

  • Strg + Alt + F drücken
  • auf den "f"-Button in der Aktionsleiste klicken
  • im Kontextmenü der Auslöserliste auf Neu -> Neue Funktion klicken

Bei den ersten beiden Varianten muss die Auslöserliste (links) aktiv sein.

Alternativ können auch direkt Aktions- oder Bedingungsdefinitionen erstellt werden (das sind auch nur benutzerdefinierte Funktionen, allerdings mit einigen vorkonfigurierten Eigenschaften). Dies geht ebenfalls auf drei verschiedenen Wegen:

  • Strg + Alt + R (Aktion) oder Strg + Alt + K (Bedingung) drücken
  • auf einen der beiden Buttons links neben dem "f"-Button klicken
  • im Kontextmenü der Auslöserliste auf Neu -> Neue Aktionsdefinition oder Neu -> Neue Bedingung klicken

Auch hier muss bei den ersten beiden Varianten die Auslöserliste aktiv sein.

Eigenschaften benutzerdefinierter Funktionen

Jede benutzerdefinierte Funktion bietet einige Konfigurationsmögkichkeiten, wie z. B. das Festlegen des Funktionstyps (Aktion, Bedingung, ...) oder das Hinzufügen von Parametern:

Optionen

Bei der Eigenschaft Optionen können der Typ der Funktion und einige Flags festgelegt werden. Wurde die Funktion direkt als Aktions- oder Bedingungsdefinition erstellt, so bedarf diese Eigenschaft gewöhnlich keine Änderung.

Typ

Dies legt den Typ der Funktion fest. Folgende Typen stehen zur Auswahl:

  • Aktion: Funktionen mit diesem Typ agieren als Methoden. Ein Beispiel für eine Aktion ist "Text-Nachricht".
  • Bedingung: Funktionen dieses Typs können z. B. in "Wenn, dann, sonst"-Aktionen oder direkt als Auslöserbedingung verwendet werden. Der Rückgabetyp sollte "Boolescher Operator" sein. Ein Beispiel für eine Bedingung ist "Vergleich".
  • Ereignis: Funktionen dieses Typs können ausschließlich bei Auslösern verwendet werden. Die Unterstützung eigener Ereignisse ist sehr gering, sodass zusätzlich zu der Funktion benutzerdefinierter Code vonnöten ist. Wichtig: Der Auslöser selbst darf bei einem eigenen Ereignis nicht als Parameter angegeben werden. Im resultierenden Galaxy-Script ist dieser Paramter dann vorhanden. Ein Beispiel für ein Ereignis ist "Einheit stirbt".
  • Funktion: Funktionen dieses Typs werden benutzt, um Werte zu ermitteln. Ein Beispiel ist "Sinus".

Flags

Zusätzlich zum Funktionstyp können folgende Flags aktiviert oder deaktiviert werden:

  • Ausgeblendet: Dieses Flag sorgt dafür, dass die Funktion nicht in der entsprechenden Liste angezeigt wird, sodass sie über das GUI nicht verwendet werden kann.
  • Benutzerdefiniertes Script: Ist dieses Flag aktiviert, so kann beim Aufruf dieser Funktion Galaxy-Code eingegeben werden. Die Funktion selbst tut dann nichts.
  • Eingeschränkt: Dieses Flag bestimmt, ob die Funktion nur in Blizzard-Maps verwendet werden kann. Es hat daher für Custom Maps keinerlei Anwendungszweck.
  • Operator: Ist dieses Flag aktiviert, so wird die Funktion nicht als Funktion betrachtet, sondern bei ihrem Aufruf lediglich ihr Inhalt an die Aufrufstelle kopiert. Solche Funktionen müssen in Galaxy-Code geschrieben werden, wozu die Eigenschaft "Benutzerdefinierter Skript-Code" dient.
  • Schleife: Dieses Flag gibt an, ob die Funktion eine Schleife darstellt (wie z. B. die Funktion "Für jeden Integer"). Nur wenn dieses Flag aktiviert ist, kann in untergeordneten Aktionen "break" verwendet werden.
  • Thread erstellen: Ist dieses Flag aktiviert, so wird beim Aufruf der Funktion ein neuer Auslöser erstellt, der dann den Code der Funktion ausführt. Dies sorgt dafür, dass die Aktionen der Funktion parallel zu der der aufrufenden Funktion ablaufen. Das Flag ist allerdings nur gültig, wenn es sich bei der Funktion um eine Aktion handelt.
  • Unterfunktionen: Funktionen mit dieser Option können weitere untergeordnete Funktionen besitzen. Ein Beispiel dafür ist die "Wenn, dann, sonst"-Aktion. Die geforderten Unterfunktionen können bei der Eigenschaft "Unterfunktionstypen" festgelegt werden. Ansonsten verhält sich eine solche Funktion völlig analog wie eine mit dem Flag "Operator".

Ausgabetyp

Dieser Wert wird für Funktions- oder Bedingungsdefinitionen verwendet, um festzulegen welchen Wert die Funktion zurückgibt. Bei Bedingungen sollte der Rückgabetyp "Boolescher Operator" sein. Bei Aktions- und Ereignisdefinitionen spielt der Rückgabetyp - zumindest bei der ausschlißlichen Verwendung im GUI - keine Rolle und wird gewöhnlich auf "(Nichts)" gestellt.

Parameter

Parameter bestimmen die Eingaben für eine Funktion. Sie sind die Einträge, die man beim Aufrufen der Funktion festlegen kann. Die vorgefertigte Funktion "Einheit vernichten" hat zum Beispiel nur einen Parameter vom Typ "Einheit".

Grammatiktext

Dies ist der Text, der im Trigger-Editor angezeigt wird. Ihr könnt hier einen beliebigen Text wählen und entscheiden, wo eure Parameter im Text vorkommen. Der Grammatiktext hat aber keine Auswirkung auf die Funktionalität der Funktion und dient lediglich der Übersichtlichkeit des GUIs.

Hinweistext

Hier könnt ihr einen Hilfstext definieren, der beim Verwenden der Funktion grau unter dem Grammatiktext angezeigt wird.

Benutzerdefinierter Skript-Code

Fortgeschrittene Mapper können hier Galaxy-Code benutzen. Damit diese Eigenschaft eine Auswirkung hat, muss entweder "Operator" oder "Unterfunktionen" aktiviert sein. Dabei gitbt es zusätzlich zur normalen Galaxy-Syntax einige Erweiterungen, die genutzt werden können. Alle diese Erweiterungen beginnen mit einem "#", gefolgt von Blockbuchstaben und evtl. Parametern. Beim resultierenden Galaxy-Script der Map werden diese speziellen Ausdrücke durch entsprechenden Code ersetzt. Es gibt folgende dieser Erweiterungen:

  • #PARAM(name): Generiert den Script-Bezeichner des Parameters mit Namen name. Als name muss der "Skript-Identifikator" des gewünschten Parameters angegeben werden.
  • #AUTOVAR(name, typ): Generiert eine lokale Variable mit Namen name vom Typ typ innerhalb der aufrufenden Funktion. Diese Eigenschaft ist nötig, da lokale Variablen vor allen Aktionen einer Funktion stehen müssen und folglich nicht direkt eingegeben werden können. Außerdem wird dadurch ermöglicht, dass beim mehrmaligen Verwenden der Funktion in einer anderen Funktion jede Verwendung ihre eigenen lokalen Variablen hat. Dabei ist name keineswegs der Scriptbezeichner der Variable. Um auf die Variable zugreifen zu können, benötigt man #AUTOVAR(name).
  • #AUTOVAR(name): Generiert den Bezeichner für eine durch #AUTOVAR(name, typ) erstellte lokale Variable.
  • #SMARTBREAK: Fügt ein break in den Code ein, allerdings nur, wenn die Funktion innerhalb einer Schleife aufgerufen wird.
  • #DEFRETURN: Generiert einen Standardwert für den Rückgabetyp der aufrufenden Funktion.

Für Funktionen, die Unterfunktionen verwenden, gibt es zusätzlich noch:

  • #SUBFUNCS(name): Kopiert alle Unterfunktionen des Unterfunktionstyp mit "Skript-Identifikator" name in den Code.
  • #SUBFUNCS(name, trennung): Ähnlich wie #SUBFUNCS(name), mit dem Unterschied, dass der bei trennung angegebene Text zwischen je zwei Unterfunktionen gesetzt wird. Dabei muss trennung als String angegeben werden.

Unterfunktionstypen

Hier können die Unterfunktionstypen einer Funktion mit dem Flag "Unterfunktionen" angegeben werden. Dies geht mit Strg + J, durch Klick auf den Aktionsleistenbutton, der bei Aktivierung der Eigenschaft aufleuchtet, oder durch einen Klick auf Neu -> Neuer Unterfunktionstyp im Kontextmenü der Funktion. In den Eigenschaften eines Unterfunktionstyps kann zusätzlich festgelegt werden, welcher Typ von Funktionen erlaubt ist (die Auswahl besteht zwischen "Aktionen", "Bedingungen" und "Ereignissen"). Beispiele für Unterfunktionstypen sind "Falls", "Dann" und "Sonst" bei der Aktion "Wenn, dann, sonst" und "Aktionen" bei der Aktion "Für jeden Integer".

Lokale Variablen und Aktionen

Lokale Variablen und Aktionen funktionieren genauso wie bei Auslösern.


Beispiele

Aktionsdefinition

Angenommen wir erstellen in userer Map sehr oft eine Einheit für Spieler 10 und lassen diese dann irgendwo hin laufen. Unser Auslöser um Einheiten zum Spieler zu schicken sieht also beispielsweise so aus:

Vorher

Ereignisse
Timer - Alle 5.0 Sekunden von Spielzeit
Lokale Variablen
Bedingungen
Aktionen
Einheit - 1 Space-Marine für Spieler 10 bei Tunnel mit Ausrichtung von 270.0 Grad erstellen (Keine Optionen)
Einheit - (Zuletzt erstellte Einheit) Befehl ( Angreifen visiert Basis an) erteilen (Bestehende Befehle ersetzen)

Nun wollen wir diese zwei Aktionen mit einer Aktionsdefinition zusammen fassen. Dafür müssen wir uns überlegen, welche Parameter wir verwenden wollen. Was sind also die Dinge, die veränderbar sein sollen? Dies soll für dieses Beispiel der Einheitentyp, der Startpunkt und der Zielpunkt sein. Nun ist das Erstellen der Aktionsdefinition sehr einfach: Wir müssen nur die Parameter erstellen, die Aktionen kopieren und die Parameter dort einsetzen, wo wir vorher feste Werte hatten. Damit man das besser sieht fangen alle Parameternamen im Beispiel mit "param_" an:

Einheit schicken

Optionen: Aktion
Ausgabetyp: Integer
Parameter
param_Einheitentyp = Keine Spielverknüpfung <Spielverknüpfung - Einheit>
param_Startpunkt = Kein Punkt <Punkt>
param_Zielpunkt = Kein Punkt <Punkt>
Grammatiktext: Erstelle einen param_Einheitentyp am param_Startpunkt und lass ihn param_Zielpunkt angreifen.
Hinweistext: (Nichts)
Benutzerdefinierter Skript-Code
Lokale Variablen
Aktionen
Einheit - 1 param_Einheitentyp für Spieler 10 bei param_Startpunkt mit Ausrichtung von 270.0 Grad erstellen (Keine Optionen)
Einheit - (Zuletzt erstellte Einheit) Befehl ( Angreifen visiert Tunnel an) erteilen (Bestehende Befehle ersetzen)

In unserem alten Auslöser können wir nun unsere neue Aktion verwenden:

Nachher

Ereignisse
Timer - Alle 5.0 Sekunden von Spielzeit
Lokale Variablen
Bedingungen
Aktionen
Erstelle einen Space-Marine am Tunnel und lass ihn Basis angreifen.

Durch den geschickt gewählten Grammatik-Text liest sich dieser nun wie ein fast korrekter deutscher Satz ;) Die wirklichen Vorteile von Aktionsdefinitionen werden jedoch erst bei längeren Beispielen klar.

Eine Karte mit diesem kleinem Beispiel kann hier heruntergeladen werden: http://starcraft2.ingame.de/filebase/?file=86325

Operator

Ein Mangel des GUIs ist, dass es keine Möglichkeit gibt, einen String in eine bestimmte Spielverknüpfung zu konvertieren. Dabei ist beides in Galaxy das gleiche. In diesem kleinen Beispiel wird gezeigt, wie mit Hilfe von Funktionen mit dem Flag "Operator" ganz leicht eine solche Konvertierungsfunktion implementiert werden kann. Dazu muss eine neue benutzerdefinierte Funktion erstellt werden. Der Typ muss "Funktion" sein und das Flag "Optionen" muss aktiviert werden. Zusätzlich muss ein Parameter vom Typ "String" hinzugefügt und der Rückgabetyp als "Spielverknüpfung - Fähigkeit" festgelegt werden:

Konvertiere String zu Spielverknüpfung (Fähigkeit)

Optionen: Funktion, Operator
Ausgabetyp: Spielverknüpfung - Fähigkeit
Parameter
String <String>
Grammatiktext: Fähigkeit(String)
Hinweistext: Konvertiert einen String in eine Fähigkeit.
Benutzerdefinierter Skript-Code

Beim benutzerdefinierten Script muss nun folgendes stehen:

(#PARAM(string))

Der gegebene Parameter "String" wird also einfach an die Stelle des Funktionsaufrufs kopiert. Mehr ist auch nicht nötig, da im Galaxy-Script alle Spielverknüpfungen als Strings dargestellt werden. Diese Funktion kann nun wie jede andere Konvertierungsfunktion verwendet werden.