/*****************************************************************************
* DikuMUD (C) 1990, 1991 by: *
* Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, *
* and Katja Nyboe. *
*---------------------------------------------------------------------------*
* MERC 2.1 (C) 1992, 1993 by: *
* Michael Chastain, Michael Quan, and Mitchell Tse. *
*---------------------------------------------------------------------------*
* SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. *
* Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, *
* gorog, Grishnakh, Nivek, Tricops, and Fireblade. *
*---------------------------------------------------------------------------*
* SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. *
* Their contributions are greatly appreciated. *
*---------------------------------------------------------------------------*
* LoP (C) 2006, 2007, 2008 by: the LoP team. *
*---------------------------------------------------------------------------*
* Quest *
*****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "h/mud.h"
void increase_gold( CHAR_DATA *ch, int amount );
void show_obj( CHAR_DATA *ch, OBJ_DATA *obj );
/* See if the character has killed the specified mobile vnum already */
int has_killed( CHAR_DATA *ch, int vnum )
{
int track;
if( !ch || !ch->pcdata )
return 0;
for( track = 0; track < MAX_KILLTRACK; track++ )
{
if( !ch->pcdata->killed[track].vnum || ch->pcdata->killed[track].vnum != vnum )
continue;
return ch->pcdata->killed[track].count;
}
return 0;
}
bool can_quest_room( CHAR_DATA *ch, ROOM_INDEX_DATA *room )
{
if( !room->first_exit || !room->area )
return false;
if( xIS_SET( room->room_flags, ROOM_DEATH )
|| xIS_SET( room->room_flags, ROOM_SAFE ) || xIS_SET( room->room_flags, ROOM_SOLITARY )
|| xIS_SET( room->room_flags, ROOM_PET_SHOP ) || xIS_SET( room->room_flags, ROOM_DONATION )
|| xIS_SET( room->room_flags, ROOM_PRIVATE ) || xIS_SET( room->area->flags, AFLAG_NOQUEST )
|| ch->level < room->area->low_hard_range || ch->level > room->area->hi_hard_range )
return false;
return true;
}
/* Can this mobile used for a quest? */
bool can_quest_mobile( CHAR_DATA *ch, CHAR_DATA *questman, CHAR_DATA *victim )
{
int leveldiff;
if( !ch || !victim )
return false;
if( !is_npc( victim ) || !can_see( ch, victim ) )
return false;
if( victim == ch || victim == questman )
return false;
if( !victim->in_room || !victim->in_room->first_exit )
return false;
leveldiff = ( victim->level - ch->level );
if( leveldiff < -5 || leveldiff > 10 )
return false;
if( xIS_SET( victim->act, ACT_PACIFIST ) || xIS_SET( victim->act, ACT_PROTOTYPE )
|| is_safe( ch, victim, false ) || xIS_SET( victim->in_room->area->flags, AFLAG_NOQUEST ) )
return false;
if( victim->pIndexData->pShop || victim->pIndexData->rShop )
return false;
if( !can_quest_room( ch, victim->in_room ) )
return false;
return true;
}
/* Should the player quest for the object? */
bool can_quest_object( CHAR_DATA *ch, OBJ_DATA *olist, OBJ_DATA *obj )
{
OBJ_DATA *cobj;
for( cobj = olist; cobj; cobj = cobj->next_content )
{
/* If they already have a copy of the object no point in bothering with it */
if( cobj->pIndexData == obj->pIndexData )
return false;
if( cobj->first_content )
if( !can_quest_object( ch, cobj->first_content, obj ) )
return false;
}
return true;
}
void reward_quest( CHAR_DATA *ch, CHAR_DATA *victim )
{
char buf[MSL];
int qpoints = 0, gold = 0, practices = 0;
if( !ch || !victim )
return;
qpoints = number_range( 3, 10 );
ch->pcdata->quest_curr += qpoints;
if( number_percent( ) < 25 )
{
gold = number_range( 100, 500 );
increase_gold( ch, gold );
}
if( number_percent( ) < 10 )
{
practices = number_range( 1, 3 );
ch->practice += practices;
}
if( gold > 0 && practices > 0 )
snprintf( buf, sizeof( buf ), "tell 0.%s As a reward I'm going to give you %d quest points, %d gold, and %d practices.", ch->name, qpoints, gold, practices );
else if( gold > 0 )
snprintf( buf, sizeof( buf ), "tell 0.%s As a reward I'm going to give you %d quest points and %d gold.", ch->name, qpoints, gold );
else if( practices > 0 )
snprintf( buf, sizeof( buf ), "tell 0.%s As a reward I'm going to give you %d quest points and %d practices.", ch->name, qpoints, practices );
else
snprintf( buf, sizeof( buf ), "tell 0.%s As a reward I'm going to give you %d quest points", ch->name, qpoints );
interpret( victim, buf );
}
void complete_quest( CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj )
{
char buf[MSL];
if( !ch )
return;
ch->questgiver = 0;
ch->questvnum = 0;
ch->questcountdown = 20;
ch->questtype = 0;
ch->pcdata->questcompleted++;
xREMOVE_BIT( ch->act, PLR_QUESTOR );
if( victim )
{
if( obj )
{
separate_obj( obj );
obj_from_char( obj );
obj_to_char( obj, victim );
snprintf( buf, sizeof( buf ), "tell 0.%s Thank you for bringing me %s.", ch->name, obj->short_descr );
interpret( victim, buf );
extract_obj( obj );
}
else
{
snprintf( buf, sizeof( buf ), "tell 0.%s Thank you for taking care of that problem for me.", ch->name );
interpret( victim, buf );
}
reward_quest( ch, victim );
snprintf( buf, sizeof( buf ), "tell 0.%s If you come back in 20 minutes I might have more for you to do.", ch->name );
interpret( victim, buf );
}
save_char_obj( ch );
}
void assign_quest( CHAR_DATA *ch, CHAR_DATA *questman )
{
CHAR_DATA *victim = NULL;
ROOM_INDEX_DATA *qroom = NULL;
OBJ_DATA *obj, *iobj = NULL;
char buf[MSL];
if( !ch || is_npc( ch ) )
return;
if( ch->questcountdown > 0 )
{
if( xIS_SET( ch->act, PLR_QUESTOR ) )
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but you're already on a quest.", ch->name );
else
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but you still have %d minutes till you can quest again.", ch->name, ch->questcountdown );
interpret( questman, buf );
return;
}
/* Lets toss through the list of objects and see if we can find one to have them quest for */
for( obj = first_object; obj; obj = obj->next )
{
iobj = NULL;
victim = NULL;
qroom = NULL;
if( number_percent( ) > 10 )
continue;
if( !can_see_obj( ch, obj ) || can_wear( obj, ITEM_NO_TAKE ) )
continue;
if( !can_quest_object( ch, ch->first_carrying, obj ) )
continue;
/* Should we kill someone for an object they have? */
if( ( victim = obj->carried_by ) )
{
if( !can_quest_mobile( ch, questman, victim ) )
continue;
else
break;
}
/* Should we look for the object in a room? */
else if( ( qroom = obj->in_room ) )
{
if( !can_quest_room( ch, qroom ) )
continue;
else
break;
}
else if( ( iobj = obj->in_obj ) )
{
bool scontinue = false;
while( iobj->in_obj )
{
if( !can_see_obj( ch, iobj ) )
{
scontinue = true;
break;
}
iobj = iobj->in_obj;
}
if( scontinue )
continue;
if( ( victim = iobj->carried_by ) )
{
if( !can_quest_mobile( ch, questman, victim ) )
continue;
else
break;
}
else if( ( qroom = iobj->in_room ) )
{
if( !can_quest_room( ch, qroom ) )
continue;
else
break;
}
}
else /* object not in a room, carried by someone or in an object */
continue;
}
/* Maybe we can find a mobile to let them kill */
if( !obj )
{
for( victim = first_char; victim; victim = victim->next )
{
if( number_percent( ) > 20 )
continue;
if( !is_npc( victim ) )
continue;
if( has_killed( ch, victim->pIndexData->vnum ) > 0 )
continue;
if( !can_quest_mobile( ch, questman, victim ) )
continue;
else
break;
}
}
if( !obj && !victim )
{
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but I don't need anything at this time.", ch->name );
interpret( questman, buf );
snprintf( buf, sizeof( buf ), "tell 0.%s Check back in 5 minutes to see if I need anything.", ch->name );
interpret( questman, buf );
ch->questcountdown = 5;
return;
}
if( obj )
{
snprintf( buf, sizeof( buf ), "tell 0.%s I'm looking for %s.", ch->name, obj->short_descr );
interpret( questman, buf );
if( qroom )
{
if( !qroom->area )
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it at %s.", ch->name, qroom->name );
else
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it at %s in %s.", ch->name, qroom->name, qroom->area->name );
interpret( questman, buf );
}
else if( victim )
{
if( !victim->in_room || !victim->in_room->area )
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it on %s.", ch->name, PERS( victim, ch ) );
else
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it on %s in %s.", ch->name, PERS( victim, ch ),
victim->in_room->area->name );
interpret( questman, buf );
}
else if( iobj )
{
if( ( victim = iobj->carried_by ) )
{
if( victim->in_room && victim->in_room->area )
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it in %s on %s in %s.", ch->name, iobj->short_descr,
PERS( victim, ch ), victim->in_room->area->name );
else
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it in %s on %s.", ch->name, iobj->short_descr,
PERS( victim, ch ) );
}
else if( ( qroom = iobj->in_room ) )
{
if( qroom->area )
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it in %s at %s in %s.", ch->name, iobj->short_descr, qroom->name, qroom->area->name );
else
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it in %s at %s.", ch->name, iobj->short_descr, qroom->name );
}
else
snprintf( buf, sizeof( buf ), "tell 0.%s Look for it in %s.", ch->name, iobj->short_descr );
interpret( questman, buf );
}
ch->questcountdown = number_range( 10, 20 );
ch->questvnum = obj->pIndexData->vnum;
ch->questtype = 1; /* Object */
snprintf( buf, sizeof( buf ), "tell 0.%s You have %d minutes to bring me it.", ch->name, ch->questcountdown );
interpret( questman, buf );
}
else /* Mobile quest here */
{
ch->questcountdown = number_range( 10, 20 );
ch->questvnum = victim->pIndexData->vnum;
ch->questtype = 2; /* Mobile */
snprintf( buf, sizeof( buf ), "tell 0.%s You have %d minutes to kill %s. Look for %s in %s.", ch->name,
ch->questcountdown, PERS( victim, ch ), him_her[victim->sex], victim->in_room->area->name );
interpret( questman, buf );
}
xSET_BIT( ch->act, PLR_QUESTOR );
ch->questgiver = questman->pIndexData->vnum;
save_char_obj( ch );
}
CHAR_DATA *find_questgiver( CHAR_DATA *ch )
{
CHAR_DATA *questgiver = NULL;
for( questgiver = ch->in_room->first_person; questgiver; questgiver = questgiver->next_in_room )
{
if( is_npc( questgiver ) && xIS_SET( questgiver->act, ACT_QUESTGIVER ) )
break;
}
return questgiver;
}
CMDF( do_aquest )
{
CHAR_DATA *questgiver;
MOB_INDEX_DATA *questmob;
OBJ_DATA *obj;
char buf[MSL];
if( !ch || is_npc( ch ) )
return;
if( !argument || argument[0] == '\0' )
{
if( ch->questcountdown > 0 )
{
if( xIS_SET( ch->act, PLR_QUESTOR ) )
{
OBJ_INDEX_DATA *oindex;
if( ch->questtype == 1 )
{
if( !( oindex = get_obj_index( ch->questvnum ) ) )
{
ch->questgiver = 0;
ch->questvnum = 0;
ch->questcountdown = 0;
ch->questtype = 0;
xREMOVE_BIT( ch->act, PLR_QUESTOR );
send_to_char( "The object you were questing for no longer exist.\r\n", ch );
send_to_char( "Quest has been removed and you may quest again.\r\n", ch );
save_char_obj( ch );
return;
}
ch_printf( ch, "You're currently on a quest to bring back %s.\r\n", oindex->short_descr );
}
else if( ch->questtype == 2 )
{
if( !( questmob = get_mob_index( ch->questvnum ) ) )
{
ch->questgiver = 0;
ch->questvnum = 0;
ch->questcountdown = 0;
ch->questtype = 0;
xREMOVE_BIT( ch->act, PLR_QUESTOR );
send_to_char( "The mobile you were questing for no longer exist.\r\n", ch );
send_to_char( "Quest has been removed and you may quest again.\r\n", ch );
save_char_obj( ch );
return;
}
ch_printf( ch, "You're currently on a quest to kill %s.\r\n", questmob->short_descr );
}
ch_printf( ch, "You have %d minute%s left to complete the quest.\r\n", ch->questcountdown,
ch->questcountdown == 1 ? "" : "s" );
}
else
ch_printf( ch, "You have %d minute%s till you can quest again.\r\n", ch->questcountdown,
ch->questcountdown == 1 ? "" : "s" );
}
else
send_to_char( "You aren't currently on a quest.\r\n", ch );
return;
}
if( !( questgiver = find_questgiver( ch ) ) )
{
send_to_char( "You aren't at a questgiver.\r\n", ch );
return;
}
if( !str_cmp( argument, "request" ) )
{
assign_quest( ch, questgiver );
return;
}
if( !str_cmp( argument, "complete" ) )
{
if( !xIS_SET( ch->act, PLR_QUESTOR ) )
{
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but you aren't on a quest.", ch->name );
interpret( questgiver, buf );
return;
}
else if( questgiver->pIndexData->vnum != ch->questgiver )
{
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but I never sent you on a quest.", ch->name );
interpret( questgiver, buf );
return;
}
if( ch->questtype == 1 )
{
for( obj = ch->first_carrying; obj; obj = obj->next_content )
{
separate_obj( obj );
if( obj->wear_loc != WEAR_NONE )
continue;
if( obj->pIndexData->vnum == ch->questvnum )
{
complete_quest( ch, questgiver, obj );
return;
}
}
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but you don't seem to have the item im wanting.", ch->name );
interpret( questgiver, buf );
}
else if( ch->questtype == 2 )
{
if( has_killed( ch, ch->questvnum ) > 0 )
{
complete_quest( ch, questgiver, NULL );
return;
}
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but you haven't killed the one I wanted yet.", ch->name );
interpret( questgiver, buf );
}
snprintf( buf, sizeof( buf ), "tell 0.%s You have %d minute%s left to complete the quest.",
ch->name, ch->questcountdown, ch->questcountdown == 1 ? "" : "s" );
interpret( questgiver, buf );
return;
}
if( !str_cmp( argument, "cancel" ) )
{
if( !xIS_SET( ch->act, PLR_QUESTOR ) )
{
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but you aren't on a quest.", ch->name );
interpret( questgiver, buf );
return;
}
else if( questgiver->pIndexData->vnum != ch->questgiver )
{
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry, but I never sent you on a quest.", ch->name );
interpret( questgiver, buf );
return;
}
ch->questgiver = 0;
ch->questvnum = 0;
ch->questcountdown = 20;
ch->questtype = 0;
xREMOVE_BIT( ch->act, PLR_QUESTOR );
snprintf( buf, sizeof( buf ), "tell 0.%s I'm sorry you aren't going to finish the quest.", ch->name );
interpret( questgiver, buf );
snprintf( buf, sizeof( buf ), "tell 0.%s Check back in 20 minutes to see if I need anything.", ch->name );
interpret( questgiver, buf );
save_char_obj( ch );
return;
}
send_to_char( "Usage: aquest [request/cancel/complete]\r\n", ch );
}
void quest_update( void )
{
CHAR_DATA *ch;
MOB_INDEX_DATA *victim;
OBJ_INDEX_DATA *oindex;
static int quest_update_time;
if( --quest_update_time > 0 )
return;
/* Should be around 1 minute per update */
quest_update_time = ( 60 * PULSE_PER_SECOND );
for( ch = first_char; ch; ch = ch->next )
{
if( is_npc( ch ) || ch->questcountdown == 0 )
continue;
if( ch->questtype == 1 && ch->questvnum != 0 && !( oindex = get_obj_index( ch->questvnum ) ) )
{
ch->questgiver = 0;
ch->questvnum = 0;
ch->questcountdown = 0;
ch->questtype = 0;
xREMOVE_BIT( ch->act, PLR_QUESTOR );
send_to_char( "The object you were questing for no longer exist.\r\n", ch );
send_to_char( "Quest has been removed and you may quest again.\r\n", ch );
save_char_obj( ch );
return;
}
else if( ch->questtype == 2 && ch->questvnum != 0 && !( victim = get_mob_index( ch->questvnum ) ) )
{
ch->questgiver = 0;
ch->questvnum = 0;
ch->questcountdown = 0;
ch->questtype = 0;
xREMOVE_BIT( ch->act, PLR_QUESTOR );
send_to_char( "The mobile you were questing for no longer exist.\r\n", ch );
send_to_char( "Quest has been removed and you may quest again.\r\n", ch );
save_char_obj( ch );
return;
}
if( --ch->questcountdown == 0 )
{
if( xIS_SET( ch->act, PLR_QUESTOR ) )
{
ch->questcountdown = 20;
ch_printf( ch, "You have ran out of time for the quest!\r\nYou can quest again in %d minutes.\r\n", ch->questcountdown );
xREMOVE_BIT( ch->act, PLR_QUESTOR );
ch->questgiver = 0;
ch->questvnum = 0;
ch->questtype = 0;
save_char_obj( ch );
}
else
send_to_char( "You may now quest again.\r\n", ch );
}
else if( ch->questcountdown < 6 && xIS_SET( ch->act, PLR_QUESTOR ) )
ch_printf( ch, "Better hurry! You only have %d minute%s left to complete the quest.\r\n", ch->questcountdown,
ch->questcountdown == 1 ? "" : "s" );
}
}
#define REWARD_FILE SYSTEM_DIR "rewards.dat"
typedef struct reward_data REWARD_DATA;
struct reward_data
{
REWARD_DATA *next, *prev;
int vnum;
int qpcost;
};
REWARD_DATA *first_reward, *last_reward;
void save_rewards( void )
{
REWARD_DATA *reward;
FILE *fp;
if( !first_reward )
{
remove_file( REWARD_FILE );
return;
}
if( !( fp = fopen( REWARD_FILE, "w" ) ) )
{
bug( "%s: Can't open %s for writing.", __FUNCTION__, REWARD_FILE );
perror( REWARD_FILE );
return;
}
for( reward = first_reward; reward; reward = reward->next )
fprintf( fp, "Reward %5d %5d\n", reward->vnum, reward->qpcost );
fprintf( fp, "%s", "End\n" );
fclose( fp );
fp = NULL;
}
void free_reward( REWARD_DATA *reward )
{
if( !reward )
return;
UNLINK( reward, first_reward, last_reward, next, prev );
DISPOSE( reward );
}
void free_rewards( void )
{
while( last_reward )
free_reward( last_reward );
}
void add_reward( int vnum, int qpcost )
{
REWARD_DATA *reward;
CREATE( reward, REWARD_DATA, 1 );
reward->vnum = vnum;
reward->qpcost = qpcost;
LINK( reward, first_reward, last_reward, next, prev );
}
void load_rewards( void )
{
FILE *fp;
first_reward = last_reward = NULL;
if( !( fp = fopen( REWARD_FILE, "r" ) ) )
return;
for( ;; )
{
char *word;
if( feof( fp ) )
break;
word = fread_word( fp );
if( word[0] == EOF )
break;
if( !str_cmp( word, "Reward" ) )
{
int vnum = fread_number( fp );
int qpcost = fread_number( fp );
if( get_obj_index( vnum ) )
add_reward( vnum, qpcost );
continue;
}
else if( !str_cmp( word, "End" ) )
break;
else
{
bug( "%s: bad section (%s).", __FUNCTION__, word );
fread_to_eol( fp );
continue;
}
}
fclose( fp );
fp = NULL;
}
REWARD_DATA *find_reward( int vnum )
{
REWARD_DATA *reward;
for( reward = first_reward; reward; reward = reward->next )
if( reward->vnum == vnum )
return reward;
return NULL;
}
CMDF( do_showrewards )
{
REWARD_DATA *reward;
int cnt = 0, col = 0;
for( reward = first_reward; reward; reward = reward->next )
{
if( ++cnt == 1 )
{
send_to_char( "-----------------------------------------------------------------\r\n", ch );
ch_printf( ch, "| %6s %6s | %6s %6s | %6s %6s | %6s %6s |\r\n", "Vnum", "QPCost", "Vnum", "QPCost",
"Vnum", "QPCost", "Vnum", "QPCost" );
send_to_char( "-----------------------------------------------------------------\r\n", ch );
}
ch_printf( ch, " %6d %6d ", reward->vnum, reward->qpcost );
if( ++col == 4 )
{
col = 0;
send_to_char( "\r\n", ch );
}
}
if( col != 0 )
send_to_char( "\r\n", ch );
ch_printf( ch, "There %s currently %d reward%s.\r\n", cnt == 1 ? "is" : "are", cnt, cnt == 1 ? "" : "s" );
}
CMDF( do_reward )
{
REWARD_DATA *reward;
OBJ_INDEX_DATA *oindex;
OBJ_DATA *obj;
CHAR_DATA *questgiver = NULL;
char arg[MSL];
int cnt = 0, value = 0;
if( !( questgiver = find_questgiver( ch ) ) )
{
send_to_char( "You aren't at a questgiver.\r\n", ch );
return;
}
if( !argument || argument[0] == '\0' )
{
for( reward = first_reward; reward; reward = reward->next )
{
if( !( oindex = get_obj_index( reward->vnum ) ) || !oindex->short_descr )
continue;
ch_printf( ch, "%3d> %6d - %s\r\n", ++cnt, reward->qpcost, oindex->short_descr );
}
if( !cnt )
send_to_char( "There are currently no rewards.\r\n", ch );
return;
}
argument = one_argument( argument, arg );
if( ( value = atoi( arg ) ) <= 0 )
{
send_to_char( "Usage: reward <#>.\r\n", ch );
return;
}
for( reward = first_reward; reward; reward = reward->next )
{
if( !( oindex = get_obj_index( reward->vnum ) ) || !oindex->short_descr )
continue;
if( ++cnt == value )
break;
}
if( !reward )
{
send_to_char( "No such reward.\r\n", ch );
return;
}
if( str_cmp( argument, "buy" ) )
{
if( !( obj = create_object( get_obj_index( reward->vnum ), 0 ) ) )
{
send_to_char( "There was a problem creating the object.\r\n", ch );
return;
}
ch_printf( ch, "%3d> %6d - %s", value, reward->qpcost, obj->short_descr );
show_obj( ch, obj );
send_to_char( "Use 'reward <#> buy' if you wish to buy this reward.\r\n", ch );
extract_obj( obj );
return;
}
if( reward->qpcost > ch->pcdata->quest_curr )
{
send_to_char( "You don't have enough quest points to get that reward yet.\r\n", ch );
return;
}
if( !( obj = create_object( get_obj_index( reward->vnum ), 0 ) ) )
{
send_to_char( "There was a problem creating the object.\r\n", ch );
return;
}
xSET_BIT( obj->extra_flags, ITEM_QUEST );
if( !( obj = obj_to_char( obj, ch ) ) )
{
send_to_char( "There was a problem in giving you the object.\r\n", ch );
return;
}
ch->pcdata->quest_curr -= reward->qpcost;
ch_printf( ch, "You have traded %d quest points for reward #%d.\r\n", reward->qpcost, value );
save_char_obj( ch );
}
CMDF( do_setreward )
{
REWARD_DATA *reward;
char arg[MIL], arg2[MIL];
int vnum = 0, value = 0;
argument = one_argument( argument, arg );
if( arg == NULL || arg[0] == '\0' )
{
send_to_char( "Usage: setreward create <vnum> <qpcost>\r\n", ch );
send_to_char( "Usage: setreward delete <vnum>\r\n", ch );
send_to_char( "Usage: setreward <vnum> vnum/qpcost <value>\r\n", ch );
return;
}
argument = one_argument( argument, arg2 );
if( arg2 == NULL || arg2[0] == '\0' )
{
do_setreward( ch, (char *)"" );
return;
}
if( !str_cmp( arg, "delete" ) )
{
vnum = atoi( arg2 );
if( !( reward = find_reward( vnum ) ) )
{
send_to_char( "There is no such reward using that vnum.\r\n", ch );
return;
}
free_reward( reward );
save_rewards( );
send_to_char( "The reward has been deleted.\r\n", ch );
return;
}
if( !str_cmp( arg, "create" ) )
{
vnum = atoi( arg2 );
if( !get_obj_index( vnum ) )
{
send_to_char( "No object is using that vnum.\r\n", ch );
return;
}
if( ( reward = find_reward( vnum ) ) )
{
send_to_char( "There is already a reward using that vnum.\r\n", ch );
return;
}
if( ( value = atoi( argument ) ) <= 0 )
{
send_to_char( "Usage: setreward create <vnum> <qpcost>\r\n", ch );
return;
}
add_reward( vnum, value );
save_rewards( );
send_to_char( "The reward has been added.\r\n", ch );
return;
}
if( !( reward = find_reward( atoi( arg ) ) ) )
{
send_to_char( "There is no reward using that vnum.\r\n", ch );
return;
}
if( !str_cmp( arg2, "vnum" ) )
{
if( ( vnum = atoi( argument ) ) <= 0 )
{
send_to_char( "Usage: setreward <vnum> vnum <new vnum>.\r\n", ch );
return;
}
if( !get_obj_index( vnum ) )
{
send_to_char( "No object is using that vnum.\r\n", ch );
return;
}
reward->vnum = vnum;
save_rewards( );
send_to_char( "That reward's vnum has been changed.\r\n", ch );
return;
}
if( !str_cmp( arg2, "qpcost" ) )
{
if( ( value = atoi( argument ) ) <= 0 )
{
send_to_char( "Usage: setreward <vnum> qpcost <qpcost>.\r\n", ch );
return;
}
reward->qpcost = value;
save_rewards( );
send_to_char( "That reward's qpcost has been changed.\r\n", ch );
return;
}
do_setreward( ch, (char *)"" );
}
CMDF( do_useglory )
{
OBJ_DATA *obj;
AFFECT_DATA *paf;
char arg1[MSL];
int value;
argument = one_argument( argument, arg1 );
if( arg1 == NULL || arg1[0] == '\0' )
{
send_to_char( "What would you like to use glory on and for?\r\n", ch );
return;
}
if( !( obj = get_obj_carry( ch, arg1 ) ) )
{
send_to_char( "You do not have that item.\r\n", ch );
return;
}
argument = one_argument( argument, arg1 );
separate_obj( obj );
if( is_obj_stat( obj, ITEM_PROTOTYPE ) )
{
send_to_char( "You can't use glory on this object.\r\n", ch );
return;
}
if( obj->wear_loc != WEAR_NONE )
{
send_to_char( "You must remove it first.\r\n", ch );
return;
}
if( !str_cmp( arg1, "weight" ) )
{
if( obj->weight <= 1 )
{
send_to_char( "No point in reduceing the weight of that object.\r\n", ch );
return;
}
if( ch->pcdata->quest_curr < 100 )
{
send_to_char( "You don't have the 100 glory required.\r\n", ch );
return;
}
obj->weight = 1;
ch->pcdata->quest_curr -= 100;
save_char_obj( ch );
send_to_char( "The object's weight has been reduced to 1.\r\n", ch );
return;
}
if( !str_cmp( arg1, "glow" ) )
{
if( ch->pcdata->quest_curr < 5 )
{
send_to_char( "You don't have the 5 glory required.\r\n", ch );
return;
}
xTOGGLE_BIT( obj->extra_flags, ITEM_GLOW );
ch->pcdata->quest_curr -= 5;
save_char_obj( ch );
if( is_obj_stat( obj, ITEM_GLOW ) )
send_to_char( "The item now glows.\r\n", ch );
else
send_to_char( "The item stops glowing.\r\n", ch );
return;
}
if( !str_cmp( arg1, "noscrap" ) )
{
if( ch->pcdata->quest_curr < 500 )
{
send_to_char( "You don't have the 500 glory required.\r\n", ch );
return;
}
if( is_obj_stat( obj, ITEM_NOSCRAP ) )
{
send_to_char( "This object already resist scrapping.\r\n", ch );
return;
}
xSET_BIT( obj->extra_flags, ITEM_NOSCRAP );
ch->pcdata->quest_curr -= 500;
save_char_obj( ch );
send_to_char( "The object will now resist scrapping.\r\n", ch );
return;
}
if( !str_cmp( arg1, "resist" ) )
{
if( ch->pcdata->quest_curr < 500 )
{
send_to_char( "You don't have the 500 glory required.\r\n", ch );
return;
}
value = get_flag( argument, ris_flags, RIS_MAX );
if( value < 0 || value >= RIS_MAX )
{
ch_printf( ch, "Unknown resistant: %s\r\n", argument );
return;
}
for( paf = obj->first_affect; paf; paf = paf->next )
{
if( paf->location == APPLY_RESISTANT && paf->modifier == value )
{
send_to_char( "The object already has an affect to help you resist that.\r\n", ch );
return;
}
}
paf = NULL;
CREATE( paf, AFFECT_DATA, 1 );
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_RESISTANT;
paf->modifier = value;
xCLEAR_BITS( paf->bitvector );
paf->next = NULL;
LINK( paf, obj->first_affect, obj->last_affect, next, prev );
ch->pcdata->quest_curr -= 500;
save_char_obj( ch );
send_to_char( "The object will now help you resist that.\r\n", ch );
return;
}
if( !str_cmp( arg1, "affect" ) )
{
if( ch->pcdata->quest_curr < 400 )
{
send_to_char( "You don't have the 400 glory required.\r\n", ch );
return;
}
value = get_flag( argument, a_flags, AFF_MAX );
if( value <= 0 || value >= AFF_MAX )
{
ch_printf( ch, "Unknown affect: %s\r\n", argument );
return;
}
/* Only allow these here */
if( value != AFF_INVISIBLE && value != AFF_DETECT_EVIL && value != AFF_DETECT_INVIS
&& value != AFF_DETECT_MAGIC && value != AFF_DETECT_HIDDEN && value != AFF_INFRARED
&& value != AFF_SNEAK && value != AFF_HIDE && value != AFF_FLYING && value != AFF_PASS_DOOR
&& value != AFF_FLOATING && value != AFF_DETECTTRAPS && value != AFF_SCRYING
&& value != AFF_AQUA_BREATH && value != AFF_DETECT_SNEAK )
{
ch_printf( ch, "Unknown affect: %s\r\n", argument );
return;
}
for( paf = obj->first_affect; paf; paf = paf->next )
{
if( paf->location == APPLY_EXT_AFFECT && paf->modifier == value )
{
send_to_char( "The object already has that affect.\r\n", ch );
return;
}
}
paf = NULL;
CREATE( paf, AFFECT_DATA, 1 );
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_EXT_AFFECT;
paf->modifier = value;
xCLEAR_BITS( paf->bitvector );
paf->next = NULL;
LINK( paf, obj->first_affect, obj->last_affect, next, prev );
ch->pcdata->quest_curr -= 400;
save_char_obj( ch );
send_to_char( "The object now has that affect.\r\n", ch );
return;
}
if( !str_cmp( arg1, "armor" ) )
{
if( ch->pcdata->quest_curr < 50 )
{
send_to_char( "You don't have the 50 glory required.\r\n", ch );
return;
}
for( paf = obj->first_affect; paf; paf = paf->next )
{
if( paf->location == APPLY_ARMOR )
break;
}
if( !paf )
{
paf = NULL;
CREATE( paf, AFFECT_DATA, 1 );
paf->type = -1;
paf->duration = -1;
paf->location = APPLY_ARMOR;
paf->modifier = 1;
xCLEAR_BITS( paf->bitvector );
paf->next = NULL;
LINK( paf, obj->first_affect, obj->last_affect, next, prev );
}
else
paf->modifier += 1;
ch->pcdata->quest_curr -= 50;
save_char_obj( ch );
send_to_char( "The object now affects your armor class more.\r\n", ch );
return;
}
}