/***************************************************************************** * 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 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 ); void complete_quest( CHAR_DATA *ch, CHAR_DATA *victim, OBJ_DATA *obj ) { char buf[MSL]; int qpoints = 0, practices = 0, gold = 0; if( !ch ) return; ch->questgiver = 0; ch->questvnum = 0; ch->questcountdown = 20; xREMOVE_BIT( ch->act, PLR_QUESTOR ); if( victim && obj ) { snprintf( buf, sizeof( buf ), "0.%s Thank you for bringing me %s.", ch->name, obj->short_descr ); do_tell( victim, buf ); 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 ), "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 ), "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 ), "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 ), "0.%s As a reward I'm going to give you %d quest points", ch->name, qpoints ); do_tell( victim, buf ); } } void assign_quest( CHAR_DATA *ch, CHAR_DATA *questman ) { char buf[MSL]; CHAR_DATA *victim = NULL; int leveldiff; AREA_DATA *qarea = NULL; ROOM_INDEX_DATA *qroom = NULL; OBJ_DATA *obj, *iobj = NULL; if( !ch || is_npc( ch ) ) return; if( ch->questcountdown > 0 ) { if( xIS_SET( ch->act, PLR_QUESTOR ) ) snprintf( buf, sizeof( buf ), "0.%s I'm sorry, but you are already on a quest.", ch->name ); else snprintf( buf, sizeof( buf ), "0.%s I'm sorry, but you aren't able to quest again yet.", ch->name ); do_tell( 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( ) > 20 ) continue; if( !can_see_obj( ch, obj ) || can_wear( obj, ITEM_NO_TAKE ) ) continue; /* Should we kill someone for an object they have? */ if( ( victim = obj->carried_by ) ) { if( !is_npc( victim ) || !can_see( ch, victim ) ) continue; if( victim == ch || victim == questman ) continue; if( !victim->in_room || !victim->in_room->first_exit ) continue; leveldiff = ( victim->level - ch->level ); if( leveldiff < -5 || leveldiff > 10 ) continue; if( xIS_SET( victim->act, ACT_PACIFIST ) || xIS_SET( victim->act, ACT_PROTOTYPE ) || ch == victim || is_safe( ch, victim, false ) || xIS_SET( victim->in_room->area->flags, AFLAG_NOQUEST ) ) continue; break; } /* Should we look for the object in a room? */ else if( ( qroom = obj->in_room ) ) { if( !qroom->first_exit ) continue; if( xIS_SET( qroom->room_flags, ROOM_DEATH ) || xIS_SET( qroom->room_flags, ROOM_PROTOTYPE ) || xIS_SET( qroom->room_flags, ROOM_SAFE ) || xIS_SET( qroom->room_flags, ROOM_SOLITARY ) || xIS_SET( qroom->room_flags, ROOM_PET_SHOP ) || xIS_SET( qroom->room_flags, ROOM_DONATION ) || xIS_SET( qroom->room_flags, ROOM_PRIVATE ) || xIS_SET( qroom->area->flags, AFLAG_NOQUEST ) || ch->level < qroom->area->low_hard_range || ch->level > qroom->area->hi_hard_range ) continue; break; } else if( ( iobj = obj->in_obj ) ) { bool scontinue = false; while( iobj->in_obj ) { if( !can_see_obj( ch, iobj ) ) scontinue = true; iobj = iobj->in_obj; } if( scontinue ) continue; if( ( victim = iobj->carried_by ) ) { if( !is_npc( victim ) || !can_see( ch, victim ) ) continue; if( victim == ch || victim == questman ) continue; if( !victim->in_room || !victim->in_room->first_exit ) continue; leveldiff = ( victim->level - ch->level ); if( leveldiff < -5 || leveldiff > 10 ) continue; if( xIS_SET( victim->act, ACT_PACIFIST ) || xIS_SET( victim->act, ACT_PROTOTYPE ) || ch == victim || is_safe( ch, victim, false ) || xIS_SET( victim->in_room->area->flags, AFLAG_NOQUEST ) ) continue; break; } else if( ( qroom = iobj->in_room ) ) { if( !qroom->first_exit ) continue; if( xIS_SET( qroom->room_flags, ROOM_DEATH ) || xIS_SET( qroom->room_flags, ROOM_PROTOTYPE ) || xIS_SET( qroom->room_flags, ROOM_SAFE ) || xIS_SET( qroom->room_flags, ROOM_SOLITARY ) || xIS_SET( qroom->room_flags, ROOM_PET_SHOP ) || xIS_SET( qroom->room_flags, ROOM_DONATION ) || xIS_SET( qroom->room_flags, ROOM_PRIVATE ) || xIS_SET( qroom->area->flags, AFLAG_NOQUEST ) || ch->level < qroom->area->low_hard_range || ch->level > qroom->area->hi_hard_range ) continue; break; } } } /* Lets toss through the list of objects found in areas and see if we can find one to have them quest for */ if( !obj ) { for( qarea = first_area; qarea; qarea = qarea->next ) { obj = NULL; iobj = NULL; qroom = NULL; victim = NULL; if( xIS_SET( qarea->flags, AFLAG_NOQUEST ) ) continue; if( ch->level < qarea->low_hard_range || ch->level > qarea->hi_hard_range ) continue; for( qroom = qarea->first_room; qroom; qroom = qroom->next_aroom ) { if( !qroom->first_exit ) continue; if( xIS_SET( qroom->room_flags, ROOM_DEATH ) || xIS_SET( qroom->room_flags, ROOM_PROTOTYPE ) || xIS_SET( qroom->room_flags, ROOM_SAFE ) || xIS_SET( qroom->room_flags, ROOM_SOLITARY ) || xIS_SET( qroom->room_flags, ROOM_PET_SHOP ) || xIS_SET( qroom->room_flags, ROOM_DONATION ) || xIS_SET( qroom->room_flags, ROOM_PRIVATE ) ) continue; if( number_percent( ) > 20 ) continue; for( obj = qroom->first_content; obj; obj = obj->next_content ) { if( number_percent( ) > 20 ) continue; if( !can_see_obj( ch, obj ) || can_wear( obj, ITEM_NO_TAKE ) ) continue; break; } if( obj ) break; } if( obj ) break; } } if( !obj ) { snprintf( buf, sizeof( buf ), "0.%s I'm sorry, but I don't need anything at this time.", ch->name ); do_tell( questman, buf ); snprintf( buf, sizeof( buf ), "0.%s Come back later.", ch->name ); do_tell( questman, buf ); ch->questcountdown = 5; return; } snprintf( buf, sizeof( buf ), "0.%s I'm looking for %s.", ch->name, obj->short_descr ); do_tell( questman, buf ); if( qroom ) { snprintf( buf, sizeof( buf ), "0.%s Look for it at %s.", ch->name, qroom->name ); do_tell( questman, buf ); } else if( victim ) { snprintf( buf, sizeof( buf ), "0.%s Look for it on %s.", ch->name, victim->name ); do_tell( questman, buf ); } else if( iobj ) { snprintf( buf, sizeof( buf ), "0.%s Look for it in %s.", ch->name, iobj->short_descr ); do_tell( questman, buf ); } xSET_BIT( ch->act, PLR_QUESTOR ); ch->questcountdown = number_range( 10, 20 ); ch->questvnum = obj->pIndexData->vnum; ch->questgiver = questman->pIndexData->vnum; snprintf( buf, sizeof( buf ), "0.%s You have %d minutes to bring me it.", ch->name, ch->questcountdown ); do_tell( questman, buf ); 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 buf[MSL]; CHAR_DATA *questgiver; 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( !( oindex = get_obj_index( ch->questvnum ) ) ) { ch->questgiver = 0; ch->questvnum = 0; ch->questcountdown = 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 are currently on a quest to bring back %s.\r\n", oindex->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, "cancel" ) ) { if( !xIS_SET( ch->act, PLR_QUESTOR ) ) { snprintf( buf, sizeof( buf ), "0.%s I'm sorry, but you aren't on a quest.", ch->name ); do_tell( questgiver, buf ); return; } else if( questgiver->pIndexData->vnum != ch->questgiver ) { snprintf( buf, sizeof( buf ), "0.%s I'm sorry, but I never sent you on a quest.", ch->name ); do_tell( questgiver, buf ); return; } ch->questgiver = 0; ch->questvnum = 0; ch->questcountdown = 20; xREMOVE_BIT( ch->act, PLR_QUESTOR ); snprintf( buf, sizeof( buf ), "0.%s I'm sorry you aren't going to finish the quest.", ch->name ); do_tell( questgiver, buf ); snprintf( buf, sizeof( buf ), "0.%s Come back later and try another quest.", ch->name ); do_tell( questgiver, buf ); save_char_obj( ch ); return; } } void quest_update( void ) { static int quest_update_time; CHAR_DATA *ch; OBJ_INDEX_DATA *oindex; 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( !( oindex = get_obj_index( ch->questvnum ) ) ) { ch->questgiver = 0; ch->questvnum = 0; ch->questcountdown = 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; } 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; 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; 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 ); for( reward = first_reward; reward; reward = reward->next ) { cnt++; 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; } 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 ) { char arg[MIL], arg2[MIL]; REWARD_DATA *reward; int vnum = 0, value = 0; argument = one_argument( argument, arg ); if( !arg || 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 || arg2[0] == '\0' ) { do_setreward( ch, "" ); return; } if( !str_cmp( arg, "delete" ) ) { vnum = atoi( arg2 ); if( !( reward = find_reward( vnum ) ) ) { send_to_char( "There is no such reward useing 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 useing that vnum.\r\n", ch ); return; } if( ( reward = find_reward( vnum ) ) ) { send_to_char( "There is already a reward useing 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 useing 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 useing 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, "" ); } CMDF( do_useglory ) { char arg1[MSL]; OBJ_DATA *obj; AFFECT_DATA *paf; int value; argument = one_argument( argument, arg1 ); if( !arg1 || 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; } }