using System.Collections.Generic; using System.Linq; using Continentis.MainGame.Card; using Continentis.MainGame.Combat; using NaughtyAttributes; using UnityEngine; namespace Continentis.MainGame.Character { public enum Fraction { Player, Ally, Enemy, Neutral } public interface ICardOwner { DeckSubmodule deckSubmodule { get; } } public partial class CharacterBase : ICardOwner { public CharacterData data; public Fraction fraction; public CombatTeam team; public int actionCountThisRound; [ShowNativeProperty] public AttributeSubmodule attributeSubmodule { get; private set; } [ShowNativeProperty] public EventSubmodule eventSubmodule { get; private set; } [ShowNativeProperty] public EquipmentSubmodule equipmentSubmodule { get; private set; } [ShowNativeProperty] public DeckSubmodule deckSubmodule { get; private set; } [ShowNativeProperty] public IntentionSubmodule intentionSubmodule { get; private set; } [ShowNativeProperty] public StatusSubmodule statusSubmodule { get; private set; } [ShowNativeProperty] public CombatBuffSubmodule combatBuffSubmodule { get; private set; } public void Initialize(Fraction fraction) { this.fraction = fraction; switch (fraction) { case Fraction.Player: this.team = CombatMainManager.Instance.characterController.playerTeam; break; case Fraction.Enemy: this.team = CombatMainManager.Instance.characterController.enemyTeam; break; default: this.team = null; break; } attributeSubmodule = new AttributeSubmodule(this); equipmentSubmodule = new EquipmentSubmodule(this); eventSubmodule = new EventSubmodule(this); deckSubmodule = new DeckSubmodule(this); intentionSubmodule = new IntentionSubmodule(this); statusSubmodule = new StatusSubmodule(this); combatBuffSubmodule = new CombatBuffSubmodule(this); } } public partial class CharacterBase { public CombatCharacterViewBase characterView; } public partial class CharacterBase { public virtual void GetIntendedCards() { bool CanAfford(CardInstance card, int stamina, int mana) { return card.cardLogic.GetAttribute("StaminaCost") <= stamina && card.cardLogic.GetAttribute("ManaCost") <= mana; } bool CheckAvailabilityAndSetTargets(CardInstance card, out List targets) { card.cardLogic.DetectTargetsValidity(out List valid, out _, out _); if (valid.Count == 0 || !card.cardLogic.CheckBeforePlay()) { targets = null; return false; // 无有效目标或无法使用则跳过 } targets = card.cardLogic.SetRandomTargets(valid); return true; } IntentionBase currentIntention = intentionSubmodule.currentIntention; List availableCards = deckSubmodule.PoolPile; List intended = new List(); int currentStamina = GetAttribute("Stamina"); int remainingStamina = currentStamina - currentIntention.guaranteedStamina; int currentMana = GetAttribute("Mana"); int remainingMana = currentMana - currentIntention.guaranteedMana; List forced = new List(); List normal = new List(); foreach (CardInstance card in availableCards) { if (card.cardLogic.weightSubmodule.forceUse) { forced.Add(card); } else { normal.Add(card); } } intentionSubmodule.intendedCards.Clear(); //(characterView.hudContainer.enablingHUDs["Intention"] as Intention)?.Clear(); // 1. 优先处理强制选择卡牌 foreach (CardInstance card in forced) { if (currentIntention.maxCardCount > 0 && intended.Count >= currentIntention.maxCardCount) { break; // 已达数量上限 } if (CanAfford(card, remainingStamina, remainingMana)) { if(!CheckAvailabilityAndSetTargets(card, out List targets)) { continue; // 无有效目标或无法使用则跳过 } intended.Add(new IntendedCard(card, targets)); remainingStamina -= card.cardLogic.GetAttribute("StaminaCost"); remainingMana -= card.cardLogic.GetAttribute("ManaCost"); } // 行动力不足则跳过该卡 } // 2. 在剩余普通卡牌中基于权重随机选取 while (intended.Count < currentIntention.maxCardCount) { // 筛选出当前资源下还能出的牌 List affordableCards = normal.FindAll(card => CanAfford(card, remainingStamina, remainingMana)); if (affordableCards.Count == 0) { break; } float totalWeight = affordableCards.Sum(card => card.cardLogic.weightSubmodule.currentWeight); if (totalWeight <= 0f) break; float r = Random.value * totalWeight; float accum = 0f; CardInstance chosen = null; foreach (CardInstance card in affordableCards) { accum += card.cardLogic.weightSubmodule.currentWeight; if (r <= accum) { chosen = card; break; } } if (chosen != null) { if (!CheckAvailabilityAndSetTargets(chosen, out List targets)) { normal.Remove(chosen); continue; // 无有效目标或无法使用则跳过 } intended.Add(new IntendedCard(chosen, targets)); normal.Remove(chosen); remainingStamina -= chosen.cardLogic.GetAttribute("StaminaCost"); remainingMana -= chosen.cardLogic.GetAttribute("ManaCost"); } } intentionSubmodule.intendedCards.AddRange(intended); } } public partial class CharacterBase { public CombatCharacterViewBase GenerateCharacterView(Vector3 position) { GameObject prefab = data.combatCharacterView; CombatCharacterViewBase characterView = Object.Instantiate(prefab, position, Quaternion.identity).GetComponent(); characterView.InitializeAnimations(); characterView.character = this; this.characterView = characterView; return characterView; } } }