using GameFramework.Event; using GeometryTD.CustomEvent; using GeometryTD.Definition; using UnityEngine; using UnityGameFramework.Runtime; namespace GeometryTD.UI { public class CombatSelectFormController : UIFormControllerCommonBase { private CombatSelectFormUseCase _useCase; protected override UIFormType UIFormTypeId => UIFormType.CombatSelectForm; protected override void RefreshUI(CombatSelectForm form, CombatSelectFormContext context) { form.RefreshUI(context); } protected override void SubscribeCustomEvents() { GameEntry.Event.Subscribe(CombatSelectItemClickEventArgs.EventId, OnSelectItemClicked); GameEntry.Event.Subscribe(CombatCoinChangedEventArgs.EventId, OnCombatCoinChanged); } protected override void UnsubscribeCustomEvents() { GameEntry.Event.Unsubscribe(CombatSelectItemClickEventArgs.EventId, OnSelectItemClicked); GameEntry.Event.Unsubscribe(CombatCoinChangedEventArgs.EventId, OnCombatCoinChanged); } public int? OpenUI(CombatSelectFormRawData rawData) { CombatSelectFormContext context = BuildContext(rawData); if (context == null || !context.IsVisible) { CloseUI(); return null; } return OpenUIInternal(context); } public override int? OpenUI(object userData = null) { if (userData is CombatSelectFormUserData clickUserData) { return OpenUI(clickUserData); } if (userData is CombatSelectFormContext context) { if (context == null || !context.IsVisible) { CloseUI(); return null; } return OpenUIInternal(context); } if (userData is CombatSelectFormRawData rawDataFromUserData) { return OpenUI(rawDataFromUserData); } if (userData != null) { Log.Warning("CombatSelectFormController.OpenUI() userData type is invalid."); return null; } if (_useCase == null) { Log.Error("CombatSelectFormController.OpenUI() useCase is null."); return null; } CombatSelectFormRawData rawData = _useCase.CreateInitialModel(); return OpenUI(rawData); } public int? OpenUI(CombatSelectFormUserData userData) { if (_useCase == null) { Log.Error("CombatSelectFormController.OpenUI() useCase is null."); return null; } if (userData == null) { _useCase.Hide(); CloseUI(); return null; } switch (userData.ClickObjectType) { case CombatSelectClickObjectType.Foundation: _useCase.SetUpgradeVisible(true); _useCase.ShowForFoundation(userData.ScreenPosition); break; case CombatSelectClickObjectType.Tower: _useCase.SetUpgradePrice(userData.UpgradeCost); _useCase.SetUpgradeVisible(!userData.IsTowerAtMaxLevel); _useCase.SetDestroyGain(userData.DestroyGain); _useCase.ShowForTower(userData.ScreenPosition); break; default: _useCase.Hide(); CloseUI(); return null; } return OpenUI(_useCase.TryRefresh()); } public override void BindUseCase(IUIUseCase useCase) { if (!(useCase is CombatSelectFormUseCase combatSelectFormUseCase)) { Log.Error("CombatSelectFormController.BindUseCase() useCase is invalid."); return; } _useCase = combatSelectFormUseCase; } public int? ShowForFoundation(Vector2 screenPosition) { if (_useCase == null) { Log.Error("CombatSelectFormController.ShowForFoundation() useCase is null."); return null; } _useCase.SetUpgradeVisible(true); _useCase.ShowForFoundation(screenPosition); return OpenUI(_useCase.TryRefresh()); } public int? ShowForTower(Vector2 screenPosition, int upgradeCost, int destroyGain) { if (_useCase == null) { Log.Error("CombatSelectFormController.ShowForTower() useCase is null."); return null; } _useCase.SetUpgradePrice(upgradeCost); _useCase.SetUpgradeVisible(true); _useCase.SetDestroyGain(destroyGain); _useCase.ShowForTower(screenPosition); return OpenUI(_useCase.TryRefresh()); } public void HideSelection() { _useCase?.Hide(); CloseUI(); } public void RefreshFromUseCase() { if (_useCase == null) { return; } CombatSelectFormRawData rawData = _useCase.TryRefresh(); CombatSelectFormContext context = BuildContext(rawData); if (context == null || !context.IsVisible) { CloseUI(); return; } SetContext(context); RefreshCurrentUI(); } private static CombatSelectFormContext BuildContext(CombatSelectFormRawData rawData) { if (rawData == null) { return null; } return new CombatSelectFormContext { IsVisible = rawData.IsVisible, ScreenPosition = rawData.ScreenPosition, ShowBuildArea = rawData.IsVisible && rawData.DisplayMode == CombatSelectDisplayMode.Build, ShowFuncArea = rawData.IsVisible && rawData.DisplayMode == CombatSelectDisplayMode.Func, BuildItems = BuildItemContexts(rawData.BuildItems), UpgradeItem = BuildItemContext(rawData.UpgradeItem), DestroyItem = BuildItemContext(rawData.DestroyItem) }; } private static TowerSelectItemContext[] BuildItemContexts(TowerSelectItemRawData[] itemRawData) { if (itemRawData == null || itemRawData.Length <= 0) { return System.Array.Empty(); } TowerSelectItemContext[] contexts = new TowerSelectItemContext[itemRawData.Length]; for (int i = 0; i < itemRawData.Length; i++) { contexts[i] = BuildItemContext(itemRawData[i]); } return contexts; } private static TowerSelectItemContext BuildItemContext(TowerSelectItemRawData rawData) { if (rawData == null) { return null; } return new TowerSelectItemContext { Icon = rawData.Icon, PriceText = BuildPriceText(rawData.Price, rawData.IsGain), IsVisible = rawData.IsVisible, IsInteractable = rawData.IsInteractable, ActionType = rawData.ActionType, ActionIndex = rawData.ActionIndex, TowerIconAreaContext = new TowerIconAreaContext() { BaseColor = rawData.BaseColor, BearingColor = rawData.BearingColor, MuzzleColor = rawData.MuzzleColor } }; } private static string BuildPriceText(int price, bool isGain) { int positivePrice = Mathf.Max(0, price); if (isGain) { return $"+{positivePrice}"; } return positivePrice.ToString(); } private void OnSelectItemClicked(object sender, GameEventArgs e) { if (!(e is CombatSelectItemClickEventArgs args)) { return; } if (_useCase == null) { return; } if (Form != null && sender is Component component) { CombatSelectForm ownerForm = component.GetComponentInParent(); if (ownerForm != Form) { return; } } _useCase.TryExecuteAction(args.ActionType, args.ActionIndex); RefreshFromUseCase(); } private void OnCombatCoinChanged(object sender, GameEventArgs e) { if (!(e is CombatCoinChangedEventArgs)) { return; } if (Form == null) { return; } RefreshFromUseCase(); } } }