diff options
author | Adam Borowski <kilobyte@angband.pl> | 2011-07-20 04:06:54 +0200 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2011-07-20 04:06:54 +0200 |
commit | c8ebf026661c21e4ce251f886ad90f48b66c1382 (patch) | |
tree | 714306020bf6536ae97bdac2f6fd28e40bfc26a7 /crawl-ref/source/spl-tornado.cc | |
parent | af7a10123b3fbee491e9f2469f49f8c24540622e (diff) | |
download | crawl-ref-c8ebf026661c21e4ce251f886ad90f48b66c1382.tar.gz crawl-ref-c8ebf026661c21e4ce251f886ad90f48b66c1382.zip |
Tornado: alter the rules for "short translocation".
You cannot move a tornado to a place where it did not reach yet.
Outside of that range, check if a new tornado can possibly intersect with
the area the old one reached, and impose a cooldown if yes.
Also, clear the cooldown if you went farther away.
Diffstat (limited to 'crawl-ref/source/spl-tornado.cc')
-rw-r--r-- | crawl-ref/source/spl-tornado.cc | 69 |
1 files changed, 53 insertions, 16 deletions
diff --git a/crawl-ref/source/spl-tornado.cc b/crawl-ref/source/spl-tornado.cc index 825b8081d4..e3bc6e3a7b 100644 --- a/crawl-ref/source/spl-tornado.cc +++ b/crawl-ref/source/spl-tornado.cc @@ -194,6 +194,23 @@ static int _rdam(int rage) return rage * 10 - 50; } +static int _tornado_age(const actor *caster) +{ + if (caster->props.exists("tornado_since")) + return you.elapsed_time - caster->props["tornado_since"].get_int(); + return 100; // for permanent tornadoes +} + +// time needed to reach the given radius +static int _age_needed(int r) +{ + if (r <= 0) + return 0; + if (r > TORNADO_RADIUS) + return INT_MAX; + return sqr(r) * 5 / 4; +} + void tornado_damage(actor *caster, int dur) { if (!dur) @@ -210,9 +227,7 @@ void tornado_damage(actor *caster, int dur) noisy(25, org, caster->mindex()); WindSystem winds(org); - int age = 100; // for permanent tornadoes - if (caster->props.exists("tornado_since")) - age = you.elapsed_time - caster->props["tornado_since"].get_int(); + int age = _tornado_age(caster); ASSERT(age >= 0); std::vector<actor*> move_act; // victims to move @@ -234,7 +249,7 @@ void tornado_damage(actor *caster, int dur) ++count_i; } // effective age at radius r - int rage = age - sqr(r) * 5 / 4; + int rage = age - _age_needed(r); /* Not just "portion of time affected": ** ** @@ -447,21 +462,43 @@ void cancel_tornado(bool tloc) void tornado_move(const coord_def &p) { - if (!you.duration[DUR_TORNADO]) + if (!you.duration[DUR_TORNADO] && !you.duration[DUR_TORNADO_COOLDOWN]) return; + int age = _tornado_age(&you); int dist2 = (you.pos() - p).abs(); - if (dist2 > sqr(TORNADO_RADIUS) + 1) - cancel_tornado(true); - else if (dist2 > 2) + if (dist2 <= 2) + return; + + int dist = 0; + while (dist * dist + 1 < dist2) + dist++; + + if (!you.duration[DUR_TORNADO]) { - 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); + if (age < _age_needed(dist - TORNADO_RADIUS)) + you.duration[DUR_TORNADO_COOLDOWN] = 0; + return; } + + if (age > _age_needed(dist)) + { + // check for actual wind too, not just the radius + WindSystem winds(you.pos()); + if (winds.has_wind(p)) + { + // blinking/cTele inside an already windy area + dprf("Tloc penalty: reducing tornado by %d turns", dist - 1); + you.duration[DUR_TORNADO] = std::max(1, + you.duration[DUR_TORNADO] - (dist - 1) * 10); + return; + } + } + + cancel_tornado(true); + + // there's an intersection between the area of the old tornado, and what + // a new one could possibly grow into + if (age > _age_needed(dist - TORNADO_RADIUS)) + you.duration[DUR_TORNADO_COOLDOWN] = random_range(25, 35); } |