skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
/**
 * A basic fence for thieves and others to sell stolen items to.
 * @change Partly rewritten by Sandoz, December 2001.
 */

#include <shop.h>

inherit NPC_OBJ;

#define TIMEOUT (60*60*24*2)

#define SKILL "general.valueing"

class offer {
    object who;
    int amount;
    int offer_time;
    object *objects;
}

class offer this_offer;
object cont;
string fence_type, *stole_from_fence;
mapping old_offers;

int query_timeout() { return TIMEOUT; }
object query_cont() { return cont; }

/** @ignore yes */
mapping query_old_offers() { return old_offers; }

void whisper( object ob, string message ) {
    do_command("whisper " + message + " to " + ob->query_name() );
} /* whisper() */

/**
 * This method creates a container for the fence to use.
 * Override it in your fence NPC if you wish.
 */
void check_cont() {
    if( !cont || ENV(cont) != TO ) {
        cont = (object)ARMOURY_H->request_item("large hessian sack", 85 );
        cont->add_property("nosteal", 1 );
        cont->move(TO);
        do_command(":produces "+cont->a_short()+" from somewhere.");
    }

    if( cont->query_loc_weight() > 2 * cont->query_max_weight() / 3 ) {
        INV(cont)->move("/room/rubbish");
        old_offers = ([ ]);
    }

} /* check_cont() */

void create() {
    do_setup++;
    ::create();
    do_setup--;
    if( !do_setup )
        TO->setup();

    check_cont();

    set_respond_to_with( ({
        ({ ({"y", "yes", "Y", "Yes", "ok", "okay"}) }) , "#do_yes",
        ({ ({"n", "no", "N", "No"}) }) , "#do_no" }) );

    old_offers = ([ ]);
    stole_from_fence = ({ });

    set_wimpy(90);

} /* create() */

void reset() {
    call_out("clean_cont", 12 );
} /* reset() */

void clean_cont() {
    // Don't dest anything if we're in the middle of dealing with someone.
    if( this_offer )
        return;

    check_cont();

    INV(cont)->move("/room/rubbish");
    old_offers = ([ ]);

} /* clean_cont() */

/**
 * This method sets the speciality of the fence.
 * This can be one of the following: weapons, jewellery,
 * armour, clothing, gems or misc.
 * @param str the speciality of the fence to use
 */
void set_fence_type( string str ) { fence_type = str; }

/** @ignore yes */
int query_cost( object thing, object buyer ) {
    return thing->query_value_at(TO);
} /* query_cost() */

/** @ignore yes */
string cost_string( object thing, string place, object buyer ) {
    return MONEY_H->money_value_string( query_cost( thing, buyer ), place );
} /* cost_string() */

/**
 * This method will work out the type of object being fenced.
 * @param ob the object to test
 * @return the object type
 */
string query_item_type(object ob) {
    if( member_array("weapons", ob->query_plurals() ) != -1 )
        return "weapons";
    if( member_array("jewellery", ob->query_plurals() ) != -1 ||
        ob->query_property("shop type") == "jewellers" )
        return "jewellery";
    if( member_array("armours", ob->query_plurals() ) != -1 )
        return "armour";
    if( member_array("clothes", ob->query_plurals() ) != -1 )
        return "clothing";
    if( member_array("gems", ob->query_plurals() ) != -1 )
        return "gems";
    return "misc";
} /* query_item_type() */

/**
 * This method returns the value of an item based on
 * the client's valueing skills.
 * @param ob the object to get the value for
 * @param player the client
 * @param type the type of the object
 * @return the value of the object
 */
int judge_value( object ob, object player, string type ) {
    int value, variance, skill;

    value = query_cost( ob, TO );
    skill = player->query_skill_bonus( SKILL+( type != "" ? "."+type : "" ) ) || 1;
    variance = to_int( value / ( 1 + ( sqrt( to_float(skill) ) / 8 ) ) );

    return value + random(variance) - random(variance);

} /* judge_value() */

/**
 * This method sets the place, or the currency area this
 * fence operates in.  This is used for currency calculations.
 * @param where the place where we operate in
 */
void set_place( string where ) { add_property("place", where ); }

/**
 * This method will return the place we are in,
 * which is used in money strings etc.
 * @return the place we are in
 */
string query_place() {
    return query_property("place") || "default";
} /* query_place() */

/**
 * This method will return the money string for the given value.
 * @param amt the amount of money to get the money string for
 * @return the money string for the given amount of money
 */
string cost_str( int amt ) {
    return MONEY_H->money_value_string( amt, query_place() );
} /* cost_str() */

int scaled_value( int n ) {
    int profit;

    profit = 5 + to_int( sqrt( to_float( n / 5 ) ) );
    if( profit > MAX_PROFIT / 3 )
        profit = MAX_PROFIT / 3;

    return n * ( 100 - profit ) / 100;

} /* scaled_value() */

int do_fail( object player ) {
    whisper( player, "Well, that was a waste of time.");
    this_offer = 0;
    return 1;
} /* do_fail() */

int do_fence( object *obs ) {
    int offer, their_skill;
    float f;
    string type, skill;
    object ob, *offered, *not_speciality, *tmp;

    check_cont();

    tell_object( TP, "You ask "+the_short()+" about fencing "+
        query_multiple_short(obs)+".\n");
    tell_room( ENV(TO), TP->the_short()+" asks "+the_short()+" about fencing "+
        query_multiple_short(obs)+".\n", TP );

    if( TP->query_property(query_name()+"_killer") &&
        ( TP->query_property(query_name()+"_killer") + TIMEOUT ) < time() ) {
        do_command("peer "+TP->query_name() );
        init_command("lsay Oh sod off you!  I wouldn't buy anything from you "
            "even if I was offered a kingdom!", 1 );
        TP->add_failed_mess( TO, "" );
        return 0;
    }

    if( this_offer && this_offer->who && ENV( this_offer->who ) == ENV(TO) &&
        this_offer->offer_time > time() - 60 ) {
        whisper( TP, ( this_offer->who != TP ? "Sorry, I'm already helping "+
            (this_offer->who)->the_short()+"." : "I'm still waiting for a "
            "response from you!") );
        TP->add_succeeded_mess( TO, "", offered );
        return 1;
    }

    if( !TP->query_visible(TO) ) {
        TP->add_failed_mess( TO, "$D doesn't seem to notice you.\n", offered );
        return 0;
    }

    TP->add_succeeded_mess( TO, "", offered );

    if( member_array( TP->query_name(), stole_from_fence ) != -1 ) {
        do_command("peer "+TP->query_name() );
        init_command("lsay Piss off scumbag!", 1 );
        return 1;
    }

    if( sizeof(obs) > MAX_OBS ) {
        whisper( TP, "Sorry, I can't handle that many items at once.");
        this_offer = 0;
        return 1;
    }

    tell_room( ENV(TO), the_short()+" studies "+
        query_multiple_short( obs, "the" )+".\n");

    if( sizeof( tmp = filter( obs, (: $1->query_keep() :) ) ) ) {
        whisper( TP, "You can't sell "+strip_colours(
            query_multiple_short(tmp, "the") )+" because you are keeping "+
            ({"it","them"})[query_group(tmp)]+".");
        if( !sizeof( obs -= tmp ) )
            return do_fail(TP);
    }

    not_speciality = ({ });

    this_offer = new( class offer );
    this_offer->objects = ({ });
    this_offer->who = TP;
    this_offer->offer_time = time();

    if( sizeof( tmp = filter( obs, (: ENV($1) != this_offer->who :) ) ) ) {
        whisper( TP, "Do you think I'm blind?  I can see that you don't "
            "have "+strip_colours( query_multiple_short(tmp) )+".");
        if( !sizeof( obs -= tmp ) )
            return do_fail(TP);
    }

    if( sizeof( tmp = filter( obs, (: $1->query_property("money") :) ) ) ) {
        whisper( TP, "You can't sell money, are you daft?");
        if( !sizeof( obs -= tmp ) )
            return do_fail(TP);
    }

    if( sizeof( tmp = filter( obs, (: $1->query_worn_by() :) ) ) ) {
        whisper( TP, "I'm sorry, but you can't fence "+strip_colours(
            query_multiple_short(tmp, "the") )+" because you're wearing "+
            ({"it","them"})[query_group(tmp)]+".");
        if( !sizeof( obs -= tmp ) )
            return do_fail(TP);
    }

    if( sizeof( tmp = filter( obs, (: $1->query_wielded() :) ) ) ) {
        whisper( TP, "You can't fence "+strip_colours(
            query_multiple_short(tmp, "the") )+" because you're holding "+
            ({"it","them"})[query_group(tmp)]+".");
        if( !sizeof( obs -= tmp ) )
            return do_fail(TP);
    }

    if( sizeof( tmp = filter( obs, (: $1->do_not_sell() :) ) ) ) {
        whisper( TP, "You can't sell "+strip_colours(
            query_multiple_short(tmp, "the") )+".");
        if( !sizeof( obs -= tmp ) )
            return do_fail(TP);
    }

    if( sizeof( tmp = filter( obs, (: $1->move(cont) :) ) ) ) {
        whisper( TP, "I can't take "+strip_colours(
            query_multiple_short(tmp, "the") )+" from you for some reason, "
            "so you can't fence "+({"it","them"})[query_group(tmp)]+".");
        if( !sizeof( obs -= tmp ) )
            return do_fail(TP);
    }

    TCRE("sandoz", sprintf("%s fencing:\n%-*#s", TP->short(), 79, implode(
        map( obs, (: $1->short(0)+" ("+query_item_type($1)+")" :) ), "\n") ) );

    foreach( ob in obs ) {
      type = query_item_type(ob);

      if( !offer = judge_value( ob, TP, type ) ) {
          whisper( TP, ob->the_short()+" isn't worth anything.");
          if( !ob->move(TP) )
              whisper( TP, "So you can have it back.");
          else {
              ob->move(environment());
              whisper( TP, "So I'll just put it down here.");
          }
          continue;
      }

      // are we a fence for this type of object?
      if( type != fence_type ) {
          offer -= offer / 5;
          not_speciality += ({ ob });
      }

      // now do the profit (just like a shop)
      offer = (int)scaled_value(offer) || 1;

      if( ob->query_property("fenced") ) {
          if( ob->query_property("fenced") == (string)TP->query_name() ) {
              do_command("'Hey, that "+ob->short(0)+" is mine you scoundrel!");
              init_command("'Think I'm stupid do you?", 2 );
              init_command("'You'd better leave, and quickly!", 4 );
              stole_from_fence += ({ TP->query_name() });
              return 1;
          } else {
              do_command("'Mmm, that looks familiar.");
              do_command(":frowns in thought");
              do_command("'Oh well.");
              this_offer->amount -= ( offer * 3 ) / 4;
          }
      }

      // Remember our previous offers.
      if( old_offers[ob] )
          offer = old_offers[ob];
      else
          old_offers[ob] = offer;

      // now see if we can fleece them
      skill = SKILL + ( type != "" ? "."+type : "" );
      their_skill = TP->query_skill_bonus(skill) || 2;

      // reduce the offer dependant on their valueing skill
      f = sqrt( to_float( their_skill / 2 ) ) / 3;
      offer -= to_int( offer / ( f < 2 ? 2 : f ) );

      this_offer->amount += offer;
      this_offer->objects += ({ ob });

    }

    if( sizeof(not_speciality) )
        whisper( TP, "Well, "+strip_colours( query_multiple_short(
            not_speciality, "the" ) )+" "+({"isn","aren"})
            [query_group(not_speciality)]+"'t really my speciality.");

    if( !sizeof( this_offer->objects ) ) {
        whisper( TP, "Well, that was a waste of time.");
        this_offer = 0;
        return 1;
    }

    // Tell em how much and wait for their response
    whisper( TP, "I'll give you "+cost_str(this_offer->amount)+" for "+
        strip_colours( query_multiple_short( this_offer->objects, "the" ) )+
        ", what do you think?");
    return 1;

} /* do_fence() */

// Now they've given a response.  Either stop or take their goods
// and give them money.
void do_yes( object person ) {
    object money, *selling, ob;
    mixed m_arr;

    if( !this_offer || person != this_offer->who )
        return;

    whisper( person, "You've got a deal.");
    selling = ({ });

    foreach( ob in this_offer->objects ) {
        ob->add_property("fenced", person->query_name(), 86400 );
        selling += ({ ob });
    }

    m_arr = MONEY_H->create_money_array( this_offer->amount, query_place() );
    money = clone_object( MONEY_OBJ );
    money->set_money_array( m_arr );

    if( money->move(person) ) {
        whisper( person, "You're too heavily burdened to accept all that "
            "money, so I'll just put it "+( ENV(TO)->query_property("here") ?
            ENV(TO)->query_property("here") : "on the floor" )+".");
        money->move(ENV(TO));
    } else {
        tell_object( person, the_short()+" gives you "+
            cost_str(this_offer->amount)+".\n");
        tell_room( ENV(TO), the_short()+" gives some coins to "+
            person->the_short()+".\n", ({ person }) );
    }

    this_offer = 0;

} /* do_yes() */

void do_no( object person ) {
    object ob;

    if( !this_offer || person != this_offer->who )
        return;

    whisper( person, "Ok, have it your own way then.");

    foreach( ob in this_offer->objects )
      if( ob->move(person) )
          ob->move(ENV(TO));

    tell_object( person, the_short()+" returns "+
        query_multiple_short( this_offer->objects, "the" )+" to you.\n");
    tell_room( ENV(TO), the_short()+" returns the items to "+
        person->the_short()+".\n", person );

    this_offer = 0;

} /* do_no() */

int attack_by( object ob ) {
    object tmp;

    if( this_offer && this_offer->who && ENV(this_offer->who) == ENV(TO) &&
        this_offer->offer_time > time() - 60 ) {
        do_command("'Hey! I'm trying to do business here!");

        foreach( tmp in this_offer->objects ) {
          if( tmp->move(this_offer->who) )
              tmp->move(ENV(TO));
        }

        whisper( this_offer->who, "Hey, you'd better take these back.");
        tell_object( this_offer->who, the_short()+" returns " +
            query_multiple_short(this_offer->objects, "the")+" to you.\n");
        tell_room( ENV(TO), the_short()+" gives some items to "+
            (this_offer->who)->the_short()+".\n", ({ this_offer->who }) );
        this_offer = 0;
    }

    return ::attack_by(ob);

} /* attack_by() */

void event_exit( object ob, string message, object to ) {
    object tmp;

    if( ob && ob == cont )
        ob->remove_property("nosteal");

    if( ob && this_offer && this_offer->who && this_offer->who == ob &&
        ENV(ob) == ENV(TO) ) {
        foreach( tmp in this_offer->objects ) {
          if( tmp->move(this_offer->who) )
              tmp->move(ENV(TO));
        }
        whisper( this_offer->who, "You might want to take these back before "
            "you go.");
        tell_object( this_offer->who, the_short()+" returns " +
            query_multiple_short(this_offer->objects, "the")+" to you.\n");
        tell_room( ENV(TO), the_short()+" returns some items to "+
            (this_offer->who)->the_short()+".\n", ({ this_offer->who }) );
        this_offer = 0;
    }

    return ::event_exit( ob, message, to );

} /* event_exit() */

void init() {
    ::init();
    TP->add_command("fence", TO,
        "<indirect:object:me> to <direct:object'person'>",
        (: do_fence($1) :) );
} /* init() */