summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/describe.cc2
-rw-r--r--crawl-ref/source/directn.cc53
-rw-r--r--crawl-ref/source/mon-util.cc69
-rw-r--r--crawl-ref/source/religion.cc30
4 files changed, 111 insertions, 43 deletions
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 754f1b6d1a..45832e5d35 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2094,7 +2094,7 @@ void describe_monsters(monsters& mons)
if (mons_is_mimic(mons.type) && mons.type != MONS_GOLD_MIMIC)
description << getLongDescription("mimic");
else
- description << getLongDescription(mons.name(DESC_PLAIN));
+ description << getLongDescription(mons.name(DESC_PLAIN, false));
std::string symbol = "";
symbol += get_monster_data(mons.type)->showchar;
diff --git a/crawl-ref/source/directn.cc b/crawl-ref/source/directn.cc
index 9c70996b98..e1ef6b8547 100644
--- a/crawl-ref/source/directn.cc
+++ b/crawl-ref/source/directn.cc
@@ -2165,10 +2165,10 @@ static void describe_monster(const monsters *mon)
std::string get_monster_desc(const monsters *mon, bool full_desc,
description_level_type mondtype)
{
- std::string desc = mon->name(mondtype);
+ std::string desc = "";
+ if (mondtype != DESC_NONE)
+ desc = mon->name(mondtype);
- const int mon_arm = mon->inv[MSLOT_ARMOUR];
- const int mon_shd = mon->inv[MSLOT_SHIELD];
std::string weap = "";
if (mon->type != MONS_DANCING_WEAPON)
@@ -2183,22 +2183,65 @@ std::string get_monster_desc(const monsters *mon, bool full_desc,
if (full_desc)
{
+ const int mon_arm = mon->inv[MSLOT_ARMOUR];
+ const int mon_shd = mon->inv[MSLOT_SHIELD];
+ const int mon_qvr = mon->inv[MSLOT_MISSILE];
+ const int mon_alt = mon->inv[MSLOT_ALT_WEAPON];
+
+ const bool need_quiver = (mon_qvr != NON_ITEM && mons_friendly(mon));
+ const bool need_alt_wpn = (mon_alt != NON_ITEM && mons_friendly(mon)
+ && !mons_wields_two_weapons(mon));
+ bool found_sth = !weap.empty();
+
+
if (mon_arm != NON_ITEM)
{
desc += ", ";
- if (!weap.empty() && mon_shd == NON_ITEM)
+ if (found_sth && mon_shd == NON_ITEM && !need_quiver
+ && !need_alt_wpn)
+ {
desc += "and ";
+ }
desc += "wearing ";
desc += mitm[mon_arm].name(DESC_NOCAP_A);
+ if (!found_sth)
+ found_sth = true;
}
if (mon_shd != NON_ITEM)
{
desc += ", ";
- if (!weap.empty() || mon_arm != NON_ITEM)
+ if (found_sth && !need_quiver && !need_alt_wpn)
desc += "and ";
desc += "wearing ";
desc += mitm[mon_shd].name(DESC_NOCAP_A);
+ if (!found_sth)
+ found_sth = true;
+ }
+
+ // For friendly monsters, also list quivered missiles
+ // and alternate weapon.
+ if (mons_friendly(mon))
+ {
+ if (mon_qvr != NON_ITEM)
+ {
+ desc += ", ";
+ if (found_sth && !need_alt_wpn)
+ desc += "and ";
+ desc += "quivering ";
+ desc += mitm[mon_qvr].name(DESC_NOCAP_A);
+ if (!found_sth)
+ found_sth = true;
+ }
+
+ if (need_alt_wpn)
+ {
+ desc += ", ";
+ if (found_sth)
+ desc += "and ";
+ desc += "carrying ";
+ desc += mitm[mon_alt].name(DESC_NOCAP_A);
+ }
}
}
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 076a9390ed..d9b3235069 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -180,11 +180,11 @@ void init_mon_name_cache()
// except looking up "rakshasa" and getting _FAKE breaks ?/M rakshasa.
if (Mon_Name_Cache.find(name) != Mon_Name_Cache.end())
{
- if (mon == MONS_RAKSHASA_FAKE ||
- mon == MONS_ARMOUR_MIMIC ||
- mon == MONS_SCROLL_MIMIC ||
- mon == MONS_POTION_MIMIC ||
- mon == MONS_ABOMINATION_LARGE)
+ if (mon == MONS_RAKSHASA_FAKE
+ || mon == MONS_ARMOUR_MIMIC
+ || mon == MONS_SCROLL_MIMIC
+ || mon == MONS_POTION_MIMIC
+ || mon == MONS_ABOMINATION_LARGE)
{
// keep previous entry
continue;
@@ -3194,6 +3194,16 @@ void monsters::pickup_message(const item_def &item, int near)
bool monsters::pickup(item_def &item, int slot, int near, bool force_merge)
{
+ // If a monster chooses a two-handed weapon as main weapon, it will
+ // first have to drop any shield it might wear.
+ // (Monsters will always favour damage over protection.)
+ if (slot == MSLOT_WEAPON && inv[MSLOT_SHIELD] != NON_ITEM
+ && hands_reqd(item, body_size(PSIZE_BODY)) == HANDS_TWO)
+ {
+ if (!drop_item(MSLOT_SHIELD, near))
+ return false;
+ }
+
if (inv[slot] != NON_ITEM)
{
if (items_stack(item, mitm[inv[slot]], force_merge))
@@ -3319,12 +3329,20 @@ static bool _is_signature_weapon(monsters *monster, const item_def &weapon)
bool monsters::pickup_melee_weapon(item_def &item, int near)
{
+ const bool is_2handed =
+ (hands_reqd(item, body_size(PSIZE_BODY)) == HANDS_TWO);
+ size_type size = body_size(PSIZE_BODY);
+
if (mons_wields_two_weapons(this))
{
+ const item_def *wpn = mslot_item(MSLOT_WEAPON);
+ const item_def *alt = mslot_item(MSLOT_ALT_WEAPON);
+
// If we have either weapon slot free, pick up the weapon.
- if (inv[MSLOT_WEAPON] == NON_ITEM)
+ if (!wpn && (!alt || hands_reqd(*alt, size) < HANDS_TWO && !is_2handed))
return pickup(item, MSLOT_WEAPON, near);
- else if (inv[MSLOT_ALT_WEAPON] == NON_ITEM)
+
+ if (!alt && (!wpn || hands_reqd(*wpn, size) < HANDS_TWO && !is_2handed))
return pickup(item, MSLOT_ALT_WEAPON, near);
}
@@ -3389,6 +3407,7 @@ bool monsters::pickup_throwable_weapon(item_def &item, int near)
bool monsters::wants_weapon(const item_def &weap) const
{
+ // monsters can't use fixed artefacts
if (is_fixed_artefact( weap ))
return (false);
@@ -3400,26 +3419,26 @@ bool monsters::wants_weapon(const item_def &weap) const
return (false);
}
- // XXX: Make this check dependent on creature size.
- // wimpy monsters (Kob, gob) shouldn't pick up halberds etc
- // of course, this also block knives {dlb}:
- if ((::mons_species(type) == MONS_KOBOLD
- || ::mons_species(type) == MONS_GOBLIN)
- && property( weap, PWPN_HIT ) <= 0)
- {
+ // Wimpy monsters (e.g. kobold, goblin) shouldn't pick up halberds etc.
+ if (!check_weapon_wieldable_size( weap, body_size(PSIZE_BODY) ))
return (false);
- }
- // Nobody picks up giant clubs:
+ // Nobody picks up giant clubs.
+ // Starting equipment is okay, of course.
if (weap.sub_type == WPN_GIANT_CLUB
|| weap.sub_type == WPN_GIANT_SPIKED_CLUB)
{
return (false);
}
+ // Demonid/undead monsters won't pick up holy wrath.
if (get_weapon_brand(weap) == SPWPN_HOLY_WRATH && mons_is_unholy(this))
return (false);
+ // Holy monsters won't pick up demonic weapons.
+ if (mons_holiness(this) == MH_HOLY && is_evil_item(weap))
+ return (false);
+
return (true);
}
@@ -3490,12 +3509,13 @@ bool monsters::pickup_armour(item_def &item, int near, bool force)
if (mslot == NUM_MONSTER_SLOTS)
return (false);
- // Don't pick up a shield if you're already wielding a two-hander, or
- // two weapons as a double-wielding monster.
- if (mslot == MSLOT_SHIELD && mslot_item(MSLOT_WEAPON)
- && (hands_reqd(*mslot_item(MSLOT_WEAPON), body_size(PSIZE_BODY))
- == HANDS_TWO
- || mslot_item(MSLOT_ALT_WEAPON) && mons_wields_two_weapons(this)))
+ // Monsters that are capable of dual wielding won't pick up shields.
+ // Neither will monsters that are already wielding a two-hander.
+ if (mslot == MSLOT_SHIELD
+ && (mons_wields_two_weapons(this)
+ || mslot_item(MSLOT_WEAPON)
+ && hands_reqd(*mslot_item(MSLOT_WEAPON), body_size(PSIZE_BODY))
+ == HANDS_TWO))
{
return (false);
}
@@ -3620,6 +3640,11 @@ bool monsters::pickup_wand(item_def &item, int near)
if (hit_dice >= 14)
return (false);
+ // This is the only type based restriction I can think of:
+ // Holy monsters won't pick up draining items.
+ if (mons_holiness(this) == MH_HOLY && item.sub_type == WAND_DRAINING)
+ return (false);
+
// If you already have a charged wand, don't bother.
// Otherwise, replace with a charged one.
if (item_def *wand = mslot_item(MSLOT_WAND))
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 88b37366ab..3ad061bdfb 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -2551,15 +2551,15 @@ bool is_evil_item(const item_def& item)
int item_eff = item_special_wield_effect(item);
retval = (is_demonic(item)
- || item.special == SPWPN_SCEPTRE_OF_ASMODEUS
- || item.special == SPWPN_STAFF_OF_DISPATER
- || item.special == SPWPN_SWORD_OF_CEREBOV
- || item_eff == SPWLD_CURSE
- || item_eff == SPWLD_TORMENT
- || item_eff == SPWLD_ZONGULDROK
- || item_brand == SPWPN_DRAINING
- || item_brand == SPWPN_PAIN
- || item_brand == SPWPN_VAMPIRICISM);
+ || item.special == SPWPN_SCEPTRE_OF_ASMODEUS
+ || item.special == SPWPN_STAFF_OF_DISPATER
+ || item.special == SPWPN_SWORD_OF_CEREBOV
+ || item_eff == SPWLD_CURSE
+ || item_eff == SPWLD_TORMENT
+ || item_eff == SPWLD_ZONGULDROK
+ || item_brand == SPWPN_DRAINING
+ || item_brand == SPWPN_PAIN
+ || item_brand == SPWPN_VAMPIRICISM);
}
break;
case OBJ_WANDS:
@@ -2570,18 +2570,18 @@ bool is_evil_item(const item_def& item)
break;
case OBJ_POTIONS:
retval = (item.sub_type == POT_BLOOD
- || item.sub_type == POT_BLOOD_COAGULATED);
+ || item.sub_type == POT_BLOOD_COAGULATED);
break;
case OBJ_BOOKS:
retval = (item.sub_type == BOOK_NECROMANCY
- || item.sub_type == BOOK_DEATH
- || item.sub_type == BOOK_UNLIFE
- || item.sub_type == BOOK_NECRONOMICON
- || item.sub_type == BOOK_DEMONOLOGY);
+ || item.sub_type == BOOK_DEATH
+ || item.sub_type == BOOK_UNLIFE
+ || item.sub_type == BOOK_NECRONOMICON
+ || item.sub_type == BOOK_DEMONOLOGY);
break;
case OBJ_STAVES:
retval = (item.sub_type == STAFF_DEATH
- || item.sub_type == STAFF_DEMONOLOGY);
+ || item.sub_type == STAFF_DEMONOLOGY);
break;
case OBJ_MISCELLANY:
retval = (item.sub_type == MISC_LANTERN_OF_SHADOWS);