/**************************************************************************** * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * * -----------------------------------------------------------| (0...0) * * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * * -----------------------------------------------------------| {o o} * * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* * Tricops and Fireblade | * * ------------------------------------------------------------------------ * * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * ------------------------------------------------------------------------ * * Shop and repair shop module * ****************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <string.h> #include <time.h> #include <sys/stat.h> #ifndef WIN32 #include <dirent.h> #endif #include "mud.h" /* * Local functions */ #define CD CHAR_DATA int get_cost args( ( CHAR_DATA *ch, SHOP_DATA *pShop, OBJ_DATA *obj, bool fBuy ) ); #undef CD /* handler.c */ extern MAT_SHOP *find_matshop (int i); extern MATERIAL_DATA *material_lookup( int number ); extern void learn_noncombat(CHAR_DATA *ch, int i); /* makeobjs.c */ extern OBJ_DATA *make_ore (int i); int get_cost( CHAR_DATA *ch, SHOP_DATA *pShop, OBJ_DATA *obj, bool fBuy ) { if (obj) { if (fBuy) { /* Low cost items need the precision, * but high cost items need to not overflow MAXINT - * items over 21 mithril could not be sold before */ if (obj->cost < 1000000) return (obj->cost * pShop->profit_sell) / 100; else return (obj->cost / 100) * pShop->profit_sell; } else { return obj->cost; } } else return 0; } void do_buy( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; int maxgold; OBJ_DATA *obj; int cost; int noi = 1; /* Number of items */ sh_int mnoi = 100; /* Max number of items to be bought at once */ MAT_SHOP *matshop; MATERIAL_DATA *mat; int i; argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Buy what?\n\r", ch ); return; } if ( ( matshop = find_matshop ( ch->in_room->vnum) ) != NULL ) { for (i = 0;i < 5; i++) { mat = material_lookup(matshop->mat[i]); if (!mat) continue; if (!str_cmp(arg, mat->name) || !str_prefix(arg, mat->name)) { if (ch->gold < mat->cost) { send_to_char("You don't have enough gold.\n\r", ch); return; } if ( ch->carry_number + 1 > can_carry_n( ch ) ) { send_to_char( "You have your hands full.\n\r", ch ); return; } if ( ch->carry_weight + mat->weight > can_carry_w( ch ) ) { send_to_char( "You can't carry that much weight.\n\r", ch ); return; } ch->gold -= mat->cost; boost_economy(ch->in_room->area, mat->cost); obj = make_ore(matshop->mat[i]); obj_to_char(obj, ch); ch_printf(ch, "You buy %s.\n\r", mat->short_descr); act(AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM); return; } } return; } if (!ch->in_room->pShop) { send_to_char("This isn't a shop.\n\r", ch); return; } if (!str_cmp(ch->in_room->pShop->owner, "(for sale)")) { if (!str_cmp(arg, "shop")) { if (ch->gold < 1000000) { send_to_char("You can't afford it.\n\r", ch); return; } act(AT_ACTION, "$n purchases this shop.", ch, NULL, NULL, TO_ROOM); send_to_char("You purchase this shop for &C1 mithril.\n\r",ch); ch->gold -= 1000000; STRFREE(ch->in_room->pShop->owner); ch->in_room->pShop->owner = STRALLOC(ch->name); fold_area(ch->in_room->area, ch->in_room->area->filename, FALSE); return; } } maxgold = ch->in_room->pShop->gold; if ( is_number( arg ) ) { noi = atoi( arg ); argument = one_argument( argument, arg ); if ( noi > mnoi ) { send_to_char("You can't buy that many items at once.\n\r", ch); return; } } obj = get_obj_list( ch, arg, ch->in_room->first_content ); if (!obj) { send_to_char("There is no such item here.\n\r", ch); return; } cost = ( get_cost( ch, ch->in_room->pShop, obj, TRUE ) * noi ); if (obj && IS_AFFECTED(ch, AFF_HAS_ARTI) && IS_OBJ_STAT(obj, ITEM_ARTIFACT)) { act(AT_ACTION, "$p evades your grasp.", ch, obj, NULL, TO_CHAR); act(AT_ACTION, "$p evades $n's grasp.", ch, obj, NULL, TO_ROOM); return; } if (IS_AFFECTED(ch, AFF_ETHEREAL)) { act(AT_ACTION, "Your hand passes through $p.", ch, obj, NULL, TO_CHAR); act(AT_ACTION, "$n's hand passes through $p.", ch, obj, NULL, TO_ROOM); return; } if ( cost <= 0 || !can_see_obj( ch, obj ) ) { send_to_char("That item isn't sold here. Try 'list'.\n\r", ch); return; } if ( noi > obj->count && !IS_OBJ_STAT(obj, ITEM_INVENTORY)) { send_to_char("There aren't enough of that item here to buy that many.\n\r", ch); return; } if ( ch->gold < cost ) { send_to_char("You can't afford to buy that.\n\r", ch); return; } if ( IS_OBJ_STAT(obj, ITEM_PROTOTYPE) && IS_SET(ch->pcdata->permissions, PERMIT_BUILD) ) { send_to_char("That is only a prototype, you can't buy that.\n\r", ch); return; } separate_obj(obj); if ( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) ) { send_to_char( "You can't carry that many items.\n\r", ch ); return; } if ( ch->carry_weight + ( get_obj_weight( obj ) * noi ) + (noi > 1 ? 2 : 0) > can_carry_w( ch ) ) { send_to_char( "You can't carry that much weight.\n\r", ch ); return; } ch->gold -= cost; if (!IS_OBJ_STAT(obj, ITEM_INVENTORY)) ch->in_room->pShop->gold += cost; if ( noi == 1 ) { act( AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You buy $p.", ch, obj, NULL, TO_CHAR ); if (str_cmp(ch->in_room->pShop->owner, "Keolah")) { /* If the shop is owned by a player, make sure their * profits are saved */ fold_area(ch->in_room->area, ch->in_room->area->filename, FALSE); WAIT_STATE(ch, PULSE_VIOLENCE); } } else { sprintf( arg, "$n buys %d $p%s.", noi, ( obj->short_descr[strlen(obj->short_descr)-1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_ROOM ); sprintf( arg, "You buy %d $p%s.", noi, ( obj->short_descr[strlen(obj->short_descr)-1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_CHAR ); act( AT_ACTION, "A clerk puts them into a bag and hands it to you.", ch, NULL, NULL, TO_CHAR ); } if ( IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) { OBJ_DATA *buy_obj, *bag; buy_obj = create_object( obj->pIndexData, 0 ); /* * Due to grouped objects and carry limitations in SMAUG * The shopkeeper gives you a bag with multiple-buy, * and also, only one object needs be created with a count * set to the number bought. -Thoric */ if ( noi > 1 ) { bag = create_object( get_obj_index( OBJ_VNUM_SHOPPING_BAG ), 1 ); xSET_BIT(bag->extra_flags, ITEM_GROUNDROT); bag->timer = 10; /* Blodkai, 4/97 */ /* perfect size bag ;) */ bag->value[0] = bag->weight + (buy_obj->weight * noi); buy_obj->count = noi; obj->pIndexData->count += (noi - 1); numobjsloaded += (noi - 1); obj_to_obj( buy_obj, bag ); obj_to_char( bag, ch ); } else obj_to_char( buy_obj, ch ); } else { obj_from_room( obj ); obj_to_char( obj, ch ); } return; } void do_list( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; char *rest; OBJ_DATA *obj; int cost, gp, count; MAT_SHOP *matshop; int i; MATERIAL_DATA *mat; rest = one_argument( argument, arg ); if ( ( matshop = find_matshop(ch->in_room->vnum)) != NULL) { for (i = 0;i < 5; i++) { mat = material_lookup(matshop->mat[i]); if (!mat) continue; gp = mat->cost; pager_printf( ch, "[&C%dm ", (int)gp/1000000 ); gp = gp % 1000000; pager_printf( ch, "&Y%dg ", (int)gp/10000 ); gp = gp % 10000; pager_printf( ch, "&W%ds ", (int)gp/100 ); gp = gp % 100; pager_printf( ch, "&O%dc&w", gp); pager_printf( ch, "] - %s\n\r", mat->short_descr ); } return; } if (!ch->in_room->pShop) { send_to_char("This isn't a shop.\n\r",ch); return; } count = 0; for ( obj = ch->in_room->first_content; obj; obj = obj->next_content ) { if ( can_see_obj( ch, obj ) && ( cost = get_cost( ch, ch->in_room->pShop, obj, TRUE ) ) > 0 && ( arg[0] == '\0' || nifty_is_name( arg, obj->name ) ) ) { if ( !count ) send_to_pager( "[Price] Item\n\r", ch ); count++; gp = get_cost(ch, ch->in_room->pShop, obj, TRUE); pager_printf( ch, "[&C%dm ", (int)gp/1000000 ); gp = gp % 1000000; pager_printf( ch, "&Y%dg ", (int)gp/10000 ); gp = gp % 10000; pager_printf( ch, "&W%ds ", (int)gp/100 ); gp = gp % 100; pager_printf( ch, "&O%dc&w", gp); pager_printf( ch, "] %s.\n\r", capitalize( aoran(myobj(obj))) ); if (count > 50) { send_to_char( "There are many other items here besides these.\n\r", ch ); break; } } } if ( !count ) { if ( arg[0] == '\0' ) send_to_char( "There is nothing for sale here.\n\r", ch ); else send_to_char( "That isnt for sale here.\n\r", ch ); } return; } void do_sell( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; OBJ_DATA *obj; int cost, gp; one_argument( argument, arg ); if (!ch->in_room->pShop) { send_to_char("This isn't a shop.\n\r", ch); return; } if ( arg[0] == '\0' ) { send_to_char( "Sell what?\n\r", ch ); return; } if (!str_cmp(arg, "shop") && !str_cmp(ch->name, ch->in_room->pShop->owner)) { do_withdraw(ch, ""); act(AT_ACTION, "$n sells the deed to the shop.", ch, NULL, NULL, TO_ROOM); send_to_char("You sell the shop to the city for &C1 mithril.\n\r", ch); ch->gold += 1000000; STRFREE(ch->in_room->pShop->owner); ch->in_room->pShop->owner = STRALLOC("(for sale)"); fold_area(ch->in_room->area, ch->in_room->area->filename, FALSE); return; } if ( str_cmp( arg, "all" ) && str_prefix( "all.", arg ) ) { /* 'sell obj' */ if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { send_to_char("You don't have that.\n\r", ch); return; } if ( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it!\n\r", ch ); return; } if ( obj->timer > 0 ) { send_to_char("You should preserve that first.\n\r", ch); return; } if (IS_OBJ_STAT(obj, ITEM_DREAMWORLD)) { send_to_char("The shop won't buy your imaginary items.\n\r", ch); return; } if ( ( cost = get_cost( ch, ch->in_room->pShop, obj, FALSE ) ) <= 0 ) { send_to_char("The shop isn't interested.\r\n", ch); return; } if ( ch->in_room->pShop->type != -1 && ch->in_room->pShop->type != obj->item_type ) { send_to_char("This shop does not deal in this type of items.\n\r", ch); return; } if ( ch->in_room->pShop->flag != -1 && !xIS_SET(obj->extra_flags, ch->in_room->pShop->flag ) ) { send_to_char("This shop does not deal in items of this nature.\n\r", ch); return; } separate_obj( obj ); if (!str_cmp(ch->in_room->pShop->owner, ch->name)) { act( AT_ACTION, "$n puts $p up for sale.", ch, obj, NULL, TO_ROOM); ch_printf(ch, "You put %s up for sale.\n\r", aoran(myobj(obj))); obj_from_char(obj); obj_to_room(obj, ch->in_room); return; } else if ( ch->in_room->pShop->gold < obj->cost && str_cmp(ch->in_room->pShop->owner, "Keolah") ) { send_to_char("The shop cannot afford to buy this.\n\r", ch); return; } act( AT_ACTION, "$n sells $p.", ch, obj, NULL, TO_ROOM ); gp = get_cost(ch, ch->in_room->pShop, obj, FALSE); ch_printf( ch, "You sell %s for &C%dmithril, ", aoran(obj->short_descr), (int)gp/1000000 ); gp = gp % 1000000; ch_printf( ch, "&Y%dgold, ", (int)gp/10000 ); gp = gp % 10000; ch_printf( ch, "&W%dsilver, ", (int)gp/100 ); gp = gp % 100; ch_printf( ch, "and &O%dcopper&w coins.\n\r", gp); ch->gold += cost; ch->in_room->pShop->gold -= cost; obj_from_char( obj ); obj_to_room( obj, ch->in_room ); } else { char *chk; bool fAll, found; OBJ_DATA *obj_next; /* 'sell all' or 'sell all.obj' */ if ( !str_cmp(arg, "all") ) { chk = arg; fAll = TRUE; } else { chk = &arg[4]; fAll = FALSE; } found = FALSE; gp = 0; for ( obj = ch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if ( (fAll || nifty_is_name_prefix( chk, obj->name ) ) && can_see_obj( ch, obj ) && obj->wear_loc == WEAR_NONE && can_drop_obj( ch, obj ) ) { if ( obj->timer > 0 ) continue; if (IS_OBJ_STAT(obj, ITEM_DREAMWORLD)) continue; if ((cost = get_cost(ch, ch->in_room->pShop, obj, FALSE)) <= 0) continue; if ( ch->in_room->pShop->type != -1 && ch->in_room->pShop->type != obj->item_type ) continue; if ( ch->in_room->pShop->flag != -1 && !xIS_SET(obj->extra_flags, ch->in_room->pShop->flag ) ) continue; if ( ch->in_room->pShop->gold < obj->cost && str_cmp(ch->in_room->pShop->owner, "Keolah") && str_cmp(ch->in_room->pShop->owner, ch->name) ) continue; separate_obj( obj ); found = TRUE; cost = get_cost(ch, ch->in_room->pShop, obj, FALSE); if (str_cmp(ch->in_room->pShop->owner, ch->name)) { gp += cost; ch->in_room->pShop->gold -= cost; } obj_from_char( obj ); obj_to_room( obj, ch->in_room ); } } if (found) { if (!str_cmp(ch->in_room->pShop->owner, ch->name)) { act( AT_ACTION, "$n puts a bunch of stuff up for sale.", ch, obj, NULL, TO_ROOM); send_to_char("You put a bunch of stuff up for sale.\n\r", ch); return; } else { ch->gold += gp; act( AT_ACTION, "$n sells a bunch of stuff.", ch, NULL, NULL, TO_ROOM ); ch_printf( ch, "You sell a bunch of stuff for &C%dmithril, ", (int)gp/1000000 ); gp = gp % 1000000; ch_printf( ch, "&Y%dgold, ", (int)gp/10000 ); gp = gp % 10000; ch_printf( ch, "&W%dsilver, ", (int)gp/100 ); gp = gp % 100; ch_printf( ch, "and &O%dcopper&w coins.\n\r", gp); STRFREE(ch->last_taken); ch->last_taken = STRALLOC("selling things"); WAIT_STATE(ch, PULSE_VIOLENCE); return; } } else { send_to_char("You have nothing this shop can buy.\n\r", ch); return; } } } void do_value( CHAR_DATA *ch, char *argument ) { OBJ_DATA *obj; int gp; if ( argument[0] == '\0' ) { send_to_char( "Value what?\n\r", ch ); return; } if (!ch->in_room->pShop) { send_to_char("This isn't a shop.\n\r", ch); return; } if ( ( obj = get_obj_carry( ch, argument ) ) == NULL ) { send_to_char("You don't have any such item.\n\r", ch); return; } if ( ( gp = get_cost( ch, ch->in_room->pShop, obj, FALSE ) ) <= 0 ) { send_to_char("The shop isn't interested in that.\n\r", ch); return; } ch_printf( ch, "%s is worth &C%dmithril, ", aoran(obj->short_descr), (int)gp/1000000 ); gp = gp % 1000000; ch_printf( ch, "&Y%dgold, ", (int)gp/10000 ); gp = gp % 10000; ch_printf( ch, "&W%dsilver, ", (int)gp/100 ); gp = gp % 100; ch_printf( ch, "and &O%dcopper&w coins.\n\r", gp); return; } void do_repair( CHAR_DATA *ch, char *argument ) { PART_DATA *part; OBJ_DATA *obj; CHAR_DATA *victim = NULL; char buf[MAX_STRING_LENGTH]; if ( argument[0] == '\0' ) { victim = ch; } if ( ( obj = get_obj_carry( ch, argument ) ) == NULL ) { if (( victim = get_char_room( ch, argument) ) == NULL) { send_to_char("You don't see that here.\n\r", ch); return; } } learn_noncombat(ch, SK_SMITH); if ( number_percent( ) * (IS_AFFECTED(ch, AFF_NUISANCE) ? 2 : 1) > (IS_NPC(ch) ? 100 : LEARNED(ch, gsn_repair)) ) { if (obj) { sprintf(buf, "repairing the %s", myobj(obj)); ch->last_taken = STRALLOC(buf); act( AT_SKILL, "You attempt to repair your $t, but damage it further.", ch, myobj(obj), NULL, TO_CHAR); act( AT_SKILL, "$n attempts to repair $s $t, but damages it.", ch, myobj(obj), NULL, TO_ROOM); damage_obj(obj); } if (victim) { sprintf(buf, "repairing %s", victim->name); ch->last_taken = STRALLOC(buf); if (!IS_AFFECTED(victim, AFF_CONSTRUCT)) { send_to_char("Just how do you propose to do that?\n\r", ch); return; } if (victim != ch) { act( AT_SKILL, "You attempt to repair $N, but damage $M further.", ch, NULL, victim, TO_CHAR ); act( AT_SKILL, "$n attempts to repair you, but damages you further.", ch, NULL, victim, TO_VICT); act( AT_SKILL, "$n attempts to repair $N, but damages $M further.", ch, NULL, victim, TO_NOTVICT); } else { act( AT_SKILL, "You attempt to repair yourself, but damage yourself further.", ch, NULL, NULL, TO_CHAR); act( AT_SKILL, "$n attempts to repair $mself, but damages $mself further.", ch, NULL, NULL, TO_ROOM); } lose_hp(victim, 20); } learn_from_failure( ch, gsn_repair ); } else { if (obj) { sprintf(buf, "repairing the %s", myobj(obj)); ch->last_taken = STRALLOC(buf); act( AT_SKILL, "You carefully repair your $t.", ch, myobj(obj), NULL, TO_CHAR); act( AT_SKILL, "$n carefully repairs $s $t.", ch, myobj(obj), NULL, TO_ROOM); obj->condition = number_fuzzy(obj->weight * 50); } if (victim) { int amt; if (!IS_AFFECTED(victim, AFF_CONSTRUCT)) { send_to_char("Just how do you propose to do that?\n\r", ch); return; } sprintf(buf, "repairing %s", victim->name); ch->last_taken = STRALLOC(buf); if (victim != ch) { act( AT_SKILL, "You carefully repair $N.", ch, NULL, victim, TO_CHAR); act( AT_SKILL, "$n carefully repairs you.", ch, NULL, victim, TO_VICT); act( AT_SKILL, "$n carefully repairs $N.", ch, NULL, victim, TO_NOTVICT); } else { act( AT_SKILL, "You carefully repair yourself.", ch, NULL, NULL, TO_CHAR); act( AT_SKILL, "$n carefully repairs $mself.", ch, NULL, NULL, TO_ROOM); } amt = number_range(ch->pcdata->noncombat[SK_SMITH], ch->pcdata->noncombat[SK_SMITH]*5); if (victim != ch) amt *= 2; if (!IS_FIGHTING(ch)) amt *= 2; victim->hit += amt; for (part = victim->first_part;part;part = part->next) { if (part->flags == PART_SEVERED && part->cond == PART_WELL && (part->connect_to ? part->connect_to->flags != PART_SEVERED : TRUE) && amt > 300) { act(AT_MAGIC, "You replace your $t.", victim, part_locs[part->loc], NULL, TO_CHAR); act(AT_MAGIC, "$n replaces $s $t.", victim, part_locs[part->loc], NULL, TO_ROOM); part->flags = PART_WELL; return; /* No more healing after a part is regened */ } else { part->cond = UMIN(PART_WELL, part->cond+amt/10); } } } learn_from_success( ch, gsn_repair ); } } /* ------------------ Shop Building and Editing Section ----------------- */ void do_makeshop( CHAR_DATA *ch, char *argument ) { SHOP_DATA *shop; int vnum; ROOM_INDEX_DATA *room; if ( !argument || argument[0] == '\0' ) { vnum = ch->in_room->vnum; room = ch->in_room; } else { vnum = atoi( argument ); if ( (room = get_room_index(vnum)) == NULL ) { send_to_char( "Room not found.\n\r", ch ); return; } } if ( room->pShop ) { send_to_char( "This room already has a shop.\n\r", ch ); return; } CREATE( shop, SHOP_DATA, 1 ); LINK( shop, first_shop, last_shop, next, prev ); shop->room = vnum; shop->profit_buy = 90; shop->profit_sell = 120; shop->type = -1; shop->flag = -1; shop->owner = STRALLOC("(for sale)"); shop->gold = 0; room->pShop = shop; send_to_char( "Done.\n\r", ch ); return; } void do_shopset( CHAR_DATA *ch, char *argument ) { SHOP_DATA *shop; ROOM_INDEX_DATA *room, *room2; char arg1[MAX_INPUT_LENGTH]; int vnum, value; if (IS_NPC(ch)) { huh(ch); return; } argument = one_argument( argument, arg1 ); if ( arg1[0] == '\0' ) { send_to_char( "Usage: shopset <field> value\n\r", ch ); send_to_char( "\n\rField being one of:\n\r", ch ); if (IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD)) send_to_char( " room salary sell type flag owner gold\n\r", ch ); else send_to_char( " sell salary\n\r", ch); return; } vnum = atoi( arg1 ); room = ch->in_room; if ( !room->pShop ) { send_to_char( "This room doesn't keep a shop.\n\r", ch ); return; } shop = room->pShop; value = atoi( argument ); if ( !str_cmp( arg1, "sell" ) && (IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD) || !str_cmp(ch->name, shop->owner)) ) { if ( value < 0 ) { send_to_char( "Out of range.\n\r", ch ); return; } shop->profit_sell = value; send_to_char( "The selling profit for this shop has been changed.\n\r", ch ); fold_area(ch->in_room->area, ch->in_room->area->filename, FALSE); return; } if ( !str_cmp( arg1, "salary" ) && (IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD) || !str_cmp(ch->name, shop->owner)) ) { if (shop->gold && !IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD)) { send_to_char("You can't change your shopkeeper's salary with money in the vault.\n\rWithdraw first, then change it.\n\r", ch); return; } if ( value < 0 || value > 100 ) { send_to_char( "Out of range.\n\r", ch ); return; } shop->profit_buy = value; send_to_char( "The salary for this shopkeeper has been changed.\n\r", ch ); fold_area(ch->in_room->area, ch->in_room->area->filename, FALSE); return; } if (!IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD)) { send_to_char("Invalid option.\n\r", ch); return; } if ( !str_cmp( arg1, "type" ) ) { if (!str_cmp(argument, "none")) { shop->flag = -1; } else { if ( !is_number(argument) ) value = get_otype(argument); if (value < 0 || value > MAX_ITEM_TYPE ) { send_to_char( "Invalid item type.\n\r", ch); return; } shop->type = value; } send_to_char("Done.\n\r", ch); return; } if ( !str_cmp( arg1, "flag" ) ) { if (!str_cmp(argument, "none")) { shop->flag = -1; } else { value = get_oflag(argument); if (value < 0 || value > MAX_BITS ) { send_to_char( "Invalid flag.\n\r", ch); return; } shop->flag = value; } send_to_char("Done.\n\r", ch); return; } if ( !str_cmp( arg1, "owner" ) ) { STRFREE(shop->owner); shop->owner = STRALLOC(argument); send_to_char("Done.\n\r", ch); return; } /* This doesn't work right now for some reason */ if ( !str_cmp( arg1, "room" ) ) { if ( (room2 = get_room_index(vnum)) == NULL ) { send_to_char( "Room not found.\n\r", ch ); return; } if ( room2->pShop ) { send_to_char( "That room already has a shop.\n\r", ch ); return; } room->pShop = NULL; room2->pShop = shop; shop->room = value; send_to_char( "Done.\n\r", ch ); return; } do_shopset( ch, "" ); return; } void do_shopstat( CHAR_DATA *ch, char *argument ) { SHOP_DATA *shop; ROOM_INDEX_DATA *room; int vnum, gp; struct stat fst; char buf[MAX_STRING_LENGTH]; if (IS_NPC(ch)) { huh(ch); return; } if ( argument[0] == '\0' ) { vnum = ch->in_room->vnum; room = ch->in_room; } else { vnum = atoi( argument ); if ( (room = get_room_index(vnum)) == NULL ) { send_to_char( "Room not found.\n\r", ch ); return; } } if ( !room->pShop ) { send_to_char( "This room doesn't keep a shop.\n\r", ch ); return; } shop = room->pShop; if (IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD)) ch_printf( ch, "Room: [%d] %s\n\r", shop->room, room->name ); else ch_printf( ch, "Stats for %s...\n\r", room->name ); if (!str_cmp(shop->owner, ch->name) || IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD)) { ch_printf( ch, "Profit: Salary %3d%% Sell %3d%% Vault: ", shop->profit_buy, shop->profit_sell); gp = shop->gold; ch_printf( ch, "&C%dm ", (int)gp/1000000 ); gp = gp % 1000000; ch_printf( ch, "&Y%dg ", (int)gp/10000 ); gp = gp % 10000; ch_printf( ch, "&W%ds ", (int)gp/100 ); gp = gp % 100; ch_printf( ch, "&O%dc&w\n\r", gp); } /* Clear out shops of players that no longer exist */ if (str_cmp(shop->owner, "(for sale)")) { sprintf( buf, "%s%c/%s", PLAYER_DIR, LOWER(shop->owner[0]), shop->owner ); if ( stat( buf, &fst ) == -1 ) { STRFREE(shop->owner); shop->owner = STRALLOC("(for sale)"); fold_area(ch->in_room->area, ch->in_room->area->filename, FALSE); } } ch_printf( ch, "The owner of this shop is %s.\n\r", capitalize(shop->owner)); ch_printf( ch, "This shop will sell %s %ss.\n\r", shop->flag == -1 ? "any" : o_flags[shop->flag], shop->type == -1 ? "item" : o_types[shop->type]); return; } void do_shops( CHAR_DATA *ch, char *argument ) { int gp; SHOP_DATA *shop; if (IS_NPC(ch)) { huh(ch); return; } if ( !first_shop ) { send_to_char( "There are no shops.\n\r", ch ); return; } set_char_color( AT_NOTE, ch ); if (IS_SET(ch->pcdata->permissions, PERMIT_HIBUILD)) for ( shop = first_shop; shop; shop = shop->next ) pager_printf( ch, "Room: %5d Salary: %3d Sell: %3d Type: %d Flag: %d Owner: %s\n\r", shop->room, shop->profit_buy, shop->profit_sell, shop->type, shop->flag, shop->owner); else for ( shop = first_shop; shop; shop = shop->next ) { if (!str_cmp(shop->owner, ch->name)) { pager_printf( ch, "Room: %20s in %10s Salary: %3d Sell: %3d Vault: ", get_room_index(shop->room)->name, get_room_index(shop->room)->area->name, shop->profit_buy, shop->profit_sell); gp = shop->gold; pager_printf( ch, "&C%dm ", (int)gp/1000000 ); gp = gp % 1000000; pager_printf( ch, "&Y%dg ", (int)gp/10000 ); gp = gp % 10000; pager_printf( ch, "&W%ds ", (int)gp/100 ); gp = gp % 100; pager_printf( ch, "&O%dc&w\n\r", gp); } } return; }