using System;
using System.Collections;
using Core;
using Gameplay.Enemy;
using Gameplay.Player;
using Interface;
using UnityEngine;
namespace Gameplay
{
///
/// 战斗流程管理器(回合制、循环抽牌)
/// 使用方法:在场景中挂载一个空物体并配置 player 与 enemy 的 Combatant 引用。
/// 该管理器通过事件回调让 UI 或其它系统接入“双方牌都打空时”的选择(继续/逃跑)。
///
public class CombatFlowManager : MonoSingleton
{
[Header("Participants")]
public PlayerController player;
public EnemyController enemy;
[Header("Flow Settings")]
[Tooltip("玩家是否先手(true=玩家先出一张)")]
public bool playerStarts = true;
[Tooltip("每出一张牌后的间隔(秒)")]
public float turnDelay = 0.8f;
// Events
public event Action OnCombatStarted;
public event Action OnCardPlayed;
public event Action OnCombatEnded; // 参数为胜利方(null 表示平局或逃跑)
public event Action OnBothEmpty; // 当双方都没有卡可以出时触发,UI 需要通过 ContinueAfterBothEmpty 或 EscapeFromCombat 响应
// internal state
private Coroutine runningRoutine;
private bool waitingForDecision = false;
private bool decisionContinue = false;
private bool decisionEscape = false;
///
/// 启动战斗流程(也可以在 Inspector 中提前绑定 player/enemy,然后只调用 StartCombat())
///
public void StartCombat(PlayerController playerController = null, EnemyController enemyController = null)
{
if (playerController != null) player = playerController;
if (enemyController != null) enemy = enemyController;
if (player == null || enemy == null)
{
Debug.LogError("CombatFlowManager: player 或 enemy 未设置。");
return;
}
// 初始化双方状态
player.StartCombat();
enemy.StartCombat();
player.InitializeDeckCycle();
enemy.InitializeDeckCycle();
runningRoutine = StartCoroutine(CombatRoutine());
OnCombatStarted?.Invoke();
}
public void StopCombat()
{
if (runningRoutine != null) StopCoroutine(runningRoutine);
runningRoutine = null;
}
private IEnumerator CombatRoutine()
{
ICharacter current = playerStarts ? player : enemy;
while (true)
{
// 结束检查
if (player.IsDead || enemy.IsDead)
{
ICharacter winner = player.IsDead ? enemy : player;
OnCombatEnded?.Invoke(winner);
runningRoutine = null;
yield break;
}
bool playerHas = player.HasCardsLeft();
bool enemyHas = enemy.HasCardsLeft();
if (!playerHas && !enemyHas)
{
// 双方都打空,等待玩家选择(由 UI 调用 ContinueAfterBothEmpty 或 EscapeFromCombat)
waitingForDecision = true;
decisionContinue = false;
decisionEscape = false;
OnBothEmpty?.Invoke();
// 等待选择
while (waitingForDecision)
yield return null;
if (decisionEscape)
{
// 玩家选择逃跑 -> 结束战斗,胜者设为 null(或按需要设成敌人/玩家)
OnCombatEnded?.Invoke(null);
runningRoutine = null;
yield break;
}
if (decisionContinue)
{
// 重新从卡册读取(重置抽牌队列),保持生命与其它状态不变
player.InitializeDeckCycle();
enemy.InitializeDeckCycle();
// 继续循环(当前先手不变)
yield return null;
continue;
}
}
// 当前回合:如果当前方没有牌则跳过(空过)
if (current.HasCardsLeft())
{
var card = current.GetNextCard();
ICharacter target;
if (current is PlayerController)
{
target = enemy;
}
else
{
target = player;
}
// 触发卡牌效果(当前仅支持直接伤害)
if (card != null)
{
card.PlayCard(new CardContext(current, target));
OnCardPlayed?.Invoke(current, card);
}
// 检查死亡(将在下一循环顶部处理)
yield return new WaitForSeconds(turnDelay);
}
else
{
// 跳过一轮,不延迟太久
yield return new WaitForSeconds(0.1f);
}
// 切换行动方
current = (current == player) ? enemy : player;
}
}
///
/// 当双方都打空时,UI 调用此方法选择继续下一轮(重新从卡册读取卡牌)
///
public void ContinueAfterBothEmpty()
{
if (!waitingForDecision) return;
decisionContinue = true;
waitingForDecision = false;
}
///
/// 当双方都打空时,UI 调用此方法选择逃跑
///
public void EscapeFromCombat()
{
if (!waitingForDecision) return;
decisionEscape = true;
waitingForDecision = false;
}
}
}