summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/travel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/travel.cc')
-rw-r--r--crawl-ref/source/travel.cc53
1 files changed, 50 insertions, 3 deletions
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index 1ad2b3be59..2c1e89e070 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -31,6 +31,7 @@
#include "view.h"
#include <algorithm>
+#include <set>
#include <cstdarg>
#include <cctype>
#include <cstdio>
@@ -40,7 +41,7 @@
#endif
#define TC_MAJOR_VERSION ((unsigned char) 4)
-#define TC_MINOR_VERSION ((unsigned char) 5)
+#define TC_MINOR_VERSION ((unsigned char) 6)
enum IntertravelDestination
{
@@ -2600,6 +2601,7 @@ void level_pos::load(FILE *file)
void stair_info::save(FILE *file) const
{
writeCoord(file, position);
+ writeShort(file, grid);
destination.save(file);
writeByte(file, guessed_pos? 1 : 0);
}
@@ -2607,6 +2609,7 @@ void stair_info::save(FILE *file) const
void stair_info::load(FILE *file)
{
readCoord(file, position);
+ grid = readShort(file);
destination.load(file);
guessed_pos = readByte(file) != 0;
}
@@ -2658,6 +2661,7 @@ void LevelInfo::update()
// Make sure our stair list is correct.
correct_stair_list(stair_positions);
+ sync_all_branch_stairs();
update_stair_distances();
}
@@ -2711,6 +2715,45 @@ void LevelInfo::update_stair(int x, int y, const level_pos &p, bool guess)
if (!guess && p.id.branch == BRANCH_VESTIBULE_OF_HELL
&& id.branch == BRANCH_MAIN_DUNGEON)
travel_hell_entry = p;
+
+ // All branch stairs land on the same place on the destination level,
+ // update the cache accordingly (but leave guessed_pos = true). This
+ // applies for both branch exits (the usual case) and branch entrances.
+ if (si->destination.id.branch != id.branch)
+ sync_branch_stairs(si);
+ }
+}
+
+// If a stair leading out of or into a branch has a known destination, all
+// stairs of the same type on this level should have the same destination set
+// as guessed_pos == true.
+void LevelInfo::sync_all_branch_stairs()
+{
+ std::set<int> synced;
+
+ for (int i = 0, size = stairs.size(); i < size; ++i)
+ {
+ const stair_info &si = stairs[i];
+ if (si.destination.id.branch != id.branch && si.destination.is_valid()
+ && synced.find(si.grid) == synced.end())
+ {
+ synced.insert( si.grid );
+ sync_branch_stairs( &si );
+ }
+ }
+}
+
+void LevelInfo::sync_branch_stairs(const stair_info *si)
+{
+ for (int i = 0, size = stairs.size(); i < size; ++i)
+ {
+ stair_info &sother = stairs[i];
+ if (si == &sother || !sother.guessed_pos || si->grid != sother.grid
+ || sother.destination.is_valid())
+ {
+ continue;
+ }
+ sother.destination = si->destination;
}
}
@@ -2820,6 +2863,7 @@ void LevelInfo::correct_stair_list(const std::vector<coord_def> &s)
{
stair_info si;
si.position = s[i];
+ si.grid = grd(si.position);
si.destination.id = level_id::get_next_level_id(s[i]);
if (si.destination.id.branch == BRANCH_VESTIBULE_OF_HELL
&& id.branch == BRANCH_MAIN_DUNGEON
@@ -2856,8 +2900,8 @@ void LevelInfo::get_stairs(std::vector<coord_def> &st)
{
for (int x = 0; x < GXM - 1; ++x)
{
- unsigned char grid = grd[x + 1][y + 1];
- unsigned char envc = (unsigned char) env.map[x][y];
+ int grid = grd[x + 1][y + 1];
+ int envc = (unsigned char) env.map[x][y];
if ((x + 1 == you.x_pos && y + 1 == you.y_pos)
|| (envc
@@ -3159,6 +3203,9 @@ void TravelCache::save(FILE *file) const
levels.begin();
for ( ; i != levels.end(); ++i)
{
+ // LevelInfos will also be created for levels in the Abyss and
+ // Pandemonium, but they shouldn't be saved because the
+ // information in them is useless.
if (i->first.level_type != LEVEL_DUNGEON)
continue;