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 »

5.3 - Die kleine Mathe-Ecke

Wenn du glaubst wir ziehen hier jetzt einen Mathe-Leistungskurs durch kann ich dich beruhigen. Ich möchte dir nur ein paar grundlegende Dinge zeigen wie du mit Makros rechnen kannst. Das funktioniert wie ein einfacher Taschenrechner:

Code: Select all

[r: 5+5]
Mathematische Regeln wie z. B. "Punkt- vor Strichrechnung" oder "Klammerrechnung" gelten natürlich auch in Makros:

Code: Select all

[r: 5+3*2]

Code: Select all

[r: 10-5+(8/2)]
Statt ganzer Zahlen kannst du selbstverständlich auch Kommazahlen benutzen. Verwende als Dezimaltrennzeichen aber immer einen Punkt (.) statt einem Komma, sonst gibt es nur eine Fehlermeldung. Beispiel:

Code: Select all

[r: 1.3 + 1.2]
Wie alles andere auch kannst du Rechnungen ebenfalls in Variablen speichern:

Code: Select all

[h: addition = 5+5]
[r: addition]
Du kannst sogar mit Variablen rechnen. Aber achte darauf, dass in diesen Variablen dann auch nur Zahlen und kein Text gespeichert sind, sonst wird es nicht funktionieren. Beispiele:

Code: Select all

[h: zahl1 = 20]
[h: zahl2 = 30]
[r: zahl1 + zahl2]

Code: Select all

[h: zahl1 = 30+30]
[h: zahl2 = 6]
[h: division = zahl1 / zahl2]
[r: division]
Wenn du über die Grundrechenarten hinaus willst gibt es noch ein paar Funktionen die du nutzen kannst. Z. B. die Funktion zum Runden einer Zahl:

Code: Select all

round(value, precision)
Wie du siehst hat die Funktion zwei mögliche Parameter. "value" steht für die Zahl die du runden möchtest und wird zwingend benötigt. "precision" steht für die Stellen hinter dem Komma, auf die du runden möchtest. "precision" ist optional. Wenn du diesen Parameter weglässt wird immer auf eine ganze Zahl gerundet. Hier zwei Beispiele:

Code: Select all

[r: round(1.34, 1)]
Gibt "1.3" zurück.

Code: Select all

[r: round(1.34)]
Gibt "1" zurück.

In der MapTool-Wiki findest du eine Liste aller mathematischen Funktionen die dir zur Verfügung stehen. Stöbere ein wenig darin herum und probiere das eine oder andere auch mal aus.
Last edited by Thargun on Tue Sep 29, 2015 4:09 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.4 - Verschachtelte Funktionen

Funktionen und andere Codeteile lassen sich oft auch verschachteln. Du kannst z. B. als Parameter einer Funktion auch eine andere Funktion einsetzen, und das sogar ohne die zweite Funktion vorher in einer Variable gespeichert zu haben.

Hier ein Beispiel bei dem wir von zwei Zahlen die größere herausfinden wollen. Die Funktion max() kennst du ja bereits.

Code: Select all

[r: max(25, 50)]
Machen wir es etwas komplizierter und nehmen als zweiten Parameter statt der Zahl 50 die Zahl 50.45 in einer Variable, die wir vorher noch Runden:

Code: Select all

[h: zahl = 50.45]
[h: gerundete.Zahl = round(zahl)]
[r: max(25, gerundete.Zahl)]
Jetzt rationalisieren wir Zeile 2 einfach weg und setzen die Funktion zum Runden als Parameter ein:

Code: Select all

[h: zahl = 50.45]
[r: max(25, round(zahl))]
Diese Verschachtelungen können noch viel komplexere Ausmaße annehmen. Doch obwohl du dir damit etwas Schreibarbeit sparst, gibt es auch eine Schattenseite: weniger Übersicht. Verschachtelten Code zu lesen und zu verstehen ist natürlich schwieriger als wenn die Befehle einzeln aufgeführt sind. Daher werden wir im Rahmen dieses Tutorials möglichst auf Verschachtelungen verzichten. Wenn du später mehr Erfahrung und einen besseren Blick für Code hast, hindert dich aber natürlich nichts daran diese Methode einzusetzen.
Last edited by Thargun on Tue Sep 29, 2015 4:09 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.5 - strformat(): Praktischer geht es nicht

Eine sehr nützliche Funktion sollten wir uns noch genauer anschauen. Stelle dir vor du fragst in einem Makro den Benutzer nach Namen, Geburtsdatum und Alter, und möchtest das dann alles zusammen in einer Variable speichern um es später im Chat auszugeben. Dann ist die folgende Methode nicht gerade benutzerfreundlich, und vor allem nicht sehr übersichtlich:

Code: Select all

[h: name = getPlayerName()]
[h: alter = 28]
[h: geburt.tag = 15]
[h: geburt.monat = "Mai"]
[h: geburt.jahr = 1977]

[h: ausgabe = "Dein Name ist "+name+", du bist "+alter+" Jahre alt und wurdest am "+geburt.tag+". "+geburt.monat+" "+geburt.jahr+" geboren."]

[r: ausgabe]
Leichter, und vor allem übersichtlicher, geht es mit der Funktion strformat(). Mit dieser Funktion lassen sich Strings formatieren und Variablen direkt einsetzen. Dabei stehen dir zwei mögliche Wege zur Verfügung.

Schauen wir uns die erste Methode an:

Code: Select all

[h: name = getPlayerName()]
[h: alter = 28]
[h: ausgabe = strformat("Dein Name ist %{name} und du bist %{alter} Jahre alt.")]
[r: ausgabe]
Wie du siehst wird als Parameter der gewünschte String angegeben. Du kannst in diesem String an beliebigen Stellen Variablen einfügen. Schreibe sie einfach in geschweifte Klammern und setze ein Prozentzeichen (%) davor.

Bei der zweiten Methode gibst du statt der Variablen nur ein "%s" an und notierst die einzusetzenden Variablen durch Kommata getrennt hinter dem String:

Code: Select all

[h: name = getPlayerName()]
[h: alter = 28]
[h: ausgabe = strformat("Dein Name ist %s und du bist %s Jahre alt.", name, alter)]
[r: ausgabe]
Beim ersten "%s" wird die erste angegebene Variable eingesetzt, beim zweiten "%s" die an zweiter Stelle angegebene Variable usw. Diese Methode sollte von dir bevorzugt eingesetzt werden, da sie saubereren Code erzeugt, keine geschweiften Klammer nutzt (und damit Fehlern vorgebeugt) und bei größeren Strings leichter zu lesen ist. Übrigens kannst du statt Variablen auch Funktionen angeben:

Code: Select all

[h: alter = 28]
[h: ausgabe = strformat("Dein Name ist %s und du bist %s Jahre alt.", getPlayerName(), alter)]
[r: ausgabe]
Und jetzt wiederholen wir das erste Beispiel ganz oben, nutzen dieses Mal aber strformat():

Code: Select all

[h: name = getPlayerName()]
[h: alter = 28]
[h: geburt.tag = 15]
[h: geburt.monat = "Mai"]
[h: geburt.jahr = 1977]

[h: ausgabe = strformat("Dein Name ist %s, du bist %s Jahre alt und wurdest am %s. %s %s geboren.", name, alter, geburt.tag, geburt.monat, geburt.jahr)]

[r: ausgabe]
Das sieht doch schon viel besser aus, oder? strformat() besitzt noch viele weitere Möglichkeiten zur Formatierung von Strings. Schaue dir die Funktion mal in der MapTool-Wiki an.
Last edited by Thargun on Tue Sep 29, 2015 4:10 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 »

6 - Datentypen im Detail

6.1 - Zahlen & Strings

Was Datentypen sind, und wie sich dabei Zahlen und Strings einordnen lassen, weißt du ja schon. Hier aber nochmal zur Wiederholung:

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.


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?"]
Last edited by Thargun on Tue Sep 29, 2015 4:10 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 »

6.2 - String-Listen

Bevor du weiter liest, blättere schnell zurück zum vorherigen Kapitel und schaue dir den String nochmal genauer an. Hast du das erledigt, und ein bisschen mit Strings und String-Funktionen herumexperimentiert, geht es jetzt mit String-Listen weiter.

Auf den ersten Blick sieht eine String-Liste genauso wie ein String aus: Alphanumerische Zeichen die von doppelten Anführungszeichen eingeschlossen werden. Und tatsächlich kannst du eine String-Liste auch genau wie ein String behandeln. Der große Unterschied ist, dass es einige Funktionen gibt die nur mit String-Listen verwendet werden können. Aber schauen wir uns so eine String-Liste mal genauer an:

Code: Select all

[stringList = "String 1, String 2, String 3, String 4, String 5"]
Eine String-Liste besteht also einfach aus mehreren Strings die durch ein Komma (,) voneinander getrennt werden. Zu jeder String-Liste gibt es auch einen Index, und der beginnt bei "0". Der erste String in der Liste hat also den Index "0", der zweite String in der Liste den Index "1", der dritte String in der Liste den Index 2, usw. Das ist wichtig wenn du z. B. einen String aus der Liste löschen möchtest.

String-Listen können für ganz verschiedene Dinge benutzt werden, z. B. für das Inventar eines Charakters. Erstelle doch mal so ein Inventar und speichere die String-Liste in einer Variable:

Code: Select all

[h: inventar = "Wasserschlauch, Proviantpacket, Fackel, Feuerstein, Schwert"]
Sortiere jetzt noch das Inventar nach Alphabet. Das geht mit der Funktion listSort(), bei der du als Parameter einfach die String-Liste angibst (die in diesem Fall in einer Variable gespeichert ist). Als zweiter Parameter muss noch der Sortierungstyp als String angegeben werden, in unserem Fall ist das ein einfaches "A" für eine normale Sortierung nach dem Alphabet:

Code: Select all

[h: inventar = "Wasserschlauch, Proviantpacket, Fackel, Feuerstein, Schwert"]
[h: inventar = listSort(inventar, "A")]
[r: inventar]
Wenn du einen bestimmten Eintrag aus einer Liste brauchst verwendest du dafür listGet(). Als Parameter gibst du dabei die String-Liste und den Index des gewünschten Eintrags an:

Code: Select all

[h: inventar = "Wasserschlauch, Proviantpacket, Fackel, Feuerstein, Schwert"]
[h: item2 = listGet(inventar, 1)]
[r: item2]
In der MapTool-Wiki findest du eine Liste aller String-List Funktionen. Da sind praktische Sachen dabei um z. B. Strings zur Liste hinzuzufügen oder zu löschen, Einträge in einer Liste zu suchen oder zu zählen, und noch einige mehr. Schaue dir die Funktionen ruhig alle an und probiere auch möglichst viele aus, denn String-Listen wirst du immer wieder benötigen.


Trennzeichen

Wenn du einer String-Liste nun aber einen Eintrag hinzufügen möchtest der selbst ein Komma beinhaltet (z. B. "Wasserflasche, 3 Liter"), ist das natürlich ziemlich ungünstig, denn der Parser denkt dann es wären zwei verschiedene Einträge. Zum Glück kannst du String-Listen aber auch mit anderen Trennzeichen nutzen, suche dir einfach eines aus das in normalen Strings sicher nicht vorkommen wird. Wie wäre es z. B. mit "A%"?

Code: Select all

[h: inventar = "Wasserschlauch A% Proviantpacket A% Fackel A% Feuerstein A% Schwert"]
listSort(), listGet() und andere Funktionen für String-Listen funktionieren jetzt allerdings nicht mehr ohne weiteres, denn sie erwarten ein Komma als Trennzeichen. Daher kannst du bei allen String-List Funktionen, die auf ein Trennzeichen angewiesen sind, das benutzte Trennzeichen auch nochmal extra angeben. Z. B. bei listGet():

Code: Select all

[h: inventar = "Wasserschlauch A% Proviantpacket A% Fackel A% Feuerstein A% Schwert"]
[h: item2 = listGet(inventar, 1, "A%")]
[r: item2]
Last edited by Thargun on Tue Sep 29, 2015 4:11 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 »

6.3 - String Property Listen

String Property Listen sind eine feine Sache. Wie eine String Liste wird sie in doppelte Einführunsgzeichen eingeschlossen und kann somit auch als normaler String behandelt werden. Die einzelnen Einträge der Liste werden hier jedoch durch ein Semikolon (;) getrennt und bestehen jeweils aus einem Schlüssel (oder "Key") und einem Wert, der diesem Schlüssel zugeordnet wird. Der Name des Schlüssels darf keine Leer- oder Sonderzeichen enthalten. Ein Beispiel:

Code: Select all

[h: stringPropertyList = "key1=wert; key2=wert; key3=wert"]
Für was ist so eine String Property Liste jetzt nützlich? Z. B. könntest du deine Charakterattribute darin speichern:

Code: Select all

[h: charakter.attribute = "Staerke=12; Geschick=13; Klugheit=10"]
Oder eine Liste deiner Waffen mit ihren verschiedenen Eigenschaften:

Code: Select all

[h: waffen = "Waffe1Name=Schwert; Waffe1Typ=Klingenwaffe; Waffe2Name=Kriegshammer; Waffe2Typ=Hiebwaffe"]
String Properties abrufen

Zum Abrufen einer String Property, bzw. ihrem Wert, nutzen wir die Funktion getStrProp(). Als Parameter wird die String Property Liste und der Schlüssel (als String) angegeben, dessen Wert du erhalten möchtest. Ein Beispiel:

Code: Select all

[h: charakter.attribute = "Staerke=12; Geschick=13; Klugheit=10"]
[h: charakter.staerke = getStrProp(charakter.attribute, "Staerke")]
Deine Staerke ist [r: charakter.staerke].
String Properties ändern und hinzufügen

Zum Ändern eines Wertes in der String Property List wird die Funktion setStrProp() genutzt. Als Parameter werden die String Property List, der Schlüssel und der neue Wert angegeben:

Code: Select all

[h: charakter.attribute = "Staerke=12; Geschick=13; Klugheit=10"]
[h: charakter.attribute = setStrProp(charakter.attribute, "Staerke", 14)]
[h: charakter.staerke = getStrProp(charakter.attribute, "Staerke")]
Deine Staerke ist [r: charakter.staerke].
Mit der gleichen Funktion kannst du auch einen komplett neuen Schlüssel mit Wert hinzufügen:

Code: Select all

[h: charakter.attribute = "Staerke=12; Geschick=13; Klugheit=10"]
[h: charakter.attribute = setStrProp(charakter.attribute, "Charisma", 13)]
[r: charakter.attribute]
Weitere Funktionen

In der MapTool-Wiki findest du eine Liste aller String Property List Funktionen. Schau mal rein und probiere einige aus, z. B. die Funktion um Einträge zu löschen.
Last edited by Thargun on Tue Sep 29, 2015 4:11 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 »

6.4 - JSON Arrays

String-Listen kennst du ja schon. Ein JSON Array, ab jetzt nur noch Array genannt, ist eigentlich nichts anderes. Darin werden also einfach beliebige Werte, bzw. Strings, in Form einer Liste gespeichert. So ein Array sieht allerdings etwas anders aus:

Code: Select all

["String 1", "String 2", "String 3", "String 4"]
Die einzelnen Einträge in einem Array werden also in doppelte Anführungszeichen (") eingeschlossen, und dann mit einem Komma (,) voneinander getrennt. Das Array selbst wird nochmal von eckigen Klammern eingeschlossen. So könntest du das zwar in den Kampagneneigenschaften als Standardwert für ein Property eintragen, in Makros würde es allerdings wegen den zusätzlichen eckigen Klammern zu Problemen kommen. Willst du also in einem Makro ein Array auf direktem Weg erstellen, und es z. B. einer Variable als Wert zuweisen, musst du das Array in einfache Anführungszeichen (') einschließen:

Code: Select all

[r: array = '["String 1", "String 2", "String 3", "String 4"]']
Die einzelnen Einträge in einem Array besitzen, wie bei einer String-List, einen Index. Und wie bei einer String-List beginnt der Index auch hier bei "0". Der erste Eintrag in der Liste hat also den Index "0", der zweite Eintarg den Index "1", der dritte Eintrag den Index "2", usw.

In Ordnung. Erstellen wir ein Inventar und spielen ein wenig damit herum:

Code: Select all

[r: inventar = '["Wasserschlauch", "Proviant", "Fackel", "Feuerstein", "Schwert"]']
Jetzt sortieren wir das Inventar mit der Funktion json.sort(). Als Parameter geben wir das Array an, das sortiert werden soll:

Code: Select all

[h: inventar = '["Wasserschlauch", "Proviant", "Fackel", "Feuerstein", "Schwert"]']
[h: inventar = json.sort(inventar)]
[r: inventar]
Und schließlich wollen wir aus der unsortierten Liste den zweiten Eintrag (Proviant) abrufen, das machen wir mit der Funktion json.get(). Als Parameter geben wir das Array und den Index des gewünschten Eintrags an:

Code: Select all

[h: inventar = '["Wasserschlauch", "Proviant", "Fackel", "Feuerstein", "Schwert"]']
[h: item = json.get(inventar, 1)]
[r: item]
In der MapTool-Wiki findest du eine Liste aller JSON Funktionen (für Arrays und Objects). Da sind praktische Sachen dabei um z. B. Strings zur Liste hinzuzufügen oder zu löschen, Einträge in einer Liste zu suchen oder zu zählen, und noch einige mehr. Schaue dir die Funktionen ruhig alle an und probiere auch möglichst viele aus.

Jetzt fragst du dich vielleicht wann du eine String-List und wann ein JSON-Array verwenden solltest. Die Frage lässt sich nicht klar beantworten, denn das hängt immer von der jeweiligen Situation und Aufgabe ab. Mit der Zeit und mit steigender Erfahrung wirst du aber schon bald selbst erkennen was in welcher Situation die meisten Vorteile bietet. Zwei Dinge kannst du dir schon mal merken:
  • Bei einem Array dürfen die einzelnen Einträge auch Kommata enthalten, da die Einträge durch den Einschluss in doppelte Anführungszeichen deutlich erkennbar sind. In einer String-List würde das Probleme verursachen, da MapTool Einträge mit einem Komma als zwei verschiedene Einträge behandeln würde.
  • Der Parser arbeitet mit JSON Arrays etwas langsamer als mit String-Listen. In den meisten Fällen wirst du nicht viel davon merken. Aber wenn du sehr viele und große Listen einsetzt, solltest du dort wo es möglich ist String-Listen benutzen.
Last edited by Thargun on Tue Sep 29, 2015 4:12 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 »

6.5 - JSON Objects

JSON Objects, ab jetzt nur noch Object genannt, haben die gleiche Aufgabe wie String Property Listen. Es handelt sich als um eine Liste bei der jeder Eintrag aus einem Schlüssel und einem Wert für diesen Schlüssel besteht. Ein Object sieht so aus:

Code: Select all

{"key1":"wert", "key2":"wert", "key3":"wert"}
Die einzelnen Einträge in der Liste werden mit einem Komma (,) getrennt. Der Schlüssel und Wert eines jeden Eintrags wird in doppelte Anführungszeichen (") eingeschlossen und mit einem Doppelpunkt (:) voneinander getrennt. So könntest du das zwar in den Kampagneneigenschaften als Standardwert für ein Property eintragen, in Makros würde es allerdings wegen den zusätzlichen geschweiften Klammern zu Problemen kommen. Willst du also in einem Makro ein Object auf direktem Weg erstellen, und es z. B. einer Variable als Wert zuweisen, musst du das Object in einfache Anführungszeichen (') einschließen:

Code: Select all

[r: object = '{"key1":"wert", "key2":"wert", "key3":"wert"}']
Objects abrufen

Zum Abrufen eines Objects, bzw. den Wert eines Schlüssels in der Liste, nutzen wir die Funktion json.get(). Als Parameter geben wir das Object und den Schlüssel (als String) an. Hier ein Beispiel mit einer Liste in der Charakterattribute gespeichert sind:

Code: Select all

[h: attribute = '{"Mut":"12", "Klugheit":"10", "Geschick":"11"}']
[h: geschickwert = json.get(attribute, "Geschick")]
Dein Geschick beträgt [r: geschickwert].
Objects ändern und hinzufügen

Zum Ändern eines Wertes in einem Object wird die Funktion json.set() genutzt. Als Parameter werden das Object, der Schlüssel und der neue Wert angegeben:

Code: Select all

[h: attribute = '{"Mut":"12", "Klugheit":"10", "Geschick":"11"}']
[h: attribute = json.set(attribute, "Geschick", 15)]
[h: geschickwert = json.get(attribute, "Geschick")]
Dein Geschick beträgt [r: geschickwert].
Mit der gleichen Funktion kannst du auch einen komplett neuen Schlüssel mit Wert hinzufügen:

Code: Select all

[h: attribute = '{"Mut":"12", "Klugheit":"10", "Geschick":"11"}']
[h: attribute = json.set(attribute, "Intuition", "14")]
[r: attribute]
Weitere Funktionen

In der MapTool-Wiki findest du eine Liste aller JSON Funktionen (für Arrays und Objects). Schau mal rein und probiere einige aus, z. B. die Funktion um Einträge zu löschen.


JSON-Objects oder String Property Lists?

Jetzt fragst du dich vielleicht wann du eine String Property List und wann ein JSON-Object verwenden solltest. Die Frage lässt sich nicht klar beantworten, denn das hängt immer von der jeweiligen Situation und Aufgabe ab. Mit der Zeit und mit steigender Erfahrung wirst du aber schon bald selbst erkennen was in welcher Situation die meisten Vorteile bietet. Zwei Dinge kannst du dir schon mal merken:
  • Bei einem Object dürfen die einzelnen Einträge auch bestimmte Sonderzeichen enthalten, die bei einer String Property List zu Problemen führen könnten.
  • Der Parser arbeitet mit JSON Objects etwas langsamer als mit String Property Listen. In den meisten Fällen wirst du nicht viel davon merken. Aber wenn du sehr viele und große Listen einsetzt, solltest du dort wo es möglich ist String Property Listen benutzen.
Last edited by Thargun on Tue Sep 29, 2015 4:12 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 »

7 - Token Properties

7.1 - Was sind Token-Properties?

Token-Properties (Token-Eigenschaften, folgend nur noch "Properties" genannt) sind etwas ganz ähnliches wie Variablen, die du auch genauso benutzen kannst. Das heißt, du kannst ihnen einen Namen geben, einen Wert eines beliebigen Datentyps zuweisen, ihren Wert ändern, sie in der Chatbox ausgeben, oder als Parameter bei Funktionen benutzen. Der wichtigste Unterschied zwischen Properties und Variablen ist folgender:

Properties und ihr zugeordneter Wert werden in Tokens fest gespeichert. Anders als Variablen sind sie dadurch jederzeit und überall existent. Wenn du also erstmal ein Property erstellt hast kannst du auf dieses Property von jedem Makro aus zugreifen, und zwar wann du willst.

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 »

7.2 - Properties erstellen

Um neue Properties zu erstellen wähle in MapTool oben im Menü Bearbeiten und dann Kampagneneigenschaften aus. In dem sich öffnenden Fenster gehst du auf den Tab Token Properties. Wenn du anschließend links bei Token Type auf Basic klickst, so dass es blau hinterlegt ist, wirst du im großen Eingabebereich daneben bereits einige Properties sehen die von MapTool voreingetragen sind. Markiere alle mit der Maus und lösche sie, schließlich wollen wir selbst Properties erstellen.

Im Eingabebereich kannst du nun deine eigenen Properties eintragen. Du musst sie untereinander schreiben, jede Property in eine eigene Zeile. Die Regeln zur Namensgebung von Properties sind so ähnlich wie die bei Variablen:
  • Der Name darf keine Leerzeichen enthalten.
  • Sonderzeichen sind ebenfalls verboten.
  • Der Name einer Property muss einmalig sein. Du darfst nicht zwei Properties mit dem selben Namen erstellen.
  • Der Name darf, ungeachtet von Groß- und Kleinschreibung, nicht mit dem Namen einer Variable in Makros übereinstimmen.
  • Der Name darf, ungeachtet von Groß- und Kleinschreibung, nicht mit dem Namen einer Spezial-Variable übereinstimmen.
Keine feste Regel, aber bei der Namensgebung unbedingt zu empfehlen, sind außerdem folgende Tipps:
  • Beginne den Namen einer Property immer mit einem Großbuchstaben. Das hilft dir Token-Properties von Variablen besser zu unterscheiden.
  • Wähle immer einen aussagekräftigen, aber eher kürzeren Namen.
In den meisten Fällen werden Charakterwerte in den Properties gespeichert. Trage also mal folgende Properties ein:

Code: Select all

Staerke
Geschick
Klugheit
Angriff
Verteidigung
HP
Ruestung
Klicke dann unter dem Eingabefenster auf die Schaltfläche Update. Diesen Schritt darfst du nie vergessen wenn du bei den Properties irgendetwas änderst, sonst werden deine Änderungen nicht gespeichert. Klicke abschließend unten rechts auf die Schaltfläche OK.

Image

In Ordnung, überprüfen wir ob das funktioniert hat. Ziehe einen neuen Token auf die Spieloberfläche, mache einen Doppelklick darauf und wähle den Tab Properties aus. Dort solltest du jetzt in der linken Spalte deine Properties sehen. In der rechten Spalte werden die zugehörigen Werte der Properties angezeigt. Da du noch keine Werte festgelegt hast ist hier noch alles leer. Du könntest die Werte für die Properties jetzt an dieser Stelle manuell eintragen, mache es aber bitte noch nicht.

Image

Hinweis 1: Jeder Token den du auf die Spieloberfläche ziehst erhält automatisch die Properties, die du in den Kampagneneigenschaften festgelegt hast. Selbstverständlich kannst du dann in jedem Token eigene Werte für die Properties eintragen. In einem Token könntest du z. B. der Property "Staerke" den Wert "10" zuordnen, und in einem anderen Token den Wert "12".

Hinweis 2: Wenn du in den Kampagneneigenschaften die Properties änderst, z. B. eine Property löschst oder eine neue hinzufügst, wirkt sich das auch auf alle Tokens auf der Spieloberfläche aus. Bei den Tokens wird dann ebenfalls die entsprechende Property gelöscht oder eben neu hinzugefügt.

Hinweis 3: Neue Properties kannst du nur in den Kampagneneigenschaften erstellen. In den Tokens selbst geht das nicht, dort kannst du nur den Wert ändern.
Last edited by Thargun on Tue Sep 29, 2015 4:13 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 »

7.3 - Standardwerte für Properties

Du kannst in den Kampagneneigenschaften für Properties auch Standardwerte festlegen. Die erhält dann jeder Token den du auf die Spieloberfläche ziehst ebenfalls automatisch. Das Format dafür ist wie folgt:

Code: Select all

Propertyname:Standardwert
Gehe also erneut in die Kampagneneigenschaften und ändere die Properties:

Code: Select all

Staerke:13
Geschick:10
Klugheit:11
Angriff:14
Verteidigung:12
HP:30
Ruestung:2
Ziehe einen neuen Token auf die Spieloberfläche und schaue dir die Properties des Tokens an. Du wirst feststellen, dass jedem Property der Standardwert zugeordnet wurde. Natürlich kannst du die Werte trotzdem manuell ändern.

Auch bei Tokens die sich bereits auf der Spieloberfläche befinden wird der Wert der Properties mit den Standardwerten gefüllt, sobald du die diese in den Kampagneneigenschaften hinzufügst. Allerdings nur, wenn für eine Property bisher kein Wert im Token festgelegt wurde. Hast du z. B. für "Staerke" bereits einen anderen Wert eingetragen, wird dieser Wert nicht überschrieben.

Aber Achtung: Änderst du z. B. den Standardwert für "Staerke" in den Kampagneneigenschaften von "13" auf "14", wird der Wert für "Staerke" in bestehenden Tokens ebenfalls auf "14" geändert, wenn er bisher "13" war, also dem alten Standardwert entsprach (aber auch nur in diesem Fall). Dabei macht es dann auch keinen Unterschied ob der Wert von "13" manuell im Token eingetragen wurde oder nicht.
Last edited by Thargun on Tue Sep 29, 2015 4:13 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 »

7.4 - Ein integrierter Charakterbogen

Dieses Thema hat zwar eigentlich nichts mit Makros zu tun, ist aber trotzdem eine tolle Sache. Also schau mal rein:

In Token-Properties werden ja sinnigerweise verschiedene Charakterwerte eingetragen, so wie in einem Charakterbogen. Gehe mal in die Kampagneneigenschaften und setze vor die ersten drei Properties (Staerke, Geschick und Klugheit) einfach ein Sternchen bzw. Multiplikationszeichen. Als Beispiel (mit Standardwert):

Code: Select all

*Staerke:13
Speichere die Änderungen und fahre jetzt mit der Maus über einen Token auf der Spieloberfläche. Wie du siehst, wird dabei unten links nun tatsächlich ein Charakterbogen angezeigt. Dieser enthält das Token-Portrait (oder das normale Tokenbild wenn kein Portrait hinzugefügt wurde) und alle Properties vor die du ein Sternchen gesetzt hast.

Image

Dieser kleine Charakterbogen wird allen Spielern angezeigt wenn sie mit der Maus über ein Token fahren. Möchtest du aber, dass ein oder mehrere Werte im Charakterbogen nur für den Besitzer des Tokens (und den Spielleiter) sichtbar sind, kombiniere in den Kampagneneigenschaften bei den entsprechenden Properties das Sternchen mit dem At-Zeichen:

Code: Select all

*@Staerke:13
Möchtest du dagegen, dass ein Wert im Charakterbogen nur für den Spielleiter sichtbar ist, kombiniere das Sternchen mit einer Raute:

Code: Select all

*#Staerke:13
Statt den vollen Namen der Properties kannst du in dem Charakterbogen auch selbst gewählte Kurzbezeichnungen anzeigen lassen. Wie wäre es mit "RS" statt "Ruestung"? Gehe erneut in die Kampagneneigenschaften zu den Properties. Kurzbezeichnungen werden immer in normale Klammern eingeschlossen und müssen direkt hinter dem Namen der Properties notiert werden:

Code: Select all

*Ruestung(RS):2
Probiere es aus und fahre anschließend mit der Maus über einen Token. Aber merke dir: Diese Kurzbezeichnung ist wirklich nur für die Anzeige im Charakterbogen gedacht. In Makros kannst du sie nicht nutzen, da brauchst du immer den vollen Namen einer Property.

Image

Übrigens: Sobald sich der Wert einer Property, die im Charakterbogen angezeigt wird, ändert, wird der Wert natürlich auch dort aktualisiert.
Last edited by Thargun on Tue Sep 29, 2015 4:13 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 »

7.5 - Der "Current Token"

Die große Frage ist: Wenn du in einem Makro Token-Properties abfragst, woher weiß das Makro dann von welchem Token es die Properties nehmen soll? Normalerweise bezieht es sich auf den Current Token, also den aktuellen Token. Bei Funktionen die Tokendaten benötigen ist es ähnlich. Zwar beziehen sich manche direkt auf ausgewählte oder verkörperte Tokens, aber die meisten eben auf den Current Token. Das Konzept des Current Token ist am Anfang etwas verwirrend, aber es ist auch nötig damit du Tokendaten wie Properties effektiv nutzen kannst.


Zustände von Tokens

Zuerst teilen wir Tokens in drei Kategorien ein. Das sind quasi die Zustände die ein Token annehmen kann.

Selected Token / Ausgewählter Token:
Ein Token der mit der Maus markiert wurde. Damit der Token für normale Spieler als markiert gilt, also der rot-weisse Rahmen darum erscheint (und nicht der grün-weisse), muss der Spieler auch die Besitzrechte (Ownership) an dem Token haben.

Impersonated Token / Verkörperter Token:
Ein Token den du verkörpert hast (Rechtsklick auf Token --> Impersonate). Eine Verkörperung lässt sich übrigens wieder aufheben wenn du im Chatbereich unten links auf die kleine rote Schaltfläche mit dem weissen "x" neben dem Tokenbild klickst.

Current Token / Aktueller Token:
Das ist etwas kniffliger. Der Current Token ist der Token auf den sich aktuell ein Makro-Befehl bezieht, oder der aktuell von einem Makro-Befehl geändert wird. Dieser Token ist quasi der Fokus eines Makros das ausgeführt wird. Dadurch kann ein Token aber auch Current Token, Impersonated Token und Selected Token zur gleichen Zeit sein.


Makros in Tokens

Wenn du einen Token auswählst, und dann ein Makro ausführst das ebenfalls in diesem Token gespeichert ist (also im Fenster "Ausgewählt" auf den Makro-Button klickst), dann ist dieser Token für das Makro auch immer der Current Token.


Makros in Library Tokens

Makros in Library Tokens werden normalerweise nicht direkt über die Makro-Buttons im Library Token, sondern von anderen Tokens oder aus den Fenstern "Global" und "Campaign (Kampagne)" heraus aufgerufen. Wenn das Makro im Library Token von einem anderen Token aus aufgerufen wird, ist der Token der das Makro aufruft der Current Token. Wird das Makro im Library Token aber aus den Fenstern "Global" oder "Campaign" heraus aufgerufen, ist der Current Token der Selected Token oder der Impersonated Token.


Makros in den Fenstern "Global" und "Campaign"

Makros die in einem dieser beiden Fenster gespeichert sind nutzen als Current Token immer den Selected Token oder der Impersonated Token.


Selected Tokens als Current Token

Damit ein Selected Token überhaupt ein Current Token sein kann muss eine Voraussetzung erfüllt sein. Öffne mal den Makro-Editor. Dort findest du unten links die Option "Auf ausgewählte Spielsteine anwenden". Nur wenn diese Option in einem Makro aktiviert ist, akzeptiert dieses Makro ein Selected Token als Current Token.


Nochmal im Klartext

Meistens ist es eigentlich ganz leicht herauszufinden was der Current Token ist:
  • Wenn Makros direkt in einem PC/NPC Token gespeichert sind und von dort aus ausgeführt werden, oder wenn die Option "Auf ausgewählte Spielsteine anwenden" im Makro aktiviert wurde, ist es der Selected Token.
  • Wenn kein Token markiert ist, oder die Option "Auf ausgewählte Spielsteine anwenden" im Makro deaktiviert wurde, ist es der Impersonated Token.
Ausserdem solltest du dir merken:
  • Beziehst du dich in einem Makro auf Tokendaten, z. B. Token-Properties, wird dafür normalerweise der Current Token herangezogen.
  • Beziehst du dich in einem Makro auf Tokendaten, und MapTool kann aus irgendeinem Grund keinen Current Token finden, geschieht entweder gar nichts oder es wird ein Fehler in der Chatbox ausgegeben.

Tokens mit gleichem Namen

Tokens mit gleichem Namen sollten unbedingt vermieden werden, da MapTool sonst eventuell Probleme bekommen kann den Current Token richtig zu bestimmen. Mit genügend Erfahrung im Makro Schreiben lässt sich zwar auch das umgehen, leichter ist es aber wenn du dafür sorgst, dass alle Tokens auf der Spieloberfläche verschiedene Namen haben. Wenn du also z. B. eine Gruppe feindlicher Orks erstellst benenne sie nach dem Schema "Ork 1, Ork 2, etc." Wenn du Tokens kopierst, und die richtigen Einstellungen in MapTool festgelegt hast, geschieht das sogar automatisch.


Der "Current Token" in diesem Tutorial

Ob du später bei deinen Makros Selected Tokens als Current Token zulässt oder nicht, bleibt dir überlassen. Beide Möglichkeiten bieten je nach Situation Vor- und Nachteile, die du mit ein wenig Erfahrung bald selbst herausfinden wirst. Um im Laufe des Tutorials mögliche Fehlerquellen auszuschließen entscheiden wir uns allerdings dagegen. Die Option "Auf ausgewählte Spielsteine anwenden" sollte also bei allen Makros deaktiviert sein.

Daraus folgt, dass der Current Token immer der Impersonated Token sein wird, also alle Tokendaten die in einem Makro abgefragt oder geändert werden, z. B. Token-Properties, sich auf den Impersonated Token, also auf den gerade verkörperten Token beziehen. Das bedeutet natürlich auch, dass du ab jetzt immer einen Token verkörpert haben solltest.

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 »

7.6 - Properties abrufen

Wenn es darum geht Properties mit ihrem Wert abzurufen, damit du damit arbeiten kannst, funktioniert das genauso wie bei Variablen. Das hast du schon gelernt, deswegen sollen an dieser Stelle ein paar einfache Beispiele genügen. Denke daran, dass du einen Token verkörpert haben musst damit die Makros wissen von welchem Token sie die Properties nutzen sollen.

Property im Chat ausgeben:

Code: Select all

[r: Staerke]
Property einer Variablen zuweisen und dann im Chat ausgeben:

Code: Select all

[h: charakter.Staerke = Staerke]
[r: charakter.Staerke]
Property mit einem Bonus von "5" im Chat ausgeben:

Code: Select all

[r: Angriff + 5]
Property mit einem Malus, der in einer Variable gespeichert ist, im Chat ausgeben:

Code: Select all

[h: angriff.Malus = 5]
[r: Angriff - angriff.Malus]
Und selbstverständlich kannst du Properties auch als Parameter in Funktionen angeben. Folgendes Beispiel liefert dir als Rückgabewert den höchsten Wert unserer drei Charakterattribute Staerke (13), Geschick (10) und Klugheit (11):

Code: Select all

[r: hoechster.Attributswert = max(Staerke, Geschick, Klugheit)]
Im letzten Beispiel geht es nicht um Properties, aber ein Token enthält ja auch noch mehr Daten die du abrufen kannst. Mit der Funktion getName() lässt sich z. B. der Name eines Tokens herausfinden. Probiere es aus:

Code: Select all

[r: getName()]
Properties per Funktion abrufen

Es gibt noch einen anderen Weg Properties abzurufen, nämlich mit der Funktion getProperty(). Als Parameter wird der Name der gewünschten Property angegeben. Du kannst den Namen direkt als String angeben oder vorher in einer Variable speichern. Beispiele:

Code: Select all

[r: getProperty("Geschick")]

Code: Select all

[h: property.Name = "Geschick"]
[r: getProperty(property.Name)]
Last edited by Thargun on Tue Sep 29, 2015 4:14 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 »

7.7 - Properties editieren

Properties lassen sich natürlich auch ändern. Charakterattribute wie Staerke oder Geschick ändern sich wahrscheinlich sehr selten. Die HP (Hitpoints, Healthpoints, Lebensenergie, oder wie du es auch nennen möchtest) dagegen relativ oft, nämlich jedes Mal wenn ein Charakter Schaden erleidet, z. B. bei einem Treffer des Gegners.

Properties lassen sich genauso wie Variablen ändern, du kannst ihnen also z. B. einen komplett neuen Wert zuweisen. Da du das schon gelernt hast hier nur drei kleine Beispiele, die alle den Wert der Property "HP" direkt auf 20 setzen:

Code: Select all

[h: HP = 20]

Code: Select all

[h: HP = 10 + 10]

Code: Select all

[h: neue.HP = 20]
[h: HP = neue.HP]
Mache einen Doppelklick auf deinen verkörperten Token und überprüfe den Wert der Property "HP", er wird nun 20 statt ehemals 30 betragen.

Der Property "HP" einen komplett neuen Wert zuzuordnen ist oft nicht sehr praktisch, denn meistens willst du ja nur eine bestimmte Anzahl abziehen oder hinzufügen. Das kann dann so aussehen:

Code: Select all

[h: HP = HP - 5]
Der neue Wert für HP ist also der alte Wert von HP abzüglich 5. Auf die gleiche Art kannst du natürlich auch HP hinzufügen:

Code: Select all

[h: HP = HP + 5]
Probiere beide Beispiele aus und schaue dir jedes Mal danach den HP-Wert deines Tokens an.

Beim Ändern der HP bietet es sich natürlich an auch mit Usereingaben zu arbeiten. Lasse uns also zwei Makros schreiben. Eines damit der Spieler HP abziehen kann, und eines damit er HP hinzufügen kann. Anschließend kannst du ein bisschen damit herumspielen.

HP abziehen:

Code: Select all

[h: HP = HP - schaden]
Nach Abzug der Schadenspunkte hast du noch [r: HP] HP.
HP hinzufügen:

Code: Select all

[h: HP = HP + hp.regeneration]
Nach dem Trinken des Heiltranks hast du nun [r: HP] HP.
Properties per Funktion editieren

Es gibt noch einen anderen Weg Properties zu ändern, nämlich mit der Funktion setProperty(). Als Parameter wird der Name der gewünschten Property benötigt (String oder Variable) und natürlich der neue Wert für die Property (auch als Variable möglich). Beispiele:

Code: Select all

[h: setProperty("HP", 10)]

Code: Select all

[h: property.Name = "HP"]
[h: neue.HP = 10]
[r: setProperty(property.Name, neue.HP)]
Last edited by Thargun on Tue Sep 29, 2015 4:15 pm, edited 1 time in total.

Post Reply

Return to “Documentation Requests/Discussion”