using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using Wizard.Battle; namespace Wizard; internal static class EnemyAIUtil { private class SelectableInfo { public List Cards; public int Count; public SelectableInfo(List cards, int count) { Cards = cards; Count = count; } } public const int TempDeckNo = 36; public const int SERIES_ID = 25; private const int RETRY_MAX = 100; private const int LOOP_MAX = 10; private static System.Random _rnd = new System.Random(); public static bool IsSameVirtualCardList(List right, List left) { if (right.Count != left.Count) { return false; } for (int i = 0; i < right.Count; i++) { if (!right[i].IsSameCard(left[i])) { return false; } } return true; } public static List GetAllMoves(BattlePlayerPair pair) { List list = new List(); List playMoves = GetPlayMoves(pair); List attackMoves = GetAttackMoves(pair); List evolveMoves = GetEvolveMoves(pair); List fusionMoves = GetFusionMoves(pair); for (int i = 0; i < playMoves.Count; i++) { list.Add(playMoves[i]); } for (int j = 0; j < attackMoves.Count; j++) { list.Add(attackMoves[j]); } for (int k = 0; k < evolveMoves.Count; k++) { list.Add(evolveMoves[k]); } for (int l = 0; l < fusionMoves.Count; l++) { list.Add(fusionMoves[l]); } list.Add(new AITurnEndMove()); return list; } public static List GetFusionMoves(BattlePlayerPair pair) { List list = new List(); foreach (BattleCardBase handCard in pair.Self.HandCardList) { if (!handCard.IsFusionable) { continue; } List> targetsList = GetTargetsList(handCard.GetSelectTypeSkill(isEvolve: false, isFusion: true), pair, handCard, isFusion: true); if (targetsList != null) { for (int i = 0; i < targetsList.Count; i++) { List targets = targetsList[i]; list.Add(new AIFusionMove(handCard, targets)); } } } return list; } public static List GetEvolveMoves(BattlePlayerPair pair) { List list = new List(); foreach (BattleCardBase inPlayCard in pair.Self.InPlayCards) { if (!inPlayCard.IsUnit || !inPlayCard.CanEvolution(isSkill: false, isSelfBattlePlayer: true)) { continue; } List> targetsList = GetTargetsList(inPlayCard.EvolutionSkills, pair, inPlayCard); if (targetsList != null) { for (int i = 0; i < targetsList.Count; i++) { List targets = targetsList[i]; list.Add(new AIEvolMove(inPlayCard, targets)); } } else { list.Add(new AIEvolMove(inPlayCard, null)); } } return list; } public static List GetAttackMoves(BattlePlayerPair pair) { List list = new List(); foreach (BattleCardBase inPlayCard in pair.Self.InPlayCards) { if (!inPlayCard.Attackable) { continue; } foreach (BattleCardBase classAndInPlayCard in pair.Opponent.ClassAndInPlayCardList) { if (AttackSelectControl.CanCardAttackTarget(inPlayCard, classAndInPlayCard, pair.Opponent.InPlayCards)) { list.Add(new AIAttackMove(inPlayCard, classAndInPlayCard)); } } } return list; } public static List GetPlayMoves(BattlePlayerPair pair, bool isCheckOnDraw = true) { List list = new List(); foreach (BattleCardBase handCard in pair.Self.HandCardList) { if (!handCard.Movable(isCheckOnDraw)) { continue; } IEnumerable enumerable = null; if (handCard.IsMutationPlayPp(handCard.SelfBattlePlayer.Pp)) { Skill_transform accelerateOrCrystallizeTransformSkill = handCard.GetAccelerateOrCrystallizeTransformSkill(); if (accelerateOrCrystallizeTransformSkill != null) { enumerable = handCard.SelfBattlePlayer.BattleMgr.CreateTransformCardRegisterVfx(accelerateOrCrystallizeTransformSkill.SkillPrm.ownerCard, accelerateOrCrystallizeTransformSkill.TransformId, accelerateOrCrystallizeTransformSkill.SkillPrm.ownerCard.IsPlayer).GetSelectTypeSkill(); } } if (enumerable == null) { enumerable = handCard.GetSelectTypeSkill(); } List> targetsList = GetTargetsList(enumerable, pair, handCard); if (targetsList != null) { for (int i = 0; i < targetsList.Count; i++) { List targets = targetsList[i]; list.Add(new AIPlayMove(handCard, targets)); } } else { list.Add(new AIPlayMove(handCard, null)); } } return list; } private static List> GetTargetsList(IEnumerable skills, BattlePlayerPair pair, BattleCardBase card, bool isFusion = false) { List selectablesList = GetSelectablesList(skills, pair, card); Dictionary> dictionary = new Dictionary>(); foreach (SkillBase skill in skills) { if (!skill.IsChoiceType || !card.Skills.HaveChoiceTransformSkill()) { continue; } IEnumerable skillUserSelectableTargets = ActionProcessor.GetSkillUserSelectableTargets(skill, pair); if (skillUserSelectableTargets == null) { continue; } foreach (BattleCardBase item in skillUserSelectableTargets) { dictionary[item.Index] = GetSelectablesList(item.GetSelectTypeSkill(), pair, item); } } if (selectablesList.Count > 0) { List> list = new List>(); SetupTargetsList(0, new List(), selectablesList, dictionary, list, isFusion); return list; } return null; } private static List GetSelectablesList(IEnumerable skills, BattlePlayerPair pair, BattleCardBase card) { List list = new List(); foreach (SkillBase skill in skills) { if (skill.IsBurialRite) { List burialRiteTarget = SkillPreprocessBurialRite.GetBurialRiteTarget(card.SelfBattlePlayer, card); if (burialRiteTarget != null && burialRiteTarget.Count > 0) { list.Add(new SelectableInfo(burialRiteTarget, 1)); } } if (skill.IsUserSelectType) { IEnumerable skillUserSelectableTargets = ActionProcessor.GetSkillUserSelectableTargets(skill, pair); int num = 1; if (skillUserSelectableTargets != null) { num = Mathf.Min(skill.GetSkillSelectCount(), skillUserSelectableTargets.Count()); list.Add(new SelectableInfo(new List(skillUserSelectableTargets), num)); } } if (!skill.IsChoiceType) { continue; } IEnumerable skillUserSelectableTargets2 = ActionProcessor.GetSkillUserSelectableTargets(skill, pair); if (skillUserSelectableTargets2 == null) { continue; } List list2 = new List(); foreach (BattleCardBase item in skillUserSelectableTargets2) { card = card.SelfBattlePlayer.BattleMgr.CreateTransformCardRegisterVfx(card, item.CardId, card.SelfBattlePlayer.IsPlayer); list2.Add(card); } int count = 1; if (skill.ApplySelectFilter is SkillChoiceSelectFilter) { count = Math.Max(1, skill.ApplySelectFilter.CalcCount(skill.OptionValue)); } list.Add(new SelectableInfo(list2, count)); } return list; } private static void SetupTargetsList(int depth, List currentList, List selectablesList, Dictionary> choiceSelectableList, List> out_targetsList, bool isFusion = false) { if (depth == selectablesList.Count) { out_targetsList.Add(new List(currentList)); return; } SelectableInfo selectableInfo = selectablesList[depth]; if (isFusion) { int num = (1 << selectableInfo.Cards.Count) - 1; for (int i = 1; i <= num; i++) { int num2 = i; int num3 = 0; for (int j = 0; j < selectableInfo.Cards.Count; j++) { BattleCardBase item = selectableInfo.Cards[j]; if (((num2 >> j) & 1) > 0) { currentList.Add(item); num3++; } } SetupTargetsList(depth + 1, currentList, selectablesList, choiceSelectableList, out_targetsList, isFusion: true); for (int k = 0; k < num3; k++) { currentList.RemoveAt(currentList.Count - 1); } } return; } List list = new List(); for (int l = 0; l < selectableInfo.Cards.Count; l++) { list.Add(l); } foreach (int[] item2 in AIMathematicsLibrary.EnumerateCombinations(list, selectableInfo.Count)) { BattleCardBase firstCard = selectableInfo.Cards[item2[0]]; bool flag = true; for (int m = 0; m < item2.Length; m++) { BattleCardBase card = selectableInfo.Cards[item2[m]]; if (currentList.Any((BattleCardBase c) => c.Index == card.Index && c.IsPlayer == card.IsPlayer)) { flag = false; } currentList.Add(card); } if (flag) { if (choiceSelectableList != null && choiceSelectableList.Any((KeyValuePair> p) => p.Key == firstCard.Index)) { if (choiceSelectableList[firstCard.Index] != null) { SetupTargetsList(0, currentList, choiceSelectableList[firstCard.Index], null, out_targetsList); } } else { SetupTargetsList(depth + 1, currentList, selectablesList, choiceSelectableList, out_targetsList); } } for (int num4 = 0; num4 < item2.Length; num4++) { currentList.RemoveAt(currentList.Count - 1); } } } public static void TurnEnd(BattleManagerBase mgr, bool isPlayer) { if (isPlayer) { mgr.VfxMgr.RegisterSequentialVfx(mgr.OperateMgr.PlayerTurnEnd()); } else { mgr.VfxMgr.RegisterSequentialVfx(mgr.OperateMgr.TurnEndOperation(isPlayer)); } } public static void SetupPlayCardSkillOptionValue(BattleCardBase playCard, BattlePlayerPair pair) { IEnumerable selectTypeSkill = playCard.GetSelectTypeSkill(); if (selectTypeSkill == null) { return; } foreach (SkillBase item in selectTypeSkill) { SkillCollectionBase.SetupOptionValue(item.OptionValue, pair, playCard, item); } } public static List GetRandomDeck(CardBasePrm.ClanType clan, int seriesRangeStart = 0, int seriesRangeEnd = 25) { int num = 0; int num2 = 0; int num3 = 40; List deck = new List(); IEnumerable allParameters = CardMaster.GetInstanceForBattle().GetAllParameters(); while (true) { for (int i = 0; i < num3; i++) { CardBasePrm.ClanType card_clan = clan; if (num2 < 10) { if (_rnd.Next(9) == 0) { card_clan = CardBasePrm.ClanType.ALL; } } else if (_rnd.Next(9) != 0) { card_clan = CardBasePrm.ClanType.ALL; } IEnumerable source = allParameters.Where((CardParameter p) => p.Clan == card_clan && seriesRangeStart <= p.BaseCardId / 1000000 % 100 && p.BaseCardId / 1000000 % 100 <= seriesRangeEnd && p.BaseCardId / 100000000 % 10 == 1 && deck.Count((int id) => id == p.BaseCardId) < 3 && !GameMgr.GetIns().GetDataMgr().IsMaintenanceCard(p.CardId) && !GameMgr.GetIns().GetDataMgr().IsMaintenanceCard(p.BaseCardId)); if (source.Count() == 0) { num++; if (num >= 100) { break; } i--; } else { CardParameter cardParameter = source.ElementAt(_rnd.Next(source.Count())); deck.Add(cardParameter.BaseCardId); } } if (deck.Count == 40) { break; } if (num2 >= 100) { throw new Exception($"デッキ構築するための使用可能な{clan}カードが不足している可能性があります。カード未実装フラグを解除するか、実装が進んでから再度お試しください。"); } num2++; num3 = 40 - deck.Count; } return deck; } }