/**************************************************************************** * Automated Quest code written by Vassago of MOONGATE, moongate.ams.com * * 4000. Copyright (c) 1996 Ryan Addams, All Rights Reserved. Use of this * * code is allowed provided you add a credit line to the effect of: * * "Quest Code (c) 1996 Ryan Addams" to your logon screen with the rest * * of the standard diku/rom credits. If you use this or a modified version * * of this code, let me know via email: moongate@moongate.ams.com. Further * * updates will be posted to the rom mailing list. If you'd like to get * * the latest version of quest.c, please send a request to the above add- * * ress. Quest Code v2.01. Please do not remove this notice from this file. * ****************************************************************************/ /*$Id: quest.c,v 1.24 2005/04/28 01:04:22 ahsile Exp $*/ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" DECLARE_DO_FUN( do_say ); /* Object vnums for Quest Rewards */ #define QUEST_ITEM1 35 /* Shield */ #define QUEST_ITEM2 36 /* Contact */ #define QUEST_ITEM3 37 /* Potion of Godlike */ #define QUEST_ITEM4 38 /* Parchment of Immortals */ #define QUEST_ITEM5 39 /* Staff of Power */ #define QUEST_ITEM6 46 /* Storm Lantern */ #define QUEST_ITEM7 51 /* Amulet of the Lost */ #define QUEST_ITEM8 43 /* Eye of Gardith */ #define QUEST_ITEM9 47 /* Sword of Abraxyz */ #define QUEST_ITEM10 27 /* Ring of Abraxyz */ #define QUEST_ITEM11 48 /* Potion of Luck */ #define QUEST_ITEM12 44 /* Black Potion */ #define QUEST_ITEM13 29 /* Potion of Titan Strength */ #define QUEST_ITEM14 /* Potion of Shielding */ #define QUEST_ITEM15 /* Potion of Resistance */ #define QUEST_ITEM16 /* Potion of Regeneration */ #define QUEST_ITEM17 49 /* Book of the Gods */ #define QUEST_OBJQUEST1 30 #define QUEST_OBJQUEST2 31 #define QUEST_OBJQUEST3 32 #define QUEST_OBJQUEST4 33 #define QUEST_OBJQUEST5 34 /* Local functions */ void generate_quest args(( CHAR_DATA *ch, CHAR_DATA *questman )); void quest_update args(( void )); bool quest_level_diff args(( int clevel, int mlevel)); bool chance args(( int num )); ROOM_INDEX_DATA *find_location( CHAR_DATA *ch, char *arg ); int get_random_skpell args(( )); /* CHANCE function. I use this everywhere in my code, very handy :> */ /* otherwise known as number_percent - tyrion */ bool chance(int num) { if (number_range(1,100) <= num) return TRUE; else return FALSE; } /* The main quest function */ void do_quest(CHAR_DATA *ch, char *argument) { CHAR_DATA *questman; OBJ_DATA *obj=NULL, *obj_next; OBJ_INDEX_DATA *questinfoobj; MOB_INDEX_DATA *questinfo; char buf [MAX_STRING_LENGTH * 2]; char arg1 [MAX_INPUT_LENGTH]; char arg2 [MAX_INPUT_LENGTH]; int pointreward; argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (arg1[0] == '\0') { send_to_char(AT_WHITE, "QUEST commands: POINTS INFO TIME REQUEST COMPLETE REFUSE LIST BUY.\n\r",ch); send_to_char(AT_WHITE, "For more information, type 'HELP QUEST'.\n\r",ch); return; } if (!strcmp(arg1, "info")) { if (IS_SET(ch->act, PLR_QUESTOR)) { if (ch->questmob == -1 && ch->questgiver->short_descr != NULL) { sprintf(buf, "Your quest is ALMOST complete!\n\rGet back to %s before your time runs out!\n\r",ch->questgiver->short_descr); send_to_char(AT_WHITE, buf, ch); } else if (ch->questobj > 0) { questinfoobj = get_obj_index(ch->questobj); if (questinfoobj != NULL) { sprintf(buf, "You are on a quest to recover the fabled %s!\n\r",questinfoobj->name); send_to_char(AT_WHITE, buf, ch); } else send_to_char(AT_WHITE, "You aren't currently on a quest.\n\r",ch); return; } else if (ch->questmob > 0) { questinfo = get_mob_index(ch->questmob); if (questinfo != NULL) { sprintf(buf, "You are on a quest to slay the dreaded %s!\n\r",questinfo->short_descr); send_to_char(AT_WHITE, buf, ch); } else send_to_char(AT_WHITE, "You aren't currently on a quest.\n\r",ch); return; } } else send_to_char(AT_WHITE, "You aren't currently on a quest.\n\r",ch); return; } if (!strcmp(arg1, "points")) { sprintf(buf, "You have %d quest points.\n\r",ch->questpoints); send_to_char(AT_WHITE, buf, ch); return; } else if (!strcmp(arg1, "time")) { if (!IS_SET(ch->act, PLR_QUESTOR)) { send_to_char(AT_WHITE, "You aren't currently on a quest.\n\r",ch); if (ch->nextquest > 1) { sprintf(buf, "There are %d minutes remaining until you can go on another quest.\n\r",ch->nextquest); send_to_char(AT_WHITE, buf, ch); } else if (ch->nextquest == 1) { sprintf(buf, "There is less than a minute remaining until you can go on another quest.\n\r"); send_to_char(AT_WHITE, buf, ch); } } else if (ch->countdown > 0) { sprintf(buf, "Time left for current quest: %d minutes.\n\r",ch->countdown); send_to_char(AT_WHITE, buf, ch); } return; } /* Checks for a character in the room with spec_questmaster set. This special procedure must be defined in special.c. You could instead use an ACT_QUESTMASTER flag instead of a special procedure. */ for ( questman = ch->in_room->people; questman != NULL; questman = questman->next_in_room ) { if (!IS_NPC(questman)) continue; if (questman->spec_fun == spec_lookup( "spec_questmaster" )) break; } if (questman == NULL || questman->spec_fun != spec_lookup( "spec_questmaster" )) { send_to_char(AT_WHITE, "You can't do that here.\n\r",ch); return; } if ( questman->fighting != NULL) { send_to_char(AT_WHITE, "Wait until the fighting stops.\n\r",ch); return; } ch->questgiver = questman; if (!strcmp(arg1, "list")) { act(AT_WHITE, "$n asks $N for a list of quest items.", ch, NULL, questman, TO_ROOM); act (AT_WHITE, "You ask $N for a list of quest items.",ch, NULL, questman, TO_CHAR); #ifdef RUN_AS_WIN32SERVICE sprintf(buf, "Current Quest Items available for Purchase:\n\r \ ============================================\r \ 1) 500qp - Shield of Abraxyz\r \ 2) 750qp - Contact Lenses\r \ 3) 150qp - Potion of Godlike Strength\r \ 4) 150qp - Parchment of Immortals\r \ 5) 1000qp - Staff of Power\r \ 6) 1500qp - Storm Lantern of Unholy Plague\r \ 7) 2500qp - Amulet of the Lost\r \ 8) 4000qp - The Eye of Gardith\r \ 9) 4500qp - The Sword of Abraxyz (LEVEL 104)\r \ 10) 5000qp - Ring of Abraxyz\r \ 11) 500qp - Potion of Luck\r \ 12) 25qp - Black Potion\r \ 13) 100qp - Potion of Titan Strength\r \ 14) 100qp - Potion of Shielding\r \ 15) 100qp - Potion of Resistance\r \ 16) 100qp - Potion of Regeneration\r \ 17) 25qp - Book of the Gods\r \ ============================================\r \ A) 250qp - 2,500,000 gold\r \ B) 500qp - 175 pracs\r \ C) 80qp - 25 pracs\r \ D) 25qp - 2 learns\r \ \r \ 14 through 16 are currently unavailable\r \ \r \ To buy an item, type 'QUEST BUY <item>'. For example, 'QUEST BUY 1' for the Shield of Abraxyz.\n\r"); #else sprintf(buf, "Current Quest Items available for Purchase:\n\r \ ============================================\r \ 1) 500qp - Shield of Abraxyz\r \ 2) 750qp - Contact Lenses\r \ 3) 150qp - Potion of Godlike Strength\r \ 4) 150qp - Parchment of Immortals\r \ 5) 1000qp - Staff of Power\r \ 6) 1500qp - Storm Lantern of Unholy Plague\r \ 7) 2500qp - Amulet of the Lost\r \ 8) 4000qp - The Eye of Gardith\r \ 9) 4500qp - The Sword of Abraxyz (LEVEL 104)\r \ 10) 5000qp - Ring of Abraxyz\r \ 11) 500qp - Potion of Luck\r \ 12) 25qp - Black Potion\r \ 13) 100qp - Potion of Titan Strength\r \ 14) 100qp - Potion of Shielding\r \ 15) 100qp - Potion of Resistance\r \ 16) 100qp - Potion of Regeneration\r \ 17) 25qp - Book of the Gods\r \ ============================================\r \ A) 250qp - 2,500,000 gold\r \ B) 500qp - 175 pracs\r \ C) 80qp - 25 pracs\r \ D) 25qp - 2 learns\r \ \r \ 14 through 16 are currently unavailable\r \ \r \ To buy an item, type 'QUEST BUY <item>'. For example, 'QUEST BUY 1' for the Shield of Abraxyz.\n\r"); #endif send_to_char(AT_WHITE, buf, ch); return; } else if (!strcmp(arg1, "buy")) { if (arg2[0] == '\0') { send_to_char(AT_WHITE, "To buy an item, type 'QUEST BUY <item>'.\n\r",ch); return; } if (is_name(arg2, "1")) { if (ch->questpoints >= 500) { ch->questpoints -= 500; obj = create_object(get_obj_index(QUEST_ITEM1),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "2")) { if (ch->questpoints >= 750) { ch->questpoints -= 750; obj = create_object(get_obj_index(QUEST_ITEM2),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "3")) { if (ch->questpoints >= 150) { ch->questpoints -= 150; obj = create_object(get_obj_index(QUEST_ITEM3),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "4")) { if (ch->questpoints >= 150) { ch->questpoints -= 150; obj = create_object(get_obj_index(QUEST_ITEM4),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "5")) { if (ch->questpoints >= 1000) { ch->questpoints -= 1000; obj = create_object(get_obj_index(QUEST_ITEM5),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "6")) { if (ch->questpoints >= 1500) { ch->questpoints -= 1500; obj = create_object(get_obj_index(QUEST_ITEM6),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "7")) { if (ch->questpoints >= 2500) { ch->questpoints -= 2500; obj = create_object(get_obj_index(QUEST_ITEM7),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "8")) { if (ch->questpoints >= 4000) { ch->questpoints -= 4000; obj = create_object(get_obj_index(QUEST_ITEM8),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "9")) { if (ch->questpoints >= 4500) { ch->questpoints -= 4500; obj = create_object(get_obj_index(QUEST_ITEM9),ch->level); obj->value[1] = 50; obj->value[2] = 95; obj->level = 104; } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "10")) { if (ch->questpoints >= 5000) { ch->questpoints -= 5000; obj = create_object(get_obj_index(QUEST_ITEM10),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "11")) { if (ch->questpoints >= 500) { ch->questpoints -= 500; obj = create_object(get_obj_index(QUEST_ITEM11),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "12")) { if (ch->questpoints >= 25) { ch->questpoints -= 25; obj = create_object(get_obj_index(QUEST_ITEM12),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "13")) { if (ch->questpoints >= 100) { ch->questpoints -= 100; obj = create_object(get_obj_index(QUEST_ITEM13),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } /* else if (is_name(arg2, "14")) { if (ch->questpoints >= 5000) { ch->questpoints -= 5000; obj = create_object(get_obj_index(QUEST_ITEM14),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "15")) { if (ch->questpoints >= 5000) { ch->questpoints -= 5000; obj = create_object(get_obj_index(QUEST_ITEM15),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "16")) { if (ch->questpoints >= 5000) { ch->questpoints -= 5000; obj = create_object(get_obj_index(QUEST_ITEM16),ch->level); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } */ else if (is_name(arg2, "17")) { if (ch->questpoints >= 25) { int skpell; char objname[ MAX_STRING_LENGTH ]; char objshort_descr[ MAX_STRING_LENGTH ]; char objdescription[ MAX_STRING_LENGTH ]; ch->questpoints -= 25; obj = create_object(get_obj_index(QUEST_ITEM17),ch->level); skpell = get_random_skpell( ); obj->value[1] = skpell; sprintf( objname, "%s %s", obj->name, skill_table[obj->value[1]].name ); sprintf( objshort_descr, "%s (%s)", obj->short_descr, skill_table[obj->value[1]].name ); sprintf( objdescription, "A Book of the Gods is here (%s).", skill_table[obj->value[1]].name ); if( number_percent( ) <= 50 ) { skpell = get_random_skpell( ); obj->value[2] = skpell; sprintf( objname, "%s %s %s", obj->name, skill_table[obj->value[1]].name, skill_table[obj->value[2]].name ); sprintf( objshort_descr, "%s (%s, %s)", obj->short_descr, skill_table[obj->value[1]].name, skill_table[obj->value[2]].name ); sprintf( objdescription, "A Book of the Gods is here (%s, %s).", skill_table[obj->value[1]].name, skill_table[obj->value[2]].name ); if( number_percent( ) <= 50 ) { skpell = get_random_skpell( ); obj->value[3] = skpell; sprintf( objname, "%s %s %s %s", obj->name, skill_table[obj->value[1]].name, skill_table[obj->value[2]].name, skill_table[obj->value[3]].name ); sprintf( objshort_descr, "%s (%s, %s, %s)", obj->short_descr, skill_table[obj->value[1]].name, skill_table[obj->value[2]].name, skill_table[obj->value[3]].name ); sprintf( objdescription, "A Book of the Gods is here (%s, %s, %s).", skill_table[obj->value[1]].name, skill_table[obj->value[2]].name, skill_table[obj->value[3]].name ); } } obj->value[0] = number_range(1, 100); free_string( obj->name ); free_string( obj->short_descr ); free_string( obj->description ); obj->name = str_dup( objname ); obj->short_descr = str_dup( objshort_descr ); obj->description = str_dup( objdescription ); } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "a")) { if (ch->questpoints >= 250) { ch->questpoints -= 250; ch->gold += 2500000; act(AT_WHITE, "$N gives 5,000,000 gold pieces to $n.", ch, NULL, questman, TO_ROOM ); act(AT_WHITE, "$N has 5,000,000 in gold transfered from $s Swiss account to your balance.", ch, NULL, questman, TO_CHAR ); return; } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "b")) { if (ch->questpoints >= 500) { ch->questpoints -= 500; ch->practice += 175; act(AT_WHITE, "$N gives 175 practices to $n.", ch, NULL, questman, TO_ROOM ); act(AT_WHITE, "$N gives you 175 practices.", ch, NULL, questman, TO_CHAR ); return; } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "c")) { if (ch->questpoints >= 80) { ch->questpoints -= 80; ch->practice += 25; act(AT_WHITE, "$N gives 25 practices to $n.", ch, NULL, questman, TO_ROOM ); act(AT_WHITE, "$N gives you 25 practices.", ch, NULL, questman, TO_CHAR ); return; } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else if (is_name(arg2, "d")) { if (ch->questpoints >= 25) { ch->questpoints -= 25; ch->pcdata->learn += 2; act(AT_WHITE, "$N gives 2 learns to $n.", ch, NULL, questman, TO_ROOM ); act(AT_WHITE, "$N gives you 1 learns.", ch, NULL, questman, TO_CHAR ); return; } else { sprintf(buf, "Sorry, %s, but you don't have enough quest points for that.",ch->name); do_say(questman,buf); return; } } else { sprintf(buf, "I don't have that item, %s.",ch->name); do_say(questman, buf); } if (obj != NULL) { SET_BIT(obj->extra_flags2, ITEM_QUEST ); /* SET_BIT(obj->extra_flags2, ITEM_NO_STEAL ); // Class/Multi Bits if( ch->multied == CLASS_MAGE || ch->class == CLASS_MAGE ) { SET_BIT( obj->extra_flags3, ITEM_PRO_MAGE ); } if( ch->multied == CLASS_CLERIC || ch->class == CLASS_CLERIC ) { SET_BIT( obj->extra_flags3, ITEM_PRO_CLERIC ); } if( ch->multied == CLASS_THIEF || ch->class == CLASS_THIEF ) { SET_BIT( obj->extra_flags3, ITEM_PRO_THIEF ); } if( ch->multied == CLASS_WARRIOR || ch->class == CLASS_WARRIOR ) { SET_BIT( obj->extra_flags3, ITEM_PRO_WARRIOR ); } if( ch->multied == CLASS_PSIONICIST || ch->class == CLASS_PSIONICIST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_PSI ); } if( ch->multied == CLASS_DRUID || ch->class == CLASS_DRUID ) { SET_BIT( obj->extra_flags3, ITEM_PRO_DRUID ); } if( ch->multied == CLASS_RANGER || ch->class == CLASS_RANGER ) { SET_BIT( obj->extra_flags3, ITEM_PRO_RANGER ); } if( ch->multied == CLASS_PALADIN || ch->class == CLASS_PALADIN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_PALADIN ); } if( ch->multied == CLASS_BARD || ch->class == CLASS_BARD ) { SET_BIT( obj->extra_flags3, ITEM_PRO_BARD ); } if( ch->multied == CLASS_VAMPIRE || ch->class == CLASS_VAMPIRE ) { SET_BIT( obj->extra_flags3, ITEM_PRO_VAMP ); } if( ch->multied == CLASS_WEREWOLF || ch->class == CLASS_WEREWOLF ) { SET_BIT( obj->extra_flags3, ITEM_PRO_WEREWOLF ); } if( ch->multied == CLASS_ANTI_PALADIN || ch->class == CLASS_ANTI_PALADIN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_ANTIPAL ); } if( ch->multied == CLASS_ASSASSIN || ch->class == CLASS_ASSASSIN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_ASSASSIN ); } if( ch->multied == CLASS_MONK || ch->class == CLASS_MONK ) { SET_BIT( obj->extra_flags3, ITEM_PRO_MONK ); } if( ch->multied == CLASS_BARBARIAN || ch->class == CLASS_BARBARIAN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_BARBARIAN ); } if( ch->multied == CLASS_ILLUSIONIST || ch->class == CLASS_ILLUSIONIST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_ILLUSIONIST ); } if( ch->multied == CLASS_NECROMANCER || ch->class == CLASS_NECROMANCER ) { SET_BIT( obj->extra_flags3, ITEM_PRO_NECROMANCER ); } if( ch->multied == CLASS_DEMONOLOGIST || ch->class == CLASS_DEMONOLOGIST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_DEMONOLOGIST ); } if( ch->multied == CLASS_SHAMAN || ch->class == CLASS_SHAMAN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_SHAMAN ); } if( ch->multied == CLASS_DARKPRIEST || ch->class == CLASS_DARKPRIEST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_DARKPRIEST ); } // Race Bits if (ch->race == race_lookup("Human")) { SET_BIT(obj->extra_flags3, ITEM_PRO_HUMAN ); } else if (ch->race == race_lookup("Elf")) { SET_BIT(obj->extra_flags3, ITEM_PRO_ELF ); } else if (ch->race == race_lookup("Halfelf")) { SET_BIT(obj->extra_flags3, ITEM_PRO_HALFELF ); } else if (ch->race == race_lookup("Orc")) { SET_BIT(obj->extra_flags3, ITEM_PRO_ORC ); } else if (ch->race == race_lookup("Drow")) { SET_BIT(obj->extra_flags3, ITEM_PRO_DROW ); } else if (ch->race == race_lookup("Dwarf")) { SET_BIT(obj->extra_flags3, ITEM_PRO_DWARF ); } else if (ch->race == race_lookup("Halfdwarf")) { SET_BIT(obj->extra_flags3, ITEM_PRO_HALFDWARF ); } else if (ch->race == race_lookup("Hobbit")) { SET_BIT(obj->extra_flags3, ITEM_PRO_HOBBIT ); } else if (ch->race == race_lookup("Giant")) { SET_BIT(obj->extra_flags3, ITEM_PRO_GIANT ); } else if (ch->race == race_lookup("Ogre")) { SET_BIT(obj->extra_flags3, ITEM_PRO_OGRE ); } // Crossover from extra3 -> extra4 here else if (ch->race == race_lookup("Angel")) { SET_BIT(obj->extra_flags4, ITEM_PRO_ANGEL ); } else if (ch->race == race_lookup("Minotaur")) { SET_BIT(obj->extra_flags4, ITEM_PRO_MINOTAUR ); } else if (ch->race == race_lookup("Feline")) { SET_BIT(obj->extra_flags4, ITEM_PRO_FELINE ); } else if (ch->race == race_lookup("Gargoyle")) { SET_BIT(obj->extra_flags4, ITEM_PRO_GARGOYLE ); } else if (ch->race == race_lookup("Canine")) { SET_BIT(obj->extra_flags4, ITEM_PRO_CANINE ); } else if (ch->race == race_lookup("Demon")) { SET_BIT(obj->extra_flags4, ITEM_PRO_DEMON ); } else if (ch->race == race_lookup("Pixie")) { SET_BIT(obj->extra_flags4, ITEM_PRO_PIXIE ); } else if (ch->race == race_lookup("Elder")) { SET_BIT(obj->extra_flags4, ITEM_PRO_ELDER ); } else if (ch->race == race_lookup("Lizardman")) { SET_BIT(obj->extra_flags4, ITEM_PRO_LIZARDMAN ); } else if (ch->race == race_lookup("Gnome")) { SET_BIT(obj->extra_flags4, ITEM_PRO_GNOME ); } */ act(AT_WHITE, "$N gives $p to $n.", ch, obj, questman, TO_ROOM ); act(AT_WHITE, "$N gives you $p.", ch, obj, questman, TO_CHAR ); obj_to_char(obj, ch); } return; } else if (!strcmp(arg1, "request")) { act(AT_WHITE, "$n asks $N for a quest.", ch, NULL, questman, TO_ROOM); act (AT_WHITE, "You ask $N for a quest.",ch, NULL, questman, TO_CHAR); if (IS_SET(ch->act, PLR_QUESTOR)) { sprintf(buf, "But you're already on a quest!"); do_say(questman, buf); return; } if (ch->nextquest > 0) { sprintf(buf, "You're very brave, %s, but let someone else have a chance.",ch->name); do_say(questman, buf); sprintf(buf, "Come back later."); do_say(questman, buf); return; } sprintf(buf, "Thank you, brave %s!",ch->name); do_say(questman, buf); ch->questmob = 0; ch->questobj = 0; generate_quest(ch, questman); if (ch->questmob > 0 || ch->questobj > 0) { SET_BIT(ch->act, PLR_QUESTOR); sprintf(buf, "You have %d minutes to complete this quest.",ch->countdown); do_say(questman, buf); sprintf(buf, "May the gods go with you!"); do_say(questman, buf); } return; } else if (!strcmp(arg1, "refuse")) { act(AT_WHITE, "$n offers to refuse the quest.",ch,NULL,questman,TO_ROOM); act(AT_WHITE, "You ask $N to refuse your quest.",ch,NULL,questman,TO_CHAR); if(!IS_SET(ch->act, PLR_QUESTOR)) { sprintf(buf, "But you are not on a quest!"); do_say(questman, buf); return; } pointreward = number_range(ch->level / 4, ch->level / 2); pointreward = UMAX( pointreward, 15); if(ch->questpoints < pointreward) { sprintf(buf, "You do not have enough quest points to refuse a quest."); do_say(questman, buf); return; } sprintf(buf, "As a penalty, I am going to take %d quest points from you.", pointreward ); do_say(questman, buf); REMOVE_BIT(ch->act, PLR_QUESTOR); ch->questgiver = NULL; ch->countdown = 0; ch->questmob = 0; ch->questobj = 0; ch->nextquest = 1; ch->questpoints -= pointreward; return; } else if (!strcmp(arg1, "complete")) { act(AT_WHITE, "$n informs $N $e has completed $s quest.", ch, NULL, questman, TO_ROOM); act (AT_WHITE, "You inform $N you have completed $s quest.",ch, NULL, questman, TO_CHAR); if (ch->questgiver != questman) { sprintf(buf, "I never sent you on a quest! Perhaps you're thinking of someone else."); do_say(questman,buf); return; } if (IS_SET(ch->act, PLR_QUESTOR)) { if (ch->questmob == -1 && ch->countdown > 0) { int reward, pointreward, pracreward; reward = number_range(2500,45000); pointreward = number_range(ch->level / 4, ch->level / 2); pointreward = UMAX( pointreward, 15); sprintf(buf, "Congratulations on completing your quest!"); do_say(questman,buf); sprintf(buf,"As a reward, I am giving you %d quest points, and %d gold.",pointreward,reward); do_say(questman,buf); if (chance(25)) { pracreward = number_range(1,5); sprintf(buf, "You gain %d practices!\n\r",pracreward); send_to_char(AT_WHITE, buf, ch); ch->practice += pracreward; } REMOVE_BIT(ch->act, PLR_QUESTOR); ch->questgiver = NULL; ch->countdown = 0; ch->questmob = 0; ch->questobj = 0; ch->nextquest = 10; ch->gold += reward; ch->questpoints += pointreward; return; } else if (ch->questobj > 0 && ch->countdown > 0) { bool obj_found = FALSE; for (obj = ch->carrying; obj != NULL; obj= obj_next) { obj_next = obj->next_content; if (obj != NULL && obj->pIndexData->vnum == ch->questobj) { obj_found = TRUE; break; } } if (obj_found == TRUE) { int reward, pointreward, pracreward; reward = number_range(2500,45000); pointreward = number_range(ch->level / 4,ch->level / 2); pointreward = UMAX(pointreward, 15); act(AT_WHITE, "You hand $p to $N.",ch, obj, questman, TO_CHAR); act(AT_WHITE, "$n hands $p to $N.",ch, obj, questman, TO_ROOM); sprintf(buf, "Congratulations on completing your quest!"); do_say(questman,buf); sprintf(buf,"As a reward, I am giving you %d quest points, and %d gold.",pointreward,reward); do_say(questman,buf); if (chance(25)) { pracreward = number_range(1,5); sprintf(buf, "You gain %d practices!\n\r",pracreward); send_to_char(AT_WHITE, buf, ch); ch->practice += pracreward; } REMOVE_BIT(ch->act, PLR_QUESTOR); ch->questgiver = NULL; ch->countdown = 0; ch->questmob = 0; ch->questobj = 0; ch->nextquest = 10; ch->gold += reward; ch->questpoints += pointreward; extract_obj(obj); return; } else { sprintf(buf, "You haven't completed the quest yet, but there is still time!"); do_say(questman, buf); return; } return; } else if ((ch->questmob > 0 || ch->questobj > 0) && ch->countdown > 0) { sprintf(buf, "You haven't completed the quest yet, but there is still time!"); do_say(questman, buf); return; } } if (ch->nextquest > 0) sprintf(buf,"But you didn't complete your quest in time!"); else sprintf(buf, "You have to REQUEST a quest first, %s.",ch->name); do_say(questman, buf); return; } send_to_char(AT_WHITE, "QUEST commands: POINTS INFO TIME REQUEST COMPLETE LIST BUY.\n\r",ch); send_to_char(AT_WHITE, "For more information, type 'HELP QUEST'.\n\r",ch); return; } void generate_quest(CHAR_DATA *ch, CHAR_DATA *questman) { CHAR_DATA *victim; MOB_INDEX_DATA *vsearch; ROOM_INDEX_DATA *room; OBJ_DATA *questitem; char buf [MAX_STRING_LENGTH]; long mcounter; int mob_vnum; for (mcounter = 0; mcounter < 99999; mcounter ++) { mob_vnum = number_range(50, 32000); if ( (vsearch = get_mob_index(mob_vnum) ) != NULL ) { if (vsearch->pShop == NULL && !IS_SET(vsearch->act, ACT_TRAIN) && !IS_SET(vsearch->act, ACT_PRACTICE) && !IS_SET(vsearch->act, ACT_IS_HEALER) && !IS_SET(vsearch->act, ACT_BANKER) && !IS_SET(vsearch->act, ACT_TEACHER) && !IS_SET(vsearch->act, ACT_PROTOTYPE) && !IS_SET(vsearch->act, ACT_PET) && !IS_SET(vsearch->affected_by, AFF_PEACE) && !IS_SET(vsearch->affected_by, AFF_CHARM) && !IS_SET(vsearch->affected_by, AFF_INVISIBLE) && !IS_SET(vsearch->affected_by4, AFF_IMMORTAL) && chance(40) && quest_level_diff(ch->level, vsearch->level) == TRUE) break; /*else break; */ } } if ( vsearch == NULL || ( victim = get_char_world( ch, vsearch->player_name ) ) == NULL) { generate_quest(ch, questman); return; } if ( ( room = find_location( ch, victim->name ) ) == NULL || ( IS_SET( victim->in_room->room_flags, ROOM_SAFE) || IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE )|| IS_SET( victim->in_room->area->area_flags, AREA_NOQUEST ) || IS_SET (victim->in_room->area->area_flags, AREA_RANDOM))) { generate_quest(ch, questman); return; } /* 40% chance it will send the player on a 'recover item' quest. */ if (IS_SET( room->area->area_flags, AREA_PROTOTYPE )|| IS_SET( room->area->area_flags, AREA_NOQUEST ) || IS_SET(room->area->area_flags, AREA_RANDOM)) { generate_quest(ch, questman); return; } if (chance(40)) { int objvnum = 0; switch(number_range(0,4)) { case 0: objvnum = QUEST_OBJQUEST1; break; case 1: objvnum = QUEST_OBJQUEST2; break; case 2: objvnum = QUEST_OBJQUEST3; break; case 3: objvnum = QUEST_OBJQUEST4; break; case 4: objvnum = QUEST_OBJQUEST5; break; } questitem = create_object( get_obj_index(objvnum), ch->level ); ch->countdown = number_range(10,30); questitem->timer = ch->countdown * 2; obj_to_room(questitem, room); ch->questobj = questitem->pIndexData->vnum; sprintf(buf, "Vile pilferers have stolen %s from the royal treasury!",questitem->short_descr); do_say(questman, buf); do_say(questman, "My court wizardess, with her magic mirror, has pinpointed its location."); sprintf(buf, "Look in the general area of %s for %s!",room->area->name, room->name); do_say(questman, buf); return; } /* Quest to kill a mob */ else { switch(number_range(0,1)) { case 0: sprintf(buf, "An enemy of mine, %s, is making vile threats against the crown.",victim->short_descr); do_say(questman, buf); sprintf(buf, "This threat must be eliminated!"); do_say(questman, buf); break; case 1: sprintf(buf, "Rune's most heinous criminal, %s, has escaped from the dungeon!",victim->short_descr); do_say(questman, buf); sprintf(buf, "Since the escape, %s has murdered %d civillians!",victim->short_descr, number_range(2,20)); do_say(questman, buf); do_say(questman,"The penalty for this crime is death, and you are to deliver the sentence!"); break; } if (room->name != NULL) { sprintf(buf, "Seek %s out somewhere in the vicinity of %s!",victim->short_descr,room->name); do_say(questman, buf); /* I changed my area names so that they have just the name of the area and none of the level stuff. You may want to comment these next two lines. - Vassago */ sprintf(buf, "That location is in the general area of %s.",room->area->name); do_say(questman, buf); } ch->questmob = victim->pIndexData->vnum; ch->countdown = number_range(10,30); } return; } bool quest_level_diff(int clevel, int mlevel) { clevel = UMIN (100, clevel); mlevel = UMIN (100, mlevel); /* Can't have quests to kill mobs lower than the player. */ if (mlevel < clevel) return FALSE; /* if the mob is within 10 levels, or both are greater than 100 return true*/ return ((mlevel - clevel < 10) || (mlevel >= 100 && clevel >= 100)); /* return (((mlevel - clevel > 0 ) || (mlevel >= 100 && clevel >= 100)) && ((clevel > 100) || (mlevel - clevel < 10) )); if (clevel < 6 && mlevel < 15) return TRUE; else if (clevel > 6 && clevel < 15 && mlevel < 30) return TRUE; else if (clevel > 14 && clevel < 25 && mlevel > 29 && mlevel < 45) return TRUE; else if (clevel > 24 && clevel < 35 && mlevel > 44 && mlevel < 55) return TRUE; else if (clevel > 34 && clevel < 60 && mlevel > 54 && mlevel < 80) return TRUE; else if (clevel > 59 && mlevel > 79) return TRUE; else return FALSE; */ } /* Called from update_handler() by pulse_area */ void quest_update(void) { DESCRIPTOR_DATA *d; CHAR_DATA *ch; for ( d = descriptor_list; d != NULL; d = d->next ) { if (d->character != NULL && d->connected == CON_PLAYING) { ch = d->character; if (ch->nextquest > 0) { ch->nextquest--; if (ch->nextquest == 0) { send_to_char(AT_WHITE, "You may now quest again.\n\r",ch); continue; } } else if (IS_SET(ch->act,PLR_QUESTOR)) { if (--ch->countdown <= 0) { char buf [MAX_STRING_LENGTH]; ch->nextquest = 10; sprintf(buf, "You have run out of time for your quest!\n\rYou may quest again in %d minutes.\n\r",ch->nextquest); send_to_char(AT_WHITE, buf, ch); REMOVE_BIT(ch->act, PLR_QUESTOR); ch->questgiver = NULL; ch->countdown = 0; ch->questmob = 0; } if (ch->countdown > 0 && ch->countdown < 6) { send_to_char(AT_WHITE, "Better hurry, you're almost out of time for your quest!\n\r",ch); continue; } } } } return; } int get_random_skpell( ) { int count; int num; int cls; num = 0; do { cls = 0; num = number_range( 1, MAX_SKILL ) - 1; for ( count = 0; count < MAX_CLASS; count++ ) { if( skill_table[num].skill_level[count] < L_APP ) { cls = count; break; } } } while (!cls || skill_table[num].slot == 0); return num; }