/***************************************************************************
* This file contains auction code developed by Brian Babey, and any *
* communication regarding it should be sent to [bbabey@iname.com] *
* Web Address: http://www.erols.com/bribe/ *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
/***************************************************************************
* ROM 2.4 is copyright 1993-1995 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@pacinfo.com) *
* Gabrielle Taylor (gtaylor@pacinfo.com) *
* Brian Moore (rom@rom.efn.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
***************************************************************************/
/***************************************************************************
* Asgardian Nightmare is copyright 1998-2001 Chris Langlois/Gabe Volker *
***************************************************************************/
#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include "merc.h"
DECLARE_DO_FUN( do_auction );
void show_obj_stats( CHAR_DATA *ch, OBJ_DATA *obj );
void auction_channel( char * msg );
/* Syntax: Auction <Item> <Minbid> */
void do_auction( CHAR_DATA *ch, char * argument )
{
long silver=0, gold=0, platinum=0, money=0, minbid=0, maxbid=0;
OBJ_DATA * obj;
char arg1[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH];
char arg2[MAX_INPUT_LENGTH];
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( ch == NULL || IS_NPC(ch) )
return;
if ((ch->in_room->vnum == ROOM_VNUM_CORNER)
&& (!IS_IMMORTAL (ch)))
{
send_to_char ("Just keep your nose in the corner like a good little player.\n\r", ch);
return;
}
if ( arg1[0] == '\0')
{
if ( IS_SET(ch->comm,COMM_NOAUCTION) )
{
REMOVE_BIT(ch->comm,COMM_NOAUCTION );
send_to_char("Auction channel is now ON.\n\r",ch);
return;
}
SET_BIT(ch->comm,COMM_NOAUCTION);
send_to_char("Auction channel is now OFF.\n\r",ch);
return;
}
if ( !str_cmp( arg1, "info" ) )
{
obj = auction_info.item;
if ( !obj )
{
send_to_char("There is nothing up for auction right now.\n\r",ch);
return;
}
if ( auction_info.owner == ch )
{
sprintf( buf, "\n\rYou are currently auctioning %s.\n\r",
obj->short_descr );
send_to_char( buf, ch );
return;
}
else
show_obj_stats( ch, obj );
return;
}
/* No Clan items, or corpses */
if( !str_cmp( arg1, "confiscate" ) )
{
obj = auction_info.item;
if(!IS_IMMORTAL(ch))
{
send_to_char("Huh?\n\r",ch);
return;
}
if ( !obj )
{
send_to_char("There is nothing up for auction right now.\n\r",ch);
return;
}
/* Now take the object */
sprintf(buf, "%s - item confiscated by the immortals.\n\r", auction_info.item->short_descr);
auction_channel( buf );
obj_to_char( auction_info.item, ch );
sprintf(buf, "%s has been confiscated from %s.\n\r", capitalize(auction_info.item->short_descr), auction_info.owner->name );
send_to_char( buf, ch );
auction_info.item = NULL;
auction_info.owner = NULL;
auction_info.current_bid = 0;
auction_info.status = 0;
return;
}
if ( !str_cmp( arg1, "bid" ) )
{
long bid;
obj = auction_info.item;
if ( !obj )
{
send_to_char("There is nothing up for auction right now.\n\r",ch);
return;
}
if ( arg2[0] == '\0' )
{
send_to_char("You must enter an amount to bid.\n\r",ch);
return;
}
bid = atol( arg2 );
if ( bid <= (auction_info.current_bid/10)+auction_info.current_bid)
{
sprintf(buf, "You must bid at least 10%% higher than the current bid. Bid at least %ld silver.\n\r",
((auction_info.current_bid/10)+auction_info.current_bid+1));
return;
}
if ( bid < auction_info.minbid )
{
sprintf( buf, "The minimum bid is %ld silver.\n\r",auction_info.minbid);
send_to_char(buf,ch);
return;
}
if ( (ch->silver + 100 * ch->gold + 10000 * ch->platinum) < bid )
{
send_to_char("You can't cover that bid.\n\r",ch);
return;
}
sprintf(buf, "%ld silver has been offered for %s.\n\r",
bid, auction_info.item->short_descr);
auction_channel( buf );
if ( auction_info.high_bidder != NULL )
{
auction_info.high_bidder->gold += auction_info.gold_held;
auction_info.high_bidder->silver += auction_info.silver_held;
auction_info.high_bidder->platinum += auction_info.platinum_held;
}
silver = UMIN( ch->silver, bid );
money = ((ch->platinum*10000)+(ch->gold*100)+(ch->silver));
money -= bid;
if (money > 9999)
platinum = money / 10000;
else
platinum = 0;
money -= (platinum*10000);
if (money > 99)
gold = money / 100;
else
gold = 0;
money -= (gold*100);
silver = money;
ch->platinum = platinum;
ch->gold = gold;
ch->silver = silver;
platinum = bid / 10000;
auction_info.platinum_held = platinum;
gold = (bid - (platinum*10000))/100;
auction_info.gold_held = gold;
silver = ((bid - (platinum*10000))-(gold*100));
auction_info.silver_held = silver;
auction_info.high_bidder = ch;
auction_info.current_bid = bid;
auction_info.status = 0;
return;
}
if ( auction_info.item != NULL )
{
send_to_char("There is already another item up for bid.\n\r",ch);
return;
}
if ( (obj = get_obj_carry( ch, arg1)) == NULL )
{
send_to_char("You aren't carrying that item.\n\r",ch);
return;
}
// Cases where the Object is Invalid
if ( IS_OBJ_STAT( obj, ITEM_NODROP ) )
{
send_to_char("You can't let go of that item.\n\r",ch);
return;
}
if ( ( obj->item_type == ITEM_CORPSE_NPC || obj->item_type == ITEM_CORPSE_PC ) )
{
send_to_char("You cannot auction corpses!.\n\r",ch);
return;
}
if (obj->clan > 0)
{
send_to_char("You cannot auction clan equipment!.\n\r",ch);
return;
}
if ((IS_SET (obj->extra_flags, ITEM_ROT_DEATH)) || (IS_SET(obj->extra_flags, ITEM_VIS_DEATH)) || (IS_SET (obj->extra_flags, ITEM_HAD_TIMER)))
{
send_to_char("That might decompose, what are you thinking??\n\r",ch);
return;
}
// if (obj->item_type == ITEM_CONTAINER && obj->contains != NULL)
// {
// send_to_char("You cannot auction containers that are not empty!.\n\r",ch);
// return;
//}
maxbid = (obj->cost * 40);
maxbid = UMAX(maxbid, (obj->level * 200000) );
if(is_number(arg2))
{
minbid = atol(arg2);
// Calculate the Maxbid. Either the cost * 40 or the level * 200000, whichever is higher.
// Minimum bid comes here
if(minbid < obj->cost)
{
printf_to_char(ch,"The minimum this item can be auctioned for is %ld.\n\r",obj->cost);
return;
}
if( minbid > maxbid*2 )
{
printf_to_char(ch,"The maximum this item can be auctioned for is %ld.\n\r", maxbid*2);
return;
}
}
if ( !str_prefix( arg2, "minimum" ) )
{
minbid = obj->cost;
}
else if ( !str_prefix( arg2, "maximum" ) )
{
minbid = maxbid; // No more than 2000 plat
// code a case for uniques here later
}
auction_info.owner = ch;
auction_info.item = obj;
auction_info.minbid = minbid;
auction_info.current_bid = 0;
auction_info.status = 0;
sprintf(buf,"Now taking bids on %s. (Minbid %ld)\n\r", obj->short_descr, auction_info.minbid );
auction_channel( buf );
obj_from_char( obj );
return;
}
void auction_update( )
{
char buf[MAX_STRING_LENGTH], temp[MAX_STRING_LENGTH],
temp1[MAX_STRING_LENGTH], temp2[MSL];
if ( auction_info.item == NULL )
return;
auction_info.status++;
if ( auction_info.status == AUCTION_LENGTH )
{
sprintf(buf,"%s SOLD to %s for %ld silver.\n\r",
capitalize(auction_info.item->short_descr),
auction_info.high_bidder->name,
auction_info.current_bid );
auction_channel( buf );
auction_info.owner->gold += auction_info.gold_held;
auction_info.owner->silver += auction_info.silver_held;
auction_info.owner->platinum += auction_info.platinum_held;
sprintf(temp2, "%ld platinum, ", auction_info.platinum_held );
sprintf(temp1, "%ld gold ", auction_info.gold_held );
sprintf(temp, "%ld silver ", auction_info.silver_held );
sprintf(buf, "You receive %s%s%s%scoins.\n\r",
auction_info.platinum_held > 0 ? temp2 : "",
auction_info.gold_held > 0 ? temp1 : "",
((auction_info.gold_held > 0) &&
(auction_info.silver_held > 0)) ? "and " : "",
auction_info.silver_held > 0 ? temp : "" );
send_to_char( buf, auction_info.owner );
obj_to_char( auction_info.item, auction_info.high_bidder );
sprintf(buf, "%s appears in your hands.\n\r",
capitalize(auction_info.item->short_descr) );
send_to_char( buf, auction_info.high_bidder );
auction_info.item = NULL;
auction_info.owner = NULL;
auction_info.high_bidder = NULL;
auction_info.current_bid = 0;
auction_info.status = 0;
auction_info.platinum_held = 0;
auction_info.gold_held = 0;
auction_info.silver_held = 0;
return;
}
if ( auction_info.status == AUCTION_LENGTH - 1 )
{
sprintf(buf, "%s - going twice at %ld silver.\n\r",
capitalize(auction_info.item->short_descr),
auction_info.current_bid );
auction_channel( buf );
return;
}
if ( auction_info.status == AUCTION_LENGTH - 2 )
{
if ( auction_info.current_bid == 0 )
{
sprintf(buf, "No bids on %s - item removed.\n\r",
auction_info.item->short_descr);
auction_channel( buf );
obj_to_char( auction_info.item, auction_info.owner );
sprintf(buf, "%s is returned to you.\n\r",
capitalize(auction_info.item->short_descr) );
send_to_char( buf, auction_info.owner );
auction_info.item = NULL;
auction_info.owner = NULL;
auction_info.current_bid = 0;
auction_info.status = 0;
return;
}
sprintf(buf, "%s - going once at %ld silver.\n\r",
capitalize(auction_info.item->short_descr),
auction_info.current_bid );
auction_channel( buf );
return;
}
return;
}
void auction_channel( char * msg )
{
char buf[MAX_STRING_LENGTH];
DESCRIPTOR_DATA *d;
sprintf(buf, "\n\r{#[{!AUCTION{#]{& %s{x", msg ); /* Add color if you wish */
for ( d = descriptor_list; d != NULL; d = d->next )
{
CHAR_DATA *victim;
victim = d->original ? d->original : d->character;
if ( d->connected == CON_PLAYING &&
!IS_SET(victim->comm,COMM_NOAUCTION) &&
!IS_SET(victim->comm,COMM_QUIET) )
{
send_to_char( buf, victim );
}
}
return;
}
/*
* Show_obj_stats: code taken from stock identify spell (-Brian)
*/
void show_obj_stats( CHAR_DATA *ch, OBJ_DATA *obj )
{
char buf[MAX_STRING_LENGTH];
AFFECT_DATA *paf;
sprintf( buf,
"Object '%s' is type %s, extra flags %s.\n\rWeight is %d, value is %d, level is %d.\n\r",
obj->name,
item_name(obj->item_type),
extra_bit_name( obj->extra_flags ),
obj->weight / 10,
obj->cost,
obj->level
);
send_to_char( buf, ch );
switch ( obj->item_type )
{
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
sprintf( buf, "Level %d spells of:", obj->value[0] );
send_to_char( buf, ch );
if ( obj->value[1] >= 0 && obj->value[1] < MAX_SKILL )
{
send_to_char( " '", ch );
send_to_char( skill_table[obj->value[1]].name, ch );
send_to_char( "'", ch );
}
if ( obj->value[2] >= 0 && obj->value[2] < MAX_SKILL )
{
send_to_char( " '", ch );
send_to_char( skill_table[obj->value[2]].name, ch );
send_to_char( "'", ch );
}
if ( obj->value[3] >= 0 && obj->value[3] < MAX_SKILL )
{
send_to_char( " '", ch );
send_to_char( skill_table[obj->value[3]].name, ch );
send_to_char( "'", ch );
}
if (obj->value[4] >= 0 && obj->value[4] < MAX_SKILL)
{
send_to_char(" '",ch);
send_to_char(skill_table[obj->value[4]].name,ch);
send_to_char("'",ch);
}
send_to_char( ".\n\r", ch );
break;
case ITEM_WAND:
case ITEM_STAFF:
sprintf( buf, "Has %d charges of level %d",
obj->value[2], obj->value[0] );
send_to_char( buf, ch );
if ( obj->value[3] >= 0 && obj->value[3] < MAX_SKILL )
{
send_to_char( " '", ch );
send_to_char( skill_table[obj->value[3]].name, ch );
send_to_char( "'", ch );
}
send_to_char( ".\n\r", ch );
break;
case ITEM_DRINK_CON:
sprintf(buf,"It holds %s-colored %s.\n\r",
liq_table[obj->value[2]].liq_color,
liq_table[obj->value[2]].liq_name);
send_to_char(buf,ch);
break;
case ITEM_CONTAINER:
sprintf(buf,"Capacity: %d# Maximum weight: %d# flags: %s\n\r",
obj->value[0], obj->value[3], cont_bit_name(obj->value[1]));
send_to_char(buf,ch);
if (obj->value[4] != 100)
{
sprintf(buf,"Weight multiplier: %d%%\n\r",
obj->value[4]);
send_to_char(buf,ch);
}
break;
case ITEM_WEAPON:
send_to_char("Weapon type is ",ch);
switch (obj->value[0])
{
case(WEAPON_EXOTIC) : send_to_char("exotic.\n\r",ch); break;
case(WEAPON_SWORD) : send_to_char("sword.\n\r",ch); break;
case(WEAPON_DAGGER) : send_to_char("dagger.\n\r",ch); break;
case(WEAPON_SPEAR) : send_to_char("spear/staff.\n\r",ch); break;
case(WEAPON_MACE) : send_to_char("mace/club.\n\r",ch); break;
case(WEAPON_AXE) : send_to_char("axe.\n\r",ch); break;
case(WEAPON_FLAIL) : send_to_char("flail.\n\r",ch); break;
case(WEAPON_WHIP) : send_to_char("whip.\n\r",ch); break;
case(WEAPON_POLEARM): send_to_char("polearm.\n\r",ch); break;
default : send_to_char("unknown.\n\r",ch); break;
}
if (obj->pIndexData->new_format)
sprintf(buf,"Damage is %dd%d (average %d).\n\r",
obj->value[1],obj->value[2],
(1 + obj->value[2]) * obj->value[1] / 2);
else
sprintf( buf, "Damage is %d to %d (average %d).\n\r",
obj->value[1], obj->value[2],
( obj->value[1] + obj->value[2] ) / 2 );
send_to_char( buf, ch );
if (obj->value[4]) /* weapon flags */
{
sprintf(buf,"Weapons flags: %s\n\r",weapon_bit_name(obj->value[4]));
send_to_char(buf,ch);
}
break;
case ITEM_ARMOR:
sprintf( buf,
"Armor class is %d pierce, %d bash, %d slash, and %d vs. magic.\n\r",
obj->value[0], obj->value[1], obj->value[2], obj->value[3] );
send_to_char( buf, ch );
break;
}
if (!obj->enchanted)
for ( paf = obj->pIndexData->affected; paf != NULL; paf = paf->next )
{
if ( paf->location != APPLY_NONE && paf->modifier != 0 )
{
sprintf( buf, "Affects %s by %d.\n\r",
affect_loc_name( paf->location ), paf->modifier );
send_to_char(buf,ch);
if (paf->bitvector)
{
switch(paf->where)
{
case TO_AFFECTS:
sprintf(buf,"Adds %s affect.\n",
affect_bit_name(paf->bitvector));
break;
case TO_OBJECT:
sprintf(buf,"Adds %s object flag.\n",
extra_bit_name(paf->bitvector));
break;
case TO_IMMUNE:
sprintf(buf,"Adds immunity to %s.\n",
imm_bit_name(paf->bitvector));
break;
case TO_RESIST:
sprintf(buf,"Adds resistance to %s.\n\r",
imm_bit_name(paf->bitvector));
break;
case TO_VULN:
sprintf(buf,"Adds vulnerability to %s.\n\r",
imm_bit_name(paf->bitvector));
break;
default:
sprintf(buf,"Unknown bit %d: %d\n\r",
paf->where,paf->bitvector);
break;
}
send_to_char( buf, ch );
}
}
}
for ( paf = obj->affected; paf != NULL; paf = paf->next )
{
if ( paf->location != APPLY_NONE && paf->modifier != 0 )
{
sprintf( buf, "Affects %s by %d",
affect_loc_name( paf->location ), paf->modifier );
send_to_char( buf, ch );
if ( paf->duration > -1)
sprintf(buf,", %d hours.\n\r",paf->duration);
else
sprintf(buf,".\n\r");
send_to_char(buf,ch);
if (paf->bitvector)
{
switch(paf->where)
{
case TO_AFFECTS:
sprintf(buf,"Adds %s affect.\n",
affect_bit_name(paf->bitvector));
break;
case TO_OBJECT:
sprintf(buf,"Adds %s object flag.\n",
extra_bit_name(paf->bitvector));
break;
case TO_WEAPON:
sprintf(buf,"Adds %s weapon flags.\n",
weapon_bit_name(paf->bitvector));
break;
case TO_IMMUNE:
sprintf(buf,"Adds immunity to %s.\n",
imm_bit_name(paf->bitvector));
break;
case TO_RESIST:
sprintf(buf,"Adds resistance to %s.\n\r",
imm_bit_name(paf->bitvector));
break;
case TO_VULN:
sprintf(buf,"Adds vulnerability to %s.\n\r",
imm_bit_name(paf->bitvector));
break;
default:
sprintf(buf,"Unknown bit %d: %d\n\r",
paf->where,paf->bitvector);
break;
}
send_to_char(buf,ch);
}
}
}
return;
}