diff options
author | gammafunk <gammafunk@gmail.com> | 2014-03-04 18:53:58 -0600 |
---|---|---|
committer | gammafunk <gammafunk@gmail.com> | 2014-03-06 11:42:35 -0600 |
commit | 4a7354f52e5f00663930a651e6502de5a8a8fb26 (patch) | |
tree | 59ece0838a119114249c1b2e86d34115829f7e0d /crawl-ref/source/player-equip.cc | |
parent | 465263a558223b22c6597894e5a0dacdb376d401 (diff) | |
download | crawl-ref-4a7354f52e5f00663930a651e6502de5a8a8fb26.tar.gz crawl-ref-4a7354f52e5f00663930a651e6502de5a8a8fb26.zip |
Fix various issues with invisible monster indicators.
Currently if a monster enters LOS and goes invisible on the same turn,
it can disappear from the screen before the player has a proper
indication of where it was. This commit makes the following changes:
1. Fixes invisible monster indicators so that they can reliably be set
in the monster map knowledge update code at locations that of the
current monster being processed in this loop. The previous code tried
to set this indicator, but due to how the old loop cleared all flags
other than MAP_SEEN_FLAG and did tiles cell draws in the same pass as
map knowledge updates, these wouldn't work. This commit adds a
MAP_INVISIBLE_UPDATE flag to help retain MAP_INVISIBLE_MONSTER when
necessary, as well as a second loop in show_init that loops over a
vector of the updated cells found in the radius_iterator loop. This
second loop should be fast enough that it doesn't significantly affect
performance.
2. Add 'bool went_unseen_this_turn' and 'coord_def unseen_pos' to the
monster class (with the necessary save compat code) to allow monsters
that go invisible in LOS to always get an invisible indicator. The
code prefers to use indicators arising from the monster failing
stealth checks if those occur; they are based on the monster's true
position and hence are usually more accurate.
3. Somewhat simplify the stealth check code for invis indicators, and
only ever allow one invis indicator per monster. The stealth check
logic perhaps could be simplified further (there are multiple checks),
but I've preserved the existing checks for now. Also turned a
coinflip() in one of the secondary checks into a seeded/hashed
coinflip so it won't change over screen updates.
This commit lets players with antennae always see the location of an
invisible monster through an invis indicator, and sets the invis
indicator on the monster's last position whenever a monster becomes
unseen (e.g. going invis or already being invis but the player removes
sinv). If the monster fails a stealth check, that potentially more
accurate information is favored over the unseen position.
Diffstat (limited to 'crawl-ref/source/player-equip.cc')
-rw-r--r-- | crawl-ref/source/player-equip.cc | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/crawl-ref/source/player-equip.cc b/crawl-ref/source/player-equip.cc index bdd9d8e438..8520751cfd 100644 --- a/crawl-ref/source/player-equip.cc +++ b/crawl-ref/source/player-equip.cc @@ -1,7 +1,7 @@ #include "AppHdr.h" #include "player-equip.h" - +#include "act-iter.h" #include "art-enum.h" #include "areas.h" #include "artefact.h" @@ -14,6 +14,7 @@ #include "itemname.h" #include "itemprop.h" #include "items.h" +#include "libutil.h" #include "misc.h" #include "notes.h" #include "options.h" @@ -36,6 +37,7 @@ static void _equip_effect(equipment_type slot, int item_slot, bool unmeld, bool msg); static void _unequip_effect(equipment_type slot, int item_slot, bool meld, bool msg); +static void _mark_unseen_monsters(); static void _calc_hp_artefact() { @@ -422,6 +424,9 @@ static void _unequip_artefact_effect(item_def &item, contaminate_player(7000, true); } + if (proprt[ARTP_EYESIGHT]) + _mark_unseen_monsters(); + if (is_unrandom_artefact(item)) { const unrandart_entry *entry = get_unrand_entry(item.special); @@ -1077,7 +1082,10 @@ static void _unequip_armour_effect(item_def& item, bool meld) case SPARM_SEE_INVISIBLE: if (!you.can_see_invisible()) + { mpr("You feel less perceptive."); + _mark_unseen_monsters(); + } break; case SPARM_DARKNESS: @@ -1534,7 +1542,6 @@ static void _unequip_jewellery_effect(item_def &item, bool mesg, bool meld) case RING_PROTECTION_FROM_FIRE: case RING_PROTECTION_FROM_MAGIC: case RING_REGENERATION: - case RING_SEE_INVISIBLE: case RING_SLAYING: case RING_SUSTAIN_ABILITIES: case RING_SUSTENANCE: @@ -1543,6 +1550,10 @@ static void _unequip_jewellery_effect(item_def &item, bool mesg, bool meld) case RING_TELEPORT_CONTROL: break; + case RING_SEE_INVISIBLE: + _mark_unseen_monsters(); + break; + case RING_PROTECTION: you.redraw_armour_class = true; break; @@ -1633,3 +1644,17 @@ bool unwield_item(bool showMsgs) return true; } + +static void _mark_unseen_monsters() +{ + + for (monster_iterator mi; mi; mi++) + { + if (testbits((*mi)->flags, MF_WAS_IN_VIEW) && !you.can_see(*mi)) + { + (*mi)->went_unseen_this_turn = true; + (*mi)->unseen_pos = (*mi)->pos(); + } + + } +} |