|
|
|
@ -3,22 +3,30 @@ |
|
|
|
|
|
|
|
|
|
template<typename Comp> |
|
|
|
|
Pathing compute_paths(gui::FSM& fsm, int& count_out) { |
|
|
|
|
Pathing paths{fsm.$level.map->width(), fsm.$level.map->height()}; |
|
|
|
|
auto& walls_original = fsm.$level.map->$walls; |
|
|
|
|
auto walls_copy = walls_original; |
|
|
|
|
|
|
|
|
|
Pathing paths{matrix::width(walls_copy), matrix::height(walls_copy)}; |
|
|
|
|
count_out = 0; |
|
|
|
|
|
|
|
|
|
fsm.$level.world->query<components::Position, Comp>( |
|
|
|
|
[&](const auto ent, auto& position, auto&) { |
|
|
|
|
// BUG: using walls() will cause a map full of walls?
|
|
|
|
|
dbc::check(matrix::width(walls_copy) == paths.$width, "WTF the maps's walls width changed?"); |
|
|
|
|
dbc::check(matrix::height(walls_copy) == paths.$height, "WTF the maps's walls height changed?"); |
|
|
|
|
|
|
|
|
|
fsm.$level.world->query<components::Position>( |
|
|
|
|
[&](const auto ent, auto& position) { |
|
|
|
|
if(ent != fsm.$level.player) { |
|
|
|
|
if(fsm.$level.world->has<Comp>(ent)) { |
|
|
|
|
paths.set_target(position.location); |
|
|
|
|
count_out++; |
|
|
|
|
count_out = count_out + 1; |
|
|
|
|
} 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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// 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); |
|
|
|
|
paths.compute_paths(walls_copy); |
|
|
|
|
|
|
|
|
|
return paths; |
|
|
|
|
} |
|
|
|
@ -70,13 +78,11 @@ bool Autowalker::path_player(Pathing& paths, Point& target_out) { |
|
|
|
|
|
|
|
|
|
if(!found) { |
|
|
|
|
dbc::log("no neighbor found, aborting autowalk"); |
|
|
|
|
fsm.autowalking = false; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(!fsm.$level.map->can_move(target_out)) { |
|
|
|
|
dbc::log("neighbors is telling me to go to a bad spot."); |
|
|
|
|
fsm.autowalking = false; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -92,18 +98,14 @@ void Autowalker::rotate_player(Point current, Point target) { |
|
|
|
|
|
|
|
|
|
if(delta_x == -1 && delta_y == 0) { |
|
|
|
|
// west
|
|
|
|
|
fmt::println("WEST: {}, {}", target.x, target.y); |
|
|
|
|
target_facing = 4; |
|
|
|
|
} else if(delta_x == 1 && delta_y == 0) { |
|
|
|
|
// east
|
|
|
|
|
fmt::println("EAST: {}, {}", target.x, target.y); |
|
|
|
|
target_facing = 0; |
|
|
|
|
} else if(delta_x == 0 && delta_y == 1) { |
|
|
|
|
fmt::println("SOUTH: {}, {}", target.x, target.y); |
|
|
|
|
// south
|
|
|
|
|
target_facing = 2; |
|
|
|
|
} else if(delta_x == 0 && delta_y == -1) { |
|
|
|
|
fmt::println("NORTH: {}, {}", target.x, target.y); |
|
|
|
|
// north
|
|
|
|
|
target_facing = 6; |
|
|
|
|
} else { |
|
|
|
@ -117,7 +119,7 @@ void Autowalker::rotate_player(Point current, Point target) { |
|
|
|
|
delta_x, delta_y)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
while(facing != target_facing) { |
|
|
|
|
send_event(dir); |
|
|
|
@ -134,9 +136,25 @@ void Autowalker::autowalk() { |
|
|
|
|
|
|
|
|
|
process_combat(); |
|
|
|
|
auto paths = path_to_enemies(); |
|
|
|
|
if(enemy_count == 0) paths = path_to_items(); |
|
|
|
|
if(item_count == 0) paths = path_to_devices(); |
|
|
|
|
if(device_count == 0) dbc::log("no more enemies, items, or devices."); |
|
|
|
|
|
|
|
|
|
if(enemy_count == 0) { |
|
|
|
|
dbc::log("Killed everything, now finding items."); |
|
|
|
|
paths = path_to_items(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(enemy_count == 0 && item_count == 0) { |
|
|
|
|
dbc::log("No more items, find the exit."); |
|
|
|
|
paths = path_to_devices(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(enemy_count == 0 && |
|
|
|
|
item_count == 0 && |
|
|
|
|
device_count == 0) |
|
|
|
|
{ |
|
|
|
|
fsm.autowalking = false; |
|
|
|
|
dbc::log("no more enemies, items, or devices."); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Point current = get_current_position(); |
|
|
|
|
Point target = current; |
|
|
|
|