diff options
author | Nicholas Feinberg <pleasingfung@gmail.com> | 2014-06-22 16:57:57 -0700 |
---|---|---|
committer | Nicholas Feinberg <pleasingfung@gmail.com> | 2014-06-22 16:59:12 -0700 |
commit | c76c7bb6881a3b5127f762cadb91379564033b49 (patch) | |
tree | 4b2cbdd642875675757e896bbd014262675c319a /crawl-ref/source/godcompanions.cc | |
parent | 3dc87739768dc6fa52fe3f348614188964a58dc6 (diff) | |
download | crawl-ref-c76c7bb6881a3b5127f762cadb91379564033b49.tar.gz crawl-ref-c76c7bb6881a3b5127f762cadb91379564033b49.zip |
Fix a crash when recalling monsters onto shafts (8717)
Also removes a layer of indentation from recall_offlevel_ally();
apologies for the messy diff!
Diffstat (limited to 'crawl-ref/source/godcompanions.cc')
-rw-r--r-- | crawl-ref/source/godcompanions.cc | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/crawl-ref/source/godcompanions.cc b/crawl-ref/source/godcompanions.cc index 466d8ac02c..9b655ebed3 100644 --- a/crawl-ref/source/godcompanions.cc +++ b/crawl-ref/source/godcompanions.cc @@ -123,49 +123,62 @@ void populate_offlevel_recall_list(vector<pair<mid_t, int> > &recall_list) } } +/** + * Attempt to recall an ally from offlevel. + * + * @param mid The ID of the monster to be recalled. + * @return Whether the monster was successfully recalled onto the level. + * Note that the monster may not still be alive or onlevel, due to shafts, etc, + * but they were here at least briefly! + */ bool recall_offlevel_ally(mid_t mid) { if (!companion_is_elsewhere(mid, true)) return false; companion* comp = &companion_list[mid]; - if (comp->mons.place(true)) - { - monster* mons = monster_by_mid(mid); + if (!comp->mons.place(true)) + return false; - // The monster is now on this level - remove_monster_from_transit(comp->level, mid); - comp->level = level_id::current(); - simple_monster_message(mons, " is recalled."); + monster* mons = monster_by_mid(mid); - // Catch up time for off-level monsters - // (We move the player away so that we don't get expiry - // messages for things that supposed wore off ages ago) - const coord_def old_pos = you.pos(); - you.moveto(coord_def(0, 0)); + // The monster is now on this level + remove_monster_from_transit(comp->level, mid); + comp->level = level_id::current(); + simple_monster_message(mons, " is recalled."); - int turns = you.elapsed_time - comp->timestamp; - // Note: these are auts, not turns, thus healing is 10 times as fast as - // for other monsters, confusion goes away after a single turn, etc. + // Now that the monster is onlevel, we can safely apply traps to it. + // old location isn't very meaningful, so use current loc + mons->apply_location_effects(mons->pos()); + // check if it was killed/shafted by a trap... + if (!mons->alive()) + return true; // still successfully recalled! - mons->heal(div_rand_round(turns * mons->off_level_regen_rate(), 100)); + // Catch up time for off-level monsters + // (We move the player away so that we don't get expiry + // messages for things that supposed wore off ages ago) + const coord_def old_pos = you.pos(); + you.moveto(coord_def(0, 0)); - if (turns >= 10 && mons->alive()) - { - // Remove confusion manually (so that the monster - // doesn't blink after being recalled) - mons->del_ench(ENCH_CONFUSION, true); - mons->timeout_enchantments(turns / 10); - } - you.moveto(old_pos); - // Do this after returning the player to the proper position - // because it uses player position - recall_orders(mons); + int turns = you.elapsed_time - comp->timestamp; + // Note: these are auts, not turns, thus healing is 10 times as fast as + // for other monsters, confusion goes away after a single turn, etc. + + mons->heal(div_rand_round(turns * mons->off_level_regen_rate(), 100)); - return true; + if (turns >= 10 && mons->alive()) + { + // Remove confusion manually (so that the monster + // doesn't blink after being recalled) + mons->del_ench(ENCH_CONFUSION, true); + mons->timeout_enchantments(turns / 10); } + you.moveto(old_pos); + // Do this after returning the player to the proper position + // because it uses player position + recall_orders(mons); - return false; + return true; } bool companion_is_elsewhere(mid_t mid, bool must_exist) |