summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spl-tornado.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2011-07-20 04:06:54 +0200
committerAdam Borowski <kilobyte@angband.pl>2011-07-20 04:06:54 +0200
commitc8ebf026661c21e4ce251f886ad90f48b66c1382 (patch)
tree714306020bf6536ae97bdac2f6fd28e40bfc26a7 /crawl-ref/source/spl-tornado.cc
parentaf7a10123b3fbee491e9f2469f49f8c24540622e (diff)
downloadcrawl-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.cc69
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);
}