diff --git a/std/transport.c b/std/transport.c
new file mode 100644
index 0000000..fffe1e0
--- /dev/null
+++ b/std/transport.c
@@ -0,0 +1,521 @@
+// MorgenGrauen MUDlib
+//
+// transport.c -- Basisklasse fuer Schiffe und aehnliche Transporter
+//
+// $Id: transport.c 9400 2015-12-11 21:56:14Z Zesstra $
+#pragma strong_types
+//#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+inherit "/std/thing/moving";
+inherit "/std/room";
+
+#include <properties.h>
+#include <moving.h>
+#include <defines.h>
+#include <language.h>
+#include <transport.h>
+#include <regexp.h>
+
+/* transport.c
+ * 
+ * Ueberarbeitete und 
+ * erweiterte Version : Tilly@MorgenGrauen, 10.01.02
+ * Basierend auf      : transport.c@SilberLand (Woody@SilberLand), 05.12.99
+ * Basierend auf      : Hates und Rumatas generisches Transport Objekt
+ *                      MorgenGrauen 15.02.93
+ */
+     
+/*
+ ********************* Variablen *********************
+ */
+
+// TODO: langfristig waer ja private schoen...
+//
+// Datenstruktur von 'route' (bei HP_ROOM)
+// 0 ({string ID,      : HP_ROOM
+// 1   string room,    : Dateiname Zielraum
+// 2   int stay,       : Dauer Haltezeit
+// 3   int next,       : Dauer naechste Fahrtzeit
+// 4   string code,    : Haltestellenname fuer QueryArrived
+// 5   mixed dest,     : Haltestellen-IDs fuer HasRoute (reise nach)
+// 6   mixed deststr }): unbenutzt.
+//
+// Datenstruktur von 'route' (bei HP_MSG, HP_FUN)
+// 0 ({string ID,      : HP_MSG
+// 1   string message, : Meldung    oder    string fun : Funktionsname
+// 2   int next})      : Dauer bis zum naechsten Ereignis
+nosave mixed *route;    /* Liste der Haltepunkte. */
+nosave int rpos;        /* Momentane Position in obiger Liste. */
+nosave string roomCode; /* Code des aktuellen Raumes (oder 0). */
+
+/*
+ ********** Management der builtin-properties **********
+ */
+
+string _query_short()
+{ 
+  if (roomCode) return Query(P_SHORT); 
+  return 0; 
+}
+
+mixed _query_transparent()
+{ 
+  if (roomCode) return Query(P_TRANSPARENT);
+  return 0; 
+}
+
+mixed *_set_route(mixed *r) { return route = r; }
+mixed *_query_route()       { return route; }
+
+/*
+ **************** Zugriffsfunktionen ***************
+ */
+
+void Halt()
+{
+  while (remove_call_out( "changeHp" )>-1);
+  while (remove_call_out( "disconnect" )>-1);
+}
+
+// Aktualisiert/Setzt die Route im TravelD, wenn erlaubt (d.h. kein
+// P_NO_TRAVELING)
+private void ReportRoute()
+{
+  if(!QueryProp(P_NO_TRAVELING))
+  {
+    mixed tmp = filter(route, function int (mixed arr)
+        {
+          return arr[0] == HP_ROOM;
+        } );
+    string *route = map(tmp, function string (mixed arr)
+        { return arr[1]; }
+        );
+    TRAVELD->AddRoute(object_name(this_object()),route);
+  }
+}
+
+varargs void Start(int pos)
+{
+  Halt();
+  rpos = (pos >= sizeof(route))?-1:pos-1;
+  call_out("changeHp",0);
+  // Tell TRAVELD our current route
+  ReportRoute();
+}
+
+void SetTravelCmds()
+{
+  if (pointerp(QueryProp(P_LEAVECMDS)))
+     AddCmd(QueryProp(P_LEAVECMDS),"GoOutside");
+  if (pointerp(QueryProp(P_ENTERCMDS)))
+    AddCmd(QueryProp(P_ENTERCMDS),"GoInside");
+  if (pointerp(QueryProp(P_TRAVEL_CMDS)))
+    AddCmd(QueryProp(P_TRAVEL_CMDS),"GoInAndOutside");
+  return;
+}
+
+mixed HasRoute(mixed dest)
+{
+  int i,s,z;
+  string str;
+  object ob;
+  mixed harb;
+  
+  s = sizeof(route);
+
+  for (i = rpos;i <= rpos+s-1;i++)
+  {
+    if (route[i%s][0] == HP_ROOM)
+    {
+      if (member(route[i%s][5],dest) != -1 &&
+          objectp(ob=load_object(route[i%s][1])) &&
+          pointerp(harb=ob->QueryProp(P_HARBOUR)) &&
+          sizeof(harb))
+      {
+        return ({ route[i%s][1], harb[0] });
+      }
+    }
+  }
+  return 0;
+}
+
+public varargs void AddRoute(string room, int stay, int next, 
+    string harbour_desc, string|string* dest_ids, string deststr)
+{
+  // Daten aus dem Zielanleger abfragen.
+  <string|string*>* harbour = room->QueryProp(P_HARBOUR)||({});
+  string* harbour_ids = ({});
+
+  // IDs des Zielanlegers fuer Syntaxpruefung 
+  if ( sizeof(harbour)==2 )
+  {
+    if ( pointerp(harbour[1]) )
+      harbour_ids = harbour[1];
+    else
+      harbour_ids = ({harbour[1]});
+  }
+  
+  // <dest_ids> in ein Array umwandeln, ist dann ggf. leer
+  if ( !dest_ids )
+  {
+    dest_ids = ({});
+  }
+  if ( stringp(dest_ids) )
+  {
+    dest_ids = ({dest_ids});
+  }
+
+  // explizit angegebene IDs stehen jetzt in <dest_ids>, die IDs des 
+  // Zielhafens aus P_HARBOUR werden addiert.
+  dest_ids += harbour_ids;
+
+  // Ist <dest> immer noch leer, versuchen wir, aus <harbour_desc> ein paar
+  // Stichwoerter zu erzeugen, die man als Zielangabe in der Syntax 
+  // "reise nach <ziel>" verwenden kann.
+  if ( !sizeof(dest_ids) )
+  {
+    // Grossgeschriebene Begriffe in <harbour_desc> in <dest> eintragen. Dazu:
+    // 1) <code> erstmal so zerschneiden, dass alle ueblichen Satzzeichen
+    // rausfliegen (es gibt Transporter, die sowas in <harbour_desc> 
+    // uebergeben).
+    dest_ids = regexplode(harbour_desc, "[(),.;:&\+_ ]", 
+                          RE_OMIT_DELIM|RE_GLOBAL);
+    // 2a) So filtern, dass nur grossgeschriebene Woerter uebrig bleiben,
+    //     von 1) uebriggebliebene Leerstrings gleich mit wegwerfen.
+    // 2b) Ergebnis kleinschreiben, damit die Syntaxpruefung damit arbeiten
+    //     kann.
+    dest_ids = map( filter(dest_ids, function int (string key) { 
+                  return (key!="" && key[0]>='A' && key[0]<='Z');
+               }), #'lower_case);
+  }
+  // Sollte <dest> jetzt immer noch leer sein, wurde an allen drei Stellen
+  // nichts oder nur Muell uebergeben.
+  if ( !sizeof(dest_ids) )
+  {
+    raise_error("Transporterfehlfunktion in AddRoute(): Identifikations"
+      "matrix unzureichend definiert. Transporter unbenutzbar fuer "
+      "Spieler. Bitte mindestens eine Ziel-ID via P_HARBOUR oder als "
+      "Argument to AddRoute().");
+  }
+  route += ({ ({ HP_ROOM, room, stay, next, harbour_desc, dest_ids, 
+                 deststr }) });
+}
+
+varargs void AddMsg(string msg, int next) 
+{
+  route += ({ ({ HP_MSG, msg, next }) }); 
+}
+
+void AddFun(string fun, int next) { route += ({ ({ HP_FUN, fun, next }) }); }
+
+string QueryArrived() { return roomCode; }
+
+mixed* QueryPosition()
+{
+  return ({ route[rpos][1],route[(rpos+1)<sizeof(route)?(rpos+1):0][1] });
+}
+
+object* QueryPassengers()
+{
+  return filter(all_inventory(),#'query_once_interactive); 
+}
+
+varargs string *QueryHarbours(int textflag)
+{
+  string *ret = ({});
+
+  foreach( mixed* entry : route )
+  {
+    if ( entry[0] == HP_ROOM )
+    {
+      if ( textflag )
+      {
+        string *hp_ids = entry[1]->QueryProp(P_HARBOUR)[1];
+        if (pointerp(hp_ids) && sizeof(hp_ids))
+        {
+          string *h = map( explode(hp_ids[0]," "), #'capitalize);
+          ret += ({ implode(h, " ") });
+        }
+      }
+      else
+      {
+        ret += ({ entry[1] });
+      }
+    }
+  }
+  return ret;
+}
+
+// beim zerstoeren sollte auch die route und der Transporter aus dem traveld
+// abgemeldet werden.
+public varargs int remove(int silent)
+{
+  TRAVELD->RemoveTransporter(this_object());
+  return ::remove(silent);
+}
+
+void RemoveRoute()
+{
+  Halt();
+  route = ({ });
+  rpos  =   0;
+  TRAVELD->RemoveTransporter(this_object());
+}
+
+varargs int Enter(object who)
+{
+  string *emsg;
+  mixed efail;
+
+  if (!objectp(who)) who = this_player();
+  if (environment(who) == this_object())
+  {
+    tell_object(who,"Da bist Du doch bereits, schon vergessen?\n");
+    return 1;
+  }
+  if (!QueryArrived()) return 0;
+  if (QueryProp(P_MAX_PASSENGERS) && 
+     (sizeof(QueryPassengers()) >= QueryProp(P_MAX_PASSENGERS)))
+  {
+    if (pointerp(efail=QueryProp(P_ENTERFAIL)))
+    {
+      if (sizeof(efail) == 2)
+        tell_room(this_object(),who->Name(WER,2)+" "+process_string(efail[1])+
+                                                   ".\n",({who}));      
+      tell_object(who,process_string(efail[0])+".\n");
+    }
+    else if (stringp(efail))
+       tell_object(who,process_string(efail)+".\n");
+    else if (closurep(efail)) funcall(efail);
+    return 1;
+  }
+  
+  tell_object(who,"Du betrittst "+name(WEN,1)+".\n");
+  if (pointerp(emsg=QueryProp(P_ENTERMSG)) && sizeof(emsg) == 2)
+     return who->move(this_object(),M_GO,"",process_string(emsg[0]),
+                                             process_string(emsg[1]));
+  return who->move(this_object(),M_GO,
+        name(WEN,1),"betritt","kommt herein");
+}
+
+varargs int Leave(object who)
+{
+  string *lmsg;
+  mixed lfail;
+
+  if (!objectp(who)) who = this_player();
+  if (environment(who) != this_object())
+  {
+    if (QueryArrived())
+    {
+      tell_object(who,"Dafuer muesstest Du erstmal dort sein.\n");
+      return 1;
+    }
+    return 0;
+  }
+  if (!QueryArrived())
+  { 
+    if (lfail=QueryProp(P_LEAVEFAIL))
+    {
+      if (pointerp(lfail) && sizeof(lfail))
+      {
+        if (sizeof(lfail) == 2)
+           tell_room(this_object(),who->Name(WER,2)+" "+process_string(
+               lfail[1])+".\n",({who}));
+        tell_object(who,process_string(lfail[0])+".\n");
+      }
+      else if (stringp(lfail))
+        tell_object(who,process_string(lfail)+".\n");
+      else if (closurep(lfail)) funcall(lfail);
+      return 1;
+    }
+    tell_object(who,"Fehler beim Verlassen des Transporters.\n"
+                    "Bitte zustaendigen Magier verstaendigen.\n");
+    return 1;
+  }
+
+  if (who->QueryProp(P_TRAVEL_INFO)) who->SetProp(P_TRAVEL_INFO,0);
+  tell_object(who,"Du verlaesst "+name(WEN,1)+".\n");
+  if (pointerp(lmsg=QueryProp(P_LEAVEMSG)) && sizeof(lmsg) == 2)
+      return who->move(environment(),M_GO,"",process_string(lmsg[0]),
+                                             process_string(lmsg[1]));
+  return who->move(environment(),M_GO,
+           name(WEN,1),"verlaesst","kommt herein");
+}
+
+/*
+ ****************** Internal Functions ******************
+ */
+
+static int GoInside(string str)
+{
+  _notify_fail("Was moechtest Du denn genau?\n");
+  if (stringp(str) && id(str)) {
+      Enter();
+      return 1;
+  }
+  return 0;
+}
+
+static int GoOutside(string str)
+{
+  _notify_fail("Was moechtest Du denn genau?\n");
+  if (stringp(str) && id(str)) {
+      Leave();
+      return 1;
+  }
+  return 0;
+}
+
+static int GoInAndOutside(string str)
+{
+  string to;
+
+  _notify_fail("Was moechtest Du denn genau?\n");
+  if (!sizeof(str)) return 0;  
+  if ((sscanf(str,"auf %s",to) == 1 || sscanf(str,"in %s",to) == 1) && id(to))
+    return Enter(),1;
+  if ((sscanf(str,"von %s",to) == 1 || sscanf(str,"aus %s",to) == 1) && id(to))
+    return Leave(),1;
+  return 0;
+}
+
+protected void create()
+{
+  ::create();
+
+  route = ({});
+
+  SetProp(P_LEAVEFAIL,"Das ist momentan viel zu gefaehrlich");
+  SetProp(P_ENTERFAIL,"Dort ist kein Platz mehr fuer Dich");
+  SetProp(P_TRANSPARENT,1);
+
+  AddId("Transporter");
+  
+  call_out("SetTravelCmds",1);
+}
+
+static varargs void disconnect(int change, int change_time)
+{
+  object room;
+  mixed *departmsg;
+
+  departmsg = QueryProp(P_DEPARTMSG);
+
+  if ((room = environment()) && pointerp(departmsg))
+  {
+    tell_room(this_object(),process_string(departmsg[0]));
+    tell_room(room,process_string(departmsg[1]));
+  }
+
+  roomCode = 0;
+
+  if (change) call_out("changeHp",change_time);
+}
+
+static varargs void connect(string room, string code)
+{
+  mixed *arrivemsg, *t;
+  object *trav, ob;
+  string *trs, *msgs;
+  int i;
+
+  if (roomCode) disconnect();
+  
+  roomCode = code?code:"";
+
+  if (catch(move(room,M_SILENT|M_NOCHECK);publish))
+  {
+    roomCode = 0;
+    return;
+  }
+
+  arrivemsg = QueryProp(P_ARRIVEMSG);
+
+  if (pointerp(arrivemsg))
+  {
+    tell_room(this_object(),process_string(arrivemsg[0]));
+    tell_room(room,process_string(arrivemsg[1]));
+  }
+
+  trav = filter(all_inventory(this_object()),#'living);
+
+  i = sizeof(trav);
+  while(i--)
+  {
+    if (pointerp(t = trav[i]->QueryProp(P_TRAVEL_INFO))&&
+        t[0]==this_object()&&t[2]==room)
+    { 
+      if (trav[i]->InFight())
+        tell_object(trav[i],break_string("Du solltest Deinen Kampf "
+                "schnell beenden,denn eigentlich wolltest Du hier "
+                "aussteigen.",78));
+      else
+        Leave(trav[i]);
+      if (environment(trav[i])!=this_object())
+        trav[i]->SetProp(P_TRAVEL_INFO,0);
+    }
+  }
+  trav = filter(all_inventory(find_object(room))-trav,#'living);
+  i=sizeof(trav);
+  while(i--)
+  {
+    if (objectp(trav[i]) && pointerp(t = trav[i]->QueryProp(P_TRAVEL_INFO))&&
+        t[0] == environment(trav[i]) && t[1] == this_object())
+    {
+      if ( trav[i]->InFight() )
+        tell_object(trav[i],
+           break_string("Du solltest Deinen Kampf schnell beenden, denn "
+                        "eigentlich wolltest Du mit "+name(WEM,1)+
+                        " reisen.",78));
+      else
+        Enter(trav[i]);
+      if (environment(trav[i]) == this_object()) 
+      {
+        t[0] = this_object();
+        trav[i]->SetProp(P_TRAVEL_INFO,t);
+      }
+    }
+  }
+}
+
+// this object never performs any clean-up, the driver should not call it
+// again.
+int clean_up(int arg) { return 0; }
+
+void changeHp()
+{
+  if (++rpos == sizeof(route))
+  {
+    rpos = 0;
+    //TRAVELD die aktuelle Route uebermitteln
+    ReportRoute();
+  }
+  if (route[rpos][0] == HP_MSG)
+  {
+    call_out("changeHp",route[rpos][2]);
+    tell_room(this_object(),route[rpos][1]);
+  }
+  else if (route[rpos][0] == HP_FUN)
+  {
+    call_out("changeHp",route[rpos][2]);
+    call_other(this_object(),route[rpos][1]);
+  }
+  else 
+  {
+    call_out("disconnect",route[rpos][2],1,route[rpos][3]);
+    connect(route[rpos][1],route[rpos][4]);
+  }
+}
+
+void __restart(string funname)
+{
+  if (!funname || funname == "" || (funname != "changeHp" && 
+                                    funname != "disconnect"))
+    return;
+  while(remove_call_out(funname) != -1);
+  call_out(funname,funname == "changeHp"?15:5);
+}
