diff --git a/Makefile b/Makefile index 455fe3d..27ba792 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) -all: build test +all: build reset: ifeq '$(OS)' 'Windows_NT' @@ -37,7 +37,7 @@ tracy_build: meson compile -j 10 -C builddir test: build - ./builddir/runtests -d yes "[map-fail]" + ./builddir/runtests -d yes run: build test ifeq '$(OS)' 'Windows_NT' @@ -60,7 +60,7 @@ clean: meson compile --clean -C builddir debug_test: build - gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests "[map-fail]" + gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests win_installer: powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp' diff --git a/src/algos/maze.cpp b/src/algos/maze.cpp index d885f42..8646748 100644 --- a/src/algos/maze.cpp +++ b/src/algos/maze.cpp @@ -9,16 +9,6 @@ using std::string; using matrix::Matrix; namespace maze { - inline size_t rand(size_t i, size_t j) { - if(i < j) { - return Random::uniform(i, j); - } else if(j < i) { - return Random::uniform(j, i); - } else { - return i; - } - } - inline bool complete(Matrix& maze, size_t width, size_t height) { for(size_t row = 1; row < height; row += 2) { for(size_t col = 1; col < width; col += 2) { @@ -89,8 +79,9 @@ namespace maze { } bool Builder::room_should_exist(Room& room, bool allow_dupes) { - if(!matrix::inbounds($walls, room.x, room.y) || - !matrix::inbounds($walls, room.x + room.width, room.y + room.height)) + // padding by 1 for the perimeter wall + if(!matrix::inbounds($walls, room.x - 1, room.y - 1) || + !matrix::inbounds($walls, room.x + room.width + 2, room.y + room.height + 2)) { return false; } @@ -187,7 +178,7 @@ namespace maze { $walls[row][col] = 0; } else { // found neighbors, pick random one - auto nb = n[rand(size_t(0), n.size() - 1)]; + auto nb = n[Random::abs(size_t(0), n.size() - 1)]; $walls[nb.y][nb.x] = 0; size_t row = (nb.y + on.y) / 2; @@ -196,12 +187,14 @@ namespace maze { on = nb; } } + + if($rooms.size() > 0) place_rooms(); } void Builder::place_rooms() { for(auto& room : $rooms) { for(matrix::rectangle it{$walls, room.x, room.y, room.width, room.height}; it.next();) { - $walls[it.y][it.x] = 0; + $walls[it.y][it.x] = SPACE_VALUE; } } } @@ -239,7 +232,7 @@ namespace maze { } void Builder::dump(const std::string& msg, bool path_too) { - auto wall_copy = $walls; + Matrix wall_copy = $walls; // mark the rooms too, but not if pathing if(!path_too) { @@ -307,6 +300,11 @@ namespace maze { } } + bool Builder::valid_door(size_t x, size_t y) { + return (space_available(x, y - 1) && space_available(x, y + 1)) // north south + || (space_available(x - 1, y) && space_available(x + 1, y)); + } + void Builder::place_doors() { for(auto room : $rooms) { int best_longest = 0; @@ -319,17 +317,14 @@ namespace maze { // can't path out of the room, so now punch a hole until it can matrix::perimeter it{room.x - 1, room.y - 1, room.width + 2, room.height + 2}; - while(it.next()) { - // don't use corners - if((it.x == room.x - 1 && it.y == room.y - 1) || - (it.x == room.x - 1 && it.y == room.y + 2) || - (it.x == room.width + 2 && it.y == room.y + 2) || - (it.x == room.width + 2 && it.y == room.y - 1)) { - continue; - } + while(it.next()) { if($walls[it.y][it.x] == WALL_VALUE) { + // valid doors are free north/south or east/west + if(!valid_door(it.x, it.y)) continue; + $walls[it.y][it.x] = SPACE_VALUE; + longest = compute_paths(room.x, room.y); // keep track of the best door so far, which is the one with the longest path @@ -348,8 +343,6 @@ namespace maze { $walls[best_door.y][best_door.x] = SPACE_VALUE; $doors.insert_or_assign(best_door, true); } - - fmt::println("map valid after doors? {}", validate()); } void Builder::inner_box(size_t outer_size, size_t inner_size) { @@ -408,7 +401,7 @@ namespace maze { // initial path test can just use one room then look for // any cells that are empty in the walls map but unpathed in the paths - Room test_room = $rooms.at(rand(0, $rooms.size() - 1)); + Room test_room = $rooms.at(Random::abs(size_t(0), $rooms.size() - 1)); compute_paths(test_room.x, test_room.y); for(matrix::each_cell it{$walls}; it.next();) { @@ -422,10 +415,10 @@ namespace maze { } bool Builder::space_available(size_t x, size_t y) { - bool in_bounds = matrix::inbounds($walls, x, y); - bool is_space = $walls[y][x] == SPACE_VALUE; - bool not_perimeter = x > 0 && y > 0 && x < $width - 2 && y < $height - 2; - return in_bounds && is_space && not_perimeter; + return (matrix::inbounds($walls, x, y) && // in bounds + $walls[y][x] == SPACE_VALUE && // is a space + !$doors.contains({x, y}) && // no door there + (x > 0 && y > 0 && x < $width - 2 && y < $height - 2)); // not perimeter; } void Builder::punch_dead_end(size_t at_x, size_t at_y, size_t x, size_t y) { diff --git a/src/algos/maze.hpp b/src/algos/maze.hpp index c3fbbaf..d8c17d3 100644 --- a/src/algos/maze.hpp +++ b/src/algos/maze.hpp @@ -47,6 +47,7 @@ namespace maze { void punch_dead_end(size_t at_x, size_t at_y, size_t x, size_t y); bool space_available(size_t x, size_t y); int compute_paths(size_t x, size_t y); + bool valid_door(size_t x, size_t y); }; std::pair script(Map& map, nlohmann::json& config); diff --git a/src/algos/rand.cpp b/src/algos/rand.cpp index 31aaa96..983e04a 100644 --- a/src/algos/rand.cpp +++ b/src/algos/rand.cpp @@ -9,5 +9,4 @@ namespace Random { int tick = Random::uniform_real(float(from), float(to)); return std::chrono::milliseconds{tick}; } - } diff --git a/src/algos/rand.hpp b/src/algos/rand.hpp index d3ed762..b82e3e4 100644 --- a/src/algos/rand.hpp +++ b/src/algos/rand.hpp @@ -27,5 +27,15 @@ namespace Random { return rand(GENERATOR); } + auto abs(auto i, auto j) { + if(i < j) { + return Random::uniform(i, j); + } else if(j < i) { + return Random::uniform(j, i); + } else { + return i; + } + } + std::chrono::milliseconds milliseconds(int from, int to); } diff --git a/src/combat/battle.cpp b/src/combat/battle.cpp index 2c337fd..ab11e82 100644 --- a/src/combat/battle.cpp +++ b/src/combat/battle.cpp @@ -30,11 +30,6 @@ namespace combat { for(auto& [entity, enemy] : $combatants) { if(enemy.combat->ap < enemy.combat->max_ap) { int new_ap = std::min(enemy.combat->max_ap, enemy.combat->ap_delta + enemy.combat->ap); - - // only add up to the max - fmt::println("enemy {} get more ap {}->{}", - entity, enemy.combat->ap, new_ap); - enemy.combat->ap = new_ap; } } diff --git a/src/constants.hpp b/src/constants.hpp index a69d841..e2f72f1 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -3,39 +3,39 @@ #include #include -constexpr const int INV_SLOTS=16; -constexpr const int TEXTURE_WIDTH=256; -constexpr const int TEXTURE_HEIGHT=256; -constexpr const int RAY_VIEW_WIDTH=900; -constexpr const int RAY_VIEW_HEIGHT=600; -constexpr const int SCREEN_WIDTH=1280; -constexpr const int SCREEN_HEIGHT=720; -constexpr const int RAY_VIEW_X=(SCREEN_WIDTH - RAY_VIEW_WIDTH); -constexpr const int RAY_VIEW_Y=0; -constexpr const int GLOW_LIMIT=220; -constexpr const int LIGHT_MULTIPLIER=2.5; -constexpr const float AIMED_AT_BRIGHTNESS=0.2f; -constexpr const int MAP_TILE_DIM=64; -constexpr const int ICONGEN_MAP_TILE_DIM=64; -constexpr const int PLAYER_SPRITE_DIR_CORRECTION=270; -constexpr const int RENDER_DISTANCE=500; -constexpr const int ROOM_SIZE=3; +constexpr int INV_SLOTS=16; +constexpr int TEXTURE_WIDTH=256; +constexpr int TEXTURE_HEIGHT=256; +constexpr int RAY_VIEW_WIDTH=900; +constexpr int RAY_VIEW_HEIGHT=600; +constexpr int SCREEN_WIDTH=1280; +constexpr int SCREEN_HEIGHT=720; +constexpr int RAY_VIEW_X=(SCREEN_WIDTH - RAY_VIEW_WIDTH); +constexpr int RAY_VIEW_Y=0; +constexpr int GLOW_LIMIT=220; +constexpr int LIGHT_MULTIPLIER=2.5; +constexpr float AIMED_AT_BRIGHTNESS=0.2f; +constexpr int MAP_TILE_DIM=64; +constexpr int ICONGEN_MAP_TILE_DIM=64; +constexpr int PLAYER_SPRITE_DIR_CORRECTION=270; +constexpr int RENDER_DISTANCE=500; +constexpr int ROOM_SIZE=3; -constexpr const int BOSS_VIEW_WIDTH=1080; -constexpr const int BOSS_VIEW_HEIGHT=SCREEN_HEIGHT; -constexpr const int BOSS_VIEW_X=SCREEN_WIDTH - BOSS_VIEW_WIDTH; -constexpr const int BOSS_VIEW_Y=0; +constexpr int BOSS_VIEW_WIDTH=1080; +constexpr int BOSS_VIEW_HEIGHT=SCREEN_HEIGHT; +constexpr int BOSS_VIEW_X=SCREEN_WIDTH - BOSS_VIEW_WIDTH; +constexpr int BOSS_VIEW_Y=0; -constexpr const bool VSYNC=false; -constexpr const int FRAME_LIMIT=60; -constexpr const int NUM_SPRITES=1; -constexpr const int MAX_LOG_MESSAGES=17; +constexpr bool VSYNC=true; +constexpr int FRAME_LIMIT=60; +constexpr int NUM_SPRITES=1; +constexpr int MAX_LOG_MESSAGES=17; #ifdef NDEBUG -constexpr const bool DEBUG_BUILD=false; +constexpr bool DEBUG_BUILD=false; #else -constexpr const bool DEBUG_BUILD=true; +constexpr bool DEBUG_BUILD=true; #endif diff --git a/src/gui/fsm.cpp b/src/gui/fsm.cpp index 9121d29..1d07f1e 100644 --- a/src/gui/fsm.cpp +++ b/src/gui/fsm.cpp @@ -152,11 +152,11 @@ namespace gui { try_move(1, true); break; case ROTATE_LEFT: - $main_ui.plan_rotate(-1, 0.25f); + $main_ui.plan_rotate(-1, DEFAULT_ROTATE); state(State::ROTATING); break; case ROTATE_RIGHT: - $main_ui.plan_rotate(1, 0.25f); + $main_ui.plan_rotate(1, DEFAULT_ROTATE); state(State::ROTATING); break; case MAP_OPEN: diff --git a/tests/battle.cpp b/tests/battle.cpp index 3a38f7e..ecdd3da 100644 --- a/tests/battle.cpp +++ b/tests/battle.cpp @@ -65,18 +65,17 @@ TEST_CASE("battle operations fantasy", "[combat-battle]") { while(auto act = battle.next()) { auto& [enemy, wants_to, cost, enemy_state] = *act; - fmt::println(">>>>> entity: {} wants to {} cost={}; has {} HP; {} ap", - enemy.entity, wants_to, - cost, enemy.combat->hp, - enemy.combat->ap); + // fmt::println(">>>>> entity: {} wants to {} cost={}; has {} HP; {} ap", + // enemy.entity, wants_to, + // cost, enemy.combat->hp, + // enemy.combat->ap); switch(enemy_state) { case BattleHostState::agree: - fmt::println("HOST and PLAYER requests match {}, doing it.", - wants_to); + // fmt::println("HOST and PLAYER requests match {}, doing it.", wants_to); break; case BattleHostState::disagree: - fmt::println("REBELIOUS ACT: {}", wants_to); + // fmt::println("REBELIOUS ACT: {}", wants_to); battle.clear_requests(); REQUIRE(battle.$player_requests.size() == 0); break; @@ -86,7 +85,7 @@ TEST_CASE("battle operations fantasy", "[combat-battle]") { } break; case BattleHostState::out_of_ap: - fmt::println("ENEMY OUT OF AP"); + // fmt::println("ENEMY OUT OF AP"); break; } } diff --git a/tests/map.cpp b/tests/map.cpp index f8e0009..f401ad1 100644 --- a/tests/map.cpp +++ b/tests/map.cpp @@ -25,7 +25,7 @@ TEST_CASE("camera control", "[map]") { Point center = map.center_camera({10,10}, 5, 5); - map.dump(center.x, center.y); + // map.dump(center.x, center.y); REQUIRE(center.x == 8); REQUIRE(center.y == 8); diff --git a/tests/mazes.cpp b/tests/mazes.cpp index 8e855a1..d66a71b 100644 --- a/tests/mazes.cpp +++ b/tests/mazes.cpp @@ -7,7 +7,7 @@ #include "algos/maze.hpp" #include "algos/stats.hpp" -#define DUMP 1 +#define DUMP 0 using std::string; using matrix::Matrix;