]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
arenas, player lighting
authorClyne Sullivan <tullivan99@gmail.com>
Mon, 7 Mar 2016 13:43:25 +0000 (08:43 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Mon, 7 Mar 2016 13:43:25 +0000 (08:43 -0500)
Changelog
include/world.h
src/entities.cpp
src/ui.cpp
src/world.cpp

index 624281e33467bbde5710ab065fef483363f0a911..a24650f1fefbe85a3ef64ae035ca21a45a0a8992 100644 (file)
--- a/Changelog
+++ b/Changelog
        - began implementing currency system
        - made the moon!
        - merchants are a-o-kay
+
+3/7/2016:
+=========
+
+       - player lighting works more
+       - arenas work
+       - cleaned up world codes
+       - andy got here
+       
+       ~ Total of 7,379 lines of code!
index 825d83df25b887bc9b8ac9e1b2aba3067fc38b20..a60eab6332b05d6580b0aab3298feac2dbbefc2f 100644 (file)
@@ -68,6 +68,20 @@ typedef struct {
     unsigned char groundColor;
 } WorldData;
 
+/**
+ * A value used by World::draw() for shading, ranges from -50 to 50 depending
+ * on the current time of day.
+ */
+
+extern int worldShade;
+
+/**
+ * The path to the currently loaded XML file.
+ */
+
+extern std::string currentXML;
+
+// prototype so Village can reference it
 class World;
 
 /**
@@ -293,6 +307,11 @@ public:
         */
        
        void addNPC(float x,float y);
+       
+       /**
+        * Adds a Merchant to the world at the specified coordinates.
+        */
+       
        void addMerchant(float x, float y);
        
        /**
@@ -413,7 +432,7 @@ public:
 };
 
 /*
- *     IndoorWorld - Indoor settings stored in a World class ;)
+ *     IndoorWorld - Indoor settings stored in a World class
  */
  
 class IndoorWorld : public World {
@@ -425,19 +444,58 @@ public:
        void draw(Player *p);                           // Draws the world (ignores layers)
 };
 
+/**
+ * The arena class - creates an arena.
+ * 
+ * This world, when created, expects a pointer to a Mob. This mob will be
+ * transported to a temporary world with the player, and the Mob will be
+ * killed upon exiting the arena.
+ */
+
 class Arena : public World {
 private:
-       Mob     *mmob;
+
+       /**
+        * The mob that the player is fighting.
+        */
+
+       Mob *mmob;
+
 public:
-       Arena(World *leave,Player *p,Mob *m);
-       ~Arena(void);
-       World *exitArena(Player *p);
+
+       /**
+        * Creates a world with the player and mob, returning the player to the
+        * world `leave` upon exit.
+        */
+
+       Arena( World *leave, Player *p, Mob *m );
+       
+       /**
+        * Frees resources taken by the arena.
+        */
+       
+       ~Arena( void );
+       
+       /**
+        * Attempts to exit the world, returning the player to the world they were
+        * last in.
+        */
+       
+       World *exitArena( Player *p );
 };
 
-extern int worldShade;
-extern std::string currentXML;
+/**
+ * Loads the player into the world created by the given XML file. If a world is
+ * already loaded it will be saved before the transition is made.
+ */
 
 World *loadWorldFromXML(std::string path);
+
+/**
+ * Loads the player into the XML-scripted world, but does not save data from the
+ * previous world if one was loaded.
+ */
+
 World *loadWorldFromXMLNoSave(std::string path);
 
 #endif // WORLD_H
index 329af63b63ca43a5c7a9011944b243d0ae20bc12..06269d607faf54e7b1fefb325c413508e39e86c1 100644 (file)
@@ -558,6 +558,7 @@ void Mob::wander(int timeRun){
           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");
                
index f0cc50710eb10cd1259af13af230b1289e1a5029..97121b4d7c9a290553507396659e564ac4348dad 100644 (file)
@@ -1483,34 +1483,36 @@ DONE:
                        }
                }
                
-               if(!dialogBoxExists&&AIpreaddr.size()){ // Flush preloaded AI functions if necessary
-                       while(!AIpreaddr.empty()){
-                               AIpreaddr.front()->addAIFunc(AIpreload.front(),false);
-                               AIpreaddr.erase(AIpreaddr.begin());
-                               AIpreload.erase(AIpreload.begin());
+                       // Flush preloaded AI functions if necessary
+               if ( !dialogBoxExists && AIpreaddr.size() ) {
+                       while ( !AIpreaddr.empty() ) {
+                               AIpreaddr.front()->addAIFunc( AIpreload.front(), false );
+                               AIpreaddr.erase( AIpreaddr.begin() );
+                               AIpreload.erase( AIpreload.begin() );
                        }
                }
        }
        
        void toggleBlack(void){
                fadeEnable ^= true;
-               fadeWhite = false;
-               fadeFast = false;
+               fadeWhite   = false;
+               fadeFast    = false;
        }
        void toggleBlackFast(void){
                fadeEnable ^= true;
-               fadeWhite = false;
-               fadeFast = true;
+               fadeWhite   = false;
+               fadeFast    = true;
        }
        void toggleWhite(void){
                fadeEnable ^= true;
-               fadeWhite = true;
-               fadeFast = false;
+               fadeWhite   = true;
+               fadeFast    = false;
        }
        void toggleWhiteFast(void){
                fadeEnable ^= true;
-               fadeWhite = true;
-               fadeFast = true;
-               Mix_PlayChannel(1,battleStart,0);
+               fadeWhite   = true;
+               fadeFast    = true;
+               
+               Mix_PlayChannel( 1, battleStart, 0 );
        }
 }
index a0ae0f3f27035491d13a535b583adb742467992e..a2baa9c8548343b5e5935ba17777cd4364cd7161 100644 (file)
@@ -523,15 +523,12 @@ draw( Player *p )
        glActiveTexture( GL_TEXTURE0 );
        bgTex->bindNext();
        
-       // help me
-       std::unique_ptr<GLfloat[][2]> pointArrayBuf = std::make_unique<GLfloat[][2]> (light.size() + p->light);
+       std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light));
        auto pointArray = pointArrayBuf.get();
        
-       //GLfloat pointArray[ light.size() + (int)p->light ][2];
-       
        for ( i = 0; i < (int)light.size(); i++ ) {
-               pointArray[i][0] = light[i].loc.x - offset.x;
-               pointArray[i][1] = light[i].loc.y;
+               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 );
@@ -542,20 +539,20 @@ draw( Player *p )
        glUniform1f( glGetUniformLocation( shaderProgram, "amb"    ), 0.5f - worldShade / 50.0f );
        
        if ( p->light ) {
-               pointArray[light.size() + 1][0] = (float)( p->loc.x + SCREEN_WIDTH / 2 );
-               pointArray[light.size() + 1][1] = (float)( p->loc.y );
+               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, (GLfloat *)&pointArray ); 
+               glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray ); 
                glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor"   ), 1.0f, 1.0f, 1.0f );
        }
        
     /*
-     * Draw the dirt?
+     * Draw the dirt.
      */
     
        glBegin( GL_QUADS );
@@ -807,9 +804,19 @@ singleDetect( Entity *e )
        }
 }
 
+/**
+ * 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.
+ */
+
 void World::
 detect( Player *p )
 {
+       int l;
+       
        // handle the player
        std::thread( &World::singleDetect, this, p).detach();
                
@@ -819,64 +826,77 @@ detect( Player *p )
         
     // handle particles
        for ( auto &part : particles ) {
-               int l;
-               unsigned int i;
-               l=(part.loc.x + part.width / 2 - worldStart) / HLINE;
-               if(l < 0) l=0;
-               i = l;
-               if(i > lineCount-1) i=lineCount-1;
-               if(part.loc.y < worldData[i].groundHeight){
-                       part.loc.y = worldData[i].groundHeight;
+               
+               // get particle's current world line
+               l = (part.loc.x + part.width / 2 - worldStart) / HLINE;
+               
+               if ( l < 0 )
+                       l = 0;
+
+               if ( l > (int)(lineCount - 1) )
+                       l = lineCount - 1;
+
+               // handle ground collision
+               if ( part.loc.y < worldData[l].groundHeight ) {
+                       part.loc.y = worldData[l].groundHeight;
                        part.vely = 0;
                        part.velx = 0;
                        part.canMove = false;
-               }else{
-                       if(part.gravity && part.vely > -2)
-                               part.vely-=.003 * deltaTime;
-               }
+               } else if ( part.gravity && part.vely > -2 )
+                       part.vely -= .003 * deltaTime;
        }
-       for(auto &b : build){
-               switch(b->bsubtype){
-                       case FOUNTAIN:
-                               for(int r = 0; r < (rand()%25)+10;r++){
-                                       addParticle(    rand()%HLINE*3 + b->loc.x + b->width/2,
-                                                                                               b->loc.y + b->height, 
-                                                                                               HLINE*1.25,
-                                                                                               HLINE*1.25, 
-                                                                                               rand()%2 == 0?-(rand()%7)*.01:(rand()%7)*.01,
-                                                                                               ((4+rand()%6)*.05), 
-                                                                                               {0,0,255}, 
-                                                                                               2500);
-
-                                       particles.back().fountain = true;
-                               }
-                               break;
-                       case FIRE_PIT:
-                               for(int r = 0; r < (rand()%20)+10;r++){
-                                       addParticle(rand()%(int)(b->width/2) + b->loc.x+b->width/4, b->loc.y+3*HLINE, HLINE, HLINE, rand()%2 == 0?-(rand()%3)*.01:(rand()%3)*.01,((4+rand()%6)*.005), {255,0,0}, 400);
-                                       particles.back().gravity = false;
-                                       particles.back().behind = true;
-                               }
-                               break;
-                       default: break;
+       
+       // handle particle creation
+       for ( auto &b : build ) {
+               switch ( b->bsubtype ) {
+               case FOUNTAIN:
+                       for ( unsigned int r = (randGet() % 25) + 11; r--; ) {
+                               addParticle(randGet() % HLINE * 3 + b->loc.x + b->width / 2,    // x
+                                                       b->loc.y + b->height,                                                           // y
+                                                       HLINE * 1.25,                                                                           // width
+                                                       HLINE * 1.25,                                                                           // height
+                                                       randGet() % 7 * .01 * (randGet() % 2 == 0 ? -1 : 1),    // vel.x
+                                                       (4 + randGet() % 6) * .05,                                                      // vel.y
+                                                       { 0, 0, 255 },                                                                          // RGB color
+                                                       2500                                                                                            // duration (ms)
+                                                       );
+
+                               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
+                                                       b->loc.y + 3 * HLINE,                                                                           // y
+                                                       HLINE,                                                                                                          // width
+                                                       HLINE,                                                                                                          // height
+                                                       randGet() % 3 * .01 * (randGet() % 2 == 0 ? -1 : 1),            // vel.x
+                                                       (4 + randGet() % 6) * .005,                                                                     // vel.y
+                                                       { 255, 0, 0 },                                                                                          // RGB color
+                                                       400                                                                                                                     // duration (ms)
+                                                       );
+
+                               particles.back().gravity = false;
+                               particles.back().behind  = true;
+                       }
+                       break;
+
+               default:
+                       break;
                }
        }
 
-       for(auto &v : village){
-               if(p->loc.x > v->start.x && p->loc.x < v->end.x){
-                       if(!v->in){
-                               ui::passiveImportantText(5000,"Welcome to %s",v->name.c_str());
+       // draws the village welcome message if the player enters the village bounds
+       for ( auto &v : village ) {
+               if ( p->loc.x > v->start.x && p->loc.x < v->end.x ) {
+                       if ( !v->in ) {
+                               ui::passiveImportantText( 5000, "Welcome to %s", v->name.c_str() );
                                v->in = true;
                        }
-               }else{
+               } else
                        v->in = false;
-               }
        }
-
-       /*if(hey->infront){
-               hey = hey->infront;
-               goto LOOOOP;
-       }*/
 }
 
 void World::addStructure(BUILD_SUB sub, float x,float y, std::string tex, std::string inside){
@@ -936,10 +956,11 @@ addParticle( float x, float y, float w, float h, float vx, float vy, Color color
 }
 
 void World::addLight(vec2 loc, Color color){
+       Light l;
        if(light.size() < 64){
-               light.emplace_back();
-               light.back().loc = loc;
-               light.back().color = color;
+               l.loc = loc;
+               l.color = color;
+               light.push_back(l);
        }
 }
 
@@ -1164,26 +1185,32 @@ void IndoorWorld::draw(Player *p){
        
        glEnable(GL_TEXTURE_2D);
        
-       std::unique_ptr<GLfloat[][2]> pointArrayBuf = std::make_unique<GLfloat[][2]> (light.size());
+       std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light));
        auto pointArray = pointArrayBuf.get();
        
-       for(uint w = 0; w < light.size(); w++){
-               pointArray[w][0] = light[w].loc.x - offset.x;
-               pointArray[w][1] = light[w].loc.y;
+       for ( i = 0; i < light.size(); i++ ) {
+               pointArray[2 * i    ] = light[i].loc.x - offset.x;
+               pointArray[2 * i + 1] = light[i].loc.y;
        }
-       glUseProgram(shaderProgram);
-       glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
-       glUniform1f(glGetUniformLocation(shaderProgram, "amb"), 0.0f);
-       if(p->light){
-               glUniform1i(glGetUniformLocation(shaderProgram, "numLight"), 1);
-               glUniform2f(glGetUniformLocation(shaderProgram, "lightLocation"), p->loc.x - offset.x+SCREEN_WIDTH/2, p->loc.y);
-               glUniform3f(glGetUniformLocation(shaderProgram, "lightColor"), 1.0f,1.0f,1.0f);
-       }else if(!light.size()){
-               glUniform1i(glGetUniformLocation(shaderProgram, "numLight"), 0);
-       }else{
-               glUniform1i(glGetUniformLocation(shaderProgram, "numLight"), light.size());
-               glUniform2fv(glGetUniformLocation(shaderProgram, "lightLocation"), light.size(), (GLfloat *)&pointArray); 
-               glUniform3f(glGetUniformLocation(shaderProgram, "lightColor"), 1.0f,1.0f,1.0f);
+       
+       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.5f - worldShade / 50.0f );
+       
+       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 ); 
+               glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor"   ), 1.0f, 1.0f, 1.0f );
        }
        
        bgTex->bind(0);
@@ -1192,10 +1219,10 @@ void IndoorWorld::draw(Player *p){
        glColor4ub(255,255,255,255);
        
        glBegin(GL_QUADS);
-                       glTexCoord2i(0,1);                                                        glVertex2i( worldStart - SCREEN_WIDTH / 2,0);
+                       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);
+                       glTexCoord2i(0,0);                                                           glVertex2i( worldStart - SCREEN_WIDTH / 2,SCREEN_HEIGHT);
        glEnd();
        
        glUseProgram(0);
@@ -1253,8 +1280,7 @@ Arena::Arena(World *leave,Player *p,Mob *m){
        
        inBattle = true;
        mmob = m;
-       //exit = leave;
-       //pxy = p->loc;
+       mmob->aggressive = false;
        
        mob.push_back(m);
        entity.push_back(m);
@@ -1264,8 +1290,6 @@ Arena::Arena(World *leave,Player *p,Mob *m){
 }
 
 Arena::~Arena(void){
-       delete bgTex;
-
        deleteEntities();
 }
 
@@ -1282,7 +1306,10 @@ World *Arena::exitArena(Player *p){
                
                p->loc = battleNestLoc.back();
                battleNestLoc.pop_back();
-               //mmob->alive = false;
+               
+               mob.clear();
+               mmob->alive = false;
+               
                return tmp;
        }else{
                return this;