Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/doc/beispiele/AddCmd/Einfuehrung.AddCmd.txt b/doc/beispiele/AddCmd/Einfuehrung.AddCmd.txt
new file mode 100644
index 0000000..eadf6f9
--- /dev/null
+++ b/doc/beispiele/AddCmd/Einfuehrung.AddCmd.txt
@@ -0,0 +1,174 @@
+Hallo MitmagierInnen *g*,
+
+Ok, dann gehts mal ein bischen zur Sache:
+
+/std/thing/commands.c wurde so erweitert, dass man auch komplexe Syntax
+direkt im AddCmd vorparsen kann.
+
+Dazu ein kurzes Beispiel:
+-------------------------
+
+In einem Objekt (ein Busch) findet sich folgende Syntaxdefinition.
+
+ AddCmd("pfluecke|ernte&fruechte|beeren&@ID","cmd_pfluecken",
+        "Was willst Du denn @verben?|Wo willst Du denn die Beeren @verben?");
+
+Der erste Parameter definiert die Syntax. Das Zeichen & trennt verschiedene
+zu parsende Items:
+
+1. pfluecke|ernte
+2. fruechte|beeren
+3. @ID
+
+Unter 1. finden sich die Verben - das sind die gleichen, die man in der
+alten Version auch belegen konnte. Die Regel reagiert also auf "pfluecke"
+oder auf "ernte".
+
+Alle weiteren Regeln muessen erfuellt werden, damit der zweite Parameter
+(die Funktion) aufgerufen wird. @ID steht dabei fuer die ID des Objektes,
+in dem das AddCmd steht. Hier also der Busch.
+
+Dazu einige Beispiele:
+
+a) > pfluecke beeren
+ -> erfuellt 1 und 2. Aber nicht 3. => Fehlermeldung.
+
+b) > ernte von busch
+ -> erfuellt 1 und 3, jedoch 2 nicht. => Fehlermeldung.
+
+c) > pfluecke fruechte von busch
+ -> erfuellt 1, 2 und 3 -> busch->cmd_pfluecken() wird aufgerufen. Das "von"
+    ist Fuellwerk. Davon kann beliebig viel im String sein. Sie werden 
+    ignoriert.
+    Es sind also auch unsinnige Syntaxe richtig, solange der String die 
+    Items erufellt.
+
+Im Fall c) wird das Verhalten des Busches durch die Funktion "cmd_pfluecken"
+definiert, wie auch in der alten Version von AddCmd.
+
+Was passiert aber in den Faellen a) und b)? Dafuer ist der dritte
+Parameter da:
+  "Was willst Du denn @VERBen?|Wo willst Du denn die Beeren @VERBen?");
+
+Hier sind zwei Fehlermeldungen, durch | getrennt, definiert:
+
+x) Was willst Du denn @VERBen?
+y) Wo willst Du denn die Beeren @VERBen?
+
+Erst wird geprueft, ob 2. erfuellt ist. Falls nicht, gibt es Fehlermeldung x)
+Dann wird auf 3. geprueft. Ist das nicht erfuellt (aber 2. schon) gibt es
+Fehlermeldung y).
+
+Im Fall a sind 1 und 2 erfuellt. Demnach wird y) ausgegeben. @VERB wird
+dabei durch das benutzte Verb ersetzt (das abschliessende en, bzw e wird
+abgeschnitten):
+ Wo willst Du denn die Beeren pfluecken?
+
+Im Fall b ist 1 erufellt, 2 aber schon nicht. Daher gibt es Fehlermeldung
+x). Auf 3. wird nicht mehr geprueft.
+ Was willst Du denn ernten?
+
+Wie schon erwaehnt erfuellt c) alle Bedingungen und es gibt keine Ausgabe -
+Statt dessen kann man das Pfluecken in der Funktion abhandeln.
+
+In den Faellen 1 und 2 wird die Fehlermeldung ueber notify_fail()
+abgehandelt. Ergo wird hier anderen Befehlen von anderen Objekten noch
+eine Chance gegeben. Gleiches gilt fuer die Funktion cmd_pfluecken(), wenn
+deren Rueckgabewert 0 ist. Auch hier gibt es die Analogie zum alten AddCmd.
+
+Gibt cmd_pfluecken() einen Wert ungleich 0 zurueck, wird die Suche nach
+der richtigen Syntax danach abgebrochen, so dass auch kein anderes Objekt
+mehr gefragt wird (wie gehabt).
+
+Das ist auch fuer Forscherpunkte wichtig. FP werden generell nur bei einem
+Rueckgabewert ungleich 0 vergeben.
+
+Eine kleine Erweiterung der Beispielsyntax:
+-------------------------------------------
+
+ AddCmd("pfluecke|ernte&fruechte|beeren&@ID@\impossible",0,
+  "Was willst Du denn @VERBen?|Wo willst Du denn die Beeren @VERBen?|"
+  "Du pflueckst ein paar Beeren und isst sie auf.^@WER isst ein paar
+  Beeren.");
+
+Eine neue Regel:
+
+4. \impossible
+
+Und eine neue Fehlermeldung:
+z) Du pflueckst ein paar Beeren und isst sie auf.^@WER isst ein paar Beeren.
+
+Zur Regel:
+
+Die Regel ist nicht erfuellbar, da Spieler das \i nicht erzeugen
+koennen. Zwangslaeufig gibt es auch keine Funktion, die aufgerufen werden
+koennte.
+
+Dafuer gibt es eine Fehlermeldung, die ein neues Element enthaelt. Das
+^. Wird diese Meldung ausgegeben ist das genau wie ein return 1 in der
+Funktion. Die Syntax wird als richtig anerkannt. (Es kann hierfuer also
+auch FP geben).
+
+Der Text vor dem ^ geht an den Spieler, alles dahinter geht an die Spieler
+im Raum. Steht hinter dem ^ nichts, gibt es keine Raummeldung.
+
+Auf diese Weise kann man leicht ein Raumkommando erstellen, dass nur
+Textausgaben macht, aber keine Funktionalitaet enthaelt. Es ist keine
+eigenstaendige Funktion mit irgendwelchem eigenen Parsing mehr noetig.
+
+Das @WER wird durch this_player()->Name() ersetzt, so dass man auch einen
+Persoenlichen bezug in den Meldungen herstellen kann.
+
+Abwaertskompatibel
+------------------
+
+Die Erweiterungen von AddCmd erlauben ein einfacheres Erstellen von
+Standard-Kommandos, ohne dass man sich mit dem Parsen in Funktionen
+beschaeftigen muss.
+
+Die Aenderung ist vollstaendig abwaertskompatibel. Wer sich also sagt,
+das das alles viel zu kompliziert sei, kann weiterhin:
+
+ AddCmd(({"pfluecke","ernte"}),"cmd_pfluecken");
+
+benutzen. Das Verhalten ist haargenau das selbe wie bisher. Dementsprechend
+ist auch kaum Aufwand beim Einpflegen dieser Aenderung notwendig.
+
+Zur Beachtung
+-------------
+
+Ueberall, wo direkt auf P_COMMANDS zugegriffen wird, kann es prinzipiell
+zu Problemen kommen, da sich die Struktur des Mappings und der Zugriff
+darauf geaendert hat.
+
+Im Folgeartikel findet sich eine Liste mit allen Objekten, die das machen. In
+den oeffentlichen Verzeichnissen werde ich mich mit den Magiern in Verbindung
+setzen oder selbst kontrollieren, ob Aenderungen notwendig sind.
+
+Objekte in den Players-Verzeichnissen werde ich nur in Ausnahmefaellen
+anpassen. Zur Erinnerung: Angeschlossenes gehoert nicht nach /players/.
+
+Der Code ist auf Kompatibilitaet mit dem alten System ausgelegt, dennoch
+gibt es ein paar Aenderungen. Zum Beispiel ist P_COMMANDS keine echte
+Property mehr sondern eine lokale Variable. Demzufolge wird P_COMMANDS
+bei "xprop" nicht mehr angezeigt. Die Schnittstelle wird durch _set_
+und _query_funktionen realisiert. Die Mappings werden _immer_ als Kopien
+rausgegeben, so dass man damit nicht versehentlich Unsinn machen kann.
+
+Schlusswort
+-----------
+
+Dieser Artikel stellt nur eine Einleitung in die Aenderung und deren
+Moeglichkeiten dar und ist keinesfalls vollstaendig. Wer mehr darueber wissen
+will, ist eingeladen, sich die Manpage zu "AddCmd" und zu den Beispielen
+"AddCmd_bsp" anzuschauen.
+
+Die Seiten sind aus dem Regenbogen "geliehen" und werden in den kommenden
+Tagen noch auf die Beduerfnisse des Morgengrauen angepasst.
+
+Mein Dank geht an Gloinson, der die Idee hatte, die Anpassungen vorzunehmen
+und Migration des Codes ins MorgenGrauen uebernommen hat.
+
+Falls nun noch Fragen sind, nur zu! :)
+
+V*,
diff --git a/doc/beispiele/AddCmd/busch.c b/doc/beispiele/AddCmd/busch.c
new file mode 100644
index 0000000..da3c5b3
--- /dev/null
+++ b/doc/beispiele/AddCmd/busch.c
@@ -0,0 +1,58 @@
+inherit "/std/thing";
+#include <properties.h>
+#include <moving.h>
+#include <language.h>
+
+#pragma strict_types,save_types,rtt_checks
+
+protected void create()
+{
+   ::create();
+
+   SetProp(P_GENDER, NEUTER);
+   SetProp(P_NAME, "Gebuesch");
+   SetProp(P_SHORT,"Ein Gebuesch");
+   SetProp(P_LONG,"Du stehst vor einem gaanz normalen Gebuesch. Es traegt "
+                  "Fruechte. Und eventuell\nkann man darin etwas finden.\n");
+   SetProp(P_NOGET,"Es ist festgewachsen, eventuell kann man es ausgraben?\n");
+
+   SetProp(P_WEIGHT,5000);
+   SetProp(P_SIZE,100);
+
+   AddId(({"busch","gebuesch"}));
+
+   AddDetail(({"fruechte","frucht"}),
+     "Es scheinen Beeren zu sein. Vielleicht kannst Du sie pfluecken?\n");
+   AddDetail("beeren",
+     "Pflueck sie doch, vielleicht bringt das ja was.\n");
+
+   // Nur wenn die Syntax erfuellt ist, wird cmd_pfluecken() aufgerufen.
+   // "pfluecke beeren von busch" etc.
+   AddCmd("pfluecke|ernte&fruechte|beeren&@ID","cmd_pfluecken",
+          "Was willst Du denn @verben?|Wo willst Du denn die Beeren @verben?");
+
+   // suchen gibt nur eine Meldung aus. Dafuer braucht man kuenftig keine
+   // Funktionen mehr.
+   AddCmd("such|suche|durchsuch|durchsuche&@ID&\nimpossible",0, 
+          "Wo willst Du @VERBen?|Du durchsuchst das Gebuesch, findest aber nichts.^"
+          "@WER1 durchsucht ein Gebuesch, findet aber nichts.");
+
+   // Graben geht eh nicht. Daher nur Fehlermeldungen.
+   // Das ^ sagt, dass hier ein return1 zurueckgegeben wird. Es gibt aber keine 
+   // Raummeldung.
+   AddCmd("grab|grabe&@ID&aus@\nimpossible",0,
+          "Was willst Du graben?|Du willst das Gebuesch ausgraben?|"
+          "Die Wurzeln scheinen tief zu rechen. Das wird nichts.^");
+}
+
+int cmd_pfluecken(string arg, mixed *param)
+{
+    object obj;
+    obj=clone_object(__DIR__"obst");
+    write("Verwundert pflueckst Du "+(obj->name())+" vom Busch. Komisch.\n");
+
+    // Das hier ist ein Beispiel fuer AddCmd, daher mach ich mir nich 
+    // die Muehe das richtig zu machen. Is eh nur fuer Magier!
+    obj->move(this_player(),M_GET|M_NOCHECK);
+    return 1;
+}
diff --git a/doc/beispiele/AddCmd/obst.c b/doc/beispiele/AddCmd/obst.c
new file mode 100644
index 0000000..8efb471
--- /dev/null
+++ b/doc/beispiele/AddCmd/obst.c
@@ -0,0 +1,232 @@
+/* Hinweis zu diesem Beispielobjekt: Lebensmittel lassen sich besser von
+ * /std/food ableiten, das bringt viele Funktionalitaeten mit, die man sonst
+ * muehsam selber basteln muss.
+ */
+
+inherit "/std/thing";
+
+#include <moving.h>
+#include <properties.h>
+#include <wizlevels.h>
+
+#define SAETTIGUNG 2
+#define HEILUNG 20
+#define EAT_DELAY 1200 // 20 Minuten
+
+#define BS78(x) break_string(x,78)
+
+protected void create()
+{
+  ::create();
+
+  // Gemeinsamer Teil des create
+  AddId("obst");
+  SetProp( P_VALUE, 60+random(10) );
+
+  // AddCmd( ({"iss","esse"}), "act_essen");  
+  // new style AddCmd
+  AddCmd( "iss|esse&@ID","act_essen","Was willst Du denn essen?");
+
+  // Nach ca. 10 Minuten resetet das Obst, im Reset wird es destructet, 
+  // so spare ich call_outs
+  set_next_reset(600);
+
+  // Name, ID, Gender, Desc und Gewicht sind Abhaengig von der Obstart
+  switch (random(11)){
+  default:
+    SetProp( P_GENDER, MALE );
+    SetProp( P_NAME, "Apfel" );
+    AddId( "apfel" );
+    SetProp( P_SHORT, "Ein Apfel" );
+    SetProp( P_LONG, BS78(
+      "Ein saftiger Apfel. Dir laeuft das Wasser im Munde zusammen."
+    ));
+    SetProp( P_WEIGHT, 80 );
+    break;
+  case 1:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Birne" );
+    AddId( "birne" );
+    SetProp( P_SHORT, "Eine Birne" );
+    SetProp( P_LONG, BS78(
+      "Eine koestliche, reife Birne. Die ist sicher lecker."
+    ));
+    SetProp( P_WEIGHT, 90 );
+    break;
+  case 2:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Banane" );
+    AddId( "banane" );
+    SetProp( P_SHORT, "Eine Banane" );
+    SetProp( P_LONG, BS78(
+      "Die Banane sieht wirklich lecker aus, am besten gleich essen."
+    ));
+    SetProp( P_WEIGHT, 110 );
+    break;  
+  case 3:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Kiwi" );
+    AddId( "kiwi" );
+    SetProp( P_SHORT, "Eine Kiwi" );
+    SetProp( P_LONG, BS78(
+      "Klein und gruen, aber mit leckeren Innenleben. Yam yam."
+    ));
+    SetProp( P_WEIGHT, 50 );
+    break;  
+  case 4:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Erdbeere" );
+    AddId( "erdbeere" );
+    SetProp( P_SHORT, "Eine Erdbeere" );
+    SetProp( P_LONG, BS78(
+      "Eine ueberdurchschnittlich grosse Erdbeere. Sie "
+      "ist sicher suess und saftig."
+    ));
+    SetProp( P_WEIGHT, 20 );
+    break;  
+  case 5:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Kirsche" );
+    AddId( "kirsche" );
+    SetProp( P_SHORT, "Eine Kirsche" );
+    SetProp( P_LONG, BS78(
+      "Zwar nur klein ist diese Kirsche, aber so dunkel wie sie "
+      "aussieht, ist sie sicher total suess und lecker."
+    ));
+    SetProp( P_WEIGHT, 15 );
+    break;  
+  case 6:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Orange" );
+    AddId( "orange" );
+    SetProp( P_SHORT, "Eine Orange" );
+    SetProp( P_LONG, BS78(
+      "Eine grosse, gelbe Orange. Eine von diesen suessen, die sich so "
+      "leicht schaelen lassen und keine Zicken machen, so wie Saftorangen."
+    ));
+    SetProp( P_WEIGHT, 90 );
+    break;  
+  case 7:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Mandarine" );
+    AddId( "mandarine" );
+    SetProp( P_SHORT, "Eine Mandarine" );
+    SetProp( P_LONG, BS78(
+      "Suess und saftig und gesund. So muss das Essen im Paradies "
+      "gewesen sein."
+    ));
+    SetProp( P_WEIGHT, 60 );
+    break;  
+  case 8:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Zitrone" );
+    AddId( "zitrone" );
+    SetProp( P_SHORT, "Eine Zitrone" );
+    SetProp( P_LONG, BS78(
+      "Sauer, sauer und nochmals sauer. Aber ultralecker. Na, sabberst Du "
+      "schon auf die Tastatur?"
+    ));
+    SetProp( P_WEIGHT, 60 );
+    break;  
+  case 9:
+    SetProp( P_GENDER, MALE );
+    SetProp( P_NAME, "Granatapfel" );
+    AddId( "granatapfel" );
+    SetProp( P_SHORT, "Ein Granatapfel" );
+    SetProp( P_LONG, BS78(
+      "Er ist zwar etwas schwieriger, den zu essen, aber der Aufwand "
+      "lohnt sich."
+    ));
+    SetProp( P_WEIGHT, 90 );
+    break;  
+  case 10:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Pflaume" );
+    AddId( "pflaume" );
+    SetProp( P_SHORT, "Eine Pflaume" );
+    SetProp( P_LONG, BS78(
+      "Eine grosse, blaue Pflaume. Lass sie Dir doch schmecken."
+    ));
+    SetProp( P_WEIGHT, 20 );
+    break;
+  }
+}
+
+void reset()
+{
+  object env = environment(this_object());
+
+  if (env) {
+    if (query_once_interactive(env)){
+      // Mein Env is ein User
+      tell_object(env, BS78(
+        capitalize(this_object()->name(WER))+" verschwindet mit einem "+
+        "\"PLOPP\" aus deinem Inventar. Da scheint Magie im Spiel zu sein."
+      ));
+    } else if (sizeof(all_inventory(env)&users())){
+      // In meinem Environment sind User (Es ist ein Raum)
+      tell_room(env, BS78(
+        capitalize(this_object()->name(WER))+" verschwindet mit einem "+
+        "\"PLOPP\". Da scheint Magie im Spiel zu sein."
+      ));
+    }
+  }
+
+  // Objekt zerstoeren
+  remove(1);
+}
+
+static int act_essen(string args)
+{
+    // Nur ein Demo-Objekt
+    if (!IS_LEARNING(this_player()))
+    {
+      write("Schwups, nun ist @@name@@ verschwunden. War wohl eine Illusion.");
+      remove(1);
+    }
+
+    // Der Syntaxtest ist unnoetig, der ist schon im new style
+    // AddCmd() eingebaut.
+
+    // Wenn das Objekt ein Environment hat (hoff ich doch)
+    // und das Environment nicht this_player() ist, 
+    // hat der Spieler das Obst nich im Inv - das geht doch nicht ...
+    if (environment(this_object()) && (environment(this_object()) != this_player()) )
+    {
+      write(BS78(
+        "Du solltest "+ this_object()->name(WER,1) + " erstmal nehmen."
+      ));
+      return 1;
+    }
+
+    // DEBUG ("Satt?");
+    if (this_player()->eat_food(SAETTIGUNG))
+    {
+      // DEBUG("Noe!");
+      if (this_player()->check_and_update_timed_key(EAT_DELAY,"vanion_zach_obst")==-1)
+      {
+        write(BS78(
+          "Du isst genuesslich "+this_object()->name(WEN,0)+
+          ". Du fuehlst Dich gestaerkt."
+        ));
+        say(BS78(
+          this_player()->name()+" isst mit vollem Genuss "+this_object()->name(WEN,0)+". "
+          "Dir laeuft das Wasser im Munde zusammen."
+        ));
+        // Heilen und aufessen :)
+        this_player()->heal_self(HEILUNG);
+      }
+      else { // if (check_and_update_timed_key())
+        // Wenn es noch zu frueh ist, wieder welches zu essen
+        // Keine Heilung, aber Saettigung
+        write(BS78(
+          "Du solltest "+this_object()->name(WEN,1)+" lieber jemandem geben, "
+          "den Du magst, statt alles selbst zu futtern, findest Du nicht? "
+          "Deine Gier hat Dir jetzt nur einen vollen Bauch und ein schlechtes "
+          "Gewissen bescheert."
+        ));
+      } // end if (check_and_update_timed_key())
+      if (!remove()) destruct(this_object());
+    } // end of eat_food
+    return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/README b/doc/beispiele/Praxis-Kurs/README
new file mode 100644
index 0000000..99a8dd0
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/README
@@ -0,0 +1,16 @@
+In diesem Verzeichnis befindet sich ein kleiner "Praxis LPC-Kurs".
+Im Prinzip sind es verschiedene gut dokumentierte LPC-Objekte die
+aufeinander aufbauen und in denen alles notwendige erklaert wird.
+Wer also schon mal irgendwo programmiert hat und sich nur an die
+LPC-Umgebung gewoehnen muss, fuer den ist dieser Mini-Kurs sicher
+genau das richtige. Fuer jemand der noch nie programmiert hat ist
+dieser Kurs alleine aber sicher nicht geeignet um programmieren zu
+lernen. Die Files sollten in der Alphabetischer Reihenfolge und da
+die Files aufeinander aufbauen, auch vollstaendig durchgegangen
+werden.
+Bei dem Verzeichnis zauberwald handelt es sich um ein kleines und
+dadurch ueberschaubares Gebiet von mir, das nicht eine Ansammlung
+von AddDetails darstellt, sondern auch komplexere Funktionen wie
+Virtual Compiler oder Heilstellen enthaelt.
+
+                                             Padreic
diff --git a/doc/beispiele/Praxis-Kurs/hello_world.c b/doc/beispiele/Praxis-Kurs/hello_world.c
new file mode 100644
index 0000000..8109e06
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/hello_world.c
@@ -0,0 +1,37 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Auch wenn dieses Objekt noch keinerlei tieferen Sinn hat, so ist es doch
+// bereits ein vollstaendiges Objekt (bereits eine einzige Funktion reicht
+//  fuer ein LPC-Object aus).
+
+// Die 3 Funktionen in diesem Objekt haben darueber hinaus noch eine
+// ganz besondere Bedeutung. Jede dieser 3 Funktionen wird vom Game-Driver
+// im laufenden Betrieb bei besonderen Anlaessen aufgerufen.
+
+protected void create()
+// Diese Funktion wird aufgerufen sobald dieses Objekt geclont wird.
+{
+   // gibt an den Spieler der dieses Objekt clont eine Meldung aus.
+   tell_object(this_player(), "Hello World!\n");
+}
+
+void init()
+// Diese Funktion wird aufgerufen, sobald ein Spieler oder ein NPC in
+// Reichweite dieses Objektes kommt: Also entweder wenn ein Lebewesen in
+// das Objekt bewegt wird oder umgekehrt oder wenn ein Lebewesen in die
+// Umgebung eines Objektes kommt oder umgekehrt.
+{
+   // gibt wieder eine Meldung an den Spieler aus...
+   tell_object(this_player(), ("Hello again :).\n");
+}
+
+void reset()
+// Diese Funktion wird im beruemten Reset aufgerufen, den Du ja sicher auch
+// schon als Spieler kennengelernt hast (Also alle 30-60 Minuten).
+// Ausnahme: Wenn das Objekt laengere Zeit mit keinem anderen Objekt
+// kommuniziert hat, wird diese Funktion vorlaeufig nicht mehr aufgerufen!
+{
+  // Hier kann man nun auch irgendetwas machen. Ein write("..") haette
+  // hier jedoch keinen Effekt, da kein Spieler diese Funktion ausgeloest
+  // hat und daher nicht bekannt ist, an wen die Meldung denn gehen soll...
+}
diff --git a/doc/beispiele/Praxis-Kurs/juwelen.c b/doc/beispiele/Praxis-Kurs/juwelen.c
new file mode 100644
index 0000000..c1070a6
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/juwelen.c
@@ -0,0 +1,66 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Dieses ist ein erstes Objekt das so oder aehnlich tatsaechlich im
+// MorgenGrauen vorkommen koennte.
+
+// Jedes Objekt im MorgenGrauen braucht bereits eine solche Vielzahl von
+// Standardfunktionen, dass es ziemlich unmoeglich ist, diese alle in jedem
+// Objekt zu definieren. Daher "erbt" man diese Funktionen von einem
+// Standardobjekt.
+// "Erben" bedeutet hierbei, das man auf alle Funktionen, die bereits im
+// Standardobjekt definiert sind, zugreifen kann.
+//
+// Die folgende Zeile erklaert, dass man das Objekt an der Position
+//  /std/thing.c "erben" moechte.
+inherit "/std/thing";
+
+
+// Die Funktion folgender Zeile kann man sich recht einfach wie folgt
+// vorstellen: Wenn der Game-Driver dieses Objekt hier compiliert, dann
+// tut er so, als wuerde die Datei /sys/properties.h genau an dieser Stelle
+// hier im Code stehen.
+//
+// Die Datei properties.h beinhaltet einfach nur haufenweise Defines fuer
+// die haufenweise Properties.
+//
+// Anmerkung: Alle Defines in dieser Datei starten uebrigens mit einem 'P_'.
+// Am Besten solltest Du einfach mal kurz in /doc/properties.h reinsehn
+// und ein bisschen rumlesen
+//  (keine Angst, die muss man nicht alle kennen :).
+#include <properties.h>
+
+protected void create()
+{
+  // Die Funktion create() wurde naemlich bereits in /std/thing.c
+  // beschrieben, kann aber nicht mehr ueber create() aufgerufen werden, da
+  // dann ja wieder diese Funktion hier aufgerufen wuerde
+  // (wodurch wir dann eine Endlos-Rekursion haetten).
+  // Kurzschreibweise waere ::create(); wenn man nur von einem Objekt erbt.
+  thing::create(); // oder auch einfach ::create();
+
+  // Auch diese Funktion wurde aus /std/thing geerbt.
+  // SetProp() ist eine der wichtigsten Funktionen ueberhaupt, wenn es darum
+  // geht, ein Objekt zu beschreiben. Mit dieser Funktion kannst Du naemlich
+  // zahlreiche Eigenschaften (engl. properties) des Objektes festlegen.
+  SetProp(P_SHORT, "Einige wertvolle Juwelen");      // die Kurzbeschreibung
+  SetProp(P_LONG, "Die Juwelen glitzern verlockend.\n"); // Langbeschreibung
+  SetProp(P_NAME, "Juwelen"); // der eigentliche Name
+  SetProp(P_NAME_ADJ, "wertvoll"); // das Adjektiv vor dem Namen
+  SetProp(P_GENDER, FEMALE); // Geschlecht (kann auch MALE oder NEUTER sein)
+  SetProp(P_WEIGHT, 5000); // dieses Objekt wiegt 5kg
+  SetProp(P_VALUE, 10000); // das Objekt ist insgesamt 10000 Muenzen Wert
+  
+  // Mit dieser Funktion kann man eine id angeben, ueber die das Objekt
+  // ansprechbar ist.
+  // Anmerkung: Auch diese Funktion ist wieder von std/thing geerbt, im
+  //   folgenden werde ich dies aber nicht mehr bei jeder Funktion extra
+  //   angeben. Wenn nicht anders angegeben, handelt es sich ab jetzt
+  //   naemlich _immer_ um ererbte Funktionen.
+  AddId("juwelen");
+  
+  // In diesem Fall benoetigt man noch ein weiteres Adjektiv, da man das
+  // Objekt ja auch mit wertvolle Juwelen ansprechen koennen moechte.
+  // z.B.: unt wertvolle juwelen
+  //       gib wertvolle juwelen an padreic
+  AddAdjective("wertvolle");
+}
diff --git a/doc/beispiele/Praxis-Kurs/los.c b/doc/beispiele/Praxis-Kurs/los.c
new file mode 100644
index 0000000..f3b41e8
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/los.c
@@ -0,0 +1,118 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h> // wieder unsere allgemeinen Propertys
+#include <moving.h>     // einige Defines zum Bewegen von Objekten (s.u.)
+
+inherit "/std/thing";
+
+protected void create()
+{
+  ::create();
+   // Objekt ueber seine Properties beschreiben...
+   SetProp(P_SHORT, "Ein Rubbellos");
+   SetProp(P_LONG,
+    "Du kannst dieses Los aufrubbeln um zu sehen, ob Du einen grossen "
+    "Schatz\ngewonnen hast.\n");
+   SetProp(P_NAME, "Rubbellos");
+   SetProp(P_ARTICLE, 1); // ist eigentlich bereits Defaultwert
+   SetProp(P_GENDER, NEUTER);
+   SetProp(P_VALUE, 1000);
+   SetProp(P_WEIGHT, 500);
+   SetProp(P_INFO, "Deine Gewinnchancen bei diesen Losen sind nicht "
+                   "sonderlich gut.\n");
+   SetProp(P_MAGIC, 0); // (einfach nur, um mal alle Properties zu benutzen)
+   AddId("los"); // noch eine id angeben...
+
+   // Mit Hilfe dieser neuen wichtigen Funktion ist es moeglich, Befehle zu
+   // definieren, ueber die man irgendetwas ausloesen koennen soll:
+   // Und zwar wird sobald ein Spieler den Befehl rubble oder rubbel
+   // benutzt, die Funktion _rubbeln() hier im Objekt aufgerufen. Da diese
+   // Funktion bisher ja noch nicht definiert ist, muss diese natuerlich
+   // auch noch programmiert werden.
+   AddCmd(({"rubble", "rubbel"}), "_rubbeln");
+}
+
+// Diese Funktion sieht gleich um einiges komplexer aus als die Funktionen
+// create(), init() und reset(), die bisher benutzt wurden.
+// Das static am Anfang erklaert nur, dass diese Funktion nicht von aussen,
+// sondern nur von innerhalb des Objektes aufgerufen werden kann.
+// Das "int" anstelle des "void" bedeutet, dass die Funktionen ein Ergebnis
+// zurueckliefert. Da diese Funktion in Verbindung mit AddCmd() benutzt
+// wird, hat dieser Rueckgabewert auch eine besondere Bedeutung:
+//   Eine 1 bedeutet, dass der Befehl fertig abgearbeitet wurde.
+//   Eine 0 bedeutet, das Objekt konnte mit dem Befehl nichts anfangen, der
+//    Gamedriver muss also noch in weiteren Objekten anfragen, die der
+//    Spieler bei sich traegt.
+// Der String 'str', den die Funktion als Parameter uebergeben bekommt,
+// enthaelt das, was der Spieler ausser dem eigentlichen Verb eingegeben
+// hat (Woerter wie 'und', 'ein', 'der', 'die', 'das' ... werden hierbei
+//  zuvor herausgefiltert)
+// Bsp.:   rubbel los      ->  _rubbeln("los")
+//         rubbel katze    ->  _rubbeln("katze")
+//         rubbel los auf  ->  _rubbeln("los auf")
+public int _rubbeln(string str)
+{
+   // Die Funktion notify_fail() ist wieder eine Funktion des Gamedrivers:
+   // Und zwar ist es moeglich hier eine Meldung anzugeben, die anstelle
+   // eines "Wie bitte?" kommt, falls kein Objekt den Befehl richtig
+   // abgearbeitet hat.
+   notify_fail("Syntax: rubbel los auf\n"); // eigentlich efun::notify_fail()
+
+   // Wenn der uebergebene String ungleich "los auf" ist, dann fuehlt sich
+   // das Objekt nicht angesprochen, kann das Verb also nicht komplett
+   // abarbeiten und gibt deshalb eine 0 zurueck.
+   if (str!="los auf") return 0;
+
+   // Auch die Funktion random() ist wieder eine Funktion des Gamedriver:
+   // Und zwar liefert sie eine ganzzahlige Zufallszahl zwischen 0 und n-1
+   //  (wobei n die uebergebene Zahl ist). In diesem Fall also zwischen
+   // 0 und 99.
+   if (random(100)<92) { // sollte diese Zahl < 92 sein, dann tue Folgendes:
+     write("Du rubbelst das Los auf. Leider war es jedoch nur eine Niete.\n"
+          +"Veraergert laesst Du das Los deshalb fallen.\n");
+   }
+   else { // sollte die Zahl nicht < 92 gewesen sein, dann tue Folgendes:
+     object ob; // bereitstellen einer Hilfsvariablen
+
+     write("Du rubbelst das Los auf und strahlst vor Freude. Es war der "
+          +"absolute Hauptgewinn.\nSofort kommt ein Bote herein und "
+          +"ueberreicht Dir Deinen Gewinn.\n");
+
+     // Mit clone_object() kann man ein beliebiges Objekt Clonen, indem man
+     // einfach den entsprechenden Filenamen als Parameter uebergibt.
+     ob=clone_object("/doc/beispiele/Praxis-Kurs/juwelen");
+
+     // Nun kommen gleich 3 neue Dinge auf einmal...
+     // Mit -> wird eine Funktion in einem anderen Objekt aufgerufen
+     //  (alternativ auch: call_other(ob,move,this_player(), M_GET); )
+     // Die Funktion, die hierbei aufgerufen werden soll, heisst move().
+     // Diese Funktion ist in allen Objekten definiert, die /std/thing erben.
+     // Somit koennen wir also fest davon ausgehen, dass sie auch in unseren
+     // Juwelen vorhanden ist.
+     // this_player() ist eine sehr wichtige Gamedriver-Funktion, da sie
+     // uns das Lebewesen zurueckliefert, das gerade aktiv durch einen Befehl
+     // den aktuellen Funktionsaufruf gestartet hat.
+     // M_GET ist lediglich ein Define, das in moving.h definiert ist.
+     // Naeheres hierzu findet man auch in <man move>.
+     ob->move(this_player(), M_GET);
+     // ACHTUNG: um dieses Beispiel simpel zu halten, wird hier darauf
+     // verzichtet, zu pruefen, ob diese Bewegung ueberhaupt funktioniert
+     // hat. Normalerweise muss man in diesem Fall (misslungene Bewegung)
+     // eine Fehlerbehandlung durchfuehren (z.B. ob wieder entfernen,
+     // Meldung an den Spieler ausgeben).
+   }
+
+   // Die Funktion say() gibt an alle Spieler im Raum des aktiven Spielers
+   // eine Nachricht aus, aber nicht an den betroffenen Spieler selbst!
+   // Die Funktion Name(), die hier im Spieler aufgerufen wird, wertet
+   // dessen Propertie P_NAME aus und dekliniert den Namen im angegebenen
+   // Fall.
+   say(this_player()->Name(WER)+" rubbelt ein Los auf.\n");
+
+   // Und nun soll sich das Objekt selbst entfernen (zerstoeren).
+   remove();
+
+   // Da der Befehl ja komplett abgearbeitet wurde, geben wir eine 1
+   // zurueck.
+   return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/milch.c b/doc/beispiele/Praxis-Kurs/milch.c
new file mode 100644
index 0000000..66b6173
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/milch.c
@@ -0,0 +1,91 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Anmerkung: Heutzutage gibt es fuer Lebensmittel (bzw. alle Dinge, die
+// man essen oder trinken kann) ein Standardobjekt namens /std/food,
+// welches viele Funktionalitaet mitbringt, die man ansonsten selber
+// muehsam basteln muss. Die Verwendung ist dringend empfohlen.
+
+#include <properties.h> // wieder unsere allgemeinen Properties
+
+inherit "/std/thing";
+
+// globale Variable, die angibt, wie voll die Flasche ist. Es sind 5
+// Portionen enthalten.
+int menge = 5;
+
+protected void create()
+{
+   ::create();
+   // Objekt ueber seine Properties beschreiben...
+   // P_SHORT und P_LONG werden direkt als Funktion implementiert (s.u.)
+   SetProp(P_NAME, "Milchflasche");
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_VALUE, 80);
+   SetProp(P_WEIGHT, 1000);
+   AddId(({"flasche", "milchflasche"}));
+   AddCmd(({"trink", "trinke"}), "_trinken");
+}
+
+// Anstelle von P_SHORT Kurzbeschreibung ueber Funktion short().
+// Dies ist nicht immer moeglich, da nicht zwangslaeufig zu jeder Propertie
+// eine gleichnamige Funktion existiert.
+// Es ist allerdings noch sog. Querymethoden (siehe dazu <man QueryProp> und
+// <man Query> bei Bedarf).
+public string short()
+{
+   string str;
+   switch(menge) {
+     case 1: str="Eine fast leere Milchflasche.\n"; break;
+     case 2: str="Eine bald leere Milchflasche.\n"; break;
+     case 3: str="Eine halbvolle Milchflasche.\n";  break;
+     case 4: str="Eine fast volle Milchflasche.\n"; break;
+     case 5: str="Eine volle Milchflasche.\n";      break;
+     default: str="Eine leere Milchflasche.\n";
+   }
+   return str;
+}
+
+public string long()
+{
+   if (menge>1)
+      return "Eine Flasche mit leckerer Vollmilch.\n";
+   else
+      return "Die Milchflasche ist bald leider schon alle, Du solltest "
+             "Dich vielleicht mal\nnach Nachschub umsehn.\n";
+}
+
+public int _trinken(string str)
+{
+   notify_fail("Syntax: trinke aus milchflasche\n");
+
+   // Falls die ersten vier Zeichen in dem uebergebenen String ungleich
+   // "aus " sind, dann fuehlt sich das Objekt nicht angesprochen, kann das
+   // Verb also nicht komplett abarbeiten und gibt deshalb eine 0 zurueck.
+   if (str[0..3]!="aus ") return 0;
+
+   // Ich benutze nun alles ab dem vierten Zeichen und pruefe, ob sich das
+   // Objekt davon angesprochen fuehlt. Hierzu dient die Funktion id().
+   // Grosser Vorteil: Uebersichtlich und spaeteres Ergaenzen von Ids bzw.
+   // Adjektiven geht sehr einfach und erspart lange if()-Abfragen.
+   if ( !id(str[4..]) ) return 0;
+
+   if (menge<=0) {
+     write("Die Milchflasche ist leider schon leer :(.\n");
+   }
+   else {
+     // drink_soft() ist eine Funktion, die in allen Lebewesen im
+     // Morgengrauen definiert ist und ueber die man sowohl Abfragen als
+     // auch hochsetzen von P_DRINK vornehmen sollte.
+     if (this_player()->drink_soft(10)) {
+
+       // heal_self() ist auch in allen Lebewesen definiert und heilt bei
+       // dem Lebewesen Lebens- und Konzentrationspunkte.
+       this_player()->heal_self(10);
+       write("Genuesslich trinkst Du einen Schluck Milch.\n");
+       say(this_player()->Name(WER)+" trinkt einen Schluck Vollmilch,\n");
+       menge--;
+     }
+     else write("Soviel kannst Du leider nicht mehr trinken.\n");
+   }
+   return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/npc.c b/doc/beispiele/Praxis-Kurs/npc.c
new file mode 100644
index 0000000..39a54fd
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/npc.c
@@ -0,0 +1,115 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h>
+#include <attributes.h>
+#include <combat.h>
+#include <guard.h>
+#include <moving.h>
+#include <new_skills.h>
+
+// Ein NPC wird nicht von /std/thing direkt geerbt, sondern von /std/npc.
+// Da /std/npc aber seinerseits wieder von /std/thing erbt, sind im NPC auch
+// saemtliche Funktionen definiert, die bereits in /std/thing enthalten sind.
+inherit "/std/npc";
+
+void create()
+{
+   ::create();
+   // create_default_npc() setzt schon mal einige wichtige Properties wie
+   // P_ATTRIBUTES automatisch...
+   create_default_npc(20, 300);
+
+   // Keine Angst: Es muessen keineswegs immer alle diese Properties benutzt
+   // werden, auch wenn ich sie jetzt einmal alle angebe, um eine Uebersicht
+   // zu geben, was man alles ueber Properties steuern kann...
+   SetProp(P_SHORT, "Ein fieser Ork");
+   SetProp(P_LONG, "Der Ork schaut Dich grimmig an.\n");
+   SetProp(P_NAME, "Ork");
+   SetProp(P_NAME_ADJ, "fies");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_MAGIC, 0);
+   SetProp(P_MATERIAL, MAT_MISC_LIVING);
+
+   // nun komen einige wirklich neue Properties
+   SetProp(P_INFO, "Der Ork ist ein ganz gemeiner... :)\n");
+   SetProp(P_ALIGN, -500); // Alignment des Gegners
+   SetProp(P_RACE, "Ork"); // Rasse des NPCs
+   SetProp(P_AGGRESSIVE, 1); // greift aggressiv jeden an
+   SetProp(P_ATTRIBUTES, ([A_INT:5, A_DEX:10, A_STR:25, A_CON:10]));
+   SetProp(P_SIZE, 134); // Groesse in cm
+   SetProp(P_MAX_HP, 300); // max. Lebenspunkte
+   SetProp(P_HP, 300); // Lebenspunkte
+   SetProp(P_MAX_SP, 200); // max. Magiepunkte
+   SetProp(P_SP, 200); // Magiepunkte
+   SetProp(P_BODY, 80); // Grundruestungsschutz des Koerpers
+   SetProp(P_MAX_HANDS, 2); // kaempft mit zwei Haenden...
+   SetProp(P_HANDS, ({" mit blossen Haenden", 150}));
+   SetProp(P_NOMAGIC, 20); // 20% Resistenz gegen Spells
+   SetProp(P_GUARD, 20); // Der NPC laesst sich ggf. weglocken
+   SetProp(P_NO_GLOBAL_ATTACK, 0); // wird von 'toete alles' erfasst
+   SetProp(P_NO_ATTACK, 0);  // kann man den NPC ueberhaupt angreifen?
+   SetProp(P_FRIEND, 0); // soll der NPC in Spells als Freund erfasst
+                         // werden?
+   SetProp(P_RESISTANCE, DT_FIRE);  // Resistenzen
+   SetProp(P_VULNERABILITY, DT_HOLY);  // Empfindlichkeiten
+   SetProp(P_FOOD, 0);
+   SetProp(P_MAX_FOOD, 100);
+   SetProp(P_DRINK, 0);
+   SetProp(P_MAX_DRINK, 100);
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_MAX_ALCOHOL, 100);
+   SetProp(P_XP, QueryProp(P_MAX_HP)*QueryProp(P_HANDS)[0]*5); // Erfahrung
+   SetProp(P_MURDER_MSG, "Ich komme doch eh wieder!\n"); // Moerdermeldung
+   SetProp(P_KILL_NAME, "Ein fieser Testork"); // noetig falls != P_NAME
+   SetProp(P_KILL_MSG, "Das kommt davon wenn man sich mit mir anlegt.\n");
+   SetProp(P_DIE_MSG, "Der Ork schreit ein letztes mal laut auf.\n");
+   SetProp(P_NOCORPSE, 0); // soll der NPC eine Leiche hinterlassen?
+   SetProp(P_HEAL, -10); // wieviel LP bekommt man beim Leichen essen...
+
+   // der Ork ist Mitglied der Abenteurergilde...
+   SetProp(P_GUILD, "abenteurer"); // in die Abenteuergilde mit ihm...
+   SetProp(P_GUILD_LEVEL, 20);
+   ModifySkill("feuerball",([SI_SKILLABILITY:10000]),1,"abenteurer");
+
+   // nun noch eine andere Art zu zaubern...
+   SetProp(P_SPELLRATE, 10);
+   AddSpell(100, 400,
+     "Der Ork tritt Dich einmal feste zwischen die Beine.\n",
+     "Der Ork tritt @WEN einmal feste zwischen die Beine.\n", DT_BLUDGEON);
+
+   // was soll der NPC mit ihm gegebenen Gegenstaenden machen...
+   SetProp(P_REJECT, ({REJECT_DROP, "Damit kann ich nichts anfangen.\n"}));
+
+   // und natuerlich auch noch eine id fuer den ork
+   AddId("ork");
+
+   // Der NPC hat immer einige Juwelen bei sich.
+   AddItem("/doc/beispiele/Praxis-Kurs/juwelen");
+}
+
+// Diese Funktion wird aufgerufen, wenn man einen Gegenstand bekommt...
+public void give_notify(object ob)
+{
+   if (ob->id("milchflasche")) // Milch annehmen und einen Spruch aufsagen
+     write("Der Ork sagt: Ohh.... Danke fuer die leckere Milch.\n");
+   else ::give_notify(ob); // Gegenstand fallen lassen
+}
+
+// Diese Funktion wird aufgerufen, wenn uns jemand im Kampf Schaden zufuegen
+// moechte...
+public varargs int Defend(int dam, mixed dam_type, mixed spell, object enemy)
+{
+   if (!random(4))
+     write("Der Ork weicht Deinem Angriff geschickt aus.\n");
+   else
+     return ::Defend(dam, dam_type, spell, enemy);
+}
+
+public void Attack(object enemy)
+{
+  // das Kommando 'Feuerball' eingeben. Da der NPC Mitglied der
+  // Abenteurergilde ist (s.o.), spricht er also den Spell, falls er genug
+  // Magiepunkt dafuer hat.
+  if (!random(3)) command_me("feuerball");
+  ::Attack(enemy);
+}
diff --git a/doc/beispiele/fernwaffen/kurzbogen.c b/doc/beispiele/fernwaffen/kurzbogen.c
new file mode 100644
index 0000000..93623e5
--- /dev/null
+++ b/doc/beispiele/fernwaffen/kurzbogen.c
@@ -0,0 +1,32 @@
+inherit "/std/ranged_weapon";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  if (!clonep(this_object())) return;
+  ::create();
+
+  SetProp(P_SHORT, "Ein Kurzbogen");
+  SetProp(P_INFO,
+    "Die Syntax lautet: schiesse <geschoss> auf <ziel>\n");
+  SetProp(P_NAME, "Kurzbogen");
+  SetProp(P_LONG, break_string(
+    "Mit diesem Kurzbogen kann man sicher nicht weit schiessen."));
+  SetProp(P_MATERIAL, MAT_MISC_WOOD);
+
+  AddId("kurzbogen");
+  SetProp(P_GENDER, MALE);
+  SetProp(P_WEIGHT, 800);
+  SetProp(P_VALUE, 300);
+
+  SetProp(P_WC, 10);
+  SetProp(P_DAM_TYPE, DT_BLUDGEON);
+
+  SetProp(P_SHOOTING_WC, 60);
+  SetProp(P_NR_HANDS, 2);
+  SetProp(P_WEAPON_TYPE, WT_RANGED_WEAPON);
+  SetProp(P_AMMUNITION, MUN_ARROW);
+  SetProp(P_STRETCH_TIME, 1);
+  SetProp(P_RANGE, 10);
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/langbogen.c b/doc/beispiele/fernwaffen/langbogen.c
new file mode 100644
index 0000000..7956dd3
--- /dev/null
+++ b/doc/beispiele/fernwaffen/langbogen.c
@@ -0,0 +1,32 @@
+inherit "/std/ranged_weapon";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  if (!clonep(this_object())) return;
+  ::create();
+
+  SetProp(P_SHORT, "Ein Langbogen");
+  SetProp(P_INFO,
+    "Die Syntax lautet: schiesse <geschoss> auf <ziel>\n");
+  SetProp(P_NAME, "Langbogen");
+  SetProp(P_LONG, break_string(
+    "Mit diesem Langbogen kann man bestimmt hervorragend weit schiessen."));
+  SetProp(P_MATERIAL, MAT_MISC_WOOD);
+
+  AddId("langbogen");
+  SetProp(P_GENDER, MALE);
+  SetProp(P_WEIGHT, 800);
+  SetProp(P_VALUE, 300);
+
+  SetProp(P_WC, 30);
+  SetProp(P_DAM_TYPE, DT_BLUDGEON);
+
+  SetProp(P_SHOOTING_WC, 120);
+  SetProp(P_NR_HANDS, 2);
+  SetProp(P_WEAPON_TYPE, WT_RANGED_WEAPON);
+  SetProp(P_AMMUNITION, MUN_ARROW);
+  SetProp(P_STRETCH_TIME, 2);
+  SetProp(P_RANGE, 30);
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/npc.c b/doc/beispiele/fernwaffen/npc.c
new file mode 100644
index 0000000..3544d44
--- /dev/null
+++ b/doc/beispiele/fernwaffen/npc.c
@@ -0,0 +1,29 @@
+inherit "/std/npc";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  ::create();
+  AddId(({"npc", "gegner", "ziel"}));
+  SetProp(P_NAME, "Ziel");
+  SetProp(P_GENDER, NEUTER);
+  SetProp(P_SHORT, "Ein Ziel");
+
+  SetProp(P_HP, 1000);
+  SetProp(P_BODY, 100);
+}
+
+varargs int Defend(int dam, string* dam_type, mixed spell, object enemy) {
+  int predam = dam;
+  int result = ::Defend(dam, &dam_type, &spell, enemy);
+  
+  string str = break_string(sprintf(
+    "Die Zielscheibe sagt: %d Schaden rein und fuer %d getroffen.",
+    predam, result), 78);
+
+  tell_room(load_object(__PATH__(0)"zielraum"), str);
+  tell_room(load_object(__PATH__(0)"schussraum"), str);
+
+  return result;
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/path.h b/doc/beispiele/fernwaffen/path.h
new file mode 100644
index 0000000..d284140
--- /dev/null
+++ b/doc/beispiele/fernwaffen/path.h
@@ -0,0 +1,3 @@
+#pragma rtt_checks, save_types
+#pragma pedantic,  range_check
+#pragma warn_empty_casts, warn_missing_return, warn_function_inconsistent
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/pfeile.c b/doc/beispiele/fernwaffen/pfeile.c
new file mode 100644
index 0000000..f4b11a3
--- /dev/null
+++ b/doc/beispiele/fernwaffen/pfeile.c
@@ -0,0 +1,41 @@
+inherit "/std/unit";
+
+#include "./path.h"
+#include <properties.h>
+#include <class.h>
+
+void create() {
+  if (!clonep(this_object())) return;
+  ::create();
+
+  SetProp(P_NAME, ({"Pfeil", "Pfeile"}) );
+  SetProp(P_LONG, break_string(
+    "Ein paar einfache Holzpfeile.", 78));
+  SetProp(P_GENDER, MALE);
+  SetProp(P_AMOUNT, 1);
+  SetProp(P_SHOOTING_WC, 40);
+  SetProp(P_DAM_TYPE, ({DT_PIERCE}));
+  SetProp(P_WEAPON_TYPE, WT_AMMU);
+  SetProp(P_MATERIAL, MAT_MISC_WOOD);
+
+  SetGramsPerUnits(120,1);
+  SetCoinsPerUnits(25,1);
+
+  AddId(MUN_ARROW);
+  AddSingularId("pfeil");
+  AddPluralId("pfeile");
+  AddClass(CL_AMMUNITION);
+
+  SetProp(P_HIT_FUNC, this_object());
+}
+
+int HitFunc(object enemy) {
+  if(!random(5)) {
+    tell_object(environment(), break_string(
+      "Der Pfeil schnurrt vom Bogen und dabei splittert das Holz "
+      "etwas. Gratiswiderhaken, das ist ja toll!", 78));
+    return 20;
+  }
+
+  return 0;
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/schussraum.c b/doc/beispiele/fernwaffen/schussraum.c
new file mode 100644
index 0000000..79179c9
--- /dev/null
+++ b/doc/beispiele/fernwaffen/schussraum.c
@@ -0,0 +1,34 @@
+inherit "/std/room";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  ::create();
+
+  SetProp(P_LIGHT, 1);
+  SetProp(P_INT_SHORT, "Auf einem Baum");
+  SetProp(P_INT_LONG, break_string(
+    "Du hockst auf einem Baum und kannst auf die Lichtung unter Dir sehen. "
+    "'schau runter' hilft sicherlich, Ziele auszumachen."));
+
+  AddDetail("runter", function string { 
+                        return __PATH__(0)"zielraum"->int_long(this_player());
+                      });
+
+  AddItem(__PATH__(0)"langbogen", REFRESH_REMOVE);
+  AddItem(__PATH__(0)"kurzbogen", REFRESH_REMOVE);
+  AddItem(__PATH__(0)"pfeile", REFRESH_REMOVE, ([P_AMOUNT: 20]));
+
+  AddExit("zielraum", __PATH__(0)"zielraum");
+  load_object(__PATH__(0)"zielraum");
+
+  SetProp(P_TARGET_AREA, __PATH__(0)"zielraum"); // anderer Raum beschiessbar
+  SetProp(P_SHOOTING_AREA, 15);                  // 15 Entfernung
+}
+
+// nur wegen des P_NEVER_CLEAN im Zielraum und nur hier in doc relevant
+public varargs int remove(int silent) {
+  __PATH__(0)"zielraum"->remove();
+  return ::remove();
+}
diff --git a/doc/beispiele/fernwaffen/zielraum.c b/doc/beispiele/fernwaffen/zielraum.c
new file mode 100644
index 0000000..6177032
--- /dev/null
+++ b/doc/beispiele/fernwaffen/zielraum.c
@@ -0,0 +1,19 @@
+inherit "/std/room";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  ::create();
+
+  SetProp(P_LIGHT, 1);
+  SetProp(P_INT_SHORT, "Auf einer Lichtung");
+  SetProp(P_INT_LONG, break_string(
+    "Auf dieser Lichtung steht ein Baum, der verdaechtig viele Aeste hat, "
+    "von denen man auf die Lichtung gut sehen kann."));
+  SetProp(P_NEVER_CLEAN, 1); // damit der Raum auch da bleibt
+
+  AddItem(__PATH__(0)"npc", REFRESH_REMOVE);
+
+  AddExit("schussraum", __PATH__(0)"schussraum");
+}
diff --git a/doc/beispiele/food/banane.c b/doc/beispiele/food/banane.c
new file mode 100644
index 0000000..8882f4f
--- /dev/null
+++ b/doc/beispiele/food/banane.c
@@ -0,0 +1,114 @@
+/*
+Beispiel fuer eine Banane, die in einem Haps weg ist,
+aber eine Schale hat, die uebrig bleibt und genau wie die
+komplette Banane vergammelt und vergeht.
+*/
+
+#include <food.h>
+
+inherit "/std/food";
+
+string _query_long() {
+  string m = "Du haeltst ";
+  if (is_not_empty()) {
+    m += "eine Banane in der Hand.";
+    if (!is_bad())
+      m += " Sie ist schoen gelb und ohne braune Flecken.";
+    else
+      m += " Sie ist total braun und schon ganz matschig.";
+
+  } else {
+    m += "eine Bananenschale in der Hand.";
+    if (is_bad())
+      m += " Sie ist ganz verschimmelt.";
+  }
+  return break_string(m);
+}
+
+void create() {
+  if (!clonep(this_object())) {
+    set_next_reset(-1);
+    return;
+  }
+  ::create();
+
+  SetProp(P_SHORT,"Eine schoene reife Banane");
+  SetProp(P_NAME, "Banane");
+  SetProp(P_GENDER,FEMALE);
+  SetProp(P_VALUE,20); // ohne Schale
+  SetProp(P_WEIGHT,50); // ohne Schale
+  // SetProp(P_POTION,1); // ist eh Standard
+  SetProp(P_CONSUME_MSG,
+    "@WER2 schaelt eine Banane und isst sie genuesslich.");
+  SetProp(P_EATER_MSG,
+    "Du schaelst eine Banane und isst sie genuesslich.");
+  SetProp(P_BAD_MSG,
+    "Die Banane wird ganz matschig und schlecht.");
+  SetProp(P_REMOVE_MSG,
+    "Die Banane ist so verschimmelt, dass Du sie entsorgst.");
+  SetProp(P_EMPTY_MSG,
+    "Aber das ist doch nur eine BananenSCHALE, die willst Du nicht essen!");
+
+  SetProp(P_MATERIAL,([MAT_MISC_PLANT:100]));
+
+  SetProp(P_EMPTY_PROPS, ([
+    P_SHORT:"Eine Bananenschale",
+    P_NAME:"Bananenschale",
+    P_EMPTY_IDS:({"schale","bananenschale","banane"}),
+    P_VALUE:5, // Wert der Bananenschale
+    P_WEIGHT:5  // Gewicht der Bananenschale
+  ]));
+
+  //SetProp(P_RESET_LIFETIME,1); // ist eh Standard
+  SetProp(P_DESTROY_BAD,300); // verdorbene Bananen verschwinden nach 5 Min
+
+  SetProp(P_FOOD,50); // Fuellgrad der Banane
+  SetProp(P_HP,5);
+  SetProp(P_SP,5);
+
+  AddId(({"banane"}));
+
+}
+
+// Der Behaelter vergammelt auch
+public int make_destroy() {
+  if (!::make_destroy()) {
+    return remove(1);
+  }
+  return 1;
+}
+
+public int make_empty() {
+  SetProp(P_BAD_MSG,
+    "Die Bananenschale wird ganz schimmlig.");
+  SetProp(P_REMOVE_MSG,
+    "Die Bananenschale zersetzt sich vollstaendig.");
+  return ::make_empty();
+}
+
+// parent methode immer aufrufen und pruefen!!
+void make_bad() {
+  if (!::make_bad()) {
+    if (is_not_empty()) {
+      SetProp(P_SHORT,"Eine matschige Banane");
+      AddAdjective(({"matschige","matschigen"}));
+      SetProp(P_EATER_MSG,"Du lutschst die matschige Banane aus ihrer"
+        "Schale. Baeh, die schmeckt ueberhaupt nicht mehr.");
+      SetProp(P_CONSUME_MSG,
+        "@WER2 lutscht eine matschige Banane aus ihrer Schale.");
+      // Die Schale ist dann natuerlich auch vergammelt
+      SetProp(P_EMPTY_PROPS, ([
+        P_SHORT:"Eine verschimmelte Bananenschale",
+        P_NAME:"Bananenschale",
+        P_EMPTY_IDS:({"schale","bananenschale","banane"}),
+        P_EMPTY_ADJ:({"verschimmelte","verschimmelten"}),
+        P_VALUE:5, // Wert der Bananenschale
+        P_WEIGHT:5  // Gewicht der Bananenschale
+      ]));
+    } else {
+      message(P_BAD_MSG);
+      SetProp(P_SHORT,"Eine verschimmelte Bananenschale");
+      AddAdjective(({"verschimmelte","verschimmelten"}));
+    }
+  }
+}
diff --git a/doc/beispiele/food/wasserflasche.c b/doc/beispiele/food/wasserflasche.c
new file mode 100644
index 0000000..3c62c13
--- /dev/null
+++ b/doc/beispiele/food/wasserflasche.c
@@ -0,0 +1,92 @@
+/*
+Beispiel fuer ein tragbares Getraenk in einer Flasche.
+*/
+
+#include <food.h>
+
+inherit "/std/food";
+
+string _query_long() {
+  string m = "Du siehst eine Glasflasche,";
+  if (is_not_empty()) {
+    m += " in der sich Wasser befindet.";
+    if (!is_bad())
+      m += " Es ist glasklar und sieht irgendwie verlockend aus.";
+    else
+      m += " Es ist truebe und sieht nicht gerade verlockend aus.";
+
+    m += " Die Flasche ist ";
+    switch (to_int((QueryProp(P_PORTIONS)-1)/2.5)) {
+      case 0:
+        m += "fast leer.";
+        break;
+      case 1:
+        m += "halb voll.";
+        break;
+      case 2:
+        m += "fast voll.";
+        break;
+      case 3:
+        m += "voll.";
+        break;
+      default:
+        m += "nicht leer.";
+    }
+  } else {
+    m += " in der frueher mal Wasser war.";
+  }
+  return break_string(m);
+}
+
+void create() {
+  if (!clonep(this_object())) {
+    set_next_reset(-1);
+    return;
+  }
+  ::create();
+
+  SetProp(P_SHORT,"Eine Flasche mit Wasser");
+  SetProp(P_NAME, "Wasserflasche");
+  SetProp(P_GENDER,FEMALE);
+  SetProp(P_VALUE,5); // pro Portion (ohne Flasche)
+  SetProp(P_WEIGHT,50); // pro Portion (ohne Flasche)
+  SetProp(P_PORTIONS,10);
+  SetProp(P_DESTROY_BAD,0); // verdorbenes Wasser wird nicht zerstoert
+  SetProp(P_CONSUME_MSG,
+    "@WER2 trinkt aus einer Flasche. Wasser laeuft ueber @WENQPPNS2 Kinn.");
+  SetProp(P_EATER_MSG,
+    "Du trinkst Wasser aus der Flasche. Etwas laeuft Dir ueber das Kinn.");
+  SetProp(P_BAD_MSG,
+    "Das Wasser in der Flasche wird truebe.");
+
+  SetProp(P_MATERIAL,([MAT_GLASS:15, MAT_WATER:85]));
+
+  SetProp(P_EMPTY_PROPS, ([
+    P_SHORT:"Eine leere Flasche",
+    P_NAME:"Flasche",
+    P_EMPTY_IDS:({"flasche"}),
+    P_EMPTY_ADJ:({"leere","leeren"}),
+    P_MATERIAL:([MAT_GLASS:100]),
+    P_VALUE:5, // Wert der Flasche ohne Wasser
+    P_WEIGHT:20  // Gewicht der Flasche ohne Wasser
+  ]));
+
+  SetProp(P_RESET_LIFETIME,3); // 3 Resets, ehe das Wasser truebe wird
+  SetProp(P_DRINK,50); // Fuellgrad pro Schluck
+  SetProp(P_DISTRIBUTION,10); // Punkte Heilung pro Heartbeat
+  SetProp(P_HP,30); // pro Schluck
+  SetProp(P_SP,30); // pro Schluck
+
+  AddId(({"flasche","wasserflasche","wasser"}));
+  AddAdjective(({"volle","vollen"}));
+
+}
+
+// parent methode immer aufrufen und pruefen!!
+void make_bad() {
+  if (!::make_bad() && is_not_empty()) {
+    // die Trinkmeldung aendern wir mal
+    SetProp(P_EATER_MSG,"Du trinkst truebes Wasser aus der Flasche. "
+      "Das war wohl nicht so gut. Dir wird ganz uebel!");
+  }
+}
\ No newline at end of file
diff --git a/doc/beispiele/kekse/keks.c b/doc/beispiele/kekse/keks.c
new file mode 100644
index 0000000..f4a2ab5
--- /dev/null
+++ b/doc/beispiele/kekse/keks.c
@@ -0,0 +1,28 @@
+/* Einfaches Beispiel zur Demonstration von Vererbung.
+   ACHTUNG: Dieses Beispiel stellt _kein_ sinnvolles Lebensmittelobjekt dar.
+            Hierfuer sollte /std/food verwendet werden, siehe auch
+            /doc/beispiele/food/
+*/
+
+#include <properties.h>
+#include <moving.h>
+inherit "/std/thing";
+
+protected void create() {
+  ::create();
+  SetProp(P_NAME, "Keks");
+  SetProp(P_GENDER, MALE);
+  AddId(({"keks"}));
+  AddCmd("iss&@ID", "action_essen", "Was willst du essen?");
+}
+
+public int action_essen(string cmd) {
+  if(this_player()->eat_food(1, 0, 
+                            "Du bekommst "+QueryPronoun(WEN)+
+                            " nicht mehr hineingestopft.\n")>0) {
+    write("Du isst "+name(WEN,1)+".\n");
+    say(this_player()->Name(WER)+" isst "+name(WEN)+".\n");
+    remove(1);
+  }
+  return 1;
+}
diff --git a/doc/beispiele/kekse/kruemelkeks.c b/doc/beispiele/kekse/kruemelkeks.c
new file mode 100644
index 0000000..2fee85a
--- /dev/null
+++ b/doc/beispiele/kekse/kruemelkeks.c
@@ -0,0 +1,15 @@
+/* Einfaches Beispiel zur Demonstration von Vererbung.
+   ACHTUNG: Dieses Beispiel stellt _kein_ sinnvolles Lebensmittelobjekt dar.
+            Hierfuer sollte /std/food verwendet werden, siehe auch
+            /doc/beispiele/food/
+*/
+
+#include <properties.h>
+inherit __DIR__"keks";
+
+varargs int remove(int silent) {
+  if(!silent && living(environment()))
+    tell_object(environment(), Name(WER,1)+
+                               " kruemelt ein letztes Mal.\n");
+  return ::remove(silent);
+}
diff --git a/doc/beispiele/master/access_rights.c b/doc/beispiele/master/access_rights.c
new file mode 100644
index 0000000..367e909
--- /dev/null
+++ b/doc/beispiele/master/access_rights.c
@@ -0,0 +1,13 @@
+// Wenn ein Verzeichnis fuer ein Objekt nicht schreibbar ist, kann der
+// Besitzer des Verzeichnisses eine Datei access_rights anlegen, die
+// dieses Recht vergibt.
+// Da DOC hier eigentlich nicht schreiben darf, war das hier noetig.
+// Ein Magier wird das fuer die eigenen Verz. idR nicht brauchen.
+
+int access_rights( string user, string pfad ) {
+  if( user=="DOC" && pfad=="opferstocklog" ) {
+  	// DOC darf opferstocklog schreiben
+	return 1;
+  }
+  return 0;
+}
diff --git a/doc/beispiele/master/opferstock.c b/doc/beispiele/master/opferstock.c
new file mode 100644
index 0000000..048a461
--- /dev/null
+++ b/doc/beispiele/master/opferstock.c
@@ -0,0 +1,142 @@
+#include <defines.h>
+#include <properties.h>
+#include <moving.h>
+//
+// By Rumata@MorgenGrauen 3/99
+//
+// Beispieldatei fuer die Benutzung von Mastern und Klienten.
+//
+// Ich gehe hier nicht auf die "normalen" Funktionen ein.
+
+inherit "/std/thing";
+
+#define OS_MASTER "/doc/beispiele/master/opferstockmaster"
+
+void create()
+{
+	if(IS_BLUE(ME)) return;
+	::create();
+	SetProp( P_NAME, "Opferstock" );
+	SetProp( P_GENDER, MALE );
+	SetProp( P_VALUE, 1000 + random(2000) );
+	AddId( ({"stock","inschrift","opferstock"}) );
+	SetProp( P_SHORT, "In einer Ecke steht ein Opferstock" );
+	SetProp( P_LONG,
+		"Der Opferstock besteht aus solidem Holz. Vorne auf dem Kasten ist eine\n"
+	+	"Inschrift zu sehen, die Du lesen kannst.\n"
+	+	"@@contents@@"
+	);
+	SetProp( P_READ_MSG,
+		">>>>>>>>>>>> Fuer den Aufbau eines Orkwaisenhauses <<<<<<<<<<<<\n"
+	+	"In den letzten Jahren wurden immer wieder unschuldige Orkkinder\n"
+	+	"durch brutale Abenteurer ihrer Eltern beraubt. Bitte unter-\n"
+	+	"stuetzen Sie mit einer kleinen Spende den Aufbau eines Waisen-\n"
+	+	"hauses fuer diese bemitleidenswerten Kreaturen.\n"
+	);
+	AddDetail( "holz", "Solide und so gut wie unzerbrechlich.\n" );
+	SetProp( P_NOGET,
+		"Der Opferstock ist nicht ohne Grund am Boden festgenagelt.\n" );
+	AddCmd( "spende","spende" );
+	AddCmd( ({"stecke","steck"}), "stecken" );
+	AddCmd( "oeffne","oeffne" );
+	AddCmd( ({"brich","breche"}),"breche" );
+}
+
+contents()
+{
+	switch(QueryProp(P_VALUE))
+	{
+	case 0:
+		return "Er ist leer.\n";
+	case 1:
+		return "Er enthaelt:\nEine Muenze.\n";
+	default:
+		return "Er enthaelt:\n"+QueryProp(P_VALUE)+" Muenzen.\n";
+	}
+}
+
+stecken( str )
+{
+	string was, worein;
+	if( !str || sscanf(str,"%s in %s",was,worein)!=2 || !id(worein) ) return 0;
+	return spende( str );
+}
+
+spende( str )
+{
+	int anz, newAl;
+	string arg;
+	
+	notify_fail( "Wieviele Muenzen willst Du denn spenden?\n" );
+	if( !str || str=="" )
+		return 0;
+	if( sscanf(str,"%d %s",anz,arg)== 2 )
+		str = arg;
+	else
+	{
+		if( str=="eine muenze" || str=="ein goldstueck" )
+		{
+			anz = 1;
+			str = "muenze";
+		}
+		else
+			return 0;
+	}
+	if( anz<=0 || 
+		member(({"muenze","goldstueck","muenzen","goldstuecke"}), str)==-1
+	)
+		return 0;
+	if( anz>PL->QueryMoney() )
+	{
+		write( "So viel Geld hast Du nicht.\n" );
+		return 1;
+	}
+	PL->AddMoney(-anz);
+	SetProp(P_VALUE,QueryProp(P_VALUE)+anz);
+
+	// Hier wird der Master aufgerufen, der das Alignment der Spieler
+	// dann aendert.
+	if( OS_MASTER->addAlignment( PL, anz/3 ) > 0 ) {
+		// Eigentlich könnte man hier auch die Meldung ausgeben, aber
+		// der Spieler soll den Unterschied zwischen Alignment geaendert
+		// unt Alignment nicht geaendert sehen koennen.
+	}
+	write( "Du hast wahrhaft das Gefuehl, etwas Gutes getan zu haben.\n" );
+
+	say( capitalize(PL->name(WER))+" spendet "+anz
+		+ ((anz==1)?" Muenze.\n":" Muenzen.\n") );
+	return 1;
+}
+
+oeffne( str )
+{
+	int newAl;
+	
+	notify_fail( "WAS willst Du oeffnen?\n" );
+	if( !id(str) )
+		return 0;
+	OS_MASTER->addAlignment( PL, -30 );
+	write( "Allein schon der Gedanke....\n" );
+	return 1;
+}
+
+breche( str )
+{
+	string arg;
+	notify_fail( "WAS willst Du aufbrechen?\n" );
+	if( !str )
+		return 0;
+	if( sscanf(str,"%s auf",arg)==1 )
+		str = arg;
+	if( !id(str) )
+		return 0;
+	write( "Dein lautes Getoese ruft einen Teufel herbei, der Dich gleich\n"
+	+	"mit in die Hoelle nimmt.\n"
+	);
+	say( capitalize(PL->name(WER))+" versucht, den Opferstock aufzubrechen.\n"
+	+ "Gleich erscheint ein Teufel, um "+PL->QueryPronoun(WEN)
+	+	" in die Hoelle zu reissen.\n" );
+	PL->move("/d/unterwelt/raeume/qualenraum",M_GO,"zur Hoelle","faehrt");
+	OS_MASTER->addAlignment( PL, -200 );
+	return 1;
+}
diff --git a/doc/beispiele/master/opferstockmaster.c b/doc/beispiele/master/opferstockmaster.c
new file mode 100644
index 0000000..33a081f
--- /dev/null
+++ b/doc/beispiele/master/opferstockmaster.c
@@ -0,0 +1,120 @@
+/*
+ * Beispieldatei fuer einen einfachen Master, der Spielerdaten auch
+ * ueber reboots, resets und updates hinweg speichert, und gleichzeitg
+ * dafuer sorgt, dass die Datenmengen nicht immer groesser werden.
+ *
+ * By: Rumata@MorgenGrauen 3/99
+ *
+ */
+
+// Von diesem Objekt gibt es keine Clones, sondern nur die Blueprint.
+// Das Konstrukt if( clonep(ME) ) destruct(this_object()); ist dadurch
+// obsolet.
+#pragma no_clone
+
+#include <properties.h>
+#include <defines.h>
+
+// Ort, an dem die Daten gespeichert werden koennen. Die Endung .o
+// wird vom System angehaengt.
+#define SAVEFILE "/doc/beispiele/master/opferstocklog"
+
+// Dieses ist der Klient, der diesen Master benutzt. Dieser Wert wird
+// in diesem Programm zwar nicht benutzt, steht hier aber, damit man
+// weiss, wofuer dieser Master gut ist.
+#define CLIENT "/doc/beispiele/master/opferstock"
+
+// Es braucht kein Objekt inheritet werden, da wir keinerlei Spiel-
+// Funktionitaet brauchen. Der Master kann nicht genommen, bewegt oder
+// sonstwie innherlab des Muds benutzt werden. Insbesondere sollen
+// im savefile zum Master keine Properties oder so auftauchen.
+// inhert "/std/thing";
+
+// Um diese Daten geht es.
+// Das Mapping speichert zu jedem Spieler, wann das letzte Mal durch einen
+// der Klienten das Alignment geaendert wurde. Alte Daten werden bei
+// Gelegenheit geloescht.
+mapping data;
+
+void purge();
+
+void create() {
+
+  // Damit Schreibzugriff auf Savefile moeglich.
+  seteuid(getuid());
+
+  if( restore_object( SAVEFILE ) ) {
+    purge();
+  } else {
+    data = ([]);
+    save_object( SAVEFILE ); // Damit Savefile und Daten immer synchron sind.
+  }
+}
+
+// Diese Funktion testet einen einzelnen Eintrag, ob er veraltet ist.
+// (ist nicht Jahr 2038-fest :-)
+int notExpired( string name, int date ) {
+  return time() - date < 86400;
+}
+
+// Das Mapping untersuchen, ob Eintraege vorhanden sind, die nicht
+// mehr benoetigt werden.
+// (In diesem Fall sind das Eintraege, die aelter als einen Tag sind.)
+// Es reicht uns, diese Funktion einmal pro reboot auszufuehren. Bei
+// anderen Anwendungen koennte das natuerlich haeufiger noetig sein.
+void purge() {
+  data = filter_indices( data, #'notExpired );
+  save_object( SAVEFILE );
+}
+
+// Diese Funktion ist die eingetliche Funktion, die "gemastert" werden
+// soll, also für mehrere Opferstoecke gemeinsam benutzt wird.
+// Der Opferstock uebergibt das Spielerobjekt und die gewuenschte
+// Alignmentaenderung, als Ergebnis wird 1 geliefert, wenn eine Aenderung
+// vorgenommen wurde (0 sonst) und das Alignment des Spielers entsprechend
+// gesetzt.
+int addAlignment( object player, int align ) {
+  int newAlign;
+  string name;
+
+  /*
+  // Falls man verhindern will, dass nur der Klient auf die Daten zugreift,
+  // kann man hier noch Abfragen einbauen, typischerweise sieht das dann so
+  // aus:
+  if( object_name(previous_object())[0..xxx] != CLIENT ) return -1;
+  // oder
+  if( geteuid(previous_object()) != geteuid() ) return -1;
+  // etc. etc.
+  */
+
+  name = geteuid(player);
+
+  // Nur eine Aenderung pro Tag.
+  // Wir benutzen hier, dass data[name] == 0 ist, falls data den Namen nicht
+  // enthaelt!
+  if( notExpired( name, data[name] ) ) return 0;
+
+  // Daten setzen und speichern.
+  data[name] = time();
+  save_object( SAVEFILE );
+
+  // Maximale Aenderung: 200
+  if( align < -200 ) align = -200;
+  if( align > 200 ) align = 200;
+
+  newAlign = player->QueryProp( P_ALIGN ) + align;
+
+  // Kappung bei +-1000
+  if( newAlign < -1000 ) newAlign = -1000;
+  if( newAlign > 1000 ) newAlign = 1000;
+ 
+  player->SetProp( P_ALIGN, newAlign );
+  return 1;
+}
+
+// Schlussbemerkung:
+//
+// Gewitzte Programmierer koennten den Klient und den Master in einer
+// Datei zusammen ablegen. Die Blueprint wird als Master, die Clones werden
+// als Klienten benutzt. Ich habe das hier bewusst anders gemacht und empfehle
+// das auch als Vorbild, weil so der Code wesentlich besser zu verstehen ist.
diff --git a/doc/beispiele/misc/bspmon1.c b/doc/beispiele/misc/bspmon1.c
new file mode 100644
index 0000000..8ba85fc
--- /dev/null
+++ b/doc/beispiele/misc/bspmon1.c
@@ -0,0 +1,78 @@
+/*
+** Ein ganz normales Standard-monster ohne Besonderheiten
+** (von Boing)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+// den Standard-NPC der Mudlib erben.
+inherit "/std/npc";
+
+#include <properties.h>
+#include <language.h>
+
+protected void create()
+{
+  ::create();    /* Nicht vergessen, ohne das geht nichts */
+
+/* Die Kurzbeschreibung wird zum Beispiel angezeigt wenn man in einen Raum
+   mit dem Monster reinlaeuft */
+  SetProp(P_SHORT, "Beispielmonster");
+
+/* Beim Anschauen des Monsters wird die long-description angezeigt */
+  SetProp(P_LONG, "Ein Beispielmonster ohne Besonderheiten.\n");
+
+/* Ein Name muss sein, da sonst z.B. im Todesfall 'Leiche von 0' daliegt */
+  SetProp(P_NAME, "Monster");
+
+/* Das Geschlecht des Monsters. Als Geschlechter sind */
+/* die in <language.h> definierten Symbole NEUTER, MALE   */
+/* und FEMALE zulaessig.                                  */
+  SetProp(P_GENDER, NEUTER);
+
+/* Ein Monster braucht mindestens eine ID, unter der man es ansprechen kann */
+/* Es kann aber auch mehrere verschiedene ID's haben.                       */
+  AddId("monster");
+  AddId("beispielmonster");
+
+/* Zuerst sollte man dem Monster einen Grundlevel geben. */
+/* Die Spellpunkte und die Lebenpunkte sowie die Attribute werden dann */
+/* automatisch angepasst. */
+  create_default_npc( 10 );
+
+/* Nun machen wir es etwas widerstandsfaehiger, indem wir P_BODY setzen.  */
+/* Nie P_TOTAL_AC oder P_AC setzen, P_TOTAL_AC wird automatisch berechnet */
+/* und P_AC ist nur fuer Ruestungen da.                                   */
+  SetProp(P_BODY, 55);
+
+/* Das Monster schlaegt mit blossen Haenden zu, also wird P_HANDS gesetzt.   */
+/* Auch hier weder P_TOTAL_WC noch P_WC setzen.                              */
+  SetProp(P_HANDS, ({" mit seinen Haenden", 55}));
+/*                  ^ dieses Leerzeichen ist wichtig                         */
+/* Beim Kampf erscheint nun: 'Das Monster greift Dich mit seinen Haenden an' */
+/* 55 entspricht der Waffenklasse                                            */
+
+/* Gesinnung des Monsters, 0 ist neutral, negativ boese und positiv gut */
+  SetProp(P_ALIGN, 100);  /* Einigermassen nett, aber nichts besonderes */
+
+/* Die Rasse des Monsters */
+  SetProp(P_RACE, "Irgendnerasse");
+
+/* Erfahrungspunkte des Monsters, beim Tod erhaelt der 'Killer' ein   */
+/* hundertstel dieses Wertes. Schon im Kampf erhaelt man bei jedem    */
+/* Schlag weapon_class*schaden/10 punkte (weapon_class hier 55), also */
+/* insgesamt weapon_class*hit_points/10.                              */
+  SetProp(P_XP, 10000);
+
+/* Die Groesse des Monsters in cm. Dies wird bei einigen Kampfbefehlen */
+/* ausgewertet, sowie bei einigen Identifikationsspruechen von Gilden  */
+  SetProp(P_SIZE,180);
+
+/* Weitere Werte: P_(MAX)_FOOD, P_(MAX)_DRINK, P_(MAX)_ALCOHOL,       */
+/* P_MSGIN, P_MSGOUT, P_MMSGIN, P_MMSGOUT, P_MAX_HANDS, P_USED_HANDS  */
+
+}
diff --git a/doc/beispiele/misc/bspmon2.c b/doc/beispiele/misc/bspmon2.c
new file mode 100644
index 0000000..95f3909
--- /dev/null
+++ b/doc/beispiele/misc/bspmon2.c
@@ -0,0 +1,199 @@
+/*
+** Ein Beispielmonster mit div Extras (von Boing, aktualisiert von Wim+Zesstra)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/npc";
+
+#include <properties.h>
+#include <language.h>
+#include <combat.h>    // fuer die damage types
+#include <moving.h>    // fuer REJECT_KEEP   
+#include <class.h>     // fuer AddClass 
+#include <new_skills.h> // fuer SP_* bei AddSpell
+
+protected void create()
+{
+  ::create();       /* WICHTIG!!! */
+
+/* Standard-Knofiguration (Erlaeuterungen siehe bspmon1.c): */
+  SetProp(P_SHORT, "Ein Zauberer");
+  SetProp(P_LONG, "Dieser Zauberer zaubert wie wild und schwingt dabei "
+    "seinen langen Bart.\n");
+  SetProp(P_NAME, "Zauberer");
+  SetProp(P_GENDER, MALE);
+  AddId("zauberer");
+  create_default_npc(18);
+  SetProp(P_ALIGN, -700);   /* Brrr, ist der boese .... */
+  SetProp(P_BODY, 125);
+  SetProp(P_HANDS, ({" mit seinem langen Bart", 185}) );
+  SetProp(P_SIZE,180);
+  SetProp(P_MAX_HANDS, 2);  /* Anzahl der Haende (default ist 2) */
+  // set_living_name() setzt einen Namen, mit der der Zauberer z.B. mit einem
+  // 'finde' gefunden werden kann. Fuer die meisten NPC ist dies nicht noetig.
+  // Speziell sollte man keine generischen Bezeichnungen hier anmelden, wenn
+  // schon, dann individuelle Namen.
+  /* set_living_name("zauberer"); */
+
+/* Mit AddClass() und P_RACE wird festgelegt, in welche Gruppe von Lebe-  */
+/* wesen der NPC gehoert, welche mit is_class_member(mixed str) abgefragt */
+/* werden kann. Im Minimalfall ist der NPC von der Klasse, die bei P_RACE */
+/* eingetragen ist. Mit AddClass() koennen aber noch weitere Eigen-       */
+/* schaften hinzugefuegt werden.                                          */
+
+  SetProp(P_RACE,"Superduperzauberer");
+  AddClass( ({ CL_HUMAN, CL_MAMMAL }) );
+
+/* Mit P_RESISTANCE und P_VULNERABILITY werden fixe Werte (50%) fuer      */
+/* Resistenzen respektive Anfaelligkeiten gesetzt                         */
+/* Die Liste der moeglichen Schadensarten ist in /sys/combat.h definiert. */  
+/* z.B.  SetProp(P_RESISTANCE, ({ DT_MAGIC }));                           */
+/*       SetProp(P_VULNERABILITY, ({ DT_COLD }))                          */
+/*                                                                        */
+/* Mit P_RESISTANCE_STRENGTHS koennen Resistenzen und Anfaelligkeit       */
+/* konfiguriert werden. Diese Property enthaelt ein Mapping von           */
+/* von Schadensarten enthaelt. Negative Faktoren bis maximal -1.0         */ 
+/* (=Immunitaet) geben Resistenzen, positive Werte Anfaelligkeiten an.    */
+
+  SetProp(P_RESISTANCE_STRENGTHS, ([ DT_MAGIC: -0.5, DT_COLD: 2.0]) );					      
+
+/* Durch diesen Befehl wird eine Waffe geclont, sofern sie nicht im Raum  */
+/* herumliegt (in dem Fall wird sie vom NPC aufgehoben), und gezueckt     */ 
+/* (definiert in /std/npc/items.c resp. /sys/npc.h)                       */
+
+  AddItem("/doc/beispiele/misc/bspwaffe1", CLONE_WIELD);
+/* Und noch eine Ruestung clonen und anziehen.                            */  
+  AddItem("/doc/beispiele/misc/bspruest1", CLONE_WEAR);
+
+/* Jetzt wird gezaubert ....     */
+
+/* SetProp(P_SPELLRATE,) legt die Wahrscheinlichkeit fest, mit der ein   */
+/* Zauberspruch durchgefuehrt wird, hier 40%                            */
+  SetProp(P_SPELLRATE,40);
+
+/* Mit AddSpell() wird ein Zauberspruch hinzugefuegt. Das erste Argument  */
+/* ist so etwas wie die relative Wahrscheinlichkeit des Spruchs im        */
+/* Vergleich zu den anderen, hier beim ersten spruch 1 beim zweiten 2,    */
+/* das heisst in 20% der Faelle wird der erste Zauberspruch genommen und  */
+/* in 40% der zweite und in 60% der dritte.                               */
+/* Das zweite Argument ist der maximale Schaden, entsprechend der WC      */
+/* einer Waffe oder P_HANDS beim waffenlosen Kampf.                       */
+/* Die zwei weiteren Argumente sind die Meldungen die der angegriffene    */
+/* Spieler selbst und eventuelle Zuschauer erhalten. Hierbei stehen @WER, */
+/* @WEN, @WEM und @WESSEN fuer den Namen des Opfers im entsprechenden     */
+/* Fall.                                                                  */
+/* Das 5. Argument ist optional und gibt den Schadenstyp an, fehlt er     */
+/* wird DT_MAGIC angenommen.                                              */  
+/* Im 6. Arugument kann eine Funktion stehen, die bei dem Spruch ausge-   */
+/* fuehrt werden soll,                                                    */
+/* Das siebte uebergibt die Spell Parameter, hier ist wichtig, dass bei   */
+/* physikalischen Schaeden auch SP_PHYSICAL_ATTACK gesetzt wird, da sonst */
+/* einige Gilden den "Zauberspruch" abwehren koennen (siehe SpellDefend)  */
+
+  AddSpell(20,60, 
+	   "  Der Zauberer wirft einen Feuerball nach Dir.\n",
+	   "  Der Zauberer wirft einen Feuerball nach @WEM.\n",
+	   ({ DT_FIRE }) );
+  AddSpell(40,95,
+	   "  Der Zauberer beschwoert einen Sturm ueber deinem Kopf hervor.\n",
+	   "  Der Zauberer beschwoert einen Sturm ueber @WESSEN Kopf hervor.\n",
+	   ({ DT_AIR, DT_LIGHTNING }) );  
+  AddSpell(60,50,
+           "  Der Zauberer tritt Dich hinterlistig.\n",
+	   "  Der Zauberer tritt nach @WEM.\n",
+	   ({ DT_BLUDGEON }), 0,
+	   ([SP_SHOW_DAMAGE:1, SP_PHYSICAL_ATTACK:1]) );  	   
+
+
+/* Reden kann der Zauberer auch von alleine, hier kommen die chats:     */
+
+/* Das erste Argument ist die Wahrscheinlichkeit, mit der das Monster
+ * einen Spruch bringt (weniger ist mehr!). Das zweite Argument ist die Liste
+ * der Sprueche (oder Aktionen).
+ */
+
+  SetChats(2, ({
+  "Der Zauberer laeuft im Kreis herum.\n",
+  "Der Zauberer stolpert ueber seinen Bart.\n",
+  "Der Zauberer sagt: Heh Du! Was machst Du da?\n",
+  "Der Zauberer murmelt ein paar seltsame Worte in seinen Bart.\n",
+  "Der Zauberer bricht in unkontrolliertes Gelaechter aus.\n",
+  "Der Zauberer sagt: Hast mir mal ne Mark, ey?\n",
+  "Der Zauberer sagt: Wenn ich diesen Olpp erwische ...\n",
+  "Der Zauberer zaubert ein Kaninchen aus seinem Hut.\n"
+  }) );
+
+/* Das selbe fuer Sprueche die waehrend eines Kampfes kommen sollen    */
+
+  SetAttackChats(20, ({
+  "Der Zauberer macht: Buh!\n",
+  "Der Zauberer wirft mit weissen Maeusen nach Dir.\n",
+  "Der Zauberer sagt: Das war ein grosser Fehler!\n",
+  "Der Zauberer beisst Dich in den Arm.\n",
+  "Der Zauberer zaubert gruene Punkte auf deine Wange.\n",
+  "Der Zauberer verwandelt sich in eine Kroete.\n",
+  "Der Zauberer verschwindet und taucht hinter Dir wieder auf.\n"
+  }) );
+
+/* Wenn er stirbt soll eine besondere Meldung erscheinen. */
+  SetProp( P_DIE_MSG, " loest sich in Luft auf.\n" );
+/* Dann soll natuerlich auch kein Leichnam rumliegen */
+  SetProp( P_NOCORPSE, 1 );
+ 
+/* Nun wollen wir den Zauberer noch auf ein paar Fragen antworten lassen    */
+/* AddInfo(DEFAULT_INFO,) setzt die Antwort auf alle Fragen, wo der         */
+/* Schluessel nicht bekannt ist. Der Name des Zauberers wird immer vor den  */
+/* String gesetzt. (SetProp(P_DEFAULT_INFO, ist obsolet und sollte nicht    */
+/* mehr angewendet werden.)                                                 */ 
+
+  AddInfo(DEFAULT_INFO,"sagt: Keine Ahnung, von was Du redest.\n",0,
+                       "sagt zu @WEM: Keine Ahnung, von was Du redest.\n");
+
+/* Die bekannten Schluessel werden mit AddInfo dazugefuegt, das erste       */
+/* Argument ist das Wort (oder die Liste von Woertern), zu der der Zauberer */
+/* befragt werden kann, das zweite Argument ist die entsprechende Antwort.  */
+/* ist das dritte Argument gesetzt, so wird die Antwort automatisch umge-   */
+/* brochen und bekommt den Text des Arguments vor jede Zeile gestellt.      */
+/* Das vierte, ebenfalls optionale, Argument wird sofern gesetzt an die     */
+/* umstehenden Personen ausgegeben, dadurch laesst sich ein Fluestern oder  */
+/* eine spielerabhaengige Antwort realisieren.                              */
+
+  AddInfo("kaninchen",
+  "sagt: Die hol ich immer aus meinem Hut.\n");
+  AddInfo("zauberei",
+  "sagt: Ich bin ein Meister der Zauberei.\n");
+  AddInfo(({"maus", "maeuse"}),
+  "sagt: Maeuse sind meine Lieblingstiere.\n"); 
+  
+  AddInfo( ({"tier","tiere"}), 
+          "Oh, hauptsaechlich beschaeftige ich mich mit Kaninchen und Maeusen.",
+          "fluestert Dir zu: ",
+          "fluestert mit @WEM.\n");
+
+/* Normalerweile nehmen Monster alles was man ihnen gibt, ohne einen Ton */
+/* zu sagen. Will man dort ein anderes Verhalten, so tut man das so:     */
+/* Moeglich sind auch REJECT_GIVE (= zurueckgeben) REJECT_DROP (=fallen  */
+/* lassen. */
+  SetProp( P_REJECT, ({ REJECT_KEEP, "Der Zauberer sagt: Dankeschoen.\n" }) );
+
+/* Der Zauberer kann auch zusaetzliche Verben haben, die nur er selber
+ * benutzen kann, kein anderes Living. Diese koennen mit add_action() im
+ * create eines NPC angemeldet werden (und idR NUR in dieser Funktion und NUR
+ * in Lebewesen, nicht in sonstigen Objekten! */
+  add_action("nasebohren", "bohreinnase");
+
+/* Verben, die Spieler in Gegenwart des Zauberers koennen sollen, werden     */
+/* mit AddCmd angemeldet. */
+}
+
+int nasebohren( string str ) // str ist das, was hinter dem verb eingegeben wurde.
+{
+   say( "Der Zauberer bohrt mit dem Stab in seiner Nase.\n" );
+   return 1; // Verb war erfolgreich.
+}
+
diff --git a/doc/beispiele/misc/bspraum1.c b/doc/beispiele/misc/bspraum1.c
new file mode 100644
index 0000000..3483095
--- /dev/null
+++ b/doc/beispiele/misc/bspraum1.c
@@ -0,0 +1,78 @@
+/* /doc/beispiele/misc/bspraum1.c von Rumata */
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/room";
+
+#include <properties.h>
+#include <language.h>
+
+protected void create()
+{
+    ::create();
+
+    SetProp( P_INT_SHORT, "Ein kleines Schreibzimmer" );
+    SetProp( P_INT_LONG,
+        "Du stehst in einem kleinen Schreibzimmer.\n"
+         "Es gehoerte wohl irgendwann einmal einem Magier, aber nun\n"
+         "ist dieser Raum verwaist und rottet vor sich hin.\n"
+         "Ein grosser Schreibtisch in der Mitte des Raumes scheint\n"
+         "noch einigermassen gut erhalten zu sein. Durch die Tuer\n"
+         "im Norden faellt etwas Licht hinein.\n"
+    );
+    SetProp( P_LIGHT, 1 );
+    SetProp( P_INDOORS, 1 );
+
+    AddDetail( ({ "schreibtisch", "tisch" }),
+        "Auf dem Tisch liegt eine dicke Staubschicht.\n"
+        "Eine Schublade findest Du ebenfalls.\n"
+    );
+    AddDetail( ({ "staub", "staubschicht", "schicht" }),
+        "Du malst gelangweilt einige Kreise in den Staub.\n"
+    );
+    AddDetail( "schublade",
+        "So sehr Du Dich anstrengst; Du kannst sie nicht bewegen.\n"
+    );
+    AddDetail( "tuer" ,
+        "Sie steht seit Jahren offen und ist in dieser Lage\n"
+        "hoffnungslos festgerostet.\n"
+    );
+
+    AddCmd( ({ "schliesse", "oeffne", "bewege", "schliess", "beweg" }), 
+            "beweg_etwas" );
+    AddExit( "norden", "players/rumata/workroom" );
+}
+
+public int beweg_etwas( string str )
+{
+    notify_fail( "Was willst Du denn bewegen ?" );
+    if( str == "tuer" )
+    {
+        write( "Die Tuer ist hoffnungslos festgerostet.\n" );
+        return 1;
+    }
+    if ( str == "lade" || str == "schublade" )
+    {
+        write( "Die Schublade klemmt einfach nur.\n" );
+        return 1;
+    }
+    if ( query_verb() == "bewege" &&
+        ( str == "tisch" || str == "schreibtisch" ) )
+    {
+        tell_object(this_player(),
+            "Der Tisch scheint am Boden festgeschraubt zu sein.\n"
+        );
+        tell_room(this_object(),
+            this_player()->name(WER,2)+" zerrt am Schreibtisch.\n"
+        );
+        return 1;
+    }
+ // offenbar passte nix, Kommando nicht erfolgreich abgearbeitet. Ggf. weitere
+ // versuchen und/oder die notify_fail-Meldung ausgeben.
+    return 0;
+}
+
diff --git a/doc/beispiele/misc/bspruest1.c b/doc/beispiele/misc/bspruest1.c
new file mode 100644
index 0000000..10e3b0e
--- /dev/null
+++ b/doc/beispiele/misc/bspruest1.c
@@ -0,0 +1,38 @@
+/*
+** Eine Beispielruestung
+** (von Boing)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/armour";
+
+#include <properties.h>
+#include <combat.h>
+#include <language.h>
+
+protected void create()
+{
+  ::create();   /* WICHTIG!!! */
+
+/* Standardkonfiguration, genaueres siehe /doc/beispiele/bspwaffe1.c    */
+  SetProp(P_SHORT, "Ein grauer Umhang");
+  SetProp(P_LONG, "Es ist ein langer grauer Umhang aus einem feinen Material.\n");
+  SetProp(P_NAME, "Umhang");
+  SetProp(P_GENDER, MALE);
+  AddId("umhang");
+  SetProp(P_WEIGHT, 250);
+  SetProp(P_VALUE, 200);
+
+/* Zur Waffe fehlt nicht mehr viel, nur noch die Ruestungsklasse (AC)    */
+/* setzen und einen Ruestungstyp setzen. Die Typen sind in sys/combat.h  */
+/* definiert. Richtlinien zu Ruestungsklassen der verschiedenen Typen    */
+/* stehen momentan in /players/boing/waffen.                             */
+
+  SetProp(P_ARMOUR_TYPE, AT_CLOAK);
+  SetProp(P_AC, 8);
+}
diff --git a/doc/beispiele/misc/bsptransporter1.c b/doc/beispiele/misc/bsptransporter1.c
new file mode 100644
index 0000000..3e26020
--- /dev/null
+++ b/doc/beispiele/misc/bsptransporter1.c
@@ -0,0 +1,132 @@
+inherit "std/transport";
+
+/* wolke.c Ein Beispiel zur Programmierung eines Transporters */
+/* von Rumata (mit kleinen Bugfixes von Wargon ;) */
+
+#include <properties.h>
+#include <language.h>
+
+create()
+{
+  ::create();
+  SetProp( P_NAME, "Woelkchen" );
+  AddId( ({ "wolke", "woelkchen" }) );
+  SetProp( P_GENDER, NEUTER );
+  SetProp( P_INT_SHORT, "Auf einer kleinen Wolke" );
+  SetProp( P_INT_LONG,
+	  "Du sitzt auf einer kleinen Wolke, die zwischen Jofs und Rumatas\n"
+	  +	"Arbeitszimmer hin- und herpendelt. Wenn sie niedrig fliegt, kannst\n"
+	  +	"Du bestimmt von ihr heruntersteigen.\n"
+	  );
+  SetProp( P_SHORT, "Eine kleine Wolke" );
+  SetProp( P_LONG,
+	  "Diese suesse kleine Cumuluswolke schwebt zwischen Jofs und Rumatas\n"
+	  +	"Arbeitszimmer hin und her. Vielleicht kannst Du auf sie draufsteigen.\n"
+	  );
+  SetProp(P_LIGHT, 1 );
+  SetProp(P_TRANSPARENT,1);
+  // Man soll auf(in) die Wolke und von ihr herunter schauen koennen.
+    
+  /*** Meldungen, die Transporter geben koennen ***/
+  
+  SetProp( P_DEPARTMSG, ({
+    "Die Wolke steigt in die Luft.\n", 
+    "Die Wolke fliegt davon.\n"
+  }) );
+  // Die erste Meldung ist fuer Leute auf der Wolke.
+  // Die zweite fuer Leute in dem Raum, in dem die Wolke ankommt.
+      
+  SetProp( P_ARRIVEMSG, ({
+    "Die Wolke naehert sich dem Boden von @@QueryArrived@@.\n",
+    "Eine kleine Wolke schwebt herab.\n"
+  }) );
+  // Die erste Meldung ist fuer Leute auf der Wolke.
+  // Die zweite fuer Leute in dem Raum, aus dem die Wolke abreist.
+    
+  SetProp( P_ENTERMSG, ({
+    "steigt auf die Wolke",
+    "kommt auf die Wolke"
+  }) );
+  // Die erste Meldung ist fuer den Raum, aus dem der Spieler kommt.
+  // (=Raum). Die zweite Meldung ist fuer Spieler in dem Raum, in
+  // den der Spieler geht (=Transporter).
+	
+  SetProp( P_LEAVEMSG, ({
+    "steigt von der Wolke",
+    "steigt von der Wolke"
+  }) );
+  // Die erste Meldung ist fuer den Raum, aus dem der Spieler kommt.
+  // (=Transporter). Die zweite Meldung ist fuer Spieler in dem Raum,
+  // in den der Spieler geht (=Raum).
+      
+  SetProp( P_LEAVEFAIL, "Die Wolke schwebt viel zu hoch" );
+  // Meldung, die kommt, wenn ein Spieler den Transporter verlassen
+  // will, aber dieser an keinem Raum angelegt hat.
+  // Ist der Parameter ein String (so wie hier), so bekommt nur
+  // der betreffende Spieler die Meldung, wenn sie ein Array aus
+  // 2 Elementen ist, bekommt der Spieler die erste und alle
+  // anderen Spieler im Transporter die zweite (mit dem Namen
+  // des Spielers davor).
+  // Moeglich waere also auch:
+  /*
+     SetProp( P_LEAVEFAIL, ({
+     "Die Wolke schwebt viel zu hoch zum Herunterspringen",
+     "faellt fast von der Wolke"
+     }) );
+  */
+
+  SetProp( P_ENTERFAIL, "Es passen nur 5 Passagiere auf die Wolke.\n" );
+  // Diese Meldung bekommt der Spieler, wenn er versucht, einen
+  // vollen Transporter zu betreten. Hier ist nur eine Meldung
+  // (an den Spieler) vorgesehen.
+
+  SetProp( P_MAX_PASSENGERS, 5 );
+  // Maximale Anzahl der Spieler, die sich im Transporter befinden
+  // koennen. Fuer Gegenstaende gibt es keine Beschraenkung.
+
+  /* Verben */
+  AddCmd( ({ "steig", "steige", "spring", "springe" }), "steige" );
+
+  /* Kurs */
+  AddRoute( "players/rumata/workroom", 30, 20, "Rumatas Arbeitszimmer" );
+  // Hier wird der Raum /players/rumata/workroom als Anlegeplatz
+  // in den Kurs eingefuegt. Der Transporter verweilt 30sek in diesem
+  // Raum und faeht dann 20sek lang, bis er den naechten Punkt
+  // erreicht. Danach kann man noch den Code angeben, der bei
+  // QueryArrived zurueckgegeben wird, setzen. Wird kein Code
+  // gesetzt, wo wird dort ein Leerstring zurueckgegeben. 0 wird
+  // dann zurueckgegeben, wenn der Transporter an keinem Raum angelegt
+  // hat.
+
+  AddMsg( "Die Wolke treibt nun im Wind Richtung Jofs Arbeitszimmer.\n", 30 );
+  // Hier wird eine Meldung ausgegeben, und der Transporter reist 30sek lang
+  // weiter.
+
+  AddMsg( "Die Wolke beginnt zu sinken.\n", 10 );
+  AddRoute( "players/jof/workroom", 30, 20, "Jofs Arbeitszimmer" );
+  AddMsg( "Die Wolke treibt nun im Wind Richtung Rumatas Arbietszimmer.\n", 30 );
+  AddMsg( "Die Wolke beginnt zu sinken.\n", 10 );
+  // Nach dem Letzten Haltepunkt wird der Kurs wieder von vorn
+  // befahren.
+ 	
+  Start();
+  // Lasse den Transporter am ersten dieser Haltepunkte starten.
+}
+
+steige(str)
+{
+  string arg, arg2;
+  
+  if (sscanf( str, "auf %s", arg ) > 0 && id(old_explode(arg," ")[0]))
+    return Enter();
+  // Wenn sicher ist, dass der Spieler die Wolke BEsteigen will,
+  // kann man mit return Enter() alle weiteren Tests durchfuehren.
+
+  if (sscanf( str, "von %s", arg ) > 0 && id(old_explode(arg, " ")[0]))
+    return Leave();
+  // Das selbe gilt fuer das ABsteigen und Leave().
+  // Verben sollten nach Enter() oder Leave() keine weiteren Befehle
+  // enthalten.
+}
+
+
diff --git a/doc/beispiele/misc/bspwaffe1.c b/doc/beispiele/misc/bspwaffe1.c
new file mode 100644
index 0000000..259ae2a
--- /dev/null
+++ b/doc/beispiele/misc/bspwaffe1.c
@@ -0,0 +1,56 @@
+/*
+** Eine Beispielwaffe
+** (von Boing)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/weapon";
+
+#include <properties.h>     /* Definition der Properties */
+#include <combat.h>         /* Definition der kampfspezifischen Konstanten */
+#include <language.h>       /* Definition von MALE, FEMALE, WER, ... */
+
+protected void create()
+{
+  ::create();   /* WICHTIG!!! */
+
+/* Kurzbeschreibung fuer Darstellung in inventories */
+  SetProp(P_SHORT, "Ein Knueppel");
+
+/* Beschreibung des Knueppels */
+  SetProp(P_LONG, 
+  "Dieser Knueppel ist ziemlich normal, er ist aus festem Holz gefertigt und\n"+
+	  "man kann ihn als Waffe benutzen.\n");
+
+/* Name und Geschlecht sind wichtig, jedes Objekt braucht das */
+  SetProp(P_NAME, "Knueppel");
+  SetProp(P_GENDER, MALE);
+
+/* Jedes Objekt braucht eine oder mehrere Id's */
+  AddId("knueppel");
+
+/* Wert und Gewicht */
+  SetProp(P_VALUE, 300);
+  SetProp(P_WEIGHT, 1250);   /* in Gramm */
+
+/* Nun die wirklich Waffenspezifischen Dinge:                   */
+/* Waffen- und Schadensarten sind in /sys/combat.h definiert    */
+  SetProp(P_WEAPON_TYPE, WT_CLUB);
+  SetProp(P_DAM_TYPE, DT_BLUDGEON);
+
+/* Die Waffenklasse muss im Bereich zwischen 1 und 200 liegen   */
+  SetProp(P_WC, 125);
+  
+/* Anzahl der benoetigten Haende, um die Waffe zu zuecken.      */
+/* Waffen mit einer WC groesser 150, sollten auf jeden Fall     */
+/* Zweihaender sein, bei Sonderfaellen bitte an den Erzmagier   */
+/* fuer Waffen wenden. Wenn nichts gesetzt wird, ist die Waffe  */
+/* ein Zweihaender.                                             */
+  SetProp(P_NR_HANDS, 1);
+}
+
diff --git a/doc/beispiele/misc/krankheit.c b/doc/beispiele/misc/krankheit.c
new file mode 100644
index 0000000..c5816a3
--- /dev/null
+++ b/doc/beispiele/misc/krankheit.c
@@ -0,0 +1,66 @@
+/*  Paracelsus: Eine Krankheit
+**
+**      Beispiel fuer die Verwendung von P_X_ATTR_MOD und P_X_HEALTH_MOD
+**
+**      Diese Krankheit setzt alle Attribute herab und erniedrigt
+**      zusaetzlich P_MAX_HP und P_MAX_SP um jew. 20 (zusaetzlich zu den
+**      Auswirkungen der Attributsenkungen).
+**      Gestartet wird die Krankheit, indem sie einfach in das Opfer
+**      bewegt wird.
+**      Man beachte, dass im remove() die P_X_*-Properties ein leeres
+**      Mapping zugewiesen bekommen und keine 0. Nur so werden die
+**      Krankheitsfolgen rueckgaengig gemacht.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/thing";
+
+#include <properties.h>
+#include <moving.h>
+#include <language.h>
+#include <class.h>
+
+protected void create()
+{
+    ::create();
+
+    // ausnahmsweise darf dieses Objekt mal kein P_SHORT+P_LONG haben...
+    SetProp(P_SHORT,0);
+    SetProp(P_LONG, 0);
+    SetProp(P_INVIS, 1); // unsichtbar machen.
+    SetProp(P_NAME,"Krankheit");
+    SetProp(P_GENDER,FEMALE);
+    // wichtig, sonst wiegt die Krankheit 1kg (Standardgewicht fuer thing) 
+    SetProp(P_WEIGHT,0);
+    SetProp(P_VALUE,0);
+    SetProp(P_MATERIAL,MAT_MISC_MAGIC);
+    SetProp(P_NODROP,1); // Nicht wegwerfbar.
+
+// ----> Dieser Abschnitt sorgt fuer fiese Statabzuege
+
+    SetProp(P_X_HEALTH_MOD,
+    ([
+        P_HP : -20,   // Max. Lebenspunkte um 20 runter
+        P_SP : -20    // Max. Konzentrationspunkte um 20 runter
+    ]) );
+    SetProp(P_X_ATTR_MOD,
+    ([
+        A_CON : -1,   // Ausdauer um 1 runter, reduziert auch max. LP!
+        A_DEX : -1,   // Geschicklichkeit um 1 runter
+        A_INT : -2,   // Intelligenz um 2 runter, reduziert auch max. KP!
+        A_STR : -4,   // Staerke um 4 runter
+    ]) );
+
+// <----
+
+    AddId( ({"PARA\nSICK\nEXAMPLE"}) );
+
+    AddClass(CL_DISEASE); // Damit Kleriker helfen koennen.
+    SetProp(P_LEVEL,15);  // Aber nicht ganz so einfach zu entfernen
+}
+
diff --git a/doc/beispiele/misc/lebensring.c b/doc/beispiele/misc/lebensring.c
new file mode 100644
index 0000000..f82ea5e
--- /dev/null
+++ b/doc/beispiele/misc/lebensring.c
@@ -0,0 +1,56 @@
+/* Paracelsus: Lebensring
+**
+**    Ein Beispiel fuer die Anwendung von P_M_HEALTH_MOD
+**
+**    Zieht ein Spieler diesen Ring an, so erhoehen sich seine maximalen
+**    Lebenspunkte dabei um 10, waehrend seine max. Konzentrationspunkte
+**    um 5 erniedrigt werden.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/armour";
+
+#include <properties.h>
+#include <armour.h>
+#include <language.h>
+#include <combat.h>
+
+protected void create()
+{
+    ::create();
+
+    SetProp(P_SHORT,"Ein Lebensring");
+    SetProp(P_LONG,
+        "Ein kleiner Ring aus einem seltsamen, gruenen Material.\n");
+    SetProp(P_INFO,
+        "Dieser Ring unterstuetzt die Gesundheit.\n"+
+        "Dabei schwaecht er leider den Geist.\n");
+    SetProp(P_NAME,"Lebensring");
+    SetProp(P_GENDER,MALE);
+    SetProp(P_WEIGHT,80);
+    SetProp(P_VALUE,2000+random(501));
+    SetProp(P_ARMOUR_TYPE,AT_RING);
+    SetProp(P_AC,0); // keine Schutzwirkung im Kampf
+    SetProp(P_MATERIAL,MAT_MISC_MAGIC);
+
+// ---->
+
+    SetProp(P_M_HEALTH_MOD,
+    ([
+        P_HP : 10,      // Max. LP um 10 erhoehen
+        P_SP : -5       // Max. KP um 5 verringern
+    ]) );
+
+// <----
+
+    AddId( ({"ring","lebensring"}) );
+
+    AddDetail( "material",
+        "Es ist gruen.\n");
+}
+
diff --git a/doc/beispiele/misc/seherhaus.c b/doc/beispiele/misc/seherhaus.c
new file mode 100644
index 0000000..ea127e4
--- /dev/null
+++ b/doc/beispiele/misc/seherhaus.c
@@ -0,0 +1,136 @@
+/*
+Kurze Uebersicht der Termini:
+
+P_HAUS_ERLAUBT     Propertie, die das Bauen eines Hauses im Raum er-
+                   laubt oder verbietet. Default auf 0
+                   Syntax: xcall $h->SetProp(P_HAUS_ERLAUBT,x)
+                   
+Save()             Muss nach Aenderungen am Haus aufgerufen werden.
+                   Syntax: xcall /d/seher/haeuser/tillyhaus->Save()
+
+Okay, also ein Seher moechte, dass sein Haus 1) unsichtbar ist, 2) mit
+einem anderen Kommando betreten werden soll und 3) nicht auf die id 
+<haus> hoert sondern auf eine andere:
+
+Zu 1): Ganz einfach, man tippe 
+
+       'xcall /d/seher/haeuser/tillyhaus->SetProp(P_SHORT,0)' und
+       'xcall /d/seher/haeuser/tillyhaus->Save()'
+
+Zu 2) und 3): Das ist nicht so einfach, sondern muss ueber den Raum, in 
+              dem das Haus steht, gemacht werden. Deswegen folgend nun 
+              ein Beispiel zu Funktionen in so einem Raum.
+
+
+Folgende Dinge stehen natuerlich schon im Raum, sonst liesse er sich
+nicht laden :-)              
+*/
+
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/room";
+
+#include <properties.h>
+#include <language.h>
+#include <moving.h>
+
+/*
+   Fuer properties und sonstige Definitionen zum Seherhaus.
+*/
+#include "/d/seher/haeuser/haus.h"
+
+/*
+   Aus Gruenden der Uebersichtlichkeit ziehen viele Magier vor, den Hauskrams
+   in eine separate Funktion zusammenzufassen.
+*/
+private void haus_create();
+
+/*
+Es folgt nun das normale create() eines Raumes
+*/
+void create(){
+  ::create();
+  /* ... div. Konfiguration des Raum ... */
+
+  /*
+  Das extra-create() muss natuerlich aufgerufen werden
+  */  
+  haus_create();
+}      
+
+/*
+Hier kommen wir nun zu der Fkt, die alles am Seherhaus verwaltet
+*/
+private void haus_create()
+{
+  object ob = find_object(HAUSNAME("tilly")); // findet Haus von Tilly
+
+  /*
+  Wenn das Haus im Raum steht. Hat den Vorteil, dass bei einem Verlegen
+  des Hauses, Cmd's usw nicht mehr verfuegbar sind -> Keine evtl Bugs :)
+  */
+  if(objectp(ob))
+  {
+    /*
+    Der Spieler wollte es ja nicht anders
+    */
+    ob->RemoveCmd(({"betret","betritt","betrete"}));
+    ob->RemoveId("haus");
+    ob->RemoveId("haus von tilly");
+    ob->AddId("steinhaufen");
+    
+    AddDetail(({"haufen","steinhaufen"}),"Da ist doch ein kleiner Spalt? "
+     +"Vielleicht kannst Du auf den Steinhaufen klettern?\n");
+
+    AddCmd(({"kletter","klettere"}),"kletter_cmd");
+  }
+}
+
+public int kletter_cmd(string str)
+{
+  object ob = find_object(HAUSNAME("tilly"));
+
+  _notify_fail("Wo moechtest Du hinklettern?\n");
+
+  if(!str) return 0;
+
+  if(str=="auf haufen" || str=="auf steinhaufen")
+  {
+    if(objectp(ob))
+    {
+      /*
+      Das ist die Meldung, die ein Spieler bekommt, wenn das Seherhaus
+      abgeschlossen ist und er versucht, es zu 'betreten'.
+      */
+      notify_fail("Du kletterst auf den Haufen, doch der Spalt ist zu "
+       "schmal fuer Dich.\n");
+       
+      if(!(ob->QueryProp(H_DOORSTAT) & D_CLOSED))
+      {
+        tell_object(this_player(),
+            "Du kletterst auf den Steinhaufen, rutschst den Spalt runter "
+             "und findest Dich urploetzlich in einer schummrigen Hoehle.\n");
+        tell_room(this_object(),this_player()->name()+" klettert auf einen "
+          "Steinhaufen und ist ploetzlich verschwunden.",({this_player()}));
+        tell_room(RAUMNAME("tilly",0),this_player()->name()+
+          " faellt fluchend herein.\n");
+        this_player()->move(RAUMNAME("tilly",0),M_GO|M_SILENT,0);
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+  
+/*
+Natuerlich gibt es noch viel mehr Moeglichkeiten rund um Seherhaeuser, 
+doch sollte dies erstmal reichen. Zu beachten ist bei solcher Vorgehens-
+weise, dass ein 'schliesse|oeffne haus' evtl zu Fehlermeldungen fuehrt.
+Dem Spieler sei nahegelegt, es doch mit 'oeffne haustuer' zu versuchen.
+
+HAUSNAME und RAUMNAME (u.a.) sind Defines aus dem haus.h. Man sollte sich
+dieses File anschauen und die dortigen Defines uebernehmen. Dann bugt auch 
+nichts, falls mal etwas an den Haeusern umgestellt wird.
+
+Tilly, 20. Mai 2001, 00:10:24h
+*/
diff --git a/doc/beispiele/misc/statkrallen.c b/doc/beispiele/misc/statkrallen.c
new file mode 100644
index 0000000..a0ae4c3
--- /dev/null
+++ b/doc/beispiele/misc/statkrallen.c
@@ -0,0 +1,61 @@
+/* Paracelsus: Statkrallen
+**
+**     Beispiel fuer die Verwendung von P_M_ATTR_MOD
+**
+**     Zieht ein Spieler diese Krallen an, so erhoeht sich seine Staerke
+**     um 2. Gleichzeitig wird das Erhoehen seiner Geschicklichkeit durch
+**     andere Ruestungen/Waffen blockiert. 
+**     Die Krallen koennen nur angezogen werden, wenn weder A_STR noch
+**     A_DEX durch eine andere Ruestung/Waffe blockiert wird.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+#include <properties.h>
+#include <language.h>
+#include <combat.h>
+
+inherit "/std/armour";
+
+protected void create()
+{
+    ::create();
+
+    SetProp(P_SHORT,"Statkrallen");
+    SetProp(P_LONG,
+        "Diese krallenbewehrten Handschuhe schimmern blaeulich.\n");
+    SetProp(P_NAME,"Statkrallen");
+    SetProp(P_INFO,"Die Krallen machen staerker.\n");
+    SetProp(P_GENDER,FEMALE);
+    SetProp(P_NOBUY,1); // wird bei Verkauf im laden zerstoert.
+    SetProp(P_WEIGHT,800);
+    SetProp(P_VALUE,5000+random(2000));
+    SetProp(P_ARMOUR_TYPE,AT_GLOVE);
+    SetProp(P_AC,2);
+    SetProp(P_EFFECTIVE_WC,15);
+    SetProp(P_MATERIAL,
+    ([
+        MAT_LEATHER    : 60,
+        MAT_MISC_METAL : 40
+    ]) );
+
+// ---->
+
+    SetProp(P_M_ATTR_MOD,
+    ([
+        A_STR : 2,  // Staerke um 2 erhoehen
+        A_DEX : 0   // Geschicklichkeit blockieren
+    ]) );
+
+// <----
+
+    AddId( ({"handschuhe","krallen"}) );
+
+    AddDetail( "schimmer",
+        "Ein blaeulicher Schimmer liegt auf den Krallen.\n");
+}
+
diff --git a/doc/beispiele/precompiler/konstanten.c b/doc/beispiele/precompiler/konstanten.c
new file mode 100644
index 0000000..687d1a3
--- /dev/null
+++ b/doc/beispiele/precompiler/konstanten.c
@@ -0,0 +1,50 @@
+// Mit dem Praecompiler lassen sich symbolische Konstanten definieren. Dies
+// z.B. sinnvoll, wenn eine Zahl eine bestimmte Bedeutung hat. Z.b. hat die
+// Zahl 42 an sich keine fixe Bedeutung, hier ist die jedoch die Antwort!
+#define ANTWORT 42
+// Schreibt man nun irgendwo im Code ANTWORT, ersetzt der Praecompiler jedes
+// Vorkommen von ANTWORT durch 42.
+
+// auch komplexere Konstanten sind moeglich, z.B. ein Argument eines Defines:
+#define ROOM(x) ("/d/ebene/zesstra/advent/room/"+x)
+// Dies dient meist, um sich Schreibarbeit zu sparen. Formuliert man nach
+// diesem #define ein ROOM("weg1"), erzeugt der Praecompiler hieraus:
+// ("/d/ebene/zesstra/advent/room/weg1")
+
+// Weiteres Beispiel:
+#define BS(x) break_string(x, 78)
+// erzeugt also aus BS("langer text") ein break_string("langer text",78)
+
+// Es gehen auch mehrere Argumente:
+#define BS(x,y) break_string(x, 78, y)
+// BS("langer text", 78, "Zesstra sagt: ")
+//   -> break_string("langer text", 78, "Zesstra sagt: ")
+
+// Solche Defines lassen sich schachteln:
+#define HOME(x) ("/d/ebene/zesstra/advent/"+x)
+#define ROOM(x) (HOME("room/"+x))
+// Ein ROOM("weg1") wird nun durch (HOME("room/"+"weg1")) ersetzt
+// und dieses wiederum durch ein 
+// (("/d/ebene/zesstra/advent/"+"room/"+"weg1")), was letztendlich ein
+// (("/d/ebene/zesstra/advent/room/weg1")) ist.
+
+// Letzteres wird haeufig benutzt bei der Erstellung von Gebieten um sich bei
+// Umzuegen Arbeit zu sparen: zieht das Gebiet um (z.B. von /players/zesstra/
+// nach /d/ebene/zesstra/advent/, reicht es aus, HOME zu aendern und man muss
+// nicht 150mal den kompletten Pfad im Code aendern.
+
+// moechte man ein Define ueber mehrere Zeilen definieren, muss der
+// Zeilenumbruch mit einem \ escaped  werden:
+#define LOG(x) log_file("bla",\
+    "Dies ist ein laengerer Text.\n")
+// WICHTIG: Hinter dem \ darf KEIN Leerzeichen, Tab o.ae. stehen!
+
+// Tips:
+// * Damit man Defines schnell als solche erkennt, sollten alle Defines
+//   grossgeschrieben werden: z.B. PL vs. pl
+// * von komplexen Defines wird abgeraten, weil sie schnell Uebersicht 
+//   und Effizienz ruinieren koennen
+// * einige haeufig benutzte Defines finden sich in <defines.h>
+// * der Driver definiert bestimmte Defines automatisch. Eine Liste
+//   findet sich in /doc/driver/predefined
+
diff --git a/doc/beispiele/rotaugenvampire/.readme b/doc/beispiele/rotaugenvampire/.readme
new file mode 100644
index 0000000..a2ceeb6
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/.readme
@@ -0,0 +1,3 @@
+Drei Beispielmonster, die wichtige Basiseigenschaften von NPCs sowie
+die Vererbung demonstrieren. Angelehnt an bspmon1.c von Boing.
+(Zesstra)
diff --git a/doc/beispiele/rotaugenvampire/rotaugenvampir.c b/doc/beispiele/rotaugenvampire/rotaugenvampir.c
new file mode 100644
index 0000000..ca464d5
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/rotaugenvampir.c
@@ -0,0 +1,135 @@
+/*
+   Ein Beispiel-NPC (von Zesstra, angelehnt an Boings bspmon1.c)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+// Einige Warnungen werden als Fehler betrachtet (empfohlen)
+#pragma pedantic, range_check
+// Schaltet bestimmte Warnungen ein (empfohlen)
+#pragma warn_deprecated, warn_empty_casts, warn_missing_return
+#pragma warn_function_inconsistent
+
+// Erbt den Standard-NPC / das Standard-Monster
+inherit "/std/npc";
+
+// Inkludiert Definitionen fuer Properties und einige Konstanten
+#include <properties.h>
+#include <language.h>
+#include <class.h> // Konstanten fuer AddClass()
+
+// create() wird beim Erzeugen des Objekt vom Driver gerufen und initialisiert
+// diesen NPC. Es bekommt kein Argument, gibt keinen Wert zurueck (Typ: void)
+// und kann nicht von ausserhalb des Objektes gerufen werden (protected).
+protected void create()
+{
+  // Nicht vergessen, ohne das geht nichts. Fuehrt das create() des geerbten
+  // /std/npc aus und initialisiert den Standard-NPC.
+  ::create();
+
+/* Die Kurzbeschreibung wird zum Beispiel angezeigt wenn man in einen Raum
+   mit dem Monster reinlaeuft */
+  SetProp(P_SHORT, "Rotaugenvampir");
+
+/* Beim Anschauen des Monsters wird die long-description angezeigt,
+ * Zeilenumbruch nach Bedarf nach 78 Zeichen. */
+  SetProp(P_LONG, break_string(
+    "Ein finster aussehender Rotaugenvampir.",78));
+
+/* Ein Name muss sein, da sonst z.B. im Todesfall 'Leiche von 0' daliegt */
+  SetProp(P_NAME, "Rotaugenvampir");
+  SetProp(P_NAME_ADJ,"ausgemergelt");
+  
+/* Das Geschlecht des Monsters. Als Geschlechter sind */
+/* die in <language.h> definierten Symbole NEUTER, MALE   */
+/* und FEMALE zulaessig.                                  */
+  SetProp(P_GENDER, MALE);
+
+/* Ein Monster braucht mindestens eine ID, unter der man es ansprechen kann */
+/* Es kann aber auch mehrere verschiedene ID's haben.                       */
+  AddId( ({"vampir","rotaugenvampir"}) );
+
+/* Zuerst sollte man dem Monster einen Grundlevel geben. */
+/* Setzt Standardwerte fuer P_LEVEL, P_MAX_HP (Lebenspunkte), P_MAX_SP
+ * (Magiepunkte), P_HANDS, P_BODY, P_XP und die Attribute A_STR, A_INT, A_DEX
+ * und A_CON. Alle koennen spaeter noch geaendert werden.
+ */
+  create_default_npc( 25 );
+
+/* Nun machen wir es etwas widerstandsfaehiger, indem wir P_BODY setzen.  */
+/* Nie P_TOTAL_AC oder P_AC setzen, P_TOTAL_AC wird automatisch berechnet */
+/* und P_AC ist nur fuer Ruestungen da.                                   */
+  SetProp(P_BODY, 55);
+
+/* Das Monster schlaegt mit blossen Haenden zu, also wird P_HANDS gesetzt.   */
+/* Auch hier weder P_TOTAL_WC noch P_WC setzen.                              */
+  SetProp(P_HANDS, ({" mit seinen Haenden", 135}));
+/*                    ^ dieses Leerzeichen ist wichtig                       */
+/* Beim Kampf erscheint nun: 'Das Monster greift Dich mit seinen Haenden an' */
+/* 135 entspricht der Waffenklasse                                            */
+
+/* Gesinnung des Monsters, 0 ist neutral, negativ boese und positiv gut */
+  SetProp(P_ALIGN, -100);  /* etwas boese, aber nichts besonderes */
+
+/* Die Rasse des Monsters */
+  SetProp(P_RACE, "Vampir");
+
+/* Erfahrungspunkte des Monsters, beim Tod erhaelt der 'Killer' ein   */
+/* hundertstel dieses Wertes. Schon im Kampf erhaelt man bei jedem    */
+/* Schlag weapon_class*schaden/10 punkte (weapon_class hier 55), also */
+/* insgesamt weapon_class*hit_points/10.                              */
+/* Ab 200000 gibt der NPC einen Stufenpunkt, ab 600000 2 Stufenpunkte */
+  SetProp(P_XP, 130000);
+  
+/* Die Groesse des Monsters in cm. Dies wird bei einigen Kampfbefehlen */
+/* ausgewertet, sowie bei einigen Identifikationsspruechen von Gilden.
+ * Irgendwas zwischen 170 und 190 cm.  */
+  SetProp(P_SIZE, 170 + random(21));
+
+/* Ein Gewicht (in Gramm) sollte der NPC haben, irgendwas zwischen 40 und 48
+ * kg.
+ */
+  SetProp(P_WEIGHT, 40000 + random(8000));
+
+/* Weitere Werte: P_(MAX)_FOOD, P_(MAX)_DRINK, P_(MAX)_ALCOHOL,       */
+/* P_MSGIN, P_MSGOUT, P_MMSGIN, P_MMSGOUT, P_MAX_HANDS                */
+
+/* Spezielle Infos (fuer den Identifiziere-Spruch) */
+  SetProp(P_INFO, break_string(
+    "Der Rotaugenvampir laesst sich vielleicht mit Knoblauch vertreiben.",
+    78));
+
+/* NPC koennen einer Klasse angehoeren und Waffen koennten z.B. gegen
+ * bestimmte Klassen/Rassen besonders (in)effektiv sein.
+ */
+  AddClass(({CL_VAMPIRE,CL_UNDEAD}));
+
+/* Resistenzen (negativ) und Anfaelligkeiten (positiv) */
+  SetProp(P_RESISTANCE_STRENGTHS, ([
+        DT_BLUDGEON:0.2,DT_RIP:0.2,
+        DT_MAGIC: -0.2, DT_COLD: -0.1, DT_TERROR: -0.8 ]) );
+  
+// Wer hat den Spieler gekillt und was sagt man dann?
+  SetProp(P_KILL_NAME,"Ein Rotaugenvampir");
+  SetProp(P_KILL_MSG,({"Grossartig %s! Ein weiteres Opfer fuer Zesstra!", 
+                       MSG_SAY}));
+
+  // beschwerde auf -moerder
+  SetProp(P_MURDER_MSG,"Du steckst doch mit Jof im Bunde, %s!");
+  SetProp(P_DIE_MSG," bricht stoehnend zusammen.\n");
+
+  // Auch NPC sollten Details haben:
+  AddDetail( ({"augen","augenlider","lider"}), break_string(
+    "Der Rotaugenvampir schaut Dich mit weit aufgerissenen, rot "
+    "schimmernden Augen wild an.",78));
+  // ...
+
+  // riecht der nach was? -> AddSmells()
+  
+  // Kann man den nach was fragen? -> AddInfo().
+
+}
+
diff --git a/doc/beispiele/rotaugenvampire/rotaugenvampirmagier.c b/doc/beispiele/rotaugenvampire/rotaugenvampirmagier.c
new file mode 100644
index 0000000..a6c5aaf
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/rotaugenvampirmagier.c
@@ -0,0 +1,77 @@
+/*
+   Ein magisch begabter Beispiel-NPC (von Zesstra, angelehnt an Boings
+   bspmon1.c)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+// Einige Warnungen werden als Fehler betrachtet (empfohlen)
+#pragma pedantic, range_check
+// Schaltet bestimmte Warnungen ein (empfohlen)
+#pragma warn_deprecated, warn_empty_casts, warn_missing_return
+#pragma warn_function_inconsistent
+
+// Dieser NPC soll ein Rotaugenvampir sein, der ein paar Spells kann. Und nen
+// Rotaugenvampir gibt es schon. Also einfach den normalen Rotaugenvampir
+// aus diesem Verzeichnis erben.
+inherit __DIR__+"rotaugenvampir";
+
+// Inkludiert Definitionen fuer Properties
+#include <properties.h>
+
+protected void create()
+{
+  // Nicht vergessen, ohne das geht nichts. Fuehrt das create() des geerbten
+  // Rotaugenvampir aus und konfiguriert ihn.
+  ::create();
+
+/* Die Kurzbeschreibung wird zum Beispiel angezeigt wenn man in einen Raum
+   mit dem Monster reinlaeuft */
+  SetProp(P_SHORT, "Rotaugenvampirmagier");
+
+/* Beim Anschauen des Monsters wird die long-description angezeigt,
+ * Zeilenumbruch nach Bedarf nach 78 Zeichen. */
+  SetProp(P_LONG, break_string(
+    "Ein finster aussehender Rotaugenvampir in einer Kutte.",78));
+
+/* Ein Name muss sein, da sonst z.B. im Todesfall 'Leiche von 0' daliegt */
+  SetProp(P_NAME, "Rotaugenvampirmagier");
+  SetProp(P_NAME_ADJ,"listenreich");
+
+  // fast alle Eigenschaften uebernehmen wir einfach unveraendert unveraendert
+  // vom normalen Rotaugenvampir. Die Hands nicht, der Magier haut nicht so
+  // gut zu...
+  SetProp(P_HANDS, ({" mit seinen Haenden", 85}));
+
+  // ok, spielt wenig Rolle in diesem Fall, aber damits stilecht ist, kriegt
+  // der hier jetzt etwas mehr an Magiepunkten (spellpoints)
+  SetProp(P_MAX_SP, 350);
+
+  // und noch ein paar Spells
+  // Anmerkung: diese Spells haben nichts mit irgendwelchen Gildenspells zu
+  // tun und - ja, tatsaechlich - verbrauchen keine Magiepunkte...
+
+  // wahrscheinlichkeit in % pro runde, einen Spell zu casten:
+  SetProp(P_SPELLRATE,30);
+  // Ein Spell, der 100 Schadenspunkte macht und in 60% der Faelle ausgewaehlt
+  // wird. Erste Meldung geht an den Spieler, die zweite an den Raum.
+  // Schadenstyp ist Schlagschaden.
+  AddSpell(60,100,
+    break_string(Name(WER) + " macht eine Handbewegung vor Deinem Gesicht. "
+      "So abgelenkt stolperst Du in faellst hart zu Boden.",78),
+    break_string(Name(WER) + " macht eine Handbewegung vor @WESSEN Gesicht. "
+      "@WER stolpert und faellt hart auf den Boden.",78),
+    ({DT_BLUDGEON}) );
+  // Ein Spell, der 800 Schadenspunkte macht und in 40% der Faelle ausgewaehlt
+  // wird. Schadenstyp: Feuer.
+  AddSpell(40,800,
+    break_string(Name(WER) + " schaut Dich mit brennenden Augen "
+      "durchdringend an. Du glaubst, innerlich zu verbrennen.",78),
+    break_string(Name(WER) + " schaut @WEN mit gluehenden Augen an. "
+      "@WER kruemmt sich vor Schmerzen.",78),
+    ({DT_FIRE}) );
+}
+
diff --git a/doc/beispiele/rotaugenvampire/rotaugenvampirmagierin.c b/doc/beispiele/rotaugenvampire/rotaugenvampirmagierin.c
new file mode 100644
index 0000000..b506e1e
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/rotaugenvampirmagierin.c
@@ -0,0 +1,48 @@
+/*
+   Ein magisch begabter Beispiel-NPC (von Zesstra, angelehnt an Boings
+   bspmon1.c)
+   In diesem Fall soll eine Magierin sein, die aber die gleichen Stats wie der
+   maennliche Kollege hat.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+// Einige Warnungen werden als Fehler betrachtet (empfohlen)
+#pragma pedantic, range_check
+// Schaltet bestimmte Warnungen ein (empfohlen)
+#pragma warn_deprecated, warn_empty_casts, warn_missing_return
+#pragma warn_function_inconsistent
+
+// Dieser NPC soll eine Rotaugenvampirmagierin sein. Und nen
+// Rotaugenvampirmagier gibt es schon. Also einfach den normalen
+// Rotaugenvampirmagier aus diesem Verzeichnis erben.
+inherit __DIR__+"rotaugenvampirmagier";
+
+// Inkludiert Definitionen fuer Properties
+#include <properties.h>
+#include <language.h> // fuer FEMALE-Define
+
+protected void create()
+{
+  // Nicht vergessen, ohne das geht nichts. Fuehrt das create() des geerbten
+  // Rotaugenvampirmagiers aus und konfiguriert ihn.
+  ::create();
+
+  // Geschlecht aendern.
+  SetProp(P_GENDER, FEMALE);
+
+  // Kurz- und Langbeschreibung aendern.
+  SetProp(P_SHORT, "Rotaugenvampirmagierin");
+  SetProp(P_LONG, break_string(
+    "Eine finster aussehende Rotaugenvampirmagierin in einer Kutte.",78));
+
+  // Name anpassen
+  SetProp(P_NAME, "Rotaugenvampirmagierin");
+
+  // Meldung anpassen.
+  SetProp(P_HANDS, ({" mit ihren Haenden", 85}));
+}
+
diff --git a/doc/beispiele/shadow/aa.c b/doc/beispiele/shadow/aa.c
new file mode 100644
index 0000000..179d7e3
--- /dev/null
+++ b/doc/beispiele/shadow/aa.c
@@ -0,0 +1,8 @@
+     void fun() {
+         printf("%O [a] fun()\n", this_object());
+     }
+
+     void fun3() {
+         printf("%O [a] fun3()\n", this_object());
+     }
+
diff --git a/doc/beispiele/shadow/bb.c b/doc/beispiele/shadow/bb.c
new file mode 100644
index 0000000..9c77090
--- /dev/null
+++ b/doc/beispiele/shadow/bb.c
@@ -0,0 +1,13 @@
+     int fun() {
+         printf("%O [b] fun()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun();
+     }
+
+     void fun2() {
+         printf("%O [b] fun2()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun3();
+         this_object()->fun3();
+     }
+
+     void do_shadow(object target) { shadow(target, 1); }
+
diff --git a/doc/beispiele/shadow/cc.c b/doc/beispiele/shadow/cc.c
new file mode 100644
index 0000000..8aa60ed
--- /dev/null
+++ b/doc/beispiele/shadow/cc.c
@@ -0,0 +1,11 @@
+     int fun() {
+         printf("%O [c] fun()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun();
+     }
+
+     void fun3() {
+         printf("%O [c] fun3()\n", this_object());
+     }
+
+     void do_shadow(object target) { shadow(target, 1); }
+
diff --git a/doc/beispiele/shadow/loadme.c b/doc/beispiele/shadow/loadme.c
new file mode 100644
index 0000000..9d6e4d5
--- /dev/null
+++ b/doc/beispiele/shadow/loadme.c
@@ -0,0 +1,24 @@
+void create() {
+     object a, b, c;
+
+     if (find_object("/doc/beispiele/shadow/aa"))
+       destruct(find_object("/doc/beispiele/shadow/aa"));
+     a = load_object("/doc/beispiele/shadow/aa");
+     if (find_object("/doc/beispiele/shadow/bb"))
+       destruct(find_object("/doc/beispiele/shadow/bb"));
+     b = load_object("/doc/beispiele/shadow/bb");
+     if (find_object("/doc/beispiele/shadow/cc"))
+       destruct(find_object("/doc/beispiele/shadow/cc"));
+     c = load_object("/doc/beispiele/shadow/cc");
+
+     b->do_shadow(a);
+     c->do_shadow(a);
+     printf("--- a->fun() ---\n");
+     a->fun();
+     printf("--- b->fun() ---\n");
+     b->fun();
+     printf("--- c->fun() ---\n");
+     c->fun();
+     printf("--- b->fun2() ---\n");
+     b->fun2();
+}
diff --git a/doc/beispiele/ssp/README b/doc/beispiele/ssp/README
new file mode 100644
index 0000000..bd1cad1
--- /dev/null
+++ b/doc/beispiele/ssp/README
@@ -0,0 +1,3 @@
+Diese Dateien sind nur als Beispiele zu verwenden und nicht in einem
+anderen Mud als dem MorgenGrauen fuer Spieler zugaenglich zu machen.
+  Boing
diff --git a/doc/beispiele/ssp/files.h b/doc/beispiele/ssp/files.h
new file mode 100644
index 0000000..8c5951a
--- /dev/null
+++ b/doc/beispiele/ssp/files.h
@@ -0,0 +1,13 @@
+#define SM(x) ("/doc/beispiele/ssp/"+x)
+#define L1(x) (SM("l1/"+x))
+#define L2(x) (SM("l2/"+x))
+#define L3(x) (SM("l3/"+x))
+#define L4(x) (SM("l4/"+x))
+#define L5(x) (SM("l5/"+x))
+#define L6(x) (SM("l6/"+x))
+#define MON(x) (SM("mon/"+x))
+#define OBJ(x) (SM("obj/"+x))
+
+#define LOG_OBJ "/players/boing/obj/logobj"
+#define PFLANZE "/doc/beispiele/ssp/mon/pflanze"
+#define MMONST "/doc/beispiele/ssp/mon/metallmonster"
diff --git a/doc/beispiele/ssp/l1/m1x1.c b/doc/beispiele/ssp/l1/m1x1.c
new file mode 100644
index 0000000..f954372
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x1.c
@@ -0,0 +1,30 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der Raum ist gefuellt\n"+
+  "mit grau-blauem Rauch, der von dem grossen Drachen stammt, der ihn be-\n"+
+  "wohnt. Es ist sehr warm hier drin und an den Waenden und an der Decke\n"+
+  "kondensiert der Dampf zu kleinen Tropfen. Der einzige Ausgang liegt im\n"+
+  "Osten.\n");
+  AddDetail("raum", "Ein Drache wohnt hier normalerweise.\n");
+  AddDetail(({"drache", "drachen"}), "Er scheint gerade nicht da zu sein.\n");
+  AddDetail("rauch", "Der Rauch zieht zum Ausgang im Osten hinaus.\n");
+  AddDetail(({"wand", "waende", "boden", "decke", "metall", "stahl"}), "Alles hier ist aus reinem Stahl.\n");
+  AddDetail("dampf", "Er kondensiert an den Waenden.\n");
+  AddDetail(({"wasser", "kondenswasser"}), "Es tropft zu Boden.\n");
+  AddDetail("tropfen", "Sie tropfen auf den Boden.\n");
+  AddDetail("ausgang", "Er liegt im Osten.\n");
+  AddItem(MON("stahldrache"), REFRESH_REMOVE);
+  AddExit("osten",L1("m2x1"));
+}
diff --git a/doc/beispiele/ssp/l1/m1x2.c b/doc/beispiele/ssp/l1/m1x2.c
new file mode 100644
index 0000000..c91355a
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x2.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. In dieser gemuetlichen\n"+
+  "Ecke (natuerlich nur fuer Metall liebende Lebewesen) hat sich wohl eine\n"+
+  "der merkwuerdigen Titanwalzen eingenistet, auf jeden Fall ist der Boden\n"+
+  "dermassen plattgewalzt, wie es nur diese Art schaffen kann. Der Gang\n"+
+  "selbst fuehrt hier nach Sueden und Osten.\n");
+  AddDetail("ecke", "Richtig nett hier ...\n");
+  AddDetail(({"wand", "waende", "decke", "metall"}), "Alles hier ist aus Metall.\n");
+  AddDetail(({"walze", "titanwalze"}), "Die Titanwalze scheint gerade nicht daheim zu sein.\n");
+  AddDetail("boden", "Der Boden ist absolut platt.\n");
+  AddDetail("gang", "Ein aus Metall gearbeiteter Gang.\n");
+  AddExit("sueden",L1("m1x3"));
+  AddExit("osten",L1("m2x2"));
+  AddItem(MON("titanwalze"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m1x3.c b/doc/beispiele/ssp/l1/m1x3.c
new file mode 100644
index 0000000..6093029
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x3.c
@@ -0,0 +1,24 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Eine lange Metallroehre\n"+
+  "fuehrt weiter von Sueden nach Norden und scheint kein Ende zu nehmen. Deine\n"+
+  "Schritte hallen blechern durch die Gaenge und informieren deren Bewohner\n"+
+  "ueber Deine Anwesenheit.\n");
+  AddDetail(({"metallroehre", "roehre", "gang", "gaenge"}), "Du befindest Dich in einer langen Metallroehre.\n");
+  AddDetail("metall", "Das Metall sieht sehr stabil aus.\n");
+  AddDetail(({"boden", "decke", "wand", "waende"}), "Alles ist aus Metall.\n");
+  AddDetail("bewohner", "Hier scheinen keine zu sein.\n");
+  AddExit("norden",L1("m1x2"));
+  AddExit("sueden",L1("m1x4"));
+}
diff --git a/doc/beispiele/ssp/l1/m1x4.c b/doc/beispiele/ssp/l1/m1x4.c
new file mode 100644
index 0000000..a279aad
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x4.c
@@ -0,0 +1,24 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Die Metallroehre, in der\n"+
+  "Du Dich befindest fuehrt von Sueden nach Norden. Auch hier klingt der Boden\n"+
+  "unter Deinen Fuessen recht hohl, es ist wohl wirklich etwas Besonderes\n"+
+  "darunter. Allerdings sind keinerlei Anzeichen fuer einen Zugang zu sehen.\n");
+  AddDetail(({"gang", "roehre", "metallroehre"}), "Der Gang fuehrt nach Norden und Sueden.\n");
+  AddDetail("metall", "Hartes, glaenzendes Metall.\n");
+  AddDetail(({"wand", "waende", "boden", "decke"}), "Alles ist aus Metall.\n");
+  AddDetail("zugang", "Es ist keiner zu sehen.\n");
+  AddExit("norden",L1("m1x3"));
+  AddExit("sueden",L1("m1x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m1x5.c b/doc/beispiele/ssp/l1/m1x5.c
new file mode 100644
index 0000000..694fb6a
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x5.c
@@ -0,0 +1,31 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include <moving.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der voellig mit Metall\n"+
+  "verkleidete Gang macht hier eine Biegung von Osten nach Norden, wo er\n"+
+  "in die schwarze Dunkelheit fuehrt. Deine Schritte hallen hier leicht nach,\n"+
+  "es scheint sich wohl ein Hohlraum unter dem Boden zu befinden.\n");
+  AddDetail("metall", "Es scheint Eisen oder Stahl zu sein.\n");
+  AddDetail(({"eisen", "stahl"}), "Du weisst nicht genau, ob es Eisen oder Stahl ist.\n");
+  AddDetail(({"gang", "roehre"}), "Der Gang macht einen Knick.\n");
+  AddDetail("dunkelheit", "Sie verschlingt alles.\n");
+  AddDetail(({"wand", "waende", "boden", "decke"}), "Alles ist aus Metall.\n");
+  AddDetail("hohlraum", "Du kannst keine Hinweise auf einen Zugang finden.\n");
+  AddDetail("zugang", "Du siehst keinen.\n");
+  AddDetail(({"knick", "biegung"}), "So nennt sich sowas halt ... ich kann nix dafuer!\n");
+  AddItem(MON("kampfblech"), REFRESH_REMOVE);
+  
+  AddExit("norden", L1("m1x4"));
+  AddExit("osten",L1("m2x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x1.c b/doc/beispiele/ssp/l1/m2x1.c
new file mode 100644
index 0000000..d4e7ae7
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x1.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dieser Gang hier ist aus\n"+
+  "reinstem Stahl gefertigt, der in Deinem Licht matt funkelt. Aus einer\n"+
+  "Kammer im Westen dringen Rauchschwaden hervor und ein Schnauben ist zu\n"+
+  "hoeren. Du kannst es allerdings auch vorziehen, nach Sueden dem Unheil\n"+
+  "zu entgehen.\n");
+  AddDetail(({"gang", "gaenge", "roehre", "roehren"}), "Der Gang macht eine Biegung von Sueden nach Westen.\n");
+  AddDetail(({"boden", "decke", "wand", "waende", "metall", "stahl"}), "Alles hier ist aus hartem Stahl.\n");
+  AddDetail("kammer", "Im Westen liegt eine Kammer.\n");
+  AddDetail(({"rauchschwaden", "rauch", "schwaden"}), "Der Rauch zieht durch ein paar Ritzen in der Decke ab.\n");
+  AddDetail(({"ritze", "ritzen"}), "Die Ritzen haben nichts Bemerkenswertes an sich.\n");
+  AddDetail("schnauben", "Von wem wohl das Schnauben kommt?\n");
+  AddExit("westen",L1("m1x1"));
+  AddExit("sueden",L1("m2x2"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x2.c b/doc/beispiele/ssp/l1/m2x2.c
new file mode 100644
index 0000000..8cefccd
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x2.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Hier verzweigt sich der\n"+
+  "Gang in verschiedene Metallroehren, die nach Norden, Sueden und Westen\n"+
+  "fuehren. Ausserdem ist in der Decke ein kleines Loch, durch das eine\n"+
+  "Leiter nach oben fuehrt.\n");
+  AddDetail(({"gang", "gaenge", "metallroehre", "metallroehren", "roehre", "roehren"}), "Gaenge fuehren in die verschiedensten Richtungen.\n");
+  AddDetail(({"wand", "waende", "boden", "metall"}), "Hier ist einfach alles aus Metall.\n");
+  AddDetail("leiter", "Die Leiter fuehrt durch ein Loch in der Decke nach oben.\n");
+  AddDetail(({"loch", "decke"}), "In der Decke ist ein Loch.\n");
+  AddExit("sueden",L1("m2x3"));
+  AddExit("norden",L1("m2x1"));
+  AddExit("westen",L1("m1x2"));
+  AddExit("oben", L1("oben"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x3.c b/doc/beispiele/ssp/l1/m2x3.c
new file mode 100644
index 0000000..f291ac2
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x3.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der Gang, in dem Du\n"+
+  "Dich befindest fuehrt schnurgerade von Norden nach Sueden. Die Waende\n"+
+  "reflektieren das Licht und Deine Schritte erzeugen einen metallischen\n"+
+  "Klang auf dem Boden.\n"); 
+  AddDetail(({"boden", "wand", "waende", "decke", "metall"}), "Alles ist aus Metall.\n");
+  AddDetail("gang", "Er fuehrt nach Norden und Sueden.\n");
+  AddDetail("licht", "Es kommt irgendwoher.\n");
+  AddDetail("schritte", "Wenn Du laeufst, machst Du Schritte, das wusstest Du aber, oder?\n");
+  AddDetail("klang", "Der Klang ist nicht sonderlich interessant, aber zweifellos vorhanden.\n");
+  AddExit("norden",L1("m2x2"));
+  AddExit("sueden",L1("m2x4"));
+  AddItem(MON("dosenoeffner"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m2x4.c b/doc/beispiele/ssp/l1/m2x4.c
new file mode 100644
index 0000000..674b44e
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x4.c
@@ -0,0 +1,22 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der voellig mit Metall\n"+
+  "ausgeschlagene Gang macht hier einen scharfen Knick von Norden nach Osten\n"+
+  "und verschwindet dort in der Dunkelheit.\n");
+  AddDetail(({"wand", "waende", "boden", "decke", "metall"}), "Alles hier ist aus Metall.\n");
+  AddDetail("gang", "Der Gang fuehrt nach Norden und Osten.\n");
+  AddDetail("dunkelheit", "Du kannst hingehen und schauen, ob sie dann noch da ist.\n");
+  AddExit("norden",L1("m2x3"));
+  AddExit("osten",L1("m3x4"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x5.c b/doc/beispiele/ssp/l1/m2x5.c
new file mode 100644
index 0000000..95b0c3d
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x5.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <rooms.h>
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Die Waende des Ganges,\n"+
+  "der von Osten nach Westen (oder andersrum) verlaeuft, sind mit glaenzendem\n"+
+  "Metall ausgekleidet. Irgendwie kommt Dir diese Umgebung ziemlich seltsam\n"+
+  "vor, aber keine Sorge, es kommt noch viel schlimmer!\n");
+  AddDetail(({"gang", "roehre"}), "Der Gang verlaeuft von Osten nach Westen.\n");
+  AddDetail(({"wand", "waende", "decke", "boden"}), "Alles ist aus glaenzendem Metall.\n");
+  AddDetail("metall", "Das Metall ist an einer Stelle leicht eingedellt.\n");
+  AddDetail(({"delle", "stelle", "beule"}), "Da wollte wohl jemand mit dem Kopf durch die Wand.\n");
+  AddExit("osten",L1("m3x5"));
+  AddExit("westen",L1("m1x5"));
+  AddItem(MON("dosenoeffner"), REFRESH_REMOVE);
+  AddItem(MON("dosenoeffner"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m3x1.c b/doc/beispiele/ssp/l1/m3x1.c
new file mode 100644
index 0000000..30022f4
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x1.c
@@ -0,0 +1,31 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist am Eingang zum Hoehlenlabyrinth der Schreckensspitze. Etwas Licht\n"+
+  "dringt vom Ausgang im Norden herein, doch im Sueden lauert die pechschwarze\n"+
+  "Dunkelheit.\n");
+  AddDetail("eingang", "Es ist der Eingang zu mehr, als Du denkst.\n");
+  AddDetail("boden", "Der Boden besteht aus grauem Fels.\n");
+  AddDetail("fels", "Der Fels ist nicht besonders interessant, nur grau.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind von Orkblut beschmutzt.\n");
+  AddDetail(({"orkblut", "blut"}), "Orks werden hier wohl zum Spass gemetzelt.\n");
+  AddDetail("decke", "Ueber Deinem Kopf, das wird Dir hier noch oefters passieren.\n");
+  AddDetail(({"hoehlenlabyrinth", "labyrinth", "hoehlen"}), "Diese Labyrinth erstreckt sich ueber etliche Ebenen, viel Spass beim\nErkunden.\n");
+  AddDetail("licht", "Das letzte Tageslicht.\n");
+  AddDetail("ausgang", "Der Ausgang aus der Dunkelheit.\n");
+  AddDetail("dunkelheit", "Das wird Dir dort unten noch oefters begegnen.\n");
+  AddItem(MON("ork"), REFRESH_REMOVE);
+  AddItem(MON("ork"), REFRESH_REMOVE);
+  AddExit("norden", "/d/gebirge/room/spitze4");
+  AddExit("sueden",L1("m3x2"));
+}
diff --git a/doc/beispiele/ssp/l1/m3x2.c b/doc/beispiele/ssp/l1/m3x2.c
new file mode 100644
index 0000000..d913527
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x2.c
@@ -0,0 +1,29 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Ein schmaler Gang, der\n"+
+  "von Norden nach Sueden fuehrt, ist hier durch den harten Fels gehauen.\n"+
+  "Der Gang ist nur grob behauen, ein Zeichen dafuer, dass hier nicht Zwerge\n"+
+  "am Werk waren, sondern boese Wesen, wahrscheinlich Orks.\n");
+  AddDetail("fels", "Der Fels ist hart und nur grob behauen.\n");
+  AddDetail(({"gang", "gaenge"}), "Der Gang fuehrt von Norden nach Sueden.\n");
+  AddDetail("boden", "Auf dem Boden siehst Du zahlreiche Ueberreste von Abenteurern, die nicht\nvorsichtig genug waren.\n");
+  AddDetail(({"rest", "ueberrest", "reste", "ueberreste", "abenteurer"}),
+  "Uhoh ... blutige Sache ...\n");
+  AddDetail("blut", "Weia ...\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind aus Fels und nicht sonderlich interessant.\n");
+  AddDetail("decke", "Wenn Du ueberlegst, was da alles ueber Deinem Kopf schwebt ... ohoh!\n");
+  AddDetail(({"ork", "orks"}), "Davon hat es sicher einige in der Naehe.\n");
+  AddDetail(({"zwerg", "zwerge"}), "Zwerge haben hiermit nichts zu tun!\n");
+  AddExit("sueden",L1("m3x3"));
+  AddExit("norden",L1("m3x1"));
+}
diff --git a/doc/beispiele/ssp/l1/m3x3.c b/doc/beispiele/ssp/l1/m3x3.c
new file mode 100644
index 0000000..f84fce5
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x3.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der schmale Gang macht\n"+
+  "hier eine Biegung von Norden nach Osten, wo er jeweils in die Dunkelheit\n"+
+  "fuehrt.\n");
+  AddDetail("gang", "Der Gang macht eine Biegung.\n");
+  AddDetail("dunkelheit", "Schwarze Dunkelheit.\n");
+  AddDetail("boden", "Auf dem Boden ist nichts Besonderes zu sehen.\n");
+  AddDetail("decke", "Die Decke ist total langweilig.\n");
+  AddDetail(({"wand", "waende"}), "An der Wand haengt eine Hand.\n");
+  AddDetail("hand", "Ach nee, hat sich nur gereimt.\n");
+  AddDetail("biegung", "Sie fuehrt nach Norden und Osten.\n");
+  AddExit("norden",L1("m3x2"));
+  AddExit("osten",L1("m4x3"));
+  AddItem(MON("ork"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m3x4.c b/doc/beispiele/ssp/l1/m3x4.c
new file mode 100644
index 0000000..549492a
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x4.c
@@ -0,0 +1,39 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include <moving.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Metallbeschlagene Waende\n"+
+  "umringen Dich im Norden, Osten und Sueden waehrend ein roehrenartiger Gang\n"+
+  "nach Westen fuehrt. Ausserdem befindet sich im Boden ein Loch, durch das\n"+
+  "eine Leiter nach unten fuehrt.\n");
+  AddDetail("loch", "Was einen da unten wohl erwarten mag?\n");
+  AddDetail("leiter", "Die Leiter fuehrt nach unten.\n");
+  AddDetail("boden", "Im Boden ist ein Loch.\n");
+  AddDetail(({"wand", "waende", "decke", "metall"}), "Alles ist aus Metall.\n");
+  AddDetail(({"roehre", "gang"}), "Der Gang fuehrt nach Westen.\n");
+  AddItem(MON("titanwalze"), REFRESH_REMOVE);
+  AddExit("westen",L1("m2x4"));
+  AddSpecialExit("unten", "unten");
+}
+
+unten()
+{
+  if (present("titanwalze"))
+  {
+    write("Die Titanwalze laesst Dich nicht vorbei.\n");
+    return 1;
+  }
+  this_player()->move(L2("m3x4"), M_GO, "nach unten");
+  this_player()->SetProp("boing:drom_marker", 1);
+  return 1;
+}
diff --git a/doc/beispiele/ssp/l1/m3x5.c b/doc/beispiele/ssp/l1/m3x5.c
new file mode 100644
index 0000000..69c58fa
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x5.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der roehrenartige Gang\n"+
+  "fuehrt von Osten nach Westen durch die Dunkelheit, nur hier glaenzt das\n"+
+  "Metall in Deinem Licht.\n");
+  AddDetail(({"gang", "roehre"}), "Wer wohl diesen Gang angelegt hat?\n");
+  AddDetail("dunkelheit", "Du kannst sie nicht erreichen, solange Du Dein Licht an laesst.\n");
+  AddDetail("metall", "Alles hier ist aus blankem Metall.\n");
+  AddDetail("boden", "Ziemlich uninteressant.\n");
+  AddDetail(({"wand", "waende"}), "Hey! Da ist eine Inschrift!\n");
+  AddDetail("inschrift", "Das ist etwas, was man lesen kann.\n");
+  AddReadDetail("inschrift", "Du liest: Boing war hier.\n");
+  AddDetail("decke", "Ist sie nicht huebsch?\n");
+  AddExit("osten",L1("m4x5"));
+  AddExit("westen",L1("m2x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m4x1.c b/doc/beispiele/ssp/l1/m4x1.c
new file mode 100644
index 0000000..a64351e
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x1.c
@@ -0,0 +1,38 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Du hast die Hoehle eines\n"+
+  "schrecklichen Untiers erreicht. Der Gestank ist wirklich grauenerregend\n"+
+  "und der Anblick rumliegender Knochen und halb verwester Koerperteile von\n"+
+  "armen Opfern tut sein Uebriges, um Dir den Appetit zu verderben. Der\n"+
+  "einzige Ausgang aus diesem Loch befindet sich im Osten.\n");
+  AddDetail(({"hoehle", "loch"}), "Ein uebles Loch, in das Du hier geraten bist.\n");
+  AddDetail("gestank", "Dir wird beinahe schlecht.\n");
+  AddDetail(({"teile", "koerperteile"}), "Buah, das ist ja widerlich.\n");
+  AddDetail("ausgang", "Der Ausgang ist im Osten.\n");
+  AddSpecialDetail("knochen", "knochen");
+  AddDetail(({"wand", "waende"}), "Die Waende sind langweilig und grau.\n");
+  AddDetail("decke", "Die Decke ist uninteressant.\n");
+  AddDetail("boden", "Die verwesenden Koerperteile auf dem Boden sind kein schoener Anblick.\n");
+  AddExit("osten",L1("m5x1"));
+  AddItem(MON("trollmops"), REFRESH_REMOVE);
+}
+
+knochen()
+{
+   if (present("trollmops"))
+      return "Der Trollmops laesst nicht zu, dass Du sein Abendessen durchwuehlst.\n";
+
+   if (this_player()->FindPotion("Du wuehlst in den Knochen herum und findest einen Zaubertrank.\n"))
+      return "";
+   return "Du wuehlst in den Knochen herum, findest aber nichts.\n";
+}
diff --git a/doc/beispiele/ssp/l1/m4x2.c b/doc/beispiele/ssp/l1/m4x2.c
new file mode 100644
index 0000000..1456ef2
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x2.c
@@ -0,0 +1,41 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Das hier scheint wohl\n"+
+  "der Aufenthaltsraum von ein paar stinkenden Trollen zu sein. Eine Menge\n"+
+  "alter Knochen liegen auf dem Boden rum und in der Ecke stinkt ein grosser\n"+
+  "Haufen Trollkot vor sich hin. Alles in allem kein gemuetlicher Ort,\n"+
+  "vielleicht solltest Du ihn nach Sueden verlassen.\n");
+  AddDetail("knochen", "Die Knochen wurden von Trollen abgenagt.\n");
+  AddDetail("boden", "Auf dem Boden liegen Knochen.\n");
+  AddDetail("decke", "Die Decke hier ist nicht so grauenhaft interessant, ich wette es wird\ninteressanter, wenn Du ein paar Ebenen tiefer vordringst.\n");
+  AddDetail(({"ebene", "ebenen"}), "Tja, wenn Du wuesstest wieviele Hohlraeume sich unter Dir befinden, dann\nwuerdest Du hier nicht so ruhig stehen.\n");
+  AddDetail(({"hohlraum", "hohlraeume"}), "Erkunde sie! Sofort!\n");
+  AddDetail(({"wand", "waende"}), "Sie sind verschmiert und ekelhaft.\n");
+  AddDetail("troll", "Keiner da! Aetschbaetsch!\n");
+  AddDetail("ecke", "Wuerg!\n");
+  AddDetail(({"trollkot", "kot", "haufen"}), "Igitt! Das stinkt ja erbaermlich.\n");
+  AddExit("sueden",L1("m4x3"));
+  AddItem(MON("troll"), REFRESH_REMOVE);
+  AddItem(MON("troll"), REFRESH_REMOVE);
+  AddCmd("erkunde", "erkunden");
+}
+
+erkunden(str)
+{ 
+   notify_fail("Was moechtest Du erkunden?\n");
+   if (!str || (str!="hohlraum" && str !="hohlraeume"))
+      return 0;
+   write("Also ein bisschen mehr musst Du da schon fuer tun.\n");
+   return 1;
+}
diff --git a/doc/beispiele/ssp/l1/m4x3.c b/doc/beispiele/ssp/l1/m4x3.c
new file mode 100644
index 0000000..37472a9
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x3.c
@@ -0,0 +1,31 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der durch den harten\n"+
+  "Fels gehauene Gang verzweigt sich hier nach Norden, Osten und Westen.\n"+
+  "Du stellst fest, dass vom Norden her ein ziemlich unangenehmer Geruch\n"+
+  "kommt.\n");
+  AddDetail("fels", "Der Fels wurde von Orks oder Trollen bearbeitet, und das ziemlich schlecht.\n");
+  AddDetail(({"gang", "gaenge"}), "Der Gang verzweigt sich hier.\n");
+  AddDetail("geruch", "Man koennte es auch Gestank nennen.\n");
+  AddDetail("gestank", "Wenn der Himmel hier sichtbar waere, wuerde es zu ihm stinken.\n");
+  AddDetail("boden", "Auf dem Boden findest Du nichts von Bedeutung.\n");
+  AddDetail("decke", "Grauer Fels.\n");
+  AddDetail(({"wand", "waende"}), "An der Wand siehst Du eine Inschrift.\n");
+  AddDetail("inschrift", "Du kannst sie lesen.\n");
+  AddReadDetail("inschrift", "Du liest: Nicht alles, was man nicht sieht, ist auch wichtig.\n");
+  AddDetail(({"orks", "trolle"}), "Die laufen hier irgendwo rum ... oder liegen tot in der Ecke.\n");
+  AddDetail("ecke", "In dieser Ecke sind jedenfalls keine.\n");
+  AddExit("norden",L1("m4x2"));
+  AddExit("osten",L1("m5x3"));
+  AddExit("westen",L1("m3x3"));
+}
diff --git a/doc/beispiele/ssp/l1/m4x4.c b/doc/beispiele/ssp/l1/m4x4.c
new file mode 100644
index 0000000..be0485f
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x4.c
@@ -0,0 +1,28 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dies ist zweifellos die\n"+
+  "Heimat eines der beruechtigten Eisenfresser, die Waende sehen auch schon\n"+
+  "ganz zernagt aus. Der einzige Ausgang fuehrt nach Sueden.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind aus reinem Eisen und wurden von einem Eisenfresser schon\nziemlich stark misshandelt.\n");
+  AddDetail("boden", "Der Boden ist aus Metall und funkelt im Licht. Solltest Du natuerlich Nacht-\nsicht haben, dann funkelt es nur in Deiner Einbildung.\n");
+  AddDetail("decke", "Die Decke hat eine gewaltige Last zu tragen.\n");
+  AddDetail("last", "Frag mich nicht wieviele Tonnen Gestein sich ueber Dir befinden.\n");
+  AddDetail("gestein", "Sowas gibt es im Gebirge, wenn es auch hier nicht so offensichtlich ist.\n");
+  AddDetail("gebirge", "Ach hoer doch auf ...\n");
+  AddDetail("eisenfresser", "Der hat sich wohl zu Tode gefressen.\n");
+  AddDetail(({"metall", "eisen"}), "Es glaenzt matt.\n");
+  AddDetail("ausgang", "Er liegt im Sueden.\n");
+  AddItem(MON("eisenfresser"), REFRESH_REMOVE);
+  AddExit("sueden",L1("m4x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m4x5.c b/doc/beispiele/ssp/l1/m4x5.c
new file mode 100644
index 0000000..d64774b
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x5.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Die metallischen Roehren\n"+
+  "verzweigen sich hier nach Norden, Osten und Westen. Im Norden scheint etwas\n"+
+  "Unangenehmes zu lauern, merkwuerdige Geraeusche dringen von dort hierher.\n");
+  AddDetail(({"wand", "waende", "roehre", "roehren", "gaenge", "gang"}), "Die Gaenge sind voellig mit Metall ausgekleidet.\n");
+  AddDetail("metall", "Das Metall glaenzt silbern.\n");
+  AddDetail("unangenehmes", "Wer weiss, was sich dort verbirgt ...\n");
+  AddDetail("boden", "Du bist froh, dass es hier einen Boden gibt, sonst wuerdest Du tief fallen.\n");
+  AddDetail("decke", "Die Decke ist metallisch und glaenzt.\n");
+  AddDetail(({"geraeusch", "geraeusche"}), "Es quietscht.\n");
+  AddExit("norden",L1("m4x4"));
+  AddExit("osten",L1("m5x5"));
+  AddExit("westen",L1("m3x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x1.c b/doc/beispiele/ssp/l1/m5x1.c
new file mode 100644
index 0000000..5865a91
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x1.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der grob behauene Gang\n"+
+  "macht hier eine Biegung von Sueden nach Westen, wo er in einem schwarzen\n"+
+  "Loch verschwindet, aus dem ein fuerchterlicher Gestank dringt.\n"); 
+  AddDetail("gang", "Der Gang fuehrt in die Dunkelheit.\n");
+  AddDetail("dunkelheit", "Schwarze, lichtlose Dunkelheit.\n");
+  AddDetail("loch", "Hier lauert irgend etwas Schreckliches.\n");
+  AddDetail("gestank", "Der Gestank ist wirklich grauenhaft.\n");
+  AddDetail("boden", "Hoppla, hier liegen Fleischfetzen rum, im Westen scheint wohl was zu wueten.\n");
+  AddDetail(({"fleischfetzen", "fetzen", "fleisch"}), "Ist ja eklig!\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind verschmiert.\n");
+  AddDetail("decke", "Gaehn.\n");
+  AddExit("westen",L1("m4x1"));
+  AddExit("sueden",L1("m5x2"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x2.c b/doc/beispiele/ssp/l1/m5x2.c
new file mode 100644
index 0000000..75f6a5f
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x2.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Ein mit roher Gewalt in\n"+
+  "den Fels genagter Gang fuehrt von Sueden nach Norden. Du spuerst, dass\n"+
+  "hinter jeder Ecke Orks oder anderes uebles Gezuecht lauern koennen.\n");
+  AddDetail(({"gang", "gaenge"}), "Der Gang fuehrt von Sueden nach Norden.\n");
+  AddDetail("fels", "Es ist ein harter Fels, der von boesen Wesen durchbohrt wurde.\n");
+  AddDetail(({"ork", "orks", "gezuecht"}), "Momentan siehst Du keine Orks, aber das kann sich ja schnell aendern.\n");
+  AddDetail("boden", "Blanker Fels.\n");
+  AddDetail("fels", "Das wird allmaehlich langweilig.\n");
+  AddDetail("decke", "An der Decke haengt eine bunte Girlande.\n");
+  AddDetail("girlande", "Wer die wohl da aufgehaengt hat?\n");
+  AddDetail(({"wand", "waende"}), "Da gibt es nichts interessantes zu sehen.\n");
+  AddExit("norden",L1("m5x1"));
+  AddExit("sueden",L1("m5x3"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x3.c b/doc/beispiele/ssp/l1/m5x3.c
new file mode 100644
index 0000000..b7d4ce7
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x3.c
@@ -0,0 +1,32 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <moving.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dunkle Gaenge fuehren\n"+
+  "nach Norden, Sueden und Westen. Der suedliche Gang ist etwas merkwuerdig,\n"+
+  "denn sein Eingang ist mit glaenzendem Metall seltsam beschlagen.\n");
+  AddDetail(({"felsboden", "boden"}), "Der blanke Felsboden geht im Sueden in Metall ueber.\n");
+  AddDetail(({"gang", "gaenge"}), "Es sind Gaenge der Orks.\n");
+  AddDetail("eingang", "Im Sueden glaenzen die Waende, die mit Metall beschlagen sind.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind da ... wie immer.\n");
+  AddDetail("decke", "Die Decke ist nicht interessant.\n");
+  AddDetail("fels", "Grauer Fels.\n");
+  AddDetail("metall", "Es scheint Eisen zu sein.\n");
+  AddDetail("eisen", "Ja, zweifellos, es ist Eisen.\n");
+  AddExit("westen",L1("m4x3"));
+  AddExit("norden",L1("m5x2"));
+  AddExit("sueden",L1("m5x4"));
+
+  AddItem(MON("orkchef"), REFRESH_REMOVE);
+}
+
diff --git a/doc/beispiele/ssp/l1/m5x4.c b/doc/beispiele/ssp/l1/m5x4.c
new file mode 100644
index 0000000..b95d15e
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x4.c
@@ -0,0 +1,25 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der Gang, der hier von\n"+
+  "Norden nach Sueden fuehrt, aehnelt mehr einer Roehre, denn alles ist voll-\n"+
+  "staendig aus einem glaenzenden Metall. Du fragst Dich, wer wohl diese\n"+
+  "Gaenge angelegt hat.\n");
+  AddDetail(({"gang", "gaenge", "roehre", "rohr"}), "Die Gaenge sind voellig mit Metall ausgekleidet.\n");
+  AddDetail("metall", "Das Metall glaenzt silbern.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende glaenzen silbern.\n");
+  AddDetail("boden", "Sei froh, dass er da ist.\n");
+  AddDetail("decke", "Die Decke ist wirklich ziemlich langweilig.\n");
+  AddExit("norden",L1("m5x3"));
+  AddExit("sueden",L1("m5x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x5.c b/doc/beispiele/ssp/l1/m5x5.c
new file mode 100644
index 0000000..4f99ba1
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x5.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Eigentlich koennte man\n"+
+  "es auch fast Roehrenlabyrinth nennen, denn Du befindest Dich in einer\n"+
+  "solchen, die hier eine Biegung von Norden nach Westen macht. Die Waende\n"+
+  "sind aus einem glaenzenden Metall gefertigt, was Dir ziemlich merkwuerdig\n"+
+  "vorkommt.\n");
+  AddDetail(({"wand", "waende", "roehre", "roehren", "gaenge", "gang"}), "Die Gaenge sind voellig mit Metall ausgekleidet.\n");
+  AddDetail("metall", "Das Metall glaenzt silbern.\n");
+  AddDetail("boden", "Der Boden ist aus Metall.\n");
+  AddDetail("decke", "Selbst die Decke glaenzt metallisch, Du fragst Dich, wer das angelegt hat.\n");
+  AddDetail("biegung", "Die Biegung fuehrt von Norden nach Westen.\n");
+  AddItem(MON("kampfblech"), REFRESH_REMOVE);
+  AddExit("norden",L1("m5x4"));
+  AddExit("westen",L1("m4x5"));
+}
diff --git a/doc/beispiele/ssp/l1/oben.c b/doc/beispiele/ssp/l1/oben.c
new file mode 100644
index 0000000..f3bc039
--- /dev/null
+++ b/doc/beispiele/ssp/l1/oben.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+ 
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+ 
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Beim Knochenschaeler");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dieser kleine Raum ist\n"+
+  "die Heimat eines fuerchterlichen Ungeheuers, die Heimat des schrecklichen\n"+
+  "Knochenschaelers. Im Boden des Raums ist ein kleines Loch, durch das eine\n"+
+  "Leiter nach unten fuehrt.\n");
+  AddDetail("raum", "Der Raum ist ziemlich klein.\n");
+  AddDetail(({"wand", "decke", "waende", "metall"}), "Alles ist aus Metall.\n");
+  AddDetail(({"boden", "loch"}), "Im Boden ist ein Loch, durch das eine Leiter nach unten fuehrt.\n");
+  AddDetail("leiter", "Die Leiter fuehrt nach unten.\n");
+  AddDetail("ungeheuer", "Der Knochenschaeler ist einfach fuerchterlich.\n");
+  AddDetail("knochenschaeler", "Zum Glueck ist er gerade nicht daheim.\n");
+  AddItem(MON("knochenschaeler"), REFRESH_REMOVE);
+  AddExit("unten", L1("m2x2"));
+}
diff --git a/doc/beispiele/ssp/mon/dosenoeffner.c b/doc/beispiele/ssp/mon/dosenoeffner.c
new file mode 100644
index 0000000..46d627c
--- /dev/null
+++ b/doc/beispiele/ssp/mon/dosenoeffner.c
@@ -0,0 +1,24 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   AddId(({"dosenoeffner", "oeffner"}));
+   AddAdjective(({"mobiler", "mobilen"}));
+   SetProp(P_SHORT, "Ein mobiler Dosenoeffner");
+   SetProp(P_LONG, "Der Dosenoeffner moechte Dir sicherlich den Kopf mit seinen scharfen\nSchneideraedern oeffnen.\n");
+   SetProp(P_NAME, "Dosenoeffner");
+   SetProp(P_GENDER, 1);
+   SetProp(P_LEVEL, 12);
+   SetProp(P_MAX_HP, 120);
+   SetProp(P_ALIGN, -123);
+   SetProp(P_BODY, 80);
+   SetProp(P_HANDS, ({" mit scharfen Schneideraedern", 50}));
+   SetProp(P_XP, 30000);
+   SetProp(P_SIZE, random(20)+40);
+   set_living_name("dosenoeffner");
+}
diff --git a/doc/beispiele/ssp/mon/eisenfresser.c b/doc/beispiele/ssp/mon/eisenfresser.c
new file mode 100644
index 0000000..ba7b041
--- /dev/null
+++ b/doc/beispiele/ssp/mon/eisenfresser.c
@@ -0,0 +1,28 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   AddId(({"eisenfresser", "fresser"}));
+   SetProp(P_SHORT, "Ein Eisenfresser");
+   SetProp(P_LONG,
+   "Eisenfresser ernaehren sich ausschliesslich von Eisen, allerdings sind\n"+
+   "sie so kurzsichtig, dass sie erstmal in alles reinbeissen, was sie\n"+
+   "irgendwie wahrnehmen.\n");
+   SetProp(P_NAME, "Eisenfresser");
+   SetProp(P_GENDER, 1);
+   SetProp(P_LEVEL, 14);
+   SetProp(P_MAX_HP, 150);
+   SetProp(P_ALIGN, -215);
+   SetProp(P_BODY, 75);
+   SetProp(P_HANDS, ({" mit eisenbeschlagenen Zaehnen", 55}));
+   SetProp(P_XP, 42000);
+   SetProp(P_AGGRESSIVE, 1);
+   SetProp(P_SIZE, random(200)+50);   /* Naja, kurzsichtig halt... ;-) */
+   set_living_name("eisenfresser");
+   AddItem( OBJ("eisenklumpen") );
+}
diff --git a/doc/beispiele/ssp/mon/kampfblech.c b/doc/beispiele/ssp/mon/kampfblech.c
new file mode 100644
index 0000000..e218d01
--- /dev/null
+++ b/doc/beispiele/ssp/mon/kampfblech.c
@@ -0,0 +1,36 @@
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Kampfblech");
+   SetProp(P_LONG, 
+   "Das Kampfblech sieht irgendwie aus wie ein normales Backblech, nur\n"+
+   "viel gefaehrlicher!\n");
+   SetProp(P_NAME, "Kampfblech");
+   SetProp(P_GENDER, 0);
+   AddId(({"blech", "kampfblech","\nkampfblech"}));
+   SetProp(P_LEVEL, 8);
+   SetProp(P_MAX_HP, 100);
+   SetProp(P_ALIGN, -33);
+   SetProp(P_BODY, 70);
+   SetProp(P_HANDS, ({" mit eisenharten Schlaegen", 60}));
+   SetProp(P_XP, 30000);
+   SetProp(P_SIZE, 40);
+   SetProp(P_RACE, "Metallmonster");
+   SetProp(P_VULNERABILITY, ({ DT_WATER }));
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_DIE_MSG, " faellt laut scheppernd um.\n");
+   set_living_name("kampfblech");
+}
+
+die()
+{
+   clone_object(OBJ("kampfblech"))->move(environment());
+   ::die();
+}
diff --git a/doc/beispiele/ssp/mon/knochenschaeler.c b/doc/beispiele/ssp/mon/knochenschaeler.c
new file mode 100644
index 0000000..84c1e3b
--- /dev/null
+++ b/doc/beispiele/ssp/mon/knochenschaeler.c
@@ -0,0 +1,43 @@
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Der Knochenschaeler");
+   SetProp(P_LONG,
+   "Der Knochenschaeler geht um, geht um\n"+
+   "Der Knochenschaeler geht um, geht um\n"+
+   "Sein Messer so lang, wie tausend grosse Zaehne\n"+
+   "Wie tausend grosse Zaehne, sein Messer so lang\n"+
+   "Er schneidet Dich in Stuecke, portionsgerecht und fein\n"+
+   "Er schneidet Dich in Stuecke, und keiner tuts ihm gleich\n"+
+   "Er schaelt die Knochen, er quaelt Deinen Geist\n"+
+   "Er schaelt die Knochen, er quaelt Deinen Geist\n"+
+   "Habet acht, habet acht! Seiet vorsichtig, habet Acht!\n"+
+   "Schau Dich um, schau Dich um\n"+
+   "Schau Dich um, Du wirst der naechste sein\n");
+   SetProp(P_NAME, "Knochenschaeler");
+   SetProp(P_GENDER, 1);
+   AddId(({"schaeler", "knochenschaeler"}));
+   SetProp(P_LEVEL, 18);
+   SetProp(P_MAX_HP, 300);
+   SetProp(P_ALIGN, -789);
+   SetProp(P_HANDS, ({" mit seinem langen Messer", 145}) );
+   SetProp(P_BODY, 110);
+   SetProp(P_XP, 220000);
+   SetProp(P_AGGRESSIVE, 1);
+   SetProp(P_SIZE, 220);
+   set_living_name("knochenschaeler");
+   clone_object(OBJ("schaelmesser"))->move(this_object());
+   command("zuecke messer");
+}
+
+QueryArticle(c, d, f)
+{
+   return ::QueryArticle(c, 1, f);
+}
diff --git a/doc/beispiele/ssp/mon/metallmonster.c b/doc/beispiele/ssp/mon/metallmonster.c
new file mode 100644
index 0000000..5482186
--- /dev/null
+++ b/doc/beispiele/ssp/mon/metallmonster.c
@@ -0,0 +1,28 @@
+inherit "std/npc";
+
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_RACE, "Metallmonster");
+   SetProp(P_DIE_MSG, " zerfaellt in seine Bestandteile.\n");
+   SetProp(P_VULNERABILITY, ({ DT_WATER }));
+}
+
+die()
+{
+   create_blech();
+   ::die();
+}
+
+create_blech()
+{
+   object b;
+   b = clone_object(OBJ("blech"));
+   b->move(environment(this_object()));
+}
diff --git a/doc/beispiele/ssp/mon/ork.c b/doc/beispiele/ssp/mon/ork.c
new file mode 100644
index 0000000..975e596
--- /dev/null
+++ b/doc/beispiele/ssp/mon/ork.c
@@ -0,0 +1,26 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein grimmiger Ork");
+   SetProp(P_LONG, "Der Ork schaut Dich unfreundlich an und wedelt mit seinem Krummschwert.\n");
+   SetProp(P_NAME, "Ork");
+   SetProp(P_GENDER, 1);
+   AddId("ork");
+   SetProp(P_RACE, "Ork");
+   SetProp(P_LEVEL, 10);
+   SetProp(P_MAX_HP, 130);
+   SetProp(P_ALIGN, -250);
+   SetProp(P_XP, 90000);
+   SetProp(P_BODY, 50);
+   SetProp(P_SIZE, random(20)+110);
+   set_living_name("ork");
+   seteuid(getuid(this_object()));
+   AddItem(OBJ("krummschwert"),CLONE_WIELD);
+   AddItem(OBJ("orkhose"),CLONE_WEAR);
+}
diff --git a/doc/beispiele/ssp/mon/orkchef.c b/doc/beispiele/ssp/mon/orkchef.c
new file mode 100644
index 0000000..2d6e6cd
--- /dev/null
+++ b/doc/beispiele/ssp/mon/orkchef.c
@@ -0,0 +1,29 @@
+inherit "std/npc";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Anfuehrer der Orks");
+   SetProp(P_LONG, "Dies ist ein fetter, stinkender Ork-Haeuptling, der Dir alles \nandere als freundlich gesonnen ist.\n");
+   SetProp(P_NAME, "Ork");
+   SetProp(P_GENDER, 1);
+   AddId(({"ork", "anfuehrer", "haeuptling"}));
+   SetProp(P_RACE, "Ork");
+   SetProp(P_LEVEL, 16);
+   SetProp(P_MAX_HP, 220);
+   SetProp(P_ALIGN, -280);
+   SetProp(P_XP, 160000);
+   SetProp(P_BODY, 60);
+   SetProp(P_SIZE, random(20)+130);
+   set_living_name("orkchef");
+   seteuid(getuid(this_object()));
+   AddItem(OBJ("saebel"),CLONE_WIELD);
+   AddItem(OBJ("orkhose"),CLONE_WEAR);
+   AddItem(OBJ("orkhelm"),CLONE_WEAR);
+}
+
+      
diff --git a/doc/beispiele/ssp/mon/stahldrache.c b/doc/beispiele/ssp/mon/stahldrache.c
new file mode 100644
index 0000000..b4efcac
--- /dev/null
+++ b/doc/beispiele/ssp/mon/stahldrache.c
@@ -0,0 +1,39 @@
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Stahldrache");
+   SetProp(P_LONG,
+   "Der Stahldrache ist ein ernstzunehmender Gegner, gepanzert mit Platten\n"+
+   "aus reinem Stahl ist es schwer, ihm irgendwie Schaden zuzufuegen.\n");
+   SetProp(P_NAME, ({"Stahldrache", "Stahldrachen", "Stahldrachen", "Stahldrachen"}));
+   SetProp(P_GENDER, 1);
+   AddId(({"drache", "stahldrache", "drachen", "stahldrachen"}));
+   SetProp(P_RACE, "Drache");
+   SetProp(P_LEVEL, 20);
+   SetProp(P_MAX_HP, 400);
+   SetProp(P_ALIGN, -250);
+   SetProp(P_HANDS, ({" mit staehlernen Klauen", 150}));
+   SetProp(P_BODY, 130);
+   SetProp(P_XP, 300000);
+   SetProp(P_SIZE, random(50)+250);
+   SetChats(40, ({
+      "Der Stahldrache schnaubt laut.\n",
+      "Der Stahldrache schaut Dich mit staehlernem Blick an.\n",
+      "Der Stahldrache waelzt sich herum.\n",
+      "Der Stahldrache spuckt etwas stahlblaues Feuer.\n",
+   }) );
+   AddSpell(1, 115, "Der Stahldrache spuckt stahlblaues Feuer auf Dich.\n",
+  	            "Der Stahldrache spuckt stahlblaues Feuer auf @WEN.\n",
+	    DT_FIRE);
+   SetProp(P_SPELLRATE,20);
+   clone_object(OBJ("gummistiefel"))->move(this_object());
+   clone_object(OBJ("stahlschwert"))->move(this_object());
+   set_living_name("stahldrache");
+}
diff --git a/doc/beispiele/ssp/mon/titanwalze.c b/doc/beispiele/ssp/mon/titanwalze.c
new file mode 100644
index 0000000..23113e6
--- /dev/null
+++ b/doc/beispiele/ssp/mon/titanwalze.c
@@ -0,0 +1,30 @@
+#include <properties.h>                    
+#include <combat.h>
+#include "../files.h"
+
+inherit MMONST;
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Eine Titanwalze");
+   SetProp(P_LONG, "Pass nur auf, dass diese Titanwalze Dir nicht ueber die Zehen rollt.\nBei diesem Gewicht koennte das auesserst unangenehme Folgen haben.\n");
+   SetProp(P_NAME, "Titanwalze");
+   SetProp(P_GENDER, 2);
+   AddId(({"walze", "titanwalze"}));
+   SetProp(P_LEVEL, 14);
+   SetProp(P_MAX_HP, 170);
+   SetProp(P_ALIGN, 120);
+   SetProp(P_XP, 51000);
+   SetProp(P_BODY, 90);
+   SetProp(P_HANDS, ({" mit wuchtigen Schlaegen", 60}));
+   SetProp(P_SIZE, 210);
+   SetProp(P_DIE_MSG, " zerfaellt in ihre Bestandteile.\n");
+   SetAttackChats(30, ({
+   "Die Titanwalze versucht Dich platt zu walzen.\n",
+   "Die Titanwalze macht: Rumpel, polter ...\n",
+   "Die Titanwalze roehrt.\n"}));
+   set_living_name("titanwalze");
+   AddItem(OBJ("titanring")); 
+}
diff --git a/doc/beispiele/ssp/mon/troll.c b/doc/beispiele/ssp/mon/troll.c
new file mode 100644
index 0000000..8eb1043
--- /dev/null
+++ b/doc/beispiele/ssp/mon/troll.c
@@ -0,0 +1,28 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Troll");
+   SetProp(P_LONG, "Ein Troll wie aus dem Bilderbuch: Gross, haesslich und dumm.\n");
+   SetProp(P_NAME, "Troll");
+   SetProp(P_GENDER, 1);
+   SetProp(P_RACE, "Troll");
+   AddId("troll");
+   SetProp(P_LEVEL, 15);
+   SetProp(P_MAX_HP, 200);
+   SetProp(P_ALIGN, -417);
+   SetProp(P_XP, 120000);
+   SetProp(P_BODY, 35);
+   SetProp(P_SIZE, random(40)+199);
+   set_living_name("troll");
+   seteuid(getuid(this_object()));
+   AddItem(OBJ("trolldolch"),CLONE_WIELD);
+   AddItem(OBJ("steinring"),CLONE_WEAR);
+   AddItem(OBJ("lkhemd"),CLONE_WEAR);
+}
+      
diff --git a/doc/beispiele/ssp/mon/trollmops.c b/doc/beispiele/ssp/mon/trollmops.c
new file mode 100644
index 0000000..5830796
--- /dev/null
+++ b/doc/beispiele/ssp/mon/trollmops.c
@@ -0,0 +1,31 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Trollmops");
+   SetProp(P_LONG, 
+   "Dies ist einer der sagenumwobenen, blutruenstigen Trollmoepse. Hervor-\n"+
+   "gegangen aus der misslungenen Kreuzung zwischen einem Troll und einem\n"+
+   "Mops, terrorisieren diese grausamen Bestien jetzt die Welt. Flieh, so-\n"+
+   "lange Du noch kannst.\n");
+   SetProp(P_NAME, "Trollmops");
+   SetProp(P_GENDER, 1);
+   AddId("trollmops");
+   AddId("troll");
+   AddId("mops");
+   SetProp(P_RACE, "Troll");
+   SetProp(P_LEVEL, 20);
+   SetProp(P_MAX_HP, 350);
+   SetProp(P_ALIGN, -735 - random(100));
+   SetProp(P_HANDS, ({" mit blutverschmierten Krallen", 200 +random(10)}));
+   SetProp(P_XP, 350000);
+   SetProp(P_BODY, 140 + random(40));
+   SetProp(P_SIZE, random(20)+105);  /* Da sind die Groessen der Eltern drin */
+   set_living_name("trollmops");
+   SetProp(P_AGGRESSIVE, 1);
+}
diff --git a/doc/beispiele/ssp/obj/blech.c b/doc/beispiele/ssp/obj/blech.c
new file mode 100644
index 0000000..5c5c2ec
--- /dev/null
+++ b/doc/beispiele/ssp/obj/blech.c
@@ -0,0 +1,16 @@
+#include <properties.h>
+
+inherit "/std/thing";
+
+create() {
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein altes Blech");
+  SetProp(P_LONG, "Das sind die Ueberreste eines Metallmonsters.\n");
+  SetProp(P_NAME, "Blech");
+  SetProp(P_GENDER, 0);
+  AddId("blech");
+  AddAdjective(({"alt", "altes"}));
+  SetProp(P_WEIGHT, 1100);
+  SetProp(P_VALUE, random(QueryProp(P_MAX_HP))+100);
+}
diff --git a/doc/beispiele/ssp/obj/eisenklumpen.c b/doc/beispiele/ssp/obj/eisenklumpen.c
new file mode 100644
index 0000000..bac122b
--- /dev/null
+++ b/doc/beispiele/ssp/obj/eisenklumpen.c
@@ -0,0 +1,16 @@
+#include <properties.h>
+
+inherit "/std/thing";
+
+create() {
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Klumpen Eisen");
+  SetProp(P_LONG, "Sieht aus, als haette da schon jemand dran rumgenagt. Derjenige muss\naber sehr stabile Zaehne gehabt haben.\n");
+  SetProp(P_NAME, "Klumpen");
+  SetProp(P_GENDER, 1);
+  AddId(({"klumpen", "eisen", "klumpen eisen"}));
+  SetProp(P_MATERIAL, MAT_IRON);
+  SetProp(P_WEIGHT, 2438);
+  SetProp(P_VALUE, random(750));
+}
diff --git a/doc/beispiele/ssp/obj/gummistiefel.c b/doc/beispiele/ssp/obj/gummistiefel.c
new file mode 100644
index 0000000..ea4728e
--- /dev/null
+++ b/doc/beispiele/ssp/obj/gummistiefel.c
@@ -0,0 +1,37 @@
+#include <properties.h>
+#include <language.h>
+#include <combat.h>
+#include "../files.h"
+ 
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Paar Gummistiefel");
+   SetProp(P_LONG, "Damit bekommt man sicher keine nassen Fuesse.\n");
+   SetProp(P_NAME, "Paar Gummistiefel");
+   SetProp(P_GENDER, 0);
+   AddId(({"stiefel", "gummistiefel", "paar", "paar stiefel"}));
+   SetProp(P_ARMOUR_TYPE, AT_BOOT);
+   SetProp(P_AC, 0);
+   SetProp(P_WEIGHT, 700);
+   SetProp(P_VALUE, 120);
+   SetProp(P_REMOVE_FUNC, this_object());
+}
+
+RemoveFunc()
+{
+   object env;
+   if ((env=environment(QueryProp(P_WORN)))==find_object(L2("m2x1")) ||
+       env==find_object(L2("m1x1")))
+   {
+      write("Das waere keine so tolle Idee hier die Gummistiefel auszuziehen.\n");
+      return 0;
+   }
+   return 1;
+}
+       
+
+
diff --git a/doc/beispiele/ssp/obj/kampfblech.c b/doc/beispiele/ssp/obj/kampfblech.c
new file mode 100644
index 0000000..63c953a
--- /dev/null
+++ b/doc/beispiele/ssp/obj/kampfblech.c
@@ -0,0 +1,22 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein totes Kampfblech");
+  SetProp(P_LONG, "Sieht aus wie ein normales Kampfblech, nur tot. Ausserdem ueberrascht Dich der merkwuerdige Griff.\n");
+  SetProp(P_NAME, "Kampfblech");
+  SetProp(P_NAME_ADJ, "tot");
+  SetProp(P_GENDER, 0);
+  SetProp(P_ARMOUR_TYPE, AT_SHIELD);
+  SetProp(P_AC, 12);
+  SetProp(P_WEIGHT, 850);
+  SetProp(P_VALUE, 420);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  SetProp(P_INFO, "Ziemlicher Schwachsinn dieses Objekt, oder nicht?\n");
+  AddId(({"schild", "blech", "kampfblech", "totes kampfblech"}));
+  AddDetail("griff", "Mit Hilfe des Griffs kannst Du das tote Kampfblech als Schild benutzen.\n");
+}
diff --git a/doc/beispiele/ssp/obj/krummschwert.c b/doc/beispiele/ssp/obj/krummschwert.c
new file mode 100644
index 0000000..659ff02
--- /dev/null
+++ b/doc/beispiele/ssp/obj/krummschwert.c
@@ -0,0 +1,22 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/weapon";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Krummschwert");
+  SetProp(P_LONG, "Das Krummschwert sieht aus, als haette es einmal einem Ork gehoert.\n");
+  SetProp(P_NAME, "Krummschwert");
+  SetProp(P_GENDER, 0);
+  SetProp(P_WC, 130 + random(15));
+  SetProp(P_VALUE, 1200 + random(200));
+  SetProp(P_WEIGHT, 1100 + random(100));
+  SetProp(P_WEAPON_TYPE, WT_SWORD);
+  SetProp(P_DAM_TYPE, DT_SLASH);
+  SetProp(P_NR_HANDS, 1);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId("schwert");
+  AddId("krummschwert");
+}
diff --git a/doc/beispiele/ssp/obj/lkhemd.c b/doc/beispiele/ssp/obj/lkhemd.c
new file mode 100644
index 0000000..5c381bc
--- /dev/null
+++ b/doc/beispiele/ssp/obj/lkhemd.c
@@ -0,0 +1,19 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein leichtes Kettenhemd");
+  SetProp(P_LONG, "Ein nicht sonderlich gut gearbeitetes Kettenhemd. Anziehen kann man\nes aber trotzdem.\n");
+  SetProp(P_NAME, "Kettenhemd");
+  SetProp(P_GENDER, 0);
+  SetProp(P_ARMOUR_TYPE, AT_ARMOUR);
+  SetProp(P_AC, 18);
+  SetProp(P_WEIGHT, 1700);
+  SetProp(P_VALUE, 1200 +random(100));
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId(({"kettenhemd", "hemd"}));
+}
diff --git a/doc/beispiele/ssp/obj/orkhelm.c b/doc/beispiele/ssp/obj/orkhelm.c
new file mode 100644
index 0000000..36d6a8b
--- /dev/null
+++ b/doc/beispiele/ssp/obj/orkhelm.c
@@ -0,0 +1,20 @@
+inherit "std/armour";
+ 
+#include <properties.h>                    
+#include <combat.h>
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Orkhelm");
+  SetProp(P_LONG, "Ein stabiler Helm, der schon ausgiebig von einem stinkenden Ork\ngetragen wurde.\n");
+  SetProp(P_NAME, "Orkhelm");
+  SetProp(P_GENDER, 1);
+  SetProp(P_ARMOUR_TYPE, AT_HELMET);
+  SetProp(P_AC, 7);
+  SetProp(P_WEIGHT, 450);
+  SetProp(P_VALUE, 350);
+  SetProp(P_MATERIAL, ([MAT_MISC_METAL:95, MAT_SLIME:5]));
+  AddId(({"helm", "orkhelm"}));
+}
diff --git a/doc/beispiele/ssp/obj/orkhose.c b/doc/beispiele/ssp/obj/orkhose.c
new file mode 100644
index 0000000..8ba0056
--- /dev/null
+++ b/doc/beispiele/ssp/obj/orkhose.c
@@ -0,0 +1,19 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Eine Orkhose");
+  SetProp(P_LONG, "Die Beinbekleidung von Orks.\n");
+  SetProp(P_NAME, "Hose");
+  SetProp(P_GENDER, 2);
+  SetProp(P_ARMOUR_TYPE, AT_TROUSERS);
+  SetProp(P_AC, 7);
+  SetProp(P_WEIGHT, 555);
+  SetProp(P_VALUE, 480 + random(40));
+  SetProp(P_MATERIAL, ([MAT_CLOTH:99, MAT_SHIT:1]));
+  AddId(({"hose", "hosen", "orkhose", "orkhosen"}));
+}
diff --git a/doc/beispiele/ssp/obj/saebel.c b/doc/beispiele/ssp/obj/saebel.c
new file mode 100644
index 0000000..3aec958
--- /dev/null
+++ b/doc/beispiele/ssp/obj/saebel.c
@@ -0,0 +1,23 @@
+inherit "std/weapon";
+
+#include <properties.h>                    
+#include <combat.h>
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein schartiger Saebel");
+  SetProp(P_LONG, "Der Saebel ist schartig, koennte aber trotzdem recht brauchbar sein.\n");
+  SetProp(P_NAME, "Saebel"); 
+  SetProp(P_GENDER, 1);
+  SetProp(P_WC, 144);
+  SetProp(P_VALUE, 1525);
+  SetProp(P_WEIGHT, 1264);
+  SetProp(P_WEAPON_TYPE, WT_SWORD);
+  SetProp(P_DAM_TYPE, DT_SLASH);
+  SetProp(P_NR_HANDS, 1);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId("saebel");
+  AddAdjective(({"schartig", "schartiger", "schartigen"}));
+}
diff --git a/doc/beispiele/ssp/obj/schaelmesser.c b/doc/beispiele/ssp/obj/schaelmesser.c
new file mode 100644
index 0000000..2b0b686
--- /dev/null
+++ b/doc/beispiele/ssp/obj/schaelmesser.c
@@ -0,0 +1,25 @@
+inherit "std/weapon";
+
+#include <combat.h>
+#include <properties.h>
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Knochenschaelmesser");
+   SetProp(P_LONG, 
+	   "Ein Messer so lang, wie tausend grosse Zaehne\n"+
+	   "Wie tausend grosse Zaehne, ein Messer so lang\n"+
+	   "So lang, wie tausend grosse, grosse Zaehne\n");
+   SetProp(P_NAME, "Knochenschaelmesser");
+   SetProp(P_GENDER, 0);
+   AddId(({"knochenschaelmesser", "schaelmesser", "messer"}));
+   SetProp(P_WC, 145);
+   SetProp(P_NR_HANDS, 1),
+   SetProp(P_WEAPON_TYPE, WT_KNIFE);
+   SetProp(P_DAM_TYPE, DT_SLASH);
+   SetProp(P_VALUE, 1610);
+   SetProp(P_WEIGHT, 1150);
+   SetProp(P_MATERIAL, MAT_MISC_METAL);
+}
diff --git a/doc/beispiele/ssp/obj/stahlschwert.c b/doc/beispiele/ssp/obj/stahlschwert.c
new file mode 100644
index 0000000..4446898
--- /dev/null
+++ b/doc/beispiele/ssp/obj/stahlschwert.c
@@ -0,0 +1,21 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/weapon";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Stahlschwert");
+  SetProp(P_LONG, "Dieses Schwert hat eine Klinge aus reinem Stahl, mit der man seine Gegner\nwohl ziemlich gut niedermachen kann. Das Schwert ist recht schwer und\nlaesst sich nur mit zwei Haenden fuehren.\n");
+  SetProp(P_NAME, "Stahlschwert");
+  SetProp(P_GENDER, 0);
+  SetProp(P_WC, 175);
+  SetProp(P_VALUE, 1750 + random(100));
+  SetProp(P_WEIGHT, 2926);
+  SetProp(P_WEAPON_TYPE, WT_SWORD);
+  SetProp(P_DAM_TYPE, DT_SLASH);
+  SetProp(P_NR_HANDS, 2);
+  SetProp(P_MATERIAL, MAT_STEEL);
+  AddId(({"schwert", "stahlschwert", "\nsspstahlschwert"}));
+}
diff --git a/doc/beispiele/ssp/obj/steinring.c b/doc/beispiele/ssp/obj/steinring.c
new file mode 100644
index 0000000..5da09a7
--- /dev/null
+++ b/doc/beispiele/ssp/obj/steinring.c
@@ -0,0 +1,19 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Steinring");
+  SetProp(P_LONG, "Ein kleiner Ring, voellig aus einem grauen Stein.\n");
+  SetProp(P_NAME, "Steinring");
+  SetProp(P_GENDER, 1);
+  SetProp(P_ARMOUR_TYPE, AT_RING);
+  SetProp(P_AC, 2);
+  SetProp(P_WEIGHT, 270);
+  SetProp(P_VALUE, 300 +random(150));
+  SetProp(P_MATERIAL, MAT_MISC_STONE);
+  AddId(({"ring", "steinring"}));
+}
diff --git a/doc/beispiele/ssp/obj/titanring.c b/doc/beispiele/ssp/obj/titanring.c
new file mode 100644
index 0000000..389de66
--- /dev/null
+++ b/doc/beispiele/ssp/obj/titanring.c
@@ -0,0 +1,18 @@
+inherit "std/armour";
+
+#include <properties.h>
+#include <combat.h>
+
+create()
+{
+  ::create();
+  SetProp(P_SHORT, "Ein Titanring");
+  SetProp(P_LONG, "Ein Ring aus Titan.\n");
+  SetProp(P_NAME, "Titanring");
+  SetProp(P_GENDER, 1);
+  AddId(({"titanring", "ring"}));
+  SetProp(P_ARMOUR_TYPE, AT_RING);
+  SetProp(P_AC, 2);
+  SetProp(P_WEIGHT, 280);
+  SetProp(P_VALUE, 520);
+}
diff --git a/doc/beispiele/ssp/obj/trolldolch.c b/doc/beispiele/ssp/obj/trolldolch.c
new file mode 100644
index 0000000..fd06092
--- /dev/null
+++ b/doc/beispiele/ssp/obj/trolldolch.c
@@ -0,0 +1,21 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/weapon";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Trolldolch");
+  SetProp(P_LONG, "Ein langer, scharfer Dolch, dem Gestank nach muss er einem Troll\ngehoert haben.\n");
+  SetProp(P_NAME, "Trolldolch");
+  SetProp(P_GENDER, 1);
+  SetProp(P_WC, 119);
+  SetProp(P_VALUE, 1000 +random(400));
+  SetProp(P_WEIGHT, 500 +random(50));
+  SetProp(P_WEAPON_TYPE, WT_KNIFE);
+  SetProp(P_DAM_TYPE, DT_PIERCE);
+  SetProp(P_NR_HANDS, 1);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId(({"dolch", "trolldolch"}));
+}
diff --git a/doc/beispiele/testobjekte/.readme b/doc/beispiele/testobjekte/.readme
new file mode 100644
index 0000000..56ff41f
--- /dev/null
+++ b/doc/beispiele/testobjekte/.readme
@@ -0,0 +1,13 @@
+
+Hier liegen Test-Objekte zu man-pages. Unterschieden wird momentan nur nach:
+- xxx_testobj -> das kann man laden und ggf clonen
+- xxx_testraum -> den kann man betreten
+
+Der Praefix deutet an, fuer welche Features (also man-pages) der Testcode geschrieben wurde. Die man-page selbst nennt diesen Dateinamen hier, insofern:
+* bitte mit Bedacht veraendern - pruefen, welche Funktionalitaet
+  beispielhaft gezeigt werden soll und das nicht loeschen
+* bitte Dateinamen nur veraendern, wenn ihr euch sicher seid, _alle_
+  darauf verweisenden man-pages ebenfalls geaendert zu haben
+
+Verantwortlich: Gloinson
+
diff --git a/doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c b/doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c
new file mode 100644
index 0000000..4225d88
--- /dev/null
+++ b/doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c
@@ -0,0 +1,105 @@
+inherit "/std/thing";

+#include <properties.h>

+#include <new_skills.h>

+#include <sensitive.h>

+

+private action_puste(string str);

+private int counter;

+

+void create() {

+  if (!clonep(this_object())) return;

+  ::create();

+  counter = 2+random(4);

+  

+  SetProp(P_NAME, "Pusteblume");

+  SetProp(P_SHORT, "Eine kleine Pustblume");

+  SetProp(P_LONG, break_string(

+    "Eine abgebluehte Pflanze, die jetzt wie ein kleiner, weisser Ball "

+	"aussieht. Die fiedrigen Samen fliegen bestimmt prima.", 78));

+  AddDetail("samen", "Er sieht sehr fein und leicht aus.\n");

+  SetProp(P_GENDER,FEMALE);

+  SetProp(P_MATERIAL, MAT_MISC_PLANT);

+  SetProp(P_NOBUY, 1);

+  SetProp(P_VALUE, random(10));

+

+  SetProp(P_INFO, "Starker Wind taete ihr nicht gut.\n");

+

+  AddId(({"blume", "pusteblume", "loewenzahn"}));

+  SetProp(P_COMBATCMDS,(["puste loewenzahn":

+                         ([C_HEAL: 5])]));

+

+  SetProp(P_SENSITIVE,({({SENSITIVE_ATTACK, DT_AIR, 20}),

+                        ({SENSITIVE_INVENTORY, DT_AIR, 20})}));

+ 

+  AddCmd("puste&@ID", #'action_puste, "Puste wen oder was (an)?");

+}

+

+private action_puste(string str) {

+  if(environment()!=this_player()) {

+    notify_fail("Dazu solltest du "+name(WEN,1)+" haben.\n");

+	return 0;

+  }

+  if (this_player()->QueryProp(P_ATTACK_BUSY)) {

+    write("Du hast dafuer momentan einfach nicht mehr die Puste.\n");

+    return 1;

+  }

+  this_player()->SetProp(P_ATTACK_BUSY, 1);

+

+  if(counter<0) {

+    write(break_string("Du pustest sinnlos auf "+name(WEN, 2)+".", 78));

+	say(break_string(this_player()->Name(WER)+

+	  " pustet wie daemlich gegen "+name(WEN, 0)+".", 78));

+	return 1;

+  } else {

+    write(break_string(

+      "Du pustest "+name(WEN, 2)+" vorsichtig an, einige Samen "

+      "loesen sich und fliegen taumelnd in deinem Atem davon."+

+	  (counter<0?" Es bleibt nur noch ein nutzloser Strunk.":""), 78));

+    say(break_string(

+      this_player()->Name(WER)+" pustet sachte gegen "+name(WEN, 0)+" und "

+	  "du schaust verzueckt den davonfliegenden Samen nach.", 78));

+  }

+	

+  object who = this_player()->QueryEnemy();

+  

+  if(objectp(who)) {

+    if(!interactive(this_player())) {

+      who->ModifySkillAttribute(SA_SPEED, 80+random(10), 6);

+	  this_player()->heal_self(5);

+	} else

+	  who->ModifySkillAttribute(SA_SPEED, 90+random(10), 4);

+  }

+

+  counter--;

+  if(counter<0) {

+    call_out(#'remove, 10+random(60));

+	AddId("strunk");

+	SetProp(P_NAME, "Strunk");

+	SetProp(P_SHORT, "Der Strunk einer Pusteblume");

+	SetProp(P_LONG, "Ein haesslicher, leerer Strunk.\n");

+	SetProp(P_GENDER, MALE);

+  }

+  return 1;

+}

+

+private void notify_env_destroy() {

+  object ob = environment();

+  while(ob && !living(ob)) ob = environment(ob);

+  if(objectp(ob))

+    tell_object(ob, "Der Wind zerblaest "+name(WEN, 2)+".\n");

+  remove(1);

+}

+

+varargs void trigger_sensitive_attack() {

+  notify_env_destroy();

+}

+

+varargs void trigger_sensitive_inv() {

+  notify_env_destroy();

+}

+

+varargs int remove(int silent) {

+  if(!silent && living(environment()))

+    tell_object(environment(), "Du wirfst "+name(WEN, 2)+" weg.\n");

+  return ::remove(silent);

+}
\ No newline at end of file
diff --git a/doc/beispiele/testobjekte/command_me_testraum.c b/doc/beispiele/testobjekte/command_me_testraum.c
new file mode 100644
index 0000000..29086ce
--- /dev/null
+++ b/doc/beispiele/testobjekte/command_me_testraum.c
@@ -0,0 +1,33 @@
+#include <properties.h>
+inherit "/std/room";
+
+void create() {
+  ::create();
+  SetProp(P_LONG, "AddCmd-Testraum, Kommandos "
+                  "\"kriech\" und \"schleiche&heran|herum\".");
+  AddCmd("schleiche&heran|herum", "action_schleichen");
+  AddExit("gilde", "/gilden/abenteurer");
+}
+
+void init() {
+  ::init();
+  add_action("action_kriechen", "kriech", 1);
+}
+
+static action_schleichen(string str) {
+  string tmp = this_player()->QueryProp(P_RACE);
+  if(tmp[<1]=='e') tmp=tmp[0..<2];
+  write(break_string("Du versuchst leise zu schleichen, dabei passiert "
+    "dir aber ein allzu "+
+	(tmp=="Mensch"?"menschliches":lower_case(tmp)+"isches")+
+	" Missgeschick. Verflucht!", 78));
+  this_player()->command_me("\\furze");
+  return 1;
+}
+
+static int action_kriechen(string str) {
+  write(break_string("Deine Knie tun zu sehr weh dafuer.", 78));
+  tell_room(this_object(), break_string(this_player()->Name(WER)+
+    " knackt mit den Knien.", 78));
+  return 1;
+}
\ No newline at end of file
diff --git a/doc/beispiele/testobjekte/modifyskillspell_test.c b/doc/beispiele/testobjekte/modifyskillspell_test.c
new file mode 100644
index 0000000..3c58342
--- /dev/null
+++ b/doc/beispiele/testobjekte/modifyskillspell_test.c
@@ -0,0 +1,103 @@
+// ModifySkill-Beispiel fuer einem Spell. Erlaeuterung auf man-Page
+// und im Objekt selbst
+inherit "/std/thing";
+#include <new_skills.h>
+#include <properties.h>
+#include <wizlevels.h>
+#include <break_string.h>
+
+static int skillset(string str);
+static int skillunset(string str);
+
+void create() {
+  if(!clonep(this_object())) {
+    set_next_reset(-1);
+    return;
+  }
+
+  ::create();
+  set_next_reset(7200);
+
+  SetProp(P_NAME, "Skillbeispiel");
+  SetProp(P_SHORT, "Eine Skillbeispiel");
+  SetProp(P_LONG, break_string(
+    "Mit \"skillset\" kann man sich den Skill (eigentlich Spell) "
+    "\"fnrx\" setzen.\n"+
+    "Durch \"skillunset\" wird der Skill geloescht.\n"
+    "Das zaehlt deshalb als Spell, weil er kleingeschrieben und "
+    "damit direkt vom Spieler (also dir) als Kommando via UseSpell() "
+    "ausfuehrbar ist.", 78, 0, BS_LEAVE_MY_LFS));
+  SetProp(P_GENDER, NEUTER);
+  AddId(({"beispiel", "skillbeispiel", "spellbeispiel",
+          "skill", "spell"}));
+  
+  AddCmd("skillset", #'skillset);
+  AddCmd("skillunset", #'skillunset);
+}
+
+// Testfunktion, weil im Code dazu aufgefordert wird, das Objekt auch
+// mal zu wegzulegen. Spieler sollten nicht an sich herumfummeln.
+private static int _checkLearner(object pl) {
+  if(!IS_LEARNER(this_player())) {
+    notify_fail("Du bist kein Magier, deshalb geht das nicht.\n");
+    call_out(#'remove, 1);
+    return 0;
+  }
+  return 1;
+}
+
+static int skillset(string str) {
+  if(!_checkLearner(this_player()))
+    return 0;
+
+  if(this_player()->QuerySkill("fnrx")) {
+    notify_fail("Du kannst den Skill schon.\n");
+    return 0;
+  }
+
+  this_player()->ModifySkill("fnrx",
+    ([SI_CLOSURE: function int (object caster, string skill, mapping sinf) {
+            caster->LearnSkill("fnrx", 1);
+            tell_object(caster, "Peng! Dein Skillwert steigt auf "+
+                                caster->QuerySkillAbility("fnrx")+".\n");
+                    return 1;
+                  },
+      SI_SKILLABILITY: 8432]), 100, "ANY");
+  tell_object(this_player(), break_string(
+    "Der Skill ist gesetzt. Tipp doch ein paar Mal \"fnrx\" und schau den "
+    "Code unter "+load_name(this_object())+" an, damit du siehst, dass der "
+    "Skill jetzt nur aus einem Eintrag in dir und einer ueber UseSpell() "
+    "gerufenen Funktion in diesem Objekt besteht. Der Skill ist kein "
+    "Kommando in einem anderen Objekt.\n\n"
+    "Wenn du dieses Objekt weglegst, funktioniert also alles weiter. "
+    "Zerstoerst du aber das Objekt (oder dich mit \"ende\", funktioniert "
+    "die Skillfunktion nicht mehr.\n"
+    "Schau dir auch xeval this_player()->QuerySkill(\"fnrx\") an.", 78, 0,
+    BS_LEAVE_MY_LFS));
+  return 1;
+}
+
+// Here be dragons!
+// Bitte benutzt die folgende Art von Manipulation der Skills nur dann,
+// wenn ihr genau wisst, was ihr tut. In anderen Worten: NICHT MACHEN!
+// Und wenn, dann NUR AM EIGENEN MAGIEROBJEKT, NICHT AN SPIELERN!
+static int skillunset(string str) {
+  if(!_checkLearner(this_player()))
+    return 0;
+
+  // per Query() das Mapping an der _query_*-Fun vorbei direkt holen
+  mapping skills = this_player()->Query(P_NEWSKILLS);
+  // ... und manipulieren (wirkt sich wegen Referenz direkt aus)
+  if(mappingp(skills) && mappingp(skills["ANY"]) &&
+     member(skills["ANY"], "fnrx")) {
+    efun::m_delete(skills["ANY"], "fnrx");
+    tell_object(this_player(), "Erledigt.\n");
+  } else
+    tell_object(this_player(), "Nichts zu erledigen.\n");
+  
+  return 1;
+}
+
+void reset() {
+  remove();
+}
diff --git a/doc/beispiele/testobjekte/netdead_info_testraum.c b/doc/beispiele/testobjekte/netdead_info_testraum.c
new file mode 100644
index 0000000..b2d8a71
--- /dev/null
+++ b/doc/beispiele/testobjekte/netdead_info_testraum.c
@@ -0,0 +1,69 @@
+// Beispielraum fuer P_NETDEAD_INFO-Funktionalitaet
+#include <properties.h>
+#include <break_string.h>
+inherit "/std/room";
+     
+string create_destiny(mixed val);
+int create_room(string dir);
+
+void create() {
+  ::create();
+
+  if (clonep(this_object())) {
+    // setze Informationen, die in einem Netztoten gespeichert werden sollen
+    Set(P_NETDEAD_INFO, random(5));
+    SetProp(P_INT_LONG, break_string(
+      "Wenn du hier einschlaefst, wird der Raum nach 30s zerstoert. Beim "
+      "Aufwachen wirst du an die Blueprint dieses Raums die Info "+
+      QueryProp(P_NETDEAD_INFO)+" uebergeben. Diese wird aus dieser Info "
+      "einen Raumpfad ermitteln, in den du bewegt wirst.", 78));
+  } else {
+    // Blueprint: hier kann man zu einem Cloneraum gehen
+    AddExit("cloneraum", #'create_room);
+    SetProp(P_INT_LONG, break_string(
+      "Zum Testen einfach den Ausgang 'cloneraum' benutzen. Es wird dann "
+      "ein Raum geclont, in den man bewegt wird. Wenn man dort einschlaeft, "
+      "wird der geclonte Raum nach circa 30s zerstoert.\n"
+      "Beim Aufwachen werden die im Spieler gespeicherten Informationen des "
+      "geclonten (und nunmehr zerstoerten) Raumes benutzt, um einen "
+      "alternativen Aufwachraum (Klerusgilde, Karategilde, Wald oder Port "
+      "Vain) zu bestimmen.\n"
+      "Andernfalls wuerde der Spieler in der Abenteurergilde erwachen.", 78,
+      0, BS_LEAVE_MY_LFS));
+  }
+
+  // Set-Method, um die Informationen aus P_NETDEAD_INFO beim Aufwachen
+  // in der Blueprint auswerten zu koennen
+  Set(P_NETDEAD_INFO, #'create_destiny, F_SET_METHOD);
+  SetProp(P_LIGHT, 1);
+}
+     
+// Raum entfernen, normalerweise so KEINE GUTE IDEE!
+void BecomesNetDead(object pl) {
+  call_out(#'remove, 30);
+}
+
+// erzeuge einen Cloneraum und bewege den Spieler dahin
+int create_room(string dir) {
+  object dest = clone_object(object_name(this_object()));
+  this_player()->move(dest, M_NOCHECK);
+  return 1;
+}
+     
+// Set-Method fuer P_NETDEAD_INFO: gibt Pfad zurueck
+// benutze die Informationen aus dem jetzt aufwachenden Netztoten, um einen
+// alternativen Aufwachraum zu ermitteln, da der Einschlafraum zerstoert ist
+string create_destiny(mixed val) {
+  if (intp(val)) {
+    switch (val) {
+      case 0:
+        return "/d/ebene/room/PortVain/po_haf1";
+      case 1:
+        return "/gilden/klerus";
+      case 2:
+        return "/gilden/karate";
+      default:
+    }
+    return "/d/ebene/room/waldweg4";
+  }
+}
diff --git a/doc/beispiele/virtual/.readme b/doc/beispiele/virtual/.readme
new file mode 100644
index 0000000..7cbded2
--- /dev/null
+++ b/doc/beispiele/virtual/.readme
@@ -0,0 +1,2 @@
+Ein einfaches Beispiel fuer per virtual compiler erzeugte Objekte von Zesstra
+und ein leicht komplexeres von Hate.
diff --git a/doc/beispiele/virtual/hate/v_room.c b/doc/beispiele/virtual/hate/v_room.c
new file mode 100644
index 0000000..59c28fd
--- /dev/null
+++ b/doc/beispiele/virtual/hate/v_room.c
@@ -0,0 +1,12 @@
+inherit "/std/room";
+
+#include <properties.h>
+#include <defines.h>
+
+create()
+{
+        if(IS_BLUE(this_object())) return;
+        ::create();
+        previous_object()->CustomizeObject();
+        call_out(symbol_function("QueryObject", find_object(OBJECTD)), 2);
+}
diff --git a/doc/beispiele/virtual/hate/vr_compiler.c b/doc/beispiele/virtual/hate/vr_compiler.c
new file mode 100644
index 0000000..1a50d0b
--- /dev/null
+++ b/doc/beispiele/virtual/hate/vr_compiler.c
@@ -0,0 +1,85 @@
+// MorgenGrauen MUDlib
+//
+// VR_COMPILER.C -- virtual room compiler
+//
+// $Date: 2002/08/28 09:57:18 $
+// $Revision: 1.3 $
+/* $Log: vr_compiler.c,v $
+ * Revision 1.3  2002/08/28 09:57:18  Rikus
+ * auf strong_types umgestellt
+ *
+ * Revision 1.2  1994/07/27 14:48:18  Jof
+ * suid
+ *
+ * Revision 1.1  1994/02/01  19:47:57  Hate
+ * Initial revision
+ *
+*/
+
+// principle:
+// 	- inherit this object into your own 'virtual_compiler.c'
+//  - customize Validate() and CustomizeObject() for you own sake
+//  
+//  * Validate() checks if a room filename given as argument (without path)
+//    is valid and returns this filename with stripped '.c'!!
+//  * CustomizeObject() uses the previous_object()->Function() strategy to
+//    customize the standard object (for example to set a description)
+//
+// Properties: P_VALID_NAME, P_MIN_X, P_MAX_X, P_MIN_Y, P_MAX_Y
+
+#pragma strong_types
+
+inherit "/std/virtual/v_compiler";
+
+#define NEED_PROTOTYPES
+
+#include <thing/properties.h>
+#include <defines.h>
+#include <v_compiler.h>
+#include "/obj/virtual/vr_compiler.h"
+#include <sys_debug.h>
+
+void create()
+{
+  ::create();
+  SetProp(P_VALID_NAME, "raum");
+}
+
+string Validate(string file)
+{
+  int x,y;
+  string path, name;
+
+  file = ::Validate(file);
+	if((sscanf(file, "%s[%d,%d]", name, x, y) == 3) &&
+			name == QueryProp(P_VALID_NAME) &&
+		  (x >= QueryProp(P_MIN_X) && x <= QueryProp(P_MAX_X)) &&
+		  (y >= QueryProp(P_MIN_Y) && y <= QueryProp(P_MAX_Y))
+		)
+      return file;
+}
+
+mixed CustomizeObject()
+{
+	string path, file, name;
+	int x,y;
+
+	if(!(file = ::CustomizeObject())) return 0;
+
+	path = QueryProp(P_COMPILER_PATH);
+	sscanf(file, "%s[%d,%d]", name, x, y);
+	name = QueryProp(P_VALID_NAME);
+	if(y < QueryProp(P_MAX_Y))
+	    previous_object()->AddExit("norden", 
+		path+"/"+name+"["+(x  )+","+(y+1)+"]");
+	if(y > QueryProp(P_MIN_Y))
+	    previous_object()->AddExit("sueden", 
+		path+"/"+name+"["+(x  )+","+(y-1)+"]");
+	if(x < QueryProp(P_MAX_X))
+	    previous_object()->AddExit("osten" , 
+		path+"/"+name+"["+(x+1)+","+(y  )+"]");
+	if(x > QueryProp(P_MIN_X))
+	    previous_object()->AddExit("westen", 
+		path+"/"+name+"["+(x-1)+","+(y  )+"]");
+}
+
diff --git a/doc/beispiele/virtual/hate/vr_compiler.h b/doc/beispiele/virtual/hate/vr_compiler.h
new file mode 100644
index 0000000..673fc54
--- /dev/null
+++ b/doc/beispiele/virtual/hate/vr_compiler.h
@@ -0,0 +1,33 @@
+// MorgenGrauen MUDlib
+//
+// V_COMPILER.H -- a general virtual compiler object
+//
+// $Date: 1994/02/01 19:47:57 $
+// $Revision: 1.1 $
+/* $Log: vr_compiler.h,v $
+ * Revision 1.1  1994/02/01  19:47:57  Hate
+ * Initial revision
+ *
+*/
+
+#include <v_compiler.h>
+
+#ifndef __VR_COMPILER_H__
+#define __VR_COMPILER_H__
+
+#define P_VALID_NAME	"valid_name"
+#define P_MIN_X				"min_x"
+#define P_MAX_X				"max_x"
+#define P_MIN_Y				"min_y"
+#define P_MAX_Y				"max_y"
+
+#endif // __V_COMPILER_H__
+
+#ifdef NEED_PROTOTYPES
+
+#ifndef __VR_COMPILER_H_PROTO__
+#define __VR_COMPILER_H_PROTO__
+
+#endif // __VR_COMPILER_H_PROTO__
+
+#endif //NEED_PROTOTYPES
diff --git a/doc/beispiele/virtual/zesstra/std_arena.c b/doc/beispiele/virtual/zesstra/std_arena.c
new file mode 100644
index 0000000..de2e5a2
--- /dev/null
+++ b/doc/beispiele/virtual/zesstra/std_arena.c
@@ -0,0 +1,20 @@
+inherit "/std/room";
+
+#pragma strong_types,save_types,rtt_checks
+#include <properties.h>
+
+protected void create()
+{
+    if(!clonep(TO))
+        return;
+    ::create();
+
+    SetProp(P_INT_LONG, break_string(
+          "Du stehst hier in einer voellig leeren Arena."
+          "Gegen wen solltest Du hier denn gleich kaempfen...?",78));
+    SetProp(P_INT_SHORT, "In einer Arena");
+    SetProp(P_LIGHT, 1);
+    SetProp(P_INDOORS,0);
+
+    AddExit("raus", "/gilden/abenteurer");
+}
diff --git a/doc/beispiele/virtual/zesstra/virtual_compiler.c b/doc/beispiele/virtual/zesstra/virtual_compiler.c
new file mode 100644
index 0000000..36753df
--- /dev/null
+++ b/doc/beispiele/virtual/zesstra/virtual_compiler.c
@@ -0,0 +1,32 @@
+inherit "/std/virtual/v_compiler.c";
+
+#pragma strong_types,rtt_checks,save_types
+
+#include <thing/properties.h>
+
+#define NEED_PROTOTYPES
+#include <v_compiler.h>
+#undef NEED_PROTOTYPES
+
+protected void create() {
+    ::create();
+
+    // jeder Spieler kriegt eine "Kopie" von std_arena als Raum.
+    SetProp(P_STD_OBJECT, __DIR__"std_arena");
+    SetProp(P_COMPILER_PATH, __DIR__);
+}
+
+public string Validate(string file)
+{
+    string raum, spieler;
+    //.c abschneiden
+    file=::Validate(file);
+    // wenn das gewuenscht file dem Schema "arena|spielername" folgt, ist es
+    // zulaessig.
+    if(sscanf(file,"%s|%s",raum,spieler)==2 && raum=="arena")
+       return file;
+
+    // nicht zulaessig.
+    return 0;
+}
+
diff --git a/doc/beispiele/zauberwald/files.h b/doc/beispiele/zauberwald/files.h
new file mode 100644
index 0000000..8525d78
--- /dev/null
+++ b/doc/beispiele/zauberwald/files.h
@@ -0,0 +1,25 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#define HOME(x) "/doc/beispiele/"+x
+#define WALD(x) HOME("zauberwald/"+x)
+#define ROOM(x) WALD("room/"+x)
+#define NPC(x)  WALD("npc/"+x)
+#define OBJ(x)  WALD("obj/"+x)
+
+#include <defines.h>
+#include <properties.h>
+#include "/p/service/padreic/mnpc/mnpc.h"
+
+#define BS(x) break_string(x, 78)
+#define PO    previous_object()
+#define DEBUG(x) tell_object(find_player("padreic"), x);
+
+#define SAECKCHEN "/d/wald/padreic/obj/saeckchen.c"
+
+
+#define ZAUBERWALD "\npadreiczauberwald" /* gesetzt wenn man im wald ist */
+#define AGGRESSIVE_TIME 900              /* zeit bis zur befriedung */
+#define ZAUBERWALDNPC WALDID("npc")
+#define AUSGANG     "\npadreicausgang"   /* die letzte Bewegung */
+#define WALDID(x)   ZAUBERWALD+x
+#define EXTRA_LONG   "\npadreiczusatzlong" /* zur ergaenzung zur VC-long */
diff --git a/doc/beispiele/zauberwald/npc/arina.c b/doc/beispiele/zauberwald/npc/arina.c
new file mode 100644
index 0000000..9e08e25
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/arina.c
@@ -0,0 +1,101 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <new_skills.h>
+#include "/p/zauberer/zauberer.h"
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Arina die Waldfee");
+   SetProp(P_LONG,
+      "Vor Dir steht Arina die weise Waldfee. Sie ist die Lehrerin des Waldes und\n"
+     +"unterrichtet die Pixies. In ihrer Hand haelt sie einen kleinen Zeigestock mit\n"
+     +"dem sie alles moegliche erklaert und Buchstaben in den Sand zeichnet. Auch\n"
+     +"Arina ist, genauso wie ihre Schwesten, bildhuebsch, doch ihr gestrenger Blick\n"
+     +"floesst jedem in ihrer Naehe grossen Respekt ein.\n");
+   SetProp(P_NAME, "Arina");
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_LEVEL, 80);
+   SetProp(P_ATTRIBUTES, (["int":80,"con":40,"str":16,"dex":50]) );
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   SetProp(P_BODY, 80);
+   SetProp(P_MAX_SP, 2000);
+   SetProp(P_SP, 2000);
+   SetProp(P_MAX_HP, 700);
+   SetProp(P_HP, 700);
+   SetProp(P_ALIGN, 400);
+   SetProp(P_RACE, "Fee");
+   SetProp(P_SIZE, 160+random(16));
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_CORPSE, OBJ("feenleiche"));
+   SetProp(P_MAX_ALCOHOL, 0); // kein rauschen :)
+   AddAdjective("wunderschoen");
+   AddId(({"arina", "fee", "waldfee", WALDID("fee")}));
+   SetProp(P_HANDS, ({" mit ihren zarten Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPELL_PENETRATION: 200]));
+   SetProp(P_XP, 800*200*5*2);
+   SetProp(P_GUILD, "zauberer");
+   SetProp(P_Z_NO_MATERIAL, 1);
+   SetProp(P_DEFAULT_INFO, "schweigt und laechelt Dich einfach nur freundlich an.\n");
+   ModifySkill("verletze",
+      ([SI_SKILLABILITY:9000, SI_SPELLCOST:0,
+        SI_SPELLFATIGUE:0, SI_NO_CONSEQUENCES:10000,
+        SI_SKILLRESTR_USE:([P_GUILD_LEVEL:0,SR_FREE_HANDS:0]),
+        SI_ARMOUR_RESTR:0]),0,"zauberer");
+   SetProp(P_GUILD, 0);
+   SetProp(P_RESISTANCE_STRENGTHS,
+      ([DT_POISON: 0.15,
+        DT_MAGIC: -0.3 ]) );
+   AddItem(OBJ("stock"), CLONE_WIELD);
+   AddItem(OBJ("kleid"), CLONE_WEAR);
+   if (file_size(SAECKCHEN)>0) AddItem(SAECKCHEN, CLONE_NEW);
+}
+
+void Attack(object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write("Die Fee macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+   if (enemy) ::Attack(enemy);
+   SetProp(P_GUILD, "zauberer");
+   command("verletze mit "+({"feuer", "magie", "eis", "wasser", "wind"})[random(5)] );
+   SetProp(P_GUILD, 0);
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write(Name(WER)+" macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+
+   if ((!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK])) && !random(3)) {
+      tell_room(environment(), Name(WER)+" weicht schnell einen Schritt zurueck und weicht Deinem Angriff aus.\n");
+      dam=0;
+   }
+   return (int)::Defend(dam, dts, spell, enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/arina\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Arina wurde von "+get_killer()+" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/laufeiche.c b/doc/beispiele/zauberwald/npc/laufeiche.c
new file mode 100644
index 0000000..0649276
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/laufeiche.c
@@ -0,0 +1,124 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <moving.h>
+#include <new_skills.h>
+
+inherit NPC("stdnpc");
+inherit MNPC_MOVING;
+
+void create()
+{
+   if (!clonep(ME)) return;
+   stdnpc::create();
+   moving::mnpc_create();
+   SetProp(P_NAME_ADJ, "alt");
+   SetProp(P_NAME, "Eiche");
+   SetProp(P_SHORT, "Eine alte Eiche");
+   SetProp(P_MSGOUT, "wandert");
+   SetProp(P_LONG,
+     "Vor Dir steht eine sehr sehr alte Eiche. Doch diese Eiche ist keine\n"
+    +"gewoehnliche Eiche, wie Du sie bereits an vielen anderen Stellen gesehn hast.\n"
+    +"Diese Eiche lebt! Du kannst deutlich einen Mund, eine Nase und sogar zwei\n"
+    +"Ohren erkennen. Sie ist eigentlich sehr friedlich gesonnen, kann aber auch\n"
+    +"sehr sehr boese werden, wenn es jemand wagt die Ruhe des Waldes zu stoeren.\n");
+   SetProp(P_RACE, "eiche");
+   SetProp(P_LEVEL, 50);
+   SetProp(P_ATTRIBUTES, (["int":50,"con":50,"str":70,"dex":15]) );
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_MAX_HP, 500);
+   SetProp(P_HP, 500);
+   SetProp(P_ALIGN, 500);
+   SetProp(P_BODY, 100);
+   SetProp(P_SIZE, 650+random(151));
+   AddAdjective("alt");
+   AddId(({"eiche", "eichen", WALDID("eiche") }));
+   SetProp(P_HANDS, ({" mit einem ihrer langen Aeste",400, DT_WHIP}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPEED:180]));
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_XP, 500*400*5);
+   SetProp(P_DEFAULT_INFO, "bleibt absolut regungslos und reagiert ueberhaupt nicht.\n");
+   SetProp(P_RESISTANCE_STRENGTHS,
+    ([DT_SLASH:     0.1,
+      DT_MAGIC:    -1.0,
+      DT_BLUDGEON: -0.5,
+      DT_POISON:    0.25,
+      DT_HOLY:     -1.0,
+      DT_RIP:       0.25,
+      DT_FIRE:      0.25,
+      DT_PIERCE:   -0.5,
+      DT_WHIP:     -1.0 ]) );
+   SetProp(MNPC_AREA, ({ ROOM("weg2"), ROOM("lichtung") }) );
+   SetProp(MNPC_RANDOM, 10);
+   SetProp(MNPC_DELAY, 8);
+   SetProp(MNPC_WALK_TIME, 600);
+   SetProp(MNPC_FLAGS, MNPC_WALK|MNPC_NO_WALK_IN_FIGHT|MNPC_ONLY_EXITS);
+}
+
+static string _query_info()
+{
+   if (!PL || PL->QueryProp(ZAUBERWALD)<=time())
+      return "Die alte Eiche ist Dir sehr friedlich gesonnen. Es ist jedoch auch sicher\n"
+            +"klug dieses nicht zu aendern, da sie mit ihren Aesten wohl auch sehr kraeftig\n"
+            +"zuschlagen kann.\n";
+   return "Du hast den Zorn der alten Eiche auf Dich gezogen, das war ganz und gar nicht\n"
+         +"klug von Dir. Jetzt lebe auch mit den Konsequenzen....\n";
+}
+
+int remove()
+// wenn eine Eiche getoetet wird, dann verlangsamt das den reset der Eiche
+// die auf weg2 blockt. In der Regel steht ja auch so schon immer eine der
+// wanderden Eichen dort. Dies soll verhindern, das gerade eine Eiche resetet
+// wenn man eine tod hat.
+{
+   call_other(ROOM("weg2"), "delay_reset");
+   catch(call_other(QueryProp(MNPC_HOME), "delay_reset", 900+random(3600)));
+   return (int)::remove();
+}
+
+// wenn man den MNPC mit einem anderen stdnpc kombiniert muessen einige
+// funktionen per Hand ueberschrieben werden....
+
+void reset()
+{
+   stdnpc::reset();
+   moving::mnpc_reset();
+}
+
+void init()
+{
+   stdnpc::init();
+   moving::mnpc_init();
+}
+
+varargs int move(mixed dest, int meth, string dir, string out, string in)
+{
+   int i;
+
+   // extra fuer den Zauberwald eingebaut
+   if (environment() && object_name(environment())==ROOM("weg2")) {
+      // wenn es die einzige Eiche ist, dann bleibt sie hier stehn,
+      // bewacht den Weg und bewegt sich nicht mehr hier weg!
+      object *inv;
+
+      inv = all_inventory(environment()) - ({ ME });
+      for (i=sizeof(inv)-1; i>=0; i--)
+         if (BLUE_NAME(inv[i])==NPC("laufeiche")) break;
+      if (i<0) return ME_CANT_LEAVE_ENV;
+   }
+   //////////////////////////////////////
+   i=(int)stdnpc::move(dest, meth, dir, out, in);
+   if (i!=1) return i;
+   moving::mnpc_move();
+   return 1;
+}
+
+int PreventFollow(object dest)
+{  return moving::mnpc_PreventFollow(dest);  }
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/laufeiche\n");
+}
diff --git a/doc/beispiele/zauberwald/npc/pixie.c b/doc/beispiele/zauberwald/npc/pixie.c
new file mode 100644
index 0000000..7ed953d
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/pixie.c
@@ -0,0 +1,150 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+#include <combat.h>
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein kleiner Pixie");
+   SetProp(P_SIZE, 55+random(11));
+   SetProp(P_LONG, BS(
+     "Der Pixie ist etwa "+QueryProp(P_SIZE)+"cm gross und sieht vermutlich einem "
+    +"kleinen pumeligen Menschenkind am aehnlichsten. Wie alle Pixies scheint er "
+    +"sehr verspielt zu sein und nichts als Unfug im Kopf zu haben, Du solltest "
+    +"Dich also vor ihm ihn acht nehmen. Auch wenn er aussieht wie ein Kind, sich "
+    +"benimmt wie ein Kind, so kann er Dir mit seiner Magie sicher uebel zu spieln."));
+   SetProp(P_INFO, /* kleine Warnung fuer die Kaempfer :) */
+     "Man sollte sich immer vor der Magie der Pixies in acht nehmen, sie ist nicht\n"
+    +"unbedingt gefaehrlich, aber es koennen die unerwartesten Dinge geschehn. So\n"
+    +"ist durchaus von Leuten bekannt die einen Kampf als kleine Ratte beendeten,\n"
+    +"oder deren Schwert im Kampf ploetzlich zu Scheisse zerfloss...\n");
+   SetProp(P_NAME_ADJ, "klein");
+   SetProp(P_NAME, "Pixie");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_RACE, "pixie");
+   SetProp(P_ATTRIBUTES, (["int":30,"con":20,"str":15,"dex":30]) );
+   SetProp(P_LEVEL, 20);
+   SetProp(P_MAX_HP, 600);
+   SetProp(P_HP, 600);
+   SetProp(P_MAX_SP, 800);
+   SetProp(P_SP, 800);
+   SetProp(P_ALIGN, 250);
+   SetProp(P_HANDS, ({" mit seinen kleinen Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_XP, 600*150*5);
+   AddAdjective("klein");
+   AddId("pixie");
+}
+
+// teleporter Ziele im Gebiet. Der Pixie will ja einfach nur ein bisschen
+// Aergern und nicht helfen (ein Pixiekampf ist kein Ausgang :)
+#define DEST ({"lichtungno", "lichtungso", "lichtungn", "lichtungs", \
+               "lichtungnw", "lichtungsw", "lichtungo", "lichtungw", \
+               "weg2", "stein"})
+
+void Attack(object enemy)
+{
+   object ob, weapon;
+   
+   ob=SelectEnemy();
+   if (ob) switch(random(7*8)) { // jede 8te Runde ein Zauberspruch...
+      case 0: // in Frosch verwandeln...
+        if (!ob->QueryProp(P_FROG)) {
+          tell_object(ob, "Der Pixie dreht Dir eine lange Nase und verwandelt Dich in einen Frosch.\n");
+          say(BS("Der Pixie dreht "+ob->name(WEM)+" eine lange Nase und verwandelt "
+                +ob->QueryPronoun(WEN)+" in einen Frosch,"), ob);
+          ob->SetProp(P_FROG, 1);
+          return;
+        }
+        break;
+      case 8..10: // einfach nur nerviger Teleport innerhalb des Gebiets :)
+        tell_object(ob,
+          "Der Pixie schliesst kurz seine Augen und eh Du Dich versiehst, verschwimmt\n"
+         +"alles um Dich herum...\n");
+        say(BS("Der Pixie schliesst kurz seine Augen und ploetzlich loest sich "
+              +ob->name(WER)+" in Luft auf."), ob);
+        ob->move(ROOM(DEST[random(sizeof(DEST))]), M_TPORT|M_NOCHECK|M_SILENT);
+        return;
+      case 16: // Geschlecht aendern... :)
+        tell_object(ob,
+          "Der Pixie grinst breit bis ueber beide Ohren und schaut Dich an, Du weisst\n"
+         +"gar nicht wie Dir geschieht, aber irgendetwas aendert sich an Deinem Koerper.\n");
+        say(BS("Der Pixie grinst "+ob->name(WEN)+" breit an. Ploetzlich "
+         +(ob->QueryProp(P_GENDER)==FEMALE
+         ? "verschwinden ihre Brueste und es waechst ihr ploetzlich ein Bart."
+         : "verschwindet sein Bart und ihm wachsen zwei neue Brueste.")), ob);
+        if (ob->QueryProp(P_GENDER)==FEMALE)
+          ob->SetProp(P_GENDER, MALE);
+        else ob->SetProp(P_GENDER, FEMALE);
+        return;
+      case 24:
+        if (objectp(weapon=ob->QueryProp(P_WEAPON))) {
+           weapon->DoUnwield(1);
+           // verfluchte Waffen nicht betreffen :))
+           if (!objectp(weapon->QueryProp(P_WIELDED))) {
+              string str1, str2;
+              str1=str2=(weapon)->name(WER);
+              if (str1[0..2]=="ein") {
+                str1="D"+str1;
+                str2="s"+str2;
+              }
+              tell_object(ob, BS(
+               "Der Pixie starrt Dir in die Augen und schnippst einmal kurz mit seinen "
+              +"Fingern. Ploetzlich zerrint "+str1+" in Deinen Haenden zu einem Haufen "
+              +"Scheisse."));
+              say(BS("Der Pixie starrt "+weapon->name(WEM)+" in die Augen und "
+                    +"schnippst einmal kurz mit den Fingern. Ploetzlich "
+                    +"zerrint "+weapon->name(WEM)+" "+str2
+                    +" in einen Haufen Scheisse."), ob);
+              weapon->remove();
+              if (weapon) destruct(weapon);
+              return;
+           }
+        }
+        break;
+      case 32:
+        if (!ob->QueryProp(P_BLIND)) {
+          tell_object(ob, BS(
+             "Der Pixie haelt sich die Hand vor die Augen und grinst breit. Ploetzlich "
+            +"merkst Du, wie alles ganz dunkel um Dich rum wird..."));
+          say(BS("Der Pixie haelt sich die Hand vor die Augen und grinst breit. "
+                +ob->name(WER)
+                +" schaut daraufhin ziemlich irritiert in die Gegend."), ob);
+          ob->SetProp(P_BLIND, 1);
+          return;
+        }
+        break;
+      case 40:
+        if (ob->QueryProp(P_POISON)<3 && ob->QueryProp(P_MAX_POISON)>=3) {
+          tell_object(ob, BS(
+             "Der Pixie streicht sich mit der Hand zufrieden ueber seinen Bauch und schaut "
+            +"Dich dabei an. Ploetzlich wird Dir richtig uebel..."));
+          say(BS("Der Pixie streicht sich mit seiner Hand zufrieden ueber seinen Bauch und\n"
+                +"schaut "+ob->name(WEM)+" dabei in die Augen. Ploetzlich wird "+ob->name(WEM)
+                +" ganz uebel."), ob);
+          ob->SetProp(P_POISON, 3);
+          return;
+        }
+        break;
+      case 48:
+        if (!ob->QueryProp(P_DEAF)) {
+          tell_object(ob, "Der Pixie haelt sich die Ohren zu und grinst breit.\n");
+          say(BS("Der Pixie haelt sich die Ohren zu und grinst dabei "
+                +ob->name(WEN)+" an."), ob);
+          ob->SetProp(P_DEAF, 1);
+          return;
+        }
+        break;
+      default:
+   }
+   if (enemy && present(enemy, environment())) ::Attack(enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/pixie\n");
+}
diff --git a/doc/beispiele/zauberwald/npc/riese.c b/doc/beispiele/zauberwald/npc/riese.c
new file mode 100644
index 0000000..a68a3e2
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/riese.c
@@ -0,0 +1,92 @@
+// (c) 2003 by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <properties.h>
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   create_default_npc(30, 2500);
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_SHORT, "Grimmbart Felsenschieber");
+   SetProp(P_LONG,
+     "Vor Dir sitzt der Riese Grimmbart Felsenschieber. Eigentlich scheint er\n"
+    +"ein sehr gutmuetiger und freundlicher Riese zu sein. Aber irgendwie wirkt\n"
+    +"er derzeit sehr traurig.\n");
+
+   SetProp(P_NAME, "Grimmbart Felsenschieber");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_SIZE, 297);
+   SetProp(P_ALIGN, 200);
+   SetProp(P_RESISTANCE_STRENGTHS,
+     ([DT_HOLY:-1.0,
+       DT_UNHOLY:0.5,
+       DT_MAGIC:0.25,
+       DT_POISON:-0.25,
+       DT_WHIP:-0.6,
+       DT_BLUDGEON:-0.3,
+       DT_PIERCE:-0.1,
+       DT_SLASH:-0.1
+     ]));
+
+   AddInfo(({"felsen", "fels"}),
+     "Ich liebe es meine Muskeln anzuspannen und Felsen zu schieben.",
+     "antwortet: ");
+   AddInfo("schieben",
+     "Ich habe doch keine Felsen mehr die ich schieben koennte.");
+   AddInfo(({"trauer", "traurigkeit"}),
+     "Frueher da habe ich den ganzen Tag hier meine Felsen hin- und "
+    +"hergeschoben, aber nun hat Ulinia mir verboten hier im Wald mit "
+    +"den Felsen zu spielen und ich musste sie alle wegtragen :o(",
+     "jammert: ");
+   AddInfo("tag", "Ja so ein Tag ist ganz schoen lang ohne Felsen",
+     "sagt: ");
+   AddInfo("ulinia",
+      "Eine richtig bloede Fee und haette sie ihre doofen Zauberkraefte nicht,"
+     +"koennte sie uns hier auch nicht alle so rumkommandieren *mopper*.",
+     "sagt: ");
+   AddInfo("grund",
+      "Nur weil mir einmal ausversehen ein klitzekleiner Fels in den Tuempel "
+     +"gefallen ist, musste ich all meine schoenen Felsen aus dem Wald bringen.",
+     "sagt: ");
+   AddInfo("tuempel",
+      "Bloeder Tuempel, wer braucht den schon!", "antwortet gereizt: ");
+   AddInfo("zauberkraefte",
+      "Ich freu mich schon richtig auf den Tag, an dem Ulinias Zauberkraefte "
+     +"nachlassen!",
+      "sagt: ");
+   AddInfo(({"wald", "zauberwald"}),
+      "Wenn es hier wieder ganz viele schoene Felsen gaebe, waer er wieder das "
+     +"reinste Paradies.", "antwortet: ");
+   AddInfo("paradies",
+      "Ja frueher war der Wald hier einmal das reinste Paradies.", "antwortet: ");
+
+   SetChats(3,
+     ({Name(WER)+" sagt: Ich bin so traurig.\n",
+       Name(WER)+" schluchzt: meine schoenen Felsen.. wuaaahhhhh\n",
+       Name(WER)+" sagt: nie wieder werde ich Felsen schieben koennen.\n",
+       Name(WER)+" sagt: F E L S E N !\n",
+       Name(WER)+" jammert: Die Welt ist so furchtbar ungerecht!\n",
+       Name(WER)+" fragt: Wie soll ich so bloss weiterleben?\n"
+     }));
+   
+   AddId("riese");
+   AddId("grimmbart");
+   AddId("felsenschieber");
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))
+    +"getoetet von /zauberwald/riese\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Grimmbart wurde von  "+get_killer()
+    +" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/stdnpc.c b/doc/beispiele/zauberwald/npc/stdnpc.c
new file mode 100644
index 0000000..a2b3d2f
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/stdnpc.c
@@ -0,0 +1,39 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit "/std/npc";
+inherit "/p/service/mupfel/getkill";
+
+void create()
+{
+   ::create();
+   SetProp(ZAUBERWALDNPC, 1);
+   SetProp(P_AGGRESSIVE, ([P_RACE:(["Dunkelelf":1, 0:0.0]) ]));
+}
+
+int AutoAttack(object ob)
+{
+   if (ob && ob->QueryProp(ZAUBERWALD)>time()) return 1;
+   return ::AutoAttack(ob);
+}
+
+int InsertEnemy(object ob)
+{
+   int ret, is_enemy;
+   is_enemy=IsEnemy(ob);
+   ret=(int)::InsertEnemy(ob);
+   if (!is_enemy) { // alle anderen Zauberwald-NPCs im Raum verstaendigen
+      filter_objects(
+        filter_objects(all_inventory(environment())-users(), "QueryProp", ZAUBERWALDNPC),
+        "InsertEnemy", ob
+      );
+   }
+   return ret;
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   if (enemy) enemy->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   return (int)::Defend(dam, dts, spell, enemy);
+}
diff --git a/doc/beispiele/zauberwald/npc/titina.c b/doc/beispiele/zauberwald/npc/titina.c
new file mode 100644
index 0000000..adce062
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/titina.c
@@ -0,0 +1,114 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <new_skills.h>
+#include "/p/zauberer/zauberer.h"
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Titina die Waldfee");
+   SetProp(P_LONG,
+      BS("Vor Dir steht Titina die Waldfee. Ihr langes goldenes Haar weht "
+     +"leicht im Wind und das einzige was sie bedeckt, ist ein leichtes Blaetterkleid "
+     +"das ihre weiblichen Rundungen ausserordentlich gut zur Geltung bringt. "
+     +"Ihre schoenen blauen Augen, tun ein uebriges um Dich ganz wahnsinnig zu machen."));
+   SetProp(P_NAME, "Titina");
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_LEVEL, 80);
+   SetProp(P_ATTRIBUTES, (["int":60,"con":40,"str":16,"dex":50]) );
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   SetProp(P_BODY, 80);
+   SetProp(P_MAX_SP, 2000);
+   SetProp(P_SP, 2000);
+   SetProp(P_MAX_HP, 600);
+   SetProp(P_HP, 600);
+   SetProp(P_ALIGN, 400);
+   SetProp(P_RACE, "Fee");
+   SetProp(P_SIZE, 160+random(16));
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_CORPSE, OBJ("feenleiche"));
+   SetProp(P_MAX_ALCOHOL, 0); // kein rauschen :)
+   AddAdjective("wunderschoen");
+   AddId(({"titina", "fee", "waldfee", WALDID("fee")}));
+   SetProp(P_HANDS, ({" mit ihren zarten Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPELL_PENETRATION: 100]));
+   SetProp(P_XP, 800*200*5*2);
+   SetProp(P_GUILD, "zauberer");
+   SetProp(P_Z_NO_MATERIAL, 1);
+   SetProp(P_DEFAULT_INFO, "schweigt und laechelt Dich einfach nur freundlich an.\n");
+   ModifySkill("verletze",
+      ([SI_SKILLABILITY:8000, SI_SPELLCOST:0,
+        SI_SPELLFATIGUE:0, SI_NO_CONSEQUENCES:10000,
+        SI_SKILLRESTR_USE:([P_GUILD_LEVEL:0,SR_FREE_HANDS:0]),
+        SI_ARMOUR_RESTR:0]),0,"zauberer");
+   SetProp(P_GUILD, 0);
+   SetProp(P_RESISTANCE_STRENGTHS,
+      ([DT_UNHOLY: 0.25,
+        DT_AIR:    0.3,
+        DT_POISON: 0.15]) ); // sonst selten in benutzung :)
+
+   AddItem(OBJ("kamm"), CLONE_WIELD);
+   AddItem(OBJ("kleid"), CLONE_WEAR);
+   if (file_size(SAECKCHEN)>0) AddItem(SAECKCHEN, CLONE_NEW);
+}
+
+static string _query_long()
+{
+   if (!PL || PL->QueryProp(P_GENDER)==FEMALE)
+      return Query(P_LONG)
+        +"Ihr ueberhebliches laecheln bringt Dich jedoch total zur Weissglut, so eine\n"
+        +"Zicke hier den ganzen Tag rumzusitzen und sich nur die Haare zu kaemmen.\n";
+   return Query(P_LONG)
+     +"Mit ihrem charmanten laecheln, zieht sie Dich sofort in ihren Bann und Du\n"
+     +"wuerdest ihr jeden Wunsch erfuellen, so sie denn einen aeussern wuerde.\n";
+}
+
+void Attack(object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write("Die Fee macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+   if (enemy) ::Attack(enemy);
+   SetProp(P_GUILD, "zauberer");
+   command("verletze mit "+({"feuer", "magie", "eis", "wasser", "gift",
+                             "wind", "saeure", "laerm"})[random(8)] );
+   SetProp(P_GUILD, 0);
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write(Name(WER)+" macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+
+   if ((!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK])) && !random(4)) {
+      tell_room(environment(), Name(WER)+" weicht schnell einen Schritt zurueck und weicht Deinem Angriff aus.\n");
+      dam=0;
+   }
+   return (int)::Defend(dam, dts, spell, enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/titina\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Titina wurde von "+get_killer()+" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/ulinia.c b/doc/beispiele/zauberwald/npc/ulinia.c
new file mode 100644
index 0000000..7ea596e
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/ulinia.c
@@ -0,0 +1,160 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <moving.h>
+#include <new_skills.h>
+#include "/p/zauberer/zauberer.h"
+
+inherit NPC("stdnpc");
+
+string info_tarnzauber()
+{
+   object ob;
+   if (present("\ntarnzauber", PL))
+      return "sagt: Ich habe Dich doch bereist verzaubert.\n";
+   ob=clone_object(OBJ("tarnzauber"));
+   ob->move(PL, M_NOCHECK);
+   ob->Initialize(PL);
+   return "sagt: Nun gut, so sei es...\n"
+         +"macht eine weite Handbewegung und Du fuehlst wie Du Dich verwandelst.\n"
+         +"sagt: Viel Glueck!";
+}
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ulinia die Waldfee");
+   SetProp(P_LONG,
+      BS("Ueber dem Teich schwebt Ulinia die Waldfee. Ihr langes goldenes Haar weht "
+     +"leicht im Wind und das einzige was sie bedeckt, ist ein leichtes Blaetterkleid "
+     +"das ihre weiblichen Rundungen ausserordentlich gut zur Geltung bringt. "
+     +"In der Hand haelt sie einen kleinen Zauberstab, mit dem sie hoch ueber allem thront."));
+   SetProp(P_NAME, "Ulinia");
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_LEVEL, 80);
+   SetProp(P_ATTRIBUTES, (["int":80,"con":40,"str":16,"dex":50]) );
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   SetProp(P_BODY, 80);
+   SetProp(P_MAX_SP, 2000);
+   SetProp(P_SP, 2000);
+   SetProp(P_MAX_HP, 800);
+   SetProp(P_HP, 800);
+   SetProp(P_ALIGN, 400);
+   SetProp(P_RACE, "Fee");
+   SetProp(P_SIZE, 160+random(16));
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_CORPSE, OBJ("feenleiche"));
+   SetProp(P_MAX_ALCOHOL, 0); // kein rauschen :)
+   AddAdjective("wunderschoen");
+   AddId(({"fee", "waldfee", "ulinia", WALDID("fee")}));
+   SetProp(P_HANDS, ({" mit ihren zarten Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPELL_PENETRATION: 250]));
+   SetProp(P_XP, 800*200*5*2);
+   SetProp(P_GUILD, "zauberer");
+   SetProp(P_Z_NO_MATERIAL, 1);
+   SetProp(P_DEFAULT_INFO, "schweigt und laechelt Dich einfach nur freundlich an.\n");
+   AddInfo(({"quest", "hilfe", "aufgabe", "dunkelelfenamulett", "delfenamulett"}),
+     "Ohh in der Tat haette ich da eine Aufgabe fuer Dich, aber ich muss Dich "
+    +"warnen, das sie nicht ganz ungefaehrlich ist.\n"
+    +"Ein befreundeter Kobold berichtete mir von einem lange verschollenen Buch, "
+    +"dass in der Bibliothek der Dunkelelfen wieder aufgetaucht ist. In diesem "
+    +"Buch ist unter anderem von einem alten Amulett die Rede, mit dessen Hilfe "
+    +"die Dunkelelfen ihre alte Macht wiedererlangen und erneut Furcht und "
+    +"Schrecken ueber das gesamte Morgengrauen bringen koennten. "
+    +"Wenn Du die Gefahr nicht scheust, waere es ausserordentlich nett wenn Du "
+    +"Dich nach Zzerenzzen begeben wuerdest und dort nach dem Amulett suchst.\n"
+    +"Solltest Du das Amulett tatsaechlich finden, so ist es wichtig das es "
+    +"auf keinen Fall in die Hand der Dunkelelfen geraet und zerstoert wird.",
+    "antwortet: ");
+   AddInfo("gefahr",
+     "Nun Du wirst Dich mitten unter die Dunkelelfen begeben muessen um "
+    +"zu ihrer Bibliothek gelangen zu koennen. In Zzerenzzen wirst Du "
+    +"hierbei voellig auf Dich allein gestellt sein.\n"
+    +"Alles was ich hierbei fuer Dich tun kann, ist einen Tarnzauber zu "
+    +"sprechen der Dich aeusserlich in einen Dunkelelfen verwandelt. "
+    +"Aber vorsicht, spaetestens wenn Du Dich in einen Kampf verwickelst, "
+    +"wird sich der Zauber loesen.", "sagt: ");
+   AddInfo("tarnzauber", #'info_tarnzauber, "");
+   AddInfo(({"furcht", "schrecken", "macht"}),
+     "Ja frueher waren die Dunkelelfen sehr sehr maechtig und alle "
+    +"friedliebenden Geschoepfe dieser Welt sollten hoffen das sie "
+    +"nie wieder ihre alte Macht erlangen werden.", "antwortet: ");  
+   AddInfo("amulett",
+     "Nun leider weiss ich auch nichts genaues ueber das Amulett. Ich bin "
+    +"nicht mal sicher ob es existiert oder je existiert hat. Aber sollte "
+    +"es noch existieren, muss es auf jeden Fall zerstoert werden!", "sagt: ");
+   AddInfo("kobold",
+     "Ich habe versprochen ihn nicht zu verraten und so kann ich Dir nichts "
+    +"weiter ueber ihn sagen.", "antwortet: ");
+   AddInfo(({"buch", "bibliothek"}),
+     "Ich denke am besten begibst Du Dich in die Hoehle des Loewen und versuchst "
+    +"in der Bibliothek der Dunkelelfen selbst ein Blick in dies Buch zu werfen.\n"
+    +"Wenn ich das noch recht in Erinnerung habe, handelt es sich hierbei um "
+    +"das Buch eines Dunkelelfen names Teyrion.", "sagt: ");
+   AddInfo("loewen", "Das ist doch bloss eine Redewendung.", "sagt: ");
+   AddInfo("redewendung", "Na das sagt man halt so...", "sagt: ");
+   AddInfo(({"hoehle", "zzerenzzen"}),
+     "Der Eingang nach Zzerenzzen liegt in der naehe von Wilhelmsburg gut hinter "
+    +"einem Wasserfall versteckt.", "sagt: ");
+   ModifySkill("verletze",
+      ([SI_SKILLABILITY:10000, SI_SPELLCOST:0,
+        SI_SPELLFATIGUE:0, SI_NO_CONSEQUENCES:10000,
+        SI_SKILLRESTR_USE:([P_GUILD_LEVEL:0,SR_FREE_HANDS:0]),
+        SI_ARMOUR_RESTR:0]),0,"zauberer");
+   SetProp(P_GUILD, 0);
+   SetProp(P_RESISTANCE_STRENGTHS,
+      ([DT_UNHOLY: 0.25,
+        DT_POISON: 0.15, 
+        DT_MAGIC: -0.3]) );
+
+   AddItem(OBJ("zauberstab"), CLONE_WIELD);
+   AddItem(OBJ("kleid"), CLONE_WEAR);
+   if (file_size(SAECKCHEN)>0) AddItem(SAECKCHEN, CLONE_NEW);
+}
+
+void Attack(object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write("Die Fee macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+   if (enemy) ::Attack(enemy);
+   SetProp(P_GUILD, "zauberer");
+   command("verletze mit "+({"feuer", "magie", "eis", "wasser", "gift",
+                             "wind", "saeure", "laerm"})[random(8)] );
+   SetProp(P_GUILD, 0);
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write(Name(WER)+" macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+
+   if ((!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK])) && !random(3)) {
+      tell_room(environment(), Name(WER)+" weicht schnell einen Schritt zurueck und weicht Deinem Angriff aus.\n");
+      dam=0;
+   }
+   return (int)::Defend(dam, dts, spell, enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/ulinia\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Ulinia wurde von "+get_killer()+" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/waechter.c b/doc/beispiele/zauberwald/npc/waechter.c
new file mode 100644
index 0000000..55c1a10
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/waechter.c
@@ -0,0 +1,87 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <new_skills.h>
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_NAME, "Waechter des Waldes");
+   SetProp(P_SHORT, "Der Waechter des Waldes");
+   SetProp(P_LONG,
+     "Vor Dir steht eine sehr sehr alte Eiche. Doch diese Eiche ist keine\n"
+    +"gewoehnliche Eiche, wie Du sie bereits an vielen anderen Stellen gesehn hast.\n"
+    +"Diese Eiche lebt! Du kannst deutlich einen Mund, eine Nase und sogar zwei\n"
+    +"Ohren erkennen. Sie ist eigentlich sehr friedlich gesonnen, kann aber auch\n"
+    +"sehr sehr boese werden, wenn es jemand wagt die Ruhe des Waldes zu stoeren.\n");
+   SetProp(P_RACE, "eiche");
+   SetProp(P_AGGRESSIVE, 0);
+   SetProp(P_LEVEL, 100);
+   SetProp(P_ATTRIBUTES, (["int":80,"con":100,"str":100,"dex":20]) );
+   SetProp(P_GENDER, MALE);
+   SetProp(P_MAX_HP, 1000);
+   SetProp(P_HP, 1000);
+   SetProp(P_ALIGN, 500);
+   SetProp(P_BODY, 100);
+   SetProp(P_SIZE, 1500);
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   AddId(({"eiche", "waechter","waechter des waldes", WALDID("waechtereiche") }));
+   SetProp(P_HANDS, ({" mit einem seiner langen Aeste",550,DT_WHIP}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPEED:210]));
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_XP, 1000*550*5);
+   SetProp(P_DEFAULT_INFO, "bleibt absolut regungslos und reagiert ueberhaupt nicht.\n");
+   SetProp(P_RESISTANCE_STRENGTHS,
+    ([DT_SLASH:     0.1,
+      DT_MAGIC:    -1.0,
+      DT_BLUDGEON: -0.5,
+      DT_POISON:    0.25,
+      DT_HOLY:     -1.0,
+      DT_RIP:       0.25,
+      DT_FIRE:      0.25,
+      DT_PIERCE:   -0.5,
+      DT_WHIP:     -1.0 ]) );
+   AddCmd(({"osten", "westen"}), "cmd_blocken");
+}
+
+static string _query_info()
+{
+   if (!PL || PL->QueryProp(ZAUBERWALD)<=time())
+      return "Die alte Eiche ist Dir sehr friedlich gesonnen. Es ist jedoch auch sicher\n"
+            +"klug dieses nicht zu aendern, da sie mit ihren Aesten wohl auch sehr kraeftig\n"
+            +"zuschlagen kann.\n";
+   return "Du hast den Zorn der alten Waechtereiche auf Dich gezogen, das war ganz und\n"
+         +"gar nicht klug von Dir. Jetzt lebe auch mit den Konsequenzen....\n";
+}
+
+static int cmd_blocken()
+{
+   if (PL->QueryProp(P_RACE)=="Dunkelelf" &&
+       PL->QueryProp(AUSGANG)==query_verb()) {
+      write(BS(Name(WER, 1)+" laesst Dich nicht vorbei.")
+           +break_string("Du solltest hier besser verschwinden, "
+                        +"so Typen wie Du sind hier nicht gern gesehn!",
+                        78, Name(WER, 1)+" sagt: "));
+      return 1;
+   }
+   if (PL && PL->QueryProp(ZAUBERWALD) &&
+       PL->QueryProp(AUSGANG)==query_verb()) {
+      write(BS(Name(WER, 1)+" steht Dir da leider im Weg und laesst Dich nicht vorbei."));
+      return 1;
+   }
+}
+
+int remove()
+{
+   call_other(ROOM("weg1"), "delay_reset");
+   return (int)::remove();
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/waechter\n");
+}
diff --git a/doc/beispiele/zauberwald/obj/feenleiche.c b/doc/beispiele/zauberwald/obj/feenleiche.c
new file mode 100644
index 0000000..0e7e034
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/feenleiche.c
@@ -0,0 +1,24 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+
+inherit "std/corpse";
+
+int mampf( string str )
+{
+   object ob;
+   if (QueryDecay()<3) return (int)::mampf(str);
+   notify_fail("Was moechtest Du essen?\n");
+   if (!str || !id(str)) return 0;
+   if (!PL->eat_food(8)) return 1; // fehlermeldung gibt eat_food aus
+   if (!objectp(ob=present(WALDID("leichenmp"), PL))) {
+      ob=clone_object(OBJ("leichenmp"));
+      ob->move(PL, M_NOCHECK|M_GET);
+   }
+   ob->new_corpse();
+   PL->restore_spell_points(50+random(100));
+   write("Du merkst wie die noch im Koerper verbliebene Energie in Dich ueberfliesst.\n");
+   remove();
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/obj/hahnenfuss.c b/doc/beispiele/zauberwald/obj/hahnenfuss.c
new file mode 100644
index 0000000..8992e46
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/hahnenfuss.c
@@ -0,0 +1,32 @@
+#include <items/kraeuter/kraeuterliste.h>
+#include <items/kraeuter/kraeuter.h>
+#include "../files.h"
+
+inherit STDPLANT;
+
+void create()
+{
+   ::create();
+   customizeMe(WASSER_HAHNENFUSS_WEISS);
+}
+
+/*varargs int move(mixed dest, int method)
+{
+   // die Einwohner des Zauberwalds sehen es nicht gerne, wenn jemand ihre
+   // magischen Pflanzen pflueckt...
+   int res;
+   res=(int)::move(dest, method);
+   if (res!=1) return res;
+   if (environment()) 
+     environment()->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   return 1;
+}*/
+
+protected void NotifyMove(object dest, object oldenv, int method) {
+  if ( !oldenv && objectp(dest) && query_once_interactive(dest) &&
+       strstr(object_name(environment(dest)),"zauberwald")>-1) {
+    dest->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+  }
+  return ::NotifyMove(dest, oldenv, method);
+}
+
diff --git a/doc/beispiele/zauberwald/obj/kamm.c b/doc/beispiele/zauberwald/obj/kamm.c
new file mode 100644
index 0000000..b26d6f8
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/kamm.c
@@ -0,0 +1,39 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/weapon";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein langer Kamm");
+   SetProp(P_NAME, "Kamm");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_LONG,
+     "Dieser schoene Kamm gehoerte einmal einer Waldfee die damit immer ihr schoenes\n"
+    +"langes Haar kaemmte...\n");
+   AddAdjective("kamm");
+   AddId("kamm");
+   SetProp(P_WEAPON_TYPE, WT_CLUB);
+   SetProp(P_DAM_TYPE, DT_PIERCE);
+   SetProp(P_NR_HANDS, 1);
+   SetProp(P_WC, 100);
+   SetProp(P_VALUE, 100);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_MATERIAL, ({ MAT_MISC_MAGIC, MAT_HORN }) );
+   AddCmd("kaemme", "cmd_kaemmen");
+}
+
+static int cmd_kaemmen(string str)
+{
+   notify_fail("Was moechtest Du denn kaemmen?\n");
+   if (str!="haare") return 0;
+   write("Eitel wie Du bist, versuchst Du Dir mit dem Kamm die Haare zu kaemmen, doch\n"
+        +"irgendwie ist er ein bisschen zu gross fuer Deine Haare.\n");
+   say(BS("Eitel wie "+PL->QueryPronoun()+" ist, kaemmt sich "+PL->name(WER)
+         +" die Haare. Doch irgendwie ist der Kamm ein bisschen zu gross fuer "
+         +PL->QueryPossPronoun(NEUTER, WEN, 1)+" kurzen Haare."));
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/obj/kleid.c b/doc/beispiele/zauberwald/obj/kleid.c
new file mode 100644
index 0000000..f52e157
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/kleid.c
@@ -0,0 +1,38 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/armour";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_NAME, "Blaetterkleid");
+   SetProp(P_SHORT, "Ein Blaetterkleid");
+   SetProp(P_GENDER, NEUTER);
+   SetProp(P_LONG,
+     "Das Blaetterkleid stammt von einer Waldfee und war genau auf ihre Rundungen\n"
+    +"und ihre Groesse abgepasst. Du hast leider nicht die geringste Chance, dieses\n"
+    +"Kleid jemals tragen zu koennen.\n");
+   AddId(({"kleid", "blaetterkleid"}));
+   SetProp(P_MATERIAL, MAT_MISC_WOOD);
+   SetProp(P_ARMOUR_TYPE, AT_ARMOUR);
+   SetProp(P_VALUE, 500);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_AC, 10);
+   SetProp(P_WEAR_FUNC, ME);
+}
+
+int WearFunc(object me, int silent)
+{
+   if (!PL || query_once_interactive(PL) || getuid(PL)!=getuid() ||
+       PL->QueryProp(P_RACE)!="Fee") {
+      if (!silent)
+        write("Dieses Kleid war genau auf die Rundungen und die Groesse der Waldfee\n"
+             +"angepasst von der es stammt. Du hast leider nicht die geringste Chance,\n"
+             +"dieses Kleid jemals tragen zu koennen.\n");
+      return 0;
+   }
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/obj/leichenmp.c b/doc/beispiele/zauberwald/obj/leichenmp.c
new file mode 100644
index 0000000..aea7c10
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/leichenmp.c
@@ -0,0 +1,81 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+/* Changelog:
+   * 09.11.06 Zesstra
+     object_info()[11] durch query_next_reset() ersetzt.
+     */
+#include "../files.h"
+
+inherit "/std/thing";
+
+static int leichen;
+
+void create()
+{
+    leichen=0;
+    if (!clonep(ME))
+       set_next_reset(-1);
+    else {
+       ::create();
+       SetProp(P_INVIS, 1);
+       SetProp(P_NODROP, 1);
+       SetProp(P_NEVERDROP, 1);
+       AddId(WALDID("leichenmp"));
+       set_next_reset(3600*3); // erster reset nach 3h
+    }
+}
+
+int remove()
+{
+    closure clo;
+    if (environment()) {
+      clo=environment()->Query(P_MAX_SP, F_QUERY_METHOD);
+      if (clo && to_object(clo)==ME)
+          environment()->Set(P_MAX_SP, 0, F_QUERY_METHOD);
+    }
+    destruct(ME);
+    return 1;
+}
+
+int calculate_mp()
+{
+    int mp;
+    switch(leichen) {
+       case 1:  mp = 5;  break;
+       case 2:  mp = 9;  break;
+       case 3:  mp = 12; break;
+       case 4:  mp = 14; break;
+       case 5:  mp = 15; break;
+       default: mp = 0;
+    }
+    SetProp(P_X_HEALTH_MOD, ([P_SP:mp]) );
+}
+
+void new_corpse()
+{
+    closure clo;
+    clo=PL->Query(P_MAX_SP, F_QUERY_METHOD);
+    if (clo && to_object(clo)!=ME) {
+       call_out("remove", 0);
+       return;
+    }
+    if (leichen<5) {
+       leichen++;
+       set_next_reset(3600+3);
+    }
+    else set_next_reset( (query_next_reset(ME)-time())+3600 );
+    calculate_mp();
+}
+
+void reset()
+{
+   leichen--;
+   if (environment()) {
+      tell_object(environment(), "Du spuerst wie Deine mentalen Kraefte schwaecher werden...\n");
+      if (environment()->QueryProp(P_SP) > environment()->QueryProp(P_MAX_SP))
+          environment()->SetProp(P_SP, environment()->QueryProp(P_MAX_SP));
+   }
+   calculate_mp();
+   if (leichen<=0)
+      remove();
+   else set_next_reset(3600);
+}
diff --git a/doc/beispiele/zauberwald/obj/stock.c b/doc/beispiele/zauberwald/obj/stock.c
new file mode 100644
index 0000000..f79d5e4
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/stock.c
@@ -0,0 +1,26 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/weapon";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein kleiner Zeigestock");
+   SetProp(P_NAME, "Zeigestock");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_LONG,
+     "Ein kleiner Stock, mit dem man gut Dinge zeigen oder in den Sand malen kann.\n");
+   AddAdjective("klein");
+   AddId(({"stock", "zeigestock"}));
+   SetProp(P_WEAPON_TYPE, WT_STAFF);
+   SetProp(P_SIZE, 120);
+   SetProp(P_DAM_TYPE, DT_BLUDGEON);
+   SetProp(P_NR_HANDS, 1);
+   SetProp(P_WC, 120);
+   SetProp(P_VALUE, 300);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_MATERIAL, MAT_MISC_WOOD);
+}
diff --git a/doc/beispiele/zauberwald/obj/tarnzauber.c b/doc/beispiele/zauberwald/obj/tarnzauber.c
new file mode 100644
index 0000000..c226494
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/tarnzauber.c
@@ -0,0 +1,78 @@
+// (c) 2003 by Padreic (Padreic@mg.mud.de)
+// Das Objekt realisiert einen Tarnzauber, aehnlich
+// dem Tarnhelm. Jedoch ohne Shadow und nur auf die
+// Rasse beschraenkt.
+
+#include <properties.h>
+#include <language.h>
+#include <moving.h>
+#include <defines.h>
+
+inherit "/std/thing";
+
+static string race;
+
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, 0);
+  SetProp(P_LONG, "Tarnzauber");
+  SetProp(P_NAME, "Tarnzauber");
+  SetProp(P_INVIS, 1);
+  SetProp(P_GENDER, MALE);
+  SetProp(P_VALUE,  0);
+  SetProp(P_NOGET, 1);
+  SetProp(P_WEIGHT, 0);
+  Set(P_DEFEND_FUNC, ME);
+  AddId("\ntarnzauber");
+}
+
+// die NPCs im Zauberwald durchschauen den Zauber... :o)
+string _query_race()
+{
+   if (previous_object(1) && getuid(previous_object(1))==getuid())
+      return previous_object()->_query_race()||race;
+   return "Dunkelelf";
+}
+
+void Initialize(object pl)
+{
+   object *armours;
+   pl->Set(P_RACE, #'_query_race, F_QUERY_METHOD);
+   armours=(pl->QueryProp(P_ARMOURS));
+   if (member(armours, ME)>=0) return 0;
+   pl->SetProp(P_ARMOURS, armours+({ ME }));
+   race=pl->Query(P_RACE);
+}
+
+int QueryDefend(string *dtyp, mixed spell, object enemy)
+{
+  mixed am;
+  // noch ein paar paranoide Sicherheitsabfragen... :o)
+  if (!previous_object() ||
+      !pointerp(am=previous_object()->QueryProp(P_ARMOURS)) ||
+      member(am, ME)==-1) return 0;
+  tell_object(previous_object(), "Dein Tarnzauber loest sich auf.\n");
+  remove();
+}
+
+int DefendFunc(string *dtyp, mixed spell, object enemy)
+{
+   return QueryDefend(dtyp, spell, enemy);
+}
+
+varargs int move(mixed dest, int method)
+// beim Tod soll sich der Zauber entfernen und auch nirgends rumfliegen
+{
+   int res;
+   res=(int)::move(dest, method);
+   if (!living(environment())) remove();
+   return res;
+}
+
+varargs int remove(int silent)
+{
+  if (living(environment())) environment()->Set(P_RACE,0,F_QUERY_METHOD);
+  return (int)::remove(silent);
+}
diff --git a/doc/beispiele/zauberwald/obj/zauberstab.c b/doc/beispiele/zauberwald/obj/zauberstab.c
new file mode 100644
index 0000000..1e01fa6
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/zauberstab.c
@@ -0,0 +1,36 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/weapon";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein Zauberstab");
+   SetProp(P_NAME, "Zauberstab");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_LONG,
+     "Dies war einmal der Zauberstab einer Waldfee aus dem Zauberwald. In dem Stab\n"
+    +"liegt sicherlich noch eine grosse Magie verborgen, doch nutzen kannst Du sie\n"
+    +"nicht.\n");
+   AddId(({"stab", "zauberstab"}));
+   SetProp(P_WEAPON_TYPE, WT_CLUB);
+   SetProp(P_DAM_TYPE, ({ DT_MAGIC, DT_BLUDGEON }) );
+   SetProp(P_NR_HANDS, 1);
+   SetProp(P_WC, 140);
+   SetProp(P_VALUE, 800);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_HIT_FUNC, ME);
+   SetProp(P_MATERIAL, ({ MAT_MISC_MAGIC, MAT_MISC_WOOD }) );
+}
+
+int HitFunc(object enemy)
+{
+    object ob;
+    ob=QueryProp(P_WIELDED);
+    if (ob && !query_once_interactive(ob) && getuid(ob)==getuid() &&
+        ob->QueryProp(P_RACE)=="Fee") return 100+random(300);
+    return 0;
+}
diff --git a/doc/beispiele/zauberwald/room/eingang.c b/doc/beispiele/zauberwald/room/eingang.c
new file mode 100644
index 0000000..058a05e
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/eingang.c
@@ -0,0 +1,48 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Auf einem kleinen Waldweg");
+   SetProp(P_INT_LONG,
+     "Du stehst auf einem kleinen Waldweg der nach Westen hin tiefer in den Wald\n"
+    +"hinein fuehrt. Nach Osten kannst Du jedoch auch wieder zurueck zur Kreuzung\n"
+    +"gelangen. Alles ist hier recht duester, denn das Zweigdach der Baeume laesst\n"
+    +"kaum noch Sonnenlicht hindurch.\n");
+   AddDetail("wald", QueryProp(P_INT_LONG));
+   AddDetail(({"boden", "weg", "erde", "waldweg"}),
+     "Der Weg wurde nicht richtig angelegt und es scheint auch nicht so, als wuerde\n"
+    +"ihn jemand pflegen. Dennoch wachsen keinerlei Pflanzen auf dem Weg und Du\n"
+    +"gehst auf der blossen Erde.\n");
+   AddDetail(({"wegrand", "wegesrand", "gestruepp"}),
+     "Am Wegesrand wachsen einige alte Baeume und andere Pflanzen die zusammen ein\n"
+    +"undurchdringliches Gestruepp ergeben. Dir bleibt also nichts weiter uebrig, als\n"
+    +"nur den Weg nach Westen oder nach Osten zu folgen.\n");
+   AddDetail(({"baeume", "alter"}),
+     "Das Alter der Baeume laesst sich nicht genau bestimmen, sie scheinen jedoch\n"
+    +"sehr sehr alt zu sein. In einem der Baeume siehst Du ein kleines Baumhaus.\n");
+   AddDetail(({"pflanzen", "farne", "straeucher"}),
+     "Verschiedene Straeucher, Farne und zahlreiche Baeume zieren den Wegesrand.\n"
+    +"Du entdeckst dabei aber nichts weiter auffaelliges.\n");
+   AddDetail(({"osten", "kreuzung"}),
+     "Wenn Du dem Weg nach Osten hin folgst, kannst Du zurueck zur Kreuzung gelangen.\n");
+   AddDetail(({"zweige", "zweigdach", "sonnenlicht", "licht", "dach", "westen"}),
+     "Das Zweigdach der Baeume laesst hier so wenig Sonnenlicht hindurch, das Du ein\n"
+    +"Stueck weiter im Westen kaum noch ohne eigene Lichtquelle weiterkommen kannst.\n"
+    +"Du solltest Dich also besser nicht ohne eigene Lichtquelle tiefer in den Wald\n"
+    +"hinein wagen.\n");
+   AddDetail(({"fackel", "lampe", "licht", "lichtquelle", "lichtspruch"}),
+     "Wenn Du beabsichtigst weiter nach Westen zu gehn, solltest Du eine Fackel,\n"
+    +"eine Lampe oder sonst irgendeine Lichtquelle mitnehemn. Zumindest ist es dort\n"
+    +"sehr dunkel.\n");
+   AddDetail(({"wolke", "wolken", "sonne", "himmel"}),
+     "Der Himmel ist durch das dichte Dach der Zweige, nicht mehr zu sehn.\n");
+   AddExit("osten", "/d/unterwelt/raeume/wald4");
+   AddExit("westen", ROOM("weg1"));
+}
diff --git a/doc/beispiele/zauberwald/room/huette.c b/doc/beispiele/zauberwald/room/huette.c
new file mode 100644
index 0000000..e19a272
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/huette.c
@@ -0,0 +1,129 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Ein Raum zum schoenen einbinden eines Seherhauses in den Wald
+
+#include "../files.h"
+#include <moving.h>
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 1);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Mitten im Wald");
+   SetProp(P_INT_LONG,
+     "Du stehst nun inmitten des Zauberwalds genau vor einer riesigen Buche unter\n"
+    +"der jemand eine kleine Huette gebaut hat. Ringsumher stehen weitere Buesche\n"
+    +"und Baeume und bilden eine dichte Vegetation, doch im Vergleich zu dieser\n"
+    +"riesigen Buche wirkt alles andere wirklich mickrig. Durch das dichte\n"
+    +"Blaetterdach dringt nur wenig Licht und so wundert es auch nicht das der\n"
+    +"Boden hier relativ feucht ist und die Pflanzen so gut gedeihen koennen. Nach\n"
+    +"Norden fuehrt als einziger Ausgang ein kleiner Trampelpfad zur Lichtung.\n");
+   AddDetail(({"natur", "wald", "zauberwald"}), QueryProp(P_INT_LONG));
+   AddDetail(({"buesche", "baeume", "vegetation", "pflanzen", "farne"}),
+     "Rings um die Huette herscht eine wilde Vegetation. Es wachsen verschiedenste\n"
+    +"Farne und Buesche und eine vielfalt verschiedenster Baeume. Alles zusammen\n"
+    +"bildet eine fast undurchdringliche Vegetation.\n");
+   AddDetail(({"licht", "blaetterdach"}),
+     "Durch das relativ dichte Blaetterdach der hohen Baeume, faellt eigentlich nur\n"
+    +"sehr wenig Licht durch und so ist es hier doch schon relativ duester, auch\n"
+    +"wenn man noch nicht unbedingt eine eigene Lichtquelle braucht um etwas sehen\n"
+    +"zu koennen.\n");
+   AddDetail("lichtquelle",
+     "Eine eigene Lichtquelle ist hier nicht unbedingt erforderlich, da dann doch\n"
+    +"noch genuegend Licht durch das Blaetterdach durchdringt.\n");
+   AddDetail("himmel",
+     "Es scheint Dir als wuerde die Sonne gerade scheinen, auch wen das dichte\n"
+    +"Blaetterdach die meisten Sonnenstrahlen nicht hindurch laesst.\n");
+   AddDetail("boden",
+     "Der Boden ist hier eigentlich, mit Ausnahme des Trampelpfads natuerlich,\n"
+    +"ziemlich zugewachsen und von zahlreichen Pflanzen ueberwuchert.\n");
+   AddDetail("erde",
+     "Die Erde ist hier ueberall ein wenig lehmig, aber wirklich besonderes kannst\n"
+    +"Du an der Erde nicht entdecken.\n");
+   AddDetail(({"trampelpfad", "ausgang", "pfad"}),
+     "Der Trampelpfad scheint doch relativ oft benutzt zu werden, denn die Erde ist\n"
+    +"fast voellig bloss gelegt und die wenigen Pflanzen die dann doch versuchen ihn\n"
+    +"zu bewachsen sind fast alle niedergetrampelt.\n");
+   AddDetail(({"lichtung", "norden"}),
+     "Vielleicht solltest Du einfach dem Trampelpfad nach Norden folgen und Dir die\n"
+    +"Lichtung einfach aus der Naehe anschauen.\n");
+   AddDetail(({"buche", "riesige buche"}),
+     "Eichen sollst Du weichen, Buchen sollst Du suchen!\n");
+   AddDetail(({"eiche", "eichen"}),
+     "Du siehst zwar alles moegliche an Baeumen hier, aber Eichen befinden sich zum\n"
+    +"Glueck nicht dadrunter.\n");
+   AddDetail(({"glueck", "frage"}),
+     "Ob es soetwas wie Glueck ueberhaupt gibt, ist wohl eher eine philosophische\n"
+    +"Frage und etwas wo man stundenlang drueber diskutieren koennte. Fuer den\n"
+    +"Moment beschliesst Du jedenfalls lieber die schoene Natur zu geniessen und\n"
+    +"dem zwitschern der Voegel zu lauschen, als Dich mit soetwas zu beschaeftigen.\n");
+   AddDetail(({"voegel", "zipfel", "baumzipfel", "zipfel der baeume"}),
+     "Oben in den Zipfeln der Baeume kannst Du wage einige Voegel erkennen, doch um\n"
+    +"diese naeher spezifizieren zu koennen, sind diese dann doch zu weit weg.\n");
+   AddDetail("moment",
+     "Geniesse den Moment und lebe Dein Leben!\n");
+   AddDetail("ruhe",
+     "Die Ruhe wird hier und da lediglich vom zwitschern einiger Voegel unterbrochen.\n");
+   AddSpecialDetail(({"huette"}), "det_huette");
+   AddSounds(SENSE_DEFAULT,
+     "Es ist hier wirklich herrlich ruhig und nur hier und da hoerst Du das\n"
+    +"zwitschern einiger Voegel. Natur pur.\n");
+   AddSounds(({"voegel", "zwitschern", "voegel zwitschern"}),
+     "Du lauschst dem zwitschern der Voegel und geniesst die himmlische Ruhe.\n");
+   AddCmd(({"such", "suche"}), "cmd_suchen");
+   AddCmd(({"geniess", "geniesse"}), "cmd_geniessen");
+   AddCmd(({"leb", "lebe"}), "cmd_leben");
+   AddCmd(({"kletter", "klettere"}), "cmd_klettern");
+   AddExit("norden", ROOM("lichtungs"));
+}
+
+static string det_huette()
+// Langbeschreibung nicht fest setzen, damit der Spieler sie selbst
+// aendern kann.
+{
+   object ob;
+   if (ob=present("\nmorgeneshaus", ME))
+      return ob->long();
+}
+
+static int cmd_suchen(string str)
+{
+   notify_fail("WAS moechtest Du suchen?\n");
+   if (str!="buchen" && str!="buche") return 0;
+   write("Du brauchst nicht lange suchen und schon entdeckt Du eine riesige Buche vor\n"
+        +"Dir, aber eigentlich waere es wohl auch eher erstaunlich, wenn Du diese\n"
+        +"riesige Buche direkt vor Deiner Nase uebersehen wuerdest :).\n");
+   return 1;
+}
+
+static int cmd_geniessen(string str)
+{
+   notify_fail("WAS moechtest Du geniessen?\n");
+   if (str!="moment" && str!="den moment" && str!="ruhe") return 0;
+   write("Du haeltst einen Moment inne und geniesst die himmlische Ruhe, die nur durch\n"
+        +"das zwitschern einiger Voegel durchbrochen aber nicht gestoert wird.\n");
+   return 1;
+}
+
+static int cmd_leben(string str)
+{
+   notify_fail("WAS moechtest Du leben?\n");
+   if (str!="leben" && str!="mein leben" && str!="dein leben") return 0;
+   write("Nun, wenn die Welt so einfach waere das Du mit einem simplen Kommando Dein\n"
+        +"ganzes Leben steuern koenntest, dann waer die Welt doch wirklich langweilig,\n"
+        +"oder? Ich will doch stark hoffen, das es sooo weit noch nicht bei Dir ist :).\n");
+   return 1;
+}
+
+static int cmd_klettern(string str)
+{
+   notify_fail("WOHIN oder WORAUF moechtest Du klettern?\n");
+   if (member(({"auf baum", "auf baumzipfel", "baum hoch",
+                "buche hoch", "auf buche"}), str)==-1) return 0;
+   write("Du versuchst vergeblich die riesige Buche hochzuklettern, doch die unteren\n"
+        +"Aeste haengen leider bereits viel zu hoch, um diese erklimmen zu koennen.\n");
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/room/schule.c b/doc/beispiele/zauberwald/room/schule.c
new file mode 100644
index 0000000..a97acc4
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/schule.c
@@ -0,0 +1,78 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   AddSpecialDetail(({"pixieschule", "schule", "sandplatz", "waldschule"}), "_query_int_long");
+   AddDetail(({"spuren", "kampfplatz", "sand"}),
+     "Die Spuren im Sand deuten auf einen laengeren Kampf hin, der hier getobt\n"
+    +"haben muss. Wer auch immer ihn verloren hat, er hat sich wacker gewehrt.\n");
+   AddDetail("wald",
+     "Was meinst Du eigentlich, wo Du gerad die ganze Zeit rumlaeufst? Mach einfach\n"
+    +"die Augen auf und schau Dir alles in Ruhe an.\n");
+   AddDetail("ruhe", "In der Ruhe liegt die Kraft...\n");
+   AddDetail(({"augen", "details", "kampfzauber", "kopf", "freund"}),
+     "Nu uebertreib mal nich, nicht jedes Substantiv verbirgt wirklich ein\n"
+    +"sinnvolles Detail.\n");
+   AddDetail("kraft",
+     "Wow! Deine Kraft ist ploetzlich auf 32 angestiegen...\n"
+    +"Das hast Du jetzt aber nicht wirklich geglaubt, oder?\n"
+    +"Wieso untersuchst Du solche Details eigentlich?\n");
+   AddSpecialDetail("zeit", "det_zeit");
+   AddDetail(({"pixies", "bloedsinn", "unfug", "zauberwesen", "streich"}), 
+     "Pixies sind kleine Zauberwesen, die nichts als Unfug im Kopf haben. Wie\n"
+    +"niemand sonst nutzen sie ihre magischen Faehigkeiten nicht um jemanden zu\n"
+    +"heilen oder fuer Kampfzauber. Nein sie nutzen sie um jemanden zu Aergern\n"
+    +"oder ihm einen Streich zu spielen. Einen Pixie zum Freund zu haben, kann\n"
+    +"sicher sehr unterhaltsam sein, auf die Dauer aber wohl auch ziemlich\n"
+    +"anstrengend.\n");
+   AddSpecialDetail("boden", "det_boden");
+   AddDetail("halbkreis",
+     "Einige Pixies sitzen im Halbkreis um Arina herum und hoeren gespannt zu, wie\n"
+    +"sie ihnen einen spannende Geschichte erzaehlt.\n");
+   AddDetail(({"geschichten", "sprache"}),
+     "Wenn Arina doch bloss in einer Sprache sprechen wuerde, Die Du verstehst...\n"
+    +"Ihre Geschichten hoeren sich jedenfalls ausserordentlich spannend an. *seufz*\n");
+   AddDetail("himmel", "Der Himmel ist klar und nahezu wolkenfrei.\n");
+   AddDetail(({"osten", "ausgang", "lichtung", "weg", "waldweg"}),
+     "Der einzige Ausgang von hier, ist der kleine Waldweg im Osten der zurueck\n"
+    +"zur grossen Lichtung fuehrt.\n");
+   SetProp(P_INT_SHORT, "Die Pixieschule");
+   AddExit("osten", ROOM("lichtungnw"));
+   AddItem(NPC("pixie"), REFRESH_MOVE_HOME);
+   AddItem(NPC("pixie"), REFRESH_MOVE_HOME);
+   AddItem(NPC("pixie"), REFRESH_MOVE_HOME);
+   AddItem(NPC("arina"), REFRESH_REMOVE, 1);
+}
+
+static string det_boden()
+{
+   if (present(WALDID("fee"), ME))
+      return GetDetail("halbkreis");
+   return GetDetail("sand");
+}
+
+static string det_zeit()
+{  return "Wir haben genau "+dtime(time())[<8..]+".\n"; }
+
+static string _query_int_long()
+{
+   if (present(WALDID("fee"), ME))
+      return "Du befindest Dich in der Waldschule der Pixies. Einige Pixies sitzen im\n"
+            +"Halbkreis um die Waldfee Arina rum und hoeren gespannt ihren Geschichten zu.\n"
+            +"Gelegentlich erhebt sich Arina um mit einem Stock etwas in den Sand zu\n"
+            +"zeichnen, oder um einen der Pixies zu ermahnen weil er wieder irgendeinen\n"
+            +"verrueckten Bloedsinn gemacht hat. Da sich ringsherum der dichte Wald\n"
+            +"anschliesst, ist der einzige Ausgang, der Weg zurueck nach Osten auf die\n"
+            +"grosse Lichtung.\n";
+   return "Du stehst auf einem kleinen Sandplatz mitten im Wald. Hier und da siehst Du\n"
+         +"im Sand noch deutlich die Spuren eines Kampfes. Umgeben wird dieser Platz\n"
+         +"von einem dichten Wald, so dass der einzige Ausgang der Weg zurueck nach\n"
+         +"Osten zur grossen Lichtung ist.\n";
+}
diff --git a/doc/beispiele/zauberwald/room/stdlichtung.c b/doc/beispiele/zauberwald/room/stdlichtung.c
new file mode 100644
index 0000000..341ee6e
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/stdlichtung.c
@@ -0,0 +1,157 @@
+// (c) by Thomas Winheller (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+
+inherit ROOM("stdroom");
+inherit "/std/room/kraeuter";
+
+void maybe_replace_program()
+// dieser Standardraum, darf _nicht_ replaced werden...
+{ }
+
+int tuempel_ex(string exit, mapping map_ldfied)
+{   return map_ldfied[exit]==ROOM("tuempel");  }
+
+static int plant;
+
+void create()
+{
+   int i;
+   string tuempel, dir;
+   mixed tmp;
+
+   if (!clonep(ME)) return;
+   ::create();
+   plant=0;
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Am Rande der Zauberlichtung");
+   SetProp(EXTRA_LONG, "");
+   if (PO) dir=(PO->CustomizeObject());
+   if (!dir) return;
+   dir=(["o":"ost", "w":"west", "n":"nord", "s":"sued",
+         "no":"nordost", "nw":"nordwest",
+         "so":"suedost", "sw":"suedwest"])[dir[8..]];
+   tuempel=filter(m_indices(QueryProp(P_EXITS)||([])), "tuempel_ex", ME, QueryProp(P_EXITS)||([]))[0][0..<3];
+   dir=capitalize(dir); tuempel=capitalize(tuempel);
+   SetProp(P_INT_LONG, BS(
+     "Du stehst am "+dir+"rand der grossen Lichtung inmitten des Zauberwalds. "
+    +tuempel+"lich von hier, befindet sich genau in der Mitte der "
+    +"Lichtung ein kleiner Tuempel in dessen Wasser sich das Sonnenlicht in "
+    +"allen Farben des Regenbogens spiegelt. Hier und da stehen um den Teich "
+    +"herum vereinzelt einige Eichen die sich irgendwie zu bewegen "
+    +"scheinen und ab und zu siehst Du wie sich einige kleine Pixies aus "
+    +"dem Wald heraus ans Wasser trauen. Die Eichen jedoch, halten immer "
+    +"einen deutlichen Abstand zum Wasser."+QueryProp(EXTRA_LONG)));
+   AddDetail(({"raum", lower_case(dir)+"rand", "zauberwald"}), QueryProp(P_INT_LONG));
+   AddDetail(({"pixies", "zauberwesen", "unfug"}),
+     "Pixies sind kleine verspielte Zauberwesen, die hier im Zauberwald wohnen. Um\n"
+    +"einem von ihnen zu begegnen wirst Du hier im Wald sicher nich lange suchen\n" 
+    +"muessen, doch vorsicht, sie haben nichts als Unfug im Kopf...\n");
+   AddDetail(({"farben", "regenbogen", "computer"}),
+     "Noch nie einen Regenbogen gesehn? Hmm.. dann sitzt Du wirklich eindeutig\n"
+    +"zuviel vor Deinem Computer...\n");
+   AddDetail("abstand",
+     "Wieso sie diesen Abstand halten kannst Du nicht nachvollziehn, aber mehr als\n"
+    +"ein paar Meter gehen sie nie an den alten Weiher dran.\n");
+   AddDetail(({"sonne", "sonnenstrahlen", "sonnenlicht", "himmel", "herz"}),
+     "Zahlreiche warme Sonnenstrahlen erwaermen Dein Herz und Du bist richtig\n"
+    +"gluecklich. Solch ein Idyllisches Plaetzchen willst Du am liebsten nie\n"
+    +"wieder verlassen. Fehlt eigentlich nur noch ein Partner, mit dem man\n"
+    +"hier gemeinsam in der Sonne liegen und das rauschen des Wassers geniessen\n"
+    +"kann.\n");
+   AddDetail("partner", "Den musst Du Dir schon selbst mitbringen...\n");
+   AddDetail(({"wald", "zauberwald"}),
+     "Du befindest Dich quasi mittem ihn ihm. Rund herum um die Lichtung schliesst\n"
+    +"sich ein dichter Wald an.\n");
+   AddDetail(({"eiche", "eichen"}),
+     "Hier befindet sich gerade keine, so dass Du sie nich naeher ansehn kannst.\n");
+   AddDetail(({"lichtung", "rand", "plaetzchen"}), QueryProp(P_INT_LONG));
+   AddDetail(({"wasser", "tuempel", "teich", lower_case(tuempel)+"en", "mitte"}),
+     "Wenn Du Dir den Tuempel in der Mitte der Lichtung etwas naeher ansehen\n"
+    +"moechtest, solltest Du vielleicht einfach noch ein bisschen naeher rangehn.\n");
+   AddDetail(({"waldweg", "weg"}),
+     "Ueber den Waldweg kannst Du den Wald wieder verlassen wenn Du moechtest.\n");
+   AddDetail(({"boden"}),
+     "Der Boden ist hier nirgends nackt sichtbar, sondern ist mit einem schoenen\n"
+    +"gruenen Rasenteppich bedeckt. Nicht zu hoch und nicht zu tief, offensichtlich\n"
+    +"bedarf diese Grasart keinerlei Pflege oder aber irgendjemand pflegt diesen\n"
+    +"Rasen hier seeehhhhrrr gruendlich.\n");
+   AddDetail(({"grasart", "rasen", "art", "gras", "rasenteppich", "halme"}),
+     "Du schaust Dir den Rasen noch einmal gruendlich an und streichst mit Deiner\n"
+    +"Hand durch die Halme. Was auch immer das fuer eine Art ist, solch einen Rasen\n"
+    +"hast Du noch nicht gesehn.\n");
+   AddDetail("hand",
+     "Sei lieber vorsichtig, sonst ist die Hand schneller ab als Du denkst...\n");
+   AddDetail("pflege",
+     "Ob jemand diesen Rasen pflegt, bzw. _wer_ kannst Du nicht entdecken...\n");
+   AddSounds(({"rauschen", "wasser"}), "Leise hoerst Du das rauschen des Wassers....\n");
+}
+
+#define VERB (["iss": "essen", "esse": "essen", "pflueck": "pfluecken", "pfluecke": "pfluecken"])
+
+static int cmd_pilze(string str)
+{
+   notify_fail("Was moechtest Du "+VERB[query_verb()]+"?\n");
+   if (str!="pilz" && str!="pilze") return 0;
+   if (plant>time()) {
+      write("Du solltest die Pilze erstmal in Ruhe wieder etwas nachwachsen lassen.\n");
+      return 1;
+   }
+   if (PL->QueryProp(ZAUBERWALD)<=time()) {
+      write("Du bist nur Gast hier und die Bewohner des Zauberwalds, sehen es nicht gerne\n"
+           +"wenn man hier einfach so die Pilze pflueckt.\n");
+      return 1;
+   }
+   plant=time()+300;
+   write("Du pflueckst Dir einige Pilze und isst sie. Anschliessend geht es Dir\n"
+        +"bedeutend besser.\n");
+   PL->reduce_hit_points( negate(100+random(100)) );
+   return 1;
+}
+
+static int cmd_farne(string str)
+{
+   int food;
+   notify_fail("Was moechtest Du "+VERB[query_verb()]+"?\n");
+   if (str!="farn" && str!="farne") return 0;
+   if (PL->QueryProp(ZAUBERWALD)<=time()) {
+      write("Du bist nur Gast hier und die Bewohner des Zauberwalds, sehen es nicht gerne\n"
+           +"wenn man hier einfach so den Farn abreisst.\n");
+      return 1;
+   }
+   // das tanken am Wasser ist umsonst, es heilt dabei wie ein
+   // mittleres Kneipenessen das genau 1 Muenze kostet. Geheilt werden nur HP
+   // Ein Missbrauch ist im Wald ausgeschlossen, bzw. man muesste den
+   // gesamten Wald leermetzeln und kann dann hier tanken bis zum naechsten
+   // reset. Bei Kosten von einer Muenze pro Heilung ist es sehr fraglich
+   // ob sich das lohnt.... :)
+   food=(PL->QueryProp(P_MAX_FOOD)) - (PL->QueryProp(P_FOOD));
+   if (food>10) food=10; // nie mehr als fuer 10 food tanken...
+   if (food <= 0 || !PL->eat_food(food, 1)) {
+      write("Du bist so voll, Du kannst leider wirklich nichts mehr essen...\n");
+      return 1;
+   }
+   write("Du pflueckst ein wenig von dem Farn und isst ihn. Sogleich spuerst Du, wie es\n"
+        +"Dir allmaehlich wieder besser geht...\n");
+   if (PL->eat_food(food)) { // food gutschreiben erfolgreich?
+      PL->buffer_hp(food*6, 8);
+      PL->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   }
+   return 1;
+}
+
+static int cmd_sueden()
+{
+   if (PL->QueryProp(ZAUBERWALD)>time()) {
+      write("Du versuchst in den Wald zu fluechten, doch die Farne und Buesche bilden\n"
+           +"eine pflanzliche Barriere und lassen Dich nicht hindurch.\n");
+      return 1;
+   }
+   write("Du machst einen Schritt hin nach Sueden und sofort biegen sich auf magische\n"
+        +"Weise die Farne und Buesche zur Seite und geben einen Trampelpfad nach Sueden\n"
+        +"frei.\n");
+   PL->move(ROOM("huette"), M_GO, "durch die Buesche nach Sueden", "zwaengt sich");
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/room/stdroom.c b/doc/beispiele/zauberwald/room/stdroom.c
new file mode 100644
index 0000000..35297e6
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/stdroom.c
@@ -0,0 +1,52 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/room";
+
+#include "../files.h"
+#include <moving.h>
+
+static string sounds();
+
+void create()
+{
+   ::create();
+   SetProp(P_NO_TPORT, NO_TPORT);
+   AddSmells(SENSE_DEFAULT,
+     "Der Duft vom Harz der Baeume und einiger sonstiger Pflanzen liegt in der Luft.\n"
+    +"Man merkt sofort, Du stehst mittem im Wald.\n");
+   AddSounds(SENSE_DEFAULT, #'sounds);
+   AddSounds(({"voegel", "voegeln", "zwitschern"}),
+     "Das herrliche zwitschern der Voegel, ist das einzige das die Ruhe im Wald\n"
+    +"durchbricht.\n");
+}
+
+static string sounds()
+{
+   if (sizeof(filter_objects(all_inventory(), "InFight")))
+      return "Der Laerm des Kampfes stoert die Ruhe des Waldes und uebertoent alles.\n";
+   if (sizeof(filter(all_inventory(), #'query_once_interactive))>1)
+      return "Es ist unheimlich still hier im Wald und nur das zwitschern einiger Voegel\n"
+            +"ist zu hoeren.\n";
+   return "Du hast das Gefuehl, als waerst Du ganz allein hier im Wald. Alles ist ruhig\n"
+         +"und nur hier und da vernimmst Du das zwitschern einiger Voegel.\n";
+}
+
+varargs void delay_reset(int time)
+// NPCs koennen boing resets verhindern
+{
+   if (time)
+      set_next_reset(time);
+   else set_next_reset(3600);
+}
+
+int _normalfunction()
+{
+  mixed z;
+  int i;
+  z=this_player()->QueryProp(AUSGANG);
+  this_player()->SetProp(AUSGANG, query_verb());
+  i=(int)::_normalfunction();
+  if (!i) this_player()->SetProp(AUSGANG, z);
+  return i;
+}
+              
\ No newline at end of file
diff --git a/doc/beispiele/zauberwald/room/stein.c b/doc/beispiele/zauberwald/room/stein.c
new file mode 100644
index 0000000..cd74b07
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/stein.c
@@ -0,0 +1,112 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Bei einem Stein");
+   AddSpecialDetail(({"ort", "wald", "platz"}), "_query_int_long");
+   AddDetail("stein",
+     "Der Stein ist, durch die Sonnenstrahlen ordentlich aufgeheizt, angenehm warm\n"
+    +"und bietet eigentlich den idealen Platz um es sich gut gehn zu lassen und in\n"
+    +"der Sonne zu liegen.\n");
+   AddDetail(({"sonne", "himmel", "sonnenstrahlen", "strahlen"}),
+     "Der blaue Himmel ist nahezu wolkenfrei und so strahlt die Sonne in voller\n"
+    +"Pracht oben am Himmel und ihre Strahlen prasseln auf Deine Haut.\n");
+   AddDetail(({"boden", "weg", "waldweg", "erde"}),
+     "Ein ganz normaler Waldweg halt, ein bisschen sandig, einige kleine Aestchen\n"
+    +"ganz normal halt.\n");
+   AddSpecialDetail("zeit", "det_zeit");
+   AddDetail(({"aestchen", "stoeckchen"}),
+     "Ganz kleine heruntergefallene Stoeckchen, durch reges drueber laufen\n"
+    +"im Laufe der Zeit kleingemalen und vom Wetter aufgeloest...\n");
+   AddDetail("wetter",
+     "Auch wenn hier heute die Sonne scheint, gibt es natuerlich auch hier\n"
+    +"gelegentlich verregnete Tage.\n");
+   AddDetail("tage", "Naja... allzuviele sind es jedoch nicht.\n");
+   AddDetail(({"nordosten", "lichtung", "ausgang", "weiher"}),
+     "Im Nordosten kannst Du immer noch die grosse Lichtung mit den wandernden Eichen\n"
+    +"und dem verwunschenen Weiher erkennen.\n");
+   AddDetail(({"eichen", "wandernde eichen"}),
+     "Im Nordosten auf der Lichtung hast Du vorhin wandernde Eichen gesehn,\n"
+    +"vielleicht solltest Du einfach nochmal zurueck gehn und sie Dir naeher\n"
+    +"anschaun.\n");
+   AddDetail(({"wolke", "wolken", "schaefchenwolke"}),
+     "Der Himmel ist eigentlich wolkenfrei nur hier und da zieht mal eine kleine\n"
+    +"Schaefchenwolke vorbei.\n");
+   AddExit("nordosten", ROOM("lichtungsw"));
+   AddItem(NPC("titina"), REFRESH_REMOVE, 1);
+   AddCmd(({"setz", "setze", "leg", "lege", "kletter", "klettere"}), "cmd_setzen");
+   AddCmd(({"steh", "stehe"}), "cmd_aufstehn");
+}
+
+#define STEIN WALDID("stein")
+
+void init()
+{
+  if (PL) PL->SetProp(STEIN, 0);
+  ::init();
+}
+
+static int cmd_aufstehn(string str)
+{
+    if (!PL->QueryProp(STEIN)) return 0;
+    if (str!="auf" && str!="von stein auf") {
+       notify_fail("Von was moechtest Du aufstehn?\n");
+       return 0;
+    }
+    PL->SetProp(STEIN, 0);
+    write("Du kletterst also vom Stein wieder runter und stehst auf.\n");
+    return 1;
+}
+
+#define VERB(x) (["setz": "setzt", "leg": "legst", "kletter": "kletterst"])[x]
+
+static int cmd_setzen(string str)
+{
+   string verb;
+   verb=query_verb();
+   if (verb && verb[<1]=='e') verb=verb[0..<2];
+   if (str!="auf stein" && str!="stein" && str!="von stein") {
+      notify_fail(BS("Wohin moechtest Du "
+                 +(verb!="kletter" ? "Dich " : "")+verb+"en?"));
+      return 0;
+   }
+   if (PL->QueryProp(STEIN)) {
+      if (verb!="kletter" || str=="auf stein") {
+         write("Du sitzt doch bereits auf dem Stein!\n");
+         return 1;
+      }
+      PL->SetProp(STEIN, 0);
+      write("Du kletterst also vom Stein wieder runter und stehst auf.\n");
+      return 1;
+   }
+
+   write(BS("Entspannt "+VERB(verb)+" Du "+(verb!="kletter" ? "Dich " : "")
+        +"auf den Stein und geniesst die Sonne."));
+   PL->SetProp(STEIN, time());
+   return 1;
+}
+
+static string det_zeit()
+{  return "Wir haben genau "+dtime(time())[<8..]+".\n"; }
+
+static string _query_int_long()
+{
+   if (present(WALDID("fee"), ME))
+      return
+        "Hier mitten im Wald steht ein grosser Stein, auf dem Titina die wunderschoene\n"
+       +"Waldfee sitzt und sich in aller Ruhe ihr langes goldenes Haar kaemmt. Die\n"
+       +"Sonne strahlt genau auf den Stein und es ist wohl wirklich der gemuetlichste\n"
+       +"Ort auf Erden. Links und rechts vom Weg schliesst der dichte Wald an und so\n"
+       +"ist der einzige Ausgang Richtung Nordosten zurueck zur Lichtung.\n";
+   return "Hier mitten im Wald steht ein grosser Stein, der von der Sonne ordentlich\n"
+         +"aufgeheizt wird und ihn zu einem traumhaften Ort fuer alle Sonnenliebhaber\n"
+         +"macht. Links und rechts vom Weg schliesst direkt der dichte Wald an und so\n"
+         +"ist der einzige Ausgang Richtung Nordosten zurueck zur Lichtung.\n";
+}
diff --git a/doc/beispiele/zauberwald/room/tuempel.c b/doc/beispiele/zauberwald/room/tuempel.c
new file mode 100644
index 0000000..6f22d86
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/tuempel.c
@@ -0,0 +1,179 @@
+// (c) by Thomas Winheller (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+
+inherit ROOM("stdroom");
+inherit "/std/room/kraeuter";
+
+void create()
+{
+   ::create();
+   SetProp(P_LIGHT, 2);
+   SetProp(P_INDOORS, 0);
+   SetProp(P_INT_SHORT, "An einem verwunschenden Weiher");
+   AddSpecialDetail(({"ort", "weiher"}), "_query_int_long");
+   AddDetail(({"seerosen", "farben", "farbenvielfalt"}),
+     "Auf dem Wasser schwimmen zahlreiche Seerosen in allen Farben des Regenbogens\n"
+    +"eine solche Farbenvielfalt wie hier, hast Du bisher noch nirgendwo sonst\n"
+    +"gesehn.\n");
+   AddDetail("regenbogen", "Derzeit steht keiner am Himmel.\n");
+   AddDetail(({"libelle", "libellen", "atmosphaere", "summen"}),
+     "Hier und da schwirren ueber dem Weiher einige Libellen herum. Ihr Summen\n"
+    +"verbreitet eine richtig idyllische Atmosphaere an diesem Ort.\n");
+   AddDetail(({"pixies", "zauberwesen"}),
+     "Pixies sind kleine verspielte Zauberwesen, die hier im Zauberwald wohnen. Um\n"
+    +"einem von ihnen zu begegnen wirst Du hier im Wald sicher nich lange suchen\n"
+    +"muessen, doch vorsicht, sie haben nichts als Unfug im Kopf...\n");
+   AddDetail(({"wald", "zauberwald", "punkt"}),
+     "Der verwunschene Weiher ist mehr oder weniger der zentrale Punkt hier im\n"
+    +"Zauberwald. Er liegt mitten auf einer grossen Lichtung umgeben vom dichten\n"
+    +"Wald der Pixies\n");
+   AddDetail(({"lichtung", "mitte"}),
+     "Der Weiher befindet sich genau in der Mitte der Lichtung, sieh Dich halt\n"
+    +"einfach mal um.\n");
+   AddDetail(({"boden", "ufer"}),
+     "Das Ufer des Weihers besteht aus zahlreichen Steinen die bis in den Weiher\n"
+    +"hineinreichen. Auf und zwischen diesen Steinen sind jedoch ueberall zahlreiche\n"
+    +"kleine und mittlere Pflanzen gewachsen.\n");
+   AddDetail(({"stein", "steine"}), "Ein Stein ist ein Stein ist ein Stein ist ein Stein ist ein Stein.\n");
+   AddDetail("pflanzen",
+     "Die verschiedensten Pflanzen wachsen zwischen den Steinen empor und begruenen\n"
+    +"das Ufer. An einer Stelle kannst Du sogar weissen Wasser-Hahnenfuss wachsen\n"
+    +"sehen.\n");
+   AddDetail(({"wasser", "schimmer", "schimmern"}),
+     "Das Wasser ist irgendwie recht trueb und es geht ein sehr seltsames Schimmern\n"
+    +"von ihm aus. Irgendetwas besonderes hat es mit diesem Wasser auf sich, das\n"
+    +"spuerst Du genau. Du weisst jedoch nicht, ob es etwas gutes oder etwas boeses\n"
+    +"ist.\n");
+   AddDetail(({"himmel", "luft", "sonne", "waerme", "strahlen", "sonnenstrahlen"}),
+     "Die Sonne steht hoch am Himmel und fuellt diesen Ort mit einer herrlichen\n"
+    +"Waerme und ihre Strahlen reflektieren im Wasser in allen erdenklichen Farben.\n");
+   AddExit("norden", ROOM("lichtungn"));
+   AddExit("nordosten", ROOM("lichtungno"));
+   AddExit("nordwesten", ROOM("lichtungnw"));
+   AddExit("osten", ROOM("lichtungo"));
+   AddExit("westen", ROOM("lichtungw"));
+   AddExit("sueden", ROOM("lichtungs"));
+   AddExit("suedwesten", ROOM("lichtungsw"));
+   AddExit("suedosten", ROOM("lichtungso"));
+   AddItem(NPC("ulinia"), REFRESH_REMOVE, 1);
+   AddCmd(({"bad", "bade", "schwimm", "schwimme", "tauch", "tauche"}), "cmd_schwimmen");
+   AddCmd(({"trink", "trinke"}), "cmd_trinken");
+   AddCmd(({"pflueck", "pfluecke"}), "cmd_pfluecken");
+   // Detail per Hand hinzufuegen, da GetPlant anstelle von AddPlant
+   // verwendet wird.
+   AddPlantDetail(OBJ("hahnenfuss"));
+}
+
+static int cmd_trinken(string str)
+{
+   int drink;
+   object ob;
+   if (member(({"wasser", "wasser aus teich", "wasser aus tuempel",
+                "wasser aus see", "aus teich", "aus tuempel", "aus wasser",
+                "aus see"}), str)==-1) {
+      notify_fail("Was moechtest Du trinken?\n");
+      return 0;
+   }
+   if ((ob=present(WALDID("fee"), ME)) && !ob->IsEnemy(PL)) {
+      write(BS("Die Waldfee scheint Deinen Entschluss ein wenig von dem "
+         +"Wasser zu kosten, bemerkt zu haben und straft Dich mit einem "
+         +"mahnenden Blick ab. Du ueberlegst es Dir also noch einmal und "
+         +"laesst von Deinem Vorhaben ab."));
+      return 1;
+   }
+   // das tanken am Wasser ist umsonst, es heilt dabei wie ein
+   // Kneipengetraenk das genau 1 Muenze kostet. Geheilt werden nur SP
+   // Ein Missbrauch ist im Wald ausgeschlossen, bzw. man muesste den
+   // gesamten Wald leermetzeln und kann dann ueben bis zum naechsten
+   // reset. Bei Kosten von einer Muenze pro Heilung ist es sehr fraglich
+   // ob sich das lohnt.... :)
+   drink=(PL->QueryProp(P_MAX_DRINK)) - (PL->QueryProp(P_DRINK));
+   if (drink>10) drink=10; // nie mehr als fuer 10 soak tanken...
+   if (drink <= 0 || !PL->drink_soft(drink, 1)) {
+      write("Du bist so voll, Du kannst leider wirklich nichts mehr trinken...\n");
+      return 1;
+   }
+   write("Du gehst an den Rand des Weihers und nimmst einen kraeftigen Schluck von dem\n"
+        +"Wasser. Sogleich spuerst Du, wie Deine mentalen Kraefte langsam gestaerkt\n"
+        +"werden.\n");
+   if (PL->drink_soft(drink)) { // soak gutschreiben erfolgreich?
+      PL->buffer_sp(drink*6, 5);
+      PL->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   }
+   return 1;
+}
+
+static int cmd_schwimmen(string str)
+{
+   string verb;
+
+   // besondere Eigenschaft der schluesselwoerter ausnutzen... :)
+   verb=(query_verb()||"");
+   if (verb[<1]!='e') verb+="e";
+   if (member(({"in teich", "in weiher", "in tuempel", "in see"}), str)==-1) {
+      notify_fail("Worin willst Du "+verb+"n?\n");
+      return 0;
+   }
+   str=capitalize(str[3..]); // "in " abschneiden...
+   if (present(WALDID("fee"), ME)) {
+      write(BS("Die Waldfee scheint Deinen Entschluss im "+str+" "+verb
+         +"n zu gehn irgendwie bemerkt zu haben und straft Dich mit einem "
+         +"mahnenden Blick ab. Deine Lust zum "+capitalize(verb)
+         +"n sinkt sogleich gegen null, denn Du verspuerst keine grosse "
+         +"Lust Dich mit der Waldfee anzulegen."));
+      return 1;
+   }
+   write(BS("Mutig gehst Du einen Schritt ins Wasser, da ueberkommt Dich auch "
+           +"schon ein seltsames kribbeln am ganzen Koerper. In windeseile "
+           +"hast Du den "+str+" auch schon wieder verlassen."));
+   return 1;
+}
+
+static int cmd_pfluecken(string str)
+{
+   object ob;
+   notify_fail("WAS moechtest Du pfluecken?\n");
+   if (member(({"hahnenfuss",
+                "wasser-hahnenfuss",
+                "weisser hahnenfuss",
+                "weisser wasser-hahnenfuss"}), str)<0) return 0;
+   if ((ob=present(WALDID("fee"), ME)) && !ob->IsEnemy(PL)) {
+      write(BS("Die Waldfee scheint Dein Vorhaben bemerkt zu haben und "
+         +"straft Dich mit einem mahnenden Blick ab. Du ueberlegst es Dir "
+         +"wieder anders und laesst von Deinem Vorhaben ab, solange die "
+         +"Fee hier wacht."));
+      return 1;
+   }
+   ob=GetPlant(OBJ("hahnenfuss"));
+   if (objectp(ob)) {
+      if (ob->move(PL, M_GET)==1)
+          write(BS("Vorsichtig pflueckst Du "+ob->name(WEN, 1)
+                  +" und nimmst "+ob->QueryPronoun(WEN)+" an Dich."));
+      else write(BS("Vorsichtig pflueckst Du "+ob->name(WEN, 1)+" kannst "
+                  +ob->QueryPronoun(WEN)+" aber nicht nehmen."));
+   }
+   else if (!ob)
+      write(BS("Der Hahnenfuss ist noch nicht wieder weit genug "
+              +"nachgewachsen um ihn pfluecken zu koennen."));
+   return 1;
+}
+
+static string _query_int_long()
+{
+   if (present(WALDID("fee"), ME))
+      return
+        "Du stehst nun an einem kleinen verwunschenen Weiher, inmitten des Zauberwalds.\n"
+       +"Auf dem Wasser schwimmen zahlreiche Seerosen in den verschiedensten Farben\n"
+       +"und hier und dort schwirrt eine Libelle in der Luft. Mitten ueber dem Weiher\n"
+       +"schwebt eine wunderschoene Waldfee in der Luft und scheint den Weiher zu\n"
+       +"bewachen. Irgendetwas geheimnisvolles scheint es mit dem Weiher auf sich\n"
+       +"zu haben, nur was?\n";
+   return
+     "Du stehst nun an einem kleinen verwunschenen Weiher, inmitten des Zauberwalds.\n"
+    +"Auf dem Wasser schwimmen zahlreiche Seerosen in den verschiedensten Farben und\n"
+    +"hier und dort schwirrt eine Libelle in der Luft. Alles scheint hier sehr\n"
+    +"friedlich zu sein, fast ein wenig zu friedlich. Irgendetwas geheimnisvolles\n"
+    +"scheint es mit diesem Weiher auf sich zu haben, nur was?\n";
+}
diff --git a/doc/beispiele/zauberwald/room/virtual_compiler.c b/doc/beispiele/zauberwald/room/virtual_compiler.c
new file mode 100644
index 0000000..1cc4d5c
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/virtual_compiler.c
@@ -0,0 +1,133 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h>
+#include <v_compiler.h>
+#include "../files.h"
+#include "/p/service/padreic/kraeuter/plant.h"
+
+inherit "std/virtual/v_compiler";
+
+create()
+{
+  ::create();
+  SetProp(P_STD_OBJECT, ROOM("stdlichtung"));
+  SetProp(P_COMPILER_PATH, ROOM(""));
+}
+
+string Validate(string file)
+{
+  file=::Validate(file);
+  switch(file) { 
+     case "lichtungso":
+     case "lichtungo":
+     case "lichtungno":
+     case "lichtungn":
+     case "lichtungs":
+     case "lichtungnw":
+     case "lichtungw":
+     case "lichtungsw":  return file;
+     default:
+  }
+}
+         
+mixed CustomizeObject()
+{
+  string file;
+  file=Validate(::CustomizeObject());
+  if (!random(3)) PO->AddItem(NPC("laufeiche"), REFRESH_DESTRUCT, ([MNPC_HOME: ROOM(file)]) );
+  switch(file) {
+     case "lichtungno":
+       PO->AddExit("westen", ROOM("lichtungn"));
+       PO->AddExit("sueden", ROOM("lichtungo"));
+       PO->AddExit("suedwesten", ROOM("tuempel"));
+       PO->AddExit("suedosten", ROOM("weg2"));
+       PO->SetProp(EXTRA_LONG,
+         " Im Suedosten befindet sich der Waldweg, ueber den Du den Wald wieder "
+        +"verlassen kannst.");
+       return file;
+
+     case "lichtungo":
+       PO->AddExit("norden", ROOM("lichtungno"));
+       PO->AddExit("sueden", ROOM("lichtungso"));
+       PO->AddExit("westen", ROOM("tuempel"));
+       PO->AddExit("osten", ROOM("weg2"));
+       PO->SetProp(EXTRA_LONG,
+         " Im Osten befindet sich der Waldweg, ueber den Du den Wald wieder "
+        +"verlassen kannst.");
+       return file;
+
+     case "lichtungso":
+       PO->AddExit("westen", ROOM("lichtungs"));
+       PO->AddExit("norden", ROOM("lichtungo"));
+       PO->AddExit("nordwesten", ROOM("tuempel"));
+       PO->AddExit("nordosten", ROOM("weg2"));
+       PO->SetProp(EXTRA_LONG,
+         " Im Nordosten befindet sich der Waldweg, ueber den Du den Wald wieder "
+        +"verlassen kannst.");
+       PO->AddItem(NPC("riese"), REFRESH_DESTRUCT);
+       return file;
+
+     case "lichtungs":
+       PO->AddExit("westen", ROOM("lichtungsw"));
+       PO->AddExit("osten", ROOM("lichtungso"));
+       PO->AddExit("norden", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG,
+         " In der Wiese siehst Du an einer Stelle etwas Klee wachsen.");
+       PO->AddPlant(BITTERKLEE);
+       // "klee" _nach_ dem AddPlant einfuegen, damit die restlichen Details
+       // wie Bitterklee trotzdem noch eingefuegt werden
+       PO->RemoveDetail(({"klee"}));
+       PO->AddDetail(({"stelle", "klee"}),
+         "Bei der Stelle scheint es sich unzweifelhaft um Bitterklee zu handeln.\n");
+       PO->AddCmd("sueden", "cmd_sueden");
+       return file;
+
+     case "lichtungn":
+       PO->AddExit("westen", ROOM("lichtungnw"));
+       PO->AddExit("osten", ROOM("lichtungno"));
+       PO->AddExit("sueden", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG, " Am Rand der Wiese entdeckt Du einige kleine Pilze im Gras.");
+       PO->AddCmd(({"esse", "iss", "pflueck", "pfluecke"}), "cmd_pilze");
+       PO->AddDetail(({"pilz", "pilze", "schimmer"}),
+         "Die Pilze haben einen aeusserst seltsamen metallischem Schimmer und\n"
+        +"verbreiten einen sehr angenehmen suesslichen Duft im Raum.\n");
+       PO->AddSmells(({"pilz", "pilze"}),
+         "Die Pilze verbreiten einen sehr suesslichen Duft.\n");
+       PO->AddSmells("duft", "Der Duft ist eigentlich sehr befreiend und angenehm.\n");
+       return file;
+
+     case "lichtungnw":
+       PO->AddExit("westen", ROOM("schule"));
+       PO->AddExit("osten", ROOM("lichtungn"));
+       PO->AddExit("sueden", ROOM("lichtungw"));
+       PO->AddExit("suedosten", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG,
+         " Nach Westen kannst Du ein Stueck in den Wald hinein gehn.");
+       return file;
+
+     case "lichtungw":
+       PO->AddExit("norden", ROOM("lichtungnw"));
+       PO->AddExit("sueden", ROOM("lichtungsw"));
+       PO->AddExit("osten", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG, " Am Waldrand stehen einige blaeuliche Farne.");
+       PO->AddCmd(({"esse", "iss", "pflueck", "pfluecke"}), "cmd_farne");
+       PO->AddDetail(({"farn", "farne"}),
+         "Die blaeulichen Farne sind wirklich sehr merkwuerdig. soetwas hast Du bisher\n"
+        +"noch nirgendwo gesehn. Irgendetwas besonderes hat es sicherlich damit auf sich.\n");
+       return file;
+
+     case "lichtungsw":
+       PO->AddExit("osten", ROOM("lichtungs"));
+       PO->AddExit("norden", ROOM("lichtungw"));
+       PO->AddExit("nordosten", ROOM("tuempel"));
+       PO->AddExit("suedwesten", ROOM("stein"));
+       PO->SetProp(EXTRA_LONG,
+         " Nach Suedwesten kannst Du ein Stueck in den Wald hinein gehn.");
+       return file;
+
+     default: return 0;
+  }
+  return file;
+}
+
+int NoParaObjects() { return 1; }
diff --git a/doc/beispiele/zauberwald/room/weg1.c b/doc/beispiele/zauberwald/room/weg1.c
new file mode 100644
index 0000000..169b73f
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/weg1.c
@@ -0,0 +1,75 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 0);
+   SetProp(P_INT_SHORT, "Auf einem Waldweg im Zauberwald");
+   AddDetail(({"blaetterdach", "dach", "baeume"}),
+     "Die Baeume rechts und links des Weges bilden ueber dem Weg ein so dichtes\n"
+    +"Blaetterdach, das so gut wie ueberhaupt kein Sonnenlicht mehr auf den Weg\n"
+    +"scheint.\n");
+   AddSpecialDetail("szene", "_query_int_long");
+   AddSpecialDetail(({"weg", "weges", "waldweg", "boden"}), "det_weg");
+   AddDetail(({"licht", "sonnenlicht", "sonnenstrahlen"}),
+     "Durch das dichte Blaetterdach schaffen es die Sonnenstrahlen nur noch sehr\n"
+    +"vereinzelt bis auf den Weg durchzukommen. Dadurch ist es hier unten relativ\n"
+    +"Feucht, kalt und dunkel.\n");
+   AddDetail(({"himmel", "sonne", "wolke", "wolken"}),
+     "Das Blaetterdach ist hier so dicht, das Du den Himmel nicht mal mehr erahnen\n"
+    +"kannst. Du weisst nicht mal, ob es regnet oder ob die Sonne scheint.\n");
+   AddDetail("feucht",
+     "Bloss weil feucht grossgeschrieben ist es noch lange kein Substantiv, wenn\n"
+    +"ueberhaupt heisst es dann _Feuchtigkeit_ :).\n");
+   AddDetail("substantiv", "Nicht jedes Substantiv ist ein sinnvolles Detail :)\n");
+   AddDetail("feuchtigkeit", "Ein wenig feucht, wie man es halt aus jedem Wald so kennt.\n");
+   AddDetail("kaelte",
+     "Durch das wenige Sonnenlicht, das bis nach hier unten durchdringt, ist es\n"
+    +"hier verhaeltnismaessig frisch.\n");
+   AddDetail("dunkelheit",
+     "Wenn es hell ist, ist es nicht mehr dunkel und wenn es nicht hell ist, kannst\n"
+    +"Du nicht viel sehn. Wie also willst Du die Dunkelheit untersuchen :)?\n");
+   AddDetail("_feuchtigkeit_", "Meine Guete, nimm doch nich immer alles gleich _so_ woertlich.\n");
+   AddDetail("guete", "Sei lieber vorsichtig, soo guetig bin ich nu auch nicht :).\n");
+   AddDetail(({"lichtquelle", "nachtsicht"}),
+     "Hier ist es eigentlich verdammt dunkel und ohne Nachtsicht oder eine eigene\n"
+    +"Lichtquelle, koenntest Du hier _nichts_ sehn.\n");
+   AddDetail(({"ausgang", "osten"}),
+     "Wenn Du dem Weg Richtung Osten folgst, dann kommst Du ziemlich bald wieder\n"
+    +"Richtung Ausgang.\n");
+   AddDetail(({"stueck", "wald", "westen"}),
+     "Naja.. Du stehst zwar schon im Wald drin, aber nach Westen hin, gehst es noch\n"
+    +"ein Stueck tiefer hinein.\n");
+   AddExit("osten", ROOM("eingang"));
+   AddExit("westen", ROOM("weg2"));
+   AddItem(NPC("waechter"), REFRESH_REMOVE, 1);
+}
+
+static string det_weg()
+{
+   if (present(WALDID("waechtereiche"), ME))
+      return "Mitten auf dem Weg steht der Waechter des Waldes und kontrolliert sehr genau,\n"
+            +"wer in den Wald hinein darf und wer nicht. Eigentlich ist er jedoch den\n"
+            +"meisten immer sehr friedlich gesonnen.\n";
+   return "Der Weg fuehrt hier nach Westen noch ein Stueck tiefer in den Wald hinein,\n"
+         +"nach Osten kannst Du jedoch wieder in Richtung Ausgang des Zauberwalds gehn.\n";
+}
+
+static string _query_int_long()
+{
+   if (present(WALDID("waechtereiche"), ME))
+      return "Hier ist es jetzt richtig duester und ohne eigene Lichtquelle koenntest Du\n"
+            +"nichts mehr sehn, da so gut wie ueberhaupt kein Licht mehr durch das\n"
+            +"Blaetterdach auf den Weg scheint. Mitten in dieser eigentlich lebens-\n"
+            +"unfreundlichen Szene, steht eine grosse alte Eiche mitten auf dem Weg.\n";
+   return "Hier ist es jetzt richtig duester und ohne eigene Lichtquelle koenntest Du\n"
+         +"hier nichts mehr sehn, da so gut wie ueberhaupt kein Licht mehr durch das\n"
+         +"Blaetterdach auf den Weg scheint. Du kannst noch ein Stueck tiefer in den\n"
+         +"Wald hinein und nach Westen gehn, oder aber zurueck Richtung Kreuzung nach\n"
+         +"Osten.\n";
+}
diff --git a/doc/beispiele/zauberwald/room/weg2.c b/doc/beispiele/zauberwald/room/weg2.c
new file mode 100644
index 0000000..0d06169
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/weg2.c
@@ -0,0 +1,93 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Am Rande einer Lichtung im Zauberwald");
+   AddSpecialDetail(({"wald", "zauberwald"}), "_query_int_long");
+   AddDetail(({"westen", "lichtung", "plaetzchen", "idyllisches plaetzchen"}),
+     "Im Westen befindet sich eine grosse Lichtung mit einem kleinen Tuempel, am\n"
+    +"Rande der Lichtung stehen vereinzelt noch einige Baeume aber zum Tuempel hin,\n"
+    +"wird es dann mehr und mehr nur noch Gras das den Boden bedeckt.\n");
+   AddDetail(({"rasen", "gras"}),
+     "Am besten betrittst Du die Lichtung einfach und schaust Dir den Rasen\n"
+    +"naeher an.\n");
+   AddDetail("tuempel",
+     "Wenn Du Dir den Tuempel naeher ansehen moechtest, dann solltest Du schon\n"
+    +"ein Stueck naeher rangehen.\n");
+   AddDetail(({"stueck", "raum"}),
+     "Na wenigstens einen Raum weiter solltest Du schon gehn.\n");
+   AddDetail("schatten",
+     "Hier befindest Du Dich noch im Schatten der Baeume, die Lichtung im Westen\n"
+    +"liegt jedoch komplett in der waermenden Sonne.\n");
+   AddSpecialDetail("sonne", "det_sonne");
+   AddDetail(({"wegesrand", "baeume", "wegrand", "rand"}),
+     "Am Wegesrand stehen einige Baeume die ein schoenes Blaetterdach ueber den Weg\n"
+    +"spannen und den Weg in ihren Schatten legen.\n");
+   AddDetail(({"himmel", "blaetterdach", "dach", "licht", "sonnenstrahlen", "wolken", "wolke"}),
+     "Das Blaetterdach ist ziemlich dicht, so dass Du nicht soo viel sehen kannst,\n"
+    +"aber einige Sonnenstrahlen durchbrechen das Dach und erreichen den Weg.\n");
+   AddDetail(({"weg", "boden", "erde", "ausgang", "osten", "richtung"}),
+     "Im Westen fuehrt der Weg zu einer grossen Lichtung, waehrend er nach Osten hin\n"
+    +"Richtung Ausgang des Zauberwalds fuehrt.\n");
+   AddDetail("voegel", "Du kannst sie deutlich hoeren, bekommst aber keinen zu sehn.\n");
+   AddExit("osten", ROOM("weg1"));
+   AddExit("suedwesten", ROOM("lichtungso"));
+   AddExit("westen", ROOM("lichtungo"));
+   AddExit("nordwesten", ROOM("lichtungno"));
+   AddCmd("osten", "cmd_osten");
+   AddItem(NPC("laufeiche"), REFRESH_DESTRUCT);
+}
+
+static string det_sonne()
+{
+   if (PL) PL->SetProp(P_BLIND, 1);
+   return "Du schaust fasziniert in die Sonne und untersucht sie naeher, doch das war\n"
+         +"wohl ein grosser Fehler, denn ploetzlich wird es ganz ganz dunkel um Dich rum.\n";
+}
+
+void init()
+{
+   // wenn man von westen kommt und keine blockende Eiche hier ist, dann
+   // so betrachten als waere man aus dem osten gekommen
+   if (query_once_interactive(PL) && !present(WALDID("eiche")))
+      PL->SetProp(AUSGANG, "westen");
+   ::init();
+}
+
+static int cmd_osten()
+// wenn gerade eine Eiche hierhin gelaufen ist, kommen feindliche
+// Spieler nicht mehr vorbei :)
+{
+   if (PL && PL->QueryProp(AUSGANG)!="westen" &&
+       PL->QueryProp(ZAUBERWALD)>time() && present(WALDID("eiche"), ME)) {
+      if (present(WALDID("eiche 2"), ME))
+         write("Die Eichen stehen Dir dabei leider im Weg und lassen Dich nicht vorbei.\n");
+      else write("Die Eiche steht Dir dabei leider im Weg und laesst Dich nicht vorbei.\n");
+      return 1;
+   }
+}
+
+static string _query_int_long()
+{
+   if (!PL || PL->QueryProp(ZAUBERWALD)<=time())
+     return
+      "Du stehst nun mitten im Zauberwald. Im Westen erstreckt sich vor Dir eine\n"
+     +"grosse Lichtung, auf die Du muehelos gelangen kannst. Nach Osten hin fuehrt\n"
+     +"ein schmaler Weg zurueck zum Ausgang des Waldes. Alles scheint hier sehr\n"
+     +"friedlich zu sein, die Voegel zwitschern und das Blaetterdach ist hier auch\n"
+     +"nicht mehr so dicht wie im Osten, so dass einige Sonnenstrahlen den Weg\n"
+     +"erreichen. Es zieht Dich foermlich nach Westen auf die Lichtung, mitten auf\n"
+     +"dieses sonnige idyllische Plaetzchen.\n";
+   return "Nichts wie raus hier. Es war ganz und gar keine gute Idee hier im Wald Deiner\n"
+         +"Aggressivitaet freien Lauf zu lassen. Du kannst von Glueck haben, wenn Du mit\n"
+         +"einem blauen Auge davon kommst und den Wald noch lebend verlassen kannst.\n"
+         +"Nach Westen gelangst Du auf die grosse Lichtung, ratsamer waere jedoch wohl\n"
+         +"eher der Waldweg im Osten, ueber den Du den Zauberwald wieder verlassen kannst.\n";
+}