aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2016-01-20 08:42:46 -0500
committerClyne Sullivan <tullivan99@gmail.com>2016-01-20 08:42:46 -0500
commit1e6676c35ce4990981e8cda389ba39108437d66d (patch)
treec1605794e8fa3d2e3dc9e29a91b0acaded59c8be /src
parent1eced16d75322832617a1b42ec94580a9713e8f0 (diff)
WIP save/load
Diffstat (limited to 'src')
-rw-r--r--src/Texture.cpp7
-rw-r--r--src/common.cpp19
-rw-r--r--src/entities.cpp2
-rw-r--r--src/gameplay.cpp105
-rw-r--r--src/inventory.cpp4
-rw-r--r--src/ui.cpp16
-rw-r--r--src/world.cpp64
7 files changed, 188 insertions, 29 deletions
diff --git a/src/Texture.cpp b/src/Texture.cpp
index 5e367a9..0dd1eff 100644
--- a/src/Texture.cpp
+++ b/src/Texture.cpp
@@ -63,6 +63,13 @@ namespace Texture{
return object;
}
+ void freeTextures(void){
+ for(unsigned int i=0;i<LoadedTextureCounter;i++){
+ glDeleteTextures(1,&LoadedTexture[i]->tex);
+ delete[] LoadedTexture[i]->name;
+ delete LoadedTexture[i];
+ }
+ }
}
Texturec::Texturec(uint amt, ...){
diff --git a/src/common.cpp b/src/common.cpp
index 2d35313..334671e 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -93,7 +93,24 @@ void strVectorSortAlpha(std::vector<std::string> *v){
}while(change);
}
-
+const char *readFile(const char *path){
+ std::ifstream in (path,std::ios::in);
+ unsigned int size;
+ GLchar *buf;
+
+ if(!in.is_open()){
+ std::cout<<"Error reading file "<<path<<"!"<<std::endl;
+ abort();
+ }
+
+ in.seekg(0,in.end);
+ buf = new GLchar[(size = in.tellg())];
+ in.seekg(0,in.beg);
+ in.read(buf,size);
+
+ in.close();
+ return buf;
+}
/*int strCreateFunc(const char *equ){
static unsigned int size;
diff --git a/src/entities.cpp b/src/entities.cpp
index ec335c7..faf415b 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -137,6 +137,8 @@ Structures::~Structures(){
delete tex;
if(name)
delete[] name;
+ if(inside)
+ delete[] inside;
}
Mob::Mob(int sub){
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();
diff --git a/src/inventory.cpp b/src/inventory.cpp
index b6819d1..108051c 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -29,6 +29,10 @@ void initInventorySprites(void){
Mix_Volume(2,100);
}
+void destroyInventory(void){
+ Mix_FreeChunk(swordSwing);
+}
+
char *getItemTexturePath(ITEM_ID id){
return item[id].textureLoc;
}
diff --git a/src/ui.cpp b/src/ui.cpp
index eecd7ef..2896102 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -67,6 +67,8 @@ unsigned int fadeIntensity = 0;
bool inBattle = false;
Mix_Chunk *battleStart;
+Mix_Chunk *sanic;
+
namespace ui {
/*
@@ -119,9 +121,20 @@ namespace ui {
DEBUG_printf("Initialized FreeType2.\n",NULL);
#endif // DEBUG
dialogClick = Mix_LoadWAV("assets/click.wav");
+ battleStart = Mix_LoadWAV("assets/sounds/frig.wav");
+ sanic = Mix_LoadWAV("assets/sounds/sanic.wav");
Mix_Volume(1,50);
}
+ void destroyFonts(void){
+ FT_Done_Face(ftf);
+ FT_Done_FreeType(ftl);
+
+ Mix_FreeChunk(dialogClick);
+ Mix_FreeChunk(battleStart);
+ Mix_FreeChunk(sanic);
+ }
+
/*
* Sets a new font family to use (*.ttf).
*/
@@ -740,8 +753,6 @@ DONE:
break;
case SDLK_LSHIFT:
if(debug){
- Mix_Chunk *sanic;
- sanic = Mix_LoadWAV("assets/sounds/sanic.wav");
Mix_PlayChannel(1,sanic,-1);
player->speed = 4.0f;
}else
@@ -884,7 +895,6 @@ DONE:
fadeEnable ^= true;
fadeWhite = true;
fadeFast = true;
- battleStart = Mix_LoadWAV("assets/sounds/frig.wav");
Mix_PlayChannel(1,battleStart,0);
}
}
diff --git a/src/world.cpp b/src/world.cpp
index 3ad877b..ed1b522 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -102,7 +102,7 @@ void World::deleteEntities(void){
entity.pop_back();
}
while(!particles.empty()){
- //delete particles.back();
+ delete particles.back();
particles.pop_back();
}
while(!light.empty()){
@@ -121,6 +121,9 @@ World::~World(void){
delete bgTex;
delete[] star;
delete[] line;
+
+ delete[] toLeft;
+ delete[] toRight;
deleteEntities();
}
@@ -1150,6 +1153,51 @@ int World::getTheWidth(void){
return -hey->x_start*2;
}
+void World::save(void){
+ static std::string data;
+
+ std::string save = (std::string)currentXML + ".dat";
+ std::ofstream out (save,std::ios::out | std::ios::binary);
+
+ std::cout<<"Saving to "<<save<<" ..."<<std::endl;
+
+ //data.append(std::to_string(npc.size()) + "\n");
+ for(auto &n : npc)
+ data.append(std::to_string(n->dialogIndex) + "\n");
+
+ data.append("dOnE\0");
+ out.write(data.c_str(),data.size());
+
+ out.close();
+}
+
+#include <sstream>
+
+extern int commonAIFunc(NPC *);
+
+void World::load(void){
+ std::string save,data,line;
+
+ save = (std::string)currentXML + ".dat";
+ data = readFile(save.c_str());
+ std::istringstream iss (data);
+
+ for(auto &n : npc){
+ std::getline(iss,line);
+ if((n->dialogIndex = std::stoi(line)) != -1)
+ n->addAIFunc(commonAIFunc,false);
+ }
+
+ while(std::getline(iss,line)){
+ if(line == "dOnE")
+ break;
+
+ std::cout<<line<<std::endl;
+ }
+
+ //abort();
+}
+
IndoorWorld::IndoorWorld(void){
}
@@ -1306,7 +1354,7 @@ using namespace tinyxml2;
char *currentXML = NULL;
-extern int commonAIFunc(NPC *);
+extern World *currentWorld;
World *loadWorldFromXML(const char *path){
XMLDocument xml;
@@ -1320,8 +1368,10 @@ World *loadWorldFromXML(const char *path){
unsigned int size = 5 + strlen(path);
- if(currentXML)
+ if(currentXML){
+ currentWorld->save();
delete[] currentXML;
+ }
memset((currentXML = new char[size]),0,size);
strcpy(currentXML,"xml/");
@@ -1388,6 +1438,7 @@ World *loadWorldFromXML(const char *path){
dialog = false;
if(wxml->QueryBoolAttribute("hasDialog",&dialog) == XML_NO_ERROR && dialog)
tmp->npc.back()->addAIFunc(commonAIFunc,false);
+ else tmp->npc.back()->dialogIndex = -1;
}else if(!strcmp(name,"structure")){
ptr = wxml->Attribute("inside");
@@ -1398,5 +1449,12 @@ World *loadWorldFromXML(const char *path){
}
wxml = wxml->NextSiblingElement();
}
+
+ std::ifstream dat (((std::string)currentXML + ".dat").c_str());
+ if(dat.good()){
+ dat.close();
+ tmp->load();
+ }
+
return tmp;
}