From f9b61b5115bb93a1381cfc3032820489875624c5 Mon Sep 17 00:00:00 2001 From: David Lawrence Ramsey Date: Fri, 6 Nov 2009 15:10:29 -0600 Subject: Consolidate player/monster sleep checks. --- crawl-ref/source/actor.h | 3 ++- crawl-ref/source/beam.cc | 18 +++++++++--------- crawl-ref/source/mon-info.cc | 6 +----- crawl-ref/source/monster.cc | 29 +++++++++++++++++++++++++++-- crawl-ref/source/monster.h | 1 + crawl-ref/source/player.cc | 33 +++++++++++++++++++++++++-------- crawl-ref/source/player.h | 1 + crawl-ref/source/spells4.cc | 14 +++++--------- 8 files changed, 71 insertions(+), 34 deletions(-) diff --git a/crawl-ref/source/actor.h b/crawl-ref/source/actor.h index 6149207816..c18722f5c1 100644 --- a/crawl-ref/source/actor.h +++ b/crawl-ref/source/actor.h @@ -141,7 +141,8 @@ public: virtual void confuse(actor *attacker, int strength) = 0; virtual void expose_to_element(beam_type element, int strength = 0) = 0; virtual void drain_stat(int stat, int amount, actor* attacker) { } - virtual void put_to_sleep(int power = 0) { }; + virtual bool can_sleep(bool holi_only = false) const = 0; + virtual void put_to_sleep(int power = 0) = 0; virtual void check_awaken(int disturbance) = 0; virtual bool wearing_light_armour(bool = false) const { return (true); } diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index e3c8360fca..fab78fd095 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -4950,9 +4950,7 @@ bool _ench_flavour_affects_monster(beam_type flavour, const monsters* mon) break; case BEAM_SLEEP: - rc = !mon->has_ench(ENCH_SLEEP_WARY) // slept recently - && mon->holiness() == MH_NATURAL // no unnatural - && mon->res_cold() <= 0; // can't be hibernated + rc = mon->can_sleep(); break; case BEAM_PORKALATOR: @@ -5157,10 +5155,14 @@ mon_resist_type bolt::apply_enchantment_to_monster(monsters* mon) return (MON_AFFECTED); case BEAM_SLEEP: - if (simple_monster_message(mon, " looks drowsy...")) - obvious_effect = true; - mon->put_to_sleep(); - return (MON_AFFECTED); + if (mon->can_sleep()) + { + if (simple_monster_message(mon, " looks drowsy...")) + obvious_effect = true; + mon->put_to_sleep(); + return (MON_AFFECTED); + } + return (MON_UNAFFECTED); case BEAM_BACKLIGHT: if (backlight_monsters(mon->pos(), hit, 0)) @@ -5202,9 +5204,7 @@ mon_resist_type bolt::apply_enchantment_to_monster(monsters* mon) && mon->add_ench(ENCH_MIGHT)) { if (simple_monster_message(mon, " seems to grow stronger.")) - { obvious_effect = true; - } } return (MON_AFFECTED); diff --git a/crawl-ref/source/mon-info.cc b/crawl-ref/source/mon-info.cc index 141584a003..db0a44240c 100644 --- a/crawl-ref/source/mon-info.cc +++ b/crawl-ref/source/mon-info.cc @@ -166,12 +166,8 @@ static std::string _verbose_info(const monsters* m) return (" (fleeing)"); if (m->asleep()) { - if (m->holiness() == MH_UNDEAD - || m->holiness() == MH_NONLIVING - || m->holiness() == MH_PLANT) - { + if (!m->can_sleep(true)) return (" (dormant)"); - } else return (" (sleeping)"); } diff --git a/crawl-ref/source/monster.cc b/crawl-ref/source/monster.cc index 27cd5113e2..e3d6ac58bd 100644 --- a/crawl-ref/source/monster.cc +++ b/crawl-ref/source/monster.cc @@ -2696,7 +2696,7 @@ void monsters::expose_to_element(beam_type flavour, int strength) switch (flavour) { case BEAM_COLD: - if (mons_class_flag(this->type, M_COLD_BLOOD) && this->res_cold() <= 0 + if (mons_class_flag(type, M_COLD_BLOOD) && res_cold() <= 0 && coinflip()) { slow_down(this, strength); @@ -5392,9 +5392,34 @@ bool monsters::do_shaft() return (reveal); } +bool monsters::can_sleep(bool holi_only) const +{ + // Undead, nonliving, and plants don't sleep. + const mon_holy_type holi = holiness(); + if (holi == MH_UNDEAD || holi == MH_NONLIVING || holi == MH_PLANT) + return (false); + + if (!holi_only) + { + // The monster is berserk or already asleep. + if (berserk() || asleep()) + return (false); + + // The monster is cold-resistant and can't be hibernated. + if (res_cold() > 0) + return (false); + + // The monster has slept recently. + if (has_ench(ENCH_SLEEP_WARY)) + return (false); + } + + return (true); +} + void monsters::put_to_sleep(int) { - if (has_ench(ENCH_BERSERK)) + if (!can_sleep()) return; behaviour = BEH_SLEEP; diff --git a/crawl-ref/source/monster.h b/crawl-ref/source/monster.h index 8e50ad0b6f..f9ffee5adb 100644 --- a/crawl-ref/source/monster.h +++ b/crawl-ref/source/monster.h @@ -363,6 +363,7 @@ public: void blink(bool allow_partial_control = true); void teleport(bool right_now = false, bool abyss_shift = false); + bool can_sleep(bool holi_only = false) const; void put_to_sleep(int power = 0); void check_awaken(int disturbance); diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 01713f190d..dbbec6e49e 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -7046,7 +7046,7 @@ void player::reset_prev_move() bool player::asleep() const { - return (duration[DUR_SLEEP] > 0); + return (duration[DUR_SLEEP]); } bool player::cannot_act() const @@ -7059,24 +7059,41 @@ bool player::can_throw_large_rocks() const return (player_genus(GENPC_OGRE) || species == SP_TROLL); } +bool player::can_sleep(bool holi_only) const +{ + // Undead, nonliving, and plants don't sleep. + const mon_holy_type holi = holiness(); + if (holi == MH_UNDEAD || holi == MH_NONLIVING || holi == MH_PLANT) + return (false); + + if (!holi_only) + { + // The player is berserk or already asleep. + if (berserk() || asleep()) + return (false); + + // The player is cold-resistant and can't be hibernated. + if (res_cold() > 0) + return (false); + } + + return (true); +} + void player::put_to_sleep(int) { ASSERT(!crawl_state.arena); - if (berserk() || asleep()) // No cumulative sleeps. - return; - - // Not all species can be put to sleep. Check holiness. - const mon_holy_type holy = holiness(); - if (holy == MH_UNDEAD || holy == MH_NONLIVING) + if (!can_sleep()) { mpr("You feel weary for a moment."); return; } mpr("You fall asleep."); + stop_delay(); - this->flash_colour = DARKGREY; + flash_colour = DARKGREY; viewwindow(true, false); // Do this *after* redrawing the view, or viewwindow() will no-op. diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 1456fd5fa4..b2e9031e1d 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -461,6 +461,7 @@ public: bool petrified() const; bool asleep() const; + bool can_sleep(bool holi_only = false) const; void put_to_sleep(int power = 0); void awake(); void check_awaken(int disturbance); diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index a70bb84861..3a513c8bcc 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -393,28 +393,24 @@ void cast_detect_secret_doors(int pow) static int _sleep_monsters(coord_def where, int pow, int, actor *) { monsters *monster = monster_at(where); - if (monster == NULL) + if (!monster) return (0); - if (monster->holiness() != MH_NATURAL) + if (!monster->can_sleep(true)) return (0); + if (monster->check_res_magic(pow)) return (0); - // Works on friendlies too, so no check for that. - - //jmf: Now that sleep == hibernation: const int res = monster->res_cold(); if (res > 0 && one_chance_in(std::max(4 - res, 1))) return (0); + if (monster->has_ench(ENCH_SLEEP_WARY) && !one_chance_in(3)) return (0); monster->put_to_sleep(); - - if (mons_class_flag( monster->type, M_COLD_BLOOD ) && coinflip()) - monster->add_ench(ENCH_SLOW); - + monster->expose_to_element(BEAM_COLD, 2); return (1); } -- cgit v1.2.3-54-g00ecf