/* * File: flood_find.h * Summary: flood_find template */ #ifndef FLOOD_FIND_H #define FLOOD_FIND_H #include "terrain.h" #include "travel.h" // You can't forward declare typedefs, so do this instead. class map_mask : public FixedArray {} ; extern map_mask dgn_Map_Mask; template class flood_find : public travel_pathfind { public: flood_find(const fgrd &f, const bound_check &bc); void add_feat(int feat); void add_point(const coord_def &pos); coord_def find_first_from(const coord_def &c, const map_mask &vlts); bool points_connected_from(const coord_def &start); bool any_point_connected_from(const coord_def &start); bool has_exit_from(const coord_def &start); bool did_leave_vault() const { return left_vault; } protected: bool path_flood(const coord_def &c, const coord_def &dc); protected: bool point_hunt, want_exit; bool needed_features[NUM_FEATURES]; std::vector needed_points; bool left_vault; const map_mask *vaults; const fgrd &fgrid; const bound_check &bcheck; }; template flood_find::flood_find(const fgrd &f, const bound_check &bc) : travel_pathfind(), point_hunt(false), want_exit(false), needed_features(), needed_points(), left_vault(true), vaults(NULL), fgrid(f), bcheck(bc) { memset(needed_features, false, sizeof needed_features); } template void flood_find::add_feat(int feat) { if (feat >= 0 && feat < NUM_FEATURES) needed_features[feat] = true; } template coord_def flood_find::find_first_from( const coord_def &c, const map_mask &vlts) { set_floodseed(c); vaults = &vlts; return pathfind(RMODE_EXPLORE); } template void flood_find::add_point(const coord_def &c) { needed_points.push_back(c); } template bool flood_find::points_connected_from( const coord_def &sp) { if (needed_points.empty()) return (true); set_floodseed(sp); pathfind(RMODE_EXPLORE); return (needed_points.empty()); } template bool flood_find::any_point_connected_from( const coord_def &sp) { if (needed_points.empty()) return (true); set_floodseed(sp); const size_t sz = needed_points.size(); pathfind(RMODE_EXPLORE); return (needed_points.size() < sz); } template bool flood_find::has_exit_from( const coord_def &sp) { want_exit = true; set_floodseed(sp); return (pathfind(RMODE_EXPLORE) == coord_def(-1, -1)); } template bool flood_find::path_flood( const coord_def &c, const coord_def &dc) { if (!bcheck(dc)) { if (want_exit) { greedy_dist = 100; greedy_place = coord_def(-1, -1); return (true); } return (false); } if (!needed_points.empty()) { std::vector::iterator i = std::find(needed_points.begin(), needed_points.end(), dc); if (i != needed_points.end()) { needed_points.erase(i); if (needed_points.empty()) return (true); } } const dungeon_feature_type feat = fgrid(dc); if (feat == NUM_FEATURES) { if (want_exit) { greedy_dist = 100; greedy_place = coord_def(-1, -1); return (true); } return (false); } if (needed_features[ feat ]) { unexplored_place = dc; unexplored_dist = traveled_distance; return (true); } if (!feat_is_traversable(feat) && feat != DNGN_SECRET_DOOR && !feat_is_trap(feat)) { return (false); } if (!left_vault && vaults && !(*vaults)[dc.x][dc.y]) left_vault = true; good_square(dc); return (false); } #endif