summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dgn-shoals.cc
diff options
context:
space:
mode:
authorDarshan Shaligram <scintilla@gmail.com>2013-02-03 17:24:51 -0500
committerDarshan Shaligram <scintilla@gmail.com>2013-02-03 21:56:11 -0500
commitea21e6f68b80c4be47bd11ebed260bb85b29f90a (patch)
tree5fca950852f0bf86b188198c10c7c83b3d9b2570 /crawl-ref/source/dgn-shoals.cc
parent7af4ce618f40e4bee0bb796d0cad9b5bd07c355e (diff)
downloadcrawl-ref-ea21e6f68b80c4be47bd11ebed260bb85b29f90a.tar.gz
crawl-ref-ea21e6f68b80c4be47bd11ebed260bb85b29f90a.zip
Fix Shoals map connections.
Shoals maps used join-the-dots which produces unnatural corridors. Fixed to postprocess the join-the-dots path and update the heightmap around the path to make it look less artificial.
Diffstat (limited to 'crawl-ref/source/dgn-shoals.cc')
-rw-r--r--crawl-ref/source/dgn-shoals.cc140
1 files changed, 135 insertions, 5 deletions
diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc
index fae08d79b0..0447ff0f69 100644
--- a/crawl-ref/source/dgn-shoals.cc
+++ b/crawl-ref/source/dgn-shoals.cc
@@ -8,6 +8,7 @@
#include "dgn-shoals.h"
#include "dgn-height.h"
#include "env.h"
+#include "flood_find.h"
#include "fprop.h"
#include "items.h"
#include "itemprop.h"
@@ -220,6 +221,22 @@ static void _shoals_apply_level()
grd(*ri) = _shoals_feature_at(*ri);
}
+static void _shoals_postbuild_apply_level()
+{
+ for (rectangle_iterator ri(1); ri; ++ri)
+ {
+ if (!map_masked(*ri, MMT_VAULT))
+ {
+ const dungeon_feature_type feat = grd(*ri);
+ if (feat_is_water(feat) || feat == DNGN_ROCK_WALL
+ || feat == DNGN_STONE_WALL || feat == DNGN_FLOOR)
+ {
+ grd(*ri) = _shoals_feature_at(*ri);
+ }
+ }
+ }
+}
+
// Returns all points in deep water with an adjacent square in shallow water.
static vector<coord_def> _shoals_water_depth_change_points()
{
@@ -288,22 +305,23 @@ static void _shoals_furniture(int margin)
static void _shoals_deepen_edges()
{
- const int edge = 2;
+ const int edge = 1;
+ const int deepen_by = 1000;
// Water of the edge of the screen is too deep to be exposed by tides.
for (int y = 1; y < GYM - 2; ++y)
{
for (int x = 1; x <= edge; ++x)
{
- dgn_height_at(coord_def(x, y)) -= 800;
- dgn_height_at(coord_def(GXM - 1 - x, y)) -= 800;
+ dgn_height_at(coord_def(x, y)) -= deepen_by;
+ dgn_height_at(coord_def(GXM - 1 - x, y)) -= deepen_by;
}
}
for (int x = 1; x < GXM - 2; ++x)
{
for (int y = 1; y <= edge; ++y)
{
- dgn_height_at(coord_def(x, y)) -= 800;
- dgn_height_at(coord_def(x, GYM - 1 - y)) -= 800;
+ dgn_height_at(coord_def(x, y)) -= deepen_by;
+ dgn_height_at(coord_def(x, GYM - 1 - y)) -= deepen_by;
}
}
}
@@ -700,6 +718,118 @@ void shoals_postprocess_level()
shoals_apply_tides(0, true, false);
}
+static void _shoals_clamp_height_at(const coord_def &c,
+ int clamp_height = SHT_ROCK - 1)
+{
+ if (!in_bounds(c))
+ return;
+
+ if (dgn_height_at(c) > clamp_height)
+ dgn_height_at(c) = clamp_height;
+}
+
+static void _shoals_connect_smooth_height_at(const coord_def &c)
+{
+ if (map_bounds_with_margin(c, 3))
+ dgn_smooth_height_at(c, 1);
+}
+
+static void _shoals_connecting_point_smooth(const coord_def &c, int radius)
+{
+ for (int dy = 0; dy < radius; ++dy)
+ {
+ for (int dx = 0; dx < radius; ++dx)
+ {
+ _shoals_connect_smooth_height_at(c + coord_def(dy, dx));
+ if (dy)
+ _shoals_connect_smooth_height_at(c + coord_def(-dy, dx));
+ if (dx)
+ _shoals_connect_smooth_height_at(c + coord_def(dy, -dx));
+ if (dx && dy)
+ _shoals_connect_smooth_height_at(c + coord_def(-dy, -dx));
+ }
+ }
+}
+
+static void _shoals_connecting_point_clamp_height(
+ const coord_def &c, int radius)
+{
+ if (!in_bounds(c))
+ return;
+
+ for (rectangle_iterator ri(c - coord_def(radius, radius),
+ c + coord_def(radius, radius)); ri; ++ri)
+ {
+ _shoals_clamp_height_at(*ri);
+ }
+
+ const int min_height_threshold = (SHT_SHALLOW_WATER + SHT_FLOOR) / 2;
+ if (dgn_height_at(c) < min_height_threshold)
+ dgn_height_at(c) = min_height_threshold;
+}
+
+bool dgn_shoals_connect_point(const coord_def &point,
+ bool (*overwriteable)(dungeon_feature_type))
+{
+ flood_find<feature_grid, coord_predicate> ff(env.grid, in_bounds, true,
+ false);
+ ff.add_feat(DNGN_FLOOR);
+
+ const coord_def target = ff.find_first_from(point, env.level_map_mask);
+ if (!in_bounds(target))
+ return false;
+
+ const vector<coord_def> track =
+ dgn_join_the_dots_pathfind(point, target, MMT_VAULT);
+
+ if (!track.empty())
+ {
+ const int n_points = 15;
+ const int radius = 4;
+
+ for (vector<coord_def>::const_iterator i = track.begin();
+ i != track.end(); ++i)
+ {
+ int height = 0, npoints = 0;
+ for (radius_iterator ri(*i, radius, C_POINTY); ri; ++ri)
+ {
+ if (in_bounds(*ri))
+ {
+ height += dgn_height_at(*ri);
+ ++npoints;
+ }
+ }
+
+ const int target_height = SHT_FLOOR;
+ if (height < target_height)
+ {
+ const int elevation_change = target_height - height;
+ const int elevation_change_per_dot =
+ max(1, elevation_change / n_points + 1);
+
+ dgn_island_centred_at(*i, n_points, radius,
+ int_range(elevation_change_per_dot,
+ elevation_change_per_dot + 20),
+ 3);
+ }
+ }
+
+ for (int i = track.size() - 1; i >= 0; --i)
+ {
+ const coord_def &p(track[i]);
+ _shoals_connecting_point_smooth(p, radius + 2);
+ }
+ for (int i = track.size() - 1; i >= 0; --i)
+ {
+ const coord_def &p(track[i]);
+ _shoals_connecting_point_clamp_height(p, radius + 2);
+ }
+
+ _shoals_postbuild_apply_level();
+ }
+ return !track.empty();
+}
+
static void _shoals_run_tide(int &tide, int &acc)
{
// If someone is calling the tide, the tide velocity is clamped high.