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

166 lines
5.7 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.Rewards;
using UnityEngine;
namespace Cielonos.MainGame
{
public partial class RunManager
{
/// <summary>
/// 管理一次 Combat 节点清空后的奖励会话。
/// 它记录待领取交互奖励数量,并集中处理装备/被动对奖励列表的临时修正。
/// </summary>
public class RunCombatRewardSubmodule : SubmoduleBase<RunManager>
{
private CombatRewardSession _combatRewardSession;
private readonly List<ICombatRewardModifier> _combatRewardModifiers = new();
public RunCombatRewardSubmodule(RunManager owner) : base(owner)
{
}
public bool HasPendingCombatRewards =>
_combatRewardSession != null && _combatRewardSession.IsActive && _combatRewardSession.PendingCount > 0;
public int PendingCount => _combatRewardSession?.PendingCount ?? 0;
public void RegisterPendingCombatReward()
{
Debug.LogWarning("[RunManager] RegisterPendingCombatReward() is obsolete. Use RegisterPendingCombatReward(Vector3).");
}
public void RegisterPendingCombatReward(Vector3 spawnPosition)
{
if (_combatRewardSession == null || !_combatRewardSession.IsActive)
{
Debug.LogWarning("[RunManager] 没有可用的 CombatRewardSession无法登记待领取奖励。");
return;
}
// Interactable 奖励生成后必须登记RunManager 才能阻止玩家在领取前前往下一个节点。
_combatRewardSession.RegisterPendingReward(spawnPosition);
}
public bool TryCompletePendingCombatReward()
{
if (_combatRewardSession == null || !_combatRewardSession.IsActive)
{
return false;
}
if (!_combatRewardSession.ResolvePendingReward())
{
return false;
}
if (_combatRewardSession.PendingCount <= 0)
{
// 所有待领取奖励处理完毕后Combat 节点才真正进入完成状态。
Clear();
owner.nodeFlowSm.CompleteCurrentNode();
}
return true;
}
public void AddCombatRewardModifier(ICombatRewardModifier modifier)
{
if (modifier == null || _combatRewardModifiers.Contains(modifier))
{
return;
}
_combatRewardModifiers.Add(modifier);
}
public CombatRewardSession GetActiveCombatRewardSession()
{
return _combatRewardSession != null && _combatRewardSession.IsActive ? _combatRewardSession : null;
}
public void Clear()
{
_combatRewardSession?.End();
_combatRewardSession = null;
_combatRewardModifiers.Clear();
}
public void BeginCombatRewardSession(CombatRewardContext context)
{
_combatRewardSession?.End();
_combatRewardSession = new CombatRewardSession(context);
}
public void ApplyCombatRewardModifiers(CombatRewardContext context, List<CombatRewardInstruction> rewards)
{
for (int i = _combatRewardModifiers.Count - 1; i >= 0; i--)
{
ICombatRewardModifier modifier = _combatRewardModifiers[i];
if (modifier == null || modifier.IsExpired)
{
_combatRewardModifiers.RemoveAt(i);
continue;
}
modifier.Modify(context, rewards);
}
}
public void NotifyCombatRewardDispatched(CombatRewardContext context)
{
for (int i = _combatRewardModifiers.Count - 1; i >= 0; i--)
{
ICombatRewardModifier modifier = _combatRewardModifiers[i];
if (modifier == null)
{
_combatRewardModifiers.RemoveAt(i);
continue;
}
modifier.OnDispatched(context);
if (modifier.IsExpired)
{
_combatRewardModifiers.RemoveAt(i);
}
}
}
public bool CompleteCombatRewardSessionIfEmpty()
{
if (_combatRewardSession == null || !_combatRewardSession.IsActive)
{
return false;
}
if (_combatRewardSession.PendingCount > 0)
{
return true;
}
_combatRewardSession.End();
_combatRewardSession = null;
owner.nodeFlowSm.CompleteCurrentNode();
return true;
}
public static bool HasInteractableCombatReward(IReadOnlyList<CombatRewardInstruction> rewards)
{
if (rewards == null)
{
return false;
}
foreach (CombatRewardInstruction reward in rewards)
{
if (reward != null && reward.UsesInteractable && reward.count > 0)
{
return true;
}
}
return false;
}
}
}
}