From aeb3afb0da0b7f6d74ced2f04567a5edcd84f529 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Thu, 19 Feb 2026 14:59:52 +0000 Subject: [PATCH 1/7] First commit --- src/DataModel/Configuration/DropItemGroup.cs | 5 +++++ src/GameLogic/DefaultDropGenerator.cs | 18 +++++++++++++++++- .../GameConfigurationInitializerBase.cs | 2 +- .../Initialization/Version075/Items/Pets.cs | 11 +++++++---- .../Initialization/Version075/Items/Potions.cs | 4 +++- .../Initialization/Version095d/Items/Pets.cs | 11 +++++++---- .../VersionSeasonSix/Items/Pets.cs | 11 +++++++---- .../VersionSeasonSix/Items/Potions.cs | 4 +++- .../VersionSeasonSix/Maps/LandOfTrials.cs | 2 +- 9 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/DataModel/Configuration/DropItemGroup.cs b/src/DataModel/Configuration/DropItemGroup.cs index 35ec995ea..bb9bbcccd 100644 --- a/src/DataModel/Configuration/DropItemGroup.cs +++ b/src/DataModel/Configuration/DropItemGroup.cs @@ -41,6 +41,11 @@ public enum SpecialItemType /// The money special item type. /// Money, + + /// + /// The jewel special item type. + /// + Jewel, } /// diff --git a/src/GameLogic/DefaultDropGenerator.cs b/src/GameLogic/DefaultDropGenerator.cs index f0d80bf52..18c31cada 100644 --- a/src/GameLogic/DefaultDropGenerator.cs +++ b/src/GameLogic/DefaultDropGenerator.cs @@ -433,7 +433,23 @@ private void AddRandomExcOptions(Item item) else { var monsterLevel = (int)monster[Stats.Level]; - var filteredPossibleItems = selectedGroup.PossibleItems.Where(it => it.DropLevel == 0 || ((it.DropLevel <= monsterLevel) && (it.DropLevel > monsterLevel - 12))).ToArray(); + List filteredPossibleItems = []; + + if (selectedGroup.ItemType == SpecialItemType.Jewel) + { + filteredPossibleItems = [.. selectedGroup.PossibleItems.Where(it => it.DropLevel <= monsterLevel)]; + + if (monsterLevel > 66) + { + // Jewel of Chaos doesn't drop after a certain monster level + filteredPossibleItems.RemoveAll(it => it.Group == 12 && it.Number == 15); + } + } + else + { + filteredPossibleItems = [.. selectedGroup.PossibleItems.Where(it => it.DropLevel == 0 || (it.DropLevel <= monsterLevel && it.DropLevel > monsterLevel - 12))]; + } + return this.GenerateItemDrop(selectedGroup, filteredPossibleItems); } } diff --git a/src/Persistence/Initialization/GameConfigurationInitializerBase.cs b/src/Persistence/Initialization/GameConfigurationInitializerBase.cs index 6c384066c..f62343be1 100644 --- a/src/Persistence/Initialization/GameConfigurationInitializerBase.cs +++ b/src/Persistence/Initialization/GameConfigurationInitializerBase.cs @@ -167,7 +167,7 @@ private void AddItemDropGroups() var jewelsDropItemGroup = this.Context.CreateNew(); jewelsDropItemGroup.SetGuid(4); jewelsDropItemGroup.Chance = 0.001; - jewelsDropItemGroup.ItemType = SpecialItemType.RandomItem; + jewelsDropItemGroup.ItemType = SpecialItemType.Jewel; jewelsDropItemGroup.Description = "The jewels drop item group (0.1 % drop chance)"; this.GameConfiguration.DropItemGroups.Add(jewelsDropItemGroup); BaseMapInitializer.RegisterDefaultDropItemGroup(jewelsDropItemGroup); diff --git a/src/Persistence/Initialization/Version075/Items/Pets.cs b/src/Persistence/Initialization/Version075/Items/Pets.cs index e814c4775..bcddbb961 100644 --- a/src/Persistence/Initialization/Version075/Items/Pets.cs +++ b/src/Persistence/Initialization/Version075/Items/Pets.cs @@ -14,7 +14,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Version075.Items; /// /// Initializer for pets. /// -public class Pets : InitializerBase +public class Pets : Jewels { /// /// Initializes a new instance of the class. @@ -29,9 +29,12 @@ public Pets(IContext context, GameConfiguration gameConfiguration) /// public override void Initialize() { - this.CreatePet(0, "Guardian Angel", 23, (Stats.DamageReceiveDecrement, 0.8f, AggregateType.Multiplicate), (Stats.MaximumHealth, 50f, AggregateType.AddRaw)); - this.CreatePet(1, "Imp", 28, (Stats.AttackDamageIncrease, 1.3f, AggregateType.Multiplicate)); - this.CreatePet(2, "Horn of Uniria", 25); + var angel = this.CreatePet(0, "Guardian Angel", 23, (Stats.DamageReceiveDecrement, 0.8f, AggregateType.Multiplicate), (Stats.MaximumHealth, 50f, AggregateType.AddRaw)); + this.AddItemToJewelItemDrop(angel); + var imp = this.CreatePet(1, "Imp", 28, (Stats.AttackDamageIncrease, 1.3f, AggregateType.Multiplicate)); + this.AddItemToJewelItemDrop(imp); + var uniria = this.CreatePet(2, "Horn of Uniria", 25); + this.AddItemToJewelItemDrop(uniria); } private ItemDefinition CreatePet(byte number, string name, int dropLevelAndLevelRequirement, params (AttributeDefinition, float, AggregateType)[] basePowerUps) diff --git a/src/Persistence/Initialization/Version075/Items/Potions.cs b/src/Persistence/Initialization/Version075/Items/Potions.cs index fb5f0e090..de721c266 100644 --- a/src/Persistence/Initialization/Version075/Items/Potions.cs +++ b/src/Persistence/Initialization/Version075/Items/Potions.cs @@ -11,7 +11,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Version075.Items; /// /// Class which contains item definitions for jewels. /// -public class Potions : InitializerBase +public class Potions : Jewels { /// /// Initializes a new instance of the class. @@ -54,6 +54,7 @@ private ItemDefinition CreateAlcohol() alcohol.Height = 2; alcohol.SetGuid(alcohol.Group, alcohol.Number); alcohol.ConsumeEffect = this.GameConfiguration.MagicEffects.First(effect => effect.Number == (short)MagicEffectNumber.Alcohol); + this.AddItemToJewelItemDrop(alcohol); return alcohol; } @@ -230,6 +231,7 @@ private ItemDefinition CreateTownPortalScroll() definition.Width = 1; definition.Height = 2; definition.SetGuid(definition.Group, definition.Number); + this.AddItemToJewelItemDrop(definition); return definition; } } \ No newline at end of file diff --git a/src/Persistence/Initialization/Version095d/Items/Pets.cs b/src/Persistence/Initialization/Version095d/Items/Pets.cs index 00650045c..4da38cfc2 100644 --- a/src/Persistence/Initialization/Version095d/Items/Pets.cs +++ b/src/Persistence/Initialization/Version095d/Items/Pets.cs @@ -15,7 +15,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Version095d.Items; /// /// Initializer for pets. /// -public class Pets : InitializerBase +public class Pets : Jewels { /// /// Initializes a new instance of the class. @@ -30,9 +30,12 @@ public Pets(IContext context, GameConfiguration gameConfiguration) /// public override void Initialize() { - this.CreatePet(0, 0, "Guardian Angel", 23, true, (Stats.DamageReceiveDecrement, 0.8f, AggregateType.Multiplicate), (Stats.MaximumHealth, 50f, AggregateType.AddRaw)); - this.CreatePet(1, 0, "Imp", 28, true, (Stats.AttackDamageIncrease, 1.3f, AggregateType.Multiplicate)); - this.CreatePet(2, 0, "Horn of Uniria", 25, true); + var angel = this.CreatePet(0, 0, "Guardian Angel", 23, true, (Stats.DamageReceiveDecrement, 0.8f, AggregateType.Multiplicate), (Stats.MaximumHealth, 50f, AggregateType.AddRaw)); + this.AddItemToJewelItemDrop(angel); + var imp = this.CreatePet(1, 0, "Imp", 28, true, (Stats.AttackDamageIncrease, 1.3f, AggregateType.Multiplicate)); + this.AddItemToJewelItemDrop(imp); + var uniria = this.CreatePet(2, 0, "Horn of Uniria", 25, true); + this.AddItemToJewelItemDrop(uniria); var dinorant = this.CreatePet(3, SkillNumber.FireBreath, "Horn of Dinorant", 110, false, (Stats.IsDinorantEquipped, 1, AggregateType.AddRaw), (Stats.DamageReceiveDecrement, 0.9f, AggregateType.Multiplicate), (Stats.AttackDamageIncrease, 1.15f, AggregateType.Multiplicate)); this.AddDinorantOptions(dinorant); diff --git a/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs b/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs index facdc13d2..074763154 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs @@ -19,7 +19,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Items; /// Initializer for pets. /// /// Pet system changed in Season 9. Reference: https://muonline.webzen.com/en/gameinfo/guide/detail/76 . -public class Pets : InitializerBase +public class Pets : Jewels { private const string PetExperienceFormula = "level * level * level * 100 * (level + 10)"; @@ -37,12 +37,15 @@ public Pets(IContext context, GameConfiguration gameConfiguration) public override void Initialize() { #pragma warning disable SA1117 // Parameters should be on same line or separete lines - this.CreatePet(0, 0, 1, 1, "Guardian Angel", 23, true, true, + var angel = this.CreatePet(0, 0, 1, 1, "Guardian Angel", 23, true, true, (Stats.DamageReceiveDecrement, 0.8f, AggregateType.Multiplicate), (Stats.MaximumHealth, 50f, AggregateType.AddRaw)); - this.CreatePet(1, 0, 1, 1, "Imp", 28, true, true, + this.AddItemToJewelItemDrop(angel); + var imp = this.CreatePet(1, 0, 1, 1, "Imp", 28, true, true, (Stats.AttackDamageIncrease, 1.3f, AggregateType.Multiplicate)); - this.CreatePet(2, 0, 1, 1, "Horn of Uniria", 25, true, true); + this.AddItemToJewelItemDrop(imp); + var uniria = this.CreatePet(2, 0, 1, 1, "Horn of Uniria", 25, true, true); + this.AddItemToJewelItemDrop(uniria); var dinorant = this.CreatePet(3, SkillNumber.FireBreath, 1, 1, "Horn of Dinorant", 110, false, true, (Stats.IsDinorantEquipped, 1, AggregateType.AddRaw), diff --git a/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs b/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs index 771d54f66..73a5fa8f5 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs @@ -14,7 +14,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Items; /// /// Class which contains item definitions for jewels. /// -public class Potions : InitializerBase +public class Potions : Jewels { /// /// Initializes a new instance of the class. @@ -75,6 +75,7 @@ private ItemDefinition CreateAlcohol() alcohol.Height = 2; alcohol.SetGuid(alcohol.Group, alcohol.Number); alcohol.ConsumeEffect = this.GameConfiguration.MagicEffects.First(effect => effect.Number == (short)MagicEffectNumber.Alcohol); + this.AddItemToJewelItemDrop(alcohol); return alcohol; } @@ -375,6 +376,7 @@ private ItemDefinition CreateTownPortalScroll() definition.Width = 1; definition.Height = 2; definition.SetGuid(definition.Group, definition.Number); + this.AddItemToJewelItemDrop(definition); return definition; } diff --git a/src/Persistence/Initialization/VersionSeasonSix/Maps/LandOfTrials.cs b/src/Persistence/Initialization/VersionSeasonSix/Maps/LandOfTrials.cs index e36603364..cf058611e 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Maps/LandOfTrials.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Maps/LandOfTrials.cs @@ -457,7 +457,7 @@ protected override void InitializeDropItemGroups() var jewelsDropItemGroup = this.Context.CreateNew(); jewelsDropItemGroup.SetGuid(this.MapNumber, 1); jewelsDropItemGroup.Chance = 0.001; - jewelsDropItemGroup.ItemType = SpecialItemType.RandomItem; + jewelsDropItemGroup.ItemType = SpecialItemType.Jewel; jewelsDropItemGroup.Description = "Jewel of Guardian"; var jewelOfGuardian = this.GameConfiguration.Items.First(y => y.Group == 14 && y.Number == 31); From bb25d5526dbc8482b0d8db46e5e8523555a9f475 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Thu, 19 Feb 2026 16:33:02 +0000 Subject: [PATCH 2/7] Removed List initialization as per Analyzer recommendation --- src/GameLogic/DefaultDropGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GameLogic/DefaultDropGenerator.cs b/src/GameLogic/DefaultDropGenerator.cs index 18c31cada..aa232982e 100644 --- a/src/GameLogic/DefaultDropGenerator.cs +++ b/src/GameLogic/DefaultDropGenerator.cs @@ -433,7 +433,7 @@ private void AddRandomExcOptions(Item item) else { var monsterLevel = (int)monster[Stats.Level]; - List filteredPossibleItems = []; + List filteredPossibleItems; if (selectedGroup.ItemType == SpecialItemType.Jewel) { From 3411943f9a93cdcacd47a79d76046c2330590721 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Wed, 4 Mar 2026 15:07:24 +0000 Subject: [PATCH 3/7] Moved method to Initializerbase --- src/Persistence/Initialization/InitializerBase.cs | 11 +++++++++++ .../Initialization/Version075/Items/Jewels.cs | 11 ----------- .../Initialization/Version075/Items/Pets.cs | 2 +- .../Initialization/Version095d/Items/Pets.cs | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Persistence/Initialization/InitializerBase.cs b/src/Persistence/Initialization/InitializerBase.cs index 2569d90c2..fbbc04969 100644 --- a/src/Persistence/Initialization/InitializerBase.cs +++ b/src/Persistence/Initialization/InitializerBase.cs @@ -195,4 +195,15 @@ protected IncreasableItemOption CreateItemOption(int number, AttributeDefinition return itemOption; } + + /// + /// Register the jewel (or jewel-like item) in the drop item group for jewels. + /// + /// The jewel you want to register. + protected void AddItemToJewelItemDrop(ItemDefinition item) + { + var id = GuidHelper.CreateGuid(4); + var jewelsItemDrop = this.GameConfiguration.DropItemGroups.First(x => x.GetId() == id); + jewelsItemDrop.PossibleItems.Add(item); + } } \ No newline at end of file diff --git a/src/Persistence/Initialization/Version075/Items/Jewels.cs b/src/Persistence/Initialization/Version075/Items/Jewels.cs index e08b7f0fb..961a4a51f 100644 --- a/src/Persistence/Initialization/Version075/Items/Jewels.cs +++ b/src/Persistence/Initialization/Version075/Items/Jewels.cs @@ -30,17 +30,6 @@ public override void Initialize() this.GameConfiguration.Items.Add(this.CreateJewelOfChaos()); } - /// - /// Register the jewel in the drop item group for jewels. - /// - /// The jewel you want to register. - protected void AddItemToJewelItemDrop(ItemDefinition item) - { - var id = GuidHelper.CreateGuid(4); - var jewelsItemDrop = this.GameConfiguration.DropItemGroups.First(x => x.GetId() == id); - jewelsItemDrop.PossibleItems.Add(item); - } - /// /// Creates an for the 'Jewel of Bless'. /// diff --git a/src/Persistence/Initialization/Version075/Items/Pets.cs b/src/Persistence/Initialization/Version075/Items/Pets.cs index bcddbb961..1d16abe57 100644 --- a/src/Persistence/Initialization/Version075/Items/Pets.cs +++ b/src/Persistence/Initialization/Version075/Items/Pets.cs @@ -14,7 +14,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Version075.Items; /// /// Initializer for pets. /// -public class Pets : Jewels +public class Pets : InitializerBase { /// /// Initializes a new instance of the class. diff --git a/src/Persistence/Initialization/Version095d/Items/Pets.cs b/src/Persistence/Initialization/Version095d/Items/Pets.cs index 4da38cfc2..d535ec284 100644 --- a/src/Persistence/Initialization/Version095d/Items/Pets.cs +++ b/src/Persistence/Initialization/Version095d/Items/Pets.cs @@ -15,7 +15,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Version095d.Items; /// /// Initializer for pets. /// -public class Pets : Jewels +public class Pets : InitializerBase { /// /// Initializes a new instance of the class. From 34e92b35fd30f65dad8f65560bca1b649a9153f6 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Wed, 4 Mar 2026 15:13:17 +0000 Subject: [PATCH 4/7] Forgot these --- src/Persistence/Initialization/Version075/Items/Potions.cs | 2 +- src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs | 2 +- .../Initialization/VersionSeasonSix/Items/Potions.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Persistence/Initialization/Version075/Items/Potions.cs b/src/Persistence/Initialization/Version075/Items/Potions.cs index de721c266..3a56d4b60 100644 --- a/src/Persistence/Initialization/Version075/Items/Potions.cs +++ b/src/Persistence/Initialization/Version075/Items/Potions.cs @@ -11,7 +11,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Version075.Items; /// /// Class which contains item definitions for jewels. /// -public class Potions : Jewels +public class Potions : InitializerBase { /// /// Initializes a new instance of the class. diff --git a/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs b/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs index 074763154..898571207 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Items/Pets.cs @@ -19,7 +19,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Items; /// Initializer for pets. /// /// Pet system changed in Season 9. Reference: https://muonline.webzen.com/en/gameinfo/guide/detail/76 . -public class Pets : Jewels +public class Pets : InitializerBase { private const string PetExperienceFormula = "level * level * level * 100 * (level + 10)"; diff --git a/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs b/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs index 73a5fa8f5..bfa2d41de 100644 --- a/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs +++ b/src/Persistence/Initialization/VersionSeasonSix/Items/Potions.cs @@ -14,7 +14,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Items; /// /// Class which contains item definitions for jewels. /// -public class Potions : Jewels +public class Potions : InitializerBase { /// /// Initializes a new instance of the class. From 6743719cb1ed00bbb2d543ceb1dc563e28ffcf91 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Wed, 4 Mar 2026 16:14:31 +0000 Subject: [PATCH 5/7] Added constant for item-monster drop level max gap --- src/GameLogic/DefaultDropGenerator.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/GameLogic/DefaultDropGenerator.cs b/src/GameLogic/DefaultDropGenerator.cs index aa232982e..5fc1fe2cc 100644 --- a/src/GameLogic/DefaultDropGenerator.cs +++ b/src/GameLogic/DefaultDropGenerator.cs @@ -18,6 +18,8 @@ public class DefaultDropGenerator : IDropGenerator /// public static readonly int BaseMoneyDrop = 7; + private static readonly int DropLevelMaxGap = 12; + private readonly IRandomizer _randomizer; /// @@ -447,7 +449,7 @@ private void AddRandomExcOptions(Item item) } else { - filteredPossibleItems = [.. selectedGroup.PossibleItems.Where(it => it.DropLevel == 0 || (it.DropLevel <= monsterLevel && it.DropLevel > monsterLevel - 12))]; + filteredPossibleItems = [.. selectedGroup.PossibleItems.Where(it => it.DropLevel == 0 || (it.DropLevel <= monsterLevel && it.DropLevel > monsterLevel - DropLevelMaxGap))]; } return this.GenerateItemDrop(selectedGroup, filteredPossibleItems); @@ -506,7 +508,7 @@ private void AddRandomExcOptions(Item item) return this._droppableItemsPerMonsterLevel[monsterLevel] ??= (from it in this._droppableItems where (it.DropLevel <= monsterLevel) - && (it.DropLevel > monsterLevel - 12) + && (it.DropLevel > monsterLevel - DropLevelMaxGap) && (!socketItems || it.MaximumSockets > 0) select it).ToList(); } From 282d2d69d573178cbec773196393101acd48970e Mon Sep 17 00:00:00 2001 From: ze-dom Date: Thu, 5 Mar 2026 16:28:03 +0000 Subject: [PATCH 6/7] Added update plugins --- .../RemoveJewelDropLevelGapPlugIn075.cs | 30 ++++++++++ .../RemoveJewelDropLevelGapPlugIn095d.cs | 30 ++++++++++ .../RemoveJewelDropLevelGapPlugInBase.cs | 58 +++++++++++++++++++ .../RemoveJewelDropLevelGapPlugInSeason6.cs | 36 ++++++++++++ .../Initialization/Updates/UpdateVersion.cs | 15 +++++ 5 files changed, 169 insertions(+) create mode 100644 src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs create mode 100644 src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs create mode 100644 src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInBase.cs create mode 100644 src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInSeason6.cs diff --git a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs new file mode 100644 index 000000000..437771d7b --- /dev/null +++ b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs @@ -0,0 +1,30 @@ +// +// 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.PlugIns; + +/// +/// This update removes the existing drop level gap condition for jewels and similar items that should always drop. +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("CD958BC1-F17A-4C60-B66D-BD29D49B6ADA")] +public class RemoveJewelDropLevelGapPlugIn075 : RemoveJewelDropLevelGapPlugInBase +{ + /// + public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + + /// + public override UpdateVersion Version => UpdateVersion.RemoveJewelDropLevelGap075; + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + await base.ApplyAsync(context, gameConfiguration).ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs new file mode 100644 index 000000000..6864d8117 --- /dev/null +++ b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs @@ -0,0 +1,30 @@ +// +// 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.PlugIns; + +/// +/// This update removes the existing drop level gap condition for jewels and similar items that should always drop. +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("6614E91E-5749-478A-96A4-3240E7C1280E")] +public class RemoveJewelDropLevelGapPlugIn095D : RemoveJewelDropLevelGapPlugInBase +{ + /// + public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + + /// + public override UpdateVersion Version => UpdateVersion.RemoveJewelDropLevelGap095d; + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + await base.ApplyAsync(context, gameConfiguration).ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInBase.cs b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInBase.cs new file mode 100644 index 000000000..f383bce2e --- /dev/null +++ b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInBase.cs @@ -0,0 +1,58 @@ +// +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// + +namespace MUnique.OpenMU.Persistence.Initialization.Updates; + +using MUnique.OpenMU.DataModel.Configuration; +using MUnique.OpenMU.Persistence.Initialization.Items; + +/// +/// This update removes the existing drop level gap condition for jewels and similar items that should always drop. +/// +public abstract class RemoveJewelDropLevelGapPlugInBase : UpdatePlugInBase +{ + /// + /// The plug in name. + /// + internal const string PlugInName = "Remove Jewel Drop Level Gap"; + + /// + /// The plug in description. + /// + internal const string PlugInDescription = "This update removes the existing drop level gap condition for jewels and similar items that should always drop."; + + /// + public override string Name => PlugInName; + + /// + public override string Description => PlugInDescription; + + /// + public override bool IsMandatory => true; + + /// + public override DateTime CreatedAt => new(2026, 3, 5, 16, 0, 0, DateTimeKind.Utc); + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + var jewelsDropGroupId = new Guid("00000200-0004-0000-0000-000000000000"); + var jewelsDropGroup = gameConfiguration.DropItemGroups.First(x => x.GetId() == jewelsDropGroupId); + jewelsDropGroup.ItemType = SpecialItemType.Jewel; + + Dictionary> itemGroupToItemNumbers = new() + { + { ItemGroups.Misc1, [0, 1, 2] }, // angel, imp, uniria + { ItemGroups.Misc2, [9, 10] }, // alcohol, town portal scroll + }; + foreach (var entry in itemGroupToItemNumbers) + { + var items = gameConfiguration.Items.Where(i => i.Group == (int)entry.Key && entry.Value.Contains(i.Number)); + foreach (var item in items) + { + jewelsDropGroup.PossibleItems.Add(item); + } + } + } +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInSeason6.cs b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInSeason6.cs new file mode 100644 index 000000000..3e2dc2947 --- /dev/null +++ b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugInSeason6.cs @@ -0,0 +1,36 @@ +// +// 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.PlugIns; + +/// +/// This update removes the existing drop level gap condition for jewels and similar items that should always drop. +/// +[PlugIn] +[Display(Name = PlugInName, Description = PlugInDescription)] +[Guid("AB1C9F8B-5E3B-4F2A-BDCD-9C0F1E5A6B7C")] +public class RemoveJewelDropLevelGapPlugInSeason6 : RemoveJewelDropLevelGapPlugInBase +{ + /// + public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + + /// + public override UpdateVersion Version => UpdateVersion.RemoveJewelDropLevelGapSeason6; + + /// + protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) + { + await base.ApplyAsync(context, gameConfiguration).ConfigureAwait(false); + + var jewelOfGuardianDropGroupId = new Guid("00000200-001f-0001-0000-000000000000"); + if (gameConfiguration.DropItemGroups.FirstOrDefault(x => x.GetId() == jewelOfGuardianDropGroupId) is { } jewelOfGuardianDropGroup) + { + jewelOfGuardianDropGroup.ItemType = SpecialItemType.Jewel; + } + } +} \ No newline at end of file diff --git a/src/Persistence/Initialization/Updates/UpdateVersion.cs b/src/Persistence/Initialization/Updates/UpdateVersion.cs index 1e771cc39..3c2993923 100644 --- a/src/Persistence/Initialization/Updates/UpdateVersion.cs +++ b/src/Persistence/Initialization/Updates/UpdateVersion.cs @@ -344,4 +344,19 @@ public enum UpdateVersion /// The version of the . /// AddProjectileCountToTripleShot = 67, + + /// + /// The version of the . + /// + RemoveJewelDropLevelGap075 = 68, + + /// + /// The version of the . + /// + RemoveJewelDropLevelGap095d = 69, + + /// + /// The version of the . + /// + RemoveJewelDropLevelGapSeason6 = 70, } \ No newline at end of file From 863821988c62192d1f33b586f09bf07f4942f265 Mon Sep 17 00:00:00 2001 From: ze-dom Date: Thu, 5 Mar 2026 17:45:02 +0000 Subject: [PATCH 7/7] Fixed data initialization keys for plugins --- .../Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs | 2 +- .../Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs index 437771d7b..84c188f98 100644 --- a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs +++ b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn075.cs @@ -17,7 +17,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Updates; public class RemoveJewelDropLevelGapPlugIn075 : RemoveJewelDropLevelGapPlugInBase { /// - public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + public override string DataInitializationKey => Version075.DataInitialization.Id; /// public override UpdateVersion Version => UpdateVersion.RemoveJewelDropLevelGap075; diff --git a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs index 6864d8117..8bd82191a 100644 --- a/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs +++ b/src/Persistence/Initialization/Updates/RemoveJewelDropLevelGapPlugIn095d.cs @@ -17,7 +17,7 @@ namespace MUnique.OpenMU.Persistence.Initialization.Updates; public class RemoveJewelDropLevelGapPlugIn095D : RemoveJewelDropLevelGapPlugInBase { /// - public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; + public override string DataInitializationKey => Version095d.DataInitialization.Id; /// public override UpdateVersion Version => UpdateVersion.RemoveJewelDropLevelGap095d;