Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/room/church.c b/room/church.c
new file mode 100644
index 0000000..e939b23
--- /dev/null
+++ b/room/church.c
@@ -0,0 +1,41 @@
+inherit "/std/room";
+
+#include <properties.h>
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT,1);
+  SetProp(P_INT_SHORT,"Village church");
+  SetProp(P_INT_LONG,
+   "You are in the local village church.\nThere is a huge pit in the center,\n" +
+	 "and a door in the west wall. There is a button beside the door.\n"+
+   "This church has the service of reviving ghosts. Dead people come\n"+
+   "to the church and pray.\n"+
+   "There is a clock on the wall.\n"+
+   "There is an exit to south.\n");
+  AddDetail("pit","In the middle of the church is a deep pit.\n"+
+        "It was used for sacrifice in the old times, but nowadays\n" +
+        "it is only left for tourists to look at.\n");
+  AddDetail(({"elevator","door","button"}),
+            "The elevator doesn't work any more. It must be a relict from another time,\n"+
+            "a long-gone time, as this whole building.\n");
+  AddDetail("clock","The clock shows this game hasn't been rebooted for centuries. Time is\n"+
+                    "standing still in this strange room.\n");
+  AddCmd("pray","pray");
+  AddCmd("open","open");
+  AddCmd("push","open");
+}
+
+open()
+{
+  notify_fail("The elevator doesn't work anymore, sorry.\n");
+  return 0;
+}
+
+pray()
+{
+  write("The gods this church was built for have died an extremly long time ago.\n");
+  return 1;
+}
+
diff --git a/room/death/death_mark.c b/room/death/death_mark.c
new file mode 100644
index 0000000..8219016
--- /dev/null
+++ b/room/death/death_mark.c
@@ -0,0 +1,67 @@
+#pragma strict_types
+
+#include <moving.h>
+#include <properties.h>
+#include <language.h>
+
+inherit "std/thing";
+
+void create()
+{
+  ::create();
+  SetProp( P_NAME, "Stempel des Todes" );
+  SetProp( P_GENDER, MALE );
+  SetProp( P_SHORT, 0 );
+  SetProp( P_INVIS, 1 );
+  SetProp( P_NEVERDROP, 1 );
+  SetProp( P_WEIGHT, 0);
+  AddId(({"death_mark","\ndeath_mark"}));
+}
+
+void reset()
+{
+  ::reset();
+  if (environment() && !query_once_interactive(environment()))
+    remove();
+}
+
+
+/*
+ * Function name: start_death
+ * Description:   Start the death sequence.
+ */
+void start_death()
+{
+  if ( !environment() || !query_once_interactive(environment())
+       || !environment()->QueryProp(P_GHOST) )
+  {
+      destruct(this_object());
+      return;
+  }
+
+  say("Du siehst eine dunkle Gestalt, die etwas Dunst einsammelt ... oder vielleicht\n"+
+      "bildest du Dir das auch nur ein ...\n");
+ environment()->move("/room/death/virtual/death_room_"+getuid(environment()),
+		     M_GO|M_SILENT|M_NO_SHOW|M_NOCHECK);
+ // direkt in virtuellen Todesraum moven
+}
+
+protected int PreventMove(object dest, object oldenv, int method) {
+  // wenn die marke schon ein Env hat oder der move nicht in einen Spieler
+  // geht, gehts nur mit M_NOCHECK.
+  if ( (environment(this_object()) || !query_once_interactive(dest)) 
+      && !(method & M_NOCHECK)) {
+    return ME_CANT_BE_DROPPED;
+  }
+
+  return ::PreventMove(dest, oldenv, method);
+}
+
+int _query_autoloadobj() { return 1; }
+
+void init()
+{
+  ::init();
+  if (this_player() == environment())
+    start_death();
+}
diff --git a/room/death/death_mark_hooked.c b/room/death/death_mark_hooked.c
new file mode 100644
index 0000000..0e09e8f
--- /dev/null
+++ b/room/death/death_mark_hooked.c
@@ -0,0 +1,66 @@
+#pragma strict_types
+
+#include <moving.h>
+#include <properties.h>
+#include <language.h>
+#include <new_skills.h>
+
+inherit "std/thing";
+
+void create()
+{
+  ::create();
+  SetProp( P_NAME, "Stempel des Todes" );
+  SetProp( P_GENDER, MALE );
+  SetProp( P_SHORT, 0 );
+  SetProp( P_INVIS, 1 );
+  SetProp( P_NEVERDROP, 1 );
+  AddId(({"death_mark","\ndeath_mark"}));
+}
+
+void reset()
+{
+  ::reset();
+  if (environment() && !query_once_interactive(environment()))
+    remove();
+}
+
+
+/*
+ * Function name: start_death
+ * Description:   Start the death sequence.
+ */
+void start_death()
+{
+  if ( !environment() || !query_once_interactive(environment())
+       || !environment()->QueryProp(P_GHOST) )
+  {
+      destruct(this_object());
+      return;
+  }
+
+  say("Du siehst eine dunkle Gestalt, die etwas Dunst einsammelt ... oder vielleicht\n"+
+      "bildest du Dir das auch nur ein ...\n");
+  environment()->move("/room/death/virtual/death_room_"+getuid(environment()),
+		     M_GO|M_SILENT|M_NO_SHOW|M_NOCHECK);
+  // Der folgende Code verhindert, dass ein unbedachter Magier im init
+  // oder exit einen Spieler tötet, und ihn dirket danach movet.
+  environment()->SetProp(P_TMP_MOVE_HOOK,({time()+10,this_object(),"catch_die_move"}));  
+}
+
+varargs int move(mixed dest,mixed method)
+{	
+  if (!method & M_NOCHECK) return ME_CANT_BE_DROPPED;
+  return ::move(dest,method);
+}
+
+int _query_autoloadobj() { return 1; }
+
+int catch_die_move() { return -1; }
+
+void init()
+{
+  ::init();
+  if (this_player() == environment())
+    start_death();
+}
diff --git a/room/death/death_room.c b/room/death/death_room.c
new file mode 100644
index 0000000..5e59f20
--- /dev/null
+++ b/room/death/death_room.c
@@ -0,0 +1,669 @@
+// MorgenGrauen MUDlib
+//
+// death_room.c -- Der Todesraum
+//
+// $Id: death_room.c 9138 2015-02-03 21:46:56Z Zesstra $
+
+
+#pragma strict_types
+
+#include <defines.h>
+#include <properties.h>
+#include <moving.h>
+#include <language.h>
+#include <wizlevels.h>
+#include <daemon.h>
+#include <new_skills.h>
+
+inherit "/std/room";
+
+mixed *players;
+mapping msgCache;
+
+
+private void flush( int unusedOnly );
+private string expand( string table, int value );
+private string parseText( string msg, object pl );
+private void do_remove();
+private varargs mixed get_sequence( string str );
+void add_player( object pl );
+static int filter_ldfied( string str );
+public int SmartLog( string creat, string myname, string str, string date );
+public mixed hier_geblieben( mixed dest, int methods, string direction,
+                             string textout, string textin );
+public void init()
+{
+  this_player()->move("/room/death/virtual/death_room_"+getuid(this_player()),
+	     M_NOCHECK|M_SILENT|M_NO_SHOW);
+  return;
+}
+
+public void create()
+{
+  if (IS_CLONE(this_object())) return;
+    ::create();
+    
+    players = ({});
+    flush(0);
+
+    SetProp( P_NAME, "Lars" );
+    SetProp( P_GENDER, MALE );
+    SetProp( P_ARTICLE, 0 );
+    SetProp( P_LIGHT,1 );
+    SetProp( P_NO_TPORT, NO_TPORT_OUT );
+    SetProp( P_LOG_FILE, "TOD/Todesraum" );
+    SetProp( P_INT_SHORT, "Arbeitszimmer des Todes" );
+    SetProp( P_INT_LONG, break_string(
+             "Ein dunkler Raum, erleuchtet von dunklem Licht, das sich der "
+             "Dunkelheit nicht so sehr zu widersetzen scheint, indem es "
+             "leuchtet, als dass es der dunkelste Punkt in einer weniger "
+             "dunklen Umgebung ist. Im seltsamen Licht erkennst Du einen "+
+             "zentral aufgestellten Schreibtisch, der mit Diagrammen und "
+             "Buechern bedeckt ist. Die Waende verschwinden hinter Regalen, "
+             "die gefuellt sind mit in Leder gebundenen, dunklen Waelzern, "
+             "von denen geheimnisvolle Runen leuchten.\nTod.", 78, 0, 1 ) );
+}
+
+
+public void reset()
+{
+    ::reset();
+    flush(1);
+}
+
+private void flush( int unusedOnly )
+{
+    string *mi;
+    int i;
+
+    if ( unusedOnly ){
+        if ( i = sizeof(mi = m_indices(msgCache)) ){
+            for ( ; i--; )
+                if ( msgCache[mi[i], 1] )
+                    msgCache[mi[i], 1] = 0;
+                else
+                    msgCache = m_copy_delete( msgCache, mi[i] );
+        }
+    }
+    else
+        msgCache = ([]);
+}
+
+
+private string expand( string table, int value )
+{
+    int sz, wert, i;
+    string *texte;
+
+    sz = sizeof( texte = explode( table, "##" ) - ({""}) );
+    
+    for ( i = 0; i < sz; i++ )
+        if ( i%2 ){
+            sscanf( texte[i], "%d", wert );
+            
+            if ( value < wert )
+                break;
+        }
+        else
+            table = texte[i];
+
+    return table;
+}
+
+
+#define TOS(s) s[<1]
+#define STOS(s) s[<2]
+#define PUSH(x,s) (s+= ({ x }))
+#define POP(s)	(s=s[0..<2])
+
+// ziemlich vom htmld abgekupfert ;)
+private string
+parseText( string msg, object pl ) 
+{
+  string *words, *texte, *todo, *done;
+  int endFlag;
+
+  int sz = sizeof( words = regexplode(msg, "[<][^>]*[>]") );
+  todo = ({ });
+  done = ({""});
+
+  for ( int i=1; i<sz; i+=2 ){
+      string cmd = words[i][1..<2];
+      TOS(done) += words[i-1];
+
+      if ( cmd[0] == '/' ){
+          endFlag = 1;
+          cmd = cmd[1..];
+      }
+      else
+          endFlag = 0;
+      
+      switch( cmd[0] ){
+      case 'A': /*** Alignment ersetzen ***/
+          if (!endFlag){
+              PUSH( cmd, todo );
+              PUSH( "", done );
+          }
+          else
+              if ( todo[<1] == "A" ){
+                  STOS(done) += expand(TOS(done), (int) pl->QueryProp(P_ALIGN));
+                  done = done[0..<2];
+                  todo = todo[0..<2];
+              }
+          break;
+          
+      case 'D': /*** Tode ersetzen ***/
+          if ( !endFlag ){
+              PUSH( cmd, todo );
+              PUSH( "", done );
+          }
+          else
+              if ( todo[<1] == "D" ){
+                  STOS(done) += expand(TOS(done), (int) pl->QueryProp(P_DEADS));
+                  POP(done);
+                  POP(todo);
+              }
+          break;
+          
+      case 'L': /*** Level ersetzen ***/
+          if ( !endFlag ){
+              PUSH( cmd, todo );
+              PUSH( "", done );
+          }
+          else
+              if ( todo[<1] == "L" ){
+                  STOS(done) += expand(TOS(done), (int) pl->QueryProp(P_LEVEL));
+                  POP(done);
+                  POP(todo);
+              }
+          break;
+          
+      case 'Z': /*** Zufall ersetzen ***/
+          if ( !endFlag ){
+              PUSH( cmd, todo );
+              PUSH( "", done );
+          }
+          else{
+              if ( todo[<1][0] == 'Z'){
+                  int cnt, rnd, wert, sz2;
+                  
+                  if ( !sscanf(todo[<1], "Z=%d", rnd) )
+                      STOS(done) += "\n###\n### Syntax Error in <Z>!\n###\n\n";
+                  else {
+                      rnd = random(rnd);
+                      sz2 = sizeof( texte = explode(TOS(done), "##") );
+                      wert=0;
+                      cnt=0;
+                      
+                      for ( int k = 1; k < sz2; k += 2 ){
+                          sscanf( texte[k], "%d", wert );
+                          cnt += wert;
+                          if ( rnd < cnt ) {
+                              STOS(done) += texte[k+1];
+                              break;
+                          }
+                      }
+                  }
+                  POP(done);
+                  POP(todo);
+              }
+          }
+          break;
+
+      case 'G': /*** Gender ersetzen ***/
+          if ( !endFlag ){
+              PUSH( cmd, todo );
+              PUSH( "", done );
+          }
+          else{
+              if( sizeof( texte = regexplode(TOS(done), ":") ) == 3 )
+                  STOS(done) += texte[2*((int) pl->QueryProp(P_GENDER)
+                                         == FEMALE)];
+              POP(done);
+              POP(todo);
+          }
+          break;
+
+      case 'R': /*** Rasse ersetzen ***/
+          if ( !endFlag ){
+              PUSH( cmd, todo );
+              PUSH( "", done );
+          }
+          else{
+              int race;
+
+              texte = regexplode( TOS(done), "\\|" );
+              race = 2 * (member( ({ "Mensch", "Elf", "Zwerg", "Hobbit",
+                                         "Feline", "Dunkelelf" }),
+                                  (string) pl->QueryProp(P_RACE) ) + 1);
+              
+              if ( race >= sizeof(texte) )
+                  race = 0;
+
+              STOS(done) += texte[race];
+              POP(done);
+              POP(todo);
+          }
+          break;
+
+      case 'n': /*** Name, normal geschrieben ***/
+          TOS(done) += (string) (pl->name(RAW));
+          break;
+
+      case 'N': /*** Name, in Grossbuchstaben ***/
+          TOS(done) += upperstring(pl->name(RAW));
+          break;
+      }
+  }
+  PUSH( words[<1], done );
+  return implode( done, "" );
+}
+
+
+public void heart_beat()
+{
+    for ( int j = sizeof(players); j--; )
+        if ( !objectp(players[j][0]) ||
+             environment(players[j][0]) != 
+	     find_object("/room/death/virtual/death_room_"+getuid(players[j][0])) )
+            players[j] = 0;
+
+    players -= ({0});
+
+    if ( !sizeof(players) ) {
+        set_heart_beat(0);
+        return;
+    }
+
+  for ( int j = sizeof(players); j--; ) {
+      int nr;
+      string msg;
+
+      nr = ++players[j][1];
+
+      if ( mappingp(players[j][2]) )
+          msg = players[j][2][nr];
+      else
+          msg = 0;
+      
+      if ( !msg )
+          msg = players[j][3][1][nr];
+      
+      if ( msg )
+          tell_object( players[j][0], parseText( msg, players[j][0] ) );
+  }
+  
+  do_remove();
+}
+
+private void
+do_remove()
+{
+    int res;
+    string prayroom;
+    object plobj, pl;
+    
+    for ( int j = sizeof(players); j--; ){
+        if ( players[j][1] >= players[j][3][0]){
+            pl = players[j][0];
+            while ( plobj = present("\ndeath_mark", pl) )
+                plobj->remove();
+            
+            if ( !(prayroom = (string) pl->QueryPrayRoom()) )
+                prayroom="/room/pray_room";
+
+            pl->Set( P_TMP_MOVE_HOOK, 0 );
+            pl->Set( P_NO_ATTACK, 0, F_QUERY_METHOD );
+            pl->Set( P_LAST_KILLER, 0 );
+            pl->Set( P_KILLER, 0 );
+            pl->Set( P_ENEMY_DEATH_SEQUENCE, 0 );
+            pl->Set( P_NEXT_DEATH_SEQUENCE, 0 );
+            pl->Set( P_POISON, 0, F_QUERY_METHOD );
+            
+            if ( catch( res = (int) pl->move(prayroom, M_GO|M_SILENT|M_NOCHECK) )
+                 || res < 1 )
+                pl->move( "/room/pray_room", M_GO|M_NOCHECK );
+
+            players[j] = 0;
+        }
+    }
+
+    players -= ({0});
+
+    if ( !sizeof(players) )
+        set_heart_beat(0);
+}
+
+private varargs mixed
+get_sequence( string str )
+{
+    string *sequences;
+    int i, len, cacheable;
+    
+    if ( !stringp(str) || catch( len = file_size(str) ) || len <= 0 ){
+        sequences = get_dir( "/room/death/sequences/*" ) - ({ ".", "..", ".svn" });
+        str = "/room/death/sequences/" + sequences[random( sizeof(sequences) )];
+    }
+
+    if ( cacheable = ((sizeof(str) > 21) &&
+                      (str[0..21] == "/room/death/sequences/")) ){
+        if ( member(msgCache, str) ){
+            msgCache[str, 1] = 1;  // Touch it!
+            return ({ msgCache[str], str });
+        }
+    }
+    
+    sequences = explode( read_file(str), "\n" );
+    sscanf( sequences[0], "%d", len );
+    string seq = implode( sequences[1..], "\n" );
+    sequences = regexplode( seq, "[0-9][0-9]*:" );
+    mapping m = ([]);
+    
+    for ( i = 1; i < sizeof(sequences)-1; i += 2 )
+        m[(int) sequences[i]] = sequences[i+1];
+
+    if ( cacheable )
+        msgCache += ([ str: ({ len, m }); 1 ]);
+
+    return ({ ({ len, m }), str });
+}
+
+// Description:   Adds a player to the list
+void add_player( object pl )
+{
+    int kart, kgen;
+    int escaped;
+    object kill_liv, kill_ob;
+    mixed dseq, act_seq, killer_name, killer_msg;
+ 
+    set_heart_beat(1);
+    kgen = MALE;
+
+    foreach(object prev : caller_stack(1)) { 
+        if ( !objectp(prev) || prev == pl )
+            continue;
+
+        string fn = object_name(prev);
+
+        if ( fn[0..12] == "/secure/login" && !kill_liv ){
+            escaped = 1;
+            break;
+        }
+
+        if ( fn[0..7] == "/secure/" && fn[0..13] != "/secure/merlin" )
+            continue;
+
+        if ( fn[0..21] == "/room/death/death_mark" )
+            continue;
+
+        if ( living(prev) ){
+            kill_liv = prev; // Killer
+            break;
+        }
+
+        kill_ob = prev; // killendes Objekt
+    }
+
+    object pre = (object) pl->QueryProp(P_KILLER);
+    if ( objectp(pre) ) {
+        dseq = (mixed) pre->QueryProp(P_ENEMY_DEATH_SEQUENCE);
+
+        if( !(killer_name = (mixed) pre->QueryProp(P_KILL_NAME)) ){
+            killer_name = (mixed) pre->QueryProp(P_NAME);
+            kart = (int) pre->QueryProp(P_ARTICLE);
+            kgen = (int) pre->QueryProp(P_GENDER);
+        }
+
+        killer_msg = (mixed)pre->QueryProp(P_KILL_MSG);  
+    }
+
+    if ( !killer_name && kill_liv && function_exists( "QueryProp", kill_liv ) ){
+        dseq = (mixed) kill_liv->QueryProp(P_ENEMY_DEATH_SEQUENCE);
+
+        if( !(killer_name = (mixed) kill_liv->QueryProp(P_KILL_NAME)) ){
+            killer_name = (mixed) kill_liv->QueryProp(P_NAME);
+            kart = (int) kill_liv->QueryProp(P_ARTICLE);
+            kgen = (int) kill_liv->QueryProp(P_GENDER);
+        }
+
+        killer_msg = (mixed) kill_liv->QueryProp(P_KILL_MSG);
+        pre = kill_liv;
+    }
+
+    if ( !killer_name && kill_ob && function_exists( "QueryProp", kill_ob ) ){
+        dseq = (mixed) kill_ob->QueryProp(P_ENEMY_DEATH_SEQUENCE);
+
+        if( !(killer_name = (mixed) kill_ob->QueryProp(P_KILL_NAME)) ){
+            killer_name = (mixed) kill_ob->QueryProp(P_NAME);
+            kart = (int) kill_ob->QueryProp(P_ARTICLE);
+            kgen = (int) kill_ob->QueryProp(P_GENDER);
+        }
+
+        killer_msg = (mixed) kill_ob->QueryProp(P_KILL_MSG);
+        pre = kill_ob;
+    }
+    
+    // falls keine Sequenz gesetzt, eventuelle eigene Todessequenz nehmen
+    if (!dseq)
+      dseq = (mixed)pl->QueryProp(P_NEXT_DEATH_SEQUENCE);
+
+    act_seq = 0;
+
+    if ( mappingp(dseq) )
+        act_seq = get_sequence( "/room/death/sequences/lars" );
+    else if ( pointerp(dseq) )  // ganze Todessequenz...
+        act_seq = ({ dseq, 0 });
+    else if ( stringp(dseq) )
+        act_seq = get_sequence(dseq);
+
+    if(pl->query_hc_play()>1)
+    {
+        act_seq=({({22,([1:"Du faellst und faellst...\n",
+                        5:"und faellst...\n",
+                        10:"und faellst...\n",
+                        12:"direkt in die Arme von TOD.\n",
+                        14:"Triumphierend laechelt er Dich an.\n",
+                        16:"NUN GEHOERST DU FUER IMMER MIR!\n",
+                        18:"HAHHHAHAHAAAAAAAAAAHAAAAAAAAA!\n",
+                        20:"TOD schlaegt Dir mit seiner Sense den Kopf ab.\n"])}),0});
+    }
+    if ( !act_seq )
+        act_seq = get_sequence();
+
+    if ( !mappingp(dseq) )
+        dseq = 0;
+
+    int i;
+    for ( i = sizeof(players); i--; )
+        if ( players[i][0] == pl )
+            break;
+
+    if ( i == -1 )
+        players += ({ ({ pl, 0, dseq, act_seq[0], act_seq[1], pre }) });
+    else
+        players[i][5] = pre;
+
+
+        if ( escaped ){
+            killer_name = "";
+            killer_msg = upperstring(getuid(pl)) + " VERSUCHTE, MIR ZU "
+                "ENTKOMMEN - JETZT HABE ICH WIEDER EXTRA-ARBEIT MIT "+
+                ((int) pl->QueryProp(P_GENDER) != 2 ? "IHM" : "IHR") +
+                " ...";
+        }
+        else if ( !killer_name ) {
+                if ( (string) pl->QueryProp(P_KILLER) == "gift" ){
+                    killer_name = "Vergiftung";
+                    kgen = FEMALE;
+                    kart = 1;
+                }
+                else{
+                    killer_name = "Etwas Geheimnisvolles und Unbekanntes";
+                    kgen = NEUTER;
+                    kart = 0;
+                }
+        }
+
+        if ( !pointerp(killer_msg) )
+            killer_msg = ({ killer_msg, 0, 0 });
+        else if ( sizeof(killer_msg) < 3 )
+            killer_msg += ({ 0, 0, 0 });
+
+        if ( stringp(killer_msg[0]) )
+            killer_msg[0] = sprintf( killer_msg[0], capitalize(getuid(pl)) );
+
+        SetProp( P_NAME, killer_name );
+        SetProp( P_ARTICLE, kart );
+        SetProp( P_GENDER, kgen );
+        string killname = Name(WER);
+        SetProp( P_NAME, "Lars" );
+        SetProp( P_ARTICLE, 0 );
+        SetProp( P_GENDER,MALE );
+
+        int magiertestie;
+        string testplayer = (string) pl->QueryProp(P_TESTPLAYER);
+        if (sizeof(testplayer))
+        {
+          if (testplayer[<5..<1]!="Gilde")
+            magiertestie = 1;
+        }
+          
+        string kanal;
+        if  (magiertestie || IS_LEARNING(pl))
+            kanal = "TdT";
+        else
+            kanal = "Tod";
+
+        CHMASTER->join( kanal, this_object() );
+
+        if ( (!stringp(killer_name) || killer_name != "") &&
+             (sizeof(killer_msg) < 4 || !killer_msg[3]) ){
+            if ( killer_msg[2] == PLURAL )
+                CHMASTER->send( kanal, this_object(),
+                                killname + " haben gerade " +
+                                capitalize(getuid(pl)) + " umgebracht." );
+            else
+                CHMASTER->send( kanal, this_object(),
+                                killname + " hat gerade " +
+                                capitalize(getuid(pl)) + " umgebracht." );
+        }
+
+        i = (int) pl->QueryProp(P_DEADS);
+        if ( i && (getuid(pl) == "key" || i%100 == 0 || i%250 == 0) ){
+            SetProp( P_NAME, "Tod" );
+            CHMASTER->send( kanal, this_object(),
+                            sprintf( "DAS WAR SCHON DAS %dTE MAL!", i ) );
+            SetProp( P_NAME, "Lars" );
+        }
+
+        if( killer_msg[0] ){
+            if ( stringp(killer_name) && killer_name == "" ){
+                CHMASTER->send( kanal, this_object(),
+                                break_string( funcall(killer_msg[0]), 78,
+                                              "["+kanal+":] " )[0..<2],
+                                MSG_EMPTY );
+                return; 
+            }
+            else {
+                if ( (killer_msg[1] < MSG_SAY) || (killer_msg[1] > MSG_GEMOTE) )
+                    killer_msg[1] = MSG_SAY;
+
+                SetProp( P_NAME, killer_name );
+                SetProp( P_ARTICLE, kart );
+                SetProp( P_GENDER, kgen );
+                CHMASTER->send( kanal, this_object(), funcall(killer_msg[0]),
+                                killer_msg[1] );
+                SetProp( P_NAME, "Lars" );
+                SetProp( P_ARTICLE, 0 );
+                SetProp( P_GENDER, MALE );
+            }
+        }
+
+        if ( pointerp(killer_msg = (mixed) pl->QueryProp(P_DEATH_MSG)) &&
+             sizeof(killer_msg) == 2 && stringp(killer_msg[0]) &&
+             intp(killer_msg[1]) ){
+            SetProp( P_NAME, capitalize(getuid(pl)) );
+            SetProp( P_ARTICLE, 0 );
+            SetProp( P_GENDER, pl->QueryProp(P_GENDER) );
+            CHMASTER->send( kanal, this_object(), killer_msg[0],
+                            killer_msg[1] );
+            SetProp( P_NAME, "Lars" );
+            SetProp( P_ARTICLE, 0 );
+            SetProp( P_GENDER, MALE );
+        }
+
+        if (pl->query_hc_play()>1){
+            SetProp( P_NAME, "Tod" );
+            CHMASTER->send( kanal, this_object(),"NUN GEHOERST DU FUER EWIG MIR!" );
+            SetProp( P_NAME, "Lars" );
+        }
+}
+
+public int
+SmartLog( string creat, string myname, string str, string date )
+{
+    int i;
+    string fn;
+    
+    for ( i = sizeof(players); i--; )
+        if ( players[i][0] == this_player() )
+            break;
+
+    // Spieler (Magier?) ist in keiner Todessequenz -> normales Repfile
+    if ( i == -1 )
+        return 0;
+
+    if ( !(fn = players[i][4]) ){
+        // Spieler hat eine unbekannte Todessequenz (kein Filename, Sequenz
+        // wurde komplett in P_ENEMY_DEATH_SEQUENCE abgelegt)
+        creat = "TOD/unbekannt.rep";
+        fn = "unbekannte Todessequenz";
+    }
+    else
+        // Jede Sequenz mit nem eigenen Repfile
+        creat = "TOD/" + explode( fn, "/" )[<1] + ".rep";
+
+    log_file( creat, myname + " von " + getuid(this_interactive())
+              + " ["+fn+"] (" + date + "):\n" + str + "\n" );
+
+    return 1;
+}
+
+public mixed hier_geblieben( mixed dest, int methods, string direction,
+                             string textout, string textin ) 
+{
+    // Magier duerfen Spieler heraustransen
+    if ( this_interactive() && IS_LEARNER(this_interactive()) &&
+         (this_interactive() != previous_object() ||
+          IS_DEPUTY(this_interactive())) ){
+        previous_object()->Set( P_TMP_MOVE_HOOK, 0 );
+        return ({ dest, methods, direction, textout, textin });
+    }
+
+    // Spieler haengt noch in der Todessequenz
+    for ( int i = sizeof(players); i--; )
+        if ( objectp(players[i][0]) && previous_object() == players[i][0] &&
+             environment(previous_object()) == find_object(
+	  "/room/death/virtual/room_death_" + getuid(previous_object()))&&
+             interactive(previous_object()) ) {
+	    // Move nur erlaubt, wenn das Ziel wieder der Todesraum ist.
+	    // wenn mal fuer nen bestimmten Zwecks Bewegungen raus aus dem
+	    // Todesraum erforderlich sind, sollten hier entsprechende
+	    // Ausnahmen eingebaut werden.
+	    if ( (stringp(dest) && 
+		  dest == object_name(environment(previous_object()))) ||
+		 (objectp(dest) &&
+		  dest == environment(previous_object())) ) {
+		previous_object()->Set( P_TMP_MOVE_HOOK, 0 );
+		return ({ dest, methods, direction, textout, textin });
+	    }
+            else
+                return -1;
+        }
+
+    // Spieler ist nicht mehr im Raum oder eingeschlafen
+    if ( previous_object() )
+        previous_object()->Set( P_TMP_MOVE_HOOK, 0 );
+    
+    return ({ dest, methods, direction, textout, textin });
+}
diff --git a/room/death/death_room_vc.c b/room/death/death_room_vc.c
new file mode 100644
index 0000000..71038fb
--- /dev/null
+++ b/room/death/death_room_vc.c
@@ -0,0 +1,168 @@
+// MorgenGrauen MUDlib
+//
+// death_room_vc.c -- Das Standardobjekt fuer den VC-Todesraum
+//
+// $Id: death_room_vc.c 8988 2014-12-31 13:10:19Z Zesstra $
+
+
+#pragma strict_types
+
+#include <defines.h>
+#include <properties.h>
+#include <moving.h>
+#include <language.h>
+#include <wizlevels.h>
+#include <daemon.h>
+#include <new_skills.h>
+
+inherit "/std/room";
+
+public int no_attack();
+public int no_poison(int val);
+
+public void create()
+{
+  if (IS_BLUE(this_object())) return;
+    ::create();
+    
+    SetProp( P_GENDER, MALE );
+    SetProp( P_ARTICLE, 0 );
+    SetProp( P_LIGHT,1 );
+    SetProp( P_NO_TPORT, NO_TPORT_OUT );
+    SetProp( P_LOG_FILE, "TOD/Todesraum" );
+    SetProp( P_INT_SHORT, "Arbeitszimmer des Todes" );
+    SetProp( P_INT_LONG, break_string(
+             "Ein dunkler Raum, erleuchtet von dunklem Licht, das sich der "
+             "Dunkelheit nicht so sehr zu widersetzen scheint, indem es "
+             "leuchtet, als dass es der dunkelste Punkt in einer weniger "
+             "dunklen Umgebung ist. Im seltsamen Licht erkennst Du einen "+
+             "zentral aufgestellten Schreibtisch, der mit Diagrammen und "
+             "Buechern bedeckt ist. Die Waende verschwinden hinter Regalen, "
+             "die gefuellt sind mit in Leder gebundenen, dunklen Waelzern, "
+             "von denen geheimnisvolle Runen leuchten.\nTod.", 78, 0, 1 ) );
+    previous_object()->CustomizeObject();
+    call_other("/room/death/death_room","???");
+}
+
+void test_remove()
+{
+  if (!sizeof(all_inventory(this_object())&users()))
+    if (!this_object()->remove()) destruct(this_object());
+}
+
+public void reset()
+{
+  ::reset();
+  test_remove();
+  return;
+}
+
+public void exit(object liv)
+{
+  call_out("test_remove",2);
+  return;
+}
+
+
+static void deep_destruct( object ob )
+{
+    if ( objectp(ob) && environment(ob) == this_object() )
+        filter( deep_inventory(ob) + ({ ob }),
+                      lambda( ({'x/*'*/}), ({#'destruct, 'x}) ) );
+}
+
+public void init()
+{  
+  string prayroom;
+  int res;
+
+  ::init();
+  if ( !query_once_interactive(this_player()) ){
+      call_out( "deep_destruct", 0, this_player() );
+      return;
+  }
+
+  if ( !(prayroom = (string) this_player()->QueryPrayRoom()) )
+      prayroom = "/room/pray_room";
+  
+  if ( !this_player()->QueryProp(P_GHOST) )
+    {
+      if ( IS_WIZARD(this_player()) &&
+           this_player()->QueryProp(P_WANTS_TO_LEARN) )
+	{
+          if ( !this_player()->QueryProp(P_INVIS) )
+              tell_room( this_object(),
+                         "Der Tod sagt: WAS WILLST DU HIER, "+
+                         upperstring((string) this_player()->name())+"?\n"+
+                         "Der Tod sagt: DU BIST UNSTERBLICH, DU HAST HIER "
+                         "NICHTS ZU SUCHEN!\n\n" );
+	}
+      else 
+	{
+          write("Der Tod sagt: WAS TUST DU HIER? DEINE ZEIT IST NOCH "
+                "NICHT REIF!\n\n");
+          
+	  if ( catch(res = (int) this_player()->move( prayroom,M_GO|M_SILENT|M_NOCHECK ))
+               || res < 1 && environment(this_player()) == this_object() )
+              this_player()->move( "/room/pray_room", M_GO|M_SILENT|M_NOCHECK );
+	}
+      return;
+    }
+
+  if ( !IS_DEPUTY(this_player()) ){
+    add_action( "filter_ldfied", "", 1 );
+    this_player()->Set( P_TMP_MOVE_HOOK,
+                        ({ time()+31536000, 
+                           find_object("/room/death/death_room"), 
+                           "hier_geblieben" }) );
+  }
+
+  this_player()->Set( P_NO_ATTACK, #'no_attack, F_QUERY_METHOD );
+  this_player()->Set( P_POISON, #'no_poison, F_SET_METHOD );
+  
+  "/room/death/death_room"->add_player(this_player());
+}
+
+// public, da command_me() sonst buggt (Wurzels Speedy o.ae.)
+public int filter_ldfied( string str )
+{
+    // Description:   Filter out relevant commands.
+    string verb;
+    
+    verb=query_verb();
+    
+    if ( (verb == "schlafe" || verb == "schlaf") && str == "ein" ){
+        write("DU KANNST DEM TOD NICHT ENTRINNEN!\n");
+        return 0;
+    }
+    
+    if ( verb == "typo" || verb == "fehler" || verb == "bug" || verb == "idee" )
+        return 0;
+
+    write( "Dein Koerper gehorcht Dir nicht !\n" );
+    return 1;
+}
+
+public int no_attack()
+{
+  int i;
+
+  // Spieler haengt noch in der Todessequenz
+  if( present(previous_object()) )
+    return 1;
+  else
+    previous_object()->Set( P_NO_ATTACK, 0, F_QUERY_METHOD );
+
+  return 0;
+}
+
+public int no_poison(int val)
+{
+  if ( val != 0 )
+  {
+    catch( raise_error("Poisoning dead players is illegal. Calling object "
+      "was "+object_name(previous_object(1))+"\n");publish );
+  }
+  return 0;
+}
+
diff --git a/room/death/virtual/virtual_compiler.c b/room/death/virtual/virtual_compiler.c
new file mode 100644
index 0000000..90d886e
--- /dev/null
+++ b/room/death/virtual/virtual_compiler.c
@@ -0,0 +1,44 @@
+// MorgenGrauen MUDlib
+//
+// virtual_compiler.c -- Virtueller Compiler fuer die Todesraeume
+//
+// $Id.$
+
+
+#pragma strong_types
+
+inherit "/std/virtual/v_compiler";
+
+#include <defines.h>
+#include <v_compiler.h>
+
+int NoParaObjects() {return 1;}
+
+void create() 
+{
+  if (IS_CLONE(this_object())) return;
+ ::create();
+ SetProp(P_STD_OBJECT, "/room/death/death_room_vc");
+ seteuid(getuid());
+ return;
+}
+
+string Validate(string file) {
+  string base, room, who;
+
+ file = ::Validate(file);
+ if(sscanf(file, "death_room_%s",who)!=1 ||
+    ((who[0..3]!="gast") &&
+    (!"/secure/master"->get_userinfo(who)))) return 0;
+ return file;
+}
+
+mixed CustomizeObject()
+{
+ string base,room,who,file,fun;
+
+ if(!(file = ::CustomizeObject()) ||
+    !Validate(file)) return 0;
+ return file;
+}
+
diff --git a/room/jail.c b/room/jail.c
new file mode 100644
index 0000000..1331223
--- /dev/null
+++ b/room/jail.c
@@ -0,0 +1,191 @@
+#pragma strong_types,rtt_checks
+
+inherit "/std/room";
+inherit "/std/hook_consumer";
+
+#define OFFICE "/d/wueste/catweazle/room/office"
+
+#include <properties.h>
+#include <wizlevels.h>
+#include <hook.h>
+
+protected void create()
+{
+  ::create();
+  SetProp(P_LIGHT, 1 );
+  SetProp(P_INT_SHORT,"Eine Gefaengniszelle");
+  SetProp(P_INT_LONG, break_string(
+      "Die Zelle ist absolut eintoenig und hat keine Fenster. Lange hier drin"
+      "zu sitzen ist bestimmt nicht angenehm. Wenn du hier heraus willst, "
+      "kannst Du wohl nur den Sheriff, seinen Stellvertreter oder einen "
+      "Erzmagier darum bitten.",78));
+  SetProp(P_INDOORS,1);
+}
+
+void init()
+{
+  ::init();
+  if (!query_once_interactive(this_player()))
+    return;
+  if ( IS_DEPUTY(this_player()) ) // EM+ sind sowieso Deputies
+    return;
+  add_action("bla","",1);
+  input_to("murks",0);
+
+  // Move-Hook anhaengen
+  int ret = this_player()->HRegisterToHook(H_HOOK_MOVE, this_object(), 
+                                 H_HOOK_LIBPRIO(1),H_HOOK_SURVEYOR,
+				 -1);
+  if ( ret <=0 )
+      raise_error("Fehler: Move-Hook konnte nicht registriert werden. "
+                  "HRegisterToHook-Ergebnis: " + ret + "\n");
+}
+
+// Move-Hook austragen.
+void exit(object liv) {
+  if (objectp(liv) && !IS_DEPUTY(liv))
+    liv->HUnregisterFromHook(H_HOOK_MOVE,this_object());
+}
+
+int bla()
+{
+  string v;
+
+  v=query_verb();
+  input_to("murks",0);
+  // sagen und schlafen erlaubt.
+  if (stringp(v) && (v=="sag"||v=="sage"||v[0]=='\''
+        ||v=="schlafe"||v=="schlaf"))
+      return 0;
+  write("Nix da.\n");
+  return 1;
+}
+
+int murks(string str)
+{
+  if (!this_player() || environment(this_player())!=this_object()) 
+      return 0;
+
+  input_to("murks",0);
+
+  if (!str||str=="") return 1;
+  // Einschlafen erlaubt.
+  if (str == "schlafe ein") {
+      this_player()->command("schlafe ein");
+      return 1;
+  }
+  if (str[0]=='\'') str="sag "+str[1..];
+  if(str[0..3]=="sag "||str[0..4]=="sage ")
+  {
+       str=implode(old_explode(str," ")[1..]," ");
+     write(break_string(str, 78, "Du sagst: "));
+     tell_room(this_object(),break_string(str,78,
+         capitalize(this_player()->name())+" sagt: "),({this_player()}));
+     return 1;
+  }
+  write("Nix da.\n");
+  return 1;
+}
+
+public varargs int remove(int silent) {
+  // keine Zerstoerung, wenn Spieler drin sind.
+  if (sizeof(filter(all_inventory(),#'query_once_interactive)))
+    return 0;
+
+  return ::remove(1);
+}
+
+public string NotifyDestruct(object caller) {
+
+  if (previous_object() != master()
+      || caller == this_object())
+    return 0;
+
+  // wenn keiner hier ist, ists egal.
+  if (!sizeof(filter(all_inventory(),#'query_once_interactive)))
+    return 0;
+
+  // Direkter Destruct mit Anwesenden nur fuer EM+
+  if (!process_call() && this_interactive()
+      && IS_ARCH(this_interactive()))
+    return 0;
+      
+  return "Direkte Zerstoerung des Jails nur fuer EM+ erlaubt.\n";
+}
+
+
+// keine anderen Move-Hooks erlaubt ausser diesem...
+status HookRegistrationCallback(object registringObject, int hookid, object
+    hookSource, int registringObjectsPriority, int registringObjectsType)
+{
+    if (hookid==H_HOOK_MOVE)
+      return 0;
+
+    return 1;
+}
+status HookCancelAllowanceCallback(object cancellingObject, int hookid, object
+    hookSource, int cancellingObjectsPriority, mixed hookData)
+{
+    if (hookid==H_HOOK_MOVE && cancellingObject != this_object()
+        && present(hookSource,this_object()))
+      return 0;
+
+    return 1;
+}
+
+status HookModificationAllowanceCallback(object modifyingObject, int hookid,
+    object hookSource, int modifyingObjectsPriority, mixed hookData)
+{
+    if (hookid==H_HOOK_MOVE && modifyingObject != this_object()
+        && present(hookSource,this_object()))
+      return 0;
+
+    return 1;
+}
+
+mixed HookCallback(object hookSource, int hookid, mixed hookData)
+{
+  // nur move hooks sind interessant hier.
+  if (hookid != H_HOOK_MOVE)
+    return ({H_NO_MOD, hookData});
+
+  // das duerfte eigentlich nicht vorkommen, da der Hook im exit() geloescht
+  // wird...
+  if (environment(hookSource) != this_object()) {
+    hookSource->HUnregisterFromHook(H_HOOK_MOVE,this_object());
+    return ({H_NO_MOD, hookData});
+  }
+
+  // Bewegungen in den Netztotenraum sind ok.
+  if (!interactive(hookSource)
+      && pointerp(hookData) && sizeof(hookData) >= 1)
+  {
+    if ((objectp(hookData[0])
+          && object_name(hookData[0]) == "/room/netztot")
+        || (stringp(hookData[0]) && hookData[0]=="/room/netztot")
+        )
+    {
+      return ({H_NO_MOD, hookData});
+    }
+  }
+
+  // Deputy (oder hoeher), kein process_call(). Sonst wird die Bewegung
+  // abgebrochen.
+  if (!this_interactive() || !IS_DEPUTY(this_interactive()))
+  {
+      return ({H_CANCELLED, hookData});
+  }
+
+  return ({H_NO_MOD, hookData});
+}
+
+// wenn hier jemand durch Zerstoerung des Objektes rauskommen will, geht das
+// schief.
+varargs void NotifyRemove(object ob) {
+  if (objectp(ob) && query_once_interactive(ob) && !IS_DEPUTY(ob))
+  {
+    ob->SetProp(P_START_HOME,"/room/jail");
+    ob->save_me(0);
+  }
+}
+
diff --git a/room/muellraum.c b/room/muellraum.c
new file mode 100644
index 0000000..21c4d22
--- /dev/null
+++ b/room/muellraum.c
@@ -0,0 +1,67 @@
+inherit "std/room";
+#include <properties.h>
+#include <wizlevels.h>
+
+void create()
+{
+  ::create();
+  SetProp(P_LIGHT, 1 );
+  SetProp(P_INT_SHORT, "Der Muellraum" );
+  SetProp(P_INDOORS, 1);
+  SetProp(P_NEVER_CLEAN, 1);
+  SetProp(P_INT_LONG,break_string(
+    "Dieser Raum ist vollkommen leer und anscheinend riiiiiiesig gross. "
+    "Du kannst seine Aussmasse nichtmals abschaetzen. Naja. Muss wohl auch "
+    "so sein, denn hier kommen alle Clones rein, die einige Sekunden "
+    "nach ihrer Erstellung noch kein Zuhause (Environment) gefunden haben. "
+    "Wenn Du das magische Kommando 'welt' gibst, wirst Du wieder in Deine Welt\n"
+    "zurueckversetzt werden."));
+  AddExit("welt", "/gilden/abenteurer");
+}
+
+// rekursiv zerstoeren
+private void rec_remove(object ob) {
+  object *inv=all_inventory(ob);
+  if (sizeof(inv)) {
+    filter(inv, #'rec_remove);
+  }
+  ob->remove(1);
+  if (objectp(ob)) destruct(ob);
+}
+
+int clean_me() {
+  object *inv=all_inventory(this_object());
+  int isize=sizeof(inv);
+  if (isize>100) {
+    //aeltestes Objekt, was kein Spieler ist, zerstoeren. Pruefung auf Spieler
+    //ist Paranoia, eigentlich sollte hier nie einer hinkommen koennen, ausser
+    //magier, und um die waers dann nicht schade. *g*
+    for (isize--; isize--; ) {
+      if (!query_once_interactive(inv[isize])) {
+	rec_remove(inv[isize]);
+	return(1);
+      }
+    }
+  }
+  return 0;
+}
+
+varargs int PreventInsert(object pl) {
+
+  if (!objectp(pl))
+    return 1;
+  clean_me();
+  return 0;
+}
+
+varargs int PreventInsertLiving(object pl) {
+
+  // keine Spieler. ;-)
+  if (!objectp(pl) || 
+      (query_once_interactive(pl) && !IS_LEARNER(pl)))
+    return 1;
+
+  clean_me();
+  return 0;
+}
+
diff --git a/room/netztot.c b/room/netztot.c
new file mode 100644
index 0000000..341c46b
--- /dev/null
+++ b/room/netztot.c
@@ -0,0 +1,92 @@
+// MorgenGrauen MUDlib
+//
+// $Id: netztot.c 8747 2014-04-26 13:08:47Z Zesstra $
+
+#include <wizlevels.h>
+#include <moving.h>
+
+create()
+{
+  call_out("invcheck",120);
+  "/obj/sperrer"->NixGibts();
+}
+
+weg(ob)
+{
+  if (!objectp(ob))
+    return;
+  ob->remove();
+  if (ob)
+    destruct(ob);
+}
+
+wegraeumen(ob)
+{
+  object *x;
+  
+  if (!objectp(ob))
+    return;
+  for (x=deep_inventory(ob);sizeof(x);x=x[1..])
+    weg(x[0]);
+  ob->move("/room/void",M_NOCHECK|M_SILENT);
+  weg(ob);
+}
+
+invcheck()
+{ 
+  while(remove_call_out("invcheck")!=-1);
+  foreach(object ob: all_inventory(this_object()))
+  {
+    if (interactive(ob))
+    {
+      catch(this_player()->move("/room/void",M_GO));
+      set_object_heart_beat(ob,1);
+    }
+    else if (!query_once_interactive(ob) && object_name(ob)!="/obj/sperrer")
+      call_out("wegraeumen",1,ob);
+  }
+  call_out("invcheck",120);
+  "/obj/sperrer"->upd();
+}
+
+init()
+{
+  if (!this_player())
+    return;
+  catch(this_player()->StopHuntingMode());
+  if (interactive(this_player()))
+    catch(this_player()->move("/room/void",M_GO));
+  if (!query_once_interactive(this_player()))
+  {
+    this_player()->remove();
+    if(this_player())
+      destruct(this_player());
+  }
+  set_object_heart_beat(this_player(),0);
+}
+
+int_long()
+{
+  return "Dies ist der Netztotenraum. Es ist dunkel. Du siehst nichts.\n";
+}
+
+int_short()
+{
+  return "Nichts zu sehen.\n";
+}
+
+QueryProp(string str)
+{
+  switch (str) {
+    case "int_long": return int_long();
+    case "int_short": return int_short();
+  }
+}
+
+// Nicht jeder Magier darf den Netztotenraum entsorgen.
+string NotifyDestruct(object caller) {
+    if( (caller!=this_object() && !ARCH_SECURITY) || process_call() ) {
+      return "Du darfst den Netztotenraum nicht zerstoeren!\n";
+    }
+}
+
diff --git a/room/nirvana.c b/room/nirvana.c
new file mode 100644
index 0000000..ea66074
--- /dev/null
+++ b/room/nirvana.c
@@ -0,0 +1,132 @@
+#include <properties.h>
+#include <moving.h>
+
+inherit "std/room";
+
+create() {
+  ::create();
+  SetProp(P_INDOORS, 1);
+  SetProp(P_LIGHT,1);
+  SetProp(P_INT_LONG,
+"Du befindest Dich im Nirvana!\n"+
+"Es sieht anders aus als Du es Dir vorgestellt hast. Eine riesige Halle \n"+
+"mit Waenden aus Nebel, einem Boden aus Wasser und einer Decke aus Feuer\n"+
+"bildet das Heim der ewig Verstorbenen.\n"+
+"Stille herrscht hier. Grosse Stille. STILLE sozusagen.\n"+
+"Rauch durchzieht die Luft. Er entspringt einer Raeucherschale, welche auf\n"+
+"einem riesigen Altar mitten im Nirvana steht.\n"+
+"Du bist nun wohl wirklich tot.\n");
+  SetProp(P_INT_SHORT,"Im Nirvana");
+  SetProp(P_NO_TPORT,NO_TPORT);
+  SetProp(P_NO_PARA_TRANS);
+  
+  AddDetail("altar",
+"Der Altar der verzweifelten Toten. Er besteht vollstaendig aus grinsenden "+
+"Totenschaedeln und bietet keinerlei Hoffnung.\nEine Raeucherschale steht auf dem Altar.\n");
+
+  AddDetail(({"tote","toten","verstorbene"}),
+"Dies hier ist das Heim der Toten.\nDu wohnst hier.\n");
+
+  AddDetail(({"hoffnung"}),
+"HAHA, KEINE HOFFNUNG!\n");
+
+  AddDetail(({"schaedel","totenschaedel"}),
+"Sie grinsen Dich haemisch an als wollten sie dich verspotten.\n"+
+"Auf einem Schadel erkennst Du eine Inschrift.\n");
+
+  AddDetail(({"inschrift"}),
+"Du kannst sie lesen.\n");
+
+  AddReadDetail(({"inschrift"}),
+"DIES IST KEIN APRILSCHERZ.\n");
+
+  AddDetail(({"schale","raeucherschale"}),
+"Aus der Schale entsteigt dunkler Rauch, der die Luft unheilvoll schwaengert.\n");
+
+
+  AddDetail(({"luft"}),
+"Luft war einmal lebensnotwendig. Du brauchst sie nicht mehr.\n");
+
+  AddDetail(({"rauch"}),
+"Der Rauch verdunkelt die Luft. Er wuerde jeden Lebenden ersticken, aber das schreckt Dich nicht mehr.\n");
+
+  AddDetail(({"stille"}),
+"Sie hoert sich irgendwie tot und endgueltig an.\n");
+
+  AddDetail(({"nirvana","raum"}),
+"Schau Dich nur um.\n");
+
+  AddDetail(({"lebende"}),
+"Zu denen gehoerst Du nicht mehr.\n");
+
+  AddDetail(({"nebel"}),
+"Der Nebel begrenzt das Nirvana seitlich. Er formt die Waende.\n");
+
+  AddDetail(({"wasser"}),
+"Der Boden des Nirvanas scheint aus Wasser zu bestehen. Du bist tot und gehst daher nicht unter.\n");
+
+  AddDetail(({"feuer"}),
+"Die Decke des Nirvanas lodert Dir feurig entgegen. Waerest Du am Leben, wuerde Dich das beunruhigen.\n");
+
+  AddDetail(({"halle"}),
+"Die Halle der Toten. Das Nirvana.\n");
+
+  AddDetail(({"heim"}),
+"Das Heim der Toten ist das Nirvana. Dein Heim.\n");
+
+
+  AddDetail(({"boden"}),
+"Der Boden wabert unter Dir. Manchmal meinst Du das Gesicht Jofs zu erkennen.\n");
+
+  AddDetail(({"gesicht"}),
+"Gesichter sind fuer Dich nicht mehr wichtig.\n");
+
+  AddDetail(({"jof"}),
+"Er schlaeft.\n");
+
+
+  AddDetail(({"decke"}),
+"Die Decke lodert Dir entgegen. Abundzu meinst Du Rumata zu erkennen.\n");
+
+  AddDetail(({"rumata"}),
+"Er ist wohl doch nicht da. Niemand wird Dir helfen. Es ist aus.\n");
+
+  AddDetail(({"wand","waende"}),
+"Der Nebel wabert auf und ab. Manchmal scheint es so, als wandere Zook durch den Nebel.\n");
+
+
+  AddDetail(({"zook"}),
+"Er grinst Dich an. Das ist wohl das Ende der Hoffnung.\nWeit hinter Zook erkennst Du eine weitere Gestalt.\n");
+
+  AddDetail(({"gestalt"}),
+"Es scheint sich um Boing zu handeln.\n");
+
+  AddDetail(({"boing"}),
+"Boing schaut Dich traurig an.\n");
+
+
+  AddDetail(({"ende"}),
+"Du hast Dein Ende erreicht. Du bist tot.\n");
+
+  AddDetail(({"leben"}),
+"Dein Leben ist zu Ende. Du bist tot.\n");
+
+  AddCmd("bete","bete");
+  AddItem("/obj/zeitungsautomat", REFRESH_REMOVE);
+}
+
+bete() {
+  write("Du haeltst eine kurze Andacht.\n");
+  if (this_player()->QueryProp(P_GHOST) && this_player()->query_hc_play()>1) {
+	write("Eine sehr starke Kraft saugt Dich auf und spuckt Dich wieder aus.\nEs scheint sich aber nichts veraendert zu haben.\n");
+	say(this_player()->name()+" erscheint nicht in koerperlicher Form.\n");
+	this_player()->SetProp(P_GHOST,0);
+  }
+  else
+  {
+        write("Fuer Dich ist dieser Altar nicht gedacht!\n");
+  }
+  return 1;
+}
+
+
diff --git a/room/noscript.c b/room/noscript.c
new file mode 100644
index 0000000..fcff28e
--- /dev/null
+++ b/room/noscript.c
@@ -0,0 +1,42 @@
+inherit "/std/room";
+#include <properties.h>
+#include <moving.h>
+
+static string x;
+static string *xx;
+
+void create() {
+  ::create();
+  x="----------";
+  xx=({
+    "/d/ebene/room/ak_str7",
+    "/d/ebene/room/dra_str3",
+    "/d/ebene/room/hp_str2c",
+    "/d/ebene/room/o_wa1d",
+    "/d/ebene/room/waldweg8"
+  });
+  SetProp(P_LIGHT,1);
+  SetProp(P_INT_LONG,
+"Dieser Raum ist fuer Leute, die TF spielen lassen.\n\
+Es gibt nur einen Weg heraus...\n");
+  AddCmd("","raus",1);
+}
+
+void init() {
+  int i;
+  
+  ::init();
+  for (i=0;i<10;i++)
+    x[i]='a'+random(26);
+}
+
+varargs string GetExits(object viewer) {
+  return sprintf("Es gibt einen sichtbaren Ausgang: %s.\n",x);
+}
+
+varargs int raus(string s) {
+  if (query_verb()!=x)
+    return 0;
+  notify_fail("Etwas hat nicht funktioniert. Bitte verstaendige einen Magier.\n");
+  return ((this_player()->move(xx[random(sizeof(xx))],M_GO))>0);
+}
diff --git a/room/nowhere.c b/room/nowhere.c
new file mode 100644
index 0000000..af55f2b
--- /dev/null
+++ b/room/nowhere.c
@@ -0,0 +1,28 @@
+inherit "std/room";
+#include <properties.h>
+#include <moving.h>
+#include <wizlevels.h>
+
+void create()
+{
+  ::create();
+  SetProp(P_LIGHT, 1 );
+  SetProp(P_INT_SHORT, "Bei den inaktiven Spielern :)" );
+  SetProp(P_INT_LONG,
+    "Hier ist absolut nichts zu sehen, die, die sich hier normalerweise\n"
+   +"aufhalten, sind eh noninteractive...\n");
+  AddCmd( "", "onlywelt", 1 );
+}
+
+int onlywelt( string s ) {
+  if( query_verb()=="welt" ) {
+    this_player()->move("/gilden/abenteurer", M_TPORT);
+    return 1;
+  }
+  if( IS_LEARNER(this_player()) ) return 0;
+  write(
+   "Wenn Du das magische Kommando 'welt' gibst, wirst Du wieder in Deine Welt\n"
+   +"zurueckversetzt werden.\n"
+  );
+  return 1;
+}
diff --git a/room/orakel.c b/room/orakel.c
new file mode 100644
index 0000000..4da1508
--- /dev/null
+++ b/room/orakel.c
@@ -0,0 +1,231 @@
+// MorgenGrauen MUDlib
+//
+// orakel.c -- Der Raum, in dem man sich neue ZT-Sprueche holen kann
+//
+// $Id: orakel.c 9371 2015-10-22 19:01:48Z Zesstra $
+
+#define TIPS(x) "/secure/ARCH/ZT/"+x
+
+#define POTIONMASTER "/secure/potionmaster"
+
+inherit "/std/room";
+
+#include <properties.h>
+
+// WANNWIEVIEL zeigt an, mit wieviel Stufenpunkten man wieviele Zaubertraenke
+// haben kann, so ist zum Beispiel an fuenfter Stelle die Zahl 25 einge-
+// tragen, also kann man mit 25 Stufenpunkten 5 Zaubertraenke bekommen.
+#define WANNWIEVIEL ({ 0, 0, 0, 0,\
+   25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325, 350, 375,\
+   400, 425, 450, 475, 500, 525, 550, 575, 600, 625, 650, 675, 700, 725,\
+   750,\
+   790, 830, 870, 910, 950, 990, 1030, 1070, 1110, 1150, 1190, 1230, 1270,\
+   1310, 1350, 1390, 1430, 1470, 1510, 1550, 1590, 1630, 1670, 1710, 1750,\
+   1790,\
+   1860, 1930, 2000, 2070, 2140, 2210, 2280, 2350, 2420, 2490,\
+   2590, 2690, 2790, 2890, 2990, 3090, 3190, 3290, 3390, 3490 })
+#define KEINTIPTEXT "Der Nebel ueber der Kugel ruehrt sich nicht.\n"
+
+
+
+protected void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 1);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Das heilige Orakel von Tingan");
+   SetProp(P_INT_LONG,
+   "Du befindest Dich in einer mittelgrossen Hoehle, die sich halbkugel-\n"+
+   "foermig ueber Deinem Kopf erhebt. Die Hoehle wird fast komplett vom\n"+
+   "gruenlich schimmernden Quellsee des Osterbachs ausgefuellt. Ueber dem\n"+
+   "See schwebt eingehuellt in langsam ziehende Nebelschwaden eine magisch\n"+
+   "leuchtende Kugel, das heilige Orakel von Tingan. Im Osten fliesst das\n"+
+   "Wasser des Sees durch einen schmalen Gang ab, dem Du folgen koenntest.\n");
+   AddDetail("boden", "Der Boden ist groesstenteils mit Wasser bedeckt.\n");
+   AddDetail("decke", "Die Decke ist aus massivem Felsgestein, Du willst gar nicht wissen,\nwieviele Tonnen davon ueber Deinem Kopf lasten.\n");
+   AddDetail(({"fels", "gestein", "felsgestein"}), "Sowas ist im Gebirge recht haeufig.\n");
+   AddDetail(({"wand", "waende"}), "Die Waende sind feucht.\n");
+   AddDetail(({"quellsee", "see"}), "Er ist die Quelle des Osterbachs.\n");
+   AddDetail("quelle", "Das heisst, der Bach entspringt hier.\n");
+   AddDetail(({"bach", "osterbach"}), "Er fliesst nach Osten ab.\n");
+   AddDetail("wasser", "Es ist klar und frisch.\n");
+   AddDetail("gang", "Er fuehrt nach Osten.\n");
+   AddDetail("orakel", "Du fuehlst grosses Wissen in Deiner Umgebung.\n");
+   AddDetail("umgebung", "Die Umgebung ist das, was Dich umgibt.\n");
+   AddDetail("wissen", "Vielleicht nuetzt es Dir ja was.\n");
+   AddDetail(({"nebel", "schwaden", "nebelschwaden"}), "Sie ziehen langsam ueber den See.\n");
+   AddDetail("kugel", "Die Kugel leuchtet in magischem Licht und laedt Dich fast zum Meditieren ein.\n");
+   AddDetail("licht", "Magisches Licht erhellt den Raum.\n");
+   AddDetail("raum", "Schau Dich einfach mal um.\n");
+   AddDetail("hoehle", "Du befindest Dich tatsaechlich in einer Hoehle.\n");
+   AddDetail("kopf", "Das anzuschauen duerfte Dir schwer fallen.\n");
+   AddCmd(({"trink", "trinke"}), "trinken");
+   AddCmd("meditiere", "meditieren");
+   AddCmd(({"wirf", "werfe"}), "werfen");
+   AddExit("osten", "/players/boing/orakel/organg2");
+}
+
+// Es wird berechnet ob der Spieler einen neuen Tip bekommen kann.
+int NeuerTip()
+{
+   mapping platt;   // Attributmapping des Spielers
+   int	   summe;   // Summe der Attribute des Spielers + der noch zu findenen
+		    // aber bekannten Zaubertrankstellen
+   int	   sps;     // Stufenpunkte des Spielers
+
+   platt  = this_player()->QueryProp(P_ATTRIBUTES);
+   summe  = (int)platt["int"] + (int)platt["con"] + 
+	    (int)platt["dex"] + (int)platt["str"] - 4; 
+   summe  += sizeof(this_player()->QueryProp(P_KNOWN_POTIONROOMS));
+   sps	  = this_player()->QueryProp(P_LEP);
+
+// Wenn genug Stufenpunkte da sind, dann wird 1 zurueckgegeben, sonst 0
+  if (summe>79)
+    return 0;
+  if (sps > WANNWIEVIEL[summe])
+    return 1;
+   return 0;
+}
+
+// Gibt die Nummer des ausgewaehlten Zaubertranks zurueck oder 0, wenn keiner
+// mehr uebrig ist.
+int ZTAuswahl()
+{
+   int* pllist;
+   int	pllsize;
+   int i;
+   mixed sorted_list; // ({ ({liste1}), ({liste2}), ..., ({liste8}) })
+
+// Initialisierung
+   sorted_list = ({ ({ }), ({ }), ({ }), ({ }), ({ }), ({ }), ({ }), ({ }) });
+   pllist      = this_player()->QueryProp(P_POTIONROOMS);
+   pllsize     = sizeof(pllist);
+
+// Zaubertraenke werden gemaess ihrer Liste in den neuen Array eingetragen.
+   for (i=0; i<pllsize; i++)
+      sorted_list[POTIONMASTER->GetListByNumber(pllist[i])] += ({ pllist[i] });
+
+// Alle Unterarrays werden aneinandergehaengt.
+   pllist = ({ });
+   for (i=0; i<8; i++)
+      pllist += sorted_list[i];
+   pllist -= this_player()->QueryProp(P_KNOWN_POTIONROOMS);
+
+// Jetzt sind alle Zaubertraenke wieder in der Liste, sortiert nach dem
+// Schwierigkeitsgrad, bis auf die Zaubertraenke, die der Spieler bereits
+// kennt (d.h. wo er schon den Tip bekommen hat, sie aber noch nicht
+// gefunden hat).
+
+
+// Einer der leichtesten Zaubertraenke wird ausgewaehlt und zurueckgegeben.
+   pllsize = sizeof(pllist);
+   if (!pllsize)
+      return -1;
+   if (pllsize>10)
+      return pllist[random(10)];
+   else
+      return pllist[random(pllsize)];
+}
+
+
+string Vision()
+{
+  int	  nr;
+  string* text;
+  int*	  liste;
+
+  if (!NeuerTip())
+    return KEINTIPTEXT + "Du hast wahrscheinlich zu wenig Stufenpunkte.\n";
+
+  nr = ZTAuswahl();
+  if (nr == -1)
+    return KEINTIPTEXT + "Du hast schon alle Zaubertraenke gefunden.\n";
+
+  text = POTIONMASTER->TipLesen(nr);
+// Das Folgende kann passieren, wenn entweder die Datei zu einem ZT nicht
+// existiert oder das Einlesen sonstwie fehlschlaegt. Zur Behebung des
+// Fehlers sollte man sich als erstes die Datei <nr>.zt anschauen.
+  if (intp(text) || !sizeof(text)) 
+    return 
+  "Ploetzlich wird es totenstill im Raum, die Nebelschwaden beginnen sich\n"+
+  "um die Kugel zu drehen. Immer schneller wird der wirbelnde Tanz, bis\n"+
+  "sich das Ganze unmerklich zu einer Schrift formt:\n"+
+  "   Fehler im Raum-Zeit-Gefuege, bitte wende Dich an Rikus\n"+
+  "   und melde ihm die Zahl '"+nr+"'!\n"+
+  "Dann zerfliesst der Nebel und alles ist beim Alten.\n";
+
+  liste = this_player()->QueryProp(P_KNOWN_POTIONROOMS);
+  this_player()->AddKnownPotion(nr);
+
+//bis nach Reboot noetig!!! Rikus
+//  "/players/boing/orakel/orakel"->AddKnownPotion(nr);
+
+  return "Der Nebel ueber der Kugel beginnt sich zu bewegen, dann hoerst Du eine\ntiefe Stimme in Deinem Kopf erklingen:\n\n"+text[random(sizeof(text))];
+}
+
+string TipListe()
+{
+  int*	  pll;
+  string* tip;
+  string  ret;
+  int	  plsize, i;
+
+  ret	 = "";
+  pll	 = this_interactive()->QueryProp(P_KNOWN_POTIONROOMS);
+  plsize = sizeof(pll);
+
+  for (i=0; i<plsize; i++)
+  {
+    tip = POTIONMASTER->TipLesen(pll[i]);
+    if (sizeof(tip))
+    {
+      ret += tip[random(sizeof(tip))];
+      ret += "--------------------------------------------------------------------------\n";
+    }
+  }
+
+  if (ret=="")
+    return "Du kennst momentan keine Tips zu Zaubertraenken.\n";
+  else
+    return "--------------------------------------------------------------------------\n"+ret;
+}
+
+int trinken(string str)
+{
+  notify_fail("Was moechtest Du trinken?\n");
+  if (!str || str=="") return 0;
+  notify_fail("Das kannst Du hier nicht trinken!\n");
+  if (str!="wasser")
+    return 0;
+  write("Du trinkst einen Schluck Quellwasser und fuehlst Dich koestlich erfrischt.\n");
+  return 1;
+}
+
+meditieren()
+{
+  write(
+  "Du sammelst Deine geistigen Kraefte und verfaellst schon schnell in einen\n"+
+  "tranceartigen Zustand. Eine Vision eines Helden, der eine Muenze in den\n"+
+  "See wirft erscheint vor Deinen Augen, verschwindet aber schon schnell\n"+
+  "wieder. Als Du wieder aufwachst, ist alles wie vorher.\n");
+  return 1;
+}
+
+int werfen(string str)
+{
+  if (str=="muenze in see" || str=="muenze in wasser" ||
+      str=="muenze in quellsee")
+  {
+    if (this_player()->QueryMoney()<1)
+    {
+      write("Du hast keine Muenze.\n");
+      return 1;
+    }
+    this_player()->AddMoney(-1);
+    write("Du wirfst eine Muenze ins Wasser.\n");
+    say(capitalize(this_player()->name())+" wirft eine Muenze ins Wasser.\n");
+    write(Vision());
+    return 1;
+  }
+  return 0;
+}
diff --git a/room/post.c b/room/post.c
new file mode 100644
index 0000000..34117de
--- /dev/null
+++ b/room/post.c
@@ -0,0 +1,12 @@
+inherit "/std/post";
+#include <properties.h>
+
+create()
+{
+	::create();
+        AddExit("osten","/gilden/abenteurer");
+	SetProp(P_INT_LONG,"Dies ist das Hauptpostamt von MorgenGrauen.\n"+
+               "Von hier aus kannst Du Briefe an Deine Mitspieler schicken und Briefe von\n"+
+               "ihnen lesen. Wenn Du das willst, tippe \"post\".\n"+
+               "Der einzige sichtbare Ausgang fuehrt nach Osten in die Gilde.\n");
+}             
diff --git a/room/pray_room.c b/room/pray_room.c
new file mode 100644
index 0000000..c056d22
--- /dev/null
+++ b/room/pray_room.c
@@ -0,0 +1,37 @@
+inherit "std/room";
+
+#include <properties.h>
+
+void create()
+{
+	::create();
+	SetProp(P_LIGHT,1);
+	SetProp(P_INT_LONG,
+   "Du befindest Dich in einer kleinen Kapelle, in der Du beten kannst, um\n"+
+   "wieder Deine natuerliche Gestalt zu erhalten. Am suedlichen Ende steht\n"+
+   "ein Altar, auf dem sich ein grosses Kreuz befindet. In den Waenden siehst\n"+
+   "Du herrliche Fenster, durch die tagsueber das Licht bunt hereinscheint.\n"+
+   "Im Norden befindet sich eine Tuer, die zur Gilde fuehrt.\n");
+  SetProp(P_INT_SHORT,"Kapelle");
+  AddDetail("altar", "Er ist aus Stein und nicht besonders schoen.\n");
+  AddDetail("kreuz", "Ein schlichtes Holzkreuz.\n");
+  AddDetail("fenster", "Die Fenster sind wunderschoen.\n");
+  AddDetail(({"wand", "waende"}), "An den Waenden siehst Du nichts besonderes.\n");
+  AddCmd("bete","bete");
+  AddExit("norden","/gilden/abenteurer");
+}
+
+static int bete() {
+   if (this_player()->QueryProp(P_GHOST))
+   {
+        write("Du haeltst eine kurze Andacht.\n");
+	write("Eine sehr starke Kraft saugt Dich auf und spuckt Dich wieder aus.\n");
+	say(this_player()->name()+" erscheint in koerperlicher Form.\n");
+	this_player()->SetProp(P_GHOST,0);
+	return 1;
+   }
+   notify_fail("Du haeltst eine kurze Andacht.\n");
+   return 0;
+}
+
+
diff --git a/room/pub2.c b/room/pub2.c
new file mode 100644
index 0000000..bf51144
--- /dev/null
+++ b/room/pub2.c
@@ -0,0 +1,44 @@
+inherit "/std/pub";
+#include <rooms.h>
+#include <properties.h>
+
+create(){
+   replace_program("std/pub.c");
+   ::create();
+
+   AddDrink("Bier nach dem Reinheitsgebot","bier",12,0,2,1,
+            ({"Der Kellner bringt Dein Bier. Du fuehlst Dich gut.",
+              "&& trinkt ein eiskaltes Bier."}));
+
+   AddDrink("Franks Spezial-Schnaps",
+            ({"schnaps","spezial","spezial-schnaps"}),
+            50,10,8,0,
+            ({"Der Kellner bringt Deinen Schnaps.\n"+
+              "Du fuehlst ein Kribbeln im ganzen Koerper.",
+              "&& schuettet einen Spezial-Schnaps herunter."}));
+
+   AddDrink("Ein beruehmter Rachenputzer",({"putzer","rachenputzer"}),
+            150,25,12,0,
+            ({"Du bekommst Deinen weltberuehmten Rachenputzer.\n"+
+              "Eine Schockwelle rast mit der Gewalt eines Baseball-Schlaegers durch\n"+
+              "Deinen Koerper und trifft mit voller Wucht Dein Gehirn.",
+              "&& torkelt, als &! einen Rachenputzer saeuft."}));
+
+   AddDrink("Eine Tasse Kaffee",({"kaffee","tasse","tasse kaffee"}),
+            20,0,-2,3,
+            ({"Baeh! Schmeckt ja widerlich!",
+              "&& verzieht angewidert das Gesicht, als &! einen Kaffee schluckt."}));
+
+   AddExit("westen","room/gilde");
+
+   SetProp(P_INT_SHORT,"Franks Abenteurer-Kneipe");
+   SetProp(P_INT_LONG,"Du bist in Franks Abenteurer-Kneipe.\n"+
+               "Wie immer ist hier mal wieder die Hoelle los. Flaschen und Glaeser\n"+
+               "fliegen durch den Raum, und du musst aufpassen, dass Du nicht in\n"+
+               "die Schlaegerei zwischen einem Kerl, der aussieht wie Sylvester\n"+
+               "Stallone und einem auch nicht gerade harmlosen Zauberer hinein-\n"+
+               "gezogen wirst.\n\n"+
+               "Wenn Du wissen willst, was Du hier trinken kannst, tippe: 'menue'.\n");	
+   SetProp(P_LIGHT,1);
+}
+
diff --git a/room/treff.c b/room/treff.c
new file mode 100644
index 0000000..17d0be8
--- /dev/null
+++ b/room/treff.c
@@ -0,0 +1,40 @@
+#include <properties.h>
+#include <rooms.h>
+#include <wizlevels.h>
+#include <language.h>
+inherit "/std/room";
+create(){
+   ::create();
+   SetProp(P_INT_SHORT,"Das juengste Geruecht");
+   SetProp(P_INT_LONG,
+	   "Dies ist ein Raum, den die Spieler gerne und oft als \n"
+	   +"'das juengste Geruecht' bezeichnen. Hier werden naem-\n"
+	   +"lich wichtige Entscheidungen im Morgengrauen disku-\n"
+	   +"tiert und beschlossen. Demzufolge ist dies ein reiner\n"
+	   +"Magierraum. Man kann sich hier treffen, reden oder\n"
+	   +"einfach herumidlen.\n");
+   AddExit("unten", "/gilden/abenteurer");
+   SetProp(P_LIGHT,100);
+   SetProp(P_INDOORS,1);
+}
+
+exit() // War schon oefter so, das Magier hier walking monsters erzeugt
+       // haben, die dann in die Gilde gehopst sind ... die exits
+			 // zu sperren hat auch keinen Sinn - Sirs MNPC moved sich dann
+			 // doch an seinen Startpunkt. Naja, machen wir es eben SO - Monster
+			 // haben hier eh nix verloren.
+{
+	object tp;
+
+	tp=previous_object();
+	if (!query_once_interactive(tp))
+		call_out("do_destruct",1,tp);
+}
+
+do_destruct(ob)
+{
+	if (ob)
+	  ob->remove();
+	if (ob)
+		destruct(ob);
+}
diff --git a/room/void.c b/room/void.c
new file mode 100644
index 0000000..061e62a
--- /dev/null
+++ b/room/void.c
@@ -0,0 +1,51 @@
+inherit "std/room";
+#include <properties.h>
+#include <moving.h>
+#include <wizlevels.h>
+
+void create()
+{
+  ::create();
+  SetProp(P_LIGHT, 1 );
+  SetProp(P_INT_SHORT, "Das Nichts" );
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_LONG,
+    "Du schwebst im absoluten, ewigen und leeren Nichts umher. Hier kommen\n"
+   +"all die hin, deren Welt, in der sie sich befanden, zerstoert worden ist.\n"
+   +"Wenn Du das magische Kommando 'welt' gibst, wirst Du wieder in Deine Welt\n"
+   +"zurueckversetzt werden.\n"
+  );
+  AddCmd( "", "onlywelt", 1 );
+}
+
+int onlywelt( string s ) {
+  if( query_verb()=="welt" ) {
+    this_player()->move("/gilden/abenteurer", M_TPORT);
+    return 1;
+  }
+  if( IS_LEARNER(this_player()) ) return 0;
+  write(
+    "Du schwebst im absoluten, ewigen und leerem Nichts umher. Hier kommen\n"
+   +"all die hin, deren Welt, in der sie sich befanden, zerstoert worden ist.\n"
+   +"Wenn Du das magische Kommando 'welt' gibst, wirst Du wieder in Deine Welt\n"
+   +"zurueckversetzt werden.\n"
+  );
+  return 1;
+}
+
+
+// Sonst zerstoert sich das Void brav selbst - an NotifyDestruct vorbei. 
+public varargs int remove()
+{
+  if (!ARCH_SECURITY || process_call())
+    return 0;
+  return ::remove();
+}
+
+// Nicht jeder Magier muss das Void entsorgen koennen.
+string NotifyDestruct(object caller) {
+    if( (caller!=this_object() && !ARCH_SECURITY) || process_call() ) {
+      return "Du darfst das Void nicht zerstoeren!\n";
+    }
+}
+
diff --git a/room/welcome/std.c b/room/welcome/std.c
new file mode 100644
index 0000000..eae3cee
--- /dev/null
+++ b/room/welcome/std.c
@@ -0,0 +1,151 @@
+#include <properties.h>
+#include <moving.h>
+#include <defines.h>
+
+inherit  "/std/room";
+
+#pragma strong_types
+#pragma rtt_checks
+#pragma no_shadow
+#pragma no_inherit
+#pragma pedantic
+#pragma range_check
+
+#define BS(x) break_string(x, 78, 0, BS_LEAVE_MY_LFS|BS_SINGLE_SPACE)
+#define TUTSTART "/d/anfaenger/arathorn/minitut/room/huette_"
+
+void create() {
+  ::create();
+
+  SetProp(P_LIGHT,1);
+  SetProp(P_LIGHT_TYPE, LT_STARS|LT_MOON);
+  SetProp(P_MAP_RESTRICTIONS, MR_NOUID|MR_NOINFO);
+  SetProp(P_INDOORS,0);
+  SetProp(P_NO_TPORT, NO_TPORT);
+
+  SetProp(P_INT_SHORT, "Irgendwo im Nirgendwo");
+  SetProp(P_INT_LONG, BS(
+    "Du schwebst im Nirgendwo. Sterne umgeben Dich, und Du glaubst "
+    "zu fallen, obwohl Du Dich vollkommen schwerelos fuehlst. Ein hauch"
+    "duenner Schleier aus Staub umfaengt Dich, als Du langsam aber sicher "
+    "Deines Koerpers gewahr wirst."));
+  AddSpecialExit("welt", function int () {
+    if ( PL->QueryGuest() ) 
+      return PL->move("/gilden/abenteurer", M_GO);
+    else return 0; 
+  });
+  Set(P_HIDE_EXITS, function mixed () {
+    return !(PL && PL->QueryGuest());
+  }, F_QUERY_METHOD);
+}
+
+void init() {
+  set_next_reset(300);
+  if ( objectp(PL) )
+    call_out("Sequenz", 0, 0);
+  return ::init();
+}
+
+// Nix resetten, aber Raum entsorgen, wenn kein Spieler drin.
+// Notfalls gibt es auch noch nen cleanup() aus dem Standardraum...
+protected void reset() {
+  if (!sizeof(filter(all_inventory(this_object()), #'query_once_interactive))
+      )
+    remove(1);
+}
+
+//TODO: Delays anpassen bzw. ausklammern, wenn immer =5 ausser am Ende.
+void Sequenz(int count) {
+  int delay;
+
+  if ( !objectp(PL) || environment(PL) != ME )
+    return;
+
+  switch(count) {
+    case 0:
+      tell_object(PL, BS(QueryProp(P_INT_LONG)));
+      delay = 4;
+      break;
+    case 1:
+      tell_object(PL, BS(
+        "\nDu schaust Dich erstaunt um. Du befindest Dich anscheinend im "
+        "Weltall, aber wie bist Du hierhergekommen? Ist das schon das "
+        "MorgenGrauen, oder bist Du wohl erst noch auf dem Weg dorthin?"));
+      delay = 8;
+      break;
+    case 2:
+      tell_object(PL, BS(
+        "\nMit einem Blick auf Deine Umgebung bemerkst Du, dass der Staub, "
+        "der Dich umgibt, sich langsam auf Dich zuzubewegen scheint. "
+        "Du willst neugierig danach greifen, aber es will Dir nicht "
+        "gelingen. Verwundert stellst Du fest, dass Du keine Haende "
+        "besitzt, und bei naeherer Betrachtung wird Dir klar, dass Du "
+        "auch sonst noch ziemlich koerperlos bist! "));
+      delay = 12;
+      break;
+    case 3:
+      tell_object(PL, BS(
+        "\nDas aendert sich aber bald, als der glitzernde Staub allmaehlich "
+        "um Dich herum eine durchscheinende Gestalt zu bilden beginnt, "
+        "die sich zuegig verdichtet."));
+      delay = 8;
+      break;
+    case 4:
+      int g = PL->QueryProp(P_GENDER);
+      string desc = PL->QueryProp(P_RACESTRING)[0];
+      string msg = (g==MALE?"ein richtiger ":"eine richtige ")+desc;
+      tell_object(PL, BS(
+        "\nSchon kurz darauf hat sich ein eleganter Koerper geformt, der "
+        "nun vollkommen Dir gehoert. Dass Du noch nackt bist, stoert Dich "
+        "nicht im geringsten, denn endlich, endlich fuehlst Du Dich "
+        "wie "+msg+"!"));
+      delay = 10;
+      break;
+    case 5:
+      tell_object(PL, BS(
+        "\nDeine Begeisterung ueber Deinen makellosen Koerper wird jaeh "
+        "unterbrochen, als ploetzlich die Sterne verblassen und sich mit "
+        "unfassbarem Tempo von Dir zu entfernen scheinen. Dann wird es "
+        "kurz schwarz um Dich herum und kurz darauf wieder hell."));
+      delay = 8;
+      break;
+    case 6:
+      tell_object(PL, "\n"+break_string(
+        "Herzlich Willkommen! Uebrigens, wenn Du auf der "
+        "Ebene Anfaenger mit anderen reden willst, folgender Tip: Probiere "
+        "mal '-anf Hallo Morgengrauen' (natuerlich ohne die ' mit "
+        "einzugeben) aus.", 78, "Merlin teilt Dir mit: "));
+      delay = 6;
+      break;
+    case 7:
+      if (PL->QueryGuest() ) {
+        PL->move("/gilden/abenteurer", M_GO);
+        return;
+      }
+      else
+        tell_object(PL, "\n"+break_string(
+          "Ich werde Dich jetzt in das Tutorial fuer Anfaenger bewegen, wo "
+          "Du Deine ersten Schritte machen kannst...",
+          78, "Merlin teilt Dir mit: ")+"\n");
+      delay = 4;
+      break;
+    case 8:
+      PL->move(TUTSTART+getuid(PL), M_GO);
+      return; // call_out nicht wieder anwerfen.
+   }
+   ++count;
+   call_out("Sequenz", delay, count);
+}
+
+// Bei Disconnect Sequenz abbrechen, bei Re-Login wieder starten mit
+// count == 5 d.h. Spieler fliegt also quasi "im Schlaf" weiter...
+void BecomesNetDead(object pl) {
+  while(remove_call_out("Sequenz")!=-1)
+   ;
+}
+
+void BecomesNetAlive(object pl) {
+  if (interactive(pl))
+    call_out("Sequenz", 6, 5);
+}
+
diff --git a/room/welcome/virtual_compiler.c b/room/welcome/virtual_compiler.c
new file mode 100644
index 0000000..a3eea2c
--- /dev/null
+++ b/room/welcome/virtual_compiler.c
@@ -0,0 +1,27 @@
+#include <defines.h>
+#include <v_compiler.h>
+inherit "/std/virtual/v_compiler";
+
+void create() {
+  ::create();
+  SetProp(P_STD_OBJECT, "/room/welcome/std");
+}
+
+string Validate(string file) {
+
+  file=::Validate(file);
+
+  // keine Unterverzeichnisse, gueltige Charnamen
+  if (strstr(file,"/") == -1
+      && sizeof(file) <= 11 // charnamen <=11 zeichen
+      && (regmatch(file,"[a-zA-Z]+") == file // nur A-Z,a-z
+          || strstr(file,"gast") == 0 // oder Gaeste
+          )
+     )
+  {
+    // Eigentlich P_COMPILER_PATH, aber hier geht jetzt auch __DIR__
+    return __DIR__ + file;
+  }
+  return 0;
+}
+