diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index 0c7b400c2..8a611df3b 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -1945,4 +1945,10 @@ namespace Framework.Constants Max, } + + public enum CorruptionEffectsFlag + { + None = 0, + Disabled = 0x1 + } } diff --git a/Source/Framework/Constants/ItemConst.cs b/Source/Framework/Constants/ItemConst.cs index 21d21395c..3a73f5b99 100644 --- a/Source/Framework/Constants/ItemConst.cs +++ b/Source/Framework/Constants/ItemConst.cs @@ -203,8 +203,8 @@ namespace Framework.Constants CritMeleeRating = 19, CritRangedRating = 20, CritSpellRating = 21, - HitTakenMeleeRating = 22, - HitTakenRangedRating = 23, + Corruption = 22, + CorruptionResistance = 23, HitTakenSpellRating = 24, CritTakenMeleeRating = 25, CritTakenRangedRating = 26, @@ -239,15 +239,15 @@ namespace Framework.Constants NatureResistance = 55, ArcaneResistance = 56, PvpPower = 57, - CrAmplify = 58, - CrMultistrike = 59, - CrReadiness = 60, + Unused0 = 58, + Unused1 = 59, + Unused3 = 60, CrSpeed = 61, CrLifesteal = 62, CrAvoidance = 63, CrSturdiness = 64, CrUnused7 = 65, - CrCleave = 66, + Unused27 = 66, CrUnused9 = 67, CrUnused10 = 68, CrUnused11 = 69, diff --git a/Source/Framework/Constants/UnitConst.cs b/Source/Framework/Constants/UnitConst.cs index fa5b7c38c..968c92ff0 100644 --- a/Source/Framework/Constants/UnitConst.cs +++ b/Source/Framework/Constants/UnitConst.cs @@ -401,8 +401,8 @@ namespace Framework.Constants CritMelee = 8, CritRanged = 9, CritSpell = 10, - Multistrike = 11, - Readiness = 12, + Corruption = 11, + CorruptionResistance = 12, Speed = 13, ResilienceCritTaken = 14, ResiliencePlayerDamage = 15, diff --git a/Source/Framework/Database/Databases/HotfixDatabase.cs b/Source/Framework/Database/Databases/HotfixDatabase.cs index eefcb76b4..a04f121f4 100644 --- a/Source/Framework/Database/Databases/HotfixDatabase.cs +++ b/Source/Framework/Database/Databases/HotfixDatabase.cs @@ -257,6 +257,9 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_CONVERSATION_LINE, "SELECT ID, BroadcastTextID, SpellVisualKitID, AdditionalDuration, NextConversationLineID, " + "AnimKitID, SpeechType, StartAnimation, EndAnimation FROM conversation_line"); + // CorruptionEffects.db2 + PrepareStatement(HotfixStatements.SEL_CORRUPTION_EFFECTS, "SELECT ID, MinCorruption, Aura, PlayerConditionID, Flags FROM corruption_effects"); + // CreatureDisplayInfo.db2 PrepareStatement(HotfixStatements.SEL_CREATURE_DISPLAY_INFO, "SELECT ID, ModelID, SoundID, SizeClass, CreatureModelScale, CreatureModelAlpha, BloodID, " + "ExtendedDisplayInfoID, NPCSoundID, ParticleColorID, PortraitCreatureDisplayInfoID, PortraitTextureFileDataID, ObjectEffectPackageID, " + @@ -1260,6 +1263,8 @@ namespace Framework.Database SEL_CONVERSATION_LINE, + SEL_CORRUPTION_EFFECTS, + SEL_CREATURE_DISPLAY_INFO, SEL_CREATURE_DISPLAY_INFO_EXTRA, diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 66f2f20f2..731771688 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -91,6 +91,7 @@ namespace Game.DataStorage ContentTuningStorage = DBReader.Read("ContentTuning.db2", HotfixStatements.SEL_CONTENT_TUNING); ContentTuningXExpectedStorage = DBReader.Read("ContentTuningXExpected.db2", HotfixStatements.SEL_CONTENT_TUNING_X_EXPECTED); ConversationLineStorage = DBReader.Read("ConversationLine.db2", HotfixStatements.SEL_CONVERSATION_LINE); + CorruptionEffectsStorage = DBReader.Read("CorruptionEffects.db2", HotfixStatements.SEL_CORRUPTION_EFFECTS); CreatureDisplayInfoStorage = DBReader.Read("CreatureDisplayInfo.db2", HotfixStatements.SEL_CREATURE_DISPLAY_INFO); CreatureDisplayInfoExtraStorage = DBReader.Read("CreatureDisplayInfoExtra.db2", HotfixStatements.SEL_CREATURE_DISPLAY_INFO_EXTRA); CreatureFamilyStorage = DBReader.Read("CreatureFamily.db2", HotfixStatements.SEL_CREATURE_FAMILY, HotfixStatements.SEL_CREATURE_FAMILY_LOCALE); @@ -432,6 +433,7 @@ namespace Game.DataStorage public static DB6Storage ContentTuningStorage; public static DB6Storage ContentTuningXExpectedStorage; public static DB6Storage ConversationLineStorage; + public static DB6Storage CorruptionEffectsStorage; public static DB6Storage CreatureDisplayInfoStorage; public static DB6Storage CreatureDisplayInfoExtraStorage; public static DB6Storage CreatureFamilyStorage; diff --git a/Source/Game/DataStorage/DB2Manager.cs b/Source/Game/DataStorage/DB2Manager.cs index 663cd0f11..426414d30 100644 --- a/Source/Game/DataStorage/DB2Manager.cs +++ b/Source/Game/DataStorage/DB2Manager.cs @@ -663,7 +663,6 @@ namespace Game.DataStorage hotfixRecord.RecordID = recordId; hotfixRecord.HotfixID = id; _hotfixData.Add(hotfixRecord); - ++_hotfixCount; deletedRecords[Tuple.Create(tableHash, recordId)] = deleted; ++count; @@ -711,7 +710,8 @@ namespace Game.DataStorage Log.outInfo(LogFilter.ServerLoading, $"Loaded {_hotfixBlob.Count} hotfix blob records in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); } - public uint GetHotfixCount() { return _hotfixCount; } + public uint GetHotfixCount() { return (uint)_hotfixData.Count; } + public List GetHotfixData() { return _hotfixData; } public byte[] GetHotfixBlobData(uint tableHash, int recordId) @@ -2054,7 +2054,6 @@ namespace Game.DataStorage } Dictionary _storage = new Dictionary(); - uint _hotfixCount = 0; List _hotfixData = new List(); Dictionary, byte[]> _hotfixBlob = new Dictionary, byte[]>(); diff --git a/Source/Game/DataStorage/Structs/C_Records.cs b/Source/Game/DataStorage/Structs/C_Records.cs index 115e6d3ae..61f0b58ae 100644 --- a/Source/Game/DataStorage/Structs/C_Records.cs +++ b/Source/Game/DataStorage/Structs/C_Records.cs @@ -240,6 +240,15 @@ namespace Game.DataStorage public byte EndAnimation; } + public sealed class CorruptionEffectsRecord + { + public uint Id; + public float MinCorruption; + public uint Aura; + public int PlayerConditionID; + public int Flags; + } + public sealed class CreatureDisplayInfoRecord { public uint Id; diff --git a/Source/Game/DataStorage/Structs/GameTablesRecords.cs b/Source/Game/DataStorage/Structs/GameTablesRecords.cs index deada762e..81ff12d76 100644 --- a/Source/Game/DataStorage/Structs/GameTablesRecords.cs +++ b/Source/Game/DataStorage/Structs/GameTablesRecords.cs @@ -62,8 +62,8 @@ namespace Game.DataStorage public float CritMelee; public float CritRanged; public float CritSpell; - public float MultiStrike; - public float Readiness; + public float Corruption; + public float CorruptionResistance; public float Speed; public float ResilienceCritTaken; public float ResiliencePlayerDamage; diff --git a/Source/Game/Entities/Item/Item.cs b/Source/Game/Entities/Item/Item.cs index 7cf3cf72e..e05264ae0 100644 --- a/Source/Game/Entities/Item/Item.cs +++ b/Source/Game/Entities/Item/Item.cs @@ -1810,6 +1810,15 @@ namespace Game.Entities public int GetItemStatValue(uint index, Player owner) { Cypher.Assert(index < ItemConst.MaxStats); + switch ((ItemModType)GetItemStatType(index)) + { + case ItemModType.Corruption: + case ItemModType.CorruptionResistance: + return _bonusData.ItemStatAllocation[index]; + default: + break; + } + uint itemLevel = GetItemLevel(owner); uint randomPropPoints = ItemEnchantmentManager.GetRandomPropertyPoints(itemLevel, GetQuality(), GetTemplate().GetInventoryType(), GetTemplate().GetSubClass()); if (randomPropPoints != 0) diff --git a/Source/Game/Entities/Player/Player.Items.cs b/Source/Game/Entities/Player/Player.Items.cs index ae94f5684..240b1bb58 100644 --- a/Source/Game/Entities/Player/Player.Items.cs +++ b/Source/Game/Entities/Player/Player.Items.cs @@ -4183,14 +4183,11 @@ namespace Game.Entities case ItemModType.PvpPower: ApplyRatingMod(CombatRating.PvpPower, val, apply); break; - case ItemModType.CrAmplify: - ApplyRatingMod(CombatRating.Amplify, val, apply); + case ItemModType.Corruption: + ApplyRatingMod(CombatRating.Corruption, val, apply); break; - case ItemModType.CrMultistrike: - ApplyRatingMod(CombatRating.Multistrike, val, apply); - break; - case ItemModType.CrReadiness: - ApplyRatingMod(CombatRating.Readiness, (int)(val * combatRatingMultiplier), apply); + case ItemModType.CorruptionResistance: + ApplyRatingMod(CombatRating.CorruptionResistance, val, apply); break; case ItemModType.CrSpeed: ApplyRatingMod(CombatRating.Speed, (int)(val * combatRatingMultiplier), apply); @@ -4204,15 +4201,6 @@ namespace Game.Entities case ItemModType.CrSturdiness: ApplyRatingMod(CombatRating.Studiness, (int)(val * combatRatingMultiplier), apply); break; - case ItemModType.CrUnused7: - ApplyRatingMod(CombatRating.Unused7, val, apply); - break; - case ItemModType.CrCleave: - ApplyRatingMod(CombatRating.Cleave, val, apply); - break; - case ItemModType.CrUnused12: - ApplyRatingMod(CombatRating.Unused12, val, apply); - break; case ItemModType.AgiStrInt: HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, val, apply); HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, val, apply); diff --git a/Source/Game/Entities/StatSystem.cs b/Source/Game/Entities/StatSystem.cs index 1dd91dd90..44c0cea5a 100644 --- a/Source/Game/Entities/StatSystem.cs +++ b/Source/Game/Entities/StatSystem.cs @@ -1377,6 +1377,10 @@ namespace Game.Entities if (affectStats) UpdateSpellCritChance(); break; + case CombatRating.Corruption: + case CombatRating.CorruptionResistance: + UpdateCorruption(); + break; case CombatRating.HasteMelee: case CombatRating.HasteRanged: case CombatRating.HasteSpell: @@ -1489,6 +1493,34 @@ namespace Game.Entities SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModHealingDonePercent), value); } + void UpdateCorruption() + { + float effectiveCorruption = GetRatingBonusValue(CombatRating.Corruption) - GetRatingBonusValue(CombatRating.CorruptionResistance); + foreach (var corruptionEffect in CliDB.CorruptionEffectsStorage.Values) + { + if (((CorruptionEffectsFlag)corruptionEffect.Flags).HasAnyFlag(CorruptionEffectsFlag.Disabled)) + continue; + + if (effectiveCorruption < corruptionEffect.MinCorruption) + { + RemoveAura(corruptionEffect.Aura); + continue; + } + + PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(corruptionEffect.PlayerConditionID); + if (playerCondition != null) + { + if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition)) + { + RemoveAura(corruptionEffect.Aura); + continue; + } + } + + CastSpell(this, corruptionEffect.Aura, true); + } + } + void UpdateArmorPenetration(int amount) { // Store Rating Value @@ -1702,10 +1734,10 @@ namespace Game.Entities return row.CritRanged; case CombatRating.CritSpell: return row.CritSpell; - case CombatRating.Multistrike: - return row.MultiStrike; - case CombatRating.Readiness: - return row.Readiness; + case CombatRating.Corruption: + return row.Corruption; + case CombatRating.CorruptionResistance: + return row.CorruptionResistance; case CombatRating.Speed: return row.Speed; case CombatRating.ResilienceCritTaken: diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index 5857d3533..789f81f52 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -3820,7 +3820,7 @@ namespace Game.Spells } } - if (IsAura(AuraType.ModRating)) + if (IsAura(AuraType.ModRating) && (MiscValue & ((1 << (int)CombatRating.Corruption) | 1 << ((int)CombatRating.CorruptionResistance))) == 0) { GtGenericMultByILvlRecord ratingMult = CliDB.CombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel); if (ratingMult != null)