Files
Continentis/Assets/Scripts/MainGame/Card/CardMainFunctions.cs
SoulliesOfficial 5fe665d0ce Card爆改!
2025-11-15 12:17:34 -05:00

320 lines
12 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 CardInstance
{
/// <summary>
/// 选中目标时触发的效果效果在所有逻辑组件的Targeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void Targeting(CharacterBase target)
{
eventSubmodule.onTargeting.Invoke(target);
}
/// <summary>
/// 取消选中目标时触发的效果效果在所有逻辑组件的Untargeting之前执行在SetUp函数生成EventSubmodule的时候
/// 如果必须需要在逻辑组件之后执行请重写Initialize函数。
/// </summary>
public virtual void Untargeting()
{
eventSubmodule.onUntargeting.Invoke();
}
}
public partial class CardInstance
{
/// <summary>
/// 刷新卡牌属性
/// </summary>
public void RefreshCardAttributes()
{
if(user == null) return;
attributeSubmodule.RefreshAllAttributes();
if ((handCardView == null && intentionCardView == null) || !handCardView.isSelecting)
{
eventSubmodule.onUntargeting();
}
contentSubmodule.dirtyMark = true;
}
/// <summary>
/// 根据卡牌内容应用属性变化
/// </summary>
public void ApplyAttributeChangesByCard()
{
cardLogic.ApplyAttributeChangesByCard();
}
}
public partial class CardInstance
{
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") || 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<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;
}
this.user = user ?? CombatMainManager.Instance.currentCharacter;
this.user.recordSubmodule.RecordCardPlay(this);
if (!willCheckBeforePlay || CheckBeforePlay())
{
this.user.ModifyStamina(-GetAttribute("StaminaCost"));
this.user.ModifyMana(-GetAttribute("ManaCost"));
if (this.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);
this.user.eventSubmodule?.onBeforePlayCard.Invoke(this, targetList);
this.user.combatBuffSubmodule.buffList.For(buff =>
{
buff.eventSubmodule?.onBeforePlayCard.Invoke(this, targetList);
});
}));
CommandQueueManager.Instance.AddCommands(PlayEffect(targetList));
CommandQueueManager.Instance.AddCommands(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 List<CommandBase> PlayEffect(List<CharacterBase> targetList)
{
return new List<CommandBase>();
}
protected virtual void AfterPlayEffect(List<CharacterBase> 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<string, List<CardInstance>> 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
{
}
}
}
}