From 42b39aa47435aba3ebc1376e05f0e54624bbfad3 Mon Sep 17 00:00:00 2001 From: Tamian Date: Tue, 1 Dec 2015 17:36:50 +0100 Subject: [PATCH] Split the look-up portion of FindEquipSlot into a second function ViableEquipSlots. This is to be able to test or check for viability between two items, including those that are NOT in inventory. Fixed minor typo in debug code. (based on https://github.com/cmangos/mangos-wotlk/commit/cce53ced2257ebbb00c5c9286b985b498907c0e7) Signed-off-by: Cala --- src/game/Player.cpp | 319 +++++++++++++++++++++++++++----------------- src/game/Player.h | 1 + 2 files changed, 201 insertions(+), 119 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 694eaf2624..28faf529ec 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -7756,127 +7756,12 @@ void Player::SetSheath(SheathState sheathed) uint8 Player::FindEquipSlot(ItemPrototype const* proto, uint32 slot, bool swap) const { - uint8 pClass = getClass(); - uint8 slots[4]; - slots[0] = NULL_SLOT; - slots[1] = NULL_SLOT; - slots[2] = NULL_SLOT; - slots[3] = NULL_SLOT; - switch (proto->InventoryType) - { - case INVTYPE_HEAD: - slots[0] = EQUIPMENT_SLOT_HEAD; - break; - case INVTYPE_NECK: - slots[0] = EQUIPMENT_SLOT_NECK; - break; - case INVTYPE_SHOULDERS: - slots[0] = EQUIPMENT_SLOT_SHOULDERS; - break; - case INVTYPE_BODY: - slots[0] = EQUIPMENT_SLOT_BODY; - break; - case INVTYPE_CHEST: - slots[0] = EQUIPMENT_SLOT_CHEST; - break; - case INVTYPE_ROBE: - slots[0] = EQUIPMENT_SLOT_CHEST; - break; - case INVTYPE_WAIST: - slots[0] = EQUIPMENT_SLOT_WAIST; - break; - case INVTYPE_LEGS: - slots[0] = EQUIPMENT_SLOT_LEGS; - break; - case INVTYPE_FEET: - slots[0] = EQUIPMENT_SLOT_FEET; - break; - case INVTYPE_WRISTS: - slots[0] = EQUIPMENT_SLOT_WRISTS; - break; - case INVTYPE_HANDS: - slots[0] = EQUIPMENT_SLOT_HANDS; - break; - case INVTYPE_FINGER: - slots[0] = EQUIPMENT_SLOT_FINGER1; - slots[1] = EQUIPMENT_SLOT_FINGER2; - break; - case INVTYPE_TRINKET: - slots[0] = EQUIPMENT_SLOT_TRINKET1; - slots[1] = EQUIPMENT_SLOT_TRINKET2; - break; - case INVTYPE_CLOAK: - slots[0] = EQUIPMENT_SLOT_BACK; - break; - case INVTYPE_WEAPON: - { - slots[0] = EQUIPMENT_SLOT_MAINHAND; - // suggest offhand slot only if know dual wielding - // (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ... - if (CanDualWield()) - slots[1] = EQUIPMENT_SLOT_OFFHAND; - break; - }; - case INVTYPE_SHIELD: - slots[0] = EQUIPMENT_SLOT_OFFHAND; - break; - case INVTYPE_RANGED: - slots[0] = EQUIPMENT_SLOT_RANGED; - break; - case INVTYPE_2HWEAPON: - slots[0] = EQUIPMENT_SLOT_MAINHAND; - break; - case INVTYPE_TABARD: - slots[0] = EQUIPMENT_SLOT_TABARD; - break; - case INVTYPE_WEAPONMAINHAND: - slots[0] = EQUIPMENT_SLOT_MAINHAND; - break; - case INVTYPE_WEAPONOFFHAND: - slots[0] = EQUIPMENT_SLOT_OFFHAND; - break; - case INVTYPE_HOLDABLE: - slots[0] = EQUIPMENT_SLOT_OFFHAND; - break; - case INVTYPE_THROWN: - slots[0] = EQUIPMENT_SLOT_RANGED; - break; - case INVTYPE_RANGEDRIGHT: - slots[0] = EQUIPMENT_SLOT_RANGED; - break; - case INVTYPE_BAG: - slots[0] = INVENTORY_SLOT_BAG_START + 0; - slots[1] = INVENTORY_SLOT_BAG_START + 1; - slots[2] = INVENTORY_SLOT_BAG_START + 2; - slots[3] = INVENTORY_SLOT_BAG_START + 3; - break; - case INVTYPE_RELIC: - { - switch (proto->SubClass) - { - case ITEM_SUBCLASS_ARMOR_LIBRAM: - if (pClass == CLASS_PALADIN) - slots[0] = EQUIPMENT_SLOT_RANGED; - break; - case ITEM_SUBCLASS_ARMOR_IDOL: - if (pClass == CLASS_DRUID) - slots[0] = EQUIPMENT_SLOT_RANGED; - break; - case ITEM_SUBCLASS_ARMOR_TOTEM: - if (pClass == CLASS_SHAMAN) - slots[0] = EQUIPMENT_SLOT_RANGED; - break; - case ITEM_SUBCLASS_ARMOR_MISC: - if (pClass == CLASS_WARLOCK) - slots[0] = EQUIPMENT_SLOT_RANGED; - break; - } - break; - } - default : - return NULL_SLOT; + if (!ViableEquipSlots(proto, &slots[0])) + { + //DEBUG_LOG("**** [Player::FindEquipSlot] ViableEquipSlots returned FALSE ****"); + return NULL_SLOT; } if (slot != NULL_SLOT) @@ -7915,6 +7800,202 @@ uint8 Player::FindEquipSlot(ItemPrototype const* proto, uint32 slot, bool swap) return NULL_SLOT; } + +bool Player::ViableEquipSlots(ItemPrototype const* proto, uint8 *viable_slots) const +{ + uint8 pClass; + + //DEBUG_LOG("**** [Player::ViableEquipSlots] Start ****"); + + if (!viable_slots) + { + //DEBUG_LOG("**** [Player::ViableEquipSlots] Return array is NULL ****"); + return false; + } + + //DEBUG_LOG("**** [Player::ViableEquipSlots] Initialize return array ****"); + viable_slots[0] = NULL_SLOT; + viable_slots[1] = NULL_SLOT; + viable_slots[2] = NULL_SLOT; + viable_slots[3] = NULL_SLOT; + + if (CanUseItem(proto) == EQUIP_ERR_OK) + { + //DEBUG_LOG("**** [Player::ViableEquipSlots] Class/Race/Faction determined viable ****"); + + //DEBUG_LOG("**** [Player::ViableEquipSlots] switch (proto->InventoryType) ****"); + switch (proto->InventoryType) + { + case INVTYPE_HEAD: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_HEAD ****"); + viable_slots[0] = EQUIPMENT_SLOT_HEAD; + break; + case INVTYPE_NECK: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_NECK ****"); + viable_slots[0] = EQUIPMENT_SLOT_NECK; + break; + case INVTYPE_SHOULDERS: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_SHOULDERS ****"); + viable_slots[0] = EQUIPMENT_SLOT_SHOULDERS; + break; + case INVTYPE_BODY: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_BODY ****"); + viable_slots[0] = EQUIPMENT_SLOT_BODY; + break; + case INVTYPE_CHEST: + case INVTYPE_ROBE: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == %s ****",(INVTYPE_CHEST ? "INVTYPE_CHEST" : "INVTYPE_ROBE")); + viable_slots[0] = EQUIPMENT_SLOT_CHEST; + break; + case INVTYPE_WAIST: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_WAIST ****"); + viable_slots[0] = EQUIPMENT_SLOT_WAIST; + break; + case INVTYPE_LEGS: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_LEGS ****"); + viable_slots[0] = EQUIPMENT_SLOT_LEGS; + break; + case INVTYPE_FEET: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_FEET ****"); + viable_slots[0] = EQUIPMENT_SLOT_FEET; + break; + case INVTYPE_WRISTS: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_WRISTS ****"); + viable_slots[0] = EQUIPMENT_SLOT_WRISTS; + break; + case INVTYPE_HANDS: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_HANDS ****"); + viable_slots[0] = EQUIPMENT_SLOT_HANDS; + break; + case INVTYPE_FINGER: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_FINGER ****"); + viable_slots[0] = EQUIPMENT_SLOT_FINGER1; + viable_slots[1] = EQUIPMENT_SLOT_FINGER2; + break; + case INVTYPE_TRINKET: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_TRINKET ****"); + viable_slots[0] = EQUIPMENT_SLOT_TRINKET1; + viable_slots[1] = EQUIPMENT_SLOT_TRINKET2; + break; + case INVTYPE_CLOAK: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_CLOAK ****"); + viable_slots[0] = EQUIPMENT_SLOT_BACK; + break; + case INVTYPE_WEAPON: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_WEAPON ****"); + viable_slots[0] = EQUIPMENT_SLOT_MAINHAND; + + //DEBUG_LOG("**** [Player::ViableEquipSlots] INVTYPE_WEAPON/Determining if can dual weild ****"); + if (CanDualWield()) + { + //DEBUG_LOG("**** [Player::ViableEquipSlots] INVTYPE_WEAPON/CanDualWield() == TRUE ****"); + viable_slots[1] = EQUIPMENT_SLOT_OFFHAND; + } + break; + case INVTYPE_SHIELD: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_SHIELD ****"); + viable_slots[0] = EQUIPMENT_SLOT_OFFHAND; + break; + case INVTYPE_RANGED: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RANGED ****"); + viable_slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case INVTYPE_2HWEAPON: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_2HWEAPON ****"); + viable_slots[0] = EQUIPMENT_SLOT_MAINHAND; + + //DEBUG_LOG("**** [Player::ViableEquipSlots] INVTYPE_2HWEAPON/Determining if can dual weild and Titian Grip ****"); + if (CanDualWield()) + { + //DEBUG_LOG("**** [Player::ViableEquipSlots] INVTYPE_2HWEAPON/CanDualWield() && CanTitanGrip() == TRUE ****"); + viable_slots[1] = EQUIPMENT_SLOT_OFFHAND; + } + break; + case INVTYPE_TABARD: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_TABARD ****"); + viable_slots[0] = EQUIPMENT_SLOT_TABARD; + break; + case INVTYPE_WEAPONMAINHAND: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_WEAPONMAINHAND ****"); + viable_slots[0] = EQUIPMENT_SLOT_MAINHAND; + break; + case INVTYPE_WEAPONOFFHAND: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_WEAPONOFFHAND ****"); + viable_slots[0] = EQUIPMENT_SLOT_OFFHAND; + break; + case INVTYPE_HOLDABLE: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_HOLDABLE ****"); + viable_slots[0] = EQUIPMENT_SLOT_OFFHAND; + break; + case INVTYPE_THROWN: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_THROWN ****"); + viable_slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case INVTYPE_RANGEDRIGHT: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RANGEDRIGHT ****"); + viable_slots[0] = EQUIPMENT_SLOT_RANGED; + break; + case INVTYPE_BAG: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_BAG ****"); + viable_slots[0] = INVENTORY_SLOT_BAG_START + 0; + viable_slots[1] = INVENTORY_SLOT_BAG_START + 1; + viable_slots[2] = INVENTORY_SLOT_BAG_START + 2; + viable_slots[3] = INVENTORY_SLOT_BAG_START + 3; + break; + case INVTYPE_RELIC: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC ****"); + + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC - Determine Play Class ****"); + pClass = getClass(); + + if (pClass) + { + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC - Call to getClass() returned sucess ****"); + + switch (proto->SubClass) + { + case ITEM_SUBCLASS_ARMOR_LIBRAM: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC / proto->SubClass == ITEM_SUBCLASS_ARMOR_LIBRAM ****"); + if (pClass == CLASS_PALADIN) + { + viable_slots[0] = EQUIPMENT_SLOT_RANGED; + } + break; + case ITEM_SUBCLASS_ARMOR_IDOL: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC / proto->SubClass == ITEM_SUBCLASS_ARMOR_IDOL ****"); + if (pClass == CLASS_DRUID) + { + viable_slots[0] = EQUIPMENT_SLOT_RANGED; + } + break; + case ITEM_SUBCLASS_ARMOR_TOTEM: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC / proto->SubClass == ITEM_SUBCLASS_ARMOR_TOTEM ****"); + if (pClass == CLASS_SHAMAN) + { + viable_slots[0] = EQUIPMENT_SLOT_RANGED; + } + break; + case ITEM_SUBCLASS_ARMOR_MISC: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC / proto->SubClass == ITEM_SUBCLASS_ARMOR_MISC ****"); + if (pClass == CLASS_WARLOCK) + { + viable_slots[0] = EQUIPMENT_SLOT_RANGED; + } + break; + default: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == INVTYPE_RELIC / proto->SubClass == UNKNOWN ****"); + break; + } + } + break; + default: + //DEBUG_LOG("**** [Player::ViableEquipSlots] proto->InventoryType == UNKNOWN ****"); + break; + } + } + return (viable_slots[0] != NULL_SLOT); +} + InventoryResult Player::CanUnequipItems(uint32 item, uint32 count) const { Item* pItem; diff --git a/src/game/Player.h b/src/game/Player.h index f9c3012547..43efb990a4 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1062,6 +1062,7 @@ class MANGOS_DLL_SPEC Player : public Unit void SetVirtualItemSlot(uint8 i, Item* item); void SetSheath(SheathState sheathed) override; // overwrite Unit version + bool ViableEquipSlots(ItemPrototype const* proto, uint8 *viable_slots) const; uint8 FindEquipSlot(ItemPrototype const* proto, uint32 slot, bool swap) const; uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = nullptr) const; Item* GetItemByGuid(ObjectGuid guid) const;