using System; using System.Collections.Generic; using GeometryTD.CustomUtility; using GeometryTD.Definition; using UnityEngine; namespace GeometryTD.UI { public partial class RepoFormController { private RepoFormContext BuildContext(RepoFormRawData rawData) { _itemContextMap.Clear(); _itemDescSeedMap.Clear(); if (rawData?.Inventory == null) { _participantTowerIds.Clear(); return null; } Dictionary muzzleMap = BuildComponentMap(rawData.Inventory.MuzzleComponents); Dictionary bearingMap = BuildComponentMap(rawData.Inventory.BearingComponents); Dictionary baseMap = BuildComponentMap(rawData.Inventory.BaseComponents); Dictionary towerMap = BuildTowerMap(rawData.Inventory.Towers); List items = new List(); if (rawData.Inventory.Towers != null) { foreach (TowerItemData tower in rawData.Inventory.Towers) { if (tower == null) { continue; } AddItemContext(items, new RepoItemContext { InstanceId = tower.InstanceId, CanDrag = true, EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.None, IconAreaContext = BuildIconAreaContext(tower) }); AddItemDescSeed( tower.InstanceId, tower.Name, "Tower", ItemDescUtility.BuildTowerDesc(tower, muzzleMap, bearingMap, baseMap) ?? string.Empty, tower.Stats != null ? tower.Stats.Tags : null); } } if (rawData.Inventory.MuzzleComponents != null) { foreach (MuzzleCompItemData item in rawData.Inventory.MuzzleComponents) { if (item == null || item.IsAssembledIntoTower) { continue; } AddItemContext(items, new RepoItemContext { InstanceId = item.InstanceId, CanDrag = true, EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.Muzzle, IconAreaContext = BuildIconAreaContext(item) }); AddItemDescSeed( item.InstanceId, item.Name, BuildComponentTypeText(item.SlotType), ItemDescUtility.BuildMuzzleDesc(item) ?? string.Empty, item.Tags); } } if (rawData.Inventory.BearingComponents != null) { foreach (BearingCompItemData item in rawData.Inventory.BearingComponents) { if (item == null || item.IsAssembledIntoTower) { continue; } AddItemContext(items, new RepoItemContext { InstanceId = item.InstanceId, CanDrag = true, EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.Bearing, IconAreaContext = BuildIconAreaContext(item) }); AddItemDescSeed( item.InstanceId, item.Name, BuildComponentTypeText(item.SlotType), ItemDescUtility.BuildBearingDesc(item) ?? string.Empty, item.Tags); } } if (rawData.Inventory.BaseComponents != null) { foreach (BaseCompItemData item in rawData.Inventory.BaseComponents) { if (item == null || item.IsAssembledIntoTower) { continue; } AddItemContext(items, new RepoItemContext { InstanceId = item.InstanceId, CanDrag = true, EnduranceRate01 = ItemDescUtility.ResolveComponentEnduranceRate(item), ClickActionType = RepoItemClickActionType.OpenDetail, ComponentSlotType = TowerCompSlotType.Base, IconAreaContext = BuildIconAreaContext(item) }); AddItemDescSeed( item.InstanceId, item.Name, BuildComponentTypeText(item.SlotType), ItemDescUtility.BuildBaseDesc(item) ?? string.Empty, item.Tags); } } ParticipantAreaContext participantAreaContext = BuildParticipantAreaContext(rawData.Inventory, towerMap, muzzleMap, bearingMap, baseMap); return new RepoFormContext { CombineAreaContext = new CombineAreaContext(), CompAreaContext = new CompAreaContext { Items = items.ToArray() }, ParticipantAreaContext = participantAreaContext }; } private void AddItemContext(List items, RepoItemContext itemContext) { if (itemContext == null) { return; } items.Add(itemContext); _itemContextMap[itemContext.InstanceId] = itemContext; } private void AddItemDescSeed(long itemId, string title, string typeText, string description, TagType[] tags) { if (itemId <= 0) { return; } _itemDescSeedMap[itemId] = new ItemDescSeed { Title = string.IsNullOrWhiteSpace(title) ? $"Item {itemId}" : title, TypeText = typeText ?? string.Empty, Description = description ?? string.Empty, Tags = CloneTags(tags) }; } private static TagType[] CloneTags(TagType[] tags) { return tags != null ? (TagType[])tags.Clone() : Array.Empty(); } private static string BuildComponentTypeText(TowerCompSlotType slotType) { return slotType switch { TowerCompSlotType.Muzzle => "Muzzle Component", TowerCompSlotType.Bearing => "Bearing Component", TowerCompSlotType.Base => "Base Component", TowerCompSlotType.Accessory => "Accessory", _ => "Component" }; } 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; } private static Dictionary BuildTowerMap(IReadOnlyList towers) { Dictionary map = new Dictionary(); if (towers == null) { return map; } for (int i = 0; i < towers.Count; i++) { TowerItemData tower = towers[i]; if (tower == null || tower.InstanceId <= 0) { continue; } map[tower.InstanceId] = tower; } return map; } private ParticipantAreaContext BuildParticipantAreaContext( BackpackInventoryData inventory, IReadOnlyDictionary towerMap, IReadOnlyDictionary muzzleMap, IReadOnlyDictionary bearingMap, IReadOnlyDictionary baseMap) { _participantTowerIds.Clear(); List participantItems = new List(); if (inventory?.ParticipantTowerInstanceIds != null && towerMap != null) { for (int i = 0; i < inventory.ParticipantTowerInstanceIds.Count; i++) { long towerId = inventory.ParticipantTowerInstanceIds[i]; if (towerId <= 0) { continue; } if (!towerMap.TryGetValue(towerId, out TowerItemData tower) || tower == null) { continue; } if (!_participantTowerIds.Add(towerId)) { continue; } participantItems.Add(new RepoItemContext { InstanceId = tower.InstanceId, CanDrag = false, EnduranceRate01 = ItemDescUtility.ResolveTowerEnduranceRate(tower, muzzleMap, bearingMap, baseMap), ClickActionType = RepoItemClickActionType.RemoveParticipant, ComponentSlotType = TowerCompSlotType.None, IconAreaContext = BuildIconAreaContext(tower) }); } } return new ParticipantAreaContext { Items = participantItems.ToArray(), MaxCount = MaxParticipantCount }; } private void ApplyParticipantSelection() { if (Form == null || _itemContextMap.Count <= 0) { return; } foreach (KeyValuePair pair in _itemContextMap) { RepoItemContext itemContext = pair.Value; if (itemContext == null || itemContext.ComponentSlotType != TowerCompSlotType.None) { continue; } Form.SetRepoItemSelected(pair.Key, _participantTowerIds.Contains(pair.Key)); } } private void RefreshParticipantAreaOnly() { if (_useCase == null || Form == null) { return; } RepoFormContext latestContext = BuildContext(_useCase.CreateInitialModel()); if (latestContext?.ParticipantAreaContext == null) { return; } Form.RefreshParticipantArea(latestContext.ParticipantAreaContext); ApplyParticipantSelection(); } private static IconAreaContext BuildIconAreaContext(TowerItemData tower) { if (tower == null) { return new IconAreaContext { ComponentSlotType = TowerCompSlotType.None, Rarity = RarityType.None, Color = Color.white, Icon = null }; } return new IconAreaContext { ComponentSlotType = TowerCompSlotType.None, Rarity = tower.Rarity, Color = IconColorGenerator.GenerateForTower(tower), Icon = null }; } private static IconAreaContext BuildIconAreaContext(TowerCompItemData item) { if (item == null) { return new IconAreaContext { ComponentSlotType = TowerCompSlotType.None, Rarity = RarityType.None, Color = Color.white, Icon = null }; } return new IconAreaContext { ComponentSlotType = item.SlotType, Rarity = item.Rarity, Color = IconColorGenerator.GenerateForComponent(item), Icon = null }; } } }