Wunderland FAQ

----------

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.

----------

Liste der Fragen

Allgemeines
Wie fange ich an?
Wie benutze ich include/define?
Wie benutze ich FTP?
Wie mache ich zeitverzögerte Ausgaben oder eine Sequenz?
Ich kann mit meinem Xtool ein Property nicht setzen, weil das Xtool dieses Property/das Makro für den Wert nicht kennt.
Wo finde ich weitere Hilfe oder gute Beispiele?
Räume
Wie kann ich testen, wieviele Spieler in einem Raum sind?
Wie kann ich die Anzeige der möglichen Ausgänge unterdrücken/verändern?
Wie kann man Magieanwendung in einem Raum unterbinden?
Wie kann ich Teleportationen in einen oder aus einem Raum verhindern?
Wie kann ich erreichen, dass bestimmte Details bedingungsabhängig sind?
Ich will in meinem Raum die tag-/nachtabhängigen Details testen. Muss ich warten, bis es Tag/Nacht ist?
NPC
Wie kann ich einen NPC programmieren, der Spielern was geben soll, wenn man ihn etwas fragt?
Wie kann ich einen NPC programmieren, der Spielern was geben soll, wenn man ihm was gibt?
Wie kann erreichen, dass mein NPC keine Gegenstände annimmt?
Wie kann ich einen NPC den Ausgang versperren lassen?
Wie erreiche ich es, dass mein NPC stärker wird?
Wie kann mein NPC eine Frage stellen und die Antwort des Spielers auswerten?
Gegenstände
Gibt es etwas, das ich beim Programmieren von Waffen berücksichtigen muß?
Wie erreiche ich, dass meine Waffe/Rüstung nur unter bestimmten Voraussetzungen gezückt/angezogen werden kann?
Warum können Magiekundige meine Rüstungen nicht tragen oder meine Waffen nicht zücken?
Ich möchte eine andere als die normale Anzieh-/Ausziehmeldung bei meiner Rüstung haben.
Wie kann ich testen, ob der Spieler einen Gegenstand selbst erworben hat?
Wie kann ich die möglichen Clones eines Objektes begrenzen? (Uniques)
Wie erreiche ich es, dass eine Rüstung/Waffe den Extralook des Spielers beeinflusst?

----------

Antworten

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. nach oben
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). nach oben
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. nach oben
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. nach oben
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. nach oben
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. nach oben
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. nach oben
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";
}
nach oben
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. nach oben

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. nach oben

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.";
}
nach oben
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.
Um Nacht in dem Raum zu schaffen, in dem Du gerade stehst, lautet das Xtool-Kommando:
xcall $h->SetProp(P_TIMEZONE, TZ_NIGHT);
Um Tag in dem Raum zu schaffen, in dem Du gerade stehst, lautet das Xtool-Kommando:
xcall $h->SetProp(P_TIMEZONE, TZ_DAY);

Aller Wahrscheinlichkeit geht das so ohne Weiteres beim ersten Mal nicht. Du wirst eine Fehlermeldung bekommen, etwa in dieser Art:
players/sunrise/.tool.lpc.c line 7 before ';}': Variable TZ_DAY not declared ! Error: Error in loading object: 'players/sunrise/.tool.lpc'.

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. nach oben

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. nach oben
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. nach oben
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. nach oben
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. nach oben
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

  • P_LEVEL wirkt sich direkt auf die Attribute des NPCs aus. Dabei wirkt sich die Stärke auf die Stärke der Normalangriffe und die Geschicklichkeit eher auf die Verteidigung.
  • P_HANDS legt die Schadensart und die Schadenstärke der Normalangriffe des NPCs.
  • Mittels AddSpell können dem NPCs Spezialangriffe gegeben werden. Je nachdem, ob diese den NPC Magiepunkte kosten oder nicht, sind auch die P_SP und P_MAX_SP für den Kampf von Bedeutung.

Verteidigung

  • Die Geschicklichkeit des NPCs wirkt sich auf das Ausweichen des NPCs im Kampf aus. Er steckt somit weniger oder weniger harte Treffer ein. P_LEVEL wirkt sich direkt auf die Attribute des NPCs aus.
  • P_BODY bildet den natürlichen Rüstungsschutz des NPCs und wirkt sich ebenfalls auf die Verteidigung aus.
  • Über das Property P_RESISTANCE können Resistenzen und Schwächen gegenüber bestimmten Schadenstypen festgelegt werden.
  • P_HP und P_MAX_HP beeinflussen direkt die Lebensdauer des NPCs.
  • Und schließlich kann im Defend des NPCs noch auf spezielle Sachen reagiert werden. Z.B. dass ein Vampir weniger Schaden erleidet, wenn der Feind Knoblauch bei sich traegt.
nach oben
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. nach oben
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. nach oben
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:
für Rüstungen: /doc/beispiele/ruestung2.c
für Waffen und Schilde: /doc/beispiele/events/schild.c nach oben

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. nach oben

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. nach oben
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. nach oben
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. nach oben
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";
}
nach oben