Browse Source

adding scripts folder

Michael8818 6 months ago
parent
commit
41941826b0
100 changed files with 12218 additions and 1 deletions
  1. 1 1
      Assets/Script.meta
  2. 604 0
      Assets/Script/AttackProcess.cs
  3. 11 0
      Assets/Script/AttackProcess.cs.meta
  4. 1092 0
      Assets/Script/AutoProcessing.cs
  5. 11 0
      Assets/Script/AutoProcessing.cs.meta
  6. 8 0
      Assets/Script/AutomaticOrder.meta
  7. 40 0
      Assets/Script/AutomaticOrder/StartTurnTamerMemory.cs
  8. 11 0
      Assets/Script/AutomaticOrder/StartTurnTamerMemory.cs.meta
  9. 78 0
      Assets/Script/BGMObject.cs
  10. 11 0
      Assets/Script/BGMObject.cs.meta
  11. 46 0
      Assets/Script/BattleMode.cs
  12. 11 0
      Assets/Script/BattleMode.cs.meta
  13. 180 0
      Assets/Script/BendText.cs
  14. 11 0
      Assets/Script/BendText.cs.meta
  15. 130 0
      Assets/Script/BrainStormObject.cs
  16. 11 0
      Assets/Script/BrainStormObject.cs.meta
  17. 64 0
      Assets/Script/BreakGlass.cs
  18. 11 0
      Assets/Script/BreakGlass.cs.meta
  19. 66 0
      Assets/Script/BurstEffectObject.cs
  20. 11 0
      Assets/Script/BurstEffectObject.cs.meta
  21. 399 0
      Assets/Script/CEntity_Base.cs
  22. 11 0
      Assets/Script/CEntity_Base.cs.meta
  23. 30 0
      Assets/Script/CEntity_Effect.cs
  24. 11 0
      Assets/Script/CEntity_Effect.cs.meta
  25. 281 0
      Assets/Script/CEntity_EffectController.cs
  26. 11 0
      Assets/Script/CEntity_EffectController.cs.meta
  27. 44 0
      Assets/Script/CPlayerElement.cs
  28. 11 0
      Assets/Script/CPlayerElement.cs.meta
  29. 38 0
      Assets/Script/CRoomElement.cs
  30. 11 0
      Assets/Script/CRoomElement.cs.meta
  31. 5533 0
      Assets/Script/CardController.cs
  32. 11 0
      Assets/Script/CardController.cs.meta
  33. 55 0
      Assets/Script/CardDetail.cs
  34. 11 0
      Assets/Script/CardDetail.cs.meta
  35. 63 0
      Assets/Script/CardDistribution.cs
  36. 11 0
      Assets/Script/CardDistribution.cs.meta
  37. 36 0
      Assets/Script/CardDistributionTab.cs
  38. 11 0
      Assets/Script/CardDistributionTab.cs.meta
  39. 1326 0
      Assets/Script/CardEffectCommons.cs
  40. 11 0
      Assets/Script/CardEffectCommons.cs.meta
  41. 8 0
      Assets/Script/CardEffectCommons.meta
  42. 8 0
      Assets/Script/CardEffectCommons/CanUseEffects.meta
  43. 41 0
      Assets/Script/CardEffectCommons/CanUseEffects/CanSuspend.cs
  44. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/CanSuspend.cs.meta
  45. 15 0
      Assets/Script/CardEffectCommons/CanUseEffects/CanUnsuspend.cs
  46. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/CanUnsuspend.cs.meta
  47. 15 0
      Assets/Script/CardEffectCommons/CanUseEffects/IgnoreBattle.cs
  48. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/IgnoreBattle.cs.meta
  49. 47 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnAddDigivolutionCards.cs
  50. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnAddDigivolutionCards.cs.meta
  51. 47 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnAttack.cs
  52. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnAttack.cs.meta
  53. 22 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnAttackTargetSwitch.cs
  54. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnAttackTargetSwitch.cs.meta
  55. 33 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnCardsAddedToHand.cs
  56. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnCardsAddedToHand.cs.meta
  57. 38 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToHandFromTrash.cs
  58. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToHandFromTrash.cs.meta
  59. 38 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToLibraryFromTrash.cs
  60. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToLibraryFromTrash.cs.meta
  61. 365 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnDeletion.cs
  62. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnDeletion.cs.meta
  63. 15 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnEndAttack.cs
  64. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnEndAttack.cs.meta
  65. 31 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnFaceUpSecurityIncrease.cs
  66. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnFaceUpSecurityIncrease.cs.meta
  67. 35 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnMove.cs
  68. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnMove.cs.meta
  69. 39 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnReturnLibraryBottomDigivolutionCards.cs
  70. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnReturnLibraryBottomDigivolutionCards.cs.meta
  71. 41 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnSuspend.cs
  72. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnSuspend.cs.meta
  73. 41 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashBySelfDigiBurst.cs
  74. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashBySelfDigiBurst.cs.meta
  75. 69 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashDigivolutionCard.cs
  76. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashDigivolutionCard.cs.meta
  77. 40 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashHand.cs
  78. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashHand.cs.meta
  79. 69 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkCard.cs
  80. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkCard.cs.meta
  81. 69 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkedCard.cs
  82. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkedCard.cs.meta
  83. 22 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnUnsuspend.cs
  84. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OnUnsuspend.cs.meta
  85. 40 0
      Assets/Script/CardEffectCommons/CanUseEffects/OptionEffect.cs
  86. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/OptionEffect.cs.meta
  87. 8 0
      Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField.meta
  88. 26 0
      Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/OnPlay.cs
  89. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/OnPlay.cs.meta
  90. 58 0
      Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/PermanentEnterField.cs
  91. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/PermanentEnterField.cs.meta
  92. 27 0
      Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/WhenDigivolving.cs
  93. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/WhenDigivolving.cs.meta
  94. 15 0
      Assets/Script/CardEffectCommons/CanUseEffects/SecurityEffect.cs
  95. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/SecurityEffect.cs.meta
  96. 30 0
      Assets/Script/CardEffectCommons/CanUseEffects/WhenAddHand.cs
  97. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/WhenAddHand.cs.meta
  98. 128 0
      Assets/Script/CardEffectCommons/CanUseEffects/WhenDeleteOpponentDigimon.cs
  99. 11 0
      Assets/Script/CardEffectCommons/CanUseEffects/WhenDeleteOpponentDigimon.cs.meta
  100. 107 0
      Assets/Script/CardEffectCommons/CanUseEffects/WhenDeleteOpponentDigimonByBattle.cs

+ 1 - 1
Assets/Scripts.meta → Assets/Script.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
 fileFormatVersion: 2
-guid: 02a3527b6b33a924e8ec66aa805ea717
+guid: a901b4c330b4533458b8ec1c15fb7cdd
 folderAsset: yes
 folderAsset: yes
 DefaultImporter:
 DefaultImporter:
   externalObjects: {}
   externalObjects: {}

+ 604 - 0
Assets/Script/AttackProcess.cs

@@ -0,0 +1,604 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using Photon.Pun;
+using System;
+using System.Linq;
+using UnityEngine.UI;
+
+public class AttackProcess : MonoBehaviourPunCallbacks
+{
+    public Permanent AttackingPermanent { get; private set; } = null;
+    public Permanent DefendingPermanent { get; private set; } = null;
+    public int AttackCount { get; set; } = 0;
+    public bool IsAttacking { get; set; } = false;
+    public bool HasDefender { get; set; } = false;
+    public bool IsBlocking { get; set; } = false;
+    public CardSource SecurityDigimon { get; set; } = null;
+    public bool DoSecurityCheck { get; set; } = false;
+    public bool IsEndAttack { get; set; } = false;
+
+    public bool UsedBlitz { get; set; } = false;
+
+    void SetAttackerDefender(Permanent attackingPermanent, Permanent defendingPermanent)
+    {
+        AttackingPermanent = attackingPermanent;
+        DefendingPermanent = defendingPermanent;
+
+        if (defendingPermanent != null)
+            HasDefender = true;
+    }
+
+    public IEnumerator Attack(Permanent attackingPermanent, Permanent defendingPermanent, ICardEffect attackEffect, bool withoutTap = false, Func<IEnumerator> beforeOnAttackCoroutine = null)
+    {
+        if (IsAttacking)
+        {
+            if (beforeOnAttackCoroutine != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(beforeOnAttackCoroutine());
+            }
+
+            yield break;
+        }
+
+        AttackingPermanent = null;
+        DefendingPermanent = null;
+
+        DoSecurityCheck = false;
+        IsBlocking = false;
+        SecurityDigimon = null;
+        IsAttacking = false;
+        HasDefender = false;
+        IsEndAttack = false;
+
+        SetAttackerDefender(attackingPermanent, defendingPermanent);
+
+        Hashtable effectHashtable = CardEffectCommons.OnAttackCheckHashtableOfPermanent(AttackingPermanent, attackEffect);
+        Hashtable counterEffectHashtable = CardEffectCommons.OnAttackCheckHashtableOfPermanent(new Permanent(AttackingPermanent.cardSources), attackEffect);
+
+        IsAttacking = true;
+
+        // check timing
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+        GManager.instance.turnStateMachine.IsSelecting = true;
+
+        // force to end attack
+        if (IsEndAttack)
+        {
+            goto EndAttack;
+        }
+
+        #region Attack Process
+        if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(AttackingPermanent))
+        {
+            AttackCount++;
+
+            GManager.instance.turnStateMachine.IsSelecting = true;
+
+            if (DefendingPermanent != null)
+            {
+                if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
+                {
+                    DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                    DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+                    GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.securityObject.securityBreakGlass.gameObject.SetActive(false);
+                }
+            }
+
+            else
+            {
+                if (GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.SecurityCards.Count >= 1)
+                {
+                    GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.securityObject.securityBreakGlass.ShowBlueMatarial();
+                }
+            }
+
+            AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
+            AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+
+            // add log
+            string log = $"\nAttack:\n{AttackingPermanent.TopCard.BaseENGCardNameFromEntity}({AttackingPermanent.TopCard.CardID})";
+
+            if (DefendingPermanent != null)
+            {
+                if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
+                    log += $"\n�«\n{DefendingPermanent.TopCard.BaseENGCardNameFromEntity}({DefendingPermanent.TopCard.CardID})\n";
+            }
+
+            else
+            {
+                log += $"\n�«\nSecurity\n";
+            }
+
+            PlayLog.OnAddLog?.Invoke(log);
+
+            List<SkillInfo> stackedSkillInfos = new List<SkillInfo>();
+
+            if (GManager.instance.autoProcessing.executingMultipleSkills != null)
+            {
+                if (GManager.instance.autoProcessing.executingMultipleSkills.StackedSkillInfos.Count >= 1)
+                {
+                    foreach (SkillInfo skillInfo in GManager.instance.autoProcessing.executingMultipleSkills.StackedSkillInfos)
+                    {
+                        stackedSkillInfos.Add(skillInfo);
+                    }
+                }
+
+                foreach (SkillInfo skillInfo in stackedSkillInfos)
+                {
+                    GManager.instance.autoProcessing.executingMultipleSkills.StackedSkillInfos.Remove(skillInfo);
+                }
+            }
+
+            // suspend
+            if (!withoutTap)
+            {
+                Hashtable attackerTapHashtable = new Hashtable()
+                {
+                    {"IsAttack", true}
+                };
+                yield return ContinuousController.instance.StartCoroutine(new SuspendPermanentsClass(
+                    new List<Permanent>() { AttackingPermanent },
+                    attackerTapHashtable).Tap());
+            }
+
+            // target arrow
+            if (DefendingPermanent == null)
+            {
+                yield return GManager.instance.OnTargetArrow(
+                        AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
+                        GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.SecurityAttackLocalCanvasPosition + GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.playerUIObjectParent.localPosition,
+                        null,
+                        null);
+            }
+            else
+            {
+                if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
+                {
+                    yield return GManager.instance.OnTargetArrow(
+                        AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
+                        DefendingPermanent.PermanentFrame.GetLocalCanvasPosition() + DefendingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
+                        null,
+                        null);
+                }
+            }
+
+            // activate cutin effects
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
+            //yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, null));
+
+            // callback that is processed before [On Attack]
+            if (beforeOnAttackCoroutine != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(beforeOnAttackCoroutine());
+            }
+
+            // trigger [On Attack] effect
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+                effectHashtable,
+                EffectTiming.OnAllyAttack));
+
+            // activate cutin effects
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, null));
+
+            if (stackedSkillInfos.Count >= 1)
+            {
+                foreach (SkillInfo skillInfo in stackedSkillInfos)
+                {
+                    GManager.instance.autoProcessing.PutStackedSkill(skillInfo);
+                }
+            }
+
+            GManager.instance.turnStateMachine.IsSelecting = true;
+
+            if (AttackingPermanent.TopCard != null)
+            {
+                AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+            }
+
+            if (DefendingPermanent != null)
+            {
+                if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
+                {
+                    DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                    DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+                }
+            }
+
+            // check timing
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+            GManager.instance.turnStateMachine.IsSelecting = true;
+
+            // force to end attack
+            if (IsEndAttack)
+            {
+                goto EndAttack;
+            }
+
+            if (AttackingPermanent.TopCard != null)
+            {
+                AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+            }
+
+            if (DefendingPermanent != null)
+            {
+                if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
+                {
+                    DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                    DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+                }
+            }
+
+            // trigger effects when counter timing (except [Counter] effects)
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+                counterEffectHashtable,
+                EffectTiming.OnCounterTiming,
+                cardEffect => !cardEffect.IsCounterEffect));
+
+            // activate cutin effects
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, null));
+
+            GManager.instance.turnStateMachine.IsSelecting = true;
+
+            // force to end attack
+            if (IsEndAttack)
+            {
+                goto EndAttack;
+            }
+
+            // trigger effects when counter timing ([Counter] effects)
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+                counterEffectHashtable,
+                EffectTiming.OnCounterTiming,
+                cardEffect => cardEffect.IsCounterEffect));
+
+            bool HasCounterEffect(List<SkillInfo> skillInfos, SkillInfo skillInfo)
+            {
+                return skillInfos.Count((skillInfo1) => skillInfo1.CardEffect.IsCounterEffect) >= 1;
+            }
+
+            // activate cutin effects
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, HasCounterEffect));
+
+            GManager.instance.turnStateMachine.IsSelecting = true;
+
+            // force to end attack
+            if (IsEndAttack)
+            {
+                goto EndAttack;
+            }
+
+            if (AttackingPermanent.TopCard == null || !AttackingPermanent.IsDigimon)
+            {
+                goto EndAttack;
+            }
+
+            AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
+            AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+
+            if (DefendingPermanent != null)
+            {
+                if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
+                {
+                    DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                    DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+                }
+            }
+
+            #region select blocker
+            bool CanSelectBlockerCondition(Permanent permanent)
+            {
+                if (CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, AttackingPermanent.TopCard))
+                {
+                    if (permanent != DefendingPermanent)
+                    {
+                        if (permanent.HasBlocker && permanent.CanBlock(AttackingPermanent))
+                        {
+                            return true;
+                        }
+                    }
+                }
+
+                return false;
+            }
+
+            if (AttackingPermanent.TopCard.Owner.Enemy.GetBattleAreaDigimons().Count(CanSelectBlockerCondition) >= 1)
+            {
+                int maxCount = 1;
+
+                Permanent selectedPermanent = null;
+
+                SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                selectPermanentEffect.SetUp(
+                    selectPlayer: AttackingPermanent.TopCard.Owner.Enemy,
+                    canTargetCondition: CanSelectBlockerCondition,
+                    canTargetCondition_ByPreSelecetedList: null,
+                    canEndSelectCondition: null,
+                    maxCount: maxCount,
+                    canNoSelect: (!IsBlocking),
+                    canEndNotMax: false,
+                    selectPermanentCoroutine: SelectPermanentCoroutine,
+                    afterSelectPermanentCoroutine: null,
+                    mode: SelectPermanentEffect.Mode.Custom,
+                    cardEffect: null);
+
+                selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will block.", "The opponent is selecting 1 Digimon that will block.");
+                
+                if(!IsBlocking)
+                    selectPermanentEffect.SetUpCustomBackButtonMessage("Not Block");
+
+                yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                {
+                    selectedPermanent = permanent;
+
+                    yield return null;
+                }
+
+                if (selectedPermanent != null)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(SwitchDefender(null, true, selectedPermanent));
+                }
+            }
+            #endregion
+
+            GManager.instance.turnStateMachine.IsSelecting = true;
+
+            //end attack
+            if (IsEndAttack)
+            {
+                goto EndAttack;
+            }
+
+            if (AttackingPermanent.TopCard == null)
+            {
+                goto EndAttack;
+            }
+
+            AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
+            AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+
+            if (DefendingPermanent != null)
+            {
+                if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
+                {
+                    DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                    DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+                }
+            }
+
+            #region there is no Defending Permanent
+            if (DefendingPermanent == null)
+            {
+                if (AttackingPermanent.Strike >= 1)
+                {
+                    //if there is no security, end the game
+                    if (AttackingPermanent.TopCard.Owner.Enemy.SecurityCards.Count == 0)
+                    {
+                        GManager.instance.turnStateMachine.EndGame(AttackingPermanent.TopCard.Owner, false);
+                        yield break;
+                    }
+                }
+
+                DoSecurityCheck = true;
+            }
+            #endregion
+
+            #region there is Defending Permanent
+            else
+            {
+                if (!CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent) || !CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(AttackingPermanent))
+                {
+                    goto EndAttack;
+                }
+
+                DefendingPermanent.TopCard.Owner.securityObject.securityBreakGlass.gameObject.SetActive(false);
+
+                DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+
+                // battle
+                IBattle battle = new IBattle(AttackingPermanent: AttackingPermanent, DefendingPermanent: DefendingPermanent, null);
+                yield return ContinuousController.instance.StartCoroutine(battle.Battle());
+
+                /*#region effect when determine whether to do security check
+                Hashtable hashtable = new Hashtable()
+                {
+                    {"battle", battle}
+                };
+
+                List<SkillInfo> skillInfos_Pierce = AutoProcessing.GetSkillInfos(hashtable, EffectTiming.OnDetermineDoSecurityCheck)
+                    .Filter(skillInfo => skillInfo.CardEffect != null && skillInfo.CardEffect.CanActivate(skillInfo.Hashtable));
+
+                if (skillInfos_Pierce.Count >= 1)
+                {
+                    GManager.instance.autoProcessing.PutStackedSkill(skillInfos_Pierce[0]);
+                }
+                #endregion*/
+                
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.TriggeredSkillProcess(true, null));
+                GManager.instance.turnStateMachine.IsSelecting = true;
+            }
+            #endregion
+
+            if (AttackingPermanent.TopCard == null)
+            {
+                goto EndAttack;
+            }
+
+            #region do security check
+            if (DoSecurityCheck && AttackingPermanent.TopCard.Owner.Enemy.SecurityCards.Count >= 1)
+            {
+                //security check process
+                yield return ContinuousController.instance.StartCoroutine(new ISecurityCheck(
+                    AttackingPermanent: AttackingPermanent,
+                    player: GManager.instance.turnStateMachine.gameContext.NonTurnPlayer).SecurityCheck());
+            }
+            #endregion
+        }
+
+        else
+        {
+            if (beforeOnAttackCoroutine != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(beforeOnAttackCoroutine());
+            }
+        }
+    #endregion
+
+    #region End Attack
+    EndAttack:;
+
+        // [On End Attack] effect
+        if (AttackingPermanent != null && AttackingPermanent.TopCard != null)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(effectHashtable, EffectTiming.OnEndAttack));
+        }
+        
+        // activate cutin effects
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+        #region reset effects which continues until the end of attack
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (Permanent permanent in player.GetFieldPermanents())
+            {
+                permanent.UntilEndAttackEffects = new List<Func<EffectTiming, ICardEffect>>();
+            }
+        }
+        #endregion
+
+        GManager.instance.turnStateMachine.IsSelecting = true;
+        #endregion
+
+        DoSecurityCheck = false;
+        IsBlocking = false;
+        SecurityDigimon = null;
+        IsAttacking = false;
+        IsEndAttack = false;
+    }
+
+    public IEnumerator SwitchDefender(ICardEffect cardEffect, bool isBlock, Permanent newDefendingPermanent)
+    {
+        if (AttackingPermanent == null) yield break;
+        if (AttackingPermanent.TopCard == null) yield break;
+        if (newDefendingPermanent != null && newDefendingPermanent.TopCard == null) yield break;
+        if (!AttackingPermanent.CanSwitchAttackTarget) yield break;
+
+        Permanent oldDefendingPermanent = DefendingPermanent;
+
+        DefendingPermanent = newDefendingPermanent;
+
+        IsBlocking = isBlock;
+
+        if (DefendingPermanent != null)
+        {
+            if (DefendingPermanent.ShowingPermanentCard != null)
+            {
+                DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+            }
+        }
+
+        Hashtable hashtable = new Hashtable(){
+                {"AttackingPermanent", AttackingPermanent},
+                {"DefendingPermanent", DefendingPermanent},
+                {"CardEffect", cardEffect}
+                };
+
+        if (isBlock)
+        {
+            hashtable.Add("IsBlock", isBlock);
+        }
+
+        if (isBlock)
+        {
+            if (DefendingPermanent != null)
+            {
+                // add log
+                string log1 = $"\nBlock:\n{DefendingPermanent.TopCard.BaseENGCardNameFromEntity}({DefendingPermanent.TopCard.CardID})\n";
+
+                PlayLog.OnAddLog?.Invoke(log1);
+
+                // suspend
+                yield return ContinuousController.instance.StartCoroutine(new SuspendPermanentsClass(new List<Permanent>() { DefendingPermanent }, hashtable).Tap());
+
+                // the effects when blocking
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(
+                    hashtable,
+                    EffectTiming.OnBlockAnyone));
+            }
+        }
+
+        if (AttackingPermanent != null)
+        {
+            if (AttackingPermanent.TopCard == null)
+            {
+                IsBlocking = false;
+                yield break;
+            }
+        }
+
+        if (DefendingPermanent != null)
+        {
+            if (DefendingPermanent.TopCard == null)
+            {
+                IsBlocking = false;
+                yield break;
+            }
+        }
+
+        if (AttackingPermanent != null)
+        {
+            // target arrow
+            for (int i = 0; i < 3; i++)
+            {
+                GManager.instance.OffTargetArrow();
+
+                yield return null;
+            }
+
+            if (DefendingPermanent != null)
+            {
+                DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
+                DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+
+                yield return GManager.instance.OnTargetArrow(
+                    AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
+                    DefendingPermanent.PermanentFrame.GetLocalCanvasPosition() + DefendingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
+                    null,
+                    null);
+            }
+
+            else
+            {
+                yield return GManager.instance.OnTargetArrow(
+                                    AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
+                                    GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.SecurityAttackLocalCanvasPosition + GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.playerUIObjectParent.localPosition,
+                                    null,
+                                    null);
+            }
+
+            AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
+            AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
+        }
+
+        if (newDefendingPermanent != oldDefendingPermanent)
+        {
+            // the effects when attack target switched
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(
+                hashtable,
+                EffectTiming.OnAttackTargetChanged));
+        }
+    }
+}
+

+ 11 - 0
Assets/Script/AttackProcess.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 29212f37b1d13894dab954e34d411d23
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1092 - 0
Assets/Script/AutoProcessing.cs

@@ -0,0 +1,1092 @@
+using Photon.Pun;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+
+public class AutoProcessing : MonoBehaviourPunCallbacks
+{
+    //Skill list before triggering and entering resolution timing
+    public List<SkillInfo> StackedSkillInfos { get; set; } = new List<SkillInfo>();
+    //Skill Processing Component List
+    public List<MultipleSkills> multipleSkills = new List<MultipleSkills>();
+
+    [SerializeField] bool SkipSameEffect;
+
+    public List<SkillInfo> skipSkillInfos = new List<SkillInfo>();
+
+    #region Available Skill Processing Component
+    public MultipleSkills availableMultipleSkills
+    {
+        get
+        {
+            foreach (MultipleSkills _multipleSkills in multipleSkills)
+            {
+                if (!_multipleSkills.IsUsing)
+                {
+                    return _multipleSkills;
+                }
+            }
+
+            return null;
+        }
+    }
+    #endregion
+
+    #region Stack during effect processing
+    public MultipleSkills executingMultipleSkills
+    {
+        get
+        {
+            for (int i = 0; i < multipleSkills.Count; i++)
+            {
+                if (multipleSkills[multipleSkills.Count - 1 - i].IsUsing)
+                {
+                    return multipleSkills[multipleSkills.Count - 1 - i];
+                }
+            }
+
+            return null;
+        }
+    }
+    #endregion
+
+    #region put the effect on the stack
+    public void PutStackedSkill(SkillInfo skillInfo)
+    {
+        if (skillInfo == null) return;
+        if (skillInfo.CardEffect == null) return;
+        if (skillInfo.CardEffect.EffectSourceCard == null) return;
+        if (!(skillInfo.CardEffect is ActivateICardEffect)) return;
+
+        CardSource card = skillInfo.CardEffect.EffectSourceCard;
+        Permanent permanent = card.PermanentOfThisCard();
+
+        #region set the flag whether it is Digimon's effect
+        if (permanent != null)
+        {
+            if (permanent.IsDigimon)
+            {
+                skillInfo.CardEffect.SetIsDigimonEffect(true);
+            }
+        }
+
+        if (card == GManager.instance.attackProcess.SecurityDigimon)
+        {
+            skillInfo.CardEffect.SetIsDigimonEffect(true);
+        }
+        #endregion
+
+        #region set the flag whether it is Tamer's effect
+        if (permanent != null)
+        {
+            if (permanent.IsTamer)
+            {
+                skillInfo.CardEffect.SetIsTamerEffect(true);
+            }
+        }
+
+        else if (card.IsTamer)
+        {
+            skillInfo.CardEffect.SetIsTamerEffect(true);
+        }
+        #endregion
+
+        #region set permanent and topCard when triggered
+        ((ActivateICardEffect)skillInfo.CardEffect).PermanentWhenTriggered = permanent;
+
+        if (permanent != null)
+        {
+            ((ActivateICardEffect)skillInfo.CardEffect).TopCardWhenTriggered = permanent.TopCard;
+        }
+        #endregion
+
+        StackedSkillInfos.Add(skillInfo);
+    }
+    #endregion
+
+    #region Automated processing checks
+    public IEnumerator AutoProcessCheck()
+    {
+        if (!GManager.instance.turnStateMachine.DoneStartGame) yield break;
+
+        yield return ContinuousController.instance.StartCoroutine(ShrinkSecurityDigimonDisplay());
+
+        GManager.instance.turnStateMachine.IsSelecting = true;
+        GManager.instance.turnStateMachine.isSync = true;
+
+        //Rule processing
+        yield return ContinuousController.instance.StartCoroutine(RuleProcess());
+
+        //Rule Timing
+        yield return ContinuousController.instance.StartCoroutine(StackSkillInfos(null, EffectTiming.RulesTiming));
+
+        //Trigger effect processing
+        yield return ContinuousController.instance.StartCoroutine(TriggeredSkillProcess(false, null));
+
+        GManager.instance.turnStateMachine.IsSelecting = false;
+        GManager.instance.turnStateMachine.isSync = false;
+    }
+    #endregion
+
+    #region Rule processing
+    public bool IsRuleProcessing { get; set; } = false;
+
+    bool IsNotDigimonInBreeding(Permanent permanent)
+    {
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (CardEffectCommons.IsExistOnBreedingArea(permanent.TopCard))
+                {
+                    if (!permanent.IsDigimon)
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    bool IsNotHavingDP(Permanent permanent)
+    {
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanent.DP < 0)
+                {
+                    if (permanent.IsPlaceToTrashDueToNotHavingDP)
+                    {
+                        if (permanent.IsDigimon)
+                        {
+                            return true;
+                        }
+
+                        if (permanent.TopCard.IsOption)
+                        {
+                            if (!permanent.IsPlayedOptionPermanent)
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    bool IsDigimonLackDP(Permanent permanent)
+    {
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanent.DP == 0)
+                {
+                    if (permanent.IsDigimon)
+                    {
+                        if (permanent.CanBeDestroyed())
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    bool IsAttackerNotADigimon()
+    {
+        if (!GManager.instance.attackProcess.IsAttacking)
+            return false;
+
+        if (GManager.instance.attackProcess.AttackingPermanent != null)
+        {
+            if (!GManager.instance.attackProcess.AttackingPermanent.IsDigimon)
+                return true;
+
+            //if (GManager.instance.attackProcess.HasDefender && GManager.instance.attackProcess.DefendingPermanent == null)
+            //    return true;
+        }
+
+        return false;
+    }
+
+    bool IsDigimonLackLinkCondition(Permanent permanent)
+    {
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanent.LinkedCards.Any(source => !source.CanLinkToTargetPermanent(permanent, false, true)))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    bool IsDigimonLackLinkCount(Permanent permanent)
+    {
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanent.LinkedCards.Count > permanent.LinkedMax)
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    bool IsPermanentFaceDown(Permanent permanent)
+    {
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanent.TopCard.IsFlipped)
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public IEnumerator RuleProcess()
+    {
+        while (DoRuleProcess())
+        {
+            IsRuleProcessing = true;
+
+            //敗北処理
+            yield return ContinuousController.instance.StartCoroutine(EndGameProcess());
+
+            if (GManager.instance.turnStateMachine.endGame) yield break;
+
+            //Trash Non Digimon from Breeding
+            yield return ContinuousController.instance.StartCoroutine(TrashNonDigimonPermanentProcess());
+
+            //DPを持たないカードをトラッシュする処理
+            yield return ContinuousController.instance.StartCoroutine(TrashNoDPPermanentProcess());
+
+            //DP不足処理
+            yield return ContinuousController.instance.StartCoroutine(DigimonLackDPProcess());
+
+            //Battle as Tamer
+            yield return ContinuousController.instance.StartCoroutine(BattleWithoutDigimon());
+
+            //Link Lacking condition
+            yield return ContinuousController.instance.StartCoroutine(DigimonLackLinkConditionProcess());
+
+            //Add link count correction
+            yield return ContinuousController.instance.StartCoroutine(DigimonLackLinkMaxCountProcess());
+
+            //Permanent Face Down
+            yield return ContinuousController.instance.StartCoroutine(CardFaceDownProcess());
+
+            IsRuleProcessing = false;
+        }
+    }
+
+    #region Whether rule processing needs to be done
+    bool DoRuleProcess()
+    {
+        if (IsRuleProcessing) return false;
+
+        #region Whether it is necessary to perform game end processing
+        if (GManager.instance.turnStateMachine.gameContext.Players.Count(player => player.IsLose) >= 1)
+        {
+            return true;
+        }
+        #endregion
+
+        #region Is it necessary to discard cards in breeding?
+        if (CardEffectCommons.HasMatchConditionPermanent(IsNotDigimonInBreeding, true))
+        {
+            return true;
+        }
+        #endregion
+        
+        #region Is it necessary to discard cards without DP?
+        if (CardEffectCommons.HasMatchConditionPermanent(IsNotHavingDP))
+        {
+            return true;
+        }
+        #endregion
+
+        #region Is it necessary to deal with Digimon's DP shortage?
+        if (CardEffectCommons.HasMatchConditionPermanent(IsDigimonLackDP))
+        {
+            return true;
+        }
+        #endregion
+
+        #region Is it necessary to deal with Battle Without Digimon?
+        if (IsAttackerNotADigimon())
+        {
+            //return true;
+        }
+        #endregion
+
+        #region Is it necessary to deal with Digimon's Link Cards?
+        if (CardEffectCommons.HasMatchConditionPermanent(IsDigimonLackLinkCondition, true))
+        {
+            return true;
+        }
+        #endregion
+
+        #region Is it necessary to deal with Digimon's Link Count?
+        if (CardEffectCommons.HasMatchConditionPermanent(IsDigimonLackLinkCount, true))
+        {
+            return true;
+        }
+        #endregion
+
+        #region Is it necessary to deal with card being face down?
+        if (CardEffectCommons.HasMatchConditionPermanent(IsPermanentFaceDown, true))
+        {
+            return true;
+        }
+        #endregion
+
+        return false;
+    }
+    #endregion
+
+    #region Each rule processing
+
+    #region Game end processing
+    IEnumerator EndGameProcess()
+    {
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players)
+        {
+            if (player.IsLose)
+            {
+                if (!player.Enemy.IsLose)
+                {
+                    GManager.instance.turnStateMachine.EndGame(player.Enemy, false);
+                }
+
+                else
+                {
+                    GManager.instance.turnStateMachine.EndGame(null, false);
+                }
+
+                yield break;
+            }
+        }
+    }
+    #endregion
+
+    #region Process of trashing cards in Breeding
+    IEnumerator TrashNonDigimonPermanentProcess()
+    {
+        List<Permanent> BreedingPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+            .Map(player => player.GetBreedingAreaPermanents()
+            .Filter(IsNotDigimonInBreeding)).Flat();
+
+        if (BreedingPermanents.Count >= 1)
+        {
+            foreach (Permanent permanent in BreedingPermanents)
+            {
+                if (permanent != null)
+                {
+                    if (permanent.TopCard != null)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
+
+                        CardSource cardSource = permanent.TopCard;
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { cardSource }, "Cards put to trash", true, true));
+
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+                    }
+                }
+            }
+        }
+    }
+    #endregion
+
+    #region Process of trashing cards without DP
+    IEnumerator TrashNoDPPermanentProcess()
+    {
+        List<Permanent> DigitamaPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+            .Map(player => player.GetBattleAreaPermanents()
+            .Filter(IsNotHavingDP)).Flat();
+
+        if (DigitamaPermanents.Count >= 1)
+        {
+            foreach (Permanent permanent in DigitamaPermanents)
+            {
+                if (permanent != null)
+                {
+                    if (permanent.TopCard != null)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
+
+                        CardSource cardSource = permanent.TopCard;
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { cardSource }, "Cards put to trash", true, true));
+
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+                    }
+                }
+            }
+        }
+    }
+    #endregion
+
+    #region Digimon DP shortage handling
+    IEnumerator DigimonLackDPProcess()
+    {
+        List<Permanent> LackPowerPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+            .Map(player => player.GetFieldPermanents()
+            .Filter(IsDigimonLackDP)).Flat();
+
+        if (LackPowerPermanents.Count >= 1)
+        {
+            Hashtable hashtable = new Hashtable()
+            {
+                { "DPZero", true }
+            };
+
+            yield return ContinuousController.instance.StartCoroutine(new DestroyPermanentsClass(LackPowerPermanents, hashtable).Destroy());
+        }
+    }
+    #endregion
+
+    #region Battle Concerning Tamer
+    IEnumerator BattleWithoutDigimon()
+    {
+        if(GManager.instance.attackProcess.AttackingPermanent == null)
+            yield break;
+
+        if(!GManager.instance.attackProcess.AttackingPermanent.IsDigimon)
+            GManager.instance.attackProcess.IsEndAttack = true;
+
+        if(GManager.instance.attackProcess.DefendingPermanent == null && GManager.instance.attackProcess.HasDefender)
+            GManager.instance.attackProcess.IsEndAttack = true;
+    }
+    #endregion
+
+    #region Link Card Lacking conditions handling
+    IEnumerator DigimonLackLinkConditionProcess()
+    {
+        List<Permanent> LackLinkConditionPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+            .Map(player => player.GetFieldPermanents()
+            .Filter(IsDigimonLackLinkCondition)).Flat();
+
+        if (LackLinkConditionPermanents.Count >= 1)
+        {
+            foreach(Permanent permanent in LackLinkConditionPermanents)
+            {
+                List<CardSource> selectedCards = permanent.LinkedCards.FindAll(source => !source.CanLinkToTargetPermanent(permanent, false));
+
+                yield return ContinuousController.instance.StartCoroutine(new ITrashLinkCards(
+                               permanent,
+                               selectedCards,
+                               null).TrashLinkCards());
+            }
+        }
+    }
+    #endregion
+
+    #region Link Card Lacking Max Count handling
+    IEnumerator DigimonLackLinkMaxCountProcess()
+    {
+        List<Permanent> LackLinkCountPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+            .Map(player => player.GetFieldPermanents()
+            .Filter(IsDigimonLackLinkCount)).Flat();
+
+        if (LackLinkCountPermanents.Count >= 1)
+        {
+            foreach (Permanent permanent in LackLinkCountPermanents)
+            {
+                yield return ContinuousController.instance.StartCoroutine(permanent.RemoveLinkedCard(null, (permanent.LinkedCards.Count - permanent.LinkedMax)));
+            }
+        }
+    }
+    #endregion
+
+    #region Process of trashing cards that are face down
+    IEnumerator CardFaceDownProcess()
+    {
+        List<Permanent> FacedownPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+            .Map(player => player.GetBattleAreaPermanents()
+            .Filter(IsPermanentFaceDown)).Flat();
+
+        foreach (Permanent permanent in FacedownPermanents)
+        {
+            if (permanent != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
+
+                    CardSource cardSource = permanent.TopCard;
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { cardSource }, "Cards put to trash", true, true));
+
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+                }
+            }
+        }
+    }
+    #endregion
+
+    #endregion
+
+    #endregion
+
+    #region Trigger effect processing
+    public IEnumerator TriggeredSkillProcess(bool CheckNewTriggredSkill_mainStack, Func<List<SkillInfo>, SkillInfo, bool> skipCondition)
+    {
+        yield return ContinuousController.instance.StartCoroutine(ShrinkSecurityDigimonDisplay());
+
+        if (StackedSkillInfos.Count > 0)
+        {
+            List<SkillInfo> skillInfos = StackedSkillInfos.Filter(skillInfo => skillInfo != null && !skipSkillInfos.Contains(skillInfo));
+
+            if (skillInfos.Count >= 1)
+            {
+                //Clear the list of triggering skills not included in the resolution timing
+                foreach (SkillInfo skillInfo in skillInfos)
+                {
+                    StackedSkillInfos.Remove(skillInfo);
+                }
+
+                //Process the list of skills being triggered
+                if (availableMultipleSkills != null)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(availableMultipleSkills.ActivateMultipleSkills(
+                        skillInfos,
+                        this,
+                        CheckNewTriggredSkill_mainStack,
+                        skipCondition));
+                }
+                yield return ContinuousController.instance.StartCoroutine(StackSkillInfos(null, EffectTiming.AfterEffectsActivate));
+            }
+        }
+    }
+    #endregion
+
+    #region List of effects already achieved
+    public List<SkillInfo> skillInfos_used
+    {
+        get
+        {
+            List<SkillInfo> skillInfos_used = new List<SkillInfo>();
+
+            foreach (MultipleSkills multipleSkills in multipleSkills)
+            {
+                foreach (SkillInfo skillInfo in multipleSkills.SkillInfos_used)
+                {
+                    skillInfos_used.Add(skillInfo);
+                }
+            }
+
+            return skillInfos_used;
+        }
+    }
+    #endregion
+
+    #region The same effect has already been achieved
+    public static bool HasExecutedSameEffect(List<SkillInfo> skillInfos, SkillInfo skillInfo)
+    {
+        return skillInfos.Some((skillInfo1) => skillInfo1.CardEffect.IsSameEffect(skillInfo.CardEffect));
+    }
+    #endregion
+
+    #region Check end of turn
+    public IEnumerator EndTurnCheck()
+    {
+        if (GManager.instance.turnStateMachine.gameContext.TurnPhase != GameContext.phase.End)
+        {
+            if (GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.MemoryForPlayer >= TurnEndMinMemory)
+            {
+                GManager.instance.turnStateMachine.Passed = false;
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.EndTurnProcess());
+            }
+        }
+    }
+    #endregion
+
+    #region Minimum memory to end turn
+    static int TurnEndMinMemory
+    {
+        get
+        {
+            int turnEndMinMemory = 1;
+
+            #region the effects of players
+            GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+                    .Map(player => player.EffectList(EffectTiming.None))
+                    .Flat()
+                    .Filter(cardEffect => cardEffect is IChangeEndTurnMinMemoryEffect && cardEffect.CanUse(null))
+                    .ForEach(cardEffect => turnEndMinMemory = ((IChangeEndTurnMinMemoryEffect)cardEffect).GetMinMemory(turnEndMinMemory));
+            #endregion
+
+            #region the effects of permanents
+            GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
+                    .Map(player => player.GetFieldPermanents())
+                    .Flat()
+                    .Map(permanent => permanent.EffectList(EffectTiming.None))
+                    .Flat()
+                    .Filter(cardEffect => cardEffect is IChangeEndTurnMinMemoryEffect && cardEffect.CanUse(null))
+                    .ForEach(cardEffect => turnEndMinMemory = ((IChangeEndTurnMinMemoryEffect)cardEffect).GetMinMemory(turnEndMinMemory));
+            #endregion
+
+            return turnEndMinMemory;
+        }
+    }
+    #endregion
+
+    #region Turn end processing
+    public IEnumerator EndTurnProcess()
+    {
+        if (GManager.instance.turnStateMachine.gameContext.TurnPhase != GameContext.phase.End)
+        {
+            GManager.instance.turnStateMachine.isSync = true;
+
+            // yield return GManager.instance.photonWaitController.StartWait("EndTurnProcess");
+
+            if (GManager.instance.turnStateMachine.Passed && GManager.instance.turnStateMachine.gameContext.TurnPhase == GameContext.phase.Main)
+            {
+                if (GManager.instance.turnStateMachine.gameContext.TurnPlayer.PlayerID == 0)
+                {
+                    GManager.instance.turnStateMachine.gameContext.Memory = 3;
+                }
+
+                else
+                {
+                    GManager.instance.turnStateMachine.gameContext.Memory = -3;
+                }
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.memoryObject.SetMemory());
+            }
+
+            GManager.instance.turnStateMachine.Passed = true;
+
+            //Effect at end of turn
+            yield return ContinuousController.instance.StartCoroutine(StackSkillInfos(null, EffectTiming.OnEndTurn));
+
+            //Automatic processing check timing
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+            if (GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.MemoryForPlayer >= TurnEndMinMemory)
+            {
+                GManager.instance.turnStateMachine.gameContext.TurnPhase = GameContext.phase.End;
+            }
+
+            else
+            {
+                GManager.instance.turnStateMachine.isSync = false;
+
+                if (GManager.instance.turnStateMachine.gameContext.TurnPhase == GameContext.phase.Main)
+                {
+                    StartCoroutine(GManager.instance.turnStateMachine.SetMainPhase());
+                }
+            }
+        }
+    }
+    #endregion
+
+    #region Shrink security Digimon display
+    public IEnumerator ShrinkSecurityDigimonDisplay()
+    {
+        if (!HasAwaitingActivateEffects()) yield break;
+
+        if (GManager.instance.attackProcess.IsAttacking)
+        {
+            if (GManager.instance.attackProcess.SecurityDigimon != null)
+            {
+                if (GManager.instance.GetComponent<Effects>().ShowUseHandCard.gameObject.activeSelf && GManager.instance.GetComponent<Effects>().ShowUseHandCard.cardSource == GManager.instance.attackProcess.SecurityDigimon)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(GManager.instance.attackProcess.SecurityDigimon));
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.attackProcess.SecurityDigimon.Owner.brainStormObject.BrainStormCoroutine(GManager.instance.attackProcess.SecurityDigimon));
+                }
+            }
+        }
+    }
+    #endregion
+
+    #region Whether there is awaiting activate effects
+    public bool HasAwaitingActivateEffects()
+    {
+        if (StackedSkillInfos.Count >= 2)
+        {
+            return true;
+        }
+
+        else if (StackedSkillInfos.Count == 1)
+        {
+            if (StackedSkillInfos[0].CardEffect.CanActivate(StackedSkillInfos[0].Hashtable))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Get skillInfos
+    public static List<SkillInfo> GetSkillInfos(Hashtable hashtable, EffectTiming timing, Func<ICardEffect, bool> cardEffectCondition = null)
+    {
+        List<SkillInfo> skillInfos = new List<SkillInfo>();
+
+        #region player effect
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (ICardEffect cardEffect in player.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+            {
+                if (cardEffect is ActivateICardEffect)
+                {
+                    if (!cardEffect.IsBackgroundProcess)
+                    {
+                        if (cardEffect.CanTrigger(hashtable))
+                        {
+                            skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Effects of permanents in play
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (Permanent permanent in player.GetFieldPermanents())
+            {
+                foreach (ICardEffect cardEffect in permanent.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (!cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanTrigger(hashtable))
+                            {
+                                skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Trash card effect
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (CardSource cardSource in player.TrashCards)
+            {
+                foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (!cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanTrigger(hashtable))
+                            {
+                                skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Effects of cards in hand
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (CardSource cardSource in player.HandCards)
+            {
+                foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (!cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanTrigger(hashtable))
+                            {
+                                skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Effects of faceup security
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (CardSource source in player.SecurityCards)
+            {
+                if (source.IsFlipped)
+                    continue;
+
+                foreach (ICardEffect cardEffect in source.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (!cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanTrigger(hashtable))
+                            {
+                                skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
+                            }
+                        }
+                    }
+                }
+            }
+        }            
+        #endregion
+
+        return skillInfos;
+    }
+    #endregion
+
+    #region Activate background effects
+    public static IEnumerator ActivateBackgroundEffects(Hashtable hashtable, EffectTiming timing, Func<ICardEffect, bool> cardEffectCondition = null)
+    {
+        #region Player effect
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (ICardEffect cardEffect in player.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+            {
+                if (cardEffect is ActivateICardEffect)
+                {
+                    if (cardEffect.IsBackgroundProcess)
+                    {
+                        if (cardEffect.CanUse(hashtable))
+                        {
+                            cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
+                            yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Effects of permanents in play
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+
+            foreach (Permanent permanent in player.GetFieldPermanents())
+            {
+                foreach (ICardEffect cardEffect in permanent.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanUse(hashtable))
+                            {
+                                cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
+                                yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Trash card effect
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (CardSource cardSource in player.TrashCards)
+            {
+                foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanUse(hashtable))
+                            {
+                                cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
+                                yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        #region Effects of cards in hand
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (CardSource cardSource in player.HandCards)
+            {
+                foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanUse(hashtable))
+                            {
+                                cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
+                                yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+    }
+    #endregion
+
+    #region Stack skillInfos
+    public IEnumerator StackSkillInfos(Hashtable hashtable, EffectTiming timing, Func<ICardEffect, bool> cardEffectCondition = null)
+    {
+        GetSkillInfos(hashtable, timing, cardEffectCondition).ForEach(skillInfo => PutStackedSkill(skillInfo));
+
+        yield return ContinuousController.instance.StartCoroutine(ActivateBackgroundEffects(hashtable, timing, cardEffectCondition));
+    }
+    #endregion
+
+    #region Get skillInfos of cards
+    public static List<SkillInfo> GetSkillInfosOfCards(Hashtable hashtable, EffectTiming timing, List<CardSource> cardSources, Func<ICardEffect, bool> cardEffectCondition = null)
+    {
+        List<SkillInfo> skillInfos = new List<SkillInfo>();
+
+        #region カードリストの効果
+        foreach (CardSource cardSource in cardSources)
+        {
+            if (cardSource.PermanentOfThisCard() == null)
+            {
+                foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (!cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanTrigger(hashtable))
+                            {
+                                skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+        return skillInfos;
+    }
+    #endregion
+
+    #region Activate background effects of cards
+    public static IEnumerator ActivateBackgroundEffectsOfCards(Hashtable hashtable, EffectTiming timing, List<CardSource> cardSources, Func<ICardEffect, bool> cardEffectCondition = null)
+    {
+        #region Effect of card list
+        foreach (CardSource cardSource in cardSources)
+        {
+            if (cardSource.PermanentOfThisCard() == null)
+            {
+                foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (cardEffect.IsBackgroundProcess)
+                        {
+                            if (cardEffect.CanUse(hashtable))
+                            {
+                                cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
+                                yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
+    }
+    #endregion
+
+    #region Stack skillInfos of cards
+    public IEnumerator StackSkillInfosOfCards(Hashtable hashtable, EffectTiming timing, List<CardSource> cardSources, Func<ICardEffect, bool> cardEffectCondition = null)
+    {
+        GetSkillInfosOfCards(hashtable, timing, cardSources, cardEffectCondition).ForEach(skillInfo => PutStackedSkill(skillInfo));
+
+        yield return ContinuousController.instance.StartCoroutine(ActivateBackgroundEffectsOfCards(hashtable, timing, cardSources, cardEffectCondition));
+    }
+    #endregion
+
+    public ICardEffect MainProcessingEffect { get; private set; } = null;
+    List<ICardEffect> _usedCutinEffects = new List<ICardEffect>();
+    public IEnumerator ActivateEffectProcess(ICardEffect cardEffect, Hashtable hashtable, bool isCheckOptional = true)
+    {
+        if (cardEffect == null) yield break;
+        if (!(cardEffect is ActivateICardEffect)) yield break;
+
+        if (cardEffect.CanActivate(hashtable) || cardEffect.IsDeclarative)
+        {
+            bool isEffectProcessing = MainProcessingEffect != null;
+
+            if (!isEffectProcessing)
+            {
+                MainProcessingEffect = cardEffect;
+
+                _usedCutinEffects = new List<ICardEffect>();
+            }
+
+            yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate_Optional_Effect_Execute(hashtable, isCheckOptional));
+
+            if (!isEffectProcessing)
+            {
+                MainProcessingEffect = null;
+
+                _usedCutinEffects = new List<ICardEffect>();
+            }
+        }
+    }
+
+    public bool IsCutInEffectHasUsed(ICardEffect cutinEffect)
+    {
+        return false;//TODO: General line 17 - _usedCutinEffects.Some(cardEffect => cardEffect.IsSameEffect(cutinEffect));
+    }
+
+    public bool IsCutInEffectUsedMaxCount(ICardEffect cutinEffect)
+    {
+        return _usedCutinEffects.Count(cardEffect => cardEffect.IsSameEffect(cutinEffect)) < cutinEffect.ChainActivations;
+    }
+
+    public void AddCutinEffect(ICardEffect cardEffect)
+    {
+        if (GManager.instance.autoProcessing.MainProcessingEffect != null)
+        {
+            _usedCutinEffects.Add(cardEffect);
+        }
+    }
+}

+ 11 - 0
Assets/Script/AutoProcessing.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 285615080c1b25f439955cf15003180e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Script/AutomaticOrder.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c94b3dd70af60ab44be0d1e77b3310a7
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 40 - 0
Assets/Script/AutomaticOrder/StartTurnTamerMemory.cs

@@ -0,0 +1,40 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+using System.ComponentModel.Design;
+
+public partial class AutomaticOrder
+{
+    public static int GetSkillIndexAutomaticOrder(List<SkillInfo> skillInfos_active)
+    {
+        if (skillInfos_active.Count == 0) return 0;
+        List<SkillInfo> skillInfos_active_clone = skillInfos_active.Clone();
+
+        #region メモリーを3にするテイマー
+        List<SkillInfo> setMemory3TamerSkills = skillInfos_active_clone
+            .Filter(skillInfo => skillInfo.CardEffect.EffectName.Contains("Set Memory to "));
+
+        skillInfos_active_clone = skillInfos_active_clone
+            .Filter(skillInfo => !setMemory3TamerSkills.Contains(skillInfo));
+        #endregion
+
+        skillInfos_active_clone =
+            setMemory3TamerSkills
+            .Concat(skillInfos_active_clone)
+            .ToList();
+
+        if (skillInfos_active_clone.Count >= 1)
+        {
+            int index = skillInfos_active.IndexOf(skillInfos_active_clone[0]);
+
+            if (0 <= index && index <= skillInfos_active.Count - 1)
+            {
+                return index;
+            }
+        }
+
+        return 0;
+    }
+}

+ 11 - 0
Assets/Script/AutomaticOrder/StartTurnTamerMemory.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fd8a639914247bf4eb633587d6ec3fd0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 78 - 0
Assets/Script/BGMObject.cs

@@ -0,0 +1,78 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using DG.Tweening;
+
+[RequireComponent(typeof(AudioSource))]
+public class BGMObject : MonoBehaviour
+{
+    public AudioSource _audio { get; set; }
+    public bool isPlaying { get; set; } = false;
+    bool isFading { get; set; } = false;
+    private void Start()
+    {
+
+    }
+
+    public void StopPlayBGM()
+    {
+        _audio = GetComponent<AudioSource>();
+
+        _audio.Stop();
+
+        _audio.clip = null;
+
+        isPlaying = false;
+    }
+
+    public void StartPlayBGM(AudioClip clip)
+    {
+        _audio = GetComponent<AudioSource>();
+
+        if (clip != null)
+        {
+            _audio.clip = clip;
+        }
+
+        if (ContinuousController.instance != null)
+        {
+            ContinuousController.instance.ChangeBGMVolume(_audio);
+        }
+
+        _audio.Play();
+
+        isPlaying = true;
+    }
+
+    private void Update()
+    {
+        if (ContinuousController.instance != null)
+        {
+            if (_audio != null && isPlaying && !isFading)
+            {
+                ContinuousController.instance.ChangeBGMVolume(_audio);
+            }
+        }
+    }
+
+    public IEnumerator FadeOut(float duration)
+    {
+        _audio = GetComponent<AudioSource>();
+
+        bool end = false;
+        isFading = true;
+
+        var sequence = DOTween.Sequence();
+
+        sequence
+            .Append(DOTween.To(() => _audio.volume, (value) => _audio.volume = value, 0, duration))
+            .AppendCallback(() => end = true);
+
+        sequence.Play();
+
+        yield return new WaitWhile(() => !end);
+
+        isPlaying = false;
+        isFading = false;
+    }
+}

+ 11 - 0
Assets/Script/BGMObject.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 48a279910aded444b8a3cf18102e91e1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 46 - 0
Assets/Script/BattleMode.cs

@@ -0,0 +1,46 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class BattleMode : MonoBehaviour
+{
+    [Header("Battle Button")]
+    public OpeningButton BattleButton;
+
+    [Header("Battle Mode Selection")]
+    public SelectBattleMode selectBattleMode;
+
+    [Header("Battle Deck Selection")]
+    public SelectBattleDeck selectBattleDeck;
+
+    [Header("RandomMatch")]
+    public LobbyManager_RandomMatch lobbyManager_RandomMatch;
+
+    [Header("Room Screen")]
+    public RoomManager roomManager;
+
+    bool first = false;
+
+    public void OffBattle()
+    {
+        roomManager.Off();
+
+        selectBattleDeck.Off();
+
+        selectBattleMode.OffSelectBattleMode();
+
+        lobbyManager_RandomMatch.OffLobby();
+
+        if (!first)
+        {
+            BattleButton.OnExit();
+            first = true;
+        }
+    }
+
+    public void SetUpBattleMode()
+    {
+        selectBattleMode.SetUpSelectBattleMode();
+        Opening.instance.optionPanel.CloseOptionPanel();
+    }
+}

+ 11 - 0
Assets/Script/BattleMode.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4d469d478613f614095c7a760b48f755
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 180 - 0
Assets/Script/BendText.cs

@@ -0,0 +1,180 @@
+using System;
+using System.Linq;
+using TMPro;
+using UnityEngine;
+
+namespace TweenableObject
+{
+    [DefaultExecutionOrder(100)]
+    [ExecuteInEditMode]
+    [RequireComponent(typeof(TextMeshPro))]
+    public class BendText : MonoBehaviour
+    {
+        [SerializeField] private bool isActive;
+        [SerializeField] private bool flip;
+        [SerializeField] private float radius;
+        [SerializeField, Range(0, 360)] private float spread;
+
+        private RectTransform _rectTransform;
+        private TextMeshPro _textMeshPro;
+        private bool _isActive;
+        private bool _flip;
+        private float _lastRadius;
+        private float _lastSpread;
+        private Rect _lastRect;
+
+        private float _maxY;
+        private float _minY;
+
+        private void Awake()
+        {
+            _rectTransform = GetComponent<RectTransform>();
+            _textMeshPro = GetComponent<TextMeshPro>();
+        }
+
+        private void OnEnable()
+        {
+            ReCalculate();
+        }
+
+        private void OnDisable()
+        {
+            _textMeshPro.ForceMeshUpdate();
+        }
+
+        private void Update()
+        {
+            // EditModeでも動作するようUpdateで更新を検出
+            ReCalculate();
+        }
+
+        // パラメータやTextMeshProの変更を監視し,変更があればメッシュの再変形を行う
+        public void ReCalculate()
+        {
+            if (!_textMeshPro.havePropertiesChanged && _isActive == isActive && _flip == flip &&
+                _lastRadius == radius && _lastSpread == spread && _rectTransform.rect == _lastRect) return;
+
+            _isActive = isActive;
+            _flip = flip;
+            _lastRadius = radius;
+            _lastSpread = spread;
+            _lastRect = _rectTransform.rect;
+
+            if (isActive) SetCurve();
+            else _textMeshPro.ForceMeshUpdate();
+
+            var enu = _textMeshPro.textInfo.meshInfo.SelectMany(m => m.vertices).Select(v => v.y).ToArray();
+            _minY = enu.Min();
+            _maxY = enu.Max();
+        }
+
+        // Textに対しメッシュの変形を実行
+        private void SetCurve()
+        {
+            _textMeshPro.ForceMeshUpdate();
+
+            var textInfo = _textMeshPro.textInfo;
+            var characterCount = textInfo.characterCount;
+
+            var rect = _rectTransform.rect;
+            var minX = rect.xMin + _textMeshPro.margin.x;
+            var maxX = rect.xMax - _textMeshPro.margin.y;
+
+            for (var i = 0; i < characterCount; i++)
+            {
+                if (!textInfo.characterInfo[i].isVisible) continue;
+
+                var vertexIndex = textInfo.characterInfo[i].vertexIndex;
+                var materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
+                var vertices = textInfo.meshInfo[materialIndex].vertices;
+
+                // 文字の中点座標を計算
+                Vector3 offsetToMidBaseline =
+                    new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2,
+                        textInfo.characterInfo[i].baseLine);
+
+                // 変形後の文字の中心位置を計算
+                var val = (offsetToMidBaseline.x - minX) / (maxX - minX);
+                var pos0 = CalcPositionFromCircle(val);
+                var pos1 = CalcPositionFromCircle(val + 0.0001f);
+
+                var rotation = Quaternion.FromToRotation(Vector3.right, (pos1 - pos0).normalized);
+
+                // 各文字の4頂点への処理
+                for (var j = 0; j < 4; ++j)
+                {
+                    var point = vertices[vertexIndex + j];
+
+                    // 中点からの相対ベクトルを算出
+                    point -= offsetToMidBaseline;
+
+                    // 移動と回転を適用
+                    point = rotation * point + new Vector3(pos0.x, offsetToMidBaseline.y, pos0.z);
+
+                    vertices[vertexIndex + j] = point;
+                }
+            }
+
+            _textMeshPro.UpdateVertexData();
+        }
+
+        // 0~1のvalueに対し,円周上の位置を返す
+        private Vector3 CalcPositionFromCircle(float val)
+        {
+            var angle = (float)(1.5 * Math.PI + (val - 0.5f) * spread * Mathf.Deg2Rad);
+            var x = radius * Mathf.Cos(angle);
+            var z = (flip ? -1 : 1) * radius * (1 + Mathf.Sin(angle));
+            return new Vector3(x, 0, z);
+        }
+
+        private readonly Color _rectColor = new Color(0.98f, 0.498f, 0.196f);
+        private readonly Color _circleColor = new Color(0.176f, 0.784f, 1);
+
+        private void OnDrawGizmosSelected()
+        {
+            var old = Gizmos.matrix;
+            var transform1 = transform;
+
+            var lossyScale = transform1.lossyScale;
+            Gizmos.matrix = Matrix4x4.TRS(transform1.position + (flip ? -1 : 1) * transform1.forward * radius * lossyScale.z, transform1.rotation, lossyScale);
+
+            const int step = 5;
+            var rangeMin = (flip ? 0 : 180) - spread / 2;
+            var rangeMax = (flip ? 0 : 180) + spread / 2;
+
+            var from = new Vector3(radius * Mathf.Sin(rangeMin * Mathf.Deg2Rad), 0, radius * Mathf.Cos(rangeMin * Mathf.Deg2Rad));
+
+            for (var i = rangeMin; i <= 360 + rangeMin; i += step)
+            {
+                // 境界部での丸め込み
+                var deg = i;
+                if (deg - rangeMin > 0 && deg - rangeMin <= step) deg = rangeMin;
+                else if (deg - rangeMax > 0 && deg - rangeMax <= step) deg = rangeMax;
+
+                var to = new Vector3(radius * Mathf.Sin(deg * Mathf.Deg2Rad), 0, radius * Mathf.Cos(deg * Mathf.Deg2Rad));
+
+                if (deg == rangeMin || deg == rangeMax)
+                {
+                    Gizmos.color = _rectColor;
+                    Gizmos.DrawLine(new Vector3(to.x, _minY, to.z), new Vector3(to.x, _maxY, to.z));
+                    Gizmos.DrawLine(new Vector3(to.x, _minY, to.z), new Vector3(to.x, _maxY, to.z));
+                }
+
+                if (from != to && rangeMin <= deg && deg <= rangeMax)
+                {
+                    Gizmos.color = _rectColor;
+                    Gizmos.DrawLine(new Vector3(from.x, _minY, from.z), new Vector3(to.x, _minY, to.z));
+                    Gizmos.DrawLine(new Vector3(from.x, _maxY, from.z), new Vector3(to.x, _maxY, to.z));
+                }
+                else
+                {
+                    Gizmos.color = _circleColor;
+                    Gizmos.DrawLine(from, to);
+                }
+                from = to;
+            }
+
+            Gizmos.matrix = old;
+        }
+    }
+}

+ 11 - 0
Assets/Script/BendText.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3c024985a59ac8448b19a126cfb0b2ef
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 130 - 0
Assets/Script/BrainStormObject.cs

@@ -0,0 +1,130 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using System;
+using System.Linq;
+
+public class BrainStormObject : MonoBehaviour
+{
+    [Header("ƒvƒŒƒCƒ„�[")]
+    public Player player;
+
+    [Header("HandCards")]
+    public List<HandCard> BrainStormHandCards = new List<HandCard>();
+
+    public IEnumerator Init()
+    {
+        this.gameObject.SetActive(true);
+
+        foreach (HandCard handCard in BrainStormHandCards)
+        {
+            handCard.gameObject.SetActive(true);
+            handCard.transform.parent.gameObject.SetActive(true);
+        }
+
+        yield return new WaitForSeconds(Time.deltaTime);
+
+        foreach (HandCard handCard in BrainStormHandCards)
+        {
+            handCard.gameObject.SetActive(false);
+            handCard.gameObject.name = $"BrainStormObject_{player.PlayerName}";
+        }
+    }
+
+    public IEnumerator BrainStormCoroutine(CardSource cardSource)
+    {
+        int count = -1;
+
+        foreach (HandCard handCard in BrainStormHandCards)
+        {
+            if (handCard.gameObject.activeSelf)
+            {
+                count = BrainStormHandCards.IndexOf(handCard);
+
+                if (handCard.cardSource == cardSource)
+                {
+                    yield break;
+                }
+            }
+        }
+
+        if (-1 <= count && count <= BrainStormHandCards.Count - 2)
+        {
+            HandCard handCard = BrainStormHandCards[count + 1];
+
+            handCard.gameObject.SetActive(true);
+            handCard.SetUpHandCard(cardSource);
+            handCard.SetUpHandCardImage();
+            handCard.Outline_Select.gameObject.SetActive(true);
+            handCard.SetOrangeOutline();
+            handCard.SkillNameText.transform.parent.gameObject.SetActive(false);
+            handCard.IsExecuting = false;
+        }
+
+        yield return null;
+    }
+
+    public void EndBrainStorm()
+    {
+        foreach (HandCard handCard in BrainStormHandCards)
+        {
+            handCard.gameObject.SetActive(false);
+        }
+    }
+
+    public IEnumerator CloseBrainstrorm(CardSource cardSource)
+    {
+        foreach (HandCard handCard in BrainStormHandCards)
+        {
+            if (handCard.gameObject.activeSelf && handCard.cardSource == cardSource)
+            {
+                handCard.gameObject.SetActive(false);
+            }
+        }
+
+        yield return null;
+    }
+
+    int _timerCount = 0;
+    int _updateFrame = 20;
+    private void Update()
+    {
+        #region Update only once every few frames
+        _timerCount++;
+
+        if (_timerCount < _updateFrame)
+        {
+            return;
+        }
+
+        else
+        {
+            _timerCount = 0;
+        }
+        #endregion
+
+        RotationCards();
+    }
+
+    void RotationCards()
+    {
+        if (!player.isYou)
+        {
+            if (ContinuousController.instance != null)
+            {
+                Quaternion localRotation = Quaternion.Euler(0, 0, 0);
+
+                if (ContinuousController.instance.reverseOpponentsCards)
+                {
+                    localRotation = Quaternion.Euler(0, 0, 180);
+                }
+
+                foreach (HandCard handCard in BrainStormHandCards)
+                {
+                    handCard.transform.localRotation = localRotation;
+                }
+            }
+        }
+    }
+}

+ 11 - 0
Assets/Script/BrainStormObject.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 69f03c9143b775b46bd7102c3692478c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 64 - 0
Assets/Script/BreakGlass.cs

@@ -0,0 +1,64 @@
+using UnityEngine;
+using System.Collections;
+using DG.Tweening;
+
+public class BreakGlass : MonoBehaviour
+{
+    [SerializeField] private bool useGravity = false;                            // 重力を有効にするかどうか
+    [SerializeField] internal Vector3 explodeVel = new Vector3(0, 0, 0f);      // 爆発の中心地
+    [SerializeField] private float explodeForce = 75000;                         // 爆発の威力
+    [SerializeField] private float explodeRange = 500;                          // 爆発の範囲
+    internal Rigidbody[] rigidBodies;
+    [SerializeField] AudioClip breakGlassSE;
+
+    public virtual void Init(Material material)
+    {
+        rigidBodies = GetComponentsInChildren<Rigidbody>();
+
+        foreach (Rigidbody rb in rigidBodies)
+        {
+            rb.isKinematic = true;
+
+            if (material != null)
+            {
+                rb.GetComponent<MeshRenderer>().material = material;
+            }
+        }
+    }
+
+    public virtual void Break()
+    {
+        this.gameObject.SetActive(true);
+        StartCoroutine(BreakIenumerator());
+    }
+
+    public virtual IEnumerator BreakIenumerator()
+    {
+        ContinuousController.instance.PlaySE(breakGlassSE);
+
+        foreach (Rigidbody rb in rigidBodies)
+        {
+            rb.isKinematic = false;
+            rb.AddExplosionForce(explodeForce, transform.position + explodeVel, explodeRange);
+        }
+
+        yield return new WaitForSeconds(0.1f);
+
+        if (!(this is SecurityBreakGlass))
+        {
+            foreach (Rigidbody rb in rigidBodies)
+            {
+                rb.velocity *= 20;
+            }
+        }
+
+        yield return new WaitForSeconds(0.15f);
+
+        foreach (Rigidbody rb in rigidBodies)
+        {
+            rb.isKinematic = true;
+        }
+
+        gameObject.SetActive(false);
+    }
+}

+ 11 - 0
Assets/Script/BreakGlass.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1561e430263a82b46887a83343eacbf0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 66 - 0
Assets/Script/BurstEffectObject.cs

@@ -0,0 +1,66 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using TMPro;
+using DG.Tweening;
+
+public class BurstEffectObject : EvolutionEffectObject
+{
+    [SerializeField] Image[] jogressEvoRootImages;
+    [SerializeField] TextMeshProUGUI evolutionText;
+    [SerializeField] AudioClip changeTextSE;
+    [SerializeField] AudioClip lightningSE;
+    [SerializeField] Material normalMaterial;
+    [SerializeField] Material lightMaterial;
+    public override IEnumerator EvolutionEffectAnimation(CardSource cardSource, CardSource[] jogressEvoRoots = null, string message = "")
+    {
+        if (ContinuousController.instance != null)
+        {
+            if (!ContinuousController.instance.showCutInAnimation)
+            {
+                yield break;
+            }
+        }
+
+        animTime = 2.7f;
+
+        yield return ContinuousController.instance.StartCoroutine(base.EvolutionEffectAnimation(cardSource));
+    }
+
+    public void Set_ULTIMATEEVOLUTION()
+    {
+        evolutionText.text = "ULTIMATE\nEVOLUTION";
+    }
+
+    public void Set_BURSTEVOLUTION()
+    {
+        evolutionText.text = "BURST\nEVOLUTION";
+    }
+
+    public void SetMaterialNormalGlow()
+    {
+        evolutionText.fontSharedMaterial = normalMaterial;
+    }
+
+    public void SetMaterialLightGlow()
+    {
+        evolutionText.fontSharedMaterial = lightMaterial;
+    }
+
+    public void PlayChangeTextSE()
+    {
+        if (ContinuousController.instance != null)
+        {
+            ContinuousController.instance.PlaySE(changeTextSE);
+        }
+    }
+
+    public void PlayLightningSE()
+    {
+        if (ContinuousController.instance != null)
+        {
+            ContinuousController.instance.PlaySE(lightningSE);
+        }
+    }
+}

+ 11 - 0
Assets/Script/BurstEffectObject.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a47c2b32469165346add1ed72e30f935
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 399 - 0
Assets/Script/CEntity_Base.cs

@@ -0,0 +1,399 @@
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+
+[CreateAssetMenu(menuName = "Create/CEntity_Base")]
+public class CEntity_Base : ScriptableObject
+{
+    public int CardIndex = 0;
+    public List<CardColor> cardColors = new List<CardColor>();
+    public int PlayCost = -1;
+    public List<EvoCost> EvoCosts = new List<EvoCost>();
+    public int Level = 0;
+    public string CardName_JPN = "";
+    public string CardName_ENG = "";
+    public List<string> Form_JPN = new List<string>();
+    public List<string> Form_ENG = new List<string>();
+    public List<string> Attribute_JPN = new List<string>();
+    public List<string> Attribute_ENG = new List<string>();
+    public List<string> Type_JPN = new List<string>();
+    public List<string> Type_ENG = new List<string>();
+    public string CardSpriteName = "";
+    public CardKind cardKind = CardKind.Digimon;
+    [TextArea] public string EffectDiscription_JPN = "";
+    [TextArea] public string EffectDiscription_ENG = "";
+    [TextArea] public string InheritedEffectDiscription_JPN = "";
+    [TextArea] public string InheritedEffectDiscription_ENG = "";
+    [TextArea] public string SecurityEffectDiscription_JPN = "";
+    [TextArea] public string SecurityEffectDiscription_ENG = "";
+    public string CardEffectClassName = "";
+    public int DP = 0;
+    public Rarity rarity;
+    public int OverflowMemory = 0;
+    public int LinkDP = 0;
+    [TextArea] public string LinkEffect = "";
+    [TextArea] public string LinkRequirement = "";
+
+    public bool HasInhetitedEffect => !string.IsNullOrEmpty(InheritedEffectDiscription_ENG) && !InheritedEffectDiscription_ENG.Equals("-");
+    public bool HasSecutiryEffect => !string.IsNullOrEmpty(SecurityEffectDiscription_ENG) && !SecurityEffectDiscription_ENG.Equals("-");
+    public string CardID = "";
+    public int MaxCountInDeck = 4;
+    public bool HasLoadStarted { get; set; } = false;
+    public Sprite CardSprite { get; set; } = null;
+    public async Task LoadCardImage()
+    {
+        if (String.IsNullOrEmpty(CardSpriteName))
+        {
+            return;
+        }
+
+        if (HasLoadStarted)
+        {
+            return;
+        }
+
+        HasLoadStarted = true;
+
+        Sprite sprite = await StreamingAssetsUtility.GetSprite(CardSpriteName, isCard: true);
+
+        CardSprite = sprite;
+    }
+
+    public async Task<Sprite> GetCardSprite()
+    {
+        if (!HasLoadStarted)
+        {
+            await LoadCardImage();
+        }
+
+        return CardSprite;
+    }
+    public bool IsACE => OverflowMemory >= 1;
+    public bool IsStandardValid => true;
+
+    #region regulation mark
+    public string RegulationMark
+    {
+        get
+        {
+            string regulationMark = "";
+
+            switch (GetParseByHyphen(CardSpriteName)[0])
+            {
+                case "ST1":
+                    regulationMark = "00";
+                    break;
+
+                case "ST2":
+                    regulationMark = "00";
+                    break;
+
+                case "ST3":
+                    regulationMark = "00";
+                    break;
+
+                case "ST4":
+                    regulationMark = "00";
+                    break;
+
+                case "ST5":
+                    regulationMark = "00";
+                    break;
+
+                case "ST6":
+                    regulationMark = "00";
+                    break;
+
+                case "ST7":
+                    regulationMark = "01";
+                    break;
+
+                case "ST8":
+                    regulationMark = "01";
+                    break;
+
+                case "ST9":
+                    regulationMark = "01";
+                    break;
+
+                case "ST10":
+                    regulationMark = "01";
+                    break;
+
+                case "ST11":
+                    regulationMark = "01";
+                    break;
+
+                case "ST12":
+                    regulationMark = "02";
+                    break;
+
+                case "ST13":
+                    regulationMark = "02";
+                    break;
+
+                case "ST14":
+                    regulationMark = "02";
+                    break;
+
+                case "BT1":
+                    regulationMark = "00";
+                    break;
+
+                case "BT2":
+                    regulationMark = "00";
+                    break;
+
+                case "BT3":
+                    regulationMark = "00";
+                    break;
+
+                case "BT4":
+                    regulationMark = "00";
+                    break;
+
+                case "BT5":
+                    regulationMark = "00";
+                    break;
+
+                case "BT6":
+                    regulationMark = "01";
+                    break;
+
+                case "BT7":
+                    regulationMark = "01";
+                    break;
+
+                case "BT8":
+                    regulationMark = "01";
+                    break;
+
+                case "BT9":
+                    regulationMark = "01";
+                    break;
+
+                case "BT10":
+                    regulationMark = "02";
+                    break;
+
+                case "BT11":
+                    regulationMark = "02";
+                    break;
+
+                case "BT12":
+                    regulationMark = "02";
+                    break;
+
+                case "BT13":
+                    regulationMark = "02";
+                    break;
+
+                case "EX1":
+                    regulationMark = "01";
+                    break;
+
+                case "EX2":
+                    regulationMark = "01";
+                    break;
+
+                case "EX3":
+                    regulationMark = "02";
+                    break;
+
+                case "EX4":
+                    regulationMark = "02";
+                    break;
+
+                case "RB1":
+                    regulationMark = "02";
+                    break;
+            }
+
+            return regulationMark;
+        }
+    }
+    #endregion
+
+    #region �Z�b�gID
+    public string SetID
+    {
+        get
+        {
+            if (GetParseByHyphen(CardSpriteName).Length >= 1)
+            {
+                return GetParseByHyphen(CardSpriteName)[0];
+            }
+
+            return "";
+        }
+    }
+    #endregion
+
+    #region whether it is permanent card
+    public bool IsPermanent => cardKind == CardKind.Digimon || cardKind == CardKind.Tamer || cardKind == CardKind.DigiEgg;
+    #endregion
+
+    #region �J�[�hIndex���f�b�L�R�[�h�ɗp���镶����ɕϊ�(256�i��)
+    public string CardIndex_String
+    {
+        get
+        {
+            string CardID_String = ConvertBinaryNumber.IntToNString(CardIndex, DeckData.m);
+
+            while (CardID_String.Length < DeckData.CardKindCellLength)
+            {
+                CardID_String = $"0{CardID_String}";
+            }
+
+            return CardID_String;
+        }
+    }
+    #endregion
+
+    #region �J�[�h�摜�����A���_�[�o�[�ŋ�؂�
+    public static string[] GetParseByUnderBar(string CardImageName)
+    {
+        string[] parseByUnderBar = new string[] { CardImageName };
+
+        if (CardImageName.Contains('_'))
+        {
+            parseByUnderBar = CardImageName.Split('_');
+        }
+
+        return parseByUnderBar;
+    }
+    #endregion
+
+    #region �J�[�h�摜�����n�C�t���ŋ�؂�
+    public static string[] GetParseByHyphen(string CardImageName)
+    {
+        string[] parseByHyphen = new string[] { CardImageName };
+
+        if (CardImageName.Contains('-'))
+        {
+            parseByHyphen = CardImageName.Split('-');
+        }
+
+        return parseByHyphen;
+    }
+    #endregion
+
+    #region �f�b�L�ɂ���Ɠ��J�[�hID�̃J�[�h�������Ă��閇��
+    public int SameCardIDCount(List<CEntity_Base> DeckCards)
+    {
+        return DeckCards.Count((cEntity_Base) => cEntity_Base.CardID == CardID);
+    }
+    #endregion
+
+    #region �p��������
+    public bool isParallel
+    {
+        get
+        {
+            if (!string.IsNullOrEmpty(CardSpriteName))
+            {
+                string s = CardSpriteName.Replace(CardID, "");
+
+                if (!string.IsNullOrEmpty(s))
+                {
+                    if (s.Contains("_P"))
+                    {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+    }
+    #endregion
+
+    #region ���x�������‚�
+    public bool HasLevel
+    {
+        get
+        {
+            if (Level == 0)
+            {
+                return false;
+            }
+
+            if (cardKind != CardKind.Digimon && cardKind != CardKind.DigiEgg)
+            {
+                return false;
+            }
+
+            return true;
+        }
+    }
+    #endregion
+
+    #region Whether the card has any cost
+    public bool HasCost => PlayCost >= 0;
+    #endregion
+
+    #region Wheter the card has play cost
+    public bool HasPlayCost => cardKind != CardKind.Option && PlayCost >= 0;
+    #endregion
+
+    #region Wheter the card has use cost
+    public bool HasUseCost => cardKind == CardKind.Option && PlayCost >= 0;
+    #endregion
+}
+public enum CardKind
+{
+    Digimon,
+    Tamer,
+    Option,
+    DigiEgg,
+}
+
+[Serializable]
+public class EvoCost : IEquatable<EvoCost>
+{
+    public CardColor CardColor;
+    public int Level;
+    public int MemoryCost;
+
+    public bool Equals(EvoCost other)
+    {
+        if (other is null)
+        {
+            return false;
+        }
+
+        if (object.ReferenceEquals(this, other))
+        {
+            return true;
+        }
+
+        return CardColor.Equals(other.CardColor) && Level.Equals(other.Level) && MemoryCost.Equals(other.MemoryCost);
+    }
+
+    public override int GetHashCode() => CardColor.GetHashCode() ^ Level.GetHashCode() + MemoryCost.GetHashCode();
+}
+
+public enum CardColor
+{
+    Red,
+    Blue,
+    Yellow,
+    Green,
+    White,
+    Black,
+    Purple,
+    None,
+}
+
+public enum Rarity
+{
+    C,
+    U,
+    R,
+    SR,
+    SEC,
+    P,
+    None,
+}

+ 11 - 0
Assets/Script/CEntity_Base.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ac423894725fed64a9146a10d3878ce1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 30 - 0
Assets/Script/CEntity_Effect.cs

@@ -0,0 +1,30 @@
+using Photon.Pun;
+using System;
+using System.Collections.Generic;
+using System.Collections;
+using UnityEngine;
+using System.Linq;
+
+public abstract partial class CEntity_Effect : MonoBehaviourPunCallbacks
+{
+    public virtual List<ICardEffect> CardEffects(EffectTiming timing, CardSource cardSource)
+    {
+        return new List<ICardEffect>();
+    }
+
+    public List<ICardEffect> GetCardEffects(EffectTiming timing, CardSource cardSource)
+    {
+        return CardEffects(timing,cardSource).Filter(cardEffect => cardEffect != null);
+    }
+
+    //後で消す
+    public static bool isExistOnField(CardSource card)
+    {
+        if (card.PermanentOfThisCard() != null)
+        {
+            return true;
+        }
+
+        return false;
+    }
+}

+ 11 - 0
Assets/Script/CEntity_Effect.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 71e579083b186564b86f3f5a5d507cca
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 281 - 0
Assets/Script/CEntity_EffectController.cs

@@ -0,0 +1,281 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+using System.IO;
+
+public class CEntity_EffectController : MonoBehaviour
+{
+    //Number of skills used this turn (referenced by use limit)
+    List<ICardEffect> UseEffectsThisTurn = new List<ICardEffect>();
+
+    #region CEntity_Effect
+    public CEntity_Effect cEntity_Effect { get; set; }
+    #endregion
+
+    #region Get effect list
+    public List<ICardEffect> GetCardEffects_ExceptAddedEffects(EffectTiming timing, CardSource card)
+    {
+        List<ICardEffect> GetCardEffects = new List<ICardEffect>();
+
+        if (cEntity_Effect != null)
+        {
+            foreach (ICardEffect cardEffect in cEntity_Effect.GetCardEffects(timing, card))
+            {
+                GetCardEffects.Add(cardEffect);
+            }
+        }
+
+        return GetCardEffects;
+    }
+    public List<ICardEffect> GetCardEffects(EffectTiming timing, CardSource card)
+    {
+        List<ICardEffect> GetCardEffects = new List<ICardEffect>();
+
+        foreach (ICardEffect cardEffect in GetCardEffects_ExceptAddedEffects(timing, card))
+        {
+            GetCardEffects.Add(cardEffect);
+        }
+
+        Permanent thisPermanent = card.PermanentOfThisCard();
+        bool isDigivolutionCard = thisPermanent != null && thisPermanent.DigivolutionCards.Contains(card);
+
+        if (!isDigivolutionCard)
+        {
+            // Effects added by other card effects
+            if (timing != EffectTiming.None)
+            {
+                #region Effects added by other card effects
+                foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+                {
+                    if (player != null)
+                    {
+                        #region Effects of permanents in play
+                        foreach (Permanent permanent in player.GetFieldPermanents())
+                        {
+                            if (permanent.TopCard.cEntity_EffectController.cEntity_Effect != null)
+                            {
+                                foreach (CardSource cardSource in permanent.cardSources)
+                                {
+                                    if (cardSource != permanent.TopCard)
+                                    {
+                                        if (!permanent.IsDigimon)
+                                        {
+                                            continue;
+                                        }
+                                    }
+
+                                    foreach (ICardEffect cardEffect in cardSource.cEntity_EffectController.cEntity_Effect.GetCardEffects(EffectTiming.None, permanent.TopCard))
+                                    {
+                                        if (cardEffect is IAddSkillEffect)
+                                        {
+                                            if (cardEffect.IsInheritedEffect == (cardSource == permanent.TopCard) || cardSource.IsFlipped)
+                                            {
+                                                continue;
+                                            }
+
+                                            if (cardEffect.CanUse(null))
+                                            {
+                                                if (!card.CanNotBeAffected(cardEffect))
+                                                    GetCardEffects = ((IAddSkillEffect)cardEffect).GetCardEffect(card, GetCardEffects, timing);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        #endregion
+
+                        #region Effects from security
+                        foreach (CardSource source in player.SecurityCards)
+                        {
+                            if (source.IsFlipped)
+                                continue;
+
+                            foreach (ICardEffect cardEffect in source.EffectList(EffectTiming.None))
+                            {
+                                if (cardEffect is IAddSkillEffect)
+                                {
+                                    if (cardEffect.CanUse(null))
+                                    {
+                                        GetCardEffects = ((IAddSkillEffect)cardEffect).GetCardEffect(card, GetCardEffects, timing);
+                                    }
+                                }
+                            }
+                        }
+                        #endregion
+
+                        #region Effects added by players
+                        foreach (ICardEffect cardEffect in player.EffectList(EffectTiming.None))
+                        {
+                            if (cardEffect is IAddSkillEffect)
+                            {
+                                if (cardEffect.CanUse(null))
+                                {
+                                    GetCardEffects = ((IAddSkillEffect)cardEffect).GetCardEffect(card, GetCardEffects, timing);
+                                }
+                            }
+                        }
+                        #endregion
+                    }
+                }
+                #endregion
+            }
+
+            // Explore about EffectTiming.None only if added by me
+            else
+            {
+                if (thisPermanent != null)
+                {
+                    if (thisPermanent.TopCard.cEntity_EffectController.cEntity_Effect != null)
+                    {
+                        foreach (CardSource cardSource in thisPermanent.cardSources)
+                        {
+                            foreach (ICardEffect cardEffect in cardSource.cEntity_EffectController.cEntity_Effect.GetCardEffects(EffectTiming.None, thisPermanent.TopCard))
+                            {
+                                if (cardEffect is IAddSkillEffect)
+                                {
+                                    if (cardEffect.IsInheritedEffect == (cardSource == thisPermanent.TopCard) || cardSource.IsFlipped)
+                                    {
+                                        continue;
+                                    }
+
+                                    if (cardEffect.CanUse(null))
+                                    {
+                                        //GetCardEffects = ((IAddSkillEffect)cardEffect).GetCardEffect(card, GetCardEffects, timing);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (CardEffectCommons.IsExistInSecurity(card))
+                {
+                    foreach (ICardEffect cardEffect in card.cEntity_EffectController.cEntity_Effect.GetCardEffects(EffectTiming.None, card))
+                    {
+                        if (cardEffect is IAddSkillEffect)
+                        {
+                            if (cardEffect.CanUse(null))
+                            {
+                                GetCardEffects = ((IAddSkillEffect)cardEffect).GetCardEffect(card, GetCardEffects, timing);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return GetCardEffects.Filter(cardEfect => cardEfect != null);
+    }
+    #endregion
+
+    #region Reset the number of uses during that turn
+    public void InitUseCountThisTurn()
+    {
+        UseEffectsThisTurn = new List<ICardEffect>();
+    }
+    #endregion
+
+    #region set card effects
+    public void AddCardEffect(string ID, string ClassName)
+    {
+        ID = ID.Split("-")[0];
+        #region Generate and set an instance of the card effect class
+        bool CanAttachEffectComponent()
+        {
+            if (string.IsNullOrEmpty(ClassName)) 
+                return false;
+
+            if (Type.GetType(ClassName) == null)
+            {
+                if (!ClassName.Contains("token"))
+                {
+                    if (Type.GetType($"DCGO.CardEffects.{ID}.{ClassName}") == null)
+                        return false;
+                }
+                else
+                {
+                    if (Type.GetType($"DCGO.CardEffects.Tokens.{ClassName}") == null)
+                        return false;
+                }
+                
+            }
+
+            return true;
+        }
+
+        CEntity_Effect cEntity_Effect = null;
+
+        if (CanAttachEffectComponent())
+        {
+            Type t = Type.GetType(ClassName);
+
+            if (t == null)
+            {
+                if (!ClassName.Contains("token"))
+                    t = Type.GetType($"DCGO.CardEffects.{ID}.{ClassName}");
+                else
+                    t = Type.GetType($"DCGO.CardEffects.Tokens.{ClassName}");
+            }
+                
+
+            Component component = this.gameObject.AddComponent(t);
+
+            if (component is CEntity_Effect)
+            {
+                cEntity_Effect = (CEntity_Effect)(component);
+            }
+
+            else
+            {
+                Debug.Log($"{ClassName} has error");
+            }
+        }
+
+        else
+        {
+            cEntity_Effect = this.gameObject.AddComponent<EmptyEffectClass>();
+        }
+
+        this.cEntity_Effect = cEntity_Effect;
+        #endregion
+    }
+    #endregion
+
+    #region Gets the number of times the effect was used this turn
+    public int GetUseCountThisTurn(ICardEffect cardEffect)
+    {
+        int useCount = 0;
+
+        foreach (ICardEffect cardEffect1 in UseEffectsThisTurn)
+        {
+            if (cardEffect.IsSameEffect(cardEffect1))
+            {
+                useCount++;
+            }
+        }
+
+        return useCount;
+    }
+    #endregion
+
+    #region Whether the effect has reached the maximum number of times it can be used this turn.
+    public bool isOverMaxCountPerTurn(ICardEffect cardEffect, int MaxCountPerTurn)
+    {
+        return GetUseCountThisTurn(cardEffect) >= MaxCountPerTurn;
+    }
+    #endregion
+
+    #region Register as effects used this turn
+    public void RegisterUseEfffectThisTurn(ICardEffect cardEffect)
+    {
+        UseEffectsThisTurn.Add(cardEffect);
+    }
+    #endregion
+}
+
+public class EmptyEffectClass : CEntity_Effect
+{
+
+}

+ 11 - 0
Assets/Script/CEntity_EffectController.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: f2f1d6478581e464188065a37f72d1b7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 44 - 0
Assets/Script/CPlayerElement.cs

@@ -0,0 +1,44 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class CPlayerElement : MonoBehaviour
+{
+    //For Room Information UI display
+    public Text PlayerName;   //PlayerName
+    public Text IsReady; //standby state
+
+    //For storing the roomname of the room entry button
+    private string playername;
+
+    //Function to set Room information from GetRoomList to RoomElement
+    public void SetPlayerInfo(string _PlayerName, bool _IsReady)
+    {
+        //Obtain roomname for room entry button
+        playername = _PlayerName;
+        PlayerName.text = _PlayerName;
+
+        if (_IsReady)
+        {
+            IsReady.text = LocalizeUtility.
+            GetLocalizedString(
+                EngMessage: "Ready",
+                JpnMessage: "準備完了"
+            );
+
+            IsReady.color = new Color32(53, 255, 4, 255);
+        }
+
+        else
+        {
+            IsReady.text = LocalizeUtility.
+            GetLocalizedString(
+                EngMessage: "Not Ready",
+                JpnMessage: "準備中"
+            );
+
+            IsReady.color = Color.red;
+        }
+    }
+}

+ 11 - 0
Assets/Script/CPlayerElement.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ab422baa4c275c846b1f3366fe714714
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 38 - 0
Assets/Script/CRoomElement.cs

@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using Photon.Pun;
+using Photon.Realtime;
+using UnityEngine.Events;
+
+public class CRoomElement : MonoBehaviour
+{
+    //For Room Information UI display
+    public Text PlayerNumber;   //the number of people
+    public Text RoomCreator;    //Room Creator Name
+
+    //For storing the roomname of the room entry button
+    private string roomname;
+
+    public string RoomName { get => roomname; }
+
+    //Function to set Room information from GetRoomList to RoomElement
+    public void SetRoomInfo(string _RoomName, int _PlayerNumber, string _RoomCreator)
+    {
+        roomname = _RoomName;
+        //Obtain roomname for room entry button
+        PlayerNumber.text = "人 数:" + _PlayerNumber + "/2";
+        RoomCreator.text = "作成者:" + _RoomCreator;
+    }
+
+    [HideInInspector] public UnityAction OnClick;
+
+    //Entry button processing
+    public void OnJoinRoomButton()
+    {
+        if (OnClick != null)
+        {
+            OnClick.Invoke();
+        }
+    }
+}

+ 11 - 0
Assets/Script/CRoomElement.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9bde3d3f8e331f54c8db220a8473be43
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5533 - 0
Assets/Script/CardController.cs

@@ -0,0 +1,5533 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Linq;
+
+#region Trash cards from hand
+
+public class IDiscardHands
+{
+    public IDiscardHands(List<IDiscardHand> discardHands, ICardEffect cardEffect)
+    {
+        foreach (IDiscardHand discardHand in discardHands)
+        {
+            this.discardHands.Add(discardHand);
+        }
+
+        this.cardEffect = cardEffect;
+    }
+
+    List<IDiscardHand> discardHands { get; set; } = new List<IDiscardHand>();
+    ICardEffect cardEffect { get; set; }
+
+    public IEnumerator DiscardHands()
+    {
+        foreach (IDiscardHand discardHand in discardHands)
+        {
+            yield return ContinuousController.instance.StartCoroutine(discardHand.Discard());
+        }
+
+        List<CardSource> discardedCards = new List<CardSource>();
+
+        foreach (IDiscardHand discardHand in discardHands)
+        {
+            if (discardHand.discarded)
+            {
+                discardedCards.Add(discardHand.cardSource);
+            }
+        }
+
+        if (discardedCards.Count >= 1)
+        {
+            #region "When cards are trashed from hand" effect
+
+            #region Hashtable setting
+
+            Hashtable hashtable = new Hashtable()
+            {
+                {"DiscardedCards", discardedCards},
+                {"CardEffect", cardEffect},
+            };
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnDiscardHand));
+
+            #endregion
+        }
+
+        #region add log
+
+        if (discardedCards.Count >= 1)
+        {
+            string log = "";
+
+            log += $"\nDiscard hand:";
+
+            foreach (CardSource cardSource in discardedCards)
+            {
+                log += $"\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})";
+            }
+
+            log += "\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+
+        #endregion
+    }
+}
+
+public class IDiscardHand
+{
+    public IDiscardHand(CardSource cardSource, Hashtable hashtable)
+    {
+        this.cardSource = cardSource;
+        this.hashtable = hashtable;
+    }
+
+    public CardSource cardSource { get; private set; }
+
+    public Hashtable hashtable { get; private set; }
+    public bool discarded { get; private set; } = false;
+
+    public IEnumerator Discard()
+    {
+        bool oldisHand = cardSource.Owner.HandCards.Contains(cardSource);
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().DeleteHandCardEffectCoroutine(cardSource));
+
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+
+        bool isTrash = CardEffectCommons.IsExistOnTrash(cardSource);
+
+        if (oldisHand && isTrash)
+        {
+            discarded = true;
+        }
+    }
+}
+
+#endregion
+
+#region Play cards
+
+public class PlayCardClass
+{
+    public PlayCardClass(List<CardSource> cardSources, Hashtable hashtable, bool payCost, Permanent targetPermanent, bool isTapped, SelectCardEffect.Root root,
+    bool activateETB)
+    {
+        if (cardSources != null)
+        {
+            CardSources = cardSources.Filter(cardSource => cardSource != null).Clone();
+        }
+
+        _hashtable = hashtable;
+        PayCost = payCost;
+        _targetPermanent = targetPermanent;
+        _isTapped = isTapped;
+        Root = root;
+        _activateETB = activateETB;
+    }
+
+    public void SetJogress(int[] jogressEvoRootsFrameIDs)
+    {
+        if (jogressEvoRootsFrameIDs != null)
+        {
+            _jogressEvoRootsFrameIDs = jogressEvoRootsFrameIDs.CloneArray();
+        }
+    }
+
+    public void SetBurst(int BurstTamerFrameID, CardSource card)
+    {
+        if (0 <= BurstTamerFrameID && BurstTamerFrameID <= card.Owner.fieldCardFrames.Count - 1)
+        {
+            _burstTamerFrameID = BurstTamerFrameID;
+        }
+    }
+
+    public void SetAppFusion(int[] AppFusionFrameID)
+    {
+        if (AppFusionFrameID != null)
+        {
+            _appFusionFrameIDs = AppFusionFrameID.CloneArray(); ;
+        }
+    }
+
+    public void SetShowEffect()
+    {
+        _showEffect = true;
+    }
+
+    public void SetIgnoreLevel()
+    {
+        _ignoreLevel = true;
+        SetIgnoreRequirements(CardEffectCommons.IgnoreRequirement.Level);
+    }
+
+    public void SetIgnoreRequirements(CardEffectCommons.IgnoreRequirement ignore)
+    {
+        _ignoreRequirement = ignore;
+    }
+
+    private bool GetIgnoreRequirement(CardEffectCommons.IgnoreRequirement ignore)
+    {
+        return _ignoreRequirement.Equals(ignore) || _ignoreRequirement.Equals(CardEffectCommons.IgnoreRequirement.All);
+    }
+
+    public void SetFixedCost(int FixedCost)
+    {
+        _fixedCost = FixedCost;
+    }
+
+    public void SetReducedCost(int ReducedCost)
+    {
+        _reducedCost = ReducedCost;
+    }
+
+    public void SetAddSecurityEndOption()
+    {
+        _addSecurityEndOption = true;
+    }
+
+    public void SetIsBreedingArea()
+    {
+        _isBreedingArea = true;
+    }
+
+    public List<CardSource> CardSources { get; private set; } = new List<CardSource>();
+    Hashtable _hashtable = null;
+    public bool PayCost { get; private set; }
+    Permanent _targetPermanent = null;
+    bool _isTapped = false;
+    public SelectCardEffect.Root Root { get; private set; } = SelectCardEffect.Root.None;
+    bool _activateETB = true;
+    bool _showEffect = false;
+    bool _ignoreLevel = false;
+    CardEffectCommons.IgnoreRequirement _ignoreRequirement = CardEffectCommons.IgnoreRequirement.None;
+    int _fixedCost = -1;
+    int _reducedCost = 0;
+    int[] _jogressEvoRootsFrameIDs = null;
+    int _burstTamerFrameID = -1;
+    int[] _appFusionFrameIDs = null;
+    bool _addSecurityEndOption = false;
+    bool _isBreedingArea = false;
+
+    public bool isJogress => _jogressEvoRootsFrameIDs != null && _jogressEvoRootsFrameIDs.Length == 2;
+
+    bool IsBurst(CardSource card)
+    {
+        Permanent burstTamer = BurstTamer(card);
+
+        if (burstTamer != null)
+        {
+            if (burstTamer.TopCard != null)
+            {
+                if (card.burstDigivolutionCondition != null)
+                {
+                    if (card.burstDigivolutionCondition.tamerCondition != null)
+                    {
+                        if (card.burstDigivolutionCondition.tamerCondition(burstTamer))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    Permanent BurstTamer(CardSource card)
+    {
+        if (0 <= _burstTamerFrameID && _burstTamerFrameID <= card.Owner.fieldCardFrames.Count - 1)
+        {
+            Permanent tamer = card.Owner.fieldCardFrames[_burstTamerFrameID].GetFramePermanent();
+
+            return tamer;
+        }
+
+        return null;
+    }
+
+    bool IsAppFusion(CardSource card)
+    {
+        CardSource linkCard = LinkedCard(card);
+
+        if (linkCard != null)
+        {
+            if (card.appFusionCondition != null)
+            {
+                if (card.appFusionCondition.digimonCondition != null)
+                {
+                    Permanent digimon = card.Owner.fieldCardFrames[_appFusionFrameIDs[0]].GetFramePermanent();
+
+                    if (card.appFusionCondition.linkedCondition != null)
+                    {
+                        if (card.appFusionCondition.linkedCondition(digimon, linkCard))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public CardSource LinkedCard(CardSource card)
+    {
+        if (_appFusionFrameIDs != null && _appFusionFrameIDs.Length == 2)
+        {
+            if (0 <= _appFusionFrameIDs[0] && _appFusionFrameIDs[0] <= card.Owner.fieldCardFrames.Count - 1)
+            {
+                Permanent targetPermanent = card.Owner.fieldCardFrames[_appFusionFrameIDs[0]].GetFramePermanent();
+
+                if (targetPermanent.LinkedCards.Count > _appFusionFrameIDs[1])
+                {
+                    CardSource link = targetPermanent.LinkedCards[_appFusionFrameIDs[1]];
+                    return link;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public IEnumerator PlayCard()
+    {
+        bool burstDigivolved = false;
+        bool appFusion = false;
+
+        List<CardSource> playedCards_fixed = new List<CardSource>();
+
+        foreach (CardSource card in CardSources)
+        {
+            GManager.instance.GetComponent<SelectDigiXrosClass>().ResetSelectDigiXrosClass();
+            GManager.instance.GetComponent<SelectAssemblyClass>().ResetSelectAssemblyClass();
+            GManager.instance.GetComponent<SelectDNACondition>().ResetSelectDNAConditionClass();
+
+            if (card == null)
+            {
+                continue;
+            }
+
+            #region Set Root
+
+            ICardEffect CardEffect = null;
+
+            CardEffect = CardEffectCommons.GetCardEffectFromHashtable(this._hashtable);
+
+            if (CardEffectCommons.IsExistOnTrash(card))
+            {
+                Root = SelectCardEffect.Root.Trash;
+            }
+            else if (card.Owner.HandCards.Contains(card))
+            {
+                Root = SelectCardEffect.Root.Hand;
+            }
+            else if (card.Owner.LibraryCards.Contains(card))
+            {
+                Root = SelectCardEffect.Root.Library;
+            }
+            else if (card.Owner.GetFieldPermanents().Count((permanent) => permanent.DigivolutionCards.Contains(card)) >= 1)
+            {
+                Root = SelectCardEffect.Root.DigivolutionCards;
+            }
+            else if (card.Owner.GetFieldPermanents().Count((permanent) => permanent.LinkedCards.Contains(card)) >= 1)
+            {
+                Root = SelectCardEffect.Root.LinkedCards;
+            }
+            else if (card.Owner.SecurityCards.Contains(card))
+            {
+                Root = SelectCardEffect.Root.Security;
+            }
+            else if (CardEffectCommons.IsExistOnExecutingArea(card))
+            {
+                Root = SelectCardEffect.Root.Execution;
+            }
+
+            #endregion
+
+            #region Set target(s)
+
+            List<Permanent> targetPermanents = new List<Permanent>();
+
+            if (card.IsPermanent)
+            {
+                if (!isJogress)
+                {
+                    if (CardEffectCommons.IsOwnerPermanent(_targetPermanent, card))
+                    {
+                        targetPermanents.Add(_targetPermanent);
+                    }
+                }
+                else
+                {
+                    for (int i = 0; i < _jogressEvoRootsFrameIDs.Length; i++)
+                    {
+                        int JogressFrameID = _jogressEvoRootsFrameIDs[i];
+
+                        if (0 <= JogressFrameID && JogressFrameID <= card.Owner.fieldCardFrames.Count - 1)
+                        {
+                            Permanent targetPermanent = card.Owner.fieldCardFrames[JogressFrameID].GetFramePermanent();
+                            targetPermanents.Add(targetPermanent);
+                        }
+                    }
+
+                    foreach (Permanent permanent in targetPermanents)
+                    {
+                        permanent.ShowingPermanentCard.SetPermanentIndexText(targetPermanents);
+                    }
+                }
+            }
+
+            #endregion
+
+            #region Determine if Evolution
+
+            bool isEvolution = false;
+
+            if (targetPermanents.Count >= 1)
+            {
+                if (!isJogress)
+                {
+                    if (IsBurst(card))
+                    {
+                        if (card.CanBurstDigivolutionFromTargetPermanent(targetPermanents[0], PayCost))
+                        {
+                            isEvolution = true;
+                        }
+                    }
+                    else if (IsAppFusion(card))
+                    {
+                        if (card.CanAppFusionFromTargetPermanent(targetPermanents[0], PayCost))
+                        {
+                            isEvolution = true;
+                        }
+                    }
+                    else
+                    {
+                        if (card.CanEvolve(targetPermanents[0], true) || GetIgnoreRequirement(CardEffectCommons.IgnoreRequirement.Level) || _ignoreLevel)
+                        {
+                            isEvolution = true;
+                        }
+                    }
+                }
+                else
+                {
+                    if (targetPermanents.Count == 2)
+                    {
+                        isEvolution = true;
+                    }
+                }
+            }
+
+            #endregion
+
+            List<CardSource> oldTrashCards = new List<CardSource>();
+
+            foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForNonTurnPlayer)
+            {
+                foreach (Permanent permanent in player.GetFieldPermanents())
+                {
+                    permanent.oldIsTapped_playCard = permanent.IsSuspended;
+                }
+            }
+
+            foreach (CardSource cardSource in card.Owner.TrashCards)
+            {
+                oldTrashCards.Add(cardSource);
+            }
+
+            // effect of removing digivolution/linked cards
+            if (card.IsPermanent && !isEvolution && card.PermanentOfThisCard() != null && (Root == SelectCardEffect.Root.DigivolutionCards || Root == SelectCardEffect.Root.LinkedCards))
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().RemoveDigivolveRootEffect(card, card.PermanentOfThisCard()));
+            }
+
+            #region select digivolution cost
+
+            int baseCost = -1;
+
+            bool costSelected = false;
+
+            yield return ContinuousController.instance.StartCoroutine(SelectCost());
+
+            IEnumerator SelectCost()
+            {
+                if (!isJogress)
+                {
+                    if (PayCost)
+                    {
+                        if (_fixedCost < 0)
+                        {
+                            Permanent targetPermanent = null;
+
+                            if (targetPermanents.Count >= 1)
+                            {
+                                targetPermanent = targetPermanents[0];
+                            }
+
+                            if (targetPermanent != null)
+                            {
+                                List<int> CostList = new List<int>();
+
+                                bool isBurst = IsBurst(card);
+                                bool isAppFusion = IsAppFusion(card);
+
+                                if (isBurst || isAppFusion)
+                                {
+                                    if (isBurst)
+                                        CostList.Add(card.burstDigivolutionCondition.cost);
+
+                                    if (isAppFusion)
+                                        CostList.Add(card.appFusionCondition.cost);
+                                }
+                                else
+                                {
+                                    foreach (int cost in card.CostList(targetPermanent, ignoreLevel: GetIgnoreRequirement(CardEffectCommons.IgnoreRequirement.Level), checkAvailability: false))
+                                    {
+                                        int evoCost = cost;
+
+                                        if (_reducedCost > 0)
+                                            evoCost -= _reducedCost;
+
+                                        CostList.Add(evoCost);
+                                    }
+                                }
+
+                                CostList = CostList.Distinct().ToList();
+
+                                if (CostList.Count >= 1)
+                                {
+                                    if (CostList.Count == 1)
+                                    {
+                                        baseCost = CostList[0];
+                                    }
+                                    else
+                                    {
+                                        costSelected = true;
+
+                                        bool MoveToExecuteCardEffect = true;
+
+                                        if (card.Owner.HandCards.Contains(card) && card.ShowingHandCard != null)
+                                        {
+                                            if (card.ShowingHandCard.gameObject.activeSelf)
+                                            {
+                                                MoveToExecuteCardEffect = false;
+                                            }
+                                        }
+
+                                        if (!card.Owner.isYou && GManager.instance.IsAI)
+                                        {
+                                            MoveToExecuteCardEffect = false;
+
+                                            costSelected = false;
+                                        }
+
+                                        if (card.Owner.isYou && ContinuousController.instance.autoMinDigivolutionCost)
+                                        {
+                                            MoveToExecuteCardEffect = false;
+
+                                            costSelected = false;
+                                        }
+
+                                        if (MoveToExecuteCardEffect)
+                                        {
+                                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(card));
+                                        }
+
+                                        SelectCountEffect selectCountEffect = GManager.instance.GetComponent<SelectCountEffect>();
+
+                                        if (selectCountEffect != null)
+                                        {
+                                            selectCountEffect.SetUp(
+                                                SelectPlayer: card.Owner,
+                                                targetPermanent: null,
+                                                MaxCount: 1,
+                                                CanNoSelect: false,
+                                                Message: "Which digivolution cost do you pay?",
+                                                Message_Enemy: "The opponent is choosing which digivolution cost to pay.",
+                                                SelectCountCoroutine: SelectCountCoroutine);
+
+                                            selectCountEffect.SetCandidates(CostList);
+                                            selectCountEffect.SetPreferMin(true);
+                                            selectCountEffect.SetNotDoSync(true);
+                                            selectCountEffect.SetIsDigivolutionCost(true);
+
+                                            yield return ContinuousController.instance.StartCoroutine(selectCountEffect.Activate());
+
+                                            IEnumerator SelectCountCoroutine(int count)
+                                            {
+                                                baseCost = count;
+                                                yield return null;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                baseCost = card.BasePlayCostFromEntity;
+                            }
+                        }
+                    }
+                }
+            }
+
+            #endregion
+
+            #region select DNA condition
+
+            int baseDNA = 0;
+
+            if (isJogress)
+            {
+                baseDNA = GManager.instance.GetComponent<SelectDNACondition>()._selectedCount;
+            }
+
+            #endregion
+
+            #region HashTable Setting
+
+            Hashtable hashtable = CardEffectCommons.WouldEnterFieldHashtable(
+                payCost: PayCost,
+                card: card,
+                root: Root,
+                isEvolution: isEvolution,
+                playCardClass: this,
+                cardEffect: CardEffect,
+                isJogress: isJogress,
+                targetPermanents: targetPermanents
+            );
+
+            #endregion
+
+            List<SkillInfo> skillInfos_BeforePayCost = AutoProcessing.GetSkillInfos(hashtable, EffectTiming.BeforePayCost)
+            .Concat(AutoProcessing.GetSkillInfosOfCards(hashtable, EffectTiming.BeforePayCost, new List<CardSource>() { card }
+                .Filter(cardSource => !CardEffectCommons.IsExistOnHand(cardSource) && !CardEffectCommons.IsExistOnTrash(cardSource) && !CardEffectCommons.IsExistInSecurity(cardSource) && cardSource.PermanentOfThisCard() == null)))
+            .ToList();
+
+            yield return ContinuousController.instance.StartCoroutine(AutoProcessing.ActivateBackgroundEffects(hashtable, EffectTiming.BeforePayCost));
+
+            #region IsShowEffect()
+
+            bool IsShowEffect()
+            {
+                if (skillInfos_BeforePayCost.Count >= 2)
+                {
+                    return true;
+                }
+                else if (skillInfos_BeforePayCost.Count == 1)
+                {
+                    if (skillInfos_BeforePayCost[0].CardEffect.CanActivate(skillInfos_BeforePayCost[0].Hashtable))
+                    {
+                        return true;
+                    }
+                }
+                else if (card.HasDigiXros && !isEvolution)
+                {
+                    return true;
+                }
+                else if (IsBurst(card))
+                {
+                    return true;
+                }
+                else if (IsAppFusion(card))
+                {
+                    return true;
+                }
+
+                return false;
+            }
+
+            #endregion
+
+            #region effect
+
+            if (PayCost || IsShowEffect())
+            {
+                if (!costSelected)
+                {
+                    if (card.IsOption || IsShowEffect())
+                    {
+                        bool noHandCard = true;
+
+                        if (card.Owner.HandCards.Contains(card))
+                        {
+                            if (card.ShowingHandCard != null)
+                            {
+                                if (card.ShowingHandCard.gameObject.activeSelf)
+                                {
+                                    if (card.ShowingHandCard.gameObject.transform.GetChild(0).gameObject.activeSelf)
+                                    {
+                                        noHandCard = false;
+                                    }
+                                }
+                            }
+                        }
+
+                        if (noHandCard)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(card));
+                        }
+                    }
+                    else
+                    {
+                        if (CardEffect == null)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShrinkUpUseHandCard(GManager.instance.GetComponent<Effects>().ShowUseHandCard));
+                        }
+                    }
+                }
+            }
+
+            #endregion
+
+            #region show expected cost
+
+            if (PayCost)
+            {
+                if (!isJogress)
+                {
+                    int cost = card.GetPayingCostWithBaseCost(baseCost, Root, targetPermanents, checkAvailability: false, FixedCost: _fixedCost);
+
+                    GManager.instance.memoryObject.ShowMemoryPredictionLine(card.Owner.ExpectedMemory(cost));
+                }
+                else
+                {
+                    if (card.jogressCondition.Count > 0)
+                    {
+                        int cost = card.GetPayingCostWithBaseCost(card.jogressCondition[baseDNA].cost, Root, targetPermanents, checkAvailability: false, FixedCost: _fixedCost);
+                        GManager.instance.memoryObject.ShowMemoryPredictionLine(card.Owner.ExpectedMemory(cost));
+                    }
+                }
+            }
+
+            #endregion
+
+            #region process cut in effects before paying cost
+
+            if (skillInfos_BeforePayCost.Count >= 1)
+            {
+                foreach (SkillInfo skillInfo in skillInfos_BeforePayCost)
+                {
+                    GManager.instance.autoProcessing_CutIn.PutStackedSkill(skillInfo);
+                }
+
+                if (IsShowEffect())
+                {
+                    foreach (Permanent targetPermanent in targetPermanents)
+                    {
+                        if (targetPermanent != null)
+                        {
+                            targetPermanent.ShowWillEvolutionEffect();
+                        }
+                    }
+                }
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, AutoProcessing.HasExecutedSameEffect));
+
+                foreach (Permanent targetPermanent in targetPermanents)
+                {
+                    if (targetPermanent != null)
+                    {
+                        targetPermanent.HideWillEvolutionEffect();
+                    }
+                }
+            }
+
+            #endregion
+
+            #region select DigiXros
+
+            if (card.HasDigiXros && !isEvolution)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<SelectDigiXrosClass>().Select(card));
+            }
+
+            #endregion
+
+            #region select Assembly
+
+            if (card.HasAssembly && !isEvolution)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<SelectAssemblyClass>().Select(card));
+            }
+
+            #endregion
+
+            #region Bounce Tamer of Burst digivolution
+
+            if (IsBurst(card))
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.selectBurstDigivolutionEffect.BounceTamer(BurstTamer(card)));
+
+                if (!GManager.instance.selectBurstDigivolutionEffect.TamerBounced)
+                {
+                    _burstTamerFrameID = -1;
+
+                    yield return ContinuousController.instance.StartCoroutine(SelectCost());
+                }
+                else
+                {
+                    burstDigivolved = true;
+                }
+            }
+
+            #endregion
+
+            #region Add Link Card of App Fusion
+
+            if (IsAppFusion(card))
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.selectAppFusionEffect.AddToSources(LinkedCard(card)));
+
+                if (!GManager.instance.selectAppFusionEffect.LinkAdded)
+                {
+                    _appFusionFrameIDs = new int[0];
+
+                    yield return ContinuousController.instance.StartCoroutine(SelectCost());
+                }
+                else
+                {
+                    appFusion = true;
+                }
+
+                yield return GManager.instance.photonWaitController.StartWait("AppFuse");
+            }
+
+            #endregion
+
+            #region fix cost to pay
+
+            int Cost = 0;
+
+            if (PayCost)
+            {
+                if (!isJogress)
+                {
+                    Cost = card.GetPayingCostWithBaseCost(baseCost, Root, targetPermanents, checkAvailability: false, FixedCost: _fixedCost);
+                    Cost = card.GetPayingCostWithBaseCost(baseCost, Root, targetPermanents, checkAvailability: false, FixedCost: _fixedCost);
+                }
+                else
+                {
+                    if (card.jogressCondition.Count > 0)
+                    {
+                        Cost = card.GetPayingCostWithBaseCost(card.jogressCondition[baseDNA].cost, Root, targetPermanents, checkAvailability: false, FixedCost: _fixedCost);
+                    }
+                }
+
+                GManager.instance.memoryObject.ShowMemoryPredictionLine(card.Owner.ExpectedMemory(Cost));
+            }
+
+            #endregion
+
+            #region end play cards
+
+            bool endPlayCard = false;
+            bool playFailed = false;
+
+            if (PayCost)
+            {
+                if (Cost > card.Owner.MaxMemoryCost)
+                {
+                    endPlayCard = true;
+                    playFailed = true;
+                }
+            }
+
+            if (isEvolution)
+            {
+                if (targetPermanents != null)
+                {
+                    if (targetPermanents.Count >= 1)
+                    {
+                        foreach (Permanent permanent in targetPermanents)
+                        {
+                            if (permanent != null)
+                            {
+                                if (permanent.TopCard == null)
+                                {
+                                    endPlayCard = true;
+                                }
+                            }
+                        }
+
+                        if (!endPlayCard)
+                        {
+                            if (!isJogress && !IsBurst(card) && !IsAppFusion(card))
+                            {
+                                if (!GetIgnoreRequirement(CardEffectCommons.IgnoreRequirement.Level) && !card.CanPlayCardTargetFrame(targetPermanents[0].PermanentFrame, PayCost, CardEffect, root: Root, fixedCost: -1))
+                                {
+                                    endPlayCard = true;
+                                    playFailed = true;
+                                }
+                            }
+                            else if (isJogress)
+                            {
+                                if (!card.CanJogressFromTargetPermanents(targetPermanents, PayCost))
+                                {
+                                    endPlayCard = true;
+                                    playFailed = true;
+                                }
+                            }
+                            else if (IsBurst(card))
+                            {
+                                if (!card.CanBurstDigivolutionFromTargetPermanent(targetPermanents[0], PayCost))
+                                {
+                                    endPlayCard = true;
+                                    playFailed = true;
+                                }
+                            }
+                            else if (IsAppFusion(card))
+                            {
+                                if (!card.CanAppFusionFromTargetPermanent(targetPermanents[0], PayCost))
+                                {
+                                    endPlayCard = true;
+                                    playFailed = true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            if (endPlayCard)
+            {
+                PlayLog.OnAddLog?.Invoke($"\nFailed to play:\n{card.BaseENGCardNameFromEntity}({card.CardID})\n");
+
+                GManager.instance.GetComponent<SelectDigiXrosClass>().ResetSelectDigiXrosClass();
+                GManager.instance.GetComponent<SelectDNACondition>().ResetSelectDNAConditionClass();
+
+                GManager.instance.GetComponent<SelectAssemblyClass>().ResetSelectAssemblyClass();
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().FailedPlayCardEffect(card));
+
+                if (card.Owner.HandCards.Contains(card))
+                {
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(card));
+
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddHandCards(new List<CardSource>() { card }, false, null));
+                }
+
+                ContinuousController.instance.StartCoroutine(OffMemoryPredictionLine());
+
+                foreach (HandCard handCard in card.Owner.brainStormObject.BrainStormHandCards)
+                {
+                    if (handCard.gameObject.activeSelf && handCard.cardSource == card)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(card.Owner.brainStormObject.CloseBrainstrorm(card));
+                    }
+                }
+
+                foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+                {
+                    foreach (FieldPermanentCard fieldPermanentCard in player.FieldPermanentObjects)
+                    {
+                        if (fieldPermanentCard != null)
+                        {
+                            fieldPermanentCard.OffPermanentIndexText();
+                        }
+                    }
+                }
+
+                if (playFailed)
+                {
+                    foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+                    {
+                        foreach (Permanent permanent in player.GetFieldPermanents())
+                        {
+                            permanent.IsSuspended = permanent.oldIsTapped_playCard;
+                        }
+                    }
+
+                    foreach (CardSource cardSource in oldTrashCards)
+                    {
+                        if (!CardEffectCommons.IsExistOnTrash(cardSource))
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+                        }
+                    }
+                }
+            }
+
+            #endregion
+
+            card.Owner.UntilCalculateFixedCostEffect = new List<Func<EffectTiming, ICardEffect>>();
+
+            if (endPlayCard)
+            {
+                continue;
+            }
+
+            #region pay cost
+
+            if (PayCost)
+            {
+                // memory lose
+                if (Cost <= card.Owner.MaxMemoryCost)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(card.Owner.AddMemory(-1 * Cost, null));
+                }
+
+                ContinuousController.instance.StartCoroutine(OffMemoryPredictionLine());
+            }
+
+            #endregion
+
+            #region cut in effect after paying cost
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(hashtable, EffectTiming.AfterPayCost));
+
+            // cur in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(
+                false,
+                AutoProcessing.HasExecutedSameEffect));
+
+            #endregion
+
+            // add to played cards
+            playedCards_fixed.Add(card);
+        }
+
+        #region filter cards
+
+        List<CardSource> permanentCards = playedCards_fixed.Filter(cardSource => cardSource.IsPermanent);
+        List<CardSource> optionCards = playedCards_fixed.Filter(cardSource => !cardSource.IsPermanent);
+
+        #region play permanent
+
+        PlayPermanentClass playPermanent = new PlayPermanentClass(permanentCards, _hashtable, _targetPermanent, _isTapped, Root, _activateETB);
+
+        if (isJogress)
+        {
+            playPermanent.SetJogress(_jogressEvoRootsFrameIDs);
+        }
+
+        if (burstDigivolved)
+        {
+            playPermanent.SetBurstDigivolved();
+        }
+
+        if (appFusion)
+            playPermanent.SetAppFusion(_appFusionFrameIDs);
+
+        if (_isBreedingArea)
+        {
+            playPermanent.SetIsBreedingArea();
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(playPermanent.PlayPermanent());
+
+        #endregion
+
+        #region use option
+
+        UseOptionClass useOption = new UseOptionClass(optionCards, _hashtable, Root)
+        {
+            _showEffect = _showEffect,
+            _addSecurityEndOption = _addSecurityEndOption
+        };
+
+        yield return ContinuousController.instance.StartCoroutine(useOption.UseOption());
+
+        #endregion
+
+        #endregion
+    }
+
+    IEnumerator OffMemoryPredictionLine()
+    {
+        yield return new WaitForSeconds(0.5f);
+
+        GManager.instance.memoryObject.OffMemoryPredictionLine();
+    }
+}
+
+#endregion
+
+#region Hatch DigiEgg
+
+public class HatchDigiEggClass
+{
+    public HatchDigiEggClass(Player player, Hashtable hashtable)
+    {
+        _player = player;
+        _hashtable = hashtable;
+    }
+
+    Player _player { get; set; }
+    Hashtable _hashtable { get; set; }
+
+    public IEnumerator Hatch()
+    {
+        if (_player == null) yield break;
+        if (!_player.CanHatch) yield break;
+
+        CardSource card = _player.DigitamaLibraryCards[0];
+
+        PlayPermanentClass playPermanentClass = new PlayPermanentClass(
+        cardSources: new List<CardSource>() { card },
+        hashtable: _hashtable,
+        targetPermanent: null,
+        isTapped: false,
+        root: SelectCardEffect.Root.Library,
+        ActivateETB: true);
+
+        playPermanentClass.SetIsBreedingArea();
+        playPermanentClass.SetIsHatching();
+
+        yield return ContinuousController.instance.StartCoroutine(playPermanentClass.PlayPermanent());
+
+        if (card.PermanentOfThisCard() != null)
+        {
+            card.PermanentOfThisCard().EnterFieldTurnCount = -1;
+        }
+    }
+}
+
+#endregion
+
+#region Play permanents
+
+#region Hashtable setting class
+
+public class OnEnterFieldHashtableParams
+{
+    public OnEnterFieldHashtableParams(
+        Permanent permanent,
+        List<CardSource> evoRoots,
+        List<CardSource> evoRootTops,
+        SelectCardEffect.Root root,
+        List<int> oldLevels,
+        bool isFromDigimonDigivolutionCards)
+    {
+        Permanent = permanent;
+
+        if (evoRoots != null)
+        {
+            EvoRoots = evoRoots.Clone();
+        }
+
+        if (evoRootTops != null)
+        {
+            EvoRootTops = evoRootTops.Clone();
+        }
+
+        Root = root;
+
+        if (oldLevels != null)
+        {
+            OldLevels = oldLevels.Clone();
+        }
+
+        IsFromDigimonDigivolutionCards = isFromDigimonDigivolutionCards;
+    }
+
+    public Permanent Permanent { get; private set; } = null;
+    public List<CardSource> EvoRoots = new List<CardSource>();
+    public List<CardSource> EvoRootTops { get; private set; } = new List<CardSource>();
+    public SelectCardEffect.Root Root { get; private set; } = SelectCardEffect.Root.None;
+    public List<int> OldLevels { get; private set; } = new List<int>();
+    public bool IsFromDigimonDigivolutionCards { get; private set; } = false;
+}
+
+#endregion
+
+public class PlayPermanentClass
+{
+    public PlayPermanentClass(List<CardSource> cardSources, Hashtable hashtable, Permanent targetPermanent, bool isTapped, SelectCardEffect.Root root, bool ActivateETB)
+    {
+        if (cardSources != null)
+        {
+            _cardSources = cardSources.Filter(cardSource => cardSource != null).Clone();
+        }
+
+        _hashtable = hashtable;
+        _targetPermanent = targetPermanent;
+        _isTapped = isTapped;
+        _root = root;
+        _activateETB = ActivateETB;
+    }
+
+    public void SetJogress(int[] jogressEvoRootsFrameIDs)
+    {
+        if (jogressEvoRootsFrameIDs != null)
+        {
+            _jogressEvoRootsFrameIDs = jogressEvoRootsFrameIDs.CloneArray();
+        }
+    }
+
+    public void SetBurstDigivolved()
+    {
+        _burstDigivolved = true;
+    }
+
+    public void SetAppFusion(int[] appFusionFrameIDs)
+    {
+        if (appFusionFrameIDs != null)
+        {
+            _appFusionFrameIDs = appFusionFrameIDs.CloneArray();
+        }
+        _appFusion = true;
+    }
+
+    public void SetIsBreedingArea()
+    {
+        _isBreedingArea = true;
+    }
+
+    public void SetIsHatching()
+    {
+        _isHatching = true;
+    }
+
+    public void SetISPlayOption()
+    {
+        _isPlayOption = true;
+    }
+
+    List<CardSource> _cardSources = new List<CardSource>();
+    Hashtable _hashtable = null;
+    Permanent _targetPermanent = null;
+    bool _isTapped = false;
+    SelectCardEffect.Root _root = SelectCardEffect.Root.None;
+    bool _activateETB = true;
+    int[] _jogressEvoRootsFrameIDs = null;
+    int _digiXrosCount = 0;
+    int _assemblyCount = 0;
+    bool _burstDigivolved = false;
+    int[] _appFusionFrameIDs = null;
+    bool _appFusion = false;
+    bool _isBreedingArea = false;
+    bool _isHatching = false;
+    bool _isPlayOption = false;
+
+    public bool isJogress => _jogressEvoRootsFrameIDs != null && _jogressEvoRootsFrameIDs.Length == 2;
+
+    public bool isAppFusion => _appFusionFrameIDs != null && _appFusionFrameIDs.Length == 2;
+
+    public IEnumerator PlayPermanent()
+    {
+        List<OnEnterFieldHashtableParams> hashtableParams = new List<OnEnterFieldHashtableParams>();
+
+        ICardEffect CardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        bool isEvolution = false;
+
+        foreach (CardSource card in _cardSources)
+        {
+            yield return ContinuousController.instance.StartCoroutine(card.Owner.brainStormObject.CloseBrainstrorm(card));
+
+            if (GManager.instance.GetComponent<SelectDigiXrosClass>().playCard == card)
+            {
+                _digiXrosCount = GManager.instance.GetComponent<SelectDigiXrosClass>().selectedDigicrossCards.Count;
+            }
+
+            if (GManager.instance.GetComponent<SelectAssemblyClass>().playCard == card)
+            {
+                _assemblyCount = GManager.instance.GetComponent<SelectAssemblyClass>().selectedAssemblyCards.Count;
+            }
+
+            bool isFromDigimonDigivolutionCards = card.Owner.GetFieldPermanents().Some((permanent) => permanent.DigivolutionCards.Contains(card));
+
+            bool isFromSecurity = card.Owner.SecurityCards.Contains(card);
+
+            yield return ContinuousController.instance.StartCoroutine(card.Owner.brainStormObject.CloseBrainstrorm(card));
+
+            GManager.instance.turnStateMachine.isSync = true;
+
+            Permanent permanent = null;
+            isEvolution = false;
+            List<CardSource> evoRoots = new List<CardSource>();
+            List<CardSource> evoRootTops = new List<CardSource>();
+            bool played = false;
+            List<int> oldLevels = new List<int>();
+
+            int frameId = -1;
+
+            if (_targetPermanent == null)
+            {
+                if (_isBreedingArea)
+                {
+                    if (card.Owner.GetBreedingAreaPermanents().Count == 0)
+                    {
+                        FieldCardFrame digieggFrame = card.Owner.fieldCardFrames.Find(fieldCardFrame =>
+                        fieldCardFrame.IsEmptyFrame() &&
+                        !fieldCardFrame.IsBattleAreaFrame());
+
+                        if (digieggFrame != null)
+                        {
+                            if (_isHatching)
+                                frameId = digieggFrame.FrameID;
+                            else if(card.CanPlayCardTargetFrame(digieggFrame, false, CardEffect, isBreedingArea: _isBreedingArea))
+                                    frameId = digieggFrame.FrameID;
+                        }
+                    }
+                }
+                else
+                {
+                    FieldCardFrame preferredFrame = card.PreferredFrame();
+
+                    if (preferredFrame != null)
+                    {
+                        frameId = preferredFrame.FrameID;
+                    }
+                }
+            }
+            else
+            {
+                frameId = _targetPermanent.PermanentFrame.FrameID;
+            }
+
+            if (!isJogress)
+            {
+                if (!(0 <= frameId && frameId < card.Owner.fieldCardFrames.Count))
+                {
+                    foreach (FieldCardFrame fieldCardFrame in card.Owner.fieldCardFrames)
+                    {
+                        if (card.CanPlayCardTargetFrame(fieldCardFrame, false, CardEffect, isBreedingArea: _isBreedingArea))
+                        {
+                            if (fieldCardFrame.IsEmptyFrame())
+                            {
+                                frameId = fieldCardFrame.FrameID;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if (0 <= frameId && frameId < card.Owner.fieldCardFrames.Count)
+                {
+                    played = true;
+
+                    if (_targetPermanent != null)
+                    {
+                        isEvolution = true;
+                    }
+                    else
+                    {
+                        if (!CardEffectCommons.CanPlayAsNewPermanent(card, false, CardEffect, isBreedingArea: _isBreedingArea, isPlayOption: _isPlayOption))
+                        {
+                            played = false;
+                        }
+
+                        if(_isHatching)
+                            played = _isHatching;
+                    }
+
+                    if (played)
+                    {
+                        card.Init();
+
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(card));
+
+                        if (isEvolution)
+                        {
+                            oldLevels.Add(_targetPermanent.Level);
+
+                            PlayLog.OnAddLog?.Invoke($"\nEvolution:\n{card.BaseENGCardNameFromEntity}({card.CardID})\n");
+
+                            permanent = _targetPermanent;
+                            evoRoots.Add(_targetPermanent.TopCard);
+                            evoRootTops.Add(_targetPermanent.TopCard);
+                            permanent.AddCardSource(card);
+                        }
+                        else
+                        {
+                            if (card.IsToken)
+                                PlayLog.OnAddLog?.Invoke($"\nPlay on field:\n{card.BaseENGCardNameFromEntity} token\n");
+                            else
+                                PlayLog.OnAddLog?.Invoke($"\nPlay on field:\n{card.BaseENGCardNameFromEntity}({card.CardID})\n");
+
+                            permanent = new Permanent(new List<CardSource>() { card }) { IsSuspended = _isTapped };
+
+                            yield return ContinuousController.instance.StartCoroutine(CardObjectController.CreateNewPermanent(permanent, frameId));
+                            permanent.EnterFieldTurnCount = GManager.instance.turnStateMachine.TurnCount;
+                        }
+
+                        GManager.instance.turnStateMachine.isSync = true;
+
+                        if (GManager.instance.turnStateMachine.DoneStartGame)
+                        {
+                            if (!isEvolution)
+                            {
+                                #region wheter to have ETB effects
+
+                                Hashtable hashtable = CardEffectCommons.OnEnterFieldHashtable(
+                                hashtableParams: new List<OnEnterFieldHashtableParams>()
+                                {
+                                    new OnEnterFieldHashtableParams(
+                                        permanent: permanent,
+                                        evoRoots: evoRoots,
+                                        evoRootTops: evoRootTops,
+                                        root: _root,
+                                        oldLevels: oldLevels,
+                                        isFromDigimonDigivolutionCards:isFromDigimonDigivolutionCards
+                                    )
+                                },
+                                isEvolution: isEvolution,
+                                isJogress: isJogress,
+                                digiXrosCount: _digiXrosCount,
+                                assemblyCount: _assemblyCount,
+                                cardEffect: CardEffect);
+
+                                bool HasETB = permanent.EffectList(EffectTiming.OnEnterFieldAnyone).Some(cardEffect =>
+                                cardEffect is ActivateICardEffect && cardEffect.CanUse(hashtable) && _activateETB && cardEffect.IsOnPlay);
+
+                                #endregion
+
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateFieldPermanentCardEffect(permanent.ShowingPermanentCard, HasETB: HasETB, isDigiXros: _digiXrosCount >= 1));
+                            }
+                            else
+                            {
+                                bool isBlast = CardEffect != null && CardEffect.EffectName != null && CardEffect.EffectName.Contains("Blast");
+                                //effect
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().DigivolveFieldPermanentCardEffect(permanent.ShowingPermanentCard, _burstDigivolved, isBlast, _appFusion));
+                            }
+                        }
+                    }
+                }
+            }
+            else
+            {
+                if (_jogressEvoRootsFrameIDs.Length == 2)
+                {
+                    played = true;
+
+                    card.Init();
+
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(card));
+
+                    isEvolution = true;
+
+                    List<Permanent> evoRootPermanents = new List<Permanent>();
+
+                    for (int i = 0; i < _jogressEvoRootsFrameIDs.Length; i++)
+                    {
+                        int frameID = _jogressEvoRootsFrameIDs[i];
+                        Permanent evoRoot = card.Owner.fieldCardFrames[frameID].GetFramePermanent();
+
+                        if (evoRoot != null)
+                        {
+                            if (evoRoot.TopCard != null)
+                            {
+                                evoRootPermanents.Add(evoRoot);
+                            }
+                        }
+                    }
+
+                    int targetFrameID = evoRootPermanents[0].PermanentFrame.FrameID;
+
+                    foreach (Permanent evoRootPermanent in evoRootPermanents)
+                    {
+                        evoRoots.Add(evoRootPermanent.TopCard);
+                    }
+
+                    List<CardSource> newDigivolutionCards = evoRootPermanents
+                        .Map(evoRootPermanent => evoRootPermanent.StackCards)
+                        .Flat();
+
+                    List<CardSource> linkCards = evoRootPermanents
+                        .Map(evoRootPermanent => evoRootPermanent.LinkedCards)
+                        .Flat();
+
+                    foreach (Permanent evoRootPermanent in evoRootPermanents)
+                    {
+                        oldLevels.Add(evoRootPermanent.Level);
+
+                        evoRootTops.Add(evoRootPermanent.TopCard);
+                    }
+
+                    foreach (Permanent evoRootPermanent in evoRootPermanents)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(evoRootPermanent.DiscardEvoRoots(ignoreOverflow: true, putToTrash: false));
+
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(evoRootPermanent, ignoreOverflow: true));
+                    }
+
+                    foreach(CardSource linkCard in linkCards)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(linkCard));
+                    }
+
+                    PlayLog.OnAddLog?.Invoke($"\nJogress:\n{card.BaseENGCardNameFromEntity}({card.CardID})\n");
+
+                    permanent = new Permanent(new List<CardSource>() { card }) { IsSuspended = false };
+
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.CreateNewPermanent(permanent, targetFrameID));
+                    permanent.EnterFieldTurnCount = -1;
+
+                    newDigivolutionCards.Reverse();
+
+                    yield return ContinuousController.instance.StartCoroutine(permanent.AddDigivolutionCardsTop(newDigivolutionCards, null));
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateFieldPermanentCardEffect(permanent.ShowingPermanentCard, isDigiXros: false, jogressEvoRoots: evoRootTops.ToArray()));
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(evoRootTops, "DNA Digivolution Cards", true, true));
+
+                    foreach (CardSource evolutionCard in permanent.DigivolutionCards)
+                    {
+                        evolutionCard.cEntity_EffectController.InitUseCountThisTurn();
+                    }
+                }
+            }
+
+            if (played)
+            {
+                if (isFromSecurity)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(new IReduceSecurity(
+                        player: card.Owner,
+                        refSkillInfos: ref ContinuousController.instance.nullSkillInfos,
+                        CardEffectCommons.GetCardEffectFromHashtable(_hashtable)).ReduceSecurity());
+                }
+
+                if (isEvolution)
+                {
+                    card.Owner.DigivolveCount_ThisTurn++;
+                    yield return ContinuousController.instance.StartCoroutine(new DrawClass(card.Owner, 1, null).Draw());
+
+                    if (_burstDigivolved)
+                    {
+                        if (permanent.TopCard != null)
+                        {
+                            permanent.IsBurstDigivolved = true;
+
+                            GManager.instance.selectBurstDigivolutionEffect.AddTrashTopCardAtTurnEnd(permanent);
+                        }
+                    }
+
+                    if (_appFusion)
+                    {
+                        if (permanent.TopCard != null)
+                        {
+                            permanent.IsAppFusion = true;
+                        }
+                    }
+
+                    permanent.CardNamesJustAfterDigivolved = permanent.TopCard.CardNames.Clone();
+
+                    permanent.DigivolvingEffect = CardEffect;
+                }
+                else
+                {
+                    permanent.PlayingEffect = CardEffect;
+
+                    if (permanent.TopCard.HasLevel)
+                    {
+                        permanent.LevelJustAfterPlayed = permanent.Level;
+                    }
+
+                    if (permanent.TopCard.HasPlayCost)
+                    {
+                        permanent.PlayCostJustAfterPlayed = permanent.TopCard.GetCostItself;
+                    }
+
+                    permanent.CardNamesJustAfterPlayed = permanent.TopCard.CardNames.Clone();
+
+                    permanent.TraitsJustAfterPlayed = permanent.TopCard.CardTraits.Clone();
+                }
+
+                #region move permanents (hybrid)
+
+                if (CardEffectCommons.IsPermanentExistsOnBattleArea(permanent))
+                {
+                    if (permanent.TopCard.PreferredFrame() != null)
+                    {
+                        if (permanent.PermanentFrame != permanent.TopCard.PreferredFrame())
+                        {
+                            if (permanent.TopCard.PreferredFrame().IsEmptyFrame())
+                            {
+                                bool move = false;
+
+                                if (permanent.IsDigimon)
+                                {
+                                    if (permanent.TopCard.Owner.isYou)
+                                    {
+                                        if (permanent.TopCard.PreferredFrame().Frame.transform.parent.localPosition.y > permanent.PermanentFrame.Frame.transform.parent.localPosition.y + 5)
+                                        {
+                                            move = true;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        if (permanent.TopCard.PreferredFrame().Frame.transform.parent.localPosition.y < permanent.PermanentFrame.Frame.transform.parent.localPosition.y - 5)
+                                        {
+                                            move = true;
+                                        }
+                                    }
+                                }
+                                else if (permanent.IsTamer || permanent.TopCard.IsOption)
+                                {
+                                    if (permanent.TopCard.Owner.isYou)
+                                    {
+                                        if (permanent.TopCard.PreferredFrame().Frame.transform.parent.localPosition.y < permanent.PermanentFrame.Frame.transform.parent.localPosition.y - 5)
+                                        {
+                                            move = true;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        if (permanent.TopCard.PreferredFrame().Frame.transform.parent.localPosition.y > permanent.PermanentFrame.Frame.transform.parent.localPosition.y + 5)
+                                        {
+                                            move = true;
+                                        }
+                                    }
+                                }
+
+                                if (move)
+                                {
+                                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.MovePermanent(permanent.PermanentFrame));
+                                }
+                            }
+                        }
+                    }
+                }
+
+                #endregion
+
+                yield return GManager.instance.GetComponent<SelectDigiXrosClass>().AddDigivolutiuonCardsByEffect(card);
+                yield return GManager.instance.GetComponent<SelectDigiXrosClass>().AddDigivolutiuonCards(card);
+
+                yield return GManager.instance.GetComponent<SelectAssemblyClass>().AddDigivolutiuonCardsByEffect(card);
+                yield return GManager.instance.GetComponent<SelectAssemblyClass>().AddDigivolutiuonCards(card);
+
+                if (GManager.instance.turnStateMachine.DoneStartGame)
+                {
+                    hashtableParams.Add(
+                        new OnEnterFieldHashtableParams(
+                            permanent: permanent,
+                            evoRoots: evoRoots,
+                            evoRootTops: evoRootTops,
+                            root: _root,
+                            oldLevels: oldLevels,
+                            isFromDigimonDigivolutionCards: isFromDigimonDigivolutionCards
+                            )
+                    );
+                }
+            }
+
+            GManager.instance.GetComponent<SelectDNACondition>().ResetSelectDNAConditionClass();
+            GManager.instance.GetComponent<SelectDigiXrosClass>().ResetSelectDigiXrosClass();
+            GManager.instance.GetComponent<SelectAssemblyClass>().ResetSelectAssemblyClass();
+
+            yield return GManager.instance.photonWaitController.StartWait("EndPlayPermanent");
+        }
+
+
+        // except [On Play] effect
+        bool CardEffectCondition(ICardEffect cardEffect)
+        {
+            if (cardEffect == null)
+            {
+                return false;
+            }
+
+            if (!_activateETB)
+            {
+                if (cardEffect is ActivateICardEffect)
+                {
+                    if (cardEffect.IsOnPlay)
+                    {
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        Hashtable effectHashtable = CardEffectCommons.OnEnterFieldHashtable(
+            hashtableParams: hashtableParams,
+            isEvolution: isEvolution,
+            isJogress: isJogress,
+            digiXrosCount: _digiXrosCount,
+            assemblyCount: _assemblyCount,
+            cardEffect: CardEffect);
+
+        #region "When permanents are played" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(
+            hashtable: effectHashtable,
+            timing: EffectTiming.OnEnterFieldAnyone,
+            cardEffectCondition: CardEffectCondition));
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Use option
+
+public class UseOptionClass
+{
+    public UseOptionClass(List<CardSource> cardSources, Hashtable hashtable, SelectCardEffect.Root root)
+    {
+        if (cardSources != null)
+        {
+            _cardSources = cardSources.Filter(cardSource => cardSource != null).Clone();
+        }
+
+        _hashtable = hashtable;
+        _root = root;
+    }
+
+    List<CardSource> _cardSources = new List<CardSource>();
+    SelectCardEffect.Root _root = SelectCardEffect.Root.None;
+    Hashtable _hashtable = null;
+    public bool _showEffect = false;
+    public bool _addSecurityEndOption = false;
+
+    public IEnumerator UseOption()
+    {
+        ICardEffect CardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        foreach (CardSource card in _cardSources)
+        {
+            if (_showEffect)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().DeleteHandCardEffectCoroutine(card));
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowUseHandCardEffect_PlayCard(card));
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(card));
+            }
+
+            PlayLog.OnAddLog?.Invoke($"\nPlay Option:\n{card.BaseENGCardNameFromEntity}({card.CardID})\n");
+
+            card.Init();
+
+            GManager.instance.turnStateMachine.isSync = true;
+
+            card.SetFace();
+
+            int cost = card.GetCostItself;
+
+            //Remove from all areas
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(card));
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddExecutingCard(card));
+
+            yield return ContinuousController.instance.StartCoroutine(card.Owner.brainStormObject.BrainStormCoroutine(card));
+
+            #region Set HashTable
+
+            Hashtable hashtable = new Hashtable()
+        {
+            {"Card", card},
+            {"Root", _root},
+            {"Cost", cost},
+        };
+
+            #endregion
+
+            #region "When option is used" effect
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnUseOption));
+
+            yield return ContinuousController.instance.StartCoroutine(AutoProcessing.ActivateBackgroundEffects(hashtable, EffectTiming.OnUseOption));
+
+            #endregion
+
+            #region effect process of option card
+
+            foreach (ICardEffect cardEffect in card.EffectList(EffectTiming.OptionSkill))
+            {
+                if (cardEffect is ActivateICardEffect)
+                {
+                    if (cardEffect.CanUse(hashtable))
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.ActivateEffectProcess(
+                                                    cardEffect,
+                                                    hashtable));
+                    }
+                }
+            }
+
+            #endregion
+
+            if (card.Owner.ExecutingCards.Contains(card))
+            {
+                if (_addSecurityEndOption && card.Owner.CanAddSecurity(CardEffect))
+                {
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddSecurityCard(card));
+                }
+                else
+                {
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(card));
+                }
+            }
+
+            yield return ContinuousController.instance.StartCoroutine(card.Owner.brainStormObject.CloseBrainstrorm(card));
+
+            yield return GManager.instance.photonWaitController.StartWait("EndPlayOption");
+        }
+    }
+}
+
+#endregion
+
+#region Draw cards
+
+public class DrawClass
+{
+    public DrawClass(Player player, int drawCount, ICardEffect cardEffect)
+    {
+        _player = player;
+        _drawCount = drawCount;
+        _cardEffect = cardEffect;
+    }
+
+    Player _player = null;
+    int _drawCount = 0;
+    ICardEffect _cardEffect = null;
+
+    public IEnumerator Draw()
+    {
+        if (_drawCount <= 0) yield break;
+        if (_player.LibraryCards.Count <= 0) yield break;
+
+        List<CardSource> DrawCards = new List<CardSource>();
+
+        for (int i = 0; i < _drawCount; i++)
+        {
+            if (_player.LibraryCards.Count > 0)
+            {
+                CardSource DrawCard = _player.LibraryCards[0];
+
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(DrawCard));
+
+                DrawCards.Add(DrawCard);
+            }
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddHandCards(DrawCards, true, _cardEffect));
+
+        #region add log
+
+        if (DrawCards.Count >= 1)
+        {
+            PlayLog.OnAddLog?.Invoke($"\nDraw {DrawCards.Count} card{Utils.PluralFormSuffix(DrawCards.Count)}\n{_player.PlayerName}\n");
+        }
+
+        #endregion
+
+        #region "When draw cards" effect
+
+        if (DrawCards.Count >= 1)
+        {
+            #region Hashtable setting
+
+            Hashtable _hashtable = new Hashtable()
+            {
+                {"Player", _player},
+                {"CardEffect", _cardEffect}
+            };
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(_hashtable, EffectTiming.OnDraw));
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Trash cards from deck too
+
+public class IAddTrashCardsFromLibraryTop
+{
+    public IAddTrashCardsFromLibraryTop(int addTrashCount, Player player, ICardEffect cardEffect)
+    {
+        _addTrashCount = addTrashCount;
+        _player = player;
+        _cardEffect = cardEffect;
+    }
+
+    public void SetNotShowCards()
+    {
+        _notShowCards = true;
+    }
+
+    int _addTrashCount;
+    Player _player;
+    public List<CardSource> discardedCards = new List<CardSource>();
+    ICardEffect _cardEffect { get; set; } = null;
+    bool _notShowCards = false;
+
+    public IEnumerator AddTrashCardsFromLibraryTop()
+    {
+        if (_addTrashCount <= 0) yield break;
+        if (_player.LibraryCards.Count == 0) yield break;
+
+        string log = "";
+
+        log += $"\nTrash cards from deck :";
+
+        for (int i = 0; i < _addTrashCount; i++)
+        {
+            if (_player.LibraryCards.Count > i)
+            {
+                CardSource DiscardCard = _player.LibraryCards[i];
+
+                discardedCards.Add(DiscardCard);
+
+                log += $"\n{DiscardCard.BaseENGCardNameFromEntity}({DiscardCard.CardID})";
+            }
+        }
+
+        if (discardedCards.Count >= 1)
+        {
+            if (!_notShowCards)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(discardedCards, "Discarded Cards", true, true));
+            }
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(new ITrashDeckCards(discardedCards, _cardEffect).TrashDeckCards());
+
+        if (discardedCards.Count >= 1)
+        {
+            for (int i = 0; i < discardedCards.Count; i++)
+            {
+                ContinuousController.instance.PlaySE(GManager.instance.DrawSE);
+                yield return new WaitForSeconds(0.06f);
+            }
+
+            log += "\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+    }
+}
+
+#endregion
+
+#region Add security from deck top
+
+public class IAddSecurityFromLibrary
+{
+    public IAddSecurityFromLibrary(Player player, int addLifeCount)
+    {
+        _player = player;
+        _addSecurityCount = addLifeCount;
+    }
+
+    Player _player = null;
+    int _addSecurityCount = 0;
+
+    public IEnumerator AddSecurity()
+    {
+        int count = 0;
+
+        for (int i = 0; i < _addSecurityCount; i++)
+        {
+            if (_player.LibraryCards.Count > 0)
+            {
+                CardSource StockCard = _player.LibraryCards[0];
+
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddSecurityCard(StockCard, useEffect: (i == 0)));
+
+                count++;
+            }
+        }
+
+        if (count > 0)
+        {
+            string log = "";
+
+            log += $"\nAdd {count} cards to security:{_player.PlayerName}";
+
+            log += "\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+    }
+}
+
+#endregion
+
+#region Recovery
+
+public class IRecovery
+{
+    public IRecovery(Player player, int AddLifeCount, ICardEffect cardEffect)
+    {
+        _player = player;
+        _addLifeCount = AddLifeCount;
+        _cardEffect = cardEffect;
+    }
+
+    Player _player = null;
+    int _addLifeCount = 0;
+    ICardEffect _cardEffect = null;
+
+    public IEnumerator Recovery()
+    {
+        if (_player.LibraryCards.Count == 0) yield break;
+        if (_addLifeCount <= 0) yield break;
+        if (!_player.CanAddSecurity(_cardEffect)) yield break;
+
+        yield return ContinuousController.instance.StartCoroutine(new IAddSecurityFromLibrary(_player, _addLifeCount).AddSecurity());
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateRecoveryEffect(_player));
+    }
+}
+
+#endregion
+
+#region Digi-Burst
+
+public class IDigiBurst
+{
+    public IDigiBurst(Permanent permanent, int DigiBurstCount, ICardEffect cardEffect)
+    {
+        _permanent = permanent;
+        _digiBurstCount = DigiBurstCount;
+        _cardEffect = cardEffect;
+    }
+
+    Permanent _permanent = null;
+    int _digiBurstCount = 0;
+    ICardEffect _cardEffect = null;
+    bool _upToMaxCount = false;
+
+    public List<CardSource> discardedCards = new List<CardSource>();
+
+    public void SetUpToMaxCount()
+    {
+        _upToMaxCount = true;
+    }
+
+    public bool CanDigiBurst()
+    {
+        if (_permanent != null)
+        {
+            if (_permanent.TopCard != null)
+            {
+                if (_permanent.ImmuneFromStackTrashing(_cardEffect)) return false;
+
+                if (_upToMaxCount)
+                {
+                    if (_permanent.DigivolutionCards.Some((cardSource) => !cardSource.CanNotTrashFromDigivolutionCards(_cardEffect)))
+                    {
+                        return true;
+                    }
+                }
+                else
+                {
+                    if (_permanent.DigivolutionCards.Count((cardSource) => !cardSource.CanNotTrashFromDigivolutionCards(_cardEffect)) >= _digiBurstCount)
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public IEnumerator DigiBurst()
+    {
+        if (CanDigiBurst())
+        {
+            discardedCards = new List<CardSource>();
+
+            List<CardSource> selectedCards = new List<CardSource>();
+
+            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+            selectCardEffect.SetUp(
+                        canTargetCondition: (cardSource) => !cardSource.CanNotTrashFromDigivolutionCards(_cardEffect),
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: CanEndSelectCondition,
+                        canNoSelect: () => false,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        message: "Select digivolution cards to discard.",
+                        maxCount: _digiBurstCount,
+                        canEndNotMax: _upToMaxCount,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.Custom,
+                        root: SelectCardEffect.Root.Custom,
+                        customRootCardList: _permanent.DigivolutionCards,
+                        canLookReverseCard: true,
+                        selectPlayer: _permanent.TopCard.Owner,
+                        cardEffect: null);
+
+            selectCardEffect.SetUseFaceDown();
+
+            selectCardEffect.SetUpCustomMessage("Select digivolution cards to discard.", "The opponent is selecting digivolution cards to discard.");
+
+            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+
+            bool CanEndSelectCondition(List<CardSource> cardSources)
+            {
+                if (CardEffectCommons.HasNoElement(cardSources))
+                {
+                    return false;
+                }
+
+                return true;
+            }
+
+            IEnumerator SelectCardCoroutine(CardSource cardSource)
+            {
+                selectedCards.Add(cardSource);
+
+                yield return null;
+            }
+
+            if (selectedCards.Count >= 1)
+            {
+                #region "When use Digi-Burst" effect
+
+                #region Hashtable setting
+
+                Hashtable hashtable = new Hashtable()
+                {
+                    {"Permanent", _permanent},
+                    {"CardEffect", _cardEffect},
+                };
+
+                #endregion
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnUseDigiburst));
+
+                #endregion
+
+                // trash digivolution cards
+                yield return ContinuousController.instance.StartCoroutine(new ITrashDigivolutionCards(_permanent, selectedCards, _cardEffect).TrashDigivolutionCards());
+
+                foreach (CardSource cardSource in selectedCards)
+                {
+                    discardedCards.Add(cardSource);
+                }
+
+                #region add log
+
+                if (selectedCards.Count >= 1)
+                {
+                    string log = "";
+
+                    log += $"\nDigiburst :";
+
+                    foreach (CardSource cardSource in selectedCards)
+                    {
+                        if (cardSource != null)
+                        {
+                            log += $"\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})";
+                        }
+                    }
+
+                    log += "\n";
+
+                    PlayLog.OnAddLog?.Invoke(log);
+                }
+
+                #endregion
+            }
+        }
+    }
+}
+
+#endregion
+
+#region Place permanents to deck bottom
+
+public class DeckBottomBounceClass
+{
+    public DeckBottomBounceClass(List<Permanent> deckBounceTargetPermanents, Hashtable hashtable)
+    {
+        _deckBounceTargetPermanents = deckBounceTargetPermanents.Clone();
+
+        _hashtable = hashtable;
+    }
+
+    public void SetNotShowCards()
+    {
+        _notShowCards = true;
+    }
+
+    public bool IsDeckBounced(Permanent permanent)
+    {
+        return DeckBouncedPermanents.Contains(permanent);
+    }
+
+    List<Permanent> _deckBounceTargetPermanents = new List<Permanent>();
+    public List<Permanent> DeckBouncedPermanents { get; private set; } = new List<Permanent>();
+    Hashtable _hashtable = new Hashtable();
+    bool _notShowCards = false;
+
+    public IEnumerator DeckBounce()
+    {
+        if (_deckBounceTargetPermanents == null) yield break;
+
+        ICardEffect cardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        _deckBounceTargetPermanents = _deckBounceTargetPermanents.Filter(permanent =>
+        permanent != null
+        && permanent.TopCard != null
+        && (cardEffect == null ||
+        (!permanent.TopCard.CanNotBeAffected(cardEffect)
+        && !permanent.CannotReturnToLibrary(cardEffect)
+        && permanent.CanBeRemoved())));
+
+        if (_deckBounceTargetPermanents.Count == 0) yield break;
+
+        _deckBounceTargetPermanents.ForEach(permanent => permanent.willBeRemoveField = true);
+
+        #region cut in effect
+
+        // "When permanents would return to deck" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _deckBounceTargetPermanents,
+                cardEffect,
+                null
+            ),
+            EffectTiming.WhenReturntoLibraryAnyone));
+
+        // "When permanents would remove field" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _deckBounceTargetPermanents,
+                cardEffect,
+                null
+            ),
+            EffectTiming.WhenRemoveField));
+
+        if (GManager.instance.autoProcessing_CutIn.HasAwaitingActivateEffects())
+        {
+            foreach (Permanent permanent in _deckBounceTargetPermanents)
+            {
+                permanent.ShowDeckBounceEffect();
+            }
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, null));
+
+            foreach (Permanent permanent in _deckBounceTargetPermanents)
+            {
+                permanent.HideDeckBounceEffect();
+            }
+        }
+
+        #endregion
+
+        // fix deck bounce target permanents
+        List<Permanent> deckBounceTargetPermanents_Fixed = _deckBounceTargetPermanents.Filter(permanent =>
+        permanent != null
+        && permanent.TopCard != null
+        && permanent.willBeRemoveField);
+
+        #region show cards
+
+        List<CardSource> returnedCards = deckBounceTargetPermanents_Fixed.Map(permanent => permanent.TopCard);
+
+        if (!_notShowCards)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(returnedCards, "Deck bottom cards", true, true));
+        }
+
+        #endregion
+
+        #region
+
+        List<CardSource> deckBottomCards = new List<CardSource>();
+
+        foreach (Permanent permanent in deckBounceTargetPermanents_Fixed)
+        {
+            #region recoed used effect
+
+            if (permanent.TopCard != null)
+            {
+                permanent.LibraryBounceEffect = cardEffect;
+            }
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().DeckBounceEffect(permanent));
+
+            yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
+
+            CardSource topCard = permanent.TopCard;
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
+
+            deckBottomCards.Add(topCard);
+
+            DeckBouncedPermanents.Add(permanent);
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddLibraryBottomCards(deckBottomCards));
+
+        #endregion
+
+        #region off icon
+
+        foreach (Permanent permanent in _deckBounceTargetPermanents)
+        {
+            if (permanent != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    permanent.willBeRemoveField = false;
+                }
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Place permanents to deck top
+
+public class DeckTopBounceClass
+{
+    public DeckTopBounceClass(List<Permanent> deckBounceTargetPermanents, Hashtable hashtable)
+    {
+        _deckBounceTargetPermanents = deckBounceTargetPermanents.Clone();
+
+        _hashtable = hashtable;
+    }
+
+    public void SetNotShowCards()
+    {
+        _notShowCards = true;
+    }
+
+    public bool IsDeckBounced(Permanent permanent)
+    {
+        return DeckBouncedPermanents.Contains(permanent);
+    }
+
+    List<Permanent> _deckBounceTargetPermanents = new List<Permanent>();
+    public List<Permanent> DeckBouncedPermanents { get; private set; } = new List<Permanent>();
+    Hashtable _hashtable = new Hashtable();
+    bool _notShowCards = false;
+
+    public IEnumerator DeckBounce()
+    {
+        if (_deckBounceTargetPermanents == null) yield break;
+
+        ICardEffect cardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        _deckBounceTargetPermanents = _deckBounceTargetPermanents.Filter(permanent =>
+        permanent != null
+        && permanent.TopCard != null
+        && (cardEffect == null ||
+        (!permanent.TopCard.CanNotBeAffected(cardEffect)
+        && !permanent.CannotReturnToLibrary(cardEffect)
+        && permanent.CanBeRemoved())));
+
+        if (_deckBounceTargetPermanents.Count == 0) yield break;
+
+        _deckBounceTargetPermanents.ForEach(permanent => permanent.willBeRemoveField = true);
+
+        #region cut in effect
+
+        // "When permanents would return to deck" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _deckBounceTargetPermanents,
+                cardEffect,
+                null
+            ),
+            EffectTiming.WhenReturntoLibraryAnyone));
+
+        // "When permanents would remove field" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _deckBounceTargetPermanents,
+                cardEffect,
+                null
+            ),
+            EffectTiming.WhenRemoveField));
+
+        if (GManager.instance.autoProcessing_CutIn.HasAwaitingActivateEffects())
+        {
+            foreach (Permanent permanent in _deckBounceTargetPermanents)
+            {
+                permanent.ShowDeckBounceEffect();
+            }
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, null));
+
+            foreach (Permanent permanent in _deckBounceTargetPermanents)
+            {
+                permanent.HideDeckBounceEffect();
+            }
+        }
+
+        #endregion
+
+        // fix deck bounce target permanents
+        List<Permanent> deckBounceTargetPermanents_Fixed = _deckBounceTargetPermanents.Filter(permanent =>
+        permanent != null
+        && permanent.TopCard != null
+        && permanent.willBeRemoveField);
+
+        #region show cards
+
+        List<CardSource> returnedCards = deckBounceTargetPermanents_Fixed.Map(permanent => permanent.TopCard);
+
+        if (!_notShowCards)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(returnedCards, "Deck bottom cards", true, true));
+        }
+
+        #endregion
+
+        #region
+
+        List<CardSource> deckTopCards = new List<CardSource>();
+
+        foreach (Permanent permanent in deckBounceTargetPermanents_Fixed)
+        {
+            #region recoed used effect
+
+            if (permanent.TopCard != null)
+            {
+                permanent.LibraryBounceEffect = cardEffect;
+            }
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().DeckBounceEffect(permanent));
+
+            yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
+
+            CardSource topCard = permanent.TopCard;
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
+
+            deckTopCards.Add(topCard);
+
+            DeckBouncedPermanents.Add(permanent);
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddLibraryTopCards(deckTopCards));
+
+        #endregion
+
+        #region off icon
+
+        foreach (Permanent permanent in _deckBounceTargetPermanents)
+        {
+            if (permanent != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    permanent.willBeRemoveField = false;
+                }
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Return permanent to hand
+
+public class HandBounceClaass
+{
+    public HandBounceClaass(List<Permanent> bounceTargetPermanents, Hashtable hashtable)
+    {
+        _bounceTargetPermanents = bounceTargetPermanents.Clone().Filter(CardEffectCommons.IsPermanentExistsOnBattleArea);
+
+        _hashtable = hashtable;
+    }
+
+    public bool IsBounced(Permanent permanent)
+    {
+        return BouncedPermanents.Contains(permanent);
+    }
+
+    List<Permanent> _bounceTargetPermanents = new List<Permanent>();
+    public List<Permanent> BouncedPermanents { get; private set; } = new List<Permanent>();
+    Hashtable _hashtable = new Hashtable();
+    bool _notShowCards = false;
+
+    public IEnumerator Bounce()
+    {
+        if (_bounceTargetPermanents == null) yield break;
+
+        ICardEffect cardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        _bounceTargetPermanents = _bounceTargetPermanents.Filter(permanent =>
+        permanent != null
+        && permanent.TopCard != null
+        && (cardEffect == null ||
+        (!permanent.TopCard.CanNotBeAffected(cardEffect)
+        && !permanent.CannotReturnToHand(cardEffect)
+        && permanent.CanBeRemoved())));
+
+        if (_bounceTargetPermanents.Count == 0) yield break;
+
+        _bounceTargetPermanents.ForEach(permanent => permanent.willBeRemoveField = true);
+
+        #region cut in effect
+
+        // "When permanents would return to hand" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _bounceTargetPermanents,
+                cardEffect,
+                null
+            ),
+            EffectTiming.WhenReturntoHandAnyone));
+
+        // "When permanents would remove field" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _bounceTargetPermanents,
+                cardEffect,
+                null
+            ),
+            EffectTiming.WhenRemoveField));
+
+        if (GManager.instance.autoProcessing_CutIn.HasAwaitingActivateEffects())
+        {
+            foreach (Permanent permanent in _bounceTargetPermanents)
+            {
+                permanent.ShowHandBounceEffect();
+            }
+
+            // shrink security Digimon display
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.ShrinkSecurityDigimonDisplay());
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, null));
+
+            foreach (Permanent permanent in _bounceTargetPermanents)
+            {
+                permanent.HideHandBounceEffect();
+            }
+        }
+
+        #endregion
+
+        // fix bounce target permanents
+        List<Permanent> bounceTargetPermanents_Fixed = _bounceTargetPermanents.Filter(permanent =>
+        permanent != null
+        && permanent.TopCard != null
+        && permanent.willBeRemoveField);
+
+        #region "When permanents returned to hand" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing
+            .StackSkillInfos(CardEffectCommons.OnDeletionHashtable(
+                bounceTargetPermanents_Fixed,
+                cardEffect,
+                null,
+                false
+                ),
+                EffectTiming.OnPermamemtReturnedToHand));
+
+        #endregion
+
+        #region record parameter just before bounce
+
+        foreach (Permanent permanent in bounceTargetPermanents_Fixed)
+        {
+            permanent.DPJustBeforeRemoveField = permanent.DP;
+
+            if (permanent.TopCard.HasLevel)
+            {
+                permanent.LevelJustBeforeRemoveField = permanent.Level;
+            }
+
+            if (permanent.TopCard.HasPlayCost)
+            {
+                permanent.CostJustBeforeRemoveField = permanent.TopCard.GetCostItself;
+            }
+
+            permanent.CardNamesJustBeforeRemoveField = new List<string>(permanent.TopCard.CardNames);
+            permanent.CardTraitsJustBeforeRemoveField = new List<string>(permanent.TopCard.CardTraits);
+
+            foreach (CardSource cardSource in permanent.cardSources)
+            {
+                cardSource.PermanentJustBeforeRemoveField = permanent;
+            }
+        }
+
+        #endregion
+
+        #region add log
+
+        if (bounceTargetPermanents_Fixed.Count >= 1)
+        {
+            string log = "";
+
+            log += $"\nReturn to hand:";
+
+            foreach (Permanent permanent in bounceTargetPermanents_Fixed)
+            {
+                log += $"\n{permanent.TopCard.BaseENGCardNameFromEntity}({permanent.TopCard.CardID})";
+            }
+
+            log += "\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+
+        #endregion
+
+        #region show cards
+
+        List<CardSource> returnedCards = bounceTargetPermanents_Fixed.Map(permanent => permanent.TopCard);
+
+        if (!_notShowCards)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(returnedCards, "Cards returned to hand", true, true));
+        }
+
+        #endregion
+
+        #region return permanent cards to hand
+
+        List<CardSource> handCards = new List<CardSource>();
+
+        foreach (Permanent permanent in bounceTargetPermanents_Fixed)
+        {
+            #region record used effect
+
+            if (permanent.TopCard != null)
+            {
+                permanent.HandBounceEffect = cardEffect;
+            }
+
+            #endregion
+
+            // record whether to return to hand by Burst Digivolution
+            permanent.IsReturnedToHandByBurstDigivolution = CardEffectCommons.IsBurst(_hashtable);
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().BounceEffect(permanent, !permanent.IsReturnedToHandByBurstDigivolution));
+
+            yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
+
+            CardSource topCard = permanent.TopCard;
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(topCard));
+
+            if (!topCard.IsDigiEgg)
+            {
+                handCards.Add(topCard);
+
+                BouncedPermanents.Add(permanent);
+            }
+            else
+            {
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddLibraryBottomCards(new List<CardSource>() { topCard }));
+            }
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddHandCards(handCards, false, cardEffect));
+
+        #endregion
+
+        #region hide icon
+
+        foreach (Permanent permanent in _bounceTargetPermanents)
+        {
+            if (permanent != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    permanent.willBeRemoveField = false;
+                }
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Place permanent to another permanent's digivolution cards
+
+public class IPlacePermanentToDigivolutionCards
+{
+    public IPlacePermanentToDigivolutionCards(
+        List<Permanent[]> permanentArrays,
+        bool toTop,
+        ICardEffect cardEffect,
+        bool skipEffectAndActivateSkill = false)
+    {
+        permanentArrays.Clone().ForEach(permanentArray => _permanentArrays.Add(permanentArray.CloneArray()));
+        _toTop = toTop;
+        _cardEffect = cardEffect;
+        _skipEffectAndActivateSkill = skipEffectAndActivateSkill;
+    }
+
+    public void SetNotShowCards()
+    {
+        _notShowCards = true;
+    }
+
+    List<Permanent[]> _permanentArrays = new List<Permanent[]>();
+    ICardEffect _cardEffect = null;
+    bool _toTop = false;
+    bool _notShowCards = false;
+    bool _skipEffectAndActivateSkill = false;
+    public bool Placed { get; private set; } = false;
+
+    public IEnumerator PlacePermanentToDigivolutionCards()
+    {
+        if (_permanentArrays.Count == 0)
+        {
+            yield break;
+        }
+
+        List<CardSource> addedDigivolutionCards = new List<CardSource>();
+
+        List<Permanent> removeFieldPermanents = new List<Permanent>();
+
+        foreach (Permanent[] permanentArray in _permanentArrays)
+        {
+            if (permanentArray.Length == 2)
+            {
+                Permanent DigivolutionPermanent = permanentArray[0];
+                Permanent getDigivolutionPermanent = permanentArray[1];
+
+                if (DigivolutionPermanent != null && getDigivolutionPermanent != null)
+                {
+                    if (DigivolutionPermanent.TopCard != null && getDigivolutionPermanent.TopCard != null && !getDigivolutionPermanent.IsToken)
+                    {
+                        if (_cardEffect != null)
+                        {
+                            if (DigivolutionPermanent.TopCard.CanNotBeAffected(_cardEffect) || getDigivolutionPermanent.TopCard.CanNotBeAffected(_cardEffect))
+                            {
+                                continue;
+                            }
+                        }
+
+                        removeFieldPermanents.Add(DigivolutionPermanent);
+                    }
+                }
+            }
+        }
+
+        foreach (Permanent permanent in removeFieldPermanents)
+        {
+            permanent.willBeRemoveField = true;
+        }
+
+        if (removeFieldPermanents.Count == 0)
+        {
+            yield break;
+        }
+
+        #region
+
+        List<SkillInfo> skillInfos = new List<SkillInfo>();
+
+        Hashtable hashtable1 =
+        CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                removeFieldPermanents,
+                _cardEffect,
+                null);
+
+        #region  "When permanents would remove field" effect
+
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            #region permanents' effects
+
+            foreach (Permanent permanent1 in player.GetFieldPermanents())
+            {
+                foreach (ICardEffect cardEffect in permanent1.EffectList(EffectTiming.WhenRemoveField))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (cardEffect.CanTrigger(hashtable1))
+                        {
+                            skillInfos.Add(new SkillInfo(cardEffect, hashtable1, EffectTiming.WhenRemoveField));
+                        }
+                    }
+                }
+            }
+
+            #endregion
+
+            #region players' effects
+
+            foreach (ICardEffect cardEffect in player.EffectList(EffectTiming.WhenRemoveField))
+            {
+                if (cardEffect is ActivateICardEffect)
+                {
+                    if (cardEffect.CanTrigger(hashtable1))
+                    {
+                        skillInfos.Add(new SkillInfo(cardEffect, hashtable1, EffectTiming.WhenRemoveField));
+                    }
+                }
+            }
+
+            #endregion
+        }
+
+        #endregion
+
+        if (skillInfos.Count >= 1)
+        {
+            foreach (SkillInfo skillInfo in skillInfos)
+            {
+                GManager.instance.autoProcessing_CutIn.PutStackedSkill(skillInfo);
+            }
+
+            bool showEffect()
+            {
+                if (skillInfos.Count >= 2)
+                {
+                    return true;
+                }
+                else if (skillInfos.Count == 1)
+                {
+                    if (skillInfos[0].CardEffect.CanActivate(skillInfos[0].Hashtable))
+                    {
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+
+            if (showEffect())
+            {
+                foreach (Permanent Permanent in removeFieldPermanents)
+                {
+                    if (Permanent != null)
+                    {
+                        if (Permanent.TopCard != null)
+                        {
+                            if (Permanent.willBeRemoveField)
+                            {
+                                if (Permanent.ShowingPermanentCard != null)
+                                {
+                                    if (Permanent.ShowingPermanentCard.WillRemoveFieldObject != null)
+                                    {
+                                        Permanent.ShowingPermanentCard.WillRemoveFieldObject.transform.parent.gameObject.SetActive(true);
+                                        Permanent.ShowingPermanentCard.WillRemoveFieldObject.SetActive(true);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                #region shrink security Digimon display
+
+                if (GManager.instance.attackProcess.IsAttacking)
+                {
+                    if (GManager.instance.attackProcess.SecurityDigimon != null)
+                    {
+                        if (GManager.instance.GetComponent<Effects>().ShowUseHandCard.gameObject.activeSelf && GManager.instance.GetComponent<Effects>().ShowUseHandCard.cardSource == GManager.instance.attackProcess.SecurityDigimon)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(GManager.instance.attackProcess.SecurityDigimon));
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.attackProcess.SecurityDigimon.Owner.brainStormObject.BrainStormCoroutine(GManager.instance.attackProcess.SecurityDigimon));
+                        }
+                    }
+                }
+
+                #endregion
+            }
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, null));
+
+            foreach (Permanent Permanent in removeFieldPermanents)
+            {
+                if (Permanent != null)
+                {
+                    if (Permanent.TopCard != null)
+                    {
+                        if (Permanent.ShowingPermanentCard != null)
+                        {
+                            if (Permanent.ShowingPermanentCard.WillRemoveFieldObject != null)
+                            {
+                                Permanent.ShowingPermanentCard.WillRemoveFieldObject.SetActive(false);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        #endregion
+
+        foreach (Permanent[] permanentArray in _permanentArrays)
+        {
+            if (permanentArray.Length == 2)
+            {
+                Permanent DigivolutionPermanent = permanentArray[0];
+                Permanent getDigivolutionPermanent = permanentArray[1];
+
+                if (DigivolutionPermanent != null && getDigivolutionPermanent != null)
+                {
+                    if (DigivolutionPermanent.TopCard != null && getDigivolutionPermanent.TopCard != null && !getDigivolutionPermanent.IsToken && DigivolutionPermanent.willBeRemoveField)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(DigivolutionPermanent.DiscardEvoRoots());
+
+                        CardSource cardSource = DigivolutionPermanent.TopCard;
+
+                        #region record used effect
+
+                        if (_cardEffect != null)
+                        {
+                            if (DigivolutionPermanent.TopCard != null)
+                            {
+                                DigivolutionPermanent.PlaceOtherPermanentEffect = _cardEffect;
+                            }
+                        }
+
+                        #endregion
+
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(
+                            DigivolutionPermanent,
+                            ignoreOverflow: true));
+
+                        List<CardSource> digivolutionCards = new List<CardSource>() { cardSource };
+
+                        if (_toTop)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(getDigivolutionPermanent.AddDigivolutionCardsTop(digivolutionCards, _cardEffect));
+                        }
+                        else
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(getDigivolutionPermanent.AddDigivolutionCardsBottom(digivolutionCards, _cardEffect, _skipEffectAndActivateSkill));
+                        }
+
+                        cardSource.cEntity_EffectController.InitUseCountThisTurn();
+
+                        addedDigivolutionCards.Add(cardSource);
+
+                        Placed = true;
+                    }
+                }
+            }
+        }
+
+        #region add log
+
+        if (addedDigivolutionCards.Count >= 1)
+        {
+            string log = "";
+
+            log += $"\nPlace in digivolution cards:";
+
+            foreach (CardSource cardSource in addedDigivolutionCards)
+            {
+                log += $"\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})";
+            }
+
+            log += "\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+
+        #endregion
+
+        #region hide icon
+
+        if (addedDigivolutionCards.Count >= 1)
+        {
+            if (!_notShowCards)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(addedDigivolutionCards, "Digivolution Cards", true, true));
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Place permanent to another permanent's Link cards
+
+public class IPlacePermanentToLinkCards
+{
+    public IPlacePermanentToLinkCards(
+        List<Permanent[]> permanentArrays,
+        ICardEffect cardEffect,
+        bool skipEffectAndActivateSkill = false)
+    {
+        permanentArrays.Clone().ForEach(permanentArray => _permanentArrays.Add(permanentArray.CloneArray()));
+        _cardEffect = cardEffect;
+        _skipEffectAndActivateSkill = skipEffectAndActivateSkill;
+    }
+
+    public void SetNotShowCards()
+    {
+        _notShowCards = true;
+    }
+
+    List<Permanent[]> _permanentArrays = new List<Permanent[]>();
+    ICardEffect _cardEffect = null;
+    bool _notShowCards = false;
+    bool _skipEffectAndActivateSkill = false;
+    public bool Placed { get; private set; } = false;
+
+    public IEnumerator PlacePermanentToLinkCards()
+    {
+        if (_permanentArrays.Count == 0)
+        {
+            yield break;
+        }
+
+        List<CardSource> addedLinkCards = new List<CardSource>();
+
+        List<Permanent> removeFieldPermanents = new List<Permanent>();
+
+        foreach (Permanent[] permanentArray in _permanentArrays)
+        {
+            if (permanentArray.Length == 2)
+            {
+                Permanent LinkedPermanent = permanentArray[0];
+                Permanent getLinkPermanent = permanentArray[1];
+
+                if (LinkedPermanent != null && getLinkPermanent != null)
+                {
+                    if (LinkedPermanent.TopCard != null && getLinkPermanent.TopCard != null && !getLinkPermanent.IsToken)
+                    {
+                        if (_cardEffect != null)
+                        {
+                            if (LinkedPermanent.TopCard.CanNotBeAffected(_cardEffect) || getLinkPermanent.TopCard.CanNotBeAffected(_cardEffect))
+                            {
+                                continue;
+                            }
+                        }
+
+                        removeFieldPermanents.Add(LinkedPermanent);
+                    }
+                }
+            }
+        }
+
+        foreach (Permanent permanent in removeFieldPermanents)
+        {
+            permanent.willBeRemoveField = true;
+        }
+
+        if (removeFieldPermanents.Count == 0)
+        {
+            yield break;
+        }
+
+        #region Cut in Effects
+
+        List<SkillInfo> skillInfos = new List<SkillInfo>();
+
+        Hashtable hashtable1 =
+        CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                removeFieldPermanents,
+                _cardEffect,
+                null);
+
+        #region  "When permanents would remove field" effect
+
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            #region permanents' effects
+
+            foreach (Permanent permanent1 in player.GetFieldPermanents())
+            {
+                foreach (ICardEffect cardEffect in permanent1.EffectList(EffectTiming.WhenRemoveField))
+                {
+                    if (cardEffect is ActivateICardEffect)
+                    {
+                        if (cardEffect.CanTrigger(hashtable1))
+                        {
+                            skillInfos.Add(new SkillInfo(cardEffect, hashtable1, EffectTiming.WhenRemoveField));
+                        }
+                    }
+                }
+            }
+
+            #endregion
+
+            #region players' effects
+
+            foreach (ICardEffect cardEffect in player.EffectList(EffectTiming.WhenRemoveField))
+            {
+                if (cardEffect is ActivateICardEffect)
+                {
+                    if (cardEffect.CanTrigger(hashtable1))
+                    {
+                        skillInfos.Add(new SkillInfo(cardEffect, hashtable1, EffectTiming.WhenRemoveField));
+                    }
+                }
+            }
+
+            #endregion
+        }
+
+        #endregion
+
+        if (skillInfos.Count >= 1)
+        {
+            foreach (SkillInfo skillInfo in skillInfos)
+            {
+                GManager.instance.autoProcessing_CutIn.PutStackedSkill(skillInfo);
+            }
+
+            bool showEffect()
+            {
+                if (skillInfos.Count >= 2)
+                {
+                    return true;
+                }
+                else if (skillInfos.Count == 1)
+                {
+                    if (skillInfos[0].CardEffect.CanActivate(skillInfos[0].Hashtable))
+                    {
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+
+            if (showEffect())
+            {
+                foreach (Permanent Permanent in removeFieldPermanents)
+                {
+                    if (Permanent != null)
+                    {
+                        if (Permanent.TopCard != null)
+                        {
+                            if (Permanent.willBeRemoveField)
+                            {
+                                if (Permanent.ShowingPermanentCard != null)
+                                {
+                                    if (Permanent.ShowingPermanentCard.WillRemoveFieldObject != null)
+                                    {
+                                        Permanent.ShowingPermanentCard.WillRemoveFieldObject.transform.parent.gameObject.SetActive(true);
+                                        Permanent.ShowingPermanentCard.WillRemoveFieldObject.SetActive(true);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                #region shrink security Digimon display
+
+                if (GManager.instance.attackProcess.IsAttacking)
+                {
+                    if (GManager.instance.attackProcess.SecurityDigimon != null)
+                    {
+                        if (GManager.instance.GetComponent<Effects>().ShowUseHandCard.gameObject.activeSelf && GManager.instance.GetComponent<Effects>().ShowUseHandCard.cardSource == GManager.instance.attackProcess.SecurityDigimon)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(GManager.instance.attackProcess.SecurityDigimon));
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.attackProcess.SecurityDigimon.Owner.brainStormObject.BrainStormCoroutine(GManager.instance.attackProcess.SecurityDigimon));
+                        }
+                    }
+                }
+
+                #endregion
+            }
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, null));
+
+            foreach (Permanent Permanent in removeFieldPermanents)
+            {
+                if (Permanent != null)
+                {
+                    if (Permanent.TopCard != null)
+                    {
+                        if (Permanent.ShowingPermanentCard != null)
+                        {
+                            if (Permanent.ShowingPermanentCard.WillRemoveFieldObject != null)
+                            {
+                                Permanent.ShowingPermanentCard.WillRemoveFieldObject.SetActive(false);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        #endregion
+
+        foreach (Permanent[] permanentArray in _permanentArrays)
+        {
+            if (permanentArray.Length == 2)
+            {
+                Permanent LinkedPermanent = permanentArray[0];
+                Permanent getLinkPermanent = permanentArray[1];
+
+                if (LinkedPermanent != null && getLinkPermanent != null)
+                {
+                    if (LinkedPermanent.TopCard != null && getLinkPermanent.TopCard != null && !getLinkPermanent.IsToken && LinkedPermanent.willBeRemoveField)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(LinkedPermanent.DiscardEvoRoots());
+
+                        CardSource cardSource = LinkedPermanent.TopCard;
+
+                        #region record used effect
+
+                        if (_cardEffect != null)
+                        {
+                            if (LinkedPermanent.TopCard != null)
+                            {
+                                LinkedPermanent.PlaceOtherPermanentEffect = _cardEffect;
+                            }
+                        }
+
+                        #endregion
+
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(
+                            LinkedPermanent,
+                            ignoreOverflow: true));
+
+                        yield return ContinuousController.instance.StartCoroutine(getLinkPermanent.AddLinkCard(cardSource, _cardEffect));
+
+                        cardSource.cEntity_EffectController.InitUseCountThisTurn();
+
+                        addedLinkCards.Add(cardSource);
+
+                        Placed = true;
+                    }
+                }
+            }
+        }
+
+        #region add log
+
+        if (addedLinkCards.Count >= 1)
+        {
+            string log = "";
+
+            log += $"\nLink cards:";
+
+            foreach (CardSource cardSource in addedLinkCards)
+            {
+                log += $"\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})";
+            }
+
+            log += "\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+
+        #endregion
+
+        #region hide icon
+
+        if (addedLinkCards.Count >= 1)
+        {
+            if (!_notShowCards)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(addedLinkCards, "Link Cards", true, true));
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Place permanents to security
+
+public class IPutSecurityPermanent
+{
+    public IPutSecurityPermanent(Permanent permanent, Hashtable hashtable, bool toTop, bool isFaceup = false)
+    {
+        _permanent = permanent;
+        _hashtable = hashtable;
+        _toTop = toTop;
+        _isFaceup = isFaceup;
+    }
+
+    Permanent _permanent = null;
+    Hashtable _hashtable = new Hashtable();
+    bool _toTop = false;
+    bool _isFaceup = false;
+
+    public IEnumerator PutSecurity()
+    {
+        if (_permanent == null) yield break;
+        if (_permanent.TopCard == null) yield break;
+        ICardEffect cardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        if (_permanent.TopCard.CanNotBeAffected(cardEffect) || !_permanent.TopCard.Owner.CanAddSecurity(cardEffect)) yield break;
+        if (!_permanent.CanBeRemoved()) yield break;
+
+        _permanent.willBeRemoveField = true;
+
+        #region "When permanents would remove field" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                new List<Permanent>() { _permanent },
+                cardEffect,
+                null
+            ),
+            EffectTiming.WhenRemoveField));
+
+        if (GManager.instance.autoProcessing_CutIn.HasAwaitingActivateEffects())
+        {
+            _permanent.ShowWillRemoveFieldEffect();
+
+            //effect
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.ShrinkSecurityDigimonDisplay());
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, null));
+
+            _permanent.HideWillRemoveFieldEffect();
+        }
+
+        #endregion
+
+        CardSource topCard = _permanent.TopCard;
+
+        if (!_permanent.willBeRemoveField)
+            yield break;
+
+        if (topCard == null)
+            yield break;
+
+        #region add log
+
+        string log = "";
+        string fromString = _toTop ? "top" : "bottom";
+
+        log += $"\nPut cards on {fromString} of security:";
+
+        log += $"\n{_permanent.TopCard.BaseENGCardNameFromEntity}({_permanent.TopCard.CardID})";
+
+        log += "\n";
+
+        PlayLog.OnAddLog?.Invoke(log);
+
+        #endregion
+
+        #region show cards
+
+        if (!topCard.IsToken)
+        {
+            if (_toTop)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { topCard }, "Security Top Card", true, true));
+            }
+            else
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { topCard }, "Security Bottom Card", true, true));
+            }
+        }
+
+        #endregion
+
+        #region place permanent to security
+
+        yield return ContinuousController.instance.StartCoroutine(_permanent.DiscardEvoRoots());
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(_permanent));
+
+        if (!topCard.IsToken)
+        {
+            if (!topCard.IsDigiEgg)
+            {
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddSecurityCard(topCard, faceUp: _isFaceup));
+
+                if (!_isFaceup)
+                    topCard.SetReverse();
+                else
+                    topCard.SetFace();
+
+                if (!_toTop)
+                {
+                    topCard.Owner.SecurityCards.Remove(topCard);
+                    topCard.Owner.SecurityCards.Add(topCard);
+                }
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateRecoveryEffect(topCard.Owner));
+                yield return ContinuousController.instance.StartCoroutine(new IAddSecurity(topCard).AddSecurity());
+            }
+            else
+            {
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddLibraryBottomCards(new List<CardSource>() { topCard }));
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Delete permanents
+
+public class DestroyPermanentsClass
+{
+    public DestroyPermanentsClass(List<Permanent> destroyTargetPermanents, Hashtable hashtable, bool notShowCards = false)
+    {
+        _destroytargetPermanents = destroyTargetPermanents.Clone();
+        _hashtable = hashtable;
+        _notShowCards = notShowCards;
+    }
+
+    public bool IsDestroyed(Permanent permanent)
+    {
+        return DestroyedPermanents.Contains(permanent);
+    }
+
+    List<Permanent> _destroytargetPermanents = new List<Permanent>();
+    public List<Permanent> DestroyedPermanents { get; private set; } = new List<Permanent>();
+    Hashtable _hashtable = null;
+    bool _notShowCards = false;
+
+    public IEnumerator Destroy()
+    {
+        if (_destroytargetPermanents == null) yield break;
+
+        ICardEffect cardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+        IBattle battle = CardEffectCommons.GetBattleFromHashtable(_hashtable);
+        bool isDPZero = CardEffectCommons.IsDPZeroDelete(_hashtable);
+
+        _destroytargetPermanents = _destroytargetPermanents.Filter(permanent =>
+        permanent != null
+        && permanent.TopCard != null
+        && (cardEffect == null ||
+        (!permanent.TopCard.CanNotBeAffected(cardEffect)
+        && permanent.CanBeDestroyedBySkill(cardEffect))));
+
+        if (_destroytargetPermanents.Count == 0) yield break;
+
+        _destroytargetPermanents.ForEach(permanent => permanent.willBeRemoveField = true);
+
+        #region cut in effect
+
+        // "When permanents would be deleted" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _destroytargetPermanents,
+                cardEffect,
+                battle
+            ),
+            EffectTiming.WhenPermanentWouldBeDeleted));
+
+        // "When permanents would remove field" effect
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenPermanentWouldRemoveFieldCheckHashtable(
+                _destroytargetPermanents,
+                cardEffect,
+                battle
+            ),
+            EffectTiming.WhenRemoveField));
+
+        if (GManager.instance.autoProcessing_CutIn.HasAwaitingActivateEffects())
+        {
+            foreach (Permanent permanent in _destroytargetPermanents)
+            {
+                permanent.ShowDeleteEffect();
+            }
+
+            // effect
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.ShrinkSecurityDigimonDisplay());
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, null));
+
+            foreach (Permanent permanent in _destroytargetPermanents)
+            {
+                permanent.HideDeleteEffect();
+            }
+        }
+
+        #endregion
+        
+        // fix delete target permanents
+        List<Permanent> destroyTargetPermanents_Fixed = _destroytargetPermanents.Filter(permanent =>
+            permanent != null
+            && permanent.TopCard != null
+            && permanent.willBeRemoveField);
+
+        #region "When permanents are deleted" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing
+            .StackSkillInfos(CardEffectCommons.OnDeletionHashtable(
+                destroyTargetPermanents_Fixed,
+                cardEffect,
+                battle,
+                isDPZero
+                ),
+                EffectTiming.OnDestroyedAnyone));
+
+        #endregion
+
+        #region record parameters just before deletion
+
+        foreach (Permanent permanent in destroyTargetPermanents_Fixed)
+        {
+            permanent.DPJustBeforeRemoveField = permanent.DP;
+
+            if (permanent.TopCard.HasLevel)
+            {
+                permanent.LevelJustBeforeRemoveField = permanent.Level;
+            }
+
+            if (permanent.TopCard.HasPlayCost)
+            {
+                permanent.CostJustBeforeRemoveField = permanent.TopCard.GetCostItself;
+            }
+
+            permanent.CardNamesJustBeforeRemoveField = new List<string>(permanent.TopCard.CardNames);
+            permanent.CardTraitsJustBeforeRemoveField = new List<string>(permanent.TopCard.CardTraits);
+
+            foreach (CardSource cardSource in permanent.cardSources)
+            {
+                cardSource.PermanentJustBeforeRemoveField = permanent;
+            }
+        }
+
+        #endregion
+
+        #region add log
+
+        if (destroyTargetPermanents_Fixed.Count >= 1)
+        {
+            string log = "";
+
+            log += $"\nDelete:";
+
+            foreach (Permanent permanent in destroyTargetPermanents_Fixed)
+            {
+                log += $"\n{permanent.TopCard.BaseENGCardNameFromEntity}({permanent.TopCard.CardID})";
+            }
+
+            log += "\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+
+        #endregion
+
+        #region show cards
+
+        List<CardSource> destroyedCards = destroyTargetPermanents_Fixed.Map(permanent => permanent.TopCard);
+
+        if (!_notShowCards)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(destroyedCards, "Deleted cards", true, true));
+        }
+
+        #endregion
+
+        #region trash permanent cards
+
+        foreach (Permanent permanent in destroyTargetPermanents_Fixed)
+        {
+            #region record wheter to be deleted by battle
+
+            if (battle != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    if (CardEffectCommons.GetLoserPermanentsFromHashtable(battle.hashtable).Contains(permanent))
+                        permanent.IsDestroyedByBattle = true;
+                }
+            }
+
+            #endregion
+
+            #region record used effect
+
+            if (permanent.TopCard != null)
+            {
+                permanent.DestroyingEffect = cardEffect;
+            }
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().DestroyPermanentEffect(permanent));
+
+            yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
+
+            CardSource topCard = permanent.TopCard;
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(topCard));
+
+            DestroyedPermanents.Add(permanent);
+        }
+
+        #endregion
+
+        #region hide icon
+
+        foreach (Permanent permanent in _destroytargetPermanents)
+        {
+            if (permanent != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    permanent.willBeRemoveField = false;
+                }
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Security check
+
+public class ISecurityCheck
+{
+    public ISecurityCheck(Permanent AttackingPermanent, Player player)
+    {
+        this.AttackingPermanent = AttackingPermanent;
+        this.player = player;
+    }
+
+    Permanent AttackingPermanent { get; set; }
+    Player player { get; set; }
+
+    public IEnumerator SecurityCheck()
+    {
+        bool StopSecurityCheck()
+        {
+            if (AttackingPermanent == null)
+            {
+                return true;
+            }
+
+            if (AttackingPermanent.TopCard == null)
+            {
+                return true;
+            }
+
+            if (!AttackingPermanent.IsDigimon)
+                return true;
+
+            return false;
+        }
+
+        if (!StopSecurityCheck())
+        {
+            if (AttackingPermanent.Strike == 0)
+            {
+                yield break;
+            }
+
+            GManager.instance.turnStateMachine.IsSelecting = true;
+
+            GManager.instance.turnStateMachine.isSecurityCehck = true;
+
+            #region loop while there are 1 or more security cards
+
+            if (player.SecurityCards.Count >= 1)
+            {
+                int checkedCount = 0;
+
+                while (true)
+                {
+                    if (StopSecurityCheck())
+                    {
+                        break;
+                    }
+
+                    if (checkedCount >= AttackingPermanent.Strike)
+                    {
+                        break;
+                    }
+
+                    if (player.SecurityCards.Count >= 1)
+                    {
+                        List<SkillInfo> triggeredSkillInfos = new List<SkillInfo>();
+
+                        
+                        CardSource brokenSecurityCard = player.SecurityCards[0];
+                        bool isFaceDown = brokenSecurityCard.IsFlipped;
+
+                        Hashtable hashtable = new Hashtable()
+                            {
+                                {"AttackingPermanent", AttackingPermanent},
+                                {"Card", brokenSecurityCard}
+                            };
+
+                        foreach (SkillInfo skillInfo in AutoProcessing.GetSkillInfos(hashtable, EffectTiming.OnSecurityCheck))
+                        {
+                            triggeredSkillInfos.Add(skillInfo);
+                        }
+
+                        checkedCount++;
+
+                        PlayLog.OnAddLog?.Invoke($"\nSecurity Check:\n{brokenSecurityCard.BaseENGCardNameFromEntity}({brokenSecurityCard.CardID})\n");
+
+                        if (brokenSecurityCard.IsDigimon)
+                        {
+                            GManager.instance.attackProcess.SecurityDigimon = brokenSecurityCard;
+                        }
+
+                        #region effect
+
+                        player.securityObject.securityBreakGlass.ShowBlueMatarial();
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().BreakSecurityEffect(player));
+
+                        yield return new WaitForSeconds(0.1f);
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().EnterSecurityCardEffect(brokenSecurityCard));
+
+                        #endregion
+
+                        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddExecutingCard(brokenSecurityCard));
+
+                        yield return ContinuousController.instance.StartCoroutine(new IReduceSecurity(
+                            player: brokenSecurityCard.Owner,
+                            refSkillInfos: ref triggeredSkillInfos).ReduceSecurity());
+
+                        #region security effect
+
+                        List<SkillInfo> secuityEffectSkillInfos = new List<SkillInfo>();
+
+                        foreach (ICardEffect cardEffect in brokenSecurityCard.EffectList(EffectTiming.SecuritySkill))
+                        {
+                            if (cardEffect is ActivateICardEffect)
+                            {
+                                Hashtable hashtable1 = new Hashtable();
+                                hashtable1.Add("Card", brokenSecurityCard);
+                                hashtable1.Add("isFaceDown", isFaceDown);
+
+                                if (cardEffect.CanUse(hashtable1))
+                                {
+                                    secuityEffectSkillInfos.Add(new SkillInfo(cardEffect, hashtable1, EffectTiming.SecuritySkill));
+                                }
+                            }
+                        }
+
+                        List<SkillInfo> beingStackedSkillInfos = GManager.instance.autoProcessing.StackedSkillInfos.Filter(skillInfo => skillInfo.Timing == EffectTiming.OnLoseSecurity || skillInfo.Timing == EffectTiming.OnSecurityCheck);
+
+                        bool isSkillStacked = (beingStackedSkillInfos.Count == 1 && beingStackedSkillInfos[0].CardEffect.CanActivate(beingStackedSkillInfos[0].Hashtable)) || (beingStackedSkillInfos.Count >= 2);
+
+                        if (secuityEffectSkillInfos.Count == 0 && !isSkillStacked)
+                        {
+                            if (!brokenSecurityCard.IsDigimon)
+                            {
+                                yield return new WaitForSeconds(0.3f);
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShrinkUpUseHandCard(GManager.instance.GetComponent<Effects>().ShowUseHandCard));
+                            }
+                        }
+                        else
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(brokenSecurityCard));
+                            yield return ContinuousController.instance.StartCoroutine(player.brainStormObject.BrainStormCoroutine(brokenSecurityCard));
+
+                            List<SkillInfo> skillInfos = new List<SkillInfo>();
+
+                            foreach (SkillInfo skillInfo in secuityEffectSkillInfos)
+                            {
+                                skillInfos.Add(skillInfo);
+                            }
+
+                            List<CardSource> cardSources = new List<CardSource>();
+
+                            for (int j = 0; j < skillInfos.Count; j++)
+                            {
+                                cardSources.Add(brokenSecurityCard);
+                            }
+
+                            while (skillInfos.Count >= 1)
+                            {
+                                SkillInfo selectedSkillInfo = null;
+
+                                if (skillInfos.Count == 1)
+                                {
+                                    selectedSkillInfo = skillInfos[0];
+                                }
+                                else
+                                {
+                                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                                    selectCardEffect.SetUp(
+                                        canTargetCondition: (cardSource) => true,
+                                        canTargetCondition_ByPreSelecetedList: null,
+                                        canEndSelectCondition: null,
+                                        canNoSelect: () => false,
+                                        selectCardCoroutine: null,
+                                        afterSelectCardCoroutine: null,
+                                        message: "select security effect",
+                                        maxCount: 1,
+                                        canEndNotMax: false,
+                                        isShowOpponent: false,
+                                        mode: SelectCardEffect.Mode.Custom,
+                                        root: SelectCardEffect.Root.Custom,
+                                        customRootCardList: cardSources,
+                                        canLookReverseCard: true,
+                                        selectPlayer: player,
+                                        cardEffect: null);
+
+                                    selectCardEffect.SetUpSkillInfos(skillInfos);
+
+                                    selectCardEffect.SetUpCustomMessage("select security effect", "the opponent is selecting security effect");
+
+                                    selectCardEffect.SetUpAfterSelectIndexCoroutine(AfterSelectIndexCoroutine);
+
+                                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+
+                                    IEnumerator AfterSelectIndexCoroutine(List<int> selectedIndexes)
+                                    {
+                                        if (selectedIndexes.Count == 1)
+                                        {
+                                            selectedSkillInfo = skillInfos[selectedIndexes[0]];
+                                            yield return null;
+                                        }
+                                    }
+                                }
+
+                                if (selectedSkillInfo != null)
+                                {
+                                    ICardEffect cardEffect = selectedSkillInfo.CardEffect;
+                                    Hashtable hashtable2 = selectedSkillInfo.Hashtable;
+
+                                    if (cardEffect.EffectSourceCard == brokenSecurityCard)
+                                    {
+                                        if (cardEffect is ActivateICardEffect)
+                                        {
+                                            skillInfos.Remove(selectedSkillInfo);
+
+                                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.ActivateEffectProcess(
+                                                cardEffect,
+                                                hashtable2));
+                                        }
+                                    }
+                                }
+                            }
+                        }
+
+                        #endregion
+
+                        // auto process check
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+                        // stack effect of "When cards are removed from security" and "checks secuirty"
+                        foreach (SkillInfo skillInfo in triggeredSkillInfos)
+                        {
+                            GManager.instance.autoProcessing.PutStackedSkill(skillInfo);
+                        }
+
+                        // auto process check
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+                        if (!StopSecurityCheck())
+                        {
+                            #region battle with security Digimon
+
+                            if (brokenSecurityCard.IsDigimon)
+                            {
+                                bool doBattle = true;
+
+                                #region "ignore battle" effect
+
+                                Hashtable hashtable3 = new Hashtable()
+                                {
+                                    {"Card", brokenSecurityCard}
+                                };
+
+                                #region the security Digimon's effect
+
+                                foreach (ICardEffect cardEffect in brokenSecurityCard.EffectList(EffectTiming.None))
+                                {
+                                    if (cardEffect is IDontBattleSecurityDigimonEffect)
+                                    {
+                                        if (cardEffect.CanUse(hashtable3))
+                                        {
+                                            if (((IDontBattleSecurityDigimonEffect)cardEffect).DontBattleSecurityDigimon(brokenSecurityCard))
+                                            {
+                                                doBattle = false;
+                                            }
+                                        }
+                                    }
+                                }
+
+                                #endregion
+
+                                #region player's effect
+
+                                foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+                                {
+                                    foreach (ICardEffect cardEffect in player.EffectList(EffectTiming.None))
+                                    {
+                                        if (cardEffect is IDontBattleSecurityDigimonEffect)
+                                        {
+                                            if (cardEffect.CanUse(hashtable3))
+                                            {
+                                                if (((IDontBattleSecurityDigimonEffect)cardEffect).DontBattleSecurityDigimon(brokenSecurityCard))
+                                                {
+                                                    doBattle = false;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+
+                                #endregion
+
+                                #endregion
+
+                                if (doBattle)
+                                {
+                                    yield return new WaitForSeconds(0.3f);
+
+                                    yield return ContinuousController.instance.StartCoroutine(new IBattle(AttackingPermanent: AttackingPermanent, DefendingPermanent: null, DefendingCard: brokenSecurityCard).Battle());
+                                }
+                            }
+
+                            #endregion
+                        }
+
+                        #region effect
+
+                        yield return ContinuousController.instance.StartCoroutine(brokenSecurityCard.Owner.brainStormObject.CloseBrainstrorm(brokenSecurityCard));
+
+                        if (brokenSecurityCard.Owner.ExecutingCards.Contains(brokenSecurityCard))
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(brokenSecurityCard));
+
+                            if (GManager.instance.GetComponent<Effects>().ShowUseHandCard.gameObject.activeSelf)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShrinkUpUseHandCard(GManager.instance.GetComponent<Effects>().ShowUseHandCard));
+                            }
+                        }
+
+                        GManager.instance.GetComponent<Effects>().ShowUseHandCard.OffDP();
+
+                        GManager.instance.attackProcess.SecurityDigimon = null;
+
+                        #endregion
+
+                        // reset effect until end of security check
+                        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+                        {
+                            player.UntilSecurityCheckEndEffects = new List<Func<EffectTiming, ICardEffect>>();
+                        }
+
+                        // auto process check
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+                        GManager.instance.turnStateMachine.IsSelecting = true;
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+            }
+
+            #endregion
+
+            GManager.instance.turnStateMachine.isSecurityCehck = false;
+        }
+    }
+}
+
+#endregion
+
+#region trash cards from security
+
+public class IDestroySecurity
+{
+    private enum TrashMode
+    {
+        TopSecurity,
+        BottomSecurity,
+        SelectedCard,
+    }
+
+    public IDestroySecurity(Player player, int destroySecurityCount, ICardEffect cardEffect, bool fromTop)
+    {
+        _player = player;
+        _destroySecurityCount = destroySecurityCount;
+        _cardEffect = cardEffect;
+        _trashMode = fromTop ? TrashMode.TopSecurity : TrashMode.BottomSecurity;
+    }
+
+    public IDestroySecurity(Player player, CardSource card, ICardEffect cardEffect)
+    {
+        _player = player;
+        _destroySecurityCount = 1;
+        _cardEffect = cardEffect;
+        _trashMode = TrashMode.SelectedCard;
+        _selectedCard = card;
+    }
+
+    Player _player = null;
+    int _destroySecurityCount = 0;
+    public List<CardSource> DestroyedSecurity = new List<CardSource>();
+    ICardEffect _cardEffect = null;
+    TrashMode _trashMode = TrashMode.TopSecurity;
+    CardSource _selectedCard = null;
+
+    public bool IsDestroyed(CardSource cardSource)
+    {
+        return DestroyedSecurity.Contains(cardSource);
+    }
+
+    public IEnumerator DestroySecurity()
+    {
+        bool StopDestroySecurity()
+        {
+            if (_player.SecurityCards.Count == 0)
+            {
+                return true;
+            }
+
+            if (!_player.CanReduceSecurity())
+            {
+                return true;
+            }
+
+            return false;
+        }
+
+        if (_player.SecurityCards.Count >= 1 && _destroySecurityCount >= 1)
+        {
+            int count = 0;
+
+            List<CardSource> discardedCards = new List<CardSource>();
+
+            while (true)
+            {
+                if (StopDestroySecurity())
+                {
+                    break;
+                }
+
+                if (count >= _destroySecurityCount)
+                {
+                    break;
+                }
+
+                if (_player.SecurityCards.Count >= 1)
+                {
+                    count++;
+
+                    CardSource destroyedSecurityCard = null;
+
+                    switch (_trashMode)
+                    {
+                        case TrashMode.TopSecurity:
+                            destroyedSecurityCard = _player.SecurityCards[0];
+                            break;
+                        case TrashMode.BottomSecurity:
+                            destroyedSecurityCard = _player.SecurityCards[_player.SecurityCards.Count - 1];
+                            break;
+                        case TrashMode.SelectedCard:
+                            destroyedSecurityCard = _player.SecurityCards.Contains(_selectedCard) ? _selectedCard : null;
+                            break;
+                    }
+
+                    if (destroyedSecurityCard == null)
+                    {
+                        break;
+                    }
+
+                    discardedCards.Add(destroyedSecurityCard);
+
+                    #region effect
+
+                    _player.securityObject.securityBreakGlass.ShowBlueMatarial();
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().BreakSecurityEffect(_player));
+
+                    yield return new WaitForSeconds(0.1f);
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().EnterSecurityCardEffect(destroyedSecurityCard));
+
+                    yield return new WaitForSeconds(0.5f);
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().DestroySecurityEffect(destroyedSecurityCard));
+
+                    #endregion
+
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(destroyedSecurityCard));
+
+                    DestroyedSecurity.Add(destroyedSecurityCard);
+                }
+            }
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(discardedCards, "Discarded Cards", true, true));
+
+            if (discardedCards.Count >= 1)
+            {
+                yield return ContinuousController.instance.StartCoroutine(new IReduceSecurity(
+                    player: _player,
+                    refSkillInfos: ref ContinuousController.instance.nullSkillInfos,
+                    cardEffect: _cardEffect).ReduceSecurity());
+
+                #region "When security cards are trashed" effect
+
+                #region Hashtable setting
+
+                Hashtable hashtable = new Hashtable()
+                {
+                    {"DiscardedCards", discardedCards},
+                    {"CardEffect", _cardEffect},
+                };
+
+                #endregion
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnDiscardSecurity));
+
+                #endregion
+            }
+
+            #region add log
+
+            if (discardedCards.Count >= 1)
+            {
+                string log = "";
+
+                string modeString = "";
+
+                switch (_trashMode)
+                {
+                    case TrashMode.TopSecurity:
+                        modeString = "Top";
+                        break;
+                    case TrashMode.BottomSecurity:
+                        modeString = "Bottom";
+                        break;
+                    case TrashMode.SelectedCard:
+                        modeString = "Selected";
+                        break;
+                }
+
+                log += $"\nDiscarded From {modeString} Security Cards:";
+
+                foreach (CardSource cardSource in discardedCards)
+                {
+                    if (cardSource != null)
+                    {
+                        log += $"\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})";
+                    }
+                }
+
+                log += "\n";
+
+                PlayLog.OnAddLog?.Invoke(log);
+            }
+
+            #endregion
+        }
+    }
+}
+
+#endregion
+
+#region Battle
+
+public class IBattle
+{
+    public IBattle(Permanent AttackingPermanent, Permanent DefendingPermanent, CardSource DefendingCard, bool IsWithoutAttack = false)
+    {
+        this.AttackingPermanent = AttackingPermanent;
+        this.DefendingPermanent = DefendingPermanent;
+        this.DefendingCard = DefendingCard;
+        this.IsWithoutAttack = IsWithoutAttack;
+    }
+
+    public Permanent AttackingPermanent { get; private set; } = null;
+    public Permanent DefendingPermanent { get; private set; } = null;
+    CardSource DefendingCard { get; set; } = null;
+    bool IsWithoutAttack { get; set; } = false;
+    public Hashtable hashtable { get; set; } = new Hashtable();
+
+    public Permanent enemyPermanent(Permanent permanent)
+    {
+        if (permanent != null)
+        {
+            if (permanent == AttackingPermanent)
+            {
+                return DefendingPermanent;
+            }
+            else if (permanent == DefendingPermanent)
+            {
+                return AttackingPermanent;
+            }
+        }
+
+        return null;
+    }
+
+    public int CompareStats()
+    {
+        int statCheck = 0;
+
+        if (AttackingPermanent.HasIceclad || DefendingPermanent.HasIceclad)
+            statCheck = AttackingPermanent.DigivolutionCards.Count - DefendingPermanent.DigivolutionCards.Count;
+        else
+            statCheck = AttackingPermanent.DP - DefendingPermanent.DP;
+
+        statCheck = Mathf.Clamp(statCheck, -1, 1);
+
+        return statCheck;
+    }
+
+    public IEnumerator Battle()
+    {
+        hashtable = new Hashtable();
+
+        if (AttackingPermanent != null)
+        {
+            bool IsExistingDefender()
+            {
+                // whether defender exists
+                if ((DefendingPermanent == null) != (DefendingCard == null))
+                {
+                    if (DefendingPermanent != null)
+                    {
+                        if (DefendingPermanent.TopCard != null)
+                        {
+                            return true;
+                        }
+                    }
+                    else if (DefendingCard != null)
+                    {
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+
+            if (IsExistingDefender())
+            {
+                if (AttackingPermanent != null)
+                {
+                    AttackingPermanent.battle = this;
+                }
+
+                if (DefendingPermanent != null)
+                {
+                    DefendingPermanent.battle = this;
+                }
+
+                List<Permanent> WinnerPermanents = new List<Permanent>();
+                List<Permanent> LoserPermanents = new List<Permanent>();
+                CardSource LoserCard = null;
+                bool WasTie = false;
+
+                //add log
+                string log = $"\nBattle:\n{AttackingPermanent.TopCard.BaseENGCardNameFromEntity}({AttackingPermanent.TopCard.CardID})";
+
+                if (DefendingPermanent != null)
+                {
+                    log += $"\n??\n{DefendingPermanent.TopCard.BaseENGCardNameFromEntity}({DefendingPermanent.TopCard.CardID})\n";
+                }
+                else if (DefendingCard != null)
+                {
+                    log += $"\n??\n{DefendingCard.BaseENGCardNameFromEntity}({DefendingCard.CardID})\n";
+                }
+
+                PlayLog.OnAddLog?.Invoke(log);
+
+                #region "At the start of battle" effect
+
+                Permanent _AttackingPermanent = null;
+                Permanent _DefendingPermanent = null;
+
+                if (AttackingPermanent != null)
+                {
+                    if (AttackingPermanent.TopCard != null)
+                    {
+                        _AttackingPermanent = new Permanent(AttackingPermanent.cardSources);
+                    }
+                }
+
+                if (DefendingPermanent != null)
+                {
+                    if (DefendingPermanent.TopCard != null)
+                    {
+                        _DefendingPermanent = new Permanent(DefendingPermanent.cardSources);
+                    }
+                }
+
+                hashtable.Add("AttackingPermanent", _AttackingPermanent);
+                hashtable.Add("DefendingPermanent", _DefendingPermanent);
+                hashtable.Add("DefendingCard", DefendingCard);
+
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnStartBattle));
+
+                #endregion
+
+                #region Show effect
+
+                bool ShowEffect()
+                {
+                    if (GManager.instance.autoProcessing.StackedSkillInfos.Count >= 2)
+                    {
+                        return true;
+                    }
+                    else if (GManager.instance.autoProcessing.StackedSkillInfos.Count == 1)
+                    {
+                        if (GManager.instance.autoProcessing.StackedSkillInfos[0].CardEffect.CanActivate(GManager.instance.autoProcessing.StackedSkillInfos[0].Hashtable))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                if (ShowEffect())
+                {
+                    if (GManager.instance.attackProcess.IsAttacking)
+                    {
+                        if (GManager.instance.attackProcess.SecurityDigimon != null)
+                        {
+                            if (GManager.instance.GetComponent<Effects>().ShowUseHandCard.gameObject.activeSelf && GManager.instance.GetComponent<Effects>().ShowUseHandCard.cardSource == GManager.instance.attackProcess.SecurityDigimon)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(GManager.instance.attackProcess.SecurityDigimon));
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.attackProcess.SecurityDigimon.Owner.brainStormObject.BrainStormCoroutine(GManager.instance.attackProcess.SecurityDigimon));
+                            }
+                        }
+                    }
+                }
+
+                #endregion
+
+                if (!IsWithoutAttack)//If started by effect, do not perform processing during this battle
+                {
+                    // auto process check
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+                    GManager.instance.turnStateMachine.IsSelecting = true;
+
+                    //Preemptive end battle if the attack process is ended
+                    if (GManager.instance.attackProcess.IsEndAttack )
+                        yield break;
+                }
+
+                #region battle with permanent
+
+                if (DefendingPermanent != null)
+                {
+                    int battleResults = CompareStats();
+                    if (battleResults == 1)
+                    {
+                        WinnerPermanents.Add(AttackingPermanent);
+
+                        if (DefendingPermanent.CanBeDestroyedByBattle(AttackingPermanent, DefendingPermanent, DefendingCard))
+                            LoserPermanents.Add(DefendingPermanent);
+                    }
+                    else if (battleResults == 0)
+                    {
+                        WasTie = true;
+
+                        WinnerPermanents.Add(AttackingPermanent);
+                        WinnerPermanents.Add(DefendingPermanent);
+
+                        if (AttackingPermanent.CanBeDestroyedByBattle(AttackingPermanent, DefendingPermanent, DefendingCard))
+                            LoserPermanents.Add(AttackingPermanent);
+
+                        if (DefendingPermanent.CanBeDestroyedByBattle(AttackingPermanent, DefendingPermanent, DefendingCard))
+                            LoserPermanents.Add(DefendingPermanent);
+                    }
+                    else if (battleResults == -1)
+                    {
+                        WinnerPermanents.Add(DefendingPermanent);
+
+                        if (AttackingPermanent.CanBeDestroyedByBattle(AttackingPermanent, DefendingPermanent, DefendingCard))
+                            LoserPermanents.Add(AttackingPermanent);
+                    }
+                }
+
+                #endregion
+
+                #region battle with card
+                else if (DefendingCard != null)
+                {
+                    if (AttackingPermanent.DP > DefendingCard.CardDP)
+                    {
+                        WinnerPermanents.Add(AttackingPermanent);
+                        LoserCard = DefendingCard;
+                    }
+                    else if (AttackingPermanent.DP == DefendingCard.CardDP)
+                    {
+                        WasTie = true;
+
+                        if (AttackingPermanent.CanBeDestroyedByBattle(AttackingPermanent, DefendingPermanent, DefendingCard))
+                        {
+                            LoserPermanents.Add(AttackingPermanent);
+                        }
+
+                        LoserCard = DefendingCard;
+                    }
+                    else if (AttackingPermanent.DP < DefendingCard.CardDP)
+                    {
+                        if (AttackingPermanent.CanBeDestroyedByBattle(AttackingPermanent, DefendingPermanent, DefendingCard))
+                        {
+                            LoserPermanents.Add(AttackingPermanent);
+                        }
+                    }
+                }
+
+                #endregion
+
+                List<Permanent> _WinnerPermanents = new List<Permanent>();
+                List<Permanent> _LoserPermanents = new List<Permanent>();
+
+                foreach (Permanent permanent in WinnerPermanents)
+                {
+                    if (permanent.TopCard != null)
+                    {
+                        _WinnerPermanents.Add(new Permanent(permanent.cardSources));
+                    }
+                }
+
+                foreach (Permanent permanent in LoserPermanents)
+                {
+                    if (permanent.TopCard != null)
+                    {
+                        _LoserPermanents.Add(new Permanent(permanent.cardSources));
+                    }
+                }
+
+                hashtable.Add("WinnerPermanents", _WinnerPermanents);
+                hashtable.Add("WinnerPermanents_real", WinnerPermanents);
+                hashtable.Add("LoserPermanents", _LoserPermanents);
+                hashtable.Add("LoserPermanents_real", LoserPermanents);
+                hashtable.Add("LoserCard", LoserCard);
+                hashtable.Add("WasTie", WasTie);
+                hashtable.Add("battle", this);
+
+                // battle effect
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().BattleEffect(WinnerPermanents, LoserPermanents, LoserCard));
+
+                DestroyPermanentsClass destoryBattlePermanents = new DestroyPermanentsClass(LoserPermanents, hashtable);
+                yield return ContinuousController.instance.StartCoroutine(destoryBattlePermanents.Destroy());
+
+                //Fix Loser Permanents
+                if(LoserPermanents.Count != destoryBattlePermanents.DestroyedPermanents.Count)
+                {
+                    LoserPermanents = destoryBattlePermanents.DestroyedPermanents;
+                    _LoserPermanents = destoryBattlePermanents.DestroyedPermanents;
+                    hashtable["LoserPermanents"] = _LoserPermanents;
+                    hashtable["LoserPermanents_real"] = LoserPermanents;
+                }
+
+                
+                // "At the end of battle" effect
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnEndBattle));
+
+                #region move up effect
+
+                if (ShowEffect())
+                {
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.ShrinkSecurityDigimonDisplay());
+                }
+
+                #endregion
+
+                #region effect when determine whether to do security check
+                
+                List<SkillInfo> skillInfos_Pierce = AutoProcessing.GetSkillInfos(hashtable, EffectTiming.OnDetermineDoSecurityCheck)
+                    .Filter(skillInfo => skillInfo.CardEffect != null && skillInfo.CardEffect.CanActivate(skillInfo.Hashtable));
+
+                if (skillInfos_Pierce.Count >= 1)
+                {
+                    GManager.instance.autoProcessing.PutStackedSkill(skillInfos_Pierce[0]);
+                }
+
+                #endregion
+            }
+        }
+
+        if (!IsWithoutAttack)//If started by effect, do not perform processing & don't reset effects relevant to the actual attack process
+        {
+            // auto process check
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
+
+            #region reset effect until the end of battle
+
+            foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+            {
+                foreach (Permanent permanent in player.GetFieldPermanents())
+                {
+                    permanent.UntilEndBattleEffects = new List<Func<EffectTiming, ICardEffect>>();
+                }
+
+                player.UntilEndBattleEffects = new List<Func<EffectTiming, ICardEffect>>();
+            }
+
+            #endregion
+        }
+
+        if (AttackingPermanent != null)
+        {
+            AttackingPermanent.battle = null;
+        }
+
+        if (DefendingPermanent != null)
+        {
+            DefendingPermanent.battle = null;
+        }
+    }
+}
+
+#endregion
+
+#region De-digivolve
+
+public class IDegeneration
+{
+    /// <summary>
+    /// De-Digivolve Class
+    /// </summary>
+    /// <param name="permanent">Target Permanent</param>
+    /// <param name="DegenerationCount">De-Digivolve Amount</param>
+    /// <param name="cardEffect">Card Effect</param>
+    /// <param name="DegenerationCountRuling">Should we enforce rule to select De-digivolve amount before digimon, disabled by default</param>
+    public IDegeneration(Permanent permanent, int DegenerationCount, ICardEffect cardEffect, bool? DegenerationCountRuling = null)
+    {
+        _permanent = permanent;
+        _degenerationCount = DegenerationCount;
+        _cardEffect = cardEffect;
+        _degenerationCountRuling = DegenerationCountRuling;
+    }
+
+    Permanent _permanent = null;
+    int _degenerationCount;
+    ICardEffect _cardEffect = null;
+    bool? _degenerationCountRuling;
+
+    public IEnumerator Degeneration()
+    {
+        if (_cardEffect == null) yield break;
+        if (_cardEffect.EffectSourceCard == null) yield break;
+        if (_permanent == null) yield break;
+        if (_permanent.TopCard == null) yield break;
+        if (_permanent.ImmuneFromDeDigivolve()) yield break;
+        if (_permanent.ImmuneFromStackTrashing(_cardEffect)) yield break;
+        if (_permanent.TopCard.CanNotBeAffected(_cardEffect)) yield break;
+
+        int maxCount = Math.Min(_permanent.DigivolutionCards.Count, _degenerationCount);
+
+        SelectCountEffect selectCountEffect = GManager.instance.GetComponent<SelectCountEffect>();
+
+        if (selectCountEffect != null && _degenerationCountRuling == null)
+        {
+            Player selectPlayer = _cardEffect.EffectSourceCard.Owner;
+
+            selectCountEffect.SetUp(
+                SelectPlayer: selectPlayer,
+                targetPermanent: _permanent,
+                MaxCount: maxCount,
+                CanNoSelect: false,
+                Message: "How many cards do you trash?",
+                Message_Enemy: "The opponent is choosing how many cards to trash.",
+                SelectCountCoroutine: SelectCountCoroutine);
+
+            yield return ContinuousController.instance.StartCoroutine(selectCountEffect.Activate());
+
+            IEnumerator SelectCountCoroutine(int count)
+            {
+                _degenerationCount = count;
+                yield return null;
+            }
+        }
+
+        if (_degenerationCount >= 1)
+        {
+            int count = 0;
+
+            List<CardSource> selectedCards = new List<CardSource>();
+
+            while (true)
+            {
+                bool StopCondition()
+                {
+                    if (_permanent.HasNoDigivolutionCards)
+                    {
+                        return true;
+                    }
+
+                    if (_permanent.Level == 3)
+                    {
+                        if (_permanent.TopCard != null)
+                        {
+                            if (_permanent.TopCard.HasLevel)
+                            {
+                                return true;
+                            }
+                        }
+                    }
+
+                    if (count >= _degenerationCount)
+                    {
+                        return true;
+                    }
+
+                    return false;
+                }
+
+                if (StopCondition())
+                {
+                    break;
+                }
+
+                if (count == 0)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateDebuffEffect(_permanent));
+                }
+
+                CardSource cardSource = _permanent.TopCard;
+
+                selectedCards.Add(cardSource);
+
+                yield return ContinuousController.instance.StartCoroutine(new AceOverflowClass(new List<CardSource>() { cardSource }).Overflow());
+
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(cardSource));
+
+                if (!cardSource.IsToken)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+                }
+
+                _permanent.ShowingPermanentCard.ShowPermanentData(true);
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().RemoveDigivolveRootEffect(cardSource, _permanent));
+
+                count++;
+            }
+
+            #region "When Top Card is Trashed" effect
+
+            #region Hashtable Setting
+
+            System.Collections.Hashtable hashtable = new System.Collections.Hashtable()
+                        {
+                            {"Permanent", _permanent},
+                            {"CardSources", selectedCards}
+                        };
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing
+                .StackSkillInfos(hashtable, EffectTiming.WhenTopCardTrashed));
+
+            #endregion
+
+            #region add log
+
+            if (selectedCards.Count >= 1)
+            {
+                string log = "";
+
+                log += $"\nDe-Digivolve :";
+
+                foreach (CardSource cardSource in selectedCards)
+                {
+                    if (cardSource != null)
+                    {
+                        log += $"\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})";
+                    }
+                }
+
+                log += "\n";
+
+                PlayLog.OnAddLog?.Invoke(log);
+            }
+
+            #endregion
+        }
+    }
+}
+
+#endregion
+
+#region Trash digivolution cards
+
+public class ITrashDigivolutionCards
+{
+    public ITrashDigivolutionCards(Permanent permanent, List<CardSource> trashTargetCards, ICardEffect cardEffect)
+    {
+        _permanent = permanent;
+
+        _trashTargetCards = trashTargetCards.Clone();
+
+        _cardEffect = cardEffect;
+    }
+
+    public bool IsTrashed(CardSource cardSource)
+    {
+        return TrashedCards.Contains(cardSource);
+    }
+
+    Permanent _permanent = null;
+    List<CardSource> _trashTargetCards = new List<CardSource>();
+    public List<CardSource> TrashedCards = new List<CardSource>();
+    ICardEffect _cardEffect = null;
+
+    public IEnumerator TrashDigivolutionCards()
+    {
+        if (_trashTargetCards == null) yield break;
+        if (_cardEffect == null) yield break;
+        if (_permanent == null) yield break;
+        if (_permanent.TopCard == null) yield break;
+        if (_permanent.ImmuneFromStackTrashing(_cardEffect)) yield break;
+        if (_permanent.TopCard.CanNotBeAffected(_cardEffect)) yield break;
+        if (_permanent.HasNoDigivolutionCards) yield break;
+
+        _trashTargetCards = _trashTargetCards.Filter((cardSource) =>
+            _permanent.DigivolutionCards.Contains(cardSource) &&
+            !cardSource.CanNotTrashFromDigivolutionCards(_cardEffect));
+
+        if (_trashTargetCards.Count == 0) yield break;
+
+        _trashTargetCards.ForEach(source => source.willBeRemoveSources = true);
+
+        string message = "Discarded card" + Utils.PluralFormSuffix(_trashTargetCards.Count);
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(_trashTargetCards, message, true, true));
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateDebuffEffect(_permanent));
+
+        #region cut in effect - Would discard
+
+        // "When digivolution cards would be trashed" effect
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenDigivolutionCardWouldDiscardedCheckHashtable(
+                _permanent,
+                _trashTargetCards,
+                _cardEffect
+            ),
+            EffectTiming.WhenWouldDigivolutionCardDiscarded));
+
+        if (GManager.instance.autoProcessing_CutIn.HasAwaitingActivateEffects())
+        {
+            // effect
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.ShrinkSecurityDigimonDisplay());
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, AutoProcessing.HasExecutedSameEffect));
+        }
+
+        #endregion
+
+        //fix trash target permanent
+        Permanent permanentTarget_Fixed = _permanent;
+
+        // fix trash sources sources
+        List<CardSource> trashDigivolutionCards_Fixed = _trashTargetCards.Filter(cardsource =>
+            cardsource != null
+            && cardsource.willBeRemoveSources);
+
+        #region "When digivolution cards are trashed" effect
+
+        #region Hashtable Setting
+
+        Hashtable hashtable = new Hashtable()
+            {
+                {"CardEffect", _cardEffect},
+                {"Permanent", permanentTarget_Fixed},
+                {"DiscardedCards", trashDigivolutionCards_Fixed},
+            };
+
+        #endregion
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnDigivolutionCardDiscarded));
+
+        #endregion
+
+        yield return ContinuousController.instance.StartCoroutine(new AceOverflowClass(_trashTargetCards).Overflow());
+
+        foreach (CardSource cardSource in trashDigivolutionCards_Fixed)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().RemoveDigivolveRootEffect(cardSource, permanentTarget_Fixed));
+
+            yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(cardSource));
+
+            if (!cardSource.IsToken)
+            {
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+            }
+
+            cardSource.willBeRemoveSources = false;
+            TrashedCards.Add(cardSource);
+        }
+    }
+}
+
+#endregion
+
+#region Trash link cards
+
+public class ITrashLinkCards
+{
+    public ITrashLinkCards(Permanent permanent, List<CardSource> trashTargetCards, ICardEffect cardEffect)
+    {
+        _permanent = permanent;
+
+        _trashTargetCards = trashTargetCards.Clone();
+
+        _cardEffect = cardEffect;
+    }
+
+    public bool IsTrashed(CardSource cardSource)
+    {
+        return TrashedLinkCards.Contains(cardSource);
+    }
+
+    Permanent _permanent = null;
+    List<CardSource> _trashTargetCards = new List<CardSource>();
+    public List<CardSource> TrashedLinkCards = new List<CardSource>();
+    ICardEffect _cardEffect = null;
+
+    public IEnumerator TrashLinkCards()
+    {
+        if (_trashTargetCards == null) yield break;
+        if (_permanent == null) yield break;
+        if (_permanent.TopCard == null) yield break;
+        if (_cardEffect != null && _permanent.TopCard.CanNotBeAffected(_cardEffect)) yield break;
+        if (_permanent.HasNoLinkCards) yield break;
+
+        _trashTargetCards = _trashTargetCards.Filter((cardSource) =>
+            _permanent.LinkedCards.Contains(cardSource));
+
+        if (_trashTargetCards.Count == 0) yield break;
+
+        _trashTargetCards.ForEach(source => source.willBeRemoveSources = true);
+
+        string message = "Discarded card" + Utils.PluralFormSuffix(_trashTargetCards.Count);
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(_trashTargetCards, message, true, true));
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateDebuffEffect(_permanent));
+
+        #region cut in effect - Would discard
+
+        // "When link cards would be trashed" effect
+        //TODO: Create CardEffectCommons.WhenLinkCardWouldDiscard function
+        /*yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
+            CardEffectCommons.WhenDigivolutionCardWouldDiscardedCheckHashtable(
+                _permanent,
+                _trashTargetCards,
+                _cardEffect
+            ),
+            EffectTiming.WhenWouldDigivolutionCardDiscarded));*/
+
+        if (GManager.instance.autoProcessing_CutIn.HasAwaitingActivateEffects())
+        {
+            // effect
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.ShrinkSecurityDigimonDisplay());
+
+            // cut in effect process
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, AutoProcessing.HasExecutedSameEffect));
+        }
+
+        #endregion
+
+        //fix trash target permanent
+        Permanent permanentTarget_Fixed = _permanent;
+
+        // fix trash sources sources
+        List<CardSource> trashLinkCards_Fixed = _trashTargetCards.Filter(cardsource =>
+            cardsource != null
+            && cardsource.willBeRemoveSources);
+
+        #region "When link cards are trashed" effect
+
+        #region Hashtable Setting
+
+        Hashtable hashtable = new Hashtable()
+            {
+                {"CardEffect", _cardEffect},
+                {"Permanent", permanentTarget_Fixed},
+                {"DiscardedCards", trashLinkCards_Fixed},
+            };
+
+        #endregion
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnLinkCardDiscarded));
+
+        #endregion
+
+        yield return ContinuousController.instance.StartCoroutine(new AceOverflowClass(_trashTargetCards).Overflow());
+
+        foreach (CardSource cardSource in trashLinkCards_Fixed)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().RemoveDigivolveRootEffect(cardSource, permanentTarget_Fixed));
+
+            if (!cardSource.IsToken)
+            {
+                yield return ContinuousController.instance.StartCoroutine(permanentTarget_Fixed.RemoveLinkedCard(cardSource));
+            }
+
+            cardSource.willBeRemoveSources = false;
+            TrashedLinkCards.Add(cardSource);
+        }
+    }
+}
+
+#endregion
+
+#region Return digivolution cards to deck bottom
+
+public class ReturnToLibraryBottomDigivolutionCardsClass
+{
+    public ReturnToLibraryBottomDigivolutionCardsClass(Permanent permanent, List<CardSource> cardSources, Hashtable hashtable)
+    {
+        _permanent = permanent;
+
+        _cardSources = cardSources.Clone();
+
+        _hashtable = hashtable;
+    }
+
+    Permanent _permanent = null;
+    List<CardSource> _cardSources = new List<CardSource>();
+    Hashtable _hashtable = null;
+
+    public IEnumerator ReturnToLibraryBottomDigivolutionCards()
+    {
+        if (_permanent == null) yield break;
+        if (_permanent.TopCard == null) yield break;
+        if (_cardSources == null) yield break;
+
+        _cardSources = _cardSources.Filter(cardSource => _permanent.DigivolutionCards.Contains(cardSource));
+
+        if (_cardSources.Count == 0) yield break;
+
+        ICardEffect CardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        if (CardEffect != null && _permanent.TopCard.CanNotBeAffected(CardEffect)) yield break;
+
+        string message = "Deck Bottom card" + Utils.PluralFormSuffix(_cardSources.Count);
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(_cardSources, message, true, true));
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateDebuffEffect(_permanent));
+
+        #region "When digivolution cards are returned to deck" effect
+
+        #region Hashtable Setting
+
+        Hashtable hashtable1 = new Hashtable()
+        {
+            {"Permanent", _permanent},
+            {"DeckBottomCards", _cardSources},
+            {"CardEffect", CardEffect},
+        };
+
+        #endregion
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable1, EffectTiming.OnDigivolutionCardReturnToDeckBottom));
+
+        #endregion
+
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddLibraryBottomCards(_cardSources));
+    }
+}
+
+#endregion
+
+#region Reduce security
+
+public class IReduceSecurity
+{
+    public IReduceSecurity(Player player, ref List<SkillInfo> refSkillInfos, ICardEffect cardEffect = null)
+    {
+        _player = player;
+        _refSkillInfos = refSkillInfos;
+        _cardEffect = cardEffect;
+    }
+
+    Player _player = null;
+    List<SkillInfo> _refSkillInfos = null;
+    ICardEffect _cardEffect = null;
+
+    public IEnumerator ReduceSecurity()
+    {
+        GManager.OnSecurityStackChanged?.Invoke(_player);
+
+        #region "When cards are removed from security" effect
+
+        #region Hashtable Setting
+
+        Hashtable hashtable = new Hashtable()
+        {
+            {"Player", _player},
+            {"SkillInfo",_refSkillInfos },
+            {"CardEffect",_cardEffect}
+        };
+
+        #endregion
+
+        if (_refSkillInfos == null)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnLoseSecurity));
+        }
+        else
+        {
+            foreach (SkillInfo skillInfo in AutoProcessing.GetSkillInfos(hashtable, EffectTiming.OnLoseSecurity))
+            {
+                _refSkillInfos.Add(skillInfo);
+            }
+        }
+
+        #endregion
+    }
+}
+
+#endregion
+
+#region Add Security
+
+public class IAddSecurity
+{
+    public IAddSecurity(CardSource source)
+    {
+        _player = source.Owner;
+        _cardSource = source;
+    }
+
+    Player _player { get; set; }
+    CardSource _cardSource {  get; set; }
+
+    public IEnumerator AddSecurity()
+    {
+        GManager.OnSecurityStackChanged?.Invoke(_player);
+
+        #region "When security cards are added" effect
+
+        #region Hashtable setting
+
+        Hashtable hashtable = new Hashtable()
+        {
+            {"Player", _player},
+            {"CardSources", new List<CardSource> { _cardSource } }
+        };
+
+        #endregion
+
+        yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnAddSecurity));
+
+        #endregion
+
+        #region "When face up cards are added"
+        if (!_cardSource.IsFlipped)
+        {
+            #region Hashtable setting
+
+            Hashtable faceUpHashtable = new Hashtable()
+            {
+                {"Player", _player},
+                {"CardSources", new List<CardSource> { _cardSource } }
+            };
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(faceUpHashtable, EffectTiming.OnFaceUpSecurityIncreased));
+        }
+        #endregion
+    }
+}
+
+#endregion
+
+#region Flip Security Face Up
+
+public class IFlipSecurity
+{
+    public IFlipSecurity(CardSource source)
+    {
+        _player = source.Owner;
+        _cardSource = source;
+    }
+
+    Player _player { get; set; }
+    CardSource _cardSource {  get; set; }
+
+    public IEnumerator FlipFaceUp()
+    {
+        if (!_player.SecurityCards.Contains(_cardSource) || !_cardSource.IsFlipped)
+            yield break;
+
+        _cardSource.SetFace();
+
+        #region "When face up cards are added"
+
+        #region Hashtable setting
+
+        Hashtable hashtable = new Hashtable()
+        {
+            {"Player", _player},
+            {"CardSources", new List<CardSource> { _cardSource } }
+        };
+
+        #endregion
+
+        if (!_cardSource.IsFlipped)
+        {
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable, EffectTiming.OnFaceUpSecurityIncreased));
+        }
+        #endregion
+    }
+}
+
+#endregion
+
+#region Suspend permanents
+
+public class SuspendPermanentsClass
+{
+    public SuspendPermanentsClass(List<Permanent> permanents, Hashtable hashtable)
+    {
+        _permanents = permanents;
+        _hashtable = hashtable;
+    }
+
+    List<Permanent> _permanents { get; set; }
+    Hashtable _hashtable { get; set; }
+
+    public IEnumerator Tap()
+    {
+        if (_permanents.Count == 0) yield break;
+
+        ICardEffect CardEffect = CardEffectCommons.GetCardEffectFromHashtable(_hashtable);
+
+        bool IsBlock = CardEffectCommons.IsBlock(_hashtable);
+
+        bool IsAttack = CardEffectCommons.IsAttack(_hashtable);
+
+        List<Permanent> suspendTargetPermanents = _permanents.Filter(PermanentCondition);
+
+        bool PermanentCondition(Permanent permanent)
+        {
+            if (permanent != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    if (permanent.IsSuspended)
+                    {
+                        return false;
+                    }
+
+                    if (!permanent.CanSuspend)
+                    {
+                        return false;
+                    }
+
+                    if (CardEffect != null)
+                    {
+                        if (permanent.TopCard.CanNotBeAffected(CardEffect))
+                        {
+                            return false;
+                        }
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        foreach (Permanent permanent in suspendTargetPermanents)
+        {
+            permanent.IsSuspended = true;
+
+            permanent.DPWhenSuspended = permanent.DP;
+
+            if (permanent.ShowingPermanentCard != null)
+            {
+                permanent.ShowingPermanentCard.ShowPermanentData(true);
+            }
+        }
+
+        if (suspendTargetPermanents.Count >= 1)
+        {
+            #region "Effects when permanents suspend
+
+            #region Hashtable Setting
+
+            Hashtable _hashtable = new Hashtable(){
+                {"Permanents", suspendTargetPermanents},
+                {"IsBlock", IsBlock}
+            };
+
+            if (CardEffect != null)
+            {
+                _hashtable.Add("CardEffect", CardEffect);
+            }
+
+            #endregion
+
+            if (IsAttack)
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(_hashtable, EffectTiming.OnTappedAnyone));
+            else
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(_hashtable, EffectTiming.OnTappedAnyone));
+
+            #endregion
+
+            yield return new WaitForSeconds(0.3f);
+        }
+    }
+}
+
+#endregion
+
+#region Unsuspend permanents
+
+public class IUnsuspendPermanents
+{
+    public IUnsuspendPermanents(List<Permanent> permanents, ICardEffect cardEffect)
+    {
+        _permanents = permanents.Clone().Filter(CardEffectCommons.IsPermanentExistsOnBattleArea);
+        _cardEffect = cardEffect;
+    }
+
+    List<Permanent> _permanents { get; set; }
+    ICardEffect _cardEffect { get; set; }
+
+    public IEnumerator Unsuspend()
+    {
+        //Permanent list that will unsuspend
+        List<Permanent> untappedPermanets = _permanents.Filter((permanent) =>
+            permanent != null
+            && permanent.TopCard != null
+            && permanent.IsSuspended
+            && permanent.CanUnsuspend
+            && (_cardEffect == null || !permanent.TopCard.CanNotBeAffected(_cardEffect)));
+
+        #region "When permanents would unsuspend" effect
+
+        #region Hashtable Setting
+
+        Hashtable hashtable1 = new Hashtable()
+        {
+            {"CardEffect", _cardEffect},
+            {"Permanents", untappedPermanets},
+        };
+
+        #endregion
+
+        List<SkillInfo> skillInfos = AutoProcessing.GetSkillInfos(hashtable1, EffectTiming.WhenUntapAnyone);
+
+        if (skillInfos.Count >= 1)
+        {
+            foreach (SkillInfo skillInfo in skillInfos)
+            {
+                GManager.instance.autoProcessing_CutIn.PutStackedSkill(skillInfo);
+            }
+
+            foreach (Permanent permanent in untappedPermanets)
+            {
+                permanent.ShowUnsuspendEffect();
+            }
+
+            //cut in effects
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(false, AutoProcessing.HasExecutedSameEffect));
+
+            untappedPermanets.ForEach(permanent =>
+            {
+                if (permanent.ShowingPermanentCard != null)
+                {
+                    permanent.ShowingPermanentCard.WillUntapObject.SetActive(false);
+                }
+            });
+        }
+
+        #endregion
+
+        // fix unsuspend target permanents
+        List<Permanent> untappedPermanets_Fixed = untappedPermanets.Filter((permanent) =>
+            permanent != null
+            && permanent.TopCard != null
+            && permanent.IsSuspended
+            && permanent.CanUnsuspend
+            && (_cardEffect == null || !permanent.TopCard.CanNotBeAffected(_cardEffect)));
+
+        if (untappedPermanets_Fixed.Count >= 1)
+        {
+            foreach (Permanent permanent in untappedPermanets_Fixed)
+            {
+                permanent.IsSuspended = false;
+
+                if (permanent.ShowingPermanentCard != null)
+                {
+                    permanent.ShowingPermanentCard.ShowPermanentData(true);
+                }
+            }
+
+            #region "When permanents are unsuspended" effect
+
+            #region Hashtable Setting
+
+            Hashtable hashtable2 = new Hashtable()
+            {
+                {"CardEffect", _cardEffect},
+                {"Permanents", untappedPermanets_Fixed},
+            };
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(hashtable2, EffectTiming.OnUnTappedAnyone));
+
+            #endregion
+
+            yield return new WaitForSeconds(0.3f);
+        }
+
+        foreach (Permanent permanent in untappedPermanets)
+        {
+            permanent.UntilNextUntapEffects = new List<Func<EffectTiming, ICardEffect>>();
+        }
+    }
+}
+
+#endregion
+
+#region Trash cards from deck top
+
+public class ITrashDeckCards
+{
+    public ITrashDeckCards(List<CardSource> cardSources, ICardEffect cardEffect)
+    {
+        this.cardSources = new List<CardSource>();
+
+        foreach (CardSource cardSource in cardSources)
+        {
+            this.cardSources.Add(cardSource);
+        }
+
+        this.cardEffect = cardEffect;
+    }
+
+    List<CardSource> cardSources { get; set; } = new List<CardSource>();
+    ICardEffect cardEffect { get; set; } = null;
+
+    public IEnumerator TrashDeckCards()
+    {
+        List<CardSource> trashCards = new List<CardSource>();
+
+        foreach (CardSource cardSource in cardSources)
+        {
+            if (cardSource.Owner.LibraryCards.Contains(cardSource))
+            {
+                trashCards.Add(cardSource);
+            }
+        }
+
+        if (trashCards.Count >= 1)
+        {
+            foreach (CardSource cardSource in trashCards)
+            {
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+            }
+
+            #region "When cards are trashed from security" effect
+
+            #region Hashtable setting
+
+            Hashtable hashtable = new Hashtable()
+            {
+                {"DiscardedCards", trashCards},
+                {"CardEffect", cardEffect},
+            };
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(
+                hashtable, EffectTiming.OnDiscardLibrary));
+
+            #endregion
+        }
+    }
+}
+
+#endregion
+
+#region Overflow of ace
+
+public class AceOverflowClass
+{
+    public AceOverflowClass(List<CardSource> cardSources)
+    {
+        _cardSources = cardSources.Clone();
+    }
+
+    List<CardSource> _cardSources = new List<CardSource>();
+
+    public IEnumerator Overflow()
+    {
+        _cardSources = _cardSources
+        .Filter(cardSource => cardSource.IsACE && !cardSource.IsFlipped && CardEffectCommons.IsExistOnBattleArea(cardSource) || CardEffectCommons.IsExistOnBreedingAreaDigimon(cardSource))
+        .OrderBy(cardSource => cardSource.Owner == GManager.instance.turnStateMachine.gameContext.TurnPlayer ? -1 : 1)
+        .ToList();
+
+        foreach (CardSource cardSource in _cardSources)
+        {
+            yield return ContinuousController.instance.StartCoroutine(cardSource.Owner.AddMemory(-cardSource.OverflowMemory, null));
+
+            string log = $"\nOverflow -{cardSource.OverflowMemory}:\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})\n";
+
+            PlayLog.OnAddLog?.Invoke(log);
+        }
+    }
+}
+
+#endregion
+
+#region TrashStack
+
+public class ITrashStack
+{
+    /// <summary>
+    /// Trash Stack Class
+    /// </summary>
+    /// <param name="permanent">Target Permanent</param>
+    /// <param name="TrashCount">Amount of cards to trash</param>
+    /// <param name="cardEffect">Card Effect</param>
+    /// <param name="fromTop">Should trashing start from top, true by default</param>
+    public ITrashStack(Permanent permanent, int TrashCount, ICardEffect cardEffect, bool fromTop = true)
+    {
+        _permanent = permanent;
+        _trashCount = TrashCount;
+        _cardEffect = cardEffect;
+        _fromTop = fromTop;
+    }
+
+    Permanent _permanent = null;
+    int _trashCount;
+    ICardEffect _cardEffect = null;
+    bool _fromTop;
+
+    public IEnumerator TrashStack()
+    {
+        if (_cardEffect == null) yield break;
+        if (_cardEffect.EffectSourceCard == null) yield break;
+        if (_permanent == null) yield break;
+        if (_permanent.TopCard == null) yield break;
+        if (_permanent.ImmuneFromStackTrashing(_cardEffect)) yield break;
+        if (_permanent.TopCard.CanNotBeAffected(_cardEffect)) yield break;
+
+        _trashCount = Math.Min(_permanent.StackCards.Count, _trashCount);
+
+        if (_trashCount >= 1)
+        {
+            int count = 0;
+
+            List<CardSource> selectedCards = new List<CardSource>();
+
+            while (true)
+            {
+                bool StopCondition()
+                {
+                    if (_permanent.HasNoDigivolutionCards)
+                    {
+                        return true;
+                    }
+
+                    if (count >= _trashCount)
+                    {
+                        return true;
+                    }
+
+                    return false;
+                }
+
+                if (StopCondition())
+                {
+                    break;
+                }
+
+                if (count == 0)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateDebuffEffect(_permanent));
+                }
+
+                CardSource cardSource = _permanent.TopCard;
+
+                selectedCards.Add(cardSource);
+
+                yield return ContinuousController.instance.StartCoroutine(new AceOverflowClass(new List<CardSource>() { cardSource }).Overflow());
+
+                yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveFromAllArea(cardSource));
+
+                if (!cardSource.IsToken)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
+                }
+
+                _permanent.ShowingPermanentCard.ShowPermanentData(true);
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().RemoveDigivolveRootEffect(cardSource, _permanent));
+
+                count++;
+            }
+
+            #region "When Top Card is Trashed" effect
+
+            #region Hashtable Setting
+
+            System.Collections.Hashtable hashtable = new System.Collections.Hashtable()
+                        {
+                            {"Permanent", _permanent},
+                            {"CardSources", selectedCards}
+                        };
+
+            #endregion
+
+            yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing
+                .StackSkillInfos(hashtable, EffectTiming.WhenTopCardTrashed));
+
+            #endregion
+
+            #region add log
+
+            if (selectedCards.Count >= 1)
+            {
+                string log = "";
+
+                log += $"\nStack Trashed :";
+
+                foreach (CardSource cardSource in selectedCards)
+                {
+                    if (cardSource != null)
+                    {
+                        log += $"\n{cardSource.BaseENGCardNameFromEntity}({cardSource.CardID})";
+                    }
+                }
+
+                log += "\n";
+
+                PlayLog.OnAddLog?.Invoke(log);
+            }
+
+            #endregion
+        }
+    }
+}
+
+#endregion

+ 11 - 0
Assets/Script/CardController.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c01c4dad8db8bd044b14c76abde39ec2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 55 - 0
Assets/Script/CardDetail.cs

@@ -0,0 +1,55 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using DG.Tweening;
+
+public class CardDetail : MonoBehaviour
+{
+    [Header("card detail HandCard")]
+    public HandCard DetailHandCard;
+
+    public void OpenCardDetail(CardSource cardSource, bool CanLookOpponentCard)
+    {
+        this.gameObject.SetActive(true);
+
+        DetailHandCard.SetUpHandCard(cardSource);
+
+        if (CanLookOpponentCard)
+        {
+            DetailHandCard.SetUpHandCardImage();
+        }
+
+        #region animation
+        DetailHandCard.transform.localPosition = new Vector3(400, 0, 0);
+        DetailHandCard.transform.localScale = new Vector3(5.6f, 5.6f, 5.6f);
+
+        float animationTime = 0.12f;
+
+        var sequence = DOTween.Sequence();
+
+        sequence
+            .Append(DetailHandCard.transform.DOLocalMove(new Vector3(550, 0, 0), animationTime))
+            .Join(DetailHandCard.transform.DOScale(new Vector3(7, 7, 7), animationTime));
+
+        sequence.Play();
+
+        #endregion
+    }
+
+    bool first = false;
+
+    public void CloseCardDetail()
+    {
+        if(first)
+        {
+            if (GManager.instance != null)
+            {
+                GManager.instance.PlayCancelSE ();
+            }
+        }
+
+        first = true;
+        this.gameObject.SetActive(false);
+    }
+}

+ 11 - 0
Assets/Script/CardDetail.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4aa7926eb8000c441a3acb20b98896a4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 63 - 0
Assets/Script/CardDistribution.cs

@@ -0,0 +1,63 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+using System.Linq;
+using UnityEngine.UI;
+
+public class CardDistribution : MonoBehaviour
+{
+    [SerializeField]
+    List<CardDistributionTab> cardDistributionTabs
+    {
+        get
+        {
+            return new List<CardDistributionTab>()
+            {
+                digitama,
+                digimon,
+                tamer,
+                option,
+                level2,
+                level3,
+                level4,
+                level5,
+                level6,
+                level7Over,
+            };
+        }
+    }
+
+    [SerializeField] CardDistributionTab digitama;
+    [SerializeField] CardDistributionTab digimon;
+    [SerializeField] CardDistributionTab tamer;
+    [SerializeField] CardDistributionTab option;
+    [SerializeField] CardDistributionTab level2;
+    [SerializeField] CardDistributionTab level3;
+    [SerializeField] CardDistributionTab level4;
+    [SerializeField] CardDistributionTab level5;
+    [SerializeField] CardDistributionTab level6;
+    [SerializeField] CardDistributionTab level7Over;
+
+    public void Init()
+    {
+        digitama.CardCondition = (cEntity_Base) => cEntity_Base.cardKind == CardKind.DigiEgg;
+        digimon.CardCondition = (cEntity_Base) => cEntity_Base.cardKind == CardKind.Digimon;
+        tamer.CardCondition = (cEntity_Base) => cEntity_Base.cardKind == CardKind.Tamer;
+        option.CardCondition = (cEntity_Base) => cEntity_Base.cardKind == CardKind.Option;
+        level2.CardCondition = (cEntity_Base) => cEntity_Base.Level == 2;
+        level3.CardCondition = (cEntity_Base) => cEntity_Base.Level == 3;
+        level4.CardCondition = (cEntity_Base) => cEntity_Base.Level == 4;
+        level5.CardCondition = (cEntity_Base) => cEntity_Base.Level == 5;
+        level6.CardCondition = (cEntity_Base) => cEntity_Base.Level == 6;
+        level7Over.CardCondition = (cEntity_Base) => cEntity_Base.Level >= 7;
+    }
+
+    public void SetCardDistribution(DeckData deckData)
+    {
+        foreach (CardDistributionTab cardDistributionTab in cardDistributionTabs)
+        {
+            cardDistributionTab.SetCardDistributionTab(deckData);
+        }
+    }
+}

+ 11 - 0
Assets/Script/CardDistribution.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: acf46fe2a0cb5894da833b6afdd21798
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
Assets/Script/CardDistributionTab.cs

@@ -0,0 +1,36 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+using UnityEngine.UI;
+using TMPro;
+using System.Linq;
+
+public class CardDistributionTab : MonoBehaviour
+{
+    [SerializeField] int MaxCount;
+    [SerializeField] TextMeshProUGUI CountText;
+    [SerializeField] Image Bar;
+    public Func<CEntity_Base, bool> CardCondition = null;
+
+    float maxLength = 22f;
+
+    public void SetCardDistributionTab(DeckData deckData)
+    {
+        if(CardCondition != null)
+        {
+            int count = deckData.AllDeckCards().Count(CardCondition);
+
+            float ratio = (float)count / MaxCount;
+
+            if(ratio >= 1)
+            {
+                ratio = 1;
+            }
+
+            CountText.text = count.ToString();
+
+            ((RectTransform)Bar.transform).sizeDelta = new Vector2(((RectTransform)Bar.transform).sizeDelta.x, maxLength * ratio);
+        }
+    }
+}

+ 11 - 0
Assets/Script/CardDistributionTab.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 52e2cdfdd111dc347a3c55096d8354a4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1326 - 0
Assets/Script/CardEffectCommons.cs

@@ -0,0 +1,1326 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Digivolution Requirements
+
+    public enum IgnoreRequirement
+    {
+        None,
+        All,
+        Level,
+        Color
+    }
+
+    #endregion
+
+    #region Play cards as new permanents
+
+    public static IEnumerator PlayPermanentCards(List<CardSource> cardSources, ICardEffect activateClass, bool payCost, bool isTapped, SelectCardEffect.Root root, bool activateETB, bool isBreedingArea = false, int fixedCost = -1)
+    {
+        if (cardSources == null) yield break;
+
+        cardSources = cardSources
+        .Filter(cardSource => cardSource != null)
+        .Filter(cardSource => CanPlayAsNewPermanent(
+            cardSource: cardSource,
+            payCost: payCost,
+            cardEffect: activateClass,
+            isBreedingArea: isBreedingArea,
+            fixedCost: fixedCost));
+
+        if (cardSources.Count == 0) yield break;
+
+        PlayCardClass playCardClass = new PlayCardClass(
+            cardSources: cardSources,
+            hashtable: CardEffectHashtable(activateClass),
+            payCost: payCost,
+            targetPermanent: null,
+            isTapped: isTapped,
+            root: root,
+            activateETB: activateETB);
+
+        if (isBreedingArea)
+            playCardClass.SetIsBreedingArea();
+
+        playCardClass.SetFixedCost(fixedCost);
+
+        yield return ContinuousController.instance.StartCoroutine(playCardClass.PlayCard());
+    }
+
+    #endregion
+
+    #region Play option cards
+
+    public static IEnumerator PlayOptionCards(List<CardSource> cardSources, ICardEffect activateClass, bool payCost, SelectCardEffect.Root root,
+        bool setAddSecurityEndOption = false)
+    {
+        if (cardSources == null) yield break;
+
+        cardSources = cardSources
+        .Filter(cardSource => cardSource != null)
+        .Filter(cardSource => !cardSource.CanNotPlayThisOption);
+
+        if (cardSources.Count == 0) yield break;
+
+        PlayCardClass playCard = new PlayCardClass(
+                cardSources: cardSources,
+                hashtable: CardEffectHashtable(activateClass),
+                payCost: payCost,
+                targetPermanent: null,
+                isTapped: false,
+                root: root,
+                activateETB: true);
+
+        if (activateClass != null)
+        {
+            playCard.SetShowEffect();
+        }
+
+        if (setAddSecurityEndOption)
+        {
+            playCard.SetAddSecurityEndOption();
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(playCard.PlayCard());
+    }
+
+    #endregion
+
+    #region Play Delay Option cards as new permanents
+
+    public static IEnumerator PlaceDelayOptionCards(CardSource card, ICardEffect cardEffect, SelectCardEffect.Root root = SelectCardEffect.Root.Execution)
+    {
+        if (CanPlayAsNewPermanent(cardSource: card, payCost: false, cardEffect: cardEffect, isPlayOption: true))
+        {
+            PlayPermanentClass playPermanent = new PlayPermanentClass(
+                cardSources: new List<CardSource>() { card },
+                hashtable: CardEffectHashtable(cardEffect),
+                targetPermanent: null,
+                isTapped: false,
+                root: root,
+                ActivateETB: true);
+
+            playPermanent.SetISPlayOption();
+
+            yield return ContinuousController.instance.StartCoroutine(playPermanent.PlayPermanent());
+
+            if (IsExistOnBattleArea(card))
+            {
+                card.PermanentOfThisCard().IsPlayedOptionPermanent = true;
+            }
+        }
+    }
+
+    #endregion
+
+    #region Play 1 Token
+
+    public static IEnumerator PlayToken(CEntity_Base tokenData, ICardEffect activateClass, bool isOwnerPermanent, bool isTapped, int quantity = 1)
+    {
+        if (activateClass == null) yield break;
+        if (activateClass.EffectSourceCard == null) yield break;
+        if (tokenData == null) yield break;
+
+        CardSource card = activateClass.EffectSourceCard;
+
+        Player player = isOwnerPermanent ? card.Owner : card.Owner.Enemy;
+
+        if (card.Owner.fieldCardFrames.Count((frame) => frame.IsEmptyFrame() && frame.IsBattleAreaFrame()) >= quantity)
+        {
+            List<CardSource> playCards = new List<CardSource>();
+
+            for (int i = 0; i < quantity; i++)
+            {
+                CardSource tokenCard = CardObjectController.CreateCardSource(
+                player.PlayerID,
+                tokenData,
+                true);
+
+                playCards.Add(tokenCard);
+            }
+
+            if (CanPlayAsNewPermanent(cardSource: playCards[0], payCost: false, cardEffect: activateClass))
+            {
+                yield return ContinuousController.instance.StartCoroutine(new PlayCardClass(
+                    cardSources: playCards,
+                    hashtable: CardEffectHashtable(activateClass),
+                    payCost: false,
+                    targetPermanent: null,
+                    isTapped: isTapped,
+                    root: SelectCardEffect.Root.None,
+                    activateETB: true).PlayCard());
+            }
+        }
+    }
+
+    #endregion
+
+    #region Play 1 [Diaboromon] Token
+
+    public static IEnumerator PlayDiaboromonToken(ICardEffect activateClass, int quantity = 1)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.DiaboromonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false,
+            quantity: quantity
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Amon of Crimson Flame] Token
+
+    public static IEnumerator PlayAmonToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.AmonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Umon of Blue Thunder] Token
+
+    public static IEnumerator PlayUmonToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.UmonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Fujitsumon] Token
+
+    public static IEnumerator PlayFujitsumonToken(ICardEffect activateClass, bool isOwnerPermanent)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.FujitsumonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: isOwnerPermanent,
+            isTapped: true
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Gyuukimon] Token
+
+    public static IEnumerator PlayGyuukimonToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.GyuukimonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [KoHagurumon] Token
+
+    public static IEnumerator PlayKoHagurumonToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.KoHagurumonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Familiar] Token
+
+    public static IEnumerator PlayFamiliarToken(ICardEffect activateClass, int quantity = 1)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.FamiliarToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false,
+            quantity: quantity
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 Self Deleting [Familiar] Token
+
+    public static IEnumerator PlaySelfDeleteFamiliarToken(ICardEffect activateClass, int quantity = 1)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.SelfDeleteFamiliarToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false,
+            quantity: quantity
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Vol�e & Zerdr�cken] Token
+
+    public static IEnumerator PlayVoleeZerdrucken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.VoleeZerdruckenToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Uka-no-Mitama] Token
+
+    public static IEnumerator PlayUkaNoMitama(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.UkaNoMitamaToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [WarGrowlmon] Token
+
+    public static IEnumerator PlayWarGrowlmonToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.WarGrowlmonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Taomon] Token
+
+    public static IEnumerator PlayTaomonToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.TaomonToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Rapidmon] Token
+
+    public static IEnumerator PlayRapidmonToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.RapidmonToken,
+          activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [Pipe-Fox] Token
+
+    public static IEnumerator PlayPipeFox(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.PipeFoxToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+        ));
+    }
+
+    #endregion
+
+    #region Play 1 [AthoRenePor] Token
+
+    public static IEnumerator PlayAthoRenePorToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.AthoRenePorToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+            ));
+    }
+
+    #endregion
+
+    #region Play 1 [Hinukamuy] Token
+
+    public static IEnumerator PlayHinukamuyToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.HinukamuyToken,
+            activateClass: activateClass,
+            isOwnerPermanent: true,
+            isTapped: false
+            ));
+    }
+
+    #endregion
+
+    #region Play 1 [Petrification] Token
+
+    public static IEnumerator PlayPetrificationToken(ICardEffect activateClass)
+    {
+        yield return ContinuousController.instance.StartCoroutine(PlayToken(
+            tokenData: ContinuousController.instance.PetrificationToken,
+            activateClass: activateClass,
+            isOwnerPermanent: false,
+            isTapped: false
+            ));
+    }
+
+    #endregion
+
+    #region Security effect of "add this card to hand"
+
+    public static IEnumerator AddThisCardToHand(CardSource card1, ICardEffect activateClass)
+    {
+        yield return new WaitForSeconds(0.5f);
+
+        yield return ContinuousController.instance.StartCoroutine(card1.Owner.brainStormObject.CloseBrainstrorm(card1));
+
+        yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddHandCards(new List<CardSource>() { card1 }, false, activateClass));
+    }
+
+    #endregion
+
+    #region Delete target permanents, and the effect determines whether the permanent has been deleted or not
+
+    public static IEnumerator DeletePeremanentAndProcessAccordingToResult(List<Permanent> targetPermanents, ICardEffect activateClass, Func<List<Permanent>, IEnumerator> successProcess, Func<IEnumerator> failureProcess)
+    {
+        DestroyPermanentsClass destroyPermanentsClass = new DestroyPermanentsClass(targetPermanents, CardEffectHashtable(activateClass));
+
+        yield return ContinuousController.instance.StartCoroutine(destroyPermanentsClass.Destroy());
+
+        if (targetPermanents.Some((permanent) => destroyPermanentsClass.IsDestroyed(permanent)))
+        {
+            if (successProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(successProcess(destroyPermanentsClass.DestroyedPermanents));
+            }
+        }
+        else
+        {
+            if (failureProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(failureProcess());
+            }
+        }
+    }
+
+    #endregion
+
+    #region Bounce target 1 permanent, and the effect determines whether the permanent has been bounced or not
+
+    public static IEnumerator BouncePeremanentAndProcessAccordingToResult(List<Permanent> targetPermanents, ICardEffect activateClass, IEnumerator successProcess, IEnumerator failureProcess)
+    {
+        HandBounceClaass bouncePermanentClass = new HandBounceClaass(targetPermanents, CardEffectHashtable(activateClass));
+
+        yield return ContinuousController.instance.StartCoroutine(bouncePermanentClass.Bounce());
+
+        if (targetPermanents.Some((permanent) => bouncePermanentClass.IsBounced(permanent)))
+        {
+            if (successProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(successProcess);
+            }
+        }
+        else
+        {
+            if (failureProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(failureProcess);
+            }
+        }
+    }
+
+    #endregion
+
+    #region Deck Bounce target 1 permanent, and the effect determines whether the permanent has been bounced or not
+
+    public static IEnumerator DeckBouncePeremanentAndProcessAccordingToResult(List<Permanent> targetPermanents, ICardEffect activateClass, IEnumerator successProcess, IEnumerator failureProcess)
+    {
+        DeckBottomBounceClass deckBounceClass = new DeckBottomBounceClass(targetPermanents, CardEffectHashtable(activateClass));
+
+        yield return ContinuousController.instance.StartCoroutine(deckBounceClass.DeckBounce());
+
+        if (targetPermanents.Some((permanent) => deckBounceClass.IsDeckBounced(permanent)))
+        {
+            if (successProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(successProcess);
+            }
+        }
+        else
+        {
+            if (failureProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(failureProcess);
+            }
+        }
+    }
+
+    #endregion
+
+    #region Trash target digivolution cards, and the effect determines whether the digivolution cards were trashed or not
+
+    public static IEnumerator TrashDigivolutionCardsAndProcessAccordingToResult(Permanent targetPermanent, List<CardSource> targetDigivolutionCards, ICardEffect activateClass, Func<List<CardSource>, IEnumerator> successProcess, Func<IEnumerator> failureProcess)
+    {
+        ITrashDigivolutionCards trashDigivolutionCards = new ITrashDigivolutionCards(targetPermanent, targetDigivolutionCards, activateClass);
+
+        yield return ContinuousController.instance.StartCoroutine(trashDigivolutionCards.TrashDigivolutionCards());
+
+        if (targetDigivolutionCards.Some((sourceCard) => trashDigivolutionCards.IsTrashed(sourceCard)))
+        {
+            if (successProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(successProcess(trashDigivolutionCards.TrashedCards));
+            }
+        }
+        else
+        {
+            if (failureProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(failureProcess());
+            }
+        }
+    }
+
+    #endregion
+
+    #region Trash target link cards, and the effect determines whether the link cards were trashed or not
+
+    public static IEnumerator TrashLinkCardsAndProcessAccordingToResult(Permanent targetPermanent, List<CardSource> targetLinkCards, ICardEffect activateClass, Func<List<CardSource>, IEnumerator> successProcess, Func<IEnumerator> failureProcess)
+    {
+        ITrashLinkCards trashLinkCards = new ITrashLinkCards(targetPermanent, targetLinkCards, activateClass);
+
+        yield return ContinuousController.instance.StartCoroutine(trashLinkCards.TrashLinkCards());
+
+        if (targetLinkCards.Some((sourceCard) => trashLinkCards.IsTrashed(sourceCard)))
+        {
+            if (successProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(successProcess(trashLinkCards.TrashedLinkCards));
+            }
+        }
+        else
+        {
+            if (failureProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(failureProcess());
+            }
+        }
+    }
+
+    #endregion
+
+    #region Trash Security cards and the effect determines whether the security were trashed or not
+
+    public static IEnumerator TrashSecurityAndProcessAccordingToResult(Player player, int trashAmount, ICardEffect activateClass, bool fromTop, Func<List<CardSource>, IEnumerator> successProcess, Func<IEnumerator> failureProcess)
+    {
+        IDestroySecurity destroySecurity = new IDestroySecurity(player, trashAmount, activateClass, fromTop);
+
+        yield return ContinuousController.instance.StartCoroutine(destroySecurity.DestroySecurity());
+
+        if (destroySecurity.DestroyedSecurity.Any())
+        {
+            if (successProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(successProcess(destroySecurity.DestroyedSecurity));
+            }
+        }
+        else
+        {
+            if (failureProcess != null)
+            {
+                yield return ContinuousController.instance.StartCoroutine(failureProcess());
+            }
+        }
+    }
+
+    #endregion
+
+    #region Trash digivolution cards from top or bottom
+
+    public static IEnumerator TrashDigivolutionCardsFromTopOrBottom(Permanent targetPermanent, int trashCount, bool isFromTop, ICardEffect activateClass, Func<CardSource, bool> cardCondition = null)
+    {
+        if (activateClass == null) yield break;
+        if (targetPermanent == null) yield break;
+        if (targetPermanent.TopCard == null) yield break;
+        if (targetPermanent.DigivolutionCards.Count((cardSource) => !cardSource.CanNotTrashFromDigivolutionCards(activateClass)) == 0) yield break;
+        if (targetPermanent.TopCard.CanNotBeAffected(activateClass)) yield break;
+        if (trashCount <= 0) yield break;
+
+        List<CardSource> trashTargetCards = new List<CardSource>();
+
+        for (int i = 0; i < targetPermanent.DigivolutionCards.Count; i++)
+        {
+            if (trashTargetCards.Count >= trashCount)
+                break;
+
+            int index = isFromTop ? i : targetPermanent.DigivolutionCards.Count - 1 - i;
+
+            CardSource trashTargetCard = targetPermanent.DigivolutionCards[index];
+
+            bool trashCard = true;
+
+            if (cardCondition != null)
+                trashCard = cardCondition(trashTargetCard);
+
+            if (trashCard)
+                trashTargetCards.Add(trashTargetCard);
+        }
+
+        yield return ContinuousController.instance.StartCoroutine(new ITrashDigivolutionCards(targetPermanent, trashTargetCards, activateClass).TrashDigivolutionCards());
+    }
+
+    #endregion
+
+    #region this Option card's Main effect
+
+    public static ActivateClass OptionMainEffect(CardSource card) => card.EffectList(EffectTiming.OptionSkill).Find(cardEffect => cardEffect != null && cardEffect is ActivateClass && cardEffect.EffectDiscription.Contains("[Main]")) as ActivateClass;
+
+    #endregion
+
+    #region this Option card's Security effect
+
+    public static ActivateClass OptionSecurityEffect(CardSource card) => card.EffectList(EffectTiming.SecuritySkill).Find(cardEffect => cardEffect != null && cardEffect is ActivateClass && cardEffect.EffectDiscription.Contains("[Security]")) as ActivateClass;
+
+    #endregion
+
+    #region Add Option's Security effect that "Activate this card's Main effect" to cardEffects
+
+    public static void AddActivateMainOptionSecurityEffect(CardSource card, ref List<ICardEffect> cardEffects, string effectName, string effectDiscription = "", Func<ICardEffect, IEnumerator> afterMainEffect = null)
+    {
+        if (OptionMainEffect(card) == null) return;
+
+        cardEffects.Add(CardEffectFactory.ActivateMainOptionSecurityEffect(card, effectName, effectDiscription, afterMainEffect));
+    }
+
+    #endregion
+
+    #region Target permanent Digivolves into Digimon card from hand or trash
+
+    public static IEnumerator DigivolveIntoHandOrTrashCard(
+        Permanent targetPermanent,
+        Func<CardSource, bool> cardCondition,
+        bool payCost,
+        (int reduceCost, Func<CardSource, bool> reduceCostCardCondition)? reduceCostTuple,
+        (int fixedCost, Func<CardSource, bool> fixedCostCardCondition)? fixedCostTuple,
+        int ignoreDigivolutionRequirementFixedCost,
+        bool isHand,
+        ICardEffect activateClass,
+        IEnumerator successProcess,
+        //bool ignoreLevel = false,
+        bool ignoreSelection = false,
+        IgnoreRequirement ignoreRequirements = IgnoreRequirement.None,
+        IEnumerator failedProcess = null,
+        bool isOptional = true)
+    {
+        if (targetPermanent == null) yield break;
+        if (targetPermanent.TopCard == null) yield break;
+        if (activateClass == null) yield break;
+        if (activateClass.EffectSourceCard == null) yield break;
+
+        Player owner = targetPermanent.TopCard.Owner;
+        SelectCardEffect.Root root = isHand ? SelectCardEffect.Root.Hand : SelectCardEffect.Root.Trash;
+        bool ignoreDigivolutionRequirement = !ignoreRequirements.Equals(IgnoreRequirement.None) || ignoreDigivolutionRequirementFixedCost >= 0;//  ignoreDigivolutionRequirementFixedCost >= 0 || ignoreRequirements;
+
+        int fixedCost = -1;
+
+        bool successful = false;
+
+        if (fixedCostTuple != null)
+        {
+            fixedCost = fixedCostTuple.Value.fixedCost;
+        }
+
+        if (ignoreDigivolutionRequirement)
+        {
+            fixedCost = ignoreDigivolutionRequirementFixedCost;
+        }
+
+        bool CanSelectCardCondition(CardSource cardSource)
+        {
+            if (cardSource.IsDigimon)
+            {
+                if (cardCondition == null || cardCondition(cardSource))
+                {
+                    if (!cardSource.CanNotEvolve(targetPermanent))
+                    {
+                        bool isBreeding = cardSource.Owner.GetBreedingAreaPermanents().Contains(targetPermanent);
+
+                        if (cardSource.CanPlayCardTargetFrame(
+                            frame: targetPermanent.PermanentFrame,
+                            PayCost: payCost,
+                            cardEffect: activateClass,
+                            root: root,
+                            fixedCost: fixedCost,
+                            ignore: ignoreRequirements,
+                            isBreedingArea: isBreeding))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        #region reduce cost
+
+        Func<EffectTiming, ICardEffect> getChangeCostEffect = null;
+
+        if (reduceCostTuple != null)
+        {
+            bool PermanentCondition(Permanent permanent)
+            {
+                return permanent == targetPermanent;
+            }
+
+            bool CardCondition(CardSource cardSource)
+            {
+                if (cardSource != null)
+                {
+                    if (cardSource.Owner == owner)
+                    {
+                        if (reduceCostTuple.Value.reduceCostCardCondition == null || reduceCostTuple.Value.reduceCostCardCondition(cardSource))
+                        {
+                            return true;
+                        }
+                    }
+                }
+
+                return false;
+            }
+
+            getChangeCostEffect = ChangeDigivolutionCostPlayerEffect(
+                permanentCondition: PermanentCondition,
+                cardCondition: CardCondition,
+                rootCondition: null,
+                changeValue: -reduceCostTuple.Value.reduceCost,
+                activateClass: activateClass,
+                setFixedCost: false);
+
+            if (getChangeCostEffect != null)
+            {
+                AddEffectToPlayer(
+                    effectDuration: EffectDuration.UntilCalculateFixedCost,
+                    card: targetPermanent.TopCard,
+                    cardEffect: null,
+                    timing: EffectTiming.None,
+                    getCardEffect: getChangeCostEffect);
+            }
+        }
+
+        #endregion
+
+        #region set fixed cost
+
+        Func<EffectTiming, ICardEffect> getFixedCostEffect = null;
+
+        if (fixedCostTuple != null)
+        {
+            bool PermanentCondition(Permanent permanent)
+            {
+                return permanent == targetPermanent;
+            }
+
+            bool CardCondition(CardSource cardSource)
+            {
+                if (cardSource != null)
+                {
+                    if (cardSource.Owner == owner)
+                    {
+                        if (fixedCostTuple.Value.fixedCostCardCondition == null || fixedCostTuple.Value.fixedCostCardCondition(cardSource))
+                        {
+                            return true;
+                        }
+                    }
+                }
+
+                return false;
+            }
+
+            getFixedCostEffect = ChangeDigivolutionCostPlayerEffect(
+                permanentCondition: PermanentCondition,
+                cardCondition: CardCondition,
+                rootCondition: null,
+                changeValue: fixedCost,
+                activateClass: activateClass,
+                setFixedCost: true);
+
+            if (getChangeCostEffect != null)
+            {
+                AddEffectToPlayer(
+                    effectDuration: EffectDuration.UntilCalculateFixedCost,
+                    card: targetPermanent.TopCard,
+                    cardEffect: null,
+                    timing: EffectTiming.None,
+                    getCardEffect: getFixedCostEffect);
+            }
+        }
+
+        #endregion
+
+        #region ignore digivolution requirement
+
+        Func<EffectTiming, ICardEffect> getIgnoreDigivolutionRequirementEffect = null;
+
+        if (ignoreDigivolutionRequirement)
+        {
+            bool PermanentCondition(Permanent permanent)
+            {
+                return permanent == targetPermanent;
+            }
+
+            bool CardCondition(CardSource cardSource)
+            {
+                if (cardSource == null)
+                {
+                    return false;
+                }
+
+                if (cardSource.Owner != owner)
+                {
+                    return false;
+                }
+
+                if (cardCondition == null || cardCondition(cardSource))
+                {
+                    return true;
+                }
+
+                return false;
+            }
+
+            getIgnoreDigivolutionRequirementEffect = GainIgnoreDigivolutionRequirementPlayerEffect(
+                permanentCondition: PermanentCondition,
+                cardCondition: CardCondition,
+                ignoreDigivolutionRequirement: ignoreDigivolutionRequirement,
+                digivolutionCost: fixedCost,
+                activateClass: activateClass);
+
+            if (getIgnoreDigivolutionRequirementEffect != null)
+            {
+                AddEffectToPlayer(
+                effectDuration: EffectDuration.UntilCalculateFixedCost,
+                card: targetPermanent.TopCard,
+                cardEffect: null,
+                timing: EffectTiming.None,
+                getCardEffect: getIgnoreDigivolutionRequirementEffect);
+            }
+        }
+
+        #endregion
+
+        List<CardSource> selectedCards = new List<CardSource>();
+
+        IEnumerator SelectCardCoroutine(CardSource cardSource)
+        {
+            selectedCards.Add(cardSource);
+
+            yield return null;
+        }
+
+        if (isHand)
+        {
+            if (owner.HandCards.Count(CanSelectCardCondition) >= 1)
+            {
+                int maxCount = Mathf.Min(1, owner.HandCards.Count(CanSelectCardCondition));
+
+                SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                selectHandEffect.SetUp(
+                    selectPlayer: owner,
+                    canTargetCondition: CanSelectCardCondition,
+                    canTargetCondition_ByPreSelecetedList: null,
+                    canEndSelectCondition: null,
+                    maxCount: maxCount,
+                    canNoSelect: isOptional,
+                    canEndNotMax: false,
+                    isShowOpponent: true,
+                    selectCardCoroutine: SelectCardCoroutine,
+                    afterSelectCardCoroutine: null,
+                    mode: SelectHandEffect.Mode.Custom,
+                    cardEffect: activateClass);
+
+                selectHandEffect.SetUpCustomMessage("Select 1 card to digivolve.", "The opponent is selecting 1 card to digivolve.");
+                selectHandEffect.SetUpCustomMessage_ShowCard("Selected Card");
+
+                yield return ContinuousController.instance.StartCoroutine(selectHandEffect.Activate());
+            }
+        }
+        else
+        {
+            if (HasMatchConditionOwnersCardInTrash(targetPermanent.TopCard, CanSelectCardCondition) && !ignoreSelection)
+            {
+                int maxCount = 1;
+
+                SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                selectCardEffect.SetUp(
+                            canTargetCondition: CanSelectCardCondition,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            canNoSelect: () => isOptional,
+                            selectCardCoroutine: SelectCardCoroutine,
+                            afterSelectCardCoroutine: null,
+                            message: "Select 1 card to digivolve.",
+                            maxCount: maxCount,
+                            canEndNotMax: false,
+                            isShowOpponent: true,
+                            mode: SelectCardEffect.Mode.Custom,
+                            root: SelectCardEffect.Root.Trash,
+                            customRootCardList: null,
+                            canLookReverseCard: true,
+                            selectPlayer: owner,
+                            cardEffect: activateClass);
+
+                selectCardEffect.SetUpCustomMessage("Select 1 card to digivolve.", "The opponent is selecting 1 card to digivolve.");
+                selectCardEffect.SetUpCustomMessage_ShowCard("Selected Card");
+
+                yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+            }
+            else
+            {
+                if (ignoreSelection)
+                    selectedCards.Add(activateClass.EffectSourceCard);
+            }
+        }
+
+        PlayCardClass playCardClass = new PlayCardClass(
+            cardSources: selectedCards,
+            hashtable: CardEffectHashtable(activateClass),
+            payCost: payCost,
+            targetPermanent: targetPermanent,
+            isTapped: false,
+            root: root,
+            activateETB: true);
+
+        //if (ignoreRequirements.Equals(IgnoreRequirement.All) || ignoreRequirements.Equals(IgnoreRequirement.Level))
+        //    playCardClass.SetIgnoreLevel();
+        playCardClass.SetIgnoreRequirements(ignoreRequirements);
+
+        //!ignoreRequirements
+        if (fixedCost >= 0)
+            playCardClass.SetFixedCost(fixedCost);
+
+        yield return ContinuousController.instance.StartCoroutine(playCardClass.PlayCard());
+
+        #region release effect
+
+        if (getChangeCostEffect != null) owner.UntilCalculateFixedCostEffect.Remove(getChangeCostEffect);
+
+        #endregion
+
+        #region release effect
+
+        if (getFixedCostEffect != null) owner.UntilCalculateFixedCostEffect.Remove(getFixedCostEffect);
+
+        #endregion
+
+        #region release effect
+
+        if (getIgnoreDigivolutionRequirementEffect != null) owner.UntilCalculateFixedCostEffect.Remove(getIgnoreDigivolutionRequirementEffect);
+
+        #endregion
+
+        if (selectedCards.Count >= 1)
+        {
+            if (IsDigivolvedByTheEffect(targetPermanent, selectedCards[0], activateClass))
+            {
+                successful = true;
+            }
+        }
+
+        if (successful)
+        {
+            if (successProcess != null)
+                yield return ContinuousController.instance.StartCoroutine(successProcess);
+        }
+        else
+        {
+            if (failedProcess != null)
+                yield return ContinuousController.instance.StartCoroutine(failedProcess);
+        }
+    }
+
+    #endregion
+
+    #region Target permanent Digivolves into Digimon card execution area
+
+    public static IEnumerator DigivolveIntoExcecutingAreaCard(
+        Permanent targetPermanent,
+        Func<CardSource, bool> cardCondition,
+        bool payCost,
+        (int reduceCost, Func<CardSource, bool> reduceCostCardCondition)? reduceCostTuple,
+        (int fixedCost, Func<CardSource, bool> fixedCostCardCondition)? fixedCostTuple,
+        int ignoreDigivolutionRequirementFixedCost,
+        ICardEffect activateClass,
+        IEnumerator successProcess,
+        bool ignoreSelection = false,
+        IgnoreRequirement ignoreRequirements = IgnoreRequirement.None)
+    {
+        if (targetPermanent == null) yield break;
+        if (targetPermanent.TopCard == null) yield break;
+        if (activateClass == null) yield break;
+        if (activateClass.EffectSourceCard == null) yield break;
+
+        Player owner = targetPermanent.TopCard.Owner;
+        SelectCardEffect.Root root = SelectCardEffect.Root.Execution;
+        bool ignoreDigivolutionRequirement = !ignoreRequirements.Equals(IgnoreRequirement.None) || ignoreDigivolutionRequirementFixedCost >= 0;//  ignoreDigivolutionRequirementFixedCost >= 0 || ignoreRequirements;
+
+        int fixedCost = -1;
+
+        if (fixedCostTuple != null)
+        {
+            fixedCost = fixedCostTuple.Value.fixedCost;
+        }
+
+        if (ignoreDigivolutionRequirement)
+        {
+            fixedCost = ignoreDigivolutionRequirementFixedCost;
+        }
+        bool CanSelectCardCondition(CardSource cardSource)
+        {
+            if (cardSource.IsDigimon)
+            {
+                if (cardCondition == null || cardCondition(cardSource))
+                {
+                    if (!cardSource.CanNotEvolve(targetPermanent))
+                    {
+                        if (cardSource.CanPlayCardTargetFrame(
+                            frame: targetPermanent.PermanentFrame,
+                            PayCost: payCost,
+                            cardEffect: activateClass,
+                            root: root,
+                            fixedCost: fixedCost,
+                            ignore: ignoreRequirements))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        #region reduce cost
+
+        Func<EffectTiming, ICardEffect> getChangeCostEffect = null;
+
+        if (reduceCostTuple != null)
+        {
+            bool PermanentCondition(Permanent permanent)
+            {
+                return permanent == targetPermanent;
+            }
+
+            bool CardCondition(CardSource cardSource)
+            {
+                if (cardSource != null)
+                {
+                    if (cardSource.Owner == owner)
+                    {
+                        if (reduceCostTuple.Value.reduceCostCardCondition == null || reduceCostTuple.Value.reduceCostCardCondition(cardSource))
+                        {
+                            return true;
+                        }
+                    }
+                }
+
+                return false;
+            }
+
+            getChangeCostEffect = ChangeDigivolutionCostPlayerEffect(
+                permanentCondition: PermanentCondition,
+                cardCondition: CardCondition,
+                rootCondition: null,
+                changeValue: -reduceCostTuple.Value.reduceCost,
+                activateClass: activateClass,
+                setFixedCost: false);
+
+            if (getChangeCostEffect != null)
+            {
+                AddEffectToPlayer(
+                    effectDuration: EffectDuration.UntilCalculateFixedCost,
+                    card: targetPermanent.TopCard,
+                    cardEffect: null,
+                    timing: EffectTiming.None,
+                    getCardEffect: getChangeCostEffect);
+            }
+        }
+
+        #endregion
+
+        #region set fixed cost
+
+        Func<EffectTiming, ICardEffect> getFixedCostEffect = null;
+
+        if (fixedCostTuple != null)
+        {
+            bool PermanentCondition(Permanent permanent)
+            {
+                return permanent == targetPermanent;
+            }
+
+            bool CardCondition(CardSource cardSource)
+            {
+                if (cardSource != null)
+                {
+                    if (cardSource.Owner == owner)
+                    {
+                        if (fixedCostTuple.Value.fixedCostCardCondition == null || fixedCostTuple.Value.fixedCostCardCondition(cardSource))
+                        {
+                            return true;
+                        }
+                    }
+                }
+
+                return false;
+            }
+
+            getFixedCostEffect = ChangeDigivolutionCostPlayerEffect(
+                permanentCondition: PermanentCondition,
+                cardCondition: CardCondition,
+                rootCondition: null,
+                changeValue: fixedCost,
+                activateClass: activateClass,
+                setFixedCost: true);
+
+            if (getChangeCostEffect != null)
+            {
+                AddEffectToPlayer(
+                    effectDuration: EffectDuration.UntilCalculateFixedCost,
+                    card: targetPermanent.TopCard,
+                    cardEffect: null,
+                    timing: EffectTiming.None,
+                    getCardEffect: getFixedCostEffect);
+            }
+        }
+
+        #endregion
+
+        #region ignore digivolution requirement
+
+        Func<EffectTiming, ICardEffect> getIgnoreDigivolutionRequirementEffect = null;
+
+        if (ignoreDigivolutionRequirement)
+        {
+            bool PermanentCondition(Permanent permanent)
+            {
+                return permanent == targetPermanent;
+            }
+
+            bool CardCondition(CardSource cardSource)
+            {
+                if (cardSource == null)
+                {
+                    return false;
+                }
+
+                if (cardSource.Owner != owner)
+                {
+                    return false;
+                }
+
+                if (cardCondition == null || cardCondition(cardSource))
+                {
+                    return true;
+                }
+
+                return false;
+            }
+
+            getIgnoreDigivolutionRequirementEffect = GainIgnoreDigivolutionRequirementPlayerEffect(
+                permanentCondition: PermanentCondition,
+                cardCondition: CardCondition,
+                ignoreDigivolutionRequirement: ignoreDigivolutionRequirement,
+                digivolutionCost: fixedCost,
+                activateClass: activateClass);
+
+            if (getIgnoreDigivolutionRequirementEffect != null)
+            {
+                AddEffectToPlayer(
+                effectDuration: EffectDuration.UntilCalculateFixedCost,
+                card: targetPermanent.TopCard,
+                cardEffect: null,
+                timing: EffectTiming.None,
+                getCardEffect: getIgnoreDigivolutionRequirementEffect);
+            }
+        }
+
+        #endregion
+
+        List<CardSource> selectedCards = new List<CardSource>();
+
+        IEnumerator SelectCardCoroutine(CardSource cardSource)
+        {
+            selectedCards.Add(cardSource);
+
+            yield return null;
+        }
+
+        if (owner.ExecutingCards.Count(CanSelectCardCondition) > 1)
+        {
+            int maxCount = 1;
+
+            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+            selectCardEffect.SetUp(
+                        canTargetCondition: CanSelectCardCondition,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 card to digivolve.",
+                        maxCount: maxCount,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.Custom,
+                        root: SelectCardEffect.Root.Execution,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: owner,
+                        cardEffect: activateClass);
+
+            selectCardEffect.SetUpCustomMessage("Select 1 card to digivolve.", "The opponent is selecting 1 card to digivolve.");
+            selectCardEffect.SetUpCustomMessage_ShowCard("Selected Card");
+
+            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+        }
+        else
+        {
+            selectedCards.Add(activateClass.EffectSourceCard);
+        }
+
+        PlayCardClass playCardClass = new PlayCardClass(
+            cardSources: selectedCards,
+            hashtable: CardEffectHashtable(activateClass),
+            payCost: payCost,
+            targetPermanent: targetPermanent,
+            isTapped: false,
+            root: root,
+            activateETB: true);
+
+        playCardClass.SetIgnoreRequirements(ignoreRequirements);
+
+        if (!ignoreDigivolutionRequirement && fixedCost >= 0) playCardClass.SetFixedCost(fixedCost);
+
+        yield return ContinuousController.instance.StartCoroutine(playCardClass.PlayCard());
+
+        #region release effect
+
+        if (getChangeCostEffect != null) owner.UntilCalculateFixedCostEffect.Remove(getChangeCostEffect);
+
+        #endregion
+
+        #region release effect
+
+        if (getFixedCostEffect != null) owner.UntilCalculateFixedCostEffect.Remove(getFixedCostEffect);
+
+        #endregion
+
+        #region release effect
+
+        if (getIgnoreDigivolutionRequirementEffect != null) owner.UntilCalculateFixedCostEffect.Remove(getIgnoreDigivolutionRequirementEffect);
+
+        #endregion
+
+        if (selectedCards.Count >= 1)
+        {
+            if (IsDigivolvedByTheEffect(targetPermanent, selectedCards[0], activateClass))
+            {
+                if (successProcess != null)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(successProcess);
+                }
+            }
+        }
+    }
+
+    #endregion
+
+    #region Get the effect given by EffectTiming
+
+    public static Func<EffectTiming, ICardEffect> GetCardEffectByEffectTiming(EffectTiming timing, ICardEffect cardEffect) => (_timing) => _timing == timing ? cardEffect : null;
+
+    #endregion
+
+    #region Draw cards and trash cards
+
+    public static IEnumerator DrawAndDiscardCards((Player drawPlayer, Player trashPlayer) player,
+                                                  int drawAmount,
+                                                  int trashAmount,
+                                                  CardSource card,
+                                                  ICardEffect activateClass,
+                                                  Func<CardSource, bool> canTrashTargetCondition = null,
+                                                  Func<List<CardSource>, CardSource, bool> canTargetCondition_ByPreSelecetedList = null,
+                                                  Func<List<CardSource>, bool> canEndSelectCondition = null,
+                                                  bool canNoSelect = false,
+                                                  bool canEndNotMax = false,
+                                                  bool isShowOpponent = true,
+                                                  Func<List<CardSource>, IEnumerator> afterSelectPermanentCoroutine = null)
+    {
+        // Callback Setup
+        Func<List<CardSource>, IEnumerator> AfterSelectCardCoroutine = afterSelectPermanentCoroutine ?? null;
+
+        // Variable setup
+        Func<CardSource, bool> targetTrashCondition = canTrashTargetCondition ?? (cs => true);
+
+        yield return ContinuousController.instance.StartCoroutine(new DrawClass(player.drawPlayer, drawAmount, activateClass).Draw());
+        SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+        selectHandEffect.SetUp(
+            selectPlayer: player.trashPlayer,
+            canTargetCondition: targetTrashCondition,
+            canTargetCondition_ByPreSelecetedList: canTargetCondition_ByPreSelecetedList,
+            canEndSelectCondition: canEndSelectCondition,
+            maxCount: trashAmount,
+            canNoSelect: canNoSelect,
+            canEndNotMax: canEndNotMax,
+            isShowOpponent: isShowOpponent,
+            selectCardCoroutine: null,
+            afterSelectCardCoroutine: AfterSelectCardCoroutine,
+            mode: SelectHandEffect.Mode.Discard,
+            cardEffect: activateClass);
+
+        yield return ContinuousController.instance.StartCoroutine(selectHandEffect.Activate());
+    }
+
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9fb521e1694f2c1498849cd54c85dbad
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Script/CardEffectCommons.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 167763466579e6349aa088f9569afd3b
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Script/CardEffectCommons/CanUseEffects.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 19b528d855e3d7941965801f0c09c15a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 41 - 0
Assets/Script/CardEffectCommons/CanUseEffects/CanSuspend.cs

@@ -0,0 +1,41 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can activate effects by suspending oneself
+    public static bool CanActivateSuspendCostEffect(CardSource card, bool includeBreeding = false)
+    {
+        return CanActivatePermanentSuspendCostEffect(card.PermanentOfThisCard(), includeBreeding);
+    }
+    #endregion
+
+    #region Can activate effects by suspending permanent
+    public static bool CanActivatePermanentSuspendCostEffect(Permanent permanent, bool includeBreeding = false)
+    {
+        if (IsPermanentExistsOnBattleArea(permanent))
+        {
+            if (!permanent.IsSuspended && permanent.CanSuspend)
+            {
+                return true;
+            }
+        }
+
+        if (includeBreeding)
+        {
+            if (IsPermanentExistsOnBreedingArea(permanent))
+            {
+                if (!permanent.IsSuspended && permanent.CanSuspend)
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/CanSuspend.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e5d5ea049cf6bc1438689dfc334de60a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
Assets/Script/CardEffectCommons/CanUseEffects/CanUnsuspend.cs

@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can unsuspend oneselef
+    public static bool CanUnsuspend(Permanent permanent)
+    {
+        return permanent != null && permanent.TopCard != null && permanent.IsSuspended && permanent.CanUnsuspend;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/CanUnsuspend.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 88ae92895756fbf41be0a1155e82227a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
Assets/Script/CardEffectCommons/CanUseEffects/IgnoreBattle.cs

@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Ignore battle Security Effect condition
+    public static bool CanUseIgnoreBattle(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerOptionMainEffect(hashtable, card);
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/IgnoreBattle.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c205a0024ec306148b0e6ceaec27871c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 47 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnAddDigivolutionCards.cs

@@ -0,0 +1,47 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When digivolution card is added due to effect" effect
+    public static bool CanTriggerOnAddDigivolutionCard(Hashtable hashtable, Func<Permanent, bool> permanentCondition, Func<ICardEffect, bool> cardEffectCondition, Func<CardSource, bool> cardCondition)
+    {
+        if (hashtable != null)
+        {
+            Permanent Permanent = GetPermanentFromHashtable(hashtable);
+
+            if (Permanent != null)
+            {
+                if (Permanent.TopCard != null)
+                {
+                    if (permanentCondition == null || permanentCondition(Permanent))
+                    {
+                        ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+                        if (CardEffect != null)
+                        {
+                            if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+                            {
+                                List<CardSource> CardSources = GetCardSourcesFromHashtable(hashtable);
+
+                                if (CardSources != null)
+                                {
+                                    if (CardSources.Count(cardSource => cardCondition == null || cardCondition(cardSource)) >= 1)
+                                    {
+                                        return true;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnAddDigivolutionCards.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5e5c09c8c2e4dda48a9fb59ebfc435f6
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 47 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnAttack.cs

@@ -0,0 +1,47 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger [On Attack] effect
+    public static bool CanTriggerOnAttack(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerOnPermanentAttack(hashtable, (permanent) => permanent.cardSources.Contains(card));
+    }
+    #endregion
+
+    #region Can trigger "when permanent attacks" effect
+    public static bool CanTriggerOnPermanentAttack(Hashtable hashtable, Func<Permanent, bool> permanentCondition)
+    {
+        if (hashtable != null)
+        {
+            if (hashtable.ContainsKey("AttackingPermanent"))
+            {
+                if (hashtable["AttackingPermanent"] is Permanent)
+                {
+                    Permanent AttackingPermanent = (Permanent)hashtable["AttackingPermanent"];
+
+                    if (AttackingPermanent != null)
+                    {
+                        if (AttackingPermanent.TopCard != null)
+                        {
+                            if (permanentCondition != null)
+                            {
+                                if (permanentCondition(AttackingPermanent))
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnAttack.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ec7b3bdcde0cf7c4dac5d698de0f5b7a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 22 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnAttackTargetSwitch.cs

@@ -0,0 +1,22 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "when this permanent 's attack target switched" effect
+    public static bool CanTriggerOnAttackTargetSwitch(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerOnPermanentAttackTargetSwitch(hashtable, permanent => permanent.cardSources.Contains(card));
+    }
+    #endregion
+
+    #region Can trigger "when attack target switched" effect
+    public static bool CanTriggerOnPermanentAttackTargetSwitch(Hashtable hashtable, Func<Permanent, bool> permanentCondition)
+    {
+        return CanTriggerOnPermanentAttack(hashtable, permanentCondition);
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnAttackTargetSwitch.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1a3c5361c4508c546a05eb29a5ef2015
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 33 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnCardsAddedToHand.cs

@@ -0,0 +1,33 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "an effect adds a card to 1 player's hand" effect
+    public static bool CanTriggerOnHandAdded(Hashtable hashtable, Player player, Func<ICardEffect, bool> cardEffectCondition)
+    {
+        List<Player> Players = GetPlayersFromHashtable(hashtable);
+
+        if (Players != null)
+        {
+            if (Players.Contains(player))
+            {
+                ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+                if (CardEffect != null)
+                {
+                    if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnCardsAddedToHand.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5f705d282dfd9b74b980cc912f8221d1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 38 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToHandFromTrash.cs

@@ -0,0 +1,38 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When your cards return to Hand from tash" effects
+
+    public static bool CanTriggerWhenOwnerCardsReturnToHandFromTrash(Hashtable hashtable, Func<CardSource, bool> cardCondition, CardSource card)
+    {
+        bool CardCondition(CardSource cardSource) => cardSource.Owner == card.Owner && (cardCondition == null || cardCondition(cardSource));
+
+        return CanTriggerWhenCardsReturnToHandFromTrash(hashtable, CardCondition, card);
+    }
+    #endregion
+
+    #region Can trigger "When cards return to hand from tash" effects
+
+    public static bool CanTriggerWhenCardsReturnToHandFromTrash(Hashtable hashtable, Func<CardSource, bool> cardCondition, CardSource card)
+    {
+        List<CardSource> CardSources = GetCardSourcesFromHashtable(hashtable);
+
+        if (CardSources != null)
+        {
+            CardSources = CardSources.Filter(cardSource => !cardSource.IsDigiEgg && (cardCondition == null || cardCondition(cardSource)));
+
+            if (CardSources.Count >= 1)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToHandFromTrash.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 031a7c9303623e546b03be5bef9a6fc2
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 38 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToLibraryFromTrash.cs

@@ -0,0 +1,38 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When your cards return to library from tash" effects
+
+    public static bool CanTriggerWhenOwnerCardsReturnToLibraryFromTrash(Hashtable hashtable, Func<CardSource, bool> cardCondition, CardSource card)
+    {
+        bool CardCondition(CardSource cardSource) => cardSource.Owner == card.Owner && (cardCondition == null || cardCondition(cardSource));
+
+        return CanTriggerWhenCardsReturnToLibraryFromTrash(hashtable, CardCondition, card);
+    }
+    #endregion
+
+    #region Can trigger "When cards return to library from tash" effects
+
+    public static bool CanTriggerWhenCardsReturnToLibraryFromTrash(Hashtable hashtable, Func<CardSource, bool> cardCondition, CardSource card)
+    {
+        List<CardSource> CardSources = GetCardSourcesFromHashtable(hashtable);
+
+        if (CardSources != null)
+        {
+            CardSources = CardSources.Filter(cardSource => !cardSource.IsDigiEgg && (cardCondition == null || cardCondition(cardSource)));
+
+            if (CardSources.Count >= 1)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnCardsReturnToLibraryFromTrash.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6139229390d4e6f41b7a53addad768df
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 365 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnDeletion.cs

@@ -0,0 +1,365 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+using UnityEditor.Rendering;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger
+
+    #region Can trigger [On Deletion] effect
+    public static bool CanTriggerOnDeletion(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerOnPermanentDeleted(hashtable, (permanent) => permanent.cardSources.Contains(card));
+    }
+    #endregion
+
+    #region Can trigger "when permanent is deleted" effect
+    public static bool CanTriggerOnPermanentDeleted(Hashtable hashtable, Func<Permanent, bool> permanentCondition)
+    {
+        List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+
+        if (hashtables != null)
+        {
+            foreach (Hashtable hashtable1 in hashtables)
+            {
+                Permanent permanent = GetPermanentFromHashtable(hashtable1);
+
+                if (permanent != null)
+                {
+                    if (permanent.TopCard != null)
+                    {
+                        if (permanentCondition != null)
+                        {
+                            if (permanentCondition(permanent))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Can trigger "when permanent is deleted by battle" effects
+    public static bool IsByBattle(Hashtable hashtable)
+    {
+        return GetBattleFromHashtable(hashtable) != null;
+    }
+    #endregion
+
+    #region Can trigger "when permanent is deleted or played by effect that satisfies the condition" effects
+    public static bool IsByEffect(Hashtable hashtable, Func<ICardEffect, bool> cardEffectCondition)
+    {
+        ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+        if (CardEffect != null)
+        {
+            if (CardEffect.EffectSourceCard != null)
+            {
+                if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #endregion
+
+    #region Can activate
+
+    #region Can activate [On Deletion] effect(not inherited)
+    public static bool CanActivateOnDeletion(CardSource card)
+    {
+        return IsExistOnTrash(card);
+    }
+    #endregion
+
+    #region Can activate [On Deletion] effect(inherited)
+    public static bool CanActivateOnDeletionInherited(Hashtable hashtable, CardSource card)
+    {
+        if (IsTopCardInTrashOnDeletion(hashtable))
+        {
+            if (IsTopCardSamePermanent(hashtable, card))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Whether TopCard is in trash when check [On Deletion] effect
+    public static bool IsTopCardInTrashOnDeletion(Hashtable hashtable)
+    {
+        List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+
+        if (hashtables != null)
+        {
+            foreach (Hashtable hashtable1 in hashtables)
+            {
+                CardSource TopCard = GetTopCardFromOneHashtable(hashtable1);
+
+                if (TopCard != null)
+                {
+                    if (IsExistOnTrash(TopCard) || TopCard.IsToken)
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Whether the card that uses the effect and the top card belonged to the same permanent
+    public static bool IsTopCardSamePermanent(Hashtable hashtable, CardSource card)
+    {
+        if (card == null) return false;
+        if (card.PermanentJustBeforeRemoveField == null) return false;
+
+        List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+
+        if (hashtables != null)
+        {
+            foreach (Hashtable hashtable1 in hashtables)
+            {
+                CardSource TopCard = GetTopCardFromOneHashtable(hashtable1);
+
+                if (TopCard != null)
+                {
+                    if (TopCard.PermanentJustBeforeRemoveField != null)
+                    {
+                        if (card.PermanentJustBeforeRemoveField == TopCard.PermanentJustBeforeRemoveField)
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Can activate [On Deletion] effect that can activate if the permanent conains specific name
+    public static bool CanActivateSelfOnDeletionWithContainingCardName(Hashtable hashtable, string name, CardSource card)
+    {
+        return CanActivateOnDeletionWithContainingCardName(
+            hashtable: hashtable,
+            name: name,
+            cardCondition: cardSource => cardSource == card
+        );
+    }
+
+    public static bool CanActivateOnDeletionWithContainingCardName(
+        Hashtable hashtable,
+        string name,
+        Func<CardSource, bool> cardCondition)
+    {
+        List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+
+        if (hashtables != null)
+        {
+            foreach (Hashtable hashtable1 in hashtables)
+            {
+                if (hashtable1 != null)
+                {
+                    List<CardSource> CardSources = GetCardSourcesFromHashtable(hashtable1);
+
+                    if (CardSources != null)
+                    {
+                        if (CardSources.Some(cardSource => cardCondition == null || cardCondition(cardSource)))
+                        {
+                            if (hashtable1.ContainsKey("CardNames"))
+                            {
+                                if (hashtable1["CardNames"] is List<string>)
+                                {
+                                    List<string> CardNames = (List<string>)hashtable1["CardNames"];
+
+                                    if (CardNames != null)
+                                    {
+                                        if (CardNames.Count((cardName) => cardName.Contains(name)) >= 1)
+                                        {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Can activate [On Deletion] effect that can activate if the permanent conains specific trait
+    public static bool CanActivateSelfOnDeletionWithContainingTrait(Hashtable hashtable, string name, CardSource card)
+    {
+        return CanActivateOnDeletionWithContainingTrait(
+            hashtable: hashtable,
+            name: name,
+            cardCondition: cardSource => cardSource == card
+        );
+    }
+
+    public static bool CanActivateOnDeletionWithContainingTrait(
+        Hashtable hashtable,
+        string name,
+        Func<CardSource, bool> cardCondition)
+    {
+        List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+        if (hashtables != null)
+        {
+            foreach (Hashtable hashtable1 in hashtables)
+            {
+                if (hashtable1 != null)
+                {
+                    List<CardSource> CardSources = GetCardSourcesFromHashtable(hashtable1);
+                    if (CardSources != null)
+                    {
+                        if (CardSources.Some(cardSource => cardCondition == null || cardCondition(cardSource)))
+                        {
+                            if (hashtable1.ContainsKey("TopCard"))
+                            {
+                                if (hashtable1["TopCard"] is CardSource)
+                                {
+                                    CardSource topCard = (CardSource)hashtable1["TopCard"];
+                                    if (topCard != null)
+                                    {
+                                        if (topCard.ContainsTraits(name))
+                                        {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Can activate [On Deletion] effect that can activate if the permanent has specific colors
+    public static bool CanActivateSelfOnDeletionWithCardColors(Hashtable hashtable, Func<List<CardColor>, bool> cardColorCondition, CardSource card)
+    {
+        return CanActivateOnDeletionWithCardColors(
+            hashtable: hashtable,
+            cardColorCondition: cardColorCondition,
+            cardCondition: cardSource => cardSource == card
+        );
+    }
+
+    public static bool CanActivateOnDeletionWithCardColors(
+        Hashtable hashtable,
+        Func<List<CardColor>, bool> cardColorCondition,
+        Func<CardSource, bool> cardCondition)
+    {
+        if (hashtable != null)
+        {
+            List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+
+            if (hashtables != null)
+            {
+                foreach (Hashtable hashtable1 in hashtables)
+                {
+                    List<CardSource> CardSources = GetCardSourcesFromHashtable(hashtable1);
+
+                    if (CardSources != null)
+                    {
+                        if (CardSources.Some(cardSource => cardCondition == null || cardCondition(cardSource)))
+                        {
+                            if (hashtable1.ContainsKey("CardColors"))
+                            {
+                                if (hashtable1["CardColors"] is List<CardColor>)
+                                {
+                                    List<CardColor> CardColors = (List<CardColor>)hashtable1["CardColors"];
+
+                                    if (CardColors != null)
+                                    {
+                                        if (cardColorCondition == null || cardColorCondition(CardColors))
+                                        {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Can activate [On Deletion] effect that can activate if the permanent has Save text
+    public static bool CanActivateSelefOnDeletionWithSaveText(Hashtable hashtable, CardSource card)
+    {
+        return CanActivateOnDeletionWithSaveText(
+            hashtable: hashtable,
+            cardCondition: cardSource => cardSource == card
+        );
+    }
+
+    public static bool CanActivateOnDeletionWithSaveText(
+        Hashtable hashtable,
+        Func<CardSource, bool> cardCondition)
+    {
+        List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+
+        if (hashtables != null)
+        {
+            foreach (Hashtable hashtable1 in hashtables)
+            {
+                List<CardSource> CardSources = GetCardSourcesFromHashtable(hashtable1);
+
+                if (CardSources != null)
+                {
+                    if (CardSources.Some(cardSource => cardCondition == null || cardCondition(cardSource)))
+                    {
+                        if (hashtable1.ContainsKey("HasSaveText"))
+                        {
+                            if (hashtable1["HasSaveText"] is bool)
+                            {
+                                bool HasSaveText = (bool)hashtable1["HasSaveText"];
+
+                                if (HasSaveText)
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnDeletion.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 038b45518bf04504ca6a0347e47badfe
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnEndAttack.cs

@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger [On End Attack] effect
+    public static bool CanTriggerOnEndAttack(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerOnAttack(hashtable, card);
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnEndAttack.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 70e1020507afd25489e12306af34d9ed
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 31 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnFaceUpSecurityIncrease.cs

@@ -0,0 +1,31 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+
+    #region Can trigger "When face-up security carsd increases" effect
+    public static bool CanTriggerOnFaceUpSecurityIncreases(Hashtable hashtable, Player player = null, Func<CardSource, bool> cardCondition = null)
+    {
+        Player _player = GetPlayerFromHashtable(hashtable);
+
+        if (player == null || player.Equals(_player))
+        {
+            List<CardSource> FaceUpCards = GetCardSourcesFromHashtable(hashtable);
+
+            if (FaceUpCards != null)
+            {
+                if (FaceUpCards.Count(cardSource => cardCondition == null || cardCondition(cardSource)) >= 1)
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnFaceUpSecurityIncrease.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9e6ffc83eb80bd34ebdbb30c71c39dec
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 35 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnMove.cs

@@ -0,0 +1,35 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "when permanent moves" effect
+    public static bool CanTriggerOnMove(Hashtable hashtable, Func<Permanent, bool> permanentCondition)
+    {
+        Permanent permanent = GetMovedPermanentFromHashtable(hashtable);
+
+        if (permanent != null)
+        {
+            if (IsPermanentExistsOnBattleArea(permanent))
+            {
+                if (permanentCondition == null || permanentCondition(permanent))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Get moved permanent
+    public static Permanent GetMovedPermanentFromHashtable(Hashtable hashtable)
+    {
+        return GetPermanentFromHashtable(hashtable);
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnMove.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 11364abf24f7f3847b565e571751d37d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 39 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnReturnLibraryBottomDigivolutionCards.cs

@@ -0,0 +1,39 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When card is returned to library bottom from this permanent due to effect" effect
+    public static bool CanTriggerOnReturnToLibraryBottomDigivolutionCard(Hashtable hashtable, Func<CardSource, bool> cardCondition, CardSource card)
+    {
+        if (IsExistOnBattleArea(card))
+        {
+            if (hashtable != null)
+            {
+                Permanent Permanent = GetPermanentFromHashtable(hashtable);
+
+                if (Permanent != null)
+                {
+                    if (Permanent == card.PermanentOfThisCard())
+                    {
+                        List<CardSource> DeckBottomCards = GetDeckBottomCardsFromHashtable(hashtable);
+
+                        if (DeckBottomCards != null)
+                        {
+                            if (DeckBottomCards.Count((cardSource) => Permanent.DigivolutionCards.Contains(cardSource) && (cardCondition == null || cardCondition(cardSource))) >= 1)
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnReturnLibraryBottomDigivolutionCards.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: eb4a30f0216898143bd5096f2d088399
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 41 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnSuspend.cs

@@ -0,0 +1,41 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "when this permanent suspends" effect
+    public static bool CanTriggerWhenSelfPermanentSuspends(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerWhenPermanentSuspends(hashtable, (permanent) => permanent.cardSources.Contains(card));
+    }
+    #endregion
+
+    #region Can trigger "when permanent suspends" effect
+    public static bool CanTriggerWhenPermanentSuspends(Hashtable hashtable, Func<Permanent, bool> permanentCondition)
+    {
+        List<Permanent> permanents = GetPermanentsFromHashtable(hashtable);
+
+        if (permanents != null)
+        {
+            foreach (Permanent Permanent in permanents)
+            {
+                if (IsPermanentExistsOnBattleArea(Permanent))
+                {
+                    if (permanentCondition != null)
+                    {
+                        if (permanentCondition(Permanent))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnSuspend.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9b61e8488d6a75348b086bac3e0eb663
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 41 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashBySelfDigiBurst.cs

@@ -0,0 +1,41 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When this digivolution card is trashed due to activating this Digimon's <Digi-Burst>" effect
+    public static bool CanTriggerOnTrashBySelfDigiBurst(Hashtable hashtable, CardSource card)
+    {
+        bool CardEffectCondition(ICardEffect cardEffect)
+        {
+            if (cardEffect != null)
+            {
+                if (!string.IsNullOrEmpty(cardEffect.EffectDiscription))
+                {
+                    if (cardEffect.EffectDiscription.Contains("Digi-Burst"))
+                    {
+                        if (cardEffect.EffectSourceCard != null)
+                        {
+                            if (IsExistOnBattleArea(cardEffect.EffectSourceCard))
+                            {
+                                if (cardEffect.EffectSourceCard.PermanentOfThisCard().cardSources.Contains(card))
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        return CanTriggerOnTrashSelfDigivolutionCard(hashtable, CardEffectCondition, card);
+
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashBySelfDigiBurst.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e5364907ae6b99942a6242378e06229f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 69 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashDigivolutionCard.cs

@@ -0,0 +1,69 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When this digivolution card is trashed" effect
+    public static bool CanTriggerOnTrashSelfDigivolutionCard(Hashtable hashtable, Func<ICardEffect, bool> cardEffectCondition, CardSource card)
+    {
+        bool PermanentCondition(Permanent permanent)
+        {
+            if (IsPermanentExistsOnBattleArea(permanent))
+            {
+                if (permanent.DigivolutionCards.Contains(card))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        bool CardCondition(CardSource cardSource)
+        {
+            return cardSource == card;
+        }
+
+        return CanTriggerOnTrashDigivolutionCard(hashtable, PermanentCondition, cardEffectCondition, CardCondition);
+    }
+    #endregion
+
+    #region Can trigger "When this digivolution card is trashed due to effect" effect
+    public static bool CanTriggerOnTrashDigivolutionCard(Hashtable hashtable, Func<Permanent, bool> permanentCondition, Func<ICardEffect, bool> cardEffectCondition, Func<CardSource, bool> cardCondition)
+    {
+        Permanent permanent = GetPermanentFromHashtable(hashtable);
+
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanentCondition == null || permanentCondition(permanent))
+                {
+                    ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+                    if (CardEffect != null)
+                    {
+                        if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+                        {
+                            List<CardSource> DiscardedCards = GetDiscardedCardsFromHashtable(hashtable);
+
+                            if (DiscardedCards != null)
+                            {
+                                if (DiscardedCards.Count(cardSource => cardCondition == null || cardCondition(cardSource)) >= 1)
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashDigivolutionCard.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 099bf6b7bca7d4c4b9be797ae1106702
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 40 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashHand.cs

@@ -0,0 +1,40 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When this hand card is trashed due to effect" effect
+    public static bool CanTriggerOnTrashSelfHand(Hashtable hashtable, Func<ICardEffect, bool> cardEffectCondition, CardSource card)
+    {
+        return CanTriggerOnTrashHand(hashtable, cardEffectCondition, cardSource => cardSource == card);
+    }
+    #endregion
+
+    #region Can trigger "When hand card is trashed due to effect" effect
+    public static bool CanTriggerOnTrashHand(Hashtable hashtable, Func<ICardEffect, bool> cardEffectCondition, Func<CardSource, bool> cardCondition)
+    {
+        ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+        if (CardEffect != null)
+        {
+            if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+            {
+                List<CardSource> DiscardedCards = GetDiscardedCardsFromHashtable(hashtable);
+
+                if (DiscardedCards != null)
+                {
+                    if (DiscardedCards.Count(cardSource => cardCondition == null || cardCondition(cardSource)) >= 1)
+                    {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashHand.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: befc23dd8b98ea943b95fb31661bb127
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 69 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkCard.cs

@@ -0,0 +1,69 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When this Link card is trashed" effect
+    public static bool CanTriggerOnTrashSelfLinkCard(Hashtable hashtable, Func<ICardEffect, bool> cardEffectCondition, CardSource card)
+    {
+        bool PermanentCondition(Permanent permanent)
+        {
+            if (IsPermanentExistsOnBattleArea(permanent))
+            {
+                if (permanent.LinkedCards.Contains(card))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        bool CardCondition(CardSource cardSource)
+        {
+            return cardSource == card;
+        }
+
+        return CanTriggerOnTrashLinkCard(hashtable, PermanentCondition, cardEffectCondition, CardCondition);
+    }
+    #endregion
+
+    #region Can trigger "When this link card is trashed due to effect" effect
+    public static bool CanTriggerOnTrashLinkCard(Hashtable hashtable, Func<Permanent, bool> permanentCondition, Func<ICardEffect, bool> cardEffectCondition, Func<CardSource, bool> cardCondition)
+    {
+        Permanent permanent = GetPermanentFromHashtable(hashtable);
+
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanentCondition == null || permanentCondition(permanent))
+                {
+                    ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+                    if (CardEffect != null)
+                    {
+                        if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+                        {
+                            List<CardSource> DiscardedCards = GetDiscardedCardsFromHashtable(hashtable);
+
+                            if (DiscardedCards != null)
+                            {
+                                if (DiscardedCards.Count(cardSource => cardCondition == null || cardCondition(cardSource)) >= 1)
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkCard.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: de049f04f69d80e4a80d15d7a706aa01
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 69 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkedCard.cs

@@ -0,0 +1,69 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "When this linked card is trashed" effect
+    public static bool CanTriggerOnTrashSelfLinkedCard(Hashtable hashtable, Func<ICardEffect, bool> cardEffectCondition, CardSource card)
+    {
+        bool PermanentCondition(Permanent permanent)
+        {
+            if (IsPermanentExistsOnBattleArea(permanent))
+            {
+                if (permanent.LinkedCards.Contains(card))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        bool CardCondition(CardSource cardSource)
+        {
+            return cardSource == card;
+        }
+
+        return CanTriggerOnTrashLinkedCard(hashtable, PermanentCondition, cardEffectCondition, CardCondition);
+    }
+    #endregion
+
+    #region Can trigger "When this linked card is trashed due to effect" effect
+    public static bool CanTriggerOnTrashLinkedCard(Hashtable hashtable, Func<Permanent, bool> permanentCondition, Func<ICardEffect, bool> cardEffectCondition, Func<CardSource, bool> cardCondition)
+    {
+        Permanent permanent = GetPermanentFromHashtable(hashtable);
+
+        if (permanent != null)
+        {
+            if (permanent.TopCard != null)
+            {
+                if (permanentCondition == null || permanentCondition(permanent))
+                {
+                    ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+                    if (CardEffect != null)
+                    {
+                        if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+                        {
+                            List<CardSource> DiscardedCards = GetDiscardedCardsFromHashtable(hashtable);
+
+                            if (DiscardedCards != null)
+                            {
+                                if (DiscardedCards.Count(cardSource => cardCondition == null || cardCondition(cardSource)) >= 1)
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnTrashLinkedCard.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5b70178e56d77fc48a1e6e44b927a5d0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 22 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnUnsuspend.cs

@@ -0,0 +1,22 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "when this permanent unsuspends" effect
+    public static bool CanTriggerWhenSelfPermanentUnsuspends(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerWhenPermanentUnsuspends(hashtable, (permanent) => permanent.cardSources.Contains(card));
+    }
+    #endregion
+
+    #region Can trigger "when permanent unsuspends" effect
+    public static bool CanTriggerWhenPermanentUnsuspends(Hashtable hashtable, Func<Permanent, bool> permanentCondition)
+    {
+        return CanTriggerWhenPermanentSuspends(hashtable, permanentCondition);
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OnUnsuspend.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 29b4ce02c7a58234bb26c98bc3b2f490
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 40 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OptionEffect.cs

@@ -0,0 +1,40 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger option [Main] effect
+    public static bool CanTriggerOptionMainEffect(Hashtable hashtable, CardSource card)
+    {
+        CardSource Card = GetCardFromHashtable(hashtable);
+
+        if (Card != null)
+        {
+            if (Card == card)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Can declare option [Delay] effect
+    public static bool CanDeclareOptionDelayEffect(CardSource card)
+    {
+        if (IsExistOnBattleArea(card))
+        {
+            if (card.PermanentOfThisCard().EnterFieldTurnCount != GManager.instance.turnStateMachine.TurnCount)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/OptionEffect.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: a66c86013eb611c4fb9cc07b3317497f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 120ce54a3f625aa418c48f2590819f49
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 26 - 0
Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/OnPlay.cs

@@ -0,0 +1,26 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+
+    #region Can trigger [On Play] effect
+    public static bool CanTriggerOnPlay(Hashtable hashtable, CardSource card, Func<SelectCardEffect.Root, bool> rootCondition = null)
+    {
+        return CanTriggerOnEnterField(hashtable, card, false, rootCondition);
+    }
+    #endregion
+
+    #region Can trigger "When permanent is played" effect
+    public static bool CanTriggerOnPermanentPlay(
+        Hashtable hashtable,
+        Func<Permanent, bool> permanentCondition,
+        Func<SelectCardEffect.Root, bool> rootCondition = null)
+    {
+        return CanTriggerOnPermanentEnterField(hashtable, permanentCondition, false, rootCondition);
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/OnPlay.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 75805250c8e7b4e4688ebbbfa35e2c83
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 58 - 0
Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/PermanentEnterField.cs

@@ -0,0 +1,58 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger one of [On Play] effect or [When Digivolving] effect
+    static bool CanTriggerOnEnterField(Hashtable hashtable, CardSource card, bool isEvolution, Func<SelectCardEffect.Root, bool> rootCondition = null)
+    {
+        return CanTriggerOnPermanentEnterField(hashtable, (permanent) => permanent.cardSources.Contains(card), isEvolution, rootCondition);
+    }
+    #endregion
+
+    #region Can trigger "When permanent is played or digivolves" effect
+    static bool CanTriggerOnPermanentEnterField(
+        Hashtable hashtable,
+        Func<Permanent, bool> permanentCondition,
+        bool isEvolution,
+        Func<SelectCardEffect.Root, bool> rootCondition = null)
+    {
+        bool IsEvolution = CardEffectCommons.IsEvolution(hashtable);
+
+        if (IsEvolution == isEvolution)
+        {
+            List<Hashtable> hashtables = GetHashtablesFromHashtable(hashtable);
+
+            if (hashtables != null)
+            {
+                foreach (Hashtable hashtable1 in hashtables)
+                {
+                    Permanent permanent = GetPermanentFromHashtable(hashtable1);
+
+                    if (permanent != null)
+                    {
+                        if (permanentCondition != null)
+                        {
+                            if (permanentCondition(permanent))
+                            {
+                                SelectCardEffect.Root root = GetRootFromHashtable(hashtable1);
+
+                                if (rootCondition == null || rootCondition(root) || root == SelectCardEffect.Root.None)
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/PermanentEnterField.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 28aa3dfce82c93e43b21cdfd8292a928
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 27 - 0
Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/WhenDigivolving.cs

@@ -0,0 +1,27 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger [When Digivolving] effect
+    public static bool CanTriggerWhenDigivolving(Hashtable hashtable, CardSource card, Func<SelectCardEffect.Root, bool> rootCondition = null)
+    {
+        return CanTriggerOnEnterField(hashtable, card, true, rootCondition);
+    }
+    #endregion
+
+    #region Can trigger "When permanent digivolves" effect
+    public static bool CanTriggerWhenPermanentDigivolving(
+        Hashtable hashtable,
+        Func<Permanent, bool> permanentCondition,
+        Func<SelectCardEffect.Root, bool> rootCondition = null)
+    {
+        return CanTriggerOnPermanentEnterField(hashtable, permanentCondition, true, rootCondition);
+    }
+    #endregion
+
+
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/PermanentEnterField/WhenDigivolving.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9c1ff1901a1149b40b942ddbb2a0fc25
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
Assets/Script/CardEffectCommons/CanUseEffects/SecurityEffect.cs

@@ -0,0 +1,15 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger [Security] effect
+    public static bool CanTriggerSecurityEffect(Hashtable hashtable, CardSource card)
+    {
+        return CanTriggerOptionMainEffect(hashtable, card);
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/SecurityEffect.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 313406f2b66049b4fbd5f112d6fa4263
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 30 - 0
Assets/Script/CardEffectCommons/CanUseEffects/WhenAddHand.cs

@@ -0,0 +1,30 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "when hand cards added" effect
+    public static bool CanTriggerWhenAddHand(Hashtable hashtable, Func<Player, bool> playerCondition, Func<ICardEffect, bool> cardEffectCondition)
+    {
+        List<Player> Players = GetPlayersFromHashtable(hashtable);
+
+        if (Players != null)
+        {
+            if (Players.Count(player => playerCondition == null || playerCondition(player)) >= 1)
+            {
+                ICardEffect CardEffect = GetCardEffectFromHashtable(hashtable);
+
+                if (cardEffectCondition == null || cardEffectCondition(CardEffect))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/WhenAddHand.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c1ebe62d0068afc459accf52ecbf26e1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 128 - 0
Assets/Script/CardEffectCommons/CanUseEffects/WhenDeleteOpponentDigimon.cs

@@ -0,0 +1,128 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "when a Digimon deletes opponent's Digimon" effect
+    public static bool CanTriggerWhenDeleteOpponentDigimon(
+        Hashtable hashtable,
+        Func<Permanent, bool> winnerCondition,
+        Func<Permanent, bool> loserCondition)
+    {
+        if (hashtable != null)
+        {
+            ICardEffect effect = GetCardEffectFromHashtable(hashtable);
+            IBattle battle = GetBattleFromHashtable(hashtable);
+
+            if (effect != null)
+            {
+                List<Permanent> permanents = new List<Permanent>();
+                List<Hashtable> effectHashtables = GetHashtablesFromHashtable(hashtable);
+
+                foreach (Hashtable effTable in effectHashtables)
+                {
+                    Permanent permanent = GetPermanentFromHashtable(effTable);
+                    if (loserCondition == null || loserCondition(permanent))
+                        permanents.Add(permanent);
+                }
+
+                permanents = permanents.Filter(loserCondition);
+
+                if (winnerCondition == null || winnerCondition(effect.EffectSourcePermanent))
+                {
+                    if(loserCondition == null || permanents.Count > 0)
+                    {
+                        return true;
+                    }
+                }
+                
+            }
+
+            if (battle != null)
+            {
+                Hashtable battleHashtable = battle.hashtable;
+
+                if (battleHashtable != null)
+                {
+                    List<Permanent> WinnerPermanents = null;
+
+                    if (battleHashtable.ContainsKey("WinnerPermanents"))
+                    {
+                        if (battleHashtable["WinnerPermanents"] is List<Permanent>)
+                        {
+                            WinnerPermanents = (List<Permanent>)battleHashtable["WinnerPermanents"];
+                        }
+                    }
+
+                    bool WinnerCondition()
+                    {
+                        if (WinnerPermanents == null || WinnerPermanents.Count == 0)
+                        {
+                            if (winnerCondition == null)
+                            {
+                                return true;
+                            }
+                        }
+
+                        else
+                        {
+                            if (WinnerPermanents.Some((permanent) => permanent != null && permanent.TopCard != null && (winnerCondition == null || winnerCondition(permanent))))
+                            {
+                                return true;
+                            }
+                        }
+
+                        return false;
+                    }
+
+                    if (WinnerCondition())
+                    {
+                        if (battleHashtable.ContainsKey("LoserPermanents"))
+                        {
+                            List<Permanent> LoserPermanents = (List<Permanent>)battleHashtable["LoserPermanents"];
+
+                            if (LoserPermanents != null)
+                            {
+                                if (winnerCondition == null || LoserPermanents.Count((permanent) => permanent != null && permanent.TopCard != null && winnerCondition(permanent)) == 0)
+                                {
+                                    if (loserCondition == null || LoserPermanents.Some((permanent) => permanent != null && permanent.TopCard != null && loserCondition(permanent)))
+                                    {
+                                        if (battleHashtable.ContainsKey("LoserPermanents_real"))
+                                        {
+                                            List<Permanent> LoserPermanents_real = (List<Permanent>)battleHashtable["LoserPermanents_real"];
+
+                                            if (LoserPermanents_real != null)
+                                            {
+                                                if (LoserPermanents_real.Some((permanent) => permanent.IsDestroyedByBattle))
+                                                {
+                                                    if (battleHashtable.ContainsKey("WinnerPermanents_real"))
+                                                    {
+                                                        List<Permanent> WinnerPermanents_real = (List<Permanent>)battleHashtable["WinnerPermanents_real"];
+
+                                                        if (WinnerPermanents_real != null)
+                                                        {
+                                                            if (WinnerPermanents_real.Some((permanent) => permanent != null && permanent.TopCard != null))
+                                                            {
+                                                                return true;
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

+ 11 - 0
Assets/Script/CardEffectCommons/CanUseEffects/WhenDeleteOpponentDigimon.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fbc669d515645ee4988a23e6941cbdee
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 107 - 0
Assets/Script/CardEffectCommons/CanUseEffects/WhenDeleteOpponentDigimonByBattle.cs

@@ -0,0 +1,107 @@
+using System.Collections;
+using System.Collections.Generic;
+using System;
+using System.Linq;
+using UnityEngine;
+
+public partial class CardEffectCommons
+{
+    #region Can trigger "when a Digimon deletes opponent's Digimon by battle" effect
+    public static bool CanTriggerWhenDeleteOpponentDigimonByBattle(
+        Hashtable hashtable,
+        Func<Permanent, bool> winnerCondition,
+        Func<Permanent, bool> loserCondition,
+        bool isOnlyWinnerSurvive,
+        Func<Permanent, bool> winnerRealCondition = null,
+        Func<Permanent, bool> loserRealCondition = null)
+    {
+        if (hashtable != null)
+        {
+            IBattle battle = GetBattleFromHashtable(hashtable);
+
+            if (battle != null)
+            {
+                Hashtable battleHashtable = battle.hashtable;
+
+                if (battleHashtable != null)
+                {
+                    List<Permanent> WinnerPermanents = null;
+
+                    if (battleHashtable.ContainsKey("WinnerPermanents"))
+                    {
+                        if (battleHashtable["WinnerPermanents"] is List<Permanent>)
+                        {
+                            WinnerPermanents = (List<Permanent>)battleHashtable["WinnerPermanents"];
+                        }
+                    }
+
+                    bool WinnerCondition()
+                    {
+                        if (WinnerPermanents == null || WinnerPermanents.Count == 0)
+                        {
+                            if (winnerCondition == null)
+                            {
+                                return true;
+                            }
+                        }
+
+                        else
+                        {
+                            if (WinnerPermanents.Some((permanent) => permanent != null && permanent.TopCard != null && (winnerCondition == null || winnerCondition(permanent))))
+                            {
+                                return true;
+                            }
+                        }
+
+                        return false;
+                    }
+
+                    if (WinnerCondition())
+                    {
+                        if (battleHashtable.ContainsKey("LoserPermanents"))
+                        {
+                            List<Permanent> LoserPermanents = (List<Permanent>)battleHashtable["LoserPermanents"];
+
+                            if (LoserPermanents != null)
+                            {
+                                if (!isOnlyWinnerSurvive || winnerCondition == null || LoserPermanents.Count((permanent) => permanent != null && permanent.TopCard != null && winnerCondition(permanent)) == 0)
+                                {
+                                    if (loserCondition == null || LoserPermanents.Some((permanent) => permanent != null && permanent.TopCard != null && loserCondition(permanent)))
+                                    {
+                                        if (battleHashtable.ContainsKey("LoserPermanents_real"))
+                                        {
+                                            List<Permanent> LoserPermanents_real = (List<Permanent>)battleHashtable["LoserPermanents_real"];
+
+                                            if (LoserPermanents_real != null)
+                                            {
+                                                if (loserRealCondition == null || LoserPermanents_real.Some((permanent) => permanent.IsDestroyedByBattle &&
+                                                (loserRealCondition(permanent))))
+                                                {
+                                                    if (battleHashtable.ContainsKey("WinnerPermanents_real"))
+                                                    {
+                                                        List<Permanent> WinnerPermanents_real = (List<Permanent>)battleHashtable["WinnerPermanents_real"];
+
+                                                        if (WinnerPermanents_real != null)
+                                                        {
+                                                            if (winnerRealCondition == null || WinnerPermanents_real.Some((permanent) => permanent != null && permanent.TopCard != null && (winnerRealCondition(permanent))))
+                                                            {
+                                                                return true;
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+}

Some files were not shown because too many files changed in this diff