Skip to content

Commit b610048

Browse files
committed
Core/Players: Fix Titan's Grip weapon type restrictions
Closes #20972 Closes #30747
1 parent 77d20d6 commit b610048

File tree

3 files changed

+72
-59
lines changed

3 files changed

+72
-59
lines changed

src/server/game/Entities/Player/Player.cpp

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1332113328
void Player::CheckTitanGripPenalty()
1332213329
{
13323-
if (!CanTitanGrip())
13330+
if (!m_titanGripPenaltySpellId)
1332413331
return;
1332513332

1332613333
bool apply = IsUsingTwoHandedWeaponInOneHand();
@@ -13336,7 +13343,7 @@ void Player::CheckTitanGripPenalty()
1333613343
bool 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

1334213349
bool 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)

src/server/game/Entities/Player/Player.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
10881088

10891089
void SetVirtualItemSlot(uint8 i, Item* item);
10901090
void SetSheath(SheathState sheathed) override; // overwrite Unit version
1091-
uint8 FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const;
1091+
uint8 FindEquipSlot(Item const* item, uint32 slot, bool swap) const;
10921092
uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = nullptr) const;
10931093
uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = nullptr) const;
10941094
Item* GetItemByGuid(ObjectGuid guid) const;
@@ -1875,8 +1875,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
18751875
void SetCanParry(bool value);
18761876
bool CanBlock() const { return m_canBlock; }
18771877
void SetCanBlock(bool value);
1878-
bool CanTitanGrip() const { return m_canTitanGrip; }
1879-
void SetCanTitanGrip(bool value, uint32 penaltySpellId = 0);
1878+
bool CanTitanGrip(Item const* item) const;
1879+
void SetCanTitanGrip(bool value, uint32 penaltySpellId = 0, int32 allowedItemClass = 0, int32 allowedItemSubClassMask = 0);
18801880
void CheckTitanGripPenalty();
18811881
bool CanTameExoticPets() const { return IsGameMaster() || HasAuraType(SPELL_AURA_ALLOW_TAME_PET_TYPE); }
18821882

@@ -2440,6 +2440,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
24402440
bool m_canParry;
24412441
bool m_canBlock;
24422442
bool m_canTitanGrip;
2443+
uint32 m_titanGripWeaponSubclasses;
2444+
uint32 m_titanGripArmorSubclasses;
24432445
uint32 m_titanGripPenaltySpellId;
24442446
uint8 m_swingErrorMsg;
24452447
float m_ammoDPS;

src/server/game/Spells/SpellEffects.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5162,7 +5162,7 @@ void Spell::EffectTitanGrip()
51625162
return;
51635163

51645164
if (m_caster->GetTypeId() == TYPEID_PLAYER)
5165-
m_caster->ToPlayer()->SetCanTitanGrip(true, effectInfo->MiscValue);
5165+
m_caster->ToPlayer()->SetCanTitanGrip(true, effectInfo->MiscValue, m_spellInfo->EquippedItemClass, m_spellInfo->EquippedItemSubClassMask);
51665166
}
51675167

51685168
void Spell::EffectRedirectThreat()

0 commit comments

Comments
 (0)