diff --git a/obj/doormaster.c b/obj/doormaster.c
new file mode 100644
index 0000000..46e9364
--- /dev/null
+++ b/obj/doormaster.c
@@ -0,0 +1,469 @@
+#include <properties.h>
+#include <defines.h>
+#include <moving.h>
+#include <language.h>
+
+#define NEED_PROTOTYPES
+#include <doorroom.h>
+
+inherit "/std/thing";
+
+#pragma strong_types
+
+private mapping door_status;
+private int id_zaehler;
+// Format: "filename1:filename2":status
+
+int oeffnen (string str);
+
+mapping QueryAllDoors() {return door_status;}
+
+int QueryDoorStatus(string dest) {
+  string source,dkey;
+  object env;
+
+  if (!dest) return 0;
+  if (!objectp(env=previous_object())) return 0;
+  source=object_name(env);
+  dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+  return door_status[dkey];
+}
+
+void SetDoorStatus(string dest, int x) {
+  string source,dkey;
+  object env;
+
+  if (!dest) return;
+  if (!objectp(env=previous_object())) return;
+  source=object_name(env);
+  dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+  door_status[dkey]=x;
+}
+
+protected void create() {
+  door_status=([]);
+  id_zaehler=0;
+  if (IS_CLONE(this_object())) remove();
+}
+
+varargs int remove(int silent) {return 0;}
+
+varargs int NewDoor(string|string* cmds, string dest, string|string* ids,
+                    mapping|<int|string|string*>* props)
+{
+  object env;
+  string source,dkey,sec_id;
+  mixed *info2,zw;
+  mapping info;
+  int i;
+
+  if (!objectp(env=previous_object())) return 0;
+  if (!cmds || !dest) return 0;
+  if (!ids) ids=({"tuer"});
+  if (stringp(cmds)) cmds=({cmds});
+  if (stringp(ids)) ids=({ids});
+  if (!pointerp(cmds) || !pointerp(ids)) return 0;
+  if (dest[0..0]!="/") dest="/"+dest;
+  id_zaehler++;
+  sec_id=sprintf("secure_id:door%d",id_zaehler);
+
+  info=([D_DEST   : dest,
+	 D_CMDS   : cmds,
+	 D_IDS    : ({ sec_id }) + ids,
+	 D_FLAGS  : (DOOR_CLOSED|DOOR_RESET_CL),
+         D_LONG   : "Eine Tuer.\n",
+	 D_SHORT  : "Eine %se Tuer. ",
+	 D_NAME   : "Tuer",
+	 D_GENDER : FEMALE]);
+  source=object_name(env);
+  dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+
+  if (pointerp(props)) {
+    for (i=0;i<sizeof(props)-1;i+=2)
+      if (intp(props[i]) && props[i]>=D_MINPROPS && props[i]<=D_MAXPROPS)
+        info[props[i]]=props[i+1];
+  }
+  else if(mappingp(props)){
+    info += props;
+  }
+
+  if (!door_status[dkey]) {
+    // Nur initialisieren, wenn Tuer noch nicht existiert.
+    if (info[D_FLAGS] & DOOR_OPEN)
+        door_status[dkey]=D_STATUS_OPEN;
+    if (info[D_FLAGS] & DOOR_CLOSED)
+        door_status[dkey]=
+          ((info[D_FLAGS] & DOOR_NEEDKEY) ? D_STATUS_LOCKED : D_STATUS_CLOSED);
+  }
+  info2=env->QueryProp(P_DOOR_INFOS);
+  if (!pointerp(info2))
+    info2=({info});
+  else
+    info2+=({info});
+  env->SetProp(P_DOOR_INFOS,info2);
+
+  if(mappingp(info[D_LONG]) && pointerp(zw=m_indices(info[D_LONG])) &&
+     sizeof(zw) && intp(zw[0]))
+    env->AddSpecialDetail(ids,"special_detail_doors");
+  else if(info[D_LONG] && info[D_LONG]!="")
+    env->AddDetail(ids,info[D_LONG]);
+
+  return 1;
+}
+
+void init_doors () {
+  object env;
+  mixed *info;
+  string source,dest,dkey;
+  int i;
+
+  if (!objectp(env=previous_object())) return;
+  info=env->QueryProp(P_DOOR_INFOS);
+  if (!pointerp(info)) return;
+
+  source=object_name(env);
+  for (i=sizeof(info)-1;i>=0;i--) {
+    if (!mappingp(info[i])) continue;
+    dest=info[i][D_DEST];
+    dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+    env->set_doors(info[i][D_CMDS],(door_status[dkey]>0));
+  }
+}
+
+string look_doors () {
+  object env;
+  mixed *info, ds;
+  string source,dkey,dest,res;
+  int i, st;
+
+  if (!objectp(env=previous_object())) return "";
+  info=env->QueryProp(P_DOOR_INFOS);
+  if (!pointerp(info)) return "";
+  init_doors(); // Aktueller Zustand soll auch bei den Exits angezeigt werden
+
+  source=object_name(env);res="";
+  for (i=sizeof(info)-1;i>=0;i--) {
+    if (!mappingp(info[i])) continue;
+    dest=info[i][D_DEST];
+    dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+    if (stringp(info[i][D_SHORT])) {
+      res+=sprintf(info[i][D_SHORT],
+		    ((door_status[dkey]>=D_STATUS_OPEN)?"geoeffnet":
+			 ((door_status[dkey]!=D_STATUS_CLOSED)?"ab":"")+"geschlossen"));
+	  if (sizeof(res) && res[<1]!='\n')
+		res+=" ";
+	}
+    else if(mappingp(ds=info[i][D_SHORT])){
+      st=door_status[dkey];
+      if((st==D_STATUS_LOCKED) && !ds[D_STATUS_LOCKED])
+        st=D_STATUS_CLOSED;
+      if(stringp(ds[st])){
+        res += ds[st];
+        if(sizeof(ds[st]) && res[<1]!='\n')res+=" ";
+      }
+    }
+  }
+  if (res && res!="")
+    return break_string(res,78,0,1);
+  return res;
+}
+
+static void door_message(object room, string dname, int dgender, string msg) {
+  object ob;
+
+  // printf("%O,%O,%O,%O\n",room,dname,dgender,msg);
+  if (!room || !dname || !msg) return;
+  ob=this_object();
+  ob->SetProp(P_NAME,dname);
+  ob->SetProp(P_GENDER,dgender);
+  ob->SetProp(P_ARTICLE,1);
+  tell_room(room,capitalize(ob->name(WER))+msg+"\n");
+}
+
+static void door_message_other(string source, string dest, string msg) {
+  mixed info;
+  object env;
+  int i;
+
+  // printf("%O %O %O\n",source,dest,msg);
+  if (!source || !dest || !msg) return;
+  if (!objectp(env=find_object(dest))) return;
+  if (!pointerp(info=env->QueryProp(P_DOOR_INFOS))) return;
+  for (i=sizeof(info)-1;i>=0;i--) {
+    if (!mappingp(info[i])) continue;
+    if (info[i][D_DEST]!=source) continue; // Andere Tuer zu diesem Raum
+    door_message(env,info[i][D_NAME],info[i][D_GENDER],msg);
+  }
+}
+
+void reset_doors () {
+  object env;
+  mixed *info;
+  string source,dest,dkey,msg;
+  int i,j;
+
+  if (!objectp(env=previous_object())) return;
+  info=env->QueryProp(P_DOOR_INFOS);
+  if (!pointerp(info)) return;
+
+  source=object_name(env);
+  for (i=sizeof(info)-1;i>=0;i--) {
+    if (!mappingp(info[i])) continue;
+    dest=info[i][D_DEST];
+    dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+
+// 	if (door_status[dkey]>-2 && door_status[dkey]<2) {
+// 	  if (door_status[dkey]>0)
+// 		door_status[dkey]=2;
+// 	  else
+// 		door_status[dkey]=-2;
+// 	  continue; // nur jeder 2. Reset wird ausgefuehrt.
+// 	}
+
+    if (info[i][D_FLAGS] & DOOR_RESET_CL) {
+      // Tuer muss bei Reset geschlossen werden
+      if (door_status[dkey] >= D_STATUS_OPEN) {
+        if(!msg=info[i][D_RESET_MSG])msg=" schliesst sich.";
+        door_message(env,info[i][D_NAME],info[i][D_GENDER],msg);
+        door_message_other(source,dest,msg);
+      }
+	  if (door_status[dkey]!=D_STATUS_LOCKED)
+		door_status[dkey]=
+      ((info[i][D_FLAGS] & DOOR_NEEDKEY) ? D_STATUS_LOCKED : D_STATUS_CLOSED);
+    }
+    if (info[i][D_FLAGS] & DOOR_RESET_OP) {
+      // Tuer muss bei Reset geoeffnet werden
+      if (door_status[dkey] < D_STATUS_OPEN) {
+        if(!msg=info[i][D_RESET_MSG])msg=" oeffnet sich.";
+        door_message(env,info[i][D_NAME],info[i][D_GENDER],msg);
+        door_message_other(source,dest,msg);
+      }
+      door_status[dkey]=D_STATUS_OPEN;
+    }
+  }
+  init_doors();
+}
+
+static varargs int exec_func2(string dest, mixed func) {
+  if (!stringp(dest) || !stringp(func)) return 1;
+  call_other(dest,func);
+  return 1;
+}
+
+varargs int go_door (string str) {
+  object env,pl,ob;
+  mixed *info;
+  string source,dest,dkey;
+  int i;
+
+  if (!str) return 0;
+  if (!objectp(env=previous_object())) return 0;
+  if (!objectp(pl=this_player())) return 0;
+  info=env->QueryProp(P_DOOR_INFOS);
+  if (!pointerp(info)) return 0;
+
+  source=object_name(env);
+  ob=this_object();
+  ob->SetProp(P_ARTICLE,1);
+  for (i=sizeof(info)-1;i>=0;i--) {
+    if (!mappingp(info[i])) continue;
+    if (member(info[i][D_CMDS],str)<0) continue;
+    dest=info[i][D_DEST];
+    dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+    ob->SetProp(P_NAME,info[i][D_NAME]);
+    ob->SetProp(P_GENDER,info[i][D_GENDER]);
+    notify_fail(capitalize(ob->name(WER,1))+" ist geschlossen.\n");
+    if((door_status[dkey]<=0) &&
+       !info[i][D_OPEN_WITH_MOVE]) continue; // Tuer geschlossen
+    if(door_status[dkey]<=0){
+      // In diesem Fall versuchen, die Tuer zu oeffnen.
+      oeffnen(info[i][D_IDS][0]);
+    }
+    notify_fail(capitalize(ob->name(WER,1))+" ist geschlossen.\n");
+    if (door_status[dkey]<=0) continue; // Tuer immer noch zu.
+    if (stringp(info[i][D_TESTFUNC]))
+      if (call_other(env,info[i][D_TESTFUNC]))
+		return 1; // Durchgang von der Tuer nicht erlaubt.
+    if (stringp(info[i][D_FUNC]))
+      call_other(env,info[i][D_FUNC]);
+	if (stringp(info[i][D_MSGS])) {
+	  if (pl->move(dest,M_GO,info[i][D_MSGS])>0)
+		return exec_func2(dest,info[i][D_FUNC2]);
+	  else
+		return 1;
+	}
+	if (pointerp(info[i][D_MSGS]) && sizeof(info[i][D_MSGS])>=3) {
+	  if (pl->move(dest,M_GO,info[i][D_MSGS][0],
+				   info[i][D_MSGS][1],info[i][D_MSGS][2]))
+		return exec_func2(dest,info[i][D_FUNC2]);
+	  else
+		return 1;
+	}
+    if (pl->move(dest,M_GO,"nach "+capitalize(str)))
+	  return exec_func2(dest,info[i][D_FUNC2]);
+    return 1;
+  }
+  return 0;
+}
+
+int oeffnen (string str) {
+  object env,schl,ob;
+  mixed *info,s2;
+  string source,dkey,dest,s1;
+  int i;
+
+  notify_fail("WAS willst Du oeffnen?\n");
+  if (!str || !this_player()) return 0;
+  notify_fail("Das kannst Du nicht oeffnen.\n");
+  str=lower_case(str);
+  if (sscanf(str,"%s mit %s",s1,s2)!=2)
+    {s1=str;s2=0;}
+  if (s2) {
+    if (!(schl=present(lower_case(s2),this_player()))) {
+      notify_fail("So einen Schluessel hast Du nicht.\n");
+      return 0;
+    } else {
+      s2=schl->QueryDoorKey();
+	  if (stringp(s2)) s2=({s2});
+    }
+  }
+
+  if (!objectp(env=previous_object())) return 0;
+  info=env->QueryProp(P_DOOR_INFOS);
+  if (!pointerp(info)) return 0;
+
+  source=object_name(env);
+  ob=this_object();
+  ob->SetProp(P_ARTICLE,1);
+  for (i=sizeof(info)-1;i>=0;i--) {
+    if (!mappingp(info[i])) continue;
+    if (member(info[i][D_IDS],s1)<0) continue; // Falsche Tuer
+    ob->SetProp(P_NAME,info[i][D_NAME]);
+    ob->SetProp(P_GENDER,info[i][D_GENDER]);
+    dest=info[i][D_DEST];
+    dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+    notify_fail(capitalize(ob->name(WER,1))+" ist doch schon geoeffnet!\n");
+    if (door_status[dkey]>0)
+      continue; // Eine andere Tuer koennte gemeint sein.
+    if ((info[i][D_FLAGS] & DOOR_NEEDKEY)
+        && door_status[dkey] == D_STATUS_LOCKED) { // abgeschlossen
+      notify_fail("Du brauchst einen Schluessel, um "+ob->name(WEN,1)+" zu oeffnen.\n");
+      if (!schl) continue; // Eine andere Tuer koennte gemeint sein.
+      notify_fail(capitalize(schl->name(WER))+" passt nicht!\n");
+      if (!pointerp(s2)) continue;
+	  if (member(s2,dkey)<0) continue; // Koennte an einer anderen passen.
+    }
+    door_status[dkey]=1;
+    init_doors();
+    write("Du oeffnest "+ob->name(WEN)+".\n");
+    say(capitalize(ob->name(WER))+" wird von "+this_player()->name(WEM)+
+        " geoeffnet.\n");
+    door_message_other(source,dest," wird von der anderen Seite geoeffnet.");
+    return 1;
+  }
+  return 0;
+}
+
+int schliessen (string str) {
+  object env,schl,ob;
+  mixed *info,s2;
+  string source,dkey,dest,s1;
+  int i,abg;
+
+  notify_fail("WAS willst Du schliessen?\n");
+  if (!str || !this_player()) return 0;
+  notify_fail("Das kannst Du nicht schliessen.\n");
+  str=lower_case(str);
+  if (sscanf(str,"%s mit %s",s1,s2)!=2)
+    {s1=str;s2=0;}
+  if (s2) {
+    if (!(schl=present(lower_case(s2),this_player()))) {
+      notify_fail("So einen Schluessel hast Du nicht.\n");
+      return 0;
+    } else {
+      s2=schl->QueryDoorKey();
+	  if (stringp(s2)) s2=({s2});
+    }
+  }
+
+  if (!objectp(env=previous_object())) return 0;
+  info=env->QueryProp(P_DOOR_INFOS);
+  if (!pointerp(info)) return 0;
+
+  source=object_name(env);
+  ob=this_object();
+  ob->SetProp(P_ARTICLE,1);
+  abg=0;
+  for (i=sizeof(info)-1;i>=0;i--) {
+    if (!mappingp(info[i])) continue;
+    if (member(info[i][D_IDS],s1)<0) continue; // Falsche Tuer
+    ob->SetProp(P_NAME,info[i][D_NAME]);
+    ob->SetProp(P_GENDER,info[i][D_GENDER]);
+    dest=info[i][D_DEST];
+    dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+	if (schl) {
+	  notify_fail(capitalize(ob->name(WER,1))+" ist doch schon abgeschlossen!\n");
+	  if (door_status[dkey]<=0
+        && door_status[dkey] == D_STATUS_LOCKED)
+      continue; // Eine andere Tuer koennte gemeint sein.
+	  if (info[i][D_FLAGS] & DOOR_CLOSEKEY) { // Schluessel noetig?
+		  notify_fail(capitalize(schl->name(WER))+" passt nicht!\n");
+		  if (!pointerp(s2)) continue;
+		  if (member(s2,dkey)<0) continue; // Koennte an einer anderen passen.
+		  door_status[dkey]=D_STATUS_LOCKED;
+		  abg=1;  // Tuer wird richtig abgeschlossen
+	  }
+    else {
+		  // ohne Schluessel abschliessbar
+		  door_status[dkey]=
+        ((info[i][D_FLAGS] & DOOR_NEEDKEY) ? D_STATUS_LOCKED : D_STATUS_CLOSED);
+	  }
+	}
+  else {
+	  notify_fail(capitalize(ob->name(WER,1))+" ist doch schon geschlossen!\n");
+	  if (door_status[dkey] < D_STATUS_OPEN)
+		  continue; // Eine andere Tuer koennte gemeint sein.
+	  if ((info[i][D_FLAGS] & DOOR_NEEDKEY) && 
+        !(info[i][D_FLAGS] & DOOR_CLOSEKEY))
+		  door_status[dkey]=D_STATUS_LOCKED; // Abschliessbar, aber dazu schluessel unnoetig
+	  else
+		  door_status[dkey]=D_STATUS_CLOSED;
+	}
+	init_doors();
+	write("Du schliesst "+ob->name(WEN)+
+		  (abg?" ab":"")+".\n");
+	say(capitalize(ob->name(WER))+" wird von "+this_player()->name(WEM)+
+		(abg?" ab":" ")+"geschlossen.\n");
+	door_message_other(source,dest," wird von der anderen Seite "+
+					   (abg?"ab":"")+"geschlossen.");
+    return 1;
+  }
+  return 0;
+}
+string special_detail_doors(string key){
+  object env;
+  mixed *info;
+  mapping dl;
+  int i, st;
+  string source, dest, dkey;
+
+  if(!objectp(env=previous_object()))return 0;
+  if(!pointerp(info=env->QueryProp(P_DOOR_INFOS)))return 0;
+  source=object_name(env);
+
+  for(i=sizeof(info)-1;i>=0;i--){
+    if(!mappingp(info[i]))continue;
+    if(member(info[i][D_IDS],key)<0)continue;
+    if(stringp(info[i][D_LONG]))return info[i][D_LONG];
+    if(!mappingp(info[i][D_LONG]))continue;
+    dl=info[i][D_LONG];
+    dest=info[i][D_DEST];
+    dkey=(source<dest)?(source+":"+dest):(dest+":"+source);
+    st=door_status[dkey];
+    if((st==D_STATUS_LOCKED) && !dl[D_STATUS_LOCKED])
+        st=D_STATUS_CLOSED; /* Falls keine eigene Beschreibung
+                             * fuer abgeschlossene Tuer vorhanden */
+    return dl[st];
+  }
+  return 0;
+}
