summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/beam.cc19
-rw-r--r--crawl-ref/source/enum.h29
-rw-r--r--crawl-ref/source/externs.h7
-rw-r--r--crawl-ref/source/fight.cc20
-rw-r--r--crawl-ref/source/mon-data.h60
-rw-r--r--crawl-ref/source/mon-util.cc26
-rw-r--r--crawl-ref/source/mon-util.h4
-rw-r--r--crawl-ref/source/monstuff.cc2
-rw-r--r--crawl-ref/source/player.cc10
-rw-r--r--crawl-ref/source/view.cc4
10 files changed, 119 insertions, 62 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 1cf809f8e5..3c5297f4e1 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2886,6 +2886,15 @@ static bool fuzz_invis_tracer(bolt &beem)
if (dist > 2)
return (false);
+ const int beam_src = beam_source(beem);
+ if (beam_src != MHITNOT && beam_src != MHITYOU)
+ {
+ // Monsters that can sense invisible
+ const monsters *mon = &menv[beam_src];
+ if (mons_sense_invis(mon))
+ return (!dist);
+ }
+
// Apply fuzz now.
int xfuzz = random_range(-2, 2),
yfuzz = random_range(-2, 2);
@@ -2960,6 +2969,10 @@ static int affect_player( struct bolt &beam )
// use beamHit, NOT beam.hit, for modification of tohit.. geez!
beamHit = beam.hit;
+ // Monsters shooting at an invisible player are very inaccurate.
+ if (you.invis && !beam.can_see_invis)
+ beamHit /= 2;
+
if (beam.name[0] != '0')
{
if (!beam.is_explosion && !beam.aimed_at_feet)
@@ -3523,10 +3536,14 @@ static int affect_monster(struct bolt &beam, struct monsters *mon)
// explosions always 'hit'
const bool engulfs = (beam.is_explosion || beam.is_big_cloud);
+ int beam_hit = beam.hit;
+ if (menv[tid].invisible() && !beam.can_see_invis)
+ beam_hit /= 2;
+
// FIXME We're randomising mon->evasion, which is further
// randomised inside test_beam_hit. This is so we stay close to the 4.0
// to-hit system (which had very little love for monsters).
- if (!engulfs && !test_beam_hit(beam.hit, random2(mon->ev)))
+ if (!engulfs && !test_beam_hit(beam_hit, random2(mon->ev)))
{
// if the PLAYER cannot see the monster, don't tell them anything!
if (player_monster_visible( &menv[tid] ) && mons_near(mon))
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 1f3338384a..c012005e80 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -1794,20 +1794,21 @@ enum mons_class_flags
M_LEVITATE = (1<< 5), // ... but not if this is set
M_INVIS = (1<< 6), // is created invis
M_SEE_INVIS = (1<< 7), // can see invis
- M_SPEAKS = (1<< 8), // uses talking code
- M_CONFUSED = (1<< 9), // monster is perma-confused,
- M_BATTY = (1<<10), // monster is batty
- M_SPLITS = (1<<11), // monster can split
- M_AMPHIBIOUS = (1<<12), // monster can swim in water,
- M_THICK_SKIN = (1<<13), // monster has more effective AC,
- M_HUMANOID = (1<<14), // for Glamour
- M_COLD_BLOOD = (1<<15), // susceptible to cold
- M_WARM_BLOOD = (1<<16), // no effect currently
- M_REGEN = (1<<17), // regenerates quickly
- M_BURROWS = (1<<18), // monster digs through rock
- M_EVIL = (1<<19), // monster vulnerable to holy spells
-
- M_UNIQUE = (1<<20), // monster is a unique
+ M_SENSE_INVIS = (1<< 8), // can sense invisible things
+ M_SPEAKS = (1<< 9), // uses talking code
+ M_CONFUSED = (1<<10), // monster is perma-confused,
+ M_BATTY = (1<<11), // monster is batty
+ M_SPLITS = (1<<12), // monster can split
+ M_AMPHIBIOUS = (1<<13), // monster can swim in water,
+ M_THICK_SKIN = (1<<14), // monster has more effective AC,
+ M_HUMANOID = (1<<15), // for Glamour
+ M_COLD_BLOOD = (1<<16), // susceptible to cold
+ M_WARM_BLOOD = (1<<17), // no effect currently
+ M_REGEN = (1<<18), // regenerates quickly
+ M_BURROWS = (1<<19), // monster digs through rock
+ M_EVIL = (1<<20), // monster vulnerable to holy spells
+
+ M_UNIQUE = (1<<21), // monster is a unique
M_ACID_SPLASH = (1<<22), // Passive acid splash when hit.
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 12a6bfb54c..d1fe6e9107 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -143,6 +143,8 @@ public:
virtual bool cannot_fight() const = 0;
virtual void attacking(actor *other) = 0;
virtual bool can_go_berserk() const = 0;
+ virtual bool can_see_invisible() const = 0;
+ virtual bool invisible() const = 0;
virtual void go_berserk(bool intentional) = 0;
virtual void hurt(const actor *attacker, int amount) = 0;
virtual void heal(int amount, bool max_too = false) = 0;
@@ -714,6 +716,8 @@ public:
bool can_swim() const;
bool is_levitating() const;
bool cannot_speak() const;
+ bool invisible() const;
+ bool can_see_invisible() const;
kill_category kill_alignment() const;
@@ -990,7 +994,8 @@ public:
int res_negative_energy() const;
bool levitates() const;
-
+ bool invisible() const;
+ bool can_see_invisible() const;
bool paralysed() const;
bool confused() const;
bool asleep() const;
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 3fbc2081d7..ce615b13ce 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -2014,8 +2014,9 @@ int melee_attack::player_to_hit(bool random_factor)
if (wearing_amulet(AMU_INACCURACY))
your_to_hit -= 5;
+ const bool see_invis = player_see_invis();
// if you can't see yourself, you're a little less acurate.
- if (you.invis && !player_see_invis())
+ if (you.invis && !see_invis)
your_to_hit -= 5;
// fighting contribution
@@ -2128,11 +2129,13 @@ int melee_attack::player_to_hit(bool random_factor)
}
// Check for backlight (Corona).
- if (defender
- && defender->atype() == ACT_MONSTER
- && def->has_ench(ENCH_BACKLIGHT))
+ if (defender && defender->atype() == ACT_MONSTER)
{
- your_to_hit += 2 + random2(8);
+ if (def->has_ench(ENCH_BACKLIGHT))
+ your_to_hit += 2 + random2(8);
+ // Invisible monsters are hard to hit.
+ else if (def->invisible() && !see_invis)
+ your_to_hit -= 6;
}
return (your_to_hit);
@@ -3068,6 +3071,13 @@ int melee_attack::mons_to_hit()
if (attacker->confused())
mhit -= 5;
+ // Invisible defender is hard to hit if you can't see invis. Note
+ // that this applies only to monsters vs monster and monster vs
+ // player. Does not apply to a player fighting an invisible
+ // monster.
+ if (defender->invisible() && !attacker->can_see_invisible())
+ mhit = mhit * 65 / 100;
+
return (mhit);
}
diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h
index c400468b40..90c1ac9695 100644
--- a/crawl-ref/source/mon-data.h
+++ b/crawl-ref/source/mon-data.h
@@ -135,7 +135,7 @@
{
MONS_GIANT_BAT, 'b', DARKGREY, "giant bat",
- M_FLIES | M_SEE_INVIS | M_WARM_BLOOD,
+ M_FLIES | M_SENSE_INVIS | M_WARM_BLOOD,
MR_NO_FLAGS,
150, 4, MONS_GIANT_BAT, MONS_GIANT_BAT, MH_NATURAL, -1,
{ {AT_HIT, AF_PLAIN, 1}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -207,7 +207,7 @@
{
MONS_HOUND, 'h', BROWN, "hound",
- M_SEE_INVIS | M_WARM_BLOOD,
+ M_SENSE_INVIS | M_WARM_BLOOD,
MR_NO_FLAGS,
300, 10, MONS_HOUND, MONS_HOUND, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -909,7 +909,7 @@
{
MONS_HUNGRY_GHOST, 'p', GREEN, "hungry ghost",
- M_SEE_INVIS | M_FLIES | M_EVIL,
+ M_SENSE_INVIS | M_FLIES | M_EVIL,
MR_RES_POISON | MR_RES_COLD,
0, 10, MONS_PHANTOM, MONS_HUNGRY_GHOST, MH_UNDEAD, -4,
{ {AT_HIT, AF_HUNGER, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -1017,7 +1017,7 @@
{
MONS_HELL_HOUND, 'h', DARKGREY, "hell hound",
- M_SEE_INVIS | M_EVIL | M_SPECIAL_ABILITY,
+ M_SENSE_INVIS | M_EVIL | M_SPECIAL_ABILITY,
MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD,
0, 10, MONS_HOUND, MONS_HELL_HOUND, MH_DEMONIC, -3,
{ {AT_BITE, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -1174,7 +1174,7 @@
{
MONS_ICE_DEVIL, '2', WHITE, "ice devil",
- M_SEE_INVIS | M_EVIL,
+ M_EVIL,
MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD,
0, 11, MONS_ICE_DEVIL, MONS_ICE_DEVIL, MH_DEMONIC, -6,
{ {AT_HIT, AF_COLD, 16}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -1629,7 +1629,7 @@
{
MONS_PULSATING_LUMP, 'J', RED, "pulsating lump",
- M_SEE_INVIS,
+ M_SENSE_INVIS,
MR_RES_POISON | MR_RES_ASPHYX,
0, 3, MONS_JELLY, MONS_PULSATING_LUMP, MH_NATURAL, -3,
{ {AT_HIT, AF_MUTATE, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -1799,7 +1799,7 @@
{
MONS_TITAN, 'C', MAGENTA, "titan",
- M_FIGHTER | M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
+ M_FIGHTER | M_SPELLCASTER | M_WARM_BLOOD | M_SENSE_INVIS | M_EVIL,
MR_RES_ELEC,
3500, 12, MONS_HILL_GIANT, MONS_TITAN, MH_NATURAL, -7,
{ {AT_HIT, AF_PLAIN, 55}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -1811,7 +1811,7 @@
{
MONS_GOLDEN_DRAGON, 'D', YELLOW, "golden dragon",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS,
+ M_SPELLCASTER | M_FLIES | M_SENSE_INVIS,
MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
3000, 17, MONS_DRAGON, MONS_GOLDEN_DRAGON, MH_NATURAL, -8,
{ {AT_BITE, AF_PLAIN, 40}, {AT_CLAW, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0} },
@@ -1865,7 +1865,7 @@
{
MONS_WAR_DOG, 'h', CYAN, "war dog",
- M_SEE_INVIS | M_WARM_BLOOD,
+ M_SENSE_INVIS | M_WARM_BLOOD,
MR_NO_FLAGS,
350, 10, MONS_HOUND, MONS_WAR_DOG, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2011,7 +2011,7 @@
{
MONS_FIRE_GIANT, 'C', RED, "fire giant",
- M_FIGHTER | M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
+ M_FIGHTER | M_SPELLCASTER | M_WARM_BLOOD | M_SENSE_INVIS | M_EVIL,
MR_RES_FIRE,
2400, 11, MONS_HILL_GIANT, MONS_FIRE_GIANT, MH_NATURAL, -4,
{ {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2023,7 +2023,7 @@
{
MONS_FROST_GIANT, 'C', LIGHTBLUE, "frost giant",
- M_FIGHTER | M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
+ M_FIGHTER | M_SPELLCASTER | M_WARM_BLOOD | M_SENSE_INVIS | M_EVIL,
MR_RES_COLD,
2600, 11, MONS_HILL_GIANT, MONS_FROST_GIANT, MH_NATURAL, -4,
{ {AT_HIT, AF_PLAIN, 35}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2082,7 +2082,7 @@
{
MONS_DEEP_TROLL, 'T', DARKGREY, "deep troll",
- M_WARM_BLOOD | M_SEE_INVIS | M_EVIL,
+ M_WARM_BLOOD | M_SENSE_INVIS | M_EVIL,
MR_NO_FLAGS,
1500, 12, MONS_TROLL, MONS_DEEP_TROLL, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 27}, {AT_CLAW, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0} },
@@ -2381,7 +2381,7 @@
{
MONS_YNOXINUL, '3', CYAN, "ynoxinul",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL,
+ M_SPELLCASTER | M_FLIES | M_SENSE_INVIS | M_EVIL,
MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD,
0, 12, MONS_YNOXINUL, MONS_YNOXINUL, MH_DEMONIC, -6,
{ {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2466,7 +2466,7 @@
{
MONS_SUN_DEMON, '2', YELLOW, "sun demon",
- M_SEE_INVIS | M_LEVITATE | M_EVIL,
+ M_SENSE_INVIS | M_LEVITATE | M_EVIL,
MR_RES_ELEC | MR_RES_POISON | MR_VUL_COLD | MR_RES_HELLFIRE,
0, 14, MONS_SUN_DEMON, MONS_SUN_DEMON, MH_DEMONIC, -6,
{ {AT_HIT, AF_FIRE, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2502,7 +2502,7 @@
{
MONS_LOROCYPROCA, '2', BLUE, "Lorocyproca",
- M_SEE_INVIS | M_INVIS | M_EVIL,
+ M_SENSE_INVIS | M_INVIS | M_EVIL,
MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC,
0, 12, MONS_LOROCYPROCA, MONS_LOROCYPROCA, MH_DEMONIC, -7,
{ {AT_HIT, AF_PLAIN, 25}, {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2526,7 +2526,7 @@
{
MONS_GIANT_AMOEBA, 'J', BLUE, "giant amoeba",
- M_NO_SKELETON | M_SEE_INVIS | M_AMPHIBIOUS,
+ M_NO_SKELETON | M_SENSE_INVIS | M_AMPHIBIOUS,
MR_RES_POISON,
1000, 10, MONS_GIANT_AMOEBA, MONS_GIANT_AMOEBA, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2875,7 +2875,7 @@
{
MONS_BROWN_OOZE, 'J', BROWN, "brown ooze",
- M_NO_SKELETON | M_SEE_INVIS | M_ACID_SPLASH,
+ M_NO_SKELETON | M_SENSE_INVIS | M_ACID_SPLASH,
MR_RES_POISON | MR_RES_ASPHYX | MR_RES_ACID,
0, 11, MONS_JELLY, MONS_BROWN_OOZE, MH_NATURAL, -7,
{ {AT_HIT, AF_ACID, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2887,7 +2887,7 @@
{
MONS_AZURE_JELLY, 'J', LIGHTBLUE, "azure jelly",
- M_NO_SKELETON | M_SEE_INVIS,
+ M_NO_SKELETON | M_SENSE_INVIS,
MR_RES_POISON | MR_RES_COLD | MR_VUL_FIRE | MR_RES_ELEC | MR_RES_ASPHYX
| MR_RES_ACID,
0, 11, MONS_JELLY, MONS_AZURE_JELLY, MH_NATURAL, -4,
@@ -2900,7 +2900,7 @@
{
MONS_DEATH_OOZE, 'J', DARKGREY, "death ooze",
- M_NO_SKELETON | M_SEE_INVIS | M_EVIL,
+ M_NO_SKELETON | M_SENSE_INVIS | M_EVIL,
MR_RES_POISON | MR_RES_COLD | MR_RES_ASPHYX | MR_RES_ACID,
0, 13, MONS_JELLY, MONS_DEATH_OOZE, MH_UNDEAD, -8,
{ {AT_HIT, AF_ROT, 32}, {AT_HIT, AF_PLAIN, 32}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2912,7 +2912,7 @@
{
MONS_ACID_BLOB, 'J', LIGHTGREEN, "acid blob",
- M_NO_SKELETON | M_SEE_INVIS | M_SPECIAL_ABILITY | M_ACID_SPLASH,
+ M_NO_SKELETON | M_SENSE_INVIS | M_SPECIAL_ABILITY | M_ACID_SPLASH,
MR_RES_POISON | MR_RES_ASPHYX | MR_RES_ACID,
0, 12, MONS_JELLY, MONS_ACID_BLOB, MH_NATURAL, -7,
{ {AT_HIT, AF_ACID, 42}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -2924,7 +2924,7 @@
{
MONS_ROYAL_JELLY, 'J', YELLOW, "royal jelly",
- M_NO_SKELETON | M_SEE_INVIS | M_ACID_SPLASH,
+ M_NO_SKELETON | M_SENSE_INVIS | M_ACID_SPLASH,
MR_RES_POISON | MR_RES_ASPHYX | MR_RES_ACID,
0, 20, MONS_JELLY, MONS_ROYAL_JELLY, MH_NATURAL, -7,
{ {AT_HIT, AF_ACID, 50}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -3393,7 +3393,7 @@
{
MONS_OOZE, 'J', LIGHTGREY, "ooze",
- M_NO_SKELETON | M_SEE_INVIS,
+ M_NO_SKELETON | M_SENSE_INVIS,
MR_RES_POISON | MR_RES_ASPHYX | MR_RES_ACID,
0, 5, MONS_JELLY, MONS_OOZE, MH_NATURAL, -6,
{ {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -3405,7 +3405,7 @@
{
MONS_VAULT_GUARD, '@', CYAN, "vault guard",
- M_FIGHTER | M_WARM_BLOOD | M_SEE_INVIS,
+ M_FIGHTER | M_WARM_BLOOD | M_SENSE_INVIS,
MR_NO_FLAGS,
0, 12, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -3516,7 +3516,7 @@
{
MONS_SKELETAL_DRAGON, 'D', LIGHTGREY, "skeletal dragon",
- M_SEE_INVIS | M_EVIL,
+ M_SENSE_INVIS | M_EVIL,
MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC,
0, 12, MONS_SKELETAL_WARRIOR, MONS_SKELETAL_DRAGON, MH_UNDEAD, -4,
{ {AT_BITE, AF_PLAIN, 30}, {AT_CLAW, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0} },
@@ -3540,7 +3540,7 @@
{
MONS_SPHINX, 'H', LIGHTGREY, "sphinx",
- M_FLIES | M_SEE_INVIS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
+ M_FLIES | M_SENSE_INVIS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD,
MR_NO_FLAGS,
0, 10, MONS_SPHINX, MONS_SPHINX, MH_NATURAL, -3,
{ {AT_HIT, AF_PLAIN, 25}, {AT_HIT, AF_PLAIN, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0} },
@@ -4000,7 +4000,7 @@
{
MONS_SERPENT_OF_HELL, 'D', RED, "Serpent of Hell",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL,
+ M_SPELLCASTER | M_FLIES | M_SENSE_INVIS | M_EVIL,
MR_RES_POISON | MR_RES_HELLFIRE,
0, 18, MONS_SERPENT_OF_HELL, MONS_SERPENT_OF_HELL, MH_DEMONIC, -13,
{ {AT_BITE, AF_PLAIN, 35}, {AT_CLAW, AF_PLAIN, 15}, {AT_CLAW, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0} },
@@ -4024,7 +4024,7 @@
{
MONS_QUICKSILVER_DRAGON, 'D', LIGHTCYAN, "quicksilver dragon",
- M_SPELLCASTER | M_FLIES | M_SEE_INVIS,
+ M_SPELLCASTER | M_FLIES | M_SENSE_INVIS,
MR_NO_FLAGS,
0, 14, MONS_DRAGON, MONS_QUICKSILVER_DRAGON, MH_NATURAL, -7,
{ {AT_BITE, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} },
@@ -4036,7 +4036,7 @@
{
MONS_IRON_DRAGON, 'D', CYAN, "iron dragon",
- M_SPELLCASTER | M_SEE_INVIS,
+ M_SPELLCASTER | M_SENSE_INVIS,
MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD,
0, 14, MONS_DRAGON, MONS_IRON_DRAGON, MH_NATURAL, -7,
{ {AT_BITE, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0} },
@@ -4211,7 +4211,7 @@
{
MONS_WOLF, 'h', LIGHTGREY, "wolf",
- M_WARM_BLOOD | M_SEE_INVIS, //jmf: until smell exists
+ M_WARM_BLOOD | M_SENSE_INVIS,
MR_NO_FLAGS,
450, 10, MONS_HOUND, MONS_WOLF, MH_NATURAL, -3,
{ {AT_BITE, AF_PLAIN, 8}, {AT_CLAW, AF_PLAIN, 2}, {AT_CLAW, AF_PLAIN, 2}, {AT_NONE, AF_PLAIN, 0} },
@@ -4223,7 +4223,7 @@
{
MONS_WARG, 'h', DARKGREY, "warg",
- M_SEE_INVIS | M_WARM_BLOOD,
+ M_SENSE_INVIS | M_WARM_BLOOD,
MR_RES_POISON,
600, 12, MONS_HOUND, MONS_WARG, MH_NATURAL, -6,
{ {AT_BITE, AF_PLAIN, 12}, {AT_CLAW, AF_PLAIN, 3}, {AT_CLAW, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0} },
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 086a63bd15..7c0da9cf5d 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -519,16 +519,21 @@ bool mons_is_unique( int mc )
return (mons_class_flag(mc, M_UNIQUE));
}
-char mons_see_invis( struct monsters *mon )
+bool mons_sense_invis(const monsters *mon)
+{
+ return (mons_class_flag(mon->type, M_SENSE_INVIS));
+}
+
+bool mons_see_invis(const monsters *mon)
{
if (mon->type == MONS_PLAYER_GHOST || mon->type == MONS_PANDEMONIUM_DEMON)
return (mon->ghost->values[ GVAL_SEE_INVIS ]);
else if (((seekmonster(mon->type))->bitfields & M_SEE_INVIS) != 0)
- return (1);
+ return (true);
else if (scan_mon_inv_randarts( mon, RAP_EYESIGHT ) > 0)
- return (1);
+ return (true);
- return (0);
+ return (false);
} // end mons_see_invis()
@@ -554,7 +559,7 @@ bool mons_player_visible( struct monsters *mon )
if (player_in_water())
return (true);
- if (mons_see_invis( mon ))
+ if (mons_see_invis( mon ) || mons_sense_invis(mon))
return (true);
return (false);
@@ -568,7 +573,6 @@ unsigned char mons_char(int mc)
return (unsigned char) smc->showchar;
} // end mons_char()
-
char mons_itemuse(int mc)
{
return (smc->gmon_use);
@@ -3859,6 +3863,16 @@ bool monsters::needs_berserk(bool check_spells) const
return (true);
}
+bool monsters::can_see_invisible() const
+{
+ return (mons_see_invis(this));
+}
+
+bool monsters::invisible() const
+{
+ return (has_ench(ENCH_INVIS));
+}
+
/////////////////////////////////////////////////////////////////////////
// mon_enchant
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index 1317bf983a..df1add3afb 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -156,8 +156,8 @@ char mons_itemuse(int mc);
/* ***********************************************************************
* called from: beam - fight - monstuff - view
* *********************************************************************** */
-char mons_see_invis( struct monsters *mon );
-
+bool mons_see_invis(const monsters *mon);
+bool mons_sense_invis(const monsters *mon);
bool mons_monster_visible( struct monsters *mon, struct monsters *targ );
bool mons_player_visible( struct monsters *mon );
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index cccb5c4036..b7248d26dc 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -1527,7 +1527,7 @@ static void handle_behaviour(struct monsters *mon)
// [dshaligram] Very smart monsters have a chance of cluing in to
// invisible players in various ways.
- else if ((intel == I_NORMAL && one_chance_in(10))
+ else if ((intel == I_NORMAL && one_chance_in(13))
|| (intel == I_HIGH && one_chance_in(6)))
proxPlayer = true;
}
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 724ccfa21c..fe79c5dff7 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -5250,3 +5250,13 @@ void player::sicken(int amount)
disease = (tmp > 210) ? 210 : tmp;
learned_something_new(TUT_YOU_SICK);
}
+
+bool player::can_see_invisible() const
+{
+ return (player_see_invis() > 0);
+}
+
+bool player::invisible() const
+{
+ return (invis);
+}
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 601d6d8cdf..f7a5adee06 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -721,9 +721,9 @@ bool check_awaken(int mons_aw)
return (true);
}
- // I assume that creatures who can see invisible are very perceptive
+ // I assume that creatures who can sense invisible are very perceptive
mons_perc = 10 + (mons_intel(monster->type) * 4) + monster->hit_dice
- + mons_see_invis(monster) * 5;
+ + mons_sense_invis(monster) * 5;
// critters that are wandering still have MHITYOU as their foe are
// still actively on guard for the player, even if they can't see