/** * This inherit is under development. Use at your own risk. * All bug reports to me, please. * * This is an inherit for pawn shops, which buy your items from you, but also * keep them for a short period of time for you to buy them back, before they * go into the shop's general inventory. * * It is built around the general store inherit /std/shop. * * @creator Vashti * @started 21st September 2002 */ #include <money.h> #include <move_failures.h> #define RECEIPT "/obj/misc/pawn_receipt" #define TO this_object() #define TP this_player() inherit "/std/shop" ; private int _pawn_ttl ; private mixed _pawn_mess ; private int _pawn_markup ; private string _shop_language; /** * This sets the language that the shop will use for receipts. * @param lang The language to write receipts in. */ void set_language( string lang ) { _shop_language = lang; } /* set_language */ /** * This returns the language that the shop is using for receipts. * @return [string] The language receipts are written in. */ string query_language() { return _shop_language; } /* query_language */ /** * This sets the percentage that the shop will mark reclaim prices up by. * The default is 20%. * @param percent The percentage to add to reclaim prices. */ void set_pawn_markup( int percent ) { _pawn_markup = percent ; } /* set_pawn_markup */ /** * This returns the percentage that the shop will mark reclaim prices up by. * @return [int] The percentage to add to reclaim prices. */ int query_pawn_markup() { return _pawn_markup ; } /* query_pawn_markup */ /** * This sets the time to live of pawned items, in seconds. That is, the * length of time between an item being pawned and the shop selling that * item to recoup its costs. The default is one week realtime. * @param ttl The time in seconds before the shop will sell a pawned item. */ void set_pawn_ttl( int ttl ) { _pawn_ttl = ttl ; } /* set_pawn_ttl */ /** * This returns the time to live of pawned items, in seconds. That is, the * length of time between an item's being pawned and the shop selling that * item to recoup its costs. * @return [int] The time in seconds before the shop will sell a pawned item. */ int query_pawn_ttl() { return _pawn_ttl ; } /* query_pawn_ttl */ /** * This sets the message given out when somebody pawns something. * @param mess The message given when something is successfully pawned. */ void set_pawn_mess( mixed mess ) { _pawn_mess = mess ; } /* set_pawn_mess */ /** * This returns the message given out when somebody pawns something. * @return [string] The message given when something is successfully pawned. */ string query_pawn_mess() { return _pawn_mess ; } /* query_pawn_mess */ /** @ignore yes */ void create() { do_setup++ ; ::create() ; do_setup-- ; add_help_file( "pawn_shop" ) ; remove_help_file( "shop" ); _pawn_mess = ({ "You pawn $ob$ for $money$.\n", "$client$ pawns $ob$.\n" }) ; _pawn_markup = 20 ; /* 20% */ _pawn_ttl = 7 * 24 * 60 * 60 ; /* 1 Roundworld week */ _shop_language = "morporkian" ; set_min_amount( 400 ) ; /* A$1 ; 4 silver coins */ add_property( "no steal", 1 ) ; /* You can't just steal your item back */ if ( ! do_setup ) { TO->setup() ; TO->reset() ; } } /* create */ /** @ignore yes */ void init() { ::init() ; add_command( "pawn", "<indirect:object:me'items'>" ) ; } /* init */ /** * This handles pawning items to the shop. */ int do_pawn( object *in_obs ) { int value, total ; mixed *m_array ; object ob, money, receipt ; object *cheap, *cre, *expensive, *kept, *nobuy, *stolen, *worn ; string place, fn ; string *text = ({ }) ; /* Make sure the shop is open for business */ if ( ! is_open( TP, 0 ) ) { return 0 ; } in_obs = uniq_array( in_obs ) ; /* Check for cre-only items */ cre = filter( in_obs, (: creator_object($1) :) ) ; if ( sizeof(cre) ) { if ( ! TP->query_creator() ) { tell_object( TP, "Oh dear, you shouldn't have " + query_multiple_short( cre ) + "! " + ( sizeof(cre) > 1 ? "They disappear" : "It disappears" ) + " with a flash of octarine light.\n" ) ; cre->move( "/room/rubbish" ) ; } else { tell_object( TP, "You decide not to pawn " + query_multiple_short( cre ) + ", as " + ( sizeof(cre) > 1 ? "they are creator-only items" : "it is a creator-only item" ) + ".\n" ) ; } foreach( ob in cre ) { if ( fn = ob->query_property( "virtual name" ) ) { fn = ob->query_property( "virtual name" ) ; } else { fn = base_name( ob ) ; } text += ({ fn }) ; } log_file( "ILLEGAL_OBJECT", "%s: %s tried to pawn %s at %s.\n\n", ctime(time()), TP->query_name(), query_multiple_short( text ), file_name( TO ) ) ; in_obs -= cre ; } /* Check for kept items */ kept = filter_array( in_obs, (: $1->query_keep() :) ) ; if ( sizeof(kept) ) { tell_object( TP, "You decide not to pawn " + query_multiple_short( kept ) + ", as you are keeping " + ( sizeof(kept) > 1 ? "them" : "it" ) + ".\n" ) ; in_obs -= kept ; } /* Check for held or worn items */ worn = filter( in_obs, (: $1->query_holder() || $1->query_worn_by() :) ) ; if ( sizeof(worn) ) { tell_object( TP, "You decide not to pawn " + query_multiple_short( worn ) + ", because you are wearing or " "holding " + ( sizeof(worn) > 1 ? "them" : "it" ) + ".\n" ) ; in_obs -= worn ; } /* Reject stolen items. */ stolen = filter( in_obs, (: $1->query_property( "stolen" ) :) ) ; if ( sizeof(stolen) ) { tell_object( TP, "You cannot pawn " + query_multiple_short( stolen ) + " because " + ( sizeof(stolen) > 1 ? "they're" : "it's" ) + " stolen!\n" ) ; in_obs -= stolen ; } /* Check for items that can't be sold, or that we don't buy */ nobuy = filter( in_obs, (: $1->do_not_sell() || TO->do_not_buy($1) :) ) ; if ( sizeof( nobuy ) ) { tell_object( TP, "You cannot pawn " + query_multiple_short( nobuy ) + ".\n" ) ; in_obs -= nobuy ; } /* Check for items that are too cheap */ cheap = filter( in_obs, (: $1->query_value() < TO->query_min_amount() :) ) ; if ( sizeof(cheap) ) { tell_object( TP, "You cannot pawn " + query_multiple_short( cheap ) + " as " + ( sizeof(cheap) > 1 ? "they are" : "it is" ) + " not expensive enough.\n" ) ; in_obs -= cheap ; } /* Check for items that are too expensive */ expensive = filter( in_obs, (: $1->query_value() > TO->query_max_amount() :) ) ; if ( sizeof(expensive) ) { tell_object( TP, "You cannot pawn " + query_multiple_short( expensive ) + " as " + ( sizeof(expensive) > 1 ? "they are" : "it is" ) + " too expensive.\n" ) ; in_obs -= expensive ; } /* Make sure we have something left to pawn after all that */ if ( ! sizeof( in_obs ) ) { add_failed_mess( "You have nothing to pawn.\n" ) ; return 0 ; } /* Okay, we've passed all the checks. * Let's do some pawning. */ /* Prepare for the sale - tally up how much money we have to give them, * give them the receipt(s), then zap the originals. */ foreach( ob in in_obs ) { /* To get the value of the item, we use the same procedure as general * stores do for items that they don't specialise in. This is so that * it doesn't become more worthwhile to pawn an object than to take it * to a general store. */ value = scaled_value( ob->query_value() ) ; value = ( value * 90 ) / 100; total += value ; receipt = clone_object( RECEIPT ) ; if ( ! receipt ) { add_failed_mess( "Oh dear, something went very wrong (can't clone receipt object). " "Please bugrep this room.\n" ) ; return 0 ; } receipt->setup_receipt( ob ) ; receipt->set_shop_path( TO ) ; receipt->set_item_value( value ) ; receipt->set_expiry_time( time() + query_pawn_ttl() ) ; receipt->setup_read_mess( _shop_language ); receipt->move( TP ) ; ob->move( "/room/rubbish" ) ; } /* Get the currency in use */ place = query_property( "place" ) ; if ( ! place || ( place == "" ) ) { place = "default" ; } /* Transfer some money to the mark^Wpawner */ m_array = MONEY_HAND->create_money_array(total, place); money = clone_object(MONEY_OBJECT); if ( ! money ) { add_failed_mess( "Oh dear, something went very wrong (can't clone money object). " "Please bugrep this room.\n" ) ; return 0 ; } money->set_money_array(m_array); if ( money->move( TP ) != MOVE_OK ) { tell_object( TP, "You're too heavily burdened to accept all that money, so the " "shopkeeper puts it on the floor.\n" ) ; money->move( TO ) ; } do_parse( _pawn_mess, in_obs, TP, MONEY_HAND->money_string( m_array ), "" ) ; return 1 ; } /* do_pawn */ /** @ignore yes * Pawn shops don't just buy things. */ int do_sell( object *in_obs ) { add_failed_mess( "If you just want to sell items, you'll need to find a general " "store. Pawn shops are for pawning in.\n" ) ; return 0 ; } /* do_buy */