180 lines
6.3 KiB
C#
180 lines
6.3 KiB
C#
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<CardLogicComponentBase> logicComponents { get; private set; }
|
||
|
||
/// <summary>
|
||
/// 生成卡牌逻辑实例
|
||
/// </summary>
|
||
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<CardLogicComponentBase>();
|
||
|
||
SetUpLogicComponents();
|
||
}
|
||
|
||
protected virtual void SetUpLogicComponents()
|
||
{
|
||
|
||
}
|
||
|
||
public virtual void Initialize()
|
||
{
|
||
RefreshCardAttributes();
|
||
CardTextInterpreter.InterpretText(this);
|
||
|
||
if (HasKeyword("Instant")) //如果是“瞬发”牌,添加抽牌后立刻打出的事件
|
||
{
|
||
eventSubmodule.onDraw.InsertByPriority("Instant", new EventUnit(() =>
|
||
{
|
||
DetectTargetsValidity(out List<CharacterBase> valid, out _, out _);
|
||
Play(SetRandomTargets(valid), user);
|
||
}, 99));
|
||
}
|
||
}
|
||
|
||
public T AddLogicComponent<T>() 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<T>() where T : CardLogicComponentBase
|
||
{
|
||
return logicComponents.OfType<T>().FirstOrDefault();
|
||
}
|
||
|
||
public void UpgradeCard()
|
||
{
|
||
if (owner is not CombatTeam)
|
||
{
|
||
KeyValuePair<string, List<CardInstance>> 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
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取衍生卡牌数据
|
||
/// </summary>
|
||
public CardData GetDerivativeCardData(int index)
|
||
{
|
||
return ModManager.GetData<CardData>(cardData.derivativeCardDataRefs[index]);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 卡牌逻辑组件基类接口
|
||
/// 注意,所有的子接口需要实现的函数:
|
||
/// ComponentTargetingEffect:此牌瞄准目标时调用
|
||
/// ComponentUntargetingEffect:此牌取消瞄准目标时调用
|
||
/// </summary>
|
||
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()
|
||
{
|
||
|
||
}
|
||
}
|
||
} |