Hier findest Du eine Sammlung immer wieder auftretender Fragen. Die Fragen werden mit kurzen Hinweisen, gegebenenfalls mit Beispielen und so weit wie möglich mit Verweisen auf Stellen innerhalb der vorliegenden Dokumentation beantwortet. Grundsätzlich sollen die hier gegebenen Antworten das persönliche Gespräch mit Deinem Sponsor oder Deiner Sponsorin nicht ersetzen sondern ergänzend wirken. |
Wie fange ich an? | |
Lass es langsam angehen. Lass Dich in den ersten Tagen von Deinem Sponsor und den Hilfeseiten
mit den grundlegenden Magierbefehlen
und Magiertools bekannt machen. Schau Dir die
Beispiele an und versuche erst einmal,
Deinen Workroom nach Deinem Geschmack zu gestalten.
Auch Dein eigener Charakter kann nun von Dir verändert werden: Deine Rasse, Dein Charakter,
Meldungen für das Clonen und Zerstören von Objekten. Wenn Du schon eine Idee davon hast, wie Du das Wunderland um neue Räumlichkeiten etc. bereichern kannst, dann halte Deine Gedanken und Vorstellungen dazu schriftlich fest, erstelle ein Konzept und überlege Dir, ob das ins Wunderland paßt und in welche Region. Zeige dem zuständigen Regionsmagier Dein Konzept. Achte darauf, dass Dein erstes Projekt nicht mehr als maximal 20 Räme umfaßt. Das ist sicherlich auf den ersten Blick nicht viel, aber mehr als genug Arbeit für den Anfang. Und Dein erstes Erfolgserlebnis ist umso näher. Frage am Anfang besser öfter als zu wenig und zeige Deine ersten Räume und Objekte Deinem Sponsor. Dieser kann Dir sicherlich oft Tipps und Hinweise geben, wie Du etwas schneller, einfacher oder sicherer lösen kannst. Und: Mach Dir nichts draus, wenn du "rumbugst". Denn: Wer nichts macht, kann auch nicht buggen. Jeder hat mal angefangen und Du wirst immer Hilfe bekommen, wenn Du brauchst. | |
Wie benutze ich include/define? | |
Include-Dateien oder besser Headerdateien dienen grundsätzlich dazu,
andere Dateien in ein File einzufügen. Sie sollten aber nicht dazu
benutzt werden, vollständigen Code, sondern vor allem
gemeinsame Definitionen und Prototypen - im Idealfall nur
Defines/Makros und Prototypen einzufügen. Defines sollten überall da verwendet werden, wo man nachträglich bestimmte Dinge, die an mehreren Stellen verwendet werden, noch ändern können soll. Oder für Abkürzungen und Vereinfachungen, wie PL für this_player(). Defines sollten vor allem dann in Headerfiles ausgelagert werden, wenn die gleichen Makros auch an anderer Stelle nochmal verwendet werden sollen. Defines werden vor dem eigentlichen 'Compilieren' durch den definierten Wert ersetzt. Include-Dateien werden analog vor dem 'Compilieren' eingefügt. D.h. bevor der Driver ein File compiliert, fügt er tatsächlich alle Includes ein und ersetzt alle Defines. Deshalb kann die exzessive Verwendung von Defines und Includes auch dazu führen, dass das Laden/Updaten eines Files sehr lange dauert. Es sollten immer nur die Includes benutzt werden, die unbedingt notwendig sind. Ausserdem kann man sich böse Fallen mit Defines bauen. Wenn man zum Beispiel Berechnungen als Makro definiert und dann überall einfügt. Ein Beispiel hierfür ist: # define square(x) x * x square(3+2) würde dann 3+2*3+2 werden und das wird als 3+(2*3)+2 berechnet und nicht als (3+2)*(3+2). |
|
Wie benutze ich FTP? | |
Die am häfigsten genutzte Art, Files zu bearbeiten, besteht darin, sich die jeweiligen
Dateien per FTP auf den heimischen Rechner zu ziehen, sie lokal zu editieren und dann per FTP
wieder einzuspielen. Die allgemeinen Zugangsdaten sind: Host: wl.mud.de Port: 4713 Benutzerkonto: <Dein Magiername> Passwort: <Dein Passwort> Eventuell musst Du noch 'passive transfer' aktivieren. Unter Windows benutzen die meisten WS_FTP oder gleich einen Editor mit FTP-Unterstüzung (z.B. UltraEdit). Für Linux-Nutzer bietet sich Xftp an. Eine umfangreichere Schritt-für-Schritt-Erklärung findest Du hier. |
|
Wie mache ich zeitverzögerte Ausgaben oder eine Sequenz? | |
Zeitverzögerte Ausgaben/Reaktionen schafft man mit call_out. Eine Sequenz ist nichts anderes eine Aufeinanderfolge mehrerer zeitverzögerter Ausgaben und ebenfalls über call_outs zu lösen. Ein Beispiel für eine kleine Sequenz findest Du hier. | |
Ich kann mit meinem Xtool ein Property/das Makro für den Wert nicht kennt. | |
Nehmen wir an, Du willst in dem Raum, in dem Du gerade stehst, die Zeitzone zum Testen auf TZ_NIGHT setzen. Das Xtool reagiert aber auf Deinen Befehl xcall $h->SetProp(P_TIMEZONE, TZ_NIGHT) mit einer schnöden Fehlermeldung, dass ihm das Makro TZ_NIGHT nicht bekannt ist. Sowas kann Dir öfter passieren. Abhilfe dagegen schafft eine kleine versteckte Datei in Deinem Home. Ihr Name ist .xtool.h und sehen kannst Du sie mit ls -a. Gibt es eine solche Datei in Deinem Home noch nicht, dann kannst Du sie einfach anlegen. In diese Datei schreibst Du nun einfach die Headerdatei, in der Dein gesuchtes Makro definiert wird. In diesem Falle ist das /sys/uhr.h. Die Datei .xtool.h sieht dann also so aus: #include <uhr.h>Nun sollte das Xtool den obigen Befehl verstehen. |
|
Wo finde ich weitere Hilfen oder gute Beispiele? | |
Weitere Beispiele findest Du in der Beispielsammlung. Eine sehr gute Hilfe sind auch die Manpages zu den einzelnen Befehlen und Funktionen. In den meisten Fällen enthalten sie auch ein bis zwei gute Beispiele. Besonders hilfreich in der WWW-Dokumentation ist die integrierte Volltextsuche über die Hilfeseiten. Mit ihrer Hilfe solltest Du fast alles finden. Des weiteren brauchst Du natürlich nicht zu zögern, Deinen Sponsor oder andere Mitmagier nach Beispielen und Hilfen zu fragen. | |
Wie kann ich testen, wieviele Spieler in einem Raum sind? | |
Man kann das Inventar des Raumes danach filtern. Wenn raum der
aktuelle Raum sei, dann ist
object *ob = filter(all_inventory(raum), #'query_once_interactive); ein Array mit allen Spielern im Raum. Im Gegensatz zu interactive() schliesst query_once_interactive() auch netztote Spieler mit ein. sizeof(ob) gibt dann die Anzahl der im Raum befindlichen Spieler wieder. |
|
Wie kann ich die Anzeige der möglichen Ausgänge unterdrücken/verändern? | |
Die Funktion GetExits() liefert die möglichen Ausgänge.
Deren Ausgabe wird an die Raumbeschreibung angehängt. Will man
nun z.B. statt dem Text "Es gibt einen sichtbaren Ausgang:
oben." lieber "Du kannst der Wendeltreppe
nach oben folgen." ausgegeben bekommen, so fügt man einfach
die folgende Funktion ein. Zu beachten ist dabei, dass man die
Zeilenumbrüche selbst setzen muss.
varargs string GetExits(object viewer, int short) { return "Du kannst der Wendeltreppe nach oben folgen.\n"; } |
|
Wie kann man Magieanwendung in einem Raum unterbinden? | |
Dazu gibt es das Property P_NOMAGIC. Damit kann man für jedes Spelllevel bestimmen, mit welcher Wahrscheinlichkeit Zaubern unmöglich sein soll. |
|
Wie kann ich Teleportationen in einen oder aus einem Raum verhindern? | |
Es gibt mehrer Möglichkeiten dazu, je nachdem welche Art von Teleportation man unterbinden will. Gegen die Sprüche und Steinringe der Magiekundigengilde wirkt das Property P_TELEPORT_FORBIDDEN Für sämtliche anderen Teleportationen gibt es das Property P_NO_TPORT, mit dem man auch einzeln regeln kann, ob der Teleport nur in den Raum oder nur aus dem Raum oder in beide Richtungen unterbunden werden soll. Natürlich gibt es ausserdem noch die Möglichkeit, Bewegungen mittels M_TPORT (also Teleportationen) über Events abzufangen. |
|
Wie kann ich erreichen, dass bestimmte Details bedingungsabhängig sind? | |
Angenommen man will, dass es für das Detail
"grasbueschel" verschiedene Texte gibt, je nachdem ob es
schon herausgerissen wurde oder nicht. Die integer-Variable raus
soll angeben, ob schon gerupft wurde oder nicht. Ist sie 1, dann
ja. Ist sie 0, dann nein.
// Vorm create() muss die Funktion deklariert werden string grasbueschel_detail(); int raus = 0; void create() { ::create() // dann der Quellcode des Raumes AddDetail(({"grasbueschel genauer", "bueschel genauer"}), #'grasbueschel_detail); } // Die Funktion soll einen Wert für AddDetail zurückgeben, // also muss sie string sein string grasbueschel_detail() { if (!raus) // wenn nicht gerupft wurde return "Es sieht so aus, als wenn das Bueschel nicht " "ganz festsaesse."; else // ansonsten return "Das Grasbueschel wurde lieblos aus der " "Erde gerissen."; } |
|
Ich will in meinem Raum die tag-/nachtabhängigen Details testen. Muss ich warten, bis es Tag/Nacht ist? | |
Nein. Es gibt verschiedene Zeitzonen
im Wunderland. Und auch welche, bei denen
es immer Tag oder immer Nacht ist. Mit dem Xtool kannst Du diese Zeitzone ganz
schnell (und temporär) für Deinen Raum setzen und so alle Details
testen. Aller Wahrscheinlichkeit geht das so ohne Weiteres beim ersten Mal nicht. Du wirst eine
Fehlermeldung bekommen, etwa in dieser Art: Diese Fehlermeldung besagt, dass dem Xtool das Makro TZ_DAY nicht bekannt ist. Entweder Du suchst nun die Headerfiles der Lib nach dem Wert des Makros im Klartext durch und gibst dann dieses an (in der Manpage zu dem jeweiligen Property steht auch, wo die Makros dazu definiert sind), oder Du zeigst dem Xtool, wo es das entsprechende Makro findet. Siehe dazu hier. |
|
Wie kann ich einen NPC programmieren, der Spielern was geben soll, wenn man ihn etwas fragt? | |
Angenommen man will, daß der NPC dem Spieler für die Frage nach Geld einen Smaragd gibt. Dazu verweist man im AddInfo auf eine Funktion, in der dies geschehen soll. In der Beispiel-Sammlung gibt es einen NPC, der genau dies tut. | |
Wie kann ich einen NPC programmieren, der Spielern was geben soll, wenn man ihm etwas gibt? | |
Über die Funktion give_notify(object ob) erfährt man, wenn dem NPC etwas gegeben wird. Man kann aber auch die Events dazu benutzen und auf ET_GIVE lauschen, wie das das Pferd aus der Beispiel-Sammlung tut. Ein Beispiel für die Benutzung des give_notify findet sich hier. | |
Wie kann ich erreichen, daß mein NPC keine Gegenstände annimmt? | |
Dazu gibt es das Property P_REJECT. Alternativ kann man natürlich auch auf den Event ET_GIVE lauschen und das jeweilige Ereignis abbrechen. In der Manpage zu P_REJECT sind zwei Beispiele zur Verwendung des Properties enthalten. | |
Wie kann ich einen NPC den Ausgang versperren lassen? | |
Es gibt dazu die Funktion GuardExit, die im NPC benutzt werden kann. In der Manpage zu GuardExit ist ein gutes Beispiel dazu. Ausserdem auch möglich, auf den Event ET_GO zu lauschen. | |
Wie erreiche ich es, dass mein NPC staerker wird? | |
Es gibt mehrere Möglichkeiten, das Kampfverhalten von NPCs zu beeinflussen. Geordnet nach Wirkung auf Angriff oder Verteidigung sind dies: Angriff
Verteidigung
|
|
Wie kann mein NPC eine Frage stellen und die Antwort des Spielers auswerten? | |
Am besten geht das über den Kommunikations-Event. Damit kann man die Antworten des Spielers auswerten, egal ob sie über das Kommando "sage", "'" oder "antworte" oder gar "frage" gegeben werden. Ein Beispiel findet sich hier. | |
Gibt es etwas, das ich beim Programmieren von Waffen berücksichtigen muß? | |
Für die Programmierung von Waffen und Rüstungen gibt es eine Richtlinie, die dabei zu beachten ist. In ihr werden die maximalen Schadens- und Rüstungswerte festgelegt, sowie Hinweise zur Bestimmung des Gewichtes. Desweiteren ist bei Waffen mit besonderen Features auch immer die Verhältnismäßigkeit zu beachten, d.h. supergute Waffen/Rüstungen sollten zumindest schwer zu bekommen sein und wenn möglich auch irgendwelche Nachteile haben. | |
Wie erreiche ich, dass meine Waffe/Rüstung nur unter bestimmten Vorraussetzungen gezückt/angezogen werden kann? | |
Für Waffen und Schilde gibt es den Event ET_WIELD, für Rüstungen den Event ET_WEAR. Diesen kann man lauschen und sie gegebenenfalls abbrechen, wenn die gewünschten Bedingungen nicht erfüllt sind.
Zwei Beispiele: |
|
Warum können Magiekundige meine Rüstungen nicht tragen oder meine Waffen nicht zücken? | |
Die Mitglieder der Gilde der Magiekundigen (und auch der -inaktiven- Gilde der Schwarzmagier) können normale Kleidung nicht tragen. Für sie gibt es spezielle Kleidungsstücke in deren Gildenladen. Wenn man eigene Kleidungsstücke auch für diese Spieler ermöglichen will, muss man ihnen eine spezielle Id geben. Für Rüstungen und Schilde ist das "\nmagiekundigen_kleidung", für Waffen ist das "\nmagiekundigen_waffe". Dabei ist jedoch darauf zu achten, dass diese Items möglichst keinen oder nur einen geringen Rüstungsschutz bzw. eine geringe Waffenklasse besitzen sollen. |
|
Ich möchte eine andere als die normale Anzieh-/Ausziehmeldung bei meiner Rüstung haben. | |
Dafür gibt es die Properties P_WEAR_MSG und P_UNWEAR_MSG. Der graue Umhang aus der Beispiel-Sammlung nutzt diese, um eine spezielle Meldung zu erzeugen. | |
Wie kann ich testen, ob der Spieler einen Gegenstand selbst erworben hat? | |
Dieses Problem stellt sich zumeist bei Quests, wo dann sichergestellt
werden soll, dass der Spieler wichtige Aktionen selbst durchgeführt
hat. Beim Clonen/Laden eines Objektes wird das Property
P_CLONER
automagisch gesetzt. Dieses kann man auswerten. In manchen Fällen ist
das jedoch nicht aussagekräftig, z.B. wenn der Cloner ein NPC ist, der
den Gegenstand stets bei sich trägt. Dann empfiehlt es sich, ein eigenes
Property anzulegen, das sich den Spieler merkt, z.B. obj->SetProp("eigentuemer", this_player()); Bei der späteren Benutzung des Objektes kann dann dieses Property abgefragt und mit dem Akteur verglichen werden. |
|
Wie kann ich die möglichen Clones eines Objektes begrenzen? (Uniques) | |
Dazu muß man das Object am Unique-Daemon anmelden. In der Manpage dazu findet sich eine genaue Beschreibung dazu und ein Beispiel. | |
Wie erreiche ich es, dass eine Rüstung/Waffe den Extralook des Spielers beeinflusst? | |
Dazu gibt es die Funktion extra_look(). Darin kann man
einen Text angeben, der beim Untersuchen des Spielers mit
ausgegeben wird. Diese Funktion wird bei NPCs nicht ausgewertet.
Beispiel:
string extra_look() { // Wenn es eine "Umgebung" gibt und das Objekt von // dieser getragen wird: if (environment() && (QueryProp(P_WORN) == environment())) return capitalize(environment()->QueryPronoun(WER))+ " traegt eine leuchtende Kaktusbluete im Haar.\n"; } |
Start » Magierhandbuch » Dokumentation » FAQ | |