Files
Continentis/Assets/Scripts/MainGame/Commands/Cmd_DrawCards.cs
SoulliesOfficial 76157e3cb1 继续
2025-10-24 09:11:22 -04:00

135 lines
6.6 KiB
C#
Raw 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;
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();
}
}
}