diff options
Diffstat (limited to 'src/gameplay.cpp')
-rw-r--r-- | src/gameplay.cpp | 105 |
1 files changed, 83 insertions, 22 deletions
diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 486c16e..b8e51dc 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -20,21 +20,38 @@ std::vector<XMLElement *> dopt; int commonAIFunc(NPC *speaker){ XMLDocument xml; XMLElement *exml,*oxml; + const char *name; unsigned int idx = 0; bool stop = false; + /* + * Load the current world's XML file into memory for reading. + */ + xml.LoadFile(currentXML); exml = xml.FirstChildElement("Dialog"); + /* + * Search for the correct dialog block. + */ + while(strcmp(exml->Attribute("name"),speaker->name)) exml = exml->NextSiblingElement(); exml = exml->FirstChildElement(); + /* + * Search for which text block should be used. + */ + do{ if(!strcmp(exml->Name(),"text")){ - if(exml->UnsignedAttribute("id") == speaker->dialogIndex){ + if(exml->UnsignedAttribute("id") == (unsigned)speaker->dialogIndex){ + + /* + * Handle any 'give' requests. + */ if((oxml = exml->FirstChildElement("give"))){ while(oxml){ @@ -43,64 +60,106 @@ int commonAIFunc(NPC *speaker){ } } + /* + * Handle any 'take' requests. + */ + + if((oxml = exml->FirstChildElement("take"))){ + while(oxml){ + player->inv->takeItem((ITEM_ID)oxml->UnsignedAttribute("id"),oxml->UnsignedAttribute("count")); + oxml = oxml->NextSiblingElement(); + } + } + + /* + * Handle dialog options. + */ + if((oxml = exml->FirstChildElement("option"))){ - const char *op; - char *bp1 = new char[1],*bp2,*tmp; - bp1[0] = '\0'; + + /* + * Convert the list of options into a single colon-separated string. + */ + + std::string optstr; + while(oxml){ - op = oxml->Attribute("text"); - - bp2 = new char[strlen(bp1) + strlen(op) + 2]; - strcpy(bp2,bp1); - bp2[idx++] = ':'; - strcpy(bp2+idx,op); - idx += strlen(op); + /* + * Create a buffer big enough for the next option. + */ + + optstr.append((std::string)":" + oxml->Attribute("text")); - tmp = bp1; - bp1 = bp2; - delete[] tmp; + /* + * Append the next option. + */ dopt.push_back(oxml); oxml = oxml->NextSiblingElement(); } - ui::dialogBox(speaker->name,bp1,false,exml->GetText()); + /* + * Get the player's choice, then set the XMLElement to the option's block. + */ + + ui::dialogBox(speaker->name,optstr.c_str(),false,exml->GetText()); ui::waitForDialog(); - if(ui::dialogOptChosen){ + + if(ui::dialogOptChosen) exml = dopt[ui::dialogOptChosen-1]; - } + while(!dopt.empty()) dopt.pop_back(); }else{ + + /* + * No options - simply print the text. + */ + ui::dialogBox(speaker->name,"",false,exml->GetText()); ui::waitForDialog(); } + + /* + * Give another NPC dialog if requested. + */ + if((name = exml->Attribute("call"))){ for(auto &n : currentWorld->npc){ if(!strcmp(n->name,name)){ - if(exml->QueryUnsignedAttribute("callid",&idx) == XML_NO_ERROR){ + if(exml->QueryUnsignedAttribute("callid",&idx) == XML_NO_ERROR) n->dialogIndex = idx; - } n->addAIFunc(commonAIFunc,false); break; } } } + + /* + * Handle the next dialog block if this one leads to another. + */ + if(exml->QueryUnsignedAttribute("nextid",&idx) == XML_NO_ERROR){ speaker->dialogIndex = idx; - if(exml->QueryBoolAttribute("stop",&stop) == XML_NO_ERROR && stop) + + if(exml->QueryBoolAttribute("stop",&stop) == XML_NO_ERROR && stop){ + speaker->dialogIndex = -1; return 0; - else if(exml->QueryBoolAttribute("pause",&stop) == XML_NO_ERROR && stop) + }else if(exml->QueryBoolAttribute("pause",&stop) == XML_NO_ERROR && stop){ + speaker->dialogIndex = -1; return 1; - else return commonAIFunc(speaker); + }else return commonAIFunc(speaker); } return 0; } } + exml = exml->NextSiblingElement(); + }while(exml); + return 0; } @@ -155,6 +214,8 @@ extern std::vector<int (*)(NPC *)> AIpreload; extern std::vector<NPC *> AIpreaddr; void destroyEverything(void){ + currentWorld->save(); + delete currentWorld; while(!AIpreload.empty()) AIpreload.pop_back(); |