diff --git a/src/GameServer/MessageHandler/MagicEffectCancelHandlerPlugIn.cs b/src/GameServer/MessageHandler/MagicEffectCancelHandlerPlugIn.cs new file mode 100644 index 0000000..ca5cd1d --- /dev/null +++ b/src/GameServer/MessageHandler/MagicEffectCancelHandlerPlugIn.cs @@ -0,0 +1,61 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.GameServer.MessageHandler; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.GameLogic; +using MUnique.OpenMU.Network.Packets.ClientToServer; +using MUnique.OpenMU.Network.PlugIns; +using MUnique.OpenMU.PlugIns; + +/// +/// Handler for magic effect cancel packets. +/// +[PlugIn] +[Display(Name = nameof(PlugInResources.MagicEffectCancelHandlerPlugIn_Name), Description = nameof(PlugInResources.MagicEffectCancelHandlerPlugIn_Description), ResourceType = typeof(PlugInResources))] +[Guid("3f25c9a1-4b8d-4e7f-9a2b-1c3d4e5f6a7b")] +[MinimumClient(1, 0, ClientLanguage.Invariant)] +internal class MagicEffectCancelHandlerPlugIn : IPacketHandlerPlugIn +{ + private const int InfinityArrowSkillId = 77; + private const int ExpansionOfWizardrySkillId = 233; + private const int ExpansionOfWizardryStrengSkillId = 380; + private const int ExpansionOfWizardryMasterySkillId = 383; + private const int InfinityArrowStrengSkillId = 441; + + /// + public bool IsEncryptionExpected => true; + + /// + public byte Key => MagicEffectCancelRequest.Code; + + /// + public async ValueTask HandlePacketAsync(Player player, Memory packet) + { + MagicEffectCancelRequest message = packet; + if (!IsCancellableSkill(message.SkillId) || player.SkillList is null || !player.SkillList.ContainsSkill(message.SkillId)) + { + return; + } + + var magicEffect = player.SkillList.GetSkill(message.SkillId)?.Skill?.MagicEffectDef; + if (magicEffect is null || !player.MagicEffectList.ActiveEffects.TryGetValue(magicEffect.Number, out var effect)) + { + return; + } + + await effect.DisposeAsync().ConfigureAwait(false); + } + + private static bool IsCancellableSkill(ushort skillId) => skillId switch + { + ExpansionOfWizardrySkillId => true, + ExpansionOfWizardryStrengSkillId => true, + ExpansionOfWizardryMasterySkillId => true, + InfinityArrowSkillId => true, + InfinityArrowStrengSkillId => true, + _ => false, + }; +} \ No newline at end of file diff --git a/src/GameServer/Properties/PlugInResources.Designer.cs b/src/GameServer/Properties/PlugInResources.Designer.cs index 910d8c1..a924d4f 100644 --- a/src/GameServer/Properties/PlugInResources.Designer.cs +++ b/src/GameServer/Properties/PlugInResources.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:4.0.30319.42000 @@ -2580,6 +2580,24 @@ namespace MUnique.OpenMU.GameServer.Properties { } } + /// + /// Looks up a localized string similar to Handler for magic effect cancel packets.. + /// + public static string MagicEffectCancelHandlerPlugIn_Description { + get { + return ResourceManager.GetString("MagicEffectCancelHandlerPlugIn_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Magic Effect Cancel Handler. + /// + public static string MagicEffectCancelHandlerPlugIn_Name { + get { + return ResourceManager.GetString("MagicEffectCancelHandlerPlugIn_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to The default implementation of the IMapChangePlugIn which is forwarding everything to the game client with specific data packets.. /// diff --git a/src/GameServer/Properties/PlugInResources.resx b/src/GameServer/Properties/PlugInResources.resx index a2945ce..dcf7494 100644 --- a/src/GameServer/Properties/PlugInResources.resx +++ b/src/GameServer/Properties/PlugInResources.resx @@ -218,6 +218,12 @@ Handler for hit packets. + + + Magic Effect Cancel Handler + + + Handler for magic effect cancel packets. Talk Npc Handler diff --git a/src/Network/Packets/ClientToServer/ClientToServerPackets.cs b/src/Network/Packets/ClientToServer/ClientToServerPackets.cs index 314a492..9eaeee2 100644 --- a/src/Network/Packets/ClientToServer/ClientToServerPackets.cs +++ b/src/Network/Packets/ClientToServer/ClientToServerPackets.cs @@ -9425,7 +9425,7 @@ public readonly struct TargetedSkill095 /// -/// Is sent by the client when: A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardy Enhance'. +/// Is sent by the client when: A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardry Enhance'. /// Causes reaction on server side: The effect is cancelled and an update is sent to the player and all surrounding players. /// public readonly struct MagicEffectCancelRequest diff --git a/src/Network/Packets/ClientToServer/ClientToServerPackets.xml b/src/Network/Packets/ClientToServer/ClientToServerPackets.xml index 89e8bfb..6d4ca95 100644 --- a/src/Network/Packets/ClientToServer/ClientToServerPackets.xml +++ b/src/Network/Packets/ClientToServer/ClientToServerPackets.xml @@ -2317,7 +2317,7 @@ MagicEffectCancelRequest 7 ClientToServer - A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardy Enhance'. + A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardry Enhance'. The effect is cancelled and an update is sent to the player and all surrounding players. diff --git a/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs b/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs index d76f8e8..94a9a49 100644 --- a/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs +++ b/src/Network/Packets/ClientToServer/ClientToServerPacketsRef.cs @@ -9300,7 +9300,7 @@ public readonly ref struct TargetedSkill095Ref /// -/// Is sent by the client when: A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardy Enhance'. +/// Is sent by the client when: A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardry Enhance'. /// Causes reaction on server side: The effect is cancelled and an update is sent to the player and all surrounding players. /// public readonly ref struct MagicEffectCancelRequestRef diff --git a/src/Network/Packets/ClientToServer/ConnectionExtensions.cs b/src/Network/Packets/ClientToServer/ConnectionExtensions.cs index 5cbdc21..6f3f0d5 100644 --- a/src/Network/Packets/ClientToServer/ConnectionExtensions.cs +++ b/src/Network/Packets/ClientToServer/ConnectionExtensions.cs @@ -3037,7 +3037,7 @@ public static class ConnectionExtensions /// The skill id. /// The player id. /// - /// Is sent by the client when: A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardy Enhance'. + /// Is sent by the client when: A player cancels a specific magic effect of a skill, usually 'Infinity Arrow' and 'Wizardry Enhance'. /// Causes reaction on server side: The effect is cancelled and an update is sent to the player and all surrounding players. /// public static async ValueTask SendMagicEffectCancelRequestAsync(this IConnection? connection, ushort @skillId, ushort @playerId) diff --git a/src/Persistence/Initialization/Skills/MagicEffectNumber.cs b/src/Persistence/Initialization/Skills/MagicEffectNumber.cs index 71dea63..1af6dc3 100644 --- a/src/Persistence/Initialization/Skills/MagicEffectNumber.cs +++ b/src/Persistence/Initialization/Skills/MagicEffectNumber.cs @@ -330,12 +330,12 @@ internal enum MagicEffectNumber : short /// /// The wiz enhance strengthener effect. /// - WizEnhance2 = 138, + WizEnhanceStrengthener = 138, /// /// The wiz enhance mastery effect. /// - WizEnhance3 = 139, + WizEnhanceMastery = 139, /// /// The critical damage increase mastery effect. diff --git a/src/Persistence/Initialization/Skills/WizardryEnhanceEffectInitializer.cs b/src/Persistence/Initialization/Skills/WizardryEnhanceEffectInitializer.cs index 24208ad..2dad7bd 100644 --- a/src/Persistence/Initialization/Skills/WizardryEnhanceEffectInitializer.cs +++ b/src/Persistence/Initialization/Skills/WizardryEnhanceEffectInitializer.cs @@ -12,9 +12,6 @@ using MUnique.OpenMU.GameLogic.Attributes; /// /// Initializer which initializes the wizardry enhance effect. /// -/// -/// It includes all attributes which are enhanced by the wizardry skill and its master skills. -/// public class WizardryEnhanceEffectInitializer : InitializerBase { /// @@ -39,30 +36,18 @@ public class WizardryEnhanceEffectInitializer : InitializerBase magicEffect.SendDuration = false; magicEffect.StopByDeath = true; magicEffect.Duration = this.Context.CreateNew(); - magicEffect.Duration.ConstantValue.Value = 1200f; // 20 minutes + magicEffect.Duration.ConstantValue.Value = 1800f; // 30 minutes - var powerUpDefinition = this.Context.CreateNew(); - magicEffect.PowerUpDefinitions.Add(powerUpDefinition); - powerUpDefinition.TargetAttribute = Stats.MinimumWizBaseDmg.GetPersistent(this.GameConfiguration); + var minWizDmgPowerUp = this.Context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(minWizDmgPowerUp); + minWizDmgPowerUp.TargetAttribute = Stats.MinimumWizBaseDmg.GetPersistent(this.GameConfiguration); + minWizDmgPowerUp.Boost = this.Context.CreateNew(); + minWizDmgPowerUp.Boost.MaximumValue = 100f; // 100 dmg - powerUpDefinition.Boost = this.Context.CreateNew(); - powerUpDefinition.Boost.ConstantValue.Value = 1.2f; - powerUpDefinition.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate; - - var powerUpDefinition2 = this.Context.CreateNew(); - magicEffect.PowerUpDefinitions.Add(powerUpDefinition2); - powerUpDefinition2.TargetAttribute = Stats.MaximumWizBaseDmg.GetPersistent(this.GameConfiguration); - - powerUpDefinition2.Boost = this.Context.CreateNew(); - powerUpDefinition2.Boost.ConstantValue.Value = 1f; - powerUpDefinition2.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate; - - var powerUpDefinition3 = this.Context.CreateNew(); - magicEffect.PowerUpDefinitions.Add(powerUpDefinition3); - powerUpDefinition3.TargetAttribute = Stats.CriticalDamageChance.GetPersistent(this.GameConfiguration); - - powerUpDefinition3.Boost = this.Context.CreateNew(); - powerUpDefinition3.Boost.ConstantValue.Value = 1f; - powerUpDefinition3.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate; + var minWizDmgPerEnergy = this.Context.CreateNew(); + minWizDmgPerEnergy.InputAttribute = Stats.TotalEnergy.GetPersistent(this.GameConfiguration); + minWizDmgPerEnergy.InputOperator = InputOperator.Multiply; + minWizDmgPerEnergy.InputOperand = 0.2f / 9; // 45 energy adds 1 min wiz damage + minWizDmgPowerUp.Boost.RelatedValues.Add(minWizDmgPerEnergy); } } \ No newline at end of file diff --git a/src/Persistence/Initialization/Skills/WizardryEnhanceMasteryEffectInitializer.cs b/src/Persistence/Initialization/Skills/WizardryEnhanceMasteryEffectInitializer.cs new file mode 100644 index 0000000..cbf6dd9 --- /dev/null +++ b/src/Persistence/Initialization/Skills/WizardryEnhanceMasteryEffectInitializer.cs @@ -0,0 +1,70 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Skills; + +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.DataModel.Attributes; +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.GameLogic.Attributes; + +/// +/// Initializer which initializes the wizardry enhance mastery effect. +/// +public class WizardryEnhanceMasteryEffectInitializer : InitializerBase +{ + /// + /// Initializes a new instance of the class. + /// + /// The context. + /// The game configuration. + public WizardryEnhanceMasteryEffectInitializer(IContext context, GameConfiguration gameConfiguration) + : base(context, gameConfiguration) + { + } + + /// + public override void Initialize() + { + var magicEffect = this.Context.CreateNew(); + this.GameConfiguration.MagicEffects.Add(magicEffect); + magicEffect.Number = (byte)MagicEffectNumber.WizEnhanceMastery; + magicEffect.Name = "Wizardry Enhance Mastery Skill Effect"; + + var wizardryEnhanceEffect = this.GameConfiguration.MagicEffects.First(e => e.Number == (short)MagicEffectNumber.WizEnhanceStrengthener); + magicEffect.InformObservers = wizardryEnhanceEffect.InformObservers; + magicEffect.SubType = wizardryEnhanceEffect.SubType; + magicEffect.SendDuration = wizardryEnhanceEffect.SendDuration; + magicEffect.StopByDeath = wizardryEnhanceEffect.StopByDeath; + magicEffect.Duration = this.Context.CreateNew(); + magicEffect.Duration.ConstantValue.Value = wizardryEnhanceEffect.Duration!.ConstantValue.Value; + magicEffect.Duration.MaximumValue = wizardryEnhanceEffect.Duration.MaximumValue; + + foreach (var powerUp in wizardryEnhanceEffect.PowerUpDefinitions) + { + var powerUpCopy = this.Context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(powerUpCopy); + powerUpCopy.TargetAttribute = powerUp.TargetAttribute!.GetPersistent(this.GameConfiguration); + powerUpCopy.Boost = this.Context.CreateNew(); + powerUpCopy.Boost.ConstantValue.Value = powerUp.Boost!.ConstantValue.Value; + powerUpCopy.Boost.ConstantValue.AggregateType = powerUp.Boost.ConstantValue.AggregateType; + powerUpCopy.Boost.MaximumValue = powerUp.Boost.MaximumValue; + + foreach (var boostRelatedValue in powerUp.Boost.RelatedValues) + { + var boostRelatedValueCopy = this.Context.CreateNew(); + boostRelatedValueCopy.InputAttribute = boostRelatedValue.InputAttribute!.GetPersistent(this.GameConfiguration); + boostRelatedValueCopy.InputOperator = boostRelatedValue.InputOperator; + boostRelatedValueCopy.InputOperand = boostRelatedValue.InputOperand; + boostRelatedValueCopy.AggregateType = boostRelatedValue.AggregateType; + powerUpCopy.Boost.RelatedValues.Add(boostRelatedValueCopy); + } + } + + var critChancePowerUp = this.Context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(critChancePowerUp); + critChancePowerUp.TargetAttribute = Stats.CriticalDamageChance.GetPersistent(this.GameConfiguration); + critChancePowerUp.Boost = this.Context.CreateNew(); + } +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Skills/WizardryEnhanceStrengthenerEffectInitializer.cs b/src/Persistence/Initialization/Skills/WizardryEnhanceStrengthenerEffectInitializer.cs new file mode 100644 index 0000000..ecbff2d --- /dev/null +++ b/src/Persistence/Initialization/Skills/WizardryEnhanceStrengthenerEffectInitializer.cs @@ -0,0 +1,72 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Skills; + +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.DataModel.Attributes; +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.GameLogic.Attributes; + +/// +/// Initializer which initializes the wizardry enhance strengthener effect. +/// +public class WizardryEnhanceStrengthenerEffectInitializer : InitializerBase +{ + /// + /// Initializes a new instance of the class. + /// + /// The context. + /// The game configuration. + public WizardryEnhanceStrengthenerEffectInitializer(IContext context, GameConfiguration gameConfiguration) + : base(context, gameConfiguration) + { + } + + /// + public override void Initialize() + { + var magicEffect = this.Context.CreateNew(); + this.GameConfiguration.MagicEffects.Add(magicEffect); + magicEffect.Number = (byte)MagicEffectNumber.WizEnhanceStrengthener; + magicEffect.Name = "Wizardry Enhance Strengthener Skill Effect"; + + var wizardryEnhanceEffect = this.GameConfiguration.MagicEffects.First(e => e.Number == (short)MagicEffectNumber.WizEnhance); + magicEffect.InformObservers = wizardryEnhanceEffect.InformObservers; + magicEffect.SubType = wizardryEnhanceEffect.SubType; + magicEffect.SendDuration = wizardryEnhanceEffect.SendDuration; + magicEffect.StopByDeath = wizardryEnhanceEffect.StopByDeath; + magicEffect.Duration = this.Context.CreateNew(); + magicEffect.Duration.ConstantValue.Value = wizardryEnhanceEffect.Duration!.ConstantValue.Value; + magicEffect.Duration.MaximumValue = wizardryEnhanceEffect.Duration.MaximumValue; + + foreach (var powerUp in wizardryEnhanceEffect.PowerUpDefinitions) + { + var powerUpCopy = this.Context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(powerUpCopy); + powerUpCopy.TargetAttribute = powerUp.TargetAttribute!.GetPersistent(this.GameConfiguration); + powerUpCopy.Boost = this.Context.CreateNew(); + powerUpCopy.Boost.ConstantValue.Value = powerUp.Boost!.ConstantValue.Value; + powerUpCopy.Boost.ConstantValue.AggregateType = powerUp.Boost.ConstantValue.AggregateType; + powerUpCopy.Boost.MaximumValue = powerUp.Boost.MaximumValue; + + foreach (var boostRelatedValue in powerUp.Boost.RelatedValues) + { + var boostRelatedValueCopy = this.Context.CreateNew(); + boostRelatedValueCopy.InputAttribute = boostRelatedValue.InputAttribute!.GetPersistent(this.GameConfiguration); + boostRelatedValueCopy.InputOperator = boostRelatedValue.InputOperator; + boostRelatedValueCopy.InputOperand = boostRelatedValue.InputOperand; + boostRelatedValueCopy.AggregateType = boostRelatedValue.AggregateType; + powerUpCopy.Boost.RelatedValues.Add(boostRelatedValueCopy); + } + } + + var maxDmgPowerUp = this.Context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(maxDmgPowerUp); + maxDmgPowerUp.TargetAttribute = Stats.MaximumWizBaseDmg.GetPersistent(this.GameConfiguration); + maxDmgPowerUp.Boost = this.Context.CreateNew(); + maxDmgPowerUp.Boost.ConstantValue.Value = 1f; + maxDmgPowerUp.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate; + } +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/FinishDarkWizardMasterTreePlugIn.cs b/src/Persistence/Initialization/Updates/FinishDarkWizardMasterTreePlugIn.cs new file mode 100644 index 0000000..b3f8cb7 --- /dev/null +++ b/src/Persistence/Initialization/Updates/FinishDarkWizardMasterTreePlugIn.cs @@ -0,0 +1,185 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using System.Runtime.InteropServices; +using MUnique.OpenMU.AttributeSystem; +using MUnique.OpenMU.DataModel.Attributes; +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.GameLogic.Attributes; +using MUnique.OpenMU.Persistence.Initialization.Skills; +using MUnique.OpenMU.PlugIns; + +/// +/// This update completes the dark wizard master tree expansion of wizardry effects. +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("C1D2E3F4-5A6B-7C8D-9E0F-1A2B3C4D5E6F")] +public class FinishDarkWizardMasterTreePlugIn : UpdatePlugInBase +{ + /// + /// The plug in name. + /// + internal const string PlugInName = "Finish Dark Wizard Master Tree PlugIn"; + + /// + /// The plug in description. + /// + internal const string PlugInDescription = "This update completes the dark wizard master tree expansion of wizardry effects."; + + /// + public override UpdateVersion Version => UpdateVersion.FinishDarkWizardMasterTree; + + /// + public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + + /// + public override string Name => PlugInName; + + /// + public override string Description => PlugInDescription; + + /// + public override bool IsMandatory => true; + + /// + public override DateTime CreatedAt => new(2026, 7, 7, 16, 0, 0, DateTimeKind.Utc); + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + // Update Wizardry Enhance effect + var wizardryEnhanceEffect = gameConfiguration.MagicEffects.First(e => e.Number == (short)MagicEffectNumber.WizEnhance); + wizardryEnhanceEffect.Duration = context.CreateNew(); + wizardryEnhanceEffect.Duration.ConstantValue.Value = 1800f; // 30 minutes + wizardryEnhanceEffect.PowerUpDefinitions.Clear(); + + var minWizDmgPowerUp = context.CreateNew(); + wizardryEnhanceEffect.PowerUpDefinitions.Add(minWizDmgPowerUp); + minWizDmgPowerUp.TargetAttribute = Stats.MinimumWizBaseDmg.GetPersistent(gameConfiguration); + minWizDmgPowerUp.Boost = context.CreateNew(); + minWizDmgPowerUp.Boost.MaximumValue = 100f; // 100 dmg + + var minWizDmgPerEnergy = context.CreateNew(); + minWizDmgPerEnergy.InputAttribute = Stats.TotalEnergy.GetPersistent(gameConfiguration); + minWizDmgPerEnergy.InputOperator = InputOperator.Multiply; + minWizDmgPerEnergy.InputOperand = 0.2f / 9; // 45 energy adds 1 min wiz damage + minWizDmgPowerUp.Boost.RelatedValues.Add(minWizDmgPerEnergy); + + // Create Wiz Enhance Strengthener & Mastery Skill Effects + var wizEnhanceStrengthenerEffect = this.CreateWizEnhanceStrengthenerEffect(context, gameConfiguration); + var wizEnhanceMasteryEffect = this.CreateWizEnhanceMasteryEffect(context, gameConfiguration); + + // Update master skills + if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.ExpansionofWizStreng) is { } expansionOfWizStreng) + { + expansionOfWizStreng.MagicEffectDef = wizEnhanceStrengthenerEffect; + } + + if (gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.ExpansionofWizMas) is { } expansionOfWizMastery) + { + expansionOfWizMastery.MagicEffectDef = wizEnhanceMasteryEffect; + + if (expansionOfWizMastery.MasterDefinition is { } masterDefinition) + { + masterDefinition.ReplacedSkill = gameConfiguration.Skills.First(s => s.Number == (short)SkillNumber.ExpansionofWizStreng); + masterDefinition.Aggregation = AggregateType.AddRaw; + } + } + } + + private MagicEffectDefinition CreateWizEnhanceStrengthenerEffect(IContext context, GameConfiguration gameConfiguration) + { + var magicEffect = context.CreateNew(); + gameConfiguration.MagicEffects.Add(magicEffect); + magicEffect.Number = (byte)MagicEffectNumber.WizEnhanceStrengthener; + magicEffect.Name = "Wizardry Enhance Strengthener Skill Effect"; + + var wizardryEnhanceEffect = gameConfiguration.MagicEffects.First(e => e.Number == (short)MagicEffectNumber.WizEnhance); + magicEffect.InformObservers = wizardryEnhanceEffect.InformObservers; + magicEffect.SubType = wizardryEnhanceEffect.SubType; + magicEffect.SendDuration = wizardryEnhanceEffect.SendDuration; + magicEffect.StopByDeath = wizardryEnhanceEffect.StopByDeath; + magicEffect.Duration = context.CreateNew(); + magicEffect.Duration.ConstantValue.Value = wizardryEnhanceEffect.Duration!.ConstantValue.Value; + magicEffect.Duration.MaximumValue = wizardryEnhanceEffect.Duration.MaximumValue; + + foreach (var powerUp in wizardryEnhanceEffect.PowerUpDefinitions) + { + var powerUpCopy = context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(powerUpCopy); + powerUpCopy.TargetAttribute = powerUp.TargetAttribute!.GetPersistent(gameConfiguration); + powerUpCopy.Boost = context.CreateNew(); + powerUpCopy.Boost.ConstantValue.Value = powerUp.Boost!.ConstantValue.Value; + powerUpCopy.Boost.ConstantValue.AggregateType = powerUp.Boost.ConstantValue.AggregateType; + powerUpCopy.Boost.MaximumValue = powerUp.Boost.MaximumValue; + + foreach (var boostRelatedValue in powerUp.Boost.RelatedValues) + { + var boostRelatedValueCopy = context.CreateNew(); + boostRelatedValueCopy.InputAttribute = boostRelatedValue.InputAttribute!.GetPersistent(gameConfiguration); + boostRelatedValueCopy.InputOperator = boostRelatedValue.InputOperator; + boostRelatedValueCopy.InputOperand = boostRelatedValue.InputOperand; + boostRelatedValueCopy.AggregateType = boostRelatedValue.AggregateType; + powerUpCopy.Boost.RelatedValues.Add(boostRelatedValueCopy); + } + } + + var maxDmgPowerUp = context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(maxDmgPowerUp); + maxDmgPowerUp.TargetAttribute = Stats.MaximumWizBaseDmg.GetPersistent(gameConfiguration); + maxDmgPowerUp.Boost = context.CreateNew(); + maxDmgPowerUp.Boost.ConstantValue.Value = 1f; + maxDmgPowerUp.Boost.ConstantValue.AggregateType = AggregateType.Multiplicate; + + return magicEffect; + } + + private MagicEffectDefinition CreateWizEnhanceMasteryEffect(IContext context, GameConfiguration gameConfiguration) + { + var magicEffect = context.CreateNew(); + gameConfiguration.MagicEffects.Add(magicEffect); + magicEffect.Number = (byte)MagicEffectNumber.WizEnhanceMastery; + magicEffect.Name = "Wizardry Enhance Mastery Skill Effect"; + + var wizardryEnhanceEffect = gameConfiguration.MagicEffects.First(e => e.Number == (short)MagicEffectNumber.WizEnhanceStrengthener); + magicEffect.InformObservers = wizardryEnhanceEffect.InformObservers; + magicEffect.SubType = wizardryEnhanceEffect.SubType; + magicEffect.SendDuration = wizardryEnhanceEffect.SendDuration; + magicEffect.StopByDeath = wizardryEnhanceEffect.StopByDeath; + magicEffect.Duration = context.CreateNew(); + magicEffect.Duration.ConstantValue.Value = wizardryEnhanceEffect.Duration!.ConstantValue.Value; + magicEffect.Duration.MaximumValue = wizardryEnhanceEffect.Duration.MaximumValue; + + foreach (var powerUp in wizardryEnhanceEffect.PowerUpDefinitions) + { + var powerUpCopy = context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(powerUpCopy); + powerUpCopy.TargetAttribute = powerUp.TargetAttribute!.GetPersistent(gameConfiguration); + powerUpCopy.Boost = context.CreateNew(); + powerUpCopy.Boost.ConstantValue.Value = powerUp.Boost!.ConstantValue.Value; + powerUpCopy.Boost.ConstantValue.AggregateType = powerUp.Boost.ConstantValue.AggregateType; + powerUpCopy.Boost.MaximumValue = powerUp.Boost.MaximumValue; + + foreach (var boostRelatedValue in powerUp.Boost.RelatedValues) + { + var boostRelatedValueCopy = context.CreateNew(); + boostRelatedValueCopy.InputAttribute = boostRelatedValue.InputAttribute!.GetPersistent(gameConfiguration); + boostRelatedValueCopy.InputOperator = boostRelatedValue.InputOperator; + boostRelatedValueCopy.InputOperand = boostRelatedValue.InputOperand; + boostRelatedValueCopy.AggregateType = boostRelatedValue.AggregateType; + powerUpCopy.Boost.RelatedValues.Add(boostRelatedValueCopy); + } + } + + var critChancePowerUp = context.CreateNew(); + magicEffect.PowerUpDefinitions.Add(critChancePowerUp); + critChancePowerUp.TargetAttribute = Stats.CriticalDamageChance.GetPersistent(gameConfiguration); + critChancePowerUp.Boost = context.CreateNew(); + + return magicEffect; + } +} diff --git a/src/Persistence/Initialization/Updates/UpdateVersion.cs b/src/Persistence/Initialization/Updates/UpdateVersion.cs index 8ee91d1..81e5e7b 100644 --- a/src/Persistence/Initialization/Updates/UpdateVersion.cs +++ b/src/Persistence/Initialization/Updates/UpdateVersion.cs @@ -479,7 +479,7 @@ public enum UpdateVersion /// The version of the . /// AddIsQuestItemFlag = 94, - + /// /// The version of the . /// @@ -514,4 +514,9 @@ public enum UpdateVersion /// The version of the . /// AddElfSoldierBuff = 101, + + /// + /// The version of the . + /// + FinishDarkWizardMasterTree = 102, } diff --git a/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs b/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs index 40fcbc7..029d952 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs @@ -81,6 +81,8 @@ internal class SkillsInitializer : SkillsInitializerBase { SkillNumber.EarthshakeMastery, MagicEffectNumber.Stunned }, { SkillNumber.CritDmgIncPowUp3, MagicEffectNumber.CriticalDamageIncreaseMastery }, { SkillNumber.SwellLifeProficiency, MagicEffectNumber.GreaterFortitudeProficiency }, + { SkillNumber.ExpansionofWizStreng, MagicEffectNumber.WizEnhanceStrengthener }, + { SkillNumber.ExpansionofWizMas, MagicEffectNumber.WizEnhanceMastery }, }; private readonly IDictionary _masterSkillRoots; @@ -701,6 +703,8 @@ internal class SkillsInitializer : SkillsInitializerBase new StunEffectInitializer(this.Context, this.GameConfiguration).Initialize(); new CriticalDamageIncreaseMasteryEffectInitializer(this.Context, this.GameConfiguration).Initialize(); new LifeSwellProficiencyEffectInitializer(this.Context, this.GameConfiguration).Initialize(); + new WizardryEnhanceStrengthenerEffectInitializer(this.Context, this.GameConfiguration).Initialize(); + new WizardryEnhanceMasteryEffectInitializer(this.Context, this.GameConfiguration).Initialize(); } private void MapSkillsToEffects() @@ -800,7 +804,7 @@ internal class SkillsInitializer : SkillsInitializerBase this.AddMasterSkillDefinition(SkillNumber.ExpansionofWizStreng, SkillNumber.ExpansionofWizardry, SkillNumber.Undefined, 2, 2, SkillNumber.ExpansionofWizardry, 20, Formula120Value, Formula120, Stats.MaximumWizBaseDmg, AggregateType.Multiplicate); this.AddMasterSkillDefinition(SkillNumber.InfernoStrengthener, SkillNumber.Inferno, SkillNumber.FlameStrengthener, 2, 3, SkillNumber.Inferno, 20, Formula502); this.AddMasterSkillDefinition(SkillNumber.BlastStrengthener, SkillNumber.Cometfall, SkillNumber.LightningStrengthener, 2, 3, SkillNumber.Cometfall, 20, Formula502); - this.AddMasterSkillDefinition(SkillNumber.ExpansionofWizMas, SkillNumber.ExpansionofWizStreng, SkillNumber.Undefined, 2, 3, SkillNumber.ExpansionofWizardry, 20, Formula120Value, Formula120, targetAttribute: Stats.CriticalDamageChance, AggregateType.Multiplicate); + this.AddMasterSkillDefinition(SkillNumber.ExpansionofWizMas, SkillNumber.ExpansionofWizStreng, SkillNumber.Undefined, 2, 3, SkillNumber.ExpansionofWizStreng, 20, Formula120Value, Formula120, Stats.CriticalDamageChance, AggregateType.AddRaw); this.AddMasterSkillDefinition(SkillNumber.PoisonStrengthener, SkillNumber.Poison, SkillNumber.Undefined, 2, 3, SkillNumber.Poison, 20, Formula632); this.AddMasterSkillDefinition(SkillNumber.EvilSpiritStreng, SkillNumber.EvilSpirit, SkillNumber.Undefined, 2, 4, SkillNumber.EvilSpirit, 20, Formula502); this.AddPassiveMasterSkillDefinition(SkillNumber.MagicMasteryGrandMaster, Stats.WizardryBaseDmg, AggregateType.AddRaw, Formula502, 4, 2, SkillNumber.EvilSpiritStreng);