mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
refactor metadata abstraction
This commit is contained in:
@@ -12,7 +12,8 @@ namespace Snap.Hutao.Model.Entity;
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[Table("inventory_items")]
|
||||
internal sealed class InventoryItem : IDbMappingForeignKeyFrom<InventoryItem, uint>, IDbMappingForeignKeyFrom<InventoryItem, uint, uint>
|
||||
internal sealed class InventoryItem : IDbMappingForeignKeyFrom<InventoryItem, uint>,
|
||||
IDbMappingForeignKeyFrom<InventoryItem, uint, uint>
|
||||
{
|
||||
/// <summary>
|
||||
/// 内部Id
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Snap.Hutao.Model.InterChange.GachaLog;
|
||||
/// UIGF物品
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class UIGFItem : GachaLogItem, IMappingFrom<UIGFItem, GachaItem, INameQuality>
|
||||
internal sealed class UIGFItem : GachaLogItem, IMappingFrom<UIGFItem, GachaItem, INameQualityAccess>
|
||||
{
|
||||
/// <summary>
|
||||
/// 额外祈愿映射
|
||||
@@ -22,7 +22,7 @@ internal sealed class UIGFItem : GachaLogItem, IMappingFrom<UIGFItem, GachaItem,
|
||||
[JsonEnum(JsonSerializeType.NumberString)]
|
||||
public GachaType UIGFGachaType { get; set; } = default!;
|
||||
|
||||
public static UIGFItem From(GachaItem item, INameQuality nameQuality)
|
||||
public static UIGFItem From(GachaItem item, INameQualityAccess nameQuality)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Abstraction;
|
||||
|
||||
internal interface ICultivatable
|
||||
internal interface ICultivationItemsAccess
|
||||
{
|
||||
List<MaterialId> CultivationItems { get; }
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Abstraction;
|
||||
|
||||
internal interface IItemSource
|
||||
internal interface IItemConvertible
|
||||
{
|
||||
Model.Item ToItem();
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace Snap.Hutao.Model.Metadata.Abstraction;
|
||||
/// 物品与星级
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal interface INameQuality
|
||||
internal interface INameQualityAccess
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
@@ -9,7 +9,7 @@ namespace Snap.Hutao.Model.Metadata.Abstraction;
|
||||
/// 指示该类为统计物品的源
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal interface IStatisticsItemSource
|
||||
internal interface IStatisticsItemConvertible
|
||||
{
|
||||
/// <summary>
|
||||
/// 转换到统计物品
|
||||
@@ -10,19 +10,9 @@ namespace Snap.Hutao.Model.Metadata.Abstraction;
|
||||
/// 指示该类为简述统计物品的源
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal interface ISummaryItemSource
|
||||
internal interface ISummaryItemConvertible
|
||||
{
|
||||
/// <summary>
|
||||
/// 星级
|
||||
/// </summary>
|
||||
QualityType Quality { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 转换到简述统计物品
|
||||
/// </summary>
|
||||
/// <param name="lastPull">距上个五星</param>
|
||||
/// <param name="time">时间</param>
|
||||
/// <param name="isUp">是否为Up物品</param>
|
||||
/// <returns>简述统计物品</returns>
|
||||
SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp);
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Metadata.Abstraction;
|
||||
using Snap.Hutao.Model.Metadata.Converter;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
using Snap.Hutao.ViewModel.Complex;
|
||||
using Snap.Hutao.ViewModel.GachaLog;
|
||||
using Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Avatar;
|
||||
|
||||
/// <summary>
|
||||
/// 角色的接口实现部分
|
||||
/// </summary>
|
||||
internal partial class Avatar : IStatisticsItemSource, ISummaryItemSource, IItemSource, INameQuality, ICalculableSource<ICalculableAvatar>, ICultivatable
|
||||
{
|
||||
/// <summary>
|
||||
/// [非元数据] 搭配数据
|
||||
/// TODO:Add View suffix.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public AvatarCollocationView? Collocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [非元数据] 烹饪奖励
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public CookBonusView? CookBonusView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [非元数据] 养成物品视图
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public List<Material>? CultivationItemsView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最大等级
|
||||
/// </summary>
|
||||
[SuppressMessage("", "CA1822")]
|
||||
public uint MaxLevel { get => GetMaxLevel(); }
|
||||
|
||||
public static uint GetMaxLevel()
|
||||
{
|
||||
return 90U;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ICalculableAvatar ToCalculable()
|
||||
{
|
||||
return CalculableAvatar.From(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为基础物品
|
||||
/// </summary>
|
||||
/// <returns>基础物品</returns>
|
||||
public Model.Item ToItem()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = AvatarIconConverter.IconNameToUri(Icon),
|
||||
Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore),
|
||||
Quality = Quality,
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public StatisticsItem ToStatisticsItem(int count)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = AvatarIconConverter.IconNameToUri(Icon),
|
||||
Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore),
|
||||
Quality = Quality,
|
||||
|
||||
Count = count,
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = AvatarIconConverter.IconNameToUri(Icon),
|
||||
Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore),
|
||||
Quality = Quality,
|
||||
|
||||
Time = time,
|
||||
LastPull = lastPull,
|
||||
IsUp = isUp,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,99 +1,118 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Metadata.Abstraction;
|
||||
using Snap.Hutao.Model.Metadata.Converter;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.ViewModel.Complex;
|
||||
using Snap.Hutao.ViewModel.GachaLog;
|
||||
using Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Avatar;
|
||||
|
||||
/// <summary>
|
||||
/// 角色
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal partial class Avatar
|
||||
internal partial class Avatar : INameQualityAccess,
|
||||
IStatisticsItemConvertible,
|
||||
ISummaryItemConvertible,
|
||||
IItemConvertible,
|
||||
ICalculableSource<ICalculableAvatar>,
|
||||
ICultivationItemsAccess
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public AvatarId Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 突破提升 Id 外键
|
||||
/// </summary>
|
||||
public PromoteId PromoteId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序号
|
||||
/// </summary>
|
||||
public uint Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 体型
|
||||
/// </summary>
|
||||
public BodyType Body { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 正面图标
|
||||
/// </summary>
|
||||
public string Icon { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 侧面图标
|
||||
/// </summary>
|
||||
public string SideIcon { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Description { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 角色加入游戏时间
|
||||
/// </summary>
|
||||
public DateTimeOffset BeginTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 星级
|
||||
/// </summary>
|
||||
public QualityType Quality { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 武器类型
|
||||
/// </summary>
|
||||
public WeaponType Weapon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 基础数值
|
||||
/// </summary>
|
||||
public AvatarBaseValue BaseValue { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 生长曲线
|
||||
/// </summary>
|
||||
public List<TypeValue<FightProperty, GrowCurveType>> GrowCurves { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 技能
|
||||
/// </summary>
|
||||
public SkillDepot SkillDepot { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 好感信息/基本信息
|
||||
/// </summary>
|
||||
public FetterInfo FetterInfo { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 皮肤
|
||||
/// </summary>
|
||||
public List<Costume> Costumes { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 养成物品
|
||||
/// </summary>
|
||||
public List<MaterialId> CultivationItems { get; set; } = default!;
|
||||
|
||||
[JsonIgnore]
|
||||
public AvatarCollocationView? CollocationView { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public CookBonusView? CookBonusView { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public List<Material>? CultivationItemsView { get; set; }
|
||||
|
||||
[SuppressMessage("", "CA1822")]
|
||||
public uint MaxLevel { get => GetMaxLevel(); }
|
||||
|
||||
public static uint GetMaxLevel()
|
||||
{
|
||||
return 90U;
|
||||
}
|
||||
|
||||
public ICalculableAvatar ToCalculable()
|
||||
{
|
||||
return CalculableAvatar.From(this);
|
||||
}
|
||||
|
||||
public Model.Item ToItem()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = AvatarIconConverter.IconNameToUri(Icon),
|
||||
Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore),
|
||||
Quality = Quality,
|
||||
};
|
||||
}
|
||||
|
||||
public StatisticsItem ToStatisticsItem(int count)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = AvatarIconConverter.IconNameToUri(Icon),
|
||||
Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore),
|
||||
Quality = Quality,
|
||||
|
||||
Count = count,
|
||||
};
|
||||
}
|
||||
|
||||
public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = AvatarIconConverter.IconNameToUri(Icon),
|
||||
Badge = ElementNameIconConverter.ElementNameToIconUri(FetterInfo.VisionBefore),
|
||||
Quality = Quality,
|
||||
|
||||
Time = time,
|
||||
LastPull = lastPull,
|
||||
IsUp = isUp,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Metadata.Abstraction;
|
||||
using Snap.Hutao.Model.Metadata.Converter;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
using Snap.Hutao.ViewModel.Complex;
|
||||
using Snap.Hutao.ViewModel.GachaLog;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Weapon;
|
||||
|
||||
/// <summary>
|
||||
/// 武器的接口实现
|
||||
/// </summary>
|
||||
internal sealed partial class Weapon : IStatisticsItemSource, ISummaryItemSource, IItemSource, INameQuality, ICalculableSource<ICalculableWeapon>, ICultivatable
|
||||
{
|
||||
/// <summary>
|
||||
/// [非元数据] 搭配数据
|
||||
/// TODO:Add View suffix.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public WeaponCollocationView? Collocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [非元数据] 养成物品视图
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public List<Material>? CultivationItemsView { get; set; }
|
||||
|
||||
/// <inheritdoc cref="INameQuality.Quality" />
|
||||
[JsonIgnore]
|
||||
public QualityType Quality
|
||||
{
|
||||
get => RankLevel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 最大等级
|
||||
/// </summary>
|
||||
internal uint MaxLevel { get => GetMaxLevelByQuality(Quality); }
|
||||
|
||||
public static uint GetMaxLevelByQuality(QualityType quality)
|
||||
{
|
||||
return quality >= QualityType.QUALITY_BLUE ? 90U : 70U;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ICalculableWeapon ToCalculable()
|
||||
{
|
||||
return CalculableWeapon.From(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换为基础物品
|
||||
/// </summary>
|
||||
/// <returns>基础物品</returns>
|
||||
public Model.Item ToItem()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = EquipIconConverter.IconNameToUri(Icon),
|
||||
Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType),
|
||||
Quality = RankLevel,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换到统计物品
|
||||
/// </summary>
|
||||
/// <param name="count">个数</param>
|
||||
/// <returns>统计物品</returns>
|
||||
public StatisticsItem ToStatisticsItem(int count)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = EquipIconConverter.IconNameToUri(Icon),
|
||||
Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType),
|
||||
Quality = RankLevel,
|
||||
Count = count,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换到简述统计物品
|
||||
/// </summary>
|
||||
/// <param name="lastPull">距上个五星</param>
|
||||
/// <param name="time">时间</param>
|
||||
/// <param name="isUp">是否为Up物品</param>
|
||||
/// <returns>简述统计物品</returns>
|
||||
public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = EquipIconConverter.IconNameToUri(Icon),
|
||||
Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType),
|
||||
Time = time,
|
||||
Quality = RankLevel,
|
||||
LastPull = lastPull,
|
||||
IsUp = isUp,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,69 +1,105 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Metadata.Abstraction;
|
||||
using Snap.Hutao.Model.Metadata.Converter;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.ViewModel.Complex;
|
||||
using Snap.Hutao.ViewModel.GachaLog;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Weapon;
|
||||
|
||||
/// <summary>
|
||||
/// 武器
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed partial class Weapon
|
||||
internal sealed partial class Weapon : INameQualityAccess,
|
||||
IStatisticsItemConvertible,
|
||||
ISummaryItemConvertible,
|
||||
IItemConvertible,
|
||||
ICalculableSource<ICalculableWeapon>,
|
||||
ICultivationItemsAccess
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public WeaponId Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 突破 Id
|
||||
/// </summary>
|
||||
public PromoteId PromoteId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 武器类型
|
||||
/// </summary>
|
||||
public WeaponType WeaponType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 等级
|
||||
/// </summary>
|
||||
public QualityType RankLevel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 描述
|
||||
/// </summary>
|
||||
public string Description { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
public string Icon { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 觉醒图标
|
||||
/// </summary>
|
||||
public string AwakenIcon { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 生长曲线
|
||||
/// </summary>
|
||||
public List<WeaponTypeValue> GrowCurves { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 被动信息, 无被动的武器为 <see langword="null"/>
|
||||
/// </summary>
|
||||
public NameDescriptions? Affix { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 养成物品
|
||||
/// </summary>
|
||||
public List<MaterialId> CultivationItems { get; set; } = default!;
|
||||
|
||||
[JsonIgnore]
|
||||
public WeaponCollocationView? CollocationView { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public List<Material>? CultivationItemsView { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public QualityType Quality
|
||||
{
|
||||
get => RankLevel;
|
||||
}
|
||||
|
||||
internal uint MaxLevel { get => GetMaxLevelByQuality(Quality); }
|
||||
|
||||
public static uint GetMaxLevelByQuality(QualityType quality)
|
||||
{
|
||||
return quality >= QualityType.QUALITY_BLUE ? 90U : 70U;
|
||||
}
|
||||
|
||||
public ICalculableWeapon ToCalculable()
|
||||
{
|
||||
return CalculableWeapon.From(this);
|
||||
}
|
||||
|
||||
public Model.Item ToItem()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = EquipIconConverter.IconNameToUri(Icon),
|
||||
Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType),
|
||||
Quality = RankLevel,
|
||||
};
|
||||
}
|
||||
|
||||
public StatisticsItem ToStatisticsItem(int count)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = EquipIconConverter.IconNameToUri(Icon),
|
||||
Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType),
|
||||
Quality = RankLevel,
|
||||
Count = count,
|
||||
};
|
||||
}
|
||||
|
||||
public SummaryItem ToSummaryItem(int lastPull, in DateTimeOffset time, bool isUp)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = Name,
|
||||
Icon = EquipIconConverter.IconNameToUri(Icon),
|
||||
Badge = WeaponTypeIconConverter.WeaponTypeToIconUri(WeaponType),
|
||||
Time = time,
|
||||
Quality = RankLevel,
|
||||
LastPull = lastPull,
|
||||
IsUp = isUp,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -262,7 +262,7 @@ internal sealed partial class CultivationService : ICultivationService
|
||||
/// <inheritdoc/>
|
||||
public async ValueTask RefreshInventoryAsync(CultivateProject project)
|
||||
{
|
||||
List<ICultivatable> cultivatables =
|
||||
List<ICultivationItemsAccess> cultivationItemsEntryList =
|
||||
[
|
||||
.. await metadataService.GetAvatarListAsync().ConfigureAwait(false),
|
||||
.. (await metadataService.GetWeaponListAsync().ConfigureAwait(false)).Where(weapon => weapon.Quality >= Model.Intrinsic.QualityType.QUALITY_BLUE),
|
||||
@@ -280,7 +280,7 @@ internal sealed partial class CultivationService : ICultivationService
|
||||
CalculateClient calculateClient = scope.ServiceProvider.GetRequiredService<CalculateClient>();
|
||||
|
||||
Response<BatchConsumption>? resp = await calculateClient
|
||||
.BatchComputeAsync(userAndUid, GeneratePromotionDeltas(cultivatables), true)
|
||||
.BatchComputeAsync(userAndUid, GeneratePromotionDeltas(cultivationItemsEntryList), true)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!resp.IsOk())
|
||||
@@ -298,7 +298,7 @@ internal sealed partial class CultivationService : ICultivationService
|
||||
}
|
||||
}
|
||||
|
||||
private static List<AvatarPromotionDelta> GeneratePromotionDeltas(List<ICultivatable> cultivatables)
|
||||
private static List<AvatarPromotionDelta> GeneratePromotionDeltas(List<ICultivationItemsAccess> cultivatables)
|
||||
{
|
||||
List<MetadataAvatar> avatars = [];
|
||||
List<MetadataWeapon> weapons = [];
|
||||
@@ -306,7 +306,7 @@ internal sealed partial class CultivationService : ICultivationService
|
||||
|
||||
while (cultivatables.Count > 0)
|
||||
{
|
||||
ICultivatable bestItem = cultivatables.OrderByDescending(item => item.CultivationItems.Count(material => !materialIds.Contains(material))).First();
|
||||
ICultivationItemsAccess bestItem = cultivatables.OrderByDescending(item => item.CultivationItems.Count(material => !materialIds.Contains(material))).First();
|
||||
|
||||
if (bestItem.CultivationItems.All(materialIds.Contains))
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ internal static class GachaStatisticsExtension
|
||||
/// <param name="dict">计数器</param>
|
||||
/// <returns>统计物品列表</returns>
|
||||
public static List<StatisticsItem> ToStatisticsList<TItem>(this Dictionary<TItem, int> dict)
|
||||
where TItem : IStatisticsItemSource
|
||||
where TItem : IStatisticsItemConvertible
|
||||
{
|
||||
IOrderedEnumerable<StatisticsItem> result = dict
|
||||
.Select(kvp => kvp.Key.ToStatisticsItem(kvp.Value))
|
||||
|
||||
@@ -27,7 +27,7 @@ internal sealed partial class GachaStatisticsSlimFactory : IGachaStatisticsSlimF
|
||||
return CreateCore(context, items, uid);
|
||||
}
|
||||
|
||||
private static void Track(INameQuality nameQuality, ref int orangeTracker, ref int purpleTracker)
|
||||
private static void Track(INameQualityAccess nameQuality, ref int orangeTracker, ref int purpleTracker)
|
||||
{
|
||||
switch (nameQuality.Quality)
|
||||
{
|
||||
@@ -69,7 +69,7 @@ internal sealed partial class GachaStatisticsSlimFactory : IGachaStatisticsSlimF
|
||||
// O(n) operation
|
||||
foreach (ref readonly GachaItem item in CollectionsMarshal.AsSpan(items))
|
||||
{
|
||||
INameQuality nameQuality = context.GetNameQualityByItemId(item.ItemId);
|
||||
INameQualityAccess nameQuality = context.GetNameQualityByItemId(item.ItemId);
|
||||
switch (item.QueryType)
|
||||
{
|
||||
case GachaType.Standard:
|
||||
|
||||
@@ -16,11 +16,11 @@ internal sealed class HistoryWishBuilder
|
||||
{
|
||||
private readonly GachaEvent gachaEvent;
|
||||
|
||||
private readonly Dictionary<IStatisticsItemSource, int> orangeUpCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemSource, int> purpleUpCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemSource, int> orangeCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemSource, int> purpleCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemSource, int> blueCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemConvertible, int> orangeUpCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemConvertible, int> purpleUpCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemConvertible, int> orangeCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemConvertible, int> purpleCounter = [];
|
||||
private readonly Dictionary<IStatisticsItemConvertible, int> blueCounter = [];
|
||||
|
||||
private int totalCountTracker;
|
||||
|
||||
@@ -37,18 +37,18 @@ internal sealed class HistoryWishBuilder
|
||||
switch (ConfigType)
|
||||
{
|
||||
case GachaType.ActivityAvatar or GachaType.SpecialActivityAvatar:
|
||||
orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemSource)a, a => 0);
|
||||
purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemSource)a, a => 0);
|
||||
orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemConvertible)a, a => 0);
|
||||
purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdAvatarMap[id]).ToDictionary(a => (IStatisticsItemConvertible)a, a => 0);
|
||||
break;
|
||||
case GachaType.ActivityWeapon:
|
||||
orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemSource)w, w => 0);
|
||||
purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemSource)w, w => 0);
|
||||
orangeUpCounter = gachaEvent.UpOrangeList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemConvertible)w, w => 0);
|
||||
purpleUpCounter = gachaEvent.UpPurpleList.Select(id => context.IdWeaponMap[id]).ToDictionary(w => (IStatisticsItemConvertible)w, w => 0);
|
||||
break;
|
||||
case GachaType.ActivityCity:
|
||||
|
||||
// Avatars are less than weapons, so we try to get the value from avatar map first
|
||||
orangeUpCounter = gachaEvent.UpOrangeList.Select(id => (IStatisticsItemSource?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0);
|
||||
purpleUpCounter = gachaEvent.UpPurpleList.Select(id => (IStatisticsItemSource?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0);
|
||||
orangeUpCounter = gachaEvent.UpOrangeList.Select(id => (IStatisticsItemConvertible?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0);
|
||||
purpleUpCounter = gachaEvent.UpPurpleList.Select(id => (IStatisticsItemConvertible?)context.IdAvatarMap.GetValueOrDefault(id) ?? context.IdWeaponMap[id]).ToDictionary(c => c, c => 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ internal sealed class HistoryWishBuilder
|
||||
/// </summary>
|
||||
/// <param name="item">物品</param>
|
||||
/// <returns>是否为Up物品</returns>
|
||||
public bool IncreaseOrange(IStatisticsItemSource item)
|
||||
public bool IncreaseOrange(IStatisticsItemConvertible item)
|
||||
{
|
||||
orangeCounter.IncreaseOne(item);
|
||||
++totalCountTracker;
|
||||
@@ -86,7 +86,7 @@ internal sealed class HistoryWishBuilder
|
||||
/// 计数四星物品
|
||||
/// </summary>
|
||||
/// <param name="item">物品</param>
|
||||
public void IncreasePurple(IStatisticsItemSource item)
|
||||
public void IncreasePurple(IStatisticsItemConvertible item)
|
||||
{
|
||||
purpleUpCounter.TryIncreaseOne(item);
|
||||
purpleCounter.IncreaseOne(item);
|
||||
@@ -97,7 +97,7 @@ internal sealed class HistoryWishBuilder
|
||||
/// 计数三星武器
|
||||
/// </summary>
|
||||
/// <param name="item">武器</param>
|
||||
public void IncreaseBlue(IStatisticsItemSource item)
|
||||
public void IncreaseBlue(IStatisticsItemConvertible item)
|
||||
{
|
||||
blueCounter.IncreaseOne(item);
|
||||
++totalCountTracker;
|
||||
|
||||
@@ -55,7 +55,7 @@ internal sealed class HutaoStatisticsFactory
|
||||
|
||||
foreach (ref readonly ItemCount item in CollectionsMarshal.AsSpan(items))
|
||||
{
|
||||
IStatisticsItemSource source = item.Item.StringLength() switch
|
||||
IStatisticsItemConvertible source = item.Item.StringLength() switch
|
||||
{
|
||||
8U => context.GetAvatar(item.Item),
|
||||
5U => context.GetWeapon(item.Item),
|
||||
|
||||
@@ -44,7 +44,7 @@ internal sealed class TypedWishSummaryBuilder
|
||||
/// <param name="item">祈愿物品</param>
|
||||
/// <param name="source">对应武器</param>
|
||||
/// <param name="isUp">是否为Up物品</param>
|
||||
public void Track(GachaItem item, ISummaryItemSource source, bool isUp)
|
||||
public void Track(GachaItem item, ISummaryItemConvertible source, bool isUp)
|
||||
{
|
||||
if (!context.TypeEvaluator(item.GachaType))
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ internal sealed class GachaLogServiceMetadataContext : IMetadataContext,
|
||||
return result;
|
||||
}
|
||||
|
||||
public INameQuality GetNameQualityByItemId(uint id)
|
||||
public INameQualityAccess GetNameQualityByItemId(uint id)
|
||||
{
|
||||
uint place = id.StringLength();
|
||||
return place switch
|
||||
|
||||
@@ -571,7 +571,7 @@
|
||||
Grid.Column="0"
|
||||
ItemTemplate="{StaticResource CollocationTemplate}"
|
||||
ItemsPanel="{StaticResource StackPanelSpacing4Template}"
|
||||
ItemsSource="{Binding Selected.Collocation.Avatars}"/>
|
||||
ItemsSource="{Binding Selected.CollocationView.Avatars}"/>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
@@ -582,7 +582,7 @@
|
||||
Grid.Column="1"
|
||||
ItemTemplate="{StaticResource CollocationTemplate}"
|
||||
ItemsPanel="{StaticResource StackPanelSpacing4Template}"
|
||||
ItemsSource="{Binding Selected.Collocation.Weapons}"/>
|
||||
ItemsSource="{Binding Selected.CollocationView.Weapons}"/>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
@@ -593,7 +593,7 @@
|
||||
Grid.Column="2"
|
||||
ItemTemplate="{StaticResource CollocationReliquaryTemplate}"
|
||||
ItemsPanel="{StaticResource StackPanelSpacing4Template}"
|
||||
ItemsSource="{Binding Selected.Collocation.ReliquarySets}"/>
|
||||
ItemsSource="{Binding Selected.CollocationView.ReliquarySets}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
<Border Padding="16" Style="{ThemeResource BorderCardStyle}">
|
||||
<StackPanel Spacing="16">
|
||||
<TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageWiKiAvatarTeamCombinationHeader}"/>
|
||||
<ItemsControl ItemTemplate="{StaticResource CollocationTemplate}" ItemsSource="{Binding Selected.Collocation.Avatars}">
|
||||
<ItemsControl ItemTemplate="{StaticResource CollocationTemplate}" ItemsSource="{Binding Selected.CollocationView.Avatars}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<cwc:UniformGrid
|
||||
|
||||
@@ -148,7 +148,7 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
|
||||
foreach (Avatar avatar in avatars)
|
||||
{
|
||||
avatar.Collocation = hutaoCache.AvatarCollocations.GetValueOrDefault(avatar.Id);
|
||||
avatar.CollocationView = hutaoCache.AvatarCollocations.GetValueOrDefault(avatar.Id);
|
||||
avatar.CookBonusView ??= CookBonusView.Create(avatar.FetterInfo.CookBonus, idMaterialMap);
|
||||
avatar.CultivationItemsView ??= avatar.CultivationItems.SelectList(i => idMaterialMap.GetValueOrDefault(i, Material.Default));
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
|
||||
foreach (Weapon weapon in weapons)
|
||||
{
|
||||
weapon.Collocation = hutaoCache.WeaponCollocations.GetValueOrDefault(weapon.Id);
|
||||
weapon.CollocationView = hutaoCache.WeaponCollocations.GetValueOrDefault(weapon.Id);
|
||||
weapon.CultivationItemsView ??= weapon.CultivationItems.SelectList(i => idMaterialMap.GetValueOrDefault(i, Material.Default));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user