dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
/*  -*- LPC -*-  */
/*
 * $Locker:  $
 * $Id: living.c,v 1.72 2003/03/07 03:24:37 ceres Exp $
 *
 */
/**
 * The main living inherit.  This inherits all the files
 * needed to be in a living object.
 * @author Pinkfish
 */
#include <dirs.h>
#include <drinks.h>
#include <living.h>
#include <move_failures.h>
#include <player.h>
#include <tune.h>
#include <position.h>
#include <obj_parser.h>

inherit "/std/container";
inherit "/std/living/armour";
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/crafts";
inherit "/std/living/stats";
inherit "/std/living/respond_cmd";
inherit "/std/living/nationality";

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

//The maximum amount of religious favour you can have.
#define MAX_FAVOUR 100

class living_data {
  int handicap;
  int burden;
  object* followers;
  class obj_match_context it_them;
  object* to_drop;
  int burden_call;
}

class messages {
   string msgout;
   string msgin;
   string mmsgout;
   string mmsgin;
}

private int alignment;
private class messages _messages;
private mixed *facing;
private mapping verbose;
private mapping abs_facing = ABS_FACING;
private mapping lengthen = LENGTHEN;

//Got religion?
private string deity;         //Your deity of choice.
private mapping deity_favour; //A mapping of deity ratings.

//private nosave object _dragging;
private nosave class living_data _liv_data;
//private nosave int _handicap;
//private nosave object *_followers;
//private nosave class obj_match_context _it_them;
//private nosave object* _to_drop;
//private nosave int _burden_call;

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();
protected mixed command(string);

/*
 * 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;

   _liv_data = new(class living_data);
   _messages = new(class messages);
   crafts::create();
   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();
   _messages->msgin = "$N arrive$s from $F.";
   _messages->msgout = "$N leave$s $T.";
   _messages->mmsgin = "$N appear$s out of the ground.";
   _messages->mmsgout = "$N disappear$s in a puff of smoke.";
   _liv_data->followers = ({ });
   verbose = ([ ]);
   set_max_items(50);
   _liv_data->to_drop = ({ });
   foreach(t in VERBOSE_TYPES) {
      verbose[t] = 1;
   }

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

   add_adjective("living");
} /* create() */

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

/**
 * 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();
} /* 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();
} /* 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();
} /* query_objective() */

/** @ignore yes */
varargs int query_weight(int actual) {
  if(!actual && this_object()->query_property("dead"))
    return 0;
  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() {
  return _liv_data->burden;
} /* query_burden() */

/**
 * This method returns the current handicap of the living
 * object.
 * @return the current handicap.
 * @see calc_burden()
 */
int query_handicap() { return _liv_data->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;
  int burden;
  object thing;
  mapping hands;
  
  _liv_data->burden_call = 0;
  
  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()) {
    this_object()->reset_carry_cap();
    _liv_data->burden = 50;
  } else
    _liv_data->burden = (100 * burden) / query_max_weight();
  
  new_handicap = (_liv_data->burden / 25) - 1;
  if(new_handicap < 0)
    new_handicap = 0;
  
  if ( _liv_data->handicap != new_handicap ) {
    adjust_bonus_dex( _liv_data->handicap - new_handicap );
    _liv_data->handicap = new_handicap;
  }
}

/**
 * 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 (_liv_data->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() */

/**
 * This method adds any commands needed by the living inherit.
 */
void living_commands() {
#if efun_defined(add_action)
   add_action( "exit_command", "*", 1 );
#endif
} /* living_commands() */

/**
 * This method allows you to make the living object eat something.
 * @param food the food object to eat
 */
void eat_this( object food ) {
  this_object()->bypass_queue();
  command( "eat " + file_name( food ) );
} /* eat_this() */

/**
 * 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) {
  if(sizeof(all_inventory(this_object())) > query_max_items())
    return 0;
  
  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 ( !this_player() || ( this_player() == this_object() ) ) {
      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_array( 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( this_player(), this_object() ) ) {
      event( environment( this_player() ), "theft", this_player(),
            this_object(), 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 .. -5001 : return "extremely good"; break;
      case -5000 .. -2501 : return "very good"; break;
      case -2500 .. -1251 : return "quite good"; break;
      case -1250 .. -601 : return "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 "evil"; break;
      case 1251 .. 2500 : return "quite evil"; break;
      case 2501 .. 5000 : return "very evil"; break;
      default : return "extremely evil"; break;
   }
} /* align_string() */

/**
 * This method returns the current deity the living object is
 * worshipping.
 * @return the current deity
 * @see /obj/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 /obj/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 /obj/handlers/room_handler
 * @see query_msgout()
 * @see set_msgin()
 */
string query_msgin() { return _messages->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 /obj/handlers/room_handler
 * @see query_msgin()
 * @see set_msgout()
 */
string query_msgout() { return _messages->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 /obj/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;
   }
   _messages->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 /obj/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;
   }
   _messages->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 _messages->mmsgin; }
/**
 * THis is the message to be used when the person is teleported.
 * @return the out message when they teleport
 */
string query_mmsgout() { return _messages->mmsgout; }

/**
 * 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;
   }
   _messages->mmsgin = str;
   return 1;
} /* set_mmsgin() */

/**
 * 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;
   }
   _messages->mmsgout = str;
   return 1;
} /* set_mmsgout() */

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

/**
 * The facing array is a list of directions and two integers which determine
 * which way we face.  The layout is:<br>
 * ({ facing, ({ dirs }), up_down_facing, ({ up_down_dirs }) })
 * @param args the facing arguments
 */
void set_facing( mixed *args ) { facing = args; }

/**
 * This method finds the relative direction from the passed in direction.
 * @param word the exit name ('east', 'west',...)
 * @param from the offset to find the exit from
 * @return the relative direction
 */
string find_rel( string word, int from ) {
  int i;

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

/**
 * Finds the absolute direction from the input relative direction.
 * @param word the exit name ('left', 'right', ...)
 * @return the absolute direction
 */
string find_abs( string word ) {
  int i;

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

/**
 * This method takes in a relative direction and reorients us in the correct
 * way to go in that direction.  This also updates our facing so we are
 * facing in the specified relative direction.
 * @param word the direction to look up
 * @return the real direction
 */
string reorient_rel( string word ) {
  int i;

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

/**
 * This method takes in a absolute direction and reorients us in the correct
 * way to go in that direction.
 * @param word the direction to look up
 */
void reorient_abs( string verb ) {
  if ((ABS_FACING)[verb]) {
    facing[0] = (ABS_FACING)[verb] % 8;
  }
} /* reorient_rel() */

/**
 * This method sets the object for us to drag when we try and leave.
 * @param thing the object to drag off
 */
void set_dragging( object thing ) { add_property("dragging", thing); }

/**
 * This method returns the object we are dragging.
 * @return the thing we are dragging
 */
object query_dragging() { return query_property("dragging"); }

/**
 * This method resets the object we are dragging.
 */
void reset_dragging() { add_property("dragging", 0); }

/**
 * This is used by the movement system to look in the room when we move.
 * It does checks for verbose and other checks before doing the look.
 */
int room_look() {
   if ( query_property( UNKNOWN_MOVE ) || !( interactive( this_object() ) ||
         this_object()->query_slave() ) )
      return 0;
   /* These need to be evaluated immediately, hence the bypass_queue() call. */
   if(!mapp(verbose))
     verbose = ([ ]);

   if(verbose && verbose["look"]) {
      this_object()->ignore_from_history( "look" );
      this_object()->bypass_queue();
      command( "look" );
   } else {
      this_object()->ignore_from_history( "glance" );
      this_object()->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;
  }
}

/**
 * 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)this_object()->move( dest, messin, messout ) != MOVE_OK )
      return 0;
   room_look();
   return_to_default_position(1);
   return 1;
} /* move_with_look() */

varargs int exit_command( string word, mixed verb, object thing, int redirection ) {
   string special_mess, *bits, *exits, redirect;
   int temp;

   if ( !environment() ) {
      return 0;
   }

   if ( !verb ) {
      verb = word;
      bits = explode( word, " " );
      if ( sizeof( bits ) > 1 ) {
         word = implode( bits[ 1 .. ], " " );
      } else {
         word = "";
      }
   } else {
      if ( pointerp( verb ) ) {
         special_mess = verb[ 1 ];
         verb = verb[ 0 ];
      }
      bits = explode( verb, " " );
      if ( sizeof( bits ) > 1 ) {
         word = implode( bits[ 1 .. ], " " );
      } else {
         word = "";
      }
   }
   if ( lengthen[ verb ] ) {
      verb = lengthen[ verb ];
   }
   exits = (string *)environment()->query_exits();
   if ( !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 {
     if (member_array(find_abs(verb), exits ) == -1 ) {
       return 0;
     }
     verb = reorient_rel(verb);
   }
   if ( !thing ) {
      thing = this_object();
   }

    //If the player has redirection enabled!
    //Redirection returns a string which is an alternative exit to try.
    //It calls exit_command to do all of the proper checks before hand,
    //it blocks recursion by way of a flag which is passed as the fourth arg
    //in exit command.
    if ( !redirection ) {
        if ( stringp( redirect = thing->query_exit_redirection( word ) ) ) {
            if ( temp = this_object()->exit_command( verb, redirect, thing, 1 ) ) 
                return temp;
        }
    }

   return (int)"/obj/handlers/room_handler"->exit_move( verb, word,
         special_mess, thing );
} /* exit_command() */

void become_flummoxed() {
   int will;

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

int run_away() {
   int i;
   object old_env;
   mixed *direcs;
   
   direcs = (mixed *)environment()->query_dest_dir(this_object());
   old_env = environment();
   while ( sizeof( direcs ) ) {
      i = random( sizeof( direcs ) / 2 ) * 2;
      if ( exit_command( direcs[i] ) ) {
          event( old_env, "run_away", direcs[ i ], direcs[ i + 1 ] );
          return 1;
      }

      direcs = delete( direcs, i, 2 );
   }
   return 0;
} /* run_away() */

/* Now handled in test_remove().
int cannot_get_stuff() { return !query_property( PASSED_OUT ); }
*/

/** @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", this_object()->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()
 */
class obj_match_context query_it_them() { return _liv_data->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( class obj_match_context args) { _liv_data->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 == this_object()) {
    return 0;
  }
  if (member_array(ob, _liv_data->followers) == -1) {
    _liv_data->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;

  i = member_array(ob, _liv_data->followers);
  if (i != -1) {
    _liv_data->followers = delete(_liv_data->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(_liv_data->followers - ({ 0 })); }

/** @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(); }

void do_burden_call() {
  if(_liv_data->burden_call)
    remove_call_out(_liv_data->burden_call);
  
  _liv_data->burden_call = call_out("calc_burden", 1);
}

int query_burden_limit() {
  if (this_object()->query_creator()) { 
    return MAX_CREATOR_INVEN;
  } else {
    return MAX_INVEN;
  }
} /* query_burden_limit() */ 

/** @ignore yes */
void event_enter( object thing, string mess, object from ) {
  if(environment( thing ) == this_object()) {
    do_burden_call();
    
    if(sizeof(all_inventory()) > query_burden_limit() ) {
      _liv_data->to_drop += ({ thing });
      remove_call_out("test_number_of_items");
      call_out("test_number_of_items", 5 + random(5));
    }
  }
}

/** @ignore yes */
void event_exit( object thing, string mess, object to ) {
  if(environment(thing) == this_object()) {
    do_burden_call();
  }
}

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

   things = all_inventory() - query_armours() - query_holding();
   how_many = sizeof(things) - query_burden_limit();
   if ( how_many < 1 ) {
      return;
   }

   _liv_data->to_drop -= ({ 0 });

   dropped = ({ });
   while(how_many > 0 && sizeof(things)) {
      if (sizeof(_liv_data->to_drop)) {
         thing = _liv_data->to_drop[random(sizeof(_liv_data->to_drop))];
      } else {
         thing = things[random(sizeof(things))];
      }
      things -= ({ thing });
      _liv_data->to_drop -= ({ thing });

      if(!thing || !thing->short() || thing->drop() ||
         thing->query_property("cannot fumble") ||
         thing->id("coin") ||
         environment(thing) != this_object()) {
        continue;
      }

      if((int)thing->move(environment()) == MOVE_OK) {
        how_many--;
        dropped += ({ thing });
      }
   }

   _liv_data->to_drop = ({ });

   if(sizeof(dropped)) {
     tell_object( this_object(), "Whoops!  You tried to carry too many "
                  "things and fumbled "+
                  query_multiple_short( dropped ) +".\n" );
     this_object()->dest_hide_shadow();
     tell_room( environment(), capitalize( the_short() ) +" juggles "+
                "around "+ query_possessive() +" stuff and fumbles "+
                query_multiple_short( dropped ) +".\n", this_object() );
   }
}

/**
 * This forces a burden recalculation.  This should also be used to
 * force a recalcuation of the number of items someone can carry.
 */
void force_burden_recalculate() {
   do_burden_call();
   remove_call_out("test_number_of_items");
   call_out("test_number_of_items", 5 + random(5));
}

/** @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(1);
 */
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(this_object());
      }
      if (!pos) {
         pos = query_default_position();
      }
   }

   if (functionp(pos)) {
      if (!evaluate(pos, this_object(), leaving)) {
         pos = 0;
         /* See if the environment has any special conditions */
         if (environment()) {
            pos = environment()->query_default_position(this_object());
         }
         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(this_object()));
         } 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(this_object()));
         }
      }
   } 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(this_object(), pos[POSITION_ME_MESS_INDEX]);
         }
         if (pos[POSITION_REST_MESS]) {
            tell_room(environment(), pos[POSITION_REST_MESS], this_object());
         }
      }
      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.
 * @param verb the exit direction that the player is trying to move.
 * @param dest_other the destination information for the exit.
 * @see /std/room->query_dest_other()
 * @return 0 means creature is free to move, 1 that it is trapped.
 */
varargs int cannot_walk( string verb, mixed *dest_other) {
   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() */

/**
 * If there is no mapping for deity favour, or if the God is not mentioned, 
 * return 0 as 'no favour'.
 * Otherwise return the favour amount.
 * @args God Name of God
 */
int query_deity_favour( string god ) {
  if ( !mapp( deity_favour ) ) 
    return 0;

  if ( !undefinedp( deity_favour[ god ] ) ) 
    return 0;

  return deity_favour[ god ];
}

/**
 * Adjust the favour rating for 'god' by amount.
 * A +ve amount is good favour, a negative is bad.
 */
void adjust_deity_favour( string god, int amount ) {

  if ( !mapp( deity_favour ) ) 
    deity_favour = ([ ]);
  
  if ( !undefinedp( deity_favour[ god ] ) ) 
    deity_favour[ god ] = amount;

  deity_favour[ god ] += amount;

  if ( deity_favour[ god ] > MAX_FAVOUR )
    deity_favour[ god ] = MAX_FAVOUR;

  if ( deity_favour[ god ] < -MAX_FAVOUR )
    deity_favour[ god ] = -MAX_FAVOUR;

  return;
}

/**
 * Return the deity favour mapping.
 */
mapping query_all_deity_favour() { return deity_favour; }