diff options
author | Adam Borowski <kilobyte@angband.pl> | 2011-07-13 03:39:29 +0200 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2011-07-13 03:39:29 +0200 |
commit | 5deb02cc05f05478753c24f8f8404a4fc4153b02 (patch) | |
tree | 5d01b94fcf32a3d72972455afb4566eea92a59c2 /crawl-ref/source/spl-tornado.cc | |
parent | 2a2a16e69f8b8a9545af63e2972b4a51baccc174 (diff) | |
download | crawl-ref-5deb02cc05f05478753c24f8f8404a4fc4153b02.tar.gz crawl-ref-5deb02cc05f05478753c24f8f8404a4fc4153b02.zip |
Fix a tornado crash when a Royal Jelly spawn goes into a prepared space.
Diffstat (limited to 'crawl-ref/source/spl-tornado.cc')
-rw-r--r-- | crawl-ref/source/spl-tornado.cc | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/crawl-ref/source/spl-tornado.cc b/crawl-ref/source/spl-tornado.cc index 7692e69f1a..f91bee56c8 100644 --- a/crawl-ref/source/spl-tornado.cc +++ b/crawl-ref/source/spl-tornado.cc @@ -277,6 +277,16 @@ void tornado_damage(actor *caster, int dur) leda = true; // and with fish, too continue; } + if (victim == &you && monster_at(*dam_i)) + { + // A far-fetched case: you're using Fedhas' passthrough + // or standing on a submerged air elemental, there are + // no free spots, and a monster tornado rotates you. + // Plants don't get uprooted, so the logic would be + // really complex. Let's not go there. + leda = true; + continue; + } leda = liquefied(victim->pos()) && victim->ground_level() || victim->atype() == ACT_MONSTER @@ -344,13 +354,37 @@ void tornado_damage(actor *caster, int dur) if (dur <= 0) return; + // Gather actors who are to be moved. + for (unsigned int i = 0; i < move_act.size(); i++) + if (move_act[i]->alive()) // shouldn't ever change... + { + // Record the old position. + move_dest[move_act[i]->mid] = move_act[i]->pos(); + + // Temporarily move to (0,0) to allow permutations. + if (mgrd(move_act[i]->pos()) == move_act[i]->mindex()) + mgrd(move_act[i]->pos()) = NON_MONSTER; + move_act[i]->moveto(coord_def()); + } + + // Need to check available positions again, as the damage call could + // have spawned something new (like Royal Jelly spawns). + for (int i = move_avail.size() - 1; i >= 0; i--) + if (actor_at(move_avail[i])) + { + move_avail[i] = move_avail[move_avail.size() - 1]; + move_avail.pop_back(); + } + + // Calculate destinations. for (unsigned int i = 0; i < move_act.size(); i++) { + coord_def pos = move_dest[move_act[i]->mid]; int r; for (r = 0; r <= TORNADO_RADIUS; r++) - if ((move_act[i]->pos() - org).abs() < sqr(r + 1) + 1) + if ((pos - org).abs() < sqr(r + 1) + 1) break; - coord_def dest = _rotate(org, move_act[i]->pos(), move_avail, rdurs[r]); + coord_def dest = _rotate(org, pos, move_avail, rdurs[r]); for (unsigned int j = 0; j < move_avail.size(); j++) if (move_avail[j] == dest) { @@ -361,14 +395,8 @@ void tornado_damage(actor *caster, int dur) } move_dest[move_act[i]->mid] = dest; } - for (unsigned int i = 0; i < move_act.size(); i++) - if (move_act[i]->alive()) // shouldn't ever change... - { - // Temporarily move to (0,0) to allow permutations. - if (mgrd(move_act[i]->pos()) == move_act[i]->mindex()) - mgrd(move_act[i]->pos()) = NON_MONSTER; - move_act[i]->moveto(coord_def()); - } + + // Actually move actors into place. for (unsigned int i = 0; i < move_act.size(); i++) if (move_act[i]->alive()) { |