diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2016-01-16 12:31:42 -0500 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2016-01-16 12:31:42 -0500 |
commit | 4b21a0fa4e6a7e35b7d9a01bbc0a7080dd392996 (patch) | |
tree | 849e56e7515d9bcd3fdcd38840af07dc2ac77987 /src | |
parent | 48cf19db2fc33875e32209eb6e32728d019cd6da (diff) |
dynamic world linking
Diffstat (limited to 'src')
-rw-r--r-- | src/common.cpp | 29 | ||||
-rw-r--r-- | src/entities.cpp | 167 | ||||
-rw-r--r-- | src/gameplay.cpp | 340 | ||||
-rw-r--r-- | src/ui.cpp | 56 | ||||
-rw-r--r-- | src/world.cpp | 398 |
5 files changed, 353 insertions, 637 deletions
diff --git a/src/common.cpp b/src/common.cpp index 84515c3..2d35313 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -92,3 +92,32 @@ void strVectorSortAlpha(std::vector<std::string> *v){ } }while(change); } + + + +/*int strCreateFunc(const char *equ){ + static unsigned int size; + static char *filebuf; + static FILE *file; + + size = 57 + strlen(equ) + 3; + + filebuf = new char[size]; + memset(filebuf,0,size); + + strcpy(filebuf,"#include <stdio.h>\n#include <math.h>\nint main(){return "); + strcat(filebuf,equ); + strcat(filebuf,";}"); + + if(!(file = fopen("gen.tmp","w"))){ + abort(); + } + + fwrite(filebuf,size,sizeof(char),file); + delete[] filebuf; + fclose(file); + + system(" + + return 0; +}*/ diff --git a/src/entities.cpp b/src/entities.cpp index 01b379b..ec335c7 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -111,6 +111,7 @@ NPC::NPC(){ //sets all of the NPC specific traits on object creation inv = new Inventory(NPC_INV_SIZE); randDialog = 6;//rand() % 12 - 1; + dialogIndex = 0; } NPC::~NPC(){ while(!aiFunc.empty()){ @@ -128,7 +129,6 @@ Structures::Structures(){ //sets the structure type alive = false; near = false; - inWorld = NULL; name = NULL; inv = NULL; @@ -446,7 +446,7 @@ void Object::interact(void){ * point to have non-normal traits so it could be invisible or invincible... */ -unsigned int Structures::spawn(BUILD_SUB sub, float x, float y, World *oi){ +unsigned int Structures::spawn(BUILD_SUB sub, float x, float y){ loc.x = x; loc.y = y; type = STRUCTURET; @@ -454,8 +454,7 @@ unsigned int Structures::spawn(BUILD_SUB sub, float x, float y, World *oi){ alive = true; bsubtype = sub; - inWorld = oi; - + /* * tempN is the amount of entities that will be spawned in the village. Currently the village * will spawn bewteen 2 and 7 villagers for the starting hut. @@ -487,7 +486,7 @@ unsigned int Structures::spawn(BUILD_SUB sub, float x, float y, World *oi){ * with type NPC. */ - oi->addNPC(loc.x + i * HLINE ,100); + //oi->addNPC(loc.x + i * HLINE ,100); } break; case FOUNTAIN: @@ -499,13 +498,13 @@ unsigned int Structures::spawn(BUILD_SUB sub, float x, float y, World *oi){ tex = new Texturec(1, sTexLoc[sub].c_str()); width = 10 * HLINE; height = 40 * HLINE; - oi->addLight({x+SCREEN_WIDTH/2,y+30*HLINE},{1.0f,1.0f,1.0f}); + //oi->addLight({x+SCREEN_WIDTH/2,y+30*HLINE},{1.0f,1.0f,1.0f}); break; case FIRE_PIT: tex = new Texturec(1, sTexLoc[sub].c_str()); width = 12 * HLINE; height = 12 * HLINE; - oi->addLight({x+SCREEN_WIDTH/2,y},{1.0f,1.0f,1.0f}); + //oi->addLight({x+SCREEN_WIDTH/2,y},{1.0f,1.0f,1.0f}); break; default: break; @@ -574,157 +573,3 @@ void Mob::wander(int timeRun){ break; } } - -char *Entity::baseSave(void){ - static EntitySavePacket *esp; - esp = new EntitySavePacket(); - if(inv) - memcpy(&esp->isp,inv->save(),sizeof(InventorySavePacket)); - else - memset(&esp->isp,0,sizeof(InventorySavePacket)); - esp->loc = loc; - esp->vel = vel; - esp->width = width; - esp->height = height; - esp->speed = speed; - esp->health = health; - esp->maxHealth = maxHealth; - esp->subtype = subtype; - esp->ticksToUse = ticksToUse; - esp->randDialog = randDialog; - esp->ground = ground; - esp->near = near; - esp->canMove = canMove; - esp->right = right; - esp->left = left; - esp->alive = alive; - esp->hit = hit; - esp->type = type; - esp->gender = gender; - if(name){ - esp->nameSize = strlen(name) + 1; - strncpy(esp->name,name,32); - }else{ - esp->nameSize = 0; - strcpy(esp->name,"\0"); - } - return (char *)esp; -} - -void Entity::baseLoad(char *e){ - EntitySavePacket *esp = (EntitySavePacket *)e; - if(esp->nameSize > 1) - inv->load(&esp->isp); - loc = esp->loc; - vel = esp->vel; - width = esp->width; - height = esp->height; - speed = esp->speed; - health = esp->health; - maxHealth = esp->maxHealth; - subtype = esp->subtype; - ticksToUse = esp->ticksToUse; - randDialog = esp->randDialog; - ground = esp->ground; - near = esp->near; - canMove = esp->canMove; - right = esp->right; - left = esp->left; - alive = esp->alive; - hit = esp->hit; - type = esp->type; - gender = esp->gender; - if(esp->nameSize){ - name = new char[esp->nameSize+1]; - strcpy(name,esp->name); - }else{ - name = new char[4]; - strncpy(name,"\0\0\0\0",4); - } -} - -char *NPC::save(unsigned int *size){ - static char *buf,*esp; - buf = new char[(*size = sizeof(EntitySavePacket) /*+ aiFunc.size() * sizeof(int(*)(NPC *))*/)]; - memcpy(buf,(esp = baseSave()),sizeof(EntitySavePacket)); - delete[] esp; - //memcpy(buf+sizeof(EntitySavePacket),aiFunc.data(),aiFunc.size() * sizeof(int(*)(NPC *))); - return buf; -} - -void NPC::load(unsigned int size,char *b){ - //unsigned int size2,i; - //int (*func)(NPC *); - baseLoad(b); - size--; - /*if(size > sizeof(EntitySavePacket)){ - size2 = (size - sizeof(EntitySavePacket)) / sizeof(int(*)(NPC *)); - std::cout<<size<<" "<<sizeof(EntitySavePacket)<<" "<<sizeof(int(*)(NPC *))<<" = "<<size2<<std::endl; - aiFunc.reserve(size2); - if(aiFunc.max_size() < size2){ - std::cout<<"what"<<std::endl; - abort(); - } - for(i=0;i<size2;i++){ - - aiFunc.push_back( - } - memcpy(aiFunc.data(),b+sizeof(EntitySavePacket),size2 * sizeof(int(*)(NPC *))); - //aiFunc.erase(aiFunc.begin()); - std::cout<<aiFunc.size()<<std::endl; - }*/ -} - -char *Structures::save(void){ - static StructuresSavePacket *ssp; - char *esp; - ssp = new StructuresSavePacket(); - esp = baseSave(); - memcpy(&ssp->esp,esp,sizeof(EntitySavePacket)); - delete[] esp; - ssp->bsubtype = bsubtype; - return (char *)ssp; -} - -void Structures::load(char *s){ - StructuresSavePacket *ssp = (StructuresSavePacket *)s; - baseLoad((char *)&ssp->esp); - bsubtype = ssp->bsubtype; -} - -char *Object::save(void){ - static ObjectSavePacket *osp; - char *esp; - osp = new ObjectSavePacket(); - memcpy(&osp->esp,(esp = baseSave()),sizeof(EntitySavePacket)); - delete[] esp; - osp->identifier = identifier; - osp->questObject = questObject; - strncpy(osp->pickupDialog,pickupDialog,256); - return (char *)osp; -} - -void Object::load(char *buf){ - ObjectSavePacket *osp = (ObjectSavePacket *)buf; - baseLoad((char *)&osp->esp); - identifier = osp->identifier; - questObject = osp->questObject; - pickupDialog = new char[256]; - strcpy(pickupDialog,osp->pickupDialog); -} - -char *Mob::save(void){ - static MobSavePacket *msp; - char *esp; - msp = new MobSavePacket(); - memcpy(&msp->esp,(esp = baseSave()),sizeof(MobSavePacket)); - delete[] esp; - msp->init_y = init_y; - return (char *)msp; -} - -void Mob::load(char *m){ - MobSavePacket *msp = (MobSavePacket *)m; - baseLoad((char *)&msp->esp); - init_y = msp->init_y; -} diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 6626811..486c16e 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -10,301 +10,143 @@ using namespace tinyxml2; extern World *currentWorld; extern Player *player; -/* - * new world - * gen - * setbackground - * setbgm - * add... - * - */ - -/* - * World definitions - */ - -/* - * initEverything() start - */ - -typedef struct { - World *ptr; - char *file; -} WorldXML; - -typedef struct { - char *name; - World *ptr; -} WorldLink; - typedef struct { NPC *npc; unsigned int index; } NPCDialog; -std::vector<NPCDialog> npcd; -std::vector<WorldXML> earthxml; -static std::vector<WorldLink> earthlnk; -std::vector<World *> earth; std::vector<XMLElement *> dopt; int commonAIFunc(NPC *speaker){ XMLDocument xml; XMLElement *exml,*oxml; - unsigned int idx; + const char *name; + unsigned int idx = 0; bool stop = false; - for(auto &n : npcd){ - if(n.npc == speaker){ - idx = n.index; - break; - } - } + xml.LoadFile(currentXML); + exml = xml.FirstChildElement("Dialog"); - for(auto &e : earthxml){ - if(e.ptr == currentWorld){ - xml.LoadFile(e.file); - - exml = xml.FirstChildElement("Dialog"); - while(strcmp(exml->Attribute("name"),speaker->name)) - exml = exml->NextSiblingElement(); - - exml = exml->FirstChildElement(); - - do{ - if(!strcmp(exml->Name(),"text")){ - if(exml->UnsignedAttribute("id") == idx){ + while(strcmp(exml->Attribute("name"),speaker->name)) + exml = exml->NextSiblingElement(); + + exml = exml->FirstChildElement(); + + do{ + if(!strcmp(exml->Name(),"text")){ + if(exml->UnsignedAttribute("id") == speaker->dialogIndex){ + + if((oxml = exml->FirstChildElement("give"))){ + while(oxml){ + player->inv->addItem((ITEM_ID)oxml->UnsignedAttribute("id"),oxml->UnsignedAttribute("count")); + oxml = oxml->NextSiblingElement(); + } + } + + if((oxml = exml->FirstChildElement("option"))){ + const char *op; + char *bp1 = new char[1],*bp2,*tmp; + bp1[0] = '\0'; + while(oxml){ + op = oxml->Attribute("text"); - if((oxml = exml->FirstChildElement("give"))){ - while(oxml){ - player->inv->addItem((ITEM_ID)oxml->UnsignedAttribute("id"),oxml->UnsignedAttribute("count")); - oxml = oxml->NextSiblingElement(); - } - } + bp2 = new char[strlen(bp1) + strlen(op) + 2]; + strcpy(bp2,bp1); - if((oxml = exml->FirstChildElement("option"))){ - const char *op; - char *bp1 = new char[1],*bp2,*tmp; - unsigned int idx = 0; - bp1[0] = '\0'; - 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); - - tmp = bp1; - bp1 = bp2; - delete[] tmp; - - dopt.push_back(oxml); - - oxml = oxml->NextSiblingElement(); - } - ui::dialogBox(speaker->name,bp1,false,exml->GetText()); - ui::waitForDialog(); - if(ui::dialogOptChosen){ - exml = dopt[ui::dialogOptChosen-1]; - } - while(!dopt.empty()) - dopt.pop_back(); - }else{ - ui::dialogBox(speaker->name,"",false,exml->GetText()); - ui::waitForDialog(); - } - if(exml->Attribute("call")){ - for(auto &n : currentWorld->npc){ - if(!strcmp(n->name,exml->Attribute("call"))){ - if(exml->QueryUnsignedAttribute("callid",&idx) == XML_NO_ERROR){ - for(auto &n2 : npcd){ - if(n2.npc == n){ - n2.index = idx; - break; - } - } - } - n->addAIFunc(commonAIFunc,false); - break; - } - } - } - if(exml->QueryUnsignedAttribute("nextid",&idx) == XML_NO_ERROR){ - for(auto &n : npcd){ - if(n.npc == speaker){ - n.index = idx; - break; - } + bp2[idx++] = ':'; + strcpy(bp2+idx,op); + idx += strlen(op); + + tmp = bp1; + bp1 = bp2; + delete[] tmp; + + dopt.push_back(oxml); + + oxml = oxml->NextSiblingElement(); + } + + ui::dialogBox(speaker->name,bp1,false,exml->GetText()); + ui::waitForDialog(); + if(ui::dialogOptChosen){ + exml = dopt[ui::dialogOptChosen-1]; + } + while(!dopt.empty()) + dopt.pop_back(); + }else{ + ui::dialogBox(speaker->name,"",false,exml->GetText()); + ui::waitForDialog(); + } + if((name = exml->Attribute("call"))){ + for(auto &n : currentWorld->npc){ + if(!strcmp(n->name,name)){ + if(exml->QueryUnsignedAttribute("callid",&idx) == XML_NO_ERROR){ + n->dialogIndex = idx; } - if(exml->QueryBoolAttribute("stop",&stop) == XML_NO_ERROR && stop) - return 0; - else if(exml->QueryBoolAttribute("pause",&stop) == XML_NO_ERROR && stop) - return 1; - else return commonAIFunc(speaker); + n->addAIFunc(commonAIFunc,false); + break; } - return 0; } } - exml = exml->NextSiblingElement(); - }while(exml); + if(exml->QueryUnsignedAttribute("nextid",&idx) == XML_NO_ERROR){ + speaker->dialogIndex = idx; + if(exml->QueryBoolAttribute("stop",&stop) == XML_NO_ERROR && stop) + return 0; + else if(exml->QueryBoolAttribute("pause",&stop) == XML_NO_ERROR && stop) + return 1; + else return commonAIFunc(speaker); + } + return 0; + } } - } + exml = exml->NextSiblingElement(); + }while(exml); return 0; } void destroyEverything(void); void initEverything(void){ - const char *name; std::vector<std::string> xmlFiles; - static char *file; - - static bool Indoor = false; - bool dialog; - float spawnx; - World **yoyo;//,**yoyo2; - XMLDocument xml; - XMLElement *wxml; + + /* + * Read the XML directory into an array. + */ if(getdir("./xml/",xmlFiles)){ std::cout<<"Error reading XML files!!!1"<<std::endl; abort(); } + /* + * Sort the files alphabetically. + */ + strVectorSortAlpha(&xmlFiles); - for(unsigned int i=0;i<xmlFiles.size();i++){ - if(strncmp(xmlFiles[i].c_str(),".",1) && strncmp(xmlFiles[i].c_str(),"..",2)){ - earthlnk.push_back((WorldLink){new char[strlen(xmlFiles[i].c_str() + 1)],NULL}); - strcpy(earthlnk.back().name,xmlFiles[i].c_str()); - } - } + /* + * Load the first file found as currentWorld. + */ for(unsigned int i=0;i<xmlFiles.size();i++){ if(strncmp(xmlFiles[i].c_str(),".",1) && strncmp(xmlFiles[i].c_str(),"..",2)){ - file = new char[5 + xmlFiles[i].size()]; - memset(file,0,5 + xmlFiles[i].size()); - strncpy(file,"xml/",4); - strcpy(file+4,xmlFiles[i].c_str()); - std::cout<<std::endl<<"Loading "<<file<<" ..."<<std::endl<<std::endl; - xml.LoadFile(file); - - wxml = xml.FirstChildElement("World");//->FirstChildElement(); - - if(wxml){ - wxml = wxml->FirstChildElement(); - earth.push_back(new World()); - Indoor = false; - }else if((wxml = xml.FirstChildElement("IndoorWorld"))){ - wxml = wxml->FirstChildElement(); - earth.push_back(new IndoorWorld()); - Indoor = true; - } - for(auto &l : earthlnk){ - if(!strcmp(file+4,l.name)){ - l.ptr = earth.back(); - break; - } - } + /* + * Read in the XML file. + */ - while(wxml){ - name = wxml->Name(); - - if(!strcmp(name,"link") && wxml->Attribute("left")){ - for(auto &l : earthlnk){ - if(!strcmp(l.name,wxml->Attribute("left"))){ - earth.back()->toLeft = &l.ptr; - break; - } - } - }else if(!strcmp(name,"link") && wxml->Attribute("right")){ - for(auto &l : earthlnk){ - if(!strcmp(l.name,wxml->Attribute("right"))){ - earth.back()->toRight = &l.ptr; - break; - } - } - }else if(Indoor && !strcmp(name,"link") && wxml->Attribute("outside")){ - for(auto &l : earthlnk){ - if(!strcmp(l.name,wxml->Attribute("outside"))){ - for(auto &b : l.ptr->build){ - if(*b->inside == earth.back()){ - ((IndoorWorld *)*b->inside)->outside = &l.ptr; - } - } - break; - } - } - }else if(!strcmp(name,"style")){ - earth.back()->setBackground((WORLD_BG_TYPE)wxml->UnsignedAttribute("background")); - earth.back()->setBGM(wxml->Attribute("bgm")); - }else if(!strcmp(name,"generation")){ - if(!strcmp(wxml->Attribute("type"),"Random")){ - if(Indoor) - ((IndoorWorld *)earth.back())->generate(wxml->UnsignedAttribute("width")); - else - earth.back()->generate(wxml->UnsignedAttribute("width")); - }else if(Indoor){ - abort(); - } - }else if(!strcmp(name,"mob")){ - if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) - earth.back()->addMob(wxml->UnsignedAttribute("type"),getRand() % earth.back()->getTheWidth() / 2,100); - else - earth.back()->addMob(wxml->UnsignedAttribute("type"),wxml->FloatAttribute("x"),wxml->FloatAttribute("y")); - }else if(!strcmp(name,"npc")){ - if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) - earth.back()->addNPC(getRand() % earth.back()->getTheWidth() / 2.0f,100); - else - earth.back()->addNPC(wxml->FloatAttribute("x"),wxml->FloatAttribute("y")); - - if(wxml->Attribute("name")){ - delete[] earth.back()->npc.back()->name; - earth.back()->npc.back()->name = new char[strlen(wxml->Attribute("name"))+1]; - strcpy(earth.back()->npc.back()->name,wxml->Attribute("name")); - } - dialog = false; - if(wxml->QueryBoolAttribute("hasDialog",&dialog) == XML_NO_ERROR && dialog){ - for(auto &ex : earthxml){ - if(ex.ptr == earth.back()) - goto SKIP; - } - earthxml.push_back((WorldXML){earth.back(),new char[64]}); - strcpy(earthxml.back().file,file); -SKIP: - earth.back()->npc.back()->addAIFunc(commonAIFunc,false); - npcd.push_back((NPCDialog){earth.back()->npc.back(),0}); - } - }else if(!strcmp(name,"structure")){ - if(wxml->Attribute("inside")){ - for(auto &l : earthlnk){ - if(!strcmp(l.name,wxml->Attribute("inside"))){ - yoyo = &l.ptr; - break; - } - } - } - if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) - earth.back()->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"),getRand() % earth.back()->getTheWidth() / 2.0f,100,yoyo);//,yoyo2); - else - earth.back()->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"),spawnx,wxml->FloatAttribute("y"),yoyo);//,yoyo2); - } - - wxml = wxml->NextSiblingElement(); - } - - delete[] file; + currentWorld = loadWorldFromXML(xmlFiles[i].c_str()); + break; } } + + /* + * Spawn the player and begin the game. + */ player = new Player(); player->spawn(200,100); - currentWorld = earth.front(); currentWorld->bgmPlay(NULL); atexit(destroyEverything); } @@ -669,15 +669,16 @@ DONE: player->right = false; left = true; right = false; - if(currentWorld->isWorldLeft()){ - memcpy(&oldpos,&player->loc,sizeof(vec2)); - tmp = currentWorld->goWorldLeft(player); - if(currentWorld != tmp){ - memcpy(&tmppos,&player->loc,sizeof(vec2)); - memcpy(&player->loc,&oldpos,sizeof(vec2)); + if(currentWorld->toLeft){ + oldpos = player->loc; + if((tmp = currentWorld->goWorldLeft(player)) != currentWorld){ + tmppos = player->loc; + player->loc = oldpos; + toggleBlackFast(); waitForCover(); - memcpy(&player->loc,&tmppos,sizeof(vec2)); + player->loc = tmppos; + currentWorld = tmp; toggleBlackFast(); } @@ -690,55 +691,52 @@ DONE: player->left = false; left = false; right = true; - if(currentWorld->isWorldRight()){ - memcpy(&oldpos,&player->loc,sizeof(vec2)); - tmp = currentWorld->goWorldRight(player); - if(currentWorld != tmp){ - memcpy(&tmppos,&player->loc,sizeof(vec2)); - memcpy(&player->loc,&oldpos,sizeof(vec2)); + if(currentWorld->toRight){ + oldpos = player->loc; + if((tmp = currentWorld->goWorldRight(player)) != currentWorld){ + tmppos = player->loc; + player->loc = oldpos; + toggleBlackFast(); waitForCover(); - memcpy(&player->loc,&tmppos,sizeof(vec2)); + player->loc = tmppos; + currentWorld = tmp; toggleBlackFast(); } } break; case SDLK_s: - /*if(player->ground == 2){ - player->ground=false; - player->loc.y-=HLINE*1.5; - }*/ break; case SDLK_w: - if(inBattle){ + /*if(inBattle){ tmp = currentWorld; currentWorld = ((Arena *)currentWorld)->exitArena(player); if(tmp != currentWorld){ //delete &tmp; toggleBlackFast(); } - }else{ + }else{*/ currentWorld=currentWorld->goInsideStructure(player); - } + //}*/ break; case SDLK_i: - currentWorld=currentWorld->goWorldBack(player); // Go back a layer if possible + /*currentWorld=currentWorld->goWorldBack(player); // Go back a layer if possible if(tmp!=currentWorld){ currentWorld->detect(player); player->vel.y=.2; player->loc.y+=HLINE*5; player->ground=false; - } + }*/ break; case SDLK_k: - currentWorld=currentWorld->goWorldFront(player); // Go forward a layer if possible + /*currentWorld=currentWorld->goWorldFront(player); // Go forward a layer if possible if(tmp!=currentWorld){ currentWorld->behind->detect(player); player->vel.y=.2; player->loc.y+=HLINE*5; player->ground=false; - } + }*/ break; case SDLK_LSHIFT: if(debug){ @@ -824,16 +822,16 @@ DONE: currentWorld->addLight({player->loc.x + SCREEN_WIDTH/2, player->loc.y},{1.0f,1.0f,1.0f}); break; case SDLK_g: - //currentWorld->addStructure(LAMP_POST, player->loc.x, player->loc.y, currentWorld); + //currentWorld->addStructure(LAMP_POST, player->loc.x, player->loc.y, NULL); break; case SDLK_h: - //currentWorld->addStructure(TOWN_HALL, player->loc.x, player->loc.y, currentWorld); + //currentWorld->addStructure(TOWN_HALL, player->loc.x, player->loc.y, NULL); break; case SDLK_j: - //currentWorld->addStructure(FOUNTAIN, player->loc.x, player->loc.y, currentWorld); + //currentWorld->addStructure(FOUNTAIN, player->loc.x, player->loc.y, NULL); break; case SDLK_v: - //currentWorld->addVillage(player->loc.x, player->loc.y, 5, 10, 100, currentWorld); + //currentWorld->addVillage(player->loc.x, player->loc.y, 5, 10, 100, NULL); break; case SDLK_b: currentWorld->addStructure(FIRE_PIT, player->loc.x, player->loc.y, NULL); diff --git a/src/world.cpp b/src/world.cpp index 6ee7255..76da308 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -42,12 +42,13 @@ const float bgDraw[3][3]={ }; float worldGetYBase(World *w){ - World *tmp = w; +// World *tmp = w; float base = GEN_MIN; - while(tmp->infront){ +/* while(tmp->infront){ tmp = tmp->infront; base -= DRAW_Y_OFFSET; - } + }*/ + if(!w)return 0; return base; } @@ -63,141 +64,13 @@ void World::setBackground(WORLD_BG_TYPE bgt){ } } -void World::save(std::ofstream *o){ - static unsigned int size2; - unsigned int size,i; - size_t bgms = strlen(bgm) + 1; - char *bufptr; - - o->write((char *)&lineCount, sizeof(unsigned int)); - o->write((char *)line ,lineCount * sizeof(struct line_t)); - o->write("GG" ,2 * sizeof(char)); - o->write((char *)star ,100 * sizeof(vec2)); - o->write((char *)&bgType , sizeof(WORLD_BG_TYPE)); - o->write((char *)&bgms , sizeof(size_t)); - o->write(bgm ,strlen(bgm)+1); - o->write("NO" ,2 * sizeof(char)); - size = npc.size(); - o->write((char *)&size,sizeof(unsigned int)); - for(i=0;i<size;i++){ - bufptr = npc[i]->save(&size2); - o->write((char *)&size2,sizeof(unsigned int)); - o->write(bufptr,size2); - delete[] bufptr; - } - size = build.size(); - o->write((char *)&size,sizeof(unsigned int)); - for(i=0;i<size;i++){ - bufptr = build[i]->save(); - o->write(bufptr,sizeof(StructuresSavePacket)); - delete[] bufptr; - } - size = object.size(); - o->write((char *)&size,sizeof(unsigned int)); - for(i=0;i<size;i++){ - bufptr = object[i]->save(); - o->write(bufptr,sizeof(ObjectSavePacket)); - delete[] bufptr; - } - size = mob.size(); - o->write((char *)&size,sizeof(unsigned int)); - for(i=0;i<size;i++){ - bufptr = mob[i]->save(); - o->write(bufptr,sizeof(MobSavePacket)); - delete[] bufptr; - } -} - -void World::load(std::ifstream *i){ - unsigned int size,size2,j; - size_t bgms; - char sig[2],*buf; - - i->read((char *)&lineCount,sizeof(unsigned int)); - - line = new struct line_t[lineCount]; - i->read((char *)line,lineCount * sizeof(struct line_t)); - - i->read(sig,2 * sizeof(char)); - if(strncmp(sig,"GG",2)){ - std::cout<<"world.dat corrupt: GG"<<std::endl; - exit(EXIT_FAILURE); - } - - x_start = 0 - getWidth(this) / 2; - - i->read((char *)star,100 * sizeof(vec2)); - i->read((char *)&bgType,sizeof(WORLD_BG_TYPE)); - - i->read((char *)&bgms,sizeof(size_t)); - bgm = new char[bgms]; - i->read(bgm,bgms); - setBGM(bgm); - - i->read(sig,2 * sizeof(char)); - if(strncmp(sig,"NO",2)){ - std::cout<<"world.dat corrupt: NO"<<std::endl; - exit(EXIT_FAILURE); - } - - i->read((char *)&size,sizeof(unsigned int)); - for(j=0;j<size;j++){ - i->read((char *)&size2,sizeof(unsigned int)); - buf = new char[size2]; - i->read(buf,size2); - npc.push_back(new NPC()); - npc.back()->load(size2,buf); - entity.push_back(npc.back()); - delete[] buf; - } - - static StructuresSavePacket *ssp; - ssp = new StructuresSavePacket(); - i->read((char *)&size,sizeof(unsigned int)); - for(j=0;j<size;j++){ - i->read((char *)ssp,sizeof(StructuresSavePacket)); - build.push_back(new Structures()); - build.back()->load((char *)ssp); - entity.push_back(build.back()); - } - delete ssp; - - static ObjectSavePacket *osp; - osp = new ObjectSavePacket(); - i->read((char *)&size,sizeof(unsigned int)); - for(j=0;j<size;j++){ - i->read((char *)osp,sizeof(ObjectSavePacket)); - object.push_back(new Object()); - object.back()->load((char *)osp); - object.back()->reloadTexture(); - entity.push_back(object.back()); - } - delete osp; - - static MobSavePacket *msp; - msp = new MobSavePacket(); - i->read((char *)&size,sizeof(unsigned int)); - for(j=0;j<size;j++){ - i->read((char *)msp,sizeof(MobSavePacket)); - mob.push_back(new Mob(0)); - mob.back()->load((char *)msp); - entity.push_back(mob.back()); - } -} - World::World(void){ bgm = NULL; bgmObj = NULL; - - /* - * Nullify pointers to other worlds. - */ - - behind = - infront = NULL; - toLeft = - toRight = (World **)&NULLPTR; + + toLeft = + toRight = NULL; /* * Allocate and clear an array for star coordinates. @@ -238,8 +111,8 @@ void World::deleteEntities(void){ } World::~World(void){ - if(behind != NULL) - delete behind; + /*if(behind != NULL) + delete behind;*/ if(bgmObj) Mix_FreeMusic(bgmObj); @@ -494,11 +367,11 @@ void World::draw(Player *p){ * Draw the background images in the appropriate order. */ -LLLOOP: - if(current->infront){ +//LLLOOP: + /*if(current->infront){ current=current->infront; goto LLLOOP; - } + }*/ cx_start = current->x_start * 1.5; width = (-x_start) << 1; @@ -597,9 +470,9 @@ LLLOOP: current=this; shade=worldShade; -LOOP1: +//LOOP1: - if(current->behind){ + //if(current->behind){ /* * Add to the y offset and shade values (explained further below) @@ -607,11 +480,11 @@ LOOP1: * */ - yoff+=DRAW_Y_OFFSET; + /*yoff+=DRAW_Y_OFFSET; shade+=DRAW_SHADE; current=current->behind; goto LOOP1; - } + }*/ /* * Here is where the actual world drawing begins. A goto is made to @@ -619,7 +492,7 @@ LOOP1: * draw the next closest layer. */ -LOOP2: +//LOOP2: /* * Calculate the offset in the line array that the player is (or would) @@ -850,14 +723,14 @@ LOOP2: * Draw the next closest world if it exists. */ - if(current->infront){ + /*if(current->infront){ yoff -= DRAW_Y_OFFSET; shade -= DRAW_SHADE; current=current->infront; goto LOOP2; - }else{ + }else{*/ /* * If finished, reset the yoff and shade variables for the next call. @@ -865,7 +738,7 @@ LOOP2: yoff=DRAW_Y_OFFSET; shade=0; - } + //} } void World::singleDetect(Entity *e){ @@ -1032,7 +905,7 @@ void World::detect(Player *p){ * Handle all remaining entities in this world. */ -LOOOOP: +//LOOOOP: static int what = 0; for(auto &e : hey->entity) hey->singleDetect(e); @@ -1053,33 +926,30 @@ LOOOOP: } what++; }what=0; - if(hey->infront){ + /*if(hey->infront){ hey = hey->infront; goto LOOOOP; - } + }*/ } -void World::addStructure(BUILD_SUB sub, float x,float y,World **inside){//,World **outside){ +void World::addStructure(BUILD_SUB sub, float x,float y,const char *inside){ build.push_back(new Structures()); - build.back()->spawn(sub,x,y,this); - build.back()->inWorld=this; - build.back()->inside = inside; - //std::cout<<"yo"<<std::endl; + build.back()->spawn(sub,x,y); + if(inside) + strcpy((build.back()->inside = new char[1 + strlen(inside)]),inside); + else + strcpy((build.back()->inside = new char[1]),"\0"); -// void * |void ** - *|void ** | void ** - //((IndoorWorld *)inside[0])->outside = outside; + //strcpy((build.back()->outside = new char[1 + strlen((char *)(currentXML+4))]),(char *)(currentXML+4)); - - - //std::cout<<"yo"<<std::endl; entity.push_back(build.back()); } -void World::addVillage(int bCount, int npcMin, int npcMax,World **inside){ +void World::addVillage(int bCount, int npcMin, int npcMax,const char *inside){ std::cout << npcMin << ", " << npcMax << std::endl; //int xwasd; for(int i = 0; i < bCount; i++){ - addStructure(HOUSE,x_start + (i * 300),100,inside);//,(World **)&NULLPTR); + addStructure(HOUSE,x_start + (i * 300),100,inside); /*std::cout<<"1\n"; HERE: xwasd = (rand()%(int)x+1000*HLINE); @@ -1141,7 +1011,7 @@ void World::addLight(vec2 loc, Color color){ * The rest of these functions are explained well enough in world.h ;) */ -void World::addLayer(unsigned int width){ +/*void World::addLayer(unsigned int width){ if(behind){ behind->addLayer(width); return; @@ -1152,7 +1022,7 @@ void World::addLayer(unsigned int width){ behind->star=star; behind->bgmObj=bgmObj; behind->bgTex=bgTex; -} +}*/ NPC *World::getAvailableNPC(void){ for(auto &n : npc){ @@ -1162,25 +1032,53 @@ NPC *World::getAvailableNPC(void){ return (NPC *)NULL; } +char *World::setToLeft(const char *file){ + if(toLeft) + delete[] toLeft; + if(!file) + return (toLeft = NULL); + + strcpy((toLeft = new char[strlen(file) + 1]),file); + return toLeft; +} +char *World::setToRight(const char *file){ + if(toRight) + delete[] toRight; + if(!file) + return (toRight = NULL); + + strcpy((toRight = new char[strlen(file) + 1]),file); + return toRight; +} + World *World::goWorldLeft(Player *p){ - if(toLeft[0]&&p->loc.x<x_start+HLINE*15){ - p->loc.x=toLeft[0]->x_start+getWidth(toLeft[0])-HLINE*10; - p->loc.y=toLeft[0]->line[toLeft[0]->lineCount-GEN_INC-1].y; - return toLeft[0]; + World *tmp; + if(toLeft && p->loc.x < x_start + HLINE * 15){ + tmp = loadWorldFromXML(toLeft); + + p->loc.x = -tmp->x_start - HLINE * 10; + p->loc.y = tmp->line[tmp->lineCount - 1].y; + + return tmp; } return this; -} +} World *World::goWorldRight(Player *p){ - if(toRight[0]&&p->loc.x+p->width>x_start+getWidth(this)-HLINE*10){ - p->loc.x=toRight[0]->x_start+HLINE*10; - p->loc.y=toRight[0]->line[0].y; - return toRight[0]; + World *tmp; + + if(toRight && p->loc.x + p->width > -x_start - HLINE * 15){ + tmp = loadWorldFromXML(toRight); + + p->loc.x = tmp->x_start + HLINE * 10; + p->loc.y = tmp->line[0].y; + + return tmp; } return this; } -World *World::goWorldBack(Player *p){ +/*World *World::goWorldBack(Player *p){ if(behind&&p->loc.x>(int)(0-getWidth(behind)/2)&&p->loc.x<getWidth(behind)/2){ return behind; } @@ -1192,42 +1090,45 @@ World *World::goWorldFront(Player *p){ return infront; } return this; -} - -bool World::isWorldLeft(void){ - return toLeft ? true : false; -} - -bool World::isWorldRight(void){ - return toRight ? true : false; -} +}*/ -std::vector<void *>thing; +std::vector<char *>inside; World *World::goInsideStructure(Player *p){ - if(!thing.size()){ + World *tmp; + char *current; + if(inside.empty()){ for(auto &b : build){ if(p->loc.x > b->loc.x && - p->loc.x + p->width < b->loc.x + b->width && - *b->inside != this ){ - thing.push_back(this); + p->loc.x + p->width < b->loc.x + b->width ){ + inside.push_back(new char[1 + strlen(currentXML)]); + strcpy(inside.back(),(char *)(currentXML+4)); + + tmp = loadWorldFromXML(b->inside); + ui::toggleBlackFast(); ui::waitForCover(); ui::toggleBlackFast(); - return (World *)*b->inside; + + return tmp; } } }else{ - for(auto &b : ((World *)thing.back())->build){ - if(*b->inside == this){ - World *tmp = (World *)thing.back(); - p->loc.x = b->loc.x + (b->width / 2) - (p->width / 2); - thing.erase(thing.end()-1); + strcpy((current = new char[strlen((char *)(currentXML + 4)) + 1]),(char *)(currentXML + 4)); + tmp = loadWorldFromXML(inside.back()); + for(auto &b : tmp->build){ + if(!strcmp(current,b->inside)){ + p->loc.x = b->loc.x + (b->width / 2); + delete[] inside.back(); + inside.pop_back(); + ui::toggleBlackFast(); ui::waitForCover(); ui::toggleBlackFast(); + return tmp; } } + delete[] current; } return this; } @@ -1241,11 +1142,11 @@ void World::addHole(unsigned int start,unsigned int end){ int World::getTheWidth(void){ World *hey=this; -LOOP: +/*LOOP: if(hey->infront){ hey=hey->infront; goto LOOP; - } + }*/ return -hey->x_start*2; } @@ -1271,8 +1172,8 @@ void IndoorWorld::generate(unsigned int width){ // Generates a flat area of wid for(i=0;i<lineCount;i++){ // Indoor areas don't have to be directly on the ground (i.e. 0)... line[i].y=INDOOR_FLOOR_HEIGHT; } - behind=infront=NULL; // Set pointers to other worlds to NULL - toLeft=toRight=NULL; // to avoid accidental calls to goWorld... functions + //behind=infront=NULL; // Set pointers to other worlds to NULL + //toLeft=toRight=NULL; // to avoid accidental calls to goWorld... functions x_start=0-getWidth(this)/2+GEN_INC/2*HLINE; // Calculate x_start (explained in world.h) } @@ -1286,6 +1187,7 @@ void IndoorWorld::draw(Player *p){ */ glEnable(GL_TEXTURE_2D); + GLfloat pointArray[light.size()][2]; for(uint w = 0; w < light.size(); w++){ pointArray[w][0] = light[w].loc.x - offset.x; @@ -1397,3 +1299,103 @@ World *Arena::exitArena(Player *p){ return this; } } + +#include <tinyxml2.h> +using namespace tinyxml2; + +char *currentXML = NULL; + +extern int commonAIFunc(NPC *); + +World *loadWorldFromXML(const char *path){ + XMLDocument xml; + XMLElement *wxml; + + World *tmp; + float spawnx; + bool dialog,Indoor; + + const char *ptr,*name; + + unsigned int size = 5 + strlen(path); + + if(currentXML) + delete[] currentXML; + + memset((currentXML = new char[size]),0,size); + strcpy(currentXML,"xml/"); + strcat(currentXML,path); + + //std::cout<<currentXML<<std::endl; + + xml.LoadFile(currentXML); + wxml = xml.FirstChildElement("World"); + + if(wxml){ + wxml = wxml->FirstChildElement(); + Indoor = false; + tmp = new World(); + }else if((wxml = xml.FirstChildElement("IndoorWorld"))){ + wxml = wxml->FirstChildElement(); + Indoor = true; + tmp = new IndoorWorld(); + } + + while(wxml){ + name = wxml->Name(); + + if(!strcmp(name,"link")){ + if((ptr = wxml->Attribute("left"))) + tmp->setToLeft(ptr); + else if((ptr = wxml->Attribute("right"))) + tmp->setToRight(ptr); + else abort(); + }else if(!strcmp(name,"style")){ + tmp->setBackground((WORLD_BG_TYPE)wxml->UnsignedAttribute("background")); + tmp->setBGM(wxml->Attribute("bgm")); + }else if(!strcmp(name,"generation")){ + if(!strcmp(wxml->Attribute("type"),"Random")){ + if(Indoor) + ((IndoorWorld *)tmp)->generate(wxml->UnsignedAttribute("width")); + else + tmp->generate(wxml->UnsignedAttribute("width")); + }else if(Indoor){ + abort(); + } + }else if(!strcmp(name,"mob")){ + unsigned int type; + + type = wxml->UnsignedAttribute("type"); + if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) + tmp->addMob(type,getRand() % tmp->getTheWidth() / 2,100); + else + tmp->addMob(type,spawnx,wxml->FloatAttribute("y")); + }else if(!strcmp(name,"npc")){ + const char *npcname; + + if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) + tmp->addNPC(getRand() % tmp->getTheWidth() / 2.0f,100); + else + tmp->addNPC(spawnx,wxml->FloatAttribute("y")); + + if((npcname = wxml->Attribute("name"))){ + delete[] tmp->npc.back()->name; + tmp->npc.back()->name = new char[strlen(npcname) + 1]; + strcpy(tmp->npc.back()->name,npcname); + } + + dialog = false; + if(wxml->QueryBoolAttribute("hasDialog",&dialog) == XML_NO_ERROR && dialog) + tmp->npc.back()->addAIFunc(commonAIFunc,false); + + }else if(!strcmp(name,"structure")){ + ptr = wxml->Attribute("inside"); + if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) + tmp->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"),getRand() % tmp->getTheWidth() / 2.0f,100,ptr); + else + tmp->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"),spawnx,wxml->FloatAttribute("y"),ptr); + } + wxml = wxml->NextSiblingElement(); + } + return tmp; +} |