]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
removed all old entity stuff
authorClyne Sullivan <tullivan99@gmail.com>
Thu, 20 Oct 2016 12:44:58 +0000 (08:44 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Thu, 20 Oct 2016 12:44:58 +0000 (08:44 -0400)
32 files changed:
include/entities.hpp [deleted file]
include/entities.hpp.bak [new file with mode: 0644]
include/inventory.hpp [deleted file]
include/inventory.hpp.bak [new file with mode: 0644]
include/mob.hpp [deleted file]
include/mob.hpp.bak [new file with mode: 0644]
include/quest.hpp [deleted file]
include/quest.hpp.bak [new file with mode: 0644]
include/ui.hpp
include/ui_action.hpp [deleted file]
include/ui_action.hpp.bak [new file with mode: 0644]
include/ui_quest.hpp
include/world.hpp
main.cpp
src/engine.cpp
src/entities.cpp [deleted file]
src/entities.cpp.bak [new file with mode: 0644]
src/inventory.cpp [deleted file]
src/inventory.cpp.bak [new file with mode: 0644]
src/items.cpp [deleted file]
src/items.cpp.bak [new file with mode: 0644]
src/mob.cpp [deleted file]
src/mob.cpp.bak [new file with mode: 0644]
src/quest.cpp [deleted file]
src/quest.cpp.bak [new file with mode: 0644]
src/ui.cpp
src/ui_action.cpp [deleted file]
src/ui_action.cpp.bak [new file with mode: 0644]
src/ui_menu.cpp
src/world.cpp
xml/!town.xml
xml/bobshouse.xml

diff --git a/include/entities.hpp b/include/entities.hpp
deleted file mode 100644 (file)
index 945e8c8..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/* ----------------------------------------------------------------------------
-** The entity stuffs.
-**
-** Entities.
-** --------------------------------------------------------------------------*/
-#ifndef ENTITIES_H
-#define ENTITIES_H
-#define DEBUG
-
-/* ----------------------------------------------------------------------------
-** Includes section
-** --------------------------------------------------------------------------*/
-
-// local game includes
-#include <common.hpp>
-#include <quest.hpp>
-#include <inventory.hpp>
-#include <texture.hpp>
-#include <save_util.hpp>
-#include <coolarray.hpp>
-
-// local library includes
-#include <tinyxml2.h>
-using namespace tinyxml2;
-
-/* ----------------------------------------------------------------------------
-** Structures section
-** --------------------------------------------------------------------------*/
-
-/**
- * An entity type enumerator for identifying entities.
- */
-enum _TYPE {
-       UNKNOWNT = -999, /**< who knows? */
-       OBJECTT = -2,    /**< an object (Object) */
-       STRUCTURET,              /**< a structure (Structures *) */
-       PLAYERT,                 /**< the player (Player *) */
-       NPCT,                    /**< an NPC (NPC *) */
-       MERCHT,                  /**< a merchant (Merchant *) */
-       MOBT                     /**< A mob (Mob *) */
-};
-
-/**
- * An enumerator for entity gender.
- */
-enum GENDER{
-       MALE,   /**< male */
-       FEMALE  /**< female */
-};
-
-/**
- * An enumerator for strcture types.
- * The subtype of a structure will affect how it is drawn and how it functions.
- */
-enum BUILD_SUB{
-       TOWN_HALL = 0,          /**< a town hall */
-       HOUSE,                          /**< a generic house */
-       HOUSE2,                         /**< a generic house of a different style */
-       HOUSE3,                         /**< a generic house of a different style */
-       HOUSE4,                         /**< a generic house of a different style */
-       FOUNTAIN,                       /**< a fountain, creates water particles */
-       LAMP_POST,                      /**< a lamppost, creates light */
-       FIRE_PIT,                       /**< a firepit, creates fire particles / light */
-       STALL_MARKET = 70,      /**< a stall for a merchant */
-       STALL_TRADER
-};
-
-/**
- * A structure for tracking potential trades between the player and a merchant.
- */
-struct Trade {
-       // the names of the items up for trade
-       std::string item[2];
-       // how much of each item to trade
-       int quantity[2];
-
-       // constructs a trade with the given values
-       Trade(int qo, std::string o, int qt, std::string t) {
-               item[0] = o;
-               item[1] = t;
-               quantity[0] = qo;
-               quantity[1] = qt;
-       }
-
-       // creates an empty trade item
-       Trade(void) {
-               item[0] = "";
-               item[1] = "";
-               quantity[0] = 0;
-               quantity[1] = 0;
-       }
-};
-typedef struct Trade Trade;
-
-/* ----------------------------------------------------------------------------
-** Variables section
-** --------------------------------------------------------------------------*/
-
-// the size of the player's inventory
-extern const unsigned int PLAYER_INV_SIZE;
-// the size of an NPC's inventory
-extern const unsigned int NPC_INV_SIZE;
-
-/* ----------------------------------------------------------------------------
-** Classes / function prototypes section
-** --------------------------------------------------------------------------*/
-
-// a prototype of the world class, necessary for some function prototypes
-class World;
-class IndoorWorld;
-
-/**
- * The light structure, used to store light coordinates and color.
- */
-
-class Light{
-public:
-       vec2 loc;               /**< Light location */
-       Color color;    /**< Light color */
-       float radius;   /**< Light radius */
-
-       bool belongsTo;
-       Entity *following;
-
-       bool flame;
-       float fireFlicker;
-       vec2 fireLoc;
-       Light()
-       {
-               loc = vec2(0,0);
-               color = Color(1.0, 1.0, 1.0);
-               radius = 0;
-
-               belongsTo = false;
-               following = nullptr;
-
-               flame = false;
-       }
-
-       Light(vec2 l, float r, Color c)
-       {
-               loc = l;
-               color = c;
-               radius = r;
-
-               belongsTo = false;
-               following = nullptr;
-
-               flame = false;
-       }
-
-       void follow(Entity *f)
-       {
-               following = f;
-               belongsTo = true;
-       }
-
-       void makeFlame(void)
-       {
-               flame = true;
-       }
-
-       void createFromXML(XMLElement *e);
-};
-
-/**
- * The entity class.
- * This class contains common functions and variables for all types of
- * entities, i.e. a common structure.
- */
-class Entity{
-protected:
-       // an incrementer for invincibility after a hit
-       unsigned int hitCooldown;
-
-       // an incrementer for triggering change of movement with wander()
-       int ticksToUse;
-
-       // entity handles an applied hit (sword) if set true
-       bool forcedMove;
-
-       // if set false, entity will be destroyed
-       bool alive;
-
-       // TODO
-       float targetx;
-
-       // the cooldown display (red overlay)
-       float hitDuration;
-
-       // the max cooldown display
-       float maxHitDuration;
-
-       // the entity's XML element, for saving/loading stuff
-       XMLElement *xmle;
-
-public:
-       // contains the entity's coordinates, in pixels
-       vec2 loc;
-       float z;
-
-       // contains the entity's velocity, in pixels
-       vec2 vel;
-
-       // the entity's width, in pixels
-       float width;
-
-       // the entity's height, in pixels
-       float height;
-
-       // a speed multiplier, applied to velocity
-       float speed;
-
-       // when true player may interact, and the entity's name will be drawn
-       bool near;
-
-       // when true, the entity can move
-       int canMove;
-
-       // tells direction entity is facing
-       bool right, left;
-
-       // tells if the entity is from another world
-       char outnabout;
-
-       // set to 1 if entity is on the ground, 0 if in the air
-       unsigned char ground;
-
-       // the entity's inventory
-       Inventory *inv;
-
-       // the entity's light
-       Light light;
-
-       // the entity's health
-       float health;
-
-       // the most health the entity can have
-       float maxHealth;
-
-       // the type of the entity
-       _TYPE type;
-
-       // the entity's subtype, if applicable
-       int     subtype;
-
-       // the entity's name, randomly generated on spawn
-       std::string name;
-
-       // the entity's gender
-       GENDER  gender;
-
-       // a texture handler for the entity
-       TextureIterator tex;
-
-       // draws the entity to the screen
-       void draw(void);
-
-       // spawns the entity at the given coordinates
-       void spawn(float, float);
-
-       // allows the entity to wander, according to what class is deriving this.
-       virtual void wander(int){}
-       virtual void wander(void){}
-
-       // allows the entity to interact with the player
-       virtual void interact(void){}
-
-       // causes the entity to move to the given x coordinate
-       void moveTo(float dest_x);
-
-       // causes the entity to follow the one provided
-       void follow(Entity *e);
-
-       // causes the entity to take a player-inflicted hit
-       void takeHit(unsigned int _health, unsigned int cooldown);
-
-       // returns the amount of cool down before next hit
-       unsigned int coolDown();
-
-       // set the cool down
-       void setCooldown(unsigned int c);
-
-       // handles hits if they've been taken
-       void handleHits(void);
-
-       // insures that the entity is dead
-       void die(void);
-
-       // checks if the entity is alive
-       bool isAlive(void) const;
-
-       // checks if the entity is hit in some way
-       bool isHit(void) const;
-
-       // returns true if this entity is near the one provided
-       bool isNear(const Entity *e);
-
-       // returns true if the coordinate is within the entity
-       bool isInside(vec2 coord) const;
-
-       // constructs the entity with an XML thing-thang
-       virtual void createFromXML(XMLElement *e, World *w=nullptr) =0;
-       virtual void saveToXML(void) =0;
-
-/*     Entity
-
-       **
-        * Forces the given entity to follow this one.
-        *
-       void lead(Entity *e, unsigned int how);
-
-       **
-        * Attempts to break free from any following.
-        *
-       void unfollow(void);*/
-
-       // a common constructor, clears variables
-       Entity(void);
-
-       // frees memory taken by the entity
-       virtual ~Entity(){}
-};
-
-class Player : public Entity {
-public:
-       Entity *ride;
-       QuestHandler qh;
-
-       Player();
-       ~Player();
-       void save(void);
-       void sspawn(float x,float y);
-       void createFromXML(XMLElement *e, World *w);
-       void saveToXML(void);
-};
-
-class Structures : public Entity {
-public:
-       BUILD_SUB bsubtype;
-       World *inWorld;
-       World *insideWorld;
-       std::string inside;
-       std::string textureLoc;
-
-       GLuint insideTex;
-
-       Structures();
-       ~Structures();
-
-       unsigned int spawn(BUILD_SUB, float, float);
-       void createFromXML(XMLElement *e, World *w);
-       void saveToXML(void);
-};
-
-
-class NPC : public Entity {
-private:
-       // the number of the random dialog to use
-       unsigned int randDialog;
-
-       unsigned int dialogCount;
-
-public:
-       int dialogIndex;
-
-       NPC();
-       ~NPC();
-
-       void drawThingy(void) const;
-
-       void addAIFunc(bool preload);
-
-       void interact();
-       void wander(int);
-       void createFromXML(XMLElement *e, World *w);
-       void saveToXML(void);
-};
-
-class Merchant : public NPC {
-public:
-       std::vector<Trade>trade;
-       uint currTrade;
-
-       std::string text[4];
-       std::string *toSay;
-       //greeting
-       //accept
-       //deny
-       //farewell
-
-       void interact();
-       Structures *inside;
-
-       Merchant();
-       ~Merchant();
-
-       void wander(int);
-       void saveToXML(void);
-};
-
-class Object : public Entity{
-public:
-       std::string iname;
-       std::string pickupDialog;
-       bool questObject = false;
-
-       Object();
-       Object(std::string in,std::string pd);
-       ~Object();
-
-       void reloadTexture(void);
-
-       void interact(void);
-
-       bool operator==(const Object &o) {
-               return (name == o.name) && (loc == o.loc);
-       }
-       void createFromXML(XMLElement *e, World *w);
-       void saveToXML(void);
-};
-
-/**
- * The particle class, handles a single particle.
- */
-class Particles{
-public:
-       // the location of the particle
-       vec2 loc;
-       float zOffset;
-
-       // the width of the particle, in pixels
-       float width;
-
-       // the height of the particle, in pixels
-       float height;
-
-       // the velocity of the particle, in pixels
-       vec2 vel;
-
-       // the color of the particle
-       Color color;
-
-       // TODO
-       vec2 index;
-
-       // the amount of milliseconds left for the particle to live
-       float duration;
-
-       // when true, the particle will move
-       bool canMove;
-
-       // TODO
-       bool fountain;
-
-       // when true, the particle will be affected by gravity
-       bool gravity;
-
-       // when true, draws the particle behind structures
-       bool behind;
-
-       // when true, the particle will bounce on impact with ground
-       bool bounce;
-
-       Structures *stu;
-
-       Particles(void){}
-
-       // creates a particle with the desired characteristics
-       Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d);
-
-       // allows the particle to be destroyed
-       ~Particles(void){}
-
-       // draws the particle
-       void draw(GLfloat*& p) const;
-
-       // updates a particle
-       void update(float _gravity, float ground_y);
-
-       // returns true if the particle should be killed
-       bool timeUp(void);
-};
-
-#include <mob.hpp>
-
-constexpr Object *Objectp(Entity *e) {
-       return (Object *)e;
-}
-
-constexpr NPC *NPCp(Entity *e) {
-       return (NPC *)e;
-}
-
-constexpr Structures *Structurep(Entity *e) {
-       return (Structures *)e;
-}
-
-constexpr Merchant *Merchantp(Entity *e) {
-       return (Merchant *)e;
-}
-
-#include <entityx/entityx.h>
-#include <events.hpp>
-
-class PlayerSystem : public entityx::System<PlayerSystem>, public entityx::Receiver<PlayerSystem> {
-private:
-       Player **m_Player;
-       bool m_MoveLeft, m_MoveRight;
-
-public:
-       PlayerSystem(Player **p)
-               : m_Player(p), m_MoveLeft(false), m_MoveRight(false) {}
-
-       void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
-
-       void configure(entityx::EventManager &ev);
-       void receive(const KeyDownEvent &kde);
-       void receive(const KeyUpEvent &kue);
-};
-
-
-#endif // ENTITIES_H
-
-/**
-ENTITY TYPES
--1 STRUCTURES
-|->1 Village
-|->2 Castle
-|
-0 PLAYERS
-|->Player
-|
-1 NPCS
-|->0 Base
-|->1 Merchant
-|
-2 MOBS
-|->1 Rabbit
-|->2 Bird
-**/
diff --git a/include/entities.hpp.bak b/include/entities.hpp.bak
new file mode 100644 (file)
index 0000000..945e8c8
--- /dev/null
@@ -0,0 +1,541 @@
+/* ----------------------------------------------------------------------------
+** The entity stuffs.
+**
+** Entities.
+** --------------------------------------------------------------------------*/
+#ifndef ENTITIES_H
+#define ENTITIES_H
+#define DEBUG
+
+/* ----------------------------------------------------------------------------
+** Includes section
+** --------------------------------------------------------------------------*/
+
+// local game includes
+#include <common.hpp>
+#include <quest.hpp>
+#include <inventory.hpp>
+#include <texture.hpp>
+#include <save_util.hpp>
+#include <coolarray.hpp>
+
+// local library includes
+#include <tinyxml2.h>
+using namespace tinyxml2;
+
+/* ----------------------------------------------------------------------------
+** Structures section
+** --------------------------------------------------------------------------*/
+
+/**
+ * An entity type enumerator for identifying entities.
+ */
+enum _TYPE {
+       UNKNOWNT = -999, /**< who knows? */
+       OBJECTT = -2,    /**< an object (Object) */
+       STRUCTURET,              /**< a structure (Structures *) */
+       PLAYERT,                 /**< the player (Player *) */
+       NPCT,                    /**< an NPC (NPC *) */
+       MERCHT,                  /**< a merchant (Merchant *) */
+       MOBT                     /**< A mob (Mob *) */
+};
+
+/**
+ * An enumerator for entity gender.
+ */
+enum GENDER{
+       MALE,   /**< male */
+       FEMALE  /**< female */
+};
+
+/**
+ * An enumerator for strcture types.
+ * The subtype of a structure will affect how it is drawn and how it functions.
+ */
+enum BUILD_SUB{
+       TOWN_HALL = 0,          /**< a town hall */
+       HOUSE,                          /**< a generic house */
+       HOUSE2,                         /**< a generic house of a different style */
+       HOUSE3,                         /**< a generic house of a different style */
+       HOUSE4,                         /**< a generic house of a different style */
+       FOUNTAIN,                       /**< a fountain, creates water particles */
+       LAMP_POST,                      /**< a lamppost, creates light */
+       FIRE_PIT,                       /**< a firepit, creates fire particles / light */
+       STALL_MARKET = 70,      /**< a stall for a merchant */
+       STALL_TRADER
+};
+
+/**
+ * A structure for tracking potential trades between the player and a merchant.
+ */
+struct Trade {
+       // the names of the items up for trade
+       std::string item[2];
+       // how much of each item to trade
+       int quantity[2];
+
+       // constructs a trade with the given values
+       Trade(int qo, std::string o, int qt, std::string t) {
+               item[0] = o;
+               item[1] = t;
+               quantity[0] = qo;
+               quantity[1] = qt;
+       }
+
+       // creates an empty trade item
+       Trade(void) {
+               item[0] = "";
+               item[1] = "";
+               quantity[0] = 0;
+               quantity[1] = 0;
+       }
+};
+typedef struct Trade Trade;
+
+/* ----------------------------------------------------------------------------
+** Variables section
+** --------------------------------------------------------------------------*/
+
+// the size of the player's inventory
+extern const unsigned int PLAYER_INV_SIZE;
+// the size of an NPC's inventory
+extern const unsigned int NPC_INV_SIZE;
+
+/* ----------------------------------------------------------------------------
+** Classes / function prototypes section
+** --------------------------------------------------------------------------*/
+
+// a prototype of the world class, necessary for some function prototypes
+class World;
+class IndoorWorld;
+
+/**
+ * The light structure, used to store light coordinates and color.
+ */
+
+class Light{
+public:
+       vec2 loc;               /**< Light location */
+       Color color;    /**< Light color */
+       float radius;   /**< Light radius */
+
+       bool belongsTo;
+       Entity *following;
+
+       bool flame;
+       float fireFlicker;
+       vec2 fireLoc;
+       Light()
+       {
+               loc = vec2(0,0);
+               color = Color(1.0, 1.0, 1.0);
+               radius = 0;
+
+               belongsTo = false;
+               following = nullptr;
+
+               flame = false;
+       }
+
+       Light(vec2 l, float r, Color c)
+       {
+               loc = l;
+               color = c;
+               radius = r;
+
+               belongsTo = false;
+               following = nullptr;
+
+               flame = false;
+       }
+
+       void follow(Entity *f)
+       {
+               following = f;
+               belongsTo = true;
+       }
+
+       void makeFlame(void)
+       {
+               flame = true;
+       }
+
+       void createFromXML(XMLElement *e);
+};
+
+/**
+ * The entity class.
+ * This class contains common functions and variables for all types of
+ * entities, i.e. a common structure.
+ */
+class Entity{
+protected:
+       // an incrementer for invincibility after a hit
+       unsigned int hitCooldown;
+
+       // an incrementer for triggering change of movement with wander()
+       int ticksToUse;
+
+       // entity handles an applied hit (sword) if set true
+       bool forcedMove;
+
+       // if set false, entity will be destroyed
+       bool alive;
+
+       // TODO
+       float targetx;
+
+       // the cooldown display (red overlay)
+       float hitDuration;
+
+       // the max cooldown display
+       float maxHitDuration;
+
+       // the entity's XML element, for saving/loading stuff
+       XMLElement *xmle;
+
+public:
+       // contains the entity's coordinates, in pixels
+       vec2 loc;
+       float z;
+
+       // contains the entity's velocity, in pixels
+       vec2 vel;
+
+       // the entity's width, in pixels
+       float width;
+
+       // the entity's height, in pixels
+       float height;
+
+       // a speed multiplier, applied to velocity
+       float speed;
+
+       // when true player may interact, and the entity's name will be drawn
+       bool near;
+
+       // when true, the entity can move
+       int canMove;
+
+       // tells direction entity is facing
+       bool right, left;
+
+       // tells if the entity is from another world
+       char outnabout;
+
+       // set to 1 if entity is on the ground, 0 if in the air
+       unsigned char ground;
+
+       // the entity's inventory
+       Inventory *inv;
+
+       // the entity's light
+       Light light;
+
+       // the entity's health
+       float health;
+
+       // the most health the entity can have
+       float maxHealth;
+
+       // the type of the entity
+       _TYPE type;
+
+       // the entity's subtype, if applicable
+       int     subtype;
+
+       // the entity's name, randomly generated on spawn
+       std::string name;
+
+       // the entity's gender
+       GENDER  gender;
+
+       // a texture handler for the entity
+       TextureIterator tex;
+
+       // draws the entity to the screen
+       void draw(void);
+
+       // spawns the entity at the given coordinates
+       void spawn(float, float);
+
+       // allows the entity to wander, according to what class is deriving this.
+       virtual void wander(int){}
+       virtual void wander(void){}
+
+       // allows the entity to interact with the player
+       virtual void interact(void){}
+
+       // causes the entity to move to the given x coordinate
+       void moveTo(float dest_x);
+
+       // causes the entity to follow the one provided
+       void follow(Entity *e);
+
+       // causes the entity to take a player-inflicted hit
+       void takeHit(unsigned int _health, unsigned int cooldown);
+
+       // returns the amount of cool down before next hit
+       unsigned int coolDown();
+
+       // set the cool down
+       void setCooldown(unsigned int c);
+
+       // handles hits if they've been taken
+       void handleHits(void);
+
+       // insures that the entity is dead
+       void die(void);
+
+       // checks if the entity is alive
+       bool isAlive(void) const;
+
+       // checks if the entity is hit in some way
+       bool isHit(void) const;
+
+       // returns true if this entity is near the one provided
+       bool isNear(const Entity *e);
+
+       // returns true if the coordinate is within the entity
+       bool isInside(vec2 coord) const;
+
+       // constructs the entity with an XML thing-thang
+       virtual void createFromXML(XMLElement *e, World *w=nullptr) =0;
+       virtual void saveToXML(void) =0;
+
+/*     Entity
+
+       **
+        * Forces the given entity to follow this one.
+        *
+       void lead(Entity *e, unsigned int how);
+
+       **
+        * Attempts to break free from any following.
+        *
+       void unfollow(void);*/
+
+       // a common constructor, clears variables
+       Entity(void);
+
+       // frees memory taken by the entity
+       virtual ~Entity(){}
+};
+
+class Player : public Entity {
+public:
+       Entity *ride;
+       QuestHandler qh;
+
+       Player();
+       ~Player();
+       void save(void);
+       void sspawn(float x,float y);
+       void createFromXML(XMLElement *e, World *w);
+       void saveToXML(void);
+};
+
+class Structures : public Entity {
+public:
+       BUILD_SUB bsubtype;
+       World *inWorld;
+       World *insideWorld;
+       std::string inside;
+       std::string textureLoc;
+
+       GLuint insideTex;
+
+       Structures();
+       ~Structures();
+
+       unsigned int spawn(BUILD_SUB, float, float);
+       void createFromXML(XMLElement *e, World *w);
+       void saveToXML(void);
+};
+
+
+class NPC : public Entity {
+private:
+       // the number of the random dialog to use
+       unsigned int randDialog;
+
+       unsigned int dialogCount;
+
+public:
+       int dialogIndex;
+
+       NPC();
+       ~NPC();
+
+       void drawThingy(void) const;
+
+       void addAIFunc(bool preload);
+
+       void interact();
+       void wander(int);
+       void createFromXML(XMLElement *e, World *w);
+       void saveToXML(void);
+};
+
+class Merchant : public NPC {
+public:
+       std::vector<Trade>trade;
+       uint currTrade;
+
+       std::string text[4];
+       std::string *toSay;
+       //greeting
+       //accept
+       //deny
+       //farewell
+
+       void interact();
+       Structures *inside;
+
+       Merchant();
+       ~Merchant();
+
+       void wander(int);
+       void saveToXML(void);
+};
+
+class Object : public Entity{
+public:
+       std::string iname;
+       std::string pickupDialog;
+       bool questObject = false;
+
+       Object();
+       Object(std::string in,std::string pd);
+       ~Object();
+
+       void reloadTexture(void);
+
+       void interact(void);
+
+       bool operator==(const Object &o) {
+               return (name == o.name) && (loc == o.loc);
+       }
+       void createFromXML(XMLElement *e, World *w);
+       void saveToXML(void);
+};
+
+/**
+ * The particle class, handles a single particle.
+ */
+class Particles{
+public:
+       // the location of the particle
+       vec2 loc;
+       float zOffset;
+
+       // the width of the particle, in pixels
+       float width;
+
+       // the height of the particle, in pixels
+       float height;
+
+       // the velocity of the particle, in pixels
+       vec2 vel;
+
+       // the color of the particle
+       Color color;
+
+       // TODO
+       vec2 index;
+
+       // the amount of milliseconds left for the particle to live
+       float duration;
+
+       // when true, the particle will move
+       bool canMove;
+
+       // TODO
+       bool fountain;
+
+       // when true, the particle will be affected by gravity
+       bool gravity;
+
+       // when true, draws the particle behind structures
+       bool behind;
+
+       // when true, the particle will bounce on impact with ground
+       bool bounce;
+
+       Structures *stu;
+
+       Particles(void){}
+
+       // creates a particle with the desired characteristics
+       Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d);
+
+       // allows the particle to be destroyed
+       ~Particles(void){}
+
+       // draws the particle
+       void draw(GLfloat*& p) const;
+
+       // updates a particle
+       void update(float _gravity, float ground_y);
+
+       // returns true if the particle should be killed
+       bool timeUp(void);
+};
+
+#include <mob.hpp>
+
+constexpr Object *Objectp(Entity *e) {
+       return (Object *)e;
+}
+
+constexpr NPC *NPCp(Entity *e) {
+       return (NPC *)e;
+}
+
+constexpr Structures *Structurep(Entity *e) {
+       return (Structures *)e;
+}
+
+constexpr Merchant *Merchantp(Entity *e) {
+       return (Merchant *)e;
+}
+
+#include <entityx/entityx.h>
+#include <events.hpp>
+
+class PlayerSystem : public entityx::System<PlayerSystem>, public entityx::Receiver<PlayerSystem> {
+private:
+       Player **m_Player;
+       bool m_MoveLeft, m_MoveRight;
+
+public:
+       PlayerSystem(Player **p)
+               : m_Player(p), m_MoveLeft(false), m_MoveRight(false) {}
+
+       void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
+
+       void configure(entityx::EventManager &ev);
+       void receive(const KeyDownEvent &kde);
+       void receive(const KeyUpEvent &kue);
+};
+
+
+#endif // ENTITIES_H
+
+/**
+ENTITY TYPES
+-1 STRUCTURES
+|->1 Village
+|->2 Castle
+|
+0 PLAYERS
+|->Player
+|
+1 NPCS
+|->0 Base
+|->1 Merchant
+|
+2 MOBS
+|->1 Rabbit
+|->2 Bird
+**/
diff --git a/include/inventory.hpp b/include/inventory.hpp
deleted file mode 100644 (file)
index 533318c..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-#ifndef INVENTORY_H
-#define INVENTORY_H
-
-#include <common.hpp>
-#include <string.h>
-
-#include <texture.hpp>
-#include <events.hpp>
-
-#define DEBUG
-
-class Entity;
-
-/**
- *     The base item class
- *     This stores the name, width, height, and texture(s)
- */
-class Item {
-private:
-       bool beingUsed;
-
-protected:
-       std::vector<Entity*> interact;
-       
-public:
-
-       // what we want to call each item
-       std::string name;
-
-       // how many pixel tall and white each thing is
-       dim2 dim;
-
-       // the total amount of this item each slot can have
-       uint maxStackSize;
-
-       // the array of textures for each frame of animation
-       Texturec *tex;
-
-       // how much the item is rotated in the hand
-       float rotation = 0.0f;
-
-       // return if the item is currently in use
-       virtual bool inUse();
-
-       // set the state of the item
-       virtual void setUse(bool use);
-
-       // add entities to the list of those being interacted
-       virtual void addInteract(Entity* e);
-       virtual void addInteract(std::vector<Entity*> e);
-
-       /**
-        *      The function we use to call the child classes ability
-        *      Note: Since this function is abstract, we HAVE to create one for each
-        *      child class/type of item.
-        */
-       virtual int useItem()=0;
-
-       virtual Item* clone()=0;
-
-       // destructor
-       virtual ~Item();
-       // return the first texture for the item
-       GLuint rtex();
-
-       // return the nth texture for the item
-       GLuint rtex(int n);
-};
-
-/**
- *     Class for blank items, we use this for items that do not have an ability
- *     Like Quest or Debug items
- */
-class BaseItem : public Item {
-public:
-       // since the items don't have a use, we don't make one for it
-       int useItem();
-
-       BaseItem* clone();
-
-       //~BaseItem(){}
-};
-
-/**
- *     Sword class. This is for swords, y'know. Pretty basic stuff
- */
-class Sword : public Item {
-//     can't touch this
-private:
-       /**
-        *      How much damage our sword will do
-        *      notice that it's private to avoid a change
-        */
-       float damage;
-
-       Ray hitbox;
-
-//can touch this
-public:
-       /**
-        *      Lets us return the amount of damage the sword has
-        *      TODO takes into account enchants and/or buffs/nerfs
-        */
-       //TODO move
-       float getDamage();
-
-       // set the damage of the sword
-       void setDamage(float d);
-
-       /**
-        *      handles the swinging of the sword
-        */
-       //TODO move
-       int useItem();
-
-       Sword* clone();
-};
-
-class Arrow : public Item {
-private:
-       // same as sword
-       float damage;
-public:
-
-       // see sword
-       float getDamage();
-
-       // sets amount of damage
-       void setDamage(float d);
-
-       // uses item
-       int useItem();
-
-       Arrow *clone();
-};
-
-/**
- *     Bow class. We use this for shooting bow and arrows
- */
-class Bow : public Item {
-private:
-       // same as sword
-       float damage;
-public:
-       // returns the amount of damage, see sword
-       float getDamage();
-
-       // sets the amount of damages
-       void setDamage(float d);
-
-       // handles shooting and arrow curving
-       int useItem();
-
-       Bow* clone();
-};
-
-/**
- *     Raw food class, this will be used for uncooked meats...
- *     TODO Eating this may cause health loss, salmonela, mad cow diese
- */
-class RawFood : public Item {
-private:
-       // the amount of the health the food heals
-       float health;
-
-public:
-       // since the health is private, we get how much it is here
-       float getHealth();
-
-       // TODO chance to hurt
-       virtual int useItem();
-
-       RawFood* clone();
-};
-
-/**
- *     Cooked/Naturale food class
- *     When this food is consumed, higher stats are gained than Raw Food and
- *     there is no chance of damage/de-buffs
- */
-class Food : public RawFood {
-private:
-public:
-
-       // consume food in hand, no chance for de-buff;
-       int useItem();
-
-       Food* clone();
-};
-
-class ItemLight : public Item {
-private:
-       // the color of the light
-       Color color;
-public:
-       // turn on/off the light
-       // TODO
-       int useItem();
-
-       ItemLight* clone();
-};
-
-/**
- *     Currency class. Well, it's used for currency
- */
-class NewCurrency : public Item {
-private:
-       // how much the coin is "worth" so to say
-       int value;
-public:
-       // get the value of the coin
-       int getValue();
-
-       // TODO maybe play a jingling noise
-       // probably won't have a use
-       int useItem();
-
-       NewCurrency(){}
-       ~NewCurrency(){}
-};
-
-/***********************************************************************************
- *                                             OLD STUFF THAT NEEDS TO GET UPDATED                                                *
- **********************************************************************************/
-
-using InventorySlot = std::pair<Item *, unsigned int>;
-
-class Inventory {
-private:
-       unsigned int size; //how many slots our inventory has
-       unsigned int sel; //what item is currently selected
-       int os = 0;
-public:
-       std::vector<InventorySlot> Items;
-
-       bool invOpen = false; //is the inventory open
-       bool invOpening = false; //is the opening animation playing
-       bool invHover = false; //are we using the fancy hover inventory
-       bool selected = false; //used in hover inventory to show which item has been selected
-       bool mouseSel = false; //the location of the temperary selection for the hover inv
-       bool usingi = false; //bool used to tell if inventory owner is using selected item
-
-       Inventory(unsigned int s);      // Creates an inventory of size 's'
-       ~Inventory(void);                       // Free's allocated memory
-
-       int useCurrent();
-       void currentAddInteract(Entity* e);
-       void currentAddInteract(std::vector<Entity*> e);
-
-       int addItem(std::string name,uint count);
-       int takeItem(std::string name,uint count);
-       int hasItem(std::string name);
-
-       int useItem(void);
-       bool detectCollision(vec2,vec2);
-
-       void setSelection(unsigned int s);
-       void setSelectionUp();
-       void setSelectionDown();
-
-       void draw(void);        // Draws a text list of items in this inventory (should only be called for the player for now)
-
-       const Item* getCurrentItem(void);
-};
-
-void initInventorySprites(void);
-void destroyInventory(void);
-
-const char *getItemTexturePath(std::string name);
-GLuint getItemTexture(std::string name);
-float getItemWidth(std::string name);
-float getItemHeight(std::string name);
-
-#include <entityx/entityx.h>
-
-class InventorySystem : public entityx::System<InventorySystem>, public entityx::Receiver<InventorySystem> {
-public:
-       void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
-
-       void configure(entityx::EventManager &em);
-       void receive(const MouseScrollEvent &mse);
-};
-
-#endif // INVENTORY_H
diff --git a/include/inventory.hpp.bak b/include/inventory.hpp.bak
new file mode 100644 (file)
index 0000000..533318c
--- /dev/null
@@ -0,0 +1,284 @@
+#ifndef INVENTORY_H
+#define INVENTORY_H
+
+#include <common.hpp>
+#include <string.h>
+
+#include <texture.hpp>
+#include <events.hpp>
+
+#define DEBUG
+
+class Entity;
+
+/**
+ *     The base item class
+ *     This stores the name, width, height, and texture(s)
+ */
+class Item {
+private:
+       bool beingUsed;
+
+protected:
+       std::vector<Entity*> interact;
+       
+public:
+
+       // what we want to call each item
+       std::string name;
+
+       // how many pixel tall and white each thing is
+       dim2 dim;
+
+       // the total amount of this item each slot can have
+       uint maxStackSize;
+
+       // the array of textures for each frame of animation
+       Texturec *tex;
+
+       // how much the item is rotated in the hand
+       float rotation = 0.0f;
+
+       // return if the item is currently in use
+       virtual bool inUse();
+
+       // set the state of the item
+       virtual void setUse(bool use);
+
+       // add entities to the list of those being interacted
+       virtual void addInteract(Entity* e);
+       virtual void addInteract(std::vector<Entity*> e);
+
+       /**
+        *      The function we use to call the child classes ability
+        *      Note: Since this function is abstract, we HAVE to create one for each
+        *      child class/type of item.
+        */
+       virtual int useItem()=0;
+
+       virtual Item* clone()=0;
+
+       // destructor
+       virtual ~Item();
+       // return the first texture for the item
+       GLuint rtex();
+
+       // return the nth texture for the item
+       GLuint rtex(int n);
+};
+
+/**
+ *     Class for blank items, we use this for items that do not have an ability
+ *     Like Quest or Debug items
+ */
+class BaseItem : public Item {
+public:
+       // since the items don't have a use, we don't make one for it
+       int useItem();
+
+       BaseItem* clone();
+
+       //~BaseItem(){}
+};
+
+/**
+ *     Sword class. This is for swords, y'know. Pretty basic stuff
+ */
+class Sword : public Item {
+//     can't touch this
+private:
+       /**
+        *      How much damage our sword will do
+        *      notice that it's private to avoid a change
+        */
+       float damage;
+
+       Ray hitbox;
+
+//can touch this
+public:
+       /**
+        *      Lets us return the amount of damage the sword has
+        *      TODO takes into account enchants and/or buffs/nerfs
+        */
+       //TODO move
+       float getDamage();
+
+       // set the damage of the sword
+       void setDamage(float d);
+
+       /**
+        *      handles the swinging of the sword
+        */
+       //TODO move
+       int useItem();
+
+       Sword* clone();
+};
+
+class Arrow : public Item {
+private:
+       // same as sword
+       float damage;
+public:
+
+       // see sword
+       float getDamage();
+
+       // sets amount of damage
+       void setDamage(float d);
+
+       // uses item
+       int useItem();
+
+       Arrow *clone();
+};
+
+/**
+ *     Bow class. We use this for shooting bow and arrows
+ */
+class Bow : public Item {
+private:
+       // same as sword
+       float damage;
+public:
+       // returns the amount of damage, see sword
+       float getDamage();
+
+       // sets the amount of damages
+       void setDamage(float d);
+
+       // handles shooting and arrow curving
+       int useItem();
+
+       Bow* clone();
+};
+
+/**
+ *     Raw food class, this will be used for uncooked meats...
+ *     TODO Eating this may cause health loss, salmonela, mad cow diese
+ */
+class RawFood : public Item {
+private:
+       // the amount of the health the food heals
+       float health;
+
+public:
+       // since the health is private, we get how much it is here
+       float getHealth();
+
+       // TODO chance to hurt
+       virtual int useItem();
+
+       RawFood* clone();
+};
+
+/**
+ *     Cooked/Naturale food class
+ *     When this food is consumed, higher stats are gained than Raw Food and
+ *     there is no chance of damage/de-buffs
+ */
+class Food : public RawFood {
+private:
+public:
+
+       // consume food in hand, no chance for de-buff;
+       int useItem();
+
+       Food* clone();
+};
+
+class ItemLight : public Item {
+private:
+       // the color of the light
+       Color color;
+public:
+       // turn on/off the light
+       // TODO
+       int useItem();
+
+       ItemLight* clone();
+};
+
+/**
+ *     Currency class. Well, it's used for currency
+ */
+class NewCurrency : public Item {
+private:
+       // how much the coin is "worth" so to say
+       int value;
+public:
+       // get the value of the coin
+       int getValue();
+
+       // TODO maybe play a jingling noise
+       // probably won't have a use
+       int useItem();
+
+       NewCurrency(){}
+       ~NewCurrency(){}
+};
+
+/***********************************************************************************
+ *                                             OLD STUFF THAT NEEDS TO GET UPDATED                                                *
+ **********************************************************************************/
+
+using InventorySlot = std::pair<Item *, unsigned int>;
+
+class Inventory {
+private:
+       unsigned int size; //how many slots our inventory has
+       unsigned int sel; //what item is currently selected
+       int os = 0;
+public:
+       std::vector<InventorySlot> Items;
+
+       bool invOpen = false; //is the inventory open
+       bool invOpening = false; //is the opening animation playing
+       bool invHover = false; //are we using the fancy hover inventory
+       bool selected = false; //used in hover inventory to show which item has been selected
+       bool mouseSel = false; //the location of the temperary selection for the hover inv
+       bool usingi = false; //bool used to tell if inventory owner is using selected item
+
+       Inventory(unsigned int s);      // Creates an inventory of size 's'
+       ~Inventory(void);                       // Free's allocated memory
+
+       int useCurrent();
+       void currentAddInteract(Entity* e);
+       void currentAddInteract(std::vector<Entity*> e);
+
+       int addItem(std::string name,uint count);
+       int takeItem(std::string name,uint count);
+       int hasItem(std::string name);
+
+       int useItem(void);
+       bool detectCollision(vec2,vec2);
+
+       void setSelection(unsigned int s);
+       void setSelectionUp();
+       void setSelectionDown();
+
+       void draw(void);        // Draws a text list of items in this inventory (should only be called for the player for now)
+
+       const Item* getCurrentItem(void);
+};
+
+void initInventorySprites(void);
+void destroyInventory(void);
+
+const char *getItemTexturePath(std::string name);
+GLuint getItemTexture(std::string name);
+float getItemWidth(std::string name);
+float getItemHeight(std::string name);
+
+#include <entityx/entityx.h>
+
+class InventorySystem : public entityx::System<InventorySystem>, public entityx::Receiver<InventorySystem> {
+public:
+       void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
+
+       void configure(entityx::EventManager &em);
+       void receive(const MouseScrollEvent &mse);
+};
+
+#endif // INVENTORY_H
diff --git a/include/mob.hpp b/include/mob.hpp
deleted file mode 100644 (file)
index 24b8ed9..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-#ifndef MOB_H_
-#define MOB_H_
-
-#include <forward_list>
-#include <tuple>
-
-#include <common.hpp>
-#include <entities.hpp>
-#include <gametime.hpp>
-#include <ui.hpp>
-#include <save_util.hpp>
-
-// local library headers
-#include <tinyxml2.h>
-using namespace tinyxml2;
-
-extern Player *player;
-extern std::string currentXML;
-
-using Drop = std::tuple<std::string, unsigned int, float>;
-
-class Mob : public Entity {
-protected:
-       XMLElement *xmle;
-       std::forward_list<Drop> drop;
-
-    unsigned int actCounter;
-    unsigned int actCounterInitial;
-    bool ridable;
-public:
-    Entity *rider;
-       bool aggressive;
-       std::string heyid;
-
-    Mob(void);
-    ~Mob(void);
-
-       void wander(void);
-    void ride(Entity *e);
-    virtual void act(void) =0;
-
-       virtual void onHit(unsigned int) =0;
-       virtual void onDeath(void);
-
-    virtual bool bindTex(void) =0;
-};
-
-constexpr Mob *Mobp(Entity *e) {
-    return (Mob *)e;
-}
-
-class Page : public Mob {
-private:
-       std::string cId, cValue;
-    std::string pageTexPath;
-    GLuint pageTexture;
-public:
-    Page(void);
-
-    void act(void);
-       void onHit(unsigned int);
-    bool bindTex(void);
-    void createFromXML(XMLElement *e, World *w) final;
-       void saveToXML(void) final;
-};
-
-class Door : public Mob {
-public:
-    Door(void);
-
-    void act(void);
-       void onHit(unsigned int);
-    bool bindTex(void);
-    void createFromXML(XMLElement *e, World *w) final;
-       void saveToXML(void) final;
-};
-
-class Cat : public Mob {
-public:
-    Cat(void);
-
-    void act(void);
-       void onHit(unsigned int);
-    bool bindTex(void);
-       void createFromXML(XMLElement *e, World *w) final;
-       void saveToXML(void) final;
-};
-
-class Rabbit : public Mob {
-public:
-    Rabbit(void);
-
-    void act(void);
-       void onHit(unsigned int);
-    bool bindTex(void);
-    void createFromXML(XMLElement *e, World *w) final;
-       void saveToXML(void) final;
-};
-
-class Bird : public Mob {
-private:
-    float initialY;
-public:
-    Bird(void);
-
-    void act(void);
-       void onHit(unsigned int);
-    bool bindTex(void);
-    void createFromXML(XMLElement *e, World *w) final;
-       void saveToXML(void) final;
-};
-
-class Trigger : public Mob {
-private:
-    std::string id;
-    bool triggered;
-public:
-       bool notext;
-
-    Trigger(void);
-
-    void act(void);
-       void onHit(unsigned int);
-    bool bindTex(void);
-    void createFromXML(XMLElement *e, World *w) final;
-       void saveToXML(void) final;
-};
-
-class Chest : public Mob {
-public:
-       Chest(void);
-
-       void act(void);
-       void onHit(unsigned int);
-       bool bindTex(void);
-       void createFromXML(XMLElement *e, World *w) final;
-       void saveToXML(void) final;
-};
-
-#endif // MOB_H_
diff --git a/include/mob.hpp.bak b/include/mob.hpp.bak
new file mode 100644 (file)
index 0000000..24b8ed9
--- /dev/null
@@ -0,0 +1,140 @@
+#ifndef MOB_H_
+#define MOB_H_
+
+#include <forward_list>
+#include <tuple>
+
+#include <common.hpp>
+#include <entities.hpp>
+#include <gametime.hpp>
+#include <ui.hpp>
+#include <save_util.hpp>
+
+// local library headers
+#include <tinyxml2.h>
+using namespace tinyxml2;
+
+extern Player *player;
+extern std::string currentXML;
+
+using Drop = std::tuple<std::string, unsigned int, float>;
+
+class Mob : public Entity {
+protected:
+       XMLElement *xmle;
+       std::forward_list<Drop> drop;
+
+    unsigned int actCounter;
+    unsigned int actCounterInitial;
+    bool ridable;
+public:
+    Entity *rider;
+       bool aggressive;
+       std::string heyid;
+
+    Mob(void);
+    ~Mob(void);
+
+       void wander(void);
+    void ride(Entity *e);
+    virtual void act(void) =0;
+
+       virtual void onHit(unsigned int) =0;
+       virtual void onDeath(void);
+
+    virtual bool bindTex(void) =0;
+};
+
+constexpr Mob *Mobp(Entity *e) {
+    return (Mob *)e;
+}
+
+class Page : public Mob {
+private:
+       std::string cId, cValue;
+    std::string pageTexPath;
+    GLuint pageTexture;
+public:
+    Page(void);
+
+    void act(void);
+       void onHit(unsigned int);
+    bool bindTex(void);
+    void createFromXML(XMLElement *e, World *w) final;
+       void saveToXML(void) final;
+};
+
+class Door : public Mob {
+public:
+    Door(void);
+
+    void act(void);
+       void onHit(unsigned int);
+    bool bindTex(void);
+    void createFromXML(XMLElement *e, World *w) final;
+       void saveToXML(void) final;
+};
+
+class Cat : public Mob {
+public:
+    Cat(void);
+
+    void act(void);
+       void onHit(unsigned int);
+    bool bindTex(void);
+       void createFromXML(XMLElement *e, World *w) final;
+       void saveToXML(void) final;
+};
+
+class Rabbit : public Mob {
+public:
+    Rabbit(void);
+
+    void act(void);
+       void onHit(unsigned int);
+    bool bindTex(void);
+    void createFromXML(XMLElement *e, World *w) final;
+       void saveToXML(void) final;
+};
+
+class Bird : public Mob {
+private:
+    float initialY;
+public:
+    Bird(void);
+
+    void act(void);
+       void onHit(unsigned int);
+    bool bindTex(void);
+    void createFromXML(XMLElement *e, World *w) final;
+       void saveToXML(void) final;
+};
+
+class Trigger : public Mob {
+private:
+    std::string id;
+    bool triggered;
+public:
+       bool notext;
+
+    Trigger(void);
+
+    void act(void);
+       void onHit(unsigned int);
+    bool bindTex(void);
+    void createFromXML(XMLElement *e, World *w) final;
+       void saveToXML(void) final;
+};
+
+class Chest : public Mob {
+public:
+       Chest(void);
+
+       void act(void);
+       void onHit(unsigned int);
+       bool bindTex(void);
+       void createFromXML(XMLElement *e, World *w) final;
+       void saveToXML(void) final;
+};
+
+#endif // MOB_H_
diff --git a/include/quest.hpp b/include/quest.hpp
deleted file mode 100644 (file)
index 2db65a2..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/** @file Quest.h\r
- * @brief The quest handling system.\r
- *\r
- * This file contains Quest and QuestHandler, used to manage quests inside the\r
- * game.\r
- */\r
-\r
-#ifndef QUEST_H\r
-#define QUEST_H\r
-\r
-#include <string>\r
-\r
-#include <inventory.hpp>\r
-\r
-/**\r
- * When defined, DEBUG allows extra messages to be printed to the terminal for\r
- * debugging purposes.\r
- */\r
-\r
-#define DEBUG\r
-\r
-typedef struct {\r
-       std::string title;\r
-       std::string desc;\r
-       std::pair<std::string, uint> reward;\r
-       std::vector<std::pair<std::string, int>> need;\r
-} Quest;\r
-\r
-/**\r
- * The Quest Handler class.\r
- *\r
- * This class handles quests, including the assigning, dropping, and completing\r
- * of the quests.\r
- */\r
-\r
-class QuestHandler {\r
-public:\r
-       std::vector<Quest>current;\r
-\r
-       /**\r
-        * Adds a quest to the current quest vector by its title.\r
-        */\r
-\r
-       int assign(std::string title,std::string desc,std::string req);\r
-\r
-       /**\r
-        * Drops a quest through its title.\r
-        */\r
-\r
-       int drop(std::string title);\r
-\r
-       /**\r
-        * Finishes a quest through it's title, also giving a pointer to the Entity\r
-        * that gave the quest originally.\r
-        */\r
-\r
-       int finish(std::string t);\r
-\r
-       /**\r
-        * Returns true if this handler is currently taking the quest.\r
-        */\r
-\r
-       bool hasQuest(std::string t);\r
-};\r
-\r
-#endif // QUEST_H\r
diff --git a/include/quest.hpp.bak b/include/quest.hpp.bak
new file mode 100644 (file)
index 0000000..2db65a2
--- /dev/null
@@ -0,0 +1,66 @@
+/** @file Quest.h\r
+ * @brief The quest handling system.\r
+ *\r
+ * This file contains Quest and QuestHandler, used to manage quests inside the\r
+ * game.\r
+ */\r
+\r
+#ifndef QUEST_H\r
+#define QUEST_H\r
+\r
+#include <string>\r
+\r
+#include <inventory.hpp>\r
+\r
+/**\r
+ * When defined, DEBUG allows extra messages to be printed to the terminal for\r
+ * debugging purposes.\r
+ */\r
+\r
+#define DEBUG\r
+\r
+typedef struct {\r
+       std::string title;\r
+       std::string desc;\r
+       std::pair<std::string, uint> reward;\r
+       std::vector<std::pair<std::string, int>> need;\r
+} Quest;\r
+\r
+/**\r
+ * The Quest Handler class.\r
+ *\r
+ * This class handles quests, including the assigning, dropping, and completing\r
+ * of the quests.\r
+ */\r
+\r
+class QuestHandler {\r
+public:\r
+       std::vector<Quest>current;\r
+\r
+       /**\r
+        * Adds a quest to the current quest vector by its title.\r
+        */\r
+\r
+       int assign(std::string title,std::string desc,std::string req);\r
+\r
+       /**\r
+        * Drops a quest through its title.\r
+        */\r
+\r
+       int drop(std::string title);\r
+\r
+       /**\r
+        * Finishes a quest through it's title, also giving a pointer to the Entity\r
+        * that gave the quest originally.\r
+        */\r
+\r
+       int finish(std::string t);\r
+\r
+       /**\r
+        * Returns true if this handler is currently taking the quest.\r
+        */\r
+\r
+       bool hasQuest(std::string t);\r
+};\r
+\r
+#endif // QUEST_H\r
index 86713937debf07dd6815ee10464a24feb9cd08a9..c7a69b63fd57490d0d1a8c483741c0fac476f9a2 100644 (file)
 // local game headers
 #include <common.hpp>
 #include <config.hpp>
-#include <entities.hpp>
-#include <inventory.hpp>
+//#include <inventory.hpp>
 #include <ui_menu.hpp>
-#include <ui_action.hpp>
+//#include <ui_action.hpp>
 
 // local library headers
 #include <SDL2/SDL_opengl.h>
@@ -71,7 +70,6 @@ namespace ui {
        extern bool posFlag;
 
        extern unsigned char dialogOptChosen;
-       extern unsigned char merchOptChosen;
        extern bool              dialogBoxExists;
        extern bool              dialogImportant;
        extern bool              dialogPassive;
@@ -123,8 +121,6 @@ namespace ui {
        void drawBox(vec2 c1, vec2 c2);
        void drawNiceBox(vec2 c1, vec2 c2, float z);
        void dialogBox(std::string name, std::string opt, bool passive, std::string text, ...);
-       void merchantBox(const char *name,Trade trade,const char *opt,bool passive,const char *text,...);
-       void merchantBox();
        void closeBox();
        void waitForDialog(void);
 
diff --git a/include/ui_action.hpp b/include/ui_action.hpp
deleted file mode 100644 (file)
index a275ab3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef ACTION_H_
-#define ACTION_H_
-
-#include <common.hpp>
-#include <ui.hpp>
-
-namespace ui {
-    namespace action {
-        extern bool make;
-
-        // enables the action ui
-        void enable(void);
-        // disables the action ui
-        void disable(void);
-
-        // draws the action ui
-        void draw(vec2 loc);
-    }
-}
-
-#endif // ACTION_H_
diff --git a/include/ui_action.hpp.bak b/include/ui_action.hpp.bak
new file mode 100644 (file)
index 0000000..a275ab3
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef ACTION_H_
+#define ACTION_H_
+
+#include <common.hpp>
+#include <ui.hpp>
+
+namespace ui {
+    namespace action {
+        extern bool make;
+
+        // enables the action ui
+        void enable(void);
+        // disables the action ui
+        void disable(void);
+
+        // draws the action ui
+        void draw(vec2 loc);
+    }
+}
+
+#endif // ACTION_H_
index 24a5e1b51d05e173d24f0fc60f567ef337f014ab..8582b67e2fd5fcec6bbcb92fc5d99e5253cccbca 100644 (file)
@@ -27,14 +27,14 @@ namespace ui {
 
                        ui::putStringCentered(offset.x, top_y - 40, "Current Quests:");
                        
-                       auto y = top_y - 100;
+                       /*auto y = top_y - 100;
                        const auto x = offset.x - 180;
                        for (const auto &q : player->qh.current) {
                                ui::putText(x, y, q.title.c_str());
                                y -= 20;
                                ui::putText(x + 40, y, q.desc.c_str());
                                y -= 40; 
-                       }
+                       }*/
 
                        std::swap(textWrap, ui::textWrapLimit);
                }
index dc07267e39a8c85e262c279d745b46d359bbf04c..36ccdfa05130f349384b3e327d5a972d9e70b6e1 100644 (file)
@@ -8,9 +8,13 @@
 
 // local game includes
 #include <common.hpp>
-#include <entities.hpp>
 #include <coolarray.hpp>
 
+#include <events.hpp>
+#include <texture.hpp>
+#include <tinyxml2.h>
+using namespace tinyxml2;
+
 /**
  * The background type enum.
  * This enum contains all different possibilities for world backgrounds; used
@@ -43,13 +47,6 @@ typedef struct {
     unsigned char groundColor;    /**< a value that affects the ground's color */
 } WorldData;
 
-/**
- * Contains info necessary for switching worlds.
- * This pair contains a pointer to the new world, and the new set of
- * coordinates the player should be at in that world.
- */
-using WorldSwitchInfo = std::pair<World *, vec2>;
-
 /**
  * Alters how bright world elements are drawn.
  * This value is based off of the current time of day (tick count), set in
@@ -95,41 +92,6 @@ constexpr const unsigned int INDOOR_FLOOR_HEIGHTT = 400;
  */
 constexpr const unsigned int INDOOR_FLOOR_HEIGHT = (INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS);
 
-/**
- * The village class.
- * This class defines an area in a world that is considered to be a village,
- * and provides a welcome message when the player enters the area.
- */
-class Village {
-public:
-       /**
-        * The name of the village.
-        */
-       std::string name;
-
-       /**
-        * The start and end coordinates of the village.
-        */
-       vec2 start, end;
-
-       /**
-        * A "player in village" flag.
-        * This flag is used to trigger displaying the welcome message.
-        */
-       bool in;
-
-       /**
-        * Constructs a village with the given name, inside the given world.
-        */
-       Village(std::string meme, World *w);
-
-       /**
-        * Destructs the village.
-        */
-       ~Village(void){}
-};
-
-
 #include <entityx/entityx.h>
 
 constexpr const char* WorldWeatherString[3] = {
@@ -138,20 +100,45 @@ constexpr const char* WorldWeatherString[3] = {
        "Snowy"
 };
 
+struct WorldData2 {
+       // data
+       std::vector<WorldData> data;
+       float startX;
+
+       // indoor
+       bool indoor;
+       float indoorWidth;
+       GLuint indoorTex;
+
+       // links
+       std::string toLeft, toRight;
+
+       // style
+       WorldBGType style;
+       std::string styleFolder;
+       std::vector<std::string> sTexLoc;
+
+       // music
+       std::string bgm;
+
+       // village
+       float villageStart, villageEnd;
+};
+
 class WorldSystem : public entityx::System<WorldSystem>, public entityx::Receiver<WorldSystem> {
 private:
-       World *world;
-       World *outside;
+       WorldData2 world;
 
        WorldWeather weather;
 
        Mix_Music *bgmObj;
-       std::string bgmObjFile;
 
        std::vector<std::string> bgFiles;
 
        TextureIterator bgTex;
 
+       XMLDocument xmlDoc;
+
 public:
        explicit WorldSystem(void);
        ~WorldSystem(void);
@@ -160,13 +147,14 @@ public:
                ev.subscribe<BGMToggleEvent>(*this);
        }
 
+       inline float getWidth(void) const
+       { return world.startX * -2.0f; }
+
        void receive(const BGMToggleEvent &bte);
 
        void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
        void render(void);
 
-       void setWorld(World *w);
-
        inline const std::string getWeatherStr(void) const
        { return WorldWeatherString[static_cast<int>(weather)]; }
 
@@ -175,299 +163,20 @@ public:
 
        void setWeather(const std::string &s);
 
-       void singleDetect(Entity *e, entityx::TimeDelta dt);
        void detect(entityx::TimeDelta dt);
 
-       void detect2(entityx::TimeDelta dt);
-
-       void enterWorld(World *w);
-       void leaveWorld(void);
-};
-
-
-/**
- * The world class.
- * This class handles entity creation, management, and deletion. Most
- * world-related operations have to be done through this class, such as
- * drawing.
- */
-class World {
-private:
-       bool m_Indoor;
-
-public:
-
-       float HouseWidth;
-       GLuint houseTex;
-
-       inline bool isIndoor(void) const
-       { return m_Indoor; }
-
-       WorldBGType bgType;
-
-       std::string styleFolder;
+       void goWorldLeft(void) {}
+       void goWorldRight(void) {}
        
-       /**
-        * An array of all the world's ground data, populated through
-        * World::generate().
-        * @see generate()
-        */
-       std::vector<WorldData> worldData;
-
-       /**
-        * Contains the size of the 'worldData' array.
-        */
-       unsigned int lineCount;
-
-       /**
-        * The starting x-coordinate of the world.
-        */
-       float worldStart;
-
-       /**
-        * The path to the XML file of the world to the left.
-        *
-        * @see setToLeft()
-        */
-       std::string toLeft;
-
-       /**
-        * The path to the XML file of the world to the right.
-        *
-        * @see setToRight()
-        */
-       std::string toRight;
-
-       /**
-        * A vector of paths for the structure textures.
-        * The appearance of structures depends on the world's theme.
-        *
-        * @see setStyle()
-        */
-       std::vector<std::string> sTexLoc;
-
-       /**
-        * Contains randomly generated coordinates for stars.
-        */
-       std::vector<vec2> star;
-
-       /**
-        * A vector of all light elements in the world.
-        *
-        * @see addLight()
-        * @see getLastLight()
-        */
-       std::vector<Light>        light;
-
-       /**
-        * A vector of all villages in the world.
-        *
-        * @see addVillage()
-        */
-       std::vector<Village>      village;
-
-       std::vector<Entity *> entityPending;
-
-       /**
-        * Destroys entities and clears vectors that contain them.
-        * This function is only called in the world destructor.
-        */
-       void deleteEntities(void);
-
-       /**
-        * The filename of the world's BGM file.
-        *
-        * @see setBGM()
-        */
-       std::string bgm;
-
-       CoolArray<Particles>    particles;
-
-       /**
-        * A vector of pointers to all entities from the other vectors.
-        * This is used to mass-manage entities, or operate on entities
-        * outside of what the world does.
-        *
-        * @see getNearInteractable()
-        */
-       std::vector<Entity *> entity;
-
-       /**
-        * Constructs the world, resets variables.
-        */
-       World(bool indoor = false);
-
-       /**
-        * Destructs the world, frees memory.
-        */
-       virtual ~World(void);
-
-       /**
-        * Generates a world of the specified width.
-        * This will populate the 'worldData' array and create star coordinates.
-        * It's necessary to call this function to actually use the world.
-        */
-       void generate(int width);
-
-       /**
-        * Draws everything the world handles to the screen (and the player).
-        * Drawing is based off of the player so that off-screen elements are not
-        * drawn.
-        */
-       virtual void draw(Player *p);
-
-       /**
-        * Gets the width of the world, presumably in pixels.
-        * TODO
-        */
-       int getTheWidth(void) const;
-
-       /**
-        * Gets the starting x-coordinate of the world.
-        *
-        * @see worldStart
-        */
-       float getWorldStart(void) const;
-
-       inline unsigned int getEntityCount(void) const {
-               return entity.size();
-       }
+       // worlddata2 stuff
+       WorldData2 worldData;
 
-       /**
-        * Gets a pointer to the most recently created light.
-        * This is used to update properties of the light outside of the
-        * world class.
-        */
-       Light& getLastLight(void);
+       void generate(unsigned int width = 0);
+       void addHole(const unsigned int& start, const unsigned int& end);
+       void addHill(const ivec2& peak, const unsigned int& width);
 
-       /**
-        * Gets a pointer ot the most recently created mob.
-        * This is used to update properties of the mob outside of the
-        * world class.
-        */
-       Mob* getLastMob(void);
-
-       /**
-        * Finds the entity nearest to the provided one.
-        */
-       Entity* getNearInteractable(Entity &e);
-
-       /**
-        * Finds the mob nearest to the given entity.
-        */
-       Mob* getNearMob(Entity &e);
-
-       /**
-        * Gets the coordinates of the `index`th structure.
-        */
-       vec2 getStructurePos(int index);
-
-       /**
-        * Gets the texture path of the `index`th structure
-        */
-       std::string getSTextureLocation(unsigned int index) const;
-
-       // saves the world's data to an XML file, either the one provided or the current path
-       void save(const std::string& s="");
-
-       // sets the world's background theme
-       void setBackground(WorldBGType bgt);
-
-       // sets the folder to collect entity textures from
-       void setStyle(std::string pre);
-
-       // gets the string that represents the current weather
-       std::string getWeatherStr(void) const;
-       const WorldWeather& getWeatherId(void) const;
-
-       // sets the weatherrrr
-       void setWeather(const std::string& w);
-
-       // sets / gets pathnames of XML files for worlds to the left and right
-       std::string setToLeft(std::string file);
-       std::string setToRight(std::string file);
-       std::string getToLeft(void) const;
-       std::string getToRight(void) const;
-
-       // attempts to enter the left/right adjacent world, returning either that world or this
-       WorldSwitchInfo goWorldLeft(Player *p);
-       WorldSwitchInfo goWorldRight(Player *p);
-
-       /**
-        * Attempts to move an NPC to the left adjacent world, returning true on success.
-        */
-       bool goWorldLeft(NPC *e);
-
-       /**
-        * Attempts to move an NPC to the world to the right, returning true on success.
-        */
-       bool goWorldRight(NPC *e);
-
-       // attempts to enter a structure that the player would be standing in front of
-       WorldSwitchInfo goInsideStructure(Player *p);
-
-       /**
-        * Adopts an NPC from another world, taking its ownership.
-        */
-       void adoptNPC(NPC *e);
-
-       /**
-        * Adopts a mob from another world, taking its ownership.
-        */
-       void adoptMob(Mob *e);
-
-       // adds a hole at the specified start and end x-coordinates
-       void addHole(unsigned int start,unsigned int end);
-
-       // adds a hill that peaks at the given coordinate and is `width` HLINEs wide
-       void addHill(ivec2 peak, unsigned int width);
-
-       // functions to add entities to the world
-       void addLight(vec2 xy, float radius, Color color);
-
-       void addMerchant(float x, float y, bool housed);
-
-       void addMob(Mob *m, vec2 coord);
-
-       void addNPC(NPC *n);
-
-       void addObject(std::string in, std::string pickupDialog, float x, float y);
-
-       void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int dur);
-       void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int dur, unsigned char flags);
-
-       void addStructure(Structures *s);
-
-       Village *addVillage(std::string name, World *world);
-};
-
-/**
- * The arena class - creates an arena.
- *
- * This world, when created, expects a pointer to a Mob. This mob will be
- * transported to a temporary world with the player, and the Mob will be
- * killed upon exiting the arena.
- */
-
-class Arena : public World {
-private:
-
-       // the mob that the player is fighting
-       Mob *mmob;
-
-public:
-
-       // creates the arena with the world being left for it
-       Arena(void);
-
-       // frees memory
-       ~Arena(void);
-
-       // starts a new fight??
-       void fight(World *leave, const Player *p, Mob *m);
-
-       // attempts to exit the arena, returning what world the player should be in
-       WorldSwitchInfo exitArena(Player *p);
+       bool save(const std::string& file);
+       void load(const std::string& file);
 };
 
 /**
@@ -495,13 +204,4 @@ World *loadWorldFromXMLNoTakeover(std::string path);
  */
 World *loadWorldFromPtr(World *ptr);
 
-/**
- * Casts a normal world to an indoor world, to access IndoorWorld-exclusive
- * elements.
- */
-constexpr IndoorWorld *Indoorp(World *w)
-{
-    return (IndoorWorld *)w;
-}
-
 #endif // WORLD_H
index 91a2759e835e1726aa11328bd1ff691b39652a4a..9fa7a55ffb4f975ee72ceb784b2cbda4bcbc646c 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -21,7 +21,7 @@ using namespace tinyxml2;
 // local game includes
 #include <common.hpp>
 #include <config.hpp>
-#include <entities.hpp>
+//#include <entities.hpp>
 #include <world.hpp>
 #include <ui.hpp>
 #include <gametime.hpp>
@@ -33,23 +33,12 @@ using namespace tinyxml2;
 ** Variables section
 ** --------------------------------------------------------------------------*/
 
-// world objects for the current world and the two that are adjacent
-World *currentWorld        = NULL,
-         *currentWorldToLeft  = NULL,
-         *currentWorldToRight = NULL;
-
-// an arena for fightin'
-Arena *arena = nullptr;
-
 // the currently used folder to grab XML files
 std::string xmlFolder;
 
 // the current menu
 Menu *currentMenu;
 
-// the player object
-Player *player;
-
 // keeps a simple palette of colors for single-color draws
 GLuint colorIndex;
 
@@ -137,13 +126,13 @@ int main(int argc, char *argv[])
        game::briceUpdate();
 
        // load sprites used in the inventory menu. See src/inventory.cpp
-       initInventorySprites();
+       //initInventorySprites();
 
        // load mouse texture, and other inventory textures
        mouseTex = Texture::loadTexture("assets/mouse.png");
 
-       player = new Player();
-       player->sspawn(0,100);
+       //player = new Player();
+       //player->sspawn(0,100);
 
        // get a world
        if (xmlFolder.empty())
@@ -197,35 +186,21 @@ int main(int argc, char *argv[])
                goto EXIT_ROUTINE;
 
        if (!worldActuallyUseThisXMLFile.empty()) {
-               delete currentWorld;
-               currentWorld = loadWorldFromXML(worldActuallyUseThisXMLFile);
-       } else if (currentWorld == nullptr) {
-
+               game::engine.getSystem<WorldSystem>()->load(worldActuallyUseThisXMLFile);
+       } else {
                // load the first valid XML file for the world
                for (const auto &xf : xmlFiles) {
                        if (xf[0] != '.') {
                                // read it in
                                std::cout << "File to load: " << xf << '\n';
-                               currentWorld = loadWorldFromXML(xf);
+                               game::engine.getSystem<WorldSystem>()->load(xf);
                                break;
                        }
                }
        }
 
-       // make sure the world was made
-       if (currentWorld == nullptr)
-               UserError("Plot twist: The world never existed...?");
-
        ui::menu::init();
-       game::events.emit<BGMToggleEvent>(currentWorld->bgm);
-
-       game::engine.getSystem<WorldSystem>()->setWorld(currentWorld);
-
-       // spawn the arena
-       arena = new Arena();
-       arena->setStyle("");
-       arena->setBackground(WorldBGType::Forest);
-       arena->bgm = "assets/music/embark.wav";
+//     game::events.emit<BGMToggleEvent>(currentWorld->bgm);
 
        // the main loop, in all of its gloriousness..
        std::thread([&]{
@@ -239,7 +214,7 @@ int main(int argc, char *argv[])
        std::thread([&]{
                while (game::engine.shouldRun()) {
                        fps = 1000 / game::time::getDeltaTime();
-                       debugY = player->loc.y;
+//                     debugY = player->loc.y;
 
                        std::this_thread::sleep_for(std::chrono::seconds(1));
                }
@@ -259,36 +234,24 @@ EXIT_ROUTINE:
     Mix_HaltMusic();
     Mix_CloseAudio();
 
-    destroyInventory();
+//    destroyInventory();
        ui::destroyFonts();
     Texture::freeTextures();
 
        // close up the game stuff
-       currentWorld->save();
-       delete arena;
-       //delete currentWorld;
+//     currentWorld->save();
 
        game::engine.getSystem<WindowSystem>()->die();
 
     return 0; // Calls everything passed to atexit
 }
 
-extern std::vector<NPC *> aipreload;
-
 void mainLoop(void){
        game::time::mainLoopHandler();
 
        if (currentMenu) {
                return;
        } else {
-               // Flush preloaded AI functions if necessary
-               if (!ui::dialogBoxExists) {
-                       while (!aipreload.empty()) {
-                               aipreload.front()->addAIFunc(false);
-                               aipreload.erase(std::begin(aipreload));
-                       }
-               }
-
                if (game::time::tickHasPassed())
                        logic();
 
@@ -300,18 +263,20 @@ void render() {
        const auto SCREEN_WIDTH = game::SCREEN_WIDTH;
        const auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
 
-       offset.x = player->loc.x + player->width / 2;
+//     offset.x = player->loc.x + player->width / 2;
+
+       auto worldWidth = game::engine.getSystem<WorldSystem>()->getWidth();
 
        // ortho x snapping
-       if (currentWorld->getTheWidth() < (int)SCREEN_WIDTH)
+       if (worldWidth < (int)SCREEN_WIDTH)
                offset.x = 0;
-       else if (offset.x - SCREEN_WIDTH / 2 < currentWorld->getTheWidth() * -0.5f)
-               offset.x = ((currentWorld->getTheWidth() * -0.5f) + SCREEN_WIDTH / 2);
-       else if (offset.x + SCREEN_WIDTH / 2 > currentWorld->getTheWidth() *  0.5f)
-               offset.x = ((currentWorld->getTheWidth() *  0.5f) - SCREEN_WIDTH / 2);
+       else if (offset.x - SCREEN_WIDTH / 2 < worldWidth * -0.5f)
+               offset.x = ((worldWidth * -0.5f) + SCREEN_WIDTH / 2);
+       else if (offset.x + SCREEN_WIDTH / 2 > worldWidth *  0.5f)
+               offset.x = ((worldWidth *  0.5f) - SCREEN_WIDTH / 2);
 
        // ortho y snapping
-       offset.y = std::max(player->loc.y + player->height / 2, SCREEN_HEIGHT / 2.0f);
+       offset.y = /*std::max(player->loc.y + player->height / 2,*/ SCREEN_HEIGHT / 2.0f; /*);*/
 
        // "setup"
        glm::mat4 projection = glm::ortho(floor(offset.x - SCREEN_WIDTH / 2),          // left
@@ -343,10 +308,9 @@ void render() {
 
        // draw the world and player
        game::engine.getSystem<WorldSystem>()->render();
-       currentWorld->draw(player);
        
        // draw the player's inventory
-       player->inv->draw();
+       //player->inv->draw();
 
        // draw the fade overlay
        ui::drawFade();
@@ -359,21 +323,21 @@ void render() {
                ui::putText(offset.x-SCREEN_WIDTH/2, (offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
                                        "fps: %d\ngrounded:%d\nresolution: %ux%u\nentity cnt: %d\nloc: (%+.2f, %+.2f)\nticks: %u\nvolume: %f\nweather: %s\nxml: %s",
                                        fps,
-                                       player->ground,
+                                       0,//player->ground,
                                        SCREEN_WIDTH,                           // Window dimensions
                                        SCREEN_HEIGHT,                          //
-                                       currentWorld->entity.size(),// Size of entity array
-                                       player->loc.x,                          // The player's x coordinate
+                                       0,//currentWorld->entity.size(),// Size of entity array
+                                       0,//player->loc.x,                              // The player's x coordinate
                                        debugY,                                         // The player's y coordinate
                                        game::time::getTickCount(),
                                        game::config::VOLUME_MASTER,
                                        game::engine.getSystem<WorldSystem>()->getWeatherStr().c_str(),
-                                       currentXML.c_str()
+                                       ""//currentXML.c_str()
                                        );
 
                // draw tracer lines if desired
-               static const GLuint tracerText = Texture::genColor(Color(100,100,255));
-               if (ui::posFlag) {
+               //static const GLuint tracerText = Texture::genColor(Color(100,100,255));
+               /*if (ui::posFlag) {
                        GLfloat *tpoint = new GLfloat[currentWorld->getEntityCount() * 2 * 5];
                        auto tp = tpoint;
 
@@ -403,7 +367,7 @@ void render() {
                        Render::textShader.unuse();
 
                        delete[] tpoint;
-               }
+               }*/
 
        }
 
@@ -421,14 +385,14 @@ void render() {
 }
 
 void logic(){
-       static bool NPCSelected    = false;
-       static bool ObjectSelected = false;
+//     static bool NPCSelected    = false;
+//     static bool ObjectSelected = false;
 
        // exit the game if the player falls out of the world
-       if (player->loc.y < 0)
-               game::endGame();
+       /*if (player->loc.y < 0)
+               game::endGame();*/
 
-       if (player->inv->usingi) {
+       /*if (player->inv->usingi) {
                for (auto &e : currentWorld->entity) {
                        if (player->inv->usingi && !e->isHit() &&
                                player->inv->detectCollision(vec2 { e->loc.x, e->loc.y }, vec2 { e->loc.x + e->width, e->loc.y + e->height})) {
@@ -437,9 +401,9 @@ void logic(){
                        }
                }
                player->inv->usingi = false;
-       }
+       }*/
 
-       for (auto &e : currentWorld->entity) {
+       /*for (auto &e : currentWorld->entity) {
                if (e->isAlive() && ((e->type == NPCT) || (e->type == MERCHT) || (e->type == OBJECTT))) {
                        if (e->type == OBJECTT && ObjectSelected) {
                                e->near = false;
@@ -475,7 +439,7 @@ void logic(){
                        e->near = player->isNear(e);
                        e->wander();
                }
-       }
+       }*/
 
        // calculate the world shading value
        worldShade = 50 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
@@ -484,10 +448,11 @@ void logic(){
        ui::fadeUpdate();
 
        // create weather particles if necessary
-       auto weather = game::engine.getSystem<WorldSystem>()->getWeatherId();
+       /*auto weather = game::engine.getSystem<WorldSystem>()->getWeatherId();
+       auto worldWidth = game::engine.getSystem<WorldSystem>()->getWidth();
        if (weather == WorldWeather::Rain) {
                for (unsigned int r = (randGet() % 25) + 11; r--;) {
-                       currentWorld->addParticle(randGet() % currentWorld->getTheWidth() - (currentWorld->getTheWidth() / 2),
+                       currentWorld->addParticle(randGet() % worldWidth - (worldWidth / 2),
                                                                          offset.y + game::SCREEN_HEIGHT / 2,
                                                                          HLINES(1.25),                                                                         // width
                                                                          HLINES(1.25),                                                                         // height
@@ -500,7 +465,7 @@ void logic(){
                }
        } else if (weather == WorldWeather::Snowy) {
                for (unsigned int r = (randGet() % 25) + 11; r--;) {
-                       currentWorld->addParticle(randGet() % currentWorld->getTheWidth() - (currentWorld->getTheWidth() / 2),
+                       currentWorld->addParticle(randGet() % worldWidth - (worldWidth / 2),
                                                                          offset.y + game::SCREEN_HEIGHT / 2,
                                                                          HLINES(1.25),                                                                         // width
                                                                          HLINES(1.25),                                                                         // height
@@ -511,10 +476,10 @@ void logic(){
                                                                          0                                                                                                     // no gravity, no bounce
                                                                          );
                }
-       }
+       }*/
 
        // increment game ticker
        game::time::tick();
-       NPCSelected = false;
-       ObjectSelected = false;
+       //NPCSelected = false;
+       //ObjectSelected = false;
 }
index 56dee480715cdb43afa0083e7fbff58126aae52a..3d498d3c193aa40b3fd737deeaee865522302418 100644 (file)
@@ -3,8 +3,7 @@
 #include <config.hpp>
 #include <world.hpp>
 #include <ui.hpp>
-#include <inventory.hpp>
-#include <entities.hpp>
+//#include <inventory.hpp>
 #include <window.hpp>
 
 extern World *currentWorld;
@@ -20,9 +19,9 @@ void Engine::init(void) {
 
     systems.add<WindowSystem>();
     systems.add<InputSystem>();
-    systems.add<InventorySystem>();
+//    systems.add<InventorySystem>();
     systems.add<WorldSystem>();
-    systems.add<PlayerSystem>(&player);
+//    systems.add<PlayerSystem>(&player);
 
     systems.configure();
 
@@ -37,8 +36,8 @@ void Engine::render(entityx::TimeDelta dt)
 void Engine::update(entityx::TimeDelta dt)
 {
     systems.update<InputSystem>(dt);
-    systems.update<InventorySystem>(dt);
-    systems.update<PlayerSystem>(dt);
+//    systems.update<InventorySystem>(dt);
+//    systems.update<PlayerSystem>(dt);
        systems.update<WorldSystem>(dt);
 }
 
diff --git a/src/entities.cpp b/src/entities.cpp
deleted file mode 100644 (file)
index e005df5..0000000
+++ /dev/null
@@ -1,1352 +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();
-       }
-}
diff --git a/src/entities.cpp.bak b/src/entities.cpp.bak
new file mode 100644 (file)
index 0000000..e005df5
--- /dev/null
@@ -0,0 +1,1352 @@
+#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();
+       }
+}
diff --git a/src/inventory.cpp b/src/inventory.cpp
deleted file mode 100644 (file)
index f7a8df7..0000000
+++ /dev/null
@@ -1,748 +0,0 @@
-#include <inventory.hpp>
-
-#include <numeric>
-
-#include <entities.hpp>
-#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/inventory.cpp.bak b/src/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/items.cpp b/src/items.cpp
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/items.cpp.bak b/src/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/mob.cpp b/src/mob.cpp
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/mob.cpp.bak b/src/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/quest.cpp b/src/quest.cpp
deleted file mode 100644 (file)
index aa0bb2e..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <algorithm>\r
-\r
-#include <quest.hpp>\r
-#include <entities.hpp>\r
-\r
-extern Player *player;\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
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
index aed2f487933a7c6ffd927fc5c77dab93c31507d1..85b2d2b7015bfad79572c6febc464061d1f1467c 100644 (file)
@@ -13,21 +13,6 @@ extern Menu* currentMenu;
 
 extern SDL_Window *window;
 
-/**
- * External references for updating player coords / current world.
- */
-
-extern Player *player;
-extern World  *currentWorld;
-extern World  *currentWorldToLeft;
-extern World  *currentWorldToRight;
-
-/**
- * Pressing ESC or closing the window will set this to false.
- */
-extern bool gameRunning;
-
-
 std::array<SDL_Keycode, 6> controlMap = {
        SDLK_w, SDLK_a, SDLK_d, SDLK_LSHIFT, SDLK_LCTRL, SDLK_e
 };
@@ -79,7 +64,6 @@ static std::vector<std::pair<vec2, std::string>> textToDraw;
 
 static std::vector<std::pair<std::string,vec3>> dialogOptText;
 static std::string dialogBoxText;
-static std::vector<vec3> merchArrowLoc (2, vec3 { 0, 0, 0 });
 static bool typeOutDone = true;
 static bool typeOutSustain = false;
 
@@ -183,7 +167,6 @@ namespace ui {
        bool dialogPassive = false;
        bool dialogMerchant = false;
        int dialogPassiveTime = 0;
-       Trade merchTrade;
 
        int fontTransInv = 255;
 
@@ -194,7 +177,6 @@ namespace ui {
        bool dialogBoxExists = false;
        bool dialogImportant = false;
        unsigned char dialogOptChosen = 0;
-       unsigned char merchOptChosen = 0;
 
        unsigned int textWrapLimit = 0;
 
@@ -582,54 +564,6 @@ namespace ui {
                ret.clear();
        }
 
-       void merchantBox(const char *name,Trade trade,const char *opt,bool passive,const char *text,...) {
-               va_list dialogArgs;
-               std::unique_ptr<char[]> printfbuf (new char[512]);
-
-               dialogPassive = passive;
-               merchTrade = trade;
-
-               // clear the buffer
-               dialogBoxText.clear();
-               dialogBoxText = (std::string)name + ": ";
-
-               va_start(dialogArgs,text);
-               vsnprintf(printfbuf.get(),512,text,dialogArgs);
-               va_end(dialogArgs);
-               dialogBoxText += printfbuf.get();
-
-               // free old option text
-               dialogOptText.clear();
-
-               dialogOptChosen = 0;
-               merchOptChosen = 0;
-
-               // handle options if desired
-               if (opt) {
-                       std::string soptbuf = opt;
-                       char *sopt = strtok(&soptbuf[0], ":");
-
-                       // cycle through options
-                       while(sopt) {
-                               dialogOptText.push_back(std::make_pair((std::string)sopt, vec3 {0,0,0}));
-                               sopt = strtok(NULL,":");
-                       }
-               }
-
-               // allow box to be displayed
-               dialogBoxExists = true;
-               dialogImportant = false;
-               dialogMerchant = true;
-               textWrapLimit = 50;
-
-               ret.clear();
-       }
-
-       void merchantBox() {
-               textWrapLimit = 50;
-               dialogMerchant = true;
-       }
-
        /**
         * Wait for a dialog box to be dismissed.
         */
@@ -904,7 +838,7 @@ namespace ui {
                auto SCREEN_HEIGHT = static_cast<float>(game::SCREEN_HEIGHT);
 
                // will return if not toggled
-               action::draw(vec2 {player->loc.x + player->width / 2, player->loc.y + player->height + game::HLINE});
+               //action::draw(vec2 {player->loc.x + player->width / 2, player->loc.y + player->height + game::HLINE});
 
                // will return if not toggled
                quest::draw();
@@ -960,132 +894,6 @@ namespace ui {
                                        putStringCentered(offset.x,offset.y,rtext);
                                        setFontSize(16);
                                }
-                       }else if (dialogMerchant) {
-                               x = offset.x - SCREEN_WIDTH / 6;
-                               y = (offset.y + SCREEN_HEIGHT / 2) - HLINES(8);
-
-                               drawNiceBox(vec2(x, y), vec2(x + (SCREEN_WIDTH / 3.0f), y - (SCREEN_HEIGHT * 0.6f)), -7.0f);
-                               // draw typeOut'd text
-                               putString(x + game::HLINE, y - fontSize - game::HLINE, (rtext = typeOut(dialogBoxText)));
-
-                               std::string itemString1 = std::to_string(merchTrade.quantity[0]) + "x",
-                                           itemString2 = std::to_string(merchTrade.quantity[1]) + "x";
-
-                               vec2 merchBase = {offset.x, offset.y + SCREEN_HEIGHT / 5};
-
-                               putStringCentered(merchBase.x + SCREEN_WIDTH / 10 - 20, merchBase.y + 40 + fontSize * 2, itemString1);
-                               putStringCentered(merchBase.x + SCREEN_WIDTH / 10 - 20, merchBase.y + 40 + fontSize    , merchTrade.item[0]);
-                               putStringCentered(merchBase.x - SCREEN_WIDTH / 10     , merchBase.y + 40 + fontSize * 2, itemString2);
-                               putStringCentered(merchBase.x - SCREEN_WIDTH / 10     , merchBase.y + 40 + fontSize    , merchTrade.item[1]);
-                               putStringCentered(offset.x, merchBase.y + 60, "for");
-
-                // render the two items we are trading
-                GLfloat item_tex[] = {0.0, 1.0,
-                                      1.0, 1.0,
-                                      1.0, 0.0,
-
-                                      1.0, 0.0,
-                                      0.0, 0.0,
-                                      0.0, 1.0};
-
-                GLfloat left_item[] = {offset.x - (SCREEN_WIDTH / 10),      offset.y + (SCREEN_HEIGHT / 5),     -7.2,
-                                       offset.x - (SCREEN_WIDTH / 10) + 40, offset.y + (SCREEN_HEIGHT / 5),     -7.2,
-                                       offset.x - (SCREEN_WIDTH / 10) + 40, offset.y + (SCREEN_HEIGHT / 5) + 40,-7.2,
-
-                                       offset.x - (SCREEN_WIDTH / 10) + 40, offset.y + (SCREEN_HEIGHT / 5) + 40,-7.2,
-                                       offset.x - (SCREEN_WIDTH / 10),      offset.y + (SCREEN_HEIGHT / 5) + 40,-7.2,
-                                       offset.x - (SCREEN_WIDTH / 10),      offset.y + (SCREEN_HEIGHT / 5),     -7.2};
-
-                GLfloat right_item[] = {offset.x + (SCREEN_WIDTH / 10) - 40,    offset.y + (SCREEN_HEIGHT / 5),     -7.2,
-                                        offset.x + (SCREEN_WIDTH / 10),         offset.y + (SCREEN_HEIGHT / 5),     -7.2,
-                                        offset.x + (SCREEN_WIDTH / 10),         offset.y + (SCREEN_HEIGHT / 5) + 40,-7.2,
-
-                                        offset.x + (SCREEN_WIDTH / 10),         offset.y + (SCREEN_HEIGHT / 5) + 40,-7.2,
-                                        offset.x + (SCREEN_WIDTH / 10) - 40,    offset.y + (SCREEN_HEIGHT / 5) + 40,-7.2,
-                                        offset.x + (SCREEN_WIDTH / 10) - 40,    offset.y + (SCREEN_HEIGHT / 5),     -7.2};
-
-                glActiveTexture(GL_TEXTURE0);
-                glBindTexture(GL_TEXTURE_2D, getItemTexture(merchTrade.item[1]));
-                glUniform1i(Render::textShader.uniform[WU_texture], 0);
-
-                               Render::textShader.use();
-                               Render::textShader.enable();
-
-                glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, left_item);
-                glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, item_tex);
-                glDrawArrays(GL_TRIANGLES, 0 ,6);
-
-                glBindTexture(GL_TEXTURE_2D, getItemTexture(merchTrade.item[0]));
-
-                glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, right_item);
-                glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, item_tex);
-                glDrawArrays(GL_TRIANGLES, 0 ,6);
-
-                Render::textShader.disable();
-                               Render::textShader.unuse();
-
-                               merchArrowLoc[0].x = offset.x - (SCREEN_WIDTH / 8.5) - 16;
-                               merchArrowLoc[1].x = offset.x + (SCREEN_WIDTH / 8.5) + 16;
-                               merchArrowLoc[0].y = offset.y + (SCREEN_HEIGHT *.2);
-                               merchArrowLoc[1].y = offset.y + (SCREEN_HEIGHT *.2);
-                               merchArrowLoc[0].z = offset.x - (SCREEN_WIDTH / 8.5);
-                               merchArrowLoc[1].z = offset.x + (SCREEN_WIDTH / 8.5);
-
-                               for(i = 0; i < 2; i++) {
-                                       if (((merchArrowLoc[i].x < merchArrowLoc[i].z) ?
-                                               (mouse.x > merchArrowLoc[i].x     && mouse.x < merchArrowLoc[i].z) :
-                                               (mouse.x < merchArrowLoc[i].x     && mouse.x > merchArrowLoc[i].z)) &&
-                                            mouse.y > merchArrowLoc[i].y - 8 && mouse.y < merchArrowLoc[i].y + 8) {
-                                               glColor3ub(255,255, 0);
-                        glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255,255,0)));
-                    }else{
-                                               glColor3ub(255,255,255);
-                        glBindTexture(GL_TEXTURE_2D, Texture::genColor(Color(255,255,255)));
-                                       }
-
-                    GLfloat tri_t[] = {0.0, 0.0,
-                                       0.0, 1.0,
-                                       1.0, 1.0};
-
-                    GLfloat tri_c[] = {merchArrowLoc[i].x, merchArrowLoc[i].y,      -7.1,
-                                       merchArrowLoc[i].z, merchArrowLoc[i].y - 8,  -7.1,
-                                       merchArrowLoc[i].z, merchArrowLoc[i].y + 8,  -7.1};
-
-                    glUniform1i(Render::textShader.uniform[WU_texture], 0);
-
-                                       Render::textShader.use();
-                                       Render::textShader.enable();
-
-                    glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, tri_c);
-                    glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tri_t);
-                    glDrawArrays(GL_TRIANGLES, 0 ,6);
-
-                    Render::textShader.disable();
-                                       Render::textShader.unuse();
-                               }
-
-
-                               // draw / handle dialog options if they exist
-                               for(i = 0; i < dialogOptText.size(); i++) {
-                                       setFontColor(255, 255, 255);
-
-                                       // draw option
-                                       dialogOptText[i].second.y = y - SCREEN_HEIGHT / 2 - (fontSize + game::HLINE) * (i + 1);
-                                       tmp = putStringCentered(offset.x, dialogOptText[i].second.y, dialogOptText[i].first);
-
-                                       // get coordinate information on option
-                                       dialogOptText[i].second.z = offset.x + tmp;
-                                       dialogOptText[i].second.x = offset.x - tmp;
-
-                                       // make text yellow if the mouse hovers over the text
-                                       if (mouse.x > dialogOptText[i].second.x && mouse.x < dialogOptText[i].second.z &&
-                                          mouse.y > dialogOptText[i].second.y && mouse.y < dialogOptText[i].second.y + 16) {
-                                                 setFontColor(255, 255, 0);
-                                                 putStringCentered(offset.x, dialogOptText[i].second.y, dialogOptText[i].first);
-                                       }
-                               }
-
-                               setFontColor(255, 255, 255);
                        } else { //normal dialog box
 
                                x = offset.x - SCREEN_WIDTH / 2  + HLINES(8);
@@ -1125,15 +933,15 @@ namespace ui {
                }
 
                if (!fadeIntensity) {
-                       vec2 hub = {
+                       /*vec2 hub = {
                                (SCREEN_WIDTH/2+offset.x)-fontSize*10,
                                (offset.y+SCREEN_HEIGHT/2)-fontSize
-                       };
+                       };*/
 
-                       putText(hub.x,hub.y,"Health: %u/%u",player->health>0?(unsigned)player->health:0,
+                       /*putText(hub.x,hub.y,"Health: %u/%u",player->health>0?(unsigned)player->health:0,
                                                                                                (unsigned)player->maxHealth
-                                                                                               );
-                       static GLuint frontHealth = Texture::genColor(Color(255,0,0));
+                                                                                               );*/
+                       /*static GLuint frontHealth = Texture::genColor(Color(255,0,0));
                        static GLuint backHealth = Texture::genColor(Color(150,0,0));
 
                        if (player->isAlive()) {
@@ -1174,13 +982,13 @@ namespace ui {
 
                 Render::textShader.disable();
                                Render::textShader.unuse();
-            }
+            }*/
 
                        /*
                         *      Lists all of the quests the player is currently taking.
                        */
 
-                       setFontColor(255,255,255,fontTransInv);
+                       /*setFontColor(255,255,255,fontTransInv);
                        if (player->inv->invOpen) {
                                hub.y = player->loc.y + fontSize * 8;
                                hub.x = player->loc.x;// + player->width / 2;
@@ -1201,7 +1009,7 @@ namespace ui {
                                hub.x = offset.x - SCREEN_WIDTH/2 + 45*4*1.5;
 
                                putStringCentered(hub.x,hub.y,"Inventory:");
-                       }
+                       }*/
                        setFontColor(255,255,255,255);
                }
        }
@@ -1248,26 +1056,8 @@ namespace ui {
                        }
                }
 
-               if (dialogMerchant) {
-                       for (i = 0; i < merchArrowLoc.size(); i++) {
-
-                               // TODO neaten this if statement
-
-                               if (((merchArrowLoc[i].x < merchArrowLoc[i].z) ?
-                                   (mouse.x > merchArrowLoc[i].x && mouse.x < merchArrowLoc[i].z) :
-                                   (mouse.x < merchArrowLoc[i].x && mouse.x > merchArrowLoc[i].z) &&
-                                        mouse.y > merchArrowLoc[i].y - 8 && mouse.y < merchArrowLoc[i].y + 8)) {
-                                               merchOptChosen = i + 1;
-                                               goto EXIT;
-                               }
-                       }
-               }
-
-
 EXIT:
-               //if (!dialogMerchant)closeBox();
                dialogBoxExists = false;
-               dialogMerchant = false;
 
                // handle important text
                if (dialogImportant) {
@@ -1441,18 +1231,12 @@ void InputSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
        auto SCREEN_WIDTH = game::SCREEN_WIDTH;
        auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
 
-       Mob *m; // ;lkjfdsa
-       Entity *ent; // used for interaction
-
        SDL_Event e;
 
        // update mouse coords
        mouse.x = premouse.x + offset.x - (SCREEN_WIDTH / 2);
        mouse.y = (offset.y + SCREEN_HEIGHT / 2) - premouse.y;
 
-       static vec2 fr;
-       static Entity *ig;
-
        while(SDL_PollEvent(&e)) {
                switch(e.type) {
 
@@ -1467,21 +1251,13 @@ void InputSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                        premouse.y=e.motion.y;
                        break;
 
-               case SDL_MOUSEBUTTONUP:
-                       if (ig) {
-                               ig->vel.x = (fr.x - mouse.x) / 50.0f;
-                               ig->vel.y = (fr.y - mouse.y) / 50.0f;
-                               //ig->forcedMove = true; // kills vel.x too quickly
-                               ig = NULL;
-                       }
-                       break;
+               //case SDL_MOUSEBUTTONUP:
 
-               // mouse clicks
                case SDL_MOUSEBUTTONDOWN:
 
                        // run actions?
-                       if ((action::make = e.button.button & SDL_BUTTON_RIGHT))
-                               /*player->inv->invHover =*/ edown = false;
+                       //if ((action::make = e.button.button & SDL_BUTTON_RIGHT))
+                       //      /*player->inv->invHover =*/ edown = false;
 
                        textToDraw.clear();
 
@@ -1492,31 +1268,13 @@ void InputSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                        } else {
                                // left click uses item
                                if (e.button.button & SDL_BUTTON_LEFT) {
-                                       if ((ent = currentWorld->getNearMob(*player)) != nullptr) {
+                                       /*if ((ent = currentWorld->getNearMob(*player)) != nullptr) {
                                                player->inv->currentAddInteract(ent);
                                        }
-                                               player->inv->useCurrent();
+                                               player->inv->useCurrent();*/
                                }
 
                        }
-
-                       if(mouse.x > player->loc.x && mouse.x < player->loc.x + player->width &&
-                          mouse.y > player->loc.y && mouse.y < player->loc.y + player->height) {
-                               player->vel.y = .05;
-                               fr = mouse;
-                               ig = player;
-                       } else {
-                               for (auto &e : currentWorld->entity) {
-                                       if (mouse.x > e->loc.x && mouse.x < e->loc.x + e->width &&
-                                               mouse.y > e->loc.y && mouse.y < e->loc.y + e->height) {
-                                               e->vel.y = .05;
-                                               fr = mouse;
-                                               ig = e;
-                                               break;
-                                       }
-                               }
-                       }
-
                        break;
 
                case SDL_MOUSEWHEEL:
@@ -1534,13 +1292,16 @@ void InputSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                case SDL_KEYUP:
                        ev.emit<KeyUpEvent>(SDL_KEY);
 
+                       if (SDL_KEY == SDLK_ESCAPE)
+                               ui::menu::toggle();
+
                        if (SDL_KEY == SDLK_q) {
-                               auto item = player->inv->getCurrentItem();
+                               /*auto item = player->inv->getCurrentItem();
                                if (item != nullptr) {
                                        if (player->inv->takeItem(item->name, 1) == 0)
                                                currentWorld->addObject(item->name, "o shit waddup",
                                                                                                player->loc.x + player->width / 2, player->loc.y + player->height / 2);
-                               }
+                               }*/
                        } else if (SDL_KEY == SDLK_h) {
                                quest::toggle();
                        } else switch (SDL_KEY) {
@@ -1550,30 +1311,10 @@ void InputSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                        case SDLK_BACKSLASH:
                                dialogBoxExists = false;
                                break;
-                       case SDLK_x:
-                               m = currentWorld->getNearMob(*player);
-                               if (m != nullptr)
-                                       m->ride(player);
-                               break;
-                       case SDLK_l:
-                               currentWorld->addLight({player->loc.x + SCREEN_WIDTH/2, player->loc.y}, 300.0f, {1.0f,1.0f,1.0f});
-                               currentWorld->getLastLight().follow(player);
-                               currentWorld->getLastLight().makeFlame();
-                               break;
-                       case SDLK_f:
-                               currentWorld->addLight({player->loc.x, player->loc.y}, 300.0f, {1.0f,1.0f,1.0f});
-                               break;
                        case SDLK_b:
                                if (debug)
                                        posFlag ^= true;
-                               else {
-                                       auto s = new Structures();
-                                       s->spawn(FIRE_PIT, player->loc.x, player->loc.y);
-                                       //currentWorld->addStructure(s);
-                                       //currentWorld->addLight({player->loc.x + SCREEN_WIDTH/2, player->loc.y}, 400.0f, {1.0f,1.0f,1.0f});
-                                       //currentWorld->getLastLight()->follow(currentWorld->build.back());
-                                       //currentWorld->getLastLight()->makeFlame();
-                               }
+
                                break;
                        case SDLK_F12:
                                // Make the BYTE array, factor of 3 because it's RBG.
@@ -1585,10 +1326,10 @@ void InputSystem::update(entityx::EntityManager &en, entityx::EventManager &ev,
                                std::cout << "Took screenshot" << std::endl;
                                break;
                        case SDLK_UP:
-                               player->inv->setSelectionUp();
+                               //player->inv->setSelectionUp();
                                break;
                        case SDLK_DOWN:
-                               player->inv->setSelectionDown();
+                               //player->inv->setSelectionDown();
                                break;
                        default:
                                break;
diff --git a/src/ui_action.cpp b/src/ui_action.cpp
deleted file mode 100644 (file)
index 9029907..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-#include <ui_action.hpp>
-#include <world.hpp>
-
-#define ACTION_PROLOUGE { actioning = true; }
-#define ACTION_EPILOUGE { actioning = false; actionHover = 0; }
-
-extern World *currentWorld;
-extern Arena *arena;
-extern Player *player;
-extern bool inBattle;
-
-static std::vector<std::pair<std::string, vec3>> actionText = {
-    {"Attack", vec3 {0, 0, 0}},
-    {"Action", vec3 {0, 0, 0}},
-    {"Umm"   , vec3 {0, 0, 0}}
-};
-
-void actionAttack(void);
-void actionAction(void);
-
-static std::vector<void (*)(void)> actionFunc = {
-    actionAttack,
-    actionAction,
-    nullptr,
-};
-
-static bool actionToggle = false, actioning = false;
-static unsigned int actionHover = 0;
-static Entity *nearEntity = nullptr, *lastEntity = nullptr;
-
-namespace ui {
-    namespace action {
-        bool make = false;
-
-        // enables action ui
-        void enable(void) {
-            actionToggle = true;
-        }
-
-        // disables action ui
-        void disable(void) {
-            actionToggle = false;
-
-            if (lastEntity != nullptr)
-                lastEntity->canMove = true;
-        }
-
-        // draws the action ui
-        void draw(vec2 loc) {
-            unsigned int i = 1;
-            float y = loc.y;
-
-            if (!actionToggle)
-                return;
-
-            nearEntity = currentWorld->getNearInteractable(*player);
-
-            if (nearEntity == nullptr) {
-                if (lastEntity != nullptr) {
-                    lastEntity->canMove = true;
-                    lastEntity = nullptr;
-                }
-                return;
-            } else if (nearEntity != lastEntity) {
-                if (lastEntity != nullptr)
-                    lastEntity->canMove = true;
-                lastEntity = nearEntity;
-            }
-
-            if (make) {
-                while(actioning);
-
-                if (!actionHover) {
-                    make = false;
-                    return;
-                }
-
-                if (actionFunc[actionHover - 1] != nullptr)
-                    std::thread(actionFunc[actionHover - 1]).detach();
-
-                actionHover = 0;
-            } else {
-                nearEntity->canMove = false;
-                ui::drawBox(vec2 {loc.x - HLINES(11), loc.y}, vec2 {loc.x + HLINES(12), loc.y + actionText.size() * HLINES(8)});
-
-                for (auto &s : actionText) {
-                    s.second.z = ui::putStringCentered((s.second.x = loc.x), (s.second.y = (y += fontSize * 1.15f)), s.first) / 2;
-
-                    if (ui::mouse.x > s.second.x - s.second.z && ui::mouse.x < s.second.x + s.second.z &&
-                        ui::mouse.y > s.second.y && ui::mouse.y < s.second.y + ui::fontSize) {
-                        actionHover = i;
-                        ui::setFontColor(255, 100, 100, 255);
-                        ui::putStringCentered(s.second.x, s.second.y, s.first);
-                        ui::setFontColor(255, 255, 255, 255);
-                    }
-                    i++;
-                }
-
-                ui::putStringCentered(loc.x, y + fontSize * 1.2f, nearEntity->name);
-            }
-
-            if (i == actionText.size())
-                actionHover = 0;
-
-            ui::setFontColor(255, 255, 255, 255);
-            make = false;
-        }
-    }
-}
-
-void actionAttack(void)
-{
-    ACTION_PROLOUGE;
-
-    auto m = currentWorld->getNearInteractable(*player);
-
-    if (m->type == MOBT) {
-        if (!inBattle && m != nullptr) {
-            arena->fight(currentWorld, player, Mobp(m));
-
-            ui::toggleWhiteFast();
-            ui::waitForCover();
-            currentWorld = arena;
-            ui::toggleWhiteFast();
-        }
-    } else {
-        ui::dialogBox(player->name, "", false, "%s doesn't appear to be in the mood for fighting...", m->name.c_str());
-    }
-
-    ACTION_EPILOUGE;
-}
-
-void actionAction(void)
-{
-    ACTION_PROLOUGE;
-
-    auto e = currentWorld->getNearInteractable(*player);
-
-    if (e->type == NPCT)
-        e->interact();
-
-    ACTION_EPILOUGE;
-}
diff --git a/src/ui_action.cpp.bak b/src/ui_action.cpp.bak
new file mode 100644 (file)
index 0000000..9029907
--- /dev/null
@@ -0,0 +1,143 @@
+#include <ui_action.hpp>
+#include <world.hpp>
+
+#define ACTION_PROLOUGE { actioning = true; }
+#define ACTION_EPILOUGE { actioning = false; actionHover = 0; }
+
+extern World *currentWorld;
+extern Arena *arena;
+extern Player *player;
+extern bool inBattle;
+
+static std::vector<std::pair<std::string, vec3>> actionText = {
+    {"Attack", vec3 {0, 0, 0}},
+    {"Action", vec3 {0, 0, 0}},
+    {"Umm"   , vec3 {0, 0, 0}}
+};
+
+void actionAttack(void);
+void actionAction(void);
+
+static std::vector<void (*)(void)> actionFunc = {
+    actionAttack,
+    actionAction,
+    nullptr,
+};
+
+static bool actionToggle = false, actioning = false;
+static unsigned int actionHover = 0;
+static Entity *nearEntity = nullptr, *lastEntity = nullptr;
+
+namespace ui {
+    namespace action {
+        bool make = false;
+
+        // enables action ui
+        void enable(void) {
+            actionToggle = true;
+        }
+
+        // disables action ui
+        void disable(void) {
+            actionToggle = false;
+
+            if (lastEntity != nullptr)
+                lastEntity->canMove = true;
+        }
+
+        // draws the action ui
+        void draw(vec2 loc) {
+            unsigned int i = 1;
+            float y = loc.y;
+
+            if (!actionToggle)
+                return;
+
+            nearEntity = currentWorld->getNearInteractable(*player);
+
+            if (nearEntity == nullptr) {
+                if (lastEntity != nullptr) {
+                    lastEntity->canMove = true;
+                    lastEntity = nullptr;
+                }
+                return;
+            } else if (nearEntity != lastEntity) {
+                if (lastEntity != nullptr)
+                    lastEntity->canMove = true;
+                lastEntity = nearEntity;
+            }
+
+            if (make) {
+                while(actioning);
+
+                if (!actionHover) {
+                    make = false;
+                    return;
+                }
+
+                if (actionFunc[actionHover - 1] != nullptr)
+                    std::thread(actionFunc[actionHover - 1]).detach();
+
+                actionHover = 0;
+            } else {
+                nearEntity->canMove = false;
+                ui::drawBox(vec2 {loc.x - HLINES(11), loc.y}, vec2 {loc.x + HLINES(12), loc.y + actionText.size() * HLINES(8)});
+
+                for (auto &s : actionText) {
+                    s.second.z = ui::putStringCentered((s.second.x = loc.x), (s.second.y = (y += fontSize * 1.15f)), s.first) / 2;
+
+                    if (ui::mouse.x > s.second.x - s.second.z && ui::mouse.x < s.second.x + s.second.z &&
+                        ui::mouse.y > s.second.y && ui::mouse.y < s.second.y + ui::fontSize) {
+                        actionHover = i;
+                        ui::setFontColor(255, 100, 100, 255);
+                        ui::putStringCentered(s.second.x, s.second.y, s.first);
+                        ui::setFontColor(255, 255, 255, 255);
+                    }
+                    i++;
+                }
+
+                ui::putStringCentered(loc.x, y + fontSize * 1.2f, nearEntity->name);
+            }
+
+            if (i == actionText.size())
+                actionHover = 0;
+
+            ui::setFontColor(255, 255, 255, 255);
+            make = false;
+        }
+    }
+}
+
+void actionAttack(void)
+{
+    ACTION_PROLOUGE;
+
+    auto m = currentWorld->getNearInteractable(*player);
+
+    if (m->type == MOBT) {
+        if (!inBattle && m != nullptr) {
+            arena->fight(currentWorld, player, Mobp(m));
+
+            ui::toggleWhiteFast();
+            ui::waitForCover();
+            currentWorld = arena;
+            ui::toggleWhiteFast();
+        }
+    } else {
+        ui::dialogBox(player->name, "", false, "%s doesn't appear to be in the mood for fighting...", m->name.c_str());
+    }
+
+    ACTION_EPILOUGE;
+}
+
+void actionAction(void)
+{
+    ACTION_PROLOUGE;
+
+    auto e = currentWorld->getNearInteractable(*player);
+
+    if (e->type == NPCT)
+        e->interact();
+
+    ACTION_EPILOUGE;
+}
index 4b4b05c41eebc4a21b941320412ccc91c4d206d0..cbe771825cf3e957e31265de94657afb6f7c9fbe 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <engine.hpp>
 #include <render.hpp>
+#include <texture.hpp>
 
 #include <fstream>
 
index ef9969f62f57cd8aeda7d4cf6679f7d391fbfe83..2772160c6d58781720b9664ab46c9102d4083c9e 100644 (file)
@@ -47,12 +47,6 @@ void makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions_Ju
 ** Variables section
 ** --------------------------------------------------------------------------*/
 
-// external variables
-extern Player      *player;                                    // main.cpp?
-extern World       *currentWorld;                      // main.cpp
-extern World       *currentWorldToLeft;                // main.cpp
-extern World       *currentWorldToRight;       // main.cpp
-extern bool         inBattle;               // ui.cpp?
 extern std::string  xmlFolder;
 
 // particle mutex
@@ -73,9 +67,6 @@ constexpr const unsigned int GRASS_HEIGHT = 4;
 // the path of the currently loaded XML file, externally referenced in places
 std::string currentXML;
 
-// keeps track of information of worlds the player has left to enter arenas
-static std::vector<WorldSwitchInfo> arenaNest;
-
 // pathnames of images for world themes
 using StyleList = std::array<std::string, 9>;
 
@@ -120,88 +111,29 @@ XMLDocument currentXMLDoc;
 ** Functions section
 ** --------------------------------------------------------------------------*/
 
-/**
- * Creates a world object.
- * Note that all this does is nullify a pointer...
- */
-World::World(bool indoor)
-       : m_Indoor(indoor), lineCount(0), worldStart(0) 
-{
-}
-
-/**
- * The world destructor.
- * This will free objects used by the world itself, then free the vectors of
- * entity-related objects.
- */
-World::
-~World(void)
-{
-       deleteEntities();
-}
-
-/**
- * The entity vector destroyer.
- * This function will free all memory used by all entities, and then empty the
- * vectors they were stored in.
- */
-template<class T>
-void clearPointerVector(T &vec)
-{
-    while (!vec.empty()) {
-        delete vec.back();
-        vec.pop_back();
-     }
-}
-
-void World::
-deleteEntities(void)
-{
-    // free particles
-       particles.clear();
-    // clear light array
-       light.clear();
-    // free villages
-       village.clear();
-    // clear entity array
-       clearPointerVector(entity);
-}
-
-/**
- * Generates a world of the specified width.
- * This will mainly populate the WorldData array, preparing most of the world
- * object for usage.
- */
-void World::
-generate(int width)
+void WorldSystem::generate(unsigned int width)
 {
     float geninc = 0;
 
-    // check for valid width
-    if (width <= 0)
-        UserError("Invalid world dimensions");
-
     // allocate space for world
-    worldData = std::vector<WorldData> (width + GROUND_HILLINESS, WorldData { false, {0, 0}, 0, 0 });
-    lineCount = worldData.size();
+    world.data = std::vector<WorldData> (width + GROUND_HILLINESS, WorldData { false, {0, 0}, 0, 0 });
 
     // prepare for generation
-    worldData.front().groundHeight = GROUND_HEIGHT_INITIAL;
-    auto wditer = std::begin(worldData) + GROUND_HILLINESS;
-
-       if (m_Indoor) {
-               for(wditer = std::begin(worldData); wditer < std::end(worldData); wditer++) {
-                       auto w = &*(wditer);
-                       w->groundHeight = GROUND_HEIGHT_MINIMUM + 5;
-                       w->groundColor = 4;
+    world.data[0].groundHeight = GROUND_HEIGHT_INITIAL;
+    auto wditer = std::begin(world.data) + GROUND_HILLINESS;
+
+       if (world.indoor) {
+               for (auto &l : world.data) {
+                       l.groundHeight = GROUND_HEIGHT_MINIMUM + 5;
+                       l.groundColor = 4;
                }
        } else {
            // give every GROUND_HILLINESSth entry a groundHeight value
-           for (; wditer < std::end(worldData); wditer += GROUND_HILLINESS)
+           for (; wditer < std::end(world.data); wditer += GROUND_HILLINESS)
                wditer[-static_cast<int>(GROUND_HILLINESS)].groundHeight = wditer[0].groundHeight + (randGet() % 8 - 4);
 
        // create slopes from the points that were just defined, populate the rest of the WorldData structure
-           for (wditer = std::begin(worldData) + 1; wditer < std::end(worldData); wditer++){
+           for (wditer = std::begin(world.data) + 1; wditer < std::end(world.data); wditer++){
                auto w = &*(wditer);
 
            if (w->groundHeight != 0)
@@ -216,585 +148,22 @@ generate(int width)
        }
 
     // define x-coordinate of world's leftmost 'line'
-    worldStart = (width - GROUND_HILLINESS) * game::HLINE / 2 * -1;
-
-    // create empty star array, should be filled here as well...
-       star = std::vector<vec2> (100, vec2 { 0, 400 });
-       for (auto &s : star) {
-               s.x = (randGet() % (static_cast<int>(-worldStart) * 2)) + worldStart;
-               s.y = (randGet() % game::SCREEN_HEIGHT) + 100;
-       }
+    world.startX = (width - GROUND_HILLINESS) * game::HLINE / 2 * -1;
 }
 
 static Color ambient;
 
-void World::draw(Player *p)
-{
-       auto HLINE = game::HLINE;
-
-       uint ls = light.size();
-
-       GLfloat *lightCoords = new GLfloat[ls * 4];
-       GLfloat *lightColors = new GLfloat[ls * 4];
-
-       uint lpIndex = 0;
-       uint lcIndex = 0;
-
-       static bool ambientUpdaterStarted = false;
-       if (!ambientUpdaterStarted) {
-               ambientUpdaterStarted = true;
-               std::thread([&](void) {
-                       while (true) {
-                               float v = 75 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
-                               float rg = std::clamp(.5f + (-v / 100.0f), 0.01f, .9f);
-                               float b  = std::clamp(.5f + (-v / 80.0f), 0.03f, .9f);
-
-                               ambient = Color(rg, rg, b, 1.0f);
-
-                               std::this_thread::sleep_for(std::chrono::milliseconds(1));
-                       }
-               }).detach();
-       }
-
-       for (uint i = 0; i < ls; i++) {
-               auto &l = light[i];
-               if (l.belongsTo) {
-            l.loc.x = l.following->loc.x;
-            l.loc.y = l.following->loc.y;
-        }
-        if (l.flame) {
-            l.fireFlicker = 0.9f + ((rand()% 2 ) / 10.0f);
-            l.fireLoc.x = l.loc.x + (rand() % 2 - 1) * 3;
-            l.fireLoc.y = l.loc.y + (rand() % 2 - 1) * 3;
-        } else {
-            l.fireFlicker = 1;
-        }
-
-               lightCoords[lpIndex++] = l.loc.x;
-               lightCoords[lpIndex++] = l.loc.y;
-               lightCoords[lpIndex++] = 0.0;
-               lightCoords[lpIndex++] = l.radius;
-
-               lightColors[lcIndex++] = l.color.red;
-               lightColors[lcIndex++] = l.color.green;
-               lightColors[lcIndex++] = l.color.blue;
-               lightColors[lcIndex++] = 1.0;
-       }
-
-       Render::worldShader.use();
-
-       glUniform4fv(Render::worldShader.uniform[WU_light], ls, lightCoords);
-       glUniform4fv(Render::worldShader.uniform[WU_light_color], ls, lightColors);
-       glUniform1i(Render::worldShader.uniform[WU_light_size], ls);
-
-       Render::worldShader.unuse();
-
-       for (auto &e :entity)
-        e->draw();
-
-       // flatten grass under the player if the player is on the ground
-       if (p->ground) {
-               int pOffset = (p->loc.x + p->width / 2 - worldStart) / HLINE;
-
-               for (unsigned int i = 0; i < worldData.size(); i++)
-                       worldData[i].grassUnpressed = !(i < static_cast<unsigned int>(pOffset + 6) && i > static_cast<unsigned int>(pOffset - 6));
-       } else {
-               for (auto &wd : worldData)
-                       wd.grassUnpressed = true;
-       }
-
-    // draw the player
-       //p->draw();
-
-       // draw particles like a MASTAH
-    glBindTexture(GL_TEXTURE_2D, colorIndex);
-    glUniform1i(Render::worldShader.uniform[WU_texture], 0);
-    Render::worldShader.use();
-
-       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, .8);
-
-    Render::worldShader.enable();
-
-       partMutex.lock();
-       uint ps = particles.size();
-    uint pss = ps * 6 * 5;
-       uint pc = 0;
-
-       std::vector<GLfloat> partVec(pss);
-       auto *pIndex = &partVec[0];
-       for (uint i = 0; i < ps; i++) {
-        pc += 30;
-               if (pc > pss) {
-                       // TODO resize the vector or something better than breaking
-                       break;
-               }
-               particles[i].draw(pIndex);
-    }
-       partMutex.unlock();
-
-    glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &partVec[0]);
-    glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &partVec[3]);
-    glDrawArrays(GL_TRIANGLES, 0, ps * 6);
-
-    Render::worldShader.disable();
-
-       glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0);
-
-    Render::worldShader.unuse();
-}
-
-/**
- * Get's the world's width in pixels.
- */
-int World::
-getTheWidth(void) const
-{
-       return (worldStart * -2);
-}
-
-float World::
-getWorldStart(void) const
-{
-    return static_cast<float>(worldStart);
-}
-
-/**
- * Get a pointer to the most recently created light.
- * Meant to be non-constant.
- */
-Light& World::
-getLastLight(void)
-{
-    return light.back();
-}
-
-/**
- * Get a pointer to the most recently created mob.
- * Meant to be non-constant.
- */
-Mob* World::
-getLastMob(void)
-{
-       for (auto e = entity.rbegin(); e != entity.rend(); ++e) {
-               if ((*e)->type == MOBT)
-                       return dynamic_cast<Mob *>(*e);
-       }
-
-    return nullptr;
-}
-
-/**
- * Get the interactable entity that is closest to the entity provided.
- */
-Entity* World::
-getNearInteractable(Entity &e)
-{
-    auto n = std::find_if(std::begin(entity), std::end(entity), [&](Entity *&a) {
-        return ((a->type == MOBT) || (a->type == NPCT) || a->type == MERCHT) &&
-               e.isNear(a) && (e.left ? (a->loc.x < e.loc.x) : (a->loc.x > e.loc.x));
-    });
-
-    return n == std::end(entity) ? nullptr : *n;
-}
-
-Mob* World::
-getNearMob(Entity &e)
-{
-    auto n = std::find_if(std::begin(entity), std::end(entity), [&](Entity *a) {
-        return (a->type == MOBT && e.isNear(a) && (e.left ? (a->loc.x < e.loc.x + e.width / 2) : (a->loc.x + a->width > e.loc.x + e.width / 2)));
-    });
-
-    return (n == std::end(entity)) ? nullptr : dynamic_cast<Mob *>(*n);
-}
-
-
-/**
- * Get the file path for the `index`th building.
- */
-std::string World::
-getSTextureLocation(unsigned int index) const
-{
-    return index < sTexLoc.size() ? sTexLoc[ index ] : "";
-}
-
-/**
- * Get the coordinates of the `index`th building, with -1 meaning the last building.
- */
-vec2 World::
-getStructurePos(int index)
-{
-    if (index < 0) {
-               for (auto e = entity.rbegin(); e != entity.rend(); ++e) {
-                       if ((*e)->type == STRUCTURET)
-                               return (*e)->loc;
-               }
-
-               return vec2 {0, 0};
-       }
-
-       int nth = 0;
-       for (const auto &e : entity) {
-               if (e->type == STRUCTURET) {
-                       if (index == nth)
-                               return e->loc;
-                       else
-                               ++nth;
-               }
-       }
-
-    return vec2 {0, 0};
-}
-
-/**
- * Saves world data to a file.
- */
-void World::save(const std::string& s)
+bool WorldSystem::save(const std::string& s)
 {
-       for (const auto &e : entity)
+       (void)s;
+       /*for (const auto &e : entity)
                e->saveToXML();
-       currentXMLDoc.SaveFile((s.empty() ? currentXML : xmlFolder + s).c_str(), false);
-}
-
-/**
- * Sets the desired theme for the world's background.
- * The images chosen for the background layers are selected depending on the
- * world's background type.
- */
-void World::setBackground(WorldBGType bgt)
-{
-       bgType = bgt;
-}
-
-/**
- * Sets the world's style.
- * The world's style will determine what sprites are used for things like\
- * generic structures.
- */
-void World::setStyle(std::string pre)
-{
-    // get folder prefix
-       std::string prefix = pre.empty() ? "assets/style/classic/" : pre;
-       styleFolder = prefix + "bg/";
-
-    for (const auto &s : buildPaths)
-        sTexLoc.push_back(prefix + s);
-}
-
-/**
- * Pretty self-explanatory.
- */
-std::string World::setToLeft(std::string file)
-{
-    return (toLeft = file);
-}
-
-/**
- * Pretty self-explanatory.
- */
-std::string World::setToRight(std::string file)
-{
-       return (toRight = file);
-}
-
-/**
- * Pretty self-explanatory.
- */
-std::string World::getToLeft(void) const
-{
-    return toLeft;
-}
-
-/**
- * Pretty self-explanatory.
- */
-std::string World::getToRight(void) const
-{
-    return toRight;
-}
-
-/**
- * Attempts to go to the left world, returning either that world or itself.
- */
-WorldSwitchInfo World::goWorldLeft(Player *p)
-{
-       World *tmp;
-    // check if player is at world edge
-       if (!toLeft.empty() && p->loc.x < worldStart + HLINES(15)) {
-        // load world (`toLeft` conditional confirms existance)
-           tmp = loadWorldFromPtr(currentWorldToLeft);
-
-        // return pointer and new player coords
-        return std::make_pair(tmp, vec2 {tmp->worldStart + tmp->getTheWidth() - (float)HLINES(15),
-                              tmp->worldData[tmp->lineCount - 1].groundHeight});
-       }
-
-       return std::make_pair(this, vec2 {0, 0});
-}
-
-/**
- * Attempts to go to the right world, returning either that world or itself.
- */
-WorldSwitchInfo World::goWorldRight(Player *p)
-{
-       World *tmp;
-       if (!toRight.empty() && p->loc.x + p->width > -worldStart - HLINES(15)) {
-        tmp = loadWorldFromPtr(currentWorldToRight);
-        return std::make_pair(tmp, vec2 {tmp->worldStart + (float)HLINES(15.0), GROUND_HEIGHT_MINIMUM} );
-       }
-
-       return std::make_pair(this, vec2 {0, 0});
-}
-
-void World::adoptNPC(NPC *e)
-{
-       entity.push_back(e);
-}
-
-void World::adoptMob(Mob* e)
-{
-       entity.push_back(e);
-}
-
-/**
- * Acts like goWorldLeft(), but takes an NPC; returning true on success.
- */
-bool World::goWorldLeft(NPC *e)
-{
-       // check if entity is at world edge
-       if (!toLeft.empty() && e->loc.x < worldStart + HLINES(15)) {
-               currentWorldToLeft->adoptNPC(e);
-
-               entity.erase(std::find(std::begin(entity), std::end(entity), e));
-
-        e->loc.x = currentWorldToLeft->worldStart + currentWorldToLeft->getTheWidth() - HLINES(15);
-               e->loc.y = GROUND_HEIGHT_MAXIMUM;
-               ++e->outnabout;
-
-               return true;
-       }
-
-       return false;
-}
-
-bool World::goWorldRight(NPC *e)
-{
-       if (!toRight.empty() && e->loc.x + e->width > -worldStart - HLINES(15)) {
-               currentWorldToRight->adoptNPC(e);
-
-               entity.erase(std::find(std::begin(entity), std::end(entity), e));
-
-               e->loc.x = currentWorldToRight->worldStart + HLINES(15);
-               e->loc.y = GROUND_HEIGHT_MINIMUM;
-               --e->outnabout;
-
-               return true;
-       }
 
+       currentXMLDoc.SaveFile((s.empty() ? currentXML : xmlFolder + s).c_str(), false);*/
        return false;
 }
 
-/**
- * Attempts to enter a building that the player is standing in front of.
- */
-WorldSwitchInfo World::goInsideStructure(Player *p)
-{
-       World *tmp;
-       static std::string outdoorData, outdoorName;
-
-       // enter a building
-       if (outdoorName.empty()) {
-        auto d = std::find_if(std::begin(entity), std::end(entity), [p](const Entity *s) {
-            return ((p->loc.x > s->loc.x) && (p->loc.x + p->width < s->loc.x + s->width));
-        });
-
-        if ((d == std::end(entity)) || dynamic_cast<Structures *>(*d)->inside.empty())
-            return std::make_pair(this, vec2 {0, 0});
-
-               outdoorData = currentXMLRaw;
-               outdoorName = currentXML;
-               currentXML = xmlFolder + dynamic_cast<Structures *>(*d)->inside;
-               const char *buf = readFile(currentXML.c_str());
-               currentXMLRaw = buf;
-               delete[] buf;
-
-               tmp = dynamic_cast<Structures *>(*d)->insideWorld;
-               tmp->houseTex = dynamic_cast<Structures *>(*d)->insideTex;
-
-               return std::make_pair(tmp, vec2 {0, 100});
-       }
-
-       // exit the building
-       else {
-        std::string current = &currentXML[xmlFolder.size()];
-               currentXML = outdoorName;
-               currentXMLRaw = outdoorData;
-               outdoorName.clear();
-               outdoorData.clear();
-
-               /*tmp = dynamic_cast<IndoorWorld *>(currentWorld)->outside; //loadWorldFromXML(inside.back());
-
-        Structures *b = nullptr;
-        for (auto &s : tmp->entity) {
-            if (s->type == STRUCTURET && dynamic_cast<Structures *>(s)->inside == current) {
-                b = dynamic_cast<Structures *>(s);
-                break;
-            }
-        }
-
-        if (b == nullptr)*/
-            return std::make_pair(currentWorld, vec2 {0, 100});
-
-               //return std::make_pair(tmp, vec2 {b->loc.x + (b->width / 2), 0});
-       }
-
-       return std::make_pair(this, vec2 {0, 0});
-}
-
-void World::
-addStructure(Structures *s)
-{
-       entityPending.push_back(s);
-}
-
-Village *World::
-addVillage(std::string name, World *world)
-{
-    village.emplace_back(name, world);
-    return &village.back();
-}
-
-void World::addMob(Mob *m, vec2 coord)
-{
-       m->spawn(coord.x, coord.y);
-
-       entityPending.push_back(m);
-}
-
-void World::
-addNPC(NPC *n)
-{
-       entityPending.push_back(n);
-}
-
-void World::
-addMerchant(float x, float y, bool housed)
-{
-       Merchant *tmp = new Merchant();
-
-       tmp->spawn(x, y);
-
-    if (housed) {
-        tmp->inside = dynamic_cast<Structures *>(*std::find_if(entity.rbegin(), entity.rend(), [&](Entity *e){ return (e->type == STRUCTURET); }));
-       tmp->z = tmp->inside->z + 0.1f;
-       }
-
-       entityPending.push_back(tmp);
-}
-
-void World::
-addObject(std::string in, std::string p, float x, float y)
-{
-       Object *tmp = new Object(in, p);
-       tmp->spawn(x, y);
-
-       entityPending.push_back(tmp);
-}
-
-void World::
-addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d)
-{
-       particles.push_back(Particles(x, y, w, h, vx, vy, color, d));
-       particles.back().canMove = true;
-}
-
-void World::
-addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d, unsigned char flags)
-{
-       particles.push_back(Particles(x, y, w, h, vx, vy, color, d));
-       particles.back().canMove = true;
-    particles.back().gravity = flags & (1 << 0);
-    particles.back().bounce  = flags & (1 << 1);
-}
-
-void World::
-addLight(vec2 loc, float radius, Color color)
-{
-       if (light.size() < 128)
-        light.emplace_back(loc, radius, color);
-}
-
-void World::
-addHole(unsigned int start, unsigned int end)
-{
-    end = fmin(worldData.size(), end);
-
-       for (unsigned int i = start; i < end; i++)
-               worldData[i].groundHeight = 0;
-}
-
-void World::
-addHill(const ivec2 peak, const unsigned int width)
-{
-       int start  = peak.x - width / 2,
-        end    = start + width,
-        offset = 0;
-       const float thing = peak.y - worldData[std::clamp(start, 0, static_cast<int>(lineCount))].groundHeight;
-    const float period = PI / width;
-
-       if (start < 0) {
-        offset = -start;
-        start = 0;
-    }
-
-    end = fmin(worldData.size(), end);
-
-       for (int i = start; i < end; i++) {
-               worldData[i].groundHeight += thing * sin((i - start + offset) * period);
-               if (worldData[i].groundHeight > peak.y)
-                       worldData[i].groundHeight = peak.y;
-       }
-}
-
-Arena::Arena(void)
-{
-       generate(800);
-       addMob(new Door(), vec2 {100, 100});
-       mmob = nullptr;
-}
-
-Arena::~Arena(void)
-{
-    if (mmob != nullptr)
-               mmob->die();
-       deleteEntities();
-}
-
-void Arena::fight(World *leave, const Player *p, Mob *m)
-{
-    inBattle = true;
-
-    entity.push_back((mmob = m));
-       mmob->aggressive = false;
-
-    arenaNest.emplace_back(leave, p->loc);
-}
-
-WorldSwitchInfo Arena::exitArena(Player *p)
-{
-       if (!mmob->isAlive() &&
-        p->loc.x + p->width / 2 > mmob->loc.x &&
-           p->loc.x + p->width / 2 < mmob->loc.x + HLINES(12)) {
-        auto ret = arenaNest.back();
-        arenaNest.pop_back();
-        inBattle = !(arenaNest.empty());
-
-        return ret;
-    }
-
-    return std::make_pair(this, vec2 {0, 0});
-}
-
-static bool loadedLeft = false;
+/*static bool loadedLeft = false;
 static bool loadedRight = false;
 
 World *loadWorldFromXML(std::string path) {
@@ -823,10 +192,6 @@ World *loadWorldFromPtr(World *ptr)
     return ptr;
 }
 
-/**
- * Loads a world from the given XML file.
- */
-
 World *
 loadWorldFromXMLNoTakeover(std::string path)
 {
@@ -835,7 +200,110 @@ loadWorldFromXMLNoTakeover(std::string path)
        loadedLeft = false, loadedRight = false;
        return ret;
 }
+*/
+
+void WorldSystem::load(const std::string& file)
+{
+       std::string xmlRaw;
+       std::string xmlPath;
+
+       // check for empty file name
+       if (file.empty())
+               return;
+
+       // load file data to string
+       xmlPath = xmlFolder + file;
+       auto xmlRawData = readFile(xmlPath.c_str());
+       xmlRaw = xmlRawData;
+       delete[] xmlRawData;
+
+       // let tinyxml parse the file
+       if (xmlDoc.Parse(xmlRaw.data()) != XML_NO_ERROR)
+               UserError("XML Error: Failed to parse file (not your fault though..?)");
+
+       // look for an opening world tag
+       auto wxml = xmlDoc.FirstChildElement("World");
+       if (wxml != nullptr) {
+               wxml = wxml->FirstChildElement();
+               world.indoor = false;
+       } else {
+               wxml = xmlDoc.FirstChildElement("IndoorWorld");
+               if (wxml != nullptr) {
+                       wxml = wxml->FirstChildElement();
+                       world.indoor = true;
+               } else {
+                       UserError("XML Error: Cannot find a <World> or <IndoorWorld> tag in " + xmlPath);
+               }
+       }
+
+       // iterate through tags
+       while (wxml) {
+               std::string tagName = wxml->Name();
+
+               // style tag
+               if (tagName == "style") {
+                       world.styleFolder = wxml->StrAttribute("folder");
+
+                       unsigned int styleNo;
+                       if (wxml->QueryUnsignedAttribute("background", &styleNo) != XML_NO_ERROR)
+                               UserError("XML Error: No background given in <style> in " + xmlPath);
+
+                       world.style = static_cast<WorldBGType>(styleNo); 
+                       world.bgm = wxml->StrAttribute("bgm");
+
+                       bgFiles.clear();
+
+                       const auto& files = bgPaths[(int)world.style];
+
+                       for (const auto& f : files)
+                               bgFiles.push_back(world.styleFolder + "bg/" + f);
+
+                       bgTex = TextureIterator(bgFiles);
+               }
+
+        // world generation
+        else if (tagName == "generation") {
+                       generate(wxml->UnsignedAttribute("width") / game::HLINE);
+               }
+
+               // indoor stuff
+               else if (tagName == "house") {
+                       if (!world.indoor)
+                               UserError("<house> can only be used inside <IndoorWorld>");
+
+                       world.indoorWidth = wxml->FloatAttribute("width");
+                       world.indoorTex = Texture::loadTexture(wxml->Attribute("texture"));
+               }
+
+               // weather tag
+               else if (tagName == "weather") {
+                       setWeather(wxml->GetText());
+               }
+
+               // link tags
+               else if (tagName == "link") {
+                       auto linkTo = wxml->Attribute("left");
+                       if (linkTo != nullptr) {
+                               world.toLeft = linkTo;
+                       } else {
+                               linkTo = wxml->Attribute("right");
+                               if (linkTo != nullptr)
+                                       world.toRight = linkTo;
+                               else
+                                       UserError("<link> doesn't handle left or right... huh");
+                       }
+               }
+
+               // time setting
+               else if (tagName == "time") {
+            game::time::setTickCount(std::stoi(wxml->GetText()));
+        }
+
+               wxml = wxml->NextSiblingElement();              
+       }
+}
 
+/*
 World *
 loadWorldFromXMLNoSave(std::string path) {
        XMLDocument *_currentXMLDoc;
@@ -852,45 +320,6 @@ loadWorldFromXMLNoSave(std::string path) {
        const char *ptr;
        std::string name, sptr;
 
-    // no file? -> no world
-    if (path.empty())
-        return nullptr;
-
-    _currentXML = xmlFolder + path;
-       const char *worthless = readFile(_currentXML.c_str());
-       _currentXMLRaw = worthless;
-       delete[] worthless;
-
-       // create a temporary XMLDocument if this isn't the main world
-       if (!loadedLeft && !loadedRight)
-               _currentXMLDoc = &currentXMLDoc;
-       else
-               _currentXMLDoc = new XMLDocument();
-
-       // parse the file
-       if (_currentXMLDoc->Parse(_currentXMLRaw.data()) != XML_NO_ERROR)
-               UserError("XML Error: Failed to parse file (not your fault though..?)");
-
-    // attempt to load a <World> tag
-       if ((wxml = _currentXMLDoc->FirstChildElement("World"))) {
-               wxml = wxml->FirstChildElement();
-               vil = _currentXMLDoc->FirstChildElement("World")->FirstChildElement("village");
-               tmp = new World();
-        Indoor = false;
-       }
-
-    // attempt to load an <IndoorWorld> tag
-    else if ((wxml = _currentXMLDoc->FirstChildElement("IndoorWorld"))) {
-               wxml = wxml->FirstChildElement();
-               vil = NULL;
-               tmp = new World(true);
-        Indoor = true;
-       }
-
-    // error: can't load a world...
-    else
-        UserError("XML Error: Cannot find a <World> or <IndoorWorld> tag in " + _currentXML + "!");
-
     // iterate through world tags
        while (wxml) {
                newEntity = nullptr;
@@ -940,38 +369,6 @@ loadWorldFromXMLNoSave(std::string path) {
 
                }
 
-        // style tags
-        else if (name == "style") {
-            // set style folder
-                       tmp->setStyle(wxml->StrAttribute("folder"));
-
-            // set background folder
-                       unsigned int bgt;
-            if (wxml->QueryUnsignedAttribute("background", &bgt) != XML_NO_ERROR)
-                UserError("XML Error: No background given in <style> in " + _currentXML + "!");
-                       tmp->setBackground(static_cast<WorldBGType>(bgt));
-
-            // set BGM file
-            tmp->bgm = wxml->StrAttribute("bgm");
-               }
-
-        // world generation (for outdoor areas)
-        else if (name == "generation") {
-                       tmp->generate(wxml->UnsignedAttribute("width") / game::HLINE);
-               }
-
-               else if (name == "house") {
-                       if (Indoor)
-                               tmp->HouseWidth = wxml->FloatAttribute("width");
-                       else
-                               UserError("<house> can only be used with indoor worlds");
-               }
-
-               // weather tags
-               else if (name == "weather") {
-                       game::engine.getSystem<WorldSystem>()->setWeather(wxml->GetText());
-               }
-
                // set spawn x for player
                else if (name == "spawnx" && !(loadedLeft | loadedRight)) {
                        player->loc.x = std::stoi(wxml->GetText());
@@ -1009,11 +406,6 @@ loadWorldFromXMLNoSave(std::string path) {
                        tmp->addHill(ivec2 { wxml->IntAttribute("peakx"), wxml->IntAttribute("peaky") }, wxml->UnsignedAttribute("width"));
                }
 
-               // time setting
-               else if (name == "time" && !(loadedLeft | loadedRight)) {
-            game::time::setTickCount(std::stoi(wxml->GetText()));
-        }
-
                if (newEntity != nullptr) {
                        //bool alive = true;
                        //if (wxml->QueryBoolAttribute("alive", &alive) != XML_NO_ERROR || alive) {
@@ -1053,9 +445,7 @@ loadWorldFromXMLNoSave(std::string path) {
        while(vil) {
                name = vil->Name();
 
-               /**
-                *      READS DATA ABOUT STRUCTURE CONTAINED IN VILLAGE
-                */
+                //READS DATA ABOUT STRUCTURE CONTAINED IN VILLAGE
 
                if (name == "structure") {
                        s = new Structures();
@@ -1147,17 +537,7 @@ loadWorldFromXMLNoSave(std::string path) {
        }
 
        return tmp;
-}
-
-Village::Village(std::string meme, World *w)
-       : name(meme)
-{
-       start.x = w->getTheWidth() / 2.0f;
-       end.x = -start.x;
-       in = false;
-}
-
-
+}*/
 
 WorldSystem::WorldSystem(void)
        : weather(WorldWeather::None), bgmObj(nullptr) {}
@@ -1169,68 +549,6 @@ WorldSystem::~WorldSystem(void)
                Mix_FreeMusic(bgmObj);
 }
 
-void WorldSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
-{
-       (void)en;
-       (void)ev;
-       (void)dt;
-
-    // fade in music if not playing
-       if (bgmObj != nullptr && !Mix_PlayingMusic())
-               Mix_FadeInMusic(bgmObj, -1, 2000);
-
-    // update player coords
-       player->loc.y += player->vel.y * dt;
-       player->loc.x += (player->vel.x * player->speed) * dt;
-
-       // update entity coords
-       for (auto &e : world->entity) {
-        // dont let structures move?
-               if (e->type != STRUCTURET && e->canMove) {
-                       e->loc.x += e->vel.x * dt;
-            e->loc.y += e->vel.y * dt;
-
-            // update boolean directions
-            e->left = e->vel.x ? (e->vel.x < 0) : e->left;
-               } else if (e->vel.y < 0) {
-            e->loc.y += e->vel.y * dt;
-        }
-       }
-
-       partMutex.lock();
-       // iterate through particles
-    world->particles.remove_if([](const Particles &part) {
-               return part.duration <= 0;
-    });
-
-    for (auto &pa : world->particles) {
-               if (pa.canMove) { // causes overhead
-                       pa.loc.y += pa.vel.y * dt;
-                       pa.loc.x += pa.vel.x * dt;
-
-                       if (pa.stu != nullptr) {
-                               if (pa.loc.x >= pa.stu->loc.x && pa.loc.x <= pa.stu->loc.x + pa.stu->width &&
-                                   pa.loc.y <= pa.stu->loc.y + pa.stu->height * 0.25f)
-                                       pa.duration = 0;
-                       }
-               }
-       }
-    partMutex.unlock();
-
-       // add entities if need be
-       auto& entityPending = world->entityPending;
-
-       if (!entityPending.empty()) {
-               while (entityPending.size() > 0) {
-                       world->entity.push_back(entityPending.back());
-                       entityPending.pop_back();
-               }
-       }
-
-       // run detect stuff
-       detect(dt);
-}
-
 void WorldSystem::render(void)
 {
        const auto SCREEN_WIDTH = game::SCREEN_WIDTH;
@@ -1241,18 +559,32 @@ void WorldSystem::render(void)
         static_cast<int>(SCREEN_WIDTH) / 2, static_cast<int>(SCREEN_HEIGHT) / 2
     };
 
-       auto& worldData = currentWorld->worldData;
-       auto& star = currentWorld->star;
-       auto worldStart = currentWorld->worldStart;
-
        int iStart, iEnd, pOffset;
 
     // world width in pixels
-       int width = worldData.size() * HLINE;
+       int width = world.data.size() * HLINE;
 
     // used for alpha values of background textures
     int alpha;
 
+
+       static bool ambientUpdaterStarted = false;
+       if (!ambientUpdaterStarted) {
+               ambientUpdaterStarted = true;
+               std::thread([&](void) {
+                       while (true) {
+                               float v = 75 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
+                               float rg = std::clamp(.5f + (-v / 100.0f), 0.01f, .9f);
+                               float b  = std::clamp(.5f + (-v / 80.0f), 0.03f, .9f);
+
+                               ambient = Color(rg, rg, b, 1.0f);
+
+                               std::this_thread::sleep_for(std::chrono::milliseconds(1));
+                       }
+               }).detach();
+       }
+
+
        switch (weather) {
        case WorldWeather::Snowy:
                alpha = 150;
@@ -1348,7 +680,7 @@ void WorldSystem::render(void)
        makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, fron_tex_coord, tex_coord, 6);
 
        // TODO make stars dynamic
-       static GLuint starTex = Texture::loadTexture("assets/style/classic/bg/star.png");
+       /*static GLuint starTex = Texture::loadTexture("assets/style/classic/bg/star.png");
        const static float stardim = 24;
        GLfloat star_coord[star.size() * 5 * 6 + 1];
     GLfloat *si = &star_coord[0];
@@ -1374,7 +706,7 @@ void WorldSystem::render(void)
                glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.3 - static_cast<float>(alpha)/255.0f);
 
                makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(5 * sizeof(GLfloat), &star_coord[0], &star_coord[3], star.size() * 6);
-       }
+       }*/
 
        Render::worldShader.disable();
 
@@ -1389,7 +721,7 @@ void WorldSystem::render(void)
        bgTex++;
        dim2 mountainDim = bgTex.getTextureDim();
     auto xcoord = width / 2 * -1 + offset.x * 0.85f;
-       for (unsigned int i = 0; i <= worldData.size() * HLINE / mountainDim.x; i++) {
+       for (int i = 0; i <= width / mountainDim.x; i++) {
         bg_items.emplace_back(mountainDim.x * i       + xcoord, GROUND_HEIGHT_MINIMUM,                                  8.0f);
         bg_items.emplace_back(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM,                                  8.0f);
         bg_items.emplace_back(mountainDim.x * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + mountainDim.y, 8.0f);
@@ -1420,18 +752,20 @@ void WorldSystem::render(void)
                bg_items.clear();
                bg_tex.clear();
 
-               if (world->isIndoor() && i == 3) {
-                       glBindTexture(GL_TEXTURE_2D, world->houseTex);
+               if (world.indoor && i == 3) {
+                       glBindTexture(GL_TEXTURE_2D, world.indoorTex);
 
-                       bg_items.emplace_back(worldStart, GROUND_HEIGHT_MINIMUM, 7-(i*.1));
-               bg_items.emplace_back(worldStart + world->HouseWidth, GROUND_HEIGHT_MINIMUM,    7-(i*.1));
-               bg_items.emplace_back(worldStart + world->HouseWidth, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
+                       const auto& startx = world.startX;
 
-               bg_items.emplace_back(worldStart + world->HouseWidth, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
-               bg_items.emplace_back(worldStart, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
-               bg_items.emplace_back(worldStart, GROUND_HEIGHT_MINIMUM,        7-(i*.1));
+                       bg_items.emplace_back(startx, GROUND_HEIGHT_MINIMUM, 7-(i*.1));
+               bg_items.emplace_back(startx + world.indoorWidth, GROUND_HEIGHT_MINIMUM,        7-(i*.1));
+               bg_items.emplace_back(startx + world.indoorWidth, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
+
+               bg_items.emplace_back(startx + world.indoorWidth, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
+               bg_items.emplace_back(startx, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
+               bg_items.emplace_back(startx, GROUND_HEIGHT_MINIMUM,    7-(i*.1));
                } else {
-                       for (int j = worldStart; j <= -worldStart; j += dim.x) {
+                       for (int j = world.startX; j <= -world.startX; j += dim.x) {
                    bg_items.emplace_back(j         + xcoord, GROUND_HEIGHT_MINIMUM,            7-(i*.1));
                    bg_items.emplace_back(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM,            7-(i*.1));
                    bg_items.emplace_back(j + dim.x + xcoord, GROUND_HEIGHT_MINIMUM + dim.y, 7-(i*.1));
@@ -1462,38 +796,38 @@ void WorldSystem::render(void)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 
     // get the line that the player is currently standing on
-    pOffset = (offset.x + player->width / 2 - worldStart) / HLINE;
+    pOffset = 200;//(offset.x + player->width / 2 - worldStart) / HLINE;
 
     // only draw world within player vision
     iStart = std::clamp(static_cast<int>(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS),
-                           0, static_cast<int>(world->lineCount));
+                           0, static_cast<int>(world.data.size()));
        iEnd = std::clamp(static_cast<int>(pOffset + (SCREEN_WIDTH / 2 / HLINE)),
-                      0, static_cast<int>(world->lineCount));
+                      0, static_cast<int>(world.data.size()));
 
     // draw the dirt
     bgTex++;
     std::vector<std::pair<vec2,vec3>> c;
 
     for (int i = iStart; i < iEnd; i++) {
-        if (worldData[i].groundHeight <= 0) { // TODO holes (andy)
-            worldData[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
+        if (world.data[i].groundHeight <= 0) { // TODO holes (andy)
+            world.data[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
             glColor4ub(0, 0, 0, 255);
         } else {
             safeSetColorA(150, 150, 150, 255);
         }
 
-        int ty = worldData[i].groundHeight / 64 + worldData[i].groundColor;
+        int ty = world.data[i].groundHeight / 64 + world.data[i].groundColor;
 
-               c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + HLINES(i),         worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
-        c.push_back(std::make_pair(vec2(1, 0), vec3(worldStart + HLINES(i) + HLINE, worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
-        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + HLINES(i) + HLINE, 0,                                        -4.0f)));
+               c.push_back(std::make_pair(vec2(0, 0), vec3(world.startX + HLINES(i),         world.data[i].groundHeight - GRASS_HEIGHT, -4.0f)));
+        c.push_back(std::make_pair(vec2(1, 0), vec3(world.startX + HLINES(i) + HLINE, world.data[i].groundHeight - GRASS_HEIGHT, -4.0f)));
+        c.push_back(std::make_pair(vec2(1, ty),vec3(world.startX + HLINES(i) + HLINE, 0,                                         -4.0f)));
 
-        c.push_back(std::make_pair(vec2(1, ty),vec3(worldStart + HLINES(i) + HLINE, 0,                                        -4.0f)));
-        c.push_back(std::make_pair(vec2(0, ty),vec3(worldStart + HLINES(i),         0,                                        -4.0f)));
-        c.push_back(std::make_pair(vec2(0, 0), vec3(worldStart + HLINES(i),         worldData[i].groundHeight - GRASS_HEIGHT, -4.0f)));
+        c.push_back(std::make_pair(vec2(1, ty),vec3(world.startX + HLINES(i) + HLINE, 0,                                         -4.0f)));
+        c.push_back(std::make_pair(vec2(0, ty),vec3(world.startX + HLINES(i),         0,                                         -4.0f)));
+        c.push_back(std::make_pair(vec2(0, 0), vec3(world.startX + HLINES(i),         world.data[i].groundHeight - GRASS_HEIGHT, -4.0f)));
 
-        if (worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1)
-            worldData[i].groundHeight = 0;
+        if (world.data[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1)
+            world.data[i].groundHeight = 0;
     }
 
     std::vector<GLfloat> dirtc;
@@ -1520,7 +854,7 @@ void WorldSystem::render(void)
     Render::worldShader.disable();
        Render::worldShader.unuse();
 
-       if (!world->isIndoor()) {
+       if (!world.indoor) {
                bgTex++;
            safeSetColorA(255, 255, 255, 255);
 
@@ -1529,7 +863,7 @@ void WorldSystem::render(void)
            std::vector<GLfloat> grasst;
 
                for (int i = iStart; i < iEnd; i++) {
-               auto wd = worldData[i];
+               auto wd = world.data[i];
                auto gh = wd.grassHeight;
 
                        // flatten the grass if the player is standing on it.
@@ -1540,6 +874,8 @@ void WorldSystem::render(void)
 
                        // actually draw the grass.
                if (wd.groundHeight) {
+                               const auto& worldStart = world.startX;
+
                    c.push_back(std::make_pair(vec2(0, 0),vec3(worldStart + HLINES(i)            , wd.groundHeight + gh[0],             -3)));
                    c.push_back(std::make_pair(vec2(1, 0),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight + gh[0],             -3)));
                    c.push_back(std::make_pair(vec2(1, 1),vec3(worldStart + HLINES(i) + HLINE / 2, wd.groundHeight - GRASS_HEIGHT,      -3)));
@@ -1583,39 +919,24 @@ void WorldSystem::render(void)
                Render::worldShader.use();
                static const GLuint rug = Texture::genColor(Color {255, 0, 0});
                glBindTexture(GL_TEXTURE_2D, rug);
-               vec2 ll = vec2 {worldStart, GROUND_HEIGHT_MINIMUM};
-               Render::drawRect(ll, vec2 {ll.x + world->HouseWidth, ll.y + 4}, -3);
+               vec2 ll = vec2 {world.startX, GROUND_HEIGHT_MINIMUM};
+               Render::drawRect(ll, vec2 {ll.x + world.indoorWidth, ll.y + 4}, -3);
                Render::worldShader.unuse();
        }
 
-       player->draw();
+       //player->draw();
 }
 
-void WorldSystem::setWorld(World *w)
-{
-       world = w;
-
-       bgFiles.clear();
-
-       const auto& files = bgPaths[(int)w->bgType];
-
-       for (const auto& f : files)
-               bgFiles.push_back(w->styleFolder + f);
-
-       bgTex = TextureIterator(bgFiles);
-}
-
-
 void WorldSystem::receive(const BGMToggleEvent &bte)
 {
-       if (bte.world == nullptr || bgmObjFile != bte.file) {
+       if (bte.world == nullptr || world.bgm != bte.file) {
                Mix_FadeOutMusic(800);
 
                if (bgmObj != nullptr)
                        Mix_FreeMusic(bgmObj);
 
-               bgmObjFile = bte.file;
-               bgmObj = Mix_LoadMUS(bgmObjFile.c_str());
+               //worldBgmFile = bte.file;
+               bgmObj = Mix_LoadMUS(world.bgm.c_str());
                Mix_PlayMusic(bgmObj, -1);
        }
 }
@@ -1632,118 +953,21 @@ void WorldSystem::setWeather(const std::string &s)
        weather = WorldWeather::None;
 }
 
-void WorldSystem::enterWorld(World *w)
-{
-       if (w != nullptr) {
-               outside = world;
-               world = w;
-       }
-}
-
-void WorldSystem::leaveWorld(void)
-{
-       world = currentWorld = outside;
-} 
-
-void WorldSystem::singleDetect(Entity *e, entityx::TimeDelta dt)
+void WorldSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
 {
-       std::string killed;
-       unsigned int i;
-       int l;
-
-       auto& worldData = world->worldData;
-
-       if (e == nullptr || !(e->isAlive()))
-               return;
-
-       // kill dead entities
-       if (e->health <= 0) {
-        // die
-        e->die();
-               if (inBattle && e->type == MOBT)
-                       Mobp(e)->onDeath();
-
-        // delete the entity
-               for (i = 0; i < world->entity.size(); i++) {
-                       if (world->entity[i] == e) {
-                               switch (e->type) {
-                               case STRUCTURET:
-                                       killed = " structure";
-                    break;
-                case NPCT:
-                                       killed = "n NPC";
-                                       break;
-                               case MOBT:
-                                       killed = " mob";
-                                       break;
-                               case OBJECTT:
-                                       killed = "n object";
-                                       break;
-                               default:
-                                       break;
-                               }
-
-                               std::cout << "Killed a" << killed << "...\n";
-                               world->entity.erase(world->entity.begin() + i);
-                               return;
-                       }
-               }
-
-        // exit on player death
-               std::cout << "RIP " << e->name << ".\n";
-               exit(0);
-       }
-
-       // collision / gravity: handle only living entities
-       else {
-
-        // forced movement gravity (sword hits)
-        e->handleHits();
-
-               // calculate the line that this entity is currently standing on
-        l = std::clamp(static_cast<int>((e->loc.x + e->width / 2 - world->worldStart) / game::HLINE),
-                       0,
-                       static_cast<int>(world->lineCount));
-
-               // if the entity is under the world/line, pop it back to the surface
-               if (e->loc.y < worldData[l].groundHeight) {
-            int dir = e->vel.x < 0 ? -1 : 1;
-            if (l + (dir * 2) < static_cast<int>(worldData.size()) &&
-                worldData[l + (dir * 2)].groundHeight - 30 > worldData[l + dir].groundHeight) {
-                e->loc.x -= (PLAYER_SPEED_CONSTANT + 2.7f) * e->speed * 2 * dir;
-                e->vel.x = 0;
-            } else {
-                e->loc.y = worldData[l].groundHeight - 0.001f * dt;
-                       e->ground = true;
-                       e->vel.y = 0;
-            }
-
-               }
+       (void)en;
+       (void)ev;
+       (void)dt;
 
-        // handle gravity if the entity is above the line
-        else {
-                       if (e->type == STRUCTURET) {
-                               e->loc.y = worldData[l].groundHeight;
-                               e->vel.y = 0;
-                               e->ground = true;
-                               return;
-                       } else if (e->vel.y > -2) {
-                e->vel.y -= GRAVITY_CONSTANT * dt;
-            }
-               }
+    // fade in music if not playing
+       if (bgmObj != nullptr && !Mix_PlayingMusic())
+               Mix_FadeInMusic(bgmObj, -1, 2000);
 
-               // insure that the entity doesn't fall off either edge of the world.
-        if (e->loc.x < world->worldStart) {
-                       e->vel.x = 0;
-                       e->loc.x = world->worldStart + HLINES(0.5f);
-               } else if (e->loc.x + e->width + game::HLINE > -((int)world->worldStart)) {
-                       e->vel.x = 0;
-                       e->loc.x = -((int)world->worldStart) - e->width - game::HLINE;
-               }
-       }
+       // run detect stuff
+       detect(dt);
 }
 
-void WorldSystem::detect2(entityx::TimeDelta dt)
+void WorldSystem::detect(entityx::TimeDelta dt)
 {
        game::entities.each<Position, Direction, Health, Solid>(
            [&](entityx::Entity e, Position &loc, Direction &vel, Health &health, Solid &dim) {
@@ -1754,12 +978,12 @@ void WorldSystem::detect2(entityx::TimeDelta dt)
                        UserError("die mofo");
 
                // get the line the entity is on
-               int line = std::clamp(static_cast<int>((loc.x + dim.width / 2 - world->worldStart) / game::HLINE),
+               int line = std::clamp(static_cast<int>((loc.x + dim.width / 2 - world.startX) / game::HLINE),
                                      0,
-                                     static_cast<int>(world->lineCount));
+                                     static_cast<int>(world.data.size()));
 
                // make sure entity is above ground
-               auto& data = world->worldData;
+               const auto& data = world.data;
                if (loc.y < data[line].groundHeight) {
                        int dir = vel.x < 0 ? -1 : 1;
                        if (line + dir * 2 < static_cast<int>(data.size()) &&
@@ -1779,90 +1003,14 @@ void WorldSystem::detect2(entityx::TimeDelta dt)
                }
 
                // insure that the entity doesn't fall off either edge of the world.
-        if (loc.x < world->worldStart) {
+        if (loc.x < world.startX) {
                        vel.x = 0;
-                       loc.x = world->worldStart + HLINES(0.5f);
-               } else if (loc.x + dim.width + game::HLINE > -((int)world->worldStart)) {
+                       loc.x = world.startX + HLINES(0.5f);
+               } else if (loc.x + dim.width + game::HLINE > -((int)world.startX)) {
                        vel.x = 0;
-                       loc.x = -((int)world->worldStart) - dim.width - game::HLINE;
+                       loc.x = -((int)world.startX) - dim.width - game::HLINE;
                }
        });
 }
 
-void WorldSystem::detect(entityx::TimeDelta dt)
-{
-       int l;
-
-       // handle the player
-    singleDetect(player, dt);
-
-    // handle other entities
-       for (auto &e : world->entity)
-               singleDetect(e, dt);
-
-       partMutex.lock();
-    // handle particles
-       for (auto &part : world->particles) {
-               // get particle's current world line
-               l = std::clamp(static_cast<int>((part.loc.x + part.width / 2 - world->worldStart) / game::HLINE),
-                       0,
-                       static_cast<int>(world->lineCount - 1));
-               part.update(GRAVITY_CONSTANT, world->worldData[l].groundHeight);
-       }
-
-       // handle particle creation
-       for (auto &e : world->entity) {
-               if (e->type == STRUCTURET) {
-                       auto b = dynamic_cast<Structures *>(e);
-                       switch (b->bsubtype) {
-                       case FOUNTAIN:
-                               for (unsigned int r = (randGet() % 25) + 11; r--;) {
-                                       world->addParticle(randGet() % HLINES(3) + b->loc.x + b->width / 2,     // x
-                                                               b->loc.y + b->height,                                                           // y
-                                                               HLINES(1.25),                                                                           // width
-                                                               HLINES(1.25),                                                                           // height
-                                                               randGet() % 7 * .01 * (randGet() % 2 == 0 ? -1 : 1),    // vel.x
-                                                               randGet() % 1 ? (8 + randGet() % 6) * .05 : (4 + randGet() % 6) * .05,// vel.y
-                                                               { 0, 0, 255 },                                                                          // RGB color
-                                                               2500                                                                                            // duration (ms)
-                                                               );
-                                       world->particles.back().fountain = true;
-                                       world->particles.back().stu = b;
-                               }
-                               break;
-                       case FIRE_PIT:
-                               for(unsigned int r = (randGet() % 20) + 11; r--;) {
-                                       world->addParticle(randGet() % (int)(b->width / 2) + b->loc.x + b->width / 4,   // x
-                                                               b->loc.y + HLINES(3),                                                                           // y
-                                                               game::HLINE,                                                                                            // width
-                                                               game::HLINE,                                                                                            // height
-                                                               randGet() % 3 * .01 * (randGet() % 2 == 0 ? -1 : 1),            // vel.x
-                                                               (4 + randGet() % 6) * .005,                                                                     // vel.y
-                                                               { 255, 0, 0 },                                                                                          // RGB color
-                                                               400                                                                                                                     // duration (ms)
-                                                               );
-                                       world->particles.back().gravity = false;
-                                       world->particles.back().behind  = true;
-                                       world->particles.back().stu = b;
-                               }
-                               break;
-                       default:
-                               break;
-                       }
-               }
-       }
-       partMutex.unlock();
-
-       // draws the village welcome message if the player enters the village bounds
-       for (auto &v : world->village) {
-               if (player->loc.x > v.start.x && player->loc.x < v.end.x) {
-            if (!v.in) {
-                           ui::passiveImportantText(5000, "Welcome to %s", v.name.c_str());
-                           v.in = true;
-                   }
-        } else {
-            v.in = false;
-        }
-       }
-}
 
index 2d110e87ce41cc712ab15c32103c3aa8450cb094..bfaa6a9c358b9b0f6496b4544e693e70352cc6a9 100644 (file)
@@ -4,11 +4,11 @@
     <generation width="1600"/>
     <time>6000</time>
     <spawnx>-300</spawnx>
-    <npc name="Sanc" hasDialog="true" health="1" x="-324.26083" y="70.398842" dindex="9999"/>
-    <npc name="Bob" hasDialog="true" spawnx="30" health="1" x="151.69295" y="71.5989" dindex="0"/>
-    <structure type="1" spawnx="300" alive="1"/>
-    <structure inside="bobshouse.xml" insideTexture="assets/style/classic/bg/insideWoodHouse.png" type="1" spawnx="10" alive="1"/>
-    <chest alive="1"/>
+    <npc name="Sanc" hasDialog="true"/>
+    <npc name="Bob" hasDialog="true" spawnx="30"/>
+    <structure type="1" spawnx="300"/>
+    <structure inside="bobshouse.xml" insideTexture="assets/style/classic/bg/insideWoodHouse.png" type="1" spawnx="10"/>
+    <chest/>
 </World>
 
 <Dialog name="Bob">
index f13d5ffb5f94c50eeffce9e738142f623d54ab0d..a1d4e7cc68450537c61170c04a9eeebdea739681 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <IndoorWorld>
     <style background="0" bgm="assets/music/theme_jazz.wav" folder="assets/style/classic/"/>
-       <house width="800" />
-       <generation width="1600" />     
+    <house width="800"/>
+    <generation width="1600"/>
     <link outside="town.xml"/>
     <npc name="Bob" hasDialog="false" spawnx="30"/>
 </IndoorWorld>