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 { public Dictionary> piles; public DeckSubmodule(CharacterBase character) : base(character) { piles = new Dictionary> { { Piles.Storage, new List() }, { Piles.Hand, new List() }, { Piles.Draw, new List() }, { Piles.Discard, new List() }, { Piles.Exhaust, new List() }, { Piles.Grave, new List() }, { Piles.Pool, new List() }, { Piles.Intention, new List() } }; } } 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)); } /// 抽取指定数量的卡牌,返回一个包含抽牌指令的指令组。 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 中读取) })); } /// 从指令组的上下文中获取抽到的卡牌列表。 public List GetDrawnCards(CommandGroup drawCardsGroup) { if (drawCardsGroup.groupContext.TryGet(CommandContextKeys.DrawnCards, out List cards)) return cards; //Debug.LogWarning("[DeckSubmodule] groupContext 中未找到 DrawnCards。"); return new List(); } /// 打出指定卡牌。 public void PlayCard(CardInstance card, List targetList) { card.Play(targetList, owner); } /// 主动弃置单张卡牌,返回包含弃牌指令的指令组。 public CommandGroup DiscardCard(CardInstance card, bool initiative, float interval = 0.1f) { return new CommandGroup(ExecutionMode.Sequential, new Cmd_DiscardCards(card.deck, new List { card }, initiative, interval), Cmd.Do(() => { CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team); })); } /// 主动弃置多张卡牌(按所属 deck 分组),返回包含弃牌指令的指令组。 public CommandGroup DiscardCards(List 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; } /// 消耗单张卡牌,返回包含消耗指令的指令组。 public CommandGroup ExhaustCard(CardInstance card, float interval = 0.1f) { return new CommandGroup(ExecutionMode.Sequential, new Cmd_ExhaustCards(owner is PlayerHero, card.deck, new List { card }, interval), Cmd.Do(() => { CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team); })); } /// 消耗多张卡牌(按所属 deck 分组),返回包含消耗指令的指令组。 public CommandGroup ExhaustCards(List 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; } /// 使用单张力量牌,返回包含使用指令的指令组。 public CommandGroup UsePowerCard(CardInstance card, float interval = 0.1f) { return new CommandGroup(ExecutionMode.Sequential, new Cmd_UsePowerCards(owner is PlayerHero, card.deck, new List { card }, interval), Cmd.Do(() => { CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(owner.team); })); } /// 使用多张力量牌(按所属 deck 分组),返回包含使用指令的指令组。 public CommandGroup UsePowerCards(List 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; } /// 将弃牌堆重新洗入抽牌堆,直接加入全局命令队列。 public void ReshuffleDeck(float interval = 0.1f) { CommandQueueManager.Instance.AddCommand(new Cmd_ReshuffleDeck(this, interval)); } } public partial class DeckSubmodule { public KeyValuePair> 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."); } /// 将卡牌移动到指定牌堆的指定位置。 public void TransferCard(string pileName, int index, CardInstance card) { Pile(pileName).Transfer(card, index); card.cardLocation = new CardLocation(pileName, index); } /// 将卡牌从一个牌堆移动到另一个牌堆(按名称)。 public void TransferCard(string fromPileName, string toPileName, CardInstance card) { List fromPile = Pile(fromPileName); List toPile = Pile(toPileName); fromPile.Transfer(toPile, card); card.cardLocation = new CardLocation(toPileName, toPile.IndexOf(card)); } /// 将卡牌从一个牌堆移动到另一个牌堆(按引用)。 public void TransferCard(List fromPile, List toPile, CardInstance card) { fromPile.Transfer(toPile, card); card.cardLocation = new CardLocation(GetCardLocation(card, out _).Key, toPile.IndexOf(card)); } /// 返回所有牌堆中的所有卡牌。 public List GetAllCards() { var allCards = new List(); foreach (var pile in piles) allCards.AddRange(pile.Value); return allCards; } } public partial class DeckSubmodule { /// 按名称获取牌堆,不存在时抛出 KeyNotFoundException。 public List Pile(string pileName) { if (piles.TryGetValue(pileName, out List pile)) return pile; throw new KeyNotFoundException($"Pile '{pileName}' not found."); } public List StoragePile => Pile(Piles.Storage); public List HandPile => Pile(Piles.Hand); public List DrawPile => Pile(Piles.Draw); public List DiscardPile => Pile(Piles.Discard); public List ExhaustPile => Pile(Piles.Exhaust); public List GravePile => Pile(Piles.Grave); public List PoolPile => Pile(Piles.Pool); public List IntentionPile => Pile(Piles.Intention); } }