Files
Continentis/Assets/Scripts/MainGame/Card/CardMainFunctions.cs

316 lines
11 KiB
C#
Raw Normal View History

2025-10-03 00:02:43 -04:00
using System;
using System.Collections.Generic;
using System.Linq;
using Continentis.MainGame.Character;
2025-10-23 00:49:44 -04:00
using Continentis.MainGame.Combat;
2025-10-03 00:02:43 -04:00
using Continentis.MainGame.Commands;
2025-10-23 00:49:44 -04:00
using SLSFramework.General;
using SLSFramework.UModAssistance;
2025-10-03 00:02:43 -04:00
using UniRx;
2025-10-23 00:49:44 -04:00
using UnityEngine;
using Random = UnityEngine.Random;
2025-10-03 00:02:43 -04:00
namespace Continentis.MainGame.Card
{
public partial class CardLogicBase
{
2025-10-23 00:49:44 -04:00
/// <summary>
/// 选中目标时触发的效果效果在所有逻辑组件的Targeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void TargetingEffect(CharacterBase target)
2025-10-03 00:02:43 -04:00
{
}
2025-10-23 00:49:44 -04:00
/// <summary>
/// 取消选中目标时触发的效果效果在所有逻辑组件的Untargeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void UntargetingEffect()
2025-10-03 00:02:43 -04:00
{
}
}
public partial class CardLogicBase
{
2025-10-23 00:49:44 -04:00
/// <summary>
/// 刷新卡牌属性
/// </summary>
2025-10-03 00:02:43 -04:00
public void RefreshCardAttributes()
{
if(user == null) return;
attributeSubmodule.RefreshAllAttributes();
2025-10-23 00:49:44 -04:00
if ((handCardView == null && intentionCardView == null) || !handCardView.isSelecting)
{
eventSubmodule.onUntargeting();
}
2025-10-03 00:02:43 -04:00
}
2025-10-23 00:49:44 -04:00
/// <summary>
/// 根据卡牌内容应用属性变化
/// </summary>
2025-10-03 00:02:43 -04:00
public virtual void ApplyAttributeChangesByCard()
{
}
}
public partial class CardLogicBase
{
2025-10-23 00:49:44 -04:00
public virtual void DetectTargetsValidity(out List<CharacterBase> valid, out List<CharacterBase> notMet, out List<CharacterBase> invalid)
2025-10-03 00:02:43 -04:00
{
2025-10-23 00:49:44 -04:00
List<CharacterBase> characters = CombatMainManager.Instance.characterController.characters;
2025-10-03 00:02:43 -04:00
invalid = new List<CharacterBase>();
2025-10-23 00:49:44 -04:00
notMet = new List<CharacterBase>();
2025-10-03 00:02:43 -04:00
valid = new List<CharacterBase>();
int targetCount = attributeSubmodule.targetCount;
if (targetCount <= -2)
{
2025-10-23 00:49:44 -04:00
return;
2025-10-03 00:02:43 -04:00
}
2025-10-27 07:04:34 -04:00
if (targetCount == 0 || HasKeyword("TargetSelf")) // 卡牌目标为自身
2025-10-03 00:02:43 -04:00
{
valid.Add(user);
invalid.AddRange(characters);
invalid.Remove(user);
}
2025-10-27 07:04:34 -04:00
else if (HasKeyword("TargetAllies")) // 卡牌目标为友方单位
2025-10-03 00:02:43 -04:00
{
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);
}
}
}
}
2025-10-27 07:04:34 -04:00
else if (HasKeyword("TargetEnemies")) // 卡牌目标为敌人
2025-10-03 00:02:43 -04:00
{
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<CharacterBase> protectedTargets = valid
.Where(target => !target.statusSubmodule.HasStatus(StatusType.Taunt))
.ToList();
2025-10-23 00:49:44 -04:00
notMet.AddRange(protectedTargets);
2025-10-03 00:02:43 -04:00
valid.RemoveAll(target => !target.statusSubmodule.HasStatus(StatusType.Taunt));
}
}
}
2025-10-27 07:04:34 -04:00
else if(HasKeyword("TargetAll")) // 卡牌目标为全体
2025-10-03 00:02:43 -04:00
{
valid.AddRange(characters);
}
else
{
2025-10-27 07:04:34 -04:00
valid.AddRange(characters);// 默认卡牌目标为所有单位
2025-10-23 00:49:44 -04:00
Debug.Log("No valid target found");
2025-10-03 00:02:43 -04:00
}
}
2025-10-23 00:49:44 -04:00
public virtual List<CharacterBase> SetRandomTargets(List<CharacterBase> valid)
{
List<CharacterBase> targets = new List<CharacterBase>();
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;
}
2025-10-03 00:02:43 -04:00
public virtual bool CheckBeforePlay()
{
2025-10-23 00:49:44 -04:00
if (!user.CheckEnoughStamina(GetAttribute("StaminaCost")))
2025-10-03 00:02:43 -04:00
{
2025-10-23 00:49:44 -04:00
MainGameManager.Instance.basePrefabs.GenerateInfoText("Not Enough Stamina", user.characterView);
2025-10-03 00:02:43 -04:00
return false;
}
2025-10-23 00:49:44 -04:00
if (!user.CheckEnoughMana(GetAttribute("ManaCost")))
2025-10-03 00:02:43 -04:00
{
2025-10-23 00:49:44 -04:00
MainGameManager.Instance.basePrefabs.GenerateInfoText("Not Enough Mana", user.characterView);
2025-10-03 00:02:43 -04:00
return false;
}
return true;
}
/// <summary>
/// 打出卡牌
/// 注意,这个函数内部包含了命令队列的调用
/// </summary>
/// <param name="targetList">目标列表</param>
/// <param name="user">使用者</param>
/// <param name="willCheckBeforePlay">打出之前是否进行可用性检测</param>
public bool Play(List<CharacterBase> targetList, CharacterBase user = null, bool willCheckBeforePlay = true)
{
if (handCardView != null)
{
if (handCardView.isDuringPlaying)
{
return false;
}
handCardView.isDuringPlaying = true;
}
2025-10-23 00:49:44 -04:00
2025-10-03 00:02:43 -04:00
cardInstance.user = user ?? CombatMainManager.Instance.currentCharacter;
if (!willCheckBeforePlay || CheckBeforePlay())
{
2025-10-23 00:49:44 -04:00
cardInstance.user.ModifyStamina(-GetAttribute("StaminaCost"));
cardInstance.user.ModifyMana(-GetAttribute("ManaCost"));
2025-10-03 00:02:43 -04:00
if (cardInstance.user is PlayerHero)
2025-10-23 00:49:44 -04:00
{
CombatUIManager.Instance.combatMainPage.combatResourcesDisplayer.UpdateIcons();
}
Debug.Log($"Starting to play card: {contentSubmodule.cardName}");
2025-10-03 00:02:43 -04:00
2025-10-23 00:49:44 -04:00
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;
}));
2025-10-03 00:02:43 -04:00
return true;
}
else
{
if (handCardView != null)
{
handCardView.isDuringPlaying = false;
}
return false;
}
}
protected virtual CommandBase PlayEffect(List<CharacterBase> targetList)
{
return null;
}
protected virtual void AfterPlayEffect(List<CharacterBase> targetList)
{
if (user is PlayerHero playerHero)
{
2025-10-23 00:49:44 -04:00
if (HasKeyword("Exhaust"))
2025-10-03 00:02:43 -04:00
{
playerHero.deckSubmodule.ExhaustCard(cardInstance);
}
else
{
playerHero.deckSubmodule.DiscardCard(cardInstance);
2025-10-23 00:49:44 -04:00
CommandQueueManager.Instance.AddCommand(new Cmd_Function(() =>
2025-10-03 00:02:43 -04:00
{
if (handCardView != null)
{
handCardView.isDuringPlaying = false;
}
}));
}
}
else if (user is CombatNPC npc)
{
2025-10-23 00:49:44 -04:00
if (HasKeyword("Exhaust"))
2025-10-03 00:02:43 -04:00
{
npc.deckSubmodule.ExhaustCard(cardInstance);
}
}
}
}
public partial class CardLogicBase
{
2025-10-23 00:49:44 -04:00
2025-10-03 00:02:43 -04:00
}
}