This commit is contained in:
SoulliesOfficial
2025-10-24 09:11:22 -04:00
parent 61a397dd4c
commit 76157e3cb1
329 changed files with 8609 additions and 4549 deletions

View File

@@ -5,6 +5,7 @@ using Continentis.MainGame.Character;
using Continentis.MainGame.Commands;
using NUnit.Framework;
using SLSFramework.General;
using SLSFramework.UModAssistance;
using UnityEngine;
namespace Continentis.MainGame.Card
@@ -247,10 +248,26 @@ namespace Continentis.MainGame.Card
}
#endregion
#region CombatResoures
#region Buffs
public partial class CardLogicBase
{
/// <summary>
/// 创建一个角色战斗Buff实例
/// 注意此函数依赖ModManager的类型注册功能请确保在Mod加载时已注册对应Buff类型
/// 此函数中的T并不是原型参数而是获取Mod中注册的类型用的
/// </summary>
protected CharacterCombatBuffBase CreateCharacterBuff<T>(params object[] parameters) where T :CharacterCombatBuffBase
{
string buffTypeID = ModManager.GetTypeID(typeof(T));
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<CharacterCombatBuffBase>(buffTypeID, parameters);
}
}
#endregion
}

View File

@@ -5,7 +5,7 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
public partial class CombatBuffBase : CardBuffBase
public partial class CardCombatBuffBase : CardBuffBase
{
public CardLogicBase sourceCard;
@@ -13,14 +13,14 @@ namespace Continentis.MainGame.Card
public CountSubmodule combatRoundTimeSubmodule;
}
public partial class CombatBuffBase
public partial class CardCombatBuffBase
{
public sealed override bool OnBuffApply(out BuffBase<CardLogicBase> existingBuff)
{
throw new System.NotImplementedException("请使用类型约束更强的OnBuffApply方法");
}
public virtual bool OnBuffApply(out CombatBuffBase existingBuff)
public virtual bool OnBuffApply(out CardCombatBuffBase existingBuff)
{
throw new System.NotImplementedException(); //需要在子类中实现
}
@@ -61,7 +61,7 @@ namespace Continentis.MainGame.Card
}
}
public partial class CombatBuffBase
public partial class CardCombatBuffBase
{
protected bool FindExistingBuff<T>(out T existingBuff) where T : CardBuffBase
{
@@ -79,7 +79,7 @@ namespace Continentis.MainGame.Card
this.sourceCharacter = sourceCharacter;
this.sourceCard = sourceCard;
if (OnBuffApply(out CombatBuffBase existingBuff))
if (OnBuffApply(out CardCombatBuffBase existingBuff))
{
this.attachedCard.combatBuffSubmodule.buffList.Add(this);
OnAfterFirstApply();

View File

@@ -28,8 +28,9 @@ namespace Continentis.MainGame.Card
[CreateAssetMenu(menuName = "Continentis/MainGame/Card/CardData", fileName = "CardData")]
public partial class CardData : ScriptableObject
{
[FormerlySerializedAs("cardLogicClassName")] [Header("Fundamental")]
public string classFullName;
[Header("Fundamental")]
public string modName;
public string className;
public string displayName;
public Rarity cardRarity;
public CardType cardType;
@@ -64,9 +65,6 @@ namespace Continentis.MainGame.Card
public partial class CardData
{
public string ModName => classFullName.Split('_').First();
public string ClassName => classFullName.Split('_').Last();
public bool HasTag(string tag)
{
return tags.Contains(tag);
@@ -88,44 +86,6 @@ namespace Continentis.MainGame.Card
public partial class CardData
{
/// <summary>
/// 生成卡牌实例
/// </summary>
/// <param name="owner">卡牌持有者</param>
/// <param name="pileName">初始卡堆名称,默认为"Draw"</param>
/// <param name="index">插入位置默认为0</param>
public CardInstance GenerateCardInstance(ICardOwner owner, string pileName = "Draw", int index = -1)
{
CardInstance cardInstance = new CardInstance(GenerateCardLogic(), owner, pileName, index);
cardInstance.cardLogic.Initialize();
return cardInstance;
}
/// <summary>
/// 生成卡牌逻辑实例
/// </summary>
public CardLogicBase GenerateCardLogic()
{
Type cardLogicType = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.FirstOrDefault(t => typeof(CardLogicBase).IsAssignableFrom(t) && t.Name == this.classFullName);//TODO: 后续优化为共用字典
if(cardLogicType == null)
{
Debug.LogError($"Card class '{classFullName}' not found in assemblies.");
return null;
}
if (Activator.CreateInstance(cardLogicType) is CardLogicBase cardLogic)
{
cardLogic.cardData = this;
cardLogic.Setup();
return cardLogic;
}
Debug.LogError($"Card class '{classFullName}' not found or could not be instantiated.");
return null;
}
/// <summary>
/// 通过索引获取衍生卡牌数据

View File

@@ -78,7 +78,7 @@ namespace Continentis.MainGame.Card
}
else
{
Debug.LogError($"[CardUpgradeNode] Attempted to get upgrade attributes for a non-terminal node card {sourceCard.classFullName}.");
Debug.LogError($"[CardUpgradeNode] Attempted to get upgrade attributes for a non-terminal node card {sourceCard.className}.");
}
return upgradeAttributes;

View File

@@ -47,6 +47,36 @@ namespace Continentis.MainGame.Card
this.deck.Pile(cardLocation.pileName).Insert(index, this);
}
}
/// <summary>
/// 根据CardLogic生成卡牌实例
/// </summary>
/// <param name="logic">卡牌逻辑实例</param>
/// <param name="owner">卡牌持有者</param>
/// <param name="pileName">初始卡堆名称"</param>
/// <param name="index">插入位置默认为0</param>
public static CardInstance GenerateCardInstance(CardLogicBase logic, ICardOwner owner, string pileName, int index = -1)
{
CardInstance cardInstance = new CardInstance(logic, owner, pileName, index);
cardInstance.cardLogic.Initialize();
return cardInstance;
}
/// <summary>
/// 根据CardData生成卡牌实例
/// </summary>
/// <param name="data">卡牌数据</param>
/// <param name="owner">卡牌持有者</param>
/// <param name="pileName">初始卡堆名称"</param>
/// <param name="index">插入位置默认为0</param>
/// <returns></returns>
public static CardInstance GenerateCardInstance(CardData data, ICardOwner owner, string pileName, int index = -1)
{
CardInstance cardInstance = new CardInstance(CardLogicBase.GenerateCardLogic(data), owner, pileName, index);
cardInstance.cardLogic.Initialize();
return cardInstance;
}
public HandCardView GenerateHandCardView(string pileName, int index = -1)
{

View File

@@ -2,14 +2,17 @@ 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;
[Header("Reference")]
public CardData cardData;
public CardInstance cardInstance;
public ICardOwner owner => cardInstance.owner;
@@ -32,6 +35,31 @@ namespace Continentis.MainGame.Card
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();
@@ -72,7 +100,7 @@ namespace Continentis.MainGame.Card
{
if (logicComponents.Any(component => component is T))
{
Debug.LogWarning($"Card {cardData.classFullName} already has component of type {typeof(T)}, cannot add duplicate.");
Debug.LogWarning($"Card {cardData.className} already has component of type {typeof(T)}, cannot add duplicate.");
return null;
}
else
@@ -99,7 +127,7 @@ namespace Continentis.MainGame.Card
cardInstance.DestroyHandCardView();
CardData newData = cardData.upgradeNode.upgradeCards[0]; //后续可改为选择升级方向
CardLogicBase newLogic = newData.GenerateCardLogic();
CardLogicBase newLogic = CardLogicBase.GenerateCardLogic(newData);
cardInstance.cardLogic = newLogic;
newLogic.cardInstance = cardInstance;
cardInstance.cardLogic.Initialize();

View File

@@ -7,22 +7,22 @@ namespace Continentis.MainGame.Card
{
public partial class CombatBuffSubmodule : SubmoduleBase<CardLogicBase>
{
public List<CombatBuffBase> buffList;
public List<CardCombatBuffBase> buffList;
public CombatBuffSubmodule(CardLogicBase owner) : base(owner)
{
buffList = new List<CombatBuffBase>();
buffList = new List<CardCombatBuffBase>();
}
}
public partial class CombatBuffSubmodule
{
public T GetBuff<T>() where T : CombatBuffBase
public T GetBuff<T>() where T : CardCombatBuffBase
{
return (T)buffList.Find(x => x.GetType() == typeof(T));
}
public bool HasBuff<T>() where T : CombatBuffBase
public bool HasBuff<T>() where T : CardCombatBuffBase
{
return buffList.Exists(x => x.GetType() == typeof(T));
}

View File

@@ -1,4 +1,5 @@
#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEngine;
using SLSFramework.UModAssistance;
@@ -10,7 +11,25 @@ namespace Continentis.MainGame.Card
public class CardDataEditor : DataEditor
{
// 存储我们需要自定义绘制的属性的引用
private SerializedProperty classFullNameProp;
private SerializedProperty modNameProp;
private SerializedProperty classNameProp;
private SerializedProperty displayNameProp;
private SerializedProperty cardRarityProp;
private SerializedProperty cardTypeProp;
private SerializedProperty tagsProp;
private SerializedProperty cardSpriteProp;
private SerializedProperty functionTextProp;
private SerializedProperty cardDescriptionProp;
private SerializedProperty baseWeightProp;
private SerializedProperty variableAttributesProp;
private SerializedProperty originalAttributesProp;
private SerializedProperty runtimeCurrentAttributesProp;
private SerializedProperty upgradeNodeProp;
private SerializedProperty prefabsProp;
private SerializedProperty derivativeCardsProp;
private SerializedProperty derivativeCharactersProp;
@@ -20,7 +39,20 @@ namespace Continentis.MainGame.Card
base.OnEnable();
// 在启用时根据我们修改后的字段名找到对应的SerializedProperty
classFullNameProp = serializedObject.FindProperty("classFullName");
modNameProp = serializedObject.FindProperty("modName");
classNameProp = serializedObject.FindProperty("className");
displayNameProp = serializedObject.FindProperty("displayName");
cardRarityProp = serializedObject.FindProperty("cardRarity");
cardTypeProp = serializedObject.FindProperty("cardType");
tagsProp = serializedObject.FindProperty("tags");
cardSpriteProp = serializedObject.FindProperty("cardSprite");
functionTextProp = serializedObject.FindProperty("functionText");
cardDescriptionProp = serializedObject.FindProperty("cardDescription");
baseWeightProp = serializedObject.FindProperty("baseWeight");
variableAttributesProp = serializedObject.FindProperty("variableAttributes");
originalAttributesProp = serializedObject.FindProperty("originalAttributes");
runtimeCurrentAttributesProp = serializedObject.FindProperty("runtimeCurrentAttributes");
upgradeNodeProp = serializedObject.FindProperty("upgradeNode");
prefabsProp = serializedObject.FindProperty("prefabRefs");
derivativeCardsProp = serializedObject.FindProperty("derivativeCardDataRefs");
derivativeCharactersProp = serializedObject.FindProperty("derivativeCharacterDataRefs");
@@ -33,30 +65,42 @@ namespace Continentis.MainGame.Card
// --- 绘制自定义的Type选择器 ---
// 我们把它从所有自动绘制的属性中分离出来,放在最前面或最后面,让布局更清晰
EditorGUILayout.Space(); // 增加一点间距
EditorGUILayout.LabelField("Logic", EditorStyles.boldLabel);
if (DrawTypeSelectorGUI(classFullNameProp, "Card Logic Class", typeof(CardLogicBase), "Continentis.Mods", "Cards"))
EditorGUILayout.LabelField("Fundamental", EditorStyles.boldLabel);
if (DrawTypeSelectorGUI(classNameProp, "Card Logic Class", typeof(CardLogicBase), out Type outType, "Continentis.Mods", "Cards"))
{
string classFullName = classFullNameProp.stringValue;
string className = classNameProp.stringValue;
string modName = outType.Namespace!.Replace("Continentis.Mods.", "").Split('.')[0];
string displayName = "Card_" + modName + "_" + className + "_DisplayName";
string functionTextName = "Card_" + modName + "_" + className + "_FunctionText";
string displayName = "Card_" + classFullName + "_DisplayName";
SerializedProperty displayNameProp = serializedObject.FindProperty("displayName");
modNameProp.stringValue = modName;
displayNameProp.stringValue = displayName;
string functionTextName = "Card_" + classFullName + "_FunctionText";
SerializedProperty functionTextProp = serializedObject.FindProperty("functionText");
functionTextProp.stringValue = functionTextName;
}
// --- 核心修复 2将 _cardLogicClassNameProp 也加入排除列表 ---
// 因为这也是我们手动绘制的
DrawPropertiesExcluding(serializedObject, new string[]
{
"m_Script",
classFullNameProp.name, // <-- 新增
prefabsProp.name,
derivativeCardsProp.name,
derivativeCharactersProp.name
});
EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.PropertyField(modNameProp);
EditorGUILayout.PropertyField(classNameProp);
EditorGUILayout.PropertyField(displayNameProp);
EditorGUI.EndDisabledGroup();
EditorGUILayout.PropertyField(cardRarityProp);
EditorGUILayout.PropertyField(cardTypeProp);
EditorGUILayout.PropertyField(tagsProp, true);
EditorGUILayout.PropertyField(cardSpriteProp);
EditorGUILayout.PropertyField(functionTextProp);
EditorGUILayout.PropertyField(cardDescriptionProp);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Attributes", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(baseWeightProp);
EditorGUILayout.PropertyField(variableAttributesProp, true);
EditorGUILayout.PropertyField(originalAttributesProp, true);
EditorGUILayout.PropertyField(runtimeCurrentAttributesProp, true);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Upgrade", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(upgradeNodeProp);
// --- 绘制自定义的引用列表 ---
EditorGUILayout.Space();