Files
Continentis/Assets/Scripts/MainGame/Commands/Cmd_UsePowerCards.cs
SoulliesOfficial 5fe665d0ce Card爆改!
2025-11-15 12:17:34 -05:00

96 lines
4.2 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_UsePowerCards : CommandBase
{
private bool isPlayer;
private readonly DeckSubmodule deck;
private readonly List<CardInstance> cardsToUse;
private readonly float interval;
private readonly float singleCardAnimationDuration = 0.5f; // 单张卡牌的动画时长
public Cmd_UsePowerCards(bool isPlayer, DeckSubmodule deck, List<CardInstance> cards, float interval)
{
this.isPlayer = isPlayer;
this.deck = deck;
this.cardsToUse = cards;
this.interval = interval;
}
protected override IObservable<Unit> OnExecute(CommandContext outerContext)
{
if (cardsToUse == null || cardsToUse.Count == 0)
{
return Observable.Return(Unit.Default);
}
Func<CardInstance, IObservable<Unit>> exhaustAction = isPlayer ? PlayerUsePowers : NpcUsePowers;
// --- 情况1并行丢弃 (所有卡牌动画同时开始) ---
if (interval <= 0f)
{
// 为每张卡牌创建一个“懒加载”的丢弃动画流。
var allDiscardAnimations = cardsToUse.Select(card =>
Observable.Defer(() => exhaustAction(card))
);
// 使用 WhenAll 等待所有的并行任务都完成。
// 只有当最后一个动画结束时WhenAll 才会发出完成信号。
return Observable.WhenAll(allDiscardAnimations).AsUnitObservable();
}
// --- 情况2交错丢弃 (按固定间隔开始动画) ---
else
{
var cardStream = cardsToUse.ToObservable();
var timerStream = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(interval));
return timerStream
.Zip(cardStream, (_, card) => card)
// 核心:不再使用 .Do(..).Subscribe(),而是使用 Select 将每个 card 转换为
// 其对应的动画流。这样主流程就“知道”了每个动画的存在。
.Select(card => exhaustAction(card))
// 使用 Merge 将所有交错开始的动画流合并为一个流。
// Merge 会同时运行所有这些动画,并在最后一个动画也完成时,它才会完成。
.Merge()
// 使用 Last 来确保我们只在整个 Merge 流全部结束后,才发出最终的完成信号。
.Last()
.AsUnitObservable();
}
}
private IObservable<Unit> PlayerUsePowers(CardInstance card)
{
deck.TransferCard(deck.Pile(card.cardLocation.pileName), deck.GravePile, card);
card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.gravePile);
RectTransform cardTransform = card.handCardView.cardTransform;
Vector2 userViewPosition = card.user.characterView.hudContainer.GetComponent<RectTransform>().position;
cardTransform.DOMove(userViewPosition, singleCardAnimationDuration).SetEase(Ease.Linear).Play();
cardTransform.DOScale(Vector3.zero, singleCardAnimationDuration).SetEase(Ease.Linear).OnComplete(() =>
{
cardTransform.anchoredPosition = Vector2.zero;
}).Play();
return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable();
}
private IObservable<Unit> NpcUsePowers(CardInstance card)
{
deck.TransferCard(deck.Pile(card.cardLocation.pileName), deck.GravePile, card);
return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable();
}
}
}