diff options
-rw-r--r-- | Changelog | 38 | ||||
-rw-r--r-- | Goals.txt | 4 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | assets/items/ITEM_PAGE.png | bin | 0 -> 349 bytes | |||
-rw-r--r-- | include/common.h | 17 | ||||
-rw-r--r-- | include/entities.h | 39 | ||||
-rw-r--r-- | include/inventory.h | 17 | ||||
-rw-r--r-- | include/ui.h | 2 | ||||
-rw-r--r-- | include/world.h | 16 | ||||
-rw-r--r-- | main.cpp | 16 | ||||
-rw-r--r-- | src/common.cpp | 17 | ||||
-rw-r--r-- | src/entities.cpp | 136 | ||||
-rw-r--r-- | src/gameplay.cpp | 94 | ||||
-rw-r--r-- | src/ui.cpp | 37 | ||||
-rw-r--r-- | src/world.cpp | 86 | ||||
-rw-r--r-- | xcf/page.xcf | bin | 0 -> 1059 bytes |
16 files changed, 435 insertions, 87 deletions
@@ -444,3 +444,41 @@ - fixed NPC spawning world location stuff - messed with threads/forks - re-fixed/added indoor environment; fixed indoor background + +12/18/2015: +=========== + + - upgraded development utilities + - began working on pages, made sprite and handler + - GLSL shaders are better + - redid theme_jazz + +12/21/2015: +=========== + + - fixed dialog options issues, finished basic pages + - added World::getAvailableNPC() for easy quest assigner assigning + - added the Condition class, so that events and actions can be remembered by NPCs + - added functionality for multiple lights (GLSL) + +12/22/2015: +=========== + + - 3 month Changelog anniversary! + - fixed dialog quitting bug + - worked on village spawning + - worked on wrapping text for dialog boxes + - did more work on GLSL shaders + +1/3/2015: +========= + + - finished wrapping text for dialog boxes + - began working on world saving/loading again + - got some mad GLSL shaders running + +1/4/2015: +========= + + - fixed basic world save/load, working on entity saving + - GLSL shaders worked? @@ -35,7 +35,7 @@ End of December: - create first 'chapters' of story - create very first areas in the game (code it) to get an idea of what's gonna go down - + January - March: =============== @@ -45,7 +45,7 @@ January - March: February - End of March: ======================== - - design sound effects / background music? + - design or focus on sound effects / background music? March-ish: ====== @@ -5,6 +5,7 @@ WIN_LIBS = -lopengl32 -lglew32 -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_m FLAGS = -std=c++11 -Iinclude -Iinclude/freetype2 -Wall -Wextra -Werror
MFLAGS64 = 64
+
all:
@echo "Building for 32-bit target"
@rm -f out/*.o
@@ -21,7 +22,7 @@ all: win32:
@g++ $(FLAGS) -o main main.cpp src/*.cpp $(WIN_LIBS)
-
+
clean:
@echo " RM main"
@-rm -f main
diff --git a/assets/items/ITEM_PAGE.png b/assets/items/ITEM_PAGE.png Binary files differnew file mode 100644 index 0000000..4602afe --- /dev/null +++ b/assets/items/ITEM_PAGE.png diff --git a/include/common.h b/include/common.h index 207b95f..0c4d700 100644 --- a/include/common.h +++ b/include/common.h @@ -151,6 +151,23 @@ extern unsigned int loops; extern GLuint shaderProgram; /** + * This class contains a string for identification and a value. It can be used to + * save certain events for and decisions so that they can be recalled later. + */ + +class Condition { +private: + char *id; + void *value; +public: + Condition(const char *_id,void *val); + ~Condition(); + + bool sameID(const char *s); + void *getValue(void); +}; + +/** * Prints a formatted debug message to the console, along with the callee's file and line * number. */ diff --git a/include/entities.h b/include/entities.h index a4bc282..90af0f2 100644 --- a/include/entities.h +++ b/include/entities.h @@ -32,7 +32,8 @@ enum MOB_SUB { MS_RABBIT = 1, MS_BIRD, MS_TRIGGER, - MS_DOOR + MS_DOOR, + MS_PAGE }; enum BUILD_SUB{ @@ -44,6 +45,31 @@ enum BUILD_SUB{ FOUNTAIN }; +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; + //Texturec *tex; +} __attribute__ ((packed)) EntitySavePacket; + class World; class Particles{ @@ -139,6 +165,9 @@ public: virtual void interact(){} virtual ~Entity(){} + + char *baseSave(void); + void baseLoad(char *); }; class Player : public Entity{ @@ -150,6 +179,11 @@ public: ~Player(); void interact(); }; + +typedef struct { + EntitySavePacket esp; +} __attribute__ ((packed)) NPCSavePacket; + class NPC : public Entity{ public: std::vector<int (*)(NPC *)>aiFunc; @@ -160,6 +194,9 @@ public: void addAIFunc(int (*func)(NPC *),bool preload); void interact(); void wander(int); + + char *save(unsigned int *size); + void load(char *b); }; class Structures : public Entity{ diff --git a/include/inventory.h b/include/inventory.h index 31b7d88..b035f91 100644 --- a/include/inventory.h +++ b/include/inventory.h @@ -60,6 +60,11 @@ struct item_t{ ITEM_ID id; } __attribute__((packed)); +typedef struct { + unsigned int size; + int os; + unsigned int sel; +} __attribute__ ((packed)) InventorySavePacket; class Inventory { private: @@ -87,6 +92,18 @@ public: void draw(void); // Draws a text list of items in this inventory (should only be called for the player for now) + char *save(void){ + static InventorySavePacket *isp = new InventorySavePacket(); + isp->size = size; + isp->os = os; + isp->sel = sel; + return (char *)isp; + } + void load(InventorySavePacket *isp){ + size = isp->size; + os = isp->os; + sel = isp->sel; + } }; void itemUse(void *p); diff --git a/include/ui.h b/include/ui.h index 6a81dab..b769bbf 100644 --- a/include/ui.h +++ b/include/ui.h @@ -33,6 +33,8 @@ namespace ui { extern unsigned char dialogOptChosen; extern bool dialogImportant; + extern unsigned int textWrapLimit; + /* * Initializes the FreeType system. */ diff --git a/include/world.h b/include/world.h index e10d0dc..5021fbb 100644 --- a/include/world.h +++ b/include/world.h @@ -8,6 +8,9 @@ #ifndef WORLD_H #define WORLD_H +#include <ostream> +#include <istream> + #include <common.h> #include <entities.h> @@ -133,6 +136,7 @@ protected: */ Texturec *bgTex; + WORLD_BG_TYPE bgType; /** * The Mix_Music object that holds the background soundtrack for the world. @@ -173,13 +177,19 @@ public: std::vector<Light > light; void addStructure(_TYPE t,BUILD_SUB sub,float x,float y,World *inside); - void addVillage(int bCount, int npcMin, int npcMax,_TYPE t,float x,float y,World *outside); + void addVillage(int bCount, int npcMin, int npcMax,_TYPE t,World *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); void addObject(ITEM_ID, bool, const char *, float, float); void addParticle(float, float, float, float, float, float, Color color, int); void addLight(vec2, Color); + + NPC *getAvailableNPC(void); + + /* + * Update coordinates of all entities. + */ void update(Player *p,unsigned int delta); @@ -263,8 +273,8 @@ public: int getTheWidth(void); - void save(FILE *); - void load(FILE *); + void save(std::ofstream *); + void load(std::ifstream *); }; /* @@ -3,7 +3,8 @@ The main game loop contains all of the global variables the game uses, and it runs the main game loop, the render loop, and the logic loop that control all of the entities. */ -#include <cstdio> // fopen +#include <fstream> +#include <istream> #include <thread> #include <common.h> @@ -123,7 +124,7 @@ Mix_Chunk *crickets; * referenced in src/entities.cpp for getting random names. */ -FILE *names; +std::istream *names; /* * loops is used for texture animation. It is believed to be passed to entity @@ -201,7 +202,7 @@ extern int fadeIntensity; int main(/*int argc, char *argv[]*/){ //*argv = (char *)argc; gameRunning=false; - + /*! * (Attempt to) Initialize SDL libraries so that we can use SDL facilities and eventually * make openGL calls. Exit if there was an error. @@ -386,7 +387,10 @@ int main(/*int argc, char *argv[]*/){ * */ - names = fopen("assets/names_en-us", "r+"); + static std::filebuf fb; + fb.open("assets/names_en-us",std::ios::in); + names = new std::istream(&fb); + crickets=Mix_LoadWAV("assets/sounds/crickets.wav"); //Mix_Volume(2,25); @@ -426,7 +430,7 @@ int main(/*int argc, char *argv[]*/){ Mix_HaltMusic(); - fclose(names); + fb.close(); SDL_GL_DeleteContext(mainGLContext); SDL_DestroyWindow(window); @@ -475,6 +479,7 @@ void mainLoop(void){ if(prev != currentWorld){ currentWorld->bgmPlay(prev); + ui::dialogBoxExists = false; } if(prevPrevTime + MSEC_PER_TICK <= currentTime){ @@ -894,6 +899,7 @@ void logic(){ m->wander((rand()%240 + 15)); // Make the mob wander :) break; case MS_TRIGGER: + case MS_PAGE: m->wander(0); break; case MS_DOOR: diff --git a/src/common.cpp b/src/common.cpp index 7449a35..dbcef0b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1,4 +1,5 @@ #include <common.h> +#include <cstring> #include <cstdio> #include <chrono> @@ -11,6 +12,22 @@ unsigned int millis(void){ #endif // __WIN32__ +Condition::Condition(const char *_id,void *val){ + id = new char[strlen(_id)+1]; + strcpy(id,_id); + value = val; +} +Condition::~Condition(){ + delete[] id; +} + +bool Condition::sameID(const char *s){ + return !strcmp(id,s); +} +void *Condition::getValue(void){ + return value; +} + void DEBUG_prints(const char* file, int line, const char *s,...){ va_list args; printf("%s:%d: ",file,line); diff --git a/src/entities.cpp b/src/entities.cpp index d12a1ca..7e8d55a 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,9 +1,10 @@ #include <entities.h> #include <ui.h> -#include <unistd.h> +#include <istream> +//#include <unistd.h> -extern FILE* names; +extern std::istream *names; extern unsigned int loops; extern World *currentWorld; @@ -12,39 +13,30 @@ extern Player *player; extern const char *itemName; -extern - void getRandomName(Entity *e){ - int tempNum,max=0; + unsigned int tempNum,max=0; char *bufs; - rewind(names); + names->seekg(0,names->beg); - bufs = new char[16]; //(char *)malloc(16); + bufs = new char[32]; - for(;!feof(names);max++){ - fgets(bufs,16,(FILE*)names); - } + for(;!names->eof();max++) + names->getline(bufs,32); tempNum = rand() % max; - rewind(names); + names->seekg(0,names->beg); - for(int i=0;i<tempNum;i++){ - fgets(bufs,16,(FILE*)names); - } + for(unsigned int i=0;i<tempNum;i++) + names->getline(bufs,32); - switch(fgetc(names)){ + switch(bufs[0]){ + default : case 'm': e->gender = MALE; break; case 'f': e->gender = FEMALE;break; - default : break; } - if((fgets(bufs,16,(FILE*)names)) != NULL){ - bufs[strlen(bufs)] = '\0'; - strcpy(e->name,bufs); - if(e->name[strlen(e->name)-1] == '\n') - e->name[strlen(e->name)-1] = '\0'; - } + strcpy(e->name,bufs+1); delete[] bufs; } @@ -73,7 +65,7 @@ void Entity::spawn(float x, float y){ //spawns the entity you pass to it based o } } - name = new char[16]; + name = new char[32]; getRandomName(this); } @@ -109,7 +101,7 @@ NPC::NPC(){ //sets all of the NPC specific traits on object creation tex = new Texturec(1,"assets/NPC.png"); inv = new Inventory(NPC_INV_SIZE); - randDialog = rand() % 12 - 1; + randDialog = 6;//rand() % 12 - 1; } NPC::~NPC(){ while(!aiFunc.empty()){ @@ -154,15 +146,22 @@ Mob::Mob(int sub){ width = HLINE * 8; height = HLINE * 8; tex = new Texturec(1, "assets/robin.png"); + break; case MS_TRIGGER: width = HLINE * 20; height = 2000; tex = new Texturec(0); + break; case MS_DOOR: width = HLINE * 12; height = HLINE * 20; tex = new Texturec(1,"assets/door.png"); break; + case MS_PAGE: + width = HLINE * 6; + height = HLINE * 4; + tex = new Texturec(1,"assets/items/ITEM_PAGE.png"); + break; } inv = new Inventory(NPC_INV_SIZE); @@ -256,6 +255,7 @@ void Entity::draw(void){ //draws the entities break; case MS_BIRD: case MS_DOOR: + case MS_PAGE: default: glActiveTexture(GL_TEXTURE0 + 0); tex->bind(0); @@ -363,7 +363,7 @@ const char *randomDialog[] = { "How much wood could a woodchuck chuck if a woodchuck could chuck wood?", "I don\'t think anyone has ever been able to climb up that hill.", "If you ever see a hole in the ground, watch out; it could mean the end for you.", - "Did you know this game has over 4000 lines of code? I didn\'t. I didn't even know I was in a game until now...", + "Did you know this game has over 5000 lines of code? I didn\'t. I didn't even know I was in a game until now...", "HELP MY CAPS LOCK IS STUCK", "You know, if anyone ever asked me who I wanted to be when I grow up, I would say Abby Ross.", "I want to have the wallpaper in our house changed. It doesn\'t really fit the environment.", @@ -493,8 +493,92 @@ void Mob::wander(int timeRun){ } break; - case MS_DOOR: + case MS_PAGE: + if(player->loc.x > loc.x - 100 && + player->loc.x < loc.x + 100 && + ui::mouse.x > loc.x && + ui::mouse.x < loc.x + width && + ui::mouse.y > loc.y - width / 2 && + ui::mouse.y < loc.y + width * 1.5 && + SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)){ + if(speed != 666){ + speed = 666; + hey(this); + speed = 0; + } + } + break; default: break; } } + +char *Entity::baseSave(void){ + static EntitySavePacket *esp = new EntitySavePacket(); + memcpy(&esp->isp,inv->save(),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; + esp->nameSize = strlen(name) + 1; + return (char *)esp; +} + +void Entity::baseLoad(char *e){ + const char *tmpname = "GG\0"; + EntitySavePacket *esp = (EntitySavePacket *)e; + 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; + name = new char[esp->nameSize+1]; + strcpy(name,tmpname); +} + +char *NPC::save(unsigned int *size){ + static char *buf = new char[(*size = sizeof(EntitySavePacket) + aiFunc.size() * sizeof(int(*)(NPC *)))],*esp; + memcpy(buf,(esp = baseSave()),sizeof(EntitySavePacket)); + delete[] esp; + memcpy(buf+sizeof(EntitySavePacket),aiFunc.data(),aiFunc.size() * sizeof(int(*)(NPC *))); + return buf; +} + +void NPC::load(char *b){ + unsigned int size = *(unsigned int *)b,size2,i; + baseLoad(b + sizeof(unsigned int)); + size2 = (size - sizeof(unsigned int) - sizeof(EntitySavePacket)) / sizeof(int(*)(NPC *)); + for(i=0;i<size2;i++){ + //aiFunc.push_back + } +} diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 1c83bd8..431d2cf 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -28,6 +28,10 @@ void story(Mob *callee){ callee->alive = false; } +/* + * Gens + */ + float gen_worldSpawnHill1(float x){ return (float)(pow(2,(-x+200)/5) + GEN_MIN); } @@ -42,7 +46,6 @@ float gen_worldSpawnHill3(float x){ */ void worldSpawnHill1_hillBlock(Mob *callee){ - std::cout<<"oi"; player->vel.x = 0; player->loc.x = callee->loc.x + callee->width; ui::dialogBox(player->name,NULL,false,"This hill seems to steep to climb up..."); @@ -51,30 +54,46 @@ void worldSpawnHill1_hillBlock(Mob *callee){ static Arena *a; void worldSpawnHill2_infoSprint(Mob *callee){ - callee->alive = false; - a = new Arena(currentWorld,player); - a->setBackground(BG_FOREST); - a->setBGM("assets/music/embark.wav"); - ui::toggleWhiteFast(); - ui::waitForCover(); - currentWorld = a; - ui::toggleWhiteFast(); + + ui::dialogBox(player->name,":Sure:Nah",false,"This page would like to take you somewhere."); + ui::waitForDialog(); + switch(ui::dialogOptChosen){ + case 1: + ui::dialogBox(player->name,NULL,true,"Cool."); + callee->alive = false; + a = new Arena(currentWorld,player); + a->setBackground(BG_FOREST); + a->setBGM("assets/music/embark.wav"); + ui::toggleWhiteFast(); + ui::waitForCover(); + currentWorld = a; + ui::toggleWhiteFast(); + break; + case 2: + default: + ui::dialogBox(player->name,NULL,false,"Okay then."); + break; + } + //ui::dialogBox("B-) ",NULL,true,"Press \'Shift\' to run!"); } -void worldSpawnHill3_itemGet(Mob *callee){ - ui::dialogBox("B-) ",NULL,true,"Right click to pick up items!"); - callee->alive = false; -} - -void worldSpawnHill3_itemSee(Mob *callee){ - ui::dialogBox("B-) ",NULL,true,"Press \'e\' to open your inventory!"); - callee->alive = false; +int worldSpawnHill2_Quest2(NPC *callee){ + ui::dialogBox(callee->name,NULL,false,"Yo."); + ui::waitForDialog(); + return 0; } -void worldSpawnHill3_leave(Mob *callee){ - ui::dialogBox("B-) ",NULL,true,"Now jump in this hole, and let your journey begin :)"); - callee->alive = false; +int worldSpawnHill2_Quest1(NPC *callee){ + ui::dialogBox(callee->name,":Cool.",false,"Did you know that I\'m the coolest NPC in the world?"); + ui::waitForDialog(); + if(ui::dialogOptChosen == 1){ + ui::dialogBox(callee->name,NULL,false,"Yeah, it is."); + currentWorld->getAvailableNPC()->addAIFunc(worldSpawnHill2_Quest2,true); + ui::waitForDialog(); + return 0; + } + return 1; } /* @@ -96,39 +115,48 @@ static World *worldSpawnHill3; static IndoorWorld *worldSpawnHill2_Building1; +static World *worldFirstVillage; /* * initEverything() start */ void destroyEverything(void); void initEverything(void){ - + static std::ifstream i ("world.dat",std::ifstream::in | std::ifstream::binary); + worldSpawnHill1 = new World(); - worldSpawnHill1->generateFunc(400,gen_worldSpawnHill1); worldSpawnHill1->setBackground(BG_FOREST); - worldSpawnHill1->setBGM("assets/music/embark.wav"); + // if(!i.fail()){ + // worldSpawnHill1->load(&i); + // i.close(); + // }else{ + worldSpawnHill1->generateFunc(400,gen_worldSpawnHill1); + worldSpawnHill1->setBGM("assets/music/embark.wav"); + // } worldSpawnHill1->addMob(MS_TRIGGER,0,0,worldSpawnHill1_hillBlock); worldSpawnHill2 = new World(); worldSpawnHill2->generate(700); worldSpawnHill2->setBackground(BG_FOREST); worldSpawnHill2->setBGM("assets/music/ozone.wav"); - worldSpawnHill2->addMob(MS_TRIGGER,-400,0,worldSpawnHill2_infoSprint); + worldSpawnHill2->addMob(MS_PAGE,-400,0,worldSpawnHill2_infoSprint); worldSpawnHill3 = new World(); worldSpawnHill3->generateFunc(1000,gen_worldSpawnHill3); worldSpawnHill3->setBackground(BG_FOREST); worldSpawnHill3->setBGM("assets/music/ozone.wav"); - worldSpawnHill3->addMob(MS_TRIGGER,-500,0,worldSpawnHill3_itemGet); - worldSpawnHill3->addMob(MS_TRIGGER,0,0,worldSpawnHill3_itemSee); - worldSpawnHill3->addObject(FLASHLIGHT,false,"",-200,300); - worldSpawnHill3->addMob(MS_TRIGGER,650,0,worldSpawnHill3_leave); - worldSpawnHill3->addHole(800,1000); + + worldFirstVillage = new World(); + worldFirstVillage->generate(1000); + worldFirstVillage->setBackground(BG_FOREST); + worldFirstVillage->setBGM("assets/music/embark.wav"); worldSpawnHill1->toRight = worldSpawnHill2; worldSpawnHill2->toLeft = worldSpawnHill1; worldSpawnHill2->toRight = worldSpawnHill3; worldSpawnHill3->toLeft = worldSpawnHill2; + worldSpawnHill3->toRight = worldFirstVillage; + worldFirstVillage->toLeft = worldSpawnHill3; /* * Spawn some entities. @@ -150,6 +178,9 @@ void initEverything(void){ worldSpawnHill2->addStructure(STRUCTURET,HOUSE,(rand()%120*HLINE),100,worldSpawnHill2_Building1); worldSpawnHill2->addLight({300,100},{1.0f,1.0f,1.0f}); + worldSpawnHill2->getAvailableNPC()->addAIFunc(worldSpawnHill2_Quest1,false); + + worldFirstVillage->addVillage(5,0,0,STRUCTURET,worldSpawnHill2_Building1); //worldSpawnHill2->addStructure(STRUCTURET,HOUSE,(rand()%120*HLINE),100,worldSpawnHill1,worldSpawnHill2); player = new Player(); @@ -164,6 +195,11 @@ extern std::vector<int (*)(NPC *)> AIpreload; extern std::vector<NPC *> AIpreaddr; void destroyEverything(void){ + static std::ofstream o; + o.open("world.dat",std::ifstream::binary); + worldSpawnHill1->save(&o); + o.close(); + while(!AIpreload.empty()) AIpreload.pop_back(); while(!AIpreaddr.empty()) @@ -95,6 +95,8 @@ namespace ui { bool dialogImportant = false; unsigned char dialogOptChosen = 0; + unsigned int textWrapLimit = 110; + /* * Current font size. Changing this WILL NOT change the font size, see setFontSize() for * actual font size changing. @@ -266,7 +268,13 @@ namespace ui { */ do{ - if(s[i]=='\n'){ // Handle newlines + if(i && ((i / 110.0) == (i / 110))){ + yo-=fontSize*1.05; + xo=x; + if(s[i] == ' ') + i++; + } + if(s[i] == '\n'){ yo-=fontSize*1.05; xo=x; }else if(s[i]==' '){ // Handle spaces @@ -300,19 +308,21 @@ namespace ui { } }while(s[++i]); - return putString(x-width/2,y,s); + putString(x-width/2,y,s); + return width; } /* * Draw a string in a typewriter-esque fashion. Each letter is rendered as calls are made * to this function. Passing a different string to the function will reset the counters. */ - + + static char *ret = NULL; char *typeOut(char *str){ static unsigned int sinc, // Acts as a delayer for the space between each character. linc=0, // Contains the number of letters that should be drawn. size=0; // Contains the full size of the current string. - static char *ret = NULL; + //static char *ret = NULL; /* * Create a well-sized buffer if we haven't yet. @@ -452,6 +462,8 @@ namespace ui { dialogBoxExists = true; dialogImportant = false; + if(ret) + ret[0] = '\0'; } void waitForDialog(void){ do{ @@ -487,7 +499,7 @@ namespace ui { } void draw(void){ unsigned char i; - float x,y; + float x,y,tmp; char *rtext; if(dialogBoxExists){ @@ -524,12 +536,12 @@ namespace ui { for(i=0;i<dialogOptCount;i++){ setFontColor(255,255,255); - dialogOptLoc[i][1]=y-SCREEN_HEIGHT/4+(fontSize+HLINE)*(i+1); - dialogOptLoc[i][2]= - putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]); - dialogOptLoc[i][0]=offset.x-dialogOptLoc[i][2]/2; + tmp = putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]); + dialogOptLoc[i][2] = offset.x + tmp; + dialogOptLoc[i][0] = offset.x - tmp; + dialogOptLoc[i][1] = y - SCREEN_HEIGHT / 4 + (fontSize + HLINE) * (i + 1); if(mouse.x > dialogOptLoc[i][0] && - mouse.x < dialogOptLoc[i][0] + dialogOptLoc[i][2] && + mouse.x < dialogOptLoc[i][2] && mouse.y > dialogOptLoc[i][1] && mouse.y < dialogOptLoc[i][1] + 16 ){ // fontSize setFontColor(255,255,0); @@ -666,7 +678,6 @@ DONE: memcpy(&player->loc,&tmppos,sizeof(vec2)); currentWorld = tmp; toggleBlackFast(); - dialogBoxExists = false; } } break; @@ -688,7 +699,6 @@ DONE: memcpy(&player->loc,&tmppos,sizeof(vec2)); currentWorld = tmp; toggleBlackFast(); - dialogBoxExists = false; } } break; @@ -804,6 +814,9 @@ DONE: case SDLK_RIGHT: player->inv->sel++; break; + case SDLK_f: + + break; default: break; } diff --git a/src/world.cpp b/src/world.cpp index b539a87..c6ab6e1 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -52,6 +52,7 @@ float worldGetYBase(World *w){ } void World::setBackground(WORLD_BG_TYPE bgt){ + bgType = bgt; switch(bgt){ case BG_FOREST: bgTex = new Texturec(7,bgPaths[0]); @@ -62,12 +63,69 @@ void World::setBackground(WORLD_BG_TYPE bgt){ } } -void World::save(FILE *s){ - fclose(s); +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)); + + /*std::vector<NPC *> npc; + std::vector<Structures *> build; + std::vector<Mob *> mob; + std::vector<Entity *> entity; + std::vector<Object *> object;*/ + + size = npc.size(); + for(i=0;i<size;i++){ + bufptr = npc[i]->save(&size2); + o->write((char *)&size2,sizeof(unsigned int)); + o->write(bufptr,size2); + } } -void World::load(FILE *s){ - fclose(s); +void World::load(std::ifstream *i){ + //unsigned int size; + size_t bgms; + char sig[2]; + + 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"<<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"<<std::endl; + exit(EXIT_FAILURE); + } + + } World::World(void){ @@ -942,16 +1000,20 @@ void World::addStructure(_TYPE t,BUILD_SUB sub, float x,float y,World *inside){ entity.push_back(build.back()); } -void World::addVillage(int bCount, int npcMin, int npcMax,_TYPE t,float x,float y,World *outside){ +void World::addVillage(int bCount, int npcMin, int npcMax,_TYPE t,World *inside){ std::cout << npcMin << ", " << npcMax << std::endl; - int xwasd; + //int xwasd; for(int i = 0; i < bCount; i++){ - xwasd = (rand()%(int)x+1000*HLINE); + addStructure(t,HOUSE,x_start + (i * 300),100,inside); + /*std::cout<<"1\n"; HERE: + xwasd = (rand()%(int)x+1000*HLINE); for(auto &bu : build){ if(xwasd > bu->loc.x && xwasd < bu->loc.x+bu->width)goto HERE; } - addStructure(t,HOUSE,xwasd,y,outside); + std::cout<<"2\n"; + addStructure(t,HOUSE,xwasd,y,inside); + std::cout<<"3\n";*/ } } void World::addMob(int t,float x,float y){ @@ -1015,6 +1077,14 @@ void World::addLayer(unsigned int width){ behind->bgTex=bgTex; } +NPC *World::getAvailableNPC(void){ + for(auto &n : npc){ + if(n->aiFunc.empty()) + return n; + } + return (NPC *)NULL; +} + World *World::goWorldLeft(Player *p){ if(toLeft&&p->loc.x<x_start+HLINE*15){ p->loc.x=toLeft->x_start+getWidth(toLeft)-HLINE*10; diff --git a/xcf/page.xcf b/xcf/page.xcf Binary files differnew file mode 100644 index 0000000..72a34cf --- /dev/null +++ b/xcf/page.xcf |