This commit is contained in:
Lightczx
2024-06-11 14:00:48 +08:00
parent 23741c4e48
commit 7cfcc17763
2 changed files with 58 additions and 21 deletions

View File

@@ -199,6 +199,13 @@ internal static partial class EnumerableExtension
return list;
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static List<TSource> SortBy<TSource, TKey>(this List<TSource> list, Func<TSource, TKey> keySelector, Comparison<TKey> comparison)
{
list.Sort((left, right) => comparison(keySelector(left), keySelector(right)));
return list;
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static List<TSource> SortByDescending<TSource, TKey>(this List<TSource> list, Func<TSource, TKey> keySelector)
where TKey : IComparable
@@ -213,4 +220,11 @@ internal static partial class EnumerableExtension
list.Sort((left, right) => comparer.Compare(keySelector(right), keySelector(left)));
return list;
}
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static List<TSource> SortByDescending<TSource, TKey>(this List<TSource> list, Func<TSource, TKey> keySelector, Comparison<TKey> comparison)
{
list.Sort((left, right) => comparison(keySelector(right), keySelector(left)));
return list;
}
}

View File

@@ -3,6 +3,7 @@
using Google.OrTools.LinearSolver;
using Microsoft.Extensions.Caching.Memory;
using Snap.Hutao.Core;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Model.Metadata.Abstraction;
using Snap.Hutao.Model.Primitive;
@@ -35,7 +36,13 @@ internal sealed partial class MinimalPromotionDelta
.. (await metadataService.GetAvatarListAsync().ConfigureAwait(false)).Where(a => a.BeginTime <= DateTimeOffset.Now),
.. (await metadataService.GetWeaponListAsync().ConfigureAwait(false)).Where(w => w.Quality >= Model.Intrinsic.QualityType.QUALITY_BLUE),
];
return memoryCache.Set(CacheKey, GeneratePromotionDeltas(Minimize(cultivationItemsEntryList)));
List<ICultivationItemsAccess> minimal = Minimize(cultivationItemsEntryList);
// Gurantee the order of avatar and weapon
// Make sure weapons can have avatar to attach
minimal.Sort(CultivationItemsAccessComparer.Shared);
return memoryCache.Set(CacheKey, ToPromotionDeltaList(minimal));
}
private static List<ICultivationItemsAccess> Minimize(List<ICultivationItemsAccess> cultivationItems)
@@ -82,9 +89,10 @@ internal sealed partial class MinimalPromotionDelta
}
}
private static List<AvatarPromotionDelta> GeneratePromotionDeltas(List<ICultivationItemsAccess> cultivationItems)
private static List<AvatarPromotionDelta> ToPromotionDeltaList(List<ICultivationItemsAccess> cultivationItems)
{
List<AvatarPromotionDelta> deltas = [];
int currentWeaponEmptyAvatarIndex = 0;
foreach (ref readonly ICultivationItemsAccess item in CollectionsMarshal.AsSpan(cultivationItems))
{
@@ -103,29 +111,27 @@ internal sealed partial class MinimalPromotionDelta
LevelTarget = 10,
}),
});
break;
case MetadataWeapon weapon:
if (deltas.FirstOrDefault(d => d.Weapon is null) is { } delta)
{
delta.Weapon = new()
{
Id = weapon.Id,
LevelCurrent = 1,
LevelTarget = 90,
};
break;
break;
case MetadataWeapon weapon:
AvatarPromotionDelta delta;
if (currentWeaponEmptyAvatarIndex < deltas.Count)
{
delta = deltas[currentWeaponEmptyAvatarIndex++];
}
else
{
delta = new();
deltas.Add(delta);
}
deltas.Add(new()
delta.Weapon = new()
{
Weapon = new()
{
Id = weapon.Id,
LevelCurrent = 1,
LevelTarget = 90,
},
});
Id = weapon.Id,
LevelCurrent = 1,
LevelTarget = 90,
};
break;
}
@@ -133,4 +139,21 @@ internal sealed partial class MinimalPromotionDelta
return deltas;
}
private sealed class CultivationItemsAccessComparer : IComparer<ICultivationItemsAccess>
{
private static readonly LazySlim<CultivationItemsAccessComparer> LazyShared = new(() => new());
public static CultivationItemsAccessComparer Shared { get => LazyShared.Value; }
public int Compare(ICultivationItemsAccess? x, ICultivationItemsAccess? y)
{
return (x, y) switch
{
(MetadataAvatar, MetadataWeapon) => -1,
(MetadataWeapon, MetadataAvatar) => 1,
_ => 0,
};
}
}
}