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/
#include <weapon.h>

inherit "/cmds/base";
mapping _weapons;
mapping _items;
mapping _matched;

// Condition modifiers for materials
mapping _conditions = ([ "cloth" : 800, "rubber" : 100, "hide" : 700, "leather" : 600, "wood" : 500, "bone" : 200, "silver" : 300, "copper" : 400, "stone" : 400, "bronze" : 500, "iron" : 700, "steel" : 900, "klatchian steel" : 1100, "octiron" : 1300 ]);

// Damage chance modifiers for materials
mapping _chances = ([ "cloth" : 20, "rubber" : 19, "hide" : 17, "leather" : 15, "wood" : 12, "bone" : 8, "silver" : 15, "copper" : 10, "stone" : 3, "bronze" : 8, "iron" : 6, "steel" : 4, "klatchian steel" : 2, "octiron" : 0 ]);

// Weight modifiers for different materials
mapping _weights = ([ "cloth" : 1, "rubber" : 3, "hide" : 2, "leather" : 2, "wood" : 3, "bone" : 3, "silver" : 6, "copper" : 6, "stone" : 5, "bronze" : 5, "iron" : 5, "steel" : 5, "klatchian steel" : 5, "octiron" : 5 ]);

// Map some weird things to more standard equivalents.
mapping _equivalents = ([ "chocolate" : "rubber",
                          "earthworm" : "octiron" ]);

// The light & heavy weapon specials.
mapping _specials = ([ "bash" : "smash",
                       "hack" : "chop",
                       "stab" : "pierce",
                       "slash" : "slice" ]);
// Standard attack names/types/skills
mapping _types = ([ "strike" : "blunt",
                    "bash" : "blunt",
                    "smash" : "blunt",
                    "hack" : "sharp",
                    "chop" : "sharp",
                    "poke" : "pierce",
                    "stab" : "pierce",
                    "pierce" : "pierce",
                    "cut" : "sharp",
                    "slash" : "sharp",
                    "slice" : "sharp",
                    "spike" : "pierce",
                    "fire" : "any" ]);

nosave string *_attack_types = ({ "blunt", "sharp", "pierce", "fire" });

void create() {
  ::create();
  _weapons = "/obj/handlers/armoury"->make_list("/obj/nweapons/",
                                                ({".c", ".wep"}));
}

string warn(int i) {
  switch(i) {
  case 2:
    return "  %^BOLD%^%^RED%^!%^RESET%^ ";
  case 1:
    return "  %^ORANGE%^o%^RESET%^ ";
  default:
    return "  %^GREEN%^-%^RESET%^ ";
  }
}

int *calc_rating(object weapon) {
    int i, size;
    int ave = 0;
    int max = 0;
    int *damage;
    mixed *data;

    data = (mixed *)weapon->query_attack_data();
    
    if ( !( size = sizeof( data ) ) )
      return ({ 0, 0 });

    for ( i = 0; i < size; i += W_ARRAY_SIZE ) {
      if ( member_array( data[ i + W_SKILL ], _attack_types ) == -1 )
        continue;
      damage = data[ i + W_DAMAGE ];
      ave += ( data[ i + W_CHANCE ] * ( damage[ F_FIXED ] +
            ( damage[ F_NUM ] * ( 1 + damage[ F_DIE ] ) ) / 2 ) ) / 100;
      if(damage[ F_FIXED ] + damage[ F_NUM ] * damage[ F_DIE ] > max)
        max = damage[ F_FIXED ] + damage[ F_NUM ] * damage[ F_DIE ];
    }
    return ({ ave, max });
}

int calc_ave(mixed damage) {
  if(arrayp(damage))
    return damage[F_FIXED] + (damage[F_NUM] * (1 + damage[F_DIE])) / 2;
  
  return damage;
}

int calc_max(mixed damage) {
  if(arrayp(damage))
    return damage[F_FIXED] + (damage[F_NUM] * damage[F_DIE]);
  
  return damage;
}

object *filter(object who) {
  object *tmp;

  if(who->query_creator())
    return ({});
  
  tmp = who->query_weapons();
  switch(sizeof(tmp)) {
  case 2:
    if(tmp[0]->query_property("virtual name")) {
      if(tmp[0]->query_property("virtual name") ==
         tmp[1]->query_property("virtual name"))
        return ({ tmp[0] });
    } else {
      if(base_name(tmp[0]) == base_name(tmp[1]))
        return ({ tmp[0] });
    }
    break;
  default:
  }
  return tmp;
}

int list(string type) {
  mapping weapons;
  object wep;
  mixed *data;
  string *names, *types, str;
  int i;

  weapons = "/obj/handlers/armoury"->query_items("weapons");

  foreach(str in keys(weapons)) {
    if(str == "twoedge" || str == "kring" ||
       strsrch(weapons[str], "ranged") != -1 ||
       strsrch(weapons[str], "misc") != -1)
      continue;
 
    wep = "/obj/handlers/armoury"->request_item(str);
    if(!wep)
      continue;

    types = wep->query_attack_types();
    if(type && types && member_array(type, types) == -1)
      continue;

    data = wep->query_attack_data();
    names = wep->query_attack_names();
    for(i=0; i<sizeof(data); i += W_ARRAY_SIZE) {
      printf("%-30s %8s %3d %3d %3d %6s\n",
             wep->query_short(),
             names[i / W_ARRAY_SIZE],
             data[i + W_CHANCE],
             calc_ave(data[i+W_DAMAGE]),
             calc_max(data[i+W_DAMAGE]),
             data[i+W_SKILL]);
      write_file("/w/ceres/WEAPONS.csv",
                 sprintf("%s,%s,%d,%d,%d,%s\n",
                         wep->query_short(),
                         names[i / W_ARRAY_SIZE],
                         data[i + W_CHANCE],
                         calc_ave(data[i+W_DAMAGE]),
                         calc_max(data[i+W_DAMAGE]),
                         data[i+W_SKILL]));
    }
    wep->dest_me();
  }
  return 1;
}

int sort_weapons(int wep1, int wep2) {
  if(wep1 > wep2)
    return -1;
  if(wep1 < wep2)
    return 1;
  return 0;
}

int players() {
  mapping weapons;
  object wep, *weps;
  mixed *data;
  string str;
  
  data = map(users(), "filter");
  weapons = ([ ]);
  foreach(weps in data) {
    if(weps) {
      foreach(wep in weps) {
        if(wep->query_property("virtual name"))
          str = (clone_object(wep->query_property("virtual name"))->query_short());
        else
          str = base_name(wep)->query_short();
        if(!weapons[str])
          weapons[str] = 1;
        else
          weapons[str] += 1;
      }
    }
  }
  foreach(str in sort_array(keys(weapons),
                            (: sort_weapons($(weapons)[$1],
                                            $(weapons)[$2]) :)))
    if(str && weapons[str])
      printf("%d %s\n", weapons[str], str);
  
  return 1;
}

private string *map_materials(string *materials) {
  string str;
  
  foreach(str in materials) {
    if(_equivalents[str]) {
      materials -= ({ str });
      materials += ({ _equivalents[str] });
    }
  }
  return materials;
}

void total(object pl) {
  write("Total of " + _matched[pl] + " weapons found.\n");
}

void check(int bad_only, string type, string search, string *weapons,
           object pl) {
  string str, *materials, att, ret;
  string *tstr, *anames;
  object wep;
  int cond, dc, ave, max, weight, tmp, bad, count;
  mixed *data;
  float wf;

  count = 0;
  foreach(str in weapons) {
    bad = 0;
    if(wep)
      wep->dest_me();

    // These don't load.
    if(str == "twoedge" || str == "kring")
      continue;

    // exclude the weird stuff if they'd checking for bad/warning weapons.
    if(bad_only && (strsrch(str, "bow") != -1 ||
                    str == "satin knife boots" || str == "knife boots" ||
                    strsrch(_items[pl][str], "ranged") != -1 ||
                    strsrch(_items[pl][str], "misc") != -1))
      continue;

    // Search for specific weapons.
    if(search != "" && strsrch(str, search) == -1 &&
       strsrch(_items[pl][str], search) == -1)
      continue;
    
    wep = clone_object(_items[pl][str]);
    if(!wep || !wep->query_short())
      continue;

    materials = map_materials(wep->query_materials());
    cond = wep->query_max_cond();
    dc = wep->query_damage_chance();

    ret = "";
    if(search)
      ret = sprintf("\n");
    
    ret += sprintf("%s (%s)\n", capitalize(wep->query_short()),
                   _items[pl][str]);

    tstr = ({ });

    if(!sizeof(materials) || sizeof(materials - keys(_conditions)))
      tstr += ({ "materials" });
    else
      ret += warn(0) + sprintf("is made of %s\n",
                               query_multiple_short(materials));

    if(wep->query_length() == 1)
      tstr += ({ "length" });
    if(wep->query_width() == 1)
      tstr += ({ "width" });
    if(!wep->query_weight())
      tstr += ({ "weight" });
    
    if(sizeof(tstr)) {
      if(sizeof(tstr) == 1 && tstr[0] == "width") {
        ret += warn(1);
        //if(bad < 2)
        //bad = 1;
      } else {
        ret += warn(2);
        bad = 2;
      }
      ret += sprintf("has no %s\n", replace(query_multiple_short(tstr),
                                            "and", "or"));

      if(member_array("materials", tstr) != -1) {
        tell_object(pl, ret);
        continue;
      }
    }

    if(wep->query_length() != 1 && wep->query_width() != 1)
      ret += warn(0) + sprintf("is %s%d\" (%dcm) by %s%d\" (%dcm) "
                               "and weighs %.1f%s (%.1fkg)\n",
                               (wep->query_length() / 12) > 0 ?
                               (wep->query_length() / 12) + "'" : "",
                               wep->query_length() % 12,
                               to_int(wep->query_length() * 2.54),
                               (wep->query_width() / 12) > 0 ?
                               (wep->query_width() / 12) + "'" : "",
                               wep->query_width() % 12,
                               to_int(wep->query_width() * 2.54),
                               wep->query_weight() / 9.0,
                               (wep->query_weight() / 9.0) == 1.0 ? "lb" :
                               "lbs",
                               wep->query_weight() / 20.0);

    // Calculate the ratio of length+width+material to weight.
    wf = 0;
    foreach(tstr in materials)
      wf += _weights[tstr];
    wf /= sizeof(materials);
    
    wf = (wep->query_weight() * (wep->query_weight() / 2)) /
      (wep->query_length() * wep->query_width() * wf);

    if(wf < 0.5 || wf > 3.0) {
      ret += warn(1);
      if(bad < 2)
        bad = 1;
    } else
      ret += warn(0);
    
    ret += sprintf("has weight factor of %.1f [0.5/1.0/3.0] "
                   "(%%^ORANGE%%^Experimental%%^RESET%%^)\n", wf);
      
    switch(type) {
    case "weapons":
      weight = 10 + 2 * sqrt(wep->query_weight());
      break;
    case "armours":
      weight = 5 + 2 * sqrt(wep->query_weight());
      break;
    case "clothes":
      weight = 2 * sqrt(wep->query_weight());
      break;
    }

    tmp = 0;
    foreach(tstr in materials)
      tmp += _conditions[tstr];

    tmp /= sizeof(materials);
    tmp *= weight;
    
    if((cond < tmp - tmp/10) || (cond > tmp + tmp/10)) {
      ret += warn(2) + sprintf("has max cond of %d should be [%d/%d/%d]\n",
                               cond, tmp - tmp/10, tmp, tmp + tmp/10);
      tell_object(pl, ret);
      continue;
    } else if(search)
      ret += warn(0) + sprintf("has max cond of %d [%d/%d/%d]\n",
                               cond, tmp - tmp/10, tmp, tmp + tmp/10);


    tmp = 0;
    foreach(tstr in materials)
      tmp += _chances[tstr];
    tmp /= sizeof(materials);

    if(dc < tmp -1 || dc > tmp+1) {
      ret += warn(2) + sprintf("has damage chance of %d should be "
                               "[%d/%d/%d]\n",
                               dc, tmp-1, tmp, tmp+1);
      bad = 2;
    } else if(search)
      ret += warn(0) + sprintf("has damage chance of %d [%d/%d/%d]\n",
                               dc, tmp-1, tmp, tmp+1);

    // Check the common specials
    anames = wep->query_attack_names();
    if(!sizeof(anames)) {
      ret += warn(2) + sprintf("has no attacks.\n");
      tell_object(pl, ret);
      continue;
    }

    foreach(att in anames) {
      if(!_specials[att] && member_array(att, keys(_types)) == -1) {
        ret += warn(1) + sprintf("has non-standard %s attack\n", att);
        if(bad < 2)
          bad = 1;
      } else if(wep->query_weight() < 30 &&
         member_array(att, values(_specials)) != -1) {
        ret += warn(2) + sprintf("has %s but is too light\n", att);
        bad = 2;
      } else if(wep->query_weight() > 50 && _specials[att] && 
                member_array(_specials[att], anames) == -1) {
        ret += warn(1) + sprintf("has %s but not %s\n", att, _specials[att]);
        if(bad < 2)
          bad = 1;
      }
    }
    
    // Check type & skill.
    data = wep->query_attack_data();
    for(tmp=0; tmp < sizeof(data); tmp += W_ARRAY_SIZE) {
      if(member_array(data[tmp+W_TYPE], _attack_types) == -1) {
        ret += warn(2) + sprintf("has unknown attack type %s\n",
                                 data[tmp+W_TYPE]);
        bad = 2;
      }
      if(member_array(data[tmp+W_SKILL], values(_types)) == -1) {
        ret += warn(2) + sprintf("has unknown attack skill %s\n",
                                 data[tmp+W_SKILL]);
        bad = 2;
      }

      if(_types[anames[tmp/W_ARRAY_SIZE]] &&
         _types[anames[tmp/W_ARRAY_SIZE]] != "any" &&
         _types[anames[tmp/W_ARRAY_SIZE]] != data[tmp+W_SKILL]) {
        ret += warn(2) + sprintf("has attack %s with skill of %s\n",
                                 anames[tmp/W_ARRAY_SIZE], data[tmp+W_SKILL]);
        bad = 2;
      }
      if(data[tmp+W_FUNCTION]) {
        ret += warn(1) + sprintf("has attack function %s on %s attack\n",
                                 data[tmp+W_FUNCTION],
                                 anames[tmp/W_ARRAY_SIZE]);
        bad = 1;
      }
    }
    
    // Check the axe attacks.
    if(strsrch(_items[pl][str], "axe") == -1 &&
       strsrch(wep->query_long(), "axe") == -1) {
      if(member_array("chop", wep->query_attack_names()) != -1) {
        ret += warn(1) + sprintf("has chop attack but is not an axe.\n");
        if(bad < 2)
          bad = 1;
      }
      if(member_array("hack", wep->query_attack_names()) != -1) {
        ret += warn(1) + sprintf("has chop attack but is not an axe.\n");
        if(bad < 2)
          bad = 1;
      }
    } else {
      if(member_array("slash", wep->query_attack_names()) != -1) {
        ret += warn(1) + sprintf("has slash attack but is an axe.\n");
        if(bad < 2)
          bad = 1;
      }
      if(member_array("slice", wep->query_attack_names()) != -1) {
        ret += warn(1) + sprintf("has slice attack but is an axe.\n");
        if(bad < 2)
          bad = 1;
      }
    }
    
    if(cond) {
      data = calc_rating(wep);
      ave = data[0];
      max = data[1];

      if(ave > 140 || max > 300) {
        ret += warn(2);
        bad = 2;
      } else
        ret += warn(0);
      
      ret += sprintf("has damage of %d/%d max permitted is [140/300]\n",
                     ave, max);

      tmp = (100 * ave * max) / cond; // damage factor
      if(tmp < 75 || tmp > 150) {
        ret += warn(1);
        if(bad < 2)
          bad = 1;
      } else
        ret += warn(0);
      
      ret += sprintf("has damage factor of %d [75/150] "
                     "(%%^ORANGE%%^Experimental%%^RESET%%^)\n",
                     tmp);
    }
    
    if(bad >= bad_only) {
      tell_object(pl, ret);
      count++;
    }
  }
  _matched[pl] += count;
  return;
}

int do_check(int bad_only, string type) {
  string *tmp, search;
  int i;

  if(!_items)
    _items = ([ ]);
  if(!_matched)
    _matched = ([ ]);
  
  if(type == "armours" || type == "clothes") {
    _items[this_player()] = "/obj/handlers/armoury"->query_items(type);
    search = "";
  } else if(type == "weapons") {
    _items[this_player()] = _weapons;
    search = "";
  } else {
    search = type;
    type = "weapons";
    _items[this_player()] = _weapons;
  }

  _matched[this_player()] = 0;
  
  tmp = keys(_items[this_player()]);

  if(!sizeof(tmp))
    return notify_fail("No items matched.\n");

  for(i=0; i<sizeof(tmp); i+= 50) {
    if(i+50 < sizeof(tmp)) {
      call_out("check", 0, bad_only, type, search, tmp[i..i+49],
               this_player());
    } else
      call_out("check", 0, bad_only, type, search, tmp[i..], this_player());
  }
  call_out("total", 1, this_player());
  return 1;
}

mixed *query_patterns() {
  return ({
    //"list", (: list("") :),
              //              "list <string'type'>", (: list($4[0]) :), 
              "players", (: players() :),
              "check", (: do_check(0, "") :),
              "check <string'type'>", (: do_check(0, $4[0]) :),
              "check bad", (: do_check(2, "") :),
                "check bad <string'type'>", (: do_check(2, $4[0]) :),
              "check warn", (: do_check(1, "") :),
              "check warn <string'type'>", (: do_check(1, $4[0]) :)
                });
}