using GeometryTD.CustomEvent; using GeometryTD.Definition; using GameFramework.Event; using UnityGameFramework.Runtime; namespace GeometryTD.UI { public class CombatInfoFormController : UIFormControllerCommonBase { private CombatInfoFormUseCase _useCase; protected override UIFormType UIFormTypeId => UIFormType.CombatInfoForm; protected override void RefreshUI(CombatInfoForm form, CombatInfoFormContext context) { form.RefreshUI(context); } protected override void SubscribeCustomEvents() { GameEntry.Event.Subscribe(CombatPauseEventArgs.EventId, OnCombatPauseButtonClicked); GameEntry.Event.Subscribe(CombatEndEventArgs.EventId, OnCombatEndButtonClicked); GameEntry.Event.Subscribe(CombatDebugFailEventArgs.EventId, OnCombatDebugFailButtonClicked); GameEntry.Event.Subscribe(CombatProcessEventArgs.EventId, OnCombatProcessChanged); GameEntry.Event.Subscribe(CombatCoinChangedEventArgs.EventId, OnCombatCoinChanged); GameEntry.Event.Subscribe(CombatBaseHpChangedEventArgs.EventId, OnCombatBaseHpChanged); GameEntry.Event.Subscribe(CombatEnemyHpRateChangedEventArgs.EventId, OnCombatEnemyHpRateChanged); } protected override void UnsubscribeCustomEvents() { GameEntry.Event.Unsubscribe(CombatPauseEventArgs.EventId, OnCombatPauseButtonClicked); GameEntry.Event.Unsubscribe(CombatEndEventArgs.EventId, OnCombatEndButtonClicked); GameEntry.Event.Unsubscribe(CombatDebugFailEventArgs.EventId, OnCombatDebugFailButtonClicked); GameEntry.Event.Unsubscribe(CombatProcessEventArgs.EventId, OnCombatProcessChanged); GameEntry.Event.Unsubscribe(CombatCoinChangedEventArgs.EventId, OnCombatCoinChanged); GameEntry.Event.Unsubscribe(CombatBaseHpChangedEventArgs.EventId, OnCombatBaseHpChanged); GameEntry.Event.Unsubscribe(CombatEnemyHpRateChangedEventArgs.EventId, OnCombatEnemyHpRateChanged); } public int? OpenUI(CombatInfoFormRawData rawData) { CombatInfoFormContext context = BuildContext(rawData); return OpenUIInternal(context); } public override int? OpenUI(object userData = null) { if (userData is CombatInfoFormContext context) { return OpenUIInternal(context); } if (userData is CombatInfoFormRawData rawDataFromUserData) { return OpenUI(rawDataFromUserData); } if (userData != null) { Log.Warning("CombatInfoFormController.OpenUI() userData type is invalid."); return null; } if (_useCase == null) { Log.Error("CombatInfoFormController.OpenUI() useCase is null."); return null; } CombatInfoFormRawData rawData = _useCase.CreateInitialModel(); return OpenUI(rawData); } public override void BindUseCase(IUIUseCase useCase) { if (!(useCase is CombatInfoFormUseCase combatInfoFormUseCase)) { Log.Error("CombatInfoFormController.BindUseCase() useCase is invalid."); return; } _useCase = combatInfoFormUseCase; } private static CombatInfoFormContext BuildContext(CombatInfoFormRawData rawData) { if (rawData == null) { return null; } return new CombatInfoFormContext { LevelMetaText = BuildLevelMetaText(rawData.LevelThemeType, rawData.LevelId), LevelPhaseText = BuildPhaseText(rawData.CurrentPhaseIndex, rawData.TotalPhaseCount), CoinText = BuildCoinText(rawData.Coin), BaseHpText = BuildBaseHpText(rawData.BaseHp, rawData.BaseHpMax), EnemyHpRateText = BuildEnemyHpRateText(rawData.EnemyHpRateMultiplier), CanPause = rawData.CanPause, CanEnd = rawData.CanEnd }; } private static string BuildLevelMetaText(LevelThemeType themeType, int levelId) { if (levelId <= 0) { return "Map -"; } return $"{themeType} Map.{levelId}"; } private static string BuildPhaseText(int currentPhaseIndex, int totalPhaseCount) { int phaseIndex = currentPhaseIndex < 0 ? 0 : currentPhaseIndex; if (totalPhaseCount <= 0) { return $"{phaseIndex}/?"; } return $"Wave: {phaseIndex}/{totalPhaseCount}"; } private static string BuildCoinText(int coin) { if (coin < 0) { return "Coin: -"; } return $"Coin: {coin}"; } private static string BuildBaseHpText(int baseHp, int baseHpMax) { if (baseHpMax <= 0) { return "\u57FA\u5730\uFF1A-"; } int clampedHp = UnityEngine.Mathf.Clamp(baseHp, 0, baseHpMax); int percent = UnityEngine.Mathf.RoundToInt((float)clampedHp / baseHpMax * 100f); return $"\u57FA\u5730\uFF1A{percent}%"; } private static string BuildEnemyHpRateText(int enemyHpRateMultiplier) { int resolvedMultiplier = enemyHpRateMultiplier > 0 ? enemyHpRateMultiplier : 1; return $"\u96BE\u5EA6\uFF1A{resolvedMultiplier}x"; } private void OnCombatPauseButtonClicked(object sender, GameEventArgs e) { if (!(sender is CombatInfoForm) || !(e is CombatPauseEventArgs)) { return; } GameEntry.UIRouter.OpenUI(UIFormType.DialogForm, new DialogFormRawData { Mode = 1, Title = "Pause", Message = "Game paused.", PauseGame = true, ConfirmText = "Continue" }); } private void OnCombatEndButtonClicked(object sender, GameEventArgs e) { if (!(sender is CombatInfoForm) || !(e is CombatEndEventArgs)) { return; } _useCase?.TryEndCombat(); } private void OnCombatDebugFailButtonClicked(object sender, GameEventArgs e) { if (!(sender is CombatInfoForm) || !(e is CombatDebugFailEventArgs)) { return; } _useCase?.TryDebugFail(); } private void OnCombatProcessChanged(object sender, GameEventArgs e) { if (!(e is CombatProcessEventArgs)) { return; } RefreshFromUseCase(); } private void OnCombatCoinChanged(object sender, GameEventArgs e) { if (!(e is CombatCoinChangedEventArgs)) { return; } RefreshFromUseCase(); } private void OnCombatBaseHpChanged(object sender, GameEventArgs e) { if (!(e is CombatBaseHpChangedEventArgs)) { return; } RefreshFromUseCase(); } private void OnCombatEnemyHpRateChanged(object sender, GameEventArgs e) { if (!(e is CombatEnemyHpRateChangedEventArgs)) { return; } RefreshFromUseCase(); } private void RefreshFromUseCase() { if (_useCase == null) { return; } CombatInfoFormRawData rawData = _useCase.TryRefresh(); CombatInfoFormContext context = BuildContext(rawData); if (context == null) { return; } SetContext(context); RefreshCurrentUI(); } } }