101 lines
4.0 KiB
C#
101 lines
4.0 KiB
C#
|
|
using System.Collections.Generic;
|
|||
|
|
using Cielonos.MainGame.Map;
|
|||
|
|
using Cielonos.MainGame.UI;
|
|||
|
|
using SLSUtilities.General;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
namespace Cielonos.MainGame
|
|||
|
|
{
|
|||
|
|
public partial class RunManager
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 管理一局 Run 的创建和销毁。
|
|||
|
|
/// 这里只负责 RunState 初始化、事件订阅入口和返回 Hub 的清理,不处理单个节点完成或奖励结算。
|
|||
|
|
/// </summary>
|
|||
|
|
public class RunSessionSubmodule : SubmoduleBase<RunManager>
|
|||
|
|
{
|
|||
|
|
public RunSessionSubmodule(RunManager owner) : base(owner)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void StartNewRun()
|
|||
|
|
{
|
|||
|
|
if (owner.mapConfig == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("[RunManager] mapConfig 未配置,无法开始 Run。");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
owner.progressSm.UnsubscribePlayerEvents();
|
|||
|
|
owner.combatSm.UnsubscribeRoomEvents();
|
|||
|
|
|
|||
|
|
Randomizer runRng = new Randomizer(MainGameManager.Seed);
|
|||
|
|
RunMapData mapData = MapGenerator.Generate(owner.mapConfig);
|
|||
|
|
if (mapData == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("[RunManager] 地图生成失败,无法开始 Run。");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
owner.currentRun = new RunState
|
|||
|
|
{
|
|||
|
|
randomizer = runRng,
|
|||
|
|
mapData = mapData,
|
|||
|
|
currentPosition = mapData.startPosition,
|
|||
|
|
visitedNodes = new HashSet<Vector2Int> { mapData.startPosition },
|
|||
|
|
exhaustedNodes = new HashSet<Vector2Int>(),
|
|||
|
|
completedNodes = new HashSet<Vector2Int>(),
|
|||
|
|
permanentlyRevealedNodes = new HashSet<Vector2Int>(),
|
|||
|
|
permanentlyRevealedTypes = new HashSet<MapNodeType>(),
|
|||
|
|
scoutRange = 1,
|
|||
|
|
elapsedTime = 0f,
|
|||
|
|
roomsCleared = 0,
|
|||
|
|
enemiesDefeated = 0,
|
|||
|
|
hurtCount = 0,
|
|||
|
|
isCompleted = false,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
owner.combatRewardSm.Clear();
|
|||
|
|
Debug.Log(
|
|||
|
|
$"[RunManager] 新一局开始(Seed: {runRng.Seed}),地图节点数:{mapData.totalNodes}," +
|
|||
|
|
$"起点:{mapData.startPosition},Boss:{mapData.bossPosition}");
|
|||
|
|
|
|||
|
|
PlayerCanvas.MainGamePages.mapPage.Populate(mapData);
|
|||
|
|
owner.progressSm.SubscribePlayerEvents();
|
|||
|
|
owner.combatSm.SubscribeRoomEvents();
|
|||
|
|
LoadStartZone(mapData);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void ReturnToHub()
|
|||
|
|
{
|
|||
|
|
owner.progressSm.UnsubscribePlayerEvents();
|
|||
|
|
owner.combatSm.UnsubscribeRoomEvents();
|
|||
|
|
owner.combatRewardSm.Clear();
|
|||
|
|
owner.currentRun = null;
|
|||
|
|
owner.phaseSm.TransitionToPhase(RunPhase.Idle);
|
|||
|
|
Debug.Log("[RunManager] 已返回 Hub,RunState 已清理。");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void LoadStartZone(RunMapData mapData)
|
|||
|
|
{
|
|||
|
|
RunMapNode startNode = mapData.nodes[mapData.startPosition];
|
|||
|
|
if (startNode.zoneData == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogWarning("[RunManager] 起点节点没有配置 ZoneData,直接进入地图选择。");
|
|||
|
|
owner.phaseSm.TransitionToPhase(RunPhase.MapSelection);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
owner.phaseSm.TransitionToPhase(RunPhase.Transitioning);
|
|||
|
|
ZoneSetupMode setupMode = RunNodeTypeUtility.ShouldStartBattleSetup(startNode, isCompleted: false)
|
|||
|
|
? ZoneSetupMode.CombatEncounter
|
|||
|
|
: ZoneSetupMode.EnvironmentOnly;
|
|||
|
|
MapManager.Instance.LoadZone(startNode.zoneData, onComplete: () =>
|
|||
|
|
{
|
|||
|
|
owner.phaseSm.TransitionToPhase(RunPhase.MapSelection);
|
|||
|
|
}, setupMode: setupMode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|