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