Files
Continentis/Assets/Scripts/MainGame/Character/CharacterSubmodules/DeckSubmodule/DeckSubmodule.cs
SoulliesOfficial c3b1561375 更新
2026-04-01 12:23:27 -04:00

247 lines
10 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.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);
}
}