diff options
author | Darshan Shaligram <scintilla@gmail.com> | 2013-02-03 17:24:51 -0500 |
---|---|---|
committer | Darshan Shaligram <scintilla@gmail.com> | 2013-02-03 21:56:11 -0500 |
commit | ea21e6f68b80c4be47bd11ebed260bb85b29f90a (patch) | |
tree | 5fca950852f0bf86b188198c10c7c83b3d9b2570 /crawl-ref/source/dgn-shoals.cc | |
parent | 7af4ce618f40e4bee0bb796d0cad9b5bd07c355e (diff) | |
download | crawl-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.cc | 140 |
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. |