/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "AzeriteEmpoweredItem.h" #include "DatabaseEnv.h" #include "DB2Stores.h" #include "Player.h" #include "UpdateData.h" AzeriteEmpoweredItem::AzeriteEmpoweredItem() { m_objectTypeId = TYPEID_AZERITE_EMPOWERED_ITEM; m_entityFragments.Add(WowCS::EntityFragment::Tag_AzeriteEmpoweredItem, false); m_azeritePowers = nullptr; m_maxTier = 0; } bool AzeriteEmpoweredItem::Create(ObjectGuid::LowType guidlow, uint32 itemId, ItemContext context, Player const* owner) { if (!Item::Create(guidlow, itemId, context, owner)) return false; InitAzeritePowerData(); return true; } void AzeriteEmpoweredItem::SaveToDB(CharacterDatabaseTransaction trans) { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED); stmt->setUInt64(0, GetGUID().GetCounter()); trans->Append(stmt); switch (GetState()) { case ITEM_NEW: case ITEM_CHANGED: { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_INSTANCE_AZERITE_EMPOWERED); stmt->setUInt64(0, GetGUID().GetCounter()); for (uint32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i) stmt->setInt32(1 + i, m_azeriteEmpoweredItemData->Selections[i]); trans->Append(stmt); break; } case ITEM_REMOVED: default: break; } Item::SaveToDB(trans); } void AzeriteEmpoweredItem::LoadAzeriteEmpoweredItemData(Player const* owner, AzeriteEmpoweredItemData& azeriteEmpoweredItem) { InitAzeritePowerData(); bool needSave = false; if (m_azeritePowers) { for (int32 i = MAX_AZERITE_EMPOWERED_TIER; --i >= 0; ) { int32 selection = azeriteEmpoweredItem.SelectedAzeritePowers[i]; if (GetTierForAzeritePower(Classes(owner->GetClass()), selection) != i) { needSave = true; break; } SetSelectedAzeritePower(i, selection); } } else needSave = true; if (needSave) { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_INSTANCE_AZERITE_EMPOWERED); for (uint32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i) stmt->setInt32(i, m_azeriteEmpoweredItemData->Selections[i]); stmt->setUInt64(5, GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } } void AzeriteEmpoweredItem::DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid) { CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE_AZERITE_EMPOWERED); stmt->setUInt64(0, itemGuid); CharacterDatabase.ExecuteOrAppend(trans, stmt); } void AzeriteEmpoweredItem::DeleteFromDB(CharacterDatabaseTransaction trans) { AzeriteEmpoweredItem::DeleteFromDB(trans, GetGUID().GetCounter()); Item::DeleteFromDB(trans); } uint32 AzeriteEmpoweredItem::GetRequiredAzeriteLevelForTier(uint32 tier) const { return sDB2Manager.GetRequiredAzeriteLevelForAzeritePowerTier(_bonusData.AzeriteTierUnlockSetId, GetContext(), tier); } int32 AzeriteEmpoweredItem::GetTierForAzeritePower(Classes playerClass, int32 azeritePowerId) const { auto azeritePowerItr = std::find_if(m_azeritePowers->begin(), m_azeritePowers->end(), [&](AzeritePowerSetMemberEntry const* power) { return power->AzeritePowerID == azeritePowerId && power->Class == playerClass; }); if (azeritePowerItr != m_azeritePowers->end()) return (*azeritePowerItr)->Tier; return MAX_AZERITE_EMPOWERED_TIER; } void AzeriteEmpoweredItem::SetSelectedAzeritePower(int32 tier, int32 azeritePowerId) { SetUpdateFieldValue(m_values.ModifyValue(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData).ModifyValue(&UF::AzeriteEmpoweredItemData::Selections, uint32(tier)), azeritePowerId); // Not added to UF::ItemData::BonusListIDs, client fakes it on its own too _bonusData.AddBonusList(sAzeritePowerStore.AssertEntry(azeritePowerId)->ItemBonusListID); } void AzeriteEmpoweredItem::ClearSelectedAzeritePowers() { for (uint32 i = 0; i < MAX_AZERITE_EMPOWERED_TIER; ++i) SetUpdateFieldValue(m_values.ModifyValue(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData).ModifyValue(&UF::AzeriteEmpoweredItemData::Selections, i), 0); _bonusData.Initialize(GetTemplate()); for (int32 bonusListID : GetBonusListIDs()) _bonusData.AddBonusList(bonusListID); } int64 AzeriteEmpoweredItem::GetRespecCost() const { if (Player const* owner = GetOwner()) return int64(float(GOLD) * sDB2Manager.GetCurveValueAt(CURVE_ID_AZERITE_EMPOWERED_ITEM_RESPEC_COST, float(owner->GetNumRespecs()))); return MAX_MONEY_AMOUNT + 1; } void AzeriteEmpoweredItem::BuildValuesCreate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const { m_objectData->WriteCreate(*data, flags, this, target); m_itemData->WriteCreate(*data, flags, this, target); m_azeriteEmpoweredItemData->WriteCreate(*data, flags, this, target); } void AzeriteEmpoweredItem::BuildValuesUpdate(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const { *data << uint32(m_values.GetChangedObjectTypeMask()); if (m_values.HasChanged(TYPEID_OBJECT)) m_objectData->WriteUpdate(*data, flags, this, target); if (m_values.HasChanged(TYPEID_ITEM)) m_itemData->WriteUpdate(*data, flags, this, target); if (m_values.HasChanged(TYPEID_AZERITE_EMPOWERED_ITEM)) m_azeriteEmpoweredItemData->WriteUpdate(*data, flags, this, target); } void AzeriteEmpoweredItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask, UF::AzeriteEmpoweredItemData::Mask const& requestedAzeriteEmpoweredItemMask, Player const* target) const { UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); UpdateMask valuesMask; if (requestedObjectMask.IsAnySet()) valuesMask.Set(TYPEID_OBJECT); UF::ItemData::Mask itemMask = requestedItemMask; m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags); if (itemMask.IsAnySet()) valuesMask.Set(TYPEID_ITEM); if (requestedAzeriteEmpoweredItemMask.IsAnySet()) valuesMask.Set(TYPEID_AZERITE_EMPOWERED_ITEM); ByteBuffer& buffer = PrepareValuesUpdateBuffer(data); std::size_t sizePos = buffer.wpos(); buffer << uint32(0); BuildEntityFragmentsForValuesUpdateForPlayerWithMask(&buffer, flags); buffer << uint32(valuesMask.GetBlock(0)); if (valuesMask[TYPEID_OBJECT]) m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); if (valuesMask[TYPEID_ITEM]) m_itemData->WriteUpdate(buffer, itemMask, true, this, target); if (valuesMask[TYPEID_AZERITE_EMPOWERED_ITEM]) m_azeriteEmpoweredItemData->WriteUpdate(buffer, requestedAzeriteEmpoweredItemMask, true, this, target); buffer.put(sizePos, buffer.wpos() - sizePos - 4); data->AddUpdateBlock(); } void AzeriteEmpoweredItem::ValuesUpdateForPlayerWithMaskSender::operator()(Player const* player) const { UpdateData udata(player->GetMapId()); WorldPacket packet; Owner->BuildValuesUpdateForPlayerWithMask(&udata, ObjectMask.GetChangesMask(), ItemMask.GetChangesMask(), AzeriteEmpoweredItemMask.GetChangesMask(), player); udata.BuildPacket(&packet); player->SendDirectMessage(&packet); } void AzeriteEmpoweredItem::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData); Item::ClearUpdateMask(remove); } void AzeriteEmpoweredItem::InitAzeritePowerData() { m_azeritePowers = sDB2Manager.GetAzeritePowers(GetEntry()); if (m_azeritePowers) m_maxTier = (*std::ranges::max_element(*m_azeritePowers, {}, &AzeritePowerSetMemberEntry::Tier))->Tier; }