Files
Cielonos/Assets/Scripts/MainGame/GameRun/RunManager/RunManager.cs
SoulliesOfficial 39b43680a9 爆更
2026-07-18 03:16:20 -04:00

150 lines
5.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
}
}