235 lines
9.6 KiB
C#
235 lines
9.6 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using Continentis.MainGame.Character;
|
||
using Sirenix.OdinInspector;
|
||
using SoulliesFramework.General;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using UnityEngine.Serialization;
|
||
|
||
namespace Continentis.MainGame.Card
|
||
{
|
||
public enum CardRarity
|
||
{
|
||
None = 0,
|
||
Common = 10,
|
||
Uncommon = 20,
|
||
Rare = 30,
|
||
Epic = 40,
|
||
Legendary = 50,
|
||
Divine = 60
|
||
}
|
||
|
||
public enum CardType
|
||
{
|
||
Attack = 0,
|
||
Skill = 10,
|
||
Power = 20,
|
||
Status = 30,
|
||
Curse = 40,
|
||
Item = 50,
|
||
}
|
||
|
||
[CreateAssetMenu(menuName = "Continentis/MainGame/Card/CardData", fileName = "CardData")]
|
||
public partial class CardData : SerializedScriptableObject
|
||
{
|
||
[Title("Fundamental")]
|
||
[ValueDropdown("GetLogicTypes", IsUniqueList = true)]
|
||
[OnValueChanged("SetCardIdentifier")]
|
||
public Type cardClass;
|
||
public string cardName;
|
||
public string cardIdentifier;
|
||
public CardRarity cardRarity;
|
||
public CardType cardType;
|
||
public Sprite cardSprite;
|
||
[TextArea(1, 10)]
|
||
public string cardDescription;
|
||
[FormerlySerializedAs("tags")] public List<string> functionalTags;
|
||
public List<string> elementalTags;
|
||
public float baseWeight = 1f;
|
||
|
||
[Searchable]
|
||
[Title("References")]
|
||
public Dictionary<string, GameObject> prefabs = new Dictionary<string, GameObject>();
|
||
[Searchable]
|
||
public List<CardData> derivativeCardDataList = new List<CardData>();
|
||
|
||
[Title("Attributes")]
|
||
[Searchable]
|
||
[Tooltip("可变属性,这个属性会自动设置BaseAttr进入Original,设置Attr,BaseAttrOffset=0,以及DisplayAttr进入Current")]
|
||
public Dictionary<string, float> variableAttributes = new Dictionary<string, float>();
|
||
|
||
[Searchable]
|
||
[Tooltip("基础属性,不会改变,通常情况下不会直接使用")]
|
||
public Dictionary<string, float> originalAttributes = new Dictionary<string, float>();
|
||
|
||
[Searchable]
|
||
[Tooltip("初始化时赋予给CurrentAttributes的属性,第一栏是属性名,第二栏是初始化时使用对应名称的OriginalAttributes的,留空则默认为0,如果是float数字则直接使用该数字")]
|
||
public Dictionary<string, string> endowingCurrentAttributes = new Dictionary<string, string>();
|
||
|
||
[Title("Upgrade")]
|
||
[InlineButton("CreateUpgradeNode", "Create")]
|
||
public CardUpgradeNode upgradeNode;
|
||
}
|
||
|
||
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 = 0)
|
||
{
|
||
CardInstance cardInstance = new CardInstance(GenerateCardLogic(), owner, pileName, index);
|
||
cardInstance.cardLogic.InitialRefresh();
|
||
return cardInstance;
|
||
}
|
||
|
||
public CardLogicBase GenerateCardLogic()
|
||
{
|
||
if (Activator.CreateInstance(cardClass) is CardLogicBase cardLogic)
|
||
{
|
||
cardLogic.cardData = this;
|
||
cardLogic.Setup();
|
||
return cardLogic;
|
||
}
|
||
|
||
Debug.LogError($"Card class '{cardClass}' not found or could not be instantiated.");
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过名称获取衍生卡牌数据
|
||
/// </summary>
|
||
public CardData GetDerivativeCardData(string cardName)
|
||
{
|
||
return derivativeCardDataList.FirstOrDefault(card => card.cardName == cardName);
|
||
}
|
||
}
|
||
|
||
#if UNITY_EDITOR
|
||
public partial class CardData
|
||
{
|
||
private void SetCardIdentifier()
|
||
{
|
||
cardIdentifier = cardClass.Name;
|
||
}
|
||
|
||
private void CreateUpgradeNode()
|
||
{
|
||
upgradeNode = new CardUpgradeNode(this);
|
||
}
|
||
|
||
private IEnumerable<ValueDropdownItem<Type>> GetLogicTypes()
|
||
{
|
||
IEnumerable<Type> types = AppDomain.CurrentDomain.GetAssemblies()
|
||
.SelectMany(assembly => assembly.GetTypes())
|
||
.Where(t => typeof(CardLogicBase).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface);
|
||
|
||
// 我们将从命名空间中移除这个公共前缀,让路径更简洁
|
||
string commonNamespacePrefix = "Continentis.Mods";
|
||
|
||
foreach (var type in types)
|
||
{
|
||
string path = "Uncategorized/" + type.Name; // 默认路径
|
||
|
||
if (type.Namespace != null && type.Namespace.StartsWith(commonNamespacePrefix))
|
||
{
|
||
// 1. 移除公共前缀
|
||
string formattedNamespace = type.Namespace.Substring(commonNamespacePrefix.Length);
|
||
|
||
// 2. 移除特定的子命名空间部分(例如 "Cards")
|
||
formattedNamespace = formattedNamespace.Replace(".Cards", "");
|
||
|
||
// 3. 将点 '.' 替换为斜杠 '/' 来创建分组
|
||
formattedNamespace = formattedNamespace.Replace('.', '/');
|
||
|
||
// 4. 组合成最终的路径
|
||
path = formattedNamespace + "/" + type.Name;
|
||
}
|
||
|
||
yield return new ValueDropdownItem<Type>(path, type);
|
||
}
|
||
}
|
||
|
||
[FoldoutGroup("Functions")]
|
||
[Button("从所有的DefaultCollection中粘贴默认属性")]
|
||
public void PasteDefaultAttributes()
|
||
{
|
||
List<CardAttributesDefaultCollection> targetCollections = new List<CardAttributesDefaultCollection>();
|
||
string[] guids = AssetDatabase.FindAssets("t:CardAttributesDefaultCollection");
|
||
|
||
foreach (string guid in guids)
|
||
{
|
||
// 将GUID转换为资产的路径
|
||
string path = AssetDatabase.GUIDToAssetPath(guid);
|
||
|
||
// 2. 验证每个资产的路径是否完全符合您指定的结构
|
||
// 使用 Path.GetDirectoryName 获取文件所在的目录
|
||
// 并统一使用'/'作为路径分隔符,以兼容不同操作系统
|
||
string directory = Path.GetDirectoryName(path)?.Replace('\\', '/');
|
||
Debug.Log($"Checking asset at path: {path}, directory: {directory}");
|
||
|
||
// 加载资产以检查其命名空间
|
||
ScriptableObject collection = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path);
|
||
Type assetType = collection.GetType();
|
||
string assetNamespace = assetType.Namespace;
|
||
|
||
// 检查目录是否有效,是否在"Assets/CoreMods/"下,并且是否以"/Characters/DefaultCollections"结尾
|
||
if (!string.IsNullOrEmpty(directory) &&
|
||
assetNamespace == typeof(CardAttributesDefaultCollection).Namespace &&
|
||
directory.StartsWith("Assets/CoreMods/") &&
|
||
directory.EndsWith("/Cards/DefaultCollections"))
|
||
{
|
||
// 3. 如果路径和命名空间都符合要求,则将该资产添加到目标列表中
|
||
CardAttributesDefaultCollection defaultList = collection as CardAttributesDefaultCollection;
|
||
targetCollections.Add(defaultList);
|
||
Debug.Log($"Loaded DefaultStringList from: {path}");
|
||
}
|
||
}
|
||
|
||
Dictionary<string, float> originalAttributes = new Dictionary<string, float>();
|
||
Dictionary<string, string> endowingCurrentAttributes = new Dictionary<string, string>();
|
||
|
||
foreach (CardAttributesDefaultCollection collection in targetCollections)
|
||
{
|
||
collection.originalAttributes.PasteDictionary(originalAttributes);
|
||
collection.endowingCurrentAttributes.PasteDictionary(endowingCurrentAttributes);
|
||
}
|
||
|
||
originalAttributes.PasteDictionary(this.originalAttributes);
|
||
endowingCurrentAttributes.PasteDictionary(this.endowingCurrentAttributes);
|
||
Debug.Log($"Pasted default attributes to file {this.name}");
|
||
}
|
||
|
||
[FoldoutGroup("Functions")]
|
||
[Button("自动设置需要加权(名称中带有Base)的属性")]
|
||
private void AutoSetUpWeightedAttributes()
|
||
{
|
||
List<string> baseAttributeNames = originalAttributes
|
||
.Where(attr => attr.Key.Contains("Base"))
|
||
.Select(attr => attr.Key).ToList();
|
||
|
||
List<string> attributeNames = baseAttributeNames
|
||
.Select(attr => attr.Replace("Base", "")).ToList();
|
||
|
||
List<string> baseOffsetAttributeName = baseAttributeNames
|
||
.Select(attr => attr + "Offset").ToList();
|
||
|
||
List<string> displayAttributeNames = baseAttributeNames
|
||
.Select(attr => attr.Replace("Base", "Display")).ToList();
|
||
|
||
for (int index = 0; index < baseAttributeNames.Count; index++)
|
||
{
|
||
endowingCurrentAttributes.TryAdd(attributeNames[index], baseAttributeNames[index]);
|
||
endowingCurrentAttributes.TryAdd(baseOffsetAttributeName[index], "0");
|
||
endowingCurrentAttributes.TryAdd(displayAttributeNames[index], baseAttributeNames[index]);
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
} |