- 添加 CombatFailedState 执行路径

- CombatInfoForm 测试异常方法
This commit is contained in:
2026-03-07 18:45:25 +08:00
parent 3badbe9212
commit eb818e6295
12 changed files with 338 additions and 18 deletions
@@ -260,7 +260,8 @@ namespace GeometryTD.CustomComponent
_combatInfoFormUseCase.Configure(
() => BuildCombatInfoFormRawData(scheduler),
() => scheduler != null && scheduler.CanEndCombat && scheduler.TryEndCombatByPlayer());
() => scheduler != null && scheduler.CanEndCombat && scheduler.TryEndCombatByPlayer(),
() => scheduler != null && scheduler.TryDebugFail("Manual debug fail from CombatInfoForm."));
int? serialId = GameEntry.UIRouter.OpenUI(UIFormType.CombatInfoForm);
if (!serialId.HasValue)
@@ -233,6 +233,19 @@ namespace GeometryTD.CustomComponent
return _combatInRunResourceManager.TryGetBuildTowerStats(buildIndex, out stats);
}
public bool TryDebugFail(string errorMessage)
{
if (_isCompleted || _currentState == null || _currentState is CombatFailedState)
{
return false;
}
EnterFailureFallback(string.IsNullOrWhiteSpace(errorMessage)
? "Manual debug fail."
: errorMessage);
return _currentState is CombatFailedState;
}
private void ResetRuntime()
{
_currentState = null;
@@ -266,6 +279,20 @@ namespace GeometryTD.CustomComponent
GameEntry.UIRouter.BindUIUseCase(UIFormType.RewardSelectForm, _rewardSelectFormUseCase);
}
private void OpenCombatFailureDialog(string errorMessage)
{
CloseDialogForm();
GameEntry.UIRouter.OpenUI(UIFormType.DialogForm, new DialogFormRawData
{
Mode = 1,
Title = "Combat Error",
Message = string.IsNullOrWhiteSpace(errorMessage) ? "Combat failed unexpectedly." : errorMessage,
PauseGame = false,
ConfirmText = "Return Menu",
OnClickConfirm = OnCombatFailureDialogConfirmed
});
}
private void ChangeState(CombatStateBase nextState)
{
if (ReferenceEquals(_currentState, nextState))
@@ -387,6 +414,11 @@ namespace GeometryTD.CustomComponent
GameEntry.UIRouter.CloseUI(UIFormType.RewardSelectForm);
}
private void CloseDialogForm()
{
GameEntry.UIRouter.CloseUI(UIFormType.DialogForm);
}
private void CompleteCombat(bool succeeded)
{
_isCompleted = true;
@@ -401,6 +433,16 @@ namespace GeometryTD.CustomComponent
GameEntry.Event.Fire(this, NodeCompleteEventArgs.Create());
}
private void CompleteFailureCombatAndNotify()
{
CleanupAllCombatEntities();
CloseCombatFinishForm();
CloseRewardSelectForm();
CloseDialogForm();
CompleteCombat(false);
GameEntry.Event.Fire(this, CombatFailureReturnEventArgs.Create());
}
private bool HandleStartFailure(string errorMessage)
{
Log.Warning("{0}", errorMessage);
@@ -419,7 +461,7 @@ namespace GeometryTD.CustomComponent
return;
}
ChangeState(new CombatFailedState(this, errorMessage, true));
ChangeState(new CombatFailedState(this, errorMessage));
}
private static int ResolveEnemyHpRateMultiplier(int displayPhaseIndex, int phaseCount)
@@ -438,6 +480,17 @@ namespace GeometryTD.CustomComponent
return 1 << completedLoopCount;
}
private void OnCombatFailureDialogConfirmed(object userData)
{
_ = userData;
if (_currentState is not CombatFailedState || _isCompleted)
{
return;
}
CompleteFailureCombatAndNotify();
}
#region Event Handlers
private void OnShowEntitySuccess(ShowEntitySuccessEventArgs args)
@@ -501,10 +554,5 @@ namespace GeometryTD.CustomComponent
#endregion
private void GameOverByFailure()
{
CompleteCombat(false);
}
}
}
@@ -7,12 +7,10 @@ namespace GeometryTD.CustomComponent
private sealed class CombatFailedState : CombatStateBase
{
private readonly string _errorMessage;
private readonly bool _notifyCombatNode;
public CombatFailedState(CombatScheduler scheduler, string errorMessage, bool notifyCombatNode) : base(scheduler)
public CombatFailedState(CombatScheduler scheduler, string errorMessage) : base(scheduler)
{
_errorMessage = errorMessage;
_notifyCombatNode = notifyCombatNode;
}
public override void OnEnter()
@@ -22,13 +20,14 @@ namespace GeometryTD.CustomComponent
Scheduler._currentLevel != null ? Scheduler._currentLevel.Id : 0,
_errorMessage);
Scheduler._enemyManager.EndPhase();
Scheduler.CleanupAllCombatEntities();
Scheduler.CloseCombatFinishForm();
Scheduler.CloseRewardSelectForm();
if (_notifyCombatNode)
{
Scheduler.GameOverByFailure();
}
Scheduler.OpenCombatFailureDialog(_errorMessage);
}
public override void OnExit()
{
Scheduler.CloseDialogForm();
}
}
}