From 5fa864a78e4ebd44189a31827edeead3f0c12597 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Sat, 7 Apr 2007 20:27:45 +0000 Subject: Implemented Erik's invisibility proposal: - M_SENSE_INVIS for perceptive monsters; split existing monsters with see invisible into M_SEE_INVIS and M_SENSE_INVIS. - Monsters that can't see invisible get to-hit penalties vs invisible players and monsters in both melee and at range. - Monsters that sense where you are know where to shoot and attack, but still get to-hit penalties because they don't know exactly where you are. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1260 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 19 +++++++++++++- crawl-ref/source/enum.h | 29 ++++++++++----------- crawl-ref/source/externs.h | 7 +++++- crawl-ref/source/fight.cc | 20 +++++++++++---- crawl-ref/source/mon-data.h | 60 ++++++++++++++++++++++---------------------- crawl-ref/source/mon-util.cc | 26 ++++++++++++++----- crawl-ref/source/mon-util.h | 4 +-- crawl-ref/source/monstuff.cc | 2 +- crawl-ref/source/player.cc | 10 ++++++++ crawl-ref/source/view.cc | 4 +-- 10 files changed, 119 insertions(+), 62 deletions(-) (limited to 'crawl-ref/source') 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 -- cgit v1.2.3-54-g00ecf