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: armour.c,v 1.23 2003/05/21 03:44:20 ceres Exp $
 * 
 */
/**
 * This file contains all the armour related code for the living
 * objects.
 * @author Pinkfish
 */
#include <clothing.h>
#include <function.h>
#include <race.h>
#include <armour.h>

inherit "/std/armour_logic";

#undef INFORM 1

nosave string skin;
nosave object *wearing;
nosave mixed stopped;
nosave mixed *_armour_callbacks;
nosave int *_cids;

void create() {
   skin = "morphological field";
   wearing = ({ });
   if(!_armour_callbacks)
     _armour_callbacks = ({ ({ }), ({ }), ({ }) });
   
   if(!_cids)
     _cids = ({ 0, 0, 0 });
   
   ::create();
} /* create() */

/**
 * Register a callback for magical protection.
 *
 * @param level How close the protection is to the skin.
 * @param callback The object & function to be called.
 * @param data Any extra data to be passed.
 * @return an ID to identify this callback.
 *
 * @example:
 * register_armour_callback(ARM_INNER,
 *                          ({ "/std/effects/religious/shield", "callback" }),
 *                          ({ "pishe" });
 *
 * The callback function will be called as:
 *
 * callback(player, type, amount, zone, ({ "pishe" }));
 *
 */
int register_armour_callback(int level, mixed callback, mixed data) {
  _armour_callbacks[level] += ({ new(class armour_callback,
                                     id : ++(_cids[level]),
                                     callback: callback,
                                     data : data) });
  return _cids[level];
}

/**
 * Remove a registered callback, used when the protection ends.
 *
 * @param level The level of the callback
 * @param id The callbacks ID.
 *
 * @see register_armour_callback()
 */
int remove_armour_callback(int level, int id) {
  int i;

  for(i=0; i<sizeof(_armour_callbacks[level]); i++) {
    if((_armour_callbacks[level][i])->id == id) {
      _armour_callbacks[level] -= ({ _armour_callbacks[level][i] });
      return 1;
    }
  }

  return 0;
}

/**
 * Update the data for an armour callback.
 *
 * @param level The level of the callback
 * @param id The callbacks ID.
 * @param data The new data.
 *
 * @see register_armour_callback()
 */
int update_armour_callback(int level, int id, mixed data) {
  int i;
  
  for(i=0; i<sizeof(_armour_callbacks[level]); i++) {
    if((_armour_callbacks[level][i])->id == id) {
      _armour_callbacks[level][i]->data = data;
      return 1;
    }
  }
  return 0;
}

/**
 * Query all the callback data. This should typically only be used for
 * debugging purposes.
 */
mixed *query_armour_callbacks() { return copy(_armour_callbacks); }

/**
 * This method returns the current skin of the living object.
 * @return the skin of the object
 * @see set_skin()
 */
string query_skin() { return skin; }

/**
 * This method sets the current skin of the living object.  This can
 * be done by the race object and by specific spells or effects.
 * @param word the new skin type
 * @see query_skin()
 */
void set_skin( string word ) { skin = word; }

/**
 * This method returns all the objects you are currently wearing.
 * @return the current array of worn objects
 * @return the array of worn stuff
 * @see query_armours()
 */
object *query_wearing() {
   wearing = filter(wearing, (: $1 && environment($1) == this_object() :));
   return copy( wearing );
} /* query_wearing() */

/**
 * This method returns all the armours that the is currently being
 * worn.  This will always return the same value as query_wearing()
 * @see query_wearing()
 * @return the array of armours
 */
object *query_armours() {
   return query_wearing();
} /* query_armours() */

/**
 * This method will make sure all the armours are unworn by the living
 * object.
 * @see query_wearing()
 */
void clear_armours() {
   wearing->set_worn_by( 0 );
   wearing = ({ });
} /* clear_armours() */

/**
 * This returns the object which stopped the blow.  This is only valid
 * inside and after a query_ac() call.
 * @return the object which stopped the call
 */
mixed query_stopped() {
   return stopped;
} /* query_stopped() */

/**
 * This method sets the object which stops the call.  This should be
 * used to do weird stuff.  I have no idea what it should be used for
 * at all and I am just rambling.
 * @param arg the new value of the stopped object
 */
void set_stopped( mixed arg ) { stopped = arg; }

/**
 * This method checks to see if the two armour types are
 * equivilant or not.
 * @param comp the first type
 * @param type the second type
 */
protected int equivalent_armour_types( mixed comp, string type ) {
   string word;

   if ( stringp( comp ) ) {
      if ( CLOTHING_HANDLER->query_equivilant_type( comp ) ) {
         return CLOTHING_HANDLER->query_equivilant_type( comp ) == type;
      }
      return comp == type;
   }
   foreach ( word in comp ) {
      if ( equivalent_armour_types( word, type ) )
         return 1;
   }
   return 0;
} /* equivalent_armour_types() */

/**
 * This is the method used to get the living object to wear a piece of
 * armour or clothing.  This is called from inside the armour or clothing
 * code itself.  It will call the function set_worn_by() on the
 * armour or clothing and if this returns a non-zero result then it
 * will add it into the current list of worn types.  Assuming the
 * type of the armour fits into the allowed list.  It will also
 * call the functon hold_item on the object if it is required to be
 * held as well (ie: shield).
 * @param armour the armour to wear
 * @param doing_hold if this is called by the hold command
 * @return the failure message, or 0 if ok
 * @see remove_armour()
 * @see query_armours()
 * @see query_wearing()
 */
string wear_armour( object armour, int doing_hold ) {
   int no_limbs;
   string type, word, fail_mess;
   mixed types;
   object thing;
   mapping things;

   if (environment(armour) != this_object()) {
      return "must be in your inventory";
   }

   wearing -= ({ 0 });
   if (member_array(armour, wearing) > -1)
     return "since you already have " + armour->query_objective() + " on";

   types = armour->query_type();
   word = this_object()->not_allowed_to_wear( types );
   if ( word ) {
      return word;
   }
   things = ([ ]);
   if ( stringp( types ) ) {
      types = ({ types });
   }
   if ( !pointerp( types ) ) {
      return "oh dear";
   }
   foreach ( type in types ) {
      if ( CLOTHING_HANDLER->query_equivilant_type( type ) ) {
         type = CLOTHING_HANDLER->query_equivilant_type( type );
      }
      things[ type ] = ({ });
      foreach ( thing in wearing ) {
         if ( equivalent_armour_types( (mixed)thing->query_type(), type ) )  {
            things[ type ] += ({ thing });
         }
      }
   }
   word = (string)this_object()->query_race_ob();
   
   if ( !word )
     return "no race object";
   
   foreach ( type in keys( things ) ) {
      if ( (int)word->query_number_worn( type ) <= sizeof( things[ type ] ) ) {
         return "since you are already wearing "+
               query_multiple_short( things[ type ] );
      }
   }
   no_limbs = (int)armour->query_no_limbs();
   if ( no_limbs && !doing_hold ) {
      if ( member_array( armour,
            (object *)this_object()->query_holding() ) != -1 ) {
         return "already wearing";
      }
      if( sizeof( (int *)armour->hold_item( this_object(), -1 ) ) ) {
         return 0;
      } else {
         return "already holding";
      }
   }
   if ( !armour->set_worn_by( this_object() ) ) {
      if( fail_mess = armour->query_wear_failure_mess() )
         return fail_mess;
      else
         return "oh dear";
   }
   wearing += ({ armour });
   this_object()->do_burden_call();
   return 0;
} /* wear_armour() */

/**
 * This method will remove the armour from the living object.
 * @param thing the armour to remove
 * @return 1 if was unsuccessful and 0 if it was successful
 * @see wear_armour()
 * @see query_armours()
 * @see query_wearing()
 */
int remove_armour( object thing ) {
   int i;

   wearing -= ({ 0 });
   i = member_array( thing, wearing );
   if ( i == -1 ) {
      return 1;
   }
   if ( !thing->set_worn_by( 0 ) ) {
      return 1;
   }
   if ( member_array( thing, (object *)this_object()->query_holding() ) != -1 ) {
      if ( !sizeof( (int *)this_object()->set_unhold( thing ) ) ) {
         return 1;
      }
   }
   wearing = delete( wearing, i, 1 );
   this_object()->do_burden_call();
   return 0;
} /* remove_armour() */

/**
 * This function returns the amount of damage that can be blocked
 * by the armour on a specified zone.  It automatically
 * damages the armour, and sets the stopped object to be the
 * the object (piece of armour) that stopped the blow.
 *
 * @param type The type of damage, eg: "sharp", "blunt", "pierce".
 * @param amount The amount of damage that is being done.
 * @param zone The zone which the damage is being done through, eg: "head".
 * @return The amount of damage that will be blocked.
 * @see query_wearing()
 */
varargs int query_ac( string type, int amount, string zone ) {
  int part, total, i, max;
  string word, *types;
  mixed most;
  object thing;
  object *defenses;
  
  stopped = 0;
#ifdef INFORM
  event( environment(), "inform", "zone "+ zone, "combat" );
#endif
  
  if ( !zone ) {
    switch(random(21)) {
    case 0..1: zone = "head"; break;
    case 2: zone = "neck"; break;
    case 3..6: zone="chest"; break;
    case 7..9: zone="abdomen"; break;
    case 10..12: zone = "arms"; break;
    case 13..14:
      zone = "hands"; break;
    case 15..18: zone = "legs"; break;
    case 19: zone = "feet"; break;
    case 20: zone = "back"; break;
    }
#ifdef INFORM
    event( environment(), "inform", "picked zone "+ zone,
           "combat" );
#endif
  }

  // Do the 'outside the armour' callbacks.
  if(sizeof(_armour_callbacks[ARM_OUTER]) && amount) {
    for(i=0; i<sizeof(_armour_callbacks[ARM_OUTER]); i++) {
      if(!_armour_callbacks[ARM_OUTER][i]->callback[0])
        remove_armour_callback(ARM_OUTER,
                               _armour_callbacks[ARM_OUTER][i]->id);
      else {
        part = call_other(_armour_callbacks[ARM_OUTER][i]->callback[0],
                          _armour_callbacks[ARM_OUTER][i]->callback[1],
                          this_object(),
                          type, amount, zone,
                          _armour_callbacks[ARM_OUTER][i]->data);
        if(part > max) {
          max = part;
          most = stopped;
        }
        total += part;
        amount -= part;
        if(amount < 1)
          break;
      }
    }
  }
  
  if(zone != "self" && amount > 0) {
    types = CLOTHING_HANDLER->query_clothing_zone( zone );
    if(!types) {
      log_file("ARMOUR_DEBUG", "No types for zone: %s", zone);
      return 0;
    }
    
    foreach ( word in  types) {
      wearing -= ({ 0 });
      defenses = wearing + filter_array(this_object()->query_holding(),
                                        (: $1 && $1->query_armour() :));
      foreach ( thing in defenses )
        if ( equivalent_armour_types( (mixed)thing->query_type(), word ) ) {
#ifdef INFORM
          event( environment(), "inform", "testing object "+
                 thing->short(), "combat" );
#endif
          part = (int)thing->query_ac( type, amount, zone );
          if (!stopped && part)
            stopped = thing;
          if(part > max) {
            max = part;
            most = stopped;
          }
          total += part;
          amount -= part;
        }
      if (amount < 1)
        break;
    }
  }

  // Do the 'against the skin' callbacks.
  if(sizeof(_armour_callbacks[ARM_INNER]) && amount > 0) {
    for(i=0; i<sizeof(_armour_callbacks[ARM_INNER]); i++) {
      if(!_armour_callbacks[ARM_INNER][i]->callback[0])
        remove_armour_callback(ARM_INNER,
                               _armour_callbacks[ARM_INNER][i]->id);
      else {
        part = call_other(_armour_callbacks[ARM_INNER][i]->callback[0],
                          _armour_callbacks[ARM_INNER][i]->callback[1],
                          this_object(),
                          type, amount, zone,
                          _armour_callbacks[ARM_INNER][i]->data);
        if(part > max) {
          max = part;
          most = stopped;
        }
        total += part;
        amount -= part;
        if(amount < 1)
          break;
      }
    }
  }

  // Does their race have special ac?
  if(amount > 0 && this_object()->query_race_ob() &&
     function_exists("query_ac", load_object(this_object()->query_race_ob()))){
    part = (this_object()->query_race_ob())->query_ac(type, amount, zone);
    if(part > max) {
      max = part;
      most = stopped;
    }
    total += part;
    amount -= part;
  }

  // Now do their skin.
  if(amount > 0) {
    if(!stopped && type != "skin")
      stopped = skin;

    // Dry them out if fire gets through.
    if(type == "fire") {
      if(this_object()->effects_matching("body.wetness") &&
         sizeof((int *)this_object()->effects_matching("body.wetness"))) {
        this_object()->add_effect("/std/effects/other/wetness", -amount );
      }
    }
    
    // Do the bodies personal AC.
    part = ::query_ac(type, amount, zone);
    if(part > max) {
      max = part;
      most = stopped;
    }
    total += part;
    amount -= part;
  }
  
  if(amount > 0 && most) {
    stopped = most;
  }
  return total;

}

/** @ignore yes */
mixed *stats() {
   return ::stats() + ({
      ({ "skin", skin }),
   });
} /* stats() */