diff --git a/autowalker.cpp b/autowalker.cpp index 2080f07..c003b04 100644 --- a/autowalker.cpp +++ b/autowalker.cpp @@ -67,7 +67,7 @@ Pathing Autowalker::path_to_enemies() { } Pathing Autowalker::path_to_items() { - return compute_paths(); + return compute_paths(); } void Autowalker::handle_window_events() { @@ -98,17 +98,11 @@ void Autowalker::process_combat() { } void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos) { + dbc::log(msg); status(L"PATH FAIL"); -#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) { @@ -195,12 +189,15 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { start = update_state(start); auto a_plan = ai::plan("Host::actions", start, goal); auto action = a_plan.script.front(); + auto level = GameDB::current_level(); // ai::dump_script("AUTOWALK", start, a_plan.script); if(action.name == "find_enemy") { status(L"FINDING ENEMY"); auto paths = path_to_enemies(); - process_move(paths); + process_move(paths, [&](auto target) -> bool { + return level.collision->occupied(target); + }); face_enemy(); } else if(action.name == "kill_enemy") { status(L"KILLING ENEMY"); @@ -214,11 +211,20 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { status(L"USING HEALING"); player_use_healing(); } else if(action.name == "collect_items") { - send_event(gui::Event::STAIRS_DOWN); - // status(L"COLLECTING ITEMS"); - // auto paths = path_to_items(); - // process_move(paths); - // path to the items and get them all + status(L"COLLECTING ITEMS"); + + 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) || + level.world->has(entity)); + }); + + if(found_it) pickup_item(); } else if(action == ai::FINAL_ACTION) { close_status(); log(L"FINAL ACTION! Autowalk done."); @@ -297,8 +303,7 @@ void Autowalker::autowalk() { } while(move_attempts < 100 && fsm.autowalking); } -void Autowalker::process_move(Pathing& paths) { - auto world = GameDB::current_world(); +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; @@ -306,14 +311,19 @@ void Autowalker::process_move(Pathing& paths) { if(!path_player(paths, target_out)) { close_status(); log(L"No paths found, aborting autowalk."); - return; + return false; } if(rayview->aiming_at != target_out) rotate_player(target_out); - send_event(gui::Event::MOVE_FORWARD); + bool found_it = is_that_it(target_out); - while(fsm.in_state(gui::State::MOVING)) send_event(gui::Event::TICK); + if(!found_it) { + send_event(gui::Event::MOVE_FORWARD); + while(fsm.in_state(gui::State::MOVING)) send_event(gui::Event::TICK); + } + + return found_it; } bool Autowalker::found_enemy() { @@ -363,6 +373,10 @@ 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(); @@ -371,10 +385,31 @@ bool Autowalker::face_enemy() { if(found) { auto enemy_pos = level.world->get(neighbors[0]); - if(rayview->aiming_at != enemy_pos.location) rotate_player(enemy_pos.location); + face_target(enemy_pos.location); } else { dbc::log("No enemies nearby, moving on."); } return found; } + +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(auto curative = level.world->get_if(entity)) { + send_event(gui::Event::AIM_CLICK); + (void)curative; + status(L"A POTION"); + } else { + send_event(gui::Event::AIM_CLICK); + status(L"I DON'T KNOW"); + } + } +} diff --git a/autowalker.hpp b/autowalker.hpp index d3db9d9..2517234 100644 --- a/autowalker.hpp +++ b/autowalker.hpp @@ -31,10 +31,10 @@ struct Autowalker { void send_event(gui::Event ev); 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 process_move(Pathing& paths); void log(std::wstring msg); void status(std::wstring msg); void close_status(); @@ -46,5 +46,7 @@ struct Autowalker { Pathing path_to_enemies(); Pathing path_to_items(); + void face_target(Point target); bool face_enemy(); + void pickup_item(); };