monster wiki fullfilled

This commit is contained in:
DismissedLight
2023-02-25 19:12:38 +08:00
parent 54535cd822
commit e50c1b9184
37 changed files with 739 additions and 88 deletions

View File

@@ -79,6 +79,7 @@
<shmmc:GachaAvatarIconConverter x:Key="GachaAvatarIconConverter"/> <shmmc:GachaAvatarIconConverter x:Key="GachaAvatarIconConverter"/>
<shmmc:GachaEquipIconConverter x:Key="GachaEquipIconConverter"/> <shmmc:GachaEquipIconConverter x:Key="GachaEquipIconConverter"/>
<shmmc:ItemIconConverter x:Key="ItemIconConverter"/> <shmmc:ItemIconConverter x:Key="ItemIconConverter"/>
<shmmc:MonsterIconConverter x:Key="MonsterIconConverter"/>
<shmmc:PropertyDescriptor x:Key="PropertyDescriptor"/> <shmmc:PropertyDescriptor x:Key="PropertyDescriptor"/>
<shmmc:QualityColorConverter x:Key="QualityColorConverter"/> <shmmc:QualityColorConverter x:Key="QualityColorConverter"/>
<shmmc:WeaponTypeIconConverter x:Key="WeaponTypeIconConverter"/> <shmmc:WeaponTypeIconConverter x:Key="WeaponTypeIconConverter"/>

View File

@@ -192,7 +192,7 @@ internal sealed class ImageCache : IImageCache, IImageCacheFilePathOperation
else if (message.StatusCode == HttpStatusCode.NotFound) else if (message.StatusCode == HttpStatusCode.NotFound)
{ {
// directly goto https://static.hut.ao // directly goto https://static.hut.ao
retryCount = 3; retryCount += 3;
} }
else if (message.StatusCode == HttpStatusCode.TooManyRequests) else if (message.StatusCode == HttpStatusCode.TooManyRequests)
{ {

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license. // Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Item;
namespace Snap.Hutao.Model.Binding.Cultivation; namespace Snap.Hutao.Model.Binding.Cultivation;

View File

@@ -1,7 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved. // Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Item;
namespace Snap.Hutao.Model.Binding.Cultivation; namespace Snap.Hutao.Model.Binding.Cultivation;

View File

@@ -1,8 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved. // Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Model.Metadata;
using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Primitive; using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.Model.Binding.Hutao; namespace Snap.Hutao.Model.Binding.Hutao;

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license. // Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Item;
namespace Snap.Hutao.Model.Binding.Inventory; namespace Snap.Hutao.Model.Binding.Inventory;

View File

@@ -157,6 +157,8 @@ internal enum FightProperty
/// <summary> /// <summary>
/// 物理抗性提升 /// 物理抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESPhysical")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_PHYSICAL_SUB_HURT = 29, FIGHT_PROP_PHYSICAL_SUB_HURT = 29,
/// <summary> /// <summary>
@@ -233,36 +235,50 @@ internal enum FightProperty
/// <summary> /// <summary>
/// 火元素抗性提升 /// 火元素抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESFire")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_FIRE_SUB_HURT = 50, FIGHT_PROP_FIRE_SUB_HURT = 50,
/// <summary> /// <summary>
/// 雷元素抗性提升 /// 雷元素抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESElec")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_ELEC_SUB_HURT = 51, FIGHT_PROP_ELEC_SUB_HURT = 51,
/// <summary> /// <summary>
/// 雷元素抗性提升 /// 雷元素抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESWater")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_WATER_SUB_HURT = 52, FIGHT_PROP_WATER_SUB_HURT = 52,
/// <summary> /// <summary>
/// 草元素抗性提升 /// 草元素抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESGrass")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_GRASS_SUB_HURT = 53, FIGHT_PROP_GRASS_SUB_HURT = 53,
/// <summary> /// <summary>
/// 风元素抗性提升 /// 风元素抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESWind")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_WIND_SUB_HURT = 54, FIGHT_PROP_WIND_SUB_HURT = 54,
/// <summary> /// <summary>
/// 岩元素抗性提升 /// 岩元素抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESRock")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_ROCK_SUB_HURT = 55, FIGHT_PROP_ROCK_SUB_HURT = 55,
/// <summary> /// <summary>
/// 冰元素抗性提升 /// 冰元素抗性提升
/// </summary> /// </summary>
[LocalizationKey("ServiceAvatarInfoPropertyRESIce")]
[Format(FormatMethod.Percent)]
FIGHT_PROP_ICE_SUB_HURT = 56, FIGHT_PROP_ICE_SUB_HURT = 56,
/// <summary> /// <summary>

View File

@@ -1,12 +1,12 @@
// Copyright (c) DGP Studio. All rights reserved. // Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Model.Binding;
using Snap.Hutao.Model.Binding.Gacha; using Snap.Hutao.Model.Binding.Gacha;
using Snap.Hutao.Model.Binding.Hutao; using Snap.Hutao.Model.Binding.Hutao;
using Snap.Hutao.Model.Calculable; using Snap.Hutao.Model.Calculable;
using Snap.Hutao.Model.Metadata.Abstraction; using Snap.Hutao.Model.Metadata.Abstraction;
using Snap.Hutao.Model.Metadata.Converter; using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Model.Metadata.Item;
namespace Snap.Hutao.Model.Metadata.Avatar; namespace Snap.Hutao.Model.Metadata.Avatar;
@@ -47,7 +47,7 @@ internal partial class Avatar : IStatisticsItemSource, ISummaryItemSource, IName
/// 转换为基础物品 /// 转换为基础物品
/// </summary> /// </summary>
/// <returns>基础物品</returns> /// <returns>基础物品</returns>
public Item ToItemBase() public Binding.Item ToItemBase()
{ {
return new() return new()
{ {

View File

@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved. // Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Model.Metadata; namespace Snap.Hutao.Model.Metadata;
/// <summary> /// <summary>
@@ -22,4 +24,20 @@ internal class BaseValue
/// 基础防御力 /// 基础防御力
/// </summary> /// </summary>
public float DefenseBase { get; set; } public float DefenseBase { get; set; }
/// <summary>
/// 获取值
/// </summary>
/// <param name="fightProperty">战斗属性</param>
/// <returns>值</returns>
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,
};
}
} }

View File

@@ -18,7 +18,14 @@ internal sealed class ItemIconConverter : ValueConverter<string, Uri>
/// <returns>链接</returns> /// <returns>链接</returns>
public static Uri IconNameToUri(string name) 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();
}
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@@ -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;
/// <summary>
/// 怪物图标转换器
/// </summary>
internal sealed class MonsterIconConverter : ValueConverter<string, Uri>
{
/// <summary>
/// 名称转Uri
/// </summary>
/// <param name="name">名称</param>
/// <returns>链接</returns>
public static Uri IconNameToUri(string name)
{
return Web.HutaoEndpoints.StaticFile("MonsterIcon", $"{name}.png").ToUri();
}
/// <inheritdoc/>
public override Uri Convert(string from)
{
return IconNameToUri(from);
}
}

View File

@@ -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;
/// <summary>
/// 展示物品
/// </summary>
[HighQuality]
internal class Display
{
/// <summary>
/// 物品Id
/// </summary>
public MaterialId Id { get; set; }
/// <summary>
/// 等级
/// </summary>
public ItemQuality RankLevel { get; set; }
/// <summary>
/// 物品类型
/// </summary>
public ItemType ItemType { get; set; }
/// <summary>
/// 图标
/// </summary>
public string Icon { get; set; } = default!;
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; } = default!;
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; } = default!;
/// <summary>
/// 类型描述
/// </summary>
public string TypeDescription { get; set; } = default!;
}

View File

@@ -5,12 +5,12 @@ using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Primitive; using Snap.Hutao.Model.Primitive;
using System.Collections.Immutable; using System.Collections.Immutable;
namespace Snap.Hutao.Model.Metadata; namespace Snap.Hutao.Model.Metadata.Item;
/// <summary> /// <summary>
/// 材料 /// 材料
/// </summary> /// </summary>
internal sealed class Material internal sealed class Material : Display
{ {
private static readonly ImmutableHashSet<MaterialId> MondayThursdayItems = new HashSet<MaterialId> private static readonly ImmutableHashSet<MaterialId> MondayThursdayItems = new HashSet<MaterialId>
{ {
@@ -48,46 +48,11 @@ internal sealed class Material
114045, 114046, 114047, 114048, // 谧林涓露 114045, 114046, 114047, 114048, // 谧林涓露
}.ToImmutableHashSet(); }.ToImmutableHashSet();
/// <summary>
/// 物品Id
/// </summary>
public MaterialId Id { get; set; }
/// <summary>
/// 等级
/// </summary>
public ItemQuality RankLevel { get; set; }
/// <summary>
/// 物品类型
/// </summary>
public ItemType ItemType { get; set; }
/// <summary> /// <summary>
/// 材料类型 /// 材料类型
/// </summary> /// </summary>
public MaterialType MaterialType { get; set; } public MaterialType MaterialType { get; set; }
/// <summary>
/// 图标
/// </summary>
public string Icon { get; set; } = default!;
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; } = default!;
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; } = default!;
/// <summary>
/// 类型描述
/// </summary>
public string TypeDescription { get; set; } = default!;
/// <summary> /// <summary>
/// 效果描述 /// 效果描述
/// </summary> /// </summary>

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license. // Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Primitive; using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.Model.Metadata.Monster; namespace Snap.Hutao.Model.Metadata.Monster;
@@ -49,7 +50,7 @@ internal sealed class Monster
/// <summary> /// <summary>
/// 掉落物 Id /// 掉落物 Id
/// </summary> /// </summary>
public IEnumerable<MaterialId>? Drops { get; set; } = default!; public List<MaterialId>? Drops { get; set; } = default!;
/// <summary> /// <summary>
/// 基本属性 /// 基本属性
@@ -61,4 +62,9 @@ internal sealed class Monster
/// </summary> /// </summary>
[JsonConverter(typeof(Core.Json.Converter.StringEnumKeyDictionaryConverter))] [JsonConverter(typeof(Core.Json.Converter.StringEnumKeyDictionaryConverter))]
public Dictionary<FightProperty, GrowCurveType> GrowCurves { get; set; } = default!; public Dictionary<FightProperty, GrowCurveType> GrowCurves { get; set; } = default!;
/// <summary>
/// 养成物品视图
/// </summary>
public List<Display>? DropsView { get; set; }
} }

View File

@@ -47,4 +47,25 @@ internal sealed class MonsterBaseValue : BaseValue
/// 物抗 /// 物抗
/// </summary> /// </summary>
public float PhysicalSubHurt { get; set; } public float PhysicalSubHurt { get; set; }
/// <summary>
/// 抗性
/// </summary>
public List<NameValue<string>> 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),
};
}
}
} }

View File

@@ -63,4 +63,10 @@ internal readonly struct MonsterId : IEquatable<MonsterId>
{ {
return Value.GetHashCode(); return Value.GetHashCode();
} }
/// <inheritdoc/>
public override string ToString()
{
return Value.ToString();
}
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -924,6 +924,78 @@ namespace Snap.Hutao.Resource.Localization {
} }
} }
/// <summary>
/// 查找类似 雷元素抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESElec {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESElec", resourceCulture);
}
}
/// <summary>
/// 查找类似 火元素抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESFire {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESFire", resourceCulture);
}
}
/// <summary>
/// 查找类似 草元素抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESGrass {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESGrass", resourceCulture);
}
}
/// <summary>
/// 查找类似 冰元素抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESIce {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESIce", resourceCulture);
}
}
/// <summary>
/// 查找类似 物理抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESPhysical {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESPhysical", resourceCulture);
}
}
/// <summary>
/// 查找类似 岩元素抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESRock {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESRock", resourceCulture);
}
}
/// <summary>
/// 查找类似 水元素抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESWater {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESWater", resourceCulture);
}
}
/// <summary>
/// 查找类似 风元素抗性 的本地化字符串。
/// </summary>
internal static string ServiceAvatarInfoPropertyRESWind {
get {
return ResourceManager.GetString("ServiceAvatarInfoPropertyRESWind", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 保存养成计划状态失败 的本地化字符串。 /// 查找类似 保存养成计划状态失败 的本地化字符串。
/// </summary> /// </summary>
@@ -4218,6 +4290,15 @@ namespace Snap.Hutao.Resource.Localization {
} }
} }
/// <summary>
/// 查找类似 掉落物品 的本地化字符串。
/// </summary>
internal static string ViewPageWikiMonsterDropItems {
get {
return ResourceManager.GetString("ViewPageWikiMonsterDropItems", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 战斗数据 的本地化字符串。 /// 查找类似 战斗数据 的本地化字符串。
/// </summary> /// </summary>
@@ -4533,6 +4614,15 @@ namespace Snap.Hutao.Resource.Localization {
} }
} }
/// <summary>
/// 查找类似 怪物资料 的本地化字符串。
/// </summary>
internal static string ViewWikiMonsterHeader {
get {
return ResourceManager.GetString("ViewWikiMonsterHeader", resourceCulture);
}
}
/// <summary> /// <summary>
/// 查找类似 武器资料 的本地化字符串。 /// 查找类似 武器资料 的本地化字符串。
/// </summary> /// </summary>

View File

@@ -405,6 +405,30 @@
<data name="ServiceAvatarInfoPropertyHp" xml:space="preserve"> <data name="ServiceAvatarInfoPropertyHp" xml:space="preserve">
<value>生命值</value> <value>生命值</value>
</data> </data>
<data name="ServiceAvatarInfoPropertyRESElec" xml:space="preserve">
<value>雷元素抗性</value>
</data>
<data name="ServiceAvatarInfoPropertyRESFire" xml:space="preserve">
<value>火元素抗性</value>
</data>
<data name="ServiceAvatarInfoPropertyRESGrass" xml:space="preserve">
<value>草元素抗性</value>
</data>
<data name="ServiceAvatarInfoPropertyRESIce" xml:space="preserve">
<value>冰元素抗性</value>
</data>
<data name="ServiceAvatarInfoPropertyRESPhysical" xml:space="preserve">
<value>物理抗性</value>
</data>
<data name="ServiceAvatarInfoPropertyRESRock" xml:space="preserve">
<value>岩元素抗性</value>
</data>
<data name="ServiceAvatarInfoPropertyRESWater" xml:space="preserve">
<value>水元素抗性</value>
</data>
<data name="ServiceAvatarInfoPropertyRESWind" xml:space="preserve">
<value>风元素抗性</value>
</data>
<data name="ServiceCultivationProjectCurrentUserdataCourrpted" xml:space="preserve"> <data name="ServiceCultivationProjectCurrentUserdataCourrpted" xml:space="preserve">
<value>保存养成计划状态失败</value> <value>保存养成计划状态失败</value>
</data> </data>
@@ -1503,6 +1527,9 @@
<data name="ViewPageSettingWebview2Header" xml:space="preserve"> <data name="ViewPageSettingWebview2Header" xml:space="preserve">
<value>Webview2 运行时</value> <value>Webview2 运行时</value>
</data> </data>
<data name="ViewPageWikiMonsterDropItems" xml:space="preserve">
<value>掉落物品</value>
</data>
<data name="ViewSpiralAbyssBattleHeader" xml:space="preserve"> <data name="ViewSpiralAbyssBattleHeader" xml:space="preserve">
<value>战斗数据</value> <value>战斗数据</value>
</data> </data>
@@ -1608,6 +1635,9 @@
<data name="ViewWikiAvatarHeader" xml:space="preserve"> <data name="ViewWikiAvatarHeader" xml:space="preserve">
<value>角色资料</value> <value>角色资料</value>
</data> </data>
<data name="ViewWikiMonsterHeader" xml:space="preserve">
<value>怪物资料</value>
</data>
<data name="ViewWikiWeaponHeader" xml:space="preserve"> <data name="ViewWikiWeaponHeader" xml:space="preserve">
<value>武器资料</value> <value>武器资料</value>
</data> </data>

View File

@@ -10,6 +10,7 @@ using Snap.Hutao.Model.Binding;
using Snap.Hutao.Model.Entity; using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database; using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Model.Entity.Primitive; using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Primitive; using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Metadata; using Snap.Hutao.Service.Metadata;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
@@ -128,7 +129,7 @@ internal sealed class CultivationService : ICultivationService
} }
/// <inheritdoc/> /// <inheritdoc/>
public List<BindingInventoryItem> GetInventoryItems(CultivateProject cultivateProject, List<Model.Metadata.Material> metadata, ICommand saveCommand) public List<BindingInventoryItem> GetInventoryItems(CultivateProject cultivateProject, List<Material> metadata, ICommand saveCommand)
{ {
Guid projectId = cultivateProject.InnerId; Guid projectId = cultivateProject.InnerId;
using (IServiceScope scope = scopeFactory.CreateScope()) using (IServiceScope scope = scopeFactory.CreateScope())
@@ -139,7 +140,7 @@ internal sealed class CultivationService : ICultivationService
.ToList(); .ToList();
List<BindingInventoryItem> results = new(); List<BindingInventoryItem> 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); InventoryItem entity = entities.SingleOrDefault(e => e.ItemId == meta.Id) ?? InventoryItem.Create(projectId, meta.Id);
results.Add(new(entity, meta, saveCommand)); results.Add(new(entity, meta, saveCommand));
@@ -158,7 +159,7 @@ internal sealed class CultivationService : ICultivationService
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>(); AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
IMetadataService metadataService = scope.ServiceProvider.GetRequiredService<IMetadataService>(); IMetadataService metadataService = scope.ServiceProvider.GetRequiredService<IMetadataService>();
List<Model.Metadata.Material> materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false); List<Material> materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false);
Dictionary<AvatarId, Model.Metadata.Avatar.Avatar> idAvatarMap = await metadataService.GetIdToAvatarMapAsync().ConfigureAwait(false); Dictionary<AvatarId, Model.Metadata.Avatar.Avatar> idAvatarMap = await metadataService.GetIdToAvatarMapAsync().ConfigureAwait(false);
Dictionary<WeaponId, Model.Metadata.Weapon.Weapon> idWeaponMap = await metadataService.GetIdToWeaponMapAsync().ConfigureAwait(false); Dictionary<WeaponId, Model.Metadata.Weapon.Weapon> idWeaponMap = await metadataService.GetIdToWeaponMapAsync().ConfigureAwait(false);
@@ -203,7 +204,7 @@ internal sealed class CultivationService : ICultivationService
List<BindingStatisticsItem> resultItems = new(); List<BindingStatisticsItem> resultItems = new();
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>(); AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
List<Model.Metadata.Material> materials = await scope.ServiceProvider List<Material> materials = await scope.ServiceProvider
.GetRequiredService<IMetadataService>() .GetRequiredService<IMetadataService>()
.GetMaterialsAsync(default) .GetMaterialsAsync(default)
.ConfigureAwait(false); .ConfigureAwait(false);

View File

@@ -4,7 +4,7 @@
using Snap.Hutao.Model.Binding.Cultivation; using Snap.Hutao.Model.Binding.Cultivation;
using Snap.Hutao.Model.Entity; using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Primitive; 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 Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;

View File

@@ -5,6 +5,7 @@ using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata;
using Snap.Hutao.Model.Metadata.Achievement; using Snap.Hutao.Model.Metadata.Achievement;
using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Monster; using Snap.Hutao.Model.Metadata.Monster;
using Snap.Hutao.Model.Metadata.Reliquary; using Snap.Hutao.Model.Metadata.Reliquary;
using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Metadata.Weapon;
@@ -197,5 +198,12 @@ internal interface IMetadataService : ICastableService
/// </summary> /// </summary>
/// <param name="token">取消令牌</param> /// <param name="token">取消令牌</param>
/// <returns>武器突破列表</returns> /// <returns>武器突破列表</returns>
ValueTask<List<Promote>> GetWeaponPromotesAsync(CancellationToken token = default(CancellationToken)); ValueTask<List<Promote>> GetWeaponPromotesAsync(CancellationToken token = default);
/// <summary>
/// 异步获取显示与材料映射
/// </summary>
/// <param name="token">取消令牌</param>
/// <returns>显示与材料映射</returns>
ValueTask<Dictionary<MaterialId, Display>> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default);
} }

View File

@@ -4,6 +4,7 @@
using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata;
using Snap.Hutao.Model.Metadata.Achievement; using Snap.Hutao.Model.Metadata.Achievement;
using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Monster; using Snap.Hutao.Model.Metadata.Monster;
using Snap.Hutao.Model.Metadata.Reliquary; using Snap.Hutao.Model.Metadata.Reliquary;
using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Metadata.Weapon;

View File

@@ -4,6 +4,7 @@
using Snap.Hutao.Model.Intrinsic; using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata;
using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Reliquary; using Snap.Hutao.Model.Metadata.Reliquary;
using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Model.Metadata.Weapon;
using Snap.Hutao.Model.Primitive; using Snap.Hutao.Model.Primitive;
@@ -27,6 +28,23 @@ internal sealed partial class MetadataService
return FromCacheAsDictionaryAsync<AvatarId, Avatar>("Avatar", a => a.Id, token); return FromCacheAsDictionaryAsync<AvatarId, Avatar>("Avatar", a => a.Id, token);
} }
/// <inheritdoc/>
public async ValueTask<Dictionary<MaterialId, Display>> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default)
{
Dictionary<MaterialId, Display> displays = await FromCacheAsDictionaryAsync<MaterialId, Display>("Display", a => a.Id, token).ConfigureAwait(false);
Dictionary<MaterialId, Material> materials = await FromCacheAsDictionaryAsync<MaterialId, Material>("Material", a => a.Id, token).ConfigureAwait(false);
// TODO: Cache this
Dictionary<MaterialId, Display> results = new(displays);
foreach ((MaterialId id, Display material) in materials)
{
results[id] = material;
}
return results;
}
/// <inheritdoc/> /// <inheritdoc/>
public ValueTask<Dictionary<MaterialId, Material>> GetIdToMaterialMapAsync(CancellationToken token = default) public ValueTask<Dictionary<MaterialId, Material>> GetIdToMaterialMapAsync(CancellationToken token = default)
{ {

View File

@@ -65,6 +65,7 @@
<None Remove="Resource\Icon\UI_ItemIcon_210.png" /> <None Remove="Resource\Icon\UI_ItemIcon_210.png" />
<None Remove="Resource\Icon\UI_ItemIcon_210_256.png" /> <None Remove="Resource\Icon\UI_ItemIcon_210_256.png" />
<None Remove="Resource\Icon\UI_ItemIcon_220021.png" /> <None Remove="Resource\Icon\UI_ItemIcon_220021.png" />
<None Remove="Resource\Icon\UI_MarkCustom_TagMonster.png" />
<None Remove="Resource\Icon\UI_MarkQuest_Events_Proce.png" /> <None Remove="Resource\Icon\UI_MarkQuest_Events_Proce.png" />
<None Remove="Resource\Icon\UI_MarkTower.png" /> <None Remove="Resource\Icon\UI_MarkTower.png" />
<None Remove="Resource\Icon\UI_MarkTower_Tower.png" /> <None Remove="Resource\Icon\UI_MarkTower_Tower.png" />
@@ -108,6 +109,7 @@
<None Remove="View\Page\SpiralAbyssRecordPage.xaml" /> <None Remove="View\Page\SpiralAbyssRecordPage.xaml" />
<None Remove="View\Page\TestPage.xaml" /> <None Remove="View\Page\TestPage.xaml" />
<None Remove="View\Page\WikiAvatarPage.xaml" /> <None Remove="View\Page\WikiAvatarPage.xaml" />
<None Remove="View\Page\WikiMonsterPage.xaml" />
<None Remove="View\Page\WikiWeaponPage.xaml" /> <None Remove="View\Page\WikiWeaponPage.xaml" />
<None Remove="View\TitleView.xaml" /> <None Remove="View\TitleView.xaml" />
<None Remove="View\UserView.xaml" /> <None Remove="View\UserView.xaml" />
@@ -150,6 +152,7 @@
<Content Include="Resource\Icon\UI_ItemIcon_210.png" /> <Content Include="Resource\Icon\UI_ItemIcon_210.png" />
<Content Include="Resource\Icon\UI_ItemIcon_210_256.png" /> <Content Include="Resource\Icon\UI_ItemIcon_210_256.png" />
<Content Include="Resource\Icon\UI_ItemIcon_220021.png" /> <Content Include="Resource\Icon\UI_ItemIcon_220021.png" />
<Content Include="Resource\Icon\UI_MarkCustom_TagMonster.png" />
<Content Include="Resource\Icon\UI_MarkQuest_Events_Proce.png" /> <Content Include="Resource\Icon\UI_MarkQuest_Events_Proce.png" />
<Content Include="Resource\Icon\UI_MarkTower.png" /> <Content Include="Resource\Icon\UI_MarkTower.png" />
<Content Include="Resource\Icon\UI_MarkTower_Tower.png" /> <Content Include="Resource\Icon\UI_MarkTower_Tower.png" />
@@ -443,6 +446,11 @@
<LastGenOutput>SH.Designer.cs</LastGenOutput> <LastGenOutput>SH.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Page Update="View\Page\WikiMonsterPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Page Update="View\Control\BaseValueSlider.xaml"> <Page Update="View\Control\BaseValueSlider.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -24,7 +24,8 @@
VerticalAlignment="Center" VerticalAlignment="Center"
VerticalContentAlignment="Center" VerticalContentAlignment="Center"
Content="{shcm:ResourceString Name=ViewControlBaseValueSliderPromoted}" 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}}"/>
<Slider <Slider
MinWidth="240" MinWidth="240"
Margin="16,0,8,0" Margin="16,0,8,0"
@@ -33,7 +34,6 @@
Minimum="1" Minimum="1"
StepFrequency="1" StepFrequency="1"
Value="{x:Bind BaseValueInfo.CurrentLevel, Mode=TwoWay}"/> Value="{x:Bind BaseValueInfo.CurrentLevel, Mode=TwoWay}"/>
</StackPanel> </StackPanel>
</wsc:Setting.ActionContent> </wsc:Setting.ActionContent>
</wsc:Setting> </wsc:Setting>

View File

@@ -14,6 +14,7 @@ namespace Snap.Hutao.View.Control;
internal sealed partial class BaseValueSlider : UserControl internal sealed partial class BaseValueSlider : UserControl
{ {
private static readonly DependencyProperty BaseValueInfoProperty = Property<BaseValueSlider>.Depend<BaseValueInfo>(nameof(BaseValueInfo)); private static readonly DependencyProperty BaseValueInfoProperty = Property<BaseValueSlider>.Depend<BaseValueInfo>(nameof(BaseValueInfo));
private static readonly DependencyProperty IsPromoteVisibleProperty = Property<BaseValueSlider>.DependBoxed<bool>(nameof(IsPromoteVisible), BoxedValues.True);
/// <summary> /// <summary>
/// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µĻ<C2B5><C4BB><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> /// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>µĻ<C2B5><C4BB><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -31,4 +32,13 @@ internal sealed partial class BaseValueSlider : UserControl
get => (BaseValueInfo)GetValue(BaseValueInfoProperty); get => (BaseValueInfo)GetValue(BaseValueInfoProperty);
set => SetValue(BaseValueInfoProperty, value); set => SetValue(BaseValueInfoProperty, value);
} }
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ť<EFBFBD>Ƿ<EFBFBD><C7B7>ɼ<EFBFBD>
/// </summary>
public bool IsPromoteVisible
{
get { return (bool)GetValue(IsPromoteVisibleProperty); }
set { SetValue(IsPromoteVisibleProperty, value); }
}
} }

View File

@@ -79,6 +79,10 @@
shvh:NavHelper.NavigateTo="shvp:WikiWeaponPage" shvh:NavHelper.NavigateTo="shvp:WikiWeaponPage"
Content="{shcm:ResourceString Name=ViewWikiWeaponHeader}" Content="{shcm:ResourceString Name=ViewWikiWeaponHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_BagTabIcon_Weapon.png}"/> Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_BagTabIcon_Weapon.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:WikiMonsterPage"
Content="{shcm:ResourceString Name=ViewWikiMonsterHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_MarkCustom_TagMonster.png}"/>
</NavigationView.MenuItems> </NavigationView.MenuItems>
<NavigationView.PaneFooter> <NavigationView.PaneFooter>

View File

@@ -300,7 +300,6 @@
Text="养成材料"/> Text="养成材料"/>
<GridView <GridView
Margin="16,16,0,0" Margin="16,16,0,0"
ItemsPanel="{StaticResource HorizontalStackPanelTemplate}"
ItemsSource="{Binding Selected.CultivationItemsView}" ItemsSource="{Binding Selected.CultivationItemsView}"
SelectionMode="None"> SelectionMode="None">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>

View File

@@ -0,0 +1,205 @@
<shc:ScopedPage
x:Class="Snap.Hutao.View.Page.WikiMonsterPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
xmlns:shc="using:Snap.Hutao.Control"
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shcp="using:Snap.Hutao.Control.Panel"
xmlns:shv="using:Snap.Hutao.ViewModel"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:wsc="using:WinUICommunity.SettingsUI.Controls"
d:DataContext="{d:DesignInstance Type=shv:WikiMonsterViewModel}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<mxi:Interaction.Behaviors>
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
</mxi:Interaction.Behaviors>
<Grid>
<Grid Visibility="{Binding Monsters, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<CommandBar
Grid.Row="0"
Background="{StaticResource CardBackgroundFillColorDefaultBrush}"
BorderBrush="{x:Null}"
BorderThickness="0"
DefaultLabelPosition="Right">
<CommandBar.Content>
<shcp:PanelSelector x:Name="ItemsPanelSelector" Margin="6,8,0,0"/>
</CommandBar.Content>
<AppBarElementContainer Visibility="Collapsed">
<AutoSuggestBox
Width="240"
Height="36"
Margin="16,6,6,0"
HorizontalAlignment="Stretch"
VerticalContentAlignment="Center"
PlaceholderText="筛选怪物"
QueryIcon="{shcm:FontIcon Glyph=&#xE721;}"
Text="{Binding FilterText, Mode=TwoWay}">
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="QuerySubmitted">
<mxic:InvokeCommandAction Command="{Binding FilterCommand}" CommandParameter="{Binding FilterText}"/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
</AutoSuggestBox>
</AppBarElementContainer>
</CommandBar>
<SplitView
Grid.Row="1"
DisplayMode="Inline"
IsPaneOpen="True"
OpenPaneLength="{StaticResource CompatSplitViewOpenPaneLength2}"
PaneBackground="{StaticResource CardBackgroundFillColorSecondary}">
<SplitView.Pane>
<cwuc:SwitchPresenter Grid.Row="1" Value="{Binding ElementName=ItemsPanelSelector, Path=Current}">
<cwuc:Case Value="List">
<ListView
Grid.Row="1"
ItemsSource="{Binding Monsters}"
SelectedItem="{Binding Selected, Mode=TwoWay}"
SelectionMode="Single">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="{Binding Key}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="0"
Width="48"
Height="48"
Margin="0,6,12,6"
Source="{Binding Icon, Converter={StaticResource MonsterIconConverter}, Mode=OneWay}"/>
<TextBlock
Grid.Column="1"
Margin="12,0,0,0"
VerticalAlignment="Center"
Text="{Binding Title}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</cwuc:Case>
<cwuc:Case Value="Grid">
<GridView
Margin="6,6,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
ItemsSource="{Binding Monsters}"
SelectedItem="{Binding Selected, Mode=TwoWay}"
SelectionMode="Single">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate>
<shvc:ItemIcon
Width="46"
Height="46"
Icon="{Binding Icon, Converter={StaticResource MonsterIconConverter}, Mode=OneWay}"
Quality="QUALITY_NONE"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</cwuc:Case>
</cwuc:SwitchPresenter>
</SplitView.Pane>
<SplitView.Content>
<ScrollViewer>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="800"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<StackPanel Margin="0,0,20,0">
<TextBlock
Margin="16,16,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding Selected.Title}"/>
<ItemsControl Margin="16,8,0,0" ItemsSource="{Binding Selected.Affixes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwuc:WrapPanel HorizontalSpacing="8" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<shvc:BaseValueSlider
Margin="16,16,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"
IsPromoteVisible="False"/>
<ItemsControl Margin="16,16,0,0" ItemsSource="{Binding Selected.BaseValue.SubHurts}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<cwuc:UniformGrid
ColumnSpacing="2"
Columns="2"
RowSpacing="2"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<wsc:Setting Header="{Binding Name}">
<TextBlock Text="{Binding Value}"/>
</wsc:Setting>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock
Margin="16,32,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageWikiMonsterDropItems}"
Visibility="{Binding Selected.DropsView, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
<GridView
Margin="16,16,-4,12"
Padding="0"
ItemsSource="{Binding Selected.DropsView}"
SelectionMode="None"
Visibility="{Binding Selected.DropsView, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<shvc:BottomTextControl Text="{Binding Name}">
<shvc:ItemIcon Icon="{Binding Icon, Converter={StaticResource ItemIconConverter}}" Quality="{Binding RankLevel}"/>
</shvc:BottomTextControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</GridView>
</StackPanel>
</Grid>
</ScrollViewer>
</SplitView.Content>
</SplitView>
</Grid>
<shvc:LoadingView IsLoading="{Binding Monsters, Converter={StaticResource EmptyObjectToBoolRevertConverter}}"/>
</Grid>
</shc:ScopedPage>

View File

@@ -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;
/// <summary>
/// 怪物资料页面
/// </summary>
internal sealed partial class WikiMonsterPage : ScopedPage
{
/// <summary>
/// 构造一个新的怪物资料页面
/// </summary>
public WikiMonsterPage()
{
InitializeComponent();
InitializeWith<WikiMonsterViewModel>();
}
}

View File

@@ -195,28 +195,31 @@
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"/> BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"/>
<TextBlock <StackPanel Visibility="{Binding Selected.Affix, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
Margin="16,32,0,0" <TextBlock
Style="{StaticResource BaseTextBlockStyle}" Margin="16,32,0,0"
Text="{Binding Selected.Affix.Name}"/> Style="{StaticResource BaseTextBlockStyle}"
<Pivot ItemsSource="{Binding Selected.Affix.Descriptions}"> Text="{Binding Selected.Affix.Name}"/>
<Pivot.HeaderTemplate> <Pivot ItemsSource="{Binding Selected.Affix.Descriptions}">
<DataTemplate> <Pivot.HeaderTemplate>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{Binding LevelFormatted}"/> <DataTemplate>
</DataTemplate> <TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{Binding LevelFormatted}"/>
</Pivot.HeaderTemplate> </DataTemplate>
<Pivot.ItemTemplate> </Pivot.HeaderTemplate>
<DataTemplate> <Pivot.ItemTemplate>
<shct:DescriptionTextBlock Margin="16,16,0,0" Description="{Binding Description}"> <DataTemplate>
<shct:DescriptionTextBlock.Resources> <shct:DescriptionTextBlock Margin="16,16,0,0" Description="{Binding Description}">
<Style BasedOn="{StaticResource BodyTextBlockStyle}" TargetType="TextBlock"> <shct:DescriptionTextBlock.Resources>
<Setter Property="TextWrapping" Value="Wrap"/> <Style BasedOn="{StaticResource BodyTextBlockStyle}" TargetType="TextBlock">
</Style> <Setter Property="TextWrapping" Value="Wrap"/>
</shct:DescriptionTextBlock.Resources> </Style>
</shct:DescriptionTextBlock> </shct:DescriptionTextBlock.Resources>
</DataTemplate> </shct:DescriptionTextBlock>
</Pivot.ItemTemplate> </DataTemplate>
</Pivot> </Pivot.ItemTemplate>
</Pivot>
</StackPanel>
<TextBlock <TextBlock
Margin="16,32,0,0" Margin="16,32,0,0"
Style="{StaticResource BaseTextBlockStyle}" Style="{StaticResource BaseTextBlockStyle}"

View File

@@ -5,6 +5,7 @@ using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Model.Binding.Cultivation; using Snap.Hutao.Model.Binding.Cultivation;
using Snap.Hutao.Model.Entity; using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.Cultivation; using Snap.Hutao.Service.Cultivation;
using Snap.Hutao.Service.Metadata; using Snap.Hutao.Service.Metadata;
@@ -186,7 +187,7 @@ internal sealed class CultivationViewModel : Abstraction.ViewModel
{ {
if (project != null) if (project != null)
{ {
List<Model.Metadata.Material> materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false); List<Material> materials = await metadataService.GetMaterialsAsync().ConfigureAwait(false);
ObservableCollection<CultivateEntryView> entries = await cultivationService ObservableCollection<CultivateEntryView> entries = await cultivationService
.GetCultivateEntriesAsync(project) .GetCultivateEntriesAsync(project)

View File

@@ -46,10 +46,10 @@ internal sealed class SettingViewModel : Abstraction.ViewModel
private readonly List<NameValue<string>> cultures = new() private readonly List<NameValue<string>> cultures = new()
{ {
new("简体中文", "zh-CN"), ToNameValue(CultureInfo.CreateSpecificCulture("zh-CN")),
new("繁體中文", "zh-TW"), ToNameValue(CultureInfo.CreateSpecificCulture("zh-TW")),
new("English (United States)", "en-US"), ToNameValue(CultureInfo.CreateSpecificCulture("en-US")),
new("한국인", "ko-KR"), ToNameValue(CultureInfo.CreateSpecificCulture("ko-KR")),
}; };
private bool isEmptyHistoryWishVisible; private bool isEmptyHistoryWishVisible;
@@ -226,6 +226,11 @@ internal sealed class SettingViewModel : Abstraction.ViewModel
/// </summary> /// </summary>
public ICommand ResetStaticResourceCommand { get; } public ICommand ResetStaticResourceCommand { get; }
private static NameValue<string> ToNameValue(CultureInfo info)
{
return new(info.NativeName, info.Name);
}
private async Task SetGamePathAsync() private async Task SetGamePathAsync()
{ {
IGameLocator locator = serviceProvider.GetRequiredService<IEnumerable<IGameLocator>>() IGameLocator locator = serviceProvider.GetRequiredService<IEnumerable<IGameLocator>>()

View File

@@ -12,6 +12,7 @@ using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Intrinsic.Immutable; using Snap.Hutao.Model.Intrinsic.Immutable;
using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata;
using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Primitive; using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.Cultivation; using Snap.Hutao.Service.Cultivation;
@@ -139,7 +140,7 @@ internal sealed class WikiAvatarViewModel : Abstraction.ViewModel
{ {
avatar.Collocation = idCollocations.GetValueOrDefault(avatar.Id); avatar.Collocation = idCollocations.GetValueOrDefault(avatar.Id);
avatar.CookBonusView ??= CookBonusView.Create(avatar.FetterInfo.CookBonus2, idMaterialMap); 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]);
} }
} }
} }

View File

@@ -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;
/// <summary>
/// 怪物资料视图模型
/// </summary>
[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<int, Dictionary<GrowCurveType, float>>? levelMonsterCurveMap;
private Dictionary<MaterialId, Material>? idMaterialMap;
/// <summary>
/// 构造一个新的怪物资料视图模型
/// </summary>
/// <param name="serviceProvider">服务提供器</param>
public WikiMonsterViewModel(IServiceProvider serviceProvider)
{
metadataService = serviceProvider.GetRequiredService<IMetadataService>();
hutaoCache = serviceProvider.GetRequiredService<IHutaoCache>();
this.serviceProvider = serviceProvider;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
}
/// <summary>
/// 角色列表
/// </summary>
public AdvancedCollectionView? Monsters { get => monsters; set => SetProperty(ref monsters, value); }
/// <summary>
/// 选中的角色
/// </summary>
public Monster? Selected
{
get => selected; set
{
if (SetProperty(ref selected, value))
{
UpdateBaseValueInfo(value);
}
}
}
/// <summary>
/// 基础数值信息
/// </summary>
public BaseValueInfo? BaseValueInfo { get => baseValueInfo; set => SetProperty(ref baseValueInfo, value); }
/// <summary>
/// 筛选文本
/// </summary>
public string? FilterText { get => filterText; set => SetProperty(ref filterText, value); }
/// <summary>
/// 打开界面命令
/// </summary>
public ICommand OpenUICommand { get; }
private async Task OpenUIAsync()
{
if (await metadataService.InitializeAsync().ConfigureAwait(false))
{
levelMonsterCurveMap = await metadataService.GetLevelToMonsterCurveMapAsync().ConfigureAwait(false);
List<Monster> monsters = await metadataService.GetMonstersAsync().ConfigureAwait(false);
Dictionary<MaterialId, Display> idDisplayMap = await metadataService.GetIdToDisplayAndMaterialMapAsync().ConfigureAwait(false);
foreach (Monster monster in monsters)
{
monster.DropsView ??= monster.Drops?.SelectList(i => idDisplayMap.GetValueOrDefault(i)!);
}
List<Monster> ordered = monsters.OrderBy(m => m.Id.Value).ToList();
await ThreadHelper.SwitchToMainThreadAsync();
Monsters = new AdvancedCollectionView(ordered, true);
Selected = Monsters.Cast<Monster>().FirstOrDefault();
}
}
private void UpdateBaseValueInfo(Monster? monster)
{
if (monster == null)
{
BaseValueInfo = null;
}
else
{
List<PropertyCurveValue> propertyCurveValues = monster.GrowCurves
.Select(curveInfo => new PropertyCurveValue(curveInfo.Key, curveInfo.Value, monster.BaseValue.GetValue(curveInfo.Key)))
.ToList();
BaseValueInfo = new(100, propertyCurveValues, levelMonsterCurveMap!);
}
}
}

View File

@@ -145,12 +145,7 @@ internal static class HutaoEndpoints
} }
#endregion #endregion
#if DEBUG
private const string HutaoMetadataSnapGenshinApi = "http://hutao-metadata-pages.snapgenshin.cn";
#else
private const string HutaoMetadataSnapGenshinApi = "http://hutao-metadata.snapgenshin.com"; private const string HutaoMetadataSnapGenshinApi = "http://hutao-metadata.snapgenshin.com";
#endif
private const string HomaSnapGenshinApi = "https://homa.snapgenshin.com"; private const string HomaSnapGenshinApi = "https://homa.snapgenshin.com";
private const string PatcherDGPStudioApi = "https://patcher.dgp-studio.cn"; private const string PatcherDGPStudioApi = "https://patcher.dgp-studio.cn";
private const string StaticSnapGenshinApi = "https://static.snapgenshin.com"; private const string StaticSnapGenshinApi = "https://static.snapgenshin.com";