/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Dystopia Mud improvements copyright (C) 2000, 2001 by Brian Graversen * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * Dystopian Questcode copyright (C) 2001 by Brian Graversen, users must * * follow the DIKU, Merc and Godwars license as well as the license * * distributed with Dystopia * ***************************************************************************/ /*************************************************************************** * _/ _/ * * _/_/_/ _/_/ _/_/_/ _/ _/_/ _/ _/ _/_/_/ * * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ * * _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ * * _/ _/ _/ _/_/_/ _/ _/_/ _/_/_/ _/_/_/ * *************************************************************************** * Mindcloud Copyright 2001-2003 by Jeff Boschee (Zarius), * * Additional credits are in the help file CODECREDITS * * All Rights Reserved. * ***************************************************************************/ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" #include "interp.h" int get_rand_mob args((void)); int get_rand_hard_mob args((void)); int get_rand_item args((void)); int load_special_item args((CHAR_DATA * ch)); int get_lbound args((void)); int get_ubound args((int bound)); void give_token args((CHAR_DATA * questmaster, CHAR_DATA * ch, int value)); QUEST_DATA *quest_free; DECLARE_QUEST_FUN(questspec_generic); DECLARE_QUEST_FUN(questspec_newbie); DECLARE_QUEST_FUN(questspec_special_item); DECLARE_QUEST_FUN(questspec_rand_mob); DECLARE_QUEST_FUN(questspec_mob_and_item); DECLARE_QUEST_FUN(questspec_hard_mob); DECLARE_QUEST_FUN(questspec_mass_kill); DECLARE_QUEST_FUN(questspec_pk); const struct quest_type quest_table[] = { {"questspec_generic", questspec_generic}, {"questspec_special_item", questspec_special_item}, {"questspec_rand_mob", questspec_rand_mob}, {"questspec_mob_and_item", questspec_mob_and_item}, {"questspec_hard_mob", questspec_hard_mob}, {"questspec_mass_kill", questspec_mass_kill}, {"questspec_pk", questspec_pk}, {"questspec_newbie", questspec_newbie}, /* * end of table */ {"", 0} }; /* * Used for show_char_to_char_0() */ bool is_quest_target(CHAR_DATA * ch, CHAR_DATA * victim) { QUEST_DATA *quest; if (IS_NPC(ch) || !IS_NPC(victim)) return FALSE; for (quest = ch->pcdata->quests; quest; quest = quest->next) { switch (quest->type) { case QT_MOB: if (victim->pIndexData->vnum == quest->vnums[0]) return TRUE; break; case QT_MOB_AND_OBJ: if (victim->pIndexData->vnum == quest->vnums[0]) return TRUE; break; case QT_MASS_KILL: if (victim->pIndexData->vnum >= quest->vnums[0] && victim->pIndexData->vnum <= quest->vnums[1]) return TRUE; break; default: continue; } } return FALSE; } /* * This is a temp function for creating the database of quest * monsters, that needs to be slain. Please don't run it * while the mud is operationel - it takes quite a while * to execute. */ void do_createbase(CHAR_DATA * ch, char *argument) { AREA_DATA *area; DESCRIPTOR_DATA *d; ROOM_INDEX_DATA *pRoom; MOB_INDEX_DATA *pMobIndex; RESET_DATA *pReset; FILE *fp; char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; int vnum, vnum2, iMin, iMax, col = 0; bool found = FALSE; if ((d = ch->desc) == NULL) { send_to_char("Huh?\n\r", ch); return; } one_argument(argument, arg); /* * put in what ever levels you want here */ if (!str_cmp(arg, "big")) { iMin = 800; iMax = 2600; } else if (!str_cmp(arg, "small")) { iMin = 10; iMax = 400; } else { send_to_char("Big or Small moblist ??\n\r", ch); return; } if ((fp = fopen("../txt/questlist.txt", "w")) == NULL) { send_to_char ("Unable to create questlist.txt - terminating attempt\n\r", ch); return; } for (area = area_first; area && !found; area = area->next) { if (area == area_first) write_to_descriptor(d, "\n\r", 0); xprintf(buf, "Processing %s....", area->name); write_to_descriptor(d, buf, 0); fprintf(fp, "/* %s */\n", area->name); found = FALSE; // reset for (vnum = area->lvnum; vnum <= area->uvnum; vnum++) { if ((pMobIndex = get_mob_index(vnum)) != NULL) { if (pMobIndex->level < iMin || pMobIndex->level > iMax) continue; for (vnum2 = area->lvnum; vnum2 <= area->uvnum; vnum2++) { if ((pRoom = get_room_index(vnum2)) != NULL) { for (pReset = pRoom->reset_first; pReset; pReset = pReset->next) { switch (pReset-> command) { default: break; case 'M': if ((pMobIndex = get_mob_index (pReset-> arg1)) != NULL) { if (pMobIndex->vnum == vnum) found = TRUE; } } } } } if (found) { found = FALSE; // reset for later use fprintf(fp, " %6d,", vnum); if (!(++col % 6)) fprintf(fp, "\n"); } } } if (col % 6) fprintf(fp, "\n"); if (area->next) write_to_descriptor(d, "Ok!\n\r", 0); else write_to_descriptor(d, "Ok!", 0); } fclose(fp); return; } int get_lbound() { int vnum, count = 0; static const int mob_table[] = { 14003, 31108, 1105, 1122, 1602, 1702, 1710, 2007, 2101, 2201, 2307, 2315, 2801, 2904, 3406, 3601, 4150, 4700, 5000, 5006, 6303, 6507, 6601, 7200, 7801, 8000, 8308, 8904, 9203, 9401, 11006, 7705, 93000, 80001, /* * END */ -1 }; /* * counting the size of the table */ for (count = 0; mob_table[count] != -1; count++); vnum = number_range(0, count - 1); return mob_table[vnum]; } int get_ubound(int bound) { int vnum; switch (bound) { case 14003: vnum = 14011; break; case 31108: vnum = 31118; break; case 1105: vnum = 1109; break; case 1122: vnum = 1125; break; case 1602: vnum = 1605; break; case 1702: vnum = 1708; break; case 1710: vnum = 1716; break; case 2007: vnum = 2013; break; case 2101: vnum = 2108; break; case 2201: vnum = 2205; break; case 2307: vnum = 2311; break; case 2315: vnum = 2321; break; case 2801: vnum = 2808; break; case 2904: vnum = 2913; break; case 3406: vnum = 3408; break; case 3601: vnum = 3604; break; case 4150: vnum = 4154; break; case 4700: vnum = 4708; break; case 5000: vnum = 5003; break; case 5006: vnum = 5008; break; case 2612: vnum = 2616; break; case 6303: vnum = 6310; break; case 6507: vnum = 6510; break; case 6601: vnum = 6606; break; case 7200: vnum = 7202; break; case 7801: vnum = 7808; break; case 8000: vnum = 8005; break; case 8308: vnum = 8312; break; case 8904: vnum = 8908; break; case 9203: vnum = 9207; break; case 9401: vnum = 9407; break; case 11006: vnum = 11008; break; case 7705: vnum = 7709; break; case 93000: vnum = 93004; break; case 80001: vnum = 80005; break; default: vnum = bound; bug("Bad Quest Vnum : %d", bound); break; } return vnum; } /* * Returns the vnum of a random object that actually pops on the mud. * It's a bit ugly, but it works :) */ int get_rand_item() { OBJ_INDEX_DATA *pObjIndex; ROOM_INDEX_DATA *pRoom; RESET_DATA *pReset; AREA_DATA *area; int vnum, i; bool found = FALSE; while (!found) { vnum = number_range(101, 90000); if ((pObjIndex = get_obj_index(vnum)) != NULL) { if (!CAN_WEAR(pObjIndex, ITEM_TAKE)) continue; if (pObjIndex->item_type == ITEM_MONEY) continue; if ((area = pObjIndex->area) != NULL) { for (i = area->lvnum; i <= area->uvnum; i++) { if ((pRoom = get_room_index(i)) != NULL) { for (pReset = pRoom->reset_first; pReset; pReset = pReset->next) { switch (pReset-> command) { default: break; case 'O': if ((pObjIndex = get_obj_index (pReset-> arg1)) != NULL) { if (pObjIndex->vnum == vnum) found = TRUE; } } } } } } } } return vnum; } int load_special_item(CHAR_DATA * ch) { OBJ_DATA *obj; OBJ_INDEX_DATA *pObjIndex; int vnum; vnum = number_range(99501, 99505); if ((pObjIndex = get_obj_index(vnum)) == NULL) { bug("Load_special_item : %d", vnum); return 103; // Just to be on the safe side } obj = create_object(pObjIndex, 50); obj->ownerid = ch->pcdata->playerid; SET_BIT(obj->extra_flags, ITEM_MQUEST); obj->timer = 25; // so it will eventually decay... obj_to_room(obj, get_rand_room()); return vnum; } int get_rand_mob() { int vnum, count = 0; static const int questmob_table[] = { /* * KaVir Odds and ends */ 105, 600, 902, 903, 904, 905, 907, 908, 912, 913, 914, 915, 916, 917, 918, 922, 924, 926, 1000, 1341, 1347, 1348, 1349, 1512, 2015, 2108, 2301, 2323, 2325, 2410, 2433, 2436, 2437, 2446, 2452, 2453, 2454, 2456, 2458, 2460, 2462, 2463, 2464, 2468, 2469, 2470, 2605, 2608, 2611, 2612, 2613, 2614, 2615, 2617, 2803, 2804, 2906, 3009, 3603, 4100, 4101, 4707, 5008, 5010, 5100, 5111, 5315, 6311, 6600, 6601, 6602, 6603, 6604, 6605, 6606, 6607, 6608, 7008, 7013, 7703, 8000, 8101, 8102, 8105, 8120, 8123, 8600, 9208, 9233, 9322, 11001, 11004, 11005, 11006, 11007, 11008, 11009, 11010, 11011, 11101, 11104, 11115, 11118, 11121, 11124, 11125, 11126, 11127, 11133, 11136, 11137, 11138, 11139, 14004, 14005, 14006, 14008, 14009, 14010, 14011, 14012, 19101, 19103, 19108, 25000, 25002, 25003, 25007, /* Anon DragonSpyre */ 14004, 14005, 14006, 14008, 14009, 14010, 14011, 14012, /* Wynfair Castle Dragonheart */ 19101, 19103, 19108, /* Xara Sunyata */ 31053, 31056, 31057, 31059, 31060, 31061, 31064, 31065, 31066, 31067, 31068, /* Xara Easy Evil Ones */ 11101, 11104, 11115, 11118, 11121, 11124, 11125, 11126, 11127, 11133, 11136, 11137, 11138, 11139, /* Xara Mountain of the Evil Ones */ 31100, 31101, 31102, 31103, 31104, 31105, 31106, 31107, 31109, 31110, 31111, 31113, 31114, 31115, 31119, 31120, 31121, 31122, 31123, 31124, 31125, 31126, 31127, /* Diku Midgaard */ 3009, 3603, 4100, 4101, 4707, 5008, 5010, 5100, 5111, 5315, 6311, 6600, 6601, 6602, 6603, 6604, 6605, 6606, 6607, 6608, 7008, 7013, 7703, 8000, 8101, 8102, 8105, 8120, 8123, 8600, 9208, 9233, 9322, 11001, 11004, 11005, 11006, 11007, 11008, 11009, 11010, 11011, 11101, 11104, 11115, 11118, 11121, 11124, 11125, 11126, 11127, 11133, 11136, 11137, 11138, 11139, 14004, 14005, 14006, 14008, 14009, 14010, 14011, 14012, 19101, 19103, 19108, 25000, 25002, 25003, 25007, /* Jaromir Atlantis */ 8101, 8102, 8105, 8120, 8123, /* Copper In the Air */ 1000, /* Diku Limbo */ /* Generic Smurf Village */ 105, /* Copper Plains of the North */ /* Casret Ultima */ 2410, 2433, 2436, 2437, 2446, 2452, 2453, 2454, 2456, 2458, 2460, 2462, 2463, 2464, 2468, 2469, 2470, /* Hatchet New Ofcol */ 600, /* Anon High Tower of Sorcery */ 1341, 1347, 1348, 1349, /* Vougon Gnome Village */ 1512, /* Tyrst Wyvern's Tower */ /* Raff Dwarven Catacombs */ 2015, /* Raff Dangerous Neighborhood */ 2108, /* Wench Dragon Tower */ /* Chris The Keep of Mahn-Tor */ 2301, 2323, 2325, /* Merc Troll Den */ 2803, 2804, /* Nirrad Land of the Fire Newts */ 2906, /* Copper Chapel Catacombs */ /* Copper Miden'nir */ /* Alfa Graveyard */ 3603, /* Hatchet Mud School */ /* Alfa Moria */ 4100, 4101, /* Anon Kingdom of Juargan */ 4707, /* Anon Great Eastern Desert */ 5008, 5010, /* Andi The Great Pyramid */ 2605, 2608, 2611, 2612, 2613, 2614, 2615, 2617, /* Anon Drow City */ 5100, /* Anon Thalos */ /* Kahn Old Thalos */ 5315, /* Alfa Ofcol */ /* Anon Arachnos */ 6311, /* Diku Haon Dor */ /* Anon Dwarven Kingdom */ /* Sandman Dwarven Day Care */ 6600, 6601, 6602, 6603, 6604, 6605, 6606, 6607, 6608, /* Diku Sewer */ 7008, 7013, /* Hatchet Valley of the Elves */ /* Diku Redferne's Residence */ /* Glop Mega-City One */ 8000, /* Generic Old Marsh */ /* Furey Machine Dreams */ 8600, /* Alfa Holy Grove */ /* Dylan Dylan's Area */ /* Raff Elemental Canyon */ 9208, 9233, /* Doctor Galaxy */ 9322, /* PinkF Mob Factory */ /* KaVir The learning centre */ 25000, 25002, 25003, 25007, /* KaVir Artifacts */ 600, 902, 903, 904, 905, 907, 908, 912, 913, 914, 915, 916, 917, 918, 922, 924, 926, 1000, 1341, 1347, 1348, 1349, 1512, 2015, 2108, 2301, 2323, 2325, 2410, 2433, 2436, 2437, 2446, 2452, 2453, 2454, 2456, 2458, 2460, 2462, 2463, 2464, 2468, 2469, 2470, 2605, 2608, 2611, 2612, 2613, 2614, 2615, 2617, 2803, 2804, 2906, 3009, 3603, 4100, 4101, 4707, 5008, 5010, 5100, 5111, 5315, 6311, 6600, 6601, 6602, 6603, 6604, 6605, 6606, 6607, 6608, 7008, 7013, 7703, 8000, 8101, 8102, 8105, 8120, 8123, 8600, 9208, 9233, 9322, 11001, 11004, 11005, 11006, 11007, 11008, 11009, 11010, 11011, 11101, 11104, 11115, 11118, 11121, 11124, 11125, 11126, 11127, 11133, 11136, 11137, 11138, 11139, 14004, 14005, 14006, 14008, 14009, 14010, 14011, 14012, 19101, 19103, 19108, 25000, 25002, 25003, 25007, /* Spawn Doom */ 11001, 11004, 11005, 11006, 11007, 11008, 11009, 11010, 11011, /* KaVir Vallandar's Tomb */ 30330, /* Garth Cannabis */ 30232, 30234, 30235, 30237, 30238, 30240, /* Dunkirk The Arena */ /* Andersen Astral/Githyanki */ 7703, /* Jobo Jobo's Hell */ 30100, 30101, 30102, 30103, 30104, 30105, 30106, 30107, 30108, 30109, 30110, 30111, /* Jobo Jobo's Heaven */ 99000, 99002, 99003, 99004, /* Jobo Old Dystopia */ 30406, 30409, /* Jobo Realm of the Dawnbringers */ 80001, 80002, 80003, 80004, 80005, 80006, /* Jobo Class EQ and other Relics */ /* Antibody Dome Ship StarSword */ 93000, 93001, 93002, 93003, 93004, 93007, 93008, 93009, 93010, 93011, 93012, 93013, 93014, 93015, 93016, 93017, 93018, 93029, 93030, /* Antibody Disneyworld */ 50002, 50003, 50004, 50005, 50006, 50007, 50008, 50011, 50012, 50013, 50014, 50018, 50019, 50022, 50024, 50026, 50027, 50029, /* Willaz Lair of the black Dragon */ 32000, /* Nyria Santa's Workshop */ 50201, 50204, 50205, 50206, 50207, 50208, 50209, 50210, 50211, 50212, 50213, 50214, 50216, 50217, 50218, 50219, /* Jatr Village of Kakakaru */ 77002, 77003, 77004, 77005, 77006, 77008, 77009, 77010, 77011, 77012, 77013, 77014, 77015, 77016, /* THE END */ -1 }; /* * counting the size of the table */ for (count = 0; questmob_table[count] != -1; count++); vnum = number_range(0, count - 1); return questmob_table[vnum]; } int get_rand_hard_mob() { int vnum, count = 0; static const int questmob_table[] = { /* * The Forbidden Fortress */ /* KaVir Odds and ends */ 5105, 5106, 5107, 5108, 5109, 8103, 8106, 8107, 8108, 8109, 8112, 8114, 8115, 8116, 8118, 8119, 8121, 8124, /* Anon DragonSpyre */ /* Wynfair Castle Dragonheart */ /* Xara Sunyata */ 31054, /* Xara Easy Evil Ones */ /* Xara Mountain of the Evil Ones */ /* Diku Midgaard */ 5105, 5106, 5107, 5108, 5109, 8103, 8106, 8107, 8108, 8109, 8112, 8114, 8115, 8116, 8118, 8119, 8121, 8124, /* Jaromir Atlantis */ 8103, 8106, 8107, 8108, 8109, 8112, 8114, 8115, 8116, 8118, 8119, 8121, 8124, /* Anon Drow City */ 5105, 5106, 5107, 5108, 5109, /* Jobo Old Dystopia */ 30400, 30401, 30402, 30403, 30408, 30500, 30501, 30502, 30503, 30506, 30508, 30509, /* Jobo Realm of the Dawnbringers */ /* THE END */ -1 }; /* * counting the size of the table */ for (count = 0; questmob_table[count] != -1; count++); vnum = number_range(0, count - 1); return questmob_table[vnum]; } void do_showquest(CHAR_DATA * ch, char *argument) { QUEST_DATA *quest; OBJ_INDEX_DATA *pObjIndex; MOB_INDEX_DATA *pMobIndex1; MOB_INDEX_DATA *pMobIndex2; MOB_INDEX_DATA *pMobIndex3; CHAR_DATA *gch; CHAR_DATA *ich = NULL; char buf[MAX_STRING_LENGTH]; bool found = FALSE; bool found2 = FALSE; if (IS_NPC(ch)) return; for (quest = ch->pcdata->quests; quest; quest = quest->next) { found = TRUE; switch (quest->type) { default: xprintf(buf, "Do_showquests: %s has bad quest type %d.", ch->name, quest->type); bug(buf, 0); break; case QT_MOB: if ((pMobIndex1 = get_mob_index(quest->vnums[0])) == NULL && quest->vnums[0] != -1) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->vnums[0]); bug(buf, 0); break; } if ((pMobIndex2 = get_mob_index(quest->giver)) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->giver); bug(buf, 0); break; } xprintf(buf, "You have been charged by #G%s#n to complete the following quest\n\r", pMobIndex2->short_descr); send_to_char(buf, ch); if (quest->vnums[0] != -1) { xprintf(buf, " * Find and slay #R%s#n.\n\r", pMobIndex1->short_descr); send_to_char(buf, ch); xprintf(buf, " * You have #C%d#n hours to complete the quest.\n\r", quest->time); send_to_char(buf, ch); } else { send_to_char (" * This quest has been #Ccompleted#n.\n\r", ch); xprintf(buf, " * You have #C%d#n hours to return to the questgiver.\n\r", quest->time); send_to_char(buf, ch); } break; case QT_PK: if ((pMobIndex2 = get_mob_index(quest->giver)) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->giver); bug(buf, 0); break; } for (gch = char_list; gch && !found2; gch = gch->next) { if (IS_NPC(gch)) continue; if (gch->pcdata->playerid == quest->vnums[0]) { ich = gch; found2 = TRUE; } } xprintf(buf, "You have been charged by #G%s#n to complete the following quest\n\r", pMobIndex2->short_descr); send_to_char(buf, ch); if (quest->vnums[0] != -1) { xprintf(buf, " * Hunt and slay #R%s#n.\n\r", found2 ? ich->name : "someone"); send_to_char(buf, ch); xprintf(buf, " * You have #C%d#n hours to complete the quest.\n\r", quest->time); send_to_char(buf, ch); } else { send_to_char (" * This quest has been #Ccompleted#n.\n\r", ch); xprintf(buf, " * You have #C%d#n hours to return to the questgiver.\n\r", quest->time); send_to_char(buf, ch); } break; case QT_OBJ: if ((pObjIndex = get_obj_index(quest->vnums[0])) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest item %d.", ch->name, quest->vnums[0]); bug(buf, 0); break; } if ((pMobIndex2 = get_mob_index(quest->giver)) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->giver); bug(buf, 0); break; } xprintf(buf, "You have been charged by #G%s#n to complete the following quest\n\r", pMobIndex2->short_descr); send_to_char(buf, ch); xprintf(buf, " * Find and return #R%s#n.\n\r", pObjIndex->short_descr); send_to_char(buf, ch); xprintf(buf, " * You have #C%d#n hours to complete the quest.\n\r", quest->time); send_to_char(buf, ch); break; case QT_MOB_AND_OBJ: if ((pMobIndex1 = get_mob_index(quest->vnums[0])) == NULL && quest->vnums[0] != -1) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->vnums[0]); bug(buf, 0); break; } if ((pObjIndex = get_obj_index(quest->vnums[1])) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest item %d.", ch->name, quest->vnums[1]); bug(buf, 0); break; } if ((pMobIndex2 = get_mob_index(quest->giver)) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->giver); bug(buf, 0); break; } xprintf(buf, "You have been charged by #G%s#n to complete the following quest\n\r", pMobIndex2->short_descr); send_to_char(buf, ch); if (quest->vnums[0] != -1) { xprintf(buf, " * Find and slay #R%s#n.\n\r", pMobIndex1->short_descr); send_to_char(buf, ch); } xprintf(buf, " * Find and return #R%s#n.\n\r", pObjIndex->short_descr); send_to_char(buf, ch); xprintf(buf, " * You have #C%d#n hours to complete the quest.\n\r", quest->time); send_to_char(buf, ch); break; case QT_MASS_KILL: if ((pMobIndex1 = get_mob_index(quest->vnums[0])) == NULL && quest->vnums[0] != -1) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->vnums[0]); bug(buf, 0); break; } if ((pMobIndex3 = get_mob_index(quest->vnums[1])) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->vnums[1]); bug(buf, 0); break; } if ((pMobIndex2 = get_mob_index(quest->giver)) == NULL) { xprintf(buf, "Do_showquests: %s has bad quest mob %d.", ch->name, quest->giver); bug(buf, 0); break; } xprintf(buf, "You have been charged by #G%s#n to complete the following quest\n\r", pMobIndex2->short_descr); send_to_char(buf, ch); if (quest->vnums[3] >= quest->vnums[2]) { send_to_char (" * This quest has been #Ccompleted#n.\n\r", ch); xprintf(buf, " * You have #C%d#n hours to return to the questgiver.\n\r", quest->time); send_to_char(buf, ch); } else { xprintf(buf, " * Find and slay #C%d#n monsters ranging from\n\r", quest->vnums[2] - quest->vnums[3]); send_to_char(buf, ch); xprintf(buf, " #R%s#n to #R%s#n.\n\r", pMobIndex1->short_descr, pMobIndex3->short_descr); send_to_char(buf, ch); xprintf(buf, " * You have #C%d#n hours to complete the quest.\n\r", quest->time); send_to_char(buf, ch); } break; } } if (!found) send_to_char("You are currently undertaking no quests.\n\r", ch); return; } void quest_to_char(CHAR_DATA * ch, QUEST_DATA * quest) { QUEST_DATA *quest_new; if (IS_NPC(ch)) { bug("Quest_to_char: on npc", 0); return; } if (quest_free == NULL) quest_new = alloc_perm(sizeof(*quest_new)); else { quest_new = quest_free; quest_free = quest_free->next; } *quest_new = *quest; quest_new->next = ch->pcdata->quests; ch->pcdata->quests = quest_new; return; } /* * Remove an affect from a char. */ void quest_from_char(CHAR_DATA * ch, QUEST_DATA * quest) { if (IS_NPC(ch)) { bug("Quest_from_char: on npc", 0); return; } if (ch->pcdata->quests == NULL) { bug("Quest_from_char: No quest", 0); return; } if (quest == ch->pcdata->quests) ch->pcdata->quests = quest->next; else { QUEST_DATA *prev; for (prev = ch->pcdata->quests; prev; prev = prev->next) { if (prev->next == quest) { prev->next = quest->next; break; } } if (prev == NULL) { bug("Quest_from_char: No quest", 0); return; } } quest->next = quest_free; quest_free = quest; return; } QUEST_FUN *quest_lookup(const char *name) { int cmd; for (cmd = 0; *quest_table[cmd].quest_name; cmd++) if (!str_cmp(name, quest_table[cmd].quest_name)) return quest_table[cmd].quest_fun; return 0; } char *quest_string(QUEST_FUN * fun) { int cmd; for (cmd = 0; *quest_table[cmd].quest_fun; cmd++) if (fun == quest_table[cmd].quest_fun) return quest_table[cmd].quest_name; return 0; } void give_token(CHAR_DATA * questmaster, CHAR_DATA * ch, int value) { OBJ_DATA *obj; char buf[MAX_STRING_LENGTH]; value *= ccenter[CCENTER_QPS_LEVEL]; value /= 100; if (IS_SET(ch->pcdata->tempflag, TEMP_EDGE)) value *= 1.1; if (ch->pcdata->time_tick > 49) { value *= 100 + ch->pcdata->time_tick / 10; value /= 100; } if (global_qp == TRUE) value *= 2; obj = create_object(get_obj_index(OBJ_VNUM_PROTOPLASM), 50); obj->value[0] = value; obj->level = value; obj->cost = 1000; obj->item_type = ITEM_QUEST; obj_to_char(obj, ch); free_string(obj->name); obj->name = str_dup("bone token"); free_string(obj->short_descr); xprintf(buf, "a %d point bone token", value); obj->short_descr = str_dup(buf); free_string(obj->description); xprintf(buf, "A %d point bone token lies on the floor.", value); obj->description = str_dup(buf); act("You recieve $p from $N.", ch, obj, questmaster, TO_CHAR); act("$n recieves $p from $N.", ch, obj, questmaster, TO_ROOM); ch->pcdata->questsrun++; ch->pcdata->questtotal += value; do_autosave(ch, ""); } void do_qcomplete(CHAR_DATA * ch, char *argument) { CHAR_DATA *questmaster; QUEST_DATA *quest; OBJ_DATA *obj; char arg[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; bool found = FALSE; if (IS_NPC(ch)) return; argument = one_argument(argument, arg); one_argument(argument, arg2); if ((questmaster = get_char_room(ch, NULL, arg)) == NULL) { send_to_char("You cannot seem to find that questmaster.\n\r", ch); return; } if (!IS_NPC(questmaster)) { send_to_char("Players cannot give quests.\n\r", ch); return; } if (questmaster->quest_fun != 0) { for (quest = ch->pcdata->quests; quest && !found; quest = quest->next) { if (quest->giver != questmaster->pIndexData->vnum) continue; found = TRUE; /* * Let's check if the quest is actually completed */ switch (quest->type) { default: bug("Quest_complete: Bad Quest Type", 0); return; case QT_MOB: if (quest->vnums[0] != -1) { send_to_char ("You have not completed that quest yet.\n\r", ch); return; } break; case QT_PK: if (quest->vnums[0] != -1) { send_to_char ("You have not completed that quest yet.\n\r", ch); return; } break; case QT_OBJ: if ((obj = get_obj_carry(ch, arg2, ch)) == NULL) { send_to_char ("What object do you wish to return?\n\r", ch); return; } if (obj->pIndexData->vnum != quest->vnums[0]) { send_to_char ("That is not the object of the quest.\n\r", ch); return; } extract_obj(obj); break; case QT_MOB_AND_OBJ: if (quest->vnums[0] != -1) { send_to_char ("You have not completed that quest yet.\n\r", ch); return; } if ((obj = get_obj_carry(ch, arg2, ch)) == NULL) { send_to_char ("What object do you wish to return?\n\r", ch); return; } if (obj->pIndexData->vnum != quest->vnums[1]) { send_to_char ("That is not the object of the quest.\n\r", ch); return; } extract_obj(obj); break; case QT_MASS_KILL: if (quest->vnums[2] > quest->vnums[3]) { send_to_char ("You have not completed that quest yet.\n\r", ch); return; } break; } (*questmaster->quest_fun) (questmaster, ch, "complete"); quest_from_char(ch, quest); } if (!found) send_to_char ("You are not questing for this questmaster.\n\r", ch); } else send_to_char("Doesn't seem like that's a questmaster.\n\r", ch); return; } void do_qgain(CHAR_DATA * ch, char *argument) { CHAR_DATA *questmaster; QUEST_DATA *quest; char arg[MAX_INPUT_LENGTH]; if (IS_NPC(ch)) return; one_argument(argument, arg); if ((questmaster = get_char_room(ch, NULL, arg)) == NULL) { send_to_char("You cannot seem to find that questmaster.\n\r", ch); return; } if (!IS_NPC(questmaster)) { send_to_char("Players cannot give quests.\n\r", ch); return; } if (questmaster->quest_fun != 0) { for (quest = ch->pcdata->quests; quest; quest = quest->next) { if (quest->giver == questmaster->pIndexData->vnum) { send_to_char ("You have already been given a quest from this questmaster.\n\r", ch); return; } } /* * ROCK THEM! */ (*questmaster->quest_fun) (questmaster, ch, "gain"); } else send_to_char("Doesn't seem like that's a questmaster.\n\r", ch); } void questspec_generic(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; do_say(questmaster, "Will you smurf this smurf for me?"); new_quest.type = QT_MOB; new_quest.time = 20; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = number_range(103, 109); quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 20; give_token(questmaster, ch, value); do_say(questmaster, "That's the spirit, thanks for solving my quest."); return; } } void questspec_newbie(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; do_say(questmaster, "There you go, type 'showquest' to see the quest."); new_quest.type = QT_MOB; new_quest.time = 20; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = number_range(957, 960); quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 50; give_token(questmaster, ch, value); do_say(questmaster, "You can spend the questpoints at the shop on floor 3."); return; } } void questspec_rand_mob(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; do_say(questmaster, "I charge you to find and kill this monster!"); new_quest.type = QT_MOB; new_quest.time = 15; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = get_rand_mob(); quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 100; give_token(questmaster, ch, value); do_say(questmaster, "Thanks for solving my quest, come back again if you want."); return; } } void questspec_hard_mob(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; do_say(questmaster, "I charge you to find and kill this horrible monster!"); new_quest.type = QT_MOB; new_quest.time = 25; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = get_rand_hard_mob(); quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 200; give_token(questmaster, ch, value); do_say(questmaster, "Thanks for solving my quest, come back again if you want."); return; } } void questspec_special_item(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; do_say(questmaster, "I charge you to retrive this ancient artifact of mine!"); new_quest.type = QT_OBJ; new_quest.time = 25; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = load_special_item(ch); quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 250; give_token(questmaster, ch, value); do_say(questmaster, "Thanks for solving my quest, come back again if you want."); return; } } void questspec_mob_and_item(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; do_say(questmaster, "Please slay this monster and retrive this item for me!"); new_quest.type = QT_MOB_AND_OBJ; new_quest.time = 25; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = get_rand_mob(); new_quest.vnums[1] = get_rand_item(); quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 550; give_token(questmaster, ch, value); do_say(questmaster, "Thanks for solving my quest, come back again if you want."); return; } } void questspec_mass_kill(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; int bound; bound = get_lbound(); do_say(questmaster, "Please slay these monsters."); new_quest.type = QT_MASS_KILL; new_quest.time = 30; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = bound; new_quest.vnums[1] = get_ubound(bound); new_quest.vnums[2] = number_range(8, 16); // amount needed to be killed new_quest.vnums[3] = 0; // counter quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 175; give_token(questmaster, ch, value); do_say(questmaster, "Thanks for solving my quest, come back again if you want."); return; } } void questspec_pk(CHAR_DATA * questmaster, CHAR_DATA * ch, char *argument) { if (!str_cmp(argument, "gain")) { QUEST_DATA new_quest; DESCRIPTOR_DATA *d; CHAR_DATA *gch = NULL; bool found = FALSE; for (d = descriptor_list; d && !found; d = d->next) { if (d->connected == CON_PLAYING && d->lookup_status == STATUS_DONE) { if ((gch = d->character) == NULL) continue; if (ch == gch) continue; found = TRUE; } } if (!found) { do_say(questmaster, "Sorry, I have no quest for you at this time."); return; } do_say(questmaster, "I charge you to find and destroy this player!"); new_quest.type = QT_PK; new_quest.time = 8; new_quest.giver = questmaster->pIndexData->vnum; new_quest.vnums[0] = gch->pcdata->playerid; quest_to_char(ch, &new_quest); return; } else if (!str_cmp(argument, "complete")) { int value = 400; give_token(questmaster, ch, value); do_say(questmaster, "Thanks for solving my quest, come back again if you want."); interpret(questmaster, "clap"); return; } }