From c0aa968809c8d8ef88048edd667b12b297a68602 Mon Sep 17 00:00:00 2001 From: Darshan Shaligram Date: Sat, 16 Jan 2010 22:50:34 +0530 Subject: Experimental level builder changes for Swamp. The Swamp now gets a border of trees and uses trees instead of walls. Swamp:5 vaults may need tweaking to fit in better. --- crawl-ref/source/dgn-height.cc | 36 +++++--------- crawl-ref/source/dgn-height.h | 4 -- crawl-ref/source/dgn-shoals.cc | 52 ++++++++++---------- crawl-ref/source/dgn-shoals.h | 2 +- crawl-ref/source/dgn-swamp.cc | 108 +++++++++++++++++++++++++++++++++++++++++ crawl-ref/source/dgn-swamp.h | 6 +++ crawl-ref/source/dungeon.cc | 78 ++++++++++++++--------------- crawl-ref/source/dungeon.h | 3 ++ crawl-ref/source/makefile.obj | 1 + crawl-ref/source/maps.cc | 2 +- 10 files changed, 194 insertions(+), 98 deletions(-) create mode 100644 crawl-ref/source/dgn-swamp.cc create mode 100644 crawl-ref/source/dgn-swamp.h diff --git a/crawl-ref/source/dgn-height.cc b/crawl-ref/source/dgn-height.cc index 8a52736fb5..16d54c17f8 100644 --- a/crawl-ref/source/dgn-height.cc +++ b/crawl-ref/source/dgn-height.cc @@ -11,8 +11,6 @@ #include "dungeon.h" #include "random.h" -const int SHOALS_ISLAND_COLLIDE_DIST2 = 5 * 5; - void dgn_initialise_heightmap(int height) { env.heightmap.reset(new grid_heightmap); @@ -70,35 +68,23 @@ void dgn_smooth_heights(int radius, int npasses) { for (int i = 0; i < npasses; ++i) { - for (rectangle_iterator ri(0); ri; ++ri) - dgn_smooth_height_at(*ri, radius); + const int xspan = GXM / 2, yspan = GYM / 2; + for (int y = yspan - 1; y >= 0; --y) + for (int x = xspan - 1; x >= 0; --x) + { + dgn_smooth_height_at(coord_def(x, y), radius); + dgn_smooth_height_at(coord_def(2 * xspan - x - 1, y), radius); + dgn_smooth_height_at(coord_def(x, 2 * yspan - y - 1), radius); + dgn_smooth_height_at(coord_def(2 * xspan - x - 1, + 2 * yspan - y - 1), + radius); + } } } ////////////////////////////////////////////////////////////////////// // dgn_island_plan -dgn_island_plan dgn_island_plan::shoals_islands(int margin) -{ - dgn_island_plan plan; - plan.level_border_depth = margin; - plan.n_aux_centres = int_range(0, 3); - plan.aux_centre_offset_range = int_range(2, 10); - - plan.atoll_roll = 10; - plan.island_separation_dist2 = SHOALS_ISLAND_COLLIDE_DIST2; - - plan.n_island_centre_delta_points = int_range(50, 60); - plan.island_centre_radius_range = int_range(3, 10); - plan.island_centre_point_height_increment = int_range(40, 60); - - plan.n_island_aux_delta_points = int_range(25, 45); - plan.island_aux_radius_range = int_range(2, 7); - plan.island_aux_point_height_increment = int_range(25, 35); - - return (plan); -} - void dgn_island_plan::build(int nislands) { for (int i = 0; i < nislands; ++i) diff --git a/crawl-ref/source/dgn-height.h b/crawl-ref/source/dgn-height.h index 1ab5954db4..7732b5d9ca 100644 --- a/crawl-ref/source/dgn-height.h +++ b/crawl-ref/source/dgn-height.h @@ -88,10 +88,6 @@ public: int_range island_aux_point_height_increment; -public: - static dgn_island_plan shoals_islands(int margin); - static dgn_island_plan snake_chambers(int margin); - public: void build(int nislands); coord_def pick_and_remove_random_island(); diff --git a/crawl-ref/source/dgn-shoals.cc b/crawl-ref/source/dgn-shoals.cc index 03dd0196d1..3f9637cbad 100644 --- a/crawl-ref/source/dgn-shoals.cc +++ b/crawl-ref/source/dgn-shoals.cc @@ -23,7 +23,6 @@ #include #include -typedef FixedArray grid_bool; typedef FixedArray grid_short; const char *ENVP_SHOALS_TIDE_KEY = "shoals-tide-height"; @@ -31,6 +30,8 @@ const char *ENVP_SHOALS_TIDE_VEL = "shoals-tide-velocity"; static dgn_island_plan _shoals_islands; +const int SHOALS_ISLAND_COLLIDE_DIST2 = 5 * 5; + // 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. @@ -128,10 +129,31 @@ static void _shoals_init_heights() dgn_initialise_heightmap(SHT_SHALLOW_WATER - 3); } +static dgn_island_plan _shoals_island_plan() +{ + dgn_island_plan plan; + plan.level_border_depth = _shoals_margin; + plan.n_aux_centres = int_range(0, 3); + plan.aux_centre_offset_range = int_range(2, 10); + + plan.atoll_roll = 10; + plan.island_separation_dist2 = SHOALS_ISLAND_COLLIDE_DIST2; + + plan.n_island_centre_delta_points = int_range(50, 60); + plan.island_centre_radius_range = int_range(3, 10); + plan.island_centre_point_height_increment = int_range(40, 60); + + plan.n_island_aux_delta_points = int_range(25, 45); + plan.island_aux_radius_range = int_range(2, 7); + plan.island_aux_point_height_increment = int_range(25, 35); + + return (plan); +} + static void _shoals_init_islands(int depth) { const int nislands = 20 - depth * 2; - _shoals_islands = dgn_island_plan::shoals_islands(_shoals_margin); + _shoals_islands = _shoals_island_plan(); _shoals_islands.build(nislands); } @@ -240,28 +262,6 @@ static coord_def _pick_shoals_island() return _shoals_islands.pick_and_remove_random_island(); } -void place_feature_at_random_floor_square(dungeon_feature_type feat, - unsigned mask = MMT_VAULT) -{ - const coord_def place = - dgn_random_point_in_bounds(DNGN_FLOOR, mask, DNGN_FLOOR); - if (place.origin()) - dgn_veto_level(); - else - grd(place) = feat; -} - -static void _shoals_place_stairs() -{ - for (int i = 0; i < 3; ++i) - { - place_feature_at_random_floor_square( - static_cast(DNGN_STONE_STAIRS_DOWN_I + i)); - place_feature_at_random_floor_square( - static_cast(DNGN_STONE_STAIRS_UP_I + i)); - } -} - static void _shoals_furniture(int margin) { if (at_branch_bottom()) @@ -302,7 +302,7 @@ static void _shoals_furniture(int margin) } } - _shoals_place_stairs(); + dgn_place_stone_stairs(); } static void _shoals_deepen_edges() @@ -665,7 +665,7 @@ static void _shoals_generate_flora() } } -void prepare_shoals(int level_number) +void dgn_build_shoals_level(int level_number) { dgn_Build_Method += make_stringf(" shoals+ [%d]", level_number); dgn_Layout_Type = "shoals"; diff --git a/crawl-ref/source/dgn-shoals.h b/crawl-ref/source/dgn-shoals.h index 1d14c620f2..de33308eac 100644 --- a/crawl-ref/source/dgn-shoals.h +++ b/crawl-ref/source/dgn-shoals.h @@ -1,7 +1,7 @@ #ifndef DGN_SHOALS_H #define DGN_SHOALS_H -void prepare_shoals(int level_number); +void dgn_build_shoals_level(int level_number); void shoals_postprocess_level(); void shoals_apply_tides(int turns_elapsed, bool force = false); void shoals_release_tide(monsters *caller); diff --git a/crawl-ref/source/dgn-swamp.cc b/crawl-ref/source/dgn-swamp.cc new file mode 100644 index 0000000000..b20627e2d3 --- /dev/null +++ b/crawl-ref/source/dgn-swamp.cc @@ -0,0 +1,108 @@ +#include "AppHdr.h" + +#include "coordit.h" +#include "dungeon.h" +#include "dgn-height.h" +#include "random.h" + +static void _swamp_slushy_patches(int depth_multiplier) +{ + const int margin = 6; + const int yinterval = 4; + const int xinterval = 4; + const int fuzz = 9; + const coord_def grdc(GXM / 2, GYM / 2); + for (int y = margin; y < GYM - margin - 1; y += yinterval) + { + for (int x = margin; x < GXM - margin - 1; x += xinterval) + { + const coord_def p(x, y); + const coord_def c(dgn_random_point_from(p, fuzz, margin)); + const coord_def center_delta(grdc - c); + const int depth = 1600 - center_delta.abs(); + const int depth_offset = depth * 10 / 1600; + dgn_island_centred_at(c, random_range(5, 25 - depth_multiplier / 2), + random_range(2, 6), + int_range(8 + depth_offset, + 17 + depth_offset), + margin); + } + } +} + +static dungeon_feature_type _swamp_feature_for_height(int height) +{ + return height >= 14? DNGN_DEEP_WATER : + height > 0? DNGN_SHALLOW_WATER : + height > -9 ? DNGN_FLOOR : + height > -13 ? DNGN_SHALLOW_WATER : + height > -17 && coinflip() ? DNGN_SHALLOW_WATER : + DNGN_TREES; +} + +static void _swamp_apply_features(int margin) +{ + for (rectangle_iterator ri(0); ri; ++ri) + { + const coord_def c(*ri); + if (unforbidden(c, MMT_VAULT)) + { + if (c.x < margin || c.y < margin || c.x >= GXM - margin + || c.y >= GYM - margin) + grd(c) = DNGN_TREES; + else + grd(c) = _swamp_feature_for_height(dgn_height_at(c)); + } + } +} + +void dgn_build_swamp_level(int level) +{ + const int swamp_depth = level_id::current().depth - 1; + dgn_initialise_heightmap(-17); + _swamp_slushy_patches(swamp_depth * 3); + dgn_smooth_heights(); + _swamp_apply_features(2); + + dgn_place_stone_stairs(); + process_disconnected_zones(0, 0, GXM - 1, GYM - 1, true, DNGN_TREES); +} + + +#if OLD_SWAMP_LAYOUT +void dgn_prepare_swamp() +{ + dgn_Build_Method += " swamp"; + dgn_Layout_Type = "swamp"; + + const int margin = 5; + + for (int i = margin; i < (GXM - margin); i++) + for (int j = margin; j < (GYM - margin); j++) + { + // Don't apply Swamp prep in vaults. + if (!unforbidden(coord_def(i, j), MMT_VAULT)) + continue; + + // doors -> floors {dlb} + if (grd[i][j] == DNGN_CLOSED_DOOR || grd[i][j] == DNGN_SECRET_DOOR) + grd[i][j] = DNGN_FLOOR; + + // floors -> shallow water 1 in 3 times {dlb} + if (grd[i][j] == DNGN_FLOOR && one_chance_in(3)) + grd[i][j] = DNGN_SHALLOW_WATER; + + // walls -> deep/shallow water or remain unchanged {dlb} + if (grd[i][j] == DNGN_ROCK_WALL) + { + const int temp_rand = random2(6); + + if (temp_rand > 0) // 17% chance unchanged {dlb} + { + grd[i][j] = ((temp_rand > 2) ? DNGN_SHALLOW_WATER // 50% + : DNGN_DEEP_WATER); // 33% + } + } + } +} +#endif diff --git a/crawl-ref/source/dgn-swamp.h b/crawl-ref/source/dgn-swamp.h new file mode 100644 index 0000000000..9cb8894a98 --- /dev/null +++ b/crawl-ref/source/dgn-swamp.h @@ -0,0 +1,6 @@ +#ifndef DGN_SWAMP_H +#define DGN_SWAMP_H + +void dgn_build_swamp_level(int level); + +#endif diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index a663cf2ebb..94850d8bb8 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -25,6 +25,7 @@ #include "coordit.h" #include "defines.h" #include "dgn-shoals.h" +#include "dgn-swamp.h" #include "effects.h" #include "env.h" #include "enum.h" @@ -133,7 +134,6 @@ static void _place_minivaults(const std::string &tag = "", static int _place_uniques(int level_number, char level_type); static void _place_traps( int level_number ); static void _place_fog_machines( int level_number ); -static void _prepare_swamp(); static void _prepare_water( int level_number ); static void _check_doors(); static void _hide_doors(); @@ -1821,9 +1821,11 @@ static void _build_dungeon_level(int level_number, int level_type) // Stairs must exist by this point (except in Shoals where they are // yet to be placed). Some items and monsters already exist. +#if OLD_SWAMP_LAYOUT // Time to make the swamp or shoals {dlb}: if (player_in_branch(BRANCH_SWAMP)) - _prepare_swamp(); + dgn_prepare_swamp(); +#endif if (dgn_level_vetoed) return; @@ -2078,42 +2080,6 @@ static void _connected_flood(int margin, int i, int j, bool taken[GXM][GYM]) _connected_flood(margin, i + idelta, j + jdelta, taken); } -static void _prepare_swamp() -{ - dgn_Build_Method += " swamp"; - dgn_Layout_Type = "swamp"; - - const int margin = 5; - - for (int i = margin; i < (GXM - margin); i++) - for (int j = margin; j < (GYM - margin); j++) - { - // Don't apply Swamp prep in vaults. - if (!unforbidden(coord_def(i, j), MMT_VAULT)) - continue; - - // doors -> floors {dlb} - if (grd[i][j] == DNGN_CLOSED_DOOR || grd[i][j] == DNGN_SECRET_DOOR) - grd[i][j] = DNGN_FLOOR; - - // floors -> shallow water 1 in 3 times {dlb} - if (grd[i][j] == DNGN_FLOOR && one_chance_in(3)) - grd[i][j] = DNGN_SHALLOW_WATER; - - // walls -> deep/shallow water or remain unchanged {dlb} - if (grd[i][j] == DNGN_ROCK_WALL) - { - const int temp_rand = random2(6); - - if (temp_rand > 0) // 17% chance unchanged {dlb} - { - grd[i][j] = ((temp_rand > 2) ? DNGN_SHALLOW_WATER // 50% - : DNGN_DEEP_WATER); // 33% - } - } - } -} - // Gives water which is next to ground/shallow water a chance of being // shallow. Checks each water space. static void _prepare_water( int level_number ) @@ -2451,6 +2417,8 @@ static builder_rc_type _builder_by_branch(int level_number) { dgn_Build_Method += " random_map_for_place"; _ensure_vault_placed_ex( _build_vaults(level_number, vault), vault ); + if (!dgn_level_vetoed && player_in_branch(BRANCH_SWAMP)) + dgn_build_swamp_level(level_number); return BUILD_SKIP; } @@ -2468,8 +2436,13 @@ static builder_rc_type _builder_by_branch(int level_number) spotty_level(false, iterations, false); return BUILD_SKIP; } + case BRANCH_SHOALS: - prepare_shoals(level_number); + dgn_build_shoals_level(level_number); + return BUILD_SKIP; + + case BRANCH_SWAMP: + dgn_build_swamp_level(level_number); return BUILD_SKIP; default: @@ -2925,6 +2898,29 @@ static void _place_fog_machines(int level_number) } } +void dgn_place_feature_at_random_floor_square(dungeon_feature_type feat, + unsigned mask = MMT_VAULT) +{ + const coord_def place = + dgn_random_point_in_bounds(DNGN_FLOOR, mask, DNGN_FLOOR); + if (place.origin()) + dgn_veto_level(); + else + grd(place) = feat; +} + +// Create randomly-placed stone stairs. +void dgn_place_stone_stairs() +{ + for (int i = 0; i < 3; ++i) + { + dgn_place_feature_at_random_floor_square( + static_cast(DNGN_STONE_STAIRS_DOWN_I + i)); + dgn_place_feature_at_random_floor_square( + static_cast(DNGN_STONE_STAIRS_UP_I + i)); + } +} + bool dgn_has_adjacent_feat(coord_def c, dungeon_feature_type feat) { for (adjacent_iterator ai(c); ai; ++ai) @@ -7885,8 +7881,8 @@ coord_def dgn_random_point_from(const coord_def &c, int radius, int margin) const coord_def res = c + coord_def(static_cast(radius * cos(angle)), static_cast(radius * sin(angle))); - if (res.x >= margin && res.x < GXM - margin - && res.y >= margin && res.y < GYM - margin) + if (res.x >= margin && res.x < GXM - margin - 1 + && res.y >= margin && res.y < GYM - margin - 1) { return res; } diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index 1ae794b96e..29217fba51 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -196,6 +196,9 @@ coord_def dgn_random_point_visible_from(const coord_def &c, int tries = 5); coord_def dgn_find_feature_marker(dungeon_feature_type feat); +// Generate 3 stone stairs in both directions. +void dgn_place_stone_stairs(); + // Set floor/wall colour based on the mons_alloc array. Used for // Abyss and Pan. void dgn_set_colours_from_monsters(); diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index 965b16bbf8..955e506563 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -36,6 +36,7 @@ dlua.o \ dungeon.o \ dgn-height.o \ dgn-shoals.o \ +dgn-swamp.o \ effects.o \ exclude.o \ feature.o \ diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc index a41fc4ce88..0855eb5664 100644 --- a/crawl-ref/source/maps.cc +++ b/crawl-ref/source/maps.cc @@ -323,7 +323,7 @@ static bool _may_overwrite_feature(const dungeon_feature_type grid, return (false); } - if (feat_is_wall(grid)) + if (feat_is_wall(grid) || grid == DNGN_TREES) return (wall_ok); // Otherwise, feel free to clobber this feature. -- cgit v1.2.3-54-g00ecf