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

Extended am Sonntag #8


Spielereignisse

Heute soll es um einen Mechanismus gehen, mit dem das Spiel dem Interface (also auch Addons wie Extended) mitteilt, was gerade auf dem Bildschirm passiert: Spielereignisse oder Events. Wer beim Wort „Event“ an ein Rockfestival denkt, den muss ich enttäuschen. Auch simple Dinge wie ein Mausklick sind Ereignisse, und das Spiel wird uns über jeden Mausklick informieren, wenn wir das wollen.

Ereignisse "abhören"

Technisch gesehen ist ein Ereignis einfach nur eine Nachricht, die jedem Addon übermittelt wird, das danach fragt. Wenn ich z.B. informiert werden möchte, sobald meine Spielfigur das Gebiet wechselt, muss sich ein Addon für das Ereignis ZONE_CHANGED registrieren. Extended übernimmt hierbei die Registrierungsarbeit für uns und wir müssen lediglich einen Arbeitsablauf festlegen, der bei einem bestimmten Ereignis starten soll.
Die Auswahl an Ereignissen ist reichlich. Probiere es aus:

/eventtrace

öffnet ein Fenster, das alle Ereignisse in Echtzeit auflistet. Selbst, wenn nichts besonderes auf dem Bildschirm passiert, können Ereignisse im Sekundentakt eintreten. Wenn du kämpfst oder in einer belebten Stadt bist, explodiert das Log förmlich.

Wo kann man Ereignisse einsetzen?

Grundsätzlich können nur Kampagnen auf Ereignisse „hören“, bei Items geht das nicht.
Innerhalb von Kampagnen kannst du Ereignisverknüpfungen auf Kampagnen-, Quest- sowie auf Questschrittebene einstellen.

  • Kampagnenereignisse bleiben solange aktiv, wie die Kampagne aktiv ist. Wird die Kampagne pausiert, wird kein Ereignis verarbeitet.
  • Questereignisse werden verarbeitet, solange die Quest sichtbar und nicht erfüllt ist.
  • Questschrittereignisse werden verarbeitet, solange die zugehörige Quest sich im betreffenden Schritt befindet und nicht erfüllt wurde. Es ist also nicht sinnvoll, einem Endschritt Ereignisse zuzuweisen.

Bedingte Ereignisse

Unter „Ereignisverknüpfungen“ kannst du jedem Ereignis mit STRG+Klick eine Bedingung zuweisen. Diese sorgt dafür, dass das Ereignis nur dann weiterverarbeitet wird, wenn die Bedingung erfüllt ist.
Das ist hilfreich, denn die meisten Ereignisse sind allgemein gehalten. Bspw. informiert das oben erwähnte Ereignis ZONE_CHANGED nur, dass man das Gebiet gewechselt hat, aber nicht, in welches. Die Quest „Reise nach Eisenschmiede“ könnte man also erfolgreich abschließen, wenn das Ereignis ZONE_CHANGED eintritt und der Gebietsname „Eisenschmiede“ lautet.

Ereignisparameter

Manche Ereignisse übermitteln zusätzliche Informationen. Z.B. liefert das Mausklickereignis GLOBAL_MOUSE_UP mit, ob die linke (leftButton) oder rechte (rightButton) Maustaste betätigt wurde.
Der Operand „Experte > Ereignisparameter (Text/Zahl)“ ist sowohl in der Ereignisbedingung als auch im aufgerufenen Arbeitsablauf abrufbar.
Alternativ kannst du das Variablen-Tag ${event.X} benutzen, wobei X für den Argument-Index steht.
Beachte, dass die Argumente nur in unmittelbar aufgerufenen Arbeitsabläufen verfügbar sind.

Spezielle Extended-Ereignisse

Fünf Ereignisse werden nicht vom Spiel generiert, sondern von Extended selbst. Um es ganz genau zu nehmen, reagiert Extended auf ein anderes Spielereignis und erzeugt daraus ein angepasstes Ereignis.
Sie werden genauso behandelt wie die anderen Ereignisse, tauchen aber nicht im /eventtrace-Log auf.

  • TRP3_EMOTE, wenn jemand ein vorgefertigtes Emote wie /hallo verwendet
  • TRP3_ITEM_USED, wenn der Spieler ein TRP-Item benutzt
  • TRP3_KILL, wenn der Spieler oder ein Gruppenmitglied eine Einheit tötet
  • TRP3_ROLL, wenn der „Würfeln“-Effekt verwendet wurde
  • TRP3_SIGNAL, wenn der „Signal senden“-Effekt verwendet wurde

Wie man Ereignisse findet

Wenn du ein neues Ereignis einstellst, hast du die Möglichkeit, den Ereigniskatalog zu durchsuchen. Dort sind viele (aber nicht alle) Ereignisse nach Kategorie aufgelistet, zusammen mit ihren Parametern, d.h. den Informationen, die mitgeliefert werden. Wenn du schon ungefähr weißt, in welche Kategorie dein Ereignis gehören könnte, kann dieser Katalog eine Hilfe sein.

Die „Probiermethode“ kann auch zum Ziel führen. Öffne dazu das /eventtrace-Tool. Dann tust du, was in deiner Quest bzw. Kampagne getan werden soll. Beobachte dabei, welche Ereignisse eintreten. Wenn ein Ereignis immer eintritt, wenn du die Questaufgabe erledigt, hast du einen guten Kandidaten gefunden.

Sei präzise

Bedenke, dass Ereignisse nicht nur für Extended entwickelt wurden. Meistens werden Ereignisse öfter ausgelöst als benötigt. Du kannst Bedingungen einsetzen, um das „richtige“ Ereignis herauszufischen.
Es kann auch vorkommen, dass mehrere Ereignisse bei einer bestimmten Aktion auslösen. Das Aufsteigen auf ein Reittier löst z.B. eine Reihe von Ereignissen aus, darunter UNIT_SPELLCAST_STOP (weil aufmountern als Zauber zählt) und COMPANION_UPDATE. Wenn die Questaufgabe darin besteht, auf ein Mount zu steigen, solltest du COMPANION_UPDATE verwenden, wenn es darum geht, einen Zauber zu wirken, kann UNIT_SPELLCAST_STOP helfen. Versuche also, ein möglichst passendes Ereignis zu wählen.


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

1 Like

Extended am Sonntag #9


Mehr Einsicht mit TRP3:Intended

Wenn die eigenen TRP3-Kreationen ambitionierter werden, wenn sich in deiner Kampagne eine stattliche Anzahl an Quests gesammelt hat oder wenn dein Item mit mehreren Variablen jongliert, kann es schonmal passieren, dass der Überblick verloren geht, insbesondere, wenn irgendetwas nicht so funktioniert, wie es soll.

Damit ich bei der Erstellung mehr Kontrolle über meine Kreation habe, habe ich mir ein Addon-Modul gebastelt, dass ihr euch bei CurseForge herunterladen könnt:

https://www.curseforge.com/wow/addons/total-rp-3-intended

Ein stiller Helfer

Zunächst wirst du nur eine neue :beetle:-Schaltfläche im TRP3-Menü sehen und so soll es auch sein: Das Modul wird nur aktiv, wenn man es explizit anweist, ein Item oder eine Kampagne zu beobachten, ansonsten bleibt es dezent im Hintergrund.
Kampagnen kannst du mit der Schaltfläche „Aktive Kampagne verfolgen“, Items mit STRG+Klick auf die Beobachtungsliste setzen. Bei einem Item wird nur das ausgewählte Exemplar beobachtet, denn jedes Exemplar kann einen anderen Status besitzen.

Objektdaten

Unter „Objektdaten“ findest du alle Objektvariablen mit ihren momentanen Werten. Außerdem gibt es eine Funktion, um den momentanen Zustand zu exportieren. So kann man bspw. andere Spieler auf den selben Stand in einer Kampagne bringen, um etwa einen Fehler zu untersuchen.

Questübersicht

Bei einer verfolgten Kampagne kannst du dir eine Übersicht mit allen enthaltenen Quests ansehen und diese nach Belieben starten oder zu beliebigen Schritten wechseln.
Das ist hilfreich, wenn du Quests testen möchtest, denn auf diese Weise musst du nicht jedes Mal die Kampagne neu starten.

Arbeitsabläufe

Zu jeder verfolgten Kreation notiert sich Intended alle Arbeitsabläufe, die ausgelöst wurden.
So kannst du nachvollziehen, ob und in welcher Reihenfolge deine Arbeitsabläufe ausgeführt wurden, oder ob sie z.B. öfter bzw. seltener als gedacht auslösen.

Kontrollpunkte

Innerhalb von Arbeitsabläufen ist es möglich, mit einem speziellen Effekt einen Kontrollpunkt anzulegen (Debug-Effekte > Kontrollpunkt). Damit hast du Einsicht in den Arbeitsablauf selbst.
Auch wenn dieser Effekt nur Intended-Benutzern zur Verfügung steht, funktionieren Kreationen weiter, wenn man das Modul nicht installiert hat. Trotzdem solltest du Kontrollpunkte löschen, sobald du sie nicht mehr benötigst, so wie ein Baugerüst abgebaut wird, wenn das Haus fertig ist.

Warnungen

Intended hat eine Bescheidene Form der sog. statischen Analyse, d.h. es kann bestimmte problemantische Konstrukte erkennen.
Wegen der Komplexität von TRP3 kann diese Liste nicht vollständig sein, und es kann mitunter falschen Alarm geben, aber es kann nicht schaden, mal einen Blick auf die Warnungen zu werfen, wenn etwas nicht richtig funktioniert.

Spoilerwarnung

Intended lässt zu, dass du mehr von einem Item oder einer Kampagne siehst, als das normalerweise der Fall wäre. Beim Erstellen, Testen und der Fehlersuche ist das praktisch, für alles andere ist das Modul nicht gedacht.

  • Benutze das Modul nicht, während du eine Kampagne durchspielst!
  • Fordere andere Spieler nicht auf, eine Variable manuell einzustellen, bevor sie ein von dir erstelltes Item benutzen können!
  • Gehe immer davon aus, dass deine Mitspieler Intended nicht installiert haben!

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

1 Like

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

Diese Richtlinie mit nur 3 Posts ist seltsame. Die Guides sind aber gut.

1 Like

Extended am Sonntag #11


Karten und Würfel

Heute geht es um eine häufig vorkommende Frage: Wie kann man Würfel oder das Ziehen von Karten aus einem Kartenstapel modellieren?
Man ahnt es vielleicht schon, es wird um Zufallswerte gehen.

Würfel erzeugen unabhängige Zufallsereignisse. Wenn ich mehrmals würfle, hat das Ergebnis nichts mit den vorherigen Würfen zu tun. Selbst bei einem gezinkten Würfel ist das so, auch wenn dort nicht alle Ergebnisse gleich wahrscheinlich sind. Münzwürfe fallen auch in diese Kategorie.

Im Gegensatz dazu entstehen beim Kartenziehen abhängige Ergebnisse. Wenn ich in einem normalen 32-Karten-Blatt einmal das Pik As ziehe, kann die nächste Karte sicher kein Pik As mehr sein. Beim Lotto ist es ähnlich.

Überlege also zuerst, in welche Kategorie deine zufälligen Ereignisse passen könnten.

Einmal Würfeln, gleiche Chancen

Wenn man „nur“ würfeln möchte, hat Extended das passende Werkzeug: Inventar > Würfeln.
Hier kannst du einstellen, wie gewürfelt werden soll. 1d6 steht z.B. für den klassischen, sechsseitigen Würfel, 1d100 entspricht dem /würfeln-Makro. Das Würfelergebnis wird auf dem Bildschirm ausgegeben. Optional kannst du das Ergebnis in eine Variable speichern.

Wenn das Ergebnis keine Zahl, sondern eine zufällige Begrüßung, ein zufälliger Soundeffekt, o.ä. sein soll, benutzt man einen Trick: Jedes mögliche Ergebnis bekommt eine Nummer. Dann würfelt man die Nummer aus und voilà.
Hierzu sollte man Experte > Dynamischer Wert > Zufallswert einsetzen, denn wir sind nicht am Ergebnis selbst interessiert (der Zahl), sondern dem zugewiesenen Ereignis.

Eine ausführliche Beschreibung zum Erstellen einer Wurfmünze findet ihr hier: [Guide][Wiki-Beitrag] How-To Total RP 3 Extended ❔ - #4 von Enestress-die-aldor .

Das folgende Beispielitem gibt die Worte „EINSicht“, „AbZWEIgung“ oder „RunDREIse“ aus, jenachdem wie man gewürfelt hat. Das Grundprinzip ist immer das selbe: Erzeuge im ersten Effekt einen zufälligen Wert und frage ihn danach in den Effektbedingungen der Reihe nach ab.

Wörterwürfel !9ozuVTjmqC8prRfCGULi1hiatcPoNUCjG2EWjuIxckeycijD7H8XApT36xS()m0TQLSxRWY(8DNV7hN9PSvZusBmSgyPKcfzjSCX4g3HzwXwFujhapOijMBv0SVazSN8zTvLZB0SanJN5yr6UacP8vk6qA9IQVRRtlXM061nDwPv5z6PvffMuEKtcX(uTtjDEHi2gm02)ryuK3G5sfjyfoNNVw9JWqwfsxV6EBDOKTrNTDboFAphhna8hA48WkU92()7d)LGxJ)09LbtdJWppZO9)siwh8MWM4cS59WxtcJwVVC9LHJlFoScXBcI2xaXWijLNTP9)d4RU2xPBtZlA6E)9PaoS(b4DQ71wIRfItlfwJCVzK7qOFmEkQl0h0nVB2M6uGefBECrxWYDt4GJyIvjlhJNWx5CLdqjUVJGOZs1WrqpqXFcJYKi1diejkjCoyUzbnhOctuKICFKfMcb(in6S915T)4oWrHHRXECqUNq6Sh(b0BHJMxEyXU8MSfCDDHLTjvijspfL80VQB11hF631FdHGB8GLp7zk737XBMl55ypdk(t5nbC8f2VhEgACHuJn1eiNyoKVjojH8HAno01K33ItEq8N73DAzsxMlpTSwJBWMTf5zB1LDx9oVuaBvQN)d

Würfeln mit ungleichen Chancen

Wenn ein gezinkter Würfel oder allgemein unterschiedlich wahrscheinliche Ereignisse benötigt werden, kann man sehr ähnlich wie im ersten Teil vorgehen, nur, dass man diesmal den Ergebnisbereich abfragt.

Als Beispiel habe ich eine Schatulle gebaut, die mit 15%-iger Wahrscheinlichkeit ein seltenes Item enthält. Ich habe das Item so konstruiert, dass es nach der Benutzung nicht verschwindet oder „leer“ ist. So könnt ihr den Effekt leichter ausprobieren.

Schatulle !nx12UTnpm4NO1AlNGGvSnG0KITa060f5KIDJSvSzs0IpuiRCO7c)ySNMDxFXgPSttNtXF)3agWsmKLejf)iP(OfUIaHVl(445i8zcUdZPlZ1L50zAqxZEHVhQbFKpnA0YYv0KPCAKpqWlYNwccJGFzFARB54r5(wxRkZf8bJPr)(c(h1p(J8Y7L5ODKlDWFc(N7BDk)ssT76tJZWTqjdMqlgsNhZ1d18kA9i0LQ8THFf2bPXA5cJkFzypNWLqMdlCPga0b3ApOP(weeyp6ROd1yXCWbuhyHsaUn9NWkUZ4rK(3CNfedNAFrbAh81ibV7EAYeCczInTGVVziz6nJXqDmTo4lOmReTudVEgJXEHmwaOsRI2wKxfnotwf9jvAcuwfnujtGStsJEVAA0Pt70ySUyxEOJ7)sPSJZFrpZPBSCO(AlotLi4BL6WI7bTmhxi1llRLYtuXWKI0u7DSD2uePtrMWVZH79Kmkn2esO3XNuvjoI3Ky0gEN6rLbYcLj4S4c0PnIAKxdO4vq86q8mKnOzNfgpHjYx0gFOHITfvQ7bm8SGOfHSkQMfsM6sMoNcgQAc5Mc9dTJcdfe)nX)7E)VBay5e)FXpvf8owCkH4nAL5HRHTqQTI2MzX7Jt)2MSQOh)(If5asF0q8kt56uv8AS9WF292293oqHMxSpKiwh5T84vsZM0uWEJD(tn5Eof7)Sjhgrx(RK5wmYAUZ1i3H62nGugsXes5BcwPLyTHpt43ZEeNiHpeRiDp3HDoJvfXCVWT3fyR)dmrEYmSUCwNZWqYmR57c8bNye7cmOrOKagPkTSPLavjRn2ie)m

Obwohl es in diesem Beispiel nur zwei mögliche Items gibt, würfle ich von 1 bis 100. Wenn ich eine Zahl zwischen 1 und 15 erwürfelt habe (beachte die Effektbedingung), bekommt der Spieler das besondere Item, ansonsten Schrott. 15 von 100 Würfelergebnissen sind also „gut“, das entspricht den 15%, die ich vorher festgelegt habe. Ich hätte auch 86 bis 100 als „gut“ definieren können, nur die Größe des Bereichs ist hier wichtig.

Karten ziehen

Sobald wir mehr als eine Karte aus einem Deck ziehen, müssen wir etwas tiefer in die Trickkiste greifen. Extended muss sich nämlich irgendwie merken, welche Karten bereits gezogen wurden, oder alternativ, welche noch gezogen werden können.

Bevor ich mich darum kümmere, erstelle ich ein Kartendeck-Item für ein Skatdeck, d.h. ich werde 32 innere Items benötigen. Jetzt könnte ich die 32 Items von Hand erstellen… oder ich baue mir fix ein paar Makros.

Kleiner Exkurs in die TRP3-API

Der folgende Teil ist optional. Ihr könnt die inneren Items auch wie gewohnt erstellen.

/run _A = function(id, name) TRP3_ToolFrame.specificDraft.IN[id] = {TY = TRP3_DB.types.ITEM, MD = {MO = TRP3_DB.modes.NORMAL}, BA = {NA = name}} end

Makro Nummer 1 erzeugt eine Funktion, die ein inneres Item mit vorgegebener Id und vorgegebenem Namen erstellt. Das Item muss dabei in der Datenbank geöffnet sein.

/run _V = {"Sieben", "Acht", "Neun", "Zehn", "Bube", "Dame", "König", "As"} _C = {"Herz", "Pik", "Kreuz", "Karo"}

Das zweite Makro enthält die zukünftigen Namen der Karten.

/run local i = 1 for _, v in pairs(_V) do for _, c in pairs(_C) do _A(("card%02d"):format(i), c .. " " .. v) i = i + 1 end end

Das dritte Makro führt letztendlich meine Einfügefunktion 32 Mal aus. Damit man die Items auch sieht, muss man gegebenenfalls einmal ins Übersichtstab und zurück wechseln.

Zurück zum Deck

Wir haben es also irgendwie geschafft, die inneren Items card01 bis card32 zu erstellen.
Bei einem echten Kartenspiel würde man das Deck zuerst mischen, und dann so viele Karten von oben abnehmen, wie benötigt.
Es gibt aber noch eine andere Methode, die zumindest mathematisch gleichwertig ist: Man beginnt mit einem sortierten Deck. Dann würfelt man von 1 bis 32 und entnimmt die Karte an der entsprechenden Position. Für die zweite Karte würfelt man von 1 bis 31 usw.
Diese Methode werde ich vorstellen. In meinem Beispiel soll folgendes passieren:

  • „mische“ den Stapel, d.h. sortiere alle Karten
  • entnehme bis zu 5 Karten
  • nachdem 5 Karten entnommen wurden, entferne alle gezogenen Karten aus dem Spielerinventar und mische neu
Kartendeck !DEv4YnQnq43f3PZKmtQpHSVCjE69dsSN5CsoSRfoPT)qgmOeRAmCJqKEx6uES6lqFX6kjigi1tL7yhzqR(0(PD3Vfc1H6t9CGVObiQhMsqy05ieC7qIJxro1BaScYup1yuOigRqq(8y94mkXBgvsj()cSgyMRCvZ75sjFIjEPmyC4ogyxwHfBh258TDHcSZEOU57b6yjFVvWkac7XksB41JdCt)IFVDqnXPB)7)kL)udwBj6kh)RSnnyn(C7aRJvVXZwMJUnuK1nCHV0oSMZCRS0XKEB7uNHhb02bQbh1zTfF)GDinN0Rkw3OugDHDyR8A0gzdSw636cYwGDSm9ubUnRDSSOYW6ofKdSeRXXTv(iTgCjrnsUMsYsxMRmxH7ExQhcS4txtj)KRQzgzUR6MLEQX5eykNloNsEqp71l02iQXXkBy0aa4eTTzQrYvQX9zpcNTMLcw1U4Hjk)j1CXVMn(Ac4tRc2W(aZmBQA9F(bn)gV0qt4ame(zkL8(VQUybCHcIUbR8GbP6yHLjbtxWwjF8Xv50TTa64sHvXS9vpwwZRjE7cpSLTgmfEDKAw2gTQHuB1ILNyd22f8il7jz4C3GfYY2s6GvxWylJ0gx3nnJpkI3rOAz7fta71M4VQKnk1lXA15v1QXkVjzPXSOTnf64APQryx1iWOVRu2xwRSNc6UWOnC2ZSDSu5QNk4jXFHj2Ukjm(BjfQDUzxdl06eDFj19E6R4XusEKG)fy9HINYngijzrHjLbx7Uy8Q5U((tw4vg8XYGEDErRYavm87r44EL3OW3pB9VXIK9FouKRr82jZeLb)XFwEd)XYG0m5BxsFvmZSUV7a2(ryNXFOmqUHLwEtzWb3KpA8LAfpQ2qUEkNZgGldIZmguFyp(iG8KECjB3kbBx2ZSENz21ZAhhgb7ZUq5j8tbdoie6097ImCDcRppnNjKN8VYiadVcauBuDrLVLSVkB40EJ5mOwxxfvg87fIy1VPSIYGNy745GUVVA5oW(XsYzMnRkZj0NtGNB6lctJZ2DIZzhkCEAlKQeQgS5WyIfh8WioT9zqh)cJJ)pcEkNOJFWFyf)tJRLvW3eEUKw)HeZKH8KCDj8KRxTyIlzM3kqYmDUFv5A3x)xJ7UPkiZw24HVgzozmG483HWVddvbooJqdhHvIqq(syjGAl)h83ictsa9jOyVam1cccnYbnAa8KW7GogQNYkVV6Fgr3dzYpRf5VzZIVh0F9h2FOIl)pEC7NuDCA0DQ7RxqCHlfmOWiFBcpAllfcVf7GSdpTUuQm4fOa6foBJU)ljNfvi4YVDhW0evWus9gUNM0)5

Das ganze funktioniert mit einem Lua-Skripteffekt. Ich habe das Skript kopiert und Zeilennummern hinzugefügt, damit ich jede Zeile einzeln erklären kann. Wenn ihr den Code weiterverwenden wollt, müsst ihr die Zeilennummern löschen.

01 local CARD_PATTERN = "0206001034S1Nus card%02d"
02 args.object.vars = args.object.vars or {}
03 if not args.object.vars.deck or #args.object.vars.deck <= 27 then
04   args.object.vars.deck = {}
05   for i = 1,32 do
06     effect("item_remove", args, CARD_PATTERN:format(i), 1000)
07     table.insert(args.object.vars.deck, i)
08   end
09   effect("text", args, "Die Karten wurden neu gemischt.", 1)
10 else
11   local r = math.random(1, #args.object.vars.deck)
12   local card = table.remove(args.object.vars.deck, r)
13   effect("item_add", args, CARD_PATTERN:format(card), 1, 2)
14 end

Zeile 1
Hier speichere ich die Id einer Spielkarte ab %02d steht als Platzhalter für die Kartennummer. Der erste Teil ist die Id des Kartendecks. Wenn ihr ein eigenes Item baut, müsst ihr diese entsprechend ändern.

Zeile 2
Mit args.object.vars habe ich direkten Zugriff auf die Objektvariablen. Ich muss getVar nicht verwenden und in diesem Fall könnte ich es auch gar nicht, denn meine Variable deck wird eine Tabelle enthalten. Dieser Fall wird von getVar nicht richtig behandelt.
Diese Zeile übernimmt den Fall, dass es noch keine Variablen im Objekt gibt (also Initialisierung).

Zeile 3
Hier prüfe ich, ob mein Deck gespeichert wurde, und wenn ja, wieviele Karten noch darin sind. Es muss gemischt werden, wenn die Variable deck nicht existiert oder 27 oder weniger Karten im Deck sind.

Zeile 4
Bevor ich mische, lege ich einen leeren Kartenstapel an.

Zeile 5
Ich betrete eine Schleife über alle meine 32 möglichen Karten.

Zeile 6
Innerhalb der Schleife entferne ich jede Karte aus dem Inventar. Sollte die Karte gar nicht im Inventar liegen, passiert nichts. Als Vorsichtsmaßnahme werden bis zu 1000 Exemplare einer Karte entfernt. Es könnte nämlich sein, dass der Spieler mehrere Decks im Inventar hat und simultan zieht.

Zeile 7
Hier wird die Tabelle mit verfügbaren Karten gefüllt. nachdem das passiert ist, stehen dort einfach nur die Zahlen 1 bis 32 der Reihe nach.

Zeile 9
Ich gebe dem Spieler den Hinweis, wenn gemischt wird, damit sich niemand wundert, warum die ausgegebenen Karten verschwinden.

Zeile 10
Ab hier wird der Fall behandelt, dass eine Karte gezogen werden soll anstatt gemischt.

Zeile 11
Zuerst würfle ich aus (math.random), welche Karte vom Stapel genommen werden soll. Diese Zahl ist die Kartenposition, nicht die Kartennummer.

Zeile 12
Mit table.remove entnehme ich die Karte an der zuvor ausgewürfelten Position. In der Variable card steht jetzt eine Kartennummer.

Zeile 13
Schließlich muss ich noch die Karte ins Spielerinventar legen. Mit CARD_PATTERN:format(card) erzeuge ich aus der Kartennummer eine Karten-Id.

Uff, so ein Kartendeck zu bauen war dann doch ein ganzes Stück schwieriger als ein paar Würfel. Das liegt daran, dass sich Extended die verfügbaren Karten merken muss. In diesem Fall ist der Lua-Effekt kaum zu vermeiden, denn das ist momentan die einzige Möglichkeit, in Extended Tabellen bzw. Listen zu verarbeiten.


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

1 Like

Extended am Sonntag #12


Kampagnen in Aktion - Echte Beispiele

Dieser Beitrag wird weniger ein Tutorial und mehr eine Vorstellung meiner eigenen veröffentlichten Extended-Kampagnen.
Vielleicht dienen sie dem einen oder anderen als Inspiration für eigene Projekte oder als Musterlösung für eigene Quests.
Wer wissen möchte, wie die Quests umgesetzt wurden, darf selbstverständlich gern einen Blick in die Datenbank riskieren. (Spoilerwarnung und so)

Was man benötigt

Für jede der vier Kampagnen ist ein Hordecharakter erforderlich, dieser muss aber nicht die Maximalstufe erreicht haben.
Wegen der Größe der Kampagnen kann der Import-Code nicht direkt ins Forum eingebettet werden, stattdessen gebe ich einen Wago.io-Link an. Auf Wago könnt ihr den Import-Code mit Hilfe der Schaltfläche „Import-String kopieren“ rechts oben abrufen.
Jenachdem, mit welcher Hardware ihr ausgestattet seid, kann das Spiel beim Importieren für einige Sekunden einfrieren. Wenn ihr bereits sehr viele Extended-Kreationen gesammelt habt, ist es ratsam, vorher eine Sicherheitskopie eurer Extended-Datenbank zu machen. (Okay, das ist eigentlich immer ratsam.)

"Die Waldläuferin Seleves"

https://wago.io/ZJwzNecYd

Mit dieser Kampagne habe ich mir selbst Extended beigebracht. Sie ist gespickt mit Rätseln und vom Schwierigkeitsgrad höher angesiedelt als die anderen Kampagnen.
Als Mischung aus Prototyp und Probieren-was-geht werden beim Durchspielen sicherlich einige Ecken und Kanten auffallen.

"Jagd auf Velaves"

https://wago.io/EmDGBbUUV

Wenn der Main eine Kampagne bekommt, warum nicht auch die Twinks? Wie in allen vier Kampagnen geht es thematisch um einen Charakterkonzept und dessen Umgebung.

"Azeroth ist nicht genug"

https://wago.io/HzQHtU3Vu

Die Antwort auf die Frage, ob man mit Extended auch Parodien machen kann. Sie lautet: Ja, es geht. Ob man es auch machen sollte, bleibt offen :wink:

"Söhne der Steppe"

https://wago.io/NLBslCmbY

Wer nicht genug vom Brachland bekommt, ist hier genau richtig. Wer Quests mit inhaltlichen Entscheidungen mag, auch.


Ich hoffe, diese kleine Sammlung dient als Inspiration für ein ähnliches Projekt. Vielleicht eine Charakterkampagne? Vielleicht eine Gildenkampagne? Oder eine eventbegleitende Kampagne?

An dieser Stelle sei auch darauf hingewiesen, dass es auf Wago noch weit mehr interessante Kreationen von anderen Autoren gibt. Klickt euch einfach mal ein wenig durch https://wago.io/totalrp.


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

1 Like

Extended am Sonntag #13


Wie man seine Extended-Daten rettet

Zur Abwechslung gibt es jetzt mal was total langweiliges, aber gleichzeitig auch total wichtiges.
Wenn man sich einloggt und plötzlich keine Profile mehr hat, oder alle eigenen Extended-Kreationen verschwunden sind, ist es meistens schon zu spät.
Daten muss man sichern, bevor das Unheil eintritt. In diesem Beitrag erkläre ich, wie, warum und wogegen ihr eure Extended-Daten schützen solltet.

Warum muss ich mich darum kümmern?

Deine Profile, dein Inventar und auch deine Extended-Kreationen werden auf deinem eigenen Computer gespeichert und nirgendwo sonst (es sei denn, du sorgst manuell dafür).
Wenn diese Daten aus irgendeinem Grund verschwinden, kann dir niemand helfen, selbst wenn er/sie es wollte.
Sich eigene Kreationen auszudenken kann durchaus Spaß machen, aber das ganze nochmal abzutippen oder einzugeben macht dann schon weniger Spaß.
10 Minuten Backup-Verwaltung können hier stundenlangen Frust ersparen.

Wieso können die Daten überhaupt verloren gehen?

Man sollte meinen, dass Datenverlust ein Problem aus den 90ern ist.

Meistens ist WoW selbst schuld

Ein typisches Szenario: WoW stürzt ab und danach sind alle Addon-Einstellungen futsch. Der Spielabsturz ist in diesem Fall oft nicht das Problem, erst mit dem darauf folgenden Spielneustart gehen die Addondaten verloren. Aber wer denkt bei einem Absturz im Eifer des Gefechts schon daran, zuerst nach rettbaren Daten zu sehen? Auch hier wieder mein Mantra: Daten vorher sichern, nicht erst warten, bis das Spiel abstürzt!
Bedenke, dass nicht nur Spielabstürze ein Problem verursachen können. WoW verwaltet für uns den verfügbaren Speicher. Das ist ein Sicherheitsmechanismus, damit Addons die Festplatte nicht zumüllen können. Wenn du viele Addons verwendest, die viele Daten abspeichern, kann es passieren, dass WoW sich weigert, all diese Daten auf der Festplatte zu speichern. Extended muss dabei nichtmal der Verursacher sein, denn alle Addons teilen sich denselben Speicher.

Andere Ursachen

Natürlich kann es auch zu Hardware-Fehlern kommen (d.h. deine Festplatte geht kaputt).

Auch wenn es banal klingt, es kommt hin und wieder vor, dass man selbst Kreationen oder Profile löscht, die man später wiederhaben möchte. Mitunter hast du dich bei der Erstellung eines Items verhaspelt und möchtest dieses auf einen früheren (funktionstüchtigen) Stand zurückversetzen.

Wo speichert Extended seine Daten ab?

In deinem WoW-Installationsverzeichnis (unter Windows standardmäßig C:\Programme\World of Warcraft\) gibt es das Unterverzeichnis World of Warcraft\_retail_\WTF\Account\[AccountName]\SavedVariables. Den grün hinterlegten Teil musst du dabei durch deinen Account bzw. deine Accounts ersetzen.
Besonders drei Dateien sind für Extended wichtig.

  • totalRP3.lua speichert deine eigenen Profile, deine TRP3-Einstellungen und das Extended-Inventar sowie das Extended-Questlog deiner Charaktere.
  • In totalRP3_Data.lua werden die Profile anderer Spieler abgespeichert.
    AHA! Mein Profil wird also doch auch woanders abgespeichert! … Mag sein, aber es ist nicht ohne weiteres in ein eigenes Profil umwandelbar.
  • totalRP3_Extended.lua enthält deine eigenen Items und Kampagnen sowie solche von anderen Spielern, und außerdem alle Verstecke und sonstige Drops aus dem Dropsystem.

Diese drei Dateien sind das Minimum, dass du sichern solltest. Wenn du dann schonmal dabei bist, kannst du selbstverständlich auch großzügig den gesamten WTF-Ordner sichern. Dann ist nicht nur Extended gesichert, sondern auch alle anderen Addons.

Backup-Lösungen

Cloudservices

Das jedes Backup darauf hinausläuft, die Daten irgendwo hinzukopieren, wo sie sicher(er) sind, kann man einen Cloudservice benutzen. Diese kann man üblicherweise so einstellen, dass sie die Daten automatisch synchronisieren, man muss sich also nur ein einziges Mal wirklich darum kümmern. Außerdem kann man relativ komfortabel beliebige ältere Versionen wiederherstellen.

Die TRP3-Entwickler haben unter https://github.com/Total-RP/Total-RP-3/wiki/How-to-backup-and-synchronize-your-add-ons-settings-using-a-cloud-service einen englischsprachigen Guide bereitgestellt, wie man soetwas aufsetzen kann.

Manuelles Backup

Wer einen Cloudservice zu teuer/zu aufwändig/zu vertrauensunwürdig findet, kann die Dateien auch einfach selbst regelmäßig irgendwohin kopieren. Idealerweise ist das „irgendwohin“ ein anderes Gerät (andere Festplatte/USB-Stick/Handy).
Hierbei sollte man darauf achten, dass man das Backup auch wirklich regelmäßig macht, z.B. einmal im Monat, oder immer, nachdem man etwas größeres erstellt hat.

Ein Backup anwenden

Sollte der Fall der Fälle eingetreten sein, empfehle ich folgende Vorgehensweise:

  1. Atme beruhigt auf, denn du hast ja ein Backup gemacht.
  2. Sichere den aktuellen Stand deiner Addon-Daten, selbst wenn du ihn als „kaputt“ erachtest. Das ist für den seltenen Fall, dass das Backup nicht funktioniert.
  3. Wichtig: Beende das Spiel.
  4. Ersetze die Addon-Dateien im SavedVariables-Ordner durch dein Backup.
  5. Starte das Spiel neu.
  6. Überprüfe, ob sich TRP3 (und ggf. andere Addons) wieder in einem akzeptablen Zustand befindet.

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

4 Likes

Juhuu! Ich sollte öfters mal Backups machen… allein dafür, sollte ich einen neuen PC kaufen.
Arigatou Sensei Seleves! :wink: :smile_cat:

1 Like

Extended am Sonntag #14


Neue Funktionen in Extended 1.5.0

Im Zuge von Patch 9.2 wurde Extended um einige Features angereichert. Auch wenn es sich hierbei um kein großes Release handelt, ist für den einen oder anderen bestimmt etwas nützliches dabei.

Id-Operanden

Zwei neue Operanden erlauben es, die Id der aktuellen Kampagne sowie die Id von Items in einem Behälter festzustellen.
Ersteres ist nützlich, wenn man sicherstellen will, dass Kampagnen-Items nur benutzt werden können, während eine bestimmte Kampagne läuft.
Den zweiten Operanden kann man benutzen, um zu erkennen, ob sich ein bestimmtes Item in einem Behälter befindet, oder ob es sich an einem bestimmten Platz befindet.

Item-Eigenschaften

Mit einer weiteren Reihe von neuen Operanden lässt sich der Name, das Icon, der Wert, die Qualität und das Gewicht eines Items mit vorgegebener Id ermitteln. In Kombination mit den oben genannten Id-Operanden kann man jetzt sehr viel mehr über den Inhalt einer Tasche erfahren, als es vorher möglich war.

Datums-Operanden

Während man bisher nur die Tageszeit (Stunde und Minute) ermitteln konnte, kommen jetzt auch Jahr, Monat, Monatstag und Wochentag hinzu.
Wer schon immer Dailys und Timegating in Extended umsetzen wollte, kann das jetzt tun :wink: .
Beachte, dass sich alle Zeitangaben auf die Ortszeit des Spielers beziehen.

Ausklingdauer bei Sounds

Mit der optionalen Ausklingdauer können Sounds nun auch sanft ausgeblendet werden. Sie werden dann über einen festgelegten Zeitraum kontinuierlich leiser, statt abrupt zu enden.

Dynamische Grenzen für Zufallswerte

Der Bereich, aus dem der Zufallszahlen-Operand auswählt (z.B. 1 - 100), kann nun auch mit Variablen festgelegt werden, z.B. 1 - ${maxHP}.

Verbesserungen bei Dokumenten

Es wurden zwei Schaltflächen hinzugefügt, mit denen man zur ersten bzw. letzten Seite gelangt.
Außerdem können Links in Dokumenten, die auf Arbeitsabläufe verweisen, optional Parameter enthalten. Jeder Parameter in einem Link wird zu einer Arbeitsablauf-Variablen, die im aufgerufenen Arbeitsablauf verfügbar ist.

Beispiel
{link*onLinkClicked(a=1,b=2)*Linktext} ruft den Arbeitsablauf onLinkClicked auf, und versieht ihn mit den Variablen a und b.

Gleichartige Arbeitsabläufe werden somit gruppierbar.

Lua-Effekt

Allen neuen Operanden können auch im Lua-Effekt verwendet werden. Zusätzlich ist es jetzt möglich, die Funktionen date, tonumber und tostring zu benutzen.


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

3 Likes

Extended am Sonntag #15


Ein Minispiel: Pairs

In Zereth Mortis gibt es gar keine neuen Puzzlespiele (hust), also muss wohl mit Extended nachgeholfen werden.
Diesmal geht es um das Kartenspiel Pairs. (auch unter dem Markennamen Memory bekannt)

  • Das Spiel besteht aus 32 Kartenpaaren mit unterschiedlichen Bildmotiven auf der einen Seite. Die Rückseite sieht bei allen Karten gleich aus.
  • Vor dem Spiel werden alle Kartenpaare gemischt und mit der Rückseite nach oben in einem Rechteck angeordnet.
  • Der Spieler darf pro Zug zwei Karten umdrehen, d.h. das Bild wird sichtbar.
  • Wenn beide Karten das selbe Motiv zeigen, dürfen die Karten aufgedeckt bleiben. (Im Originalspiel werden diese Karten aus der Anordnung entfernt und der Spieler erhält sie als Punkte.)
  • Wenn die Karten nicht das selbe Motiv zeigen, müssen sie wieder umgedreht werden und der nächste Spielzug beginnt.
  • Sobald alle Karten aufgedeckt wurden, ist das Spiel zuende.

Import-Code

Vor der Erklärung findet ihr hier das fertige Item zum Schnell-Importieren:

Pairs !LJvBZTnUr4)lA6hStVtMsQo1XZKpyl7ulxh5CbYj3nxdHbbxjItGaQaG2rrJ1V9UaK6DkL761V1rAiXlp4bl2DXIfmUv8G4(TW)rDWNTJjrDIoTDNorrD6pA6DM4(DqeKE99pt0mt6vAUV8GFjMC19XK76H1CXKlV3Zd5MlkREZ1X9)BNgHTpi(YycPRFmAvxKGUsbFSVkzG)PxciqPyGLePXel3iMGKWmJSLDqKAoto)roo(EQu4RZF8TZF0Pvf5jG5OrG7tmZrE8)W8hB8Cd)ZLyBC8XZVTIGNcd0dSPo53aUR5tmJD(TZVvme7T5qHX68sjIdbgHtsgOW(FS83MiwxGUfKwOKelW1Q0dYYgq2GMfykPY3H9xxBw)str16)TR3)k(wcyZPC1uxdL2m9ZQsvQPao0GwFE((JAtDvuDq2srudgy4q0oDudRUqLsfPulih6TWlm3K39Z(QV51D(74RHm0oC8kA8ML)uKEwDKQsln4)U8mo0QnW0s3ZWoSqxnASSr(cSd1g0ViuR1p4P7zrQlB(JVYxodeJYCZFmvxVpKyPbBblVDlHEJ2xxsR3tALSwvQztuSNjWXDEJYAp10xZ73SugcoNFPc85DA)sJVNPApZJuOg)Q1IOC0sf(BRMDrf0JF1wcvcJp2ksH1KIneJGjPQsPYhF(xrL(MAw(cDvLz4pIA6FPASlu(2BbkDZ8p2oIvZTOfJ56)rW)sHfFQIjT9n0E3WRPAEroOCuV)Wgrz3k4Ff3(i(Br)IFKpCXsQh8ZXKzzToN)YhyOt1StYA9YSjy153(xMficln7KjVuoYl7(pJ7Fwm59x5h87XJs6FFGr67Ij)dwomqRLoXKBawkyIjV7JXjXKp3R6CLBA5XDfyDc103PvUBkgbyZT9n)tfy7(gPvT2zbP(g7Rn5m5D46g76s)cG0)cKl94GAzXsZFcxVbRo76bl8h9uRDoNP2dFcB8M9IpmWoM5kxlCyNvtVl2Zx2DDEjl909HueQNOcvPCk0kAkZmoxRv(DoudmrBHg1styxCGJzRCoBWsesHBknfY1QScLdmurEUwY8S7JEwd4kCCJ2AXypWHH9SqM(VlepbM9GdN5Xu7eGzYyQ09cczJMZqzZLrtKOsH2Xcm3EPDctYsfkelgVsOgj9659G1W4cMKMykSzcNE4W9HtpQaOS8ee3EGyhp1amEgDOCkoRuEM3jDpGFMzmcTX)MBMUniEMaEccBZtqvnDmyWnUgM9BSdanTqncqpdUKzTcEv1CMTgvvnddLFoBIASHnA0bGpYl5weVtaMOwuMukyk(2luV76VbpdsUHn051hJ0YuqHkL6GMlSCAcYf6rtJAFG5xPtKakeixOkwZ9ESafoOmByBB)xUkskqVuV4LGT43WvJW96Of6ifWh3oPgimjpdYNsFteTWvAIDatwhstoA3nOOPsnGlJRT5GtWPP46MMaYTf1WG(kqBLrN80KudduAJTLhFRAGMWsM6kmoj0Mofqf6Z1bcNgQe3eLH7tnmrAP)TQEk5A9yVkcxCCHsXW9TjAfmuyZqFR64pfEsxyaJfJvlZlW5QM9GEGGAKqbO7Dj9JeFlxxdSHadZXB)RNHO83EFA8aPuwklNPCchm0GNLudUmqMJBEcHzqfXeHX7zvTBcJTgcYxLwNQ2tdwlNU9fU)21Umuvu5x2j5q1jT3mxqhdD6X0VSGXfYvYNM7mXYltjWQRYOpKW7lh)NE4BMERdYNG4gkftgO3vK)XwBkYv489NJ(znnyiED(r(PsTUOHSUmLB7VwoQVSQ)nBEfqXoyeLDhiCHOVJvyLAVSuDy25Ip7GOM798F1LauBQY(FDYYhiJIAZD(7NU8(C4))XSNtbhtiTH0kVUl9JxFb5((us3p27ddQN0W3OzdEl)cmK7FyroQytpqIltCTQjYfyrdWZC2XEZpOqpNICufHroN)izIaqxSVvGImGbtvGk8nCQ(woORAHbpo6o8ahzqOktA(deSsR3GcupK(FhjxsrODV3NgVpF7WTec5tJn8txG51hUobw5H((NFcBct0VBiV)R8Zv7O3GiVoaHe(SsxgUtqyqDd885R9dYT4AfKRqn4RpjQZjTXWHrrN35SZBFkc2pyqIli7poiZGNWGZxC)oTcCUtxD90C6cAA358orNh1P8wlxJx7X9PQVGgj9t4DdAEAtuWVd7SurIRzVfQNxaF)NdRQREi8YBIWLnPxm50V6l8rSqWS61gLe5IJ)pp

Das Item verwendet den Lua-Effekt. Um es zu benutzen, müsst ihr mit ALT+Rechtsklick Lua-Skripte für dieses Item erlauben.

Struktur

Das Item ist als Dokument-Item aufgebaut. Der Arbeitsablauf onUse im Item sorgt für das Mischen der Karten, während das innere Dokument sich um die Darstellung des Spielbretts sowie die einzelnen Spielzüge kümmert.
Das Spieldokument wird hierbei dynamisch erzeugt und nach jedem Zug aktualisiert. Dafür sorgt der Arbeitsablauf onCardClick im Dokument.

Einstellen des Spielbretts (onUse)

Grundeinstellungen

Im Lua-Effekt des Item-Arbeitsablaufs lege ich zunächst einige Variablen fest. Das erkennt man am vorangestellten args.object.vars.

  • width und height stellen die Breite und Höhe des Spielbretts ein.
  • backside ist das Icon, das die Rückseite der Karten darstellt.
  • icons ist die Liste der Motive.

Modellierung der Karten

Alle Karten werden in der Liste cards gespeichert. Jede einzelne davon hat zwei Eigenschaften:

  • index gibt an, um welche Karte es sich handelt. Ich verwende also keine Namen wie Kaninchenkarte, sondern simple Nummern von 1 bis 32, denn um 8x8 Karten zu belegen, brauche ich 32 Paare. Dieser Index wird sich nicht mehr ändern.
  • shown ist ein Wahrheitswert, der angibt, ob die Karte schon aufgedeckt wurde. Am Anfang ist dieser Wert bei allen Karten false, aber im Verlauf des Spiel werden diese nach und nach auf true gesetzt.
local n = args.object.vars.width * args.object.vars.height
local cards = {}
for i = 1, n/2 do
    table.insert(cards, {index = i, shown = false})
    table.insert(cards, {index = i, shown = false})
end

In diesem Code-Teil erkennt man, wie die Karten nach Paaren geordnet in die Liste eingefügt werden. table.insert steht zwei mal dort, denn für jedes Motiv gibt es zwei Karten.

Mischen der Karten

Wären die Karten bereits geordnet, wäre das Spiel ziemlich leicht, also sorgt der nächste Teil fürs Mischen:

local temp, flipTo
for i = 1, n-1 do
    flipTo = math.random(i, n)
    temp = cards[flipTo]
    cards[flipTo] = cards[i]
    cards[i] = temp
end

Alle Karten müssen vollständig gemischt werden, also benutze ich eine Abwandlung der Vorgehensweise aus dem Beitrag zum Kartenmischen.

  • Um festzustellen welche Karte an die erste Stelle soll, würfle von 1 bis 64. Vertausche dann die Karte an Position 1 mit der an der erwürfelten Position.
  • Für die zweite Karte, würfle von 2 bis 64, denn die Karte an Position 1 wurde bereits ausgewürfelt. Danach wird wie im ersten Schritt getauscht.
  • Fahre fort, bis alle Karten gemischt sind.

Vorbereiten des ersten Spielzugs

Schließlich speichere ich meine nun gemischte Kartenanordnung als Objektvariable (args.object.vars.cards = cards). Außerdem lege ich zwei weitere Variablen firstCard und secondCard fest. Darin halte ich fest, welche Karten der Spieler umdreht. Beide Variablen sind zum Anfang 0, d.h. der Spieler hat noch keine Karte angerührt.
Ganz am Ende des Lua-Codeblocks zeichne ich das Spielbrett board. Die Erläuterung dazu kommt weiter unten.

Auswerten der Spielzüge im Dokument (onCardClick)

Jedes Mal, wenn der Spieler auf eine Karte klickt, muss das Spiel angemessen reagieren. Das hängt einerseits davon ab, welche Karte angeklickt wurde, und andererseits davon, wieviele Karten bereits aufgedeckt sind.
Ganz am Anfang des Lua-Skripts importiere ich die Arbeitsablauf-Variable cardIndex:

local cardIndex = tonumber(getVar(args, "w", "cardIndex"))
local v = args.object.vars

cardIndex steht für die Position der angeklickten Karte, nicht für das Motiv.
In der zweiten Zeile lege ich eine Abkürzung fest, das erspart Tipparbeit.

Spielzuglogik

Danach folgt ein kleines Monster. Dieses Monster sind die in Code gegossenen Spielregeln:

if v.firstCard == 0 then -- 1
    v.firstCard = cardIndex
elseif v.secondCard == 0 then -- 2
    v.secondCard = cardIndex
    if v.cards[v.firstCard].index == v.cards[v.secondCard].index then -- 2A
        v.cards[v.firstCard].shown = true
        v.cards[v.secondCard].shown = true
        v.firstCard = 0
        v.secondCard = 0
        effect("sound_id_self", args, "SFX", 9637, false)
    else -- 2B
        effect("sound_id_self", args, "SFX", 9638, false)
    end
else -- 3
    v.firstCard = cardIndex
    v.secondCard = 0
end

Okay, einmal kurz durchatmen, wir haben es mit einer Wenn-Dann-Sequenz zu tun.

  • 1 beschreibt die Situation, wenn noch keine Karte umgedreht wurde. In diesem Fall setzen wir die Variable firstCard. D.h. die erste Karte ist die soeben umgedrehte Karte
  • Bei 2 wurde die zweite Karte umgedreht. Jetzt muss das Spiel überprüfen, ob ein Paar gefunden wurde.
  • 2A behandelt den Fall, dass ein Paar gefunden wurde. Wir setzen die Marke shown für beide Karten auf true. Dann setzen wir unsere beiden Variablen firstCard und secondCard wieder auf 0 zurück. Somit beginnt ein neuer Zug.
    Schließlich lasse ich noch einen Sound abspielen, in dem eine freundliche Elfe darauf hinweist, dass ein Paar gefunden wurde.
  • 2B behandelt den Fall, dass kein Paar gefunden wurde. Auch dieser Fall wird von der überaus freundlichen Bluthelfe kommentiert.
    Beachte, dass hier die Variablen firstCard und secondCard nicht zurückgesetzt werden, sonst würde der Spieler das falsche Paar nicht sehen.
  • Der letzte Fall 3 behandelt die Auswirkungen eines falschen Zuges. Sobald eine dritte Karte gezogen wird, werden die anderen beiden verdeckt.

Darstellung des Spielbretts

Die zweite Hälfte des Lua-Effekts befasst sich mit dem sichtbaren Teil des Spiels.

local board = ""
local c = 0
for i = 1, v.width * v.height do
    if v.cards[i].shown or i == v.firstCard or i == v.secondCard then -- 1
        board = board .. "{icon:" .. v.icons[v.cards[i].index] .. ":32}"
    else -- 2
        board = board .. "{link*onCardClick(cardIndex=" .. i .. ")*{icon:" .. v.backside .. ":32}}"
    end
    c = c + 1 -- 3
    if c == v.width then
        board = board .. "\n"
        c = 0
    end
end
args.object.vars.board = board

Für jede Karte wird ein passendes Icon angezeigt.

  • An der Stelle 1 überprüfe ich, ob die Karte gerade sichtbar ist. Eine Karte ist sichtbar, wenn sie bereits als Paar gefunden wurde (shown) ODER wenn sie die erste (firstCard) oder zweite (secondCard) eines Spielzugs ist.
    Eine sichtbare Karte kann man nicht anklicken (d.h. umdrehen), also wird die Karte als normales Icon dargestellt.
  • Wenn die Karte nicht sichtbar ist (Stelle 2), muss die Rückseite angezeigt werden (v.backside). Außerdem muss die Karte anklickbar sein. Das übernimmt der Teil {link*onCardClick(cardIndex=" .. i .. ")*. Das ist ein parametrisierter Dokument-Link, ein neues Feature mit Extended 1.5.0.
  • Damit das Spielbrett schön rechteckig aussieht, füge ich in regelmäßigen Abständen (3) einen Zeilenumbruch ein: board = board .. "\n". Die Sequenz \n erzeugt einen solchen Zeilenumbruch.

Platz für Verbesserung

Nachdem du das Spiel ausprobiert hast, kannst du dir eine Kopie des Items erstellen und dich an folgendem probieren:

  • Verändere die Motive, verwende z.B. nur Bilder, die zu einer bestimmten Thematik passen.
  • Vergrößere oder verkleinere das Spielbrett. Wenn du das Spielbrett vergrößerst, brauchst du auch mehr Motive.
  • Verwende andere Soundeffekte, z.B. ein Kommentar eines zufälligen Volks.
  • Füge eine besonderen Effekt ein, wenn der Spieler alle Karten aufgedeckt hat. Dazu wirst du ein paar Codezeilen brauchen, die das Spielende feststellen.

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

3 Likes

Extended am Sonntag #16


Geheime Dokumente

Heute geht es darum, geheime Informationen oder wertvolle Gegenstände vor den Blicken oder Händen Unbefugter zu schützen. Das kann ein neugieriger Bote sein, der eine Nachricht überbringen, aber nicht lesen soll. Das kann ein Teilnehmer einer Schnitzeljagd sein, der die Trophäe erst bekommen soll, wenn bestimmte Vorbedingungen erfüllt sind. Oder es kann irgendetwas anderes sein, was der Extended-Benutzer (noch) nicht sehen können soll.
In den folgenden Beispielen wird der Schutzmechanismus immer ein Passwort sein, man könnte die Information aber auch hinter einem Rätsel oder allgemein einer Aufgabe verbergen.

:warning: Beachte, dass die Sicherheit hier lediglich im Spielkontext gewährleistet ist. Du solltest mit den folgenden Items auf keinen Fall echte Daten schützen!

Level 1: Statische Daten, statisches Passwort

Importcode: Geheimes Dokument !Trv4sjoqm4NL7b402c4CYm(dSG2ohwqtb88hHwBxHouAz2Db17g5z)s2f6nC6aZg2Szt(Y3(fqxmgJCPVoTOvpeiRRxRoT98E8(Tp5GrTOiGWiEnVoJnX)cH(JqyyiTtJWD9zV3rEIgX7d6z9hmaJUWXbHRJXRra8TUh3ZwtotpIWF20n7JBtR(9(KfILII1c5(KyXB6Z(Z5B(GUaDLR9)jg9dYoIVie0A(niCB6AXn1v6OA560YHPYfceU5b8zeMfIrT7qvoWLJSVqPlQENdoylhvGh7((TKF25CR3XhZACDDPUytGinxiPQYagI6rjQE121IknA)yyIW4dTguxnrj4FaX8QPdfn9Aroc7sLZ3iRxVHUlHxL9qyCQs9ATuBEa2y3KZmput9bczlfzRg34Vd7)acOVLfQgaDAKNcf64NLPvzljBdQYQRYpU5aoTW0KjcLhGy9PyJlg74QRoiq2rTAvrQC12Jq5L0IY7ekvktTpTDHS4Lx2NStiFvuSqi1FdHke8ogU3NzlsUzy75QL1VEcH9FI09jSY8lzeANsKTvwOFFOyNO0WQgHlmAYXNSgnm0N4k3ZDADUN3(eVwD7CzxNlqWNLVIskbQVhVuMwwIWuEOHC)fhLpLsZzDoZXovmGu56PhMXGHKNCIs8)uTA31JPdWFKbEHSsgEab69gcjZBTnknGm9NGrC2NXgnNqnr3k7a2eGVFp))Px3NukuIk71B6zRUEmqiZ9s6XmKoSOA38sHwlKZDVWaLNTs)BTZMQ9jndbS4Io9(EgPanwtBMeXRt7zGNVzySpxapNlPihycb4)nyMjCI9OvFtEMnW2mAJM3YFAe)7d

Der einfachste Fall ist ein Dokument, dass sich nur dann öffnet, wenn man ein Passwort eingibt.

  1. Erstelle einen Dokument-Gegenstand. Wenn du die Vorlage „Dokument-Gegenstand“ benutzt, wird automatisch ein vorbereitetes, inneres Dokument angelegt, dass sich bei Benutzung (onUse) öffnet.
  2. Überführe den Gegenstand in den Experten-Modus, denn es wird ein zweiter Arbeitsablauf benötigt.
  3. Füge dem Gegenstand neben onUse einen zweiten Arbeitsablauf hinzu: checkPassword.
  4. Entferne den Effekt „Dokument öffnen“ aus dem onUse-Arbeitsablauf, denn das Dokument soll erst nach der Passwortkontrolle angezeigt werden.
  5. Füge den Effekt „Experte > Eingabeaufforderung“ in den Arbeitsablauf onUse ein. Stelle darin die Objektvariable password ein sowie den Rückruf-Arbeitsablauf checkPassword.
  6. Der erste Effekt in checkPassword wird eine Bedingung sein: "Objektvariable password ist gleich dem direkten Text-Wert eniarku"
    In der Bedingung steht also das gesuchte Passwort. Als Fehlermeldung bei Nichterfüllung wähle eine Phrase wie „Zugriff verweigert“. Dieser Text wird angezeigt, wenn das falsche Passwort eingegeben wurde.
  7. Der zweite Effekt ist der „Dokument öffnen“-Effekt, der vorher aus dem Arbeitsablauf onUse entfernt wurde. Das Öffnen des Dokuments wird also hinter die Passwortkontrolle verlegt.

Das ist schonmal ein guter Anfang, aber das Passwort ist fest an das Item gebunden. Wenn sich das Passwort einmal herumgesprochen hat, benötigt man eine neue Version mit einem neuen Passwort.

Level 2: Statische Daten, dynamisches Passwort

Importcode: Ganz Geheimes Dokument !nsv3YPTsm4NLEBNPn2MqtdZKladjqkyiznH(ZCwSXwaUXExgVlesZe)003K(IvP1GZa9KZPJ9S)ODL0N(KwXT5(CpB83Qgo6Wz4SJLLvTtR7fwBBg3RgEdwppAmwgrt(FHZApKZ63d3P5SbTjPdqjEdP9DBwkVBhU3hSS4Sw(8wC2KECVtRJBh1S0PKP(mN90Qgrp3zRohYkcwalHKmiViWh2QFZtNS65IRlU2CNNste3)2OLHIfWOqL6bzE8B3Tqxe8RFkIHCXZKoO7ra0Y9tCVpIZKdzEnrylVFDgimNoA6LC2vHzGVuMQtw1fcr95SlVLpJZyUKoh6mscZNgnGhQcJKyoBty(0v5YSvOPdZxOkpK5bRbvrWEtueajOfNbcdBR0YCiUY(izZKilXzCV60sDzGG)PjknF)hRRnb(2GsNiE8sPq3D9caf7qIVb9OMeoDN0A7JusONmplmTpcr8OwdjqwswgsAe6zB7ZrOnMrjn3Hezqu3vHIFueCvz(bJOkQKOe8o300aFwlAZypA8oueMVDneABYYowNJ3SdTVNlYBIntZsurtfsnmxMgdX2XMce8ctmJUgJpPdzj9(0Iumwb)Vzd5SVdrhMnKgw)Bx8pgSEm7t8(rmotWzoKaN)6m((ksJRseRwR)xYVrlHO7Fr(RNSp6MhgZZQWtKueVFZoewcqJ6i(oGaoevKBiPxCXUx7)xQEeNvbtdpXMhMKoauQqQ46RRxKNmFErWgi)bizbKRFtviolpueT8vywSrJP2AQAP8Hdi3JApveq9KETxjkiADEI(X(Wgi1q(MwwSHJ3xcv19Qp29kgXSlwZZGuub178xMhMMILXCVZmf2)XjS2yIW5eRAN44ueyz1W2UHZzL9c7GT203TRZkl(o8MVV(7PNdhRKvTgNwNGc(yJqxpQIFWeZBN2JntyzpdRAy94S6BPf3IlivOEX98nVwXXMUV0IRiifuyBgJUvrBmOXuKY0GwBQelrLMZ)n

Um das obige Dokument zu verbessern, soll ein Mechanismus eingebaut werden, mit dem man das Passwort ändern kann. Das wird über einen Dokument-Link geschehen, d.h. wenn das Dokument geöffnet ist, hat man die Möglichkeit, das Passwort zu verändern.
Das Passwort wird dann nicht mehr in der Datenbank gespeichert, sondern individuell in jedem Item. Man kann also auch verschiedene Passwörter vergeben.
Ausgehend vom oben dargestellten Dokument-Item, gehe folgendermaßen vor:

  1. Im Arbeitsablauf onUse, füge den Effekt „Experte > Variablenoperation (Initialisierung)“ an erster Stelle ein. In diesem Effekt setzen wir die Objekt-Variable storedPassword. Das Standardpasswort soll zunächst leer bleiben.
  2. Im Effekt „Eingabeaufforderung“ ändere den Variablennamen zu inputPassword. Das gesuchte Passwort wird also in der Variable storedPassword gespeichert, während das eingegebene Passwort in inputPassword steht.
  3. Die Bedingung im Arbeitsablauf checkPassword muss dann entsprechend angepasst werden. Statt das eingegebene Passwort mit einem festen Text zu vergleichen, steht nun auf der einen Seite inputPassword und auf der anderen storedPassword.
  4. Jetzt fehlt nur noch die „Passwort ändern“-Funktion. Dazu legen wir einen dritten Arbeitsablauf changePassword an. Dieser liegt jedoch im inneren Dokument und nicht im Item selbst.
    Einziger Effekt in diesem Arbeitsabaluf ist „Experte > Eingabeaufforderung“ mit der Objektvariable storedPassword.
  5. Damit changePassword auch aufgerufen werden kann, fügen wir dem Dokument einen Dokument-Link hinzu.

Wir haben jetzt ein Dokument-Item, bei dem wir jedem Exemplar ein individuelles Passwort zuweisen können, bevor es verteilt wird. Aber das reicht mir noch nicht, denn der Inhalt ist festgelegt und kann nur in der Datenbank geändert werden.

Level 3: Die allesverschlingende* Schließkassette

* allesverschlingend-aber-danach-auch-wieder-ausspuckend-sofern-man-sich-das-passwort-gemerkt-hat

Importcode: Schließkassette !TF1xtnUnq8plDM(wBZz78hMlZKhcjP9YvWHdLaxBNQyh71jUySzKKdCCZ5Vk9f(MWxSURSXGdoPqkp2jzSLwjT)2D1U)Km3KpLBBI)nAIpT4m8TLHHLPHXYpOoiGB3eNbBSn(uXzt)nSn2NnGKMeptcud2u6jPlgKRqSvOpNT2vmpzXFbE4ADflL5dYs0q9h9(ts9mPYvLkNc3O42T4Sjbbqmcg9JH)JcL4ZyoZIe0CpbjkX7cWxdqGBeA21aqlsG1EcGoyu6ecWBLsEruiIA8pM5KEzMdeRw5gPGyiZ5xGLqSuD)DX(ypim(2uP3QOq4()UENVjjOnzrlkTTa3WOZtexeeLCnoBXxMftUjN5Le7)WSkCJCVWBfqJ7wXdkcneKu3E9k20xVrOcTIoLg2cHBS3kQtR9mGjvjcW)exP86er(otDoEBsWb1JXvIKlVQkg2qkiZCkuBUhTjsn1McHNDBQ5gOQi)C6t9YTgZ3r4omE9CCaLBymiMlJsuZjZUi0J)RlEhhgvk)hYf)svO1UvylTcB)kuyZDRWoAfEWRqHT2PcZ3TpOOTUVo6U30l92SUxjsRTSFV4v6vtr)TuvE)0GhRKZCQqeuh67fPtV6iopdeeYjs5)gfsvKKjPX(4o1Cjefubm2p)zco73BA0Pdb5In1B91)spr4g1LuZg5(td01KnOefKrmZPxMZth8b5FSoH0K)63QZ5AxkSKgSAMZJLW)F56lsHVKYvRCcXJbP0DjWzhcRU)o8iorMZLPsKhEDc20hEEDreqtsIN81OCZ8XZu2s9qn89vi6dJVkvvdppwMMNsSf(ED3Yj9QYB26PQvTLNfk31s348QslSsO(3txkcdcWqmiUgcxcc13vsNTz88TGD7n)knVDmFB9kJBLYB3euBJBQcX1h3jL2tQtEQbrxG6vFJPNDs2wVbR(YsDQXFFru8T3cfFHaj4LkcvF5iynePx8rJjaMm7HpfaN0mMU(zWdIy9XMF)xltL629)uEeX9Z(qFU(Rrgmrd)y0MzStP6vgBm(6Mw5wa(A4mUTbND850lCjhslLnCervfNQUfrWpeYPJWx)kwZbkfuyw(Up5QKzo3MM5OnlbsAXobV(OP57rqhpiNm9YqP3CABArYnlxLivHIeCt5Orue4Xu2UD15RFt7aOPB3hn3cp8IcdqtbHJ9P(6n8t6tDMztppRV2LgCk1zizewMy6XNgPNcJFiNDUE6SdPNdMQLmQiaC8qkaC0eoZh0tHXGiCdv(ttxjCJIq9JzbiKdgIrsR3z08DwwzoggDTm7AG46FgkVr7gytfov9hoYog13OpJ6Q6Im7AA0Tno(GNJJISa8SNiPoHz0G5NoQpBI9C0ZgFY0I0ZN95O18jQ5PNuyk3UuC()a

Das letzte Item ist ein Behälter, in den man beliebige Gegenstände einschließen kann.
Um das Passwort einzustellen, benutzt man den leeren, geöffneten Behälter. Wenn man Items in den Behälter legt und ihn dann benutzt, werden die Items eingeschlossen. Sie sind dann nicht mehr im Behälter zu sehen. Um die Items wieder auszuschließen, muss man den Behälter nochmals benutzen und das vorher festgelegte Passwort eingeben.

Damit das ganze funktioniert, braucht es etwas Luarkanmagie.

  1. Im onUse-Arbeitsablauf initialisiere ich zunächst einige Variablen, die wichtigste davon ist locked, die festhält, ob der Behälter gerade auf- oder zugeschlossen ist.
  2. Im fünften Effekt von onUse prüfe ich, ob der Beählter geöffnet ist. Wenn ja, prüfe im nächsten Effekt, ob der Behälter leer ist. Wenn der Behälter leer ist (und geöffnet), erfrage ein neues Passwort.
  3. Der Arbeitsablauf lock kümmert sich um das Einschließen. Zunächst werden die Zustandsvariablen aktualisiert, dann kommt das Herzstück, ein Luaskript:
    args.object.vars.content = args.object.content
    args.object.content = {}
    
    Der gesamte Inhalt (args.object.content) wandert in die Objektvariable content. Das was der Code macht, ist quasi ein Etikettentausch, so wie ein cleverer Arbeiter, der Zementsäcke vom Keller ins Lager schleppen soll, und daraufhin einfach "Lager" auf die Kellertür schreibt.
  4. Das Aufschließen funktioniert sehr ähnlich, nur, dass die Passwortabfrage vorgeschaltet wird. Außerdem prüfe ich, ob der Behälter leer ist, damit die eingeschlossenen Items keine anderen Items ersetzen. tryUnlock prüft, ob aufgeschlossen werden kann, onUnlock überprüft das Passwort, ändert die Zustandsvariablen und führt dann ein sehr ähnliches Luaskript wie oben aus.

Die Schließkassette ist sehr vielseitig, da man beliebige Items, sogar ganze Taschen, einschließen kann.
Hierbei gibt es einen kleinen Schönheitsfehler: Der Behälter wird nicht aktualisiert, während er benutzt wird, d.h. man kann Items sehen, die nur scheinbar darin liegen, bzw. leere Slots, die in Wirklichkeit belegt sind. Man kann sich behelfen, indem man die Tasche mit Doppelklick erneut öffnet.
Wer diesen Anzeigefehler beheben kann, darf sich einen Keks aussuchen.


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

4 Likes

Juhuuu!
Vielen Dank für die Mühe und die vielen Guides und Tipps! :smiley:

1 Like

Extended am Sonntag #17


Die Konzeptomate

Kennst du das auch? Du möchtest einen neuen Charakter erstellen aber dir fällt einfach kein Konzept ein?
Hadere nicht länger, iss eine Konzeptomate!

Kostprobe:

Der Charakter verbrachte die Jugendjahre in einem Wanderzirkus in Unterstadt.
Eine im Alkohol ertrunkene Handelsreise machte schließlich überdeutlich, worauf es ankommt:
Geld. Und im Zweifelsfall richtet man sich nach Velen.

Importcode: Konzeptomate !LZv3UTnUs4xMfO3C22yN2KUfyVWn)3M)ALtsp7fYM2I2I10KzjPIBsr9RYEZ(mSxL78l2zgkhBlhYeVahymafiqrswI8JdhoZ8nIKP1sBMEAn4Vn2eowpnb()21RxV2gBZhT136ME6MWtKC0P4XmDx8Fn)VPj7EwAYXhbx5stE)zyrKCyJYlpCp4LEZgW9BM((0KKDkV95nkRkSa(sAY3V(hJ)WUCZ427KZmSbo80B4Mogw3ChFC7mbC4df95QSVYYnWf)Y31grFH6hJBlu4LsDxMtOv)4LJ)W3FfwG(sDpHY)0)zbtk6j4MFGxXVHRCWzdNw(2U5sbFYFjfDZh3EY9D4MmEHdV8)mU9iTHv0BCBUDCBMAGE4q37Quj)Y3DgMWbvD7luzaIgoU9FmIl6XL2EmPCCBJaRihwJaAT(QrXWJ)Y3fzA5dOgeoOqCNpME6BH)JIPKtBaIy9GIHaM9Y0nBTFAYbSH891k3PAZqM8yMPppnz)pN2jn5QJsp91Oq)WA4tUl36eQBXh(Wc8PoSoE7pva3hVzRY7EEOBEYUicob6Gp9mp2CLD5h1CANzIL72dLM45jnXJVbpWN1blYstUHzAP78vEx417Qvzp8JtFIYhOBoV7GwQ0ew5VKmYReA81kE2V)7t1aVbAFpGgOHBN(86YNcFOeFpm(yGGY44QRHJ3(W7a)jfw4iuzBH341RdiV5kd5Df8oq)GUWecXVbVr9ARdixFJvgZxPHsUu1)aEVj)TQVsyxg(iW3yDa8A)2kd8l5gaPwgOUhqydYz4KARffKARUgYN5zbHBnVYrmDJR5gga0flEJV4h5lE8h1dXYV83kDcmthyzjJVMwld2RT6J2t6Ml61ZA4cBybKF8(MRduxFLb9o6UdCmHmQrkS9dc81aORTYG(9CWjPOFHQFieVPx743wlq(TRmMtUwBC3GJcSoM0fb7En(eOyxhGF7vh8DZlKwa0rg6JM8s2EDa6TwzmFa3h5JfK55G1fzejo2dcEIxdq)n)lGENcJd0t6B7XHahdHBSZlzTOKV664hcoIVJlCb1r8A2Rff7vxV(qqXacuoQjBVEDT1I2rTvx9yQJghWmi8WrVUrT1Y4XAR(asa2sK0tqi7hgwBT4CS2Q7D8CZK77ZLCrqm7DnwB94BC1DoEoqJnIz6spJ1wlaE1dF)eU1YFwpJ1kd6BTec)Qhb)XGOwXnt(NE9uXa(SUoGV6XttvawreIY6dzWOKcOwbnjmbcHAo0H0AvqZmkM1weeZuI2AfuFLq54M)SGlLlJBhz4RwbXxGaggNM5cjOjfL1k4(mtFJy4qwWyP(jL6Afb0NaLWx4YzswWHqeI86sJ7LG)oviithMRvqCJcmfVcvqx0uI7AvlvCRdZNCiqtksRvqDIRWmCKaQ4qQ00H1Avv6cJ2f2qfDiRUeIvd4YCMi44q6WuTcOpGL1N7UlSTdcXwTcO3diQQSDZhkIKfwkXyTcY)mZb4M7ckTPeH1QgqesWA9qDeliuI1AfCFsHSV2eMfiLOTwb0FmND342NOZImMKs0xRcCEmZieI0AvJFAzwm71Z700QlSiSNsvnGK3uOAnsBg0tQhfOMN9fAdunErtGHopFroJeDGsnwqFpFPEuMoy0nETUabS)8L4NE4d)hQyJXJ(5l2Z8Z(GqLPNgZ2Lkq4R8nOWTGdd41GR3ERT2(TPjz(YbEWmUKDlO95V(jcU45rutCkiecqXC9NP76NtbTS5lvMlnVpg3gNShHusJ5G2QluzTezTSCzVkfDY(Fbb8PBbb(bdi6eQylDFgy8QWXh2cgOAbCx91MwkZednjvMD8ZoKYqhK6)SGRU7FJY4))X7ZrAFb8MBWjbZGiFpbkLtN5G(kwF(WIhbyhzsMZCOEP2GtgOGcxsLhN5q(ymB8H9z9ZzgCMlA(mh6kh3UaNdyNzYIMmA6KgN5yFxH9oX1YW(0OtwCMd4gkMPBUG8zWzoIbxtzIyXmrQ83mhZjoEUmYWD6K6M54DF2qHmSsbDYBZc(x9rggaS0jFnZb7b8Sczyo40jtnlQkOCmByDbkLHMfhSHtfcBh(OcR1z5rOgsPe1Si4N83MbHZ2bLsrZCeFKYbS4IyCJsjOPcK5sjc6Guiiv2zw0WHf8u3DqqitOSZSiIJyOBX5rGpzfnjfttCTe4BaVFeqtMnml4KMHomnNJxwKpghLOyodTxQLV4Rp26SJmmmNJuEKO3if7YzWn5w5nmvKV(9pN0lNjBAMZK3ATgwqHdD4uodWnuzfuNp5CWkLCJiOSLsSjNH3lC5HZPnPisox59wCei1N46ZG7bS7K6reNg5cO1y028qOLo8iNH2pMZY6hzoGrhEKZG7hGitcAwGsCixWjHjYeeIu0gNJ3caV3goLyKI24meFsbMgp6tACoGzYEfMiPDKumgNb5J1Mxa(3IntrjeLX5qwif4A7(sTnC0RlYCC(hLUjPOpoBvY7BsSclWB3Vo2J46MoejFeYL4IcimQPeLYQ4UqnAY94QQ8r42rgQLvrSRW0PaOy6O)QNUkWLmvFq1wgqw)tmzZLKr8CJHlGQiOiIouoxE0FpCd9aSEfh80Hb6JWUH3pMLlkXeTkUVwlfoHD22NI38ByBcuIFA1gHs4)(9O0xHB7lszSoccXzTAtiJpCY9oruni6WETkU7ykCmzqithkSvHm34mS(pH9r6qMDjGJQhmJlIRpkXRTkWhYuIRlKWLHd3GuuCxc6t(htg3GwiP)NiTk0hi9OMNZ6frStjAVvXoUDe1qoqNRLGDDyalUizc7xIumHR2k6vihkuSibztj6WlzOP46C9tOZViL4PtO6MKIpC5EmxzGzs742FuGtTpUqHBfCjAzgZf(RRrhIXpztyXTEdmONqnfkXwEHgtH6HDjqMzOdJxBFVIMHWFv2hd)ZfMyQqKI78cih3Ufr1ha9mPdoRp36xGdyFqJm)wEy05G3pP0Qdl(6x46m5EtFUFo27vHFcjhDyBVSjLVo5EvFRdnOCJgAf12c3daXuhcGpWasAX)E5wZ7zfaMhez9ktjg4p2CYHfDaXUHHRUDUmMSNumWFCJWt(UbUzVoBKI1z4k)noqxaM8JhleD4LVSEfo7YM8x8OAw0HzEmKNj4bxVw0HG(YiVqXZ5EJRtJ8jOodD4PVm(BYToBbaHbUfc78obtY)g4SuGlFVhS6MbrXnU9iwUYkukr5OfLEy4OlOej)WEhXythXnd4MNkEckX4pC7qIBMV34ZL4t7GNszaiqtbysFfsxWCNWmi8w8ePseWYJLUIHKCIz9LuS)xg6GhVrt(NCLpeR9eQ74YbEAC(b(LzGeozVOE8Pukcc04Son6F5jns)q3TdZwq3cJWD7X8B4sFz6395to7I0PRwE3d7C5hFgMs80KeCZNNlHxW(RtNImjxMIeot2jWpLSlAu5vBS5RQxFC76B(UnQ)oWmMFJqFVVaf5LWV)Y38s41DxMwUH5NSt1xQ(7Qx7DB4TpTZzE4DeU5SFYvPNcV2Ux4)xYoyOWjjhb8S)gEYNNs4UCRFF39G6t5YN83sWbW75o2V(rn09FTdKGjNNGddE7wPjxKG7U(hdp9PSCdUSdX6St5Eh)03qpeyA6ZUIVz)Pg((KZB43X49hVSHht743e53fl86Bac3pThE9r7GMcUP1qGLDREADwRxVPxUc)2fNIh3PPVO2dleNhtqlOb8A3va2oUe6MV2NNbuJf3tyhaoMhGRlEuimRFlJJ7eYOIJx561piODPP)V

Wie es funktioniert

Man kann es sich sicherlich schon denken: Das Item benutzt vorgefertigte Textbausteine und fügt sie zufällig zusammen.

Ein Blick ins innere Dokument offenbart, welche Teile des Textes sich ändern können und welche nicht:

{p}
Der Charakter verbrachte die Jugendjahre ${origin} in ${location}.
{/p}
{p}
Eine ${qualifier} ${event} machte schließlich überdeutlich, worauf es ankommt:
{/p}
{p}
${trait}. Und im Zweifelsfall richtet man sich nach ${idol}.
{/p}

Die mit ${} markierten Stellen sind Variablen, die vor der Anzeige im Item-Arbeitsablauf onUse ihre Werte zugewiesen bekommen.

Das Auswürfeln der sechs Variablen habe ich auf einen Arbeitsablauf pro Variable aufgeteilt. Das ist nicht notwendig, aber übersichtlicher. Jeder der sechs Arbeitsabläufe (z.B. setEvent) funktioniert ähnlich: Würfle eine Zufallszahl zwischen 1 und 20 aus und weise dann, abhängig vom Ergebnis, einen der vordefinierten Werte zu.

All diese sechs Arbeitsabläufe werden im onUse-Arbeitsablauf der Reihe nach ausgeführt, zum Schluss noch etwas Deko und ganz am Ende das Anzeigen des Ergebnis-Dokuments.


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

4 Likes

Extended am Sonntag #18


Hinter den Kulissen der Datenbank

In diesem Beitrag von Enestress werden bereits alle wichtigen Funktionen der Objektdatenbank vorgestellt.
Im Folgenden wird es um das Konzept dahinter gehen, denn wenn man das Prinzip versteht, fällt es leichter, Kreationen zu verstehen.

Item ist nicht gleich Item

Wenn von „Item/Kampagne erstellen“ die Rede ist, ist üblicherweise das Festlegen von Eigenschaften, Arbeitsabläufen, etc. gemeint.
Mit einem Item in der Datenbank hat man aber noch kein Item in Inventar, denn die Datenbank ist keine Sammlung von Items, sondern von Itemvorlagen, man spricht hier üblicherweise von Klassen.
Dass die Datenbank kein „Lager“ ist, wird auch klar, wenn man die Datenbank-Funktion „Zu Inventar hinzufügen“ verwendet. Das betreffende Item verschwindet nicht aus der Datenbank, sondern ein Exemplar (Instanz) entsteht. Wenn dieses erstellte Exemplar zerstört wird, bleibt es in der Datenbank erhalten. Umgedreht bleibt ein Item im Inventar erhalten, wenn der zugehörige Datenbankeintrag verschwindet. Das Item ist dann aber nicht mehr benutzbar. Extended meldet uns „Missing Class“.

Datenbank = Bauplanbibliothek

Während das Inventar speichert, welche Items in meinem Besitz sind, speichert die Datenbank, was diese Items können, also ihre Eigenschaften.
Ein typischer Itemdatensatz ist sehr klein:

  • Item-Klasse
  • Taschenplatz
  • Anzahl (falls stapelbar)
  • ggf. Item-Variablen

Wenn das Item benutzt wird, konsultiert Extended die Datenbank:

  1. Gibt es die Item-Klasse in der Datenbank?
  2. Wenn ja, ist ein Verhalten „Bei Benutzug“ angegeben?
  3. Wenn ja, gibt es den angegebenen Arbeitsablauf?
  4. Wenn ja, führe den Arbeitsablauf aus.

Ohne Datenbankeintrag gibt es also kein Verhalten und auch keine Eigenschaften.

Austausch von Items

Wenn man einem anderen Spieler ein Item gibt, müssen folglich beide Teile (Klasse und Instanz) übertragen werden.
Wenn der Empfänger den Datenbankeintag bereits besitzt, wird die Klasseninformation ausgespart, aber halt:
Hier kommt die Version ins Spiel. Wer sich jemals gefragt hat, warum Extended zu jeder Item-Klasse eine Versionsnummer abspeichert, bekommt hier die Antwort. Die Versionsnummer wird verwendet, um nachzuprüfen, ob Absender und Empfänger eines Items oder einer Kampagne auf dem selben Stand sind. Sollte das nicht der Fall sein, fragt Extended nach, ob man die Version des Senders übernehmen möchte.
Die Datenbank kann immer nur eine einzige Version eines Objekts abspeichern, jedes Item der selben Klasse verhält sich also gleich. Wenn man eine neue Version eines Items erhält (entweder, weil man abspeichert, oder weil man einen neuen Import-Code einfügt), werden automatisch alle Inventar-Instanzen des Items aktualisiert.

Durchbrochene Hierarchien

In der Datenbank wird über innere Objekte eine Hierarchie aufgebaut. Diese Objekthierarchie hat genau zwei Aufgaben:

  • Übersicht beim Erstellen verschaffen
  • dafür sorgen, dass beim Handeln alle notwendigen Klassendaten mitgeliefert werden

Und das war’s. Im Inventar hat sie keinerlei (*) Bedeutung. Das einzige Ordnungsprinzip, das das Inventar kennt, ist die Anordnung der Taschen.
Jedes innere Item wird im Inventar zu einem eigenständigen Gegenstand, selbst, wenn das äußere Item suggeriert, dass das innere Item von diesem produziert/erschaffen/etc. wird oder auf sonstige Weise mit ihm zu tun hat.

(*) Bis auf eine Ausnahme: Wenn man bei einer Tasche festlegt, dass sie nur innere Items enthalten darf, wird es nicht möglich sein, ein anderes Item darin abzulegen.

Jedes Item steht für sich

Dass jedes Item (d.h. jede Instanz) losgelöst von der Objekthierarchie in der Datenbank existiert, hat zwei Konsequenzen.
Einerseits ist es möglich, jedem einzelnen Item einen individuellen Satz von Variablen zu verpassen, also einen individuellen Zustand.
Andererseits ist es nicht mehr möglich, mit einem Item im Inventar Einfluss auf ein anderes zu nehmen.

Typische Fragestellungen:

Wie kann ich die Variablen eines inneren Items verändern?

  • Es ist nicht klar, welches innere Item gemeint ist, denn es könnten mehrere Exemplare im Inventar liegen.
  • Hier liegt ein kategorisches Missverständnis vor: Innere Items sind Eigenschaften der Klasse, aber Variablen gehören zur Instanz.

Wie kann ich das äußere Item löschen?

  • Wie bei der ersten Frage ist nicht klar, welches Exemplar gelöscht werden soll.
  • In diesem konkreten Fall kann man sich behelfen, indem man das Item direkt über die Id anspricht, statt sich auf die Eigenschaft „äußeres Item“ zu verlassen.

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

2 Likes

Extended am Sonntag #19


Texturen und Bilder

Dokumente können Bilder enthalten, ebenso wie Zwischensequenzen. Bei Zwischensequenzen kann man außerdem noch ein Hintergrundbild einstellen.
Während Extended bei Dokumenten eine Bildersuche anbietet, muss man bei Zwischensequenzen den Bildpfad angeben.
Heute wird es darum gehen, wie man an diese Bildpfade kommt.

Grundsätzliches

In Extended können nur Bilder, Artworks oder Texturen aus dem Spielclient verwendet werden, eigene Kreationen (wie z.B. eine Charakterzeichnung) können nicht angezeigt werden.
Die Experten unter uns werden einwenden, dass man Bilder, die im Addons-Verzeichnis liegen, sehr wohl im Spiel anzeigen kann. Das würde dann aber nur auf dem eigenen Rechner funktionieren, was dem Zweck von Extended, nämlich dem Austausch von Items, zuwiderläuft.

Die Bildersuche im Dokument-Editor enthält bereits eine ganze Reihe an Bildpfaden, die man verwenden kann, sie ist aber nicht vollständig.

Die einfache Methode

Im einfachsten Fall ist das gewünschte Bild bereits in der Bildersuche hinterlegt. Wenn man solch einen Bildpfad benötigt, kann man wie folgt vorgehen:

  • Erstelle ein Dummy-Dokument.
  • Suche das Bild mit der eingebauten Bildersuche und füge es ins Dokument ein.
  • Der Bildpfad steht nun als Teil des {img}-Tags im Dokument, z.B. {img:Interface\QuestionFrame\answer-warboard-classic-StonetalonMountains:512:256}. Hier ist der gesuchte Pfad Interface\QuestionFrame\answer-warboard-classic-StonetalonMountains.

Möchte man dieses Bild für eine Zwischensequenz verwenden, benutzt man genau diesen Pfad.

Die fortgeschrittene Methode

Sollte man kein passendes Bild in der Bildersuche finden, kann man zunächst „informiert raten“. Wenn der Standard-Hintergrund für Zwischensequenzen bspw. Interface\DRESSUPFRAME\DressUpBackground-NightElf1 ist, dann gibt es bestimmt auch Interface\DRESSUPFRAME\DressUpBackground-Orc1
Wer einen besseren Überblick haben möchte, kann sich auch auf vorgefertigten Ressourcensammlungen im Internet umsehen. Auf diversen Projektseiten haben sich Addon-Autoren die Mühe gemacht, alle im Spiel enthaltenen Bilder aufzulisten.
:warning: Beachte, dass alle Bilder aus dem Spielclient geistiges Eigentum von Blizzard sind!

Die Expertenmethode

Texturensammlungen im Internet können veraltet oder unvollständig sein. Für alle, die es wirklich wissen wollen, hat WOW eine eingebaute Exportfunktion. Damit kann man alle Bilder aus dem Spiel in ein separates Verzeichnis extrahieren, wie aus einer ZIP-Datei, um sie anschließend zu betrachten.

  1. Besorge dir ein Bildbetrachtungsprogramm, das in der Lage ist, BLP-Dateien anzuzeigen.
  2. Stelle sicher, dass genügend Platz auf deiner Festplatte ist. Du wirst ca. 6 GB benötigen.
  3. Starte das Spiel mit der Konsolenoption:
    Öffne die Spieloptionen im Battle.net (Zahnrad neben dem blauen Startknopf).
    Setze einen Haken in „Zusätzliche Befehlszeilenargumente“. Ein Eingabefeld erscheint.
    In dieses schreibst du -console.
  4. Logge dich auf einem beliebigen Charakter ein.
  5. Gib den Makrobefehl /run SetConsoleKey("z") in den Chat ein. Dieser Schritt ist notwendig, weil die Standardtaste, um die Konsole aufzurufen, sich mit dem deutschen Tastaturlayout beißt.
  6. Logge dich aus. „Ausloggen“, nicht „Spiel verlassen“.
    Du landest wieder im Charakterbildschirm.
  7. Drücke die Taste z, also die eben festgelegte Konsolentaste.
    Ein Konsolenfenster öffnet sich.
  8. Gib ExportInterfaceFiles art ein und drücke dann die Eingabetaste.
    Dieser Befehl braucht seine Zeit. Das Bild kann für mehrere Minuten einfrieren, denn hier werden mehrere GB an Bilddaten entpackt.
    Übrigens: Mit ExportInterfaceFiles code bekommt man den Lua-Code des Standardinterfaces.
  9. Entferne das zusätzliche Argument aus Schritt 3 wieder. Der Makrobefehl aus 5. setzt sich nach einem Spielneustart von selbst zurück.

Nun sollten alle Texturen in _retail_\BlizzardInterfaceArt\ im WOW-Installationsverzeichnis liegen. Wenn du ein passendes Bild gefunden hast, entspricht der Pfad, den du in Extended angeben musst, dem Teil, der mit Interface anfängt, aber ohne die Dateiendung .BLP.


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


(OT) Edit/Nachtrag: Defekte Dokument-Links in Version 1.5.0

In Version 1.5.0 hat sich ein Fehler eingeschlichen, der bewirkt, dass externe Links in Dokumenten nicht mehr angezeigt werden.
Wer diese Feature ausgiebig benutzt, kann auf einen Bugfix warten, oder, im Geiste dieses Threads, die defekte Datei vorab selbst austauschen.
Die Korrektur ist bereits auf dem GitHub von Extended verfügbar. GitHub ist eine öffentlich zugängliche Code-Bibliothek für viele Software-Projekte, darunter auch WoW-Addons wie Extended.

  1. Lade die Datei https://raw.githubusercontent.com/Total-RP/Total-RP-3-Extended/8656bced78199dde22792df5823e5569b7ae99e1/totalRP3_Extended/document/document.lua herunter.
    Auch zu erreichen unter https://github.com/Total-RP/Total-RP-3-Extended/blob/master/totalRP3_Extended/document/document.lua. Von dort klickt man auf „History“ und dann auf das Commit vom 18. März („Document URL fix“). Dort klickt man rechts auf der Titelleiste der geänderten Datei auf weiteres „(…)“ und dann „View file“. Zum Schluss führt ein Klick auf „Raw“ zur gesuchten Datei.
  2. Speichere die Datei in deinem WoW-Installationsverzeichnis unter _retail_\Interface\AddOns\totalRP3_Extended\document\document.lua.

Wer so vorgeht, bekommt das Beste aus beiden Welten, die aktuellste Version, aber ohne den nervigen Bug.
Sobald die nächste Extended-Version erscheint, werden alle Dateien regulär mit der neuesten veröffentlichten Version überschrieben, es ist nicht notwendig, diesen kleinen Vorab-Fix „aufzuräumen“.

2 Likes

Jeah! Vielen dank für die Infos!

1 Like

Extended am Sonntag #20


Kampagne: Hasenjagd

Im letzten Teil dieser Miniserie stelle ich eine kleine Kampagne vor, in der man sich auf die Suche nach allerhand Hasen begeben soll. Natürlich hat das total überhaupt keinen Bezug zu einem gewissen Feiertag, von dem ich nie etwas gehört habe.

Importcode: Hasenjagd !nRv3UTTXs4NLauGc0ARs9VKr7Xq)fBLAlL4v2UNGasrjTIAJPivixzh7IYNKdW5M(mKRYD6f7mZSl)rYYXXXQbhedjXLlNz2z)MVzMLXmV5aZE5H)mkcFwWKzuYOAH8LRuQCR3(kNUM9kcZG1Th8P0Kn4FBYA1WKXAPUEcxAlCdvx8Mo4u)GrbR53A5zpNBjcTMzhWXHB0kvcV58ujCsx13N2gN1P9nz96JxFCd14nBq6VLjlCb311AUTJyS1cF3BN7hSywG9OrcyAT7yYYLlx0WjlJgov4bgw0W5IXZIg6bFkZzYE9zMnbPdw)PCHx0WEGfgnuect8y7qo8006CeQ141lBaQ9WcwGiTDjlCd7uBF4ZrYozUSb)bm(SGOHZShb6ych1P)iBxh7aj3BgOtyeh(0LG16bMEh0QUeVkypy(2HHrd5H6N8grWvU06XrmcxoVSlSCKAhjZ3RJNKhG)uzZ4glJR2DHFjMaMMpiBlXeRqU7utMDGtO6(m2l)dCZVxL81XnC0fG)Jb)5coitMNjRaoqX7lvHKp3YEYK1e4gOOOHBbvenmmp6RMaRshhc8LxP9ELaX6Dn3t6hC7M2IenL7zfFyjpucGJGR6p69T994pzZHmaFYG22YVOEWmqtekdoBfeM1NLUlKbbPX9WV0R2hge1gamTxI4LWeWBc8aX234FZlOn(ySMwIOYAQaCTTdMcGA8rvc4A)Gqje4W9omA42b(rVQlnFBhaRfWfrdBl8C4he9QOxTpbeHGOvFkycI)GNSzG94zU2WghE73U6ZoC6xnyT62fFiunW8AaclmeKZWJ3Rr0q2ED2941ABfVQVeuYCFj)lQKjcBxFhRqjeu(KXmzGWtCDSgT0ZBl41SWgLIbFqIXX6CbS1D2RlA150(daASw9JNN2knzGBF8vwCmIW6A7aWon102KOrK7V9BAQ6RrP1aqeX35Nv3iryl9esRjGPz7nMdmPcpzIazlCTVf2wqN7(5lwVCoYb3B)I1Rwix5ez(RjkRxbZmRXgzz13AibdJ1HVoNL6iopKtpk7Wdpmt4a4l6qaPl5Usaxgc)C6QpdmQem(AEWe75ZLifzhbIIBDma1AWyDIg(MZ7Wg0P3lEbeW8AgS0YxRcPuio5eqW)U98f2oinb4U1Hta5mxtoZfeKbUXBAq0rSM4fx2a)8cyid4bpJgQdDrBuhfmkQsvbKxwW60YOkOD6zoNsqaziHpBrc(SUaKaZb8EBNjzdmqVXZlSOuTcfl9fcmKAqgRprLWoZKvg(cmOYFSKAtb(Q950k70lXV00DD3c5LMPd(vAmqY0A1gIKQ)lgL(LcfIgwO4bLQCqPAW4W(aJ7cq6W9hazXDDjF89gtRgg7bKZfQyGyitxTTMsYm5l6lvPnC8h4ZK8fFlX)XP7)Ir9PreDITkjHzITfI6EjrYVv2FWj0gHmhDmm5tieBNxtOOZXvD7c1QwOY9qXyjgGR5iypcJbNApM)UJobImE3P(t4UHV78Uw9eoZKJ8d84DCN(UQSZSoYoau5Gao3QLTN)IBnaVXjNNWnqmaAB(v2GfFPVoBYCfVFtUR)mVLEohQm7t68YnSA0o)H)ugS4aLmpy6sx3)cLCXyjtPKgHX5q5quHtzxvpSdzBUajgcRL7XaSY)EYdQ36gmnNi8hJg(EU8UFe3cKYN5QPCSwpD1NGIq5OtclqfuSUUuSWoihPhzablNRZDt5CtZZI5MHz4tUckH7HpvhqLytPdupWCBxqhISRUCp9vx1yr(RT3YwKQqvGAEjUGigBGBagyehuFmR9)sP2E971zD129uu6n7tXINFwwiC3w97XExwo2tuKWd6tFDjWcubiWoUJ6BGPvNOuZIb0ej)MP5U63KymskrdxxX9rqfGp)wOoQaXQprLTtm3qsRgur4Ke(GHQwaIzazrsYgM2dJ9iHRqERLe2AVckYsLL7LA9ekqG4iouZw8fR(7zZ3tRUjyvzrdLl9wRBMJvnsS6ZJ4iN5l0Ldk)67XkUNSDvxpnGYn12maRxgq(p7LtD4HlG83WkDjcQdPcNeaM)3bopIL7)xAQrLx4BROWn1JCRnSqTnfWN7F9J2QswyvMkohd6mWw13KHHbUgF4UMEGwyE861YgM84TWG7(R(pkGiS1cB7nUJh4lNrLRbBYJVcXcHej3vUQ8feqbYJKjmaGlegsHtgptWx9FH7Chsq2KFdulOMs5L(sFIQgjAcqAiCKRixdusiwM30z2ldLcoMU(gFStOeUxhEaCXu4jCcSNctb5J5btIXIBVplSpTJS9UJSSvFclfvWHL7jaeh0IatjIwciMRKXl2qFkbJ3Yamui8WDpkF7Tc9Lq5s(hxhE3jygsn7bTS9d)5tfj(xKDu8ja)PtnySpbOwVHhKCNMYyyHltBp5PAtu0X6bfu7lPnlr1lsw5Zoi8R4Wl(MddzAfn4b6CkGda6q8eIUIkMaduYeGC3YKWiiTLmBlwDNWTD1prtHlvIX1(EQiqapGRsnvoGVVBPhF2Cm1NQRQ65FSUQsJhZ2svrQXOMpElv5Z0s1Cr4ylyHaXacUYHyzuiU5kvlA7KwSGEST8xaI3B9J1cUhUtFdz)uF0ElgBHJwspdiJHdxMUdV9WqbjMpcvyKs9G(0qAHRuIepDvOIlyRNU2dBkloyAuI5U1Wh0(PZminY5gvOWKKyGShyqEJQgfQMCRFAJtm4jlUcvkxtbZXOHFsvi83S4QuQAD9rpuHKw1NJ0QvVyDvmFVAK0Q)CKwH6flutDN8gK4Y)82jkBuRAch6uBH7P8WqBhiKQnMw83jupMLs4qPRWSl7PByaJYxdrLldHdcOgbi6XZWlOotE0Jq9FcW1MhhLsT(JE)xnlpjgFRnKBgvMKe8RNs)(YCJG3k4aLUVx7XZmNVw(AvFWCZiWMv973UrMGPD5MX6IDNSxKkYnCzy8gRY3pxww6SDPpBd5UtCAzK5gEnevZQ)9ZRLHzCxKsjLxetP8ZBKs5BEpyDRCNSfKkYn2bYthnzTVFBbzs1TlXTRl2DIplvKB4ZQJdqPuFwNC7gvV)GhAlUhniBQYhRsReNO14Lbqgx5xVZCloWKZsYJw0Ym)7FKtSxU9ZattImq1pp(2NwIDfCmDCY6J8knzPEA9eC1lieCWhV6VHUnYCazjBX6j33vCnmJBGUONTHuv0(65nW31wS5muby6z0i4kPiCTPOxzQv9j9X6O3(lC4cOuYYB)9oGVVH8gXVVbdJdku4G8LtFFetUaUFUY5m0VIJQjVAI8huUYbLGPkX3nb(FRcjDgNudEBTHpz2tie7Z598B4UJHI4KcphaJdnL5rNSe7mOHQ8rd3pAyEddv)Bm9rQrhNBAJA7PhrD6dyNGo0rwSLZJjhDARSJSdcElq(0qDgL7d9YmYfWPPhYyCBuHCaSdt5eWL5QA5hjLv(dPP5)7d

Wie es funktioniert

… muss wohl ein Geheimnis bleiben, denn das kleine Rätsel soll doch nicht gespoilert werden.
Wer dennoch wissen möchte, wie die Kampagne aufgebaut ist, kann nach dem Importieren gern einen Blick in die Datenbank werfen.

Wer weiß, vielleicht findet sich ja jemand, der das Abenteuer weiterführt?


Viel Spaß beim Experimentieren und
:wave: bis irgendwann mal wieder…

2 Likes

Die Textkopiermaschine

Früher, wo alles besser war, wo Extended noch GHI hieß und Gott noch ein DJ war, konnte man den Inhalt von Büchern einfach in ein eigenes Item übertragen.
<Suggestivfrage>Ob das auch mit Extended geht?</Suggestivfrage>

Hör auf zu labern und gib mir die Lösung!

Auf Wago findest du die aktuelle Version des Items: https://wago.io/y8juN17eZ.
Mit einem Klick auf „Import-String kopieren“ erhältst du einen Import-Code, den du wie gewohnt in deine Objektdatenbank einfügen kannst.

  1. Bereite das Dokument-Item („Rohling“) vor, in den der Text eingefügt werden soll. Dieses Item muss ein leeres inneres Dokument enthalten.
  2. Lege die Kopiermaschine in dein Inventar. Du kannst dazu die Datenbank-Funktion „Zu Hauptinventar hinzufügen“ benutzen. Die Kopiermaschine findest du unter „Datenbank anderer Spieler“.
  3. Die Maschine benutzt den Makro-Effekt. Damit sie funktioniert, musst du sie in den Sicherheitseinstellungen freischalten (Alt+Rechtsklick).
  4. Die Kopiermaschine ist ein Behälter. Öffne ihn mit Doppelklick und lege deinen Dokument-Rohling in den ersten Platz der Maschine.
  5. :warning: Beachte: Die Itemdaten deines Rohlings werden verändert! Eventuell vorhanderer Text wird überschrieben. :warning:
  6. Lies die Warnung in Schritt 5.
  7. Öffne das gewünschte Buch bzw. den Brief im Spiel.
  8. Benutze die Maschine per Rechtsklick.

Wenn alles geklappt hat öffnet sich die Datenbank und der Text ist in der Dokumentvorlage sichtbar. Du kannst ihn jetzt weiterbearbeiten.

Wie funktioniert das Teil?

Idealerweise sollte diese Funktion Teil von Extended oder von einem TRP3-Zusatzmodul sein. Ich habe es in ein Item gegossen, um euch ein weiteres Addon zu ersparen. Wer Lust hat, aus dem Code ein Modul zu bauen, darf das gern tun.

Kern des Items ist ein Makro-Effekt. Dieser führt ein Lua-Skript aus, das ungewöhnlicherweise in den Item-Notizen zu finden ist. Hier war also etwas schwarze Magie erforderlich.

Das Skript aus der Item-Notiz ist das eigentliche Herzstück. Der obere Teil sucht nach dem Item (das Item sucht sich quasi selbst), während der eigentliche Kopiervorgang am Ende steht:

local currPage = ItemTextGetPage()
for i = 1,currPage-1 do
	ItemTextPrevPage() -- blättere zur ersten Seite zurück
end
local PA = {}
table.insert(PA, {TX = "{h1:c}" .. (ItemTextGetItem() or "") .. "{/h1}\n" .. ItemTextGetText()}) -- erste Seite mit Überschrift
while ItemTextHasNextPage() do
	ItemTextNextPage() -- alle anderen Seiten einfügen
	table.insert(PA, {TX = ItemTextGetText()})
end
documentClass.PA = PA -- Au weia!

In der letzten Zeile geschieht dann das Ungeheure. Eigentlich sollte man die Itemdatenbank nicht so direkt bearbeiten. In diesem Fall geht alles gut, aber es wäre schöner, wenn die Funktion in das Addon selbst oder in ein Modul wandert, wo sie eigentlich hingehört. :wink:

7 Likes

Mit dem neuen Inhaltsupdate 9.2.5 erhielten auch TRP3 (auf Version 2.3.11.) und TRP3 Extended (auf Version 1.5.1.) ihre Updates, die das oben zitierte Problem beheben. Ich empfehle daher zeitnah auf die entsprechenden Versionen zu updaten.

Womöglich gar auch die ideale Gelegenheit dem „Guide für Backups und der Datenrettung“ nochmals einen Besuch abzustatten, sollte man sich zu den Leidgeplagten zählen, die öfters nach einem Update ihre Flags missen.

▲ Zurück nach oben
▲ Zurück nach oben
Item mit Aufladungen / Begrenzte Anzahl Anwendungen

Einen besonderen Dank an Frejna(@DieAldorEU), basiert die Idee und der erste Entwurf dieser Itemart auf einer Frage zu TRP3E, die sie einst stellte. Eigentlich bestand zunächst gar keine Absicht einen kleinen Guide zu dieser Art Items zu verfassen, liegt das gemeinsame Herumtüfteln mit Frenja auch bereits gut ein Jahr zurück.

Doch wiederkehrende Fragen, die nach dieser oder ähnlicher Möglichkeiten in TRP3E sich erkundigten, legten nahe, dass es womöglich eine hilfreiche Ergänzung für diesen How-To sein könnte.

Dass es so ist, mag verständlich sein, ist die Lösung wohl nicht direkt offensichtlich. TRP3E bietet keine Checkbox an, die mit einem einfachen Klick es ermöglicht ein Item mit begrenzten Aufladungen oder einer begrenzten Anzahl an Benutzungen zu erzeugen. Leider wird man dafür etwas mehr tun müssen als das. Aber keine Sorge, einmal verstanden, ist die Lösung recht simpel.

In diesem Beispiel bauen wir ein simples Puderdöschen, welches genug Inhalt besitzt, um das Näschen genau fünf mal zu pudern.

Sollte man Schwierigkeiten haben, so kann man das Item, welches wir nun bauen, auch als Import-Code weiter unten finden.

Aber der Reihe nach.


Ein Puderdöschen

Zu Beginn brauch es natürlich überhaupt eines Items, welches wir mit den begrenzten Anzahl an Aufladungen ausstatten können.

Der einfachste Weg, um alles zu bekommen, das wir brauchen werden, ist schlicht ein ‚Expertenitem‘ zu bauen. Keine Sorge, es klingt komplexer als es eigentlich ist.

Gegenstand erstellen → Experten-Gegenstand

Auf diesen Gegenstand können nun nach eigener Vorliebe alle Anzeigeeinstellungen ausgefüllt werden. Die für dieses Beispiel wichtigen Einstellungen sind jedoch die folgenden:

  • Ein Häkchen bei ‚Benutzen‘ setzen
  • Die Textvariabel ${useVar::5} in einer der Beschreibungsfelder des Items schreiben

Während die Itemeigenschaft ‚Benutzen‘ womöglich recht selbsterklärend ist, mag die Textzeile ${useVar::5} vermutlich zunächst eher kryptisch erscheinen. Was genau bedeutet sie?

${variabelname} ist ein Textplatzhalter. An dieser Stelle wird in einem Text immer der Wert angezeigt, der unter dem entsprechenden Variablennamen gespeichert ist. In diesem konkreten Beispiel weiter oben also der Wert, der unter der Variabel useVar gespeichert wurde. Noch existiert diese Variabel aber nicht, weswegen wir einen ‚Defaultwert‘ angeben müssen. Dies geschieht, indem wir ::x hinter dem Variablennamen setzen. Wobei X alles Beliebige sein kann. In unserem Beispiel sehen wir eine 5 dort stehen. Das bedeutet, solange die Variabel nicht initialisiert worden ist, wird an dieser Stelle im Text der Wert 5 stehen.

Natürlich, kann dort auch jede andere beliebige Zahl stehen. Welche, das kommt ganz darauf an, wie viele Aufladungen/Benutzungen zu Beginn möglich sind.

Im Beispielitem habe ich diesen Platzhalter in das Feld ‚Rechter Tooltip-Text‘ geschrieben. Jedoch kann er nahezu überall in den Anzeigeeinstellungen verwendet werden. Ebenso kann man ihn in Dokumenten-Items verwenden. Weitere Beispiele kann man im Guide von Seleves zu Dokumente unter TRP3E unter dem Punkt Variablen-Tags in Dokumenten nachlesen.

Warum machen wir das aber? Nun, das ist im Grunde ganz simpel. Wir sollten natürlich demjenigen, der dieses Item benutzt, mitteilen, wie viele Anwendungen ihm noch verbleiben. Es direkt in den Tooltip zu schreiben, ist dabei die offensichtlichste Möglichkeit.

Damit haben wir jetzt ein Item, mit dem wir fortfahren können. Ihr solltet also zu diesem Zeitpunkt etwas haben, das ungefähr so aussieht:

Nun speichern nicht vergessen.

Ein Arbeitsablauf anlegen

Jetzt fehlt nur noch ein Arbeitsablauf, der das Mitzählen von Benutzungen ermöglicht. Keine Sorge, in seiner simpelsten Ausführung ist dieser Arbeitsablauf äußerst kurz. Genaugenommen sind nur drei Schritte wirklich notwendig.

Sobald ihr also einen Arbeitsablauf erstellt habt unter dem Reiter ‚Arbeitsabläufe‘, fügen wir mit ‚Element in Arbeitsablauf einfügen‘ folgende drei Arbeitsschritte ein:

Variabel initialisieren
Effekt → Experte → Variabelnoperation

In diesem Effekt wählen wir die folgenden Einstellungen:

  • Quelle: Objekt
  • Art der Rechenoperation: Initialisierung
  • Variabelnname: useVar
  • Wert: 5

Was genau haben wir damit aber nun bezweckt?

Wir haben eine Variabel erzeugt (initialisiert), die so lange gespeichert wird, wie das Item besteht (Quelle: Objekt). Diese Variabel hört auf den Namen useVar und beginnt mit dem Wert 5.

Sowohl Name als auch der Startwert können frei gewählt werden. Es muss an anderen Stellen dieses Beispielitems nur berücksichtigt werden dann. So z.B. der Variablen-Platzhalter, wie er weiter oben beschrieben wurde.


Variabel subtrahieren
Effekt → Experte → Variabelnoperation

In diesem Effekt wählen wir die folgenden Einstellungen:

  • Quelle: Objekt
  • Art der Rechenoperation: Subtraktion
  • Variabelnname: useVar
  • Wert: 1

Dieser Arbeitsschritt bewirkt, dass, wann immer er durchlaufen wird, die Zahl, die unter useVar gerade gespeichert ist, um 1 reduziert wird. Also, die Ausladungen/Anwendungen des Items reduzieren sich um 1.


Gegenstand verbrauchen
Effekt → Inventar → Gegenstand verbrauchen

Zum Schluss möchten wir natürlich, dass das Item ‚verbraucht‘ wird, sobald alle Aufladungen/Benutzungen aufgebraucht worden sind. Also, der Inhalt des Puderdöschens aufgebraucht worden ist.

Lassen wir diesen Eintrag so nun im Arbeitsablauf stehen, wird er bei jeder Gelegenheit ausgeführt, was wir natürlich nicht wollen. Daher müssen wir ihn mit einer Bedingung belegen:

  • Rechtsklick auf Effekt: Gegenstand verbrauchen
  • Effektbedingung bearbeiten
  • Auf den ersten Eintrag unter ‚Bedingungstest‘ klicken
  • Im linken Feld: Experte → Variablenwert (numerisch) setzen
  • Dort Quelle: Objekt und Variablenname: useVar setzen
  • Im mittleren Feld ‚ist gleich‘ auswählen
  • Im rechten Feld: Direkter Wert → Zahlenwert setzen
  • Dort eine 0 als Wert setzen

Am Ende müsste bei Euch etwas zu sehen sein, das so aussieht:

Damit wurde sichergestellt, dass das Item nur dann aufgebraucht wird, wenn alle Benutzungen aufgebraucht worden sind. Also die Variabel useVar den Wert 0 erreicht hat.

Nun speichern nicht vergessen.

Euer Arbeitsablauf sollte nun folgendermaßen aussehen:

In Worten gefasst, wird der Arbeitsablauf jetzt also folgendes machen: Er wird bei einer erstmaligen Ausführung die Variabel useVar erzeugen. Vor der Benutzung wird im Textplatzhalter der Defaultwert angezeigt. Die Rechenoperation: Initialisierung wird genau ein mal ausgeführt, egal wie oft der Arbeitsablauf durchlaufen wird. Mit jedem Durchlauf wird die Variabel um ein reduziert. Dies geschieht so lange, bis wir den Wert 0 erreichen, worauf das Item zerstört wird. Es wurde also aufgebraucht.

Natürlich kann man diesen Arbeitsablauf noch um eigene Schritte ergänzen. Wie Textmeldungen, die erscheinen, wenn bestimmte Füllstände erreicht worden sind oder aber Klänge, die abgespielt werden, wenn das Items benutzt wird.

Damit wären wir beinahe durch.

Den Arbeitsablauf verknüpfen

Das einzige, was nun noch fehlt, ist es, die Benutzen Aktion mit dem Arbeitsverkauf zu verknüpfen. Dazu gehen wir schlicht in den Reiter ‚Ereignisverknüpfung‘ und wählen für den Punkt ‚Bei Benutzung‘ den Arbeitsablauf aus, den wir gerade erzeugt haben.

Geschafft! Du hast soeben ein Item mit einer begrenzten Anzahl an Benutzungen angelegt.

▲ Zurück nach oben

An dieser Stelle sei bedankt, wer mir bis hier hin gefolgt ist. Und ich hoffe, dieser kleine Guide konnte dem ein oder anderen von Nutzen sein.

Wer auf Probleme stößt oder Fragen hat, darf gerne diese in diesem Thread äußern oder aber im Privaten direkt über den Ingamechat an mich wenden. Oder sie oder er möge in das Beispielitem hinein schauen können. Wie dieser Code zu verwenden ist, kann man hier nachlesen.

TRP3 Extendend Beispiel-Item-Code (klicken zum erweitern ...)

!vk12UTjqq0FM(AIzHqXfj)a(IuTKdo1JV0QQUemS1zBTxIGfRErnFw9hO)y9mluvLK(sfOb25Y5CMzhPqUwMkWRxWlLP(sYluejc8gggDyyuDJmnazqZtH1kP1Vd)JZ0e2BrLPP9Kk5JwvnNarRzlJjP6ag)PlL0586SQ9FsvamYRp00fKQCu((rFGPHABuBZRLPxjPqqg)q49OUbwJK8zhbphCTvDkRxlorv(NW950XFXDQIpNbCYFe79SYSXhhnQVLplt96vXJuILfY)xdEXtBpX)Q9c(lxLkBU(yt3mFXCMKLBE68gHUEQBQpfssmq4pW3)HBfdJf(XEGLjJrS70L5xmvRsowwvlPTqqqlLBHiUm8Yqa)sMpiLT9Bb01WZS3I6bUIObEHD4ge7nmomcy(CCHwEDsNCNS0j35Y9iRv8vjrZXNVCLBTHWNPB4zlD9UUrmTHKD7uuLztd0sc(DSY0A)MYWjmMXMUHGcfVs4kaAyXm0pQ69h1Q9kJ6HB7kP1CqzIDcbsinbf2wQQl)1pBWkGXTLIaVjXDdHMbh2K6CnJTtwX2DZWKkeQCkZQVadTTOIqp4AxcNXno7Ci1iVmTPPOwFVvxzYUxF4KYyZQRAu5w0otCeUctHx89UTG44WFWnwJQOTwB)6c1z1rElX2TF4UASs5V)d

1 Like