From cb408a63a0f03ccb0b0ce7c338527a3b4964aff9 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 20 Oct 2016 08:44:58 -0400 Subject: [PATCH] removed all old entity stuff --- include/{entities.hpp => entities.hpp.bak} | 0 include/{inventory.hpp => inventory.hpp.bak} | 0 include/{mob.hpp => mob.hpp.bak} | 0 include/{quest.hpp => quest.hpp.bak} | 0 include/ui.hpp | 8 +- include/{ui_action.hpp => ui_action.hpp.bak} | 0 include/ui_quest.hpp | 4 +- include/world.hpp | 390 +----- main.cpp | 121 +- src/engine.cpp | 11 +- src/{entities.cpp => entities.cpp.bak} | 0 src/{inventory.cpp => inventory.cpp.bak} | 1 - src/{items.cpp => items.cpp.bak} | 0 src/{mob.cpp => mob.cpp.bak} | 0 src/{quest.cpp => quest.cpp.bak} | 17 +- src/ui.cpp | 303 +---- src/{ui_action.cpp => ui_action.cpp.bak} | 0 src/ui_menu.cpp | 1 + src/world.cpp | 1244 +++--------------- xml/!town.xml | 10 +- xml/bobshouse.xml | 4 +- 21 files changed, 330 insertions(+), 1784 deletions(-) rename include/{entities.hpp => entities.hpp.bak} (100%) rename include/{inventory.hpp => inventory.hpp.bak} (100%) rename include/{mob.hpp => mob.hpp.bak} (100%) rename include/{quest.hpp => quest.hpp.bak} (100%) rename include/{ui_action.hpp => ui_action.hpp.bak} (100%) rename src/{entities.cpp => entities.cpp.bak} (100%) rename src/{inventory.cpp => inventory.cpp.bak} (99%) rename src/{items.cpp => items.cpp.bak} (100%) rename src/{mob.cpp => mob.cpp.bak} (100%) rename src/{quest.cpp => quest.cpp.bak} (76%) rename src/{ui_action.cpp => ui_action.cpp.bak} (100%) diff --git a/include/entities.hpp b/include/entities.hpp.bak similarity index 100% rename from include/entities.hpp rename to include/entities.hpp.bak diff --git a/include/inventory.hpp b/include/inventory.hpp.bak similarity index 100% rename from include/inventory.hpp rename to include/inventory.hpp.bak diff --git a/include/mob.hpp b/include/mob.hpp.bak similarity index 100% rename from include/mob.hpp rename to include/mob.hpp.bak diff --git a/include/quest.hpp b/include/quest.hpp.bak similarity index 100% rename from include/quest.hpp rename to include/quest.hpp.bak diff --git a/include/ui.hpp b/include/ui.hpp index 8671393..c7a69b6 100644 --- a/include/ui.hpp +++ b/include/ui.hpp @@ -21,10 +21,9 @@ // local game headers #include #include -#include -#include +//#include #include -#include +//#include // local library headers #include @@ -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.bak similarity index 100% rename from include/ui_action.hpp rename to include/ui_action.hpp.bak diff --git a/include/ui_quest.hpp b/include/ui_quest.hpp index 24a5e1b..8582b67 100644 --- a/include/ui_quest.hpp +++ b/include/ui_quest.hpp @@ -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); } diff --git a/include/world.hpp b/include/world.hpp index dc07267..36ccdfa 100644 --- a/include/world.hpp +++ b/include/world.hpp @@ -8,9 +8,13 @@ // local game includes #include -#include #include +#include +#include +#include +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; - /** * 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 constexpr const char* WorldWeatherString[3] = { @@ -138,20 +100,45 @@ constexpr const char* WorldWeatherString[3] = { "Snowy" }; +struct WorldData2 { + // data + std::vector data; + float startX; + + // indoor + bool indoor; + float indoorWidth; + GLuint indoorTex; + + // links + std::string toLeft, toRight; + + // style + WorldBGType style; + std::string styleFolder; + std::vector sTexLoc; + + // music + std::string bgm; + + // village + float villageStart, villageEnd; +}; + class WorldSystem : public entityx::System, public entityx::Receiver { private: - World *world; - World *outside; + WorldData2 world; WorldWeather weather; Mix_Music *bgmObj; - std::string bgmObjFile; std::vector bgFiles; TextureIterator bgTex; + XMLDocument xmlDoc; + public: explicit WorldSystem(void); ~WorldSystem(void); @@ -160,13 +147,14 @@ public: ev.subscribe(*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(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; - - /** - * 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 sTexLoc; - - /** - * Contains randomly generated coordinates for stars. - */ - std::vector star; - - /** - * A vector of all light elements in the world. - * - * @see addLight() - * @see getLastLight() - */ - std::vector light; - - /** - * A vector of all villages in the world. - * - * @see addVillage() - */ - std::vector village; - - std::vector 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; - - /** - * 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; - - /** - * 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 diff --git a/main.cpp b/main.cpp index 91a2759..9fa7a55 100644 --- a/main.cpp +++ b/main.cpp @@ -21,7 +21,7 @@ using namespace tinyxml2; // local game includes #include #include -#include +//#include #include #include #include @@ -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()->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()->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(currentWorld->bgm); - - game::engine.getSystem()->setWorld(currentWorld); - - // spawn the arena - arena = new Arena(); - arena->setStyle(""); - arena->setBackground(WorldBGType::Forest); - arena->bgm = "assets/music/embark.wav"; +// game::events.emit(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()->die(); return 0; // Calls everything passed to atexit } -extern std::vector 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()->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()->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()->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()->getWeatherId(); + /*auto weather = game::engine.getSystem()->getWeatherId(); + auto worldWidth = game::engine.getSystem()->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; } diff --git a/src/engine.cpp b/src/engine.cpp index 56dee48..3d498d3 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -3,8 +3,7 @@ #include #include #include -#include -#include +//#include #include extern World *currentWorld; @@ -20,9 +19,9 @@ void Engine::init(void) { systems.add(); systems.add(); - systems.add(); +// systems.add(); systems.add(); - systems.add(&player); +// systems.add(&player); systems.configure(); @@ -37,8 +36,8 @@ void Engine::render(entityx::TimeDelta dt) void Engine::update(entityx::TimeDelta dt) { systems.update(dt); - systems.update(dt); - systems.update(dt); +// systems.update(dt); +// systems.update(dt); systems.update(dt); } diff --git a/src/entities.cpp b/src/entities.cpp.bak similarity index 100% rename from src/entities.cpp rename to src/entities.cpp.bak diff --git a/src/inventory.cpp b/src/inventory.cpp.bak similarity index 99% rename from src/inventory.cpp rename to src/inventory.cpp.bak index f7a8df7..1b325c0 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp.bak @@ -2,7 +2,6 @@ #include -#include #include #include diff --git a/src/items.cpp b/src/items.cpp.bak similarity index 100% rename from src/items.cpp rename to src/items.cpp.bak diff --git a/src/mob.cpp b/src/mob.cpp.bak similarity index 100% rename from src/mob.cpp rename to src/mob.cpp.bak diff --git a/src/quest.cpp b/src/quest.cpp.bak similarity index 76% rename from src/quest.cpp rename to src/quest.cpp.bak index aa0bb2e..f19359e 100644 --- a/src/quest.cpp +++ b/src/quest.cpp.bak @@ -1,9 +1,6 @@ #include #include -#include - -extern Player *player; int QuestHandler::assign(std::string title,std::string desc,std::string req) { Quest tmp; @@ -43,15 +40,15 @@ int QuestHandler::drop(std::string title) { int QuestHandler::finish(std::string t) { for (auto c = current.begin(); c != current.end(); c++) { if ((*c).title == t) { - for (auto &n : (*c).need) { - if (player->inv->hasItem(n.first) < n.second) + //for (auto &n : (*c).need) { + //if (player->inv->hasItem(n.first) < n.second) return 0; - } + //} - for (auto &n : (*c).need) - player->inv->takeItem(n.first, n.second); - current.erase(c); - return 1; + //for (auto &n : (*c).need) + //player->inv->takeItem(n.first, n.second); + //current.erase(c); + //return 1; } } diff --git a/src/ui.cpp b/src/ui.cpp index aed2f48..85b2d2b 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -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 controlMap = { SDLK_w, SDLK_a, SDLK_d, SDLK_LSHIFT, SDLK_LCTRL, SDLK_e }; @@ -79,7 +64,6 @@ static std::vector> textToDraw; static std::vector> dialogOptText; static std::string dialogBoxText; -static std::vector 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 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(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(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.bak similarity index 100% rename from src/ui_action.cpp rename to src/ui_action.cpp.bak diff --git a/src/ui_menu.cpp b/src/ui_menu.cpp index 4b4b05c..cbe7718 100644 --- a/src/ui_menu.cpp +++ b/src/ui_menu.cpp @@ -2,6 +2,7 @@ #include #include +#include #include diff --git a/src/world.cpp b/src/world.cpp index ef9969f..2772160 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -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 arenaNest; - // pathnames of images for world themes using StyleList = std::array; @@ -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 -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 (width + GROUND_HILLINESS, WorldData { false, {0, 0}, 0, 0 }); - lineCount = worldData.size(); + world.data = std::vector (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(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 (100, vec2 { 0, 400 }); - for (auto &s : star) { - s.x = (randGet() % (static_cast(-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(pOffset + 6) && i > static_cast(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 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(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(*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(*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(*d)->inside.empty()) - return std::make_pair(this, vec2 {0, 0}); - - outdoorData = currentXMLRaw; - outdoorName = currentXML; - currentXML = xmlFolder + dynamic_cast(*d)->inside; - const char *buf = readFile(currentXML.c_str()); - currentXMLRaw = buf; - delete[] buf; - - tmp = dynamic_cast(*d)->insideWorld; - tmp->houseTex = dynamic_cast(*d)->insideTex; - - return std::make_pair(tmp, vec2 {0, 100}); - } - - // exit the building - else { - std::string current = ¤tXML[xmlFolder.size()]; - currentXML = outdoorName; - currentXMLRaw = outdoorData; - outdoorName.clear(); - outdoorData.clear(); - - /*tmp = dynamic_cast(currentWorld)->outside; //loadWorldFromXML(inside.back()); - - Structures *b = nullptr; - for (auto &s : tmp->entity) { - if (s->type == STRUCTURET && dynamic_cast(s)->inside == current) { - b = dynamic_cast(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(*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(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 or 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