diff options
-rw-r--r-- | crawl-ref/source/describe.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/directn.cc | 53 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 69 | ||||
-rw-r--r-- | crawl-ref/source/religion.cc | 30 |
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); |