Files
Continentis/Assets/Scripts/MainGame/Card/CardLogicBase.cs

195 lines
6.8 KiB
C#
Raw Normal View History

2025-10-03 00:02:43 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using Continentis.MainGame.Character;
2025-10-24 09:11:22 -04:00
using Continentis.MainGame.Equipment;
2025-10-23 00:49:44 -04:00
using SLSFramework.General;
2025-10-24 09:11:22 -04:00
using SLSFramework.UModAssistance;
2025-11-08 09:50:55 -05:00
using UniRx;
2025-10-03 00:02:43 -04:00
using UnityEngine;
namespace Continentis.MainGame.Card
{
public abstract partial class CardLogicBase
{
2025-10-24 09:11:22 -04:00
[Header("Reference")]
public CardData cardData;
2025-10-03 00:02:43 -04:00
public CardInstance cardInstance;
2025-11-08 09:50:55 -05:00
public CompositeDisposable disposables = new CompositeDisposable();
2025-10-03 00:02:43 -04:00
public ICardOwner owner => cardInstance.owner;
public CharacterBase user => cardInstance.user;
2025-10-23 00:49:44 -04:00
public CombatTeam team => cardInstance.team;
2025-10-03 00:02:43 -04:00
public HandCardView handCardView => cardInstance.handCardView;
2025-10-23 00:49:44 -04:00
public IntentionCardView intentionCardView => cardInstance.intentionCardView;
[Header("Card Base Info")]
2025-10-03 00:02:43 -04:00
public Guid cardID;
public int upgradeLevel;
2025-10-23 00:49:44 -04:00
[Header("Submodules")]
2025-10-03 00:02:43 -04:00
public AttributeSubmodule attributeSubmodule { get; private set; }
public WeightSubmodule weightSubmodule { get; private set; }
public CombatBuffSubmodule combatBuffSubmodule { get; private set; }
2025-10-23 00:49:44 -04:00
public EventSubmodule eventSubmodule { get; private set; }
2025-10-03 00:02:43 -04:00
public ContentSubmodule contentSubmodule { get; private set; }
public PlaySubmodule playSubmodule { get; private set; }
2025-10-23 00:49:44 -04:00
public HashSet<CardLogicComponentBase> logicComponents { get; private set; }
2025-10-24 09:11:22 -04:00
/// <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;
}
2025-10-03 00:02:43 -04:00
public void Setup()
{
this.cardID = Guid.NewGuid();
2025-10-27 07:04:34 -04:00
2025-10-23 00:49:44 -04:00
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()
{
2025-10-03 00:02:43 -04:00
}
2025-10-23 00:49:44 -04:00
public virtual void Initialize()
2025-10-03 00:02:43 -04:00
{
RefreshCardAttributes();
2025-11-08 09:50:55 -05:00
2025-10-23 00:49:44 -04:00
if (HasKeyword("Instant")) //如果是“瞬发”牌,添加抽牌后立刻打出的事件
{
2025-10-31 10:02:30 -04:00
eventSubmodule.onDraw.InsertByPriority("Instant", new PrioritizedAction(() =>
2025-10-23 00:49:44 -04:00
{
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))
{
2025-10-24 09:11:22 -04:00
Debug.LogWarning($"Card {cardData.className} already has component of type {typeof(T)}, cannot add duplicate.");
2025-10-23 00:49:44 -04:00
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();
2025-10-03 00:02:43 -04:00
}
public void UpgradeCard()
{
2025-10-23 00:49:44 -04:00
if (owner is not CombatTeam)
2025-10-03 00:02:43 -04:00
{
KeyValuePair<string, List<CardInstance>> currentPile = cardInstance.deck.GetCardLocation(cardInstance, out int index);
if (!cardData.upgradeNode.isTerminalNode)
{
cardInstance.DestroyHandCardView();
2025-10-23 00:49:44 -04:00
2025-10-03 00:02:43 -04:00
CardData newData = cardData.upgradeNode.upgradeCards[0]; //后续可改为选择升级方向
2025-10-24 09:11:22 -04:00
CardLogicBase newLogic = CardLogicBase.GenerateCardLogic(newData);
2025-10-03 00:02:43 -04:00
cardInstance.cardLogic = newLogic;
newLogic.cardInstance = cardInstance;
2025-10-23 00:49:44 -04:00
cardInstance.cardLogic.Initialize();
if (user is PlayerHero)
cardInstance.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.Pile(currentPile.Key), index);
2025-10-03 00:02:43 -04:00
}
}
else
{
2025-10-23 00:49:44 -04:00
2025-10-03 00:02:43 -04:00
}
}
2025-10-27 07:04:34 -04:00
/// <summary>
/// 获取衍生卡牌数据
/// </summary>
public CardData GetDerivativeCardData(int index)
{
return ModManager.GetData<CardData>(cardData.derivativeCardDataRefs[index]);
}
2025-10-30 12:07:59 -04:00
/// <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;
}
2025-10-03 00:02:43 -04:00
}
2025-10-23 00:49:44 -04:00
/// <summary>
/// 卡牌逻辑组件基类接口
/// 注意,所有的子接口需要实现的函数:
/// ComponentTargetingEffect此牌瞄准目标时调用
/// ComponentUntargetingEffect此牌取消瞄准目标时调用
/// </summary>
public abstract class CardLogicComponentBase
2025-10-03 00:02:43 -04:00
{
2025-10-23 00:49:44 -04:00
protected CardLogicBase card;
protected CharacterBase user => card.user;
protected CombatTeam team => card.team;
2025-10-03 00:02:43 -04:00
2025-10-23 00:49:44 -04:00
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()
{
}
2025-10-03 00:02:43 -04:00
}
}