From 9748d6306db7aa66128baeeca4c2a27b0efa1d87 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 9 Nov 2015 08:05:37 -0500 Subject: worlds have indepentdent entity arrays --- include/world.h | 15 ++++++ main.cpp | 155 ++++++++++++++++++++----------------------------------- src/entities.cpp | 12 ++--- src/gameplay.cpp | 28 +++------- src/world.cpp | 67 +++++++++++++++--------- 5 files changed, 126 insertions(+), 151 deletions(-) diff --git a/include/world.h b/include/world.h index e3c7f15..754f3c7 100644 --- a/include/world.h +++ b/include/world.h @@ -67,6 +67,21 @@ public: *behind, *infront; + /* + * Entity arrays. + */ + + std::vector npc; + std::vector build; + std::vector mob; + std::vector entity; + + void addStructure(_TYPE t,float x,float y); + void addMob(int t,float x,float y); + void addNPC(float x,float y); + + void update(Player *p,unsigned int delta); + /* * Constructor and deconstructor, these do what you would expect. */ diff --git a/main.cpp b/main.cpp index c68b342..292cde6 100644 --- a/main.cpp +++ b/main.cpp @@ -81,17 +81,10 @@ float handAngle; * Entity-derived object that is not pointed to in the entity * array. * - * entity - Contains pointers to 'all' entities that have been created in - * the game, including NPCs, Structures, and Mobs. World draws - * and entity handling done by the world cycle through entities - * using this array. Entities made that aren't added to this - * array probably won't be noticable by the game. - * */ World *currentWorld=NULL; Player *player; -extern std::vector entity; /* * Tells if player is currently inside a structure. @@ -542,20 +535,7 @@ void mainLoop(void){ * Update player and entity coordinates. */ - player->loc.y+= player->vel.y *deltaTime; - player->loc.x+=(player->vel.x*player->speed)*deltaTime; - - for(auto &e : entity){ - - if( e->type == NPCT || - e->type == MOBT ){ - e->loc.x += e->vel.x * deltaTime; - e->loc.y += e->vel.y * deltaTime; - - if(e->vel.x < 0)e->left = true; - else if(e->vel.x > 0)e->left = false; - } - } + currentWorld->update(player,deltaTime); /* * Update debug variables if necessary @@ -847,7 +827,7 @@ void render(){ curCoord.x += float((HLINE) * cos(angle*PI/180)); curCoord.y += float((HLINE) * sin(angle*PI/180)); } - for(auto &en : entity){ + for(auto &en : currentWorld->entity){ if(curCoord.x > en->loc.x && curCoord.x < en->loc.x + en->width){ if(curCoord.y > en->loc.y && curCoord .y < en->loc.y + en->height){ r.end = curCoord; @@ -907,7 +887,7 @@ void render(){ player->ground, SCREEN_WIDTH, // Window dimensions SCREEN_HEIGHT, // - entity.size(), // Size of entity array + currentWorld->entity.size(),// Size of entity array player->loc.x, // The player's x coordinate debugY, // The player's y coordinate tickCount, @@ -1007,109 +987,88 @@ void logic(){ * */ - for(int i = 0 ; i < entity.size(); i++){ - - /* - * Check if the entity is in this world and is alive. - */ - - if(entity[i]->inWorld == currentWorld && - entity[i]->alive){ - + for(auto &n : currentWorld->npc){ + if(n->alive){ /* - * Switch on the entity's type and handle them accordingly + * 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 + * that the NPC doesn't move when it talks to the player. + * */ - switch(entity[i]->type){ - - case NPCT: // Handle NPCs + if(n->canMove) n->wander((rand() % 120 + 30)); - /* - * 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 - * that the NPC doesn't move when it talks to the player. - * - */ + /* + * Don't bother handling the NPC if another has already been handled. + */ - if(entity[i]->canMove) - NPCp(entity[i])->wander((rand() % 120 + 30)); + if(NPCSelected){ + n->near=false; + break; + } - /* - * Don't bother handling the NPC if another has already been handled. - */ + /* + * Check if the NPC is under the mouse. + */ - if(NPCSelected){ - entity[i]->near=false; - break; - } + if(ui::mouse.x >= n->loc.x && + ui::mouse.x <= n->loc.x + n->width && + ui::mouse.y >= n->loc.y && + ui::mouse.y <= n->loc.y + n->width ){ /* - * Check if the NPC is under the mouse. + * Check of the NPC is close enough to the player for interaction to be + * considered legal. In other words, require the player to be close to + * the NPC in order to interact with it. + * + * This uses the Pythagorean theorem to check for NPCs within a certain + * radius (40 HLINEs) of the player's coordinates. + * */ - if(ui::mouse.x >= entity[i]->loc.x && - ui::mouse.x <= entity[i]->loc.x + entity[i]->width && - ui::mouse.y >= entity[i]->loc.y && - ui::mouse.y <= entity[i]->loc.y + entity[i]->width ){ + if(pow((n->loc.x - player->loc.x),2) + pow((n->loc.y - player->loc.y),2) <= pow(40*HLINE,2)){ /* - * Check of the NPC is close enough to the player for interaction to be - * considered legal. In other words, require the player to be close to - * the NPC in order to interact with it. - * - * This uses the Pythagorean theorem to check for NPCs within a certain - * radius (40 HLINEs) of the player's coordinates. - * + * Set Entity->near so that this NPC's name is drawn under them, and toggle NPCSelected + * so this NPC is the only one that's clickable. */ - if(pow((entity[i]->loc.x - player->loc.x),2) + pow((entity[i]->loc.y - player->loc.y),2) <= pow(40*HLINE,2)){ - - /* - * Set Entity->near so that this NPC's name is drawn under them, and toggle NPCSelected - * so this NPC is the only one that's clickable. - */ - - entity[i]->near=true; - NPCSelected=true; + n->near=true; + NPCSelected=true; - /* - * Check for a right click, and allow the NPC to interact with the - * player if one was made. - */ + /* + * Check for a right click, and allow the NPC to interact with the + * player if one was made. + */ - if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)){ + if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)){ - NPCp(entity[i])->interact(); - Mix_PlayChannel( -1, horn, 0); // Audio feedback + n->interact(); + Mix_PlayChannel( -1, horn, 0); // Audio feedback - } } + } /* * Hide the NPC's name if the mouse isn't on the NPC. */ - }else entity[i]->near=false; - - break; // End case NPCT - - case MOBT: // Handle Mobs - - /* - * Run the Mob's AI function. - */ - - switch(entity[i]->subtype){ - case MS_RABBIT: - case MS_BIRD: - Mobp(entity[i])->wander((rand()%240 + 15)); // Make the mob wander - break; - } + }else n->near=false; + } + } - break; // End case MOBT + for(auto &m : currentWorld->mob){ + if(m->alive){ - default:break; + /* + * Run the Mob's AI function. + */ + switch(m->subtype){ + case MS_RABBIT: + case MS_BIRD: + m->wander((rand()%240 + 15)); // Make the mob wander :) + break; } } } diff --git a/src/entities.cpp b/src/entities.cpp index acc45bd..9a3730e 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -1,14 +1,11 @@ #include #include -std::vector entity; -std::vector npc; -std::vector build; -std::vector mob; - extern FILE* names; extern unsigned int loops; +extern World *currentWorld; + void Entity::spawn(float x, float y){ //spawns the entity you pass to it based off of coords and global entity settings loc.x = x; loc.y = y; @@ -317,10 +314,7 @@ unsigned int Structures::spawn(_TYPE t, float x, float y){ //spawns a structure * with type NPC by using polymorphism. */ - npc.push_back(new NPC()); - npc.back()->spawn(loc.x+(i-5),100); - - entity.push_back(npc.back()); + currentWorld->addNPC(loc.x+(i-5),100); } break; diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 39d0675..e9d0a74 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -5,11 +5,6 @@ extern World *currentWorld; extern Player *player; -extern std::vector entity; -extern std::vector build; -extern std::vector mob; -extern std::vector npc; - extern void mainLoop(void); @@ -23,7 +18,7 @@ int giveTestQuest(NPC *speaker){ unsigned int i; ui::dialogBox(speaker->name,"Here, have a quest!"); player->qh.assign("Test"); - npc[1]->addAIFunc(compTestQuest,true); + currentWorld->npc[1]->addAIFunc(compTestQuest,true); return 0; } @@ -75,9 +70,7 @@ void initEverything(void){ * Create a structure (this will create villagers when spawned). */ - build.push_back(new Structures()); - entity.push_back(build.back()); - build.back()->spawn(STRUCTURET,(rand()%120*HLINE),10); + currentWorld->addStructure(STRUCTURET,(rand()%120*HLINE),10); /* * Generate an indoor world and link the structure to it. @@ -85,26 +78,19 @@ void initEverything(void){ IndoorWorld *iw=new IndoorWorld(); iw->generate(200); - build.back()->inside=iw; + currentWorld->build.back()->inside=iw; /* * Spawn a mob. */ - mob.push_back(new Mob(MS_RABBIT)); - entity.push_back(mob.back()); - mob.back()->spawn(200,100); - - mob.push_back(new Mob(MS_BIRD)); - entity.push_back(mob.back()); - mob.back()->spawn(-500,500); + currentWorld->addMob(MS_RABBIT,200,100); + currentWorld->addMob(MS_BIRD,-500,500); /* * Link all the entities that were just created to the initial world, and setup a test AI function. */ - npc[0]->addAIFunc(giveTestQuest,false); - for(i=0;iinWorld=currentWorld; - } + currentWorld->npc[0]->addAIFunc(giveTestQuest,false); + } diff --git a/src/world.cpp b/src/world.cpp index b0f419d..09da095 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -19,9 +19,6 @@ #define INDOOR_FLOOR_HEIGHT 100 // Defines how high the base floor of an IndoorWorld should be -extern std::vector entity; -extern std::vector build; - bool worldInside = false; float worldGetYBase(World *w){ @@ -188,6 +185,19 @@ World::~World(void){ free(line); } +void World::update(Player *p,unsigned int delta){ + p->loc.y+= p->vel.y *delta; + p->loc.x+=(p->vel.x*p->speed)*delta; + + for(auto &e : entity){ + if(e->type != STRUCTURET) + e->loc.x += e->vel.x * delta; + e->loc.y += e->vel.y * delta; + if(e->vel.x < 0)e->left = true; + else if(e->vel.x > 0)e->left = false; + } +} + int worldShade = 0; void World::draw(Player *p){ @@ -271,9 +281,8 @@ LOOP2: */ if(current==this){ - for(i=0;iinWorld==this && entity[i]->type == STRUCTURET) - entity[i]->draw(); + for(i=0;idraw(); } } @@ -393,11 +402,10 @@ LOOP2: * Draw non-structure entities. */ - for(i=0;iinWorld==this && entity[i]->type != STRUCTURET) - entity[i]->draw(); - } - + for(i=0;idraw(); + for(i=0;idraw(); } /* @@ -511,14 +519,29 @@ void World::detect(Player *p){ * Handle all remaining entities in this world. */ - for(i=0;iinWorld==this){ - - singleDetect(entity[i]); - - } - } + for(i=0;ispawn(t,x,y); + + 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()); +} + +void World::addNPC(float x,float y){ + npc.push_back(new NPC()); + npc.back()->spawn(x,y); + + entity.push_back(npc.back()); } /* @@ -644,9 +667,7 @@ void IndoorWorld::draw(Player *p){ glVertex2i(x_start+i*HLINE ,line[i].y-50); } glEnd(); - for(i=0;iinWorld==this) - entity[i]->draw(); - } + for(i=0;idraw(); p->draw(); } -- cgit v1.2.3