summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/dat/descript/cards.txt10
-rw-r--r--crawl-ref/source/dat/descript/items.txt8
-rw-r--r--crawl-ref/source/files.cc5
-rw-r--r--crawl-ref/source/misc.cc2
-rw-r--r--crawl-ref/source/overmap.cc42
-rw-r--r--crawl-ref/source/overmap.h7
-rw-r--r--crawl-ref/source/spells4.cc2
-rw-r--r--crawl-ref/source/tags.cc15
-rw-r--r--crawl-ref/source/tags.h3
-rw-r--r--crawl-ref/source/travel.cc90
-rw-r--r--crawl-ref/source/travel.h26
-rw-r--r--crawl-ref/source/view.cc3
12 files changed, 173 insertions, 40 deletions
diff --git a/crawl-ref/source/dat/descript/cards.txt b/crawl-ref/source/dat/descript/cards.txt
index f945df51d4..24fcb33346 100644
--- a/crawl-ref/source/dat/descript/cards.txt
+++ b/crawl-ref/source/dat/descript/cards.txt
@@ -103,6 +103,11 @@ Experience card
This card makes you more experienced.
It is usually found in decks of changes and wonders.
%%%%
+Wild Magic card
+
+This card causes wild magic, as if from miscasting a spell, to act upon you.
+It is usually found in the deck of wonders.
+%%%%
the Helix card
This cards changes your mutations. Higher power levels make the change more likely to be beneficial.
@@ -251,11 +256,6 @@ Famine card
This card starves you.
It is usually only found in Nemelex Xobeh's deck of punishment.
%%%%
-Wild Magic card
-
-This card causes wild magic, as if from miscasting a spell, to act upon you.
-It is usually only found in Nemelex Xobeh's deck of punishment.
-%%%%
# deck of oddities (random card, along with a few others)
the Bargain card
diff --git a/crawl-ref/source/dat/descript/items.txt b/crawl-ref/source/dat/descript/items.txt
index a42add8db1..a30b6ad72d 100644
--- a/crawl-ref/source/dat/descript/items.txt
+++ b/crawl-ref/source/dat/descript/items.txt
@@ -509,7 +509,7 @@ deck of wonders
A deck of highly mysterious and magical cards, which can permanently
alter the drawer's physical and mental condition, for better or worse.
-It may contain the following cards: the Potion, Focus, Shuffle, Experience, the Helix, the Sage.
+It may contain the following cards: the Potion, Focus, Shuffle, Experience, Wild Magic, the Helix, the Sage.
%%%%
demon blade
@@ -1309,9 +1309,9 @@ not apply to beings fully immune to magic.
scroll of silence
This scroll eliminates all sound near the reader. This makes reading
-scrolls, casting spells, praying or yelling in the reader's vicinity
-impossible. (Applies to reader too, of course.) This silence will not
-hide your presence, since its oppressive, unnatural effect will almost
+scrolls, casting spells, praying or yelling in the reader's vicinity
+impossible. (Applies to reader too, of course.) This silence will not
+hide your presence, since its oppressive, unnatural effect will almost
certainly alert any living creature that something is very wrong.
%%%%
scythe
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 78d86aa5a1..b10808d4a9 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -1441,7 +1441,10 @@ bool load( dungeon_feature_type stair_taken, load_mode_type load_mode,
you.attribute[ATTR_ABYSS_ENTOURAGE] = 0;
if (load_mode != LOAD_VISITOR)
+ {
dungeon_events.fire_event(DET_ENTERED_LEVEL);
+// set_level_exclusion_annotation(get_exclusion_desc());
+ }
if (load_mode == LOAD_ENTER_LEVEL)
{
@@ -1818,7 +1821,7 @@ void restore_game(void)
if (travelf)
{
reader inf(travelf);
- travel_cache.load(inf);
+ travel_cache.load(inf, minorVersion);
fclose(travelf);
}
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index f7c10046fe..6181cea8f0 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -2769,7 +2769,7 @@ void set_auto_exclude(const monsters *mon)
{
if (need_auto_exclude(mon) && !is_exclude_root(mon->pos()))
{
- toggle_exclude(mon->pos());
+ toggle_exclude(mon->pos(), true);
#ifdef USE_TILE
viewwindow(true, false);
#endif
diff --git a/crawl-ref/source/overmap.cc b/crawl-ref/source/overmap.cc
index 5c1df7c285..26d797ef72 100644
--- a/crawl-ref/source/overmap.cc
+++ b/crawl-ref/source/overmap.cc
@@ -57,6 +57,7 @@ portal_vault_map_type portal_vaults_present;
portal_note_map_type portal_vault_notes;
portal_vault_colour_map_type portal_vault_colours;
annotation_map_type level_annotations;
+annotation_map_type level_exclusions;
static void _seen_altar( god_type god, const coord_def& pos );
static void _seen_staircase(dungeon_feature_type which_staircase,
@@ -721,14 +722,45 @@ void clear_level_annotation(level_id li)
level_annotations.erase(li);
}
-std::string get_level_annotation(level_id li)
+void set_level_exclusion_annotation(std::string str, level_id li)
+{
+ if (str.empty())
+ {
+ clear_level_exclusion_annotation(li);
+ return;
+ }
+
+ level_exclusions[li] = str;
+}
+
+void clear_level_exclusion_annotation(level_id li)
+{
+ level_exclusions.erase(li);
+}
+
+std::string get_level_annotation(level_id li, bool skip_excl)
{
annotation_map_type::const_iterator i = level_annotations.find(li);
- if (i == level_annotations.end())
+ if (skip_excl)
+ {
+ if (i == level_annotations.end())
+ return "";
+
+ return (i->second);
+ }
+
+ annotation_map_type::const_iterator j = level_exclusions.find(li);
+
+ if (i == level_annotations.end() && j == level_exclusions.end())
return "";
- return (i->second);
+ if (i == level_annotations.end())
+ return (j->second);
+ if (j == level_annotations.end())
+ return (i->second);
+
+ return (i->second + ", " + j->second);
}
bool level_annotation_has(std::string find, level_id li)
@@ -768,7 +800,7 @@ void annotate_level()
if (!get_level_annotation(li).empty())
{
mpr("Current level annotation is:", MSGCH_PROMPT);
- mpr(get_level_annotation(li).c_str() );
+ mpr(get_level_annotation(li, true).c_str() );
}
mpr("Set level annotation to what (using ! forces prompt)? ",
@@ -780,7 +812,7 @@ void annotate_level()
if (buf[0] == 0)
{
- if (get_level_annotation(li).length() > 0)
+ if (get_level_annotation(li, true).length() > 0)
{
if (!yesno("Really clear the annotation?"))
return;
diff --git a/crawl-ref/source/overmap.h b/crawl-ref/source/overmap.h
index 60c71beb73..90b79b56a4 100644
--- a/crawl-ref/source/overmap.h
+++ b/crawl-ref/source/overmap.h
@@ -25,7 +25,12 @@ void set_level_annotation(std::string str,
level_id li = level_id::current());
void clear_level_annotation(level_id li = level_id::current());
-std::string get_level_annotation(level_id li = level_id::current());
+void set_level_exclusion_annotation(std::string str,
+ level_id li = level_id::current());
+void clear_level_exclusion_annotation(level_id li = level_id::current());
+
+std::string get_level_annotation(level_id li = level_id::current(),
+ bool skip_excl = false);
bool level_annotation_has(std::string str,
level_id li = level_id::current());
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index 0101f92d1c..6484fa1f83 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -1359,7 +1359,7 @@ bool cast_fragmentation(int pow, const dist& spd)
{
int debris = 0;
bool explode = false;
- bool hole = true;
+ bool hole = true;
const char *what = NULL;
ray_def ray;
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index 520e02fc02..3b6c0ef4af 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -96,6 +96,7 @@ extern std::map<level_pos, std::string> portal_vaults_present;
extern std::map<level_pos, std::string> portal_vault_notes;
extern std::map<level_pos, char> portal_vault_colours;
extern std::map<level_id, std::string> level_annotations;
+extern std::map<level_id, std::string> level_exclusions;
// temp file pairs used for file level cleanup
@@ -166,7 +167,7 @@ static void tag_construct_lost_monsters(writer &th);
static void tag_construct_lost_items(writer &th);
static void tag_read_you(reader &th, char minorVersion);
static void tag_read_you_items(reader &th, char minorVersion);
-static void tag_read_you_dungeon(reader &th);
+static void tag_read_you_dungeon(reader &th, char minorVersion);
static void tag_read_lost_monsters(reader &th);
static void tag_read_lost_items(reader &th);
@@ -722,7 +723,7 @@ tag_type tag_read(FILE *fp, char minorVersion)
{
case TAG_YOU: tag_read_you(th, minorVersion); break;
case TAG_YOU_ITEMS: tag_read_you_items(th, minorVersion); break;
- case TAG_YOU_DUNGEON: tag_read_you_dungeon(th); break;
+ case TAG_YOU_DUNGEON: tag_read_you_dungeon(th, minorVersion); break;
case TAG_LEVEL: tag_read_level(th, minorVersion); break;
case TAG_LEVEL_ITEMS: tag_read_level_items(th, minorVersion); break;
case TAG_LEVEL_MONSTERS: tag_read_level_monsters(th, minorVersion); break;
@@ -1133,6 +1134,8 @@ static void tag_construct_you_dungeon(writer &th)
marshall_level_pos, marshallByte);
marshallMap(th, level_annotations,
marshall_level_id, marshallStringNoMax);
+ marshallMap(th, level_exclusions,
+ marshall_level_id, marshallStringNoMax);
marshallPlaceInfo(th, you.global_info);
std::vector<PlaceInfo> list = you.get_all_place_info();
@@ -1575,7 +1578,7 @@ static PlaceInfo unmarshallPlaceInfo(reader &th)
return place_info;
}
-static void tag_read_you_dungeon(reader &th)
+static void tag_read_you_dungeon(reader &th, char minorVersion)
{
// how many unique creatures?
int count_c = unmarshallShort(th);
@@ -1616,6 +1619,12 @@ static void tag_read_you_dungeon(reader &th)
unmarshallMap(th, level_annotations,
unmarshall_level_id, unmarshallStringNoMax);
+ if (minorVersion >= TAG_ANNOTATE_EXCL)
+ {
+ unmarshallMap(th, level_exclusions,
+ unmarshall_level_id, unmarshallStringNoMax);
+ }
+
PlaceInfo place_info = unmarshallPlaceInfo(th);
ASSERT(place_info.is_global());
you.set_place_info(place_info);
diff --git a/crawl-ref/source/tags.h b/crawl-ref/source/tags.h
index d6bcebc293..0535dbefad 100644
--- a/crawl-ref/source/tags.h
+++ b/crawl-ref/source/tags.h
@@ -69,7 +69,8 @@ enum tag_minor_version
TAG_MINOR_JIYVA = 17, // Added some player bits for Jiyva.
TAG_MINOR_ZOT_OPEN = 18, // Remember whether Zot was opened.
TAG_MINOR_JELLY = 19, // Remember whether the royal jelly is dead.
- TAG_MINOR_VERSION = 19 // Current version. (Keep equal to max.)
+ TAG_ANNOTATE_EXCL = 20, // Store exclusion information for annotations.
+ TAG_MINOR_VERSION = 20 // Current version. (Keep equal to max.)
};
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index 4dbbce3a68..e7f9d11f87 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -424,6 +424,7 @@ void clear_excludes()
toggle_exclude(curr_excludes[i].pos);
#endif
curr_excludes.clear();
+ clear_level_exclusion_annotation();
if (can_travel_interlevel())
{
@@ -456,19 +457,20 @@ void cycle_exclude_radius(const coord_def &p)
}
}
-void toggle_exclude(const coord_def &p)
+void toggle_exclude(const coord_def &p, bool autoexcl)
{
if (is_exclude_root(p))
set_exclude(p, 0);
else
- set_exclude(p, LOS_RADIUS);
+ set_exclude(p, LOS_RADIUS, autoexcl);
#ifdef USE_TILE
_tile_exclude_gmap_update(p);
#endif
+ set_level_exclusion_annotation(get_exclusion_desc());
}
-void set_exclude(const coord_def &p, int radius)
+void set_exclude(const coord_def &p, int radius, bool autoexcl)
{
// Sanity checks; excludes can be set in Pan and regular dungeon
// levels only.
@@ -499,7 +501,12 @@ void set_exclude(const coord_def &p, int radius)
}
else
{
- curr_excludes.push_back(travel_exclude(p, radius));
+ int montype = NON_MONSTER;
+ const monsters *m = monster_at(p);
+ if (m && mons_near(m) && you.can_see(m))
+ montype = m->type;
+
+ curr_excludes.push_back(travel_exclude(p, radius, autoexcl, montype));
}
if (can_travel_interlevel())
@@ -509,6 +516,64 @@ void set_exclude(const coord_def &p, int radius)
}
}
+// If a grid that was placed automatically no longer contains the original
+// monster (or it is invisible), remove the exclusion.
+void maybe_remove_autoexclusion(const coord_def &p)
+{
+ ASSERT(in_bounds(p) && see_grid(p) && is_exclude_root(p));
+
+ for (int i = 0, count = curr_excludes.size(); i < count; ++i)
+ {
+ if (curr_excludes[i].pos == p)
+ {
+ if (curr_excludes[i].autoexclude)
+ {
+ const monsters *m = monster_at(p);
+ if (!m || !you.can_see(m) || m->type != curr_excludes[i].mon)
+ {
+ set_exclude(p, 0);
+ set_level_exclusion_annotation(get_exclusion_desc());
+ }
+ }
+ break;
+ }
+ }
+}
+
+// Lists alls exclusions on the current level.
+std::string get_exclusion_desc()
+{
+ std::vector<std::string> monsters;
+ int count_other = 0;
+ for (int i = 0, count = curr_excludes.size(); i < count; ++i)
+ {
+ if (curr_excludes[i].mon != NON_MONSTER)
+ monsters.push_back(get_monster_data(curr_excludes[i].mon)->name);
+ else
+ count_other++;
+ }
+
+ if (count_other > 0)
+ {
+ snprintf(info, INFO_SIZE, "%d %sexclusion%s",
+ count_other, monsters.empty() ? "" : "more ",
+ count_other > 1 ? "s" : "");
+ monsters.push_back(info);
+ }
+ else if (monsters.empty())
+ return "";
+
+ std::string desc = "";
+ if (monsters.size() > 1 || count_other == 0)
+ {
+ snprintf(info, INFO_SIZE, "exclusion%s: ",
+ monsters.size() > 1 ? "s" : "");
+ desc += info;
+ }
+ return (desc + comma_separated_line(monsters.begin(), monsters.end(),
+ ", and ", ", "));
+}
+
static bool _is_monster_blocked(const coord_def& c)
{
const monsters *mons = monster_at(c);
@@ -3595,11 +3660,13 @@ void LevelInfo::save(writer& outf) const
{
marshallCoord(outf, excludes[i].pos);
marshallShort(outf, excludes[i].radius);
+ marshallBoolean(outf, excludes[i].autoexclude);
+ marshallShort(outf, excludes[i].mon);
}
}
}
-void LevelInfo::load(reader& inf)
+void LevelInfo::load(reader& inf, char minorVersion)
{
stairs.clear();
int stair_count = unmarshallShort(inf);
@@ -3635,7 +3702,14 @@ void LevelInfo::load(reader& inf)
coord_def c;
unmarshallCoord(inf, c);
const int radius = unmarshallShort(inf);
- excludes.push_back(travel_exclude(c, radius));
+ bool autoexcl = false;
+ int mon = NON_MONSTER;
+ if (minorVersion >= TAG_ANNOTATE_EXCL)
+ {
+ autoexcl = unmarshallBoolean(inf);
+ mon = unmarshallShort(inf);
+ }
+ excludes.push_back(travel_exclude(c, radius, autoexcl, mon));
}
}
}
@@ -3897,7 +3971,7 @@ void TravelCache::save(writer& outf) const
waypoints[wp].save(outf);
}
-void TravelCache::load(reader& inf)
+void TravelCache::load(reader& inf, char minorVersion)
{
levels.clear();
@@ -3916,7 +3990,7 @@ void TravelCache::load(reader& inf)
// Must set id before load, or travel_hell_entry will not be
// correctly set.
linfo.id = id;
- linfo.load(inf);
+ linfo.load(inf, minorVersion);
levels[id] = linfo;
}
diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h
index e584bc3057..60f1e23cd6 100644
--- a/crawl-ref/source/travel.h
+++ b/crawl-ref/source/travel.h
@@ -60,9 +60,12 @@ void init_travel_terrain_check(bool check_race_equip = true);
void stop_running(void);
void travel_init_new_level();
void cycle_exclude_radius(const coord_def &p);
-void toggle_exclude(const coord_def &p);
-void set_exclude(const coord_def &p, int radius2);
+void toggle_exclude(const coord_def &p, bool autoexcl = false);
+void set_exclude(const coord_def &p, int radius2, bool autoexcl = false);
+void maybe_remove_autoexclusion(const coord_def &p);
+std::string get_exclusion_desc();
void clear_excludes();
+
unsigned char is_waypoint(const coord_def &p);
bool is_exclude_root(const coord_def &p);
bool is_stair(dungeon_feature_type gridc);
@@ -351,15 +354,18 @@ void mark_all_excludes_non_updated();
struct travel_exclude
{
- coord_def pos; // exclusion centre
- int radius; // exclusion radisu
- env_show_grid show; // los from exclusion centre
- bool uptodate; // Is show up to date?
+ coord_def pos; // exclusion centre
+ int radius; // exclusion radius
+ bool autoexclude; // Was set automatically.
+ int mon; // Monster around which exclusion is centered.
+ env_show_grid show; // los from exclusion centre
+ bool uptodate; // Is show up to date?
void set_exclude_show();
- travel_exclude(const coord_def &p, int r = LOS_RADIUS)
- : pos(p), radius(r)
+ travel_exclude(const coord_def &p, int r = LOS_RADIUS,
+ bool autoexcl = false, int mons = NON_MONSTER)
+ : pos(p), radius(r), autoexclude(autoexcl), mon(mons)
{
set_exclude_show();
}
@@ -378,7 +384,7 @@ struct LevelInfo
}
void save(writer&) const;
- void load(reader&);
+ void load(reader&, char minorVersion);
std::vector<stair_info> &get_stairs()
{
@@ -490,7 +496,7 @@ public:
void update();
void save(writer&) const;
- void load(reader&);
+ void load(reader&, char minorVersion);
bool is_known_branch(unsigned char branch) const;
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 9ebb400a95..fa46b023f5 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -5336,6 +5336,9 @@ void viewwindow(bool draw_it, bool do_updates)
const coord_def sep = ep - coord_def(1,1);
#endif
+ if (in_bounds(gc) && see_grid(gc) && is_exclude_root(gc))
+ maybe_remove_autoexclusion(gc);
+
// Print tutorial messages for features in LOS.
if (Options.tutorial_left
&& in_bounds(gc)