/* * oldQuest.cpp * Xml parsing and various quest related functions (Including monster interaction) * ____ _ * | _ \ ___ __ _| |_ __ ___ ___ * | |_) / _ \/ _` | | '_ ` _ \/ __| * | _ < __/ (_| | | | | | | \__ \ * |_| \_\___|\__,_|_|_| |_| |_|___/ * * Permission to use, modify and distribute is granted via the * Creative Commons - Attribution - Non Commercial - Share Alike 3.0 License * http://creativecommons.org/licenses/by-nc-sa/3.0/ * * Copyright (C) 2007-2012 Jason Mitchell, Randi Mitchell * Contributions by Tim Callahan, Jonathan Hseu * Based on Mordor (C) Brooke Paul, Brett J. Vickers, John P. Freeman * */ #include "mud.h" #include "commands.h" #include "factions.h" #include "quests.h" #include "tokenizer.h" // Function prototypes static questPtr parseQuest(xmlDocPtr doc, xmlNodePtr cur); // Loads the quests file bool Config::loadQuestTable() { xmlDocPtr doc; questPtr curquest; xmlNodePtr cur; char filename[80]; // build an XML tree from a the file sprintf(filename, "%s/questTable.xml", Path::Game); doc = xml::loadFile(filename, "Quests"); if(doc == NULL) return(false); cur = xmlDocGetRootElement(doc); numQuests = 0; memset(questTable, 0, sizeof(questTable)); // First level we expect a Quest cur = cur->children; while(cur && xmlIsBlankNode(cur)) cur = cur->next; if(cur == 0) { xmlFreeDoc(doc); return(false); } clearQuestTable(); // Go through the nodes and grab off all Quests while(cur != NULL) { if((!strcmp((char *)cur->name, "Quest"))) { // Parse the quest curquest = parseQuest(doc, cur); // If we parsed a valid quest, add it to the table if(curquest != NULL) questTable[numQuests++] = curquest; // No more than 128 quests currently allowed if(numQuests >= 128) break; } cur = cur->next; } xmlFreeDoc(doc); xmlCleanupParser(); return(true); } static questPtr parseQuest(xmlDocPtr doc, xmlNodePtr cur) { questPtr ret = NULL; ret = new quest; if(ret == NULL) { loge("Quest_Load: out of memory\n"); return(NULL); } cur = cur->children; // Note: (char *)xmlNodeListGetString returns a string which MUST be freed // thus we can't use atoi...use toInt or toLong while(cur != NULL) { if((!strcmp((char *)cur->name, "ID"))) ret->num = xml::toNum<int>((char *)xmlNodeListGetString(doc, cur->children, 1)); if((!strcmp((char *)cur->name, "name"))) ret->name = (char *)xmlNodeListGetString(doc, cur->children, 1); if((!strcmp((char *)cur->name, "exp"))) ret->exp = xml::toNum<int>((char *)xmlNodeListGetString(doc, cur->children, 1)); cur = cur->next; } return (ret); } // Free the memory being used by the quest table void Config::clearQuestTable() { int i; for(i=0;i<numQuests;i++) freeQuest(questTable[i]); } // Free the memory being used by a quest void freeQuest(questPtr toFree) { if(toFree->name) free(toFree->name); delete toFree; } void fulfillQuest(Player* player, Object* object) { if(object->getQuestnum()) { player->print("Quest fulfilled!"); if(object->getType() != MONEY) { player->printColor(" Don't drop %P.\n", object); player->print("You won't be able to pick it up again."); } player->print("\n"); player->setQuest(object->getQuestnum()-1); player->addExperience(get_quest_exp(object->getQuestnum())); if(!player->halftolevel()) player->print("%ld experience granted.\n", get_quest_exp(object->getQuestnum())); } for(Object *obj : object->objects) { fulfillQuest(player, obj); } }