summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spl-tornado.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2011-07-18 02:07:32 +0200
committerAdam Borowski <kilobyte@angband.pl>2011-07-18 02:12:07 +0200
commit5aaa1d73326d1e7de71da91aa0afef330197c3fe (patch)
tree311344672471c4b64d1f45bd835ca19f5932bfa7 /crawl-ref/source/spl-tornado.cc
parent10e7cd3e721e34b3930e5b0274a9e0d28505f51a (diff)
downloadcrawl-ref-5aaa1d73326d1e7de71da91aa0afef330197c3fe.tar.gz
crawl-ref-5aaa1d73326d1e7de71da91aa0afef330197c3fe.zip
Fix teleportation moving Tornado with you.
It's hard to explain how the winds could follow you, especially as they don't do so between levels. Translocating within the radius doesn't cause an immediate abort, but there is a penalty steep enough that for practical purpose it does. Long distance teleports let you get out of cooldown, short ones don't.
Diffstat (limited to 'crawl-ref/source/spl-tornado.cc')
-rw-r--r--crawl-ref/source/spl-tornado.cc51
1 files changed, 43 insertions, 8 deletions
diff --git a/crawl-ref/source/spl-tornado.cc b/crawl-ref/source/spl-tornado.cc
index 562cba1e57..ea710da28b 100644
--- a/crawl-ref/source/spl-tornado.cc
+++ b/crawl-ref/source/spl-tornado.cc
@@ -411,7 +411,7 @@ void tornado_damage(actor *caster, int dur)
fire_final_effects();
}
-void cancel_tornado()
+void cancel_tornado(bool tloc)
{
if (!you.duration[DUR_TORNADO])
return;
@@ -419,14 +419,49 @@ void cancel_tornado()
dprf("Aborting tornado.");
if (you.duration[DUR_TORNADO] == you.duration[DUR_LEVITATION])
{
- you.duration[DUR_LEVITATION] = 0;
- you.duration[DUR_CONTROLLED_FLIGHT] = 0;
- you.attribute[ATTR_LEV_UNCANCELLABLE] = 0;
- burden_change();
- // NO checking for water, since this is called only during level
- // change, and being, say, banished from above water shouldn't
- // kill you.
+ if (tloc)
+ {
+ // it'd be better to abort levitation instantly, but let's first
+ // make damn sure all ways of translocating are prevented from
+ // landing you in water. Insta-kill due to an arrow of dispersal
+ // is not nice.
+ you.duration[DUR_LEVITATION] = std::min(20,
+ you.duration[DUR_LEVITATION]);
+ you.duration[DUR_CONTROLLED_FLIGHT] = std::min(20,
+ you.duration[DUR_CONTROLLED_FLIGHT]);
+ }
+ else
+ {
+ you.duration[DUR_LEVITATION] = 0;
+ you.duration[DUR_CONTROLLED_FLIGHT] = 0;
+ you.attribute[ATTR_LEV_UNCANCELLABLE] = 0;
+ burden_change();
+ // NO checking for water, since this is called only during level
+ // change, and being, say, banished from above water shouldn't
+ // kill you.
+ }
}
you.duration[DUR_TORNADO] = 0;
you.duration[DUR_TORNADO_COOLDOWN] = 0;
}
+
+void tornado_move(const coord_def &p)
+{
+ if (!you.duration[DUR_TORNADO])
+ return;
+
+ int dist2 = (you.pos() - p).abs();
+ if (dist2 > sqr(TORNADO_RADIUS) + 1)
+ cancel_tornado(true);
+ else if (dist2 > 2)
+ {
+ int dist = 0;
+ while (dist * dist + 1 < dist2)
+ dist++;
+ dist--;
+ if (dist > 0)
+ dprf("Tloc penalty: reducing tornado by %d turns", dist);
+ you.duration[DUR_TORNADO] = std::max(1,
+ you.duration[DUR_TORNADO] - dist * 10);
+ }
+}