diff --git a/std/npc/chat.c b/std/npc/chat.c
new file mode 100644
index 0000000..7f4f89b
--- /dev/null
+++ b/std/npc/chat.c
@@ -0,0 +1,66 @@
+// MorgenGrauen MUDlib
+//
+// npc/chat.c -- Labernde NPCs
+//
+// $Id: chat.c 6801 2008-03-21 23:34:46Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#include <properties.h>
+#define NEED_PROTOTYPES
+#include <living/combat.h>
+#include <thing/properties.h>
+#undef NEED_PROTOTYPES
+
+#define ME this_object()
+
+/*
+ * Some simple chat variables
+ */
+
+/*
+ * heart_beat is called so the monster may chat.
+ */
+void SetChats(int chance, mixed strs) {
+  if (!pointerp(strs))
+    return;
+  SetProp(P_CHAT_CHANCE,chance);
+  SetProp(P_CHATS,strs);
+}
+
+void SetAttackChats(int chance, mixed strs) {
+  if (!pointerp(strs))
+    return;
+  SetProp(P_ACHAT_CHANCE,chance);
+  SetProp(P_ACHATS,strs);
+}
+
+void DoAttackChat() {
+  string* c;
+  if (!ME || !environment(ME))
+    return;
+  if (QueryProp(P_DISABLE_ATTACK)>0)return ;
+  if (random(100) < QueryProp(P_ACHAT_CHANCE))
+    if ((c = QueryProp(P_ACHATS)) && sizeof(c)) 
+      tell_room(environment(ME),
+		process_string(c[random(sizeof(c))]));
+}
+
+void DoChat() {
+  string *c;
+  if (!ME || !environment(ME))
+    return;
+  if (random(100) < QueryProp(P_CHAT_CHANCE))
+    if ((c = QueryProp(P_CHATS)) && sizeof(c)) 
+      tell_room(environment(ME),
+		process_string(c[random(sizeof(c))]));
+}
+
+protected void heart_beat()
+{
+  if( InFight() ) DoAttackChat();
+  else            DoChat();
+}
diff --git a/std/npc/combat.c b/std/npc/combat.c
new file mode 100644
index 0000000..747714b
--- /dev/null
+++ b/std/npc/combat.c
@@ -0,0 +1,407 @@
+// MorgenGrauen MUDlib
+//
+// npc/combat.c -- NPC-spezifische Kampffunktionen
+//
+// $Id: combat.c 9488 2016-02-19 21:24:04Z Arathorn $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "std/living/combat";
+
+#include <combat.h>
+#include <language.h>
+#include <properties.h>
+#include <wizlevels.h>
+#include <health.h>
+#include <new_skills.h>
+
+#define NEED_PROTOTYPES 1
+#include <living/life.h>
+#undef NEED_PROTOTYPES
+
+#define HB_CHECK 7
+#define ME this_object()
+#define STATMASTER "/p/service/rochus/guildstat/master"
+
+nosave int heartbeat, beatcount;
+
+private void catch_up_hbs();
+
+protected void create() {
+  ::create();
+  beatcount=1;
+  heartbeat=1;
+}
+
+protected void create_super() {
+  set_next_reset(-1);
+}
+
+// aktuelles Lebewesen, fuer das dieser NPC gerade taetig ist. Default:
+// Spieler, bei dem er als Helfer-NPC registriert ist.
+public object QueryUser()
+{
+  mixed helperdata = QueryProp(P_HELPER_NPC);
+  if (pointerp(helperdata) && objectp(helperdata[0]))
+    return helperdata[0];
+  return 0;
+}
+
+// ggf. Feinde expiren. Soll das Problem verringern, dass Spieler nach Tagen
+// erst die Meldung kriegen, dass der NPC sie nicht mehr jagt, wenn der HB
+// reaktivert wird.
+void reset() {
+  // ggf. die abgeschalteten HBs nachholen.
+  if (!heartbeat)
+    catch_up_hbs();
+  // ggf. P_ENEMY_DAMAGE zuruecksetzen
+  ResetEnemyDamage();
+}
+
+static void _set_max_hp(int i) {
+  Set(P_MAX_HP,i);
+  SetProp(P_HP,i);
+}
+
+static void _set_max_sp(int i) {
+  Set(P_MAX_SP,i);
+  SetProp(P_SP,i);
+}
+
+
+// Check-Funktion fuer die P_NO_ATTACK-QueryMethod
+static mixed _check_immortality()
+{
+    int t;
+
+    if ( !(t = Query("time_to_mortality")) || time() > t ){
+        // Zeit ist abgelaufen - wieder angreifbar machen
+        Set( P_NO_ATTACK, 0, F_QUERY_METHOD );
+        heartbeat = 1;
+        beatcount = 1;
+        set_heart_beat(1);
+
+        return 0;
+    }
+
+    // der NPC ist noch unangreifbar
+    return break_string( capitalize(name( WER, 1 )) + " versteckt sich hinter "
+                         "einem Fehler im Raum-Zeit-Gefuege und entgeht so "
+                         "voruebergehend allen Angriffen.", 78 );
+}
+
+
+// wenn der HeartBeat buggt, wird diese Funktion vom Master aufgerufen
+public void make_immortal()
+{
+    // fuer 5 Minuten unangreifbar machen
+    Set( P_NO_ATTACK, #'_check_immortality, F_QUERY_METHOD );
+
+    Set( "time_to_mortality", time() + 300, F_VALUE );
+
+    // damit die Spieler keinen Vorteil durch den Bug haben, heilen
+    heal_self(10000);
+
+    // da nun der Heartbeat abgeschaltet ist und normalerweise erst
+    // reaktiviert wird, sobald jemand nach 5min P_NO_ATTACK abfragt, muss man
+    // aber auf Viecher achten, die immer nen Heartbeat haben wollen. In dem
+    // fall per call_out selber die Prop abfragen.
+    if (QueryProp(P_HB))
+      call_out(#'QueryProp, 301, P_NO_ATTACK);
+}
+
+
+// Damit NPCs gegeneinander weiterkaempfen, auch wenn kein Spieler
+// in der Naehe ist:
+static int _query_hb()
+{
+    // TODO: return InFight() || Query(P_HB, F_VALUE), sobald InFight()
+    // geaendert.
+    return (InFight() || Query(P_HB,F_VALUE)) ? 1 : 0;
+}
+
+
+#define SPELL_TOTALRATE 0
+#define SPELL_DAMAGE 1
+#define SPELL_TEXT_FOR_ENEMY 2
+#define SPELL_TEXT_FOR_OTHERS 3
+#define SPELL_DAMTYPE 4
+#define SPELL_FUNC 5
+#define SPELL_ARG 6
+
+varargs int AddSpell(int rate, int damage, string TextForEnemy,
+                     string TextForOthers, string|string* dam_type, string func,
+                     int|mapping spellarg) {
+  mixed *spells;
+  int total_rates;
+
+  if (rate<0 || damage<=0 || !stringp(TextForEnemy) ||
+      !stringp(TextForOthers))
+     return 0;
+
+  if (stringp(dam_type))
+     dam_type = ({dam_type});
+  else if (!pointerp(dam_type))
+      dam_type = ({DT_MAGIC});
+  
+  // Tatsaechlich ist es immer ein nicht-physischer Angriff, wenn spellarg ein
+  // int ist, weil wenn spellarg==0 ist der Default nicht-physischer Angriff
+  // und bei spellarg!=0 auch. Nur mit einem mapping kann man einen phys.
+  // Angriff erzeugen.
+  if (intp(spellarg))
+    spellarg = ([SP_PHYSICAL_ATTACK: 0]);
+
+  // Falls vorhanden, alte Syntax auf die von replace_personal() anpassen,
+  // die im heart_beat() beim Ausgeben der Meldung verwendet wird.
+  if ( strstr(TextForOthers, "@", 0) != -1 )
+  {
+    // Zeichen nach @WER & Co in runde Klammern einschliessen, damit es als
+    // Sub-Pattern im Ausgabestring wiederholt werden kann. Ansonsten wuerde
+    // es mit ersetzt.
+    TextForOthers = regreplace(TextForOthers, "@WER([^1-9])", "@WER1\\1", 1);
+    TextForOthers = regreplace(TextForOthers, "@WESSEN([^1-9])",
+                               "@WESSEN1\\1", 1);
+    TextForOthers = regreplace(TextForOthers, "@WEM([^1-9])", "@WEM1\\1", 1);
+    TextForOthers = regreplace(TextForOthers, "@WEN([^1-9])", "@WEN1\\1", 1);
+  }
+  total_rates=Query("npc:total_rates")+rate;
+  spells=Query(P_SPELLS);
+  if (!pointerp(spells))
+    spells=({});
+  spells+=({({total_rates, damage, TextForEnemy, TextForOthers,
+              dam_type, func, spellarg})});
+  Set(P_SPELLS,spells);
+  Set("npc:total_rates",total_rates);
+  return 1;
+}
+
+int AutoAttack(object ob) {
+  mixed m;
+
+  if (!query_once_interactive(ob))
+    return 0;
+  if (mappingp(m=QueryProp(P_AGGRESSIVE))) {
+    mixed *ind,x,z;
+    float f;
+    int i,n;
+
+    ind=m_indices(m)-({0});n=0;f=0.0;
+    for (i=sizeof(ind)-1;i>=0;i--) {
+      x=ind[i];
+      if ((z=m[x][ob->QueryProp(x)]) || (z=m[x][0])) {
+  f=f+(float)z;
+  n++;
+      }
+    }
+    if (n)
+      m=f/((float)n);
+    else
+      m=m[0];
+  }
+  if (((int)(100*(m+ob->QueryProp(P_AGGRESSIVE))))<=random(100))
+    return 0;
+  if  (IS_LEARNER(ob)
+       && (ob->QueryProp(P_INVIS)
+     || ob->QueryProp(P_WANTS_TO_LEARN)))
+    return 0;
+  return 1;
+}
+
+void SpellAttack(object enemy) {
+}
+
+#if 0
+TJ(string s) {
+  object o;
+  if (o=find_player("jof"))
+    tell_object(o,sprintf("%O: %s\n",this_object(),s));
+}
+#else
+#define TJ(x)
+#endif
+
+protected void heart_beat() {
+  int r,i;
+  mixed env,*spells, sinfo;
+  object enemy;
+
+  if ( --beatcount < 0 )
+      beatcount = 0;
+  
+  if (!beatcount && !Query(P_HB)) {
+    if (!environment()) {
+      set_heart_beat(0);
+      heartbeat = 0;
+      if( clonep(this_object()) ) remove();
+      return;
+    }
+    if (!QueryProp(P_POISON)) {
+      // Spieler anwesend?
+      env = filter(all_inventory(environment()), #'query_once_interactive);
+      if (!sizeof(env)) {
+	// Nein, HBs abschalten.
+	set_heart_beat(0);
+	heartbeat=0;
+	TJ("OFF\n");
+	beatcount=HB_CHECK;
+	Set("npc:beat_off_num",absolute_hb_count());
+	return;
+      }
+    }
+  }
+  ::heart_beat();
+  if (!ME)
+      return;
+  enemy=SelectEnemy();
+  if (QueryProp(P_AGGRESSIVE)
+      && (!enemy || environment()!=environment(enemy))
+      && !beatcount) {
+    beatcount=HB_CHECK;
+    env=filter(all_inventory(environment()),#'AutoAttack);
+    if (!sizeof(env))
+       return;
+    i=random(sizeof(env));
+    Kill(env[i]);
+  }
+  else if (!beatcount)
+    beatcount=HB_CHECK;
+  if (!objectp(enemy) ||QueryProp(P_DISABLE_ATTACK)>0)
+    return;
+  SpellAttack(enemy);
+
+  if (!pointerp(spells=Query(P_SPELLS))
+      || !sizeof(spells)
+      || !objectp(enemy=SelectEnemy())
+      || environment(enemy)!=environment()
+      || (QueryProp(P_DISABLE_ATTACK)>0)
+      || random(100)>Query(P_SPELLRATE))
+    return;
+  r=random(Query("npc:total_rates"));
+  for (i=sizeof(spells)-1;(i>0 && spells[i-1][SPELL_TOTALRATE]>r);i--)
+    ;
+  string akt_spell_mess = spells[i][SPELL_TEXT_FOR_ENEMY];
+  if ( sizeof(akt_spell_mess) )
+    tell_object(enemy, break_string(akt_spell_mess, 78));
+  akt_spell_mess = spells[i][SPELL_TEXT_FOR_OTHERS];
+  // Nur, wenn ueberhaupt eine Meldung gesetzt wurde, muss diese verarbeitet
+  // werden.
+  if (stringp(akt_spell_mess) && sizeof(akt_spell_mess))
+  {
+    akt_spell_mess = replace_personal(akt_spell_mess, ({enemy}), 1);
+    say(break_string(akt_spell_mess, 78),({enemy, this_object()}));
+  }
+  sinfo = deep_copy(spells[i][SPELL_ARG]);
+  if(!mappingp(sinfo))
+    sinfo=([ SI_MAGIC_TYPE :({ MT_ANGRIFF }) ]);
+  else if(!sinfo[SI_MAGIC_TYPE])
+    sinfo[ SI_MAGIC_TYPE]=({ MT_ANGRIFF });
+  if(!sinfo[SP_PHYSICAL_ATTACK] &&
+     (enemy->SpellDefend(this_object(),sinfo) >
+      random(MAX_ABILITY+QueryProp(P_LEVEL)*50))){
+    tell_object(enemy,"Du wehrst den Spruch ab.\n");
+    say(enemy->Name(WER,1)+" wehrt den Spruch ab.\n",
+        ({ enemy, this_object()}));
+    return ;
+  }
+  int damage = random(spells[i][SPELL_DAMAGE])+1;
+  enemy->Defend(damage, spells[i][SPELL_DAMTYPE],
+                spells[i][SPELL_ARG],
+                this_object());
+
+  // Falls der Gegner (oder wir) im Defend stirbt, hier abbrechen
+  if ( !objectp(ME) || !objectp(enemy) 
+      || enemy->QueryProp(P_GHOST) ) return;
+  
+  if (spells[i][SPELL_FUNC] && stringp(spells[i][SPELL_FUNC]))
+    catch(call_other(this_object(),
+         spells[i][SPELL_FUNC],
+         enemy,
+         damage,
+         spells[i][SPELL_DAMTYPE]);publish);
+}
+
+// Heartbeats nachholen.
+private void catch_up_hbs() {
+  // gibt es HBs zum nachholen?
+  int beat_off_num = Query("npc:beat_off_num");
+  if (!beat_off_num)
+    return; // nein.
+  // wieviele HBs nachholen?
+  beat_off_num = absolute_hb_count() - beat_off_num;
+  
+  if (beat_off_num>0) {
+    // Nicht ausgefuehrtes HEILEN nachholen
+    int rlock=QueryProp(P_NO_REGENERATION);
+    int hp=QueryProp(P_HP);
+    int sp=QueryProp(P_SP);
+    int alc=QueryProp(P_ALCOHOL);
+    if (!(rlock & NO_REG_HP)) {
+      hp+=beat_off_num/HEAL_DELAY+alc/ALCOHOL_DELAY;
+      SetProp(P_HP,hp);
+    }
+    if (!(rlock & NO_REG_SP)) {
+      sp+=beat_off_num/HEAL_DELAY+alc/ALCOHOL_DELAY;
+      SetProp(P_SP,sp);
+    }
+    alc-=beat_off_num/ALCOHOL_DELAY;
+    if ( alc < 0 )
+      alc = 0;
+    SetProp(P_ALCOHOL,alc);
+    int da = QueryProp(P_DISABLE_ATTACK);
+    // Paralysen abbauen
+    if ( da > 0 ) {
+      da -= beat_off_num;
+      if ( da < 0 )
+	da = 0;
+      SetProp( P_DISABLE_ATTACK, da );
+    }
+    // Hunttimes aktualisieren, Feinde expiren
+    update_hunt_times(beat_off_num);
+    if (!heartbeat)
+      // HBs immer noch abgeschaltet, naechstes Mal HBs seit jetzt nachholen.
+      Set("npc:beat_off_num",absolute_hb_count());
+    else
+      // HB laeuft wieder, nix mehr nachholen, bis zur naechsten Abschaltung.
+      Set("npc:beat_off_num",0);
+  }
+}
+
+void init() {
+
+  // ggf. Heartbeats nachholen und wieder einschalten.
+  if (!heartbeat) {
+    set_heart_beat(1);
+    heartbeat=1;
+    catch_up_hbs();
+  }
+
+  if (AutoAttack(this_player()))
+    Kill(this_player());
+}
+
+private nosave closure mod_att_stat;
+
+int Defend(int dam, mixed dam_type, mixed spell, object enemy) {
+  if (objectp(enemy=(enemy||this_player()))
+      && query_once_interactive(enemy)
+      && !IS_LEARNER(enemy)) {
+    if (!objectp(get_type_info(mod_att_stat,2))) {
+      object ma;
+      if (!objectp(ma=find_object(STATMASTER)))
+        return ::Defend(dam,dam_type,spell,enemy);
+      // Keine Statistik wenn Master nicht geladen ist.
+      mod_att_stat=symbol_function("ModifyAttackStat",ma);
+    }
+    funcall(mod_att_stat,
+            enemy->QueryProp(P_GUILD),
+            enemy->QueryProp(P_GUILD_LEVEL),
+            dam,
+            dam_type,
+            spell);
+  }
+
+  return ::Defend(dam,dam_type,spell,enemy);
+}
diff --git a/std/npc/comm.c b/std/npc/comm.c
new file mode 100644
index 0000000..892d8fa
--- /dev/null
+++ b/std/npc/comm.c
@@ -0,0 +1,57 @@
+// MorgenGrauen MUDlib
+//
+// npc/comm.c -- Basiskommunikation fuer NPCs
+//
+// $Id: comm.c 9358 2015-10-22 18:35:04Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "/std/living/comm";
+
+#include <language.h>
+#include <living/comm.h>
+#define NEED_PROTOTYPES
+#include <thing/description.h>
+
+
+void create() {
+  add_action( "sage", "sag", 1 );
+  add_action( "echo", "echo" );
+  add_action( "emote", "emote" );
+}
+
+int echo( string str ) {
+  say( str + "\n" );
+  return 1;
+}
+
+int sage( string str ) {
+  say( break_string(str, 78, capitalize(name(WER,2))+" sagt: "));
+  return 1;
+}
+
+int emote( string str ) {
+  say( capitalize(name(WER,2))+" "+str+"\n" );
+  return 1;
+}
+
+// zum ueberschreiben - DEPRECATED! USE ReceiveMsg()!
+public void catch_msg(mixed *arr, object obj) {}
+public void catch_tell(string str) {}
+
+// by default, the msg is delivered to catch_tell() for compatibility reasons
+// and otherwise ignored.
+public varargs int ReceiveMsg(string msg, int msg_typ, string msg_action,
+                              string msg_prefix, object origin)
+{
+  // compatibility...
+  if (msg_typ & MSG_DONT_WRAP)
+    catch_tell(sprintf("%s%s", msg_prefix||"", msg));
+  else
+    catch_tell(sprintf("%s%s\n", msg_prefix||"", msg));
+  return MSG_DELIVERED;
+}
+
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;
+}
+
diff --git a/std/npc/items.c b/std/npc/items.c
new file mode 100644
index 0000000..f0260cf
--- /dev/null
+++ b/std/npc/items.c
@@ -0,0 +1,240 @@
+// MorgenGrauen MUDlib
+//
+// /std/npc/items.c -- Item-Verwaltung fuer NPCs
+//
+// $Id: items.c 8146 2012-10-30 18:18:14Z Zesstra $
+//
+// (c) by Padreic (Padreic@mg.mud.de)
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#define NEED_PROTOTYPES
+#include <thing/properties.h>
+#include <thing/description.h>
+#include <living/combat.h>
+#undef NEED_PROTOTYPES
+#include <npc.h>
+#include <properties.h>
+#include <combat.h>
+#include <config.h>
+#include <moving.h>
+#include <sys_debug.h>
+
+protected void create()
+{
+  // dieses flag ist nur bis zum ersten move gesetzt. Nimmt danach also auch
+   Set(NPC_NEEDS_ITEM_INIT, 1);  // keinen Speicher mehr in Anspruch.
+   // Set(P_ITEMS, ({})); // keine initialisierung spart Speicher  
+}
+
+protected void create_super() {
+      set_next_reset(-1);
+}
+
+protected object* maybe_own_stuff() {
+  object* obs = all_inventory(environment());
+  object haufen = present("\nhaufen "+name(WEM),environment());
+  if( objectp(haufen) ) obs += all_inventory(haufen);
+  object leiche = present("\nleiche "+name(WEM),environment());
+  if( objectp(leiche) ) obs += all_inventory(leiche);
+  return obs;
+}
+
+// clont alle Objekte die geclont werden muessen...
+protected void _clone_items()
+{
+  int i, j, mode, refresh;
+  object ob, *inv1;
+  mixed  props, *items;
+  string file, *inv2;
+
+  if (!pointerp(items=QueryProp(P_ITEMS))) return;
+  if (environment()) { // Liste mit filenamen (inv2) erstellen.
+    inv1 = maybe_own_stuff();
+    inv2 = map(inv1, #'load_name);
+  }
+  else inv2=({}); // inv1 wird gar nicht mehr benoetigt
+
+  for (i=sizeof(items)-1; i>=0; i--) {
+    ob = items[i][RITEM_OBJECT];
+    file = items[i][RITEM_FILE];
+    mode = items[i][RITEM_REFRESH];
+    refresh = mode & 0x0000ffff;
+    props = items[i][RITEM_PROPS];
+    if (props && intp(props)) { // unique Gegenstand?
+      ob=find_object(file);
+      if (ob) {
+        // kann ob aufgenommen werden? Wenn das Objekt in inv1 drin ist, ist es
+        // im Env oder in einer Leiche oder einem Haufen.
+        if (member(inv1,ob) > -1) {
+          if (environment()) {
+            if (environment(ob) == environment())
+              tell_room(environment(),
+                  capitalize(name(WER))+" hebt "+ob->name(WEN)+" auf.\n");
+            else
+              tell_room(environment(),break_string(
+                  capitalize(name(WER))+" nimmt "+ob->name(WEN)+ " aus "
+                  +environment(ob)->name(WEM) + ".",78));
+          }
+          ob->remove();  // zerstoeren und neuladen.
+          if (ob) destruct(ob);
+          if (catch(ob=load_object(file);publish))             
+              raise_error(sprintf(
+                "_clone_items(): %O does not exist or is not loadable\n", file)); 
+          ob->move(this_object(), M_NOCHECK);
+          items[i][RITEM_OBJECT]=ob;
+        }
+        else switch( refresh ) {
+          case REFRESH_DESTRUCT:
+            if (environment(ob)) {
+              ob=0; // nicht zuecken, tragen, initialisieren...
+              break;
+            }
+          case REFRESH_ALWAYS:
+          case REFRESH_REMOVE:                
+            ob->remove();
+            if (ob) destruct(ob);
+            if (catch(ob=load_object(file);publish)) 
+                raise_error(sprintf("_clone_items(): "
+                      "%O does not exist or is not loadable\n", file));
+            ob->move(this_object(), M_NOCHECK);
+            items[i][RITEM_OBJECT]=ob;
+            break;
+          case REFRESH_NONE:
+          default: ob=0; // nicht zuecken, tragen, initialisieren...
+        }
+      }
+      else {
+        if (catch(ob=load_object(file);publish)) raise_error(sprintf(
+          "_clone_items(): %O does not exist or is not loadable\n", file));
+        if (objectp(ob)) ob->move(this_object(), M_NOCHECK);
+        items[i][RITEM_OBJECT]=ob;
+      }
+    } // if (props ...) // also nicht unique
+    else {
+      switch( refresh ) {
+        case REFRESH_DESTRUCT: // erfuellt auch REFRESH_REMOVE Bedingung...
+          if (ob) {
+            ob=0; // nicht zuecken, tragen, initialisieren...
+            break;
+          }
+        case REFRESH_REMOVE:
+          if (ob) {
+            if(present(ob, this_object())) {
+              ob=0; // nicht zuecken, tragen, initialisieren...
+              break;
+            }
+            else {
+              if ((member(inv2, file))==-1) {  
+                ob=0;
+              }
+            }
+          }
+        case REFRESH_NONE: // wird entfernt nach dem ersten clonen!!!
+        case REFRESH_ALWAYS:
+          // schauen ob der Gegenstand im environment liegt.
+          if ((j=member(inv2, file))!=-1) {
+            ob=inv1[j]; // inv1 kann leer sein, aber dann ist inv2 auch leer
+            inv1[j]=0; // wichtig falls mehrere gleiche AddItems
+            inv2[j]=0; // = 0 setzen um Array kopieren zu vermeiden
+            if (environment()) {
+              if (environment() == environment(ob))
+                tell_room(environment(),
+                    capitalize(name(WER))+" hebt "+ob->name(WEN)+" auf.\n");
+              else
+                tell_room(environment(),break_string(
+                    capitalize(name(WER))+" nimmt "+ob->name(WEN)+" aus "
+                    +environment(ob)->name(WEM) + ".",78));
+            }
+          }
+          if (ob) {
+            ob->remove();
+            if (ob) destruct(ob);
+          }
+          if (catch(ob=clone_object(file);publish)) raise_error(sprintf(
+            "_clone_items(): %O does not exist or is not loadable\n", file));
+          ob->move(this_object(), M_NOCHECK);
+          switch( refresh ) {
+          case REFRESH_NONE:
+            items[i] = 0; // Speicher freimachen
+            break;
+          case REFRESH_ALWAYS:
+            items[i][RITEM_OBJECT] = 0; // Objekt "vergessen"
+            break;
+          default:
+            items[i][RITEM_OBJECT] = ob;
+          }
+          break;
+        default: ob=0; // nicht zuecken, tragen, initialisieren...
+      }
+    } // if (props ...) else 
+    if (ob) {
+      if (mappingp(props)) walk_mapping(props, symbol_function("SetProp", ob));
+      // Eigentlich will man hier sowas wie command("zuecke schwert")
+      // machen, aber das handling der id's kann nicht sicherstellen,
+      // dass der NPC die richtige Waffe erwischt, deshalb machen wir
+      // das tragen hier von Hand.
+      if (mode & CLONE_WEAR) {
+        if( mode & CLONE_NO_CHECK ) {
+          object *armours;
+          ob->DoUnwear(); // evtl. dem Vorgaenger abnehmen.
+          UseHands(ob, ob->QueryProp(P_NR_HANDS));
+          armours=QueryProp(P_ARMOURS)+({ ob });
+          SetProp(P_ARMOURS, armours);
+          SetProp(P_TOTAL_AC, QueryProp(P_TOTAL_AC)+ob->QueryProp(P_AC));
+          ob->SetProp(P_WORN, this_object());
+        } else {
+          command( "trage \n"+object_name(ob) );
+        }
+      }
+      if (mode & CLONE_WIELD) {
+        if( mode & CLONE_NO_CHECK ) {
+          ob->DoUnwield(); // evtl. dem Vorgaenger abnehmen. 
+          UseHands(ob, ob->QueryProp(P_NR_HANDS));
+          SetProp(P_WEAPON, ob);
+          SetProp(P_TOTAL_WC, ob->QueryProp(P_WC));
+          ob->SetProp(P_WIELDED, this_object());
+        } else {
+          command( "zuecke \n"+object_name(ob) );
+        }
+      }
+    } // if (ob) 
+  } // for i
+  items-=({ 0 }); // REFRESH_NONEs von nicht unique Objekten 
+  if (!sizeof(items)) items=0; // Speicher sparen...
+  SetProp(P_ITEMS, items);
+  Set(NPC_NEEDS_ITEM_INIT, 0);
+}
+
+public varargs object AddItem(mixed filename, int refresh, mixed props)
+{
+  // Aus Array ein Element auswaehlen
+  if (pointerp(filename)) 
+    filename = filename[random(sizeof(filename))];
+ 
+  // Kein String? -> Fehler
+  if (!stringp(filename)){
+    raise_error("AddItem: filename or array of filenames expected.\n"); 
+  } else {
+    // Pfad normieren und eventuell vorhandenes ".c" entfernen
+    filename = MASTER->_get_path(
+                  filename[<2..]==".c"?filename=filename[0..<3]
+                                        : filename,"?"); 
+    // Property setzen
+    SetProp(P_ITEMS, (QueryProp(P_ITEMS)||({}))+
+                     ({ ({ 0, filename, refresh, props }) }));
+
+  if (environment()) _clone_items();
+  }
+  return 0;
+}
+
+void reset()
+// fuer REFRESH_ Objekte...
+{
+  _clone_items();
+}
+
diff --git a/std/npc/moving.c b/std/npc/moving.c
new file mode 100644
index 0000000..f06e0da
--- /dev/null
+++ b/std/npc/moving.c
@@ -0,0 +1,39 @@
+// MorgenGrauen MUDlib
+//
+// living/moving.c -- moving of living objects
+//
+// $Id$
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "/std/living/moving";
+
+#include <hook.h>
+#define NEED_PROTOTYPES
+#include <moving.h>
+
+//<int|<string|closure>* >* GuardExit(object room, int hookid,
+//                                    <string|closure>* hdata)
+//{
+//}
+
+protected int _reg_exit_hook(object dest, object oldenv)
+{
+  closure cl = symbol_function("GuardExit", this_object());
+  if (cl)
+  {
+    if (oldenv)
+      oldenv->HUnregisterFromHook(H_HOOK_EXIT_USE, cl);
+    return dest->HRegisterModifier(H_HOOK_EXIT_USE, cl);
+  }
+  return 0;
+}
+// Krams nach dem Move machen und nebenbei zum Ueberschreiben.
+protected void NotifyMove(object dest, object oldenv, int method)
+{
+  _reg_exit_hook(dest, oldenv);
+  return ::NotifyMove(dest, oldenv, method);
+}
diff --git a/std/npc/put_and_get.c b/std/npc/put_and_get.c
new file mode 100644
index 0000000..8b72cf4
--- /dev/null
+++ b/std/npc/put_and_get.c
@@ -0,0 +1,36 @@
+// MorgenGrauen MUDlib
+//
+// npc/put_and_get.c.c -- Geben und nehmen fuer NPCs
+//
+// $Id: put_and_get.c 6371 2007-07-17 22:46:50Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "std/living/put_and_get";
+#include <moving.h>
+#include <properties.h>
+
+void give_notify( object obj )
+{
+   mixed* msg;
+   if (pointerp(msg=QueryProp(P_REJECT))) {
+      switch(msg[0]) {
+         case REJECT_GIVE:
+            say(msg[1]);
+            give_obj( obj, this_player() );
+            break;
+         case REJECT_LIGHT_MODIFIER:
+            if (obj->QueryProp(P_LIGHT_MODIFIER) ||
+                obj->QueryProp(P_LIGHT)) break;
+         case REJECT_DROP:
+            say(msg[1]);
+            drop_obj( obj );
+            break;
+         case REJECT_KEEP:
+         default: say(msg[1]); /* keep it */
+    }
+  }
+}
diff --git a/std/npc/sequencer.c b/std/npc/sequencer.c
new file mode 100644
index 0000000..50c85e3
--- /dev/null
+++ b/std/npc/sequencer.c
@@ -0,0 +1,125 @@
+// MorgenGrauen MUDlib
+//
+// npc/sequencer.c -- Scripte und Trigger fuer NPCs :)
+//
+// $Id: sequencer.c 7526 2010-04-02 00:01:26Z Arathorn $
+
+// seq2.c
+// Version 2.0 des Sequencers von Don Rumata 28.06.93
+// 
+// Sinn:
+//   Bereitstellung von Funktionen, ddamit ein npc mehrere Befehle
+//   bei Eintritt eines bestimmten Ereignisses nacheinander
+//   automatisch durchfuehrt.
+//
+// Ereignisse:
+//   TellEvent: Es wird etwas in dem Raum, in dem der npc sich
+//              befindet, gesagt.
+//   GiveEvent: Es wird dem npc etwas gegeben.
+//
+// Programm:
+//   Ein Programm ist eine Liste von Befehlen.
+//   Jeder Befehl ist eine Liste, bestehend aus einem Kommando
+//   und einer Zahl.
+//   Das Kommendo wird aehnlich der Befehle, die ein Spieler ein-
+//   gibt ausgefuehrt.
+//   Vorsicht: NPCs koennen nur einen Teil der Befehle, die ein
+//   Spieler kann, dafuer aber immer 'echo' und 'emote'.
+//   Die Zahl gibt die Anzahl der Sekunden an, in der der naechste
+//   Befehl ausgefuehrt wird.
+//
+// Funktionen:
+//   RegisterTell( funktion, programm )
+//     Wenn dem npc etwas gesagt wird, so wird die gesagte Meldung
+//     an die Funktion uebergeben. Gibt die Funktionen nicht 0
+//     zurueck, wird das Programm gestartet.
+//   RegisterGive( funktion, programm )
+//     Wird dem npc etwas gegeben, so wird das Objekt an die
+//     Funktion uebergeben. Gibt die Funktion nicht 0 zurueck, so
+//     wird das Programm gestartet.
+//   Load( programm )
+//     Starte das angegebene Programm.
+//
+//   give_notify() gibt eine 1 zurueck, wenn das Objekt akzeptiert
+//     wurde. (Es muss - falls gewuenscht - dann von Hand zuruech-
+//     gegeben werden. (give_obj(ob,this_player())) in der Funk.)
+//   mittels add_action() kann man im create() ds NPCs eigene
+//     Verben fuer den NPC einfuehren.
+//
+// Es kann immer nur eine Funktion (egal ob Tell oder Give) angemeldet
+// sein. Es kann immer nur ein Programm gleichzeitig laufen.
+//
+// Ideen und Bugreports an Rumata
+
+string givefun, tellfun;
+mixed *program;
+int isRunning;
+
+// zur sicherheit nicht von aussen aufrufbar !!!!
+static string RegisterGive( string fun, mixed prog )
+{
+  if( isRunning ) return 0;
+  program = prog;
+  tellfun = 0;
+  return givefun = fun;
+}
+
+// zur sicherheit nicht von aussen aufrufbar !!!!
+static string RegisterTell( string fun, mixed prog )
+{
+  if( isRunning ) return 0;
+  program = prog;
+  givefun = 0;
+  return tellfun = fun;
+}
+
+// zur sicherheit nicht von aussen aufrufbar !!!!
+static void Start()
+{
+  if( isRunning || !objectp(this_object())) return;
+  isRunning = 1;
+  call_out( "nextStep", 0, 0 );
+}
+
+static void Load( mixed prog )
+{
+  if( isRunning ) return;
+  program = prog;
+  Start();
+}
+
+public void catch_tell( string str )
+{
+  if( isRunning || previous_object()==this_object()) return;
+  if( stringp(tellfun) && call_other( this_object(), tellfun, str ) )
+    Start();
+}
+
+int give_notify( object ob )
+{
+  if( isRunning ) return 0;
+  if( stringp(givefun) && call_other( this_object(), givefun, ob ) )
+  {
+    Start();
+    return 1;
+  }
+  return 0;
+}
+
+static void nextStep( int line )
+{
+  if( !isRunning ) return;
+  if( line >= sizeof( program ) )
+  {
+    isRunning = 0;
+    return;
+  }
+  command( process_string( program[line][0] ) );
+  if( !isRunning || !objectp(this_object()) ) return;
+  call_out( "nextStep", program[line][1], line+1 );
+}
+
+mixed QueryProg()
+{
+  return program[0..];
+} 
