Files
Continentis/Assets/Scripts/MainGame/Character/CharacterSubmodules/IntentionSubmodule/IntentionSubmodule_Functions.cs
SoulliesOfficial c3b1561375 更新
2026-04-01 12:23:27 -04:00

238 lines
11 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.Card;
using SLSFramework.General;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Continentis.MainGame.Character
{
public partial class IntentionSubmodule
{
// ──────────────────────────────────────────────────────────────
// 原子操作层
// ──────────────────────────────────────────────────────────────
/// <summary>移除指定位置的意图卡并销毁其视图。</summary>
/// <returns>被移除的 IntendedCard索引越界时返回 null。</returns>
public IntendedCard RemoveIntendedCardAt(int index)
{
if (!IsValidIndex(index)) return null;
IntendedCard removed = intendedCards[index];
removed.cardInstance.DestroyIntentionCardView();
intendedCards.RemoveAt(index);
onIntendedCardRemoved.Invoke(removed, index);
return removed;
}
/// <summary>替换指定位置的意图卡,销毁旧视图并生成新视图。</summary>
/// <returns>被替换掉的旧 IntendedCard索引越界时返回 null。</returns>
public IntendedCard ReplaceIntendedCardAt(int index, IntendedCard newCard)
{
if (!IsValidIndex(index)) return null;
if (newCard == null)
{
Debug.LogWarning("[IntentionSubmodule] ReplaceIntendedCardAt: newCard is null, performing remove instead.");
return RemoveIntendedCardAt(index);
}
IntendedCard oldCard = intendedCards[index];
oldCard.cardInstance.DestroyIntentionCardView();
intendedCards[index] = newCard;
newCard.cardInstance.GenerateIntentionCardView();
// 设置文本解析目标
if (newCard.targets.Count > 0)
{
newCard.cardInstance.Targeting(newCard.targets[0]);
newCard.cardInstance.contentSubmodule.dirtyMark = true;
}
onIntendedCardReplaced.Invoke(oldCard, newCard, index);
return oldCard;
}
/// <summary>在指定位置插入一张新意图卡并生成视图。</summary>
public void InsertIntendedCard(int index, IntendedCard newCard)
{
if (newCard == null)
{
Debug.LogWarning("[IntentionSubmodule] InsertIntendedCard: newCard is null, insertion skipped.");
return;
}
int clampedIndex = Mathf.Clamp(index, 0, intendedCards.Count);
intendedCards.Insert(clampedIndex, newCard);
newCard.cardInstance.GenerateIntentionCardView();
// 设置文本解析目标
if (newCard.targets.Count > 0)
{
newCard.cardInstance.Targeting(newCard.targets[0]);
newCard.cardInstance.contentSubmodule.dirtyMark = true;
}
onIntendedCardInserted.Invoke(newCard, clampedIndex);
}
/// <summary>在末尾追加一张新意图卡并生成视图。</summary>
public void AddIntendedCard(IntendedCard newCard)
{
InsertIntendedCard(intendedCards.Count, newCard);
}
// ──────────────────────────────────────────────────────────────
// 查询 / 工具层
// ──────────────────────────────────────────────────────────────
/// <summary>返回 intendedCards 中的随机索引,列表为空时返回 -1。</summary>
public int GetRandomIntendedCardIndex()
{
return intendedCards.Count == 0 ? -1 : Random.Range(0, intendedCards.Count);
}
/// <summary>
/// 使用过滤器从 intendedCards 中筛选出符合条件的意图卡索引列表。
/// </summary>
/// <param name="filter">返回 true 表示该意图卡通过筛选。</param>
public List<int> GetFilteredIntendedCardIndices(Func<IntendedCard, bool> filter)
{
List<int> result = new List<int>();
for (int i = 0; i < intendedCards.Count; i++)
{
if (filter(intendedCards[i]))
result.Add(i);
}
return result;
}
/// <summary>
/// 使用过滤器从 intendedCards 中随机选取一个符合条件的意图卡索引。
/// </summary>
/// <returns>随机索引,无符合条件的意图卡时返回 -1。</returns>
public int GetRandomFilteredIntendedCardIndex(Func<IntendedCard, bool> filter)
{
List<int> filtered = GetFilteredIntendedCardIndices(filter);
return filtered.Count == 0 ? -1 : filtered[Random.Range(0, filtered.Count)];
}
/// <summary>
/// 尝试从 PoolPile 中获取一张可替换的随机卡牌(排除当前已在 intendedCards 中的卡牌)。
/// </summary>
/// <param name="result">生成的 IntendedCard失败时为 null。</param>
/// <param name="checkAffordability">是否检查体力/法力消耗。</param>
/// <returns>是否成功找到可替换的卡牌。</returns>
public bool TryGetRandomReplacementCard(out IntendedCard result, bool checkAffordability = false)
{
result = null;
HashSet<CardInstance> currentCards = new HashSet<CardInstance>(
intendedCards.Select(ic => ic.cardInstance));
List<CardInstance> candidates = owner.deckSubmodule.PoolPile
.Where(card => !currentCards.Contains(card) && !card.weightSubmodule.forceIgnore)
.ToList();
if (checkAffordability)
{
int stamina = owner.GetAttribute(CharacterAttributes.Stamina);
int mana = owner.GetAttribute(CharacterAttributes.Mana);
candidates = candidates.Where(card =>
card.GetAttribute(CardAttributes.StaminaCost) <= stamina &&
card.GetAttribute(CardAttributes.ManaCost) <= mana).ToList();
}
if (candidates.Count == 0) return false;
CardInstance chosen = candidates[Random.Range(0, candidates.Count)];
if (!owner.CheckAvailabilityAndSetTargets(chosen, out List<CharacterBase> targets))
return false;
result = new IntendedCard(chosen, targets);
return true;
}
// ──────────────────────────────────────────────────────────────
// 组合操作层
// ──────────────────────────────────────────────────────────────
/// <summary>随机移除一张意图卡。</summary>
/// <returns>被移除的 IntendedCard列表为空时返回 null。</returns>
public IntendedCard RemoveRandomIntendedCard()
{
int index = GetRandomIntendedCardIndex();
return index < 0 ? null : RemoveIntendedCardAt(index);
}
/// <summary>
/// 随机移除一张符合过滤条件的意图卡。
/// </summary>
/// <param name="filter">返回 true 表示该意图卡可被移除。</param>
/// <returns>被移除的 IntendedCard无符合条件的意图卡时返回 null。</returns>
public IntendedCard RemoveRandomIntendedCard(Func<IntendedCard, bool> filter)
{
int index = GetRandomFilteredIntendedCardIndex(filter);
return index < 0 ? null : RemoveIntendedCardAt(index);
}
/// <summary>
/// 随机将一张意图卡替换为 PoolPile 中的另一张卡牌。
/// 若无可替换卡牌则降级为移除。
/// </summary>
/// <param name="checkAffordability">是否检查体力/法力消耗。</param>
/// <returns>操作是否成功执行(移除或替换均算成功)。</returns>
public bool ChangeRandomIntendedCard(bool checkAffordability = false)
{
int index = GetRandomIntendedCardIndex();
if (index < 0) return false;
if (TryGetRandomReplacementCard(out IntendedCard replacement, checkAffordability))
{
ReplaceIntendedCardAt(index, replacement);
}
else
{
RemoveIntendedCardAt(index);
}
return true;
}
/// <summary>
/// 随机将一张符合过滤条件的意图卡替换为 PoolPile 中的另一张卡牌。
/// 若无可替换卡牌则降级为移除。
/// </summary>
/// <param name="filter">返回 true 表示该意图卡可被替换。</param>
/// <param name="checkAffordability">是否检查体力/法力消耗。</param>
/// <returns>操作是否成功执行。</returns>
public bool ChangeRandomIntendedCard(Func<IntendedCard, bool> filter, bool checkAffordability = false)
{
int index = GetRandomFilteredIntendedCardIndex(filter);
if (index < 0) return false;
if (TryGetRandomReplacementCard(out IntendedCard replacement, checkAffordability))
{
ReplaceIntendedCardAt(index, replacement);
}
else
{
RemoveIntendedCardAt(index);
}
return true;
}
// ──────────────────────────────────────────────────────────────
// 内部工具
// ──────────────────────────────────────────────────────────────
private bool IsValidIndex(int index)
{
if (index >= 0 && index < intendedCards.Count) return true;
Debug.LogWarning($"[IntentionSubmodule] Index {index} out of range (count: {intendedCards.Count}).");
return false;
}
}
}