mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
collocation for wiki avatar
This commit is contained in:
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
internal class ComplexAvatar
|
||||
public class ComplexAvatar
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个胡桃数据库角色
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
/// <summary>
|
||||
/// 圣遗物套装
|
||||
/// </summary>
|
||||
internal class ComplexReliquarySet
|
||||
public class ComplexReliquarySet
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的胡桃数据库圣遗物套装
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Snap.Hutao.Model.Binding.Hutao;
|
||||
/// <summary>
|
||||
/// 胡桃数据库武器
|
||||
/// </summary>
|
||||
internal class ComplexWeapon
|
||||
public class ComplexWeapon
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个胡桃数据库武器
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Snap.Hutao.Service.Hutao;
|
||||
/// <summary>
|
||||
/// 胡桃 API 缓存
|
||||
/// </summary>
|
||||
internal interface IHtaoCache
|
||||
internal interface IHutaoCache
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色使用率
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user