summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/arena.cc3
-rw-r--r--crawl-ref/source/externs.h1
-rw-r--r--crawl-ref/source/fight.cc5
-rw-r--r--crawl-ref/source/initfile.cc4
-rw-r--r--crawl-ref/source/libutil.cc17
-rw-r--r--crawl-ref/source/libutil.h2
-rw-r--r--crawl-ref/source/monstuff.cc20
7 files changed, 39 insertions, 13 deletions
diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc
index 67b8e9413f..035aa6caa2 100644
--- a/crawl-ref/source/arena.cc
+++ b/crawl-ref/source/arena.cc
@@ -263,6 +263,9 @@ namespace arena
{
std::string spec = find_monster_spec();
+ Options.arena_force_ai =
+ strip_bool_tag(spec, "force_ai", Options.arena_force_ai);
+
allow_summons = !strip_tag(spec, "no_summons");
do_alert = strip_tag(spec, "alert");
no_immobile = strip_tag(spec, "no_immobile");
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index af8295ad48..737290714a 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -2028,6 +2028,7 @@ public:
bool arena_dump_msgs;
bool arena_dump_msgs_all;
bool arena_list_eq;
+ bool arena_force_ai;
// Messages that stop travel
std::vector<message_filter> travel_stop_message;
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index bff9578af4..fb71076fe5 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -370,10 +370,9 @@ void melee_attack::init_attack()
defender_shield = defender->shield();
water_attack = is_water_attack(attacker, defender);
- attacker_visible = attacker->visible() || crawl_state.arena;
+ attacker_visible = attacker->visible();
attacker_invisible = (!attacker_visible && see_grid(attacker->pos()));
- defender_visible = (defender &&
- (defender->visible() || crawl_state.arena));
+ defender_visible = (defender && defender->visible());
defender_invisible = (!defender_visible && defender
&& see_grid(defender->pos()));
needs_message = (attacker_visible || defender_visible);
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 0eb4305592..1e4c59cf9c 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -717,6 +717,10 @@ void game_options::reset_options()
arena_dump_msgs_all = false;
arena_list_eq = false;
+ // If true, monsters are forced to target each other in arena
+ // mode, even when outside LOS of each other.
+ arena_force_ai = true;
+
// Sort only pickup menus by default.
sort_menus.clear();
set_menu_sort("pickup: true");
diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc
index 9005ab4132..5dfd13d9b7 100644
--- a/crawl-ref/source/libutil.cc
+++ b/crawl-ref/source/libutil.cc
@@ -222,8 +222,9 @@ bool strip_tag(std::string &s, const std::string &tag, bool skip_padding)
return (true);
}
- if ((pos = s.find(tag + " ")) != std::string::npos
- || (pos = s.find(" " + tag)) != std::string::npos)
+ if ((pos = s.find(tag + " ")) == 0
+ || ((pos = s.find(" " + tag)) != std::string::npos
+ && pos + tag.length() + 1 == s.length()))
{
s.erase(pos, tag.length() + 1);
trim_string(s);
@@ -258,6 +259,18 @@ std::string strip_tag_prefix(std::string &s, const std::string &tagprefix)
return (argument);
}
+// Get a boolean flag from embedded tags in a string, using "<flag>"
+// for true and "no_<flag>" for false. If neither tag is found,
+// returns the default value.
+bool strip_bool_tag(std::string &s, const std::string &name, bool defval)
+{
+ if (strip_tag(s, name))
+ return (true);
+ if (strip_tag(s, "no_" + name))
+ return (false);
+ return (defval);
+}
+
int strip_number_tag(std::string &s, const std::string &tagprefix)
{
const std::string num = strip_tag_prefix(s, tagprefix);
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index 4be7ec41d6..f64e8ae07c 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -39,6 +39,8 @@ bool ends_with(const std::string &s, const std::string &suffix);
#define TAG_UNFOUND -20404
bool strip_tag(std::string &s, const std::string &tag, bool nopad = false);
int strip_number_tag(std::string &s, const std::string &tagprefix);
+bool strip_bool_tag(std::string &s, const std::string &name,
+ bool defval = false);
std::string strip_tag_prefix(std::string &s, const std::string &tagprefix);
std::string article_a(const std::string &name, bool lowercase = true);
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index a2d1069512..5aecdd1ca6 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -3643,11 +3643,18 @@ static void _handle_behaviour(monsters *mon)
if (crawl_state.arena)
{
- if (!mon->get_foe() || one_chance_in(3))
+ if (Options.arena_force_ai)
+ {
+ if (!mon->get_foe() || one_chance_in(3))
+ mon->foe = MHITNOT;
+ if (mon->foe == MHITNOT || mon->foe == MHITYOU)
+ _arena_set_foe(mon);
+ return;
+ }
+ // If we're not forcing monsters to attack, just make sure they're
+ // not targeting the player in arena mode.
+ else if (mon->foe == MHITYOU)
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()))
@@ -4431,7 +4438,7 @@ static void _handle_movement(monsters *monster)
{
delta = monster->target - monster->pos();
- if (crawl_state.arena)
+ if (crawl_state.arena && Options.arena_force_ai)
{
const bool ranged =
mons_has_ranged_attack(monster)
@@ -4662,9 +4669,6 @@ static void _handle_movement(monsters *monster)
}
}
}
-
- if (mmov.origin() && monster->behaviour == BEH_WANDER && crawl_state.arena)
- _check_wander_target(monster);
}
static void _make_mons_stop_fleeing(monsters *mon)