From 387a4edcfab4c91294f7b4b12b09a6cffccdcab8 Mon Sep 17 00:00:00 2001 From: qhy040404 Date: Fri, 29 Nov 2024 13:38:27 +0800 Subject: [PATCH] inventory combine --- .../Model/Intrinsic/Frozen/IntrinsicFrozen.cs | 7 + .../Model/Metadata/Item/DisplayItem.cs | 2 + .../Model/Metadata/Item/Material.cs | 18 ++ .../Service/Cultivation/CultivationService.cs | 185 ++++++++++++++---- .../Cultivation/ResinStatisticsItem.cs | 2 +- .../Cultivation/StatisticsCultivateItem.cs | 6 +- 6 files changed, 173 insertions(+), 47 deletions(-) diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Frozen/IntrinsicFrozen.cs b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Frozen/IntrinsicFrozen.cs index 0a203dbefd..67cb85e28f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Frozen/IntrinsicFrozen.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/Frozen/IntrinsicFrozen.cs @@ -60,6 +60,13 @@ internal static class IntrinsicFrozen SH.ModelMetadataMaterialWeaponAscensionMaterial, ]; + public static FrozenSet ResinMaterialTypeDescriptions { get; } = + [ + SH.ModelMetadataMaterialCharacterTalentMaterial, + SH.ModelMetadataMaterialCharacterLevelUpMaterial, + SH.ModelMetadataMaterialWeaponAscensionMaterial, + ]; + private static FrozenSet NamesFromEnum(Func selector) where TEnum : struct, Enum { diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/DisplayItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/DisplayItem.cs index e869e1ee35..5f4c0471e1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/DisplayItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/DisplayItem.cs @@ -17,6 +17,8 @@ internal class DisplayItem public required string Icon { get; init; } public required string Name { get; init; } + + public required uint Rank { get; init; } public string? Description { get; init; } diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs index f03b55bdb3..b391d8f9eb 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs @@ -17,6 +17,7 @@ internal sealed class Material : DisplayItem RankLevel = default, ItemType = default, Icon = default!, + Rank = default, Description = "???", TypeDescription = "???", }; @@ -59,6 +60,23 @@ public bool IsInventoryItem() return IntrinsicFrozen.MaterialTypeDescriptions.Contains(TypeDescription); } + public bool IsResinItem() + { + // 摩拉 大英雄的经验 + if (Id == 202U || Id == 104003U) + { + return true; + } + + // 智识之冕 + if (TypeDescription is null || Id == 104319U) + { + return false; + } + + return IntrinsicFrozen.ResinMaterialTypeDescriptions.Contains(TypeDescription); + } + public bool IsTodaysItem(bool treatSundayAsTrue = false) { // TODO: support different time zone diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index 770b2623ed..a34516781e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -94,7 +94,7 @@ public async ValueTask> GetStatist if (resultItems.SingleOrDefault(i => i.Inner.Id == item.ItemId) is { } existedItem) { - existedItem.Count += item.Count; + existedItem.Count += (int)item.Count; } else { @@ -107,7 +107,7 @@ public async ValueTask> GetStatist { if (resultItems.SingleOrDefault(i => i.Inner.Id == inventoryItem.ItemId) is { } existedItem) { - existedItem.TotalCount += inventoryItem.Count; + existedItem.TotalCount += (int)inventoryItem.Count; } } @@ -119,78 +119,177 @@ public async ValueTask GetResinStatisticsAsync(ObservableCollec await taskContext.SwitchToBackgroundAsync(); ResinStatistics statistics = new(); - foreach (StatisticsCultivateItem statisticsCultivateItem in statisticsCultivateItems) - { - if (statisticsCultivateItem.IsFinished) - { - continue; - } + IEnumerable> groupedItems = statisticsCultivateItems + .Where(i => i.Inner.IsResinItem()) + .GroupBy(i => i.Inner.Rank); - Material material = statisticsCultivateItem.Inner; - if (material.TypeDescription is null || material.Id == 104319U) + foreach ((uint rank, IEnumerable items) in groupedItems) + { + // 摩拉 + if (rank is 10U) { - continue; - } + StatisticsCultivateItem item = items.Single(); + if (item.IsFinished) + { + continue; + } - if (material.Id == 202U) - { - double times = statisticsCultivateItem.Count - statisticsCultivateItem.TotalCount; + double times = item.Count - item.TotalCount; statistics.BlossomOfWealth.RawItemCount += times; continue; } - if (material.Id == 104003U) + if (rank is 100U) { - double times = (statisticsCultivateItem.Count - statisticsCultivateItem.TotalCount) * 20000D; + StatisticsCultivateItem item = items.Single(); + if (item.IsFinished) + { + continue; + } + + double times = (item.Count - item.TotalCount) * 20000D; statistics.BlossomOfRevelation.RawItemCount += times; continue; } - if (material.TypeDescription.Equals(SH.ModelMetadataMaterialCharacterTalentMaterial, StringComparison.CurrentCulture)) + if (rank is 11101U) { - int pieces = material.RankLevel switch + foreach (StatisticsCultivateItem item in items) { - QualityType.QUALITY_GREEN => 1, - QualityType.QUALITY_BLUE => 3, - QualityType.QUALITY_PURPLE => 9, - _ => throw HutaoException.NotSupported(), - }; + double times = item.Count - item.TotalCount; + switch (item.Inner.RankLevel) + { + case QualityType.QUALITY_PURPLE: + statistics.NormalBoss.RawItemCount += times; + continue; + case QualityType.QUALITY_ORANGE: + statistics.WeeklyBoss.RawItemCount += times; + continue; + default: + throw HutaoException.NotSupported(); + } + } - double times = (statisticsCultivateItem.Count - statisticsCultivateItem.TotalCount) * pieces; - statistics.TalentBooks.RawItemCount += times; continue; } - if (material.TypeDescription.Equals(SH.ModelMetadataMaterialCharacterLevelUpMaterial, StringComparison.CurrentCulture)) + // 天赋书,武器突破材料。一次循环最多为4个 + double greenItems = 0D; + double blueItems = 0D; + double purpleItems = 0D; + double orangeItems = 0D; + + ResinStatisticsItem targetStatisticsItem = ((rank / 1000) % 10) switch { - double times = statisticsCultivateItem.Count - statisticsCultivateItem.TotalCount; - switch (material.RankLevel) + 3 => statistics.TalentBooks, + 5 => statistics.WeaponAscension, + _ => throw HutaoException.NotSupported(), + }; + + foreach (StatisticsCultivateItem item in items) + { + switch (item.Inner.RankLevel) { + case QualityType.QUALITY_GREEN: + greenItems += item.Count - item.TotalCount; + continue; + case QualityType.QUALITY_BLUE: + blueItems += item.Count - item.TotalCount; + continue; case QualityType.QUALITY_PURPLE: - statistics.NormalBoss.RawItemCount += times; + purpleItems += item.Count - item.TotalCount; continue; case QualityType.QUALITY_ORANGE: - statistics.WeeklyBoss.RawItemCount += times; + orangeItems += item.Count - item.TotalCount; continue; default: throw HutaoException.NotSupported(); } } - if (material.TypeDescription.Equals(SH.ModelMetadataMaterialWeaponAscensionMaterial, StringComparison.CurrentCulture)) + blueItems *= 3D; + purpleItems *= 9D; + orangeItems *= 27D; + + // TODO: Refactor this + if (orangeItems > 0) { - int pieces = material.RankLevel switch + if (purpleItems > 0) { - QualityType.QUALITY_GREEN => 1, - QualityType.QUALITY_BLUE => 3, - QualityType.QUALITY_PURPLE => 9, - QualityType.QUALITY_ORANGE => 27, - _ => throw HutaoException.NotSupported(), - }; - - double times = (statisticsCultivateItem.Count - statisticsCultivateItem.TotalCount) * pieces; - statistics.WeaponAscension.RawItemCount += times; - continue; + if (blueItems > 0) + { + targetStatisticsItem.RawItemCount += orangeItems + purpleItems + blueItems + greenItems; + } + else + { + if (greenItems > 0) + { + double orangeAndPurpleNeed = orangeItems + purpleItems; + double blue = -blueItems > orangeAndPurpleNeed ? orangeAndPurpleNeed : -blueItems; + targetStatisticsItem.RawItemCount += orangeAndPurpleNeed + greenItems - blue; + } + else + { + targetStatisticsItem.RawItemCount += orangeItems + purpleItems + blueItems + greenItems; + } + } + } + else + { + if (blueItems > 0) + { + double purple = -purpleItems > orangeItems ? orangeItems : -purpleItems; + targetStatisticsItem.RawItemCount += orangeItems - purple + blueItems + greenItems; + } + else + { + if (greenItems > 0) + { + double purpleAndBlue = -(purpleItems + blueItems) > orangeItems ? orangeItems : -(purpleItems + blueItems); + targetStatisticsItem.RawItemCount += orangeItems - purpleAndBlue + greenItems; + } + else + { + targetStatisticsItem.RawItemCount += orangeItems + purpleItems + blueItems + greenItems; + } + } + } + } + else + { + if (purpleItems > 0) + { + if (blueItems > 0) + { + targetStatisticsItem.RawItemCount += purpleItems + blueItems + greenItems; + } + else + { + if (greenItems > 0) + { + double blue = -blueItems > purpleItems ? purpleItems : -blueItems; + targetStatisticsItem.RawItemCount += purpleItems - blue + greenItems; + } + else + { + targetStatisticsItem.RawItemCount += purpleItems + blueItems + greenItems; + } + } + } + else + { + if (blueItems > 0) + { + targetStatisticsItem.RawItemCount += blueItems + greenItems; + } + else + { + if (greenItems > 0) + { + targetStatisticsItem.RawItemCount += greenItems; + } + } + } } } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/ResinStatisticsItem.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/ResinStatisticsItem.cs index 50ec886790..da69aa47d8 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/ResinStatisticsItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/ResinStatisticsItem.cs @@ -42,7 +42,7 @@ public WorldDropProability SelectedWorldDropProability public bool HasData { - get => RawItemCount is not 0D; + get => RawItemCount > 0D; } public int TotalResin diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/StatisticsCultivateItem.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/StatisticsCultivateItem.cs index 9225691923..804d8f4f00 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/StatisticsCultivateItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Cultivation/StatisticsCultivateItem.cs @@ -10,14 +10,14 @@ internal sealed class StatisticsCultivateItem public StatisticsCultivateItem(Material inner, Model.Entity.CultivateItem entity) { Inner = inner; - Count = entity.Count; + Count = (int)entity.Count; } public Material Inner { get; } - public uint Count { get; set; } + public int Count { get; set; } - public uint TotalCount { get; set; } + public int TotalCount { get; set; } public bool IsFinished { get => TotalCount >= Count; }