Files
Continentis/Assets/Scripts/MainGame/Card/CardMainFunctions.cs
SoulliesOfficial 9b1b5ca93f initial
2025-10-03 00:02:43 -04:00

298 lines
9.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Continentis.MainGame.Character;
using Continentis.MainGame.Commands;
using DamageNumbersPro;
using SoulliesFramework.General;
using UnityEngine;
using UniRx;
namespace Continentis.MainGame.Card
{
public partial class CardLogicBase
{
public void Targeting(CharacterBase target)
{
TargetingEffect(target);
}
public void Untargeting()
{
UntargetingEffect();
}
protected virtual void TargetingEffect(CharacterBase target)
{
}
protected virtual void UntargetingEffect()
{
}
}
public partial class CardLogicBase
{
public void RefreshCardAttributes()
{
if(user == null) return;
attributeSubmodule.RefreshAllAttributes();
if(handCardView == null || !handCardView.isSelecting) Untargeting();
}
public virtual void ApplyAttributeChangesByCard()
{
}
}
public partial class CardLogicBase
{
public virtual void SetTargets(out List<CharacterBase> valid,
out List<CharacterBase> conditionNotMet, out List<CharacterBase> invalid)
{
List<CharacterBase> characters = CombatMainManager.Instance.characters;
invalid = new List<CharacterBase>();
conditionNotMet = new List<CharacterBase>();
valid = new List<CharacterBase>();
int targetCount = attributeSubmodule.targetCount;
if (targetCount <= -2)
{
throw new Exception("Target count is invalid.");
}
if (targetCount == 0 || cardData.functionalTags.Contains("TargetSelf")) // 卡牌目标为自身
{
valid.Add(user);
invalid.AddRange(characters);
invalid.Remove(user);
}
else if (cardData.functionalTags.Contains("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 (cardData.functionalTags.Contains("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<CharacterBase> protectedTargets = valid
.Where(target => !target.statusSubmodule.HasStatus(StatusType.Taunt))
.ToList();
conditionNotMet.AddRange(protectedTargets);
valid.RemoveAll(target => !target.statusSubmodule.HasStatus(StatusType.Taunt));
}
}
}
else if(cardData.functionalTags.Contains("TargetAll")) // 卡牌目标为全体
{
valid.AddRange(characters);
}
else
{
throw new Exception("No valid target found, please check the card data.");
}
}
public virtual bool CheckBeforePlay()
{
Vector3 userPosition = user.characterView.transform.position;
if (!CheckEnoughStamina())
{
MainGameManager.Instance.basePrefabs.GenerateInfoText("Not Enough Stamina", userPosition);
return false;
}
if (!CheckEnoughMana())
{
MainGameManager.Instance.basePrefabs.GenerateInfoText("Not Enough Mana", userPosition);
return false;
}
return true;
}
/*public void Play(List<CharacterBase> targetList, CharacterBase user = null, bool willCheckBeforePlay = true)
{
CommandQueueManager.Instance.AddCommand(_Play(targetList, user, willCheckBeforePlay));
}*/
/// <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;
}
cardInstance.user = user ?? CombatMainManager.Instance.currentCharacter;
if (!willCheckBeforePlay || CheckBeforePlay())
{
eventSubmodule.onBeforePlay.Invoke(targetList);
CommandQueueManager.Instance.AddCommand(PlayEffect(targetList));
eventSubmodule.onAfterPlay.Invoke(targetList);
AfterPlayEffect(targetList);
combatBuffSubmodule.buffList.For(buff => buff.usageSubmodule?.UpdateModule());
if (cardInstance.user is PlayerHero)
CombatUIManager.Instance.deckPage.combatResourcesDisplayer.UpdateIcons();
return true;
}
else
{
if (handCardView != null)
{
handCardView.isDuringPlaying = false;
}
return false;
}
}
protected virtual CommandBase PlayEffect(List<CharacterBase> targetList)
{
ConsumeStamina();
ConsumeMana();
return null;
}
protected virtual void AfterPlayEffect(List<CharacterBase> targetList)
{
if (user is PlayerHero playerHero)
{
if (HasTag("Exhaust"))
{
playerHero.deckSubmodule.ExhaustCard(cardInstance);
}
else
{
playerHero.deckSubmodule.DiscardCard(cardInstance);
CommandQueueManager.Instance.AddCommand(new Cmd_Function(0, () =>
{
if (handCardView != null)
{
handCardView.isDuringPlaying = false;
}
}));
}
}
else if (user is CombatNPC npc)
{
if (HasTag("Exhaust"))
{
npc.deckSubmodule.ExhaustCard(cardInstance);
}
}
}
}
public partial class CardLogicBase
{
/// <summary>
/// 添加格挡(格挡每回合结束后会清空)
/// </summary>
protected void AddBlock(int block, CharacterBase target = null)
{
target ??= user;
target.attributeSubmodule.generalAttributeGroup.current["Block"] += block;
target.characterView.hudContainer.UpdateAllHUD();
}
/// <summary>
/// 添加闪避(闪避在回合结束后或被击中后清空)
/// </summary>
protected void AddDodge(int dodge, CharacterBase target = null)
{
target ??= user;
target.attributeSubmodule.generalAttributeGroup.current["Dodge"] += dodge;
target.characterView.hudContainer.UpdateAllHUD();
}
/// <summary>
/// 添加护盾(护盾不会自动清空)
/// </summary>
protected void AddShield(int shield, CharacterBase target = null)
{
target ??= user;
target.attributeSubmodule.generalAttributeGroup.current["Shield"] += shield;
target.characterView.hudContainer.UpdateAllHUD();
}
}
}