using System; using System.Collections.Generic; using System.Linq; using Continentis.MainGame.Character; using Continentis.MainGame.Equipment; using SLSFramework.General; using SLSFramework.UModAssistance; using UnityEngine; namespace Continentis.MainGame.Card { public abstract partial class CardLogicBase { [Header("Reference")] public CardData cardData; public CardInstance cardInstance; public ICardOwner owner => cardInstance.owner; public CharacterBase user => cardInstance.user; public CombatTeam team => cardInstance.team; public HandCardView handCardView => cardInstance.handCardView; public IntentionCardView intentionCardView => cardInstance.intentionCardView; [Header("Card Base Info")] public Guid cardID; public int upgradeLevel; [Header("Submodules")] public AttributeSubmodule attributeSubmodule { get; private set; } public WeightSubmodule weightSubmodule { get; private set; } public CombatBuffSubmodule combatBuffSubmodule { get; private set; } public EventSubmodule eventSubmodule { get; private set; } public ContentSubmodule contentSubmodule { get; private set; } public PlaySubmodule playSubmodule { get; private set; } public HashSet logicComponents { get; private set; } /// /// 生成卡牌逻辑实例 /// public static CardLogicBase GenerateCardLogic(CardData data) { string typeID = ModManager.GetTypeID(data.modName, "Cards", data.className); Type logicType = ModManager.GetType(typeID); if(logicType == null) { Debug.LogError($"Card class '{typeID}' not found in assemblies."); return null; } if (Activator.CreateInstance(logicType) is CardLogicBase cardLogic) { cardLogic.cardData = data; cardLogic.Setup(); return cardLogic; } Debug.LogError($"Card class '{typeID}' not found or could not be instantiated."); return null; } public void Setup() { this.cardID = Guid.NewGuid(); 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.logicComponents = new HashSet(); SetUpLogicComponents(); } protected virtual void SetUpLogicComponents() { } public virtual void Initialize() { RefreshCardAttributes(); CardTextInterpreter.InterpretText(this); if (HasKeyword("Instant")) //如果是“瞬发”牌,添加抽牌后立刻打出的事件 { eventSubmodule.onDraw.InsertByPriority("Instant", new PrioritizedAction(() => { DetectTargetsValidity(out List valid, out _, out _); Play(SetRandomTargets(valid), user); }, 99)); } } public T AddLogicComponent() where T : CardLogicComponentBase, new() { if (logicComponents.Any(component => component is T)) { Debug.LogWarning($"Card {cardData.className} already has component of type {typeof(T)}, cannot add duplicate."); return null; } else { T component = new T(); component.Initialize(this); logicComponents.Add(component); return component; } } public T LogicComponent() where T : CardLogicComponentBase { return logicComponents.OfType().FirstOrDefault(); } public void UpgradeCard() { if (owner is not CombatTeam) { KeyValuePair> currentPile = cardInstance.deck.GetCardLocation(cardInstance, out int index); if (!cardData.upgradeNode.isTerminalNode) { cardInstance.DestroyHandCardView(); CardData newData = cardData.upgradeNode.upgradeCards[0]; //后续可改为选择升级方向 CardLogicBase newLogic = CardLogicBase.GenerateCardLogic(newData); cardInstance.cardLogic = newLogic; newLogic.cardInstance = cardInstance; cardInstance.cardLogic.Initialize(); if (user is PlayerHero) cardInstance.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.Pile(currentPile.Key), index); } } else { } } /// /// 获取衍生卡牌数据 /// public CardData GetDerivativeCardData(int index) { return ModManager.GetData(cardData.derivativeCardDataRefs[index]); } /// /// 获取衍生卡牌数据 /// public CardData GetDerivativeCardData(string dataName) { if (cardData.derivativeCardDataRefs.Contains(dataName)) { return ModManager.GetData(dataName); } Debug.LogError($"Card {cardData.className} does not contain derivative card data '{dataName}'."); return null; } } /// /// 卡牌逻辑组件基类接口 /// 注意,所有的子接口需要实现的函数: /// ComponentTargetingEffect:此牌瞄准目标时调用 /// ComponentUntargetingEffect:此牌取消瞄准目标时调用 /// public abstract class CardLogicComponentBase { protected CardLogicBase card; protected CharacterBase user => card.user; protected CombatTeam team => card.team; public virtual void Initialize(CardLogicBase card) { this.card = card; card.eventSubmodule.onTargeting += TargetingEffect; card.eventSubmodule.onUntargeting += UntargetingEffect; } protected virtual void TargetingEffect(CharacterBase target) { } protected virtual void UntargetingEffect() { } } }