summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-07-20 02:39:52 +0000
committerzelgadis <zelgadis@c06c8d41-db1a-0410-9941-cceddc491573>2009-07-20 02:39:52 +0000
commite94983596e609fa3207c31f6e46916979c5b445c (patch)
treebeb5297603c039db6495910c21ead8219f180462 /crawl-ref
parentc8b4a65460278737d2c72e8afefb19da29fbca20 (diff)
downloadcrawl-ref-e94983596e609fa3207c31f6e46916979c5b445c.tar.gz
crawl-ref-e94983596e609fa3207c31f6e46916979c5b445c.zip
Backport r10344: fix for cloud part of bug 2820876.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup-0.5@10345 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/cloud.cc90
-rw-r--r--crawl-ref/source/cloud.h2
-rw-r--r--crawl-ref/source/spl-mis.cc36
-rw-r--r--crawl-ref/source/spl-mis.h2
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 543ed6cf5f..96ed2e6703 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)
{
@@ -828,9 +840,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!";
@@ -1998,9 +2008,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:
@@ -2230,8 +2238,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;
@@ -2525,8 +2532,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;
@@ -2557,14 +2563,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)
@@ -2665,8 +2669,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:
@@ -2697,8 +2700,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);