summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dungeon.cc
diff options
context:
space:
mode:
authorDarshan Shaligram <dshaligram@users.sourceforge.net>2010-01-09 19:31:38 +0530
committerDarshan Shaligram <dshaligram@users.sourceforge.net>2010-01-09 19:33:59 +0530
commitf402990b9d7a17aa5e775c445891bc8428f40692 (patch)
tree06b7d90b58cf89287aa99af45d65660c11aa4a9a /crawl-ref/source/dungeon.cc
parent43274d595d2920ea45aee3aad0c46d6cb9c9b170 (diff)
downloadcrawl-ref-f402990b9d7a17aa5e775c445891bc8428f40692.tar.gz
crawl-ref-f402990b9d7a17aa5e775c445891bc8428f40692.zip
Change stair placement on Shoal:$ so it no longer groups all stairs together.
Diffstat (limited to 'crawl-ref/source/dungeon.cc')
-rw-r--r--crawl-ref/source/dungeon.cc85
1 files changed, 85 insertions, 0 deletions
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 71dffc3610..dc371ba174 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -2916,6 +2916,91 @@ static void _place_fog_machines(int level_number)
}
}
+bool dgn_has_adjacent_feat(coord_def c, dungeon_feature_type feat)
+{
+ for (adjacent_iterator ai(c); ai; ++ai)
+ if (grd(*ai) == feat)
+ return true;
+ return false;
+}
+
+static inline bool _point_matches_feat(coord_def c,
+ dungeon_feature_type searchfeat,
+ unsigned mapmask,
+ dungeon_feature_type adjacent_feat,
+ bool monster_free)
+{
+ return (grd(c) == searchfeat
+ && (!monster_free || !monster_at(c))
+ && unforbidden(c, mapmask)
+ && (adjacent_feat == DNGN_UNSEEN ||
+ dgn_has_adjacent_feat(c, adjacent_feat)));
+}
+
+// Returns a random point in map bounds matching the given search feature,
+// and respecting the map mask (a map mask of MMT_VAULT ensures that
+// positions inside vaults will not be returned).
+//
+// If adjacent_feat is not DNGN_UNSEEN, the chosen square will be
+// adjacent to a square containing adjacent_feat.
+//
+// If monster_free is true, the chosen square will never be occupied by
+// a monster.
+//
+// If tries is set to anything other than -1, this function will make tries
+// attempts to find a suitable square, and may fail if the map is crowded.
+// If tries is set to -1, this function will examine the entire map and
+// guarantees to find a suitable point if available.
+//
+// If a suitable point is not available (or was not found in X tries),
+// returns coord_def(0,0)
+//
+coord_def dgn_random_point_in_bounds(dungeon_feature_type searchfeat,
+ unsigned mapmask,
+ dungeon_feature_type adjacent_feat,
+ bool monster_free,
+ int tries)
+{
+ if (tries == -1)
+ {
+ // Try a quick and dirty random search:
+ coord_def chosen = dgn_random_point_in_bounds(searchfeat,
+ mapmask,
+ adjacent_feat,
+ monster_free,
+ 10);
+ if (!chosen.origin())
+ return chosen;
+
+ // Exhaustive search; will never fail if a suitable place is
+ // available, but is also far more expensive.
+ int nfound = 0;
+ for (rectangle_iterator ri(1); ri; ++ri)
+ {
+ const coord_def c(*ri);
+ if (_point_matches_feat(c, searchfeat, mapmask, adjacent_feat,
+ monster_free)
+ && one_chance_in(++nfound))
+ {
+ chosen = c;
+ }
+ }
+ return (chosen);
+ }
+ else
+ {
+ // Random search.
+ while (--tries >= 0)
+ {
+ const coord_def c = random_in_bounds();
+ if (_point_matches_feat(c, searchfeat, mapmask, adjacent_feat,
+ monster_free))
+ return c;
+ }
+ return (coord_def(0, 0));
+ }
+}
+
static void _place_specific_feature(dungeon_feature_type feat)
{
coord_def c;