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 living inherit.  This inherits all the files
 * needed to be in a living object.
 * @author Pinkfish
 * @changed Removed the effects inherit/code, because
 * /std/container already inherits all that.
 * - Sandoz, April 2003.
 */

#include <dirs.h>
#include <drinks.h>
#include <living.h>
#include <tune.h>
#include <position.h>

inherit "/std/container";
inherit "/std/living/armour";
inherit "/std/living/body";
inherit "/std/living/carrying";
inherit "/std/living/combat";
inherit "/std/living/force";
inherit "/std/living/gender";
inherit "/std/living/health";
inherit "/std/living/holding";
inherit "/std/living/money";
inherit "/std/living/skills";
inherit "/std/living/spells";
inherit "/std/living/stats";
inherit "/std/living/respond_cmd";

#define VERBOSE_TYPES ({"combat", "look", "score", "names", \
                        "htell", "hsay", "finger"})

private int alignment;
private string msgout;
private string msgin;
private string mmsgout;
private string mmsgin;
private string destmsg;
private string deity;
private mixed facing;
private mapping verbose;

private nosave int handicap;
private nosave object dragging, *followers, *to_drop;
private nosave mixed it_them;

void return_to_default_position(int leaving);
void set_position(string name);
void set_position_on(mixed ob);
void set_position_multiple(int mult);
void set_position_type(string type);
object query_position_on();

/*
 * What position are they in?  Standing, sitting, lying, froging?
 */
private nosave string position;
private nosave mixed default_position;
private /* This will force an object to not use the position from the room. */
nosave int always_use_default_position;
/* in case they are standing on something or something... */
private nosave mixed position_on;

void create() {
    string t;

    container::create();
    armour::create();
    combat::create();
    health::create();
    holding::create();
    skills::create();
    spells::create();
    respond_cmd::create();
    enable_commands();
    reset_can_export_inventory();
    reset_effects();
    msgin = "$N arrive$s from $F.";
    msgout = "$N leave$s $T.";
    mmsgin = "$N appear$s out of the ground.";
    mmsgout = "$N disappear$s in a puff of smoke.";
    destmsg = "$N destruct$s $O.";
    followers = ({ });
    to_drop = ({ });
    verbose = ([ ]);

    foreach( t in VERBOSE_TYPES)
        verbose[t] = 1;

    facing = ({ 0, ({ "north", "northeast", "east", "southeast", "south",
                      "southwest", "west", "northwest" }),
                      ({ "up", "down" }) });
    it_them = ({ TO });
    position = STANDING;

} /* create() */

/**
 * This method returns the pronoun string of the living object.
 * A pronoun is "he", "she", "it".
 * @return the pronoun string
 */
string query_pronoun() { return gender::query_pronoun(); }

/**
 * This method returns the prossessive string of the living object.
 * A possessive is "her", "his", "its".
 * @return the possessive string
 */
string query_possessive() { return gender::query_possessive(); }

/**
 * This method returns the objective string of the living object.
 * An objective is "her", "him", "it".
 * @return the objective string
 */
string query_objective() { return gender::query_objective(); }

/** @ignore yes */
int query_weight() {
    if( TO->query_property("dead") )
        return 0;
    return stats::query_weight();
} /* query_weight() */

/**
 * This method returns the actual weight of the living object.
 * This is useful when you need to know the real weight of a ghost,
 * as ghosts weight nothing themselves.
 * @return the actual weight of the living
 */
int query_actual_weight() { return stats::query_weight(); }

/**
 * This method returns the current burden level of the living
 * object.  This is returned as a percentage of the maximum
 * weight that the living can carry.
 * @return the burden level (0-100)
 */
int query_burden() {
    int burden;
    object thing;
    mapping hands;

    update_loc_weight();
    burden = query_loc_weight();
    foreach( thing in query_wearing() )
        burden -= (int)thing->query_complete_weight() / 2;

    hands = ([ ]);
    foreach( thing in query_holding() )
        if( objectp( thing ) )
            hands[ thing ]++;

    foreach( thing in keys( hands ) )
        burden += (int)thing->query_complete_weight() / hands[ thing ];

    if( !query_max_weight() ) {
        TO->reset_carry_cap();
        return 50;
    }

    return ( 100 * burden ) / query_max_weight();

} /* query_burden() */

/**
 * This method returns the current handicap of the living
 * object.
 * @return the current handicap.
 * @see calc_burden()
 */
int query_handicap() { return handicap; }

/**
 * This method calculates the current handicap of the living
 * object.  The handicap is based on the burden of the
 * person, the more burdened the higher the handicap.  The
 * handicap is 1 point of dexterity for every 25% burdened.
 * @see query_handicap()
 * @see query_burden()
 */
void calc_burden() {
    int new_handicap;

    new_handicap = ( query_burden() / 25 ) - 1;
    if( new_handicap < 0 )
        new_handicap = 0;

    if( handicap != new_handicap ) {
        adjust_bonus_dex( handicap - new_handicap );
        handicap = new_handicap;
    }

} /* calc_burden() */

/**
 * This method returns the string representation of the current
 * burden level.
 * @return the burden string
 * @see calc_burden()
 * @see query_burden()
 */
string burden_string() {
    switch( handicap ) {
      case 0 :
        return "unburdened";
      case 1 :
        return "burdened";
      case 2 :
        return "heavily burdened";
      case 3 :
        return "very heavily burdened";
      default :
        return "incredibly heavily burdened";
    }
} /* burden_string() */

/** @ignore yes */
int remove_armour( object thing ) {
    int i;

    i = ::remove_armour( thing );

    if( !i && sizeof( all_inventory() ) > MAX_INVEN ) {
        remove_call_out("test_number_of_items");
        to_drop += ({ thing });
        call_out("test_number_of_items", 5 + random( 5 ) );
    }

    return i;

} /* remove_armour() */

/**
 * This method adds any commands needed by the living inherit.
 */
void living_commands() { combat_commands(); }

/**
 * This method handles the cannot get flags.  This is placed
 * into the living object so that things which are marked as
 * being unable to be picked up can still be put into normal
 * containers.  The upwards checking of containers stops here.
 * This should make it so that objects marked as unable to be
 * picked up cannot be put into objects in the players
 * inventory.
 * @return 1 if the object can be added, 0 if not.
 */
int test_add( object ob, int flag ) { return !flag; }

/**
 * This method handles the cannot drop flags.  This is placed
 * into the living object so that things which are marked as
 * being unable to be dropped can still be remove from normal
 * containers.  This does all sorts of other exciting checks
 * now.
 * @return 1 if the object can be added, 0 if not.
 */
int test_remove( object ob, int flag, mixed dest ) {
    object thing;

    if( flag )
        return 0;

    if( !TP || TP == TO )
        return !flag;

    if( stringp( dest ) )
        thing = find_object( dest );

    if( objectp( dest ) ) {
        thing = dest;
        dest = file_name( dest );
    }

    if( thing->query_corpse() || dest == "/room/rubbish" )
        return !flag;

    /*
     * True theft commands should return 1 to query_theft_command().
     *  Things like the ritual "fumble" and the command "disarm" should return -1.
     */
    if( sizeof( filter( previous_object( -1 ),
        (: $1->query_theft_command() :) ) ) )
        return !flag;

    /* We should now only be considering things like "get", "take" and "palm". */
    if( !query_property( PASSED_OUT ) )
        return 0;

    if( !pk_check( TP, TO ) ) {
        event( ENV( TP ), "theft", TP, TO, ({ ob }) );
        return !flag;
    }

    write("An unseen force stays your hand.\n");
    return 0;

} /* test_remove() */

/**
 * This method returns the current alignment of the living
 * object.
 * @return the current alignment
 * @see set_al()
 * @see adjust_al()
 * @see adjust_alignment()
 * @see align_string()
 */
int query_al() { return alignment; }

/**
 * This method sets the current alignment of the living
 * object.
 * @param number the new alignment for the object
 * @see query_al()
 * @see adjust_al()
 * @see adjust_alignment()
 * @see align_string()
 */
void set_al( int number ) { alignment = number; }

/**
 * This method adjusts the current alignment of the living
 * object.
 * @param number the amount to change the alignment by
 * @return the new alignment
 * @see query_al()
 * @see set_al()
 * @see adjust_alignment()
 * @see align_string()
 */
int adjust_al( int number ) {
    alignment += number;

    if( alignment < -MAX_AL )
        alignment = -MAX_AL;

    if( alignment > MAX_AL )
        alignment = MAX_AL;

    return alignment;

} /* adjust_al() */

/**
 * This method adjusts the current alignment of the living
 * object.  This is called when an object dies and handles the
 * mangling of the change value based on the current alignment and
 * the alignment of the thing dieing.
 * @param number the amount to change the alignment by
 * @return the new alignment
 * @see query_al()
 * @see adjust_al()
 * @see set_al()
 * @see align_string()
 */
int adjust_alignment( int number ) {
    int change;

    // To become more evil you must kill something that is at least 20%
    // good as you are evil and vice versa.
    change = -( number + alignment / 5 );

    // This stops the changes being too extreme. Increase this for smaller
    // changes, decrease it for larger ones.
    change /= 20;

    // Now wasn't that nice and easy? :-)
    return adjust_al( change );

} /* adjust_alignment() */

/**
 * This method returns the string associated with the current
 * alignment of the living object.
 * @return the string associated with the alignment
 * @see query_al()
 * @see adjust_al()
 * @see adjust_alignment()
 * @see set_al()
 */
string align_string() {
    switch ( alignment ) {
    case -MAX_AL .. -5201 : return "Lumen Incarnate"; break;
    case -5200 .. -5001 : return "extremely good"; break;
    case -5000 .. -2501 : return "very good"; break;
    case -2500 .. -1251 : return "quite good"; break;
    case -1250 .. -601 : return "fairly good"; break;
    case -600 .. -301 : return "barely good"; break;
    case -300 .. 300 : return "neutral"; break;
    case 301 .. 600 : return "barely evil"; break;
    case 601 .. 1250 : return "fairly evil"; break;
    case 1251 .. 2500 : return "quite evil"; break;
    case 2501 .. 4800 : return "very evil"; break;
    case 4801 .. 5000 : return "extremely evil"; break;
    default : return "Elytra Incarnate"; break;
    }
} /* align_string() */

/**
 * This method returns the current deity the living object is
 * worshipping.
 * @return the current deity
 * @see /handlers/diety_handler
 * @see set_deity()
 */
string query_deity() { return deity; }
/**
 * This method sets the current deity the living object is
 * worshipping.
 * @param word the new deity
 * @see /handlers/diety_handler
 * @see query_deity()
 */
void set_deity( string word ) { deity = word; }

/**
 * This is the method used to query the current message to use when
 * entering a room.   A $N in the string will be expanded to the
 * name and a $F will be expanded to the from direction.
 * @return the message to print when entering a room.
 * @see /handlers/room_handler
 * @see query_msgout()
 * @see set_msgin()
 */
string query_msgin() { return msgin; }
/**
 * This is the method used to query the current message to use when
 * exiting a room.   A $N in the string will be expanded to the
 * name and a $T will be expanded to the to direction.
 * @return the message to print when entering a room.
 * @see /handlers/room_handler
 * @see query_msgin()
 * @see set_msgout()
 */
string query_msgout() { return msgout; }

/**
 * This is the method used to set the current message to use when
 * entering a room.   A $N in the string will be expanded to the
 * name and a $F will be expanded to the from direction.
 * @param str the message to print when entering a room
 * @see /handlers/room_handler
 * @see query_msgin()
 * @see set_msgout()
 */
int set_msgin(string str) {
    if( strsrch( str, "$N" ) == -1 || strsrch( str, "$F" ) == -1 )
        return 0;
    msgin = str;
    return 1;
} /* set_msgin() */
/**
 * This is the method used to query the current message to use when
 * exiting a room.   A $N in the string will be expanded to the
 * name and a $T will be expanded to the to direction.
 * @return the message to print when entering a room.
 * @see /handlers/room_handler
 * @see query_msgout()
 * @see set_msgin()
 */
int set_msgout(string str) {
    if( strsrch( str, "$N" ) == -1 || strsrch( str, "$T" ) == -1 )
        return 0;
    msgout = str;
    return 1;
} /* set_msgout() */

/**
 * THis is the message to be used when the person is teleported.
 * @return the in message when they teleport
 */
string query_mmsgin() { return mmsgin; }
/**
 * THis is the message to be used when the person is teleported.
 * @return the out message when they teleport
 */
string query_mmsgout() { return mmsgout; }

/**
* This is the message that is returned when they dest something.
* @return the dest message
*/
string query_destmsg() { return destmsg; }

/**
 * The teleport in message.  Sets the message to be seen when
 * a player telerpots into the room.
 * @param str the message to be seen
 */
int set_mmsgin(string str) {
    if( strsrch( str, "$N" ) == -1 )
        return 0;
    mmsgin = str;
    return 1;
} /* set_mmsgin() */

/**
* The dest message. Used when the cre dests something.
* @param str the message to be seen
*/
int set_destmsg( string str ) {
    if( strsrch( str, "$N" ) == -1 )
        return 0;
    if( strsrch( str, "$O" ) == -1 )
        return 0;
    destmsg = str;
    return 1;
} /* set_destmsg() */

/**
 * Sets the teleport out message.  If the player teleports out, this
 * is the message seen.
 * @param str the teleport message
 */
int set_mmsgout(string str) {
    if( strsrch( str, "$N" ) == -1 )
        return 0;
    mmsgout = str;
    return 1;
} /* set_mmsgout() */

mixed query_facing() { return copy( facing ); }

void set_facing( mixed args ) { facing = args; }

string find_rel( string word, int from ) {
    int i;

    if( ( i = member_array( word, facing[ 1 ] ) ) != -1 ) {
        i = ( i + 8 - facing[ 0 ] ) % 8;
        return REL_DIRS[ 3 * i + from ];
    }
    if( ( i = member_array( word, facing[ 2 ] ) ) != -1 )
        return ({ "up", "down" })[ i ];

    return word;

} /* find_rel() */

string find_abs( string word ) {
    int i;

    if( ( i = member_array( word, REL_DIRS ) ) != -1 ) {
        i = ( i / 3 + facing[ 0 ]) % 8;
        return facing[ 1 ][ i ];
    }
    if( ( i = member_array( word, ({ "up", "down" }) ) ) != -1 )
        return facing[ 2 ][ i ];

    return word;

} /* find_rel() */

string reorient_rel( string word ) {
    int i;

    if( ( i = member_array( word, REL_DIRS ) ) != -1 ) {
        i = ( i / 3 + facing[ 0 ] ) % 8;
        facing[ 0 ] = i;
        return facing[ 1 ][ i ];
    }
    if( ( i = member_array( word, ({ "up", "down" }) ) ) != -1 )
        return facing[ 2 ][ i ];

    return word;

} /* reorient_rel() */

void set_dragging( object thing ) { dragging = thing; }

object query_dragging() { return dragging; }

void reset_dragging() { dragging = 0; }

int room_look() {
    if( query_property( UNKNOWN_MOVE ) || !( interactive( TO ) ||
        TO->query_slave() ) )
        return 0;

    /* These need to be evaluated immediately, hence the bypass_queue() call. */
    if( !mapp(verbose) )
        verbose = ([ ]);

    if( verbose && verbose["look"] ) {
        TO->ignore_from_history("look");
        TO->bypass_queue();
        command("look");
    } else {
        TO->ignore_from_history("glance");
        TO->bypass_queue();
        command("glance");
    }

    return 1;

} /* room_look() */

/**
 * This method returns the current verbose mode setting of the player.
 * @param the type of verbosity, by default it will return the normal stuff.
 * @return the verbose mode of the player
 */
int query_verbose(string type) {
    if( !verbose || !mapp(verbose) )
        verbose = ([ ]);
    return verbose[type];
} /* query_verbose() */

/**
 * This method sets the verbosity for a given type.
 */
void set_verbose( string type, int val ) {
    if( !verbose || !mapp(verbose) )
        verbose = ([ ]);

    if( member_array(type, VERBOSE_TYPES) != -1 )
        verbose[type] = val;
} /* set_verbose() */

/**
 * This method returns the current verbose/brief types.
 */
string *query_verbose_types() { return VERBOSE_TYPES; }

varargs int move_with_look( mixed dest, string messin, string messout ) {
    return_to_default_position(1);
    if( (int)TO->move( dest, messin, messout ) )
        return 0;
    room_look();
    return_to_default_position(1);
    return 1;
} /* move_with_look() */

/**
 * This method is called whenever someone enters a command.
 * It is here that the exits of the room are checked to see
 * if the command entered is a move command.
 * @param word the command entered
 * @param verb no idea
 * @param thing the object moving, not really used
 * @return 1 if the command matched an exit and the move
 * was successful, 0 if not
 */
varargs int exit_command( string word, mixed verb, object thing ) {
    string special_mess, *bits, *exits, old;
    int ret;

    if( !environment() )
        return 0;

    if( !verb ) {
        bits = explode( word, " " ) - ({ "", 0 });
        verb = implode( bits, " ");
        if( sizeof( bits ) > 1 )
            word = implode( bits[ 1 .. ], " " );
        else
            word = "";
    } else {
        if( pointerp( verb ) ) {
            special_mess = verb[ 1 ];
            verb = verb[ 0 ];
        }
        bits = explode( verb, " " ) - ({ "", 0 });
        if( sizeof( bits ) > 1 )
            word = implode( bits[ 1 .. ], " " );
        else
            word = "";
    }

    if( LENGTHEN[ verb ] )
        verb = LENGTHEN[ verb ];

    if( !exits = (string *)environment()->query_exits() )
        return 0;

    if( member_array( verb, exits ) != -1 ) {
        if( environment()->query_relative( verb ) )
            return 0;
        if( (ABS_FACING)[ verb ] )
            facing[ 0 ] = (ABS_FACING)[ verb ] % 8;
    } else {
        verb = reorient_rel( verb );
        if( member_array( verb, exits ) == -1 )
            return 0;
    }

    if( !thing )
        thing = TO;

    old = thing->query_current_verb();
    thing->set_current_verb( verb );

    ret = (int)ROOM_H->exit_move( verb, word, special_mess, thing );

    thing->set_current_verb( old );

    return ret;

} /* exit_command() */

void become_flummoxed() {
    int will;

    will = query_int() * query_wis();
    if( will < random( WILL_POWER ) )
        TO->interrupt_ritual();
    if( will < random( WILL_POWER ) )
        TO->interrupt_spell();
    if( will < random( WILL_POWER ) )
        TO->stop_all_fight();
} /* become_flummoxed() */

/**
 * This method is called when the creature wimpies.
 * @return 1 if the wimpying was successful, 0 if not.
 */
int run_away() {
    int i;
    object tp;
    mixed direcs;

    direcs = (mixed)ENV(TO)->query_dest_dir();
    tp = TP;

    set_this_player(TO);

    while( sizeof( direcs ) ) {
        i = random( sizeof( direcs ) / 2 ) * 2;
        if( exit_command(direcs[i]) ) {
            set_this_player(tp);
            return 1;
        }
        direcs = delete( direcs, i, 2 );
    }

    set_this_player(tp);
    return 0;

} /* run_away() */

/** @ignore yes */
mixed stats() {
    return container::stats() + stats::stats() + ({
      ({ "max_hp", max_hp }),
      ({ "hp",  hp }),
      ({ "max_gp", max_gp }),
      ({ "gp", gp }),
      ({ "alcohol", drink_info[ D_ALCOHOL ] }),
      ({ "food", drink_info[ D_FOOD ] }),
      ({ "drink", drink_info[ D_DRINK ] }),
      ({ "gender", query_gender_string() }),
      ({ "alignment", TO->query_al() }),
      ({ "deity", deity }),
      ({ "total money", query_value() }),
      ({ "xp", query_xp() }),
    }) + armour::stats() + combat::stats();
} /*  stats() */

/**
 * This method returns the current array used for calculating 'it' and
 * 'them' in the find_match code.
 * @return the array of objects matching them
 * @see /secure/simul_efun->find_match()
 * @see set_it_them()
 */
mixed query_it_them() { return it_them; }
/**
 * This method sets the current array used for calculating 'it' and
 * 'them' in the find_match code.
 * @param args the new array of objects
 * @see /secure/simul_efun->find_match()
 * @see query_it_them()
 */
void set_it_them( mixed args ) { it_them = args; }

/**
 * This method adds a follower to the living object.  A follower will
 * happily follow around the person in front.  Used in the follow
 * command.
 * @param ob the object to follow us
 * @see remove_follower()
 * @see query_followers()
 * @return 1 on success, 0 on failure
 */
int add_follower( object ob ) {
    if( ob == TO )
        return 0;

    if( member_array( ob, followers ) == -1 )
        followers += ({ ob });

    return 1;

} /* add_follower() */

/**
 * This method removes a follower from the living object.  A follower will
 * happily follow around the person in front.  Used in the unfollow
 * and lose commands.
 * @param ob the object to remove from the follow list
 * @see add_follower()
 * @see query_followers()
 * @return 1 on success, 0 on failure
 */
int remove_follower(object ob) {
    int i;

    if( ( i = member_array( ob, followers ) ) != -1 ) {
        followers = delete( followers, i, 1 );
        return 1;
    }

    return 0;

} /* remove_follower() */

/**
 * This is a method to check to see if this object can actually follow
 * the person they are following.
 * @param thing the thing following us
 * @param verb the direction they are going to
 * @param special any special stuff
 * @return 1 if we are allowed to go there, 0 otherwise
 */
int check_doing_follow(object thing, string verb, string special) {
    return 1;
} /* check_doing_follow() */

/**
 * This method returns the current room of the object.  This was needed
 * previously to use in things like unique_array, before function
 * pointers came into existance.
 * @return the environment of the object
 */
object query_current_room() { return environment(); }

/**
 * This method returns the current list of followers to the living
 * object.
 * @see add_follower()
 * @see remove_follower()
 */
mixed query_followers() { return copy(followers); }

/** @ignore yes */
varargs void adjust_money(mixed amt, string type) {
    return money::adjust_money(amt, type);
} /* adjust_money() */

/** @ignore yes */
mixed query_money_array() {
    return money::query_money_array();
} /* query_money_array() */

/** @ignore yes */
int query_money(string type) {
    return money::query_money(type);
} /* query_money() */

/** @ignore yes */
int query_value() { return money::query_value(); }

/** @ignore yes */
void event_enter( object thing, string mess, object from ) {
    if( ENV( thing ) == TO ) {
        call_out( "calc_burden", 1 );
        if( sizeof( all_inventory() ) > MAX_INVEN ) {
            remove_call_out( "test_number_of_items" );
            to_drop += ({ thing });
            call_out( "test_number_of_items", 5 + random( 5 ) );
        }
    }
} /* event_enter() */

/** @ignore yes */
void event_exit( object thing, string mess, object to ) {
    if( ENV( thing ) == TO )
        call_out("calc_burden", 1 );
} /* event_exit() */

/** @ignore yes */
void test_number_of_items() {
    int i, how_many;
    object thing, *things;

    how_many = sizeof( all_inventory() - query_armours() ) -
               ( MAX_INVEN + query_dex() );
    if( how_many < 1 ) {
        to_drop = ({ });
        return;
    }
    things = ({ });
    for( i = 0; ( i < how_many ) && ( i < sizeof( to_drop ) ); i++ ) {
        thing = to_drop[ i ];
        if( !thing )
            continue;
        if( ENV( thing ) != TO || !thing->short() || thing->drop() ||
            thing->query_property("cannot fumble") )
            continue;
        if( !(int)thing->move( environment() ) )
            things += ({ thing });
    }

    to_drop = ({ });
    if( !sizeof( things ) )
        return;

    tell_object( TO, "Whoops!  You tried to carry too many things "+
        "and fumbled "+ query_multiple_short( things ) +".\n" );
    TO->dest_hide_shadow();
    tell_room( environment(), the_short()+" juggles around "+
        query_possessive() +" stuff and fumbles "+
        query_multiple_short( things ) +".\n", TO );
} /* test_number_of_items() */

/** @ignore yes */
object *find_inv_match( string words, object looker ) {
    return sort_array( container::find_inv_match( words, looker ),
        (: ( member_array( $1, query_holding() ) != -1 ? -1 : 0 ) :) );
} /* find_inv_match() */

/** @ignore yes */
int attack_by(object ob) {
    return_to_default_position(0);
    return ::attack_by(ob);
} /* attack_by() */

/** @ignore yes */
int attack_ob(object ob) {
    return_to_default_position(0);
    return ::attack_ob(ob);
} /* attack_ob() */

/**
 * This method sets the always the flag to always use the default position.
 * If this is set then rooms cannot override the position message which is
 * displayed by the object.
 * @param flag if we should always use the default position
 * @see query_always_use_default_position()
 * @see set_default_position()
 * @see return_to_default_position()
 */
void set_always_use_default_position(int flag) {
    always_use_default_position = flag;
} /* set_always_use_default_position() */

/**
 * This method sets the always the flag to always use the default position.
 * If this is set then rooms cannot override the position message which is
 * displayed by the object.
 * @return the always use default position flag
 * @see set_always_use_default_position()
 * @see set_default_position()
 * @see return_to_default_position()
 */
int query_always_use_default_position() {
    return always_use_default_position;
} /* query_always_use_default_position() */

/**
 * This method sets the default position of the object.  This is used to
 * allow things to default to some other exciting off beat and froopy
 * default position.  The value returned by this is the command code
 * used to put the object back into the default position or an
 * array which contains three or one elements, the first is the string
 * to use as the position, the second and third (if they exist) are
 * the string to tell the person when changing and the string to tell
 * everyone else when changing position.
 * @return the default position
 * @see set_default_position()
 * @see return_to_default_position()
 * @see set_always_use_default_position()
 */
string query_default_position() {
    mixed pos;

    if( stringp(default_position) &&
        default_position->query_position_command() ) {
        pos = default_position;
    } else if( pointerp(default_position) &&
        ( sizeof(default_position) == POSITION_MESS_SIZE ||
        sizeof(default_position) == POSITION_ONLY_TYPE_SIZE ) ) {
        pos = default_position;
    } else if( functionp(default_position) ) {
        pos = default_position;
    }

    if( !pos )
        pos = STANDING_CMD;

    return pos;

} /* query_default_position() */

/**
 * This sets the default position of the object.  This is used to
 * allow things to default to some other exciting off beat and froopy
 * default position.  The paramater to this is the command code
 * used to put the object back into the default position or an
 * array which contains three or one elements, the first is the string
 * to use as the position, the second and third (if they exist) are
 * the string to tell the person when changing and the string to tell
 * everyone else when changing position.  The paramer can also be
 * a function pointer, if it is then it will be evaluated and
 * have two parameters passed into the function.  The first is
 * the object returing to the position and the second is the leaving
 * flag.
 * <p>
 * Please note!  After setting the position you will need to
 * make the object return to the default position to use it.
 * <p>
 * A second note!  A room can also define a query_default_position()
 * function which will be called, if this returns a value (and the
 * override flag is not set) then that will be used for the default
 * position.
 * @param str the new default position
 * @see query_default_position()
 * @see set_always_use_default_position()
 * @see /obj/monster()->set_cannot_change_position()
 * @see return_to_default_position()
 * @example
 * set_default_position("/cmds/living/kneel");
 * @example
 * set_default_position(({ "running" }));
 * @example
 * set_default_position(({ "fishing",
 *                         "You start to fish.\n",
 *                         the_short() + " starts to fish.\n" }));
 * @example
 * npc->set_default_position(({ "running" }));
 * npc->return_to_default_position();
 */
void set_default_position(mixed str) {
    if( stringp(str) && str->query_position_command() &&
        str != STANDING_CMD ) {
        default_position = str;
    } else if( !str || str == STANDING_CMD ) {
        default_position = 0;
    } else if( pointerp(str) && ( sizeof(str) == POSITION_ONLY_TYPE_SIZE ||
        sizeof(str) == POSITION_MESS_SIZE ) ) {
        default_position = str;
    } else if( functionp(str) ) {
        default_position = str;
    }
} /* set_default_position() */

/**
 * This method returns the living object to its default position.
 * @param leaving this is if we are leaving the room
 * @see set_default_position()
 * @see query_default_position()
 * @see set_always_use_default_position()
 */
void return_to_default_position(int leaving) {
    mixed pos;

    /* See if we are being forced to always use the set default position. */
    if( query_always_use_default_position() ) {
        pos = query_default_position();
    } else {
        /* See if the room has a default position they wish to tell us about. */
        pos = 0;
        if( environment() )
            pos = environment()->query_default_position(TO);
        if( !pos )
            pos = query_default_position();
    }

    if( functionp(pos) ) {
        if( !evaluate( pos, TO, leaving ) ) {
            pos = 0;
            /* See if the environment has any special conditions */
            if( environment() )
                pos = environment()->query_default_position(TO);
            if( !pos )
                pos = STANDING_CMD;
        }
    }

    if( stringp(pos) ) {
        /* If we are not standing up...  Stand up... */
        if( position != pos->query_position_type() ||
            ( leaving && query_position_on() ) ) {
            if( leaving ) {
                catch( pos->position_floor(TO) );
            } else {
                /*
                 * If they are not leaving, just get them to stand up or
                 * whatever, this way people can fight on chairs and
                 * stuff...
                 */
                catch( pos->position(TO) );
            }
        }
    } else if( pointerp(pos) && position != pos[POSITION_TYPE_INDEX] ) {
        /* If it is a pointer, then we do something special... */
        if( sizeof(pos) > 1 ) {
            if( pos[POSITION_ME_MESS_INDEX] )
                tell_object(TO, pos[POSITION_ME_MESS_INDEX]);
            if( pos[POSITION_REST_MESS] )
                tell_room(environment(), pos[POSITION_REST_MESS], TO);
        }
        set_position( pos[POSITION_TYPE_INDEX] );
        set_position_on(0);
        set_position_type(0);
        set_position_multiple(0);
    }
} /* return_to_default_position() */

/**
 * This sets the current position of the object.
 * @param name the string to use for the position
 * @see query_position()
 * @see query_position_on()
 * @see query_position_multiple()
 * @see query_position_type()
 * @see set_position_on()
 * @see set_position_multiple()
 * @see set_position_type()
 */
void set_position(string name) {
    position = name;
} /* set_position() */

/**
 * This queries the current position of the object.
 * @return the current position of the living
 * @see query_position_on()
 * @see query_position_multiple()
 * @see query_position_type()
 * @see set_position()
 * @see set_position_on()
 * @see set_position_multiple()
 * @see set_position_type()
 */
string query_position() {
    return position;
} /* query_position() */

/**
 * This sets the current object which is being referenced as being
 * 'on', 'beside' or 'at'.
 * @param ob the object being referenced
 * @see query_position()
 * @see query_position_on()
 * @see query_position_multiple()
 * @see query_position_type()
 * @see set_position()
 * @see set_position_multiple()
 * @see set_position_type()
 */
void set_position_on(mixed ob) {
    if( !position_on )
        position_on = allocate(POSITION_ARRAY_SIZE);
    position_on[POS_ON_OBJECT] = ob;
} /* set_position_on() */

/**
 * This sets fact that the object being referenced is one of many.  So
 * you get something more like 'xx is sitting on one of the couches'.
 * @param mult 0 if non-multiple, 1 if multiple
 * @see query_position()
 * @see query_position_on()
 * @see query_position_multiple()
 * @see query_position_type()
 * @see set_position()
 * @see set_position_multiple()
 * @see set_position_type()
 */
void set_position_multiple(int mult) {
    if( !position_on )
        position_on = allocate(POSITION_ARRAY_SIZE);
    position_on[POS_MULTIPLE] = mult;
} /* set_position_multiple() */

/**
 * This returns fact that the object being referenced is one of many.  So
 * you get something more like 'xx is sitting on one of the couches'.
 * @return 0 if non-multiple, 1 if multiple
 * @see query_position_on()
 * @see query_position_multiple()
 * @see query_position_type()
 * @see set_position()
 * @see set_position_on()
 * @see set_position_multiple()
 * @see set_position_type()
 */
int query_position_multiple() {
    if( !position_on )
        return 0;
    return position_on[POS_MULTIPLE];
} /* query_position_multiple() */

/**
 * This sets way the object is being referenced.  The 'on', 'at', 'beside'
 * or whatever strings.
 * @param type the new type string
 * @see query_position()
 * @see query_position_on()
 * @see query_position_multiple()
 * @see query_position_type()
 * @see set_position()
 * @see set_position_on()
 * @see set_position_multiple()
 */
void set_position_type(string type) {
    if( !position_on )
        position_on = allocate(POSITION_ARRAY_SIZE);
    position_on[POS_TYPE] = type;
} /* set_position_type() */

/**
 * This returns way the object is being referenced.
 * The 'on', 'at', 'beside'
 * or whatever strings.
 * @return the current type string
 * @see query_position()
 * @see query_position_on()
 * @see query_position_multiple()
 * @see set_position()
 * @see set_position_on()
 * @see set_position_multiple()
 * @see set_position_type()
 */
string query_position_type() {
    if( !position_on || !position_on[POS_TYPE] )
        return "on";
    return position_on[POS_TYPE];
} /* query_position_type() */

/**
 * This queries the current object being referenced.  This can be an
 * object or a string.
 * @return the current object being referenced
 * @see query_position()
 * @see query_position_multiple()
 * @see query_position_type()
 * @see set_position()
 * @see set_position_on()
 * @see set_position_multiple()
 * @see set_position_type()
 */
object query_position_on() {
    if( !position_on )
        return 0;
    return position_on[POS_ON_OBJECT];
} /* query_position_on() */

/**
 * This method returns the short description of the object
 * we are referencing.
 * @return the short description of the object, "" if none
 * @see query_position_on()
 * @see set_position_on()
 * @see query_position_long()
 */
string query_position_on_short() {
    if( !position_on || !position_on[POS_ON_OBJECT] )
        return "";
    if( stringp(position_on[POS_ON_OBJECT]) )
        return position_on[POS_ON_OBJECT];
    return position_on[POS_ON_OBJECT]->the_short();
} /* query_position_on_short() */

/**
 * This method returns the string used in the long description of the
 * living object.
 * @return the long description of the position
 * @see query_position_type()
 * @see query_position_on_short()
 */
string query_position_long() {
    if( position != STANDING || position_on ) {
        if( position_on ) {
            return query_pronoun() + " is " + query_position_type() + " "+
                   query_position_on_short()+".\n";
        }
        return query_pronoun()+" is "+position+" on the floor.\n";
    }
    return "";
} /* query_position_long() */

/**
 * This method returns the description used in the inventory listing
 * code.
 * @return the string used in inventory listings
 * @see query_position_long()
 * @see query_position_on_short()
 * @see query_position_type()
 */
string query_position_short() {
    if( !position_on || !position_on[POS_ON_OBJECT] )
        return position;
    return position + " " + query_position_type() + " " +
        query_position_on_short();
} /* query_position_short() */

/**
 * This method returns 1 if the creature is trapped, ie cannot walk.
 * By default, a creature is free to walk, hence the normal return
 * value of 0.  If you shadow this method, including a message about
 * why the player cannot move move is a good idea.
 * @return 0 means creature is free to move, 1 that it is trapped.
 * @see no_use_doors, exit_command
 */
int cannot_walk() { return 0; }

/**
 * This method returns 1 if the creature shouldn't be able to use
 * closed doors.
 * By default, any creature is able to move through closed doors
 * by opening them, so the default value is 0.
 * If you shadow this method, including a message about why the
 * player cannot move in a particular direction, is a good idea.
 * @return 0 means creature is free to move through closed doors,
 * 1 that it cannot.
 * @see cannot_walk, exit_command
 */
int no_use_doors() { return 0; }

/**
 * This method can be shadowed by all forms of magical and
 * religious shields so that the shields command will give
 * the player a nice description.
 * The first element in the array should contain the description
 * as shown to the player, the second element should contain the
 * description shown to others.
 * @example ({ "You have a nice shield.", "He has a nice shield." })
 * @return Array with description of shield.
 */
string *query_arcane_shields() { return ({ }); }

/** @ignore yes */
int can_find_match_reference_inside_object( object thing, object looker ) {
    if( member_array(thing, query_wearing_hidden( looker, 0 ) ) != -1 )
        return 0;
    return 1;
} /* can_find_match_reference_inside_object() */

/** @ignore yes */
void dest_me() {
    LIVING_H->living_dested();
    ::dest_me();
} /* dest_me() */

/** @ignore yes */
void heart_beat() {
    stats::heart_beat();
    combat::heart_beat();
} /* heart_beat() */