diff --git a/std/player/base.c b/std/player/base.c
new file mode 100644
index 0000000..9c9a6e1
--- /dev/null
+++ b/std/player/base.c
@@ -0,0 +1,4355 @@
+// MorgenGrauen MUDlib
+//
+// player/base.c -- the basic player object
+//
+// $Id: base.c 9467 2016-02-19 19:48:24Z Zesstra $
+#pragma strong_types
+#pragma save_types
+#pragma range_check
+#pragma no_clone
+#pragma pedantic
+
+#include <sys_debug.h>
+#include <regexp.h>
+#include <input_to.h>
+#include <logging.h>
+#include <werliste.h>
+#include <time.h>
+#include <errord.h>
+#include <wizlevels.h>
+#include <money.h>
+
+inherit "/std/hook_provider";
+inherit "/std/player/restrictions";
+inherit "/std/living/attributes";
+inherit "/std/living/put_and_get";
+inherit "/std/living/clothing";
+inherit "/std/thing/properties";
+inherit "/std/player/util";
+inherit "/std/thing/language";
+inherit "/std/player/travel";
+inherit "/std/player/combat";
+inherit "/std/player/description";
+inherit "/std/player/moving";
+inherit "/std/player/life";
+inherit "/std/player/comm";
+inherit "/std/player/viewcmd";
+inherit "/std/player/moneyhandler";
+inherit "/std/player/command";
+inherit "/std/living/skill_attributes";
+inherit "/std/living/light";
+inherit "/std/player/skills";
+inherit "/std/player/quests";
+inherit "/std/player/potion";
+inherit "/std/player/soul";
+inherit "/std/more";
+inherit "/std/user_filter";
+inherit "/secure/telnetneg";
+inherit "/std/player/guide";
+inherit "/std/player/reputation";
+inherit "/std/player/protocols/gmcp";
+inherit "/std/living/helpers";
+
+#define NEED_PROTOTYPES
+#include <player/skills.h>
+#include <player/gmcp.h>
+#undef NEED_PROTOTYPES
+#include <player.h>
+#include <properties.h>
+#include <udp.h>
+#include <config.h>
+#include <ansi.h>
+#include <wizlevels.h>
+#include <living.h>
+#include <attributes.h>
+#include <language.h>
+#include <moving.h>
+#include <defines.h>
+#include <terminal.h>
+#include <new_skills.h>
+#include <pager.h>
+#include <combat.h>
+#include "/secure/questmaster.h"
+#include "/secure/lepmaster.h"
+#include <events.h>
+
+#undef NAME /* DEFINED BY UDP.H; BAD NAME CLASH :( */
+#define NAME(who) capitalize(getuid(who))
+
+mapping autoload;           /* autoload-mapping */
+int hc_play;
+
+private nosave mapping autoload_rest;
+private nosave string  *autoload_error;
+private nosave string realip; 
+
+private nosave string passw;        /* temporarily for password change */
+private nosave string passwold;     /* temporarily for password change */
+
+// HB-Zaehler. Wenn 0 erreicht wird, wird  ein Telnet TM Paket als Keep-Alive
+// an den Client gesendet und der Counter wieder auf hochgesetzt. 
+// Wenn == 0, ist das Keep-Alive abgeschaltet.
+private int telnet_tm_counter;
+
+nosave string default_home; /* Where to move us if we dont have a home set */
+
+nosave int ndead_lasttime;
+nosave mixed ndead_location;
+nosave string ndead_l_filename;
+nosave int ndead_currently;
+nosave int ndead_next_check;
+nosave object *hb_obs;
+
+private nosave string default_pray_room;
+
+nosave mixed env_ndead_info;
+
+static int _set_invis(int a);
+static string _set_tty(string str);
+static mixed _set_fraternitasdonoarchmagorum(mixed arg);
+
+
+static string al_to_title(int a);
+
+static void ndead_revive();
+
+static int wegmeldung(string player);
+
+int quit();
+void save_me(mixed value_items);
+varargs int remove(mixed arg);
+mixed RaceDefault(string arg);
+
+/** Setzt Defaultwerte vor dem Laden des Savefiles.
+    Nur die Werte bleiben spaeter uebrig, die NICHT aus dem Savefile geladen
+    werden und diese hier ersetzen.
+    Ausserdem kann man hier nicht mit den Werten aus den Savefiles arbeiten.
+    Hierzu muss man updates_after_restore() verwenden.
+*/
+protected void create()
+{
+  if(QueryProp(P_LEVEL)) 
+  {
+    return; // darf nur EINMAL gemacht werden
+  }
+  call_out("checkConsistency", 0);
+
+  ndead_next_check=NETDEAD_CHECK_TIME;
+  ndead_lasttime=0;
+  ndead_location=0;
+  ndead_l_filename=0;
+  ndead_currently=0;
+  ndead_next_check=0;
+  hc_play=0;
+  
+  command::create();
+  properties::create();
+  description::create();
+  light::create();
+  attributes::create();
+  clothing::create();
+  combat::create();
+  life::create();
+  comm::create();
+  viewcmd::create();
+  quests::create();
+  restrictions::create();
+  moving::create();
+  travel::create();
+  skills::create();
+   
+  SetProp(P_LEVEL, -1);
+  Set(P_LEVEL, SAVE|SECURED, F_MODE_AS);
+  Set(P_GHOST, SAVE, F_MODE_AS);
+  SetProp(P_SCREENSIZE, -1);
+  Set(P_SCREENSIZE, SAVE,F_MODE_AS);
+  Set(P_MORE_FLAGS, SAVE, F_MODE_AS);
+  SetProp(P_WEIGHT_PERCENT,100);
+  SetProp(P_LONG, 0);
+  SetProp(P_TITLE, "der hoffnungsvolle Anfaenger");
+  SetProp(P_ALIGN, 0);
+  SetProp(P_GENDER, NEUTER);
+  Set(P_GENDER, SAVE, F_MODE_AS);
+  SetProp(P_TTY, "vt100");
+  Set(P_TTY, SAVE, F_MODE_AS);
+  SetProp(P_WEIGHT, 75000);
+  SetProp(P_MAX_HP,50);
+  SetProp(P_MAX_SP,50);
+  SetProp(P_MAX_FOOD,100);
+  SetProp(P_MAX_DRINK,100);
+  SetProp(P_MAX_ALCOHOL,100);
+  Set( P_WIMPY, 20, F_VALUE);
+
+  SetProp(P_HANDS, ({" mit blossen Haenden", 30}));
+  Set(P_HANDS, SAVE, F_MODE_AS);
+  SetProp(P_MAX_HANDS, 2);
+
+  Set(P_MARRIED, SAVE, F_MODE_AS);
+  Set(P_EXTRA_LOOK, SAVE, F_MODE_AS);
+  Set(P_SHOW_EXITS, SAVE, F_MODE_AS);
+  Set(P_SHOW_EXITS, 1);
+  Set(P_WANTS_TO_LEARN, SAVE, F_MODE_AS);
+  Set(P_CAN_FLAGS, SAVE, F_MODE_AS);
+  Set(P_TESTPLAYER, SAVE|PROTECTED, F_MODE_AS);
+  Set(P_ALLOWED_SHADOW, SAVE|SECURED, F_MODE_AS);
+  Set(P_SECOND, SAVE, F_MODE_AS);
+  Set(P_INVIS, SAVE, F_MODE_AS);
+  Set(P_READ_NEWS, SAVE, F_MODE_AS);
+  Set(P_START_HOME, SAVE, F_MODE_AS);
+  Set(P_PRAY_ROOM, SAVE, F_MODE_AS);
+  Set(P_MAILADDR, SAVE, F_MODE_AS);
+  Set(P_HOMEPAGE, SAVE, F_MODE_AS);
+  Set(P_ICQ, SAVE, F_MODE_AS);
+  Set(P_MESSENGER, SAVE, F_MODE_AS);
+  Set(P_LOCATION, SAVE, F_MODE_AS);
+
+  Set(P_NO_ASCII_ART, SAVE, F_MODE_AS);
+
+  Set(P_VISUALBELL, SAVE, F_MODE_AS);
+  Set(P_CARRIED_VALUE, SAVE, F_MODE_AS);
+
+  Set(P_PROMPT, "> ");
+  Set(P_PROMPT, SAVE, F_MODE_AS);
+  Set(P_CALLED_FROM_IP, SAVE, F_MODE_AS);
+  Set(P_INFORMME,SAVE|PROTECTED,F_MODE_AS);
+  Set(P_WAITFOR,SAVE|PROTECTED,F_MODE_AS);
+  Set(P_WAITFOR_REASON,SAVE|PROTECTED,F_MODE_AS);
+  Set(P_DAILY_PLAYTIME,SAVE|PROTECTED,F_MODE_AS);
+  Set(P_NETDEAD_ENV, PROTECTED|NOSETMETHOD, F_MODE_AS);
+  
+  autoload = ([]);
+  autoload_rest = ([]);
+  autoload_error = ({});
+  SetProp(P_ARTICLE,0);
+  Set(P_GUILD,SAVE,F_MODE_AS);
+  Set(P_GUILD_TITLE,SAVE,F_MODE_AS);
+  Set(P_GUILD_LEVEL,SAVE,F_MODE_AS);
+  Set(P_GUILD_RATING,SAVE,F_MODE_AS);
+  Set(P_NEWSKILLS,SAVE,F_MODE_AS);
+  Set(P_NEEDED_QP,REQ_QP);
+  Set(P_DEADS,0);
+  Set(P_DEADS, NOSETMETHOD,F_SET_METHOD);
+  Set(P_DEADS,SAVE|PROTECTED|SECURED,F_MODE_AS);
+  Set(P_LAST_LOGIN,-1);
+  Set(P_LAST_LOGIN, NOSETMETHOD,F_SET_METHOD);
+  Set(P_LAST_LOGIN,SAVE|PROTECTED|SECURED,F_MODE_AS);
+  Set(P_LAST_LOGOUT,-1);
+  Set(P_LAST_LOGOUT, NOSETMETHOD,F_SET_METHOD);
+  Set(P_LAST_LOGOUT,SAVE|PROTECTED|SECURED,F_MODE_AS);
+  Set(P_CLOCKMSG,SAVE,F_MODE_AS);
+  Set(P_TIMEZONE,SAVE,F_MODE_AS);
+  Set(P_SHOWEMAIL,SAVE,F_MODE_AS);
+  Set(P_LAST_QUIT,SAVE|PROTECTED|SECURED,F_MODE_AS);
+
+  Set(P_CMSG, 0, F_MODE); // to clean out the old clone messages
+  Set(P_DMSG, 0, F_MODE);
+  Set(P_CLONE_MSG, SAVE, F_MODE);
+  SetProp(P_CLONE_MSG, "zaubert etwas hervor");
+  Set(P_DESTRUCT_MSG, SAVE, F_MODE);
+  SetProp(P_DESTRUCT_MSG, "verschwindet einfach");
+
+  Set(P_FAO, SAVE|SECURED, F_MODE_AS);
+  Set(P_FAO_PORTALS, SAVE, F_MODE_AS);
+
+  SetProp(P_NEWBIE_GUIDE,0);
+  Set(P_NEWBIE_GUIDE,SAVE,F_MODE_AS);
+
+  //TODO: Remove - Property ist not needed any more.
+  Set(P_TELNET_KEEP_ALIVE, PROTECTED|SAVE, F_MODE_AD);
+  SetProp(P_TELNET_KEEP_ALIVE, 0);
+
+  AddId("Interactive");
+
+  realip="";
+}
+
+// ACHTUNG: Falls hier mal sonst noch weitere Resets geerbt werden, muss das
+// hier ordentlich definiert werden!
+void reset() { 
+  comm::reset();
+  // momentan kann der Reset jetzt abgeschaltet werden, da er nur die
+  // TM-History loescht und ggf. von Netdead() und Disconnect() reaktiviert
+  // wird.
+  set_next_reset(-1);
+}
+
+protected void NotifyMove(object dest, object oldenv, int method)
+{
+  moving::NotifyMove(dest,oldenv,method);
+  // ggf. Daten ueber neues Env per GMCP senden.
+  if (dest != oldenv)
+    GMCP_Room();
+}
+
+string Forschung()
+{
+  return LEPMASTER->QueryForschung();
+}
+
+/** Setzt Defaultwerte fuer Rassen - wird von den Shells ueberschrieben.
+*/
+mixed RaceDefault(string arg)
+{
+  if (!arg)
+    return 0;
+  switch(arg)
+  {
+    case P_HANDS :
+      return ({" mit blossen Haenden",30,DT_BLUDGEON});
+    case P_BODY :
+      return 0;
+  }
+  return 0;
+}
+
+/** Prueft Spielerobjekt auf Konsistenz.
+  Ueberprueft das Spielerobjekt nach kompletter Initialisierung (im 
+  callout) auf korrekte Werte einiger Props.
+*/
+void checkConsistency()
+{ mixed h;
+  int   m;
+
+  if (pointerp(h=RaceDefault(P_HANDS)) && sizeof(h)>1)
+    m=(int)h[1];
+  else
+    m=30;
+  if((h=Query(P_HANDS))[1] > m && !IS_LEARNER(this_object())) {
+    log_file("inconsistent", sprintf(
+      "[%s] %O: HANDS: %d\n", dtime(time()), this_player(), h[1]));
+    h[1] = m;
+    Set(P_HANDS,h);
+  }
+
+  if (Query(P_BODY)!=(m=RaceDefault(P_BODY)))
+     Set(P_BODY,m);
+
+  if (!Query(P_SECOND_MARK,F_MODE))
+    Set(P_SECOND_MARK,SAVE|PROTECTED,F_MODE_AS);
+  if (!Query(P_TTY_SHOW,F_MODE)&SAVE)
+  {
+    Set(P_TTY_SHOW,0,F_VALUE);
+    Set(P_TTY_SHOW,SAVE,F_MODE_AS);
+  }
+  if (Query(P_TTY_COLS,F_MODE)&SAVE)
+  {
+    Set(P_TTY_COLS,SAVE,F_MODE_AD);
+    Set(P_TTY_ROWS,SAVE,F_MODE_AD);
+    Set(P_TTY_TYPE,SAVE,F_MODE_AD);
+  }
+}
+
+/** Bittet das Spielerobjekt, sich zu zerstoeren.
+  \param[in] silent Flag, ob ohne Textausgaben zerstoert werden soll
+  \return Erfolg der Selbstzerstoerung
+*/
+varargs int remove(int silent)
+{
+  return moving::remove(silent);
+}
+
+/** Schaltet in allen Objekten im Inv HBs aus.
+  Schaltet im Inv in allen Objekten (rekursiv, deep_inventory)
+  die Heartbeats aus. Falls obs uebergeben wird, werden diese Objekte
+  statt des Inventars benutzt.
+  Speichert die Objekte, die einen HB hatten, in der glob. Var. hb_obs.
+  @param[in] obs mixed - Objekte, in denen der HB abgeschaltet werden soll. 
+    Container werden rekursiv behandelt.
+  @attention Achtung! Niemals zweimal hintereinander rufen, ohne 
+    zwischendurch restart_heart_beats() gerufen zu haben!
+  @sa restart_heart_beats
+*/
+varargs static void stop_heart_beats(mixed obs)
+{
+  int i;
+
+  if (!obs)
+  {
+    hb_obs=({});
+    obs=deep_inventory(ME);
+  } 
+  foreach(mixed ob: obs) {
+    if (pointerp(ob))
+        stop_heart_beats(ob);
+    else if (set_object_heart_beat(ob,0))  
+        hb_obs+=({ob});
+  }
+}
+
+/** Schaltet HBs in Objekten im Inv wieder ein.
+  Schaltet in allen Objekten in hb_obs den Heartbeat ein.
+    In hb_obs (glob. Var.) stehen alle Objekte, die beim letzten Aufruf von
+    stop_heart_beats() einen HB hatten.
+  @sa stop_heart_beats
+*/
+static void restart_heart_beats()
+{
+  int i;
+
+  if (pointerp(hb_obs))
+  {
+    foreach(object ob: hb_obs)
+      set_object_heart_beat(ob,1);
+    hb_obs=0;
+  }
+}
+
+/** Prueft auf abgelaufene Spielzeit.
+  Prueft in Spielerobjekten, ob die taegliche Maximalspielzeit
+    abgelaufen ist.
+    Wird im heart_beat() gerufen.
+  @return int - Flag, ob Spielzeit abgelaufen und Logout erfolgen soll
+*/
+static int CheckDailyPlaytime() {
+  int *spieldauer,d;
+
+  if (!pointerp(spieldauer=Query(P_DAILY_PLAYTIME)))
+    return 0;
+  // 0:Minuten pro Tag, 1:Nr. des letzen Tages, 2:Nr. des angefangenen Tages,
+  // 3:letzte Zeitpruefung, 4:verbleibende Zeit
+  d=time()/86400;
+  if (spieldauer[1]<=d) { // Ende der zeitbeschraenkten Tage?
+    Set(P_DAILY_PLAYTIME,0);
+    return 0;
+  } else if (spieldauer[2]!=d) { // Neuer Tag?
+    spieldauer[4]=spieldauer[0];
+    spieldauer[2]=d;
+  } else {
+    spieldauer[4]-=(time()-spieldauer[3]);
+  }
+  spieldauer[3]=time();  // Letzte Zeitpruefung
+  Set(P_DAILY_PLAYTIME,spieldauer);
+  if (spieldauer[4]<0) { // Keine Zeit mehr uebrig fuer heute
+    if (!interactive(ME))
+      return 1;
+    write("Du hast lange genug gemuddet fuer heute.\n");
+    say(Name(WER)+" hat fuer heute genug gemuddet.\n");
+    remove_interactive(ME);
+    return 1;
+  }
+  return 0;
+}
+
+/** Gibt Erwartemeldung mit Grund aus.
+  @param[in] who   string - Wer ist hereingekommen?
+  @param[in] invis int - Ist der Spieler Invis?
+*/
+static void Show_WaitFor_Reason(string who, int invis)
+{
+  mixed list;
+  string reason,name;
+
+  if (invis) name="("+who+")";
+    else name=who;
+  if ((mappingp(list=QueryProp(P_WAITFOR_REASON))) && (reason=list[who]))
+    tell_object(ME,sprintf("\nDu erwartest %s wegen:\n%s\n",name,reason));
+  else
+    tell_object(ME,sprintf("Du erwartest %s aus keinem bestimmten Grund.\n",
+      name));
+}
+
+/** Gibt Liste der Erwarteten Spieler an this_player() aus.
+*/
+static void ListAwaited() //Anwesende Erwartete auflisten
+{
+    string *list;
+    mixed mlist;
+    object ob;
+    int mag;
+
+    mag=IS_LEARNER(ME);
+
+    list=({});
+    foreach(string erwartet : QueryProp(P_WAITFOR)) {
+        if (objectp(ob=find_player(lower_case(erwartet)))) {
+            if (ob->QueryProp(P_INVIS)) {
+                if (mag) list+=({ sprintf("(%s)",erwartet) });
+            }
+            else list+=({erwartet});
+        }
+    }
+    if (sizeof(list))
+        printf("Anwesende Erwartete: %s.\n",
+            CountUp(sort_array(list,#'>)));
+
+    if ((mappingp(mlist=QueryProp(P_WAITFOR_REASON))) && (sizeof(mlist)))
+        {
+          foreach(string erwartet : mlist) {
+                if (!(ob=find_player(lower_case(erwartet))) ||
+                    (!mag && ob->QueryProp(P_INVIS)));
+                else Show_WaitFor_Reason(erwartet,ob->QueryProp(P_INVIS));
+          }
+        }
+}
+/** Teilt den Gilden und anderen Spielern mit, wer reingekommen ist.
+  Ausserdem wird ggf. PlayerQuit() im Environment gerufen.
+  \param[in] rein int - wahr, wenn der Spieler einloggt.
+*/
+protected void call_notify_player_change(int rein)
+{
+  string wer = getuid(ME);
+  // erst die Gilde informieren
+  string gilde = QueryProp(P_GUILD);
+  if (stringp(gilde) && (find_object("/gilden/"+gilde)
+        || file_size("/gilden/"+gilde+".c")>0))
+    catch(("/gilden/"+gilde)->notify_player_change(ME, rein); publish);
+
+  // dann die anderen Spieler
+  int mag = IS_LEARNER(ME);
+  int invis = QueryProp(P_INVIS);
+  object *u = users() - ({ME}); // sich selber nicht melden 
+  if (mag && invis) {   // Invismagier nur Magiern melden
+    u = filter(u, function int (object o)
+        { return query_wiz_level(o) >= LEARNER_LVL; }
+        );
+  }
+  u->notify_player_change(capitalize(wer),rein,invis);
+
+  // und beim Ausloggen noch das Env informieren.
+  if (!rein) {
+    if(environment()) catch(environment()->PlayerQuit(ME);publish);
+  }
+}
+
+/** Ruft im uebergebenen Objekt ein init() auf, sofern notwendig.
+  Ruft in ob ein init() auf, falls das Objekt nach dem
+    letzten Ausloggen geschaffen wurde.
+  \param[in] ob object - Objekt, in dem init() gerufen wird.
+  \param[in] logout int - Letzter Logout
+  \return 1, falls init() gerufen wurde. 0 sonst.
+*/
+static int call_init( object ob, int logout )
+{
+    if ( objectp(ob) && object_time(ob) > logout )
+        return catch(ob->init(); publish), 1;
+    return(0);
+}
+
+/** Holt seit dem letzten Ausloggen ausgefallene Inits nach.
+  Ruft in den uebergebenen Objekten call_init(), was einen init()
+  ausloest, falls das Objekt seit dem letzten Ausloggen erstellt wurde.
+  \param[in] logout Zeitpunkt des letzten Logouts
+  \param[in] obs Array von Objekten
+  \sa call_init()
+*/
+static void inits_nachholen( int logout, object *obs )
+{
+    filter( obs, "call_init", ME, logout );
+}
+
+/** Belebt einen Netztoten wieder.
+  Wird im Login gerufen, wenn der Spieler netztot war. Aequivalent zu
+  start_player()
+  @param[in] silent Wenn Flag gesetzt, werden keine Meldung an den Raum
+  ausgegeben.
+  @param[in] ip Textuelle Repraesentation der IP-Adresse, von der der Spieler
+  kommt.
+  @see start_player()
+*/
+varargs void Reconnect( int silent )
+{
+    int num;
+    string called_from_ip;
+    object *inv;
+
+    if ( query_once_interactive(ME) )
+    {
+        // perform the telnet negotiations. (all that are available)
+        "*"::startup_telnet_negs();
+        Set( P_LAST_LOGIN, time() );
+    }
+
+    enable_commands();
+    set_living_name( getuid() );
+    _remove_netdead();
+    set_heart_beat(1);
+    // Hunttimes aktualisieren und ggf. Feinde vergessen.
+    update_hunt_times((time()-QueryProp(P_LAST_LOGOUT)) /__HEART_BEAT_INTERVAL__);
+    // Heartbeats in Objekten im Inv reaktiveren.
+    restart_heart_beats();
+    // life.c will ggf. was aufraeumen
+    life::reconnect();
+
+    log_file( "REENTER", sprintf( "%-11s %s, %-15s (%s).\n",
+                                  capitalize(getuid(ME)), ctime(time())[4..15],
+                                  query_ip_number(ME)||"Unknown",
+                                  query_ip_name(ME)||"Unknown" ),
+              200000 );
+
+    if ( ndead_currently )
+        ndead_revive();
+
+    if ( !silent && interactive(ME) )
+        call_notify_player_change(1);
+
+    command::reconnect();
+    if ( query_once_interactive(ME) )
+        modify_prompt();
+
+    // Login-event ausloesen
+    EVENTD->TriggerEvent(EVT_LIB_LOGIN, ([
+          E_OBJECT: ME,
+          E_PLNAME: getuid(ME),
+          E_ENVIRONMENT: environment() ]) );
+
+    catch( num = "secure/mailer"->FingerMail(geteuid());publish );
+
+    if ( num )
+        write( "Du hast " + num + " neue" + (num == 1 ? "n Brief" : " Briefe")
+               + " im Postamt liegen.\n" );
+
+    if ( QueryProp(P_AWAY) )
+        write( break_string( "Du bist als abwesend gekennzeichnet: " +
+                             QueryProp(P_AWAY) + ".", 78 ) );
+
+    catch( RegisterChannels(); publish );
+
+    if ( (called_from_ip = Query(P_CALLED_FROM_IP)) &&
+         query_ip_number(ME) != called_from_ip ) {
+        string tmp;
+
+        if ( stringp(tmp = query_ip_name(called_from_ip)) &&
+             tmp != called_from_ip )
+            tmp = " [" + tmp + "]";
+        else
+            tmp = "";
+
+        write( "Das letzte Mal kamst Du von " + called_from_ip + tmp + ".\n" );
+    }
+
+    Set( P_CALLED_FROM_IP, query_ip_number(ME) );
+
+    // falls Gegenstaende mit 'upd -ar' upgedated wurden, muessen die
+    // "verloren gegangenen" init()'s nachgeholt werden
+    if ( query_once_interactive(ME) && !IS_LEARNER(ME) )
+        call_out( "inits_nachholen", 0, Query(P_LAST_LOGOUT),
+                  all_inventory(ME) );
+
+    // noch nicht geclonte Autoloader "nach"clonen
+    while ( remove_call_out("load_auto_objects") != -1 )
+        /* do nothing */;
+
+    if ( sizeof(autoload_rest) )
+        call_out( "load_auto_objects", 0, autoload_rest );
+
+    if (ndead_location) {
+      catch( ndead_location->BecomesNetAlive(ME);publish );
+      inv = all_inventory(ndead_location);
+      ndead_location = 0;
+    }
+    else
+      inv = ({});
+
+    inv += deep_inventory(ME);
+
+    //ZZ foreach statt call_other(), damit nen bug in BNA nicht die anderen
+    //BNA verhindert.
+    foreach(object ob: inv) {
+        //es ist nicht auszuschliessen, dass Items durch BecomesNetAlive()
+        //eines anderen zerstoert werden.
+        if (objectp(ob))
+          catch( call_other(ob, "BecomesNetAlive", ME);publish );
+    }
+
+    // Erst an dieser Stelle, weil der Spieler u.U. durch ein BecomesNetAlive()
+    // noch bewegt wurde.
+    if ( !silent && environment() && object_name(environment()) != NETDEAD_ROOM )
+    {
+        if(query_hc_play()<=1)
+          tell_room(environment(),QueryProp(P_NAME) + " weilt wieder unter den Lebenden.\n",({ME}) );
+        else 
+          tell_room(environment(),QueryProp(P_NAME) + " weilt wieder unter den Verstorbenen.\n",({ME}) );
+    }
+
+    NewbieIntroMsg();
+
+    if ( query_once_interactive(ME) )
+        ListAwaited();
+}
+
+/** Loggt einen Spieler aus und macht ihn netztot.
+  Bewegt einen Spieler in den Netztotenraum, deaktiviert Heartbeats im
+  Inventar, ruft BecomesNetDead(), loest Erwartemeldungen aus, triggert
+  Ausloggevent.
+*/
+void NetDead()
+{
+  object *inv;
+  int num;
+
+  catch(RemoveChannels();publish);
+
+  if(query_hc_play()>1)
+    say("Ploetzlich weicht alle spirituelle Energie aus "+QueryProp(P_NAME)+".\n");
+  else
+    say("Ploetzlich weicht alles Leben aus "+QueryProp(P_NAME)+".\n");
+
+  _set_netdead();
+  remove_call_out("quit");
+  remove_living_name();
+  // Wird zwar im save_me() gemacht, aber die Zeitunterschiede beim
+  // fingern direkt nach dem Ausloggen fuehren immer wieder zu Verwirrungen
+  if(query_once_interactive(ME) && !QueryProp(P_INVIS))
+      Set(P_LAST_LOGOUT,time());
+  if (ME)
+    ndead_location = environment();
+
+  if (query_once_interactive(ME))
+    call_notify_player_change(0);
+
+  // Logout-event ausloesen
+  EVENTD->TriggerEvent(EVT_LIB_LOGOUT, ([
+          E_OBJECT: ME,
+          E_PLNAME: getuid(ME),
+          E_ENVIRONMENT: environment() ]) );
+
+  set_next_reset(900);
+  /* Bei Nicht-Magier-Shells wird comm::reset() aufgerufen, das prueft, ob
+     der Spieler immer noch netztot ist, und falls ja, die tmhist loescht.
+     Die Methode wird von /std/shells/magier.c ueberschrieben, netztote
+     Magier (die eigentlich schon anderweitig beseitigt worden sein sollten)
+     werden remove()d und destruct()ed. --Amynthor 05.05.2008 */
+
+  if (environment()) {
+    catch(environment()->BecomesNetDead(ME);publish);
+    inv = deep_inventory(ME)+all_inventory(environment());
+  }
+  else inv=deep_inventory(ME);
+  foreach(object ob: inv) {
+      if (objectp(ob)) //man weiss nie was BND() macht...
+          catch( call_other(ob, "BecomesNetDead", ME);publish );
+  }
+}
+
+
+/** Sendet ggf. Telnet Timing Marks als Keep-Alive Pakete an den Client.
+  * Wird in heart_beat() gerufen.
+  * @return 1, falls der Spieler Keep-Alive Paket wuenscht, sonst 0. 
+  * @see heart_beat()
+*/
+protected int CheckTelnetKeepAlive() {
+  if (telnet_tm_counter > 0) {
+    // Spieler hat offenbar ein Keep-Alive konfiguriert ...
+    if (!(--telnet_tm_counter)) {
+      // und das Intervall ist gerade abgelaufen.
+      // Prop offenbar gesetzt, FEature ist wirklich gewuenscht,
+      // Telnet Timing Mark senden 
+      send_telnet_timing_mark();
+      // alle 120 HBs (240s, 4min).
+      // sollte eigentlich 240 / __HEART_BEAT_INTERVAL__ sein. Aber spart
+      // eine Operation im HB. ;-)
+      telnet_tm_counter = 120;
+    }
+    return 1; // Keep-Alive ist eingeschaltet
+  }
+  return 0;
+}
+
+static void ndead_move_me();
+
+/** Heartbeat des Spielerobjektes.
+  Prueft taegliche Spielzeit, speichert regelmaessig den Spieler,
+  bewegt Netztote in den Netztodenraum, ruft die HBs aus living/combat und
+  player/life.
+*/
+protected void heart_beat() {
+  if (!ME)
+    return;
+  if (ndead_currently)
+  {
+    if (interactive(ME))
+    {
+      ndead_revive();
+      ndead_location=0;
+    }
+    else return;
+  }
+  else
+    if (!(ndead_next_check--))
+    {
+      ndead_next_check=NETDEAD_CHECK_TIME;
+      if (!interactive(ME))
+        if (ndead_lasttime)
+        {
+          save_me(1);
+          if (IS_LEARNER(ME))
+          {
+            quit();
+            if (ME)
+              remove();
+            if (ME)
+              destruct(ME);
+            return;
+          }
+          ndead_move_me();
+          // Zumindest bei Gaesten ist das Objekt jetzt zerstoert
+          if (!objectp(this_object()))
+            return;
+        }
+        else
+          ndead_lasttime=1;
+    }
+  if (ME && ndead_lasttime && interactive(ME))
+    ndead_lasttime=0;
+  if (CheckDailyPlaytime())
+    return;
+
+  CheckTelnetKeepAlive();
+
+  life::heart_beat();
+  combat::heart_beat();
+  skills::heart_beat();
+}
+
+/** ID-Funktion fuer Spielerobjekte.
+ * id() fuer Spieler. Besondere Behandlung fuer Froesche und Geister,
+ * sowie Invis-Status.
+ * Gibt immer 0 zurueck, wenn P_INVIS && lvl < P_LEVEL
+ * @param[in] str angefragter ID-String
+ * @param[in] lvl Level des Anfragenden
+ * @return 1, falls str auf den Spieler zutrifft, 0 sonst.
+ */
+varargs int id(string str, int lvl)
+{
+  if (::id(str))
+    return 1;
+  if (Query(P_INVIS) && lvl < QueryProp(P_LEVEL))
+    return 0;
+  if (QueryProp(P_GHOST)&& str == "geist von "+ lower_case(QueryProp(P_NAME)))
+    return 1;
+  if (QueryProp(P_FROG) && str == "frosch") return 1;
+  return(0);
+}
+
+/** Setzt Spielerhomepage (Spielerkommando).
+  * @param[in] str Spielereingabe
+  * @return 1 bei Erfolg, 0 sonst.
+  */
+static int set_homepage(string str)
+{
+  mixed tmp;
+  if (!(str=_unparsed_args())) {
+    if (!QueryProp(P_HOMEPAGE))
+      write("Du hast keine URL-Adresse gesetzt!\n");
+    else
+      write("Deine offizielle URL-Adresse lautet: " + QueryProp(P_HOMEPAGE)
+            +"\n");
+    return 1;
+  }
+  write("Deine offizielle URL-Adresse wurde geaendert.\n");
+  if (str=="keine") 
+    SetProp(P_HOMEPAGE, 0);
+  else {
+    tmp = filter(regexplode(str, "[<][^>]*[>]"),
+                       lambda(({'e}), ({#'!=, ({#'[, 'e, 0}), '<'})));
+    write("Sie lautet jetzt: "+(str = implode(tmp, ""))+"\n");
+    SetProp(P_HOMEPAGE, str);
+  }
+  return 1;
+}
+
+/** Setzt Spieler-Wohnort (Spielerkommando).
+  * \param[in] str Spielereingabe
+  * \return 1 bei Erfolg, 0 sonst.
+  */
+static int set_location( string str )
+{
+    mixed ort;
+
+    if ( str == "0" || str == "loeschen" ){
+        Set( P_LOCATION, 0 );
+        write( "Du loescht Deine Ortsangabe.\n" );
+        return 1;
+    }
+
+    if ( stringp(str = _unparsed_args()) && str != "" ){
+        Set( P_LOCATION, capitalize(str) );
+        printf( "Du aenderst Deine Ortsangabe auf \"%s\".\n",
+                Query(P_LOCATION) );
+    }
+    else if ( stringp(ort = Query(P_LOCATION)) )
+        printf( "Deine Ortsangabe lautet \"%s\".\n", Query(P_LOCATION) );
+    else{
+        Set( P_LOCATION, 0, F_VALUE );
+        write( "Du hast keine Ortsangabe gesetzt.\n" );
+    }
+
+    return 1;
+}
+
+/** Setzt ICQ-UIN des Spielers (Spielerkommando).
+  * \param[in] str Spielereingabe
+  * \return 1 bei Erfolg, 0 sonst.
+  */
+static int set_icq(string str) {
+  int num;
+
+  if (!str || str=="") {
+    if (!num=QueryProp(P_ICQ))
+      write("Du hast keine ICQ-Nummer gesetzt!\n");
+    else
+      printf("Deine ICQ-Nummer lautet: %d\n",num);
+    return 1;
+  }
+  if (sscanf(str,"%d",num)!=1 || !num) {
+    write("Deine ICQ-Nummer wurde geloescht.\n");
+    SetProp(P_ICQ, 0);
+  } else {
+    write("Deine ICQ-Nummer wurde geaendert.\n");
+    printf("Sie lautet jetzt: %d\n",num);
+    SetProp(P_ICQ, num);
+  }
+  return 1;
+}
+
+/** Setzt Instant Messanger vom Spieler (Spielerkommando).
+  * \param[in] str Spielereingabe
+  * \return 1 bei Erfolg, 0 sonst.
+  */
+static int set_messenger(string str) {
+  int num;
+  string s;
+
+  if (!str || str=="") {
+    if (!s=QueryProp(P_MESSENGER))
+      if (!num=QueryProp(P_ICQ)) 
+        write("Du hast keine Messenger-ID gesetzt.\n");
+      else 
+        printf("Du hast keine Messenger-ID gesetzt, aber eine ICQ-Nummer: %d\n", num);
+    else
+      printf("Deine Messenger-ID lautet: %s\n", s);
+    return 1;
+  }
+  if (str=="loeschen" || str=="keine") {
+    write("Deine Messenger-ID wurde geloescht.\n");
+    SetProp(P_MESSENGER, 0);
+  } else {
+    s = _unparsed_args();
+    printf("Deine Messenger-ID lautet nun: %s\n", s);
+    SetProp(P_MESSENGER, s);
+  }
+  return 1;
+}
+
+
+// Prueft, ob der String vermutlich eine eMail-Adresse ist.
+// dies ist nicht narrensicher, wird aber die meisten eMail-Adressen zulassen
+// und viel Schrott ablehnen.
+private string check_email(string str) {
+  if (!stringp(str)) return 0;
+  return regmatch(lower_case(str),
+      "[a-z0-9._%+-]+@(?:[a-z0-9-]+\.)+[a-z]{2,4}",RE_PCRE);
+}
+
+/** Setzt Email-Adresse des Spielers (Spielerkommando).
+  * \param[in] str Spielereingabe
+  * \return 1 bei Erfolg, 0 sonst.
+  */
+static int set_email(string str)
+{
+  if (!(str=_unparsed_args())) {
+    write("Deine offizielle Email-Adresse lautet: " + QueryProp(P_MAILADDR)
+          +"\n");
+    return 1;
+  }
+  str = check_email(str);
+  if (!str) {
+    notify_fail("Deine Eingabe scheint keine gueltige EMail-Adresse "
+        "zu sein.\n");
+    return 0;
+  }
+  write("Deine EMail-Adresse wurde geaendert zu:\n"
+      +str+"\n");
+  SetProp(P_MAILADDR, str);
+  return 1;
+}
+
+/** Spielerkommando 'selbstloeschung'.
+  * Gibt Meldung aus und fragt nach einer Bestaetigung.
+  * \return 1 bei Erfolg, 0 sonst.
+  */
+static int self_delete()
+{
+  write(
+    "     B I S T  D U  D I R  W I R K L I C H  S I C H E R ????????????\n"+
+    "Wenn Du Dich selbstloeschen willst, ist Dein Charakter UNWIDERRUFLICH\n"+
+    "verloren. Es gibt KEINE Moeglichkeit ihn wiederzuerschaffen. Solltest\n"+
+    "Du nur zeitweilig vom "MUDNAME" wegbleiben wollen, so benutze bitte\n"+
+    "den Befehl 'spielpause'.\n"+
+    "Fallst Du Dich immer noch selbstloeschen willst, gib Dein Password ein."+
+    "\n\n");
+  input_to("self_delete2",INPUT_PROMPT|INPUT_NOECHO, "Bitte das Password angeben: ");
+  return 1;
+}
+
+/** Spielerkommando 'selbstloeschung'.
+  * Empfaengt Bestaetigung des Spielers und ruft Loeschfunktion in 
+  * /secure/master auf.
+  * \param[in] str Spielereingabe
+  * \return 1 bei Erfolg, 0 sonst.
+  */
+int self_delete2(string str)
+{
+  int ret;
+  ret=(int)"secure/master"->delete_player(str, getuid(PL));
+  if (!ret)
+  {
+    write("Das hat nicht hingehauen (Gott sei Dank ....)\n");
+    return 1;
+  }
+  if (QueryProp(P_GUILD)&&file_size(GUILD_DIR+QueryProp(P_GUILD)+".c")>-1)
+    catch(call_other(GUILD_DIR+QueryProp(P_GUILD), "austreten");publish);
+
+  if (QueryProp(P_DEADS) < 5) {
+    write("Adios! Man sieht sich.\n");
+    say(name(WER,1)+" hat sich gerade selbst zerstoert.\n");
+  }
+  else {
+    write(
+      "\nTod kommt auf seinem weissen Pferd angeritten.\n"
+     +"Er steigt ab, baut sich drohend vor Dir auf und mustert Dich schadenfroh.\n"
+     +"\nTod sagt: ENDLICH! NUN KANN DIR AUCH LARS NICHT MEHR HELFEN!\n"
+     +"\nTod holt weit mit seiner Sense aus. Mit grossem Schwung laesst er sie auf\n"
+     +"Dich zusausen und dann...\n");
+    say(name(WER,1)+" schied gerade endgueltig von uns.\n");
+  }
+
+  // Event ausloesen. ;-)
+  EVENTD->TriggerEvent(EVT_LIB_PLAYER_DELETION, ([
+        E_PLNAME: getuid(ME),
+        E_ENVIRONMENT: environment(),
+        E_GUILDNAME: QueryProp(P_GUILD) ]) );
+
+  remove(1);
+  return 1;
+}
+
+/** Setzt neue taegliche Spieldauer (Spielerkommando).
+  * \param[in] str Spielereingabe
+  * \return 1 bei Erfolg, 0 sonst.
+  */
+static int spieldauer(string str) {
+  int min,day;
+  string foo;
+
+  notify_fail("  spieldauer <x> minuten fuer %d tage\noder\n"+
+              "  spieldauer <x> stunden fuer %d tage\n");
+  if (!str)
+    return 0;
+  if (sscanf(str,"%d stunde%s fuer %d tag%s",min,foo,day,foo)==4)
+    min*=60;
+  else if (sscanf(str,"%d minute%s fuer %d tag%s",min,foo,day,foo)!=4)
+    return 0;
+  if (min<5)
+    min=5;
+  if (min>=1440)
+    return notify_fail("Witzbold.\n"),0;
+
+  Set(P_DAILY_PLAYTIME,
+      ({min*60,time()/86400+day,time()/86400,time(),min*60}));
+  // 0:Minuten pro Tag, 1:Nr. des letzen Tages, 2:Nr. des angefangenen Tages,
+  // 3:letzte Zeitpruefung, 4:verbleibende Zeit
+  printf("Du darfst die naechsten %d Tag(e) nur noch\n"+
+   "%d Minuten am Tag mudden.\n",day,min);
+  return 1;
+}
+
+/** Interpretiert Angabe des Spielers fuer Spielpause.
+  * \param[in] a Zeitangabe fuer Spielpause.
+  * \return Zeitpunkt, Ende der Spielpause.
+  */
+private int InterpretTime(string a){
+  // akzeptiert folgende Formate:
+  //   dd.mm.jj     (Rueckgabe: 0:00 des entsprechenden Tages)
+
+  int *ts = allocate(9);
+  int i,j,k,nrargs;
+
+  if ((nrargs=sscanf(a,"%d.%d.%d",i,j,k))==3 ||
+      (nrargs=sscanf(a,"%d.%d.",i,j))==2) {
+    // wenn kein jahr angegeben ist, das aktuelle nehmen.
+    if (nrargs == 2)
+       ts[TM_YEAR] = localtime()[TM_YEAR];
+    else {
+       // Zwei-Ziffern-Angabe des Jahres...
+       if (k<100)
+           k += 2000;
+       ts[TM_YEAR] = k;
+    }
+    ts[TM_MDAY] = i;
+    ts[TM_MON] = j - 1;
+
+    int zeit = mktime(ts);
+
+    // negative und vergangene Zeiten pruefen.
+    if (zeit <= time()) {
+      write("Dieser Zeitpunkt liegt in der Vergangenheit.\n");
+      return 0;
+    }
+    return zeit;
+  }
+  return 0;
+}
+
+/** Setzt neue Spielpause (Spielerkommando).
+  * Fragt vorher nach Bestaetigung durch den Spieler.
+  * \param[in] str Spielereingabe
+  * \return 1 bei Erfolg, 0 sonst.
+  * \sa spielpause2()
+  */
+static int spielpause(string str)
+{
+  int days,endezeit;
+  string foo;
+
+  notify_fail("spielpause <x> tage          oder\n"+
+              "spielpause bis tt.mm[.jj]\n");
+  if (!str) return 0;
+  if(sscanf(_unparsed_args(),"bis %s",foo)==1) {
+    endezeit = InterpretTime(foo);
+    if (endezeit == 0) 
+        return 0;
+    days = ((endezeit - time()) / 86400) + 1;
+  }
+  else if(sscanf(str, "%d tag%s", days, foo) == 2) {
+    if (days < 0)
+        days = -1;
+    else
+        endezeit = (time()/86400) * 86400 + days * 86400;
+  }
+  else return 0;
+
+  if (days > 0)
+    write(strftime("Du wirst Dich erst wieder am %d.%m.%Y einloggen koennen!\n",
+          endezeit));
+  else if (days < 0)
+    write( "Du wirst Dich auf unbestimmte Zeit nicht mehr einloggen koennen.\n"
+          +"Wenn Du wieder spielen willst, musst Du Dich an einen Gott oder\n"
+          +"Erzmagier wenden (mit einem Gast oder Mail von aussen).\n" );
+  else {
+    write( "Die Spielpause ist aufgehoben.\n" );
+    master()->TBanishName(getuid(this_object()), 0);
+    return 1;
+  }
+  write( "Wenn Du das wirklich willst, gib jetzt 'ja' ein.\n" );
+  input_to( "spielpause2", INPUT_PROMPT, "]", days);
+  return 1;
+}
+
+/** Setzt neue taegliche Spieldauer, wird ueber spielpause() gerufen.
+  * \param[in] str Spielereingabe, Bestaetigung
+  * \param[in] days Dauer der Spielpause (in Tagen).
+  * \sa spielpause()
+  */
+static void spielpause2(string str, int days)
+{
+  if (str && (str == "ja" || str == "Ja" || str == "JA")) {
+    master()->TBanishName(getuid(this_object()), days);
+    write(
+      "Ok, die Spielpause wird mit dem naechsten Ausloggen wirksam.\n"
+     +"Solltest Du es Dir bis dahin noch einmal ueberlegt haben, so kannst\n"
+     +"Du den Vorgang mit 'spielpause 0 tage' wieder rueckgaengig machen.\n" );
+    return;
+  }
+  write("Vorgang wurde abgebrochen.\n" );
+}
+
+/** Setzt neues Passwort (Spielerkommando).
+  * Fragt nach altem Passwort und ruft change_password2().
+  * \return 1 bei Erfolg, 0 sonst.
+  * \sa change_password2(), change_password3(), change_password4()
+  */
+static int change_password() {
+  string verb;
+  verb=query_verb();
+  if (verb!="passwd"&&verb!="password"&&verb!="passwort")
+    return 0;
+  input_to("change_password2",INPUT_NOECHO|INPUT_PROMPT,
+      "Bitte das ALTE Passwort angeben: ");
+  return 1;
+}
+
+/** Setzt neues Passwort (Spielerkommando).
+  * Prueft altes Passwort, fragt nach neuem Passwort und ruft 
+  *   change_password3().
+  * \param[in] str Spielereingabe des alten Passwortes
+  * \return 1 bei Erfolg, 0 sonst.
+  * \sa change_password(), change_password3(), change_password4()
+  */
+static int change_password2(string str) {
+  write("\n");
+  if (!str)
+    str="";
+  if (MASTER->update_password(str,str) == 0) {
+    write("Falsches Passwort!\n");
+    return 1;
+  }
+  passwold = str;
+  input_to("change_password3",INPUT_NOECHO|INPUT_PROMPT,
+      "Bitte das NEUE Passwort eingeben: ");
+  return 1;
+}
+
+/** Setzt neues Passwort (Spielerkommando).
+  * Prueft neues Passwort, fragt nach Bestaetigung des neues
+  * Passwortes und ruft change_password4().
+  * \param[in] str Spielereingabe des neuen Passwortes
+  * \return 1 bei Erfolg, 0 sonst.
+  * \sa change_password(), change_password2(), change_password4()
+  */
+static int change_password3( string str )
+{
+    write( "\n" );
+
+    if ( !str || str == "" ){
+        write( "Abgebrochen !\n" );
+        passwold = passw = 0;
+        return 1;
+    }
+
+    if ( passwold == str ){
+        write( "Das war Dein altes Passwort.\n" );
+        input_to( "change_password3", INPUT_NOECHO|INPUT_PROMPT,
+            "Bitte das NEUE Passwort eingeben (zum Abbruch Return druecken): ");
+        return 1;
+    }
+
+    if ( !MASTER->good_password( str, getuid(ME) ) ){
+        input_to( "change_password3", INPUT_NOECHO|INPUT_PROMPT,
+            "Bitte das NEUE Passwort eingeben: ");
+        return 1;
+    }
+
+    passw = str;
+    input_to( "change_password4", INPUT_NOECHO|INPUT_PROMPT,
+        "Bitte nochmal: ");
+    return 1;
+}
+
+/** Setzt neues Passwort (Spielerkommando).
+  * Prueft neues Passwort und setzt neues Passwort.
+  * \param[in] str Spielereingabe des neuen Passwortes
+  * \return 1 bei Erfolg, 0 sonst.
+  * \sa change_password(), change_password2(), change_password3()
+  */
+static int change_password4( string str )
+{
+    write( "\n" );
+
+    if ( !str || str != passw ){
+        write( "Das war verschieden! Passwort NICHT geaendert.\n" );
+        passwold = passw = 0;
+        return 1;
+    }
+
+    if ( MASTER->update_password( passwold, passw ) )
+        write( "Passwort geaendert.\n" );
+    else
+        write( "Hat nicht geklappt!\n" );
+
+    passwold = passw = 0;
+    return 1;
+}
+
+
+/*
+ *-----------------------------------------------------------------
+ * Rueckmeldungen von Spielern an Magier
+ *-----------------------------------------------------------------
+ */
+static int fehlerhilfe(string str) {
+  write("Welche Art von Fehler moechtest Du denn melden?\n"
+      "Fehlfunktionen    ->  bug\n"
+      "Ideen/Anregungen  ->  idee\n"
+      "Tippfehler/Typos  ->  typo\n"
+      "fehlende Details  ->  detail\n");
+
+  return 1;
+}
+
+/** Setzt eine Fehlermeldung an Magier ab (Spielerkommando).
+  * Fragt nach der Fehlermeldung und liest sie via bug2() ein, fall der
+  * Spieler kein Argument angeben hat.
+  * \param[in] str optionale Spielereingabe der Fehlerbeschreibung
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see bug2(string)
+  */
+static int bug(string str) {
+  if (!(str=_unparsed_args())) {
+    write( "Wie sieht der Fehler denn aus?\n" );
+    input_to("bug2", INPUT_PROMPT, "]");
+    return 1;
+  }
+  write("Vielen Dank fuer die Hilfe.\n");
+  smart_log("BUGS",str);
+  return 1;
+}
+
+/** Setzt eine Fehlermeldung an Magier ab (Spielerkommando).
+  * Lies Fehlerbeschreibung ein und speichert sie ab.
+  * \param[in] str Spielereingabe der Fehlerbeschreibung.
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see bug(string)
+  */
+static int bug2(string str) {
+  if (!str || str == "") {
+    write("Bug abgebrochen...\n");
+    return 1;
+  }
+  write("Vielen Dank fuer die Hilfe.\n");
+  smart_log("BUGS",str);
+  return 1;
+}
+
+/** Setzt eine Typomeldung an Magier ab (Spielerkommando).
+  * Fragt nach der Typomeldung und liest sie via typo2() ein, fall der
+  * Spieler kein Argument angeben hat.
+  * \param[in] str optionale Spielereingabe der Typobeschreibung
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see typo2(string)
+  */
+static int typo(string str) {
+  if (!(str=_unparsed_args())) {
+    write( "Wo ist denn der Tippfehler?\n" );
+    input_to("typo2", INPUT_PROMPT, "]");
+    return 1;
+  }
+  write("Vielen Dank fuer die Hilfe.\n");
+  smart_log("TYPO",str);
+  return 1;
+}
+
+/** Setzt eine Fehlermeldung an Magier ab (Spielerkommando).
+  * Liest die Typobeschreibung ein und speichert sie.
+  * \param[in] str Spielereingabe der Typobeschreibung
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see typo(string)
+  */
+static int typo2(string str) {
+  if (!str || str == "") {
+    write("Typo abgebrochen...\n");
+    return 1;
+  }
+  smart_log("TYPO",str);
+  write("Vielen Dank fuer die Hilfe.\n");
+  return 1;
+}
+
+/** Setzt eine Idee an Magier ab (Spielerkommando).
+  * Fragt nach der Idee und liest sie via idee2() ein, falls der
+  * Spieler kein Argument angeben hat.
+  * \param[in] str optionale Spielereingabe der Idee
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see idea2(string)
+  */
+static int idea(string str) {
+  if (!(str=_unparsed_args())) {
+    write( "Was fuer eine Idee hast Du denn?\n" );
+    input_to("idea2",INPUT_PROMPT, "]");
+    return 1;
+  }
+  write("Vielen Dank fuer die Hilfe.\n");
+  smart_log("IDEA",str);
+  return 1;
+}
+
+/** Setzt eine Idee an Magier ab (Spielerkommando).
+  * Liest die Idee ein und speichert sie.
+  * \param[in] str Spielereingabe der Idee
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see idea(string)
+  */
+static int idea2(string str) {
+  if (!str || str == "") {
+    write("Idee abgebrochen...\n");
+    return 1;
+  }
+  write("Vielen Dank fuer die Hilfe.\n");
+  smart_log("IDEA",str);
+  return 1;
+}
+
+/** Setzt ein fehlendes Detail an Magier ab (Spielerkommando).
+  * Fragt nach dem Detail und liest es via idee2() ein, falls der
+  * Spieler kein Argument angeben hat.
+  * \param[in] str optionale Spielereingabe des fehlenden Details
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see md2(string)
+  */
+static int md(string str) {
+  if (!(str=_unparsed_args())) {
+    write( "Fuer welches Detail fehlt denn die Beschreibung?\n" );
+    input_to("md2",INPUT_PROMPT, "]");
+    return 1;
+  }
+  write("Vielen Dank fuer die Hilfe.\n");
+  smart_log("DETAILS",str);
+  return 1;
+}
+
+/** Setzt ein fehlendes Detail an Magier ab (Spielerkommando).
+  * Liest das Detail ein und speichert es.
+  * \param[in] str Spielereingabe des fehlenden Details.
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see md(string)
+  */
+static int md2(string str) {
+  if (!str || str == "") {
+    write("Details abgebrochen...\n");
+    return 1;
+  }
+  write("Vielen Dank fuer die Hilfe.\n");
+  smart_log("DETAILS",str);
+  return 1;
+}
+
+/** Loggt eine Spielermeldung an Magier.
+  * Loggt die Spielermeldung in das passende File unter /log/report/ oder im
+  * vom Magier gewuenschten File. Hierbei werden Fehler, Ideen, MDs und Typos
+  * in getrennte Files sortiert.
+  * \param[in] str Spielermeldung
+  * \param[in] myname Art der Spielermeldung (DETAILS, BUG, TYPO, MD)
+  * @see md(string), idea(string), bug(string), typo(string)
+  */
+void smart_log(string myname, string str)
+{
+  string obnam;
+  object obj;
+
+  string *tmp = explode(str, ":");
+  if (sizeof(tmp) > 1) {
+    obnam = lower_case(trim(tmp[0]));
+    obj = present(obnam, environment()) || present(obnam);
+    if (!obj) {
+      obj = environment(this_object());
+    }
+    else // nur hier Teil vor dem : wegschneiden
+      str = trim(implode(tmp[1..],":"));
+  }
+  else {
+    obj = QueryProp(P_REFERENCE_OBJECT);
+    if (!obj || !present(obj))
+      obj = environment(this_interactive());
+  }
+
+  mapping err = ([ F_PROG: "unbekannt",
+           F_LINE: 0,
+           F_MSG: str,
+           F_OBJ: obj
+         ]);
+
+  string desc="etwas unbekanntes";
+  switch(myname) {
+    case "BUGS":
+      desc="einen Fehler";
+      err[F_TYPE]=T_REPORTED_ERR;
+      break;
+    case "DETAILS":
+      desc="ein fehlendes Detail";
+      err[F_TYPE]=T_REPORTED_MD;
+      break;
+    case "IDEA":
+      desc="eine Idee";
+      err[F_TYPE]=T_REPORTED_IDEA;
+      break;
+    case "TYPO":
+      desc="einen Typo";
+      err[F_TYPE]=T_REPORTED_TYPO;
+      break;
+  }
+
+  // Eintragung in die Fehler-DB
+  string hashkey = (string)ERRORD->LogReportedError(err);
+
+  // ggf. will das Objekte mit noch irgendwas anfangen.
+  obj->SmartLog(0, myname, str, strftime("%d. %b %Y"));
+
+  tell_object(this_object(), break_string( sprintf(
+    "Du hast an %s erfolgreich %s abgesetzt.\n"
+    "Die ID der abgesetzten Meldung lautet: %s\n",
+    (obj->IsRoom() ? "diesem Raum" : obj->name(WEM,1)),desc,
+    hashkey||"N/A"),78,BS_LEAVE_MY_LFS));
+}
+
+/** Speichert den Spieler und loggt ihn aus (Spielerkommando 'ende').
+  * Der Spieler wird vollstaendig ausgeloggt, d.h. das Spielerobjekt
+  * zerstoert.
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see disconnect()
+  */
+int quit()
+{
+  int arg;
+  SetProp(P_LAST_QUIT,time());
+  catch(RemoveChannels();publish);
+  if(!QueryGuest())
+  {
+    save_me(0);
+    tell_object(ME,"Speichere "+QueryProp(P_NAME)+".\n");
+  }
+
+  if (interactive(ME))
+    call_notify_player_change(0);
+
+  remove_living_name();
+  // EVT_LIB_LOGOUT wird in remove() getriggert.
+  if(catch(remove();publish)) destruct(ME);
+  return 1;
+}
+
+/** Wrapper im quit() herum, verhindert 'ende', falls Spieler kaempft.
+  * \return 0 oder Rueckgabewert von quit()
+  * @see quit()
+  */
+static int new_quit() {
+  notify_fail("Du bist in Gedanken noch bei Deinem letzten Kampf.\n"+
+              "Warte noch etwas bevor Du das Spiel verlaesst,\n"+
+              "damit Du so nicht in RL weitermachst...\n");
+  if (time()-Query(P_LAST_COMBAT_TIME)<120 && !IS_LEARNING(ME))
+    return 0;
+  return quit();
+}
+
+/** Gibt die Infos ueber den Char an den Spieler aus (Spielerkommando 'info').
+  * \param[in] arg Wenn arg=="short", wird eine Kurzuebersicht ausgegeben.
+  * \return 1
+  * @see short_score()
+  */
+static int score(string arg) {
+  string tmp, gender;
+  int i,sz,val;
+  mixed ind;
+  object *enem1, *enem2, *inv;
+
+  if (QueryProp(P_GHOST)) {
+    write("Im ewigen Leben gibt es keine Punkte.\n");
+    return 1;
+  }
+
+  int plev = LEPMASTER->QueryLevel();
+ 
+  switch(tmp = QueryProp(P_GENDER)) {
+  case MALE: gender = "maennlich"; break;
+  case FEMALE: gender = "weiblich"; break;
+  case NEUTER: gender = "neutral"; break;
+  default: gender = lower_case(tmp);
+  }
+
+  ind = m_indices(QueryProp(P_ATTRIBUTES));
+  tmp = "";
+  foreach(string index: ind) {
+    string aname;
+    switch (index) {
+      case "int": aname = "Intelligenz"; break;
+      case "con": aname = "Ausdauer"; break;
+      case "dex": aname = "Geschicklichkeit"; break;
+      case "str": aname = "Kraft"; break;
+      default:
+        if(stringp(index)) aname = capitalize(index);
+        else aname = "Unbekannt";
+    }
+    aname = sprintf("%-18'.'s %2.2d", aname+" ", QueryRealAttribute(index));
+    if((val = QueryAttributeOffset(index)))
+      aname += sprintf(" (%s%d)", (val>=0?"+":""), val);
+    tmp += aname + "\n";
+  }
+
+  printf("- %-'-'68s\n",
+         TeamPrefix()+capitalize(implode(explode(short()||"","\n"),""))+" ");
+  if(arg!="short") {
+    printf("Rasse ............ %-' '18s Abenteuer ........ %d %s\n",
+           QueryProp(P_RACE), QueryProp(P_QP),
+           (val = QM->QueryTotalQP()) == QueryProp(P_QP) ? "" : "("+val+")");
+    printf("Geschlecht ....... %-' '18s Groesse .......... %d cm\n",
+           gender, QueryProp(P_SIZE));
+    printf("Stufe ............ %-3.3d %-' '14s Gewicht .......... %d kg\n",
+           QueryProp(P_LEVEL), (QueryProp(P_LEVEL) < plev ? "("+plev+")" : ""),
+           QueryProp(P_WEIGHT) / 1000);
+    printf("Gilde ............ %-' '18s Gildenstufe ...... %d\n",
+         capitalize(QueryProp(P_GUILD)), QueryProp(P_GUILD_LEVEL));
+  }
+  printf("Erfahrung ........ %-' '18s Charakter ........ %-s\n\n",
+         QueryProp(P_XP)+ " Punkte", al_to_title(QueryProp(P_ALIGN)));
+  printf("%#-76.2s\n\n", tmp);
+  printf("Gesundheit ....... %-3.3d %-' '14s Gift ............. %s\n",
+         QueryProp(P_HP),
+         (QueryProp(P_HP) == (val = QueryProp(P_MAX_HP)) ? "" : "("+val+")"),
+         ((val = QueryProp(P_POISON)) ?
+          (val < 4 ? "leicht" : "gefaehrlich") : "gesund"));
+  printf("Konzentration .... %-3.3d %-' '14s Vorsicht ......... %s\n",
+         QueryProp(P_SP),
+         (QueryProp(P_SP) == (val = QueryProp(P_MAX_SP)) ? "" : "("+val+")"),
+         ((ind = QueryProp(P_WIMPY)) ? ""+ind : "mutig"));
+  printf("Todesfolgen....... %-' '18s %s\n",
+         ((val = death_suffering()) ? ""+((val+9)/10) : "kein Malus"),
+         (QueryProp(P_WIMPY) && ind=QueryProp(P_WIMPY_DIRECTION))
+         ? sprintf("Fluchtrichtung ... %O", ind) : "");
+  printf("%s",
+         (time()-Query(P_LAST_COMBAT_TIME)<120 && !IS_LEARNING(ME)) ?
+         "Spiel verlassen .. nicht moeglich\n" : ""
+         );
+
+  if(arg!="short") {
+    write(break_string(Forschung(), 70));
+    if(ind=QueryProp(P_AWAY))
+      printf("Du bist nicht ansprechbar: %O\n",ind);
+  }
+
+  if(sizeof(enem1=((mixed)QueryEnemies())[0])) {
+    enem2=({});
+    inv=all_inventory(environment(ME));
+    foreach(object en: enem1) {
+      if (member(inv,en)==-1) // Ist unser Feind und ist nicht hier
+        enem2+=({en});
+    }
+    if(sizeof(enem2))
+    {
+      write(break_string(
+            "Du verfolgst " + CountUp(map_objects(enem2, "name", WEN))+".",
+            78));
+    }
+  }
+  if(arg!="short") show_age();
+  printf("%-'-'70s\n", "");
+  return 1;
+}
+
+/** Gibt eine kuerzere Info ueber den Char aus (Spielerkommando punkte|score).
+    Ruft score("short").
+  * \param[in] arg UNUSED
+  * \return 1 bei Erfolg, 0 sonst.
+  * @see score(string), very_short_score()
+  */
+static int short_score(string arg) {
+  return score("short");
+}
+
+/** Gibt eine Miniinfo ueber LP / KP aus (Spielerkommando: kurzinfo)
+  * \return 1
+  * @see score(string), short_score(string)
+  */
+static int very_short_score(string arg) {
+  int    lp,mlp,xlp,kp,mkp,xkp;
+  string bar;
+
+  lp=QueryProp(P_HP); mlp=QueryProp(P_MAX_HP);
+  kp=QueryProp(P_SP); mkp=QueryProp(P_MAX_SP);
+  if (mlp)
+    xlp=(lp*40/mlp);
+  if (mkp)
+    xkp=(kp*40/mkp);
+  bar="  .    .    .    .    .    .    .    .  ";
+  if (QueryProp(P_NO_ASCII_ART) || arg == "-k")
+    printf("Gesundheit: %3.3d (%3.3d), Konzentration: %3.3d (%3.3d)\n",
+           lp, mlp, kp, mkp);
+  else
+    printf("Gesundheit:    0 |%'#'40.40s| %3.3d%s\n"+
+           "Konzentration: 0 |%'#'40.40s| %3.3d%s\n",
+           (xlp<0?bar:bar[xlp..]),lp,(lp==mlp?"":sprintf(" (%d)",mlp)),
+           (xkp<0?bar:bar[xkp..]),kp,(kp==mkp?"":sprintf(" (%d)",mkp))
+           );
+  return 1;
+}
+
+/** Gibt eine Manpage/Hilfeseite an den Spieler aus.
+    Beruecksichtigt hierbei die Synonymliste aus dir/.synonym, um die richtige
+    Manpage auszugeben.
+  * \param[in] dir Verzeichnis der gewuenschten Manpage
+  * \param[in] page Name der gewuenschten Manpage
+  * \return String der gewuenschten Manpage
+  */
+static string getmanpage(string dir, string page)
+{
+  string text, *syn;
+  int i;
+
+  if (dir[<1] != '/')
+    dir += "/";
+
+  if ((text=read_file(dir+page)) && sizeof(text))
+    return text;
+
+  if (text = read_file(dir+".synonym")) {
+    syn = regexplode(text, "([ \t][ \t]*|\n)");
+    if ((i=member(syn, page))!=-1)
+      return read_file(dir+syn[i+2]);
+  }
+  return 0;
+}
+
+/** Gibt eine Hilfeseite an den Spieler aus (Spielerkommando hilfe|man).
+  * Die Hilfeseite wird in div. Verzeichnissen gesucht (je nach Gilde,
+  * Magier-/Spielerstatus).
+  * \param[in] str Name der gewuenschten Hilfeseite.
+  * \return 1
+  */
+static int help(string str) {
+  string verb, rest, text, gilde;
+  mixed found;
+
+  found=0;
+  text = "";
+  if (str) {
+    str = implode( explode(str, ".." ), "");
+
+    if ( sscanf( str, "gilde %s %s", gilde, rest)==2)
+      str=rest;
+    else
+      gilde=QueryProp(P_GUILD);
+    if (!gilde) gilde="abenteurer";
+
+    if ( sscanf( str, "%s %s",verb,rest )==2 ) str = verb;
+
+    if ((IS_LEARNER(PL)) ) {
+      if (rest = getmanpage("/doc/wiz/",str)) {
+        found = 1;
+        text += rest;
+      }
+      else if (rest = getmanpage("/doc/mcmd/", str)) {
+        found = 1;
+        text += rest;
+      }
+    }
+
+    if ((IS_SEER(PL)) /*&& !found*/ ) {
+      if (rest = getmanpage("/doc/scmd/",str)) {
+        if (found)
+          text += "\n--------------------\n";
+        found = 1;
+        text += rest;
+      }
+    }
+
+    if (rest = getmanpage("/doc/g."+gilde+"/",str)) {
+      if (found)
+        text += "\n--------------------\n";
+      found = 1;
+      text += rest;
+    } else {
+      if (rest = getmanpage("/doc/help/",str)) {
+        if (found)
+          text += "\n--------------------\n";
+        found = 1;
+        text += rest;
+      }
+      else if (rest = getmanpage("/doc/pcmd/",str)) {
+        if (found)
+          text += "\n--------------------\n";
+        found = 1;
+        text += rest;
+      }
+      else if (rest = getmanpage("/doc/REGELN/",str)) {
+        if (found)
+          text += "\n--------------------\n";
+        found = 1;
+        text += rest;
+      }
+    }
+
+    if (!found)
+      text = "Dazu ist keine Hilfe verfuegbar.\n";
+
+    More(text,0);
+    return 1;
+  }
+  if (IS_LEARNER(PL))
+    text = read_file("/doc/hilfe.magier");
+  else if (IS_SEER(PL))
+    text = read_file("/doc/hilfe.seher");
+
+  More(text + read_file("/doc/hilfe.spieler"), 0);
+  return 1;
+}
+
+/** Ermittelt angebene Optionen fuer das Spielerkommando 'wer'.
+  * \param[in] str vom Spieler spezifizierter String von Filteroptionen: -k,
+  * -v, -a, -s (+ Langformen).
+  * \return Array von Spieleroptionen als veroderte Int-Flags und Rest der
+  * Spielereingabe ohne die Optionen.
+  */
+static mixed filter_who_options(string str)
+{
+  string* opt, *ans;
+  int i,len,res;
+
+  opt = explode(str," "); len=sizeof(opt);
+  ans = ({});
+  res = 0;
+  for(i=0;i<len;i++)
+    switch(opt[i]){
+      case "-k":
+      case "-kurz":
+      res |= WHO_SHORT; break;
+      case "-v":
+      case "-vertikal":
+      res |= WHO_VERTICAL; break;
+      case "-alphabetisch":
+      case "-a":
+      case "-alpha":
+      res |= WHO_ALPHA; break;
+      case "-s":
+      case "-spieler":
+      res |= WHO_PLAYER_VIEW; break;
+      default:
+      return ({ res, implode(opt[i..]," ") });
+    }
+  return ({ res, 0 });
+
+}
+
+/** Spielerkommando 'wer', fragt /obj/werliste ab.
+  * \param[in] str Spielereingabe mit Optionen fuer wer.
+  * \return 1
+  */
+static int who(string str) {
+  int i,shrt;
+  string ret;
+  mixed ans;
+
+  if ((str=_unparsed_args())&&str[0..0]!="-") {
+    ans = filter_who_options(str);
+    shrt = ans[0];
+    str = ans[1];
+    if (!shrt) {
+      if (ret=INETD->_send_udp(str,
+                              ([ REQUEST: "who", SENDER: getuid(ME) ]), 1 ))
+        write(ret);
+      else
+        write("Anfrage abgeschickt.\n");
+      return 1;
+    }
+  }
+  if (str) i=(member(str,'o')>0); else i=0;
+  if (sizeof(str)>1 && str[0] == '-') str = str[1..1];
+  More(implode( "/obj/werliste"->QueryWhoListe(
+    IS_LEARNER(ME) && QueryProp(P_WANTS_TO_LEARN),shrt,0,str,i),"\n"),0);
+  return 1;
+}
+
+/** Spielerkommando 'kwer', fragt /obj/werliste ab.
+  * \param[in] str Spielereingabe mit Optionen fuer wer.
+  * \return 1
+  */
+static int kwho(string str)
+{
+  int shrt;
+  mixed res;
+
+  if(str) {
+    res = filter_who_options(str);
+    shrt = res[0];
+    str = res[1];
+  }
+  More(implode( "/obj/werliste"->QueryWhoListe(
+      IS_LEARNER(ME) && QueryProp(P_WANTS_TO_LEARN), shrt|WHO_SHORT ,0,str),
+    "\n")+"\n\n",0);
+  return 1;
+}
+
+/** Spielerkommando 'kkwer', gibt eine einfache Liste der Anwesenden aus.
+    Filtert unsichtbare Spieler aus, falls SPielerobjekt kein Magier ist.
+  * \param[in] str Spielereingabe mit Optionen fuer wer.
+  * \return 1
+  */
+static varargs int kkwho(string str) {
+  object *obs;
+  string *namen;
+
+  obs=filter_users(str);
+  namen=({});
+  if (IS_LEARNER(this_player())) {
+    foreach(object ob: obs) {
+      if (environment(ob))
+        namen+=({capitalize(geteuid(ob))});
+    }
+  } 
+  else {
+    foreach(object ob: obs) {
+      if (!ob->QueryProp(P_INVIS) && environment(ob))
+        namen+=({capitalize(geteuid(ob))});
+    }
+  }
+  if (sizeof(namen))
+    write(break_string(CountUp(sort_array(namen,#'>),", ", ", ")+".",75));
+  else
+    write("Keine passenden Spieler gefunden.\n");
+  
+  return 1;
+}
+
+/** Spielerkommando 'toete'.
+  * Prueft auf Geist, Gast, toten HC-Spieler, Waffe/freie Hand. Versucht einen
+  * Gegner zu finden und ruft dann Kill(string).
+  * \param[in] str Spielereingabe
+  * \return 1 oder 0, falls kein potentieller Gegner bei 'toete alle' gefunden
+  * wird.
+  */
+static int kill(string str) {
+  object eob,wob;
+
+  if (QueryProp(P_GHOST))
+  {
+    write("Das kannst Du in Deinem immateriellen Zustand nicht.\n");
+    return 1;
+  }
+  
+  if(hc_play>1)
+  {
+    write("DAS HAST DU HINTER DIR.\n");
+    return 1;
+  }
+  
+  if (QueryGuest())
+  {
+    write("Du bist doch nur Gast hier.\n");
+    return 1;
+  }
+  if (!str || str == "") {
+    write("WEN willst Du toeten?\n");
+    return 1;
+  }
+  if( !QueryProp(P_WEAPON) && QueryProp(P_FREE_HANDS)==0 ) {
+    write(
+      "Dazu solltest Du eine Waffe gezueckt oder eine Hand frei haben.\n");
+    return 1;
+  }
+  str=lower_case(str);
+  if (str=="alle") {
+    object livs;
+    livs=filter(all_inventory(environment(PL)),
+        function int (object ob) {
+            if (living(ob) && !query_once_interactive(ob)
+                  && !ob->QueryProp(P_INVIS)
+                  && !ob->QueryProp(P_NO_GLOBAL_ATTACK)
+                  && !ob->QueryProp(P_FRIEND))
+            {
+                Kill(ob);
+                return 1;
+            }
+            return 0;
+        } );
+    // wenn Gegner gefunden, raus, ansonsten kommt die Fehlermeldung unten.
+    if (sizeof(livs)) return 1;
+  }
+  else {
+    int i=1;
+    while(objectp(eob = present(str,i++,environment(PL)))) {
+      if (living(eob) && !eob->QueryProp(P_INVIS))
+        break;
+      else
+        eob=0;
+    }
+  }
+  if (!objectp(eob)) {
+    // per write und return 1 ist hier mal ok, weil dies Kommando im Spieler
+    // eh zuletzt in der Kommandokette ausgefuehrt wird und per return 0 eh
+    // kein anderes mehr zum Zug kommt.
+    write("Du siehst hier kein derartiges Wesen!\n");
+    return 1;
+  }
+  else if (eob == PL) {
+    write("Selbstmord ist keine Loesung!\n");
+    return 1;
+  }
+
+  /* Kill him */
+  Kill(eob);
+  return 1;
+}
+
+/** Spielerkommando 'stop'.
+  * Loescht die Gegnerliste, sofern man nicht InFight() ist.
+  * \param[in] str Spielereingabe, wird ignoriert.
+  * \return 1
+  */
+static int stop( string str )
+{
+    if ( InFight() ){
+        write( "Das geht nicht mitten im Kampf.\n" );
+        return 1;
+    }
+
+    if ( !str ){
+        StopHuntingMode();
+        write( "Ok.\n" );
+        return 1;
+    }
+
+    if ( !StopHuntID(str) )
+        write( "So jemanden verfolgst Du nicht!\n" );
+
+    return 1;
+}
+
+/** Spielerkommando fuers emoten ':'.
+  * \param[in] str Spielereingabe
+  * \param[in] genitiv Genetivflag
+  * \return 1 oder 0, falls Spieler nicht emoten kann (kein CAN_EMOTE Flag in
+  * P_CAN_FLAGS).
+  */
+int emote(string str,int genitiv)
+{
+  string *commands,message,verb;
+  object living;
+  int i,size;
+
+  if (!(Query(P_CAN_FLAGS)&CAN_EMOTE)) return 0;
+  if (query_verb()[0]==';') genitiv=1;
+  if (query_verb()[0]==':'||query_verb()[0]==';')
+    verb=query_verb()[1..]+" ";
+  else
+    verb="";
+  str=this_player()->_unparsed_args();
+  commands=explode(verb+(str||""),"#");
+  message=break_string((IS_SEER(ME) ? "" : ">")
+                       +capitalize(genitiv ? name(WESSEN) :
+                                   name())
+                       +" "+commands[0],78);
+  size=sizeof(commands);
+  if(size>=3)
+  {
+    living=find_living(lower_case(commands[1]));
+    if(!living || environment(living)!=environment() ||
+       (living->QueryProp(P_INVIS)) && !IS_LEARNER(ME))
+    {
+      write(capitalize(commands[1])+" sehe ich hier nicht!\n");
+      return 1;
+    }
+    if(living!=this_object())
+      tell_object(living,break_string((IS_SEER(this_player()) ? "" : ">")
+                                    +capitalize(genitiv ?
+                                                this_player()->name(WESSEN) :
+                                                this_player()->name())
+                                    +" "+commands[2],78));
+  }
+  if(size>=4)
+    write(break_string(commands[3],78));
+  else
+    write(message);
+  tell_room(environment(),message,({this_object(),living}));
+  return 1;
+}
+
+/** Spielerkommando fuers remoten 'r:'.
+  * \param[in] str Spielereingabe
+  * \param[in] flag Genetivflag
+  * \return 1 oder 0, falls Spieler nicht emoten kann (kein CAN_REMOTE Flag in
+  * P_CAN_FLAGS).
+  */
+static int remote(string str, int flag)
+{
+  int m;
+  string tmp, dest;
+  string *exstr;
+  object destpl;
+
+  if ( !(Query(P_CAN_FLAGS) & CAN_REMOTE) )
+      return 0;
+
+  if ( !(str=_unparsed_args()) ||
+       sizeof( (exstr=explode(str," ")) - ({""}) ) <= 1 ){
+      write("Was willst Du zu wem `emoten`?\n");
+      return 1;
+  }
+
+  dest = lower_case(exstr[0]);
+
+  if( !(destpl=find_player( dest ) ) ||
+      (destpl->QueryProp(P_INVIS) && !IS_LEARNER(ME)) ){
+    write("Einen solchen Spieler gibt es derzeit nicht.\n");
+    return 1;
+  }
+
+  tmp = implode( exstr[1..], " " );
+
+  tmp = regreplace( tmp, "(^|[^#])#($|[^#])", "\\1aus der Ferne\\2", 1 );
+  tmp = regreplace( tmp, "(^|[^\\^])\\^($|[^\\^])", "\\1in der Ferne\\2", 1 );
+  tmp = regreplace( tmp, "##", "#", 1 );
+  tmp = regreplace( tmp, "\\^\\^", "^", 1 );
+
+  if ( strstr( tmp, "aus der Ferne" ) == -1
+       && strstr( tmp, "in der Ferne" ) == -1 )
+      tmp += " aus der Ferne";
+
+  if ( QueryProp(P_INVIS) && IS_LEARNER(destpl) ){
+      str = "(" + capitalize(getuid(ME));
+      if ( flag )
+          str += member( "sxz", str[<1] ) == -1 ? "s" : "'";
+      str += ")";
+  }
+  else
+      str = (flag ? capitalize(name(WESSEN)) : capitalize(name(WER)));
+
+  str += " " + tmp + (member( ".?!", tmp[<1] ) == -1 ? "." : "") + "\n";
+
+  m = destpl->ReceiveMsg(str, MT_COMM|MT_FAR, MA_EMOTE,0, ME);
+  switch(m)
+  {
+    case MSG_DELIVERED:
+      _recv(destpl, capitalize(destpl->name()) + "->" + str, MSGFLAG_REMOTE);
+      break;
+    case MSG_BUFFERED:
+      write( capitalize(destpl->name(WER) + " ist gerade beschaeftigt.\n") );
+      break;
+    case MSG_IGNORED:
+      write( capitalize(destpl->name(WER) + " ignoriert Dich.\n") );
+      break;
+    case MSG_VERB_IGN:
+    case MSG_MUD_IGN:
+      write( capitalize(destpl->name(WER) + " ignoriert Deine Meldung.\n") );
+      break;
+    default:
+      write( capitalize(destpl->name(WER) + " kann Dich gerade nicht "
+            "wahrnehmen.\n") );
+  }
+  return 1;
+}
+
+/** Spielerkommando fuers emoten im Genitiv ';'.
+  * Ruft emote(string,int) auf.
+  */
+static int gemote(string str)
+{
+  return emote(str, 1);
+}
+
+/** Spielerkommando fuers remoten im Genitiv 'r;'.
+  * Ruft remote(string, int) auf.
+  */
+static int gremote(string str)
+{
+  return remote(str, 1);
+}
+
+static void load_auto_objects(mapping map_ldfied);
+
+private void InitPlayer();
+private void InitPlayer2();
+private void InitPlayer3();
+
+/** Gibt eine Zufallszahl um P_AVERAGE_SIZE herum zurueck.
+  * \return Zufaellige Groesse.
+  */
+private int RandomSize()
+{
+  return (100+random(13)-random(13)+random(13)-random(13))*
+    (QueryProp(P_AVERAGE_SIZE)||170)/100;
+}
+
+/** Setzt bestimmte Props im Spieler, falls diese nicht gesetzt sind oder
+  * loescht obsolete Props. Repariert bestimmte Datenstrukturen im Spieler.
+  * Wird von start_player() nach Laden des Savefiles gerufen.
+  * Momentan wird z.B. die Groesse gesetzt, falls sie bisher 0 ist und die
+  * Skills des Spielers initialisiert bzw. repariert oder auf die aktuellste
+  * Version des Skillsystems
+  * Ruft ggf. InitSkills() und FixSkills().
+  * @param[in] newflag Gibt an, ob es ein neuerstellter Spieler ist.
+  * @sa start_player(), InitSkills(), FixSkills()
+  */
+private void updates_after_restore(int newflag) {
+ 
+  // Seher duerfen die Fluchtrichtung uebermitteln lassen.
+  // Eigentlich koennte es Merlin machen. Dummerweise gibt es ja auch alte
+  // Seher und dann kann es gleiche fuer alle hier gemacht werden. (Ob der
+  // Code jemals rauskann?)
+  //TODO: Irgendwann alle Seher korrigieren und Code nach Merlin schieben...
+  if (IS_SEER(ME))
+    SetProp(P_CAN_FLAGS,QueryProp(P_CAN_FLAGS) | CAN_REPORT_WIMPY_DIR);
+
+  // ggf. Invis-Eigenschaft aus dem Loginobjekt abrufen (Invislogin), koennte
+  // ja anders als aus Savefile sein. Gesetztes P_INVIS aus diesem aber
+  // beibehalten.
+  if (IS_LEARNER(ME) && !QueryProp(P_INVIS)
+//      && load_name(previous_object()) == "/secure/login"
+      )
+  {
+    SetProp(P_INVIS, previous_object()->query_invis());
+    if (QueryProp(P_INVIS))
+      tell_object(ME, "DU BIST UNSICHTBAR!\n" );
+  }
+  "*"::updates_after_restore(newflag);
+
+  attributes::UpdateAttributes();
+
+  int size=Query(P_SIZE);
+  if (!size) size=RandomSize();
+  while(size==QueryProp(P_AVERAGE_SIZE))
+    size=RandomSize();
+  Set(P_SIZE,size);
+
+  // Prop wird nicht mehr genutzt. TODO: irgendwann entfernen.
+  Set(P_SECOND_LIST, SAVE, F_MODE_AD);
+  Set(P_SECOND_LIST, 0, F_VALUE);
+}
+
+
+/** Setzt den HC-Modus.
+  */
+varargs nomask void set_hc_play(string str,int val)
+{
+   string str1;
+
+    str1 = explode( object_name(previous_object()), "#" )[0];
+    
+    if ( str1 != "/secure/login" &&
+         previous_object()!=this_object() &&
+         extern_call() &&
+         (!geteuid(ME) || geteuid(ME) != getuid(ME) ||
+          capitalize(geteuid(ME)) != str ||
+          geteuid(ME) != geteuid(previous_object())) ){
+        write( "DIESER VERSUCH WAR ILLEGAL !!\n" );
+        return;
+    }
+    
+    hc_play=val;
+}
+
+/** gibt den HC-Modus zurueck.
+  */
+nomask int query_hc_play()
+{
+  return hc_play;
+}
+
+/** Initialisiert und aktiviert das Spielerobjekt.
+  * Kann nur von /secure/login oder /secure/master gerufen werden.
+  * Startet Telnet Negotiation, laedt Savefile, setzt einige Props. 
+  * Ruft updates_after_restore(), um div. Daten zu aktualisieren/reparieren.
+  * Ruft create() aus /std/player/potion.c.
+  * Bei neuem Spieler wird der entsprechende Event ausgeloest die Attribute
+  * auf die Startwerte gesetzt.
+  * Prueft Zweitiemarkierungen.
+  * Ruft InitPlayer().
+  * @param[in] str Name des Charakters, der geladen werden soll.
+  * @param[in] ip textuelle Repraesentation der IP-Adresse des Spielers.
+  * @return 1 bei Erfolg, 0 sonst.
+  * @todo Div. Reparaturen/Updates nach updates_after_restore() auslagern.
+  */
+varargs nomask int start_player( string str, string ip )
+{
+    mixed second;
+    int newflag;  /* could player be restored? */
+    string str1;
+
+    call_out( "disconnect", 600 );
+
+    str1 = explode( object_name(previous_object()), "#" )[0];
+
+    if ( str1 != "/secure/login" &&
+         str1 != "/secure/master" &&
+         (!geteuid(ME) || geteuid(ME) != getuid(ME) ||
+          capitalize(geteuid(ME)) != str ||
+          geteuid(ME) != geteuid(previous_object())) ){
+        write( "DIESER VERSUCH WAR ILLEGAL !!\n" );
+        destruct(ME);
+        return 0;
+    }
+
+    /* try to restore player. If it doesn't exist, set the new flag */
+    newflag = !restore_object( "/" + SAVEPATH + lower_case(str)[0..0] + "/"
+                               +lower_case(str) );
+
+    updates_after_restore(newflag);
+
+   if ( query_once_interactive(ME) )
+    {
+      // Telnet-Negotiations durchfuehren, aber nur die grundlegenden aus
+      // telnetneg. Alle anderen sollten erst spaeter, nach vollstaendiger
+      // Initialisierung gemacht werden.
+        telnetneg::startup_telnet_negs();
+        modify_prompt();
+        Set( P_LAST_LOGIN, time() );
+    }
+
+    Set( P_WANTS_TO_LEARN, 1 ); // 1 sollte der default sein !!!
+    Set( P_WANTS_TO_LEARN, PROTECTED, F_MODE_AS );
+    // Eingefuegt 18.11.99, kann nach einem Jahr wieder raus:
+    Set( P_TESTPLAYER, PROTECTED, F_MODE_AS );
+
+    if ( IS_LEARNER(ME) )
+        SetProp( P_CAN_FLAGS, QueryProp(P_CAN_FLAGS)|CAN_REMOTE );
+
+    Set( P_NAME, str );
+    Set( P_NAME, SECURED, F_MODE_AS );
+
+    if ( !QueryProp(P_NEEDED_QP) )
+        SetProp( P_NEEDED_QP, REQ_QP );
+
+    Set( P_NEEDED_QP, NOSETMETHOD, F_SET_METHOD );
+    Set( P_NEEDED_QP, SAVE|SECURED, F_MODE_AS );
+
+    /* autosave the player after 500 heartbeats */
+    time_to_save = age + 500;
+    potion::create(); /* DO IT HERE AFTER THE RESTORE !! */
+
+    AddId( getuid() );
+    SetProp( P_AC, 0 );
+    SetProp( P_WEAPON, 0 );
+
+    /* Set some things which wont be set when all is OK */
+    SetProp( P_MAX_HP, (QueryAttribute(A_CON) * 8 + 42 ));
+    SetProp( P_MAX_SP, (QueryAttribute(A_INT) * 8 + 42 ));
+
+    catch( bb = "/secure/bbmaster"->query_bb() );
+
+    /* If this is a new character, we call the adventurers guild to get
+     * our first title !
+     */
+    if ( newflag ) {
+        if ( QueryGuest())
+            SetProp( P_TITLE, "ueberkommt das "MUDNAME" ..." );
+
+        Set( P_LEVEL, -1 );
+        SetProp( P_ATTRIBUTES, ([ A_STR:1, A_CON:1, A_INT:1, A_DEX:1 ]) );
+        SetProp( P_HP, QueryProp(P_MAX_HP) );
+
+        // Event ausloesen
+        EVENTD->TriggerEvent(EVT_LIB_PLAYER_CREATION, ([
+              E_OBJECT: ME,
+              E_PLNAME: getuid(ME) ]) );
+    }
+    
+    InitPlayer();
+
+    // Padreic 01.02.1999
+    if ( !IS_LEARNER(ME) && second = QueryProp(P_SECOND) ) {
+        if ( stringp(second) && lower_case(second)[0..3] == "von " ) {
+            second = lower_case(second[4..]);
+            SetProp( P_SECOND, second );
+        }
+
+        if ( !stringp(second ) ||
+             file_size( "/save/" + second[0..0] + "/" + second + ".o" ) <= 0 ){
+            if ( stringp(second) &&
+                 file_size( "/save/" + lower_case(second[0..0]) + "/" +
+                            lower_case(second) + ".o" ) >0 ){
+                SetProp( P_SECOND, lower_case(second) );
+                log_file( "WRONG_SECOND",
+                          sprintf( "%s: %s: P_SECOND = %O -> Automatisch "
+                                   "korrigiert,\n",
+                                   dtime(time()), object_name(), second ) );
+            }
+            else {
+                tell_object( ME,
+                             "*\n*\n* Deine Zweitiemarkierung ist ungueltig, "
+                             "bitte aendere diese und sprich im\n* Zweifel "
+                             "bitte einen Erzmagier an.\n*\n*\n" );
+
+                log_file( "WRONG_SECOND",
+                          sprintf( "%s: %s: P_SECOND = %O\n",
+                                   dtime(time()), object_name(), second ) );
+                // ein bisschen deutlicher auffordern.. Padreic 08.04.1999
+                move( "/d/gebirge/room/zwafflad", M_GO );
+            }
+        }
+    }
+    return(0);
+}
+
+/** Letzte Phase der Spielerinitialisierung beim Laden des Charakters.
+  * Ruft enable_commands(), aktiviert den Heartbeat und aktiviert die
+  * Kommandos aus den geerbten command.c, put_and_get.c, team.c, soul.c,
+  * guide.c, setzt den Living Name.
+  * Registriert UseSpell() als Catchall-Kommando.
+  * Laesst den Spieler ggf. einen Level per /std/gilde aufsteigen, ruft
+  * call_notify_player_change(), loest Login-Event aus.
+  * Gibt Willkommenstexte, News und neue Mails aus.
+  * Findet den Startraum und bewegt den Spieler dorthin.
+  * Ruft FinalSetup() (aus den Rassenshells).
+  * Begrenzt Geldmenge im Spieler (wegen Bankzweities) nach Tragkraft und
+  * erstattet Geld bei Reboot.
+  * Ruft set_is_wizard().
+  * Startet Clonen der Autoloader.
+  * @sa InitPlayer3(),InitPlayer2(), InitPlayer(), start_player().
+  */
+private void InitPlayer4()
+{
+    int num, str, ski;
+    string err, called_from_ip;
+    mixed start_place;
+    object mon;
+
+    enable_commands();
+    set_heart_beat(1);
+    command::initialize();
+    add_put_and_get_commands();
+    add_team_commands();
+    add_soul_commands();
+    add_guide_commands();
+    add_action( "UseSpell", "", 1 );
+    set_living_name( getuid() );
+    while ( remove_call_out("disconnect") != -1 )
+        ;
+
+    if ( QueryProp(P_LEVEL) == -1 )
+    {
+        catch( "/std/gilde"->try_player_advance(this_object()) ;publish );
+    }
+
+    if ( interactive(ME) )
+        call_notify_player_change(1);
+
+    if ( interactive(this_object()) ) {
+        cat( "/etc/NEWS" );
+
+        NewbieIntroMsg();
+
+        if ( QueryProp(P_INVIS) && !IS_WIZARD(ME) )
+            SetProp( P_INVIS, 0 );
+
+        catch( num = "secure/mailer"->FingerMail(getuid());publish );
+
+        if ( num )
+            write( "Du hast " + num + " neue" +
+                   (num == 1 ? "n Brief" : " Briefe")+" im Postamt liegen.\n" );
+
+        catch( RegisterChannels();publish );
+
+        if ( (called_from_ip = Query(P_CALLED_FROM_IP)) &&
+             query_ip_number(ME) != called_from_ip ){
+            string tmp;
+
+            if ( stringp(tmp = query_ip_name(called_from_ip)) &&
+                 tmp != called_from_ip )
+                tmp = " [" + tmp + "]";
+            else
+                tmp = "";
+
+            write( "Das letzte Mal kamst Du von " + called_from_ip
+                   + tmp + ".\n" );
+        }
+
+        Set( P_CALLED_FROM_IP, query_ip_number(ME) );
+    }
+
+    if ( !stringp(default_home) || default_home == "" )
+        default_home = "/gilden/abenteurer";
+
+    if ( IS_SEER(ME) && !IS_LEARNER(ME) )
+        catch( start_place = HAUSVERWALTER->FindeHaus(getuid(ME));publish );
+    // wenn der Spieler noch ganz frisch ist und noch wenig  Stufenpunkte
+    // gekriegt hat und das Tutorial noch nicht gemacht hat, startet er im
+    // Tutorial.
+    else if (QueryProp(P_LEP) <= 120
+             && QM->HasMiniQuest(this_object(),
+               "/d/anfaenger/ennox/tutorial/npcs/verkaeufer") != 1)
+        start_place = "/room/welcome/"+ getuid(this_object());
+    else
+        start_place = 0;
+
+    if ( !start_place )
+        start_place = QueryProp(P_START_HOME);
+
+    if( objectp(start_place) || (stringp(start_place) && start_place != "" ) ){
+        if ((err = catch(move( start_place, M_GO|M_SILENT|M_NO_SHOW );publish)) 
+            || !environment() )
+            err = catch(move( default_home, M_GO|M_SILENT|M_NO_SHOW );publish);
+    }
+    else
+        err = catch(move( default_home, M_GO|M_SILENT|M_NO_SHOW );publish);
+
+    if ( err )
+        catch(move( "/gilden/abenteurer", M_GO|M_SILENT|M_NO_SHOW );publish);
+
+    // Die Shell muss FinalSetup() nicht implementieren. Daher Callother
+    catch( ME->FinalSetup();publish );
+
+    // Login-event ausloesen
+    EVENTD->TriggerEvent(EVT_LIB_LOGIN, ([
+          E_OBJECT: ME,
+          E_PLNAME: getuid(ME),
+          E_ENVIRONMENT: environment() ]) );
+
+    // erst jetzt GMCP freigeben und zu verhandeln.
+    gmcp::startup_telnet_negs();
+
+    // Schonmal sichern, falls ein Bug (Evalcost...) dazwischen kommen sollte.
+    autoload_rest = autoload;
+
+    // Um Geld-Xties mit illegal viel Geld zu vermeiden, kommt ein Check:
+    if ( !IS_LEARNER(ME) && !Query(P_TESTPLAYER) &&
+         mon = present( "\ngeld", ME ) ){
+        // maximale Kraft, die der Spieler haette haben koennen
+        str = QueryAttribute(A_STR) + 4;
+        if ( Query(P_FROG) )
+            str += 30;
+        if ( str < 1 )
+            str = QueryRealAttribute(A_STR) + 4;
+        if ( str > 30 )
+            str = 30;
+
+        // Trageskill beachten
+        ski = to_int(UseSkill( SK_CARRY, ([SI_SKILLARG : str ]) ));
+        if ( !intp(ski) )
+            ski = 0;
+
+        // Wieviel konnte der Spieler insgesamt maximal tragen?
+        num = 9200 + str * 800 + ski;
+        if ( num < 3000 )
+            num = 3000;
+
+        // Verdoppeln fuer einen guten Container und nochmal 20% draufschlagen
+        // zur Sicherheit. Das Ganze danach *4, um die maximale Anzahl Muenzen
+        // zu erhalten.
+        num = (int) (num * 8.8);
+
+        // Geld, das zuviel ist, auf den Maximalwert kuerzen.
+        // Zur Sicherheit wird mitgeloggt. Falls ein Spieler sich (zu recht)
+        // beschwert, kann man immer noch wieder die Summe korrigieren ;-)
+        if ( (str = mon->QueryProp(P_AMOUNT)) > num ){
+            mon->SetProp( P_AMOUNT, num );
+            log_file( "ZUVIEL_GELD", sprintf( "%s: %s hatte %d Muenzen bei "
+                                              "sich. Korrigiert auf %d.\n ",
+                                              ctime(time())[4..],
+                                              capitalize(getuid(ME)),
+                                              str, num ) );
+        }
+    }
+    int entschaedigung = QueryProp(P_CARRIED_VALUE);
+    if ( entschaedigung > 0 )
+    {
+        write( "Du findest " + entschaedigung +
+               " Muenzen, die Du beim letzten Mal verloren hast.\n" );
+
+        if ( MayAddWeight( entschaedigung / 4 ) ){
+            write( "Weil Du nicht mehr soviel tragen kannst, spendest Du den "+
+                   "Rest der Zentralbank.\n" );
+
+            num = (QueryProp(P_MAX_WEIGHT) - query_weight_contents()) * 4;
+            entschaedigung = (num < 0) ? 0 : num;
+        }
+
+        AddMoney( entschaedigung );
+        SetProp(P_CARRIED_VALUE,0);
+    }
+
+    if ( !QueryProp(P_INVIS) )
+        say( capitalize(name(WER)) + " betritt diese Welt.\n" );
+    else
+        write( "DU BIST UNSICHTBAR!\n\n" );
+#if __EFUN_DEFINED__(set_is_wizard)
+    if ( IS_WIZARD(getuid(ME)) )
+        set_is_wizard( ME, 1 );
+    else
+        set_is_wizard( ME, 0 );
+#endif
+    if ( query_once_interactive(ME) )
+        ListAwaited();
+
+    // Autoloader werden ganz zum Schluss geclont, da das bis zum bitteren
+    // (Evalcost-)Ende geschieht und danach u.U. keine Rechenzeit fuer
+    // andere Aktionen mehr ueber ist
+    load_auto_objects( autoload );
+}
+
+/** Setzt die Spielerinitialisierung nach start_player() fort.
+  * Prueft den Wert der vom Spieler getragenen Sachen (fuer Entschaedigung
+  * nach Reboot).
+  * Setzt div. Properties des "Spielerkoerpers", die eigentlich gespeichert
+  * werden, nach einem Reboot zurueck.
+  * Fragt ggf. nach eMail-Adresse und uebergibt per input_to an
+  * InitPlayer2().
+  * @sa InitPlayer3(),InitPlayer2(), InitPlayer(), start_player().
+*/
+private void InitPlayer()
+{
+    string mailaddr;
+
+    // wenn es einen Crash gab, sollen Spieler nicht noch extra bestraft werden
+    if ( file_time( "/save/" + getuid()[0..0] + "/" + getuid() + ".o" )
+         < last_reboot_time() ){
+        SetProp( P_FOOD, 0 );
+        SetProp( P_DRINK, 0 );
+        SetProp( P_ALCOHOL, 0 );
+        SetProp( P_BLIND, 0 );
+        SetProp( P_DEAF, 0 );
+        SetProp( P_POISON, 0 );
+        SetProp( P_GHOST, 0 );
+        SetProp( P_FROG, 0 );
+        SetProp( P_HP, QueryProp(P_MAX_HP) );
+        SetProp( P_SP, QueryProp(P_MAX_SP) );
+    }
+
+    if ( QueryGuest() )
+        Set( P_MAILADDR, "none" );
+    else if ( !(mailaddr = Query(P_MAILADDR)) || mailaddr == "" ) {
+        write(break_string(
+          "Eine gueltige EMail-Adresse erleichtert es erheblich, Dir "
+          "ein neues Passwort setzen zu lassen, falls Du einmal Dein "
+          "Passwort vergisst.",78)); 
+        input_to( "getmailaddr",INPUT_PROMPT,
+            "Gib bitte Deine EMail-Adresse an: " );
+        return;
+    }
+    InitPlayer2();
+}
+
+/** liest eMail-Adresse vom Spieler ein und speichert sie.
+  * Uebergibt anschliessend an InitPlayer2()
+  * @param[in] maddr Spielereingabe der Emailadresse.
+  * @sa InitPlayer2().
+  */
+static void getmailaddr( string maddr )
+{
+    maddr = check_email(maddr);
+
+    if ( !stringp(maddr)) {
+      write("Deine Eingabe scheint keine gueltige EMail-Adresse gewesen "
+          "zu sein.\n");
+      input_to( "getmailaddr", INPUT_PROMPT,
+          "Gib bitte Deine EMail-Adresse an: " );
+      return;
+    }
+    Set( P_MAILADDR, maddr );
+    InitPlayer2();
+}
+
+
+/** Prueft Geschlecht des Spielers und fragt ggf. beim Spieler nach.
+  * Uebergibt an InitPlayer3() oder get_gender().
+  * @sa InitPlayer3(), get_gender().
+  */
+private void InitPlayer2()
+{
+    if( member(({ MALE, FEMALE }), QueryProp(P_GENDER) ) == -1 ) {
+        input_to( "getgender", INPUT_PROMPT,
+            "Bist Du maennlich oder weiblich: ");
+        return;
+    }
+
+    InitPlayer3();
+}
+
+/** Liest Spielerantwort auf die Frage nach dem Geschlecht des Chars ein.
+  * Wird gerufen von input_to().
+  * Uebergibt an InitPlayer3().
+  * @sa InitPlayer3().
+  */
+static void getgender( string gender_string )
+{
+    gender_string = lower_case( gender_string );
+
+    if ( sizeof(gender_string)==1 && gender_string[0] == 'm' ){
+        write( "Willkommen, mein Herr!\n" );
+        SetProp( P_GENDER, MALE );
+    }
+    else if ( sizeof(gender_string)==1 && gender_string[0] == 'w' ){    
+        write( "Willkommen, gnae' Frau!\n" );
+        SetProp( P_GENDER, FEMALE );    
+    }    
+    else {
+        write( "Wie? Was? Verstehe ich nicht!\n" );    
+        input_to( "getgender", INPUT_PROMPT,
+            "Bist Du maennlich oder weiblich? (tippe m oder w): ");    
+        return;
+    }
+
+    InitPlayer3();
+}
+
+
+/** Prueft Terminaltyp des Spielers und fragt ggf. beim Spieler nach.
+  * Uebergibt an InitPlayer4() oder gettty().
+  * @sa InitPlayer4(), gettty().
+  */
+private void InitPlayer3()
+{
+    if ( !QueryProp(P_TTY) || QueryProp(P_TTY) == "none" )
+    {
+        write( "Waehle einen Terminaltyp (kann spaeter mit <stty> geaendert "
+               "werden)\n");
+        input_to( "gettty", INPUT_PROMPT, "vt100, ansi, dumb (Standard: dumb): " );
+        return;
+    }
+    InitPlayer4();
+}
+
+/** Liest Spielerantwort auf die Frage nach dem Terminaltyp ein.
+  * Wird gerufen von input_to().
+  * Uebergibt an InitPlayer4().
+  * @sa InitPlayer4().
+  */
+static void gettty( string ttystr )
+{
+    if ( !ttystr || ttystr == "" )
+        ttystr = "dumb";
+
+    ttystr = lower_case(ttystr);
+
+    if ( ttystr == "vt100" ){
+        write( "Dies sollte " + ANSI_BOLD + "fett" + ANSI_NORMAL + " sein.\n" );
+        SetProp( P_TTY, ttystr );
+    }
+    else
+        if ( ttystr == "ansi" ){
+            write( "Dies sollte " + ANSI_RED + "rot" + ANSI_NORMAL +
+                   " sein.\n" );
+            SetProp( P_TTY, "ansi" );
+        }
+        else if ( ttystr == "dumb" ){
+            write( "Ohje, oede! Besorg Dir ein besseres Terminal!\n" );
+            SetProp( P_TTY, "dumb" );
+        }
+        else {
+            write( "Dieser Terminaltyp wird nicht unterstuetzt. Nimm bitte "
+                   "einen aus:\nvt100, ansi or dumb (Standard ist dumb).\n" );
+            input_to( "gettty", INPUT_PROMPT,
+                "vt100, ansi or dumb (Standard ist dumb): ");
+            return;
+        }
+
+    InitPlayer4();
+}
+
+
+/** Liefert die UID des Charakters zurueck, also den Charakternamen.
+  * @return UID des Objekts (Charaktername).
+  */
+nomask string query_real_name() {
+  /* ACHTUNG !! DIES LFUN DARF NICHT ENTFERNT WERDEN !!! */
+  /* Sie wird vom Gamedriver (zB bei F_ED) aufgerufen !! */
+  /* Ich bin da zwar nicht so ueberzeugt von, dass der Driver die heutzutage
+   * noch ruft, aber die halbe Mudlib ruft sie. ;-) (Zesstra, 27.4.08)
+   */
+  return getuid();
+}
+
+/*
+ * the wizard command review: show player moving messages
+ */
+int review() {
+  string *msg;
+  write(short());
+  write("Deine Bewegungen werden wie folgt gemeldet:\n"+
+        "mout:  "+name(WER)+" "+(msg=explode(QueryProp(P_MSGOUT),"#"))[0]
+       +" <Richtung>"+(sizeof(msg)>1 ? msg[1] : "")+".\n"+
+        "min:   "+name(WER)+" "+QueryProp(P_MSGIN)+".\n"+
+        "mmout: "+name(WER)+" "+QueryProp(P_MMSGOUT)+".\n"+
+        "mmin:  "+name(WER)+" "+QueryProp(P_MMSGIN)+".\n"+
+        (IS_LEARNER(ME) ?
+         "cmsg:  "+name(WER)+" "+QueryProp(P_CLONE_MSG)+".\n"+
+         "dmsg:  <Irgendetwas> "+QueryProp(P_DESTRUCT_MSG)+".\n"
+         : "")+
+        "Wenn Du jemanden angreifst, sieht das so aus:\n"+
+        name(WER)+" greift Dich"+QueryProp(P_HANDS)[0]+" an.\n");
+  return 1;
+}
+
+/*
+ * set player moving messages
+ */
+
+static int setmin(string str)
+{
+  SetProp(P_MSGIN, _unparsed_args()||"kommt an");
+  write("Ok.\n");
+  return 1;
+}
+
+static int setmout(string str)
+{
+  string *msg;
+
+  if(sizeof(msg=explode((_unparsed_args()||"geht"),"#"))>2)
+  {
+    write("Du darfst nur einmal '#' fuer die Richtung angeben.\n");
+    return 1;
+  }
+  if(sizeof(msg)>1)
+  {
+    if (msg[0]!="" && msg[0][<1]==' ') msg[0]=msg[0][0..<2];
+    SetProp(P_MSGOUT, msg[0]+"#"+msg[1]);
+  }
+  else
+    SetProp(P_MSGOUT, _unparsed_args()||"geht");
+  write("Ok.\n");
+  return 1;
+}
+
+static int setmmin(string str)
+{
+  SetProp(P_MMSGIN, _unparsed_args()||"erscheint");
+  write("Ok.\n");
+  return 1;
+}
+
+static int setmmout(string str)
+{
+  SetProp(P_MMSGOUT, _unparsed_args()||"verschwindet");
+  write("Ok.\n");
+  return 1;
+}
+
+static int setcmsg(string str)
+{
+  SetProp(P_CLONE_MSG, _unparsed_args()||"zaubert etwas aus "
+          + QueryPossPronoun(MALE,WEM) + " Aermel hervor");
+  write("Ok.\n");
+  return 1;
+}
+
+static int setdmsg(string str)
+{
+  SetProp(P_DESTRUCT_MSG, _unparsed_args()||"wird von " + name(WER,1)
+          + " zerstaeubt");
+  write("Ok.\n");
+  return 1;
+}
+
+static int set_title(string str)
+{
+  string bonus;
+  
+  if(!IS_SEER(this_object()) && !FAO_HAS_TITLE_GIFT(this_object()) )
+  {
+    return 0;
+  }
+  
+  bonus = "";
+  if (!(str=_unparsed_args()))
+    str = "";
+  else if( str[0..2]=="\\b," || str[0..2]=="\\b'" )
+  {
+    bonus = "\b"; // ein backspace fuer ein (hoch)komma ist ok! :-)
+    str = str[2..];
+  }
+  if(str=="0")  // damit der Gildentitel zum Vorschein kommen kann
+    SetProp(P_TITLE, 0);
+  else
+    SetProp(P_TITLE, bonus+str);
+  write("Ok.\n");
+  return 1;
+}
+
+static int extra_input(string str, string look)
+{
+  if (str=="**")
+  {
+    if (look=="")
+      SetProp(P_EXTRA_LOOK,0);
+    else
+      SetProp(P_EXTRA_LOOK,look);
+    write("Ok.\n");
+    return 1;
+  }
+  input_to("extra_input",INPUT_PROMPT, "]" ,look+str+"\n");
+  return 1;
+}
+
+static int extralook(mixed str)
+{
+  if( str=="?" )
+  {
+    write( "Dein Extralook ist : "+QueryProp(P_EXTRA_LOOK) + "\n");
+    return 1;
+  }
+  write("Bitte gib Deinen Extra-Look ein. Beenden mit **:\n");
+  input_to("extra_input",INPUT_PROMPT,"]","");
+  return 1;
+}
+
+static void calculate_value()
+{
+  int i, carried_value, value;
+
+  carried_value=0;
+  foreach(object ob: deep_inventory(ME)) {
+    if (!ob->QueryProp(P_AUTOLOADOBJ))
+      carried_value+=((value=(int)ob->QueryProp(P_VALUE)) > 1000 ? 1000 : value);
+  }
+  SetProp(P_CARRIED_VALUE, carried_value);
+}
+
+/* Called by command 'save' */
+int save_character() {
+  save_me(1);
+  write("Ok.\n");
+  return 1;
+}
+
+void save_me(mixed value_items)
+{
+  // Gaeste werden nicht gespeichert
+  if( getuid()[0..3]=="gast" )
+    return;
+ 
+  // Autoloader identifizieren und speichern
+  autoload=([]);
+  foreach(object ob: deep_inventory(ME)) {
+    int val = ob->QueryProp( P_AUTOLOADOBJ );
+    if (val && clonep(ob))
+    {
+      string obname=load_name(ob);
+      if (obname == GELD)
+        autoload[obname] += val;
+      else
+        autoload += ([obname:val]);
+    }
+  }
+  // An noch nicht geclonte Autoloader denken!
+  autoload += autoload_rest;
+  
+  // Im Bedarfsfall Wert des Inventory bestimmen
+  if (value_items)
+    calculate_value();
+  else
+    SetProp(P_CARRIED_VALUE, 0);
+
+  // Logout-Zeit speichern
+  if(query_once_interactive(ME) && !QueryProp(P_INVIS))
+    Set(P_LAST_LOGOUT,time());
+
+  // Funktion zur Bestimmung des Gildenrating aufrufen
+  string gilde=GUILD_DIR+QueryProp(P_GUILD);
+  if (find_object(gilde) || file_size(gilde+".c")>-1)
+    catch(call_other(gilde,"GuildRating",this_object());publish);
+
+  // Speichern des Spielers
+  save_object("/"+SAVEPATH+getuid()[0..0]+"/" + getuid());
+}
+
+static varargs void log_autoload( string file, string reason, mixed data, string error )
+{
+  if (member(autoload_error,file)!=-1) return;
+  log_file(SHELLLOG("NO_AUTO_FILE"),sprintf("%s: %s: %s\nreason: cannot %s file\ndata: %O\n%s\n",
+           ctime()[4..15],capitalize(getuid()),file,reason,data,
+           (error?"Fehlermeldung: "+error+"\n":"")));
+  autoload_error+=({file});
+}
+
+// tics, die fuer autoloader reichen sollten:
+#define SAFE_FOR_AUTOLOADER __MAX_EVAL_COST__/4
+
+private void load_auto_object( string file, mixed data )
+{
+    object ob;
+    string error;
+   
+    if( get_eval_cost() < SAFE_FOR_AUTOLOADER ) return;
+    m_delete( autoload_rest, file );
+    autoload_error-=({file});
+
+    if ( file == "/obj/money" )
+      file = "/items/money";
+    if ( file == "/obj/seercard" )
+      file = "/items/seercard";
+    
+    ob = find_object(file);
+    
+    if (!ob)
+    {
+        if (file_size(file+".c")<0&&
+           file_size(implode(explode(file,"/")[0..<2],"/")+
+                     "/virtual_compiler.c")<0)
+        {
+           log_autoload(file,"find",data,0);
+           return;
+        }
+        if (error = catch(load_object(file); publish))
+        {
+           log_autoload(file,"load",data,error);
+           return;
+        }
+    }
+    if ( error = catch(ob = clone_object(file); publish) )
+    {
+        log_autoload(file,"clone",data, error);
+        return;
+    }
+
+    if ( error = catch(ob->SetProp( P_AUTOLOADOBJ, data ); publish) )
+    {
+        log_autoload(file,"SetProp",data, error);
+        ob->remove(1);
+        if (ob) destruct(ob);
+        return;
+    }
+
+    if ( error = catch(ob->move( ME, M_NOCHECK );publish) ) {
+        log_autoload(file,"move",data, error);
+        ob->remove(1);
+        if(ob) destruct(ob);
+        return;
+    }
+}
+
+static void load_auto_objects( mapping map_ldfied )
+{
+    if ( (!mappingp(map_ldfied) || !sizeof(map_ldfied)) && !sizeof(autoload_rest) )
+        return;
+
+    // Mit Netztoten Spielern rechnen manche Autoloader nicht. Also
+    // das Clonen unterbrechen und in Reconnect() wieder anwerfen.
+    if ( !interactive() )
+        return;
+
+    // Kleiner Hack: autoload_rest ist eine globale Variable, die beim
+    // Clonen der einzelnen Autoloader direkt veraendert wird.
+    // So lange das Mapping noch Eintraege hat, muessen wir noch fehlende
+    // Autoloader clonen.
+    if ( !sizeof(autoload_rest) )
+        autoload_rest = map_ldfied;
+
+    // Schon hier einen call_out() zum "Nach"clonen von noch nicht geclonten
+    // Autoloadern starten, da spaeter u.U. keine Rechenzeit mehr dafuer da ist.
+    while ( remove_call_out("load_auto_objects") != -1 )
+        /* do nothing */;
+    
+    // Mit Parameter '0' aufrufen, da das globale Mapping benutzt wird.
+    // Verzoegerung 0 in rekursiven Callouts ist bloed, also 1s Delay
+    call_out( "load_auto_objects", 2, 0 );
+    
+    // Mit catch() gegen die Evalcost-Falle!
+    // Mit Absicht das walk_mapping() aus der "alten" Version erhalten und
+    // nicht durch eine (einfachere) Schleife inkl. get_eval_cost() ersetzt,
+    // da eine Schleife gegenueber der walk_mapping()-Loesung den Aufbau
+    // der previous_object()-Kette veraendern wuerde; darauf testen aber
+    // manche Objekte.
+    catch( walk_mapping( autoload_rest, #'load_auto_object/*'*/ ) );
+}
+
+/*
+ * al_to_title: Make the numeric alignment value into a string
+ */
+static string al_to_title(int a)
+{
+  if (a >= KILL_NEUTRAL_ALIGNMENT * 100)
+    return "heilig";
+  if (a > KILL_NEUTRAL_ALIGNMENT * 20)
+    return "gut";
+  if (a > KILL_NEUTRAL_ALIGNMENT * 4)
+    return "nett";
+  if (a > - KILL_NEUTRAL_ALIGNMENT * 4)
+    return "neutral";
+  if (a > - KILL_NEUTRAL_ALIGNMENT * 20)
+    return "frech";
+  if (a > - KILL_NEUTRAL_ALIGNMENT * 100)
+    return "boese";
+  return "satanisch";
+}
+
+static int toggle_whimpy_dir(string str) {
+  SetProp(P_WIMPY_DIRECTION,str=_unparsed_args()||str);
+  if (str)
+    printf("Ok, Fluchtrichtung %O.\n",str);
+  else
+    printf("Ok, bevorzugte Fluchtrichtung deaktiviert.\n");
+  return 1;
+}
+
+static int toggle_whimpy(string str)
+{
+  int i;
+
+  if(!str || str=="" || (sscanf(str,"%d",i)<0))
+  {
+    write("vorsicht <hp>, 0<=hp<"+QueryProp(P_MAX_HP)+"\n");
+    return 1;
+  }
+  if(i>=QueryProp(P_MAX_HP) || i<0)
+  {
+    write("Der Wert ist nicht erlaubt.\n");
+    return 1;
+  }
+  if(!i) write("Prinz Eisenherz-Modus.\n");
+  else write("Vorsicht-Modus ("+i+")\n");
+  SetProp(P_WIMPY,i);
+  return 1;
+}
+
+/** Bestimmt, ob das Spielerobjekt beschattet werden darf.
+  * Beschatten ist nur fuer Objekte erlaubt, die in /std/player/shadows
+  * abgelegt sind.
+  * Ausnahme: Testspieler mit gesetztem P_ALLOWED_SHADOW
+  * @param[in] obj Objekt, was beschatten moechte.
+  * @return 0, wenn Beschatten erlaubt, 1 sonst.
+  */
+varargs nomask int query_prevent_shadow(object obj)
+{
+  string what, allowed_shadow;
+  int    dummy;
+
+//  if ( Query(P_TESTPLAYER) )
+//      return 0;
+  
+  if (obj){
+    what=object_name(obj);
+    if (what && what != "" &&
+        sscanf(what,"/std/player/shadows/%s#%d",what,dummy)==2)
+      return 0;
+    
+    // Einem Testspieler kann man P_ALLOWED_SHADOW auf einen zu testenden
+    // Shadow setzen.
+    if ( Query(P_TESTPLAYER) && 
+         stringp(what) && 
+         stringp(allowed_shadow=Query(P_ALLOWED_SHADOW)) &&
+         strstr(what, allowed_shadow)==0)
+            return 0;
+  }
+  return 1;
+}
+
+static int uhrzeit()
+{
+  write(dtime(time()+QueryProp(P_TIMEZONE)*3600)+".\n");
+  return 1;
+}
+
+protected string SetDefaultHome(string str)
+{
+  return default_home=str;
+}
+
+string QueryDefaultHome()
+{
+  return default_home;
+}
+
+protected string SetDefaultPrayRoom(string str)
+{
+  if(hc_play>1)
+  {
+    default_pray_room="/room/nirvana";
+  }
+  else
+    default_pray_room=str;
+  
+  return default_pray_room;
+}
+
+string QueryPrayRoom()
+{
+  if(hc_play>1)
+  {
+    return "/room/nirvana";
+  } 
+  string room = QueryProp(P_PRAY_ROOM);
+  if (stringp(room))
+    return room;
+  else if (default_pray_room)
+    return default_pray_room;
+  // hoffentlich ist das wenigstens gesetzt. 
+  return default_home;
+}
+
+void _restart_beat()
+{
+  tell_object(ME,
+      "Der GameDriver teilt Dir mit: Dein Herzschlag hat wieder eingesetzt.\n");
+  set_heart_beat(1);
+}
+
+static int weg(string str)
+{
+  if (!(str=_unparsed_args()))
+  {
+    printf("Du bist nicht%s als abwesend gekennzeichnet.\n",
+           QueryProp(P_AWAY) ? " mehr" : "");
+    SetProp(P_AWAY, 0);
+    return 1;
+  }
+  write("Du bist jetzt als abwesend gekennzeichnet.\n");
+  SetProp(P_AWAY, str);
+  return 1;
+}
+
+/* Ein Befehl zum anschauen der Wegmeldung anderer Spieler */
+static int wegmeldung(string player)
+{
+
+  object player_ob;
+  string weg;
+
+  if ( !player || player=="" || 
+       player==lowerstring(this_player()->QueryProp(P_NAME)))
+  {
+    weg=this_player()->QueryProp(P_AWAY);
+    write ("Du bist "+(weg?"":"nicht ")+"als abwesend gekennzeichnet.\n");
+    if (weg)
+      write(break_string(weg, 78,"Grund: ",BS_INDENT_ONCE));
+    return 1;  
+  }
+
+  // Welcher Spieler ist gemeint?
+  player_ob=find_player(player);
+
+  // Spieler nicht da oder Invis und Anfrager is kein Magier
+  if (!player_ob || 
+      (player_ob->QueryProp(P_INVIS) && !IS_LEARNER(this_player()))) 
+  {
+    write(capitalize(player)+" ist gerade nicht im Spiel.\n");
+    return 1;
+  }
+
+  weg=player_ob->QueryProp(P_AWAY);
+
+        // player_ob->Name() gibt bei invis-Magiern "Jemand" zurueck
+  write (player_ob->QueryProp(P_NAME)+" ist "+
+         (weg?"":"nicht ")+"als abwesend gekennzeichnet.\n");
+
+  if (weg)
+    write(break_string(weg, 78,"Grund: ",BS_INDENT_ONCE));
+
+  return 1;
+}
+
+static string timediff(int time)
+{
+  string ret;
+
+  ret="";
+  if(time>=86400) {
+    ret+=time/86400+"d ";
+    time%=86400;
+  }
+  if(time<36000) ret+="0";
+  ret+=time/3600+":";
+  time%=3600;
+  if(time<600) ret+="0";
+  ret+=time/60+":";
+  time%=60;
+  if(time<10) ret+="0";
+  ret+=time+"";
+  return ret;
+}
+
+
+/* Ein Befehl zum anschauen der Idlezeit anderer Spieler */
+static int idlezeit(string player)
+{
+
+  object player_ob;
+  int idle;
+
+  if ( !player || player=="" || 
+       player==lowerstring(this_player()->QueryProp(P_NAME)))
+  {
+    write ("Du bist selber natuerlich gerade nicht idle.\n");
+    return 1;  
+  }
+
+  // Welcher Spieler ist gemeint?
+  player_ob=find_player(player);
+
+  // Spieler nicht da oder Invis und Anfrager is kein Magier
+  if (!player_ob || 
+      (player_ob->QueryProp(P_INVIS) && !IS_LEARNER(this_player()))) 
+  {
+    write(capitalize(player)+" ist gerade nicht im Spiel.\n");
+    return 1;
+  }
+
+  idle=query_idle(player_ob);
+
+        // player_ob->Name() gibt bei invis-Magiern "Jemand" zurueck
+  write (player_ob->QueryProp(P_NAME)+" ist "+
+         (idle>=60?timediff(idle):"nicht")+" passiv.\n");
+
+  return 1;
+}
+
+
+/** Belebt einen netztoten Spieler wieder.
+  * Reaktiviert Heartbeats, bewegt den Spieler zurueck an den Ort, der eim
+  * Einschlafen zum Aufwachen ermittelt wurde (im einfachsten Fall der Raum,
+  * wo man eingeschlafen ist).
+  */
+static void ndead_revive()
+{
+    string fname;
+    int ret;
+
+    set_heart_beat(1);
+    ndead_next_check = NETDEAD_CHECK_TIME;
+    ndead_currently = 0;
+    ndead_lasttime = 0;
+
+    if ( !objectp(ndead_location) && 
+         stringp(ndead_l_filename) && sizeof(ndead_l_filename)) {
+        
+        if ( member( ndead_l_filename, '#' ) == -1 ){
+            catch(load_object( ndead_l_filename); publish);
+            ndead_location = find_object(ndead_l_filename);
+        }
+        else {
+            ndead_location = find_object(ndead_l_filename);
+            if ( !ndead_location && env_ndead_info ){
+                fname = explode( ndead_l_filename, "#" )[0];
+                catch(ndead_location = 
+                    (load_object(fname)->SetProp(P_NETDEAD_INFO, env_ndead_info));
+                    publish);
+                if ( !objectp(ndead_location) ){
+                    catch(load_object( ndead_location);publish);
+                    ndead_location = find_object(ndead_location);
+                }
+            }
+        }
+    }
+
+    if ( !objectp(ndead_location)
+        || catch(ret = move( ndead_location, M_GO|M_SILENT );publish) 
+        || ret != 1 ) {
+        move( "gilden/abenteurer", M_GO|M_SILENT );
+        ndead_location = environment();
+    }
+
+    //  ndead_location=0;
+    ndead_l_filename = 0;
+    env_ndead_info = 0;
+}
+
+/** Bewegt einen netztoten Spieler in den Netztotenraum
+  * Gerufen von heartbeat().
+  * Zerstoert Gaeste, verlaesst ggf. das Team, ermittelt, ob der Spieler beim
+  * Aufwachen in das alte Environment bewegt werden soll oder in einen anderen
+  * Raum, hierzu wird im Environment P_NETDEAD_INFO abgefragt.
+  * Deaktiviert die Kommandos per disable_commands().
+  */
+static void ndead_move_me() {
+  object team;
+  mixed amem;
+
+  set_heart_beat(0);
+  stop_heart_beats();
+  if (QueryGuest()) {
+    quit();
+    if (ME)
+      remove();
+    if (ME)
+      destruct(ME);
+    return;
+  }
+  ndead_next_check=NETDEAD_CHECK_TIME;
+  ndead_currently=1;
+  ndead_lasttime=0;
+  ndead_location=environment();
+  if (objectp(ndead_location))
+    ndead_l_filename=object_name(ndead_location);
+  
+  if (objectp(environment())
+      && sizeof(explode(object_name(environment()),"#")) > 1)
+    env_ndead_info=environment()->QueryProp(P_NETDEAD_INFO);
+  else
+    env_ndead_info=0;
+  
+  if ( objectp(team=Query(P_TEAM)) )
+      // Der Test auf assoziierte Teammitglieder (== FolgeNPCs)
+      // verhindert, dass Spieler nach "schlafe ein" aus dem
+      // Team ausgetragen werden. -- 29.01.2002 Tiamak
+      //      && !objectp(amem=Query(P_TEAM_ASSOC_MEMBERS))
+      //      && !(pointerp(amem) && sizeof(amem)))
+    team->RemoveMember(ME);
+  
+  disable_commands();
+  move(NETDEAD_ROOM,M_GO|M_NO_ATTACK|M_NOCHECK,"ins Reich der Netztoten");
+}
+
+/** Ist dieser Character ein Gast?
+  * @return 1, wenn Gast, 0 sonst.
+  */
+int QueryGuest()
+{
+  string dummy;
+  return sscanf(getuid(),"gast%d",dummy);
+}
+
+/** Spielerkommando 'schlafe ein'.
+  * Ruft remove_interactive() bei Spielern, bei Magiern wird quit() gerufen,
+  * um das Magierobjekt zu zerstoeren.
+  * @sa quit()
+  */
+int disconnect(string str)
+{ 
+  string verb;
+  string desc = break_string(
+      "\"schlafe ein\" beendet Deine Verbindung mit "MUDNAME". Du behaeltst "
+     "Deine Sachen.\nFalls "MUDNAME" jedoch abstuerzt oder neu gestartet "
+     "wird, waehrend Du weg bist, verlierst Du die meisten allerdings "
+     "(genauso, als wenn Du Deine Verbindung mit \"ende\" beendet haettest). "
+     "In diesem Fall bekommst Du dann eine kleine Entschaedigung."
+     ,78,0,BS_LEAVE_MY_LFS);
+
+  verb=query_verb();
+  if (!verb)
+    verb="AUTOCALL";
+  if (verb[0..5]=="schlaf" && str!="ein")
+  {
+    notify_fail(desc);
+    return 0;
+  }
+  if (IS_LEARNER(this_object()))
+    return quit();
+  
+  tell_object(this_object(), desc);
+
+  if (clonep(environment()) && !environment()->QueryProp(P_NETDEAD_INFO))
+    tell_object(this_object(),break_string(
+        "\nACHTUNG: Wenn Du hier laengere Zeit schlaefst, "
+        "kommst Du vermutlich nicht an diesen Ort zurueck!",78));
+
+  say(capitalize(name(WER))+" hat gerade die Verbindung zu "MUDNAME" gekappt.\n");
+  remove_interactive(ME);
+  call_out(#'clear_tell_history,4);
+  return 1;
+}
+
+static int finger (string str)
+{
+  string ret;
+  mixed xname;
+
+  if (!str || str==""
+      || sizeof(explode(str," ")-({"-n","-p","-s","-v","-a"}))>1)
+  {
+    write("finger <spielername> oder finger <spielername@mudname>\n"+
+      "Bitte nur den reinen Spielernamen verwenden, keine Namensvorsaetze oder Titel\n");
+    return 1;
+  }
+  xname=explode(str,"@");
+  if(sizeof(xname)==2)
+  {
+    if (xname[0]=="-n " || xname[0]=="-p " || xname[0]=="-s ")  {
+      write("finger <spielername>@<mudname> - der Spielername fehlt.\n");
+      return 1;
+    }
+    if (ret=INETD->_send_udp(xname[1],([
+                   REQUEST: "finger",
+                   SENDER: getuid(ME),
+                   DATA: (explode(xname[0]," ")-({"-n","-p","-s"}))[0]
+                   ]), 1))
+            write(ret);
+        else
+      write("Anfrage abgeschickt.\n");
+    return 1;
+  }
+  "/p/daemon/finger"->finger_single(str,1);
+  return 1;
+}
+
+string lalign(string str, int wid)
+{
+  return (str+"                                                   "+
+      "                                                   ")[0..wid-1];
+}
+
+#define MUDS_BAR "\
+-------------------------------------------------------------------------------"
+
+private void format(mixed mud, mixed hosts, string output)
+{
+  output += lalign(hosts[mud][HOST_NAME], 20) + "  " +
+        (hosts[mud][HOST_STATUS] ?
+           hosts[mud][HOST_STATUS] > 0 ?
+             "UP       " + ctime(hosts[mud][HOST_STATUS])[4..15] :
+             "DOWN     " + ctime(-hosts[mud][HOST_STATUS])[4..15]
+         : "UNKNOWN  Never accessed.") + "\n";
+}
+
+static int muds() {
+  mapping hosts;
+  int i;
+  mixed muds, output;
+
+  output = lalign("Mudname", 20) + "  Status   Last access";
+  output += "\n" + MUDS_BAR[0..sizeof(output)] + "\n";
+  muds = sort_array(m_indices(hosts = INETD->query("hosts")),#'>);
+  map(muds, #'format, hosts, &output);
+  More(output);
+  return 1;
+}
+
+// **** local property methods
+static int _set_level(int i)
+{
+  if (!intp(i)) return -1;
+  if (i<1) return -1;
+  Set(P_LEVEL, i);
+  GMCP_Char( ([P_LEVEL: i]) );
+  return i;
+}
+
+static int _set_invis(int a)
+{
+  return Set(P_INVIS, intp(a) ? a : !Query(P_INVIS));
+}
+
+/* sets the terminal type */
+/* note: support vt100 (b/w), ansi (color), dumb (none) */
+static string _set_tty(string str) {
+  if(str != "dumb" && str != "vt100" && str != "ansi")
+    return Query(P_TTY);
+  return Set(P_TTY, str);
+}
+
+static int stty(string str)
+{
+  if(str!="dumb"&&str!="vt100"&&str!="ansi"&&str!="reset")
+  {
+    write("Kommando: stty dumb|vt100|ansi oder reset\n");
+  }
+  if(str == "reset") {
+      printf("[30;47m[0mDieser Text sollte lesbar sein!\n");
+      return 1;
+  }
+
+  write("TTY steht jetzt auf "+SetProp(P_TTY,str)+".\n");
+  if(str == "ansi" || str == "vt100") {
+      printf("Terminal Test:\n");
+      printf("VT100: [1mfett[0m [4munterstrichen[0m "+
+             "[5mblinkend[0m [7minvers[0m\n");
+      if(str == "ansi") {
+          printf("ANSI Farben und VT100 Attribute:\n");
+          foreach(int fg: 30 .. 37) {
+              foreach(int bg: 40 .. 47) {
+                  printf("[%d;%dm[1m@[0m", fg, bg);
+                  printf("[%d;%dm[4m@[0m", fg, bg);
+                  printf("[%d;%dm[5m@[0m", fg, bg);
+                  printf("[%d;%dm[7m@[0m", fg, bg);
+              }
+              printf("\n");
+          }
+          printf("Sollte dieser Text hier nicht richtig lesbar\nsein,"+
+                 "benutze das Kommando stty reset!\n");
+      }
+
+  }
+  return 1;
+}
+
+int set_ascii_art(string str)
+{
+  if (str!="ein"&&str!="aus")
+  {
+     printf("Du moechtest 'Grafik' "+(QueryProp(P_NO_ASCII_ART)?"NICHT ":"")+
+                     "sehen.\n");
+  }
+
+  if (str=="ein") {
+    SetProp(P_NO_ASCII_ART, 0);
+    printf("Zukuenftig moechtest Du 'Grafik' sehen.\n");
+  }
+
+  if (str=="aus") {
+    SetProp(P_NO_ASCII_ART, 1);
+    printf("Zukuenftig moechtest Du KEINE 'Grafik' mehr sehen.\n");
+  }
+
+
+  return 1;
+}
+
+int _set_shell_version(int arg)
+{
+  if (!intp(arg))
+    return -1;
+  Set(P_SHELL_VERSION,({QueryProp(P_RACE),arg}));
+  return 1;
+}
+
+int _query_shell_version()
+{   mixed sv;
+
+    if (!(sv=Query(P_SHELL_VERSION)) || !pointerp(sv) || sizeof(sv)!=2 ||
+        sv[0]!=QueryProp(P_RACE) || !intp(sv[1]))
+      return 0;
+    return sv[1];
+}
+
+// XxXxXxXxXx
+
+int more(string str)
+{
+  if(!str)
+  {
+    notify_fail("Usage: more <file>\n");
+    return 0;
+  }
+  if (file_size(str) <= 0) {
+    notify_fail(str+": No such file\n");
+    return 0;
+  }
+  More(str, 1);
+  return 1;
+}
+
+static int set_visualbell(string str)
+{
+  if(!str)
+  {
+    write("Derzeitige Einstellung fuer Tonausgabe: "+
+         (QueryProp(P_VISUALBELL)?"AUS":"EIN")+".\n");
+    return 1;
+  }
+  if (str=="ein")
+  {
+    if(!QueryProp(P_VISUALBELL))
+      write("Die Tonausgabe stand schon auf EIN.\n");
+    else
+      {
+  SetProp(P_VISUALBELL,0);
+        write("OK, Tonausgabe auf EIN gestellt.\n");
+      }
+  }
+  else
+    if (str=="aus")
+    {
+      if(QueryProp(P_VISUALBELL))
+        write("Die Tonausgabe stand schon auf AUS.\n");
+      else
+        {
+          SetProp(P_VISUALBELL,1);
+    write("OK, Tonausgabe auf AUS gestellt.\n");
+  }
+    }
+    else
+      write("Syntax: ton [ein|aus]\n");
+  return 1;
+}
+
+static int set_screensize(string str)
+{
+  int size;
+
+  if (str && (str[0..2] == "abs" || str[0..2]=="rel")) {
+    size = QueryProp(P_MORE_FLAGS);
+    if (str[0..2] == "abs") {
+      size |= E_ABS;
+      write("Es wird beim Prompt die Zeilenzahl des Textes angegeben.\n");
+    }
+    else {
+      size &= ~E_ABS;
+      write("Es wird beim Prompt der prozentuale Anteil des Textes angegeben.\n");
+    }
+    SetProp(P_MORE_FLAGS, size);
+    return 1;
+  }
+
+  if ( str && (str=="auto" || sscanf( str, "auto %d", size )) ){
+      if ( size > 0 ){
+          write("Ungueltiger Wert! "
+                "In Verbindung mit 'auto' sind nur negative Werte erlaubt.\n");
+          return 1;
+      }
+
+      SetProp( P_SCREENSIZE, size-1 );
+
+      write("Ok, Deine Zeilenzahl wird nun automatisch ermittelt (derzeit "+
+            QueryProp(P_SCREENSIZE)+").\n"+
+            break_string("Bitte beachte, dass dies nur einwandfrei "
+                         "funktioniert, wenn Dein Client Telnetnegotiations "
+                         "unterstuetzt (siehe auch \"hilfe telnegs\").") );
+    return 1;
+  }
+
+  if ( !str || str=="" || !sscanf( str, "%d", size ) || size < 0 || size > 100){
+      write(break_string(
+            sprintf("Mit dem Befehl 'zeilen <groesse>' kannst Du einstellen, "
+            "wieviele Zeilen bei mehrseitigen Texten auf einmal ausgegeben "
+            "werden. Die angegebene Groesse muss zwischen 0 und 100 liegen. "
+            "Bei Groesse 0 wird einfach alles ausgegeben (ohne Pause). Mit "
+            "der Einstellung 'auto' wird die Groesse automatisch ueber "
+            "die Telnetnegotiations ermittelt (siehe auch 'hilfe telnegs'). "
+            "Um nach einer Seite Text noch etwas Platz zu haben, kann man z.B. "
+            "'zeilen auto -3' einstellen.\n"
+            "Die Voreinstellung ist 20 Zeilen.\n"
+            "Mit 'zeilen abs[olut]' und 'zeilen rel[ativ]' kannst Du fest"
+            "legen, ob im Prompt bei langen Texten die aktuelle Zeilennummer "
+            "oder eine prozentuale Angabe ausgegeben wird.\n"
+            "Deine aktuelle Einstellung ist %d%s Zeilen (%s).",
+            QueryProp(P_SCREENSIZE),
+            Query(P_SCREENSIZE) < 0 ? " 'automatische'" : "",
+            QueryProp(P_MORE_FLAGS) & E_ABS ? "absolut" : "relativ"),78,0,1));
+    return 1;
+  }
+
+  SetProp( P_SCREENSIZE, size );
+
+  printf( "Okay, Deine Zeilenzahl steht nun auf %d.\n", size );
+  return 1;
+}
+
+static int _query_screensize()
+{
+    int sz,rows;
+
+    if ( (sz=Query(P_SCREENSIZE)) >= 0 )
+        return sz;
+
+    if ( !rows=QueryProp(P_TTY_ROWS) )
+        return 0;
+
+    return (rows+=sz) >= 5 ? rows : 5;
+}
+
+static int presay(string str)
+{
+  if (!str=_unparsed_args())
+    write("Dein Presay ist jetzt geloescht.\n");
+  else
+    printf("Dein Presay lautet jetzt: \"%s\".\n",str=capitalize(str));
+  SetProp(P_PRESAY,str);
+  return 1;
+}
+
+static int sethands(string str)
+{
+  mixed *hands;
+
+  if (!(str=_unparsed_args()))
+  {
+    write("sethands <message>\n");
+    return 1;
+  }
+  if (str=="0")
+      hands=RaceDefault(P_HANDS);
+  if (!hands || !pointerp(hands))
+      hands=Query(P_HANDS);
+  hands[0]=" "+str;
+  Set(P_HANDS,hands);
+  write("Ok.\n");
+  return 1;
+}
+
+static int inform(string str)
+{
+  switch (str) {
+    case "on":
+    case "ein":
+    case "an":
+      if (Query(P_INFORMME))
+    write("Das hattest Du schon so eingestellt.\n");
+      else
+      {
+    write("Kuenftig wirst Du informiert, wenn jemand das "MUDNAME" verlaesst/betritt.\n");
+    Set(P_INFORMME,1);
+      }
+      return 1;
+    case "aus":
+    case "off":
+      if (!Query(P_INFORMME))
+    write("Das hattest Du schon so eingestellt.\n");
+      else
+      {
+    write("Ok.\n");
+    Set(P_INFORMME,0);
+      }
+      return 1;
+    case 0:
+      write("Inform-Mode ist "+(Query(P_INFORMME)?"an":"aus")+"geschaltet.\n");
+      return 1;
+    }
+  write("inform an oder inform aus, bitte.\n");
+  return 1;
+}
+
+void delayed_write(mixed *what)
+{
+  if (!pointerp(what)||!sizeof(what)||!pointerp(what[0]))
+    return;
+  tell_object(ME,what[0][0]);
+  if (sizeof(what)>1&&sizeof(what[0])>1)
+    call_out("delayed_write",what[0][1],what[1..]);
+}
+
+void notify_player_change(string who, int rein, int invis)
+{
+  string *list,name;
+  mixed mlist;
+
+  if (invis) name="("+who+")";
+    else name=who;
+
+  if (Query(P_INFORMME))
+  {
+      if (rein)
+        tell_object(ME,name+" ist gerade ins "MUDNAME" gekommen.\n");
+      else
+        tell_object(ME,name+" hat gerade das "MUDNAME" verlassen.\n");
+  }
+
+  if(Query(P_WAITFOR_FLAGS) & (0x01))return ;
+
+  if(pointerp(list=Query(P_WAITFOR)) && sizeof(list) && member(list,who)!=-1)
+  {
+    if (!QueryProp(P_VISUALBELL))
+        name+=sprintf("%c",7); // Char fuer Pieps an den String anhaengen.
+    // Moechte der Spieler keine ASCII-Grafik sehen, wird diese Meldung ohne
+    // Leerzeichen formatiert, so dass sie von Screenreadern vorgelesen wird.
+    // Anderenfalls wuerde sie einzeln buchstabiert.
+    if ( QueryProp(P_NO_ASCII_ART) )
+    {
+      delayed_write( ({ ({ sprintf("%s IST JETZT %sDA !!!\n", 
+                           name, (rein?"":"NICHT MEHR ")) }) }) );
+    }
+    else 
+    {
+      delayed_write( ({ ({ sprintf("%s   I S T   J E T Z T   %sD A !!!\n",
+                           name, (rein?"":"N I C H T   M E H R   ")) }) }) );
+    }
+  }
+
+  if (rein && (sizeof(mlist=QueryProp(P_WAITFOR_REASON))) &&
+     (mappingp(mlist)) && (mlist[who]))
+        Show_WaitFor_Reason(who,invis);
+}
+
+static int erwarte(string str)
+{
+  string *list,*str1;
+  mixed mlist;
+  int i;
+
+  if (!mappingp(mlist=QueryProp(P_WAITFOR_REASON)))
+     mlist=([]);
+  if (!pointerp(list=Query(P_WAITFOR)))
+     list=({});
+
+  if (!str || str=="-u")
+  {
+     if(Query(P_WAITFOR_FLAGS)&0x01)
+       write("Du hast 'erwarte' temporaer deaktiviert.\n");
+     write("Du erwartest jetzt");
+     if (!sizeof(list))
+        write(" niemanden mehr.\n");
+     else
+     {
+        write(":\n");
+        if (!str) list=sort_array(list,#'>);
+        More(break_string(CountUp(list),78));
+     }
+     return 1;
+  }
+  if(str=="aus"){
+    Set(P_WAITFOR_FLAGS,Query(P_WAITFOR_FLAGS)|0x01);
+    write("Erwarte ist jetzt deaktiviert.\n");
+    return 1;
+  }
+  if(str=="an" || str=="ein"){
+    Set(P_WAITFOR_FLAGS,Query(P_WAITFOR_FLAGS)&0xFE);
+    write("Erwarte ist jetzt aktiv.\n");
+    return 1;
+  }
+
+  str1=explode(_unparsed_args()||""," ");
+  if (sizeof(str1)==1)
+  {
+     if (str1[0]!="wegen")
+     {
+        str=capitalize(lower_case(str));
+        if (member(list,str)!=-1)
+        {
+           SetProp(P_WAITFOR_REASON,m_copy_delete(mlist,str));
+           list-=({str});
+           write(str+" aus der Liste entfernt.\n");
+        } else
+        {
+           if (sizeof(list)>1000)
+           {
+             write("Du erwartest schon genuegend!\n");
+             return 1;
+           }
+           list+=({str});
+           write(str+" an die Liste angehaengt.\n");
+        }
+        Set(P_WAITFOR,list);
+     }
+     else
+     {
+        if (sizeof(mlist) && sizeof(list=m_indices(mlist)))
+        {
+           write("Du erwartest aus einem bestimmten Grund:\n");
+           write(break_string(CountUp(sort_array(list,#'>))+".",78));
+        }
+        else write("Du erwartest niemanden aus einem bestimmten Grund.\n");
+     }
+     return 1;
+  }
+  notify_fail("Falsche Syntax, siehe 'hilfe erwarte'!\n");
+  if (str1[1]!="wegen") return 0;
+  if (sizeof(str1)==2)
+     Show_WaitFor_Reason(capitalize(lower_case(str1[0])),0);
+  else {
+     string s=capitalize(lower_case(str1[0]));
+     if (sizeof(str1)==3 && (str1[2]=="nichts" || str1[2]=="loeschen"))
+        if (!mlist[s])
+           write("Du hast "+s+" aus keinem bestimmten Grund erwartet!\n");
+        else
+        {
+           SetProp(P_WAITFOR_REASON,m_copy_delete(mlist,s));
+           write("Du erwartest "+s+" aus keinem bestimmten Grund mehr!\n");
+        }
+     else
+     {
+        if (IS_ARCH(ME)) i=80; else if (IS_LEARNER(ME)) i=40;
+        else if (IS_SEER(ME)) i=20; else i=10;
+        if (!mlist[s] && sizeof(mlist)>=i)
+           write("Sorry, aber Du erwartest schon genuegend Leute!\n");
+        else
+        {
+           SetProp(P_WAITFOR_REASON,mlist+([s:implode(str1[2..]," ")]));
+           Show_WaitFor_Reason(s,0);
+        }
+     }
+  }
+  return 1;
+}
+
+static int uhrmeldung(string str)
+{
+  if (!(str=_unparsed_args()))
+  {
+    str=QueryProp(P_CLOCKMSG);
+    if (!str)
+    {
+      write("Du hast die Standard-Uhrmeldung.\n");
+      return 1;
+    }
+        if( !stringp(str) ) str = sprintf("%O\n",str);
+    printf("Deine Uhrmeldung ist:\n%s\n",str[0..<2]);
+    return 1;
+  }
+  if (str=="0")
+  {
+    SetProp(P_CLOCKMSG,0);
+    write("Ok, Du hast jetzt wieder die Standard-Meldung.\n");
+    return 1;
+  }
+  if (sizeof(explode(str,"%d"))>2)
+  {
+    write("Fehler, es darf nur ein %d in der Meldung vorkommen.\n");
+    return 1;
+  }
+  /* Mehrere %-Parameter verursachen das Abschalten der Uhr zur vollen Stunde.
+   */
+  if (sizeof(explode(str,"%"))>2)
+  {
+    write("Fehler: Zuviele %-Parameter in der Meldung.\n");
+    return 1;
+  }
+  /* Nur ein %-Parameter, aber der falsche: nicht sinnvoll. */
+  else
+  {
+    int i = strstr(str,"%",0);
+    if ( i>-1 && ( i==sizeof(str)-1 || str[i+1]!='d'))
+    {
+      write("Fehler: Falscher %-Parameter in der Meldung.\n");
+      return 1;
+    }
+  }
+  str+="\n";
+  SetProp(P_CLOCKMSG,str);
+  write("Ok.\n");
+  return 1;
+}
+
+static int zeitzone(string str)
+{
+  int zt;
+  if(!str || str==""){
+    if(!(zt=QueryProp(P_TIMEZONE)))
+      write("Du hast derzeit die gleiche Zeitzone wie das "MUDNAME" "+
+            "eingestellt.\n");
+    else if(zt>0)
+      printf("Deine Zeitzone ist auf %d Stunden vor (oestlich) von Berlin "+
+             "eingestellt.\n",zt);
+    else
+      printf("Deine Zeitzone ist auf %d Stunden nach (westlich) von "+
+             "Berlin eingestellt.\n",-zt);
+    return 1;
+  }
+  if(sscanf(str,"utc %d",zt)==1)  zt=(zt-1)%24;
+  else zt=to_int(str)%24;
+
+  SetProp(P_TIMEZONE,zt);
+
+  if(!zt)
+    write("Du hast derzeit die gleiche Zeitzone wie das "MUDNAME" "+
+          "eingestellt.\n");
+  else if(zt>0)
+    printf("Deine Zeitzone ist auf %d Stunden vor (oestlich) von Berlin "+
+           "eingestellt.\n",zt);
+  else
+    printf("Deine Zeitzone ist auf %d Stunden nach (westlich) von "+
+           "Berlin eingestellt.\n",-zt);
+  return 1;
+}
+
+static int emailanzeige(string str){
+  notify_fail("Syntax: emailanzeige [alle|freunde|niemand]\n");
+  if(!str || str==""){
+    if(!(str=QueryProp(P_SHOWEMAIL)))str="Niemandem";
+    else if(str=="alle")str="allen";
+    else if(str=="freunde")str="Deinen Freunden";
+    else if(str=="niemand")str="niemandem";
+    else{
+      SetProp(P_SHOWEMAIL,0);
+      str="Niemandem";
+    }
+    write("Deine Email wird "+str+" angezeigt.\n");
+    return 1;
+  }
+  else if(member(({"alle","freunde","niemand"}),str)==-1)return 0;
+
+  SetProp(P_SHOWEMAIL,str);
+
+  if(str=="alle")str="allen";
+  else if(str=="freunde")str="Deinen Freunden";
+  else str="niemandem";
+  write("Deine Email wird "+str+" angezeigt.\n");
+  return 1;
+}
+
+static int zaubertraenke()
+{
+  More("/room/orakel"->TipListe());
+  return 1;
+}
+
+varargs static int angriffsmeldung(string arg) {
+  if (arg=="ein" || arg=="an")
+    SetProp(P_SHOW_ATTACK_MSG,1);
+  else if (arg=="aus")
+    SetProp(P_SHOW_ATTACK_MSG,0);
+  if (QueryProp(P_SHOW_ATTACK_MSG))
+    write("Du siehst saemtliche Angriffsmeldungen von Dir.\n");
+  else
+    write("Du siehst nur neue Angriffsmeldungen von Dir.\n");
+  return 1;
+}
+
+static mixed _query_localcmds()
+{
+  return ({({"zeilen","set_screensize",0,0}),
+           ({"email","set_email",0,0}),
+           ({"url","set_homepage",0,0}),
+           ({"icq","set_icq",0,0}),
+           ({"messenger", "set_messenger", 0, 0}), 
+           ({"ort","set_location",0,0}),
+           ({"punkte","short_score",0,0}),
+           ({"score","short_score",0,0}),
+           ({"info","score",0,0}),
+           ({"kurzinfo","very_short_score",0,0}),
+           ({"quit","new_quit",0,0}),
+           ({"ende","new_quit",0,0}),
+           ({"disconnect","disconnect",0,0}),
+           ({"schlaf","disconnect",1,0}),
+           ({"speichern","save_character",0,0}),
+           ({"save","save_character",0,0}),
+           ({"toete","kill",0,0}),
+           ({"angriffsmeldung","angriffsmeldung",0,0}),
+           ({"passw","change_password",1,0}),
+           ({"hilfe","help",1,0}),
+           ({"selbstloeschung","self_delete",0,0}),
+           ({"spielpause","spielpause",0,0}),
+           ({"spieldauer","spieldauer",0,0}),
+           ({"idee","idea",0,0}),
+           ({"typo","typo",0,0}),
+           ({"bug","bug",0,0}),
+           ({"fehler","fehlerhilfe",0,0}),
+           ({"md","md",0,0}),
+           ({"detail","md",0,0}),
+           ({"vorsicht","toggle_whimpy",0,0}),
+           ({"stop","stop",0,0}),
+           ({"kwho","kwho",0,0}),
+           ({"kwer","kwho",0,0}),
+           ({"kkwer","kkwho",0,0}),
+           ({"kkwho","kkwho",0,0}),
+           ({"who","who",0,0}),
+           ({"wer","who",0,0}),
+           ({"zeit","uhrzeit",0,0}),
+           ({"uhrzeit","uhrzeit",0,0}),
+           ({"weg","weg",0,0}),
+           ({"wegmeldung", "wegmeldung", 0, 0}),
+           ({"idlezeit", "idlezeit", 0, 0}),
+           ({"finger","finger",0,0}),
+           ({"muds","muds",0,0}),
+           ({"emote","emote",0,0}),
+           ({":","emote",1,0}),
+           ({";","emote",1,0}),
+           ({"remote","remote",0,SEER_LVL}),
+           ({"r:","remote",1,0}),
+           ({"r;","gremote",1,0}),
+           ({"titel","set_title",0,0}),
+           ({"review","review",0,SEER_LVL}),
+           ({"setmin","setmin",0,SEER_LVL}),
+           ({"setmout","setmout",0,SEER_LVL}),
+           ({"setmmin","setmmin",0,SEER_LVL}),
+           ({"setmmout","setmmout",0,SEER_LVL}),
+           ({"sethands","sethands",0,SEER_LVL}),
+           ({"presay","presay",0,SEER_LVL}),
+           ({"extralook","extralook",0,SEER_LVL}),
+           ({"fluchtrichtung","toggle_whimpy_dir",0,SEER_LVL}),
+           ({"inform","inform",0,0}),
+           ({"erwarte","erwarte",0,0}),
+           ({"stty","stty",0,0}),
+           ({"grafik", "set_ascii_art", 0, 0}), 
+           ({"uhrmeldung","uhrmeldung",0,0}),
+           ({"zeitzone","zeitzone",0,0}),
+           ({"behalte","behalte",0,0}),
+           ({"zweitiemarkierung","zweitiemarkierung",0,0}),
+           ({"emailanzeige","emailanzeige",0,0}),
+           ({"topliste","topliste",0,0}),
+           ({"ton","set_visualbell",0,0}),
+           ({"telnegs","show_telnegs",0,0}),
+           ({"spotte", "spotte", 0, 0}),
+           ({"reise","reise",0,0}),
+           ({"zaubertraenke","zaubertraenke",0,0}),
+           ({"telnet","telnet_cmd",0,0}),
+     })+
+     command::_query_localcmds()+
+     viewcmd::_query_localcmds()+
+     comm::_query_localcmds()+
+     skills::_query_localcmds()+
+     description::_query_localcmds();
+}
+
+static int _check_keep(object ob)
+{
+  return (ob->QueryProp(P_KEEP_ON_SELL))==geteuid(ME);
+}
+
+static mixed _set_testplayer(mixed arg) {
+  mixed res;
+  object setob;
+
+  setob=this_player();
+  if (!objectp(setob) || !query_once_interactive(setob))
+    setob=this_interactive();
+  if (!objectp(setob))
+    setob=previous_object();
+  if (setob && !IS_DEPUTY(setob)) {
+    arg=geteuid(setob);
+    if (!arg || arg=="NOBODY")
+      arg=getuid(setob);
+    arg=capitalize(arg);
+  }
+  res=Set(P_TESTPLAYER,arg);
+  Set(P_TESTPLAYER,PROTECTED,F_MODE_AS);
+  return res;
+}
+
+int zweitiemarkierung(string arg)
+{
+  if (!QueryProp(P_SECOND))
+    return _notify_fail("Aber Du bist doch gar kein Zweiti.\n"),0;
+  notify_fail("Syntax: zweitiemarkierung [unsichtbar|sichtbar|name]\n");
+  if (!arg)
+    return 0;
+  switch (arg)
+  {
+    case "unsichtbar" :
+      SetProp(P_SECOND_MARK,-1);
+      write("Jetzt sieht kein Spieler mehr, dass Du ein Zweiti bist.\n");
+      return 1;
+    case "sichtbar" :
+      SetProp(P_SECOND_MARK,0);
+      write("Jetzt sieht kein Spieler mehr, wessen Zweiti Du bist.\n");
+      return 1;
+    case "name" :
+      SetProp(P_SECOND_MARK,1);
+      write("Jetzt koennen alle sehen, wessen Zweiti Du bist.\n");
+      return 1;
+  }
+  return 0;
+}
+
+int topliste(string arg)
+{
+    if (!arg)
+    {
+        printf("Du hast Dich fuer die Topliste %s.\n",
+            (QueryProp(P_NO_TOPLIST) ? "gesperrt" : "freigegeben"));
+        return 1;
+    }
+    else if (member(({"j","ja","n","nein"}),arg)==-1)
+        return _notify_fail("Syntax: topliste [ja|nein]\n"),0;
+    if (arg[0]=='j')
+    {
+        SetProp(P_NO_TOPLIST,0);
+        write("Du kannst jetzt (theoretisch) in der Topliste auftauchen.\n");
+    }
+    else
+    {
+        SetProp(P_NO_TOPLIST,1);
+        write("Du wirst jetzt nicht in der Topliste auftauchen.\n");
+    }
+    Set(P_NO_TOPLIST,SAVE|PROTECTED,F_MODE_AS);
+    return 1;
+}
+
+int show_telnegs(string arg)
+{
+    if (!arg)
+    {
+        write("Du bekommst Aenderungen Deiner Fenstergroesse "+
+              (QueryProp(P_TTY_SHOW)?"":"nicht ")+"angezeigt.\n");
+        return 1;
+    }
+    if (member(({"ein","an","aus"}),arg)==-1)
+    {
+        write("Syntax: telnegs [ein|aus]\n");
+        return 1;
+    }
+    if (arg=="ein" || arg=="an")
+    {
+        write("Du bekommst "+(QueryProp(P_TTY_SHOW)?"":"nun ")+
+              "Aenderungen Deiner Fenstergroesse angezeigt.\n");
+        Set(P_TTY_SHOW,1);
+        return 1;
+    }
+    write("Du bekommst "+(QueryProp(P_TTY_SHOW)?"nun ":"")+
+          "Aenderungen Deiner Fenstergroesse nicht "+
+          (QueryProp(P_TTY_SHOW)?"mehr ":"")+"angezeigt.\n");
+    Set(P_TTY_SHOW,0);
+    return 1;
+}
+
+private int set_keep_alive(string str) {
+  if (str == "ein") {
+    telnet_tm_counter = 240 / __HEART_BEAT_INTERVAL__;
+    tell_object(this_object(), break_string(
+        "An Deinen Client werden jetzt alle 4 Minuten unsichtbare Daten "
+        "geschickt, um zu verhindern, dass Deine Verbindung zum "MUDNAME
+        " beendet wird.", 78));
+  }
+  else if (str == "aus") {
+    telnet_tm_counter = 0;
+    tell_object(this_object(),break_string(
+        "Du hast das Senden von unsichtbaren Daten (Keep-Alive-Pakete) an "
+        "Deinen Client ausgeschaltet.",78));
+  }
+  else {
+    if (!telnet_tm_counter)
+      tell_object(this_object(), break_string(
+        "An Deinen Client werden keine Keep-Alive-Pakete geschickt.",78));
+    else
+      tell_object(this_object(), break_string(
+        "An Deinen Client werden alle 4 Minuten " 
+        "unsichtbare Daten geschickt, damit Deine Verbindung "
+        "zum "MUDNAME" nicht beendet wird.",78));
+  }
+  return 1;
+}
+
+private int print_telnet_rttime() {
+  int rtt = QueryProp(P_TELNET_RTTIME);
+  if (rtt>0)
+    tell_object(ME, break_string(
+      "Die letzte gemessene 'round-trip' Zeit vom MG zu Deinem Client "
+      "und zurueck betrug " + rtt + " us.",78));
+  else
+    tell_object(ME, break_string(
+      "Bislang wurde die 'round-trip' Zeit vom MG zu Deinem Client "
+      "noch nicht gemessen oder Dein Client unterstuetzt dieses "
+      "nicht.",78));
+  return 1;
+}
+
+int telnet_cmd(string str) {
+  if (!str) return 0;
+  string *args = explode(str, " ");
+  string newargs;
+  if (sizeof(args) > 1)
+    newargs = implode(args[1..], " ");
+  else
+    newargs = "";
+
+  switch(args[0])
+  {
+    case "keepalive":
+      return set_keep_alive(newargs);
+    case "rttime":
+      return print_telnet_rttime();
+  }
+  return 0;
+}
+
+int spotte( string str )
+{
+    _notify_fail( "Hier ist nichts, was Du verspotten koenntest!\n" );
+    return 0;
+}
+
+int behalte(string str)
+{
+  object ob,*obs;
+  string s;
+
+  if (str)
+  {
+    if (str=="alles") {
+      filter_objects(all_inventory(), "SetProp", P_KEEP_ON_SELL, getuid());
+      write("Ok!\n");
+      return 1;
+    }
+    if (str=="nichts") {
+      filter_objects(all_inventory(), "SetProp", P_KEEP_ON_SELL, 0);
+      write("Ok!\n");
+      return 1;
+    }
+    if (!sizeof(obs=find_obs(str,PUT_GET_NONE)))
+    {
+      _notify_fail("Aber sowas hast Du nicht dabei!\n");
+      return 0;
+    }
+    else ob=obs[0];
+
+    if (ob->QueryProp(P_KEEP_ON_SELL)==geteuid(ME))
+        ob->SetProp(P_KEEP_ON_SELL,0);
+    else
+        ob->SetProp(P_KEEP_ON_SELL,geteuid(ME));
+
+    // erneut abfragen, da sich der Wert nicht geaendert haben muss
+    if (ob->QueryProp(P_KEEP_ON_SELL)==geteuid(ME))
+        write(break_string(sprintf("Ok, Du wirst %s jetzt bei 'verkaufe alles' "
+                                   "behalten.\n",ob->name(WEN)),78));
+    else
+        write(break_string(sprintf("Ok, Du wirst %s beim naechsten 'verkaufe "
+                                   "alles' mitverkaufen!\n",ob->name(WEN)),78));
+
+    return 1;
+  }
+  s=make_invlist(ME,filter(all_inventory(ME),#'_check_keep)); //'));
+  More(s);
+  return 1;
+}
+
+static int _query_lep()
+{
+  int val;
+  val = LEPMASTER->QueryLEP();
+  Set( P_LEP, val );
+  return val;
+}
+
+static mixed _set_fraternitasdonoarchmagorum(mixed arg)
+{
+  if (!intp(arg)) return -1;
+
+  if ((!previous_object(1)||object_name(previous_object(1))!=FAO_MASTER) && 
+      (!this_interactive() || !IS_ARCH(this_interactive())))
+    return -1;
+
+  if (!intp(arg)) return -1;
+
+  log_file("fao/P_FAO",sprintf("%s - %s P_FAO gesetzt auf %O\n",
+        dtime(time()),query_real_name(),arg) );
+  return Set(P_FAO,arg);
+}
+
+nomask void set_realip(string str)
+{
+  if(previous_object() && strstr(object_name(previous_object()),"/secure")==0)
+  {
+    realip=str;
+  }
+}
+
+nomask string query_realip()
+{
+  return realip ? realip : "";
+}
+
+mixed _query_netdead_env() {
+        return ndead_location || ndead_l_filename;
+}
