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/
/**
 * This inherit handles auctioning stuff.
 * @author Pinkfish
 * @started Mon Apr 30 22:47:38 PDT 2001
 */
#include <room/auction.h>
#include <player.h>
#include <money.h>
#include <move_failures.h>
#include <mail.h>
#include <player_handler.h>
#include <am_time.h>

inherit "/std/shops/inherit/shop_event";
inherit "/std/shops/inherit/open_shop";

// 15 minutes.
#define DEFAULT_QUICK_AUCTION_LENGTH (15 * 60)
// 1 hour
#define DEFAULT_SHORT_AUCTION_LENGTH (60 * 60)
// 1 day
#define DEFAULT_MEDIUM_AUCTION_LENGTH (AM_SECONDS_PER_DAY)
// 3 days.
#define DEFAULT_LONG_AUCTION_LENGTH (AM_SECONDS_PER_DAY * 3)
// 14 days.
#define DEFAULT_VERY_LONG_AUCTION_LENGTH (AM_SECONDS_PER_DAY * 14)
#define DEFAULT_RETRIEVAL_TIME (AM_SECONDS_PER_DAY * 7)
#define DEFAULT_EXTENSION_TIME (20 * 60)

class auction {
   mixed save_stuff;
   int time_started;
   int auction_length;
   string name;
   string seller;
   string current_bidder;
   int bid;
   int reserve;
   int retries;
   string end_function;
   mixed extra;
}

private nosave mixed* _auction_obs;
private nosave int _callout_id;
private nosave string _save_file;
private nosave int _max_auctions;
private nosave mapping _auction_times;
private nosave int _retrieval_time;
private nosave int _max_retries;
private nosave int _cut;
private nosave int _minimum_bid_increase; // percentage
private nosave function _can_bid;
private nosave int _allow_add;
private nosave string _bid_type_names;
private class auction* _auctions;
private class auction* _finished_auctions;
private mapping _royalties;

void next_auction_finish();
mixed query_property(string name);
class auction query_auction_item(string id);
void retry_auction(class auction auction);

void create() {
   _auctions = ({ });
   _finished_auctions = ({ });
   _cut = 10;
   _max_auctions = 20;
   _auction_obs = ({ });
   _royalties = ([ ]);
   _auction_times = ([
                      "quick" : DEFAULT_QUICK_AUCTION_LENGTH,
                      "short" : DEFAULT_SHORT_AUCTION_LENGTH,
                      "medium" : DEFAULT_MEDIUM_AUCTION_LENGTH,
                      "long" : DEFAULT_LONG_AUCTION_LENGTH,
                      "very long" : DEFAULT_VERY_LONG_AUCTION_LENGTH
                    ]);
   _retrieval_time = DEFAULT_RETRIEVAL_TIME;
   _max_retries = 5;
   _minimum_bid_increase = 10; // percentage
   _allow_add = 1;
   shop_event::create();
} /* create() */

/**
 * This method returns the current list of available auctions.
 * @return the current auctions
 */
class auction *query_auctions() { return copy(_auctions); }

/**
 * This method returns the current list of finished auctions.
 * @return the current auctions
 */
class auction *query_finished_auctions() { return copy(_finished_auctions); }

/**
 * This method loads the auction house up.
 */
void load_me() {
   unguarded( (: restore_object(_save_file, 1) :));
   _auction_obs = allocate(sizeof(_auctions));
   if (!_royalties) {
      _royalties = ([ ]);
   }
   next_auction_finish();
} /* load_me() */

/**
 * This method saves the auction house.
 */
void save_me() {
   unguarded( (: save_object(_save_file) :));
} /* save_me() */

/**
 * This method sets the save file name.
 * @param fname the save file name
 */
void set_save_file(string fname) {
   _save_file = fname;
   load_me();
} /* set_save_file() */

/**
 * This method queries the save file name.
 */
string query_save_file() {
   return _save_file;
} /* query_save_file() */

/**
 * This method sets a function to be called to check if someone can
 * bid or not.
 * @param func the function to call
 */
void set_check_can_bid(function f) {
   _can_bid = f;
} /* set_check_can_bid() */

/**
 * This method sets the allowed add flag.  If theis flag is set to 0
 * then it is not possible for players to add items for
 * auctions.
 * @param flag the allowed add flag
 */
void set_allowed_add(int flag) {
   _allow_add = flag;
} /* set_allowed_add() */

/**
 * This method sets the maximum number of simultaneous auctions.
 * @param i the number of items.
 */
void set_max_auctions(int i) { _max_auctions = i; }

/**
 * This method sets the length of auctions in seconds.
 * @param index the name of the auction type to change
 * @param i the length of auctions.
 */
void set_auction_time(string index, int i) {
   if (!i) {
      map_delete(_auction_times, index);
   } else {
      if (!_auction_times[index]) {
         _bid_type_names = 0;
      }
      _auction_times[index] = i;
   }
}

/**
 * This method returns the length of auctions in seconds.
 * @return the length of auctions.
 */
mapping query_auction_times() { return _auction_times; }

/**
 * This method sets the length of the retrieval time.
 *
 * @param i the number of seconds the item will wait for someone to claim it.
 */
void set_retrieval_time(int i) { _retrieval_time = i; }

/**
 * This method sets the number of times an item will be retried before
 * the auction is failed.
 *
 * @param i the number of seconds the item will wait for someone to claim it.
 */
void set_max_retries(int i) { _max_retries = i; }

/**
 * This method sets the minimum bid increase (as a percentage of the
 * current bid).
 *
 * @param i percentage
 */
void set_min_bid_increase(int i) { _minimum_bid_increase = i; }

/**
 * This method puts an item up for auction.
 * @param obs the objects to sell
 * @param name the name of the item
 * @param reserve the reserve price of the item
 * @param seller the seller of the item
 * @param length the length of the auction
 * @param end_function the function to call when the item is sold
 * @return 1 on success, 0 on failure
 */
int add_item_to_auction(object* obs, string name, int reserve,
                        string seller, int length,
                         string end_function, mixed extra) {
   class auction new_auct;

   if (sizeof(_auctions) + sizeof(_finished_auctions) >= _max_auctions) {
      return 0;
   }

   if (!reserve) {
      reserve = 40;
   }

   new_auct = new(class auction);
   new_auct->save_stuff = AUTO_LOAD_OB->create_auto_load(obs);
   new_auct->name = name;
   new_auct->reserve = reserve;
   new_auct->end_function = end_function;
   new_auct->time_started = time();
   if (!length) {
      new_auct->auction_length = _auction_times["very long"];
   } else {
      new_auct->auction_length = length;
   }
   new_auct->seller = seller;
   new_auct->extra = extra;
   _auctions += ({ new_auct });
   _auction_obs += ({ obs });
   save_me();
   next_auction_finish();
   // To stop it hanging onto object references that might cease to exist
   _auction_obs -= ({ obs });
   _auction_obs += ({ 0 });
   return 1;
} /* add_item_to_auction() */

/**
 * This method finds the objects associated with the auction item.
 * @param auction the auction item
 * @return the objects associated with it
 */
object* query_auction_objects(class auction auct) {
   int i;


   for (i = 0; i < sizeof(_auctions); i++) {
      if (_auctions[i] == auct) {
         if (!_auction_obs[i]) {
            _auction_obs[i] = AUTO_LOAD_OB->load_auto_load_to_array(auct->save_stuff);
         }
         return _auction_obs[i];
      }
   }
   return ({ });
} /* query_auction_objects() */

/**
 * This method makes a bid on an item.
 * @param item the item to bid on
 * @param bid the amount to bid
 * @param person the person making the bid
 */
void bid_on_item(class auction auct,
                 int bid, string person) {
                 
    if (bid > auct->bid && bid >= auct->reserve) {
        auct->bid = bid;
        auct->current_bidder = person;
        if (auct->auction_length + auct->time_started - time() < 
            DEFAULT_EXTENSION_TIME) {
         
            auct->auction_length = time() - auct->time_started + 
                DEFAULT_EXTENSION_TIME;
        }
    }
    
} /* bid_on_item() */

/** @ignore yes
 * This can be used to alter the bid info if necessary.
 */
int reset_bid(string id, int bid, string person) {
  class auction auct;
  
  if(!(this_player()->query_lord()))
    return 0;
  auct = query_auction_item(id);
  if(!auct)
    return 0;

  auct->bid = bid;
  auct->current_bidder = person;
  return 1;
}

/**
 * This method removes the specified auction from the list.
 * @param auction the auction item that is being removed
 */
void remove_finished_auction_item(class auction auction) {
   int i;

   for (i = 0; i < sizeof(_finished_auctions); i++) {
      if (_finished_auctions[i] == auction) {
         _finished_auctions = _finished_auctions[0..i-1] + _finished_auctions[i+1..];
      }
   }
} /* remove_auction_item() */

/**
 * This method removes the specified auction from the list.
 * @param auction the auction item that is being removed
 */
void remove_auction_item(class auction auction) {
   int i;

   for (i = 0; i < sizeof(_auctions); i++) {
      if (_auctions[i] == auction) {
         if (i < sizeof(_auction_obs) && _auction_obs[i]) {
            ((_auction_obs[i]) - ({ 0 }))->move("/room/rubbish");
         }
         _auctions = _auctions[0..i-1] + _auctions[i+1..];
         _auction_obs = _auction_obs[0..i-1] + _auction_obs[i+1..];
      }
   }
} /* remove_auction_item() */

/**
 * This method finishes the aution on the specified item.
 * @param auction the auction item that is being finished
 */
void finish_auction(class auction auction) {
   string place;

   if (auction->end_function) {
      call_other(this_object(), auction->end_function, 
                 AUCTION_FINISH_PHASE, auction, auction->extra,
                 auction->current_bidder, auction->bid);
   }

   place = query_property("place");
   remove_auction_item(auction);
   // make them pay to get the item back
   if (!auction->current_bidder) {
      auction->current_bidder = auction->seller;
      auction->bid = 4000;
   }
   _finished_auctions += ({ auction });
   save_me();
   if (auction->current_bidder &&
       PLAYER_HANDLER->test_user(lower_case(auction->current_bidder))) {
      AUTO_MAILER->auto_mail(lower_case(auction->current_bidder),
                              this_object()->query_short(),
                              "Results of auction for " + auction->name,
                              "",
                              "Your auction for " + auction->name +
                              " has completed.\nPlease pay the " +
                              MONEY_HAND->money_value_string(auction->bid, place) +
                              " as soon as you can.\n", 0, auction->current_bidder);
   } else {
      // Retry it.
      retry_auction(auction);
   }
   return ;
} /* finish_auction() */

/**
 * This method forcibly finishes the auction on the specified item.
 * This is only to be used for debugging purposes.
 * @param auction the auction item that is being finished
 */
void force_finish_auction(string id) {
   string place;
   class auction auction;

   auction = query_auction_item(id);

   if (auction->end_function) {
      call_other(this_object(), auction->end_function, 
                 AUCTION_FINISH_PHASE, auction, auction->extra,
                 auction->current_bidder, auction->bid);
   }

   place = query_property("place");
   remove_auction_item(auction);
   // make them pay to get the item back
   if (!auction->current_bidder) {
      auction->current_bidder = auction->seller;
      auction->bid = 4000;
   }
   _finished_auctions += ({ auction });
   save_me();
   if (auction->current_bidder &&
       PLAYER_HANDLER->test_user(lower_case(auction->current_bidder))) {
      AUTO_MAILER->auto_mail(lower_case(auction->current_bidder),
                              this_object()->query_short(),
                              "Results of auction for " + auction->name,
                              "",
                              "Your auction for " + auction->name +
                              " has completed.\nPlease pay the " +
                              MONEY_HAND->money_value_string(auction->bid, place) +
                              " as soon as you can.\n");
   }
   return ;
} /* finish_auction() */

/**
 * This method retries the aution on the specified item.
 * @param auction the auction item that is being finished
 */
void retry_auction(class auction auction) {
   string place;

   if (auction->end_function) {
      call_other(this_object(), auction->end_function, 
                 AUCTION_RETRY_PHASE, auction, auction->extra);
   }

   place = query_property("place");
   remove_finished_auction_item(auction);
   // make them pay to get the item back
   auction->bid = 0;
   auction->current_bidder = 0;
   auction->retries++;
   auction->time_started = time();
   if (auction->retries > _max_retries) {
      // Toss it completely.
   } else {
      _auctions += ({ auction });
      _auction_obs += ({ 0 });
   }
   save_me();
   if (auction->seller &&
       PLAYER_HANDLER->test_user(lower_case(auction->seller))) {
      AUTO_MAILER->auto_mail(lower_case(auction->seller),
                              this_object()->query_short(),
                              "Default on auction of " + auction->name,
                              "",
                              "Your auction for " + auction->name +
                              " has completed and the payee defaulted.\n"
                              "The item has been put up for reauctioning.\n");
   }
   return ;
} /* finish_auction() */

/**
 * This method finds the item based on some useful string.
 * @param id the id to lookup
 * @return the auction item, 0 in the case of error
 */
class auction query_auction_item(string id) {
   id = lower_case(id);
   if (strlen(id) == 1 &&
       id[0] >= 'a' && id[0] < 'a' + sizeof(_auctions)) {
      return _auctions[id[0] - 'a'];
   }
   return 0;
} /* query_auction_item() */

/**
 * This method prints a nice string showing how long it is till then
 * end of the thing.
 * @param left the time to get the difference for
 * @return time end string
 */
string query_time_end_string(int left) {
   string str;
   string extra;

   if (left >= AM_SECONDS_PER_DAY) {
      str = (left / AM_SECONDS_PER_DAY) + " day";
      if ((left / AM_SECONDS_PER_DAY) > 1) {
         str += "s";
      }
      left = left % (AM_SECONDS_PER_DAY);
      if (left >= (AM_SECONDS_PER_MINUTE * AM_MINUTES_PER_HOUR)) {
         if ((left / (AM_SECONDS_PER_MINUTE * AM_MINUTES_PER_HOUR)) > 1) {
             extra = "s";
          } else {
             extra = "";
         }
         return str + " and " +
           (left / (AM_SECONDS_PER_MINUTE * AM_MINUTES_PER_HOUR)) + " hour" +
           extra;
      }
      return str;
   } else if (left >= AM_SECONDS_PER_MINUTE * AM_MINUTES_PER_HOUR) {
      if ((left / (AM_SECONDS_PER_MINUTE * AM_MINUTES_PER_HOUR)) > 1) {
          extra = "s";
       } else {
          extra = "";
      }
      str = (left / (AM_SECONDS_PER_MINUTE * AM_MINUTES_PER_HOUR)) + " hour" +
            extra;
      left %= AM_SECONDS_PER_MINUTE * AM_MINUTES_PER_HOUR;
      if ((left / (AM_SECONDS_PER_MINUTE)) > 1) {
          extra = "s";
       } else {
          extra = "";
      }
      if (left > AM_SECONDS_PER_MINUTE) {
         return str + " and " + (left / AM_SECONDS_PER_MINUTE) + " minute" +
                extra;
      }
      return str;
   } else if (left <= 0) {
      return "already finished";
   }

    if( !(left/60) ) {
        return "less than a minute";
    }
    else {
        str = "";
        str += ( left / 60) + " minute";
        if (left / 60 > 1) {
            str += "s";
        }
        return str;
    }
   
} /* query_auction_end_string() */

/**
 * This method printsd a nice string showing how long till the auction
 * ends.
 * @param auction the auction to get an end string for
 * @return auction end string
 */
string query_auction_end_string(class auction auction) {
   return query_time_end_string(auction->time_started +
                                auction->auction_length - time());
} /* query_auction_end_string() */

/**
 * This method figures out when the last auction will finish.
 * @return when the last auction finished
 */
int query_last_auction_finish_time() {
   int tim;
   class auction auction;

   foreach (auction in _auctions) {
      if (tim < auction->time_started + auction->auction_length) {
         tim = auction->time_started + auction->auction_length;
      }
   }
   return tim;
} /* query_last_auction_finish_time() */

/**
 * This method figures out when the next auction finishes and sets up
 * a timeout.
 */
void next_auction_finish() {
   class auction auct;
   int next;
   int tmp;

   next = 0;
   foreach (auct in _auctions) {
      tmp = auct->time_started + auct->auction_length - time();
      if (tmp <= 0) {
         finish_auction(auct);
      } else if (tmp < next || !next) {
         next = tmp;
      }
   }

   //
   // Check for auctions that have timedout out their stay in the
   // claim list.
   //
   foreach (auct in _finished_auctions) {
      tmp = auct->time_started + auct->auction_length + _retrieval_time -
        time();
      if (tmp <= 0) {
         retry_auction(auct);
         tmp = auct->time_started + auct->auction_length - time();
         if (tmp < next || !next) {
            next = tmp;
         }
      } else if (tmp < next || !next) {
         next = tmp;
      }
   }

   if (_callout_id) {
      remove_call_out(_callout_id);
      _callout_id = 0;
   }
   if (next) {
      _callout_id = call_out("next_auction_finish", next);
   }
} /* next_auction_finish() */

/**
 * This method lists all the current auctions.
 */
int do_list() {
   string str;
   class auction bing;
   int pos;
   string place;

   if (!is_open(this_player(), 0)) {
      add_failed_mess(this_object()->the_short() + " is not open.\n");
      return 0;
   }

   if (!sizeof(_auctions)) {
      add_failed_mess("Nothing currently on auction.\n");
      return 0;
   }

   place = query_property("place");
   str = "Items currently up for auction:\n";
   foreach (bing in _auctions) {
      str += sprintf("%c) %s", pos + 'A', bing->name);
      if (bing->current_bidder) {
         str += "; " + 
                MONEY_HAND->money_value_string(bing->bid, place) +
                " by " + bing->current_bidder + "; finishes in " +
                query_auction_end_string(bing) + ".\n";
      } else {
         str += "; no current bid; finishes in " +
                query_auction_end_string(bing) + ".\n";
      }
      pos++;
   }

   if (!broadcast_shop_event(AUCTION_EVENT_LIST,
                             this_player(), str)) {
      write("$P$Auctions$P$" + str);
   }
   return 1;
} /* do_list() */

/**
 * This method allows you to browse the item.
 * @param id the id of the auction thing to browse
 */
int do_browse(string id) {
   class auction bing;
   string place;
   string str;
   object* obs;
   object ob;

   if (!is_open(this_player(), 0)) {
      add_failed_mess(this_object()->the_short() + " is not open.\n");
      return 0;
   }

   bing = query_auction_item(id);
   if (!bing) {
      add_failed_mess("There is no auction item " + id + ".\n");
      return 0;
   }

   place = query_property("place");
   str = "Auction called " + bing->name + " started at " +
        amtime(bing->time_started) + " finishes at " +
        amtime(bing->time_started + bing->auction_length) + " (in " +
        query_auction_end_string(bing) + ".\n";
   str += "Reserve price " +
          MONEY_HAND->money_value_string(bing->reserve, place);
   if (bing->bid) {
      str += "; current bid " +
             MONEY_HAND->money_value_string(bing->bid, place) +
             " by " + bing->current_bidder + ".\n";
   } else {
      str += "; no current bid.\n";
   }
   obs = query_auction_objects(bing);
   foreach (ob in obs) {
      str += "\n$I$0=$C$" + ob->the_short() + ":\n$I$3=   " +
             ob->long();
      if (ob->query_readable_message(this_player())) {
         str += "$I$0=Read message:\n$I$3=   " + ob->query_readable_message(this_player()) + "\n";
      }
   }
 
   if (!broadcast_shop_event(AUCTION_EVENT_BROWSE,
                             this_player(), bing, obs, str)) {
      write("$P$Browse Auction$P$" + str);
   }
   return 1;
} /* do_browse() */

/**
 * This method makes a bid on the specified item.
 * @param id the item to bid on
 * @param bid the amount to bid
 * @return 1 on success, 0 on failure
 */
int do_bid(string id, string bid) {
   class auction auct;
   string place;
   int value;
   int inc;

   if (!is_open(this_player(), 0)) {
      add_failed_mess(this_object()->the_short() + " is not open.\n");
      return 0;
   }
   
   auct = query_auction_item(id);
   if (!auct) {
      if (!broadcast_shop_event(AUCTION_EVENT_BAD_ITEM,
                                 this_player(), id)) {
         add_failed_mess("There is no auction item " + id + ".\n");
      }
      return 0;
   }

   place = query_property("place");
   value = MONEY_HAND->value_from_string(bid, place);

   if (_can_bid) {
      if (!evaluate(_can_bid, this_player(), auct, value)) {
         return 0;
      }
   }

   inc = auct->bid + ((auct->bid * _minimum_bid_increase) / 100);
   if (value < inc) {
      if (!broadcast_shop_event(AUCTION_EVENT_BID_TOO_SMALL,
                                 this_player(), auct, value, inc)) {
         add_failed_mess("You must bid " + _minimum_bid_increase + "% more than "
                         "the current bid, current bid is " +
                         MONEY_HAND->money_value_string(auct->bid, place) +
                         " so " + _minimum_bid_increase + "% more is " +
                         MONEY_HAND->money_value_string(inc, place) +
                         ".\n");
      }
      return 0;
   }
   
   if (value < auct->reserve) {
      if (!broadcast_shop_event(AUCTION_EVENT_BID_BELOW_RESERVE,
                                 this_player(), auct, value, auct->reserve)) {
         add_failed_mess("You must bid more than the reserve bid, it is " +
                      MONEY_HAND->money_value_string(auct->reserve, place) + ".\n");
      }
      return 0;
   }

   bid_on_item(auct, value, this_player()->query_cap_name());
   save_me();
   if (!broadcast_shop_event(AUCTION_EVENT_BID,
                             this_player(), auct, value)) {
      add_succeeded_mess("$N $V " +
                         MONEY_HAND->money_value_string(value, place) +
                         " on " + auct->name + ".\n");
   }
   return 1;
} /* do_bid() */

/**
 * This method withdraws the item from bidding.  You pay a penalty when you
 * do this, 10% of the current item cost.
 * @param id the id to withdraw
 */
int do_withdraw(string id) {
   class auction auct;
   string place;
   int value;
   object* obs;
   object ob;

   if (!is_open(this_player(), 0)) {
      add_failed_mess(this_object()->the_short() + " is not open.\n");
      return 0;
   }
   
   auct = query_auction_item(id);
   if (!auct) {
      if (!broadcast_shop_event(AUCTION_EVENT_BAD_ITEM,
                                 this_player(), id)) {
         add_failed_mess("There is no auction item " + id + ".\n");
      }
      return 0;
   }

   place = query_property("place");
   if (lower_case(auct->seller) == this_player()->query_name() ||
       this_player()->query_creator()) {
      // Make sure they have the money.
      if (auct->reserve > auct->bid) {
         value = auct->reserve;
      } else {
         value = auct->bid;
      }
      if (this_player()->query_value_in(place) < value) {
         if (!broadcast_shop_event(AUCTION_EVENT_TOO_POOR,
                              this_player(), auct, 
                              this_player()->query_value_in(place),
                              auct->bid)) {
            add_failed_mess("You need at least " +
                            MONEY_HAND->money_value_string(value, place) +
                            " to withdraw this item from auction.\n");
         }
         return 0;
      }
      obs = query_auction_objects(auct);
      this_player()->pay_money(MONEY_HAND->create_money_array(value, place),
        place);
      remove_auction_item(auct);
      save_me();
      if (auct->end_function) {
         call_other(this_object(), auct->end_function, 
                    AUCTION_WITHDRAW_PHASE, auct, auct->extra);
      }
      foreach (ob in obs) {
         if (ob->move(this_player()) != MOVE_OK) {
             ob->move(this_object());
             write("Unable to move " + ob->the_short() +
                   " into your inventory, put on the floor.\n");
         }
      }
      if (!broadcast_shop_event(AUCTION_EVENT_WITHDRAW,
                                 this_player(), auct)) {
         add_succeeded_mess("$N remove$s " + auct->name + " from auction.\n");
      }
      return 1;
   }
   if (!broadcast_shop_event(AUCTION_EVENT_CANNOT_WITHDRAW,
                              this_player(), auct)) {
      add_failed_mess("You cannot withdraw that item from auction.\n");
   }
   return 0;
} /* do_withdraw() */

/**
 * This method claims anything that you can bought and is waiting for
 * pickup.
 */
int do_claim() {
   class auction auction;
   int num;
   string place;
   object* obs;
   object ob;
   int i;
   int value;

   if (!is_open(this_player(), 0)) {
      add_failed_mess(this_object()->the_short() + " is not open.\n");
      return 0;
   }
   
   place = query_property("place");
   value = this_player()->query_value_in(place);
   foreach (auction in _finished_auctions) {
      if (!auction->current_bidder) {
         remove_finished_auction_item(auction);
      } else if (lower_case(auction->current_bidder) == this_player()->query_name()) {
         if (value < auction->bid) {
            if (!broadcast_shop_event(AUCTION_EVENT_TOO_POOR,
                              this_player(), auction, value, auction->bid)) {
               write("You do not have enough money to pay for " +
                     MONEY_HAND->money_value_string(auction->bid, place) +
                     ".\n");
            }
         } else {
            
            this_player()->pay_money( 
                MONEY_HAND->create_money_array(auction->bid, place), place);
            value -= auction->bid;
            // Add the bid to the royalties.
            _royalties[lower_case(auction->seller)] += auction->bid -
                                           auction->bid * _cut / 100;
            obs = AUTO_LOAD_OB->load_auto_load_to_array(auction->save_stuff);
            foreach (ob in obs) {
               if (ob->move(this_player()) != MOVE_OK) {
                  ob->move(this_object());
                  write("Unable to move " + ob->the_short() +
                        " into your inventory, put on the floor.\n");
               }
            }
            if (!broadcast_shop_event(AUCTION_EVENT_CLAIM,
                              this_player(), auction, auction->bid, obs)) {
               write("You paid " +
                     MONEY_HAND->money_value_string(auction->bid, place) +
                     " for " +
                     query_multiple_short(obs) + ".\n");
            }
            remove_finished_auction_item(auction);
            save_me();
            if (auction->end_function) {
               call_other(this_object(), auction->end_function, 
                          AUCTION_CLAIM_PHASE, auction, auction->extra,
                          auction->current_bidder, auction->bid, obs);
            }
         }
         num++;
      }
      i++;
   }
   if (!num) {
      if (!broadcast_shop_event(AUCTION_EVENT_NOTHING_TO_CLAIM,
                              this_player())) {
         add_failed_mess("You cannot find anything to claim.\n");
      }
   }
   return num;
} /* do_claim() */

/**
 * This method adds an item for bidding.
 * @param name the name to put them up for bidding as
 * @param obs the objects to auction
 * @param res_str the reserve price
 * @param length the length of the auction
 * @return 1 on success, 0 on failed
 */
int do_add(string name, object* obs, string res_str, string length) {
   int reserve;
   string ret;
   string place;
   int len;

   if (!is_open(this_player(), 0)) {
      add_failed_mess(this_object()->the_short() + " is not open.\n");
      return 0;
   }
   
   place = query_property("place");

   len = _auction_times[length];

   if (sizeof(_auctions) >= _max_auctions) {
      if (!broadcast_shop_event(AUCTION_EVENT_FULL,
                             this_player(), name, obs, reserve, len)) {
         add_failed_mess("The auction house is full.\n");
      }
      return 0;
   }

   if (res_str) {
      reserve = MONEY_HAND->value_from_string(res_str, place);
      if (!reserve) {
         if (!broadcast_shop_event(AUCTION_EVENT_BAD_MONEY,
                             this_player(), name, obs, reserve, len)) {
            add_failed_mess("Unable to figure out how much " + res_str +
                            " is.\n");
         }
         return 0;
      }
   }


   ret = "You are putting " + query_multiple_short(obs) + " up for "
         "auction as " + name + " for " +
          query_time_end_string(len);
   if (reserve) {
     ret += " with a reserve price of " +
            MONEY_HAND->money_value_string(reserve, place);
   }
   if (!broadcast_shop_event(AUCTION_EVENT_ADD_AUCTION,
                             this_player(), name, obs, reserve, len, ret + ".")) {
      write(ret + ".\n");
      write("Are you sure you wish to do this? ");
   }
   input_to("confirm_auction", 0, name, obs, reserve, len);
   add_succeeded_mess(({ "", "$N put$s $I up for auction.\n" }), obs);
   return 1;
} /* do_add() */

/** Confirm the addition */
void confirm_auction(string check, string name, object* obs, int reserve, int len) {
   string place;
   string ret;

   place = query_property("place");
   check = lower_case(check);
   if (!strlen(check) || check[0] != 'y') {
      if (!broadcast_shop_event(AUCTION_EVENT_ADD_ABORT,
                             this_player(), name, obs, reserve, len)) {
         write("Ok, Aborting.\n");
      }
      return ;
   }
   
   add_item_to_auction(obs, name, reserve,
                       this_player()->query_cap_name(), len, 0, 0);
   ret = "You put " + query_multiple_short(obs) + " up for "
         "auction as " + name + " for " + 
          query_time_end_string(len);
   if (reserve) {
     ret += " with a reserve price of " +
            MONEY_HAND->money_value_string(reserve, place) + "";
   }
   if (!broadcast_shop_event(AUCTION_EVENT_CONFIRM_AUCTION,
                             this_player(), name, obs, reserve, len, ret + ".")) {
      write(ret + ".\n");
   }
   
   // Finally, get rid of the items which now exist in the auction house
   obs->move("/room/rubbish");
   
} /* confirm_auction() */

/**
 * This method shoes information about the auction house, like the
 * amount of time for each type of auction.
 * @return 1 on success
 */
int do_info() {
   string ret;
   string name;
   int len;

   if (!is_open(this_player(), 0)) {
      add_failed_mess(this_object()->the_short() + " is not open.\n");
      return 0;
   }

   ret = "$I$3=The times for the auction are:\n";
   foreach (name, len in _auction_times) {
      ret += name + ": " + query_time_end_string(len) + "\n";
   }
   if (!broadcast_shop_event(AUCTION_EVENT_INFO, this_player(), ret)) {
      write("$P$Auction lengths$P$" + ret);
   }
   return 1;
} /* do_info() */

void init() {
   add_command("list", "", (: do_list() :));
   add_command("browse", "<string'auction id'>", (: do_browse($4[0]) :));
   add_command("bid", "<string'auction id'> for <string'money'>",
               (: do_bid($4[0], $4[1]) :));
   add_command("bid", "<string'money'> on <string'auction id'>",
               (: do_bid($4[1], $4[0]) :));
   add_command("claim", "", (: do_claim() :));
   add_command("withdraw", "<string'auction id'> [from auction]",
                (: do_withdraw($4[0]) :));
   if (_allow_add) {
      if (!_bid_type_names) {
         _bid_type_names = implode(keys(_auction_times), "|");
      }
      add_command("info", "", (: do_info() :));
      add_command("add", "{" + _bid_type_names +
                   "} auction of <indirect:object:me> as <string'name'>",
                  (: do_add($4[2], $1, 0, $4[0]) :));
      add_command("add", "{" + _bid_type_names +
                  "}  auction of <indirect:object:me> as <string'name'> reserve <string'price'>",
                  (: do_add($4[2], $1, $4[3], $4[0]) :));
   }
} /* init() */