/* * This is a pawned item receipt. * It can be turned back into its item if reclaimed at a pawn shop. * Based heavily on /obj/misc/al_receipt.c * * Vashti 22nd September 2002 */ #include <am_time.h> #include <armoury.h> #include <money.h> #include <move_failures.h> #include <player.h> #include <virtual.h> #define TO this_object() #define TP this_player() inherit "/obj/misc/paper" ; private int _expired ; private int _expired_sold ; private int _expiry_time ; private int _item_value, _obplural ; private int _timestamp; private mixed _static_save; private string _obname, _obpath, _obshort ; private string _shop_path, _virt_name ; object do_kiss(); /** @ignore yes */ void setup() { set_name( "receipt" ); set_short( "pawned item receipt" ) ; add_adjective( ({ "pawned", "item" }) ); set_long( "This is a small slip of paper, with a black border.\n" ); set_main_plural( "pawned item receipts" ) ; add_plural( "receipts" ); add_adjective( "pawned" ) ; set_value( 0 ) ; set_weight( 1 ); _obname = "unknown object"; _obpath = "***"; _timestamp = time(); } /* setup */ /** @ignore yes */ void init() { add_command( "reclaim", "<direct:object:me'receipt'>" ) ; } /* init */ /** @ignore yes */ void reset() { object item ; if ( ( ! _expired ) && time() > _expiry_time ) { _expired = 1 ; set_short( "expired pawned item receipt" ) ; add_adjective( "expired" ) ; if ( ! _expired_sold ) { _expired_sold = 1 ; item = do_kiss() ; if ( item ) { item->move( _shop_path->query_store_room() ) ; } } } } /* reset */ /** * This sets the short of the pawned object. */ void set_obshort( string s ) { _obshort = s; } /* set_obshort */ /** * This returns the short of the pawned object. * @return [string] The short of the pawned object. */ string query_obshort() { return _obshort; } /* query_obshort */ /** * This sets the time at which this receipt will die. * @param time The time in seconds when this receipt will be killed. */ void set_expiry_time( int time ) { _expiry_time = time ; } /* set_expiry_time */ /** * This returns the Unix time in seconds at which this receipt will expire. * @return [int] The time of death in seconds. */ int query_expiry_time() { return _expiry_time ; } /* query_expiry_time */ /** * This sets the value of the item this receipt is based on. * @param value The value of the original item. */ void set_item_value( int value ) { _item_value = value ; } /* set_item_value */ /** * This returns the value of the item this receipt was based on. * @return [int] the value of the original item. */ int query_item_value() { return _item_value ; } /* query_item_value */ /** * This allows us to set the path of the shop that spawned us, so that this * receipt can only be redeemed at that shop. * @param shop - either a shop object or a string path. */ void set_shop_path( mixed shop ) { if ( objectp( shop ) ) { _shop_path = base_name( shop ) ; return ; } _shop_path = shop ; return ; } /* set_shop_path */ /** * This returns the path to the shop that this receipt was spawned by. * @return [string] the path to the cloning shop. */ string query_shop_path() { return _shop_path ; } /* query_shop_path */ /** * Sets the name of the object. This will be used so the item recipt * can be identified. * @param name the object name */ void set_obname( string name ) { _obname = name; } /* set_obname */ /** * Sets the path to the object. The path of the object for the recipt to * work with. * @param path the object path */ void set_object( string path ) { _obpath = path; } /* set_object */ /** * This method sets the virtual object name of the item. * @param name the virtual object name */ void set_virtobname( string name ) { _virt_name = name; } /* set_virtobname */ /** * This method returns the name of the object. * @return the name of the object */ string query_obname() { return _obname; } /* query_obname */ /** * This method returns the path of the object. * @return the path of the object */ string query_obpath() { return _obpath; } /* query_obpath */ /** * This method returns the timestamp of the reciept. This is the time the * receipt was created. * @return the timestamp */ int query_timestamp() { return _timestamp; } /* query_timestamp */ /** * This method returns the virtual object path name of the item. * @return the virtual object name */ string query_virt_obname() { return _virt_name; } /* query_virt_obname */ /** * This method returns the save information for the object. THis is not * just the static save information, it is an array of two elements. The * first is the static save information and the second is the dynamic * save information. * @return the save information */ mixed query_static_save() { return _static_save; } /* query_static_save */ /** * This allows us to check if the object is a pawned item receipt. * @return 1 if the object is a pawned item receipt. */ int query_pawned_item_receipt() { return 1 ; } /* query_pawned_item_receipt */ /** * This method sets the save information for the file. It actually sets * both the static and dynamic information. This assumes it is passed * an array of two elements, the first is the static save information and * the second is the dynamic save information. * @param args the data as defined above */ void set_static_save( mixed args ) { mixed p; _static_save = args; if (_obname != "unknown object") { return; } // Try to find the short in here somewhere p = args[0]; while (mapp(p)) { if (!undefinedp(p["short"])) { _obname = p["short"]; return; } p = p["::"]; } } /** * This sets whether or not our object is actually a collective, * and so more than one object. */ void set_object_plural( object ob ) { if ( ob->query_collective() && ob->query_amount() > 1 ) { _obplural = 1; } else { _obplural = 0; } } /* set_plural */ /** * This lets us check whether or not our object is a plural object. */ int query_object_plural() { return _obplural; } /* query_plural */ /** * This returns a short which is accurate for both ordinary and * collective objects. */ string query_correct_short( object ob ) { if ( ! ob ) { return 0; } set_object_plural( ob ); if ( _obplural ) { return pluralize( ob->query_short() ); } return ob->query_short(); } /* query_correct_short */ /** * This method sets up the receipt for the specified object. * @param ob the object to setup the reciept for */ void setup_receipt( object ob ) { mixed* bits; bits = AUTO_LOAD_OB->fragile_auto_str_ob(ob); set_obname(ob->query_name()); set_obshort( query_correct_short( ob ) ); set_object(bits[1]); set_static_save(bits[2]); } /* setup_receipt() */ /** * This takes a sentence and pluralises it appropriately. * @parma text The sentence to pluralise. * @param plural Whether or not the sentence should be in plural form. */ string pluralize_sentence( string text, int plural ) { if ( plural ) { return replace( text, ({ "$o", "them", "$r", "they", "$ve", "ve" }) ); } return replace( text, ({ "$o", "it", "$r", "it", "$ve", "s" }) ); } /* pluralize_sentence */ /** @ignore yes */ string query_details() { if ( _expired ) { return pluralize_sentence( "This is a receipt for your pawned " + query_obshort() + ".\n" "Sadly, you have left it too long to collect $o and $r ha$ve " "expired, so the shop will put $o up for sale. Better hurry to " + _shop_path->the_short() + " sharpish and try to buy $o back!", _obplural ); } return pluralize_sentence( "This is a receipt for your pawned " + query_obshort() + ".\n" "You must reclaim $o from " + _shop_path->the_short() + " before " + AM_TIME_HANDLER->query_am_time( _expiry_time ) + " or $r will " "be sold.", _obplural ); } /** * This sets up a message for us to get when we read the receipt. * Because we're using a function pointer, add_read_mess doesn't work. * @param lang The language to produce the message in. */ mixed *query_read_mess() { string lang; if ( _shop_path ) { lang = _shop_path->query_language(); } else { lang = "general"; } return ::query_read_mess() + ({ ({ (: query_details() :), "neat printing", lang, 0 }) }); } /* query_read_mess */ /** @ignore yes */ mapping query_dynamic_auto_load() { return ([ "::" : ::query_dynamic_auto_load(), "obname" : _obname, "obpath" : _obpath, "obvalue" : value, "virt" : _virt_name, "timestamp" : _timestamp, "static" : _static_save, "been sold" : _expired_sold, "expired" : _expired, "expires on" : _expiry_time, "item value" : _item_value, "item short" : _obshort, "item plural": _obplural, "shop path" : _shop_path ]); } /* query_dynamic_auto_load() */ /** @ignore yes */ void init_dynamic_arg(mapping arg, object) { _obname = arg["obname"]; if ( stringp( _obname ) ) { add_adjective( explode( lower_case( _obname ), " " ) ); } _obpath = arg["obpath"]; set_value(arg["obvalue"]); _virt_name = arg["virt"]; _timestamp = arg["timestamp"]; _static_save = arg["static"]; _expired = arg["expired"] ; _expired_sold = arg["been sold"] ; _expiry_time = arg["expires on"] ; _item_value = arg["item value"] ; _obshort = arg["item short"]; _obplural = arg["item plural"]; _shop_path = arg["shop path"] ; ::init_dynamic_arg(arg["::"]); if ( _expired ) { set_short( "expired pawned item receipt" ) ; add_adjective( "expired" ) ; set_main_plural( "expired pawned item receipts" ) ; add_plural( "pawned item receipts" ) ; } } /** @ignore yes */ mixed *stats() { mixed *stuff; stuff = ::stats() + ({ ({ "obname", _obname }), ({ "obpath", _obpath }), ({ "timestamp", _timestamp + " (" + ctime(_timestamp) + ")" }), ({ "been sold", _expired_sold }), ({ "expired", _expired }), ({ "expires on", _expiry_time }), ({ "item short", _obshort }), ({ "item value", _item_value }), ({ "item plural", _obplural }), ({ "shop path", _shop_path }) }); if (_virt_name) stuff += ({ ({ "virtname", _virt_name }) }); return stuff; } /* stats */ /** @ignore yes */ object do_kiss() { object thing; if (sizeof(_static_save) < 2) { if (this_player()->query_creator()) { write("This receipt has no auto-load information, possibly " "because the object was broken when the player logged " "out. It will have to be replaced by hand.\n"); } else { write("Sorry, but this object is too broken to repair " "with a kiss. You'll have to contact a creator.\n"); } return 0; } // If we have virtual names, try and fiddle with this. if (_virt_name) { _virt_name = CLONER->other_file( _virt_name ); if (file_size(_virt_name) <= 0) { // try and rewrite through the armoury _virt_name = ARMOURY->remap_file_path(_virt_name); } if (file_size(_virt_name) <= 0) { write("The receipt whispers: Sorry, I'm still broken. " "Try again some other time, or contact a creator.\n"); return 0; } } if ( !catch( thing = (object)CLONER->clone( _obpath ) ) ) { if ( thing ) { thing->init_static_arg(_static_save[0]); thing->init_dynamic_arg(_static_save[1]); thing->add_property(VIRTUAL_NAME_PROP, _virt_name); move("/room/rubbish"); return thing; } else { write("The receipt whispers: I'm going to need some " "creator help.\n"); thing->dest_me(); } } else { write("The receipt whispers: Sorry, I'm still broken. " "Try again some other time, or contact a creator.\n"); } return 0; } /* do_kiss() */ /** * This handles all the reclaiming of objects that have been pawned. */ int do_reclaim() { int cost, i ; object change, item ; string change_str, place ; /* Make sure we're a pawned item receipt */ if ( ! query_pawned_item_receipt() ) { add_failed_mess( "$D is not a pawned item receipt.\n" ) ; return 0 ; } /* Make sure we're in the right place */ if ( base_name( environment( TP ) ) != _shop_path ) { add_failed_mess( "This is not the right place for you to reclaim $D. " "Try a pawn shop.\n" ) ; return 0 ; } /* Make sure that place is open for business */ if ( ! environment( TP )->is_open( TP, 0 ) ) { return 0; } /* Make sure the receipt hasn't expired */ if ( _expired ) { add_failed_mess( "Oh dear, your receipt has expired. With luck, your " + query_obshort() + " will be available for sale in the shop.\n" ) ; return 0 ; } /* Do the money transfer thing */ place = query_property( "place" ) ; if ( ! place || ( place == "" ) ) { place = "default" ; } cost = ( ( 100 + _shop_path->query_pawn_markup() ) * _item_value ) / 100 ; debug_printf( "cost = %d, _item_value = %d, markup = %d", cost, _item_value, _shop_path->query_pawn_markup() ) ; if ( TP->query_value_in( place ) < cost ) { add_failed_mess( "You don't have enough money to reclaim $D. " "It would cost you " + MONEY_HAND->money_value_string( cost, place ) + "\n" ) ; return 0 ; } change = MONEY_HAND->pay_amount_from( cost, TP, place ) ; if ( change ) { change->move( TP ) ; change_str = change->short() ; } /* Make the receipt back into what it should be */ item = do_kiss(); if ( ! item ) { add_failed_mess( "Oh dear, your item doesn't seem to be here any more. " "Please contact a liaison.\n" ); return 0; } i = item->move( TP ); if ( i != MOVE_OK ) { tell_object( TP, "You're too heavily burdened to accept " + item->the_short() + ", so it is placed on the floor for you.\n" ); item->move( environment(TP) ); } add_succeeded_mess( ({ "$N $V " + item->the_short() + " for " + MONEY_HAND->money_value_string( cost, place ) + ( change_str ? " and receive " + change_str + " in change" : "" ) + ".\n", "$N $V $D and receives " + item->the_short() + " in exchange.\n" }) ) ; return 1 ; } /* do_reclaim */