@@ -291,6 +291,8 @@ Player::Player(WorldSession* session): Unit(true)
291291 m_canParry = false;
292292 m_canBlock = false;
293293 m_canTitanGrip = false;
294+ m_titanGripWeaponSubclasses = 0;
295+ m_titanGripArmorSubclasses = 0;
294296 m_titanGripPenaltySpellId = 0;
295297 m_ammoDPS = 0.0f;
296298
@@ -9382,15 +9384,10 @@ void Player::SetSheath(SheathState sheathed)
93829384 Unit::SetSheath(sheathed); // this must visualize Sheath changing for other players...
93839385}
93849386
9385- uint8 Player::FindEquipSlot(ItemTemplate const* proto , uint32 slot, bool swap) const
9387+ uint8 Player::FindEquipSlot(Item const* item , uint32 slot, bool swap) const
93869388{
9387- uint8 playerClass = GetClass();
9388-
9389- uint8 slots[4];
9390- slots[0] = NULL_SLOT;
9391- slots[1] = NULL_SLOT;
9392- slots[2] = NULL_SLOT;
9393- slots[3] = NULL_SLOT;
9389+ std::array<uint8, 4> slots = { NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT };
9390+ ItemTemplate const* proto = item->GetTemplate();
93949391 switch (proto->InventoryType)
93959392 {
93969393 case INVTYPE_HEAD:
@@ -9455,27 +9452,7 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c
94559452 break;
94569453 case INVTYPE_2HWEAPON:
94579454 slots[0] = EQUIPMENT_SLOT_MAINHAND;
9458- if (Item* mhWeapon = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
9459- {
9460- if (ItemTemplate const* mhWeaponProto = mhWeapon->GetTemplate())
9461- {
9462- if (mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF)
9463- {
9464- const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true);
9465- break;
9466- }
9467- }
9468- }
9469-
9470- if (GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
9471- {
9472- if (proto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || proto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF)
9473- {
9474- const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true);
9475- break;
9476- }
9477- }
9478- if (CanDualWield() && CanTitanGrip() && proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF)
9455+ if (CanDualWield() && CanTitanGrip(item))
94799456 slots[1] = EQUIPMENT_SLOT_OFFHAND;
94809457 break;
94819458 case INVTYPE_TABARD:
@@ -9497,13 +9474,11 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c
94979474 slots[0] = EQUIPMENT_SLOT_RANGED;
94989475 break;
94999476 case INVTYPE_BAG:
9500- slots[0] = INVENTORY_SLOT_BAG_START + 0;
9501- slots[1] = INVENTORY_SLOT_BAG_START + 1;
9502- slots[2] = INVENTORY_SLOT_BAG_START + 2;
9503- slots[3] = INVENTORY_SLOT_BAG_START + 3;
9477+ slots = { INVENTORY_SLOT_BAG_START + 0, INVENTORY_SLOT_BAG_START + 1, INVENTORY_SLOT_BAG_START + 2, INVENTORY_SLOT_BAG_START + 3 };
95049478 break;
95059479 case INVTYPE_RELIC:
95069480 {
9481+ uint8 playerClass = GetClass();
95079482 switch (proto->SubClass)
95089483 {
95099484 case ITEM_SUBCLASS_ARMOR_LIBRAM:
@@ -11216,7 +11191,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1121611191 if (ssd && ssd->Maxlevel < DEFAULT_MAX_LEVEL && ssd->Maxlevel < GetLevel())
1121711192 return EQUIP_ERR_NOT_EQUIPPABLE;
1121811193
11219- uint8 eslot = FindEquipSlot(pProto , slot, swap);
11194+ uint8 eslot = FindEquipSlot(pItem , slot, swap);
1122011195 if (eslot == NULL_SLOT)
1122111196 return EQUIP_ERR_NOT_EQUIPPABLE;
1122211197
@@ -11286,7 +11261,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1128611261 }
1128711262 else if (type == INVTYPE_2HWEAPON)
1128811263 {
11289- if (!CanDualWield() || !CanTitanGrip())
11264+ if (!CanDualWield() || !CanTitanGrip(pItem ))
1129011265 return EQUIP_ERR_2HSKILLNOTFOUND;
1129111266 }
1129211267
@@ -11295,17 +11270,9 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1129511270 }
1129611271
1129711272 // equip two-hand weapon case (with possible unequip 2 items)
11298- if (type == INVTYPE_2HWEAPON )
11273+ if (eslot == EQUIPMENT_SLOT_MAINHAND )
1129911274 {
11300- if (eslot == EQUIPMENT_SLOT_OFFHAND)
11301- {
11302- if (!CanTitanGrip())
11303- return EQUIP_ERR_NOT_EQUIPPABLE;
11304- }
11305- else if (eslot != EQUIPMENT_SLOT_MAINHAND)
11306- return EQUIP_ERR_NOT_EQUIPPABLE;
11307-
11308- if (!CanTitanGrip())
11275+ if (!CanTitanGrip(pItem))
1130911276 {
1131011277 // offhand item must can be stored in inventory for offhand item and it also must be unequipped
1131111278 Item* offItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
@@ -13321,18 +13288,58 @@ bool Player::IsUseEquipedWeapon(bool mainhand) const
1332113288 return !IsInFeralForm() && (!mainhand || !HasUnitFlag(UNIT_FLAG_DISARMED));
1332213289}
1332313290
13324- void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/)
13291+ bool Player::CanTitanGrip(Item const* item) const
1332513292{
13326- if (value == m_canTitanGrip)
13327- return;
13293+ if (!m_canTitanGrip)
13294+ return false;
13295+
13296+ ItemTemplate const* itemTemplate = item->GetTemplate();
13297+
13298+ uint32 subClassMask = [&]
13299+ {
13300+ switch (itemTemplate->Class)
13301+ {
13302+ case ITEM_CLASS_WEAPON:
13303+ return m_titanGripWeaponSubclasses;
13304+ case ITEM_CLASS_ARMOR:
13305+ return m_titanGripArmorSubclasses;
13306+ default:
13307+ break;
13308+ }
13309+ return 0u;
13310+ }();
1332813311
13312+ return !subClassMask || subClassMask & (1 << itemTemplate->SubClass);
13313+ }
13314+
13315+ void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/, int32 allowedItemClass /*= 0*/, int32 allowedItemSubClassMask /*= 0*/)
13316+ {
1332913317 m_canTitanGrip = value;
13318+ if (value)
13319+ {
13320+ switch (allowedItemClass)
13321+ {
13322+ case ITEM_CLASS_WEAPON:
13323+ m_titanGripWeaponSubclasses = allowedItemSubClassMask;
13324+ break;
13325+ case ITEM_CLASS_ARMOR:
13326+ m_titanGripArmorSubclasses = allowedItemSubClassMask;
13327+ break;
13328+ default:
13329+ break;
13330+ }
13331+ }
13332+ else
13333+ {
13334+ m_titanGripWeaponSubclasses = 0;
13335+ m_titanGripArmorSubclasses = 0;
13336+ }
1333013337 m_titanGripPenaltySpellId = penaltySpellId;
1333113338}
1333213339
1333313340void Player::CheckTitanGripPenalty()
1333413341{
13335- if (!CanTitanGrip() )
13342+ if (!m_titanGripPenaltySpellId )
1333613343 return;
1333713344
1333813345 bool apply = IsUsingTwoHandedWeaponInOneHand();
@@ -13348,7 +13355,7 @@ void Player::CheckTitanGripPenalty()
1334813355bool Player::IsTwoHandUsed() const
1334913356{
1335013357 Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
13351- return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
13358+ return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(mainItem );
1335213359}
1335313360
1335413361bool Player::IsUsingTwoHandedWeaponInOneHand() const
@@ -23533,13 +23540,23 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
2353323540 if (!offItem)
2353423541 return;
2353523542
23536- // unequip offhand weapon if player doesn't have dual wield anymore
23537- if (!CanDualWield() && (offItem->GetTemplate()->InventoryType == INVTYPE_WEAPONOFFHAND || offItem->GetTemplate()->InventoryType == INVTYPE_WEAPON))
23538- force = true;
23543+ ItemTemplate const* offhandTemplate = offItem->GetTemplate();
23544+
23545+ // unequip offhand weapon if player doesn't have dual wield anymore
23546+ if (!CanDualWield() && (offhandTemplate->InventoryType == INVTYPE_WEAPONOFFHAND || offhandTemplate->InventoryType == INVTYPE_WEAPON))
23547+ force = true;
2353923548
2354023549 // need unequip offhand for 2h-weapon without TitanGrip (in any from hands)
23541- if (!force && (CanTitanGrip() || (offItem->GetTemplate()->InventoryType != INVTYPE_2HWEAPON && !IsTwoHandUsed())))
23542- return;
23550+ if (!force)
23551+ {
23552+ Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
23553+ if ((!mainItem || mainItem->GetTemplate()->InventoryType != INVTYPE_2HWEAPON)
23554+ && offhandTemplate->InventoryType != INVTYPE_2HWEAPON)
23555+ return;
23556+
23557+ if ((!mainItem || CanTitanGrip(mainItem)) && CanTitanGrip(offItem))
23558+ return;
23559+ }
2354323560
2354423561 ItemPosCountVec off_dest;
2354523562 if (CanStoreItem(NULL_BAG, NULL_SLOT, off_dest, offItem, false) == EQUIP_ERR_OK)
0 commit comments