@@ -279,6 +279,8 @@ Player::Player(WorldSession* session): Unit(true)
279279 m_canParry = false;
280280 m_canBlock = false;
281281 m_canTitanGrip = false;
282+ m_titanGripWeaponSubclasses = 0;
283+ m_titanGripArmorSubclasses = 0;
282284 m_titanGripPenaltySpellId = 0;
283285 m_ammoDPS = 0.0f;
284286
@@ -9380,15 +9382,10 @@ void Player::SetSheath(SheathState sheathed)
93809382 Unit::SetSheath(sheathed); // this must visualize Sheath changing for other players...
93819383}
93829384
9383- uint8 Player::FindEquipSlot(ItemTemplate const* proto , uint32 slot, bool swap) const
9385+ uint8 Player::FindEquipSlot(Item const* item , uint32 slot, bool swap) const
93849386{
9385- uint8 playerClass = GetClass();
9386-
9387- uint8 slots[4];
9388- slots[0] = NULL_SLOT;
9389- slots[1] = NULL_SLOT;
9390- slots[2] = NULL_SLOT;
9391- slots[3] = NULL_SLOT;
9387+ std::array<uint8, 4> slots = { NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT };
9388+ ItemTemplate const* proto = item->GetTemplate();
93929389 switch (proto->InventoryType)
93939390 {
93949391 case INVTYPE_HEAD:
@@ -9453,27 +9450,7 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c
94539450 break;
94549451 case INVTYPE_2HWEAPON:
94559452 slots[0] = EQUIPMENT_SLOT_MAINHAND;
9456- if (Item* mhWeapon = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
9457- {
9458- if (ItemTemplate const* mhWeaponProto = mhWeapon->GetTemplate())
9459- {
9460- if (mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF)
9461- {
9462- const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true);
9463- break;
9464- }
9465- }
9466- }
9467-
9468- if (GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
9469- {
9470- if (proto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || proto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF)
9471- {
9472- const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true);
9473- break;
9474- }
9475- }
9476- if (CanDualWield() && CanTitanGrip() && proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF)
9453+ if (CanDualWield() && CanTitanGrip(item))
94779454 slots[1] = EQUIPMENT_SLOT_OFFHAND;
94789455 break;
94799456 case INVTYPE_TABARD:
@@ -9495,13 +9472,11 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c
94959472 slots[0] = EQUIPMENT_SLOT_RANGED;
94969473 break;
94979474 case INVTYPE_BAG:
9498- slots[0] = INVENTORY_SLOT_BAG_START + 0;
9499- slots[1] = INVENTORY_SLOT_BAG_START + 1;
9500- slots[2] = INVENTORY_SLOT_BAG_START + 2;
9501- slots[3] = INVENTORY_SLOT_BAG_START + 3;
9475+ slots = { INVENTORY_SLOT_BAG_START + 0, INVENTORY_SLOT_BAG_START + 1, INVENTORY_SLOT_BAG_START + 2, INVENTORY_SLOT_BAG_START + 3 };
95029476 break;
95039477 case INVTYPE_RELIC:
95049478 {
9479+ uint8 playerClass = GetClass();
95059480 switch (proto->SubClass)
95069481 {
95079482 case ITEM_SUBCLASS_ARMOR_LIBRAM:
@@ -11214,7 +11189,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1121411189 if (ssd && ssd->Maxlevel < DEFAULT_MAX_LEVEL && ssd->Maxlevel < GetLevel())
1121511190 return EQUIP_ERR_NOT_EQUIPPABLE;
1121611191
11217- uint8 eslot = FindEquipSlot(pProto , slot, swap);
11192+ uint8 eslot = FindEquipSlot(pItem , slot, swap);
1121811193 if (eslot == NULL_SLOT)
1121911194 return EQUIP_ERR_NOT_EQUIPPABLE;
1122011195
@@ -11284,7 +11259,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1128411259 }
1128511260 else if (type == INVTYPE_2HWEAPON)
1128611261 {
11287- if (!CanDualWield() || !CanTitanGrip())
11262+ if (!CanDualWield() || !CanTitanGrip(pItem ))
1128811263 return EQUIP_ERR_2HSKILLNOTFOUND;
1128911264 }
1129011265
@@ -11293,17 +11268,9 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1129311268 }
1129411269
1129511270 // equip two-hand weapon case (with possible unequip 2 items)
11296- if (type == INVTYPE_2HWEAPON )
11271+ if (eslot == EQUIPMENT_SLOT_MAINHAND )
1129711272 {
11298- if (eslot == EQUIPMENT_SLOT_OFFHAND)
11299- {
11300- if (!CanTitanGrip())
11301- return EQUIP_ERR_NOT_EQUIPPABLE;
11302- }
11303- else if (eslot != EQUIPMENT_SLOT_MAINHAND)
11304- return EQUIP_ERR_NOT_EQUIPPABLE;
11305-
11306- if (!CanTitanGrip())
11273+ if (!CanTitanGrip(pItem))
1130711274 {
1130811275 // offhand item must can be stored in inventory for offhand item and it also must be unequipped
1130911276 Item* offItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
@@ -13319,18 +13286,58 @@ bool Player::IsUseEquipedWeapon(bool mainhand) const
1331913286 return !IsInFeralForm() && (!mainhand || !HasUnitFlag(UNIT_FLAG_DISARMED));
1332013287}
1332113288
13322- void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/)
13289+ bool Player::CanTitanGrip(Item const* item) const
1332313290{
13324- if (value == m_canTitanGrip)
13325- return;
13291+ if (!m_canTitanGrip)
13292+ return false;
13293+
13294+ ItemTemplate const* itemTemplate = item->GetTemplate();
13295+
13296+ uint32 subClassMask = [&]
13297+ {
13298+ switch (itemTemplate->Class)
13299+ {
13300+ case ITEM_CLASS_WEAPON:
13301+ return m_titanGripWeaponSubclasses;
13302+ case ITEM_CLASS_ARMOR:
13303+ return m_titanGripArmorSubclasses;
13304+ default:
13305+ break;
13306+ }
13307+ return 0u;
13308+ }();
1332613309
13310+ return !subClassMask || subClassMask & (1 << itemTemplate->SubClass);
13311+ }
13312+
13313+ void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/, int32 allowedItemClass /*= 0*/, int32 allowedItemSubClassMask /*= 0*/)
13314+ {
1332713315 m_canTitanGrip = value;
13316+ if (value)
13317+ {
13318+ switch (allowedItemClass)
13319+ {
13320+ case ITEM_CLASS_WEAPON:
13321+ m_titanGripWeaponSubclasses = allowedItemSubClassMask;
13322+ break;
13323+ case ITEM_CLASS_ARMOR:
13324+ m_titanGripArmorSubclasses = allowedItemSubClassMask;
13325+ break;
13326+ default:
13327+ break;
13328+ }
13329+ }
13330+ else
13331+ {
13332+ m_titanGripWeaponSubclasses = 0;
13333+ m_titanGripArmorSubclasses = 0;
13334+ }
1332813335 m_titanGripPenaltySpellId = penaltySpellId;
1332913336}
1333013337
1333113338void Player::CheckTitanGripPenalty()
1333213339{
13333- if (!CanTitanGrip() )
13340+ if (!m_titanGripPenaltySpellId )
1333413341 return;
1333513342
1333613343 bool apply = IsUsingTwoHandedWeaponInOneHand();
@@ -13346,7 +13353,7 @@ void Player::CheckTitanGripPenalty()
1334613353bool Player::IsTwoHandUsed() const
1334713354{
1334813355 Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
13349- return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
13356+ return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(mainItem );
1335013357}
1335113358
1335213359bool Player::IsUsingTwoHandedWeaponInOneHand() const
@@ -23531,13 +23538,23 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
2353123538 if (!offItem)
2353223539 return;
2353323540
23534- // unequip offhand weapon if player doesn't have dual wield anymore
23535- if (!CanDualWield() && (offItem->GetTemplate()->InventoryType == INVTYPE_WEAPONOFFHAND || offItem->GetTemplate()->InventoryType == INVTYPE_WEAPON))
23536- force = true;
23541+ ItemTemplate const* offhandTemplate = offItem->GetTemplate();
23542+
23543+ // unequip offhand weapon if player doesn't have dual wield anymore
23544+ if (!CanDualWield() && (offhandTemplate->InventoryType == INVTYPE_WEAPONOFFHAND || offhandTemplate->InventoryType == INVTYPE_WEAPON))
23545+ force = true;
2353723546
2353823547 // need unequip offhand for 2h-weapon without TitanGrip (in any from hands)
23539- if (!force && (CanTitanGrip() || (offItem->GetTemplate()->InventoryType != INVTYPE_2HWEAPON && !IsTwoHandUsed())))
23540- return;
23548+ if (!force)
23549+ {
23550+ Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
23551+ if ((!mainItem || mainItem->GetTemplate()->InventoryType != INVTYPE_2HWEAPON)
23552+ && offhandTemplate->InventoryType != INVTYPE_2HWEAPON)
23553+ return;
23554+
23555+ if ((!mainItem || CanTitanGrip(mainItem)) && CanTitanGrip(offItem))
23556+ return;
23557+ }
2354123558
2354223559 ItemPosCountVec off_dest;
2354323560 if (CanStoreItem(NULL_BAG, NULL_SLOT, off_dest, offItem, false) == EQUIP_ERR_OK)
0 commit comments