166 lines
5.7 KiB
C#
166 lines
5.7 KiB
C#
|
|
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;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|