geometry-tower-defense/Assets/GameMain/Scripts/CustomComponent/InventoryGeneration/RewardCandidateBuilder.cs

80 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
using GeometryTD.DataTable;
using GeometryTD.Definition;
using UnityEngine;
namespace GeometryTD.CustomComponent
{
public sealed class RewardCandidateBuilder
{
private readonly DropPoolRoller _dropPoolRoller;
public RewardCandidateBuilder(DropPoolRoller dropPoolRoller)
{
_dropPoolRoller = dropPoolRoller;
}
public IReadOnlyList<TowerCompItemData> BuildCandidates(
int displayPhaseIndex,
LevelThemeType themeType,
int candidateCount,
Func<DROutGameDropPool, TowerCompItemData> buildRewardItem)
{
int resolvedCount = Mathf.Max(0, candidateCount);
if (resolvedCount <= 0)
{
return Array.Empty<TowerCompItemData>();
}
List<TowerCompItemData> candidates = new List<TowerCompItemData>(resolvedCount);
HashSet<int> selectedPoolRowIds = new HashSet<int>();
int maxAttempts = Mathf.Max(resolvedCount * 6, resolvedCount);
int phaseIndex = Mathf.Max(1, displayPhaseIndex);
int attempts = 0;
while (candidates.Count < resolvedCount && attempts < maxAttempts)
{
attempts++;
if (!_dropPoolRoller.TryRollRow(phaseIndex, themeType, out DROutGameDropPool selectedRow) || selectedRow == null)
{
break;
}
if (!selectedPoolRowIds.Add(selectedRow.Id))
{
continue;
}
TowerCompItemData candidate = buildRewardItem(selectedRow);
if (candidate == null)
{
continue;
}
candidates.Add(candidate);
}
attempts = 0;
while (candidates.Count < resolvedCount && attempts < maxAttempts)
{
attempts++;
if (!_dropPoolRoller.TryRollRow(phaseIndex, themeType, out DROutGameDropPool selectedRow) || selectedRow == null)
{
break;
}
TowerCompItemData candidate = buildRewardItem(selectedRow);
if (candidate == null)
{
continue;
}
candidates.Add(candidate);
}
return candidates;
}
}
}