using System; using System.Collections.Generic; using System.IO; using System.Linq; using Continentis.MainGame.Character; using SLSFramework.General; using UnityEngine; using NaughtyAttributes; using SLSFramework.UModAssistance; using UnityEngine.Serialization; #if UNITY_EDITOR using UnityEditor; #endif namespace Continentis.MainGame.Card { 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 : ScriptableObject { [Header("Fundamental")] public string modName; public string className; public string displayName; public Rarity cardRarity; public CardType cardType; public List tags; public Sprite cardSprite; public string functionText; public string cardDescription; [Header("Intention")] public float baseWeight = 1f; [Header("Attributes")] [Tooltip("可变属性,这个属性会自动设置BaseAttr进入Original,设置Attr,BaseAttrOffset=0,以及DisplayAttr进入Current")] public SerializableDictionary variableAttributes = new SerializableDictionary(); [Tooltip("基础属性,不会改变,通常情况下不会直接使用")] public SerializableDictionary originalAttributes = new SerializableDictionary(); [FormerlySerializedAs("endowingCurrentAttributes")] [Tooltip("初始化时赋予给CurrentAttributes的属性,第一栏是属性名,第二栏是初始化时使用对应名称的OriginalAttributes的,留空则默认为0,如果是float数字则直接使用该数字")] public SerializableDictionary runtimeCurrentAttributes = new SerializableDictionary(); [Header("Upgrade")] public CardUpgradeNode upgradeNode; [Header("References")] public List prefabRefs = new List(); public List derivativeCardDataRefs = new List(); public List derivativeCharacterDataRefs = new List(); } public partial class CardData { public bool HasTag(string tag) { return tags.Contains(tag); } public bool HasKeyword(string keyword) { return functionText.Contains($"$Keyword(\"{keyword}\")"); } } public partial class CardData { public static CardData Get(string dataID) { return ModManager.GetData(dataID); } } public partial class CardData { /// /// 通过索引获取衍生卡牌数据 /// public CardData GetDerivativeCardData(int index) { return ModManager.GetData(derivativeCardDataRefs[index]); } /// /// 通过索引获取衍生角色数据 /// /// /// public CharacterData GetDerivativeCharacterData(int index) { return ModManager.GetData(derivativeCharacterDataRefs[index]); } } #if UNITY_EDITOR public partial class CardData {/* private void SetCardIdentifier() { cardIdentifier = cardClass.Name; int underscoreIndex = cardClass.Name.IndexOf('_'); string cardNamePart = cardClass.Name.Substring(underscoreIndex + 1); string result = Regex.Replace(cardNamePart, "([a-z])([A-Z])", "$1 $2"); cardName = result; } private void CreateUpgradeNode() { upgradeNode = new CardUpgradeNode(this); } private IEnumerable> GetLogicTypes() { IEnumerable 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(path, type); } } [FoldoutGroup("Functions")] [Button("从所有的DefaultCollection中粘贴默认属性")] public void PasteDefaultAttributes() { List targetCollections = new List(); 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(path); Type assetType = collection.GetType(); string assetNamespace = assetType.Namespace; // 检查目录是否有效,是否在"Assets/Mods/"下,并且是否以"/Characters/DefaultCollections"结尾 if (!string.IsNullOrEmpty(directory) && assetNamespace == typeof(CardAttributesDefaultCollection).Namespace && directory.StartsWith("Assets/Mods/") && directory.EndsWith("/Cards/DefaultCollections")) { // 3. 如果路径和命名空间都符合要求,则将该资产添加到目标列表中 CardAttributesDefaultCollection defaultList = collection as CardAttributesDefaultCollection; targetCollections.Add(defaultList); Debug.Log($"Loaded DefaultStringList from: {path}"); } } Dictionary variableAttributes = new Dictionary(); Dictionary originalAttributes = new Dictionary(); Dictionary endowingCurrentAttributes = new Dictionary(); foreach (CardAttributesDefaultCollection collection in targetCollections) { collection.variableAttributes.PasteDictionary(variableAttributes); collection.originalAttributes.PasteDictionary(originalAttributes); collection.endowingCurrentAttributes.PasteDictionary(endowingCurrentAttributes); } variableAttributes.PasteDictionary(this.variableAttributes); originalAttributes.PasteDictionary(this.originalAttributes); endowingCurrentAttributes.PasteDictionary(this.endowingCurrentAttributes); Debug.Log($"Pasted default attributes to file {this.name}"); }*/ } #endif }