-
Notifications
You must be signed in to change notification settings - Fork 478
feat(persistence): add Crest of Monarch drop group in Icarus #709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| // <copyright file="AddCrestOfMonarchDropGroupUpdateSeason6.cs" company="MUnique"> | ||
| // Licensed under the MIT License. See LICENSE file in the project root for full license information. | ||
| // </copyright> | ||
|
|
||
| namespace MUnique.OpenMU.Persistence.Initialization.Updates; | ||
|
|
||
| using System.Runtime.InteropServices; | ||
| using MUnique.OpenMU.DataModel.Configuration; | ||
| using MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Maps; | ||
| using MUnique.OpenMU.PlugIns; | ||
|
|
||
| /// <summary> | ||
| /// This update adds the Crest of Monarch drop item group for the Icarus map. | ||
| /// </summary> | ||
| [PlugIn] | ||
| [Display(Name = PlugInName, Description = PlugInDescription)] | ||
| [Guid("FF14A478-3EA8-4C41-A298-8E6698D5973D")] | ||
| public class AddCrestOfMonarchDropGroupUpdateSeason6 : UpdatePlugInBase | ||
| { | ||
| /// <summary> | ||
| /// The plug in name. | ||
| /// </summary> | ||
| internal const string PlugInName = "Add Crest of Monarch Drop Group"; | ||
|
|
||
| /// <summary> | ||
| /// The plug in description. | ||
| /// </summary> | ||
| internal const string PlugInDescription = "Adds the Crest of Monarch (Loch's Feather +1) drop item group to Icarus."; | ||
|
|
||
| /// <inheritdoc /> | ||
| public override UpdateVersion Version => UpdateVersion.AddCrestOfMonarchDropGroupSeason6; | ||
|
|
||
| /// <inheritdoc /> | ||
| public override string DataInitializationKey => VersionSeasonSix.DataInitialization.Id; | ||
|
|
||
| /// <inheritdoc /> | ||
| public override string Name => PlugInName; | ||
|
|
||
| /// <inheritdoc /> | ||
| public override string Description => PlugInDescription; | ||
|
|
||
| /// <inheritdoc /> | ||
| public override bool IsMandatory => true; | ||
|
|
||
| /// <inheritdoc /> | ||
| public override DateTime CreatedAt => new(2026, 03, 13, 12, 0, 0, DateTimeKind.Utc); | ||
|
|
||
| /// <inheritdoc /> | ||
| #pragma warning disable CS1998 | ||
| protected override async ValueTask ApplyAsync(IContext context, GameConfiguration gameConfiguration) | ||
| #pragma warning restore CS1998 | ||
| { | ||
| var map = gameConfiguration.Maps.First(m => m.Number == Icarus.Number && m.Discriminator == 0); | ||
| var lochsFeather = gameConfiguration.Items.First(item => item.Group == 13 && item.Number == 14); | ||
| var crestId = GuidHelper.CreateGuid<DropItemGroup>(Icarus.Number, 2); | ||
|
|
||
| var crestGroup = gameConfiguration.DropItemGroups.FirstOrDefault(group => group.GetId() == crestId); | ||
| if (crestGroup is null) | ||
| { | ||
| crestGroup = context.CreateNew<DropItemGroup>(); | ||
| crestGroup.SetGuid(Icarus.Number, 2); | ||
| gameConfiguration.DropItemGroups.Add(crestGroup); | ||
| } | ||
|
|
||
| crestGroup.Description = "Crest of Monarch"; | ||
| crestGroup.Chance = 0.001; | ||
| crestGroup.MinimumMonsterLevel = 82; | ||
| crestGroup.MaximumMonsterLevel = null; | ||
| crestGroup.ItemLevel = 1; | ||
| if (crestGroup.PossibleItems.Count != 1 || crestGroup.PossibleItems.First().GetItemId() != lochsFeather.GetItemId()) | ||
| { | ||
| crestGroup.PossibleItems.Clear(); | ||
| crestGroup.PossibleItems.Add(lochsFeather); | ||
| } | ||
|
|
||
| if (!map.DropItemGroups.Any(group => group.GetId() == crestGroup.GetId())) | ||
| { | ||
| map.DropItemGroups.Add(crestGroup); | ||
| } | ||
| } | ||
|
Comment on lines
+52
to
+80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method contains several magic numbers (e.g., For example, you could define constants at the class level: private const byte LochsFeatherItemGroup = 13;
private const short LochsFeatherItemNumber = 14;
private const short CrestOfMonarchDropItemGroupId = 2;
private const double ItemDropChance = 0.001;
private const byte MinimumMonsterLevel = 82;
private const byte CrestOfMonarchItemLevel = 1; |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,10 +5,13 @@ | |
| namespace MUnique.OpenMU.Persistence.Initialization.Tests; | ||
|
|
||
| using Microsoft.Extensions.Logging.Abstractions; | ||
| using MUnique.OpenMU.AttributeSystem; | ||
| using MUnique.OpenMU.DataModel; | ||
| using MUnique.OpenMU.DataModel.Configuration; | ||
| using MUnique.OpenMU.GameLogic; | ||
| using MUnique.OpenMU.Persistence.EntityFramework; | ||
| using MUnique.OpenMU.Persistence.Initialization.Updates; | ||
| using MUnique.OpenMU.Persistence.Initialization.VersionSeasonSix.Maps; | ||
| using MUnique.OpenMU.Persistence.InMemory; | ||
|
|
||
| /// <summary> | ||
|
|
@@ -47,9 +50,47 @@ public async Task TestSeason6DataAsync() | |
| var contextProvider = new InMemoryPersistenceContextProvider(); | ||
| var dataInitialization = new VersionSeasonSix.DataInitialization(contextProvider, new NullLoggerFactory()); | ||
| await dataInitialization.CreateInitialDataAsync(1, true).ConfigureAwait(false); | ||
| await this.AssertIcarusFeatherAndCrestDropGroupsAsync(contextProvider).ConfigureAwait(false); | ||
| await this.TestIfItemsFitIntoInventoriesAsync(contextProvider).ConfigureAwait(false); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Tests that applying the update for Crest of Monarch in Season 6 is idempotent. | ||
| /// </summary> | ||
| [Test] | ||
| public async Task TestSeason6CrestOfMonarchUpdatePlugInAsync() | ||
| { | ||
| var contextProvider = new InMemoryPersistenceContextProvider(); | ||
| var dataInitialization = new VersionSeasonSix.DataInitialization(contextProvider, new NullLoggerFactory()); | ||
| await dataInitialization.CreateInitialDataAsync(1, true).ConfigureAwait(false); | ||
|
|
||
| using var context = contextProvider.CreateNewContext(); | ||
| var gameConfiguration = (await context.GetAsync<GameConfiguration>().ConfigureAwait(false)).First(); | ||
| var map = gameConfiguration.Maps.First(m => m.Number == Icarus.Number && m.Discriminator == 0); | ||
|
|
||
| var crestGroupId = GuidHelper.CreateGuid<DropItemGroup>(Icarus.Number, 2); | ||
| if (gameConfiguration.DropItemGroups.FirstOrDefault(group => group.GetId() == crestGroupId) is { } existingCrestGroup) | ||
| { | ||
| map.DropItemGroups.Remove(existingCrestGroup); | ||
| gameConfiguration.DropItemGroups.Remove(existingCrestGroup); | ||
| } | ||
|
|
||
| var update = new AddCrestOfMonarchDropGroupUpdateSeason6(); | ||
| await update.ApplyUpdateAsync(context, gameConfiguration).ConfigureAwait(false); | ||
| await update.ApplyUpdateAsync(context, gameConfiguration).ConfigureAwait(false); | ||
|
|
||
| var groups = gameConfiguration.DropItemGroups.Where(group => group.GetId() == crestGroupId).ToList(); | ||
| Assert.That(groups, Has.Count.EqualTo(1)); | ||
| Assert.That(map.DropItemGroups.Count(group => group.GetId() == crestGroupId), Is.EqualTo(1)); | ||
| Assert.That(groups[0].Description.ToString(), Is.EqualTo("Crest of Monarch")); | ||
| Assert.That(groups[0].Chance, Is.EqualTo(0.001)); | ||
| Assert.That(groups[0].MinimumMonsterLevel, Is.EqualTo((byte)82)); | ||
| Assert.That(groups[0].ItemLevel, Is.EqualTo((byte)1)); | ||
| Assert.That(groups[0].PossibleItems, Has.Count.EqualTo(1)); | ||
| Assert.That(groups[0].PossibleItems.Single().Group, Is.EqualTo((byte)13)); | ||
| Assert.That(groups[0].PossibleItems.Single().Number, Is.EqualTo((short)14)); | ||
|
Comment on lines
+85
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These assertions use hardcoded values (e.g., |
||
| } | ||
|
|
||
| /// <summary> | ||
| /// Tests the data initialization using the in-memory persistence. | ||
| /// </summary> | ||
|
|
@@ -114,4 +155,35 @@ private async Task TestIfItemsFitIntoInventoriesAsync(IPersistenceContextProvide | |
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private async Task AssertIcarusFeatherAndCrestDropGroupsAsync(IPersistenceContextProvider contextProvider) | ||
| { | ||
| using var context = contextProvider.CreateNewConfigurationContext(); | ||
| var gameConfiguration = (await context.GetAsync<GameConfiguration>().ConfigureAwait(false)).First(); | ||
| var map = gameConfiguration.Maps.First(m => m.Number == Icarus.Number && m.Discriminator == 0); | ||
|
|
||
| var lochsFeatherGroupId = GuidHelper.CreateGuid<DropItemGroup>(Icarus.Number, 1); | ||
| var crestGroupId = GuidHelper.CreateGuid<DropItemGroup>(Icarus.Number, 2); | ||
| var featherGroup = gameConfiguration.DropItemGroups.Single(group => group.GetId() == lochsFeatherGroupId); | ||
| var crestGroup = gameConfiguration.DropItemGroups.Single(group => group.GetId() == crestGroupId); | ||
|
|
||
| Assert.That(map.DropItemGroups.Any(group => group.GetId() == lochsFeatherGroupId), Is.True); | ||
| Assert.That(map.DropItemGroups.Any(group => group.GetId() == crestGroupId), Is.True); | ||
|
|
||
| Assert.That(featherGroup.Description.ToString(), Is.EqualTo("Loch's Feather")); | ||
| Assert.That(featherGroup.Chance, Is.EqualTo(0.001)); | ||
| Assert.That(featherGroup.MinimumMonsterLevel, Is.EqualTo((byte)82)); | ||
| Assert.That(featherGroup.ItemLevel, Is.Null); | ||
| Assert.That(featherGroup.PossibleItems, Has.Count.EqualTo(1)); | ||
| Assert.That(featherGroup.PossibleItems.Single().Group, Is.EqualTo((byte)13)); | ||
| Assert.That(featherGroup.PossibleItems.Single().Number, Is.EqualTo((short)14)); | ||
|
|
||
| Assert.That(crestGroup.Description.ToString(), Is.EqualTo("Crest of Monarch")); | ||
| Assert.That(crestGroup.Chance, Is.EqualTo(0.001)); | ||
| Assert.That(crestGroup.MinimumMonsterLevel, Is.EqualTo((byte)82)); | ||
| Assert.That(crestGroup.ItemLevel, Is.EqualTo((byte)1)); | ||
| Assert.That(crestGroup.PossibleItems, Has.Count.EqualTo(1)); | ||
| Assert.That(crestGroup.PossibleItems.Single().Group, Is.EqualTo((byte)13)); | ||
| Assert.That(crestGroup.PossibleItems.Single().Number, Is.EqualTo((short)14)); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.