using System; using System.Collections.Generic; using GeometryTD.CustomUtility; using GeometryTD.Definition; using GeometryTD.UI; using UnityEngine; namespace GeometryTD.Entity { public sealed class CombatSelectUseCaseConfigurator { private const int BuildOptionCount = 4; private readonly BuildTowerVisualInfo[] _buildTowerVisualInfos = new BuildTowerVisualInfo[BuildOptionCount]; public void Configure( CombatSelectFormUseCase useCase, Func coinProvider, Func> buildActionFactory, Func upgradeAction, int upgradeCost, Func destroyAction, int destroyGain, int[] buildTowerCosts, int currentBuildTowerCount, BackpackInventoryData inventorySnapshot, IReadOnlyList participantTowers) { if (useCase == null) { return; } useCase.SetCoinProvider(coinProvider); Dictionary muzzleMap = BuildComponentMap(inventorySnapshot?.MuzzleComponents); Dictionary bearingMap = BuildComponentMap(inventorySnapshot?.BearingComponents); Dictionary baseMap = BuildComponentMap(inventorySnapshot?.BaseComponents); int availableBuildCount = Mathf.Clamp(currentBuildTowerCount, 0, BuildOptionCount); for (int i = 0; i < BuildOptionCount; i++) { bool isBuildAvailable = i < availableBuildCount; BuildTowerVisualInfo buildVisual = ResolveBuildTowerVisual(participantTowers, i, muzzleMap, bearingMap, baseMap); _buildTowerVisualInfos[i] = buildVisual; useCase.SetBuildAction( i, isBuildAvailable && buildActionFactory != null ? buildActionFactory.Invoke(i) : null, GetBuildTowerCost(buildTowerCosts, i), null, isBuildAvailable, buildVisual.BaseColor, buildVisual.BearingColor, buildVisual.MuzzleColor); useCase.SetBuildVisible(i, isBuildAvailable); } useCase.SetUpgradeAction(upgradeAction, Mathf.Max(0, upgradeCost)); useCase.SetDestroyAction(destroyAction, Mathf.Max(0, destroyGain)); } public BuildTowerVisualInfo GetBuildVisualInfo(int buildIndex) { if (buildIndex < 0 || buildIndex >= _buildTowerVisualInfos.Length) { return BuildTowerVisualInfo.Default; } return _buildTowerVisualInfos[buildIndex]; } private static int GetBuildTowerCost(int[] buildTowerCosts, int buildIndex) { if (buildTowerCosts == null || buildIndex < 0 || buildIndex >= buildTowerCosts.Length) { return 0; } return Mathf.Max(0, buildTowerCosts[buildIndex]); } private static BuildTowerVisualInfo ResolveBuildTowerVisual( IReadOnlyList participantTowers, int buildIndex, IReadOnlyDictionary muzzleMap, IReadOnlyDictionary bearingMap, IReadOnlyDictionary baseMap) { if (participantTowers == null || buildIndex < 0 || buildIndex >= participantTowers.Count) { return BuildTowerVisualInfo.Default; } TowerItemData tower = participantTowers[buildIndex]; if (tower == null) { return BuildTowerVisualInfo.Default; } Color muzzleColor = ResolveComponentColor(muzzleMap, tower.MuzzleComponentInstanceId); Color bearingColor = ResolveComponentColor(bearingMap, tower.BearingComponentInstanceId); Color baseColor = ResolveComponentColor(baseMap, tower.BaseComponentInstanceId); return new BuildTowerVisualInfo(muzzleColor, bearingColor, baseColor); } private static Color ResolveComponentColor(IReadOnlyDictionary componentMap, long componentId) where TComp : TowerCompItemData { if (componentMap == null || componentId <= 0) { return Color.white; } return componentMap.TryGetValue(componentId, out TComp component) && component != null ? IconColorGenerator.GenerateForComponent(component) : Color.white; } private static Dictionary BuildComponentMap(IReadOnlyList items) where TComp : TowerCompItemData { Dictionary map = new Dictionary(); if (items == null) { return map; } for (int i = 0; i < items.Count; i++) { TComp item = items[i]; if (item == null || item.InstanceId <= 0) { continue; } map[item.InstanceId] = item; } return map; } } public readonly struct BuildTowerVisualInfo { public static BuildTowerVisualInfo Default => new BuildTowerVisualInfo(Color.white, Color.white, Color.white); public BuildTowerVisualInfo(Color muzzleColor, Color bearingColor, Color baseColor) { MuzzleColor = muzzleColor; BearingColor = bearingColor; BaseColor = baseColor; } public Color MuzzleColor { get; } public Color BearingColor { get; } public Color BaseColor { get; } } }