final_realms_fluffos_v1/
final_realms_fluffos_v1/bin/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/ChangeLog.old/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/Win32/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/compat/simuls/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/clone/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/command/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/data/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/etc/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/include/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/inherit/master/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/log/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/compiler/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/efuns/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/single/tests/operators/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/testsuite/u/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/tmp/
final_realms_fluffos_v1/fluffos-2.9-ds2.11/windows/
final_realms_fluffos_v1/lib/baseobs/guilds/
final_realms_fluffos_v1/lib/baseobs/misc/
final_realms_fluffos_v1/lib/baseobs/races/shadows/
final_realms_fluffos_v1/lib/cmds/god/
final_realms_fluffos_v1/lib/cmds/handlers/
final_realms_fluffos_v1/lib/cmds/handlers/cmds/
final_realms_fluffos_v1/lib/d/heaven/
final_realms_fluffos_v1/lib/d/heaven/heaven/ave/
final_realms_fluffos_v1/lib/d/mudlib/
final_realms_fluffos_v1/lib/d/newbie/
final_realms_fluffos_v1/lib/d/newbie/docs/
final_realms_fluffos_v1/lib/d/newbie/drow/armour/
final_realms_fluffos_v1/lib/d/newbie/drow/items/
final_realms_fluffos_v1/lib/d/newbie/drow/mobs/
final_realms_fluffos_v1/lib/d/newbie/drow/oldmobs/
final_realms_fluffos_v1/lib/d/newbie/drow/weapons/
final_realms_fluffos_v1/lib/d/newbie/duergar/weapons/
final_realms_fluffos_v1/lib/d/newbie/dwarf/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/cafe/
final_realms_fluffos_v1/lib/d/newbie/elf/chars/equip/
final_realms_fluffos_v1/lib/d/newbie/elf/items/armours/
final_realms_fluffos_v1/lib/d/newbie/elf/items/obj/
final_realms_fluffos_v1/lib/d/newbie/elf/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/elf/quick_fix/
final_realms_fluffos_v1/lib/d/newbie/gnome/armour/
final_realms_fluffos_v1/lib/d/newbie/gnome/buildings/
final_realms_fluffos_v1/lib/d/newbie/gnome/items/
final_realms_fluffos_v1/lib/d/newbie/gnome/npcs/clones/
final_realms_fluffos_v1/lib/d/newbie/gnome/rooms/northrooms/
final_realms_fluffos_v1/lib/d/newbie/gnome/weapons/
final_realms_fluffos_v1/lib/d/newbie/goblin/armour/
final_realms_fluffos_v1/lib/d/newbie/goblin/items/
final_realms_fluffos_v1/lib/d/newbie/grads/log/
final_realms_fluffos_v1/lib/d/newbie/grads/npcs/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/
final_realms_fluffos_v1/lib/d/newbie/grads/rooms/cave1/
final_realms_fluffos_v1/lib/d/newbie/grads/temp/
final_realms_fluffos_v1/lib/d/newbie/guests/weapons/
final_realms_fluffos_v1/lib/d/newbie/half-elf/items/
final_realms_fluffos_v1/lib/d/newbie/half-elf/newroomss/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/castle/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/drows/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/savannah/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/secret/
final_realms_fluffos_v1/lib/d/newbie/half-elf/rooms/town/
final_realms_fluffos_v1/lib/d/newbie/halfling/
final_realms_fluffos_v1/lib/d/newbie/halfling/misc/
final_realms_fluffos_v1/lib/d/newbie/halfling/rooms/cave/
final_realms_fluffos_v1/lib/d/newbie/human/
final_realms_fluffos_v1/lib/d/newbie/human/armour/
final_realms_fluffos_v1/lib/d/newbie/human/monsters/
final_realms_fluffos_v1/lib/d/newbie/human/obj/
final_realms_fluffos_v1/lib/d/newbie/human/weapons/
final_realms_fluffos_v1/lib/d/newbie/lizard/armour/
final_realms_fluffos_v1/lib/d/newbie/lizard/items/
final_realms_fluffos_v1/lib/d/newbie/lizard/underwater/
final_realms_fluffos_v1/lib/d/newbie/lizard/weapons/
final_realms_fluffos_v1/lib/d/newbie/logs/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/
final_realms_fluffos_v1/lib/d/newbie/new_halfelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/npcs/
final_realms_fluffos_v1/lib/d/newbie/newdrow/rooms/
final_realms_fluffos_v1/lib/d/newbie/newelf/
final_realms_fluffos_v1/lib/d/newbie/newelf/chars/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/
final_realms_fluffos_v1/lib/d/newbie/newelf/npcs/recopied/
final_realms_fluffos_v1/lib/d/newbie/newelf/obj/
final_realms_fluffos_v1/lib/d/newbie/newelf/quest_docs./
final_realms_fluffos_v1/lib/d/newbie/newken/
final_realms_fluffos_v1/lib/d/newbie/newken/chars/
final_realms_fluffos_v1/lib/d/newbie/newken/misc/
final_realms_fluffos_v1/lib/d/newbie/newken/npcs/
final_realms_fluffos_v1/lib/d/newbie/newken/obj/
final_realms_fluffos_v1/lib/d/newbie/newliz/
final_realms_fluffos_v1/lib/d/newbie/newliz/cave/
final_realms_fluffos_v1/lib/d/newbie/newliz/npcs/
final_realms_fluffos_v1/lib/d/newbie/orc/items/misc/
final_realms_fluffos_v1/lib/d/newbie/orc/items/weapons/
final_realms_fluffos_v1/lib/d/newbie/orc/tower/
final_realms_fluffos_v1/lib/d/vehicle/
final_realms_fluffos_v1/lib/doc/
final_realms_fluffos_v1/lib/doc/driver/
final_realms_fluffos_v1/lib/doc/driver/concepts/
final_realms_fluffos_v1/lib/doc/driver/driver/
final_realms_fluffos_v1/lib/doc/driver/efuns/arrays/
final_realms_fluffos_v1/lib/doc/driver/efuns/bitstrings/
final_realms_fluffos_v1/lib/doc/driver/efuns/communication/
final_realms_fluffos_v1/lib/doc/driver/efuns/core/
final_realms_fluffos_v1/lib/doc/driver/efuns/debugging/
final_realms_fluffos_v1/lib/doc/driver/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/driver/efuns/interactive/
final_realms_fluffos_v1/lib/doc/driver/efuns/mappings/
final_realms_fluffos_v1/lib/doc/driver/efuns/objects/
final_realms_fluffos_v1/lib/doc/driver/efuns/security/
final_realms_fluffos_v1/lib/doc/driver/efuns/strings/
final_realms_fluffos_v1/lib/doc/driver/efuns/system/
final_realms_fluffos_v1/lib/doc/driver/efuns/types/
final_realms_fluffos_v1/lib/doc/driver/lpc/constructs/
final_realms_fluffos_v1/lib/doc/driver/lpc/types/
final_realms_fluffos_v1/lib/doc/driver/platforms/
final_realms_fluffos_v1/lib/doc/lpc/
final_realms_fluffos_v1/lib/doc/mail/
final_realms_fluffos_v1/lib/doc/man/
final_realms_fluffos_v1/lib/doc/man/html/
final_realms_fluffos_v1/lib/doc/man/html/applies/
final_realms_fluffos_v1/lib/doc/man/html/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/html/driver/
final_realms_fluffos_v1/lib/doc/man/html/efuns/
final_realms_fluffos_v1/lib/doc/man/html/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/html/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/html/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/html/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/html/efuns/general/
final_realms_fluffos_v1/lib/doc/man/html/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/html/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/
final_realms_fluffos_v1/lib/doc/man/local/applies/
final_realms_fluffos_v1/lib/doc/man/local/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/local/applies/master/
final_realms_fluffos_v1/lib/doc/man/local/concepts/
final_realms_fluffos_v1/lib/doc/man/local/defines/
final_realms_fluffos_v1/lib/doc/man/local/driver/
final_realms_fluffos_v1/lib/doc/man/local/efuns/
final_realms_fluffos_v1/lib/doc/man/local/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/local/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/local/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/local/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/local/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/local/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/local/efuns/general/
final_realms_fluffos_v1/lib/doc/man/local/efuns/interactive/
final_realms_fluffos_v1/lib/doc/man/local/efuns/internals/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/local/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/local/efuns/objects/
final_realms_fluffos_v1/lib/doc/man/local/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/local/efuns/sockets/
final_realms_fluffos_v1/lib/doc/man/local/efuns/strings/
final_realms_fluffos_v1/lib/doc/man/local/efuns/system/
final_realms_fluffos_v1/lib/doc/man/local/historical/
final_realms_fluffos_v1/lib/doc/man/local/lfun/QC/
final_realms_fluffos_v1/lib/doc/man/local/lfun/events/
final_realms_fluffos_v1/lib/doc/man/local/lfun/monster/
final_realms_fluffos_v1/lib/doc/man/local/lfun/properties/
final_realms_fluffos_v1/lib/doc/man/local/lpc/
final_realms_fluffos_v1/lib/doc/man/local/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/local/lpc/types/
final_realms_fluffos_v1/lib/doc/man/local/standards/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/basic/
final_realms_fluffos_v1/lib/doc/man/local/tutorials/intermediate/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/interactive/
final_realms_fluffos_v1/lib/doc/man/mudos/applies/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/concepts/
final_realms_fluffos_v1/lib/doc/man/mudos/driver/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/arrays/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/buffers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/calls/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/compile/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/filesystem/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/floats/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/functions/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/general/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mappings/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mixed/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/mudlib/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/numbers/
final_realms_fluffos_v1/lib/doc/man/mudos/efuns/parsing/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/constructs/
final_realms_fluffos_v1/lib/doc/man/mudos/lpc/types/
final_realms_fluffos_v1/lib/doc/races/
final_realms_fluffos_v1/lib/doc/races/old_race/
final_realms_fluffos_v1/lib/global/virtual/
final_realms_fluffos_v1/lib/global/wiz_backup/
final_realms_fluffos_v1/lib/net/config/
final_realms_fluffos_v1/lib/net/daemon/chars/
final_realms_fluffos_v1/lib/net/inherit/
final_realms_fluffos_v1/lib/net/intermud3/
final_realms_fluffos_v1/lib/net/intermud3/cmds/
final_realms_fluffos_v1/lib/net/intermud3/save/
final_realms_fluffos_v1/lib/net/intermud3/services/
final_realms_fluffos_v1/lib/net/obj/
final_realms_fluffos_v1/lib/net/old/
final_realms_fluffos_v1/lib/net/old/intermud/
final_realms_fluffos_v1/lib/net/old/intermud/adm/
final_realms_fluffos_v1/lib/net/old/intermud/services/
final_realms_fluffos_v1/lib/net/old/intermud/udp/
final_realms_fluffos_v1/lib/net/virtual/
final_realms_fluffos_v1/lib/obj/b_day/
final_realms_fluffos_v1/lib/obj/chars/
final_realms_fluffos_v1/lib/obj/handlers/lists/
final_realms_fluffos_v1/lib/obj/handlers/useless/
final_realms_fluffos_v1/lib/obj/monsters/
final_realms_fluffos_v1/lib/obj/roomgen/
final_realms_fluffos_v1/lib/obj/soul/
final_realms_fluffos_v1/lib/obj/vegetation/
final_realms_fluffos_v1/lib/obj/weapons/oldsys/
final_realms_fluffos_v1/lib/open/
final_realms_fluffos_v1/lib/players/g/
final_realms_fluffos_v1/lib/releasefiles/d/heaven/
final_realms_fluffos_v1/lib/releasefiles/d/mudlib/
final_realms_fluffos_v1/lib/releasefiles/d/newbie/
final_realms_fluffos_v1/lib/releasefiles/doc/
final_realms_fluffos_v1/lib/releasefiles/players/g/
final_realms_fluffos_v1/lib/releasefiles/save/
final_realms_fluffos_v1/lib/releasefiles/save/environ/
final_realms_fluffos_v1/lib/releasefiles/save/roomgen/
final_realms_fluffos_v1/lib/releasefiles/secure/
final_realms_fluffos_v1/lib/releasefiles/w/
final_realms_fluffos_v1/lib/releasefiles/w/god/
final_realms_fluffos_v1/lib/room/
final_realms_fluffos_v1/lib/save/
final_realms_fluffos_v1/lib/save/environ/
final_realms_fluffos_v1/lib/save/roomgen/
final_realms_fluffos_v1/lib/scripts/
final_realms_fluffos_v1/lib/secure/crerem/
final_realms_fluffos_v1/lib/secure/dom/
final_realms_fluffos_v1/lib/secure/log/
final_realms_fluffos_v1/lib/secure/misc/
final_realms_fluffos_v1/lib/std/adnd/
final_realms_fluffos_v1/lib/std/commands/shadows/
final_realms_fluffos_v1/lib/std/creator/
final_realms_fluffos_v1/lib/std/curses/
final_realms_fluffos_v1/lib/std/curses/old_sys/
final_realms_fluffos_v1/lib/std/curses/shadows/
final_realms_fluffos_v1/lib/std/dom/
final_realms_fluffos_v1/lib/std/effects/
final_realms_fluffos_v1/lib/std/effects/healing/
final_realms_fluffos_v1/lib/std/effects/other/
final_realms_fluffos_v1/lib/std/effects/poisons/
final_realms_fluffos_v1/lib/std/environ/
final_realms_fluffos_v1/lib/std/guilds/
final_realms_fluffos_v1/lib/std/guilds/priests/samples/
final_realms_fluffos_v1/lib/std/guilds/wizards/
final_realms_fluffos_v1/lib/std/living/baldy/
final_realms_fluffos_v1/lib/std/living/divstuff/
final_realms_fluffos_v1/lib/std/paran/
final_realms_fluffos_v1/lib/std/poisons/
final_realms_fluffos_v1/lib/std/poisons/shadows/
final_realms_fluffos_v1/lib/std/poisons/weapons/
final_realms_fluffos_v1/lib/std/race_groups/
final_realms_fluffos_v1/lib/std/room/
final_realms_fluffos_v1/lib/std/room/old/
final_realms_fluffos_v1/lib/std/rooms/
final_realms_fluffos_v1/lib/std/shadows/
final_realms_fluffos_v1/lib/std/shadows/test_shad/
final_realms_fluffos_v1/lib/std/socket/
final_realms_fluffos_v1/lib/std/spells/
final_realms_fluffos_v1/lib/std/vaults/
final_realms_fluffos_v1/lib/tmp/
final_realms_fluffos_v1/lib/w/
final_realms_fluffos_v1/lib/w/god/
final_realms_fluffos_v1/old/
final_realms_fluffos_v1/win32/
inherit "/std/room";
/* Reworked by Hamlet July/August 1995. */
/* New features:
        1)  DOCUMENTATION!  
        2)  A more sensical scaled_value()  (makes more sense to me at least)
    3)  Ability to force-set the price the shop will offer for an item;
        set_resale_value(), adjust_resale_value(), query_resale_value(),
        prevent_resale(), and allow_resale()  all added to 
        /std/basic/misc.c (so, /std/object).
    4)  Stolen items are worth less now.  % modifier and 
        set_stolen_modifier() to alter that modifier.  Also
        set_stolen_modifier(), query_stolen_modifier(), and
        no_sell_if_stolen() in /std/basic/misc.c
    5)  A shop can be sell-only.  The commands "value" and "sell"
        are turned off for that.  Put sell_only() in setup();
        6)  You can specify a special function in your shop to be run
            ever time something is sold or bought.  call is
            set_sell_func("func") and set_buy_func("func");
            func should look like:  void func(object *stuff);
            Yes, this means that stuff is an ARRAY of items being bought
            or sold.
    
*/

// Edited 11 SEP 94 by Timion and Taniwha to fix the sell item bug.

/*
 * Original made who knows when.
 * Modified by bil to make the list a lot nicer.
 * Modified by Pinkfish to give shops types and make them send out
 * reps to sell/buy things from other shops.
 */

/* I am not sure whose code is whose any more.  This *is* an extensive
   rewrite, and a lot of it is now mine.  Credits stay, though, since
   I don't know which is which. - Hamlet
*/
/* Note:  rewrite is not done.  A lot of the code is original still.
          Don't expect that to be true for long (muhahaha)
*/

#include "money.h"
#include "move_failures.h"
#include "shop.h"
#include "armoury.h"

mixed our_storeroom;
mixed buy_mess, sell_mess, list_mess, value_mess, browse_mess,
      open_cond, *other_shops;
int amount_sold,
    amount_bought;
 string shop_type;
int stolen_modifier;  /* This will be a percent value */
int only_sell = 0;
string sell_func, buy_func;

 string query_name(object ob);
 string query_short(object ob);
int check_inv(object ob, string str);
string shop_list(mixed arr, int detail);
void do_buy(object *ob, int cost, object pl);
string shop_parse(string str, mixed ob, object client, string money,
                              string extra);
void do_parse(mixed arr, mixed ob, object client, string money,
                              string extra);

void create() {
  buy_mess = ({ "You buy $ob$ for $money$.\n",
                "$client$ buys $ob$.\n" });
  sell_mess = ({ "You sell $ob$ for $money$.\n",
                 "$client$ sells $ob$.\n" });
  list_mess = "$extra$";
  value_mess = "The $ob$ is valued at $money$.\n";
  browse_mess = "The $ob$ costs $money$, it looks like:\n$extra$";
  open_cond = 1;
  other_shops = ({ });
   shop_type = "general";
  stolen_modifier = 33;  /* 33% of normal value */
  ::create();
}

/* These make spiffy messages for various actions. */
void set_sell_message(mixed str) { sell_mess = str; }
void set_buy_message(mixed str) { buy_mess = str; }
void set_value_message(mixed str) { value_mess = str; }
void set_browse_message(mixed str) { browse_mess = str; }
void set_list_message(mixed str) { list_mess = str; }

void set_open_condition(mixed str) { open_cond = str; }

mixed query_sell_mess() { return sell_mess; }
mixed query_list_mess() { return list_mess; }
mixed query_value_mess() { return value_mess; }
mixed query_buy_mess() { return buy_mess; }
mixed query_browse_mess() { return browse_mess; }

/* These initialize sell_func and buy_func, which are special functions
   that can be set to run when something is bought or sold.
*/
void set_sell_func(string str) {  sell_func = str; }
void set_buy_func(string str) { buy_func = str; }

mixed query_open_condition() { return open_cond; }

/* This is whether the shop is open or not.  open_cond can be
   an int (true/false). Or a string, in which case it 'points'
   to a function in the current object to run.  OR, it can be
   an array.  ({ "object/name", "function_name" }) where it runs
   "object/name"->function_name() to determine whether the shop is
   open.
*/
int test_open() {
  if (stringp(open_cond))
    return (int)call_other(this_object(), open_cond);
  if (intp(open_cond))
     return open_cond;
  return (int)call_other(open_cond[0], open_cond[1]);
}

int sell_only() {  only_sell = 1; return 1; }

void init() {
  ::init();
  add_action("sell", "sell");
  add_action("buy", "buy");
  add_action("list", "list");
  add_action("browse", "browse");
  add_action("value", "value");
}

/* This determines how much the shopkeeper will offer for an item, according
   to its value.  It only gets called if set_no_resell() has not been called
   and resale_value has not been hand-set to something.
*/
int scaled_value(int n)
{
   int *prates;
   int i, tot;

   tot = 0;
   prates = PAY_RATES;
   for(i=0;( (i<sizeof(prates)) && (n > prates[i]) );i+=2);
   
   if(i>0)
     i-=2;/* prates[i] is now the rate-increment directly below the value. */

   tot = (n - prates[i]) * ((prates[i+2] / prates[i+3]) - 
           (prates[i] / prates[i+1]));
   tot /= (prates[i+2] - prates[i]);
   tot += (prates[i] / prates[i+1]);
       
   /* For those curious, we just defined a line segment.  Basically, we
      used  y - y1 = m(x - x1).  And found the y value for x = n.
      Read shop.h for better explanation.
   */
       
   return tot;
}

int set_stolen_modifier(int amt) { 
  if(amt > 100)
    amt = 100;
  if(amt < 0)
    amt = 0;
  
  stolen_modifier = amt;
  
  return amt;
}

/* This checks the player to make sure they have the item. 
   I *think* this is a paranoia check, but I'll leave it.
*/
int check_inv(object thing, string str)
{
  int i;
  object *inv = find_match(str,this_player());
  
  for(i =0; i < sizeof(inv); i++) {
    if(inv[i] == thing) return(1);
  }
  
  return(0);
}

int sell(string str) {
  object *obs, *selling, *cannot;
  mixed *m_array;
  int i, j, no, amt, value, total_amt;
   string s;

  if (!test_open())
    return 0;
  
  if(only_sell) {
    tell_object(this_player(),"This shop does not buy merchandise.\n");
    return 1;
  }
  
  if (!str || str == "") {
    notify_fail("Usage: sell <objects>\n");
    return 0;
  }
  obs = find_match(str, this_player());
  if (!sizeof(obs)) {
    notify_fail("Nothing to sell.\n");
    return 0;
  }
  if(sizeof(obs) > MAX_OBS) {
    write("The shopkeeper can't cope with all those objects.\n");
    obs = obs[0..MAX_OBS - 1];
  }
  selling = cannot = ({ });
  for (i=0;i<sizeof(obs);i++) {
    if( (obs[i]->query_value() > 0) && !obs[i]->do_not_sell() &&
        (obs[i]->query_resale_value() != -1) && 
        ((obs[i]->query_stolen_modifier() != -1) || 
          !obs[i]->query_property("stolen")) && !obs[i]->query_in_use()) {
            /* O.K. this SHOULD check to see if the item IS in the inventory 
               before we move it */
       if(check_inv(obs[i],str)) {
        if (obs[i]->move(our_storeroom)) {
          if (obs[i]->short())
            cannot += ({ obs[i] });
          continue;
        }
      /* the call other (buried) in the below is so that we can update 
         /std/shop and have all the shops prices fall in line consistently */
      amt = obs[i]->query_resale_value(); 
      if(!amt) {
        amt = (int)"/std/shop"->scaled_value((int)obs[i]->query_value());
        if(amt > MAX_AMOUNT)
          amt = MAX_AMOUNT;
      }
      
      /* Let's not let something sell back for more than it was bought for */
      if(amt > obs[i]->query_value())
        amt = obs[i]->query_value();

      /* "hot" goods lose value!  */      
      if(obs[i]->query_property("stolen")) {
        if(obs[i]->query_stolen_modifier() == 0)
          amt = amt * stolen_modifier / 100;
        else
          amt = amt * obs[i]->query_stolen_modifier() / 100;
      }
        
      total_amt += amt;
      selling += ({ obs[i] });
      obs[i]->being_sold();
    } else if (obs[i]->short())
        cannot += ({ obs[i] });
  /* end of test if exists, not that this DOESN'T do the cannot that it should
*/
          }
    else if (obs[i]->short())
      cannot += ({ obs[i] });
  }
  if (!sizeof(selling)) {
     if (sizeof(cannot))
      notify_fail("You cannot sell "+query_multiple_short(cannot)+", maybe you are holding or wearing it, or just don't have one.\n");
    else
      notify_fail("Nothing to sell.\n");
    return 0;
  }
  amount_sold += total_amt;
  m_array = (mixed *)MONEY_HAND->create_money_array(total_amt);
  this_player()->adjust_money(m_array);
  if (sizeof(cannot))
    write("You cannot sell "+query_multiple_short(cannot)+", maybe you are wearing or holding it, or just don't have one.\n");
  do_parse(sell_mess, selling, this_player(),
                (string)MONEY_HAND->money_string(m_array), "");
  if(sell_func)  call_other(this_object(),sell_func,selling);
  return 1;
}

int buy(string str) {
  int i, amt, ob_amt, total_cost;
  object *obs, *to_buy, *cannot, *too_much;
  string s;

  if (!test_open())
     return 0;

  if (!str || str == "") {
    notify_fail("Usage: buy <objects>\n");
    return 0;
  }
  obs = find_match(str, our_storeroom);
  if (!sizeof(obs)) {
    notify_fail("Cannot find "+str+".\n");
    return 0;
  }
  if(sizeof(obs) > MAX_OBS) {
    write("The shopkeeper can't cope with all those objects.\n");
    obs = obs[0..MAX_OBS-1];
  }
  to_buy = too_much = cannot = ({ });
  amt = (int)this_player()->query_value();
  while (i<sizeof(obs)) {
    if ((ob_amt = (int)obs[i]->query_value()) > amt) {
      if (obs[i]->short())
        too_much += ({ obs[i] });
      obs = delete(obs, i, 1);
       continue;
    }
    if (obs[i]->move(this_player())) {
      if (obs[i]->short())
        cannot += ({ obs[i] });
       i++;
      continue;
    }
    obs[i]->move(our_storeroom);
    amt -= ob_amt;
    total_cost += ob_amt;
    to_buy += ({ obs[i] });
    i++;
  }
  amount_bought += total_cost;
  s = "";
  if (sizeof(cannot))
    s += "You cannot pick up "+query_multiple_short(cannot)+".\n";
  if (sizeof(too_much))
    s += capitalize(query_multiple_short(too_much))+" costs too much.\n";
  if(!sizeof(to_buy)) {
    if(s != "")
      notify_fail(s);
    else
      notify_fail("Nothing to buy.\n");
    return 0;
   } else {
    write(s);
  }
  do_buy(to_buy, total_cost, this_player());
  if(buy_func)  call_other(this_object(),buy_func,to_buy);
  return 1;
}

void do_buy(object *obs, int cost, object pl) {
  int i;
  mixed fish;

  for (i=0;i<sizeof(obs);i++)
    obs[i]->move(pl);
  pl->pay_money(fish = (int)MONEY_HAND->create_money_array(cost));
  do_parse(buy_mess, obs, pl,
                     (string)MONEY_HAND->money_string(fish), "");
}

int list(string str) {
  object ob;

  if (!test_open())
     return 0;
  if (!str || str == "" || str == "all") {
    if (objectp(our_storeroom))
      ob = our_storeroom;
    else
      ob = find_object(our_storeroom);
    do_parse(list_mess, this_object(), this_player(), "",
                                       shop_list(all_inventory(ob), 0));
    return 1;
  }
  do_parse(list_mess, this_object(), this_player(), "",
           shop_list(find_match(str, our_storeroom), 1));
  return 1;
}

int browse(string str) {
  object *obs;
  int i;

  if (!test_open())
    return 0;
   if (!str || str == "") {
    notify_fail("Usage: browse <objects>\n");
    return 0;
  }

  obs = find_match(str, our_storeroom);
  if (!sizeof(obs)) {
    notify_fail("Cannot find "+str+".\n");
    return 0;
  }
  for (i=0;i<sizeof(obs);i++)
    do_parse(browse_mess, obs[i], this_player(),
         (string)MONEY_HAND->money_value_string(obs[i]->query_value()),
         (string)obs[i]->long());
/*
    write("You look at "+obs[i]->short()+" it costs "+
           MONEY_HAND->money_string(obs[i]->query_money_array())+"\n"+
          obs[i]->long());
 */
  return 1;
}
 int value(string str) {
  object *obs;
  int i, val;

  if (!test_open())
    return 0;

  if(only_sell) {
    tell_object(this_player(),"This shop cannot appraise your goods.\n");
    return 1;
  }
              
  if (!str || str =="") {
    notify_fail("Usage: value <object>\n");
    return 0;
  }

  obs = find_match(str, this_player());
  if (!sizeof(obs)) {
    notify_fail("Cannot find "+str+".\n");
    return 0;
  }
  for (i=0;i<sizeof(obs);i++) {
    /* the call other is so that we can change the PAY_RATES array, and 
       then just update /std/shop to immediately and consistently effect 
       all shops */
    val = obs[i]->query_resale_value();
    
    if(!val) {
      val = (int)"/std/shop"->scaled_value((int)obs[i]->query_value());
      if (val > MAX_AMOUNT)
        val = MAX_AMOUNT;
    }
    
    if(val > obs[i]->query_value())
      val = obs[i]->query_value();

    /* "hot" goods lose value!  */      
    if(obs[i]->query_property("stolen")) {
      if(obs[i]->query_stolen_modifier() == 0)
        val = val * stolen_modifier / 100;
      else
        val = val * obs[i]->query_stolen_modifier() / 100;
    }
      
    do_parse(value_mess, obs[i], this_player(),
             (string)MONEY_HAND->money_value_string(val),
             (string)(obs[i]->do_not_sell() || 
                      (obs[i]->query_resale_value() == -1)) );
  }
  return 1;
}

string shop_list(mixed arr, int detail) {
  mapping inv, costs;
  object *list;
  string s, mon, *shorts, *vals;
  int i, j;
  mixed ind;

  if (pointerp(arr))
    list = arr;
  else
    list = all_inventory(this_object()); 
  /* only keep track of things with shorts ;) */
  inv = ([ ]);
  for (i=0; i<sizeof(list); i++) {
    s = (string)list[i]->short();
    if (!s || !list[i]->query_value())
      continue;
    if(!stringp(s))
      s = "get a creator for this one!";
    if (inv[s])
      inv[s] += ({ list[i] });
    else
      inv[s] = ({ list[i] });
  }
/* ok print it */
  s = "";
  shorts = m_indices(inv);
  if(!sizeof(shorts)) {
    if(detail)
      return "The shop is all out of what you wanted.\n";
    else
      return "The shop is totally out of stock.\n";
  }
  s = "You find on offer:\n";
  for (i=0; i<sizeof(shorts); i++) {
     ind = inv[shorts[i]];
    switch(sizeof(ind)) {
      case 1:
        s += "Our very last " + shorts[i];
        break;
      case 2..5:
        s += capitalize(query_num(sizeof(ind), 0) + " " +
            (string)ind[0]->query_plural());
        break;
      default:
        if(detail)
          s += capitalize(query_num(sizeof(ind), 0) + " " +
              (string)ind[0]->query_plural());
        else
          s += "A large selection of " +
              (string)ind[0]->query_plural();
    }
    if(detail) {
      costs = ([ ]);
      for(j=0;j<sizeof(ind);j++) {
        mon=(string)MONEY_HAND->money_value_string((int)ind[j]->query_value());
        if(!costs[mon])
           costs[mon] = ({ "" + (j + 1) });
        else
          costs[mon] += ({ "" + (j + 1) });
      }
      if(m_sizeof(costs) == 1) {
        s += " for " + m_indices(costs)[0];
        if(sizeof(m_values(costs)[0]) > 1)
          s += " each.\n";
        else
          s += ".\n";
      } else {
        s += ":-\n";
        vals = m_indices(costs);
        for(j=0;j<sizeof(vals);j++)
          s += "  [#" + implode(costs[vals[j]], ",") + "] for " + vals[j] +
              ".\n";
      }
    } else {
      s += ".\n";
    }
  }
  return s;
 }
void set_store_room(mixed ob) {
  if (stringp(ob)) {
    our_storeroom = find_object(ob);
    if (!our_storeroom)
      call_other(ob, "??");
    our_storeroom = find_object(ob);
  }
  our_storeroom = ob;
  our_storeroom->add_property("no_clean_up",1);
}
object query_store_room() { return our_storeroom; }

void do_parse(mixed arr, mixed ob, object client, string money,
                         string extra) {
  if (stringp(arr))
    write(shop_parse(arr, ob, client, money, extra));
  else {
    write(shop_parse(arr[0], ob, client, money, extra));
    say(shop_parse(arr[1], ob, client, money, extra));
  }
}
 string shop_parse(string str, mixed ob, object client, string money,
                         string extra) {
  string s1, s2, s3, rest;

  rest = "";
  while(sscanf(str,"%s$%s$%s", s1, s2, s3) == 3)
    switch (s2) {
      case "ob" :
        if (pointerp(ob))
          str = s1+query_multiple_short(ob)+s3;
        else
          str = s1+ob->short()+s3;
        break;
      case "client" :
        str = s1+client->query_cap_name()+s3;
        break;
      case "extra" :
        str = s1+extra+s3;
        break;
      case "money" :
        str = s1+money+s3;
         break;
      default :
        rest = s1+"$"+s2+"$";
        str = s3;
        break;
    }
  return rest+str;
}


/*
 * The shop types are:
 *  Jewelry
 *  Armory
  *  Magic
 *  General
 */
object *query_stock(string type) {
  mixed *obs;
  int i;

  obs = unique_array(all_inventory(our_storeroom), "query_shop_type");
  for (i=0;i<sizeof(obs);i++)
    if ((string)obs[i][0]->query_shop_type() == type)
      return obs[i];
  return ({ });
}

mixed *stats() {
  return ::stats() + ({
    ({ "total sold", amount_sold }),
     ({ "total bought", amount_bought }),
    });
}
 string query_shop_type() { return shop_type; }
void set_shop_type(string ty) { shop_type = ty; }

 
/* This stuff is for 'sales reps' that run from shop to shop buying and
   selling.  I can't imagine the point.  Leaving it in case someone
   goes crazy and actually wants it.
*/

/* Other shop handling code */
/*
int add_other_shop(mixed shop) {
  mixed *co_ord;

  if (pointerp(shop)) { *//* Given us a co-ordinate *//*
    other_shops += ({ shop });
    return 1;
  }
  co_ord = (mixed *)shop->query_co_ord();
  if (!pointerp(co_ord))
    return 0;
  other_shops += ({ co_ord });
}
*/
/* Ok, now, sales rep creation... Creates a rep  */
/*
object create_rep() {
  object ob;

  ob = clone_object("/obj/monster");
  ob->set_name("rep");
  ob->set_short("sales rep");
  ob->add_adjective("sales");
  ob->set_long("A tall strong looking sales rep.  He stares at you with "
               "bright pierceing eyes.\n");
  ob->set_guild("fighter");
  ob->set_race("human");
  ob->adjust_bon_str(15);  *//* Strong so they can carry all the junk *//*
  ob->set_level(300); *//* Don't want em killed.  They make a lot of money :) *//*
  ARMOURY->request_weapon("bastard", 100)->move(ob);
  ARMOURY->request_weapon("platemail", 100)->move(ob);
  ARMOURY->request_weapon("med_shield", 100)->move(ob);
  ob->init_equip();
   ob->add_property("rep type", shop_type);
}
*/
/* Send them out!  Watch them run! */
/*
void send_out_reps() {
  int i;
  object ob;

  for (i=0;i<sizeof(other_shops);i++) {
    ob = (object)this_object()->create_rep();
    ob->add_property("goto co-ordinate", other_shops[i]);
    ob->add_property("goto property", "shop");
    ob->move(this_object());
    ob->add_triggered_action("froggy", "goto_co_ord", this_object(),
                             "rep_made_it");
  }
}

void rep_made_it(int bing) {
  object *obs;
  int i, cost;
   if (!bing) {
    previous_object()->init_command("'Oh no!  I am utterly lost");
    previous_object()->init_command("sigh");
    call_out("set_up_return", 5, previous_object());
    return ;
  }
  obs = (object *)environment(previous_object())->query_stock(shop_type);
  if (!sizeof(obs)) {
    this_object()->none_to_sell();
    call_out("set_up_return", 5, previous_object());
    return ;
  }
  for (i=0;i<sizeof(obs);i++)
    cost += (int)obs[i]->query_value()*2/3;
  call_out("do_rep_buy", 5, ({ previous_object(), obs, cost }));
  previous_object()->adjust_value(cost);
}
  
void do_rep_buy(mixed *bing) {
  object rep, *obs;
  int i, cost;

  rep = bing[0];
  obs = bing[1];
  cost = bing[2];
  do_buy(obs, cost, rep);
   call_out("set_up_return", 5, rep);
}

void set_up_return(object rep) {
  rep->add_property("goto co-ordinate", this_object()->query_co_ord());
  rep->add_triggered_action("froggy", "goto_co_ord", this_object(),
                             "rep_came_back");
}

int rep_came_back() {
  int i;
  object *obs;

  obs = all_inventory(previous_object());
  for (i=0;i<sizeof(obs);i++)
    obs[i]->move(our_storeroom);
  previous_object()->dest_me();
}
*/