From 85bbe2431c71de1cc3f99450977b833e1ed4a9cb Mon Sep 17 00:00:00 2001 From: SoulliesOfficial Date: Sat, 15 Nov 2025 09:08:36 -0500 Subject: [PATCH] =?UTF-8?q?=E6=84=8F=E5=9B=BE=E5=88=9D=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.idea/codeStyles/codeStyleConfig.xml | 5 + Assets/Mods/Basic/Basic_CombatOrganizer.asset | 3 +- Assets/Mods/Basic/Basic_Manifest.asset | 17 +- .../Basic_NecromanticInfusion.meta | 8 - .../CardData_Basic_NecromanticInfusion.asset | 26 ++- ...dData_Basic_NecromanticInfusion.asset.meta | 0 .../NecromanticInfusion.cs | 12 +- .../NecromanticInfusion.cs.meta | 0 .../MarshalOfUnderworld/WrathOfUnderworld.cs | 2 - ...acterData_Basic_MarshalOfUnderworld.asset} | 19 ++- ...Data_Basic_MarshalOfUnderworld.asset.meta} | 0 .../Characters/Scripts/MarshalOfUnderworld.cs | 130 +++++++++++++++ ...ld.cs.meta => MarshalOfUnderworld.cs.meta} | 0 .../Scripts/MarshallOfUnderworld.cs | 16 -- .../Rules/Basic_AttributeRulesCollection.cs | 5 + .../MainGame/Card/CardData/CardData.cs | 2 +- Assets/Scripts/MainGame/Card/CardInstance.cs | 8 +- Assets/Scripts/MainGame/Card/CardLogicBase.cs | 4 +- .../MainGame/Card/CardMainFunctions.cs | 6 +- .../Card/CardSubmodules/WeightSubmodule.cs | 5 + .../MainGame/Character/CharacterBase.cs | 155 ++++-------------- .../Character/CharacterData/CharacterData.cs | 6 - .../MainGame/Character/CharacterInstance.cs | 16 ++ .../Character/CharacterInstance.cs.meta | 2 + .../Character/CharacterMainFunctions.cs | 133 +++++++++++++++ .../CharacterSubmodules/IntentionSubmodule.cs | 34 +++- .../CharacterSubmodules/RecordSubmodule.cs | 76 +++++++++ .../RecordSubmodule.cs.meta | 2 + .../Scripts/MainGame/Character/CombatNPC.cs | 3 +- .../Character/Editor/CharacterDataEditor.cs | 2 +- .../Scripts/MainGame/Character/PlayerHero.cs | 3 +- .../MainGame/Combat/CombatMainManager.cs | 4 + .../UModAssistance/ModBrowser.cs | 2 +- 33 files changed, 508 insertions(+), 198 deletions(-) create mode 100644 .idea/.idea.Continentis/.idea/codeStyles/codeStyleConfig.xml delete mode 100644 Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion.meta rename Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/{Basic_NecromanticInfusion => }/CardData_Basic_NecromanticInfusion.asset (75%) rename Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/{Basic_NecromanticInfusion => }/CardData_Basic_NecromanticInfusion.asset.meta (100%) rename Assets/Mods/Basic/Cards/{Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion => Scripts/Enemies/Bosses/MarshalOfUnderworld}/NecromanticInfusion.cs (59%) rename Assets/Mods/Basic/Cards/{Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion => Scripts/Enemies/Bosses/MarshalOfUnderworld}/NecromanticInfusion.cs.meta (100%) rename Assets/Mods/Basic/Characters/Data/{CharacterData_Basic_MarshalOfTheUnderworld.asset => CharacterData_Basic_MarshalOfUnderworld.asset} (91%) rename Assets/Mods/Basic/Characters/Data/{CharacterData_Basic_MarshalOfTheUnderworld.asset.meta => CharacterData_Basic_MarshalOfUnderworld.asset.meta} (100%) create mode 100644 Assets/Mods/Basic/Characters/Scripts/MarshalOfUnderworld.cs rename Assets/Mods/Basic/Characters/Scripts/{MarshallOfUnderworld.cs.meta => MarshalOfUnderworld.cs.meta} (100%) delete mode 100644 Assets/Mods/Basic/Characters/Scripts/MarshallOfUnderworld.cs create mode 100644 Assets/Scripts/MainGame/Character/CharacterInstance.cs create mode 100644 Assets/Scripts/MainGame/Character/CharacterInstance.cs.meta create mode 100644 Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs create mode 100644 Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs.meta diff --git a/.idea/.idea.Continentis/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.Continentis/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..79ee123c --- /dev/null +++ b/.idea/.idea.Continentis/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/Assets/Mods/Basic/Basic_CombatOrganizer.asset b/Assets/Mods/Basic/Basic_CombatOrganizer.asset index b677cfe2..fbd847b2 100644 --- a/Assets/Mods/Basic/Basic_CombatOrganizer.asset +++ b/Assets/Mods/Basic/Basic_CombatOrganizer.asset @@ -18,5 +18,4 @@ MonoBehaviour: - CharacterData_Basic_Assassin - CharacterData_Basic_Cleric enemyCharacters: - - CharacterData_Basic_MarshalOfTheUnderworld - - CharacterData_Basic_MarshalOfTheUnderworld + - CharacterData_Basic_MarshalOfUnderworld diff --git a/Assets/Mods/Basic/Basic_Manifest.asset b/Assets/Mods/Basic/Basic_Manifest.asset index 98e44b9a..98512083 100644 --- a/Assets/Mods/Basic/Basic_Manifest.asset +++ b/Assets/Mods/Basic/Basic_Manifest.asset @@ -18,16 +18,17 @@ MonoBehaviour: - KeywordData_Basic_Buff_Assassin - KeywordData_Basic_Default cardDataIDList: + - CardData_Basic_AblazeInPurgatory + - CardData_Basic_HellfireBrand + - CardData_Basic_SoulCleave + - CardData_Basic_ArmyOfTheDead + - CardData_Basic_GreatswordSweep + - CardData_Basic_HellfireBlast + - CardData_Basic_NecromanticInfusion + - CardData_Basic_WrathOfUnderworld - CardData_Basic_Rouse - CardData_Basic_Tactic - CardData_Basic_Whimsy - - CardData_Basic_AblazeInPurgatory - - CardData_Basic_ArmyOfTheDead - - CardData_Basic_HellfireBlast - - CardData_Basic_HellfireBrand - - CardData_Basic_NecromanticInfusion - - CardData_Basic_SoulCleave - - CardData_Basic_WrathOfTheUnderworld - CardData_Basic_Bludgeon - CardData_Basic_DualStrike - CardData_Basic_FireBolt @@ -105,7 +106,7 @@ MonoBehaviour: - CharacterData_Basic_Cleric - CharacterData_Basic_Knight - CharacterData_Basic_Mage - - CharacterData_Basic_MarshalOfTheUnderworld + - CharacterData_Basic_MarshalOfUnderworld - CharacterData_Basic_SkeletonGuard equipmentDataIDList: - EquipmentData_Basic_SteelBracer diff --git a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion.meta b/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion.meta deleted file mode 100644 index 4be6c477..00000000 --- a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3665151d5823cfb4990befbc8e4dbc62 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/CardData_Basic_NecromanticInfusion.asset b/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/CardData_Basic_NecromanticInfusion.asset similarity index 75% rename from Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/CardData_Basic_NecromanticInfusion.asset rename to Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/CardData_Basic_NecromanticInfusion.asset index cdab567b..ede33485 100644 --- a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/CardData_Basic_NecromanticInfusion.asset +++ b/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/CardData_Basic_NecromanticInfusion.asset @@ -13,18 +13,32 @@ MonoBehaviour: m_Name: CardData_Basic_NecromanticInfusion m_EditorClassIdentifier: modName: Basic + categoryName: className: NecromanticInfusion displayName: Card_Basic_NecromanticInfusion_DisplayName - cardRarity: 40 + cardRarity: 30 cardType: 10 - tags: [] + keywords: + - TargetEnemies cardSprite: {fileID: 21300000, guid: 4319eef242cf5a94cace1528f74bfe42, type: 3} + cardLayoutTags: [] functionText: Card_Basic_NecromanticInfusion_FunctionText - cardDescription: $Keyword("Exhaust"), Apply 50% Lifesteal amplification to all - allies. - baseWeight: 10 + cardDescription: + baseWeight: 0 variableAttributes: - dictionaryList: [] + dictionaryList: + - Key: TargetCount + Value: 1 + index: 0 + isKeyDuplicated: 0 + - Key: StaminaCost + Value: 2 + index: 1 + isKeyDuplicated: 0 + - Key: ManaCost + Value: 0 + index: 2 + isKeyDuplicated: 0 dividerPosProp: 0.5 originalAttributes: dictionaryList: [] diff --git a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/CardData_Basic_NecromanticInfusion.asset.meta b/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/CardData_Basic_NecromanticInfusion.asset.meta similarity index 100% rename from Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/CardData_Basic_NecromanticInfusion.asset.meta rename to Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/CardData_Basic_NecromanticInfusion.asset.meta diff --git a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/NecromanticInfusion.cs b/Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/NecromanticInfusion.cs similarity index 59% rename from Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/NecromanticInfusion.cs rename to Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/NecromanticInfusion.cs index 6713f407..92ab4f38 100644 --- a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/NecromanticInfusion.cs +++ b/Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/NecromanticInfusion.cs @@ -12,16 +12,18 @@ namespace Continentis.Mods.Basic.Cards { protected override List PlayEffect(List targetList) { - base.PlayEffect(targetList); + CommandGroup main = new CommandGroup(new Cmd_Function(() => + { + CreateCharacterBuff(2).Apply(user, user, this); + })); - CommandGroup mainGroup = TargetListCommandGroup(targetList, ExecutionMode.Parallel, ExecutionMode.Parallel, + CommandGroup weak = TargetListCommandGroup(targetList, new Cmd_ParamFunction(0.2f, target => { - Basic_SoulAbsorption buff = new Basic_SoulAbsorption(50); - buff.Apply(target, user, this); + CreateCharacterBuff(2).Apply(target, user, this); })); - return new List { mainGroup }; + return new List { main, weak }; } } } \ No newline at end of file diff --git a/Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/NecromanticInfusion.cs.meta b/Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/NecromanticInfusion.cs.meta similarity index 100% rename from Assets/Mods/Basic/Cards/Data/Enemies/Bosses/MarshalOfUnderworld/Basic_NecromanticInfusion/NecromanticInfusion.cs.meta rename to Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/NecromanticInfusion.cs.meta diff --git a/Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/WrathOfUnderworld.cs b/Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/WrathOfUnderworld.cs index 9db45396..4257e4ed 100644 --- a/Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/WrathOfUnderworld.cs +++ b/Assets/Mods/Basic/Cards/Scripts/Enemies/Bosses/MarshalOfUnderworld/WrathOfUnderworld.cs @@ -18,8 +18,6 @@ namespace Continentis.Mods.Basic.Cards protected override List PlayEffect(List targetList) { - base.PlayEffect(targetList); - CommandGroup singleTargetGroup = new CommandGroup(ExecutionMode.Parallel, new Cmd_PlayAnimation(user.characterView, "Attack"), new Cmd_ParamFunction(0.4f, target => diff --git a/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfTheUnderworld.asset b/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfUnderworld.asset similarity index 91% rename from Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfTheUnderworld.asset rename to Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfUnderworld.asset index 52fd5cde..b12e7bb9 100644 --- a/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfTheUnderworld.asset +++ b/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfUnderworld.asset @@ -10,13 +10,13 @@ MonoBehaviour: m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: b6560183465e5944ba49e39974faafd4, type: 3} - m_Name: CharacterData_Basic_MarshalOfTheUnderworld + m_Name: CharacterData_Basic_MarshalOfUnderworld m_EditorClassIdentifier: - haveCustomClass: 0 - classFullName: + haveCustomClass: 1 + classFullName: MarshalOfUnderworld modName: Basic - className: MarshalOfTheUnderworld - displayName: Marshal Of The Underworld + className: MarshalOfUnderworld + displayName: Marshal Of Underworld tags: [] avatar: {fileID: 21300000, guid: 8b60e98b9ca5e6a4587341cd27607e24, type: 3} portrait: {fileID: 0} @@ -144,7 +144,7 @@ MonoBehaviour: index: 20 isKeyDuplicated: 0 - Key: StaminaRecoverPerAction - Value: 0 + Value: 4 index: 21 isKeyDuplicated: 0 - Key: ManaRecoverPerAction @@ -192,6 +192,11 @@ MonoBehaviour: prefabRefs: [] derivativeCardDataRefs: [] derivativeCharacterDataRefs: [] - initialDeckRef: [] + initialDeckRef: + - CardData_Basic_ArmyOfTheDead + - CardData_Basic_GreatswordSweep + - CardData_Basic_HellfireBlast + - CardData_Basic_WrathOfUnderworld + - CardData_Basic_NecromanticInfusion hudDataRefs: - HUDData_Basic_Default diff --git a/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfTheUnderworld.asset.meta b/Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfUnderworld.asset.meta similarity index 100% rename from Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfTheUnderworld.asset.meta rename to Assets/Mods/Basic/Characters/Data/CharacterData_Basic_MarshalOfUnderworld.asset.meta diff --git a/Assets/Mods/Basic/Characters/Scripts/MarshalOfUnderworld.cs b/Assets/Mods/Basic/Characters/Scripts/MarshalOfUnderworld.cs new file mode 100644 index 00000000..491f6e03 --- /dev/null +++ b/Assets/Mods/Basic/Characters/Scripts/MarshalOfUnderworld.cs @@ -0,0 +1,130 @@ +using System.Collections.Generic; +using System.Linq; +using Continentis.MainGame.Card; +using Continentis.MainGame.Character; +using Continentis.MainGame.Combat; +using Continentis.Mods.Basic.Buffs; +using Continentis.Mods.Basic.Cards; +using UnityEngine; + +namespace Continentis.Mods.Basic.Characters +{ + public class MarshalOfUnderworld : CharacterLogicBase + { + public override void Initialize(CharacterBase character) + { + base.Initialize(character); + character.RegisterIntention( + new Normal(character.intentionSubmodule), + new SummonFirst(character.intentionSubmodule), + new UltimateAttackFirst(character.intentionSubmodule)); + } + + private class Normal : IntentionBase + { + public Normal(IntentionSubmodule intentionSubmodule) : base(intentionSubmodule) + { + + } + + public override void RefreshCardWeights() + { + characterDeck.PoolPile.ForEach(card => + { + card.cardLogic.weightSubmodule.baseWeight = 0; + card.cardLogic.weightSubmodule.forceUse = false; + card.cardLogic.weightSubmodule.forceIgnore = false; + }); + + foreach (CardInstance card in characterDeck.PoolPile) + { + if (card.cardLogic is HellfireBlast) + { + card.cardLogic.weightSubmodule.baseWeight = 1; + } + else if (card.cardLogic is NecromanticInfusion) + { + if (characterRecord.GetLastActionsRecords(3) + .Any(rec => rec.cardsPlayed.Any(recCard => recCard.cardLogic is NecromanticInfusion))) + { + card.cardLogic.weightSubmodule.baseWeight = 0; + } + else + { + card.cardLogic.weightSubmodule.baseWeight = 1; + } + } + else if (card.cardLogic is GreatswordSweep) + { + card.cardLogic.weightSubmodule.baseWeight = 1; + } + } + } + } + + private class SummonFirst : Normal + { + public SummonFirst(IntentionSubmodule intentionSubmodule) : base(intentionSubmodule) + { + Priority = 20; + } + + public override bool Condition() + { + List allies = CombatMainManager.Instance.characterController.GetAllAllies(character); + return allies.Count == 1; // Only self is present + } + + public override void RefreshCardWeights() + { + base.RefreshCardWeights(); + + foreach (CardInstance card in characterDeck.PoolPile) + { + if (card.cardLogic is ArmyOfTheDead) + { + card.cardLogic.weightSubmodule.forceUse = true; + } + } + } + } + + private class UltimateAttackFirst : Normal + { + public UltimateAttackFirst(IntentionSubmodule intentionSubmodule) : base(intentionSubmodule) + { + Priority = 10; + } + + public override bool Condition() + { + List targets = CombatMainManager.Instance.characterController.GetAllEnemies(character); + foreach (CharacterBase target in targets) + { + if (target.combatBuffSubmodule.TryGetBuff(out Burn burn)) + { + if (burn.unitedStackSubmodule.stackAmount >= 5) + { + return true; + } + } + } + + return false; + } + + public override void RefreshCardWeights() + { + base.RefreshCardWeights(); + + foreach (CardInstance card in characterDeck.PoolPile) + { + if (card.cardLogic is WrathOfUnderworld) + { + card.cardLogic.weightSubmodule.forceUse = true; + } + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Mods/Basic/Characters/Scripts/MarshallOfUnderworld.cs.meta b/Assets/Mods/Basic/Characters/Scripts/MarshalOfUnderworld.cs.meta similarity index 100% rename from Assets/Mods/Basic/Characters/Scripts/MarshallOfUnderworld.cs.meta rename to Assets/Mods/Basic/Characters/Scripts/MarshalOfUnderworld.cs.meta diff --git a/Assets/Mods/Basic/Characters/Scripts/MarshallOfUnderworld.cs b/Assets/Mods/Basic/Characters/Scripts/MarshallOfUnderworld.cs deleted file mode 100644 index 994b82cf..00000000 --- a/Assets/Mods/Basic/Characters/Scripts/MarshallOfUnderworld.cs +++ /dev/null @@ -1,16 +0,0 @@ -using UnityEngine; - -public class MarshallOfUnderworld : MonoBehaviour -{ - // Start is called once before the first execution of Update after the MonoBehaviour is created - void Start() - { - - } - - // Update is called once per frame - void Update() - { - - } -} diff --git a/Assets/Mods/Basic/Rules/Basic_AttributeRulesCollection.cs b/Assets/Mods/Basic/Rules/Basic_AttributeRulesCollection.cs index 24ae2dbe..656fdf6e 100644 --- a/Assets/Mods/Basic/Rules/Basic_AttributeRulesCollection.cs +++ b/Assets/Mods/Basic/Rules/Basic_AttributeRulesCollection.cs @@ -9,6 +9,11 @@ namespace Continentis.Mods.Basic.Rules { public override void ApplyRules_ConvertCoreIntoGeneral(Dictionary core, Dictionary general) { + if (core.TryGetValue("DisableConversion", out float value) && value > 0) //如果禁用属性转换,则直接返回 + { + return; + } + float level = core["Level"]; general["MaximumHealth"] += Mathf.FloorToInt(level * 3); general["MaximumMana"] += Mathf.FloorToInt(level / 2); diff --git a/Assets/Scripts/MainGame/Card/CardData/CardData.cs b/Assets/Scripts/MainGame/Card/CardData/CardData.cs index 02a0fa19..65424ffd 100644 --- a/Assets/Scripts/MainGame/Card/CardData/CardData.cs +++ b/Assets/Scripts/MainGame/Card/CardData/CardData.cs @@ -43,7 +43,7 @@ namespace Continentis.MainGame.Card public string functionText; public string cardDescription; - [Header("Intention")] public float baseWeight = 1f; + [Header("Intention")] public float baseWeight = 0f; [Header("Attributes")] [Tooltip("可变属性,这个属性会自动设置BaseAttr进入Original,设置Attr,BaseAttrOffset=0,以及DisplayAttr进入Current")] public SerializableDictionary variableAttributes = new SerializableDictionary(); diff --git a/Assets/Scripts/MainGame/Card/CardInstance.cs b/Assets/Scripts/MainGame/Card/CardInstance.cs index 6feb4108..07c73237 100644 --- a/Assets/Scripts/MainGame/Card/CardInstance.cs +++ b/Assets/Scripts/MainGame/Card/CardInstance.cs @@ -12,9 +12,11 @@ namespace Continentis.MainGame.Card [Header("References")] public DeckSubmodule deck; //public string currentPileName; + public ICardOwner owner; public CharacterBase user; - public CombatTeam team; + public CombatTeam usingTeam; + public CardLogicBase cardLogic; public CardLocation cardLocation; public HandCardView handCardView; @@ -29,11 +31,11 @@ namespace Continentis.MainGame.Card this.user = owner as CharacterBase; if (this.owner is CombatTeam team) { - this.team = team; + this.usingTeam = team; } else if (this.owner is CharacterBase character) { - this.team = character.team; + this.usingTeam = character.team; } this.deck = owner.deckSubmodule; diff --git a/Assets/Scripts/MainGame/Card/CardLogicBase.cs b/Assets/Scripts/MainGame/Card/CardLogicBase.cs index 65639608..1568c06e 100644 --- a/Assets/Scripts/MainGame/Card/CardLogicBase.cs +++ b/Assets/Scripts/MainGame/Card/CardLogicBase.cs @@ -19,7 +19,7 @@ namespace Continentis.MainGame.Card public ICardOwner owner => cardInstance.owner; public CharacterBase user => cardInstance.user; - public CombatTeam team => cardInstance.team; + public CombatTeam UsingTeam => cardInstance.usingTeam; public HandCardView handCardView => cardInstance.handCardView; public IntentionCardView intentionCardView => cardInstance.intentionCardView; @@ -173,7 +173,7 @@ namespace Continentis.MainGame.Card { protected CardLogicBase card; protected CharacterBase user => card.user; - protected CombatTeam team => card.team; + protected CombatTeam team => card.UsingTeam; public virtual void Initialize(CardLogicBase card) { diff --git a/Assets/Scripts/MainGame/Card/CardMainFunctions.cs b/Assets/Scripts/MainGame/Card/CardMainFunctions.cs index 64f1a8b0..1780c769 100644 --- a/Assets/Scripts/MainGame/Card/CardMainFunctions.cs +++ b/Assets/Scripts/MainGame/Card/CardMainFunctions.cs @@ -176,6 +176,7 @@ namespace Continentis.MainGame.Card } cardInstance.user = user ?? CombatMainManager.Instance.currentCharacter; + cardInstance.user.recordSubmodule.RecordCardPlay(cardInstance); if (!willCheckBeforePlay || CheckBeforePlay()) { @@ -212,7 +213,10 @@ namespace Continentis.MainGame.Card }); AfterPlayEffect(targetList); playSubmodule.isDuringPlayEffect = false; - handCardView.isDuringPlaying = false; + if (handCardView != null) + { + handCardView.isDuringPlaying = false; + } })); return true; } diff --git a/Assets/Scripts/MainGame/Card/CardSubmodules/WeightSubmodule.cs b/Assets/Scripts/MainGame/Card/CardSubmodules/WeightSubmodule.cs index 31a9e029..1a578acc 100644 --- a/Assets/Scripts/MainGame/Card/CardSubmodules/WeightSubmodule.cs +++ b/Assets/Scripts/MainGame/Card/CardSubmodules/WeightSubmodule.cs @@ -17,5 +17,10 @@ namespace Continentis.MainGame.Card this.baseWeight = owner.cardData.baseWeight; this.currentWeight = baseWeight; } + + public void RefreshCurrentWeight() + { + this.currentWeight = baseWeight; + } } } \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Character/CharacterBase.cs b/Assets/Scripts/MainGame/Character/CharacterBase.cs index c10b9950..3172232c 100644 --- a/Assets/Scripts/MainGame/Character/CharacterBase.cs +++ b/Assets/Scripts/MainGame/Character/CharacterBase.cs @@ -4,6 +4,7 @@ using System.Linq; using Continentis.MainGame.Card; using Continentis.MainGame.Combat; using NaughtyAttributes; +using SLSFramework.UModAssistance; using UnityEngine; using Object = UnityEngine.Object; using Random = UnityEngine.Random; @@ -28,6 +29,7 @@ namespace Continentis.MainGame.Character public Guid elementID { get; set; } public CharacterData data; + public CharacterLogicBase logicBase; public Fraction fraction; public CombatTeam team; @@ -54,13 +56,17 @@ namespace Continentis.MainGame.Character [ShowNativeProperty] public CombatBuffSubmodule combatBuffSubmodule { get; private set; } + + [ShowNativeProperty] + public RecordSubmodule recordSubmodule { get; private set; } - public void Initialize(Fraction fraction) + public virtual void Initialize(Fraction fraction, CharacterData data) { (this as IGameElement).Initialize(); this.fraction = fraction; - + this.data = data; + switch (fraction) { case Fraction.Player: @@ -81,6 +87,33 @@ namespace Continentis.MainGame.Character intentionSubmodule = new IntentionSubmodule(this); statusSubmodule = new StatusSubmodule(this); combatBuffSubmodule = new CombatBuffSubmodule(this); + recordSubmodule = new RecordSubmodule(this); + + this.logicBase = GenerateCharacterLogic(data); + this.logicBase.Initialize(this); + + } + + /// + /// 生成卡牌逻辑实例 + /// + public static CharacterLogicBase GenerateCharacterLogic(CharacterData data) + { + string typeID = ModManager.GetTypeID(data.modName, "Characters", "", data.className); + Type logicType = ModManager.GetType(typeID); + + if(logicType == null) + { + return new CharacterLogicBase(); + } + + if (Activator.CreateInstance(logicType) is CharacterLogicBase logic) + { + return logic; + } + + Debug.LogError($"Card class '{typeID}' not found or could not be instantiated."); + return null; } } @@ -88,124 +121,6 @@ namespace Continentis.MainGame.Character { public CombatCharacterViewBase characterView; } - - public partial class CharacterBase - { - public virtual void GetIntendedCards() - { - bool CanAfford(CardInstance card, int stamina, int mana) - { - return card.cardLogic.GetAttribute("StaminaCost") <= stamina && - card.cardLogic.GetAttribute("ManaCost") <= mana; - } - - bool CheckAvailabilityAndSetTargets(CardInstance card, out List targets) - { - card.cardLogic.DetectTargetsValidity(out List valid, out _, out _); - if (valid.Count == 0 || !card.cardLogic.CheckBeforePlay()) - { - targets = null; - return false; // 无有效目标或无法使用则跳过 - } - - targets = card.cardLogic.SetRandomTargets(valid); - - return true; - } - - IntentionBase currentIntention = intentionSubmodule.currentIntention; - List availableCards = deckSubmodule.PoolPile; - List intended = new List(); - int currentStamina = GetAttribute("Stamina"); - int remainingStamina = currentStamina - currentIntention.guaranteedStamina; - int currentMana = GetAttribute("Mana"); - int remainingMana = currentMana - currentIntention.guaranteedMana; - - List forced = new List(); - List normal = new List(); - - foreach (CardInstance card in availableCards) - { - if (card.cardLogic.weightSubmodule.forceUse) - { - forced.Add(card); - } - else - { - normal.Add(card); - } - } - - intentionSubmodule.intendedCards.Clear(); - //(characterView.hudContainer.enablingHUDs["Intention"] as Intention)?.Clear(); - - // 1. 优先处理强制选择卡牌 - foreach (CardInstance card in forced) - { - if (currentIntention.maxCardCount > 0 && intended.Count >= currentIntention.maxCardCount) - { - break; // 已达数量上限 - } - - if (CanAfford(card, remainingStamina, remainingMana)) - { - if(!CheckAvailabilityAndSetTargets(card, out List targets)) - { - continue; // 无有效目标或无法使用则跳过 - } - - intended.Add(new IntendedCard(card, targets)); - remainingStamina -= card.cardLogic.GetAttribute("StaminaCost"); - remainingMana -= card.cardLogic.GetAttribute("ManaCost"); - } - // 行动力不足则跳过该卡 - } - - // 2. 在剩余普通卡牌中基于权重随机选取 - while (intended.Count < currentIntention.maxCardCount) - { - // 筛选出当前资源下还能出的牌 - List affordableCards = normal.FindAll(card => CanAfford(card, remainingStamina, remainingMana)); - - if (affordableCards.Count == 0) - { - break; - } - - float totalWeight = affordableCards.Sum(card => card.cardLogic.weightSubmodule.currentWeight); - if (totalWeight <= 0f) break; - - float r = Random.value * totalWeight; - float accum = 0f; - CardInstance chosen = null; - foreach (CardInstance card in affordableCards) - { - accum += card.cardLogic.weightSubmodule.currentWeight; - if (r <= accum) - { - chosen = card; - break; - } - } - - if (chosen != null) - { - if (!CheckAvailabilityAndSetTargets(chosen, out List targets)) - { - normal.Remove(chosen); - continue; // 无有效目标或无法使用则跳过 - } - - intended.Add(new IntendedCard(chosen, targets)); - normal.Remove(chosen); - remainingStamina -= chosen.cardLogic.GetAttribute("StaminaCost"); - remainingMana -= chosen.cardLogic.GetAttribute("ManaCost"); - } - } - - intentionSubmodule.intendedCards.AddRange(intended); - } - } public partial class CharacterBase { diff --git a/Assets/Scripts/MainGame/Character/CharacterData/CharacterData.cs b/Assets/Scripts/MainGame/Character/CharacterData/CharacterData.cs index 4f36e23a..efe59e50 100644 --- a/Assets/Scripts/MainGame/Character/CharacterData/CharacterData.cs +++ b/Assets/Scripts/MainGame/Character/CharacterData/CharacterData.cs @@ -57,12 +57,6 @@ namespace Continentis.MainGame.Character public List hudDataRefs; } - public partial class CharacterData - { - public string ModName => haveCustomClass ? classFullName.Split('_').First() : modName; - public string ClassName => haveCustomClass ? classFullName.Split('_').Last() : className; - } - public partial class CharacterData { public static CharacterData Get(string dataID) diff --git a/Assets/Scripts/MainGame/Character/CharacterInstance.cs b/Assets/Scripts/MainGame/Character/CharacterInstance.cs new file mode 100644 index 00000000..229a7517 --- /dev/null +++ b/Assets/Scripts/MainGame/Character/CharacterInstance.cs @@ -0,0 +1,16 @@ +using Continentis.MainGame.Card; +using Continentis.MainGame.Equipment; +using SLSFramework.UModAssistance; +using UnityEngine; + +namespace Continentis.MainGame.Character +{ + public partial class CharacterLogicBase + { + protected CharacterBase character; + public virtual void Initialize(CharacterBase character) + { + this.character = character; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Character/CharacterInstance.cs.meta b/Assets/Scripts/MainGame/Character/CharacterInstance.cs.meta new file mode 100644 index 00000000..ea392a1a --- /dev/null +++ b/Assets/Scripts/MainGame/Character/CharacterInstance.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 59a1c52238303dc41bd58e565f7fbeda \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Character/CharacterMainFunctions.cs b/Assets/Scripts/MainGame/Character/CharacterMainFunctions.cs index 33e991a1..3cdc380c 100644 --- a/Assets/Scripts/MainGame/Character/CharacterMainFunctions.cs +++ b/Assets/Scripts/MainGame/Character/CharacterMainFunctions.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Continentis.MainGame.Card; using Continentis.MainGame.Equipment; using SLSFramework.General; @@ -278,4 +279,136 @@ namespace Continentis.MainGame.Character target.characterView.hudContainer.UpdateAllHUD(); } } + + public partial class CharacterBase + { + public virtual void RegisterIntention(params IntentionBase[] intentions) + { + intentionSubmodule.allIntentions.AddRange(intentions); + } + + public virtual void IntentionBrain() + { + List availableIntentions = intentionSubmodule.allIntentions.Where(intention => intention.Condition()).ToList(); + availableIntentions.Sort(); + intentionSubmodule.currentIntention = availableIntentions.FirstOrDefault() ?? new IntentionBase(intentionSubmodule); + intentionSubmodule.currentIntention.RefreshCardWeights(); + intentionSubmodule.currentIntention.RefreshTargets(); + } + + public virtual void GetIntendedCards() + { + bool CanAfford(CardInstance card, int stamina, int mana) + { + return card.cardLogic.GetAttribute("StaminaCost") <= stamina && + card.cardLogic.GetAttribute("ManaCost") <= mana; + } + + bool CheckAvailabilityAndSetTargets(CardInstance card, out List targets) + { + card.cardLogic.DetectTargetsValidity(out List valid, out _, out _); + if (valid.Count == 0 || !card.cardLogic.CheckBeforePlay()) + { + targets = null; + return false; // 无有效目标或无法使用则跳过 + } + + targets = card.cardLogic.SetRandomTargets(valid); + + return true; + } + + IntentionBase currentIntention = intentionSubmodule.currentIntention; + List availableCards = deckSubmodule.PoolPile; + List intended = new List(); + int currentStamina = GetAttribute("Stamina"); + int remainingStamina = currentStamina - currentIntention.guaranteedStamina; + int currentMana = GetAttribute("Mana"); + int remainingMana = currentMana - currentIntention.guaranteedMana; + + List forced = new List(); + List normal = new List(); + + foreach (CardInstance card in availableCards) + { + if (card.cardLogic.weightSubmodule.forceUse) + { + forced.Add(card); + } + else + { + normal.Add(card); + } + } + + intentionSubmodule.intendedCards.Clear(); + //(characterView.hudContainer.enablingHUDs["Intention"] as Intention)?.Clear(); + + // 1. 优先处理强制选择卡牌 + foreach (CardInstance card in forced) + { + if (currentIntention.maxCardCount > 0 && intended.Count >= currentIntention.maxCardCount) + { + break; // 已达数量上限 + } + + if (CanAfford(card, remainingStamina, remainingMana)) + { + if(!CheckAvailabilityAndSetTargets(card, out List targets)) + { + continue; // 无有效目标或无法使用则跳过 + } + + intended.Add(new IntendedCard(card, targets)); + remainingStamina -= card.cardLogic.GetAttribute("StaminaCost"); + remainingMana -= card.cardLogic.GetAttribute("ManaCost"); + } + // 行动力不足则跳过该卡 + } + + // 2. 在剩余普通卡牌中基于权重随机选取 + while (intended.Count < currentIntention.maxCardCount) + { + // 筛选出当前资源下还能出的牌 + List affordableCards = normal.FindAll(card => CanAfford(card, remainingStamina, remainingMana)); + + if (affordableCards.Count == 0) + { + break; + } + + float totalWeight = affordableCards.Sum(card => card.cardLogic.weightSubmodule.currentWeight); + if (totalWeight <= 0f) break; + + float r = Random.value * totalWeight; + float accum = 0f; + CardInstance chosen = null; + foreach (CardInstance card in affordableCards) + { + accum += card.cardLogic.weightSubmodule.currentWeight; + if (r <= accum) + { + chosen = card; + break; + } + } + + if (chosen != null) + { + if (!CheckAvailabilityAndSetTargets(chosen, out List targets)) + { + normal.Remove(chosen); + continue; // 无有效目标或无法使用则跳过 + } + + intended.Add(new IntendedCard(chosen, targets)); + normal.Remove(chosen); + remainingStamina -= chosen.cardLogic.GetAttribute("StaminaCost"); + remainingMana -= chosen.cardLogic.GetAttribute("ManaCost"); + } + } + + intentionSubmodule.intendedCards.AddRange(intended); + } + } } \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Character/CharacterSubmodules/IntentionSubmodule.cs b/Assets/Scripts/MainGame/Character/CharacterSubmodules/IntentionSubmodule.cs index 567e88d2..c05b00ce 100644 --- a/Assets/Scripts/MainGame/Character/CharacterSubmodules/IntentionSubmodule.cs +++ b/Assets/Scripts/MainGame/Character/CharacterSubmodules/IntentionSubmodule.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Continentis.MainGame.Card; +using SLSFramework.General; using UnityEngine; using UnityEngine.Events; @@ -8,6 +9,7 @@ namespace Continentis.MainGame.Character { public class IntentionSubmodule : SubmoduleBase { + public List allIntentions; public IntentionBase currentIntention; public UnityAction getIntendedCards; @@ -15,7 +17,8 @@ namespace Continentis.MainGame.Character public IntentionSubmodule(CharacterBase owner) : base(owner) { - currentIntention = new IntentionBase(); + allIntentions = new List(); + currentIntention = new IntentionBase(this); getIntendedCards = owner.GetIntendedCards; intendedCards = new List(); } @@ -33,11 +36,30 @@ namespace Continentis.MainGame.Character } } - public class IntentionBase + public class IntentionBase : IPrioritized { - public int guaranteedStamina = 0; - public int guaranteedMana = 0; - public int maxCardCount = 999; + public IntentionSubmodule intentionSubmodule; + public CharacterBase character => intentionSubmodule.owner; + public DeckSubmodule characterDeck => character.deckSubmodule; + public RecordSubmodule characterRecord => character.recordSubmodule; + public int Priority { get; protected set; } + public int guaranteedStamina; + public int guaranteedMana; + public int maxCardCount; + + public IntentionBase(IntentionSubmodule intentionSubmodule) + { + this.intentionSubmodule = intentionSubmodule; + this.Priority = 0; + this.guaranteedStamina = 0; + this.guaranteedMana = 0; + this.maxCardCount = 999; + } + + public virtual bool Condition() + { + return true; + } public virtual void RefreshCardWeights() { @@ -48,5 +70,7 @@ namespace Continentis.MainGame.Character { } + + } } \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs b/Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs new file mode 100644 index 00000000..10d4a660 --- /dev/null +++ b/Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Continentis.MainGame.Card; +using UnityEngine; + +namespace Continentis.MainGame.Character +{ + public partial class RecordSubmodule : SubmoduleBase + { + public int currentRound; + public int currentAction; + public List actionRecords; + + public RecordSubmodule(CharacterBase owner) : base(owner) + { + actionRecords = new List(); + } + + public void SetAction(int round, int actionIndex) + { + currentRound = round; + currentAction = actionIndex; + actionRecords.Add(new ActionRecord(round, actionIndex, new List())); + } + } + + public partial class RecordSubmodule + { + public void RecordCardPlay(CardInstance card) + { + if (actionRecords.Count == 0) + { + Debug.LogWarning("No action record to add card play to."); + return; + } + ActionRecord currentRecord = actionRecords[actionRecords.Count - 1]; + currentRecord.cardsPlayed.Add(card); + Debug.Log($"在回合 {currentRecord.round} 行动 {currentRecord.actionIndex} 中记录了卡牌 {card.cardLogic.contentSubmodule.cardName} 的使用。"); + } + } + + public partial class RecordSubmodule + { + public ActionRecord GetRecord(int round, int actionIndex) + { + return actionRecords.FirstOrDefault(record => record.round == round && record.actionIndex == actionIndex); + } + + public List GetLastActionsRecords(int count) + { + return actionRecords.Skip(Mathf.Max(0, actionRecords.Count - count)).ToList(); + } + + public List GetLastRoundsRecords(int roundCount) + { + int minRound = Mathf.Max(0, currentRound - roundCount + 1); + return actionRecords.Where(record => record.round >= minRound).ToList(); + } + } + + [Serializable] + public class ActionRecord + { + public int round; + public int actionIndex; + public List cardsPlayed; + + public ActionRecord(int round, int actionIndex, List cardsPlayed) + { + this.round = round; + this.actionIndex = actionIndex; + this.cardsPlayed = cardsPlayed; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs.meta b/Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs.meta new file mode 100644 index 00000000..c7939f6d --- /dev/null +++ b/Assets/Scripts/MainGame/Character/CharacterSubmodules/RecordSubmodule.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 95504a2d65ce1fa4d82cbdb23ef16892 \ No newline at end of file diff --git a/Assets/Scripts/MainGame/Character/CombatNPC.cs b/Assets/Scripts/MainGame/Character/CombatNPC.cs index 55385dc1..abcddf33 100644 --- a/Assets/Scripts/MainGame/Character/CombatNPC.cs +++ b/Assets/Scripts/MainGame/Character/CombatNPC.cs @@ -13,8 +13,7 @@ namespace Continentis.MainGame.Character public static CombatNPC GenerateCharacter(CharacterData data, Fraction fraction) { CombatNPC combatNpc = new CombatNPC(); - combatNpc.data = data; - combatNpc.Initialize(fraction); + combatNpc.Initialize(fraction, data); return combatNpc; } diff --git a/Assets/Scripts/MainGame/Character/Editor/CharacterDataEditor.cs b/Assets/Scripts/MainGame/Character/Editor/CharacterDataEditor.cs index 4ce6f814..f81aa87d 100644 --- a/Assets/Scripts/MainGame/Character/Editor/CharacterDataEditor.cs +++ b/Assets/Scripts/MainGame/Character/Editor/CharacterDataEditor.cs @@ -77,7 +77,7 @@ namespace Continentis.MainGame.Character if (_haveCustomClassProp.boolValue) { // 如果勾选,则显示class选择器 - DrawSearchableTypeSelector(_classFullNameProp, "Character Class", typeof(CharacterBase), null, "Continentis.Mods", "Characters"); + DrawSearchableTypeSelector(_classFullNameProp, "Character Logic Class", typeof(CharacterLogicBase), null, "Continentis.Mods", "Characters"); } else { diff --git a/Assets/Scripts/MainGame/Character/PlayerHero.cs b/Assets/Scripts/MainGame/Character/PlayerHero.cs index 23dd788d..1b9d8841 100644 --- a/Assets/Scripts/MainGame/Character/PlayerHero.cs +++ b/Assets/Scripts/MainGame/Character/PlayerHero.cs @@ -16,8 +16,7 @@ namespace Continentis.MainGame.Character public static PlayerHero GenerateCharacter(CharacterData data) { PlayerHero playerHero = new PlayerHero(); - playerHero.data = data; - playerHero.Initialize(Fraction.Player); + playerHero.Initialize(Fraction.Player, data); return playerHero; } diff --git a/Assets/Scripts/MainGame/Combat/CombatMainManager.cs b/Assets/Scripts/MainGame/Combat/CombatMainManager.cs index b753eb7d..97f94229 100644 --- a/Assets/Scripts/MainGame/Combat/CombatMainManager.cs +++ b/Assets/Scripts/MainGame/Combat/CombatMainManager.cs @@ -103,6 +103,9 @@ namespace Continentis.MainGame.Combat { if (character is CombatNPC npc) { + npc.IntentionBrain(); + npc.deckSubmodule.PoolPile.ForEach(card => card.cardLogic.weightSubmodule.RefreshCurrentWeight()); + npc.intentionSubmodule.getIntendedCards.Invoke(); foreach (IntendedCard intendedCard in npc.intentionSubmodule.intendedCards) { @@ -144,6 +147,7 @@ namespace Continentis.MainGame.Combat currentCharacter = characterController.actionOrderList[0]; currentCharacter.eventSubmodule.onActionStart.Invoke(); + currentCharacter.recordSubmodule.SetAction(currentRound, ++currentActionIndex); if (currentCharacter is PlayerHero playerHero) { diff --git a/Assets/Scripts/ScriptExtensions/UModAssistance/ModBrowser.cs b/Assets/Scripts/ScriptExtensions/UModAssistance/ModBrowser.cs index 2697ef7a..f0a3b24c 100644 --- a/Assets/Scripts/ScriptExtensions/UModAssistance/ModBrowser.cs +++ b/Assets/Scripts/ScriptExtensions/UModAssistance/ModBrowser.cs @@ -55,7 +55,7 @@ namespace SLSFramework.UModAssistance { ModHost host = await ModManager.LoadAsync(mod); ModManager.RegisterTypesFromMod(host, typeof(RulesCollectionBase)); - ModManager.RegisterTypesFromMod(host, typeof(CharacterBase)); + ModManager.RegisterTypesFromMod(host, typeof(CharacterLogicBase)); ModManager.RegisterTypesFromMod(host, typeof(CardLogicBase)); ModManager.RegisterTypesFromMod(host, typeof(EquipmentBase)); ModManager.RegisterTypesFromMod(host, typeof(CardCombatBuffBase));