using System.Collections.Generic; using GeometryTD.CustomEvent; using GeometryTD.Definition; using GameFramework.Event; using UnityGameFramework.Runtime; namespace GeometryTD.UI { public class RepoFormController : UIFormControllerCommonBase { private RepoFormUseCase _useCase; private readonly Dictionary _itemContextMap = new Dictionary(); protected override UIFormType UIFormTypeId => UIFormType.RepoForm; protected override void RefreshUI(RepoForm form, RepoFormContext context) { form.RefreshUI(context); } protected override void SubscribeCustomEvents() { GameEntry.Event.Subscribe(RepoItemSelectedEventArgs.EventId, OnRepoItemSelected); GameEntry.Event.Subscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked); } protected override void UnsubscribeCustomEvents() { GameEntry.Event.Unsubscribe(RepoItemSelectedEventArgs.EventId, OnRepoItemSelected); GameEntry.Event.Unsubscribe(CombineSlotClickedEventArgs.EventId, OnCombineSlotClicked); } public override int? OpenUI(object userData = null) { if (userData is RepoFormContext repoFormContext) { return OpenUIInternal(repoFormContext); } if (userData is RepoFormRawData rawDataFromUserData) { return OpenUI(rawDataFromUserData); } if (userData != null) { Log.Warning("RepoFormController.OpenUI() userData type is invalid."); return null; } if (_useCase == null) { Log.Error("RepoFormController.OpenUI() useCase is null."); return null; } RepoFormRawData rawData = _useCase.CreateInitialModel(); return OpenUI(rawData); } public int? OpenUI(RepoFormRawData rawData) { RepoFormContext context = BuildContext(rawData); return OpenUIInternal(context); } public override void BindUseCase(IUIUseCase useCase) { if (!(useCase is RepoFormUseCase repoFormUseCase)) { Log.Error("RepoFormController.BindUseCase() useCase is invalid."); return; } _useCase = repoFormUseCase; } private RepoFormContext BuildContext(RepoFormRawData rawData) { _itemContextMap.Clear(); if (rawData?.Inventory == null) { return null; } List items = new List(); if (rawData.Inventory.Towers != null) { foreach (var tower in rawData.Inventory.Towers) { AddItemContext(items, new RepoItemContext { Title = $"[Tower] {tower.Name} ({tower.Rarity})", InstanceId = tower.InstanceId, ComponentSlotType = TowerCompSlotType.None }); } } if (rawData.Inventory.MuzzleComponents != null) { foreach (var item in rawData.Inventory.MuzzleComponents) { AddItemContext(items, new RepoItemContext { Title = $"[Muzzle] {item.Name} ({item.Rarity})", InstanceId = item.InstanceId, ComponentSlotType = TowerCompSlotType.Muzzle }); } } if (rawData.Inventory.BearingComponents != null) { foreach (var item in rawData.Inventory.BearingComponents) { AddItemContext(items, new RepoItemContext { Title = $"[Bearing] {item.Name} ({item.Rarity})", InstanceId = item.InstanceId, ComponentSlotType = TowerCompSlotType.Bearing }); } } if (rawData.Inventory.BaseComponents != null) { foreach (var item in rawData.Inventory.BaseComponents) { AddItemContext(items, new RepoItemContext { Title = $"[Base] {item.Name} ({item.Rarity})", InstanceId = item.InstanceId, ComponentSlotType = TowerCompSlotType.Base }); } } return new RepoFormContext { CombineAreaContext = new CombineAreaContext(), CompAreaContext = new CompAreaContext { Items = items.ToArray() } }; } private void AddItemContext(List items, RepoItemContext itemContext) { if (itemContext == null) { return; } items.Add(itemContext); _itemContextMap[itemContext.InstanceId] = itemContext; } private void OnRepoItemSelected(object sender, GameEventArgs e) { if (!(e is RepoItemSelectedEventArgs args)) { return; } if (Form == null || !_itemContextMap.TryGetValue(args.ItemId, out RepoItemContext itemContext)) { return; } bool assigned = Form.TryAssignItemToCombineArea(itemContext); if (assigned) { Form.SetRepoItemSelected(args.ItemId, true); } } private void OnCombineSlotClicked(object sender, GameEventArgs e) { if (!(e is CombineSlotClickedEventArgs args)) { return; } if (Form == null) { return; } if (Form.TryClearCombineSlot(args.SlotIndex, out long removedItemId) && removedItemId > 0) { Form.SetRepoItemSelected(removedItemId, false); } } } }