using System; using System.Collections.Generic; using System.Linq; using Continentis.MainGame.Character; using Continentis.MainGame.Combat; using Continentis.MainGame.Commands; using SLSFramework.General; using SLSFramework.UModAssistance; using UniRx; using UnityEngine; using Random = UnityEngine.Random; namespace Continentis.MainGame.Card { public partial class CardInstance { /// /// 选中目标时触发的效果,效果在所有逻辑组件的Targeting之前执行(在SetUp函数生成EventSubmodule的时候)。 /// 如果必须需要在逻辑组件之后执行,请重写Initialize函数。 /// public virtual void Targeting(CharacterBase target) { eventSubmodule.onTargeting.Invoke(target); } /// /// 取消选中目标时触发的效果,效果在所有逻辑组件的Untargeting之前执行(在SetUp函数生成EventSubmodule的时候)。 /// 如果必须需要在逻辑组件之后执行,请重写Initialize函数。 /// public virtual void Untargeting() { eventSubmodule.onUntargeting.Invoke(); } } public partial class CardInstance { /// /// 刷新卡牌属性 /// public void RefreshCardAttributes() { if(user == null) return; attributeSubmodule.RefreshAllAttributes(); Untargeting(); /*if ((handCardView == null && intentionCardView == null)) { Untargeting(); } else { if (handCardView != null && !handCardView.isSelecting) { Untargeting(); } }*/ contentSubmodule.dirtyMark = true; } /// /// 根据卡牌内容应用属性变化 /// public void ApplyAttributeChangesByCard() { cardLogic.ApplyAttributeChangesByCard(); } } public partial class CardInstance { public virtual void DetectTargetsValidity(out List valid, out List notMet, out List invalid) { List characters = CombatMainManager.Instance.characterController.characters; invalid = new List(characters); notMet = new List(); valid = new List(); int targetCount = attributeSubmodule.targetCount; if (targetCount <= -2) { Debug.LogError("Invalid target count setting on card: " + contentSubmodule.cardName); return; } if (HasKeyword("TargetAll")) { valid.AddRange(characters); } else { if (HasKeyword("TargetAllies") || HasKeyword("Blessing")) { valid.AddRange(user.fraction is Fraction.Ally or Fraction.Player ? characters.Where(character => character.fraction is Fraction.Ally or Fraction.Player) : characters.Where(character => character.fraction == user.fraction)); valid.Remove(user); } if (HasKeyword("TargetSelf")) { valid.Add(user); } if (HasKeyword("TargetEnemies")) { valid.AddRange(user.fraction is Fraction.Ally or Fraction.Player ? characters.Where(character => character.fraction is Fraction.Enemy or Fraction.Neutral) : characters.Where(character => character.fraction != user.fraction)); //处理保护,嘲讽等 if (targetCount != -1) { List protectedTargets = valid.Where(target => target.statusSubmodule.HasStatus(StatusType.Protected)).ToList(); notMet.AddRange(protectedTargets); valid.RemoveRange(protectedTargets); } } } foreach (CharacterBase validTarget in valid) { invalid.Remove(validTarget); } } public virtual List SetRandomTargets(List valid) { List targets = new List(); int maximumTargets = attributeSubmodule.targetCount; if (maximumTargets == -1 || maximumTargets >= valid.Count) { targets.AddRange(valid); } else { while (targets.Count < maximumTargets && valid.Count > 0) { CharacterBase target = valid[Random.Range(0, valid.Count)]; valid.Remove(target); targets.Add(target); } } return targets; } public virtual bool CheckBeforePlay() { if (!user.CheckEnoughStamina(GetAttribute("StaminaCost"))) { MainGameManager.Instance.basePrefabs.GenerateInfoText("Not Enough Stamina", user.characterView); return false; } if (!user.CheckEnoughMana(GetAttribute("ManaCost"))) { MainGameManager.Instance.basePrefabs.GenerateInfoText("Not Enough Mana", user.characterView); return false; } return true; } /// /// 打出卡牌 /// 注意,这个函数内部包含了命令队列的调用 /// /// 目标列表 /// 使用者 /// 是否不消耗资源 /// 打出之前是否进行可用性检测 public bool Play(List targetList, CharacterBase user = null, bool willCheckBeforePlay = true, bool noConsumption = false) { if (handCardView != null) { if (handCardView.isDuringPlaying) { return false; } handCardView.isDuringPlaying = true; } this.user = user ?? CombatMainManager.Instance.currentCharacter; this.user.recordSubmodule.RecordCardPlay(this); if (!willCheckBeforePlay || CheckBeforePlay()) { if (!noConsumption) { this.user.ModifyStamina(-GetAttribute("StaminaCost")); this.user.ModifyMana(-GetAttribute("ManaCost")); } Debug.Log($"Starting to play card: {contentSubmodule.cardName}"); CommandQueueManager.Instance.AddCommand(new Cmd_Function(() => { playSubmodule.isDuringPlayEffect = true; eventSubmodule.onBeforePlay.Invoke(targetList); this.user.eventSubmodule?.onBeforePlayCard.Invoke(this, targetList); this.user.combatBuffSubmodule.buffList.For(buff => { buff.eventSubmodule?.onBeforePlayCard.Invoke(this, targetList); }); })); CommandQueueManager.Instance.AddCommand(PlayEffect(targetList)); CommandQueueManager.Instance.AddCommand(cardLogic.PlayEffect(targetList)); CommandQueueManager.Instance.AddCommand(new Cmd_Function(() => { eventSubmodule.onAfterPlay.Invoke(targetList); combatBuffSubmodule.buffList.For(buff => buff.usageSubmodule?.UpdateModule()); this.user.eventSubmodule.onAfterPlayCard.Invoke(this, targetList); this.user.combatBuffSubmodule.buffList.For(buff => { buff.eventSubmodule?.onAfterPlayCard.Invoke(this, targetList); }); AfterPlayEffect(targetList); cardLogic.AfterPlayEffect(targetList); playSubmodule.isDuringPlayEffect = false; if (handCardView != null) { handCardView.isDuringPlaying = false; } })); return true; } else { if (handCardView != null) { handCardView.isDuringPlaying = false; } return false; } } protected virtual CommandGroup PlayEffect(List targetList) { return new CommandGroup(); } protected virtual void AfterPlayEffect(List targetList) { if (contentSubmodule.cardType == CardType.Power) { CommandQueueManager.Instance.AddCommand(user.deckSubmodule.UsePowerCard(this)); return; } if (HasKeyword("Exhaust")) { CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(this)); return; } if(HasKeyword("Exhaustible")) { if (!HasAttribute("ExhaustibleCount")) { Debug.LogError("Exhaustible card missing ExhaustibleCount attribute: " + contentSubmodule.cardName); CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(this)); return; } ModifyAttribute("ExhaustibleCount", -1); if(GetAttribute("ExhaustibleCount") <= 0) { CommandQueueManager.Instance.AddCommand(user.deckSubmodule.ExhaustCard(this)); return; } } if (user is PlayerHero playerHero) { if(!HasKeyword("Reuseable")) { CommandQueueManager.Instance.AddCommand(playerHero.deckSubmodule.DiscardCard(this, false)); CommandQueueManager.Instance.AddCommand(new Cmd_Function(() => { if (handCardView != null) { handCardView.isDuringPlaying = false; } })); } } else if (user is CombatNPC npc) { } } } public partial class CardInstance { public void UpgradeCard() { if (owner is not CombatTeam) { KeyValuePair> 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 { } } } }