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