diff options
-rw-r--r-- | crawl-ref/source/dungeon.cc | 84 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/files.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.cc | 11 | ||||
-rw-r--r-- | crawl-ref/source/mapmark.h | 1 |
5 files changed, 108 insertions, 7 deletions
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index cb6391feb4..469a8de116 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -5600,6 +5600,58 @@ static void place_extra_lab_minivaults(int level_number) } } +// Checks if there is a square with the given mask within radius of pos. +static bool has_vault_in_radius(const coord_def &pos, int radius, + unsigned mask) +{ + for (int yi = -radius; yi <= radius; ++yi) + { + for (int xi = -radius; xi <= radius; ++xi) + { + const coord_def p = pos + coord_def(xi, yi); + if (!in_bounds(p)) + continue; + if (!unforbidden(p, mask)) + return (true); + } + } + return (false); +} + +// Find an entry point that's: +// * At least 25 squares away from the exit. +// * At least 4 squares away from the nearest vault. +// * Floor (well, obviously). +static coord_def labyrinth_find_entry_point(const dgn_region ®, + const coord_def &end) +{ + const int min_distance = 25 * 25; + // Try many times. + for (int i = 0; i < 2000; ++i) + { + const coord_def place = reg.random_point(); + if (grd(place) != DNGN_FLOOR) + continue; + + if ((place - end).abs() < min_distance) + continue; + + if (has_vault_in_radius(place, 4, MMT_VAULT)) + continue; + + return (place); + } + return (coord_def()); +} + +static void labyrinth_place_entry_point(const dgn_region ®ion, + const coord_def &pos) +{ + const coord_def p = labyrinth_find_entry_point(region, pos); + if (in_bounds(p)) + env_add_marker(new map_feature_marker(pos, DNGN_ENTER_LABYRINTH)); +} + static void labyrinth_level(int level_number) { dgn_region lab = @@ -5665,6 +5717,8 @@ static void labyrinth_level(int level_number) 15 * 15, DNGN_METAL_WALL, 34 * 34, DNGN_STONE_WALL, 0); + + labyrinth_place_entry_point(lab, end); // turn rock walls into undiggable stone or metal: // dungeon_feature_type wall_xform = @@ -6760,7 +6814,24 @@ static coord_def dgn_find_closest_to_stone_stairs() return (np.nearest); } -coord_def dgn_find_nearby_stair(int stair_to_find, bool find_closest) +static coord_def dgn_find_labyrinth_entry_point() +{ + std::vector<map_marker*> markers = env_get_all_markers(); + for (int i = 0, size = markers.size(); i < size; ++i) + { + map_marker *mark = markers[i]; + if (mark->get_type() == MAT_FEATURE + && dynamic_cast<map_feature_marker*>(mark)->feat + == DNGN_ENTER_LABYRINTH) + { + return (mark->pos); + } + } + return (coord_def()); +} + +coord_def dgn_find_nearby_stair(dungeon_feature_type stair_to_find, + bool find_closest) { if (stair_to_find == DNGN_ROCK_STAIRS_UP || stair_to_find == DNGN_ROCK_STAIRS_DOWN) @@ -6769,6 +6840,17 @@ coord_def dgn_find_nearby_stair(int stair_to_find, bool find_closest) if (in_bounds(pos)) return (pos); } + + if (stair_to_find == DNGN_ENTER_LABYRINTH) + { + const coord_def pos(dgn_find_labyrinth_entry_point()); + if (in_bounds(pos)) + return (pos); + + // Couldn't find a good place, warn, and use old behaviour. + mpr("Oops, couldn't find labyrinth entry marker.", MSGCH_DIAGNOSTICS); + stair_to_find = DNGN_FLOOR; + } // scan around the player's position first int basex = you.x_pos; diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h index 9561e587b5..36cf1e0e28 100644 --- a/crawl-ref/source/dungeon.h +++ b/crawl-ref/source/dungeon.h @@ -281,6 +281,7 @@ bool place_specific_trap(int spec_x, int spec_y, trap_type spec_type); void place_spec_shop(int level_number, int shop_x, int shop_y, int force_s_type, bool representative = false); bool unforbidden(const coord_def &c, unsigned mask); -coord_def dgn_find_nearby_stair(int stair_to_find, bool find_closest); +coord_def dgn_find_nearby_stair(dungeon_feature_type stair_to_find, + bool find_closest); #endif diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 437ea5b389..bc9704669f 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -643,7 +643,8 @@ static void sanity_test_monster_inventory() } } -static void place_player_on_stair(branch_type old_branch, int stair_taken) +static void place_player_on_stair(branch_type old_branch, + int stair_taken) { bool find_first = true; @@ -666,8 +667,7 @@ static void place_player_on_stair(branch_type old_branch, int stair_taken) stair_taken = DNGN_ENTER_ABYSS; find_first = false; } - else if (stair_taken == DNGN_ENTER_HELL - || stair_taken == DNGN_ENTER_LABYRINTH) + else if (stair_taken == DNGN_ENTER_HELL) { // the vestibule and labyrith always start from this stair stair_taken = DNGN_STONE_STAIRS_UP_I; @@ -710,7 +710,12 @@ static void place_player_on_stair(branch_type old_branch, int stair_taken) } else if (stair_taken == DNGN_EXIT_PORTAL_VAULT) { - stair_taken = DNGN_STONE_STAIRS_DOWN_I; + stair_taken = DNGN_ROCK_STAIRS_DOWN; + } + else if (stair_taken == DNGN_ENTER_LABYRINTH) + { + // dgn_find_nearby_stair uses special logic for labyrinths. + stair_taken = DNGN_ENTER_LABYRINTH; } else // Note: stair_taken can equal things like DNGN_FLOOR { @@ -720,7 +725,8 @@ static void place_player_on_stair(branch_type old_branch, int stair_taken) } const coord_def where_to_go = - dgn_find_nearby_stair(stair_taken, find_first); + dgn_find_nearby_stair(static_cast<dungeon_feature_type>(stair_taken), + find_first); you.moveto(where_to_go); } diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc index 191466f9e2..366d4aa37d 100644 --- a/crawl-ref/source/mapmark.cc +++ b/crawl-ref/source/mapmark.cc @@ -442,6 +442,17 @@ void env_move_markers(const coord_def &from, const coord_def &to) } } +std::vector<map_marker*> env_get_all_markers() +{ + std::vector<map_marker*> rmarkers; + for (dgn_marker_map::const_iterator i = env.markers.begin(); + i != env.markers.end(); ++i) + { + rmarkers.push_back(i->second); + } + return (rmarkers); +} + std::vector<map_marker*> env_get_markers(const coord_def &c) { std::pair<dgn_marker_map::const_iterator, dgn_marker_map::const_iterator> diff --git a/crawl-ref/source/mapmark.h b/crawl-ref/source/mapmark.h index 49983e8017..f8137d4308 100644 --- a/crawl-ref/source/mapmark.h +++ b/crawl-ref/source/mapmark.h @@ -104,6 +104,7 @@ void env_activate_markers(); void env_add_marker(map_marker *); void env_remove_marker(map_marker *); void env_remove_markers_at(const coord_def &c, map_marker_type); +std::vector<map_marker*> env_get_all_markers(); map_marker *env_find_marker(const coord_def &c, map_marker_type); std::vector<map_marker*> env_get_markers(const coord_def &c); void env_clear_markers(); |