150 lines
5.3 KiB
C#
150 lines
5.3 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using Cielonos.MainGame.Map;
|
|||
|
|
using Cielonos.MainGame.Rewards;
|
|||
|
|
using Sirenix.OdinInspector;
|
|||
|
|
using SLSUtilities.General;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
namespace Cielonos.MainGame
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 驱动整局 Roguelite Run 的会话管理器。
|
|||
|
|
/// 对外保持原有 RunManager API,对内将生命周期、节点流程、奖励、统计等职责拆分给 Submodule。
|
|||
|
|
/// </summary>
|
|||
|
|
public partial class RunManager : Singleton<RunManager>, ISubstructureOwner
|
|||
|
|
{
|
|||
|
|
[TitleGroup("配置")]
|
|||
|
|
[Tooltip("地图生成配置")]
|
|||
|
|
public MapGenerationConfig mapConfig;
|
|||
|
|
|
|||
|
|
[TitleGroup("运行时状态"), ReadOnly]
|
|||
|
|
public RunState currentRun;
|
|||
|
|
|
|||
|
|
[TitleGroup("运行时状态"), ReadOnly]
|
|||
|
|
public RunPhase currentPhase = RunPhase.Idle;
|
|||
|
|
|
|||
|
|
[ShowInInspector, FoldoutGroup("Submodules"), ReadOnly]
|
|||
|
|
private RunSessionSubmodule sessionSm;
|
|||
|
|
|
|||
|
|
[ShowInInspector, FoldoutGroup("Submodules"), ReadOnly]
|
|||
|
|
private RunPhaseSubmodule phaseSm;
|
|||
|
|
|
|||
|
|
[ShowInInspector, FoldoutGroup("Submodules"), ReadOnly]
|
|||
|
|
private RunNodeFlowSubmodule nodeFlowSm;
|
|||
|
|
|
|||
|
|
[ShowInInspector, FoldoutGroup("Submodules"), ReadOnly]
|
|||
|
|
private RunCombatSubmodule combatSm;
|
|||
|
|
|
|||
|
|
[ShowInInspector, FoldoutGroup("Submodules"), ReadOnly]
|
|||
|
|
private RunCombatRewardSubmodule combatRewardSm;
|
|||
|
|
|
|||
|
|
[ShowInInspector, FoldoutGroup("Submodules"), ReadOnly]
|
|||
|
|
private RunProgressSubmodule progressSm;
|
|||
|
|
|
|||
|
|
[ShowInInspector, FoldoutGroup("Submodules"), ReadOnly]
|
|||
|
|
private RunMapQuerySubmodule mapQuerySm;
|
|||
|
|
|
|||
|
|
public event Action<RunPhase> OnPhaseChanged;
|
|||
|
|
public event Action<Vector2Int> OnNodeSelected;
|
|||
|
|
public event Action<ZoneEntryContext> OnZoneEntered;
|
|||
|
|
public event Action<RunMapNode> OnCombatRoomCleared;
|
|||
|
|
public event Action<RunMapNode> OnNodeCompleted;
|
|||
|
|
public event Action<RunState> OnRunEnded;
|
|||
|
|
|
|||
|
|
protected override void Awake()
|
|||
|
|
{
|
|||
|
|
base.Awake();
|
|||
|
|
InitializeSubstructures();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void InitializeSubstructures()
|
|||
|
|
{
|
|||
|
|
InitializeSubmodules();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void InitializeSubmodules()
|
|||
|
|
{
|
|||
|
|
phaseSm ??= new RunPhaseSubmodule(this);
|
|||
|
|
combatRewardSm ??= new RunCombatRewardSubmodule(this);
|
|||
|
|
progressSm ??= new RunProgressSubmodule(this);
|
|||
|
|
combatSm ??= new RunCombatSubmodule(this);
|
|||
|
|
nodeFlowSm ??= new RunNodeFlowSubmodule(this);
|
|||
|
|
mapQuerySm ??= new RunMapQuerySubmodule(this);
|
|||
|
|
sessionSm ??= new RunSessionSubmodule(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void StartNewRun() => sessionSm.StartNewRun();
|
|||
|
|
|
|||
|
|
public void ReturnToHub() => sessionSm.ReturnToHub();
|
|||
|
|
|
|||
|
|
public void SelectNode(Vector2Int targetPosition) => nodeFlowSm.SelectNode(targetPosition);
|
|||
|
|
|
|||
|
|
public void CompleteCurrentNode() => nodeFlowSm.CompleteCurrentNode();
|
|||
|
|
|
|||
|
|
public void RegisterPendingCombatReward() => combatRewardSm.RegisterPendingCombatReward();
|
|||
|
|
|
|||
|
|
public void RegisterPendingCombatReward(Vector3 spawnPosition) =>
|
|||
|
|
combatRewardSm.RegisterPendingCombatReward(spawnPosition);
|
|||
|
|
|
|||
|
|
public bool TryCompletePendingCombatReward() => combatRewardSm.TryCompletePendingCombatReward();
|
|||
|
|
|
|||
|
|
public void AddCombatRewardModifier(ICombatRewardModifier modifier) =>
|
|||
|
|
combatRewardSm.AddCombatRewardModifier(modifier);
|
|||
|
|
|
|||
|
|
public CombatRewardSession GetActiveCombatRewardSession() => combatRewardSm.GetActiveCombatRewardSession();
|
|||
|
|
|
|||
|
|
public bool HasPendingCombatRewards => combatRewardSm.HasPendingCombatRewards;
|
|||
|
|
|
|||
|
|
public bool CanSelectMapNodes => mapQuerySm.CanSelectMapNodes;
|
|||
|
|
|
|||
|
|
public bool IsNormalCombatNode(MapNodeType nodeType) => RunNodeTypeUtility.IsNormalCombatNode(nodeType);
|
|||
|
|
|
|||
|
|
public bool IsCombatNode(MapNodeType nodeType) => RunNodeTypeUtility.IsCombatNode(nodeType);
|
|||
|
|
|
|||
|
|
public HashSet<Vector2Int> GetSelectablePositions() => mapQuerySm.GetSelectablePositions();
|
|||
|
|
|
|||
|
|
public Dictionary<Vector2Int, NodeDisplayState> GetAllNodeDisplayStates() =>
|
|||
|
|
mapQuerySm.GetAllNodeDisplayStates();
|
|||
|
|
|
|||
|
|
public bool IsNodeExhausted(Vector2Int position) => mapQuerySm.IsNodeExhausted(position);
|
|||
|
|
|
|||
|
|
public void IncreaseScoutRange(int amount) => mapQuerySm.IncreaseScoutRange(amount);
|
|||
|
|
|
|||
|
|
public void RevealNode(Vector2Int position) => mapQuerySm.RevealNode(position);
|
|||
|
|
|
|||
|
|
public void RevealNodeType(MapNodeType nodeType) => mapQuerySm.RevealNodeType(nodeType);
|
|||
|
|
|
|||
|
|
private void Update()
|
|||
|
|
{
|
|||
|
|
progressSm.TickElapsedTime();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
internal void RaisePhaseChanged(RunPhase phase) => OnPhaseChanged?.Invoke(phase);
|
|||
|
|
|
|||
|
|
internal void RaiseNodeSelected(Vector2Int position) => OnNodeSelected?.Invoke(position);
|
|||
|
|
|
|||
|
|
internal void RaiseZoneEntered(ZoneEntryContext context) => OnZoneEntered?.Invoke(context);
|
|||
|
|
|
|||
|
|
internal void RaiseCombatRoomCleared(RunMapNode node) => OnCombatRoomCleared?.Invoke(node);
|
|||
|
|
|
|||
|
|
internal void RaiseNodeCompleted(RunMapNode node) => OnNodeCompleted?.Invoke(node);
|
|||
|
|
|
|||
|
|
internal void RaiseRunEnded(RunState run) => OnRunEnded?.Invoke(run);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public enum RunPhase
|
|||
|
|
{
|
|||
|
|
Idle,
|
|||
|
|
MapSelection,
|
|||
|
|
Transitioning,
|
|||
|
|
InCombat,
|
|||
|
|
InShop,
|
|||
|
|
InRest,
|
|||
|
|
InMechanical,
|
|||
|
|
InBoss,
|
|||
|
|
InEvent,
|
|||
|
|
Settlement,
|
|||
|
|
}
|
|||
|
|
}
|