summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/externs.h2
-rw-r--r--crawl-ref/source/mon-util.cc37
2 files changed, 29 insertions, 10 deletions
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 28f0337792..3b9f3ff3ea 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1550,6 +1550,7 @@ public:
int action_energy(energy_use_type et) const;
bool do_shaft();
+ bool has_spell_of_type(unsigned) const;
private:
void init_with(const monsters &mons);
@@ -1572,7 +1573,6 @@ private:
bool check_set_valid_home(const coord_def &place,
coord_def &chosen,
int &nvalid) const;
- bool has_spell_of_type(unsigned) const;
};
struct cloud_struct
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index caa5a89bcf..86cae98ca6 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -4044,22 +4044,30 @@ bool monsters::has_spell_of_type(unsigned disciplines) const
return (false);
}
-bool monsters::can_use_missile(const item_def &item) const
+static bool _needs_ranged_attack(const monsters *mon)
{
- // Don't allow monsters to pick up missiles without the corresponding
- // launcher. The opposite is okay, and sufficient wandering will
- // hopefully take the monster to a stack of appropriate missiles.
-
// Prevent monsters that have conjurations from grabbing missiles.
- if (has_spell_of_type(SPTYP_CONJURATION))
+ if (mon->has_spell_of_type(SPTYP_CONJURATION))
return (false);
// Same for summonings, but make an exception for friendlies.
- if (!mons_friendly(this) && has_spell_of_type(SPTYP_SUMMONING))
+ if (!mons_friendly(mon) && mon->has_spell_of_type(SPTYP_SUMMONING))
return (false);
// Blademasters don't want to throw stuff.
- if (type == MONS_DEEP_ELF_BLADEMASTER)
+ if (mon->type == MONS_DEEP_ELF_BLADEMASTER)
+ return (false);
+
+ return (true);
+}
+
+bool monsters::can_use_missile(const item_def &item) const
+{
+ // Don't allow monsters to pick up missiles without the corresponding
+ // launcher. The opposite is okay, and sufficient wandering will
+ // hopefully take the monster to a stack of appropriate missiles.
+
+ if (!_needs_ranged_attack(this))
return (false);
if (item.base_type == OBJ_WEAPONS
@@ -4068,6 +4076,10 @@ bool monsters::can_use_missile(const item_def &item) const
return (is_throwable(this, item));
}
+ // Darts and stones are allowed even without launcher.
+ if (item.sub_type == MI_DART || item.sub_type == MI_STONE)
+ return (true);
+
item_def *launch;
for (int i = MSLOT_WEAPON; i <= MSLOT_ALT_WEAPON; ++i)
{
@@ -4548,6 +4560,11 @@ static bool _compatible_launcher_ammo_brands(item_def *launcher,
bool monsters::pickup_launcher(item_def &launch, int near)
{
+ // Don't allow monsters to pick up launchers that would also
+ // refuse to pick up the matching ammo.
+ if (!_needs_ranged_attack(this))
+ return (false);
+
// Don't allow monsters to switch to another type of launcher
// as that would require them to also drop their ammunition
// and then try to find ammunition for their new launcher.
@@ -4735,10 +4752,12 @@ static int _q_adj_damage(int damage, int qty)
bool monsters::pickup_throwable_weapon(item_def &item, int near)
{
const mon_inv_type slot = item_to_mslot(item);
- // If it's a meele weapon then pickup_melee_weapon() already rejected
+
+ // If it's a melee weapon then pickup_melee_weapon() already rejected
// it, even though it can also be thrown.
if (slot == MSLOT_WEAPON)
return (false);
+
ASSERT(slot == MSLOT_MISSILE);
// If occupied, don't pick up a throwable weapons if it would just