From c52e267a7c4023d9ec765ebbf6ce0a44f811a636 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Mon, 20 Jul 2009 02:35:00 +0000 Subject: Bug 2820876: don't do a big cloud miscast in non-lethal mode if two player turns in the cloud could kill the player. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@10344 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/cloud.cc | 90 ++++++++++++++++++++++++++++++++++++++++++++- crawl-ref/source/cloud.h | 2 + crawl-ref/source/spl-mis.cc | 36 +++++++++--------- crawl-ref/source/spl-mis.h | 2 + 4 files changed, 112 insertions(+), 18 deletions(-) diff --git a/crawl-ref/source/cloud.cc b/crawl-ref/source/cloud.cc index a2a4f8609c..bbbaca890a 100644 --- a/crawl-ref/source/cloud.cc +++ b/crawl-ref/source/cloud.cc @@ -235,7 +235,11 @@ void check_place_cloud( cloud_type cl_type, const coord_def& p, int lifetime, int steam_cloud_damage(const cloud_struct &cloud) { - int decay = cloud.decay; + return steam_cloud_damage(cloud.decay); +} + +int steam_cloud_damage(int decay) +{ decay = std::min(decay, 60); decay = std::max(decay, 10); @@ -429,6 +433,90 @@ beam_type cloud2beam(cloud_type flavour) } } +// NOTE: Keep in sync with in_a_cloud() +int max_cloud_damage(cloud_type cl_type, int power) +{ + int speed = player_speed(); + int dam = 0; + int resist = 0; + + switch (cl_type) + { + case CLOUD_FIRE: + if (you.duration[DUR_FIRE_SHIELD]) + return (0); + resist = player_res_fire(); + + // Intentional fall-throuigh + case CLOUD_COLD: + if (cl_type == CLOUD_COLD) + resist = player_res_cold(); + + if (resist <= 0) + { + dam += 32 * speed / 10; + + if (resist < 0) + dam += 16 * speed / 10; + } + else + { + dam += 32 * speed / 10; + dam /= (1 + resist * resist); + } + break; + + case CLOUD_STINK: + if (player_res_poison()) + return (0); + + dam += 2 * speed / 10; + break; + + case CLOUD_POISON: + if (player_res_poison()) + return (0); + + dam += 9 * speed / 10; + break; + + case CLOUD_STEAM: + { + ASSERT(power >= 0); + + if (player_res_steam() > 0 || power == 0) + return (0); + + const int base_dam = steam_cloud_damage(power * 10); + dam += (base_dam - 1) * speed / 10; + + const int res_fire = player_res_fire(); + if (res_fire < 0) + dam += base_dam / 2 * speed / 10; + else if (res_fire) + dam /= 1 + (res_fire / 2); + + break; + } + + case CLOUD_MIASMA: + if (player_prot_life() >= 3) + return (0); + + dam += 11 * speed / 10; + + break; + default: + break; + } + + if (dam < 0) + dam = 0; + + return (dam); +} + +// NOTE: Keep in sync with max_cloud_damage() void in_a_cloud() { int cl = env.cgrid(you.pos()); diff --git a/crawl-ref/source/cloud.h b/crawl-ref/source/cloud.h index 679798e48b..240ef74e77 100644 --- a/crawl-ref/source/cloud.h +++ b/crawl-ref/source/cloud.h @@ -55,10 +55,12 @@ void manage_clouds(void); bool is_opaque_cloud(unsigned char cloud_idx); int steam_cloud_damage(const cloud_struct &cloud); +int steam_cloud_damage(int decay); cloud_type beam2cloud(beam_type flavour); beam_type cloud2beam(cloud_type flavour); +int max_cloud_damage(cloud_type cl_type, int power = -1); void in_a_cloud(void); std::string cloud_name(cloud_type type); diff --git a/crawl-ref/source/spl-mis.cc b/crawl-ref/source/spl-mis.cc index 643cebdfe0..ddbdde0782 100644 --- a/crawl-ref/source/spl-mis.cc +++ b/crawl-ref/source/spl-mis.cc @@ -541,6 +541,18 @@ bool MiscastEffect::_explosion() return (true); } +bool MiscastEffect::_big_cloud(cloud_type cl_type, int power, int size, + int spread_rate) +{ + if (avoid_lethal( 2 * max_cloud_damage(cl_type, power) )) + return (false); + + do_msg(true); + big_cloud(cl_type, kc, kt, target->pos(), power, size, spread_rate); + + return (true); +} + bool MiscastEffect::_lose_stat(unsigned char which_stat, unsigned char stat_loss) { @@ -829,9 +841,7 @@ void MiscastEffect::_conjuration(int severity) mon_msg_seen = "Smoke pours from @the_monster@'s @hands@!"; mon_msg_unseen = "Smoke appears from out of nowhere!"; - do_msg(); - big_cloud(CLOUD_GREY_SMOKE, kc, kt, target->pos(), 20, - 7 + random2(7)); + _big_cloud(CLOUD_GREY_SMOKE, 20, 7 + random2(7)); break; case 1: you_msg = "A wave of violent energy washes through your body!"; @@ -1999,9 +2009,7 @@ void MiscastEffect::_fire(int severity) mon_msg_seen = "Smoke pours from @the_monster@'s @hands@!"; mon_msg_unseen = "Smoke appears out of nowhere!"; - do_msg(); - big_cloud(random_smoke_type(), kc, kt, target->pos(), 20, - 7 + random2(7)); + _big_cloud(random_smoke_type(), 20, 7 + random2(7)); break; case 1: @@ -2231,8 +2239,7 @@ void MiscastEffect::_ice(int severity) mon_msg_seen = "Freezing gasses pour from @the_monster@'s " "@hands@!"; - do_msg(); - big_cloud(CLOUD_COLD, kc, kt, target->pos(), 20, 8 + random2(4)); + _big_cloud(CLOUD_COLD, 20, 8 + random2(4)); break; } break; @@ -2526,8 +2533,7 @@ void MiscastEffect::_air(int severity) "@hands@!"; mon_msg_unseen = "Noxious gasses appear from out of thin air!"; - do_msg(); - big_cloud(CLOUD_STINK, kc, kt, target->pos(), 20, 9 + random2(4)); + _big_cloud(CLOUD_STINK, 20, 9 + random2(4)); break; } break; @@ -2558,14 +2564,12 @@ void MiscastEffect::_air(int severity) "@hands@!"; mon_msg_unseen = "Venomous gasses pour forth from the thin air!"; - do_msg(); - big_cloud(CLOUD_POISON, kc, kt, target->pos(), 20, 8 + random2(5)); + _big_cloud(CLOUD_POISON, 20, 8 + random2(5)); break; } } } -// XXX MATT void MiscastEffect::_poison(int severity) { switch (severity) @@ -2666,8 +2670,7 @@ void MiscastEffect::_poison(int severity) "@hands@!"; mon_msg_unseen = "Noxious gasses pour forth from the thin air!"; - do_msg(); - big_cloud(CLOUD_STINK, kc, kt, target->pos(), 20, 8 + random2(5)); + _big_cloud(CLOUD_STINK, 20, 8 + random2(5)); break; case 2: @@ -2698,8 +2701,7 @@ void MiscastEffect::_poison(int severity) "@hands@!"; mon_msg_unseen = "Venomous gasses pour forth from the thin air!"; - do_msg(); - big_cloud(CLOUD_POISON, kc, kt, target->pos(), 20, 7 + random2(7)); + _big_cloud(CLOUD_POISON, 20, 7 + random2(7)); break; case 2: if (player_res_poison()) diff --git a/crawl-ref/source/spl-mis.h b/crawl-ref/source/spl-mis.h index 783562587f..5def1b7dd2 100644 --- a/crawl-ref/source/spl-mis.h +++ b/crawl-ref/source/spl-mis.h @@ -124,6 +124,8 @@ private: void do_msg(bool suppress_nothing_happens = false); bool _ouch(int dam, beam_type flavour = BEAM_NONE); bool _explosion(); + bool _big_cloud(cloud_type cl_type, int pow, int size, + int spread_rate = -1); bool _lose_stat(unsigned char which_stat, unsigned char stat_loss); void _potion_effect(int pot_eff, int pow); bool _create_monster(monster_type what, int abj_deg, bool alert = false); -- cgit v1.2.3-54-g00ecf