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: remove.c,v 1.19 2003/01/30 06:33:24 pinkfish Exp $
 * $Log: remove.c,v $
 * Revision 1.19  2003/01/30 06:33:24  pinkfish
 * Add in stuff to make sure they drop extra items.
 *
 * Revision 1.18  2002/06/18 20:51:06  presto
 * You know, I really think I might have it right this time.  No, really!
 *
 * Revision 1.17  2002/05/17 00:45:19  trilogy
 *  Forcibly unlocked by presto
 *
 * Revision 1.15  2002/05/16 01:54:40  trilogy
 *  Forcibly unlocked by presto
 *
 * Revision 1.13  2002/02/12 04:42:29  presto
 * Fixed so that an item never blocks itself (which is possible for items
 * of mixed type)
 *
 * Revision 1.12  2002/01/15 01:40:24  presto
 * So help me God, I hope it works now.
 *
 * Revision 1.11  2002/01/07 05:27:16  presto
 * Fixed mistake with not removing things that were *indirectly* blocked by
 * other things
 *
 * Revision 1.10  2002/01/06 05:37:27  presto
 * Rewrote.  Seems to work better now, and I think it's more understandable. :)
 * Will keep an eye on it
 *
 * Revision 1.9  2001/12/07 15:12:11  taffyd
 * Fixed typo and grammar oddity.
 *
 * Revision 1.8  2001/11/08 02:22:07  pinkfish
 * Fox up some little errors.
 *
 * Revision 1.7  2001/11/07 23:09:56  pinkfish
 * Fix up the auto removal a little more.
 *
 * Revision 1.6  2001/11/07 21:46:34  pinkfish
 * Make it so it automatically takes and puts stuff on and off.
 *
 * Revision 1.5  1999/12/08 04:09:04  ceres
 * Modified to use standard can_wear_or_remove() function in /obj/handlers/clot
 * hing_handler
 *
 * Revision 1.4  1998/09/15 00:28:32  pinkfish
 * Fix up the output errors for remove.
 *
 * Revision 1.3  1998/08/25 10:18:41  pinkfish
 * Change remove so it will order the thnigs to remove...  SO it takes
 * the toip off first.
 *
 * Revision 1.2  1998/03/27 20:49:01  pinkfish
 * To the new clothing handler.
 *
 * Revision 1.1  1998/01/06 05:28:43  ceres
 * Initial revision
 * 
*/
#include <clothing.h>
#include <tasks.h>

//#define DEBUG

#define SKILL "covert.manipulation.sleight-of-hand"
#ifdef DEBUG
#define TELL_ME "presto"
#endif

inherit "cmds/base";

int cmd(object *things)  {
   object  *removed = ({ });
   object  *blocking = ({ });
   object  *blocked;
   object  *total_blocking = ({ });
   object  *succeeded;
   object  *failed;
   object  *failed_rewear;
   object   ob;
   object   blocker;
   mapping  is_blocking = ([ ]);
   mapping  hide_invis;
   string   tmp1;
   string   tmp2;
   int      last_blocking;
   int      limit;
   int      i;
   int      hiding;
   int      sneaking;
   int      difficulty;
   int      light;
   int      my_light;

   succeeded = this_player()->query_wearing();
   failed = filter(things, (: member_array($1, $(succeeded)) == -1 :));
   things -= failed;
   if (sizeof(things) == 0)  {
      write("You are not wearing " + query_multiple_short(failed, "the") +
            ".\n");
      return 1;
   }

   succeeded = things;
   for (i = 0; i < sizeof(succeeded); i++)  {
      ob = succeeded[i];
      blocking = CLOTHING_HANDLER->query_items_blocking(ob, this_player()) -
                 ({ ob });
      if (sizeof(blocking))  {
         foreach (blocker in blocking)  {
            if (undefinedp(is_blocking[blocker]))
               is_blocking[blocker] = ({ ob });
            else
               is_blocking[blocker] |= ({ ob });
         }

         total_blocking |= blocking;

         /*
          * We need to add the blocking things to the things we are checking,
          * because the blocking things may themselves be blocked by something
          * that was not blocking the thing that the original blocker was
          * blocking.  Oh... you want an EXAMPLE.  OK:
          *
          * Example: a silk shirt is blocked by a mail shirt, but NOT by a
          * scabbard.  However, the mail shirt IS blocked by the scabbard, so
          * it has to be removed before we can remove the mail shirt; so that
          * we can remove the silk shirt.
          */

         succeeded = ({ things..., total_blocking... });
      }
   }

   /*
    * OK, here is the important, complicated bit.  At this point, the
    * is_blocking mapping is keeping track of everything that is blocking
    * something else, and what it is blocking.  We need to build an array of
    * blocking objects in order from outermost layer to innermost.  That way
    * there should be no failures when we remove the covering stuff to get
    * to the things that the player wants to remove.  Here is how this works:
    *
    * 1. Loop over all items that are blocking something else
    * 2. For each item, find the last thing in the array (so far) that would
    *    block the item.  Insert the item we are adding should immediately
    *    after that position.
    * 3. Loop over the array we are building up to the step 2 index and check
    *    whether each object would have been blocked by the new item, or by
    *    anything else that we moved already in a previous run through the
    *    loop.  If so, move the object after the new item and previously moved
    *    items.
    */
    
   total_blocking = ({ });
   foreach (ob, blocked in is_blocking)  {

#ifdef DEBUG
      if (this_player() == find_player(TELL_ME))
      tell_creator(TELL_ME, "ob == %s, blocked == %O\n",
                   ob->short(), blocked->short());
#endif
        
      /* Find the last thing that is blocking 'ob' */
      last_blocking = -1;
      for (i = sizeof(total_blocking) - 1; i >= 0; i--)  {
         if (member_array(ob, is_blocking[total_blocking[i]]) > -1)  {
            last_blocking = i;
            break;
         }
      }

      if (last_blocking == -1)  {
         /*
          * Nothing is blocking 'ob', so we can safely put it at the
          * front of the list, because then, even if it blocks something
          * else, it will get removed first.
          */
         total_blocking = ({ ob, total_blocking... });

#ifdef DEBUG
         if (this_player() == find_player(TELL_ME))
            tell_creator(TELL_ME, "Nothing is blocking ob, adding it to "
                         "the beginning\n%O\n", total_blocking->short());
#endif

         continue;
      }

      total_blocking = ({ total_blocking[0 .. last_blocking]...,
                          ob,
                          total_blocking[(last_blocking + 1) .. ]... });

#ifdef DEBUG
      if (this_player() == find_player(TELL_ME))
         tell_creator(TELL_ME, "Adding ob after last_blocking position "
                      "(%d)\n%O\n",
                      last_blocking, total_blocking->short());
#endif

      limit = last_blocking;
      blocking = copy(blocked);
      for (i = 0; i < limit; i++)  {
         /*
          * If the object we are checking is blocked by anything we have
          * moved so far, then we have to move it too
          */
         if (member_array(total_blocking[i], blocking) > -1)  {
            blocking += is_blocking[total_blocking[i]];
            if (i == 0)
               total_blocking =
                  ({ total_blocking[1 .. (last_blocking + 1)]...,
                     total_blocking[0],
                     total_blocking[(last_blocking + 2) .. ]... });
            else
               total_blocking =
                  ({ total_blocking[0 .. (i - 1)]...,
                     total_blocking[(i + 1) .. (last_blocking + 1)]...,
                     total_blocking[i],
                     total_blocking[(last_blocking + 2) .. ]... });
            --limit;
            --i;

#ifdef DEBUG
            if (this_player() == find_player(TELL_ME))
               tell_creator(TELL_ME, "Reordered list:\n%O\n",
                            total_blocking->short());
#endif

         }
      }
   }

   /* Remove stuff that's blocking the stuff we asked to remove */
   foreach (blocker in total_blocking)  {
      tmp1 = CLOTHING_HANDLER->can_wear_or_remove(blocker, this_player());
      if (tmp1)  { /* This *shouldn't* happen */
//         log_file("REMOVE_FAILURE", "things == %O\n", things);
//         log_file("REMOVE_FAILURE", "reason == %s\n", tmp1);
//         log_file("REMOVE_FAILURE", "blocker == %s (%s, %O)\n", blocker->short(), file_name(blocker), blocker);
//         log_file("REMOVE_FAILURE", "total_blocking == \n");
//         for (i = 0; i < sizeof(total_blocking); i++)  {
//            log_file("REMOVE_FAILURE", "   %O (%s)\n", total_blocking[i], total_blocking[i]->short());
//         }
//         log_file("REMOVE_FAILURE", "is_blocking == \n");
//         foreach (ob, blocked in is_blocking)  {
//            log_file("REMOVE_FAILURE", "   %O (%s): \n", ob, ob->short());
//            for (i = 0; i < sizeof(blocked); i++)  {
//               log_file("REMOVE_FAILURE", "      %O (%s)\n", blocked[i], blocked[i]->short());
//            }
//         }
//         log_file("REMOVE_FAILURE", "removed == %O\n", removed);
         write("You cannot remove " +
               query_multiple_short(is_blocking[blocker], "the") +
               " " + tmp1 + ".\n");
         things -= is_blocking[blocker];
         break;
      }
      else if (this_player()->remove_armour(blocker))  {
         write("You cannot remove " +
               query_multiple_short(is_blocking[blocker], "the") +
               " because you cannot remove " + blocker->one_short() + ".\n");
         things -= is_blocking[blocker];
         break;
      }
      else removed += ({ blocker });
   }

   /* Now remove the stuff we really wanted to */
   /*
    * Start with things we already removed because they were blocking
    * something else
    */
   succeeded = things & removed;
   failed = ({ });

   /* Now try to remove the rest */
   foreach (ob in things - removed)  {
      if (this_player()->remove_armour(ob))
         failed += ({ ob });
      else
         succeeded += ({ ob });
   }

   if (sizeof(succeeded) > 0)  {
      removed -= things;
      tmp2 = query_multiple_short(succeeded, "the") ;
      if (sizeof(removed) > 0)  {
         tmp1 = query_multiple_short(removed, "the");
         write("You remove " + tmp1 + " so you can remove " + tmp2 + ".\n");
         say(this_player()->the_short() + " removes " + tmp1 + " so " +
             this_player()->query_pronoun() + " can remove " + tmp2 + ".\n");
      }
      else  {
        hide_invis = ( mapping )this_player()->query_hide_invis();
        hiding = hide_invis[ "hiding" ] ? 1 : 0;
        sneaking = this_player()->query_sneak_level() ? 1 : 0;
      
        if( hiding || sneaking ) {
          my_light = this_player()->query_light();
          light = environment( this_player() )->query_light();
        
          difficulty = light + ( 4 * my_light ) / ( light + 1 );
      
          difficulty += succeeded[0]->query_complete_weight();
      
          debug_printf( "Difficulty = %d.\n Skill = %s\n Bonus = %d\n",
                        difficulty, SKILL, this_player()->
                        query_skill_bonus( SKILL ) );
          switch( TASKER->perform_task( this_player(), SKILL, difficulty,
            TM_FREE ) ) {
            case AWARD :
              write( "%^YELLOW%^" + ({
                "You discover something that lets your fingers move more "
                  "nimbly.",
                "You find yourself capable of deceiving the eye with greater "
                  "ease than before.",
                "You realise how to deceive the eye more effectively."
              })[ random(3) ] + "%^RESET%^\n" );
            case SUCCEED :
              add_succeeded_mess( ({ "$N $V " + tmp2 + ", managing to stay "
                "unnoticed.\n",
                "" }) );
              break;
            default :
              this_player()->add_succeeded_mess( this_object(), "$N "
                "unsuccessfully tr$y to " + query_verb() + " " + tmp2 +
                " while staying unnoticed.\n", ({ }) );
              break;
          }
        } else {
          this_player()->add_succeeded_mess( this_object(), "$N $V " + tmp2 +
            ".\n", ({ }) );
        }
      }
   }

   /* Put stuff back on that we took off */
   succeeded = ({ });
   failed_rewear = ({ });
   foreach (ob in removed)  {
      if (this_player()->wear_armour(ob))
         failed_rewear += ({ ob });
      else
         succeeded += ({ ob });
   }

   if (sizeof(succeeded) > 0)  {
      // Make sure they drop extra items
      this_player()->force_burden_recalculate();
      tmp1 = query_multiple_short(succeeded, "the");
      write("You wear " + tmp1 + ".\n");
      say(this_player()->the_short() + " wears " + tmp1 + ".\n");
   }

   if (sizeof(failed_rewear) > 0)  {
      write("You cannot put " +
            query_multiple_short(failed_rewear, "the") + " back on.\n");
   }

   if (sizeof(failed) > 0)  {
      write("You cannot remove " + query_multiple_short(failed, "the") +
            ".\n");
   }

   return 1;
}


mixed *query_patterns() {
   return ({ "<indirect:object:me>", (: cmd($1) :) });
} /* query_patterns() */