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));