summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarshan Shaligram <dshaligram@users.sourceforge.net>2009-12-28 18:56:12 +0530
committerDarshan Shaligram <dshaligram@users.sourceforge.net>2009-12-28 18:58:40 +0530
commitadcc6b42f200b5a4c7f75d5826884494684a587b (patch)
treea87e2989e483753613455b4c8d61391a4fd2a76d
parent4bd11a2119ce0fd7f137233e16cd7f745c13a2dd (diff)
downloadcrawl-ref-adcc6b42f200b5a4c7f75d5826884494684a587b.tar.gz
crawl-ref-adcc6b42f200b5a4c7f75d5826884494684a587b.zip
Postprocess shoals levels to fix heightmap for vaults on the level so that the tide interacts reasonably with vaults.
-rw-r--r--crawl-ref/source/dgn-shoals.cc90
-rw-r--r--crawl-ref/source/dgn-shoals.h1
-rw-r--r--crawl-ref/source/dungeon.cc12
3 files changed, 83 insertions, 20 deletions
diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc
index da0070239e..0215afd81f 100644
--- a/crawl-ref/source/dgn-shoals.cc
+++ b/crawl-ref/source/dgn-shoals.cc
@@ -6,6 +6,7 @@
#include "dungeon.h"
#include "dgn-shoals.h"
#include "env.h"
+#include "flood_find.h"
#include "items.h"
#include "maps.h"
#include "mon-place.h"
@@ -76,6 +77,40 @@ static dungeon_feature_type _shoals_feature_at(const coord_def &c)
return _shoals_feature_by_height(height);
}
+static int _shoals_feature_height(dungeon_feature_type feat)
+{
+ switch (feat)
+ {
+ case DNGN_FLOOR:
+ return SHT_FLOOR;
+ case DNGN_SHALLOW_WATER:
+ return SHT_SHALLOW_WATER;
+ case DNGN_DEEP_WATER:
+ return SHT_SHALLOW_WATER - 1;
+ default:
+ return 0;
+ }
+}
+
+// Returns true if the given feature can be affected by Shoals tides.
+static bool _shoals_tide_susceptible_feat(dungeon_feature_type feat)
+{
+ return (feat_is_water(feat) || feat == DNGN_FLOOR);
+}
+
+// Return true if tide effects can propagate through this square.
+// NOTE: uses RNG!
+static bool _shoals_tide_passable_feat(dungeon_feature_type feat)
+{
+ return (feat_is_watery(feat)
+ // The Shoals tide can sometimes lap past the doorways of rooms
+ // near the water. Note that the actual probability of the tide
+ // getting through a doorway is this probability * 0.5 --
+ // see _shoals_apply_tide.
+ || (feat == DNGN_OPEN_DOOR && !one_chance_in(3))
+ || (feat == DNGN_CLOSED_DOOR && one_chance_in(3)));
+}
+
static void _shoals_init_heights()
{
env.heightmap.reset(new grid_heightmap);
@@ -448,6 +483,31 @@ void prepare_shoals(int level_number)
_shoals_furniture(_shoals_margin);
}
+// Search the map for vaults and set the terrain heights for features
+// in the vault to reasonable levels.
+void shoals_postprocess_level()
+{
+ if (!player_in_branch(BRANCH_SHOALS) || !env.heightmap.get())
+ return;
+
+ for (rectangle_iterator ri(1); ri; ++ri)
+ {
+ const coord_def c(*ri);
+ if (!(dgn_Map_Mask(c) & MMT_VAULT))
+ continue;
+
+ const dungeon_feature_type feat(grd(c));
+ if (!_shoals_tide_susceptible_feat(feat))
+ continue;
+
+ const dungeon_feature_type expected_feat(_shoals_feature_at(c));
+ // It would be nice to do actual height contours within
+ // vaults, but for now, keep it simple.
+ if (feat != expected_feat)
+ shoals_heights(c) = _shoals_feature_height(feat);
+ }
+}
+
// The raw tide height / TIDE_MULTIPLIER is the actual tide height. The higher
// the tide multiplier, the slower the tide advances and recedes. A multiplier
// of X implies that the tide will advance visibly about once in X turns.
@@ -554,22 +614,8 @@ static void _shoals_apply_tide_feature_at(coord_def c,
dungeon_terrain_changed(c, feat, true, false, true);
}
-static int _shoals_feature_height(dungeon_feature_type feat)
-{
- switch (feat)
- {
- case DNGN_FLOOR:
- return SHT_FLOOR;
- case DNGN_SHALLOW_WATER:
- return SHT_SHALLOW_WATER;
- case DNGN_DEEP_WATER:
- return SHT_SHALLOW_WATER - 1;
- default:
- return 0;
- }
-}
-
-// Determines if the
+// Determines if the tide is rising or falling based on before and
+// after features at the same square.
static tide_direction _shoals_feature_tide_height_change(
dungeon_feature_type oldfeat,
dungeon_feature_type newfeat)
@@ -623,12 +669,16 @@ static void _shoals_apply_tide(int tide)
for (int i = 0, size = cpage.size(); i < size; ++i)
{
coord_def c(cpage[i]);
- const bool was_wet(feat_is_water(grd(c)));
+ const bool was_wet(_shoals_tide_passable_feat(grd(c)));
seen_points(c) = true;
_shoals_apply_tide_at(c, tide);
- // Only wet squares can propagate the tide onwards.
- if (was_wet)
+ const bool is_wet(feat_is_water(grd(c)));
+ // Only squares that were wet (before applying tide
+ // effects!) can propagate the tide onwards. If the tide is
+ // receding and just left the square dry, there's only a chance of
+ // it continuing past and draining other squares through this one.
+ if (was_wet && (is_wet || coinflip()))
{
for (adjacent_iterator ai(c); ai; ++ai)
{
@@ -638,7 +688,7 @@ static void _shoals_apply_tide(int tide)
if (!seen_points(adj))
{
const dungeon_feature_type feat = grd(adj);
- if (feat_is_water(feat) || feat == DNGN_FLOOR)
+ if (_shoals_tide_susceptible_feat(feat))
{
npage.push_back(adj);
seen_points(adj) = true;
diff --git a/crawl-ref/source/dgn-shoals.h b/crawl-ref/source/dgn-shoals.h
index aae09ff653..f558f6606f 100644
--- a/crawl-ref/source/dgn-shoals.h
+++ b/crawl-ref/source/dgn-shoals.h
@@ -2,6 +2,7 @@
#define DGN_SHOALS_H
void prepare_shoals(int level_number);
+void shoals_postprocess_level();
void shoals_apply_tides(int turns_elapsed);
#endif
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 89e643a68b..48268f2067 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -233,6 +233,8 @@ typedef std::list<coord_def> coord_list;
static void _dgn_set_floor_colours();
static bool _fixup_interlevel_connectivity();
+void dgn_postprocess_level();
+
//////////////////////////////////////////////////////////////////////////
// Static data
@@ -374,6 +376,8 @@ bool builder(int level_number, int level_type)
vault_names.push_back(you.level_type_name);
}
+ dgn_postprocess_level();
+
dgn_Layout_Type.clear();
Level_Unique_Maps.clear();
Level_Unique_Tags.clear();
@@ -398,6 +402,13 @@ bool builder(int level_number, int level_type)
return (false);
}
+// Should be called after a level is constructed to perform any final
+// fixups.
+void dgn_postprocess_level()
+{
+ shoals_postprocess_level();
+}
+
void level_welcome_messages()
{
for (int i = 0, size = Level_Vaults.size(); i < size; ++i)
@@ -4132,6 +4143,7 @@ bool dgn_place_map(const map_def *mdef, bool clobber, bool make_no_exits,
}
setup_environment_effects();
+ dgn_postprocess_level();
}
return (did_map);