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

106 lines
4.5 KiB
C#
Raw Permalink 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.Collections.Generic;
using Cielonos.MainGame.Characters;
using Cielonos.MainGame.Rewards;
using UnityEngine;
namespace Cielonos.MainGame
{
public partial class RunManager
{
/// <summary>
/// CombatRoom 到 Run 流程的桥接层。
/// CombatRoomSubmodule 只负责报告“战斗清空”,这里负责判断当前节点是否合法、生成 CombatRewardSession 并推动节点完成。
/// </summary>
public class RunCombatSubmodule : SubmoduleBase<RunManager>
{
public RunCombatSubmodule(RunManager owner) : base(owner)
{
}
public void SubscribeRoomEvents()
{
// RunManager 是战斗结果进入 Run 流程的唯一入口,避免 UI/奖励系统重复解释 CombatRoom 事件。
CombatManager.CombatRoomSm.OnRoomCleared += OnRoomCleared;
CombatManager.CombatRoomSm.OnEnemyDefeated += OnEnemyDefeated;
}
public void UnsubscribeRoomEvents()
{
if (CombatManager.Instance == null || CombatManager.CombatRoomSm == null)
{
return;
}
CombatManager.CombatRoomSm.OnRoomCleared -= OnRoomCleared;
CombatManager.CombatRoomSm.OnEnemyDefeated -= OnEnemyDefeated;
}
private void OnEnemyDefeated(CharacterBase enemy)
{
owner.progressSm.RecordEnemyDefeated(enemy);
EnemyDefeatRewardDispatcher.Dispatch(enemy, owner.currentRun?.randomizer?.Channel("EnemyDrop"));
}
private void OnRoomCleared()
{
if (owner.currentRun == null) return;
if (!owner.currentRun.mapData.nodes.TryGetValue(owner.currentRun.currentPosition, out RunMapNode node))
{
return;
}
if (!RunNodeTypeUtility.IsCombatNode(node.nodeType))
{
// 起点或非战斗节点不应该因为空房间触发 Run 完成逻辑。
Debug.LogWarning($"[RunManager] Ignored OnRoomCleared because current node is not a Combat node: {node.nodeType}.");
return;
}
owner.RaiseCombatRoomCleared(node);
if (owner.currentRun.currentPosition == owner.currentRun.mapData.bossPosition)
{
Debug.Log("[RunManager] Boss 房间已清空,等待玩家交互并离开。");
owner.phaseSm.TransitionToPhase(RunPhase.MapSelection);
return;
}
CombatRewardContext rewardContext = new CombatRewardContext(
owner.currentRun,
node,
owner.currentRun.currentPosition,
owner.currentRun.randomizer?.Next() ?? new System.Random());
// 奖励结算分三步:建立 session、解析配置、让装备/被动修正奖励列表。
owner.combatRewardSm.BeginCombatRewardSession(rewardContext);
List<CombatRewardInstruction> rewards =
CombatRewardResolver.Resolve(MainGameManager.Config?.combatRewardProfile, rewardContext);
owner.combatRewardSm.ApplyCombatRewardModifiers(rewardContext, rewards);
bool hasInteractableReward = RunCombatRewardSubmodule.HasInteractableCombatReward(rewards);
if (hasInteractableReward)
{
owner.phaseSm.TransitionToPhase(RunPhase.MapSelection);
}
bool hasPendingReward = rewards.Count > 0 && CombatRewardDispatcher.Dispatch(rewardContext, rewards);
owner.combatRewardSm.NotifyCombatRewardDispatched(rewardContext);
if (hasPendingReward)
{
Debug.Log($"[RunManager] Combat 房间已清空,生成 {owner.combatRewardSm.PendingCount} 个待领取奖励。");
return;
}
if (hasInteractableReward)
{
Debug.LogWarning("[RunManager] Combat 奖励规则包含交互奖励,但没有成功生成任何待领取奖励。");
}
Debug.Log("[RunManager] 收到 OnRoomCleared完成当前 Combat 节点。");
owner.combatRewardSm.CompleteCombatRewardSessionIfEmpty();
}
}
}
}