247 lines
10 KiB
C#
247 lines
10 KiB
C#
using System;
|
||
using System.Linq;
|
||
using System.Collections.Generic;
|
||
using Continentis.MainGame.Card;
|
||
using Continentis.MainGame.Commands;
|
||
using SLSFramework.General;
|
||
using UnityEngine;
|
||
|
||
namespace Continentis.MainGame.Character
|
||
{
|
||
public partial class DeckSubmodule : SubmoduleBase<CharacterBase>
|
||
{
|
||
public Dictionary<string, List<CardInstance>> piles;
|
||
|
||
public DeckSubmodule(CharacterBase character) : base(character)
|
||
{
|
||
piles = new Dictionary<string, List<CardInstance>>
|
||
{
|
||
{ Piles.Storage, new List<CardInstance>() },
|
||
{ Piles.Hand, new List<CardInstance>() },
|
||
{ Piles.Draw, new List<CardInstance>() },
|
||
{ Piles.Discard, new List<CardInstance>() },
|
||
{ Piles.Exhaust, new List<CardInstance>() },
|
||
{ Piles.Grave, new List<CardInstance>() },
|
||
{ Piles.Pool, new List<CardInstance>() },
|
||
{ Piles.Intention, new List<CardInstance>() }
|
||
};
|
||
}
|
||
}
|
||
|
||
public partial class DeckSubmodule
|
||
{
|
||
public void SetUpHandCardViews()
|
||
{
|
||
DrawPile.ForEach(card => card.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.drawPile));
|
||
HandPile.ForEach(card =>
|
||
{
|
||
if (!card.playSubmodule.isDuringPlayEffect)
|
||
card.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.handPile);
|
||
});
|
||
DiscardPile.ForEach(c => c.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.discardPile));
|
||
ExhaustPile.ForEach(c => c.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.exhaustPile));
|
||
}
|
||
|
||
/// <summary>抽取指定数量的卡牌,返回一个包含抽牌指令的指令组。</summary>
|
||
public CommandGroup DrawCards(int cardCount, float interval = 0.1f)
|
||
{
|
||
if (owner.statusSubmodule.HasStatus(StatusType.Heavy))
|
||
{
|
||
MainGameManager.GenerateInfoText("Heavy: Can not draw cards", owner.characterView);
|
||
return new CommandGroup(ExecutionMode.Sequential);
|
||
}
|
||
|
||
if (cardCount > DrawPile.Count && DiscardPile.Count > 0)
|
||
{
|
||
//Debug.Log("抽牌堆牌数不足,且弃牌堆有牌,正在洗牌...");
|
||
ReshuffleDeck();
|
||
}
|
||
|
||
//Debug.Log($"准备抽取 {cardCount} 张卡牌。");
|
||
|
||
return new CommandGroup(ExecutionMode.Sequential,
|
||
new Cmd_DrawCards(this, cardCount, interval),
|
||
Cmd.Do(() =>
|
||
{
|
||
// TODO: 抽牌后的处理(DrawnCards 可从 groupContext 中读取)
|
||
}));
|
||
}
|
||
|
||
/// <summary>从指令组的上下文中获取抽到的卡牌列表。</summary>
|
||
public List<CardInstance> GetDrawnCards(CommandGroup drawCardsGroup)
|
||
{
|
||
if (drawCardsGroup.groupContext.TryGet(CommandContextKeys.DrawnCards, out List<CardInstance> cards))
|
||
return cards;
|
||
|
||
//Debug.LogWarning("[DeckSubmodule] groupContext 中未找到 DrawnCards。");
|
||
return new List<CardInstance>();
|
||
}
|
||
|
||
/// <summary>打出指定卡牌。</summary>
|
||
public void PlayCard(CardInstance card, List<CharacterBase> targetList)
|
||
{
|
||
card.Play(targetList, owner);
|
||
}
|
||
|
||
/// <summary>主动弃置单张卡牌,返回包含弃牌指令的指令组。</summary>
|
||
public CommandGroup DiscardCard(CardInstance card, bool initiative, float interval = 0.1f)
|
||
{
|
||
return new CommandGroup(ExecutionMode.Sequential,
|
||
new Cmd_DiscardCards(card.deck, new List<CardInstance> { card }, initiative, interval),
|
||
Cmd.Do(() =>
|
||
{
|
||
CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team);
|
||
}));
|
||
}
|
||
|
||
/// <summary>主动弃置多张卡牌(按所属 deck 分组),返回包含弃牌指令的指令组。</summary>
|
||
public CommandGroup DiscardCards(List<CardInstance> cards, bool initiative, float interval = 0.1f)
|
||
{
|
||
var groupedCards = cards.GroupBy(card => card.deck)
|
||
.ToDictionary(g => g.Key, g => g.ToList());
|
||
|
||
var group = new CommandGroup(ExecutionMode.Sequential);
|
||
foreach (var kvp in groupedCards)
|
||
group.AddCommand(new Cmd_DiscardCards(kvp.Key, kvp.Value, initiative, interval));
|
||
|
||
group.AddCommand(Cmd.Do(() =>
|
||
{
|
||
CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team);
|
||
}));
|
||
|
||
return group;
|
||
}
|
||
|
||
/// <summary>消耗单张卡牌,返回包含消耗指令的指令组。</summary>
|
||
public CommandGroup ExhaustCard(CardInstance card, float interval = 0.1f)
|
||
{
|
||
return new CommandGroup(ExecutionMode.Sequential,
|
||
new Cmd_ExhaustCards(owner is PlayerHero, card.deck, new List<CardInstance> { card }, interval),
|
||
Cmd.Do(() =>
|
||
{
|
||
CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team);
|
||
}));
|
||
}
|
||
|
||
/// <summary>消耗多张卡牌(按所属 deck 分组),返回包含消耗指令的指令组。</summary>
|
||
public CommandGroup ExhaustCards(List<CardInstance> cards, float interval = 0.1f)
|
||
{
|
||
var groupedCards = cards.GroupBy(card => card.deck)
|
||
.ToDictionary(g => g.Key, g => g.ToList());
|
||
|
||
var group = new CommandGroup(ExecutionMode.Sequential);
|
||
foreach (var kvp in groupedCards)
|
||
group.AddCommand(new Cmd_ExhaustCards(owner is PlayerHero, kvp.Key, kvp.Value, interval));
|
||
|
||
group.AddCommand(Cmd.Do(() =>
|
||
{
|
||
CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team);
|
||
}));
|
||
|
||
return group;
|
||
}
|
||
|
||
/// <summary>使用单张力量牌,返回包含使用指令的指令组。</summary>
|
||
public CommandGroup UsePowerCard(CardInstance card, float interval = 0.1f)
|
||
{
|
||
return new CommandGroup(ExecutionMode.Sequential,
|
||
new Cmd_UsePowerCards(owner is PlayerHero, card.deck, new List<CardInstance> { card }, interval),
|
||
Cmd.Do(() =>
|
||
{
|
||
CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team);
|
||
}));
|
||
}
|
||
|
||
/// <summary>使用多张力量牌(按所属 deck 分组),返回包含使用指令的指令组。</summary>
|
||
public CommandGroup UsePowerCards(List<CardInstance> cards, float interval = 0.1f)
|
||
{
|
||
var groupedCards = cards.GroupBy(card => card.deck)
|
||
.ToDictionary(g => g.Key, g => g.ToList());
|
||
|
||
var group = new CommandGroup(ExecutionMode.Sequential);
|
||
foreach (var kvp in groupedCards)
|
||
group.AddCommand(new Cmd_UsePowerCards(owner is PlayerHero, kvp.Key, kvp.Value, interval));
|
||
|
||
group.AddCommand(Cmd.Do(() =>
|
||
{
|
||
CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team);
|
||
}));
|
||
|
||
return group;
|
||
}
|
||
|
||
/// <summary>将弃牌堆重新洗入抽牌堆,直接加入全局命令队列。</summary>
|
||
public void ReshuffleDeck(float interval = 0.1f)
|
||
{
|
||
CommandQueueManager.Instance.AddCommand(new Cmd_ReshuffleDeck(this, interval));
|
||
}
|
||
}
|
||
|
||
public partial class DeckSubmodule
|
||
{
|
||
public KeyValuePair<string, List<CardInstance>> GetCardLocation(CardInstance card, out int index)
|
||
{
|
||
index = -1;
|
||
foreach (var pile in piles)
|
||
{
|
||
index = pile.Value.IndexOf(card);
|
||
if (index != -1)
|
||
return pile;
|
||
}
|
||
throw new Exception("Card not found in any pile.");
|
||
}
|
||
|
||
/// <summary>将卡牌移动到指定牌堆的指定位置。</summary>
|
||
public void TransferCard(string pileName, int index, CardInstance card)
|
||
{
|
||
Pile(pileName).Transfer(card, index);
|
||
card.cardLocation = new CardLocation(pileName, index);
|
||
}
|
||
|
||
/// <summary>将卡牌从一个牌堆移动到另一个牌堆(按名称)。</summary>
|
||
public void TransferCard(string fromPileName, string toPileName, CardInstance card)
|
||
{
|
||
List<CardInstance> fromPile = Pile(fromPileName);
|
||
List<CardInstance> toPile = Pile(toPileName);
|
||
fromPile.Transfer(toPile, card);
|
||
card.cardLocation = new CardLocation(toPileName, toPile.IndexOf(card));
|
||
}
|
||
|
||
/// <summary>将卡牌从一个牌堆移动到另一个牌堆(按引用)。</summary>
|
||
public void TransferCard(List<CardInstance> fromPile, List<CardInstance> toPile, CardInstance card)
|
||
{
|
||
fromPile.Transfer(toPile, card);
|
||
card.cardLocation = new CardLocation(GetCardLocation(card, out _).Key, toPile.IndexOf(card));
|
||
}
|
||
|
||
/// <summary>返回所有牌堆中的所有卡牌。</summary>
|
||
public List<CardInstance> GetAllCards()
|
||
{
|
||
var allCards = new List<CardInstance>();
|
||
foreach (var pile in piles)
|
||
allCards.AddRange(pile.Value);
|
||
return allCards;
|
||
}
|
||
}
|
||
|
||
public partial class DeckSubmodule
|
||
{
|
||
/// <summary>按名称获取牌堆,不存在时抛出 KeyNotFoundException。</summary>
|
||
public List<CardInstance> Pile(string pileName)
|
||
{
|
||
if (piles.TryGetValue(pileName, out List<CardInstance> pile))
|
||
return pile;
|
||
throw new KeyNotFoundException($"Pile '{pileName}' not found.");
|
||
}
|
||
|
||
public List<CardInstance> StoragePile => Pile(Piles.Storage);
|
||
public List<CardInstance> HandPile => Pile(Piles.Hand);
|
||
public List<CardInstance> DrawPile => Pile(Piles.Draw);
|
||
public List<CardInstance> DiscardPile => Pile(Piles.Discard);
|
||
public List<CardInstance> ExhaustPile => Pile(Piles.Exhaust);
|
||
public List<CardInstance> GravePile => Pile(Piles.Grave);
|
||
public List<CardInstance> PoolPile => Pile(Piles.Pool);
|
||
public List<CardInstance> IntentionPile => Pile(Piles.Intention);
|
||
}
|
||
}
|