]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
dynamic world linking
authorClyne Sullivan <tullivan99@gmail.com>
Sat, 16 Jan 2016 17:31:42 +0000 (12:31 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Sat, 16 Jan 2016 17:31:42 +0000 (12:31 -0500)
Changelog
include/common.h
include/entities.h
include/world.h
src/common.cpp
src/entities.cpp
src/gameplay.cpp
src/ui.cpp
src/world.cpp
xml/playerSpawnHill1_Building1.xml

index cad80bad4fe413e9444575b296241476559e16ff..a4c3ede6639f47d50e6f94d3a7999d7862634f02 100644 (file)
--- a/Changelog
+++ b/Changelog
        - xml'd buildings and their indoors
        - xml'd settings for screen dimensions
        - xml'd item giving through npc dialog
+
+1/14/2015:
+==========
+
+       - pondered on non-random generation
+       - fixed some drawing issues
+       - made spritesheet for easier solid-color-texture drawing
+       
+       - began to incorporate XML into the world class for dynamic world loading...
+
+1/16/2015:
+==========
+
+       - removed layers
+       - switched world linking from pointers to file names, rewrote all world-linking code
+       - worlds are now loaded dynamically
index 48026b08722b06a25b952ad2bf810974975ff0fe..ae832f1bed777c09fe06f22895c8f6e27d42ba0a 100644 (file)
@@ -205,6 +205,8 @@ unsigned int millis(void);
 int getdir(const char *dir, std::vector<std::string> &files);
 void strVectorSortAlpha(std::vector<std::string> *v);
 
+int strCreateFunc(const char *equ);
+
 extern void *NULLPTR;
 
 #endif // COMMON_H
index 412ec42537d7064d8ce58c562947dfa8bb320878..d434546914614038dcc0e59b72e49dd2822a9030 100644 (file)
@@ -47,31 +47,6 @@ enum BUILD_SUB{
        FIRE_PIT = 7
 };
 
-typedef struct {
-       InventorySavePacket isp;
-       vec2 loc;
-       vec2 vel;
-       float width;
-       float height;
-       float speed;
-       float health;
-       float maxHealth;
-       int subtype;
-       int ticksToUse;
-       unsigned int randDialog;
-       unsigned char ground;
-       bool near;
-       bool canMove;
-       bool right,left;
-       bool alive;
-       bool hit;
-       _TYPE type;
-       GENDER  gender;
-       size_t nameSize;
-       char   name[32];
-       //Texturec *tex;
-} __attribute__ ((packed)) EntitySavePacket;
-
 class World;
 
 class Particles{
@@ -176,9 +151,6 @@ public:
        virtual void interact(){}
        
        virtual ~Entity(){}
-       
-       char *baseSave(void);
-       void baseLoad(char *);
 };
 
 class Player : public Entity{
@@ -194,6 +166,7 @@ public:
 class NPC : public Entity{
 public:
        std::vector<int (*)(NPC *)>aiFunc;
+       unsigned int dialogIndex;
        
        NPC();
        ~NPC();
@@ -201,29 +174,18 @@ public:
        void addAIFunc(int (*func)(NPC *),bool preload);
        void interact();
        void wander(int);
-       
-       char *save(unsigned int *size);
-       void load(unsigned int,char *b);
 };
 
-typedef struct {
-       EntitySavePacket esp;
-       BUILD_SUB bsubtype;
-} __attribute__ ((packed)) StructuresSavePacket;
-
 class Structures : public Entity{
 public:
-       World *inWorld;
-       World **inside;
        BUILD_SUB bsubtype;
+       char *inside;
+       //char *outside;
        
        Structures();
        ~Structures();
        
-       unsigned int spawn(BUILD_SUB, float, float, World *);
-       
-       char *save(void);
-       void load(char *s);
+       unsigned int spawn(BUILD_SUB, float, float);
 };
 
 class Mob : public Entity{
@@ -235,24 +197,8 @@ public:
        ~Mob();
        
        void wander(int);
-       
-       char *save(void);
-       void load(char *);
 };
 
-typedef struct {
-       EntitySavePacket esp;
-       double init_y;
-       //void (*hey)(Mob *callee);
-} __attribute__ ((packed)) MobSavePacket;
-
-typedef struct {
-       EntitySavePacket esp;
-       ITEM_ID identifier;
-       bool questObject;
-       char pickupDialog[256];
-} __attribute__ ((packed)) ObjectSavePacket;
-
 class Object : public Entity{
 private:
        ITEM_ID identifier;
@@ -267,9 +213,6 @@ public:
        void reloadTexture(void);
        
        void interact(void);
-       
-       char *save(void);
-       void load(char *);
 };
 #endif // ENTITIES_H
 
index 91fcf8ad5fcf093a91f6915fe7224ac9133cbe43..a1cc870b58962aa12643c1cfbfee929ba9b17817 100644 (file)
 
 #define GEN_INC 10
 
+/**
+ * Defines the lowest possible y value for a world line.
+ */
 
 #define GEN_MIN  80
+
+/**
+ * Defines the highest possible y value for a randomly generated world line.
+ */
+
 #define GEN_MAX  110
 
 
@@ -54,11 +62,15 @@ typedef enum {
        RAIN            /**< Rain (not implemented :) )*/
 } WEATHER;
 
+/**
+ * The light structure, used to store light coordinates and color.
+ */
+
+typedef struct {
+       vec2 loc;               /**< Light location */
+       Color color;    /**< Light color */
+} Light;
 
-typedef struct{
-       vec2 loc;
-       Color color;
-}Light;
 /**
  * The line structure.
  * This structure is used to store the world's ground, stored in vertical
@@ -156,13 +168,13 @@ public:
         * These pointers keep track of worlds that are adjacent to this one. Used in
         * ui.cpp for world jumping.
         */
-
-       World **toLeft,
-                 **toRight,
-                 *behind,
-                 *infront;
        
-       /*
+       char *toLeft,*toRight;
+       
+       char *setToLeft(const char *file);
+       char *setToRight(const char *file);
+       
+       /**
         * These vectors contain the NPCs, Mobs, Structures and Objects that are
         * loaded inside the world, with the Entity vector containing pointers to
         * the contents of all the others.
@@ -176,8 +188,8 @@ public:
        std::vector<Particles   *>      particles;
        std::vector<Light        >  light;
        
-       void addStructure(BUILD_SUB sub,float x,float y,World **inside);//,World **outside);
-       void addVillage(int bCount, int npcMin, int npcMax,World **inside);
+       void addStructure(BUILD_SUB sub,float x,float y,const char *inside);
+       void addVillage(int bCount, int npcMin, int npcMax,const char *inside);
        void addMob(int t,float x,float y);
        void addMob(int t,float x,float y,void (*hey)(Mob *));
        void addNPC(float x,float y);
@@ -221,12 +233,6 @@ public:
        void setBGM(const char *path);
        void bgmPlay(World *prev);
        
-       /*
-        *      Looks for the furthest back layer in this world and adds a new layer of width `width` behind it.
-       */
-       
-       void addLayer(unsigned int width);
-       
        /*
         *      Draw the world and entities based on the player's coordinates. Virtual for the same
         *      reason generate() is.
@@ -234,7 +240,6 @@ public:
                                                                                                                
        virtual void draw(Player *p);
        
-       
        /*
         *      Detect the player and any entities in the current world.
        */
@@ -248,12 +253,7 @@ public:
        */
        
        World *goWorldLeft(Player *p);
-       World *goWorldRight(Player *p);                                 
-       World *goWorldBack(Player *p);
-       World *goWorldFront(Player *p);
-
-       bool isWorldLeft(void);
-       bool isWorldRight(void);
+       World *goWorldRight(Player *p);
        
        /*
         *      Called to enter/exit a structure.
@@ -272,9 +272,6 @@ public:
        */
        
        int getTheWidth(void);
-       
-       void save(std::ofstream *);
-       void load(std::ifstream *);
 };
 
 /*
@@ -289,7 +286,6 @@ float worldGetYBase(World *w);
  
 class IndoorWorld : public World {
 public:
-       World **outside;
        IndoorWorld(void);
        ~IndoorWorld(void);
        
@@ -308,5 +304,8 @@ public:
 };
 
 extern int worldShade;
+extern char *currentXML;
+
+World *loadWorldFromXML(const char *path);
 
 #endif // WORLD_H
index 84515c3626058394b263f21d0ced0f5bd8bbf0f6..2d3531373dcf1ca15e015158c09dc2c588c581b2 100644 (file)
@@ -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;
+}*/
index 01b379b4a59d5ec390c2c162658d01dd0ff18723..ec335c7cde3073f007415104ae38f29018abeabf 100644 (file)
@@ -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;
-}
index 6626811585f25eb6098233766217f8a0c540352c..486c16ea4cbe0acffdd53e4caf1a853de4ea053a 100644 (file)
@@ -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);
 }
index 46702204ffb2578e284d2a4dc1d6e59dc8e92e04..eecd7ef57237572f588149d419e97f1fe1397d9c 100644 (file)
@@ -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);
index 6ee725535a3ff748ad714421f7f021c7ab2316d5..76da308ece30347fc7a00a5d226020e6e35d59ff 100644 (file)
@@ -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;
+}
index a9245e755ee26c5cd86a8daacb8e178e79622270..1580bd28d2459838f8e830d7812ff00ff6db8a6b 100644 (file)
@@ -1,9 +1,7 @@
 <?xml version="1.0"?>
 <IndoorWorld>
        <style background="1" bgm="assets/music/theme_jazz.wav" />
-       <generation type="Random" width="400" />
-
-       <link outside="playerSpawnHill1.xml" />
+       <generation type="Random" width="300" />
 
 </IndoorWorld>