Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/doc/lfun/AddInfo b/doc/lfun/AddInfo
new file mode 100644
index 0000000..9de7bd2
--- /dev/null
+++ b/doc/lfun/AddInfo
@@ -0,0 +1,219 @@
+AddInfo()
+FUNKTION:
+     varargs void AddInfo( frage, meldung
+			   [, indent [, [silent [, casebased] ] ] );
+
+DEFINIERT IN:
+     /std/npc/info.c
+
+ARGUMENTE:
+     string/string* frage
+	Schluesseltext(e) auf die Informationen gegeben werden sollen.
+     string/closure meldung
+	Information, die gegeben werden soll/Closure
+     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.
+
+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.
+
+     Frage:
+      Schluessel muessen kleingeschrieben sein, koennen aber Leerzeichen
+      enthalten.
+
+     Meldung:
+      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: ".
+
+     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.
+
+     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 Strings von 'silent' und 'meldung' werden geparsed. Dabei werden die
+     Schluesselworte @WER, @WESSEN, @WEM, @WEN durch TP->Name(..) ersetzt und
+     @CAP_WER, @CAP_WESSEN, @CAP_WEM, @CAP_WEN durch capitalize(TP-Name(..)).
+
+     Mittels der in <npc.h> definierten Frage DEFAULT_INFO kann eine
+     Meldung gesetzt werden, die gegeben werden soll, wenn der Spieler
+     etwas fragt, auf das keine Antwort vorgegeben ist (das loest
+     SetProp(P_DEFAULT_INFO, <text>) ab).
+
+BEISPIELE:
+     ### 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");
+
+     ### einfache Beispiele, auch mit casebased ###
+     AddInfo(({"knete","kohle"}),
+	     "sagt: ich habe so etwas nicht.\n");
+     AddInfo("geld",
+	     "Ich habe zwar kein Geld, aber ... blablabla ...",
+	     "sagt: " );
+     AddInfo("muenzen",
+	     "fluestert: Du willst Geld?\n",
+	     0,
+	     "fluestert @WEM etwas zu.\n");
+
+     // "frage monster nach geld": alle im Raum hoeren
+     //  Das Monster sagt: Ich habe zwar kein Geld, aber ...
+     //  Das Monster sagt: ... blablabla ...
+
+     // "frage monster nach muenzen":
+     // - der Fragensteller hoert:
+     //   "Das Monster fluestert: Du willst Geld?"
+     // - alle andere hoeren:
+     //   "Das Monster fluestert <Fragenstellernamen> etwas zu."
+
+     ### 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!");
+     }
+
+     // "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 ###
+     // ein Prototyp, damit wir die Methode bekannt machen
+     static string query_kekse();
+     static 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!");
+     }
+
+     static mixed case_fighting() {
+      if(InFight())
+       return("Keine Zeit fuer Kekse. Muss kaempfen.");
+      return 0;
+     }
+
+     // "frage monster nach keks":
+     // - wenn es kaempft, hoeren alle:
+     //   "Das Monster sagt: Keine Zeit fuer Kekse. Muss kaempfen.
+     // - sonst, wenn es noch Kekse hat, hoeren alle:
+     //   "Das Monster sagt: Ich hab noch welche. Aetsch!
+     // - sonst:
+     //   "Das Monster sagt: "Menno. Keine mehr da!
+
+
+     ### dynamisch und komplex ###
+     // ein Prototyp, damit wir die Methode bekannt machen
+     static 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);
+     ...
+
+     // 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);
+      }
+
+      // 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."+
+          ((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: "+
+             CountUp(y)+
+             (sizeof(y)==1?" ist":" sind")+
+             " aus Gold.":"")):
+           ""));
+     }
+
+     // "frage monster nach gold"
+     // - der Fragesteller hoert zB:
+     //   Das Monster murmelt: Ich hab kein Gold bei mir. Aber du hast ja
+     //   Das Monster murmelt: jede Menge Kohle bei dir, so etwas <number>
+     //   Das Monster murmelt: Muenzen. Ausserdem ist/sind noch <object1>
+     //   Das Monster murmelt: und <object2> aus Gold."
+     // - die Umstehenden hoeren:
+     //   "Das Monster murmelt @WEM etwas zu."
+     //   oder
+     //   "Das Monster murmelt @WEM etwas zu und glotzt ihn/sie gierig an."
+
+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
+
+7.Apr 2004 Gloinson