]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
vector2 stuff, other things
authorClyne Sullivan <tullivan99@gmail.com>
Fri, 13 Jan 2017 15:42:55 +0000 (10:42 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Fri, 13 Jan 2017 15:42:55 +0000 (10:42 -0500)
24 files changed:
Makefile
include/common.hpp
include/render.hpp
include/texture.hpp
include/vector2.hpp [new file with mode: 0644]
include/world.hpp
main.cpp
src/components.cpp
src/entities.cpp.bak [deleted file]
src/gametime.cpp
src/inventory.cpp
src/inventory.cpp.bak [deleted file]
src/items.cpp.bak [deleted file]
src/mob.cpp.bak [deleted file]
src/old/entities.cpp.bak [new file with mode: 0644]
src/old/inventory.cpp.bak [new file with mode: 0644]
src/old/items.cpp.bak [new file with mode: 0644]
src/old/mob.cpp.bak [new file with mode: 0644]
src/old/quest.cpp.bak [new file with mode: 0644]
src/quest.cpp.bak [deleted file]
src/texture.cpp
src/ui.cpp
src/world.cpp
xml/!town.xml

index f8d751131a94c9a40f810b3c62d352ac811bbc4e..471a11a3635cef0562f8e2002bbda68bd1bbccea 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ endif
 
 CXXFLAGS = -ggdb -m$(TARGET_BITS) -std=c++14 -fext-numeric-literals
 CXXINC   = -Iinclude -Iinclude/freetype -I.
-CXXWARN  = -Wall -Wextra #-Werror -pedantic
+CXXWARN  = -Wall -Wextra -Werror -pedantic
 
 CXXSRCDIR = src
 CXXOUTDIR = out
@@ -56,4 +56,4 @@ $(CXXOUTDIR)/%.o: $(CXXSRCDIR)/%.cpp
 
 $(CXXOUTDIR)/%.o: $(CXXSRCDIR)/%.cc
        @echo "  CXX    " $<
-       @$(CXX) $(CXXFLAGS) $(CXXINC) $(CXXWARN) $(LIBS) -c $< -o $@
\ No newline at end of file
+       @$(CXX) $(CXXFLAGS) $(CXXINC) $(CXXWARN) $(LIBS) -c $< -o $@
index abfd28bbb805ef27fb2c6e2f18adfa9464c212b2..12444647b10504375e8ad2c6d02bb852de2dd737 100644 (file)
@@ -55,73 +55,10 @@ using uint = unsigned int;
 
 #define coalesce(v1, v2) ((v1 != nullptr) ? v1 : v2)
 
-/**
- * Creates a coordinate of integers.
- */
-typedef struct {
-       int x; /**< The x coordinate */
-       int y; /**< The y coordinate */
-} ivec2;
+#include <vector2.hpp>
 
-/**
- * A pair of x and y for dimensions (i.e. width and height).
- */
-typedef ivec2 dim2;
-
-/**
- * Creates a coordinate out of floating point integers.
- */
-struct vec2 {
-       float x;
-       float y;
-
-       vec2(float _x = 0.0f, float _y = 0.0f)
-               : x(_x), y(_y) {}
-
-       bool operator==(const vec2 &v) const {
-               return (x == v.x) && (y == v.y);
-       }
-
-       template<typename T>
-       const vec2 operator=(const T &n) {
-               x = y = n;
-               return *this;
-       }
-
-       template<typename T>
-       vec2 operator+(T n) const {
-               return vec2 (x + n, y + n);
-       }
-
-       vec2 operator+(const vec2 &v) {
-               return vec2 (x + v.x, y + v.y);
-       }
-
-       vec2 operator*(const float&n) const {
-               return vec2 (x * n, y * n);
-       }
-
-       vec2 operator/(const float& n) const {
-               return vec2 (x / n, y / n);
-       }
-
-       // std::swap can't work due to being packed
-
-       inline void swapX(vec2 &v) {
-               float t = x;
-               x = v.x, v.x = t;
-       }
-
-       inline void swapY(vec2 &v) {
-               float t = y;
-               y = v.y, v.y = t;
-       }
-
-       std::string toString(void) const {
-               return "(" + std::to_string(x) + ", " + std::to_string(y) + ")";
-       }
-
-} __attribute__ ((packed));
+using vec2 = vector2<float>;
+using dim2 = vector2<int>;
 
 /**
  * A structure for three-dimensional points.
@@ -133,8 +70,7 @@ struct vec3 {
 
        vec3(float _x = 0.0f, float _y = 0.0f, float _z = 1.0f)
                : x(_x), y(_y), z(_z) {}
-
-} __attribute__ ((packed));
+};
 
 /**
  * This structure contains two sets of coordinates for ray drawing.
@@ -155,35 +91,15 @@ public:
        float blue;  /**< The amount of blue */
        float alpha; /**< Transparency */
 
-    Color() {
-               red = green = blue = alpha = 0.0f;
-       }
+       Color(float r = 0, float g = 0, float b = 0, float a = 255)
+               : red(r), green(g), blue(b), alpha(a) {}
 
-       Color(float r, float g ,float b) {
-               red = r;
-               green = g;
-               blue = b;
-        alpha = 255;
+       Color operator-(const float& a) {
+               return Color(red - a, green - a, blue - a, alpha);
        }
 
-    Color(float r, float g, float b, float a) {
-        red = r;
-        green = g;
-        blue = b;
-        alpha = a;
-    }
-
-       Color operator-=(float a) {
-               red -= a;
-               green -= a;
-               blue -= a;
-               return{red+a,green+a,blue+a};
-       }
-       Color operator+=(float a) {
-               return{red+a,green+a,blue+a};
-       }
-       Color operator=(float a) {
-               return{red=a,green=a,blue=a};
+       Color operator+(const float& a) {
+               return Color(red + a, green + a, blue + a, alpha);
        }
 };
 
@@ -206,14 +122,6 @@ constexpr float MSEC_PER_TICK = 1000.0f / TICKS_PER_SEC;
  */
 std::vector<std::string> StringTokenizer(const std::string& str, char delim);
 
-/**
- * Seperates a string like, "23,12" to a vec2.
- * 
- * @param s the string to parse
- * @return the vec2 of the values passed in the string
- */
-vec2 str2coord(std::string s);
-
 /**
  * Returns a measurement in HLINEs
  *
index cf58519e44822e3acbc4240f775af2a4ec4d0948..997d7d0f67306c490413622fca1d67bfb2110421 100644 (file)
@@ -69,8 +69,6 @@ namespace Render {
     extern Shader worldShader;
     extern Shader textShader;
 
-    void initShaders(void);
-
     void useShader(Shader *s);
 
     void drawRect(vec2 ll, vec2 ur, float z);
index 3cb8d1fa5b39bac83b1686b1b0ccf7e507411962..43db1b6fc3d1332e25f91bb2611b1166eeb05488 100644 (file)
@@ -93,6 +93,8 @@ namespace Colors {
        extern ColorTex red;   /**< A solid red texture. */
        extern ColorTex blue;  /**< A solid blue texture. */
 
+       extern GLfloat texCoord[12];
+
        /**
         * Creates the colors.
         */
diff --git a/include/vector2.hpp b/include/vector2.hpp
new file mode 100644 (file)
index 0000000..debaee9
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef VECTOR2_HPP_
+#define VECTOR2_HPP_
+
+#include <string>
+#include <type_traits>
+
+template<typename T>
+struct vector2 {
+       static_assert(std::is_arithmetic<T>::value, "vector2 members must be an arithmetic type (i.e. numbers)");
+
+       T x, y;
+
+       vector2(T _x = 0, T _y = 0)
+               : x(_x), y(_y) {}
+
+       // format: "3, 5"
+       vector2(const std::string& s) {
+               *this = s;
+       }
+
+       vector2<T>& operator=(const T& value) {
+               x = y = value;
+               return *this;
+       }
+
+       vector2<T>& operator=(const std::string& s) {
+               auto comma = s.find(',');
+               x = std::stoi(s.substr(0, comma));
+               y = std::stoi(s.substr(comma + 1));
+               return *this;
+       }
+
+       // addition
+       vector2<T> operator+(const vector2<T>& v) const {
+               return vector2<T>(x + v.x, y + v.y);
+       }
+
+       vector2<T> operator+(const T& n) const {
+               return vector2<T>(x + n, y + n);
+       }
+
+       // subtraction
+       vector2<T> operator-(const vector2<T>& v) const {
+               return vector2<T>(x - v.x, y - v.y);
+       }
+
+       vector2<T> operator-(const T& n) const {
+               return vector2<T>(x - n, y - n);
+       }
+
+       // multiplication
+       vector2<T> operator*(const vector2<T>& v) const {
+               return vector2<T>(x * v.x, y * v.y);
+       }
+
+       vector2<T> operator*(const T& n) const {
+               return vector2<T>(x * n, y * n);
+       }
+
+       // division
+       vector2<T> operator/(const vector2<T>& v) const {
+               return vector2<T>(x / v.x, y / v.y);
+       }
+
+       vector2<T> operator/(const T& n) const {
+               return vector2<T>(x / n, y / n);
+       }
+
+       // compare
+       bool operator==(const vector2<T>& v) const {
+               return (x == v.x) && (y == v.y);
+       }
+
+       // other functions
+       std::string toString(void) const {
+               return "(" + std::to_string(x) + ", " + std::to_string(y) + ")";
+       }
+};
+
+#endif // VECTOR2_HPP_
index 14c64d04c354b0d89124b81c523ff114a8ca811c..9b683148cea99ff0878ab5b4c0f5644e70ac54e0 100644 (file)
@@ -37,7 +37,7 @@ struct WorldData {
     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 */
-} __attribute__ ((packed));
+};
 
 /**
  * Defines how many game ticks it takes to go from day to night or vice versa.
@@ -171,8 +171,8 @@ public:
        WorldData2 worldData;
 
        void generate(int width = 0);
-       void addHole(const unsigned int& start, const unsigned int& end);
-       void addHill(const ivec2& peak, const unsigned int& width);
+       //void addHole(const unsigned int& start, const unsigned int& end);
+       //void addHill(const ivec2& peak, const unsigned int& width);
 
        bool save(void);
        void load(const std::string& file);
index 40a84977f82eb5fca551115b4780d99150f696c4..2e5e69dd0e7c0359cedd5f57369c98d64e281fc2 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
 
        // read in all XML file names in the folder
        std::list<std::string> xmlFiles;
-       if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles))
+       if (getdir(std::string("./" + xmlFolder), xmlFiles))
                UserError("Error reading XML files!!!");
 
        // kill the world if needed
index 28a81fe30cc9ead3e558ae3d8966543bff719e0e..b758cb6af85af8d2559802e95990c0c38305cf74 100644 (file)
@@ -306,12 +306,12 @@ std::vector<Frame> developFrame(XMLElement* xml)
                                std::string sname = sxml->Name();
                                if (sname == "src") {
                                        foffset = (sxml->Attribute("offset") != nullptr) ? 
-                                               str2coord(sxml->Attribute("offset")) : vec2(0,0);
+                                               sxml->StrAttribute("offset") : vec2(0,0);
                                        fdraw = (sxml->Attribute("drawOffset") != nullptr) ?
-                                               str2coord(sxml->Attribute("drawOffset")) : vec2(0,0);
+                                               sxml->StrAttribute("drawOffset") : vec2(0,0);
 
                                        if (sxml->Attribute("size") != nullptr) {
-                                               fsize = str2coord(sxml->Attribute("size"));
+                                               fsize = sxml->Attribute("size");
                                                tmpf.push_back(std::make_pair(SpriteData(sxml->GetText(), foffset, fsize), fdraw));
                                        } else {
                                                tmpf.push_back(std::make_pair(SpriteData(sxml->GetText(), foffset), fdraw));
diff --git a/src/entities.cpp.bak b/src/entities.cpp.bak
deleted file mode 100644 (file)
index 25dd379..0000000
+++ /dev/null
@@ -1,1371 +0,0 @@
-#include <entities.hpp>
-
-#include <istream>
-#include <sstream>
-#include <fstream>
-
-#include <ui.hpp>
-#include <world.hpp>
-#include <gametime.hpp>
-#include <brice.hpp>
-
-#include <render.hpp>
-#include <engine.hpp>
-
-///NEW
-#include <components.hpp>
-#include <entityx/entityx.h>
-///OLD
-
-extern std::istream *names;
-
-extern Player *player;                 // main.cpp
-extern World *currentWorld;            // main.cpp
-extern unsigned int loops;             // main.cpp
-
-extern std::string xmlFolder;
-extern XMLDocument currentXMLDoc;
-
-// a dynamic array of pointers to the NPC's that are being assigned the preloads
-std::vector<NPC *> aipreload;
-
-// the size of the player's inventory
-const unsigned int PLAYER_INV_SIZE = 43;
-// the size of an NPC's inventory
-const unsigned int NPC_INV_SIZE = 3;
-
-static std::vector<std::string> randomDialog (readFileA("assets/dialog_en-us"));
-
-
-void PlayerSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
-{
-       (void)en;
-       (void)ev;
-       (void)dt;
-
-       if (!m_MoveLeft && !m_MoveRight)
-               (*m_Player)->vel.x = 0;
-}
-
-void PlayerSystem::configure(entityx::EventManager &ev)
-{
-       ev.subscribe<KeyDownEvent>(*this);
-       ev.subscribe<KeyUpEvent>(*this);
-}
-
-extern World  *currentWorldToLeft;
-extern World  *currentWorldToRight;
-extern bool gameRunning;
-extern bool inBattle;
-
-void PlayerSystem::receive(const KeyUpEvent &kue)
-{
-       auto p = *m_Player;
-       auto kc = kue.keycode;
-
-       if (kc == SDLK_ESCAPE) {
-               ui::menu::toggle();
-               p->save();
-       } else if (kc == getControl(1)) {
-               m_MoveLeft = false;
-       } else if (kc == getControl(2)) {
-               m_MoveRight = false;
-       } else if (kc == getControl(3) || kc == getControl(4)) {
-               player->speed = 1;
-       } else if (kc == getControl(5)) {
-               if (p->inv->invHover) {
-                       p->inv->invHover = false;
-               } else {
-                       if (!p->inv->selected)
-                               p->inv->invOpening ^= true;
-                       else
-                               p->inv->selected = false;
-
-                       p->inv->mouseSel = false;
-               }
-
-               // disable action ui
-               ui::action::disable();
-       }
-}
-
-void PlayerSystem::receive(const KeyDownEvent &kde)
-{
-       auto p = *m_Player;
-       auto kc = kde.keycode;
-
-       auto worldSwitch = [&](const WorldSwitchInfo& wsi){
-               player->canMove = false;
-               ui::toggleBlackFast();
-               ui::waitForCover();
-               game::events.emit<BGMToggleEvent>(wsi.first->bgm, wsi.first);
-               std::tie(currentWorld, player->loc) = wsi; // using p causes segfault
-               game::engine.getSystem<WorldSystem>()->setWorld(currentWorld);
-               ui::toggleBlackFast();
-               ui::waitForUncover();
-               player->canMove = true; // using p causes segfault
-       };
-
-       if ((kc == SDLK_SPACE) && (game::canJump & p->ground)) {
-               p->loc.y += HLINES(2);
-               p->vel.y = .4;
-               p->ground = false;
-       }
-
-       if (!ui::dialogBoxExists || ui::dialogPassive) {
-               if (kc == getControl(0)) {
-                       if (inBattle) {
-                               std::thread([&](void){
-                                       auto thing = dynamic_cast<Arena *>(currentWorld)->exitArena(p);
-                                       if (thing.first != currentWorld)
-                                               worldSwitch(thing);
-                               }).detach();
-                       } else if (!ui::fadeIntensity) {
-                               std::thread([&](void){
-                                       auto thing = currentWorld->goInsideStructure(p);
-                                       if (thing.first != currentWorld)
-                                               worldSwitch(thing);
-                               }).detach();
-                       }
-               } else if (kc == getControl(1)) {
-                       if (!ui::fadeEnable) {
-                               p->vel.x = -PLAYER_SPEED_CONSTANT;
-                               if (std::stoi(game::getValue("Slow")) == 1)
-                                       p->vel.x /= 2.0f;
-                               p->left = m_MoveLeft = true;
-                               p->right = m_MoveRight = false;
-                               if (currentWorldToLeft) {
-                                       std::thread([&](void){
-                                               auto thing = currentWorld->goWorldLeft(p);
-                                               if (thing.first != currentWorld)
-                                                       worldSwitch(thing);
-                                       }).detach();
-                               }
-                       }
-               } else if (kc == getControl(2)) {
-                       if (!ui::fadeEnable) {
-                               p->vel.x = PLAYER_SPEED_CONSTANT;
-                               if (std::stoi(game::getValue("Slow")) == 1)
-                                       p->vel.x /= 2.0f;
-                               p->right = m_MoveRight = true;
-                               p->left = m_MoveLeft = false;
-                               if (currentWorldToRight) {
-                                       std::thread([&](void){
-                                               auto thing = currentWorld->goWorldRight(p);
-                                               if (thing.first != currentWorld)
-                                                       worldSwitch(thing);
-                                       }).detach();
-                               }
-                       }
-               } else if (kc == getControl(3)) {
-                       if (game::canSprint)
-                               p->speed = 2.0f;
-               } else if (kc == getControl(4)) {
-                       p->speed = .5;
-               } else if (kc == getControl(5)) {
-                       /*static int heyOhLetsGo = 0;
-
-                       //edown = true;
-
-                       // start hover counter?
-                       if (!heyOhLetsGo) {
-                               heyOhLetsGo = game::time::getTickCount();
-                               p->inv->mouseSel = false;
-                       }
-
-                       // run hover thing
-                       if (game::time::getTickCount() - heyOhLetsGo >= 2 && !(p->inv->invOpen) && !(p->inv->selected)) {
-                               p->inv->invHover = true;
-
-                               // enable action ui
-                               ui::action::enable();
-                       }*/
-               }
-       } else if (kc == SDLK_DELETE) {
-               game::endGame();
-       } else if (kc == SDLK_t) {
-               game::time::tick(50);
-       }
-}
-
-
-void getRandomName(Entity *e)
-{
-       auto names = readFileA("assets/names_en-us");
-       auto name = names[randGet() % names.size()];
-
-       // gender is a binary construct
-       e->gender = (name[0] == 'm') ? MALE : FEMALE;
-
-       e->name = &name[1];
-}
-
-Entity::Entity(void)
-{
-       vel = 0;
-       width = 0;
-       height = 0;
-       health = 0;
-       maxHealth = 0;
-       outnabout = 0;
-       targetx = 0.9112001f;
-
-       type = UNKNOWNT;
-
-       // set flags
-       alive      = true;
-       right      = true;
-       left       = false;
-       near       = false;
-       canMove    = true;
-       ground     = false;
-       forcedMove = false;
-       z = 0.0f;
-
-       // clear counters
-       ticksToUse = 0;
-       hitCooldown = 0;
-
-       hitDuration = maxHitDuration = 0;
-
-       inv = nullptr;
-}
-
-// spawns the entity you pass to it based off of coords and global entity settings
-void Entity::spawn(float x, float y)
-{
-       loc.x = x;
-       loc.y = y;
-
-       if (health == 0 && maxHealth == 0)
-               health = maxHealth = 1;
-
-       // generate a name
-       if (type == MOBT)
-               name = "mob";
-       else
-               getRandomName(this);
-
-       setCooldown(0);
-}
-
-void Entity::takeHit(unsigned int _health, unsigned int cooldown)
-{
-       if (hitCooldown <= 1) {
-               // modify variables
-               health = fmax(health - _health, 0);
-               forcedMove = true;
-               hitCooldown = cooldown;
-
-               hitDuration = maxHitDuration = 350.0f;
-
-               // pushback
-               vel.x = player->left ? -0.5f : 0.5f;
-               vel.y = 0.2f;
-       }
-}
-
-unsigned int Entity::coolDown()
-{
-       return hitCooldown;
-}
-
-void Entity::setCooldown(unsigned int c)
-{
-       hitCooldown = c;
-}
-
-void Entity::handleHits(void)
-{
-       hitCooldown = fmax(static_cast<int>(hitCooldown - game::time::getDeltaTime()), 0);
-       hitDuration = fmax(hitDuration - game::time::getDeltaTime(), 0);
-
-       if (!forcedMove)
-               return;
-
-       // reduce knockback
-       if ((vel.x > 0.0005f) || (vel.x < -0.0005f))
-               vel.x *= 0.6f;
-       else
-               forcedMove = false;
-}
-
-void Entity::die(void)
-{
-       alive = false;
-       health = 0;
-
-       /*if (xmle) {
-               xmle->SetAttribute("alive", false);
-               currentXMLDoc.SaveFile(currentXML.c_str(), false);
-       }*/
-}
-
-bool Entity::isAlive(void) const
-{
-       return alive;
-}
-
-bool Entity::isHit(void) const
-{
-       return forcedMove;
-}
-
-void Entity::moveTo(float dest_x)
-{
-       targetx = dest_x;
-}
-
-Player::Player() : Entity()
-{
-       width = HLINES(10);
-       height = HLINES(16);
-
-       type = PLAYERT; //set type to player
-       subtype = 0;
-       health = maxHealth = 100;
-       speed = 1;
-       canMove = true;
-
-       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);
-       dim2 tmpDim = Texture::imageDim(tex.getTexturePath(0));
-       width = HLINES(tmpDim.x/2);
-       height = HLINES(tmpDim.y/2);
-
-       z = -2.0;
-}
-
-Player::~Player()
-{
-       delete inv;
-       delete &tex;
-}
-
-void Player::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)e;
-       (void)w;
-}
-
-void Player::saveToXML(void)
-{}
-
-NPC::NPC() : Entity()
-{
-       width = HLINES(10);
-       height = HLINES(16);
-
-       type    = NPCT; //sets type to npc
-       subtype = 0;
-
-       health = maxHealth = 100;
-
-       maxHealth = health = 100;
-       canMove = true;
-
-       tex = TextureIterator({"assets/NPC.png"});
-       inv = new Inventory(NPC_INV_SIZE);
-
-       randDialog = randGet() % randomDialog.size();
-       dialogIndex = 0;
-       dialogCount = 0;
-
-       dim2 tmpDim = Texture::imageDim(tex.getTexturePath(0));
-       width = HLINES(tmpDim.x/2);
-       height = HLINES(tmpDim.y/2);
-}
-
-NPC::~NPC()
-{
-       delete inv;
-}
-
-void NPC::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       std::string npcname;
-       bool dialog;
-       unsigned int flooor;
-
-       xmle = e;
-       (void)w;
-
-    // spawn at coordinates if desired
-       E_LOAD_COORDS(100);
-
-    // name override
-       if (!(npcname = e->StrAttribute("name")).empty())
-               name = npcname;
-
-    // dialog enabling
-       dialog = false;
-       if (e->QueryBoolAttribute("hasDialog", &dialog) == XML_NO_ERROR && dialog)
-               addAIFunc(false);
-       else
-        dialogIndex = 9999;
-
-    // custom health value
-       E_LOAD_HEALTH;
-
-       // movemenet
-       if (e->QueryBoolAttribute("canMove", &dialog) == XML_NO_ERROR)
-               canMove = dialog;
-
-       // dialog index
-       if (e->QueryUnsignedAttribute("dindex", &flooor) == XML_NO_ERROR)
-               dialogIndex = flooor;
-}
-
-void NPC::saveToXML(void)
-{
-       E_SAVE_HEALTH;
-       E_SAVE_COORDS;
-       xmle->SetAttribute("dindex", dialogIndex);
-}
-
-Merchant::Merchant() : NPC()
-{
-       width = HLINES(10);
-       height = HLINES(16);
-
-       type    = MERCHT; //sets type to merchant
-       subtype = 0;
-
-       health = maxHealth = 100;
-
-       canMove = true;
-
-       trade.reserve(100);
-       currTrade = 0;
-
-       inside = nullptr;
-
-       //tex = new Texturec(1,"assets/NPC.png");
-       //inv = new Inventory(NPC_INV_SIZE);
-       //inv = new Inventory(1);
-
-       //randDialog = rand() % RAND_DIALOG_COUNT - 1;
-       dialogIndex = 0;
-
-       dim2 tmpDim = Texture::imageDim(tex.getTexturePath(0));
-       width = HLINES(tmpDim.x/2);
-       height = HLINES(tmpDim.y/2);
-}
-
-Merchant::~Merchant()
-{
-}
-
-void Merchant::saveToXML(void){}
-
-Structures::Structures() : Entity()
-{
-       type = STRUCTURET;
-       canMove = false;
-       health = maxHealth = 1;
-}
-
-Structures::~Structures()
-{
-}
-
-extern std::string currentXMLRaw;
-
-void Structures::createFromXML(XMLElement *e, World *w)
-{
-       float spawnx;
-
-       if (e->QueryBoolAttribute("alive", &alive) == XML_NO_ERROR && !alive) {
-               //die();
-               return;
-       }
-
-       inWorld = w;
-       inside = e->StrAttribute("inside");
-
-       // edge
-       if (!inside.empty()) {
-               insideWorld = loadWorldFromXMLNoTakeover(inside);
-       }
-
-       textureLoc = e->StrAttribute("texture");
-
-       insideTex = Texture::loadTexture(e->StrAttribute("insideTexture"));
-
-       spawn(static_cast<BUILD_SUB>(e->UnsignedAttribute("type")),
-             e->QueryFloatAttribute("spawnx", &spawnx) == XML_NO_ERROR ? spawnx : (randGet() % w->getTheWidth() / 2.0f),
-             100);
-
-       xmle = e;
-}
-
-void Structures::saveToXML(void)
-{
-       xmle->SetAttribute("alive", alive);
-}
-
-Object::Object()
-{
-       type = OBJECTT;
-}
-
-Object::Object(std::string in, std::string pd)
-{
-       iname = in;
-
-       pickupDialog = pd;
-       questObject = !pd.empty();
-
-       type = OBJECTT;
-       width  = getItemWidth(in);
-       height = getItemHeight(in);
-
-       tex = TextureIterator({getItemTexturePath(in)});
-}
-
-Object::~Object()
-{
-}
-
-void Object::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)e;
-       (void)w;
-}
-
-void Object::saveToXML(void)
-{}
-
-void Object::reloadTexture(void)
-{
-       tex = TextureIterator({getItemTexturePath(iname)});
-       width  = getItemWidth(iname);
-       height = getItemHeight(iname);
-}
-
-bool Entity::isNear(const Entity *e) {
-       return (e != nullptr) ? (pow(e->loc.x - loc.x, 2) + pow(e->loc.y - loc.y, 2) <= pow(HLINES(40), 2)) : false;
-}
-
-void NPC::drawThingy(void) const
-{
-       if (dialogCount) {
-               const auto w = width / 3;
-               GLfloat tex_coord[] = {
-                       0, 0, 1, 0, 1, 1,
-                       1, 1, 0, 1, 0, 0
-               };
-               const GLfloat c[4] = {
-                       loc.x + w, loc.y + height, loc.x + w * 2, loc.y + height + w
-               };
-               GLfloat coords[] = {
-                       c[0], c[1], z, c[2], c[1], z, c[2], c[3], z,
-                       c[2], c[3], z, c[0], c[3], z, c[0], c[1], z
-               };
-
-               // TODO use texture made for this
-               static GLuint thingyColor = Texture::genColor(Color(236, 238, 15));
-
-               Render::worldShader.use();
-               Render::worldShader.enable();
-
-               glBindTexture(GL_TEXTURE_2D, thingyColor);
-
-               glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords);
-               glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex_coord);
-               glDrawArrays(GL_TRIANGLES, 0, 6);
-
-               Render::worldShader.disable();
-               Render::worldShader.unuse();
-       }
-}
-
-void Entity::draw(void)
-{
-       GLfloat tex_coord[] = {0.0, 0.0,
-                                                  1.0, 0.0,
-                                                  1.0, 1.0,
-
-                                                  1.0, 1.0,
-                                                  0.0, 1.0,
-                                                  0.0, 0.0};
-
-       GLfloat tex_coordL[] = {1.0, 0.0,
-                                                       0.0, 0.0,
-                                                       0.0, 1.0,
-
-                                                       0.0, 1.0,
-                                                       1.0, 1.0,
-                                                       1.0, 0.0};
-
-       GLfloat coords[] = {loc.x, loc.y, z,
-                                               loc.x + width, loc.y, z,
-                                               loc.x + width, loc.y + height, z,
-
-                                               loc.x + width, loc.y + height, z,
-                                               loc.x, loc.y + height, z,
-                                               loc.x, loc.y, z};
-
-
-       glActiveTexture(GL_TEXTURE0);
-
-       if (!alive)
-               return;
-
-       if (type == NPCT) {
-               NPCp(this)->drawThingy();
-
-               if (gender == MALE)
-                       glColor3ub(255, 255, 255);
-               else if (gender == FEMALE)
-                       glColor3ub(255, 105, 180);
-       } else if (type == MOBT) {
-               if (Mobp(this)->rider != nullptr) {
-                       Mobp(this)->rider->loc.x = loc.x + width * 0.25f;
-               Mobp(this)->rider->loc.y = loc.y + height - HLINES(5);
-               Mobp(this)->rider->vel.y = .12;
-                       Mobp(this)->rider->z     = z + 0.01;
-           }
-       }
-       switch(type) {
-       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;
-                       glActiveTexture(GL_TEXTURE0);
-                       tex(texState);
-               }
-               if (!ground) {
-                       glActiveTexture(GL_TEXTURE0);
-                       tex(0);
-               } else if (vel.x) {
-                       glActiveTexture(GL_TEXTURE0);
-                       tex(texState);
-               } else {
-                       glActiveTexture(GL_TEXTURE0);
-                       tex(0);
-               }
-               break;
-       case MOBT:
-               if (!Mobp(this)->bindTex())
-                       goto NOPE;
-               break;
-       case STRUCTURET:
-               /* fall through */
-       default:
-               glActiveTexture(GL_TEXTURE0);
-               tex(0);
-               break;
-       }
-
-       Render::worldShader.use();
-       // make the entity hit flash red
-       if (maxHitDuration-hitDuration) {
-               float flashAmt = 1-(hitDuration/maxHitDuration);
-               glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, flashAmt, flashAmt, 1.0);
-       }
-
-       glUniform1i(Render::worldShader.uniform[WU_texture], 0);
-       Render::worldShader.enable();
-
-       glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords);
-       if (left)
-               glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coordL);
-       else
-               glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coord);
-       glDrawArrays(GL_TRIANGLES, 0, 6);
-
-       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
-NOPE:
-if (near && type != MOBT)
-       ui::putStringCentered(loc.x+width/2,loc.y-ui::fontSize-game::HLINE/2,name);
-if (health != maxHealth) {
-
-       static GLuint frontH = Texture::genColor(Color(255,0,0));
-       static GLuint backH =  Texture::genColor(Color(150,0,0));
-       glUniform1i(Render::worldShader.uniform[WU_texture], 0);
-
-       GLfloat coord_back[] = {
-               loc.x,                  loc.y + height,                               z + 0.1f,
-               loc.x + width,  loc.y + height,                               z + 0.1f,
-               loc.x + width,  loc.y + height + game::HLINE * 2, z + 0.1f,
-
-               loc.x + width,  loc.y + height + game::HLINE * 2, z + 0.1f,
-               loc.x,                  loc.y + height + game::HLINE * 2, z + 0.1f,
-               loc.x,                  loc.y + height,                               z + 0.1f,
-       };
-
-       GLfloat coord_front[] = {
-               loc.x,                                      loc.y + height,                   z,
-               loc.x + health / maxHealth * width, loc.y + height,                   z,
-               loc.x + health / maxHealth * width, loc.y + height + game::HLINE * 2, z,
-
-               loc.x + health / maxHealth * width, loc.y + height + game::HLINE * 2, z,
-               loc.x,                              loc.y + height + game::HLINE * 2, z,
-               loc.x,                              loc.y + height,                   z,
-       };
-
-       glBindTexture(GL_TEXTURE_2D, backH);
-       GLfloat tex[] = { 0.0, 0.0,
-                                         1.0, 0.0,
-                                         1.0, 1.0,
-
-                                         1.0, 1.0,
-                                         0.0, 1.0,
-                                         0.0, 0.0,
-       };
-       glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coord_back);
-       glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex);
-       glDrawArrays(GL_TRIANGLES, 0, 6);
-
-       glBindTexture(GL_TEXTURE_2D, frontH);
-       glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coord_front);
-       glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex);
-       glDrawArrays(GL_TRIANGLES, 0, 6);
-}
-
-Render::worldShader.disable();
-Render::worldShader.unuse();
-}
-
-/**
- * Handles NPC movement, usually just random walking.
- */
-
-void NPC::
-wander(int timeRun)
-{
-       static int direction;
-
-       if (forcedMove)
-               return;
-
-       if (hitCooldown)
-               hitCooldown--;
-
-       if (targetx != 0.9112001f) {
-               if (loc.x > targetx + HLINES(5))
-                       vel.x = HLINES(-0.018);
-               else if (loc.x < targetx - HLINES(5))
-                       vel.x = HLINES(0.018);
-               else {
-                       targetx = 0.9112001f;
-                       vel.x = 0;
-               }
-       } else if (ticksToUse == 0) {
-               ticksToUse = timeRun;
-
-               vel.x = HLINES(0.008);
-               direction = (randGet() % 3 - 1);
-
-               if (direction == 0)
-                       ticksToUse *= 2;
-
-               vel.x *= direction;
-       }
-
-       if (vel.x < 0)
-               currentWorld->goWorldLeft(this);
-
-       ticksToUse--;
-}
-
-void NPC::addAIFunc(bool preload)
-{
-       if (preload)
-               aipreload.push_back(this);
-       else
-               ++dialogCount;
-}
-
-extern int commonAIFunc(NPC *speaker);
-
-void NPC::interact() { //have the npc's interact back to the player
-       std::thread([this]{
-               std::vector<XMLElement *> dopt;
-               XMLDocument *xml;
-               XMLElement *exml,*oxml;
-
-               static unsigned int oldidx = 9999;
-               const char *ptr;
-               std::string nname;
-               unsigned int idx;
-               bool stop;
-               float tgt = 0.12345678f;
-               bool pmove = true, advance = false;
-
-               loc.y += 5;
-
-               // freeze the npc, face the player
-               canMove = false;
-               left    = (player->loc.x < loc.x);
-               right   = !left;
-
-               // if there's actual scripted stuff to do, do it
-               if (dialogCount && dialogIndex != 9999) {
-                       // load the XML file and find the dialog tags
-                       if (outnabout == 0) {
-                               xml = &currentXMLDoc;
-                       } else if (outnabout < 0) {
-                               xml = new XMLDocument();
-                               xml->LoadFile((xmlFolder + currentWorld->getToLeft()).c_str());
-                       } else {
-                               xml = new XMLDocument();
-                               xml->LoadFile((xmlFolder + currentWorld->getToRight()).c_str());
-                       }
-
-COMMONAIFUNC:
-                       idx = 0;
-                       stop = false;
-                       exml = xml->FirstChildElement("Dialog");
-
-                       // search for the dialog block associated with this npc
-                       while (exml->StrAttribute("name") != name)
-                               exml = exml->NextSiblingElement();
-
-                       // search for the desired text block
-                       exml = exml->FirstChildElement();
-                       do {
-                               if (std::string("text") == exml->Name() && exml->UnsignedAttribute("id") == (unsigned)dialogIndex)
-                                       break;
-                       } while ((exml = exml->NextSiblingElement()));
-
-                       // handle quest tags
-                       if ((oxml = exml->FirstChildElement("quest"))) {
-                               std::string qname;
-
-                               // iterate through all quest tags
-                               do {
-                                       // assign quest
-                                       if (!(qname = oxml->StrAttribute("assign")).empty())
-                                               player->qh.assign(qname, oxml->StrAttribute("desc"), (oxml->GetText() == nullptr) ? "" : oxml->GetText());
-
-                                       // check / finish quest
-                                       else if (!(qname = oxml->StrAttribute("check")).empty()) {
-                                               if (player->qh.hasQuest(qname) && player->qh.finish(qname)) {
-                                                       // QuestHandler::finish() did all the work..
-                                                       break;
-                                               } else {
-                                                       // run error dialog
-                                                       oldidx = dialogIndex;
-                                                       dialogIndex = oxml->UnsignedAttribute("fail");
-                                                       goto COMMONAIFUNC;
-                                               }
-                                       }
-                               } while((oxml = oxml->NextSiblingElement("quest")));
-                       }
-
-                       // handle give tags
-                       if ((oxml = exml->FirstChildElement("give"))) {
-                               do player->inv->addItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count"));
-                               while ((oxml = oxml->NextSiblingElement("give")));
-                       }
-
-                       // handle take tags
-                       if ((oxml = exml->FirstChildElement("take"))) {
-                               do player->inv->takeItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count"));
-                               while ((oxml = oxml->NextSiblingElement()));
-                       }
-
-                       // handle movement directs
-                       if ((oxml = exml->FirstChildElement("gotox"))) {
-                               moveTo((tgt = std::stoi(oxml->GetText())));
-                               if (oxml->QueryBoolAttribute("playerMove", &pmove) != XML_NO_ERROR)
-                                       pmove = true;
-                               if (oxml->QueryBoolAttribute("advance", &advance) != XML_NO_ERROR)
-                                       advance = false;
-                       }
-
-                       // handle attribute setting
-                       if ((oxml = exml->FirstChildElement("set"))) {
-                               do game::setValue(oxml->StrAttribute("id"), oxml->StrAttribute("value"));
-                               while ((oxml = oxml->NextSiblingElement()));
-                               game::briceUpdate();
-                       }
-
-                       // asdlfkj
-
-                       auto txml = exml->FirstChildElement("content");
-                       if (txml == nullptr)
-                               goto OTHERSTUFF;
-
-                       ptr = txml->GetText() - 1;
-                       while (*++ptr && isspace(*ptr));
-
-                       // handle dialog options
-                       if ((oxml = exml->FirstChildElement("option"))) {
-                               std::string optstr;
-
-                               // convert option strings to a colon-separated format
-                               do {
-                                       // append the next option
-                                       optstr.append(std::string(":") + oxml->Attribute("text"));
-
-                                       // save the associated XMLElement
-                                       dopt.push_back(oxml);
-                               } while ((oxml = oxml->NextSiblingElement()));
-
-                               // run the dialog stuff
-                               ui::dialogBox(name, optstr, false, ptr);
-                               ui::waitForDialog();
-
-                               if (ui::dialogOptChosen)
-                                       exml = dopt[ui::dialogOptChosen - 1];
-
-                               dopt.clear();
-                       }
-
-                       // optionless dialog
-                       else {
-                               ui::dialogBox(name, "", false, ptr);
-                               ui::waitForDialog();
-                       }
-
-OTHERSTUFF:
-
-                       // trigger other npcs if desired
-                       if (!(nname = exml->StrAttribute("call")).empty()) {
-                               NPC *n = dynamic_cast<NPC *>(*std::find_if(std::begin(currentWorld->entity), std::end(currentWorld->entity), [nname](Entity *e) {
-                                       return (e->type == NPCT && e->name == nname);
-                               }));
-
-                               if (exml->QueryUnsignedAttribute("callid", &idx) == XML_NO_ERROR) {
-                                       n->dialogIndex = idx;
-                                       n->addAIFunc(false);
-                               }
-                       }
-
-                       if (tgt != 0.12345678f) {
-                               stop = canMove;
-                               canMove = true;
-                               while (targetx != 0.9112001f) {
-                                       if (!pmove)
-                                               player->speed = 0;
-                               }
-                               if (!pmove) {
-                                       pmove = true;
-                                       player->speed = 1;
-                               }
-                               canMove = stop;
-                       }
-
-                       // handle potential following dialogs
-                       if ((idx = exml->UnsignedAttribute("nextid"))) {
-                               dialogIndex = idx;
-
-                               // stop talking
-                               if (exml->QueryBoolAttribute("stop", &stop) == XML_NO_ERROR && stop) {
-                                       dialogIndex = 9999;
-                                       dialogCount--;
-                               }
-
-                               // pause, allow player to click npc to continue
-                               else if (exml->QueryBoolAttribute("pause", &stop) == XML_NO_ERROR && stop) {
-                                       //return 1;
-                               }
-
-                               // instantly continue
-                               else {
-                                       goto COMMONAIFUNC;
-                               }
-                       }
-
-                       // advance if desired
-                       else if (advance) {
-                               goto COMMONAIFUNC;
-                       }
-
-                       // stop talking
-                       else {
-                               // error text?
-                               if (oldidx != 9999) {
-                                       dialogIndex = oldidx;
-                                       oldidx = 9999;
-                               } else {
-                                       dialogIndex = 9999;
-                                       dialogCount--;
-                               }
-                       }
-               } else {
-                       ui::dialogBox(name, "", false, randomDialog[randDialog]);
-               }
-
-               ui::waitForDialog();
-               canMove = true;
-       }).detach();
-}
-
-void Merchant::wander(int timeRun) {
-       static int direction;
-
-       if (forcedMove)
-               return;
-
-       if (ticksToUse == 0) {
-               ticksToUse = timeRun;
-
-               vel.x = HLINES(0.008);
-               direction = (randGet() % 3 - 1);
-
-               if (direction == 0)
-                       ticksToUse *= 2;
-
-               vel.x *= direction;
-       }
-
-       if (vel.x < 0)
-               currentWorld->goWorldLeft(this);
-       if (inside != nullptr) {
-               loc.y = inside->loc.y + HLINES(2);
-               vel.y = GRAVITY_CONSTANT * 5;
-               if (loc.x <= inside->loc.x + HLINES(5))
-                       loc.x = inside->loc.x + HLINES(5);
-               else if (loc.x + width >= inside->loc.x + inside->width - HLINES(5))
-                       loc.x = inside->loc.x + inside->width - width - HLINES(5);
-       }
-       ticksToUse--;
-}
-
-void Merchant::interact() {
-       std::thread([this]{
-               ui::merchantBox(name.c_str(), trade[currTrade], ":Accept:Good-Bye", false, toSay->c_str());
-               ui::waitForDialog();
-
-               // handle normal dialog options
-               switch (ui::dialogOptChosen) {
-               // Accept
-               case 1:
-                       if (!(player->inv->takeItem(trade[currTrade].item[1], trade[currTrade].quantity[1]))) {
-                               player->inv->addItem(trade[currTrade].item[0],trade[currTrade].quantity[0]);
-                               toSay = &text[1];
-                               interact();
-                       } else {
-                               toSay = &text[2];
-                               interact();
-                       }
-                       break;
-
-               // Good-bye
-               case 2:
-                       break;
-
-               default:
-                       break;
-               }
-
-               // handle merchant-specific dialog options
-               switch (ui::merchOptChosen) {
-               // left arrow
-               case 1:
-                       if (currTrade)
-                               currTrade--;
-                       ui::dontTypeOut();
-                       interact(); // TODO should we nest like this?
-                       break;
-
-               // right arrow
-               case 2:
-                       if (currTrade < trade.size() - 1)
-                               currTrade++;
-                       ui::dontTypeOut();
-                       interact();
-                       break;
-
-               default:
-                       break;
-               toSay = &text[0];
-               }
-       }).detach();
-}
-
-void Object::interact(void) {
-       std::thread([this]{
-               if(questObject && alive){
-                       ui::dialogBox(player->name, ":Yes:No", false, pickupDialog);
-                       ui::waitForDialog();
-                       if (ui::dialogOptChosen == 1) {
-                               player->inv->addItem(iname, 1);
-                               alive = false;
-                       }
-               }else{
-                       alive = false;
-                       player->inv->addItem(iname, 1);
-               }
-       }).detach();
-}
-
-bool Entity::isInside(vec2 coord) const {
-       return coord.x >= loc.x &&
-                  coord.x <= loc.x + width &&
-                  coord.y >= loc.y     &&
-              coord.y <= loc.y + height;
-}
-
-/*
- *     This spawns the structures
- *
- * Structures::spawn           This allows us to spawn buildings and large amounts of entities with it.
- *                                                     Passed are the type and x and y coordinates. These set the x and y coords
- *                                                     of the structure being spawned, the type pass just determines what rules to follow
- *                                                     when spawing the structure and entities. In theory this function can also spawn
- *                                                     void spawn points for large amounts of entities. This would allow for the spawn
- *                                                     point to have non-normal traits so it could be invisible or invincible...
-*/
-
-unsigned int Structures::spawn(BUILD_SUB sub, float x, float y) {
-       loc.x = x;
-       loc.y = y;
-       type = STRUCTURET;
-
-       alive = true;
-       canMove = false;
-
-       bsubtype = sub;
-       dim2 dim;
-
-       z = 1.0;
-       /*
-        *      tempN is the amount of entities that will be spawned in the village. Currently the village
-        *      will spawn bewteen 2 and 7 villagers for the starting hut.
-       */
-
-       //unsigned int tempN = (randGet() % 5 + 2);
-
-       if (textureLoc.empty())
-               textureLoc = inWorld->getSTextureLocation(sub);
-
-       switch(sub) {
-               case STALL_MARKET:
-                       tex = TextureIterator({ textureLoc });
-                       dim = Texture::imageDim(textureLoc);
-                       width = HLINES(dim.x/2);
-                       height = HLINES(dim.y/2);
-                       break;
-               default:
-                       tex = TextureIterator({ textureLoc });
-                       dim = Texture::imageDim(textureLoc);
-                       width = HLINES(dim.x/2);
-                       height = HLINES(dim.y/2);
-                       inv = NULL;
-                       break;
-       }
-
-       return 0;
-}
-
-/*Particles::Particles(const Structures *&s, vec2 vell, Color c, float d, )
-{
-
-}*/
-
-Particles::Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d)
-{
-       loc = vec2 {x, y};
-       vel = vec2 {vx, vy};
-       width = w;
-       height = h;
-       color = c;
-       duration = d;
-       gravity = true;
-       fountain = false;
-       behind = false;
-       bounce = false;
-       index = Texture::getIndex(c);
-       zOffset = ((rand()%20)-10)/1000.0f;
-       stu = nullptr;
-}
-
-void Particles::draw(GLfloat*& p) const
-{
-       vec2 tc = vec2(0.25f * index.x, 0.125f * (8.0f - index.y));
-
-       float z = (behind ? 2.0f : 0.9f) + zOffset;
-
-       // lower left
-    *(p++) = loc.x;
-    *(p++) = loc.y;
-    *(p++) = z;
-
-       *(p++) = tc.x;
-       *(p++) = tc.y;
-
-       // lower right
-    *(p++) = loc.x + width;
-    *(p++) = loc.y;
-    *(p++) = z;
-
-       *(p++) = tc.x;
-       *(p++) = tc.y;
-
-       // upper right
-    *(p++) = loc.x + width;
-    *(p++) = loc.y + height;
-    *(p++) = z;
-
-       *(p++) = tc.x;
-       *(p++) = tc.y;
-
-       // upper right
-    *(p++) = loc.x + width;
-    *(p++) = loc.y + height;
-    *(p++) = z;
-
-       *(p++) = tc.x;
-       *(p++) = tc.y;
-
-       // upper left
-    *(p++) = loc.x;
-    *(p++) = loc.y + height;
-    *(p++) = z;
-
-       *(p++) = tc.x;
-    *(p++) = tc.y;
-
-       // lower left
-    *(p++) = loc.x;
-    *(p++) = loc.y;
-    *(p++) = z;
-
-    *(p++) = tc.x;
-    *(p++) = tc.y;
-}
-
-void Particles::update(float _gravity, float ground_y)
-{
-       auto delta = game::time::getDeltaTime();
-
-       // handle ground collision
-       if (loc.y < ground_y) {
-               loc.y = ground_y;
-
-               // handle bounce
-               if (bounce) {
-                       vel.y *= -0.2f;
-                       vel.x /= 4.0f;
-               } else {
-                       vel = 0.0f;
-                       canMove = false;
-               }
-       }
-
-       // handle gravity
-       else if (gravity && vel.y > -1.0f) {
-               vel.y -= _gravity * delta;
-       }
-
-       // handle lifetime
-       duration -= delta;
-}
-
-bool Particles::timeUp(void)
-{
-       return !(duration > 0);
-}
-
-void Player::save(void) {
-       std::string data;
-       std::ofstream out (xmlFolder + ".main.dat", std::ios::out | std::ios::binary);
-       std::cout<<"Saving player data..."<<std::endl;
-       data.append(std::to_string((int)loc.x) + "\n");
-       data.append(std::to_string((int)loc.y) + "\n");
-       data.append(std::to_string((int)health) + "\n");
-       data.append(std::to_string((int)maxHealth) + "\n");
-       data.append(std::to_string((int)game::time::getTickCount()) + "\n");
-
-       data.append("qwer\n");
-       data.append(std::to_string((int)inv->Items.size()) + "\n");
-       for(auto &i : inv->Items) {
-               if(i.second)
-                       data.append(std::to_string(uint(i.second)) + "\n" + i.first->name + "\n");
-       }
-       data.append("qwer\n");
-
-       data.append(std::string(currentXML.data() + 4) + "\n");
-
-       data.append("dOnE\0");
-       out.write(data.data(),data.size());
-       out.close();
-}
-
-void Player::sspawn(float x,float y) {
-       unsigned int i;
-       int count;
-       std::ifstream in (xmlFolder + ".main.dat", std::ios::in | std::ios::binary);
-       spawn(x,y);
-
-       if (in.good()) {
-               std::istringstream data;
-               std::string ddata;
-               std::streampos len;
-
-               in.seekg(0,std::ios::end);
-               len = in.tellg();
-               in.seekg(0,std::ios::beg);
-
-               std::vector<char> buf (len,'\0');
-               in.read(buf.data(),buf.size());
-
-               data.rdbuf()->pubsetbuf(buf.data(),buf.size());
-
-               std::getline(data,ddata);
-               loc.x = std::stoi(ddata);
-               std::getline(data,ddata);
-               loc.y = std::stoi(ddata);
-               std::getline(data,ddata);
-               health = std::stoi(ddata);
-               std::getline(data,ddata);
-               maxHealth = std::stoi(ddata);
-               std::getline(data,ddata);
-               game::time::tick(std::stoi(ddata));
-
-               std::getline(data,ddata);
-               std::getline(data,ddata);
-
-               for (i = std::stoi(ddata);i;i--) {
-                       std::getline(data,ddata);
-                       if (ddata == "qwer")
-                               break;
-                       count = std::stoi(ddata);
-
-                       std::getline(data,ddata);
-                       if (ddata == "qwer")
-                               break;
-                       inv->addItem(ddata, (uint)count);
-               }
-
-               std::getline(data,ddata);
-               currentWorld = loadWorldFromXMLNoSave(ddata);
-
-               in.close();
-       }
-}
-
-
-//NEW
-void entityxTest(void)
-{
-       entityx::Entity e = game::entities.create();
-       e.assign<Position>(100.0f, 100.0f);
-       e.assign<Direction>(0.0f, 0.0f);
-       
-       e = game::entities.create();
-       e.assign<Position>(0.0f, 100.0f);
-       e.assign<Direction>(-0.01f, 0.0f);
-       e.assign<Visible>(-.2f);
-       auto sprite_h = e.assign<Sprite>();
-       sprite_h->addSpriteSegment(SpriteData(game::sprite_l.loadSprite("assets/cat.png"),
-                                                                                 vec2(0, 0),
-                                                                                 vec2(19, 15)),
-                                                                                 vec2(0, 0));
-}
index 1005d84580117d71eca4656633f100c6a40edc5a..cb736ff2efb4a1468c17989f7a51b7ed805795d7 100644 (file)
@@ -1,15 +1,9 @@
 #include <gametime.hpp>
 
-#include <common.hpp>
+#include <common.hpp> // millis
 
 static unsigned int tickCount = 0;
-static float deltaTime = 1;
-
-// millisecond timers
-static unsigned int currentTime = 0;
-static unsigned int prevTime;
-
-static float accum = 0.0f;
+static unsigned int deltaTime = 1;
 
 namespace game {
     namespace time {
@@ -34,15 +28,19 @@ namespace game {
         }
 
         void mainLoopHandler(void) {
-               if (!currentTime)
-                       currentTime = prevTime = millis();
+                       static unsigned int cur = 0, prev;
 
-               currentTime = millis();
-               deltaTime       = currentTime - prevTime;
-               prevTime        = currentTime;
+                       if (cur == 0)
+                               cur = prev = millis();
+
+                       cur = millis();
+                       deltaTime = cur - prev;
+                       prev = cur;
         }
 
         bool tickHasPassed(void) {
+                       static unsigned int accum = 0;
+
             accum += deltaTime;
             if (accum > MSEC_PER_TICK) {
                        accum = 0.0f;
index 480c8032df25240138d9bdf22439fbab46cca3a1..ed6028b1d4d572601d01a6a6da8bac1be1e365b8 100644 (file)
@@ -2,10 +2,10 @@
 
 #include <common.hpp>
 #include <events.hpp>
-#include <texture.hpp>
-#include <render.hpp>
+//#include <texture.hpp>
+//#include <render.hpp>
 
-constexpr const char* ICON_TEX_FILE_PATH = "config/invIcons.txt";
+constexpr const char* iconTexturePath = "config/invIcons.txt";
 
 static std::vector<Texture> iconTextures;
 
@@ -16,7 +16,7 @@ void InventorySystem::configure(entityx::EventManager &ev)
 
 void InventorySystem::loadIcons(void) {
     iconTextures.clear();
-    auto icons = readFileA(ICON_TEX_FILE_PATH);
+    auto icons = readFileA(iconTexturePath);
     for (const auto& s : icons)
         iconTextures.push_back(s);
 }
diff --git a/src/inventory.cpp.bak b/src/inventory.cpp.bak
deleted file mode 100644 (file)
index 1b325c0..0000000
+++ /dev/null
@@ -1,747 +0,0 @@
-#include <inventory.hpp>
-
-#include <numeric>
-
-#include <gametime.hpp>
-
-#include <render.hpp>
-
-#include <tinyxml2.h>
-using namespace tinyxml2;
-
-extern Player *player;
-extern GLuint invUI;
-static vec2 itemLoc;
-static const unsigned char numSlot = 7;
-Mix_Chunk* swordSwing;
-
-static std::vector<NewCurrency *> currencyMap;
-static std::vector<Item *> ItemMap;
-
-
-void itemDraw(Player *p, Item* d);
-
-bool strCaseCmp(std::string one, std::string two)
-{
-       for (auto &s : one) {
-               s = std::tolower(s);
-       }
-       for (auto &t : two) {
-               t = std::tolower(t);
-       }
-
-       if (one == two) return true;
-       return false;
-}
-
-void items(void)
-{
-       XMLDocument xml;
-       xml.LoadFile("config/items.xml");
-       XMLElement *exml = xml.FirstChildElement("item");
-       XMLElement *cxml = xml.FirstChildElement("currency");
-
-       while (cxml) {
-
-               // NEWEWEWEWEWEWEWEW
-               // TODO
-
-
-               cxml = cxml->NextSiblingElement();
-       }
-       while (exml) {
-
-               std::string name = exml->Attribute("type");
-               // if the type is blank
-               if (strCaseCmp(name, "blank")) {
-
-                       ItemMap.push_back(new BaseItem());
-
-               // if the type is a sword
-               } else if (strCaseCmp(name, "sword")) {
-
-                       Sword *tmpSword = new Sword();
-                       tmpSword->setDamage(exml->FloatAttribute("damage"));
-                       ItemMap.push_back(tmpSword->clone());
-                       delete tmpSword;
-
-               // if the type is a bow
-               } else if (strCaseCmp(name, "bow")) {
-
-                       Bow *tmpBow = new Bow();
-                       tmpBow->setDamage(exml->FloatAttribute("damage"));
-                       ItemMap.push_back(tmpBow->clone());
-                       delete tmpBow;
-
-               // arrow
-               } else if (strCaseCmp(name, "arrow")) {
-
-                       Arrow *tmpArrow = new Arrow();
-                       tmpArrow->setDamage(exml->FloatAttribute("damage"));
-                       ItemMap.push_back(tmpArrow->clone());
-                       delete tmpArrow;
-
-               // uncooked / raw food
-               }else if (strCaseCmp(name, "raw food")) {
-
-                       ItemMap.push_back(new RawFood());
-
-               // cooked food or natural food
-               } else if (strCaseCmp(name, "food") || strCaseCmp(name, "cooked food")) {
-
-                       ItemMap.push_back(new Food());
-
-               // light
-               } else if (strCaseCmp(name, "light")) {
-
-                       ItemMap.push_back(new ItemLight());
-
-               // if type was not specified make it a base item
-               } else {
-
-                       ItemMap.push_back(new BaseItem());
-               }
-
-               // set how much of the item we can stack
-               if(exml->QueryUnsignedAttribute("maxStackSize", &ItemMap.back()->maxStackSize) != XML_NO_ERROR) {
-                       ItemMap.back()->maxStackSize = 1;
-               }
-
-               // set all of the texture frames we can use
-               ItemMap.back()->tex = new Texturec(1, exml->Attribute("sprite"));
-
-               // get the width and height of the object based off of its sprite
-               dim2 tmpDim = Texture::imageDim(exml->Attribute("sprite"));
-               ItemMap.back()->dim.x = HLINES(tmpDim.x/2);
-               ItemMap.back()->dim.y = HLINES(tmpDim.y/2);
-
-               ItemMap.back()->name = exml->Attribute("name");
-
-               exml = exml->NextSiblingElement();
-       }
-}
-
-int Inventory::addItem(std::string name, uint count)
-{
-       for (uint i = 0; i < ItemMap.size(); i++) {
-               if (strCaseCmp(ItemMap[i]->name, name)) {
-                       for (auto &it : Items) {
-                               if (it.second && strCaseCmp(it.first->name, name)) {
-                                       if ((it.second + count) < it.first->maxStackSize) {
-                                               it.second += count;
-                                               return 0;
-                                       } else {
-                                               count -= (it.second + count) - it.first->maxStackSize;
-                                               it.second = it.first->maxStackSize;
-                                       }
-                               }
-                       }
-                       uint tmpCount = count;
-                       do {
-                               if ((count) > ItemMap[i]->maxStackSize) {
-                                       count -=  ItemMap[i]->maxStackSize;
-                                       tmpCount = ItemMap[i]->maxStackSize;
-                               } else {
-                                       tmpCount = count;
-                                       count = 0;
-                               }
-                               Items[os] = std::make_pair(ItemMap[i]->clone(), tmpCount);
-                               if (!Items[os+1].second) {
-                                       os++;
-                               } else {
-                                       for (uint z = 0; z < Items.size(); z++) {
-                                               if (!Items[z].second) {
-                                                       os = z;
-                                               }
-                                       }
-                               }
-                       } while (count > 0);
-                       return 0;
-               }
-       }
-       return -1;
-}
-
-int Inventory::takeItem(std::string name, uint count)
-{
-
-       // returns
-       // 0 = good
-       // -1 = no such item exists
-       // -2 = if item doesnt exist in inventory
-       // postive items = number returned is how many more the item needs
-
-       std::string iden;
-
-       for (uint i = 0; i < ItemMap.size(); i++) {
-               if (ItemMap[i]->name == name) {
-                       iden = name;
-                       break;
-               }
-       }
-
-       if (iden.empty()) {
-               return -1;
-       }
-
-       for (auto &i : Items) {
-               if (i.second && i.first->name == iden) {
-                       if (count > i.second) {
-                               return (count - i.second);
-                       } else {
-                               i.second -= count;
-
-                       }
-                       return 0;
-               }
-       }
-
-       return -2;
-}
-
-int Inventory::hasItem(std::string name) {
-
-       for (auto &i : Items) {
-               if (i.first->name == name) {
-                       return i.second;
-               }
-       }
-
-       return 0;
-}
-void initInventorySprites(void) {
-
-       items();
-
-       // keep
-       swordSwing = Mix_LoadWAV("assets/sounds/shortSwing.wav");
-       Mix_Volume(2,100);
-}
-
-void destroyInventory(void) {
-
-       // NEWEWEWEWEWEWEWEW
-       while (!ItemMap.empty()) {
-               delete ItemMap.back();
-               ItemMap.pop_back();
-       }
-
-       Mix_FreeChunk(swordSwing);
-}
-
-
-const char *getItemTexturePath(std::string name){
-       for (auto &i : ItemMap) {
-               if (i->name == name)
-                       return i->tex->texLoc[0].c_str();
-       }
-       return NULL;
-}
-
-GLuint getItemTexture(std::string name) {
-       for (auto &i : ItemMap) {
-               if (i->name == name) {
-                       return i->tex->image[0];
-               }
-       }
-       return 0;
-}
-
-float getItemWidth(std::string name) {
-       for (auto &i : ItemMap) {
-               if (i->name == name)
-                       return i->dim.x;
-       }
-       return 0;
-}
-
-float getItemHeight(std::string name) {
-       for (auto &i : ItemMap) {
-               if (i->name == name)
-                       return i->dim.y;
-       }
-       return 0;
-}
-
-Inventory::Inventory(unsigned int s) {
-       sel=0;
-       size=s;
-
-       Items.resize(size);
-       for (auto &i : Items) {
-               i = std::make_pair(nullptr, 0);
-       }
-}
-
-Inventory::~Inventory(void) {
-}
-
-void Inventory::setSelection(unsigned int s) {
-       sel=s;
-}
-
-void Inventory::setSelectionUp() {
-       if (!sel--)
-               sel++;
-}
-
-void Inventory::setSelectionDown() {
-       if (++sel >= numSlot)
-               sel = numSlot - 1;
-}
-
-void Inventory::draw(void) {
-       static std::vector<int>dfp(numSlot);
-       static std::vector<Ray>iray(numSlot);
-       static std::vector<vec2>curCoord(numSlot);
-       static int range = 200;
-
-       static std::vector<int>curdfp(4);
-       static std::vector<Ray>curRay(4);
-       static std::vector<vec2>curCurCoord(4);
-       static int curRange = 100;
-
-       static std::vector<int>massDfp(32);
-       static std::vector<vec2>massRay(32);
-       static std::vector<int>massOrder = {9,10,11,12,13,14,22,21,20,19,18,17,16,8,0,1,2,3,4,5,6,7,15,23,31,30,29,28,27,26,25,24};
-       static std::vector<int>massOrderClosing = {31,30,23,29,22,15,28,21,14,7,27,20,13,6,26,19,12,5,25,18,11,4,24,17,10,3,16,9,2,8,1,0};
-       static int massRange = 200;
-
-       static int itemWide = 45;
-       float angleB = (float)180/(float)numSlot;
-       float angle = float(angleB/2.0f);
-       unsigned int a = 0;
-       //static vec2 mouseStart = {0,0};
-
-       auto deltaTime = game::time::getDeltaTime();
-       auto SCREEN_WIDTH = game::SCREEN_WIDTH;
-       auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
-
-       for (auto &r : iray) {
-               r.start.x = player->loc.x + (player->width  / 2);
-               r.start.y = player->loc.y + (player->height / 2);
-               curCoord[a++] = r.start;
-       } a = 0;
-
-       for (auto &cr : curRay) {
-               cr.start.x = (offset.x + SCREEN_WIDTH / 2);
-               cr.start.y =  offset.y - (a * itemWide * 1.5f);
-               curCurCoord[a++] = cr.start;
-       } a = 0;
-
-       for (int r = 0; r < 4; r++) {
-               for (int c = 0; c < 8; c++) {
-                       massRay[a  ].x = ((offset.x - SCREEN_WIDTH  / 2) + itemWide) + c * itemWide * 1.5f;
-                       massRay[a++].y = ((offset.y + SCREEN_HEIGHT / 2) - itemWide * 1.5f) - r * itemWide * 1.5f;
-               }
-       } 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 = std::clamp(255 * (averagef(dfp) / range), 0ul, 255ul);
-
-       if (invOpening) {
-               for (auto &d : dfp) {
-                       if (!a || dfp[a - 1] > 50)
-                               d += 4.0f * deltaTime;
-                       if (d > range)
-                               d = range;
-                       a++;
-               } a = 0;
-
-               for (auto &cd : curdfp) {
-                       if (!a || curdfp[a - 1] > 90)
-                               cd += 3.0f * deltaTime;
-                       if (cd > curRange)
-                               cd = curRange;
-                       a++;
-               } a = 0;
-
-               while (a < massOrder.size()) {
-                       if (!a || massDfp[massOrder[a - 1]] > massRange * 0.75f)
-                               massDfp[massOrder[a]] += 20.0f * deltaTime;
-                       if (massDfp[massOrder[a]] > massRange)
-                               massDfp[massOrder[a]] = massRange;
-                       a++;
-               } a = 0;
-
-               if (numSlot > 0)
-                       invOpen = true;
-       } else {
-               for (auto &d : dfp) {
-                       if (d > 0)
-                               d -= 4.5f * deltaTime;
-               }
-               for (auto &cd : curdfp) {
-                       if (cd > 0)
-                               cd -= 3.0f * deltaTime;
-               }
-
-               while (a < massRay.size()) {
-                       if (!a || massDfp[massOrderClosing[a - 1]] <= 0)
-                               massDfp[massOrderClosing[a]] -= 30.0f * deltaTime;
-                       else if (massDfp[massOrderClosing[a - 1]] < 0)
-                               massDfp[massOrderClosing[a - 1]] = 0;
-                       a++;
-               } a = 0;
-
-               if (std::all_of(std::begin(massDfp), std::end(massDfp), [](auto d) { return d <= 0; })) {
-                       invOpen = false;
-                       for (auto &md : massDfp) {
-                               if (md < 0)
-                                       md = 0;
-                       }
-               }
-
-       }
-
-       /*
-        *      a = 0
-        */
-
-       if (invOpen) {
-        Render::useShader(&Render::textShader);
-               for(auto &mr : massRay) {
-            float t = (((float)massDfp[a]/(float)massRange)*.5f);
-            glActiveTexture(GL_TEXTURE0);
-            Render::textShader.use();
-
-                       glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(0.0f,0.0f,0.0f, t >= 0? 255*t : 0)));
-            glUniform1i(Render::textShader.uniform[WU_texture], 0);
-
-            Render::drawRect(vec2(mr.x-(itemWide/2), mr.y-(itemWide/2)), vec2(mr.x-(itemWide/2)+itemWide, mr.y-(itemWide/2)+itemWide), -6.0);
-
-            glUseProgram(0);
-                       if (!Items.empty() && a+numSlot < Items.size() && Items[a+numSlot].second) {
-                               Render::textShader.use();
-                glBindTexture(GL_TEXTURE_2D, Items[a+numSlot].first->tex->image[0]);//itemtex[items[a+numSlot].id]);
-                               glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0f, 1.0f, 1.0f, ((float)massDfp[a]/(float)(massRange?massRange:1))*0.8f);
-
-                if (Items[a+numSlot].first->dim.y > Items[a+numSlot].first->dim.x) {
-                    Render::drawRect(vec2(mr.x-((itemWide/2)*((float)Items[a+numSlot].first->dim.x/(float)Items[a+numSlot].first->dim.y)),     mr.y-(itemWide/2)),
-                                     vec2(mr.x+((itemWide/2)*((float)Items[a+numSlot].first->dim.x/(float)Items[a+numSlot].first->dim.y)),     mr.y+(itemWide/2)), -6.1);
-                } else {
-                    Render::drawRect(vec2(mr.x-(itemWide/2),mr.y-(itemWide/2)*((float)Items[a+numSlot].first->dim.y/(float)Items[a+numSlot].first->dim.x)),
-                                     vec2(mr.x-(itemWide/2),mr.y+(itemWide/2)*((float)Items[a+numSlot].first->dim.y/(float)Items[a+numSlot].first->dim.x)), -6.1);
-                }
-                               ui::setFontColor(255,255,255,((float)massDfp[a]/(float)(massRange?massRange:1))*255);
-                               ui::putText(mr.x-(itemWide/2)+(itemWide*.85),mr.y-(itemWide/2),"%d",Items[a+numSlot].second);
-                               ui::setFontColor(255,255,255,255);
-                Render::textShader.unuse();
-                       }
-                       a++;
-               }a=0;
-
-               for(auto &cr : curRay) {
-                       curCurCoord[a].x -= float((curdfp[a]) * cos(-1));
-                       curCurCoord[a].y += float((curdfp[a]) * sin(0));
-                       cr.end = curCurCoord[a];
-
-            float curTrans = (((float)curdfp[a]/(float)(curRange?curRange:1))*0.5f);
-
-            Render::textShader.use();
-                       glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(0.0f, 0.0f, 0.0f, curTrans >= 0 ? 255 * curTrans : 0)));
-            Render::drawRect(vec2(cr.end.x-(itemWide/2),                cr.end.y-(itemWide/2)),
-                             vec2(cr.end.x-(itemWide/2)+itemWide,cr.end.y-(itemWide/2)+itemWide), -6.0);
-            Render::textShader.unuse();
-                       a++;
-               }a=0;
-
-               for(auto &r : iray) {
-                       angle = 180 - (angleB * a) - angleB / 2.0f;
-                       curCoord[a].x += float((dfp[a]) * cos(angle*PI/180));
-                       curCoord[a].y += float((dfp[a]) * sin(angle*PI/180));
-                       r.end = curCoord[a];
-
-            float t = ((float)dfp[a]/(float)(range?range:1))*0.5f;
-
-            Render::textShader.use();
-                       glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(0.0f, 0.0f, 0.0f, t >= 0 ? 255 * t : 0)));
-            Render::drawRect(vec2(r.end.x-(itemWide/2),                 r.end.y-(itemWide/2)),
-                             vec2(r.end.x-(itemWide/2)+itemWide,r.end.y-(itemWide/2)+itemWide), -6.0);
-
-                       if (!Items.empty() && a < numSlot && Items[a].second) {
-                               glBindTexture(GL_TEXTURE_2D, Items[a].first->tex->image[0]);//itemtex[items[a].id]);
-                               glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0f, 1.0f, 1.0f, ((float)dfp[a]/(float)(range?range:1))*0.8f);
-                               if (Items[a].first->dim.y > Items[a].first->dim.x) {
-                                   Render::drawRect(vec2(r.end.x-((itemWide/2)*((float)Items[a].first->dim.x/(float)Items[a].first->dim.y)),   r.end.y-(itemWide/2)),
-                                     vec2(r.end.x+((itemWide/2)*((float)Items[a].first->dim.x/(float)Items[a].first->dim.y)),  r.end.y+(itemWide/2)), -6.1);
-                } else {
-                    Render::drawRect(vec2(r.end.x-(itemWide/2),r.end.y-(itemWide/2)*((float)Items[a].first->dim.y/(float)Items[a].first->dim.x)),
-                                     vec2(r.end.x+(itemWide/2),r.end.y+(itemWide/2)*((float)Items[a].first->dim.y/(float)Items[a].first->dim.x)), -6.1);
-                               }
-                               ui::setFontColor(255,255,255,((float)dfp[a]/(float)(range?range:1))*255);
-                               ui::putStringCentered(r.end.x,r.end.y-(itemWide*.9),Items[a].first->name);//itemMap[items[a].id]->name);
-                               ui::putText(r.end.x-(itemWide/2)+(itemWide*.85),r.end.y-(itemWide/2),"%d",Items[a].second);
-                               ui::setFontColor(255,255,255,255);
-                       }
-            Render::textShader.unuse();
-                       if (sel == a) {
-                               static float sc = 1;
-                               static bool up;
-                               up ? sc += .0025*deltaTime : sc -= .0025*deltaTime;
-                               if (sc > 1.2) {
-                                       up = false;
-                                       sc = 1.2;
-                               }
-                               if (sc < 1.0) {
-                                       up = true;
-                                       sc = 1.0;
-                               }
-                float t = ((float)dfp[a]/(float)(range?range:1));
-                Render::useShader(&Render::textShader);
-
-                Render::textShader.use();
-                glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
-
-                // bottom
-                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t >= 0 ? 255 * t : 0)));
-                Render::drawRect(vec2(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09),
-                                 vec2(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2), -6.2);
-
-                // top
-                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t  >= 0 ? 255 * t : 0)));
-                Render::drawRect(vec2(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09),
-                                 vec2(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2), -6.2);
-
-                // left
-                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t >= 0 ? 255 * t : 0)));
-                Render::drawRect(vec2(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09),
-                                 vec2(r.end.x - (itemWide*sc)/2                                   ,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09), -6.2);
-
-                // right
-                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t >= 0 ? 255 * t : 0)));
-                Render::drawRect(vec2(r.end.x + (itemWide*sc)/2                                        ,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09),
-                                 vec2(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09), -6.2);
-
-                //glUseProgram(0);
-                       }
-                       a++;
-               }
-       } /*else if (invHover) {
-               static unsigned int highlight = 0;
-               static unsigned int thing = 0;
-
-               if (!mouseSel) {
-                       // setup?
-                       mouseStart.x = ui::mouse.x - offset.x;
-                       highlight = sel;
-                       thing = sel;
-                       mouseSel = true;
-               } else {
-                       if((ui::mouse.x - offset.x) >= mouseStart.x){
-                               thing = (ui::mouse.x - offset.x - mouseStart.x)/80;
-                               highlight=sel+thing;
-                               if(highlight>numSlot-1)highlight=numSlot-1;
-                               if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
-                                       sel = highlight;
-                                       mouseSel=false;
-                                       invHover=false;
-                                       selected = true;
-                               }
-                       }
-                       if ((ui::mouse.x - offset.x) < mouseStart.x) {
-                               thing = (mouseStart.x - (ui::mouse.x - offset.x))/80;
-                               if ((int)sel - (int)thing < 0)
-                                       highlight = 0;
-                               else
-                                       highlight = sel - thing;
-                               if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
-                                       sel = highlight;
-                                       mouseSel=false;
-                                       invHover=false;
-                                       selected = true;
-                               }
-                       }
-               }
-
-               a = 0;
-               for (auto &r : iray) {
-                       angle = 180 - (angleB * a) - angleB / 2.0f;
-                       curCoord[a].x += float(range) * cos(angle*PI/180);
-                       curCoord[a].y += float(range) * sin(angle*PI/180);
-                       r.end = curCoord[a];
-
-                       // square drawing
-                       glColor4f(0.0f, 0.0f, 0.0f, a == highlight ? 0.5f : 0.1f);
-                       glBegin(GL_QUADS);
-                               glVertex2i(r.end.x-(itemWide/2),        r.end.y-(itemWide/2));
-                               glVertex2i(r.end.x+(itemWide/2),        r.end.y-(itemWide/2));
-                               glVertex2i(r.end.x+(itemWide/2),        r.end.y+(itemWide/2));
-                               glVertex2i(r.end.x-(itemWide/2),        r.end.y+(itemWide/2));
-                       glEnd();
-
-                       if (a < items.size() && items[a].count) {
-                               glEnable(GL_TEXTURE_2D);
-                               glBindTexture(GL_TEXTURE_2D, itemtex[items[a].id]);
-                               glColor4f(1.0f, 1.0f, 1.0f, a == highlight ? 0.8f : 0.2f);
-                               glBegin(GL_QUADS);
-                                       if(itemMap[items[a].id]->height > itemMap[items[a].id]->width){
-                                               glTexCoord2i(0,1);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
-                                               glTexCoord2i(1,1);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
-                                               glTexCoord2i(1,0);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
-                                               glTexCoord2i(0,0);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
-                                       }else{
-                                               glTexCoord2i(0,1);glVertex2i(r.end.x-(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
-                                               glTexCoord2i(1,1);glVertex2i(r.end.x+(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
-                                               glTexCoord2i(1,0);glVertex2i(r.end.x+(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
-                                               glTexCoord2i(0,0);glVertex2i(r.end.x-(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
-                                       }
-                               glEnd();
-                               glDisable(GL_TEXTURE_2D);
-                       }
-                       a++;
-               }
-
-               if (highlight < items.size()) {
-                       ui::putStringCentered(player->loc.x + player->width / 2,
-                                             player->loc.y + range * 0.75f,
-                                                             itemMap[items[highlight].id]->name
-                                                         );
-               }
-       }*/
-       /*if (!items.empty() && items.size() > sel && items[sel].count)
-               itemDraw(player,items[sel].id);*/
-       if (!Items.empty() && Items.size() > sel && Items[sel].second)
-               itemDraw(player, Items[sel].first);
-}
-
-void itemDraw(Player *p, Item *d) {
-
-       itemLoc.y = p->loc.y+(p->height/3);
-       itemLoc.x = p->left?p->loc.x-d->dim.x/2:p->loc.x+p->width-d->dim.x/2;
-
-       Render::worldShader.use();
-
-       if (p->left) {
-               // move to center of screen
-               glm::mat4 tro = glm::translate(glm::mat4(1.0f),
-                                                                          glm::vec3(itemLoc.x+d->dim.x/2, itemLoc.y, 0));
-               // rotate off center
-               glm::mat4 rot = glm::rotate(glm::mat4(1.0f),
-                                                                       static_cast<GLfloat>((d->rotation*3.14159)/180.0f),
-                                                                       glm::vec3(0.0f, 0.0f, 1.0f));
-               // move back to player
-               glm::mat4 trt = glm::translate(glm::mat4(1.0f),
-                                                                          glm::vec3(-itemLoc.x-d->dim.x/2, -itemLoc.y, 0));
-               // tell shader to translate the object using steps above
-               glUniformMatrix4fv(Render::worldShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(tro * rot * trt));
-       } else {
-               // move to center of screen
-               glm::mat4 tro = glm::translate(glm::mat4(1.0f),
-                                                                          glm::vec3(itemLoc.x+d->dim.x/2,itemLoc.y,0));
-               // rotate off center
-               glm::mat4 rot = glm::rotate(glm::mat4(1.0f),
-                                                                       static_cast<GLfloat>((d->rotation*3.14159)/180.0f),
-                                                                       glm::vec3(0.0f, 0.0f, 1.0f));
-               // move back to player
-               glm::mat4 trt = glm::translate(glm::mat4(1.0f),
-                                                                          glm::vec3(-itemLoc.x-d->dim.x/2,-itemLoc.y,0));
-               // tell shader to translate the object using steps above
-               glUniformMatrix4fv(Render::worldShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(tro * rot * trt));
-       }
-
-    GLfloat itemTex[12] = {0.0, 0.0,
-                           1.0, 0.0,
-                           1.0, 1.0,
-
-                           1.0, 1.0,
-                           0.0, 1.0,
-                           0.0, 0.0};
-    if (!p->left) {
-        itemTex[0] = 1.0;
-        itemTex[2] = 0.0;
-        itemTex[4] = 0.0;
-        itemTex[6] = 0.0;
-        itemTex[8] = 1.0;
-        itemTex[10] = 1.0;
-    }
-
-    GLfloat itemCoords[] = {itemLoc.x,          itemLoc.y,          p->z,
-                            itemLoc.x+d->dim.x, itemLoc.y,          p->z,
-                            itemLoc.x+d->dim.x, itemLoc.y+d->dim.y, p->z,
-
-                            itemLoc.x+d->dim.x, itemLoc.y+d->dim.y, p->z,
-                            itemLoc.x,          itemLoc.y+d->dim.y, p->z,
-                            itemLoc.x,          itemLoc.y,          p->z};
-
-       glBindTexture(GL_TEXTURE_2D,d->tex->image[0]);
-
-    Render::worldShader.enable();
-
-    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, itemCoords);
-    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, itemTex);
-    glDrawArrays(GL_TRIANGLES, 0, 6);
-
-       Render::worldShader.disable();
-       Render::worldShader.unuse();
-}
-
-/*
- *     This function is used to trigger the player's item's ability.
- */
-int Inventory::useItem(void)
-{
-       return 0;
-}
-
-int Inventory::useCurrent()
-{
-       if (Items[sel].second)
-               return Items[sel].first->useItem();
-       return -1;
-}
-
-void Inventory::currentAddInteract(Entity* e)
-{
-       if (Items[sel].second)
-               Items[sel].first->addInteract(e);
-}
-
-void Inventory::currentAddInteract(std::vector<Entity*> e)
-{
-       if (Items[sel].second)
-               Items[sel].first->addInteract(e);
-}
-
-bool Inventory::detectCollision(vec2 one, vec2 two) {
-       (void)one;
-       (void)two;
-       return false;
-}
-
-const Item* Inventory::getCurrentItem(void)
-{
-       if (Items.size() > 0)
-               return Items[sel].first;
-       else
-               return nullptr;
-}
-
-void InventorySystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
-{
-       (void)en;
-       (void)ev;
-       (void)dt;
-}
-
-void InventorySystem::configure(entityx::EventManager &em)
-{
-       em.subscribe<MouseScrollEvent>(*this);
-}
-
-void InventorySystem::receive(const MouseScrollEvent &mse)
-{
-       static int mouseWheelUpCount = 0, mouseWheelDownCount = 0;
-
-       if ((mse.scrollDistance < 0) && ((++mouseWheelUpCount % 5) == 0) ) {
-               mouseWheelUpCount = 0;
-               player->inv->setSelectionUp();
-       } else if ( (++mouseWheelDownCount % 5) == 0 ) {
-               mouseWheelDownCount = 0;
-               player->inv->setSelectionDown();
-       }
-}
diff --git a/src/items.cpp.bak b/src/items.cpp.bak
deleted file mode 100644 (file)
index 180c5fa..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-#include <inventory.hpp>
-#include <entities.hpp>
-#include <world.hpp>
-
-extern Player *player;
-extern World *currentWorld;
-
-/************************************************************************************
-*                                          GLOBAL                                   *
-************************************************************************************/
-
-/**************************************************
-*                    USE ITEM                     *
-**************************************************/
-
-int BaseItem::useItem()
-{
-       return 0;
-}
-
-int Sword::useItem()
-{
-    if (inUse())
-               return -1;
-
-       std::thread([this]{
-               setUse(true);
-               volatile bool swing = true;
-               bool back = false;
-               float coef = 0.0f;
-
-               while (swing) {
-
-                       // handle swinging
-                       if (!back)
-                               coef += .8f;
-                       else
-                               coef -= .4f;
-
-                       if (player->left)
-                               rotation = coef;
-                       else
-                               rotation = -coef;
-
-                       if (coef > 80 && !back)
-                               back = true;
-
-                       if (coef <= 0 && back) {
-                               swing = false;
-                               coef = 0.0f;
-                               rotation = 0.0f;
-                       }
-
-                       if (!back) {
-                               // handle collision with interaction
-                               hitbox.start.y = player->loc.y+(player->height/3);
-                               hitbox.start.x = player->left ? player->loc.x : player->loc.x + player->width;
-
-                               for (auto &e : interact) {
-                                       float dist = 0.0f;
-                                       while (dist < dim.y) {
-                                               hitbox.end = hitbox.start;
-                                               if (player->left)
-                                                       hitbox.end.x -= dist * cos(rotation*PI/180);
-                                               else 
-                                                       hitbox.end.x += dist * cos(rotation*PI/180);
-
-                                               hitbox.end.y += dist * sin(rotation*PI/180);
-
-                                               if (hitbox.end.x > e->loc.x && hitbox.end.x < e->loc.x + e->width) {
-                                                       if (hitbox.end.y > e->loc.y && hitbox.end.y < e->loc.y + e->height) {
-                                                               if (e->type == MOBT)
-                                                                       Mobp(e)->onHit(damage);
-                                                               else
-                                                                       e->takeHit(damage, 600);
-
-                                                               // add some blood
-                                                               //for(int r = 0; r < (rand()%5);r++)
-                                                                       //currentWorld->addParticle(rand()%game::HLINE*3 + e->loc.x - .05f,e->loc.y + e->height*.5, game::HLINE,game::HLINE, -(rand()%10)*.01,((rand()%4)*.001-.002), {(rand()%75+10)/100.0f,0,0}, 10000);
-                                                       }
-                                               }
-
-                                               dist += HLINES(0.5f);
-                                       }
-                               }
-                       }
-
-                       // add a slight delay
-                       SDL_Delay(1);
-               }
-               for (auto &e : interact)
-                       e->setCooldown(0);
-               setUse(false);
-       }).detach();
-
-       return 0;
-}
-
-int Arrow::useItem()
-{
-
-       return 0;
-}
-
-int Bow::useItem()
-{
-       if (inUse())
-               return -1;
-
-       std::thread([this](void) {
-               setUse(true);
-
-               static Particles* part = nullptr;
-
-               if (part == nullptr) {
-                       float rot = atan(sqrt(pow(ui::mouse.y-(player->loc.y + player->height),2)/pow(ui::mouse.x-player->loc.x,2)));
-                       float speed = 1.0;
-                       float vx = speed * cos(rot);
-                       float vy = speed * sin(rot);
-
-                       vx *= (ui::mouse.x < player->loc.x) ? -1 : 1;
-                       vy *= (ui::mouse.y < player->loc.y + player->height) ? -1 : 1;
-
-                       currentWorld->addParticle(player->loc.x,                                        // x
-                                                                         player->loc.y + player->height,       // y
-                                                                         HLINES(3),                                            // width
-                                                                         HLINES(3),                                            // height
-                                                                         vx,                                                           // vel.x
-                                                                         vy,                                                           // vel.y
-                                                                         {139, 69, 19},                                        // RGB color
-                                                                         2500                                                          // duration (ms)
-                                                                         );
-                       part = &currentWorld->particles.back();
-               } else {
-                       if (part->vel.x < 0.05 && part->vel.y < 0.05) {
-                               part->duration = 0;
-                               part = nullptr;
-                       }
-               }
-
-               setUse(false);
-       }).detach();
-
-       return 0;
-}
-
-// TODO chance to hurt
-int RawFood::useItem()
-{
-       return 0;
-}
-
-int Food::useItem()
-{
-    std::cout << "Yum!" << std::endl;
-       return 0;
-}
-
-int ItemLight::useItem()
-{
-       if (player->light.radius > 0)
-               player->light.radius = 0;
-       else
-               player->light.radius = 500;
-       return 0;
-}
-
-/**************************************************
-*                       CLONE                     *
-**************************************************/
-
-BaseItem* BaseItem::clone()
-{
-       return new BaseItem(*this);
-}
-
-Sword* Sword::clone()
-{
-       return new Sword(*this);
-}
-
-Arrow* Arrow::clone()
-{
-       return new Arrow(*this);
-}
-
-Bow* Bow::clone()
-{
-       return new Bow(*this);
-}
-
-Food* Food::clone()
-{
-       return new Food(*this);
-}
-
-RawFood* RawFood::clone()
-{
-       return new RawFood(*this);
-}
-
-ItemLight* ItemLight::clone()
-{
-       return new ItemLight(*this);
-}
-/************************************************************************************
-*                                    ITEM SPECIFIC                                  *
-************************************************************************************/
-
-/**************************************************
-*                      ITEM                       *
-**************************************************/
-
-bool Item::inUse()
-{
-       return beingUsed;
-}
-
-void Item::setUse(bool use)
-{
-       beingUsed = use;
-}
-
-void Item::addInteract(Entity* e)
-{
-       interact.push_back(e);
-}
-
-void Item::addInteract(std::vector<Entity*> e)
-{
-       for (auto &v : e) {
-               interact.push_back(v);
-       }
-}
-
-GLuint Item::rtex()
-{
-       return tex->image[0];
-}
-
-GLuint Item::rtex(int n)
-{
-       return tex->image[n];
-}
-
-Item::~Item()
-{
-       delete tex;
-}
-
-/**************************************************
-*                      SWORD                      *
-**************************************************/
-
-float Sword::getDamage()
-{
-       return damage;
-}
-
-void Sword::setDamage(float d)
-{
-       damage = d;
-}
-
-/**************************************************
-*                      ARROW                      *
-**************************************************/
-
-float Arrow::getDamage()
-{
-       return damage;
-}
-
-void Arrow::setDamage(float d)
-{
-       damage = d;
-}
-
-
-/**************************************************
-*                      BOW                        *
-**************************************************/
-
-float Bow::getDamage()
-{
-       return damage;
-}
-
-void Bow::setDamage(float d)
-{
-       damage = d;
-}
-
-/**************************************************
-*                      FOODS                      *
-**************************************************/
-
-float RawFood::getHealth()
-{
-       return health;
-}
diff --git a/src/mob.cpp.bak b/src/mob.cpp.bak
deleted file mode 100644 (file)
index e78e5cd..0000000
+++ /dev/null
@@ -1,539 +0,0 @@
-#include <mob.hpp>
-#include <ui.hpp>
-#include <world.hpp>
-#include <brice.hpp>
-
-extern World *currentWorld;
-
-Mob::Mob(void)
-{
-    type = MOBT;
-       inv = nullptr;
-    rider = nullptr;
-       xmle = nullptr;
-    canMove = true;
-       loc = 0;
-}
-
-Page::Page(void) : Mob()
-{
-
-    ridable = false;
-    aggressive = false;
-    maxHealth = health = 50;
-    width = HLINES(6);
-    height = HLINES(4);
-    tex = TextureIterator({"assets/items/ITEM_PAGE.png"});
-    pageTexture = 0;
-}
-
-void Page::act(void)
-{
-    if (player->loc.x > loc.x - 100 && player->loc.x < loc.x + 100 && isInside(ui::mouse) &&
-        (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT))) {
-        std::thread([this](void){
-            ui::drawPage(pageTexture);
-            ui::waitForDialog();
-                       game::setValue(cId, cValue);
-                       game::briceUpdate();
-            die();
-        }).detach();
-    }
-}
-
-void Page::onHit(unsigned int _health)
-{
-       (void)_health;
-       act();
-}
-
-bool Page::bindTex(void)
-{
-    glActiveTexture(GL_TEXTURE0);
-    tex(0);
-    return true;
-}
-
-void Page::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)w;
-    float Xlocx;
-    if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
-        loc.x = Xlocx;
-    pageTexPath = e->StrAttribute("id");
-    pageTexture = Texture::loadTexture(pageTexPath);
-
-       cId = e->StrAttribute("cid");
-       cValue = e->StrAttribute("cvalue");
-
-       xmle = e;
-}
-
-void Page::saveToXML(void)
-{}
-
-Door::Door(void) : Mob()
-{
-    ridable = false;
-    aggressive = false;
-    maxHealth = health = 50;
-    width = HLINES(12);
-    height = HLINES(20);
-    tex = TextureIterator({"assets/style/classic/door.png"});
-}
-
-void Door::act(void)
-{
-}
-
-void Door::onHit(unsigned int _health)
-{
-       (void)_health;
-}
-
-bool Door::bindTex(void)
-{
-    glActiveTexture(GL_TEXTURE0);
-    tex(0);
-    return true;
-}
-
-void Door::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)w;
-    float Xlocx;
-    if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
-        loc.x = Xlocx;
-}
-
-void Door::saveToXML(void)
-{}
-
-Cat::Cat(void) : Mob()
-{
-    ridable = true;
-    aggressive = false;
-    maxHealth = health = 100000;
-    width  = HLINES(19);
-    height = HLINES(15);
-    tex = TextureIterator({"assets/cat.png"});
-    actCounterInitial = 0;
-    actCounter = 1;
-}
-
-void Cat::act(void)
-{
-    static float vely = 0;
-    if (rider != nullptr) {
-        if (!rider->ground) {
-            loc.y += HLINES(2);
-            vel.y = .4;
-        }
-        if (rider->speed > 1) {
-            vely = .5;
-        } else if (rider->speed == .5) {
-            vely = -.5;
-        } else {
-            vely = 0;
-        }
-        vel.y = vely;
-        if (!rider->ground) {
-            if ((vel.y -= .015) < -.2)
-                rider->ground = true;
-        }
-        vel.x = .1 * (rider->left ? -1 : 1);
-    } else {
-        vel = 0;
-    }
-}
-
-void Cat::onHit(unsigned int _health)
-{
-       health += _health;
-}
-
-bool Cat::bindTex(void)
-{
-       glActiveTexture(GL_TEXTURE0);
-    tex(0);
-       return true;
-}
-
-void Cat::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)w;
-    float spawnc;
-
-    if (e->QueryFloatAttribute("x", &spawnc) == XML_NO_ERROR)
-        loc.x = spawnc;
-       else
-               loc.x = e->FloatAttribute("spawnx");
-
-       if (e->QueryFloatAttribute("y", &spawnc) == XML_NO_ERROR)
-               loc.y = spawnc;
-
-       xmle = e;
-}
-
-void Cat::saveToXML(void)
-{
-       E_SAVE_COORDS;
-       xmle->SetAttribute("alive", alive);
-}
-
-Rabbit::Rabbit(void) : Mob()
-{
-    ridable = true;
-    aggressive = false;
-    maxHealth = health = 50;
-    width  = HLINES(10);
-    height = HLINES(8);
-    tex = TextureIterator({"assets/rabbit.png", "assets/rabbit1.png"});
-    actCounterInitial = randGet() % 240 + 15;
-    actCounter = 1;
-
-       drop = {
-               std::make_tuple("Dank MayMay", 5, 1.00f)
-       };
-}
-
-void Rabbit::act(void)
-{
-    static int direction = 0;
-
-    if (!--actCounter) {
-        actCounter = actCounterInitial;
-        direction = (randGet() % 3 - 1);       //sets the direction to either -1, 0, 1
-        if (direction == 0)
-            ticksToUse /= 2;
-        vel.x *= direction;
-    }
-
-    if (ground && direction) {
-        ground = false;
-        vel.y = .15;
-        loc.y += HLINES(0.25f);
-        vel.x = 0.05f * direction;
-    }
-}
-
-void Rabbit::onHit(unsigned int _health)
-{
-       takeHit(_health, 600);
-}
-
-bool Rabbit::bindTex(void)
-{
-    glActiveTexture(GL_TEXTURE0);
-    tex(!ground);
-    return true;
-}
-
-void Rabbit::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)w;
-    float spawnc;
-
-       xmle = e;
-
-    if (e->QueryFloatAttribute("x", &spawnc) == XML_NO_ERROR)
-        loc.x = spawnc;
-       else
-               loc.x = e->FloatAttribute("spawnx");
-
-       if (e->QueryFloatAttribute("y", &spawnc) == XML_NO_ERROR)
-               loc.y = spawnc;
-
-       E_LOAD_HEALTH;
-       
-       if (e->QueryBoolAttribute("aggressive", &aggressive) != XML_NO_ERROR)
-               aggressive = false;
-}
-
-void Rabbit::saveToXML(void)
-{
-       E_SAVE_HEALTH;
-}
-
-Bird::Bird(void) : Mob()
-{
-    ridable = true;
-    aggressive = false;
-    maxHealth = health = 50;
-    width = HLINES(8);
-    height = HLINES(8);
-    tex = TextureIterator({"assets/robin.png"});
-    actCounterInitial = actCounter = 200;
-}
-
-void Bird::act(void)
-{
-    static bool direction = false;
-    static const float wstart = currentWorld->getWorldStart();
-
-    if (!--actCounter) {
-        actCounter = actCounterInitial;
-        direction ^= 1;
-    }
-
-    if (loc.x > -wstart - HLINES(10.0f))
-        loc.x = wstart + HLINES(10.0f);
-    else if (loc.x < wstart + HLINES(10.0f))
-        loc.x = -wstart - HLINES(10.0f);
-
-    if (loc.y <= initialY)
-        vel.y = 0.3f;
-    vel.x = direction ? -0.3f : 0.3f;
-}
-
-void Bird::onHit(unsigned int _health)
-{
-       takeHit(_health, 1000);
-}
-
-bool Bird::bindTex(void)
-{
-    glActiveTexture(GL_TEXTURE0);
-    tex(0);
-    return true;
-}
-
-void Bird::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)w;
-    float Xlocx;
-
-       xmle = e;
-
-       if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
-               loc.x = Xlocx;
-       if (e->QueryFloatAttribute("y", &initialY) != XML_NO_ERROR)
-               initialY = 300;
-
-       E_LOAD_HEALTH;
-
-    if (e->QueryBoolAttribute("aggressive", &aggressive) != XML_NO_ERROR)
-        aggressive = false;
-}
-
-void Bird::saveToXML(void)
-{
-       E_SAVE_COORDS;
-       E_SAVE_HEALTH;
-}
-
-Trigger::Trigger(void) : Mob()
-{
-    ridable = false;
-    aggressive = false;
-    maxHealth = health = 50;
-    width = HLINES(20);
-    height = 2000;
-    //tex = TextureIterator();
-    triggered = false;
-       notext = false;
-}
-
-void Trigger::act(void)
-{
-    auto c = player->loc.x + player->width / 2;
-    static bool running = false;
-
-    if (triggered) {
-        die();
-    } else if (!running && c > loc.x && c < loc.x + width) {
-        std::thread([&]{
-            running = true;
-
-            XMLDocument xml;
-            XMLElement *exml;
-
-            xml.LoadFile(currentXML.c_str());
-            exml = xml.FirstChildElement("Trigger");
-
-            while(exml && exml->StrAttribute("id") != id)
-                exml = exml->NextSiblingElement();
-
-            player->vel.x = 0;
-
-                       if (notext) {
-                               for (auto &e : currentWorld->entity) {
-                                       if (e->type == NPCT && e->name == exml->GetText()) {
-                                               e->interact();
-                                               break;
-                                       }
-                               }
-                       } else {
-
-                       /*if (exml == nullptr) {
-                               auto id = xmle->StrAttribute("cid");
-                               if (!id.empty()) {
-                                       game::setValue(id, xmle->StrAttribute("cvalue"));
-                                       game::briceUpdate();
-                               }
-                               return;
-                       }*/
-
-                   ui::toggleBlackFast();
-                   ui::waitForCover();
-
-               std::string text = exml->GetText();
-                   char *pch = strtok(&text[0], "\n");
-
-                   while (pch) {
-                       ui::importantText(pch);
-                       ui::waitForDialog();
-                       pch = strtok(NULL, "\n");
-                   }
-
-               ui::toggleBlackFast();
-                       }
-
-            triggered = true;
-            running = false;
-        }).detach();
-    }
-}
-
-void Trigger::onHit(unsigned int _health)
-{
-       (void)_health;
-}
-
-bool Trigger::bindTex(void)
-{
-    return false;
-}
-
-void Trigger::createFromXML(XMLElement *e, World *w=nullptr)
-{
-       (void)w;
-       float Xlocx;
-
-       if (e->QueryFloatAttribute("spawnx", &Xlocx) == XML_NO_ERROR)
-               loc.x = Xlocx;
-
-       if (e->QueryBoolAttribute("notext", &notext) != XML_NO_ERROR)
-               notext = false;
-
-       id = e->StrAttribute("id");
-
-       xmle = e;
-}
-
-void Trigger::saveToXML(void)
-{}
-
-Chest::Chest(void) : Mob()
-{
-    ridable = false;
-    aggressive = false;
-    maxHealth = health = 100;
-    width = HLINES(10);
-    height = HLINES(5);
-    tex = TextureIterator({"assets/chest.png"});
-       inv = new Inventory(1);
-}
-
-void Chest::act(void)
-{
-       if (isInside(ui::mouse) && player->isNear(this)) {
-               if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) && !ui::dialogBoxExists)
-                       for (auto &i : inv->Items) {
-                               player->inv->addItem(i.first->name, i.second);
-                               inv->takeItem(i.first->name, i.second);
-                       }
-       }
-
-       for (auto &e : currentWorld->entity) {
-               if (e->type == OBJECTT && e->isNear(this)) {
-                       auto o = dynamic_cast<Object *>(e);
-                       inv->addItem(o->iname, 1);
-                       e->health = 0;
-               }
-       }
-}
-
-void Chest::onHit(unsigned int _health)
-{
-       (void)_health;
-       die();
-}
-
-bool Chest::bindTex(void)
-{
-    glActiveTexture(GL_TEXTURE0);
-    tex(0);
-    return true;
-}
-
-void Chest::createFromXML(XMLElement *e, World *w)
-{
-       (void)w;
-       loc = vec2 { 0, 100 };
-       xmle = e;
-}
-
-void Chest::saveToXML(void)
-{
-       xmle->SetAttribute("alive", alive);
-}
-
-
-
-Mob::~Mob()
-{
-       delete inv;
-}
-
-extern World *currentWorld;
-extern Arena *arena;
-
-void Mob::wander(void)
-{
-       static bool YAYA = false;
-
-    if (forcedMove)
-               return;
-
-    if (aggressive && !YAYA && isInside(vec2 {player->loc.x + width / 2, player->loc.y + height / 4})) {
-               if (!ui::dialogBoxExists) {
-            std::thread([&](void){
-                           arena->fight(currentWorld, player, this);
-                           ui::toggleWhiteFast();
-                           YAYA = true;
-                           ui::waitForCover();
-                           YAYA = false;
-                           currentWorld = arena;
-                           ui::toggleWhiteFast();
-            }).detach();
-               }
-       }
-    act();
-}
-
-void Mob::ride(Entity *e)
-{
-    if (!ridable)
-        return;
-
-    if (rider == e)
-        rider = nullptr;
-    else
-        rider = e;
-}
-
-void Mob::onDeath(void)
-{
-       vec2 q = vec2 {player->loc.x, game::SCREEN_HEIGHT - 100.0f};
-
-       ui::putTextL(q, "Player got: ");
-
-       for (const auto &d : drop) {
-               if ((randGet() % 100) < std::get<float>(d) * 100.0f) {
-                       q.y -= 20;
-                       ui::putTextL(q, "%d x %s", std::get<unsigned int>(d), std::get<std::string>(d).c_str());
-                       player->inv->addItem(std::get<std::string>(d), std::get<unsigned int>(d));
-               }
-       }
-}
diff --git a/src/old/entities.cpp.bak b/src/old/entities.cpp.bak
new file mode 100644 (file)
index 0000000..25dd379
--- /dev/null
@@ -0,0 +1,1371 @@
+#include <entities.hpp>
+
+#include <istream>
+#include <sstream>
+#include <fstream>
+
+#include <ui.hpp>
+#include <world.hpp>
+#include <gametime.hpp>
+#include <brice.hpp>
+
+#include <render.hpp>
+#include <engine.hpp>
+
+///NEW
+#include <components.hpp>
+#include <entityx/entityx.h>
+///OLD
+
+extern std::istream *names;
+
+extern Player *player;                 // main.cpp
+extern World *currentWorld;            // main.cpp
+extern unsigned int loops;             // main.cpp
+
+extern std::string xmlFolder;
+extern XMLDocument currentXMLDoc;
+
+// a dynamic array of pointers to the NPC's that are being assigned the preloads
+std::vector<NPC *> aipreload;
+
+// the size of the player's inventory
+const unsigned int PLAYER_INV_SIZE = 43;
+// the size of an NPC's inventory
+const unsigned int NPC_INV_SIZE = 3;
+
+static std::vector<std::string> randomDialog (readFileA("assets/dialog_en-us"));
+
+
+void PlayerSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
+{
+       (void)en;
+       (void)ev;
+       (void)dt;
+
+       if (!m_MoveLeft && !m_MoveRight)
+               (*m_Player)->vel.x = 0;
+}
+
+void PlayerSystem::configure(entityx::EventManager &ev)
+{
+       ev.subscribe<KeyDownEvent>(*this);
+       ev.subscribe<KeyUpEvent>(*this);
+}
+
+extern World  *currentWorldToLeft;
+extern World  *currentWorldToRight;
+extern bool gameRunning;
+extern bool inBattle;
+
+void PlayerSystem::receive(const KeyUpEvent &kue)
+{
+       auto p = *m_Player;
+       auto kc = kue.keycode;
+
+       if (kc == SDLK_ESCAPE) {
+               ui::menu::toggle();
+               p->save();
+       } else if (kc == getControl(1)) {
+               m_MoveLeft = false;
+       } else if (kc == getControl(2)) {
+               m_MoveRight = false;
+       } else if (kc == getControl(3) || kc == getControl(4)) {
+               player->speed = 1;
+       } else if (kc == getControl(5)) {
+               if (p->inv->invHover) {
+                       p->inv->invHover = false;
+               } else {
+                       if (!p->inv->selected)
+                               p->inv->invOpening ^= true;
+                       else
+                               p->inv->selected = false;
+
+                       p->inv->mouseSel = false;
+               }
+
+               // disable action ui
+               ui::action::disable();
+       }
+}
+
+void PlayerSystem::receive(const KeyDownEvent &kde)
+{
+       auto p = *m_Player;
+       auto kc = kde.keycode;
+
+       auto worldSwitch = [&](const WorldSwitchInfo& wsi){
+               player->canMove = false;
+               ui::toggleBlackFast();
+               ui::waitForCover();
+               game::events.emit<BGMToggleEvent>(wsi.first->bgm, wsi.first);
+               std::tie(currentWorld, player->loc) = wsi; // using p causes segfault
+               game::engine.getSystem<WorldSystem>()->setWorld(currentWorld);
+               ui::toggleBlackFast();
+               ui::waitForUncover();
+               player->canMove = true; // using p causes segfault
+       };
+
+       if ((kc == SDLK_SPACE) && (game::canJump & p->ground)) {
+               p->loc.y += HLINES(2);
+               p->vel.y = .4;
+               p->ground = false;
+       }
+
+       if (!ui::dialogBoxExists || ui::dialogPassive) {
+               if (kc == getControl(0)) {
+                       if (inBattle) {
+                               std::thread([&](void){
+                                       auto thing = dynamic_cast<Arena *>(currentWorld)->exitArena(p);
+                                       if (thing.first != currentWorld)
+                                               worldSwitch(thing);
+                               }).detach();
+                       } else if (!ui::fadeIntensity) {
+                               std::thread([&](void){
+                                       auto thing = currentWorld->goInsideStructure(p);
+                                       if (thing.first != currentWorld)
+                                               worldSwitch(thing);
+                               }).detach();
+                       }
+               } else if (kc == getControl(1)) {
+                       if (!ui::fadeEnable) {
+                               p->vel.x = -PLAYER_SPEED_CONSTANT;
+                               if (std::stoi(game::getValue("Slow")) == 1)
+                                       p->vel.x /= 2.0f;
+                               p->left = m_MoveLeft = true;
+                               p->right = m_MoveRight = false;
+                               if (currentWorldToLeft) {
+                                       std::thread([&](void){
+                                               auto thing = currentWorld->goWorldLeft(p);
+                                               if (thing.first != currentWorld)
+                                                       worldSwitch(thing);
+                                       }).detach();
+                               }
+                       }
+               } else if (kc == getControl(2)) {
+                       if (!ui::fadeEnable) {
+                               p->vel.x = PLAYER_SPEED_CONSTANT;
+                               if (std::stoi(game::getValue("Slow")) == 1)
+                                       p->vel.x /= 2.0f;
+                               p->right = m_MoveRight = true;
+                               p->left = m_MoveLeft = false;
+                               if (currentWorldToRight) {
+                                       std::thread([&](void){
+                                               auto thing = currentWorld->goWorldRight(p);
+                                               if (thing.first != currentWorld)
+                                                       worldSwitch(thing);
+                                       }).detach();
+                               }
+                       }
+               } else if (kc == getControl(3)) {
+                       if (game::canSprint)
+                               p->speed = 2.0f;
+               } else if (kc == getControl(4)) {
+                       p->speed = .5;
+               } else if (kc == getControl(5)) {
+                       /*static int heyOhLetsGo = 0;
+
+                       //edown = true;
+
+                       // start hover counter?
+                       if (!heyOhLetsGo) {
+                               heyOhLetsGo = game::time::getTickCount();
+                               p->inv->mouseSel = false;
+                       }
+
+                       // run hover thing
+                       if (game::time::getTickCount() - heyOhLetsGo >= 2 && !(p->inv->invOpen) && !(p->inv->selected)) {
+                               p->inv->invHover = true;
+
+                               // enable action ui
+                               ui::action::enable();
+                       }*/
+               }
+       } else if (kc == SDLK_DELETE) {
+               game::endGame();
+       } else if (kc == SDLK_t) {
+               game::time::tick(50);
+       }
+}
+
+
+void getRandomName(Entity *e)
+{
+       auto names = readFileA("assets/names_en-us");
+       auto name = names[randGet() % names.size()];
+
+       // gender is a binary construct
+       e->gender = (name[0] == 'm') ? MALE : FEMALE;
+
+       e->name = &name[1];
+}
+
+Entity::Entity(void)
+{
+       vel = 0;
+       width = 0;
+       height = 0;
+       health = 0;
+       maxHealth = 0;
+       outnabout = 0;
+       targetx = 0.9112001f;
+
+       type = UNKNOWNT;
+
+       // set flags
+       alive      = true;
+       right      = true;
+       left       = false;
+       near       = false;
+       canMove    = true;
+       ground     = false;
+       forcedMove = false;
+       z = 0.0f;
+
+       // clear counters
+       ticksToUse = 0;
+       hitCooldown = 0;
+
+       hitDuration = maxHitDuration = 0;
+
+       inv = nullptr;
+}
+
+// spawns the entity you pass to it based off of coords and global entity settings
+void Entity::spawn(float x, float y)
+{
+       loc.x = x;
+       loc.y = y;
+
+       if (health == 0 && maxHealth == 0)
+               health = maxHealth = 1;
+
+       // generate a name
+       if (type == MOBT)
+               name = "mob";
+       else
+               getRandomName(this);
+
+       setCooldown(0);
+}
+
+void Entity::takeHit(unsigned int _health, unsigned int cooldown)
+{
+       if (hitCooldown <= 1) {
+               // modify variables
+               health = fmax(health - _health, 0);
+               forcedMove = true;
+               hitCooldown = cooldown;
+
+               hitDuration = maxHitDuration = 350.0f;
+
+               // pushback
+               vel.x = player->left ? -0.5f : 0.5f;
+               vel.y = 0.2f;
+       }
+}
+
+unsigned int Entity::coolDown()
+{
+       return hitCooldown;
+}
+
+void Entity::setCooldown(unsigned int c)
+{
+       hitCooldown = c;
+}
+
+void Entity::handleHits(void)
+{
+       hitCooldown = fmax(static_cast<int>(hitCooldown - game::time::getDeltaTime()), 0);
+       hitDuration = fmax(hitDuration - game::time::getDeltaTime(), 0);
+
+       if (!forcedMove)
+               return;
+
+       // reduce knockback
+       if ((vel.x > 0.0005f) || (vel.x < -0.0005f))
+               vel.x *= 0.6f;
+       else
+               forcedMove = false;
+}
+
+void Entity::die(void)
+{
+       alive = false;
+       health = 0;
+
+       /*if (xmle) {
+               xmle->SetAttribute("alive", false);
+               currentXMLDoc.SaveFile(currentXML.c_str(), false);
+       }*/
+}
+
+bool Entity::isAlive(void) const
+{
+       return alive;
+}
+
+bool Entity::isHit(void) const
+{
+       return forcedMove;
+}
+
+void Entity::moveTo(float dest_x)
+{
+       targetx = dest_x;
+}
+
+Player::Player() : Entity()
+{
+       width = HLINES(10);
+       height = HLINES(16);
+
+       type = PLAYERT; //set type to player
+       subtype = 0;
+       health = maxHealth = 100;
+       speed = 1;
+       canMove = true;
+
+       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);
+       dim2 tmpDim = Texture::imageDim(tex.getTexturePath(0));
+       width = HLINES(tmpDim.x/2);
+       height = HLINES(tmpDim.y/2);
+
+       z = -2.0;
+}
+
+Player::~Player()
+{
+       delete inv;
+       delete &tex;
+}
+
+void Player::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)e;
+       (void)w;
+}
+
+void Player::saveToXML(void)
+{}
+
+NPC::NPC() : Entity()
+{
+       width = HLINES(10);
+       height = HLINES(16);
+
+       type    = NPCT; //sets type to npc
+       subtype = 0;
+
+       health = maxHealth = 100;
+
+       maxHealth = health = 100;
+       canMove = true;
+
+       tex = TextureIterator({"assets/NPC.png"});
+       inv = new Inventory(NPC_INV_SIZE);
+
+       randDialog = randGet() % randomDialog.size();
+       dialogIndex = 0;
+       dialogCount = 0;
+
+       dim2 tmpDim = Texture::imageDim(tex.getTexturePath(0));
+       width = HLINES(tmpDim.x/2);
+       height = HLINES(tmpDim.y/2);
+}
+
+NPC::~NPC()
+{
+       delete inv;
+}
+
+void NPC::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       std::string npcname;
+       bool dialog;
+       unsigned int flooor;
+
+       xmle = e;
+       (void)w;
+
+    // spawn at coordinates if desired
+       E_LOAD_COORDS(100);
+
+    // name override
+       if (!(npcname = e->StrAttribute("name")).empty())
+               name = npcname;
+
+    // dialog enabling
+       dialog = false;
+       if (e->QueryBoolAttribute("hasDialog", &dialog) == XML_NO_ERROR && dialog)
+               addAIFunc(false);
+       else
+        dialogIndex = 9999;
+
+    // custom health value
+       E_LOAD_HEALTH;
+
+       // movemenet
+       if (e->QueryBoolAttribute("canMove", &dialog) == XML_NO_ERROR)
+               canMove = dialog;
+
+       // dialog index
+       if (e->QueryUnsignedAttribute("dindex", &flooor) == XML_NO_ERROR)
+               dialogIndex = flooor;
+}
+
+void NPC::saveToXML(void)
+{
+       E_SAVE_HEALTH;
+       E_SAVE_COORDS;
+       xmle->SetAttribute("dindex", dialogIndex);
+}
+
+Merchant::Merchant() : NPC()
+{
+       width = HLINES(10);
+       height = HLINES(16);
+
+       type    = MERCHT; //sets type to merchant
+       subtype = 0;
+
+       health = maxHealth = 100;
+
+       canMove = true;
+
+       trade.reserve(100);
+       currTrade = 0;
+
+       inside = nullptr;
+
+       //tex = new Texturec(1,"assets/NPC.png");
+       //inv = new Inventory(NPC_INV_SIZE);
+       //inv = new Inventory(1);
+
+       //randDialog = rand() % RAND_DIALOG_COUNT - 1;
+       dialogIndex = 0;
+
+       dim2 tmpDim = Texture::imageDim(tex.getTexturePath(0));
+       width = HLINES(tmpDim.x/2);
+       height = HLINES(tmpDim.y/2);
+}
+
+Merchant::~Merchant()
+{
+}
+
+void Merchant::saveToXML(void){}
+
+Structures::Structures() : Entity()
+{
+       type = STRUCTURET;
+       canMove = false;
+       health = maxHealth = 1;
+}
+
+Structures::~Structures()
+{
+}
+
+extern std::string currentXMLRaw;
+
+void Structures::createFromXML(XMLElement *e, World *w)
+{
+       float spawnx;
+
+       if (e->QueryBoolAttribute("alive", &alive) == XML_NO_ERROR && !alive) {
+               //die();
+               return;
+       }
+
+       inWorld = w;
+       inside = e->StrAttribute("inside");
+
+       // edge
+       if (!inside.empty()) {
+               insideWorld = loadWorldFromXMLNoTakeover(inside);
+       }
+
+       textureLoc = e->StrAttribute("texture");
+
+       insideTex = Texture::loadTexture(e->StrAttribute("insideTexture"));
+
+       spawn(static_cast<BUILD_SUB>(e->UnsignedAttribute("type")),
+             e->QueryFloatAttribute("spawnx", &spawnx) == XML_NO_ERROR ? spawnx : (randGet() % w->getTheWidth() / 2.0f),
+             100);
+
+       xmle = e;
+}
+
+void Structures::saveToXML(void)
+{
+       xmle->SetAttribute("alive", alive);
+}
+
+Object::Object()
+{
+       type = OBJECTT;
+}
+
+Object::Object(std::string in, std::string pd)
+{
+       iname = in;
+
+       pickupDialog = pd;
+       questObject = !pd.empty();
+
+       type = OBJECTT;
+       width  = getItemWidth(in);
+       height = getItemHeight(in);
+
+       tex = TextureIterator({getItemTexturePath(in)});
+}
+
+Object::~Object()
+{
+}
+
+void Object::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)e;
+       (void)w;
+}
+
+void Object::saveToXML(void)
+{}
+
+void Object::reloadTexture(void)
+{
+       tex = TextureIterator({getItemTexturePath(iname)});
+       width  = getItemWidth(iname);
+       height = getItemHeight(iname);
+}
+
+bool Entity::isNear(const Entity *e) {
+       return (e != nullptr) ? (pow(e->loc.x - loc.x, 2) + pow(e->loc.y - loc.y, 2) <= pow(HLINES(40), 2)) : false;
+}
+
+void NPC::drawThingy(void) const
+{
+       if (dialogCount) {
+               const auto w = width / 3;
+               GLfloat tex_coord[] = {
+                       0, 0, 1, 0, 1, 1,
+                       1, 1, 0, 1, 0, 0
+               };
+               const GLfloat c[4] = {
+                       loc.x + w, loc.y + height, loc.x + w * 2, loc.y + height + w
+               };
+               GLfloat coords[] = {
+                       c[0], c[1], z, c[2], c[1], z, c[2], c[3], z,
+                       c[2], c[3], z, c[0], c[3], z, c[0], c[1], z
+               };
+
+               // TODO use texture made for this
+               static GLuint thingyColor = Texture::genColor(Color(236, 238, 15));
+
+               Render::worldShader.use();
+               Render::worldShader.enable();
+
+               glBindTexture(GL_TEXTURE_2D, thingyColor);
+
+               glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords);
+               glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex_coord);
+               glDrawArrays(GL_TRIANGLES, 0, 6);
+
+               Render::worldShader.disable();
+               Render::worldShader.unuse();
+       }
+}
+
+void Entity::draw(void)
+{
+       GLfloat tex_coord[] = {0.0, 0.0,
+                                                  1.0, 0.0,
+                                                  1.0, 1.0,
+
+                                                  1.0, 1.0,
+                                                  0.0, 1.0,
+                                                  0.0, 0.0};
+
+       GLfloat tex_coordL[] = {1.0, 0.0,
+                                                       0.0, 0.0,
+                                                       0.0, 1.0,
+
+                                                       0.0, 1.0,
+                                                       1.0, 1.0,
+                                                       1.0, 0.0};
+
+       GLfloat coords[] = {loc.x, loc.y, z,
+                                               loc.x + width, loc.y, z,
+                                               loc.x + width, loc.y + height, z,
+
+                                               loc.x + width, loc.y + height, z,
+                                               loc.x, loc.y + height, z,
+                                               loc.x, loc.y, z};
+
+
+       glActiveTexture(GL_TEXTURE0);
+
+       if (!alive)
+               return;
+
+       if (type == NPCT) {
+               NPCp(this)->drawThingy();
+
+               if (gender == MALE)
+                       glColor3ub(255, 255, 255);
+               else if (gender == FEMALE)
+                       glColor3ub(255, 105, 180);
+       } else if (type == MOBT) {
+               if (Mobp(this)->rider != nullptr) {
+                       Mobp(this)->rider->loc.x = loc.x + width * 0.25f;
+               Mobp(this)->rider->loc.y = loc.y + height - HLINES(5);
+               Mobp(this)->rider->vel.y = .12;
+                       Mobp(this)->rider->z     = z + 0.01;
+           }
+       }
+       switch(type) {
+       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;
+                       glActiveTexture(GL_TEXTURE0);
+                       tex(texState);
+               }
+               if (!ground) {
+                       glActiveTexture(GL_TEXTURE0);
+                       tex(0);
+               } else if (vel.x) {
+                       glActiveTexture(GL_TEXTURE0);
+                       tex(texState);
+               } else {
+                       glActiveTexture(GL_TEXTURE0);
+                       tex(0);
+               }
+               break;
+       case MOBT:
+               if (!Mobp(this)->bindTex())
+                       goto NOPE;
+               break;
+       case STRUCTURET:
+               /* fall through */
+       default:
+               glActiveTexture(GL_TEXTURE0);
+               tex(0);
+               break;
+       }
+
+       Render::worldShader.use();
+       // make the entity hit flash red
+       if (maxHitDuration-hitDuration) {
+               float flashAmt = 1-(hitDuration/maxHitDuration);
+               glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, flashAmt, flashAmt, 1.0);
+       }
+
+       glUniform1i(Render::worldShader.uniform[WU_texture], 0);
+       Render::worldShader.enable();
+
+       glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords);
+       if (left)
+               glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coordL);
+       else
+               glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coord);
+       glDrawArrays(GL_TRIANGLES, 0, 6);
+
+       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
+NOPE:
+if (near && type != MOBT)
+       ui::putStringCentered(loc.x+width/2,loc.y-ui::fontSize-game::HLINE/2,name);
+if (health != maxHealth) {
+
+       static GLuint frontH = Texture::genColor(Color(255,0,0));
+       static GLuint backH =  Texture::genColor(Color(150,0,0));
+       glUniform1i(Render::worldShader.uniform[WU_texture], 0);
+
+       GLfloat coord_back[] = {
+               loc.x,                  loc.y + height,                               z + 0.1f,
+               loc.x + width,  loc.y + height,                               z + 0.1f,
+               loc.x + width,  loc.y + height + game::HLINE * 2, z + 0.1f,
+
+               loc.x + width,  loc.y + height + game::HLINE * 2, z + 0.1f,
+               loc.x,                  loc.y + height + game::HLINE * 2, z + 0.1f,
+               loc.x,                  loc.y + height,                               z + 0.1f,
+       };
+
+       GLfloat coord_front[] = {
+               loc.x,                                      loc.y + height,                   z,
+               loc.x + health / maxHealth * width, loc.y + height,                   z,
+               loc.x + health / maxHealth * width, loc.y + height + game::HLINE * 2, z,
+
+               loc.x + health / maxHealth * width, loc.y + height + game::HLINE * 2, z,
+               loc.x,                              loc.y + height + game::HLINE * 2, z,
+               loc.x,                              loc.y + height,                   z,
+       };
+
+       glBindTexture(GL_TEXTURE_2D, backH);
+       GLfloat tex[] = { 0.0, 0.0,
+                                         1.0, 0.0,
+                                         1.0, 1.0,
+
+                                         1.0, 1.0,
+                                         0.0, 1.0,
+                                         0.0, 0.0,
+       };
+       glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coord_back);
+       glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex);
+       glDrawArrays(GL_TRIANGLES, 0, 6);
+
+       glBindTexture(GL_TEXTURE_2D, frontH);
+       glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coord_front);
+       glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex);
+       glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+Render::worldShader.disable();
+Render::worldShader.unuse();
+}
+
+/**
+ * Handles NPC movement, usually just random walking.
+ */
+
+void NPC::
+wander(int timeRun)
+{
+       static int direction;
+
+       if (forcedMove)
+               return;
+
+       if (hitCooldown)
+               hitCooldown--;
+
+       if (targetx != 0.9112001f) {
+               if (loc.x > targetx + HLINES(5))
+                       vel.x = HLINES(-0.018);
+               else if (loc.x < targetx - HLINES(5))
+                       vel.x = HLINES(0.018);
+               else {
+                       targetx = 0.9112001f;
+                       vel.x = 0;
+               }
+       } else if (ticksToUse == 0) {
+               ticksToUse = timeRun;
+
+               vel.x = HLINES(0.008);
+               direction = (randGet() % 3 - 1);
+
+               if (direction == 0)
+                       ticksToUse *= 2;
+
+               vel.x *= direction;
+       }
+
+       if (vel.x < 0)
+               currentWorld->goWorldLeft(this);
+
+       ticksToUse--;
+}
+
+void NPC::addAIFunc(bool preload)
+{
+       if (preload)
+               aipreload.push_back(this);
+       else
+               ++dialogCount;
+}
+
+extern int commonAIFunc(NPC *speaker);
+
+void NPC::interact() { //have the npc's interact back to the player
+       std::thread([this]{
+               std::vector<XMLElement *> dopt;
+               XMLDocument *xml;
+               XMLElement *exml,*oxml;
+
+               static unsigned int oldidx = 9999;
+               const char *ptr;
+               std::string nname;
+               unsigned int idx;
+               bool stop;
+               float tgt = 0.12345678f;
+               bool pmove = true, advance = false;
+
+               loc.y += 5;
+
+               // freeze the npc, face the player
+               canMove = false;
+               left    = (player->loc.x < loc.x);
+               right   = !left;
+
+               // if there's actual scripted stuff to do, do it
+               if (dialogCount && dialogIndex != 9999) {
+                       // load the XML file and find the dialog tags
+                       if (outnabout == 0) {
+                               xml = &currentXMLDoc;
+                       } else if (outnabout < 0) {
+                               xml = new XMLDocument();
+                               xml->LoadFile((xmlFolder + currentWorld->getToLeft()).c_str());
+                       } else {
+                               xml = new XMLDocument();
+                               xml->LoadFile((xmlFolder + currentWorld->getToRight()).c_str());
+                       }
+
+COMMONAIFUNC:
+                       idx = 0;
+                       stop = false;
+                       exml = xml->FirstChildElement("Dialog");
+
+                       // search for the dialog block associated with this npc
+                       while (exml->StrAttribute("name") != name)
+                               exml = exml->NextSiblingElement();
+
+                       // search for the desired text block
+                       exml = exml->FirstChildElement();
+                       do {
+                               if (std::string("text") == exml->Name() && exml->UnsignedAttribute("id") == (unsigned)dialogIndex)
+                                       break;
+                       } while ((exml = exml->NextSiblingElement()));
+
+                       // handle quest tags
+                       if ((oxml = exml->FirstChildElement("quest"))) {
+                               std::string qname;
+
+                               // iterate through all quest tags
+                               do {
+                                       // assign quest
+                                       if (!(qname = oxml->StrAttribute("assign")).empty())
+                                               player->qh.assign(qname, oxml->StrAttribute("desc"), (oxml->GetText() == nullptr) ? "" : oxml->GetText());
+
+                                       // check / finish quest
+                                       else if (!(qname = oxml->StrAttribute("check")).empty()) {
+                                               if (player->qh.hasQuest(qname) && player->qh.finish(qname)) {
+                                                       // QuestHandler::finish() did all the work..
+                                                       break;
+                                               } else {
+                                                       // run error dialog
+                                                       oldidx = dialogIndex;
+                                                       dialogIndex = oxml->UnsignedAttribute("fail");
+                                                       goto COMMONAIFUNC;
+                                               }
+                                       }
+                               } while((oxml = oxml->NextSiblingElement("quest")));
+                       }
+
+                       // handle give tags
+                       if ((oxml = exml->FirstChildElement("give"))) {
+                               do player->inv->addItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count"));
+                               while ((oxml = oxml->NextSiblingElement("give")));
+                       }
+
+                       // handle take tags
+                       if ((oxml = exml->FirstChildElement("take"))) {
+                               do player->inv->takeItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count"));
+                               while ((oxml = oxml->NextSiblingElement()));
+                       }
+
+                       // handle movement directs
+                       if ((oxml = exml->FirstChildElement("gotox"))) {
+                               moveTo((tgt = std::stoi(oxml->GetText())));
+                               if (oxml->QueryBoolAttribute("playerMove", &pmove) != XML_NO_ERROR)
+                                       pmove = true;
+                               if (oxml->QueryBoolAttribute("advance", &advance) != XML_NO_ERROR)
+                                       advance = false;
+                       }
+
+                       // handle attribute setting
+                       if ((oxml = exml->FirstChildElement("set"))) {
+                               do game::setValue(oxml->StrAttribute("id"), oxml->StrAttribute("value"));
+                               while ((oxml = oxml->NextSiblingElement()));
+                               game::briceUpdate();
+                       }
+
+                       // asdlfkj
+
+                       auto txml = exml->FirstChildElement("content");
+                       if (txml == nullptr)
+                               goto OTHERSTUFF;
+
+                       ptr = txml->GetText() - 1;
+                       while (*++ptr && isspace(*ptr));
+
+                       // handle dialog options
+                       if ((oxml = exml->FirstChildElement("option"))) {
+                               std::string optstr;
+
+                               // convert option strings to a colon-separated format
+                               do {
+                                       // append the next option
+                                       optstr.append(std::string(":") + oxml->Attribute("text"));
+
+                                       // save the associated XMLElement
+                                       dopt.push_back(oxml);
+                               } while ((oxml = oxml->NextSiblingElement()));
+
+                               // run the dialog stuff
+                               ui::dialogBox(name, optstr, false, ptr);
+                               ui::waitForDialog();
+
+                               if (ui::dialogOptChosen)
+                                       exml = dopt[ui::dialogOptChosen - 1];
+
+                               dopt.clear();
+                       }
+
+                       // optionless dialog
+                       else {
+                               ui::dialogBox(name, "", false, ptr);
+                               ui::waitForDialog();
+                       }
+
+OTHERSTUFF:
+
+                       // trigger other npcs if desired
+                       if (!(nname = exml->StrAttribute("call")).empty()) {
+                               NPC *n = dynamic_cast<NPC *>(*std::find_if(std::begin(currentWorld->entity), std::end(currentWorld->entity), [nname](Entity *e) {
+                                       return (e->type == NPCT && e->name == nname);
+                               }));
+
+                               if (exml->QueryUnsignedAttribute("callid", &idx) == XML_NO_ERROR) {
+                                       n->dialogIndex = idx;
+                                       n->addAIFunc(false);
+                               }
+                       }
+
+                       if (tgt != 0.12345678f) {
+                               stop = canMove;
+                               canMove = true;
+                               while (targetx != 0.9112001f) {
+                                       if (!pmove)
+                                               player->speed = 0;
+                               }
+                               if (!pmove) {
+                                       pmove = true;
+                                       player->speed = 1;
+                               }
+                               canMove = stop;
+                       }
+
+                       // handle potential following dialogs
+                       if ((idx = exml->UnsignedAttribute("nextid"))) {
+                               dialogIndex = idx;
+
+                               // stop talking
+                               if (exml->QueryBoolAttribute("stop", &stop) == XML_NO_ERROR && stop) {
+                                       dialogIndex = 9999;
+                                       dialogCount--;
+                               }
+
+                               // pause, allow player to click npc to continue
+                               else if (exml->QueryBoolAttribute("pause", &stop) == XML_NO_ERROR && stop) {
+                                       //return 1;
+                               }
+
+                               // instantly continue
+                               else {
+                                       goto COMMONAIFUNC;
+                               }
+                       }
+
+                       // advance if desired
+                       else if (advance) {
+                               goto COMMONAIFUNC;
+                       }
+
+                       // stop talking
+                       else {
+                               // error text?
+                               if (oldidx != 9999) {
+                                       dialogIndex = oldidx;
+                                       oldidx = 9999;
+                               } else {
+                                       dialogIndex = 9999;
+                                       dialogCount--;
+                               }
+                       }
+               } else {
+                       ui::dialogBox(name, "", false, randomDialog[randDialog]);
+               }
+
+               ui::waitForDialog();
+               canMove = true;
+       }).detach();
+}
+
+void Merchant::wander(int timeRun) {
+       static int direction;
+
+       if (forcedMove)
+               return;
+
+       if (ticksToUse == 0) {
+               ticksToUse = timeRun;
+
+               vel.x = HLINES(0.008);
+               direction = (randGet() % 3 - 1);
+
+               if (direction == 0)
+                       ticksToUse *= 2;
+
+               vel.x *= direction;
+       }
+
+       if (vel.x < 0)
+               currentWorld->goWorldLeft(this);
+       if (inside != nullptr) {
+               loc.y = inside->loc.y + HLINES(2);
+               vel.y = GRAVITY_CONSTANT * 5;
+               if (loc.x <= inside->loc.x + HLINES(5))
+                       loc.x = inside->loc.x + HLINES(5);
+               else if (loc.x + width >= inside->loc.x + inside->width - HLINES(5))
+                       loc.x = inside->loc.x + inside->width - width - HLINES(5);
+       }
+       ticksToUse--;
+}
+
+void Merchant::interact() {
+       std::thread([this]{
+               ui::merchantBox(name.c_str(), trade[currTrade], ":Accept:Good-Bye", false, toSay->c_str());
+               ui::waitForDialog();
+
+               // handle normal dialog options
+               switch (ui::dialogOptChosen) {
+               // Accept
+               case 1:
+                       if (!(player->inv->takeItem(trade[currTrade].item[1], trade[currTrade].quantity[1]))) {
+                               player->inv->addItem(trade[currTrade].item[0],trade[currTrade].quantity[0]);
+                               toSay = &text[1];
+                               interact();
+                       } else {
+                               toSay = &text[2];
+                               interact();
+                       }
+                       break;
+
+               // Good-bye
+               case 2:
+                       break;
+
+               default:
+                       break;
+               }
+
+               // handle merchant-specific dialog options
+               switch (ui::merchOptChosen) {
+               // left arrow
+               case 1:
+                       if (currTrade)
+                               currTrade--;
+                       ui::dontTypeOut();
+                       interact(); // TODO should we nest like this?
+                       break;
+
+               // right arrow
+               case 2:
+                       if (currTrade < trade.size() - 1)
+                               currTrade++;
+                       ui::dontTypeOut();
+                       interact();
+                       break;
+
+               default:
+                       break;
+               toSay = &text[0];
+               }
+       }).detach();
+}
+
+void Object::interact(void) {
+       std::thread([this]{
+               if(questObject && alive){
+                       ui::dialogBox(player->name, ":Yes:No", false, pickupDialog);
+                       ui::waitForDialog();
+                       if (ui::dialogOptChosen == 1) {
+                               player->inv->addItem(iname, 1);
+                               alive = false;
+                       }
+               }else{
+                       alive = false;
+                       player->inv->addItem(iname, 1);
+               }
+       }).detach();
+}
+
+bool Entity::isInside(vec2 coord) const {
+       return coord.x >= loc.x &&
+                  coord.x <= loc.x + width &&
+                  coord.y >= loc.y     &&
+              coord.y <= loc.y + height;
+}
+
+/*
+ *     This spawns the structures
+ *
+ * Structures::spawn           This allows us to spawn buildings and large amounts of entities with it.
+ *                                                     Passed are the type and x and y coordinates. These set the x and y coords
+ *                                                     of the structure being spawned, the type pass just determines what rules to follow
+ *                                                     when spawing the structure and entities. In theory this function can also spawn
+ *                                                     void spawn points for large amounts of entities. This would allow for the spawn
+ *                                                     point to have non-normal traits so it could be invisible or invincible...
+*/
+
+unsigned int Structures::spawn(BUILD_SUB sub, float x, float y) {
+       loc.x = x;
+       loc.y = y;
+       type = STRUCTURET;
+
+       alive = true;
+       canMove = false;
+
+       bsubtype = sub;
+       dim2 dim;
+
+       z = 1.0;
+       /*
+        *      tempN is the amount of entities that will be spawned in the village. Currently the village
+        *      will spawn bewteen 2 and 7 villagers for the starting hut.
+       */
+
+       //unsigned int tempN = (randGet() % 5 + 2);
+
+       if (textureLoc.empty())
+               textureLoc = inWorld->getSTextureLocation(sub);
+
+       switch(sub) {
+               case STALL_MARKET:
+                       tex = TextureIterator({ textureLoc });
+                       dim = Texture::imageDim(textureLoc);
+                       width = HLINES(dim.x/2);
+                       height = HLINES(dim.y/2);
+                       break;
+               default:
+                       tex = TextureIterator({ textureLoc });
+                       dim = Texture::imageDim(textureLoc);
+                       width = HLINES(dim.x/2);
+                       height = HLINES(dim.y/2);
+                       inv = NULL;
+                       break;
+       }
+
+       return 0;
+}
+
+/*Particles::Particles(const Structures *&s, vec2 vell, Color c, float d, )
+{
+
+}*/
+
+Particles::Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d)
+{
+       loc = vec2 {x, y};
+       vel = vec2 {vx, vy};
+       width = w;
+       height = h;
+       color = c;
+       duration = d;
+       gravity = true;
+       fountain = false;
+       behind = false;
+       bounce = false;
+       index = Texture::getIndex(c);
+       zOffset = ((rand()%20)-10)/1000.0f;
+       stu = nullptr;
+}
+
+void Particles::draw(GLfloat*& p) const
+{
+       vec2 tc = vec2(0.25f * index.x, 0.125f * (8.0f - index.y));
+
+       float z = (behind ? 2.0f : 0.9f) + zOffset;
+
+       // lower left
+    *(p++) = loc.x;
+    *(p++) = loc.y;
+    *(p++) = z;
+
+       *(p++) = tc.x;
+       *(p++) = tc.y;
+
+       // lower right
+    *(p++) = loc.x + width;
+    *(p++) = loc.y;
+    *(p++) = z;
+
+       *(p++) = tc.x;
+       *(p++) = tc.y;
+
+       // upper right
+    *(p++) = loc.x + width;
+    *(p++) = loc.y + height;
+    *(p++) = z;
+
+       *(p++) = tc.x;
+       *(p++) = tc.y;
+
+       // upper right
+    *(p++) = loc.x + width;
+    *(p++) = loc.y + height;
+    *(p++) = z;
+
+       *(p++) = tc.x;
+       *(p++) = tc.y;
+
+       // upper left
+    *(p++) = loc.x;
+    *(p++) = loc.y + height;
+    *(p++) = z;
+
+       *(p++) = tc.x;
+    *(p++) = tc.y;
+
+       // lower left
+    *(p++) = loc.x;
+    *(p++) = loc.y;
+    *(p++) = z;
+
+    *(p++) = tc.x;
+    *(p++) = tc.y;
+}
+
+void Particles::update(float _gravity, float ground_y)
+{
+       auto delta = game::time::getDeltaTime();
+
+       // handle ground collision
+       if (loc.y < ground_y) {
+               loc.y = ground_y;
+
+               // handle bounce
+               if (bounce) {
+                       vel.y *= -0.2f;
+                       vel.x /= 4.0f;
+               } else {
+                       vel = 0.0f;
+                       canMove = false;
+               }
+       }
+
+       // handle gravity
+       else if (gravity && vel.y > -1.0f) {
+               vel.y -= _gravity * delta;
+       }
+
+       // handle lifetime
+       duration -= delta;
+}
+
+bool Particles::timeUp(void)
+{
+       return !(duration > 0);
+}
+
+void Player::save(void) {
+       std::string data;
+       std::ofstream out (xmlFolder + ".main.dat", std::ios::out | std::ios::binary);
+       std::cout<<"Saving player data..."<<std::endl;
+       data.append(std::to_string((int)loc.x) + "\n");
+       data.append(std::to_string((int)loc.y) + "\n");
+       data.append(std::to_string((int)health) + "\n");
+       data.append(std::to_string((int)maxHealth) + "\n");
+       data.append(std::to_string((int)game::time::getTickCount()) + "\n");
+
+       data.append("qwer\n");
+       data.append(std::to_string((int)inv->Items.size()) + "\n");
+       for(auto &i : inv->Items) {
+               if(i.second)
+                       data.append(std::to_string(uint(i.second)) + "\n" + i.first->name + "\n");
+       }
+       data.append("qwer\n");
+
+       data.append(std::string(currentXML.data() + 4) + "\n");
+
+       data.append("dOnE\0");
+       out.write(data.data(),data.size());
+       out.close();
+}
+
+void Player::sspawn(float x,float y) {
+       unsigned int i;
+       int count;
+       std::ifstream in (xmlFolder + ".main.dat", std::ios::in | std::ios::binary);
+       spawn(x,y);
+
+       if (in.good()) {
+               std::istringstream data;
+               std::string ddata;
+               std::streampos len;
+
+               in.seekg(0,std::ios::end);
+               len = in.tellg();
+               in.seekg(0,std::ios::beg);
+
+               std::vector<char> buf (len,'\0');
+               in.read(buf.data(),buf.size());
+
+               data.rdbuf()->pubsetbuf(buf.data(),buf.size());
+
+               std::getline(data,ddata);
+               loc.x = std::stoi(ddata);
+               std::getline(data,ddata);
+               loc.y = std::stoi(ddata);
+               std::getline(data,ddata);
+               health = std::stoi(ddata);
+               std::getline(data,ddata);
+               maxHealth = std::stoi(ddata);
+               std::getline(data,ddata);
+               game::time::tick(std::stoi(ddata));
+
+               std::getline(data,ddata);
+               std::getline(data,ddata);
+
+               for (i = std::stoi(ddata);i;i--) {
+                       std::getline(data,ddata);
+                       if (ddata == "qwer")
+                               break;
+                       count = std::stoi(ddata);
+
+                       std::getline(data,ddata);
+                       if (ddata == "qwer")
+                               break;
+                       inv->addItem(ddata, (uint)count);
+               }
+
+               std::getline(data,ddata);
+               currentWorld = loadWorldFromXMLNoSave(ddata);
+
+               in.close();
+       }
+}
+
+
+//NEW
+void entityxTest(void)
+{
+       entityx::Entity e = game::entities.create();
+       e.assign<Position>(100.0f, 100.0f);
+       e.assign<Direction>(0.0f, 0.0f);
+       
+       e = game::entities.create();
+       e.assign<Position>(0.0f, 100.0f);
+       e.assign<Direction>(-0.01f, 0.0f);
+       e.assign<Visible>(-.2f);
+       auto sprite_h = e.assign<Sprite>();
+       sprite_h->addSpriteSegment(SpriteData(game::sprite_l.loadSprite("assets/cat.png"),
+                                                                                 vec2(0, 0),
+                                                                                 vec2(19, 15)),
+                                                                                 vec2(0, 0));
+}
diff --git a/src/old/inventory.cpp.bak b/src/old/inventory.cpp.bak
new file mode 100644 (file)
index 0000000..1b325c0
--- /dev/null
@@ -0,0 +1,747 @@
+#include <inventory.hpp>
+
+#include <numeric>
+
+#include <gametime.hpp>
+
+#include <render.hpp>
+
+#include <tinyxml2.h>
+using namespace tinyxml2;
+
+extern Player *player;
+extern GLuint invUI;
+static vec2 itemLoc;
+static const unsigned char numSlot = 7;
+Mix_Chunk* swordSwing;
+
+static std::vector<NewCurrency *> currencyMap;
+static std::vector<Item *> ItemMap;
+
+
+void itemDraw(Player *p, Item* d);
+
+bool strCaseCmp(std::string one, std::string two)
+{
+       for (auto &s : one) {
+               s = std::tolower(s);
+       }
+       for (auto &t : two) {
+               t = std::tolower(t);
+       }
+
+       if (one == two) return true;
+       return false;
+}
+
+void items(void)
+{
+       XMLDocument xml;
+       xml.LoadFile("config/items.xml");
+       XMLElement *exml = xml.FirstChildElement("item");
+       XMLElement *cxml = xml.FirstChildElement("currency");
+
+       while (cxml) {
+
+               // NEWEWEWEWEWEWEWEW
+               // TODO
+
+
+               cxml = cxml->NextSiblingElement();
+       }
+       while (exml) {
+
+               std::string name = exml->Attribute("type");
+               // if the type is blank
+               if (strCaseCmp(name, "blank")) {
+
+                       ItemMap.push_back(new BaseItem());
+
+               // if the type is a sword
+               } else if (strCaseCmp(name, "sword")) {
+
+                       Sword *tmpSword = new Sword();
+                       tmpSword->setDamage(exml->FloatAttribute("damage"));
+                       ItemMap.push_back(tmpSword->clone());
+                       delete tmpSword;
+
+               // if the type is a bow
+               } else if (strCaseCmp(name, "bow")) {
+
+                       Bow *tmpBow = new Bow();
+                       tmpBow->setDamage(exml->FloatAttribute("damage"));
+                       ItemMap.push_back(tmpBow->clone());
+                       delete tmpBow;
+
+               // arrow
+               } else if (strCaseCmp(name, "arrow")) {
+
+                       Arrow *tmpArrow = new Arrow();
+                       tmpArrow->setDamage(exml->FloatAttribute("damage"));
+                       ItemMap.push_back(tmpArrow->clone());
+                       delete tmpArrow;
+
+               // uncooked / raw food
+               }else if (strCaseCmp(name, "raw food")) {
+
+                       ItemMap.push_back(new RawFood());
+
+               // cooked food or natural food
+               } else if (strCaseCmp(name, "food") || strCaseCmp(name, "cooked food")) {
+
+                       ItemMap.push_back(new Food());
+
+               // light
+               } else if (strCaseCmp(name, "light")) {
+
+                       ItemMap.push_back(new ItemLight());
+
+               // if type was not specified make it a base item
+               } else {
+
+                       ItemMap.push_back(new BaseItem());
+               }
+
+               // set how much of the item we can stack
+               if(exml->QueryUnsignedAttribute("maxStackSize", &ItemMap.back()->maxStackSize) != XML_NO_ERROR) {
+                       ItemMap.back()->maxStackSize = 1;
+               }
+
+               // set all of the texture frames we can use
+               ItemMap.back()->tex = new Texturec(1, exml->Attribute("sprite"));
+
+               // get the width and height of the object based off of its sprite
+               dim2 tmpDim = Texture::imageDim(exml->Attribute("sprite"));
+               ItemMap.back()->dim.x = HLINES(tmpDim.x/2);
+               ItemMap.back()->dim.y = HLINES(tmpDim.y/2);
+
+               ItemMap.back()->name = exml->Attribute("name");
+
+               exml = exml->NextSiblingElement();
+       }
+}
+
+int Inventory::addItem(std::string name, uint count)
+{
+       for (uint i = 0; i < ItemMap.size(); i++) {
+               if (strCaseCmp(ItemMap[i]->name, name)) {
+                       for (auto &it : Items) {
+                               if (it.second && strCaseCmp(it.first->name, name)) {
+                                       if ((it.second + count) < it.first->maxStackSize) {
+                                               it.second += count;
+                                               return 0;
+                                       } else {
+                                               count -= (it.second + count) - it.first->maxStackSize;
+                                               it.second = it.first->maxStackSize;
+                                       }
+                               }
+                       }
+                       uint tmpCount = count;
+                       do {
+                               if ((count) > ItemMap[i]->maxStackSize) {
+                                       count -=  ItemMap[i]->maxStackSize;
+                                       tmpCount = ItemMap[i]->maxStackSize;
+                               } else {
+                                       tmpCount = count;
+                                       count = 0;
+                               }
+                               Items[os] = std::make_pair(ItemMap[i]->clone(), tmpCount);
+                               if (!Items[os+1].second) {
+                                       os++;
+                               } else {
+                                       for (uint z = 0; z < Items.size(); z++) {
+                                               if (!Items[z].second) {
+                                                       os = z;
+                                               }
+                                       }
+                               }
+                       } while (count > 0);
+                       return 0;
+               }
+       }
+       return -1;
+}
+
+int Inventory::takeItem(std::string name, uint count)
+{
+
+       // returns
+       // 0 = good
+       // -1 = no such item exists
+       // -2 = if item doesnt exist in inventory
+       // postive items = number returned is how many more the item needs
+
+       std::string iden;
+
+       for (uint i = 0; i < ItemMap.size(); i++) {
+               if (ItemMap[i]->name == name) {
+                       iden = name;
+                       break;
+               }
+       }
+
+       if (iden.empty()) {
+               return -1;
+       }
+
+       for (auto &i : Items) {
+               if (i.second && i.first->name == iden) {
+                       if (count > i.second) {
+                               return (count - i.second);
+                       } else {
+                               i.second -= count;
+
+                       }
+                       return 0;
+               }
+       }
+
+       return -2;
+}
+
+int Inventory::hasItem(std::string name) {
+
+       for (auto &i : Items) {
+               if (i.first->name == name) {
+                       return i.second;
+               }
+       }
+
+       return 0;
+}
+void initInventorySprites(void) {
+
+       items();
+
+       // keep
+       swordSwing = Mix_LoadWAV("assets/sounds/shortSwing.wav");
+       Mix_Volume(2,100);
+}
+
+void destroyInventory(void) {
+
+       // NEWEWEWEWEWEWEWEW
+       while (!ItemMap.empty()) {
+               delete ItemMap.back();
+               ItemMap.pop_back();
+       }
+
+       Mix_FreeChunk(swordSwing);
+}
+
+
+const char *getItemTexturePath(std::string name){
+       for (auto &i : ItemMap) {
+               if (i->name == name)
+                       return i->tex->texLoc[0].c_str();
+       }
+       return NULL;
+}
+
+GLuint getItemTexture(std::string name) {
+       for (auto &i : ItemMap) {
+               if (i->name == name) {
+                       return i->tex->image[0];
+               }
+       }
+       return 0;
+}
+
+float getItemWidth(std::string name) {
+       for (auto &i : ItemMap) {
+               if (i->name == name)
+                       return i->dim.x;
+       }
+       return 0;
+}
+
+float getItemHeight(std::string name) {
+       for (auto &i : ItemMap) {
+               if (i->name == name)
+                       return i->dim.y;
+       }
+       return 0;
+}
+
+Inventory::Inventory(unsigned int s) {
+       sel=0;
+       size=s;
+
+       Items.resize(size);
+       for (auto &i : Items) {
+               i = std::make_pair(nullptr, 0);
+       }
+}
+
+Inventory::~Inventory(void) {
+}
+
+void Inventory::setSelection(unsigned int s) {
+       sel=s;
+}
+
+void Inventory::setSelectionUp() {
+       if (!sel--)
+               sel++;
+}
+
+void Inventory::setSelectionDown() {
+       if (++sel >= numSlot)
+               sel = numSlot - 1;
+}
+
+void Inventory::draw(void) {
+       static std::vector<int>dfp(numSlot);
+       static std::vector<Ray>iray(numSlot);
+       static std::vector<vec2>curCoord(numSlot);
+       static int range = 200;
+
+       static std::vector<int>curdfp(4);
+       static std::vector<Ray>curRay(4);
+       static std::vector<vec2>curCurCoord(4);
+       static int curRange = 100;
+
+       static std::vector<int>massDfp(32);
+       static std::vector<vec2>massRay(32);
+       static std::vector<int>massOrder = {9,10,11,12,13,14,22,21,20,19,18,17,16,8,0,1,2,3,4,5,6,7,15,23,31,30,29,28,27,26,25,24};
+       static std::vector<int>massOrderClosing = {31,30,23,29,22,15,28,21,14,7,27,20,13,6,26,19,12,5,25,18,11,4,24,17,10,3,16,9,2,8,1,0};
+       static int massRange = 200;
+
+       static int itemWide = 45;
+       float angleB = (float)180/(float)numSlot;
+       float angle = float(angleB/2.0f);
+       unsigned int a = 0;
+       //static vec2 mouseStart = {0,0};
+
+       auto deltaTime = game::time::getDeltaTime();
+       auto SCREEN_WIDTH = game::SCREEN_WIDTH;
+       auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
+
+       for (auto &r : iray) {
+               r.start.x = player->loc.x + (player->width  / 2);
+               r.start.y = player->loc.y + (player->height / 2);
+               curCoord[a++] = r.start;
+       } a = 0;
+
+       for (auto &cr : curRay) {
+               cr.start.x = (offset.x + SCREEN_WIDTH / 2);
+               cr.start.y =  offset.y - (a * itemWide * 1.5f);
+               curCurCoord[a++] = cr.start;
+       } a = 0;
+
+       for (int r = 0; r < 4; r++) {
+               for (int c = 0; c < 8; c++) {
+                       massRay[a  ].x = ((offset.x - SCREEN_WIDTH  / 2) + itemWide) + c * itemWide * 1.5f;
+                       massRay[a++].y = ((offset.y + SCREEN_HEIGHT / 2) - itemWide * 1.5f) - r * itemWide * 1.5f;
+               }
+       } 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 = std::clamp(255 * (averagef(dfp) / range), 0ul, 255ul);
+
+       if (invOpening) {
+               for (auto &d : dfp) {
+                       if (!a || dfp[a - 1] > 50)
+                               d += 4.0f * deltaTime;
+                       if (d > range)
+                               d = range;
+                       a++;
+               } a = 0;
+
+               for (auto &cd : curdfp) {
+                       if (!a || curdfp[a - 1] > 90)
+                               cd += 3.0f * deltaTime;
+                       if (cd > curRange)
+                               cd = curRange;
+                       a++;
+               } a = 0;
+
+               while (a < massOrder.size()) {
+                       if (!a || massDfp[massOrder[a - 1]] > massRange * 0.75f)
+                               massDfp[massOrder[a]] += 20.0f * deltaTime;
+                       if (massDfp[massOrder[a]] > massRange)
+                               massDfp[massOrder[a]] = massRange;
+                       a++;
+               } a = 0;
+
+               if (numSlot > 0)
+                       invOpen = true;
+       } else {
+               for (auto &d : dfp) {
+                       if (d > 0)
+                               d -= 4.5f * deltaTime;
+               }
+               for (auto &cd : curdfp) {
+                       if (cd > 0)
+                               cd -= 3.0f * deltaTime;
+               }
+
+               while (a < massRay.size()) {
+                       if (!a || massDfp[massOrderClosing[a - 1]] <= 0)
+                               massDfp[massOrderClosing[a]] -= 30.0f * deltaTime;
+                       else if (massDfp[massOrderClosing[a - 1]] < 0)
+                               massDfp[massOrderClosing[a - 1]] = 0;
+                       a++;
+               } a = 0;
+
+               if (std::all_of(std::begin(massDfp), std::end(massDfp), [](auto d) { return d <= 0; })) {
+                       invOpen = false;
+                       for (auto &md : massDfp) {
+                               if (md < 0)
+                                       md = 0;
+                       }
+               }
+
+       }
+
+       /*
+        *      a = 0
+        */
+
+       if (invOpen) {
+        Render::useShader(&Render::textShader);
+               for(auto &mr : massRay) {
+            float t = (((float)massDfp[a]/(float)massRange)*.5f);
+            glActiveTexture(GL_TEXTURE0);
+            Render::textShader.use();
+
+                       glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(0.0f,0.0f,0.0f, t >= 0? 255*t : 0)));
+            glUniform1i(Render::textShader.uniform[WU_texture], 0);
+
+            Render::drawRect(vec2(mr.x-(itemWide/2), mr.y-(itemWide/2)), vec2(mr.x-(itemWide/2)+itemWide, mr.y-(itemWide/2)+itemWide), -6.0);
+
+            glUseProgram(0);
+                       if (!Items.empty() && a+numSlot < Items.size() && Items[a+numSlot].second) {
+                               Render::textShader.use();
+                glBindTexture(GL_TEXTURE_2D, Items[a+numSlot].first->tex->image[0]);//itemtex[items[a+numSlot].id]);
+                               glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0f, 1.0f, 1.0f, ((float)massDfp[a]/(float)(massRange?massRange:1))*0.8f);
+
+                if (Items[a+numSlot].first->dim.y > Items[a+numSlot].first->dim.x) {
+                    Render::drawRect(vec2(mr.x-((itemWide/2)*((float)Items[a+numSlot].first->dim.x/(float)Items[a+numSlot].first->dim.y)),     mr.y-(itemWide/2)),
+                                     vec2(mr.x+((itemWide/2)*((float)Items[a+numSlot].first->dim.x/(float)Items[a+numSlot].first->dim.y)),     mr.y+(itemWide/2)), -6.1);
+                } else {
+                    Render::drawRect(vec2(mr.x-(itemWide/2),mr.y-(itemWide/2)*((float)Items[a+numSlot].first->dim.y/(float)Items[a+numSlot].first->dim.x)),
+                                     vec2(mr.x-(itemWide/2),mr.y+(itemWide/2)*((float)Items[a+numSlot].first->dim.y/(float)Items[a+numSlot].first->dim.x)), -6.1);
+                }
+                               ui::setFontColor(255,255,255,((float)massDfp[a]/(float)(massRange?massRange:1))*255);
+                               ui::putText(mr.x-(itemWide/2)+(itemWide*.85),mr.y-(itemWide/2),"%d",Items[a+numSlot].second);
+                               ui::setFontColor(255,255,255,255);
+                Render::textShader.unuse();
+                       }
+                       a++;
+               }a=0;
+
+               for(auto &cr : curRay) {
+                       curCurCoord[a].x -= float((curdfp[a]) * cos(-1));
+                       curCurCoord[a].y += float((curdfp[a]) * sin(0));
+                       cr.end = curCurCoord[a];
+
+            float curTrans = (((float)curdfp[a]/(float)(curRange?curRange:1))*0.5f);
+
+            Render::textShader.use();
+                       glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(0.0f, 0.0f, 0.0f, curTrans >= 0 ? 255 * curTrans : 0)));
+            Render::drawRect(vec2(cr.end.x-(itemWide/2),                cr.end.y-(itemWide/2)),
+                             vec2(cr.end.x-(itemWide/2)+itemWide,cr.end.y-(itemWide/2)+itemWide), -6.0);
+            Render::textShader.unuse();
+                       a++;
+               }a=0;
+
+               for(auto &r : iray) {
+                       angle = 180 - (angleB * a) - angleB / 2.0f;
+                       curCoord[a].x += float((dfp[a]) * cos(angle*PI/180));
+                       curCoord[a].y += float((dfp[a]) * sin(angle*PI/180));
+                       r.end = curCoord[a];
+
+            float t = ((float)dfp[a]/(float)(range?range:1))*0.5f;
+
+            Render::textShader.use();
+                       glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(0.0f, 0.0f, 0.0f, t >= 0 ? 255 * t : 0)));
+            Render::drawRect(vec2(r.end.x-(itemWide/2),                 r.end.y-(itemWide/2)),
+                             vec2(r.end.x-(itemWide/2)+itemWide,r.end.y-(itemWide/2)+itemWide), -6.0);
+
+                       if (!Items.empty() && a < numSlot && Items[a].second) {
+                               glBindTexture(GL_TEXTURE_2D, Items[a].first->tex->image[0]);//itemtex[items[a].id]);
+                               glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0f, 1.0f, 1.0f, ((float)dfp[a]/(float)(range?range:1))*0.8f);
+                               if (Items[a].first->dim.y > Items[a].first->dim.x) {
+                                   Render::drawRect(vec2(r.end.x-((itemWide/2)*((float)Items[a].first->dim.x/(float)Items[a].first->dim.y)),   r.end.y-(itemWide/2)),
+                                     vec2(r.end.x+((itemWide/2)*((float)Items[a].first->dim.x/(float)Items[a].first->dim.y)),  r.end.y+(itemWide/2)), -6.1);
+                } else {
+                    Render::drawRect(vec2(r.end.x-(itemWide/2),r.end.y-(itemWide/2)*((float)Items[a].first->dim.y/(float)Items[a].first->dim.x)),
+                                     vec2(r.end.x+(itemWide/2),r.end.y+(itemWide/2)*((float)Items[a].first->dim.y/(float)Items[a].first->dim.x)), -6.1);
+                               }
+                               ui::setFontColor(255,255,255,((float)dfp[a]/(float)(range?range:1))*255);
+                               ui::putStringCentered(r.end.x,r.end.y-(itemWide*.9),Items[a].first->name);//itemMap[items[a].id]->name);
+                               ui::putText(r.end.x-(itemWide/2)+(itemWide*.85),r.end.y-(itemWide/2),"%d",Items[a].second);
+                               ui::setFontColor(255,255,255,255);
+                       }
+            Render::textShader.unuse();
+                       if (sel == a) {
+                               static float sc = 1;
+                               static bool up;
+                               up ? sc += .0025*deltaTime : sc -= .0025*deltaTime;
+                               if (sc > 1.2) {
+                                       up = false;
+                                       sc = 1.2;
+                               }
+                               if (sc < 1.0) {
+                                       up = true;
+                                       sc = 1.0;
+                               }
+                float t = ((float)dfp[a]/(float)(range?range:1));
+                Render::useShader(&Render::textShader);
+
+                Render::textShader.use();
+                glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
+
+                // bottom
+                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t >= 0 ? 255 * t : 0)));
+                Render::drawRect(vec2(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09),
+                                 vec2(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2), -6.2);
+
+                // top
+                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t  >= 0 ? 255 * t : 0)));
+                Render::drawRect(vec2(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09),
+                                 vec2(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2), -6.2);
+
+                // left
+                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t >= 0 ? 255 * t : 0)));
+                Render::drawRect(vec2(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09),
+                                 vec2(r.end.x - (itemWide*sc)/2                                   ,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09), -6.2);
+
+                // right
+                glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255, 255, 255, t >= 0 ? 255 * t : 0)));
+                Render::drawRect(vec2(r.end.x + (itemWide*sc)/2                                        ,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09),
+                                 vec2(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09), -6.2);
+
+                //glUseProgram(0);
+                       }
+                       a++;
+               }
+       } /*else if (invHover) {
+               static unsigned int highlight = 0;
+               static unsigned int thing = 0;
+
+               if (!mouseSel) {
+                       // setup?
+                       mouseStart.x = ui::mouse.x - offset.x;
+                       highlight = sel;
+                       thing = sel;
+                       mouseSel = true;
+               } else {
+                       if((ui::mouse.x - offset.x) >= mouseStart.x){
+                               thing = (ui::mouse.x - offset.x - mouseStart.x)/80;
+                               highlight=sel+thing;
+                               if(highlight>numSlot-1)highlight=numSlot-1;
+                               if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
+                                       sel = highlight;
+                                       mouseSel=false;
+                                       invHover=false;
+                                       selected = true;
+                               }
+                       }
+                       if ((ui::mouse.x - offset.x) < mouseStart.x) {
+                               thing = (mouseStart.x - (ui::mouse.x - offset.x))/80;
+                               if ((int)sel - (int)thing < 0)
+                                       highlight = 0;
+                               else
+                                       highlight = sel - thing;
+                               if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
+                                       sel = highlight;
+                                       mouseSel=false;
+                                       invHover=false;
+                                       selected = true;
+                               }
+                       }
+               }
+
+               a = 0;
+               for (auto &r : iray) {
+                       angle = 180 - (angleB * a) - angleB / 2.0f;
+                       curCoord[a].x += float(range) * cos(angle*PI/180);
+                       curCoord[a].y += float(range) * sin(angle*PI/180);
+                       r.end = curCoord[a];
+
+                       // square drawing
+                       glColor4f(0.0f, 0.0f, 0.0f, a == highlight ? 0.5f : 0.1f);
+                       glBegin(GL_QUADS);
+                               glVertex2i(r.end.x-(itemWide/2),        r.end.y-(itemWide/2));
+                               glVertex2i(r.end.x+(itemWide/2),        r.end.y-(itemWide/2));
+                               glVertex2i(r.end.x+(itemWide/2),        r.end.y+(itemWide/2));
+                               glVertex2i(r.end.x-(itemWide/2),        r.end.y+(itemWide/2));
+                       glEnd();
+
+                       if (a < items.size() && items[a].count) {
+                               glEnable(GL_TEXTURE_2D);
+                               glBindTexture(GL_TEXTURE_2D, itemtex[items[a].id]);
+                               glColor4f(1.0f, 1.0f, 1.0f, a == highlight ? 0.8f : 0.2f);
+                               glBegin(GL_QUADS);
+                                       if(itemMap[items[a].id]->height > itemMap[items[a].id]->width){
+                                               glTexCoord2i(0,1);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
+                                               glTexCoord2i(1,1);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
+                                               glTexCoord2i(1,0);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
+                                               glTexCoord2i(0,0);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
+                                       }else{
+                                               glTexCoord2i(0,1);glVertex2i(r.end.x-(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+                                               glTexCoord2i(1,1);glVertex2i(r.end.x+(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+                                               glTexCoord2i(1,0);glVertex2i(r.end.x+(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+                                               glTexCoord2i(0,0);glVertex2i(r.end.x-(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+                                       }
+                               glEnd();
+                               glDisable(GL_TEXTURE_2D);
+                       }
+                       a++;
+               }
+
+               if (highlight < items.size()) {
+                       ui::putStringCentered(player->loc.x + player->width / 2,
+                                             player->loc.y + range * 0.75f,
+                                                             itemMap[items[highlight].id]->name
+                                                         );
+               }
+       }*/
+       /*if (!items.empty() && items.size() > sel && items[sel].count)
+               itemDraw(player,items[sel].id);*/
+       if (!Items.empty() && Items.size() > sel && Items[sel].second)
+               itemDraw(player, Items[sel].first);
+}
+
+void itemDraw(Player *p, Item *d) {
+
+       itemLoc.y = p->loc.y+(p->height/3);
+       itemLoc.x = p->left?p->loc.x-d->dim.x/2:p->loc.x+p->width-d->dim.x/2;
+
+       Render::worldShader.use();
+
+       if (p->left) {
+               // move to center of screen
+               glm::mat4 tro = glm::translate(glm::mat4(1.0f),
+                                                                          glm::vec3(itemLoc.x+d->dim.x/2, itemLoc.y, 0));
+               // rotate off center
+               glm::mat4 rot = glm::rotate(glm::mat4(1.0f),
+                                                                       static_cast<GLfloat>((d->rotation*3.14159)/180.0f),
+                                                                       glm::vec3(0.0f, 0.0f, 1.0f));
+               // move back to player
+               glm::mat4 trt = glm::translate(glm::mat4(1.0f),
+                                                                          glm::vec3(-itemLoc.x-d->dim.x/2, -itemLoc.y, 0));
+               // tell shader to translate the object using steps above
+               glUniformMatrix4fv(Render::worldShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(tro * rot * trt));
+       } else {
+               // move to center of screen
+               glm::mat4 tro = glm::translate(glm::mat4(1.0f),
+                                                                          glm::vec3(itemLoc.x+d->dim.x/2,itemLoc.y,0));
+               // rotate off center
+               glm::mat4 rot = glm::rotate(glm::mat4(1.0f),
+                                                                       static_cast<GLfloat>((d->rotation*3.14159)/180.0f),
+                                                                       glm::vec3(0.0f, 0.0f, 1.0f));
+               // move back to player
+               glm::mat4 trt = glm::translate(glm::mat4(1.0f),
+                                                                          glm::vec3(-itemLoc.x-d->dim.x/2,-itemLoc.y,0));
+               // tell shader to translate the object using steps above
+               glUniformMatrix4fv(Render::worldShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(tro * rot * trt));
+       }
+
+    GLfloat itemTex[12] = {0.0, 0.0,
+                           1.0, 0.0,
+                           1.0, 1.0,
+
+                           1.0, 1.0,
+                           0.0, 1.0,
+                           0.0, 0.0};
+    if (!p->left) {
+        itemTex[0] = 1.0;
+        itemTex[2] = 0.0;
+        itemTex[4] = 0.0;
+        itemTex[6] = 0.0;
+        itemTex[8] = 1.0;
+        itemTex[10] = 1.0;
+    }
+
+    GLfloat itemCoords[] = {itemLoc.x,          itemLoc.y,          p->z,
+                            itemLoc.x+d->dim.x, itemLoc.y,          p->z,
+                            itemLoc.x+d->dim.x, itemLoc.y+d->dim.y, p->z,
+
+                            itemLoc.x+d->dim.x, itemLoc.y+d->dim.y, p->z,
+                            itemLoc.x,          itemLoc.y+d->dim.y, p->z,
+                            itemLoc.x,          itemLoc.y,          p->z};
+
+       glBindTexture(GL_TEXTURE_2D,d->tex->image[0]);
+
+    Render::worldShader.enable();
+
+    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, itemCoords);
+    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, itemTex);
+    glDrawArrays(GL_TRIANGLES, 0, 6);
+
+       Render::worldShader.disable();
+       Render::worldShader.unuse();
+}
+
+/*
+ *     This function is used to trigger the player's item's ability.
+ */
+int Inventory::useItem(void)
+{
+       return 0;
+}
+
+int Inventory::useCurrent()
+{
+       if (Items[sel].second)
+               return Items[sel].first->useItem();
+       return -1;
+}
+
+void Inventory::currentAddInteract(Entity* e)
+{
+       if (Items[sel].second)
+               Items[sel].first->addInteract(e);
+}
+
+void Inventory::currentAddInteract(std::vector<Entity*> e)
+{
+       if (Items[sel].second)
+               Items[sel].first->addInteract(e);
+}
+
+bool Inventory::detectCollision(vec2 one, vec2 two) {
+       (void)one;
+       (void)two;
+       return false;
+}
+
+const Item* Inventory::getCurrentItem(void)
+{
+       if (Items.size() > 0)
+               return Items[sel].first;
+       else
+               return nullptr;
+}
+
+void InventorySystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
+{
+       (void)en;
+       (void)ev;
+       (void)dt;
+}
+
+void InventorySystem::configure(entityx::EventManager &em)
+{
+       em.subscribe<MouseScrollEvent>(*this);
+}
+
+void InventorySystem::receive(const MouseScrollEvent &mse)
+{
+       static int mouseWheelUpCount = 0, mouseWheelDownCount = 0;
+
+       if ((mse.scrollDistance < 0) && ((++mouseWheelUpCount % 5) == 0) ) {
+               mouseWheelUpCount = 0;
+               player->inv->setSelectionUp();
+       } else if ( (++mouseWheelDownCount % 5) == 0 ) {
+               mouseWheelDownCount = 0;
+               player->inv->setSelectionDown();
+       }
+}
diff --git a/src/old/items.cpp.bak b/src/old/items.cpp.bak
new file mode 100644 (file)
index 0000000..180c5fa
--- /dev/null
@@ -0,0 +1,301 @@
+#include <inventory.hpp>
+#include <entities.hpp>
+#include <world.hpp>
+
+extern Player *player;
+extern World *currentWorld;
+
+/************************************************************************************
+*                                          GLOBAL                                   *
+************************************************************************************/
+
+/**************************************************
+*                    USE ITEM                     *
+**************************************************/
+
+int BaseItem::useItem()
+{
+       return 0;
+}
+
+int Sword::useItem()
+{
+    if (inUse())
+               return -1;
+
+       std::thread([this]{
+               setUse(true);
+               volatile bool swing = true;
+               bool back = false;
+               float coef = 0.0f;
+
+               while (swing) {
+
+                       // handle swinging
+                       if (!back)
+                               coef += .8f;
+                       else
+                               coef -= .4f;
+
+                       if (player->left)
+                               rotation = coef;
+                       else
+                               rotation = -coef;
+
+                       if (coef > 80 && !back)
+                               back = true;
+
+                       if (coef <= 0 && back) {
+                               swing = false;
+                               coef = 0.0f;
+                               rotation = 0.0f;
+                       }
+
+                       if (!back) {
+                               // handle collision with interaction
+                               hitbox.start.y = player->loc.y+(player->height/3);
+                               hitbox.start.x = player->left ? player->loc.x : player->loc.x + player->width;
+
+                               for (auto &e : interact) {
+                                       float dist = 0.0f;
+                                       while (dist < dim.y) {
+                                               hitbox.end = hitbox.start;
+                                               if (player->left)
+                                                       hitbox.end.x -= dist * cos(rotation*PI/180);
+                                               else 
+                                                       hitbox.end.x += dist * cos(rotation*PI/180);
+
+                                               hitbox.end.y += dist * sin(rotation*PI/180);
+
+                                               if (hitbox.end.x > e->loc.x && hitbox.end.x < e->loc.x + e->width) {
+                                                       if (hitbox.end.y > e->loc.y && hitbox.end.y < e->loc.y + e->height) {
+                                                               if (e->type == MOBT)
+                                                                       Mobp(e)->onHit(damage);
+                                                               else
+                                                                       e->takeHit(damage, 600);
+
+                                                               // add some blood
+                                                               //for(int r = 0; r < (rand()%5);r++)
+                                                                       //currentWorld->addParticle(rand()%game::HLINE*3 + e->loc.x - .05f,e->loc.y + e->height*.5, game::HLINE,game::HLINE, -(rand()%10)*.01,((rand()%4)*.001-.002), {(rand()%75+10)/100.0f,0,0}, 10000);
+                                                       }
+                                               }
+
+                                               dist += HLINES(0.5f);
+                                       }
+                               }
+                       }
+
+                       // add a slight delay
+                       SDL_Delay(1);
+               }
+               for (auto &e : interact)
+                       e->setCooldown(0);
+               setUse(false);
+       }).detach();
+
+       return 0;
+}
+
+int Arrow::useItem()
+{
+
+       return 0;
+}
+
+int Bow::useItem()
+{
+       if (inUse())
+               return -1;
+
+       std::thread([this](void) {
+               setUse(true);
+
+               static Particles* part = nullptr;
+
+               if (part == nullptr) {
+                       float rot = atan(sqrt(pow(ui::mouse.y-(player->loc.y + player->height),2)/pow(ui::mouse.x-player->loc.x,2)));
+                       float speed = 1.0;
+                       float vx = speed * cos(rot);
+                       float vy = speed * sin(rot);
+
+                       vx *= (ui::mouse.x < player->loc.x) ? -1 : 1;
+                       vy *= (ui::mouse.y < player->loc.y + player->height) ? -1 : 1;
+
+                       currentWorld->addParticle(player->loc.x,                                        // x
+                                                                         player->loc.y + player->height,       // y
+                                                                         HLINES(3),                                            // width
+                                                                         HLINES(3),                                            // height
+                                                                         vx,                                                           // vel.x
+                                                                         vy,                                                           // vel.y
+                                                                         {139, 69, 19},                                        // RGB color
+                                                                         2500                                                          // duration (ms)
+                                                                         );
+                       part = &currentWorld->particles.back();
+               } else {
+                       if (part->vel.x < 0.05 && part->vel.y < 0.05) {
+                               part->duration = 0;
+                               part = nullptr;
+                       }
+               }
+
+               setUse(false);
+       }).detach();
+
+       return 0;
+}
+
+// TODO chance to hurt
+int RawFood::useItem()
+{
+       return 0;
+}
+
+int Food::useItem()
+{
+    std::cout << "Yum!" << std::endl;
+       return 0;
+}
+
+int ItemLight::useItem()
+{
+       if (player->light.radius > 0)
+               player->light.radius = 0;
+       else
+               player->light.radius = 500;
+       return 0;
+}
+
+/**************************************************
+*                       CLONE                     *
+**************************************************/
+
+BaseItem* BaseItem::clone()
+{
+       return new BaseItem(*this);
+}
+
+Sword* Sword::clone()
+{
+       return new Sword(*this);
+}
+
+Arrow* Arrow::clone()
+{
+       return new Arrow(*this);
+}
+
+Bow* Bow::clone()
+{
+       return new Bow(*this);
+}
+
+Food* Food::clone()
+{
+       return new Food(*this);
+}
+
+RawFood* RawFood::clone()
+{
+       return new RawFood(*this);
+}
+
+ItemLight* ItemLight::clone()
+{
+       return new ItemLight(*this);
+}
+/************************************************************************************
+*                                    ITEM SPECIFIC                                  *
+************************************************************************************/
+
+/**************************************************
+*                      ITEM                       *
+**************************************************/
+
+bool Item::inUse()
+{
+       return beingUsed;
+}
+
+void Item::setUse(bool use)
+{
+       beingUsed = use;
+}
+
+void Item::addInteract(Entity* e)
+{
+       interact.push_back(e);
+}
+
+void Item::addInteract(std::vector<Entity*> e)
+{
+       for (auto &v : e) {
+               interact.push_back(v);
+       }
+}
+
+GLuint Item::rtex()
+{
+       return tex->image[0];
+}
+
+GLuint Item::rtex(int n)
+{
+       return tex->image[n];
+}
+
+Item::~Item()
+{
+       delete tex;
+}
+
+/**************************************************
+*                      SWORD                      *
+**************************************************/
+
+float Sword::getDamage()
+{
+       return damage;
+}
+
+void Sword::setDamage(float d)
+{
+       damage = d;
+}
+
+/**************************************************
+*                      ARROW                      *
+**************************************************/
+
+float Arrow::getDamage()
+{
+       return damage;
+}
+
+void Arrow::setDamage(float d)
+{
+       damage = d;
+}
+
+
+/**************************************************
+*                      BOW                        *
+**************************************************/
+
+float Bow::getDamage()
+{
+       return damage;
+}
+
+void Bow::setDamage(float d)
+{
+       damage = d;
+}
+
+/**************************************************
+*                      FOODS                      *
+**************************************************/
+
+float RawFood::getHealth()
+{
+       return health;
+}
diff --git a/src/old/mob.cpp.bak b/src/old/mob.cpp.bak
new file mode 100644 (file)
index 0000000..e78e5cd
--- /dev/null
@@ -0,0 +1,539 @@
+#include <mob.hpp>
+#include <ui.hpp>
+#include <world.hpp>
+#include <brice.hpp>
+
+extern World *currentWorld;
+
+Mob::Mob(void)
+{
+    type = MOBT;
+       inv = nullptr;
+    rider = nullptr;
+       xmle = nullptr;
+    canMove = true;
+       loc = 0;
+}
+
+Page::Page(void) : Mob()
+{
+
+    ridable = false;
+    aggressive = false;
+    maxHealth = health = 50;
+    width = HLINES(6);
+    height = HLINES(4);
+    tex = TextureIterator({"assets/items/ITEM_PAGE.png"});
+    pageTexture = 0;
+}
+
+void Page::act(void)
+{
+    if (player->loc.x > loc.x - 100 && player->loc.x < loc.x + 100 && isInside(ui::mouse) &&
+        (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT))) {
+        std::thread([this](void){
+            ui::drawPage(pageTexture);
+            ui::waitForDialog();
+                       game::setValue(cId, cValue);
+                       game::briceUpdate();
+            die();
+        }).detach();
+    }
+}
+
+void Page::onHit(unsigned int _health)
+{
+       (void)_health;
+       act();
+}
+
+bool Page::bindTex(void)
+{
+    glActiveTexture(GL_TEXTURE0);
+    tex(0);
+    return true;
+}
+
+void Page::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)w;
+    float Xlocx;
+    if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
+        loc.x = Xlocx;
+    pageTexPath = e->StrAttribute("id");
+    pageTexture = Texture::loadTexture(pageTexPath);
+
+       cId = e->StrAttribute("cid");
+       cValue = e->StrAttribute("cvalue");
+
+       xmle = e;
+}
+
+void Page::saveToXML(void)
+{}
+
+Door::Door(void) : Mob()
+{
+    ridable = false;
+    aggressive = false;
+    maxHealth = health = 50;
+    width = HLINES(12);
+    height = HLINES(20);
+    tex = TextureIterator({"assets/style/classic/door.png"});
+}
+
+void Door::act(void)
+{
+}
+
+void Door::onHit(unsigned int _health)
+{
+       (void)_health;
+}
+
+bool Door::bindTex(void)
+{
+    glActiveTexture(GL_TEXTURE0);
+    tex(0);
+    return true;
+}
+
+void Door::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)w;
+    float Xlocx;
+    if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
+        loc.x = Xlocx;
+}
+
+void Door::saveToXML(void)
+{}
+
+Cat::Cat(void) : Mob()
+{
+    ridable = true;
+    aggressive = false;
+    maxHealth = health = 100000;
+    width  = HLINES(19);
+    height = HLINES(15);
+    tex = TextureIterator({"assets/cat.png"});
+    actCounterInitial = 0;
+    actCounter = 1;
+}
+
+void Cat::act(void)
+{
+    static float vely = 0;
+    if (rider != nullptr) {
+        if (!rider->ground) {
+            loc.y += HLINES(2);
+            vel.y = .4;
+        }
+        if (rider->speed > 1) {
+            vely = .5;
+        } else if (rider->speed == .5) {
+            vely = -.5;
+        } else {
+            vely = 0;
+        }
+        vel.y = vely;
+        if (!rider->ground) {
+            if ((vel.y -= .015) < -.2)
+                rider->ground = true;
+        }
+        vel.x = .1 * (rider->left ? -1 : 1);
+    } else {
+        vel = 0;
+    }
+}
+
+void Cat::onHit(unsigned int _health)
+{
+       health += _health;
+}
+
+bool Cat::bindTex(void)
+{
+       glActiveTexture(GL_TEXTURE0);
+    tex(0);
+       return true;
+}
+
+void Cat::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)w;
+    float spawnc;
+
+    if (e->QueryFloatAttribute("x", &spawnc) == XML_NO_ERROR)
+        loc.x = spawnc;
+       else
+               loc.x = e->FloatAttribute("spawnx");
+
+       if (e->QueryFloatAttribute("y", &spawnc) == XML_NO_ERROR)
+               loc.y = spawnc;
+
+       xmle = e;
+}
+
+void Cat::saveToXML(void)
+{
+       E_SAVE_COORDS;
+       xmle->SetAttribute("alive", alive);
+}
+
+Rabbit::Rabbit(void) : Mob()
+{
+    ridable = true;
+    aggressive = false;
+    maxHealth = health = 50;
+    width  = HLINES(10);
+    height = HLINES(8);
+    tex = TextureIterator({"assets/rabbit.png", "assets/rabbit1.png"});
+    actCounterInitial = randGet() % 240 + 15;
+    actCounter = 1;
+
+       drop = {
+               std::make_tuple("Dank MayMay", 5, 1.00f)
+       };
+}
+
+void Rabbit::act(void)
+{
+    static int direction = 0;
+
+    if (!--actCounter) {
+        actCounter = actCounterInitial;
+        direction = (randGet() % 3 - 1);       //sets the direction to either -1, 0, 1
+        if (direction == 0)
+            ticksToUse /= 2;
+        vel.x *= direction;
+    }
+
+    if (ground && direction) {
+        ground = false;
+        vel.y = .15;
+        loc.y += HLINES(0.25f);
+        vel.x = 0.05f * direction;
+    }
+}
+
+void Rabbit::onHit(unsigned int _health)
+{
+       takeHit(_health, 600);
+}
+
+bool Rabbit::bindTex(void)
+{
+    glActiveTexture(GL_TEXTURE0);
+    tex(!ground);
+    return true;
+}
+
+void Rabbit::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)w;
+    float spawnc;
+
+       xmle = e;
+
+    if (e->QueryFloatAttribute("x", &spawnc) == XML_NO_ERROR)
+        loc.x = spawnc;
+       else
+               loc.x = e->FloatAttribute("spawnx");
+
+       if (e->QueryFloatAttribute("y", &spawnc) == XML_NO_ERROR)
+               loc.y = spawnc;
+
+       E_LOAD_HEALTH;
+       
+       if (e->QueryBoolAttribute("aggressive", &aggressive) != XML_NO_ERROR)
+               aggressive = false;
+}
+
+void Rabbit::saveToXML(void)
+{
+       E_SAVE_HEALTH;
+}
+
+Bird::Bird(void) : Mob()
+{
+    ridable = true;
+    aggressive = false;
+    maxHealth = health = 50;
+    width = HLINES(8);
+    height = HLINES(8);
+    tex = TextureIterator({"assets/robin.png"});
+    actCounterInitial = actCounter = 200;
+}
+
+void Bird::act(void)
+{
+    static bool direction = false;
+    static const float wstart = currentWorld->getWorldStart();
+
+    if (!--actCounter) {
+        actCounter = actCounterInitial;
+        direction ^= 1;
+    }
+
+    if (loc.x > -wstart - HLINES(10.0f))
+        loc.x = wstart + HLINES(10.0f);
+    else if (loc.x < wstart + HLINES(10.0f))
+        loc.x = -wstart - HLINES(10.0f);
+
+    if (loc.y <= initialY)
+        vel.y = 0.3f;
+    vel.x = direction ? -0.3f : 0.3f;
+}
+
+void Bird::onHit(unsigned int _health)
+{
+       takeHit(_health, 1000);
+}
+
+bool Bird::bindTex(void)
+{
+    glActiveTexture(GL_TEXTURE0);
+    tex(0);
+    return true;
+}
+
+void Bird::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)w;
+    float Xlocx;
+
+       xmle = e;
+
+       if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
+               loc.x = Xlocx;
+       if (e->QueryFloatAttribute("y", &initialY) != XML_NO_ERROR)
+               initialY = 300;
+
+       E_LOAD_HEALTH;
+
+    if (e->QueryBoolAttribute("aggressive", &aggressive) != XML_NO_ERROR)
+        aggressive = false;
+}
+
+void Bird::saveToXML(void)
+{
+       E_SAVE_COORDS;
+       E_SAVE_HEALTH;
+}
+
+Trigger::Trigger(void) : Mob()
+{
+    ridable = false;
+    aggressive = false;
+    maxHealth = health = 50;
+    width = HLINES(20);
+    height = 2000;
+    //tex = TextureIterator();
+    triggered = false;
+       notext = false;
+}
+
+void Trigger::act(void)
+{
+    auto c = player->loc.x + player->width / 2;
+    static bool running = false;
+
+    if (triggered) {
+        die();
+    } else if (!running && c > loc.x && c < loc.x + width) {
+        std::thread([&]{
+            running = true;
+
+            XMLDocument xml;
+            XMLElement *exml;
+
+            xml.LoadFile(currentXML.c_str());
+            exml = xml.FirstChildElement("Trigger");
+
+            while(exml && exml->StrAttribute("id") != id)
+                exml = exml->NextSiblingElement();
+
+            player->vel.x = 0;
+
+                       if (notext) {
+                               for (auto &e : currentWorld->entity) {
+                                       if (e->type == NPCT && e->name == exml->GetText()) {
+                                               e->interact();
+                                               break;
+                                       }
+                               }
+                       } else {
+
+                       /*if (exml == nullptr) {
+                               auto id = xmle->StrAttribute("cid");
+                               if (!id.empty()) {
+                                       game::setValue(id, xmle->StrAttribute("cvalue"));
+                                       game::briceUpdate();
+                               }
+                               return;
+                       }*/
+
+                   ui::toggleBlackFast();
+                   ui::waitForCover();
+
+               std::string text = exml->GetText();
+                   char *pch = strtok(&text[0], "\n");
+
+                   while (pch) {
+                       ui::importantText(pch);
+                       ui::waitForDialog();
+                       pch = strtok(NULL, "\n");
+                   }
+
+               ui::toggleBlackFast();
+                       }
+
+            triggered = true;
+            running = false;
+        }).detach();
+    }
+}
+
+void Trigger::onHit(unsigned int _health)
+{
+       (void)_health;
+}
+
+bool Trigger::bindTex(void)
+{
+    return false;
+}
+
+void Trigger::createFromXML(XMLElement *e, World *w=nullptr)
+{
+       (void)w;
+       float Xlocx;
+
+       if (e->QueryFloatAttribute("spawnx", &Xlocx) == XML_NO_ERROR)
+               loc.x = Xlocx;
+
+       if (e->QueryBoolAttribute("notext", &notext) != XML_NO_ERROR)
+               notext = false;
+
+       id = e->StrAttribute("id");
+
+       xmle = e;
+}
+
+void Trigger::saveToXML(void)
+{}
+
+Chest::Chest(void) : Mob()
+{
+    ridable = false;
+    aggressive = false;
+    maxHealth = health = 100;
+    width = HLINES(10);
+    height = HLINES(5);
+    tex = TextureIterator({"assets/chest.png"});
+       inv = new Inventory(1);
+}
+
+void Chest::act(void)
+{
+       if (isInside(ui::mouse) && player->isNear(this)) {
+               if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) && !ui::dialogBoxExists)
+                       for (auto &i : inv->Items) {
+                               player->inv->addItem(i.first->name, i.second);
+                               inv->takeItem(i.first->name, i.second);
+                       }
+       }
+
+       for (auto &e : currentWorld->entity) {
+               if (e->type == OBJECTT && e->isNear(this)) {
+                       auto o = dynamic_cast<Object *>(e);
+                       inv->addItem(o->iname, 1);
+                       e->health = 0;
+               }
+       }
+}
+
+void Chest::onHit(unsigned int _health)
+{
+       (void)_health;
+       die();
+}
+
+bool Chest::bindTex(void)
+{
+    glActiveTexture(GL_TEXTURE0);
+    tex(0);
+    return true;
+}
+
+void Chest::createFromXML(XMLElement *e, World *w)
+{
+       (void)w;
+       loc = vec2 { 0, 100 };
+       xmle = e;
+}
+
+void Chest::saveToXML(void)
+{
+       xmle->SetAttribute("alive", alive);
+}
+
+
+
+Mob::~Mob()
+{
+       delete inv;
+}
+
+extern World *currentWorld;
+extern Arena *arena;
+
+void Mob::wander(void)
+{
+       static bool YAYA = false;
+
+    if (forcedMove)
+               return;
+
+    if (aggressive && !YAYA && isInside(vec2 {player->loc.x + width / 2, player->loc.y + height / 4})) {
+               if (!ui::dialogBoxExists) {
+            std::thread([&](void){
+                           arena->fight(currentWorld, player, this);
+                           ui::toggleWhiteFast();
+                           YAYA = true;
+                           ui::waitForCover();
+                           YAYA = false;
+                           currentWorld = arena;
+                           ui::toggleWhiteFast();
+            }).detach();
+               }
+       }
+    act();
+}
+
+void Mob::ride(Entity *e)
+{
+    if (!ridable)
+        return;
+
+    if (rider == e)
+        rider = nullptr;
+    else
+        rider = e;
+}
+
+void Mob::onDeath(void)
+{
+       vec2 q = vec2 {player->loc.x, game::SCREEN_HEIGHT - 100.0f};
+
+       ui::putTextL(q, "Player got: ");
+
+       for (const auto &d : drop) {
+               if ((randGet() % 100) < std::get<float>(d) * 100.0f) {
+                       q.y -= 20;
+                       ui::putTextL(q, "%d x %s", std::get<unsigned int>(d), std::get<std::string>(d).c_str());
+                       player->inv->addItem(std::get<std::string>(d), std::get<unsigned int>(d));
+               }
+       }
+}
diff --git a/src/old/quest.cpp.bak b/src/old/quest.cpp.bak
new file mode 100644 (file)
index 0000000..f19359e
--- /dev/null
@@ -0,0 +1,65 @@
+#include <algorithm>\r
+\r
+#include <quest.hpp>\r
+\r
+int QuestHandler::assign(std::string title,std::string desc,std::string req) {\r
+       Quest tmp;\r
+       char *tok;\r
+\r
+       tmp.title = title;\r
+       tmp.desc = desc;\r
+\r
+       tok = strtok(&req[0], "\n\r\t,");\r
+       tmp.need.emplace_back("", 0);\r
+\r
+       while (tok) {\r
+               if (!tmp.need.back().first.empty()) {\r
+                       tmp.need.back().second = atoi(tok);\r
+                       tmp.need.emplace_back("", 0);\r
+               } else\r
+                       tmp.need.back().first = tok;\r
+\r
+               tok = strtok(NULL, "\n\r\t,");\r
+       }\r
+\r
+       tmp.need.pop_back();\r
+       current.push_back(tmp);\r
+\r
+       return 0;\r
+}\r
+\r
+int QuestHandler::drop(std::string title) {\r
+       current.erase(std::remove_if (current.begin(),\r
+                                                                  current.end(),\r
+                                                                  [&](Quest q) { return q.title == title; }),\r
+                                  current.end());\r
+\r
+       return 0;\r
+}\r
+\r
+int QuestHandler::finish(std::string t) {\r
+       for (auto c = current.begin(); c != current.end(); c++) {\r
+               if ((*c).title == t) {\r
+                       //for (auto &n : (*c).need) {\r
+                               //if (player->inv->hasItem(n.first) < n.second)\r
+                                       return 0;\r
+                       //}\r
+\r
+                       //for (auto &n : (*c).need)\r
+                               //player->inv->takeItem(n.first, n.second);\r
+                       //current.erase(c);\r
+                       //return 1;\r
+               }\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+bool QuestHandler::hasQuest(std::string t) {\r
+       for (auto &c : current) {\r
+               if (c.title == t)\r
+                       return true;\r
+       }\r
+\r
+       return false;\r
+}\r
diff --git a/src/quest.cpp.bak b/src/quest.cpp.bak
deleted file mode 100644 (file)
index f19359e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <algorithm>\r
-\r
-#include <quest.hpp>\r
-\r
-int QuestHandler::assign(std::string title,std::string desc,std::string req) {\r
-       Quest tmp;\r
-       char *tok;\r
-\r
-       tmp.title = title;\r
-       tmp.desc = desc;\r
-\r
-       tok = strtok(&req[0], "\n\r\t,");\r
-       tmp.need.emplace_back("", 0);\r
-\r
-       while (tok) {\r
-               if (!tmp.need.back().first.empty()) {\r
-                       tmp.need.back().second = atoi(tok);\r
-                       tmp.need.emplace_back("", 0);\r
-               } else\r
-                       tmp.need.back().first = tok;\r
-\r
-               tok = strtok(NULL, "\n\r\t,");\r
-       }\r
-\r
-       tmp.need.pop_back();\r
-       current.push_back(tmp);\r
-\r
-       return 0;\r
-}\r
-\r
-int QuestHandler::drop(std::string title) {\r
-       current.erase(std::remove_if (current.begin(),\r
-                                                                  current.end(),\r
-                                                                  [&](Quest q) { return q.title == title; }),\r
-                                  current.end());\r
-\r
-       return 0;\r
-}\r
-\r
-int QuestHandler::finish(std::string t) {\r
-       for (auto c = current.begin(); c != current.end(); c++) {\r
-               if ((*c).title == t) {\r
-                       //for (auto &n : (*c).need) {\r
-                               //if (player->inv->hasItem(n.first) < n.second)\r
-                                       return 0;\r
-                       //}\r
-\r
-                       //for (auto &n : (*c).need)\r
-                               //player->inv->takeItem(n.first, n.second);\r
-                       //current.erase(c);\r
-                       //return 1;\r
-               }\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-bool QuestHandler::hasQuest(std::string t) {\r
-       for (auto &c : current) {\r
-               if (c.title == t)\r
-                       return true;\r
-       }\r
-\r
-       return false;\r
-}\r
index b47c3c74d498856e954107bd2fd0ab07ebeaaf1f..721e5cb7d9d69a04a46a9160174af2a92dec7aa9 100644 (file)
@@ -10,6 +10,10 @@ namespace Colors
        ColorTex red;
        ColorTex blue;
 
+       GLfloat texCoord[12] = {
+               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+       };
+
        void init(void) {
                white = ColorTex(Color(255, 255, 255));
                black = ColorTex(Color(0,   0,   0  ));
index 9470a56d1682fa8fc88de45c93b2e14288cb3112..552884f2cdfca5868db8f8c933d9fc0160eb9376 100644 (file)
@@ -650,8 +650,8 @@ namespace ui {
                auto stride = 5 * sizeof(GLfloat);
 
                // we always want to make sure c1 is lower left and c2 is upper right
-               if (c1.x > c2.x) c1.swapX(c2); // std::swap(c1.x, c2.y);
-               if (c1.y > c2.y) c1.swapY(c2); // std::swap(c1.y, c2.y);
+               if (c1.x > c2.x) std::swap(c1.x, c2.x);
+               if (c1.y > c2.y) std::swap(c1.y, c2.y);
 
                // if the box is too small, we will not be able to draw it
                if (c2.x - c1.x < (boxCornerDim.x) || c2.y - c1.y < (boxCornerDim.y))
index 65514421aa603fa73c8e3fc73ad4a0aa8caa6eef..8f4be8edfdb84ac57d057a6d4a7f03672e292a45 100644 (file)
@@ -324,9 +324,9 @@ void WorldSystem::load(const std::string& file)
                                                vec2 coords;
 
                                                if (wxml->Attribute("position") != nullptr) {
-                                                       coords = str2coord(wxml->StrAttribute("position"));
+                                                       coords = wxml->StrAttribute("position");
                                                } else {
-                                                       coords = str2coord(abcd->StrAttribute("value"));
+                                                       coords = abcd->StrAttribute("value");
                                                }
 
                                                float cdat[2] = {coords.x, coords.y};
@@ -345,7 +345,7 @@ void WorldSystem::load(const std::string& file)
                                                vec2 dim;
 
                                                if (abcd->Attribute("value") != nullptr)
-                                                       dim = str2coord(abcd->StrAttribute("value"));
+                                                       dim = abcd->StrAttribute("value");
                                                else
                                                        dim = entity.component<Sprite>()->getSpriteSize();
 
@@ -355,9 +355,9 @@ void WorldSystem::load(const std::string& file)
                                                vec2 dir;
 
                                                if (wxml->Attribute("direction") != nullptr) {
-                                                       dir = str2coord(wxml->StrAttribute("direction"));
+                                                       dir = wxml->StrAttribute("direction");
                                                } else if (wxml->Attribute("value") != nullptr) {
-                                                       dir = str2coord(wxml->StrAttribute("value"));
+                                                       dir = wxml->StrAttribute("value");
                                                } else {
                                                        dir = vec2(0,0);
                                                }
@@ -669,9 +669,8 @@ void WorldSystem::render(void)
        const auto SCREEN_WIDTH = game::SCREEN_WIDTH;
        const auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
 
-       const ivec2 backgroundOffset = ivec2 {
-        static_cast<int>(SCREEN_WIDTH) / 2, static_cast<int>(SCREEN_HEIGHT) / 2
-    };
+       const vector2<int> backgroundOffset
+               (static_cast<int>(SCREEN_WIDTH) / 2, static_cast<int>(SCREEN_HEIGHT) / 2);
 
        int iStart, iEnd, pOffset;
 
@@ -1179,8 +1178,6 @@ void WorldSystem::detect(entityx::TimeDelta dt)
 void WorldSystem::goWorldRight(Position& p, Solid &d)
 {
        if (!(world.toRight.empty()) && (p.x + d.width > world.startX * -1 - HLINES(5))) {
-               auto& rs = *game::engine.getSystem<RenderSystem>();
-               //rs.fadeLock();
                ui::toggleBlack();
                ui::waitForCover();
                while (waitToSwap)
@@ -1188,7 +1185,6 @@ void WorldSystem::goWorldRight(Position& p, Solid &d)
                load(world.toRight);
                game::engine.getSystem<PlayerSystem>()->setX(world.startX + HLINES(10));
                ui::toggleBlack();
-               //rs.unfade();
        }
 }
 
index 0a281240eed22257c18a2bd4126b5b57ef054942..47ddf273292849f1f6f6ba89ee363007544c87fd 100644 (file)
@@ -12,7 +12,6 @@
     <npc name="Bob" hasDialog="true" position="50.0,100.0"/>
     <structure type="1" position="300.0,100.0"/>
     <structure inside="bobshouse.xml" type="1" position="10.0,100.0"/>
-    <chest/>
 </World>
 
 <Dialog name="Bob">