]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
added TextureIterator
authorClyne Sullivan <tullivan99@gmail.com>
Sun, 1 May 2016 01:08:39 +0000 (21:08 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Sun, 1 May 2016 01:08:39 +0000 (21:08 -0400)
include/common.hpp
include/entities.hpp
include/texture.hpp
include/world.hpp
main.cpp
setup.mk [deleted file]
src/common.cpp
src/entities.cpp
src/inventory.cpp
src/mob.cpp
src/world.cpp

index c30f861f90d0f91716ed123326b8728e85026e64..3712f62fa53c77a4b23c0c209a5df5a8615e3e19 100644 (file)
 
 // holy moly
 #include <iostream>
-#include <cstdlib>
 #include <string>
 #include <vector>
-#include <string>
-#include <fstream>
 #include <thread>
-#include <mutex>
-#include <future>
 #include <cmath>
 #include <algorithm>
 
 #include <SDL2/SDL_image.h>
 #include <SDL2/SDL_mixer.h>
 
+#include <config.hpp>
+
 #ifdef __WIN32__
 typedef unsigned int uint;
 #undef near
 #endif
 
-/**
- * Defines how many game ticks should occur in one second, affecting how often
- * game logic is handled.
- */
-
-#define TICKS_PER_SEC 20
+// the number of ticks that should occur in one second
+constexpr const unsigned int TICKS_PER_SEC = 20;
 
-/**
- * Defines how many milliseconds each game tick will take.
- */
-
-#define MSEC_PER_TICK (1000 / TICKS_PER_SEC)
-
-/**
- * This flag lets the compuler know that we are testing for segfault locations.
- * If this flag is enabled, the function C(x) will print 'x' to terminal
- */
+// the number of milliseconds inbetween each tick
+constexpr const float MSEC_PER_TICK = 1000.0f / TICKS_PER_SEC;
 
+// segfault-debugging output
 //#define SEGFAULT
 
-/**
- * This flag lets the compiler know that we want to use shaders.
- */
-
-#define SHADERS
-
-template<typename N>
-N abso(N v) {
-       if (v < 0) {
-               return v * -1;
-       }else
-               return v;
-}
-
-template<class A>
-float averagef(A v) {
-       float avg = 0;
-       for(auto &a : v) {
-               avg += a;
-       }
-       avg /= v.size();
-       return avg;
-}
+#ifdef SEGFAULT
+#define C(x) std::cout << x << std::endl
+#else
+#define C(x)
+#endif
 
+// printf's a message to the console with file/line info
+#define DEBUG_printf(message, ...) DEBUG_prints(__FILE__, __LINE__, message, __VA_ARGS__)
 
 extern GLuint colorIndex;      // Texture.cpp?
 
@@ -90,6 +60,8 @@ typedef struct {
        int y;
 } ivec2;
 
+typedef ivec2 dim2;
+
 struct _vec2 {
        float x;
        float y;
@@ -115,8 +87,6 @@ typedef struct {
        float z;
 } vec3;
 
-typedef ivec2 dim2;
-
 /**
  * This structure contains two sets of coordinates for ray drawing.
  */
@@ -126,140 +96,82 @@ typedef struct {
        vec2 end;
 } Ray;
 
-struct col {
+struct _color {
        float red;
        float green;
        float blue;
-       col operator-=(float a) {
+       _color operator-=(float a) {
                red-=a;
                green-=a;
                blue-=a;
                return{red+a,green+a,blue+a};
        }
-       col operator+=(float a) {
+       _color operator+=(float a) {
                return{red+a,green+a,blue+a};
        }
-       col operator=(float a) {
+       _color operator=(float a) {
                return{red=a,green=a,blue=a};
        }
 };
 
-typedef col Color;
-
-/**
- * Define the game's name (displayed in the window title).
- */
-
-#define GAME_NAME              "Independent Study v0.7 alpha - NOW WITH lights and snow and stuff"
-
-extern bool uiLoop;
-extern std::mutex mtx;
-
-/**
- * Define the length of a single HLINE.
- * The game has a great amount of elements that need to be drawn or detected, and having each
- * of them use specific hard-coded numbers would be painful to debug. As a solution, this
- * definition was made. Every item being drawn to the screen and most object detection/physic
- * handling is done based off of this number. Increasing it will give the game a zoomed-in
- * feel, while decreasing it will do the opposite.
- *
- */
-
-#define HLINES(n) (static_cast<int>(game::HLINE * n))
-
-/**
- * A 'wrapper' for libc's srand(), as we hope to eventually have our own random number
- * generator.
- */
-
-#define initRand(s) srand(s)
-
-
-
-/**
- * A 'wrapper' for libc's rand(), as we hope to eventually have our own random number
- * generator.
- */
+typedef struct _color Color;
 
-#define getRand() rand()
+// gets the length of `n` HLINEs
+template<typename T>
+inline T HLINES(const T &n)
+{
+       return (static_cast<T>(game::HLINE) * n);
+}
 
-#define randGet     rand
+// random number generator initializer (TODO decide how to random gen. numbers)
 #define randInit    srand
 
-/**
- * Included in common.h is a prototype for DEBUG_prints, which writes a formatted
- * string to the console containing the callee's file and line number. This macro simplifies
- * it to a simple printf call.
- *
- * DEBUG must be defined for this macro to function.
- */
-
-#define DEBUG_printf(message, ...) DEBUG_prints(__FILE__, __LINE__, message, __VA_ARGS__)
-
-#ifdef SEGFAULT
-#define C(x) std::cout << x << std::endl
-#else
-#define C(x)
-#endif
-
-/**
- * Defines pi for calculations that need it.
- */
-
-#define PI 3.1415926535
+// gets random number
+#define randGet     rand
 
+// defines pi for calculations that need it.
+constexpr const float PI = 3.1415926535f;
 
 // references the variable in main.cpp, used for drawing with the player
 extern vec2 offset;
 
-// counts the number of times logic() (see main.cpp) has been called, for animating sprites
-extern unsigned int loops;
-
+// the shader program created in main.cpp
 extern GLuint shaderProgram;
 
 /**
  *     Prints a formatted debug message to the console, along with the callee's file and line
  *     number.
  */
-
 void DEBUG_prints(const char* file, int line, const char *s,...);
 
 /**
  * Sets color using glColor3ub(), but handles potential overflow.
  */
-
 void safeSetColor(int r,int g,int b);
 
 /**
  * Sets color using glColor4ub(), but handles potential overflow.
  */
-
 void safeSetColorA(int r,int g,int b,int a);
 
 
-/**
- * We've encountered many problems when attempting to create delays for triggering
- * the logic function. As a result, we decided on using the timing libraries given
- * by <chrono> in the standard C++ library. This function simply returns the amount
- * of milliseconds that have passed since the epoch.
- */
-
+// use our own millis function if we can, windows doesn't like <chrono> at the moment...
 #ifdef __WIN32__
-#define millis()       SDL_GetTicks()
+#define millis() SDL_GetTicks()
 #else
 unsigned int millis(void);
 #endif // __WIN32__
 
+// reads the names of files in a directory into the given string vector
 int getdir(std::string dir, std::vector<std::string> &files);
+
+// sorts a vector of strings alphabetically
 void strVectorSortAlpha(std::vector<std::string> *v);
 
+// reads the given file into a buffer and returns a pointer to the buffer
 const char *readFile(const char *path);
 
-int strCreateFunc(const char *equ);
-
-template<typename N, size_t s>
-size_t arrAmt(N (&)[s]) {return s;}
-
+// aborts the program, printing the given error
 void UserError(std::string reason);
 
 #endif // COMMON_H
index 862020693731e6749e61ebf153f4ff9ba3f24b4b..f8780df01e65fe98fcdf6e35dbe6687373440cd5 100644 (file)
@@ -230,10 +230,7 @@ public:
        GENDER  gender;
 
        // a texture handler for the entity
-       Texturec *tex;
-
-       // TODO
-       Texturec *ntex;
+       TextureIterator tex;
 
        // draws the entity to the screen
        void draw(void);
index 99d2d848d5624da9f91a832f433e9c470d0cdfa9..59358f25bd790573d2460b00dd45eaf7661104b4 100644 (file)
@@ -36,6 +36,49 @@ namespace Texture {
        dim2 imageDim(std::string fileName);
 }
 
+/**
+ * DRAFT texture iterator?
+ */
+class TextureIterator {
+private:
+       std::vector<std::pair<GLuint, std::string>> textures;
+       std::vector<std::pair<GLuint, std::string>>::iterator position;
+public:
+       TextureIterator(void) {
+               position = std::begin(textures);
+       }
+       TextureIterator(const std::vector<std::string> &l) {
+               for (const auto &s : l)
+                       textures.emplace_back(Texture::loadTexture(s), s);
+               position = std::begin(textures);
+       }
+       void operator++(int) noexcept {
+               if (++position < std::end(textures))
+                       glBindTexture(GL_TEXTURE_2D, (*position).first);
+               else
+                       position = std::end(textures) - 1;
+       }
+       void operator--(int) noexcept {
+               if (--position >= std::begin(textures))
+                       glBindTexture(GL_TEXTURE_2D, (*position).first);
+               else
+                       position = std::begin(textures);
+       }
+       void operator()(const int &index) {
+               if (index < 0 || index > static_cast<int>(textures.size()))
+                       throw std::invalid_argument("texture index out of range");
+
+               position = std::begin(textures) + index;
+               glBindTexture(GL_TEXTURE_2D, (*position).first);
+       }
+       const std::string& getTexturePath(const int &index) {
+               if (index < 0 || index > static_cast<int>(textures.size()))
+                       throw std::invalid_argument("texture index out of range");
+
+               return textures[index].second;
+       }
+};
+
 /**
  * The Texturec class.
  *
index daf8ae4bee57b00231f6e98a61cf8c923890b531..0aea879149f488cce8a3773c67435cad368aa97c 100644 (file)
@@ -66,16 +66,18 @@ extern int worldShade;
 extern std::string currentXML;
 
 // defines how many game ticks it takes for a day to elapse
-extern const unsigned int DAY_CYCLE;
+constexpr const unsigned int DAY_CYCLE = 12000;
 
 // velocity of player when moved by user
-extern const float PLAYER_SPEED_CONSTANT;
+constexpr const float PLAYER_SPEED_CONSTANT = 0.15f;
 
 // maximum pull of gravity in one game tick
-extern const float GRAVITY_CONSTANT;
+constexpr const float GRAVITY_CONSTANT = 0.001f;
 
 // height of the floor in an indoor world
-extern const unsigned int INDOOR_FLOOR_HEIGHT;
+constexpr const unsigned int INDOOR_FLOOR_THICKNESS = 50;
+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
@@ -110,7 +112,7 @@ protected:
        int worldStart;
 
        // holds / handles textures for background elements
-       Texturec *bgTex;
+       TextureIterator bgTex;
 
        // defines what type of background is being used
        WorldBGType bgType;
index 26a027bc77fe199ac451d4f5183a3c159e5644b8..6de7c038fda49f7f80933cd508e55af5e53f55e9 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -22,6 +22,9 @@ using namespace tinyxml2;
 ** Variables section
 ** --------------------------------------------------------------------------*/
 
+// the game's window title name
+constexpr const char *GAME_NAME = "Independent Study v0.7 alpha - NOW WITH lights and snow and stuff";
+
 // the current weather, declared in world.cpp
 extern WorldWeather weather;
 
@@ -125,7 +128,7 @@ int main(int argc, char *argv[]){
                UserError(std::string("GLEW was not able to initialize! Error: ") + reinterpret_cast<const char *>(glewGetErrorString(err)));
 
        // start the random number generator
-       initRand(millis());
+       randInit(millis());
 
        // 'basic' OpenGL setup
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
@@ -196,7 +199,7 @@ int main(int argc, char *argv[]){
        strVectorSortAlpha(&xmlFiles);
 
        // load the first valid XML file for the world
-       for (xf : xmlFiles) {
+       for (const auto &xf : xmlFiles) {
                if (xf[0] != '.' && strcmp(&xf[xf.size() - 3], "dat")){
                        // read it in
                        std::cout << "File to load: " << xf << '\n';
diff --git a/setup.mk b/setup.mk
deleted file mode 100644 (file)
index 89bb9c3..0000000
--- a/setup.mk
+++ /dev/null
@@ -1,5 +0,0 @@
-# Target OS, can be either 'linux' or 'win32'
-TARGET_OS = linux
-
-# Bits setting, 32 or 64
-TARGET_BITS = 32
index c86454b60130487a8c941d324dd26e2efb67900a..3b9ead751b26205e462a3a0159952c472db13203 100644 (file)
@@ -3,6 +3,7 @@
 #include <cstring>
 #include <cstdio>
 #include <chrono>
+#include <fstream>
 
 #ifndef __WIN32__
 
index b9c1d0d8a4bfec83ae91c0372ee9617c8dfb2121..c90650e7d499e315c2bb365c34be03d136258938 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <istream>
 #include <sstream>
+#include <fstream>
 
 #include <ui.hpp>
 #include <world.hpp>
@@ -41,7 +42,7 @@ const char *randomDialog[RAND_DIALOG_COUNT] = {
        "What's a bagel? I don't know because I'm mormon"
 };
 
-void getRandomName(Entity *e)
+void randGetomName(Entity *e)
 {
        unsigned int tempNum,max=0;
        char *bufs;
@@ -105,7 +106,7 @@ void Entity::spawn(float x, float y)
        if (type == MOBT)
                name[0] = '\0';
        else
-               getRandomName(this);
+               randGetomName(this);
 }
 
 void Entity::takeHit(unsigned int _health, unsigned int cooldown)
@@ -163,21 +164,21 @@ Player::Player(){ //sets all of the player specific traits on object creation
        speed = 1;
        canMove = true;
 
-       tex = new Texturec(9,   "assets/player/playerk.png",
-                                                       "assets/player/playerk1.png",
-                                                       "assets/player/playerk2.png",
-                                                       "assets/player/playerk3.png",
-                                                       "assets/player/playerk4.png",
-                                                       "assets/player/playerk5.png",
-                                                       "assets/player/playerk6.png",
-                                                       "assets/player/playerk7.png",
-                                                       "assets/player/playerk8.png");
-                                                       
+       tex = TextureIterator({"assets/player/playerk.png",
+                                                  "assets/player/playerk1.png",
+                                                  "assets/player/playerk2.png",
+                                                  "assets/player/playerk3.png",
+                                                  "assets/player/playerk4.png",
+                                                  "assets/player/playerk5.png",
+                                                  "assets/player/playerk6.png",
+                                                  "assets/player/playerk7.png",
+                                                  "assets/player/playerk8.png"
+                                              });
+
        inv = new Inventory(PLAYER_INV_SIZE);
 }
 Player::~Player() {
        delete inv;
-       delete tex;
        delete[] name;
 }
 
@@ -193,7 +194,7 @@ NPC::NPC() {        //sets all of the NPC specific traits on object creation
        maxHealth = health = 100;
        canMove = true;
 
-       tex = new Texturec(1,"assets/NPC.png");
+       tex = TextureIterator({"assets/NPC.png"});
        inv = new Inventory(NPC_INV_SIZE);
 
        randDialog = rand() % RAND_DIALOG_COUNT - 1;
@@ -203,7 +204,6 @@ NPC::NPC() {        //sets all of the NPC specific traits on object creation
 NPC::~NPC()
 {
        delete inv;
-       delete tex;
        delete[] name;
 }
 
@@ -233,12 +233,8 @@ Merchant::Merchant() {     //sets all of the Merchant specific traits on object crea
 }
 
 Merchant::~Merchant() {
-       /*while(!aiFunc.empty()) {
-               aiFunc.pop_back();
-       }*/
        delete inside;
        //delete inv;
-       //delete tex;
        //delete[] name;
 }
 
@@ -254,8 +250,6 @@ Structures::Structures() { //sets the structure type
        canMove = false;
 }
 Structures::~Structures() {
-       delete tex;
-
        if (name)
                delete[] name;
 }
@@ -269,8 +263,7 @@ Object::Object() {
        canMove = false;
 
        maxHealth = health = 1;
-
-       tex = NULL;
+       
        inv = NULL;
 }
 
@@ -287,19 +280,15 @@ Object::Object(std::string in, std::string pd) {
        height = getItemHeight(in);
 
        maxHealth = health = 1;
-       tex = new Texturec(1,getItemTexturePath(in));
+       tex = TextureIterator({getItemTexturePath(in)});
        inv = NULL;
 }
 Object::~Object() {
-       delete tex;
        delete[] name;
 }
 
 void Object::reloadTexture(void) {
-       if (tex)
-               delete tex;
-
-       tex = new Texturec(1,getItemTexturePath(iname));
+       tex = TextureIterator({getItemTexturePath(iname)});
        width  = getItemWidth(iname);
        height = getItemHeight(iname);
 }
@@ -352,17 +341,17 @@ void Entity::draw(void)
                if (speed && !(game::time::getTickCount() % ((2.0f/speed) < 1 ? 1 : (int)((float)2.0f/(float)speed)))) {
                        if (++texState==9)texState=1;
                        glActiveTexture(GL_TEXTURE0);
-                       tex->bind(texState);
+                       tex(texState);
                }
                if (!ground) {
                        glActiveTexture(GL_TEXTURE0 + 0);
-                       tex->bind(0);
+                       tex(0);
                }else if (vel.x) {
                        glActiveTexture(GL_TEXTURE0 + 0);
-                       tex->bind(texState);
+                       tex(texState);
                }else{
                        glActiveTexture(GL_TEXTURE0 + 0);
-                       tex->bind(0);
+                       tex(0);
                }
                break;
        case MOBT:
@@ -373,7 +362,7 @@ void Entity::draw(void)
                /* fall through */
        default:
                glActiveTexture(GL_TEXTURE0);
-               tex->bind(0);
+               tex(0);
                break;
        }
 
@@ -429,7 +418,7 @@ wander(int timeRun)
                ticksToUse = timeRun;
 
                vel.x = HLINES(0.008);
-               direction = (getRand() % 3 - 1);
+               direction = (randGet() % 3 - 1);
 
                if (direction == 0)
                        ticksToUse *= 2;
@@ -622,7 +611,7 @@ void Merchant::wander(int timeRun) {
                ticksToUse = timeRun;
 
                vel.x = HLINES(0.008);
-               direction = (getRand() % 3 - 1);
+               direction = (randGet() % 3 - 1);
 
                if (direction == 0)
                        ticksToUse *= 2;
@@ -745,20 +734,20 @@ unsigned int Structures::spawn(BUILD_SUB sub, float x, float y) {
         *      will spawn bewteen 2 and 7 villagers for the starting hut.
        */
 
-       //unsigned int tempN = (getRand() % 5 + 2);
+       //unsigned int tempN = (randGet() % 5 + 2);
 
        if (textureLoc.empty())
                textureLoc = inWorld->getSTextureLocation(sub);
 
        switch(sub) {
                case STALL_MARKET:
-                       tex = new Texturec({ textureLoc });
+                       tex = TextureIterator({ textureLoc });
                        dim = Texture::imageDim(textureLoc);
                        width = dim.x;
                        height = dim.y;
                        break;
                default:
-                       tex = new Texturec({ textureLoc });
+                       tex = TextureIterator({ textureLoc });
                        dim = Texture::imageDim(textureLoc);
                        width = dim.x;
                        height = dim.y;
index 78502a78c4a0f0035786d1e55602c37c27f8dd2d..83c1f0ad882391f7c44e4a8bcbf141983ca31ca2 100644 (file)
@@ -1,4 +1,7 @@
 #include <inventory.hpp>
+
+#include <numeric>
+
 #include <entities.hpp>
 #include <ui.hpp>
 #include <gametime.hpp>
@@ -296,6 +299,11 @@ void Inventory::draw(void) {
                }
        } a = 0;
 
+       auto averagef = [](const std::vector<int> &v) {
+               auto sum = std::accumulate(std::begin(v), std::end(v), 0);
+               return sum / v.size();
+       };
+
        ui::fontTransInv = 255 * (averagef(dfp) / range);
        if (ui::fontTransInv > 255)
                ui::fontTransInv = 255;
index 220e948e622e19b7f25c1b732f0ec20883310267..e98a648632cfcb8ac3c6021d8540eeaeca918adb 100644 (file)
@@ -17,7 +17,7 @@ Page::Page(void) : Mob()
     maxHealth = health = 50;
     width = HLINES(6);
     height = HLINES(4);
-    tex = new Texturec({"assets/items/ITEM_PAGE.png"});
+    tex = TextureIterator({"assets/items/ITEM_PAGE.png"});
 }
 
 void Page::act(void)
@@ -35,7 +35,7 @@ void Page::act(void)
 bool Page::bindTex(void)
 {
     glActiveTexture(GL_TEXTURE0);
-    tex->bind(0);
+    tex(0);
     return true;
 }
 
@@ -54,7 +54,7 @@ Door::Door(void) : Mob()
     maxHealth = health = 50;
     width = HLINES(12);
     height = HLINES(20);
-    tex = new Texturec({"assets/door.png"});
+    tex = TextureIterator({"assets/door.png"});
 }
 
 void Door::act(void)
@@ -64,7 +64,7 @@ void Door::act(void)
 bool Door::bindTex(void)
 {
     glActiveTexture(GL_TEXTURE0);
-    tex->bind(0);
+    tex(0);
     return true;
 }
 
@@ -82,7 +82,7 @@ Cat::Cat(void) : Mob()
     maxHealth = health = 1000;
     width  = HLINES(19);
     height = HLINES(15);
-    tex = new Texturec({"assets/cat.png"});
+    tex = TextureIterator({"assets/cat.png"});
     actCounterInitial = 0;
     actCounter = 1;
 }
@@ -116,7 +116,7 @@ void Cat::act(void)
 bool Cat::bindTex(void)
 {
     glActiveTexture(GL_TEXTURE0);
-    tex->bind(0);
+    tex(0);
     return true;
 }
 
@@ -134,8 +134,8 @@ Rabbit::Rabbit(void) : Mob()
     maxHealth = health = 50;
     width  = HLINES(10);
     height = HLINES(8);
-    tex = new Texturec({"assets/rabbit.png", "assets/rabbit1.png"});
-    actCounterInitial = getRand() % 240 + 15;
+    tex = TextureIterator({"assets/rabbit.png", "assets/rabbit1.png"});
+    actCounterInitial = randGet() % 240 + 15;
     actCounter = 1;
 }
 
@@ -145,7 +145,7 @@ void Rabbit::act(void)
     static int direction = 0;
     if (!--actCounter) {
         actCounter = actCounterInitial;
-        direction = (getRand() % 3 - 1);       //sets the direction to either -1, 0, 1
+        direction = (randGet() % 3 - 1);       //sets the direction to either -1, 0, 1
         if (direction == 0)
             ticksToUse /= 2;
         vel.x *= direction;
@@ -165,7 +165,7 @@ void Rabbit::act(void)
 bool Rabbit::bindTex(void)
 {
     glActiveTexture(GL_TEXTURE0);
-    tex->bind(!ground);
+    tex(!ground);
     return true;
 }
 
@@ -187,7 +187,7 @@ Bird::Bird(void) : Mob()
     maxHealth = health = 50;
     width = HLINES(8);
     height = HLINES(8);
-    tex = new Texturec({"assets/robin.png"});
+    tex = TextureIterator({"assets/robin.png"});
     actCounterInitial = actCounter = 200;
 }
 
@@ -208,7 +208,7 @@ void Bird::act(void)
 bool Bird::bindTex(void)
 {
     glActiveTexture(GL_TEXTURE0);
-    tex->bind(0);
+    tex(0);
     return true;
 }
 
@@ -232,7 +232,7 @@ Trigger::Trigger(void) : Mob()
     maxHealth = health = 50;
     width = HLINES(20);
     height = 2000;
-    tex = new Texturec(0);
+    //tex = TextureIterator();
     triggered = false;
 }
 
@@ -294,7 +294,6 @@ void Trigger::createFromXML(const XMLElement *e)
 Mob::~Mob()
 {
        delete inv;
-       delete tex;
        delete[] name;
 }
 
index 5d6e7c1810b5b2623ebc5537ef34043a7bdb54bd..a7c2fdfc278ec59a6da87b87626e4e769f2b42ae 100644 (file)
@@ -7,6 +7,7 @@
 // standard library headers
 #include <algorithm>
 #include <sstream>
+#include <fstream>
 
 // local game headers
 #include <ui.hpp>
@@ -29,26 +30,16 @@ extern bool         inBattle;               // ui.cpp?
 extern std::string  xmlFolder;
 
 // externally referenced in main.cpp
-const unsigned int DAY_CYCLE = 12000;
 int worldShade = 0;
 
-// externally referenced in entities.cpp
-const float PLAYER_SPEED_CONSTANT = 0.150f;
-const float GRAVITY_CONSTANT      = 0.001f;
-
 // ground-generating constants
-static const float GROUND_HEIGHT_INITIAL =  80.0f;
-static const float GROUND_HEIGHT_MINIMUM =  60.0f;
-static const float GROUND_HEIGHT_MAXIMUM = 110.0f;
-static const float GROUND_HILLINESS      =  10.0f;
+constexpr const float GROUND_HEIGHT_INITIAL =  80.0f;
+constexpr const float GROUND_HEIGHT_MINIMUM =  60.0f;
+constexpr const float GROUND_HEIGHT_MAXIMUM = 110.0f;
+constexpr const float GROUND_HILLINESS      =  10.0f;
 
 // defines grass height in HLINEs
-static const unsigned int GRASS_HEIGHT = 4;
-
-// indoor world constants
-static const unsigned int INDOOR_FLOOR_THICKNESS = 50;
-static const unsigned int INDOOR_FLOOR_HEIGHTT = 400;
-const unsigned int INDOOR_FLOOR_HEIGHT = INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS;
+constexpr const unsigned int GRASS_HEIGHT = 4;
 
 // the path of the currently loaded XML file, externally referenced in places
 std::string currentXML;
@@ -63,7 +54,7 @@ static std::vector<std::string> inside;
 static std::vector<WorldSwitchInfo> arenaNest;
 
 // pathnames of images for world themes
-static const unsigned int BG_PATHS_ENTRY_SIZE = 9;
+constexpr const unsigned int BG_PATHS_ENTRY_SIZE = 9;
 static const std::string bgPaths[][BG_PATHS_ENTRY_SIZE] = {
     {"bg.png",                                 // Daytime background
      "bgn.png",                                        // Nighttime background
@@ -108,11 +99,6 @@ static const float bgDraw[4][3]={
 ** Functions section
 ** --------------------------------------------------------------------------*/
 
-// externs
-extern int  commonAIFunc(NPC *);               // gameplay.cpp
-extern void commonTriggerFunc(Mob *);  // gameplay.cpp
-extern void commonPageFunc(Mob *);             // gameplay.cpp
-
 /**
  * Creates a world object.
  * Note that all this does is nullify a pointer...
@@ -135,7 +121,6 @@ World::
        if (bgmObj != nullptr)
                Mix_FreeMusic(bgmObj);
 
-       delete bgTex;
        deleteEntities();
 }
 
@@ -144,27 +129,27 @@ World::
  * This function will free all memory used by all entities, and then empty the
  * vectors they were stored in.
  */
+template<class T>
+void clearPointerVector(T &vec)
+{
+    while (!vec.empty()) {
+        delete vec.back();
+        vec.pop_back();
+     }
+}
+
 void World::
 deleteEntities(void)
 {
     // free mobs
-    while (!mob.empty()) {
-               delete mob.back();
-               mob.pop_back();
-       }
+    clearPointerVector(mob);
 
     // free npcs
        merchant.clear(); // TODO
-       while (!npc.empty()) {
-               delete npc.back();
-               npc.pop_back();
-       }
+    clearPointerVector(npc);
 
     // free structures
-       while (!build.empty()) {
-               delete build.back();
-               build.pop_back();
-       }
+    clearPointerVector(build);
 
     // free objects
        object.clear();
@@ -202,7 +187,7 @@ generate(int width)
 
     // give every GROUND_HILLINESSth entry a groundHeight value
     for (; wditer < std::end(worldData); wditer += GROUND_HILLINESS)
-        (*(wditer - GROUND_HILLINESS)).groundHeight = (*wditer).groundHeight + (getRand() % 8 - 4);
+        (*(wditer - GROUND_HILLINESS)).groundHeight = (*wditer).groundHeight + (randGet() % 8 - 4);
 
     // create slopes from the points that were just defined, populate the rest of the WorldData structure
     for (wditer = std::begin(worldData) + 1; wditer < std::end(worldData); wditer++){
@@ -212,10 +197,10 @@ generate(int width)
             geninc = ((w + static_cast<int>(GROUND_HILLINESS))->groundHeight - w->groundHeight) / GROUND_HILLINESS;
 
         w->groundHeight   = fmin(fmax((w - 1)->groundHeight + geninc, GROUND_HEIGHT_MINIMUM), GROUND_HEIGHT_MAXIMUM);
-        w->groundColor    = getRand() % 32 / 8;
+        w->groundColor    = randGet() % 32 / 8;
         w->grassUnpressed = true;
-        w->grassHeight[0] = (getRand() % 16) / 3 + 2;
-        w->grassHeight[1] = (getRand() % 16) / 3 + 2;
+        w->grassHeight[0] = (randGet() % 16) / 3 + 2;
+        w->grassHeight[1] = (randGet() % 16) / 3 + 2;
     }
 
     // define x-coordinate of world's leftmost 'line'
@@ -224,8 +209,8 @@ generate(int width)
     // create empty star array, should be filled here as well...
        star = std::vector<vec2> (100, vec2 { 0, 400 });
        for (auto &s : star) {
-               s.x = (getRand() % (-worldStart * 2)) + worldStart;
-               s.y = (getRand() % game::SCREEN_HEIGHT) + 100;
+               s.x = (randGet() % (-worldStart * 2)) + worldStart;
+               s.y = (randGet() % game::SCREEN_HEIGHT) + 100;
        }
 }
 
@@ -270,7 +255,7 @@ draw(Player *p)
        glEnable(GL_TEXTURE_2D);
 
        // the sunny wallpaper is faded with the night depending on tickCount
-       bgTex->bind(0);
+       bgTex(0);
     switch (weather) {
     case WorldWeather::Snowy:
         alpha = 150;
@@ -291,7 +276,7 @@ draw(Player *p)
                glTexCoord2i(0, 1); glVertex2i(offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y);
        glEnd();
 
-       bgTex->bindNext();
+       bgTex++;
        safeSetColorA(255, 255, 255, !alpha ? 255 : worldShade * 4);
        glBegin(GL_QUADS);
         glTexCoord2i(0, 0); glVertex2i(offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y);
@@ -304,7 +289,7 @@ draw(Player *p)
 
        // draw the stars if the time deems it appropriate
        if (worldShade > 0) {
-               safeSetColorA(255, 255, 255, 255 - (getRand() % 30 - 15));
+               safeSetColorA(255, 255, 255, 255 - (randGet() % 30 - 15));
 
         auto xcoord = offset.x * 0.9f;
                for (auto &s : star)
@@ -314,7 +299,7 @@ draw(Player *p)
        // draw remaining background items
        glEnable(GL_TEXTURE_2D);
 
-       bgTex->bindNext();
+       bgTex++;
        safeSetColorA(150 + shadeBackground * 2, 150 + shadeBackground * 2, 150 + shadeBackground * 2, 255);
        glBegin(GL_QUADS); {
         auto xcoord = width / 2 * -1 + offset.x * 0.85f;
@@ -327,7 +312,7 @@ draw(Player *p)
        } glEnd();
 
        for (unsigned int i = 0; i < 4; i++) {
-               bgTex->bindNext();
+               bgTex++;
                safeSetColorA(bgDraw[i][0] + shadeBackground * 2,
                       bgDraw[i][0] + shadeBackground * 2,
                       bgDraw[i][0] + shadeBackground * 2,
@@ -392,7 +377,7 @@ draw(Player *p)
     // draw light elements
     glEnable(GL_TEXTURE_2D);
     glActiveTexture(GL_TEXTURE0);
-    bgTex->bindNext();
+    bgTex++;
 
     std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size()));
        auto pointArray = pointArrayBuf.get();
@@ -408,8 +393,9 @@ draw(Player *p)
         }
        }
 
-    for (unsigned int i = 0; i < light.size(); i++)
+    for (unsigned int i = 0; i < light.size(); i++) {
         flameArray[i] = light[i].fireFlicker;
+    }
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@@ -463,7 +449,7 @@ draw(Player *p)
        // draw the grass
        glEnable(GL_TEXTURE_2D);
        glActiveTexture(GL_TEXTURE0);
-       bgTex->bindNext();
+       bgTex++;
        glUseProgram(shaderProgram);
        glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
     safeSetColorA(255, 255, 255, 255);
@@ -756,7 +742,7 @@ update(Player *p, unsigned int delta)
                        (*part).loc.y += pa.vel.y * delta;
                        (*part).loc.x += pa.vel.x * delta;
 
-            if (std::any_of(std::begin(build), std::end(build), [pa](Structures *s) {
+            if (std::any_of(std::begin(build), std::end(build), [pa](const Structures *s) {
                     return (s->bsubtype == FOUNTAIN) &&
                            (pa.loc.x >= s->loc.x) && (pa.loc.x <= s->loc.x + s->width) &&
                            (pa.loc.y <= s->loc.y + s->height * 0.25f);
@@ -981,10 +967,10 @@ setBackground(WorldBGType bgt)
     // load textures with a limit check
        switch ((bgType = bgt)) {
        case WorldBGType::Forest:
-               bgTex = new Texturec(bgFiles);
+               bgTex = TextureIterator(bgFiles);
                break;
        case WorldBGType::WoodHouse:
-               bgTex = new Texturec(bgFilesIndoors);
+               bgTex = TextureIterator(bgFilesIndoors);
                break;
     default:
         UserError("Invalid world background type");
@@ -1003,14 +989,14 @@ setStyle(std::string pre)
     // get folder prefix
        std::string prefix = pre.empty() ? "assets/style/classic/" : pre;
 
-    for (s : buildPaths)
+    for (const auto &s : buildPaths)
         sTexLoc.push_back(prefix + s);
 
     prefix += "bg/";
 
-    for (s : bgPaths[0])
+    for (const auto &s : bgPaths[0])
         bgFiles.push_back(prefix + s);
-    for (s : bgPaths[1])
+    for (const auto &s : bgPaths[1])
         bgFilesIndoors.push_back(prefix + s);
 }
 
@@ -1192,8 +1178,9 @@ addMerchant(float x, float y, bool housed)
        merchant.push_back(new Merchant());
        merchant.back()->spawn(x, y);
 
-    if (housed)
+    if (housed) {
         merchant.back()->inside = build.back();
+    }
 
        npc.push_back(merchant.back());
        entity.push_back(npc.back());
@@ -1228,14 +1215,13 @@ void World::
 addLight(vec2 loc, Color color)
 {
        if (light.size() < 64)
-        light.push_back(Light(loc, color, 1));
+        light.emplace_back(loc, color, 1);
 }
 
 void World::
 addHole(unsigned int start, unsigned int end)
 {
-    if (end > worldData.size())
-        end = worldData.size();
+    end = fmin(worldData.size(), end);
 
        for (unsigned int i = start; i < end; i++)
                worldData[i].groundHeight = 0;
@@ -1255,8 +1241,7 @@ addHill(const ivec2 peak, const unsigned int width)
         start = 0;
     }
 
-       if (end > (signed)worldData.size())
-         end = worldData.size();
+    end = fmin(worldData.size(), end);
 
        for (int i = start; i < end; i++) {
                worldData[i].groundHeight += thing * sin((i - start + offset) * period);
@@ -1269,8 +1254,6 @@ IndoorWorld::IndoorWorld(void) {
 }
 
 IndoorWorld::~IndoorWorld(void) {
-       delete bgTex;
-
        deleteEntities();
 }
 
@@ -1279,7 +1262,8 @@ addFloor(unsigned int width)
 {
     if (floor.empty())
         generate(width);
-    floor.emplace_back(width, floor.size() * INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS);
+
+    floor.emplace_back(width, floor.size() * INDOOR_FLOOR_HEIGHT);
     fstart.push_back(0);
 }
 
@@ -1289,7 +1273,8 @@ addFloor(unsigned int width, unsigned int start)
 {
     if (floor.empty())
         generate(width);
-    floor.emplace_back(width, floor.size() * INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS);
+
+    floor.emplace_back(width, floor.size() * INDOOR_FLOOR_HEIGHT);
     fstart.push_back(start);
 }
 
@@ -1402,8 +1387,9 @@ draw(Player *p)
         }
        }
 
-    for(i = 0; i < light.size(); i++)
+    for(i = 0; i < light.size(); i++) {
         flameArray[i] = light[i].fireFlicker;
+    }
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@@ -1421,7 +1407,7 @@ draw(Player *p)
         glUniform1fv(glGetUniformLocation(shaderProgram, "fireFlicker"), light.size(), flameArray);
        }
 
-       bgTex->bind(0);
+       bgTex(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);
@@ -1445,7 +1431,7 @@ draw(Player *p)
         safeSetColor(150, 100, 50);
         for (f = 0; f < floor.size(); f++) {
             i = 0;
-               for (h : floor[f]) {
+               for (const auto &h : floor[f]) {
                        x = worldStart + fstart[f] * HLINE + HLINES(i);
                        glVertex2i(x        , h            );
                        glVertex2i(x + HLINE, h            );
@@ -1724,7 +1710,7 @@ loadWorldFromXMLNoSave(std::string path) {
         else if (name == "structure") {
                        tmp->addStructure((BUILD_SUB) wxml->UnsignedAttribute("type"),
                                                           wxml->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
-                                                              getRand() % tmp->getTheWidth() / 2.0f : spawnx,
+                                                              randGet() % tmp->getTheWidth() / 2.0f : spawnx,
                                                           100,
                                                           wxml->StrAttribute("texture"),
                                                           wxml->StrAttribute("inside")