|
|
|
@ -1,9 +1,29 @@ |
|
|
|
|
#include "autowalker.hpp" |
|
|
|
|
|
|
|
|
|
Pathing Autowalker::compute_paths() { |
|
|
|
|
Pathing paths{fsm.$level.map->width(), fsm.$level.map->height()}; |
|
|
|
|
enemy_count = 0; |
|
|
|
|
|
|
|
|
|
fsm.$level.world->query<components::Position, components::Combat>( |
|
|
|
|
[&](const auto ent, auto& position, auto&) { |
|
|
|
|
if(ent != fsm.$level.player) { |
|
|
|
|
paths.set_target(position.location); |
|
|
|
|
enemy_count++; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
void Autowalker::autowalk() { |
|
|
|
|
fmt::println("I'M WALKIN' HEAR!"); |
|
|
|
|
fmt::println("PATHING to {} count enemies", enemy_count); |
|
|
|
|
|
|
|
|
|
// BUG: using walls() will cause a map full of walls?
|
|
|
|
|
dbc::check(matrix::width(fsm.$level.map->$walls) == paths.$width, "WTF the maps's walls width changed?"); |
|
|
|
|
dbc::check(matrix::height(fsm.$level.map->$walls) == paths.$height, "WTF the maps's walls height changed?"); |
|
|
|
|
|
|
|
|
|
paths.compute_paths(fsm.$level.map->$walls); |
|
|
|
|
|
|
|
|
|
return paths; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Autowalker::window_events() { |
|
|
|
|
fsm.$window.handleEvents( |
|
|
|
|
[&](const sf::Event::KeyPressed &) { |
|
|
|
|
fsm.autowalking = false; |
|
|
|
@ -14,35 +34,44 @@ void Autowalker::autowalk() { |
|
|
|
|
fmt::println("ABORT AUTOWALK"); |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!fsm.autowalking) return; |
|
|
|
|
|
|
|
|
|
while(fsm.in_state(gui::State::IN_COMBAT) || fsm.in_state(gui::State::ATTACKING)) { |
|
|
|
|
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)) { |
|
|
|
|
fsm.event(gui::Event::TICK); |
|
|
|
|
send_event(gui::Event::TICK); |
|
|
|
|
} else { |
|
|
|
|
fsm.event(gui::Event::ATTACK); |
|
|
|
|
send_event(gui::Event::ATTACK); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fsm.handle_world_events(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Point Autowalker::get_current_position() { |
|
|
|
|
auto& player_position = fsm.$level.world->get<components::Position>(fsm.$level.player); |
|
|
|
|
auto current = player_position.location; |
|
|
|
|
Point target = current; |
|
|
|
|
bool found = fsm.$level.map->neighbors(target, false, -1); |
|
|
|
|
return player_position.location; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Autowalker::path_player(Pathing& paths, Point& target_out) { |
|
|
|
|
bool found = paths.random_walk(target_out, false, PATHING_TOWARD); |
|
|
|
|
|
|
|
|
|
if(!found) { |
|
|
|
|
dbc::log("no neighbor found, aborting autowalk"); |
|
|
|
|
fsm.autowalking = false; |
|
|
|
|
return; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!fsm.$level.map->can_move(target)) { |
|
|
|
|
if(!fsm.$level.map->can_move(target_out)) { |
|
|
|
|
dbc::log("neighbors is telling me to go to a bad spot."); |
|
|
|
|
fsm.autowalking = false; |
|
|
|
|
return; |
|
|
|
|
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); |
|
|
|
|
|
|
|
|
@ -79,32 +108,65 @@ void Autowalker::autowalk() { |
|
|
|
|
auto dir = facing < target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT; |
|
|
|
|
|
|
|
|
|
while(facing != target_facing) { |
|
|
|
|
fsm.event(dir); |
|
|
|
|
fsm.render(); |
|
|
|
|
fsm.handle_world_events(); |
|
|
|
|
send_event(dir); |
|
|
|
|
facing = fsm.$main_ui.$compass_dir; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
dbc::check(fsm.$main_ui.$compass_dir == target_facing, |
|
|
|
|
"player isn't facing the correct direction"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!fsm.in_state(gui::State::IN_COMBAT)) { |
|
|
|
|
if(fsm.in_state(gui::State::ATTACKING)) { |
|
|
|
|
fsm.event(gui::Event::TICK); |
|
|
|
|
} else { |
|
|
|
|
fsm.event(gui::Event::MOVE_FORWARD); |
|
|
|
|
} |
|
|
|
|
void Autowalker::autowalk() { |
|
|
|
|
window_events(); |
|
|
|
|
if(!fsm.autowalking) return; |
|
|
|
|
|
|
|
|
|
fsm.handle_world_events(); |
|
|
|
|
process_combat(); |
|
|
|
|
auto paths = compute_paths(); |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
fmt::println("IN WHILE MOVING"); |
|
|
|
|
fsm.event(gui::Event::TICK); |
|
|
|
|
fsm.event(gui::Event::ATTACK); |
|
|
|
|
fsm.render(); |
|
|
|
|
fsm.handle_world_events(); |
|
|
|
|
} while(fsm.in_state(gui::State::MOVING)); |
|
|
|
|
Point current = get_current_position(); |
|
|
|
|
Point target = current; |
|
|
|
|
|
|
|
|
|
matrix::dump("AUTO PATHS", paths.$paths, current.x, current.y); |
|
|
|
|
|
|
|
|
|
if(!path_player(paths, target)) { |
|
|
|
|
dbc::log("no paths found, aborting autowalk"); |
|
|
|
|
fsm.autowalking = false; |
|
|
|
|
return; |
|
|
|
|
} else if(enemy_count == 0) { |
|
|
|
|
dbc::log("Nobody left to kill. You win."); |
|
|
|
|
fsm.autowalking = false; |
|
|
|
|
return; |
|
|
|
|
} else { |
|
|
|
|
dbc::log("Hunting down more enemies."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rotate_player(current, target); |
|
|
|
|
|
|
|
|
|
int move_attempts = 0; |
|
|
|
|
do { |
|
|
|
|
process_combat(); |
|
|
|
|
process_move(); |
|
|
|
|
// BUG: sometimes in idle but there's an enemy near but combat hasn't started
|
|
|
|
|
// for now just toss out an ATTACK and it'll be ignored or cause combat
|
|
|
|
|
send_event(gui::Event::ATTACK); |
|
|
|
|
move_attempts++; |
|
|
|
|
} while(move_attempts < 100 && !player_has_moved(target)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Autowalker::process_move() { |
|
|
|
|
send_event(gui::Event::MOVE_FORWARD); |
|
|
|
|
while(fsm.in_state(gui::State::MOVING)) send_event(gui::Event::TICK); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Autowalker::player_has_moved(Point target) { |
|
|
|
|
Point current = get_current_position(); |
|
|
|
|
return current.x == target.x && current.y == target.y; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Autowalker::send_event(gui::Event ev) { |
|
|
|
|
fsm.event(ev); |
|
|
|
|
fsm.render(); |
|
|
|
|
fsm.handle_world_events(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Autowalker::start_autowalk() { |
|
|
|
|