Autowalker now walks more accurately to locations, fights enemies, and also picks up loot drops and healing items _only_.

This commit is contained in:
Zed A. Shaw 2025-09-04 23:40:36 -04:00
parent 40b2d7f45d
commit f03a3a31a8
2 changed files with 58 additions and 21 deletions

View file

@ -67,7 +67,7 @@ Pathing Autowalker::path_to_enemies() {
}
Pathing Autowalker::path_to_items() {
return compute_paths<components::InventoryItem>();
return compute_paths<components::Curative>();
}
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<components::Curative>(entity) ||
level.world->has<ritual::JunkPile>(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<bool(Point)> 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);
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<components::Position>(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<components::Curative>(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");
}
}
}

View file

@ -31,10 +31,10 @@ struct Autowalker {
void send_event(gui::Event ev);
void process_combat();
bool process_move(Pathing& paths, std::function<bool(Point)> 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();
};