Zeige Ergebnis 1 bis 6 von 6
  1. #1
    Benutzerbild von L4nf3ar
    Registriert seit
    Nov 2002
    Ort
    Münster, NRW
    BNet Account
    wolf2
    Beiträge
    602

    Einsteiger Guide zum Trigger-Editor

    Triggern für den Weltfrieden

    Einsteiger Kurz-Guide zum Trigger-Editor von Warcraft 3: TFT



    Vokabeln
    Folgende Begriffe werdet ihr vermutlich häufig hören wenn es um den Auslösereditor geht:

    • Trigger: Ein Auslöser. Besteht aus Ereigniss(en), Bedingung(en) und Aktion(en)
    • Integer: eine Ganzzahl
    • Real: eine Kommazahl. Wird im Editor immer auf zwei Stellen nach dem Komma gerundet.
    • Boolean: ein Wert, der nur entweder "false" (falsch) oder "true" (wahr) ergeben kann. Wird immer dann ausgegeben, wenn irgendetwas geprüft werden soll.
    • GUI: engl. "graphical user interface", zu deutsch "graphische Benutzeroberfläche". Der gesamte Warcraft-3-Editor ist so eine GUI, denn natürlich wird alles was ihr damit anstellt am Ende in eine Programmiersprache (in diesem Fall JASS) umgewandelt.
    • JASS: die Programmiersprache, mit der der Editor arbeitet. Zu Jass gibt es zahlreiche gute Tutorials, auch das offizielle Handbuch ist sehr nützlich.
    • Variable: einfach ein Speicher für irgendeinen Wert oder ein Objekt. Ein Wert kann z. B. "5","9.87" oder "true" sein während Objekte alles ist, was nicht Integer, Real oder Boolean ist. Zum Beispiel Einheiten, Punkte oder Gegenstände.
      Es gibt lokale und globale Variablen (wird weiter unten erklärt)


    Definition
    Trigger (dt.: Auslöser), der: eine Funktion oder Zusammenfassung von Funktionen, die im Spiel einen bestimmten Effekt haben und die über den Trigger-Editor implementiert (eingebaut) werden können.
    Trigger zeichnen sich durch 3 intuitiv verständliche Bausteine aus:
    • Ereignis: eine oder mehrere Situationen, die einmal oder mehrmals im Spiel eintritt und den Trigger auslöst. Ohne Ereignis wird der Trigger niemals seine Aktionen ausführen (es sei denn man löst ihn "manuell" aus). Der Trigger wird ausgelöst wenn IRGENDEINES der Ereignisse eintritt.
    Ereignisse sind durch OR (logisches oder) verknüpft.
    • Bedingung: die Bedingungen müssen beim Eintritt des Ereignisses (und nur dann) erfüllt sein. Der Trigger wird dann und nur dann ausgelöst wenn ALLE Bedingungen erfüllt sind. Ein Trigger ohne Bedingung wird IMMER ausgeführt sobald das Ereignis eintritt. Bedingungen als Baustein des Triggers sind abzugrenzen von den If/Then/Else-Konstruktionen, die man nur im Aktions-Teil benutzen kann.
    Bedingungen sind durch AND (logisches und) verknüpft.
    • Aktionen: dieser Baustein ist das „Herz“ jedes Auslösers. Hier wird definiert, was bei Eintritt irgendeines der definierten Ereignisse und bei Zutreffen aller Bedingungen passieren soll.


    Ich werde mich auf grundlegende Techniken und Möglichkeiten des Trigger-Editors beschränken, die dennoch äußerst erstaunliche Resultate haben können.

    Motivation
    Wer ein eigenes Projekt mit dem Warcraft 3-Editor startet hat normalerweise nicht im Sinn sich auf die Einheiten, Zauber und Möglichkeiten des normalen Spiels zu beschränken.
    Der Editor ist ein ausgesprochen mächtiges Werkzeug, der – wie es beim Starten versprochen wird – viele Eigenschaften des Spiels so stark und vielfältig verändern kann, dass man damit absolut neue Spiele schaffen kann. Es gibt Unmengen von Fan-Maps im Netz, deren Autoren ihren (teilweise umwerfenden) Erfindungsdrang und ihre Ideenvielfalt nur dadurch umsetzen konnten, dass der Editor wirklich vielseitig ist und die meisten Dinge im Spiel verändern kann.

    In diesem Guide behandle ich einen Teil des Editors, der vielleicht der Wichtigste, mit Sicherheit aber derjenige mit dem größten „Impact“ ist. Ohne den Auslöser-Editor ist keine einzige der Millionen Fan-Maps denkbar, die auch nur geringstfügig vom Originalspiel abweicht.
    Anders ausgedrückt: am Trigger-Editor kommt ihr nicht vorbei. Und das wollt ihr auch gar nicht.
    Um euch mal ein bisschen das Wasser im Mund zusammenlaufen zu lassen bevor wir richtig beginnen, ein paar kleine Appetithäppchen:
    • Fast völlige Kontrolle über Zauber. Ihr könnt die aberwitzigsten und abgefahrensten Fähigkeiten, Zauber und Effekte erzeugen, die bis ins kleinste Detail handgefertigt werden können. Der Grad des Aufwandes ist dabei ganz von euch abhängig. Auch mit wenig „Geduld“ und Zeit lassen sich erstaunliche Dinge erreichen, wer ein bisschen akribischer ist und nicht zögert die Profis in Foren um Rat zu fragen der kann seiner Phantasie praktisch jede nur vorstellbare Form geben.
    • Die Freiheit, auf nahezu beliebige Situationen zu reagieren: mit dem Editor lassen sich nicht „nur“ Projekte realisieren, die einigermaßen nahe am Strategie-Rollen-Spiel-Konzept von WC3 festhalten. Ihr könnt auch Moorhuhnjagd, Kartenspiele, Tower-Defense, Creepwars und etliche andere Dinge umsetzen. Als Einsteiger empfehle ich aber dringend, den Auslösereditor zunächst einmal für die einfacheren Projekte zu benutzen, beispielsweise Tower-Defense-Maps oder euer um 10.000.000 geile Features angereichertes, persönliches Warcraft 3… mit eigenen Einheiten, eigenen Fähigkeiten, neuen Features, Anreizen und so weiter und so fort.
    • Für jeden was dabei: wenn ihr durch diesen Guide Lust bekommen habt euch noch tiefer mit dem Editor zu beschäftigen dann gibt es im Editor noch viel viel mehr Möglichkeiten als ihr euch möglicherweise vorstellen könnt
    Irgendwann auf dem Weg zum Profi-Mapper (auf dem auch ich mich derzeit befinde) werdet ihr sogar der graphischen Benutzeroberfläche abschwören und euch auf den „Editor pur“ stürzen, nämlich die Programmiersprache JASS, auf der alles aufbaut. Wer dagegen sofort mit JASS starten möchte: auch dazu gibt es zahlreiche gute Guides, die unschwer zu finden sind.
    Die GUI sollte aber keinesfalls als Einschränkung eurer Kreativität missverstanden werden. Im Gegenteil: ihr werdet Wochen, Monate damit arbeiten und dabei das ungeheuer wichtige Wissen bekommen, das alles dominiert: welche Wege es gibt, euer Ziel zu erreichen.
    Im Trigger-Editor gibt es nämlich so gut wie immer mehr als einen Weg, um eure Vorstellung zu implementieren. Alle Alternativen haben Vor- und Nachteile.
    Insofern halte ich persönlich es für sehr ratsam, erstmal mit der GUI zu arbeiten und später dann auf JASS umzusteigen. Ihr werdet feststellen, dass JASS euch dann sehr einfach fällt, weil ihr fast alle Funktionen schon kennt und versteht. Die Programmiersprache an sich ähnelt Java und C, ist also durchaus nicht schwer zu erlernen.

    Hallo Welt!
    Unsere lehrreiche Reise ins Innere von Warcraft 3 beginnen wir (und hier wird jeder, der mal irgendwas programmiert hat aufstöhnen ^^) mit dem guten, alten „Hallo Welt!“-Programm. Vorweg: ihr werdet keine 5 Minuten brauchen um das hier zu verstehen, vermutlich eher 5 Sekunden.

    Rufen wir uns kurz ins Gedächtnis zurück, was ein Trigger ist.
    Ein Trigger reagiert auf ein Ereignis, prüft die Bedingungen und löst Aktionen aus.

    Wir möchten gerne, dass Spieler 1 (Rot) eine hübsche kleine Nachricht erhält, die ihm „Hallo Welt!“ sagt – auch wenn „Hallo Spieler 1“ vielleicht passender wäre 

    Den Warcraft 3-Editor startet ihr und kümmert euch nicht weiter um die Karte. Das ist eine Standardkarte, die jedes Mal erzeugt wird wenn ihr den Editor startet. Klickt ihr stattdessen auf eine Karten-Datei, so wird diese geladen.
    Öffnet nun den Auslöser-Editor mit F4. Die Shortcuts auswendig zu lernen ist übrigens sehr ratsam und erspart euch viel Zeit und Mausbewegerei!
    Seht ihr das weite Blatt Papier in der Leiste oben? Damit erzeugt man einen neuen Auslöser. Fertige Karten bestehen – je nach Komplexität – aus wenigen bis hin zu hunderten von verschiedenen Auslösern.
    Links seht ihr bereits fertige Auslöser, die zu der Standardkarte gehören. Die brauchen uns hier nicht zu kümmern aber schaut sie euch ruhig mal an und versucht zu verstehen was da passiert.

    Erzeugt nun einen neuen Auslöser und gebt ihm wenn ihr wollt einen aussagekräftigen Namen. Das ist sinnvoll, damit man später (wenn es viele Auslöser gibt) schnell das findet wonach man sucht. Über die Kategorien (Ordnersymbol) lässt sich das Ganze noch besser sortieren.
    Im rechten Fenster seht ihr nun die drei Bestandteile eines Triggers: Ereignis, Bedingung, Aktion.
    Mit den entsprechenden Symbolen aus der oberen Leiste (Shortcuts STRG+E,+D,+R) könnt ihr jeden Baustein erzeugen.

    Im Normalfall fängt man mit dem Ereignis an. Erzeugt also ein neues Ereignis. „Map Initialization“ ist genau richtig, das könnt ihr direkt so stehen lassen und OK klicken.
    Eine Bedingung ist zwar für unser kleines Experiment nicht zwingend erforderlich aber wir sind ja hier zum Lernen
    Erzeugt also eine Bedingung. Es gibt zahlreiche Arten von Bedingungs-Typen, was uns interessiert ist ein simpler mathematischer Ausdruck: ist 7 größer als 5? 7 und 5 sind offenbar Integer-Werte (ganze Zahlen), wählt also „Integer Comparison“. Die blauen Links sind einer der großen Vorteile der graphischen Benutzeroberfläche im Editor. Nicht nur wird der Editor versuchen, sie mit verständlicher Sprache zu verbinden sondern sie erleichtern auch den Zugriff auf die große Vielfalt von Funktionen. Jedem wird wohl direkt klar werden, was hier abgefragt wird. Klickt den linken Link an, und tragt im unteren Feld „Wert“ eine 7 sein. Statt „gleich“ kommt natürlich „größer als“ und statt der 0 kommt eine 5 in unsere Bedingung. Fertig. Alles bestätigen und ab zur Aktion.

    Erzeugt eine Aktion. „Do Nothing“ (Nichtstun) kommt für uns natürlich nicht in Frage
    Der Aktions-Typ hilft jetzt weiter. Was wollen wir? Wir möchten eine Textnachricht an Spieler 1 schicken. So eine Aktion finden wir bei „Spiel“. Ihr habt die Wahl zwischen einer „auto-timed“ Nachricht, deren Anzeigedauer auf der Länge des Textes basiert oder einer „explicitly timed“ Nachricht, deren Dauer ihr selbst festsetzen könnt. „All players“ ist offensichtlich falsch, hier tragen wir die Spielergruppe – Spieler 1 (Rot) ein. Als „Text“ möchten wir „Hallo Welt!“ angezeigt bekommen.
    Fertig.

    Jetzt muss natürlich getestet werden, ob die Karte auch so funktioniert wie wir uns das wünschen. Mit STRG+F9 (oder dem Button oben rechts) startet das Spiel genau die geöffnete Karte. Ihr werdet feststellen, dass euch ein nettes „Hallo Welt!“ begrüßt sobald ihr beginnt.

    Ausprobieren, Testen und immer wieder: experimentieren!
    Nach diesem kleinen Einstiegs-Trigger wird es Zeit für die wichtigste Lektion: einfach immer wieder ausprobieren. Die schiere Fülle an Möglichkeiten im Editor ist dermaßen überwältigend, dass ihr mindestens 2, 3 Wochen gut damit beschäftigt sein könnt einen gewissen Überblick zu bekommen. Schaut euch alle Ereignisse, Bedingungen und Aktionen an, die interessant klingen (natürlich gilt: je mehr desto besser) und übt an einfachen Triggern.
    Da es kein Handbuch und keinen Support seitens Blizzard für den Editor gibt ist die einfachste und spaßigste Art den Umgang zu erlernen, indem ihr wirklich einfach experementiert. Natürlich sind sehr grundlegende Kenntnisse über Informatik vorteilhaft, aber Dinge wie Indizes, Arrays, Variablen, Datentypen und Schleifen kann man auch ohne mathematische Vorkenntnisse sehr gut verstehen.
    Die wichtigsten Begriffe in dieser Übungsphase seien hier zusammengestellt:

    • Variable: Eine Variable könnt ihr euch als Pfeil vorstellen. Ein Pfeil, zum Beispiel an der Autobahn, zeigt nach Hamburg. Es steht auch „Hamburg“ drauf. Aber genauso wenig wie der Pfeil an der Autobahn die tatsächliche Stadt Hamburg ist, ist die Variable das Objekt, auf das sie zeigt. Ich möchte hier keine Einführung in objektorientierte Programmierung geben, deshalb ganz einfach: eine Variable ist ein Pfeil, der auf ein Objekt zeigt. Objekte können im Editor unter anderem Einheiten, Einheitengruppen, Fähigkeiten, Locations (Kombination aus X- und Y-Koordinate), Gebiete….. und vieles vieles mehr sein.
    Der Unterschied zwischen Objekt und Variable ist deshalb wichtig, weil ihr einer Variablen einen anderen Wert (ein anderes Objekt) zuordnen könnt. Wenn das passiert dann verschwindet das vorher gespeicherte Objekt NICHT. Die Variable, erinnern wir uns, ist nur der Pfeil der darauf zeigt. Jetzt zeigt sie eben auf etwas anderes.
    Ausnahmen bei dieser Regel sind die langweiligen Standard-Datentypen: Integer, Real, Boolean (Wahrheitswert) vor allem. Wenn ihr einer Integer-Variable einen anderen Wert zuweist, dann geht der vorher gespeicherte Wert tatsächlich „verloren“. Da das aber nur eine dumme ganze Zahl ist stört es niemanden. Zur not speichert ihr sie eben in eine andere Variable bevor ihr der alten einen neuen Wert zuweist.
    Beispiel: eine Einheiten-Variable zeigt auf einen Fußsoldaten, der irgendwo auf eurer Karte steht. Wenn ihr diese Variable ändert, zum Beispiel auf den Greifenreiter gleich daneben dann geht dabei der Fußsoldat selbstverständlich nicht flöten. Es zeigt nur kein Pfeil mehr auf ihn.
    Anders sieht es aus, wenn ihr z. B. „Remove Unit“ mit dieser Variable aufruft. Dann wird tatsächlich das Objekt gelöscht, auf das der Pfeil zeigt. Dabei wird die Variable automatisch auf „null“ gesetzt (ein künstliches Objekt das nichts macht, nicht mit der Zahl 0 zu verwechseln).
    Es versteht sich wohl von selbst, dass ihr einer Variable nur Objekte von ihrem Typ zuweisen könnt. Einer Einheiten-Variable lassen sich keine Integer-Werte zuweisen und so weiter.
    Das sei an dieser Stelle genug
    • Array: ein Array ist einfach ein Speicher für Variablen. Der lässt sich schön sortieren, man kann über Indizes auf seine Felder zugreifen (in jedem Feld ist eine Variable gespeichert) und es ist alles in allem sehr viel bequemer mit Arrays zu arbeiten als für jede von 100 Einheiten eine eigene Variable anzulegen… wie ihr euch vielleicht vorstellen könnt
    Das erste Array-Feld trägt den Index 0. Das sei hier erwähnt weil man bei Schleifen gerne Arrays auffüllt und dann fälschlicherweise bei 1 anfängt. Das geht auch, aber in dem Fall muss die Arraylänge um 1 größer sein als die Anzahl an Objekten, die darin gespeichert werden sollen (besser gesagt: die Anzahl an PFEILEN auf Objekte).
    Mit Euereinheitenarray[0] könnt ihr also auf das erste Feld zugreifen, und so weiter. Wenn ihr einen Array anlegt und ihm die Größe 10 gebt, dann gehen die Indizes von 0 bis 9.
    • Schleife: Schleifen sind nützliche Konstrukte, die es euch erlauben eine Aktion mehrmals zu wiederholen. Und zwar nur solange, bis eine bestimmte Bedingung erfüllt ist, dann bricht die Schleife ab. Ihr möchtet 100 Einheiten erzeugen, alle vom selben Typ? Na viel Spaß, wenn ihr dazu jedes Mal die Zeile „Create 1 Fußsoldat for……“ nehmt. Besser ist wohl eine Schleife von 1 bis 100, die in jedem Durchlauf 1 Soldat erzeugt. Das Beispiel HAKT natürlich GANZ GEWALTIG weil ihr auch direkt „Create 100 Fußsoldat for…“ nehmen könnt. Sagen wir also ihr möchtet 50 Spezialeffekte, ok?
    • If/Then/Else: Schon wieder so eine Bedingungsabfrage? Ja genau, aber im Gegensatz zu der Struktur von Auslösern könnt ihr hier auch eintragen was passieren soll wenn die Bedingung (If) NICHT eingehalten wird.
    Euer Soldat lebt? -> Heilen
    Euer Soldat lebt nicht (zum Beispiel weil er… tot ist ^^)? -> Wiederbeleben
    Das Prinzip leuchtet sofort ein.
    • Integer: dies ist einer der langweiligen Basisdatentypen und steht für eine positive oder negative ganze Zahl oder 0.
    Besonders oft stolpert ihr über Integer, wenn ihr auf bestimmte Array-Indizes zugreifen wollt, denn das sind ja nur ganze Zahlen.
    Ihr solltet euch gut überlegen, ob ihr Integer oder Real-Variablen erzeugt. Real hat den Vorteil, dass es eine Fließkommazahl ist. Allerdings gibt es viele Funktionen, die nur Integerwerte akzeptieren und genauso viele, die nur Real akzeptieren. In dem Fall muss man das eine in das andere umwandeln. Um Klickerei und Zeit zu sparen empfiehlt es sich genau zu überlegen was man mit der Variable anstellen will.
    • Real: das Ganze für Fließkommazahlen wie z. B. 9,67.
    • Boolean: ein Wahrheitswert, der immer dann ausgespuckt wird wenn irgendeine Bedingung oder logische Abfrage ausgewertet wird. (5>7) zum Beispiel wird natürlich „false“ (falsch) ergeben während (Fußsoldat is alive) „true“ (wahr) ergibt… wenn er lebt. Andere Werte sind nicht möglich, entweder ja oder nein.
    • Leaks: unter einem Leak versteht man, dass ein Objekt von keinem Pfeil (Variable) mehr erreicht wird, das aber trotzdem noch besteht. Sowas ist ärgerlich, weil es Arbeitsspeicher belegt und auf schwächeren Rechnern zu Lags führt. Wer zuviel „leakt“ kann selbst Highend-Rechner ins Schwitzen bringen.
    Für Einsteiger sind Leaks erstmal nicht so ganz primär, ich wollte sie aber trotzdem kurz ansprechen damit ihr wisst wovon die Leute im Forum reden wenn sie über Leaks diskutieren.
    Also:
    Set Punktvariable x = (50.00, 40.00)
    Es wird ein Punktobjekt erzeugt, das den Punkt auf der Karte definiert, der 50 Einheiten in X- und 40 Einheiten in Y-Richtung liegt.
    Set Punktvariable x = (20.00, 40.00)
    Jetzt zeigt x auf ein anderes Punktobjekt. Das alte ist deshalb aber nicht gelöscht worden! Es besteht immer noch, belegt Speicher, man kann aber nichts mehr damit machen. Um das zu vermeiden gibt es einfache Custom-Script-Anweisungen, mit denen man so was manuell löschen kann. Der Speicher wird freigegeben und alle sind glücklich.
    Am ehesten müsst ihr euch um Leaks sorgen wenn es um Punkte auf der Karte oder um Einheitengruppen handelt. Simple Custom-Scripts helfen da aus der Patsche und sind schnell in Guides oder im Forum gefunden.
    Für kleine Karten ohne viele Trigger (besser gesagt: ohne viel Objekterzeugen) ist das Leakentfernen nicht unbedingt nötig, gewöhnt es euch aber am besten schon am Anfang an, dann macht man es später ganz nebenbei aus Routine.
    Einige andere objektorientierte Sprachen wie Java haben übrigens ein eigenes S
    Subprogramm namens „Garbage Collector“ um solche Leaks zu beheben. Ach wie schön wäre es wenn Jass das auch hätte
    • Custom Script: Über diesen Begriff werdet ihr früh und ständig stolpern wenn ihr in Foren unterwegs seid. Custom Script (dt. etwa: „selbsterzeugtes Skript“) werdet ihr an der einen oder anderen Stelle verwenden, wenn die GUI mal nicht mehr weiter weiß. Jass ist eine ziemlich umfassende Programmiersprache und nicht alle Möglichkeiten davon wurden in der graphischen Oberfläche vom Editor berücksichtigt. Wenn es ein Problem oder eine Aufgabe gibt, die ihr so ohne weiteres nicht lösen könnt dann ist Custom Script euer Freund.
    Ihr weist das Programm an, eine Zeile Code auszuführen der direkt in Jass geschrieben ist. Für Einsteiger ist Custom Script fast ausschließlich beim Leakentfernen wichtig. Später dann ist es eine Art „Übergang“ zwischen GUI-unterstützter und reiner Jass-Programmierung. Warum?
    Nun, ihr könnt jeden Auslöser in „eigenen Text“ umwandeln. Das ist etwas verwirrend beschrieben, heißt aber nur, dass ihr den Auslöser danach in reinem Jass-Code vorliegen habt, ohne die schöne graphische Oberfläche mit Ereignis, Bedingung, Aktion und so. Nun will ich ja nicht auf die Vorteile der GUI verzichten nur um ein, zwei Zeilen Jass-Code manuell zu schreiben. Deshalb lasse ich den Trigger wie er ist und füge diese Zeilen als Custom Script ein. Gut, was?
    • Gameplay-Konstanten: das sind wichtige Werte, die ihr über „Erweitert“->Gameplaykonstanten aufruft. Viele davon sind selbsterklärend. Hier könnt ihr zum Beispiel das Essenlimit ändern, die Auswirkungen verschiedener Rüstungs- und Angriffstypen verändern oder neue Hauptquartier-Typen definieren.


    Fehlerquellen, Tipps und Tricks
    Obwohl der Editor wie gesagt ein sehr umfangreiches und mächtiges Tool ist, sind manche Features, sagen wir mal, etwas unglücklich ausgedrückt. Oder sie werden nicht genügend erklärt. Oder sie haben Eigenschaften, die man so ohne weiteres nicht sieht und dann wundert man sich warum der doofe Trigger nicht macht was er soll
    Wannimmer ihr ein Problem habt schaut erstmal kurz in die Foren-Stickies rein, 99% der Einsteigerprobleme hatten nämlich bereits viele Leute vor euch. Die Suchfunktion ist auch nett, spuckt aber nicht immer hilfreiche Titel aus
    Wenn ihr dann doch einen neuen Post macht, dann am besten nicht für ein Mini-Problemchen sondern für mehrere Probleme, über die ihr im Laufe der Zeit gestolpert seid. Sehr hilfreich ist, wenn ihr dazu euren Trigger postet, aber nur den relevanten Teil. Niemand hat Lust sich massenhaft uninteressante Zeilen durchzulesen.

    Ich werde jetzt mal aus dem Nähkästchen plaudern was man so alles als Anfänger vermutlich NICHT weiß und auch nicht auf den ersten Blick rausbekommt. Ich werde euch über einige… Eigenheiten des Editors aufklären und ein paar Dinge erwähnen, die man einfach wissen sollte.

    Casting Unit, Triggering Unit, Last Created Unit… aaargh?
    Keine Sorge, Einheiten (Units) sind halt ein großer Part vieler Karten.
    Casting Unit: sollte NIE verwendet werden, nehmt stattdessen „Triggering Unit“! Fragt nicht warum, macht es einfach
    Triggering Unit: bezeichnet die Einheit, die im Ereignis steht. Ist das Ereignis zum Beispiel „Einheit fängt an eine Fähigkeit zu wirken“ dann bezeichnet es genau diese Einheit.
    Last Created Unit: Diesen Begriff werdet ihr sehr sehr oft verwenden, wenn ihr mit Dummy-Einheiten arbeitet (s. weiter unten). Ihr erzeugt eine Einheit per Auslöser, jetzt möchtet ihr irgendwas damit anstellen? „Last Created Unit“ ist eure Wahl
    Warum kann ich meine eigenen Zauber nicht per Trigger wirken? Da stehen nur die normalen Zauber aus dem Originalspiel!!
    Ja, und genau die braucht ihr auch. Immer wenn ihr einen eigenen Zauber entwerft müsst ihr ja einen der Zauber aus dem Originalspiel dazu verwenden. Der wird dann kopiert und die Kopie könnt ihr neu benennen, die Effekte ändern usw.
    Alle Kopien haben denselben "Order String" wie ihr Original. Das bedeutet wenn ihr einen Zauber "Gelber Blitz" bastelt, der auf der Orc-Heilwelle beruht dann müsst ihr um ihn per Trigger auszulösen eben Orc-Heilwelle wirken lassen.
    Vorsicht: nie einer Einheit zwei Zauber mit demselben Order String geben sonst weiß sie nicht welchen sie benutzen soll.
    • [b]Shift, euer treuer Freund[/u]
    Die Shift-Taste ist eine Art Bodyguard, der euch vor einigen ausgesprochen frechen Einschränkungen im Editor und in den Gameplay-Konstanten (siehe unten) schützt. Manche Werte will das Spiel partout nicht unter/über bestimmte Grenzen setzen. Zum Beispiel wird es sich hartnäckig weigern, einer Einheit negative Rüstung zu geben. Das ist aber manchmal ja gewollt und praktisch. Statt normal „Enter“ zu drücken um den Wert zu ändern versucht es mal mit Shift+Enter. Danach ist der Editor brav wie ein Schäfchen und fügt die Werte ein, die ihr eintippt. Manchmal hilft allerdings selbst das nicht weiter. Nobody’s perfect ^^
    Einheit beginnt, eine Fähigkeit zu wirken vs. Einheit beginnt den Effekt einer Fähigkeit
    Machen wir uns nichts vor, die meisten Trigger in Fanmaps sind solche, die Fähigkeiten abändern. Wer will schon die langweiligen Skills aus dem Originalspiel? Ich möchte viel lieber einen Sturmhammer, der beim Aufschlag zersplitter, nach 3 Sekunden weitere Ziele mit 5 weiteren Hämmern trifft, dabei noch naheliegende freundliche Leichen wiederbelebt und am Ende ein Gewitter über der ganzen Karte erzeugt, das alles kaputtmacht. UND der außerdem noch vergiftet…
    Naja, oder so ähnlich, hust hust. Ist übrigens ein ziemlich einfacher Trigger, nix allzu Schweres dran. Versucht es dochmal

    Also jetzt aber zur Sache. Was ist der Unterschied zwischen den zwei Ereignissen? Das erste (Fähigkeit wirken) tritt dann ein wenn eine Einheit sich darauf „vorbereitet“ einen Skill zu benutzen. Wichtig ist, dass sie den Skill NOCH NICHT begonnen hat. Das heißt unter anderem, dass der Cooldown nicht aktiviert wurde und dass der Spieler sie noch immer mit einem schnellen „Stopp“-Befehl vom Zaubern abhalten kann. Stellt euch vor, ihr verursacht als Aktion einen Flammenstoß, der nahe Gegner röstet. Der Spieler drückt aber flott auf „S“ (stoppen) und die Einheit verbraucht weder Mana, noch wird der Cooldown aktiviert. Euer Auslöser macht aber trotzdem was er soll und erzeugt den Flammenstoß.
    Unschön 

    Das zweite Ereignis ist, was ihr wollt. Sobald der EFFEKT einer Fähigkeit gestartet wird wird sowohl der etwaige Cooldown ausgelöst als auch alle anderen Effekte des Zaubers ausgelöst (Mana wird verbraucht usw.).

    Es gibt aber auch viele Situationen, in denen die erste Variante zum Erfolg führt, die zweite aber nicht. Stellt euch vor, ihr wollt nach dem Beginn des Wirkens erstmal überprüfen, ob die Einheit mehr als 50% Trefferpunkte hat. Wenn nicht -> Zaubern abbrechen. Das klappt nur mit „beginnt, eine Fähigkeit zu wirken“, denn wenn der Effekt eintritt ist es schon zu spät.

    Ganz wichtig: diese zwei Ereignisse verhalten sich auch dann so, wenn die Fähigkeit keine Zauberzeit hat, also sofort gewirkt wird. MERKEN!
    Bewegungsgeschwindigkeit
    Wenn die Einheit im Objekteditor als Bewegungsgeschwindigkeit 0 hat, dann könnt ihr diese nicht per Auslöser erhöhen. Aus einer unbeweglichen Einheit, z. B. einem Gebäude lässt sich per Auslöser keine bewegliche machen. Das gilt auch umgekehrt! Eine laut Objekteditor bewegliche Einheit könnt ihr nicht auf Geschwindigkeit 0 setzen, das Minimum ist 1. Beide Dinge sind nur über den Objekteditor möglich.
    Maximales Leben und Mana
    Ihr könnt per Auslöser die Trefferpunkte und das Mana einer Einheit nicht über das Maximum setzen. Besser gesagt: nicht per „Set Life/Mana of Einheit to …“. Das Gleiche gilt für das Minimum: unter 0 geht nicht. Workarounds dazu: siehe Forum.
    Helden-XP und mehr
    Das Erfahrung-Sammeln könnt ihr in den Gameplay-Konstanten ausschalten. Auch andere Heldeneigenschaften sind dort veränderbar, zum Beispiel so, dass ein Skill jedes Level erhöht werden kann und nicht – wie im normalen Spiel – nur alle 2 Level.


    Dummies: euer wichtigstes Werkzeug
    Zugegeben, der Name ist nicht sehr schmeichelhaft. „Dummies“ sind spezielle Einheiten, normalerweise unsichtbar für die Spieler, die die ganze dreckige Arbeit für euch erledigen. Wenn ihr eigene Fähigkeiten baut werdet ihr fast zwangsläufig über die Dummies stolpern. Natürlich sind die Skills aus dem Originalspiel schon ganz nett und man kann sie durchaus auch mal verwenden „so wie sie sind“, also nur im Objekteditor ein paar Werte verändern.

    Was aber ein kreativer Mapper ist, der will alles ganz anders. Nehmen wir mal ein ganz simples Beispiel zur Demonstration:

    Euer Held (nennen wir ihn Ridcully) soll einen Feuerball auf den Gegner schleudern.
    Haha, prima, den gibt’s ja schon als Fähigkeit. Warum brauchen wir jetzt einen Dummy?
    Der Feuerball soll… danach weiterspringen! Boah! Gut, was?

    Ablauf:
    1. Feuerball-Zauber im Objekteditor erzeugen und dem Helden geben.
    2. einen weiteren Feuerball-Zauber im Objekteditor erzeugen. Dieser soll alle Eigenschaften des „weiterspringenden“ Feuerballs haben. Zum Beispiel könnte der Schaden nur 50% vom primären Feuerball sein. Oder vielleicht stunnt er nicht so lange (oder gar nicht).
    3. dieser zweite Feuerballzauber wird jetzt eurem Dummy gegeben -> was genau der Dummy ist erkläre ich sofort.
    4. Ab in den Auslöser-Editor: Ereignis: „Einheit startet den Effekt einer Fähigkeit“. Bedingung: „Fähigkeit = Feuerball“.
    Aktion:
    a. Erzeuge an der Position vom Primärziel eine Dummyeinheit
    b. Befehle ihr, den sekundären Feuerball auf irgendeinen nahen Feind zu wirken
    c. Füge dem Dummy einen Expiration Timer hinzu (warum? Kommt gleich!)

    Ihr seht also, der Dummy macht all das, was durch das Originalspiel nicht vorgesehen ist. Weil der Dummy unsichtbar ist sieht es so aus, als ob Ridcully einen weiterspringenden Feuerball zaubert. Er trifft erst sein eigentliches Ziel und von dessen Position aus fliegt ein weiterer Feuerball zu einem anderen Feind.

    Dummies sind üüüberaus hilfreich und alles, was ein bisschen komplexer ist setzt mindestens einen Dummy voraus.

    Was müsst ihr dabei beachten?
    Nehmt eine kleine Einheit, z. B. den Soldaten, erzeugt davon eine neue Einheit, nennt sie „Dummy“ (oder so ähnlich ^^). Jetzt löscht ihr erstmal das Einheiten-Modell im Objekteditor. Shift+Enter, dann „.mdl“ eintragen, ohne Dateinamen. Die erzeugte Fehlermeldung könnt ihr getrost ignorieren.
    Bewegung auf 0, Drehbewegung mit Shift+Enter auf 10000000 (Maximum halt).
    Ganz wichtig: Zauberpunkt und Zauber-Rückbewegung auf 0.00 setzen. Das ist Wichtig mit einem großen W!
    Als Fähigkeiten sollte jeder Dummy generell haben:
    • Heuschrecke: der Dummy kann nicht mehr ausgewählt werden, zeigt seinen HP-Balken nicht an und hat keine Kollisionsgröße. In seltenen Fällen ist Heuschrecke nicht so gut, dann müsst ihr es per Trigger manuell entfernen (mehr dazu Forum).
    • Unverwundbar (Neutral): selbsterklärend, ihr wollt ja nicht dass er aus Versehen von Flächenschaden getötet wird, oder?

    Gebt ihm ruhig viel Mana und Trefferpunkt, schaden kann es nicht.
    Seine Wiederbelebungseigenschaften: „kann nicht erweckt werden, zerfällt“

    Um den sekundären Feuerball casten zu können muss der Dummy ihn natürlich erstmal haben. Entweder fügt ihr ihn direkt im Objekteditor als Fähigkeit hinzu oder (meist besser) per Auslöser (Add Ability).

    Kommen wir zu dem ominösen „Expiration Timer“. Dieser sorgt dafür, dass der Dummy nach einer bestimmten Zeit automatisch stirbt. Das ist wichtig, weil ihr sonst im Laufe der Zeit die ganze Karte mit Dummies pflastert, die die Performance beinträchtigen. Außerdem sind sie in gewisser Weise „Leak“, weil es sich um Dinge handelt die keine Sau mehr braucht.
    Natürlich könnt ihr auch „feste“ Dummies auf der Karte setzen, die nicht sterben sollen sondern immer mal wieder irgendwas zaubern sollen.


    Zum Abschluss eine kleine Aufgabe: ihr möchtet, dass der Feuerball sich nach dem Aufprall in FÜNF weitere Feuerbälle aufteilt, die bis zu 5 nahe Gegner treffen. Tipp: man kann per Schleife einfach 5 Dummies erzeugen und……

    Lokale Variablen und "Wait" (für Fortgeschrittene)
    Wenn ihr gerade anfangt mit dem Triggereditor zu arbeiten solltet ihr diesen Absatz erstmal auslassen. Wenn ihr allerdings "Shadowing" (s. unten) nutzen wollt ist dieser Absatz wichtig für euch. Ihr braucht ihn nicht voll zu verstehen um Shadowing anzuwenden, es macht Einsteigern das Lösen vieler Probleme aber deutlich einfacher.
    Wie ihr wisst könnt ihr im Auslösereditor Variablen anlegen. Das sind GLOBALE Variablen. Warum? Weil sie ÜBERALL (global eben) benutzt werden können. Sie können auch ÜBERALL verändert werden. Egal in welchem Trigger, egal an welcher Stelle, egal ob in Ereignis, Bedingung oder Aktion: ihr könnt jede globale Variable abfragen.
    Genau das ist das Problem. Was, wenn ihr ausschließen wollt, dass eine Variable verändert wird?
    Deshalb gibt es LOKALE Variablen. Die lassen sich aber leider nicht im GUI anlegen sondern ihr müsst sie per Custom Script erzeugen oder gleich den ganzen Auslöser in Jass schreiben. Für viele Trigger reicht Custom Script aus:
    Erzeugung einer lokalen Variable: "local xyz name" [xyz ist der Variablentyp, z. B. unit (Einheit), group (Einheitengruppe), location (Punkt), integer (Integer) und so weiter]
    Änderung einer lokalen Variable: "set name = ..." [zum Beispiel "set lunit = LastCreatedUnit()", wobei lunit der Name einer lokalen Einheit-Variable ist]

    Lokale Variablen müsst ihr immer als erste Aktion(en) erzeugen. Versucht nicht, sie mittendrin zu erzeugen, das klappt nicht.
    Lokale Variablen könnt ihr nur in DIESEM EINEN AUSLÖSER verwenden, in dem sie definiert sind. Genauer gesagt: in der Jass-Funktion, in der sie definiert sind. Es ist aber, wenn ihr Jass statt GUI benutzt möglich die Werte von lokalen Variablen an andere Funktionen zu übergeben, als Parameter.
    Das Schöne an den "locals" ist, dass sie untrennbar mit ihrem Auslöser (ihrer Funktion) verbunden sind. Jeder einzelne Aufruf dieser Funktion (jede "Instanz") erzeugt sozusagen eine andere Variable. Wenn ihr aber auf eure local zugreift weiß das Programm ganz genau, welcher Aufruf gemeint ist und kann damit den richtigen Wert für die lokale Variable finden.
    Sie kann wie gesagt nicht von anderen Auslösern oder Funktionen verwendet werden (nur ihr Wert kann übergeben werden) und diese können sie auch in keinem Fall verändern.

    Angenommen, ihr möchtet Last Created Unit abspeichern, einen Wait einbauen und dann wieder darauf zurückgreifen. Ihr speichert sie also in eine globale Einheit-Variable namens "globalunit". Während des Waits kann es passieren, dass "globalunit" - weil sie GLOBAL ist - irgendwo anders verändert wird. Wenn der Auslöser nach dem Wait weiterläuft hat die Variable also den falschen Wert.
    Mit einer local wäre das nicht passiert: die gehört exakt diesem einen Aufruf des Auslösers an und hat auch nach dem Wait den richtigen Wert. Wenn der Auslöser derweil nochmal gestartet wird erzeugt er eine weitere local, die auf denselben Namen hört, aber einen anderen Wert hat. Das Programm weiß, welche local zu welchem Auslöser-Aufruf gehört. (Ein Hinweis warum das so ist zeigt sich schon, weil in jedem Aufruf die Initialisierung mit "local xyz name" vorgenommen wird. Jeder Aufruf erzeugt seine "persönliche" lokale Variable).

    Lokale Variablen werdet ihr oft brauchen wenn "Zeit vergeht", also besonders bei Wait und Wait until Condition. Aber auch wenn ein Timer ablaufen soll, ein periodisches Ereignis eintreten muss etc.

    Shadowing
    Dieser Abschnitt setzt voraus, dass ihr wisst wie man lokale Variablen erzeugt und verwendet.
    Shadowing haftet ein bisschen das Gefühl von "Trickserei" an, es ist eigentlich nicht von Blizzard vorgesehen gewesen und es könnte auch sein, obwohl sehr unwahrscheinlich, dass es irgendwann entfernt wird.
    Shadowing ist eine Möglichkeit, eure lokalen Variablen wie globale zu behandeln. Das bedeutet, ihr könnt die bequeme graphische Oberfläche benutzen um sie aufzurufen, zu benutzen und zu verändern. Statt das Ganze in Jass tun zu müssen. Gerade für Einsteiger also seine sehr schöne, einfache Möglichkeit in den Genuss der Vorteile von locals zu kommen ohne aber großartig Jass anzuwenden.
    Ihr definiert eure lokale Variable wie schon erwähnt per Custom Script: "local integer udg_meineZahl"
    Dann erzeugt ihr wie gewohnt im Editor eine globale Variable und nennt sie "meineZahl".
    Der Trick ist einfach nur, dass globale Variablen in Jass immer ein udg_ vorangestellt bekommen, um sie von den lokalen zu unterscheiden. Wenn ihr nun aber einer lokalen Variable einen udg_-Namen (hier: udg_meineZahl) gebt dann "überdeckt" sie jede globale Variable, die genauso heißt. Wenn ihr im Editor eine globale Variable namens "meineZahl" erzeugt, dann heißt sie in Jass "udg_meineZahl", und diesen Namen habt ihr bereits einer lokalen Variable gegeben.

    Der Effekt: in diesem Auslöser (und nur dort!) könnt ihr jetzt beliebige Aktionen ausführen und braucht dazu überhaupt kein Jass. Benutzt überall, wo ihr die lokale Variable braucht einfach die globale. Das Programm ist angewiesen, bei Namenskonflikten lokalen Variaben den Vorrang zu lassen. Das heißt im Endeffekt wird jedesmal eure lokale Variable verwendet. Gut, was?
    Ausnahme: Bedingungen, sowohl im Auslöser als auch in If/Then/Else-Konstrukten können diese Variable leider nicht benutzen. Das liegt daran, dass im GUI erzeugte Bedingungen in Jass als eigene Funktionen realisiert werden. Und wie wir wissen kann eine lokale Variable immer nur in einer einzigen Funktion benutzt werden. Diese Ausnahme lässt sich tatsächlich nur umgehen wenn ihr den Jass-Code manuell eingebt.

    Somit ist Shadowing eine angenehme Art, lokale Variablen zu nutzen und trotzdem nicht auf den Komfort der GUI zu verzichten.

    Multi Unit Instanceablity (MUI)
    Dieser Abschnitt richtet sich an Einsteiger, die bereits etwas Erfahrung im Editor gesammelt haben.

    Wenn ein Ereignis auf eurer Karte (am besten kann man das an Zaubern erklären) parallel ausgeführt werden kann - das heißt wenn es mehrfach gleichzeitig aktiv sein kann - dann gibt es sehr schnell Probleme mit Variablen. Diese werden unerwünscht überschrieben und das Ganze funktioniert einfach nicht. In sehr einfachen Fällen kann man sowas noch umgehen, indem man einfach verschiedene Variablen einsetzt. Aber generell lassen sich alle parallelen Fähigkeiten nur mit MUI-Triggern realisieren.
    MUI steht eben für die Eigenschaft, dass alles wie gewünscht abläuft obwohl der Trigger eine Begebenheit realisiert (z. B. eine Fähigkeit), die mehrfach gleichzeitig aktiv sein kann. Wir sprechen dann von sogenannten "Instanzen" eines Zaubers. Für den Rest des Abschnitts bleibe ich dabei vom Zauber zu sprechen, denn Fähigkeiten sind am häufigsten der Grund, weshalb man MUI benötigt

    MUI zu erreichen geht, grob gesagt, auf 3 Wege:
    1. Ausnutzung der "Custom Value" von Einheiten. Dieser kann man künstlich (also per Trigger) einen einzigartigen Wert geben. Nachteil: funktioniert nur mit Einheiten (Doodads oder Spezialeffekte beispielsweise haben keine Custom Value) und ist in manchen Situationen zu beschränkt. Vorteil: einfach zu verstehen, einfach zu basteln, extrem schnell.
    2. Benutzung von Hashtables (Hash-Tabellen). Vorteil: alle Objekte in WC3 können benutzt werden (z. B. Doodads, Einheiten, Spezialeffekte, Locations, Einheitengruppen, Gebiete usw.), die Einzigartigkeit der "HandleID" ist automatisch gewährleistet. Nachteil: Ziemlich langsam, etwa 3x langsamer als Arraysysteme.
    3. Parallele Arrays. Da ich diese nie benutze muss ich euch hier an andere Quellen verweisen, es gibt aber sehr gute Guides dazu. Die Vorteile ähneln denen von Hashtabellen, Arrays sind außerdem deutlich schneller. Der Nachteil ist aber zweifellos, dass sie kompliziert sind und nicht einfach gewartet werden können. Außerdem muss die Einzigartigkeit genau wie bei Custom Values (hier nur komplexer) künstlich selber gewährleistet werden. Gerade für Einsteiger würde ich eher zu den ersten beiden Methoden weisen.



    Zunächst lege ich euch ans Herzen meinen Video-Guide zu MUI anzuschauen. Es gibt dort auch weitere Beispiele zum Üben!

    Custom Value
    Jede Einheit hat eine sogenannte Custom Value, die nur Integerwerte speichern kann. Man kann die Custom Value für viele verschiedene Dinge gebrauchen, deshalb ist das ein Nachteil für MUI. Denn wenn man die CV zum Beispiel schon nutzt um (nur als Beispiel) der Einheit die Anzahl von Gegnern um sie herum zuzuweisen, dann ist sie nicht mehr für MUI-Fähigkeit geeignet.
    Deshalb ist MUI per Custom Value zwar einfach umzusetzen, man muss sich aber schon beim Beginn der Kartengestaltung klar sein, dass man danach die Custom Value nicht mehr für andere Zwecke nutzen kann.

    Etwas anders sieht es aus wenn ihr CV-MUI (Custom-Value-MUI) nur für Dummyeinheiten benutzt, die im Regelfall sowieso recht flott wieder entfernt werden. Für Dummies werdet ihr die Custom Value normalerweise nicht anderweitig einsetzen - natürlich gibt es auch da Ausnahmen.

    Generell ist MUI per Custom Value also immer dann eine gute (und einfache!) Wahl, wenn es darum geht, dass ihr Zauber mit Hilfe von Dummies abwandelt. Zu jedem Zauber gehört dann ein oder mehrere Dummies und denen könnt ihr einzigartige Custom Values zuweisen, um sie eindeutig zu markieren.

    Zum Beispiel so:
    cv_dummy ist eine Integer-Variable mit dem Anfangswert 0.
    Setze Custom Value von Dummy auf cv_dummy
    Setze cv_dummy auf (cv_dummy + 1)
    Wenn cv_dummy > Grenzwert, dann Setze cv_dummy = 0.

    Auf diese Art bekommt jeder Dummy garantiert eine andere CV solange der Grenzwert nicht erreicht ist. Diesen könnt ihr natürlich ganz nach euren Wünschen setzen, bei einem Grenzwert von 1000 sind zum Beispiel 1000 unterscheidbar Dummies möglich.

    Um euren MUI-Zauber zu basteln braucht ihr jetzt noch Arrays mit je 1000 Slots, die die MUI-Komponenten (z. B. Lebenszeit für einen Spezialeffekt oder Ziel für einen Zauber) enthalten.

    Wenn der Dummy benutzt wird braucht ihr nur noch Array[cv_dummy] zu nutzen und habt garantiert das richtige Ziel, die richtige verbleibende Lebenszeit für Spezialeffekte und so weiter gewählt.

    Hashtables und HandleID
    Von den englischen Begriffen braucht ihr euch nicht abschrecken lassen. Hashtabellen könnt ihr in der GUI wie ganz normale Excel-Tabellen benutzen, das heißt ihr gebt nur Zeile und Spalte an und bekommt dann einen Wert zurück. Oder ihr speichert dort etwas ab.
    Warum sind Hashtables jetzt für MUI interessant?
    Jedes Objekt (Einheiten, Spezialeffekte, Doodads, Einheitengruppen, Regionen usw.) in Warcraft3 hat eine HandleID, eine garantiert (!) einzigartige ganze Zahl. Custom Values müsst ihr erstens SELBER einzigartig machen (was Aufwand bedeutet) und zweitens gibt es sie nur bei Einheiten, nicht aber bei Spezialeffekten, Doodads und so weiter.
    Also liegt hier schonmal ein großer Vorteil. Ihr könnt also als "Referenz" eures MUI-Zaubers nicht nur Einheiten (z. B. den Zaubernden) benutzen sondern auch alle anderen Objekte. Angenommen ihr möchtet ein Doodad, einen Baum erzeugen und dieser soll dann, was weiß ich, umliegende Einheiten mit Kastanien bewerfen (LOL ^^). Intuitiv würde man also gerne etwas haben, was diesen speziellen Baum eindeutig charakterisiert. Doodads haben aber keine Custom Value! Lösung: HandleID!
    Außerdem sind Hashtabellen im Gegensatz zu dem Array den man bei Custom Value benutzt sozusagen "unbegrenzt", ihr braucht euch keinerlei Gedanken über Indexe und Grenzwerte zu machen.
    Außerdem braucht ihr normalerweise nur eine einzige Hashtabelle um ALLE MUI-Zauber in eurer Karte zu verwalten. Das liegt daran, dass die Hashtabelle eben unbegrenzt ist.
    Anstatt die MUI-Komponente (z. B. verbleibende Lebenszeit, verursachter Schaden, irgendwelche Realwerte usw.) wie bei Custom Value in Arrays zu speichern reicht bei Verwendung von Hashtabellen ein einzelner Wert - eine weitere Vereinfachung.

    So. Bis hierhin klingt es also sehr vorteilhaft, HandleIDs zusammen mit Hashtabellen zu benutzen.
    Es gibt aber durchaus auch Nachteile:
    - es dauert etwa 3 mal so lange etwas aus Hashtabellen zu lesen oder dort zu speichern wie bei normalen Arrays. Wenn ihr viele hochfrequente Trigger benutzt, die auf Hashtables zugreifen kann das schonmal zu Verzögerungen im Spiel führen. Durch geschicktes Verwenden von globalen Variablen ist dieses Problem eingrenzbar, trotzdem sind Arrays im Zweifelsfall immer deutlich performanter.
    Warum ist das so? Weil Hashtabellen besondere (komplexe) Formeln benutzen um auf ihre Felder zuzugreifen. Der Vorteil dieser Hashfunktionen ist, dass alles sehr platzsparend gespeichert werden kann, der Nachteil eben, dass es lange dauert um es wiederzufinden. Jedenfalls länger als bei Arrays.
    - Ihr müsst mehr Variablen anlegen. Das ist ja nun kein wirklicher Nachteil aber manchmal stört es schon, wenn man im Editor für jeden Zauber an die 10-20 Variablen anlegen soll. Die richtige Benennung sorgt aber dafür, dass ihr trotzdem nicht durcheinander kommt.


    Wie läuft das Ganze konkret ab?
    Ihr speichert die HandleID von eurem Referenz-Objekt ab, beispielsweise von der zaubernden Einheit. Diese HandleID, ein Integerwert, wird jetzt als Zeilennummer in eurer Hashtabelle benutzt. Weil HandleIDs einzigartig sind stehen in dieser Zeile nur MUI-Komponenten, die GENAU ZU DIESEM Referenzobjekt gehören. Alle anderen Referenzobjekt (also z. B. weitere Einheiten, die denselben Zauber nutzen) stehen in anderen Zeilen.
    Nun müsst ihr kurz überlegen wieviele MUI-Komponenten es gibt. Ich gehe mal davon aus, dass ihr nur einen Realwert und eine Einheit (z. B. einen Dummy) abspeichern wollt. Ihr erzeugt zwei INTEGER-Variablen und speichert da die Spaltennummer für die jeweilige MUI-Komponenten. Wichtig ist, dass jede Komponenten eine andere Spalte bekommt... logisch. Wir möchten in Spalte 0 den Realwert und in Spalte 1 die Dummyeinheit speichern. Also die Integer-Variablen auf 0 und 1 setzen.
    Wenn etwas in einer Hashtabelle zu speichern oder von dort zu laden ist taucht immer "Save/Load ... as value of value in hashtable" auf.
    Ihr möchtet jetzt gerne euren Realwert und die Dummyeinheit abspeichern.
    Als Aktion müsst ihr offensichtlich "Save Real" wählen. "..." ist dann ein Realwert, zum Beispiel 5,00. "value of value" steht für Spalte und Zeile, in der abgespeichert wird. Das erste value ist die SPALTE, nach "of" kommt die ZEILE. Die Spalte ist jetzt eure Integervariable, die den Wert 0 hat, die Zeile ist eure HandleID von der zaubernden Einheit. Die Hashtabelle könnt ihr irgendwo erzeugen und in eine Variable speichern.
    Fertig.
    Genauso verfahrt ihr mit allen anderen MUI-Komponenten, nur müsst ihr eben die Spalte entsprechend ändern. Bringt ja nix wieder in Spalte 0 zu speichern, dann wird das was dort steht überschrieben ^^

    Weil das Laden aus Hashtabellen (genau wie Speichern) wie gesagt langsam ist solltet ihr bemüht sein die MUI-Komponenten erst zu benutzen nachdem ihr sie in globale Variablen (lokale gehen natürlich auch) zwischengespeichert habt.
    Angenommen ihr habt eine Spaltennummer "LIFETIME_REMAINING" genannt. Der Hashtabellen-Eintrag bei Spalte "LIFETIME_REMAINING" und Zeile "HandleIDvonEuremReferenzObjekt" gibt an, wie lange ein Dummy (der in eine anderen Spalte gespeichert ist) noch leben soll. LIFETIME_REMAINING ist ein Integerwert, z. B. 4, das heißt der entsprechende Eintrag steht in Spalte 4. Die verbleibende Lebenszeit werdet ihr normalerweise als Real-Wert speichern.
    Nun geht ihr nur hin und legt eine Real-Variable namens "lifetime_remaining" (man beachte die Kleinschreibung) an. Sobald ihr jetzt die verbleibende Lifetime braucht speichert ihr den Hashtabellen-Eintrag bei "LIFETIME_REMAINING of HandleID in EureHashTabelle" in "lifetime_remaining" ab.
    Warum das Ganze?
    Normalerweise müsstet ihr jedesmal wenn ihr die verbleibende Lebenszeit braucht den Wert erst "langsam" aus der Hashtabelle anfordern. Das ist nicht besonders performant, im Gegenteil: wenn ihr viele Sachen damit anstellt muss der Wert häufig geladen werden! Viel sinnvoller ist es, ihn ganz am Anfang in die globale Real-Variable "lifetime_remaining" zu speichern und DIESE dann zu benutzen.
    Wenn ihr keine weiteren Aktionen mit der Lebenszeit vorhabt speichert ihr lifetime_remaining dann wieder in die Hashtabelle. Warum? Weil Real-Werte (wie ihr euch sicher erinnert) keine Objekte sind. Das heißt wenn zwei Variablen auf 5,00 zeigen und eine davon geändert wird (z. B. auf 6,00) dann zeigt die andere IMMER NOCH auf 5,0.
    Diesen Schritt (am Ende wieder in Hashtabelle speichern) könnt ihr bei Objekten natürlich weglassen, da werden automatisch alle anderen Zeiger aktualisiert.

    Tja, ich hoffe das war verständlich
    Eine Hashtabelle ist nicht nur eine bequemere, sondern auch weniger eingeschränkte Möglichkeit MUI zu erreichen wenn man es mit dem Custom-Value-Ansatz vergleicht. Auf der anderen Seite ist sie langsamer und schwerer zu verstehen.

    to be continued... (vielleicht )

    mfg
    Lanfear
    Geändert von L4nf3ar (14. Juni 2010 um 20:25 Uhr)
    Der Pessimist sieht die Dunkelheit des Tunnels.
    Der Optimist sieht das Licht am Ende des Tunnels.
    Der Realist sieht, dass es der heranrasende Zug ist.


    ... Und der Zugführer sieht drei Idioten auf den Gleisen sitzen.

  2. #2
    Staff Maps
    Projektbetreuung

    Mappinghelfer des Monats
    Benutzerbild von Der sensige Derwisch
    Registriert seit
    Apr 2009
    Ort
    irgendwo im nirgendwo
    BNet Account
    Der_Wisch
    Beiträge
    2.487
    Hört sich ganz nett an

    Aber wenns ein GUI-Trigger-Guide ist warum sprichst du dann Gameplaykonstanten oder das benutzen von Shift im Objekt Editor an? (Was man durch ändern in den Voreinspellungen/Preferenses in 90% der fälle garnicht mehr braucht ^^)

    Und zu guter lezt
    Wär schön gewesen wenn du mehr Funktionasaufrufe wie (triggering unit) usw erwähnt/erklärt hättest ^^
    Außerdem hat du was von entleaken erzähl den customscript aber vergessen ^^

  3. #3
    cool....danke schön, hat mir gut geholfen

  4. #4
    Benutzerbild von L4nf3ar
    Registriert seit
    Nov 2002
    Ort
    Münster, NRW
    BNet Account
    wolf2
    Beiträge
    602
    Zitat Zitat von Der sensige Derwisch Beitrag anzeigen
    Hört sich ganz nett an

    Aber wenns ein GUI-Trigger-Guide ist warum sprichst du dann Gameplaykonstanten oder das benutzen von Shift im Objekt Editor an? (Was man durch ändern in den Voreinspellungen/Preferenses in 90% der fälle garnicht mehr braucht ^^)

    Und zu guter lezt
    Wär schön gewesen wenn du mehr Funktionasaufrufe wie (triggering unit) usw erwähnt/erklärt hättest ^^
    Außerdem hat du was von entleaken erzähl den customscript aber vergessen ^^
    Nunja, wenn man triggert stößt man häufig auf Blockaden aus den Gameplaykonstanten oder dem Objekteditor, deshalb ist es ganz nützlich zu wissen wo man sowas ändern kann (und dass Shift dabei oft hilft).
    Das mit den Triggern und dem Erklären ist insofern fast überflüssig, als man durch Ausprobieren und mit Englischkenntnissen sehr schnell versteht was gemeint ist. Diese Probierphase dauert ja eigentlich für immer an und ist imo das Wichtigste am Kartenbasteln. Wenn man sofort erklärt bekommt was welche Aktion, Bedingung, Ereignis genau macht dann übersieht man viele Dinge, auf die man sonst fast zwangsläufig selber gestoßen wäre.
    Ich hatte an dem Abend einfach Lust mal bisschen zu schreiben, das hier erhebt keineswegs irgendeinen Anspruch. Wenn mir danach ist erweitere ich den Guide noch
    Der Pessimist sieht die Dunkelheit des Tunnels.
    Der Optimist sieht das Licht am Ende des Tunnels.
    Der Realist sieht, dass es der heranrasende Zug ist.


    ... Und der Zugführer sieht drei Idioten auf den Gleisen sitzen.

  5. #5
    Moderator
    Off-Topic Forum

    Staff Maps
    Benutzerbild von Balnazzar
    Registriert seit
    Nov 2007
    Ort
    BW
    Beiträge
    8.008
    Sehr schön, und weil du dir soviel Arbeit gemacht hast, mach ich das hier mal sticky
    You are the church, I am the steeple.
    When we fuck, we are all god's people.
    Listen.

  6. #6
    Benutzerbild von *Ashara*
    Registriert seit
    Jun 2015
    Ort
    Hamburg
    Beiträge
    6
    Sehr gut erklärt

Ähnliche Themen

  1. WARLOCK explained! + Einsteiger guide
    Von PoWerJin im Forum Fungame & Mapping Community Forum
    Antworten: 2
    Letzter Beitrag: 10. Februar 2012, 11:54
  2. GG-Client, der Einsteiger Guide
    Von Revil0 im Forum DotA Forum
    Antworten: 22
    Letzter Beitrag: 09. Januar 2009, 10:47
  3. Fragen zum Trigger-Editor
    Von Tybald im Forum Triggerforum
    Antworten: 2
    Letzter Beitrag: 02. Februar 2006, 20:13
  4. Frage zum Trigger Editor + Tutorial zu TD's
    Von Invis.Immortal im Forum Allgemeine Mappingfragen
    Antworten: 4
    Letzter Beitrag: 04. Februar 2005, 15:57

Forumregeln

  • Es ist dir nicht erlaubt, neue Themen zu verfassen.
  • Es ist dir nicht erlaubt, auf Beiträge zu antworten.
  • Es ist dir nicht erlaubt, Anhänge hochzuladen.
  • Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
  •