diff options
Diffstat (limited to 'src/server/game')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 121 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 8 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 2 |
3 files changed, 72 insertions, 59 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ff4f91cc297..739d19806bd 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -279,6 +279,8 @@ Player::Player(WorldSession* session): Unit(true) m_canParry = false; m_canBlock = false; m_canTitanGrip = false; + m_titanGripWeaponSubclasses = 0; + m_titanGripArmorSubclasses = 0; m_titanGripPenaltySpellId = 0; m_ammoDPS = 0.0f; @@ -9370,15 +9372,10 @@ void Player::SetSheath(SheathState sheathed) Unit::SetSheath(sheathed); // this must visualize Sheath changing for other players... } -uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const +uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const { - uint8 playerClass = GetClass(); - - uint8 slots[4]; - slots[0] = NULL_SLOT; - slots[1] = NULL_SLOT; - slots[2] = NULL_SLOT; - slots[3] = NULL_SLOT; + std::array<uint8, 4> slots = { NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT }; + ItemTemplate const* proto = item->GetTemplate(); switch (proto->InventoryType) { case INVTYPE_HEAD: @@ -9443,27 +9440,7 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c break; case INVTYPE_2HWEAPON: slots[0] = EQUIPMENT_SLOT_MAINHAND; - if (Item* mhWeapon = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) - { - if (ItemTemplate const* mhWeaponProto = mhWeapon->GetTemplate()) - { - if (mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || mhWeaponProto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF) - { - const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true); - break; - } - } - } - - if (GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND)) - { - if (proto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM || proto->SubClass == ITEM_SUBCLASS_WEAPON_STAFF) - { - const_cast<Player*>(this)->AutoUnequipOffhandIfNeed(true); - break; - } - } - if (CanDualWield() && CanTitanGrip() && proto->SubClass != ITEM_SUBCLASS_WEAPON_POLEARM && proto->SubClass != ITEM_SUBCLASS_WEAPON_STAFF) + if (CanDualWield() && CanTitanGrip(item)) slots[1] = EQUIPMENT_SLOT_OFFHAND; break; case INVTYPE_TABARD: @@ -9485,13 +9462,11 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c 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; + slots = { INVENTORY_SLOT_BAG_START + 0, INVENTORY_SLOT_BAG_START + 1, INVENTORY_SLOT_BAG_START + 2, INVENTORY_SLOT_BAG_START + 3 }; break; case INVTYPE_RELIC: { + uint8 playerClass = GetClass(); switch (proto->SubClass) { case ITEM_SUBCLASS_ARMOR_LIBRAM: @@ -11204,7 +11179,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool if (ssd && ssd->Maxlevel < DEFAULT_MAX_LEVEL && ssd->Maxlevel < GetLevel()) return EQUIP_ERR_NOT_EQUIPPABLE; - uint8 eslot = FindEquipSlot(pProto, slot, swap); + uint8 eslot = FindEquipSlot(pItem, slot, swap); if (eslot == NULL_SLOT) return EQUIP_ERR_NOT_EQUIPPABLE; @@ -11274,7 +11249,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool } else if (type == INVTYPE_2HWEAPON) { - if (!CanDualWield() || !CanTitanGrip()) + if (!CanDualWield() || !CanTitanGrip(pItem)) return EQUIP_ERR_2HSKILLNOTFOUND; } @@ -11283,17 +11258,9 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool } // equip two-hand weapon case (with possible unequip 2 items) - if (type == INVTYPE_2HWEAPON) + if (eslot == EQUIPMENT_SLOT_MAINHAND) { - if (eslot == EQUIPMENT_SLOT_OFFHAND) - { - if (!CanTitanGrip()) - return EQUIP_ERR_NOT_EQUIPPABLE; - } - else if (eslot != EQUIPMENT_SLOT_MAINHAND) - return EQUIP_ERR_NOT_EQUIPPABLE; - - if (!CanTitanGrip()) + if (!CanTitanGrip(pItem)) { // offhand item must can be stored in inventory for offhand item and it also must be unequipped Item* offItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND); @@ -13309,18 +13276,58 @@ bool Player::IsUseEquipedWeapon(bool mainhand) const return !IsInFeralForm() && (!mainhand || !HasUnitFlag(UNIT_FLAG_DISARMED)); } -void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/) +bool Player::CanTitanGrip(Item const* item) const { - if (value == m_canTitanGrip) - return; + if (!m_canTitanGrip) + return false; + + ItemTemplate const* itemTemplate = item->GetTemplate(); + uint32 subClassMask = [&] + { + switch (itemTemplate->Class) + { + case ITEM_CLASS_WEAPON: + return m_titanGripWeaponSubclasses; + case ITEM_CLASS_ARMOR: + return m_titanGripArmorSubclasses; + default: + break; + } + return 0u; + }(); + + return !subClassMask || subClassMask & (1 << itemTemplate->SubClass); +} + +void Player::SetCanTitanGrip(bool value, uint32 penaltySpellId /*= 0*/, int32 allowedItemClass /*= 0*/, int32 allowedItemSubClassMask /*= 0*/) +{ m_canTitanGrip = value; + if (value) + { + switch (allowedItemClass) + { + case ITEM_CLASS_WEAPON: + m_titanGripWeaponSubclasses = allowedItemSubClassMask; + break; + case ITEM_CLASS_ARMOR: + m_titanGripArmorSubclasses = allowedItemSubClassMask; + break; + default: + break; + } + } + else + { + m_titanGripWeaponSubclasses = 0; + m_titanGripArmorSubclasses = 0; + } m_titanGripPenaltySpellId = penaltySpellId; } void Player::CheckTitanGripPenalty() { - if (!CanTitanGrip()) + if (!m_titanGripPenaltySpellId) return; bool apply = IsUsingTwoHandedWeaponInOneHand(); @@ -13336,7 +13343,7 @@ void Player::CheckTitanGripPenalty() bool Player::IsTwoHandUsed() const { Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); - return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(); + return mainItem && mainItem->GetTemplate()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(mainItem); } bool Player::IsUsingTwoHandedWeaponInOneHand() const @@ -23521,13 +23528,17 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/) if (!offItem) return; - // unequip offhand weapon if player doesn't have dual wield anymore - if (!CanDualWield() && (offItem->GetTemplate()->InventoryType == INVTYPE_WEAPONOFFHAND || offItem->GetTemplate()->InventoryType == INVTYPE_WEAPON)) - force = true; + // unequip offhand weapon if player doesn't have dual wield anymore + if (!CanDualWield() && (offItem->GetTemplate()->InventoryType == INVTYPE_WEAPONOFFHAND || offItem->GetTemplate()->InventoryType == INVTYPE_WEAPON)) + force = true; // need unequip offhand for 2h-weapon without TitanGrip (in any from hands) - if (!force && (CanTitanGrip() || (offItem->GetTemplate()->InventoryType != INVTYPE_2HWEAPON && !IsTwoHandUsed()))) - return; + if (!force && CanTitanGrip(offItem)) + { + Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); + if (!mainItem || CanTitanGrip(mainItem)) + return; + } ItemPosCountVec off_dest; if (CanStoreItem(NULL_BAG, NULL_SLOT, off_dest, offItem, false) == EQUIP_ERR_OK) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index fdb042894f8..29c98bb71d2 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1088,7 +1088,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetVirtualItemSlot(uint8 i, Item* item); void SetSheath(SheathState sheathed) override; // overwrite Unit version - uint8 FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const; + uint8 FindEquipSlot(Item const* item, uint32 slot, bool swap) const; uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = nullptr) const; uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = nullptr) const; Item* GetItemByGuid(ObjectGuid guid) const; @@ -1875,8 +1875,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetCanParry(bool value); bool CanBlock() const { return m_canBlock; } void SetCanBlock(bool value); - bool CanTitanGrip() const { return m_canTitanGrip; } - void SetCanTitanGrip(bool value, uint32 penaltySpellId = 0); + bool CanTitanGrip(Item const* item) const; + void SetCanTitanGrip(bool value, uint32 penaltySpellId = 0, int32 allowedItemClass = 0, int32 allowedItemSubClassMask = 0); void CheckTitanGripPenalty(); bool CanTameExoticPets() const { return IsGameMaster() || HasAuraType(SPELL_AURA_ALLOW_TAME_PET_TYPE); } @@ -2440,6 +2440,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool m_canParry; bool m_canBlock; bool m_canTitanGrip; + uint32 m_titanGripWeaponSubclasses; + uint32 m_titanGripArmorSubclasses; uint32 m_titanGripPenaltySpellId; uint8 m_swingErrorMsg; float m_ammoDPS; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 93bfda549b1..b878dbe45c1 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5162,7 +5162,7 @@ void Spell::EffectTitanGrip() return; if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->SetCanTitanGrip(true, effectInfo->MiscValue); + m_caster->ToPlayer()->SetCanTitanGrip(true, effectInfo->MiscValue, m_spellInfo->EquippedItemClass, m_spellInfo->EquippedItemSubClassMask); } void Spell::EffectRedirectThreat() |