diff options
-rw-r--r-- | Changelog | 27 | ||||
-rw-r--r-- | assets/sounds/cricket.wav | bin | 8695476 -> 0 bytes | |||
-rw-r--r-- | include/common.hpp | 10 | ||||
-rw-r--r-- | include/entities.hpp | 2 | ||||
-rw-r--r-- | include/world.hpp | 13 | ||||
-rw-r--r-- | main.cpp | 55 | ||||
-rw-r--r-- | src/common.cpp | 18 | ||||
-rw-r--r-- | src/entities.cpp | 12 | ||||
-rw-r--r-- | src/gameplay.cpp | 18 | ||||
-rw-r--r-- | src/inventory.cpp | 133 | ||||
-rw-r--r-- | src/texture.cpp | 6 | ||||
-rw-r--r-- | src/ui.cpp | 62 | ||||
-rw-r--r-- | src/world.cpp | 370 | ||||
-rw-r--r-- | xml/playerSpawnHill1.xml | 5 | ||||
-rw-r--r-- | xml/playerSpawnHill1_Building1.xml | 9 |
15 files changed, 426 insertions, 314 deletions
@@ -843,3 +843,30 @@ - prevented structures from moving - began making indoor worlds good - inventory slots are actually being used + +3/30/2016: +========== + + - implemented multiple floors in indoor worlds, xml'd + - made headers .hpp + - fixed player-following light + - began retexturing indoor worlds + - rediscovered important-text music fades + +3/31/2016: +========== + + - npcs and mobs can spawn on specific floors + - npcs can go to locations after dialog + - aborts/exits are better labeled + - began implementing food items + - more better item stuff + +4/4/2016: +========= + + - improved world handling + - player can now begin game inside + - removed unnecessary cout's + - began actual storyline work? + - began actual fighting work diff --git a/assets/sounds/cricket.wav b/assets/sounds/cricket.wav Binary files differdeleted file mode 100644 index 70be7e5..0000000 --- a/assets/sounds/cricket.wav +++ /dev/null diff --git a/include/common.hpp b/include/common.hpp index 2abd9db..c9837dd 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -180,7 +180,13 @@ extern float VOLUME_SFX; */ #define DEBUG_printf( message, ...) DEBUG_prints(__FILE__, __LINE__, message, __VA_ARGS__ ) -void C(std::string m); + +#ifdef SEGFAULT +#define C(x) std::cout << m << std::endl +#else +#define C(x) +#endif + /** * Defines pi for calculations that need it. */ @@ -241,7 +247,7 @@ void safeSetColorA(int r,int g,int b,int a); unsigned int millis(void); #endif // __WIN32__ -int getdir(const char *dir, std::vector<std::string> &files); +int getdir(std::string dir, std::vector<std::string> &files); void strVectorSortAlpha(std::vector<std::string> *v); const char *readFile(const char *path); diff --git a/include/entities.hpp b/include/entities.hpp index e7864d0..7c1a254 100644 --- a/include/entities.hpp +++ b/include/entities.hpp @@ -177,6 +177,8 @@ public: Texturec *tex; Texturec *ntex; + float targetx; + unsigned int randDialog; void draw(void); diff --git a/include/world.hpp b/include/world.hpp index d086687..40e4a38 100644 --- a/include/world.hpp +++ b/include/world.hpp @@ -17,12 +17,16 @@ #define GROUND_HILLINESS 10 +#define PLAYER_SPEED_CONSTANT 0.15f + /** * Defines how many game ticks it takes for a day to elapse. */ #define DAY_CYCLE 12000 +#define Indoorp(x) ((IndoorWorld *)x) + /** * The background type enum. * This enum contains all different possibilities for world backgrounds; used @@ -485,6 +489,7 @@ class IndoorWorld : public World { private: std::vector<std::vector<float>> floor; + std::vector<float> fstart; void singleDetect( Entity *e ); @@ -493,6 +498,11 @@ public: ~IndoorWorld(void); void addFloor( unsigned int width ); + void addFloor( unsigned int width, unsigned int start ); + bool moveToFloor( Entity *e, unsigned int _floor ); + + bool isFloorAbove( Entity *e ); + bool isFloorBelow( Entity *e ); void draw(Player *p); // Draws the world (ignores layers) }; @@ -537,6 +547,9 @@ public: World *exitArena( Player *p ); }; +bool isCurrentWorldIndoors( void ); +float getIndoorWorldFloorHeight( void ); + std::string getWorldWeatherStr( WorldWeather ww ); /** @@ -439,7 +439,7 @@ int main(int argc, char *argv[]){ Mix_CloseAudio(); destroyInventory(); - ui::destroyFonts(); + ui::destroyFonts(); Texture::freeTextures(); SDL_GL_DeleteContext(mainGLContext); @@ -480,7 +480,8 @@ void mainLoop(void){ deltaTime = currentTime - prevTime; prevTime = currentTime; - if(currentMenu)goto MENU; + if ( currentMenu ) + goto MENU; /* * Run the logic handler if MSEC_PER_TICK milliseconds have passed. @@ -520,14 +521,14 @@ void mainLoop(void){ if ( deltaTime ) fps = 1000 / deltaTime; - if(!(debugDiv % 10)) + if ( !(debugDiv % 10) ) debugY = player->loc.y; } MENU: render(); } -void render(){ +void render() { /* * This offset variable is what we use to move the camera and locked @@ -752,21 +753,31 @@ void render(){ static bool objectInteracting = false; void logic(){ - - /* - * NPCSelected is used to insure that only one NPC is made interactable with the mouse - * if, for example, multiple entities are occupying one space. - */ - static bool NPCSelected = false; - /* - * Run the world's detect function. This handles the physics of the player and any entities - * that exist in this world. - */ - + // exit the game if the player falls out of the world + if ( player->loc.y < 0 ) + gameRunning = false; + + for ( auto &e : currentWorld->entity ) { + if ( player->inv->usingi ) { + e->hit = false; + + std::cout << "bang" << std::endl; + + if ( player->inv->usingi && !e->hit && + player->inv->detectCollision( { e->loc.x, e->loc.y }, { e->loc.x + e->width, e->loc.y + e->height} ) ) { + e->health -= 25; + e->hit = true; + //for(int r = 0; r < (rand()%5);r++) + // currentWorld->addParticle(rand()%HLINE*3 + n->loc.x - .05f,n->loc.y + n->height*.5, HLINE,HLINE, -(rand()%10)*.01,((rand()%4)*.001-.002), {(rand()%75+10)/100.0f,0,0}, 10000); + //if ( e->health <= 0 ) { + //for(int r = 0; r < (rand()%30)+15;r++) + // currentWorld->addParticle(rand()%HLINE*3 + n->loc.x - .05f,n->loc.y + n->height*.5, HLINE,HLINE, -(rand()%10)*.01,((rand()%10)*.01-.05), {(rand()%75)+10/100.0f,0,0}, 10000); + } + } + } - if(player->loc.y<.02)gameRunning=false; /* * Entity logic: This loop finds every entity that is alive and in the current world. It then @@ -786,18 +797,6 @@ void logic(){ if(n->canMove) n->wander((rand() % 120 + 30)); - if(!player->inv->usingi) n->hit = false; - - if(player->inv->usingi && !n->hit && player->inv->detectCollision({n->loc.x, n->loc.y},{n->loc.x+n->width,n->loc.y+n->height})){ - n->health -= 25; - n->hit = true; - for(int r = 0; r < (rand()%5);r++) - currentWorld->addParticle(rand()%HLINE*3 + n->loc.x - .05f,n->loc.y + n->height*.5, HLINE,HLINE, -(rand()%10)*.01,((rand()%4)*.001-.002), {(rand()%75+10)/100.0f,0,0}, 10000); - if(n->health <= 0){ - for(int r = 0; r < (rand()%30)+15;r++) - currentWorld->addParticle(rand()%HLINE*3 + n->loc.x - .05f,n->loc.y + n->height*.5, HLINE,HLINE, -(rand()%10)*.01,((rand()%10)*.01-.05), {(rand()%75)+10/100.0f,0,0}, 10000); - } - } /* * Don't bother handling the NPC if another has already been handled. */ diff --git a/src/common.cpp b/src/common.cpp index 50678f1..b4258f6 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -20,14 +20,6 @@ unsigned int millis(void){ #endif // __WIN32__ -void C(std::string m){ - #ifdef SEGFAULT - std::cout << m << std::endl; - #else - (void)m; - #endif -} - void DEBUG_prints(const char* file, int line, const char *s,...){ va_list args; printf("%s:%d: ",file,line); @@ -58,10 +50,10 @@ void safeSetColorA(int r,int g,int b,int a){ glColor4ub(r,g,b,a); } -int getdir(const char *dir, std::vector<std::string> &files){ +int getdir(std::string dir, std::vector<std::string> &files){ DIR *dp; struct dirent *dirp; - if(!(dp = opendir(dir))){ + if(!(dp = opendir(dir.c_str()))){ std::cout <<"Error ("<<errno<<") opening "<<dir<<std::endl; return errno; } @@ -89,10 +81,8 @@ const char *readFile(const char *path){ unsigned int size; GLchar *buf; - if(!in.is_open()){ - std::cout<<"Error reading file "<<path<<"!"<<std::endl; - abort(); - } + if ( !in.is_open() ) + UserError("Error reading file " + (std::string)path + "!"); in.seekg(0,in.end); buf = new GLchar[(size = in.tellg()) + 1]; diff --git a/src/entities.cpp b/src/entities.cpp index f4e2dd7..bea2117 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -75,6 +75,7 @@ void Entity::spawn(float x, float y){ //spawns the entity you pass to it based o loc.y = y; vel.x = 0; vel.y = 0; + targetx = 0.9112001f; alive = true; right = true; @@ -407,6 +408,13 @@ wander( int timeRun ) direction = 0; vel.x = .018 * HLINE * direction; + } else if ( targetx != 0.9112001f ) { + if ( loc.x > targetx + HLINE * 5) + vel.x = -0.018 * HLINE; + else if ( loc.x < targetx - HLINE * 5) + vel.x = 0.018 * HLINE; + else + targetx = 0.9112001f; } else if ( ticksToUse == 0 ) { ticksToUse = timeRun; @@ -489,21 +497,17 @@ void Merchant::interact(){ ui::merchantBox(name, trade[currTrade], ":Accept:Good-Bye", false, "Welcome to Smithy\'s. Buy your sausages here you freaking meme lording screw-face"); ui::waitForDialog(); if(ui::dialogOptChosen == 1){ - std::cout << "Gimme ye' munny" << std::endl; if(!(player->inv->takeItem(trade[currTrade].item[1],trade[currTrade].quantity[1]))) player->inv->addItem(trade[currTrade].item[0],trade[currTrade].quantity[0]); }else if(ui::dialogOptChosen == 2){ - std::cout << "See ye!" << std::endl; }else if(ui::merchOptChosen == 1){ if(currTrade != 0){ currTrade--; - std::cout << "Last trade" << std::endl; interact(); } }else if(ui::merchOptChosen == 2){ if(currTrade < trade.size()){ currTrade++; - std::cout << "Next trade" << std::endl; interact(); } } diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 4aa751f..351cf0f 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -111,6 +111,13 @@ CONT: } /* + * Handle 'go to' thingy + */ + + if ( (oxml = exml->FirstChildElement("gotox")) ) + speaker->targetx = atoi(oxml->GetText()); + + /* * Handle dialog options. */ @@ -273,21 +280,14 @@ void initEverything(void){ * Read the XML directory into an array. */ - C("Scanning XML directory"); - if(getdir(std::string("./"+xmlFolder).c_str(),xmlFiles)){ - std::cout<<"Error reading XML files!!!1"<<std::endl; - abort(); - } - C("Done scanning XML directory"); + if ( getdir( std::string("./" + xmlFolder).c_str(), xmlFiles ) ) + UserError("Error reading XML files!!!"); /* * Sort the files alphabetically. */ - C("Sorting XML files alphabetically"); strVectorSortAlpha(&xmlFiles); - C("Dpne sorting XML files alphabetically"); - /* * Load the first file found as currentWorld. diff --git a/src/inventory.cpp b/src/inventory.cpp index 474a941..14ccfd06 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -182,17 +182,16 @@ void Inventory::setSelection(unsigned int s){ } void Inventory::setSelectionUp(){ - if(!sel--)sel++; + if ( !sel-- ) + sel++; } void Inventory::setSelectionDown(){ - sel++; - if(sel>=numSlot)sel=numSlot-1; + if ( ++sel >= numSlot ) + sel = numSlot - 1; } void Inventory::draw(void){ - C("Inventory Start Draw"); - static unsigned int lop = 0; static std::vector<int>dfp(numSlot); static std::vector<Ray>iray(numSlot); static std::vector<vec2>curCoord(numSlot); @@ -213,91 +212,82 @@ void Inventory::draw(void){ float angleB = (float)180/(float)numSlot; float angle = float(angleB/2.0f); unsigned int a = 0; - static bool end = false; static vec2 mouseStart = {0,0}; C("End define"); - for(auto &r : iray){ - r.start.x = player->loc.x + (player->width/2); - r.start.y = player->loc.y + (player->height/2); + for ( auto &r : iray ) { + r.start.x = player->loc.x + (player->width / 2); + r.start.y = player->loc.y + (player->height / 2); curCoord[a++] = r.start; - }a=0; + } a = 0; - for(auto &cr : curRay){ - cr.start.x = (offset.x + SCREEN_WIDTH/2); - cr.start.y = offset.y - (a*itemWide*1.5); + for ( auto &cr : curRay ) { + cr.start.x = (offset.x + SCREEN_WIDTH / 2); + cr.start.y = offset.y - (a * itemWide * 1.5f); curCurCoord[a++] = cr.start; - }a=0; - - for(int r = 0; r < 4; r++){ - for(int c = 0; c < 8; c++){ - //std::cout << a << ","; - massRay[a].x = ((offset.x - SCREEN_WIDTH/2) + itemWide) + c*itemWide*1.5; - massRay[a++].y = ((offset.y + SCREEN_HEIGHT/2) - itemWide*1.5) - r*itemWide*1.5; - //std::cout << massRay[a-1].x << "," << massRay[a-1].y << " " << std::endl; + } a = 0; + + for ( int r = 0; r < 4; r++ ) { + for ( int c = 0; c < 8; c++ ) { + massRay[a ].x = ((offset.x - SCREEN_WIDTH / 2) + itemWide ) + c * itemWide * 1.5f; + massRay[a++].y = ((offset.y + SCREEN_HEIGHT / 2) - itemWide * 1.5f) - r * itemWide * 1.5f; } - //std::cout << std::endl; - }a=0; - //std::cout << std::endl; + } a = 0; - ui::fontTransInv = 255*(averagef(dfp)/range); - if(ui::fontTransInv > 255) + ui::fontTransInv = 255 * (averagef(dfp) / range); + if ( ui::fontTransInv > 255 ) ui::fontTransInv = 255; - if(ui::fontTransInv < 0) + else if ( ui::fontTransInv < 0 ) ui::fontTransInv = 0; - if(invOpening){ - for(auto &d : dfp){ - if(!a || dfp[a - 1] > 50) - d += 1.65 * deltaTime; - if(d >= range) + if ( invOpening ) { + for ( auto &d : dfp ) { + if ( !a || dfp[a - 1] > 50 ) + d += 1.65f * deltaTime; + if ( d > range ) d = range; a++; - }a=0; - for(auto &cd : curdfp){ - if(!a || curdfp[a-1] > 90) - cd += 1.5 * deltaTime; - if(cd >= curRange) + } a = 0; + + for ( auto &cd : curdfp ) { + if ( !a || curdfp[a - 1] > 90 ) + cd += 1.5f * deltaTime; + if ( cd > curRange ) cd = curRange; a++; - }a=0; - for(uint i = 0; i < massOrder.size();i++){ - if(!a || massDfp[massOrder[a-1]] > massRange*.75) - massDfp[massOrder[a]] += 5.00 * deltaTime; - if(massDfp[massOrder[a]] >= massRange) - massDfp[massOrder[a]] = massRange; - a++; - }a=0; - - if(numSlot > 0)invOpen=true; - }else{ - for(auto &d : dfp){ - if(d > 0){ - d -= 1.65 * deltaTime; - } + } a = 0; + + for ( unsigned int i = 0; i < massOrder.size() ; i++, a++ ) { + if ( !a || massDfp[ massOrder[a - 1] ] > massRange * 0.75f ) + massDfp[ massOrder[a] ] += 5.0f * deltaTime; + if ( massDfp[ massOrder[a] ] > massRange ) + massDfp[ massOrder[a] ] = massRange; + } a = 0; + + if ( numSlot > 0 ) + invOpen = true; + } else { + for ( auto &d : dfp ) { + if ( d > 0 ) + d -= 1.65f * deltaTime; } - for(auto &cd : curdfp){ - if(cd > 0){ - cd -= 1.0 * deltaTime; - } + for ( auto &cd : curdfp ) { + if ( cd > 0 ) + cd -= 1.0f * deltaTime; } - for(uint i = 0; i < massRay.size();i++){ - if(!a || massDfp[massOrderClosing[a-1]] <= 0) - massDfp[massOrderClosing[a]] -= 10.0f * deltaTime; - if(massDfp[massOrderClosing[a-1]] <= 0){ - massDfp[massOrderClosing[a-1]] = 0; - } - a++; - }a=0; - end = std::all_of(std::begin(massDfp),std::end(massDfp),[](auto d){return d <= 0;}); + for ( unsigned int i = 0; i < massRay.size(); i++, a++ ) { + if ( !a || massDfp[ massOrderClosing[a - 1] ] <= 0 ) + massDfp[ massOrderClosing[a] ] -= 10.0f * deltaTime; + if ( massDfp[ massOrderClosing[a - 1] ] < 0 ) + massDfp[ massOrderClosing[a - 1] ] = 0; + } a = 0; - if(end){ + if ( std::all_of( std::begin(massDfp), std::end(massDfp), [](auto d){ return d <= 0; } ) ) { invOpen = false; - for(auto &md : massDfp){ - if(md < 0){ + for ( auto &md : massDfp ) { + if ( md < 0 ) md = 0; - } } } @@ -529,7 +519,6 @@ void Inventory::draw(void){ if(!items.empty() && items.size() > sel && items[sel].count) itemDraw(player,items[sel].id); - lop++; } void itemDraw(Player *p,uint id){ @@ -552,10 +541,8 @@ void itemDraw(Player *p,uint id){ } } }else hangle = 0.0f; - if(p->inv->usingi){ + if ( p->inv->usingi ) p->inv->useItem(); - std::cout << "using" << std::endl; - } glUseProgram(shaderProgram); glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0); diff --git a/src/texture.cpp b/src/texture.cpp index a361f19..1f8dca3 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -143,7 +143,6 @@ namespace Texture{ vec2 getIndex(Color c){ for(auto &i : ind){ if(c.red == i.color.red && c.green == i.color.green && c.blue == i.color.blue){ - //std::cout << float(i.indexy) << "," << float(i.indexx) << std::endl; return {float(i.indexx), float(i.indexy)}; } } @@ -152,22 +151,17 @@ namespace Texture{ float shit = 999; for(uint y = 0; y < 8; y++){ for(uint x = 0; x < 4; x++){ - //std::cout << y << "," << x << ":" << pixels[y][x].red << "," << pixels[y][x].green << "," << pixels[y][x].blue << std::endl; buff = sqrt(pow((pixels[y][x].red- c.red), 2)+ pow((pixels[y][x].green-c.green),2)+ pow((pixels[y][x].blue- c.blue), 2)); - //std::cout << buff << std::endl; if(buff < shit){ shit = buff; buf[0] = y; buf[1] = x; } - // - //std::cout << shit << std::endl; } } ind.push_back({c, (int)buf[1], (int)buf[0]}); - //std::cout << float(buf[1]) << ", " << float(buf[0]) << std::endl; return {float(buf[1]),float(buf[0])}; } } @@ -214,10 +214,8 @@ namespace ui { */ void initFonts(void){ - if(FT_Init_FreeType(&ftl)){ - std::cout<<"Error! Couldn't initialize freetype."<<std::endl; - abort(); - } + if ( FT_Init_FreeType(&ftl) ) + UserError("Couldn't initialize freetype."); #ifdef DEBUG DEBUG_printf("Initialized FreeType2.\n",NULL); @@ -244,10 +242,9 @@ namespace ui { */ void setFontFace(const char *ttf){ - if(FT_New_Face(ftl,ttf,0,&ftf)){ - std::cout<<"Error! Couldn't open "<<ttf<<"."<<std::endl; - abort(); - } + if ( FT_New_Face( ftl, ttf, 0, &ftf ) ) + UserError("Error! Couldn't open " + (std::string)ttf + "."); + #ifdef DEBUG DEBUG_printf("Using font %s\n",ttf); #endif // DEBUG @@ -527,8 +524,6 @@ namespace ui { va_list dialogArgs; std::unique_ptr<char[]> printfbuf (new char[512]); - std::cout << "Buying and selling on the bi-weekly!" << std::endl; - dialogPassive = passive; std::cout << "Market Trading: " << trade.quantity[0] << " " << trade.item[0] << " for " << trade.quantity[1] << " " << trade.item[1] << std::endl; @@ -602,9 +597,6 @@ namespace ui { va_list textArgs; char *printfbuf; - //if(!player->ground)return; - - //memset(dialogBoxText,0,512); dialogBoxText.clear(); printfbuf = new char[ 512 ]; @@ -616,16 +608,12 @@ namespace ui { dialogBoxExists = true; dialogImportant = true; - //toggleBlack(); } - void passiveImportantText(int duration, const char *text,...){ + void passiveImportantText(int duration, const char *text, ...){ va_list textArgs; char *printfbuf; - //if(!player->ground)return; - - //memset(dialogBoxText,0,512); dialogBoxText.clear(); printfbuf = new char[ 512 ]; @@ -683,12 +671,9 @@ namespace ui { setFontSize(16); } }else if(dialogMerchant){ - //static int dispItem; - x=offset.x-SCREEN_WIDTH/6; y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8; - glColor3ub(255,255,255); glBegin(GL_LINE_STRIP); glVertex2f(x-1 ,y+1); @@ -965,7 +950,7 @@ namespace ui { while(SDL_PollEvent(&e)){ switch(e.type){ case SDL_QUIT: - gameRunning=false; + gameRunning = false; return; break; case SDL_MOUSEMOTION: @@ -1285,7 +1270,7 @@ EXIT: // escape - quit game case SDL_QUIT: - gameRunning=false; + gameRunning = false; break; // mouse movement - update mouse vector @@ -1363,11 +1348,9 @@ EXIT: break; case SDLK_a: if(fadeEnable)break; - player->vel.x=-.15; - player->left = true; - player->right = false; - left = true; - right = false; + player->vel.x = -PLAYER_SPEED_CONSTANT; + player->left = left = true; + player->right = right = false; if ( !currentWorld->toLeft.empty() ) { oldpos = player->loc; if((tmp = currentWorld->goWorldLeft(player)) != currentWorld){ @@ -1385,11 +1368,9 @@ EXIT: break; case SDLK_d: if(fadeEnable)break; - player->vel.x=.15; - player->right = true; - player->left = false; - left = false; - right = true; + player->vel.x = PLAYER_SPEED_CONSTANT; + player->right = right = true; + player->left = left = false; if ( !currentWorld->toRight.empty() ) { oldpos = player->loc; if((tmp = currentWorld->goWorldRight(player)) != currentWorld){ @@ -1461,8 +1442,7 @@ EXIT: */ case SDL_KEYUP: - if(SDL_KEY == SDLK_ESCAPE){ - //gameRunning = false; + if ( SDL_KEY == SDLK_ESCAPE ) { currentMenu = &pauseMenu; player->save(); return; @@ -1471,6 +1451,18 @@ EXIT: case SDLK_z: weather = WorldWeather::Snowy; break; + case SDLK_i: + if ( isCurrentWorldIndoors() && Indoorp(currentWorld)->isFloorAbove( player ) ) { + player->loc.y += getIndoorWorldFloorHeight(); + player->ground = false; + } + break; + case SDLK_k: + if ( isCurrentWorldIndoors() && Indoorp(currentWorld)->isFloorBelow( player ) ) { + player->loc.y -= getIndoorWorldFloorHeight(); + player->ground = false; + } + break; case SDLK_a: left = false; break; diff --git a/src/world.cpp b/src/world.cpp index 442abb0..73d8841 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -312,10 +312,8 @@ update( Player *p, unsigned int delta ) p->loc.y += p->vel.y * delta; p->loc.x +=(p->vel.x * p->speed) * delta; - if ( p->loc.y > 5000 ) { - std::cout << "Too high for me m8." << std::endl; - abort(); - } + if ( p->loc.y > 5000 ) + UserError("Too high for me m8."); // update entity coords for ( auto &e : entity ) { @@ -353,9 +351,9 @@ update( Player *p, unsigned int delta ) } // handle music fades - if ( ui::dialogImportant ) - Mix_FadeOutMusic(2000); - else if( !Mix_PlayingMusic() ) + if ( ui::dialogImportant ) { + //Mix_FadeOutMusic(2000); + } else if( !Mix_PlayingMusic() ) Mix_FadeInMusic(bgmObj,-1,2000); } @@ -545,9 +543,6 @@ void World::draw(Player *p){ l.fireFlicker = .9+((rand()%2)/10.0f); l.fireLoc.x = l.loc.x + (rand()%2-1)*3; l.fireLoc.y = l.loc.y + (rand()%2-1)*3; - - //std::cout << l.fireLoc.x << "," << l.fireLoc.y << std::endl; - //std::cout << l.loc.x << "," << l.loc.y << std::endl << std::endl; }else{ l.fireFlicker = 1.0f; } @@ -775,8 +770,8 @@ singleDetect( Entity *e ) return; } } - std::cout<<"RIP "<<e->name<<"."<<std::endl; - exit(0); + std::cout << "RIP " << e->name << "." << std::endl; + exit( 0 ); } // handle only living entities @@ -784,39 +779,32 @@ singleDetect( Entity *e ) if ( e->type == MOBT && Mobp(e)->subtype == MS_TRIGGER ) return; - /* - * Calculate the line that this entity is currently standing on. - */ - - l=(e->loc.x + e->width / 2 - worldStart) / HLINE; + // calculate the line that this entity is currently standing on + l = (e->loc.x + e->width / 2 - worldStart) / HLINE; if ( l < 0 ) l = 0; i = l; if ( i > lineCount - 1 ) i = lineCount - 1; - /* - * If the entity is under the world/line, pop it back to the surface. - */ - + // if the entity is under the world/line, pop it back to the surface if ( e->loc.y < worldData[i].groundHeight ) { - int dir = e->vel.x > 0 ? -1 : 1; - if ( worldData[i].groundHeight - 30 > worldData[i + dir].groundHeight ) { - e->loc.x += HLINE * 8 * dir; - e->loc.y = worldData[i + 8 * dir].groundHeight; + int dir = e->vel.x < 0 ? -1 : 1; + if ( worldData[i + (dir * 8)].groundHeight - 30 > worldData[i + dir].groundHeight ) { + e->loc.x -= ( PLAYER_SPEED_CONSTANT + 2.7 ) * e->speed * 2 * dir; + e->vel.x = 0; } else { e->loc.y = worldData[i].groundHeight - .001 * deltaTime; e->ground = true; e->vel.y = 0; } - /* - * Handle gravity if the entity is above the line. - */ + } - } else { + // handle gravity if the entity is above the line + else { - if(e->type == STRUCTURET && e->loc.y > 2000){ + if ( e->type == STRUCTURET ) { e->loc.y = worldData[i].groundHeight; e->vel.y = 0; e->ground = true; @@ -998,11 +986,11 @@ addParticle( float x, float y, float w, float h, float vx, float vy, Color color particles.back().gravity = gravity; } - -void World::addLight(vec2 loc, Color color){ - if(light.size() < 64){ - light.push_back(Light(loc,color,1)); - } +void World:: +addLight( vec2 loc, Color color ) +{ + if ( light.size() < 64 ) + light.push_back( Light( loc, color, 1 ) ); } std::string World:: @@ -1017,7 +1005,6 @@ setToRight( std::string file ) return (toRight = file); } -//what is this clyne why are they differnet World *World:: goWorldLeft( Player *p ) { @@ -1085,8 +1072,8 @@ goInsideStructure( Player *p ) if ( p->loc.x > b->loc.x && p->loc.x + p->width < b->loc.x + b->width ) { - if ( b->inside.empty() ) - return this; + if ( b->inside.empty() ) + return this; inside.push_back(currentXML.c_str() + xmlFolder.size()); @@ -1096,11 +1083,13 @@ goInsideStructure( Player *p ) ui::waitForCover(); ui::toggleBlackFast(); + glClearColor(0,0,0,1); + return tmp; } } } else { - current = currentXML.c_str() + xmlFolder.size(); + current = currentXML.c_str() + xmlFolder.size(); tmp = loadWorldFromXML( inside.back() ); for ( auto &b : tmp->build ) { if ( current == b->inside ) { @@ -1113,6 +1102,8 @@ goInsideStructure( Player *p ) ui::toggleBlackFast(); + glClearColor(1,1,1,1); + return tmp; } } @@ -1133,12 +1124,12 @@ addHill( const ivec2 peak, const unsigned int width ) { int start = peak.x - width / 2, end = start + width, offset; const float thing = peak.y - worldData[start].groundHeight; - const float period = PI / width; + const float period = PI / width; if ( start < 0 ) { - offset = -start; - start = 0; - } + offset = -start; + start = 0; + } if ( end > (signed)worldData.size() ) end = worldData.size(); @@ -1182,20 +1173,15 @@ void World::save(void){ } data.append("dOnE\0"); - std::cout << "Writing to the file" << std::endl; out.write(data.c_str(),data.size()); - out.close(); - std::cout << "Done saving" << std::endl; } void World::load(void){ std::string save,data,line; const char *filedata; - //std::cout << "Loading from: " << std::string(currentXML + ".dat") << std::endl; save = std::string(currentXML + ".dat"); - //std::cout << "save file: " << save << std::endl; filedata = readFile(save.c_str()); data = filedata; std::istringstream iss (data); @@ -1244,6 +1230,15 @@ void World::load(void){ delete[] filedata; } +float getIndoorWorldFloorHeight( void ) +{ + return INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS; +} + +bool isCurrentWorldIndoors( void ) { + return !inside.empty(); +} + IndoorWorld::IndoorWorld(void){ } @@ -1259,35 +1254,88 @@ addFloor( unsigned int width ) if ( floor.empty() ) generate( width ); floor.emplace_back( width, floor.size() * INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS ); + fstart.push_back( 0 ); +} + + +void IndoorWorld:: +addFloor( unsigned int width, unsigned int start ) +{ + if ( floor.empty() ) + generate( width ); + floor.emplace_back( width, floor.size() * INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS ); + fstart.push_back( start ); +} + +bool IndoorWorld:: +moveToFloor( Entity *e, unsigned int _floor ) +{ + if ( _floor > floor.size() ) + return false; + + e->loc.y = floor[_floor - 1][0]; + return true; +} + +bool IndoorWorld:: +isFloorAbove( Entity *e ) +{ + for ( unsigned int i = 0; i < floor.size(); i++ ) { + if ( floor[i][0] + INDOOR_FLOOR_HEIGHTT - 100 > e->loc.y ) + return (i + 1) != floor.size(); + } + return false; +} + +bool IndoorWorld:: +isFloorBelow( Entity *e ) +{ + for ( unsigned int i = 0; i < floor.size(); i++ ) { + if ( floor[i][0] + INDOOR_FLOOR_HEIGHTT - 100 > e->loc.y ) + return i > 0; + } + return false; } void IndoorWorld:: singleDetect( Entity *e ) { + unsigned int floornum = 0; + float start, end; + if ( !e->alive ) return; if ( e->type == MOBT && Mobp(e)->subtype == MS_TRIGGER ) return; - for ( auto &f : floor ) { - if ( f[0] + INDOOR_FLOOR_HEIGHTT < e->loc.y ) { - C("floor"); - if ( e->loc.y < f[0] ) { - e->loc.y = f[0]; + for ( ; floornum < floor.size(); floornum++ ) { + if ( floor[floornum][0] + INDOOR_FLOOR_HEIGHTT - 100 > e->loc.y ) { + if ( e->loc.y < floor[floornum][0] ) { + e->loc.y = floor[floornum][0]; e->vel.y = 0; e->ground = true; - } else if ( e->vel.y > -2 ) - e->vel.y -= GRAVITY_CONSTANT * deltaTime; + } break; } } - if(e->loc.x < worldStart){ // Left bound - e->vel.x=0; - e->loc.x=(float)worldStart + HLINE / 2; - }else if(e->loc.x + e->width + HLINE > worldStart + worldStart * -2){ // Right bound - e->vel.x=0; - e->loc.x=worldStart + worldStart * -2 - e->width - HLINE; + if ( e->vel.y > -2 ) + e->vel.y -= GRAVITY_CONSTANT * deltaTime; + + if ( e->ground ) { + e->loc.y = ceil( e->loc.y ); + e->vel.y = 0; + } + + start = worldStart + fstart[floornum] * HLINE; + end = start + floor[floornum].size() * HLINE; + + if ( e->loc.x < start ) { + e->vel.x = 0; + e->loc.x = start + HLINE / 2; + } else if ( e->loc.x + e->width + HLINE > end ) { + e->vel.x = 0; + e->loc.x = end - e->width - HLINE; } } @@ -1295,14 +1343,14 @@ singleDetect( Entity *e ) void IndoorWorld:: draw( Player *p ) { - unsigned int i; + unsigned int i,f; int x; // draw lights for ( auto &l : light ) { if ( l.belongsTo ) { l.loc.x = l.following->loc.x + SCREEN_WIDTH / 2; - l.loc.y = l.following->loc.y; + l.loc.y = ( l.following->loc.y > SCREEN_HEIGHT / 2 ) ? SCREEN_HEIGHT / 2 : l.following->loc.y; } if ( l.flame ) { l.fireFlicker = .9 + ( (rand() % 2) / 10.0f ); @@ -1367,14 +1415,15 @@ draw( Player *p ) glUniform1i( glGetUniformLocation(shaderProgram, "sampler"), 0 ); glBegin( GL_QUADS ); safeSetColor( 150, 100, 50 ); - for ( auto &f : floor ) { + for ( f = 0; f < floor.size(); f++ ) { i = 0; - for ( h : f ) { - x = worldStart + i++ * HLINE; + for ( h : floor[f] ) { + x = worldStart + fstart[f] * HLINE + (i * HLINE); glVertex2i( x , h ); glVertex2i( x + HLINE, h ); glVertex2i( x + HLINE, h - INDOOR_FLOOR_THICKNESS ); glVertex2i( x , h - INDOOR_FLOOR_THICKNESS ); + i++; } } glEnd(); @@ -1457,12 +1506,8 @@ static bool loadedLeft = false; static bool loadedRight = false; World *loadWorldFromXML(std::string path){ - C("Scanning for save file"); - std::cout << "Scanning: " << path << std::endl; if ( !currentXML.empty() ) currentWorld->save(); - std::cout << "After Scanning: " << path << std::endl; - C("Done scanning for save file"); return loadWorldFromXMLNoSave(path); } @@ -1479,8 +1524,6 @@ World *loadWorldFromPtr( World *ptr ) currentWorldToRight = loadWorldFromXML( tmp->toRight ); loadedRight = false; - std::cout<<tmp->npc.back()->name<<std::endl; - return tmp; } @@ -1497,99 +1540,160 @@ loadWorldFromXMLNoSave( std::string path ) { World *tmp; float spawnx, randx; bool dialog,Indoor; + unsigned int flooor; const char *ptr; - std::string name; + std::string name, sptr; + // no file? -> no world if ( path.empty() ) return NULL; - std::cout << "File path: " << path << std::endl; - currentXML = std::string("storyXML/" + path); - std::cout << "Full file path: " << currentXML << std::endl; - - xml.LoadFile(currentXML.c_str()); - wxml = xml.FirstChildElement("World"); + currentXML = std::string(xmlFolder + path); + xml.LoadFile( currentXML.c_str() ); - if(wxml){ + // attempt to load a <World> tag + if ( (wxml = xml.FirstChildElement("World")) ) { wxml = wxml->FirstChildElement(); vil = xml.FirstChildElement("World")->FirstChildElement("village"); - Indoor = false; tmp = new World(); - }else if((wxml = xml.FirstChildElement("IndoorWorld"))){ + Indoor = false; + } + + // attempt to load an <IndoorWorld> tag + else if( (wxml = xml.FirstChildElement("IndoorWorld")) ) { wxml = wxml->FirstChildElement(); vil = NULL; - Indoor = true; tmp = new IndoorWorld(); + Indoor = true; } - while(wxml){ + // error: can't load a world... + else + UserError("XML Error: Cannot find a <World> or <IndoorWorld> tag in " + currentXML + "!"); + + // iterate through world tags + while ( wxml ) { name = wxml->Name(); + // world linkage if ( name == "link" ) { - if ((ptr = wxml->Attribute("left"))) { - tmp->setToLeft(ptr); + + // links world to the left + if ( (ptr = wxml->Attribute("left")) ) { + tmp->setToLeft( ptr ); + + // load the left world if it isn't if ( !loadedLeft ) { loadedLeft = true; currentWorldToLeft = loadWorldFromXMLNoSave( ptr ); loadedLeft = false; } - } else if ((ptr = wxml->Attribute("right"))) { - tmp->setToRight(ptr); + } + + // links world to the right + else if ( (ptr = wxml->Attribute("right")) ) { + tmp->setToRight( ptr ); + + // load the right world if it isn't if ( !loadedRight ) { loadedRight = true; currentWorldToRight = loadWorldFromXMLNoSave( ptr ); loadedRight = false; } - } else - abort(); - } else if ( name == "style" ) { - tmp->setStyle(wxml->StrAttribute("folder")); - tmp->setBackground((WorldBGType)wxml->UnsignedAttribute("background")); - tmp->setBGM(wxml->StrAttribute("bgm")); - } else if ( name == "generation" ) { - if ( !Indoor && !strcmp(wxml->Attribute("type"),"Random") ) - tmp->generate(wxml->UnsignedAttribute("width")); - else if ( Indoor ) - abort(); - } else if ( name == "mob" ) { - unsigned int type; - type = wxml->UnsignedAttribute("type"); - if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) - tmp->addMob(type,0,100); + } + + // error, invalid link tag + else + UserError("XML Error: Invalid <link> tag in " + currentXML + "!"); + + } + + // style tags + else if ( name == "style" ) { + // set style folder + tmp->setStyle( wxml->StrAttribute("folder") ); + + // set background folder + if ( wxml->QueryUnsignedAttribute("background", &flooor) != XML_NO_ERROR ) + UserError("XML Error: No background given in <style> in " + currentXML + "!"); + tmp->setBackground( (WorldBGType)flooor ); + + // set BGM file + tmp->setBGM( wxml->StrAttribute("bgm") ); + } + + // world generation (for outdoor areas) + else if ( name == "generation" ) { + // random gen. + if ( !Indoor && wxml->StrAttribute("type") == "Random" ) + tmp->generate( wxml->UnsignedAttribute("width") ); + else { + if ( Indoor ) + UserError("XML Error: <generation> tags can't be in <IndoorWorld> tags (in " + currentXML + ")!"); + else + UserError("XML Error: Invalid <generation> tag in " + currentXML + "!"); + } + } + + // mob creation + else if ( name == "mob" ) { + // type info + if ( wxml->QueryUnsignedAttribute("type", &flooor) != XML_NO_ERROR ) + UserError("XML Error: Invalid type value in <mob> in " + currentXML + "!"); + + // spawn at coordinate if desired + if ( wxml->QueryFloatAttribute( "x", &spawnx ) == XML_NO_ERROR ) + tmp->addMob( flooor, spawnx, wxml->FloatAttribute("y")); else - tmp->addMob(type,spawnx,wxml->FloatAttribute("y")); - if(wxml->QueryBoolAttribute("aggressive",&dialog) == XML_NO_ERROR) + tmp->addMob( flooor, 0, 100 ); + + // aggressive tag + if ( wxml->QueryBoolAttribute( "aggressive", &dialog ) == XML_NO_ERROR ) tmp->mob.back()->aggressive = dialog; - } else if ( name == "npc" ) { + // indoor spawning floor selection + if ( Indoor && wxml->QueryUnsignedAttribute( "floor", &flooor ) == XML_NO_ERROR ) + Indoorp(tmp)->moveToFloor( tmp->npc.back(), flooor ); + } + + // npc creation + else if ( name == "npc" ) { const char *npcname; - if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) - tmp->addNPC(0,100); + // spawn at coordinates if desired + if ( wxml->QueryFloatAttribute( "x", &spawnx ) == XML_NO_ERROR) + tmp->addNPC( spawnx, wxml->FloatAttribute("y") ); else - tmp->addNPC(spawnx,wxml->FloatAttribute("y")); + tmp->addNPC( 0, 100 ); - - if((npcname = wxml->Attribute("name"))){ - delete[] tmp->npc.back()->name; + // name override + 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); + strcpy( tmp->npc.back()->name, npcname ); } + // dialog enabling dialog = false; - if(wxml->QueryBoolAttribute("hasDialog",&dialog) == XML_NO_ERROR && dialog) - tmp->npc.back()->addAIFunc(commonAIFunc,false); - else tmp->npc.back()->dialogIndex = 9999; - - } else if ( name == "structure" ) { - tmp->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"), - wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR ? - getRand() % tmp->getTheWidth() / 2.0f : - spawnx, + if ( wxml->QueryBoolAttribute( "hasDialog", &dialog ) == XML_NO_ERROR && dialog ) + tmp->npc.back()->addAIFunc( commonAIFunc, false ); + else + tmp->npc.back()->dialogIndex = 9999; + + if ( Indoor && wxml->QueryUnsignedAttribute( "floor", &flooor ) == XML_NO_ERROR ) + Indoorp(tmp)->moveToFloor( tmp->npc.back(), flooor ); + } + + // structure creation + else if ( name == "structure" ) { + tmp->addStructure( (BUILD_SUB) wxml->UnsignedAttribute("type"), + wxml->QueryFloatAttribute( "x", &spawnx ) != XML_NO_ERROR ? + getRand() % tmp->getTheWidth() / 2.0f : spawnx, 100, wxml->StrAttribute("texture"), - wxml->StrAttribute("inside")); + wxml->StrAttribute("inside") + ); } else if ( name == "trigger" ) { tmp->addMob(MS_TRIGGER,wxml->FloatAttribute("x"),0,commonTriggerFunc); tmp->mob.back()->heyid = wxml->Attribute("id"); @@ -1601,7 +1705,10 @@ loadWorldFromXMLNoSave( std::string path ) { } else if ( name == "time" ) { tickCount = std::stoi( wxml->GetText() ); } else if ( Indoor && name == "floor" ) { - ((IndoorWorld *)tmp)->addFloor( wxml->UnsignedAttribute("width") ); + if ( wxml->QueryFloatAttribute("start",&spawnx) == XML_NO_ERROR ) + Indoorp(tmp)->addFloor( wxml->UnsignedAttribute("width"), spawnx ); + else + Indoorp(tmp)->addFloor( wxml->UnsignedAttribute("width") ); } wxml = wxml->NextSiblingElement(); @@ -1633,7 +1740,6 @@ loadWorldFromXMLNoSave( std::string path ) { vil->StrAttribute("inside")); }else if ( name == "stall" ) { if(!strcmp(vil->Attribute("type"),"market")){ - std::cout << "Market" << std::endl; tmp->addStructure((BUILD_SUB)70, vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx, @@ -1643,22 +1749,17 @@ loadWorldFromXMLNoSave( std::string path ) { tmp->addMerchant(0,100); tmp->merchant.back()->inside = tmp->build.back(); if(vil->FirstChildElement("buy")){ - std::cout << "Buy" << std::endl; - }if(vil->FirstChildElement("sell")){ - std::cout << "Sell" << std::endl; - }if(vil->FirstChildElement("trade")){ - std::cout << "Trade" << std::endl; + }else if(vil->FirstChildElement("sell")){ + }else if(vil->FirstChildElement("trade")){ tmp->merchant.back()->trade.push_back(Trade(vil->FirstChildElement("trade")->IntAttribute("quantity"), vil->FirstChildElement("trade")->Attribute("item"), vil->FirstChildElement("trade")->IntAttribute("quantity1"), vil->FirstChildElement("trade")->Attribute("item1"))); tmp->merchant.back()->trade.push_back(Trade(1,"Wood Sword", 420, "Dank MayMay")); } - std::cout << "new trade" << std::endl; strcpy(tmp->merchant.back()->name,"meme"); }else if(!strcmp(vil->Attribute("type"),"trader")){ - std::cout << "Trader" << std::endl; tmp->addStructure((BUILD_SUB)71, vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx, @@ -1688,10 +1789,7 @@ loadWorldFromXMLNoSave( std::string path ) { tmp->load(); } - std::cout << "adadadadasdsa" << std::endl; - return tmp; - } Village::Village(const char *meme, World *w){ diff --git a/xml/playerSpawnHill1.xml b/xml/playerSpawnHill1.xml index 4930f68..936731e 100644 --- a/xml/playerSpawnHill1.xml +++ b/xml/playerSpawnHill1.xml @@ -17,7 +17,7 @@ <page x="-200" id="assets/pages/gootaGoFast.png" /> - <village name="Scrub Lawd"> + <village name="Swaggggggggggggg"> <structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/> <structure type="5" x="-500" /> <stall type="market" texture="assets/style/classic/stall.png"> @@ -37,8 +37,9 @@ And it wasn't stormy. <Dialog name="Ralph"> - <text id="0" nextid="1" > + <text id="0" nextid="1"> Hello there! My name is Ralph. + <gotox>300</gotox> </text> <text id="1" nextid="2" call="Johnny" callid="0" pause="true" > diff --git a/xml/playerSpawnHill1_Building1.xml b/xml/playerSpawnHill1_Building1.xml index 8478908..bbf882f 100644 --- a/xml/playerSpawnHill1_Building1.xml +++ b/xml/playerSpawnHill1_Building1.xml @@ -2,11 +2,10 @@ <IndoorWorld> <style background="1" bgm="assets/music/theme_jazz.wav" /> - <floor width="300"> - <npc name="Bob" hasDialog="true" /> - </floor> + <floor width="300" /> + <floor width="200" start="100" /> - <floor width="200" /> + <npc name="Bob" hasDialog="true" floor="2" /> </IndoorWorld> @@ -55,7 +54,7 @@ <give id="Wood Sword22" count="1"/> <give id="Wood Sword23" count="1"/> <give id="Wood Sword24" count="1"/> - <give id="Wood Sword25" count="1"/> + <give id="Wood Sword25" count="6"/> <give id="Wood Sword26" count="1"/> <give id="Wood Sword27" count="1"/> <give id="Wood Sword28" count="1"/> |