using System; using System.Collections.Generic; using Continentis.MainGame.Character; using Continentis.MainGame.Combat; using Continentis.MainGame.UI; using Lean.Pool; using NaughtyAttributes; using SLSFramework.General; using UniRx; using UnityEngine; namespace Continentis.MainGame.Card { public partial class CardInstance : IGameElement { public Guid elementID { get; set; } [Header("References")] public DeckSubmodule deck; public CardLocation cardLocation; public CardData cardData; public CompositeDisposable disposables = new CompositeDisposable(); public ICardOwner owner; public CharacterBase user; public CombatTeam usingTeam; public CardLogicBase cardLogic; public int upgradeLevel; [Header("Submodules")] [ShowNativeProperty] public AttributeSubmodule attributeSubmodule { get; private set; } [ShowNativeProperty] public WeightSubmodule weightSubmodule { get; private set; } [ShowNativeProperty] public CombatBuffSubmodule combatBuffSubmodule { get; private set; } [ShowNativeProperty] public EventSubmodule eventSubmodule { get; private set; } [ShowNativeProperty] public ContentSubmodule contentSubmodule { get; private set; } [ShowNativeProperty] public PlaySubmodule playSubmodule { get; private set; } public CardInstance(CardData data, ICardOwner owner, string initialPileName, int index = -1) { (this as IGameElement).Initialize(); this.cardData = data; this.owner = owner; this.user = owner as CharacterBase; if (this.owner is CombatTeam team) { this.usingTeam = team; } else if (this.owner is CharacterBase character) { this.usingTeam = character.team; } this.deck = owner.deckSubmodule; this.cardLocation = new CardLocation(initialPileName, index); if (index < 0) { this.deck.Pile(cardLocation.pileName).Add(this); } else { this.deck.Pile(cardLocation.pileName).Insert(index, this); } this.attributeSubmodule = new AttributeSubmodule(this); this.weightSubmodule = new WeightSubmodule(this); this.eventSubmodule = new EventSubmodule(this); this.combatBuffSubmodule = new CombatBuffSubmodule(this); this.contentSubmodule = new ContentSubmodule(this); this.playSubmodule = new PlaySubmodule(this); this.cardLogic = CardLogicBase.GenerateCardLogic(data); this.cardLogic.Initialize(this); this.cardLogic.SetUpLogicComponents(); } /// /// 根据CardLogic生成卡牌实例 /// /// 卡牌实体实例 /// 卡牌持有者 /// 初始卡堆名称" /// 插入位置,默认为0 public static CardInstance GenerateCardInstance(CardInstance template, ICardOwner owner, string pileName, int index = -1) { CardInstance cardInstance = new CardInstance(template.cardData, owner, pileName, index); //TODO: 复制template的属性到cardInstance return cardInstance; } /// /// 根据CardData生成卡牌实例 /// /// 卡牌数据 /// 卡牌持有者 /// 初始卡堆名称" /// 插入位置,默认为0 /// public static CardInstance GenerateCardInstance(CardData data, ICardOwner owner, string pileName, int index = -1) { CardInstance card = new CardInstance(data, owner, pileName, index); if (owner == CombatMainManager.Instance.characterController.playerTeam) { CombatUIManager.Instance.combatMainPage.teamSwitchButton .UpdateTeamPileText(CombatMainManager.Instance.characterController.playerTeam); } //下面的部分后续放入CardLogic的初始化函数中 card.RefreshCardAttributes(); if (card.HasKeyword("Instant")) //如果是“瞬发”牌,添加抽牌后立刻打出的事件 { card.eventSubmodule.onDraw.InsertByPriority("Instant", new PrioritizedAction(() => { card.DetectTargetsValidity(out List valid, out _, out _); card.Play(card.SetRandomTargets(valid), card.user); }, 99)); } return card; } public HandCardView GenerateHandCardView(string pileName, int index = -1) { PileBase pile = CombatUIManager.Instance.combatMainPage.Pile(pileName); return GenerateHandCardView(pile, index); } /// /// 生成手牌 /// /// 手牌生成位置 /// 插入位置,-1为末尾 /// public HandCardView GenerateHandCardView(PileBase pile, int index = -1) { GameObject handCardObjectPrefab = MainGameManager.Instance.basePrefabs.handCardObject; HandCardView handCardView = LeanPool.Spawn(handCardObjectPrefab, pile.rectTransform).GetComponent(); if (index >= 0) { pile.InsertCard(handCardView, index); } else { pile.AddCard(handCardView); } handCardView.card = this; this.handCardView = handCardView; handCardView.transform.localScale = pile is HandPile ? Vector3.one : Vector3.zero; handCardView.Setup(this); handCardView.currentPile = pile; handCardView.cardOrb.gameObject.SetActive(false); return handCardView; } public void DestroyHandCardView() { if (handCardView != null) { handCardView.currentPile.RemoveCard(handCardView); LeanPool.Despawn(handCardView.gameObject); handCardView = null; } } public IntentionCardView GenerateIntentionCardView() { GameObject intentionCardObjectPrefab = MainGameManager.Instance.basePrefabs.intentionCardObject; HUD_Intention intention = user.characterView.hudContainer.enablingHUDs["Intention"] as HUD_Intention; IntentionCardView intentionCardView = LeanPool.Spawn(intentionCardObjectPrefab, intention.hudTransform).GetComponent(); intention.AddCard(intentionCardView); intentionCardView.card = this; this.intentionCardView = intentionCardView; intentionCardView.transform.localScale = Vector3.one; intentionCardView.Setup(this); return intentionCardView; } public void DestroyIntentionCardView() { if (intentionCardView != null) { HUD_Intention intention = user.characterView.hudContainer.enablingHUDs["Intention"] as HUD_Intention; intention.RemoveCard(intentionCardView); intentionCardView = null; } } } public partial class CardInstance { public HandCardView handCardView; public IntentionCardView intentionCardView; } public class CardLocation { public string pileName; public int index; public CardLocation(string pileName, int index) { this.pileName = pileName; this.index = index; } } }