Skip to content

Commit

Permalink
Merge pull request #414 from MUnique/dev/fix-sets
Browse files Browse the repository at this point in the history
Fixed item set completion bonuses
  • Loading branch information
sven-n authored Jun 8, 2024
2 parents d59e889 + 2421611 commit 3ac0828
Show file tree
Hide file tree
Showing 18 changed files with 10,105 additions and 75 deletions.
9 changes: 5 additions & 4 deletions src/DataModel/Configuration/Items/ItemSetGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace MUnique.OpenMU.DataModel.Configuration.Items;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.DataModel.Entities;

/// <summary>
/// Defines an item set group. With (partial) completion of the set, additional options are getting applied.
Expand All @@ -28,8 +29,9 @@ public partial class ItemSetGroup
public string Name { get; set; } = string.Empty;

/// <summary>
/// Gets or sets a value indicating whether all of the options of this item set always apply.
/// If not, the minimum item count and the minimum set levels are respected.
/// Gets or sets a value indicating whether the options of this item set always apply to an item,
/// even if the group wasn't explicitly added to the <see cref="Item.ItemSetGroups"/>.
/// The minimum item count and the minimum set levels are respected.
/// </summary>
public bool AlwaysApplies { get; set; }

Expand Down Expand Up @@ -57,8 +59,7 @@ public partial class ItemSetGroup
/// <remarks>
/// The order is defined by <see cref="ItemOption.Number"/>.
/// </remarks>
[MemberOfAggregate]
public virtual ICollection<IncreasableItemOption> Options { get; protected set; } = null!;
public virtual ItemOptionDefinition? Options { get; set; } = null!;

/// <summary>
/// Gets or sets the items of this set.
Expand Down
1 change: 0 additions & 1 deletion src/DataModel/GameConfigurationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public static class GameConfigurationHelper
{ typeof(ItemOptionDefinition), c => c.ItemOptions },
{
typeof(IncreasableItemOption), c => c.ItemOptions.SelectMany(o => o.PossibleOptions)
.Concat(c.ItemSetGroups.SelectMany(o => o.Options))
},
{ typeof(ItemSetGroup), c => c.ItemSetGroups },
{ typeof(ItemOfItemSet), c => c.ItemSetGroups.SelectMany(o => o.Items) },
Expand Down
4 changes: 2 additions & 2 deletions src/GameLogic/DefaultDropGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public DefaultDropGenerator(GameConfiguration config, IRandomizer randomizer)
{
this._randomizer = randomizer;
this._droppableItems = config.Items.Where(i => i.DropsFromMonsters).ToList();
this._ancientItems = this._droppableItems.Where(i => i.PossibleItemSetGroups.Any(o => o.Options.Any(o => o.OptionType == ItemOptionTypes.AncientOption))).ToList();
this._ancientItems = this._droppableItems.Where(i => i.PossibleItemSetGroups.Any(o => o.Options?.PossibleOptions.Any(o => o.OptionType == ItemOptionTypes.AncientOption) ?? false)).ToList();
}

/// <inheritdoc/>
Expand Down Expand Up @@ -327,7 +327,7 @@ private static bool IsGroupRelevant(MonsterDefinition monsterDefinition, DropIte

private void ApplyRandomAncientOption(Item item)
{
var ancientSet = item.Definition?.PossibleItemSetGroups.Where(g => g!.Options.Any(o => o.OptionType == ItemOptionTypes.AncientOption)).SelectRandom(this._randomizer);
var ancientSet = item.Definition?.PossibleItemSetGroups.Where(g => g!.Options?.PossibleOptions.Any(o => o.OptionType == ItemOptionTypes.AncientOption) ?? false).SelectRandom(this._randomizer);
if (ancientSet is null)
{
return;
Expand Down
29 changes: 17 additions & 12 deletions src/GameLogic/ItemPowerUpFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,14 @@ public IEnumerable<PowerUpWrapper> GetSetPowerUps(
.Distinct();

var result = Enumerable.Empty<PowerUpDefinition>();
foreach (var group in itemGroups)
{
if (group.AlwaysApplies)
{
result = result.Concat(group.Options.Select(o => o.PowerUpDefinition ?? throw Error.NotInitializedProperty(o, nameof(o.PowerUpDefinition))));

continue;
}
var alwaysGroups = activeItems.SelectMany(i => i.Definition!.PossibleItemSetGroups).Where(i => i.AlwaysApplies).Distinct();

var itemsOfGroup = activeItems.Where(i => i.ItemSetGroups.Any(ios => ios.ItemSetGroup == group)
&& (group.SetLevel == 0 || i.Level >= group.SetLevel));
foreach (var group in alwaysGroups.Concat(itemGroups).Distinct())
{
var itemsOfGroup = activeItems.Where(i =>
((group.AlwaysApplies && i.Definition!.PossibleItemSetGroups.Contains(group))
|| i.ItemSetGroups.Any(ios => ios.ItemSetGroup == group))
&& (group.SetLevel == 0 || i.Level >= group.SetLevel));
var setMustBeComplete = group.MinimumItemCount == group.Items.Count;
if (group.SetLevel > 0 && setMustBeComplete && itemsOfGroup.All(i => i.Level > group.SetLevel))
{
Expand All @@ -97,19 +94,27 @@ public IEnumerable<PowerUpWrapper> GetSetPowerUps(
continue;
}

if (group.Options is not { } options)
{
this._logger.LogWarning("Options of set {group} is not initialized", group);
continue;
}

var itemCount = group.CountDistinct ? itemsOfGroup.Select(item => item.Definition).Distinct().Count() : itemsOfGroup.Count();
var setIsComplete = itemCount == group.Items.Count;
if (setIsComplete)
{
// Take all options when the set is complete
result = result.Concat(group.Options.Select(o => o.PowerUpDefinition ?? throw Error.NotInitializedProperty(o, nameof(o.PowerUpDefinition))));
result = result.Concat(
options.PossibleOptions
.Select(o => o.PowerUpDefinition ?? throw Error.NotInitializedProperty(o, nameof(o.PowerUpDefinition))));
continue;
}

if (itemCount >= group.MinimumItemCount)
{
// Take the first n-1 options
result = result.Concat(group.Options.OrderBy(o => o.Number)
result = result.Concat(options.PossibleOptions.OrderBy(o => o.Number)
.Take(itemCount - 1)
.Select(o => o.PowerUpDefinition ?? throw Error.NotInitializedProperty(o, nameof(o.PowerUpDefinition))));
}
Expand Down
2 changes: 1 addition & 1 deletion src/GameServer/RemoteView/IItemSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ private static void ReadAncientOption(byte ancientByte, IContext persistenceCont
var bonusLevel = (ancientByte & AncientBonusLevelMask) >> 2;
var setDiscriminator = ancientByte & AncientDiscriminatorMask;
var ancientSets = item.Definition!.PossibleItemSetGroups
.Where(set => set.Options.Any(o => o.OptionType == ItemOptionTypes.AncientOption))
.Where(set => set.Options?.PossibleOptions.Any(o => o.OptionType == ItemOptionTypes.AncientOption) ?? false)
.SelectMany(i => i.Items).Where(i => i.ItemDefinition == item.Definition)
.Where(set => set.AncientSetDiscriminator == setDiscriminator).ToList();
if (ancientSets.Count > 1)
Expand Down
39 changes: 18 additions & 21 deletions src/Persistence/BasicModel/ItemSetGroup.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,6 @@ public partial class ItemSetGroup : MUnique.OpenMU.DataModel.Configuration.Items
/// </summary>
public Guid Id { get; set; }

/// <summary>
/// Gets the raw collection of <see cref="Options" />.
/// </summary>
[System.Text.Json.Serialization.JsonPropertyName("options")]
public ICollection<IncreasableItemOption> RawOptions { get; } = new List<IncreasableItemOption>();

/// <inheritdoc/>
[System.Text.Json.Serialization.JsonIgnore]
public override ICollection<MUnique.OpenMU.DataModel.Configuration.Items.IncreasableItemOption> Options
{
get => base.Options ??= new CollectionAdapter<MUnique.OpenMU.DataModel.Configuration.Items.IncreasableItemOption, IncreasableItemOption>(this.RawOptions);
protected set
{
this.Options.Clear();
foreach (var item in value)
{
this.Options.Add(item);
}
}
}

/// <summary>
/// Gets the raw collection of <see cref="Items" />.
/// </summary>
Expand All @@ -67,6 +46,24 @@ protected set
}
}

/// <summary>
/// Gets the raw object of <see cref="Options" />.
/// </summary>
[System.Text.Json.Serialization.JsonPropertyName("options")]
public ItemOptionDefinition RawOptions
{
get => base.Options as ItemOptionDefinition;
set => base.Options = value;
}

/// <inheritdoc/>
[System.Text.Json.Serialization.JsonIgnore]
public override MUnique.OpenMU.DataModel.Configuration.Items.ItemOptionDefinition Options
{
get => base.Options;
set => base.Options = value;
}

/// <inheritdoc />
public override MUnique.OpenMU.DataModel.Configuration.Items.ItemSetGroup Clone(MUnique.OpenMU.DataModel.Configuration.GameConfiguration gameConfiguration)
{
Expand Down
5 changes: 3 additions & 2 deletions src/Persistence/EntityFramework/CachingRepositoryProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ protected override void Initialize()

this.RegisterRepository(new ConfigurationTypeRepository<ItemOptionDefinition>(this._parent, this.LoggerFactory, config => config.RawItemOptions));
this.RegisterRepository(new ConfigurationTypeRepository<IncreasableItemOption>(
this._parent, this.LoggerFactory,
config => config.RawItemOptions.SelectMany(o => o.RawPossibleOptions).Concat(config.RawItemSetGroups.SelectMany(g => g.RawOptions)).Distinct().ToList()));
this._parent,
this.LoggerFactory,
config => config.RawItemOptions.SelectMany(o => o.RawPossibleOptions).Distinct().ToList()));
this.RegisterRepository(new ConfigurationTypeRepository<AttributeDefinition>(this._parent, this.LoggerFactory, config => config.RawAttributes));
this.RegisterRepository(new ConfigurationTypeRepository<DropItemGroup>(this._parent, this.LoggerFactory, config => config.RawDropItemGroups));
this.RegisterRepository(new ConfigurationTypeRepository<CharacterClass>(this._parent, this.LoggerFactory, config => config.RawCharacterClasses));
Expand Down
Loading

0 comments on commit 3ac0828

Please sign in to comment.