From 57f4a1b1382e1c4204cd0991eb3f574420184b83 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Fri, 26 Oct 2007 05:09:10 +0000 Subject: Beogh orcs will follow the PC downstairs even if they're not directly adjacent to the player, but are adjacent to other friendly orcs that are (in)directly adjacent to the player. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2583 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/files.cc | 74 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 17 deletions(-) (limited to 'crawl-ref/source/files.cc') diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 238bbe0918..96ca78e133 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -780,6 +780,30 @@ static void clear_clouds() env.cgrid.init(EMPTY_CLOUD); } +static bool grab_follower_at(const coord_def &pos) +{ + if (pos == you.pos()) + return (false); + + monsters *fmenv = monster_at(pos); + if (!fmenv || !fmenv->alive()) + return (false); + + // monster has to be already tagged in order to follow: + if (!testbits( fmenv->flags, MF_TAKING_STAIRS )) + return (false); + +#if DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "%s is following to %s.", + fmenv->name(DESC_CAP_THE, true).c_str(), + level_id::current().describe().c_str()); +#endif + fmenv->set_transit(level_id::current()); + fmenv->destroy_inventory(); + monster_cleanup(fmenv); + return (true); +} + static void grab_followers() { const bool can_follow = level_type_allows_followers(you.level_type); @@ -802,28 +826,44 @@ static void grab_followers() monster_teleport(fmenv, true); continue; } + } + } - // monster has to be already tagged in order to follow: - if (!testbits( fmenv->flags, MF_TAKING_STAIRS )) - continue; - - if (!can_follow) + if (can_follow) + { + memset(travel_point_distance, 0, sizeof(travel_distance_grid_t)); + std::vector places[2]; + int place_set = 0; + places[place_set].push_back(you.pos()); + while (!places[place_set].empty()) + { + for (int i = 0, size = places[place_set].size(); i < size; ++i) { - // Monster can't follow us, so clear the follower flag. - fmenv->flags &= ~MF_TAKING_STAIRS; - continue; + const coord_def &p = places[place_set][i]; + coord_def fp; + for (fp.x = p.x - 1; fp.x <= p.x + 1; ++fp.x) + for (fp.y = p.y - 1; fp.y <= p.y + 1; ++fp.y) + { + if (!in_bounds(fp) || travel_point_distance[fp.x][fp.y]) + continue; + travel_point_distance[fp.x][fp.y] = 1; + if (grab_follower_at(fp)) + places[!place_set].push_back(fp); + } } - -#if DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, "%s is following to %s.", - fmenv->name(DESC_CAP_THE, true).c_str(), - level_id::current().describe().c_str()); -#endif - fmenv->set_transit(level_id::current()); - fmenv->destroy_inventory(); - monster_cleanup(fmenv); + places[place_set].clear(); + place_set = !place_set; } } + + // Clear flags on the followers that didn't make it. + for (int i = 0; i < MAX_MONSTERS; ++i) + { + monsters *mons = &menv[i]; + if (!mons->alive()) + continue; + mons->flags &= ~MF_TAKING_STAIRS; + } } // Should be called after grab_followers(), so that items carried by -- cgit v1.2.3-54-g00ecf