]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
npc world switching
authorClyne Sullivan <tullivan99@gmail.com>
Fri, 13 May 2016 12:47:12 +0000 (08:47 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Fri, 13 May 2016 12:47:12 +0000 (08:47 -0400)
Changelog
include/entities.hpp
include/world.hpp
main.cpp
src/entities.cpp
src/ui.cpp
src/world.cpp

index 2d11496241890a7e12f3ab1a47bbc5155734f56d..bd4fb68b6db411cc8d1e9f52916b06e2473b3818 100644 (file)
--- a/Changelog
+++ b/Changelog
        - fixed important bugs/memory leaks, few segfaults happen now
        - new rendering almost complete
        - brice stuff almost done
+
+5/13/2016:
+==========
+
+       - NPCs and mobs can gracefully walk between worlds, carry dialog
+       - began more work on combat stuffs
index ce2e14d854150dd644a27b4447fee13b2dc875c9..7487bbebf3da45e468e9f882317323132a2509d8 100644 (file)
@@ -207,6 +207,9 @@ public:
        // tells direction entity is facing
        bool right, left;
 
+       // tells if the entity is from another world
+       char outnabout;
+
        // set to 1 if entity is on the ground, 0 if in the air
        unsigned char ground;
 
index c40f5f5373e1fd711b053cc5468e0093a421de81..74f9cb76b665b1b1bf4877ae12e90d20167c6146 100644 (file)
@@ -1,24 +1,15 @@
-/* ----------------------------------------------------------------------------
-** The world stuffs.
-**
-** This file contains the classes and variables necessary to create an in-game
-** world... "and stuffs".
-** --------------------------------------------------------------------------*/
 #ifndef WORLD_H
 #define WORLD_H
 
-/* ----------------------------------------------------------------------------
-** Includes section
-** --------------------------------------------------------------------------*/
+/**
+ * @file  world.hpp
+ * @brief The world system
+ */
 
 // local game includes
 #include <common.hpp>
 #include <entities.hpp>
 
-/* ----------------------------------------------------------------------------
-** Structures section
-** --------------------------------------------------------------------------*/
-
 /**
  * The background type enum.
  * This enum contains all different possibilities for world backgrounds; used
@@ -47,164 +38,363 @@ enum class WorldWeather : unsigned char {
  * lines. Dirt color and grass properties are also kept track of here.
  */
 typedef struct {
-    bool          grassUnpressed;
-    float         grassHeight[2];
-    float         groundHeight;
-    unsigned char groundColor;
+    bool          grassUnpressed; /**< squishes grass if false */
+    float         grassHeight[2]; /**< height of the two grass blades */
+    float         groundHeight;   /**< height of the 'line' */
+    unsigned char groundColor;    /**< a value that affects the ground's color */
 } WorldData;
 
+/**
+ * Contains info necessary for switching worlds.
+ * This pair contains a pointer to the new world, and the new set of
+ * coordinates the player should be at in that world.
+ */
 typedef std::pair<World *, vec2> WorldSwitchInfo;
 
-/* ----------------------------------------------------------------------------
-** Variables section
-** --------------------------------------------------------------------------*/
-
-// affects brightness of world elements when drawn
+/**
+ * Alters how bright world elements are drawn.
+ * This value is based off of the current time of day (tick count), set in
+ * main.cpp.
+ */
 extern int worldShade;
 
-// the path to the currently loaded XML file.
+/**
+ * The file path to the currently loaded XML file.
+ */
 extern std::string currentXML;
 
-// defines how many game ticks it takes for a day to elapse
+/**
+ * Defines how many game ticks it takes to go from day to night or vice versa.
+ */
 constexpr const unsigned int DAY_CYCLE = 12000;
 
-// velocity of player when moved by user
+/**
+ * Defines the velocity of player when moved by the keyboard
+ */
 constexpr const float PLAYER_SPEED_CONSTANT = 0.15f;
 
-// maximum pull of gravity in one game tick
+/**
+ * Defines the strongest pull gravity can have on an entity.
+ * This is the most that can be subtracted from an entity's velocity in one
+ * game tick.
+ */
 constexpr const float GRAVITY_CONSTANT = 0.001f;
 
-// height of the floor in an indoor world
+/**
+ * Defines the thickness of the floor in an indoor world.
+ */
 constexpr const unsigned int INDOOR_FLOOR_THICKNESS = 50;
+
+/**
+ * Defines how far each floor can be from the next (height).
+ */
 constexpr const unsigned int INDOOR_FLOOR_HEIGHTT = 400;
-constexpr const unsigned int INDOOR_FLOOR_HEIGHT = (INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS);
 
-/* ----------------------------------------------------------------------------
-** Classes / function prototypes section
-** --------------------------------------------------------------------------*/
+/**
+ * Gets a combined height of the floor and the area before it.
+ * This value is commonly used for operations like moving between floors.
+ */
+constexpr const unsigned int INDOOR_FLOOR_HEIGHT = (INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS);
 
 /**
- * The village class, used to group structures into villages.
+ * The village class.
+ * This class defines an area in a world that is considered to be a village,
+ * and provides a welcome message when the player enters the area.
  */
 class Village {
 public:
+       /**
+        * The name of the village.
+        */
        std::string name;
+
+       /**
+        * The start and end coordinates of the village.
+        */
        vec2 start, end;
+
+       /**
+        * A "player in village" flag.
+        * This flag is used to trigger displaying the welcome message.
+        */
        bool in;
 
+       /**
+        * Constructs a village with the given name, inside the given world.
+        */
        Village(std::string meme, World *w);
+
+       /**
+        * Destructs the village.
+        */
        ~Village(void){}
 };
 
 /**
- * The world class. This class does everything a world should do.
+ * The world class. 
+ * This class handles entity creation, management, and deletion. Most
+ * world-related operations have to be done through this class, such as
+ * drawing.
  */
 class World {
 protected:
 
-       // an array of all the world's ground data
+       /**
+        * An array of all the world's ground data, populated through
+        * World::generate().
+        *
+        * @see generate()
+        */
        std::vector<WorldData> worldData;
 
-       // the world's current weather
+       /**
+        * Contains the current state of weather in the world.
+        */
        WorldWeather weather;
 
-       // the size of `worldData`
+       /**
+        * Contains the size of the 'worldData' array.
+        */
        unsigned int lineCount;
 
-       // the left-most (negative) coordinate of the worldStart
+       /**
+        * The starting x-coordinate of the world.
+        */
        float worldStart;
 
-       // holds / handles textures for background elements
+       /**
+        * Handles textures for the background elements.
+        */
        TextureIterator bgTex;
 
-       // defines what type of background is being used
+       /**
+        * Defines the set of background images being used for the world.
+        *
+        * @see setBackground()
+        */
        WorldBGType bgType;
 
-       // an SDL_mixer object for the world's BGM
+       /**
+        * SDL_Mixer's object for the loaded BGM.
+        */
        Mix_Music *bgmObj;
 
-       // the pathname of the loaded BGM
+       /**
+        * The filename of the world's BGM file.
+        *
+        * @see setBGM()
+        */
        std::string bgm;
 
-       // XML file names of worlds to the left and right, empty if nonexistant
+       /**
+        * The path to the XML file of the world to the left.
+        *
+        * @see setToLeft()
+        */
        std::string toLeft;
+
+       /**
+        * The path to the XML file of the world to the right.
+        *
+        * @see setToRight()
+        */
        std::string toRight;
 
-       // structure texture file paths
+       /**
+        * A vector of paths for the structure textures.
+        * The appearance of structures depends on the world's theme.
+        *
+        * @see setStyle()
+        */
        std::vector<std::string> sTexLoc;
 
-       // TODO
+       /**
+        * The paths of files to be used for the background textures.
+        *
+        * @see setStyle()
+        */
        std::vector<std::string> bgFiles;
+
+       /**
+        * The paths of files to be used for the indoor background textures.
+        *
+        * @see setStyle()
+        */
        std::vector<std::string> bgFilesIndoors;
 
-       // an array of star coordinates
+       /**
+        * Contains randomly generated coordinates for stars.
+        */
        std::vector<vec2> star;
 
-       // entity vectors
+       /**
+        * A vector of all light elements in the world.
+        *
+        * @see addLight()
+        * @see getLastLight()
+        */
        std::vector<Light>        light;
+
+       /**
+        * A vector of all mobs in the world.
+        *
+        * @see addMob()
+        * @see getLastMob()
+        * @see getNearMob()
+        */
        std::vector<Mob *>        mob;
+
+       /**
+        * A vector of all objects in the world.
+        *
+        * @see addObject()
+        */
        std::vector<Object>           object;
+
+       /**
+        * A vector of all particles in the world.
+        *
+        * @see addParticle()
+        */
        std::vector<Particles>    particles;
+
+       /**
+        * A vector of all structures in the world.
+        *
+        * @see addStructure()
+        * @see getStructurePos()
+        */
        std::vector<Structures *> build;
+
+       /**
+        * A vector of all villages in the world.
+        *
+        * @see addVillage()
+        */
        std::vector<Village>      village;
 
-       // handles death, gravity, etc. for a single entity
+       /**
+        * Handles death, gravity, etc. for a single entity
+        */
        virtual void singleDetect(Entity *e);
 
-       // frees entities and clears vectors that contain them
+       /**
+        * Destroys entities and clears vectors that contain them.
+        * This function is only called in the world destructor.
+        */
        void deleteEntities(void);
-
-protected:
        
+       /**
+        * Draws background textures.
+        */
        void drawBackgrounds();
 
 public:
 
-       // entity vectors that need to be public because we're based
+       /**
+        * A vector of pointers to all entities from the other vectors.
+        * This is used to mass-manage entities, or operate on entities
+        * outside of what the world does.
+        *
+        * @see getNearInteractable()
+        */
        std::vector<Entity *> entity;
 
+       /**
+        * A vector of all NPCs in the world.
+        *
+        * @see addNPC()
+        */
        std::vector<NPC *>      npc;
+
+       /**
+        * A vector of all merchants in the world.
+        *
+        * @see addMerchant()
+        */
        std::vector<Merchant *> merchant;
 
-       // the world constructor, prepares variables
+       /**
+        * Constructs the world, resets variables.
+        */
        World(void);
 
-       // destructor, frees used memory
+       /**
+        * Destructs the world, frees memory.
+        */
        virtual ~World(void);
 
-       // generates a world of the specified width
+       /**
+        * Generates a world of the specified width.
+        * This will populate the 'worldData' array and create star coordinates.
+        * It's necessary to call this function to actually use the world.
+        */
        void generate(int width);
 
-       // draws everything to the screen
+       /**
+        * Draws everything the world handles to the screen (and the player).
+        * Drawing is based off of the player so that off-screen elements are not
+        * drawn.
+        */
        virtual void draw(Player *p);
 
-       // handles collisions/death of player and all entities
+       /**
+        * Handles physics for all entities and the player.
+        *
+        * @see singleDetect()
+        */
        void detect(Player *p);
 
-       // updates entities, moving them and such
+       /**
+        * Updates entity positions, time of day, and music.
+        */
        void update(Player *p, unsigned int delta, unsigned int ticks);
 
-       // gets the world's width in TODO
+       /**
+        * Gets the width of the world, presumably in pixels.
+        * TODO
+        */
        int getTheWidth(void) const;
 
-       // gets the starting x coordinate of the world
+       /**
+        * Gets the starting x-coordinate of the world.
+        *
+        * @see worldStart
+        */
        float getWorldStart(void) const;
 
-       // gets a pointer to the most recently added light
+       /**
+        * Gets a pointer to the most recently created light.
+        * This is used to update properties of the light outside of the
+        * world class.
+        */
        Light *getLastLight(void);
 
-       // gets a pointer to the most recently added mob
+       /**
+        * Gets a pointer ot the most recently created mob.
+        * This is used to update properties of the mob outside of the
+        * world class.
+        */
        Mob *getLastMob(void);
 
-       // gets the nearest interactable entity to the given one
+       /**
+        * Finds the entity nearest to the provided one.
+        */
        Entity *getNearInteractable(Entity &e);
 
+       /**
+        * Finds the mob nearest to the given entity.
+        */
        Mob *getNearMob(Entity &e);
 
-       // gets the coordinates of the `index`th structure
+       /**
+        * Gets the coordinates of the `index`th structure.
+        */
        vec2 getStructurePos(int index);
 
-       // gets the texture path of the `index`th structure
+       /**
+        * Gets the texture path of the `index`th structure
+        */
        std::string getSTextureLocation(unsigned int index) const;
 
        // saves the world's data to an XML file
@@ -239,12 +429,29 @@ public:
        WorldSwitchInfo goWorldLeft(Player *p);
        WorldSwitchInfo goWorldRight(Player *p);
 
-       // attempts to move an NPC to the left adjacent world, returning true on success
+       /**
+        * Attempts to move an NPC to the left adjacent world, returning true on success.
+        */
        bool goWorldLeft(NPC *e);
 
+       /**
+        * Attempts to move an NPC to the world to the right, returning true on success.
+        */
+       bool goWorldRight(NPC *e);
+
        // attempts to enter a structure that the player would be standing in front of
        WorldSwitchInfo goInsideStructure(Player *p);
 
+       /**
+        * Adopts an NPC from another world, taking its ownership.
+        */
+       void adoptNPC(NPC *e);
+       
+       /**
+        * Adopts a mob from another world, taking its ownership.
+        */
+       void adoptMob(Mob *e);
+
        // adds a hole at the specified start and end x-coordinates
        void addHole(unsigned int start,unsigned int end);
 
index 4c3ba81854bd8410f1a4200644d41f3f7eeced03..a9138c787f17405abb8d025e0bf70568068226e9 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -506,6 +506,8 @@ void logic(){
                                e->near = false;
                                continue;
                        } else if (e->canMove) {
+                               if (!currentWorld->goWorldLeft(dynamic_cast<NPC *>(e)))
+                                       currentWorld->goWorldRight(dynamic_cast<NPC *>(e));
                                e->wander((rand() % 120 + 30));
                                if (NPCSelected) {
                                        e->near = false;
@@ -520,8 +522,13 @@ void logic(){
                                else
                                        NPCSelected = true;
 
-                               if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) && !ui::dialogBoxExists)
+                               if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) && !ui::dialogBoxExists) {
+                                       if (ui::mouse.x < player->loc.x && player->right)
+                                               player->left = true, player->right = false;
+                                       else if(ui::mouse.x > player->loc.x && player->left)
+                                               player->right = true, player->left = false;
                                        e->interact();
+                               }
                        } else {
                                e->near = false;
                        }
index 5084fd6a38d7a23666d710726d9200f15a25fca0..dc1a45a4ba7004fa50b52a5f8dc25e6b545cb663 100644 (file)
@@ -79,6 +79,7 @@ Entity::Entity(void)
        height = 0;
        health = 0;
        maxHealth = 0;
+       outnabout = 0;
        z = 1.0f;
        targetx = 0.9112001f;
 
@@ -374,18 +375,19 @@ void Entity::draw(void)
        case PLAYERT:
                static int texState = 0;
                if (speed && !(game::time::getTickCount() % ((2.0f/speed) < 1 ? 1 : (int)((float)2.0f/(float)speed)))) {
-                       if (++texState==9)texState=1;
+                       if (++texState == 9)
+                               texState = 1;
                        glActiveTexture(GL_TEXTURE0);
                        tex(texState);
                }
                if (!ground) {
-                       glActiveTexture(GL_TEXTURE0 + 0);
+                       glActiveTexture(GL_TEXTURE0);
                        tex(0);
-               }else if (vel.x) {
-                       glActiveTexture(GL_TEXTURE0 + 0);
+               } else if (vel.x) {
+                       glActiveTexture(GL_TEXTURE0);
                        tex(texState);
-               }else{
-                       glActiveTexture(GL_TEXTURE0 + 0);
+               } else {
+                       glActiveTexture(GL_TEXTURE0);
                        tex(0);
                }
                break;
@@ -427,13 +429,13 @@ if (health != maxHealth) {
        glUniform1i(worldShader_uniform_texture, 0);
 
        GLfloat coord_back[] = {
-               loc.x,                  loc.y + height,                              z,
-               loc.x + width,  loc.y + height,                              z,
-               loc.x + width,  loc.y + height + game::HLINE * 2,z,
+               loc.x,                  loc.y + height,                               z,
+               loc.x + width,  loc.y + height,                               z,
+               loc.x + width,  loc.y + height + game::HLINE * 2, z,
 
-               loc.x + width,  loc.y + height + game::HLINE * 2,z,
-               loc.x,                  loc.y + height + game::HLINE * 2,z,
-               loc.x,                  loc.y + height,                              z,
+               loc.x + width,  loc.y + height + game::HLINE * 2, z,
+               loc.x,                  loc.y + height + game::HLINE * 2, z,
+               loc.x,                  loc.y + height,                               z,
        };
 
        GLfloat coord_front[] = {
@@ -550,7 +552,12 @@ void NPC::interact() { //have the npc's interact back to the player
 
                if (dialogCount && dialogIndex != 9999) {
                        // load the XML file and find the dialog tags
-                       xml.LoadFile(currentXML.c_str());
+                       if (outnabout == 0)
+                               xml.LoadFile(currentXML.c_str());
+                       else if (outnabout < 0)
+                               xml.LoadFile((xmlFolder + currentWorld->getToLeft()).c_str());
+                       else
+                               xml.LoadFile((xmlFolder + currentWorld->getToRight()).c_str());
 COMMONAIFUNC:
                        idx = 0;
                        stop = false;
@@ -608,6 +615,10 @@ COMMONAIFUNC:
                        if ((oxml = exml->FirstChildElement("gotox")))
                                moveTo(std::stoi(oxml->GetText()));
 
+                       // asdlfkj
+                       auto ptr = exml->GetText() - 1;
+                       while (isspace(*++ptr));
+
                        // handle dialog options
                        if ((oxml = exml->FirstChildElement("option"))) {
                                std::string optstr;
@@ -620,9 +631,9 @@ COMMONAIFUNC:
                                        // save the associated XMLElement
                                        dopt.push_back(oxml);
                                } while ((oxml = oxml->NextSiblingElement()));
-
+                               
                                // run the dialog stuff
-                               ui::dialogBox(name, optstr, false, exml->GetText() + 2);
+                               ui::dialogBox(name, optstr, false, ptr);
                                ui::waitForDialog();
 
                                if (ui::dialogOptChosen)
@@ -633,7 +644,7 @@ COMMONAIFUNC:
 
                        // optionless dialog
                        else {
-                               ui::dialogBox(name, "", false, exml->GetText());
+                               ui::dialogBox(name, "", false, ptr);
                                ui::waitForDialog();
                        }
 
index 64e18fea6aa940aeeaa62dafc814320a196e0cb6..51edb8653b60cd08f9d5fb54078ec13a14cb1a89 100644 (file)
@@ -442,7 +442,7 @@ namespace ui {
 
        std::string ret;
        std::string typeOut(std::string str) {
-               static unsigned int tadv = TICKS_PER_SEC / 12;
+               static unsigned int tadv = 1;
                static unsigned int tickk,
                                                        linc=0, //      Contains the number of letters that should be drawn.
                                                        size=0; //      Contains the full size of the current string.
@@ -467,9 +467,21 @@ namespace ui {
                        tickk = tickCount + tadv;
                        ret += str[linc];
 
-                       if (linc < size)
-                               linc++;
-                       else
+                       if (linc < size) {
+                               switch (str[++linc]) {
+                               case '!':
+                               case '?':
+                               case '.':
+                                       tadv = 10;
+                                       break;
+                               case ',':
+                                       tadv = 5;
+                               break;
+                               default:
+                                       tadv = 1;
+                                       break;
+                               }
+                       } else
                                typeOutDone = true;
                }
 
index 88ef57a523aca040ccafd8db814fbce4aeb9b814..327a7873b1edd3b6c18b3729f5dea6e14dff476e 100644 (file)
@@ -1089,8 +1089,7 @@ void World::load(void){
  * Toggle play/stop of the background music.
  * If new music is to be played a crossfade will occur, otherwise... uhm.
  */
-void World::
-bgmPlay(World *prev) const
+void World::bgmPlay(World *prev) const
 {
        if (prev == nullptr || bgm != prev->bgm) {
                Mix_FadeOutMusic(800);
@@ -1103,8 +1102,7 @@ bgmPlay(World *prev) const
  * 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.
  */
-void World::
-setBGM(std::string path)
+void World::setBGM(std::string path)
 {
        if (!path.empty())
                bgmObj = Mix_LoadMUS((bgm = path).c_str());
@@ -1115,8 +1113,7 @@ setBGM(std::string path)
  * The images chosen for the background layers are selected depending on the
  * world's background type.
  */
-void World::
-setBackground(WorldBGType bgt)
+void World::setBackground(WorldBGType bgt)
 {
     // load textures with a limit check
        switch ((bgType = bgt)) {
@@ -1137,8 +1134,7 @@ setBackground(WorldBGType bgt)
  * The world's style will determine what sprites are used for things like\
  * generic structures.
  */
-void World::
-setStyle(std::string pre)
+void World::setStyle(std::string pre)
 {
     // get folder prefix
        std::string prefix = pre.empty() ? "assets/style/classic/" : pre;
@@ -1157,8 +1153,7 @@ setStyle(std::string pre)
 /**
  * Pretty self-explanatory.
  */
-std::string World::
-getWeatherStr(void) const
+std::string World::getWeatherStr(void) const
 {
        switch (weather) {
        case WorldWeather::Sunny:
@@ -1177,8 +1172,7 @@ getWeatherStr(void) const
        return "???";
 }
 
-const WorldWeather& World::
-getWeatherId(void) const
+const WorldWeather& World::getWeatherId(void) const
 {
        return weather;
 }
@@ -1186,8 +1180,7 @@ getWeatherId(void) const
 /**
  * Pretty self-explanatory.
  */
-std::string World::
-setToLeft(std::string file)
+std::string World::setToLeft(std::string file)
 {
     return (toLeft = file);
 }
@@ -1195,8 +1188,7 @@ setToLeft(std::string file)
 /**
  * Pretty self-explanatory.
  */
-std::string World::
-setToRight(std::string file)
+std::string World::setToRight(std::string file)
 {
        return (toRight = file);
 }
@@ -1204,8 +1196,7 @@ setToRight(std::string file)
 /**
  * Pretty self-explanatory.
  */
-std::string World::
-getToLeft(void) const
+std::string World::getToLeft(void) const
 {
     return toLeft;
 }
@@ -1213,8 +1204,7 @@ getToLeft(void) const
 /**
  * Pretty self-explanatory.
  */
-std::string World::
-getToRight(void) const
+std::string World::getToRight(void) const
 {
     return toRight;
 }
@@ -1222,8 +1212,7 @@ getToRight(void) const
 /**
  * Attempts to go to the left world, returning either that world or itself.
  */
-WorldSwitchInfo World::
-goWorldLeft(Player *p)
+WorldSwitchInfo World::goWorldLeft(Player *p)
 {
        World *tmp;
 
@@ -1243,8 +1232,7 @@ goWorldLeft(Player *p)
 /**
  * Attempts to go to the right world, returning either that world or itself.
  */
-WorldSwitchInfo World::
-goWorldRight(Player *p)
+WorldSwitchInfo World::goWorldRight(Player *p)
 {
        World *tmp;
 
@@ -1256,19 +1244,51 @@ goWorldRight(Player *p)
        return std::make_pair(this, vec2 {0, 0});
 }
 
+void World::adoptNPC(NPC *e)
+{
+       entity.push_back(e);
+       npc.push_back(e);
+}
+
+void World::adoptMob(Mob *e)
+{
+       entity.push_back(e);
+       mob.push_back(e);
+}
+
 /**
  * Acts like goWorldLeft(), but takes an NPC; returning true on success.
  */
-bool World::
-goWorldLeft(NPC *e)
+bool World::goWorldLeft(NPC *e)
 {
        // check if entity is at world edge
-       if(!toLeft.empty() && e->loc.x < worldStart + HLINES(15)) {
-        currentWorldToLeft->addNPC(e->loc.x,e->loc.y);
-        e->die();
+       if (!toLeft.empty() && e->loc.x < worldStart + HLINES(15)) {
+               currentWorldToLeft->adoptNPC(e);
+
+               npc.erase(std::find(std::begin(npc), std::end(npc), e));
+               entity.erase(std::find(std::begin(entity), std::end(entity), e));
+
+        e->loc.x = currentWorldToLeft->worldStart + currentWorldToLeft->getTheWidth() - HLINES(15);
+               e->loc.y = GROUND_HEIGHT_MAXIMUM;
+               ++e->outnabout;
+
+               return true;
+       }
+
+       return false;
+}
+
+bool World::goWorldRight(NPC *e)
+{
+       if (!toRight.empty() && e->loc.x + e->width > -worldStart - HLINES(15)) {
+               currentWorldToRight->adoptNPC(e);
 
-        currentWorldToLeft->npc.back()->loc.x = currentWorldToLeft->worldStart + currentWorldToLeft->getTheWidth() - HLINES(15);
-               currentWorldToLeft->npc.back()->loc.y = GROUND_HEIGHT_MAXIMUM;
+               npc.erase(std::find(std::begin(npc), std::end(npc), e));
+               entity.erase(std::find(std::begin(entity), std::end(entity), e));
+       
+               e->loc.x = currentWorldToRight->worldStart + HLINES(15);
+               e->loc.y = GROUND_HEIGHT_MINIMUM;
+               --e->outnabout;
 
                return true;
        }
@@ -1279,8 +1299,7 @@ goWorldLeft(NPC *e)
 /**
  * Attempts to enter a building that the player is standing in front of.
  */
-WorldSwitchInfo World::
-goInsideStructure(Player *p)
+WorldSwitchInfo World::goInsideStructure(Player *p)
 {
        World *tmp;