From 3738559721d08c98bbf42b5debddee0cac63196b Mon Sep 17 00:00:00 2001 From: haranp Date: Tue, 17 Feb 2009 20:41:45 +0000 Subject: 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 --- crawl-ref/source/directn.cc | 3 +- crawl-ref/source/misc.cc | 2 +- crawl-ref/source/mon-util.cc | 5 +++ crawl-ref/source/mon-util.h | 1 + crawl-ref/source/stash.cc | 80 +++++++++++++++++++++++++++++++++----------- crawl-ref/source/tilepick.cc | 16 ++++----- crawl-ref/source/travel.cc | 8 ++--- crawl-ref/source/view.cc | 13 ++++--- 8 files changed, 88 insertions(+), 40 deletions(-) (limited to 'crawl-ref/source') 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 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( - const_cast(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); -- cgit v1.2.3-54-g00ecf