diff --git a/std/living/moving.c b/std/living/moving.c
new file mode 100644
index 0000000..c6149ff
--- /dev/null
+++ b/std/living/moving.c
@@ -0,0 +1,457 @@
+// MorgenGrauen MUDlib
+//
+// living/moving.c -- moving of living objects
+//
+// $Id: moving.c 9448 2016-01-22 17:52:28Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "/std/thing/moving";
+
+#define NEED_PROTOTYPES
+#include <hook.h>
+#include <living/moving.h>
+#include <living/skills.h>
+#include <thing/properties.h>
+#include <thing/description.h>
+#include <moving.h>
+#include <new_skills.h>
+#include <living.h>
+
+#undef NEED_PROTOTYPES
+
+#include <config.h>
+#include <properties.h>
+#include <language.h>
+#include <wizlevels.h>
+#include <defines.h>
+
+
+protected void create()
+{
+    if (object_name(this_object()) == __FILE__[0..<3])
+    {
+      return;
+    }
+    offerHook(H_HOOK_MOVE,1);
+}
+
+public void AddPursuer(object ob)
+{
+  mixed *pur;
+
+  if (!objectp(ob))
+    return;
+
+  if (!pointerp(pur=Query(P_PURSUERS)))
+    pur=({0,({})});
+  else if (member(pur[1],ob)!=-1)
+    return;
+  
+  SetProp(P_PURSUERS,({ pur[0], pur[1]+({ob})-({0}) }));
+  ob->_SetPursued(ME);
+}
+
+public void RemovePursuer(object ob)
+{
+  mixed *pur;
+
+  if (pointerp(pur=Query(P_PURSUERS,F_VALUE)) 
+      && member(pur[1],ob)!=-1)
+  {
+    pur[1]-=({ob,0});
+    if (ob)
+      ob->_RemovePursued(ME);
+    if (!pur[0]&&!sizeof(pur[1]))
+      pur=0;
+    SetProp(P_PURSUERS,pur);
+  }
+}
+
+public void _SetPursued(object ob)
+{
+  mixed *pur;
+
+  if (!pointerp(pur=Query(P_PURSUERS)))
+    pur=({0,({})});
+  else
+    if (objectp(pur[0]))
+      pur[0]->RemovePursuer(ME);
+  pur[0]=ob;
+  pur[1]-=({0});
+  Set(P_PURSUERS,pur);
+}
+
+public void _RemovePursued(object ob)
+{
+  mixed *pur;
+
+  if (!pointerp(pur=Query(P_PURSUERS)) || pur[0]!=ob)
+    return;
+  pur[0]=0;
+  pur[1]-=({0});
+  if (!sizeof(pur[1]))
+    pur=0;
+  Set(P_PURSUERS,pur);
+}
+
+
+private void kampfende( object en ) {
+  if (!objectp(en)) return;
+  tell_object( ME, capitalize(en->name()) +
+      " ist jetzt hinter Dir her.\n" );
+  tell_object( en, "Du verfolgst jetzt " + name(WEN) + ".\n" );      
+  en->InsertSingleEnemy(ME);
+}
+
+private int _is_learner(object pl) {
+  return IS_LEARNER(pl); 
+}
+
+
+// a) Pruefungen, ob das move erlaubt ist.
+// b) zum Ueberschreiben
+protected int PreventMove(object dest, object oldenv, int method) {
+
+  // M_NOCHECK? -> Bewegung eh erlaubt (und Rueckgabewert wuerde ignoriert),
+  // aber PreventInsert/PreventLeave() rufen und ignorieren.
+  if ((method&M_NOCHECK)) {
+      // erst PreventLeaveLiving() rufen...
+      if(environment())        
+          environment()->PreventLeaveLiving(this_object(), dest);
+      // dann PreventInsertLiving() im Ziel-Env.
+      dest->PreventInsertLiving(this_object());
+      // und raus...
+      return(0);
+  }
+
+  // bei Lebewesen muss die Bewegungsmethode M_GO und M_TPORT sein. Dies ist
+  // gleichzeigt die Restriktion gegen das Nehmen von Lebewesen, da dort
+  // M_GET/M_GIVE/M_PUT etc. verwendet wuerde. Bei M_GO und M_TPORT findet
+  // keine Pruefung statt, ob das Objekt ins Ziel 'reinpasst' (Gewicht, Anzahl
+  // Objekte usw.).
+  // Ich finde es etwas merkwuerdig gebaut (Zesstra).
+  if ( !(method & (M_GO | M_TPORT)) )
+      return ME_PLAYER;
+  
+  // alte und neue Umgebung auf NO_TPORT pruefen.
+  if ( (method & M_TPORT) ) {
+    if ( environment() &&
+        (environment()->QueryProp(P_NO_TPORT) & (NO_TPORT_OUT|NO_TPORT)) )
+          return ME_CANT_TPORT_OUT;
+    else if ( dest->QueryProp(P_NO_TPORT) & (NO_TPORT_IN|NO_TPORT) )
+          return ME_CANT_TPORT_IN;
+  }
+
+  // erst PreventLeaveLiving() testen...
+  if( environment() && environment()->PreventLeaveLiving(this_object(), dest))
+      return ME_CANT_LEAVE_ENV;
+  // dann PreventInsertLiving() im Ziel-Env
+  if (dest->PreventInsertLiving(this_object())) 
+      return ME_CANT_BE_INSERTED;
+
+  return 0;
+}
+
+// Krams nach dem Move machen und nebenbei zum Ueberschreiben.
+protected void NotifyMove(object dest, object oldenv, int method) {
+  mixed res;
+  object enem;
+
+  // Begruessungsschlag fuer die Gegener
+  if ( !(method & M_NO_ATTACK) )
+      InitAttack();
+
+  if (!objectp(ME)) return;
+
+  // Verfolger nachholen.
+  if ( pointerp(res = Query(P_PURSUERS)) && sizeof(res[1]) ) {
+      while ( remove_call_out( "TakeFollowers" ) >= 0 );
+
+      call_out( "TakeFollowers", 0 );
+  }
+
+  // und noch das Team nachholen.
+  if ( oldenv != dest
+      && objectp(ME)
+      && QueryProp(P_TEAM_AUTOFOLLOW)
+      && objectp( enem = IsTeamLeader() ) )
+      enem->StartFollow(oldenv); // Teamverfolgung
+
+}
+
+varargs public int move( object|string dest, int method, string direction,
+                         string textout, string textin )
+{
+    int para, nightvis, invis, tmp;
+    object oldenv, *inv;
+    string fn,vc;
+    mixed res;
+    mixed hookData, hookRes;
+
+    if (!objectp(dest) && !stringp(dest))
+      raise_error(sprintf("Wrong argument 1 to move(). 'dest' must be a "
+            "string or object! Argument was: %.100O\n",
+            dest));
+
+    // altes Env erstmal merken.
+    oldenv = environment();
+    
+    //erstmal den richtigen Zielraum suchen, bevor irgendwelche Checks gemacht
+    //werden...
+    // Ist der Spieler in einer Parallelwelt?
+    if ( (para = QueryProp(P_PARA)) && intp(para) ) {
+        fn = objectp(dest) ? object_name(dest) : dest;
+
+        // Falls der Zielraum nicht schon explizit in der Parallelwelt ist,
+        // neuen Zielraum suchen. Aber nur, wenn fn kein # enthaelt (also kein
+        // Clone ist), sonst wuerde eine Bewegung nach raum#42^para versucht,
+        // was dann buggt. ;-) Problem wird offenbar, wenn ein Para-Lebewesen
+        // im create() eines VC-Raums in Para in den Raum bewegt wird, da
+        // dieser dann noch nicht vom Driver umbenannt wurde und raum#42
+        // heisst.
+        if ( !sizeof(regexp( ({ fn }), "\\^[1-9][0-9]*$" )) &&
+            strrstr(fn,"#")==-1 )
+        {
+            fn += "^" + para;
+
+          // Der Parallelwelt-Raum muss existieren und fuer Spieler
+          // freigegeben sein, damit er zum neuen Ziel wird. Ansonsten
+          // duerfen nur NPCs, Testspieler und Magier herein.
+          if ( (find_object(fn) 
+                || ((file_size(fn+".c")>0 ||
+                    (file_size(vc=implode(explode(fn,"/")[0..<2],"/")+
+                          "/virtual_compiler.c")>0 &&
+                    !catch(tmp=(int)call_other(vc,"QueryValidObject",fn);
+                           publish) && tmp>0)) &&
+                    !catch(load_object(fn);publish) )) &&
+                  (!interactive(ME) || !fn->QueryProp(P_NO_PLAYERS) || 
+                  (method & M_NOCHECK) || IS_LEARNER(ME) ||
+                  (stringp(res = QueryProp(P_TESTPLAYER)) &&
+                   IS_LEARNER( lower_case(res) ))) )
+          {
+              dest = fn;
+          }
+          else
+          {
+              // Wir bleiben in der Normalwelt.
+              para = 0;
+          }
+        }
+    }
+
+    // jetzt erstmal Hooks abpruefen, da sie ggf. die Daten aendern.
+    // alten P_TMP_MOVE_HOOK pruefen.
+    if ( res = QueryProp(P_TMP_MOVE_HOOK) ){
+        if ( pointerp(res) && sizeof(res) >= 3
+             && intp(res[0]) && time()<res[0]
+             && objectp(res[1]) && stringp(res[2]) ){
+            if ( res = call_other( res[1], res[2], dest, method, direction,
+                                   textout, textin ) ){
+                if ( pointerp(res) && sizeof(res) == 5 ){
+                    dest = res[0];
+                    method = res[1];
+                    direction = res[2];
+                    textout = res[3];
+                    textin = res[4];
+                }
+                else if ( intp(res) && res == -1 )
+                    return ME_CANT_LEAVE_ENV;
+            }
+        } else
+            SetProp( P_TMP_MOVE_HOOK, 0 );
+    }
+    // move hook nach neuem Hooksystem triggern.
+    hookData=({dest,method,direction,textout,textin});
+    hookRes=HookFlow(H_HOOK_MOVE,hookData);
+    if(hookRes && pointerp(hookRes) && sizeof(hookRes)>H_RETDATA) {
+      if(hookRes[H_RETCODE]==H_CANCELLED) {
+        return ME_CANT_LEAVE_ENV;
+      }
+    else if(hookRes[H_RETCODE]==H_ALTERED && hookRes[H_RETDATA] &&
+          pointerp(hookRes[H_RETDATA]) && sizeof(hookRes[H_RETDATA])>=5 ){
+      dest = hookRes[H_RETDATA][0];
+      method = hookRes[H_RETDATA][1];
+      direction = hookRes[H_RETDATA][2];
+      textout = hookRes[H_RETDATA][3];
+      textin = hookRes[H_RETDATA][4];
+      }
+    }
+
+    // dest auf Object normieren
+    if (stringp(dest)) dest=load_object(dest);
+
+    // jetzt Checks durchfuehren, ob das Move durchgefuehrt werden darf.
+    if (tmp=PreventMove(dest, oldenv, method)) {
+      // auf gueltigen Fehler pruefen, wer weiss, was Magier da evtl.
+      // versehentlich zurueckgeben.
+      if (VALID_MOVE_ERROR(tmp))
+        return(tmp);
+      else
+        return(ME_DONT_WANT_TO_BE_MOVED);
+    }
+  
+    if ( invis = QueryProp(P_INVIS) )
+        method |= M_SILENT;
+
+    if ( objectp(oldenv) ) {
+        if ( !(method & M_SILENT) ) {
+            string *mout;
+            if ( !textout ){
+                if ( method & M_TPORT )
+                    textout = (string) QueryProp(P_MMSGOUT) ||
+                        (string) QueryProp(P_MSGOUT);
+                else 
+                    textout = (mout = explode( (string)
+                                                QueryProp(P_MSGOUT) || "",
+                                                      "#" ))[0]
+                         || (string)QueryProp(P_MMSGOUT);
+            }
+
+            if ( !sizeof(direction) )
+                direction = 0;
+
+            inv = all_inventory(environment()) - ({ this_object() });
+            inv = filter( inv, #'living/*'*/ );
+            inv -= filter_objects( inv, "CannotSee", 1 );
+
+            filter( inv, #'tell_object/*'*/,
+                          Name( WER, 2 ) + " " + textout +
+                          (direction ? " " + direction : "") +
+                          (sizeof(mout) > 1 ? mout[1] : "") + ".\n" );
+        }
+        // Magier sehen auch Bewegungen, die M_SILENT sind
+        else if ( interactive(ME) ){
+            inv = (all_inventory(environment()) & users())
+                - ({ this_object() });
+            inv = filter( inv, #'_is_learner/*'*/ );
+
+            if ( invis )
+                fn = "(" + capitalize(getuid(ME)) + ") verschwindet "
+                    "unsichtbar.\n";
+            else
+                fn = capitalize(getuid(ME)) + " verschwindet ganz leise.\n";
+            
+            filter( inv, #'tell_object/*'*/, fn );
+        }
+        
+        // Nackenschlag beim Fluechten:
+        if ( !(method & M_NO_ATTACK) && objectp(ME) )
+            ExitAttack();
+        //falls nach ExitAttack() das Living nicht mehr existiert, muss das
+        //move() auch nicht mehr fortgesetzt werden. Weiter unten gibt es auch
+        //min. eine Stelle, die nicht prueft und ggf. buggt. Daher erfolgt
+        //hier ggf. ein Abbruch. 15.11.06 Zesstra
+        if (!objectp(ME)) return(ME_WAS_DESTRUCTED);
+
+        // Nackenschlag kann ME in den Todesraum bewegt haben...
+        if ( oldenv == environment() ) {
+            // Fuer alle anwesenden gegner kampfende() aufrufen
+            filter((QueryEnemies()[0] & all_inventory(oldenv))-({0}),
+                #'kampfende);
+            // Bugs im exit() sind ohne catch() einfach mist.
+            catch(environment()->exit(ME, dest);publish);
+        }
+    }
+
+    // irgendwas kann das Objekt zerstoert haben, z.B. env->exit().
+    if (!objectp(ME)) return(ME_WAS_DESTRUCTED);
+
+    if ( oldenv != environment() )
+        // Der Nackenschlag oder exit() koennen einen schon bewegt haben.
+        // Und wenn es in den Todesraum ist. ;^)
+        return MOVE_OK;
+    
+    SetProp( P_PREPARED_SPELL, 0 ); // Spruchvorbereitung abgebrochen
+    SetProp( P_LAST_MOVE, time() ); // Zeitpunkt der letzten Bewegung
+    
+    move_object(ME, dest);
+    if (!objectp(ME))
+      return(ME_WAS_DESTRUCTED);
+
+    dest = environment();
+    
+    nightvis = UseSkill(SK_NIGHTVISION);
+    // Meldungen an nicht-Blinde ausgeben, falls keine 'stille' Bewegung
+    if ( !(method & M_SILENT) ) {
+      if ( !textin ) {        
+        if ( method & M_TPORT )
+              textin = (string) QueryProp(P_MMSGIN);
+        else
+              textin = (string) QueryProp(P_MSGIN);
+      }
+            
+      inv = all_inventory(environment()) - ({ this_object() });
+      inv = filter( inv, #'living/*'*/ );
+            inv -= filter_objects( inv, "CannotSee", 1 );
+            filter( inv, #'tell_object/*'*/,
+                          capitalize(name( WER, 0 )) + " " + textin + ".\n" );
+    }
+    // sonst: Magier sehen auch M_SILENT-Bewegungen, hier also nur an Magier
+    // ausgeben, alle anderen sehen eh nix.
+    else if ( interactive(ME) ) {  
+      inv = (all_inventory(environment()) & users()) - ({this_object()});        
+      inv = filter( inv, #'_is_learner/*'*/ );        
+      if ( invis )
+        fn = "(" + capitalize(getuid(ME)) + ") taucht unsichtbar auf.\n";
+      else
+        fn = capitalize(getuid(ME)) + " schleicht leise herein.\n";        
+      filter( inv, #'tell_object, fn );    
+    }
+
+    // "Objekt" ueber das Move informieren.
+    NotifyMove(dest, oldenv, method);
+
+    // InitAttack() in NotifyMove() kann das Objekt zerstoert haben.
+    if (!objectp(ME))
+      return(ME_WAS_DESTRUCTED);
+
+    //scheint wohl geklappt zu haben.
+    return MOVE_OK;
+}
+
+public void TakeFollowers()
+{
+  mixed *f,env;
+  int meth,i,r;
+
+  f=Query(P_PURSUERS);
+  if (!pointerp(f))
+    return;
+  env=environment();
+  if(object_name(env) == "/room/netztot") return;
+  foreach(object follower: f[1]-({0}) ) {
+    // die pruefung auf objectp ist nicht verrueckt, es kann theo. sein, dass
+    // Verfolger im PreventFollow() oder in ihrem move/init andere Verfolger
+    // zerstoeren.
+    if (objectp(follower) && environment(follower)!=env) {
+      //meth=M_NOCHECK;
+      meth=M_GO;
+      if (follower->Query(P_FOLLOW_SILENT))
+          meth|=M_SILENT|M_NO_SHOW;
+      catch(r=follower->PreventFollow(env);publish);
+      if (!r)
+          follower->move(env,meth);
+      else if (r==2)
+          RemovePursuer(follower);
+    }
+  }
+}
+
+varargs public int remove()
+{ object team;
+
+  if (environment())
+  {
+    if ( objectp(team=Query(P_TEAM)) )
+      catch(team->RemoveMember(ME);publish);
+
+    environment()->NotifyRemove(ME);
+  }
+  destruct(ME);
+  return 1;
+}
+
