diff --git a/std/npc/info.c b/std/npc/info.c
new file mode 100644
index 0000000..d66ee26
--- /dev/null
+++ b/std/npc/info.c
@@ -0,0 +1,345 @@
+// MorgenGrauen MUDlib
+//
+// npc/info.c -- Behandeln von Fragen an den NPC
+//
+// $Id: info.c 9522 2016-03-01 19:20:10Z Arathorn $
+
+/* Letzte Aenderungen von Wim 8.1.99
+ *
+ * AddInfo( schluessel, antwort [, indent [, [silent [, casebased] ] ] )
+ *  Wenn ein Spieler dieses Monster nach "schluessel" fragt, so gib die
+ *  Programmierte Antwort aus.
+ *  Erweiterung von Wim: ist silent gesetzt, so erfolgt eine "persoenliche"
+ *    Antwort. d.h. umstehende Personen bekommen bei silent==1 keinen, bei
+ *    stringp(silent), den String ausgegeben, dabei kann er auch die Schluessel-
+ *    Worte @WER @WESSEN @WEM @WEN enthalten.
+ *  - Ergaenzt um @CAP_WER... fuer zwangs-capitalisierte Namen an Satzanfaengen.
+ *    ist bei fragenden NPCs und PCs mit Tarnkappe wichtig! (Silvana)
+ *  - Auch in der Antwort des fragenden wird nun ersetzt (Vanion)
+ *  Enthaelt casedbased einen Funktionsnamen oder verweist auf eine closure, so
+ *    wird die Beantwortung der Frage von dem return-Wert abhaengig gemacht.
+ *    Bei 0 wird die Frage normal beantwortet, bei 1 erfolgt die Ausgabe des
+ *    unter DEFAULT_NOINFO gespeicherten Textes.
+ *    Wird ein String zurueckgegeben, so wird er unter Beachtung von ident an
+ *    Stelle der urspruenglichen Information ausgegeben.
+ *
+ * RemoveInfo( schluessel )
+ *  Das Monster antwortet nicht mehr auf diesen Schluessel.
+ *
+ * SetProp( P_DEFAULT_INFO, antwort [, indent ] )
+ *  Setze die Antwort, die das Monster auf unverstaendliche Fragen geben
+ *  soll. (Diese Funktion ist obsolet! Benutze stattdessen
+ *  AddInfo( "\ndefault info", antwort [, indent ] );
+ *
+ * GetInfo( [schluessel] )
+ *  Wenn Schluessel gesetzt ist, so wird die dazugehoerige Info,
+ *  ansonsten werden alle Infos zurueckgegeben.
+ *
+ * Die Antworten sollten wie emote - kommandos aussehen.
+ * Der optionale Indent wird zum Umbrechen von langen Infos benutzt.
+ * (Typischerweise sollte indent="sagt: " sein.)
+ *
+ * In den Infos darf mit process_string gearbeitet werden. Das Ergebnis von
+ * process_string wird dann mit umgebrochen!
+ *
+ *---------------------------------------------------------------------------
+ */
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <thing/description.h>
+#include <thing/properties.h>
+#include <npc.h>
+#undef NEED_PROTOTYPES
+
+#include <properties.h>
+#include <language.h>
+#include <defines.h>
+#include <config.h>
+#include <exploration.h>
+
+// TODO: langfristig waer hier private schoen.
+nosave mapping infos;
+
+protected void create()
+{
+    // Initialisierung nur wenn noetig, damit beim virtuellen Erben von
+    // /std/npc in npc1 und npc2 dann in npc3 beim npc1::create();
+    // npc2:create(); im zweiten create() die Infos nicht
+    // ueberschrieben/geloescht werden.
+    if (!mappingp(infos)) {
+        infos = ([
+            DEFAULT_INFO:"schaut Dich fragend an.\n";0;
+            "schaut @WEN fragend an.\n";0,
+            DEFAULT_NOINFO:"moechte Dir nicht antworten.\n";0;
+            "verweigert @WEM die Antwort.\n";1
+            ]);
+    }
+}
+
+
+void init() {
+  add_action( "frage", "frag", 1 );
+}
+
+
+static void smart_npc_log(string str)
+{
+  string creat, creat_det;
+
+  if (!stringp(creat=QueryProp(P_LOG_INFO))) {
+    creat = MASTER->creator_file(this_object());
+    if (creat == ROOTID)
+      creat = "ROOT";
+    else if( creat==BACKBONEID )
+      creat="STD";
+    creat_det="report/"+explode(creat, ".")[<1]+"_INFO.rep";
+    creat="report/"+explode(creat, ".")[<1]+".rep";
+  }
+  log_file(creat,
+           sprintf("INFO von %s [%s] (%s):\n%s\n",
+                   getuid(this_interactive()),
+                   explode(object_name(this_object()),"#")[0],
+                   strftime("%d. %b %Y"),
+                   str));
+  if (stringp(creat_det) && sizeof(creat_det))
+    log_file(creat_det,
+             sprintf("INFO von %s [%s] (%s):\n%s\n",
+                     getuid(this_interactive()),
+                     explode(object_name(this_object()),"#")[0],
+                     strftime("%d. %b %Y"),
+                     str));
+}
+
+public int frage(string str) {
+  string myname, text;
+
+  str=(extern_call()?this_player()->_unparsed_args():str);
+  if( !str || sscanf( str, "%s nach %s", myname, text ) != 2 ) {
+    _notify_fail( "WEN willst Du nach WAS fragen?\n" );
+    return 0;
+  }
+
+  if( !id( lower_case(myname) )
+    || QueryProp(P_INVIS) ) {
+    _notify_fail( "So jemanden findest Du hier nicht.\n" );
+    return 0;
+  }
+  say( capitalize(this_player()->name(WER))+" fragt " +
+    name(WEN,2)+" nach "+capitalize(text)+".\n",
+      this_player() );
+
+  text = lower_case(text);
+  GiveEP(EP_INFO, text);
+
+  return do_frage( text );
+}
+
+static string infoDefaultReplace(string pstring, object pl)
+{
+  pstring=" "+pstring;
+  if (strstr(pstring,"@WER",0) >-1 )
+    pstring= regreplace(pstring,"@WER",pl->name(WER,1),1);
+  if (strstr(pstring,"@WESSEN",0) >-1 )
+    pstring= regreplace(pstring,"@WESSEN",pl->name(WESSEN,1),1);
+  if (strstr(pstring,"@WEM",0) >-1 )
+    pstring= regreplace(pstring,"@WEM",pl->name(WEM,1),1);
+  if (strstr(pstring,"@WEN",0) >-1 )
+    pstring= regreplace(pstring,"@WEN",pl->name(WEN,1),1);
+  if (strstr(pstring,"@CAP_WER",0) >-1 )
+    pstring= regreplace(pstring,"@CAP_WER",pl->Name(WER,1),1);
+  if (strstr(pstring,"@CAP_WESSEN",0) >-1 )
+    pstring= regreplace(pstring,"@CAP_WESSEN",pl->Name(WESSEN,1),1);
+  if (strstr(pstring,"@CAP_WEM",0) >-1 )
+    pstring= regreplace(pstring,"@CAP_WEM",pl->Name(WEM,1),1);
+  if (strstr(pstring,"@CAP_WEN",0) >-1 )
+    pstring= regreplace(pstring,"@CAP_WEN",pl->Name(WEN,1),1);
+
+  return pstring[1..];
+}
+
+static mixed *GetInfoArr(string str)
+{  
+   return ({ infos[str, 0], infos[str, 1], infos[str,2], infos[str, 3] });
+}
+
+public int do_frage(string text)
+{
+  string indent,answer;
+  mixed silent, preinfo, noanswer;
+  mixed *info;
+
+  if (stringp(preinfo = QueryProp(P_PRE_INFO)))
+  {
+     // Die message action wird auf "frage" fixiert, damit dies immer das
+     // gleiche ist, egal, mit welchem Verb man in diese Funktion kommt.
+     this_player()->ReceiveMsg(preinfo, MT_LISTEN, "frage",
+                               Name(WER,2)+" ",this_object());
+     send_room(environment(this_object()),
+               "ist nicht gewillt, "+this_player()->Name(WEM,2)
+               +" zu antworten.",
+               MT_LISTEN, "frage",
+               Name(WER,2)+" ",
+               ({this_player()}) );
+     return 1;
+  }
+  else
+  {
+    if (intp(preinfo) && preinfo > 0)
+      return 1;
+  }
+
+  info=GetInfoArr(text);
+  if (!info[0])
+  {
+    if( this_interactive() && QueryProp(P_LOG_INFO) )
+      smart_npc_log(text);
+    text = DEFAULT_INFO;
+    info=GetInfoArr(text);
+  }
+
+  if (closurep(info[0]) ) {
+    answer=funcall(info[0]);
+    if( !answer || answer=="") return 1;
+  } else {
+    answer=process_string(info[0]);
+  }
+
+  if (closurep(info[3]) )
+   {
+    noanswer=funcall(info[3]);
+    if ( intp(noanswer) && noanswer > 0)
+     {
+       text = DEFAULT_NOINFO;
+       info = GetInfoArr(text);
+       if (closurep(info[0]) ) {
+         answer=funcall(info[0]);
+         if( !answer || answer=="") return 1;
+       } else {
+         answer=process_string(info[0]);
+       }
+     }
+    else if ( stringp(noanswer) )
+      answer = noanswer;
+   }
+
+  silent=info[2];
+
+  // Replacements gehen auch in der Antwort des NPC. Das gibt den Antworten 
+  // eine persoenliche Note, und so teuer is das auch nicht :)
+  answer = infoDefaultReplace(answer, this_player());
+
+  if( indent=info[1] )
+  {
+    if (stringp(silent) || (intp(silent) && silent > 0) )
+    {  // Persoenliche Antwort mit indent
+       this_player()->ReceiveMsg(answer, MT_LISTEN|MSG_BS_LEAVE_LFS,
+                                 "frage",
+                                 Name(WER,2)+" "+indent,
+                                 this_object());
+       if (stringp(silent))
+       {
+          silent=infoDefaultReplace(silent, this_player());
+          send_room(environment(), silent, MT_LISTEN, "frage",
+                    Name(WER,2)+" ", ({this_player()}));
+       }
+    }
+    else // "normale Antwort" mit Indent
+    {
+      send_room(environment(), answer, MT_LISTEN|MSG_BS_LEAVE_LFS,
+                "frage",
+                Name(WER,2)+" "+indent, ({this_object()}));
+    }
+  }
+  else
+  {
+    if (stringp(silent) || (intp(silent) && silent > 0) )
+    {  // Persoenliche Antwort ohne indent
+       this_player()->ReceiveMsg(answer, MT_LISTEN|MSG_DONT_WRAP,
+                                 "frage",
+                                 Name(WER,2)+" ",
+                                 this_object());
+       if (stringp(silent))
+       {
+          silent=infoDefaultReplace(silent, this_player());
+          send_room(environment(), silent, MT_LISTEN, "frage",
+                    Name(WER,2)+" ", ({this_player()}) );
+       }
+    }
+    else // "normale Antwort" ohne Indent
+      send_room(environment(), answer, MT_LISTEN|MSG_DONT_WRAP,
+                "frage", Name(WER,2)+" ");
+  }
+  return 1;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ * Setzen von Infos
+ *---------------------------------------------------------------------------
+ */
+
+public varargs void AddInfo(mixed key, mixed info, string indent, 
+                            mixed silent, mixed casebased ) {
+
+  if (stringp(casebased))
+    casebased=symbol_function(casebased,this_object());
+
+  if( pointerp( key ) ) {
+    int i;
+    for ( i=sizeof( key )-1; i>=0; i-- )
+      infos += ([ key[i]: info; indent; silent; casebased ]);
+  }
+  else
+    infos += ([ key: info; indent; silent; casebased ]);
+}
+
+public varargs void AddSpecialInfo(mixed keys, string functionname, 
+                      string indent, mixed silent, mixed casebased )
+{
+  int i;
+  closure cl;
+
+  if(!(cl=symbol_function(functionname,this_object()))) return;
+  return AddInfo(keys,cl,indent,silent,casebased);
+}
+
+
+public void RemoveInfo( string key )
+{
+  m_delete(infos,key);
+}
+
+static varargs void _set_default_info( mixed info )
+{
+  if (pointerp(info))
+    apply(#'AddInfo/*'*/,DEFAULT_INFO,info);
+  else
+    AddInfo(DEFAULT_INFO,info);
+}
+
+public varargs mixed GetInfo(string str)
+{
+  if (!str) return deep_copy(infos);
+  return infos[str];
+}
+
+
+static mapping _query_npc_info()
+{
+    return deep_copy(infos);
+}
+
+
+static mapping _set_npc_info( mapping map_ldfied )
+{
+    if ( !mappingp(map_ldfied) )
+        return 0;
+
+    return infos = map_ldfied;
+}
+
