From e50c1b918431074d8cd6300728927dd2b9798833 Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Sat, 25 Feb 2023 19:12:38 +0800 Subject: [PATCH] monster wiki fullfilled --- src/Snap.Hutao/Snap.Hutao/App.xaml | 1 + .../Snap.Hutao/Core/Caching/ImageCache.cs | 2 +- .../Binding/Cultivation/CultivateItem.cs | 2 +- .../Cultivation/StatisticsCultivateItem.cs | 2 +- .../Model/Binding/Hutao/CookBonusView.cs | 2 +- .../Model/Binding/Inventory/InventoryItem.cs | 2 +- .../Model/Intrinsic/FightProperty.cs | 16 ++ .../Metadata/Avatar/Avatar.Implementation.cs | 4 +- .../Snap.Hutao/Model/Metadata/BaseValue.cs | 18 ++ .../Metadata/Converter/ItemIconConverter.cs | 9 +- .../Converter/MonsterIconConverter.cs | 28 +++ .../Snap.Hutao/Model/Metadata/Item/Display.cs | 50 +++++ .../Model/Metadata/{ => Item}/Material.cs | 39 +--- .../Model/Metadata/Monster/Monster.cs | 8 +- .../Metadata/Monster/MonsterBaseValue.cs | 21 ++ .../Snap.Hutao/Model/Primitive/MonsterId.cs | 6 + .../Icon/UI_MarkCustom_TagMonster.png | Bin 0 -> 3328 bytes .../Resource/Localization/SH.Designer.cs | 90 ++++++++ .../Snap.Hutao/Resource/Localization/SH.resx | 30 +++ .../Service/Cultivation/CultivationService.cs | 9 +- .../Cultivation/ICultivationService.cs | 2 +- .../Service/Metadata/IMetadataService.cs | 10 +- .../MetadataService.Implementation.cs | 1 + .../Metadata/MetadataService.Indexing.cs | 18 ++ src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj | 8 + .../View/Control/BaseValueSlider.xaml | 4 +- .../View/Control/BaseValueSlider.xaml.cs | 10 + src/Snap.Hutao/Snap.Hutao/View/MainView.xaml | 4 + .../Snap.Hutao/View/Page/WikiAvatarPage.xaml | 1 - .../Snap.Hutao/View/Page/WikiMonsterPage.xaml | 205 ++++++++++++++++++ .../View/Page/WikiMonsterPage.xaml.cs | 22 ++ .../Snap.Hutao/View/Page/WikiWeaponPage.xaml | 47 ++-- .../ViewModel/CultivationViewModel.cs | 3 +- .../Snap.Hutao/ViewModel/SettingViewModel.cs | 13 +- .../ViewModel/WikiAvatarViewModel.cs | 3 +- .../ViewModel/WikiMonsterViewModel.cs | 132 +++++++++++ .../Snap.Hutao/Web/HutaoEndpoints.cs | 5 - 37 files changed, 739 insertions(+), 88 deletions(-) create mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/MonsterIconConverter.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Display.cs rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/{ => Item}/Material.cs (84%) create mode 100644 src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_MarkCustom_TagMonster.png create mode 100644 src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml create mode 100644 src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/ViewModel/WikiMonsterViewModel.cs diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml b/src/Snap.Hutao/Snap.Hutao/App.xaml index efe6ecc9..8f6478f6 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml @@ -79,6 +79,7 @@ + diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs b/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs index 6018042a..23a8a390 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs @@ -192,7 +192,7 @@ internal sealed class ImageCache : IImageCache, IImageCacheFilePathOperation else if (message.StatusCode == HttpStatusCode.NotFound) { // directly goto https://static.hut.ao - retryCount = 3; + retryCount += 3; } else if (message.StatusCode == HttpStatusCode.TooManyRequests) { diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs index e914fa4f..37078db8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/CultivateItem.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. using CommunityToolkit.Mvvm.ComponentModel; -using Snap.Hutao.Model.Metadata; +using Snap.Hutao.Model.Metadata.Item; namespace Snap.Hutao.Model.Binding.Cultivation; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/StatisticsCultivateItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/StatisticsCultivateItem.cs index 454d96f9..cbfb324c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/StatisticsCultivateItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Cultivation/StatisticsCultivateItem.cs @@ -1,7 +1,7 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. -using Snap.Hutao.Model.Metadata; +using Snap.Hutao.Model.Metadata.Item; namespace Snap.Hutao.Model.Binding.Cultivation; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/CookBonusView.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/CookBonusView.cs index 38964623..1de3aa6b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/CookBonusView.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/CookBonusView.cs @@ -1,8 +1,8 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. -using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Avatar; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Primitive; namespace Snap.Hutao.Model.Binding.Hutao; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Inventory/InventoryItem.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Inventory/InventoryItem.cs index 2056358d..2a570dfc 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Inventory/InventoryItem.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Inventory/InventoryItem.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. using CommunityToolkit.Mvvm.ComponentModel; -using Snap.Hutao.Model.Metadata; +using Snap.Hutao.Model.Metadata.Item; namespace Snap.Hutao.Model.Binding.Inventory; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/FightProperty.cs b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/FightProperty.cs index 9bec87c6..ca97396d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/FightProperty.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Intrinsic/FightProperty.cs @@ -157,6 +157,8 @@ internal enum FightProperty /// /// 物理抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESPhysical")] + [Format(FormatMethod.Percent)] FIGHT_PROP_PHYSICAL_SUB_HURT = 29, /// @@ -233,36 +235,50 @@ internal enum FightProperty /// /// 火元素抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESFire")] + [Format(FormatMethod.Percent)] FIGHT_PROP_FIRE_SUB_HURT = 50, /// /// 雷元素抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESElec")] + [Format(FormatMethod.Percent)] FIGHT_PROP_ELEC_SUB_HURT = 51, /// /// 雷元素抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESWater")] + [Format(FormatMethod.Percent)] FIGHT_PROP_WATER_SUB_HURT = 52, /// /// 草元素抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESGrass")] + [Format(FormatMethod.Percent)] FIGHT_PROP_GRASS_SUB_HURT = 53, /// /// 风元素抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESWind")] + [Format(FormatMethod.Percent)] FIGHT_PROP_WIND_SUB_HURT = 54, /// /// 岩元素抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESRock")] + [Format(FormatMethod.Percent)] FIGHT_PROP_ROCK_SUB_HURT = 55, /// /// 冰元素抗性提升 /// + [LocalizationKey("ServiceAvatarInfoPropertyRESIce")] + [Format(FormatMethod.Percent)] FIGHT_PROP_ICE_SUB_HURT = 56, /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs index 1de06732..901f63bf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/Avatar.Implementation.cs @@ -1,12 +1,12 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. -using Snap.Hutao.Model.Binding; using Snap.Hutao.Model.Binding.Gacha; using Snap.Hutao.Model.Binding.Hutao; using Snap.Hutao.Model.Calculable; using Snap.Hutao.Model.Metadata.Abstraction; using Snap.Hutao.Model.Metadata.Converter; +using Snap.Hutao.Model.Metadata.Item; namespace Snap.Hutao.Model.Metadata.Avatar; @@ -47,7 +47,7 @@ internal partial class Avatar : IStatisticsItemSource, ISummaryItemSource, IName /// 转换为基础物品 /// /// 基础物品 - public Item ToItemBase() + public Binding.Item ToItemBase() { return new() { diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs index c828de94..4b5d2cd4 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/BaseValue.cs @@ -1,6 +1,8 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Model.Intrinsic; + namespace Snap.Hutao.Model.Metadata; /// @@ -22,4 +24,20 @@ internal class BaseValue /// 基础防御力 /// public float DefenseBase { get; set; } + + /// + /// 获取值 + /// + /// 战斗属性 + /// + public float GetValue(FightProperty fightProperty) + { + return fightProperty switch + { + FightProperty.FIGHT_PROP_BASE_HP => HpBase, + FightProperty.FIGHT_PROP_BASE_ATTACK => AttackBase, + FightProperty.FIGHT_PROP_BASE_DEFENSE => DefenseBase, + _ => 0, + }; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ItemIconConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ItemIconConverter.cs index ea6e9ae0..ce8728ef 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ItemIconConverter.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ItemIconConverter.cs @@ -18,7 +18,14 @@ internal sealed class ItemIconConverter : ValueConverter /// 链接 public static Uri IconNameToUri(string name) { - return Web.HutaoEndpoints.StaticFile("ItemIcon", $"{name}.png").ToUri(); + if (name.StartsWith("UI_RelicIcon_")) + { + return RelicIconConverter.IconNameToUri(name); + } + else + { + return Web.HutaoEndpoints.StaticFile("ItemIcon", $"{name}.png").ToUri(); + } } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/MonsterIconConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/MonsterIconConverter.cs new file mode 100644 index 00000000..8dd2e040 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/MonsterIconConverter.cs @@ -0,0 +1,28 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Control; + +namespace Snap.Hutao.Model.Metadata.Converter; + +/// +/// 怪物图标转换器 +/// +internal sealed class MonsterIconConverter : ValueConverter +{ + /// + /// 名称转Uri + /// + /// 名称 + /// 链接 + public static Uri IconNameToUri(string name) + { + return Web.HutaoEndpoints.StaticFile("MonsterIcon", $"{name}.png").ToUri(); + } + + /// + public override Uri Convert(string from) + { + return IconNameToUri(from); + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Display.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Display.cs new file mode 100644 index 00000000..ff1dd92a --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Display.cs @@ -0,0 +1,50 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Model.Intrinsic; +using Snap.Hutao.Model.Primitive; +using System.Collections.Immutable; + +namespace Snap.Hutao.Model.Metadata.Item; + +/// +/// 展示物品 +/// +[HighQuality] +internal class Display +{ + /// + /// 物品Id + /// + public MaterialId Id { get; set; } + + /// + /// 等级 + /// + public ItemQuality RankLevel { get; set; } + + /// + /// 物品类型 + /// + public ItemType ItemType { get; set; } + + /// + /// 图标 + /// + public string Icon { get; set; } = default!; + + /// + /// 名称 + /// + public string Name { get; set; } = default!; + + /// + /// 描述 + /// + public string Description { get; set; } = default!; + + /// + /// 类型描述 + /// + public string TypeDescription { get; set; } = default!; +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Material.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs similarity index 84% rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Material.cs rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs index 6729ad94..4ff79bb2 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Material.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Item/Material.cs @@ -5,12 +5,12 @@ using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Primitive; using System.Collections.Immutable; -namespace Snap.Hutao.Model.Metadata; +namespace Snap.Hutao.Model.Metadata.Item; /// /// 材料 /// -internal sealed class Material +internal sealed class Material : Display { private static readonly ImmutableHashSet MondayThursdayItems = new HashSet { @@ -48,46 +48,11 @@ internal sealed class Material 114045, 114046, 114047, 114048, // 谧林涓露 }.ToImmutableHashSet(); - /// - /// 物品Id - /// - public MaterialId Id { get; set; } - - /// - /// 等级 - /// - public ItemQuality RankLevel { get; set; } - - /// - /// 物品类型 - /// - public ItemType ItemType { get; set; } - /// /// 材料类型 /// public MaterialType MaterialType { get; set; } - /// - /// 图标 - /// - public string Icon { get; set; } = default!; - - /// - /// 名称 - /// - public string Name { get; set; } = default!; - - /// - /// 描述 - /// - public string Description { get; set; } = default!; - - /// - /// 类型描述 - /// - public string TypeDescription { get; set; } = default!; - /// /// 效果描述 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs index 65849b3f..798162ef 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/Monster.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. using Snap.Hutao.Model.Intrinsic; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Primitive; namespace Snap.Hutao.Model.Metadata.Monster; @@ -49,7 +50,7 @@ internal sealed class Monster /// /// 掉落物 Id /// - public IEnumerable? Drops { get; set; } = default!; + public List? Drops { get; set; } = default!; /// /// 基本属性 @@ -61,4 +62,9 @@ internal sealed class Monster /// [JsonConverter(typeof(Core.Json.Converter.StringEnumKeyDictionaryConverter))] public Dictionary GrowCurves { get; set; } = default!; + + /// + /// 养成物品视图 + /// + public List? DropsView { get; set; } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/MonsterBaseValue.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/MonsterBaseValue.cs index 3eebf98b..d05735a6 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/MonsterBaseValue.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Monster/MonsterBaseValue.cs @@ -47,4 +47,25 @@ internal sealed class MonsterBaseValue : BaseValue /// 物抗 /// public float PhysicalSubHurt { get; set; } + + /// + /// 抗性 + /// + public List> SubHurts + { + get + { + return new() + { + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_FIRE_SUB_HURT, FireSubHurt), + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_WATER_SUB_HURT, WaterSubHurt), + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_GRASS_SUB_HURT, GrassSubHurt), + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_ELEC_SUB_HURT, ElecSubHurt), + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_WIND_SUB_HURT, WindSubHurt), + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_ICE_SUB_HURT, IceSubHurt), + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_ROCK_SUB_HURT, RockSubHurt), + Converter.PropertyDescriptor.FormatNameValue(Intrinsic.FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, PhysicalSubHurt), + }; + } + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Primitive/MonsterId.cs b/src/Snap.Hutao/Snap.Hutao/Model/Primitive/MonsterId.cs index 27fe1524..2300f8fb 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Primitive/MonsterId.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Primitive/MonsterId.cs @@ -63,4 +63,10 @@ internal readonly struct MonsterId : IEquatable { return Value.GetHashCode(); } + + /// + public override string ToString() + { + return Value.ToString(); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_MarkCustom_TagMonster.png b/src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_MarkCustom_TagMonster.png new file mode 100644 index 0000000000000000000000000000000000000000..d883405d55a75b8aa8f08f4f96e35d28cad06a72 GIT binary patch literal 3328 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 + /// 查找类似 雷元素抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESElec { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESElec", resourceCulture); + } + } + + /// + /// 查找类似 火元素抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESFire { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESFire", resourceCulture); + } + } + + /// + /// 查找类似 草元素抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESGrass { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESGrass", resourceCulture); + } + } + + /// + /// 查找类似 冰元素抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESIce { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESIce", resourceCulture); + } + } + + /// + /// 查找类似 物理抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESPhysical { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESPhysical", resourceCulture); + } + } + + /// + /// 查找类似 岩元素抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESRock { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESRock", resourceCulture); + } + } + + /// + /// 查找类似 水元素抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESWater { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESWater", resourceCulture); + } + } + + /// + /// 查找类似 风元素抗性 的本地化字符串。 + /// + internal static string ServiceAvatarInfoPropertyRESWind { + get { + return ResourceManager.GetString("ServiceAvatarInfoPropertyRESWind", resourceCulture); + } + } + /// /// 查找类似 保存养成计划状态失败 的本地化字符串。 /// @@ -4218,6 +4290,15 @@ namespace Snap.Hutao.Resource.Localization { } } + /// + /// 查找类似 掉落物品 的本地化字符串。 + /// + internal static string ViewPageWikiMonsterDropItems { + get { + return ResourceManager.GetString("ViewPageWikiMonsterDropItems", resourceCulture); + } + } + /// /// 查找类似 战斗数据 的本地化字符串。 /// @@ -4533,6 +4614,15 @@ namespace Snap.Hutao.Resource.Localization { } } + /// + /// 查找类似 怪物资料 的本地化字符串。 + /// + internal static string ViewWikiMonsterHeader { + get { + return ResourceManager.GetString("ViewWikiMonsterHeader", resourceCulture); + } + } + /// /// 查找类似 武器资料 的本地化字符串。 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx index f0aa03d6..8f22b0c1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx @@ -405,6 +405,30 @@ 生命值 + + 雷元素抗性 + + + 火元素抗性 + + + 草元素抗性 + + + 冰元素抗性 + + + 物理抗性 + + + 岩元素抗性 + + + 水元素抗性 + + + 风元素抗性 + 保存养成计划状态失败 @@ -1503,6 +1527,9 @@ Webview2 运行时 + + 掉落物品 + 战斗数据 @@ -1608,6 +1635,9 @@ 角色资料 + + 怪物资料 + 武器资料 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs index 6f383623..9f3d22fc 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/CultivationService.cs @@ -10,6 +10,7 @@ using Snap.Hutao.Model.Binding; using Snap.Hutao.Model.Entity; using Snap.Hutao.Model.Entity.Database; using Snap.Hutao.Model.Entity.Primitive; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Primitive; using Snap.Hutao.Service.Metadata; using System.Collections.ObjectModel; @@ -128,7 +129,7 @@ internal sealed class CultivationService : ICultivationService } /// - public List GetInventoryItems(CultivateProject cultivateProject, List metadata, ICommand saveCommand) + public List GetInventoryItems(CultivateProject cultivateProject, List metadata, ICommand saveCommand) { Guid projectId = cultivateProject.InnerId; using (IServiceScope scope = scopeFactory.CreateScope()) @@ -139,7 +140,7 @@ internal sealed class CultivationService : ICultivationService .ToList(); List results = new(); - foreach (Model.Metadata.Material meta in metadata.Where(m => m.IsInventoryItem()).OrderBy(m => m.Id)) + foreach (Material meta in metadata.Where(m => m.IsInventoryItem()).OrderBy(m => m.Id)) { InventoryItem entity = entities.SingleOrDefault(e => e.ItemId == meta.Id) ?? InventoryItem.Create(projectId, meta.Id); results.Add(new(entity, meta, saveCommand)); @@ -158,7 +159,7 @@ internal sealed class CultivationService : ICultivationService AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); IMetadataService metadataService = scope.ServiceProvider.GetRequiredService(); - List materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false); + List materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false); Dictionary idAvatarMap = await metadataService.GetIdToAvatarMapAsync().ConfigureAwait(false); Dictionary idWeaponMap = await metadataService.GetIdToWeaponMapAsync().ConfigureAwait(false); @@ -203,7 +204,7 @@ internal sealed class CultivationService : ICultivationService List resultItems = new(); AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService(); - List materials = await scope.ServiceProvider + List materials = await scope.ServiceProvider .GetRequiredService() .GetMaterialsAsync(default) .ConfigureAwait(false); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs index abce43e9..324c20fe 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Cultivation/ICultivationService.cs @@ -4,7 +4,7 @@ using Snap.Hutao.Model.Binding.Cultivation; using Snap.Hutao.Model.Entity; using Snap.Hutao.Model.Entity.Primitive; -using Snap.Hutao.Model.Metadata; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate; using System.Collections.ObjectModel; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs index 70e9a4a1..69f8c57b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs @@ -5,6 +5,7 @@ using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Achievement; using Snap.Hutao.Model.Metadata.Avatar; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Metadata.Monster; using Snap.Hutao.Model.Metadata.Reliquary; using Snap.Hutao.Model.Metadata.Weapon; @@ -197,5 +198,12 @@ internal interface IMetadataService : ICastableService /// /// 取消令牌 /// 武器突破列表 - ValueTask> GetWeaponPromotesAsync(CancellationToken token = default(CancellationToken)); + ValueTask> GetWeaponPromotesAsync(CancellationToken token = default); + + /// + /// 异步获取显示与材料映射 + /// + /// 取消令牌 + /// 显示与材料映射 + ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs index 4d5b66cb..4e407ba7 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Implementation.cs @@ -4,6 +4,7 @@ using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Achievement; using Snap.Hutao.Model.Metadata.Avatar; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Metadata.Monster; using Snap.Hutao.Model.Metadata.Reliquary; using Snap.Hutao.Model.Metadata.Weapon; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs index 49543eb6..8d9f6d83 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs @@ -4,6 +4,7 @@ using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Avatar; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Metadata.Reliquary; using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Primitive; @@ -27,6 +28,23 @@ internal sealed partial class MetadataService return FromCacheAsDictionaryAsync("Avatar", a => a.Id, token); } + /// + public async ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default) + { + Dictionary displays = await FromCacheAsDictionaryAsync("Display", a => a.Id, token).ConfigureAwait(false); + Dictionary materials = await FromCacheAsDictionaryAsync("Material", a => a.Id, token).ConfigureAwait(false); + + // TODO: Cache this + Dictionary results = new(displays); + + foreach ((MaterialId id, Display material) in materials) + { + results[id] = material; + } + + return results; + } + /// public ValueTask> GetIdToMaterialMapAsync(CancellationToken token = default) { diff --git a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj index e87a360d..5d69d513 100644 --- a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj +++ b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj @@ -65,6 +65,7 @@ + @@ -108,6 +109,7 @@ + @@ -150,6 +152,7 @@ + @@ -443,6 +446,11 @@ SH.Designer.cs + + + MSBuild:Compile + + MSBuild:Compile diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml b/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml index 3650ac76..57fd254c 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml @@ -24,7 +24,8 @@ VerticalAlignment="Center" VerticalContentAlignment="Center" Content="{shcm:ResourceString Name=ViewControlBaseValueSliderPromoted}" - IsChecked="{x:Bind BaseValueInfo.Promoted, Mode=TwoWay}"/> + IsChecked="{x:Bind BaseValueInfo.Promoted, Mode=TwoWay}" + Visibility="{x:Bind IsPromoteVisible, Converter={StaticResource BoolToVisibilityConverter}}"/> - diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml.cs index ac4ec11e..4f7e6567 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Control/BaseValueSlider.xaml.cs @@ -14,6 +14,7 @@ namespace Snap.Hutao.View.Control; internal sealed partial class BaseValueSlider : UserControl { private static readonly DependencyProperty BaseValueInfoProperty = Property.Depend(nameof(BaseValueInfo)); + private static readonly DependencyProperty IsPromoteVisibleProperty = Property.DependBoxed(nameof(IsPromoteVisible), BoxedValues.True); /// /// һµĻֵ @@ -31,4 +32,13 @@ internal sealed partial class BaseValueSlider : UserControl get => (BaseValueInfo)GetValue(BaseValueInfoProperty); set => SetValue(BaseValueInfoProperty, value); } + + /// + /// ťǷɼ + /// + public bool IsPromoteVisible + { + get { return (bool)GetValue(IsPromoteVisibleProperty); } + set { SetValue(IsPromoteVisibleProperty, value); } + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml index ac3f5a1e..ce2163b7 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml @@ -79,6 +79,10 @@ shvh:NavHelper.NavigateTo="shvp:WikiWeaponPage" Content="{shcm:ResourceString Name=ViewWikiWeaponHeader}" Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_BagTabIcon_Weapon.png}"/> + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml index 5ab08886..6acd71c2 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml @@ -300,7 +300,6 @@ Text="养成材料"/> diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml new file mode 100644 index 00000000..834af513 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml.cs new file mode 100644 index 00000000..7f04b2dd --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiMonsterPage.xaml.cs @@ -0,0 +1,22 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Snap.Hutao.Control; +using Snap.Hutao.ViewModel; + +namespace Snap.Hutao.View.Page; + +/// +/// 怪物资料页面 +/// +internal sealed partial class WikiMonsterPage : ScopedPage +{ + /// + /// 构造一个新的怪物资料页面 + /// + public WikiMonsterPage() + { + InitializeComponent(); + InitializeWith(); + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml index 1364b9fe..a06b11d7 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiWeaponPage.xaml @@ -195,28 +195,31 @@ HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"/> - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false); + List materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false); ObservableCollection entries = await cultivationService .GetCultivateEntriesAsync(project) diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs index 5a61d758..59f89fb6 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs @@ -46,10 +46,10 @@ internal sealed class SettingViewModel : Abstraction.ViewModel private readonly List> cultures = new() { - new("简体中文", "zh-CN"), - new("繁體中文", "zh-TW"), - new("English (United States)", "en-US"), - new("한국인", "ko-KR"), + ToNameValue(CultureInfo.CreateSpecificCulture("zh-CN")), + ToNameValue(CultureInfo.CreateSpecificCulture("zh-TW")), + ToNameValue(CultureInfo.CreateSpecificCulture("en-US")), + ToNameValue(CultureInfo.CreateSpecificCulture("ko-KR")), }; private bool isEmptyHistoryWishVisible; @@ -226,6 +226,11 @@ internal sealed class SettingViewModel : Abstraction.ViewModel /// public ICommand ResetStaticResourceCommand { get; } + private static NameValue ToNameValue(CultureInfo info) + { + return new(info.NativeName, info.Name); + } + private async Task SetGamePathAsync() { IGameLocator locator = serviceProvider.GetRequiredService>() diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs index daaff74a..c987d25a 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiAvatarViewModel.cs @@ -12,6 +12,7 @@ using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Intrinsic.Immutable; using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Avatar; +using Snap.Hutao.Model.Metadata.Item; using Snap.Hutao.Model.Primitive; using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Service.Cultivation; @@ -139,7 +140,7 @@ internal sealed class WikiAvatarViewModel : Abstraction.ViewModel { avatar.Collocation = idCollocations.GetValueOrDefault(avatar.Id); avatar.CookBonusView ??= CookBonusView.Create(avatar.FetterInfo.CookBonus2, idMaterialMap); - avatar.CultivationItemsView ??= avatar.CultivationItems.Select(i => idMaterialMap[i]).ToList(); + avatar.CultivationItemsView ??= avatar.CultivationItems.SelectList(i => idMaterialMap[i]); } } } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiMonsterViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiMonsterViewModel.cs new file mode 100644 index 00000000..d47160a7 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/WikiMonsterViewModel.cs @@ -0,0 +1,132 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using CommunityToolkit.Mvvm.Input; +using CommunityToolkit.WinUI.UI; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Primitives; +using Snap.Hutao.Model.Binding.BaseValue; +using Snap.Hutao.Model.Binding.Hutao; +using Snap.Hutao.Model.Entity.Primitive; +using Snap.Hutao.Model.Intrinsic; +using Snap.Hutao.Model.Intrinsic.Immutable; +using Snap.Hutao.Model.Metadata.Item; +using Snap.Hutao.Model.Metadata.Monster; +using Snap.Hutao.Model.Metadata.Weapon; +using Snap.Hutao.Model.Primitive; +using Snap.Hutao.Service.Abstraction; +using Snap.Hutao.Service.Cultivation; +using Snap.Hutao.Service.Hutao; +using Snap.Hutao.Service.Metadata; +using Snap.Hutao.Service.User; +using Snap.Hutao.View.Dialog; +using Snap.Hutao.Web.Response; +using System.Collections.Immutable; +using System.Runtime.InteropServices; +using CalcAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta; +using CalcClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient; +using CalcConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Consumption; + +namespace Snap.Hutao.ViewModel; + +/// +/// 怪物资料视图模型 +/// +[Injection(InjectAs.Scoped)] +internal class WikiMonsterViewModel : Abstraction.ViewModel +{ + private readonly IServiceProvider serviceProvider; + private readonly IMetadataService metadataService; + private readonly IHutaoCache hutaoCache; + + private AdvancedCollectionView? monsters; + private Monster? selected; + private string? filterText; + private BaseValueInfo? baseValueInfo; + private Dictionary>? levelMonsterCurveMap; + private Dictionary? idMaterialMap; + + /// + /// 构造一个新的怪物资料视图模型 + /// + /// 服务提供器 + public WikiMonsterViewModel(IServiceProvider serviceProvider) + { + metadataService = serviceProvider.GetRequiredService(); + hutaoCache = serviceProvider.GetRequiredService(); + this.serviceProvider = serviceProvider; + + OpenUICommand = new AsyncRelayCommand(OpenUIAsync); + } + + /// + /// 角色列表 + /// + public AdvancedCollectionView? Monsters { get => monsters; set => SetProperty(ref monsters, value); } + + /// + /// 选中的角色 + /// + public Monster? Selected + { + get => selected; set + { + if (SetProperty(ref selected, value)) + { + UpdateBaseValueInfo(value); + } + } + } + + /// + /// 基础数值信息 + /// + public BaseValueInfo? BaseValueInfo { get => baseValueInfo; set => SetProperty(ref baseValueInfo, value); } + + /// + /// 筛选文本 + /// + public string? FilterText { get => filterText; set => SetProperty(ref filterText, value); } + + /// + /// 打开界面命令 + /// + public ICommand OpenUICommand { get; } + + private async Task OpenUIAsync() + { + if (await metadataService.InitializeAsync().ConfigureAwait(false)) + { + levelMonsterCurveMap = await metadataService.GetLevelToMonsterCurveMapAsync().ConfigureAwait(false); + + List monsters = await metadataService.GetMonstersAsync().ConfigureAwait(false); + Dictionary idDisplayMap = await metadataService.GetIdToDisplayAndMaterialMapAsync().ConfigureAwait(false); + foreach (Monster monster in monsters) + { + monster.DropsView ??= monster.Drops?.SelectList(i => idDisplayMap.GetValueOrDefault(i)!); + } + + List ordered = monsters.OrderBy(m => m.Id.Value).ToList(); + await ThreadHelper.SwitchToMainThreadAsync(); + + Monsters = new AdvancedCollectionView(ordered, true); + Selected = Monsters.Cast().FirstOrDefault(); + } + } + + private void UpdateBaseValueInfo(Monster? monster) + { + if (monster == null) + { + BaseValueInfo = null; + } + else + { + List propertyCurveValues = monster.GrowCurves + .Select(curveInfo => new PropertyCurveValue(curveInfo.Key, curveInfo.Value, monster.BaseValue.GetValue(curveInfo.Key))) + .ToList(); + + BaseValueInfo = new(100, propertyCurveValues, levelMonsterCurveMap!); + } + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs b/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs index 0ecce16a..91170743 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/HutaoEndpoints.cs @@ -145,12 +145,7 @@ internal static class HutaoEndpoints } #endregion -#if DEBUG - private const string HutaoMetadataSnapGenshinApi = "http://hutao-metadata-pages.snapgenshin.cn"; -#else private const string HutaoMetadataSnapGenshinApi = "http://hutao-metadata.snapgenshin.com"; -#endif - private const string HomaSnapGenshinApi = "https://homa.snapgenshin.com"; private const string PatcherDGPStudioApi = "https://patcher.dgp-studio.cn"; private const string StaticSnapGenshinApi = "https://static.snapgenshin.com";