From 86d488e3efa0b1d8ec12223527235e3ef3a5fec2 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Wed, 31 Dec 2008 08:41:27 +0000 Subject: 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 --- crawl-ref/source/monstuff.cc | 53 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'crawl-ref/source/monstuff.cc') 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 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) -- cgit v1.2.3-54-g00ecf