[Guide][Wiki-Beitrag] How-To Total RP 3 Extended ❔

Extended am Sonntag #10


Der dynamische Notizblock

Ein Notizblock? Könnte man da nicht einfach ein Dokument-Item erstellen und fertig?

Könnte man.

Aber dann lernen wir ja gar nichts über dynamische Dokumente. Und Variablen. Und man braucht jedes Mal ein neues Item für eine simple Notiz. Und außerdem. Und überhaupt.

Import-Code

Bevor es losgeht findet ihr hier das fertige Item zum Schnell-Importieren:

Notizblock

!1Ev3YPTru4xgFvMMyjHTtqtCNbd4c1oIeV4F60PRqiDSzRxKi6hNyiwpl9POx1RAEX65SlcqGi21tYypIDxT7589D(5BbUjVp3Xe)3OMb3XIZmmTQBw30W61hCYh)yc3PgUdwxh6zyukSCwqKp9r)FJZA1JZoTlolLZoQhzqwNg6PDAZDoWWaxVp)ioJ1KotuyJGG(WNtBkf(3sRW6tpj0WanKWrIao7oVy3jXrJNG2Yl(Me9lzhjstH8bKnYhaIWBGHqOIaEbbGY2e0zrCN9wXFDdNKHVyF6fPQ)y4)srsAX0126JbTOH)j4xgArkyCOY9(rHPqyQce7mB(ShMn5H)9VMT7eAWoZwa4hOLwhwSqoZIwWAtaGzGSXObDtgf9PsyyTSy(ak1LpGszBJ2mXnHpT0XtGZXrYefPNnQMT)dziVJNcc)rHaMVUlkmFWoZsJNypr6DpeBFDMuI0FuTTZ)A)pbZVF4FOGtcYlV0SyqHN2Iqmo4eLkMUvCSzi6hvWNixn(IKW7BSWd9VIIDMySdXNivcu0X8HL1q5)QEmfP1iMDuZt4oVHZExlYcVd7jD6PmR7XC2hYGK0JXd42j7gGZo(mQD8YUyuzFS7SJjTPw4EeH3tBtVRowvD2o1Ov)fVXq)OizQyshWlaIreqeG50aTu0TQOtb1ivIU9x2)FEc8nRZwl6ImnO49Z3Ko97pcWkwMxPuViuKk8KIPqGY7QAZdNlLDhg(JZGcG9SZBBRPmol09trX3ET87dWZ)YxECOV(X3SewnDLn8SBYl6RwfRuN1QiBJ40Ev7KVHWUifKRPSR6dkPQtvrBrm)zRxuH81mPi82xu(sRxOV6zKiCA21F9FUbcjn95BCHw6lOrcigF7wv32Blfspz0wCbtvgFf1f1f0SENxe4WLoNX19KZxI1ahonBC(GtHeafhJb)rPj3subtc4jA2tzKU8HOcZLChu6O15QpiRGGG1LZ2)Z0GZWb0rk(MaAXHwTPBcxikBBJkYQ881Eylr8CT5PawfGkXS3ZqsBw3sHvuW6u84QAdfugQfBw5iQQAC5p0qfSqfvCY5o0ZlAOWzZZOjN1LGHQIY2(TNaeiu29NrN2ICQLrD0mTPn3TjvUFN7yrIVljk4AGH(lv2MDe9SPYPx2M8q6QkWTVQi8RP)s(uYOt8MaXdZcdKGHLNMMxGRibbw9haLclBq9HYislzjZTkyUgJvWC)ryjfKyBBAyuIX6WSM3AUPJERXWNQo(tRiwdgvrmINTQIurlDseg0CfbUjG86sUGD8vKt0rB0ld)U179Ynb92A9Woa0IdxyBC5dESlfCdx)AHcxvCLWBxEHGJXIgCT7hg7f6pIMuHMlwGp2f)(Mp(1Ek)yQJBedXkvuMjk((QyQQn)GT4oKSj4v58kUpcNfaPEcjbLQvO0DsN2J2PQGKXajChK8Y(JI9KyVWf4VVathSwyIS(UgM7AzLpWYWU2BSTOI(sRBwhl4TTEnIe8CQF0trBkRzfgp4cmk8Q9ELQo5zO9v81EQuOTK46pLpG0DrHis3DLU98bEdNMj)6FNOvGta)Syr69NIavsjiT4Fbk5)h

Was das Item können soll

Ich möchte einen handelsüblichen Notizblock modellieren, von dem man Zettel abreißen und einzeln beschreiben kann.

  • Jeder Zettel soll zunächst eine Überschrift bekommen.
  • Man kann danach beliebig viel Text hinzufügen, das muss nicht sofort passieren, d.h. man soll alte Notizen später ergänzen können.
  • Man kann eine Notiz unterschreiben. Wenn man eine Notiz unterschrieben hat, soll es nicht mehr möglich sein, Text anzufügen.
    Bei einem echten Notizzettel würde das natürlich trotzdem gehen, aber… ich will das so :yum:

Objektstruktur

Der Notizblock ist ein Item (wow, Sherlock…), der ein inneres Item enthält, das einen einzelnen Notizzettel modelliert. In diesem befindet sich ein Dokument, dass die eigentliche Notiz anzeigt. Wir haben es also mit einem Dokument in einem Item in einem Item zu tun.
Da ich mehrere Arbeitsabläufe pro Item und Dokument benötigen werde, überführe ich als erste Amtshandlung meine Objekte in den Expertenmodus.

Variablen

Der Notizblock an sich benötigt nur eine Objektvariable: Mit charges speichere ich, wieviele (leere) Zettel der Block noch enthält.

Die einzelnen Zettel brauchen da etwas mehr Information. Beachte, dass die Objektvariablen der Notizzettel nichts mit der des Blocks zu tun haben. Auch wenn der Block zerstört wird, bleiben die abgelösten Zettel erhalten.

  • initialized erhält den Wert true, sobald der Zettel zum ersten Mal benutzt wird.
  • title speichert den Titel bzw. das Thema der Notiz.
  • content enthält den eigentlichen Inhalt, der nach und nach eingegeben wird.
  • controls beinhaltet die Schaltflächen „Text hinzufügen“ und „Signieren“. Nachdem signiert wurde, wird diese Variable mit einem Text „unterschrieben von…“ überschrieben.
  • signature enthält die „Unterschrift“, sobald unterschrieben wurde.
  • addedText ist eine temporäre Variable, um Text zwischenzuspeichern, der hinzugefügt werden soll.

Das äußere Item: Notizblock

Der Notizblock ist ein benutzbares Item. Im Tooltip informiere ich den Spieler mit ${charges::100} darüber, wieviele leere Zettel noch am Block heften. Die ::100 stellt dabei sicher, dass auch dann etwas angezeigt wird, wenn der Block noch nie benutzt wurde und somit die Variable charges noch nicht existiert.
Benutzt man den Notizblock, wird onUse ausgeführt. Achtung: Es gibt einen weiteren Arbeitsablauf mit selbem Namen im Notizzettel-Item.

  1. Initialisiere die Variable charges mit 100. Indem ich „Initialisieren“ statt „Wertzuweisung“ verwende, wird der Effekt nur bei der ersten Benutzung aktiv. Danach wird er ignoriert, da es die Variable charges schon gibt.
  2. Verringere charges um 1, denn wir reißen gleich ein Blatt ab.
  3. Spiele einen passenden Sound ab. Geschenkt.
  4. Füge das innere Item (Notizzettel) dem Spielerinventar hinzu.
  5. Bedingung: wenn charges Null erreicht:
  6. Verbrauche (d.h. Zerstöre) den Notizblock.

Das Dokument

Der Inhalt des Dokuments, also des Objekts, das später meine Notiz auf den Bildschirm bringt, sieht… unspektakulär aus:

{h1:c}${title}{/h1}${content}
${controls}

In diesem Fall liegt die Würze in der Kürze.
${title} wird durch den vom Spieler vergebenen Titel ersetzt, ${content} entsprechend durch den Inhalt.
${controls} beinhaltet die beiden Schaltflächen/Links, mit denen ich Text hinzufügen kann oder signieren.

Die drei Dokument-Arbeitsabläufe onAddTextClick, onAddTextInput und onSignClick heben wir uns für später auf, denn zuerst kümmern wir uns um…

Das innere Item: Notizzettel

Wie der Notizblock ist dieses Item als benutzbar angelegt. Im Tooltip zeige ich mit ${title::<Kein Titel>} den Titel an. Man muss also nicht jede Notiz „durchklicken“, um den Titel zu erfahren.
Außerdem fülle ich das Feld „Beschreibungstext“ mit ${signature::Ein einfacher Notizzettel} aus. Das sorgt dafür, dass eine nicht unterzeichnete Notiz mit der Bemerkung „Ein einfacher Notizzettel“ versehen wird, ein unterschriebener hingegen mit der entsprechenden „Unterschrift“.

Der Notizzettel hat zwei Arbeitsabläufe: onUse und initialize. Wenn man einen Notizzettel benutzt (also rechtsklickt), …

  1. … wird das innere Dokument angezeigt, aber nur, wenn die Variable initialized auf true gesetzt ist.
  2. … wird initialize aufgerufen, aber nur, wenn die Variable initialized nicht auf true gesetzt ist.

Anders ausgedrückt: onUse bereitet den Notizzettel vor, falls das noch nicht geschehen ist, ansonsten zeigt es seinen Inhalt an.

initialize kümmert sich darum, dass beim ersten Benutzen alle Variablen korrekt eingerichtet werden:

  1. Setze initialized auf true.
  2. Lege die Variable content an. In der Datenbank sieht das Konstrukt etwas merkwürdig aus. Dort steht content [=], aber es hat seine Richtigkeit. Der Inhalt soll anfangs leer sein.
  3. Weise der Variable controls den Wert {h3:c}{link*onAddTextClick*Text hinzufügen} {link*onSignClick*Signieren}{/h3} zu. Hier sind also die beiden Schaltflächen, die später im Dokument zu sehen sein werden. Sie stehen deshalb nicht direkt im Dokument, damit ich sie nach dem Signieren entfernen kann.
  4. Eingabeaufforderung für die Variable title. Der Spieler soll hier einen Titel wählen. Sobald das geschehen ist, wird onUse aufgerufen.

Wer aufmerksam gelesen hat, wird feststellen, dass die beiden Arbeitsabläufe sich gegenseitig aufrufen. Das könnte sich zu einer gefährlichen Endlosschleife entwickeln. In diesem Fall ist das kein Problem, denn wir steuern die Aufrufe über die Variable initialized. Indem wir sie im ersten Schritt auf true setzen, stellen wir sicher, dass es kein ewiges hin und her geben kann.

Interaktionen im Dokument

Wie oben erwähnt, bleiben noch die drei Dokument-Arbeitsabläufe zu klären.

onAddTextClick wird ausgelöst, sobald der Spieler auf die entsprechende Schaltfläche unten im Dokument klickt. Als einzigen Effekt enthält der Arbeitsablauf eine Eingabeaufforderung für die Variable addedText.

Ist der Spieler fertig mit Schreiben, wird onAddTextInput aufgerufen.

Hier wird im ersten Schritt die Variable content modifiziert: ${content}{p} {/p}{p}${addedText}{/p}. Der neue Wert besteht aus dem alten Wert (dafür sorgt der erste Teil ${content}), sowie dem neuen Text ${addedText}, der in einen Absatz eingebettet wird (dafür sorgen {p} und {/p}).
Dazwischen habe ich ein komisches Konstrukt {p} {/p} reingemogelt. Dieses erzeugt eine Leerzeile. Das Leerzeichen in der Mitte ist ein geschütztes Leerzeichen, sonst funktioniert der Trick nicht.
Das geschützte Leerzeichen ist über die Tastenkombination ALT+255 erreichbar. Im Gegensatz zum normalen Leerzeichen wird es wie Text behandelt. Ohne dieses spezielle Zeichen würde Extended „denken“, dass mein Absatz leer ist, und ihn nicht anzeigen. Ich habe also einen nicht leeren Absatz und Extended spendiert mir den Zeilenumbruch, den ich haben möchte. Der Absatz an sich ist nicht zu sehen, weil… naja, weil er nur aus Leerzeichen besteht.

Im zweiten Schritt wird das Dokument erneut angezeigt. Bedenke, dass an dieser Stelle das Dokument bereits offen ist, aber indem ich es erneut öffne, wird auch der Inhalt mit dem neuen Wert von content aktualisiert.

Der letzte Arbeitsablauf ist onSignClick, der ausgelöst wird, wenn der Spieler seine Notiz unterzeichnen möchte.
Ähnlich wie bei onAddTextInput werden hier Variablen neu gesetzt.
Zunächst bekommt controls den neuen Wert {h3:c}unterzeichnet von ${trp:player:full}{/h3}. Damit werden die beiden Schaltflächen durch einen Text ersetzt und sind nicht mehr anklickbar. ${trp:player:full} ist ein Variablen-Tag, das den Spielernamen beinhaltet.
Danach wird das Dokument erneut angezeigt, damit die Änderungen sichtbar werden.
Im letzten Schritt wird die Variable signature eingestellt. Dadurch ist dann bereits im Item-Tooltip ersichtlich, dass die Notiz fertiggestellt wurde, und nicht mehr veränderbar ist.


Viel Spaß beim Experimentieren und
:wave: bis zum nächsten Sonntag…

2 Likes