aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/Common.h2
-rw-r--r--src/server/game/Achievements/AchievementMgr.h2
-rw-r--r--src/server/game/Chat/HyperlinkTags.cpp11
-rw-r--r--src/server/game/DataStores/DB2Structure.h320
-rw-r--r--src/server/game/Entities/Item/Item.cpp2
-rw-r--r--src/server/game/Entities/Item/Item.h2
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Spells/SpellInfo.cpp54
-rw-r--r--src/server/game/Spells/SpellInfo.h12
-rw-r--r--src/server/shared/DataStores/DB2Store.h2
-rw-r--r--tests/DummyData.cpp21
-rw-r--r--tests/DummyData.h37
-rw-r--r--tests/game/Hyperlinks.cpp18
13 files changed, 284 insertions, 201 deletions
diff --git a/src/common/Common.h b/src/common/Common.h
index 902b8cf6567..efbb181737b 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -139,7 +139,7 @@ struct LocalizedString
return Str[locale];
}
- char const* Str[TOTAL_LOCALES];
+ std::array<char const*, TOTAL_LOCALES> Str;
};
#pragma pack(pop)
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 478518f3626..6c87792a38d 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -140,6 +140,8 @@ protected:
private:
Guild* _owner;
+
+ friend class UnitTestDataLoader;
};
class TC_GAME_API AchievementGlobalMgr
diff --git a/src/server/game/Chat/HyperlinkTags.cpp b/src/server/game/Chat/HyperlinkTags.cpp
index b72dcfddb91..83c037d23cc 100644
--- a/src/server/game/Chat/HyperlinkTags.cpp
+++ b/src/server/game/Chat/HyperlinkTags.cpp
@@ -71,13 +71,17 @@ class HyperlinkDataTokenizer
bool Trinity::Hyperlinks::LinkTags::achievement::StoreTo(AchievementLinkData& val, std::string_view text)
{
HyperlinkDataTokenizer t(text);
+
uint32 achievementId;
if (!t.TryConsumeTo(achievementId))
return false;
val.Achievement = sAchievementStore.LookupEntry(achievementId);
- if (!(val.Achievement && t.TryConsumeTo(val.CharacterId) && t.TryConsumeTo(val.IsFinished) &&
- t.TryConsumeTo(val.Month) && t.TryConsumeTo(val.Day)))
+
+ if (!(val.Achievement && t.TryConsumeTo(val.CharacterId) && t.TryConsumeTo(val.IsFinished) && t.TryConsumeTo(val.Month) && t.TryConsumeTo(val.Day)))
return false;
+ if ((12 < val.Month) || (31 < val.Day))
+ return false;
+
int32 year;
if (!t.TryConsumeTo(year))
return false;
@@ -90,8 +94,7 @@ bool Trinity::Hyperlinks::LinkTags::achievement::StoreTo(AchievementLinkData& va
else
val.Year = 0;
- return (t.TryConsumeTo(val.Criteria[0]) &&
- t.TryConsumeTo(val.Criteria[1]) && t.TryConsumeTo(val.Criteria[2]) && t.TryConsumeTo(val.Criteria[3]) && t.IsEmpty());
+ return (t.TryConsumeTo(val.Criteria[0]) && t.TryConsumeTo(val.Criteria[1]) && t.TryConsumeTo(val.Criteria[2]) && t.TryConsumeTo(val.Criteria[3]) && t.IsEmpty());
}
bool Trinity::Hyperlinks::LinkTags::apower::StoreTo(ArtifactPowerLinkData& val, std::string_view text)
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 153e9630ca7..b4eb05bf73f 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -77,8 +77,8 @@ struct AdventureJournalEntry
uint16 CurrencyType;
uint32 CurrencyQuantity;
uint16 UiMapID;
- uint32 BonusPlayerConditionID[2];
- uint8 BonusValue[2];
+ std::array<uint32, 2> BonusPlayerConditionID;
+ std::array<uint8, 2> BonusValue;
};
struct AdventureMapPOIEntry
@@ -104,7 +104,7 @@ struct AnimationDataEntry
uint16 Fallback;
uint8 BehaviorTier;
int32 BehaviorID;
- int32 Flags[2];
+ std::array<int32, 2> Flags;
};
struct AnimKitEntry
@@ -146,8 +146,8 @@ struct AreaTableEntry
uint8 WildBattlePetLevelMax;
uint8 WindSettingsID;
int32 ContentTuningID;
- int32 Flags[2];
- uint16 LiquidTypeID[4];
+ std::array<int32, 2> Flags;
+ std::array<uint16, 4> LiquidTypeID;
// helpers
bool IsSanctuary() const
@@ -290,7 +290,7 @@ struct ArtifactPowerRankEntry
struct ArtifactQuestXPEntry
{
uint32 ID;
- uint32 Difficulty[10];
+ std::array<uint32, 10> Difficulty;
};
struct ArtifactTierEntry
@@ -510,7 +510,7 @@ struct BattlemasterListEntry
int32 Flags;
int32 IconFileDataID;
int32 RequiredPlayerConditionID;
- int16 MapID[16];
+ std::array<int16, 16> MapID;
EnumFlag<BattlemasterListFlags> GetFlags() const { return static_cast<BattlemasterListFlags>(Flags); }
};
@@ -527,9 +527,9 @@ struct BroadcastTextEntry
uint16 EmotesID;
uint8 Flags;
uint32 ChatBubbleDurationMs;
- uint32 SoundKitID[2];
- uint16 EmoteID[MAX_BROADCAST_TEXT_EMOTES];
- uint16 EmoteDelay[MAX_BROADCAST_TEXT_EMOTES];
+ std::array<uint32, 2> SoundKitID;
+ std::array<uint16, MAX_BROADCAST_TEXT_EMOTES> EmoteID;
+ std::array<uint16, MAX_BROADCAST_TEXT_EMOTES> EmoteDelay;
};
struct BroadcastTextDurationEntry
@@ -655,7 +655,7 @@ struct ChrCustomizationChoiceEntry
uint16 UiOrderIndex;
int32 Flags;
int32 AddedInPatch;
- int32 SwatchColor[2];
+ std::array<int32, 2> SwatchColor;
};
struct ChrCustomizationDisplayInfoEntry
@@ -719,8 +719,8 @@ struct ChrCustomizationReqChoiceEntry
struct ChrModelEntry
{
- float FaceCustomizationOffset[3];
- float CustomizeOffset[3];
+ std::array<float, 3> FaceCustomizationOffset;
+ std::array<float, 3> CustomizeOffset;
uint32 ID;
int32 Sex;
int32 DisplayID;
@@ -776,8 +776,8 @@ struct ChrRacesEntry
int32 SelectScreenFileDataID;
int32 NeutralRaceID;
int32 LowResScreenFileDataID;
- int32 AlteredFormStartVisualKitID[3];
- int32 AlteredFormFinishVisualKitID[3];
+ std::array<int32, 3> AlteredFormStartVisualKitID;
+ std::array<int32, 3> AlteredFormFinishVisualKitID;
int32 HeritageArmorAchievementID;
int32 StartingLevel;
int32 UiDisplayOrder;
@@ -789,10 +789,10 @@ struct ChrRacesEntry
int32 HelmetAnimScalingRaceID;
int32 TransmogrifyDisabledSlotMask;
int32 UnalteredVisualCustomizationRaceID;
- float AlteredFormCustomizeOffsetFallback[3];
+ std::array<float, 3> AlteredFormCustomizeOffsetFallback;
float AlteredFormCustomizeRotationFallback;
- float Unknown910_1[3];
- float Unknown910_2[3];
+ std::array<float, 3> Unknown910_1;
+ std::array<float, 3> Unknown910_2;
int8 BaseLanguage;
int8 CreatureType;
int8 MaleModelFallbackSex;
@@ -819,7 +819,7 @@ struct ChrSpecializationEntry
int32 SpellIconFileID;
int8 PrimaryStatPriority;
int32 AnimReplacements;
- int32 MasterySpellID[MAX_MASTERY_SPELLS];
+ std::array<int32, MAX_MASTERY_SPELLS> MasterySpellID;
bool IsPetSpecialization() const
{
@@ -841,7 +841,7 @@ struct CinematicSequencesEntry
{
uint32 ID;
uint32 SoundID;
- uint16 Camera[8];
+ std::array<uint16, 8> Camera;
};
struct ContentTuningEntry
@@ -942,7 +942,7 @@ struct CreatureDisplayInfoEntry
int8 Gender;
int32 DissolveOutEffectID;
int8 CreatureModelMinLod;
- int32 TextureVariationFileDataID[3];
+ std::array<int32, 3> TextureVariationFileDataID;
};
struct CreatureDisplayInfoExtraEntry
@@ -967,13 +967,13 @@ struct CreatureFamilyEntry
int16 PetFoodMask;
int8 PetTalentType;
int32 IconFileID;
- int16 SkillLine[2];
+ std::array<int16, 2> SkillLine;
};
struct CreatureModelDataEntry
{
uint32 ID;
- float GeoBox[6];
+ std::array<float, 6> GeoBox;
uint32 Flags;
uint32 FileDataID;
uint32 BloodID;
@@ -1003,7 +1003,7 @@ struct CreatureModelDataEntry
float TamedPetBaseScale;
int8 Unknown820_1; // scale related
float Unknown820_2; // scale related
- float Unknown820_3[2]; // scale related
+ std::array<float, 2> Unknown820_3; // scale related
EnumFlag<CreatureModelDataFlags> GetFlags() const { return static_cast<CreatureModelDataFlags>(Flags); }
};
@@ -1272,7 +1272,7 @@ struct CurrencyTypesEntry
int32 XpQuestDifficulty;
int32 AwardConditionID;
int32 MaxQtyWorldStateID;
- int32 Flags[2];
+ std::array<int32, 2> Flags;
};
struct CurveEntry
@@ -1354,8 +1354,8 @@ struct DungeonEncounterEntry
struct DurabilityCostsEntry
{
uint32 ID;
- uint16 WeaponSubClassCost[21];
- uint16 ArmorSubClassCost[8];
+ std::array<uint16, 21> WeaponSubClassCost;
+ std::array<uint16, 8> ArmorSubClassCost;
};
struct DurabilityQualityEntry
@@ -1428,7 +1428,7 @@ struct ExpectedStatModEntry
struct FactionEntry
{
uint32 ID;
- Trinity::RaceMask<int64> ReputationRaceMask[4];
+ std::array<Trinity::RaceMask<int64>, 4> ReputationRaceMask;
LocalizedString Name;
LocalizedString Description;
int16 ReputationIndex;
@@ -1437,12 +1437,12 @@ struct FactionEntry
uint32 FriendshipRepID;
uint8 Flags;
uint16 ParagonFactionID;
- int16 ReputationClassMask[4];
- uint16 ReputationFlags[4];
- int32 ReputationBase[4];
- int32 ReputationMax[4];
- float ParentFactionMod[2]; // Faction outputs rep * ParentFactionModOut as spillover reputation
- uint8 ParentFactionCap[2]; // The highest rank the faction will profit from incoming spillover
+ std::array<int16, 4> ReputationClassMask;
+ std::array<uint16, 4> ReputationFlags;
+ std::array<int32, 4> ReputationBase;
+ std::array<int32, 4> ReputationMax;
+ std::array<float, 2> ParentFactionMod; // Faction outputs rep * ParentFactionModOut as spillover reputation
+ std::array<uint8, 2> ParentFactionCap; // The highest rank the faction will profit from incoming spillover
// helpers
bool CanHaveReputation() const
@@ -1461,8 +1461,8 @@ struct FactionTemplateEntry
uint8 FactionGroup;
uint8 FriendGroup;
uint8 EnemyGroup;
- uint16 Enemies[MAX_FACTION_RELATIONS];
- uint16 Friend[MAX_FACTION_RELATIONS];
+ std::array<uint16, MAX_FACTION_RELATIONS> Enemies;
+ std::array<uint16, MAX_FACTION_RELATIONS> Friend;
//------------------------------------------------------- end structure
@@ -1534,7 +1534,7 @@ struct GameObjectArtKitEntry
{
uint32 ID;
int32 AttachModelFileID;
- int32 TextureVariationFileID[3];
+ std::array<int32, 3> TextureVariationFileID;
};
struct GameObjectDisplayInfoEntry
@@ -1552,7 +1552,7 @@ struct GameObjectsEntry
{
LocalizedString Name;
DBCPosition3D Pos;
- float Rot[4];
+ std::array<float, 4> Rot;
uint32 ID;
int32 OwnerID;
int32 DisplayID;
@@ -1561,7 +1561,7 @@ struct GameObjectsEntry
int32 PhaseUseFlags;
int32 PhaseID;
int32 PhaseGroupID;
- int32 PropValue[8];
+ std::array<int32, 8> PropValue;
};
struct GarrAbilityEntry
@@ -1718,7 +1718,7 @@ struct GarrPlotEntry
int32 AllianceConstructObjID;
uint8 Flags;
uint8 UiCategoryID;
- uint32 UpgradeRequirement[2];
+ std::array<uint32, 2> UpgradeRequirement;
};
struct GarrPlotBuildingEntry
@@ -1835,8 +1835,8 @@ struct HeirloomEntry
int8 SourceTypeEnum;
uint8 Flags;
int32 LegacyItemID;
- int32 UpgradeItemID[6];
- uint16 UpgradeItemBonusListID[6];
+ std::array<int32, 6> UpgradeItemID;
+ std::array<uint16, 6> UpgradeItemBonusListID;
};
#define MAX_HOLIDAY_DURATIONS 10
@@ -1853,10 +1853,10 @@ struct HolidaysEntry
uint8 Priority;
int8 CalendarFilterType;
uint8 Flags;
- uint16 Duration[MAX_HOLIDAY_DURATIONS];
- uint32 Date[MAX_HOLIDAY_DATES]; // dates in unix time starting at January, 1, 2000
- uint8 CalendarFlags[MAX_HOLIDAY_DURATIONS];
- int32 TextureFileDataID[3];
+ std::array<uint16, MAX_HOLIDAY_DURATIONS> Duration;
+ std::array<uint32, MAX_HOLIDAY_DATES> Date; // dates in unix time starting at January, 1, 2000
+ std::array<uint8, MAX_HOLIDAY_DURATIONS> CalendarFlags;
+ std::array<int32, 3> TextureFileDataID;
};
struct ImportPriceArmorEntry
@@ -1914,13 +1914,13 @@ struct ItemAppearanceEntry
struct ItemArmorQualityEntry
{
uint32 ID;
- float Qualitymod[7];
+ std::array<float, 7> Qualitymod;
};
struct ItemArmorShieldEntry
{
uint32 ID;
- float Quality[7];
+ std::array<float, 7> Quality;
uint16 ItemLevel;
};
@@ -1943,7 +1943,7 @@ struct ItemBagFamilyEntry
struct ItemBonusEntry
{
uint32 ID;
- int32 Value[4];
+ std::array<int32, 4> Value;
uint16 ParentItemBonusListID;
uint8 Type;
uint8 OrderIndex;
@@ -2013,35 +2013,35 @@ struct ItemDamageAmmoEntry
{
uint32 ID;
uint16 ItemLevel;
- float Quality[7];
+ std::array<float, 7> Quality;
};
struct ItemDamageOneHandEntry
{
uint32 ID;
uint16 ItemLevel;
- float Quality[7];
+ std::array<float, 7> Quality;
};
struct ItemDamageOneHandCasterEntry
{
uint32 ID;
uint16 ItemLevel;
- float Quality[7];
+ std::array<float, 7> Quality;
};
struct ItemDamageTwoHandEntry
{
uint32 ID;
uint16 ItemLevel;
- float Quality[7];
+ std::array<float, 7> Quality;
};
struct ItemDamageTwoHandCasterEntry
{
uint32 ID;
uint16 ItemLevel;
- float Quality[7];
+ std::array<float, 7> Quality;
};
struct ItemDisenchantLootEntry
@@ -2081,10 +2081,10 @@ struct ItemExtendedCostEntry
uint8 MinFactionID;
uint8 MinReputation;
uint8 RequiredAchievement; // required personal arena rating
- int32 ItemID[MAX_ITEM_EXT_COST_ITEMS]; // required item id
- uint16 ItemCount[MAX_ITEM_EXT_COST_ITEMS]; // required count of 1st item
- uint16 CurrencyID[MAX_ITEM_EXT_COST_CURRENCIES]; // required curency id
- uint32 CurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES]; // required curency count
+ std::array<int32, MAX_ITEM_EXT_COST_ITEMS> ItemID; // required item id
+ std::array<uint16, MAX_ITEM_EXT_COST_ITEMS> ItemCount; // required count of 1st item
+ std::array<uint16, MAX_ITEM_EXT_COST_CURRENCIES> CurrencyID; // required curency id
+ std::array<uint32, MAX_ITEM_EXT_COST_CURRENCIES> CurrencyCount; // required curency count
};
struct ItemLevelSelectorEntry
@@ -2176,7 +2176,7 @@ struct ItemSearchNameEntry
uint16 RequiredSkillRank;
uint32 RequiredAbility;
uint16 ItemLevel;
- int32 Flags[4];
+ std::array<int32, 4> Flags;
};
#define MAX_ITEM_SET_ITEMS 17
@@ -2188,7 +2188,7 @@ struct ItemSetEntry
uint32 SetFlags;
uint32 RequiredSkill;
uint16 RequiredSkillRank;
- uint32 ItemID[MAX_ITEM_SET_ITEMS];
+ std::array<uint32, MAX_ITEM_SET_ITEMS> ItemID;
};
struct ItemSetSpellEntry
@@ -2216,8 +2216,8 @@ struct ItemSparseEntry
float QualityModifier;
uint32 BagFamily;
float ItemRange;
- float StatPercentageOfSocket[MAX_ITEM_PROTO_STATS];
- int32 StatPercentEditor[MAX_ITEM_PROTO_STATS];
+ std::array<float, MAX_ITEM_PROTO_STATS> StatPercentageOfSocket;
+ std::array<int32, MAX_ITEM_PROTO_STATS> StatPercentEditor;
int32 Stackable;
int32 MaxCount;
uint32 RequiredAbility;
@@ -2226,7 +2226,7 @@ struct ItemSparseEntry
uint32 VendorStackCount;
float PriceVariance;
float PriceRandomValue;
- int32 Flags[MAX_ITEM_PROTO_FLAGS];
+ std::array<int32, MAX_ITEM_PROTO_FLAGS> Flags;
int32 FactionRelated;
int32 ModifiedCraftingReagentItemID;
int32 ContentTuningID;
@@ -2238,7 +2238,7 @@ struct ItemSparseEntry
uint16 SocketMatchEnchantmentId;
uint16 TotemCategoryID;
uint16 InstanceBound;
- uint16 ZoneBound[MAX_ITEM_PROTO_ZONES];
+ std::array<uint16, MAX_ITEM_PROTO_ZONES> ZoneBound;
uint16 ItemSet;
uint16 LockID;
uint16 StartQuestID;
@@ -2252,14 +2252,14 @@ struct ItemSparseEntry
uint8 ArtifactID;
uint8 SpellWeight;
uint8 SpellWeightCategory;
- uint8 SocketType[MAX_ITEM_PROTO_SOCKETS];
+ std::array<uint8, MAX_ITEM_PROTO_SOCKETS> SocketType;
uint8 SheatheType;
uint8 Material;
uint8 PageMaterialID;
uint8 LanguageID;
uint8 Bonding;
uint8 DamageDamageType;
- int8 StatModifierBonusStat[MAX_ITEM_PROTO_STATS];
+ std::array<int8, MAX_ITEM_PROTO_STATS> StatModifierBonusStat;
uint8 ContainerSlots;
uint8 MinReputation;
uint8 RequiredPVPMedal;
@@ -2364,7 +2364,7 @@ struct JournalTierEntry
struct KeychainEntry
{
uint32 ID;
- uint8 Key[KEYCHAIN_SIZE];
+ std::array<uint8, KEYCHAIN_SIZE> Key;
};
struct KeystoneAffixEntry
@@ -2419,7 +2419,7 @@ struct LFGDungeonsEntry
uint16 MentorItemLevel;
uint8 MentorCharLevel;
int32 ContentTuningID;
- int32 Flags[2];
+ std::array<int32, 2> Flags;
// Helpers
uint32 Entry() const { return ID + (TypeID << 24); }
@@ -2432,14 +2432,14 @@ struct LightEntry
float GameFalloffStart;
float GameFalloffEnd;
int16 ContinentID;
- uint16 LightParamsID[8];
+ std::array<uint16, 8> LightParamsID;
};
struct LiquidTypeEntry
{
uint32 ID;
char const* Name;
- char const* Texture[6];
+ std::array<char, 6> const* Texture;
uint16 Flags;
uint8 SoundBank; // used to be "type", maybe needs fixing (works well for now)
uint32 SoundID;
@@ -2454,11 +2454,11 @@ struct LiquidTypeEntry
uint8 ParticleTexSlots;
uint8 MaterialID;
int32 MinimapStaticCol;
- uint8 FrameCountTexture[6];
- int32 Color[2];
- float Float[18];
- uint32 Int[4];
- float Coefficient[4];
+ std::array<uint8, 6> FrameCountTexture;
+ std::array<int32, 2> Color;
+ std::array<float, 18> Float;
+ std::array<uint32, 4> Int;
+ std::array<float, 4> Coefficient;
};
#define MAX_LOCK_CASE 8
@@ -2467,10 +2467,10 @@ struct LockEntry
{
uint32 ID;
int32 Flags;
- int32 Index[MAX_LOCK_CASE];
- uint16 Skill[MAX_LOCK_CASE];
- uint8 Type[MAX_LOCK_CASE];
- uint8 Action[MAX_LOCK_CASE];
+ std::array<int32, MAX_LOCK_CASE> Index;
+ std::array<uint16, MAX_LOCK_CASE> Skill;
+ std::array<uint8, MAX_LOCK_CASE> Type;
+ std::array<uint8, MAX_LOCK_CASE> Action;
};
struct MailTemplateEntry
@@ -2504,7 +2504,7 @@ struct MapEntry
int16 WindSettingsID;
int32 ZmpFileDataID;
int32 WdtFileDataID;
- int32 Flags[2];
+ std::array<int32, 2> Flags;
// Helpers
uint8 Expansion() const { return ExpansionID; }
@@ -2546,7 +2546,7 @@ struct MapChallengeModeEntry
uint8 Flags;
uint32 ExpansionLevel;
int32 RequiredWorldStateID; // maybe?
- int16 CriteriaCount[3];
+ std::array<int16, 3> CriteriaCount;
};
struct MapDifficultyEntry
@@ -2699,7 +2699,7 @@ struct NumTalentsAtLevelEntry
struct OverrideSpellDataEntry
{
uint32 ID;
- int32 Spells[MAX_OVERRIDE_SPELL];
+ std::array<int32, MAX_OVERRIDE_SPELL> Spells;
int32 PlayerActionBarFileDataID;
uint8 Flags;
};
@@ -2786,30 +2786,30 @@ struct PlayerConditionEntry
uint8 MaxPVPRank;
int32 ContentTuningID;
int32 CovenantID;
- uint16 SkillID[4];
- uint16 MinSkill[4];
- uint16 MaxSkill[4];
- uint32 MinFactionID[3];
- uint8 MinReputation[3];
- int32 PrevQuestID[4];
- int32 CurrQuestID[4];
- int32 CurrentCompletedQuestID[4];
- int32 SpellID[4];
- int32 ItemID[4];
- uint32 ItemCount[4];
- uint16 Explored[2];
- uint32 Time[2];
- int32 AuraSpellID[4];
- uint8 AuraStacks[4];
- uint16 Achievement[4];
- uint16 AreaID[4];
- uint8 LfgStatus[4];
- uint8 LfgCompare[4];
- uint32 LfgValue[4];
- uint32 CurrencyID[4];
- uint32 CurrencyCount[4];
- uint32 QuestKillMonster[6];
- int32 MovementFlags[2];
+ std::array<uint16, 4> SkillID;
+ std::array<uint16, 4> MinSkill;
+ std::array<uint16, 4> MaxSkill;
+ std::array<uint32, 3> MinFactionID;
+ std::array<uint8, 3> MinReputation;
+ std::array<int32, 4> PrevQuestID;
+ std::array<int32, 4> CurrQuestID;
+ std::array<int32, 4> CurrentCompletedQuestID;
+ std::array<int32, 4> SpellID;
+ std::array<int32, 4> ItemID;
+ std::array<uint32, 4> ItemCount;
+ std::array<uint16, 2> Explored;
+ std::array<uint32, 2> Time;
+ std::array<int32, 4> AuraSpellID;
+ std::array<uint8, 4> AuraStacks;
+ std::array<uint16, 4> Achievement;
+ std::array<uint16, 4> AreaID;
+ std::array<uint8, 4> LfgStatus;
+ std::array<uint8, 4> LfgCompare;
+ std::array<uint32, 4> LfgValue;
+ std::array<uint32, 4> CurrencyID;
+ std::array<uint32, 4> CurrencyCount;
+ std::array<uint32, 6> QuestKillMonster;
+ std::array<int32, 2> MovementFlags;
};
struct PowerDisplayEntry
@@ -2914,7 +2914,7 @@ struct PvpTierEntry
struct QuestFactionRewardEntry
{
uint32 ID;
- int16 Difficulty[10];
+ std::array<int16, 10> Difficulty;
};
struct QuestInfoEntry
@@ -2938,7 +2938,7 @@ struct QuestLineXQuestEntry
struct QuestMoneyRewardEntry
{
uint32 ID;
- uint32 Difficulty[10];
+ std::array<uint32, 10> Difficulty;
};
struct QuestPackageItemEntry
@@ -2966,7 +2966,7 @@ struct QuestV2Entry
struct QuestXPEntry
{
uint32 ID;
- uint16 Difficulty[10];
+ std::array<uint16, 10> Difficulty;
};
struct RandPropPointsEntry
@@ -2976,12 +2976,12 @@ struct RandPropPointsEntry
float DamageSecondaryF;
int32 DamageReplaceStat;
int32 DamageSecondary;
- float EpicF[5];
- float SuperiorF[5];
- float GoodF[5];
- uint32 Epic[5];
- uint32 Superior[5];
- uint32 Good[5];
+ std::array<float, 5> EpicF;
+ std::array<float, 5> SuperiorF;
+ std::array<float, 5> GoodF;
+ std::array<uint32, 5> Epic;
+ std::array<uint32, 5> Superior;
+ std::array<uint32, 5> Good;
};
struct RewardPackEntry
@@ -3177,7 +3177,7 @@ struct SpellAuraOptionsEntry
uint8 ProcChance;
int32 ProcCharges;
uint16 SpellProcsPerMinuteID;
- int32 ProcTypeMask[2];
+ std::array<int32, 2> ProcTypeMask;
uint32 SpellID;
};
@@ -3293,10 +3293,10 @@ struct SpellEffectEntry
float GroupSizeBasePointsCoefficient;
float EffectBasePoints;
int32 ScalingClass;
- int32 EffectMiscValue[2];
- uint32 EffectRadiusIndex[2];
+ std::array<int32, 2> EffectMiscValue;
+ std::array<uint32, 2> EffectRadiusIndex;
flag128 EffectSpellClassMask;
- int16 ImplicitTarget[2];
+ std::array<int16, 2> ImplicitTarget;
uint32 SpellID;
SpellEffectAttributes GetEffectAttributes() const { return static_cast<SpellEffectAttributes>(EffectAttributes); }
@@ -3322,8 +3322,8 @@ struct SpellInterruptsEntry
uint32 ID;
uint8 DifficultyID;
int16 InterruptFlags;
- int32 AuraInterruptFlags[MAX_SPELL_AURA_INTERRUPT_FLAGS];
- int32 ChannelInterruptFlags[MAX_SPELL_AURA_INTERRUPT_FLAGS];
+ std::array<int32, MAX_SPELL_AURA_INTERRUPT_FLAGS> AuraInterruptFlags;
+ std::array<int32, MAX_SPELL_AURA_INTERRUPT_FLAGS> ChannelInterruptFlags;
uint32 SpellID;
};
@@ -3334,21 +3334,21 @@ struct SpellItemEnchantmentEntry
uint32 ID;
LocalizedString Name;
LocalizedString HordeName;
- uint32 EffectArg[MAX_ITEM_ENCHANTMENT_EFFECTS];
- float EffectScalingPoints[MAX_ITEM_ENCHANTMENT_EFFECTS];
+ std::array<uint32, MAX_ITEM_ENCHANTMENT_EFFECTS> EffectArg;
+ std::array<float, MAX_ITEM_ENCHANTMENT_EFFECTS> EffectScalingPoints;
uint32 IconFileDataID;
int32 MinItemLevel;
int32 MaxItemLevel;
uint32 TransmogUseConditionID;
uint32 TransmogCost;
- int16 EffectPointsMin[MAX_ITEM_ENCHANTMENT_EFFECTS];
+ std::array<int16, MAX_ITEM_ENCHANTMENT_EFFECTS> EffectPointsMin;
uint16 ItemVisual;
uint16 Flags;
uint16 RequiredSkillID;
uint16 RequiredSkillRank;
uint16 ItemLevel;
uint8 Charges;
- uint8 Effect[MAX_ITEM_ENCHANTMENT_EFFECTS];
+ std::array<uint8, MAX_ITEM_ENCHANTMENT_EFFECTS> Effect;
int8 ScalingClass;
int8 ScalingClassRestricted;
uint8 ConditionID;
@@ -3361,12 +3361,12 @@ struct SpellItemEnchantmentEntry
struct SpellItemEnchantmentConditionEntry
{
uint32 ID;
- uint8 LtOperandType[5];
- uint32 LtOperand[5];
- uint8 Operator[5];
- uint8 RtOperandType[5];
- uint8 RtOperand[5];
- uint8 Logic[5];
+ std::array<uint8, 5> LtOperandType;
+ std::array<uint32, 5> LtOperand;
+ std::array<uint8, 5> Operator;
+ std::array<uint8, 5> RtOperandType;
+ std::array<uint8, 5> RtOperand;
+ std::array<uint8, 5> Logic;
};
struct SpellLabelEntry
@@ -3398,7 +3398,7 @@ struct SpellLevelsEntry
struct SpellMiscEntry
{
uint32 ID;
- int32 Attributes[15];
+ std::array<int32, 15> Attributes;
uint8 DifficultyID;
uint16 CastingTimeIndex;
uint16 DurationIndex;
@@ -3479,8 +3479,8 @@ struct SpellRangeEntry
LocalizedString DisplayName;
LocalizedString DisplayNameShort;
uint8 Flags;
- float RangeMin[2];
- float RangeMax[2];
+ std::array<float, 2> RangeMin;
+ std::array<float, 2> RangeMax;
};
#define MAX_SPELL_REAGENTS 8
@@ -3489,8 +3489,8 @@ struct SpellReagentsEntry
{
uint32 ID;
int32 SpellID;
- int32 Reagent[MAX_SPELL_REAGENTS];
- int16 ReagentCount[MAX_SPELL_REAGENTS];
+ std::array<int32, MAX_SPELL_REAGENTS> Reagent;
+ std::array<int16, MAX_SPELL_REAGENTS> ReagentCount;
};
struct SpellReagentsCurrencyEntry
@@ -3515,8 +3515,8 @@ struct SpellShapeshiftEntry
uint32 ID;
int32 SpellID;
int8 StanceBarOrder;
- int32 ShapeshiftExclude[2];
- int32 ShapeshiftMask[2];
+ std::array<int32, 2> ShapeshiftExclude;
+ std::array<int32, 2> ShapeshiftMask;
};
#define MAX_SHAPESHIFT_SPELLS 8
@@ -3532,8 +3532,8 @@ struct SpellShapeshiftFormEntry
int16 CombatRoundTime;
float DamageVariance;
uint16 MountTypeID;
- uint32 CreatureDisplayID[4];
- uint32 PresetSpellID[MAX_SHAPESHIFT_SPELLS];
+ std::array<uint32, 4> CreatureDisplayID;
+ std::array<uint32, MAX_SHAPESHIFT_SPELLS> PresetSpellID;
EnumFlag<SpellShapeshiftFormFlags> GetFlags() const { return static_cast<SpellShapeshiftFormFlags>(Flags); }
};
@@ -3557,15 +3557,15 @@ struct SpellTotemsEntry
{
uint32 ID;
int32 SpellID;
- uint16 RequiredTotemCategoryID[MAX_SPELL_TOTEMS];
- int32 Totem[MAX_SPELL_TOTEMS];
+ std::array<uint16, MAX_SPELL_TOTEMS> RequiredTotemCategoryID;
+ std::array<int32, MAX_SPELL_TOTEMS> Totem;
};
struct SpellVisualEntry
{
uint32 ID;
- float MissileCastOffset[3];
- float MissileImpactOffset[3];
+ std::array<float, 3> MissileCastOffset;
+ std::array<float, 3> MissileImpactOffset;
uint32 AnimEventSoundID;
int32 Flags;
int8 MissileAttachment;
@@ -3604,8 +3604,8 @@ struct SpellVisualEffectNameEntry
struct SpellVisualMissileEntry
{
- float CastOffset[3];
- float ImpactOffset[3];
+ std::array<float, 3> CastOffset;
+ std::array<float, 3> ImpactOffset;
uint32 ID;
uint16 SpellVisualEffectNameID;
uint32 SoundEntriesID;
@@ -3631,7 +3631,7 @@ struct SpellVisualKitEntry
int32 FallbackSpellVisualKitId;
uint16 DelayMin;
uint16 DelayMax;
- int32 Flags[2];
+ std::array<int32, 2> Flags;
};
struct SpellXSpellVisualEntry
@@ -3667,7 +3667,7 @@ struct SummonPropertiesEntry
struct TactKeyEntry
{
uint32 ID;
- uint8 Key[TACTKEY_SIZE];
+ std::array<uint8, TACTKEY_SIZE> Key;
};
struct TalentEntry
@@ -3681,7 +3681,7 @@ struct TalentEntry
uint16 SpecID;
uint32 SpellID;
uint32 OverridesSpellID;
- uint8 CategoryMask[2];
+ std::array<uint8, 2> CategoryMask;
};
struct TaxiNodesEntry
@@ -3700,7 +3700,7 @@ struct TaxiNodesEntry
float Facing;
uint32 SpecialIconConditionID;
uint32 VisibilityConditionID;
- int32 MountCreatureID[2];
+ std::array<int32, 2> MountCreatureID;
};
struct TaxiPathEntry
@@ -3799,7 +3799,7 @@ struct TransportAnimationEntry
struct TransportRotationEntry
{
uint32 ID;
- float Rot[4];
+ std::array<float, 4> Rot;
uint32 TimeIndex;
uint32 GameObjectsID;
};
@@ -3827,7 +3827,7 @@ struct UiMapAssignmentEntry
{
DBCPosition2D UiMin;
DBCPosition2D UiMax;
- DBCPosition3D Region[2];
+ std::array<DBCPosition3D, 2> Region;
uint32 ID;
int32 UiMapID;
int32 OrderIndex;
@@ -3884,9 +3884,9 @@ struct UnitConditionEntry
{
uint32 ID;
uint8 Flags;
- uint8 Variable[MAX_UNIT_CONDITION_VALUES];
- int8 Op[MAX_UNIT_CONDITION_VALUES];
- int32 Value[MAX_UNIT_CONDITION_VALUES];
+ std::array<uint8, MAX_UNIT_CONDITION_VALUES> Variable;
+ std::array<int8, MAX_UNIT_CONDITION_VALUES> Op;
+ std::array<int32, MAX_UNIT_CONDITION_VALUES> Value;
EnumFlag<UnitConditionFlags> GetFlags() const { return static_cast<UnitConditionFlags>(Flags); }
};
@@ -3908,8 +3908,8 @@ struct UnitPowerBarEntry
uint16 Flags;
float StartInset;
float EndInset;
- int32 FileDataID[6];
- int32 Color[6];
+ std::array<int32, 6> FileDataID;
+ std::array<int32, 6> Color;
};
#define MAX_VEHICLE_SEATS 8
@@ -3933,8 +3933,8 @@ struct VehicleEntry
uint16 VehicleUIIndicatorID;
int32 MissileTargetingID;
uint16 VehiclePOITypeID;
- uint16 SeatID[8];
- uint16 PowerDisplayID[3];
+ std::array<uint16, 8> SeatID;
+ std::array<uint16, 3> PowerDisplayID;
};
struct VehicleSeatEntry
@@ -4061,7 +4061,7 @@ struct WorldMapOverlayEntry
int32 HitRectRight;
uint32 PlayerConditionID;
uint32 Flags;
- uint32 AreaID[MAX_WORLD_MAP_OVERLAY_AREA_IDX];
+ std::array<uint32, MAX_WORLD_MAP_OVERLAY_AREA_IDX> AreaID;
};
struct WorldStateExpressionEntry
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 8912559e0f0..a137f4219fb 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -2812,7 +2812,7 @@ void BonusData::AddBonusList(uint32 bonusListId)
AddBonus(bonus->Type, bonus->Value);
}
-void BonusData::AddBonus(uint32 type, int32 const (&values)[4])
+void BonusData::AddBonus(uint32 type, std::array<int32, 4> const& values)
{
switch (type)
{
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index a53a7c0f8b3..d04676920eb 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -97,7 +97,7 @@ struct BonusData
void Initialize(ItemTemplate const* proto);
void Initialize(WorldPackets::Item::ItemInstance const& itemInstance);
void AddBonusList(uint32 bonusListId);
- void AddBonus(uint32 type, int32 const (&values)[4]);
+ void AddBonus(uint32 type, std::array<int32, 4> const& values);
private:
struct
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 3b6d5c29153..45213a1e214 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -7596,7 +7596,7 @@ void ObjectMgr::LoadGameObjectTemplate()
go.name = db2go->Name[sWorld->GetDefaultDbcLocale()];
go.size = db2go->Scale;
memset(go.raw.data, 0, sizeof(go.raw.data));
- memcpy(go.raw.data, db2go->PropValue, std::min(sizeof(db2go->PropValue), sizeof(go.raw.data)));
+ std::copy(db2go->PropValue.begin(), db2go->PropValue.end(), std::begin(go.raw.data));
go.ContentTuningId = 0;
go.ScriptId = 0;
}
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index d792c8057a0..f6b87135126 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -216,8 +216,8 @@ uint32 SpellImplicitTargetInfo::GetExplicitTargetMask(bool& srcSet, bool& dstSet
return targetMask;
}
-SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_TARGETS] =
-{
+std::array<SpellImplicitTargetInfo::StaticData, TOTAL_SPELL_TARGETS> SpellImplicitTargetInfo::_data =
+{ {
{TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, //
{TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 1 TARGET_UNIT_CASTER
{TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_NEARBY, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 2 TARGET_UNIT_NEARBY_ENEMY
@@ -370,7 +370,7 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_T
{TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_RANDOM}, // 149
{TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 150 TARGET_UNIT_OWN_CRITTER
{TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_ENEMY, TARGET_DIR_NONE}, // 151
-};
+} };
SpellEffectInfo::SpellEffectInfo(SpellInfo const* spellInfo, SpellEffectEntry const& _effect)
: EffectAttributes(SpellEffectAttributes::None)
@@ -781,8 +781,8 @@ ExpectedStatType SpellEffectInfo::GetScalingExpectedStat() const
return ExpectedStatType::None;
}
-SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
-{
+std::array<SpellEffectInfo::StaticData, TOTAL_SPELL_EFFECTS> SpellEffectInfo::_data =
+{ {
// implicit target type used target object type
{EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 0
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL
@@ -1072,7 +1072,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 285 SPELL_EFFECT_MODIFY_KEYSTONE_2
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 284 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE
{EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 285 SPELL_EFFECT_SET_GARRISON_FOLLOWER_LEVEL
-};
+} };
SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, SpellInfoLoadHelper const& data)
: Id(spellName->ID), Difficulty(difficulty)
@@ -1230,8 +1230,8 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S
// SpellReagentsEntry
if (SpellReagentsEntry const* _reagents = data.Reagents)
{
- std::copy(std::begin(_reagents->Reagent), std::end(_reagents->Reagent), Reagent.begin());
- std::copy(std::begin(_reagents->ReagentCount), std::end(_reagents->ReagentCount), ReagentCount.begin());
+ Reagent = _reagents->Reagent;
+ ReagentCount = _reagents->ReagentCount;
}
ReagentsCurrency = data.ReagentsCurrency;
@@ -1257,8 +1257,8 @@ SpellInfo::SpellInfo(SpellNameEntry const* spellName, ::Difficulty difficulty, S
// SpellTotemsEntry
if (SpellTotemsEntry const* _totem = data.Totems)
{
- std::copy(std::begin(_totem->RequiredTotemCategoryID), std::end(_totem->RequiredTotemCategoryID), TotemCategory.begin());
- std::copy(std::begin(_totem->Totem), std::end(_totem->Totem), Totem.begin());
+ TotemCategory = _totem->RequiredTotemCategoryID;
+ Totem = _totem->Totem;
}
_visuals = data.Visuals;
@@ -3497,9 +3497,9 @@ void SpellInfo::_LoadImmunityInfo()
void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& spellEffectInfo, bool apply) const
{
- ImmunityInfo const* immuneInfo = spellEffectInfo.GetImmunityInfo();
+ ImmunityInfo const& immuneInfo = spellEffectInfo.GetImmunityInfo();
- if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
+ if (uint32 schoolImmunity = immuneInfo.SchoolImmuneMask)
{
target->ApplySpellImmune(Id, IMMUNITY_SCHOOL, schoolImmunity, apply);
@@ -3520,7 +3520,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s
target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::InvulnerabilityBuff);
}
- if (uint32 mechanicImmunity = immuneInfo->MechanicImmuneMask)
+ if (uint32 mechanicImmunity = immuneInfo.MechanicImmuneMask)
{
for (uint32 i = 0; i < MAX_MECHANIC; ++i)
if (mechanicImmunity & (1 << i))
@@ -3530,7 +3530,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s
target->RemoveAurasWithMechanic(mechanicImmunity, AURA_REMOVE_BY_DEFAULT, Id);
}
- if (uint32 dispelImmunity = immuneInfo->DispelImmune)
+ if (uint32 dispelImmunity = immuneInfo.DispelImmune)
{
target->ApplySpellImmune(Id, IMMUNITY_DISPEL, dispelImmunity, apply);
@@ -3547,7 +3547,7 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s
}
}
- if (uint32 damageImmunity = immuneInfo->DamageSchoolMask)
+ if (uint32 damageImmunity = immuneInfo.DamageSchoolMask)
{
target->ApplySpellImmune(Id, IMMUNITY_DAMAGE, damageImmunity, apply);
@@ -3555,14 +3555,14 @@ void SpellInfo::ApplyAllSpellImmunitiesTo(Unit* target, SpellEffectInfo const& s
target->RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::InvulnerabilityBuff);
}
- for (AuraType auraType : immuneInfo->AuraTypeImmune)
+ for (AuraType auraType : immuneInfo.AuraTypeImmune)
{
target->ApplySpellImmune(Id, IMMUNITY_STATE, auraType, apply);
if (apply && HasAttribute(SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY))
target->RemoveAurasByType(auraType);
}
- for (SpellEffectName effectType : immuneInfo->SpellEffectImmune)
+ for (SpellEffectName effectType : immuneInfo.SpellEffectImmune)
target->ApplySpellImmune(Id, IMMUNITY_EFFECT, effectType, apply);
}
@@ -3576,20 +3576,20 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
if (!effectInfo.IsEffect())
continue;
- ImmunityInfo const* immuneInfo = effectInfo.GetImmunityInfo();
+ ImmunityInfo const& immuneInfo = effectInfo.GetImmunityInfo();
if (!auraSpellInfo->HasAttribute(SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
{
- if (uint32 schoolImmunity = immuneInfo->SchoolImmuneMask)
+ if (uint32 schoolImmunity = immuneInfo.SchoolImmuneMask)
if ((auraSpellInfo->SchoolMask & schoolImmunity) != 0)
return true;
}
- if (uint32 mechanicImmunity = immuneInfo->MechanicImmuneMask)
+ if (uint32 mechanicImmunity = immuneInfo.MechanicImmuneMask)
if ((mechanicImmunity & (1 << auraSpellInfo->Mechanic)) != 0)
return true;
- if (uint32 dispelImmunity = immuneInfo->DispelImmune)
+ if (uint32 dispelImmunity = immuneInfo.DispelImmune)
if (auraSpellInfo->Dispel == dispelImmunity)
return true;
@@ -3599,8 +3599,8 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
if (!auraSpellEffectInfo.IsEffect())
continue;
- auto spellImmuneItr = immuneInfo->SpellEffectImmune.find(auraSpellEffectInfo.Effect);
- if (spellImmuneItr == immuneInfo->SpellEffectImmune.cend())
+ auto spellImmuneItr = immuneInfo.SpellEffectImmune.find(auraSpellEffectInfo.Effect);
+ if (spellImmuneItr == immuneInfo.SpellEffectImmune.cend())
{
immuneToAllEffects = false;
break;
@@ -3608,7 +3608,7 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
if (uint32 mechanic = auraSpellEffectInfo.Mechanic)
{
- if (!(immuneInfo->MechanicImmuneMask & (1 << mechanic)))
+ if (!(immuneInfo.MechanicImmuneMask & (1 << mechanic)))
{
immuneToAllEffects = false;
break;
@@ -3620,13 +3620,13 @@ bool SpellInfo::CanSpellProvideImmunityAgainstAura(SpellInfo const* auraSpellInf
if (AuraType auraName = auraSpellEffectInfo.ApplyAuraName)
{
bool isImmuneToAuraEffectApply = false;
- auto auraImmuneItr = immuneInfo->AuraTypeImmune.find(auraName);
- if (auraImmuneItr != immuneInfo->AuraTypeImmune.cend())
+ auto auraImmuneItr = immuneInfo.AuraTypeImmune.find(auraName);
+ if (auraImmuneItr != immuneInfo.AuraTypeImmune.cend())
isImmuneToAuraEffectApply = true;
if (!isImmuneToAuraEffectApply && !auraSpellInfo->IsPositiveEffect(auraSpellEffectInfo.EffectIndex) && !auraSpellInfo->HasAttribute(SPELL_ATTR2_UNAFFECTED_BY_AURA_SCHOOL_IMMUNE))
{
- if (uint32 applyHarmfulAuraImmunityMask = immuneInfo->ApplyHarmfulAuraImmuneMask)
+ if (uint32 applyHarmfulAuraImmunityMask = immuneInfo.ApplyHarmfulAuraImmuneMask)
if ((auraSpellInfo->GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
isImmuneToAuraEffectApply = true;
}
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 420155343e0..2012b9b3a63 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -209,7 +209,7 @@ private:
SpellTargetCheckTypes SelectionCheckType; // defines selection criteria
SpellTargetDirectionTypes DirectionType; // direction for cone and dest targets
};
- static StaticData _data[TOTAL_SPELL_TARGETS];
+ static std::array<StaticData, TOTAL_SPELL_TARGETS> _data;
};
struct TC_GAME_API ImmunityInfo
@@ -295,7 +295,7 @@ public:
SpellTargetObjectTypes GetUsedTargetObjectType() const;
ExpectedStatType GetScalingExpectedStat() const;
- ImmunityInfo const* GetImmunityInfo() const { return &_immunityInfo; }
+ ImmunityInfo const& GetImmunityInfo() const { return _immunityInfo; }
private:
struct StaticData
@@ -306,7 +306,7 @@ private:
SpellEffectImplicitTargetTypes ImplicitTargetType; // defines what target can be added to effect target list if there's no valid target type provided for effect
SpellTargetObjectTypes UsedTargetObjectType; // defines valid target object type for spell effect
};
- static StaticData _data[TOTAL_SPELL_EFFECTS];
+ static std::array<StaticData, TOTAL_SPELL_EFFECTS> _data;
ImmunityInfo _immunityInfo;
};
@@ -398,10 +398,10 @@ class TC_GAME_API SpellInfo
float Speed = 0.0f;
float LaunchDelay = 0.0f;
uint32 StackAmount = 0;
- std::array<uint32, MAX_SPELL_TOTEMS> Totem = {};
- std::array<uint32, MAX_SPELL_TOTEMS> TotemCategory = {};
+ std::array<int32, MAX_SPELL_TOTEMS> Totem = {};
+ std::array<uint16, MAX_SPELL_TOTEMS> TotemCategory = {};
std::array<int32, MAX_SPELL_REAGENTS> Reagent = {};
- std::array<uint32, MAX_SPELL_REAGENTS> ReagentCount = {};
+ std::array<int16, MAX_SPELL_REAGENTS> ReagentCount = {};
std::vector<SpellReagentsCurrencyEntry const*> ReagentsCurrency;
int32 EquippedItemClass = -1;
int32 EquippedItemSubClassMask = 0;
diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h
index c69a44028b7..51f223a5a30 100644
--- a/src/server/shared/DataStores/DB2Store.h
+++ b/src/server/shared/DataStores/DB2Store.h
@@ -126,6 +126,8 @@ private:
T** AsT;
char** AsChar;
} _indexTable;
+
+ friend class UnitTestDataLoader;
};
#endif
diff --git a/tests/DummyData.cpp b/tests/DummyData.cpp
index e5d0427e908..4d89a2b02aa 100644
--- a/tests/DummyData.cpp
+++ b/tests/DummyData.cpp
@@ -17,6 +17,7 @@
#include "DummyData.h"
+#include "DB2Stores.h"
#include "ItemDefines.h"
#include "ItemTemplate.h"
#include "ObjectMgr.h"
@@ -56,3 +57,23 @@
const_cast<ItemSparseEntry*>(t.ExtendedData)->OverallQualityID = ITEM_QUALITY_NORMAL;
SetItemLocale(6948, LOCALE_esMX, "Piedra de hogar");
}
+
+static UnitTestDataLoader::DB2<AchievementEntry, &AchievementEntry::ID> achievements(sAchievementStore);
+/*static*/ void UnitTestDataLoader::LoadAchievementTemplates()
+{
+ auto loader = achievements.Loader();
+
+ AchievementEntry& toc5 = loader.Add();
+ toc5.ID = 4298;
+ toc5.Faction = 1;
+ toc5.InstanceID = 650;
+ toc5.Title.Str.fill("");
+ toc5.Title.Str[LOCALE_enUS] = "Heroic: Trial of the Champion";
+ toc5.Title.Str[LOCALE_esES] = "Heroico: Prueba del Campe\xc3\xb3n";
+ toc5.Title.Str[LOCALE_esMX] = "Heroico: Prueba del Campe\xc3\xb3n";
+ toc5.Category = 14921;
+ toc5.Points = 10;
+ toc5.Flags = 0;
+ toc5.MinimumCriteria = 0;
+ toc5.SharesCriteria = 0;
+}
diff --git a/tests/DummyData.h b/tests/DummyData.h
index 98812d3b6b8..35ec4d62e86 100644
--- a/tests/DummyData.h
+++ b/tests/DummyData.h
@@ -20,6 +20,7 @@
#include "Common.h"
#include "Define.h"
+#include "DB2Store.h"
#include <string_view>
@@ -28,6 +29,42 @@ struct ItemTemplate;
class UnitTestDataLoader
{
public:
+ template <typename T, uint32 T::*ID>
+ class DB2
+ {
+ class LoaderGuard
+ {
+ public:
+ LoaderGuard(DB2& d) : _d(d) {}
+ ~LoaderGuard() { _d.Dump(); }
+
+ T& Add() { return _d._storage.emplace_back(); }
+ private:
+ DB2& _d;
+ };
+
+ public:
+ DB2(DB2Storage<T>& store) : _store(store) {}
+ LoaderGuard Loader() { return {*this}; }
+ void Dump()
+ {
+ delete[] _store._indexTable.AsT;
+ for (T const& entry : _storage)
+ if (entry.*ID >= _store._indexTableSize)
+ _store._indexTableSize = entry.*ID + 1;
+ _store._indexTable.AsT = new T*[_store._indexTableSize];
+ for (size_t i = 0; i < _store._indexTableSize; ++i)
+ _store._indexTable.AsT[i] = nullptr;
+ for (T& entry : _storage)
+ _store._indexTable.AsT[entry.*ID] = &entry;
+ }
+
+ private:
+ std::vector<T> _storage;
+ DB2Storage<T>& _store;
+ };
+
+ static void LoadAchievementTemplates();
static void LoadItemTemplates();
private:
diff --git a/tests/game/Hyperlinks.cpp b/tests/game/Hyperlinks.cpp
index 7a1c3821a2c..a4f01a37992 100644
--- a/tests/game/Hyperlinks.cpp
+++ b/tests/game/Hyperlinks.cpp
@@ -72,3 +72,21 @@ TEST_CASE("|Hitem validation", "[Hyperlinks]")
REQUIRE(false == CheckAllLinks("This is a |cffffffff|Hitem:6948:-1:::::::60:::::|h[Hearthstone]|h|r that is quite negative."));
}
}
+
+TEST_CASE("|Hachievement validation", "[Hyperlinks]")
+{
+ UnitTestDataLoader::LoadAchievementTemplates();
+ sWorld->setIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY, 1);
+
+ REQUIRE(true == CheckAllLinks("|cffffff00|Hachievement:4298:Player-0-000000FD:0:0:0:-1:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(false == CheckAllLinks("|cffffff00|Hachievement|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(false == CheckAllLinks("|cffffff00|Hachievement:1:Player-0-000000FD:0:0:0:-1:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(false == CheckAllLinks("|cffff0000|Hachievement:4298:Player-0-000000FD:0:0:0:-1:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(false == CheckAllLinks("|cffffff00|Hachievement:4298:00000000000000XY:0:0:0:-1:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(true == CheckAllLinks("|cffffff00|Hachievement:4298:Player-0-000000FD:1:12:20:12:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(false == CheckAllLinks("|cffffff00|Hachievement:4298:Player-0-000000FD:1:12:40:12:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(false == CheckAllLinks("|cffffff00|Hachievement:4298:Player-0-000000FD:1:14:20:12:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+ REQUIRE(false == CheckAllLinks("|cffffff00|Hachievement:4298:Player-0-000000FD:1:0:0:-1:0:0:0:0|h[Heroic: Trial of the Champion]|h|r"));
+
+ REQUIRE(true == CheckAllLinks("|cffffff00|Hachievement:4298:Player-0-000000FD:1:12:20:12:0:0:0:0|h[Heroico: Prueba del Campe\xc3\xb3n]|h|r"));
+}