From 76a8dfce1c91c8536c940b53883eaf0ed7bd769a Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 11 Jan 2017 10:50:19 -0500 Subject: more windows stuff --- main.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp index a9ccac8..66b729a 100644 --- a/main.cpp +++ b/main.cpp @@ -108,7 +108,7 @@ int main(int argc, char *argv[]) SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // enable v-sync (TODO but 1000 fps?) - SDL_GL_SetSwapInterval(1); + SDL_GL_SetSwapInterval(0); // hide the cursor SDL_ShowCursor(SDL_DISABLE); // switch to pixel grid @@ -196,7 +196,7 @@ int main(int argc, char *argv[]) worldShade = 50 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI)); // update fades - ui::fadeUpdate(); + //ui::fadeUpdate(); // increment game ticker game::time::tick(); @@ -207,7 +207,7 @@ int main(int argc, char *argv[]) std::this_thread::sleep_for(1ms); } }); - + static float fpsInternal = 0; // the debug loop, gets debug screen values @@ -219,12 +219,16 @@ int main(int argc, char *argv[]) } }); - // thre render loop, renders + // the render loop, renders const bool &run = game::engine.shouldRun; while (run) { fpsInternal++; render(); game::engine.resetRender(0); // TODO stupid + + SDL_Event e; + while (SDL_PollEvent(&e)) + game::events.emit(e); } // on game end, get back together -- cgit v1.2.3 From b018bfd5d69a51b352cc87cf92136a0b20712845 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 11 Jan 2017 21:20:57 -0500 Subject: who knows --- include/common.hpp | 23 +++------------- include/components.hpp | 11 ++++++++ main.cpp | 5 +--- src/common.cpp | 71 +++++++++++++++++++++----------------------------- src/components.cpp | 62 +++++++++++++++++++++++++++++++++++++++++-- src/world.cpp | 6 ++--- 6 files changed, 108 insertions(+), 70 deletions(-) (limited to 'main.cpp') diff --git a/include/common.hpp b/include/common.hpp index 1178540..12231dc 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -54,8 +54,6 @@ using uint = unsigned int; */ #define DEBUG_printf(message, ...) DEBUG_prints(__FILE__, __LINE__, message, __VA_ARGS__) -#define BREAKPOINT __asm__("int $3") - #define coalesce(v1, v2) ((v1 != nullptr) ? v1 : v2) /** @@ -193,12 +191,12 @@ public: /** * The amount of game ticks that should occur each second. */ -constexpr const unsigned int TICKS_PER_SEC = 20; +constexpr unsigned int TICKS_PER_SEC = 20; /** * The amount of milliseconds it takes for a game tick to fire. */ -constexpr const float MSEC_PER_TICK = 1000.0f / TICKS_PER_SEC; +constexpr float MSEC_PER_TICK = 1000.0f / TICKS_PER_SEC; /** * Separates a string into tokens using the given delimiter. @@ -217,16 +215,6 @@ std::vector StringTokenizer(const std::string& str, char delim); */ vec2 str2coord(std::string s); -/** - * A function to draw a colored box for OpenGL. - * To use it, the lower left hand and upper right hand coords are given. - * - * @param the lower left coordinate - * @param the upper right coordinate - * @param the z coordinate - */ -void drawRect(vec2 ll, vec2 ur, float z); - /** * Returns a measurement in HLINEs * @@ -252,7 +240,7 @@ inline T HLINES(const T &n) #define randGet rand // defines pi for calculations that need it. -constexpr const float PI = 3.1415926535f; +constexpr float PI = 3.1415926535f; // references the variable in main.cpp, used for drawing with the player extern vec2 offset; @@ -266,10 +254,7 @@ void DEBUG_prints(const char* file, int line, const char *s,...); unsigned int millis(void); // reads the names of files in a directory into the given string vector -int getdir(std::string dir, std::vector &files); - -// sorts a vector of strings alphabetically -void strVectorSortAlpha(std::vector *v); +int getdir(std::string dir, std::list& files); // reads the given file into a buffer and returns a pointer to the buffer std::string readFile(const std::string& path); diff --git a/include/components.hpp b/include/components.hpp index 805e8b2..00ac8fa 100644 --- a/include/components.hpp +++ b/include/components.hpp @@ -335,9 +335,20 @@ class RenderSystem : public entityx::System { private: std::string loadTexString; Texture loadTexResult; + + float fadeIntensity; + bool fadeIn; public: + RenderSystem(void) + : fadeIntensity(1), fadeIn(true) {} + Texture loadTexture(const std::string& file); void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override; + + void fade(void); + void fadeLock(void); + void unfade(void); + void unfadeLock(void); }; class DialogSystem : public entityx::System, public entityx::Receiver { diff --git a/main.cpp b/main.cpp index 66b729a..712c44a 100644 --- a/main.cpp +++ b/main.cpp @@ -142,13 +142,10 @@ int main(int argc, char *argv[]) xmlFolder = "xml/"; // read in all XML file names in the folder - std::vector xmlFiles; + std::list xmlFiles; if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles)) UserError("Error reading XML files!!!"); - // alphabetically sort files - strVectorSortAlpha(&xmlFiles); - // kill the world if needed if (worldReset) { // TODO TODO TODO we do xml/*.dat now... diff --git a/src/common.cpp b/src/common.cpp index 6539a05..2ec80a7 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -18,8 +18,10 @@ #endif // __WIN32__ unsigned int millis(void) { - std::chrono::system_clock::time_point now=std::chrono::system_clock::now(); - return std::chrono::duration_cast(now.time_since_epoch()).count(); + using namespace std::chrono; + + auto now = system_clock::now(); + return duration_cast(now.time_since_epoch()).count(); } @@ -37,7 +39,7 @@ std::vector StringTokenizer(const std::string& str, char delim) std::string token; while (getline(is, token, delim)) - tokens.push_back(token); + tokens.emplace_back(token); return tokens; } @@ -51,56 +53,41 @@ void DEBUG_prints(const char* file, int line, const char *s,...) va_end(args); } -int getdir(std::string dir, std::vector &files) +int getdir(std::string dir, std::list& files) { #ifndef __WIN32__ - DIR *dp; - struct dirent *dirp; - if (!(dp = opendir(dir.c_str()))) { - std::cout <<"Error ("<d_name)); - closedir(dp); -#else - HANDLE dirh; - WIN32_FIND_DATA file_data; + auto dp = opendir(dir.c_str()); + if (dp == nullptr) + UserError("Couldn\'t open folder: " + dir); - if ((dirh = FindFirstFile((dir + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE) - return -1; /* No files found */ + auto dirp = readdir(dp); + while (dirp != nullptr) { + files.emplace_back(dirp->d_name); + dirp = readdir(dp); + } - do { - const std::string file_name = file_data.cFileName; - const std::string full_file_name = dir + file_name; - const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + closedir(dp); +#else + WIN32_FIND_DATA fileData; + auto dirh = FindFirstFile((dir + "/*").c_str(), &fileData); + if (dirh == INVALID_HANDLE_VALUE) + UserError("Couldn\'t open folder: " + dir); - if (file_name[0] == '.') - continue; + do { + auto fileName = fileData.cFileName; - if (is_directory) - continue; + if (fileName[0] == '.') + continue; - files.push_back(file_name); - } while (FindNextFile(dirh, &file_data)); + if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + files.emplace_back(fileName); + } while (FindNextFile(dirh, &fileData)); FindClose(dirh); #endif // __WIN32__ - return 0; -} -void strVectorSortAlpha(std::vector *v) -{ - static bool change; - do { - change = false; - for (unsigned int i=0; i < v->size() - 1; i++) { - if (v[0][i] > v[0][i + 1]) { - std::swap(v[0][i], v[0][i + 1]); - change = true; - } - } - } while (change); + files.sort(); + return 0; } std::string readFile(const std::string& path) diff --git a/src/components.cpp b/src/components.cpp index a7d504d..4d80d25 100644 --- a/src/components.cpp +++ b/src/components.cpp @@ -12,6 +12,8 @@ #include +using namespace std::literals::chrono_literals; + static std::vector randomDialog (readFileA("assets/dialog_en-us")); void MovementSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) @@ -66,10 +68,34 @@ Texture RenderSystem::loadTexture(const std::string& file) loadTexString = file; loadTexResult = Texture(); while (loadTexResult.isEmpty()) - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); return loadTexResult; } +void RenderSystem::fade(void) +{ + fadeIn = false, fadeIntensity = 0; +} + +void RenderSystem::fadeLock(void) +{ + fade(); + while (fadeIntensity < 1) + std::this_thread::sleep_for(1ms); +} + +void RenderSystem::unfade(void) +{ + fadeIn = true, fadeIntensity = 1; +} + +void RenderSystem::unfadeLock(void) +{ + fade(); + while (fadeIntensity > 0) + std::this_thread::sleep_for(1ms); +} + void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) { (void)ev; @@ -79,7 +105,14 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, loadTexString.clear(); } + // update fade system + if (fadeIn && fadeIntensity > 0) + fadeIntensity -= 0.01f; + else if(!fadeIn && fadeIntensity < 1) + fadeIntensity += 0.01f; + Render::worldShader.use(); + Render::worldShader.enable(); en.each([dt](entityx::Entity entity, Visible &visible, Sprite &sprite, Position &pos) { // Verticies and shit @@ -131,7 +164,6 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, sp.tex.use(); glUniform1i(Render::worldShader.uniform[WU_texture], 0); - Render::worldShader.enable(); glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords); glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0 ,tex_coord); @@ -153,6 +185,32 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, ui::setFontZ(-5.0); ui::putStringCentered(pos.x + dim.width / 2, pos.y - ui::fontSize - HLINES(0.5), name.name); }); + + // draw fade + static const GLfloat tex[8] = { + 0, 0, 0, 0, 0, 0, 0, 0 + }; + + auto SCREEN_WIDTH2 = game::SCREEN_WIDTH / 2, SCREEN_HEIGHT2 = game::SCREEN_HEIGHT / 2; + GLfloat coord[12] = { + offset.x - SCREEN_WIDTH2 - 1, offset.y - SCREEN_HEIGHT2, -7.9, + offset.x + SCREEN_WIDTH2, offset.y - SCREEN_HEIGHT2, -7.9, + offset.x - SCREEN_WIDTH2 - 1, offset.y + SCREEN_HEIGHT2, -7.9, + offset.x + SCREEN_WIDTH2, offset.y + SCREEN_HEIGHT2, -7.9 + }; + + Render::textShader.use(); + Render::textShader.enable(); + + Colors::black.use(); + glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0f, 1.0f, 1.0f, fadeIntensity); + glUniform1i(Render::textShader.uniform[WU_texture], 0); + glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coord); + glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex); + glDrawArrays(GL_QUADS, 0, 4); + + Render::textShader.disable(); + Render::textShader.unuse(); } void DialogSystem::configure(entityx::EventManager &ev) diff --git a/src/world.cpp b/src/world.cpp index a1d2f3c..a80fba8 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1178,13 +1178,13 @@ void WorldSystem::detect(entityx::TimeDelta dt) void WorldSystem::goWorldRight(Position& p, Solid &d) { if (!(world.toRight.empty()) && (p.x + d.width > world.startX * -1 - HLINES(5))) { - ui::toggleBlack(); - ui::waitForCover(); + auto& rs = *game::engine.getSystem(); + rs.fadeLock(); while (waitToSwap) std::this_thread::sleep_for(1ms); load(world.toRight); game::engine.getSystem()->setX(world.startX + HLINES(10)); - ui::toggleBlack(); + rs.unfade(); } } -- cgit v1.2.3 From 620311fb15953984c2fe37917d678f9b3aaa00b6 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 12 Jan 2017 09:27:43 -0500 Subject: fixes, main cleanup --- include/common.hpp | 1 - include/components.hpp | 14 +--- include/engine.hpp | 7 -- include/render.hpp | 3 + include/window.hpp | 4 +- main.cpp | 212 +++++-------------------------------------------- src/components.cpp | 66 ++------------- src/engine.cpp | 13 +-- src/render.cpp | 124 +++++++++++++++++++++++++++++ src/ui.cpp | 47 ++++++----- src/window.cpp | 6 +- src/world.cpp | 10 ++- 12 files changed, 196 insertions(+), 311 deletions(-) (limited to 'main.cpp') diff --git a/include/common.hpp b/include/common.hpp index 12231dc..abfd28b 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -14,7 +14,6 @@ #include #include #include -#include // alternative windows thread library #ifndef __WIN32__ diff --git a/include/components.hpp b/include/components.hpp index 00ac8fa..2ec7a28 100644 --- a/include/components.hpp +++ b/include/components.hpp @@ -336,19 +336,11 @@ private: std::string loadTexString; Texture loadTexResult; - float fadeIntensity; - bool fadeIn; public: - RenderSystem(void) - : fadeIntensity(1), fadeIn(true) {} - Texture loadTexture(const std::string& file); - void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override; - - void fade(void); - void fadeLock(void); - void unfade(void); - void unfadeLock(void); + void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override + { (void)en; (void)ev; (void)dt; } + void render(void); }; class DialogSystem : public entityx::System, public entityx::Receiver { diff --git a/include/engine.hpp b/include/engine.hpp index a331e50..417522d 100644 --- a/include/engine.hpp +++ b/include/engine.hpp @@ -39,13 +39,6 @@ public: */ void init(void); - /** - * Updates all rendering systems. - * @param dt the delta time - */ - void render(entityx::TimeDelta dt); - void resetRender(entityx::TimeDelta dt); - /** * Updates all logic systems. * @param dt the delta time diff --git a/include/render.hpp b/include/render.hpp index 0a2adcd..cf58519 100644 --- a/include/render.hpp +++ b/include/render.hpp @@ -74,6 +74,9 @@ namespace Render { void useShader(Shader *s); void drawRect(vec2 ll, vec2 ur, float z); + + void init(void); + void render(const int& fps); } #endif // RENDER_HPP_ diff --git a/include/window.hpp b/include/window.hpp index 5cf05ea..d53a2bf 100644 --- a/include/window.hpp +++ b/include/window.hpp @@ -36,7 +36,9 @@ public: void die(void); void configure(entityx::EventManager &ev); - void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override; + void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override + { (void)en; (void)ev; (void)dt; } + void render(void); void receive(const WindowResizeEvent&); void receive(const ScreenshotEvent&); }; diff --git a/main.cpp b/main.cpp index 712c44a..40a8497 100644 --- a/main.cpp +++ b/main.cpp @@ -4,15 +4,11 @@ */ // standard library includes -#include -#include #include using namespace std::literals::chrono_literals; // local library includes #include -#include -using namespace tinyxml2; // our own includes #include @@ -20,17 +16,15 @@ using namespace tinyxml2; #include #include #include -#include #include #include #include #include -#include /** * The currently used folder to look for XML files in. */ -std::string xmlFolder; +std::string xmlFolder = "xml/"; /** * The current menu, if any are open (TODO why is this here) @@ -42,13 +36,6 @@ Menu *currentMenu; */ vec2 offset; -/** - * The current FPS of the game. - */ -static unsigned int fps = 0; - -void render(void); - /** * The main program. * Init, load, run. Die. @@ -58,10 +45,7 @@ int main(int argc, char *argv[]) static bool worldReset = false, worldDontReallyRun = false; std::string worldActuallyUseThisXMLFile; - // - // get command line arguments, if any - // - + // handle command line args if (argc > 1) { for (int i = 1; i < argc; i++) { std::string s = argv[i]; @@ -80,67 +64,17 @@ int main(int argc, char *argv[]) // game::engine.init(); - // used three times below - auto worldSys = game::engine.getSystem(); - - // - // initialize GLEW - // - -#ifndef __WIN32__ - glewExperimental = GL_TRUE; -#endif - auto glewError = glewInit(); - if (glewError != GLEW_OK) - UserError(std::string("GLEW was not able to initialize! Error: ") - + reinterpret_cast(glewGetErrorString(glewError))); - - // - // start the random number generator (TODO our own?) - // + // initialize the renderer + Render::init(); + // start the random number generator randInit(millis()); - // - // some basic OpenGL setup stuff - // - - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - // enable v-sync (TODO but 1000 fps?) - SDL_GL_SetSwapInterval(0); - // hide the cursor - SDL_ShowCursor(SDL_DISABLE); - // switch to pixel grid - glViewport(0, 0, game::SCREEN_WIDTH, game::SCREEN_HEIGHT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glClearColor(1, 1, 1, 1); - - // - // initialize shaders - // - - std::cout << "Initializing shaders!\n"; - Render::initShaders(); - Colors::init(); - - // - // load some saved data - // - + // load saved data game::briceLoad(); game::briceUpdate(); - // load sprites used in the inventory menu. See src/inventory.cpp - //initInventorySprites(); - - // get a world - // - - if (xmlFolder.empty()) - xmlFolder = "xml/"; - // read in all XML file names in the folder std::list xmlFiles; if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles)) @@ -148,11 +82,12 @@ int main(int argc, char *argv[]) // kill the world if needed if (worldReset) { - // TODO TODO TODO we do xml/*.dat now... + // TODO TODO TODO we do xml/*.dat now... kill that game::briceClear(); } // either load the given XML, or find one + auto worldSys = game::engine.getSystem(); if (!worldActuallyUseThisXMLFile.empty()) { worldSys->load(worldActuallyUseThisXMLFile); } else { @@ -167,19 +102,14 @@ int main(int argc, char *argv[]) } } - // - // initialize ui - // - - ui::menu::init(); - - ///////////////////////////// // // // actually start the game // // // ///////////////////////////// + std::list eventQueue; + if (!worldDontReallyRun) { // the main loop, in all of its gloriousness... std::thread thMain ([&] { @@ -193,19 +123,24 @@ int main(int argc, char *argv[]) worldShade = 50 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI)); // update fades - //ui::fadeUpdate(); + ui::fadeUpdate(); // increment game ticker game::time::tick(); } + while (!eventQueue.empty()) { + game::events.emit(eventQueue.back()); + eventQueue.pop_back(); + } + game::engine.update(game::time::getDeltaTime()); std::this_thread::sleep_for(1ms); } }); - static float fpsInternal = 0; + static int fps = 0, fpsInternal = 0; // the debug loop, gets debug screen values std::thread thDebug ([&] { @@ -220,12 +155,11 @@ int main(int argc, char *argv[]) const bool &run = game::engine.shouldRun; while (run) { fpsInternal++; - render(); - game::engine.resetRender(0); // TODO stupid + Render::render(fps); SDL_Event e; while (SDL_PollEvent(&e)) - game::events.emit(e); + eventQueue.push_back(e); } // on game end, get back together @@ -234,17 +168,11 @@ int main(int argc, char *argv[]) //game::engine.getSystem()->thAmbient.join(); // segfault or something } - // - // put away the brice for later, save world - // - + // save game::briceSave(); worldSys->save(); - // - // close things, free stuff, yada yada - // - + // exit Mix_HaltMusic(); Mix_CloseAudio(); @@ -253,103 +181,5 @@ int main(int argc, char *argv[]) game::engine.getSystem()->die(); - // - // goodbye - // - return 0; // Calls everything passed to atexit } - -void render() { - static const Texture mouseTex ("assets/goodmouse.png"); - static const glm::mat4 view = glm::lookAt( - glm::vec3(0.0f, 0.0f, 0.0f), // pos - glm::vec3(0.0f, 0.0f, -10.0f), // looking at - glm::vec3(0.0f, 1.0f, 0.0f) // up vector - ); - - static const auto& SCREEN_WIDTH2 = game::SCREEN_WIDTH / 2.0f; - static const auto& SCREEN_HEIGHT2 = game::SCREEN_HEIGHT / 2.0f; - - // - // set the ortho - // - - auto ps = game::engine.getSystem(); - auto ploc = ps->getPosition(); - offset.x = ploc.x + ps->getWidth() / 2; - - const auto& worldWidth = game::engine.getSystem()->getWidth(); - if (worldWidth < (int)SCREEN_WIDTH2 * 2) - offset.x = 0; - else if (offset.x - SCREEN_WIDTH2 < worldWidth * -0.5f) - offset.x = ((worldWidth * -0.5f) + SCREEN_WIDTH2); - else if (offset.x + SCREEN_WIDTH2 > worldWidth * 0.5f) - offset.x = ((worldWidth * 0.5f) - SCREEN_WIDTH2); - - // ortho y snapping - offset.y = std::max(ploc.y /*+ player->height / 2*/, SCREEN_HEIGHT2); - - // "setup" - glm::mat4 projection = glm::ortho(floor(offset.x - SCREEN_WIDTH2), // left - floor(offset.x + SCREEN_WIDTH2), // right - floor(offset.y - SCREEN_HEIGHT2), // bottom - floor(offset.y + SCREEN_HEIGHT2), // top - static_cast(10.0), // near - static_cast(-10.0)); // far - - glm::mat4 ortho = projection * view; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // TODO add depth - glEnable(GL_DEPTH_TEST); - - - Render::worldShader.use(); - glUniformMatrix4fv(Render::worldShader.uniform[WU_ortho], 1, GL_FALSE, glm::value_ptr(ortho)); - glUniformMatrix4fv(Render::worldShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f))); - Render::worldShader.unuse(); - - Render::textShader.use(); - glUniformMatrix4fv(Render::textShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(ortho)); - glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0); - Render::textShader.unuse(); - - // draw the world and player - game::engine.getSystem()->render(); - game::engine.getSystem()->render(); - - // draw the player's inventory - //player->inv->draw(); - - game::engine.render(0); - - // draw the fade overlay - ui::drawFade(); - - // draw ui elements - ui::draw(); - - // draw the debug overlay if desired - if (ui::debug) { - auto pos = game::engine.getSystem()->getPosition(); - ui::putText(offset.x - SCREEN_WIDTH2, (offset.y + SCREEN_HEIGHT2) - ui::fontSize, - "loc: %s\noffset: %s\nfps: %d\nticks: %d\npcount: %d\nxml: %s", - pos.toString().c_str(), offset.toString().c_str(), fps, - game::time::getTickCount(), game::engine.getSystem()->getCount(), - game::engine.getSystem()->getXMLFile().c_str()); - } - - // draw the menu - if (currentMenu) - ui::menu::draw(); - - // draw the mouse - Render::textShader.use(); - glActiveTexture(GL_TEXTURE0); - mouseTex.use(); - Render::useShader(&Render::textShader); - Render::drawRect(vec2(ui::mouse.x, ui::mouse.y - 64), vec2(ui::mouse.x + 64, ui::mouse.y), -9.9); - Render::textShader.unuse(); -} diff --git a/src/components.cpp b/src/components.cpp index 4d80d25..28a81fe 100644 --- a/src/components.cpp +++ b/src/components.cpp @@ -72,49 +72,18 @@ Texture RenderSystem::loadTexture(const std::string& file) return loadTexResult; } -void RenderSystem::fade(void) +void RenderSystem::render(void) { - fadeIn = false, fadeIntensity = 0; -} - -void RenderSystem::fadeLock(void) -{ - fade(); - while (fadeIntensity < 1) - std::this_thread::sleep_for(1ms); -} - -void RenderSystem::unfade(void) -{ - fadeIn = true, fadeIntensity = 1; -} - -void RenderSystem::unfadeLock(void) -{ - fade(); - while (fadeIntensity > 0) - std::this_thread::sleep_for(1ms); -} - -void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) -{ - (void)ev; - if (!loadTexString.empty()) { loadTexResult = Texture(loadTexString); loadTexString.clear(); } - - // update fade system - if (fadeIn && fadeIntensity > 0) - fadeIntensity -= 0.01f; - else if(!fadeIn && fadeIntensity < 1) - fadeIntensity += 0.01f; Render::worldShader.use(); Render::worldShader.enable(); - en.each([dt](entityx::Entity entity, Visible &visible, Sprite &sprite, Position &pos) { + game::entities.lock(); + game::entities.each([](entityx::Entity entity, Visible &visible, Sprite &sprite, Position &pos) { // Verticies and shit float its = 0; @@ -179,38 +148,13 @@ void RenderSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, Render::worldShader.disable(); Render::worldShader.unuse(); - en.each([](entityx::Entity e, Visible &v, Position &pos, Solid& dim, Name &name) { + game::entities.each([](entityx::Entity e, Visible &v, Position &pos, Solid& dim, Name &name) { (void)e; (void)v; ui::setFontZ(-5.0); ui::putStringCentered(pos.x + dim.width / 2, pos.y - ui::fontSize - HLINES(0.5), name.name); }); - - // draw fade - static const GLfloat tex[8] = { - 0, 0, 0, 0, 0, 0, 0, 0 - }; - - auto SCREEN_WIDTH2 = game::SCREEN_WIDTH / 2, SCREEN_HEIGHT2 = game::SCREEN_HEIGHT / 2; - GLfloat coord[12] = { - offset.x - SCREEN_WIDTH2 - 1, offset.y - SCREEN_HEIGHT2, -7.9, - offset.x + SCREEN_WIDTH2, offset.y - SCREEN_HEIGHT2, -7.9, - offset.x - SCREEN_WIDTH2 - 1, offset.y + SCREEN_HEIGHT2, -7.9, - offset.x + SCREEN_WIDTH2, offset.y + SCREEN_HEIGHT2, -7.9 - }; - - Render::textShader.use(); - Render::textShader.enable(); - - Colors::black.use(); - glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0f, 1.0f, 1.0f, fadeIntensity); - glUniform1i(Render::textShader.uniform[WU_texture], 0); - glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coord); - glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex); - glDrawArrays(GL_QUADS, 0, 4); - - Render::textShader.disable(); - Render::textShader.unuse(); + game::entities.unlock(); } void DialogSystem::configure(entityx::EventManager &ev) diff --git a/src/engine.cpp b/src/engine.cpp index abadf3f..c7999ed 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -38,22 +38,11 @@ void Engine::init(void) { systems.configure(); ui::initSounds(); + ui::menu::init(); game::config::update(); getSystem()->create(); } -void Engine::render(entityx::TimeDelta dt) -{ - systems.update(dt); - //systems.update(dt); // doesn't do anything... - - ui::fadeUpdate(); -} -void Engine::resetRender(entityx::TimeDelta dt) -{ - systems.update(dt); -} - void Engine::update(entityx::TimeDelta dt) { systems.update(dt); diff --git a/src/render.cpp b/src/render.cpp index 908b620..4e32311 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -1,7 +1,12 @@ #include +#include + static Shader *currentShader = nullptr; +void preRender(void); +void render(const int&); + namespace Render { Shader worldShader; @@ -62,4 +67,123 @@ void drawRect(vec2 ll, vec2 ur, float z) currentShader->disable(); } +void init(void) +{ +#ifndef __WIN32__ + glewExperimental = GL_TRUE; +#endif + + auto glewError = glewInit(); + if (glewError != GLEW_OK) + UserError(std::string("GLEW was not able to initialize! Error: ") + + reinterpret_cast(glewGetErrorString(glewError))); + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // anti-aliasing + SDL_GL_SetSwapInterval(0); // v-sync + SDL_ShowCursor(SDL_DISABLE); // hide the cursor + glViewport(0, 0, game::SCREEN_WIDTH, game::SCREEN_HEIGHT); // pixel coordinates + glEnable(GL_BLEND); // alpha enabling + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // + glClearColor(1, 1, 1, 1); // white clear color + + std::cout << "Initializing shaders!\n"; + initShaders(); + ::Colors::init(); +} + +void render(const int& fps) +{ + preRender(); + ::render(fps); +} + +} // namespace render + +#include +#include +#include +#include +#include +#include +#include +#include + +void preRender(void) +{ + static const glm::mat4 view = glm::lookAt( + glm::vec3(0.0f, 0.0f, 0.0f), // pos + glm::vec3(0.0f, 0.0f, -10.0f), // looking at + glm::vec3(0.0f, 1.0f, 0.0f) // up vector + ); + + static const auto& SCREEN_WIDTH2 = game::SCREEN_WIDTH / 2.0f; + static const auto& SCREEN_HEIGHT2 = game::SCREEN_HEIGHT / 2.0f; + + // + // set the ortho + // + + auto ps = game::engine.getSystem(); + auto ploc = ps->getPosition(); + offset.x = ploc.x + ps->getWidth() / 2; + + const auto& worldWidth = game::engine.getSystem()->getWidth(); + if (worldWidth < (int)SCREEN_WIDTH2 * 2) + offset.x = 0; + else if (offset.x - SCREEN_WIDTH2 < worldWidth * -0.5f) + offset.x = ((worldWidth * -0.5f) + SCREEN_WIDTH2); + else if (offset.x + SCREEN_WIDTH2 > worldWidth * 0.5f) + offset.x = ((worldWidth * 0.5f) - SCREEN_WIDTH2); + + // ortho y snapping + offset.y = std::max(ploc.y /*+ player->height / 2*/, SCREEN_HEIGHT2); + + // "setup" + glm::mat4 projection = glm::ortho(floor(offset.x - SCREEN_WIDTH2), // left + floor(offset.x + SCREEN_WIDTH2), // right + floor(offset.y - SCREEN_HEIGHT2), // bottom + floor(offset.y + SCREEN_HEIGHT2), // top + static_cast(10.0), // near + static_cast(-10.0)); // far + + glm::mat4 ortho = projection * view; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + + Render::worldShader.use(); + glUniformMatrix4fv(Render::worldShader.uniform[WU_ortho], 1, GL_FALSE, glm::value_ptr(ortho)); + glUniformMatrix4fv(Render::worldShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f))); + Render::worldShader.unuse(); + + Render::textShader.use(); + glUniformMatrix4fv(Render::textShader.uniform[WU_transform], 1, GL_FALSE, glm::value_ptr(ortho)); + glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.0); + Render::textShader.unuse(); +} + +void render(const int& fps) +{ + preRender(); + + game::engine.getSystem()->render(); + + game::engine.getSystem()->render(); + + game::engine.getSystem()->render(); + + // draw the debug overlay if desired + if (ui::debug) { + auto pos = game::engine.getSystem()->getPosition(); + ui::putText(offset.x - game::SCREEN_WIDTH / 2, (offset.y + game::SCREEN_HEIGHT / 2) - ui::fontSize, + "loc: %s\noffset: %s\nfps: %d\nticks: %d\npcount: %d\nxml: %s", + pos.toString().c_str(), offset.toString().c_str(), fps, + game::time::getTickCount(), game::engine.getSystem()->getCount(), + game::engine.getSystem()->getXMLFile().c_str()); + } + + ui::drawFade(); + ui::draw(); + + game::engine.getSystem()->render(); } diff --git a/src/ui.cpp b/src/ui.cpp index 21ed180..9470a56 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -535,8 +535,8 @@ namespace ui { auto& fi = fadeIntensity; fi = 0; - //while (fi < 255) - //std::this_thread::sleep_for(1ms); + while (fi < 255) + std::this_thread::sleep_for(1ms); fi = 255; } @@ -973,6 +973,18 @@ namespace ui { }*/ setFontColor(255,255,255,255); } + + if (currentMenu != nullptr) + menu::draw(); + + // draw the mouse + static const Texture mouseTex ("assets/goodmouse.png"); + Render::textShader.use(); + glActiveTexture(GL_TEXTURE0); + mouseTex.use(); + Render::useShader(&Render::textShader); + Render::drawRect(vec2(ui::mouse.x, ui::mouse.y - 64), vec2(ui::mouse.x + 64, ui::mouse.y), -9.9); + Render::textShader.unuse(); } void closeBox() { @@ -1017,43 +1029,40 @@ namespace ui { } void drawFade(void) { - static const auto SCREEN_WIDTH2 = game::SCREEN_WIDTH / 2; - static const auto SCREEN_HEIGHT2 = game::SCREEN_HEIGHT / 2; - if (!fadeIntensity) { if (fontSize != 16) setFontSize(16); return; } - static const GLfloat tex[] = { - 0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0 + static const GLfloat tex[12] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - GLfloat backdrop[] = { - offset.x - SCREEN_WIDTH2 - 1, offset.y - SCREEN_HEIGHT2, -7.9, - offset.x + SCREEN_WIDTH2, offset.y - SCREEN_HEIGHT2, -7.9, - offset.x - SCREEN_WIDTH2 - 1, offset.y + SCREEN_HEIGHT2, -7.9, - offset.x + SCREEN_WIDTH2, offset.y + SCREEN_HEIGHT2, -7.9 + vec2 p1 (offset.x - game::SCREEN_WIDTH / 2, offset.y - game::SCREEN_HEIGHT / 2); + vec2 p2 (p1.x + game::SCREEN_WIDTH, p1.y + game::SCREEN_HEIGHT); + GLfloat backdrop[18] = { + p1.x, p1.y, -7.9, + p2.x, p1.y, -7.9, + p2.x, p2.y, -7.9, + + p2.x, p2.y, -7.9, + p1.x, p2.y, -7.9, + p1.x, p1.y, -7.9 }; setFontZ(-8.2); - glUniform1i(Render::textShader.uniform[WU_texture], 0); - Render::textShader.use(); Render::textShader.enable(); + Colors::black.use(); glUniform4f(Render::textShader.uniform[WU_tex_color], 1.0f, 1.0f, 1.0f, fadeIntensity / 255.0f); glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, backdrop); glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDrawArrays(GL_TRIANGLES, 0, 6); Render::textShader.disable(); Render::textShader.unuse(); - setFontZ(-8.0); } diff --git a/src/window.cpp b/src/window.cpp index 29bd7c7..992e3c1 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -95,11 +95,7 @@ void WindowSystem::receive(const ScreenshotEvent &scr) std::cout << "Triggered\n"; } -void WindowSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) +void WindowSystem::render(void) { - (void)en; - (void)ev; - (void)dt; - SDL_GL_SwapWindow(window); } diff --git a/src/world.cpp b/src/world.cpp index a80fba8..6551442 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1147,7 +1147,8 @@ void WorldSystem::detect(entityx::TimeDelta dt) const auto& data = world.data; if (loc.y < data[line].groundHeight) { int dir = vel.x < 0 ? -1 : 1; - if (line + dir * 2 < static_cast(data.size()) && + auto thing = line + dir * 2; + if (thing > 0 && thing < static_cast(data.size()) && data[line + dir * 2].groundHeight - 30 > data[line + dir].groundHeight) { loc.x -= (PLAYER_SPEED_CONSTANT + 2.7f) * dir * 2; vel.x = 0; @@ -1179,12 +1180,15 @@ void WorldSystem::goWorldRight(Position& p, Solid &d) { if (!(world.toRight.empty()) && (p.x + d.width > world.startX * -1 - HLINES(5))) { auto& rs = *game::engine.getSystem(); - rs.fadeLock(); + //rs.fadeLock(); + ui::toggleBlack(); + ui::waitForCover(); while (waitToSwap) std::this_thread::sleep_for(1ms); load(world.toRight); game::engine.getSystem()->setX(world.startX + HLINES(10)); - rs.unfade(); + ui::toggleBlack(); + //rs.unfade(); } } -- cgit v1.2.3 From f91e95eed85bdd74b219b20a435fa6f297069da1 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Fri, 13 Jan 2017 10:42:55 -0500 Subject: vector2 stuff, other things --- Makefile | 4 +- include/common.hpp | 112 +--- include/render.hpp | 2 - include/texture.hpp | 2 + include/vector2.hpp | 80 +++ include/world.hpp | 6 +- main.cpp | 2 +- src/components.cpp | 6 +- src/entities.cpp.bak | 1371 --------------------------------------------- src/gametime.cpp | 24 +- src/inventory.cpp | 8 +- src/inventory.cpp.bak | 747 ------------------------ src/items.cpp.bak | 301 ---------- src/mob.cpp.bak | 539 ------------------ src/old/entities.cpp.bak | 1371 +++++++++++++++++++++++++++++++++++++++++++++ src/old/inventory.cpp.bak | 747 ++++++++++++++++++++++++ src/old/items.cpp.bak | 301 ++++++++++ src/old/mob.cpp.bak | 539 ++++++++++++++++++ src/old/quest.cpp.bak | 65 +++ src/quest.cpp.bak | 65 --- src/texture.cpp | 4 + src/ui.cpp | 4 +- src/world.cpp | 18 +- xml/!town.xml | 1 - 24 files changed, 3152 insertions(+), 3167 deletions(-) create mode 100644 include/vector2.hpp delete mode 100644 src/entities.cpp.bak delete mode 100644 src/inventory.cpp.bak delete mode 100644 src/items.cpp.bak delete mode 100644 src/mob.cpp.bak create mode 100644 src/old/entities.cpp.bak create mode 100644 src/old/inventory.cpp.bak create mode 100644 src/old/items.cpp.bak create mode 100644 src/old/mob.cpp.bak create mode 100644 src/old/quest.cpp.bak delete mode 100644 src/quest.cpp.bak (limited to 'main.cpp') diff --git a/Makefile b/Makefile index f8d7511..471a11a 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ endif CXXFLAGS = -ggdb -m$(TARGET_BITS) -std=c++14 -fext-numeric-literals CXXINC = -Iinclude -Iinclude/freetype -I. -CXXWARN = -Wall -Wextra #-Werror -pedantic +CXXWARN = -Wall -Wextra -Werror -pedantic CXXSRCDIR = src CXXOUTDIR = out @@ -56,4 +56,4 @@ $(CXXOUTDIR)/%.o: $(CXXSRCDIR)/%.cpp $(CXXOUTDIR)/%.o: $(CXXSRCDIR)/%.cc @echo " CXX " $< - @$(CXX) $(CXXFLAGS) $(CXXINC) $(CXXWARN) $(LIBS) -c $< -o $@ \ No newline at end of file + @$(CXX) $(CXXFLAGS) $(CXXINC) $(CXXWARN) $(LIBS) -c $< -o $@ diff --git a/include/common.hpp b/include/common.hpp index abfd28b..1244464 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -55,73 +55,10 @@ using uint = unsigned int; #define coalesce(v1, v2) ((v1 != nullptr) ? v1 : v2) -/** - * Creates a coordinate of integers. - */ -typedef struct { - int x; /**< The x coordinate */ - int y; /**< The y coordinate */ -} ivec2; +#include -/** - * A pair of x and y for dimensions (i.e. width and height). - */ -typedef ivec2 dim2; - -/** - * Creates a coordinate out of floating point integers. - */ -struct vec2 { - float x; - float y; - - vec2(float _x = 0.0f, float _y = 0.0f) - : x(_x), y(_y) {} - - bool operator==(const vec2 &v) const { - return (x == v.x) && (y == v.y); - } - - template - const vec2 operator=(const T &n) { - x = y = n; - return *this; - } - - template - vec2 operator+(T n) const { - return vec2 (x + n, y + n); - } - - vec2 operator+(const vec2 &v) { - return vec2 (x + v.x, y + v.y); - } - - vec2 operator*(const float&n) const { - return vec2 (x * n, y * n); - } - - vec2 operator/(const float& n) const { - return vec2 (x / n, y / n); - } - - // std::swap can't work due to being packed - - inline void swapX(vec2 &v) { - float t = x; - x = v.x, v.x = t; - } - - inline void swapY(vec2 &v) { - float t = y; - y = v.y, v.y = t; - } - - std::string toString(void) const { - return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; - } - -} __attribute__ ((packed)); +using vec2 = vector2; +using dim2 = vector2; /** * A structure for three-dimensional points. @@ -133,8 +70,7 @@ struct vec3 { vec3(float _x = 0.0f, float _y = 0.0f, float _z = 1.0f) : x(_x), y(_y), z(_z) {} - -} __attribute__ ((packed)); +}; /** * This structure contains two sets of coordinates for ray drawing. @@ -155,35 +91,15 @@ public: float blue; /**< The amount of blue */ float alpha; /**< Transparency */ - Color() { - red = green = blue = alpha = 0.0f; - } + Color(float r = 0, float g = 0, float b = 0, float a = 255) + : red(r), green(g), blue(b), alpha(a) {} - Color(float r, float g ,float b) { - red = r; - green = g; - blue = b; - alpha = 255; + Color operator-(const float& a) { + return Color(red - a, green - a, blue - a, alpha); } - Color(float r, float g, float b, float a) { - red = r; - green = g; - blue = b; - alpha = a; - } - - Color operator-=(float a) { - red -= a; - green -= a; - blue -= a; - return{red+a,green+a,blue+a}; - } - Color operator+=(float a) { - return{red+a,green+a,blue+a}; - } - Color operator=(float a) { - return{red=a,green=a,blue=a}; + Color operator+(const float& a) { + return Color(red + a, green + a, blue + a, alpha); } }; @@ -206,14 +122,6 @@ constexpr float MSEC_PER_TICK = 1000.0f / TICKS_PER_SEC; */ std::vector StringTokenizer(const std::string& str, char delim); -/** - * Seperates a string like, "23,12" to a vec2. - * - * @param s the string to parse - * @return the vec2 of the values passed in the string - */ -vec2 str2coord(std::string s); - /** * Returns a measurement in HLINEs * diff --git a/include/render.hpp b/include/render.hpp index cf58519..997d7d0 100644 --- a/include/render.hpp +++ b/include/render.hpp @@ -69,8 +69,6 @@ namespace Render { extern Shader worldShader; extern Shader textShader; - void initShaders(void); - void useShader(Shader *s); void drawRect(vec2 ll, vec2 ur, float z); diff --git a/include/texture.hpp b/include/texture.hpp index 3cb8d1f..43db1b6 100644 --- a/include/texture.hpp +++ b/include/texture.hpp @@ -93,6 +93,8 @@ namespace Colors { extern ColorTex red; /**< A solid red texture. */ extern ColorTex blue; /**< A solid blue texture. */ + extern GLfloat texCoord[12]; + /** * Creates the colors. */ diff --git a/include/vector2.hpp b/include/vector2.hpp new file mode 100644 index 0000000..debaee9 --- /dev/null +++ b/include/vector2.hpp @@ -0,0 +1,80 @@ +#ifndef VECTOR2_HPP_ +#define VECTOR2_HPP_ + +#include +#include + +template +struct vector2 { + static_assert(std::is_arithmetic::value, "vector2 members must be an arithmetic type (i.e. numbers)"); + + T x, y; + + vector2(T _x = 0, T _y = 0) + : x(_x), y(_y) {} + + // format: "3, 5" + vector2(const std::string& s) { + *this = s; + } + + vector2& operator=(const T& value) { + x = y = value; + return *this; + } + + vector2& operator=(const std::string& s) { + auto comma = s.find(','); + x = std::stoi(s.substr(0, comma)); + y = std::stoi(s.substr(comma + 1)); + return *this; + } + + // addition + vector2 operator+(const vector2& v) const { + return vector2(x + v.x, y + v.y); + } + + vector2 operator+(const T& n) const { + return vector2(x + n, y + n); + } + + // subtraction + vector2 operator-(const vector2& v) const { + return vector2(x - v.x, y - v.y); + } + + vector2 operator-(const T& n) const { + return vector2(x - n, y - n); + } + + // multiplication + vector2 operator*(const vector2& v) const { + return vector2(x * v.x, y * v.y); + } + + vector2 operator*(const T& n) const { + return vector2(x * n, y * n); + } + + // division + vector2 operator/(const vector2& v) const { + return vector2(x / v.x, y / v.y); + } + + vector2 operator/(const T& n) const { + return vector2(x / n, y / n); + } + + // compare + bool operator==(const vector2& v) const { + return (x == v.x) && (y == v.y); + } + + // other functions + std::string toString(void) const { + return "(" + std::to_string(x) + ", " + std::to_string(y) + ")"; + } +}; + +#endif // VECTOR2_HPP_ diff --git a/include/world.hpp b/include/world.hpp index 14c64d0..9b68314 100644 --- a/include/world.hpp +++ b/include/world.hpp @@ -37,7 +37,7 @@ struct WorldData { float grassHeight[2]; /**< height of the two grass blades */ float groundHeight; /**< height of the 'line' */ unsigned char groundColor; /**< a value that affects the ground's color */ -} __attribute__ ((packed)); +}; /** * Defines how many game ticks it takes to go from day to night or vice versa. @@ -171,8 +171,8 @@ public: WorldData2 worldData; void generate(int width = 0); - void addHole(const unsigned int& start, const unsigned int& end); - void addHill(const ivec2& peak, const unsigned int& width); + //void addHole(const unsigned int& start, const unsigned int& end); + //void addHill(const ivec2& peak, const unsigned int& width); bool save(void); void load(const std::string& file); diff --git a/main.cpp b/main.cpp index 40a8497..2e5e69d 100644 --- a/main.cpp +++ b/main.cpp @@ -77,7 +77,7 @@ int main(int argc, char *argv[]) // read in all XML file names in the folder std::list xmlFiles; - if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles)) + if (getdir(std::string("./" + xmlFolder), xmlFiles)) UserError("Error reading XML files!!!"); // kill the world if needed diff --git a/src/components.cpp b/src/components.cpp index 28a81fe..b758cb6 100644 --- a/src/components.cpp +++ b/src/components.cpp @@ -306,12 +306,12 @@ std::vector developFrame(XMLElement* xml) std::string sname = sxml->Name(); if (sname == "src") { foffset = (sxml->Attribute("offset") != nullptr) ? - str2coord(sxml->Attribute("offset")) : vec2(0,0); + sxml->StrAttribute("offset") : vec2(0,0); fdraw = (sxml->Attribute("drawOffset") != nullptr) ? - str2coord(sxml->Attribute("drawOffset")) : vec2(0,0); + sxml->StrAttribute("drawOffset") : vec2(0,0); if (sxml->Attribute("size") != nullptr) { - fsize = str2coord(sxml->Attribute("size")); + fsize = sxml->Attribute("size"); tmpf.push_back(std::make_pair(SpriteData(sxml->GetText(), foffset, fsize), fdraw)); } else { tmpf.push_back(std::make_pair(SpriteData(sxml->GetText(), foffset), fdraw)); diff --git a/src/entities.cpp.bak b/src/entities.cpp.bak deleted file mode 100644 index 25dd379..0000000 --- a/src/entities.cpp.bak +++ /dev/null @@ -1,1371 +0,0 @@ -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -///NEW -#include -#include -///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 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 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(*this); - ev.subscribe(*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(wsi.first->bgm, wsi.first); - std::tie(currentWorld, player->loc) = wsi; // using p causes segfault - game::engine.getSystem()->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(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(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(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 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 = ¤tXMLDoc; - } 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(*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..."<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 buf (len,'\0'); - in.read(buf.data(),buf.size()); - - data.rdbuf()->pubsetbuf(buf.data(),buf.size()); - - std::getline(data,ddata); - loc.x = std::stoi(ddata); - std::getline(data,ddata); - loc.y = std::stoi(ddata); - std::getline(data,ddata); - health = std::stoi(ddata); - std::getline(data,ddata); - maxHealth = std::stoi(ddata); - std::getline(data,ddata); - game::time::tick(std::stoi(ddata)); - - std::getline(data,ddata); - std::getline(data,ddata); - - for (i = std::stoi(ddata);i;i--) { - std::getline(data,ddata); - if (ddata == "qwer") - break; - count = std::stoi(ddata); - - std::getline(data,ddata); - if (ddata == "qwer") - break; - inv->addItem(ddata, (uint)count); - } - - std::getline(data,ddata); - currentWorld = loadWorldFromXMLNoSave(ddata); - - in.close(); - } -} - - -//NEW -void entityxTest(void) -{ - entityx::Entity e = game::entities.create(); - e.assign(100.0f, 100.0f); - e.assign(0.0f, 0.0f); - - e = game::entities.create(); - e.assign(0.0f, 100.0f); - e.assign(-0.01f, 0.0f); - e.assign(-.2f); - auto sprite_h = e.assign(); - sprite_h->addSpriteSegment(SpriteData(game::sprite_l.loadSprite("assets/cat.png"), - vec2(0, 0), - vec2(19, 15)), - vec2(0, 0)); -} diff --git a/src/gametime.cpp b/src/gametime.cpp index 1005d84..cb736ff 100644 --- a/src/gametime.cpp +++ b/src/gametime.cpp @@ -1,15 +1,9 @@ #include -#include +#include // millis static unsigned int tickCount = 0; -static float deltaTime = 1; - -// millisecond timers -static unsigned int currentTime = 0; -static unsigned int prevTime; - -static float accum = 0.0f; +static unsigned int deltaTime = 1; namespace game { namespace time { @@ -34,15 +28,19 @@ namespace game { } void mainLoopHandler(void) { - if (!currentTime) - currentTime = prevTime = millis(); + static unsigned int cur = 0, prev; - currentTime = millis(); - deltaTime = currentTime - prevTime; - prevTime = currentTime; + if (cur == 0) + cur = prev = millis(); + + cur = millis(); + deltaTime = cur - prev; + prev = cur; } bool tickHasPassed(void) { + static unsigned int accum = 0; + accum += deltaTime; if (accum > MSEC_PER_TICK) { accum = 0.0f; diff --git a/src/inventory.cpp b/src/inventory.cpp index 480c803..ed6028b 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -2,10 +2,10 @@ #include #include -#include -#include +//#include +//#include -constexpr const char* ICON_TEX_FILE_PATH = "config/invIcons.txt"; +constexpr const char* iconTexturePath = "config/invIcons.txt"; static std::vector iconTextures; @@ -16,7 +16,7 @@ void InventorySystem::configure(entityx::EventManager &ev) void InventorySystem::loadIcons(void) { iconTextures.clear(); - auto icons = readFileA(ICON_TEX_FILE_PATH); + auto icons = readFileA(iconTexturePath); for (const auto& s : icons) iconTextures.push_back(s); } diff --git a/src/inventory.cpp.bak b/src/inventory.cpp.bak deleted file mode 100644 index 1b325c0..0000000 --- a/src/inventory.cpp.bak +++ /dev/null @@ -1,747 +0,0 @@ -#include - -#include - -#include - -#include - -#include -using namespace tinyxml2; - -extern Player *player; -extern GLuint invUI; -static vec2 itemLoc; -static const unsigned char numSlot = 7; -Mix_Chunk* swordSwing; - -static std::vector currencyMap; -static std::vector 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::vectordfp(numSlot); - static std::vectoriray(numSlot); - static std::vectorcurCoord(numSlot); - static int range = 200; - - static std::vectorcurdfp(4); - static std::vectorcurRay(4); - static std::vectorcurCurCoord(4); - static int curRange = 100; - - static std::vectormassDfp(32); - static std::vectormassRay(32); - static std::vectormassOrder = {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::vectormassOrderClosing = {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 &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((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((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 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(*this); -} - -void InventorySystem::receive(const MouseScrollEvent &mse) -{ - static int mouseWheelUpCount = 0, mouseWheelDownCount = 0; - - if ((mse.scrollDistance < 0) && ((++mouseWheelUpCount % 5) == 0) ) { - mouseWheelUpCount = 0; - player->inv->setSelectionUp(); - } else if ( (++mouseWheelDownCount % 5) == 0 ) { - mouseWheelDownCount = 0; - player->inv->setSelectionDown(); - } -} diff --git a/src/items.cpp.bak b/src/items.cpp.bak deleted file mode 100644 index 180c5fa..0000000 --- a/src/items.cpp.bak +++ /dev/null @@ -1,301 +0,0 @@ -#include -#include -#include - -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 = ¤tWorld->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 e) -{ - for (auto &v : e) { - interact.push_back(v); - } -} - -GLuint Item::rtex() -{ - return tex->image[0]; -} - -GLuint Item::rtex(int n) -{ - return tex->image[n]; -} - -Item::~Item() -{ - delete tex; -} - -/************************************************** -* SWORD * -**************************************************/ - -float Sword::getDamage() -{ - return damage; -} - -void Sword::setDamage(float d) -{ - damage = d; -} - -/************************************************** -* ARROW * -**************************************************/ - -float Arrow::getDamage() -{ - return damage; -} - -void Arrow::setDamage(float d) -{ - damage = d; -} - - -/************************************************** -* BOW * -**************************************************/ - -float Bow::getDamage() -{ - return damage; -} - -void Bow::setDamage(float d) -{ - damage = d; -} - -/************************************************** -* FOODS * -**************************************************/ - -float RawFood::getHealth() -{ - return health; -} diff --git a/src/mob.cpp.bak b/src/mob.cpp.bak deleted file mode 100644 index e78e5cd..0000000 --- a/src/mob.cpp.bak +++ /dev/null @@ -1,539 +0,0 @@ -#include -#include -#include -#include - -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", ¬ext) != 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(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(d) * 100.0f) { - q.y -= 20; - ui::putTextL(q, "%d x %s", std::get(d), std::get(d).c_str()); - player->inv->addItem(std::get(d), std::get(d)); - } - } -} diff --git a/src/old/entities.cpp.bak b/src/old/entities.cpp.bak new file mode 100644 index 0000000..25dd379 --- /dev/null +++ b/src/old/entities.cpp.bak @@ -0,0 +1,1371 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +///NEW +#include +#include +///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 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 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(*this); + ev.subscribe(*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(wsi.first->bgm, wsi.first); + std::tie(currentWorld, player->loc) = wsi; // using p causes segfault + game::engine.getSystem()->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(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(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(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 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 = ¤tXMLDoc; + } 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(*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..."<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 buf (len,'\0'); + in.read(buf.data(),buf.size()); + + data.rdbuf()->pubsetbuf(buf.data(),buf.size()); + + std::getline(data,ddata); + loc.x = std::stoi(ddata); + std::getline(data,ddata); + loc.y = std::stoi(ddata); + std::getline(data,ddata); + health = std::stoi(ddata); + std::getline(data,ddata); + maxHealth = std::stoi(ddata); + std::getline(data,ddata); + game::time::tick(std::stoi(ddata)); + + std::getline(data,ddata); + std::getline(data,ddata); + + for (i = std::stoi(ddata);i;i--) { + std::getline(data,ddata); + if (ddata == "qwer") + break; + count = std::stoi(ddata); + + std::getline(data,ddata); + if (ddata == "qwer") + break; + inv->addItem(ddata, (uint)count); + } + + std::getline(data,ddata); + currentWorld = loadWorldFromXMLNoSave(ddata); + + in.close(); + } +} + + +//NEW +void entityxTest(void) +{ + entityx::Entity e = game::entities.create(); + e.assign(100.0f, 100.0f); + e.assign(0.0f, 0.0f); + + e = game::entities.create(); + e.assign(0.0f, 100.0f); + e.assign(-0.01f, 0.0f); + e.assign(-.2f); + auto sprite_h = e.assign(); + sprite_h->addSpriteSegment(SpriteData(game::sprite_l.loadSprite("assets/cat.png"), + vec2(0, 0), + vec2(19, 15)), + vec2(0, 0)); +} diff --git a/src/old/inventory.cpp.bak b/src/old/inventory.cpp.bak new file mode 100644 index 0000000..1b325c0 --- /dev/null +++ b/src/old/inventory.cpp.bak @@ -0,0 +1,747 @@ +#include + +#include + +#include + +#include + +#include +using namespace tinyxml2; + +extern Player *player; +extern GLuint invUI; +static vec2 itemLoc; +static const unsigned char numSlot = 7; +Mix_Chunk* swordSwing; + +static std::vector currencyMap; +static std::vector 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::vectordfp(numSlot); + static std::vectoriray(numSlot); + static std::vectorcurCoord(numSlot); + static int range = 200; + + static std::vectorcurdfp(4); + static std::vectorcurRay(4); + static std::vectorcurCurCoord(4); + static int curRange = 100; + + static std::vectormassDfp(32); + static std::vectormassRay(32); + static std::vectormassOrder = {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::vectormassOrderClosing = {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 &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((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((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 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(*this); +} + +void InventorySystem::receive(const MouseScrollEvent &mse) +{ + static int mouseWheelUpCount = 0, mouseWheelDownCount = 0; + + if ((mse.scrollDistance < 0) && ((++mouseWheelUpCount % 5) == 0) ) { + mouseWheelUpCount = 0; + player->inv->setSelectionUp(); + } else if ( (++mouseWheelDownCount % 5) == 0 ) { + mouseWheelDownCount = 0; + player->inv->setSelectionDown(); + } +} diff --git a/src/old/items.cpp.bak b/src/old/items.cpp.bak new file mode 100644 index 0000000..180c5fa --- /dev/null +++ b/src/old/items.cpp.bak @@ -0,0 +1,301 @@ +#include +#include +#include + +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 = ¤tWorld->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 e) +{ + for (auto &v : e) { + interact.push_back(v); + } +} + +GLuint Item::rtex() +{ + return tex->image[0]; +} + +GLuint Item::rtex(int n) +{ + return tex->image[n]; +} + +Item::~Item() +{ + delete tex; +} + +/************************************************** +* SWORD * +**************************************************/ + +float Sword::getDamage() +{ + return damage; +} + +void Sword::setDamage(float d) +{ + damage = d; +} + +/************************************************** +* ARROW * +**************************************************/ + +float Arrow::getDamage() +{ + return damage; +} + +void Arrow::setDamage(float d) +{ + damage = d; +} + + +/************************************************** +* BOW * +**************************************************/ + +float Bow::getDamage() +{ + return damage; +} + +void Bow::setDamage(float d) +{ + damage = d; +} + +/************************************************** +* FOODS * +**************************************************/ + +float RawFood::getHealth() +{ + return health; +} diff --git a/src/old/mob.cpp.bak b/src/old/mob.cpp.bak new file mode 100644 index 0000000..e78e5cd --- /dev/null +++ b/src/old/mob.cpp.bak @@ -0,0 +1,539 @@ +#include +#include +#include +#include + +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", ¬ext) != 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(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(d) * 100.0f) { + q.y -= 20; + ui::putTextL(q, "%d x %s", std::get(d), std::get(d).c_str()); + player->inv->addItem(std::get(d), std::get(d)); + } + } +} diff --git a/src/old/quest.cpp.bak b/src/old/quest.cpp.bak new file mode 100644 index 0000000..f19359e --- /dev/null +++ b/src/old/quest.cpp.bak @@ -0,0 +1,65 @@ +#include + +#include + +int QuestHandler::assign(std::string title,std::string desc,std::string req) { + Quest tmp; + char *tok; + + tmp.title = title; + tmp.desc = desc; + + tok = strtok(&req[0], "\n\r\t,"); + tmp.need.emplace_back("", 0); + + while (tok) { + if (!tmp.need.back().first.empty()) { + tmp.need.back().second = atoi(tok); + tmp.need.emplace_back("", 0); + } else + tmp.need.back().first = tok; + + tok = strtok(NULL, "\n\r\t,"); + } + + tmp.need.pop_back(); + current.push_back(tmp); + + return 0; +} + +int QuestHandler::drop(std::string title) { + current.erase(std::remove_if (current.begin(), + current.end(), + [&](Quest q) { return q.title == title; }), + current.end()); + + return 0; +} + +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) + return 0; + //} + + //for (auto &n : (*c).need) + //player->inv->takeItem(n.first, n.second); + //current.erase(c); + //return 1; + } + } + + return 0; +} + +bool QuestHandler::hasQuest(std::string t) { + for (auto &c : current) { + if (c.title == t) + return true; + } + + return false; +} diff --git a/src/quest.cpp.bak b/src/quest.cpp.bak deleted file mode 100644 index f19359e..0000000 --- a/src/quest.cpp.bak +++ /dev/null @@ -1,65 +0,0 @@ -#include - -#include - -int QuestHandler::assign(std::string title,std::string desc,std::string req) { - Quest tmp; - char *tok; - - tmp.title = title; - tmp.desc = desc; - - tok = strtok(&req[0], "\n\r\t,"); - tmp.need.emplace_back("", 0); - - while (tok) { - if (!tmp.need.back().first.empty()) { - tmp.need.back().second = atoi(tok); - tmp.need.emplace_back("", 0); - } else - tmp.need.back().first = tok; - - tok = strtok(NULL, "\n\r\t,"); - } - - tmp.need.pop_back(); - current.push_back(tmp); - - return 0; -} - -int QuestHandler::drop(std::string title) { - current.erase(std::remove_if (current.begin(), - current.end(), - [&](Quest q) { return q.title == title; }), - current.end()); - - return 0; -} - -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) - return 0; - //} - - //for (auto &n : (*c).need) - //player->inv->takeItem(n.first, n.second); - //current.erase(c); - //return 1; - } - } - - return 0; -} - -bool QuestHandler::hasQuest(std::string t) { - for (auto &c : current) { - if (c.title == t) - return true; - } - - return false; -} diff --git a/src/texture.cpp b/src/texture.cpp index b47c3c7..721e5cb 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -10,6 +10,10 @@ namespace Colors ColorTex red; ColorTex blue; + GLfloat texCoord[12] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + void init(void) { white = ColorTex(Color(255, 255, 255)); black = ColorTex(Color(0, 0, 0 )); diff --git a/src/ui.cpp b/src/ui.cpp index 9470a56..552884f 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -650,8 +650,8 @@ namespace ui { auto stride = 5 * sizeof(GLfloat); // we always want to make sure c1 is lower left and c2 is upper right - if (c1.x > c2.x) c1.swapX(c2); // std::swap(c1.x, c2.y); - if (c1.y > c2.y) c1.swapY(c2); // std::swap(c1.y, c2.y); + if (c1.x > c2.x) std::swap(c1.x, c2.x); + if (c1.y > c2.y) std::swap(c1.y, c2.y); // if the box is too small, we will not be able to draw it if (c2.x - c1.x < (boxCornerDim.x) || c2.y - c1.y < (boxCornerDim.y)) diff --git a/src/world.cpp b/src/world.cpp index 6551442..8f4be8e 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -324,9 +324,9 @@ void WorldSystem::load(const std::string& file) vec2 coords; if (wxml->Attribute("position") != nullptr) { - coords = str2coord(wxml->StrAttribute("position")); + coords = wxml->StrAttribute("position"); } else { - coords = str2coord(abcd->StrAttribute("value")); + coords = abcd->StrAttribute("value"); } float cdat[2] = {coords.x, coords.y}; @@ -345,7 +345,7 @@ void WorldSystem::load(const std::string& file) vec2 dim; if (abcd->Attribute("value") != nullptr) - dim = str2coord(abcd->StrAttribute("value")); + dim = abcd->StrAttribute("value"); else dim = entity.component()->getSpriteSize(); @@ -355,9 +355,9 @@ void WorldSystem::load(const std::string& file) vec2 dir; if (wxml->Attribute("direction") != nullptr) { - dir = str2coord(wxml->StrAttribute("direction")); + dir = wxml->StrAttribute("direction"); } else if (wxml->Attribute("value") != nullptr) { - dir = str2coord(wxml->StrAttribute("value")); + dir = wxml->StrAttribute("value"); } else { dir = vec2(0,0); } @@ -669,9 +669,8 @@ void WorldSystem::render(void) const auto SCREEN_WIDTH = game::SCREEN_WIDTH; const auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; - const ivec2 backgroundOffset = ivec2 { - static_cast(SCREEN_WIDTH) / 2, static_cast(SCREEN_HEIGHT) / 2 - }; + const vector2 backgroundOffset + (static_cast(SCREEN_WIDTH) / 2, static_cast(SCREEN_HEIGHT) / 2); int iStart, iEnd, pOffset; @@ -1179,8 +1178,6 @@ void WorldSystem::detect(entityx::TimeDelta dt) void WorldSystem::goWorldRight(Position& p, Solid &d) { if (!(world.toRight.empty()) && (p.x + d.width > world.startX * -1 - HLINES(5))) { - auto& rs = *game::engine.getSystem(); - //rs.fadeLock(); ui::toggleBlack(); ui::waitForCover(); while (waitToSwap) @@ -1188,7 +1185,6 @@ void WorldSystem::goWorldRight(Position& p, Solid &d) load(world.toRight); game::engine.getSystem()->setX(world.startX + HLINES(10)); ui::toggleBlack(); - //rs.unfade(); } } diff --git a/xml/!town.xml b/xml/!town.xml index 0a28124..47ddf27 100644 --- a/xml/!town.xml +++ b/xml/!town.xml @@ -12,7 +12,6 @@ - -- cgit v1.2.3 From d20633705e53a122467fb39fdbb2de3cfec279f7 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 14 Jan 2017 12:48:49 -0500 Subject: thread work --- include/particle.hpp | 4 +-- main.cpp | 76 ++++++++++++++++++++++++++++++++-------------------- src/particle.cpp | 2 +- src/render.cpp | 2 +- 4 files changed, 51 insertions(+), 33 deletions(-) (limited to 'main.cpp') diff --git a/include/particle.hpp b/include/particle.hpp index 55228c0..48a8938 100644 --- a/include/particle.hpp +++ b/include/particle.hpp @@ -17,13 +17,13 @@ enum class ParticleType : char { struct Particle { int timeLeft; + ParticleType type; vec2 velocity; vec2 location; - ParticleType type; vec2 color; // assets/colorIndex.png Particle(vec2 p, ParticleType t, int tl, vec2 c) - : timeLeft(tl), location(p), type(t), color(c) {} + : timeLeft(tl), type(t), location(p), color(c) {} }; class ParticleSystem : public entityx::System { diff --git a/main.cpp b/main.cpp index 2e5e69d..49199a0 100644 --- a/main.cpp +++ b/main.cpp @@ -21,6 +21,31 @@ using namespace std::literals::chrono_literals; #include #include +class GameThread : public entityx::Receiver { +private: + std::atomic_bool die; + bool running; + std::thread thread; + +public: + template + GameThread(F&& func) { + die.store(false); + running = true; + thread = std::thread([this](F&& f) { + while (!die.load()) + f(); + running = false; + }, std::forward(func)); + } + + void stop(void) { + die.store(true); + while (running) + std::this_thread::sleep_for(2ms); + } +}; + /** * The currently used folder to look for XML files in. */ @@ -112,43 +137,36 @@ int main(int argc, char *argv[]) if (!worldDontReallyRun) { // the main loop, in all of its gloriousness... - std::thread thMain ([&] { - const bool &run = game::engine.shouldRun; - while (run) { - game::time::mainLoopHandler(); - - if (game::time::tickHasPassed()) { - // calculate the world shading value - extern int worldShade; // TODO kill - worldShade = 50 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI)); + GameThread gtMain ([&] { + game::time::mainLoopHandler(); - // update fades - ui::fadeUpdate(); + if (game::time::tickHasPassed()) { + // calculate the world shading value + extern int worldShade; // TODO kill + worldShade = 50 * sin((game::time::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI)); - // increment game ticker - game::time::tick(); - } + // update fades + ui::fadeUpdate(); - while (!eventQueue.empty()) { - game::events.emit(eventQueue.back()); - eventQueue.pop_back(); - } - - game::engine.update(game::time::getDeltaTime()); + // increment game ticker + game::time::tick(); + } - std::this_thread::sleep_for(1ms); + while (!eventQueue.empty()) { + game::events.emit(eventQueue.back()); + eventQueue.pop_back(); } + + game::engine.update(game::time::getDeltaTime()); + std::this_thread::sleep_for(1ms); }); static int fps = 0, fpsInternal = 0; // the debug loop, gets debug screen values - std::thread thDebug ([&] { - const bool &run = game::engine.shouldRun; - while (run) { - fps = fpsInternal, fpsInternal = 0; - std::this_thread::sleep_for(1s); - } + GameThread gtDebug ([&] { + fps = fpsInternal, fpsInternal = 0; + std::this_thread::sleep_for(1s); }); // the render loop, renders @@ -163,8 +181,8 @@ int main(int argc, char *argv[]) } // on game end, get back together - thMain.join(); - thDebug.join(); + gtMain.stop(); + gtDebug.stop(); //game::engine.getSystem()->thAmbient.join(); // segfault or something } diff --git a/src/particle.cpp b/src/particle.cpp index 198387c..6eeec33 100644 --- a/src/particle.cpp +++ b/src/particle.cpp @@ -89,6 +89,7 @@ void ParticleSystem::update(entityx::EntityManager &en, entityx::EventManager &e for (unsigned int i = 0; i < parts.size(); i++) { auto& p = parts[i]; + auto& vel = p.velocity; // update timers if (p.timeLeft > 0) @@ -97,7 +98,6 @@ void ParticleSystem::update(entityx::EntityManager &en, entityx::EventManager &e continue; // update movement - auto& vel = p.velocity; switch (p.type) { case ParticleType::Drop: if (vel.y > -.6) diff --git a/src/render.cpp b/src/render.cpp index a63d63a..5cbd11e 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -79,7 +79,7 @@ void init(void) + reinterpret_cast(glewGetErrorString(glewError))); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // anti-aliasing - SDL_GL_SetSwapInterval(0); // v-sync + SDL_GL_SetSwapInterval(1); // v-sync SDL_ShowCursor(SDL_DISABLE); // hide the cursor glViewport(0, 0, game::SCREEN_WIDTH, game::SCREEN_HEIGHT); // pixel coordinates glEnable(GL_BLEND); // alpha enabling -- cgit v1.2.3 From 8452b199d28bea53bf2c5e3b3d604064000fc73d Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 18 Jan 2017 06:46:36 -0500 Subject: inventory bar --- include/inventory.hpp | 32 ++++++++++++++++++---- main.cpp | 14 ++++++---- src/inventory.cpp | 76 +++++++++++++++++++++++++++------------------------ 3 files changed, 77 insertions(+), 45 deletions(-) (limited to 'main.cpp') diff --git a/include/inventory.hpp b/include/inventory.hpp index 15877e9..44ed148 100644 --- a/include/inventory.hpp +++ b/include/inventory.hpp @@ -6,20 +6,40 @@ #include #include -struct InventoryEntry { - GLuint icon; +struct Item { std::string name; std::string type; + int value; + int stackSize; + Texture sprite; + + Item(void) + : value(0), stackSize(1) {} + + Item(XMLElement *e) { + name = e->StrAttribute("name"); + type = e->StrAttribute("type"); + + value = 0; + e->QueryIntAttribute("value", &value); + stackSize = 1; + e->QueryIntAttribute("maxStackSize", &stackSize); + + sprite = Texture(e->StrAttribute("sprite")); + } +}; +struct InventoryEntry { + Item* item; int count; - int max; vec2 loc; + + InventoryEntry(void) + : item(nullptr), count(0) {} }; class InventorySystem : public entityx::System, public entityx::Receiver { private: - entityx::Entity currentItemEntity; - std::vector items; public: @@ -36,6 +56,8 @@ public: void receive(const KeyDownEvent &kde); void render(void); + + void add(const std::string& name, int count); }; #endif // INVENTORY_HPP_ diff --git a/main.cpp b/main.cpp index 49199a0..7e06d7d 100644 --- a/main.cpp +++ b/main.cpp @@ -20,29 +20,29 @@ using namespace std::literals::chrono_literals; #include #include #include +#include class GameThread : public entityx::Receiver { private: std::atomic_bool die; - bool running; std::thread thread; public: template GameThread(F&& func) { die.store(false); - running = true; thread = std::thread([this](F&& f) { while (!die.load()) f(); - running = false; }, std::forward(func)); } + ~GameThread(void) { + thread.join(); + } + void stop(void) { die.store(true); - while (running) - std::this_thread::sleep_for(2ms); } }; @@ -133,6 +133,10 @@ int main(int argc, char *argv[]) // // ///////////////////////////// + + game::engine.getSystem()->add("Debug", 3); + + std::list eventQueue; if (!worldDontReallyRun) { diff --git a/src/inventory.cpp b/src/inventory.cpp index de18104..354db9c 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -4,39 +4,16 @@ #include #include #include +#include -#include +#include #include using namespace tinyxml2; constexpr const char* itemsPath = "config/items.xml"; - -struct Item { - std::string name; - std::string type; - int value; - int stackSize; - Texture sprite; - - Item(void) - : value(0), stackSize(1) {} - - Item(XMLElement *e) { - name = e->StrAttribute("name"); - type = e->StrAttribute("type"); - - value = 0; - e->QueryIntAttribute("value", &value); - stackSize = 1; - e->QueryIntAttribute("maxStackSize", &stackSize); - - sprite = Texture(e->StrAttribute("sprite")); - } -}; - -static std::deque itemList; +static std::unordered_map itemList; void InventorySystem::configure(entityx::EventManager &ev) { @@ -52,7 +29,7 @@ void InventorySystem::loadItems(void) { UserError("No items found"); do { - itemList.emplace_back(item); + itemList.emplace(item->StrAttribute("name"), item); item = item->NextSiblingElement("item"); } while (item != nullptr); } @@ -66,11 +43,6 @@ void InventorySystem::update(entityx::EntityManager &en, entityx::EventManager & void InventorySystem::render(void) { - Render::textShader.use(); - Render::textShader.enable(); - Colors::black.use(); - glUniform4f(Render::textShader.uniform[WU_tex_color], 1, 1, 1, .8); - // calculate positions items.front().loc = vec2(offset.x - 35 * items.size(), offset.y - game::SCREEN_HEIGHT / 2); for (unsigned int i = 1; i < items.size(); i++) @@ -78,17 +50,40 @@ void InventorySystem::render(void) // draw items for (const auto& i : items) { + // draw the slot + Render::textShader.use(); + Render::textShader.enable(); + + Colors::black.use(); + glUniform4f(Render::textShader.uniform[WU_tex_color], 1, 1, 1, .8); glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, Colors::texCoord); vec2 end = i.loc + 64; GLfloat coords[18] = { - i.loc.x, i.loc.y, -9, end.x, i.loc.y, -9, end.x, end.y, -9, - end.x, end.y, -9, i.loc.x, end.y, -9, i.loc.x, i.loc.y, -9 + i.loc.x, i.loc.y, -7, end.x, i.loc.y, -7, end.x, end.y, -7, + end.x, end.y, -7, i.loc.x, end.y, -7, i.loc.x, i.loc.y, -7 }; glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords); glDrawArrays(GL_TRIANGLES, 0, 6); + glUniform4f(Render::textShader.uniform[WU_tex_color], 1, 1, 1, 1); + + // draw the item + if (i.item != nullptr) { + i.item->sprite.use(); + static const GLfloat tex[12] = {0,1,1,1,1,0,1,0,0,0,0,1}; + glVertexAttribPointer(Render::textShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex); + vec2 end = i.loc + i.item->sprite.getDim(); + GLfloat coords[18] = { + i.loc.x, i.loc.y, -7.1, end.x, i.loc.y, -7.1, end.x, end.y, -7.1, + end.x, end.y, -7.1, i.loc.x, end.y, -7.1, i.loc.x, i.loc.y, -7.1 + }; + glVertexAttribPointer(Render::textShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coords); + glDrawArrays(GL_TRIANGLES, 0, 6); + ui::setFontZ(-7.2); + ui::putText(i.loc.x, i.loc.y, std::to_string(i.count).c_str()); + ui::setFontZ(-6); + } } - glUniform4f(Render::textShader.uniform[WU_tex_color], 1, 1, 1, 1); Render::textShader.disable(); Render::textShader.unuse(); } @@ -97,3 +92,14 @@ void InventorySystem::receive(const KeyDownEvent &kde) { (void)kde; } + +void InventorySystem::add(const std::string& name, int count) +{ + for (auto& i : items) { + if (i.count == 0) { + i.item = &itemList[name]; + i.count = count; + break; + } + } +} -- cgit v1.2.3