/**
* @@ Copyright (Wheel of Time Project)
*
* Wheel of Time (WoT) Mud System v0.1a
* Copyright (c) 1998, by Gary McNickle <gary@tarmongaidon.org>
*
* The author(s) retain full copyright to this package and are granting you a
* non-exclusive right to use it. Any distrobutions or changes to this code
* must contain the original copyrights as contained in this header.
*/
/**
* @@ Objective (auction.c)
*
* To provide an auction system that can handle more than one item for sale at once. With this
* system, each player can auction as many items at once as they like. I've not included any
* limits here, though I can see how they may become necessary if this becomes very popular.
*
* Thanks to Erwin for his parse_bet function.
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <time.h>
#include <errno.h>
#include "merc.h"
#include "olc.h"
#define ALL -1
#define SUMMARY 0
#define DETAIL 1
#define LOG_DIR ""
#define _DOFUN( fun ) void fun(CHAR_DATA *ch, char *argument)
/* Helper Functions */
/** Function: chprintf
* Descr : Sends formatted output to the specified player
* Returns : N/A
* Syntax : chprintf(CH, arguments...)
* Written : v1.0 1/99
* Author : Gary McNickle <gary@tarmongaidon.org>
*/
void chprintf(CHAR_DATA * ch, char *fmt, ...)
{
char buf[MSL];
va_list args;
va_start (args, fmt);
vsnprintf (buf, MSL, fmt, args);
va_end (args);
send_to_char (buf, ch);
}
char *errmsg (int err)
{
static char buf[13];
memset (buf, 0, 13);
sprintf (buf, "%s",
err == ETXTBSY ? "ETXTBSY" :
err == ELOOP ? "ELOOP" :
err == EEXIST ? "EEXIST" :
err == EISDIR ? "EISDIR" :
err == EFAULT ? "EFAULT" :
err == EACCES ? "EACCES" :
err == ENAMETOOLONG ? "ENAMETOOLONG" :
err == ENOENT ? "ENOENT" :
err == ENOTDIR ? "ENOTDIR" :
err == EMFILE ? "EMFILE" :
err == ENFILE ? "ENFILE" :
err == ENOMEM ? "ENOMEM" :
err == EROFS ? "EROFS" :
err == ENOSPC ? "ENOSPC" : "(unknown)");
return buf;
}
int eq_cost(OBJ_DATA* pObj)
{
/*
For a full version of this function, find the 'qgen' snippet
released to the rom mailing list, or take it from the WoTMud
server code. It's not required for this auction system.
*/
return 0;
}
long get_auction_id (void)
{
static long last_auction_id;
if (last_auction_id >= current_time)
last_auction_id++;
else
last_auction_id = current_time;
return last_auction_id;
}
/** Function: player_silver
* Descr : Determines the potential amount of silver a player is
* : carrying. Uses each gold as 100 silver.
* Returns : long
* Syntax : player_silver( whos )
* Written : v1.0 1/99
* Author : Gary McNickle <gary@tarmongaidon.org>
*/
long player_silver (CHAR_DATA * ch)
{
return
(ch->gold > 0) ? (ch->gold * 100) + ch->silver :
(ch->silver > 0) ? ch->silver : 0;
}
/** Function: amt_to_player
* Descr : Adds an amount of silver to a players gold and silver stats
* : Converts amounts over 100 to gold and remaining silver
* Returns : void
* Syntax : amt_to_player(to who, amount to give in silver)
* Written : v1.0 1/99
* Author : Gary McNickle <gary@tarmongaidon.org>
*/
void amt_to_player (CHAR_DATA * ch, long amt)
{
long in_gold = -1;
if (amt >= 1000)
{
in_gold = amt / 100;
amt -= (in_gold * 100);
}
if (in_gold > 0)
ch->gold += in_gold;
if (amt > 0)
ch->silver += amt;
}
/** Function: amt_from_player
* Descr : Deducts an amount of monies from a players silver and gold
stats.
* : Converts amounts over 100 to gold and remaining silver.
* Returns : TRUE/FALSE on success
* Syntax : amt_from_player( from who, amount in silver to deduct )
* Written : v1.0 1/99
* Author : Gary McNickle <gary@tarmongaidon.org>
*/
bool amt_from_player (CHAR_DATA * ch, long amt)
{
long in_gold = -1;
long in_silver = -1;
if (amt >= 1000)
{
in_gold = amt / 100;
amt -= (in_gold * 100);
}
in_silver = amt;
if (in_gold > 0)
{
if (in_gold > ch->gold)
return FALSE;
ch->gold -= in_gold;
}
if (in_silver > 0)
{
if (in_silver > ch->silver)
{
if (ch->gold < 1)
return FALSE;
ch->gold -= 1;
ch->silver += 100;
}
ch->silver -= in_silver;
}
return TRUE;
}
/** Function: announce_auction
* Descr : Displays a string to the entire mud. Anyone with the auction channel active
* : should see it.
* Returns : n/a
* Syntax : announce_auction( text )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
void announce_auction (char *text)
{
DESCRIPTOR_DATA *d, *d_next;
CHAR_DATA *ch;
for (d = descriptor_list; d != NULL; d = d_next)
{
d_next = d->next;
ch = d->original ? d->original : d->character;
if (d->connected == CON_PLAYING
&& !IS_SET(ch->comm,COMM_NOAUCTION)
&& !IS_SET(ch->comm,COMM_QUIET))
{
chprintf (ch, "{c[{YAuction{c]{x %s", text);
}
}
}
/** Function: is_valid_auction
* Descr : Given an auction #, determines if that auction has expired or not
* Returns : the auction data corresponding to the auction #
* Syntax : is_valid_auction( auction number in question )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
AUCTION_DATA *is_valid_auction (int number)
{
AUCTION_DATA *pAuc;
for (pAuc = house_auctions; pAuc != NULL; pAuc = pAuc->next)
if (pAuc && !pAuc->expired && pAuc->auction_number == number)
return pAuc;
return NULL;
}
/** Function: number_bids
* Descr : Returns the number of valid bids a particular auction has received.
* Returns : see description
* Syntax : number_bids( auction data in question )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
int number_bids (AUCTION_DATA * auction)
{
int count = 0;
BIDDER_DATA *bidders;
for (bidders = auction->bidders; bidders != NULL; bidders = bidders->next)
if (bidders->opening_bid > 0)
count++;
return count;
}
/** Function: winning_bidder
* Descr : Determines the current (if any) winning bidder of a given auction
* Returns : Bidder data of winner
* Syntax : winning_bidder( auction data in question )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
BIDDER_DATA *winning_bidder (AUCTION_DATA * auction)
{
BIDDER_DATA *winner = NULL;
BIDDER_DATA *bidder = NULL;
long last = 0;
for (bidder = auction->bidders; bidder != NULL; bidder = bidder->next)
{
if (!bidder)
break;
if (bidder->max_bid > last && bidder->max_bid >= auction->reserve_price)
winner = bidder;
last = bidder->max_bid;
}
return winner;
}
/** Function: minimum_bid
* Descr : Determines the minimum valid bid on an ongoing auction
* Returns : Minimum bid required to bid on this item
* Syntax : minimum_bid( auction data in question )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
long minimum_bid (AUCTION_DATA * auction)
{
if (auction->high_bid < auction->opening_price)
return auction->opening_price;
else
return auction->high_bid + auction->bid_increment;
}
/** Function: find_bidder
* Descr : Determines if a given player (CH) has bid on a particular auction or not
* Returns : TRUE if 'ch' is bidding on auction in question, FALSE if not
* Syntax : find_bidder( ch in question, auction in question )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
bool find_bidder (CHAR_DATA * ch, AUCTION_DATA * auction)
{
BIDDER_DATA *bidder = NULL;
for (bidder = auction->bidders; bidder != NULL; bidder = bidder->next)
{
if (!bidder)
break;
if (bidder->who == ch)
return TRUE;
}
return FALSE;
}
/** Function: show_auctions
* Descr : Displays output of all current auctions to player.
* Returns : n/a
* Syntax : show_auctions( to who, auction # [detail] )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
void show_auctions (CHAR_DATA * ch, char *argument)
{
AUCTION_DATA *pAuc, *pAuc_next;
CHAR_DATA *whose = NULL;
int Count = 0;
int AucID = -1;
char arg1[MIL], arg2[MIL];
char *header =
"{C//{c-| {YAuctions {c|-----------------------------------------------------------{C//{x\n\r";
char *seperator =
"{C//{c------------------------------------------------------------------------{C//{x\n\r";
bool Detail = FALSE;
bool iBids = FALSE;
bool iWins = FALSE;
bool iLoss = FALSE;
bool iAll = FALSE;
memset (arg1, 0, MIL);
memset (arg2, 0, MIL);
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (!arg1 || arg1[0] == '\0')
iAll = TRUE;
if (arg1[0] == '#')
{
AucID = atoi (arg2);
if (AucID < 0)
{
send_to_char ("Invalid auction number.\n\r", ch);
return;
}
}
else
if (!str_prefix (arg1, "detail") || !str_prefix (arg2, "detail"))
Detail = TRUE;
if (!str_prefix (arg1, "bids"))
iBids = TRUE;
else if (!str_prefix (arg1, "winning"))
iWins = TRUE;
else if (!str_prefix (arg1, "losing"))
iLoss = TRUE;
else if (!str_prefix (arg1, "all"))
iAll = TRUE;
else
whose = get_char_world (ch, arg1);
/* header... */
send_to_char (header, ch);
for (pAuc = house_auctions; pAuc != NULL; pAuc = pAuc_next)
{
pAuc_next = pAuc->next;
if (pAuc && pAuc->seller && !pAuc->expired)
{
char flags[100];
BIDDER_DATA *winner = NULL;
winner = winning_bidder (pAuc);
if (!iAll)
{
if (AucID > 0 && pAuc->auction_number != AucID)
continue;
else if (iWins && (winner && winner->who != ch))
continue;
else
if (iLoss && (find_bidder (ch, pAuc) && (winner && winner->who != ch)))
continue;
else if (iBids && !find_bidder (ch, pAuc))
continue;
else if (whose && pAuc->seller != whose)
continue;
}
Count++;
sprintf (flags, "{B*{x %s %s",
(pAuc->reserve_price > pAuc->high_bid) ? "{RR{x" : "{w-{x",
(minimum_bid (pAuc) > player_silver (ch)) ? "{YG{x" : "{w-{x");
chprintf (ch,
"{C// {G%-3d {g%-12.12s {WItem:{w %-37.37s {WO:{w%6d {C//{x\n\r"
"{C// {WBids: {w%-3d {WHigh Bid: {w%-28.28s {YM:{w%6d {GH:{w%6d {C//{x\n\r%s",
pAuc->auction_number,
PERS (pAuc->seller, ch),
pAuc->item->short_descr,
pAuc->opening_price,
number_bids (pAuc),
(winner
&& winner->who) ? PERS (winner->who,
ch) : "None Yet",
minimum_bid (pAuc), pAuc->high_bid, seperator);
if (Detail) /* Show item detail */
{
(*skill_table[ skill_lookup("identify") ].spell_fun)
(0, LEVEL_HERO - 1, ch, pAuc->item, TARGET_NONE);
send_to_char (seperator, ch);
}
}
}
/* footer... */
chprintf (ch,
"{C//{c-| {YTotal {W%d {c-------------------------------------------------------------{C//{x\n\r",
Count);
}
/** Function: log_auction
* Descr : Logs auction data to AUCTION_FILE log
* Returns : n/a
* Syntax : log_auction( auction data )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
void log_auction (AUCTION_DATA * pAuc)
{
FILE *fp = NULL;
char *strtime;
char fname[MIL];
sprintf (fname, "%s%s", LOG_DIR, AUCTION_FILE);
if (!(fp = fopen (fname, "a")))
{
logf ("[%s] Could not open file %s in order to save mud data.",
errmsg (errno), fname);
return;
}
strtime = ctime (¤t_time);
strtime[strlen (strtime) - 1] = '\0';
fprintf (fp, "%s | [v: %d] [a: %ld] [p: %d] %s was sold by %s to %s for $%ld gold.\n",
strtime,
pAuc->item->pIndexData->vnum,
pAuc->auction_id,
eq_cost(pAuc->item),
pAuc->item->short_descr,
pAuc->seller->name,
winning_bidder (pAuc)->who->name, pAuc->high_bid);
fclose (fp);
}
/** Function: auction_update
* Descr : Updates each item currently being sold
* Returns : n/a
* Syntax : void
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
void auction_update (void)
{
AUCTION_DATA *pAuc;
char buf[MSL];
for (pAuc = house_auctions; pAuc != NULL; pAuc = pAuc->next)
{
if (pAuc->item != NULL && !pAuc->expired)
{
switch (++pAuc->going)
{
case 1:
case 2:
{
if (pAuc->high_bid > 0)
sprintf (buf, "{c[{Y#%d{c] {c'{x%s{c' {wgoing %s for %ld gold.{x\n\r",
pAuc->auction_number,
pAuc->item->short_descr,
pAuc->going == 1 ? "once" : "twice", pAuc->high_bid);
else
sprintf (buf, "{c[{Y#%d{c] {c'{x%s{c' {whas no bids yet.{x\n\r",
pAuc->auction_number, pAuc->item->short_descr);
announce_auction (buf);
break;
}
case 3:
{
pAuc->expired = TRUE;
pAuc->time_closed = current_time;
if (pAuc->high_bid > 0)
{
CHAR_DATA *winner = NULL;
if (winning_bidder (pAuc) != NULL)
winner = winning_bidder (pAuc)->who;
if (!winner)
{
sprintf (buf,
"{c[{Y#%d] {c'{x%s{c' {wno bids met the reserve price. Auction over.{x\n\r",
pAuc->auction_number, pAuc->item->short_descr);
announce_auction (buf);
obj_to_char (pAuc->item, pAuc->seller);
act("An auctioneers aide appears before you and returns your $p",
pAuc->seller, pAuc->item, NULL, TO_CHAR);
act ("An auctioneers aid appears before $n, and hands $m $p",
pAuc->seller, pAuc->item, NULL, TO_ROOM);
return;
}
sprintf (buf, "{c[{Y#%d{c] {c'{x%s{c' {wsold to %s for %ld gold!{x\n\r",
pAuc->auction_number,
pAuc->item->short_descr,
winner->name, pAuc->high_bid);
announce_auction (buf);
obj_to_char (pAuc->item, winner);
act ("An auctioneers aide appears before you and hands you $p",
winner, pAuc->item, NULL, TO_CHAR);
act ("An auctioneers aid appears before $n, and hands $m $p",
winner, pAuc->item, NULL, TO_ROOM);
amt_to_player (winner, (long)(pAuc->high_bid * .90));
log_auction (pAuc);
}
else
/* not sold! */
{
sprintf (buf,
"{YNo bids were received for auction {W#%d{Y, item removed.{x\n\r",
pAuc->auction_number);
announce_auction (buf);
act ("An auctioneers aid appears before you and returns your $p",
pAuc->seller, pAuc->item, NULL, TO_CHAR);
act ("An auctioneers aid appears before $n, and hands $m $p.",
pAuc->seller, pAuc->item, NULL, TO_ROOM);
obj_to_char (pAuc->item, pAuc->seller);
}
}
} /* switch */
} /* if valid auction */
} /* end: for loop through auctions */
}
/** Function: outbid
* Descr : Determines if a bidders bid on a particular auction is outbid or not.
* : Updates proxy bids appropriately.
* Returns : TRUE if the players bid was outbid by another (via proxy)
* Syntax : outbid(who's bidding, on which auction item, how much is the bid)
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
bool outbid (CHAR_DATA * ch, AUCTION_DATA * auction, long bid)
{
bool winner = TRUE;
BIDDER_DATA *bids;
for (bids = auction->bidders; bids != NULL; bids = bids->next)
if (bids->max_bid > bid && bids->max_bid >= auction->high_bid)
{
/* Ok, someone elses proxy bid is higher than ours, so update their
* bids as well... */
winner = FALSE;
if (bid + auction->bid_increment <= bids->max_bid)
bids->current_bid = bid + auction->bid_increment;
else
bids->current_bid = bids->max_bid;
if (bids->current_bid > auction->high_bid)
auction->high_bid = bids->current_bid;
bids->time_last_bid = current_time;
}
return !(winner);
}
/** Function: add_bidder
* Descr : Adds a bidder (or updates his data) to an auction
* Returns : n/a
* Syntax : add_bidder(bidder, auction bidding on, amount of bid)
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
void add_bidder (CHAR_DATA * ch, AUCTION_DATA * auction, long bid)
{
BIDDER_DATA *bidder;
/* is this character allready on the bidder list? */
for (bidder = auction->bidders; bidder != NULL; bidder = bidder->next)
if (bidder->who == ch)
{
/* Yep, allready here... update data */
if (bidder->max_bid < bid)
bidder->max_bid = bid;
bidder->current_bid = bid;
bidder->time_last_bid = current_time;
if (bidder->time_opening_bid == 0)
bidder->time_opening_bid = current_time;
return;
}
/* no, not here eh? */
bidder = new_bidder ();
bidder->who = ch;
bidder->max_bid = bid;
bidder->current_bid = bid;
bidder->opening_bid = bid;
bidder->time_last_bid = current_time;
bidder->time_opening_bid = current_time;
bidder->next = auction->bidders;
auction->bidders = bidder;
}
/** Function: do_auction
* Descr : Main auction command parser. See details below
* Returns : n/a
* Syntax : do_auction( see below )
* Written : v1.0 4/00
* Author : Gary McNickle <rhuarc@tarmongaidon.org>
*/
_DOFUN (do_auction)
{
AUCTION_DATA *pAuc = NULL;
char arg[MIL];
char buf[MSL];
/* Syntax
*
* show Defaults to detail of last item bid on, or all if no bids
* - # Show detail of the specified item
* - detail Show detail for all items (default is summary)
* - bids Show detail for all items currently bidding on
* - winning Show detail for all items currently winning bids on
* - losing Show detail for all items currently losing bids on
* - 'name' Show all auctions by a specific person (detail)
* - all Show summary of all auctions (default action)
*
* sell [item] Put an item up for auction
* - reserve Set the reserve price, if any
* - # [#] How many of these items are up for sale?
* - open Set the opening bid
* - inc Set the minimum bid increment
* - commit Commit the item to sale
*
* bid <#> <amt>
*
* cancel/stop
*/
if (IS_NPC (ch))
{
send_to_char ("Mobs may not participate in auctions.\n\r", ch);
return;
}
argument = one_argument (argument, arg);
if (ch->desc->editor != ED_NONE
&& (ch->desc->editor != ED_AUCTION && !str_prefix (arg, "stop")))
{
send_to_char ("Please leave OLC before participating in an auction.\n\r", ch);
return;
}
if (!arg || arg[0] == '\0' || !str_prefix (arg, "show"))
{
show_auctions (ch, argument);
return;
}
/* Otherwise, parse the arguments... */
if (!str_cmp (arg, "on"))
{
if (IS_SET(ch->comm,COMM_NOAUCTION))
REMOVE_BIT(ch->comm,COMM_NOAUCTION);
send_to_char ("Your auction channel is now ON.\n\r", ch);
return;
}
else if (!str_cmp (arg, "off"))
{
if (!IS_SET(ch->comm,COMM_NOAUCTION))
SET_BIT(ch->comm,COMM_NOAUCTION);
send_to_char ("Your auction channel is now OFF.\n\r", ch);
return;
}
while (arg[0] != '\0')
{
if (!str_prefix (arg, "help"))
{
do_help (ch, "auction");
return;
}
if (!str_prefix (arg, "bid"))
{
int auc = 0;
long bid = 0;
long min = 0;
argument = one_argument (argument, arg);
if (!arg || (auc = atoi (arg)) < 0 || !is_number (arg))
{
send_to_char("And just which auction would you like to bid on PLEASE?\n\r", ch);
return;
}
if ((pAuc = is_valid_auction (auc)) == NULL)
{
send_to_char
("I cant seem to find that item, how much did you say you would give for it? *grin*\n\r",
ch);
return;
}
if (pAuc->seller == ch)
{
send_to_char
("Sorry, but sellers are forbidden to bid on their own auctions!\n\r",ch);
return;
}
argument = one_argument (argument, arg);
bid = atoi(arg);
min = minimum_bid (pAuc);
if (bid == 0)
{
send_to_char ("Hey, we don't just GIVE things away here!\n\r", ch);
return;
}
else
if (bid < min)
{
chprintf (ch,
"The minimum bid for this item is %d %s, bid higher!\n\r",
min, (min > 100) ? "gold" : "silver");
return;
}
if (bid > player_silver (ch))
{
send_to_char ("You dont have that much on you!\n\r", ch);
return;
}
/* Check proxies... */
if (!outbid (ch, pAuc, bid))
{
chprintf (ch, "YOU have the highest bid for %s!\n\r",
pAuc->item->short_descr);
if (pAuc->reserve_price > bid)
send_to_char ("Your bid does not meet the reserve price.\n\r", ch);
else
if (pAuc->reserve_price > 0 && pAuc->reserve_price <= bid)
send_to_char ("Your bid meets or exceeds the reserve price!\n\r", ch);
/* Only add successful bidders to bidder list */
add_bidder (ch, pAuc, bid);
pAuc->high_bid = bid;
pAuc->going = 0;
amt_from_player (ch, bid);
return;
}
else
{
send_to_char ("Syntax error, see help auction.\n\r", ch);
return;
}
} /* end: bid */
if (!str_prefix (arg, "reserve"))
{
long price = 0;
pAuc = (AUCTION_DATA *) ch->desc->pEdit;
if (!pAuc || ch->desc->editor != ED_AUCTION)
{
send_to_char ("You must begin an auction first.\n\r", ch);
return;
}
argument = one_argument (argument, arg);
price = atoi(arg);
if (price < 1)
{
send_to_char ("Sell it for HOW much? *bog*\n\r", ch);
return;
}
if (price < pAuc->opening_price)
{
send_to_char
("Reserve prices must be higher than opening prices!\n\r", ch);
return;
}
pAuc->reserve_price = price;
chprintf (ch, "O.K. %s will sell for a minimum of %d %s\n\r",
pAuc->item->short_descr,
pAuc->reserve_price,
(pAuc->reserve_price > 99) ? "gold" : "silver");
return;
}
else if (!str_prefix (arg, "open"))
{
long price = 0;
pAuc = (AUCTION_DATA *) ch->desc->pEdit;
if (!pAuc || ch->desc->editor != ED_AUCTION)
{
send_to_char ("You must begin an auction first.\n\r", ch);
return;
}
argument = one_argument (argument, arg);
price = atoi(arg);
if (price < 1)
{
send_to_char ("Start the bidding for HOW much? *bog*\n\r", ch);
return;
}
pAuc->opening_price = price;
chprintf (ch, "O.K. %s will begin selling for %d %s\n\r",
pAuc->item->short_descr,
pAuc->opening_price,
(pAuc->opening_price > 99) ? "gold" : "silver");
return;
} /* end: open */
else if (!str_prefix (arg, "increment"))
{
long inc = 0;
pAuc = (AUCTION_DATA *) ch->desc->pEdit;
if (!pAuc || ch->desc->editor != ED_AUCTION)
{
send_to_char ("You must begin an auction first.\n\r", ch);
return;
}
argument = one_argument (argument, arg);
inc = atoi(arg);
if (inc <= 0)
{
send_to_char ("Increment the bidding by HOW much? *bog*\n\r", ch);
return;
}
pAuc->bid_increment = inc;
chprintf (ch, "O.K. %s will accept bid increments of +%d %s\n\r",
pAuc->item->short_descr,
pAuc->bid_increment,
(pAuc->bid_increment > 99) ? "gold" : "silver");
return;
} /* end: inc */
else
if (!str_prefix (arg, "commit"))
{
pAuc = (AUCTION_DATA *) ch->desc->pEdit;
if (!pAuc || ch->desc->editor != ED_AUCTION)
{
send_to_char ("You must begin an auction first.\n\r", ch);
return;
}
if (pAuc->opening_price <= 0)
{
send_to_char
("Let me get this straight... you want me to GIVE this away?\n\r",
ch);
return;
}
pAuc->expired = FALSE;
pAuc->next = house_auctions;
house_auctions = pAuc;
ch->desc->pEdit = NULL;
ch->desc->editor = ED_NONE;
send_to_char ("Your item is now on the block!\n\r", ch);
sprintf (buf, "{c[{Y#%d{c] {c'{x%s{c' {whas been put up for auction by %s{x\n\r",
pAuc->auction_number,
pAuc->item->short_descr,
PERS (pAuc->seller, ch));
announce_auction( buf );
return;
} /* end: commit */
else if (!str_cmp ("#", arg))
{
long value = 0;
char buf[MIL];
pAuc = (AUCTION_DATA *) ch->desc->pEdit;
if (!pAuc || ch->desc->editor != ED_AUCTION)
{
send_to_char ("You must begin an auction first.\n\r", ch);
return;
}
argument = one_argument (argument, arg);
if (!arg || (value = atol (arg)) < 0 || !is_number (arg))
{
send_to_char ("HOW many are you selling?\n\r", ch);
return;
}
sprintf (buf, "%ld.%s", value, pAuc->item->short_descr);
if (!get_obj_carry (ch, buf, ch))
{
send_to_char ("But you don't have that many!\n\r", ch);
return;
}
pAuc->number_for_sale = (short)value;
value = (pAuc->reserve_price > 0) ? pAuc->reserve_price : pAuc->opening_price;
chprintf (ch,
"O.K. You are selling %d %s's for a minimum of %d %s each.\n\r",
pAuc->number_for_sale, pAuc->item->short_descr,
(value) ? "gold" : "silver");
return;
}
else if (!str_prefix (arg, "clear"))
{
pAuc = (AUCTION_DATA *) ch->desc->pEdit;
if (!pAuc)
{
send_to_char ("Uh huh, sure thing.\n\r", ch);
return;
}
if (pAuc->item != NULL)
{
chprintf (ch, "Your %s has been returned to you.\n\r",
pAuc->item->short_descr);
obj_to_char (pAuc->item, pAuc->seller);
}
free_auction (pAuc);
ch->desc->pEdit = NULL;
send_to_char ("Auction data cleared.\n\r", ch);
return;
}
else if (!str_prefix ("sell", arg))
{
OBJ_DATA *item = NULL;
char arg2[MIL], arg3[MIL];
long open = -1;
pAuc = (AUCTION_DATA *) ch->desc->pEdit;
if (pAuc != NULL)
{
send_to_char ("Will you PLEASE decide what you want to sell?\n\r",
ch);
return;
}
memset (arg2, 0, MIL);
memset (arg3, 0, MIL);
argument = one_argument (argument, arg2);
argument = one_argument (argument, arg3);
if ((item = get_obj_list (ch, arg2, ch->carrying)) == NULL)
{
send_to_char ("You aren't carrying that!\n\r", ch);
return;
}
if (!IS_NULLSTR (arg3) && is_number (arg3))
open = atoi(arg3);
/*
if (IS_SET (item->extra_flags, ITEM_GUILD) )
{
send_to_char ("Guild items may not be auctioned, shame on you!\n\r", ch);
return;
}
if (IS_SET (item->extra_flags, ITEM_GHOST) )
{
send_to_char ("Items found in the Dreamworld may not be auctioned.\n\r", ch);
return;
}
else
if (IS_SET (item->wear_flags, ITEM_WEAR_TATTOO))
{
send_to_char ("How do you propose to remove THAT?\n\r", ch);
return;
}
else
*/
if (IS_SET (item->extra_flags, ITEM_NOREMOVE) && !IS_IMMORTAL (ch))
{
act ("You can't remove $p.", ch, item, NULL, TO_CHAR);
return;
}
/* Here is where we assign the actual auction item... */
pAuc = new_auction ();
pAuc->seller = ch;
pAuc->item = item;
pAuc->auction_id = get_auction_id ();
if (open > 0)
pAuc->opening_price = open;
ch->desc->pEdit = (void *) pAuc;
ch->desc->editor = ED_AUCTION;
obj_from_char (item);
if (open > 0)
chprintf (ch,
"Ok, I'll start the bidding for %s at $%d gold.\n\r",
pAuc->item->short_descr, pAuc->opening_price);
else
send_to_char ("Ok, now what?\n\r", ch);
} /* end: sell */
argument = one_argument (argument, arg);
} /* end: while loop through arguments */
return;
}