aboutsummaryrefslogtreecommitdiffstats
path: root/src/gameplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gameplay.cpp')
-rw-r--r--src/gameplay.cpp105
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();