diff --git a/Makefile b/Makefile index 27ba792..c03917b 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ tracy_build: meson compile -j 10 -C builddir test: build - ./builddir/runtests -d yes + ./builddir/runtests -d yes "[systems-engine]" run: build test ifeq '$(OS)' 'Windows_NT' @@ -48,7 +48,7 @@ else endif debug: build - gdb --nx -x .gdbinit --ex run --args builddir/runtests + gdb --nx -x .gdbinit --ex run --args builddir/runtests "[systems-engine]" debug_run: build gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/zedcaster @@ -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 + gdb --nx -x .gdbinit --ex run --ex bt --ex q --args builddir/runtests "[systems-engine]" win_installer: powershell 'start "C:\Program Files (x86)\solicus\InstallForge\bin\ifbuilderenvx86.exe" scripts\win_installer.ifp' diff --git a/src/game/autowalker.cpp b/src/game/autowalker.cpp deleted file mode 100644 index 6ab5450..0000000 --- a/src/game/autowalker.cpp +++ /dev/null @@ -1,420 +0,0 @@ -#include "game/autowalker.hpp" -#include "ai/ai_debug.hpp" -#include "game/level.hpp" -#include "game/systems.hpp" - -struct InventoryStats { - int healing = 0; - int other = 0; -}; - -template -int number_left() { - int count = 0; - auto world = GameDB::current_world(); - auto player = GameDB::the_player(); - - world->query( - [&](const auto ent, auto&, auto&) { - if(ent != player) { - count++; - } - }); - - return count; -} - -template -Pathing compute_paths() { - auto& level = GameDB::current_level(); - auto walls_copy = level.map->$walls; - - Pathing paths{matrix::width(walls_copy), matrix::height(walls_copy)}; - - System::multi_path(level, paths, walls_copy); - - return paths; -} - -DinkyECS::Entity Autowalker::camera_aim() { - auto& level = GameDB::current_level(); - auto player_pos = GameDB::player_position(); - - // what happens if there's two things at that spot - if(level.collision->something_there(player_pos.aiming_at)) { - return level.collision->get(player_pos.aiming_at); - } else { - return DinkyECS::NONE; - } -} - -void Autowalker::log(std::wstring msg) { - fsm.$map_ui.log(msg); -} - -void Autowalker::status(std::wstring msg) { - fsm.$main_ui.$overlay_ui.show_text("bottom", msg); -} - -void Autowalker::close_status() { - fsm.$main_ui.$overlay_ui.close_text("bottom"); -} - -Pathing Autowalker::path_to_enemies() { - return compute_paths(); -} - -Pathing Autowalker::path_to_items() { - return compute_paths(); -} - -void Autowalker::handle_window_events() { - fsm.$window.handleEvents( - [&](const sf::Event::KeyPressed &) { - fsm.autowalking = false; - close_status(); - log(L"Aborting autowalk."); - }, - [&](const sf::Event::MouseButtonPressed &) { - fsm.autowalking = false; - close_status(); - log(L"Aborting autowalk."); - } - ); -} - -void Autowalker::process_combat() { - while(fsm.in_state(gui::State::IN_COMBAT) - || fsm.in_state(gui::State::ATTACKING)) - { - if(fsm.in_state(gui::State::ATTACKING)) { - send_event(game::Event::TICK); - } else { - send_event(game::Event::ATTACK); - } - } -} - -void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos) { - dbc::log(msg); - status(L"PATH FAIL"); - matrix::dump("MOVE FAIL PATHS", bad_paths, pos.x, pos.y); - log(L"Autowalk failed to find a path."); - send_event(game::Event::BOSS_START); -} - -bool Autowalker::path_player(Pathing& paths, Point& target_out) { - auto& level = GameDB::current_level(); - auto found = paths.find_path(target_out, PATHING_TOWARD, false); - - if(found == PathingResult::FAIL) { - // failed to find a linear path, try diagonal - if(paths.find_path(target_out, PATHING_TOWARD, true) == PathingResult::FAIL) { - path_fail("random_walk", paths.$paths, target_out); - return false; - } - } - - if(!level.map->can_move(target_out)) { - path_fail("level_map->can_move", paths.$paths, target_out); - return false; - } - - return true; -} - -void Autowalker::rotate_player(Point target) { - auto &player = GameDB::player_position(); - - if(target == player.location) { - dbc::log("player stuck at a locatoin"); - fsm.autowalking = false; - return; - } - - auto dir = System::shortest_rotate(player.location, player.aiming_at, target); - - for(int i = 0; player.aiming_at != target; i++) { - if(i > 10) { - dbc::log("HIT OVER ROTATE BUG!"); - break; - } - - send_event(dir); - - while(fsm.in_state(gui::State::ROTATING) || - fsm.in_state(gui::State::COMBAT_ROTATE)) - { - send_event(game::Event::TICK); - } - } - - fsm.autowalking = player.aiming_at == target; -} - -void Autowalker::update_state(ai::EntityAI& player_ai) { - int enemy_count = number_left(); - int item_count = number_left(); - - player_ai.set_state("no_more_enemies", enemy_count == 0); - player_ai.set_state("no_more_items", item_count == 0); - - player_ai.set_state("enemy_found", found_enemy()); - player_ai.set_state("health_good", player_health_good()); - - player_ai.set_state("in_combat", - fsm.in_state(gui::State::IN_COMBAT) || - fsm.in_state(gui::State::ATTACKING)); - - auto inv = player_item_count(); - player_ai.set_state("have_item", inv.other > 0 || inv.healing > 0); - player_ai.set_state("have_healing", inv.healing > 0); - - player_ai.update(); -} - -void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { - ai::EntityAI player_ai("Host::actions", start, goal); - update_state(player_ai); - auto level = GameDB::current_level(); - - if(player_ai.wants_to("find_enemy")) { - status(L"FINDING ENEMY"); - auto paths = path_to_enemies(); - process_move(paths, [&](auto target) -> bool { - return level.collision->occupied(target); - }); - face_enemy(); - } else if(player_ai.wants_to("kill_enemy")) { - status(L"KILLING ENEMY"); - - if(fsm.in_state(gui::State::IN_COMBAT)) { - if(face_enemy()) { - process_combat(); - } - } - } else if(player_ai.wants_to("use_healing")) { - status(L"USING HEALING"); - player_use_healing(); - } else if(player_ai.wants_to("collect_items") || player_ai.wants_to("find_healing")) { - fmt::println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - status(player_ai.wants_to("collect_items") ? L"COLLECTING ITEMS" : L"FIND HEALING"); - player_ai.dump(); - - auto paths = path_to_items(); - - bool found_it = process_move(paths, [&](auto target) -> bool { - if(!level.collision->something_there(target)) return false; - - auto entity = level.collision->get(target); - return level.world->has(entity); - }); - - if(found_it) pickup_item(); - fmt::println("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - } else if(!player_ai.active()) { - close_status(); - log(L"FINAL ACTION! Autowalk done."); - fsm.autowalking = false; - } else { - close_status(); - dbc::log($F("Unknown action: {}", player_ai.to_string())); - } -} - -void Autowalker::open_map() { - if(!map_opened_once) { - if(!fsm.$map_open) { - send_event(game::Event::MAP_OPEN); - map_opened_once = true; - } - } -} - -void Autowalker::close_map() { - if(fsm.$map_open) { - send_event(game::Event::MAP_OPEN); - } -} - -void Autowalker::autowalk() { - handle_window_events(); - if(!fsm.autowalking) { - close_status(); - return; - } - - open_map(); - face_enemy(); - - int move_attempts = 0; - - auto start = ai::load_state("Host::initial_state"); - auto goal = ai::load_state("Host::final_state"); - - do { - handle_window_events(); - handle_player_walk(start, goal); - - close_map(); - - move_attempts++; - } while(move_attempts < 100 && fsm.autowalking); -} - -bool Autowalker::process_move(Pathing& paths, std::function is_that_it) { - // target has to start at the player location then... - auto target_out = GameDB::player_position().location; - - // ... target gets modified as an out parameter to find the path - if(!path_player(paths, target_out)) { - close_status(); - log(L"No paths found, aborting autowalk."); - return false; - } - - if(rayview->aiming_at != target_out) rotate_player(target_out); - - bool found_it = is_that_it(target_out); - - if(!found_it) { - send_event(game::Event::MOVE_FORWARD); - while(fsm.in_state(gui::State::MOVING)) send_event(game::Event::TICK); - } - - return found_it; -} - -bool Autowalker::found_enemy() { - auto& level = GameDB::current_level(); - auto player = GameDB::player_position(); - - for(matrix::compass it{level.map->$walls, player.location.x, player.location.y}; it.next();) { - Point aim{it.x, it.y}; - auto aimed_ent = level.collision->occupied_by(player.aiming_at); - if(aim != player.aiming_at || aimed_ent == DinkyECS::NONE) continue; - - if(level.world->has(aimed_ent)) return true; - } - - return false; -} - -bool Autowalker::found_item() { - auto world = GameDB::current_world(); - auto aimed_at = camera_aim(); - return aimed_at != DinkyECS::NONE && world->has(aimed_at); -} - -void Autowalker::send_event(game::Event ev, std::any data) { - fsm.event(ev, data); - fsm.render(); - fsm.handle_world_events(); -} - -bool Autowalker::player_health_good() { - auto world = GameDB::current_world(); - auto player = GameDB::the_player(); - auto combat = world->get(player); - float health = float(combat.hp) / float(combat.max_hp); - return health > 0.5f; -} - -InventoryStats Autowalker::player_item_count() { - InventoryStats stats; - auto& level = GameDB::current_level(); - auto& inventory = level.world->get(level.player); - - if(inventory.has("pocket_r")) { - stats.other += 1; - stats.healing += 1; - } - - if(inventory.has("pocket_l")) { - stats.other += 1; - stats.healing += 1; - } - - return stats; -} - -void Autowalker::player_use_healing() { - auto& level = GameDB::current_level(); - auto& inventory = level.world->get(level.player); - - if(inventory.has("pocket_r")) { - auto gui_id = fsm.$status_ui.$gui.entity("pocket_r"); - send_event(game::Event::USE_ITEM, gui_id); - } - - if(inventory.has("pocket_l")) { - auto gui_id = fsm.$status_ui.$gui.entity("pocket_l"); - send_event(game::Event::USE_ITEM, gui_id); - } -} - -void Autowalker::start_autowalk() { - fsm.autowalking = true; -} - -void Autowalker::face_target(Point target) { - if(rayview->aiming_at != target) rotate_player(target); -} - -bool Autowalker::face_enemy() { - auto& level = GameDB::current_level(); - auto player_at = GameDB::player_position(); - - auto [found, neighbors] = level.collision->neighbors(player_at.location, true); - - if(found) { - auto enemy_pos = level.world->get(neighbors[0]); - face_target(enemy_pos.location); - } else { - dbc::log("No enemies nearby, moving on."); - } - - return found; -} - -void Autowalker::click_inventory(const std::string& name, guecs::Modifiers mods) { - auto& cell = fsm.$status_ui.$gui.cell_for(name); - fsm.$status_ui.mouse(cell.mid_x, cell.mid_y, mods); - fsm.handle_world_events(); -} - -void Autowalker::pocket_potion(GameDB::Level &level) { - auto& inventory = level.world->get(level.player); - - if(inventory.has("pocket_r") && inventory.has("pocket_l")) { - player_use_healing(); - } - - send_event(game::Event::AIM_CLICK); - - if(inventory.has("pocket_r")) { - click_inventory("pocket_l", {1 << guecs::ModBit::left}); - } else { - click_inventory("pocket_r", {1 << guecs::ModBit::left}); - } -} - -void Autowalker::pickup_item() { - auto& level = GameDB::current_level(); - auto& player_pos = GameDB::player_position(); - auto collision = level.collision; - - if(collision->something_there(player_pos.aiming_at)) { - auto entity = collision->get(player_pos.aiming_at); - fmt::println("AIMING AT entity {} @ {},{}", - entity, player_pos.aiming_at.x, player_pos.aiming_at.y); - - if(level.world->has(entity)) { - pocket_potion(level); - status(L"A POTION"); - } else { - send_event(game::Event::AIM_CLICK); - status(L"I DON'T KNOW"); - } - } -} diff --git a/src/game/autowalker.hpp b/src/game/autowalker.hpp deleted file mode 100644 index 8fb405b..0000000 --- a/src/game/autowalker.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -#include "ai/ai.hpp" -#include "gui/fsm.hpp" -#include - -struct InventoryStats; - -struct Autowalker { - int enemy_count = 0; - int item_count = 0; - int device_count = 0; - bool map_opened_once = false; - gui::FSM& fsm; - std::shared_ptr rayview; - - Autowalker(gui::FSM& fsm) - : fsm(fsm), rayview(fsm.$main_ui.$rayview) {} - - void autowalk(); - void start_autowalk(); - void open_map(); - void close_map(); - bool found_enemy(); - bool found_item(); - - void handle_window_events(); - void handle_player_walk(ai::State& start, ai::State& goal); - - void send_event(game::Event ev, std::any data={}); - void process_combat(); - bool process_move(Pathing& paths, std::function cb); - bool path_player(Pathing& paths, Point &target_out); - void path_fail(const std::string& msg, Matrix& bad_paths, Point pos); - void rotate_player(Point target); - void log(std::wstring msg); - void status(std::wstring msg); - void close_status(); - bool player_health_good(); - void player_use_healing(); - InventoryStats player_item_count(); - void update_state(ai::EntityAI& player_ai); - DinkyECS::Entity camera_aim(); - - Pathing path_to_enemies(); - Pathing path_to_items(); - void face_target(Point target); - bool face_enemy(); - void pickup_item(); - void pocket_potion(GameDB::Level &level); - void click_inventory(const std::string& name, guecs::Modifiers mods); -}; diff --git a/src/game/systems.cpp b/src/game/systems.cpp index 1c21c54..d01fb93 100644 --- a/src/game/systems.cpp +++ b/src/game/systems.cpp @@ -366,10 +366,6 @@ void System::device(World &world, Entity actor, Entity item) { for(auto event : device.events) { if(event == "STAIRS_DOWN") { world.send(game::Event::STAIRS_DOWN, actor, device); - } else if(event == "STAIRS_UP") { - world.send(game::Event::STAIRS_UP, actor, device); - } else if(event == "TRAP") { - world.send(game::Event::TRAP, actor, device); } else if(event == "LOOT_CONTAINER") { world.send(game::Event::LOOT_CONTAINER, actor, device); } else { @@ -388,25 +384,6 @@ void System::move_player(Position move_to) { level.collision->move(old_pos.location, move_to.location, level.player); } - -void System::player_status() { - auto& level = GameDB::current_level(); - auto& combat = level.world->get(level.player); - float percent = float(combat.hp) / float(combat.max_hp); - - if(percent > 0.8) { - sound::play("hp_status_80"); - } else if(percent > 0.6) { - sound::play("hp_status_60"); - } else if(percent > 0.3) { - sound::play("hp_status_30"); - } else if(percent > 0.1) { - sound::play("hp_status_10"); - } else { - sound::play("hp_status_00"); - } -} - std::shared_ptr System::sprite_effect(Entity entity) { auto world = GameDB::current_world(); if(auto se = world->get_if(entity)) { @@ -497,96 +474,6 @@ bool System::inventory_occupied(Entity container_id, const std::string& name) { return inventory.has(name); } - -void System::draw_map(Matrix& grid, EntityGrid& entity_map) { - auto& level = GameDB::current_level(); - auto& world = *level.world; - Map &map = *level.map; - Matrix &fow = level.lights->$fow; - size_t view_x = matrix::width(grid) - 1; - size_t view_y = matrix::height(grid) - 1; - - entity_map.clear(); - - auto player_pos = world.get(level.player).location; - Point cam_orig = map.center_camera(player_pos, view_x, view_y); - auto &tiles = map.tiles(); - auto &tile_set = textures::get_map_tile_set(); - - /* I'm doing double tid->wchar_t conversion here, maybe just - * render the tids into the grid then let someone else do this. */ - - // first fill it with the map cells - for(shiterator::each_cell_t it{grid}; it.next();) { - size_t tile_y = size_t(it.y) + cam_orig.y; - size_t tile_x = size_t(it.x) + cam_orig.x; - - if(matrix::inbounds(tiles, tile_x, tile_y) && fow[tile_y][tile_x]) { - size_t tid = tiles[tile_y][tile_x]; - grid[it.y][it.x] = tile_set[tid]; - } else { - grid[it.y][it.x] = L' '; - } - } - - // then get the enemy/item/device tiles and fill those in - world.query([&](auto, auto &pos, auto &entity_glyph) { - // BUG: don't I have a within bounds macro somewhere? - if(pos.location.x >= cam_orig.x - && pos.location.x <= cam_orig.x + view_x - && pos.location.y >= cam_orig.y - && pos.location.y <= cam_orig.y + view_y) - { - if(fow[pos.location.y][pos.location.x]) { - Point view_pos = map.map_to_camera(pos.location, cam_orig); - entity_map.insert_or_assign(view_pos, entity_glyph.display); - } - } - }); -} - -void System::render_map(Matrix& tiles, EntityGrid& entity_map, sf::RenderTexture& render, int compass_dir, wchar_t player_display) { - sf::Vector2i tile_sprite_dim{MAP_TILE_DIM,MAP_TILE_DIM}; - unsigned int width = matrix::width(tiles); - unsigned int height = matrix::height(tiles); - sf::Vector2u dim{width * tile_sprite_dim.x, height * tile_sprite_dim.y}; - auto render_size = render.getSize(); - - if(render_size.x != width || render_size.y != height) { - bool worked = render.resize(dim); - dbc::check(worked, "Failed to resize map render target."); - } - - render.clear({0,0,0,255}); - - for(matrix::each_row it{tiles}; it.next();) { - wchar_t display = tiles[it.y][it.x]; - if(display == L' ') continue; // skip for now - auto& sprite = textures::get_map_sprite(display); - sprite.setPosition({float(it.x * tile_sprite_dim.x), float(it.y * tile_sprite_dim.y)}); - render.draw(sprite); - } - - for(auto [point, display] : entity_map) { - auto& sprite = textures::get_map_sprite(display); - - if(display == player_display) { - sf::Vector2f center{float(tile_sprite_dim.x / 2), float(tile_sprite_dim.y / 2)}; - float degrees = (((compass_dir * 45) + PLAYER_SPRITE_DIR_CORRECTION) % 360); - - sprite.setOrigin(center); - sprite.setRotation(sf::degrees(degrees)); - sprite.setPosition({float(point.x * tile_sprite_dim.x) + center.x, float(point.y * tile_sprite_dim.y) + center.y}); - } else { - sprite.setPosition({float(point.x * tile_sprite_dim.x), float(point.y * tile_sprite_dim.y)}); - } - - render.draw(sprite); - } - - render.display(); -} - bool System::use_item(const string& slot_name) { auto& level = GameDB::current_level(); auto& world = *level.world; diff --git a/src/game/systems.hpp b/src/game/systems.hpp index 2de17f7..b1edd4e 100644 --- a/src/game/systems.hpp +++ b/src/game/systems.hpp @@ -28,7 +28,6 @@ namespace System { void combat(int attack_id); std::shared_ptr sprite_effect(Entity entity); - void player_status(); void distribute_loot(Position target_pos); void pickup(); @@ -40,9 +39,6 @@ namespace System { void inventory_swap(Entity container_id, const std::string& a_name, const std::string &b_name); bool inventory_occupied(Entity container_id, const std::string& name); - void draw_map(Matrix& grid, EntityGrid& entity_map); - void render_map(Matrix& tiles, EntityGrid& entity_map, sf::RenderTexture& render, int compass_dir, wchar_t player_display); - void set_position(DinkyECS::World& world, SpatialMap& collision, Entity entity, Position pos); bool use_item(const std::string& slot_name); diff --git a/src/gui/fsm.cpp b/src/gui/fsm.cpp index 59c1e9d..8a7686a 100644 --- a/src/gui/fsm.cpp +++ b/src/gui/fsm.cpp @@ -49,11 +49,7 @@ namespace gui { // BUG: maybe this is a function on main_ui? auto cell = $main_ui.overlay_cell("left"); $debug_ui.init(cell); - $status_ui.init(); - $map_ui.init(); - $map_ui.log(L"Welcome to the game!"); - run_systems(); state(State::IDLE); @@ -154,14 +150,10 @@ namespace gui { $main_ui.plan_rotate(1, DEFAULT_ROTATE); state(State::ROTATING); break; - case MAP_OPEN: - $map_open = !$map_open; - break; case ATTACK: state(State::ATTACKING); break; case COMBAT_START: - $map_open = false; state(State::IN_COMBAT); break; case CLOSE: @@ -362,10 +354,6 @@ namespace gui { if($loot_ui.active) $loot_ui.render($window); if(in_state(State::LOOTING)) $dnd_loot.render(); - - if($map_open) { - $map_ui.render($window, $main_ui.$compass_dir); - } } void FSM::update() { @@ -409,18 +397,6 @@ namespace gui { switch(evt) { case eGUI::COMBAT: { auto &damage = std::any_cast(data); - - if(damage.enemy_did > 0) { - $map_ui.log($F(L"Enemy HIT YOU for {} damage!", damage.enemy_did)); - } else { - $map_ui.log(L"Enemy MISSED YOU."); - } - - if(damage.player_did > 0) { - $map_ui.log($F(L"You HIT enemy for {} damage!", damage.player_did)); - } else { - $map_ui.log(L"You MISSED the enemy."); - } } break; case eGUI::COMBAT_START: @@ -463,9 +439,6 @@ namespace gui { $loot_ui.update(); event(Event::LOOT_OPEN); } break; - case eGUI::HP_STATUS: - System::player_status(); - break; case eGUI::ATTACK: event(Event::ATTACK, data); break; @@ -483,7 +456,6 @@ namespace gui { case eGUI::NOOP: { if(data.type() == typeid(std::string)) { auto name = std::any_cast(data); - $map_ui.log($F(L"NOOP EVENT! {},{}", evt, entity)); } } break; default: diff --git a/src/gui/fsm.hpp b/src/gui/fsm.hpp index 791183b..0610626 100644 --- a/src/gui/fsm.hpp +++ b/src/gui/fsm.hpp @@ -6,7 +6,6 @@ #include "gui/main_ui.hpp" #include "gui/status_ui.hpp" #include "gui/loot_ui.hpp" -#include "gui/map_view.hpp" #include "events.hpp" #include "gui/event_router.hpp" #include "gui/dnd_loot.hpp" @@ -30,11 +29,9 @@ namespace gui { sf::RenderWindow $window; bool $draw_stats = false; bool autowalking = false; - bool $map_open = false; DebugUI $debug_ui; MainUI $main_ui; StatusUI $status_ui{STATUS_UI_X, STATUS_UI_Y, STATUS_UI_WIDTH, STATUS_UI_HEIGHT}; - MapViewUI $map_ui; LootUI $loot_ui; gui::routing::Router $router; DNDLoot $dnd_loot; diff --git a/src/gui/map_view.cpp b/src/gui/map_view.cpp deleted file mode 100644 index 8b21214..0000000 --- a/src/gui/map_view.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "map_view.hpp" -#include -#include -#include "dbc.hpp" -#include "game/components.hpp" -#include "algos/rand.hpp" -#include "game/systems.hpp" -#include "algos/rand.hpp" -#include -#include -#include -#include -#include "graphics/palette.hpp" -#include "game/level.hpp" - -constexpr const int MAP_WIDTH=13; -constexpr const int MAP_HEIGHT=13; - -namespace gui { - using namespace components; - using namespace guecs; - - MapViewUI::MapViewUI() : - $map_render(std::make_shared()), - $map_sprite($map_render->getTexture()), - $map_tiles(matrix::make(MAP_WIDTH, MAP_HEIGHT)) - { - auto world = GameDB::current_world(); - auto player = GameDB::the_player(); - $player_display = world->get(player).display; - } - - void MapViewUI::init() { - $gui.position(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - $gui.layout("[log_view| *%(200)map_grid | _ ]"); - $gui.set($gui.MAIN, {$gui.$parser, palette::get("tiles/fg:wall_plain")}); - - $log_to = $gui.entity("log_view"); - $gui.set($log_to, {10, THEME.DARK_MID, THEME.BORDER_COLOR, 10}); - $gui.set($log_to, {L"Welcome to the Game!", 25, THEME.TEXT_COLOR, 10}); - - auto map_cell = lel::center(MAP_TILE_DIM * MAP_WIDTH, MAP_TILE_DIM * MAP_HEIGHT, $gui.cell_for("map_grid")); - $map_sprite.setPosition({(float)map_cell.x, (float)map_cell.y + 30}); - - $gui.init(); - } - - void MapViewUI::render(sf::RenderWindow &window, int compass_dir) { - $gui.render(window); - System::draw_map($map_tiles, $entity_map); - System::render_map($map_tiles, $entity_map, *$map_render, compass_dir, $player_display); - $map_sprite.setTexture($map_render->getTexture(), true); - window.draw($map_sprite); - // $gui.debug_layout(window); - } - - void MapViewUI::update() { - if(auto text = $gui.get_if($log_to)) { - //BUG: I'm calling this what it is, fix it - wstring log_garbage; - for(auto msg : $messages) { - log_garbage += msg + L"\n"; - } - text->update(log_garbage); - } - } - - void MapViewUI::log(wstring msg) { - $messages.push_front(msg); - if($messages.size() > MAX_LOG_MESSAGES) { - $messages.pop_back(); - } - update(); - } -} diff --git a/src/gui/map_view.hpp b/src/gui/map_view.hpp deleted file mode 100644 index 8d64e35..0000000 --- a/src/gui/map_view.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include "graphics/textures.hpp" -#include "algos/matrix.hpp" -#include -#include -#include "algos/dinkyecs.hpp" -#include "game/map.hpp" - -namespace gui { - class MapViewUI { - public: - guecs::UI $gui; - wchar_t $player_display = L'@'; - DinkyECS::Entity $log_to; - EntityGrid $entity_map; - std::deque $messages; - std::shared_ptr $map_render; - sf::Sprite $map_sprite; - matrix::Matrix $map_tiles; - - MapViewUI(); - void init(); - void render(sf::RenderWindow &window, int compass_dir); - void log(std::wstring msg); - void update(); - }; -} diff --git a/src/main.cpp b/src/main.cpp index 6f356c7..a889731 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,6 @@ #include "gui/fsm.hpp" #include "graphics/textures.hpp" #include "game/sound.hpp" -#include "game/autowalker.hpp" #include "ai/ai.hpp" #include #include "graphics/shaders.hpp" @@ -19,19 +18,13 @@ int main(int argc, char* argv[]) { ai::init("ai"); GameDB::init(); cinematic::init(); - sound::mute(true); gui::FSM main; main.event(game::Event::START); - Autowalker walker(main); sound::play("ambient_1", true); - if(argc > 1 && argv[1][0] == 't') { - walker.start_autowalk(); - } - while(main.active()) { main.update(); main.render(); @@ -41,11 +34,7 @@ int main(int argc, char* argv[]) { || main.in_state(gui::State::LOOTING) || main.in_state(gui::State::IN_COMBAT)) { - if(main.autowalking) { - walker.autowalk(); - } else { - main.handle_keyboard_mouse(); - } + main.handle_keyboard_mouse(); } else{ main.event(game::Event::TICK); } diff --git a/src/meson.build b/src/meson.build index a04566c..35ec50d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -18,7 +18,6 @@ sources = files( 'gui/loot_ui.cpp', 'gui/status_ui.cpp', 'gui/main_ui.cpp', - 'gui/map_view.cpp', 'gui/overlay_ui.cpp', # graphics @@ -45,7 +44,6 @@ sources = files( 'game/map.cpp', 'game/level.cpp', 'game/inventory.cpp', - 'game/autowalker.cpp', 'game/sound.cpp', 'game/systems.cpp', 'game/components.cpp', diff --git a/tests/map.cpp b/tests/map.cpp index cf9ef69..7e044bf 100644 --- a/tests/map.cpp +++ b/tests/map.cpp @@ -52,34 +52,3 @@ TEST_CASE("map placement test", "[map-fail]") { } } } - -TEST_CASE("map image test", "[map]") { - GameDB::init(); - - auto& level = GameDB::current_level(); - Matrix map_tiles = matrix::make(7,7); - EntityGrid entity_map; - - auto render = std::make_shared(); - sf::Sprite sprite{render->getTexture()}; - auto player = level.world->get_the(); - auto& player_pos = level.world->get(player.entity); - auto player_display = level.world->get(player.entity).display; - - for(matrix::each_row it{level.map->walls()}; it.next();) { - player_pos.location.x = it.x; - player_pos.location.y = it.y; - System::draw_map(map_tiles, entity_map); - System::render_map(map_tiles, entity_map, *render, 2, player_display); - - // randomly test about 80% of them - if(Random::uniform(0, 100) < 20) break; - -#ifdef TEST_RENDER - // confirm we get two different maps - auto out_img = render->getTexture().copyToImage(); - bool worked = out_img.saveToFile(fmt::format("tmp/map_render{}{}.png", it.x, it.y)); - REQUIRE(worked); -#endif - } -} diff --git a/tests/systems.cpp b/tests/systems.cpp index 18c6384..55c7308 100644 --- a/tests/systems.cpp +++ b/tests/systems.cpp @@ -34,3 +34,105 @@ TEST_CASE("figure out best rotation direction", "[systems-rotate]") { } } } + +using MovingFunc = std::function; +using CombatFunc = std::function; +using RenderFunc = std::function; +using UpdateFunc = std::function; +using UseFunc = std::function; +using PickupFunc = std::function; + +struct Engine { + std::vector $moving; + std::vector $combat; + std::vector $render; + std::vector $update; + std::vector $use; + std::vector $pickup; + + void addMoving(MovingFunc action) { + $moving.emplace_back(action); + } + + void addCombat(CombatFunc action) { + $combat.emplace_back(action); + } + + void addRender(RenderFunc action) { + $render.emplace_back(action); + } + + void addUpdate(UpdateFunc action) { + $update.emplace_back(action); + } + + void addUse(UseFunc action) { + $use.emplace_back(action); + } + + void addPickup(PickupFunc action) { + $pickup.emplace_back(action); + } + + void runMoving() { + for(auto func : $moving) { + func(); + } + } + + void runCombat(bool attr) { + for(auto func : $combat) { + func(attr); + } + } + + void runRender() { + for(auto func : $render) { + func(); + } + } + + void runUpdate() { + for(auto func : $update) { + func(); + } + } + + void runUse() { + for(auto func : $use) { + func(); + } + } + + void runPickup() { + for(auto func : $pickup) { + func(); + } + } +}; + +void test_system_1() { + fmt::println("TEST 1"); +} + +void test_combat(bool what) { + fmt::println("TEST 2: {}", what); +} + +TEST_CASE("new system running engine thing", "[systems-engine]") { + Engine systems; + + systems.addMoving(test_system_1); + systems.addCombat(test_combat); + systems.addRender(test_system_1); + systems.addUpdate(test_system_1); + systems.addUse(test_system_1); + systems.addPickup(test_system_1); + + systems.runCombat(false); + systems.runMoving(); + systems.runRender(); + systems.runUpdate(); + systems.runUse(); + systems.runPickup(); +}