Files
Continentis/Assets/Scripts/MainGame/Card/CardLogicBase.cs
2025-10-30 12:07:59 -04:00

194 lines
6.7 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.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>
/// 获取衍生卡牌数据
/// </summary>
public CardData GetDerivativeCardData(string dataName)
{
if (cardData.derivativeCardDataRefs.Contains(dataName))
{
return ModManager.GetData<CardData>(dataName);
}
Debug.LogError($"Card {cardData.className} does not contain derivative card data '{dataName}'.");
return null;
}
}
/// <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()
{
}
}
}