- quests can require one item for completion
- better-er text drawing
- can set world themes through XML
+
+2/10/2016:
+==========
+
+ - proper quest handling: multiple req's, re-classified, overall good
+ - began considering unique_ptr's because they're good
+ - fixed inventory everything
+ - themes work
--- /dev/null
+<?xml version="1.0"?>
+<screen width="1280" height="800" fullscreen="true"/>
+
+<!--
+
+Available fonts:
+
+ 8-BIT WONDER.TTF
+ FreePixel.ttf
+ Perfect DOS VGA 437.ttf
+ Perfect DOS VGA 437 Win.ttf
+ PIXEAB__.TTF
+ PIXEARG_.TTF
+ VCR_OSD_MONO_1.001.ttf
+
+-->
+
+<font path="ttf/FreePixel.ttf"/>
+
+<hline size="3"/>
+
+<volume>
+ <master volume="100"/>
+ <music volume="50"/>
+ <sfx volume="50"/>
+</volume>
\r
#define DEBUG\r
\r
+struct need_t {\r
+ std::string name;\r
+ int n;\r
+};\r
+\r
typedef struct {\r
std::string title;\r
std::string desc;\r
struct item_t reward;\r
- std::vector<std::string> need;\r
+ std::vector<struct need_t> need;\r
} Quest;\r
\r
/**\r
* Adds a quest to the current quest vector by its title.\r
*/\r
\r
- int assign(const char *t);\r
+ int assign(std::string title,std::string desc,std::string req);\r
\r
/**\r
* Drops a quest through its title.\r
*/\r
\r
- int drop(const char *t);\r
+ int drop(std::string title);\r
\r
/**\r
* Finishes a quest through it's title, also giving a pointer to the Entity\r
int addItem(std::string name,uint count);
int takeItem(std::string name,uint count);
+ int hasItem(std::string name);
int useItem(void);
bool detectCollision(vec2,vec2);
\r
extern Player *player;\r
\r
-int QuestHandler::assign(const char *t){\r
- return strcmp(t,"h");\r
+int QuestHandler::assign(std::string title,std::string desc,std::string req){\r
+ Quest tmp;\r
+ char *tok;\r
+ \r
+ tmp.title = title;\r
+ tmp.desc = desc;\r
+\r
+ std::unique_ptr<char[]> buf (new char[req.size()]);\r
+\r
+ strcpy(buf.get(),req.c_str());\r
+ tok = strtok(buf.get(),"\n\r\t,");\r
+ tmp.need.push_back({"\0",0});\r
+ \r
+ while(tok){\r
+ if(tmp.need.back().name != "\0"){\r
+ tmp.need.back().n = atoi(tok);\r
+ tmp.need.push_back({"\0",0});\r
+ }else\r
+ tmp.need.back().name = tok;\r
+ \r
+ tok = strtok(NULL,"\n\r\t,");\r
+ }\r
+ \r
+ tmp.need.pop_back();\r
+ current.push_back(tmp);\r
+\r
+ return 0;\r
}\r
\r
-int QuestHandler::drop(const char *t){\r
- return strcmp(t,"h");\r
+int QuestHandler::drop(std::string title){\r
+ for(unsigned int i=0;i<current.size();i++){\r
+ if(current[i].title == title){\r
+ current.erase(current.begin()+i);\r
+ return 0;\r
+ }\r
+ }\r
+ return -1;\r
}\r
\r
int QuestHandler::finish(std::string t){\r
for(unsigned int i=0;i<current.size();i++){\r
if(current[i].title == t){\r
- if(!player->inv->takeItem(current[i].need.back(),1)){\r
- current.erase(current.begin()+i);\r
- return 1;\r
- }else return 0;\r
+ for(auto &n : current[i].need){\r
+ if(player->inv->hasItem(n.name) < n.n)\r
+ return 0;\r
+ }\r
+ \r
+ for(auto &n : current[i].need){\r
+ player->inv->takeItem(n.name,n.n);\r
+ }\r
+ \r
+ current.erase(current.begin()+i);\r
+ return 1;\r
}\r
}\r
return 0;\r
if((oxml = exml->FirstChildElement("quest"))){
const char *qname;
- Quest tmp;
+
while(oxml){
- if((qname = oxml->Attribute("assign"))){
- tmp.title = qname;
- tmp.desc = "None";
- tmp.reward = (struct item_t){0,0};
-
- if(oxml->GetText()){
- tmp.need.push_back(oxml->GetText());
- }
-
- player->qh.current.push_back(tmp);
- }else if((qname = oxml->Attribute("check"))){
+ if((qname = oxml->Attribute("assign")))
+ player->qh.assign(qname,"None",(std::string)oxml->GetText());
+ else if((qname = oxml->Attribute("check"))){
if(player->qh.hasQuest(qname) && player->qh.finish(qname)){
- player->qh.finish(qname);
goto CONT;
}else{
oldidx = speaker->dialogIndex;
static vec2 itemLoc;
Mix_Chunk* swordSwing;
-std::vector<Item *> itemMap;
+static std::vector<Item *> itemMap;
void items(void){
XMLDocument xml;
itemMap.back()->texloc = exml->Attribute("sprite");
exml = exml->NextSiblingElement();
- }
+ }
}
int Inventory::addItem(std::string name,uint count){
return 0;
}
}
- items.push_back((item_t){i,count});
+ items.push_back((item_t){count,i});
return 0;
}
}
return -2;
}
+int Inventory::hasItem(std::string name){
+ unsigned int id = 999999;
+
+ for(unsigned int i=0;i<itemMap.size();i++){
+ if(itemMap[i]->name == name){
+ id = i;
+ break;
+ }
+ }
+
+ if(id == 999999)
+ return 0;
+
+ for(auto &i : items){
+ if(i.id == id)
+ return i.count;
+ }
+
+ return 0;
+}
+
static GLuint *itemtex;
void itemDraw(Player *p,uint id);
}
glEnd();
glDisable(GL_TEXTURE_2D);
- ui::putText(r.end.x-(itemWide/2),r.end.y-(itemWide*.9),"%s",itemMap[items[a].id]->name);
+ ui::putText(r.end.x-(itemWide/2),r.end.y-(itemWide*.9),"%s",itemMap[items[a].id]->name.c_str());
ui::putText(r.end.x-(itemWide/2)+(itemWide*.85),r.end.y-(itemWide/2),"%d",items[a].count);
}
<Dialog name="Johnny">
<text id="0" nextid="1" pause="true" >
Sup bro! Have a quest. To complete it, just go talk to Ralph again.
- <quest assign="Your First Quest" >Dank MayMay</quest>
+ <quest assign="Your First Quest" >
+ Dank MayMay,2
+ Wood Sword,1
+ </quest>
</text>
<text id="1" nextid="1" pause="true" >
</IndoorWorld>
<Dialog name="Bob">
- <text id="0">
- Hey. Have a Dank Maymay :)
+ <text id="0" nextid="1" pause="true">
+ Hey. Have a Dank MayMay :)
<give id="Dank MayMay" count="1" />
</text>
+
+ <text id="1" nextid="2">
+ What? You want another Dank MayMay?
+ </text>
+
+ <text id="2" nextid="3" pause="true">
+ K.
+ <give id="Dank MayMay" count="1" />
+ </text>
+
+ <text id="3" nextid="4">
+ Well... I'm out of Dank MayMays.
+ </text>
+
+ <text id="4">
+ Have a sword though.
+ <give id="Wood Sword" count="1" />
+ </text>
+
</Dialog>