diff options
author | Adam Borowski <kilobyte@angband.pl> | 2011-07-18 02:07:32 +0200 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2011-07-18 02:12:07 +0200 |
commit | 5aaa1d73326d1e7de71da91aa0afef330197c3fe (patch) | |
tree | 311344672471c4b64d1f45bd835ca19f5932bfa7 /crawl-ref/source/spl-tornado.cc | |
parent | 10e7cd3e721e34b3930e5b0274a9e0d28505f51a (diff) | |
download | crawl-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.cc | 51 |
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); + } +} |