diff --git a/src/Persistence/Initialization/Updates/FixAreaSkillsUpdatePlugIn.cs b/src/Persistence/Initialization/Updates/FixAreaSkillsUpdatePlugIn.cs new file mode 100644 index 000000000..7925af2e7 --- /dev/null +++ b/src/Persistence/Initialization/Updates/FixAreaSkillsUpdatePlugIn.cs @@ -0,0 +1,101 @@ +// +// 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.DataModel.Configuration; +using MUnique.OpenMU.Persistence.Initialization.Skills; +using MUnique.OpenMU.PlugIns; + +/// +/// This update fixes area skills' range, effect radius, and delay issues. +/// Hellfire, Decay, and Ice Storm had missing area skill settings causing incorrect hit radius. +/// Ice Storm had an incorrect 200ms delay between hits. +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("B9938E4D-8F63-48DF-AE45-6739D1E2A8C7")] +public class FixAreaSkillsUpdatePlugIn : UpdatePlugInBase +{ + /// + /// The plug in name. + /// + internal const string PlugInName = "Fix Area Skills"; + + /// + /// The plug in description. + /// + internal const string PlugInDescription = "Fixes Hellfire, Decay, and Ice Storm skills' range, effect radius, and delay."; + + /// + public override UpdateVersion Version => UpdateVersion.FixAreaSkills; + + /// + public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + + /// + public override string Name => PlugInName; + + /// + public override string Description => PlugInDescription; + + /// + public override bool IsMandatory => false; + + /// + public override DateTime CreatedAt => new(2026, 04, 09, 12, 0, 0, DateTimeKind.Utc); + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + // Fix Hellfire Strengthener + var hellfireStrengthener = gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.HellfireStrengthener); + if (hellfireStrengthener != null) + { + hellfireStrengthener.Range = 4; + hellfireStrengthener.AttackDamage = 3; + + if (hellfireStrengthener.AreaSkillSettings == null) + { + var areaSkillSettings = context.CreateNew(); + hellfireStrengthener.AreaSkillSettings = areaSkillSettings; + areaSkillSettings.EffectRange = 2; + } + } + + // Fix Decay Strengthener + var decayStrengthener = gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.DecayStrengthener); + if (decayStrengthener != null) + { + decayStrengthener.Range = 6; + + if (decayStrengthener.AreaSkillSettings == null) + { + var areaSkillSettings = context.CreateNew(); + decayStrengthener.AreaSkillSettings = areaSkillSettings; + areaSkillSettings.EffectRange = 2; + } + } + + // Fix base Decay skill + var decay = gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.Decay); + if (decay != null) + { + if (decay.AreaSkillSettings == null) + { + var areaSkillSettings = context.CreateNew(); + decay.AreaSkillSettings = areaSkillSettings; + areaSkillSettings.EffectRange = 2; + } + } + + // Fix Ice Storm - remove incorrect 200ms delay + var iceStorm = gameConfiguration.Skills.FirstOrDefault(s => s.Number == (short)SkillNumber.IceStorm); + if (iceStorm?.AreaSkillSettings != null) + { + iceStorm.AreaSkillSettings.DelayBetweenHits = TimeSpan.Zero; + } + } +} diff --git a/src/Persistence/Initialization/Updates/UpdateVersion.cs b/src/Persistence/Initialization/Updates/UpdateVersion.cs index 3932ebc5a..f8b45d15f 100644 --- a/src/Persistence/Initialization/Updates/UpdateVersion.cs +++ b/src/Persistence/Initialization/Updates/UpdateVersion.cs @@ -392,4 +392,9 @@ public enum UpdateVersion /// The version of the . /// FixSummonerCurseSkills = 77, + + /// + /// The version of the . + /// + FixAreaSkills = 78, } diff --git a/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs b/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs index 06bbd91af..927a48d2a 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/SkillsInitializer.cs @@ -112,6 +112,7 @@ public override void Initialize() this.CreateSkill(SkillNumber.EvilSpirit, "Evil Spirit", CharacterClasses.AllMagicians, DamageType.Wizardry, 45, 7, manaConsumption: 90, energyRequirement: 220, skillType: SkillType.AreaSkillAutomaticHits); this.AddAreaSkillSettings(SkillNumber.EvilSpirit, false, default, default, default, true, TimeSpan.FromMilliseconds(100), TimeSpan.FromMilliseconds(1000), 0, 2, default, default, 0.7f); this.CreateSkill(SkillNumber.Hellfire, "Hellfire", CharacterClasses.AllMagicians, DamageType.Wizardry, 120, 4, manaConsumption: 160, energyRequirement: 260, elementalModifier: ElementalType.Fire, skillType: SkillType.AreaSkillAutomaticHits); + this.AddAreaSkillSettings(SkillNumber.Hellfire, false, 0, 0, 0, effectRange: 2); this.CreateSkill(SkillNumber.PowerWave, "Power Wave", CharacterClasses.AllMagicians | CharacterClasses.AllSummoners, DamageType.Wizardry, 14, 6, manaConsumption: 5, energyRequirement: 56); this.CreateSkill(SkillNumber.AquaBeam, "Aqua Beam", CharacterClasses.AllMagicians, DamageType.Wizardry, 80, 6, manaConsumption: 140, energyRequirement: 345, elementalModifier: ElementalType.Water, skillType: SkillType.AreaSkillAutomaticHits); this.AddAreaSkillSettings(SkillNumber.AquaBeam, true, 1.5f, 1.5f, 8f); @@ -140,8 +141,9 @@ public override void Initialize() this.CreateSkill(SkillNumber.SummonBali, "Summon Bali", CharacterClasses.AllElfs, manaConsumption: 250, energyRequirement: 260, skillType: SkillType.SummonMonster); this.CreateSkill(SkillNumber.SummonSoldier, "Summon Soldier", CharacterClasses.AllElfs, manaConsumption: 350, energyRequirement: 280, skillType: SkillType.SummonMonster); this.CreateSkill(SkillNumber.Decay, "Decay", CharacterClasses.SoulMasterAndGrandMaster, DamageType.Wizardry, 95, 6, 7, 110, energyRequirement: 953, elementalModifier: ElementalType.Poison, skillType: SkillType.AreaSkillAutomaticHits); + this.AddAreaSkillSettings(SkillNumber.Decay, false, 0, 0, 0, effectRange: 2); this.CreateSkill(SkillNumber.IceStorm, "Ice Storm", CharacterClasses.SoulMasterAndGrandMaster, DamageType.Wizardry, 80, 6, 5, 100, energyRequirement: 849, elementalModifier: ElementalType.Ice, skillType: SkillType.AreaSkillAutomaticHits); - this.AddAreaSkillSettings(SkillNumber.IceStorm, false, default, default, default, true, TimeSpan.Zero, TimeSpan.FromMilliseconds(200), targetAreaDiameter: 3, useTargetAreaFilter: true); + this.AddAreaSkillSettings(SkillNumber.IceStorm, false, default, default, default, true, TimeSpan.Zero, TimeSpan.Zero, targetAreaDiameter: 3, useTargetAreaFilter: true); this.CreateSkill(SkillNumber.Nova, "Nova", CharacterClasses.SoulMasterAndGrandMaster, DamageType.Wizardry, distance: 6, manaConsumption: 180 / 12 /* mana per stage */, levelRequirement: 100, energyRequirement: 1052, elementalModifier: ElementalType.Fire); this.CreateSkill(SkillNumber.NovaStart, "Nova (Start)", CharacterClasses.SoulMasterAndGrandMaster, DamageType.None, abilityConsumption: 45, levelRequirement: 100, energyRequirement: 1052, skillType: SkillType.Other); this.CreateSkill(SkillNumber.TwistingSlash, "Twisting Slash", CharacterClasses.AllKnights | CharacterClasses.AllMGs, DamageType.Physical, distance: 2, abilityConsumption: 10, manaConsumption: 10, elementalModifier: ElementalType.Wind, skillType: SkillType.AreaSkillAutomaticHits); @@ -296,8 +298,10 @@ public override void Initialize() this.CreateSkill(SkillNumber.PoisonStrengthener, "Poison Strengthener", CharacterClasses.GrandMaster, DamageType.Wizardry, 3, 6, manaConsumption: 46, levelRequirement: 30, energyRequirement: 100, elementalModifier: ElementalType.Poison); this.CreateSkill(SkillNumber.EvilSpiritStreng, "Evil Spirit Streng", CharacterClasses.GrandMaster, DamageType.Wizardry, 22, 6, manaConsumption: 108, levelRequirement: 50, energyRequirement: 100); this.CreateSkill(SkillNumber.MagicMasteryGrandMaster, "Magic Mastery", CharacterClasses.GrandMaster, damage: 22, levelRequirement: 50, skillType: SkillType.PassiveBoost); - this.CreateSkill(SkillNumber.DecayStrengthener, "Decay Strengthener", CharacterClasses.GrandMaster, DamageType.Wizardry, 22, 6, 10, 120, 96, 243, elementalModifier: ElementalType.Poison); - this.CreateSkill(SkillNumber.HellfireStrengthener, "Hellfire Strengthener", CharacterClasses.GrandMaster, DamageType.Wizardry, 3, manaConsumption: 176, levelRequirement: 60, energyRequirement: 100, elementalModifier: ElementalType.Fire); + this.CreateSkill(SkillNumber.DecayStrengthener, "Decay Strengthener", CharacterClasses.GrandMaster, DamageType.Wizardry, 22, 6, 10, 120, 96, 243, elementalModifier: ElementalType.Poison, skillType: SkillType.AreaSkillAutomaticHits); + this.AddAreaSkillSettings(SkillNumber.DecayStrengthener, false, 0, 0, 0, effectRange: 2); + this.CreateSkill(SkillNumber.HellfireStrengthener, "Hellfire Strengthener", CharacterClasses.GrandMaster, DamageType.Wizardry, 3, 4, manaConsumption: 176, levelRequirement: 60, energyRequirement: 100, elementalModifier: ElementalType.Fire, skillType: SkillType.AreaSkillAutomaticHits); + this.AddAreaSkillSettings(SkillNumber.HellfireStrengthener, false, 0, 0, 0, effectRange: 2); this.CreateSkill(SkillNumber.IceStrengthener, "Ice Strengthener", CharacterClasses.GrandMaster, DamageType.Wizardry, 3, 6, manaConsumption: 42, levelRequirement: 25, energyRequirement: 100, elementalModifier: ElementalType.Ice); this.CreateSkill(SkillNumber.OneHandedStaffStrengthener, "One-handed Staff Stren", CharacterClasses.GrandMaster | CharacterClasses.DuelMaster, DamageType.Wizardry, 22, skillType: SkillType.PassiveBoost); this.CreateSkill(SkillNumber.TwoHandedStaffStrengthener, "Two-handed Staff Stren", CharacterClasses.GrandMaster | CharacterClasses.DuelMaster, DamageType.Wizardry, 4, skillType: SkillType.PassiveBoost);