Files
Continentis/Assets/Scripts/MainGame/Card/CardMainFunctions.cs
2025-10-30 12:07:59 -04:00

267 lines
9.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
/// <summary>
/// 选中目标时触发的效果效果在所有逻辑组件的Targeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void TargetingEffect(CharacterBase target)
{
}
/// <summary>
/// 取消选中目标时触发的效果效果在所有逻辑组件的Untargeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void UntargetingEffect()
{
}
}
public partial class CardLogicBase
{
/// <summary>
/// 刷新卡牌属性
/// </summary>
public void RefreshCardAttributes()
{
if(user == null) return;
attributeSubmodule.RefreshAllAttributes();
if ((handCardView == null && intentionCardView == null) || !handCardView.isSelecting)
{
eventSubmodule.onUntargeting();
}
}
/// <summary>
/// 根据卡牌内容应用属性变化
/// </summary>
public virtual void ApplyAttributeChangesByCard()
{
}
}
public partial class CardLogicBase
{
public virtual void DetectTargetsValidity(out List<CharacterBase> valid, out List<CharacterBase> notMet, out List<CharacterBase> invalid)
{
List<CharacterBase> characters = CombatMainManager.Instance.characterController.characters;
invalid = new List<CharacterBase>(characters);
notMet = new List<CharacterBase>();
valid = new List<CharacterBase>();
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"))
{
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<CharacterBase> 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<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;
}
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;
}
/// <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())
{
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;
handCardView.isDuringPlaying = false;
}));
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)
{
if (HasKeyword("Exhaust"))
{
playerHero.deckSubmodule.ExhaustCard(cardInstance);
}
else if(!HasKeyword("Reuse"))
{
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
{
}
}