TrinityCore
Loading...
Searching...
No Matches
ArtifactHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "WorldSession.h"
19#include "ArtifactPackets.h"
20#include "ConditionMgr.h"
21#include "DB2Stores.h"
22#include "GameTables.h"
23#include "Item.h"
24#include "Player.h"
25#include "SpellAuraEffects.h"
26#include "SpellInfo.h"
27#include "SpellPackets.h"
28
30{
32 return;
33
34 Item* artifact = _player->GetItemByGuid(artifactAddPower.ArtifactGUID);
35 if (!artifact || artifact->IsArtifactDisabled())
36 return;
37
38 uint32 currentArtifactTier = artifact->GetModifier(ITEM_MODIFIER_ARTIFACT_TIER);
39
40 uint64 xpCost = 0;
42 xpCost = uint64(currentArtifactTier == MAX_ARTIFACT_TIER ? cost->XP2 : cost->XP);
43
44 if (xpCost > artifact->m_itemData->ArtifactXP)
45 return;
46
47 if (artifactAddPower.PowerChoices.empty())
48 return;
49
50 UF::ArtifactPower const* artifactPower = artifact->GetArtifactPower(artifactAddPower.PowerChoices[0].ArtifactPowerID);
51 if (!artifactPower)
52 return;
53
54 ArtifactPowerEntry const* artifactPowerEntry = sArtifactPowerStore.LookupEntry(artifactPower->ArtifactPowerID);
55 if (!artifactPowerEntry)
56 return;
57
58 if (uint32(artifactPowerEntry->Tier) > currentArtifactTier)
59 return;
60
61 uint32 maxRank = artifactPowerEntry->MaxPurchasableRank;
62 if (uint32(artifactPowerEntry->Tier) < currentArtifactTier)
63 {
64 if (artifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_FINAL)
65 maxRank = 1;
66 else if (artifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_MAX_RANK_WITH_TIER)
67 maxRank += currentArtifactTier - artifactPowerEntry->Tier;
68 }
69
70 if (artifactAddPower.PowerChoices[0].Rank != artifactPower->PurchasedRank + 1 ||
71 artifactAddPower.PowerChoices[0].Rank > maxRank)
72 return;
73
74 if (!(artifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_NO_LINK_REQUIRED))
75 {
76 if (std::vector<uint32> const* artifactPowerLinks = sDB2Manager.GetArtifactPowerLinks(artifactPower->ArtifactPowerID))
77 {
78 bool hasAnyLink = false;
79 for (uint32 artifactPowerLinkId : *artifactPowerLinks)
80 {
81 ArtifactPowerEntry const* artifactPowerLink = sArtifactPowerStore.LookupEntry(artifactPowerLinkId);
82 if (!artifactPowerLink)
83 continue;
84
85 UF::ArtifactPower const* artifactPowerLinkLearned = artifact->GetArtifactPower(artifactPowerLinkId);
86 if (!artifactPowerLinkLearned)
87 continue;
88
89 if (artifactPowerLinkLearned->PurchasedRank >= artifactPowerLink->MaxPurchasableRank)
90 {
91 hasAnyLink = true;
92 break;
93 }
94 }
95
96 if (!hasAnyLink)
97 return;
98 }
99 }
100
101 ArtifactPowerRankEntry const* artifactPowerRank = sDB2Manager.GetArtifactPowerRank(artifactPower->ArtifactPowerID, artifactPower->CurrentRankWithBonus + 1 - 1); // need data for next rank, but -1 because of how db2 data is structured
102 if (!artifactPowerRank)
103 return;
104
105 artifact->SetArtifactPower(artifactPower->ArtifactPowerID, artifactPower->PurchasedRank + 1, artifactPower->CurrentRankWithBonus + 1);
106
107 if (artifact->IsEquipped())
108 {
109 _player->ApplyArtifactPowerRank(artifact, artifactPowerRank, true);
110
111 for (UF::ArtifactPower const& power : artifact->m_itemData->ArtifactPowers)
112 {
113 ArtifactPowerEntry const* scaledArtifactPowerEntry = sArtifactPowerStore.AssertEntry(power.ArtifactPowerID);
114 if (!(scaledArtifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_SCALES_WITH_NUM_POWERS))
115 continue;
116
117 ArtifactPowerRankEntry const* scaledArtifactPowerRank = sDB2Manager.GetArtifactPowerRank(scaledArtifactPowerEntry->ID, 0);
118 if (!scaledArtifactPowerRank)
119 continue;
120
121 artifact->SetArtifactPower(power.ArtifactPowerID, power.PurchasedRank, power.CurrentRankWithBonus + 1);
122
123 _player->ApplyArtifactPowerRank(artifact, scaledArtifactPowerRank, false);
124 _player->ApplyArtifactPowerRank(artifact, scaledArtifactPowerRank, true);
125 }
126 }
127
128 artifact->SetArtifactXP(artifact->m_itemData->ArtifactXP - xpCost);
129 artifact->SetState(ITEM_CHANGED, _player);
130
131 uint32 totalPurchasedArtifactPower = artifact->GetTotalPurchasedArtifactPowers();
132 uint32 artifactTier = 0;
133
134 for (ArtifactTierEntry const* tier : sArtifactTierStore)
135 {
136 if (artifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_FINAL && artifactPowerEntry->Tier < MAX_ARTIFACT_TIER)
137 {
138 artifactTier = artifactPowerEntry->Tier + 1;
139 break;
140 }
141
142 if (totalPurchasedArtifactPower < tier->MaxNumTraits)
143 {
144 artifactTier = tier->ArtifactTier;
145 break;
146 }
147 }
148
149 artifactTier = std::max(artifactTier, currentArtifactTier);
150
151 for (uint32 i = currentArtifactTier; i <= artifactTier; ++i)
152 artifact->InitArtifactPowers(artifact->GetTemplate()->GetArtifactID(), uint8(i));
153
154 artifact->SetModifier(ITEM_MODIFIER_ARTIFACT_TIER, artifactTier);
156}
157
159{
161 return;
162
163 ArtifactAppearanceEntry const* artifactAppearance = sArtifactAppearanceStore.LookupEntry(artifactSetAppearance.ArtifactAppearanceID);
164 if (!artifactAppearance)
165 return;
166
167 Item* artifact = _player->GetItemByGuid(artifactSetAppearance.ArtifactGUID);
168 if (!artifact)
169 return;
170
171 ArtifactAppearanceSetEntry const* artifactAppearanceSet = sArtifactAppearanceSetStore.LookupEntry(artifactAppearance->ArtifactAppearanceSetID);
172 if (!artifactAppearanceSet || artifactAppearanceSet->ArtifactID != artifact->GetTemplate()->GetArtifactID())
173 return;
174
176 return;
177
178 artifact->SetAppearanceModId(artifactAppearance->ItemAppearanceModifierID);
179 artifact->SetModifier(ITEM_MODIFIER_ARTIFACT_APPEARANCE_ID, artifactAppearance->ID);
180 artifact->SetState(ITEM_CHANGED, _player);
181 Item* childItem = _player->GetChildItemByGuid(artifact->GetChildItem());
182 if (childItem)
183 {
184 childItem->SetAppearanceModId(artifactAppearance->ItemAppearanceModifierID);
185 childItem->SetState(ITEM_CHANGED, _player);
186 }
187
188 if (artifact->IsEquipped())
189 {
190 // change weapon appearance
191 _player->SetVisibleItemSlot(artifact->GetSlot(), artifact);
192 if (childItem)
193 _player->SetVisibleItemSlot(childItem->GetSlot(), childItem);
194
195 // change druid form appearance
196 if (artifactAppearance->OverrideShapeshiftDisplayID && artifactAppearance->OverrideShapeshiftFormID && _player->GetShapeshiftForm() == ShapeshiftForm(artifactAppearance->OverrideShapeshiftFormID))
198 }
199}
200
202{
204 return;
205
206 Item* artifact = _player->GetItemByGuid(confirmArtifactRespec.ArtifactGUID);
207 if (!artifact || artifact->IsArtifactDisabled())
208 return;
209
210 uint64 xpCost = 0;
212 xpCost = uint64(artifact->GetModifier(ITEM_MODIFIER_ARTIFACT_TIER) == 1 ? cost->XP2 : cost->XP);
213
214 if (xpCost > artifact->m_itemData->ArtifactXP)
215 return;
216
217 uint64 newAmount = artifact->m_itemData->ArtifactXP - xpCost;
218 for (uint32 i = 0; i <= artifact->GetTotalPurchasedArtifactPowers(); ++i)
219 if (GtArtifactLevelXPEntry const* cost = sArtifactLevelXPGameTable.GetRow(i))
220 newAmount += uint64(artifact->GetModifier(ITEM_MODIFIER_ARTIFACT_TIER) == 1 ? cost->XP2 : cost->XP);
221
222 for (UF::ArtifactPower const& artifactPower : artifact->m_itemData->ArtifactPowers)
223 {
224 uint8 oldPurchasedRank = artifactPower.PurchasedRank;
225 if (!oldPurchasedRank)
226 continue;
227
228 artifact->SetArtifactPower(artifactPower.ArtifactPowerID, artifactPower.PurchasedRank - oldPurchasedRank, artifactPower.CurrentRankWithBonus - oldPurchasedRank);
229
230 if (artifact->IsEquipped())
231 if (ArtifactPowerRankEntry const* artifactPowerRank = sDB2Manager.GetArtifactPowerRank(artifactPower.ArtifactPowerID, 0))
232 _player->ApplyArtifactPowerRank(artifact, artifactPowerRank, false);
233 }
234
235 for (UF::ArtifactPower const& power : artifact->m_itemData->ArtifactPowers)
236 {
237 ArtifactPowerEntry const* scaledArtifactPowerEntry = sArtifactPowerStore.AssertEntry(power.ArtifactPowerID);
238 if (!(scaledArtifactPowerEntry->Flags & ARTIFACT_POWER_FLAG_SCALES_WITH_NUM_POWERS))
239 continue;
240
241 ArtifactPowerRankEntry const* scaledArtifactPowerRank = sDB2Manager.GetArtifactPowerRank(scaledArtifactPowerEntry->ID, 0);
242 if (!scaledArtifactPowerRank)
243 continue;
244
245 artifact->SetArtifactPower(power.ArtifactPowerID, power.PurchasedRank, 0);
246
247 _player->ApplyArtifactPowerRank(artifact, scaledArtifactPowerRank, false);
248 }
249
250 artifact->SetArtifactXP(newAmount);
251 artifact->SetState(ITEM_CHANGED, _player);
252}
DB2Storage< ArtifactAppearanceEntry > sArtifactAppearanceStore("ArtifactAppearance.db2", &ArtifactAppearanceLoadInfo::Instance)
DB2Storage< ArtifactPowerEntry > sArtifactPowerStore("ArtifactPower.db2", &ArtifactPowerLoadInfo::Instance)
DB2Storage< ArtifactTierEntry > sArtifactTierStore("ArtifactTier.db2", &ArtifactTierLoadInfo::Instance)
DB2Storage< ArtifactAppearanceSetEntry > sArtifactAppearanceSetStore("ArtifactAppearanceSet.db2", &ArtifactAppearanceSetLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
@ ARTIFACT_POWER_FLAG_SCALES_WITH_NUM_POWERS
Definition DBCEnums.h:218
@ ARTIFACT_POWER_FLAG_MAX_RANK_WITH_TIER
Definition DBCEnums.h:220
@ ARTIFACT_POWER_FLAG_NO_LINK_REQUIRED
Definition DBCEnums.h:216
@ ARTIFACT_POWER_FLAG_FINAL
Definition DBCEnums.h:217
#define MAX_ARTIFACT_TIER
Definition DBCEnums.h:225
@ AnyArtifactPowerRankPurchased
uint8_t uint8
Definition Define.h:156
uint64_t uint64
Definition Define.h:153
uint32_t uint32
Definition Define.h:154
GameTable< GtArtifactLevelXPEntry > sArtifactLevelXPGameTable
@ ITEM_MODIFIER_ARTIFACT_APPEARANCE_ID
@ ITEM_MODIFIER_ARTIFACT_TIER
@ ITEM_CHANGED
Definition Item.h:47
@ GAMEOBJECT_TYPE_ITEM_FORGE
ShapeshiftForm
@ UNIT_NPC_FLAG_ARTIFACT_POWER_RESPEC
@ UNIT_NPC_FLAG_2_NONE
static bool IsPlayerMeetingCondition(Player const *player, uint32 conditionId)
Definition Item.h:179
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:1258
uint8 GetSlot() const
Definition Item.h:290
void SetArtifactPower(uint16 artifactPowerId, uint8 purchasedRank, uint8 currentRankWithBonus)
Definition Item.cpp:2651
void InitArtifactPowers(uint8 artifactId, uint8 artifactTier)
Definition Item.cpp:2666
void SetModifier(ItemModifier modifier, uint32 value)
Definition Item.cpp:2483
ItemTemplate const * GetTemplate() const
Definition Item.cpp:1233
UF::UpdateField< UF::ItemData, uint32(WowCS::EntityFragment::CGObject), TYPEID_ITEM > m_itemData
Definition Item.h:459
bool IsEquipped() const
Definition Item.cpp:1336
UF::ArtifactPower const * GetArtifactPower(uint32 artifactPowerId) const
Definition Item.cpp:2634
bool IsArtifactDisabled() const
Definition Item.cpp:2618
void SetArtifactXP(uint64 xp)
Definition Item.h:448
void SetAppearanceModId(uint32 appearanceModId)
Definition Item.h:356
ObjectGuid GetChildItem() const
Definition Item.h:433
uint32 GetModifier(ItemModifier modifier) const
Definition Item.cpp:2470
uint32 GetTotalPurchasedArtifactPowers() const
Definition Item.cpp:2711
void SetVisibleItemSlot(uint8 slot, Item const *item)
Definition Player.cpp:11830
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, NPCFlags npcFlags, NPCFlags2 npcFlags2) const
Definition Player.cpp:1903
Item * GetChildItemByGuid(ObjectGuid guid) const
Definition Player.cpp:9721
GameObject * GetGameObjectIfCanInteractWith(ObjectGuid const &guid) const
Definition Player.cpp:1960
void UpdateCriteria(CriteriaType type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, WorldObject *ref=nullptr)
Definition Player.cpp:27588
Item * GetItemByGuid(ObjectGuid guid) const
Definition Player.cpp:9614
void ApplyArtifactPowerRank(Item *artifact, ArtifactPowerRankEntry const *artifactPowerRank, bool apply)
Definition Player.cpp:8508
void RestoreDisplayId(bool ignorePositiveAurasPreventingMounting=false)
Definition Unit.cpp:10803
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1504
bool IsMounted() const
Definition Unit.h:912
Array< ArtifactPowerChoice, 1 > PowerChoices
void HandleConfirmArtifactRespec(WorldPackets::Artifact::ConfirmArtifactRespec &confirmArtifactRespec)
void HandleArtifactSetAppearance(WorldPackets::Artifact::ArtifactSetAppearance &artifactSetAppearance)
void HandleArtifactAddPower(WorldPackets::Artifact::ArtifactAddPower &artifactAddPower)
Player * _player
uint8 GetArtifactID() const