skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
/**
 * The main player object.  Does all the player related stuff.
 * @author Pinkfish
 * @started December 1991
 */

#include <config.h>
#include <board.h>
#include <drinks.h>
#include <living.h>
#include <command.h>
#include <player.h>

/** These are defines for the prompt system. */
#define ON 2
#define HP 4
#define GP 8
#define XP 16
#define WD 32

/**
 * This defines the number the players stats are set to when
 * logging in for the first time, or refreshing.
 */
#define NEW_STAT 8

inherit "/global/player/line_ed";
inherit "/global/player/auto_load";
inherit "/global/player/events";
inherit "/global/player/log";
inherit "/global/player/more_string";
inherit "/global/player/finger";
inherit "/global/player/pweath";
inherit "/std/living/living";
inherit "/global/player/psoul";
inherit "/global/player/guild-race";
inherit "/global/player/more_file";
inherit "/global/player/path";
inherit "/global/player/start_position";
inherit "/global/player/family";
inherit "/global/player/channels";

#define MIN_TIME_TO_SAVE 60
#define LEVEL_CACHE 60

class player_data {
    int _hb_num;
    int _level;
    int _level_time;
    object _snoopee;
    string _my_ident;
    mapping _titles;
    int _update_tmps_call_out;
    int _save_inhibit;
    int _last_save;
    int _quitting;
} /* player_data() */

private int time_on;
private int channel_silenced;
private int all_silenced;
private int max_deaths;
private int monitor;
private int refresh_time;
private int start_time;
private int creator;
private int deaths;
private int last_log_on;
private int no_logins;
private int activity_counter;
private string last_on_from;

private nosave class player_data _player_data;

void start_player();
void public_commands();
int save();
void do_load_auto();
void set_name(string str);
void continue_start_player();
int restart_heart_beat();
int brief_verbose(string, string);
int quit_alt();
int review();
int toggle_wimpy(string);
int do_refresh(int);
int set_prompt( string str );

void create() {
    if( query_name() )
        return;

    living::create();
    events::create();
    psoul::create();
    channels::channel_commands();
    line_ed::create();
    more_string::create();
    start_position::create();
    add_property("determinate", "");

    _player_data = new( class player_data );
    _player_data->_save_inhibit = 1;
    _player_data->_titles = ([ ]);

    time_on = time();
    start_time = time();
    last_log_on = time();

    seteuid("PLAYER");

    Str = NEW_STAT;
    Dex = NEW_STAT;
    Int = NEW_STAT;
    Con = NEW_STAT;
    Wis = NEW_STAT;

    sp = 50;
    max_sp = 50;
    wimpy = 25;
    max_deaths = 100;

    set_desc(0);

    add_ac("bing1", "blunt", 15 );
    add_ac("bing2", "sharp", 15 );
    add_ac("bing3", "pierce", 15 );
    add_property("player", 1 );

    set_cols(79);
    set_rows(24);

    race_ob = CONFIG_DEFAULT_RACE;
    sscanf( file_name(TO), "%s#", my_file_name );
    add_language("common");

} /* create() */

/** @ignore yes */
void dest_me() {
    if( query_name() != "object" && objectp(TP) && TP != TO &&
        file_name(PO) != SHUTDOWN_H && base_name(TP) != LOGIN_OBJ ) {
        user_event( TO, "inform", CAP( TP->query_name() )+" dests "+
            query_cap_name(), "dest");
        tell_object( TO, "You were destructed by "+
            CAP( TP->query_name() )+".\n");
    }

    CHANNEL_H->remove_user();
    ::dest_me();

} /* dest_me() */

/**
 * This method stops the player from being able to save.  This is done while
 * the inventory is regenerating to stop problems with inventory loss due
 * to logging off before it has finished.
 * @see allow_save()
 * @see query_save_inhibit()
 */
void disallow_save() { _player_data->_save_inhibit = 1; }

/**
 * This method allows the player to save again after they have been
 * disallowed.
 * @see disallow_save()
 * @see query_save_inhibit()
 */
void allow_save() { _player_data->_save_inhibit = 0; }

/**
 * This method returns the value of the disallowing save variable.  If this
 * is a non-zero value then the player must not be saved.
 * @see allow_save()
 * @see disallow_save()
 */
int query_save_inhibit() { return _player_data->_save_inhibit; }

private int set_quitting() { _player_data->_quitting = 1; }

/**
 * This method queries whether or not the player is in the
 * middle of quitting.
 * @return 1 if we are quitting, 0 if not
 */
int query_quitting() { return _player_data->_quitting; }

/**
 * This method queries whether or not the player has been silenced.
 * @return 1 if we are silenced, 0 if not
 */
int query_silenced() { return all_silenced; }

/**
 * This method silences the player.
 * @return 1 upon success, 0 upon failure
 */
int set_silenced() {
    if( !adminp( previous_object(-1) ) || creatorp(TO) )
        return 0;

    all_silenced = 1;
    return 1;

} /* set_silenced() */

/**
 * This method removes the silencing from the player.
 * @return 1 upon success, 0 upon failure
 */
int unset_silenced() {
    if( !adminp( previous_object(-1) ) || creatorp(TO) )
        return 0;

    all_silenced = 0;
    return 1;

} /* unset_silenced() */

int query_channel_silenced() { return channel_silenced; }

int set_channel_silenced() {
    if( !adminp( previous_object(-1) ) || creatorp(TO) )
        return 0;

    channel_silenced = 1;
    return 1;

} /* set_channel_silenced() */

int unset_channel_silenced() {
    if( !adminp( previous_object(-1) ) || creatorp(TO) )
        return 0;

    channel_silenced = 0;
    return 1;

} /* unset_channel_silenced() */

/**
 * This is the date on which the character was started.  The very first
 * time the player ever logged on.
 * @return the time at which the player first logged on
 */
int query_start_time() { return start_time; }

/**
 * This method returns the current capitalised name of the player.
 * @return the capitalised name
 */
nomask string query_cap_name() { return CAP( query_name() ); }

/**
 * This method is called from within the login code to start up the
 * new player, set their name and move them into the correct
 * location on the mud.
 * @param bong the name of the player
 * @param new_flag are they a new player?
 * @param c_name their capitalized name
 * @param ident the ident from the authorisation code
 * @param go_invis whether or not we should go invis
 */
void move_player_to_start( string bong, int new_flag, string c_name,
                           string ident, int go_invis ) {
    if( base_name(PO) != LOGIN_OBJ ) {
        write("You don't have clearance to do that.\n");
        return;
    }

    seteuid( "Root" );
    set_name( bong );
    _player_data->_my_ident = ident;

    if( !new_flag )
        unguarded( (: restore_object,
            LOGIN_OBJ->query_player_file_name( query_name() ), 1 :) );

    // Reload timed properties.
    reload_player_properties();
    disallow_save(); // Don't allow saves until the autoload has finished.
    add_property("player", 1 );
    set_short( query_cap_name() );
    add_property("determinate", "");

    if( !query_cols() )
        set_cols(79);

    if( creatorp(TP) ) {
        seteuid( query_name() );
        if( file_size ("/w/"+ query_name() +"/cmds" ) == -2 )
            AddSearchPath( ({ "/w/"+ query_name() +"/cmds" }) );
        AddSearchPath( ({ DIR_PLAYER_CMDS, DIR_SECURE_PLAYER_CMDS,
            DIR_CREATOR_CMDS, DIR_SECURE_CREATOR_CMDS,DIR_PENDING_CMDS }) );
    } else {
        seteuid( "PLAYER" );
        AddSearchPath( ({ DIR_PLAYER_CMDS, DIR_SECURE_PLAYER_CMDS }) );
    }

    if( playtesterp(TP) )
        AddSearchPath( ({ DIR_PLAYTESTER_CMDS}) );

    no_logins++;

    if( time_on > 0 )
        time_on = 0;

    time_on += time();

    printf("You last logged in from %s.\n", last_on_from );

    last_on_from = query_ip_name(TO)+" ("+query_ip_number(TO)+")";

    if( new_flag ){
        add_property("death system","v2");
        add_property("new player!", 1 );
    }
    
    LOGIN_H->player_logon( bong, query_property("guest"),
      ( query_ip_name() ? query_ip_name() : query_ip_number() ) );

    write( LOGIN_H->get_message("/doc/NEWS") );
    call_out( (: continue_start_player :), 0 );

} /*  move_player_to_start() */

/** @ignore yes */
protected void move_to_start_pos() {
    int newp;

    ::move_to_start_pos();

    if( newp = query_property("new player!") )
        remove_property("new player!");

    command( ( query_verbose("look") ? "look" : "glance" ) );

    if( !finger_set() )
        write("%^BOLD%^Please set your finger information with "
            "'chfn'.%^RESET%^\n");

    no_time_left();
    START_PLAYER->logged_on_times(no_logins);

    if( newp )
        add_property("skills version", SKILL_H->query_version() );
    else
        SKILL_H->player_logon();

} /* move_to_start_pos() */

/**
 * @ignore yes
 * This function tracks a players activity to determine whether they're still
 * active or not.
 */
protected void update_activity( int logon ) {
    int offline;

    // Lower their activity score if they haven't been on for
    // more than a week.
    if( last_log_on > 0 ) {
        offline = time() - last_log_on;
        if( offline > 0 )
            activity_counter -= ( offline / (3600 * 24 * 7) ) * 10;
    }

    if( activity_counter <= -55 )
        activity_counter = -55;

    // When they logon give them a couple more activity points.
    // Give them some more for each hour they were on when they leave.
    activity_counter += ( logon ? 3 : 2 * ( (time() - last_log_on ) / 3600) );

    // Set minima and maxima to the counter.
    if( activity_counter >= 0 )
        activity_counter = 0;

    last_log_on = time();

    catch( PLAYER_H->delete_from_cache( query_name() ) );

} /* update_activity() */

/**
 * Return the current value of this players activity_counter
 * (used for debugging)
 */
int query_activity_counter() { return activity_counter; }

/** @ignore yes */
private void check_announcements() {
    mapping news_rc;
    mixed stuff;

    if( !news_rc = BOARD_H->query_newsrc( query_name() ) )
        news_rc = ([ ]);

    stuff = BOARD_H->get_subjects("announcements");

    if( sizeof(stuff) && stuff[<1][B_NAME] != query_cap_name() &&
        stuff[<1][B_TIME] > news_rc["announcements"] )
        write("\nThere are %^YELLOW%^NEW%^RESET%^ announcements.  "
          "You can read them with \"news\".\n\n");

} /* check_announcements() */

/** @ignore yes */
void continue_start_player() {
    string title;

    start_player();
    no_time_left();
    call_out( (: move_to_start_pos :), 0 );

    // Remove passed out property, unless the player is
    // in a trance, e.g. when contemplating.
    if( query_property(PASSED_OUT) && !query_property(TRANCE) )
        call_out( (: remove_property :), 10 + random(30), PASSED_OUT );

    // Check to see if the player has the afk flag.
    // If they do, then remove it along with the afk message.
    if( query_property("afk") ) {
        remove_property("afk");
        remove_property("afk_string");
    }

    remove_property(UNKNOWN_MOVE);
    remove_property(RUNNING_MOVE);

    // For effects.
    init_after_save();

    printf("%s", fix_string( MAIL_H->new_mail( query_name() ) ) );

    check_announcements();

    if( query_property("dead") )
        clone_object(DEATH_SHADOW)->setup_shadow( TO );

    if( query_property("noregen") )
        DEATH->person_died( query_name() );

    exec_alias("login", "");
    update_activity(1);

    title = LIBRARY_H->query_title( query_name() );

    if( stringp(title) )
        _player_data->_titles += (["quest" : title ]);

    if( query_property("new player!") ) {

        user_event( TO, "newbie", query_cap_name()+" arrives on "+
            mud_name()+" for the first time!");
        set_last_pos(CONFIG_NEWBIE_START_LOCATION);
        START_PLAYER->start_player();
    }

    add_language("common");
    check_family_name();

} /* continue_start_player() */

/** @ignore yes */
void start_player() {
    int number;

    if( creator && my_file_name != PLAYER_OBJ ) {
        TP->all_commands();
        TP->app_commands();
        TP->wiz_commands();
    }

    // Call this out with a delay of 2, so that our stats
    // will have time to reset first.
    // - Sandoz.
    call_out( (: do_load_auto :), 2 );

    reset_get();
    enable_commands();
    public_commands();
    channel_commands();
    parser_commands();
    force_commands();
    race_guild_commands();
    soul_commands();
    event_commands();
    finger_commands();
    communicate_commands();
    living_commands();
    logging_commands();
    editor_commands();

    set_no_check(1);

    if( TP->query_property("stats_rearranged") ) {
        set_con(Con);
        set_dex(Dex);
        set_int(Int);
        set_str(Str);
        set_wis(Wis);
    } else {
        set_con(NEW_STAT);
        set_dex(NEW_STAT);
        set_int(NEW_STAT);
        set_str(NEW_STAT);
        set_wis(NEW_STAT);
        add_known_command("rearrange");
    }

    reset_all();
    set_current_path( query_home_dir() );
    set_heart_beat(1);

    if( wimpy > 50 )
        wimpy = 25;

    if( contmp || dextmp || inttmp || strtmp || wistmp )
        _player_data->_update_tmps_call_out = call_out(
            (: update_tmps :), 900 );

    number = max_sp - query_real_max_sp();
    if( number > 0 )
        max_sp -= number;

    BIRTHDAY_H->check_player(TO);

} /* start_player() */

/** @ignore yes */
int adjust_hp( int number, object attacker, object weapon, string attack ) {
    if( !interactive( TO ) )
        return query_hp();
    return ::adjust_hp( number, attacker, weapon, attack );
} /* adjust_hp() */

/**
 * Starts the autoloading process.  This is called just after a player
 * logs in to start up the auto loading process.
 */
void do_load_auto() {
    load_auto_load_alt( query_auto_load_string(), TO, TO, (: tell_object( TO,
          "\n%^CYAN%^Inventory regeneration complete.%^RESET%^\n") :) );
    set_auto_load_string(0);
    allow_save();
} /* do_load_auto() */

/** @ignore yes */
void public_commands() {
    add_command("restart", TO, "", (: restart_heart_beat() :) );
    add_command("save", TO, "", (: save() :) );

    add_command("quit", TO, "", (: quit_alt() :) );
    add_command("review", TO, "", (: review() :) );

    add_command("wimpy", TO, "", (: toggle_wimpy(0) :) );
    add_command("wimpy", TO, "<word'number'>", (: toggle_wimpy($4[0]) :) );

    add_command("refresh", TO, "", (: do_refresh(0) :) );
    add_command("refresh", TO, "me", (: do_refresh(1) :) );

    add_command("prompt", TO, "", (: set_prompt( 0 ) :) );
    add_command("prompt", TO,
        "{on|off|hp|ep|xp"+( TO->query_creator() ? "|wd" : "")+"}",
        (: set_prompt($4[0]) :) );

} /* public_commands() */

/**
 * Force the player to glance.  Forces the player to glance in a
 * certain direction.
 * @param str the direction to glance in
 * @return 0 ifg the command failed, non zer if it succeeded
 */
int glance( string str ) {
    return command("glance" + ( str ? " "+str : "" ) );
} /* glance() */

/**
 * Force the player to look.  Forces the player to look at something
 * or just around.  If the input is set to "" then they look around.
 * @param str what to look at
 * @return 0 if it failed, non zero on success
 * @see efun::command()
 */
int look_me(string str) {
    return command( str ? "look" + str : "look");
} /* look_me() */

/** @ignore yes */
int review() {
    write("Entry  : " + query_msgin() + "\n");
    write("Exit   : " + query_msgout() + "\n");
    write("MEntry : " + query_mmsgin() + "\n");
    write("MExit  : " + query_mmsgout() + "\n");
    write("Editor : " + query_editor() + "\n");
    return 1;
} /* review() */


/**
 * Forces the player to examine something.  This does the same as the look_me
 * function.
 * @see look_me()
 * @return 0 on a failure, non zero on success.
 * @param arg the thing to look at.
 */
int examine( string arg ) {
    return look_me( arg ? " at "+arg : "" );
} /* examine() */

/** @ignore yes */
varargs string short( int dark, int verbose ) {
    string str, family, title;

    str = ( !interactive(TO) ? "the net dead statue of " : "");

    family = query_family_name();
    family = ( family ? " "+family : "");

    if( verbose )
        title = query_player_title();

    title = ( title ? title + " " : "");

    return str + title + living::short( dark ) + family;

} /* short() */

/**
 * This method changes the current value of the wimpy variables.
 * @param str the new value of the wimpy variable
 * @return 0 on failure and 1 on success
 */
int toggle_wimpy( string str ) {
    int number;

    if( !str ) {
        write( ( wimpy ? "You are in wimpy mode, you will run away at "+
            wimpy+"% of your max hps.\n" : "You are in brave mode.\n" ) );
        write("Usage: wimpy <num> (Caution!  Please read help wimpy!)\n");
        return 1;
    }

    if( sscanf( str, "%d", number ) != 1 )
        return notify_fail("You must set your wimpy to a number.\n");

    if( number < 0 || number > 50 )
        return notify_fail("Your wimpy must be between 0 and 50.\n");

    TO->set_wimpy( number );
    printf("Wimpy set to %d%%\n", wimpy );
    return 1;

} /* toggle_wimpy() */

/**
 * This method returns any extra information associated with the score.  This
 * method will mostly be overridden by shadows which wish to place more
 * information into the score command.
 * @return the extra information to place in the score
 */
string extra_score() { return ""; }

/**
 * This method queries whether or not we are old enough to be saved.
 * @return 1 if we are old enough to save, 0 if too young
 */
nomask int query_old_enough_to_save() {
    return -TO->query_time_on() > MIN_TIME_TO_SAVE;
} /* query_old_enough_to_save() */

/**
 * This method is called to save the player to disc.  It will print
 * a message to the player to inform them of the face they have
 * been saved.
 * @return always returns 1
 * @see save_me()
 */
nomask int save() {
    if( query_property("guest") ) {
        if( query_verb() == "save" )
            tell_object( TO, "Not saving for guests... Sorry.\n");
        return 1;
    }

    if( !query_old_enough_to_save() ) {
        if( query_verb() == "save")
            tell_object( TO, "Sorry, you must be at least "+
              time_string(MIN_TIME_TO_SAVE)+" old to save.\n");
        return 1;
    }

    if( my_file_name == PLAYER_OBJ || query_verb() == "save") {
        if( query_verb() == "save") {
            if( _player_data->_last_save + MIN_SAVE_REPEAT > time() ) {
                tell_object( TO, "Please use this command sparingly or it "
                  "lags the mud.\n");
                return 1;
            }
            _player_data->_last_save = time();
        }
        tell_object( TO, "Saving...\n");
    }

    TO->save_me();
    return 1;

} /* save() */

/**
 * Saves the player.  Saves the player to disc, doing all the autoload
 * stuff and such like.
 * @see save()
 */
void save_me() {
    if( query_property("guest") ) {
        if( query_verb() == "save")
            tell_object( TO, "Not saving for guests... Sorry.\n" );
        return;
    }

    if( !query_old_enough_to_save() ) {
        if( query_verb() == "save")
            tell_object( TO, "Sorry, you must be at least "+
              time_string(MIN_TIME_TO_SAVE)+" old to save.\n");
        return;
    }

    if( query_auto_loading() || query_save_inhibit() )
        return;

    if( race_ob )
        race_ob->player_save(TO);

    check_last_pos();

    // For effects.
    effect_freeze();
    effects_saving();

    // Recreating the autoload stuff.
    create_auto_load( all_inventory(), 1 );
    if( interactive(TO) )
        last_on_from = query_ip_name(TO)+" ("+query_ip_number(TO)+")";

    // Keep the time_on calculation as close to the saving as possible.
    time_on -= time();
    // Save timed properties.
    save_player_properties();
    catch( unguarded( (: save_object,
          LOGIN_OBJ->query_player_file_name( query_name() ), 1 :) ) );
    // Reload timed properties.
    reload_player_properties();
    time_on += time();
    ITEM_H->save_all_item_states( TO->query_name() );

    effect_unfreeze();

    // Clear the autoload string after saving to save memory.
    set_auto_load_string(0);

} /* save_me() */

void save_with_auto_load( mixed al ) {
    if( query_property("guest") ) {
        if( query_verb() == "save")
            tell_object( TO, "Not saving for guests... sorry.\n");
        return;
    }

    if( !query_old_enough_to_save() ) {
        if( query_verb() == "save")
            tell_object( TO, "Sorry, you must be at least "+
              time_string(MIN_TIME_TO_SAVE)+" old to save.\n");
        return;
    }

    if( query_save_inhibit() )
        return;

    if( race_ob )
        race_ob->player_save(TO);

    // For effects.
    effect_freeze();
    effects_saving();

    set_auto_load_string(al);

    // Put the time_on calculation as close to the save as possible.
    time_on -= time();
    // Save timed properties.
    save_player_properties();
    catch( unguarded( (: save_object,
          LOGIN_OBJ->query_player_file_name( query_name() ), 1 :) ) );
    // Reload timed properties.
    reload_player_properties();
    time_on += time();

    effect_unfreeze();

} /* save_with_auto_load() */

/**
 * This is the quit code called by the command 'quit'
 * @return 1 if successful, 0 if failed
 * @see quit()
 * @see do_quit()
 */
int quit_alt() {
    object frog;

    if( ENV(TO) && file_name(ENV(TO)) == "/room/departures") {
        if( TO == TP )
            tell_object( TO, "You cannot quit while already in the "
                "departures room.\n");
        return 1;
    }

    if( query_auto_loading() ) {
        if( !interactive(TO) )
            dest_me();
        else
            tell_object( TO, "You cannot quit yet: your inventory is still "
              "being generated.\n");
        return 1;
    }

    if( sizeof( filter( (object *)TO->query_attacker_list(),
        (: living( $1 ) :) ) ) && TP == TO && interactive(TO) ) {
        tell_object( TO, "You cannot quit while in combat.  Use 'stop' to "
            "stop fighting.\n");
        return 1;
    }

    set_quitting();
    check_last_pos();
    update_activity(0);

    // Added to help people tell when the player quits.
    catch( TO->event_quit(TO) );
    catch( editor_check_do_quit() );

    if( query_old_enough_to_save() && !query_property("guest") )
        tell_object( TO, "Saving your inventory.\n");

    event( ENV(TO), "see", query_cap_name()+" leaves the game.\n", TO,
        ({ TO }) );

    catch( move("/room/departures") );

    user_event( TO, "inform", query_cap_name()+" leaves "+mud_name(),
        "logon", TO );

    catch( LOGIN_H->player_logout( query_name() ) );

    if( race_ob )
        catch( race_ob->player_quit(TO) );

    frog = clone_object("/obj/monster/greco");
    frog->move("/room/departures");
    frog->get_rid_of(TO);

    return 1;

} /* quit_alt() */

/**
 * quits the player.
 * @return zero if it failed, non zero on success
 * @see quit()
 * @see quit_alt()
 */
int do_quit() {
    return quit_alt();
} /* do_quit() */

/**
 * A forced quit.
 * This is the function called by external objects to quit
 * a player. It avoids checks for things like being in combat.
 * @return 0 if it failed, non zero if it succeeded.
 * @see do_quit()
 * @see quit_alt()
 * @see efun::command()
 */
int quit() {
    set_quitting();
    check_last_pos();
    update_activity(0);

    catch( editor_check_do_quit() );

    // Added to help people tell when the player quits.
    catch( TO->event_quit(TO) );

    event( ENV(TO), "see", query_cap_name()+" leaves the game.\n", TO,
        ({ TO }) );

    user_event( TO, "inform", query_cap_name()+" leaves "+mud_name(),
        "logon", TO );

    tell_object( TO, "Thanks for playing.  See you next time.\n");

    catch( LOGIN_H->player_logout( query_name() ) );

    if( race_ob )
        catch( race_ob->player_quit(TO) );

    if( query_auto_loading() || query_save_inhibit() ) {
        tell_object( TO, "Forced to quit whilst auto loading.  "
          "Not saving...\n");
        if( catch( dest_me() ) )
            destruct(TO);
        return 1;
    }

    if( !query_old_enough_to_save() || query_property("guest") ) {
        if( catch( dest_me() ) )
            destruct(TO);
        return 1;
    }

    catch( save_me() );
    catch( INV(TO)->set_tracked_item_status_reason("QUIT") );
    catch( INV(TO)->dest_me() );
    catch( ITEM_H->save_all_item_states_delete_cache( TO->query_name() ));

    effects_quiting();

    if( catch( dest_me() ) )
        destruct(TO);

    return 1;

} /* quit() */

/**
 * This method returns the mapping of all the title associated with this
 * player.
 * @return the current mapping of titles
 * @see query_title()
 * @see set_title()
 * @see remove_title()
 */
mapping query_titles() { return copy( _player_data->_titles ); }

/**
 * This method returns the list of titles associated with this player.
 * @return the list of titles
 * @see query_titles()
 * @see set_title()
 * @see remove_title()
 */
string query_title() {
    return implode( values( _player_data->_titles ), ", " );
} /* query_title() */

/**
 * This method sets the current title type to be of a certain name.
 * @param type the type of title to set
 * @param title the string to set it to
 * @see query_title()
 * @see set_title()
 * @see remove_title()
 */
void set_title( string type, string title ) {
    _player_data->_titles[ type ] = title;
} /* set_title() */

/**
 * This method removes the title of the given type from the title mapping.
 * @param type the type of title to remove
 * @see query_title()
 * @see set_title()
 * @see remove_title()
 */
void remove_title( string type ) {
    map_delete( _player_data->_titles, type );
} /* remove_title() */

/**
 * This method returns the number of times the player has died.
 * @return the number of times the player has died
 * @see adjust_deaths()
 * @see adjust_max_deaths()
 */
int query_deaths() { return deaths; }

/**
 * This method changes the number of times the player has died.
 * @see query_deaths()
 * @see adjust_max_deaths()
 */
void adjust_deaths(int i) { deaths += i; }

/** @ignore yes */
protected void set_name( string str ) {
    if( query_name() && query_name() != "object")
        return;
    ::set_name(str);
    set_living_name( query_name() );
    set_main_plural( query_name() );
} /* set_name() */

/* No idea what these are doing here? */
/** @ignore yes */
void init_static_arg( mapping map ) { return; }
/** @ignore yes */
void init_dynamic_arg( mapping map ) { return; }

/** @ignore yes */
string long( string str, int dark ) {
    string s, tmp, title;

    title = query_player_title();
    title = ( title ? title + " " : "" );

    s = "You see "+ title + query_short();

    if( tmp = query_family_name() )
        s += " " + query_family_name();

    s += " "+TITLE_H->query_title(TO)+".\n";

    if( race_ob )
        s += race_ob->query_desc(TO);

    if( dark == 2 || dark == -2 ) {
        s += "It is too ";
        if( dark == 2 )
            s += "dark";
        else
            s += "bright";
        s += " to see "+HIS+" description or what "+HE+" is wearing or "
        "carrying.\n";
        s += calc_extra_look();
    } else {
        if( query_desc() && query_desc() != "" )
            s += CAP(HE) + " " + query_desc() + "\n";
        s += CAP(HE) + " " + TO->health_string(TO,0) + ".\n";
        s += CAP(HE) + " is " + query_position_short() + ".\n";
        if( query_property( PASSED_OUT ) )
            s += CAP(HE)+" appears to be passed out.\n";
        s += calc_extra_look();
        s += weather_extra_look();
        s += query_living_contents(0);
    }

    return s;

} /* long() */

/**
 * This method is called when the player dies.  It creates the corpse
 * and handles all the bits and pieces that should be dealth with
 * when a player dies.
 * <p>
 * If this method returns 0 then the automatic death handling code
 * in the living object is used instead of this.
 * @return always returns 1
 */
mixed second_life() {
    object corpse;

    add_property("dead", time() );

    if( !DEATH->someone_died( TO ) ) {
        if( !creatorp(TO) && !query_property("no die") )
            deaths = deaths + 11;
    } else {
        add_property( PK_KILLED, 1 );
    }

    effects_thru_death();
    corpse = make_corpse();

    if( deaths > max_deaths ) {
        tell_object( TO, "You have died your final death.  "+
            "Your name will be inscribed in the Hall of Legends.\n");
        shout( query_cap_name()+" has died for the last time.  "+
            "All mourn "+HIS+" passing.\n" );
        LIBRARY_H->complete_death( query_name() );
        corpse->add_property("Died Last Time", time() );
        corpse->set_decay( 0 );
    }

    corpse->move( environment() );
    call_out( (: save_me :), 0 );

    DEATH->person_died( query_name() );
    clone_object( DEATH_SHADOW )->setup_shadow( TO );

    gp = 0;
    hp = 0;
    sp = 0;
    xp = 0;

    spells = ([ ]);

    contmp = dextmp = inttmp = strtmp = wistmp = 0;
    remove_call_out( _player_data->_update_tmps_call_out );

    adjust_tmp_con( -2 );
    adjust_tmp_dex( -2 );
    adjust_tmp_int( -2 );
    adjust_tmp_str( -2 );
    adjust_tmp_wis( -2 );

    return corpse;

} /* second_life() */

/**
 * This method removes the ghost from the player.  This stops them
 * being a ghost and turns them back into a real person.
 * @see second_life()
 */
void remove_ghost() {
    if( deaths > max_deaths ) {
        if( TP != TO ) {
            tell_object( TO, TP->query_cap_name()+" tried to raise you, but "
                "you are completely dead.\n");
            tell_object( TP, query_cap_name()+" is completely dead, you "
                "cannot raise "+HIM+".\n");
            return;
        } else {
            tell_object( TO, "You are completely dead.  You cannot be "
                "raised.\n");
            say( query_cap_name()+" struggles to appear in a solid form, but "
                "fails.\n");
            return;
        }
    }

    remove_property("dead");
    remove_property(PK_KILLED);

    tell_object( TO, "You reappear in a more solid form.\n");
    say( query_cap_name()+" appears in more solid form.\n");

    if( query_hp() < 0 )
        set_hp( 1 );

    set_personal_temp(0);

    TO->dest_death_shadow();
    save_me();
    all_inventory()->recovery_from_death();

} /* remove_ghost() */

/**
 * Called when the player goes net dead.  This is called
 * by the driver when a player goes net dead.  Turns them into
 * a statue and stuff.
 */
void net_dead() {
    catch( editor_check_do_quit() );

    if( !environment() || file_name( environment() ) == "/room/departures")
        return;

    if( query_name() == "guest" || query_name() == "root") {
        say( query_cap_name()+" vanishes in a puff of logic.\n");
        quit();
    } else {
        event( ENV(TO), "see", query_cap_name()+" goes white, looks very "
            "chalky and turns into a statue.\n", TO, ({ TO }) );
        user_event( TO, "inform", query_cap_name()+" has lost "+HIS+" link",
            "link-death", TO );
        check_last_pos();
        LOGIN_H->player_net_dead( query_name() );
        save_me();
    }

} /* net_dead() */

/**
 * Checks to see if they have idled out.  This is called from within
 * the heart beat code.
 * @see heart_beat()
 */
void idle_out() {
    event( ENV(TO), "see", query_cap_name()+" has been idle for too long, "+
        HE+" vanishes in a puff of boredom.\n", TO, ({ TO }) );
    tell_object( TO, "You idled out, sorry.\n");
    quit();
} /* idle_out() */

/**
 * The main heart beat function.  This is called by the driver
 * every 2 seconds on the player.  Does all the maintenace
 * stuff like executing commands, fixing up hps and stuff like that.
 */
void heart_beat() {
    int idle_time;

    flush_queue();

    idle_time = ( !interactive(TO) ? time() - last_command : query_idle(TO) );

    if( idle_time > FULL_IDLE ) {
        if( ( LOGIN_H->is_discworld_full() || idle_time > MAX_IDLE ) &&
            ( !interactive(TO) || !creatorp(TO) ) ) {
            call_out( (: idle_out :), 2 );
        }
    }

    if( !interactive(TO) ) {
        if( idle_time > 60 )
            quit();
        return;
    }

    living::heart_beat();
    adjust_sp( 1 );
    living::update_volumes();

    // Reset it every hour to stop it rolling over.
    if( ++_player_data->_hb_num >= 1800 )
        _player_data->_hb_num = 0;

    // Do the news check and personal temperature calculation
    // every few minutes.
    if( !( _player_data->_hb_num % 120 ) )
        calc_personal_temp();

    if( !( _player_data->_hb_num % 900 ) )
        check_announcements();

} /* heart_beat() */

/**
 * Is the monitor turned on?  The hit point monitor which is
 * displyed during combat...
 * @return 1 if it is on, 0 if not
 */
int query_monitor() { return ( monitor & 1 ); }

/**
 * Set the hit point monitor.  This sets the value of the hit point
 * monitor flag.  If it is set to 0, the monitor is turned off.  If
 * it is set to 1 the monitor is turned on.
 * @param i the new value for the hit point monitor flag
 */
void set_monitor( int i ) {
    if( !i )
        monitor &= ~1;
    else
        monitor |= 1;
} /* set_monitor() */

/** @ignore yes */
int set_prompt( string str ) {
    if( !str ) {
        string *arr;

        arr = ({ });

        if( monitor & HP )
            arr += ({"hit points"});
        if( monitor & GP )
            arr += ({"energy points"});
        if( monitor & XP )
            arr += ({"experience points"});
        if( monitor & WD )
            arr += ({"working directory"});

        str = "Your prompt is currently displaying ";

        if( !sizeof(arr) )
            str += "nothing";
        else
            str += query_multiple_short(arr);

        if( monitor & ON ) {
            if( !sizeof(arr) )
                str += ", but has been turned on";
            else
                str += " and has been turned on";
        } else {
            if( sizeof(arr) )
                str += ", but has been turned off";
            else
                str += " and has been turned off";
        }

        write( str+".\n");
        return 1;
    }

    switch( str ) {
      case "on" :
        if( monitor & ON  ) {
            write("Your prompt is already turned on.\n");
            return 1;
        }
        monitor |= ON;
        write("You turn your prompt on.\n");
        return 1;
      case "off":
        if( !( monitor & ON )  ) {
            write("Your prompt is already turned off.\n");
            return 1;
        }
        monitor &= ~ON;
        write("You turn your prompt off.\n");
        return 1;
      case "hp":
        if( monitor & HP ) {
            monitor &= ~HP;
            write("Your prompt will not display "+str+" anymore.\n");
        } else {
            monitor |= HP;
            write("Your prompt will now display "+str+".\n");
        }
      break;
      case "ep":
        if( monitor & GP ) {
            monitor &= ~GP;
            write("Your prompt will not display "+str+" anymore.\n");
        } else {
            monitor |= GP;
            write("Your prompt will now display "+str+".\n");
        }
      break;
      case "xp":
        if( monitor & XP ) {
            monitor &= ~XP;
            write("Your prompt will not display "+str+" anymore.\n");
        } else {
            monitor |= XP;
            write("Your prompt will now display "+str+".\n");
        }
      break;
      case "wd":
        str = "working directory";
        if( monitor & WD ) {
            monitor &= ~WD;
            write("Your prompt will not display your "+str+" anymore.\n");
        } else {
            monitor |= WD;
            write("Your prompt will now display your "+str+".\n");
        }
      break;
      default:
        return notify_fail("Something has broken, please file a bug "
            "report.\n");
    }

    if( !( monitor & HP ) && !( monitor & GP ) &&
        !( monitor & XP ) && !( monitor & WD ) ) {
        monitor &= ~ON;
        write("Your prompt turns itself off as you choose it not to "
            "display "+str+" anymore.\n");
    }

    return 1;

} /* set_prompt() */

/** @ignore yes */
protected void write_prompt() {
    if( !( monitor & ON ) || ( !( monitor & HP ) && !( monitor & GP ) &&
        !( monitor & XP ) && !( monitor & WD ) ) ) {
        efun::tell_object( TO, "> ");
    } else {
        string ret;

        if( monitor & HP ) {
            ret = "Hp: ";

            switch( query_hp() * 100 / query_max_hp() ) {
              case 61..100 :
                ret += "%^GREEN%^";
              break;
              case 31..60 :
                ret += "%^YELLOW%^";
              break;
              default :
                ret += "%^RED%^";
            }

            ret += query_hp()+"%^RESET%^";
        }

        if( monitor & GP ) {
            if( !ret )
                ret = "Ep: ";
            else
                ret += " Ep: ";

            switch( query_gp() * 100 / query_max_gp() ) {
              case 61..100 :
                ret += "%^GREEN%^";
              break;
              case 31..60 :
                ret += "%^YELLOW%^";
              break;
              default :
                ret += "%^RED%^";
            }
            ret += query_gp()+"%^RESET%^";
        }

        if( monitor & XP ) {
            if( !ret )
                ret = "Xp: " + query_xp();
            else
                ret += " Xp: " + query_xp();
        }

        if( monitor & WD ) {
            if( !ret )
                ret = "Dir: "+TO->query_current_path();
            else
                ret += " Dir: "+TO->query_current_path();
        }

        efun::tell_object( TO, fix_string( ret + ">\n") );
    }

} /* write_prompt() */

/**
 * Called when the player wimpies out of a place.  This does all the run
 * away stuff and things like that.
 * @return 1 if succeeded in running away, 0 if not
 */
int run_away() {
    int number;

    become_flummoxed();
    number = ::run_away();

    if( number )
        tell_object( TO, ( number ? "Your feet run away with you!" :
            "You try to run away, but no matter how you scrabble, you can't "
            "find any way out.")+"\n");

    return number;

} /* run_away() */

/**
 * @ignore yes
 * This is needed by the driver.
 */
int query_wizard() { return creator; }

/**
 * The amount of time on line.  This is the total amount of time online
 * in seconds from when they first started playing.  The return from
 * this method is *negative*, you will need to make it positive to use it
 * most likely.
 * @return the total log on time in seconds (the return value is *negative*)
 */
nomask int query_time_on() { return time_on - time(); }

/**
 * This method determins if the player is mature or not yet.  It is based
 *  on the amount of time on.
 * @return 1 if the player is mature, 0 if they are not
 */
int query_mature() { return ( MATURITY * 60 * 60 + time_on < time() ); }

/**
 * This method checks to see if the player can see at the passed
 * in light level.
 * @return -2 or -1 if it is too dark, 1 or 2 if too bright, 0 if they can see
 */
int check_dark( int light ) {
    int i;

    if( query_property("dead") )
        return 0;

    if( race_ob )
        if( catch( i = race_ob->query_dark(light) ) )
            race_ob = CONFIG_DEFAULT_RACE;
        else
            return i;

    return CONFIG_DEFAULT_RACE->query_dark(light);

} /* check_dark() */

/**
 * This method returns the players level.
 * @return their level
 */
int query_level() {
    if( _player_data->_level_time < ( time() - LEVEL_CACHE ) ) {
        _player_data->_level =  STD_GUILD_OBJ->query_level(TO);
        _player_data->_level_time = time();
    }

    return _player_data->_level;

} /* query_level() */

/**
 * Restarts their heartbeat if it has been turned off for some reason.
 * @return always returns 1
 */
int restart_heart_beat() {
    set_heart_beat(1);
    tell_object( TO, "Ok, heart beat restarted.\n");
    return 1;
} /* restart_heart_beat() */

/** @ignore yes */
nomask void set_snoopee( object ob ) { _player_data->_snoopee = ob; }

/**
 * Returns the object snooping us.  If someone is snooping the player it
 * returns the object doing the snooping.  If no one is snooping the player
 * it returns 0.
 * @return the object snooping the player
 * @see efun::snoop()
 */
nomask object query_snoopee() { return _player_data->_snoopee; }

/** @ignore yes */
void set_creator( int i ) {
    if( PO != master() && file_name(PO) != DOMAIN_H ) {
        write("Illegal attempt to set creator!\n");
        log_file("ILLEGAL", this_player(1)->query_name()+" ("+
            file_name(this_player(1))+") Illegal attempt to set_creator "+
            "at "+ctime(time())+" from "+file_name(PO)+"\n");
        return;
    }

    creator = i;
    set_home_dir("/w/"+query_name() );
    save_me();

} /* set_creator() */

/**
 * Prevent the object from shadowing us?  This checks to see if we should
 * prevent this object from shadowing the player.
 * @return 1 if we are prventing the shadow
 */
int query_prevent_shadow( object ob ) {
    if( function_exists("query_prevent_shadow", ob ) ||
        function_exists("query_name", ob ) ||
        function_exists("query_creator", ob ) ||
        function_exists("dest_me", ob ) ||
        function_exists("query_object_type", ob ) ||
        function_exists("save_me", ob ) )
        return 1;
    return 0;
} /* query_prevent_shadow() */

/**
 * Returns the maxium number of deaths.  This is the maxium
 * number of times they can die before they are totally dead.
 * @return the maxium number fo deaths
 */
int query_max_deaths() { return max_deaths; }

/**
 * Sets the maximum number of deaths.  This sets the maximum
 * number of times a player can die.
 * @param i the number of deaths to set it to
 * @see adjust_max_deaths()
 */
void set_max_deaths(int i) { max_deaths = i; }

/**
 * Changes the current number of maxium deaths.  This adjust
 * the number of times a player can die before they are totally dead.
 * @return the current total maximum deaths
 */
int adjust_max_deaths(int i) { return ( max_deaths += i ); }

/** @ignore yes */
varargs int move( mixed dest, string msgin, string msgout ) {
    int i;
    object env;

    env = environment();

    if( !i = living::move( dest, msgin, msgout ) )
        me_moveing(env);

    return i;

} /* move() */

/** @ignore yes */
nomask protected int do_refresh( int me ) {

    if( !me )
        return notify_fail("Please read \"help refresh\" before doing "
            "this!\n");

    if( query_property("guest") )
        return notify_fail("Guest characters cannot refresh, sorry.\n");

    if( creatorp(TO) )
        return notify_fail("You cannot refresh a creator character, please "
          "ask an admin to demote you first.\n");

    write("%^BOLD%^%^RED%^WARNING!%^RESET%^%^RESET%^\nPlease make sure you "
      "have read \"help refresh\" before doing this!\nAre you certain you "
      "wish to refresh yourself?\n%^YELLOW%^Please note you are using the "
      "character "+query_cap_name()+"!%^RESET%^\nAnswer \"YES\" or \"NO\"\n");

    input_to("refresh2");
    return 1;

} /* do_refresh() */

/** @ignore yes */
protected int refresh2( string str ) {
    if( str != "YES") {
        write("Alright, not refreshing you.\n");
        return 1;
    }

    write("Ok, refreshing you.\n");
    say( query_cap_name()+" refreshes "+HIM+"self.\n");

    move_with_look( CONFIG_NEWBIE_START_LOCATION );

    Str = NEW_STAT;
    Dex = NEW_STAT;
    Int = NEW_STAT;
    Con = NEW_STAT;
    Wis = NEW_STAT;

    inttmp = dextmp = wistmp = strtmp = contmp = 0;
    race_ob = CONFIG_DEFAULT_RACE;

    set_al(0);
    set_deity(0);
    languages = ({"common"});
    set_skills(0);

    add_skill_level("general.language.common.spoken", 100 );
    add_skill_level("general.language.common.written", 100 );
    spells = ([ ]);

    xp = 0;
    deaths = 0;
    max_deaths = 100;

    refresh_time = time_on - time();
    refresh_time = -refresh_time;

    totaly_zap_bonus_cache();
    known_commands = ({"skills", "rearrange", "ep"});
    reset_starts();
    race_guild_commands();
    totaly_zap_stat_cache();

    drink_info = allocate( D_SIZEOF );

    map_prop = ([
        "determinate" : "",
        "player" : 1,
        "skills version" : SKILL_H->query_version(),
        "death system" : "v2",
        NEWS_RC : TP->query_property(NEWS_RC),
    ]);

    TO->remove_ghost();
    reset_all();
    set_family_name(0);
    _player_data->_titles = ([ ]);

    all_inventory()->dest_me();

    if( sizeof( all_inventory() ) ) {
        foreach( object ob in all_inventory() ) {
            if( ob )
                destruct(ob);
        }
    }

    // First refresh, then related files.
    REFRESH_H->player_refreshed(TO);
    BULK_DELETE_H->delete_related_files( query_name(), 0 );
    START_PLAYER->start_player();

    user_event( TO, "inform", query_name()+" refreshes "+HIM+"self",
        "refresh", TO );
    write("Done.\n");
    return 1;

} /* refresh2() */

/**
 * This method returns the one letter object type which is used in the
 * finger command to display the type of object.
 * @return the one letter object type
 */
string query_object_type() {
    if( playtesterp( query_name() ) )
        return "p";
    return " ";
} /* query_object_type() */

/** @ignore yes */
void set_my_ident( string str ) {
    if( base_name(PO) != LOGIN_OBJ ) {
        user_event( TO, "inform", "Invalid call to set_my_ident", "cheat");
        return;
    }

    _player_data->_my_ident = str;

} /* set_my_ident() */

/**
 * This method returns the ident of the player.  The ident is
 * determined using the authentication protocol.
 * @return the ident of the player
 */
string query_my_ident() {
    if( PO != find_object("/secure/simul_efun") )
        return 0;
    return _player_data->_my_ident;
} /* query_my_ident() */

/** @ignore yes */
void event_enter( object thing, string mess, object from ) {
    events::event_enter( thing, mess, from );
    living::event_enter( thing, mess, from );
} /* event_enter() */

/** @ignore yes */
void event_exit( object thing, string mess, object to ) {
    events::event_exit( thing, mess, to );
    living::event_exit( thing, mess, to );
} /* event_exit() */

/** @ignore yes */
string *parse_command_id_list() {
    return living::parse_command_id_list() +
    family::parse_command_id_list();
} /* parse_command_id_list() */

/** @ignore yes */
string *parse_command_plural_id_list() {
    return living::parse_command_plural_id_list() +
    family::parse_command_plural_id_list();
} /* parse_command_plural_id_list() */

/** @ignore yes */
string *parse_command_adjectiv_id_list() {
    return living::parse_command_adjectiv_id_list() +
    family::parse_command_adjectiv_id_list();
} /* parse_command_adjectiv_id_list() */

/**
 * This method returns the time at which the player last logged on.
 * @return the last logged on time
 */
int query_last_log_on() { return last_log_on; }

/**
 * This method returns the ip from which the player last logged on.
 * @return the ip address from which they last logged on
 */
string query_last_on_from() { return last_on_from; }

/* This is the time since the last refresh... */
/**
 * This method returns the time at which the player last refreshed.
 * @return the last refresh time
 */
int query_refresh_time() { return refresh_time; }

/**
 * This method returns the number of times the player has logged onto the mud.
 * @return the number of logins
 */
int query_no_logins() { return no_logins; }

/**
 * This method returns if the object is a creator or not.
 * @return 1 if the object is a creator, 0 if not
 */
int query_creator() { return 0; }

/**
 * This method returns the array of our friends.
 * @return our friends array
 */
string *query_friends() { return query_property("friends") || ({ }); }

/**
 * This method will return 1 if the input name is a friend.
 * @param who the person to test for friendship
 * @return 1 if the specified person is our friend or not
 */
int query_friend( string who ) {
    return member_array( who, query_friends() ) != -1;
} /* query_friend() */