@ -34,20 +34,29 @@ Pathing compute_paths() {
Pathing paths { matrix : : width ( walls_copy ) , matrix : : height ( walls_copy ) } ;
Pathing paths { matrix : : width ( walls_copy ) , matrix : : height ( walls_copy ) } ;
level . world - > query < components : : Position > (
// first, put everything of this type as a target
[ & ] ( const auto ent , auto & position ) {
level . world - > query < components : : Position , Comp > (
[ & ] ( const auto ent , auto & position , auto & ) {
if ( ent ! = level . player ) {
if ( ent ! = level . player ) {
if ( level . world - > has < Comp > ( ent ) ) {
paths . set_target ( position . location ) ;
paths . set_target ( position . location ) ;
}
} else {
} ) ;
// this will mark that spot as a wall so we don't path there temporarily
walls_copy [ position . location . y ] [ position . location . x ] = WALL_PATH_LIMIT ;
level . world - > query < components : : Collision > (
}
[ & ] ( const auto ent , auto & collision ) {
if ( collision . has ) {
auto & pos = level . world - > get < components : : Position > ( ent ) ;
walls_copy [ pos . location . y ] [ pos . location . x ] = WALL_VALUE ;
}
}
} ) ;
} ) ;
paths . compute_paths ( walls_copy ) ;
paths . compute_paths ( walls_copy ) ;
auto pos = GameDB : : player_position ( ) . location ;
matrix : : dump ( " compute_paths walls " , walls_copy , pos . x , pos . y ) ;
matrix : : dump ( " compute_paths input " , paths . $ input , pos . x , pos . y ) ;
matrix : : dump ( " compute_paths paths " , paths . $ paths , pos . x , pos . y ) ;
return paths ;
return paths ;
}
}
@ -57,7 +66,7 @@ DinkyECS::Entity Autowalker::camera_aim() {
if ( level . collision - > something_there ( fsm . $ main_ui . $ rayview - > aiming_at ) ) {
if ( level . collision - > something_there ( fsm . $ main_ui . $ rayview - > aiming_at ) ) {
return level . collision - > get ( fsm . $ main_ui . $ rayview - > aiming_at ) ;
return level . collision - > get ( fsm . $ main_ui . $ rayview - > aiming_at ) ;
} else {
} else {
return 0 ;
return DinkyECS : : NONE ;
}
}
}
}
@ -124,17 +133,19 @@ void Autowalker::path_fail(const std::string& msg, Matrix& bad_paths, Point pos)
bool Autowalker : : path_player ( Pathing & paths , Point & target_out ) {
bool Autowalker : : path_player ( Pathing & paths , Point & target_out ) {
auto & level = GameDB : : current_level ( ) ;
auto & level = GameDB : : current_level ( ) ;
bool found = paths . random_walk ( target_out , false , PATHING_TOWARD , 4 , 8 ) ;
auto found = paths . find_path ( target_out , PATHING_TOWARD , false ) ;
if ( ! found ) {
if ( found = = PathingResult : : FAIL ) {
// failed to find a linear path, try diagonal
// failed to find a linear path, try diagonal
if ( ! paths . random_walk ( target_out , false , PATHING_TOWARD , 8 , 8 ) ) {
if ( paths . find_path ( target_out , PATHING_TOWARD , true ) = = PathingResult : : FAIL ) {
path_fail ( " random_walk " , paths . $ paths , target_out ) ;
path_fail ( " random_walk " , paths . $ paths , target_out ) ;
return false ;
return false ;
}
}
}
}
if ( ! level . map - > can_move ( target_out ) ) {
if ( ! level . map - > can_move ( target_out ) ) {
fmt : : println ( " ----- FAIL MAP IS, cell is {} " , paths . $ paths [ target_out . y ] [ target_out . x ] ) ;
level . map - > dump ( target_out . x , target_out . y ) ;
path_fail ( " level_map->can_move " , paths . $ paths , target_out ) ;
path_fail ( " level_map->can_move " , paths . $ paths , target_out ) ;
return false ;
return false ;
}
}
@ -143,15 +154,18 @@ bool Autowalker::path_player(Pathing& paths, Point& target_out) {
}
}
void Autowalker : : rotate_player ( Point target ) {
void Autowalker : : rotate_player ( Point target ) {
auto rayview = fsm . $ main_ui . $ rayview ;
// auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT;
// auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT;
auto dir = gui : : Event : : ROTATE_LEFT ;
auto dir = gui : : Event : : ROTATE_LEFT ;
fmt : : println ( " ROTATE TO: {},{} aim is {},{} " ,
target . x , target . y , rayview - > aiming_at . x , rayview - > aiming_at . y ) ;
while ( rayview - > aiming_at ! = target ) {
while ( rayview - > aiming_at ! = target ) {
send_event ( dir ) ;
send_event ( 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 ( rayview - > aiming_at = = target , " failed to aim at target " ) ;
}
}
ai : : State Autowalker : : update_state ( ai : : State start ) {
ai : : State Autowalker : : update_state ( ai : : State start ) {
@ -160,10 +174,12 @@ ai::State Autowalker::update_state(ai::State start) {
ai : : set ( start , " no_more_enemies " , enemy_count = = 0 ) ;
ai : : set ( start , " no_more_enemies " , enemy_count = = 0 ) ;
ai : : set ( start , " no_more_items " , item_count = = 0 ) ;
ai : : set ( start , " no_more_items " , item_count = = 0 ) ;
ai : : set ( start , " enemy_found " ,
fsm . in_state ( gui : : State : : IN_COMBAT ) | |
// BUG: so isn't this wrong? we "find" an enemy when we are aiming at one
fsm . in_state ( gui : : State : : ATTACKING ) ) ;
ai : : set ( start , " enemy_found " , found_enemy ( ) ) ;
ai : : set ( start , " health_good " , player_health_good ( ) ) ;
ai : : set ( start , " health_good " , player_health_good ( ) ) ;
ai : : set ( start , " in_combat " ,
ai : : set ( start , " in_combat " ,
fsm . in_state ( gui : : State : : IN_COMBAT ) | |
fsm . in_state ( gui : : State : : IN_COMBAT ) | |
fsm . in_state ( gui : : State : : ATTACKING ) ) ;
fsm . in_state ( gui : : State : : ATTACKING ) ) ;
@ -187,12 +203,15 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) {
start = update_state ( start ) ;
start = update_state ( start ) ;
auto a_plan = ai : : plan ( " Host::actions " , start , goal ) ;
auto a_plan = ai : : plan ( " Host::actions " , start , goal ) ;
auto action = a_plan . script . front ( ) ;
auto action = a_plan . script . front ( ) ;
ai : : dump_script ( " AUTOWALK " , start , a_plan . script ) ;
if ( action . name = = " find_enemy " ) {
if ( action . name = = " find_enemy " ) {
status ( L " FINDING ENEMY " ) ;
status ( L " FINDING ENEMY " ) ;
auto paths = path_to_enemies ( ) ;
auto paths = path_to_enemies ( ) ;
process_move ( paths ) ;
process_move ( paths ) ;
send_event ( gui : : Event : : ATTACK ) ;
face_enemy ( ) ;
} else if ( action . name = = " face_enemy " ) {
face_enemy ( ) ;
} else if ( action . name = = " kill_enemy " ) {
} else if ( action . name = = " kill_enemy " ) {
status ( L " KILLING ENEMY " ) ;
status ( L " KILLING ENEMY " ) ;
@ -213,7 +232,6 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) {
close_status ( ) ;
close_status ( ) ;
log ( L " FINAL ACTION! Autowalk done. " ) ;
log ( L " FINAL ACTION! Autowalk done. " ) ;
fsm . autowalking = false ;
fsm . autowalking = false ;
ai : : dump_script ( " AUTOWALK " , start , a_plan . script ) ;
} else {
} else {
close_status ( ) ;
close_status ( ) ;
dbc : : log ( fmt : : format ( " Unknown action: {} " , action . name ) ) ;
dbc : : log ( fmt : : format ( " Unknown action: {} " , action . name ) ) ;
@ -295,23 +313,25 @@ void Autowalker::process_move(Pathing& paths) {
return ;
return ;
}
}
rotate_player ( target ) ;
if ( rayview - > aiming_at ! = target ) rotate_player ( target ) ;
// what are we aiming at?
send_event ( gui : : Event : : MOVE_FORWARD ) ;
auto aimed_at = camera_aim ( ) ;
if ( aimed_at & & world - > has < components : : InventoryItem > ( aimed_at ) ) {
// NOTE: if we're aiming at an item then pick it up
// for now just loot it then close to get it off the map
send_event ( gui : : Event : : LOOT_ITEM ) ;
send_event ( gui : : Event : : LOOT_OPEN ) ;
} else {
send_event ( gui : : Event : : MOVE_FORWARD ) ;
}
while ( fsm . in_state ( gui : : State : : MOVING ) ) send_event ( gui : : Event : : TICK ) ;
while ( fsm . in_state ( gui : : State : : MOVING ) ) send_event ( gui : : Event : : TICK ) ;
}
}
bool Autowalker : : found_enemy ( ) {
auto world = GameDB : : current_world ( ) ;
auto aimed_at = camera_aim ( ) ;
return aimed_at ! = DinkyECS : : NONE & & world - > has < components : : Combat > ( aimed_at ) ;
}
bool Autowalker : : found_item ( ) {
auto world = GameDB : : current_world ( ) ;
auto aimed_at = camera_aim ( ) ;
return aimed_at ! = DinkyECS : : NONE & & world - > has < components : : InventoryItem > ( aimed_at ) ;
}
void Autowalker : : send_event ( gui : : Event ev ) {
void Autowalker : : send_event ( gui : : Event ev ) {
fsm . event ( ev ) ;
fsm . event ( ev ) ;
fsm . render ( ) ;
fsm . render ( ) ;
@ -345,8 +365,14 @@ bool Autowalker::face_enemy() {
auto [ found , neighbors ] = level . collision - > neighbors ( player_at . location , true ) ;
auto [ found , neighbors ] = level . collision - > neighbors ( player_at . location , true ) ;
if ( found ) {
if ( found ) {
fmt : : println ( " FOUND ENEMIES: " ) ;
for ( auto & ent : neighbors ) {
auto enemy_pos = level . world - > get < components : : Position > ( ent ) ;
fmt : : println ( " \t {}={},{} " , ent , enemy_pos . location . x , enemy_pos . location . y ) ;
}
auto enemy_pos = level . world - > get < components : : Position > ( neighbors [ 0 ] ) ;
auto enemy_pos = level . world - > get < components : : Position > ( neighbors [ 0 ] ) ;
rotate_player ( enemy_pos . location ) ;
if ( rayview - > aiming_at ! = enemy_pos . location ) rotate_player ( enemy_pos . location ) ;
} else {
} else {
dbc : : log ( " No enemies nearby, moving on. " ) ;
dbc : : log ( " No enemies nearby, moving on. " ) ;
}
}