using System.Collections.Generic; using System.Linq; using Cute; using Wizard.Battle.Card; using Wizard.Battle.View.Vfx; namespace Wizard; public class AIOperationProcessor { private BattleManagerBase _battleMgr; private EnemyAI _ai; public AIOperationProcessor(BattleManagerBase mgr, EnemyAI ai) { _battleMgr = mgr; _ai = ai; } public VfxBase AIPlayCard(AISituationInfo situation) { _ai.BestPlayPtnRecord = null; SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create(); VfxBase emote = _ai.GetEmote(AIEmoteCmdType.ON_CARD_PLAY_ALLY, situation); sequentialVfxPlayer.Register(emote); AIRealBattleCardSearcher.SearchBattleCardFromSituation(_ai.PlayerPair, situation, out var actor, out var targetList); AISelectedTargetInfoSet selectedTargets = situation.SelectedTargets; if (targetList.IsNotNullOrEmpty() && !selectedTargets.HasChoiceTarget) { SequentialVfxPlayer sequentialVfxPlayer2 = SequentialVfxPlayer.Create(); for (int i = 0; i < targetList.Count; i++) { BattleCardBase battleCardBase = targetList[i]; if (!battleCardBase.IsClass && !battleCardBase.BattleCardView.IsLoadResorces) { sequentialVfxPlayer2.Register(WaitVfx.Create(0.07f)); sequentialVfxPlayer2.Register(battleCardBase.LoadResource()); sequentialVfxPlayer2.Register(WaitVfx.Create(0.2f)); } } sequentialVfxPlayer.Register(sequentialVfxPlayer2); } BattleCardBase battleCardBase2 = actor; int num = 0; if (actor.HasSkillAccelerate || actor.HasSkillCrystallize) { int num2 = CalcFixedUseCostTransformId(actor, actor.SelfBattlePlayer.Pp); if (num2 > 0) { battleCardBase2 = BattleManagerBase.GetIns().CreateTransformCardRegisterVfx(actor, num2, actor.IsPlayer); } } else if (actor.Skills.CheckWhenPlayChoice && actor.Skills.Count() > 1) { SkillBase skillBase = actor.Skills.Get(0); SkillBase skillBase2 = actor.Skills.Get(1); if (skillBase.IsChoiceType && skillBase2 is Skill_transform) { battleCardBase2 = targetList[0]; num = 1; } } BattlePlayerPair battlePlayerPair = _ai.PlayerPair.VirtualClone(CloneActualFlags.All); battlePlayerPair.Self.AddCurrentTrunPlayCount(1); BattleCardBase battleCardBase3 = battlePlayerPair.Self.HandCardList.Where((BattleCardBase c) => c.Index == actor.Index && c.CardId == actor.CardId && c.IsPlayer == actor.IsPlayer).FirstOrDefault(); if (battleCardBase3 != null) { battlePlayerPair.Self.HandCardList.Remove(battleCardBase3); } List checkSkillList = GetCheckSkillList(battleCardBase2.Skills, battlePlayerPair); if (CheckSelectTypeSkillTargetCount(actor, checkSkillList, targetList, num, "[PlayCard]") || targetList != null) { CheckSelectTypeSkillTarget(actor, battlePlayerPair, checkSkillList, targetList, num, "[PlayCard]"); } if (!targetList.IsNotNullOrEmpty() || !targetList.Any((BattleCardBase c) => c is IVirtualBattleCard) || !actor.Skills.HaveChoiceTransformSkill()) { sequentialVfxPlayer.Register(_battleMgr.OperateMgr.InitSetCard(actor, actor.IsPlayer, targetList.IsNotNullOrEmpty())); } sequentialVfxPlayer.Register(_battleMgr.OperateMgr.PlayCard(actor, actor.IsPlayer, targetList)); return sequentialVfxPlayer; } public VfxBase AIEvolutionCard(AISituationInfo situation) { AIRealBattleCardSearcher.SearchBattleCardFromSituation(_ai.PlayerPair, situation, out var actor, out var targetList); if (!actor.CanEvolution(isSkill: false, isSelfBattlePlayer: true)) { AIConsoleUtility.LogError("Evolution Condition Error!!!"); } if (actor.EvolutionSkills.HasEvolutionSkillWithSelection) { List checkSkillList = GetCheckSkillList(actor.EvolutionSkills, _ai.PlayerPair); CheckSelectTypeSkillTarget(actor, _ai.PlayerPair, checkSkillList, targetList, 0, "[Evolution]"); } SequentialVfxPlayer sequentialVfxPlayer = SequentialVfxPlayer.Create(); VfxBase emote = _ai.GetEmote(AIEmoteCmdType.ON_ALLY_EVOLUTION, situation); sequentialVfxPlayer.Register(emote); if (emote != NullVfx.GetInstance()) { _ai.EmoteQuery.OnCardPlayEmotion(); } sequentialVfxPlayer.Register(_battleMgr.OperateMgr.EvolutionCard(actor, actor.IsPlayer, targetList)); return sequentialVfxPlayer; } public VfxBase AIFusionCard(AISituationInfo situation) { AIRealBattleCardSearcher.SearchBattleCardFromSituation(_ai.PlayerPair, situation, out var actor, out var targetList); SkillBase item = actor.Skills.FirstOrDefault((SkillBase s) => s is Skill_fusion); CheckSelectTypeSkillTarget(actor, _ai.PlayerPair, new List { item }, targetList, 0, "[Fusion]"); return _battleMgr.OperateMgr.FusionCard(actor, actor.IsPlayer, targetList); } private List GetCheckSkillList(SkillCollectionBase skillCollection, BattlePlayerPair playerPair) { List list = new List(); IEnumerable selectTypeSkill = skillCollection.GetSelectTypeSkill(isEvolve: true, isFusion: false, isActivateFanfare: false, playerPair); SkillConditionCheckerOption option = new SkillConditionCheckerOption(); foreach (SkillBase item in skillCollection.Where((SkillBase s) => s.IsChoiceType && s.CheckCondition(playerPair, option, isPrePlay: true))) { if (!list.Contains(item)) { list.Add(item); } } foreach (SkillBase item2 in selectTypeSkill) { if (!list.Contains(item2)) { list.Add(item2); } } return list; } private void CheckSelectTypeSkillTarget(BattleCardBase actor, BattlePlayerPair playerPair, IEnumerable skills, List targetList, int selectTargetNumber, string checkTimingName) { int num = selectTargetNumber; bool flag = false; foreach (SkillBase skill in skills) { if (skill.IsBurialRite) { BattleCardBase card = targetList[num]; if (!actor.SelfBattlePlayer.HandCardList.Any((BattleCardBase c) => c.Index == card.Index && c.IsPlayer == card.IsPlayer)) { string message = actor.BaseParameter.CardName + checkTimingName + "BURIAL_RITE Target not in Hand list Error!!!"; ThrowErrorMessage(message); } else if (!card.IsInHand || !card.IsUnit) { string message2 = actor.BaseParameter.CardName + checkTimingName + "BURIAL_RITE Wrong targeted selection criteria Error!!!"; ThrowErrorMessage(message2); } flag = true; num++; } if (skill.ApplySelectFilter is SkillRandomSelectFilter || skill.ApplySelectFilter is SkillSelectAllFilter || (!skill.IsChoiceType && skill.ApplySelectFilter is SkillSelectNullFilter)) { continue; } IEnumerable selectableCards = skill.GetSelectableCards(playerPair, new SkillConditionCheckerOption()); int skillSelectCount = skill.GetSkillSelectCount(); int num2 = targetList.Count - num; skillSelectCount = ((skillSelectCount > num2) ? num2 : skillSelectCount); List list = new List(targetList.GetRange(num, skillSelectCount)); num += skillSelectCount; if (list.Count > 1) { for (int num3 = 0; num3 < list.Count; num3++) { BattleCardBase card2 = list[num3]; List list2 = list.Where((BattleCardBase c) => c.Index == card2.Index && c.IsPlayer == card2.IsPlayer).ToList(); if (list2.Count > 1) { string message3 = $"{actor.BaseParameter.CardName}{checkTimingName}Duplicate {list2.Count} selected card Error!!!"; ThrowErrorMessage(message3); } } } int num4 = 0; for (int num5 = 0; num5 < list.Count; num5++) { BattleCardBase card3 = list[num5]; if (!selectableCards.Any((BattleCardBase c) => c.Index == card3.Index && c.IsPlayer == card3.IsPlayer)) { if (num4 < selectableCards.Count() && !flag) { targetList[num5] = selectableCards.ElementAt(num4); num4++; } string message4 = actor.BaseParameter.CardName + checkTimingName + "Target not in selection list Error!!!"; ThrowErrorMessage(message4); } } } } private bool CheckSelectTypeSkillTargetCount(BattleCardBase actor, IEnumerable skills, List targetList, int selectCardCount, string checkTimingName) { string text = checkTimingName + actor.BaseParameter.CardName + "\n"; int num = selectCardCount; foreach (SkillBase skill in skills) { if (skill.IsBurialRite) { selectCardCount++; num++; text += "BurialRite1回"; if (skill is Skill_none) { continue; } } if (!(skill.ApplySelectFilter is SkillRandomSelectFilter) && !(skill.ApplySelectFilter is SkillSelectAllFilter) && (!skill.IsBurialRite || skill.ApplySelectFilter is SkillUserSelectFilter) && (skill.IsChoiceType || !(skill.ApplySelectFilter is SkillSelectNullFilter))) { BattlePlayerReadOnlyInfoPair playerInfoPair = new BattlePlayerReadOnlyInfoPair(actor.SelfBattlePlayer, actor.OpponentBattlePlayer); SkillConditionCheckerOption option = new SkillConditionCheckerOption(); if (skill.CheckCondition(playerInfoPair, option, isPrePlay: true)) { int skillSelectCount = skill.GetSkillSelectCount(); selectCardCount += skillSelectCount; num += ((!actor.IsUnit && !actor.IsField) ? 1 : 0); text += $"{skill}{skillSelectCount}回"; } } } if (selectCardCount <= 0) { return false; } bool flag = false; if (targetList == null || targetList.Count <= 0) { if (num <= 0) { return false; } text += "\n選択されていません"; flag = true; } else { int count = targetList.Count; int num2 = count - selectCardCount; if (num2 < 0 && count < num) { text += "\n少なく選択されています"; flag = true; } if (num2 > 0) { text += $"\n{num2}回多く選択されています"; flag = true; } } if (flag) { ThrowErrorMessage(text); } return flag; } public int CalcFixedUseCostTransformId(BattleCardBase actor, int currentPp) { int num = -1; int cost = actor.Cost; int result = -1; for (int i = 0; i < actor.Skills.Count(); i++) { if (!(actor.Skills.ElementAt(i) is Skill_pp_fixeduse skill_pp_fixeduse) || currentPp < skill_pp_fixeduse._fixedUsePP) { continue; } bool num2 = skill_pp_fixeduse.CheckCondition(_ai.PlayerPair, new SkillConditionCheckerOption(), isPrePlay: true); bool flag = num2 && num < skill_pp_fixeduse._fixedUsePP; bool flag2 = num2 && skill_pp_fixeduse._fixedUsePP < cost && currentPp < cost; if (flag || flag2) { if (actor.Skills.ElementAt(i + 1) is Skill_transform skill_transform) { result = skill_transform.TransformId; } num = skill_pp_fixeduse._fixedUsePP; } } return result; } private void ThrowErrorMessage(string message) { AIConsoleUtility.LogError(message); } }