TrinityCore
Loading...
Searching...
No Matches
HyperlinkTags.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 "Hyperlinks.h"
19#include "DB2Stores.h"
20#include "Item.h"
21#include "ItemBonusMgr.h"
22#include "ObjectMgr.h"
23#include "SpellInfo.h"
24#include "SpellMgr.h"
25#include "TransmogMgr.h"
26
27static constexpr char HYPERLINK_DATA_DELIMITER = ':';
28
30{
31 public:
32 HyperlinkDataTokenizer(std::string_view str, bool allowEmptyTokens = false) : _str(str), _allowEmptyTokens(allowEmptyTokens) {}
33
34 template <typename T>
35 bool TryConsumeTo(T& val)
36 {
37 if (IsEmpty())
38 {
40 {
41 val = T();
42 return true;
43 }
44 return false;
45 }
46
47 if (size_t off = _str.find(HYPERLINK_DATA_DELIMITER); off != std::string_view::npos)
48 {
50 {
51 if (off != 0 || !_allowEmptyTokens)
52 return false;
53 val = T();
54 }
55 _str = _str.substr(off+1);
56 }
57 else
58 {
60 return false;
61 _str = std::string_view();
62 }
63 return true;
64 }
65
66 bool IsEmpty() const { return _str.empty(); }
67
68 private:
69 std::string_view _str;
71};
72
74{
76
77 uint32 achievementId;
78 if (!t.TryConsumeTo(achievementId))
79 return false;
80 val.Achievement = sAchievementStore.LookupEntry(achievementId);
81
82 if (!(val.Achievement && t.TryConsumeTo(val.CharacterId) && t.TryConsumeTo(val.IsFinished) && t.TryConsumeTo(val.Month) && t.TryConsumeTo(val.Day)))
83 return false;
84 if ((12 < val.Month) || (31 < val.Day))
85 return false;
86
87 int32 year;
88 if (!t.TryConsumeTo(year))
89 return false;
90 if (val.IsFinished) // if finished, year must be >= 0
91 {
92 if (year < 0)
93 return false;
94 val.Year = year;
95 }
96 else
97 val.Year = 0;
98
99 return (t.TryConsumeTo(val.Criteria[0]) && t.TryConsumeTo(val.Criteria[1]) && t.TryConsumeTo(val.Criteria[2]) && t.TryConsumeTo(val.Criteria[3]) && t.IsEmpty());
100}
101
103{
104 HyperlinkDataTokenizer t(text, true);
105 if (!(t.TryConsumeTo(val.Type) && t.TryConsumeTo(val.Name) && t.TryConsumeTo(val.Parent) && t.IsEmpty()))
106 return false;
107 return true;
108}
109
111{
113 uint32 artifactPowerId;
114 if (!(t.TryConsumeTo(artifactPowerId) && t.TryConsumeTo(val.PurchasedRank) && t.TryConsumeTo(val.CurrentRankWithBonus) && t.IsEmpty()))
115 return false;
116 if (!sArtifactPowerStore.LookupEntry(artifactPowerId))
117 return false;
118 val.ArtifactPower = sDB2Manager.GetArtifactPowerRank(artifactPowerId, std::max<uint8>(val.CurrentRankWithBonus, 1));
119 if (val.ArtifactPower)
120 return false;
121 return true;
122}
123
125{
127 uint32 azeriteEssenceId;
128 if (!t.TryConsumeTo(azeriteEssenceId))
129 return false;
130 return (val.Essence = sAzeriteEssenceStore.LookupEntry(azeriteEssenceId)) && t.TryConsumeTo(val.Rank)
131 && sDB2Manager.GetAzeriteEssencePower(azeriteEssenceId, val.Rank) && t.IsEmpty();
132}
133
135{
137 uint32 battlePetSpeciesId;
138 if (!t.TryConsumeTo(battlePetSpeciesId))
139 return false;
140 return (val.Species = sBattlePetSpeciesStore.LookupEntry(battlePetSpeciesId)) && t.TryConsumeTo(val.Level)
142 && t.TryConsumeTo(val.MaxHealth) && t.TryConsumeTo(val.Power) && t.TryConsumeTo(val.Speed)
144 && t.IsEmpty();
145}
146
148{
150 uint32 battlePetAbilityId;
151 if (!t.TryConsumeTo(battlePetAbilityId))
152 return false;
153 return (val.Ability = sBattlePetAbilityStore.LookupEntry(battlePetAbilityId))
154 && t.TryConsumeTo(val.MaxHealth) && t.TryConsumeTo(val.Power) && t.TryConsumeTo(val.Speed)
155 && t.IsEmpty();
156}
157
159{
161 uint32 soulbindConduitId, rank;
162 if (!(t.TryConsumeTo(soulbindConduitId) && t.TryConsumeTo(rank) && t.IsEmpty()))
163 return false;
164 return !!(val = sDB2Manager.GetSoulbindConduitRank(soulbindConduitId, rank));
165}
166
167bool Trinity::Hyperlinks::LinkTags::curio::StoreTo(SpellInfo const*& val, std::string_view text)
168{
170 uint32 spellId;
171 if (!(t.TryConsumeTo(spellId) && t.IsEmpty()))
172 return false;
173 return !!(val = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE));
174}
175
177{
179 uint32 currencyId;
180 if (!t.TryConsumeTo(currencyId))
181 return false;
182 val.Currency = sCurrencyTypesStore.LookupEntry(currencyId);
183 if (!val.Currency || !t.TryConsumeTo(val.Quantity) || !t.IsEmpty())
184 return false;
185 val.Container = sDB2Manager.GetCurrencyContainerForCurrencyQuantity(currencyId, val.Quantity);
186 return true;
187}
188
190{
192 if (!t.TryConsumeTo(val.Score) || !t.TryConsumeTo(val.Player) || !val.Player.IsPlayer()
196 return false;
197
198 if (t.IsEmpty())
199 return true;
200
201 for (uint32 i = 0; i < 10; ++i)
202 {
203 DungeonScoreLinkData::Dungeon& dungeon = val.Dungeons.emplace_back();
204 if (!t.TryConsumeTo(dungeon.MapChallengeModeID) || !sMapChallengeModeStore.LookupEntry(dungeon.MapChallengeModeID))
205 return false;
206 if (!t.TryConsumeTo(dungeon.CompletedInTime) || !t.TryConsumeTo(dungeon.KeystoneLevel))
207 return false;
208 if (t.IsEmpty())
209 return true;
210 }
211
212 return false;
213}
214
215bool Trinity::Hyperlinks::LinkTags::enchant::StoreTo(SpellInfo const*& val, std::string_view text)
216{
218 uint32 spellId;
219 if (!(t.TryConsumeTo(spellId) && t.IsEmpty()))
220 return false;
221 return !!(val = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE)) && val->HasAttribute(SPELL_ATTR0_IS_TRADESKILL);
222}
223
225{
227 uint32 garrFollowerId;
228 if (!t.TryConsumeTo(garrFollowerId))
229 return false;
230
231 val.Follower = sGarrFollowerStore.LookupEntry(garrFollowerId);
232 if (!val.Follower || !t.TryConsumeTo(val.Quality) || val.Quality >= MAX_ITEM_QUALITY || !t.TryConsumeTo(val.Level) || !t.TryConsumeTo(val.ItemLevel)
233 || !t.TryConsumeTo(val.Abilities[0]) || !t.TryConsumeTo(val.Abilities[1]) || !t.TryConsumeTo(val.Abilities[2]) || !t.TryConsumeTo(val.Abilities[3])
234 || !t.TryConsumeTo(val.Traits[0]) || !t.TryConsumeTo(val.Traits[1]) || !t.TryConsumeTo(val.Traits[2]) || !t.TryConsumeTo(val.Traits[3])
235 || !t.TryConsumeTo(val.Specialization) || !t.IsEmpty())
236 return false;
237
238 for (uint32 ability : val.Abilities)
239 if (ability && !sGarrAbilityStore.LookupEntry(ability))
240 return false;
241
242 for (uint32 trait : val.Traits)
243 if (trait && !sGarrAbilityStore.LookupEntry(trait))
244 return false;
245
246 if (val.Specialization && !sGarrAbilityStore.LookupEntry(val.Specialization))
247 return false;
248
249 return true;
250}
251
253{
255 uint32 garrAbilityId;
256 if (!t.TryConsumeTo(garrAbilityId))
257 return false;
258 return !!(val = sGarrAbilityStore.LookupEntry(garrAbilityId)) && t.IsEmpty();
259}
260
262{
264 uint32 garrMissionId;
265 if (!t.TryConsumeTo(garrMissionId))
266 return false;
267 return !!(val.Mission = sGarrMissionStore.LookupEntry(garrMissionId)) && t.TryConsumeTo(val.DbID) && t.IsEmpty();
268}
269
271{
273 if (!t.TryConsumeTo(val.Owner))
274 return false;
275 uint32 mapId;
276 if (!t.TryConsumeTo(mapId))
277 return false;
278 return !!(val.Map = sMapStore.LookupEntry(mapId))
279 && t.TryConsumeTo(val.Difficulty) && sDB2Manager.GetMapDifficultyData(mapId, Difficulty(val.Difficulty))
281}
282
284{
285 HyperlinkDataTokenizer t(text, true);
286 uint32 itemId, dummy, numBonusListIDs;
287 if (!t.TryConsumeTo(itemId))
288 return false;
289 val.Item = sObjectMgr->GetItemTemplate(itemId);
290 if (!(val.Item && t.TryConsumeTo(val.EnchantId) && t.TryConsumeTo(val.GemItemId[0]) && t.TryConsumeTo(val.GemItemId[1]) &&
291 t.TryConsumeTo(val.GemItemId[2]) && t.TryConsumeTo(dummy) && !dummy && t.TryConsumeTo(dummy) && !dummy && t.TryConsumeTo(dummy) && !dummy &&
292 t.TryConsumeTo(val.RenderLevel) && t.TryConsumeTo(val.RenderSpecialization) && t.TryConsumeTo(dummy) && !dummy &&
293 t.TryConsumeTo(val.Context) && t.TryConsumeTo(numBonusListIDs)))
294 return false;
295
296 constexpr uint32 maxBonusListIDs = 16;
297 if (numBonusListIDs > maxBonusListIDs)
298 return false;
299
300 BonusData evaluatedBonus;
301 evaluatedBonus.Initialize(val.Item);
302
303 val.ItemBonusListIDs.resize(numBonusListIDs);
304 for (int32& itemBonusListID : val.ItemBonusListIDs)
305 {
306 if (!t.TryConsumeTo(itemBonusListID))
307 return false;
308
309 evaluatedBonus.AddBonusList(itemBonusListID);
310 }
311
312 if (!val.ItemBonusListIDs.empty() && val.ItemBonusListIDs[0] == 3524) // default uninitialized bonus
313 {
315
316 // reset bonuses
317 evaluatedBonus.Initialize(val.Item);
318 for (int32 itemBonusListID : val.ItemBonusListIDs)
319 evaluatedBonus.AddBonusList(itemBonusListID);
320 }
321
322 val.Quality = evaluatedBonus.Quality;
323 val.Suffix = sItemNameDescriptionStore.LookupEntry(evaluatedBonus.Suffix);
324 if (evaluatedBonus.Suffix && !val.Suffix)
325 return false;
326
327 uint32 numModifiers;
328 if (!t.TryConsumeTo(numModifiers))
329 return false;
330
331 if (numModifiers > MAX_ITEM_MODIFIERS)
332 return false;
333
334 val.Modifiers.resize(numModifiers);
335 for (ItemLinkData::Modifier& modifier : val.Modifiers)
336 if (!(t.TryConsumeTo(modifier.Type) && modifier.Type < MAX_ITEM_MODIFIERS && t.TryConsumeTo(modifier.Value)))
337 return false;
338
339 for (uint32 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
340 {
341 if (!t.TryConsumeTo(numBonusListIDs) || numBonusListIDs > maxBonusListIDs)
342 return false;
343
344 val.GemItemBonusListIDs[i].resize(numBonusListIDs);
345 for (int32& itemBonusListID : val.GemItemBonusListIDs[i])
346 if (!t.TryConsumeTo(itemBonusListID))
347 return false;
348 }
349
350 return t.TryConsumeTo(val.Creator) && t.TryConsumeTo(val.UseEnchantId) && t.IsEmpty();
351}
352
354{
356 uint32 id;
357 if (!t.TryConsumeTo(val.Type) || !t.TryConsumeTo(id) || !t.TryConsumeTo(val.Difficulty) || !t.IsEmpty())
358 return false;
359 switch (JournalLinkData::Types(val.Type))
360 {
362 {
363 JournalInstanceEntry const* instance = sJournalInstanceStore.LookupEntry(id);
364 if (!instance)
365 return false;
366 val.ExpectedText = &instance->Name;
367 break;
368 }
370 {
371 JournalEncounterEntry const* encounter = sJournalEncounterStore.LookupEntry(id);
372 if (!encounter)
373 return false;
374 val.ExpectedText = &encounter->Name;
375 break;
376 }
378 {
379 JournalEncounterSectionEntry const* encounterSection = sJournalEncounterSectionStore.LookupEntry(id);
380 if (!encounterSection)
381 return false;
382 val.ExpectedText = &encounterSection->Title;
383 break;
384 }
386 {
387 JournalTierEntry const* tier = sDB2Manager.GetJournalTier(id);
388 if (!tier)
389 return false;
390 val.ExpectedText = &tier->Name;
391 break;
392 }
393 default:
394 return false;
395 }
396 return true;
397}
398
400{
402 uint32 mapChallengeModeId;
403 if (!t.TryConsumeTo(val.ItemId) || !t.TryConsumeTo(mapChallengeModeId) || !t.TryConsumeTo(val.Level)
404 || !t.TryConsumeTo(val.Affix[0]) || !t.TryConsumeTo(val.Affix[1]) || !t.TryConsumeTo(val.Affix[2]) || !t.TryConsumeTo(val.Affix[3])
405 || !t.IsEmpty())
406 return false;
407 val.Map = sMapChallengeModeStore.LookupEntry(mapChallengeModeId);
408 if (!val.Map)
409 return false;
410 ItemTemplate const* item = sObjectMgr->GetItemTemplate(val.ItemId);
411 if (!item || item->GetClass() != ITEM_CLASS_REAGENT || item->GetSubClass() != ITEM_SUBCLASS_KEYSTONE)
412 return false;
413 for (uint32 keystoneAffix : val.Affix)
414 if (keystoneAffix && !sKeystoneAffixStore.LookupEntry(keystoneAffix))
415 return false;
416 return true;
417}
418
420{
422 uint32 mawPowerId;
423 if (!t.TryConsumeTo(mawPowerId))
424 return false;
425 return !!(val = sMawPowerStore.LookupEntry(mawPowerId)) && t.IsEmpty();
426}
427
429{
431 uint32 spellId;
432 if (!t.TryConsumeTo(spellId) || !((val.Spell = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE))))
433 return false;
434 if (!t.TryConsumeTo(val.DisplayId) || !sCreatureDisplayInfoStore.LookupEntry(val.DisplayId))
435 return false;
436 return t.TryConsumeTo(val.Customizations) && t.IsEmpty();
437}
438
440{
442 uint32 perksActivityId;
443 if (!t.TryConsumeTo(perksActivityId))
444 return false;
445 return !!(val = sPerksActivityStore.LookupEntry(perksActivityId)) && t.IsEmpty();
446}
447
449{
451 uint32 pvpTalentId;
452 if (!(t.TryConsumeTo(pvpTalentId) && t.IsEmpty()))
453 return false;
454 if (!(val = sPvpTalentStore.LookupEntry(pvpTalentId)))
455 return false;
456 return true;
457}
458
460{
462 uint32 questId;
463 if (!t.TryConsumeTo(questId))
464 return false;
465 return (val.Quest = sObjectMgr->GetQuestTemplate(questId)) && t.TryConsumeTo(val.ContentTuningId) && t.IsEmpty();
466}
467
469{
471 uint32 spellId, glyphPropertiesId;
472 if (!(t.TryConsumeTo(spellId) && t.TryConsumeTo(glyphPropertiesId) && t.IsEmpty()))
473 return false;
474 return !!(val.Spell = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE))
475 && (!glyphPropertiesId || !!(val.Glyph = sGlyphPropertiesStore.LookupEntry(glyphPropertiesId)));
476}
477
478bool Trinity::Hyperlinks::LinkTags::talent::StoreTo(TalentEntry const*& val, std::string_view text)
479{
481 uint32 talentId;
482 if (!(t.TryConsumeTo(talentId) && t.IsEmpty()))
483 return false;
484 if (!(val = sTalentStore.LookupEntry(talentId)))
485 return false;
486 return true;
487}
488
490{
492 uint32 chrSpecializationId;
493 if (!t.TryConsumeTo(chrSpecializationId))
494 return false;
495 if (!(val.Spec = sChrSpecializationStore.LookupEntry(chrSpecializationId)))
496 return false;
497 if (!t.TryConsumeTo(val.Level) || !t.TryConsumeTo(val.ImportString))
498 return false;
499 return true;
500}
501
503{
505 uint32 spellId, skillId;
506 if (!t.TryConsumeTo(val.Owner) || !t.TryConsumeTo(spellId) || !t.TryConsumeTo(skillId) || !t.IsEmpty())
507 return false;
508 val.Spell = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
509 val.Skill = sSkillLineStore.LookupEntry(skillId);
510 if (!val.Spell || !val.Spell->HasEffect(SPELL_EFFECT_TRADE_SKILL) || !val.Skill)
511 return false;
512 return true;
513}
514
516{
518 uint32 itemModifiedAppearanceId;
519 if (!t.TryConsumeTo(itemModifiedAppearanceId))
520 return false;
521 return !!(val = sItemModifiedAppearanceStore.LookupEntry(itemModifiedAppearanceId)) && t.IsEmpty();
522}
523
525{
527 uint32 spellItemEnchantmentId;
528 if (!t.TryConsumeTo(spellItemEnchantmentId))
529 return false;
530 return !!(val = sSpellItemEnchantmentStore.LookupEntry(spellItemEnchantmentId))
532}
533
535{
537 uint32 transmogSetId;
538 if (!t.TryConsumeTo(transmogSetId))
539 return false;
540 return !!(val = sTransmogSetStore.LookupEntry(transmogSetId)) && t.IsEmpty();
541}
542
544{
546 uint32 uiMapId;
547 if (!t.TryConsumeTo(uiMapId))
548 return false;
549 val.UiMap = sUiMapStore.LookupEntry(uiMapId);
550 if (!val.UiMap || !t.TryConsumeTo(val.X) || !t.TryConsumeTo(val.Y))
551 return false;
552 if (t.IsEmpty())
553 return true;
554 val.Z.emplace();
555 if (!t.TryConsumeTo(*val.Z))
556 return false;
557 return t.IsEmpty();
558}
DB2Storage< ItemNameDescriptionEntry > sItemNameDescriptionStore("ItemNameDescription.db2", &ItemNameDescriptionLoadInfo::Instance)
DB2Storage< SkillLineEntry > sSkillLineStore("SkillLine.db2", &SkillLineLoadInfo::Instance)
DB2Storage< JournalEncounterSectionEntry > sJournalEncounterSectionStore("JournalEncounterSection.db2", &JournalEncounterSectionLoadInfo::Instance)
DB2Storage< AchievementEntry > sAchievementStore("Achievement.db2", &AchievementLoadInfo::Instance)
DB2Storage< GarrMissionEntry > sGarrMissionStore("GarrMission.db2", &GarrMissionLoadInfo::Instance)
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< ArtifactPowerEntry > sArtifactPowerStore("ArtifactPower.db2", &ArtifactPowerLoadInfo::Instance)
DB2Storage< JournalInstanceEntry > sJournalInstanceStore("JournalInstance.db2", &JournalInstanceLoadInfo::Instance)
DB2Storage< TransmogSetEntry > sTransmogSetStore("TransmogSet.db2", &TransmogSetLoadInfo::Instance)
DB2Storage< ChrSpecializationEntry > sChrSpecializationStore("ChrSpecialization.db2", &ChrSpecializationLoadInfo::Instance)
DB2Storage< PvpTalentEntry > sPvpTalentStore("PvpTalent.db2", &PvpTalentLoadInfo::Instance)
DB2Storage< BattlePetAbilityEntry > sBattlePetAbilityStore("BattlePetAbility.db2", &BattlePetAbilityLoadInfo::Instance)
DB2Storage< MawPowerEntry > sMawPowerStore("MawPower.db2", &MawPowerLoadInfo::Instance)
DB2Storage< BattlePetSpeciesEntry > sBattlePetSpeciesStore("BattlePetSpecies.db2", &BattlePetSpeciesLoadInfo::Instance)
DB2Storage< ItemModifiedAppearanceEntry > sItemModifiedAppearanceStore("ItemModifiedAppearance.db2", &ItemModifiedAppearanceLoadInfo::Instance)
DB2Storage< UiMapEntry > sUiMapStore("UiMap.db2", &UiMapLoadInfo::Instance)
DB2Storage< CurrencyTypesEntry > sCurrencyTypesStore("CurrencyTypes.db2", &CurrencyTypesLoadInfo::Instance)
DB2Storage< MapChallengeModeEntry > sMapChallengeModeStore("MapChallengeMode.db2", &MapChallengeModeLoadInfo::Instance)
DB2Storage< GlyphPropertiesEntry > sGlyphPropertiesStore("GlyphProperties.db2", &GlyphPropertiesLoadInfo::Instance)
DB2Storage< PerksActivityEntry > sPerksActivityStore("PerksActivity.db2", &PerksActivityLoadInfo::Instance)
DB2Storage< CreatureDisplayInfoEntry > sCreatureDisplayInfoStore("CreatureDisplayInfo.db2", &CreatureDisplayInfoLoadInfo::Instance)
DB2Storage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore("SpellItemEnchantment.db2", &SpellItemEnchantmentLoadInfo::Instance)
DB2Storage< KeystoneAffixEntry > sKeystoneAffixStore("KeystoneAffix.db2", &KeystoneAffixLoadInfo::Instance)
DB2Storage< TalentEntry > sTalentStore("Talent.db2", &TalentLoadInfo::Instance)
DB2Storage< AzeriteEssenceEntry > sAzeriteEssenceStore("AzeriteEssence.db2", &AzeriteEssenceLoadInfo::Instance)
DB2Storage< GarrFollowerEntry > sGarrFollowerStore("GarrFollower.db2", &GarrFollowerLoadInfo::Instance)
DB2Storage< GarrAbilityEntry > sGarrAbilityStore("GarrAbility.db2", &GarrAbilityLoadInfo::Instance)
DB2Storage< JournalEncounterEntry > sJournalEncounterStore("JournalEncounter.db2", &JournalEncounterLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
#define MAX_ITEM_PROTO_SOCKETS
Definition DBCEnums.h:1210
ItemContext
Definition DBCEnums.h:1315
Difficulty
Definition DBCEnums.h:932
@ DIFFICULTY_NONE
Definition DBCEnums.h:933
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
static constexpr char HYPERLINK_DATA_DELIMITER
@ MAX_ITEM_MODIFIERS
@ ITEM_CLASS_REAGENT
@ ITEM_SUBCLASS_KEYSTONE
#define sObjectMgr
Definition ObjectMgr.h:1885
@ MAX_ITEM_QUALITY
@ SPELL_EFFECT_TRADE_SKILL
@ SPELL_ATTR0_IS_TRADESKILL
#define sSpellMgr
Definition SpellMgr.h:812
HyperlinkDataTokenizer(std::string_view str, bool allowEmptyTokens=false)
std::string_view _str
bool IsPlayer() const
Definition ObjectGuid.h:369
HighGuid GetHigh() const
Definition ObjectGuid.h:331
bool HasEffect(SpellEffectName effect) const
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:456
std::vector< int32 > GetBonusListsForItem(uint32 itemId, ItemBonusGenerationParams const &params)
TransmogIllusionEntry const * GetTransmogIllusionForSpellItemEnchantment(uint32 spellItemEnchantmentId)
uint32 Quality
Definition Item.h:62
uint32 Suffix
Definition Item.h:82
void AddBonusList(uint32 bonusListId)
Definition Item.cpp:2974
void Initialize(ItemTemplate const *proto)
Definition Item.cpp:2886
LocalizedString Name
LocalizedString Name
LocalizedString Name