Macros for Dummies - A MapTool Macro-Tutorial (german)

Doc requests, organization, and submissions

Moderators: dorpond, trevor, Azhrei

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

3.6 - Code und Text die Zweite

Wenn du etwas in der Chatbox oder sonst irgendwo (z. B. in einem Charakterbogen) ausgeben willst ist es meist sinnvoll wenn du Code und Text dabei kombinierst. Dafür gibt es mehrere Möglichkeiten, fangen wir doch mit der einfachsten an:

Code: Select all

Mein Name ist [r: getPlayerName()]
Du schreibst in deinem Makro also ganz normal den Text, und fügst den Code einfach an passender Stelle ein. Hier noch ein Beispiel:

Code: Select all

[r: getPlayerName()] hat eine [r: 1d6] gewuerfelt.
Bei der zweiten Möglichkeit verwendest du ausschließlich Code und integrierst den Text einfach. Funktionen und Text lassen sich generell mit einem einfachen + Zeichen verbinden. Hört sich kompliziert an? Ist es aber nicht. Hier wieder die zwei Beispiele:

Code: Select all

[r: "Mein Name ist " + getPlayerName()]

Code: Select all

[r: getPlayerName() + " hat eine " + 1d6 + " gewuerfelt."]
Die Leerzeichen im eigentlichen Code kannst du übrigens auch weglassen wenn du möchtest:

Code: Select all

[r: getPlayerName()+" hat eine "+1d6+" gewuerfelt."]
Die Leerzeichen im integrierten Text kannst du natürlich ebenfalls weglassen. Das sieht dann aber bei der Ausgabe in der Chatbox etwas gequetscht aus, meinst du nicht? Später zeige ich dir noch einen effektiveren Weg um Code und Text zu verbinden, aber dafür ist es jetzt noch zu früh. Probiere erst mal die Beispiele oben aus.
Last edited by Thargun on Tue Sep 29, 2015 4:03 pm, edited 1 time in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

3.7 - Die Syntax: Ein Wesen der dritten Art

Syntax. Noch so eine Fachsimpelei. Ein Wort das direkt aus einer chinesischen Buchstabensuppe zu stammen scheint. In Wirklichkeit ist es ganz simpel. Die Syntax ist ein System von Regeln die eingehalten werden müssen, damit der Parser deinen geschriebenen Makro-Code auch verstehen und richtig umsetzen kann.

Ein paar dieser Regeln kennst du schon, z. B. dass Code immer in eckigen Klammern stehen muss, oder dass Text im Code immer in doppelte Anführungszeichen eingeschlossen werden muss. Weitere Regeln lernst du später. Für den Moment wollen wir uns aber noch folgende Dinge anschauen:


Geschweifte Klammern {}

Das Code immer in eckigen Klammern stehen muss, ist ehrlich gesagt nicht ganz richtig, du kannst Code nämlich auch in geschweiften Klammern schreiben. Es gibt dabei allerdings zwei wichtige Unterschiede:

1. - Wenn du Code in geschweiften Klammer schreibst, wirkt das so als ob du die Roll Option result benutzen würdest. Es wird also immer gleich der Rückgabewert einer Funktion ausgegeben:

Code: Select all

{1d20}
wirkt also genauso wie

Code: Select all

[r: 1d20]
Ein paar weitere Beispiele:

Code: Select all

{1d6 + 5}

Code: Select all

{getPlayerName()}

Code: Select all

{"Das hier ist Text im Code."}
Und natürlich kannst du auch hier wieder Text und Code kombinieren:

Code: Select all

Mein Name ist {getPlayerName()}

Code: Select all

{getPlayerName()+" hat eine "+1d6+" gewuerfelt."}
Den Wert von Variablen oder Token-Properties kannst du ebenfalls auf diese Weise ausgeben. Was Variablen und Properties sind siehst du später noch. Aber hier schon mal ein Beispiel:

Code: Select all

[h: variable = "Nur ein Test."]
{variable}
2. - Wenn du geschweifte Klammern benutzt können keine weiteren Roll Options verwendet werden, sonst verursacht das einen Fehler. Hier ein Beispiel, probiere es ruhig mal aus:

Code: Select all

{h: 1d20}
Nachdem ich dir nun gezeigt habe wie man Code in geschweiften Klammern schreibt, sage ich dir: Lass es! Finger weg! Mach es nicht wenn du Alternativen hast! Machst du es doch, kann es zu Problemen bei Codeverzweigungen, Codeschleifen oder Codeverschachtelungen kommen (was das jetzt schon wieder alles ist siehst du noch früh genug). Zwar wirst du geschweifte Klammern später trotzdem benutzen, dann aber auf andere Art und Weise.


Verschachtelte Klammern

Du weißt nun, dass Code immer in eckige oder geschweifte Klammern eingeschlossen werden muss. Eine Verschachtelung dieser Klammern (abgesehen von normalen runden Klammern die ja nichts mit Code zu tun haben), ist aber nicht möglich. Folgende Beispiele funktionieren also nicht:

Code: Select all

[r: "Wuerfelwurf" [r: 1d20]]

Code: Select all

[r: "Wuerfelwurf:" {1d20}]

Code: Select all

{"Wuerfelwurf:" {1d20}}

Code: Select all

{"Wuerfelwurf:" [r: 1d20]}
Bei Codeverzweigungen und gleichzeitiger Anwendung der CODE Roll Option ist es dagegen sogar nötig, eckige und geschweifte Klammern auf eine bestimmte Art miteinander zu kombinieren. Aber das zeige ich dir wenn es soweit ist.


Zeilenumbrüche, Leerzeichen & Übersichtliche Makros

Der Parser ignoriert beim Lesen von Makros alle Zeilenumbrüche und überflüssige Leerzeichen. Das hier:

Code: Select all

[r: "Ein Affe "]
       sucht eine
   [r: " Banane"]
wird vom Parser also so gelesen:

Code: Select all

[r:"Ein Affe "]sucht eine[r:" Banane"]
Trotzdem solltest du in deinen Makros natürlich Zeilenumbrüche und Leerzeichen verwenden, sonst hättest du ja gar keine Übersicht mehr. Hier das Beispiel einer IF-Anweisung wie ich sie notiere (den Code musst du jetzt noch nicht verstehen):

Code: Select all

[r,if(10 < 20), code:
  {
    [r: "Die Zahl ist kleiner als 20"]
  };
  {
    [r: "Die Zahl ist nicht kleiner als 20"]
  }
]
Andere notieren sie vielleicht so:

Code: Select all

[r, if(10 < 20), code: {
  [r: "Die Zahl ist kleiner als 20"] 
  };{ 
  [r: "Die Zahl ist nicht kleiner als 20"] 
}]
Ich halte die erste Variante für übersichtlicher. Aber wie du am Ende deine Makros auch schreibst, achte auf folgende Dinge:
  • Halte deine Makros immer übersichtlich! Du, und auch fremde Leute die vielleicht deine Makros lesen, sollten leicht und schnell erkennen können was da vor sich geht, und wo Befehle anfangen und wieder enden.
  • Hast du dich für eine bestimmte Schreibweise entschieden, behalte sie auch bei! Nichts ist verwirrender als wenn du deine Makros mal auf die eine Art und Weise schreibst, und mal auf eine andere.

Syntaxfehler

Besonders Einsteiger machen wegen fehlender Routine gerne Syntaxfehler. Dein Makro will einfach nicht funktionieren? Dann überprüfe es als erstes auf solche Fehler. Vielleicht hast du nur irgendwo eine Klammer nicht geschlossen oder ein Komma vergessen. So einfach kann das manchmal sein.
Last edited by Thargun on Tue Sep 29, 2015 4:05 pm, edited 2 times in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

3.8 - Kommentare

Etwas das du dir von Anfang an angewöhnen solltest, ist es deine Makros zu kommentieren. Das bedeutet, dass du im Makro Kommentare hinzufügst, die beschreiben was da überhaupt passiert. Das scheint dir überflüssig zu sein? Ok, wenn dein Makro nur ein paar Zeilen hat stimmt das sogar, denn dann langt ein kurzer Blick um zu sehen was da abgeht. Jetzt stelle dir aber mal vor, du schreibst ein Makro mit irgendwas zwischen 50 und 500 Zeilen, was realistischer ist als du im Moment vielleicht glaubst. Meinst du, du kapierst auch noch ein Jahr später was du da zusammengebastelt hast, ohne den Code mindestens eine Stunde lang zu analysieren? Außerdem können dann auch andere Leute leicht erkennen was du da fabriziert hast, wenn sie mal deine Makros anschauen.

Dummerweise hat die MapTool Scriptsprache keine Kommentarfunktion. Aber HTML hat eine, und HTML kannst du auch in Makros benutzen. Das komische HTML-Ding habe ich ja schon mal am Anfang des Tutorials erwähnt, und später schauen wir uns das noch genauer an. Versprochen! Im Moment ist aber nur wichtig, dass du weißt wie Kommentare funktionieren. Hier ein Beispiel:

Code: Select all

<!-- Das ist ein Kommentar -->
Alles was zwischen <!-- und --> steht wird als Kommentar gewertet. Die gesamte Kommentarzeile wird zwar vom Parser gelesen, aber nicht in der Chatbox ausgegeben. Wichtig ist noch, dass innerhalb des Kommentars keine Makrobefehle stehen, denn die werden dann trotzdem vom Parser interpretiert und ausgeführt. Also z. B. so etwas hier:

Code: Select all

<!-- Das ist ein schlechter Kommentar mit Wuerfelfunktion [1d20] -->
Leider versteht sich der MapTool-Parser mit dem HTML-Kommentar nicht sonderlich gut. Irgendwann hatten die mal Streit, wegen einer Frau oder so, und haben die Sache bis heute nicht ordentlich ausdiskutiert. Das führt zum einen dazu, dass bei einem HTML-Kommentar eventuell trotzdem eine leere Zeile in der Chatbox ausgegeben wird, und zum anderen dazu, dass der Stack-Speicher stärker als nötig belastet wird. Was Letzteres bedeutet erfährst du später. Damit es aber gar nicht erst zu Problemen kommt, notiere Kommentare in Makros immer auf folgende Weise:

Code: Select all

[h: "<!-- Das ist ein Kommentar -->"]
Damit hättest du einen versteckten Kommentar der wunderbar funktioniert. Und so könnte das dann in einem Makro aussehen:

Code: Select all

[h: "<!-- Den Namen des Spielers im Chat ausgeben -->"]

[r: getPlayerName() + " wuerfelt mit einem W6."]

[h: "<!-- Wuerfelwurf und Ausgabe des Ergebnisses im Chat -->"]

[r: "Das Ergebnis des Wurfs ist " + 1d6]
Natürlich musst du nicht jede einzelne Zeile oder jede Funktion kommentieren. Füge Kommentare einfach da ein wo sie dir sinnvoll und wichtig erscheinen. Bedenke dabei immer, dass vielleicht auch fremde Leute deine Makros lesen und verstehen wollen. Mit der Zeit bekommst du dann schon ein Gefühl dafür.
Last edited by Thargun on Tue Sep 29, 2015 4:05 pm, edited 1 time in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

3.9 - Trusted Makros

Makros sind richtige kleine Miststücke. Wenn du nicht aufpasst trinken sie dein letztes kühles Bier weg und rülpsen dir anschließend noch ins Gesicht. Damit du über die hinterhältigen Biester nicht die Kontrolle verlierst, und sie dir nicht auf der Nase herumtanzen, brauchst du einen Spitzel der dich über ihre geheimen Pläne informiert. Also ein Makro dem du vertrauen kannst.

Ok, ganz so schlimm ist es eigentlich nicht. Aber vertrauenswürdige Makros gibt es tatsächlich. Manche Funktionen und Parameter (Zusatzangaben zu den Funktionen) können nur in diesen vertrauenswürdigen Makros, den Trusted Makros benutzt werden. Damit ein normales Makro zu einem Trusted Makro wird, müssen ein paar Bedingungen erfüllt sein:

1. - Das Makro darf nicht von Spielern editierbar sein. Um das zu erreichen wechsele im Makro-Editor auf den Tab "Optionen" und entferne das Häkchen bei "Spielern Makrobearbeitung erlauben":

Image

2. - Das Makro darf kein anderes Makro aufrufen das nicht Trusted ist, sonst wird es selbst zu einem Untrusted Makro.

Die genauen Bedingungen hängen außerdem davon ab an welchem Ort das Makro gespeichert ist, und ob es vom GM oder von einem Spieler aufgerufen wird. Eine vollständige Übersicht wann ein Makro Trusted ist und wann nicht findest du in der MapTool-Wiki.

Und warum der ganze Aufwand? Kurz gesagt kann damit z. B. verhindert werden, dass normale Spieler Zugriff auf Dinge haben, in die sie ihre Nase eigentlich gar nicht reinstecken sollten, ihnen aber auch Zugriff auf Funktionen gewähren, die sie normalerweise nicht nutzen könnten. Das hört sich im ersten Moment kompliziert an, aber mit steigender Erfahrung wirst du schon bald hinter das Geheimnis kommen.

Tipp 1: Solange kein Grund dagegen spricht solltest du "Spielern Makrobearbeitung erlauben" in jedem Makro gleich deaktivieren, sonst wunderst du dich später vielleicht warum eine bestimmte Funktion nicht das tut was du möchtest. Damit du das nicht jedes Mal manuell machen musst, kannst du in den MapTool-Einstellungen auch als Standard festlegen, dass diese Option in neu erstellten Makros erst gar nicht aktiviert ist.

Tipp 2: Wenn eine Funktion oder ein Funktionsparameter ein Trusted Makro benötigt, findest du bei der jeweiligen Funktionsbeschreibung in der MapTool-Wiki immer einen deutlich markierten Hinweis darauf.

Tipp 3: Ob dein Makro Trusted ist oder nicht kannst du auch mit der Funktion isTrusted() überprüfen.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4 - Variablen: Die großen Unbekannten

4.1 - Was ist eine Variable?

Egal wie viel du auch über Makros lernst, wenn du keine Variablen benutzt macht das alles eigentlich gar keinen Sinn. Das wäre wie ein Lagerhaus in dem du die Kisten nie wieder öffnen oder bewegen kannst, wenn du sie erst einmal eingelagert hast. Was also ist eine Variable überhaupt? Gute Frage, denn eine Variable kann tatsächlich alles Mögliche sein.

Wenn du ein neues Makro schreibst existieren noch keine Variablen in diesem Makro, du musst sie erst erstellen. Stelle dir eine Variable wie eine leere Holzkiste vor in die du wirklich alles reinpacken kannst. Das kann z. B. Text sein, eine Zahl, das Ergebnis eines Würfelwurfs oder der Rückgabewert einer beliebigen Funktion. Das Lustige an der Geschichte: Manchmal weißt du selbst nicht genau was in der Kiste steckt.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.2 - Der Name einer Variable

Wenn du eine Variable erstellst willst du später damit ja auch irgendetwas machen, z. B. ihren Inhalt ändern oder in der Chatbox ausgeben. Deshalb braucht jede Variable einen Namen, damit du sie wiederfindest und benutzen kannst. Den Namen jeder Variable kannst du dir frei aussuchen, musst dabei aber ein paar Regeln beachten:
  • Der Name darf keine Leerzeichen enthalten.
  • Sonderzeichen, ausser einem normalen Punkt (.), sind ebenfalls verboten.
  • Der Name muss innerhalb eines Makros einmalig sein. Andere Variablen innerhalb desselben Makros müssen also einen anderen Namen haben.
  • Der Name darf, ungeachtet von Groß- und Kleinschreibung, nicht mit dem Namen eines Token-Properties übereinstimmen.
  • Der Name darf, ungeachtet von Groß- und Kleinschreibung, nicht mit dem Namen einer Spezial-Variable übereinstimmen.
Was Token-Properties und Spezial-Variablen sind zeige ich dir später. Keine feste Regel, aber bei der Namensgebung unbedingt zu empfehlen, sind außerdem folgende Tipps:
  • Beginne den Namen einer Variable immer mit einem Kleinbuchstaben. Das hilft dir später Variablen von Token-Properties besser zu unterscheiden.
  • Wähle immer einen aussagekräftigen Namen für deine Variablen, und scheue dabei auch nicht davor zurück längere Variablennamen zu benutzen.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.3 - Eine Variable erstellen

In Ordnung, dann lasse uns mal ein paar Variablen erstellen. Das funktioniert nach einem ganz einfachen Schema:

Code: Select all

Variablenname = Wert
Der Wert ist das was in die Holzkiste, also in die Variable, hineingepackt werden soll. Dieses "Hineinpacken" nennt sich auch zuordnen oder die Variable definieren. Um nun einen beliebigen Wert einer Variable zuzuordnen benutzen wir einfach das Gleichheitszeichen (=). Und weil du bestimmt nicht willst, dass die Prozedur in der Chatbox ausgegeben wird, benutzt du auch noch die Roll Option hide zum Erstellen.

Ok, denke dir jetzt eine beliebige Zahl zwischen 1 und 1000 aus und ordne diese Zahl einer Variable zu. Ich nehme die 18:

Code: Select all

[h: zahl = 18]
Das war schon der ganze Zaubertrick, in der Holzkiste befindet sich nun die Zahl 18. Oder besser ausgedrückt: Die Variable mit dem Namen "zahl" besitzt nun den Wert "18". Und was machen wir jetzt damit? Wir geben die Variable in der Chatbox wieder aus, schauen also was sich in der Holzkiste befindet. Der gesamte Code für das Makro lautet dann folgendermaßen:

Code: Select all

[h: zahl = 18]
[r: zahl]
Wie du in der zweiten Zeile siehst, musst du einfach nur den Namen der Variable angeben, damit ihr Wert in der Chatbox ausgegeben wird. Na los! Ausprobieren!

Natürlich kannst du nicht nur Zahlen einer Variable zuordnen. Wie wäre es mit ein wenig Text?

Code: Select all

[h: hinweisText = "Variablen sind garnicht so kompliziert."]
[r: hinweisText]
Oder vielleicht lieber eine Funktion?

Code: Select all

[h: spielerName = getPlayerName()]
[r: spielerName]
Selbstverständlich kannst du auch hier wieder Text und Funktionen kombinieren:

Code: Select all

[h: wuerfelergebnis = getPlayerName()+" hat eine "+1d6+" gewuerfelt."]
[r: wuerfelergebnis]
Bei der Ausgabe in der Chatbox musst du dich auch nicht auf eine Variable beschränken. Variablen lassen sich wie Code und Text miteinander kombinieren, denn eine Variable ist nichts anderes als ein Stück Code. Zwei Beispiele:

Code: Select all

[h: spielerName = getPlayerName()]
[h: wuerfelwurf = 1d6]
[r: spielerName+" wuerfelt eine "+wuerfelwurf]

Code: Select all

[h: spielerName = getPlayerName()]
[h: zwischentext = " wuerfelt eine "]
[h: wuerfelwurf = 1d6]
[r: spielerName + zwischentext + wuerfelwurf]
Schlussendlich kannst du auch eine leere Variable definieren, da ist dann nichts drinnen. Mache dir jetzt noch keine Sorgen für was das nützlich sein könnte, schaue es dir einfach mal an:

Code: Select all

[h: leereVariable = ""]
Wichtig: Wenn du einer Variable eine Zahl zuordnen willst, mache es wie im ersten Beispiel. Also:

Code: Select all

[h: zahl = 18]
Wenn du dagegen diese Variante verwendest

Code: Select all

[h: zahl = "18"]
wird die 18 vom Parser nicht als Zahl erkannt, sondern als Text. Der Parser ist da zwar sehr großzügig was die Interpretation angeht, trotzdem kann es unter gewissen Umständen zu Problemen führen.
Last edited by Thargun on Tue Sep 29, 2015 4:06 pm, edited 1 time in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.4 - Noch mehr Variablen

Da eine Variable ja Code ist, kannst die sie auch beim Erstellen einer Variable benutzen und mit Funktionen, Text oder weiteren Variablen kombinieren:

Code: Select all

[h: wuerfelwurf = 1d6]
[h: probe = getPlayerName()+" wuerfelt eine "+wuerfelwurf]
[r: probe]

Code: Select all

[h: spielerName = getPlayerName()]
[h: zwischentext = " wuerfelt eine "]
[h: wuerfelwurf = 1d6]
[h: probe = spielerName + zwischentext + wuerfelwurf]
[r: probe]
Das Schöne an Variablen ist, dass ihr Inhalt nicht festgelegt ist. Das bedeutet, dass du den zugeordneten Wert einer Variable jederzeit ändern kannst. Probiere es mal hiermit:

Code: Select all

[h: wasserstand = "Ich habe noch 1 Liter Wasser."]
[r: wasserstand]
[h: wasserstand = "Ich habe etwas getrunken und jetzt noch einen halben Liter Wasser."]
[r: wasserstand]
Wie du siehst wird die Variable "wasserstand" zweimal ausgegeben (Zeile 2 und 4). In Zeile 3 definierst du die Variable aber komplett neu, wodurch bei der zweiten Ausgabe ein anderer Text in der Chatbox erscheint als bei der ersten Ausgabe, bei der die Variable noch einen anderen Wert hatte.

Es ist natürlich nicht immer sinnvoll einer Variable einen komplett neuen Wert zuzuordnen, oft wirst du wahrscheinlich eher zwei verschiedene Variablen erstellen. Interessanter wird es z. B. bei Codeverästelungen oder wenn du später noch weitere Methoden kennenlernst um den Wert einer Variable zu ändern. Aber alles zu seiner Zeit.

Wenn du eine neue Variable erstellst, oder einer bereits bestehenden Variable einen komplett neuen Wert zuordnen möchtest, kannst du dafür auch den Wert einer anderen, bereits bestehenden Variable benutzen. Beispiele:

Code: Select all

[h: wuerfelwurf = 1d6]
[h: endergebnis = wuerfelwurf]
[r: endergebnis]

Code: Select all

[h: aktuelles.Beispiel = "Dies ist der aktuelle Beispieltext."]
[h: neues.Beispiel = "Dies ist der neue Beispieltext"]
[h: aktuelles.Beispiel = neues.Beispiel]
[r: aktuelles.beispiel]
Wenn der Inhalt einer Variable eine Zahl ist, lässt sich diese auch ohne Zwischenschritte ändern:

Code: Select all

[h: zauberpunkte = 30]
[h: zauberpunkte = zauberpunkte - 5]
[r: zauberpunkte]
Die Magie geschieht in Zeile 2: Der neue Wert für "zauberpunkte" ist gleich der alte Wert für "zauberpunkte" abzüglich 5.

Bisher hast du immer die Roll Option hide benutzt um eine Variable zu erstellen. Es kann aber auch sinnvoll sein result zu benutzen. Z. B. dann, wenn du die Variable zwar später noch ändern und weiterverwenden willst, den beim Erstellen zugeordneten Wert aber auch gleich ausgeben möchtest:

Code: Select all

[r: wasserstand = "Ich habe 1 Liter Wasser. Aber ich bin durstig, das wird sich also bald aendern."]
Wenn du also result beim Definieren einer Variable verwendest wird der zugeordnete Wert sofort in der Chatbox ausgegeben. Jetzt hast du es bestimmt gemerkt: So hättest du in jedem Beispiel dieses Kapitels jeweils die letzte Zeile sparen können. Aber das waren ja auch nur Beispiele.
Last edited by Thargun on Tue Sep 29, 2015 4:07 pm, edited 1 time in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.5 - Kann man Variablen löschen?

Nein, das geht nicht. Du kannst eine Variable jederzeit neu definieren und ihr einen neuen Wert zuordnen, du kannst sie sogar zu einer leeren Variable machen, aber so richtig löschen kannst du sie nicht. Das ist aber auch gar nicht nötig. Wenn du eine bereits erstellte Variable nicht mehr brauchst, greifst du einfach nicht mehr darauf zu. Außerdem wirken Variablen immer nur innerhalb eines bestimmten Makros, und ist das Makro durchgelaufen gibt es auch die Variable nicht mehr.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.6 - Variablen sind lokal begrenzt

Eine Variable existiert immer nur innerhalb des Makros, in dem du sie erstellt hast. Deswegen sagt man auch es handelt sich um lokale Variablen. Von anderen Makros aus kannst du also nicht auf diese Variable zugreifen. Lasse uns das etwas genauer anschauen:

Nehmen wir an du schreibst zwei verschiedene Makros: Makro 1 und Makro 2. Wenn du nun in Makro 1 die Variable "wasserstand" erstellst, kannst du auch nur in Makro 1 darauf zugreifen und damit arbeiten. In Makro 2 existiert diese Variable einfach nicht. Umgekehrt gilt das natürlich genauso.

Du könntest jetzt in Makro 2 ebenfalls eine Variable mit dem Namen "wasserstand" erstellen, und wenn du möchtest ihr sogar den gleichen Wert zuweisen wie der Variable in Makro 1. Trotzdem sind und bleiben es zwei verschiedene Variablen, auf die du nur in den jeweils zugehörigen Makros zugreifen kannst.

Oder stelle dir es doch vor als ob du im Wohn- und im Schlafzimmer (beide schalldicht) den gleichen CD-Player (ohne Fernbedienung) stehen hast. Du kannst beide benutzen und sogar in beide die gleiche CD einlegen. Trotzdem spielen beide ihre eigene Musik, und die kannst du nur hören oder ändern wenn du auch im jeweiligen Raum bist.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.7 - Usereingaben in Variablen speichern

Für das, was wir bisher mit Variablen gemacht haben, bräuchten wir sie eigentlich gar nicht. Schließlich haben wir so oder so immer nur feste, vorher eingegebene Werte benutzt. Richtig spannend wird es erst wenn wir gar nicht wissen welchen Wert eine Variable haben wird, sondern das bei jedem Aufruf des Makro beliebig festlegen können.

Als erstes Beispiel wirst du ein einfaches Makro schreiben bei dem der Nutzer seinen Namen angeben kann:

Code: Select all

Mein Name ist [r: spielerName].
Fällt dir etwas auf? Das Makro benutzt die Variable "spielerName" und gibt deren Wert in der Chatbox aus. Aber wie soll das gehen wenn du der Variable doch vorher keinen Wert zugeordnet hast? Eigentlich gar nicht. Das merkt aber auch der Parser und fragt beim Ausführen des Makros einfach nach, welchen Wert die Variable haben soll. Probiere es aus und gib in dem kleinen Fenster das erscheint deinen Namen ein.

Als nächstes Beispiel basteln wir ein kleines Würfelmakro, bei dem mit beliebig vielen W20 gewürfelt werden kann. Dafür nutzen wir eine neue Funktion:

Code: Select all

roll(times, sides)
roll() ist die eigentliche Funktion zum Würfeln. times und sides sind Parameter, also Zusatzangaben zur Funktion. times steht dabei für die Anzahl der Würfel, und sides für die Seitenanzahl des Würfels. Du kannst für die Parameter beliebige Zahlen einsetzen, probiere es mal:

Code: Select all

[r: roll(3, 20)]
In diesem Fall wird also mit drei 20-seitigen Würfeln gewürfelt (3W20). Statt Zahlen kannst du als Parameter aber auch Variablen einsetzen:

Code: Select all

[h: wuerfel.anzahl = 3]
[h: wuerfel.seiten = 20]
[r: roll(wuerfel.anzahl, wuerfel.seiten)]
Jetzt ändere das nochmal, damit der Nutzer des Makros nach der Anzahl der Würfel gefragt wird:

Code: Select all

[h: wuerfel.seiten = 20]
[r: roll(wuerfel.anzahl, wuerfel.seiten)]
Du siehst: Der Variable wuerfel.anzahl wird kein Wert zugeordnet. Der Parser fragt beim Ausführen des Makros also nach, und du kannst die Würfelanzahl jedes Mal neu bestimmen.

Die in diesem Kapitel vorgestellte Methode der Usereingabe reicht aus wenn es darum geht ein oder zwei Werte in einem Makro vom User bestimmen zu lassen. Besonders elegant ist sie aber nicht gerade. Der User sieht nur dieses seltsame kleine Fenster, und hat nur den kryptischen Namen der Variable als Hinweis was er da überhaupt eingeben soll. Und jetzt stelle dir mal vor es geht nicht darum einen Wert einzugeben, sondern vielleicht drei, fünf oder zehn. Das wird dann ganz schön mühselig und unübersichtlich.

Später zeige ich dir bessere Methoden zur Usereingabe, aber für den Moment soll das reichen, und du weißt schon mal wie das Prinzip funktioniert.
Last edited by Thargun on Tue Sep 29, 2015 4:07 pm, edited 1 time in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.8 - Datentypen: Eine kleine Übersicht

Wenn du z. B. einer Variable einen Wert zuordnest, dann ist dieser Wert auch immer von einer bestimmten Art, bzw. von einem bestimmten Datentyp. Es ist wichtig zu wissen welchen Datentyp ein Wert besitzt, denn nur so kannst du den Wert richtig behandeln und damit umgehen. Das hört sich schon wieder viel komplizierter an als es eigentlich ist. Schauen wir doch einfach mal rein.


Zahlen

Das sollte ziemlich klar sein. Egal ob ganze Zahlen wie 1, 15 und 4369, negative Zahlen wie -5 und -126, oder Kommazahlen wie 1.4 und 32.562: Sie alle gehören zum Datentyp "Zahl". Beispiele:

Code: Select all

[beispiel.zahl = 15]

Code: Select all

[beispiel.zahl = -22]
String

Bisher habe ich immer von Code oder Text gesprochen, oder von Text der in Code integriert wurde. Letzteres ist eigentlich nicht ganz richtig. Tatsächlich handelt es sich dabei auch um einen bestimmten Datentyp, nämlich den "String".

Ein String ist einfach eine beliebige Kette von alphanumerischen Zeichen die in doppelte Anführungszeichen eingeschlossen wird. Zu alphanumerischen Zeichen gehören alle Buchstaben, Ziffern, und im weiteren Sinne auch Sonderzeichen wie z. B. Punkte, Kommata oder Bindestriche. Hier einige Beispiele:

Code: Select all

[beispiel.string = "Test"]

Code: Select all

[beispiel.string = "Dies ist ein Beispiel fuer einen String."]

Code: Select all

[beispiel.string = "123 Kuehe & 2 Katzen trinken eine Menge Wasser. - Richtig?"]
In der MapTool-Wiki findest du eine Liste aller String-Funktionen, mit denen du Strings z. B. ändern oder manipulieren kannst. Wenn du Kapitel 5 - Funktionen und wie sie funktionieren - beendet hast, stöbere ein wenig in der Liste und probiere ein paar dieser Funktionen aus.


Weitere Datentypen

Die folgenden Datentypen erwähne ich im Moment nur der Vollständigkeit halber. Wir werden sie uns später noch genauer anschauen.
  • String List
  • String Property List
  • JSON Array
  • JSON Object
Last edited by Thargun on Tue Sep 29, 2015 4:08 pm, edited 1 time in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

4.9 - Spezial-Variablen

Es gibt in MapTool eine Reihe von Spezial-Variablen die für bestimmte Aufgaben reserviert sind. Wenn du neue Variablen erstellst darfst du deshalb nie den Namen einer Spezial-Variablen verwenden. Natürlich kannst du die Spezial-Variablen trotzdem nutzen. Auch wenn sie alle sehr verschiedene Aufgaben haben können schauen wir uns einfach mal ein Beispiel an.

In der Spezial-Variable token.name wird immer der Name eines Tokens gespeichert. Genauer gesagt der Name des aktuellen Tokens, aber dazu kommen wir erst noch. Du kannst diese Variable also nutzen um diesen Tokennamen in der Chatbox auszugeben, oder den Tokennamen einer von dir selbst erstellten Variable zuzuordnen. Du kannst sogar den Wert von token.name ändern, dann ändert sich tatsächlich auch der Name des Tokens.

Später nehmen wir einige Spezial-Variablen etwas genauer unter die Lupe. Im Moment langt es aber wenn du weißt, dass es sie gibt. In der MapTool-Wiki findest du eine Liste aller Spezial-Variablen. Wenn du möchtest kannst du ja schon mal reinschnuppern, dann weißt du zumindest welche Namen du bei selbst erstellten Variablen nicht benutzen darfst.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

5 - Funktionen und wie sie funktionieren

5.1 - Der Rückgabewert

Funktionen sind eine wichtige Sache beim Schreiben von Makros, denn du wirst sie sehr häufig verwenden. Jede Funktion bewirkt etwas anderes, und wenn du sie benutzt, liefert sie dir immer etwas zurück: Das Ergebnis der Funktion, auch Rückgabewert genannt.

Manche Funktionen liefern dir ein ganz spezielles Ergebnis zurück. getPlayerName(), eine Funktion die du ja schon kennst, liefert z. B. den Namen des Spielers zurück der das Makro ausführt:

Code: Select all

[r: getPlayerName()]
Ziehe mal einen neuen Token auf die Spieloberfläche, markiere den Token mit der Maus, und führe folgende Funktion aus:

Code: Select all

[r: getSelected()]
Auch bei dieser Funktion wird dir ein ganz spezielles Ergebnis zurückgeliefert, nämlich die ID des aktuell markierten Tokens. Ja, ich weiß, auf dem Bildschirm erscheint nur eine wirre Zeichenfolge, aber so sieht eine ID eben aus.

Jetzt klicke mit der Maus mal irgendwo auf die Spieloberfläche damit der Token nicht mehr markiert ist, und führe dann die Funktion getSelected() erneut aus. Wie du siehst, siehst du nichts. Da kein Token markiert ist kann auch keine ID zurückgeliefert werden. Aber auch wenn es nicht danach aussieht wird in diesem Fall trotzdem etwas zurückgeliefert, nämlich ein leeres Ergebnis. Merke dir das schon mal.

Hinweis: Jeder Token auf der Spieloberfläche hat, unabhängig von seinem Namen oder anderen Eigenschaften, eine einmalige ID (Identifikationsnummer), mit der sich der Token von anderen Tokens unterscheiden lässt. Diese ID kann in vielen Funktionen auch als Parameter angegeben werden um ein Token direkt "anzusprechen".

Manche Funktionen liefern aber auch kein spezielles Ergebnis zurück, sondern einfach nur den Wert "1" oder "0". Eine "1" steht dabei für True (auf Deutsch: wahr oder richtig) und eine "0" für False (auf Deutsch: unwahr oder falsch).

Mit der Funktion hasImpersonated() lässt sich z. B. feststellen, ob der Spieler der das Makro ausführt gerade einen Token verkörpert hat (impersonated) oder nicht. Probiere es aus:

Code: Select all

[r: hasImpersonated()]
Als Rückgabewert erhältst du eine "0" (False), weil du gerade keinen Token verkörperst. Jetzt verkörpere einen Token (Rechtsklick auf Token --> Impersonate), und führe die Funktion erneut aus. Nun wirst du eine "1" (True) als Rückgabewert erhalten, da du jetzt einen Token verkörperst.

Hinweis: Achte darauf, dass auch der Rückgabewert immer einen bestimmten Datentyp besitzt. getPlayerName() gibt z. B. einen String zurück, während hasImpersonated() eine Zahl zurückgibt.
Last edited by Thargun on Tue Sep 29, 2015 4:08 pm, edited 1 time in total.

Thargun
Giant
Posts: 188
Joined: Sun Sep 14, 2014 4:27 am

Re: Macros for Dummies - A guide to MapTool-Macros (german)

Post by Thargun »

5.2 - Parameter

Ein Parameter ist eine zusätzliche Angabe zu einer Funktion. Diese zusätzliche Angabe, die immer einen bestimmten Wert enthält, wird von der Funktion berücksichtigt wenn sie ihr Ergebnis, also den Rückgabewert, zurückliefert.

Bei manchen Funktionen können keine Parameter angegeben werden, bei anderen ist es zwingend notwendig, und bei wieder anderen ist es rein optional. Das kommt immer auf die entsprechende Funktion an, genauso wie die mögliche Anzahl und Art (Datentyp) der Parameter. Mehrere Parameter werden normalerweise durch Kommata (,) getrennt. Das hört sich für dich alles nach Fachchinesisch an? Keine Panik, nach ein paar Beispielen wird es deutlicher.

Mit der Funktion max() lässt sich die größte bzw. höchste Zahl aus mehreren Zahlen herausfinden. Dafür werden alle zu prüfenden Zahlen als Parameter angegeben. Logischerweise muss der Datentyp aller Parameter dann auch "Zahl" sein. Mindestens ein Parameter muss angegeben werden, sinnvoll wird es aber natürlich erst mit zwei oder mehr Parametern.

Code: Select all

[r: groesste.Zahl = max(2, 50, -3, 15)]
Der Rückgabewert der Funktion ist die größte Zahl, also 50.

Mit der Funktion length() lässt sich feststellen wie viele Zeichen ein String (also eine Zeichenkette) enthält. Es wird ein Parameter von Datentyp "String" benötigt.

Code: Select all

[r: anzahl.Zeichen = length("abcdef")]
Der String enthält sechs Zeichen, der Rückgabewert der Funktion ist also 6.

Jetzt ziehe zwei oder mehr Tokens auf die Spieloberfläche und füge sie der Initiativeliste hinzu. Mit der Funktion removeAllFromInitiative() kannst du nun alle Tokens aus der Initiativeliste entfernen. Parameter sind hier nicht nötig. Zwar liefert die Funktion auch einen Rückgabewert, nämlich die Anzahl der Tokens die entfernt wurden, aber da uns der nicht interessiert speichern wir den Rückgabewert nicht in einer Variable, sondern führen einfach nur die Funktion aus:

Code: Select all

[h: removeAllFromInitiative()]
Denke daran, dass als Parameter immer auch Variablen erlaubt sind. Selbstverständlich muss der Wert in der Variable vom passenden Datentyp sein. Ein Beispiel:

Mit der Funktion startsWith() lässt sich feststellen ob ein String mit einem oder mehreren bestimmten Zeichen, also einem bestimmten Substring beginnt. Es werden zwei Parameter benötigt, beide von Datentyp String. Das Format:

Code: Select all

startsWith(string, substring)
Jetzt als Makro:

Code: Select all

[r: gleicher.Anfang = startsWith("Tutorial", "Tu")]
Der Rückgabewert ist "1" (True), da Tutorial tatsächlich mit Tu beginnt. Jetzt kannst du aber auch einen oder beide Parameter durch Variablen ersetzen:

Code: Select all

[h: parameter1 = "Tutorial"]
[h: parameter2 = "Tu"]
[r: gleicher.Anfang = startsWith(parameter1, parameter2)]
Hier noch ein Beispiel. Wir verwenden erneut die Funktion max() von weiter oben.

Code: Select all

[h: zahl1 = 50]
[h: zahl2 = -3]
[r: groesste.Zahl = max(2, zahl1, zahl2, 15)]
Last edited by Thargun on Tue Sep 29, 2015 4:08 pm, edited 1 time in total.

Post Reply

Return to “Documentation Requests/Discussion”