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: armoury.c,v 1.34 2002/11/10 02:17:42 ceres Exp $
 */
/**
 * Keeps track of all the standard armours, weapons and clothing.
 *
 * @see /include/armoury.h
 * @index armour
 * @index weapon
 * @index scabard
 * @index clothing
 * @index clothes
 * @index jewellery
 * @index misc
 * @index plants
 * @author Furball
 * @changes Many many, by many people
 * @changes 4/1/97 Ceres
 * The discworld armoury was rewritten by Ceres on 4/1/97 to handle
 * subdirectories within the standard dirs.
 * @changes 5/2/2001 Pinkfish
 * Changed to allow the various domains to have their own armoury
 * subdirectories that can be found and specified with a flag to the
 * creation sequences.
 * @changes 23 Apr 2001 Ceres
 * Removed the recycling. It was a lot of overhead for little benefit.
 * @changes 24 Aug 2001 Siel
 * added /obj/misc/, /obj/plants/ and /obj/furnitures/ to the request list
 */
#include <move_failures.h>
#include <armoury.h>

/* two week timeout */
#define MAX_RECYCLE 6


inherit "/std/room/basic_room";

#define DEFAULT_RECYCLE_AREA "default"
#define SAVE "/save/armoury"
#define TYPES ({"armours", "clothes", "weapons", "plants", "foods", "scabbards", "jewelleries", "misc" })

private nosave int _total_requests;

private mapping _smalls;
private mapping _armour_list;
private mapping _weapon_list;
private mapping _clothing_list;
private mapping _jewellery_list;
private mapping _scabbard_list;
private mapping _food_list;
private mapping _misc_list;
private mapping _plant_list;
private mapping _areas;
private mapping forbidden;

private void rehash_all();
int rehash(string place);
string* walk_directory (string);

/** @ignore yes */
void save_me() {
   unguarded( (: save_object(SAVE, 3) :));
} /* save_me() */

/** @ignore yes */
void load_me() {
   unguarded( (: restore_object(SAVE, 1) :));
} /* load_me() */

void setup() {
   set_short( "" + mud_name() + " Armoury" );
   add_property( "determinate", "the " );
   set_light( 50 );
   set_long( "You are in the " + mud_name() + " Armoury.  From here you can list "
         "all of the \"weapons\", \"armour\", \"clothing\", \"jewellery\", "
         "\"food\", \"plants\", \"misc\" "
         "and \"scabbards\" that are available, and \"request\" one of "
         "them.  The armoury stores its list of items in mappings, which "
         "can be updated with \"rehash\".  The list of forbidden items "
         "can be listed out or added to with \"forbid\".\n" );
   _smalls = ([ ]);
   _areas = ([ ]);
   _armour_list = _weapon_list = _clothing_list = _plant_list = _misc_list =
      _jewellery_list = _scabbard_list = _food_list = ([ ]);
   // If it is in the boot sequence
   load_me();
   rehash_all();
} /* setup() */

/**
 * This returns the list of small objects available for the area.  These
 * are things that can be fgound in gutters and so on.
 * @param area the area of the recycling
 * @return the array of small objects
 */
object *query_smalls(string area) {
   if (!area) {
      area = DEFAULT_RECYCLE_AREA;
   }
   return _smalls[area];
}

/**
 * Returns the list of domain armoury items.
 * @param domain the domain/area to get the items from.
 * @return the area sub-mapping.
 */
mapping query_area(string domain) {
  if (_areas[domain]) {
      return _areas[domain];
  }

  return ([ ]);
} /* query_area() */

int request(string, int, string);
int forbid(string);

/** @ignore yes */
void init() {
   string comm;
   ::init();
   add_command("rehash", "{foods|clothes|weapons|armours|misc|jewelleries|"
                         "scabbards|plants}",
                (:rehash($4[0]) :));
   add_command("rehash", "domain <string'domain'>",
                (:rehash($4[0]) :));
   add_command("request", "<string'item name'> <number'percent'>",
                (:request($4[0], $4[1], 0):));
   add_command("request", "<string'item name'> <number'percent'> in <string'area'>",
               (:request($4[0], $4[1], $4[2]):));
   add_command("forbid", "", (:forbid, "":));
   add_command("forbid", "<string'name'>", (:forbid($4[0]):));
   foreach(comm in ({"weapons", "armour", "clothing", "jewellery", "plant",
                     "misc", "scabbards", "food", })) {
      add_command(comm, "", (:call_other(this_object(), $(comm)):));
   }
} /* init() */

/* Internal Functions */

// create a list of armours/whatever.  base_dir is the dir to look in,
// extensions is the file extensions to look for.  The base_dir will be
// recursed to find all files in sub-dirs as well.
/** @ignore yes */
mapping make_list(string base_dir, string *extensions) {
  string *dirs, dir, extension, file_name;
//   mixed *tmp, *file;
  mapping list;

  dirs = walk_directory (base_dir);

  // make a mapping of names to filenames
  list = ([ ]);
  foreach(dir in dirs) {
    foreach(extension in extensions) {
      foreach(file_name in unguarded((: get_dir, dir+"*"+extension :))) {
        if (file_name[0] != '.') {
          list[ replace_string(explode(file_name, ".")[0], "_", " ") ] =
                    dir + "" + file_name;
        }
      }
    }
  }

  return list;
} /* make_list() */


/** @ignore yes */
int clean_up(int i) { return 0; }

// External functions

/**
 * This will choose a small item from the specific area.
 * @param area the are to check in
 * @return the small object to choose
 */
object choose_small_item(string area) {
  object ob;

  if(!area)
    area = DEFAULT_RECYCLE_AREA;

  if(!_smalls || !_smalls[area] || !arrayp(_smalls[area]) || !_smalls[area][0])
    return 0;

  ob = clone_object(_smalls[area][0]);
  _smalls[area] = _smalls[area][1..];
  return ob;
}

/**
 * General item retreival function.  It returns a new item
 * it handles any sort of item.  The percentage is the
 * percentage condition in which it is returned.
 * The "word" parameter is the name of the requested item, essentially
 * the filename without directory and with "_"'s changed to " "'s. The
 * "percent" parameter is used as measure of how good it
 * is compared to a fully functional one. So a 50% dagger is only 50% as
 * good as a 100% one.
 * <p>
 * The file armoury.h defines the ARMOURY variable.  You need to include
 * this into your file to use it.  You should include this file and
 * uyse ythis define rather than the full path to the armoury, as
 * otherwise your code could stuff up :)
 * @param word the name of the item to retreive
 * @param percent the percentage condition to be in
 * @param area the area to choose the item in
 * @see /include/armoury.h
 * @return the requested object, or 0 on failure
 * @example
 * // get a slightly worn long sword and give it to the npc.
 * ARMOURY->request_item("long sword", 85)->move(npc);
 * @example
 * // Get a random condition armour.
 * armour = ARMOURY->request_item("leather jacket", random(100));
 */
object request_item(string word, int percent, string area) {
  int add_area;
  object thing;
  string filename;

  if(!word) {
    return 0;
  }
  if (!area) {
    area = DEFAULT_RECYCLE_AREA;
  }

  if (_areas[area] &&
      _areas[area][word]) {
    filename = _areas[area][word];
    add_area = 1;
  } else if(_weapon_list[word]) {
    filename = _weapon_list[word];
  } else if(_armour_list[word]) {
    filename = _armour_list[word];
  } else if(_clothing_list[word]) {
    filename = _clothing_list[word];
  } else if(_jewellery_list[word]) {
    filename = _jewellery_list[word];
  } else if(_scabbard_list[word]) {
    filename = _scabbard_list[word];
  } else if(_misc_list[word]) {
    filename = _misc_list[word];
  } else if(_plant_list[word]) {
    filename = _plant_list[word];
  } else if(_food_list[word]) {
    filename = _food_list[word];
  } else {
    if(base_name(previous_object()) != "/cmds/creator/req_uest") {
      printf( "No file for item \"%s\".\n", word );
      log_file( "ARMOURY", "%s No file for %s (%s)\n", ctime(time())[4..9],
                word, file_name( previous_object() ) );
    }
    return 0;
  }

  if(file_size( filename ) > 0)
    thing = clone_object(filename);

  if(!thing) {
    printf( "Cannot find item \"%s\".\n", word );
    log_file( "ARMOURY", "Cannot find %s (%s)\n", word,
              file_name( previous_object() ) );
    return 0;
  }

  _total_requests++;

  if(!_smalls[area])
    _smalls[area] = ({ });

  // If there's less than 20 items in the smalls list and this item meets
  // all the criteria then add it.
  if(sizeof(_smalls[area]) < 20 &&
     thing->query_weight() < roll_MdN(5, 20) && // must be small
     thing->query_value() < random(4000) && // not too valuable
     !thing->query_liquid() && // must not be a liquid
     !sizeof((mapping)thing->query_value_info()) &&
     strsrch(filename, "_pt") == -1 && // not in pt
     strsrch(filename, "_dev") == -1 && // not in dev
     !thing->query_property("no recycling")) { // must be recyclable
    _smalls[area] += ({ filename });
  }

  if (add_area)
    thing->add_property(ARMOURY_RECYCLING_AREA_PROP, area);

  thing->set_percentage( percent );
  return thing;
} /* request_item() */

/**
 * This method tries to find a match for the object if it has moved between
 * directories.
 * @param path the old path
 * @return the new path
 */
string remap_file_path(string path) {
   string* bits;
   mapping list;
   string new_fname;

   bits = explode(path, "/");
   if (bits[0] != "obj") {
      return path;
   }
   switch (bits[1]) {
   case "armours" :
      list = _armour_list;
      break;
   case "weapons" :
      list = _weapon_list;
      break;
   case "clothes" :
      list = _clothing_list;
      break;
   case "jewellery" :
      list = _jewellery_list;
      break;
   case "scabbards" :
      list = _scabbard_list;
      break;
   case "food" :
      list = _food_list;
      break;
   case "misc" :
      list = _misc_list;
      break;
   case "plants" :
      list = _plant_list;
      break;
   }

   if (list) {
      new_fname = list[replace_string(explode(bits[<1], ".")[0], "_", " ")];
      if (new_fname) {
         return new_fname;
      }
   }

   return path;
} /* remap_file_path() */

// Action functions

// Update the list of known items
/** @ignore yes */
int rehash(string thing) {
  string special;
  int found;

  switch (thing) {
  case "armours" :
     _armour_list=make_list("/obj/armours/", ({".arm", ".c"}));
     break;
  case "clothes" :
     _clothing_list=make_list("/obj/clothes/", ({".clo", ".c"}));
     break;
  case "weapons" :
     _weapon_list = make_list("/obj/weapons/", ({".wep", ".c"}));
     break;
  case "scabbards" :
     _scabbard_list = make_list( "/obj/scabbards/", ({ ".sca", ".c" }));
     break;
  case "jewellery" :
  case "jewelleries" :
     _jewellery_list = make_list( "/obj/jewellery/", ({ ".arm", ".clo", ".c" }));
     break;
  case "food" :
  case "foods" :
     _food_list = make_list( "/obj/food/", ({ ".ob", ".food", ".c" }));
     break;
  case "misc" :
     _misc_list = make_list( "/obj/misc/", ({ ".ob", ".c" }));
     break;
  case "plants" :
     _plant_list = make_list( "/obj/plants/", ({ ".ob", ".food", ".c" }));
     break;
  default :
    // Rehash the domains...
    if (file_size("/d/" + thing + "/items") == -2) {
      _areas[thing] = make_list( "/d/" + thing + "/items/",
                                  ({ ".arm", ".c", ".clo", ".wep", ".sca",
                                     ".ob", ".food" }));
      found = 1;
    }
    if (file_size("/d/" + thing + "/armoury") == -2) {
      foreach (special in get_dir("/d/" + thing + "/armoury")) {
         if (file_size("/d/" + thing + "/armoury/" + special + "/") == -2) {
           _areas[special] = make_list( "/d/" + thing + "/armoury/" + special + "/",
                                  ({ ".arm", ".c", ".clo", ".wep", ".sca" }));
         }
      }
       return 0;
    }
  }

  save_me();

  write("Rehash of " + thing + " complete.\n");
  return 1;
}

/**
 * This method rehashes a specific directory of things.  At the moment we
 * fudge this a little.
 * @param dir the directory to rehash
 * @return 1 if it found something to rehash
 */
int rehash_specific_dir(string dir) {
   return rehash(explode(dir, "/")[1]);
}

/**
 * This will only be called in the bootup sequence -- yea right! I've made it
 * work a little more slowly.
 */
private void rehash_all() {
  string thing;
  int i;

  foreach(thing in TYPES + "/secure/master"->query_domains()) {
    i += 5;

    call_out("rehash", i, thing);
  }
} /* rehash_all() */

/** @ignore yes */
string *query_types() { return TYPES + keys(_areas); }

/** @ignore yes */
mapping query_items(string type, string filter) {
  mapping items;
  string item;

  switch(type) {
  case "armours":
    items = _armour_list;
    break;
  case "weapons":
    items = _weapon_list;
    break;
  case "clothes":
    items = _clothing_list;
    break;
  case "jewellery":
  case "jewelleries":
    items = _jewellery_list;
    break;
  case "scabbards":
    items = _scabbard_list;
    break;
  case "food":
  case "foods":
    items = _food_list;
    break;
  case "misc":
    items = _misc_list;
    break;
  case "plants":
    items = _plant_list;
    break;
  default:
    if(member_array(type, "/secure/master"->query_domains()) != -1 &&
       _areas[type])
      items = _areas[type];
    else
      return 0;
  }

  items = copy (items);
  if (sizeof (filter)) {
    foreach(item in keys(items))
      if(strsrch(item, filter) == -1)
        map_delete(items, item);
  }
  return items;
}

// Return an item for someone
/** @ignore yes */
int request( string word, int percentage, string area ) {
  object thing;

  thing = request_item( word, percentage, area );

  if ( !thing ) {
    add_failed_mess(word + " not found.\n");
    return 0;
  }
  if ( (int)thing->move( this_player() ) != MOVE_OK ) {
    write( (string)thing->a_short() +" has been placed in here.\n" );
    thing->move( this_object() );
  } else
    write( (string)thing->a_short() +
          " has been placed in your inventory.\n" );
  return 1;
} /* request() */

/** @ignore yes */
mixed stats() {
  string tmp;
  mixed *ret;

  ret = ({ });
  foreach(tmp in keys(_areas)) {
    ret += ({ tmp, sizeof(_areas[tmp]) });
  }
  
  return ::stats() + ({
    ({ "item requests", _total_requests, }),
      ({ "armours", sizeof(_armour_list) }),
      ({ "clothes", sizeof(_clothing_list) }),
      ({ "weapons", sizeof(_weapon_list) }),
      ({ "scabbards", sizeof(_scabbard_list) }),
      ({ "jewellery", sizeof(_jewellery_list) }),
      ({ "food", sizeof(_food_list) }),
      ({ "misc", sizeof(_misc_list) }),
      ({ "plants", sizeof(_plant_list) }),
      ret });
} /* stats() */

/** @ignore yes */
string* walk_directory (string dir) {
  string *tmp, *dirs = ({ }), *tmp2;
  mixed *file;

  tmp = get_dir(dir, -1);

  if (sizeof (tmp))
    dirs += ({dir});

  foreach(file in tmp) {
    if(file[1] == -2) {
      tmp2 = walk_directory (dir + file [0] + "/");
      if (sizeof (tmp2))
        dirs += tmp2;
    }
  }

  return dirs;
}