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 00000000..d883405d
Binary files /dev/null and b/src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_MarkCustom_TagMonster.png differ
diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
index 78696444..238858f7 100644
--- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
+++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.Designer.cs
@@ -924,6 +924,78 @@ namespace Snap.Hutao.Resource.Localization {
}
}
+ ///
+ /// 查找类似 雷元素抗性 的本地化字符串。
+ ///
+ 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";