using System.Collections.Generic;
using Cielonos.MainGame.Rewards;
using UnityEngine;
namespace Cielonos.MainGame
{
public partial class RunManager
{
///
/// 管理一次 Combat 节点清空后的奖励会话。
/// 它记录待领取交互奖励数量,并集中处理装备/被动对奖励列表的临时修正。
///
public class RunCombatRewardSubmodule : SubmoduleBase
{
private CombatRewardSession _combatRewardSession;
private readonly List _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 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 rewards)
{
if (rewards == null)
{
return false;
}
foreach (CombatRewardInstruction reward in rewards)
{
if (reward != null && reward.UsesInteractable && reward.count > 0)
{
return true;
}
}
return false;
}
}
}
}