summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/flood_find.h
diff options
context:
space:
mode:
authorMatthew Cline <zelgadis@sourceforge.net>2009-11-29 01:08:06 -0800
committerMatthew Cline <zelgadis@sourceforge.net>2009-11-29 01:14:47 -0800
commit7f9e84d7674d4a370c1514f40832afaf654736cc (patch)
treef286f068de02f1470c7db26ec80e5e4e72d66dd1 /crawl-ref/source/flood_find.h
parent83b3d564bcad6422fca7545cb5bc56fd9aa92a1c (diff)
downloadcrawl-ref-7f9e84d7674d4a370c1514f40832afaf654736cc.tar.gz
crawl-ref-7f9e84d7674d4a370c1514f40832afaf654736cc.zip
Reduce dependency on travel.h
Removed inclusion of travel.h from most .h files to reduce the number of .cc files dependant on it. This involved moving the level_pos declaration to externs.h, moving the flood_find template to it's own header file, and moving two typedefs from travel.h to travel_defs.h because typedefs can't be forward declared (argh).
Diffstat (limited to 'crawl-ref/source/flood_find.h')
-rw-r--r--crawl-ref/source/flood_find.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/crawl-ref/source/flood_find.h b/crawl-ref/source/flood_find.h
new file mode 100644
index 0000000000..ad4b6bf310
--- /dev/null
+++ b/crawl-ref/source/flood_find.h
@@ -0,0 +1,173 @@
+/*
+ * 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<unsigned short, GXM, GYM> {} ;
+
+extern map_mask dgn_Map_Mask;
+
+template <typename fgrd, typename bound_check>
+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<coord_def> needed_points;
+ bool left_vault;
+ const map_mask *vaults;
+
+ const fgrd &fgrid;
+ const bound_check &bcheck;
+};
+
+template <typename fgrd, typename bound_check>
+flood_find<fgrd, bound_check>::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 <typename fgrd, typename bound_check>
+void flood_find<fgrd, bound_check>::add_feat(int feat)
+{
+ if (feat >= 0 && feat < NUM_FEATURES)
+ needed_features[feat] = true;
+}
+
+template <typename fgrd, typename bound_check>
+coord_def
+flood_find<fgrd, bound_check>::find_first_from(
+ const coord_def &c,
+ const map_mask &vlts)
+{
+ set_floodseed(c);
+ vaults = &vlts;
+ return pathfind(RMODE_EXPLORE);
+}
+
+template <typename fgrd, typename bound_check>
+void flood_find<fgrd, bound_check>::add_point(const coord_def &c)
+{
+ needed_points.push_back(c);
+}
+
+template <typename fgrd, typename bound_check>
+bool flood_find<fgrd, bound_check>::points_connected_from(
+ const coord_def &sp)
+{
+ if (needed_points.empty())
+ return (true);
+ set_floodseed(sp);
+ pathfind(RMODE_EXPLORE);
+ return (needed_points.empty());
+}
+
+template <typename fgrd, typename bound_check>
+bool flood_find<fgrd, bound_check>::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 <typename fgrd, typename bound_check>
+bool flood_find<fgrd, bound_check>::has_exit_from(
+ const coord_def &sp)
+{
+ want_exit = true;
+ set_floodseed(sp);
+ return (pathfind(RMODE_EXPLORE) == coord_def(-1, -1));
+}
+
+template <typename fgrd, typename bound_check>
+bool flood_find<fgrd, bound_check>::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<coord_def>::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