继续
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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>
|
||||
/// 通过索引获取衍生卡牌数据
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user