Updates erzeugter Manpages

Diese Manpages werden mit sphinx erzeugt. Sie werden
hier committet, damit auch Nutzer ohne sphinx die
Textversion haben.

Change-Id: Ibe6acc626b51b42364af33450a719e88281651b9
diff --git a/doc/lfun/AddExtraLook b/doc/lfun/AddExtraLook
index 7436f7e..279b496 100644
--- a/doc/lfun/AddExtraLook
+++ b/doc/lfun/AddExtraLook
@@ -2,9 +2,11 @@
 AddExtraLook()
 **************
 
-AddExtraLook() varargs int AddExtraLook(string look, [int duration,
-string key,
 
+FUNKTION
+========
+
+   varargs int AddExtraLook(string look, [int duration, string key,
    string lookende, object ob]);
 
 
@@ -14,117 +16,168 @@
    /std/living/description.c
 
 
+ARGUMENTE
+=========
+
+   string look:
+
+      * String, der in der Langbeschreibung des Lebewesens
+        zusaetzlich ausgegeben wird.
+
+      * zu rufender Funktionsname, wenn 'ob' angegeben ist
+
+   int duration:
+
+      * > 0: Dauer der Gueltigkeit des Extralooks in Sekunden.
+
+      * 0:   Unbegrenzt gueltiger Eintrag. Rebootfest.
+
+      * < 0: Bis Ende/Reboot bestehender Eintrag.
+
+   string key:
+      Schluesselwort, unter dem der Eintrag registriert wird und mit
+      dem man diesen auch mittels RemoveExtraLook() entfernen kann.
+      Sollte eindeutig sein! Ist 'key' nicht angeben, wird der
+      Objektname (object_name()) des setzenden Objekts benutzt.
+
+   string lookende:
+
+      * String, der an das Lebewesen (nur bei Spielern) ausgegeben
+        wird, wenn der eingetragene Extralook abgelaufen ist.
+
+      * zu rufender Funktionsname, wenn 'ob' angegeben ist
+
+   object ob:
+      Ein Objekt, an dem die in 'look' und 'lookende' abgelegten
+      Methoden bei Abfrage oder Ablauf aufgerufen werden. Die Methoden
+      bekommen das Living uebergeben und muessen selbst umgebrochene
+      Strings zurueckgeben.
+
+
 BESCHREIBUNG
 ============
 
    Der Extralook erscheint in der Langbeschreibung des Lebewesens.
-   Eintraege koennen mit dieser Funktion hinzugefuegt werden. Dies ist der
-   bevorzugte Weg, wenn ansonsten extra ein Objekt im Spielerinventar abgelegt
-   werden muesste.
 
+   Texte dafuer koennen mit dieser Funktion hinzugefuegt und verwaltet
+   werden. Wenn ihr nicht ohnehin unbedingt ein Objekt IM Spieler
+   ablegt (wie zB eine Ruestung mit einem Extralook) (1), dann ist
+   diese Methode bevorzugt zu verwenden.
 
+   Ueber die Angabe eines 'ob' koennen Looks auch dynamisch erstellt
+   werden, dabei werden dann 'look' bzw. 'lookende' als Methoden am
+   Objekt gerufen. (1) Ein so fuer AddExtraLook verwendetes Objekt
+   'ob' muss nicht wie bisher ueblich im Inv des Spieler liegen!
 
-   Alle Parameter bis auf <look> sind optional.
-
-
-ARGUMENTE
-=========
-
-   - string look:
-     String, der in der Langbeschreibung des Lebewesens zusaetzlich ausgegeben
-     wird.
-     Kann auch ein Funktionsname sein, wenn <ob> angegeben wird (s.u.).
-   - int duration:
-     > 0: Wie lang bleibt der Extralook gueltig (in Sekunden)? Anschliessend
-          wird er automatisch geloescht.
-     0:   Dieser Eintrag bleibt unbegrenzt gueltig.
-     < 0: Dieser Eintrag bleibt bis zum Ende/Reboot bestehen.
-   - string key:
-     Schluesselwort, unter dem der Eintrag registriert wird und mit dem man ihn
-     auch mittels RemoveExtraLook() entfernen kann. Sollte natuerlich
-     moeglichst eindeutig sein. ;-) Wenn <key> nicht angeben wird, wird der
-     Objektname (object_name()) benutzt.
-   - string lookende:
-     String, der an das Lebewesen (nur bei Spielern) ausgegeben wird, wenn der
-     eingetragene Extralook abgelaufen ist.
-     Kann auch ein Funktionsname sein, wenn <ob> angegeben wird.
-   - object ob:
-     Wenn hier ein Objekt angegeben wird, werden <look> und <lookende> als
-     Funktonsnamen aufgefasst. Diese Funktionen werden in <ob> aufgerufen, wenn
-     der Extralook des Lebewesen angezeigt wird bzw. der eingetragene Extralook
-     abgelaufen ist. Diese Funktionen bekommen das jeweilige Lebenwesen als
-     Objekt uebergeben. Sie muessen einen String zurueckliefern, der ausgegeben
-     wird. Dieser String wird direkt so ausgeben, also selber fuer Zeilenumbruch
-     etc. sorgen!
-     WICHTIG: Das Objekt sollte nach Moeglichkeit eine Blueprint sein, da das
-     ganze nix mehr ausgibt, sobald der Clone zerstoert wird, falls hier
-     einer angeben wird. Wenn ihr keine BP uebergebt: Wisst, was ihr tut. ;-)
-
-
-RUECKGABEWERTE
-==============
-
-   > 0, falls der Eintrag erfolgreich registriert wurde.
-   < 0 sonst.
-     -1: <key> war nicht gueltig und es konnte keiner ermittelt werden.
-     -2: <look> war kein gueltiger String.
-     -3: <duration> war kein Integer.
-     -4: unter <key> gibt es schon einen Eintrag.
+   Direkt angegebene Texte (also nicht von einem Objekt 'ob' bezogen)
+   werden durch replace_personal() gefiltert und unter Beibehaltung
+   existierender Umbrueche auf 78 Zeichen umgebrochen.
 
 
 BEMERKUNGEN
 ===========
 
-   Die Strings <look> und <lookende> werden vor Ausgabe durch
-   replace_personal() geschickt, daher ist die Verwendung von @WER1, @WESSEN1
-   usw. moeglich (s. replace_personal). Dies gilt aber _nicht_ fuer den Fall,
-   dass die entsprechenden Funktionen in <ob> gerufen werden, dann muessen die
-   Funktionen selber umbrechen, etc.
-   Nach replace_personal() werden die Strings noch von break_string() auf 78
-   Zeilen umgebrochen, allerdings bleiben dabei vorhandene Umbrueche erhalten.
-   Die Meldung von <lookende> bzw. der Funktionsaufruf erfolgt, wenn der
-   Extralook der Lebewesen das erste Mal nach Ablauf der Gueltigkeit aufgerufen
-   wird.
+   * Die Meldung von <lookende> bzw. der Funktionsaufruf erfolgt,
+     wenn der Extralook der Lebewesen das erste Mal nach Ablauf der
+     Gueltigkeit aufgerufen wird.
+
+   * Das uebergbene Objekt sollte fuer permanente Eintraege eine
+     Blueprint sein, da Clones irgendwann (spaetestens mit Reboot)
+     zerstoert werden und der Eintrag dann bei Abfrage automatisch
+     geloescht wird.
+
+   * Folgerung: Clone-Objekte koennen fuer selbst beschraenkt
+     temporaere Extralooks benutzt werden.
+
+
+RUECKGABEWERTE
+==============
+
+   Siehe auch /sys/living/description.h fuer Konstanten.
+
+   * 1, falls der Eintrag erfolgreich registriert wurde.
+
+   * < 0 sonst.
+
+     * -1: <key> war nicht gueltig und es konnte keiner ermittelt
+       werden.
+
+     * -2: <look> war kein gueltiger String.
+
+     * -3: <duration> war kein Integer.
+
+     * -4: unter <key> gibt es schon einen Eintrag.
 
 
 BEISPIELE
 =========
 
-   # einfacher Eintrag, "fuer die Ewigkeit"
+   // (1) einfacher Eintrag, "fuer die Ewigkeit"
    living->AddExtraLook("@WER1 hat den Drachengott der SSP besiegt.");
 
-   # Eintrag der nach 1h automatisch weg ist.
+   // (2) Eintrag der nach 1h automatisch weg ist.
    living->AddExtraLook("@WER1 ist ganz mit Marmelade bedeckt.", 3600);
 
-
-
-   # Eintrag mit bestimmten Schluessel, damit man ihn wieder entfernen kann.
+   // (3) Eintrag mit bestimmten Schluessel, damit man ihn wieder entfernen kann
    living->AddExtraLook("@WER1 ist ganz mit Marmelade bedeckt.", 3600,
                         "humni_marmeladen_look");
 
-
-
-   # Mit "Ende"-Meldung, aber kein eigener Schluessel.
+   // (4) Mit "Ende"-Meldung, aber kein eigener Schluessel
    living->AddExtraLook("@WER1 ist patschnass.", 1200, 0,
                         "Du bist endlich wieder trocken. Puuh.");
 
+   // (5) Mit Objekt, welches den Extralook dynamisch erzeugt
+   living->AddExtraLook("get_my_special_extralook", 3600, 0, 0,
+                        this_object());
+   // In diesem Fall muss this_object() natuerlich die Funktion
+   // "get_my_special_extralook()" definieren, die einen String zurueckgibt
 
-
-   # Mit Objekt, was den Extralook dynamisch erzeugt
-   living->AddExtraLook("get_my_special_extralook", 3600, 0, 0, this_object());
-     In diesem Fall muss this_object() natuerlich die Funktion
-     "get_my_special_extralook()" definieren, die einen String zurueckgibt.
-
-   # Mit Objekt, was den Extralook und die Endemeldung dynamisch erzeugt
+   // (6) Mit Objekt, welches den Extralook dynamisch erzeugt
+   // Hier wird explizit die Blueprint uebergeben, der Extralook ist also
+   // rebootfest.
    living->AddExtraLook("get_my_special_extralook", 3600, 0,
-                        "extralookende", this_object());
+                        "extralookende", blueprint(this_object()));
+
+   // Mit Objekt, was den Extralook und die Endemeldung dynamisch erzeugt
+   // und keine festgelegte Existenzdauer hat, sondern sich aufgrund
+   // eigener Konditionen entsorgt
+   void set_extra_look(object living) {
+     object dyntemplook = clone_object("/path/to/some/object");
+     if(living->AddExtraLook("get_my_special_extralook", 0,
+                             object_name(dyntemplook),
+                             0, dyntemplook) == XL_OK)
+       dyntemplook->SetProp(P_INTERNAL_EXTRA_LOOK, living);
+     else
+       dyntemplook->remove();
+   }
+
+   // entsprechendes Objekt:
+   varargs int remove(int silent) {
+     object ob = QueryProp(P_INTERNAL_EXTRA_LOOK);
+     // wenn der Spieler da ist, entfernen wir den Look regulaer
+     if(objectp(ob))
+       ob->RemoveExtraLook(object_name(this_object()));
+     return ::remove(silent);
+   }
+
+   void reset() {
+     if(!random(10))
+       remove();
+     else
+       ::reset();
+   }
 
 
 SIEHE AUCH
 ==========
 
-   RemoveExtraLook(),
-   replace_personal(), break_string()
-   P_INTERNAL_EXTRA_LOOK
+   Verwandt:
+      *RemoveExtraLook()*, *P_INTERNAL_EXTRA_LOOK*
 
-14.05.2007, Zesstra
+   Sonstiges:
+      *replace_personal()*, *break_string()*
+
+   Fuer Spielerobjekte:
+      *P_EXTRA_LOOK*
+
+5. Juni 2017 Gloinson
diff --git a/doc/lfun/AddInfo b/doc/lfun/AddInfo
index 759a300..a75a22d 100644
--- a/doc/lfun/AddInfo
+++ b/doc/lfun/AddInfo
@@ -7,7 +7,7 @@
 ========
 
    varargs void AddInfo( frage, meldung
-                         [, indent [, [silent [, casebased] ] ] );
+      [, indent [, [silent [, casebased] ] ] );
 
 
 DEFINIERT IN
@@ -21,58 +21,67 @@
 
    string/string* frage
       Schluesseltext(e) auf die Informationen gegeben werden sollen.
+
    string/closure meldung
-      Information, die gegeben werden soll/Closure
+      Information, die gegeben werden soll/Closure Bekommt nichts
+      uebergeben.
+
    string indent
       Text, der sich bei mehrzeiligen Meldungen wiederholen soll.
+
    int/string silent
       Ist silent gesetzt, so erfolgt Antwort nur an Fragenden.
+
    string/closure casebased
-      Closure mit Returnwert string oder int.
+      Closure mit Returnwert string oder int. Bekommt nichts
+      uebergeben.
 
 
 BESCHREIBUNG
 ============
 
-   Wenn ein Spieler ein NPC mittels "frage <monstername> nach <frage>" nach
-   einer Information mit dem Schluessel 'frage' fragt, so wird die
-   entsprechende 'meldung' ausgegeben (oder die Closure in 'meldung'
-   gerufen und der zurueckgegebene Text ausgegeben). Der Meldung wird
-   der Name des Monsters vorangestellt.
+   Wenn ein Spieler ein NPC mittels "frage <monstername> nach <frage>"
+   nach einer Information mit dem Schluessel 'frage' fragt, so wird
+   die entsprechende 'meldung' ausgegeben (oder die Closure in
+   'meldung' gerufen und der zurueckgegebene Text ausgegeben). Der
+   Meldung wird der Name des Monsters vorangestellt.
 
    Frage:
-    Schluessel muessen kleingeschrieben sein, koennen aber Leerzeichen
-    enthalten.
+      Schluessel muessen kleingeschrieben sein, koennen aber
+      Leerzeichen enthalten.
 
    Meldung:
-    Wenn kein 'indent' angegeben ist, muss man die Meldung selbst
-    umbrechen.
+      Wenn kein 'indent' angegeben ist, muss man die Meldung selbst
+      umbrechen.
 
    Indent:
-    Wird ein 'indent' angegeben so wird jeder Zeile hinter dem
-    Monsternamen noch das 'indent' vorangesetzt. Zusaetzlich wird
-    'meldung' auf jeden Fall sauber umgebrochen.
-    Ein typisches indent ist "sagt: ".
+      Wird ein 'indent' angegeben so wird jeder Zeile hinter dem
+      Monsternamen noch das 'indent' vorangesetzt. Ein typisches
+      indent ist "sagt: ".
 
    Silent:
-    Bei 'silent'==1 erfolgt keine Textausgabe der Antwortmeldung im Raum,
-    ist 'silent' ein String, so wird jener an alle anderen Spieler ausser
-    dem Fragesteller im Raum ausgegeben.
+      Bei 'silent'==1 erfolgt keine Textausgabe der Antwortmeldung im
+      Raum, ist 'silent' ein String, so wird jener an alle anderen
+      Spieler ausser dem Fragesteller im Raum ausgegeben.
 
    Casebased:
-    Die als Closure angegebene Methode entscheidet, ob oder wie der NPC
-    auf diese Frage antworten soll:
-    - return 0:       normale Antwort mit "meldung"
-    - return 1:       keine Antwort/Antwort mit DEFAULT_NOINFO
-    - return string:  Antwort mit string unter Beruecksichtigung eines
-                      indent
+      Die als Closure angegebene Methode entscheidet, ob oder wie der
+      NPC auf diese Frage antworten soll:
 
-   Die Strings von 'silent' und 'meldung' werden geparsed.
-   Dabei koennen die @...-Tags von replace_personal() verwendet werden,
+      # return 0:    normale Antwort mit "meldung"
+
+      # return 1:    keine Antwort/Antwort mit DEFAULT_NOINFO
+
+      # return string: Antwort mit string unter Beruecksichtigung
+      eines indent
+
+   Die Strings von 'silent' und 'meldung' werden geparsed. Dabei
+   koennen die @[...]-Tags von replace_personal() verwendet werden,
    Objekt 1 ist this_player(). Ersetzte String am Satzanfang werden
-   automatisch gross geschrieben.
-   AddInfo() konvertiert die alten Schluesselworte @WER, @WESSEN, @WEM,
-   @WEN zu denen von replace_personal().
+   automatisch gross geschrieben. AddInfo() konvertiert die alten
+   Schluesselworte @WER, @WESSEN, @WEM, @WEN zu denen von
+   replace_personal(), jedoch nicht in den Rueckgabe- werten von
+   Closures.
 
    Mittels der in <npc.h> definierten Frage DEFAULT_INFO kann eine
    Meldung gesetzt werden, die gegeben werden soll, wenn der Spieler
@@ -83,25 +92,27 @@
 BEISPIELE
 =========
 
-   ### eine Standardantwort setzen ###
+   Siehe auch: /doc/beispiele/AddInfo/
+
+   // Beispiel 1: ### eine Standardantwort setzen ###
    AddInfo(DEFAULT_INFO, "starrt Dir boese in die Augen.\n");
    // identisch zu
-   SetProp(P_DEFAULT_INFO, "starrt Dir boese in die Augen.\n");
+   // obsolet: SetProp(P_DEFAULT_INFO, "starrt Dir boese in die Augen.\n");
 
-   ### einfache Beispiele, auch mit casebased ###
+   // Beispiel 2: einfache Beispiele, auch mit casebased
    AddInfo(({"knete","kohle"}),
-           "sagt: ich habe so etwas nicht.\n");
+       "sagt: ich habe so etwas nicht.\n");
    AddInfo("geld",
-           "Ich habe zwar kein Geld, aber ... blablabla ...",
-           "sagt: " );
+       "Ich habe zwar kein Geld, aber [...] blablabla [...]",
+       "sagt: ");
    AddInfo("muenzen",
-           "fluestert: Du willst Geld?\n",
-           0,
-           "fluestert @WEM etwas zu.\n");
+       "fluestert: Du willst Geld?",
+       0,
+       "fluestert @WEM etwas zu.");
 
    // "frage monster nach geld": alle im Raum hoeren
-   //  Das Monster sagt: Ich habe zwar kein Geld, aber ...
-   //  Das Monster sagt: ... blablabla ...
+   //  Das Monster sagt: Ich habe zwar kein Geld, aber [...]
+   //  Das Monster sagt: [...] blablabla [...]
 
    // "frage monster nach muenzen":
    // - der Fragensteller hoert:
@@ -109,47 +120,48 @@
    // - alle andere hoeren:
    //   "Das Monster fluestert <Fragenstellernamen> etwas zu."
 
-   ### dynamisch ###
+   // Beispiel 3: dynamisch
    // ein Prototyp, damit wir die Methode bekannt machen
-   static string query_kekse();
-   ...
-   AddInfo(({"keks","kekse"}),
-           #'query_kekse,             // ein Verweis auf die Funktion
-           "sagt: ");
-   ...
-   static string query_kekse() {
-    if(present("keks"))
-     return("Ich hab noch welche. Aetsch!");
-    return("Menno. Keine mehr da!");
-   }
+   protected string query_kekse();
 
+   AddInfo(({"keks","kekse"}),
+       #'query_kekse,        // ein Verweis auf die Funktion
+       "sagt: ");
+
+   protected string query_kekse() {
+     if(present("keks", this_object()))
+       return("Ich hab noch welche. Aetsch!");
+     else if(present("keks", environment()))
+       return("Da liegt einer!");
+     return("Menno. Keine mehr da!");
+   }
    // "frage monster nach keks":
    // - wenn es noch Kekse hat, hoeren alle:
    //   "Das Monster sagt: Ich hab noch welche. Aetsch!
    // - sonst:
    //   "Das Monster sagt: "Menno. Keine mehr da!
 
-   ### dynamischer ###
+   // Beispiel 4: dynamischer
    // ein Prototyp, damit wir die Methode bekannt machen
-   static string query_kekse();
-   static mixed case_fighting();
-   ...
+   protected string query_kekse();
+   protected mixed case_fighting();
+
    AddInfo(({"keks","kekse"}),
-           #'query_kekse,"            // ein Verweis auf die Funktion
-           sagt: ",
-           0,                         // nicht silent :)
-           #'case_fighting);          // noch ein Funktionsverweis
-   ...
-   static string query_kekse() {
-    if(present("keks"))
-     return("Ich hab noch welche. Aetsch!");
-    return("Menno. Keine mehr da!");
+       #'query_kekse,"        // ein Verweis auf die Funktion
+       sagt: ",
+       0,                     // nicht silent :)
+       #'case_fighting);      // noch ein Funktionsverweis
+
+   protected string query_kekse() {
+     if(present("keks"))
+       return("Ich hab noch welche. Aetsch!");
+     return("Menno. Keine mehr da!");
    }
 
-   static mixed case_fighting() {
-    if(InFight())
-     return("Keine Zeit fuer Kekse. Muss kaempfen.");
-    return 0;
+   protected mixed case_fighting() {
+     if(InFight())
+       return("Keine Zeit fuer Kekse. Muss kaempfen.");
+     return 0;
    }
 
    // "frage monster nach keks":
@@ -160,59 +172,53 @@
    // - sonst:
    //   "Das Monster sagt: "Menno. Keine mehr da!
 
-
-   ### dynamisch und komplex ###
+   // Beispiel 5: ### dynamisch und komplex ###
    // ein Prototyp, damit wir die Methode bekannt machen
-   static string question_gold();
-   ...
+   protected string question_gold();
 
    // "gold" wird eine Closure auf die Methode question_gold()
    // zugewiesen, ausserdem soll es still bleiben (wir informieren
    // den Restraum selbst)
-   AddInfo("gold",#'question_gold,"murmelt: ",1);
-   ...
+   AddInfo("gold", #'question_gold, "murmelt: ", 1);
 
    // los gehts, wir generieren unsere Antwort selbst
-   static string question_gold() {
-    int money;
-    string *y, objstr;
-    object o;
-    // wieviel Kohle hat der Spieler
-    money=this_player()->QueryMoney();
-    y=allocate(0);
-    // und jetzt suchen wir die Dinge aus Gold
-    o=first_inventory(this_player());
-    while(o) {
-     if(o->QueryMaterial(MAT_GOLD)>0 &&
-        strstr(object_name(o),"/obj/money"))
-      y+=({o->name(WER,1)});
-     o=next_inventory(o);
-    }
+   protected string question_gold() {
+     // wieviel Kohle hat der Spieler
+     int money = this_player()->QueryMoney();
+     string *y = map(deep_inventory(this_player()),
+                   function string(object o) {
+                     if(o->QueryMaterial(MAT_GOLD)>0 &&
+                        strstr(object_name(o),"/items/money")<0 &&
+                        o->QueryProp(P_NAME))
+                       return o->name(WER,1);
+                   })-({0});
 
-    // das geht an alle anderen im Raum, silent bietet sich hier
-    // nicht an, weil es mehrere Moeglichkeiten gibt
-    say(break_string(
-     Name(WER,1)+" murmelt "+
-     this_player()->name(WEM,1)+
-     " etwas zu"+
-     ((money || sizeof(y))?
-      " und glotzt "+
-      this_player()->QueryPronoun(WEN)+" gierig an.":
-      "."),78),({this_player()}));
-
-    // und hier die Antwort an den Spieler selbst, mit vielen
-    // Verzweigungen fuer dessen Besitztum
-    return("Ich hab kein Gold bei mir."+
+     // das geht an alle anderen im Raum, silent bietet sich hier
+     // nicht an, weil es mehrere Moeglichkeiten gibt
+     send_room(environment(),
+       (Name(WER,1)+" murmelt "+
+        this_player()->name(WEM,1)+
+        " etwas zu"+
         ((money || sizeof(y))?
+          " und glotzt "+this_player()->QueryPronoun(WEN)+" gierig an.":
+          ".")),
+       MT_LOOK|MT_LISTEN,
+       MA_EMOTE, 0, ({this_player()}));
+
+     // und hier die Antwort an den Spieler selbst, mit vielen
+     // Verzweigungen fuer dessen Besitztum
+     return("Ich hab kein Gold bei mir."+
+       ((money || sizeof(y))?
          " Aber du "+
-         (money?"hast ja jede Menge Kohle bei dir, so etwa "+money+
-          " Muenzen."+
-          (sizeof(y)?
-           " Ausserdem "+
-           ((sizeof(y)==1)?"ist":"sind")+
-           " auch noch "+CountUp(y)+" aus Gold.":
-           ""):
-          (sizeof(y)?" Aber was du so bei dir hast: "+
+         (money?
+           "hast ja jede Menge Kohle bei dir, so etwa "+money+
+           " Muenzen."+
+           (sizeof(y)?
+             " Ausserdem "+
+             ((sizeof(y)==1)?"ist":"sind")+
+             " auch noch "+CountUp(y)+" aus Gold.":
+             ""):
+           (sizeof(y)?"hast ja ein paar Wertsachen dabei: "+
            CountUp(y)+
            (sizeof(y)==1?" ist":" sind")+
            " aus Gold.":"")):
@@ -234,10 +240,19 @@
 SIEHE AUCH
 ==========
 
-   Verwandt:  AddSpecialInfo(L), RemoveInfo(L)
-   Props:     P_PRE_INFO, P_DEFAULT_INFO
-   Files:     /std/npc/info.c
-   Loggen:    P_LOG_INFO
-   Interna:   GetInfoArr, do_frage
+   Verwandt:
+      *AddSpecialInfo()*, *RemoveInfo()*
 
-7.Apr 2004 Gloinson
+   Props:
+      *P_PRE_INFO*
+
+   Files:
+      /std/npc/info.c
+
+   Loggen:
+      *P_LOG_INFO*
+
+   Interna:
+      *GetInfoArr()* , *do_frage()*
+
+7. Mar 2017 Gloinson
diff --git a/doc/lfun/AddRoomMessage b/doc/lfun/AddRoomMessage
index aa700c1..7d33a52 100644
--- a/doc/lfun/AddRoomMessage
+++ b/doc/lfun/AddRoomMessage
@@ -6,7 +6,7 @@
 FUNKTION
 ========
 
-   void AddRoomMessage(string *msg, int time, mixed *func);
+   void AddRoomMessage(string* msg, int time, mixed* func);
 
 
 DEFINIERT IN
@@ -18,67 +18,80 @@
 ARGUMENTE
 =========
 
-   msg
-        Array von Strings mit den Meldungen.
-   time
-        Der Abstand zwischen zwei Meldungen in Sekunden.
-   func (optional)
-        String oder Array von Strings mit Funktionsnamen
+   string* msg
+      Array von Strings mit den Meldungen.
+
+   int time
+      Der Abstand zwischen zwei Meldungen in Sekunden.
+
+   string|string* func (optional)
+      String oder Array von Strings mit Funktionsnamen
 
 
 BESCHREIBUNG
 ============
 
-   Mit dieser Funktion legt man fest, dass in bestimmten Zeitabstaenden
-   Meldungen an den Raum geschickt werden sollen.
+   Mit dieser Funktion legt man fest, dass in bestimmten
+   Zeitabstaenden Meldungen an den Raum geschickt werden sollen.
 
-   Es wird alle time Sekunden zufaellig eine der in msg angegebenen
-   Meldungen ausgegeben. Hat man auch noch func angegeben, so wird
-   zusaetzlich diese Funktion (bei einem Array: eine zufaellig ausgesuchte
-   Funktion) im Raum aufgerufen. Als Parameter bekommt die Funktion die
-   Nummer der ausgegebenen Meldung.
+   Es wird alle 'time' Sekunden (beim ersten Betreten durch einen
+   Spieler ein random() des Wertes) zufaellig eine der in msg
+   angegebenen Meldungen ausgegeben. Hat man func angegeben, so wird
+   diese Funktion (bei einem Array: eine zufaellig ausgesuchte
+   Funktion) im Raum aufgerufen. Als Parameter bekommt die Funktion
+   die Nummer der ggf zuvor ausgegebenen Meldung (Default also 0).
 
-   Bevor man allerdings jeden Raum mit AddRoomMessage() pflastert, sollte
-   man folgendes bedenken:
-      o Viele Meldungen in vielen Raeumen tendieren dazu, den Spielern auf
-        die Nerven zu gehen!
-      o Da das Timing ueber einen call_out() gesteuert wird, ist das Ganze
-        aus Sicht des GameDrivers auch noch relativ teuer!
-   Fazit: weniger ist mehr!
+   Bevor man allerdings jeden Raum mit AddRoomMessage() pflastert,
+   sollte man folgendes bedenken (Fazit: weniger ist mehr):
+
+   * Viele Meldungen in vielen Raeumen tendieren dazu, den Spielern
+     auf die Nerven zu gehen.
+
+   * Die das Timing steuernden call_out() sind nicht umsonst.
 
 
 BEMERKUNGEN
 ===========
 
-   * Falls time < 15 Sekunden ist, wird auf 15 Sekunden aufgerundet.
-   * der Praefix Add... taeuscht hier. Ein Aufruf von AddRoomMessage()
-     ueberschreibt alle vorherigen Werte
-   * THIS_PLAYER() NICHT VERWENDEN!
+   * falls time < 15 Sekunden ist, wird auf 15 Sekunden aufgerundet
+
+   * der Praefix Add... taeuscht hier. Ein Aufruf von
+     AddRoomMessage() ueberschreibt alle vorherigen Werte
+
+   * this_player() NICHT VERWENDEN!
+
+   * Abschalten der Raumnachrichten:
+
+     * passiert automatisch nur, wenn alle Spieler den Raum
+       verlassen haben
+
+     * ist manuell nur ueber Loeschen der Nachrichten umsetzbar,
+       also mit "AddRoomMessage((string)0, 0, (string)0);"
+
    In Funktionen, die durch AddRoomMessage() ausgeloest werden, darf
-   this_player() nicht verwendet werden. AddRoomMessage ist call_out-
-   gesteuert und speichert somit das this_player(). Damit ist this_player()
-   immer der Spieler, der den Raum geladen, also den Raum als erster
-   betreten hat.
-   Spieler also bitte selbst ueber filter(all_inventory(this_object()),
-                                          #'interactive) suchen.
+   this_player() nicht verwendet werden, da die call_out()-Kette den
+   ersten ausloesenden Spieler speichert. Anwesende Spieler also bitte
+   ggf mit "filter(all_inventory(this_object()), #'interactive)"
+   suchen.
 
 
 BEISPIELE
 =========
 
-   Es soll alle halbe Minute eine Meldung ausgegeben werden. Falls es
-   unter den Fuessen knackt, soll man zudem mit 30%-iger
-   Wahrscheinlichkeit zusammenzucken:
+   // Beispiel 1:
+   // Es soll alle halbe Minute eine Meldung ausgegeben werden. Falls es
+   // unter den Fuessen knackt, soll man zudem mit 30%-iger
+   // Wahrscheinlichkeit zusammenzucken:
 
    inherit "/std/room";
 
    void create() {
      ::create();
-     AddRoomMessage( ({ "In der Ferne schreit ein Kaeuzchen.\n",
-                        "Es raschelt im Gebuesch.\n",
-                        "Etwas knackt unter Deinen Fuessen.\n" }),
-                      30, ({"sound", "sound_more_rnd"}) );
-     ...
+     AddRoomMessage(({"In der Ferne schreit ein Kaeuzchen.\n",
+                       "Es raschelt im Gebuesch.\n",
+                       "Etwas knackt unter Deinen Fuessen.\n"}),
+                    30,
+                    ({"sound", "sound_more_rnd"}) );
    }
 
    void sound(int msg) {
@@ -88,16 +101,60 @@
    }
 
    // Extra-Beispiel: wir setzen die Wartedauer (Parameter tim) neu
-   void sound_more_rnd() {
-     sound(0);   // die Message-Nummer ist hier unwichtig
+   void sound_more_rnd(int msg) {
+     sound(msg);
      SetProp(P_MSG_PROB, 25+random(20));  // neue Wartedauer
    }
 
+   // Beispiel 2: Abschalten der Raumnachrichten
+   public int action_laerm(string str);
+   protected void reset_room_messages();
+
+   void create() {
+     ::create();
+     reset_room_messages();
+
+     AddCmd("mach|mache&laerm|krach",
+            "action_laerm",
+            "Was willst du machen?");
+     AddCmd("schlag|schlage&laerm|krach",
+            "action_laerm",
+            "Was willst du schlagen?");
+   }
+
+   protected void reset_room_messages() {
+     AddRoomMessage(({"Das Reh quakt leise.\n",
+                      "Der Frosch grunzt.\n",
+                      "Gelbe Schnorpfel pupsen im Takt.\n"}),
+                    45);
+   }
+
+   public int action_laerm(string str) {
+     AddRoomMessage((string)0, 0, (string)0);
+
+     this_player()->ReceiveMsg(
+       "Du schreist dir kurz die Seele aus dem Leib. Alle Tiere "
+       "verstummen sofort.", MT_NOTIFICATION);
+     send_room(this_object(),
+       this_player()->Name()+" schreit laut. Alle Tiere verstummen "
+       "sofort.", MT_LISTEN, 0, 0, ({this_player()}));
+     return 1;
+   }
+
+   void reset() {
+     :reset();
+     if(!QueryProp(P_ROOM_MSG))
+       reset_room_messages();
+   }
+
 
 SIEHE AUCH
 ==========
 
-   Verwandt: tell_room(), ReceiveMsg()
-   Props:    P_ROOM_MSG, P_FUNC_MSG, P_MSG_PROB
+   Verwandt:
+      tell_room(), *send_room()*, *ReceiveMsg()*
 
-2.Feb 2016 Gloinson
+   Props:
+      *P_MSG_PROB*, *P_FUNC_MSG*, *P_ROOM_MSG*
+
+28. Mar 2016 Gloinson
diff --git a/doc/lfun/Defend b/doc/lfun/Defend
index aa53945..3e40cfc 100644
--- a/doc/lfun/Defend
+++ b/doc/lfun/Defend
@@ -6,8 +6,9 @@
 FUNKTION
 ========
 
-   public int Defend(int dam, string|string* dam_type, int|mapping spell,
-                      object enemy)
+   public int Defend(int dam, string|string* dam_type, int|mapping
+   spell,
+      object enemy)
 
 
 DEFINIERT IN
@@ -19,120 +20,139 @@
 ARGUMENTE
 =========
 
-   int dam                  initiale Staerke des Angriffs (10 dam ~ 1 HP)
-   string* dam_type         Art(en) des Schadens, der angerichtet werden
-                            soll
-                            Muss ein Array von Schadenstypen sein,
-                            alte Objekte uebergeben hier manchmal strings.
-   int/mapping spell        - 0 fuer normale Angriffe (keine Zauber)
-                            - 1 fuer Zauber (Standardruestungen ignorieren)
-                            - mapping fuer mehr Informationen
-                            Heute bitte nach Moeglichkeit ein Mapping
-                            uebergeben.
-   object enemy             der Feind/Schadenverursacher
+   int dam
+      Initiale Staerke des Angriffs (10 dam ~ 1 HP)
+
+   string* dam_type
+      Art des Schadens, der angerichtet werden soll Muss ein Array von
+      Schadenstypen sein, alte Objekte uebergeben hier manchmal
+      strings.
+
+   mapping spell
+      Mapping mit zusaetzlichen Informationen zum Angriff(Siehe unten)
+      Alte Objekte uebergeben manchmal einen Integer (0 fuer
+      Physikalischen Angriff, 1 fuer Zauber.
+
+   object enemy
+      Der Feind/Schadenverursacher
 
 
 BESCHREIBUNG
 ============
 
    1. Generell
-   Wenn das Lebewesen angegriffen wird, wird geprueft, wie stark die
-   Ruestungen und koerpereigenen Abwehrkraefte sind und die Staerke des
-   Schadens dementsprechend vermindert.
-   Ggf. wird der Schaden zugefuegt und der Feind in  die Liste der Feinde
-   aufgenommen. Der Schaden betraegt:
-    (dam-Summe(Ruestungsstaerken)-random(P_BODY+A_DEX))*CheckResistance/10
-   aber nicht unter 0.
+
+      Wenn das Lebewesen angegriffen wird, wird geprueft, wie stark
+      die Ruestungen und koerpereigenen Abwehrkraefte sind und die
+      Staerke des Schadens dementsprechend vermindert. Ggf. wird der
+      Schaden zugefuegt und der Feind in  die Liste der Feinde
+      aufgenommen. Der Schaden betraegt: (dam-Summe(Ruestungsstaerken
+      )-random(P_BODY+A_DEX))*CheckResistance/10 aber nicht unter 0.
 
    2. Der Parameter 'spell'
-   Ist 'spell' 0, dann gilt der Angriff als normale physische Attacke
-   Uebergibt man als 'spell'-Parameter ein Mapping, so gibt es dafuer
-   diverse Flags, die das Ergebnis manipulieren (in new_skills.h
-   enthalten). Nichtangabe eines Flags gilt als 0.
 
-   - SP_PHYSICAL_ATTACK ---------- 0/1
-              1, wenn Ruestungen wirken sollen, 0 sonst
-              -> entspricht !spell, wenn dieses Int ist
-   - SP_NO_ENEMY ----------------- 0/1
-              1, falls der Angriff nicht toedlich ist, es also keinen echten
-              Gegner gibt
-              -> es wird dann reduce_hit_points() gerufen statt do_damage()
-   - SP_NO_ACTIVE_DEFENSE -------- 0/1
-              1, falls aktive Abwehren (wie zurueckschlagende Amulette,
-              Karateabwehren oder Ausweichmanoever) unterbleiben sollen
-              -> zB bei Kratzen durch Dornen oder Fall aus grosser Hoehe
-                 ist aktive Abwehr oder Ausweichen unlogisch
-   - SP_RECURSIVE ---------------- 0/1
-              1, falls der Spell aus einem Defend gerufen wurde (oder einer
-              DefendFunc)
-              -> verhindert Rekursionsprobleme
-   - SP_NAME --------------------- string
-              Name des Spells
-   - SP_REDUCE_ARMOUR ------------ Mapping: keys AT_X/P_BODY, values int>=0
-              Die Schutzwirkung durch P_AC/Magie einer Ruestung wird
-              typabhaengig reduziert. Aufbau eines Mappings im Beispiel:
-              ([AT_BOOTS: 0,  // Stiefel schuetzen gar nicht
-                P_BODY:  50,  // Koerper zu 50%
-                AT_BELT: 600  // Guertel zu 600%
-              ])
-              -> alle 'fehlenden' Eintraege wirken normal
-   - SP_SHOW_DAMAGE -------------- 0/1 oder Array von Arrays
-              0, fuer keine Treffermeldung, 1 sonst
-              In einem Array koennen Ersatz-Treffermeldungen definiert
-              werden. Format ist:
+      Ist 'spell' 0, dann gilt der Angriff als normale physische
+      Attacke Uebergibt man als 'spell'-Parameter ein Mapping, so gibt
+      es dafuer diverse Flags, die das Ergebnis manipulieren (in
+      new_skills.h enthalten). Nichtangabe eines Flags gilt als 0.
+
+      * SP_PHYSICAL_ATTACK ---------- 0/1 1, wenn Ruestungen wirken
+        sollen, 0 sonst -> entspricht !spell, wenn dieses Int ist
+
+      * SP_NO_ENEMY ----------------- 0/1 1, falls der Angriff nicht
+        toedlich ist, es also keinen echten Gegner gibt -> es wird
+        dann reduce_hit_points() gerufen statt do_damage()
+
+      * SP_NO_ACTIVE_DEFENSE -------- 0/1 1, falls aktive Abwehren
+        (wie zurueckschlagende Amulette, Karateabwehren oder
+        Ausweichmanoever) unterbleiben sollen -> zB bei Kratzen durch
+        Dornen oder Fall aus grosser Hoehe ist aktive Abwehr oder
+        Ausweichen unlogisch
+
+      * SP_RECURSIVE ---------------- 0/1 1, falls der Spell aus
+        einem Defend gerufen wurde (oder einer DefendFunc) ->
+        verhindert Rekursionsprobleme
+
+      * SP_NAME --------------------- string Name des Spells
+
+      * SP_GLOBAL_ATTACK ------------ 0/1 1 bei Flaechenspells
+
+      * SP_REDUCE_ARMOUR ------------ Mapping: keys AT_X/P_BODY,
+        values int>=0 Die Schutzwirkung durch P_AC/Magie einer
+        Ruestung wird typabhaengig reduziert. Aufbau eines Mappings im
+        Beispiel:
+
+           ([AT_BOOTS: 0,  // Stiefel schuetzen gar nicht P_BODY:  50,
+           // Koerper zu 50% AT_BELT: 600  // Guertel zu 600% ])
+
+        -> alle 'fehlenden' Eintraege wirken normal
+
+      * SP_SHOW_DAMAGE -------------- 0/1 oder Array von Arrays 0,
+        fuer keine Treffermeldung, 1 sonst In einem Array koennen
+        Ersatz-Treffermeldungen definiert werden. Format ist:
+
               ({
-               ({ int lphit1, string mess_me,
-                              string mess_en,
-                              string mess_room }),
-               ({ lphit2, mess_me, mess_en, mess_room }),
-               ...
-               ({ lphitn, mess_me, mess_en, mess_room }),
-              })
-              wobei lphit1<lphit2<...<lphitn sein muss, d.h. das Array-
-              Array aufsteigend sortiert.
 
-              Ist ein Treffer x LP hart, werden die Meldungen des lphit-
-              Arrays ausgegeben, dessen Wert am naehesten unter dem Schaden
-              liegt.
+           ({ int lphit1, string mess_me, string mess_en, string
+           mess_room }), ({ lphit2, mess_me, mess_en, mess_room }),
+           ... ({ lphitn, mess_me, mess_en, mess_room }), }) wobei
+           lphit1<lphit2<...<lphitn sein muss, d.h. das Array-Array
+           aufsteigend sortiert.
 
-              In den Meldungen mess_me (an den Getroffenen), mess_en (an
-              den Feind), mess_room (an die restlichen Umstehenden) koennen
-              Ersatzstrings wie folgt verwendet werden:
-              @WER1/@WESSEN1/@WEM1/@WEN1 - name(casus) des Getroffenen (TO)
-              @WER2/@WESSEN2/@WEM2/@WEN2 - name(casus) des Feindes (enemy)
-   - EINFO_DEFEND ------------ Mapping
-              Dieses Mapping liefert erweiterte Informationen zu dem
-              bisherigen Ablauf des aktiven Attacks.
-              Die verfuegbaren Informationen sind in der Manpage zu
-              DefendInfo festgehalten.
+        Ist ein Treffer x LP hart, werden die Meldungen des lphit-
+        Arrays ausgegeben, dessen Wert am naehesten unter dem Schaden
+        liegt.
+
+        In den Meldungen mess_me (an den Getroffenen), mess_en (an den
+        Feind), mess_room (an die restlichen Umstehenden) koennen
+        Ersatzstrings wie folgt verwendet werden:
+
+           @WER1/@WESSEN1/@WEM1/@WEN1 - name(casus) des Getroffenen
+           (TO) @WER2/@WESSEN2/@WEM2/@WEN2 - name(casus) des Feindes
+           (enemy)
+
+      * EINFO_DEFEND ------------ Mapping Dieses Mapping liefert
+        erweiterte Informationen zu dem bisherigen Ablauf des aktiven
+        Attacks. Die verfuegbaren Informationen sind in der Manpage zu
+        DefendInfo festgehalten.
 
    3. Reihenfolgen in Defend
-   - das Living wird angegriffen, wenn
-     - P_NO_ATTACK != 0
-     - 'enemy' existiert und kein netztoter Spieler ist
-   - P_DEFENDERS werden durchgegangen (und eventuell benachrichtigt)
-   - P_TMP_ATTACK_HOOK wird abgefragt
-   - die Ruestungen werden vom Schaden gegebenenfalls abgezogen
-   - magischer Ausweichskill beruecksichtigt
-   - sensitive Objekte werden ggf. benachrichtigt
-   - InternalModifyDefend wird gerufen
-   - Koerperabwehr abgezogen
-   - der Schaden an do_damage()/reduce_hit_points() uebergeben
-   - Flucht ueberpruefen mit CheckWimpyAndFlee()
+
+      * das Living wird angegriffen, wenn - P_NO_ATTACK != 0 -
+        'enemy' existiert und kein netztoter Spieler ist
+
+      * P_DEFENDERS werden durchgegangen (und eventuell
+        benachrichtigt)
+
+      * P_TMP_ATTACK_HOOK wird abgefragt
+
+      * die Ruestungen werden vom Schaden gegebenenfalls abgezogen
+
+      * magischer Ausweichskill beruecksichtigt
+
+      * sensitive Objekte werden ggf. benachrichtigt
+
+      * InternalModifyDefend wird gerufen
+
+      * Koerperabwehr abgezogen
+
+      * der Schaden an do_damage()/reduce_hit_points() uebergeben
+
+      * Flucht ueberpruefen mit CheckWimpyAndFlee()
 
 
 BEMERKUNGEN
 ===========
 
-   Ruestungen wirken konventionell nur, wenn mindestens ein Schadensanteil
-   mechanisch ist und es kein Spell oder ein Spell mit SP_PHYSICAL_ATTACK
-   auf 1 ist.
+   Ruestungen wirken konventionell nur, wenn mindestens ein
+   Schadensanteil mechanisch ist und es kein Spell oder ein Spell mit
+   SP_PHYSICAL_ATTACK auf 1 ist.
 
-   Defend() beruecksichtigt magische Verteidigungen, die der Spieler bei
-   sich hat, sollte also aus Fairness gegenueber den Objekten anderer
-   Magier immer dem direkten reduce_hit_points() oder do_damage()
-   vorgezogen werden. Mittels der Flags in 'spell' kann man sehr viel
-   aendern.
+   Defend() beruecksichtigt magische Verteidigungen, die der Spieler
+   bei sich hat, sollte also aus Fairness gegenueber den Objekten
+   anderer Magier immer dem direkten reduce_hit_points() oder
+   do_damage() vorgezogen werden. Mittels der Flags in 'spell' kann
+   man sehr viel aendern.
 
 
 RUECKGABEWERT
@@ -142,11 +162,11 @@
    Lebenspunkte des Lebewesens.
 
 BEISPIELE (SIEHE AUCH Defend_bsp):
-   // ein simpler Angriff: enem->Defend(100, ({DT_BLUDGEON}), 0,
-   this_object());
+   // ein simpler Angriff: enem->Defend(100, ({DT_BLUDGEON}),
+   ([SP_PHYSICAL_ATTACK:1]), this_object());
 
    // ein magischer Angriff (ohne Treffermeldung): enem->Defend(100,
-   ({DT_BLUDGEON, DT_FIRE}), 1, this_object());
+   ({DT_BLUDGEON, DT_FIRE}), ([SP_PHYSICAL_ATTACK:0]), this_object());
 
    // ein magischer Angriff mit Treffermeldung: enem->Defend(100,
    ({DT_BLUDGEON, DT_FIRE}), ([SP_SHOW_DAMAGE:1]),
@@ -157,19 +177,23 @@
 SIEHE AUCH
 ==========
 
-   Angriff:   Attack(L), P_NO_ATTACK, InsertEnemy(L)
-   Schaden:   P_ENABLE_IN_ATTACK_OUT, P_LAST_MOVE,
-              do_damage(L), reduce_hit_points(L)
-   Schutz:    P_DEFENDERS, InformDefend(L), DefendOther(L)
-              P_ARMOURS, P_AC, P_DEFEND_FUNC, QueryDefend(L)
-              P_BODY, A_DEX
-   Daten:     P_LAST_COMBAT_TIME
-              P_LAST_DAMTYPES, P_LAST_DAMTIME, P_LAST_DAMAGE
-              P_DAMAGE_MSG
-   Resistenz: P_RESISTANCE_STRENGTHS, CheckResistance(L)
-   Sonstiges: CheckSensitiveAttack(L)
-              InternalModifyDefend(L)
-              UseSkill(L),
-              DefendInfo
+   Angriff: *Attack()*, *P_NO_ATTACK*, *InsertEnemy()* Schaden:
+   *P_ENABLE_IN_ATTACK_OUT*,
 
-15.09.2010, Zesstra
+      *P_LAST_MOVE*, *do_damage()*, *reduce_hit_points()*
+
+   Schutz:    *P_DEFENDERS*, *InformDefend()*,
+      *DefendOther()*, *P_ARMOURS*, *P_AC*, *P_DEFEND_FUNC*,
+      *QueryDefend()*, *P_BODY*
+
+   Daten:     *P_LAST_COMBAT_TIME*,
+      *P_LAST_DAMTYPES*, *P_LAST_DAMTIME*, *P_LAST_DAMAGE*,
+      *P_DAMAGE_MSG*
+
+   Resistenz: *P_RESISTANCE_STRENGTHS*,
+      *CheckResistance()*
+
+   Sonstiges: *CheckSensitiveAttack()*,
+      *InternalModifyDefend()*, *UseSkill()*, *DefendInfo()*
+
+Letzte Aenderung: 29.12.2017, Bugfix
diff --git a/doc/lfun/DefendFunc b/doc/lfun/DefendFunc
index 1683b3f..a544cc2 100644
--- a/doc/lfun/DefendFunc
+++ b/doc/lfun/DefendFunc
@@ -3,43 +3,39 @@
 ************
 
 
-DefendFunc(L)
-=============
-
-
 FUNKTION
 ========
 
-   int DefendFunc(string|string *dtyp, int|mappingspell, object enemy);
+   public int DefendFunc(string* dtyp, mapping spell, object enemy);
 
 
 DEFINIERT IN
 ============
 
-   eigenen Objekten; fuer /std/armour/combat.c
+   Eigenen Objekten; fuer /std/armour/combat.c
 
 
 ARGUMENTE
 =========
 
    dtyp
-        Schadenstypen der Angriffsart.
-        Sollte heute ein string* sein.
+      Schadenstypen der Angriffsart.
+
    spell
-        0 bei veralteten konventionellen Angriffen im Regelfall jedoch
-        ein Mapping mit weiteren Infos.
-        Bei einem konventionellen Angriff ist spell[SP_PHYSICAL_ATTACK] gleich
-        1.
+      Ein Mapping mit weiteren Infos. Bei einem konventionellen
+      Angriff ist spell[SP_PHYSICAL_ATTACK] gleich 1.
+
    enemy
-        Der angreifende Gegner
+      Der angreifende Gegner
 
 
 BESCHREIBUNG
 ============
 
-   Anhand der uebergebenen Parameter kann hier ein Ruestungsbonus (oder
-   auch ein Ruestungsmalus) errechnet werden, der zu dem normalen
-   Ruestungswert (abhaengig von der Angriffsart) hinzuaddiert wird.
+   Anhand der uebergebenen Parameter kann hier ein Ruestungsbonus
+   (oder auch ein Ruestungsmalus) errechnet werden, der zu dem
+   normalen Ruestungswert (abhaengig von der Angriffsart) hinzuaddiert
+   wird.
 
 
 RUeCKGABEWERT
@@ -54,8 +50,9 @@
    Auch wenn man eine DefendFunc() benutzt, darf der Rueckgabewert
    zusammen mit der P_AC insgesamt nur in sehr seltenen, wohldurch-
    dachten Ausnahmefaellen die maximal zulaessige P_AC fuer diesen
-   Ruestungstyp ueberschreiten. In solchen Ausnahmefaellen duerfen
-   die DefendFuncs nicht konstant wirken.
+   Ruestungstyp ueberschreiten. In solchen Ausnahmefaellen duerfen die
+   DefendFuncs nicht konstant wirken. Ausserdem sind solche Ruestungen
+   immer genehmigungspflichtig.
 
    Bei aktivem Zurueckschlagen IMMER auf Flags wie SP_RECURSIVE und
    SP_NO_ACTIVE_DEFENSE pruefen und ggf. abbrechen.
@@ -64,44 +61,46 @@
 BEISPIELE
 =========
 
-   Eine Ruestung, die bei Angriffen mit Feuer ihre volle Staerke entfaltet
-   und bei Angriffen durch Geister geschwaecht wird:
+   Eine Ruestung, die bei Angriffen mit Feuer ihre volle Staerke
+   entfaltet und bei Angriffen durch Geister geschwaecht wird:
 
-   void create()
-   {
-     ::create();
+   protected void create() {
 
-     SetProp(P_ARMOUR_TYPE, AT_ARMOUR);
-     SetProp(P_AC, 20);
-     ...
-     // Die DefendFunc() ist in der Ruestung selbst definiert
-     SetProp(P_DEFEND_FUNC, this_object());
+      ::create();
+
+      SetProp(P_ARMOUR_TYPE, AT_ARMOUR); SetProp(P_AC, 20); ... // Die
+      DefendFunc() ist in der Ruestung selbst definiert
+      SetProp(P_DEFEND_FUNC, this_object());
+
    }
 
-   int DefendFunc(string *dtyp, mixed spell, object enemy)
-   {
-     int prot;
+   public int DefendFunc(string* dtyp, mapping spell, object enemy) {
 
-     // Zuerst fragen wir den Angriff durch Feuer ab:
-     if (member(dtyp, DT_FIRE) >= 0)  // Feuer gehoert zu den Schadenstypen
-       prot = 5 + random(10); // Das ergibt maximal 14. Zusammen mit P_AC
-                              // kommt man also maximal auf 14+20 = 34,
-                              // liegt also unter der fuer AT_ARMOUR
-                              // geltenden Obergrenze
+      int prot;
 
-     // Und jetzt der Geistertest
-     if (enemy->QueryProp(P_RACE) == "Geist" ||
-         enemy->is_class_member(CL_GHOST))
-       prot -= random(10);
+      // Zuerst fragen wir den Angriff durch Feuer ab: if
+      (member(dtyp, DT_FIRE) >= 0)  // Feuer gehoert zu den
+      Schadenstypen
 
-     // Der Rueckgabewert wird auf den aus P_AC errechneten Wert draufgeschlagen
-     return prot;
+         prot = 5 + random(10); // Das ergibt maximal 14. Zusammen mit
+         P_AC
+            // kommt man also maximal auf 14+20 = 34, // liegt also
+            unter der fuer AT_ARMOUR // geltenden Obergrenze
+
+      // Und jetzt der Geistertest if (enemy->QueryProp(P_RACE) ==
+      "Geist" ||
+
+            enemy->is_class_member(CL_GHOST))
+
+         prot -= random(10);
+
+      // Der Rueckgabewert wird auf den aus P_AC errechneten Wert
+      draufgeschlagen return prot;
+
    }
 
 
 SIEHE AUCH
 ==========
 
-   P_DEFEND_FUNC, QueryDefend(), /std/armour/combat.c
-
-Last modified: 18.Jul 2006 Muadib
+   *P_DEFEND_FUNC*, "QueryDefendd" /std/armour/combat.c
diff --git a/doc/lfun/GetShopItems b/doc/lfun/GetShopItems
new file mode 100644
index 0000000..9c7f28d
--- /dev/null
+++ b/doc/lfun/GetShopItems
@@ -0,0 +1,40 @@
+
+GetShopItems()
+**************
+
+
+FUNKTION
+========
+
+   protected object* GetShopItems()
+
+
+DEFINIERT IN
+============
+
+   /std/room/shop.c
+
+
+BESCHREIBUNG
+============
+
+   Erstellt ein Array mit den zum Verkauf stehenden Objekten.
+
+
+BEMERKUNG
+=========
+
+   Enthaelt nur jeweils einen Clone von jeder Blueprint.
+
+
+RUECKGABEWERTE
+==============
+
+   Object-Array mit zuerst den Objekten im Store und anschliessend den
+   fixed-Objects.
+
+
+SIEHE AUCH
+==========
+
+   *PrintList()*
diff --git a/doc/lfun/GuildName b/doc/lfun/GuildName
new file mode 100644
index 0000000..4a4dbdf
--- /dev/null
+++ b/doc/lfun/GuildName
@@ -0,0 +1,37 @@
+
+GuildName()
+***********
+
+
+FUNKTION
+========
+
+   string GuildName()
+
+
+DEFINIERT IN
+============
+
+   /std/gilden_ob.c
+
+
+RUeCKGABEWERT
+=============
+
+   string mit Gildennamen
+
+
+BESCHREIBUNG
+============
+
+   Gibt Gildennamen (genauer: object_name ohne "/gilden/") zurueck.
+
+
+SIEHE AUCH
+==========
+
+   Verwandt:
+      *GuildName()*
+
+   Props:
+      *P_GUILD*
diff --git a/doc/lfun/InternalModifyDefend b/doc/lfun/InternalModifyDefend
index 3015534..3762c07 100644
--- a/doc/lfun/InternalModifyDefend
+++ b/doc/lfun/InternalModifyDefend
@@ -10,8 +10,8 @@
 FUNKTION
 ========
 
-   protected void InternalModifyDefend(int dam, mixed dt, mixed spell,
-                                    object enemy)
+   protected void InternalModifyDefend(int dam, string* dt, mapping
+   spell, object enemy)
 
 
 DEFINIERT IN
@@ -23,28 +23,31 @@
 ARGUMENTE
 =========
 
-   int dam             Staerke des abzuwehrenden Angriffs (in HP/10)
-   string/string* dt   Art(en) des Schadens, der angerichtet werden soll
-   int/mapping spell   0 fuer normale Angriffe (keine Zauber)
-                       1 fuer Zauber (Standardruestungen ignorieren)
-                       mapping fuer mehr Informationen
-   object enemy        der Feind/Schadenverursacher
+   int dam
+      Staerke des abzuwehrenden Angriffs (in HP/10)
+
+   string* dt
+      Art(en) des Schadens, der angerichtet werden soll
+
+   mapping spell
+      Mapping mit zusaetzlichen Informationen ueber den Angriff
+
+   object enemy
+      der Feind/Schadenverursacher
 
 
 BESCHREIBUNG
 ============
 
    Dient dazu noch Aenderungen am Verhalten der Defend() vornehmen zu
-   koennen. Die Parameter werden alle per Referenz uebergeben, Aenderungen
-   wirken also direkt in der Defend()!
-   Einfach ueberschreiben, aber ::InternalModifyDefend(&..., &....) nicht
-   vergessen!
+   koennen. Die Parameter werden alle per Referenz uebergeben,
+   Aenderungen wirken also direkt im Defend()!
+
+   Einfach ueberschreiben, aber ::InternalModifyDefend(&..., &....)
+   nicht vergessen!
 
 
 SIEHE AUCH
 ==========
 
-   InternalModifyAttack(L)
-   Defend(L)
-
-28.03.2008, Zesstra
+   *InternalModifyAttack()* *Defend()*
diff --git a/doc/lfun/IsGuildMember b/doc/lfun/IsGuildMember
new file mode 100644
index 0000000..bc29366
--- /dev/null
+++ b/doc/lfun/IsGuildMember
@@ -0,0 +1,67 @@
+
+IsGuildMember()
+***************
+
+
+FUNKTION
+========
+
+   varargs int IsGuildMember(object pl)
+
+
+DEFINIERT IN
+============
+
+   /std/gilden_ob.c
+
+
+RUeCKGABEWERT
+=============
+
+   1
+      wenn Gildenmitglied
+
+   0
+      sonst
+
+
+BESCHREIBUNG
+============
+
+   Gibt 1 zurueck, wenn der Spieler Gildenmitglied ist, d.h. P_GUILD
+   entsprechend den Gildennamen gesetzt ist. Weitere Pruefungen auf
+   Properties oder Skills werden nicht vorgenommen.
+
+   Kann fuer Spieleraktionen im Gildenraum benutzt werden. Setzt
+   bereits ein _notify_fail() fuer Nichtgildenmitglieder.
+
+
+BEISPIEL
+========
+
+   protected int clown_weihe(string str)
+   {
+     if(IsGuildMember()) {
+       tortenweihe+=getuid(this_player());
+       this_player()->ReceiveMsg(
+         "Du kniest nieder und empfaengt die Torte des Meisterclown.",
+         MT_NOTIFICATION);
+       send_room(
+         this_object(),
+         this_player()->Name()+" kniet nieder und wird wuerdig getortet.",
+         MT_LOOK|MT_LISTEN,
+         MA_EMOTE, 0, ({this_player()}));
+       return 1;
+     }
+     return 0;
+   }
+
+
+SIEHE AUCH
+==========
+
+   Verwandt:
+      *GuildName()*
+
+   Props:
+      *P_GUILD*
diff --git a/doc/lfun/PreventFollow b/doc/lfun/PreventFollow
index c3de6b1..fcfc2a6 100644
--- a/doc/lfun/PreventFollow
+++ b/doc/lfun/PreventFollow
@@ -12,61 +12,50 @@
 ARGUMENTE
 =========
 
-   dest: Zielobjekt, in das der Verfolgte bewegt werden soll.
+   dest:
+      Zielobjekt, in das der Verfolgte bewegt werden soll.
 
 
 FUNKTION
 ========
 
    In jedem Verfolger, der mit AddPursuer in die Liste der Verfolger
-   eingetragen wurde, wird vor dem Bewegen in das Zielobjekt die Funktion
-   PreventFollow mit dem Zielobjekt als Argument aufgerufen.
+   eingetragen wurde, wird vor dem Bewegen in das Zielobjekt die
+   Funktion PreventFollow mit dem Zielobjekt als Argument aufgerufen.
 
 
 RUECKGABEWERT
 =============
 
-   0: Verfolger darf in das Zielobjekt folgen
-   1: Verfolger darf in dieses Zielobjekt nicht folgen
-      (Verfolgung bleibt weiterhin aktiv)
-   2: Verfolger darf in dieses Zielobjekt nicht folgen
-      (Verfolgung wird abgebrochen und Verfolger aus der Verfolgerliste
-       ausgetragen)
+   0:
+      Verfolger darf in das Zielobjekt folgen
 
+   1:
+      Verfolger darf in dieses Zielobjekt nicht folgen (Verfolgung
+      bleibt weiterhin aktiv)
 
-BEMERKUNG
-=========
-
-   Durch PreventFollow kann der raeumliche Bereich, in dem verfolgt werden
-   darf, eingeschraenkt werden.
+   2:
+      Verfolger darf in dieses Zielobjekt nicht folgen (Verfolgung
+      wird abgebrochen und Verfolger aus der Verfolgerliste
+      ausgetragen)
 
 
 BEISPIELE
 =========
 
-   Man moechte, dass ein NPC auf einer Insel nicht mit dem Spieler in das
-   Boot steigt, um mit dem Spieler zusammen von der Insel herunterzukommen.
+   Man moechte, dass nur dann verfolgt wird, wenn das Ziel im gleichen
+   Gebiet liegt, wie man selber (wenn __PATH__(1) das
+   Gebietsverzeichnis ist):
 
-   #define PATH(x) ("/d/.../.../mein/pfad/+(x)")
+   int PreventFollow(object ziel) {
 
-   ...
+      if (strstr(load_name(ziel), __PATH__(1)) != 0)
+         return 1;
 
-   int PreventFollow(object boot)
-    {
-     if ( object_name(boot)[0..strlen(PATH("boot"))-1] == PATH("boot") )
-      return 1;
-    }
-
-   Diese Funktions-Definition ist sehr flexibel, denn sie erlaubt sowohl
-   spaetere Pfadanpassung als auch mehrere Boote.
-   Da ueber die Funktion strlen() nur bis zum letzten Buchstaben des
-   angegebenen Strings getestet wird, wird also gleichzeitig auch auf
-   boot[1], boot[2] usw. getestet.
+   }
 
 
 SIEHE AUCH
 ==========
 
-   "AddPursuer", "RemovePursuer"
-
-Last modified: Tue Jun 10 13:59:30 2003 by Gabylon
+   * *AddPursuer()*, *RemovePursuer()*
diff --git a/doc/lfun/PrintList b/doc/lfun/PrintList
new file mode 100644
index 0000000..18be079
--- /dev/null
+++ b/doc/lfun/PrintList
@@ -0,0 +1,57 @@
+
+PrintList()
+***********
+
+
+FUNKTION
+========
+
+   varargs protected int PrintList(string filter_fun, int liststyle)
+
+
+DEFINIERT IN
+============
+
+   /std/room/shop.c
+
+
+ARGUMENTE
+=========
+
+   string filter_fun:
+      Bestimmt welche Art von Items angezeigt werden sollen (z.B. nur
+      Waffen).
+
+   int liststyle:
+      Angabe zur Formatierung. - 1: Einspaltige Ausgabe mit mehr
+      Zeichen fuer den Namen. - 0: Die Standardausgabe mit zwei
+      Spalten.
+
+
+BESCHREIBUNG
+============
+
+   Erstellt anhand der Parameter und dem Rueckgabewert von
+   GetShopItems() die Ausgabe der zu verkaufenden Gegenstaende fuer
+   den Spieler.
+
+
+RUECKGABEWERTE
+==============
+
+   Immer 1.
+
+
+BEMERKUNGEN
+===========
+
+   filter_fun bekommt als Argument ein Objekt uebergeben und muss
+   einen Wert !=0 zurueckgeben, wenn das Objekt in die Ausgabe
+   aufgenommen werden soll. Es funktionieren alle Datentypen, es
+   empfiehlt sich aber ein Integer von 1 fuer true.
+
+
+SIEHE AUCH
+==========
+
+   *GetShopItems()*
diff --git a/doc/lfun/RemoveExtraLook b/doc/lfun/RemoveExtraLook
index 0369992..1bcde43 100644
--- a/doc/lfun/RemoveExtraLook
+++ b/doc/lfun/RemoveExtraLook
@@ -2,11 +2,11 @@
 RemoveExtraLook()
 *****************
 
-RemoveExtraLook()
 
+FUNKTION
+========
 
-int RemoveExtraLook(string look);
-=================================
+int RemoveExtraLook(string key);
 
 
 DEFINIERT IN
@@ -15,51 +15,78 @@
    /std/living/description.c
 
 
+ARGUMENTE
+=========
+
+   * string key: Schluessel, unter dem der Extralook registriert
+     wurde ODER Objektname des registrierenden Objektes
+
+
 BESCHREIBUNG
 ============
 
    Der Extralook erscheint in der Langbeschreibung des Lebewesens.
-   Eintraege koennen mit dieser Funktion (vorzeitig) wieder entfernt werden.
 
-
-ARGUMENTE
-=========
-
-   - string look:
-     Schluesselwort, unter dem der Eintrag, den man entfernen moechte, von
-     AddExtraLook() registriert wurde.
-
-
-RUECKGABEWERTE
-==============
-
-   > 0, falls der Eintrag erfolgreich entfernt wurde.
-   < 0 sonst.
-     -1: keinen (gueltigen) <key> uebergeben.
-     -2: kein Eintrag fuer <key> gefunden.
+   Eintraege koennen mit dieser Funktion (vorzeitig) wieder entfernt
+   werden. Dazu wird entweder der selbst festgelegte Schluessel oder
+   der implizite Schluessel *object_name()* des setzenden Objekts
+   benoetigt.
 
 
 BEMERKUNGEN
 ===========
 
-   Beim Entfernen mit dieser Funktion wird die "Endemeldung" des entfernten
-   Eintrages nicht ausgegeben.
+   Beim Entfernen mit dieser Funktion wird die "Endemeldung" des
+   entfernten Eintrages nicht ausgegeben.
+
+
+RUECKGABEWERTE
+==============
+
+   Siehe auch /sys/living/description.h fuer Konstanten.
+
+   * 1, falls der Eintrag erfolgreich entfernt wurde.
+
+   * < 0 sonst.
+
+     * -1: keinen (gueltigen) <key> uebergeben.
+
+     * -2: kein Eintrag fuer <key> gefunden.
 
 
 BEISPIELE
 =========
 
-   # Extralook registrieren.
-   living->AddExtraLook("@WER1 wird von einer Horde Daemonen verfolgt.",
-                        "ennox_daemonenhordenverfolgerlook");
-   # Nun kann der Eintrag auch wieder entfernt werden:
+   // (1) Loeschen ueber expliziten Key
+   living->AddExtraLook(
+     "@WER1 wird von einer Horde Daemonen verfolgt.",
+     1800, "ennox_daemonenhordenverfolgerlook");
+
+   // Nun kann der Eintrag auch wieder entfernt werden:
    living->RemoveExtraLook("ennox_daemonenhordenverfolgerlook");
 
+   // (2) Loeschen ueber impliziten Objektnamen-Schluessel
+   living->AddExtraLook("Eine Sonnenblume ragt aus dem Ohr.")
+   // das ist nur aus dem gleichen Objekt heraus moeglich:
+   living->RemoveExtraLook(0);
+
+   // (3) Loeschen ueber impliziten Objektnamen-Schluessel
+   string implizite_id = object_name(this_object());
+   living->AddExtraLook("Eine Sonnenblume ragt aus dem Ohr.")
+   // diese ID kann man natuerlich durch die Gegend schicken
+   living->RemoveExtraLook(implizite_id);
+
 
 SIEHE AUCH
 ==========
 
-   AddExtraLook(),
-   P_INTERNAL_EXTRA_LOOK
+   Verwandt:
+      *AddExtraLook()*, *P_INTERNAL_EXTRA_LOOK*
 
-14.05.2007, Zesstra
+   Sonstiges:
+      *replace_personal()*, *break_string()*
+
+   Fuer Spielerobjekte:
+      *P_EXTRA_LOOK*
+
+15. Jun 2017 Gloinson
diff --git a/doc/lfun/SetAttackChats b/doc/lfun/SetAttackChats
index 90e8a66..b5a26e9 100644
--- a/doc/lfun/SetAttackChats
+++ b/doc/lfun/SetAttackChats
@@ -18,87 +18,108 @@
 ARGUMENTE
 =========
 
-   chance
-        Prozentuale Wahrscheinlichkeit einer Ausgabe
-   strs
-        Stringarray mit den Monsterchats
+   int chance
+      Prozentuale Wahrscheinlichkeit einer Ausgabe
+
+   mixed strs
+      Array mit den verschiedenen Moeglichkeiten der Monsterchats
 
 
 BESCHREIBUNG
 ============
 
-   Der NPC gibt mit der Wahrscheinlichkeit 'chance' einen zufaellig
-   gewaehlten Text aus 'strs' von sich. Die Arrayelemente koennen
-   auch Funktionen ("@@func@@") oder Closures enthalten, die dann
-   aufgerufen werden und deren Rueckgabewerte das Monster dann ausgibt.
+   Der NPC gibt mit der Wahrscheinlichkeit <chance> waehrend des
+   Kampfes pro Heartbeat einen zufaellig gewaehlten Text aus dem Array
+   <strs> in den Raum aus. Dabei wird per Default send_room() ohne
+   erneutes Umbrechen mit den Messagetypen
+   MT_LOOK|MT_LISTEN|MT_FEEL|MT_SMELL verwendet.
 
+   Die einzelnen Arrayelemente koennen:
 
-RUECKGABEWERT
-=============
+      * Strings sein
 
-   keiner
+      * Closures sein, deren Rueckgabe ausgegeben wird und die
+        zusaetzlich einen aenderbaren und in send_room() verwendeten
+        'msg_typ' per Referenz uebergeben bekommen
+
+      * Arrays mit der Struktur *({<string|closure msg >, <int
+        msg_typ>})* sein, fuer die obige Regeln auf 'msg' angewendet
+        werden und bei denen 'msg_typ' im send_room() verwendet wird
+
+   Fuer keine Ausgabe muss man einen Leerstring "" zurueckgeben oder
+   verwenden. In allen Funktionen ist this_player() das Monster
+   selbst. Normalerweise muss man die Nachrichten selbst umbrechen,
+   ausser man uebergibt die Message-Typen explizit und uebergibt kein
+   MSG_DONT_WRAP.
 
 
 BEMERKUNGEN
 ===========
 
-   AttackChats werden nur im Kampf ausgegeben. Ansonsten ist SetChats()
-   zu verwenden.
+   * ausserhalb des  Kampf werden keine AttackChats ausgegeben, man
+     muss dann SetChats() verwenden
 
+   * die strings werden (noch) durch process_string() geschickt,
+     dieses sollte man aber nicht mehr verwenden
 
+   * 'chance' gilt sowohl fuer Attack- als auch normale Chats
 
-   'chance' wird in der Property P_ACHAT_CHANCE abgelegt. Um einen NPC
-   voruebergehend 'stillzulegen', kann man P_ACHAT_CHANCE auf 0 setzen.
+   * 'chance' wird in der Property P_CHAT_CHANCE abgelegt. Um einen
+     NPC voruebergehend 'stillzulegen', kann man P_CHAT_CHANCE auf 0
+     setzen
 
+   * Spieler koennen P_CHAT_CHANCE temporaer auf 0 setzen
+     ('stillen')
 
+   * NPC haben bei Abwesenheit von Spielern in der Regel keinen
+     Heartbeat, weswegen dann auch die Chats ausgeschaltet sind
 
-   Man kann AttackChats nutzen, um Monsterspells zu realisieren. Besser
-   ist es aber, dafuer 'AddSpell' zu verwenden.
+   * send_room() bekommt immer MSG_DONT_STORE|MSG_DONT_BUFFER
+     uebergeben
+
+   Man kann AttackChats nutzen, um Monsterspells zu realisieren.
+   Besser ist es aber, dafuer 'AddSpell' zu benutzen, ausser man
+   moechte zB die Spielerfaehigkeit des Abschaltens der Chats
+   verwenden.
 
 
 BEISPIELE
 =========
 
+   protected string knirschschrei(int msg_typ);
+
    SetAttackChats( 20,
-     ({ "Der Ork tritt Dir in den Hintern.\n",
-        "Der Ork bruellt: Lebend kommst Du hier nicht raus!\n",
-        "Der Ork blutet schon aus mehreren Wunden.\n",
-        "@@knirsch@@" }) );
+    ({"Der Ork tritt Dir in den Hintern.\n",
+      ({"Der Ork bruellt: Lebend kommst Du hier nicht raus!\n", MT_LISTEN}),
+      ({"Der Ork blutet schon aus mehreren Wunden.\n", MT_LOOK}),
+      #'knirschschrei}));
 
-
-
-   string knirsch()
-   {
-     object *ruestung, *tmp, helm;
-
-
-
-     ruestung = this_player()->QueryProp(P_ARMOURS); // getragene Ruestung
-     tmp = filter_objects(ruestung, "id", AT_HELMET);
-     // Wenn der Spieler einen Helm traegt, enthaelt 'tmp' jetzt
-     // ein Array mit dem Helmobjekt als einzigem Element
-     if (sizeof(tmp)) helm = tmp[0];
-       if (objectp(helm))
-       {
-         // AC nur dann senken, wenn sie nicht schon 0 ist.
-         if (helm->QueryProp(P_AC)>0) {
-           helm->Damage(1);
-           return "Der Ork beschaedigt Deinen Helm!\n";
-         }
-         return "";
+   protected string knirsch(int msg_typ) {
+     object helm = this_player()->QueryArmourByType(AT_HELMET);
+     if (objectp(helm)) {
+       // AC nur dann senken, wenn sie nicht schon 0 ist.
+       if (helm->QueryProp(P_AC)>0) {
+         helm->Damage(1);
+         msg_typ = MT_LISTEN|MT_FEEL;
+         return ("Der Ork schreit dich so laut an, dass dabei "+
+                 helm->QueryOwn(WER)+" "+
+                 helm->name(RAW)+" beschaedigt wird.");
        }
-       else
-         return ""; // keine Meldung
+     }
+     return ""; // keine Meldung
    }
 
 
 SIEHE AUCH
 ==========
 
-   P_ACHAT_CHANCE, SetChats(), /std/npc/chat.c, AddSpell()
+   Verwandt:
+      *SetChats()*, *AddSpell()*
 
+   Props:
+      *P_CHAT_CHANCE*
 
-LETZTE AENDERUNG
-================
+   Sonstiges:
+      *send_room()*, *process_string()*
 
-   Don, 27.12.2007, 16:35:00 von Arathorn
+3. April 2017 Gloinson
diff --git a/doc/lfun/SetChats b/doc/lfun/SetChats
index 70d312e..ee6d04b 100644
--- a/doc/lfun/SetChats
+++ b/doc/lfun/SetChats
@@ -6,7 +6,7 @@
 FUNKTION
 ========
 
-   void SetChats(int chance,mixed strs);
+   void SetChats(int chance, mixed strs);
 
 
 DEFINIERT IN
@@ -18,77 +18,139 @@
 ARGUMENTE
 =========
 
-   chance
-     Prozentuale Wahrscheinlichkeit einer Ausgabe
-   strs
-     Stringarray mit den Monsterchats
+   int chance
+      Prozentuale Wahrscheinlichkeit einer Ausgabe
+
+   mixed strs
+      Array mit den verschiedenen Moeglichkeiten der Monsterchats
 
 
 BESCHREIBUNG
 ============
 
-   Der NPC gibt mit der Wahrscheinlichkeit <chance> pro Heartbeat einen
-   zufaellig gewaehlten Text aus dem Array <strs> von sich.
-   Die Arrayelemente koennen auch Closures oder
-   process_string()-Funktionen ("@@func@@") enthalten, die dann
-   aufgerufen werden und deren Rueckgabewerte das Monster dann ausgibt.
-    (Fuer keine Ausgabe dann Leerstring "" zurueckgeben!)
-   In diesen Funktionen ist this_player() das Monster selbst!
-   Fuer Zeilenumbrueche ist immer selbst zu sorgen.
+   Der NPC gibt mit der Wahrscheinlichkeit <chance> pro Heartbeat
+   einen zufaellig gewaehlten Text aus dem Array <strs> in den Raum
+   aus. Dabei wird per Default send_room() ohne erneutes Umbrechen mit
+   den Messagetypen MT_LOOK|MT_LISTEN|MT_FEEL|MT_SMELL verwendet.
 
+   Die einzelnen Arrayelemente koennen:
 
-RUECKGABEWERT
-=============
+      * Strings sein
 
-   keiner
+      * Closures sein, deren Rueckgabe ausgegeben wird und die
+        zusaetzlich einen aenderbaren und in send_room() verwendeten
+        'msg_typ' per Referenz uebergeben bekommen
 
+      * Arrays mit der Struktur *({<string|closure msg >, <int
+        msg_typ>})* sein, fuer die obige Regeln auf 'msg' angewendet
+        werden und bei denen 'msg_typ' im send_room() verwendet wird
 
-BEISPIELE
-=========
-
-   Ein einfaches Beispiel:
-     // Prototype fuer Closure.
-     static string info1();
-     void create()
-     { ...
-       SetChats(20,
-      ({"Der Ork sagt: Hau ab, bevor ich Dich fresse.\n",
-        "Der Ork grinst Dich unverschaemt an.\n",
-        "Der Ork wedelt mit seinem Saebel vor Deinem Gesicht herum.\n",
-        "Der Ork droht Dir mit der Faust.\n",
-        #'info1,
-        "@@info2@@"}));
-     }
-     // Funktion als Closure. Prototype notwendig!
-     static string info1()
-     { if(QueryProp(P_HP)<QueryProp(P_ALIGN))
-         return"Gleich werde ich von hier fliehen!\n";
-       return"";
-     }
-     // Funktion als process_string().
-     string info2()
-     { return QueryProp(P_HP)==QueryProp(P_MAX_HP)?
-    "Der Ork grinst: Mir geht es fantastisch!\n":
-    "Der Ork seufzt: Mir ging es wirklich schon mal besser.\n";
-     }
+   Fuer keine Ausgabe muss man einen Leerstring "" zurueckgeben oder
+   verwenden. In allen Funktionen ist this_player() das Monster
+   selbst. Normalerweise muss man die Nachrichten selbst umbrechen,
+   ausser man uebergibt die Message-Typen explizit und uebergibt kein
+   MSG_DONT_WRAP.
 
 
 BEMERKUNGEN
 ===========
 
-         Im Kampf werden keine Chats ausgegeben. Es ist dann SetAttackChats()
-         zu verwenden.
-         Funktionen als process_string() sollte man nicht mehr verwenden.
-         <chance> wird in der Property P_CHAT_CHANCE abgelegt. Um einen NPC
-         voruebergehend 'stillzulegen', kann man P_CHAT_CHANCE auf 0 setzen.
-   Wenn kein Spieler anwesend ist, haben NPC in der Regel keinen Heartbeat,
-   weswegen dann auch die Chats ausgeschaltet sind.
-   Spieler koennen NPC 'stillen', d.h. Chats und AttackChats abschalten.
+   * im Kampf werden keine Chats ausgegeben, man muss dann
+     SetAttackChats() verwenden
+
+   * die strings werden (noch) durch process_string() geschickt,
+     dieses sollte man aber nicht mehr verwenden
+
+   * 'chance' gilt sowohl fuer Attack- als auch normale Chats
+
+   * 'chance' wird in der Property P_CHAT_CHANCE abgelegt. Um einen
+     NPC voruebergehend 'stillzulegen', kann man P_CHAT_CHANCE auf 0
+     setzen
+
+   * Spieler koennen P_CHAT_CHANCE temporaer auf 0 setzen
+     ('stillen')
+
+   * NPC haben bei Abwesenheit von Spielern in der Regel keinen
+     Heartbeat, weswegen dann auch die Chats ausgeschaltet sind
+
+   * send_room() bekommt immer MSG_DONT_STORE|MSG_DONT_BUFFER
+     uebergeben
+
+
+BEISPIELE
+=========
+
+   // Ein einfaches Beispiel:
+   SetChats(20,
+    ({"Der Ork sagt: Hau ab, bevor ich Dich fresse.\n",
+      "Der Ork grinst Dich unverschaemt an.\n",
+      "Der Ork wedelt mit seinem Saebel vor dir herum.\n",
+      "Der Ork stupst Dich mit dem Finger hart.\n"}));
+
+   // Ein Beispiel mit send_room-Typen ohne MSG_DONT_WRAP
+   SetChats(20,
+    ({({"Der Ork sagt: Hau ab, bevor ich Dich fresse.", MT_LISTEN}),
+      ({"Der Ork grinst Dich unverschaemt an.", MT_LOOK}),
+      ({"Der Ork wedelt mit seinem Saebel vor dir herum.", MT_LOOK}),
+      ({"Der Ork stupst Dich mit dem Finger hart.", MT_LOOK|MT_FEEL})}));
+
+   // Laengeres Beispiel mit Closures
+   protected string chat_flightinfo(int msg_typ);
+   protected string chat_trysteal(int msg_typ);
+
+   void create() {
+     SetChats(20,
+      ({({"Der Ork sagt: Hau ab, bevor ich Dich fresse.\n", MT_LISTEN}),
+        #'chat_flightinfo,
+        #'chat_trysteal}));
+     // [...]
+   }
+
+   protected string chat_flightinfo(int msg_typ) {
+     msg_typ = MT_LISTEN;
+     return ("Der Ork sagt: "+
+             (QueryProp(P_HP)<QueryProp(P_WIMPY)?
+               "Ich hab Angst!":
+               "Guck mich nicht so an, Schwaechling!"));
+   }
+
+   protected string chat_trysteal(int msg_typ) {
+     object *pls = filter(all_inventory(environment()), #'interactive);
+     if(sizeof(pls)) {
+       object pl = pls[random(sizeof(pls))];
+       if(!IS_LEARNER(pl)) {
+         object *objs = all_inventory(pl);
+         if(sizeof(objs)) {
+           object ob = objs[random(sizeof(objs))];
+           if(ob->move(this_object(),
+                       M_NO_SHOW|M_GIVE|M_MOVE_ALL)==MOVE_OK) {
+             if(pl->ReceiveMsg(Name(WER)+" stiehlt dir "+ob->name(WEN, 0)+".",
+                               MT_FEEL|MT_LOOK)<0)
+               pl->ReceiveMsg("Irgendwie scheint dir jetzt etwas zu fehlen.",
+                              MT_FEEL|MT_LOOK|MSG_DONT_IGNORE);
+             send_room(environment(),
+               Name(WER, 1)+" bestiehlt "+pl->name(WEN)+".",
+               MT_LOOK, 0, 0, ({pl}));
+             return "";
+           }
+         }
+       }
+     }
+     msg_typ = MT_LOOK;
+     return Name(WER, 1)+" schaut sich verstohlen um.";
+   }
 
 
 SIEHE AUCH
 ==========
 
-   P_CHAT_CHANCE, SetAttackChats(), process_string()
+   Verwandt:
+      *SetAttackChats()*
 
-Last modified: Sat Jan 18 18:48:06 2003 by Patryn
+   Props:
+      *P_CHAT_CHANCE*
+
+   Sonstiges:
+      *send_room()*, *process_string()*
+
+3. April 2017 Gloinson
diff --git a/doc/lfun/list b/doc/lfun/list
new file mode 100644
index 0000000..41b989f
--- /dev/null
+++ b/doc/lfun/list
@@ -0,0 +1,44 @@
+
+list()
+******
+
+
+FUNKTION
+========
+
+   int list(string str)
+
+
+DEFINIERT IN
+============
+
+   /std/room/shop.c
+
+
+ARGUMENTE
+=========
+
+   string str: Durch den Spieler eingegebene Argumente
+
+
+BESCHREIBUNG
+============
+
+   Diese Funktion wird aufgerufen, wenn ein Spieler im Laden 'zeige'
+   eingibt. Anhand von str wird geprueft, welche Art von Waren er
+   aufgelistet haben moechte und in welchem Format. Diese
+   Informationen werden dann zur Ausgabe an PrintList()
+   weitergeleitet.
+
+
+RUECKGABEWERTE
+==============
+
+   1 bei erfolgreichem Erkennen der Parameter, sonst 0. (siehe auch
+   AddCmd())
+
+
+SIEHE AUCH
+==========
+
+   *PrintList()*, *AddCmd()*
diff --git a/doc/lfun/obsolete/AddRoomCmd b/doc/lfun/obsolete/AddRoomCmd
new file mode 100644
index 0000000..f4aeb68
--- /dev/null
+++ b/doc/lfun/obsolete/AddRoomCmd
@@ -0,0 +1,23 @@
+
+AddRoomCmd()
+************
+
+
+SYNTAX
+======
+
+   AddRoomCmd( string kommando, string funktion );
+   AddRoomCmd( string *kommandos, string funktion );
+
+
+FUNKTION
+========
+
+   Diese Funktion ist veraltet. Sie wird vollstaendig durch
+   die Funktion AddCmd ersetzt.
+
+
+SIEHE AUCH
+==========
+
+   "AddCmd"
diff --git a/doc/lfun/obsolete/DoList b/doc/lfun/obsolete/DoList
new file mode 100644
index 0000000..4a20ef8
--- /dev/null
+++ b/doc/lfun/obsolete/DoList
@@ -0,0 +1,39 @@
+
+DoList()
+********
+
+********************* OBSOLETE LFUN
+*********************************** * Diese Lfun bitte nicht mehr
+benutzen, sondern stattdessen           * * PrintList()
+* *******************************************************************
+****
+
+
+FUNKTION
+========
+
+   static int DoList(string query_fun)
+
+
+DEFINIERT IN
+============
+
+   /std/room/shop.c
+
+
+BESCHREIBUNG
+============
+
+   Veraltete Version von PrintList(), bitte nicht verwenden!
+
+
+RUECKGABEWERTE
+==============
+
+   Immer 1.
+
+
+SIEHE AUCH
+==========
+
+   "PrintList"
diff --git a/doc/lfun/obsolete/GetList b/doc/lfun/obsolete/GetList
new file mode 100644
index 0000000..5cd4fec
--- /dev/null
+++ b/doc/lfun/obsolete/GetList
@@ -0,0 +1,39 @@
+
+GetList()
+*********
+
+********************* OBSOLETE LFUN
+*********************************** * Diese Lfun bitte nicht mehr
+benutzen, sondern stattdessen           * * GetShopItems()
+* *******************************************************************
+****
+
+
+FUNKTION
+========
+
+   static mixed >>*<<GetList()
+
+
+DEFINIERT IN
+============
+
+   /std/room/shop.c
+
+
+BESCHREIBUNG
+============
+
+   Veraltete Version von GetShopItems(), bitte nicht verwenden!
+
+
+RUECKGABEWERTE
+==============
+
+   Liste der verkaeuflichen Objekte.
+
+
+SIEHE AUCH
+==========
+
+   "GetShopItems"
diff --git a/doc/lfun/obsolete/extra_look b/doc/lfun/obsolete/extra_look
index d8e9703..6d134a9 100644
--- a/doc/lfun/obsolete/extra_look
+++ b/doc/lfun/obsolete/extra_look
@@ -4,7 +4,7 @@
 
 ********************* VERALTETE LFUN ****************************** *
 Diese LFUN ist veraltet. Bitte benutzt sie NICHT mehr, sondern  * *
-stattdessden AddExtraLook().                                    *
+stattdessden AddExtraLook() oder P_EXTRA_LOOK.                  *
 *******************************************************************
 
 extra_look()
@@ -19,14 +19,12 @@
 BESCHREIBUNG
 ============
 
-   Kann in Objekt definiert sein. Wenn ein Living (std/living/description)
-   das Objekt enthaelt, wird zu dessen long() der zurueckgegebene String
-   hinzugefuegt.
+   Kann in Objekt definiert sein. Wenn ein Living
+   (std/living/description) das Objekt enthaelt, wird zu dessen long()
+   der zurueckgegebene String hinzugefuegt.
 
 
 SIEHE AUCH
 ==========
 
-   AddExtraLook()
-
-25.Jan 2015 Gloinson
+   *AddExtraLook()*, *P_EXTRA_LOOK*