summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-18 04:37:20 +0000
committerdolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2008-06-18 04:37:20 +0000
commitda651d3cf70da11fb5178027a4f2d58e7755648f (patch)
tree6053aecf61a2fabc3a95e5356ba4c56927298f56 /crawl-ref
parent96c9c3ffb539e3e5c5e95db89544d984953aafd1 (diff)
downloadcrawl-ref-da651d3cf70da11fb5178027a4f2d58e7755648f.tar.gz
crawl-ref-da651d3cf70da11fb5178027a4f2d58e7755648f.zip
More progress on making pacified monsters leave the level. They'll now
find the nearest exit, and disappear once they reach it. There's a new travel target, MTRAV_EXIT. Notes: This is currently very simplistic. The monsters still don't use pathfinding, so if they're blocked, they'll just stand there again. With shaft traps, the monsters shouldn't try to go directly to the target, since they can't disappear at the same time they fall through to another level. With teleport traps, they should only go to them when all paths to exits are blocked, and they shouldn't disappear when they hit them. There may also be issues if a monster hits one and reappears nearby, since it won't be far enough outside the player's LOS to disappear. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5935 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/enum.h3
-rw-r--r--crawl-ref/source/mon-util.h2
-rw-r--r--crawl-ref/source/monplace.cc5
-rw-r--r--crawl-ref/source/monstuff.cc87
-rw-r--r--crawl-ref/source/traps.cc1
5 files changed, 89 insertions, 9 deletions
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 14581e94a0..bbdfad70a9 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -2789,7 +2789,8 @@ enum montravel_target_type
MTRAV_NONE = 0,
MTRAV_PLAYER, // Travelling to reach the player.
MTRAV_PATROL, // Travelling to reach the patrol point.
- MTRAV_UNREACHABLE // Not travelling because player is unreachable.
+ MTRAV_UNREACHABLE, // Not travelling because player is unreachable.
+ MTRAV_EXIT // Travelling to reach a level exit.
};
#ifdef WIZARD
diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h
index 7b00dee43e..ce71eccfa7 100644
--- a/crawl-ref/source/mon-util.h
+++ b/crawl-ref/source/mon-util.h
@@ -646,7 +646,7 @@ mon_attitude_type mons_attitude(const monsters *m);
bool mons_behaviour_perceptible(const monsters *mon);
bool mons_is_native_in_branch(const monsters *monster,
- const branch_type branch);
+ const branch_type branch = you.where_are_you);
bool mons_is_god_gift(const monsters *mon, god_type god = you.religion);
bool mons_is_chaotic(const monsters *mon);
bool mons_is_poisoner(const monsters *mon);
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 2a54fae689..01a7cf4f8c 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -2635,7 +2635,7 @@ bool monster_pathfind::traversable(coord_def p)
// at home in this branch.
if (grd(p) == DNGN_SECRET_DOOR && mons_friendly(mons)
&& (mons_intel(mons->type) < I_NORMAL
- || !mons_is_native_in_branch(mons, you.where_are_you)))
+ || !mons_is_native_in_branch(mons)))
{
return (false);
}
@@ -2696,8 +2696,7 @@ int monster_pathfind::travel_cost(coord_def npos)
bool knows_trap = (!mons_friendly(mons)
|| grd(npos) != DNGN_UNDISCOVERED_TRAP
|| mons_intel(mons->type) >= I_NORMAL
- && mons_is_native_in_branch(mons,
- you.where_are_you));
+ && mons_is_native_in_branch(mons));
trap_type tt = env.trap[trap].type;
if (tt == TRAP_ALARM || tt == TRAP_ZOT)
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 866b7dbcb4..f84d4c9037 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -2405,6 +2405,68 @@ static void _mark_neighbours_player_unreachable(monsters *mon)
}
}
+static void _mons_find_level_exits(const monsters *mon,
+ std::vector<coord_def> &e,
+ int range = -1)
+{
+ if (range == -1)
+ range = LOS_RADIUS;
+
+ // Sweep every square within range.
+ for (radius_iterator ri(mon->pos(), range, true, false); ri; ++ri)
+ {
+ // All types of stairs.
+ if (is_stair(grd(*ri)))
+ e.push_back(*ri);
+
+ // Teleportation and shaft traps: only known traps if the
+ // monster isn't native to the branch, or all traps if it is.
+ trap_type tt = trap_type_at_xy((*ri).x, (*ri).y);
+ if ((tt == TRAP_TELEPORT || tt == TRAP_SHAFT)
+ && (grd[(*ri).x][(*ri).y] != DNGN_UNDISCOVERED_TRAP
+ || mons_is_native_in_branch(mon)))
+ {
+ e.push_back(*ri);
+ }
+
+ // Any place the monster can submerge.
+ if (monster_can_submerge(mon, grd(*ri)))
+ e.push_back(*ri);
+ }
+}
+
+static bool _mons_find_nearest_level_exit(const monsters *mon,
+ coord_def &e)
+{
+ std::vector<coord_def> level_exits;
+
+ _mons_find_level_exits(mon, level_exits);
+
+ e.x = -1;
+ e.y = -1;
+
+ int old_dist = -1;
+
+ for (unsigned int i = 0; i < level_exits.size(); ++i)
+ {
+ int dist = distance(mon->x, mon->y, level_exits[i].x,
+ level_exits[i].y);
+
+ if (old_dist == -1 || old_dist >= dist)
+ {
+ if (old_dist == dist && coinflip())
+ continue;
+
+ old_dist = dist;
+
+ e.x = level_exits[i].x;
+ e.y = level_exits[i].y;
+ }
+ }
+
+ return (old_dist != -1);
+}
+
static void _make_mons_leave_level(monsters *mon)
{
if (mons_is_leaving(mon))
@@ -2834,8 +2896,7 @@ static void _handle_behaviour(monsters *mon)
#ifdef DEBUG_PATHFIND
mprf("Need to calculate a path... (dist = %d)", dist);
#endif
- const bool native =
- mons_is_native_in_branch(mon, you.where_are_you);
+ const bool native = mons_is_native_in_branch(mon);
int range = 0;
switch (mons_intel(mon->type))
@@ -3241,6 +3302,26 @@ static void _handle_behaviour(monsters *mon)
_make_mons_leave_level(mon);
return;
}
+
+ // If the monster isn't travelling toward an exit, make it
+ // start doing so.
+ if (mon->travel_target != MTRAV_EXIT)
+ {
+ coord_def e;
+ if (_mons_find_nearest_level_exit(mon, e))
+ {
+ mon->foe = MHITNOT;
+ mon->target_x = e.x;
+ mon->target_y = e.y;
+ mon->travel_target = MTRAV_EXIT;
+ }
+ }
+ // If it is, and it's on the exit, make it leave the level.
+ else if (mon->x == mon->target_x && mon->y == mon->target_y)
+ {
+ _make_mons_leave_level(mon);
+ return;
+ }
break;
case BEH_FLEE:
@@ -6546,7 +6627,7 @@ static bool _is_trap_safe(const monsters *monster, const int trap_x,
// * very intelligent monsters can be assumed to have a high T&D skill
// (or have memorised part of the dungeon layout ;) )
if (intel >= I_NORMAL && mechanical
- && (mons_is_native_in_branch(monster, you.where_are_you)
+ && (mons_is_native_in_branch(monster)
|| monster->attitude == ATT_FRIENDLY
&& player_knows_trap
|| intel >= I_HIGH && one_chance_in(3)))
diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc
index 1434640c19..d399ae7cd1 100644
--- a/crawl-ref/source/traps.cc
+++ b/crawl-ref/source/traps.cc
@@ -928,7 +928,6 @@ dungeon_feature_type trap_category(trap_type type)
// Returns index of the trap for a given (x,y) coordinate pair {dlb}
int trap_at_xy(int which_x, int which_y)
{
-
for (int which_trap = 0; which_trap < MAX_TRAPS; which_trap++)
{
if (env.trap[which_trap].x == which_x