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;
}
}
}