From 2938a1783179eed29180c7c575bb4247a15e9d5d Mon Sep 17 00:00:00 2001 From: Adrian Hedqvist Date: Tue, 9 Jan 2018 22:13:52 +0100 Subject: [PATCH 1/5] Update README.md Updated screenshot --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bc05cf8..0a432c3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A work-in-progress, cross-platform roguelike written in C++ using SDL2 and OpenGL. -![Screenshot](https://i.imgur.com/apzKOmm.png) +![Screenshot](https://i.imgur.com/aKUhgCz.png) ## Compiling From 9557a88ed46a9e1e9aa3994762f9ec1dd7e051f1 Mon Sep 17 00:00:00 2001 From: Adrian Hedqvist Date: Tue, 9 Jan 2018 22:15:19 +0100 Subject: [PATCH 2/5] Update README.md Updated todo list --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0a432c3..366afc2 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ I heavily recommend you to use [vcpkg](https://github.com/Microsoft/vcpkg) to in * [ ] Data editors? * [ ] Dungeon generation * [x] Generate rooms & corridors - * [ ] Place entrance & exit - * [ ] Place enemies + * [x] Place entrance & exit + * [x] Place enemies * [ ] Prefabs * [ ] Items * [ ] Inventory From 6bbca15092f53671b850dcf38eb399d9a61afa54 Mon Sep 17 00:00:00 2001 From: Adrian Hedqvist Date: Wed, 10 Jan 2018 09:53:40 +0100 Subject: [PATCH 3/5] blargh --- CMakeLists.txt | 12 ++- src/Mapgen.cpp | 260 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Shader.cpp | 117 ++++++++++++++++++++++ src/Shader.h | 27 +++++ 4 files changed, 415 insertions(+), 1 deletion(-) create mode 100644 src/Mapgen.cpp create mode 100644 src/Shader.cpp create mode 100644 src/Shader.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c4cf22e..e253000 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,4 +36,14 @@ link_libraries( ) file(GLOB SOURCES "src/*.cpp" "src/*.c" "src/*.h") -add_executable(dungeon ${SOURCES}) +add_executable(${TARGET} ${SOURCES}) + +#target_link_libraries(${TARGET} PUBLIC glbinding::glbinding) +#target_link_libraries(${TARGET} PUBLIC ${SDL2_LIBRARY}) +#target_link_libraries(${TARGET} PUBLIC ${OPENGL_LIBRARY}) +#target_link_libraries(${TARGET} PUBLIC ${LUA_LIBRARY}) + +target_link_libraries(${TARGET} PUBLIC glbinding::glbinding) +target_link_libraries(${TARGET} PUBLIC SDL2) +target_link_libraries(${TARGET} PUBLIC OpenGL) +target_link_libraries(${TARGET} PUBLIC lua) diff --git a/src/Mapgen.cpp b/src/Mapgen.cpp new file mode 100644 index 0000000..b4c0512 --- /dev/null +++ b/src/Mapgen.cpp @@ -0,0 +1,260 @@ +#include "Mapgen.h" +#include "vec2i.h" +#include +#include +#include +#include "Rng.h" +#include + +struct Room { + vec2i pos; + vec2i size; +}; + +const char walltile = '#'; +const char floortile = '.'; +const char doortile = '+'; +const char testtile = ' '; + +bool aabb(Room &a, Room &b) { + return a.pos.x <= b.pos.x + b.size.x && a.pos.x + a.size.x >= b.pos.x && + a.pos.y <= b.pos.y + b.size.y && a.pos.y + a.size.y >= b.pos.y; +} + +void maze_fill(Tilemap& map, int x, int y, Rng &rng) { + if (map.get_tile(x, y) != walltile) return; + + const std::vector dirs { vec2i(0,1), vec2i(1,0), vec2i(0,-1), vec2i(-1,0) }; + + std::vector stack { vec2i(x,y) }; + while (!stack.empty()) { + vec2i pos = stack.back(); + map.set_tile(pos.x, pos.y, floortile); + std::vector options; + for (vec2i dir : dirs) { + vec2i next = { pos.x + dir.x, pos.y + dir.y }; + if (map.get_tile(next.x, next.y) != walltile) continue; + if (next.x == 0 || next.x == map.get_width() - 1 || next.y == 0 || next.y == map.get_height() - 1) continue; + + int up = dir.y <= 0 ? 1 : 0; + int down = dir.y >= 0 ? 1 : 0; + int left = dir.x <= 0 ? 1 : 0; + int right = dir.x >= 0 ? 1 : 0; + + std::vector neigh = map.get_neighbours(next.x, next.y, up, down, left, right); + bool enclosed = true; + for (vec2i n : neigh) { + if (map.get_tile(n.x, n.y) != walltile) { + enclosed = false; + break; + } + } + + if (enclosed) { + options.emplace_back(next.x, next.y); + } + } + if (!options.empty()) { + stack.emplace_back(options.at(rng.get_int(options.size() - 1))); + } + else { + stack.pop_back(); + } + } + +} + +Tilemap generate_dungeon(int width, int height) { + return generate_dungeon(Rng::get_random_seed(), width, height); +} + +Tilemap generate_dungeon(unsigned int seed, int width, int height) { + Tilemap map = Tilemap(width, height); + + // Set the whole map to walls + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + map.set_tile(x, y, walltile); + } + } + + Rng rng = Rng(seed); + + // Room placement + std::vector rooms; + for (int i = 0; i < sqrt(width*height); i++) { + Room room; + room.size = vec2i(rng.get_int(6, 12), rng.get_int(6, 12)); + room.pos = vec2i(rng.get_int(width - room.size.x), rng.get_int(height - room.size.y)); + + // Check if the room overlaps with some other room + bool coll = false; + for (Room r : rooms) { + if (aabb(room, r)) { + coll = true; + break; + } + } + if (!coll) { + rooms.emplace_back(room); + } + } + + // Fill the rooms with floor tiles + for (Room r : rooms) { + for (int x = r.pos.x+1; x < r.pos.x + r.size.x-1; x++) { + for (int y = r.pos.y+1; y < r.pos.y + r.size.y-1; y++) { + map.set_tile(x, y, floortile); + } + } + } + + // Maze generation + std::vector maze_start_points; + for (int x = 0; x < map.get_width(); x++) { + for (int y = 0; y < map.get_height(); y++) { + std::vector neigh = map.get_neighbours(x, y, 1); + int count = 0; + for (vec2i n : neigh) { + if (map.get_tile(n.x, n.y) == walltile) count++; + } + // If this tile is a wall and is completely surrounded by other walls, start generating a maze here. + if (count >= 8) { + maze_fill(map, x, y, rng); + maze_start_points.emplace_back(vec2i(x, y)); + } + } + } + + // Door placement + for (Room r : rooms) { + std::vector potential_doors; + for (int y = 0; y < r.size.y; y++) { + for (int x = 0; x < r.size.x; x++) { + // if we are at the rooms walls, but not the corners + if ((x == 0 || x == r.size.x-1) != (y == 0 || y == r.size.y - 1)) { + int dx = 0; + if (x == 0) { + dx = -1; + } + else if (x == r.size.x-1) { + dx = 1; + } + + int dy = 0; + if (y == 0) { + dy = -1; + } + else if (y == r.size.y-1) { + dy = 1; + } + + // If there is a floor tile on the other side of this room wall + if (map.get_tile(r.pos.x+x+dx, r.pos.y+y+dy) == floortile) { + potential_doors.emplace_back(r.pos.x + x, r.pos.y + y); + } + } + } + } + /* Debug thing, place doors at all potential spots + for (vec2i pos : potential_doors) { + map.set_tile(pos.x, pos.y, doortile); + } + /*/ + if (potential_doors.empty()) continue; + + // Pick up to 3 spots and place doorss + int doors_amount = potential_doors.size() < 3 ? potential_doors.size() : 4; + doors_amount = rng.get_int(2, doors_amount); + + for (int i = 0; i < doors_amount; i++) { + //for (int i = 0; i < potential_doors.size(); i++) { + if (potential_doors.empty()) break; + + int r = rng.get_int(potential_doors.size()-1); + vec2i pos = potential_doors.at(r); + map.set_tile(pos.x, pos.y, doortile); + potential_doors.erase(r + potential_doors.begin()); + for (int j = potential_doors.size() - 1; j >= 0; j--) { + if ((pos - potential_doors[j]).dist() <= 4) { + potential_doors.erase(j + potential_doors.begin()); + } + } + } + //*/ + } + + // Clean up dead ends in the maze + std::vector dead_ends; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + std::vector neigh{vec2i(x + 1, y), vec2i(x, y + 1), vec2i(x - 1, y), vec2i(x, y - 1) }; + int count = 0; + for (vec2i pos : neigh) { + if (map.get_tile(pos.x, pos.y) == walltile) { + count++; + } + } + if (count >= neigh.size() - 1) { + dead_ends.emplace_back(vec2i(x, y)); + } + } + } + int pass_amount = (width + height)/2; + for (int pass = 0; pass < pass_amount; pass++) { + if (dead_ends.empty()) break; + std::vector new_dead_ends; + for (vec2i pos : dead_ends) { + std::vector neigh { vec2i(pos.x + 1, pos.y), vec2i(pos.x, pos.y + 1), vec2i(pos.x - 1, pos.y), vec2i(pos.x, pos.y - 1) }; + int count = 0; + vec2i next; + for (vec2i n : neigh) { + if (map.get_tile(n.x, n.y) == walltile) { + continue; + } + else { + count++; + next = n; + } + } + if (count == 1) { + map.set_tile(pos.x, pos.y, walltile); + new_dead_ends.emplace_back(next); + } + else if (count == 0) { + map.set_tile(pos.x, pos.y, walltile); + } + } + dead_ends = new_dead_ends; + } + + /* flood-fill the map to see that you can actually reach everywhere + bool started = false; + for (int x = 0; x < map.get_width(); x++) { + for (int y = 0; y < map.get_height(); y++) { + if (map.get_tile(x,y) == floortile) { + std::vector stack{vec2i(x,y)}; + map.set_tile(x, y, testtile); + while (!stack.empty()) { + vec2i pos = stack.back(); + stack.pop_back(); + + auto neigh = map.get_neighbours(pos.x, pos.y); + for (vec2i n : neigh) { + char tile = map.get_tile(n.x, n.y); + if (tile == floortile || tile == doortile) { + map.set_tile(pos.x, pos.y, testtile); + stack.emplace_back(n); + } + } + } + + started = true; + break; + } + } + if (started) break; + } + //*/ + return map; +} diff --git a/src/Shader.cpp b/src/Shader.cpp new file mode 100644 index 0000000..f20a935 --- /dev/null +++ b/src/Shader.cpp @@ -0,0 +1,117 @@ +#include "Shader.h" +#include +#include +#include +#include +#include +#include + +using namespace gl; + +gl::GLint Shader::get_uniform_location(std::string name) { + auto it = uniforms.find(name); + if (it == uniforms.end()) { + GLint loc = glGetUniformLocation(program_id, name.c_str()); + uniforms.insert(std::pair(name, glGetUniformLocation(program_id, name.c_str()))); + return loc; + } + return it->second; +} + +Shader::Shader(std::ifstream vert, std::ifstream frag) { + std::string vsource; + if (vert.is_open()) { + std::string line; + while (getline(vert, line)) { + vsource += line + "\n"; + } + vert.close(); + } + + std::string fsource; + if (frag.is_open()) { + std::string line; + while (getline(frag, line)) { + fsource += line + "\n"; + } + frag.close(); + } + + Shader(vsource, fsource); +} + +Shader::Shader(std::string vertsource, std::string fragsource) { + GLuint vert_id = glCreateShader(GL_VERTEX_SHADER); + GLuint frag_id = glCreateShader(GL_FRAGMENT_SHADER); + + char const * vs = vertsource.c_str(); + glShaderSource(vert_id, 1, &vs, nullptr); + glCompileShader(vert_id); + + char const * fs = fragsource.c_str(); + glShaderSource(frag_id, 1, &fs, nullptr); + glCompileShader(frag_id); + + GLboolean result = GL_FALSE; + int infologlength = 0; + glGetShaderiv(vert_id, GL_COMPILE_STATUS, &result); + glGetShaderiv(vert_id, GL_INFO_LOG_LENGTH, &infologlength); + if (infologlength > 0) { + std::string errorlog(infologlength + 1, ' '); + glGetShaderInfoLog(vert_id, infologlength, NULL, &errorlog[0]); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Errors compiling vertex shader:\n%s\n", &errorlog[0]); + } + + result = GL_FALSE; + infologlength = 0; + glGetShaderiv(frag_id, GL_COMPILE_STATUS, &result); + glGetShaderiv(frag_id, GL_INFO_LOG_LENGTH, &infologlength); + if (infologlength > 0) { + std::string errorlog(infologlength + 1, ' '); + glGetShaderInfoLog(frag_id, infologlength, NULL, &errorlog[0]); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Errors compiling frag shader:\n%s\n", &errorlog[0]); + } + + program_id = glCreateProgram(); + glAttachShader(program_id, vert_id); + glAttachShader(program_id, frag_id); + glLinkProgram(program_id); + + result = GL_FALSE; + infologlength = 0; + glGetShaderiv(program_id, GL_LINK_STATUS, &result); + glGetShaderiv(program_id, GL_INFO_LOG_LENGTH, &infologlength); + if (infologlength > 0) { + std::string errorlog(infologlength + 1, ' '); + glGetShaderInfoLog(program_id, infologlength, NULL, &errorlog[0]); + SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Errors when linking shader program:\n%s\n", &errorlog[0]); + } + + glDetachShader(program_id, vert_id); + glDetachShader(program_id, frag_id); + glDeleteShader(vert_id); + glDeleteShader(frag_id); + + uniform_color = glGetUniformLocation(program_id, "colortint"); + uniform_mvp = glGetUniformLocation(program_id, "MVP"); +} + +void Shader::use() { glUseProgram(program_id); } + +void Shader::set_color_tint(Color col) { glUniform4f(uniform_color, col.r, col.g, col.b, col.a); } + +void Shader::set_mvp(glm::mat4x4 mvp) { glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, &mvp[0][0]); } + +void Shader::set_aux_uniform(std::string name, glm::fvec4 val) { glUniform4f(get_uniform_location(name), val.r, val.g, val.b, val.a); } + +void Shader::set_aux_uniform(std::string name, float val) { + glUniform1f(get_uniform_location(name), val); +} + +Shader::~Shader() {} + +void Shader::erase() { + if (program_id) { + glDeleteShader(program_id); + } +} diff --git a/src/Shader.h b/src/Shader.h new file mode 100644 index 0000000..e28cbd2 --- /dev/null +++ b/src/Shader.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include +#include "Renderer.h" + +class Shader { + gl::GLuint program_id = 0; + gl::GLint uniform_color; + gl::GLint uniform_mvp; + std::map uniforms; + gl::GLint get_uniform_location(std::string name); +public: + Shader(std::ifstream vert, std::ifstream frag); + Shader(std::string vert, std::string frag); + void use(); + void set_color_tint(Color col); + void set_mvp(glm::mat4x4 mvp); + void set_aux_uniform(std::string name, glm::fvec4 val); + void set_aux_uniform(std::string name, float val); + ~Shader(); + void erase(); +}; + From 68d85c5eae9f56716d179283c58d15f4cd9753c1 Mon Sep 17 00:00:00 2001 From: Adrian Hedqvist Date: Wed, 10 Jan 2018 10:10:43 +0100 Subject: [PATCH 4/5] fixes --- src/Mapgen.cpp | 7 ++----- src/PlayState.cpp | 2 +- src/TileSet.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Mapgen.cpp b/src/Mapgen.cpp index 2eacb40..24c9b0b 100644 --- a/src/Mapgen.cpp +++ b/src/Mapgen.cpp @@ -1,9 +1,5 @@ #include "Mapgen.h" -<<<<<<< HEAD #include "vec2i.h" -======= -#include "vec2i.h" ->>>>>>> 9557a88ed46a9e1e9aa3994762f9ec1dd7e051f1 #include #include #include @@ -255,7 +251,8 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height, TileSet tiles // Find the room furthest away from the entrance and make it the exit Pathfinder::DijkstraMap dijk; const float maxv = width+height; - Pathfinder::calc_dijkstra_map(map, std::vector{ startpos }, dijk, maxv); + std::vector goals = { startpos }; + Pathfinder::calc_dijkstra_map(map, goals, dijk, maxv); float exitroomval = 0; Room* exitroom = &startroom; diff --git a/src/PlayState.cpp b/src/PlayState.cpp index 4d600aa..8a3476d 100644 --- a/src/PlayState.cpp +++ b/src/PlayState.cpp @@ -16,7 +16,7 @@ #include "Shaman.h" #include "Rng.h" #include "TileSet.h" -#include +#include InputAction player_action; TileSet tileset; diff --git a/src/TileSet.cpp b/src/TileSet.cpp index ddffb46..caf8891 100644 --- a/src/TileSet.cpp +++ b/src/TileSet.cpp @@ -1,6 +1,6 @@ #include "TileSet.h" -#include -#include +#include +#include Tile null = Tile(); @@ -67,7 +67,7 @@ void TileSet::load_from_table(kaguya::LuaStackRef table) { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Tileset: Missing value wall for tile: %s", key.c_str()); } SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Tileset: Added tile: %s", key.c_str()); - tiles.insert_or_assign(key, t); + tiles[key] = t; if (tiles.count(key) == 0) { SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Tileset: Could not find the tile we just added?!: %s", key.c_str()); } @@ -75,7 +75,7 @@ void TileSet::load_from_table(kaguya::LuaStackRef table) { } void TileSet::add_tile(std::string name, Tile tile) { - tiles.insert_or_assign(name, tile); + tiles[name] = tile; } Tile const& TileSet::get_tile(std::string name) { From e0d1bcad3ad34a9c89f0fb90f29966e82015c5c7 Mon Sep 17 00:00:00 2001 From: Adrian Hedqvist Date: Wed, 17 Jan 2018 10:17:07 +0100 Subject: [PATCH 5/5] Minor tweaks --- data/tiles.lua | 42 +++++++++++++++++++++++++++++++++++++++++- src/Mapgen.cpp | 18 +++++++++++------- src/PlayState.cpp | 15 +++++++++------ src/TileSet.cpp | 2 +- src/Tilemap.cpp | 3 +++ 5 files changed, 65 insertions(+), 15 deletions(-) diff --git a/data/tiles.lua b/data/tiles.lua index 787fd68..754f442 100644 --- a/data/tiles.lua +++ b/data/tiles.lua @@ -21,7 +21,7 @@ local tiles = { }, dungeon_floor = { glyph = '.', - fg = {.8,.8,1,1}, + fg = {.8,.8,.95,1}, bg = {.1,.1,.2,1}, passable = true, opaque = false, @@ -29,6 +29,26 @@ local tiles = { description = "A stone floor", tags = { "dungeon", "stone", "floor" } }, + -- dungeon_floor2 = { + -- glyph = '.', + -- fg = {.85,.85,.9,1}, + -- bg = {.15,.15,.25,1}, + -- passable = true, + -- opaque = false, + -- wall = false, + -- description = "A stone floor", + -- tags = { "dungeon", "stone", "floor" } + -- }, + -- dungeon_floor3 = { + -- glyph = '.', + -- fg = {.75,.75,.95,1}, + -- bg = {.1,.1,.25,1}, + -- passable = true, + -- opaque = false, + -- wall = false, + -- description = "A stone floor", + -- tags = { "dungeon", "stone", "floor" } + -- }, dungeon_entrance = { glyph = '>', fg = {.8,.8,1,1}, @@ -49,6 +69,26 @@ local tiles = { description = "Stone stairs going downwards", tags = { "dungeon", "stone", "exit" } }, + -- grass = { + -- glyph = '"', + -- fg = {.4,.95,.4,1}, + -- bg = {.1,.15,.2,1}, + -- passable = true, + -- opaque = false, + -- wall = false, + -- description = "A patch of grass", + -- tags = { "dungeon", "floor", "grass" } + -- }, + -- moss = { + -- glyph = '.', + -- fg = {.4,.95,.4,1}, + -- bg = {.1,.15,.2,1}, + -- passable = true, + -- opaque = false, + -- wall = false, + -- description = "A patch of moss", + -- tags = { "dungeon", "floor", "moss" } + -- }, } local dijkstra_debug_amount = 100 diff --git a/src/Mapgen.cpp b/src/Mapgen.cpp index 24c9b0b..d034dbe 100644 --- a/src/Mapgen.cpp +++ b/src/Mapgen.cpp @@ -20,6 +20,10 @@ bool aabb(Room &a, Room &b) { a.pos.y <= b.pos.y + b.size.y && a.pos.y + a.size.y >= b.pos.y; } +template T rand_entry(std::vector &vec, Rng &rng) { + return vec[rng.get_int(vec.size()-1)]; +} + void maze_fill(Tilemap& map, int x, int y, std::string wall, std::string floor, Rng &rng) { if (!map.get_tile(x, y).wall) return; @@ -55,7 +59,7 @@ void maze_fill(Tilemap& map, int x, int y, std::string wall, std::string floor, } } if (!options.empty()) { - stack.emplace(options.at(rng.get_int(options.size() - 1))); + stack.emplace(rand_entry(options,rng)); } else { stack.pop(); @@ -87,7 +91,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height, TileSet tiles // Set the whole map to walls for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { - map.set_tile(x, y, wall_tiles[rng.get_int(0, wall_tiles.size()-1)]); + map.set_tile(x, y, rand_entry(wall_tiles, rng)); } } @@ -115,7 +119,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height, TileSet tiles for (Room r : rooms) { for (int x = r.pos.x+1; x < r.pos.x + r.size.x-1; x++) { for (int y = r.pos.y+1; y < r.pos.y + r.size.y-1; y++) { - map.set_tile(x, y, floor_tiles[rng.get_int(0, floor_tiles.size() - 1)]); + map.set_tile(x, y, rand_entry(floor_tiles, rng)); } } } @@ -133,7 +137,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height, TileSet tiles } // If this tile is a wall and is completely surrounded by other walls, start generating a maze here. if (count >= 8) { - maze_fill(map, x, y, wall_tiles[rng.get_int(0, wall_tiles.size() - 1)], floor_tiles[rng.get_int(0, floor_tiles.size() - 1)], rng); + maze_fill(map, x, y, rand_entry(wall_tiles, rng), floor_tiles[rng.get_int(0, floor_tiles.size() - 1)], rng); maze_start_points.emplace_back(vec2i(x, y)); } } @@ -186,7 +190,7 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height, TileSet tiles int r = rng.get_int(potential_doors.size()-1); vec2i pos = potential_doors.at(r); - map.set_tile(pos.x, pos.y, door_tiles[rng.get_int(0, door_tiles.size() - 1)]); + map.set_tile(pos.x, pos.y, rand_entry(door_tiles, rng)); potential_doors.erase(r + potential_doors.begin()); for (int j = potential_doors.size() - 1; j >= 0; j--) { if ((pos - potential_doors[j]).dist() <= 4) { @@ -231,11 +235,11 @@ Tilemap generate_dungeon(unsigned int seed, int width, int height, TileSet tiles } } if (count == 1) { - map.set_tile(pos.x, pos.y, wall_tiles[rng.get_int(0, wall_tiles.size() - 1)]); + map.set_tile(pos.x, pos.y, rand_entry(wall_tiles, rng)); new_dead_ends.emplace_back(next); } else if (count == 0) { - map.set_tile(pos.x, pos.y, wall_tiles[rng.get_int(0, wall_tiles.size() - 1)]); + map.set_tile(pos.x, pos.y, rand_entry(wall_tiles, rng)); } } dead_ends = new_dead_ends; diff --git a/src/PlayState.cpp b/src/PlayState.cpp index 8a3476d..3168bd4 100644 --- a/src/PlayState.cpp +++ b/src/PlayState.cpp @@ -126,15 +126,17 @@ Gamestate *PlayState::update(double delta) { } if (dir != vec2i(0,0)) { if (!actor->move(dir.x, dir.y, &tilemap)) { - vec2i heropos = actor->get_position(); - Actor* act = tilemap.get_actor(heropos.x + dir.x, heropos.y + dir.y); - if(act == nullptr) { + vec2i pos = actor->get_position(); + auto acts = tilemap.get_actors(pos.x + dir.x, pos.y + dir.y, 0); + if(acts.empty()) { SDL_LogVerbose(SDL_LOG_CATEGORY_SYSTEM, "Turn aborted: invalid player action.\n"); player_action = ACTION_NONE; return nullptr; // unable to move and nothing to attack == abort turn } - if (act->is_alive() && act->get_actor_faction() != actor->get_actor_faction()) { - actor->attack(act); + for (Actor* a : acts) { + if (a->is_alive() && a->get_actor_faction() != actor->get_actor_faction()) { + actor->attack(a); + } } } } @@ -240,7 +242,8 @@ void PlayState::draw(double delta) { int sprite = var->get_sprite_id(); Color fg = var->get_sprite_color()*0.35f; - app->renderer->draw_sprite(ascii->get_sprite(sprite), fg, black, margin.x + (offset.x + pos.x) * asciisize.x, margin.y + (offset.y + pos.y) * asciisize.y); + Color bg = tilemap.get_tile(pos.x, pos.y).bg; + app->renderer->draw_sprite(ascii->get_sprite(sprite), fg, bg, margin.x + (offset.x + pos.x) * asciisize.x, margin.y + (offset.y + pos.y) * asciisize.y); } } diff --git a/src/TileSet.cpp b/src/TileSet.cpp index caf8891..49520e2 100644 --- a/src/TileSet.cpp +++ b/src/TileSet.cpp @@ -66,7 +66,7 @@ void TileSet::load_from_table(kaguya::LuaStackRef table) { else { SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Tileset: Missing value wall for tile: %s", key.c_str()); } - SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Tileset: Added tile: %s", key.c_str()); + //SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Tileset: Added tile: %s", key.c_str()); tiles[key] = t; if (tiles.count(key) == 0) { SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "Tileset: Could not find the tile we just added?!: %s", key.c_str()); diff --git a/src/Tilemap.cpp b/src/Tilemap.cpp index 3304849..1869c49 100644 --- a/src/Tilemap.cpp +++ b/src/Tilemap.cpp @@ -111,6 +111,7 @@ Actor * Tilemap::get_actor(int x, int y) { std::vector Tilemap::get_actors(int x, int y, int range) { std::vector found; std::vector neigh = get_neighbours(x, y, range); + neigh.emplace_back(vec2i(x,y)); for (Actor* ent : actors) { for (vec2i pos : neigh) { vec2i apos = ent->get_position(); @@ -157,10 +158,12 @@ void Tilemap::draw(Renderer *renderer, SpriteAtlas* sprites, int x, int y, int t } void Tilemap::debug_print() { + /* for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { printf("\t%d", get_tile(x, y)); } printf("\n"); } + */ }