collocation for wiki avatar

This commit is contained in:
DismissedLight
2022-10-25 15:47:12 +08:00
parent 792a701183
commit 7a99c44b29
12 changed files with 187 additions and 17 deletions

View File

@@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao;
/// <summary>
/// 角色
/// </summary>
internal class ComplexAvatar
public class ComplexAvatar
{
/// <summary>
/// 构造一个胡桃数据库角色

View File

@@ -1,16 +1,15 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.Model.Binding.Hutao;
/// <summary>
/// 角色搭配
/// </summary>
internal class ComplexAvatarCollocation : ComplexAvatar
public class ComplexAvatarCollocation : ComplexAvatar
{
/// <summary>
/// 构造一个新的角色搭配
@@ -22,6 +21,11 @@ internal class ComplexAvatarCollocation : ComplexAvatar
{
}
/// <summary>
/// 角色Id
/// </summary>
public AvatarId AvatarId { get; set; }
/// <summary>
/// 角色
/// </summary>

View File

@@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao;
/// <summary>
/// 圣遗物套装
/// </summary>
internal class ComplexReliquarySet
public class ComplexReliquarySet
{
/// <summary>
/// 构造一个新的胡桃数据库圣遗物套装

View File

@@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao;
/// <summary>
/// 胡桃数据库武器
/// </summary>
internal class ComplexWeapon
public class ComplexWeapon
{
/// <summary>
/// 构造一个胡桃数据库武器

View File

@@ -3,6 +3,7 @@
using Snap.Hutao.Model.Binding.Gacha;
using Snap.Hutao.Model.Binding.Gacha.Abstraction;
using Snap.Hutao.Model.Binding.Hutao;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata.Abstraction;
using Snap.Hutao.Model.Metadata.Converter;
@@ -84,6 +85,11 @@ public class Avatar : IStatisticsItemSource, ISummaryItemSource, INameQuality
/// </summary>
public IEnumerable<Costume> Costumes { get; set; } = default!;
/// <summary>
/// [非元数据] 搭配数据
/// </summary>
public ComplexAvatarCollocation? Collocation { get; set; }
/// <summary>
/// 转换为基础物品
/// </summary>

View File

@@ -0,0 +1,31 @@
// 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 class GachaAvatarImgConverter : ValueConverterBase<string, Uri>
{
private const string BaseUrl = "https://static.snapgenshin.com/GachaAvatarImg/UI_Gacha_AvatarImg_{0}.png";
/// <summary>
/// 名称转Uri
/// </summary>
/// <param name="name">名称</param>
/// <returns>链接</returns>
public static Uri IconNameToUri(string name)
{
name = name["UI_AvatarIcon_".Length..];
return new Uri(string.Format(BaseUrl, name));
}
/// <inheritdoc/>
public override Uri Convert(string from)
{
return IconNameToUri(from);
}
}

View File

@@ -12,8 +12,8 @@ namespace Snap.Hutao.Service.Hutao;
/// <summary>
/// 胡桃 API 缓存
/// </summary>
[Injection(InjectAs.Singleton, typeof(IHtaoCache))]
internal class HutaoCache : IHtaoCache
[Injection(InjectAs.Singleton, typeof(IHutaoCache))]
internal class HutaoCache : IHutaoCache
{
private readonly IHutaoService hutaoService;
private readonly IMetadataService metadataService;
@@ -91,6 +91,7 @@ internal class HutaoCache : IHtaoCache
{
return new ComplexAvatarCollocation(idAvatarMap[co.AvatarId])
{
AvatarId = co.AvatarId,
Avatars = co.Avatars.Select(a => new ComplexAvatar(idAvatarMap[a.Item], a.Rate)).ToList(),
Weapons = co.Weapons.Select(w => new ComplexWeapon(idWeaponMap[w.Item], w.Rate)).ToList(),
ReliquarySets = co.Reliquaries.Select(r => new ComplexReliquarySet(r, idReliquarySetMap)).ToList(),

View File

@@ -9,7 +9,7 @@ namespace Snap.Hutao.Service.Hutao;
/// <summary>
/// 胡桃 API 缓存
/// </summary>
internal interface IHtaoCache
internal interface IHutaoCache
{
/// <summary>
/// 角色使用率

View File

@@ -25,6 +25,7 @@
<shmmc:ElementNameIconConverter x:Key="ElementNameIconConverter"/>
<shmmc:WeaponTypeIconConverter x:Key="WeaponTypeIconConverter"/>
<shmmc:AvatarNameCardPicConverter x:Key="AvatarNameCardPicConverter"/>
<shmmc:GachaAvatarImgConverter x:Key="GachaAvatarImgConverter"/>
<shmmc:DescParamDescriptor x:Key="DescParamDescriptor"/>
<shmmc:PropertyInfoDescriptor x:Key="PropertyDescriptor"/>
@@ -69,6 +70,10 @@
</shct:DescriptionTextBlock.Resources>
</shct:DescriptionTextBlock>
</DataTemplate>
<ItemsPanelTemplate x:Key="HorizontalStackPanelTemplate">
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Page.Resources>
<SplitView
@@ -370,6 +375,94 @@
Margin="16,16,0,0"
Skills="{Binding Selected.SkillDepot.Talents}"
ItemTemplate="{StaticResource TalentDataTemplate}"/>
<TextBlock Text="搭配角色" Style="{StaticResource BaseTextBlockStyle}" Margin="16,32,0,0"/>
<GridView
Margin="16,16,0,0"
SelectionMode="None"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Selected.Collocation.Avatars}">
<GridView.ItemTemplate>
<DataTemplate>
<Border
ToolTipService.ToolTip="{Binding Name}"
Background="{StaticResource CardBackgroundFillColorDefault}">
<StackPanel>
<shvc:ItemIcon
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<TextBlock
Margin="0,0,0,2"
HorizontalAlignment="Center"
Text="{Binding Rate}"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock Text="搭配武器" Style="{StaticResource BaseTextBlockStyle}" Margin="16,0,0,0"/>
<GridView
Margin="16,16,0,0"
SelectionMode="None"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Selected.Collocation.Weapons}">
<GridView.ItemTemplate>
<DataTemplate>
<Border
ToolTipService.ToolTip="{Binding Name}"
Background="{StaticResource CardBackgroundFillColorDefault}">
<StackPanel>
<shvc:ItemIcon
Icon="{Binding Icon}"
Quality="{Binding Quality}"/>
<TextBlock
Margin="0,0,0,2"
HorizontalAlignment="Center"
Text="{Binding Rate}"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock Text="搭配圣遗物" Style="{StaticResource BaseTextBlockStyle}" Margin="16,0,0,0"/>
<GridView
Margin="16,16,0,0"
SelectionMode="None"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Selected.Collocation.ReliquarySets}">
<GridView.ItemTemplate>
<DataTemplate>
<Border
ToolTipService.ToolTip="{Binding Name}"
Background="{StaticResource CardBackgroundFillColorDefault}">
<StackPanel>
<Grid>
<shvc:ItemIcon Quality="QUALITY_ORANGE"/>
<ItemsControl
Margin="0,0,16,0"
HorizontalAlignment="Center"
ItemsSource="{Binding Icons}"
ItemsPanel="{StaticResource HorizontalStackPanelTemplate}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<shci:CachedImage Width="48" Margin="0,0,-16,0" Source="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
<TextBlock
Margin="0,0,0,2"
HorizontalAlignment="Center"
Text="{Binding Rate}"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<TextBlock Text="其他" Style="{StaticResource BaseTextBlockStyle}" Margin="16,32,0,0"/>
<!--衣装-->
@@ -445,6 +538,17 @@
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander>
<Border
Margin="16,16,0,0"
Background="{StaticResource CardBackgroundFillColorDefault}"
BorderThickness="1"
BorderBrush="{StaticResource CardStrokeColorDefault}"
CornerRadius="{StaticResource CompatCornerRadius}">
<shci:CachedImage
HorizontalAlignment="Stretch"
Source="{Binding Selected.Icon,Converter={StaticResource GachaAvatarImgConverter}}"/>
</Border>
</StackPanel>
</ScrollViewer>
</Grid>

View File

@@ -15,7 +15,7 @@ namespace Snap.Hutao.ViewModel;
[Injection(InjectAs.Scoped)]
internal class HutaoDatabaseViewModel : ObservableObject, ISupportCancellation
{
private readonly IHtaoCache hutaoCache;
private readonly IHutaoCache hutaoCache;
private List<ComplexAvatarRank>? avatarUsageRanks;
private List<ComplexAvatarRank>? avatarAppearanceRanks;
@@ -28,7 +28,7 @@ internal class HutaoDatabaseViewModel : ObservableObject, ISupportCancellation
/// <param name="hutaoCache">胡桃服务缓存</param>
/// <param name="metadataService">元数据服务</param>
/// <param name="asyncRelayCommandFactory">异步命令工厂</param>
public HutaoDatabaseViewModel(IHtaoCache hutaoCache, IAsyncRelayCommandFactory asyncRelayCommandFactory)
public HutaoDatabaseViewModel(IHutaoCache hutaoCache, IAsyncRelayCommandFactory asyncRelayCommandFactory)
{
this.hutaoCache = hutaoCache;

View File

@@ -6,8 +6,11 @@ using CommunityToolkit.WinUI.UI;
using Snap.Hutao.Core.Threading;
using Snap.Hutao.Factory.Abstraction;
using Snap.Hutao.Model;
using Snap.Hutao.Model.Binding.Hutao;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Hutao;
using Snap.Hutao.Service.Metadata;
namespace Snap.Hutao.ViewModel;
@@ -19,6 +22,7 @@ namespace Snap.Hutao.ViewModel;
internal class WikiAvatarViewModel : ObservableObject
{
private readonly IMetadataService metadataService;
private readonly IHutaoCache hutaoCache;
// filters
private readonly List<Selectable<string>> filterElementInfos;
@@ -34,10 +38,12 @@ internal class WikiAvatarViewModel : ObservableObject
/// 构造一个新的角色资料视图模型
/// </summary>
/// <param name="metadataService">元数据服务</param>
/// <param name="hutaoCache">胡桃缓存</param>
/// <param name="asyncRelayCommandFactory">异步命令工厂</param>
public WikiAvatarViewModel(IMetadataService metadataService, IAsyncRelayCommandFactory asyncRelayCommandFactory)
public WikiAvatarViewModel(IMetadataService metadataService, IHutaoCache hutaoCache, IAsyncRelayCommandFactory asyncRelayCommandFactory)
{
this.metadataService = metadataService;
this.hutaoCache = hutaoCache;
OpenUICommand = asyncRelayCommandFactory.Create(OpenUIAsync);
filterElementInfos = new()
@@ -146,17 +152,33 @@ internal class WikiAvatarViewModel : ObservableObject
{
if (await metadataService.InitializeAsync().ConfigureAwait(false))
{
IList<Avatar> avatars = await metadataService.GetAvatarsAsync().ConfigureAwait(false);
IOrderedEnumerable<Avatar> sorted = avatars
List<Avatar> avatars = await metadataService.GetAvatarsAsync().ConfigureAwait(false);
List<Avatar> sorted = avatars
.OrderByDescending(avatar => avatar.BeginTime)
.ThenByDescending(avatar => avatar.Sort);
.ThenByDescending(avatar => avatar.Sort)
.ToList();
await CombineWithAvatarCollocationsAsync(sorted).ConfigureAwait(false);
await ThreadHelper.SwitchToMainThreadAsync();
Avatars = new AdvancedCollectionView(sorted.ToList(), true);
Avatars = new AdvancedCollectionView(sorted, true);
Selected = Avatars.Cast<Avatar>().FirstOrDefault();
}
}
private async Task CombineWithAvatarCollocationsAsync(List<Avatar> avatars)
{
if (await hutaoCache.InitializeForWikiAvatarViewModelAsync().ConfigureAwait(false))
{
Dictionary<AvatarId, ComplexAvatarCollocation> idCollocations = hutaoCache.AvatarCollocations!.ToDictionary(a => a.AvatarId);
foreach (Avatar avatar in avatars)
{
avatar.Collocation = idCollocations.GetValueOrDefault(avatar.Id);
}
}
}
private void OnFilterChanged()
{
if (Avatars is not null)

View File

@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.Web.Hutao.Model;
/// <summary>
@@ -11,5 +13,5 @@ public abstract class AvatarBuild
/// <summary>
/// 角色Id
/// </summary>
public int AvatarId { get; set; }
public AvatarId AvatarId { get; set; }
}