/***************************************************************************
* Star Wars: Rise in Power MUD Codebase *
*--------------------------------------------------------------------------*
* SWRiP Code Additions and changes from the SWReality and Smaug Code *
* copyright (c) 2001 by Mark Miller (Darrik Vequir) *
*--------------------------------------------------------------------------*
* Star Wars Reality Code Additions and changes from the Smaug Code *
* copyright (c) 1997 by Sean Cooper *
* -------------------------------------------------------------------------*
* Starwars and Starwars Names copyright(c) Lucas Film Ltd. *
*--------------------------------------------------------------------------*
* SMAUG 1.0 (C) 1994, 1995, 1996 by Derek Snider *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, *
* Scryn, Rennard, Swordbearer, Gorog, Grishnakh and Tricops *
* ------------------------------------------------------------------------ *
* 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 <ctype.h>
#include <stdarg.h>
#include <sys/stat.h>
#include "mud.h"
#define VENDOR_FEE .05 /*fee vendor charges, taken out of all gode with teh GETGOLD command*/
#define COST_EQUATION (int) (cost*cost_equation( obj ))
float cost_equation( OBJ_DATA *obj )
{
float count = obj->pIndexData->count;
count = URANGE( 50, count, 500 );
return (100/(count));
}
#if defined(KEY)
#undef KEY
#endif
#define KEY( literal, field, value ) \
if ( !strcmp( word, literal ) ) \
{ \
field = value; \
fMatch = TRUE; \
break; \
}
/*
* Local functions
*/
#define CD CHAR_DATA
CD * find_keeper args( ( CHAR_DATA *ch ) );
CD * find_keeper_q args( ( CHAR_DATA *ch, bool message ) );
CD * find_fixer args( ( CHAR_DATA *ch ) );
int get_cost args( ( CHAR_DATA *ch, CHAR_DATA *keeper,
OBJ_DATA *obj, bool fBuy ) );
int get_repaircost args( ( CHAR_DATA *keeper, OBJ_DATA *obj ) );
#undef CD
/*
* Shopping commands.
*/
CHAR_DATA *find_keeper( CHAR_DATA *ch )
{
return find_keeper_q( ch, TRUE );
}
CHAR_DATA *find_keeper_q( CHAR_DATA *ch, bool message )
{
CHAR_DATA *keeper;
SHOP_DATA *pShop;
pShop = NULL;
for ( keeper = ch->in_room->first_person;
keeper;
keeper = keeper->next_in_room )
if ( IS_NPC(keeper) && (pShop = keeper->pIndexData->pShop) != NULL )
break;
if ( !pShop )
{
if ( message )
send_to_char( "You can't do that here.\n\r", ch );
return NULL;
}
/*
* Shop hours.
*/
if ( pShop->open_hour > pShop->close_hour )
{
if( time_info.hour < pShop->open_hour && time_info.hour > pShop->close_hour )
{
do_say( keeper, "Sorry, come back later." );
return NULL;
}
}
else
if( time_info.hour < pShop->open_hour || time_info.hour > pShop->close_hour )
{
if( time_info.hour > pShop->open_hour )
{
do_say( keeper, "Sorry, come back later." );
return NULL;
}
if ( time_info.hour > pShop->close_hour )
{
do_say( keeper, "Sorry, come back tomorrow." );
return NULL;
}
}
if ( !knows_language( keeper, ch->speaking, ch ) )
{
do_say( keeper, "I can't understand you." );
return NULL;
}
return keeper;
}
/*
* repair commands.
*/
CHAR_DATA *find_fixer( CHAR_DATA *ch )
{
CHAR_DATA *keeper;
REPAIR_DATA *rShop;
rShop = NULL;
for ( keeper = ch->in_room->first_person;
keeper;
keeper = keeper->next_in_room )
if ( IS_NPC(keeper) && (rShop = keeper->pIndexData->rShop) != NULL )
break;
if ( !rShop )
{
send_to_char( "You can't do that here.\n\r", ch );
return NULL;
}
/*
* Shop hours.
*/
if ( time_info.hour < rShop->open_hour )
{
do_say( keeper, "Sorry, come back later." );
return NULL;
}
if ( time_info.hour > rShop->close_hour )
{
do_say( keeper, "Sorry, come back tomorrow." );
return NULL;
}
if ( !knows_language( keeper, ch->speaking, ch ) )
{
do_say( keeper, "I can't understand you." );
return NULL;
}
return keeper;
}
int get_cost_quit( CHAR_DATA *ch )
{
long cost = 1000;
int golddem = 100000;
long gold;
if( !ch )
return 0;
if( ch->top_level <= 6 )
return 0;
gold = ch->gold + (IS_NPC(ch) ? 0 : ch->pcdata->bank) + 1;
if( gold < 5000 )
return 0;
cost *= gold/golddem;
return (int) cost;
}
int get_cost( CHAR_DATA *ch, CHAR_DATA *keeper, OBJ_DATA *obj, bool fBuy )
{
SHOP_DATA *pShop;
int cost;
bool richcustomer;
int profitmod;
if ( !obj || ( pShop = keeper->pIndexData->pShop ) == NULL )
return 0;
if ( ( ch->gold + (IS_NPC(ch) ? 0 : ch->pcdata->bank) ) > (ch->top_level * 1000) )
richcustomer = TRUE;
else
richcustomer = FALSE;
if ( fBuy )
{
cost = (int) (cost * (80 + UMIN(ch->top_level, LEVEL_AVATAR))) / 100;
profitmod = 13 - get_curr_cha(ch) + (richcustomer ? 15 : 0)
+ ((URANGE(5,ch->top_level,LEVEL_AVATAR)-20)/2);
cost = (int) (obj->cost
* UMAX( (pShop->profit_sell+1), pShop->profit_buy+profitmod ) )
/ 100;
}
else
{
OBJ_DATA *obj2;
int itype;
profitmod = get_curr_cha(ch) - 13 - (richcustomer ? 15 : 0);
cost = 0;
for ( itype = 0; itype < MAX_TRADE; itype++ )
{
if ( obj->item_type == pShop->buy_type[itype] )
{
cost = (int) (obj->cost
* UMIN( (pShop->profit_buy-1),
pShop->profit_sell+profitmod) ) / 100;
break;
}
}
for ( obj2 = keeper->first_carrying; obj2; obj2 = obj2->next_content )
{
if ( obj->pIndexData == obj2->pIndexData )
{
cost /= (obj2->count+1);
break;
}
}
cost = UMIN( cost , 2500 );
}
if( cost > 0 )
{
cost = COST_EQUATION;
if( cost <= 0 )
cost = 1;
}
if ( obj->item_type == ITEM_ARMOR )
cost = (int) (cost * (obj->value[0]+1) / (obj->value[1]+1) );
if ( obj->item_type == ITEM_WEAPON )
{
cost = (int) (cost * (obj->value[0]+1) / INIT_WEAPON_CONDITION+1);
cost = (int) (cost * (obj->value[4]+1) / (obj->value[5]+1));
}
if ( obj->item_type == ITEM_DEVICE )
cost = (int) (cost * (obj->value[2]+1) / (obj->value[1]+1));
return cost;
}
int get_repaircost( CHAR_DATA *keeper, OBJ_DATA *obj )
{
REPAIR_DATA *rShop;
int cost;
int itype;
bool found;
if ( !obj || ( rShop = keeper->pIndexData->rShop ) == NULL )
return 0;
cost = 0;
found = FALSE;
for ( itype = 0; itype < MAX_FIX; itype++ )
{
if ( obj->item_type == rShop->fix_type[itype] )
{
cost = (int) (obj->cost * rShop->profit_fix / 100);
found = TRUE;
break;
}
}
if ( !found )
cost = -1;
if ( cost == 0 )
cost = 1;
if ( found && cost > 0 )
{
switch (obj->item_type)
{
case ITEM_ARMOR:
if (obj->value[0] >= obj->value[1])
cost = -2;
else
cost *= (obj->value[1] - obj->value[0]);
break;
case ITEM_WEAPON:
if (INIT_WEAPON_CONDITION == obj->value[0])
cost = -2;
else
cost *= (INIT_WEAPON_CONDITION - obj->value[0]);
break;
case ITEM_DEVICE:
if (obj->value[2] >= obj->value[1])
cost = -2;
else
cost *= (obj->value[1] - obj->value[2]);
}
}
return cost;
}
void do_buy( CHAR_DATA *ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
int maxgold;
argument = one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Buy what?\n\r", ch );
return;
}
if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *pet;
ROOM_INDEX_DATA *pRoomIndexNext;
ROOM_INDEX_DATA *in_room;
if ( IS_NPC(ch) )
return;
pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 );
if ( !pRoomIndexNext )
{
bug( "Do_buy: bad pet shop at vnum %d.", ch->in_room->vnum );
send_to_char( "Sorry, you can't buy that here.\n\r", ch );
return;
}
in_room = ch->in_room;
ch->in_room = pRoomIndexNext;
pet = get_char_room( ch, arg );
ch->in_room = in_room;
if ( pet == NULL || !IS_NPC( pet ) || !IS_SET(pet->act, ACT_PET) )
{
send_to_char( "Sorry, you can't buy that here.\n\r", ch );
return;
}
if ( IS_SET(ch->act, PLR_BOUGHT_PET) )
{
send_to_char( "You already bought one pet this level.\n\r", ch );
return;
}
if ( ch->gold < 10 * pet->top_level * pet->top_level )
{
send_to_char( "You can't afford it.\n\r", ch );
return;
}
if ( ch->top_level < pet->top_level )
{
send_to_char( "You're not ready for this pet.\n\r", ch );
return;
}
maxgold = 10 * pet->top_level * pet->top_level;
ch->gold -= maxgold;
boost_economy( ch->in_room->area, maxgold );
pet = create_mobile( pet->pIndexData );
// SET_BIT(ch->act, PLR_BOUGHT_PET);
SET_BIT(pet->act, ACT_PET);
SET_BIT(pet->affected_by, AFF_CHARM);
argument = one_argument( argument, arg );
if ( arg[0] != '\0' )
{
sprintf( buf, "%s %s", pet->name, arg );
STRFREE( pet->name );
pet->name = STRALLOC( buf );
}
sprintf( buf, "%sA neck tag says 'I belong to %s'.\n\r",
pet->description, ch->name );
STRFREE( pet->description );
pet->description = STRALLOC( buf );
if( ch->pcdata )
ch->pcdata->pet = pet;
char_to_room( pet, ch->in_room );
add_follower( pet, ch );
send_to_char( "Enjoy your pet.\n\r", ch );
act( AT_ACTION, "$n bought $N as a pet.", ch, NULL, pet, TO_ROOM );
return;
}
else
{
CHAR_DATA *keeper;
OBJ_DATA *obj;
int cost;
int noi = 1; /* Number of items */
sh_int mnoi = 20; /* Max number of items to be bought at once */
if ( ( keeper = find_keeper( ch ) ) == NULL )
return;
if ( keeper == NULL )
return;
maxgold = keeper->top_level * 10;
if ( is_number( arg ) )
{
noi = atoi( arg );
argument = one_argument( argument, arg );
if ( noi > mnoi )
{
act( AT_TELL, "$n tells you 'I don't sell that many items at"
" once.'", keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
return;
}
}
obj = get_obj_carry( keeper, arg );
if ( !obj && arg[0] == '#' )
{
int onum, oref;
bool ofound = FALSE;
onum =0;
oref = atoi(arg+1);
for ( obj = keeper->last_carrying; obj; obj = obj->prev_content )
{
if ( obj->wear_loc == WEAR_NONE
&& can_see_obj( ch, obj ) )
onum++;
if ( onum == oref )
{
ofound = TRUE;
break;
}
else if ( onum > oref )
break;
}
if (!ofound)
obj = NULL;
}
if ( !obj )
{
send_to_char( "Buy what?\n\r", ch );
return;
}
cost = ( get_cost( ch, keeper, obj, TRUE ) * noi );
if (keeper->home != NULL && obj->cost > 0)
cost= obj->cost;
if ( cost <= 0 || !can_see_obj( ch, obj ) )
{
act( AT_TELL, "$n tells you 'I don't sell that -- try 'list'.'",
keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
return;
}
if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) && ( noi > 1 ) )
{
interpret( keeper, "laugh" );
act( AT_TELL, "$n tells you 'I don't have enough of those in stock"
" to sell more than one at a time.'", keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
return;
}
if ( ch->gold < cost )
{
act( AT_TELL, "$n tells you 'You can't afford to buy $p.'",
keeper, obj, ch, TO_VICT );
ch->reply = keeper;
return;
}
if ( IS_SET(obj->extra_flags, ITEM_PROTOTYPE)
&& get_trust( ch ) < LEVEL_IMMORTAL )
{
act( AT_TELL, "$n tells you 'This is a only a prototype! I can't sell you that...'",
keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
return;
}
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;
}
if ( noi == 1 )
{
if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) || ( keeper->home != NULL ) )
separate_obj( obj );
act( AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM );
act( AT_ACTION, "You buy $p.", ch, obj, NULL, TO_CHAR );
}
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, "$N puts them into a bag and hands it to you.",
ch, NULL, keeper, TO_CHAR );
}
ch->gold -= cost;
keeper->gold += cost;
if ( ( keeper->gold > maxgold ) && (keeper->owner == NULL ))
{
boost_economy( keeper->in_room->area, keeper->gold - maxgold/2 );
keeper->gold = maxgold/2;
act( AT_ACTION, "$n puts some credits into a large safe.", keeper, NULL, NULL, TO_ROOM );
}
if ( IS_OBJ_STAT( obj, ITEM_INVENTORY ) && ( keeper->home == NULL ) )
{
OBJ_DATA *buy_obj, *bag;
buy_obj = create_object( obj->pIndexData, obj->level );
/*
* 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 );
/* 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 );
/* vendor snippit. Forces vendor to save after anyone buys anything*/
if ( keeper->home != NULL )
{
save_vendor (keeper);
bag->cost = 0;
}
}
else
obj_to_char( buy_obj, ch );
/* vendor snippit. Forces vendor to save after anyone buys anything*/
if ( keeper->home != NULL )
{
save_vendor (keeper);
buy_obj->cost = 0;
}
}
else
{
obj_from_char( obj );
obj_to_char( obj, ch );
/* vendor snippit. Forces vendor to save after anyone buys anything*/
if ( keeper->home != NULL )
{
save_vendor (keeper);
obj->cost = 0;
}
}
return;
}
}
void do_list( CHAR_DATA *ch, char *argument )
{
if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) )
{
ROOM_INDEX_DATA *pRoomIndexNext;
CHAR_DATA *pet;
bool found;
pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 );
if ( !pRoomIndexNext )
{
bug( "Do_list: bad pet shop at vnum %d.", ch->in_room->vnum );
send_to_char( "You can't do that here.\n\r", ch );
return;
}
found = FALSE;
for ( pet = pRoomIndexNext->first_person; pet; pet = pet->next_in_room )
{
if ( IS_SET(pet->act, ACT_PET) && IS_NPC(pet) )
{
if ( !found )
{
found = TRUE;
send_to_char( "Pets for sale:\n\r", ch );
}
ch_printf( ch, "[%2d] %8d - %s\n\r",
pet->top_level,
10 * pet->top_level * pet->top_level,
pet->short_descr );
}
}
if ( !found )
send_to_char( "Sorry, we're out of pets right now.\n\r", ch );
return;
}
else
{
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *keeper;
OBJ_DATA *obj;
int cost;
int oref = 0;
bool found;
one_argument( argument, arg );
if ( ( keeper = find_keeper( ch ) ) == NULL )
return;
found = FALSE;
for ( obj = keeper->last_carrying; obj; obj = obj->prev_content )
{
if ( obj->wear_loc == WEAR_NONE
&& can_see_obj( ch, obj ) )
{
oref++;
if ( ( cost = get_cost( ch, keeper, obj, TRUE ) ) > 0
&& ( arg[0] == '\0' || nifty_is_name( arg, obj->name ) ) )
{
if (keeper->home != NULL)
cost = obj->cost;
if ( !found )
{
found = TRUE;
send_to_char( "[Price] {ref} Item\n\r", ch );
}
ch_printf( ch, "[%5d] {%3d} %s%s.\n\r",
cost, oref, capitalize( obj->short_descr ),
IS_SET(obj->extra_flags, ITEM_HUTT_SIZE) ? " (hutt size)" :
( IS_SET(obj->extra_flags, ITEM_LARGE_SIZE) ? " (large)" :
( IS_SET(obj->extra_flags, ITEM_HUMAN_SIZE) ? " (medium)" :
( IS_SET(obj->extra_flags, ITEM_SMALL_SIZE) ? " (small)" :
"" ) ) ) );
}
}
}
if ( !found )
{
if ( arg[0] == '\0' )
send_to_char( "You can't buy anything here.\n\r", ch );
else
send_to_char( "You can't buy that here.\n\r", ch );
}
return;
}
}
void do_sell( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *keeper;
OBJ_DATA *obj;
int cost;
bool spice = FALSE;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Sell what?\n\r", ch );
return;
}
if ( ( keeper = find_keeper( ch ) ) == NULL )
return;
if ( ( obj = get_obj_carry( ch, arg ) ) == NULL )
{
act( AT_TELL, "$n tells you 'You don't have that item.'",
keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
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 )
{
act( AT_TELL, "$n tells you, '$p is depreciating in value too quickly...'", keeper, obj, ch, TO_VICT );
return;
}
if ( ( cost = get_cost( ch, keeper, obj, FALSE ) ) <= 0 )
{
act( AT_ACTION, "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT );
return;
}
if( obj->item_type == ITEM_SPICE )
spice = TRUE;
if ( cost > keeper->gold && ( economy_has( ch->in_room->area, cost) || spice ) )
{
act( AT_TELL, "$n makes a credit transaction.", keeper, obj, ch, TO_VICT );
lower_economy( ch->in_room->area, cost-keeper->gold );
}
if ( !economy_has( ch->in_room->area, cost ) && !spice )
{
act( AT_ACTION, "$n can not afford $p right now.", keeper, obj, ch, TO_VICT );
return;
}
separate_obj( obj );
act( AT_ACTION, "$n sells $p.", ch, obj, NULL, TO_ROOM );
sprintf( buf, "You sell $p for %d credit%s.",
cost, cost == 1 ? "" : "s" );
act( AT_ACTION, buf, ch, obj, NULL, TO_CHAR );
ch->gold += cost;
keeper->gold -= cost;
if ( spice )
boost_economy( ch->in_room->area, cost*1.5);
if ( keeper->gold < 0 )
keeper->gold = 0;
if ( obj->item_type == ITEM_TRASH )
extract_obj( obj );
else if ( IS_SET( obj->extra_flags , ITEM_CONTRABAND) )
{
long ch_exp;
ch_exp = UMIN( obj->cost*10 , ( exp_level( ch->skill_level[SMUGGLING_ABILITY]+1) - exp_level( ch->skill_level[SMUGGLING_ABILITY]) ) / 10 );
ch_printf( ch, "You receive %ld smuggling experience for unloading your contraband.\n\r " , ch_exp );
gain_exp( ch, ch_exp , SMUGGLING_ABILITY );
if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE )
extract_obj( obj );
else
{
REMOVE_BIT( obj->extra_flags , ITEM_CONTRABAND );
obj_from_char( obj );
obj_to_char( obj, keeper );
}
}
else if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE )
extract_obj( obj );
else
{
obj_from_char( obj );
obj_to_char( obj, keeper );
}
return;
}
void do_value( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *keeper;
OBJ_DATA *obj;
int cost;
if ( argument[0] == '\0' )
{
send_to_char( "Value what?\n\r", ch );
return;
}
if ( ( keeper = find_keeper( ch ) ) == NULL )
return;
if ( ( obj = get_obj_carry( ch, argument ) ) == NULL )
{
act( AT_TELL, "$n tells you 'You don't have that item.'",
keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
return;
}
if ( !can_drop_obj( ch, obj ) )
{
send_to_char( "You can't let go of it!\n\r", ch );
return;
}
if ( ( cost = get_cost( ch, keeper, obj, FALSE ) ) <= 0 )
{
act( AT_ACTION, "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT );
return;
}
sprintf( buf, "$n tells you 'I'll give you %d credits for $p.'", cost );
act( AT_TELL, buf, keeper, obj, ch, TO_VICT );
ch->reply = keeper;
return;
}
/*
* Repair a single object. Used when handling "repair all" - Gorog
*/
void repair_one_obj( CHAR_DATA *ch, CHAR_DATA *keeper, OBJ_DATA *obj,
char *arg, int maxgold, char *fixstr, char*fixstr2 )
{
char buf[MAX_STRING_LENGTH];
int cost;
if ( !can_drop_obj( ch, obj ) )
ch_printf( ch, "You can't let go of %s.\n\r", obj->name );
else if ( ( cost = get_repaircost( keeper, obj ) ) < 0 )
{
if (cost != -2)
act( AT_TELL, "$n tells you, 'Sorry, I can't do anything with $p.'",
keeper, obj, ch, TO_VICT );
else
act( AT_TELL, "$n tells you, '$p looks fine to me!'", keeper, obj, ch, TO_VICT );
}
/* "repair all" gets a 10% surcharge - Gorog */
else if ( (cost = strcmp("all",arg) ? cost : 11*cost/10) > ch->gold )
{
sprintf( buf,
"$N tells you, 'It will cost %d credit%s to %s %s...'", cost,
cost == 1 ? "" : "s", fixstr, obj->name );
act( AT_TELL, buf, ch, NULL, keeper, TO_CHAR );
act( AT_TELL, "$N tells you, 'Which I see you can't afford.'", ch,
NULL, keeper, TO_CHAR );
}
else
{
sprintf( buf, "$n gives $p to $N, who quickly %s it.", fixstr2 );
act( AT_ACTION, buf, ch, obj, keeper, TO_ROOM );
sprintf( buf, "$N charges you %d credit%s to %s $p.",
cost, cost == 1 ? "" : "s", fixstr );
act( AT_ACTION, buf, ch, obj, keeper, TO_CHAR );
ch->gold -= cost;
keeper->gold += cost;
if ( keeper->gold < 0 )
keeper->gold = 0;
else
if ( keeper->gold > maxgold )
{
boost_economy( keeper->in_room->area, keeper->gold - maxgold/2 );
keeper->gold = maxgold/2;
act( AT_ACTION, "$n puts some credits into a large safe.", keeper,
NULL, NULL, TO_ROOM );
}
switch ( obj->item_type )
{
default:
send_to_char( "For some reason, you think you got ripped off...\n\r", ch);
break;
case ITEM_ARMOR:
obj->value[0] = obj->value[1];
break;
case ITEM_WEAPON:
obj->value[0] = INIT_WEAPON_CONDITION;
break;
case ITEM_DEVICE:
obj->value[2] = obj->value[1];
break;
}
oprog_repair_trigger( ch, obj );
}
}
void do_repair( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *keeper;
OBJ_DATA *obj;
char *fixstr;
char *fixstr2;
int maxgold;
if ( argument[0] == '\0' )
{
send_to_char( "Repair what?\n\r", ch );
return;
}
if ( ( keeper = find_fixer( ch ) ) == NULL )
return;
maxgold = keeper->top_level * 10;
switch( keeper->pIndexData->rShop->shop_type )
{
default:
case SHOP_FIX:
fixstr = "repair";
fixstr2 = "repairs";
break;
case SHOP_RECHARGE:
fixstr = "recharge";
fixstr2 = "recharges";
break;
}
if ( !strcmp( argument, "all" ) )
{
for ( obj = ch->first_carrying; obj ; obj = obj->next_content )
{
if ( obj->wear_loc == WEAR_NONE
&& can_see_obj( ch, obj )
&& ( obj->item_type == ITEM_ARMOR
|| obj->item_type == ITEM_WEAPON
|| obj->item_type == ITEM_DEVICE ) )
repair_one_obj( ch, keeper, obj, argument, maxgold,
fixstr, fixstr2);
}
return;
}
if ( ( obj = get_obj_carry( ch, argument ) ) == NULL )
{
act( AT_TELL, "$n tells you 'You don't have that item.'",
keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
return;
}
repair_one_obj( ch, keeper, obj, argument, maxgold, fixstr, fixstr2); }
void appraise_all( CHAR_DATA *ch, CHAR_DATA *keeper, char *fixstr )
{
OBJ_DATA *obj;
char buf[MAX_STRING_LENGTH], *pbuf=buf;
int cost, total=0;
for ( obj = ch->first_carrying; obj != NULL ; obj = obj->next_content )
{
if ( obj->wear_loc == WEAR_NONE
&& can_see_obj( ch, obj )
&& ( obj->item_type == ITEM_ARMOR
|| obj->item_type == ITEM_WEAPON
|| obj->item_type == ITEM_DEVICE ) )
{
if ( !can_drop_obj( ch, obj ) )
ch_printf( ch, "You can't let go of %s.\n\r", obj->name );
else if ( ( cost = get_repaircost( keeper, obj ) ) < 0 )
{
if (cost != -2)
act( AT_TELL,
"$n tells you, 'Sorry, I can't do anything with $p.'",
keeper, obj, ch, TO_VICT );
else
act( AT_TELL, "$n tells you, '$p looks fine to me!'",
keeper, obj, ch, TO_VICT );
}
else
{
sprintf( buf,
"$N tells you, 'It will cost %d credit%s to %s %s'",
cost, cost == 1 ? "" : "s", fixstr, obj->name );
act( AT_TELL, buf, ch, NULL, keeper, TO_CHAR );
total += cost;
}
}
}
if ( total > 0 )
{
send_to_char ("\n\r", ch);
sprintf( buf,
"$N tells you, 'It will cost %d credit%s in total.'",
total, cost == 1 ? "" : "s" );
act( AT_TELL, buf, ch, NULL, keeper, TO_CHAR );
strcpy( pbuf,
"$N tells you, 'Remember there is a 10% surcharge for repair all.'");
act( AT_TELL, buf, ch, NULL, keeper, TO_CHAR );
}
}
void do_appraise( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
CHAR_DATA *keeper;
OBJ_DATA *obj;
int cost;
char *fixstr;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char( "Appraise what?\n\r", ch );
return;
}
if ( ( keeper = find_fixer( ch ) ) == NULL )
return;
switch( keeper->pIndexData->rShop->shop_type )
{
default:
case SHOP_FIX:
fixstr = "repair";
break;
case SHOP_RECHARGE:
fixstr = "recharge";
break;
}
if ( !strcmp( arg, "all") )
{
appraise_all( ch, keeper, fixstr );
return;
}
if ( ( obj = get_obj_carry( ch, arg ) ) == NULL )
{
act( AT_TELL, "$n tells you 'You don't have that item.'",
keeper, NULL, ch, TO_VICT );
ch->reply = keeper;
return;
}
if ( !can_drop_obj( ch, obj ) )
{
send_to_char( "You can't let go of it.\n\r", ch );
return;
}
if ( ( cost = get_repaircost( keeper, obj ) ) < 0 )
{
if (cost != -2)
act( AT_TELL, "$n tells you, 'Sorry, I can't do anything with $p.'", keeper, obj, ch, TO_VICT );
else
act( AT_TELL, "$n tells you, '$p looks fine to me!'", keeper, obj, ch, TO_VICT );
return;
}
sprintf( buf,
"$N tells you, 'It will cost %d credit%s to %s that...'", cost,
cost == 1 ? "" : "s", fixstr );
act( AT_TELL, buf, ch, NULL, keeper, TO_CHAR );
if ( cost > ch->gold )
act( AT_TELL, "$N tells you, 'Which I see you can't afford.'", ch,
NULL, keeper, TO_CHAR );
return;
}
/* ------------------ Shop Building and Editing Section ----------------- */
void do_makeshop( CHAR_DATA *ch, char *argument )
{
SHOP_DATA *shop;
sh_int vnum;
MOB_INDEX_DATA *mob;
if ( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: makeshop <mobvnum>\n\r", ch );
return;
}
vnum = atoi( argument );
if ( (mob = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !can_medit(ch, mob) )
return;
if ( mob->pShop )
{
send_to_char( "This mobile already has a shop.\n\r", ch );
return;
}
CREATE( shop, SHOP_DATA, 1 );
LINK( shop, first_shop, last_shop, next, prev );
shop->keeper = vnum;
shop->profit_buy = 120;
shop->profit_sell = 90;
shop->open_hour = 0;
shop->close_hour = 23;
mob->pShop = shop;
send_to_char( "Done.\n\r", ch );
return;
}
void do_shopset( CHAR_DATA *ch, char *argument )
{
SHOP_DATA *shop;
MOB_INDEX_DATA *mob, *mob2;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
sh_int vnum;
int value;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char( "Usage: shopset <mob vnum> <field> value\n\r", ch );
send_to_char( "\n\rField being one of:\n\r", ch );
send_to_char( " buy0 buy1 buy2 buy3 buy4 buy sell open close keeper\n\r", ch );
return;
}
vnum = atoi( arg1 );
if ( (mob = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !can_medit(ch, mob) )
return;
if ( !mob->pShop )
{
send_to_char( "This mobile doesn't keep a shop.\n\r", ch );
return;
}
shop = mob->pShop;
value = atoi( argument );
if ( !str_cmp( arg2, "buy0" ) )
{
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->buy_type[0] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "buy1" ) )
{
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->buy_type[1] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "buy2" ) )
{
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->buy_type[2] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "buy3" ) )
{
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->buy_type[3] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "buy4" ) )
{
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->buy_type[4] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "buy" ) )
{
if ( value <= (shop->profit_sell+5) || value > 1000 )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
shop->profit_buy = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "sell" ) )
{
if ( value < 0 || value >= (shop->profit_buy-5) )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
shop->profit_sell = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "open" ) )
{
if ( value < 0 || value > 23 )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
shop->open_hour = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "close" ) )
{
if ( value < 0 || value > 23 )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
shop->close_hour = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "keeper" ) )
{
if ( (mob2 = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !can_medit(ch, mob) )
return;
if ( mob2->pShop )
{
send_to_char( "That mobile already has a shop.\n\r", ch );
return;
}
mob->pShop = NULL;
mob2->pShop = shop;
shop->keeper = value;
send_to_char( "Done.\n\r", ch );
return;
}
do_shopset( ch, "" );
return;
}
void do_shopstat( CHAR_DATA *ch, char *argument )
{
SHOP_DATA *shop;
MOB_INDEX_DATA *mob;
sh_int vnum;
if ( argument[0] == '\0' )
{
send_to_char( "Usage: shopstat <keeper vnum>\n\r", ch );
return;
}
vnum = atoi( argument );
if ( (mob = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !mob->pShop )
{
send_to_char( "This mobile doesn't keep a shop.\n\r", ch );
return;
}
shop = mob->pShop;
ch_printf( ch, "Keeper: %d %s\n\r", shop->keeper, mob->short_descr );
ch_printf( ch, "buy0 [%s] buy1 [%s] buy2 [%s] buy3 [%s] buy4 [%s]\n\r",
o_types[shop->buy_type[0]],
o_types[shop->buy_type[1]],
o_types[shop->buy_type[2]],
o_types[shop->buy_type[3]],
o_types[shop->buy_type[4]] );
ch_printf( ch, "Profit: buy %3d%% sell %3d%%\n\r",
shop->profit_buy,
shop->profit_sell );
ch_printf( ch, "Hours: open %2d close %2d\n\r",
shop->open_hour,
shop->close_hour );
return;
}
void do_shops( CHAR_DATA *ch, char *argument )
{
SHOP_DATA *shop;
if ( !first_shop )
{
send_to_char( "There are no shops.\n\r", ch );
return;
}
set_char_color( AT_NOTE, ch );
for ( shop = first_shop; shop; shop = shop->next )
ch_printf( ch, "Keeper: %5d Buy: %3d Sell: %3d Open: %2d Close: %2d Buy: %2d %2d %2d %2d %2d\n\r",
shop->keeper, shop->profit_buy, shop->profit_sell,
shop->open_hour, shop->close_hour,
shop->buy_type[0], shop->buy_type[1],
shop->buy_type[2], shop->buy_type[3], shop->buy_type[4] );
return;
}
/* -------------- Repair Shop Building and Editing Section -------------- */
void do_makerepair( CHAR_DATA *ch, char *argument )
{
REPAIR_DATA *repair;
sh_int vnum;
MOB_INDEX_DATA *mob;
if ( !argument || argument[0] == '\0' )
{
send_to_char( "Usage: makerepair <mobvnum>\n\r", ch );
return;
}
vnum = atoi( argument );
if ( (mob = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !can_medit(ch, mob) )
return;
if ( mob->rShop )
{
send_to_char( "This mobile already has a repair shop.\n\r", ch );
return;
}
CREATE( repair, REPAIR_DATA, 1 );
LINK( repair, first_repair, last_repair, next, prev );
repair->keeper = vnum;
repair->profit_fix = 100;
repair->shop_type = SHOP_FIX;
repair->open_hour = 0;
repair->close_hour = 23;
mob->rShop = repair;
send_to_char( "Done.\n\r", ch );
return;
}
void do_repairset( CHAR_DATA *ch, char *argument )
{
REPAIR_DATA *repair;
MOB_INDEX_DATA *mob, *mob2;
char arg1[MAX_INPUT_LENGTH];
char arg2[MAX_INPUT_LENGTH];
sh_int vnum;
int value;
argument = one_argument( argument, arg1 );
argument = one_argument( argument, arg2 );
if ( arg1[0] == '\0' || arg2[0] == '\0' )
{
send_to_char( "Usage: repairset <mob vnum> <field> value\n\r", ch );
send_to_char( "\n\rField being one of:\n\r", ch );
send_to_char( " fix0 fix1 fix2 profit type open close keeper\n\r", ch );
return;
}
vnum = atoi( arg1 );
if ( (mob = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !can_medit(ch, mob) )
return;
if ( !mob->rShop )
{
send_to_char( "This mobile doesn't keep a repair shop.\n\r", ch );
return;
}
repair = mob->rShop;
value = atoi( argument );
if ( !str_cmp( arg2, "fix0" ) )
{
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;
}
repair->fix_type[0] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "fix1" ) )
{
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;
}
repair->fix_type[1] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "fix2" ) )
{
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;
}
repair->fix_type[2] = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "profit" ) )
{
if ( value < 1 || value > 1000 )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
repair->profit_fix = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "type" ) )
{
if ( value < 1 || value > 2 )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
repair->shop_type = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "open" ) )
{
if ( value < 0 || value > 23 )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
repair->open_hour = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "close" ) )
{
if ( value < 0 || value > 23 )
{
send_to_char( "Out of range.\n\r", ch );
return;
}
repair->close_hour = value;
send_to_char( "Done.\n\r", ch );
return;
}
if ( !str_cmp( arg2, "keeper" ) )
{
if ( (mob2 = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !can_medit(ch, mob) )
return;
if ( mob2->rShop )
{
send_to_char( "That mobile already has a repair shop.\n\r", ch );
return;
}
mob->rShop = NULL;
mob2->rShop = repair;
repair->keeper = value;
send_to_char( "Done.\n\r", ch );
return;
}
do_repairset( ch, "" );
return;
}
void do_repairstat( CHAR_DATA *ch, char *argument )
{
REPAIR_DATA *repair;
MOB_INDEX_DATA *mob;
sh_int vnum;
if ( argument[0] == '\0' )
{
send_to_char( "Usage: repairstat <keeper vnum>\n\r", ch );
return;
}
vnum = atoi( argument );
if ( (mob = get_mob_index(vnum)) == NULL )
{
send_to_char( "Mobile not found.\n\r", ch );
return;
}
if ( !mob->rShop )
{
send_to_char( "This mobile doesn't keep a repair shop.\n\r", ch );
return;
}
repair = mob->rShop;
ch_printf( ch, "Keeper: %d %s\n\r", repair->keeper, mob->short_descr );
ch_printf( ch, "fix0 [%s] fix1 [%s] fix2 [%s]\n\r",
o_types[repair->fix_type[0]],
o_types[repair->fix_type[1]],
o_types[repair->fix_type[2]] );
ch_printf( ch, "Profit: %3d%% Type: %d\n\r",
repair->profit_fix,
repair->shop_type );
ch_printf( ch, "Hours: open %2d close %2d\n\r",
repair->open_hour,
repair->close_hour );
return;
}
void do_repairshops( CHAR_DATA *ch, char *argument )
{
REPAIR_DATA *repair;
if ( !first_repair )
{
send_to_char( "There are no repair shops.\n\r", ch );
return;
}
set_char_color( AT_NOTE, ch );
for ( repair = first_repair; repair; repair = repair->next )
ch_printf( ch, "Keeper: %5d Profit: %3d Type: %d Open: %2d Close: %2d Fix: %2d %2d %2d\n\r",
repair->keeper, repair->profit_fix, repair->shop_type,
repair->open_hour, repair->close_hour,
repair->fix_type[0], repair->fix_type[1], repair->fix_type[2] );
return;
}
/*This is the command used to buy a contract from a vendor to place a player
owned vendor
*/
void do_buyvendor (CHAR_DATA *ch, char *argument)
{
CHAR_DATA *keeper;
OBJ_DATA *deed;
char buf[MAX_STRING_LENGTH];
char buf1[MAX_STRING_LENGTH];
char strsave[MAX_INPUT_LENGTH];
struct stat fst;
if (IS_NPC(ch))
return;
if ( !str_cmp( argument, "yes" ) )
{
sprintf( buf, "%s/%s", VENDOR_DIR, capitalize( ch->name ) );
remove( buf );
}
sprintf( strsave, "%s/%s", VENDOR_DIR, capitalize( ch->name ) );
if ( stat( strsave, &fst ) != -1 )
{
send_to_char( "You already have a shop!\n\r", ch);
send_to_char( "If you want to buy one anyway, type buyvendor yes.\n\r", ch);
send_to_char( "Your old one will be deleted.\n\r", ch);
return;
}
if ( (keeper = find_keeper_q( ch, FALSE ) ) == NULL )
{
send_to_char ("There is no one to buy that from!\n\r", ch);
return;
}
if ( ch->gold < COST_BUY_VENDOR )
{
sprintf(buf1, "%s says, You are too poor!\n\r", keeper->name);
send_to_char (buf1, ch);
return;
}
if ( (ch->top_level) < LEVEL_BUY_VENDOR )
{
sprintf (buf1, "you must be at least %d level.\n\r", LEVEL_BUY_VENDOR);
send_to_char (buf1, ch);
return;
}
if ( (get_obj_index (OBJ_VNUM_DEED) ) == NULL )
{
bug ("BUYVENDOR: Deed is missing!");
return;
}
deed = create_object ( get_obj_index(OBJ_VNUM_DEED), 0);
obj_to_char (deed, ch);
send_to_char_color ("&bVery well, you may have a contract for a vendor.\n\r", ch);
ch->gold = ch->gold - COST_BUY_VENDOR;
}
/*this is the command that places the vendor at the specified location*/
void do_placevendor (CHAR_DATA *ch, char *argument)
{
char strsave[MAX_INPUT_LENGTH];
struct stat fst;
CHAR_DATA *vendor;
MOB_INDEX_DATA *temp;
OBJ_DATA *obj;
char vnum1[MAX_INPUT_LENGTH];
char buf [MAX_INPUT_LENGTH];
if ( find_keeper_q (ch, FALSE) )
{
send_to_char ("A vendor is already here!\n\r",ch);
return;
}
if ( IS_NPC(ch) )
return;
/* better way to do this? what if they have another object called deed?*/
if ( ( obj = get_obj_carry( ch, "deed" ) ) == NULL )
{
send_to_char( "You do not have a deed!.\n\r", ch );
return;
}
if (obj->pIndexData->vnum != OBJ_VNUM_DEED)
{
send_to_char( "You do not have a deed!.\n\r", ch );
return;
}
if (!IS_SET(ch->in_room->room_flags, ROOM_PLR_SHOP) )
{
send_to_char( "You need to find a free shop.\n\r", ch);
return;
}
sprintf( strsave, "%s/%s", VENDOR_DIR, capitalize( ch->name ) );
if ( stat( strsave, &fst ) != -1 )
{
send_to_char( "You already have a shop!\n\r", ch);
return;
}
if ( (temp = get_mob_index (MOB_VNUM_VENDOR) ) == NULL )
{
log_string ("do_placevendor: no vendor vnum");
return;
}
char_to_room( create_mobile( temp ), ch->in_room );
vendor = get_char_room(ch, temp->player_name);
sprintf (buf, vendor->long_descr, ch->name);
vendor->long_descr = STRALLOC( buf );
sprintf (buf, "%s", ch->name);
vendor->owner = STRALLOC(buf);
vendor->home = ch->in_room;
save_vendor (vendor);
separate_obj( obj );
extract_obj( obj );
act( AT_ACTION, "$n appears in a swirl of smoke.\n", vendor, NULL, NULL, TO_ROOM );
sprintf(vnum1,"%d", vendor->pIndexData->vnum);
do_makeshop (vendor, vnum1 ); /*makes the vendor a shop.. there has to be a
better way to do it but hell if i know what it is!*/
}
void do_pricevendor (CHAR_DATA *ch, char *argument)
{
CHAR_DATA *vendor;
CHAR_DATA *ch1;
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char logbuf[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
struct tm *tms;
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if ( arg1[0] == '\0' )
{
send_to_char("usage:> pricevendor <item> <cost>\n\r",ch);
return;
}
if (arg2[0] == '\0')
{
send_to_char("usage:> pricevendor <item> <cost>\n\r",ch);
return;
}
if ( ( vendor = find_keeper (ch) ) == NULL )
{
return;
}
if ( !(vendor->owner) )
return;
if ( (ch1 = get_char_room(ch, vendor->owner)) == NULL )
{
send_to_char ("This isnt your vendor!\n\r",ch);
return;
}
if ( str_cmp( ch1->name, vendor->owner ) )
{
send_to_char ("Trying to steal huh?\n\r",ch);
tms = localtime(¤t_time);
tms->tm_hour += 24;
ch->pcdata->release_date = mktime(tms);
ch->pcdata->helled_by = STRALLOC("VendorCheat");
act(AT_MAGIC, "$n disappears in a cloud of hellish light.", ch, NULL, ch, TO_NOTVICT);
char_from_room(ch);
char_to_room(ch, get_room_index(6));
act(AT_MAGIC, "$n appears in a could of hellish light.", ch, NULL, ch, TO_NOTVICT);
do_look(ch, "auto");
ch_printf(ch, "The immortals are not pleased with your actions.\n\r"
"You shall remain in hell for 24 Hours.\n\r");
save_char_obj(ch); /* used to save ch, fixed by Thoric 09/17/96 */
sprintf( logbuf , "%s just tried to abuse the vendor bug!" , ch->name);
log_string( logbuf );
return;
}
if ( ch->fighting)
{
send_to_char ("Not while you fightZ!\n\r",ch);
return;
}
if ( (obj = get_obj_carry( vendor, arg1 )) != NULL)
{
obj->cost = atoi (arg2);
send_to_char("The price has been changed\n\r",ch);
save_vendor(vendor);
return;
}
send_to_char("He doesnt have that item!\n\r",ch);
save_vendor(vendor);
return;
}
void do_collectgold (CHAR_DATA *ch, char *argument)
{
CHAR_DATA *vendor;
CHAR_DATA *ch1;
long gold;
char buf [MAX_INPUT_LENGTH];
char logbuf [MAX_INPUT_LENGTH];
char name[MAX_INPUT_LENGTH];
struct tm *tms;
if ( ( vendor = find_keeper (ch) ) == NULL )
{
return;
}
if (vendor->owner == NULL)
{
send_to_char("thats not a vendor!\n\r",ch);
return;
}
sprintf(name, "%s", vendor->owner);
if ( (ch1 = get_char_room(ch, vendor->owner)) == NULL )
{
send_to_char ("Trying to steal huh?\n\r",ch);
return;
}
if ( str_cmp( ch1->name, vendor->owner ) )
{
send_to_char ("Trying to steal huh?\n\r",ch);
tms = localtime(¤t_time);
tms->tm_hour += 24;
ch->pcdata->release_date = mktime(tms);
ch->pcdata->helled_by = STRALLOC("VendorCheat");
act(AT_MAGIC, "$n disappears in a cloud of hellish light.", ch, NULL, ch, TO_NOTVICT);
char_from_room(ch);
char_to_room(ch, get_room_index(6));
act(AT_MAGIC, "$n appears in a could of hellish light.", ch, NULL, ch, TO_NOTVICT);
do_look(ch, "auto");
ch_printf(ch, "The immortals are not pleased with your actions.\n\r"
"You shall remain in hell for 24 Hours.\n\r");
save_char_obj(ch); /* used to save ch, fixed by Thoric 09/17/96 */
sprintf( logbuf , "%s just tried to abuse the vendor bug!" , ch->name);
log_string( logbuf );
return;
}
if ( !(ch == ch1) )
{
sprintf (buf, "collectgold: %s and ch1 = %s\n\r", name, ch1->name);
log_string (buf);
send_to_char ("This isnt your vendor!\n\r",ch);
return;
}
if ( ch->fighting)
{
send_to_char ("Not while you fightZ!\n\r",ch);
return;
}
gold = vendor->gold;
gold -= (gold * VENDOR_FEE);
if( vendor->in_room && vendor->in_room->area )
boost_economy( vendor->in_room->area, vendor->gold);
vendor->gold = 0;
ch->gold += gold;
send_to_char_color ("&GYour vendor gladly hands over his earnings minus a small fee of course..\n\r",ch);
act( AT_ACTION, "$n hands over some money.\n\r", vendor, NULL, NULL, TO_ROOM );
}
/* Write vendor to file */
void fwrite_vendor( FILE *fp, CHAR_DATA *mob )
{
if ( !IS_NPC( mob ) || !fp )
return;
fprintf( fp, "Vnum %d\n", mob->pIndexData->vnum );
if (mob->gold > 0)
fprintf (fp, "Gold %d\n",mob->gold);
if ( mob->home )
fprintf( fp, "Home %d\n", mob->home->vnum );
if (mob->owner != NULL )
fprintf (fp, "Owner %s~\n", mob->owner );
if ( QUICKMATCH( mob->short_descr, mob->pIndexData->short_descr) == 0 )
fprintf( fp, "Short %s~\n", mob->short_descr );
fprintf( fp, "Position %d\n", mob->position );
fprintf( fp, "Flags %d\n", mob->act );
fprintf( fp, "END\n" );
return;
}
/* read vendor from file */
CHAR_DATA * fread_vendor( FILE *fp )
{
CHAR_DATA *mob = NULL;
char *word;
bool fMatch;
int inroom = 0;
ROOM_INDEX_DATA *pRoomIndex = NULL;
CHAR_DATA *victim;
CHAR_DATA *vnext;
char buf [MAX_INPUT_LENGTH];
char vnum1 [MAX_INPUT_LENGTH];
word = feof( fp ) ? "END" : fread_word( fp );
if ( !strcmp(word, "Vnum") )
{
int vnum;
vnum = fread_number( fp );
mob = create_mobile( get_mob_index(vnum));
if ( !mob )
{
for ( ; ; )
{
word = feof( fp ) ? "END" : fread_word( fp );
if ( !strcmp( word, "END" ) )
break;
}
bug("Fread_mobile: No index data for vnum %d", vnum );
return NULL;
}
}
else
{
for ( ; ; )
{
word = feof( fp ) ? "END" : fread_word( fp );
if ( !strcmp( word, "END" ) )
break;
}
extract_char(mob, TRUE);
bug("Fread_vendor: Vnum not found", 0 );
return NULL;
}
for ( ; ;) {
word = feof( fp ) ? "END" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER(word[0]) ) {
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case '#':
if ( !strcmp( word, "#OBJECT" ) )
{
fread_obj ( mob, fp, OS_CARRY );
}
break;
case 'D':
KEY( "Description", mob->description, fread_string(fp));
break;
case 'E':
if ( !strcmp( word, "END" ) )
{
if ( inroom == 0 )
inroom = ROOM_VNUM_VENSTOR;
mob->home = get_room_index(inroom);
pRoomIndex = get_room_index( inroom );
if ( !pRoomIndex )
{
pRoomIndex = get_room_index( ROOM_VNUM_VENSTOR );
mob->home = get_room_index( ROOM_VNUM_VENSTOR );
}
mob->in_room = pRoomIndex;
/* the following code is to make sure no more then one player owned vendor
is in the room - meckteck */
for ( victim = mob->in_room->first_person; victim; victim = vnext )
{
vnext = victim->next_in_room;
if (victim->home != NULL)
{
extract_char( victim, TRUE);
break;
}
}
char_to_room(mob, pRoomIndex);
sprintf(vnum1,"%d", mob->pIndexData->vnum);
do_makeshop (mob, vnum1 );
sprintf (buf, mob->long_descr, mob->owner);
mob->long_descr = STRALLOC( buf );
mob->hit = 10000;
mob->max_hit = 10000;
return mob;
}
break;
case 'F':
KEY( "Flags", mob->act, fread_number(fp));
break;
case 'G':
KEY("Gold", mob->gold, fread_number(fp));
break;
case 'H':
KEY("Home", inroom, fread_number(fp) );
break;
case 'L':
break;
case 'N':
break;
case 'O':
KEY ("Owner", mob->owner, fread_string (fp) );
break;
case 'P':
KEY( "Position", mob->position, fread_number( fp ) );
break;
case 'S':
KEY( "Short", mob->short_descr, fread_string(fp));
break;
}
if ( !fMatch )
{
bug ( "Fread_mobile: no match.", 0 );
bug ( word, 0 );
}
}
return NULL;
}
void save_vendor( CHAR_DATA *ch )
{
char strsave[MAX_INPUT_LENGTH];
FILE *fp;
if ( !ch )
{
bug( "Save_char_obj: null ch!", 0 );
return;
}
de_equip_char( ch );
sprintf( strsave, "%s%s",VENDOR_DIR, capitalize( ch->owner ) );
if ( ( fp = fopen( strsave, "w" ) ) == NULL )
{
perror( strsave );
bug( "Save_vendor: fopen", 0 );
}
else
{
bool ferr;
fchmod(fileno(fp), S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | S_IROTH|S_IWOTH);
fprintf( fp, "#VENDOR\n" );
fwrite_vendor( fp, ch );
if ( ch->first_carrying )
fwrite_obj( ch, ch->last_carrying, fp, 0, OS_CARRY );
fprintf(fp, "#END\n" );
ferr = ferror(fp);
fclose( fp );
if (ferr)
{
perror(strsave);
bug("Error writing temp file for %s -- not copying", strsave);
}
}
re_equip_char( ch );
return;
}