/**
* 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 );
}