diff options
author | Brendan Hickey <brendan@bhickey.net> | 2013-03-02 17:39:09 -0800 |
---|---|---|
committer | Brendan Hickey <brendan@bhickey.net> | 2013-03-02 17:45:20 -0800 |
commit | 2a9ad8e908992dffb255856b15b4afe9c01906c0 (patch) | |
tree | f547eba3e5d9bebc2571ac02f0973854b52a1064 /crawl-ref/source/dgn-proclayouts.cc | |
parent | a843345b50b3ee2e58450861978ec8bfc4d7b887 (diff) | |
download | crawl-ref-2a9ad8e908992dffb255856b15b4afe9c01906c0.tar.gz crawl-ref-2a9ad8e908992dffb255856b15b4afe9c01906c0.zip |
Dungeon Levels in the Abyss
Use chunks of real levels to generate abyss levels.
Diffstat (limited to 'crawl-ref/source/dgn-proclayouts.cc')
-rw-r--r-- | crawl-ref/source/dgn-proclayouts.cc | 100 |
1 files changed, 99 insertions, 1 deletions
diff --git a/crawl-ref/source/dgn-proclayouts.cc b/crawl-ref/source/dgn-proclayouts.cc index 99758965f4..56831f7492 100644 --- a/crawl-ref/source/dgn-proclayouts.cc +++ b/crawl-ref/source/dgn-proclayouts.cc @@ -6,6 +6,9 @@ #include <cmath> #include "dgn-proclayouts.h" +#include "coord.h" +#include "coordit.h" +#include "files.h" #include "hash.h" #include "perlin.h" #include "terrain.h" @@ -81,7 +84,8 @@ WorleyLayout::operator()(const coord_def &p, const uint32_t offset) const const uint8_t choice = parity ? id % size : min(id % size, (id / size) % size); - ProceduralSample sample = (*layouts[(choice + seed) % size])(p, offset); + const coord_def pd = p + id; + ProceduralSample sample = (*layouts[(choice + seed) % size])(pd, offset); return ProceduralSample(p, sample.feat(), min(changepoint, sample.changepoint())); @@ -181,3 +185,97 @@ NewAbyssLayout::operator()(const coord_def &p, const uint32_t offset) const return ProceduralSample(p, feat, offset + delta); } + +dungeon_feature_type sanitize_feature(dungeon_feature_type feature, bool strict) +{ + if (feat_is_gate(feature)) + feature = DNGN_STONE_ARCH; + if (feat_is_stair(feature)) + feature = strict ? DNGN_FLOOR : DNGN_STONE_ARCH; + if (feat_is_altar(feature)) + feature = DNGN_FLOOR; + if (feature == DNGN_ENTER_SHOP) + feature = DNGN_ABANDONED_SHOP; + if (feat_is_trap(feature, true)) + feature = DNGN_FLOOR; + switch (feature) + { + // demote permarock + case DNGN_PERMAROCK_WALL: + feature = DNGN_ROCK_WALL; + break; + case DNGN_CLEAR_PERMAROCK_WALL: + feature = DNGN_CLEAR_ROCK_WALL; + break; + case DNGN_SLIMY_WALL: + feature = DNGN_GREEN_CRYSTAL_WALL; + case DNGN_UNSEEN: + feature = DNGN_FLOOR; + default: + // handle more terrain types. + break; + } + return feature; +} + +LevelLayout::LevelLayout(level_id id, uint32_t _seed, const ProceduralLayout &_layout) : layout(_layout) +{ + if(!is_existing_level(id)) + { + for (rectangle_iterator ri(0); ri; ++ri) + { + grid(*ri) = DNGN_UNSEEN; + } + return; + } + level_excursion le; + le.go_to(id); + grid = feature_grid(grd); + for (rectangle_iterator ri(0); ri; ++ri) + { + grid(*ri) = sanitize_feature(grid(*ri), true); + if (!in_bounds(*ri)) + { + grid(*ri) = DNGN_UNSEEN; + continue; + } + + uint32_t solid_count = 0; + for (adjacent_iterator ai(*ri); ai; ++ai) + { + solid_count += feat_is_solid(grd(*ai)); + } + coord_def p = *ri; + uint64_t base = hash3(p.x, p.y, seed); + int div = base % 2 ? 12 : 11; + switch (solid_count) + { + case 8: + grid(*ri) = DNGN_UNSEEN; + break; + case 7: + case 6: + case 5: + if (!((base / 2) % div)) + grid(*ri) = DNGN_UNSEEN; + break; + case 0: + case 1: + if (!(base % 14)) + grid(*ri) = DNGN_UNSEEN; + break; + } + } + le.~level_excursion(); +} + +ProceduralSample +LevelLayout::operator()(const coord_def &p, const uint32_t offset) const +{ + coord_def cp = clip(p); + dungeon_feature_type feat = grid(cp); + if (feat == DNGN_UNSEEN) { + return layout(p, offset); + } + return ProceduralSample(p, feat, offset + 4096); +} |