Card爆改!

This commit is contained in:
SoulliesOfficial
2025-11-15 12:17:34 -05:00
parent 85bbe2431c
commit 5fe665d0ce
121 changed files with 838 additions and 783 deletions

View File

@@ -21,7 +21,7 @@ namespace Continentis.MainGame
}
}
public static void InterpretText(CardLogicBase card, bool overrideDescription = false)
public static void InterpretText(CardInstance card, bool overrideDescription = false)
{
//card.contentSubmodule.keywords.Clear();
@@ -46,7 +46,7 @@ namespace Continentis.MainGame
public static partial class CardTextInterpreter
{
private static string GetAttribute(CardLogicBase card, string attributeName, bool higherIsBetter, bool inPercent)
private static string GetAttribute(CardInstance card, string attributeName, bool higherIsBetter, bool inPercent)
{
string displayName = "Display" + attributeName;
string baseName = "Base" + attributeName;
@@ -66,14 +66,14 @@ namespace Continentis.MainGame
}
}
private static string GetAttribute(CardLogicBase card, string attributeName, bool inPercent)
private static string GetAttribute(CardInstance card, string attributeName, bool inPercent)
{
string displayName = "Display" + attributeName;
int displayValue = card.GetAttribute(displayName);
return DynamicTextInterpreter.GetValue(displayValue, inPercent);
}
private static string RemoveWhenSelecting(CardLogicBase card, string toRemove)
private static string RemoveWhenSelecting(CardInstance card, string toRemove)
{
return card.handCardView != null && card.handCardView.isSelecting ? "" : toRemove;
}

View File

@@ -11,7 +11,7 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
#region Fundamental
public partial class CardLogicBase
public partial class CardInstance
{
public List<string> GetElementalKeywords(List<string> overrideKeywords = null)
{
@@ -25,223 +25,9 @@ namespace Continentis.MainGame.Card
}
}
#endregion
#region Command
public partial class CardLogicBase
{
/// <summary>
/// 创建一个命令组,组内命令按顺序执行
/// </summary>
/// <param name="commands">命令模板</param>
protected CommandGroup SingleCommandGroup(params CommandBase[] commands)
{
return SingleCommandGroup(ExecutionMode.Parallel, commands);
}
/// <summary>
/// 创建一个命令组,组内命令按指定顺序执行
/// </summary>
/// <param name="executionMode">执行模式,顺序或并行</param>
/// <param name="commands">命令模板</param>
protected virtual CommandGroup SingleCommandGroup(
ExecutionMode executionMode = ExecutionMode.Parallel, params CommandBase[] commands)
{
CommandGroup singleGroup = new CommandGroup(executionMode);
foreach (CommandBase template in commands)
{
singleGroup.AddCommand(template.Clone());
}
return singleGroup;
}
/// <summary>
/// 对目标列表中的每个目标依次执行一组有参函数命令每组命令的参数为targetList中的个体主体Group顺序执行单体Group并行执行。
/// </summary>
/// <param name="targetList">目标列表</param>
/// <param name="singleCommands">单体命令模板</param>
protected CommandGroup TargetListCommandGroup(List<CharacterBase> targetList,
params CommandBase[] singleCommands)
{
return TargetListCommandGroup(targetList, ExecutionMode.Sequential, ExecutionMode.Parallel, singleCommands);
}
/// <summary>
/// 对目标列表中的每个目标依次执行一组有参函数命令每组命令的参数为targetList中的个体。
/// </summary>
/// <param name="targetList">目标列表</param>
/// <param name="mainExecutionMode">主体Group各个目标的执行顺序</param>
/// <param name="singleExecutionMode">单体Group一个目标中指令的执行顺序</param>
/// <param name="singleCommands">单体命令模板</param>
protected virtual CommandGroup TargetListCommandGroup(
List<CharacterBase> targetList, ExecutionMode mainExecutionMode = ExecutionMode.Sequential,
ExecutionMode singleExecutionMode = ExecutionMode.Parallel,
params CommandBase[] singleCommands)
{
CommandGroup mainGroup = new CommandGroup(mainExecutionMode);
foreach (CharacterBase target in targetList)
{
CommandGroup singleGroup = new CommandGroup(singleExecutionMode);
foreach (CommandBase template in singleCommands)
{
CommandBase clone = template.Clone();
List<CommandBase> allCommands = new List<CommandBase>();
if (clone is CommandGroup group)
{
allCommands.AddRange(group.GetAllCommands(true));
}
else
{
allCommands.Add(clone);
}
foreach (CommandBase cmd in allCommands)
{
cmd.selfContext.context["Target"] = target;
}
singleGroup.AddCommand(clone);
}
mainGroup.AddCommand(singleGroup);
}
return mainGroup;
}
}
#endregion
#region Attack
public partial class CardLogicBase
{
/// <summary>
/// 获取最终伤害
/// </summary>
/// <param name="target">目标</param>
/// <param name="elementalTags">元素标签若为null则使用卡牌的元素标签</param>
public virtual int GetFinalDamage(CharacterBase target, List<string> elementalTags = null)
{
return GetFinalDamage(target, elementalTags, out _, out _, out _, out _);
}
/// <summary>
/// 获取最终伤害
/// </summary>
/// <param name="elementalTags">元素标签若为null则使用卡牌的元素标签</param>
public virtual int GetUserDamage(List<string> elementalTags = null)
{
return GetUserDamage(elementalTags, out _, out _, out _, out _);
}
/// <summary>
/// 获取在没有指定目标时的最终伤害值
/// </summary>
protected virtual int GetUserDamage(List<string> elementalTags,
out float baseDamageAfterOffset, out float elementalMultiplier, out float magicMultiplier, out float finalMultiplier)
{
elementalTags ??= GetElementalKeywords();
//----计算基础伤害增量----
int physicsOffset = 0;
if (HasKeyword("Physics") || HasKeyword("Slash") || HasKeyword("Prick") || HasKeyword("Strike"))
{
physicsOffset = user.GetAttribute("PhysicsDamageDealtOffset"); //物理伤害基础增量
}
int magicOffset = 0;
if (HasKeyword("Magic") || HasKeyword("Arcane") || HasKeyword("Sorcery"))
{
magicOffset = user.GetAttribute("MagicDamageDealtOffset"); //魔法伤害基础增量
}
Debug.Log("Magic Offset: " + magicOffset);
//----计算伤害因数----
//计算元素伤害加成注意“物理Physics”也是一种元素因此下方没有“通用物理伤害加成”的计算
elementalMultiplier = 1;
foreach (string element in elementalTags)
{
elementalMultiplier *= user.GetRawAttribute(element + "DamageDealtMultiplier", 1);
}
//计算通用的魔法伤害加成
magicMultiplier = 1;
if (HasKeyword("Magic") || HasKeyword("Arcane") || HasKeyword("Sorcery"))
{
magicMultiplier = user.GetRawAttribute("MagicDamageDealtMultiplier", 1);
}
//计算最终伤害加成
finalMultiplier = user.GetRawAttribute("FinalDamageDealtMultiplier", 1);
//----计算最终伤害----
baseDamageAfterOffset = attributeSubmodule.GetCurrentAttribute("Damage") + physicsOffset + magicOffset;
float finalDamage = baseDamageAfterOffset * elementalMultiplier * magicMultiplier * finalMultiplier;
return Mathf.RoundToInt(finalDamage);
}
protected virtual int GetFinalDamage(CharacterBase target, List<string> elementalTags,
out float baseDamageAfterOffset, out float elementalMultiplier, out float magicMultiplier, out float finalMultiplier)
{
elementalTags ??= GetElementalKeywords();
//----计算基础伤害增量----
int physicsOffset = 0;
if (HasKeyword("Physics") || HasKeyword("Slash") || HasKeyword("Prick") || HasKeyword("Strike"))
{
physicsOffset = user.GetAttribute("PhysicsDamageDealtOffset"); //物理伤害基础增量
}
int magicOffset = 0;
if (HasKeyword("Magic") || HasKeyword("Arcane") || HasKeyword("Sorcery"))
{
magicOffset = user.GetAttribute("MagicDamageDealtOffset"); //魔法伤害基础增量
}
//----计算伤害因数----
//计算元素伤害加成注意“物理Physics”也是一种元素因此下方没有“通用物理伤害加成”的计算
elementalMultiplier = 1;
foreach (string element in elementalTags)
{
elementalMultiplier *= user.GetRawAttribute(element + "DamageDealtMultiplier", 1) *
target.GetRawAttribute(element + "DamageGainMultiplier", 1);
}
//计算通用的魔法伤害加成
magicMultiplier = 1;
if (HasKeyword("Magic") || HasKeyword("Arcane") || HasKeyword("Sorcery"))
{
magicMultiplier = user.GetRawAttribute("MagicDamageDealtMultiplier", 1) *
target.GetRawAttribute("MagicDamageGainMultiplier", 1);
}
//计算最终伤害加成
finalMultiplier = user.GetRawAttribute("FinalDamageDealtMultiplier", 1) *
target.GetRawAttribute("FinalDamageGainMultiplier", 1);
//----计算最终伤害----
baseDamageAfterOffset = attributeSubmodule.GetCurrentAttribute("Damage") + physicsOffset + magicOffset;
float finalDamage = baseDamageAfterOffset * elementalMultiplier * magicMultiplier * finalMultiplier;
return Mathf.RoundToInt(finalDamage);
}
}
#endregion
#region Attributes
public partial class CardLogicBase
public partial class CardInstance
{
/// <summary>
/// 设置可变属性值
@@ -308,68 +94,4 @@ namespace Continentis.MainGame.Card
}
}
#endregion
#region Buffs
public partial class CardLogicBase
{
/// <summary>
/// 创建一个角色战斗Buff实例
/// 注意此函数依赖ModManager的类型注册功能请确保在Mod加载时已注册对应Buff类型
/// 此函数中的T并不是原型参数而是获取Mod中注册的类型用的
/// </summary>
public T CreateCharacterBuff<T>(params object[] parameters) where T :CharacterCombatBuffBase
{
string buffTypeID = ModManager.GetTypeID(typeof(T));
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
public T CreateCharacterBuff<T>(string buffTypeID, params object[] parameters) where T :CharacterCombatBuffBase
{
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
/// <summary>
/// 创建一个卡牌战斗Buff实例
/// 注意此函数依赖ModManager的类型注册功能请确保在Mod加载时已注册对应Buff类型
/// 此函数中的T并不是原型参数而是获取Mod中注册的类型用的
/// </summary>
public T CreateCardBuff<T>(params object[] parameters) where T :CardBuffBase
{
string buffTypeID = ModManager.GetTypeID(typeof(T));
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
public T CreateCardBuff<T>(string buffTypeID, params object[] parameters) where T :CardBuffBase
{
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
}
#endregion
}

View File

@@ -8,7 +8,7 @@ namespace Continentis.MainGame.Card
{
public abstract class CardBuffSubmodule : BuffSubmodule
{
public CardLogicBase card => (buff as CardBuffBase)?.attachedCard;
public CardInstance card => (buff as CardBuffBase)?.attachedCard;
protected CardBuffSubmodule(CardBuffBase buff) : base(buff)
{

View File

@@ -3,9 +3,9 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
public abstract partial class CardBuffBase : BuffBase<CardLogicBase>
public abstract partial class CardBuffBase : BuffBase<CardInstance>
{
public CardLogicBase attachedCard;
public CardInstance attachedCard;
public CharacterBase sourceCharacter;
public UsageSubmodule usageSubmodule;
@@ -18,11 +18,11 @@ namespace Continentis.MainGame.Card
public partial class CardBuffBase
{
public override void Apply(CardLogicBase attached)
public override void Apply(CardInstance attached)
{
this.Apply(attached, null);
}
public abstract void Apply(CardLogicBase attachedCard, CharacterBase sourceCharacter = null);
public abstract void Apply(CardInstance attachedCard, CharacterBase sourceCharacter = null);
}
}

View File

@@ -16,7 +16,7 @@ namespace Continentis.MainGame.Card
public partial class CardCombatBuffBase
{
public sealed override bool OnBuffApply(out BuffBase<CardLogicBase> existingBuff)
public sealed override bool OnBuffApply(out BuffBase<CardInstance> existingBuff)
{
throw new System.NotImplementedException("请使用类型约束更强的OnBuffApply方法");
}
@@ -70,12 +70,12 @@ namespace Continentis.MainGame.Card
return base.FindExistingSameBuff(out existingBuff, attachedCard.combatBuffSubmodule.buffList);
}
public override void Apply(CardLogicBase attachedCard, CharacterBase sourceCharacter = null)
public override void Apply(CardInstance attachedCard, CharacterBase sourceCharacter = null)
{
this.Apply(attachedCard, sourceCharacter, null);
}
public void Apply(CardLogicBase attachedCard, CharacterBase sourceCharacter = null, CardLogicBase sourceCard = null)
public void Apply(CardInstance attachedCard, CharacterBase sourceCharacter = null, CardLogicBase sourceCard = null)
{
this.attachedCard = attachedCard;
this.sourceCharacter = sourceCharacter;

View File

@@ -1,34 +1,55 @@
using System;
using System.Collections.Generic;
using Continentis.MainGame.Character;
using Continentis.MainGame.Combat;
using Continentis.MainGame.UI;
using Lean.Pool;
using NaughtyAttributes;
using SLSFramework.General;
using UniRx;
using UnityEngine;
namespace Continentis.MainGame.Card
{
public partial class CardInstance
public partial class CardInstance : IGameElement
{
public Guid elementID { get; set; }
[Header("References")]
public DeckSubmodule deck;
//public string currentPileName;
public CardLocation cardLocation;
public CardData cardData;
public CompositeDisposable disposables = new CompositeDisposable();
public ICardOwner owner;
public CharacterBase user;
public CombatTeam usingTeam;
public CardLogicBase cardLogic;
public CardLocation cardLocation;
public HandCardView handCardView;
public IntentionCardView intentionCardView;
public CardInstance(CardLogicBase cardLogic, ICardOwner owner, string initialPileName, int index = -1)
public int upgradeLevel;
[Header("Submodules")]
[ShowNativeProperty]
public AttributeSubmodule attributeSubmodule { get; private set; }
[ShowNativeProperty]
public WeightSubmodule weightSubmodule { get; private set; }
[ShowNativeProperty]
public CombatBuffSubmodule combatBuffSubmodule { get; private set; }
[ShowNativeProperty]
public EventSubmodule eventSubmodule { get; private set; }
[ShowNativeProperty]
public ContentSubmodule contentSubmodule { get; private set; }
[ShowNativeProperty]
public PlaySubmodule playSubmodule { get; private set; }
public CardInstance(CardData data, ICardOwner owner, string initialPileName, int index = -1)
{
cardLogic.cardInstance = this;
this.cardLogic = cardLogic;
(this as IGameElement).Initialize();
this.cardData = data;
this.owner = owner;
this.user = owner as CharacterBase;
if (this.owner is CombatTeam team)
{
this.usingTeam = team;
@@ -49,19 +70,30 @@ namespace Continentis.MainGame.Card
{
this.deck.Pile(cardLocation.pileName).Insert(index, this);
}
this.attributeSubmodule = new AttributeSubmodule(this);
this.weightSubmodule = new WeightSubmodule(this);
this.eventSubmodule = new EventSubmodule(this);
this.combatBuffSubmodule = new CombatBuffSubmodule(this);
this.contentSubmodule = new ContentSubmodule(this);
this.playSubmodule = new PlaySubmodule(this);
this.cardLogic = CardLogicBase.GenerateCardLogic(data);
this.cardLogic.Initialize(this);
this.cardLogic.SetUpLogicComponents();
}
/// <summary>
/// 根据CardLogic生成卡牌实例
/// </summary>
/// <param name="logic">卡牌逻辑实例</param>
/// <param name="template">卡牌实体实例</param>
/// <param name="owner">卡牌持有者</param>
/// <param name="pileName">初始卡堆名称"</param>
/// <param name="index">插入位置默认为0</param>
public static CardInstance GenerateCardInstance(CardLogicBase logic, ICardOwner owner, string pileName, int index = -1)
public static CardInstance GenerateCardInstance(CardInstance template, ICardOwner owner, string pileName, int index = -1)
{
CardInstance cardInstance = new CardInstance(logic, owner, pileName, index);
//cardInstance.cardLogic.Initialize();
CardInstance cardInstance = new CardInstance(template.cardData, owner, pileName, index);
//TODO: 复制template的属性到cardInstance
return cardInstance;
}
@@ -76,15 +108,27 @@ namespace Continentis.MainGame.Card
/// <returns></returns>
public static CardInstance GenerateCardInstance(CardData data, ICardOwner owner, string pileName, int index = -1)
{
CardInstance cardInstance = new CardInstance(CardLogicBase.GenerateCardLogic(data), owner, pileName, index);
cardInstance.cardLogic.Initialize();
CardInstance card = new CardInstance(data, owner, pileName, index);
if (owner == CombatMainManager.Instance.characterController.playerTeam)
{
CombatUIManager.Instance.combatMainPage.teamSwitchButton.UpdateTeamPileText(CombatMainManager.Instance.characterController.playerTeam);
CombatUIManager.Instance.combatMainPage.teamSwitchButton
.UpdateTeamPileText(CombatMainManager.Instance.characterController.playerTeam);
}
return cardInstance;
//下面的部分后续放入CardLogic的初始化函数中
card.RefreshCardAttributes();
if (card.HasKeyword("Instant")) //如果是“瞬发”牌,添加抽牌后立刻打出的事件
{
card.eventSubmodule.onDraw.InsertByPriority("Instant", new PrioritizedAction(() =>
{
card.DetectTargetsValidity(out List<CharacterBase> valid, out _, out _);
card.Play(card.SetRandomTargets(valid), card.user);
}, 99));
}
return card;
}
public HandCardView GenerateHandCardView(string pileName, int index = -1)
@@ -112,7 +156,7 @@ namespace Continentis.MainGame.Card
pile.AddCard(handCardView);
}
handCardView.cardInstance = this;
handCardView.card = this;
this.handCardView = handCardView;
handCardView.transform.localScale = pile is HandPile ? Vector3.one : Vector3.zero;
@@ -140,7 +184,7 @@ namespace Continentis.MainGame.Card
HUD_Intention intention = user.characterView.hudContainer.enablingHUDs["Intention"] as HUD_Intention;
IntentionCardView intentionCardView = LeanPool.Spawn(intentionCardObjectPrefab, intention.hudTransform).GetComponent<IntentionCardView>();
intention.AddCard(intentionCardView);
intentionCardView.cardInstance = this;
intentionCardView.card = this;
this.intentionCardView = intentionCardView;
intentionCardView.transform.localScale = Vector3.one;
intentionCardView.Setup(this);
@@ -157,6 +201,12 @@ namespace Continentis.MainGame.Card
}
}
}
public partial class CardInstance
{
public HandCardView handCardView;
public IntentionCardView intentionCardView;
}
public class CardLocation
{

View File

@@ -13,27 +13,9 @@ namespace Continentis.MainGame.Card
public abstract partial class CardLogicBase
{
[Header("Reference")]
public CardData cardData;
public CardInstance cardInstance;
public CompositeDisposable disposables = new CompositeDisposable();
public ICardOwner owner => cardInstance.owner;
public CharacterBase user => cardInstance.user;
public CombatTeam UsingTeam => cardInstance.usingTeam;
public HandCardView handCardView => cardInstance.handCardView;
public IntentionCardView intentionCardView => cardInstance.intentionCardView;
[Header("Card Base Info")]
public Guid cardID;
public int upgradeLevel;
[Header("Submodules")]
public AttributeSubmodule attributeSubmodule { get; private set; }
public WeightSubmodule weightSubmodule { get; private set; }
public CombatBuffSubmodule combatBuffSubmodule { get; private set; }
public EventSubmodule eventSubmodule { get; private set; }
public ContentSubmodule contentSubmodule { get; private set; }
public PlaySubmodule playSubmodule { get; private set; }
public CardInstance card;
public CardData cardData => card.cardData;
public CharacterBase user => card.user;
public HashSet<CardLogicComponentBase> logicComponents { get; private set; }
/// <summary>
@@ -52,8 +34,6 @@ namespace Continentis.MainGame.Card
if (Activator.CreateInstance(logicType) is CardLogicBase cardLogic)
{
cardLogic.cardData = data;
cardLogic.Setup();
return cardLogic;
}
@@ -61,45 +41,24 @@ namespace Continentis.MainGame.Card
return null;
}
public void Setup()
public virtual void Initialize(CardInstance cardInstance)
{
this.cardID = Guid.NewGuid();
this.attributeSubmodule = new AttributeSubmodule(this);
this.weightSubmodule = new WeightSubmodule(this);
this.eventSubmodule = new EventSubmodule(this);
this.combatBuffSubmodule = new CombatBuffSubmodule(this);
this.contentSubmodule = new ContentSubmodule(this);
this.playSubmodule = new PlaySubmodule(this);
this.logicComponents = new HashSet<CardLogicComponentBase>();
SetUpLogicComponents();
card = cardInstance;
logicComponents = new HashSet<CardLogicComponentBase>();
card.eventSubmodule.onTargeting += TargetingEffect;
card.eventSubmodule.onUntargeting += UntargetingEffect;
}
protected virtual void SetUpLogicComponents()
public virtual void SetUpLogicComponents()
{
}
public virtual void Initialize()
{
RefreshCardAttributes();
if (HasKeyword("Instant")) //如果是“瞬发”牌,添加抽牌后立刻打出的事件
{
eventSubmodule.onDraw.InsertByPriority("Instant", new PrioritizedAction(() =>
{
DetectTargetsValidity(out List<CharacterBase> valid, out _, out _);
Play(SetRandomTargets(valid), user);
}, 99));
}
}
public T AddLogicComponent<T>() where T : CardLogicComponentBase, new()
{
if (logicComponents.Any(component => component is T))
{
Debug.LogWarning($"Card {cardData.className} already has component of type {typeof(T)}, cannot add duplicate.");
Debug.LogWarning($"Card {card.cardData.className} already has component of type {typeof(T)}, cannot add duplicate.");
return null;
}
else
@@ -116,30 +75,319 @@ namespace Continentis.MainGame.Card
return logicComponents.OfType<T>().FirstOrDefault();
}
public void UpgradeCard()
public virtual void ApplyAttributeChangesByCard()
{
if (owner is not CombatTeam)
{
KeyValuePair<string, List<CardInstance>> currentPile = cardInstance.deck.GetCardLocation(cardInstance, out int index);
if (!cardData.upgradeNode.isTerminalNode)
{
cardInstance.DestroyHandCardView();
CardData newData = cardData.upgradeNode.upgradeCards[0]; //后续可改为选择升级方向
CardLogicBase newLogic = CardLogicBase.GenerateCardLogic(newData);
cardInstance.cardLogic = newLogic;
newLogic.cardInstance = cardInstance;
cardInstance.cardLogic.Initialize();
if (user is PlayerHero)
cardInstance.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.Pile(currentPile.Key), index);
}
}
else
{
}
}
public virtual List<CommandBase> PlayEffect(List<CharacterBase> targetList)
{
return null;
}
public virtual void AfterPlayEffect(List<CharacterBase> targetList)
{
}
}
#region Attributes
public partial class CardLogicBase
{
/// <summary>
/// 设置可变属性值
/// </summary>
/// <param name="attributeName">属性名,通常为</param>
/// <param name="additive">是否为叠加true为叠加false为覆盖true时originalValue为外部传入值</param>
/// <param name="originalValue">原始伤害值仅在additive为true时有效否则此值被覆盖为BaseAttribute</param>
/// <param name="baseOffset">伤害增量</param>
public void SetVariableAttribute(string attributeName, int baseOffset, bool additive = false, int originalValue = 0)
{
card.SetVariableAttribute(attributeName, baseOffset, additive, originalValue);
}
/// <summary>
/// 检查卡牌是否具有某属性
/// </summary>
public bool HasAttribute(string attributeName)
{
return card.HasAttribute(attributeName);
}
/// <summary>
/// 获取卡牌的属性值
/// </summary>
public int GetAttribute(string attributeName, int defaultValue = 0)
{
return card.GetAttribute(attributeName, defaultValue);
}
public float GetRawAttribute(string attributeName, float defaultValue = 0)
{
return card.GetRawAttribute(attributeName, defaultValue);
}
/// <summary>
/// 设置卡牌的属性值
/// </summary>
public void SetAttribute(string attributeName, int value)
{
card.SetAttribute(attributeName, value);
}
/// <summary>
/// 设置卡牌的属性值
/// </summary>
public void SetAttribute(string attributeName, float value)
{
card.SetAttribute(attributeName, value);
}
/// <summary>
/// 修改卡牌的属性值
/// </summary>
public void ModifyAttribute(string attributeName, int delta)
{
card.ModifyAttribute(attributeName, delta);
}
}
#endregion
#region Command
public partial class CardLogicBase
{
/// <summary>
/// 创建一个命令组,组内命令按顺序执行
/// </summary>
/// <param name="commands">命令模板</param>
protected CommandGroup SingleCommandGroup(params CommandBase[] commands)
{
return SingleCommandGroup(ExecutionMode.Parallel, commands);
}
/// <summary>
/// 创建一个命令组,组内命令按指定顺序执行
/// </summary>
/// <param name="executionMode">执行模式,顺序或并行</param>
/// <param name="commands">命令模板</param>
protected virtual CommandGroup SingleCommandGroup(
ExecutionMode executionMode = ExecutionMode.Parallel, params CommandBase[] commands)
{
CommandGroup singleGroup = new CommandGroup(executionMode);
foreach (CommandBase template in commands)
{
singleGroup.AddCommand(template.Clone());
}
return singleGroup;
}
/// <summary>
/// 对目标列表中的每个目标依次执行一组有参函数命令每组命令的参数为targetList中的个体主体Group顺序执行单体Group并行执行。
/// </summary>
/// <param name="targetList">目标列表</param>
/// <param name="singleCommands">单体命令模板</param>
protected CommandGroup TargetListCommandGroup(List<CharacterBase> targetList,
params CommandBase[] singleCommands)
{
return TargetListCommandGroup(targetList, ExecutionMode.Sequential, ExecutionMode.Parallel,
singleCommands);
}
/// <summary>
/// 对目标列表中的每个目标依次执行一组有参函数命令每组命令的参数为targetList中的个体。
/// </summary>
/// <param name="targetList">目标列表</param>
/// <param name="mainExecutionMode">主体Group各个目标的执行顺序</param>
/// <param name="singleExecutionMode">单体Group一个目标中指令的执行顺序</param>
/// <param name="singleCommands">单体命令模板</param>
protected virtual CommandGroup TargetListCommandGroup(
List<CharacterBase> targetList, ExecutionMode mainExecutionMode = ExecutionMode.Sequential,
ExecutionMode singleExecutionMode = ExecutionMode.Parallel,
params CommandBase[] singleCommands)
{
CommandGroup mainGroup = new CommandGroup(mainExecutionMode);
foreach (CharacterBase target in targetList)
{
CommandGroup singleGroup = new CommandGroup(singleExecutionMode);
foreach (CommandBase template in singleCommands)
{
CommandBase clone = template.Clone();
List<CommandBase> allCommands = new List<CommandBase>();
if (clone is CommandGroup group)
{
allCommands.AddRange(group.GetAllCommands(true));
}
else
{
allCommands.Add(clone);
}
foreach (CommandBase cmd in allCommands)
{
cmd.selfContext.context["Target"] = target;
}
singleGroup.AddCommand(clone);
}
mainGroup.AddCommand(singleGroup);
}
return mainGroup;
}
}
#endregion
#region Attack
public partial class CardLogicBase
{
/// <summary>
/// 获取最终伤害
/// </summary>
/// <param name="target">目标</param>
/// <param name="elementalTags">元素标签若为null则使用卡牌的元素标签</param>
public virtual int GetTargetedFinalDamage(CharacterBase target, List<string> elementalTags = null)
{
return GetFinalDamage(target, elementalTags, out _, out _, out _, out _);
}
/// <summary>
/// 获取最终伤害
/// </summary>
/// <param name="elementalTags">元素标签若为null则使用卡牌的元素标签</param>
public virtual int GetNoTargetFinalDamage(List<string> elementalTags = null)
{
return GetFinalDamage(null, elementalTags, out _, out _, out _, out _);
}
protected virtual int GetFinalDamage(CharacterBase target, List<string> elementalTags,
out float baseDamageAfterOffset, out float elementalMultiplier,
out float magicMultiplier, out float finalMultiplier)
{
bool haveTarget = target != null;
elementalTags ??= card.GetElementalKeywords();
//----计算基础伤害增量----
int physicsOffset = 0;
if (card.HasKeyword("Physics") || card.HasKeyword("Slash") || card.HasKeyword("Prick") || card.HasKeyword("Strike"))
{
physicsOffset = user.GetAttribute("PhysicsDamageDealtOffset"); //物理伤害基础增量
}
int magicOffset = 0;
if (card.HasKeyword("Magic") || card.HasKeyword("Arcane") || card.HasKeyword("Sorcery"))
{
magicOffset = user.GetAttribute("MagicDamageDealtOffset"); //魔法伤害基础增量
}
//----计算伤害因数----
//计算元素伤害加成注意“物理Physics”也是一种元素因此下方没有“通用物理伤害加成”的计算
elementalMultiplier = 1;
foreach (string element in elementalTags)
{
float targetGain = haveTarget ? target.GetRawAttribute(element + "DamageGainMultiplier", 1) : 1;
elementalMultiplier *= user.GetRawAttribute(element + "DamageDealtMultiplier", 1) * targetGain;
}
//计算通用的魔法伤害加成
magicMultiplier = 1;
if (card.HasKeyword("Magic") || card.HasKeyword("Arcane") || card.HasKeyword("Sorcery"))
{
float targetGain = haveTarget ? target.GetRawAttribute("MagicDamageGainMultiplier", 1) : 1;
magicMultiplier = user.GetRawAttribute("MagicDamageDealtMultiplier", 1) * targetGain;
}
//计算最终伤害加成
float targetFinalGain = haveTarget ? target.GetRawAttribute("FinalDamageGainMultiplier", 1) : 1;
finalMultiplier = user.GetRawAttribute("FinalDamageDealtMultiplier", 1) * targetFinalGain;
//----计算最终伤害----
baseDamageAfterOffset = card.attributeSubmodule.GetCurrentAttribute("Damage") + physicsOffset + magicOffset;
float finalDamage = baseDamageAfterOffset * elementalMultiplier * magicMultiplier * finalMultiplier;
return Mathf.RoundToInt(finalDamage);
}
}
#endregion
#region Buffs
public partial class CardLogicBase
{
/// <summary>
/// 创建一个角色战斗Buff实例
/// 注意此函数依赖ModManager的类型注册功能请确保在Mod加载时已注册对应Buff类型
/// 此函数中的T并不是原型参数而是获取Mod中注册的类型用的
/// </summary>
public T CreateCharacterBuff<T>(params object[] parameters) where T :CharacterCombatBuffBase
{
string buffTypeID = ModManager.GetTypeID(typeof(T));
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
public T CreateCharacterBuff<T>(string buffTypeID, params object[] parameters) where T :CharacterCombatBuffBase
{
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
/// <summary>
/// 创建一个卡牌战斗Buff实例
/// 注意此函数依赖ModManager的类型注册功能请确保在Mod加载时已注册对应Buff类型
/// 此函数中的T并不是原型参数而是获取Mod中注册的类型用的
/// </summary>
public T CreateCardBuff<T>(params object[] parameters) where T :CardBuffBase
{
string buffTypeID = ModManager.GetTypeID(typeof(T));
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
public T CreateCardBuff<T>(string buffTypeID, params object[] parameters) where T :CardBuffBase
{
if (string.IsNullOrEmpty(buffTypeID))
{
Debug.LogError($"Failed to get buff name for type {typeof(T).FullName}");
return null;
}
return ModManager.CreateInstance<T>(buffTypeID, parameters);
}
}
#endregion
public abstract partial class CardLogicBase
{
/// <summary>
/// 获取衍生卡牌数据
/// </summary>
@@ -161,6 +409,24 @@ namespace Continentis.MainGame.Card
Debug.LogError($"Card {cardData.className} does not contain derivative card data '{dataName}'.");
return null;
}
/// <summary>
/// 选中目标时触发的效果效果在所有逻辑组件的Targeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void TargetingEffect(CharacterBase target)
{
}
/// <summary>
/// 取消选中目标时触发的效果效果在所有逻辑组件的Untargeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void UntargetingEffect()
{
}
}
/// <summary>
@@ -171,15 +437,16 @@ namespace Continentis.MainGame.Card
/// </summary>
public abstract class CardLogicComponentBase
{
protected CardLogicBase card;
protected CardLogicBase mainLogic;
protected CardInstance card => mainLogic.card;
protected CharacterBase user => card.user;
protected CombatTeam team => card.UsingTeam;
protected CombatTeam usingTeam => card.usingTeam;
public virtual void Initialize(CardLogicBase card)
{
this.card = card;
card.eventSubmodule.onTargeting += TargetingEffect;
card.eventSubmodule.onUntargeting += UntargetingEffect;
this.mainLogic = card;
this.card.eventSubmodule.onTargeting += TargetingEffect;
this.card.eventSubmodule.onUntargeting += UntargetingEffect;
}
protected virtual void TargetingEffect(CharacterBase target)

View File

@@ -12,28 +12,28 @@ using Random = UnityEngine.Random;
namespace Continentis.MainGame.Card
{
public partial class CardLogicBase
public partial class CardInstance
{
/// <summary>
/// 选中目标时触发的效果效果在所有逻辑组件的Targeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void TargetingEffect(CharacterBase target)
public virtual void Targeting(CharacterBase target)
{
eventSubmodule.onTargeting.Invoke(target);
}
/// <summary>
/// 取消选中目标时触发的效果效果在所有逻辑组件的Untargeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void UntargetingEffect()
public virtual void Untargeting()
{
eventSubmodule.onUntargeting.Invoke();
}
}
public partial class CardLogicBase
public partial class CardInstance
{
/// <summary>
/// 刷新卡牌属性
@@ -54,13 +54,13 @@ namespace Continentis.MainGame.Card
/// <summary>
/// 根据卡牌内容应用属性变化
/// </summary>
public virtual void ApplyAttributeChangesByCard()
public void ApplyAttributeChangesByCard()
{
cardLogic.ApplyAttributeChangesByCard();
}
}
public partial class CardLogicBase
public partial class CardInstance
{
public virtual void DetectTargetsValidity(out List<CharacterBase> valid, out List<CharacterBase> notMet, out List<CharacterBase> invalid)
{
@@ -175,15 +175,15 @@ namespace Continentis.MainGame.Card
handCardView.isDuringPlaying = true;
}
cardInstance.user = user ?? CombatMainManager.Instance.currentCharacter;
cardInstance.user.recordSubmodule.RecordCardPlay(cardInstance);
this.user = user ?? CombatMainManager.Instance.currentCharacter;
this.user.recordSubmodule.RecordCardPlay(this);
if (!willCheckBeforePlay || CheckBeforePlay())
{
cardInstance.user.ModifyStamina(-GetAttribute("StaminaCost"));
cardInstance.user.ModifyMana(-GetAttribute("ManaCost"));
this.user.ModifyStamina(-GetAttribute("StaminaCost"));
this.user.ModifyMana(-GetAttribute("ManaCost"));
if (cardInstance.user is PlayerHero)
if (this.user is PlayerHero)
{
CombatUIManager.Instance.combatMainPage.combatResourcesDisplayer.UpdateIcons();
}
@@ -194,24 +194,26 @@ namespace Continentis.MainGame.Card
{
playSubmodule.isDuringPlayEffect = true;
eventSubmodule.onBeforePlay.Invoke(targetList);
cardInstance.user.eventSubmodule?.onBeforePlayCard.Invoke(cardInstance, targetList);
cardInstance.user.combatBuffSubmodule.buffList.For(buff =>
this.user.eventSubmodule?.onBeforePlayCard.Invoke(this, targetList);
this.user.combatBuffSubmodule.buffList.For(buff =>
{
buff.eventSubmodule?.onBeforePlayCard.Invoke(cardInstance, targetList);
buff.eventSubmodule?.onBeforePlayCard.Invoke(this, targetList);
});
}));
CommandQueueManager.Instance.AddCommands(PlayEffect(targetList));
CommandQueueManager.Instance.AddCommands(cardLogic.PlayEffect(targetList));
CommandQueueManager.Instance.AddCommand(new Cmd_Function(() =>
{
eventSubmodule.onAfterPlay.Invoke(targetList);
combatBuffSubmodule.buffList.For(buff => buff.usageSubmodule?.UpdateModule());
cardInstance.user.eventSubmodule.onAfterPlayCard.Invoke(cardInstance, targetList);
cardInstance.user.combatBuffSubmodule.buffList.For(buff =>
this.user.eventSubmodule.onAfterPlayCard.Invoke(this, targetList);
this.user.combatBuffSubmodule.buffList.For(buff =>
{
buff.eventSubmodule?.onAfterPlayCard.Invoke(cardInstance, targetList);
buff.eventSubmodule?.onAfterPlayCard.Invoke(this, targetList);
});
AfterPlayEffect(targetList);
cardLogic.AfterPlayEffect(targetList);
playSubmodule.isDuringPlayEffect = false;
if (handCardView != null)
{
@@ -233,37 +235,37 @@ namespace Continentis.MainGame.Card
protected virtual List<CommandBase> PlayEffect(List<CharacterBase> targetList)
{
return null;
return new List<CommandBase>();
}
protected virtual void AfterPlayEffect(List<CharacterBase> targetList)
{
if (contentSubmodule.cardType == CardType.Power)
{
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.UsePowerCard(cardInstance));
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.UsePowerCard(this));
return;
}
if (HasKeyword("Exhaust"))
{
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(cardInstance));
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(this));
return;
}
if(HasKeyword("Exhaustible"))
{
if (!cardInstance.cardLogic.HasAttribute("ExhaustibleCount"))
if (!HasAttribute("ExhaustibleCount"))
{
Debug.LogError("Exhaustible card missing ExhaustibleCount attribute: " + contentSubmodule.cardName);
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(cardInstance));
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(this));
return;
}
cardInstance.cardLogic.ModifyAttribute("ExhaustibleCount", -1);
ModifyAttribute("ExhaustibleCount", -1);
if(cardInstance.cardLogic.GetAttribute("ExhaustibleCount") <= 0)
if(GetAttribute("ExhaustibleCount") <= 0)
{
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(cardInstance));
CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(this));
return;
}
}
@@ -272,7 +274,7 @@ namespace Continentis.MainGame.Card
{
if(!HasKeyword("Reuseable"))
{
CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.DiscardCard(cardInstance, false));
CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.DiscardCard(this, false));
CommandQueueManager.Instance.AddCommand(new Cmd_Function(() =>
{
if (handCardView != null)
@@ -289,8 +291,30 @@ namespace Continentis.MainGame.Card
}
}
public partial class CardLogicBase
public partial class CardInstance
{
public void UpgradeCard()
{
if (owner is not CombatTeam)
{
KeyValuePair<string, List<CardInstance>> currentPile = deck.GetCardLocation(this, out int index);
if (!cardData.upgradeNode.isTerminalNode)
{
DestroyHandCardView();
CardData newData = cardData.upgradeNode.upgradeCards[0]; //后续可改为选择升级方向
CardLogicBase newLogic = CardLogicBase.GenerateCardLogic(newData);
this.cardLogic = newLogic;
newLogic.card = this;
this.cardLogic.Initialize(this);
if (user is PlayerHero)
GenerateHandCardView(CombatUIManager.Instance.combatMainPage.Pile(currentPile.Key), index);
}
}
else
{
}
}
}
}

View File

@@ -6,11 +6,11 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
public partial class AttributeSubmodule : SubmoduleBase<CardLogicBase>
public partial class AttributeSubmodule : SubmoduleBase<CardInstance>
{
public AttributeGroup attributeGroup;
public AttributeSubmodule(CardLogicBase card) : base(card)
public AttributeSubmodule(CardInstance card) : base(card)
{
Initialize(card.cardData);
}

View File

@@ -5,11 +5,11 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
public partial class CombatBuffSubmodule : SubmoduleBase<CardLogicBase>
public partial class CombatBuffSubmodule : SubmoduleBase<CardInstance>
{
public List<CardCombatBuffBase> buffList;
public CombatBuffSubmodule(CardLogicBase owner) : base(owner)
public CombatBuffSubmodule(CardInstance owner) : base(owner)
{
buffList = new List<CardCombatBuffBase>();
}

View File

@@ -6,7 +6,7 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
public class ContentSubmodule : SubmoduleBase<CardLogicBase>
public class ContentSubmodule : SubmoduleBase<CardInstance>
{
public List<string> keywords;
@@ -22,7 +22,7 @@ namespace Continentis.MainGame.Card
/// </summary>
public bool dirtyMark;
public ContentSubmodule(CardLogicBase card) : base(card)
public ContentSubmodule(CardInstance card) : base(card)
{
keywords = card.cardData.keywords;
cardName = card.cardData.displayName.Localize();

View File

@@ -7,7 +7,7 @@ using UnityEngine.Events;
namespace Continentis.MainGame.Card
{
public partial class EventSubmodule : SubmoduleBase<CardLogicBase>
public partial class EventSubmodule : SubmoduleBase<CardInstance>
{
public UnityAction<CharacterBase> onTargeting; //选中目标时
public UnityAction onUntargeting; //取消选中目标时
@@ -27,11 +27,8 @@ namespace Continentis.MainGame.Card
public OrderedDictionary<string, PrioritizedCheckAndEffect> onInitiativeDiscard; //此卡牌被主动弃牌时如果读到任意一个true打断弃牌行为执行所有对应效果
public OrderedDictionary<string, PrioritizedAction> onExhaust; //此卡牌被消耗时
public EventSubmodule(CardLogicBase card) : base(card)
public EventSubmodule(CardInstance card) : base(card)
{
onTargeting += card.TargetingEffect;
onUntargeting = card.UntargetingEffect;
onCombatStart = new OrderedDictionary<string, PrioritizedAction>();
onCombatEnd = new OrderedDictionary<string, PrioritizedAction>();

View File

@@ -2,11 +2,11 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
public partial class PlaySubmodule : SubmoduleBase<CardLogicBase>
public partial class PlaySubmodule : SubmoduleBase<CardInstance>
{
public bool isDuringPlayEffect;
public PlaySubmodule(CardLogicBase card) : base(card)
public PlaySubmodule(CardInstance card) : base(card)
{
isDuringPlayEffect = false;
}

View File

@@ -3,14 +3,14 @@ using UnityEngine;
namespace Continentis.MainGame.Card
{
public class WeightSubmodule : SubmoduleBase<CardLogicBase>
public class WeightSubmodule : SubmoduleBase<CardInstance>
{
public bool forceUse;
public bool forceIgnore;
public float baseWeight;
public float currentWeight;
public WeightSubmodule(CardLogicBase owner) : base(owner)
public WeightSubmodule(CardInstance owner) : base(owner)
{
this.forceUse = false;
this.forceIgnore = false;

View File

@@ -10,8 +10,7 @@ namespace Continentis.MainGame.Card
{
public abstract partial class CardViewBase : UIElementBase, IPointerEnterHandler, IPointerExitHandler
{
public CardInstance cardInstance;
public CardLogicBase cardLogic => cardInstance.cardLogic;
public CardInstance card;
public Canvas canvas;
public RectTransform cardTransform;
@@ -58,7 +57,7 @@ namespace Continentis.MainGame.Card
isHovering = true;
List<string> allKeywords = new List<string>();
allKeywords.AddRange(cardLogic.contentSubmodule.keywords);
allKeywords.AddRange(card.contentSubmodule.keywords);
keywordList.Enable(allKeywords);
}
@@ -75,20 +74,25 @@ namespace Continentis.MainGame.Card
{
if (card != null)
{
cardInstance = card;
this.card = card;
isOccupied = false;
isHovering = false;
isSelecting = false;
isDuringPlaying = false;
}
cardNameText.text = cardLogic.contentSubmodule.cardName;
cardDescriptionText.text = cardLogic.contentSubmodule.interpretedFunctionText;
cardImage.sprite = cardLogic.contentSubmodule.cardSprite;
if (cardLogic.contentSubmodule.cardRarity != Rarity.None)
else if (this.card == null)
{
cardRarityMark.color = MainGameManager.Instance.basePrefabs.GetRarityColor(cardLogic.contentSubmodule.cardRarity);
Debug.LogError("CardViewBase Setup called with null card!");
return;
}
cardNameText.text = this.card.contentSubmodule.cardName;
cardDescriptionText.text = this.card.contentSubmodule.interpretedFunctionText;
cardImage.sprite = this.card.contentSubmodule.cardSprite;
if (this.card.contentSubmodule.cardRarity != Rarity.None)
{
cardRarityMark.color = MainGameManager.Instance.basePrefabs.GetRarityColor(this.card.contentSubmodule.cardRarity);
}
else
{
@@ -98,21 +102,21 @@ namespace Continentis.MainGame.Card
if (string.IsNullOrEmpty(collectionName)) collectionName = "Basic";
CardViewCollection collection = MainGameManager.Instance.basePrefabs.cardViewCollections[collectionName];
List<string> layoutTags = cardLogic.cardData.cardLayoutTags; //TODO后续可扩展为动态布局标签
List<string> layoutTags = this.card.cardData.cardLayoutTags; //TODO后续可扩展为动态布局标签
string firstLayoutTag = layoutTags.Count > 0 ? layoutTags[0] : "Default";
if (!collection.cardViews.ContainsKey(firstLayoutTag)) firstLayoutTag = "Default";
cardBackground.sprite = collection.cardViews[firstLayoutTag].background;
cardTypeText.text = cardLogic.contentSubmodule.cardType.ToString();
cardTypeText.text = this.card.contentSubmodule.cardType.ToString();
staminaCostText.rectTransform.parent.gameObject.SetActive(true);
staminaCostText.text = cardLogic.attributeSubmodule.GetRoundCurrentAttribute("StaminaCost").ToString();
staminaCostText.text = this.card.attributeSubmodule.GetRoundCurrentAttribute("StaminaCost").ToString();
int manaCost = cardLogic.attributeSubmodule.GetRoundCurrentAttribute("ManaCost");
int manaCost = this.card.attributeSubmodule.GetRoundCurrentAttribute("ManaCost");
manaCostText.rectTransform.parent.gameObject.SetActive(manaCost > 0);
manaCostText.text = manaCost.ToString();
if (cardLogic.HasKeyword("Unplayable")) // 如果卡牌不能被打出,则隐藏费用文本
if (this.card.HasKeyword("Unplayable")) // 如果卡牌不能被打出,则隐藏费用文本
{
staminaCostText.rectTransform.parent.gameObject.SetActive(false);
manaCostText.rectTransform.parent.gameObject.SetActive(false);

View File

@@ -20,7 +20,7 @@ namespace Continentis.MainGame.Card
public override void OnPointerEnter(PointerEventData eventData)
{
base.OnPointerEnter(eventData);
cardLogic.contentSubmodule.dirtyMark = true;
card.contentSubmodule.dirtyMark = true;
if (CombatUIManager.Instance.selectingCardView == null)
{
canvas.overrideSorting = true;
@@ -46,7 +46,7 @@ namespace Continentis.MainGame.Card
{
if(isOccupied) return;
if (CombatUIManager.Instance.combatMainPage.handCardSelector.selectedCards.Contains(cardInstance))
if (CombatUIManager.Instance.combatMainPage.handCardSelector.selectedCards.Contains(card))
{
CombatUIManager.Instance.combatMainPage.handCardSelector.Deselect(this);
}
@@ -59,7 +59,7 @@ namespace Continentis.MainGame.Card
{
if(isOccupied) return;
if (CombatUIManager.Instance.combatMainPage.customCardSelector.selectedCards.Contains(cardInstance))
if (CombatUIManager.Instance.combatMainPage.customCardSelector.selectedCards.Contains(card))
{
CombatUIManager.Instance.combatMainPage.customCardSelector.Deselect(this);
}
@@ -75,14 +75,14 @@ namespace Continentis.MainGame.Card
isSelecting = true;
CombatUIManager.Instance.selectingCardView = this;
cardInstance.user = CombatMainManager.Instance.currentCharacter;
cardLogic.DetectTargetsValidity(out validTargets, out conditionNotMetTargets, out invalidTargets);
card.user = CombatMainManager.Instance.currentCharacter;
card.DetectTargetsValidity(out validTargets, out conditionNotMetTargets, out invalidTargets);
if (cardLogic.attributeSubmodule.targetCount == 1)
if (card.attributeSubmodule.targetCount == 1)
{
CombatUIManager.Instance.arrowsPage.GeneratePointerArrow(cardTransform.position, cardTransform.position, true);
}
else if (cardLogic.attributeSubmodule.targetCount == -1)
else if (card.attributeSubmodule.targetCount == -1)
{
CombatUIManager.Instance.arrowsPage.GeneratePointerArrow(cardTransform.position, cardTransform.position, true);
@@ -105,16 +105,16 @@ namespace Continentis.MainGame.Card
// 如果悬停视图不是空的,说明鼠标移动到了一个新的目标上
if (CombatUIManager.Instance.hoveringCharacterView != null)
{
cardLogic.eventSubmodule.onTargeting(CombatUIManager.Instance.hoveringCharacterView.character);
card.Targeting(CombatUIManager.Instance.hoveringCharacterView.character);
currentTargetingCharacterView = CombatUIManager.Instance.hoveringCharacterView;
}
else // 悬停视图是空的,说明鼠标离开了之前的目标
{
cardLogic.eventSubmodule.onUntargeting();
card.Untargeting();
currentTargetingCharacterView = null;
}
cardLogic.contentSubmodule.dirtyMark = true;
card.contentSubmodule.dirtyMark = true;
}
Vector3 startPosition = cardTransform.position + new Vector3(0, cardTransform.rect.height * cardTransform.lossyScale.y / 2, 0);
@@ -124,7 +124,7 @@ namespace Continentis.MainGame.Card
CombatCharacterViewBase hoveringCharacterView = CombatUIManager.Instance.hoveringCharacterView;
CharacterBase hoveringCharacter = hoveringCharacterView != null ? hoveringCharacterView.character : null;
if (cardLogic.attributeSubmodule.targetCount == 1)
if (card.attributeSubmodule.targetCount == 1)
{
mainPointerArrow.SetArrow(startPosition, endPosition);
@@ -148,7 +148,7 @@ namespace Continentis.MainGame.Card
mainPointerArrow.SetColor(Color.white);
}
}
else if (cardLogic.attributeSubmodule.targetCount == -1)
else if (card.attributeSubmodule.targetCount == -1)
{
mainPointerArrow.SetArrow(startPosition, endPosition);
@@ -213,7 +213,7 @@ namespace Continentis.MainGame.Card
CombatUIManager.Instance.arrowsPage.otherPointerArrows.ForEach(arrow => { arrow.gameObject.SetActive(false); });
}
}
else if (cardLogic.attributeSubmodule.targetCount == 0)
else if (card.attributeSubmodule.targetCount == 0)
{
Vector3 cardPosition = SpaceConverter.ScreenPointToUIPoint(arrowCanvasRect, eventData.position, uiCamera);
cardTransform.position = cardPosition;
@@ -234,21 +234,21 @@ namespace Continentis.MainGame.Card
CombatUIManager.Instance.selectingCardView = null;
canvas.overrideSorting = false;
canvas.sortingOrder = 0;
cardLogic.eventSubmodule.onUntargeting();
cardLogic.contentSubmodule.dirtyMark = true;
card.eventSubmodule.onUntargeting();
card.contentSubmodule.dirtyMark = true;
}
else
{
return;
}
if (cardLogic.HasKeyword("Unplayable")) // 如果有“不能打出”关键词,直接返回
if (card.HasKeyword("Unplayable")) // 如果有“不能打出”关键词,直接返回
{
return;
}
if (!cardLogic.HasKeyword("TargetSelf"))
if (!card.HasKeyword("TargetSelf"))
{
if (!validTargets.Contains(hoveringCharacter))
{
@@ -258,14 +258,14 @@ namespace Continentis.MainGame.Card
}
// 根据目标类型,打出卡牌
if (cardLogic.attributeSubmodule.targetCount == 1)
if (card.attributeSubmodule.targetCount == 1)
{
if (hoveringCharacter != null && validTargets.Contains(hoveringCharacter))
{
if (!cardLogic.Play(new List<CharacterBase>() { hoveringCharacter }))
if (!card.Play(new List<CharacterBase>() { hoveringCharacter }))
{
cardLogic.eventSubmodule.onUntargeting();
cardLogic.contentSubmodule.dirtyMark = true;
card.eventSubmodule.onUntargeting();
card.contentSubmodule.dirtyMark = true;
}
}
}
@@ -275,18 +275,18 @@ namespace Continentis.MainGame.Card
bool isInDropZone = RectTransformUtility.RectangleContainsScreenPoint(dropZone, eventData.position, uiCamera);
List<CharacterBase> targetList = new List<CharacterBase>();
if (cardLogic.attributeSubmodule.targetCount == -1)
if (card.attributeSubmodule.targetCount == -1)
{
targetList.AddRange(validTargets);
}
else if (cardLogic.HasKeyword("TargetSelf") && cardLogic.attributeSubmodule.targetCount == 0)
else if (card.HasKeyword("TargetSelf") && card.attributeSubmodule.targetCount == 0)
{
targetList.Add(cardLogic.user);
targetList.Add(card.user);
}
if (!isInDropZone)
{
cardLogic.Play(targetList);
card.Play(targetList);
}
}
}

View File

@@ -8,12 +8,12 @@ namespace Continentis.MainGame.Card
{
protected override void TargetingEffect(CharacterBase target)
{
card.SetAttribute("DisplayDamage", card.GetFinalDamage(target));
card.SetAttribute("DisplayDamage", mainLogic.GetTargetedFinalDamage(target));
}
protected override void UntargetingEffect()
{
card.SetAttribute("DisplayDamage", card.GetUserDamage());
card.SetAttribute("DisplayDamage", mainLogic.GetNoTargetFinalDamage());
}
/// <summary>

View File

@@ -26,7 +26,7 @@ namespace Continentis.MainGame.Card
commandGroup.AddCommand(new Cmd_Function(() =>
{
customCardSelector.Setup(title, card.cardInstance, cardsToSelect, maxSelection, forceMax);
customCardSelector.Setup(title, mainLogic.card, cardsToSelect, maxSelection, forceMax);
}));
commandGroup.AddCommand(new Cmd_WaitForUI(customCardSelector));
commandGroup.AddCommand(new Cmd_Function(() =>

View File

@@ -42,7 +42,7 @@ namespace Continentis.MainGame.Card
commandGroup.AddCommand(new Cmd_Function(() =>
{
handCardSelector.Setup(title, card.cardInstance, maxSelection, selectCondition, forceMax);
handCardSelector.Setup(title, mainLogic.card, maxSelection, selectCondition, forceMax);
}));
commandGroup.AddCommand(new Cmd_WaitForUI(handCardSelector));
commandGroup.AddCommand(new Cmd_Function(() =>

View File

@@ -60,12 +60,12 @@ namespace Continentis.MainGame.Character
[ShowNativeProperty]
public RecordSubmodule recordSubmodule { get; private set; }
public virtual void Initialize(Fraction fraction, CharacterData data)
public CharacterBase(CharacterData data, Fraction fraction)
{
(this as IGameElement).Initialize();
this.fraction = fraction;
this.data = data;
this.fraction = fraction;
switch (fraction)
{
@@ -91,7 +91,6 @@ namespace Continentis.MainGame.Character
this.logicBase = GenerateCharacterLogic(data);
this.logicBase.Initialize(this);
}
/// <summary>

View File

@@ -91,21 +91,21 @@ namespace Continentis.MainGame.Character
attachedCharacter.combatBuffSubmodule.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffApplied.Invoke(this));
RefreshAttributes();
iconSubmodule?.Update();
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.cardLogic.RefreshCardAttributes());
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.RefreshCardAttributes());
}
public override void Remove()
{
OnBuffRemove();
this.attachedCharacter.combatBuffSubmodule.buffList.Remove(this);
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.cardLogic.RefreshCardAttributes());
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.RefreshCardAttributes());
attachedCharacter.combatBuffSubmodule.buffList.Exclude(this).For(buff => buff.eventSubmodule?.onOtherBuffRemoved.Invoke(this));
}
public override void UntriggerRemove()
{
this.attachedCharacter.combatBuffSubmodule.buffList.Remove(this);
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.cardLogic.RefreshCardAttributes());
attachedCharacter.deckSubmodule.GetAllCards().ForEach(card => card.RefreshCardAttributes());
}
/// <summary>

View File

@@ -7,7 +7,7 @@ namespace Continentis.MainGame.Character
{
public partial class CharacterLogicBase
{
protected CharacterBase character;
protected CharacterBase character;
public virtual void Initialize(CharacterBase character)
{
this.character = character;

View File

@@ -300,20 +300,20 @@ namespace Continentis.MainGame.Character
{
bool CanAfford(CardInstance card, int stamina, int mana)
{
return card.cardLogic.GetAttribute("StaminaCost") <= stamina &&
card.cardLogic.GetAttribute("ManaCost") <= mana;
return card.GetAttribute("StaminaCost") <= stamina &&
card.GetAttribute("ManaCost") <= mana;
}
bool CheckAvailabilityAndSetTargets(CardInstance card, out List<CharacterBase> targets)
{
card.cardLogic.DetectTargetsValidity(out List<CharacterBase> valid, out _, out _);
if (valid.Count == 0 || !card.cardLogic.CheckBeforePlay())
card.DetectTargetsValidity(out List<CharacterBase> valid, out _, out _);
if (valid.Count == 0 || !card.CheckBeforePlay())
{
targets = null;
return false; // 无有效目标或无法使用则跳过
}
targets = card.cardLogic.SetRandomTargets(valid);
targets = card.SetRandomTargets(valid);
return true;
}
@@ -331,7 +331,7 @@ namespace Continentis.MainGame.Character
foreach (CardInstance card in availableCards)
{
if (card.cardLogic.weightSubmodule.forceUse)
if (card.weightSubmodule.forceUse)
{
forced.Add(card);
}
@@ -360,8 +360,8 @@ namespace Continentis.MainGame.Character
}
intended.Add(new IntendedCard(card, targets));
remainingStamina -= card.cardLogic.GetAttribute("StaminaCost");
remainingMana -= card.cardLogic.GetAttribute("ManaCost");
remainingStamina -= card.GetAttribute("StaminaCost");
remainingMana -= card.GetAttribute("ManaCost");
}
// 行动力不足则跳过该卡
}
@@ -377,7 +377,7 @@ namespace Continentis.MainGame.Character
break;
}
float totalWeight = affordableCards.Sum(card => card.cardLogic.weightSubmodule.currentWeight);
float totalWeight = affordableCards.Sum(card => card.weightSubmodule.currentWeight);
if (totalWeight <= 0f) break;
float r = Random.value * totalWeight;
@@ -385,7 +385,7 @@ namespace Continentis.MainGame.Character
CardInstance chosen = null;
foreach (CardInstance card in affordableCards)
{
accum += card.cardLogic.weightSubmodule.currentWeight;
accum += card.weightSubmodule.currentWeight;
if (r <= accum)
{
chosen = card;
@@ -403,8 +403,8 @@ namespace Continentis.MainGame.Character
intended.Add(new IntendedCard(chosen, targets));
normal.Remove(chosen);
remainingStamina -= chosen.cardLogic.GetAttribute("StaminaCost");
remainingMana -= chosen.cardLogic.GetAttribute("ManaCost");
remainingStamina -= chosen.GetAttribute("StaminaCost");
remainingMana -= chosen.GetAttribute("ManaCost");
}
}

View File

@@ -32,11 +32,11 @@ namespace Continentis.MainGame.Character
{
public void SetUpHandCardViews()
{
DrawPile.ForEach(c=> c.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.drawPile));
HandPile.ForEach(c=>
DrawPile.ForEach(card=> card.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.drawPile));
HandPile.ForEach(card =>
{
if(!c.cardLogic.playSubmodule.isDuringPlayEffect)
c.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.handPile);
if(!card.playSubmodule.isDuringPlayEffect)
card.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.handPile);
});
DiscardPile.ForEach(c=>c.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.discardPile));
ExhaustPile.ForEach(c=>c.GenerateHandCardView(CombatUIManager.Instance.combatMainPage.exhaustPile));
@@ -83,7 +83,7 @@ namespace Continentis.MainGame.Character
public void PlayCard(CardInstance card, List<CharacterBase> targetList)
{
card.cardLogic.Play(targetList, owner);
card.Play(targetList, owner);
}
public CommandGroup DiscardCard(CardInstance card, bool initiative, float interval = 0.1f)

View File

@@ -36,7 +36,7 @@ namespace Continentis.MainGame.Character
}
ActionRecord currentRecord = actionRecords[actionRecords.Count - 1];
currentRecord.cardsPlayed.Add(card);
Debug.Log($"在回合 {currentRecord.round} 行动 {currentRecord.actionIndex} 中记录了卡牌 {card.cardLogic.contentSubmodule.cardName} 的使用。");
Debug.Log($"在回合 {currentRecord.round} 行动 {currentRecord.actionIndex} 中记录了卡牌 {card.contentSubmodule.cardName} 的使用。");
}
}

View File

@@ -5,17 +5,14 @@ namespace Continentis.MainGame.Character
{
public partial class CombatNPC : CharacterBase
{
public CombatNPC(CharacterData data, Fraction fraction) : base(data, fraction)
{
}
}
public partial class CombatNPC
{
public static CombatNPC GenerateCharacter(CharacterData data, Fraction fraction)
{
CombatNPC combatNpc = new CombatNPC();
combatNpc.Initialize(fraction, data);
return combatNpc;
}
}
}

View File

@@ -8,19 +8,13 @@ namespace Continentis.MainGame.Character
{
public partial class PlayerHero : CharacterBase
{
public PlayerHero(CharacterData data, Fraction fraction) : base(data, fraction)
{
}
}
public partial class PlayerHero
{
public static PlayerHero GenerateCharacter(CharacterData data)
{
PlayerHero playerHero = new PlayerHero();
playerHero.Initialize(Fraction.Player, data);
return playerHero;
}
public override void InitializeCards()
{
base.InitializeCards();
@@ -30,13 +24,13 @@ namespace Continentis.MainGame.Character
drawPile.Shuffle();
// 处理“固有”卡牌
foreach (CardInstance card in drawPile.Where(card => card.cardLogic.HasKeyword("Innate")).ToList())
foreach (CardInstance card in drawPile.Where(card => card.HasKeyword("Innate")).ToList())
{
deckSubmodule.TransferCard("Draw", 0, card);
}
// 处理“迟钝”卡牌
foreach (CardInstance card in drawPile.Where(card => card.cardLogic.HasKeyword("Tardy")).ToList())
foreach (CardInstance card in drawPile.Where(card => card.HasKeyword("Tardy")).ToList())
{
deckSubmodule.TransferCard("Draw", "Discard", card);
}

View File

@@ -44,7 +44,7 @@ namespace Continentis.MainGame.Combat
foreach (var data in playerHeroDataList)
{
PlayerHero hero = PlayerHero.GenerateCharacter(data);
PlayerHero hero = new PlayerHero(data, Fraction.Player);
CombatCharacterViewBase view = hero.GenerateCharacterView(new Vector3(-4.5f, 0, 0));
playerHeroes.Add(hero);
@@ -54,7 +54,7 @@ namespace Continentis.MainGame.Combat
foreach (var data in enemyDataList)
{
CombatNPC enemy = CombatNPC.GenerateCharacter(data, Fraction.Enemy);
CombatNPC enemy = new CombatNPC(data, Fraction.Enemy);
CombatCharacterViewBase view = enemy.GenerateCharacterView(new Vector3(4.5f, 0, 0));
view.mainView.transform.localEulerAngles = new Vector3(0, 180, 0);
@@ -82,7 +82,7 @@ namespace Continentis.MainGame.Combat
return;
}
CombatNPC npc = CombatNPC.GenerateCharacter(data, fraction);
CombatNPC npc = new CombatNPC(data, fraction);
npc.InitializeCards();
Vector3 eulerAngles = fraction == Fraction.Enemy ? new Vector3(0, 180, 0) : Vector3.zero;

View File

@@ -80,7 +80,7 @@ namespace Continentis.MainGame.Combat
foreach (CardInstance card in characterController.characters.SelectMany(character => character.deckSubmodule.GetAllCards()))
{
card.cardLogic.eventSubmodule.onCombatStart.Invoke();
card.eventSubmodule.onCombatStart.Invoke();
}
NextRound();
@@ -104,7 +104,7 @@ namespace Continentis.MainGame.Combat
if (character is CombatNPC npc)
{
npc.IntentionBrain();
npc.deckSubmodule.PoolPile.ForEach(card => card.cardLogic.weightSubmodule.RefreshCurrentWeight());
npc.deckSubmodule.PoolPile.ForEach(card => card.weightSubmodule.RefreshCurrentWeight());
npc.intentionSubmodule.getIntendedCards.Invoke();
foreach (IntendedCard intendedCard in npc.intentionSubmodule.intendedCards)
@@ -112,9 +112,9 @@ namespace Continentis.MainGame.Combat
intendedCard.cardInstance.GenerateIntentionCardView();
if (intendedCard.targets.Count > 0)
{
var cardLogic = intendedCard.cardInstance.cardLogic;
cardLogic.eventSubmodule.onTargeting(intendedCard.targets[0]);
cardLogic.contentSubmodule.dirtyMark = true;
CardInstance card = intendedCard.cardInstance;
card.eventSubmodule.onTargeting(intendedCard.targets[0]);
card.contentSubmodule.dirtyMark = true;
//TODO: 现在仅对第一个目标显示指向,后续可以对多目标进行优化
}
}
@@ -190,7 +190,7 @@ namespace Continentis.MainGame.Combat
foreach (IntendedCard intendedCard in currentCharacter.intentionSubmodule.intendedCards)
{
CommandQueueManager.Instance.AddCommand(new Cmd_Function(0.25f, () => intendedCard.cardInstance.DestroyIntentionCardView()));
intendedCard.cardInstance.cardLogic.Play(intendedCard.targets, currentCharacter, false);
intendedCard.cardInstance.Play(intendedCard.targets, currentCharacter, false);
}
CommandQueueManager.Instance.AddCommand(new Cmd_Function(0f, EndAction));
}
@@ -208,7 +208,7 @@ namespace Continentis.MainGame.Combat
CommandQueueManager.Instance.AddCommand(new Cmd_Function(currentCharacter.eventSubmodule.onActionEnd.Invoke));
foreach (var card in currentCharacter.deckSubmodule.GetAllCards())
{
CommandQueueManager.Instance.AddCommand(new Cmd_Function(card.cardLogic.eventSubmodule.onActionEnd.Invoke));
CommandQueueManager.Instance.AddCommand(new Cmd_Function(card.eventSubmodule.onActionEnd.Invoke));
}
CommandQueueManager.Instance.AddCommand(new Cmd_Function(() =>
@@ -220,8 +220,8 @@ namespace Continentis.MainGame.Combat
Debug.Log(currentCharacter.data.className + " 结束行动,整理手牌。");
List<CardInstance> handPile = new List<CardInstance>(playerHero.deckSubmodule.HandPile);
List<CardInstance> cardToRetain = handPile.Where(card => card.cardLogic.HasKeyword("Retain")).ToList(); //含有“保留”关键词的卡牌
List<CardInstance> cardToExhaust = handPile.Where(card => card.cardLogic.HasKeyword("Ethereal")).ToList(); //含有“虚无”关键词的卡牌
List<CardInstance> cardToRetain = handPile.Where(card => card.HasKeyword("Retain")).ToList(); //含有“保留”关键词的卡牌
List<CardInstance> cardToExhaust = handPile.Where(card => card.HasKeyword("Ethereal")).ToList(); //含有“虚无”关键词的卡牌
List<CardInstance> cardsToDiscard = handPile.Except(cardToRetain).Except(cardToExhaust).ToList(); //其他卡牌,默认丢弃
CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.ExhaustCards(cardToExhaust));
CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.DiscardCards(cardsToDiscard, false));

View File

@@ -72,11 +72,11 @@ namespace Continentis.MainGame.Commands
{
if (isInitiative)
{
if (card.cardLogic.eventSubmodule.onInitiativeDiscard.GetChecks().Any()) // 如果主动弃牌后,有触发条件,则打断弃牌,直接触发效果
if (card.eventSubmodule.onInitiativeDiscard.GetChecks().Any()) // 如果主动弃牌后,有触发条件,则打断弃牌,直接触发效果
{
CommandQueueManager.Instance.AddCommand(new Cmd_Function(() =>
{
card.cardLogic.eventSubmodule.onInitiativeDiscard.GetEffects().ForEach(effect => effect.Invoke());
card.eventSubmodule.onInitiativeDiscard.GetEffects().ForEach(effect => effect.Invoke());
}));
return Observable.Return(Unit.Default);
}

View File

@@ -97,7 +97,7 @@ namespace Continentis.MainGame.Commands
CardInstance card = deck.DrawPile[0];
deck.TransferCard(deck.DrawPile, deck.HandPile, card);
card.cardLogic.eventSubmodule.onDraw.Invoke();
card.eventSubmodule.onDraw.Invoke();
card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.handPile);
Vector3 targetPosition = CombatUIManager.Instance.combatMainPage.handPile.GetCardPosition(index, totalCount);
@@ -116,7 +116,7 @@ namespace Continentis.MainGame.Commands
private IObservable<Unit> Draw(CardInstance card, int index, int totalCount)
{
deck.TransferCard(card.cardLocation.pileName, "Hand", card);
card.cardLogic.eventSubmodule.onDraw.Invoke();
card.eventSubmodule.onDraw.Invoke();
card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.handPile);
Vector3 targetPosition = CombatUIManager.Instance.combatMainPage.handPile.GetCardPosition(index, totalCount);

View File

@@ -72,7 +72,7 @@ namespace Continentis.MainGame.Commands
private IObservable<Unit> PlayerExhaustCard(CardInstance card)
{
deck.TransferCard(deck.Pile(card.cardLocation.pileName), deck.ExhaustPile, card);
card.cardLogic.eventSubmodule.onExhaust.Invoke();
card.eventSubmodule.onExhaust.Invoke();
card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.exhaustPile);
@@ -94,7 +94,7 @@ namespace Continentis.MainGame.Commands
private IObservable<Unit> NpcExhaustCard(CardInstance card)
{
deck.TransferCard(deck.Pile(card.cardLocation.pileName), deck.ExhaustPile, card);
card.cardLogic.eventSubmodule.onExhaust.Invoke();
card.eventSubmodule.onExhaust.Invoke();
return Observable.Timer(TimeSpan.FromSeconds(singleCardAnimationDuration)).AsUnitObservable();
}
}

View File

@@ -77,7 +77,7 @@ namespace Continentis.MainGame.Commands
card.handCardView.TransferCardView(CombatUIManager.Instance.combatMainPage.gravePile);
RectTransform cardTransform = card.handCardView.cardTransform;
Vector2 userViewPosition = card.cardLogic.user.characterView.hudContainer.GetComponent<RectTransform>().position;
Vector2 userViewPosition = card.user.characterView.hudContainer.GetComponent<RectTransform>().position;
cardTransform.DOMove(userViewPosition, singleCardAnimationDuration).SetEase(Ease.Linear).Play();
cardTransform.DOScale(Vector3.zero, singleCardAnimationDuration).SetEase(Ease.Linear).OnComplete(() =>
{

View File

@@ -58,7 +58,7 @@ namespace Continentis.MainGame.UI
this.selectedCards = new List<CardInstance>();
foreach (CardInstance card in this.cardsToSelect)
{
Debug.Log($"Card to select: {card.cardLogic.contentSubmodule.cardName} from {card.cardLocation.pileName}");
Debug.Log($"Card to select: {card.contentSubmodule.cardName} from {card.cardLocation.pileName}");
CombatUIManager.Instance.combatMainPage.Pile(card.cardLocation.pileName).RemoveCard(card.handCardView);
card.handCardView.transform.SetParent(selectionContainer, false);
card.handCardView.transform.localScale = Vector3.one;
@@ -80,7 +80,7 @@ namespace Continentis.MainGame.UI
public void Select(HandCardView cardView)
{
if (selectedCards.Contains(cardView.cardInstance))
if (selectedCards.Contains(cardView.card))
{
return;
}
@@ -90,7 +90,7 @@ namespace Continentis.MainGame.UI
return;
}
selectedCards.Add(cardView.cardInstance);
selectedCards.Add(cardView.card);
cardView.EnableSelectShadow();
if (isForcedMaximum)
{
@@ -100,7 +100,7 @@ namespace Continentis.MainGame.UI
public void Deselect(HandCardView cardView)
{
selectedCards.Remove(cardView.cardInstance);
selectedCards.Remove(cardView.card);
cardView.DisableSelectShadow();
if (isForcedMaximum)
{

View File

@@ -80,19 +80,19 @@ namespace Continentis.MainGame.UI
return;
}
if (selectedCards.Contains(cardView.cardInstance))
if (selectedCards.Contains(cardView.card))
{
return;
}
if (!selectionCondition(cardView.cardInstance))
if (!selectionCondition(cardView.card))
{
return;
}
string pileName = cardView.cardInstance.cardLocation.pileName;
int index = cardView.cardInstance.deck.Pile(pileName).IndexOf(cardView.cardInstance);
selectedCards.Add(cardView.cardInstance);
string pileName = cardView.card.cardLocation.pileName;
int index = cardView.card.deck.Pile(pileName).IndexOf(cardView.card);
selectedCards.Add(cardView.card);
CombatUIManager.Instance.combatMainPage.Pile(pileName).RemoveCard(cardView);
cardView.transform.SetParent(selectionContainer, false);
@@ -105,9 +105,9 @@ namespace Continentis.MainGame.UI
public void Deselect(HandCardView cardView)
{
CardLocation location = cardView.cardInstance.cardLocation;
CardLocation location = cardView.card.cardLocation;
PileBase uiPile = CombatUIManager.Instance.combatMainPage.Pile(location.pileName);
selectedCards.Remove(cardView.cardInstance);
selectedCards.Remove(cardView.card);
uiPile.AddCard(cardView);
cardView.transform.SetParent(uiPile.rectTransform, false);
cardView.transform.SetSiblingIndex(location.index);

View File

@@ -45,10 +45,10 @@ namespace Continentis.MainGame.UI
{
CombatUIManager.Instance.combatMainPage.ClearAllCardViews();
CombatMainManager.Instance.characterController.playerTeam.deckSubmodule.SetUpHandCardViews();
CombatMainManager.Instance.characterController.playerTeam.deckSubmodule.GetAllCards().ForEach(c =>
CombatMainManager.Instance.characterController.playerTeam.deckSubmodule.GetAllCards().ForEach(card =>
{
c.user = CombatMainManager.Instance.currentCharacter;
c.cardLogic.RefreshCardAttributes();
card.user = CombatMainManager.Instance.currentCharacter;
card.RefreshCardAttributes();
});
}));