From 6c4e2411eda3b895df30a9d7defc4c2a8bc6bc16 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Sun, 14 Sep 2008 16:27:46 +0000 Subject: Revamped labyrinth walls and colours so it's no longer immediately obvious if you're near the exit. Fixed bad foe check in submerge function. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6926 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/dungeon.cc | 201 +++++++++++++++++++++---------------------- crawl-ref/source/mon-util.cc | 5 +- 2 files changed, 99 insertions(+), 107 deletions(-) diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index b1291a0164..03ddda0503 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -76,6 +76,7 @@ #endif #define MAX_PIT_MONSTERS 10 +const dungeon_feature_type LAB_WALL = DNGN_STONE_WALL; struct pit_mons_def { @@ -331,7 +332,6 @@ bool builder(int level_number, int level_type) if (!dgn_level_vetoed && _valid_dungeon_level(level_number, level_type)) { dgn_Layout_Type.clear(); - _dgn_map_colour_fixup(); return (true); } @@ -6265,7 +6265,8 @@ static void _find_maze_neighbours(const coord_def &c, } } -static void _labyrinth_maze_recurse(const coord_def &c, const dgn_region &where) +static void _labyrinth_maze_recurse(const coord_def &c, + const dgn_region &where) { coord_list neighbours; _find_maze_neighbours(c, where, neighbours); @@ -6296,12 +6297,68 @@ static void _labyrinth_build_maze(coord_def &e, const dgn_region &lab) _labyrinth_maze_recurse(lab.random_point(), lab); do - { e = lab.random_point(); - } while (grd(e) != DNGN_FLOOR); } +static int _labyrinth_random_colour() +{ + // Avoid using existing wall colours. + return random_choose(BLACK, RED, YELLOW, BLUE, MAGENTA, DARKGREY, + LIGHTBLUE, WHITE, LIGHTCYAN, LIGHTMAGENTA, + LIGHTRED, -1); +} + +static void _labyrinth_colour_maze_flood( + const coord_def &c, + const std::vector &corder, + int colour) +{ + if (colour) + env.grid_colours(c) = colour; + + travel_point_distance[c.x][c.y] = 1; + + if (one_chance_in(45)) + colour = _labyrinth_random_colour(); + + for (int i = 0, size = corder.size(); i < size; ++i) + { + coord_def dp = c + corder[i]; + if (map_bounds(dp) && !travel_point_distance[dp.x][dp.y] + && grd(dp) == DNGN_ROCK_WALL) + { + _labyrinth_colour_maze_flood(dp, corder, colour); + } + } +} + +static void _labyrinth_colour_maze(const coord_def &e, const dgn_region &lab) +{ + coord_def start = e; + for (rectangle_iterator r(e - coord_def(1, 1), e + coord_def(1, 1)); + r; ++r) + if (map_bounds(*r) && grd(*r) == DNGN_ROCK_WALL) + start = *r; + if (grd(start) != DNGN_ROCK_WALL) + return; + + int colour = _labyrinth_random_colour(); + std::vector flood_points[2]; + int page = 0; + flood_points[page].push_back(start); + + std::vector check_order; + for (int y = -1; y <= 1; ++y) + for (int x = -1; x <= 1; ++x) + if (!x != !y) + check_order.push_back(coord_def(x, y)); + + std::random_shuffle(check_order.begin(), check_order.end()); + memset(travel_point_distance, 0, sizeof(travel_distance_grid_t)); + _labyrinth_colour_maze_flood(start, check_order, colour); +} + static void _labyrinth_place_items(const coord_def &end) { int num_items = 8 + random2avg(12, 2); @@ -6343,75 +6400,6 @@ static void _init_minivault_placement(int vault, vault_placement &place) vault_main(vgrid, place, vault); } -static void _change_walls_from_centre(const dgn_region ®ion, - const coord_def ¢re, - bool rectangular, - unsigned mmask, - dungeon_feature_type wall, - const std::vector &ldist) -{ - if (ldist.empty()) - return; - - const coord_def &end = region.pos + region.size; - for (int y = region.pos.y; y < end.y; ++y) - for (int x = region.pos.x; x < end.x; ++x) - { - const coord_def c(x, y); - if (grd(c) != wall || !unforbidden(c, mmask)) - continue; - - const int distance = - rectangular? (c - centre).rdist() : (c - centre).abs(); - - for (int i = 0, size = ldist.size(); i < size; ++i) - { - if (distance <= ldist[i].dist) - { - grd(c) = ldist[i].feat; - break; - } - } - } -} - -// Called as: -// change_walls_from_centre( region_affected, centre, rectangular, wall, -// dist1, feat1, dist2, feat2, ..., 0 ) -// What it does: -// Examines each square in region_affected, calculates its distance from -// "centre" (the centre need not be in region_affected). If the distance is -// less than or equal to dist1, and the feature == wall, then it is replaced -// by feat1. Otherwise, if the distance <= dist2 and feature == wall, it is -// replaced by feat2, and so on. A distance of 0 indicates the end of the -// list of distances. -// -static void _change_walls_from_centre(const dgn_region ®ion, - const coord_def &c, - bool rectangular, - dungeon_feature_type wall, - ...) -{ - std::vector ldist; - - va_list args; - va_start(args, wall); - - while (true) - { - const int dist = va_arg(args, int); - if (!dist) - break; - - const dungeon_feature_type feat = - static_cast( va_arg(args, int) ); - - ldist.push_back(dist_feat(dist, feat)); - } - - _change_walls_from_centre(region, c, rectangular, MMT_VAULT, wall, ldist); -} - static void _place_extra_lab_minivaults(int level_number) { std::set vaults_used; @@ -6492,52 +6480,57 @@ static void _labyrinth_level(int level_number) int vault = random_map_for_tag("minotaur", true, false); vault_placement place; - if (vault != -1) - _init_minivault_placement(vault, place); - coord_def end; + _labyrinth_build_maze(end, lab); + _labyrinth_colour_maze(end, lab); - if (vault == -1 || !_build_minivaults(level_number, vault)) { - vault = -1; - _labyrinth_place_exit(end); - } - else - { - const vault_placement &rplace = *(Level_Vaults.end() - 1); - if (rplace.map.has_tag("generate_loot")) + // If we place any vaults, make sure they overwrite the maze + // colours where appropriate. + dgn_colour_override_manager colour_man; + + if (vault != -1) + _init_minivault_placement(vault, place); + + if (vault == -1 || !_build_minivaults(level_number, vault)) + { + vault = -1; + _labyrinth_place_exit(end); + } + else { - for (int y = rplace.pos.y; - y <= rplace.pos.y + rplace.size.y - 1; ++y) + const vault_placement &rplace = *(Level_Vaults.end() - 1); + if (rplace.map.has_tag("generate_loot")) { - for (int x = rplace.pos.x; - x <= rplace.pos.x + rplace.size.x - 1; ++x) + for (int y = rplace.pos.y; + y <= rplace.pos.y + rplace.size.y - 1; ++y) { - if (grd[x][y] == DNGN_ESCAPE_HATCH_UP) + for (int x = rplace.pos.x; + x <= rplace.pos.x + rplace.size.x - 1; ++x) { - _labyrinth_place_items(coord_def(x, y)); - break; + if (grd[x][y] == DNGN_ESCAPE_HATCH_UP) + { + _labyrinth_place_items(coord_def(x, y)); + break; + } } } } + place.pos = rplace.pos; + place.size = rplace.size; } - place.pos = rplace.pos; - place.size = rplace.size; - } - if (vault != -1) - end = place.pos + place.size / 2; - - _place_extra_lab_minivaults(level_number); + if (vault != -1) + end = place.pos + place.size / 2; - _change_walls_from_centre(lab, end, false, - DNGN_ROCK_WALL, - 15 * 15, DNGN_METAL_WALL, - 34 * 34, DNGN_STONE_WALL, - 0); + _place_extra_lab_minivaults(level_number); + _labyrinth_place_entry_point(lab, end); + } - _labyrinth_place_entry_point(lab, end); + // This must be done outside the scope of the + // dgn_colour_override_manager, or it will undo the colours. + _replace_area(0, 0, GXM - 1, GYM - 1, DNGN_ROCK_WALL, LAB_WALL, MMT_VAULT); link_items(); } diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 4a314fbbf6..d68d027129 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -3004,15 +3004,14 @@ bool monsters::wants_submerge() const || type == MONS_LAVA_SNAKE || (type == MONS_MERMAID && you.species != SP_MERFOLK); - const actor *tfoe = get_foe(); - int roll = 8; // Shallow water takes a little more effort to submerge in, so we're // less likely to bother. if (grd(pos()) == DNGN_SHALLOW_WATER) roll = roll * 7 / 5; - if (foe && grid_distance(tfoe->pos(), pos()) > 1 && !has_ranged_attack) + const actor *tfoe = get_foe(); + if (tfoe && grid_distance(tfoe->pos(), pos()) > 1 && !has_ranged_attack) roll /= 2; // Don't submerge if we just unsubmerged to shout -- cgit v1.2.3-54-g00ecf