135 lines
6.6 KiB
C#
135 lines
6.6 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Continentis.MainGame.Card;
|
||
using Continentis.MainGame.Character;
|
||
using DG.Tweening;
|
||
using SLSFramework.General;
|
||
using UniRx;
|
||
using UnityEngine;
|
||
using Random = UnityEngine.Random;
|
||
|
||
namespace Continentis.MainGame.Commands
|
||
{
|
||
public class Cmd_DrawCards : CommandBase
|
||
{
|
||
private readonly DeckSubmodule deck;
|
||
|
||
private readonly bool isCustomDraw;
|
||
private readonly int drawCount;
|
||
private readonly float interval;
|
||
private readonly float singleCardAnimationDuration = 0.5f; // 单张卡牌的动画时长
|
||
|
||
private readonly List<CardInstance> customDrawCards;
|
||
|
||
public Cmd_DrawCards(DeckSubmodule deck, int drawCount, float interval = 0.1f)
|
||
{
|
||
this.isCustomDraw = false;
|
||
this.deck = deck;
|
||
this.drawCount = drawCount;
|
||
this.interval = interval;
|
||
this.customDrawCards = null;
|
||
}
|
||
|
||
public Cmd_DrawCards(DeckSubmodule deck, List<CardInstance> customDrawCards, float interval = 0.1f)
|
||
{
|
||
this.isCustomDraw = true;
|
||
this.deck = deck;
|
||
this.drawCount = customDrawCards.Count;
|
||
this.interval = interval;
|
||
this.customDrawCards = customDrawCards;
|
||
}
|
||
|
||
protected override IObservable<Unit> OnExecute(CommandContext outerContext)
|
||
{
|
||
if (!isCustomDraw)
|
||
{
|
||
// 确定最终能抽的数量
|
||
int finalDrawCount = Mathf.Min(drawCount, deck.DrawPile.Count);
|
||
|
||
if (finalDrawCount <= 0)
|
||
{
|
||
Debug.Log("无牌可抽。");
|
||
outerContext.context["DrawnCards"] = new List<CardLogicBase>();
|
||
return Observable.Return(Unit.Default);
|
||
}
|
||
else
|
||
{
|
||
Debug.Log($"最终抽取 {finalDrawCount} 张卡牌。");
|
||
}
|
||
|
||
// 从抽牌堆顶部取出卡牌
|
||
List<CardInstance> drawnCards = deck.DrawPile.Take(finalDrawCount).ToList();
|
||
|
||
// --- 关键:将结果存入上下文 ---
|
||
// 这替代了 'out' 参数,让后续指令可以访问到这次抽到的牌。
|
||
outerContext.context["DrawnCards"] = drawnCards;
|
||
Debug.Log($"抽取 {drawnCards.Count} 张卡牌,并将列表存入DrawnCards。");
|
||
|
||
|
||
// --- 2. 异步的动画阶段 ---
|
||
|
||
// 创建一个交错的动画流,和我们修正后的 Cmd_DiscardCards 完全一样
|
||
return drawnCards.ToObservable()
|
||
.Zip(Observable.Interval(TimeSpan.FromSeconds(interval)), (card, _) => card)
|
||
// 使用 Select 将每个 card 和它的索引传递给动画方法
|
||
.Select((card, index) => Draw(index, drawnCards.Count))
|
||
.Merge() // 并行执行所有交错开始的动画
|
||
.Last() // 等待最后一个动画流完成
|
||
.AsUnitObservable();
|
||
}
|
||
else
|
||
{
|
||
outerContext.context["DrawnCards"] = customDrawCards;
|
||
Debug.Log($"抽取 {customDrawCards.Count} 张指定卡牌,并将列表存入DrawnCards。");
|
||
return customDrawCards.ToObservable()
|
||
.Zip(Observable.Interval(TimeSpan.FromSeconds(interval)), (card, _) => card)
|
||
// 使用 Select 将每个 card 和它的索引传递给动画方法
|
||
.Select((card, index) => Draw(card, index, customDrawCards.Count))
|
||
.Merge() // 并行执行所有交错开始的动画
|
||
.Last() // 等待最后一个动画流完成
|
||
.AsUnitObservable();
|
||
}
|
||
}
|
||
|
||
private IObservable<Unit> Draw(int index, int totalCount)
|
||
{
|
||
CardInstance card = deck.DrawPile[0];
|
||
|
||
deck.TransferCard(deck.DrawPile, deck.HandPile, card);
|
||
card.cardLogic.eventSubmodule.onDraw.Invoke();
|
||
card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.handPile);
|
||
|
||
Vector3 targetPosition = CombatUIManager.Instance.combatMainPage.handPile.GetCardPosition(index, totalCount);
|
||
Quaternion targetRotation = CombatUIManager.Instance.combatMainPage.handPile.GetCardRotation(index, totalCount);
|
||
Vector3 deltaMove = targetPosition - card.handCardView.cardTransform.localPosition;
|
||
Vector3 randomLift = new Vector3(Random.Range(-200f, 200f), Random.Range(200f, 600f), 0);
|
||
|
||
card.handCardView.cardTransform.DOBlendableLocalMoveBy(deltaMove, singleCardAnimationDuration).Play();
|
||
card.handCardView.cardTransform.DOBlendableLocalMoveBy(randomLift, singleCardAnimationDuration * 0.5f).SetLoops(2, LoopType.Yoyo).Play();
|
||
card.handCardView.cardTransform.DOLocalRotateQuaternion(targetRotation, singleCardAnimationDuration).Play();
|
||
card.handCardView.cardTransform.DOScale(Vector3.one, singleCardAnimationDuration).Play();
|
||
|
||
return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable();
|
||
}
|
||
|
||
private IObservable<Unit> Draw(CardInstance card, int index, int totalCount)
|
||
{
|
||
deck.TransferCard(card.cardLocation.pileName, "Hand", card);
|
||
card.cardLogic.eventSubmodule.onDraw.Invoke();
|
||
card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.handPile);
|
||
|
||
Vector3 targetPosition = CombatUIManager.Instance.combatMainPage.handPile.GetCardPosition(index, totalCount);
|
||
Quaternion targetRotation = CombatUIManager.Instance.combatMainPage.handPile.GetCardRotation(index, totalCount);
|
||
Vector3 deltaMove = targetPosition - card.handCardView.cardTransform.localPosition;
|
||
Vector3 randomLift = new Vector3(Random.Range(-200f, 200f), Random.Range(200f, 600f), 0);
|
||
|
||
card.handCardView.cardTransform.DOBlendableLocalMoveBy(deltaMove, singleCardAnimationDuration).Play();
|
||
card.handCardView.cardTransform.DOBlendableLocalMoveBy(randomLift, singleCardAnimationDuration * 0.5f).SetLoops(2, LoopType.Yoyo).Play();
|
||
card.handCardView.cardTransform.DOLocalRotateQuaternion(targetRotation, singleCardAnimationDuration).Play();
|
||
card.handCardView.cardTransform.DOScale(Vector3.one, singleCardAnimationDuration).Play();
|
||
|
||
return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable();
|
||
}
|
||
}
|
||
} |