From 548bc77ba634d243459a79c9bc3b4bf3cc9b0a33 Mon Sep 17 00:00:00 2001 From: SepComet <202308010230@stu.csust.edu.cn> Date: Sun, 8 Mar 2026 17:00:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=84=E8=8C=83=E7=B1=BB=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CombatScheduler/CombatLoadSession.cs | 28 +-- ...ceManager.cs => CombatRunResourceStore.cs} | 2 +- ...cs.meta => CombatRunResourceStore.cs.meta} | 0 .../CombatScheduler/CombatScheduler.cs | 206 +++++++++--------- ...nator.cs => CombatSchedulerCoordinator.cs} | 122 +++++------ ...eta => CombatSchedulerCoordinator.cs.meta} | 0 ...meContext.cs => CombatSchedulerRuntime.cs} | 6 +- ...cs.meta => CombatSchedulerRuntime.cs.meta} | 0 .../CombatSettlementContext.cs | 4 +- ...wService.cs => CombatSettlementService.cs} | 42 ++-- ...s.meta => CombatSettlementService.cs.meta} | 0 .../CombatStates/CombatFailedState.cs | 18 +- .../CombatStates/CombatFinishFormState.cs | 18 +- .../CombatStates/CombatLoadingState.cs | 32 +-- .../CombatRewardSelectionState.cs | 30 +-- .../CombatStates/CombatRunningPhaseState.cs | 56 ++--- .../CombatStates/CombatSettlementState.cs | 26 +-- .../CombatStates/CombatStateBase.cs | 10 +- .../CombatWaitingForPhaseEndState.cs | 24 +- .../CombatWaitingForReturnState.cs | 18 +- ...pResolveContext.cs => EnemyDropContext.cs} | 4 +- ...ntext.cs.meta => EnemyDropContext.cs.meta} | 0 .../EnemyDrop/EnemyDropResolver.cs | 6 +- ...ropResolveResult.cs => EnemyDropResult.cs} | 6 +- ...Result.cs.meta => EnemyDropResult.cs.meta} | 0 ...hedulerHost.cs => ICombatSchedulerPort.cs} | 2 +- ...t.cs.meta => ICombatSchedulerPort.cs.meta} | 0 ...onfigService.cs => EnemyConfigProvider.cs} | 8 +- ...ce.cs.meta => EnemyConfigProvider.cs.meta} | 0 .../CombatNode/EnemyManager/EnemyManager.cs | 22 +- ...rResolver.cs => EnemySpawnPathResolver.cs} | 2 +- ...cs.meta => EnemySpawnPathResolver.cs.meta} | 0 .../Combat/UseCase/CombatFinishFormUseCase.cs | 8 +- docs/CodeX-TODO.md | 40 ++-- docs/CombatNodeArchitecture.md | 61 ++++-- 35 files changed, 417 insertions(+), 384 deletions(-) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatInRunResourceManager.cs => CombatRunResourceStore.cs} (99%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatInRunResourceManager.cs.meta => CombatRunResourceStore.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatSchedulerFlowCoordinator.cs => CombatSchedulerCoordinator.cs} (57%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatSchedulerFlowCoordinator.cs.meta => CombatSchedulerCoordinator.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatSchedulerRuntimeContext.cs => CombatSchedulerRuntime.cs} (86%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatSchedulerRuntimeContext.cs.meta => CombatSchedulerRuntime.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatSettlementFlowService.cs => CombatSettlementService.cs} (89%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{CombatSettlementFlowService.cs.meta => CombatSettlementService.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/{EnemyDropResolveContext.cs => EnemyDropContext.cs} (70%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/{EnemyDropResolveContext.cs.meta => EnemyDropContext.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/{EnemyDropResolveResult.cs => EnemyDropResult.cs} (59%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/{EnemyDropResolveResult.cs.meta => EnemyDropResult.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{ICombatSchedulerHost.cs => ICombatSchedulerPort.cs} (91%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/{ICombatSchedulerHost.cs.meta => ICombatSchedulerPort.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/{EnemyConfigService.cs => EnemyConfigProvider.cs} (92%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/{EnemyConfigService.cs.meta => EnemyConfigProvider.cs.meta} (100%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/{SpawnerResolver.cs => EnemySpawnPathResolver.cs} (98%) rename Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/{SpawnerResolver.cs.meta => EnemySpawnPathResolver.cs.meta} (100%) diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatLoadSession.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatLoadSession.cs index bc3eb7d..7d3dc7b 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatLoadSession.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatLoadSession.cs @@ -45,7 +45,7 @@ namespace GeometryTD.CustomComponent _currentMap = null; } - public bool StartLoading(DRLevel level, MapEntityLoadContext mapLoadContext, ICombatSchedulerHost schedulerHost, out string errorMessage) + public bool StartLoading(DRLevel level, MapEntityLoadContext mapLoadContext, ICombatSchedulerPort schedulerPort, out string errorMessage) { errorMessage = null; if (_entity == null) @@ -59,7 +59,7 @@ namespace GeometryTD.CustomComponent return false; } - if (!TryOpenCombatInfoForm(schedulerHost, out errorMessage)) + if (!TryOpenCombatInfoForm(schedulerPort, out errorMessage)) { return false; } @@ -257,7 +257,7 @@ namespace GeometryTD.CustomComponent return true; } - private bool TryOpenCombatInfoForm(ICombatSchedulerHost schedulerHost, out string errorMessage) + private bool TryOpenCombatInfoForm(ICombatSchedulerPort schedulerPort, out string errorMessage) { errorMessage = null; if (_combatInfoFormUseCase == null) @@ -267,9 +267,9 @@ namespace GeometryTD.CustomComponent } _combatInfoFormUseCase.Configure( - () => BuildCombatInfoFormRawData(schedulerHost), - () => schedulerHost != null && schedulerHost.CanEndCombat && schedulerHost.TryEndCombatByPlayer(), - () => schedulerHost != null && schedulerHost.TryDebugFail("Manual debug fail from CombatInfoForm.")); + () => BuildCombatInfoFormRawData(schedulerPort), + () => schedulerPort != null && schedulerPort.CanEndCombat && schedulerPort.TryEndCombatByPlayer(), + () => schedulerPort != null && schedulerPort.TryDebugFail("Manual debug fail from CombatInfoForm.")); int? serialId = GameEntry.UIRouter.OpenUI(UIFormType.CombatInfoForm); if (!serialId.HasValue) @@ -283,26 +283,26 @@ namespace GeometryTD.CustomComponent return true; } - private static CombatInfoFormRawData BuildCombatInfoFormRawData(ICombatSchedulerHost schedulerHost) + private static CombatInfoFormRawData BuildCombatInfoFormRawData(ICombatSchedulerPort schedulerPort) { - if (schedulerHost == null) + if (schedulerPort == null) { return null; } - DRLevel level = schedulerHost.CurrentLevel; + DRLevel level = schedulerPort.CurrentLevel; LevelThemeType themeType = level != null ? level.LevelThemeType : LevelThemeType.None; int levelId = level != null ? level.Id : 0; int baseHpMax = level != null ? Mathf.Max(0, level.BaseHp) : 0; return CombatInfoFormUseCase.BuildRawData( themeType, levelId, - schedulerHost.DisplayPhaseIndex, - schedulerHost.PhaseCount, - schedulerHost.CurrentCoin, - schedulerHost.CurrentBaseHp, + schedulerPort.DisplayPhaseIndex, + schedulerPort.PhaseCount, + schedulerPort.CurrentCoin, + schedulerPort.CurrentBaseHp, baseHpMax, - schedulerHost.CanEndCombat); + schedulerPort.CanEndCombat); } private void CloseCombatInfoForm() diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs similarity index 99% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs index 568d457..b86db61 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs @@ -7,7 +7,7 @@ using UnityEngine; namespace GeometryTD.CustomComponent { - internal sealed class CombatInRunResourceManager + internal sealed class CombatRunResourceStore { private readonly List _buildTowerStatsSnapshot = new(); private readonly List _participantTowerSnapshot = new(); diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs index 1b992c2..ffbe01f 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatScheduler.cs @@ -11,58 +11,58 @@ using UnityGameFramework.Runtime; namespace GeometryTD.CustomComponent { - public partial class CombatScheduler : ICombatSchedulerHost + public partial class CombatScheduler : ICombatSchedulerPort { - private readonly CombatSchedulerRuntimeContext _context = new(); - private readonly CombatSchedulerFlowCoordinator _flowCoordinator; + private readonly CombatSchedulerRuntime _runtime = new(); + private readonly CombatSchedulerCoordinator _coordinator; private bool _initialized; public CombatScheduler() { - _flowCoordinator = new CombatSchedulerFlowCoordinator(this, _context); + _coordinator = new CombatSchedulerCoordinator(this, _runtime); } public bool IsRunning => - _context.CurrentState is CombatLoadingState or CombatRunningPhaseState or CombatWaitingForPhaseEndState; + _runtime.CurrentState is CombatLoadingState or CombatRunningPhaseState or CombatWaitingForPhaseEndState; - public bool IsCompleted => _context.IsCompleted; - public DRLevel CurrentLevel => _context.CurrentLevel; - public DRLevelPhase CurrentPhase => _context.PhaseLoopRuntime.CurrentPhase; - public MapEntity CurrentMap => _context.LoadSession.CurrentMap; - public int DisplayPhaseIndex => _context.PhaseLoopRuntime.DisplayPhaseIndex; - public int PhaseCount => _context.PhaseLoopRuntime.PhaseCount; - public bool CanEndCombat => _context.PhaseLoopRuntime.CanEndCombat; - public int CurrentCoin => _context.CombatInRunResourceManager.CurrentCoin; - public int CurrentGold => _context.CombatInRunResourceManager.CurrentGold; - public int CurrentBaseHp => _context.CombatInRunResourceManager.CurrentBaseHp; - public int CurrentBuildTowerCount => _context.CombatInRunResourceManager.CurrentBuildTowerCount; - public int DefeatedEnemyCount => _context.EnemyManager.DefeatedEnemyCount; - public int GainedCoin => _context.CombatInRunResourceManager.GainedCoin; - public int GainedGold => _context.CombatInRunResourceManager.GainedGold; + public bool IsCompleted => _runtime.IsCompleted; + public DRLevel CurrentLevel => _runtime.CurrentLevel; + public DRLevelPhase CurrentPhase => _runtime.PhaseLoopRuntime.CurrentPhase; + public MapEntity CurrentMap => _runtime.LoadSession.CurrentMap; + public int DisplayPhaseIndex => _runtime.PhaseLoopRuntime.DisplayPhaseIndex; + public int PhaseCount => _runtime.PhaseLoopRuntime.PhaseCount; + public bool CanEndCombat => _runtime.PhaseLoopRuntime.CanEndCombat; + public int CurrentCoin => _runtime.CombatRunResourceStore.CurrentCoin; + public int CurrentGold => _runtime.CombatRunResourceStore.CurrentGold; + public int CurrentBaseHp => _runtime.CombatRunResourceStore.CurrentBaseHp; + public int CurrentBuildTowerCount => _runtime.CombatRunResourceStore.CurrentBuildTowerCount; + public int DefeatedEnemyCount => _runtime.EnemyManager.DefeatedEnemyCount; + public int GainedCoin => _runtime.CombatRunResourceStore.GainedCoin; + public int GainedGold => _runtime.CombatRunResourceStore.GainedGold; public void OnInit(Action combatEndedCallback) { - _context.CombatEndedCallback = combatEndedCallback; + _runtime.CombatEndedCallback = combatEndedCallback; if (!_initialized) { - _context.Entity = GameEntry.Entity; - _context.EventBridge.Bind( + _runtime.Entity = GameEntry.Entity; + _runtime.EventBridge.Bind( OnShowEntitySuccess, OnShowEntityFailure, OnHideEntityComplete, OnOpenUIFormSuccess, OnOpenUIFormFailure, OnCloseUIFormComplete); - _context.EnemyManager.OnInit(this); - _context.LoadSession.OnInit(_context.Entity); - _flowCoordinator.EnsureCombatFinishFormUseCaseBound(); - _flowCoordinator.EnsureRewardSelectFormUseCaseBound(); + _runtime.EnemyManager.OnInit(this); + _runtime.LoadSession.OnInit(_runtime.Entity); + _coordinator.EnsureCombatFinishFormUseCaseBound(); + _coordinator.EnsureRewardSelectFormUseCaseBound(); _initialized = true; } - _flowCoordinator.ResetRuntime(); + _coordinator.ResetRuntime(); } public bool Start( @@ -74,37 +74,37 @@ namespace GeometryTD.CustomComponent RunNodeType nodeType = RunNodeType.None, int sequenceIndex = -1) { - if (!_initialized || _context.Entity == null) + if (!_initialized || _runtime.Entity == null) { - return _flowCoordinator.HandleStartFailure("CombatScheduler start failed. Runtime is not initialized."); + return _coordinator.HandleStartFailure("CombatScheduler start failed. Runtime is not initialized."); } if (level == null || phases == null || phases.Count <= 0) { - return _flowCoordinator.HandleStartFailure("CombatScheduler start failed. Invalid level or phase data."); + return _coordinator.HandleStartFailure("CombatScheduler start failed. Invalid level or phase data."); } - _flowCoordinator.CleanupAllCombatEntities(); - _flowCoordinator.CloseCombatFinishForm(); - _flowCoordinator.CloseRewardSelectForm(); - _flowCoordinator.CloseDialogForm(); - _context.EnemyManager.EndPhase(); - _context.EnemyManager.ResetCombatStats(); - _flowCoordinator.ResetRuntime(); - _context.IsFinishAsVictory = true; + _coordinator.CleanupAllCombatEntities(); + _coordinator.CloseCombatFinishForm(); + _coordinator.CloseRewardSelectForm(); + _coordinator.CloseDialogForm(); + _runtime.EnemyManager.EndPhase(); + _runtime.EnemyManager.ResetCombatStats(); + _coordinator.ResetRuntime(); + _runtime.IsFinishAsVictory = true; - _context.CurrentLevel = level; - _context.RunId = runId; - _context.NodeId = nodeId; - _context.NodeType = nodeType; - _context.SequenceIndex = sequenceIndex; - _context.CombatInRunResourceManager.InitializeForCombat(level); + _runtime.CurrentLevel = level; + _runtime.RunId = runId; + _runtime.NodeId = nodeId; + _runtime.NodeType = nodeType; + _runtime.SequenceIndex = sequenceIndex; + _runtime.CombatRunResourceStore.InitializeForCombat(level); for (int i = 0; i < phases.Count; i++) { DRLevelPhase phase = phases[i]; if (phase != null) { - _context.PhaseBuffer.Add(phase); + _runtime.PhaseBuffer.Add(phase); } } @@ -112,27 +112,27 @@ namespace GeometryTD.CustomComponent { foreach (var pair in spawnEntriesByPhaseId) { - _context.SpawnEntriesByPhaseId[pair.Key] = pair.Value; + _runtime.SpawnEntriesByPhaseId[pair.Key] = pair.Value; } } - _context.PhaseLoopRuntime.SetPhases(_context.PhaseBuffer); - if (_context.PhaseLoopRuntime.PhaseCount <= 0) + _runtime.PhaseLoopRuntime.SetPhases(_runtime.PhaseBuffer); + if (_runtime.PhaseLoopRuntime.PhaseCount <= 0) { - return _flowCoordinator.HandleStartFailure($"CombatScheduler start failed. Level '{level.Id}' has no phase data."); + return _coordinator.HandleStartFailure($"CombatScheduler start failed. Level '{level.Id}' has no phase data."); } - ChangeState(new CombatLoadingState(_context, _flowCoordinator)); + ChangeState(new CombatLoadingState(_runtime, _coordinator)); Log.Info( "CombatScheduler started. Level={0}, PhaseCount={1}.", - _context.CurrentLevel.Id, - _context.PhaseLoopRuntime.PhaseCount); + _runtime.CurrentLevel.Id, + _runtime.PhaseLoopRuntime.PhaseCount); return true; } public void OnUpdate(float elapseSeconds, float realElapseSeconds) { - _context.CurrentState?.OnUpdate(elapseSeconds, realElapseSeconds); + _runtime.CurrentState?.OnUpdate(elapseSeconds, realElapseSeconds); } public void OnDestroy() @@ -142,33 +142,33 @@ namespace GeometryTD.CustomComponent return; } - _context.CurrentState?.OnExit(); - _context.CurrentState?.OnDestroy(); - _context.CurrentState = null; - _flowCoordinator.CleanupAllCombatEntities(); - _flowCoordinator.CloseCombatFinishForm(); - _flowCoordinator.CloseRewardSelectForm(); - _flowCoordinator.CloseDialogForm(); - _context.EnemyManager.OnDestroy(); - _flowCoordinator.ResetRuntime(); - _context.EventBridge.Unbind(); - _context.CombatFinishFormUseCase = null; - _context.RewardSelectFormUseCase = null; - _context.CombatEndedCallback = null; + _runtime.CurrentState?.OnExit(); + _runtime.CurrentState?.OnDestroy(); + _runtime.CurrentState = null; + _coordinator.CleanupAllCombatEntities(); + _coordinator.CloseCombatFinishForm(); + _coordinator.CloseRewardSelectForm(); + _coordinator.CloseDialogForm(); + _runtime.EnemyManager.OnDestroy(); + _coordinator.ResetRuntime(); + _runtime.EventBridge.Unbind(); + _runtime.CombatFinishFormUseCase = null; + _runtime.RewardSelectFormUseCase = null; + _runtime.CombatEndedCallback = null; - _context.Entity = null; + _runtime.Entity = null; _initialized = false; } public bool TryEndCombatByPlayer() { - if (_context.CurrentState is not CombatRunningPhaseState && - _context.CurrentState is not CombatWaitingForPhaseEndState) + if (_runtime.CurrentState is not CombatRunningPhaseState && + _runtime.CurrentState is not CombatWaitingForPhaseEndState) { return false; } - return _context.PhaseLoopRuntime.TryRequestEndCombat(); + return _runtime.PhaseLoopRuntime.TryRequestEndCombat(); } public void OnEnemyReachedBase(DREnemy enemy) @@ -184,7 +184,7 @@ namespace GeometryTD.CustomComponent return; } - _flowCoordinator.ApplyBaseDamage(resolvedBaseDamage); + _coordinator.ApplyBaseDamage(resolvedBaseDamage); } public void OnEnemyDefeated(DREnemy enemy) @@ -194,18 +194,18 @@ namespace GeometryTD.CustomComponent return; } - EnemyDropResolveContext context = new( + EnemyDropContext context = new( enemy, - _context.PhaseLoopRuntime.DisplayPhaseIndex, - _flowCoordinator.ResolveCurrentThemeType()); - EnemyDropResolveResult result = _context.EnemyDropResolver.Resolve(context); - _context.CombatInRunResourceManager.AddEnemyDefeatedReward(result.Coin, result.Gold); - _context.CombatInRunResourceManager.AddEnemyDefeatedLoot(result.LootItem); + _runtime.PhaseLoopRuntime.DisplayPhaseIndex, + _coordinator.ResolveCurrentThemeType()); + EnemyDropResult result = _runtime.EnemyDropResolver.Resolve(context); + _runtime.CombatRunResourceStore.AddEnemyDefeatedReward(result.Coin, result.Gold); + _runtime.CombatRunResourceStore.AddEnemyDefeatedLoot(result.LootItem); } public bool OnCombatFinishReturnRequested() { - if (_context.CurrentState is not CombatWaitingForReturnState waitingForReturnState) + if (_runtime.CurrentState is not CombatWaitingForReturnState waitingForReturnState) { return false; } @@ -216,68 +216,68 @@ namespace GeometryTD.CustomComponent public bool TryConsumeCoin(int coin) { - return _context.CombatInRunResourceManager.TryConsumeCoin(coin); + return _runtime.CombatRunResourceStore.TryConsumeCoin(coin); } public void AddCoin(int coin) { - _context.CombatInRunResourceManager.AddCoin(coin); + _runtime.CombatRunResourceStore.AddCoin(coin); } public bool TryGetBuildTowerStats(int buildIndex, out TowerStatsData stats) { - return _context.CombatInRunResourceManager.TryGetBuildTowerStats(buildIndex, out stats); + return _runtime.CombatRunResourceStore.TryGetBuildTowerStats(buildIndex, out stats); } public bool TryDebugFail(string errorMessage) { - if (_context.IsCompleted || _context.CurrentState == null || _context.CurrentState is CombatFailedState) + if (_runtime.IsCompleted || _runtime.CurrentState == null || _runtime.CurrentState is CombatFailedState) { return false; } - _flowCoordinator.EnterFailureFallback(string.IsNullOrWhiteSpace(errorMessage) + _coordinator.EnterFailureFallback(string.IsNullOrWhiteSpace(errorMessage) ? "Manual debug fail." : errorMessage); - return _context.CurrentState is CombatFailedState; + return _runtime.CurrentState is CombatFailedState; } - void ICombatSchedulerHost.ChangeState(CombatStateBase nextState) + void ICombatSchedulerPort.ChangeState(CombatStateBase nextState) { ChangeState(nextState); } internal void ChangeState(CombatStateBase nextState) { - if (ReferenceEquals(_context.CurrentState, nextState)) + if (ReferenceEquals(_runtime.CurrentState, nextState)) { return; } - _context.CurrentState?.OnExit(); - _context.CurrentState?.OnDestroy(); - _context.CurrentState = nextState; - _context.CurrentState?.OnInit(); - _context.CurrentState?.OnEnter(); + _runtime.CurrentState?.OnExit(); + _runtime.CurrentState?.OnDestroy(); + _runtime.CurrentState = nextState; + _runtime.CurrentState?.OnInit(); + _runtime.CurrentState?.OnEnter(); } #region Event Handlers private void OnShowEntitySuccess(ShowEntitySuccessEventArgs args) { - var status = _context.LoadSession.HandleShowEntitySuccess(args, out string errorMessage); + var status = _runtime.LoadSession.HandleShowEntitySuccess(args, out string errorMessage); if (status == CombatLoadSession.EventHandleStatus.Failed) { - _flowCoordinator.EnterFailureFallback(errorMessage); + _coordinator.EnterFailureFallback(errorMessage); return; } if (status == CombatLoadSession.EventHandleStatus.Succeeded) { - MapEntity map = _context.LoadSession.CurrentMap; + MapEntity map = _runtime.LoadSession.CurrentMap; Log.Info( "Map ready. LevelId={0}, PathCells={1}, FoundationCells={2}, Spawners={3}, House={4}.", - _context.CurrentLevel != null ? _context.CurrentLevel.Id : 0, + _runtime.CurrentLevel != null ? _runtime.CurrentLevel.Id : 0, map.PathCells.Count, map.FoundationCells.Count, map.Spawners.Length, @@ -287,39 +287,39 @@ namespace GeometryTD.CustomComponent private void OnShowEntityFailure(ShowEntityFailureEventArgs args) { - var status = _context.LoadSession.HandleShowEntityFailure(args, out string errorMessage); + var status = _runtime.LoadSession.HandleShowEntityFailure(args, out string errorMessage); if (status == CombatLoadSession.EventHandleStatus.Failed) { - _flowCoordinator.EnterFailureFallback(errorMessage); + _coordinator.EnterFailureFallback(errorMessage); } } private void OnHideEntityComplete(HideEntityCompleteEventArgs args) { - _context.LoadSession.HandleHideEntityComplete(args); + _runtime.LoadSession.HandleHideEntityComplete(args); } private void OnOpenUIFormSuccess(OpenUIFormSuccessEventArgs args) { - var status = _context.LoadSession.HandleOpenUIFormSuccess(args, out string errorMessage); + var status = _runtime.LoadSession.HandleOpenUIFormSuccess(args, out string errorMessage); if (status == CombatLoadSession.EventHandleStatus.Failed) { - _flowCoordinator.EnterFailureFallback(errorMessage); + _coordinator.EnterFailureFallback(errorMessage); } } private void OnOpenUIFormFailure(OpenUIFormFailureEventArgs args) { - var status = _context.LoadSession.HandleOpenUIFormFailure(args, out string errorMessage); + var status = _runtime.LoadSession.HandleOpenUIFormFailure(args, out string errorMessage); if (status == CombatLoadSession.EventHandleStatus.Failed) { - _flowCoordinator.EnterFailureFallback(errorMessage); + _coordinator.EnterFailureFallback(errorMessage); } } private void OnCloseUIFormComplete(CloseUIFormCompleteEventArgs args) { - _context.LoadSession.HandleCloseUIFormComplete(args); + _runtime.LoadSession.HandleCloseUIFormComplete(args); } #endregion diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerFlowCoordinator.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerCoordinator.cs similarity index 57% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerFlowCoordinator.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerCoordinator.cs index dcc451b..bf13646 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerFlowCoordinator.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerCoordinator.cs @@ -9,21 +9,21 @@ using UnityGameFramework.Runtime; namespace GeometryTD.CustomComponent { - internal sealed class CombatSchedulerFlowCoordinator + internal sealed class CombatSchedulerCoordinator { - private readonly ICombatSchedulerHost _schedulerHost; - private readonly CombatSchedulerRuntimeContext _context; - public ICombatSchedulerHost Host => _schedulerHost; + private readonly ICombatSchedulerPort _schedulerPort; + private readonly CombatSchedulerRuntime _runtime; + public ICombatSchedulerPort Port => _schedulerPort; - public CombatSchedulerFlowCoordinator(ICombatSchedulerHost schedulerHost, CombatSchedulerRuntimeContext context) + public CombatSchedulerCoordinator(ICombatSchedulerPort schedulerPort, CombatSchedulerRuntime runtime) { - _schedulerHost = schedulerHost; - _context = context; + _schedulerPort = schedulerPort; + _runtime = runtime; } public void ChangeState(CombatStateBase nextState) { - _schedulerHost.ChangeState(nextState); + _schedulerPort.ChangeState(nextState); } public int ResolveEnemyHpRateMultiplier(int displayPhaseIndex, int phaseCount) @@ -44,40 +44,40 @@ namespace GeometryTD.CustomComponent public void ResetRuntime() { - _context.CurrentState = null; - _context.PhaseBuffer.Clear(); - _context.SpawnEntriesByPhaseId.Clear(); - _context.PhaseLoopRuntime.Reset(); - _context.LoadSession.Reset(); - _context.CombatInRunResourceManager.Reset(); - _context.EnemyDropResolver.Reset(); - _context.SettlementContext = null; - _context.CurrentLevel = null; - _context.IsFinishAsVictory = true; - _context.IsCompleted = false; - _context.NodeEnterFired = false; - _context.RunId = null; - _context.NodeId = 0; - _context.NodeType = RunNodeType.None; - _context.SequenceIndex = -1; + _runtime.CurrentState = null; + _runtime.PhaseBuffer.Clear(); + _runtime.SpawnEntriesByPhaseId.Clear(); + _runtime.PhaseLoopRuntime.Reset(); + _runtime.LoadSession.Reset(); + _runtime.CombatRunResourceStore.Reset(); + _runtime.EnemyDropResolver.Reset(); + _runtime.SettlementContext = null; + _runtime.CurrentLevel = null; + _runtime.IsFinishAsVictory = true; + _runtime.IsCompleted = false; + _runtime.NodeEnterFired = false; + _runtime.RunId = null; + _runtime.NodeId = 0; + _runtime.NodeType = RunNodeType.None; + _runtime.SequenceIndex = -1; } public void CleanupAllCombatEntities() { - _context.LoadSession.Cleanup(); - _context.EnemyManager.CleanupTrackedEnemies(); + _runtime.LoadSession.Cleanup(); + _runtime.EnemyManager.CleanupTrackedEnemies(); } public void EnsureCombatFinishFormUseCaseBound() { - _context.CombatFinishFormUseCase ??= new CombatFinishFormUseCase(_schedulerHost); - GameEntry.UIRouter.BindUIUseCase(UIFormType.CombatFinishForm, _context.CombatFinishFormUseCase); + _runtime.CombatFinishFormUseCase ??= new CombatFinishFormUseCase(_schedulerPort); + GameEntry.UIRouter.BindUIUseCase(UIFormType.CombatFinishForm, _runtime.CombatFinishFormUseCase); } public void EnsureRewardSelectFormUseCaseBound() { - _context.RewardSelectFormUseCase ??= new RewardSelectFormUseCase(); - GameEntry.UIRouter.BindUIUseCase(UIFormType.RewardSelectForm, _context.RewardSelectFormUseCase); + _runtime.RewardSelectFormUseCase ??= new RewardSelectFormUseCase(); + GameEntry.UIRouter.BindUIUseCase(UIFormType.RewardSelectForm, _runtime.RewardSelectFormUseCase); } public void OpenCombatFailureDialog(string errorMessage) @@ -96,30 +96,30 @@ namespace GeometryTD.CustomComponent public bool TryBeginNextPhase() { - if (!_context.PhaseLoopRuntime.TryEnterNextPhase(out DRLevelPhase nextPhase)) + if (!_runtime.PhaseLoopRuntime.TryEnterNextPhase(out DRLevelPhase nextPhase)) { - _schedulerHost.ChangeState(new CombatSettlementState(_context, this, true)); + _schedulerPort.ChangeState(new CombatSettlementState(_runtime, this, true)); return false; } - _context.SpawnEntriesByPhaseId.TryGetValue(nextPhase.Id, out IReadOnlyList spawnEntries); - _schedulerHost.ChangeState(new CombatRunningPhaseState(_context, this, nextPhase, spawnEntries)); + _runtime.SpawnEntriesByPhaseId.TryGetValue(nextPhase.Id, out IReadOnlyList spawnEntries); + _schedulerPort.ChangeState(new CombatRunningPhaseState(_runtime, this, nextPhase, spawnEntries)); return true; } public void EnterWaitingForPhaseEnd() { - _schedulerHost.ChangeState(new CombatWaitingForPhaseEndState(_context, this)); + _schedulerPort.ChangeState(new CombatWaitingForPhaseEndState(_runtime, this)); } public void CompleteCurrentPhase() { - _context.EnemyManager.EndPhase(); + _runtime.EnemyManager.EndPhase(); Log.Info( "CombatScheduler phase completed. Level={0}, Phase={1}, Elapsed={2:F2}s.", - _context.CurrentLevel != null ? _context.CurrentLevel.Id : 0, - _context.PhaseLoopRuntime.CurrentPhase != null ? _context.PhaseLoopRuntime.CurrentPhase.Id : 0, - _context.PhaseLoopRuntime.CurrentPhaseElapsed); + _runtime.CurrentLevel != null ? _runtime.CurrentLevel.Id : 0, + _runtime.PhaseLoopRuntime.CurrentPhase != null ? _runtime.PhaseLoopRuntime.CurrentPhase.Id : 0, + _runtime.PhaseLoopRuntime.CurrentPhaseElapsed); TryBeginNextPhase(); } @@ -132,7 +132,7 @@ namespace GeometryTD.CustomComponent return true; } - if (_context.PhaseLoopRuntime.IsEndCombatRequested) + if (_runtime.PhaseLoopRuntime.IsEndCombatRequested) { isVictory = true; return true; @@ -144,30 +144,30 @@ namespace GeometryTD.CustomComponent public void OnFullBaseHpRewardSelected(RewardSelectItemRawData selectedReward) { - if (_context.CurrentState is not CombatRewardSelectionState || _context.SettlementContext == null) + if (_runtime.CurrentState is not CombatRewardSelectionState || _runtime.SettlementContext == null) { return; } - _context.SettlementFlowService.ApplySelectedReward(_context.SettlementContext, selectedReward); - _schedulerHost.ChangeState(new CombatFinishFormState(_context, this)); + _runtime.CombatSettlementService.ApplySelectedReward(_runtime.SettlementContext, selectedReward); + _schedulerPort.ChangeState(new CombatFinishFormState(_runtime, this)); } public void OnFullBaseHpRewardGiveUp() { - if (_context.CurrentState is not CombatRewardSelectionState || _context.SettlementContext == null) + if (_runtime.CurrentState is not CombatRewardSelectionState || _runtime.SettlementContext == null) { return; } - _schedulerHost.ChangeState(new CombatFinishFormState(_context, this)); + _schedulerPort.ChangeState(new CombatFinishFormState(_runtime, this)); } public LevelThemeType ResolveCurrentThemeType() { - if (_context.CurrentLevel != null) + if (_runtime.CurrentLevel != null) { - return _context.CurrentLevel.LevelThemeType; + return _runtime.CurrentLevel.LevelThemeType; } return LevelThemeType.None; @@ -175,12 +175,12 @@ namespace GeometryTD.CustomComponent public int ApplyBaseDamage(int damage) { - return _context.CombatInRunResourceManager.ApplyBaseDamage(damage); + return _runtime.CombatRunResourceStore.ApplyBaseDamage(damage); } public int GetCurrentBaseHp() { - return Mathf.Max(0, _context.CombatInRunResourceManager.CurrentBaseHp); + return Mathf.Max(0, _runtime.CombatRunResourceStore.CurrentBaseHp); } public void CloseCombatFinishForm() @@ -204,10 +204,10 @@ namespace GeometryTD.CustomComponent GameEntry.Event.Fire( this, NodeCompleteEventArgs.Create( - _context.RunId, - _context.NodeId, - _context.NodeType, - _context.SequenceIndex, + _runtime.RunId, + _runtime.NodeId, + _runtime.NodeType, + _runtime.SequenceIndex, succeeded, GameEntry.PlayerInventory != null ? GameEntry.PlayerInventory.GetInventorySnapshot() : null)); } @@ -225,7 +225,7 @@ namespace GeometryTD.CustomComponent public bool HandleStartFailure(string errorMessage) { Log.Warning("{0}", errorMessage); - _context.EnemyManager.EndPhase(); + _runtime.EnemyManager.EndPhase(); CleanupAllCombatEntities(); CloseCombatFinishForm(); CloseRewardSelectForm(); @@ -236,18 +236,18 @@ namespace GeometryTD.CustomComponent public void EnterFailureFallback(string errorMessage) { - if (_context.CurrentState is CombatFailedState || _context.IsCompleted) + if (_runtime.CurrentState is CombatFailedState || _runtime.IsCompleted) { return; } - _schedulerHost.ChangeState(new CombatFailedState(_context, this, errorMessage)); + _schedulerPort.ChangeState(new CombatFailedState(_runtime, this, errorMessage)); } public void OnCombatFailureDialogConfirmed(object userData) { _ = userData; - if (_context.CurrentState is not CombatFailedState || _context.IsCompleted) + if (_runtime.CurrentState is not CombatFailedState || _runtime.IsCompleted) { return; } @@ -257,10 +257,10 @@ namespace GeometryTD.CustomComponent private void CompleteCombat(bool succeeded) { - _context.IsCompleted = true; - _context.CurrentState = null; - _context.CombatInRunResourceManager.MarkCombatEnded(); - _context.CombatEndedCallback?.Invoke(succeeded); + _runtime.IsCompleted = true; + _runtime.CurrentState = null; + _runtime.CombatRunResourceStore.MarkCombatEnded(); + _runtime.CombatEndedCallback?.Invoke(succeeded); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerFlowCoordinator.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerCoordinator.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerFlowCoordinator.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerCoordinator.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntimeContext.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntime.cs similarity index 86% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntimeContext.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntime.cs index bbf451f..b815aee 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntimeContext.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntime.cs @@ -8,7 +8,7 @@ using UnityGameFramework.Runtime; namespace GeometryTD.CustomComponent { - internal sealed class CombatSchedulerRuntimeContext + internal sealed class CombatSchedulerRuntime { public List PhaseBuffer { get; } = new(); public Dictionary> SpawnEntriesByPhaseId { get; } = new(); @@ -16,9 +16,9 @@ namespace GeometryTD.CustomComponent public PhaseLoopRuntime PhaseLoopRuntime { get; } = new(); public CombatLoadSession LoadSession { get; } = new(); public CombatEventBridge EventBridge { get; } = new(); - public CombatInRunResourceManager CombatInRunResourceManager { get; } = new(); + public CombatRunResourceStore CombatRunResourceStore { get; } = new(); public EnemyDropResolver EnemyDropResolver { get; } = new(); - public CombatSettlementFlowService SettlementFlowService { get; } = new(); + public CombatSettlementService CombatSettlementService { get; } = new(); public EntityComponent Entity { get; set; } public DRLevel CurrentLevel { get; set; } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntimeContext.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntime.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntimeContext.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSchedulerRuntime.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementContext.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementContext.cs index aa61c92..92738b5 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementContext.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementContext.cs @@ -4,12 +4,12 @@ namespace GeometryTD.CustomComponent { internal sealed class CombatSettlementContext { - public CombatSettlementFlowState Flow { get; } = new(); + public CombatSettlementFlags Flags { get; } = new(); public CombatSettlementResult Result { get; } = new(); public CombatSettlementSummary Summary { get; } = new(); } - internal sealed class CombatSettlementFlowState + internal sealed class CombatSettlementFlags { public bool ShouldOpenRewardSelection; public bool DidEnterRewardSelection; diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementFlowService.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementService.cs similarity index 89% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementFlowService.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementService.cs index 28010bb..e464d75 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementFlowService.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementService.cs @@ -8,7 +8,7 @@ using UnityGameFramework.Runtime; namespace GeometryTD.CustomComponent { - internal sealed class CombatSettlementFlowService + internal sealed class CombatSettlementService { private const int RewardSelectDisplayCount = 3; private const float FullBaseHpGoldBonusRate = 0.3f; @@ -21,13 +21,13 @@ namespace GeometryTD.CustomComponent bool isVictory, DRLevel currentLevel, int defeatedEnemyCount, - CombatInRunResourceManager resourceManager) + CombatRunResourceStore resourceStore) { bool shouldOpenFullBaseHpRewardSelect = false; ResolveSettlementByBaseHp( isVictory, currentLevel, - resourceManager, + resourceStore, out int currentBaseHp, out int maxBaseHp, out int levelRewardGold, @@ -40,19 +40,19 @@ namespace GeometryTD.CustomComponent { }; settlementContext.Result.IsVictory = isVictory; - settlementContext.Result.FinalCoin = Mathf.Max(0, resourceManager != null ? resourceManager.CurrentCoin : 0); + settlementContext.Result.FinalCoin = Mathf.Max(0, resourceStore != null ? resourceStore.CurrentCoin : 0); settlementContext.Result.FinalBaseHp = currentBaseHp; settlementContext.Result.MaxBaseHp = maxBaseHp; settlementContext.Result.DefeatedEnemyCount = Mathf.Max(0, defeatedEnemyCount); - settlementContext.Result.GainedGold = Mathf.Max(0, resourceManager != null ? resourceManager.GainedGold : 0); - settlementContext.Result.RewardInventory = resourceManager != null - ? resourceManager.GetRewardInventorySnapshot() + settlementContext.Result.GainedGold = Mathf.Max(0, resourceStore != null ? resourceStore.GainedGold : 0); + settlementContext.Result.RewardInventory = resourceStore != null + ? resourceStore.GetRewardInventorySnapshot() : new BackpackInventoryData(); settlementContext.Result.Penalty.ShouldApplyLowBaseHpPenalty = appliedLowBaseHpPenalty; settlementContext.Result.Penalty.LowBaseHpEndurancePenaltyValue = appliedLowBaseHpPenalty ? LowBaseHpTowerEndurancePenalty : 0f; - settlementContext.Flow.ShouldOpenRewardSelection = shouldOpenFullBaseHpRewardSelect; - settlementContext.Flow.DidEnterRewardSelection = false; + settlementContext.Flags.ShouldOpenRewardSelection = shouldOpenFullBaseHpRewardSelect; + settlementContext.Flags.DidEnterRewardSelection = false; settlementContext.Summary.DefeatedEnemyCount = settlementContext.Result.DefeatedEnemyCount; settlementContext.Summary.GainedGold = settlementContext.Result.GainedGold; settlementContext.Summary.RewardInventory = settlementContext.Result.RewardInventory; @@ -72,7 +72,7 @@ namespace GeometryTD.CustomComponent public void CommitSettlementInventory(CombatSettlementContext settlementContext) { - if (settlementContext == null || settlementContext.Flow.IsCommitted) + if (settlementContext == null || settlementContext.Flags.IsCommitted) { return; } @@ -82,7 +82,7 @@ namespace GeometryTD.CustomComponent settlementContext.Result.RewardInventory = rewardInventory; settlementContext.Summary.RewardInventory = rewardInventory; settlementContext.Result.Penalty.AffectedTowerCount = ApplyDeferredSettlementPenalty(settlementContext); - settlementContext.Flow.IsCommitted = true; + settlementContext.Flags.IsCommitted = true; } public bool TryPrepareRewardSelection( @@ -105,7 +105,7 @@ namespace GeometryTD.CustomComponent RewardSelectDisplayCount); if (candidateItems == null || candidateItems.Count <= 0) { - settlementContext.Flow.ShouldOpenRewardSelection = false; + settlementContext.Flags.ShouldOpenRewardSelection = false; return false; } @@ -123,7 +123,7 @@ namespace GeometryTD.CustomComponent if (rewardPool.Count <= 0) { - settlementContext.Flow.ShouldOpenRewardSelection = false; + settlementContext.Flags.ShouldOpenRewardSelection = false; return false; } @@ -139,11 +139,11 @@ namespace GeometryTD.CustomComponent RewardSelectFormRawData rawData = rewardSelectFormUseCase.CreateInitialModel(); if (rawData == null || rawData.RewardItems == null || rawData.RewardItems.Length <= 0) { - settlementContext.Flow.ShouldOpenRewardSelection = false; + settlementContext.Flags.ShouldOpenRewardSelection = false; return false; } - settlementContext.Flow.DidEnterRewardSelection = true; + settlementContext.Flags.DidEnterRewardSelection = true; GameEntry.UIRouter.OpenUI(UIFormType.RewardSelectForm, rawData); return true; } @@ -175,7 +175,7 @@ namespace GeometryTD.CustomComponent private static void ResolveSettlementByBaseHp( bool isVictory, DRLevel currentLevel, - CombatInRunResourceManager resourceManager, + CombatRunResourceStore resourceStore, out int currentBaseHp, out int maxBaseHp, out int levelRewardGold, @@ -184,8 +184,8 @@ namespace GeometryTD.CustomComponent out bool appliedLowBaseHpPenalty, out bool shouldOpenFullBaseHpRewardSelect) { - currentBaseHp = Mathf.Max(0, resourceManager != null ? resourceManager.CurrentBaseHp : 0); - maxBaseHp = resourceManager != null ? Mathf.Max(0, resourceManager.MaxBaseHp) : 0; + currentBaseHp = Mathf.Max(0, resourceStore != null ? resourceStore.CurrentBaseHp : 0); + maxBaseHp = resourceStore != null ? Mathf.Max(0, resourceStore.MaxBaseHp) : 0; if (maxBaseHp > 0) { currentBaseHp = Mathf.Clamp(currentBaseHp, 0, maxBaseHp); @@ -197,7 +197,7 @@ namespace GeometryTD.CustomComponent appliedLowBaseHpPenalty = false; shouldOpenFullBaseHpRewardSelect = false; - if (!isVictory || resourceManager == null) + if (!isVictory || resourceStore == null) { return; } @@ -220,10 +220,10 @@ namespace GeometryTD.CustomComponent } } - int goldForBonusCalculation = Mathf.Max(0, resourceManager.GainedGold) + levelRewardGold; + int goldForBonusCalculation = Mathf.Max(0, resourceStore.GainedGold) + levelRewardGold; bonusGold = bonusRate > 0f ? Mathf.FloorToInt(goldForBonusCalculation * bonusRate) : 0; int settlementGold = levelRewardGold + bonusGold; - resourceManager.AddSettlementGold(settlementGold); + resourceStore.AddSettlementGold(settlementGold); } private static int ApplyDeferredSettlementPenalty(CombatSettlementContext settlementContext) diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementFlowService.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementService.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementFlowService.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementService.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFailedState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFailedState.cs index 74a22f4..a82a73a 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFailedState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFailedState.cs @@ -7,9 +7,9 @@ namespace GeometryTD.CustomComponent private readonly string _errorMessage; public CombatFailedState( - CombatSchedulerRuntimeContext context, - CombatSchedulerFlowCoordinator flow, - string errorMessage) : base(context, flow) + CombatSchedulerRuntime runtime, + CombatSchedulerCoordinator coordinator, + string errorMessage) : base(runtime, coordinator) { _errorMessage = errorMessage; } @@ -18,17 +18,17 @@ namespace GeometryTD.CustomComponent { Log.Error( "CombatScheduler failed. LevelId={0}, {1}", - Context.CurrentLevel != null ? Context.CurrentLevel.Id : 0, + Runtime.CurrentLevel != null ? Runtime.CurrentLevel.Id : 0, _errorMessage); - Context.EnemyManager.EndPhase(); - Flow.CloseCombatFinishForm(); - Flow.CloseRewardSelectForm(); - Flow.OpenCombatFailureDialog(_errorMessage); + Runtime.EnemyManager.EndPhase(); + Coordinator.CloseCombatFinishForm(); + Coordinator.CloseRewardSelectForm(); + Coordinator.OpenCombatFailureDialog(_errorMessage); } public override void OnExit() { - Flow.CloseDialogForm(); + Coordinator.CloseDialogForm(); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFinishFormState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFinishFormState.cs index 0d8a49f..1d1c375 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFinishFormState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatFinishFormState.cs @@ -2,24 +2,24 @@ namespace GeometryTD.CustomComponent { internal sealed class CombatFinishFormState : CombatStateBase { - public CombatFinishFormState(CombatSchedulerRuntimeContext context, CombatSchedulerFlowCoordinator flow) - : base(context, flow) + public CombatFinishFormState(CombatSchedulerRuntime runtime, CombatSchedulerCoordinator coordinator) + : base(runtime, coordinator) { } public override void OnEnter() { - if (Context.SettlementContext == null) + if (Runtime.SettlementContext == null) { - Flow.EnterFailureFallback("Combat finish form failed. Settlement context is missing."); + Coordinator.EnterFailureFallback("Combat finish form failed. Settlement context is missing."); return; } - Flow.EnsureCombatFinishFormUseCaseBound(); - Context.SettlementFlowService.OpenCombatFinishForm( - Context.SettlementContext, - Context.CombatFinishFormUseCase); - Flow.ChangeState(new CombatWaitingForReturnState(Context, Flow)); + Coordinator.EnsureCombatFinishFormUseCaseBound(); + Runtime.CombatSettlementService.OpenCombatFinishForm( + Runtime.SettlementContext, + Runtime.CombatFinishFormUseCase); + Coordinator.ChangeState(new CombatWaitingForReturnState(Runtime, Coordinator)); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatLoadingState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatLoadingState.cs index ac23a12..330cc10 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatLoadingState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatLoadingState.cs @@ -8,23 +8,23 @@ namespace GeometryTD.CustomComponent { internal sealed class CombatLoadingState : CombatStateBase { - public CombatLoadingState(CombatSchedulerRuntimeContext context, CombatSchedulerFlowCoordinator flow) - : base(context, flow) + public CombatLoadingState(CombatSchedulerRuntime runtime, CombatSchedulerCoordinator coordinator) + : base(runtime, coordinator) { } public override void OnEnter() { - if (Context.CurrentLevel == null) + if (Runtime.CurrentLevel == null) { - Flow.EnterFailureFallback("Combat loading failed. Current level is null."); + Coordinator.EnterFailureFallback("Combat loading failed. Current level is null."); return; } MapEntityLoadContext mapLoadContext = BuildMapLoadContext(); - if (!Context.LoadSession.StartLoading(Context.CurrentLevel, mapLoadContext, Flow.Host, out string errorMessage)) + if (!Runtime.LoadSession.StartLoading(Runtime.CurrentLevel, mapLoadContext, Coordinator.Port, out string errorMessage)) { - Flow.EnterFailureFallback($"Combat loading failed. {errorMessage}"); + Coordinator.EnterFailureFallback($"Combat loading failed. {errorMessage}"); } } @@ -33,20 +33,20 @@ namespace GeometryTD.CustomComponent _ = elapseSeconds; _ = realElapseSeconds; - if (!Context.LoadSession.IsReady) + if (!Runtime.LoadSession.IsReady) { return; } - Flow.TryBeginNextPhase(); + Coordinator.TryBeginNextPhase(); } private MapEntityLoadContext BuildMapLoadContext() { List buildTowerStatsSnapshot = new(); - for (int i = 0; i < Context.CombatInRunResourceManager.CurrentBuildTowerCount; i++) + for (int i = 0; i < Runtime.CombatRunResourceStore.CurrentBuildTowerCount; i++) { - if (Context.CombatInRunResourceManager.TryGetBuildTowerStats(i, out TowerStatsData stats) && + if (Runtime.CombatRunResourceStore.TryGetBuildTowerStats(i, out TowerStatsData stats) && stats != null) { buildTowerStatsSnapshot.Add(stats); @@ -56,16 +56,16 @@ namespace GeometryTD.CustomComponent MapData mapData = new MapData( entityId: 0, typeId: 0, - levelId: Context.CurrentLevel.Id, + levelId: Runtime.CurrentLevel.Id, position: Vector3.zero, - initialCoin: Context.CombatInRunResourceManager.CurrentCoin, + initialCoin: Runtime.CombatRunResourceStore.CurrentCoin, buildTowerStatsSnapshot: buildTowerStatsSnapshot, - inventorySnapshot: Context.CombatInRunResourceManager.GetCombatInventorySnapshot(), - participantTowerSnapshot: Context.CombatInRunResourceManager.GetParticipantTowerSnapshot()); + inventorySnapshot: Runtime.CombatRunResourceStore.GetCombatInventorySnapshot(), + participantTowerSnapshot: Runtime.CombatRunResourceStore.GetParticipantTowerSnapshot()); return new MapEntityLoadContext( mapData, - Context.CombatInRunResourceManager.TryConsumeCoin, - Context.CombatInRunResourceManager.AddCoin); + Runtime.CombatRunResourceStore.TryConsumeCoin, + Runtime.CombatRunResourceStore.AddCoin); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRewardSelectionState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRewardSelectionState.cs index d116e1e..b2ae171 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRewardSelectionState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRewardSelectionState.cs @@ -2,36 +2,36 @@ namespace GeometryTD.CustomComponent { internal sealed class CombatRewardSelectionState : CombatStateBase { - public CombatRewardSelectionState(CombatSchedulerRuntimeContext context, CombatSchedulerFlowCoordinator flow) - : base(context, flow) + public CombatRewardSelectionState(CombatSchedulerRuntime runtime, CombatSchedulerCoordinator coordinator) + : base(runtime, coordinator) { } public override void OnEnter() { - if (Context.SettlementContext == null) + if (Runtime.SettlementContext == null) { - Flow.EnterFailureFallback("Combat reward selection failed. Settlement context is missing."); + Coordinator.EnterFailureFallback("Combat reward selection failed. Settlement context is missing."); return; } - Flow.EnsureRewardSelectFormUseCaseBound(); - if (!Context.SettlementFlowService.TryPrepareRewardSelection( - Context.SettlementContext, - Context.EnemyDropResolver, - Context.PhaseLoopRuntime.DisplayPhaseIndex, - Flow.ResolveCurrentThemeType(), - Context.RewardSelectFormUseCase, - Flow.OnFullBaseHpRewardSelected, - Flow.OnFullBaseHpRewardGiveUp)) + Coordinator.EnsureRewardSelectFormUseCaseBound(); + if (!Runtime.CombatSettlementService.TryPrepareRewardSelection( + Runtime.SettlementContext, + Runtime.EnemyDropResolver, + Runtime.PhaseLoopRuntime.DisplayPhaseIndex, + Coordinator.ResolveCurrentThemeType(), + Runtime.RewardSelectFormUseCase, + Coordinator.OnFullBaseHpRewardSelected, + Coordinator.OnFullBaseHpRewardGiveUp)) { - Flow.ChangeState(new CombatFinishFormState(Context, Flow)); + Coordinator.ChangeState(new CombatFinishFormState(Runtime, Coordinator)); } } public override void OnExit() { - Flow.CloseRewardSelectForm(); + Coordinator.CloseRewardSelectForm(); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRunningPhaseState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRunningPhaseState.cs index 183ce08..9f791df 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRunningPhaseState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatRunningPhaseState.cs @@ -11,10 +11,10 @@ namespace GeometryTD.CustomComponent private readonly IReadOnlyList _spawnEntries; public CombatRunningPhaseState( - CombatSchedulerRuntimeContext context, - CombatSchedulerFlowCoordinator flow, + CombatSchedulerRuntime runtime, + CombatSchedulerCoordinator coordinator, DRLevelPhase phase, - IReadOnlyList spawnEntries) : base(context, flow) + IReadOnlyList spawnEntries) : base(runtime, coordinator) { _phase = phase; _spawnEntries = spawnEntries; @@ -22,59 +22,59 @@ namespace GeometryTD.CustomComponent public override void OnEnter() { - Context.EnemyManager.BeginPhase(_phase, _spawnEntries); + Runtime.EnemyManager.BeginPhase(_phase, _spawnEntries); GameEntry.Event.Fire( - Flow, + Coordinator, CombatProcessEventArgs.Create( - Context.PhaseLoopRuntime.DisplayPhaseIndex, - Context.PhaseLoopRuntime.PhaseCount)); + Runtime.PhaseLoopRuntime.DisplayPhaseIndex, + Runtime.PhaseLoopRuntime.PhaseCount)); GameEntry.Event.Fire( - Flow, + Coordinator, CombatEnemyHpRateChangedEventArgs.Create( - Flow.ResolveEnemyHpRateMultiplier( - Context.PhaseLoopRuntime.DisplayPhaseIndex, - Context.PhaseLoopRuntime.PhaseCount))); + Coordinator.ResolveEnemyHpRateMultiplier( + Runtime.PhaseLoopRuntime.DisplayPhaseIndex, + Runtime.PhaseLoopRuntime.PhaseCount))); - if (!Context.NodeEnterFired) + if (!Runtime.NodeEnterFired) { - Context.NodeEnterFired = true; + Runtime.NodeEnterFired = true; GameEntry.Event.Fire( - Flow, + Coordinator, NodeEnterEventArgs.Create( - Context.RunId, - Context.NodeId, - Context.NodeType, - Context.SequenceIndex)); + Runtime.RunId, + Runtime.NodeId, + Runtime.NodeType, + Runtime.SequenceIndex)); } Log.Info( "CombatScheduler phase started. Level={0}, Phase={1}, EndType={2}, Entries={3}.", - Context.CurrentLevel != null ? Context.CurrentLevel.Id : 0, - Context.PhaseLoopRuntime.DisplayPhaseIndex, + Runtime.CurrentLevel != null ? Runtime.CurrentLevel.Id : 0, + Runtime.PhaseLoopRuntime.DisplayPhaseIndex, _phase.EndType, _spawnEntries != null ? _spawnEntries.Count : 0); } public override void OnUpdate(float elapseSeconds, float realElapseSeconds) { - if (Context.PhaseLoopRuntime.CurrentPhase == null) + if (Runtime.PhaseLoopRuntime.CurrentPhase == null) { - Flow.EnterFailureFallback("CombatScheduler update failed. Current phase is null."); + Coordinator.EnterFailureFallback("CombatScheduler update failed. Current phase is null."); return; } - Context.PhaseLoopRuntime.AdvancePhaseElapsed(elapseSeconds); - Context.EnemyManager.OnUpdate(elapseSeconds, realElapseSeconds); + Runtime.PhaseLoopRuntime.AdvancePhaseElapsed(elapseSeconds); + Runtime.EnemyManager.OnUpdate(elapseSeconds, realElapseSeconds); - if (Flow.ShouldEnterSettlementFromActiveState(out bool isVictory)) + if (Coordinator.ShouldEnterSettlementFromActiveState(out bool isVictory)) { - Flow.ChangeState(new CombatSettlementState(Context, Flow, isVictory)); + Coordinator.ChangeState(new CombatSettlementState(Runtime, Coordinator, isVictory)); return; } - if (Context.EnemyManager.IsPhaseSpawnCompleted) + if (Runtime.EnemyManager.IsPhaseSpawnCompleted) { - Flow.EnterWaitingForPhaseEnd(); + Coordinator.EnterWaitingForPhaseEnd(); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatSettlementState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatSettlementState.cs index f3f92b4..b365b38 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatSettlementState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatSettlementState.cs @@ -5,30 +5,30 @@ namespace GeometryTD.CustomComponent private readonly bool _isVictory; public CombatSettlementState( - CombatSchedulerRuntimeContext context, - CombatSchedulerFlowCoordinator flow, - bool isVictory) : base(context, flow) + CombatSchedulerRuntime runtime, + CombatSchedulerCoordinator coordinator, + bool isVictory) : base(runtime, coordinator) { _isVictory = isVictory; } public override void OnEnter() { - Context.EnemyManager.EndPhase(); - Context.EnemyManager.CleanupTrackedEnemies(); - Context.IsFinishAsVictory = _isVictory; - Context.SettlementContext = Context.SettlementFlowService.BuildSettlementContext( + Runtime.EnemyManager.EndPhase(); + Runtime.EnemyManager.CleanupTrackedEnemies(); + Runtime.IsFinishAsVictory = _isVictory; + Runtime.SettlementContext = Runtime.CombatSettlementService.BuildSettlementContext( _isVictory, - Context.CurrentLevel, - Context.EnemyManager.DefeatedEnemyCount, - Context.CombatInRunResourceManager); - if (Context.SettlementContext.Flow.ShouldOpenRewardSelection) + Runtime.CurrentLevel, + Runtime.EnemyManager.DefeatedEnemyCount, + Runtime.CombatRunResourceStore); + if (Runtime.SettlementContext.Flags.ShouldOpenRewardSelection) { - Flow.ChangeState(new CombatRewardSelectionState(Context, Flow)); + Coordinator.ChangeState(new CombatRewardSelectionState(Runtime, Coordinator)); return; } - Flow.ChangeState(new CombatFinishFormState(Context, Flow)); + Coordinator.ChangeState(new CombatFinishFormState(Runtime, Coordinator)); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatStateBase.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatStateBase.cs index 5658a6f..54248c7 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatStateBase.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatStateBase.cs @@ -2,13 +2,13 @@ namespace GeometryTD.CustomComponent { internal abstract class CombatStateBase { - protected CombatSchedulerRuntimeContext Context { get; } - protected CombatSchedulerFlowCoordinator Flow { get; } + protected CombatSchedulerRuntime Runtime { get; } + protected CombatSchedulerCoordinator Coordinator { get; } - protected CombatStateBase(CombatSchedulerRuntimeContext context, CombatSchedulerFlowCoordinator flow) + protected CombatStateBase(CombatSchedulerRuntime runtime, CombatSchedulerCoordinator coordinator) { - Context = context; - Flow = flow; + Runtime = runtime; + Coordinator = coordinator; } public virtual void OnInit() diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForPhaseEndState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForPhaseEndState.cs index a04d3d8..6c9bccb 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForPhaseEndState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForPhaseEndState.cs @@ -4,8 +4,8 @@ namespace GeometryTD.CustomComponent { internal sealed class CombatWaitingForPhaseEndState : CombatStateBase { - public CombatWaitingForPhaseEndState(CombatSchedulerRuntimeContext context, CombatSchedulerFlowCoordinator flow) - : base(context, flow) + public CombatWaitingForPhaseEndState(CombatSchedulerRuntime runtime, CombatSchedulerCoordinator coordinator) + : base(runtime, coordinator) { } @@ -13,34 +13,34 @@ namespace GeometryTD.CustomComponent { _ = realElapseSeconds; - DRLevelPhase currentPhase = Context.PhaseLoopRuntime.CurrentPhase; + DRLevelPhase currentPhase = Runtime.PhaseLoopRuntime.CurrentPhase; if (currentPhase == null) { - Flow.EnterFailureFallback("CombatScheduler waiting phase failed. Current phase is null."); + Coordinator.EnterFailureFallback("CombatScheduler waiting phase failed. Current phase is null."); return; } - Context.PhaseLoopRuntime.AdvancePhaseElapsed(elapseSeconds); + Runtime.PhaseLoopRuntime.AdvancePhaseElapsed(elapseSeconds); - if (Flow.ShouldEnterSettlementFromActiveState(out bool isVictory)) + if (Coordinator.ShouldEnterSettlementFromActiveState(out bool isVictory)) { - Flow.ChangeState(new CombatSettlementState(Context, Flow, isVictory)); + Coordinator.ChangeState(new CombatSettlementState(Runtime, Coordinator, isVictory)); return; } PhaseEndConditionContext conditionContext = new( currentPhase, - Context.PhaseLoopRuntime.CurrentPhaseElapsed, - Context.EnemyManager.IsPhaseSpawnCompleted, - Context.EnemyManager.AliveEnemyCount, - Context.EnemyManager.HasAliveBoss); + Runtime.PhaseLoopRuntime.CurrentPhaseElapsed, + Runtime.EnemyManager.IsPhaseSpawnCompleted, + Runtime.EnemyManager.AliveEnemyCount, + Runtime.EnemyManager.HasAliveBoss); IPhaseEndCondition endCondition = PhaseEndConditionFactory.Create(currentPhase.EndType); if (!endCondition.ShouldExit(conditionContext)) { return; } - Flow.CompleteCurrentPhase(); + Coordinator.CompleteCurrentPhase(); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForReturnState.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForReturnState.cs index ffa7790..593c2ac 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForReturnState.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatStates/CombatWaitingForReturnState.cs @@ -4,8 +4,8 @@ namespace GeometryTD.CustomComponent { private bool _returnRequested; - public CombatWaitingForReturnState(CombatSchedulerRuntimeContext context, CombatSchedulerFlowCoordinator flow) - : base(context, flow) + public CombatWaitingForReturnState(CombatSchedulerRuntime runtime, CombatSchedulerCoordinator coordinator) + : base(runtime, coordinator) { } @@ -24,17 +24,17 @@ namespace GeometryTD.CustomComponent return; } - if (Context.SettlementContext == null) + if (Runtime.SettlementContext == null) { - Flow.EnterFailureFallback("Combat return failed. Settlement context is missing."); + Coordinator.EnterFailureFallback("Combat return failed. Settlement context is missing."); return; } - Context.SettlementFlowService.CommitSettlementInventory(Context.SettlementContext); - Context.LoadSession.Cleanup(); - Flow.CloseCombatFinishForm(); - Flow.CloseRewardSelectForm(); - Flow.CompleteNormalCombatAndNotify(Context.IsFinishAsVictory); + Runtime.CombatSettlementService.CommitSettlementInventory(Runtime.SettlementContext); + Runtime.LoadSession.Cleanup(); + Coordinator.CloseCombatFinishForm(); + Coordinator.CloseRewardSelectForm(); + Coordinator.CompleteNormalCombatAndNotify(Runtime.IsFinishAsVictory); } } } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveContext.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropContext.cs similarity index 70% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveContext.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropContext.cs index 705385f..d09cad0 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveContext.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropContext.cs @@ -3,9 +3,9 @@ using GeometryTD.Definition; namespace GeometryTD.CustomComponent { - internal readonly struct EnemyDropResolveContext + internal readonly struct EnemyDropContext { - public EnemyDropResolveContext(DREnemy enemy, int displayPhaseIndex, LevelThemeType themeType) + public EnemyDropContext(DREnemy enemy, int displayPhaseIndex, LevelThemeType themeType) { Enemy = enemy; DisplayPhaseIndex = displayPhaseIndex; diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveContext.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropContext.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveContext.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropContext.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs index 2f4fbd6..8995244 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs @@ -31,12 +31,12 @@ namespace GeometryTD.CustomComponent _nextDropItemInstanceId = 1; } - public EnemyDropResolveResult Resolve(in EnemyDropResolveContext context) + public EnemyDropResult Resolve(in EnemyDropContext context) { DREnemy enemy = context.Enemy; if (enemy == null) { - return EnemyDropResolveResult.Empty; + return EnemyDropResult.Empty; } int coin = Mathf.Max(0, enemy.DropCoin); @@ -58,7 +58,7 @@ namespace GeometryTD.CustomComponent lootItem = droppedItem; } - return new EnemyDropResolveResult(coin, gold, lootItem); + return new EnemyDropResult(coin, gold, lootItem); } public IReadOnlyList RollSettlementRewardCandidates( diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveResult.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResult.cs similarity index 59% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveResult.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResult.cs index ee7339d..132efb4 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveResult.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResult.cs @@ -2,11 +2,11 @@ using GeometryTD.Definition; namespace GeometryTD.CustomComponent { - internal readonly struct EnemyDropResolveResult + internal readonly struct EnemyDropResult { - public static EnemyDropResolveResult Empty => new(0, 0, null); + public static EnemyDropResult Empty => new(0, 0, null); - public EnemyDropResolveResult(int coin, int gold, TowerCompItemData lootItem) + public EnemyDropResult(int coin, int gold, TowerCompItemData lootItem) { Coin = coin; Gold = gold; diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveResult.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResult.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolveResult.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResult.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerHost.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerPort.cs similarity index 91% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerHost.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerPort.cs index ddf80ba..52bd1ab 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerHost.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerPort.cs @@ -2,7 +2,7 @@ using GeometryTD.DataTable; namespace GeometryTD.CustomComponent { - internal interface ICombatSchedulerHost + internal interface ICombatSchedulerPort { DRLevel CurrentLevel { get; } int DisplayPhaseIndex { get; } diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerHost.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerPort.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerHost.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/ICombatSchedulerPort.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigService.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigProvider.cs similarity index 92% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigService.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigProvider.cs index 8fdd461..d2c5223 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigService.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigProvider.cs @@ -6,7 +6,7 @@ using UnityGameFramework.Runtime; namespace GeometryTD.CustomComponent { - public sealed class EnemyConfigService + public sealed class EnemyConfigProvider { private const int DefaultEnemyConfigId = 1; @@ -28,7 +28,7 @@ namespace GeometryTD.CustomComponent { if (!_enemyConfigMissingLogged) { - Log.Warning("EnemyManagerComponent can not find DREnemy data table."); + Log.Warning("EnemyConfigProvider can not find DREnemy data table."); _enemyConfigMissingLogged = true; } @@ -59,7 +59,7 @@ namespace GeometryTD.CustomComponent if (!_enemyConfigMissingLogged) { - Log.Warning("EnemyManagerComponent found no enemy configs."); + Log.Warning("EnemyConfigProvider found no enemy configs."); _enemyConfigMissingLogged = true; } @@ -101,4 +101,4 @@ namespace GeometryTD.CustomComponent return Mathf.Max(0, (displayPhaseIndex - 1) / phaseCount); } } -} \ No newline at end of file +} diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigService.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigProvider.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigService.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigProvider.cs.meta diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyManager.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyManager.cs index 877c017..b8bb859 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyManager.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyManager.cs @@ -12,8 +12,8 @@ namespace GeometryTD.CustomComponent { private readonly List _trackedEnemyIdBuffer = new(); private readonly EnemySpawnDirector _enemySpawnDirector = new(); - private readonly EnemyConfigService _enemyConfigService = new(); - private readonly SpawnerResolver _spawnerResolver = new(); + private readonly EnemyConfigProvider _enemyConfigProvider = new(); + private readonly EnemySpawnPathResolver _enemySpawnPathResolver = new(); private readonly EnemyLifecycleTracker _enemyLifecycleTracker = new(); private CombatScheduler _combatScheduler; @@ -39,8 +39,8 @@ namespace GeometryTD.CustomComponent _entity = GameEntry.Entity; _defeatedEnemyCount = 0; _enemySpawnDirector.Reset(); - _enemyConfigService.Reset(); - _spawnerResolver.Reset(); + _enemyConfigProvider.Reset(); + _enemySpawnPathResolver.Reset(); _trackedEnemyIdBuffer.Clear(); _enemyLifecycleTracker.Reset(); @@ -59,7 +59,7 @@ namespace GeometryTD.CustomComponent _ = phase; EndPhase(); - _spawnerResolver.RefreshCache(_combatScheduler, true); + _enemySpawnPathResolver.RefreshCache(_combatScheduler, true); _enemySpawnDirector.BeginPhase(spawnEntries); } @@ -70,7 +70,7 @@ namespace GeometryTD.CustomComponent return; } - _spawnerResolver.RefreshCache(_combatScheduler, false); + _enemySpawnPathResolver.RefreshCache(_combatScheduler, false); _enemySpawnDirector.OnUpdate(elapseSeconds, SpawnEnemies); } @@ -93,11 +93,11 @@ namespace GeometryTD.CustomComponent GameEntry.Event.Unsubscribe(ShowEntityFailureEventArgs.EventId, OnShowEntityFailure); GameEntry.Event.Unsubscribe(HideEntityCompleteEventArgs.EventId, OnHideEntityComplete); - _spawnerResolver.Reset(); + _enemySpawnPathResolver.Reset(); _trackedEnemyIdBuffer.Clear(); _enemyLifecycleTracker.Reset(); _defeatedEnemyCount = 0; - _enemyConfigService.Reset(); + _enemyConfigProvider.Reset(); _combatScheduler = null; _initialized = false; } @@ -139,18 +139,18 @@ namespace GeometryTD.CustomComponent return; } - if (!_spawnerResolver.TryResolveSpawnPath(_combatScheduler, entry.SpawnPointId, out IReadOnlyList pathPoints)) + if (!_enemySpawnPathResolver.TryResolveSpawnPath(_combatScheduler, entry.SpawnPointId, out IReadOnlyList pathPoints)) { return; } - DREnemy enemyConfig = _enemyConfigService.GetEnemyConfig(entry.EnemyId); + DREnemy enemyConfig = _enemyConfigProvider.GetEnemyConfig(entry.EnemyId); if (enemyConfig == null) { return; } - int scaledBaseHp = _enemyConfigService.ResolveScaledEnemyBaseHp(enemyConfig.BaseHp, _combatScheduler); + int scaledBaseHp = _enemyConfigProvider.ResolveScaledEnemyBaseHp(enemyConfig.BaseHp, _combatScheduler); bool isBoss = entry.EntryType == Definition.EntryType.Boss; for (int i = 0; i < spawnCount; i++) diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/SpawnerResolver.cs b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemySpawnPathResolver.cs similarity index 98% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/SpawnerResolver.cs rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemySpawnPathResolver.cs index c3c3c57..e8696df 100644 --- a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/SpawnerResolver.cs +++ b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemySpawnPathResolver.cs @@ -5,7 +5,7 @@ using UnityEngine; namespace GeometryTD.CustomComponent { - internal sealed class SpawnerResolver + internal sealed class EnemySpawnPathResolver { private readonly List _spawners = new(); private readonly Dictionary _spawnerByOrder = new(); diff --git a/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/SpawnerResolver.cs.meta b/Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemySpawnPathResolver.cs.meta similarity index 100% rename from Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/SpawnerResolver.cs.meta rename to Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemySpawnPathResolver.cs.meta diff --git a/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatFinishFormUseCase.cs b/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatFinishFormUseCase.cs index 16ace9b..7753947 100644 --- a/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatFinishFormUseCase.cs +++ b/Assets/GameMain/Scripts/UI/Combat/UseCase/CombatFinishFormUseCase.cs @@ -7,7 +7,7 @@ namespace GeometryTD.UI { public class CombatFinishFormUseCase : IUIUseCase { - private ICombatSchedulerHost _combatSchedulerHost; + private ICombatSchedulerPort _combatSchedulerPort; private CombatSettlementContext _settlementContext; private bool _isSummaryPrepared; @@ -27,14 +27,14 @@ namespace GeometryTD.UI _isSummaryPrepared = true; } - internal CombatFinishFormUseCase(ICombatSchedulerHost combatSchedulerHost) + internal CombatFinishFormUseCase(ICombatSchedulerPort combatSchedulerPort) { - _combatSchedulerHost = combatSchedulerHost; + _combatSchedulerPort = combatSchedulerPort; } public bool TryReturnToMenu() { - return _combatSchedulerHost != null && _combatSchedulerHost.OnCombatFinishReturnRequested(); + return _combatSchedulerPort != null && _combatSchedulerPort.OnCombatFinishReturnRequested(); } private CombatFinishFormRawData BuildModel() diff --git a/docs/CodeX-TODO.md b/docs/CodeX-TODO.md index dc2ba27..a964c8c 100644 --- a/docs/CodeX-TODO.md +++ b/docs/CodeX-TODO.md @@ -8,8 +8,8 @@ 和上一版相比,仓库已经把 Run 相关基础件进一步接到了 `ProcedureMain`,因此这份清单不再把重点放在“有没有 Run 模型”,而是聚焦下面这几个真实阻塞项: -- 已有 `ProcedureMain + NodeMapForm` 的临时 Run 推进闭环,正式节点面板骨架已经接入流程。 -- 固定 10 节点顺序已经开始驱动战斗 / 事件 / 商店入口,但节点事件上下文仍然是空载版本。 +- 已有 `ProcedureMenu + MenuForm -> ProcedureMain + NodeMapForm` 的主入口链路,正式节点面板骨架已经接入流程。 +- 固定 10 节点顺序已经开始驱动战斗 / 事件 / 商店入口,节点事件也已带上基础 Run 上下文字段。 - 出战入口已有“至少有参战塔”的最小校验,但还没收口成严格的最终合法性约束。 - 品质 / Tag / 耐久仍然停留在部分实现状态,尚未和 M1 范围完全对齐。 @@ -30,13 +30,13 @@ ### 2. 战斗结算、掉落与奖励选择已有基础实现 - 敌人被击败后已能发放 coin / gold / 组件掉落。 -- `CombatInRunResourceManager` 维护局内资源与奖励背包快照。 +- `CombatRunResourceStore` 维护局内资源与奖励背包快照。 - 结算链已包含奖励计算、奖励选择 UI、FinishForm 返回等基础骨架。 关键文件: -- `Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatInRunResourceManager.cs` +- `Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs` - `Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs` -- `Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementFlowService.cs` +- `Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatSettlementService.cs` - `Assets/GameMain/Scripts/UI/Combat/` ### 3. 背包、参战区与组装基础能力已经存在 @@ -107,6 +107,19 @@ - `Assets/GameMain/Scripts/UI/Game/View/NodeItem.cs` - `Assets/GameMain/Scripts/Event/Game/NodeMapNodeEnterRequestedEventArgs.cs` +### 8. 菜单入口已切回独立 Menu 流程 + +- `ProcedureMenu` 当前只负责菜单入口,不再承载主流程 Hub 与节点推进逻辑。 +- `MenuForm` 已按五层结构补齐 `RawData / UseCase / Controller / Context / View`。 +- `Start` 按钮现在会驱动 `ProcedureMenu` 切场景,并在主场景加载完成后进入 `ProcedureMain`。 +- `Settings` 仍保留 `TODO` 占位,`Exit` 会直接退出游戏。 + +关键文件: +- `Assets/GameMain/Scripts/Procedure/ProcedureMenu.cs` +- `Assets/GameMain/Scripts/Procedure/Base/ProcedureChangeScene.cs` +- `Assets/GameMain/Scripts/UI/Menu/Controller/MenuFormController.cs` +- `Assets/GameMain/Scripts/UI/Menu/View/MenuForm.cs` + ## 当前未完成 ### 1. Run 主流程已经形成基于 `NodeMapForm` 的临时闭环,但还没完全收口 @@ -127,14 +140,14 @@ - `Assets/GameMain/Scripts/UI/Game/View/NodeMapForm.cs` - `Assets/GameMain/Scripts/UI/Game/Controller/NodeMapFormController.cs` -### 2. 固定 10 节点序列已开始驱动真实流程,但上下文仍不完整 +### 2. 固定 10 节点序列已开始驱动真实流程,但正式上下文系统仍不完整 - `FixedRunNodeSequenceBuilder` 已定义固定顺序和 Boss 终点。 - `ProcedureMain` 已开始用当前 `RunNodeState.LinkedLevelId` 驱动战斗入口。 - `EventNodeComponent` 和 `ShopNodeComponent` 已能进入并完成当前节点。 - `EventNodeComponent` 的 UI 生命周期也已统一走 `UIRouter`。 -- 但 `NodeEnter / NodeComplete` 仍是默认空载事件,没有附带当前 Run 节点信息。 -- 因此“固定 10 节点序列”已经在驱动流程,但还没有形成可观测、可追踪的正式节点上下文系统。 +- `NodeEnter / NodeComplete` 已带 `runId / nodeId / nodeType / sequenceIndex` 等基础字段,`NodeComplete` 也会回传成功状态与库存快照。 +- 当前缺的不是“有没有上下文字段”,而是更系统化的节点追踪、展示与统一收口能力。 关键文件: - `Assets/GameMain/Scripts/Procedure/FixedRunNodeSequenceBuilder.cs` @@ -144,7 +157,7 @@ - `Assets/GameMain/Scripts/Event/Game/NodeEnterEventArgs.cs` - `Assets/GameMain/Scripts/Event/Game/NodeCompleteEventArgs.cs` -### 3. 商店节点已纳入临时 Run 推进闭环,但回流目标仍是测试 Hub +### 3. 商店节点已纳入临时 Run 推进闭环,但回流目标仍是 MVP Hub - 现在可以单独打开商店、随机生成组件、购买并退出。 - 商店结束后已能通过 `ProcedureMain` 推进当前 `RunState`。 @@ -201,7 +214,7 @@ 结合静态代码检查,当前更接近下面这个状态: - `P0-04`:基础模型已完成,并已接入 `ProcedureMain + NodeMapForm` 的临时 Run 闭环。 -- `P0-05`:固定 10 节点序列已由 builder + `ProcedureMain + NodeMapForm` 驱动实际流程,但缺完整事件上下文与地图表现层。 +- `P0-05`:固定 10 节点序列已由 builder + `ProcedureMain + NodeMapForm` 驱动实际流程,基础事件上下文字段已接入,但缺更完整的地图表现层与正式上下文系统。 - `P0-06`:节点进入、完成、失败后回 `NodeMapForm` 的临时闭环已存在,但正式地图表现与正式结算仍未完成。 - `P0-10`:未完成。 - `P0-11`:未完成。 @@ -216,9 +229,9 @@ - 继续以 `NodeMapForm` 为基础补正式节点地图表现 - 至少补上节点连线、Boss 视觉强调、当前节点说明和完成态反馈 -2. 再把节点事件改成带上下文的真实推进 - - `NodeEnterEventArgs` 和 `NodeCompleteEventArgs` 传递 `runId / nodeId / nodeType / sequenceIndex` - - 节点完成后由流程层调用 `RunStateAdvanceService` +2. 再补齐节点上下文的消费、追踪与统一推进 + - 继续沿用 `NodeEnterEventArgs` 和 `NodeCompleteEventArgs` 现有的 `runId / nodeId / nodeType / sequenceIndex` + - 节点完成后统一由流程层调用 `RunStateAdvanceService` - 节点失败时明确是否停局、重试或返回菜单 3. 然后继续收口战斗关卡选择 @@ -236,6 +249,7 @@ ## 当前做变更时要记住的约束 - 不要再把 Hub 退回 `TestMenuForm` 语义。 +- 不要把菜单入口和主流程 Hub 混回同一个 Procedure;保持 `ProcedureMenu -> ProcedureMain` 的职责边界。 - 优先补“临时闭环 -> 正式节点 UI / 正式上下文”的收口,不要继续只加单点功能。 - 商店已经接入 Run,下一步重点不是继续扩商店,而是把 Hub/UI 做正式。 - 若 M1 最终不做完整耐久 / 红色品质,要先同步文档再改代码目标。 diff --git a/docs/CombatNodeArchitecture.md b/docs/CombatNodeArchitecture.md index 4a30bbc..4c474ab 100644 --- a/docs/CombatNodeArchitecture.md +++ b/docs/CombatNodeArchitecture.md @@ -68,8 +68,8 @@ - 上述状态类可以作为 `CombatScheduler` 的嵌套类实现,也可以拆成独立文件;但必须只服务于 `CombatScheduler` 状态机,不形成独立业务边界。 - 共享数据与共享服务统一收口到 `CombatScheduler` 内部持有的运行时承载体,不允许散落在各状态类中。 - 若 `CombatScheduler` 体量过大,允许在其内部实现中继续拆出: - - `CombatSchedulerRuntimeContext`:承载共享运行时字段与共享服务引用 - - `CombatSchedulerFlowCoordinator`:承载多个状态共用的流程辅助方法 + - `CombatSchedulerRuntime`:承载共享运行时字段与共享服务引用 + - `CombatSchedulerCoordinator`:承载多个状态共用的流程辅助方法 - 上述拆分只属于 `CombatScheduler` 的内部实现细化,不改变 `CombatScheduler` 作为唯一状态机边界的职责。 - 所有状态切换只能通过 `CombatScheduler.ChangeState(...)` 完成。 - 状态类不能彼此直接操控。 @@ -213,7 +213,23 @@ ## 4. 共享服务与推荐命名 -### 4.1 CombatLoadSession +### 4.1 命名后缀词典 + +- `Scheduler`:只用于状态机边界或阶段推进总控,例如 `CombatScheduler`。 +- `Manager`:只用于子域 Facade/聚合入口,例如 `EnemyManager`。 +- `Coordinator`:只用于跨状态、跨服务的流程编排,不持有独立业务真值。 +- `Service`:只用于聚焦业务行为,不承担框架事件桥接或异步句柄跟踪。 +- `Session`:只用于一次加载/交互过程的生命周期对象。 +- `Bridge`:只用于框架边界适配器。 +- `Runtime`:只用于运行时可变状态承载。 +- `Context`:只用于被动数据包或共享上下文。 +- `Result`:只用于动作输出或结算产出;若外围服务名已表达动作语义,不再重复动作前缀。 +- `Flags`:只用于聚合布尔控制项,不承载流程编排逻辑。 +- `Resolver`:只用于映射、查找、判定、解析职责。 +- `Tracker`:只用于跟踪运行中的实体或事实真值。 +- `Port`:只用于向内部状态或 use case 暴露的受限宿主接口。 + +### 4.2 CombatLoadSession 文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatLoadSession.cs` @@ -227,20 +243,20 @@ - 跟踪加载成功/失败状态。 - 对外提供 `CurrentMap` 与 `IsReady`。 -### 4.1.x CombatSchedulerRuntimeContext / CombatSchedulerFlowCoordinator(实现细化) +### 4.2.x CombatSchedulerRuntime / CombatSchedulerCoordinator(实现细化) 当前实现允许: -- 用 `CombatSchedulerRuntimeContext` 承载所有状态共享的运行时字段与共享服务引用。 -- 用 `CombatSchedulerFlowCoordinator` 承载多个状态共用的流程辅助逻辑。 +- 用 `CombatSchedulerRuntime` 承载所有状态共享的运行时字段与共享服务引用。 +- 用 `CombatSchedulerCoordinator` 承载多个状态共用的流程辅助逻辑。 约束: - 两者都必须由 `CombatScheduler` 持有并统一管理生命周期。 - 两者都不替代 `CombatScheduler` 对外暴露状态机边界。 -- `RuntimeContext` 不负责状态切换。 -- `FlowCoordinator` 不持有独立业务真值,只能围绕共享运行时做编排辅助。 -- 状态类只允许通过 `RuntimeContext + FlowCoordinator` 访问共享状态与共享流程,不应再直接耦合其他状态实现细节。 +- `Runtime` 不负责状态切换。 +- `Coordinator` 不持有独立业务真值,只能围绕共享运行时做编排辅助。 +- 状态类只允许通过 `Runtime + Coordinator` 访问共享状态与共享流程,不应再直接耦合其他状态实现细节。 -### 4.2 PhaseLoopRuntime +### 4.3 PhaseLoopRuntime 文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/PhaseLoopRuntime.cs` @@ -257,9 +273,9 @@ 约束: - 只做 phase 运行时数据管理,不直接切状态。 -### 4.3 CombatInRunResourceManager(推荐命名) +### 4.4 CombatRunResourceStore -当前相关文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatResourceManager.cs` +文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatRunResourceStore.cs` 目标职责: - 持有本局 `Coin` 真值。 @@ -280,9 +296,9 @@ - `Coin / BaseHp` 变化事件同时携带“当前值”和“变化量”。 - `Gold` 只是结算累计值,不要求战斗内实时事件驱动。 -### 4.4 EnemyDropResolver(推荐命名) +### 4.5 EnemyDropResolver -当前相关文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/CombatResourceManager.cs` +文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/CombatScheduler/EnemyDrop/EnemyDropResolver.cs` 目标职责: - 只负责敌人死亡后的掉落判定。 @@ -297,7 +313,7 @@ - 不直接修改资源状态。 - 不直接读取 `CombatNodeComponent`、`MapEntity`、`EnemyManager` 内部状态。 -### 4.5 IPhaseEndCondition(推荐命名) +### 4.6 IPhaseEndCondition 目标职责: - 作为 `PhaseEndType` 判定接口。 @@ -334,9 +350,9 @@ 生命周期: - 由 `CombatRunningPhaseState` 在状态进入/退出时初始化与重置。 -### 5.2 SpawnerResolver +### 5.2 EnemySpawnPathResolver -文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/SpawnerResolver.cs` +文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemySpawnPathResolver.cs` 职责: - 缓存当前地图可用 `Spawner`。 @@ -356,9 +372,9 @@ Boss 识别规则: - Boss 身份由 `DRLevelSpawnEntry.EntryType == Boss` 决定。 - 不由 `DREnemy` 自身类型决定。 -### 5.4 EnemyConfigService +### 5.4 EnemyConfigProvider -文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigService.cs` +文件:`Assets/GameMain/Scripts/CustomComponent/CombatNode/EnemyManager/EnemyConfigProvider.cs` 职责: - 读取 `DREnemy`。 @@ -436,6 +452,9 @@ Boss 识别规则: - 是否进入过奖励选择 - `FinishForm` 所需摘要数据 +命名约束: +- 结算上下文中的布尔控制项统一收口到 `Flags`,不再使用 `Flow` 命名。 + 奖励选择约束: - 满血奖励选择结果只写入结算上下文。 - 不直接写入局内资源管理器。 @@ -447,7 +466,7 @@ Boss 识别规则: 1. `CombatScheduler` 只做状态机管理与共享运行时收口,不继续吸收具体业务细节。 2. `CombatNodeComponent` 不再持有战斗内资源真值。 -3. 局内 `Coin / Gold / BaseHp / Loot Backpack / BuildTowerSnapshots` 以 `CombatInRunResourceManager` 为唯一真值来源。 +3. 局内 `Coin / Gold / BaseHp / Loot Backpack / BuildTowerSnapshots` 以 `CombatRunResourceStore` 为唯一真值来源。 4. 敌人死亡掉落判定以 `EnemyDropResolver` 为唯一判定入口。 5. 存活敌人数与 `HasAliveBoss` 以 `EnemyLifecycleTracker` 为唯一真值来源。 6. Phase 运行时信息与统一结束标记以 `PhaseLoopRuntime` 为唯一真值来源。 @@ -483,7 +502,7 @@ Boss 识别规则: ### 10.4 新增战斗内资源或建塔快照规则 -优先改 `CombatInRunResourceManager`,不要回流到 `CombatNodeComponent`。 +优先改 `CombatRunResourceStore`,不要回流到 `CombatNodeComponent`。 ### 10.5 新增地图/战斗基础 UI 加载规则