summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/mon-util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/mon-util.cc')
-rw-r--r--crawl-ref/source/mon-util.cc41
1 files changed, 38 insertions, 3 deletions
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 007b7d8c03..e9731e36d2 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -3133,9 +3133,7 @@ bool monsters::fumbles_attack(bool verbose)
{
if (verbose)
{
- const bool can_see =
- mons_near(this) && player_monster_visible(this);
- if (can_see)
+ if (you.can_see(this))
mprf("%s splashes around in the water.",
this->name(DESC_CAP_THE).c_str());
else if (!silenced(you.x_pos, you.y_pos) && !silenced(x, y))
@@ -4581,6 +4579,43 @@ bool monsters::invisible() const
return (has_ench(ENCH_INVIS) && !backlit());
}
+bool monsters::visible_to(actor *looker)
+{
+ if (this == looker)
+ return (!invisible() || can_see_invisible());
+
+ if (looker->atype() == ACT_PLAYER)
+ return player_monster_visible(this);
+ else
+ {
+ monsters* mon = dynamic_cast<monsters*>(looker);
+
+ return mons_monster_visible(mon, this);
+ }
+}
+
+bool monsters::can_see(actor *target)
+{
+ if (this == target)
+ return visible_to(target);
+
+ if (!target->visible_to(this))
+ return false;
+
+ if (target->atype() == ACT_PLAYER)
+ return mons_near(this);
+
+ monsters* mon = dynamic_cast<monsters*>(target);
+ int tx = mon->x;
+ int ty = mon->y;
+
+ if (distance(x, y, tx, ty) > LOS_RADIUS)
+ return false;
+
+ // Ignoring clouds for now.
+ return (num_feats_between(x, y, tx, ty, DNGN_UNSEEN, DNGN_MAXOPAQUE) == 0);
+}
+
void monsters::mutate()
{
if (holiness() != MH_NATURAL)