summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-20 11:40:25 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-20 11:40:25 +0000
commitb27a757b68bf8a1dcbcb9b3a5cfea5c1278c9bb4 (patch)
tree1f3ba836c9d1cec2e625c6a4382f5babe32a8463 /crawl-ref/source
parentab679653017c1d661572cf34a62bf5ddf7c1304e (diff)
downloadcrawl-ref-b27a757b68bf8a1dcbcb9b3a5cfea5c1278c9bb4.tar.gz
crawl-ref-b27a757b68bf8a1dcbcb9b3a5cfea5c1278c9bb4.zip
Updated travel to allow it to use rock stairs.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1898 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/direct.cc22
-rw-r--r--crawl-ref/source/dungeon.cc27
-rw-r--r--crawl-ref/source/misc.cc6
-rw-r--r--crawl-ref/source/travel.cc97
-rw-r--r--crawl-ref/source/travel.h26
5 files changed, 139 insertions, 39 deletions
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index b2c3382803..745f662aea 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -1526,6 +1526,21 @@ static void describe_monster_weapon(monsters *mons)
mpr(msg.str().c_str());
}
+#ifdef DEBUG_DIAGNOSTICS
+static std::string stair_destination_description(const coord_def &pos)
+{
+ if (LevelInfo *linf = travel_cache.find_level_info(level_id::current()))
+ {
+ const stair_info *si = linf->get_stair(pos);
+ if (si)
+ return (" " + si->describe());
+ else if (is_stair(grd(pos)))
+ return (" (unknown stair)");
+ }
+ return ("");
+}
+#endif
+
static void describe_cell(int mx, int my)
{
bool mimic_item = false;
@@ -1648,10 +1663,13 @@ static void describe_cell(int mx, int my)
std::string marker;
if (map_marker *mark = env.find_marker(coord_def(mx, my), MAT_ANY))
marker = " (" + mark->describe() + ")";
- mprf("(%d,%d): %s - %s%s", mx, my,
+ const std::string traveldest =
+ stair_destination_description(coord_def(mx, my));
+ mprf("(%d,%d): %s - %s%s%s", mx, my,
stringize_glyph(get_screen_glyph(mx, my)).c_str(),
feature_desc.c_str(),
- marker.c_str());
+ marker.c_str(),
+ traveldest.c_str());
#else
mpr(feature_desc.c_str());
#endif
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index f46559ba58..311ea74805 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -294,12 +294,17 @@ static inline bool dgn_grid_is_passable(dungeon_feature_type grid)
&& grid != DNGN_SECRET_DOOR));
}
+static inline bool dgn_square_is_passable(const coord_def &c)
+{
+ return (dgn_map_mask(c) && dgn_grid_is_passable(grd(c)));
+}
+
static inline void dgn_point_record_stub(const coord_def &) { }
template <class point_record>
static void dgn_fill_zone(
const coord_def &c, int zone, point_record &prec,
- bool (*passable)(dungeon_feature_type) = dgn_grid_is_passable)
+ bool (*passable)(const coord_def &) = dgn_square_is_passable)
{
// No bounds checks, assuming the level has at least one layer of
// rock border.
@@ -312,12 +317,8 @@ static void dgn_fill_zone(
continue;
const coord_def cp(c.x + xi, c.y + yi);
- if (travel_point_distance[cp.x][cp.y]
- || dgn_map_mask(cp)
- || !passable(grd(cp)))
- {
+ if (travel_point_distance[cp.x][cp.y] || !passable(cp))
continue;
- }
prec(cp);
dgn_fill_zone(cp, zone, prec);
@@ -6448,6 +6449,13 @@ struct nearest_point
}
};
+inline static bool dgn_square_travel_ok(const coord_def &c)
+{
+ const dungeon_feature_type feat = grd(c);
+ return (is_traversable(feat) || grid_is_trap(feat)
+ || feat == DNGN_SECRET_DOOR);
+}
+
// Fill travel_point_distance out from all stone stairs on the level.
static coord_def dgn_find_closest_to_stone_stairs()
{
@@ -6457,17 +6465,12 @@ static coord_def dgn_find_closest_to_stone_stairs()
for (int y = 0; y < GYM; ++y)
for (int x = 0; x < GXM; ++x)
if (!travel_point_distance[x][y] && grid_is_stone_stair(grd[x][y]))
- dgn_fill_zone(coord_def(x, y), 1, np, is_traversable);
+ dgn_fill_zone(coord_def(x, y), 1, np, dgn_square_travel_ok);
return (np.nearest);
}
coord_def dgn_find_nearby_stair(int stair_to_find, bool find_closest)
{
-#ifdef DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "Placing PC on %s",
- dungeon_feature_name(
- static_cast<dungeon_feature_type>(stair_to_find)));
-#endif
if (stair_to_find == DNGN_ROCK_STAIRS_UP
|| stair_to_find == DNGN_ROCK_STAIRS_DOWN)
{
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 0a83963b72..be7d8d1e1f 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -601,9 +601,9 @@ void up_stairs(void)
int old_level = you.your_level;
// Interlevel travel data:
- bool collect_travel_data = you.level_type != LEVEL_LABYRINTH
- && you.level_type != LEVEL_ABYSS
- && you.level_type != LEVEL_PANDEMONIUM;
+ const bool collect_travel_data = you.level_type != LEVEL_LABYRINTH
+ && you.level_type != LEVEL_ABYSS
+ && you.level_type != LEVEL_PANDEMONIUM;
level_id old_level_id = level_id::current();
LevelInfo &old_level_info = travel_cache.get_level_info(old_level_id);
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index b5c6b48b04..3bdd1219db 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -44,7 +44,7 @@
#endif
#define TC_MAJOR_VERSION ((unsigned char) 4)
-#define TC_MINOR_VERSION ((unsigned char) 7)
+#define TC_MINOR_VERSION ((unsigned char) 9)
enum IntertravelDestination
{
@@ -2393,6 +2393,11 @@ static int find_transtravel_stair( const level_id &cur,
for (int i = 0, count = stairs.size(); i < count; ++i)
{
stair_info &si = stairs[i];
+
+ // Skip placeholders, since there are no real stairs there.
+ if (!si.can_travel())
+ continue;
+
int deltadist = li.distance_between(this_stair, &si);
if (!this_stair)
{
@@ -2461,9 +2466,7 @@ static int find_transtravel_stair( const level_id &cur,
// We need to get the stairs at the new location and set the
// distance on them as well.
LevelInfo &lo = travel_cache.get_level_info(dest.id);
- stair_info *so = lo.get_stair(dest.pos);
-
- if (so)
+ if (stair_info *so = lo.get_stair(dest.pos))
{
if (so->distance == -1 || so->distance > dist2stair)
so->distance = dist2stair;
@@ -2472,7 +2475,8 @@ static int find_transtravel_stair( const level_id &cur,
}
// Okay, take these stairs and keep going.
- int newdist = find_transtravel_stair(dest.id, target,
+ const int newdist =
+ find_transtravel_stair(dest.id, target,
dist2stair, dest.pos, closest_level,
best_level_distance, best_stair,
target_has_excludes);
@@ -2789,14 +2793,36 @@ void stair_info::save(FILE *file) const
writeShort(file, grid);
destination.save(file);
writeByte(file, guessed_pos? 1 : 0);
+ writeByte(file, type);
}
void stair_info::load(FILE *file)
{
readCoord(file, position);
- grid = readShort(file);
+ grid = static_cast<dungeon_feature_type>(readShort(file));
destination.load(file);
guessed_pos = readByte(file) != 0;
+ type = static_cast<stair_type>(readByte(file));
+}
+
+std::string stair_info::describe() const
+{
+ if (destination.is_valid())
+ {
+ const level_pos &lp(destination);
+ return
+ make_stringf(
+ " (-> %s@(%d,%d)%s%s)", lp.id.describe().c_str(),
+ lp.pos.x, lp.pos.y,
+ guessed_pos? " guess" : "",
+ type == PLACEHOLDER? " placeholder" : "");
+ }
+ else if (destination.id.is_valid())
+ {
+ return make_stringf(
+ " (->%s (?))", destination.id.describe().c_str());
+ }
+ return (" (?)");
}
void LevelInfo::set_level_excludes()
@@ -2882,6 +2908,34 @@ void LevelInfo::update_stair(int x, int y, const level_pos &p, bool guess)
if (si->destination.id.branch != id.branch)
sync_branch_stairs(si);
}
+ else if (!si && guess)
+ {
+ create_placeholder_stair(coord_def(x, y), p);
+ }
+}
+
+void LevelInfo::create_placeholder_stair(const coord_def &stair,
+ const level_pos &dest)
+{
+ // If there are any existing placeholders with the same 'dest', zap them.
+ for (int i = 0, size = stairs.size(); i < size; ++i)
+ {
+ if (stairs[i].type == stair_info::PLACEHOLDER
+ && stairs[i].destination == dest)
+ {
+ stairs.erase( stairs.begin() + i );
+ break;
+ }
+ }
+
+ stair_info placeholder;
+ placeholder.position = stair;
+ placeholder.grid = DNGN_FLOOR;
+ placeholder.destination = dest;
+ placeholder.type = stair_info::PLACEHOLDER;
+ stairs.push_back(placeholder);
+
+ resize_stair_distances();
}
// If a stair leading out of or into a branch has a known destination, all
@@ -2940,7 +2994,7 @@ stair_info *LevelInfo::get_stair(const coord_def &pos)
int LevelInfo::get_stair_index(const coord_def &pos) const
{
- for (int i = stairs.size() - 1; i >= 0; --i)
+ for (int i = static_cast<int>(stairs.size()) - 1; i >= 0; --i)
{
if (stairs[i].position == pos)
return i;
@@ -2955,6 +3009,9 @@ void LevelInfo::correct_stair_list(const std::vector<coord_def> &s)
// First we kill any stairs in 'stairs' that aren't there in 's'.
for (int i = ((int) stairs.size()) - 1; i >= 0; --i)
{
+ if (stairs[i].type != stair_info::PHYSICAL)
+ continue;
+
bool found = false;
for (int j = s.size() - 1; j >= 0; --j)
{
@@ -2973,17 +3030,17 @@ void LevelInfo::correct_stair_list(const std::vector<coord_def> &s)
// in 'stairs'.
for (int i = 0, sz = s.size(); i < sz; ++i)
{
- bool found = false;
+ int found = -1;
for (int j = stairs.size() - 1; j >= 0; --j)
{
if (s[i] == stairs[j].position)
{
- found = true;
+ found = j;
break;
}
}
- if (!found)
+ if (found == -1)
{
stair_info si;
si.position = s[i];
@@ -2999,11 +3056,20 @@ void LevelInfo::correct_stair_list(const std::vector<coord_def> &s)
// in whenever the player takes these stairs.
stairs.push_back(si);
}
+ else
+ {
+ stairs[found].type = stair_info::PHYSICAL;
+ }
}
+ resize_stair_distances();
+}
+
+void LevelInfo::resize_stair_distances()
+{
const int nstairs = stairs.size();
stair_distances.reserve( nstairs * nstairs );
- stair_distances.resize( nstairs * nstairs, 0 );
+ stair_distances.resize( nstairs * nstairs, 0 );
}
int LevelInfo::distance_between(const stair_info *s1, const stair_info *s2)
@@ -3028,11 +3094,10 @@ void LevelInfo::get_stairs(std::vector<coord_def> &st)
dungeon_feature_type grid = grd[x][y];
int envc = env.map[x][y].object;
- if ((x == you.x_pos && y == you.y_pos)
- || (envc
- && is_travelable_stair(grid)
- && (is_terrain_seen(x, y)
- || !is_branch_stair(x, y))))
+ if (((x == you.x_pos && y == you.y_pos)
+ || envc)
+ && is_travelable_stair(grid)
+ && (is_terrain_seen(x, y) || !is_branch_stair(x, y)))
{
// Convert to grid coords, because that's what we use
// everywhere else.
diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h
index 7f234ca7da..a4e4317220 100644
--- a/crawl-ref/source/travel.h
+++ b/crawl-ref/source/travel.h
@@ -344,27 +344,37 @@ private:
struct stair_info
{
+public:
+ enum stair_type
+ {
+ PHYSICAL,
+ PLACEHOLDER
+ };
+
+public:
coord_def position; // Position of stair
- int grid; // Grid feature of the stair.
+ dungeon_feature_type grid; // Grid feature of the stair.
level_pos destination; // The level and the position on the level this
// stair leads to. This may be a guess.
int distance; // The distance traveled to reach this stair.
bool guessed_pos; // true if we're not sure that 'destination' is
// correct.
+ stair_type type;
stair_info()
: position(-1, -1), grid(DNGN_FLOOR), destination(),
- distance(-1), guessed_pos(true)
+ distance(-1), guessed_pos(true), type(PHYSICAL)
{
}
- void clear_distance()
- {
- distance = -1;
- }
+ void clear_distance() { distance = -1; }
void save(FILE *) const;
void load(FILE *);
+
+ std::string describe() const;
+
+ bool can_travel() const { return (type == PHYSICAL); }
};
struct travel_exclude
@@ -447,6 +457,10 @@ private:
level_id id;
friend class TravelCache;
+
+private:
+ void create_placeholder_stair(const coord_def &, const level_pos &);
+ void resize_stair_distances();
};
const int TRAVEL_WAYPOINT_COUNT = 10;