From 3ff8840fe2ccee9318c8e224e4ae81d8a5a03217 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 9 Jan 2022 18:15:38 +0100 Subject: [PATCH] Core/Items: ported several enchantment flag implementations from master branch --- src/server/game/DataStores/DBCEnums.h | 12 +++--- src/server/game/DataStores/DBCStructure.h | 2 + src/server/game/Entities/Item/Item.cpp | 12 +++--- src/server/game/Entities/Player/Player.cpp | 13 ++++++- src/server/game/Spells/Spell.cpp | 8 ++-- src/server/game/Spells/SpellMgr.cpp | 45 ++-------------------- src/server/game/Spells/SpellMgr.h | 3 -- src/server/game/World/World.cpp | 3 -- 8 files changed, 35 insertions(+), 63 deletions(-) diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index c9f80d2dc5..f2d9422542 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -515,14 +515,16 @@ DEFINE_ENUM_FLAG(SpellCategoryFlags); #define MAX_EFFECT_MASK 7 #define MAX_SPELL_REAGENTS 8 -enum EnchantmentSlotMask +enum class SpellItemEnchantmentFlags : uint32 { - ENCHANTMENT_CAN_SOULBOUND = 0x01, - ENCHANTMENT_UNK1 = 0x02, - ENCHANTMENT_UNK2 = 0x04, - ENCHANTMENT_UNK3 = 0x08 + Soulbound = 0x001, + DoNotLog = 0x002, + MainhandOnly = 0x004, + AllowEnteringArena = 0x008 }; +DEFINE_ENUM_FLAG(SpellItemEnchantmentFlags); + #define MAX_TALENT_RANK 5 #define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK #define MAX_TALENT_TABS 3 diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 054ac79e2b..a1f718554d 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -2337,6 +2337,8 @@ struct SpellItemEnchantmentEntry uint32 RequiredSkillRank; // 20 uint32 MinLevel; // 21 //uint32 ItemLevel; // 22 + + EnumFlag GetFlags() const { return static_cast(Flags); } }; struct SpellItemEnchantmentConditionEntry diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index be5df747aa..9d4593cb18 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -748,7 +748,7 @@ bool Item::IsBoundByEnchant() const if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot))) if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id)) - if (enchantEntry->Flags & ENCHANTMENT_CAN_SOULBOUND) + if (enchantEntry->GetFlags().HasFlag(SpellItemEnchantmentFlags::Soulbound)) return true; } @@ -817,11 +817,13 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint Player* owner = GetOwner(); if (slot < MAX_INSPECTED_ENCHANTMENT_SLOT) { - if (uint32 oldEnchant = GetEnchantmentId(slot)) - owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), ObjectGuid::Empty, GetEntry(), oldEnchant); + if (SpellItemEnchantmentEntry const* oldEnchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(slot))) + if (!oldEnchant->GetFlags().HasFlag(SpellItemEnchantmentFlags::DoNotLog)) + owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), ObjectGuid::Empty, GetEntry(), oldEnchant->ID); - if (id) - owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), caster, GetEntry(), id); + if (SpellItemEnchantmentEntry const* newEnchant = sSpellItemEnchantmentStore.LookupEntry(id)) + if (!newEnchant->GetFlags().HasFlag(SpellItemEnchantmentFlags::DoNotLog)) + owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), caster, GetEntry(), id); } SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET, id); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0975fcc162..164c1f0bfa 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -11848,6 +11848,15 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update) SetVisibleItemSlot(slot, nullptr); if (slot == EQUIPMENT_SLOT_MAINHAND || slot == EQUIPMENT_SLOT_OFFHAND) CheckTitanGripPenalty(); + + if (slot == EQUIPMENT_SLOT_MAINHAND) + { + // clear main hand only enchantments + for (uint32 enchantSlot = 0; enchantSlot < MAX_ENCHANTMENT_SLOT; ++enchantSlot) + if (SpellItemEnchantmentEntry const* enchantment = sSpellItemEnchantmentStore.LookupEntry(pItem->GetEnchantmentId(EnchantmentSlot(enchantSlot)))) + if (enchantment->GetFlags().HasFlag(SpellItemEnchantmentFlags::MainhandOnly)) + pItem->ClearEnchantment(EnchantmentSlot(enchantSlot)); + } } } else if (Bag* pBag = GetBagByPos(bag)) @@ -13117,7 +13126,7 @@ void Player::RemoveArenaEnchantments(EnchantmentSlot slot) // in inventory for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) - if (pItem->GetEnchantmentId(slot)) + if (!sSpellMgr->IsArenaAllowedEnchancment(pItem->GetEnchantmentId(slot))) pItem->ClearEnchantment(slot); // in inventory bags @@ -13125,7 +13134,7 @@ void Player::RemoveArenaEnchantments(EnchantmentSlot slot) if (Bag* pBag = GetBagByPos(i)) for (uint32 j = 0; j < pBag->GetBagSize(); j++) if (Item* pItem = pBag->GetItemByPos(j)) - if (pItem->GetEnchantmentId(slot)) + if (!sSpellMgr->IsArenaAllowedEnchancment(pItem->GetEnchantmentId(slot))) pItem->ClearEnchantment(slot); } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 3235a3418f..2eedc59104 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7124,7 +7124,7 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 / { if (!enchantEntry) return SPELL_FAILED_ERROR; - if (enchantEntry->Flags & ENCHANTMENT_CAN_SOULBOUND) + if (enchantEntry->GetFlags().HasFlag(SpellItemEnchantmentFlags::Soulbound)) return SPELL_FAILED_NOT_TRADEABLE; } break; @@ -7138,10 +7138,10 @@ SpellCastResult Spell::CheckItems(uint32* param1 /*= nullptr*/, uint32* param2 / if (item->GetOwner() != m_caster) { uint32 enchant_id = m_spellInfo->Effects[i].MiscValue; - SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!pEnchant) + SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id); + if (!enchantEntry) return SPELL_FAILED_ERROR; - if (pEnchant->Flags & ENCHANTMENT_CAN_SOULBOUND) + if (enchantEntry->GetFlags().HasFlag(SpellItemEnchantmentFlags::Soulbound)) return SPELL_FAILED_NOT_TRADEABLE; } diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index c560320be0..f50c58379a 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -637,7 +637,10 @@ SpellEnchantProcEntry const* SpellMgr::GetSpellEnchantProcEvent(uint32 enchId) c bool SpellMgr::IsArenaAllowedEnchancment(uint32 ench_id) const { - return mEnchantCustomAttr[ench_id]; + if (SpellItemEnchantmentEntry const* enchantment = sSpellItemEnchantmentStore.LookupEntry(ench_id)) + return enchantment->GetFlags().HasFlag(SpellItemEnchantmentFlags::AllowEnteringArena); + + return false; } const std::vector* SpellMgr::GetSpellLinked(int32 spell_id) const @@ -2098,46 +2101,6 @@ void SpellMgr::LoadSpellPetAuras() TC_LOG_INFO("server.loading", ">> Loaded %u spell pet auras in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -// Fill custom data about enchancments -void SpellMgr::LoadEnchantCustomAttr() -{ - uint32 oldMSTime = getMSTime(); - - uint32 size = sSpellItemEnchantmentStore.GetNumRows(); - mEnchantCustomAttr.resize(size); - - for (uint32 i = 0; i < size; ++i) - mEnchantCustomAttr[i] = 0; - - uint32 count = 0; - for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i) - { - SpellInfo const* spellInfo = GetSpellInfo(i); - if (!spellInfo) - continue; - - /// @todo find a better check - if (!spellInfo->HasAttribute(SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT)) - continue; - - for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) - { - if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) - { - uint32 enchId = spellInfo->Effects[j].MiscValue; - SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId); - if (!ench) - continue; - mEnchantCustomAttr[enchId] = true; - ++count; - break; - } - } - } - - TC_LOG_INFO("server.loading", ">> Loaded %u custom enchant attributes in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - void SpellMgr::LoadSpellEnchantProcData() { uint32 oldMSTime = getMSTime(); diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 8f6dfdc79e..d5104d23db 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -557,7 +557,6 @@ struct PetDefaultSpellsEntry typedef std::map PetDefaultSpellsMap; typedef std::vector SpellCustomAttribute; -typedef std::vector EnchantCustomAttribute; typedef std::vector SpellInfoMap; @@ -698,7 +697,6 @@ class TC_GAME_API SpellMgr void LoadSpellThreats(); void LoadSkillLineAbilityMap(); void LoadSpellPetAuras(); - void LoadEnchantCustomAttr(); void LoadSpellEnchantProcData(); void LoadSpellLinked(); void LoadPetLevelupSpellMap(); @@ -732,7 +730,6 @@ class TC_GAME_API SpellMgr SpellPetAuraMap mSpellPetAuraMap; SpellLinkedMap mSpellLinkedMap; SpellEnchantProcEventMap mSpellEnchantProcEventMap; - EnchantCustomAttribute mEnchantCustomAttr; SpellAreaMap mSpellAreaMap; SpellAreaForQuestMap mSpellAreaForQuestMap; SpellAreaForQuestMap mSpellAreaForQuestEndMap; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 8d5fcaab4f..5203d77e3f 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1997,9 +1997,6 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Spell target coordinates..."); sSpellMgr->LoadSpellTargetPositions(); - TC_LOG_INFO("server.loading", "Loading enchant custom attributes..."); - sSpellMgr->LoadEnchantCustomAttr(); - TC_LOG_INFO("server.loading", "Loading linked spells..."); sSpellMgr->LoadSpellLinked();