diff options
author | Shauren <shauren.trinity@gmail.com> | 2022-01-09 16:31:12 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-01-09 16:31:12 +0100 |
commit | 241193cd0287c3d7a2cbaf7f2c5775d414b4d0b3 (patch) | |
tree | 01b863fd5bf6bbfdc048293f4d7c181315f2ae11 /src | |
parent | 6df3cb0995d6bcb28998ca14fd39c9afe9d939b2 (diff) |
Core/Items: Implemented many new enchantment flags
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Item/Item.cpp | 26 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 16 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/TransmogrificationHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 41 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 4 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 3 |
10 files changed, 56 insertions, 68 deletions
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index 7b73f6a0d50..d1b7390ed83 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -3347,6 +3347,8 @@ struct SpellItemEnchantmentEntry uint8 ConditionID; uint8 MinLevel; uint8 MaxLevel; + + EnumFlag<SpellItemEnchantmentFlags> GetFlags() const { return static_cast<SpellItemEnchantmentFlags>(Flags); } }; struct SpellItemEnchantmentConditionEntry diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index a799e882e58..295eb89f451 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -1485,16 +1485,22 @@ DEFINE_ENUM_FLAG(SpellEffectAttributes); #define MAX_SPELL_AURA_INTERRUPT_FLAGS 2 -enum SpellItemEnchantmentFlags +enum class SpellItemEnchantmentFlags : uint16 { - ENCHANTMENT_CAN_SOULBOUND = 0x01, - ENCHANTMENT_UNK1 = 0x02, - ENCHANTMENT_UNK2 = 0x04, - ENCHANTMENT_UNK3 = 0x08, - ENCHANTMENT_COLLECTABLE = 0x100, - ENCHANTMENT_HIDE_IF_NOT_COLLECTED = 0x200, + Soulbound = 0x001, + DoNotLog = 0x002, + MainhandOnly = 0x004, + AllowEnteringArena = 0x008, + DoNotSaveToDB = 0x010, + ScaleAsAGem = 0x020, + DisableInChallengeModes = 0x040, + DisableInProvingGrounds = 0x080, + AllowTransmog = 0x100, + HideUntilCollected = 0x200, }; +DEFINE_ENUM_FLAG(SpellItemEnchantmentFlags); + enum SpellProcsPerMinuteModType { SPELL_PPM_MOD_HASTE = 1, diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 744dda953cc..5e3ef4a6588 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -580,9 +580,17 @@ void Item::SaveToDB(CharacterDatabaseTransaction& trans) std::ostringstream ssEnchants; for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i) { - ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << ' '; - ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << ' '; - ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << ' '; + if (SpellItemEnchantmentEntry const* enchantment = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(i))); + enchantment && !enchantment->GetFlags().HasFlag(SpellItemEnchantmentFlags::DoNotSaveToDB)) + { + ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << ' '; + ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << ' '; + ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << ' '; + } + else + { + ssEnchants << "0 0 0 "; + } } stmt->setString(++index, ssEnchants.str()); @@ -1303,7 +1311,7 @@ bool Item::IsBoundByEnchant() const for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) 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; return false; @@ -1369,11 +1377,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, GetGUID(), GetEntry(), oldEnchant, slot); + if (SpellItemEnchantmentEntry const* oldEnchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(slot))) + if (!oldEnchant->GetFlags().HasFlag(SpellItemEnchantmentFlags::DoNotLog)) + owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), ObjectGuid::Empty, GetGUID(), GetEntry(), oldEnchant->ID, slot); - if (id) - owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), caster, GetGUID(), GetEntry(), id, slot); + if (SpellItemEnchantmentEntry const* newEnchant = sSpellItemEnchantmentStore.LookupEntry(id)) + if (!newEnchant->GetFlags().HasFlag(SpellItemEnchantmentFlags::DoNotLog)) + owner->GetSession()->SendEnchantmentLog(GetOwnerGUID(), caster, GetGUID(), GetEntry(), id, slot); } ApplyArtifactPowerEnchantmentBonuses(slot, GetEnchantmentId(slot), false, owner); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 70ca1340b31..c2f677c250d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -12365,6 +12365,7 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) case EQUIPMENT_SLOT_MAINHAND: case EQUIPMENT_SLOT_OFFHAND: RecalculateRating(CR_ARMOR_PENETRATION); + break; default: break; } @@ -12621,9 +12622,17 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update) // remove item dependent auras and casts (only weapon and armor slots) if (slot < EQUIPMENT_SLOT_END) { - // remove held enchantments, update expertise + // update expertise 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)); + UpdateExpertise(BASE_ATTACK); + } else if (slot == EQUIPMENT_SLOT_OFFHAND) UpdateExpertise(OFF_ATTACK); // update armor penetration - passive auras may need it @@ -12632,6 +12641,7 @@ void Player::RemoveItem(uint8 bag, uint8 slot, bool update) case EQUIPMENT_SLOT_MAINHAND: case EQUIPMENT_SLOT_OFFHAND: RecalculateRating(CR_ARMOR_PENETRATION); + break; default: break; } @@ -14056,7 +14066,7 @@ void Player::RemoveArenaEnchantments(EnchantmentSlot slot) uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++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 @@ -14064,7 +14074,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/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 61cc65af1c3..57a98bf1338 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1926,7 +1926,7 @@ void WorldSession::HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipm if (!illusion) return false; - if (!illusion->ItemVisual || !(illusion->Flags & ENCHANTMENT_COLLECTABLE)) + if (!illusion->ItemVisual || !illusion->GetFlags().HasFlag(SpellItemEnchantmentFlags::AllowTransmog)) return false; if (PlayerConditionEntry const* condition = sPlayerConditionStore.LookupEntry(illusion->TransmogUseConditionID)) diff --git a/src/server/game/Handlers/TransmogrificationHandler.cpp b/src/server/game/Handlers/TransmogrificationHandler.cpp index 5c75c4670fa..1e59760df46 100644 --- a/src/server/game/Handlers/TransmogrificationHandler.cpp +++ b/src/server/game/Handlers/TransmogrificationHandler.cpp @@ -135,7 +135,7 @@ void WorldSession::HandleTransmogrifyItems(WorldPackets::Transmogrification::Tra return; } - if (!illusion->ItemVisual || !(illusion->Flags & ENCHANTMENT_COLLECTABLE)) + if (!illusion->ItemVisual || !illusion->GetFlags().HasFlag(SpellItemEnchantmentFlags::AllowTransmog)) { TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - %s, Name: %s tried to transmogrify illusion using not allowed enchant (%d).", player->GetGUID().ToString().c_str(), player->GetName().c_str(), transmogItem.SpellItemEnchantmentID); return; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 8a3c26bd7b2..ad8e6d3191f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -7087,7 +7087,7 @@ SpellCastResult Spell::CheckItems(int32* param1 /*= nullptr*/, int32* 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; @@ -7101,10 +7101,10 @@ SpellCastResult Spell::CheckItems(int32* param1 /*= nullptr*/, int32* param2 /*= if (item->GetOwner() != player) { uint32 enchant_id = spellEffectInfo.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 e3b2e9b00d4..5599e0cea39 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -634,7 +634,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; } std::vector<int32> const* SpellMgr::GetSpellLinked(int32 spell_id) const @@ -1988,42 +1991,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] = false; - - uint32 count = 0; - for (SpellInfo const& spellInfo : mSpellInfoMap) - { - /// @todo find a better check - if (!spellInfo.HasAttribute(SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !spellInfo.HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT)) - continue; - - for (SpellEffectInfo const& spellEffectInfo : spellInfo.GetEffects()) - { - if (spellEffectInfo.Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) - { - uint32 enchId = spellEffectInfo.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 ee5399ab202..00b93cb18fd 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -578,8 +578,6 @@ struct PetDefaultSpellsEntry // < 0 for petspelldata id, > 0 for creature_id typedef std::map<int32, PetDefaultSpellsEntry> PetDefaultSpellsMap; -typedef std::vector<bool> EnchantCustomAttribute; - typedef std::unordered_map<int32, std::vector<int32>> SpellLinkedMap; bool IsPrimaryProfessionSkill(uint32 skill); @@ -739,7 +737,6 @@ class TC_GAME_API SpellMgr void LoadSpellThreats(); void LoadSkillLineAbilityMap(); void LoadSpellPetAuras(); - void LoadEnchantCustomAttr(); void LoadSpellEnchantProcData(); void LoadSpellLinked(); void LoadPetLevelupSpellMap(); @@ -772,7 +769,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 52655e381ce..7848c80f0f1 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -2080,9 +2080,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(); |