diff --git a/src/Actor.cpp b/src/Actor.cpp index bd0e47c..20e9b12 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -2,7 +2,11 @@ #include "Tilemap.h" #include "BehaviourTree.h" +int idcounter = 0; + Actor::Actor(Tilemap * map, vec2i pos) { + id = idcounter++; + name = "Actor"; this->map = map; position = pos; bt = nullptr; diff --git a/src/Actor.h b/src/Actor.h index a696bf2..de97c28 100644 --- a/src/Actor.h +++ b/src/Actor.h @@ -1,5 +1,6 @@ #pragma once #include "vec2i.h" +#include class BehaviourTree; @@ -19,6 +20,8 @@ class Actor { protected: BehaviourTree* bt; public: + int id; + std::string name; Tilemap* map; bool alive; int health; diff --git a/src/App.cpp b/src/App.cpp index e262ed5..31d89c1 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -100,6 +100,9 @@ int App::start() { case SDL_WINDOWEVENT_CLOSE: running = false; break; + case SDL_WINDOWEVENT_RESIZED: + renderer->set_window_size(ev.window.data1, ev.window.data2); + break; default: break; } @@ -154,7 +157,9 @@ int App::start() { SDL_Delay(1); } delete renderer; + ImGui::Shutdown(); SDL_Quit(); + SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Quit."); return 0; } diff --git a/src/Config.cpp b/src/Config.cpp index 08506b4..b780ebd 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -3,12 +3,13 @@ #include #include #include +#include #include #include using namespace std; -bool isFloat(string myString) { +bool isFloat(const string &myString) { istringstream iss(myString); float f; iss >> noskipws >> f; // noskipws considers leading whitespace invalid @@ -16,7 +17,7 @@ bool isFloat(string myString) { return iss.eof() && !iss.fail(); } -bool isInt(string myString) { +bool isInt(const string &myString) { istringstream iss(myString); int i; iss >> noskipws >> i; // noskipws considers leading whitespace invalid @@ -45,7 +46,7 @@ static inline void trim(string &s) { Config::Config(string path) { - this->path = path; + this->path = std::move(path); } void Config::load() { @@ -57,7 +58,7 @@ void Config::load() { if (conf.is_open()) { string line; while (getline(conf, line)) { - int pos = line.find("="); + unsigned int pos = line.find('='); if (pos > 0) { string key = line.substr(0, pos); string value = line.substr(pos + 1, line.length()); @@ -182,5 +183,24 @@ bool Config::getBool(std::string key, bool defaultvalue) { } -Config::~Config() { +Config::~Config() = default; + +void Config::setString(std::string key, std::string value) { + deleteValue(key); + strings.insert(pair{key, value}); +} + +void Config::setInt(std::string key, int value) { + deleteValue(key); + ints.insert(pair{key, value}); +} + +void Config::setFloat(std::string key, float value) { + deleteValue(key); + floats.insert(pair{key, value}); +} + +void Config::setBool(std::string key, bool value) { + deleteValue(key); + bools.insert(pair{key, value}); } diff --git a/src/Config.h b/src/Config.h index a69739d..1201a6e 100644 --- a/src/Config.h +++ b/src/Config.h @@ -17,6 +17,10 @@ public: int getInt(std::string key, int defaultvalue); float getFloat(std::string key, float defaultvalue); bool getBool(std::string key, bool defaultvalue); + void setString(std::string key, std::string value); + void setInt(std::string key, int value); + void setFloat(std::string key, float value); + void setBool(std::string key, bool value); ~Config(); }; diff --git a/src/Goblin.cpp b/src/Goblin.cpp index 6b50bcd..fac0aa4 100644 --- a/src/Goblin.cpp +++ b/src/Goblin.cpp @@ -8,6 +8,7 @@ BehaviourTree* gobtree = nullptr; Goblin::Goblin(Tilemap* map, vec2i pos) : Actor(map, pos) { + name = "Goblin"; alive = true; health = 4; maxhealth = 4; diff --git a/src/Hero.cpp b/src/Hero.cpp index cbb5428..6a1baa8 100644 --- a/src/Hero.cpp +++ b/src/Hero.cpp @@ -9,6 +9,7 @@ #include "FleeNode.h" Hero::Hero(Tilemap* map, vec2i pos) : Actor(map, pos) { + name = "Hero"; alive = true; health = 6; maxhealth = 6; diff --git a/src/PlayState.cpp b/src/PlayState.cpp index 7d1fad0..d6992b0 100644 --- a/src/PlayState.cpp +++ b/src/PlayState.cpp @@ -99,7 +99,7 @@ void PlayState::new_game() { tilemap = new Tilemap(32, 32); int y = 0; int x = 0; - for (int i = 0; i < map.length(); i++) { + for (char i : map) { if (y >= 32) { break; @@ -108,25 +108,25 @@ void PlayState::new_game() { y++; x = 0; } - if (map[i] == ' ' || map[i] == '\t' || map[i] == '\n') { + if (i == ' ' || i == '\t' || i == '\n') { continue; } - if (map[i] == '@') { + if (i == '@') { hero = new Hero(tilemap, vec2i(x, y)); tilemap->add_actor(hero); tilemap->set_tile(x, y, '.'); } - else if (map[i] == 'g') { + else if (i == 'g') { tilemap->add_actor(new Goblin(tilemap, vec2i(x, y))); tilemap->set_tile(x, y, '.'); } - else if (map[i] == 's') { + else if (i == 's') { tilemap->add_actor(new Shaman(tilemap, vec2i(x, y))); tilemap->set_tile(x, y, '.'); } else { - tilemap->set_tile(x, y, map[i]); + tilemap->set_tile(x, y, i); } x++; } @@ -168,10 +168,13 @@ Gamestate *PlayState::update(double delta) { } } } + hero->update(); + fov->calc(hero->get_position(), 6); } auto actors = tilemap->get_actor_list(); for (Actor* var : *actors) { + if (var == hero) continue; var->update(); } for (int i = (int)actors->size() - 1; i >= 0; i--) { @@ -183,38 +186,57 @@ Gamestate *PlayState::update(double delta) { actors->erase(actors->begin() + i); } } - if (hero) { - fov->calc(hero->get_position(), 6); - } action = ACTION_NONE; } return nullptr; } +bool debug_actors = false; +bool debug_settings = false; + void PlayState::draw(double delta) { if (debug) { - bool wireframe = app->renderer->is_wireframes_enabled(); - ImGui::Checkbox("Wireframes", &wireframe); - app->renderer->set_wireframes_enabled(wireframe); - bool vsync = app->renderer->is_vsync_enabled(); - ImGui::Checkbox("VSync", &vsync); - app->renderer->set_vsync_enabled(vsync); + { + ImGui::BeginMainMenuBar(); - ImGui::BeginMainMenuBar(); + if (ImGui::BeginMenu("View")) { + ImGui::MenuItem("Settings", nullptr, &debug_settings); + ImGui::MenuItem("Actors", nullptr, &debug_actors); + ImGui::EndMenu(); + } - if (ImGui::BeginMenu("File")) { - ImGui::EndMenu(); + ImGui::EndMainMenuBar(); } + if (debug_settings) { + ImGui::Begin("Settings", &debug_settings); - if (ImGui::BeginMenu("Edit")) { - ImGui::EndMenu(); + bool wireframe = app->renderer->is_wireframes_enabled(); + ImGui::Checkbox("Wireframes", &wireframe); + app->renderer->set_wireframes_enabled(wireframe); + bool vsync = app->renderer->is_vsync_enabled(); + ImGui::Checkbox("VSync", &vsync); + app->renderer->set_vsync_enabled(vsync); + + ImGui::End(); } + if (debug_actors) { + ImGui::Begin("Actors", &debug_actors); - if (ImGui::BeginMenu("View")) { - ImGui::EndMenu(); + auto actors = tilemap->get_actor_list(); + const char* headers[] { + "id", "name", "health" + }; + static float widths[3]{0.2f, 0.5f, 0.3f}; + ImGui::BeginTable("ActorColumns", headers, widths, 3); + for (Actor* act : *actors) { + ImGui::Text("%d", act->id); ImGui::NextColumn(); + ImGui::Text(act->name.c_str()); ImGui::NextColumn(); + ImGui::Text("%d/%d", act->health, act->maxhealth); ImGui::NextColumn(); + } + ImGui::EndTable(); + + ImGui::End(); } - - ImGui::EndMainMenuBar(); } vec2i asciisize = { diff --git a/src/Renderer.cpp b/src/Renderer.cpp index d85bb8e..2d0ef4f 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -9,21 +9,22 @@ #include "imgui_impl_sdl_gl3.h" #include #include +#include const GLfloat rectVertData[]{ 0,0,0, 1,0,0, 0,1,0, 1,1,0 }; glm::mat4 screenVPmat; -float widthmult; -float heightmult; +double widthmult; +double heightmult; GLuint LoadShader(const char* path, GLenum shadertype) { GLuint shaderId = glCreateShader(shadertype); std::string shadersource; std::ifstream shaderstream(path, std::ios::in); if (shaderstream.is_open()) { - std::string line = ""; + std::string line; while (getline(shaderstream, line)) { shadersource += line + "\n"; } @@ -105,8 +106,8 @@ Renderer::~Renderer() { GLuint shaderProg; GLuint wireShaderProg; GLuint spriteVertArrayId; -GLuint colorUniform; -GLuint mvpUniform; +GLint colorUniform; +GLint mvpUniform; bool Renderer::Init(std::string title, int width, int height) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); @@ -114,7 +115,7 @@ bool Renderer::Init(std::string title, int width, int height) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - window = SDL_CreateWindow(title.data(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); + window = SDL_CreateWindow(title.data(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL /* | SDL_WINDOW_RESIZABLE */); if (window == NULL) { SDL_LogCritical(SDL_LOG_CATEGORY_RENDER,"Failed to create a window!\n"); return false; @@ -164,7 +165,7 @@ bool Renderer::Init(std::string title, int width, int height) { colorUniform = glGetUniformLocation(shaderProg, "colortint"); mvpUniform = glGetUniformLocation(shaderProg, "MVP"); - SetWindowSize(width, height); + set_window_size(width, height); SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Renderer initialized.\n"); return true; @@ -174,35 +175,35 @@ void Renderer::set_color(float r, float g, float b, float a) { currentcolor = { r, g, b, a }; } -void Renderer::SetColor(Color col) { +void Renderer::set_color(Color col) { set_color(col.r, col.g, col.b, col.a); } -void Renderer::SetTitle(const char * title) { +void Renderer::set_title(const char *title) { SDL_SetWindowTitle(window, title); } -void Renderer::SetWindowSize(int width, int height) { +void Renderer::set_window_size(int width, int height) { SDL_SetWindowSize(window, width, height); windowwidth = width; windowheight = height; - widthmult = 1.f / windowwidth * 2; - heightmult = 1.f / windowheight * 2; + widthmult = 1. / windowwidth * 2; + heightmult = 1. / windowheight * 2; glm::mat4 projection = glm::ortho(-1, 1, 1, -1); glm::mat4 view = glm::scale(glm::vec3(widthmult, heightmult, 1)) * glm::translate(glm::vec3(-windowwidth / 2, -windowheight / 2, 0)) * glm::mat4(1); screenVPmat = projection * view; - SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Window size set to %dx%d.\n", width, height); + SDL_LogDebug(SDL_LOG_CATEGORY_RENDER, "Window size set to %dx%d.\n", windowwidth, windowheight); } -void Renderer::SetClearColor(float r, float g, float b, float a) { +void Renderer::set_clear_color(float r, float g, float b, float a) { glClearColor(r, g, b, a); } -void Renderer::SetClearColor(Color col) { +void Renderer::set_clear_color(Color col) { glClearColor(col.r, col.g, col.b, col.a); } @@ -265,7 +266,7 @@ Texture * Renderer::LoadTexture(std::string path) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - Texture t; + Texture t{}; t.id = textureId; t.w = surface->w; t.h = surface->h; @@ -294,10 +295,10 @@ Sprite Renderer::CreateSprite(std::string path, int x, int y, int w, int h) { sprite.region.y = y; sprite.region.w = w; sprite.region.h = h; - sprite.texture = LoadTexture(path); + sprite.texture = LoadTexture(std::move(path)); if (sprite.texture != nullptr) { - float tw = (float)sprite.texture->w; - float th = (float)sprite.texture->h; + auto tw = (float)sprite.texture->w; + auto th = (float)sprite.texture->h; const float uvs[] = { x / tw, y / th, (x + w) / tw, y / th, @@ -319,7 +320,6 @@ void Renderer::draw_sprite(Sprite *sprite, int x, int y, float sx, float sy) { glm::mat4 model = glm::translate(glm::vec3(x, y, 0)) * glm::scale(glm::vec3(sprite->region.w * sx, sprite->region.h * sy, 1)) * glm::mat4(1); glm::mat4 mvp = screenVPmat * model; - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -337,9 +337,9 @@ void Renderer::draw_sprite(Sprite *sprite, int x, int y, float sx, float sy) { glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, spriteVBuf); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, sprite->uvBuf); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); @@ -353,9 +353,9 @@ void Renderer::draw_sprite(Sprite *sprite, int x, int y, float sx, float sy) { glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, spriteVBuf); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindBuffer(GL_ARRAY_BUFFER, sprite->uvBuf); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } diff --git a/src/Renderer.h b/src/Renderer.h index 9122a97..48bcccd 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -47,11 +47,11 @@ public: ~Renderer(); bool Init(std::string title, int width, int height); void set_color(float r, float g, float b, float a); - void SetColor(Color col); - void SetTitle(const char* title); - void SetWindowSize(int width, int height); - void SetClearColor(float r, float g, float b, float a); - void SetClearColor(Color col); + void set_color(Color col); + void set_title(const char *title); + void set_window_size(int width, int height); + void set_clear_color(float r, float g, float b, float a); + void set_clear_color(Color col); void set_vsync_enabled(bool enabled); bool is_vsync_enabled(); void set_wireframes_enabled(bool enabled); diff --git a/src/Shaman.cpp b/src/Shaman.cpp index b37bc00..97e794d 100644 --- a/src/Shaman.cpp +++ b/src/Shaman.cpp @@ -12,6 +12,7 @@ BehaviourTree* shamtree = nullptr; Shaman::Shaman(Tilemap* map, vec2i pos) : Actor(map, pos) { + name = "Shaman"; alive = true; health = 2; maxhealth = 2; diff --git a/src/imconfig.h b/src/imconfig.h index 9d31631..03b5beb 100644 --- a/src/imconfig.h +++ b/src/imconfig.h @@ -14,7 +14,7 @@ //#define IMGUI_API __declspec( dllimport ) //---- Include imgui_user.h at the end of imgui.h -//#define IMGUI_INCLUDE_IMGUI_USER_H +#define IMGUI_INCLUDE_IMGUI_USER_H //---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions) //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS diff --git a/src/imgui_user.cpp b/src/imgui_user.cpp new file mode 100644 index 0000000..f09ad42 --- /dev/null +++ b/src/imgui_user.cpp @@ -0,0 +1,72 @@ +// +// Created by Adrian on 2017-09-23. +// + +#include +#include "imgui.h" + +namespace ImGui { + int BeginTable(const char* columnsId, const char** headers, float* widths, int count, bool draw_border) + { + if(count<=0) + return 0; + + // Draw column headers + ImGuiStyle & style = ImGui::GetStyle(); + const ImVec2 firstTextSize = ImGui::CalcTextSize(headers[0], NULL, true); + + ImGui::BeginChild(columnsId, ImVec2(0,firstTextSize.y + 2 * style.ItemSpacing.y), true); + + char str_id[256]; + sprintf(str_id, "tbl0_%s", columnsId); + ImGui::Columns(count, str_id, draw_border); + + float offset = 0.0f; + for(int i=0; i < count; i++) + { + ImGui::SetColumnOffset(i, offset); + + if(widths[i] <= 0) + { + const ImVec2 textsize = ImGui::CalcTextSize(headers[i], NULL, true); + const float colSizeX = (textsize.x + 2 * style.ItemSpacing.x); + widths[i] = colSizeX + 1; + } + + if(i < (count-1)) + { + float curOffset = offset; + offset = ImGui::GetColumnOffset(i+1); + widths[i] = offset - curOffset + 1; + } + + ImGui::Text(headers[i]); + ImGui::NextColumn(); + } + + ImGui::Columns(1); + ImGui::EndChild(); + + // Draw body + str_id[3] = '1'; + columnsId = str_id; + + ImGui::BeginChild(columnsId, ImVec2(0,0), true); + ImGui::Columns(count, columnsId, draw_border); + + offset = 0.0f; + for(int i=0; i < count; i++) + { + ImGui::SetColumnOffset(i, offset); + offset += widths[i] - 1; + } + + return 1; + } + + void EndTable() + { + ImGui::Columns(1); + ImGui::EndChild(); + } +} diff --git a/src/imgui_user.h b/src/imgui_user.h new file mode 100644 index 0000000..44833ee --- /dev/null +++ b/src/imgui_user.h @@ -0,0 +1,31 @@ +// +// Created by Adrian on 2017-09-23. +// + +#ifndef DUNGEON_IMGUI_USER_H +#define DUNGEON_IMGUI_USER_H + +namespace ImGui { + /* // [table src] https://github.com/ocornut/imgui/issues/513#issuecomment-240388455 + + // Usage: + static const char *headers[] = { + "Index", "Color", "Flip?", "Filename" + }; + static float widths[ IM_ARRAYSIZE(headers) ] = {}; + if( ImGui::BeginTable("WinTextureContent", headers, widths, IM_ARRAYSIZE(headers)) ) { + // Draw as many rows as needed + for( int i = 0; i < 10; ++i ) { + ImGui::Text("%d", i); ImGui::NextColumn(); + ImGui::ColorButton( ImVec4(0.5f,0.2f,i*0.3f,1.f)); ImGui::NextColumn(); + ImGui::Text("%s", i % 2 ? "yes" : "no"); ImGui::NextColumn(); + ImGui::Text(__FILE__); ImGui::NextColumn(); + } + ImGui::EndTable(); + } + */ + int BeginTable(const char* columnsId, const char** headers, float *widths, int count, bool border=true); + void EndTable(); +} + +#endif //DUNGEON_IMGUI_USER_H