diff --git a/autowalker.cpp b/autowalker.cpp index 683c9a8..60d92cd 100644 --- a/autowalker.cpp +++ b/autowalker.cpp @@ -2,6 +2,7 @@ #include "ai_debug.hpp" #include "gui/ritual_ui.hpp" #include "game_level.hpp" +#define DEBUG struct InventoryStats { int healing = 0; @@ -102,20 +103,23 @@ void Autowalker::process_combat() { if(fsm.in_state(gui::State::ATTACKING)) { send_event(gui::Event::TICK); } else { - send_event(gui::Event::ATTACK);; + send_event(gui::Event::ATTACK); } } } -Point Autowalker::get_current_position() { - return GameDB::player_position().location; -} - -void Autowalker::path_fail(Matrix& bad_paths, Point pos) { +void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos) { status(L"PATH FAIL"); - log(L"Autowalk failed to find a path."); +#ifdef DEBUG matrix::dump("MOVE FAIL PATHS", bad_paths, pos.x, pos.y); + dbc::sentinel(fmt::format("[{}]: Autowalk failed to find a path.", msg)); +#else + log(L"Autowalk failed to find a path."); + (void)bad_paths; // shutup compiler errors + (void)pos; + (void)msg; send_event(gui::Event::STAIRS_DOWN); +#endif } bool Autowalker::path_player(Pathing& paths, Point& target_out) { @@ -125,77 +129,29 @@ bool Autowalker::path_player(Pathing& paths, Point& target_out) { if(!found) { // failed to find a linear path, try diagonal if(!paths.random_walk(target_out, false, PATHING_TOWARD, 8, 8)) { - path_fail(paths.$paths, target_out); + path_fail("random_walk", paths.$paths, target_out); return false; } } if(!level.map->can_move(target_out)) { - path_fail(paths.$paths, target_out); + path_fail("level_map->can_move", paths.$paths, target_out); return false; } return true; } -void Autowalker::rotate_player(Point current, Point target) { - int delta_x = int(target.x) - int(current.x); - int delta_y = int(target.y) - int(current.y); +void Autowalker::rotate_player(Point target) { + auto rayview = fsm.$main_ui.$rayview; - int facing = fsm.$main_ui.$compass_dir; - int target_facing = 0; + // auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT; + auto dir = gui::Event::ROTATE_LEFT; - /* This is a massive pile of garbage. Need a way - * to determine player facing direction without - * hacking into the compass, and also do accurate - * turns. - */ - if(delta_x == -1 && delta_y == 0) { - // west - target_facing = 4; - } else if(delta_x == 1 && delta_y == 0) { - // east - target_facing = 0; - } else if(delta_x == 0 && delta_y == 1) { - // south - target_facing = 2; - } else if(delta_x == 0 && delta_y == -1) { - // north - target_facing = 6; - } else if(delta_x == 1 && delta_y == -1) { - // north east - target_facing = 7; - } else if(delta_x == 1 && delta_y == 1) { - // south east - target_facing = 1; - } else if(delta_x == -1 && delta_y == 1) { - // south west - target_facing = 3; - } else if(delta_x == -1 && delta_y == -1) { - // north west - target_facing = 5; - } else { - dbc::sentinel( - fmt::format("got more than 8 direction result: " - "current={},{} " - "target={},{} " - "delta={},{} ", - current.x, current.y, - target.x, target.y, - delta_x, delta_y)); - } - - auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT; - - while(facing != target_facing) { + while(rayview->aiming_at != target) { send_event(dir); - facing = fsm.$main_ui.$compass_dir; + while(fsm.in_state(gui::State::ROTATING)) send_event(gui::Event::TICK); } - - while(fsm.in_state(gui::State::ROTATING)) send_event(gui::Event::TICK); - - dbc::check(fsm.$main_ui.$compass_dir == target_facing, - "player isn't facing the correct direction"); } ai::State Autowalker::update_state(ai::State start) { @@ -240,14 +196,11 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { } else if(action.name == "kill_enemy") { status(L"KILLING ENEMY"); - // TODO: find the enemy and then rotate toward them - Point current = get_current_position(); if(fsm.in_state(gui::State::IN_COMBAT)) { - rotate_player(current, {current.x - 1, current.y - 1}); - dbc::log("TODO: you should find the enemy and face them instead of THIS GARBAGE!"); + if(face_enemy()) { + process_combat(); + } } - - process_combat(); } else if(action.name == "use_healing") { status(L"USING HEALING"); player_use_healing(); @@ -332,16 +285,17 @@ void Autowalker::autowalk() { void Autowalker::process_move(Pathing& paths) { auto world = GameDB::current_world(); - Point current = get_current_position(); - Point target = current; + // target has to start at the player location then... + auto target = GameDB::player_position().location; + // ... target gets modified as an out parameter to find the path if(!path_player(paths, target)) { close_status(); log(L"No paths found, aborting autowalk."); return; } - rotate_player(current, target); + rotate_player(target); // what are we aiming at? auto aimed_at = camera_aim(); @@ -383,3 +337,19 @@ void Autowalker::player_use_healing() { void Autowalker::start_autowalk() { fsm.autowalking = true; } + +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]); + rotate_player(enemy_pos.location); + } else { + dbc::log("No enemies nearby, moving on."); + } + + return found; +} diff --git a/autowalker.hpp b/autowalker.hpp index 1fd6dab..6850055 100644 --- a/autowalker.hpp +++ b/autowalker.hpp @@ -28,9 +28,8 @@ struct Autowalker { void send_event(gui::Event ev); void process_combat(); bool path_player(Pathing& paths, Point &target_out); - void path_fail(Matrix& bad_paths, Point pos); - Point get_current_position(); - void rotate_player(Point current, Point target); + void path_fail(const std::string& msg, Matrix& bad_paths, Point pos); + void rotate_player(Point target); void process_move(Pathing& paths); void log(std::wstring msg); void status(std::wstring msg); @@ -43,4 +42,5 @@ struct Autowalker { Pathing path_to_enemies(); Pathing path_to_items(); + bool face_enemy(); };