summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/stuff.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-10-26 05:09:10 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-10-26 05:09:10 +0000
commit57f4a1b1382e1c4204cd0991eb3f574420184b83 (patch)
tree0bb1f6dd8b26850ccb94fb6223a25b4b616f5cb5 /crawl-ref/source/stuff.cc
parent05d5bcd6a07ce1ef26ca901167a06b67bf806f68 (diff)
downloadcrawl-ref-57f4a1b1382e1c4204cd0991eb3f574420184b83.tar.gz
crawl-ref-57f4a1b1382e1c4204cd0991eb3f574420184b83.zip
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
Diffstat (limited to 'crawl-ref/source/stuff.cc')
-rw-r--r--crawl-ref/source/stuff.cc134
1 files changed, 99 insertions, 35 deletions
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index 50483f903c..7562d1e0b0 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -102,53 +102,117 @@ void set_redraw_status( unsigned long flags )
you.redraw_status_flags |= flags;
}
-void tag_followers( void )
-{
- int count_x, count_y;
+static bool tag_follower_at(const coord_def &pos)
+{
+ if (!in_bounds(pos) || pos == you.pos())
+ return (false);
- for (count_x = you.x_pos - 1; count_x <= you.x_pos + 1; count_x++)
- {
- for (count_y = you.y_pos - 1; count_y <= you.y_pos + 1; count_y++)
- {
- if (count_x == you.x_pos && count_y == you.y_pos)
- continue;
+ if (mgrd(pos) == NON_MONSTER)
+ return (false);
- if (mgrd[count_x][count_y] == NON_MONSTER)
- continue;
+ monsters *fmenv = &menv[mgrd(pos)];
- struct monsters *fmenv = &menv[mgrd[count_x][count_y]];
+ if (fmenv->type == MONS_PLAYER_GHOST
+ || !fmenv->alive()
+ || mons_is_stationary(fmenv)
+ || fmenv->incapacitated())
+ {
+ return (false);
+ }
- if (fmenv->type == MONS_PANDEMONIUM_DEMON
- || fmenv->type == MONS_PLAYER_GHOST // cdl
- || !fmenv->alive()
- || mons_is_stationary(fmenv)
- || fmenv->incapacitated())
- {
- continue;
- }
+ if (!monster_habitable_grid(fmenv, DNGN_FLOOR))
+ return (false);
- if (!monster_habitable_grid(fmenv, DNGN_FLOOR))
- continue;
+ if (fmenv->speed_increment < 50)
+ return (false);
- if (fmenv->speed_increment < 50)
- continue;
+ // only friendly monsters, or those actively seeking the
+ // player, will follow up/down stairs.
+ if (!(mons_friendly(fmenv) ||
+ (fmenv->behaviour == BEH_SEEK && fmenv->foe == MHITYOU)))
+ {
+ return (false);
+ }
- // only friendly monsters, or those actively seeking the
- // player, will follow up/down stairs.
- if (!(mons_friendly(fmenv) ||
- (fmenv->behaviour == BEH_SEEK && fmenv->foe == MHITYOU)))
- {
- continue;
- }
+ // Monsters that are not directly adjacent are subject to more
+ // stringent checks.
+ if ((pos - you.pos()).abs() > 2)
+ {
+ if (!mons_friendly(fmenv))
+ return (false);
+
+ // Orcs will follow Beogh worshippers.
+ if (!(mons_species(fmenv->type) == MONS_ORC
+ && you.religion == GOD_BEOGH))
+ return (false);
+ }
- // monster is chasing player through stairs:
- fmenv->flags |= MF_TAKING_STAIRS;
+ // monster is chasing player through stairs:
+ fmenv->flags |= MF_TAKING_STAIRS;
#if DEBUG_DIAGNOSTICS
- mprf(MSGCH_DIAGNOSTICS, "%s is marked for following.",
- fmenv->name(DESC_CAP_THE, true).c_str() );
+ mprf(MSGCH_DIAGNOSTICS, "%s is marked for following.",
+ fmenv->name(DESC_CAP_THE, true).c_str() );
#endif
+ return (true);
+}
+
+static int follower_tag_radius2()
+{
+ // If only friendlies are adjacent, we set a max radius of 6, otherwise
+ // only adjacent friendlies may follow.
+ coord_def p;
+ for (p.x = you.x_pos - 1; p.x <= you.x_pos + 1; ++p.x)
+ for (p.y = you.y_pos - 1; p.y <= you.y_pos + 1; ++p.y)
+ {
+ if (p == you.pos())
+ continue;
+ if (const monsters *mon = monster_at(p))
+ {
+ if (!mons_friendly(mon))
+ return (2);
+ }
+ }
+ return (6 * 6);
+}
+
+void tag_followers()
+{
+ const int radius2 = follower_tag_radius2();
+ int n_followers = 18;
+
+ std::vector<coord_def> places[2];
+ int place_set = 0;
+
+ places[place_set].push_back(you.pos());
+ memset(travel_point_distance, 0, sizeof(travel_distance_grid_t));
+ while (!places[place_set].empty())
+ {
+ for (int i = 0, size = places[place_set].size(); i < size; ++i)
+ {
+ 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 (fp == p || (fp - you.pos()).abs() > radius2
+ || !in_bounds(fp) || travel_point_distance[fp.x][fp.y])
+ {
+ continue;
+ }
+ travel_point_distance[fp.x][fp.y] = 1;
+ if (tag_follower_at(fp))
+ {
+ // If we've run out of our follower allowance, bail.
+ if (--n_followers <= 0)
+ return;
+ places[!place_set].push_back(fp);
+ }
+ }
}
+ places[place_set].clear();
+ place_set = !place_set;
}
}