From f119c29736878ef93deed692013d3c974831b038 Mon Sep 17 00:00:00 2001 From: zelgadis Date: Sat, 22 Nov 2008 03:48:27 +0000 Subject: Fix bug 2298697: for dealing with weapons of returning which fail to return, mons_throw() should have been using the mslot of the weapon, not weapon's mitm index. Introduces the new functions get_mon_equip_slot() and item_to_mslot(). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7530 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/items.cc | 18 ++++++++++++++++++ crawl-ref/source/items.h | 3 ++- crawl-ref/source/mon-util.cc | 25 +++++++++++++++++++++++++ crawl-ref/source/mon-util.h | 1 + crawl-ref/source/mstuff2.cc | 4 +++- 5 files changed, 49 insertions(+), 2 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 1675ec0c9b..498722a4a4 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -2019,6 +2019,24 @@ int get_equip_slot(const item_def *item) return worn; } +mon_inv_type get_mon_equip_slot(const monsters* mon, const item_def &item) +{ + ASSERT(mon->alive()); + + mon_inv_type slot = item_to_mslot(item); + + if (slot == NUM_MONSTER_SLOTS) + return NUM_MONSTER_SLOTS; + + if (mon->mslot_item(slot) == &item) + return slot; + + if (slot == MSLOT_WEAPON && mon->mslot_item(MSLOT_ALT_WEAPON) == &item) + return MSLOT_ALT_WEAPON; + + return NUM_MONSTER_SLOTS; +} + static std::string _drop_selitem_text( const std::vector *s ) { char buf[130]; diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h index 79ec57bf00..fa892313c4 100644 --- a/crawl-ref/source/items.h +++ b/crawl-ref/source/items.h @@ -122,7 +122,8 @@ bool pickup_single_item(int link, int qty); bool drop_item( int item_dropped, int quant_drop, bool try_offer = false ); -int get_equip_slot(const item_def *item); +int get_equip_slot(const item_def *item); +mon_inv_type get_mon_equip_slot(const monsters* mon, const item_def &item); void origin_set(const coord_def& where); void origin_set_monster(item_def &item, const monsters *monster); diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 9b78057767..72c277c7ca 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -4131,6 +4131,31 @@ mon_inv_type equip_slot_to_mslot(equipment_type eq) } } +mon_inv_type item_to_mslot(const item_def &item) +{ + switch(item.base_type) + { + case OBJ_WEAPONS: + return MSLOT_WEAPON; + case OBJ_MISSILES: + return MSLOT_MISSILE; + case OBJ_ARMOUR: + return equip_slot_to_mslot(get_armour_slot(item)); + case OBJ_WANDS: + return MSLOT_WAND; + case OBJ_SCROLLS: + return MSLOT_SCROLL; + case OBJ_POTIONS: + return MSLOT_POTION; + case OBJ_MISCELLANY: + return MSLOT_MISCELLANY; + case OBJ_GOLD: + return MSLOT_GOLD; + default: + return NUM_MONSTER_SLOTS; + } +} + bool monsters::pickup_armour(item_def &item, int near, bool force) { ASSERT(item.base_type == OBJ_ARMOUR); diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 5b858ac0ab..6ca24ba116 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -818,5 +818,6 @@ bool mons_class_can_pass(int mc, const dungeon_feature_type grid); bool mons_can_pass(const monsters *mon, dungeon_feature_type grid); mon_inv_type equip_slot_to_mslot(equipment_type eq); +mon_inv_type item_to_mslot(const item_def &item); #endif diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index 3e7a06f2fd..22b9aa24c9 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -840,6 +840,8 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) int weapon = monster->inv[MSLOT_WEAPON]; int lnchType = (weapon != NON_ITEM) ? mitm[weapon].sub_type : 0; + mon_inv_type slot = get_mon_equip_slot(monster, mitm[hand_used]); + const bool skilled = mons_class_flag(monster->type, M_FIGHTER); monster->lose_energy(EUT_MISSILE); @@ -1203,7 +1205,7 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) } } else if (dec_mitm_item_quantity(hand_used, 1)) - monster->inv[returning ? hand_used : MSLOT_MISSILE] = NON_ITEM; + monster->inv[returning ? slot : MSLOT_MISSILE] = NON_ITEM; return (true); } -- cgit v1.2.3-54-g00ecf