summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2009-02-17 20:41:45 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2009-02-17 20:41:45 +0000
commit3738559721d08c98bbf42b5debddee0cac63196b (patch)
tree78b9c39aa6a5c6dfaf59a1f50b2bd77dc38e2b4c /crawl-ref
parent999f4ba812512fbc28c9cbdc5d4f42a8eafdd1dd (diff)
downloadcrawl-ref-3738559721d08c98bbf42b5debddee0cac63196b.tar.gz
crawl-ref-3738559721d08c98bbf42b5debddee0cac63196b.zip
Fix [2604363]: stashes and autoexplore leaked information about mimics.
(Incidentally, if you walk into a mimic by accident, the stash won't go away until the next turn. Technically a bug, but a minor one.) git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9118 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/directn.cc3
-rw-r--r--crawl-ref/source/misc.cc2
-rw-r--r--crawl-ref/source/mon-util.cc5
-rw-r--r--crawl-ref/source/mon-util.h1
-rw-r--r--crawl-ref/source/stash.cc80
-rw-r--r--crawl-ref/source/tilepick.cc16
-rw-r--r--crawl-ref/source/travel.cc8
-rw-r--r--crawl-ref/source/view.cc13
8 files changed, 88 insertions, 40 deletions
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index d09e40c902..0aad26a41d 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -455,8 +455,7 @@ void full_describe_view()
for (radius_iterator ri(you.pos(), LOS_RADIUS); ri; ++ri)
{
const monsters *mon = monster_at(*ri);
- const bool unknown_mimic =
- (mon && mons_is_mimic(mon->type) && !mons_is_known_mimic(mon));
+ const bool unknown_mimic = (mon && mons_is_unknown_mimic(mon));
if (unknown_mimic) // It'll be on top.
{
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index c5650baf26..94b6758a96 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -2672,7 +2672,7 @@ std::vector<monsters*> get_nearby_monsters(bool want_move,
if (mon->alive()
&& (!require_visible || player_monster_visible(mon))
&& !mons_is_submerged(mon)
- && (!mons_is_mimic(mon->type) || mons_is_known_mimic(mon))
+ && !mons_is_unknown_mimic(mon)
&& (!dangerous_only || !mons_is_safe(mon, want_move,
consider_user_options)))
{
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index e9bbd67c48..98a7f1d2ca 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -2680,6 +2680,11 @@ bool mons_is_known_mimic(const monsters *m)
return mons_is_mimic(m->type) && testbits(m->flags, MF_KNOWN_MIMIC);
}
+bool mons_is_unknown_mimic(const monsters *m)
+{
+ return mons_is_mimic(m->type) && !mons_is_known_mimic(m);
+}
+
bool mons_looks_stabbable(const monsters *m)
{
const unchivalric_attack_type uat = is_unchivalric_attack(&you, m);
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index ab343e73df..a814e39549 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -770,6 +770,7 @@ bool mons_is_influenced_by_sanctuary(const monsters *m);
bool mons_is_fleeing_sanctuary(const monsters *m);
bool mons_was_seen(const monsters *m);
bool mons_is_known_mimic(const monsters *m);
+bool mons_is_unknown_mimic(const monsters *m);
bool mons_is_holy(const monsters *mon);
bool mons_is_evil(const monsters *mon);
bool mons_is_unholy(const monsters *mon);
diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc
index d9aa7e1a48..f4f7d2e1ff 100644
--- a/crawl-ref/source/stash.cc
+++ b/crawl-ref/source/stash.cc
@@ -28,6 +28,7 @@ REVISION("$Rev$");
#include "message.h"
#include "misc.h"
#include "mon-util.h"
+#include "monstuff.h"
#include "notes.h"
#include "overmap.h"
#include "place.h"
@@ -301,6 +302,30 @@ bool Stash::is_boring_feature(dungeon_feature_type feat)
}
}
+static bool _grid_has_mimic_item(const coord_def& pos)
+{
+ const monsters *mon = monster_at(pos);
+ return (mon && mons_is_unknown_mimic(mon));
+}
+
+static bool _grid_has_perceived_item(const coord_def& pos)
+{
+ return (igrd(pos) != NON_ITEM || _grid_has_mimic_item(pos));
+}
+
+static bool _grid_has_perceived_multiple_items(const coord_def& pos)
+{
+ int count = 0;
+
+ if (_grid_has_mimic_item(pos))
+ ++count;
+
+ for (stack_iterator si(pos); si && count < 2; ++si)
+ ++count;
+
+ return (count > 1);
+}
+
void Stash::update()
{
coord_def p(x,y);
@@ -313,7 +338,6 @@ void Stash::update()
if (grid_is_trap(feat))
trap = get_trap_type(p);
- int objl = igrd[x][y];
// If this is your position, you know what's on this square
if (p == you.pos())
{
@@ -321,12 +345,9 @@ void Stash::update()
items.clear();
// Now, grab all items on that square and fill our vector
- while (objl != NON_ITEM)
- {
- if (!is_filtered(mitm[objl]))
- add_item(mitm[objl]);
- objl = mitm[objl].link;
- }
+ for (stack_iterator si(p); si; ++si)
+ if (!is_filtered(*si))
+ add_item(*si);
verified = true;
}
@@ -334,19 +355,31 @@ void Stash::update()
// what the player sees on the square is the first item in this vector.
else
{
- if (objl == NON_ITEM)
+ if (!_grid_has_perceived_item(p))
{
items.clear();
verified = true;
- return ;
+ return;
}
// There's something on this square. Take a squint at it.
- const item_def &item = mitm[objl];
+ const item_def *pitem;
+ item_def mimic_item;
+ if (_grid_has_mimic_item(p))
+ {
+ get_mimic_item(monster_at(p), mimic_item);
+ pitem = &mimic_item;
+ }
+ else
+ {
+ pitem = &mitm[igrd(p)];
+ }
+
+ const item_def& item = *pitem;
tutorial_first_item(item);
- if (item.link == NON_ITEM)
+ if (!_grid_has_perceived_multiple_items(p))
items.clear();
// We knew of nothing on this square, so we'll assume this is the
@@ -356,15 +389,18 @@ void Stash::update()
{
if (!is_filtered(item))
add_item(item);
- verified = (item.link == NON_ITEM);
- return ;
+ // Note that we could be lying here, since we can have
+ // a verified falsehood (if there's a mimic.)
+ verified = !_grid_has_perceived_multiple_items(p);
+ return;
}
// There's more than one item in this pile. As long as the top item is
// not filtered, we can check to see if it matches what we think the
// top item is.
- if (is_filtered(item)) return;
+ if (is_filtered(item))
+ return;
const item_def &first = items[0];
// Compare these items
@@ -382,9 +418,7 @@ void Stash::update()
if (are_items_same(items[i], item))
{
// Found it. Swap it to the front of the vector.
- item_def temp = items[i];
- items[i] = items[0];
- items[0] = temp;
+ std::swap(items[i], items[0]);
// We don't set verified to true. If this stash was
// already unverified, it remains so.
@@ -1081,8 +1115,14 @@ level_id LevelStashes::where() const
Stash *LevelStashes::find_stash(int x, int y)
{
- return const_cast<Stash *>(
- const_cast<const LevelStashes *>(this)->find_stash(x, y) );
+ if (x == -1 || y == -1)
+ {
+ x = you.pos().x;
+ y = you.pos().y;
+ }
+ const int abspos = (GXM * y) + x;
+ stashes_t::iterator st = m_stashes.find(abspos);
+ return (st == m_stashes.end()? NULL : &st->second);
}
const Stash *LevelStashes::find_stash(int x, int y) const
@@ -1486,7 +1526,7 @@ void StashTracker::update_visible_stashes(
const dungeon_feature_type grid = grd[cx][cy];
if ((!lev || !lev->update_stash(cx, cy))
&& mode == ST_AGGRESSIVE
- && (igrd[cx][cy] != NON_ITEM
+ && (_grid_has_perceived_item(coord_def(cx,cy))
|| !Stash::is_boring_feature(grid)))
{
if (!lev)
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 7f23c07988..6b66e9c6f2 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -4356,7 +4356,7 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected)
if (!mons_is_known_mimic(mon))
{
// if necessary add item brand
- if (igrd[gx][gy] != NON_ITEM)
+ if (igrd(gc) != NON_ITEM)
{
if (foreground)
t |= TILE_FLAG_S_UNDER;
@@ -4371,14 +4371,14 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected)
if (foreground)
env.tile_bg[ep.x-1][ep.y-1] |= TILE_FLAG_CURSOR3;
else
- env.tile_bk_bg[gx][gy] |= TILE_FLAG_CURSOR3;
+ env.tile_bk_bg(gc) |= TILE_FLAG_CURSOR3;
}
}
}
else if (menv[idx].holiness() == MH_PLANT)
{
// if necessary add item brand
- if (igrd[gx][gy] != NON_ITEM)
+ if (igrd(gc) != NON_ITEM)
{
if (foreground)
t |= TILE_FLAG_S_UNDER;
@@ -4399,7 +4399,7 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected)
if (!player_monster_visible(mon)
|| mons_is_lurking(mon)
- || (mons_is_mimic(mon->type) && !mons_is_known_mimic(mon))
+ || mons_is_unknown_mimic(mon)
|| mons_class_flag(mon->type, M_NO_EXP_GAIN))
{
return;
@@ -4430,7 +4430,7 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected)
}
else
{
- env.tile_bk_fg[gc.x][gc.y] = t0;
+ env.tile_bk_fg(gc) = t0;
}
}
@@ -4491,9 +4491,9 @@ void tile_finish_dngn(unsigned int *tileb, int cx, int cy)
if (in_bounds)
{
- wall_flv = env.tile_flv[gc.x][gc.y].wall;
- floor_flv = env.tile_flv[gc.x][gc.y].floor;
- special_flv = env.tile_flv[gc.x][gc.y].special;
+ wall_flv = env.tile_flv(gc).wall;
+ floor_flv = env.tile_flv(gc).floor;
+ special_flv = env.tile_flv(gc).special;
}
_finalize_tile(&tileb[count+1], wall_flv, floor_flv, special_flv);
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index 6f981823da..cb00257661 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -516,7 +516,7 @@ static bool _is_monster_blocked(const coord_def& c)
&& player_monster_visible(mons)
&& mons_is_stationary(mons)
&& mons_was_seen(mons)
- && (!mons_is_mimic(mons->type) || mons_is_known_mimic(mons)));
+ && !mons_is_unknown_mimic(mons));
}
/*
@@ -843,7 +843,7 @@ inline static void _check_interesting_square(int x, int y,
{
if (const monsters *mons = monster_at(pos))
{
- if (mons_is_mimic(mons->type) && !mons_is_known_mimic(mons))
+ if (mons_is_unknown_mimic(mons))
{
item_def item;
get_mimic_item(mons, item);
@@ -1411,9 +1411,7 @@ static bool _is_greed_inducing_square(const LevelStashes *ls,
if (const monsters *mons = monster_at(c))
{
- if (mons_is_mimic(mons->type)
- && mons_was_seen(mons)
- && !mons_is_known_mimic(mons))
+ if (mons_is_unknown_mimic(mons) && mons_was_seen(mons))
{
item_def mimic_item;
get_mimic_item(mons, mimic_item);
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 5bda2008f4..fa5994034d 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -964,7 +964,7 @@ void beogh_follower_convert(monsters *monster, bool orc_hit)
static void _handle_seen_interrupt(monsters* monster)
{
- if (mons_is_mimic(monster->type) && !mons_is_known_mimic(monster))
+ if (mons_is_unknown_mimic(monster))
return;
activity_interrupt_data aid(monster);
@@ -1309,9 +1309,14 @@ void update_monsters_in_view()
if (monster->attitude == ATT_HOSTILE)
num_hostile++;
- if (player_monster_visible(monster)
- && (!mons_is_mimic(monster->type)
- || mons_is_known_mimic(monster)))
+ if (mons_is_unknown_mimic(monster))
+ {
+ // For unknown mimics, don't mark as seen,
+ // but do mark it as in view for later messaging.
+ // FIXME: is this correct?
+ monster->flags |= MF_WAS_IN_VIEW;
+ }
+ else if (player_monster_visible(monster))
{
if (!(monster->flags & MF_WAS_IN_VIEW) && you.turn_is_over)
_handle_seen_interrupt(monster);