@@ -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
@@ -9370,15 +9372,10 @@ void Player::SetSheath(SheathState sheathed)
93709372 Unit::SetSheath(sheathed); // this must visualize Sheath changing for other players...
93719373}
93729374
9373- uint8 Player::FindEquipSlot(ItemTemplate const* proto , uint32 slot, bool swap) const
9375+ uint8 Player::FindEquipSlot(Item const* item , uint32 slot, bool swap) const
93749376{
9375- uint8 playerClass = GetClass();
9376-
9377- uint8 slots[4];
9378- slots[0] = NULL_SLOT;
9379- slots[1] = NULL_SLOT;
9380- slots[2] = NULL_SLOT;
9381- slots[3] = NULL_SLOT;
9377+ std::array<uint8, 4> slots = { NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT };
9378+ ItemTemplate const* proto = item->GetTemplate();
93829379 switch (proto->InventoryType)
93839380 {
93849381 case INVTYPE_HEAD:
@@ -9443,27 +9440,7 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c
94439440 break;
94449441 case INVTYPE_2HWEAPON:
94459442 slots[0] = EQUIPMENT_SLOT_MAINHAND;
9446- if (Item* mhWeapon = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
9447- {
9448- if (ItemTemplate const* mhWeaponProto = mhWeapon->GetTemplate())
9449- {
9450- if (mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF)
9451- {
9452- const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true);
9453- break;
9454- }
9455- }
9456- }
9457-
9458- if (GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
9459- {
9460- if (proto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || proto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF)
9461- {
9462- const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true);
9463- break;
9464- }
9465- }
9466- if (CanDualWield() && CanTitanGrip() && proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF)
9443+ if (CanDualWield() && CanTitanGrip(item))
94679444 slots[1] = EQUIPMENT_SLOT_OFFHAND;
94689445 break;
94699446 case INVTYPE_TABARD:
@@ -9485,13 +9462,11 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c
94859462 slots[0] = EQUIPMENT_SLOT_RANGED;
94869463 break;
94879464 case INVTYPE_BAG:
9488- slots[0] = INVENTORY_SLOT_BAG_START + 0;
9489- slots[1] = INVENTORY_SLOT_BAG_START + 1;
9490- slots[2] = INVENTORY_SLOT_BAG_START + 2;
9491- slots[3] = INVENTORY_SLOT_BAG_START + 3;
9465+ slots = { INVENTORY_SLOT_BAG_START + 0, INVENTORY_SLOT_BAG_START + 1, INVENTORY_SLOT_BAG_START + 2, INVENTORY_SLOT_BAG_START + 3 };
94929466 break;
94939467 case INVTYPE_RELIC:
94949468 {
9469+ uint8 playerClass = GetClass();
94959470 switch (proto->SubClass)
94969471 {
94979472 case ITEM_SUBCLASS_ARMOR_LIBRAM:
@@ -11204,7 +11179,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1120411179 if (ssd && ssd->Maxlevel < DEFAULT_MAX_LEVEL && ssd->Maxlevel < GetLevel())
1120511180 return EQUIP_ERR_NOT_EQUIPPABLE;
1120611181
11207- uint8 eslot = FindEquipSlot(pProto , slot, swap);
11182+ uint8 eslot = FindEquipSlot(pItem , slot, swap);
1120811183 if (eslot == NULL_SLOT)
1120911184 return EQUIP_ERR_NOT_EQUIPPABLE;
1121011185
@@ -11274,7 +11249,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1127411249 }
1127511250 else if (type == INVTYPE_2HWEAPON)
1127611251 {
11277- if (!CanDualWield() || !CanTitanGrip())
11252+ if (!CanDualWield() || !CanTitanGrip(pItem ))
1127811253 return EQUIP_ERR_2HSKILLNOTFOUND;
1127911254 }
1128011255
@@ -11283,17 +11258,9 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
1128311258 }
1128411259
1128511260 // equip two-hand weapon case (with possible unequip 2 items)
11286- if (type == INVTYPE_2HWEAPON )
11261+ if (eslot == EQUIPMENT_SLOT_MAINHAND )
1128711262 {
11288- if (eslot == EQUIPMENT_SLOT_OFFHAND)
11289- {
11290- if (!CanTitanGrip())
11291- return EQUIP_ERR_NOT_EQUIPPABLE;
11292- }
11293- else if (eslot != EQUIPMENT_SLOT_MAINHAND)
11294- return EQUIP_ERR_NOT_EQUIPPABLE;
11295-
11296- if (!CanTitanGrip())
11263+ if (!CanTitanGrip(pItem))
1129711264 {
1129811265 // offhand item must can be stored in inventory for offhand item and it also must be unequipped
1129911266 Item* offItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
@@ -13309,18 +13276,58 @@ bool Player::IsUseEquipedWeapon(bool mainhand) const
1330913276 return !IsInFeralForm() && (!mainhand || !HasUnitFlag(UNIT_FLAG_DISARMED));
1331013277}
1331113278
13312- void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/)
13279+ bool Player::CanTitanGrip(Item const* item) const
1331313280{
13314- if (value == m_canTitanGrip)
13315- return;
13281+ if (!m_canTitanGrip)
13282+ return false;
13283+
13284+ ItemTemplate const* itemTemplate = item->GetTemplate();
1331613285
13286+ uint32 subClassMask = [&]
13287+ {
13288+ switch (itemTemplate->Class)
13289+ {
13290+ case ITEM_CLASS_WEAPON:
13291+ return m_titanGripWeaponSubclasses;
13292+ case ITEM_CLASS_ARMOR:
13293+ return m_titanGripArmorSubclasses;
13294+ default:
13295+ break;
13296+ }
13297+ return 0u;
13298+ }();
13299+
13300+ return !subClassMask || subClassMask & (1 << itemTemplate->SubClass);
13301+ }
13302+
13303+ void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/, int32 allowedItemClass /*= 0*/, int32 allowedItemSubClassMask /*= 0*/)
13304+ {
1331713305 m_canTitanGrip = value;
13306+ if (value)
13307+ {
13308+ switch (allowedItemClass)
13309+ {
13310+ case ITEM_CLASS_WEAPON:
13311+ m_titanGripWeaponSubclasses = allowedItemSubClassMask;
13312+ break;
13313+ case ITEM_CLASS_ARMOR:
13314+ m_titanGripArmorSubclasses = allowedItemSubClassMask;
13315+ break;
13316+ default:
13317+ break;
13318+ }
13319+ }
13320+ else
13321+ {
13322+ m_titanGripWeaponSubclasses = 0;
13323+ m_titanGripArmorSubclasses = 0;
13324+ }
1331813325 m_titanGripPenaltySpellId = penaltySpellId;
1331913326}
1332013327
1332113328void Player::CheckTitanGripPenalty()
1332213329{
13323- if (!CanTitanGrip() )
13330+ if (!m_titanGripPenaltySpellId )
1332413331 return;
1332513332
1332613333 bool apply = IsUsingTwoHandedWeaponInOneHand();
@@ -13336,7 +13343,7 @@ void Player::CheckTitanGripPenalty()
1333613343bool Player::IsTwoHandUsed() const
1333713344{
1333813345 Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
13339- return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
13346+ return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(mainItem );
1334013347}
1334113348
1334213349bool Player::IsUsingTwoHandedWeaponInOneHand() const
@@ -23521,13 +23528,17 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
2352123528 if (!offItem)
2352223529 return;
2352323530
23524- // unequip offhand weapon if player doesn't have dual wield anymore
23525- if (!CanDualWield() && (offItem->GetTemplate()->InventoryType == INVTYPE_WEAPONOFFHAND || offItem->GetTemplate()->InventoryType == INVTYPE_WEAPON))
23526- force = true;
23531+ // unequip offhand weapon if player doesn't have dual wield anymore
23532+ if (!CanDualWield() && (offItem->GetTemplate()->InventoryType == INVTYPE_WEAPONOFFHAND || offItem->GetTemplate()->InventoryType == INVTYPE_WEAPON))
23533+ force = true;
2352723534
2352823535 // need unequip offhand for 2h-weapon without TitanGrip (in any from hands)
23529- if (!force && (CanTitanGrip() || (offItem->GetTemplate()->InventoryType != INVTYPE_2HWEAPON && !IsTwoHandUsed())))
23530- return;
23536+ if (!force && CanTitanGrip(offItem))
23537+ {
23538+ Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);
23539+ if (!mainItem || CanTitanGrip(mainItem))
23540+ return;
23541+ }
2353123542
2353223543 ItemPosCountVec off_dest;
2353323544 if (CanStoreItem(NULL_BAG, NULL_SLOT, off_dest, offItem, false) == EQUIP_ERR_OK)
0 commit comments