/** * Auction Room Inheritable * This room will give you everything you need to make an auction room * @author Terano * @started 3 October, 1998 */ #include <money.h> #include <move_failures.h> #define SAVEPATH location #define CASE "/obj/misc/case" inherit "/std/room/basic_room"; inherit "/global/auto_load"; class lot_details { string seller; mixed *current_bid; int expiry_time; mapping all_bids; } mapping lots = ([ ]); //Stored as ([ "lot id": ({ auto_loading string, lot_details }), ]) mapping payments = ([ ]); //Stored as ([ "name": amount ]) nosave string currency = "default"; nosave string location; nosave string *case_desc = ({ }); nosave object *cases = ({ }); nosave int admin_cost = 2000; //Defaults to $5 AM nosave float commission = (5/100); //Defaults to 5% int do_deposit( object *things, int auction_time, string time_type ); int do_bid( string offer, object *boxs ); int do_collect( object *boxs, string pattern ); void save_file(); void load_file(); void load_inv(); void set_location( string loc ); void set_currency( string cur ); void set_admin_cost( int value ); void set_commission( int percent ); void set_case_desc( string *bits ); void adjust_money( int amount, object player ); void create() { do_setup++; ::create(); do_setup--; if ( !do_setup ) { this_object()->setup(); this_object()->reset(); } call_out( "load_file", 2 ); //To give time for location data to be restored call_out( "load_inv", 4 ); //To give time for save data to be restored } void init() { this_player()->add_command( "bid", this_object(),"<string> on <indirect:object:here>", (: do_bid( $4[0], $1 ) :) ); this_player()->add_command( "collect", this_object(), ({ "<indirect:object:here>", "money" }), (: do_collect( $1, $5 ) :) ); this_player()->add_command( "deposit", this_object(), "<indirect:object> for <number>" " {minute|hour|day} auction", (: do_deposit( $1, $4[1], $4[2] ) :) ); } int do_deposit( object *things, int auction_time, string time_type ) { object *auctioned = ({ }); object *unauctionable = ({ }); object box; class lot_details temp; int finishtime; if ( auction_time < 0 ) { add_failed_mess( this_object(), "That's not a valid length.\n" ); return 0; } switch( time_type ) { case "minute": finishtime = time() + ( auction_time * 60 ); break; case "hour": finishtime = time() + ( auction_time * 60 * 60 ); break; case "day": finishtime = time() + ( auction_time * 60 * 60 * 24 ); break; default: return 0; } box = clone_object( CASE ); auctioned = filter_array( things, (: $1->move( $(box) ) == MOVE_OK :) ); unauctionable = things - auctioned; if ( sizeof( unauctionable ) ) { auctioned->move( this_player() ); this_player()->add_failed_mess( this_object(), "You can't $V $I.\n", unauctionable ); return 0; } box->add_property( "lot_code", finishtime ); temp = new( class lot_details, seller: this_player()->query_name(), current_bid: allocate(2), expiry_time: finishtime, all_bids: ([ ]) ); lots[ finishtime ] = ({ create_auto_load( ({ box }), 0 ), temp }); box->move( this_object() ); box->add_extra_look( this_object() ); box->add_property("there", "against a wall"); if ( sizeof( case_desc) ) box->setup_case( case_desc ); save_file(); this_player()->add_succeeded_mess( this_object(), "$N $V $I for "+ add_a( query_num( auction_time, 5000 ) ) + " " + time_type + " auction.\n", auctioned ); return 1; } int do_bid( string offer, object *boxs ) { object box; int value, lot_number; class lot_details current_lot; if ( sizeof( boxs ) > 1 ) { this_player()->add_failed_mess( this_object(), "You can only $V on one case at " "a time.\n" ); return 0; } box = boxs[0]; lot_number = box->query_property( "lot_code" ); if ( undefinedp( lots[ lot_number ] ) ) return 0; if (time() > lot_number ) { this_player()->add_failed_mess( this_object(), "The bidding on this " "item is finished.\n" ); return 0; } current_lot = lots[ lot_number ][1]; value = MONEY_HAND->value_from_string( offer, currency ); if ( this_player()->query_value_in( currency ) < value ) { this_player()->add_failed_mess( "You don't have that much.\n" ); return 0; } if ( sizeof( current_lot->current_bid ) && current_lot->current_bid[1] > value ) { this_player()->add_failed_mess( this_object(), "Someone else has already bid more then that.\n"); return 0; } current_lot->all_bids[ this_player()->query_name() ] = value; current_lot->current_bid[0] = this_player()->query_name(); current_lot->current_bid[1] = value; this_player()->add_succeeded_mess(this_object(), "$N $V "+ offer +" for "+ query_multiple_short( all_inventory( box ) ) +".\n" ); save_file(); return 1; } int do_collect( object *boxs, string pattern) { int amount; object box, *collected, *things; int lotid; class lot_details temp; if ( pattern == "money" ) { if ( undefinedp( payments[ this_player()->query_name() ] ) ) { this_player()->add_failed_mess( this_object(), "You aren't owed any money!\n" ); return 0; } amount = payments[ this_player()->query_name() ]; adjust_money( amount - ( amount * commission ), this_player() ); printf( "You recieve %s, minus %s comission.\n", MONEY_HAND->money_value_string( amount, currency ), MONEY_HAND->money_value_string( (amount/20), currency ) ); map_delete( payments, this_player()->query_name() ); this_player()->add_succeeded_mess( this_object(), "$N $V some money from $D.\n" ); save_file(); return 1; } if ( sizeof( boxs ) > 1 ) { this_player()->add_failed_mess( this_object(), "You can only $V one case at " "a time.\n" ); return 0; } box = boxs[0]; things = all_inventory( box ); lotid = box->query_property( "lot_code" ); if ( undefinedp( lots[ lotid ] ) ) return notify_fail( "Something screwed up, please bug rep this room.\n" ); temp = lots[ lotid ][1]; if ( lotid > time() ) { this_player()->add_failed_mess( this_object(), "The auction isn't over yet.\n" ); return 0; } if ( sizeof( temp->current_bid ) && temp->current_bid[0] != this_player()->query_name() ) { this_player()->add_failed_mess( this_object(), "You aren't entitled to this lot!\n"); return 0; } if ( !sizeof( temp->current_bid ) ) { //No bidders if ( this_player()->query_name() != temp->seller ) { this_player()->add_failed_mess( this_object(), "You aren't entitled to this lot!\n"); return 0; } adjust_money( -admin_cost, this_player() ); collected = filter_array( things, (: $1->move( this_player(), "$N is given to you." ) == MOVE_OK :) ); if ( sizeof( things - collected ) ) { write( "However you can't carry "+ query_multiple_short( things - collected ) +" and it is put on the ground instead.\n" ); ( things - collected )->move( this_object() ); } this_player()->add_succeeded_mess( this_object(), "$N pays the administration " "fee and $V $I.\n", things ); box->move( "/room/rubbish" ); map_delete( lots, lotid ); save_file(); return 1; } amount = temp->current_bid[1]; if ( this_player()->query_value_in( currency ) < amount ) { this_player()->add_failed_mess( this_object(), "It will cost you "+ MONEY_HAND->money_value_string( amount, currency ) +" to collect " "your items.\n" ); return 0; } adjust_money( -amount, this_player() ); collected = filter_array( things, (: $1->move( this_player(), "$N is given to you." ) == MOVE_OK :) ); if ( sizeof( things - collected ) ) { write( "However you can't carry "+ query_multiple_short( things - collected ) +" and it is put on the ground instead.\n" ); ( things - collected )->move( this_object() ); } this_player()->add_succeeded_mess( this_object(), "$N pays the bid " "and $V $I.\n", things ); if (!undefinedp( payments[ temp->seller ] ) ) payments[ temp->seller ] += amount; else payments[ temp->seller ] = amount; box->move( "/room/rubbish" ); map_delete( lots, lotid ); save_file(); return 1; } void load_file() { if ( !stringp( location ) ) return; if ( file_size( SAVEPATH +".o" ) < 0 ) return; unguarded( (: restore_object, SAVEPATH :) ); return; } void save_file() { if ( !stringp( location ) ) return; unguarded( (: save_object, SAVEPATH :) ); return; } string extra_look( object ob ) { class lot_details temp; mixed bing; string ret; if ( ob == this_object() && query_auto_loading() ) return "Cases are being wheeled into the room.\n"; if ( ob->query_name() != "case" ) return ""; if ( undefinedp( lots[ ob->query_property( "lot_code" ) ] ) ) return ""; temp = lots[ ob->query_property( "lot_code" ) ][1]; bing = temp->current_bid; if ( !stringp( bing[0] ) ) ret = "No bid as of yet.\n"; else ret = "The current bid is "+ MONEY_HAND->money_value_string( bing[1], currency ) +".\n"; return ret + "The bidding on this lot stops at "+ mudtime( ob->query_property( "lot_code" ) ); } void load_inv() { mixed key; mixed data; if ( !sizeof( lots ) ) return; foreach( key,data in lots ) { cases += load_auto_load_to_array( data[0], this_player() ); } call_out( (: cases->add_extra_look( this_object() ) :), 10 ); call_out( (: cases->move( this_object() ) :), 10 ); } void dest_me() { save_file(); if ( sizeof( cases ) ) cases->dest_me(); ::dest_me(); } void set_save_path( string path ) { location = loc; } void set_currency( string cur ) { currency = cur; } void set_admin_cost( int value ) { admin_cost = value; } void set_commission( int percent ) { commission = percent/100; } void set_case_desc( string *bits ) { case_desc = bits; } mapping query_lots() { return lots; } mapping query_payments() { return payments; } void adjust_money( int amount, object player ) { object money; if ( amount < 0 ) { //Taking money player->pay_money( MONEY_HAND->create_money_array( amount, currency ), currency ); return; } money = MONEY_HAND->create_money_array( amount, currency ); player->adjust_money( money, currency ); }