diff --git a/Source/Framework/Database/Databases/HotfixDatabase.cs b/Source/Framework/Database/Databases/HotfixDatabase.cs index 3c4365f37..fac97ffce 100644 --- a/Source/Framework/Database/Databases/HotfixDatabase.cs +++ b/Source/Framework/Database/Databases/HotfixDatabase.cs @@ -988,6 +988,9 @@ namespace Framework.Database "RtOperandType1, RtOperandType2, RtOperandType3, RtOperandType4, RtOperandType5, RtOperand1, RtOperand2, RtOperand3, RtOperand4, RtOperand5, " + "Logic1, Logic2, Logic3, Logic4, Logic5 FROM spell_item_enchantment_condition"); + // SpellLabel.db2 + PrepareStatement(HotfixStatements.SEL_SPELL_LABEL, "SELECT ID, LabelID, SpellID FROM spell_label"); + // SpellLearnSpell.db2 PrepareStatement(HotfixStatements.SEL_SPELL_LEARN_SPELL, "SELECT ID, SpellID, LearnSpellID, OverridesSpellID FROM spell_learn_spell"); @@ -1693,6 +1696,8 @@ namespace Framework.Database SEL_SPELL_ITEM_ENCHANTMENT_CONDITION, + SEL_SPELL_LABEL, + SEL_SPELL_LEARN_SPELL, SEL_SPELL_LEVELS, diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 929919771..cd5839163 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -277,6 +277,7 @@ namespace Game.DataStorage SpellInterruptsStorage = ReadDB2("SpellInterrupts.db2", HotfixStatements.SEL_SPELL_INTERRUPTS); SpellItemEnchantmentStorage = ReadDB2("SpellItemEnchantment.db2", HotfixStatements.SEL_SPELL_ITEM_ENCHANTMENT, HotfixStatements.SEL_SPELL_ITEM_ENCHANTMENT_LOCALE); SpellItemEnchantmentConditionStorage = ReadDB2("SpellItemEnchantmentCondition.db2", HotfixStatements.SEL_SPELL_ITEM_ENCHANTMENT_CONDITION); + SpellLabelStorage = ReadDB2("SpellLabel.db2", HotfixStatements.SEL_SPELL_LABEL); SpellLearnSpellStorage = ReadDB2("SpellLearnSpell.db2", HotfixStatements.SEL_SPELL_LEARN_SPELL); SpellLevelsStorage = ReadDB2("SpellLevels.db2", HotfixStatements.SEL_SPELL_LEVELS); SpellMiscStorage = ReadDB2("SpellMisc.db2", HotfixStatements.SEL_SPELL_MISC); @@ -642,6 +643,7 @@ namespace Game.DataStorage public static DB6Storage SpellInterruptsStorage; public static DB6Storage SpellItemEnchantmentStorage; public static DB6Storage SpellItemEnchantmentConditionStorage; + public static DB6Storage SpellLabelStorage; public static DB6Storage SpellLearnSpellStorage; public static DB6Storage SpellLevelsStorage; public static DB6Storage SpellMiscStorage; diff --git a/Source/Game/DataStorage/Structs/S_Records.cs b/Source/Game/DataStorage/Structs/S_Records.cs index 467fac714..4bb427b17 100644 --- a/Source/Game/DataStorage/Structs/S_Records.cs +++ b/Source/Game/DataStorage/Structs/S_Records.cs @@ -359,6 +359,13 @@ namespace Game.DataStorage public byte[] Logic = new byte[5]; } + public sealed class SpellLabelRecord + { + public uint Id; + public uint LabelID; + public int SpellID; + } + public sealed class SpellLearnSpellRecord { public uint Id; diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index d2bfb028f..d15b0cce8 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -31,7 +31,7 @@ namespace Game.Spells { public class SpellInfo { - public SpellInfo(SpellNameRecord spellName, Difficulty difficulty, SpellInfoLoadHelper data, List visuals) + public SpellInfo(SpellNameRecord spellName, Difficulty difficulty, SpellInfoLoadHelper data, List labels, List visuals) { Id = spellName.Id; Difficulty = difficulty; @@ -185,6 +185,9 @@ namespace Game.Spells ChannelInterruptFlags2 = (SpellAuraInterruptFlags2)_interrupt.ChannelInterruptFlags[1]; } + foreach (var label in labels) + Labels.Add(label.LabelID); + // SpellLevelsEntry SpellLevelsRecord _levels = data.Levels; if (_levels != null) @@ -3555,6 +3558,11 @@ namespace Game.Spells var playerCondition = CliDB.PlayerConditionStorage.LookupByKey(ShowFutureSpellPlayerConditionID); return playerCondition == null || ConditionManager.IsPlayerMeetingCondition(player, playerCondition); } + + public bool HasLabel(uint labelId) + { + return Labels.Contains(labelId); + } public static SpellCastTargetFlags GetTargetFlagMask(SpellTargetObjectTypes objType) { @@ -3724,6 +3732,8 @@ namespace Game.Spells public int RequiredAreasID { get; set; } public SpellSchoolMask SchoolMask { get; set; } public uint ChargeCategoryId; + public List Labels = new(); + // SpellScalingEntry public ScalingInfo Scaling; public uint ExplicitTargetMask { get; set; } diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index f348a7d72..45dc1b462 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -2217,6 +2217,9 @@ namespace Game.Entities foreach (SpellInterruptsRecord interrupts in CliDB.SpellInterruptsStorage.Values) GetLoadHelper(interrupts.SpellID, interrupts.DifficultyID).Interrupts = interrupts; + foreach (SpellLabelRecord label in CliDB.SpellLabelStorage.Values) + GetLoadHelper(label.LabelID, 0).Labels.Add(label); + foreach (SpellLevelsRecord levels in CliDB.SpellLevelsStorage.Values) GetLoadHelper(levels.SpellID, levels.DifficultyID).Levels = levels; @@ -2270,7 +2273,8 @@ namespace Game.Entities if (spellNameEntry == null) continue; - var visuals = data.Value.Visuals; // copy, need to ensure source remains unmodified + var labels = new List(data.Value.Labels); // copy, need to ensure source remains unmodified + var visuals = new List(data.Value.Visuals); // copy, need to ensure source remains unmodified // fill blanks DifficultyRecord difficultyEntry = CliDB.DifficultyStorage.LookupByKey(data.Key.difficulty); @@ -2300,6 +2304,8 @@ namespace Game.Entities if (data.Value.Interrupts == null) data.Value.Interrupts = fallbackData.Interrupts; + labels.AddRange(fallbackData.Labels); + if (data.Value.Levels == null) data.Value.Levels = fallbackData.Levels; @@ -2324,7 +2330,7 @@ namespace Game.Entities //second key = id - mSpellInfoMap.Add(spellNameEntry.Id, new SpellInfo(spellNameEntry, data.Key.difficulty, data.Value, visuals)); + mSpellInfoMap.Add(spellNameEntry.Id, new SpellInfo(spellNameEntry, data.Key.difficulty, data.Value, labels, visuals)); } Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo store in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime)); @@ -3999,6 +4005,7 @@ namespace Game.Entities public SpellEffectRecord[] Effects = new SpellEffectRecord[SpellConst.MaxEffects]; public SpellEquippedItemsRecord EquippedItems; public SpellInterruptsRecord Interrupts; + public List Labels = new(); public SpellLevelsRecord Levels; public SpellMiscRecord Misc; public SpellPowerRecord[] Powers = new SpellPowerRecord[SpellConst.MaxPowersPerSpell]; diff --git a/sql/updates/hotfixes/master/2021_06_04_01_hotfixes.sql b/sql/updates/hotfixes/master/2021_06_04_01_hotfixes.sql new file mode 100644 index 000000000..c0c6e8a73 --- /dev/null +++ b/sql/updates/hotfixes/master/2021_06_04_01_hotfixes.sql @@ -0,0 +1,14 @@ +-- +-- Table structure for table `spell_label` +-- +DROP TABLE IF EXISTS `spell_label`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `spell_label` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `LabelID` int(10) unsigned NOT NULL DEFAULT '0', + `SpellID` int(11) NOT NULL DEFAULT '0', + `VerifiedBuild` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`VerifiedBuild`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */;