diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2016-03-15 08:43:44 -0400 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2016-03-15 08:43:44 -0400 |
commit | 93d6035dad1eb60fb01648232809e55059dd1cfa (patch) | |
tree | 2384f3991593ce6b4a37e7e289cfdd634aeec380 | |
parent | c8c09860cb732006e161d26f25ff46e508770218 (diff) |
hills
-rw-r--r-- | Changelog | 58 | ||||
-rw-r--r-- | include/world.h | 11 | ||||
-rw-r--r-- | main.cpp | 140 | ||||
-rw-r--r-- | src/entities.cpp | 22 | ||||
-rw-r--r-- | src/inventory.cpp | 10 | ||||
-rw-r--r-- | src/ui.cpp | 2 | ||||
-rw-r--r-- | src/world.cpp | 495 | ||||
-rw-r--r-- | xml/playerSpawnHill1.xml | 29 | ||||
-rw-r--r-- | xml/playerSpawnHill1_Building1.xml | 12 | ||||
-rw-r--r-- | xml/playerSpawnHill2.xml | 4 |
10 files changed, 425 insertions, 358 deletions
@@ -44,7 +44,7 @@ - successfully ran game 200 entities - improved debug screen - added mouse interaction w/ NPCs - + 9/30/2015: ========== @@ -54,10 +54,10 @@ - began work on giving names to NPCs - began working on config file - created a bug file - + - added displaying of entity names on mouse hover - found more fonts - + 10/1/2015: ========== @@ -125,20 +125,20 @@ - fixed delaying quest assignments until dialog is closed - checked and secured errors in malloc/calloc calls - + 10/19/2015: =========== - fixed malloc/strlen bug that crashes the game on some linux systems - broke andy's linux system on his laptop, allowing for test game build on Windows - began extensive documentation in main.cpp - + 10/20/2015: =========== - andy's laptop 'can' boot - added 200+ lines of documentation to main.cpp - + 10/21/2015: =========== @@ -156,14 +156,14 @@ - successfully build game on 32-bit Windows (game crashes on execution) - removed npc array; NPCs are now created in the entity array - created a basic texture handling library - + 10/23/2015: =========== - fixed entity initialization - added multiple mobs - improved texture handling - + 10/26/2015: =========== @@ -231,7 +231,7 @@ - added typewriter-esque text drawing - documented ui.h - continued work on GLSL shaders - + 11/4/2015: ========== @@ -266,7 +266,7 @@ - added drawing/handling of entities on all layers at all times - removed building entering/exiting - andy broke SDL cuz he's bad - + 11/10/2015: =========== @@ -296,7 +296,7 @@ - minor bug fixes - began working on arenas - began working on cutscene triggers - + 11/17/2015: =========== @@ -317,7 +317,7 @@ - texture loaded tracks loaded textures to prevent re-loading (frees resources) - continued work on things finished the following day (11/20) :) - + 11/20/2015: =========== @@ -408,7 +408,7 @@ - imrpoved BGM handling - continued work on particles, made a fountain - added sanic - + ~ Broke 5000 lines of code/doc, now with some file Doxygen'd 12/14/2015: @@ -488,21 +488,21 @@ - can save NPCs and Structures - more shadering - + 1/6/2016: ========= - flashlight! - XML-scripted worlds!!! - !!!!!!!!!!!!!!!!!!!!!!!! - + 1/7/2016: ========= - xml'd npc and mob spawning - xml'd npc dialogs - drafted page xml - + 1/11/2016: ========== @@ -518,7 +518,7 @@ - xml'ing indoors - shaderssss - more music - + 1/13/2016: ========== @@ -533,7 +533,7 @@ - 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/2016: @@ -587,7 +587,7 @@ - wrote paper regarding what we've learned, and where we're at - ported game to Windows, left EXE and DLLs in repo - + 2/1/2016: ========= @@ -632,7 +632,7 @@ - partially fixed text drawing - XML'd quest checking, working on quest requirements - worked on XML'ing villages - + 2/9/2016: ========= @@ -673,7 +673,7 @@ - mob deaths are saved - fixed building spawning - volumes are better - + ~ 5 month Changelog anniversary!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2/23/2016: @@ -741,7 +741,7 @@ - arenas work - cleaned up world codes - andy got here - + ~ Total of 7,379 lines of code! 3/8/2016: @@ -756,3 +756,17 @@ - pages are XMLable and can be drawn - dialogs are cool with threads - better lighting + +3/14/2016: +========== + + - began implementing hills in worlds + - more inventory stuffs + +3/15/2016: +========== + + - finished hills, fixed hill collision physics + - fixed player repositioning when switching worlds + - XML'd tickCount setting + - even more inventory stuffs (side panes) diff --git a/include/world.h b/include/world.h index a60eab6..55c08f5 100644 --- a/include/world.h +++ b/include/world.h @@ -421,8 +421,15 @@ public: void addHole(unsigned int start,unsigned int end); - /* - * Get's the world's width. + /** + * Adds a hill to the world, given the peak's coordinates and how wide the + * hill can be. + */ + + void addHill( ivec2 peak, unsigned int width ); + + /** + * Gets the world's width. */ int getTheWidth(void) const; @@ -104,7 +104,7 @@ GLuint fragShader; /** * TODO */ - + GLuint shaderProgram; /** @@ -202,9 +202,9 @@ void mainLoop(void); int main(int argc, char *argv[]){ (void)argc; (void)argv; - + static SDL_GLContext mainGLContext = NULL; - + gameRunning = false; /** @@ -307,13 +307,13 @@ int main(int argc, char *argv[]){ std::cout << "GLEW was not able to initialize! Error: " << glewGetErrorString(err) << std::endl; return -1; } - + /* * Initialize the random number generator. At the moment, initRand is a macro pointing to libc's * srand, and its partner getRand points to rand. This is because having our own random number * generator may be favorable in the future, but at the moment is not implemented. */ - + initRand(millis()); /* @@ -321,24 +321,24 @@ int main(int argc, char *argv[]){ * setup the alpha channel for textures/transparency, and finally hide the system's mouse * cursor so that we may draw our own. */ - + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); //SDL_GL_SetSwapInterval(0); - + glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - + SDL_ShowCursor(SDL_DISABLE); Texture::initColorIndex(); initEntity(); - + /* * Initializes our shaders so that the game has shadows. */ - + std::cout << "Initializing shaders!" << std::endl; const GLchar *shaderSource = readFile("test.frag"); @@ -353,17 +353,17 @@ int main(int argc, char *argv[]){ glGetShaderiv(fragShader, GL_COMPILE_STATUS, &bufferln); glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength); - + std::vector<char> fragShaderError ((logLength > 1) ? logLength : 1); - + glGetShaderInfoLog(fragShader, logLength, NULL, &fragShaderError[0]); std::cout << &fragShaderError[0] << std::endl; - + if(bufferln == GL_FALSE){ std::cout << "Error compiling shader" << std::endl; } - shaderProgram = glCreateProgram(); + shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, fragShader); glLinkProgram(shaderProgram); glValidateProgram(shaderProgram); @@ -373,18 +373,18 @@ int main(int argc, char *argv[]){ std::vector<char> programError( (logLength > 1) ? logLength : 1 ); glGetProgramInfoLog(shaderProgram, logLength, NULL, &programError[0]); std::cout << &programError[0] << std::endl; - + delete[] shaderSource; - + glEnable(GL_MULTISAMPLE); - + /* * Create all the worlds, entities, mobs, and the player. This function is defined in * src/gameplay.cpp */ - + fadeIntensity = 250; - + initEverything(); if(!currentWorld){ @@ -403,40 +403,40 @@ int main(int argc, char *argv[]){ invUI = Texture::loadTexture("assets/invUI.png" ); mouseTex = Texture::loadTexture("assets/mouse.png"); - + initInventorySprites(); - + /************************** **** GAMELOOP **** **************************/ - + std::cout << "Num threads: " << std::thread::hardware_concurrency() << std::endl; //currentWorld->mob.back()->followee = player; - + gameRunning = true; while(gameRunning){ mainLoop(); } - + /************************** **** CLOSE PROGRAM **** **************************/ - + /* * Close the window and free resources */ - + Mix_HaltMusic(); Mix_CloseAudio(); - + destroyInventory(); ui::destroyFonts(); Texture::freeTextures(); - + SDL_GL_DeleteContext(mainGLContext); SDL_DestroyWindow(window); - + return 0; // Calls everything passed to atexit } @@ -451,20 +451,20 @@ static float debugY=0; void mainLoop(void){ static unsigned int debugDiv=0; // A divisor used to update the debug menu if it's open - + static unsigned int prevTime = 0, // Used for timing operations currentTime = 0, // prevPrevTime= 0; // World *prev; - + if(!currentTime) // Initialize currentTime if it hasn't been currentTime=millis(); - + /* * Update timing values. This is crucial to calling logic and updating the window (basically * the entire game). */ - + prevTime = currentTime; currentTime = millis(); deltaTime = currentTime - prevTime; @@ -477,7 +477,7 @@ void mainLoop(void){ */ prev = currentWorld; - + //pool.Enqueue(ui::handleEvents); ui::handleEvents(); @@ -496,23 +496,23 @@ void mainLoop(void){ /* * Update player and entity coordinates. */ - + /*pool.Enqueue([](){ currentWorld->update(player,deltaTime); });*/ - + currentWorld->update(player,deltaTime); - + /* * Update debug variables if necessary */ - + if ( ++debugDiv == 20 ) { debugDiv=0; - + if ( deltaTime ) fps = 1000 / deltaTime; - else if(!(debugDiv%10)) + if(!(debugDiv%10)) debugY = player->loc.y; } MENU: @@ -520,12 +520,12 @@ MENU: } void render(){ - + /* * This offset variable is what we use to move the camera and locked * objects on the screen so they always appear to be in the same relative area */ - + offset.x = player->loc.x + player->width/2; offset.y = SCREEN_HEIGHT/2; @@ -533,7 +533,7 @@ void render(){ * If the camera will go off of the left or right of the screen we want to lock it so we can't * see past the world render */ - + if(currentWorld->getTheWidth() < (int)SCREEN_WIDTH){ offset.x = 0; }else{ @@ -542,7 +542,7 @@ void render(){ if(player->loc.x + player->width + SCREEN_WIDTH/2 > currentWorld->getTheWidth() * 0.5f) offset.x = ((currentWorld->getTheWidth() * 0.5f) - SCREEN_WIDTH / 2) - player->width / 2; } - + if(player->loc.y > SCREEN_HEIGHT/2) offset.y = player->loc.y + player->height; @@ -558,7 +558,7 @@ void render(){ * * glMatrixMode This changes our current stacks mode so the drawings below * it can take on certain traits. - * + * * GL_PROJECTION This is the matrix mode that sets the cameras position, * GL_PROJECTION is made up of a stack with two matrices which * means we can make up to 2 seperate changes to the camera. @@ -582,7 +582,7 @@ void render(){ * glLoadIdentity This scales the current matrix back to the origin so the * translations are seen normally on a stack. */ - + glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); @@ -591,7 +591,7 @@ void render(){ glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - + /* * glPushAttrib This passes attributes to the renderer so it knows what it can * render. In our case, GL_DEPTH_BUFFER_BIT allows the renderer to @@ -602,14 +602,14 @@ void render(){ * glClear This clears the new matrices using the type passed. In our case: * GL_COLOR_BUFFER_BIT allows the matrices to have color on them */ - + glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT ); glClear(GL_COLOR_BUFFER_BIT); /************************** **** RENDER STUFF HERE **** **************************/ - + /* * Call the world's draw function, drawing the player, the world, the background, and entities. Also * draw the player's inventory if it exists. @@ -622,7 +622,7 @@ void render(){ /* * Calculate the player's hand angle. */ - + handAngle = atan((ui::mouse.y - (player->loc.y + player->height/2)) / (ui::mouse.x - player->loc.x + player->width/2))*180/PI; if(ui::mouse.x < player->loc.x){ if(handAngle <= 0) @@ -631,21 +631,21 @@ void render(){ handAngle+=180; } } - + if(ui::mouse.x > player->loc.x && ui::mouse.y < player->loc.y+player->height/2 && handAngle <= 0) handAngle = 360 + handAngle; - + /* * Draw the player's inventory. */ - + player->inv->draw(); /* * Here we draw a black overlay if it's been requested. */ - + if(fadeIntensity){ if(fadeWhite) safeSetColorA(255,255,255,fadeIntensity); @@ -662,7 +662,7 @@ void render(){ /* * Draw UI elements. This includes the player's health bar and the dialog box. */ - + ui::draw(); /* @@ -670,7 +670,7 @@ void render(){ */ if(ui::debug){ - + ui::putText(offset.x-SCREEN_WIDTH/2, (offset.y+SCREEN_HEIGHT/2)-ui::fontSize, "FPS: %d\nG:%d\nRes: %ux%u\nE: %d\nPOS: (x)%+.2f\n (y)%+.2f\nTc: %u\nHA: %+.2f\nPl: %d\n Vol: %f", @@ -686,7 +686,7 @@ void render(){ player->light, VOLUME_MASTER ); - + if(ui::posFlag){ glBegin(GL_LINES); glColor3ub(255,0,0); @@ -722,7 +722,7 @@ void render(){ glTexCoord2f(0,1);glVertex2i(ui::mouse.x ,ui::mouse.y-HLINE*5 ); glEnd(); glDisable(GL_TEXTURE_2D); - + /************************** **** END RENDERING **** **************************/ @@ -757,7 +757,7 @@ void logic(){ * Run the world's detect function. This handles the physics of the player and any entities * that exist in this world. */ - + currentWorld->detect(player); if(player->loc.y<.02)gameRunning=false; @@ -766,10 +766,10 @@ void logic(){ * basically runs their AI functions depending on what type of entity they are. For NPCs, * click detection is done as well for NPC/player interaction. */ - + for(auto &n : currentWorld->npc){ if(n->alive){ - + /* * Make the NPC 'wander' about the world if they're allowed to do so. * Entity->canMove is modified when a player interacts with an NPC so @@ -778,9 +778,9 @@ 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((vec2){n->loc.x, n->loc.y},(vec2){n->loc.x+n->width,n->loc.y+n->height})){ n->health -= 25; n->hit = true; @@ -791,7 +791,7 @@ void logic(){ 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. */ @@ -848,7 +848,7 @@ void logic(){ }else n->near=false; } } - + for(auto &m : currentWorld->mob){ if(m->alive){ @@ -873,7 +873,7 @@ void logic(){ } } } - + if(!objectInteracting){ for(auto &o : currentWorld->object){ if(o->alive){ @@ -898,11 +898,11 @@ void logic(){ } } } - + /* * Switch between day and night (SUNNY and DARK) if necessary. */ - + if(!(tickCount%DAY_CYCLE)||!tickCount){ if ( weather == WorldWeather::Sunny ) weather = WorldWeather::Dark; @@ -921,7 +921,7 @@ void logic(){ /* * Transition to and from black if necessary. */ - + if(fadeEnable){ if(fadeIntensity < 150)fadeIntensity+=fadeFast?40:10; else if(fadeIntensity < 255)fadeIntensity+=fadeFast?20:5; diff --git a/src/entities.cpp b/src/entities.cpp index 8a10428..7d906ea 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -562,17 +562,19 @@ void Mob::wander(int timeRun){ if(aggressive && !YAYA && player->loc.x + (width / 2) > loc.x && player->loc.x + (width / 2) < loc.x + width && player->loc.y + (height / 3) > loc.y && player->loc.y + (height / 3) < loc.y + height ){ - Arena *a = new Arena(currentWorld,player,this); - a->setStyle(""); - a->setBackground( WorldBGType::Forest ); - a->setBGM("assets/music/embark.wav"); + if ( !ui::dialogBoxExists ) { + Arena *a = new Arena(currentWorld,player,this); + a->setStyle(""); + a->setBackground( WorldBGType::Forest ); + a->setBGM("assets/music/embark.wav"); - ui::toggleWhiteFast(); - YAYA = true; - ui::waitForCover(); - YAYA = false; - currentWorld = a; - ui::toggleWhiteFast(); + ui::toggleWhiteFast(); + YAYA = true; + ui::waitForCover(); + YAYA = false; + currentWorld = a; + ui::toggleWhiteFast(); + } } switch(subtype){ diff --git a/src/inventory.cpp b/src/inventory.cpp index e82d99e..795fb55 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -142,12 +142,12 @@ const char *getItemTexturePath(std::string name){ } GLuint getItemTexture(std::string name){ - for(auto &i : itemMap){ - if(i->name == name) - return Texture::loadTexture(i->texloc); + for ( int i = itemMap.size(); i--; ) { + if ( itemMap[i]->name == name ) + return itemtex[i]; } - - return Texture::loadTexture("assets/items/ITEM_TEST.png"); + DEBUG_printf("Failed to find texture for item %s!", name.c_str() ); + return 0; } float getItemWidth(std::string name){ @@ -706,7 +706,7 @@ namespace ui { glColor3ub(255,255,255); glBegin(GL_LINE_STRIP); - glVertex2f(x-1 ,y+1); + glVertex2f(x-1 ,y+1); glVertex2f(x+1+(SCREEN_WIDTH/3),y+1); glVertex2f(x+1+(SCREEN_WIDTH/3),y-1-SCREEN_HEIGHT*.6); glVertex2f(x-1,y-1-SCREEN_HEIGHT*.6); diff --git a/src/world.cpp b/src/world.cpp index af28ac5..097847f 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -66,10 +66,10 @@ const std::string bgPaths[2][9]={ const std::string buildPaths[] = { "townhall.png", - "house1.png", - "house2.png", - "house1.png", - "house1.png", + "house1.png", + "house2.png", + "house1.png", + "house1.png", "fountain1.png", "lampPost1.png", "brazzier.png" @@ -88,7 +88,7 @@ const float bgDraw[4][3]={ /** * Sets the desired theme for the world's background. - * + * * The images chosen for the background layers are selected depending on the * world's background type. */ @@ -101,7 +101,7 @@ setBackground( WorldBGType bgt ) case WorldBGType::Forest: bgTex = new Texturec( bgFiles ); break; - + case WorldBGType::WoodHouse: bgTex = new Texturec( bgFilesIndoors ); break; @@ -114,7 +114,7 @@ setBackground( WorldBGType bgt ) /** * Sets the world's style. - * + * * The world's style will determine what sprites are used for things like\ * generic structures. */ @@ -123,25 +123,25 @@ void World:: setStyle( std::string pre ) { unsigned int i; - + // get folder prefix std::string prefix = pre.empty() ? "assets/style/classic/" : pre; - + for ( i = 0; i < arrAmt(buildPaths); i++ ) sTexLoc.push_back( prefix + buildPaths[i] ); - + prefix += "bg/"; - + for ( i = 0; i < arrAmt(bgPaths[0]); i++ ) bgFiles.push_back( prefix + bgPaths[0][i] ); - + for ( i = 0; i < arrAmt(bgPaths[1]); i++ ) bgFilesIndoors.push_back( prefix + bgPaths[1][i] ); } /** * Creates a world object. - * + * * Note that all this does is nullify pointers, to prevent as much disaster as * possible. Functions like setBGM(), setStyle() and generate() should be called * before the World is actually put into use. @@ -151,14 +151,14 @@ World:: World( void ) { bgmObj = NULL; - + toLeft = NULL; toRight = NULL; } /** * The entity vector destroyer. - * + * * This function will free all memory used by all entities, and then empty the * vectors they were stored in. */ @@ -177,25 +177,25 @@ deleteEntities( void ) delete npc.back(); npc.pop_back(); } - + // free structures while ( !build.empty() ) { delete build.back(); build.pop_back(); } - + // free objects while ( !object.empty() ) { delete object.back(); object.pop_back(); } - + // clear entity array entity.clear(); - + // free particles particles.clear(); - + // clear light array light.clear(); @@ -208,7 +208,7 @@ deleteEntities( void ) /** * The world destructor. - * + * * This will free objects used by the world itself, then free the vectors of * entity-related objects. */ @@ -219,9 +219,9 @@ World:: // sdl2_mixer's object if(bgmObj) Mix_FreeMusic(bgmObj); - + delete bgTex; - + delete[] toLeft; delete[] toRight; @@ -230,20 +230,20 @@ World:: /** * Generates a world of the specified width. - * + * * This will mainly populate the WorldData array, mostly preparing the World * object for usage. */ void World:: generate( unsigned int width ) -{ +{ // iterator for `for` loops std::vector<WorldData>::iterator wditer; - + // see below for description float geninc = 0; - + // check for valid width if ( (int)width <= 0 ) UserError("Invalid world dimensions"); @@ -251,17 +251,17 @@ generate( unsigned int width ) // allocate space for world worldData = std::vector<WorldData> (width + GROUND_HILLINESS, WorldData { false, {0,0}, 0, 0 }); lineCount = worldData.size(); - + // prepare for generation worldData.front().groundHeight = GROUND_HEIGHT_INITIAL; wditer = worldData.begin(); - + // give every GROUND_HILLINESSth entry a groundHeight value for(unsigned int i = GROUND_HILLINESS; i < worldData.size(); i += GROUND_HILLINESS, wditer += GROUND_HILLINESS) worldData[i].groundHeight = (*wditer).groundHeight + (randGet() % 8 - 4); // create slopes from the points that were just defined, populate the rest of the WorldData structure - + for(wditer = worldData.begin(); wditer != worldData.end(); wditer++){ if ((*wditer).groundHeight) // wditer + GROUND_HILLINESS can go out of bounds (invalid read) @@ -279,15 +279,15 @@ generate( unsigned int width ) (*wditer).groundHeight = GROUND_HEIGHT_MINIMUM; else if ( (*wditer).groundHeight > GROUND_HEIGHT_MAXIMUM ) (*wditer).groundHeight = GROUND_HEIGHT_MAXIMUM; - + if( (*wditer).groundHeight <= 0 ) (*wditer).groundHeight = GROUND_HEIGHT_MINIMUM; } - + // define x-coordinate of world's leftmost 'line' worldStart = (width - GROUND_HILLINESS) * HLINE / 2 * -1; - + // create empty star array, should be filled here as well... star = std::vector<vec2> (100, vec2 { 0, 400 } ); for ( auto &s : star ) { @@ -298,7 +298,7 @@ generate( unsigned int width ) /** * Updates all entity and player coordinates with their velocities. - * + * * Also handles music fading, although that could probably be placed elsewhere. */ @@ -308,15 +308,20 @@ update( Player *p, unsigned int delta ) // update player coords 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(); + } + // update entity coords for ( auto &e : entity ) { e->loc.y += e->vel.y * delta; - + // dont let structures move? if ( e->type != STRUCTURET && e->canMove ) { e->loc.x += e->vel.x * delta; - + // update boolean directions if ( e->vel.x < 0 ) e->left = true; @@ -342,7 +347,7 @@ update( Player *p, unsigned int delta ) } } } - + // handle music fades if ( ui::dialogImportant ) Mix_FadeOutMusic(2000); @@ -352,7 +357,7 @@ update( Player *p, unsigned int delta ) /** * Set the world's BGM. - * + * * This will load a sound file to be played while the player is in this world. * If no file is found, no music should play. */ @@ -366,7 +371,7 @@ setBGM( std::string path ) /** * Toggle play/stop of the background music. - * + * * If new music is to be played a crossfade will occur, otherwise... uhm. */ @@ -388,7 +393,7 @@ bgmPlay( World *prev ) const /** * The world draw function. - * + * * This function will draw the background layers, entities, and player to the * screen. */ @@ -398,34 +403,34 @@ draw( Player *p ) { // iterators int i, iStart, iEnd; - + // shade value for draws -- may be unnecessary int shadeBackground = -worldShade; - + // player's offset in worldData[] int pOffset; - + // world width in pixels int width = worldData.size() * HLINE; - + // shade value for GLSL float shadeAmbient = -worldShade / 50.0f + 0.5f; // -0.5f to 1.5f if ( shadeAmbient < 0 ) shadeAmbient = 0; else if ( shadeAmbient > 0.9f ) shadeAmbient = 1; - + /* * Draw background images. */ - + glEnable( GL_TEXTURE_2D ); - + // the sunny wallpaper is faded with the night depending on tickCount - + bgTex->bind( 0 ); safeSetColorA( 255, 255, 255, 255 - worldShade * 4 ); - + glBegin( GL_QUADS ); glTexCoord2i( 0, 0 ); glVertex2i( worldStart, SCREEN_HEIGHT ); glTexCoord2i( 1, 0 ); glVertex2i( -worldStart, SCREEN_HEIGHT ); @@ -435,24 +440,24 @@ draw( Player *p ) bgTex->bindNext(); safeSetColorA( 255, 255, 255, worldShade * 4 ); - + glBegin( GL_QUADS ); glTexCoord2i( 0, 0 ); glVertex2i( worldStart, SCREEN_HEIGHT ); glTexCoord2i( 1, 0 ); glVertex2i( -worldStart, SCREEN_HEIGHT ); glTexCoord2i( 1, 1 ); glVertex2i( -worldStart, 0 ); glTexCoord2i( 0, 1 ); glVertex2i( worldStart, 0 ); glEnd(); - + glDisable( GL_TEXTURE_2D ); - + // draw the stars if the time deems it appropriate - + //if (((( weather == WorldWeather::Dark ) & ( tickCount % DAY_CYCLE )) < DAY_CYCLE / 2) || // ((( weather == WorldWeather::Sunny ) & ( tickCount % DAY_CYCLE )) > DAY_CYCLE * .75) ){ - if ( worldShade > 0 ) { + if ( worldShade > 0 ) { safeSetColorA( 255, 255, 255, 255 - (getRand() % 30 - 15) ); - + for ( i = 0; i < 100; i++ ) { glRectf(star[i].x + offset.x * .9, star[i].y, @@ -460,15 +465,15 @@ draw( Player *p ) star[i].y + HLINE ); } - } - + } + // draw remaining background items - + glEnable( GL_TEXTURE_2D ); - + bgTex->bindNext(); safeSetColorA( 150 + shadeBackground * 2, 150 + shadeBackground * 2, 150 + shadeBackground * 2, 255 ); - + glBegin( GL_QUADS ); for ( i = 0; i <= (int)(worldData.size() * HLINE / 1920); i++ ) { glTexCoord2i( 0, 1 ); glVertex2i( width / 2 * -1 + (1920 * i ) + offset.x * .85, GROUND_HEIGHT_MINIMUM ); @@ -477,11 +482,11 @@ draw( Player *p ) glTexCoord2i( 0, 0 ); glVertex2i( width / 2 * -1 + (1920 * i ) + offset.x * .85, GROUND_HEIGHT_MINIMUM + 1080 ); } glEnd(); - + for ( i = 0; i < 4; i++ ) { bgTex->bindNext(); safeSetColorA( bgDraw[i][0] + shadeBackground * 2, bgDraw[i][0] + shadeBackground * 2, bgDraw[i][0] + shadeBackground * 2, bgDraw[i][1] ); - + glBegin( GL_QUADS ); for( int j = worldStart; j <= -worldStart; j += 600 ){ glTexCoord2i( 0, 1 ); glVertex2i( j + offset.x * bgDraw[i][2], GROUND_HEIGHT_MINIMUM ); @@ -491,22 +496,22 @@ draw( Player *p ) } glEnd(); } - + glDisable( GL_TEXTURE_2D ); - + // draw black under backgrounds - + glColor3ub( 0, 0, 0 ); glRectf( worldStart, GROUND_HEIGHT_MINIMUM, -worldStart, 0 ); - + pOffset = (offset.x + p->width / 2 - worldStart) / HLINE; - + /* * Prepare for world ground drawing. */ - + // only draw world within player vision - + if ((iStart = pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS) < 0) iStart = 0; @@ -518,51 +523,51 @@ draw( Player *p ) // draw particles and buildings std::for_each( particles.begin(), particles.end(), [](Particles part) { if ( part.behind ) part.draw(); }); - + for ( auto &b : build ) b->draw(); // draw light elements? - + glEnable( GL_TEXTURE_2D ); - + glActiveTexture( GL_TEXTURE0 ); bgTex->bindNext(); - + std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light)); auto pointArray = pointArrayBuf.get(); - + for ( i = 0; i < (int)light.size(); i++ ) { pointArray[2 * i ] = light[i].loc.x - offset.x; pointArray[2 * i + 1] = light[i].loc.y; } - + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - + glUseProgram( shaderProgram ); glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0 ); glUniform1f( glGetUniformLocation( shaderProgram, "amb" ), shadeAmbient ); - + if ( p->light ) { pointArray[2 * (light.size() + 1) ] = (float)( p->loc.x + SCREEN_WIDTH / 2 ); pointArray[2 * (light.size() + 1) + 1] = (float)( p->loc.y ); } - + if ( light.size() + (int)p->light == 0) glUniform1i( glGetUniformLocation( shaderProgram, "numLight"), 0); else { glUniform1i ( glGetUniformLocation( shaderProgram, "numLight" ), light.size() + (int)p->light ); - glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray ); + glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray ); glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor" ), 1.0f, 1.0f, 1.0f ); } - + /* * Draw the dirt. */ - + glBegin( GL_QUADS ); - + // faulty /*glTexCoord2i(0 ,0);glVertex2i(pOffset - (SCREEN_WIDTH / 1.5),0); glTexCoord2i(64,0);glVertex2i(pOffset + (SCREEN_WIDTH / 1.5),0); @@ -578,50 +583,50 @@ draw( Player *p ) glTexCoord2i( 0, 0 ); glVertex2i(worldStart + i * HLINE , worldData[i].groundHeight - GRASS_HEIGHT ); glTexCoord2i( 1, 0 ); glVertex2i(worldStart + i * HLINE + HLINE , worldData[i].groundHeight - GRASS_HEIGHT ); - + glTexCoord2i( 1, (int)(worldData[i].groundHeight / 64) + worldData[i].groundColor ); glVertex2i(worldStart + i * HLINE + HLINE, 0 ); glTexCoord2i( 0, (int)(worldData[i].groundHeight / 64) + worldData[i].groundColor ); glVertex2i(worldStart + i * HLINE , 0 ); - + if ( worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1 ) worldData[i].groundHeight = 0; } - + glEnd(); - + glUseProgram(0); glDisable(GL_TEXTURE_2D); - + /* * Draw the grass/the top of the ground. */ glEnable( GL_TEXTURE_2D ); - + glActiveTexture( GL_TEXTURE0 ); bgTex->bindNext(); - + glUseProgram( shaderProgram ); glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0); float cgh[2]; for ( i = iStart; i < iEnd - GROUND_HILLINESS; i++ ) { - + // load the current line's grass values if ( worldData[i].groundHeight ) memcpy( cgh, worldData[i].grassHeight, 2 * sizeof( float )); else memset( cgh, 0 , 2 * sizeof( float )); - + // flatten the grass if the player is standing on it. if( !worldData[i].grassUnpressed ){ cgh[0] /= 4; cgh[1] /= 4; } - + // actually draw the grass. - + safeSetColorA( 255, 255, 255, 255 ); - + glBegin( GL_QUADS ); glTexCoord2i( 0, 0 ); glVertex2i( worldStart + i * HLINE , worldData[i].groundHeight + cgh[0] ); glTexCoord2i( 1, 0 ); glVertex2i( worldStart + i * HLINE + HLINE / 2, worldData[i].groundHeight + cgh[0] ); @@ -640,9 +645,9 @@ draw( Player *p ) /* * Draw remaining entities. */ - + std::for_each( particles.begin(), particles.end(), [](Particles part) { if ( !part.behind ) part.draw(); }); - + for ( auto &n : npc ) n->draw(); @@ -651,11 +656,11 @@ draw( Player *p ) for ( auto &o : object ) o->draw(); - + /* * Handle grass-squishing. */ - + // calculate the line that the player is on int ph = ( p->loc.x + p->width / 2 - worldStart ) / HLINE; @@ -671,13 +676,13 @@ draw( Player *p ) /* * Draw the player. */ - + p->draw(); } /** * Handles physics and such for a single entity. - * + * * This function is kept private, as World::detect() should be used instead to * handle stuffs for all entities at once. */ @@ -688,11 +693,11 @@ singleDetect( Entity *e ) std::string killed; unsigned int i,j; int l; - + /* * Kill any dead entities. */ - + if ( !e->alive || e->health <= 0 ) { for ( i = 0; i < entity.size(); i++) { if ( entity[i] == e ){ @@ -748,71 +753,77 @@ singleDetect( Entity *e ) std::cout<<"RIP "<<e->name<<"."<<std::endl; exit(0); } - + /* * Handle only living entities. */ - + if(e->alive){ - + 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; 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 ( e->loc.y < worldData[i].groundHeight ) { - e->loc.y= worldData[i].groundHeight - .001 * deltaTime; - e->ground=true; - e->vel.y=0; - + if ( worldData[i].groundHeight - e->loc.y > 30 ) { + int dir = e->vel.x > 0 ? -1 : 1; + e->loc.x += HLINE * 8 * dir; + e->loc.y = worldData[i + 8 * dir].groundHeight; + } 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{ - + if(e->type == STRUCTURET && e->loc.y > 2000){ e->loc.y = worldData[i].groundHeight; e->vel.y = 0; e->ground = true; return; }else if(e->vel.y > -2)e->vel.y-=.003 * deltaTime; - + } - + /* * Insure that the entity doesn't fall off either edge of the world. */ 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; - + } } } /** * Handle entity logic for the world. - * + * * This function runs World::singleDetect() for the player and every entity * currently in a vector of this world. Particles and village entrance/exiting * are also handled here. @@ -822,20 +833,20 @@ void World:: detect( Player *p ) { int l; - + // handle the player std::thread( &World::singleDetect, this, p).detach(); - + // handle other entities for ( auto &e : entity ) std::thread(&World::singleDetect,this,e).detach(); - + // handle particles for ( auto &part : particles ) { - + // get particle's current world line l = (part.loc.x + part.width / 2 - worldStart) / HLINE; - + if ( l < 0 ) l = 0; @@ -851,7 +862,7 @@ detect( Player *p ) } else if ( part.gravity && part.vely > -2 ) part.vely -= .003 * deltaTime; } - + // handle particle creation for ( auto &b : build ) { switch ( b->bsubtype ) { @@ -870,7 +881,7 @@ detect( Player *p ) particles.back().fountain = true; } break; - + case FIRE_PIT: for(unsigned int r = (randGet() % 20) + 11; r--; ) { addParticle(randGet() % (int)(b->width / 2) + b->loc.x + b->width / 4, // x @@ -909,18 +920,18 @@ void World::addStructure(BUILD_SUB sub, float x,float y, std::string tex, std::s build.push_back(new Structures()); build.back()->inWorld = this; build.back()->textureLoc = tex; - + build.back()->spawn(sub,x,y); - + build.back()->inside = inside; - + entity.push_back(build.back()); } void World::addMob(int t,float x,float y){ mob.push_back(new Mob(t)); mob.back()->spawn(x,y); - + entity.push_back(mob.back()); } @@ -928,14 +939,14 @@ void World::addMob(int t,float x,float y,void (*hey)(Mob *)){ mob.push_back(new Mob(t)); mob.back()->spawn(x,y); mob.back()->hey = hey; - + entity.push_back(mob.back()); } void World::addNPC(float x,float y){ npc.push_back(new NPC()); npc.back()->spawn(x,y); - + entity.push_back(npc.back()); } @@ -975,7 +986,7 @@ char *World::setToLeft(const char *file){ delete[] toLeft; if(!file) return (toLeft = NULL); - + strcpy((toLeft = new char[strlen(file) + 1]),file); return toLeft; } @@ -984,7 +995,7 @@ char *World::setToRight(const char *file){ delete[] toRight; if(!file) return (toRight = NULL); - + strcpy((toRight = new char[strlen(file) + 1]),file); return toRight; } @@ -993,33 +1004,37 @@ World *World:: goWorldLeft( Player *p ) { World *tmp; - - // check if player is at world edge - if(toLeft && p->loc.x < worldStart + HLINE * 15.0f){ - - // load world (`toLeft` conditional confirms existance) + + // check if player is at world edge + if( toLeft && p->loc.x < worldStart + HLINE * 15.0f ) { + + // load world (`toLeft` conditional confirms existance) tmp = loadWorldFromXML(toLeft); - - // adjust player location - p->loc.x = tmp->worldStart - HLINE * -10.0f; + + // adjust player location + p->loc.x = tmp->worldStart + HLINE * 20; p->loc.y = tmp->worldData[tmp->lineCount - 1].groundHeight; - + return tmp; } + return this; -} +} -World *World::goWorldRight(Player *p){ +World *World:: +goWorldRight( Player *p ) +{ World *tmp; - - if(toRight && p->loc.x + p->width > -worldStart - HLINE * 15){ + + if( toRight && p->loc.x + p->width > -worldStart - HLINE * 15 ) { tmp = loadWorldFromXML(toRight); - - p->loc.x = tmp->worldStart + HLINE * 10; + + p->loc.x = tmp->worldStart - HLINE * -15.0f; p->loc.y = GROUND_HEIGHT_MINIMUM; - + return tmp; } + return this; } @@ -1033,13 +1048,13 @@ goInsideStructure( Player *p ) if(p->loc.x > b->loc.x && p->loc.x + p->width < b->loc.x + b->width ){ inside.push_back((std::string)(currentXML.c_str() + 4)); - + tmp = loadWorldFromXML(b->inside.c_str()); - + ui::toggleBlackFast(); ui::waitForCover(); ui::toggleBlackFast(); - + return tmp; } } @@ -1052,11 +1067,11 @@ goInsideStructure( Player *p ) ui::toggleBlackFast(); ui::waitForCover(); - + p->loc.x = b->loc.x + (b->width / 2); - + ui::toggleBlackFast(); - + return tmp; } } @@ -1065,10 +1080,32 @@ goInsideStructure( Player *p ) return this; } -void World::addHole(unsigned int start,unsigned int end){ - unsigned int i; - for(i=start;i<end;i++){ +void World:: +addHole( unsigned int start, unsigned int end ) +{ + for ( unsigned int i = end; i-- > start; ) worldData[i].groundHeight = 0; +} + +void World:: +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; + + if ( start < 0 ) { + offset = -start; + start = 0; + } + + if ( end > (signed)worldData.size() ) + end = worldData.size(); + + for ( int i = start; i < end; i++ ) { + worldData[i].groundHeight += thing * sin((i - start + offset) * period); + if ( worldData[i].groundHeight > peak.y ) + worldData[i].groundHeight = peak.y; } } @@ -1080,10 +1117,10 @@ getTheWidth( void ) const void World::save(void){ std::string data; - + std::string save = (std::string)currentXML + ".dat"; std::ofstream out (save,std::ios::out | std::ios::binary); - + std::cout<<"Saving to "<<save<<" ..."<<std::endl; for(auto &n : npc){ @@ -1091,40 +1128,40 @@ void World::save(void){ data.append(std::to_string((int)n->loc.x) + "\n"); data.append(std::to_string((int)n->loc.y) + "\n"); } - + for(auto &b : build){ data.append(std::to_string((int)b->loc.x) + "\n"); data.append(std::to_string((int)b->loc.y) + "\n"); } - + for(auto &m : mob){ data.append(std::to_string((int)m->loc.x) + "\n"); data.append(std::to_string((int)m->loc.y) + "\n"); data.append(std::to_string((int)m->alive) + "\n"); } - + data.append("dOnE\0"); out.write(data.c_str(),data.size()); - + out.close(); } void World::load(void){ std::string save,data,line; const char *filedata; - + save = (std::string)currentXML + ".dat"; filedata = readFile(save.c_str()); data = filedata; std::istringstream iss (data); - + for(auto &n : npc){ std::getline(iss,line); if(line == "dOnE")return; if((n->dialogIndex = std::stoi(line)) != 9999) n->addAIFunc(commonAIFunc,false); else n->clearAIFunc(); - + std::getline(iss,line); if(line == "dOnE")return; n->loc.x = std::stoi(line); @@ -1132,7 +1169,7 @@ void World::load(void){ if(line == "dOnE")return; n->loc.y = std::stoi(line); } - + for(auto &b : build){ std::getline(iss,line); if(line == "dOnE")return; @@ -1141,7 +1178,7 @@ void World::load(void){ if(line == "dOnE")return; b->loc.y = std::stoi(line); } - + for(auto &m : mob){ std::getline(iss,line); if(line == "dOnE")return; @@ -1153,12 +1190,12 @@ void World::load(void){ if(line == "dOnE")return; m->alive = std::stoi(line); } - + while(std::getline(iss,line)){ if(line == "dOnE") break; } - + delete[] filedata; } @@ -1167,16 +1204,16 @@ IndoorWorld::IndoorWorld(void){ IndoorWorld::~IndoorWorld(void){ delete bgTex; - + deleteEntities(); } void IndoorWorld::generate(unsigned int width){ // Generates a flat area of width 'width' lineCount=width+GROUND_HILLINESS; // Sets line count to the desired width plus GEN_INC to remove incorrect line calculations. if(lineCount<=0)abort(); - + worldData = std::vector<WorldData> (lineCount, WorldData { false, {0,0}, INDOOR_FLOOR_HEIGHT, 0 }); - + worldStart = (width - GROUND_HILLINESS) * HLINE / 2 * -1; } @@ -1184,71 +1221,71 @@ void IndoorWorld::draw(Player *p){ unsigned int i,ie; //int j,x,v_offset; int x; - + /* * Draw the background. */ - + glEnable(GL_TEXTURE_2D); - + std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light)); auto pointArray = pointArrayBuf.get(); - + for ( i = 0; i < light.size(); i++ ) { pointArray[2 * i ] = light[i].loc.x - offset.x; pointArray[2 * i + 1] = light[i].loc.y; } - + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - + glUseProgram( shaderProgram ); glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0 ); glUniform1f( glGetUniformLocation( shaderProgram, "amb" ), 0.3f ); - + if ( p->light ) { pointArray[2 * (light.size() + 1) ] = (float)( p->loc.x + SCREEN_WIDTH / 2 ); pointArray[2 * (light.size() + 1) + 1] = (float)( p->loc.y ); } - + if ( light.size() + (int)p->light == 0) glUniform1i( glGetUniformLocation( shaderProgram, "numLight"), 0); else { glUniform1i ( glGetUniformLocation( shaderProgram, "numLight" ), light.size() + (int)p->light ); - glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray ); + glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray ); glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor" ), 1.0f, 1.0f, 1.0f ); } - + bgTex->bind(0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //for the s direction glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //for the t direction glColor4ub(255,255,255,255); - + glBegin(GL_QUADS); glTexCoord2i(0,1); glVertex2i( worldStart - SCREEN_WIDTH / 2,0); glTexCoord2i((-worldStart*2+SCREEN_WIDTH)/512,1);glVertex2i(-worldStart + SCREEN_WIDTH / 2,0); glTexCoord2i((-worldStart*2+SCREEN_WIDTH)/512,0);glVertex2i(-worldStart + SCREEN_WIDTH / 2,SCREEN_HEIGHT); glTexCoord2i(0,0); glVertex2i( worldStart - SCREEN_WIDTH / 2,SCREEN_HEIGHT); glEnd(); - + glUseProgram(0); glDisable(GL_TEXTURE_2D); - + /* * Calculate the starting and ending points to draw the ground from. */ - + /*v_offset = (p->loc.x - x_start) / HLINE; j = v_offset - (SCREEN_WIDTH / 2 / HLINE) - GEN_INC; if(j < 0)j = 0; i = j; - + ie = v_offset + (SCREEN_WIDTH / 2 / HLINE) - GEN_INC; if(ie > lineCount)ie = lineCount;*/ - + i = 0; ie = lineCount; - + /* * Draw the ground. */ @@ -1257,7 +1294,7 @@ void IndoorWorld::draw(Player *p){ glBegin(GL_QUADS); for(;i < ie - GROUND_HILLINESS;i++){ safeSetColor(150,100,50); - + x = worldStart + i * HLINE; glVertex2i(x ,worldData[i].groundHeight); glVertex2i(x + HLINE,worldData[i].groundHeight); @@ -1266,11 +1303,11 @@ void IndoorWorld::draw(Player *p){ } glEnd(); glUseProgram(0); - + /* * Draw all entities. */ - + for ( auto &part : particles ) part.draw(); @@ -1283,14 +1320,14 @@ void IndoorWorld::draw(Player *p){ Arena::Arena(World *leave,Player *p,Mob *m){ generate(800); addMob(MS_DOOR,100,100); - + inBattle = true; mmob = m; mmob->aggressive = false; - + mob.push_back(m); entity.push_back(m); - + battleNest.push_back(leave); battleNestLoc.push_back(p->loc); } @@ -1305,17 +1342,17 @@ World *Arena::exitArena(Player *p){ p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12 ){ tmp = battleNest.front(); battleNest.erase(battleNest.begin()); - + inBattle = !battleNest.empty(); ui::toggleBlackFast(); ui::waitForCover(); - + p->loc = battleNestLoc.back(); battleNestLoc.pop_back(); - + mob.clear(); mmob->alive = false; - + return tmp; }else{ return this; @@ -1338,14 +1375,14 @@ loadWorldFromXMLNoSave( std::string path ) { XMLDocument xml; XMLElement *wxml; XMLElement *vil; - + World *tmp; float spawnx, randx; bool dialog,Indoor; - + const char *ptr; std::string name; - + currentXML = (std::string)"xml/" + path; xml.LoadFile(currentXML.c_str()); @@ -1362,10 +1399,10 @@ loadWorldFromXMLNoSave( std::string path ) { Indoor = true; tmp = new IndoorWorld(); } - + while(wxml){ name = wxml->Name(); - + if ( name == "link" ) { if((ptr = wxml->Attribute("left"))) tmp->setToLeft(ptr); @@ -1382,7 +1419,7 @@ loadWorldFromXMLNoSave( std::string path ) { if(Indoor) ((IndoorWorld *)tmp)->generate(wxml->UnsignedAttribute("width")); else { - + tmp->generate(wxml->UnsignedAttribute("width")); } }else if(Indoor) @@ -1396,7 +1433,7 @@ loadWorldFromXMLNoSave( std::string path ) { tmp->addMob(type,spawnx,wxml->FloatAttribute("y")); if(wxml->QueryBoolAttribute("aggressive",&dialog) == XML_NO_ERROR) tmp->mob.back()->aggressive = dialog; - + } else if ( name == "npc" ) { const char *npcname; @@ -1404,23 +1441,23 @@ loadWorldFromXMLNoSave( std::string path ) { tmp->addNPC(0,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 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 : + wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR ? + getRand() % tmp->getTheWidth() / 2.0f : spawnx, 100, wxml->StrAttribute("texture"), @@ -1431,7 +1468,11 @@ loadWorldFromXMLNoSave( std::string path ) { } else if ( name == "page" ) { tmp->addMob( MS_PAGE, wxml->FloatAttribute("x"), 0, commonPageFunc ); tmp->mob.back()->heyid = wxml->Attribute("id"); - } + } else if ( name == "hill" ) { + tmp->addHill( ivec2 { wxml->IntAttribute("peakx"), wxml->IntAttribute("peaky") }, wxml->UnsignedAttribute("width") ); + } else if ( name == "time") { + tickCount = std::stoi( wxml->GetText() ); + } wxml = wxml->NextSiblingElement(); } @@ -1453,7 +1494,7 @@ loadWorldFromXMLNoSave( std::string path ) { /** * READS DATA ABOUT STRUCTURE CONTAINED IN VILLAGE */ - + if ( name == "structure" ) { tmp->addStructure((BUILD_SUB)vil->UnsignedAttribute("type"), vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx, @@ -1464,7 +1505,7 @@ loadWorldFromXMLNoSave( std::string path ) { if(!strcmp(vil->Attribute("type"),"market")){ std::cout << "Market" << std::endl; tmp->addStructure((BUILD_SUB)70, - vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? + vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx, 100, vil->StrAttribute("texture"), @@ -1488,20 +1529,20 @@ loadWorldFromXMLNoSave( std::string path ) { }else if(!strcmp(vil->Attribute("type"),"trader")){ std::cout << "Trader" << std::endl; tmp->addStructure((BUILD_SUB)71, - vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? + vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx, 100, vil->StrAttribute("texture"), vil->StrAttribute("inside")); } } - + vptr->build.push_back(tmp->build.back()); - + if(vptr->build.back()->loc.x < vptr->start.x){ vptr->start.x = vptr->build.back()->loc.x; } - + if(vptr->build.back()->loc.x + vptr->build.back()->width > vptr->end.x){ vptr->end.x = vptr->build.back()->loc.x + vptr->build.back()->width; } @@ -1509,7 +1550,7 @@ loadWorldFromXMLNoSave( std::string path ) { //go to the next element in the village block vil = vil->NextSiblingElement(); } - + std::ifstream dat (((std::string)currentXML + ".dat").c_str()); if(dat.good()){ dat.close(); diff --git a/xml/playerSpawnHill1.xml b/xml/playerSpawnHill1.xml index c79b93f..86ee397 100644 --- a/xml/playerSpawnHill1.xml +++ b/xml/playerSpawnHill1.xml @@ -2,17 +2,20 @@ <World> <style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/" /> <generation type="Random" width="500" /> - <link left="playerSpawnHill2.xml" /> - - <mob x="300" type="1" aggressive="true" /> - - <trigger x="-300" id="Test" /> - + <link right="playerSpawnHill2.xml" /> + <time>12000</time> + + <hill peakx="0" peaky="1000" width="50" /> + + <mob x="300" type="1" aggressive="false" /> + + <!--<trigger x="-300" id="Test" />--> + <npc name="Ralph" hasDialog="true" /> <npc name="Johnny" hasDialog="false" /> - + <page x="-200" id="assets/pages/gootaGoFast.png" /> - + <village name="the Cranmore Tubing Park"> <structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/> <structure type="5" x="-500" inside="playerSpawnHill1_Building1.xml"/> @@ -32,20 +35,20 @@ And it wasn't stormy. ...</Trigger> <Dialog name="Ralph"> - + <text id="0" nextid="1" > Hello there! My name is Ralph. </text> - + <text id="1" nextid="2" call="Johnny" callid="0" pause="true" > You should go talk to my friend Johnny. He's a pretty chill dude. </text> - + <text id="2" > Niice. <quest check="Your First Quest" fail="3" /> </text> - + <text id="3"> Go check out Johnny. He's cool. </text> @@ -59,7 +62,7 @@ And it wasn't stormy. Wood Sword,1 </quest> </text> - + <text id="1" nextid="1" pause="true" > Broooooooooooooo... </text> diff --git a/xml/playerSpawnHill1_Building1.xml b/xml/playerSpawnHill1_Building1.xml index 67695c7..f0c8a21 100644 --- a/xml/playerSpawnHill1_Building1.xml +++ b/xml/playerSpawnHill1_Building1.xml @@ -2,7 +2,7 @@ <IndoorWorld> <style background="1" bgm="assets/music/theme_jazz.wav" /> <generation type="Random" width="300" /> - + <npc name="Bob" hasDialog="true" /> </IndoorWorld> @@ -12,23 +12,23 @@ Hey. Have a Dank MayMay :) <give id="Dank MayMay" count="1" /> </text> - + <text id="1" nextid="2"> What? You want another Dank MayMay? </text> - + <text id="2" nextid="3" pause="true"> K. <give id="Dank MayMay" count="1" /> </text> - + <text id="3" nextid="4"> Well... I'm out of Dank MayMays. </text> - + <text id="4"> Have a sword though. <give id="Wood Sword" count="1" /> </text> - + </Dialog> diff --git a/xml/playerSpawnHill2.xml b/xml/playerSpawnHill2.xml index c46dad3..8d3d328 100644 --- a/xml/playerSpawnHill2.xml +++ b/xml/playerSpawnHill2.xml @@ -3,7 +3,7 @@ <style background="0" bgm="assets/music/embark.wav" folder="assets/style/rustic/"/> <generation type="Random" width="1000" /> <structure type="5" inside="playerSpawnHill1_Building1.xml"/> - - <link right="playerSpawnHill1.xml" /> + + <link left="playerSpawnHill1.xml" /> </World> |