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 CardLogicBase { /// /// 选中目标时触发的效果,效果在所有逻辑组件的Targeting之前执行(在SetUp函数生成EventSubmodule的时候)。 /// 如果必须需要在逻辑组件之后执行,请重写Initialize函数。 /// public virtual void TargetingEffect(CharacterBase target) { } /// /// 取消选中目标时触发的效果,效果在所有逻辑组件的Untargeting之前执行(在SetUp函数生成EventSubmodule的时候)。 /// 如果必须需要在逻辑组件之后执行,请重写Initialize函数。 /// public virtual void UntargetingEffect() { } } public partial class CardLogicBase { /// /// 刷新卡牌属性 /// public void RefreshCardAttributes() { if(user == null) return; attributeSubmodule.RefreshAllAttributes(); if ((handCardView == null && intentionCardView == null) || !handCardView.isSelecting) { eventSubmodule.onUntargeting(); } } /// /// 根据卡牌内容应用属性变化 /// public virtual void ApplyAttributeChangesByCard() { } } public partial class CardLogicBase { public virtual void DetectTargetsValidity(out List valid, out List notMet, out List invalid) { List characters = CombatMainManager.Instance.characterController.characters; invalid = new List(); notMet = new List(); valid = new List(); int targetCount = attributeSubmodule.targetCount; if (targetCount <= -2) { return; } if (targetCount == 0 || HasKeyword("TargetSelf")) // 卡牌目标为自身 { valid.Add(user); invalid.AddRange(characters); invalid.Remove(user); } else if (HasKeyword("TargetAllies")) // 卡牌目标为友方单位 { if(user.fraction is Fraction.Ally or Fraction.Player) { foreach (CharacterBase character in characters) { if (character.fraction is Fraction.Ally or Fraction.Player) { valid.Add(character); } else { invalid.Add(character); } } } else { foreach (CharacterBase character in characters) { if (character.fraction == user.fraction) { valid.Add(character); } else { invalid.Add(character); } } } } else if (HasKeyword("TargetEnemies")) // 卡牌目标为敌人 { if (user.fraction is Fraction.Ally or Fraction.Player) { foreach (CharacterBase character in characters) { if (character.fraction is Fraction.Enemy or Fraction.Neutral) { valid.Add(character); } else { invalid.Add(character); } } } else { foreach (CharacterBase character in characters) { if (character.fraction != user.fraction) { valid.Add(character); } else { invalid.Add(character); } } } if (targetCount != -1) { if (valid.Any(target => target.statusSubmodule.HasStatus(StatusType.Taunt))) { List protectedTargets = valid .Where(target => !target.statusSubmodule.HasStatus(StatusType.Taunt)) .ToList(); notMet.AddRange(protectedTargets); valid.RemoveAll(target => !target.statusSubmodule.HasStatus(StatusType.Taunt)); } } } else if(HasKeyword("TargetAll")) // 卡牌目标为全体 { valid.AddRange(characters); } else { valid.AddRange(characters);// 默认卡牌目标为所有单位 Debug.Log("No valid target found"); } } 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) { if (handCardView != null) { if (handCardView.isDuringPlaying) { return false; } handCardView.isDuringPlaying = true; } cardInstance.user = user ?? CombatMainManager.Instance.currentCharacter; if (!willCheckBeforePlay || CheckBeforePlay()) { cardInstance.user.ModifyStamina(-GetAttribute("StaminaCost")); cardInstance.user.ModifyMana(-GetAttribute("ManaCost")); if (cardInstance.user is PlayerHero) { CombatUIManager.Instance.combatMainPage.combatResourcesDisplayer.UpdateIcons(); } Debug.Log($"Starting to play card: {contentSubmodule.cardName}"); CommandQueueManager.Instance.AddCommand(new Cmd_Function(() => { playSubmodule.isDuringPlayEffect = true; eventSubmodule.onBeforePlay.Invoke(targetList); cardInstance.user.eventSubmodule?.onBeforePlayCard.Invoke(cardInstance, targetList); cardInstance.user.combatBuffSubmodule.buffList.For(buff => { buff.eventSubmodule?.onBeforePlayCard.Invoke(cardInstance, targetList); }); })); CommandQueueManager.Instance.AddCommand(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 => { buff.eventSubmodule?.onAfterPlayCard.Invoke(cardInstance, targetList); }); AfterPlayEffect(targetList); playSubmodule.isDuringPlayEffect = false; })); return true; } else { if (handCardView != null) { handCardView.isDuringPlaying = false; } return false; } } protected virtual CommandBase PlayEffect(List targetList) { return null; } protected virtual void AfterPlayEffect(List targetList) { if (user is PlayerHero playerHero) { if (HasKeyword("Exhaust")) { playerHero.deckSubmodule.ExhaustCard(cardInstance); } else { playerHero.deckSubmodule.DiscardCard(cardInstance); CommandQueueManager.Instance.AddCommand(new Cmd_Function(() => { if (handCardView != null) { handCardView.isDuringPlaying = false; } })); } } else if (user is CombatNPC npc) { if (HasKeyword("Exhaust")) { npc.deckSubmodule.ExhaustCard(cardInstance); } } } } public partial class CardLogicBase { } }