Added public files
Roughly added all public files. Probably missed some, though.
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);
+}