Applying Matthew's latest patch (1789869): Identify items you see monsters use.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2068 c06c8d41-db1a-0410-9941-cceddc491573
L254F6ZIU2HWGLFFGPIORTN4C3TDQ3E5JZ7Z7GQA5AEDIKL6PKDAC BSI5DB3LVY42ZHOS46X2CAPPVOSOTTQWFGLTMAKRFTROI5BQWFDQC J6APXOT4QOGQFONWB7G546VTVF6QG42HVOROMHF7YBDJPR4K26OAC PFEJ4LMDNEKLMGRCMWQ7EIRVU4JMYGICI4G7X4WVWOROVXQCBZ7QC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC ANOEQTM6IGCBTESKKQ5PCBSDTZ7VGRCMDIOAFEH4R7DJHKWKDFAAC UWMN4HLG6YA2YFQEVIVMDISD6APKEPIZXMMPMNUYCBQDSAUYSXPQC QS3ZRS3E6KL3YJHPKYEWCWJYRBJSXD5OOYF6Y25HZVECGPJRDB5QC 3GSAVTNKEG45AT2U734R5STSRP22WJZL3H6KUFRUWCIA6A4CZE5QC C67GX7W5HBCDPQJRSHWMLM4DUJ3ELFSHH42SVICFJVCJW25T5Z3AC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC HDLNRHAMFVDM4QCZMY6COBYZ35ODPR5PONT4UE77UAZ7GEE2FLHQC 4GGNXCX2CLKWQZIZT543LXFFKFRD4PY5XPJFLGWKW4ACKYZNLVPQC KTXVWUS3MNY7WCPUYZDDU3RVLFKKFLSWRCWKSDNYNMPYZQCVJ24AC VNHFP63ZLLZU3A3PLXP4BITX57DUIYDHFOHQYK3BOBHV3S64G26QC CIPVRZGLOZHCERK6YPOBV3P2E4IAB4H6D5EHLRQE2O5E4P4VCBUAC OQ4KB7QCJSK7GSW3DYBARH4DCB75HFKLUSOSOZZZ4IUFKNGFRUDQC 2KTJHQUX2LTU2BCLS5YXVRRKMOYKKIZAPF2LBKORFGSHEN5IO3IAC U24V52ZGVQ2XGYA4RNKT26VIIEKUYC6AUEWZSDYJFXB5ZWMMXTPAC QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC L4PKJZERR7WADKWHY3MR6J6OZFREVPL3CB43I6MLJ2BVKWCUTE7AC TV3ZC6WOZKSQQJQN26JIVKCHK6UK7WMDBYZDUYRWEAZ4JB4YVNAAC LW4N5EHKL776DURXZMAM6JEW3JPWWX5BSNP7TCZHTLCDOQTTGFCAC BNTPYSO6ECZ76CHHLDP3ASSPDSEUH4Y3E3LETKNXVWAWJRFL3YEQC TJRYL3NXPW5IUGEV3YOC7JYWEXCZDBFPLT4AUG4P227WVKVB72ZAC HSRRNAU5UAYC6B6IQWGJPFROMZBTJICPCH6DJVZDHDTAGOQ6IOYAC WLX2RQMMOMP2PYPAGJRM4VFD2WTLJTOAZZPPY3MV76FU2EGEJ54QC }}static void learn_visible_mon_eq_egos(monsters *mon){for (int i = 0; i < NUM_MONSTER_SLOTS; i++){mon_inv_type slot = static_cast<mon_inv_type>(i);int index = mon->inv[slot];if (index == NON_ITEM)continue;// Alternate weapons aren't wielded (and thus have no// visible differences) unless the monster can wield two// weapons at once.if (slot == MSLOT_ALT_WEAPON && !mons_wields_two_weapons(mon))continue;item_def &item = mitm[index];if (mons_eq_obvious_ego(item, mon))set_ident_flags(item, ISFLAG_KNOW_TYPE);
int ego = item.special;switch(ego){case SPWPN_FLAMING:case SPWPN_FREEZING:case SPWPN_HOLY_WRATH:case SPWPN_VENOM:// Electric branded weapons are constantly cracklingcase SPWPN_ELECTROCUTION:// Unlike SPWPN_FLAME, SPWPN_FROST has a persistant visual effect.case SPWPN_FROST:return true;// SPWPN_FLAME just "glows red for a moment" when first equipped,// so it isn't obvious after that.case SPWPN_FLAME:return false;}return false;}
void monsters::equip(const item_def &item, int slot, int near)
void monsters::equip_armour(item_def &item, int near){if (need_message(near))mprf("%s wears %s.", name(DESC_CAP_THE).c_str(),item.name(DESC_NOCAP_A).c_str());ac += property( item, PARM_AC );const int armour_plus = item.plus;ASSERT(abs(armour_plus) < 20);if (abs(armour_plus) < 20)ac += armour_plus;ev += property( item, PARM_EVASION ) / 2;if (ev < 1)ev = 1; // This *shouldn't* happen.}void monsters::equip(item_def &item, int slot, int near)
{ac += property( item, PARM_AC );const int armour_plus = item.plus;ASSERT(abs(armour_plus) < 20);if (abs(armour_plus) < 20)ac += armour_plus;ev += property( item, PARM_EVASION ) / 2;if (ev < 1)ev = 1; // This *shouldn't* happen.
equip_armour(item, near);
void monsters::unequip_weapon(item_def &item, int near){if (need_message(near))mprf("%s unwields %s.", name(DESC_CAP_THE).c_str(),item.name(DESC_NOCAP_A).c_str());const int brand = get_weapon_brand(item);if (brand == SPWPN_PROTECTION)ac -= 5;if (brand != SPWPN_NORMAL && need_message(near)){bool message_given = true;switch (brand){case SPWPN_FLAMING:mpr("It stops flaming.");break;
void monsters::unequip(const item_def &item, int slot, int near)
case SPWPN_HOLY_WRATH:mpr("It stops glowing.");break;case SPWPN_ELECTROCUTION:mpr("It stops crackling.");break;case SPWPN_VENOM:mpr("It stops dripping with poison.");break;case SPWPN_DISTORTION:mpr("Its appearance distorts for a moment.");break;default:message_given = false;}if (message_given)set_ident_flags(item, ISFLAG_KNOW_TYPE);}}void monsters::unequip_armour(item_def &item, int near)
// XXX: Handle armour removal when armour swapping is implemented.
if (need_message(near))mprf("%s takes off %s.", name(DESC_CAP_THE).c_str(),item.name(DESC_NOCAP_A).c_str());ac -= property( item, PARM_AC );const int armour_plus = item.plus;ASSERT(abs(armour_plus) < 20);if (abs(armour_plus) < 20)ac -= armour_plus;ev -= property( item, PARM_EVASION ) / 2;if (ev < 1)ev = 1; // This *shouldn't* happen.}bool monsters::unequip(item_def &item, int slot, int near, bool force){if (item.cursed() && !force)return false;if (!force && mons_near(this) && player_monster_visible(this))set_ident_flags(item, ISFLAG_KNOW_CURSE);
if (get_weapon_brand(item) == SPWPN_PROTECTION)ac -= 5;
unequip_weapon(item, near);break;// Armour swapping not implemented yet, but armour can be// removed if wizard forces monster to wear a new piece of// armour with the "give item" wizard command.case OBJ_ARMOUR:unequip_armour(item, near);
// Cannot drop cursed weapon or armour.if ((eslot == MSLOT_WEAPON || eslot == MSLOT_ARMOUR)&& mitm[index].cursed())return (false);
// Unequip equipped items before dropping them; unequip() prevents// cursed items from being removed.bool was_unequipped = false;if (eslot == MSLOT_WEAPON || eslot == MSLOT_ARMOUR|| (eslot == MSLOT_ALT_WEAPON && mons_wields_two_weapons(this) )){if (!unequip(mitm[index], eslot, near))return (false);was_unequipped = true;}
if (defender->atype() == ACT_PLAYER && attacker_visible&& weapon != NULL && !is_artefact(*weapon)){// If the player is being sent to the Abyss by being attacked// with a distortion weapon, then we have to ID it before// the player goes to Abyss, while the weapon object is// still in memory.set_ident_flags(*weapon, ISFLAG_KNOW_TYPE);}else if (defender_visible)obvious_effect = true;
#ifdef WIZARDvoid wizard_give_monster_item(monsters *mon){mon_itemuse_type item_use = mons_itemuse( mon->type );if (item_use < MONUSE_STARTING_EQUIPMENT){mpr("That type of monster can't use any items.");return;}int player_slot = prompt_invent_item( "Give which item to monster?",MT_DROP, -1 );if (player_slot == PROMPT_ABORT)return;for (int i = 0; i < NUM_EQUIP; i++)if (you.equip[i] == player_slot){mpr("Can't give equipped items to a monster.");return;}item_def &item = you.inv[player_slot];mon_inv_type mon_slot;switch(item.base_type){case OBJ_WEAPONS:// Let wizard specify which slot to put weapon into via// inscriptions.if (item.inscription.find("first") != std::string::npos|| item.inscription.find("primary") != std::string::npos){mpr("Putting weapon into primary slot by inscription");mon_slot = MSLOT_WEAPON;break;}else if (item.inscription.find("second") != std::string::npos|| item.inscription.find("alt") != std::string::npos){mpr("Putting weapon into alt slot by inscription");mon_slot = MSLOT_ALT_WEAPON;break;}// For monsters which can wield two weapons, prefer whichever// slot is empty (if there is an empty slot).if (mons_wields_two_weapons(mon)){if (mon->inv[MSLOT_WEAPON] == NON_ITEM){mpr("Dual wielding monster, putting into empty primary slot");mon_slot = MSLOT_WEAPON;break;}else if (mon->inv[MSLOT_ALT_WEAPON] == NON_ITEM){mpr("Dual wielding monster, putting into empty alt slot");mon_slot = MSLOT_ALT_WEAPON;break;}}
// Try to replace a ranged weapon with a ranged weapon and// a non-ranged weapon with a non-ranged weaponif (mon->inv[MSLOT_WEAPON] != NON_ITEM&& (is_range_weapon(mitm[mon->inv[MSLOT_WEAPON]])== is_range_weapon(item))){mpr("Replacing primary slot with similar weapon");mon_slot = MSLOT_WEAPON;break;}if (mon->inv[MSLOT_ALT_WEAPON] != NON_ITEM&& (is_range_weapon(mitm[mon->inv[MSLOT_ALT_WEAPON]])== is_range_weapon(item))){mpr("Replacing alt slot with similar weapon");mon_slot = MSLOT_ALT_WEAPON;break;}
// Prefer the empty slot (if any)if (mon->inv[MSLOT_WEAPON] == NON_ITEM){mpr("Putting weapon into empty primary slot");mon_slot = MSLOT_WEAPON;break;}else if (mon->inv[MSLOT_ALT_WEAPON] == NON_ITEM){mpr("Putting weapon into empty alt slot");mon_slot = MSLOT_ALT_WEAPON;break;}// Default to primary weapon slotmpr("Defaulting to primary slot");mon_slot = MSLOT_WEAPON;break;case OBJ_ARMOUR:mon_slot = MSLOT_ARMOUR;break;case OBJ_MISSILES:mon_slot = MSLOT_MISSILE;break;case OBJ_WANDS:mon_slot = MSLOT_WAND;break;case OBJ_SCROLLS:mon_slot = MSLOT_SCROLL;break;case OBJ_POTIONS:mon_slot = MSLOT_POTION;break;case OBJ_MISCELLANY:mon_slot = MSLOT_MISCELLANY;break;default:mpr("You can't give that type of item to a monster.");return;}// Shouldn't be be using MONUSE_MAGIC_ITEMS?if (item_use == MONUSE_STARTING_EQUIPMENT&& !mons_is_unique( mon->type )){switch(mon_slot){case MSLOT_WEAPON:case MSLOT_ALT_WEAPON:case MSLOT_ARMOUR:case MSLOT_MISSILE:break;default:mpr("That type of monster can only use weapons and armour.");return;}}int index = get_item_slot(10);if (index == NON_ITEM){mpr("Too many items on level, bailing.");return;}// Move monster's old item to player's inventory as last stepint old_eq = NON_ITEM;if (mon->inv[mon_slot] != NON_ITEM){old_eq = mon->inv[mon_slot];// Alternative weapons don't get (un)wielded unless the monster// can wield two weapons.if (mon_slot != MSLOT_ALT_WEAPON || mons_wields_two_weapons(mon))mon->unequip(*(mon->mslot_item(mon_slot)), mon_slot, 1, true);}item_def &new_item = mitm[index];new_item = item;new_item.link = NON_ITEM;new_item.x = 0;new_item.y = 0;mon->inv[mon_slot] = index;// Alternative weapons don't get (un)wielded unless the monster// can wield two weapons.if (mon_slot != MSLOT_ALT_WEAPON || mons_wields_two_weapons(mon))mon->equip(new_item, mon_slot, 1);// Item is gone from player's inventorydec_inv_item_quantity(player_slot, item.quantity);// Monster's old item moves to player's inventory.if (old_eq != NON_ITEM){mpr("Fetching monster's old item.");move_item_to_player(old_eq, mitm[old_eq].quantity);}}#endif
// Forget things that nearby monsters are carrying, as well// (for use with the "give monster an item" wizard targetting// command).for (i = 0; i < MAX_MONSTERS; i++){monsters* mon = &menv[i];if (!invalid_monster(mon) && mons_near(mon)){for (j = 0; j < NUM_MONSTER_SLOTS; j++){if (mon->inv[j] == NON_ITEM)continue;item_def &item = mitm[mon->inv[j]];if (!is_valid_item(item))continue;set_ident_type( item.base_type, item.sub_type,ID_UNKNOWN_TYPE );unset_ident_flags( item, ISFLAG_IDENT_MASK );}}}