summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/dungeon.cc17
-rw-r--r--crawl-ref/source/files.cc17
-rw-r--r--crawl-ref/source/it_use3.cc18
-rw-r--r--crawl-ref/source/misc.cc33
4 files changed, 74 insertions, 11 deletions
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 708fdf1064..a8733319e1 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -7747,6 +7747,23 @@ coord_def dgn_find_nearby_stair(dungeon_feature_type stair_to_find,
dungeon_feature_name(stair_to_find));
#endif
+ if (stair_to_find == DNGN_EXIT_PORTAL_VAULT)
+ {
+ const coord_def pos(_dgn_find_feature_marker(stair_to_find));
+ if (in_bounds(pos))
+ {
+ if (map_marker *marker = env.markers.find(pos, MAT_FEATURE))
+ env.markers.remove(marker);
+ return (pos);
+ }
+
+#ifdef DEBUG_DIAGNOSTICS
+ mprf(MSGCH_WARN, "Ouch, no portal vault exit point!");
+#endif
+
+ stair_to_find = DNGN_FLOOR;
+ }
+
if (stair_to_find == DNGN_ESCAPE_HATCH_UP
|| stair_to_find == DNGN_ESCAPE_HATCH_DOWN)
{
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 792f541063..d2085cc678 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -820,7 +820,8 @@ static void _sanity_test_monster_inventory()
}
}
-static void _place_player_on_stair(branch_type old_branch,
+static void _place_player_on_stair(level_area_type old_level_type,
+ branch_type old_branch,
int stair_taken)
{
bool find_first = true;
@@ -849,6 +850,14 @@ static void _place_player_on_stair(branch_type old_branch,
// The vestibule and labyrinth always start from this stair.
stair_taken = DNGN_EXIT_HELL;
}
+ else if (stair_taken == DNGN_EXIT_PORTAL_VAULT
+ || ((old_level_type == LEVEL_LABYRINTH
+ || old_level_type == LEVEL_PORTAL_VAULT)
+ && (stair_taken == DNGN_ESCAPE_HATCH_DOWN
+ || stair_taken == DNGN_ESCAPE_HATCH_UP)))
+ {
+ stair_taken = DNGN_EXIT_PORTAL_VAULT;
+ }
else if (stair_taken >= DNGN_STONE_STAIRS_DOWN_I
&& stair_taken <= DNGN_ESCAPE_HATCH_DOWN)
{
@@ -885,10 +894,6 @@ static void _place_player_on_stair(branch_type old_branch,
{
stair_taken = DNGN_STONE_ARCH;
}
- else if (stair_taken == DNGN_EXIT_PORTAL_VAULT)
- {
- stair_taken = DNGN_ESCAPE_HATCH_DOWN;
- }
else if (stair_taken == DNGN_ENTER_LABYRINTH)
{
// dgn_find_nearby_stair uses special logic for labyrinths.
@@ -1197,7 +1202,7 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode,
{
_clear_clouds();
if (you.level_type != LEVEL_ABYSS)
- _place_player_on_stair(old_branch, stair_taken);
+ _place_player_on_stair(old_level_type, old_branch, stair_taken);
else
you.moveto(coord_def(45, 35)); // FIXME: should be abyss_center
}
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 6405cf33a3..b5e79d0872 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -364,8 +364,22 @@ static bool evoke_horn_of_geryon()
{
map_feature_marker *featm =
dynamic_cast<map_feature_marker*>(marker);
- grd[count_x][count_y] = featm->feat;
- env.markers.remove(marker);
+ // [ds] Ensure we're activating the correct feature
+ // markers. Feature markers are also used for other
+ // things, notably to indicate the return point from
+ // a labyrinth or portal vault.
+ switch (featm->feat)
+ {
+ case DNGN_ENTER_COCYTUS:
+ case DNGN_ENTER_DIS:
+ case DNGN_ENTER_GEHENNA:
+ case DNGN_ENTER_TARTARUS:
+ grd[count_x][count_y] = featm->feat;
+ env.markers.remove(marker);
+ break;
+ default:
+ break;
+ }
}
}
}
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 1b950bc588..5414e6b14f 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -53,6 +53,7 @@
#include "lev-pand.h"
#include "macro.h"
#include "makeitem.h"
+#include "mapmark.h"
#include "message.h"
#include "mon-util.h"
#include "monstuff.h"
@@ -1691,6 +1692,26 @@ void up_stairs(dungeon_feature_type force_stair,
request_autopickup();
} // end up_stairs()
+// Adds a dungeon marker at the point of the level where returning from
+// a labyrinth or portal vault should drop the player.
+static void _mark_portal_return_point(const coord_def &pos)
+{
+ // First toss all markers of this type. Stale markers are possible
+ // if the player goes to the Abyss from a portal vault /
+ // labyrinth, thus returning to this level without activating a
+ // previous portal vault exit marker.
+ const std::vector<map_marker*> markers = env.markers.get_all(MAT_FEATURE);
+ for (int i = 0, size = markers.size(); i < size; ++i)
+ env.markers.remove(markers[i]);
+
+ if (!env.markers.find(pos, MAT_FEATURE))
+ {
+ map_feature_marker *mfeat =
+ new map_feature_marker(pos, DNGN_EXIT_PORTAL_VAULT);
+ env.markers.add(mfeat);
+ }
+}
+
void down_stairs( int old_level, dungeon_feature_type force_stair,
entry_cause_type entry_cause )
{
@@ -1825,9 +1846,9 @@ void down_stairs( int old_level, dungeon_feature_type force_stair,
}
// Interlevel travel data.
- bool collect_travel_data = can_travel_interlevel();
+ const bool collect_travel_data = can_travel_interlevel();
- level_id old_level_id = level_id::current();
+ const level_id old_level_id = level_id::current();
LevelInfo &old_level_info = travel_cache.get_level_info(old_level_id);
const coord_def stair_pos = you.pos();
if (collect_travel_data)
@@ -1872,7 +1893,13 @@ void down_stairs( int old_level, dungeon_feature_type force_stair,
}
if (stair_find == DNGN_ENTER_LABYRINTH)
- dungeon_terrain_changed(you.pos(), DNGN_FLOOR);
+ dungeon_terrain_changed(you.pos(), DNGN_STONE_ARCH);
+
+ if (stair_find == DNGN_ENTER_LABYRINTH
+ || stair_find == DNGN_ENTER_PORTAL_VAULT)
+ {
+ _mark_portal_return_point(you.pos());
+ }
if (stair_find == DNGN_ENTER_LABYRINTH)
you.level_type = LEVEL_LABYRINTH;