1
0
mirror of https://github.com/wangdage12/Snap.Hutao.git synced 2026-07-31 04:10:25 +08:00

当角色满,而武器未满时。使武器也能关联上角色

This commit is contained in:
mfkvfhpdx
2026-05-04 10:43:20 +08:00
parent 18afbffbcc
commit c6a2212caa
4 changed files with 111 additions and 0 deletions
@@ -0,0 +1,41 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Snap.Hutao.Migrations
{
/// <inheritdoc />
public partial class AddCultivateEntryAssociationOnly : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_cultivate_entries_cultivate_entries_RelatedEntryId",
table: "cultivate_entries");
migrationBuilder.AddForeignKey(
name: "FK_cultivate_entries_cultivate_entries_RelatedEntryId",
table: "cultivate_entries",
column: "RelatedEntryId",
principalTable: "cultivate_entries",
principalColumn: "InnerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_cultivate_entries_cultivate_entries_RelatedEntryId",
table: "cultivate_entries");
migrationBuilder.AddForeignKey(
name: "FK_cultivate_entries_cultivate_entries_RelatedEntryId",
table: "cultivate_entries",
column: "RelatedEntryId",
principalTable: "cultivate_entries",
principalColumn: "InnerId",
onDelete: ReferentialAction.SetNull);
}
}
}
@@ -77,6 +77,11 @@ internal sealed partial class CultivationService : ICultivationService
foreach (ref readonly CultivateEntry entry in entries.AsSpan())
{
ImmutableArray<CultivateItem> items = cultivationRepository.GetCultivateItemImmutableArrayByEntryId(entry.InnerId);
if (IsHiddenAssociationOnlyAvatarEntry(entry, items.Length))
{
continue;
}
ImmutableArray<CultivateItemView>.Builder entryItems = ImmutableArray.CreateBuilder<CultivateItemView>(items.Length);
foreach (ref readonly CultivateItem cultivateItem in items.AsSpan())
@@ -267,6 +272,34 @@ internal sealed partial class CultivationService : ICultivationService
return cultivationRepository.TryGetAvatarCultivateEntryInnerId(projects.CurrentItem.InnerId, avatarId);
}
public async ValueTask<Guid?> EnsureAvatarAssociationStubAsync(uint avatarId, LevelInformation levelInformation)
{
IAdvancedDbCollectionView<CultivateProject> projects = await GetProjectCollectionAsync().ConfigureAwait(false);
if (!await EnsureCurrentProjectAsync(projects).ConfigureAwait(false))
{
return null;
}
ArgumentNullException.ThrowIfNull(projects.CurrentItem);
await taskContext.SwitchToBackgroundAsync();
Guid projectId = projects.CurrentItem.InnerId;
if (cultivationRepository.TryGetAvatarCultivateEntryInnerId(projectId, avatarId) is Guid existing)
{
return existing;
}
CultivateEntry entry = CultivateEntry.From(projectId, CultivateType.AvatarAndSkill, avatarId);
cultivationRepository.AddCultivateEntry(entry);
CultivateEntryLevelInformation level = CultivateEntryLevelInformation.From(entry.InnerId, CultivateType.AvatarAndSkill, levelInformation);
cultivationRepository.AddLevelInformation(level);
entryCollectionCache.TryRemove(projectId, out _);
return entry.InnerId;
}
public async ValueTask<ProjectAddResultKind> TryAddProjectAsync(CultivateProject project)
{
if (string.IsNullOrWhiteSpace(project.Name))
@@ -483,4 +516,25 @@ internal sealed partial class CultivationService : ICultivationService
string avatarName = context.GetAvatarItem(related.Id).Name;
return $"{avatarName}·{weaponName}";
}
/// <summary>
/// 无材料的「已满配」角色占位行不在养成列表展示(仍为武器的 RelatedEntryId 解析目标)。
/// </summary>
private static bool IsHiddenAssociationOnlyAvatarEntry(CultivateEntry entry, int cultivateItemCount)
{
if (entry.Type is not CultivateType.AvatarAndSkill || cultivateItemCount != 0)
{
return false;
}
if (entry.LevelInformation is not CultivateEntryLevelInformation li)
{
return false;
}
return li.AvatarLevelFrom == li.AvatarLevelTo
&& li.SkillALevelFrom == li.SkillALevelTo
&& li.SkillELevelFrom == li.SkillELevelTo
&& li.SkillQLevelFrom == li.SkillQLevelTo;
}
}
@@ -29,6 +29,12 @@ internal interface ICultivationService
ValueTask<Guid?> TryGetAvatarCultivateEntryInnerIdAsync(uint avatarId);
/// <summary>
/// 当前计划中尚无该角色的养成条目时,插入一条无材料行的角色占位条目(等级信息与 delta 一致),供武器 RelatedEntryId 关联。
/// 若已存在角色条目则返回其 InnerId。
/// </summary>
ValueTask<Guid?> EnsureAvatarAssociationStubAsync(uint avatarId, LevelInformation levelInformation);
void SaveCultivateItem(CultivateItemView item);
ValueTask<ProjectAddResultKind> TryAddProjectAsync(CultivateProject project);
@@ -364,6 +364,16 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
relatedAvatarEntryId = await scopeContext.CultivationService.TryGetAvatarCultivateEntryInnerIdAsync(options.Delta.AvatarId).ConfigureAwait(false);
}
if (relatedAvatarEntryId is null && avatarSave.Kind is ConsumptionSaveResultKind.NoItem)
{
relatedAvatarEntryId = await scopeContext.CultivationService.TryGetAvatarCultivateEntryInnerIdAsync(options.Delta.AvatarId).ConfigureAwait(false);
}
if (relatedAvatarEntryId is null && !consumption.WeaponConsume.IsEmpty)
{
relatedAvatarEntryId = await scopeContext.CultivationService.EnsureAvatarAssociationStubAsync(options.Delta.AvatarId, levelInformation).ConfigureAwait(false);
}
InputConsumption weaponInput = new()
{
Type = CultivateType.Weapon,