summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-08-04 10:01:49 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-08-04 10:01:49 +0000
commit5f0573841648581363fc0ce9a33a778c40370b6f (patch)
treed25224ab0b2e43241561227d0a5efcf6bd6c9dd6
parentf6560b8a7a40642b77680014677087f8ab2172a9 (diff)
downloadcrawl-ref-5f0573841648581363fc0ce9a33a778c40370b6f.tar.gz
crawl-ref-5f0573841648581363fc0ce9a33a778c40370b6f.zip
Trunk-0.4 r6764: Warn the player if interlevel travel is going to take them to a level outside the range [src,dest] (rax, doy). ^G => Esc in yesno prompts.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.4@6765 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/stuff.cc5
-rw-r--r--crawl-ref/source/travel.cc83
-rw-r--r--crawl-ref/source/travel.h8
3 files changed, 94 insertions, 2 deletions
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index 3406decaa9..67f50b723f 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -1008,7 +1008,8 @@ bool yesno( const char *str, bool safe, int safeanswer, bool clear_after,
tmp = map->find(tmp)->second;
if (safeanswer
- && (tmp == ' ' || tmp == 27 || tmp == '\r' || tmp == '\n'))
+ && (tmp == ' ' || tmp == ESCAPE || tmp == CONTROL('G')
+ || tmp == '\r' || tmp == '\n'))
{
tmp = safeanswer;
}
@@ -1103,7 +1104,7 @@ int yesnoquit( const char* str, bool safe, int safeanswer, bool allow_all,
int tmp = getchm(KC_CONFIRM);
- if (tmp == CK_ESCAPE || tmp == 'q' || tmp == 'Q')
+ if (tmp == CK_ESCAPE || tmp == CONTROL('G') || tmp == 'q' || tmp == 'Q')
return -1;
if ((tmp == ' ' || tmp == '\r' || tmp == '\n') && safeanswer)
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index da2685d2e0..058cbf7d22 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -93,6 +93,10 @@ static level_id last_stair;
// Where travel wants to get to.
static travel_target level_target;
+// How many stairs there are between the source and destination of
+// interlevel travel, as estimated by level_distance.
+static int _Src_Dest_Level_Delta = -1;
+
// Remember the last place explore stopped because autopickup failed.
static coord_def explore_stopped_pos;
@@ -123,6 +127,56 @@ const signed char FORBIDDEN = -1;
// Map of terrain types that are traversable.
static signed char traversable_terrain[256];
+/*
+ * Warn if interlevel travel is going to take you outside levels in
+ * the range [src,dest].
+ */
+class deviant_route_warning
+{
+private:
+ travel_target target;
+ bool warned;
+
+public:
+ deviant_route_warning(): target(), warned(false)
+ {
+ }
+
+ void new_dest(const travel_target &dest);
+ bool warn_continue_travel(const travel_target &des,
+ const level_id &deviant);
+};
+
+void deviant_route_warning::new_dest(const travel_target &dest)
+{
+ if (target != dest)
+ {
+ warned = false;
+ target = dest;
+ }
+}
+
+// Returns true if the player wants to continue travelling after the warning.
+bool deviant_route_warning::warn_continue_travel(
+ const travel_target &dest, const level_id &deviant)
+{
+ // We've already prompted, don't ask again, on the player's head be it.
+ if (target == dest && warned)
+ return (true);
+
+ target = dest;
+ const std::string prompt =
+ make_stringf("Have to go through %s. Continue?",
+ deviant.describe().c_str());
+ // If the user says "Yes, shut up and take me there", we won't ask
+ // again for that destination. If the user says "No", we will
+ // prompt again.
+ cursor_control con(true);
+ return ((warned = yesno(prompt.c_str(), true, 'n', true, false)));
+}
+
+static deviant_route_warning _Route_Warning;
+
static command_type _trans_negotiate_stairs();
static bool _find_transtravel_square(const level_pos &pos,
bool verbose = true);
@@ -2442,6 +2496,12 @@ void start_translevel_travel(bool prompt_for_destination)
you.running = RMODE_INTERLEVEL;
you.running.x = you.running.y = 0;
last_stair.depth = -1;
+
+ _Route_Warning.new_dest(level_target);
+
+ _Src_Dest_Level_Delta = level_distance(level_id::current(),
+ level_target.p.id);
+
_start_running();
}
}
@@ -2760,6 +2820,29 @@ static bool _find_transtravel_square(const level_pos &target, bool verbose)
if (best_stair.x != -1 && best_stair.y != -1)
{
+ // Is this stair going offlevel?
+ if ((level_target.p.id != current || level_target.p.pos != best_stair)
+ && _Src_Dest_Level_Delta != -1)
+ {
+ // If so, is the original level closer to the target level than
+ // the destination of the stair?
+ LevelInfo &li = travel_cache.get_level_info(current);
+ const stair_info *dest_stair = li.get_stair(best_stair);
+
+ if (dest_stair && dest_stair->destination.id.is_valid())
+ {
+ const int ndist =
+ level_distance(dest_stair->destination.id,
+ level_target.p.id);
+
+ if (_Src_Dest_Level_Delta < ndist
+ && !_Route_Warning.warn_continue_travel(
+ level_target,
+ dest_stair->destination.id))
+ return (false);
+ }
+ }
+
you.running.x = best_stair.x;
you.running.y = best_stair.y;
return (true);
diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h
index 752c285044..cd34eda39d 100644
--- a/crawl-ref/source/travel.h
+++ b/crawl-ref/source/travel.h
@@ -345,6 +345,14 @@ struct travel_target
p.clear();
entrance_only = false;
}
+ bool operator == (const travel_target &other) const
+ {
+ return p == other.p && entrance_only == other.entrance_only;
+ }
+ bool operator != (const travel_target &other) const
+ {
+ return !operator == (other);
+ }
};
// Tracks items discovered by explore in this turn.