summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/monstuff.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-31 08:41:27 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-31 08:41:27 +0000
commit86d488e3efa0b1d8ec12223527235e3ef3a5fec2 (patch)
tree88b3d97a6f74ea6eb21405b3072e1e1a9c6830b0 /crawl-ref/source/monstuff.cc
parent496a1b4c58651aa28878db51bb1d5f3534d8a0a5 (diff)
downloadcrawl-ref-86d488e3efa0b1d8ec12223527235e3ef3a5fec2.tar.gz
crawl-ref-86d488e3efa0b1d8ec12223527235e3ef3a5fec2.zip
Add arena mode, activated on the command-line by 'crawl -arena "monster v monster"' (eg: crawl -arena "Sigmund v Jessica") to let monsters fight each other undisturbed by the player. Good to examine monster AI and monster behaviour when the player is AWOL.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8059 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/monstuff.cc')
-rw-r--r--crawl-ref/source/monstuff.cc53
1 files changed, 51 insertions, 2 deletions
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index ea3118f5ec..f630cbeb59 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -509,7 +509,8 @@ static void _give_adjusted_experience(monsters *monster, killer_type killer,
// Give a message for monsters dying out of sight.
if (need_xp_msg && exp_gain > 0
- && (!mons_near(monster) || !you.can_see(monster)))
+ && (!mons_near(monster) || !you.can_see(monster))
+ && !crawl_state.arena)
{
mpr("You feel a bit more experienced.");
}
@@ -3403,6 +3404,41 @@ static bool _handle_monster_patrolling(monsters *mon)
return (false);
}
+static void _arena_set_foe(monsters *mons)
+{
+ const int mind = monster_index(mons);
+
+ int nearest = -1;
+ int best_distance = -1;
+ for (int i = 0; i < MAX_MONSTERS; ++i)
+ {
+ if (mind == i)
+ continue;
+
+ const monsters *other(&menv[i]);
+ if (!other->alive() || mons_aligned(mind, i))
+ continue;
+
+ const int distance = grid_distance(mons->pos(), other->pos());
+ if (best_distance == -1 || distance < best_distance)
+ {
+ best_distance = distance;
+ nearest = i;
+ }
+ }
+
+ if (nearest != -1)
+ {
+ mons->foe = nearest;
+ mons->target = menv[nearest].pos();
+ }
+ else
+ {
+ mons->foe = MHITNOT;
+ mons->target = mons->pos();
+ }
+}
+
//---------------------------------------------------------------
//
// handle_behaviour
@@ -3441,6 +3477,7 @@ static void _handle_behaviour(monsters *mon)
bool patrolling = mon->is_patrolling();
static std::vector<level_exit> e;
static int e_index = -1;
+
// Check for confusion -- early out.
if (mon->has_ench(ENCH_CONFUSION))
{
@@ -3448,6 +3485,15 @@ static void _handle_behaviour(monsters *mon)
return;
}
+ if (crawl_state.arena)
+ {
+ if (!mon->get_foe() || one_chance_in(3))
+ mon->foe = MHITNOT;
+ if (mon->foe == MHITNOT || mon->foe == MHITYOU)
+ _arena_set_foe(mon);
+ return;
+ }
+
if (mons_wall_shielded(mon) && grid_is_solid(mon->pos()))
{
// Monster is safe, so it's behaviour can be simplified to fleeing.
@@ -4060,7 +4106,7 @@ bool simple_monster_message(const monsters *monster, const char *event,
description_level_type descrip)
{
- if (mons_near( monster )
+ if ((mons_near( monster ) || crawl_state.arena)
&& (channel == MSGCH_MONSTER_SPELL || channel == MSGCH_FRIEND_SPELL
|| player_monster_visible(monster)))
{
@@ -4250,7 +4296,9 @@ static void _handle_movement(monsters *monster)
delta = you.pos() - monster->pos();
}
else
+ {
delta = monster->target - monster->pos();
+ }
// Move the monster.
mmov.x = (delta.x > 0) ? 1 : ((delta.x < 0) ? -1 : 0);
@@ -6526,6 +6574,7 @@ static void _handle_monster_move(int i, monsters *monster)
}
_handle_behaviour(monster);
+ ASSERT(!crawl_state.arena || monster->foe != MHITYOU);
// Submerging monsters will hide from clouds.
if (cloud_num != EMPTY_CLOUD && _mons_avoids_cloud(monster, cl_type)