Преглед изворни кода

Merge pull request #102 from DCGO2/bt21purple

Adding all of BT21 purple
Michael8818 пре 1 година
родитељ
комит
6be632d0dc
42 измењених фајлова са 6693 додато и 0 уклоњено
  1. 113 0
      Assets/CardEffect/BT21/Purple/BT21_063.cs
  2. 11 0
      Assets/CardEffect/BT21/Purple/BT21_063.cs.meta
  3. 143 0
      Assets/CardEffect/BT21/Purple/BT21_064.cs
  4. 11 0
      Assets/CardEffect/BT21/Purple/BT21_064.cs.meta
  5. 203 0
      Assets/CardEffect/BT21/Purple/BT21_065.cs
  6. 11 0
      Assets/CardEffect/BT21/Purple/BT21_065.cs.meta
  7. 419 0
      Assets/CardEffect/BT21/Purple/BT21_066.cs
  8. 11 0
      Assets/CardEffect/BT21/Purple/BT21_066.cs.meta
  9. 198 0
      Assets/CardEffect/BT21/Purple/BT21_067.cs
  10. 11 0
      Assets/CardEffect/BT21/Purple/BT21_067.cs.meta
  11. 230 0
      Assets/CardEffect/BT21/Purple/BT21_068.cs
  12. 11 0
      Assets/CardEffect/BT21/Purple/BT21_068.cs.meta
  13. 380 0
      Assets/CardEffect/BT21/Purple/BT21_069.cs
  14. 11 0
      Assets/CardEffect/BT21/Purple/BT21_069.cs.meta
  15. 195 0
      Assets/CardEffect/BT21/Purple/BT21_070.cs
  16. 11 0
      Assets/CardEffect/BT21/Purple/BT21_070.cs.meta
  17. 427 0
      Assets/CardEffect/BT21/Purple/BT21_071.cs
  18. 11 0
      Assets/CardEffect/BT21/Purple/BT21_071.cs.meta
  19. 128 0
      Assets/CardEffect/BT21/Purple/BT21_072.cs
  20. 11 0
      Assets/CardEffect/BT21/Purple/BT21_072.cs.meta
  21. 578 0
      Assets/CardEffect/BT21/Purple/BT21_073.cs
  22. 11 0
      Assets/CardEffect/BT21/Purple/BT21_073.cs.meta
  23. 698 0
      Assets/CardEffect/BT21/Purple/BT21_074.cs
  24. 11 0
      Assets/CardEffect/BT21/Purple/BT21_074.cs.meta
  25. 330 0
      Assets/CardEffect/BT21/Purple/BT21_075.cs
  26. 11 0
      Assets/CardEffect/BT21/Purple/BT21_075.cs.meta
  27. 189 0
      Assets/CardEffect/BT21/Purple/BT21_076.cs
  28. 11 0
      Assets/CardEffect/BT21/Purple/BT21_076.cs.meta
  29. 517 0
      Assets/CardEffect/BT21/Purple/BT21_077.cs
  30. 11 0
      Assets/CardEffect/BT21/Purple/BT21_077.cs.meta
  31. 300 0
      Assets/CardEffect/BT21/Purple/BT21_078.cs
  32. 11 0
      Assets/CardEffect/BT21/Purple/BT21_078.cs.meta
  33. 180 0
      Assets/CardEffect/BT21/Purple/BT21_079.cs
  34. 11 0
      Assets/CardEffect/BT21/Purple/BT21_079.cs.meta
  35. 441 0
      Assets/CardEffect/BT21/Purple/BT21_088.cs
  36. 11 0
      Assets/CardEffect/BT21/Purple/BT21_088.cs.meta
  37. 169 0
      Assets/CardEffect/BT21/Purple/BT21_089.cs
  38. 11 0
      Assets/CardEffect/BT21/Purple/BT21_089.cs.meta
  39. 381 0
      Assets/CardEffect/BT21/Purple/BT21_099.cs
  40. 11 0
      Assets/CardEffect/BT21/Purple/BT21_099.cs.meta
  41. 243 0
      Assets/CardEffect/BT21/Purple/BT21_100.cs
  42. 11 0
      Assets/CardEffect/BT21/Purple/BT21_100.cs.meta

+ 113 - 0
Assets/CardEffect/BT21/Purple/BT21_063.cs

@@ -0,0 +1,113 @@
+using System.Collections;
+using System.Collections.Generic;
+
+//bt21_063 Gumdramon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_063 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Digivolution condition
+            if(timing == EffectTiming.None)
+            {
+                bool Condition(Permanent permanent)
+                {
+                    return (permanent.TopCard.HasSaveText || permanent.TopCard.EqualsTraits("Hero")) && permanent.Level == 2;
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(Condition, 0, false, card, null));
+            }
+            #endregion
+
+            #region On Play
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Trash 1 [Hero] / Save, <Draw 2>", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] By trashing 1 card with <Save> in its text or the [Hero] trait from your hand, <Draw 2>.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                bool HasNameOrTrait(CardSource cardSource)
+                {
+                    return cardSource.EqualsTraits("Hero") || cardSource.HasSaveText;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) &&
+                           CardEffectCommons.HasMatchConditionOwnersHand(card, HasNameOrTrait);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+                    bool trashed = false;
+                    selectHandEffect.SetUp(
+                        canTargetCondition: HasNameOrTrait,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectHandEffect.Mode.Discard,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    selectHandEffect.SetUpCustomMessage("Select 1 card with the [Hero] trait or <Save> in text to discard.",
+                        "The opponent is selecting 1 card with the [Hero] trait or <Save> in text to discard.");
+
+                    yield return ContinuousController.instance.StartCoroutine(selectHandEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        trashed = true;
+                        yield return null;
+                    }
+
+                    if (trashed)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(
+                            new DrawClass(card.Owner, 2, activateClass).Draw());
+                    }
+                }
+            }
+            #endregion
+
+            #region On-deletion save
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                cardEffects.Add(CardEffectFactory.SaveEffect(card: card));
+            }
+            #endregion
+
+            #region inherit your turn +2k
+            if (timing == EffectTiming.None)
+            {
+                bool condition()
+                {
+                    return CardEffectCommons.IsExistOnBattleArea(card) && CardEffectCommons.IsOwnerTurn(card);
+                }
+
+                cardEffects.Add(CardEffectFactory.ChangeSelfDPStaticEffect(changeValue: 2000, isInheritedEffect: true, card: card, condition: condition));
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_063.cs.meta

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

+ 143 - 0
Assets/CardEffect/BT21/Purple/BT21_064.cs

@@ -0,0 +1,143 @@
+using System.Collections;
+using System.Collections.Generic;
+
+//bt21-064 guilmon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_064 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+
+            #region Digivolution Condition
+            if (timing == EffectTiming.None)
+            {
+                bool PermanentCondition(Permanent targetPermanent)
+                {
+                    return targetPermanent.TopCard.EqualsCardName("Guilmon") || (targetPermanent.Level == 2 && targetPermanent.TopCard.EqualsTraits("Hero"));
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(
+                    permanentCondition: PermanentCondition,
+                    digivolutionCost: 0,
+                    ignoreDigivolutionRequirement: false,
+                    card: card, condition: null)
+                );
+            }
+            #endregion
+
+            #region on play
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Trash 1 [Hero] / gallant line, <Draw 2>", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] By trashing 1 card with [Guilmon], [Growlmon], [Gallantmon] or [Megidramon] in its name or the [Hero] trait from your hand, <Draw 2>.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                bool HasNameOrTrait(CardSource cardSource)
+                {
+                    return cardSource.EqualsTraits("Hero") 
+                        || cardSource.ContainsCardName("Growlmon")
+                        || cardSource.ContainsCardName("Gallantmon")
+                        || cardSource.ContainsCardName("Megidramon");
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) &&
+                           CardEffectCommons.HasMatchConditionOwnersHand(card, HasNameOrTrait);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+                    bool trashed = false;
+                    selectHandEffect.SetUp(
+                        canTargetCondition: HasNameOrTrait,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectHandEffect.Mode.Discard,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    selectHandEffect.SetUpCustomMessage("Select 1 card with the [Hero] trait or guilmon/growlmon/gallantmon/megidramon in name to discard.",
+                        "The opponent is selecting 1 card with the [Hero] trait or guilmon/growlmon/gallantmon/megidramon in name to discard.");
+
+                    yield return ContinuousController.instance.StartCoroutine(selectHandEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        trashed = true;
+                        yield return null;
+                    }
+
+                    if (trashed)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(
+                            new DrawClass(card.Owner, 2, activateClass).Draw());
+                    }
+                }
+            }
+            #endregion
+
+            #region On Deletion inherit
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Memory +1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                activateClass.SetIsInheritedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Deletion] Gain 1 memory.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletionInherited(hashtable, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.CanActivateOnDeletion(card))
+                    {
+                        if (card.Owner.CanAddMemory(activateClass))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(card.Owner.AddMemory(1, activateClass));
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_064.cs.meta

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

+ 203 - 0
Assets/CardEffect/BT21/Purple/BT21_065.cs

@@ -0,0 +1,203 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_065 Ghostmon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_065 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Your Turn
+            if (timing == EffectTiming.BeforePayCost)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Reduce the digivolution cost by 1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDiscription());
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[Your Turn] When this Digimon would digivolve into a Digimon card with the [Ghost] trait, reduce the digivolution cost by 1.";
+                }
+
+                bool PermanentCondition(Permanent permanent)
+                {
+
+                    if (CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card))
+                    {
+                        if (permanent == card.PermanentOfThisCard())
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool HasProperTrait(CardSource source)
+                {
+                    return source.IsDigimon && source.EqualsTraits("Ghost");
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleAreaDigimon(card))
+                    {
+                        if (CardEffectCommons.IsOwnerTurn(card))
+                        {
+                            if (CardEffectCommons.CanTriggerWhenPermanentWouldDigivolve(hashtable, PermanentCondition, HasProperTrait))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    if (isExistOnField(card))
+                    {
+                        Hashtable hashtable = new Hashtable();
+                        hashtable.Add("CardEffect", activateClass);
+
+                        ContinuousController.instance.PlaySE(GManager.instance.GetComponent<Effects>().BuffSE);
+
+                        ChangeCostClass changeCostClass = new ChangeCostClass();
+                        changeCostClass.SetUpICardEffect("Digivolution Cost -1", CanUseCondition1, card);
+                        changeCostClass.SetUpChangeCostClass(changeCostFunc: ChangeCost, cardSourceCondition: CardSourceCondition, rootCondition: RootCondition, isUpDown: isUpDown, isCheckAvailability: () => false, isChangePayingCost: () => true);
+                        card.Owner.UntilCalculateFixedCostEffect.Add((_timing) => changeCostClass);
+
+                        yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.ShowReducedCost(_hashtable));
+
+                        bool CanUseCondition1(Hashtable hashtable)
+                        {
+                            return true;
+                        }
+
+                        int ChangeCost(CardSource cardSource, int Cost, SelectCardEffect.Root root, List<Permanent> targetPermanents)
+                        {
+                            if (CardSourceCondition(cardSource))
+                            {
+                                if (RootCondition(root))
+                                {
+                                    if (PermanentsCondition(targetPermanents))
+                                    {
+                                        Cost -= 1;
+                                    }
+                                }
+                            }
+
+                            return Cost;
+                        }
+
+                        bool PermanentsCondition(List<Permanent> targetPermanents)
+                        {
+                            if (targetPermanents != null)
+                            {
+                                if (targetPermanents.Count(PermanentCondition) >= 1)
+                                {
+                                    return true;
+                                }
+                            }
+
+                            return false;
+                        }
+
+                        bool PermanentCondition(Permanent targetPermanent)
+                        {
+                            if (targetPermanent.TopCard != null)
+                            {
+                                if (targetPermanent.TopCard.Owner == card.Owner)
+                                {
+                                    if (targetPermanent.TopCard.Owner.GetBattleAreaPermanents().Contains(targetPermanent))
+                                    {
+                                        return true;
+                                    }
+                                }
+                            }
+
+                            return false;
+                        }
+
+                        bool CardSourceCondition(CardSource cardSource)
+                        {
+                            if (cardSource != null)
+                            {
+                                if (cardSource.Owner == card.Owner)
+                                {
+                                    return cardSource.EqualsTraits("Ghost");
+                                }
+                            }
+
+                            return false;
+                        }
+
+                        bool RootCondition(SelectCardEffect.Root root)
+                        {
+                            return true;
+                        }
+
+                        bool isUpDown()
+                        {
+                            return true;
+                        }
+
+                    }
+                }
+            }
+            #endregion
+
+            #region On Deletion inherit
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Memory +1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                activateClass.SetIsInheritedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Deletion] Gain 1 memory.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletionInherited(hashtable, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.CanActivateOnDeletion(card))
+                    {
+                        if (card.Owner.CanAddMemory(activateClass))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(card.Owner.AddMemory(1, activateClass));
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_065.cs.meta

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

+ 419 - 0
Assets/CardEffect/BT21/Purple/BT21_066.cs

@@ -0,0 +1,419 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21_066 Arresterdramon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_066 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Digivolution condition
+            if (timing == EffectTiming.None)
+            {
+                bool Condition(Permanent permanent)
+                {
+                    return (permanent.TopCard.EqualsTraits("Hero") || permanent.TopCard.HasSaveText) && permanent.Level == 3;
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(Condition, 2, false, card, null));
+            }
+            #endregion
+
+            #region On Play
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Play Hero or Hunter tamer", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] You may play 1 Tamer card with the [Hunter] or [Hero] trait from your hand without paying the cost.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                bool IsTamerCardCondition(CardSource cardSource)
+                {
+                    return cardSource.IsTamer &&
+                           (cardSource.EqualsTraits("Hero") || cardSource.EqualsTraits("Hunter")) &&
+                           CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) &&
+                           CardEffectCommons.HasMatchConditionOwnersHand(card, IsTamerCardCondition);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                    selectHandEffect.SetUp(
+                        selectPlayer: card.Owner,
+                        canTargetCondition: IsTamerCardCondition,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        maxCount: 1,
+                        canNoSelect: true,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        mode: SelectHandEffect.Mode.Custom,
+                        cardEffect: activateClass);
+
+                    selectHandEffect.SetUpCustomMessage("Select 1 card to play.", "The opponent is selecting 1 card to play.");
+                    selectHandEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                    yield return StartCoroutine(selectHandEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    if (selectedCards.Count >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                            cardSources: selectedCards,
+                            activateClass: activateClass,
+                            payCost: false,
+                            isTapped: false,
+                            root: SelectCardEffect.Root.Hand,
+                            activateETB: true));
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Play Hero or Hunter tamer", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] You may play 1 Tamer card with the [Hunter] or [Hero] trait from your hand without paying the cost.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                bool IsTamerCardCondition(CardSource cardSource)
+                {
+                    return cardSource.IsTamer &&
+                           (cardSource.EqualsTraits("Hero") || cardSource.EqualsTraits("Hunter")) &&
+                           CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) &&
+                           CardEffectCommons.HasMatchConditionOwnersHand(card, IsTamerCardCondition);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                    selectHandEffect.SetUp(
+                        selectPlayer: card.Owner,
+                        canTargetCondition: IsTamerCardCondition,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        maxCount: 1,
+                        canNoSelect: true,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        mode: SelectHandEffect.Mode.Custom,
+                        cardEffect: activateClass);
+
+                    selectHandEffect.SetUpCustomMessage("Select 1 card to play.", "The opponent is selecting 1 card to play.");
+                    selectHandEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                    yield return StartCoroutine(selectHandEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    if (selectedCards.Count >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                            cardSources: selectedCards,
+                            activateClass: activateClass,
+                            payCost: false,
+                            isTapped: false,
+                            root: SelectCardEffect.Root.Hand,
+                            activateETB: true));
+                    }
+                }
+            }
+            #endregion
+
+            #region On delete save from hand or trash + save
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Save and place 1 card under your 1 Tamer from trash", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDiscription());
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[On Deletion] You may place 1 Digimon card with <Save> in its text or the [Hero] trait from your hand or trash under any of your Tamers. Then, <Save>.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnDeletion(hashtable, card);
+                }
+
+                bool IsOwnTamerCondition(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleArea(permanent, card)
+                           && permanent.IsTamer;
+                }
+
+                bool SelectableDigimonCondition(CardSource cardSource)
+                {
+                    return cardSource.IsDigimon && (cardSource.EqualsTraits("Hero") || cardSource.HasSaveText);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletion(card) &&
+                           CardEffectCommons.HasMatchConditionOwnersPermanent(card, IsOwnTamerCondition) &&
+                           (CardEffectCommons.HasMatchConditionOwnersHand(card, SelectableDigimonCondition) ||
+                            CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, SelectableDigimonCondition));
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectHand = CardEffectCommons.HasMatchConditionOwnersHand(card, SelectableDigimonCondition);
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, SelectableDigimonCondition);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From hand", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you place a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to place a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements,
+                                selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage,
+                                notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager
+                            .WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: SelectableDigimonCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: 1,
+                                canNoSelect: false,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place under a tamer.",
+                                "The opponent is selecting 1 card to play.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Placed card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+                        else
+                        {
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: SelectableDigimonCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => false,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to place under a tamer.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to place under a tamer.",
+                                "The opponent is selecting 1 card to place under a tamer.");
+
+                            yield return StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            Permanent selectedPermanent = null;
+
+                            SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                            selectPermanentEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: IsOwnTamerCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: 1,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                selectPermanentCoroutine: SelectPermanentCoroutine,
+                                afterSelectPermanentCoroutine: null,
+                                mode: SelectPermanentEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectPermanentEffect.SetUpCustomMessage("Select 1 Tamer to place the chosen card under.",
+                                "The opponent is selecting 1 Tamer to place the chosen card under.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                            IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                            {
+                                selectedPermanent = permanent;
+
+                                yield return null;
+                            }
+
+                            if (selectedPermanent != null)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(
+                                    selectedPermanent.AddDigivolutionCardsBottom(selectedCards, activateClass));
+                            }
+                        }
+                    }
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.SaveProcess(hashtable, activateClass, card, IsOwnTamerCondition));
+                }
+            }
+            #endregion
+
+            #region inherit your turn +2k
+            if (timing == EffectTiming.None)
+            {
+                bool condition()
+                {
+                    return CardEffectCommons.IsExistOnBattleArea(card) && CardEffectCommons.IsOwnerTurn(card);
+                }
+
+                cardEffects.Add(CardEffectFactory.ChangeSelfDPStaticEffect(changeValue: 2000, isInheritedEffect: true, card: card, condition: condition));
+            }
+            #endregion
+
+            #region Digixros
+            if (timing == EffectTiming.None)
+            {
+                AddDigiXrosConditionClass addDigiXrosConditionClass = new AddDigiXrosConditionClass();
+                addDigiXrosConditionClass.SetUpICardEffect($"DigiXros", CanUseCondition, card);
+                addDigiXrosConditionClass.SetUpAddDigiXrosConditionClass(getDigiXrosCondition: GetDigiXros);
+                addDigiXrosConditionClass.SetNotShowUI(true);
+                cardEffects.Add(addDigiXrosConditionClass);
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return true;
+                }
+
+                DigiXrosCondition GetDigiXros(CardSource cardSource)
+                {
+                    if (cardSource == card)
+                    {
+                        DigiXrosConditionElement element = new DigiXrosConditionElement(CanSelectCardCondition, "Digimon card with <Save> in text");
+
+                        bool CanSelectCardCondition(CardSource cardSource)
+                        {
+                            if (cardSource != null)
+                            {
+                                if (cardSource.Owner == card.Owner)
+                                {
+                                    if (cardSource.IsDigimon)
+                                    {
+                                        if (cardSource.HasSaveText)
+                                        {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+
+                            return false;
+                        }
+
+                        List<DigiXrosConditionElement> elements = new List<DigiXrosConditionElement>() { element };
+
+                        DigiXrosCondition digiXrosCondition = new DigiXrosCondition(elements, null, 2);
+
+                        return digiXrosCondition;
+                    }
+
+                    return null;
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_066.cs.meta

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

+ 198 - 0
Assets/CardEffect/BT21/Purple/BT21_067.cs

@@ -0,0 +1,198 @@
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21_067 Garurumon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_067 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Digivolution condition
+            if(timing == EffectTiming.None)
+            {
+                bool Condition(Permanent permanent)
+                {
+                    return (permanent.TopCard.ContainsCardName("Gabumon") || permanent.TopCard.EqualsTraits("ADVENTURE")) && permanent.Level == 3;
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(Condition, 2, false, card, null));
+            }
+            #endregion
+
+            #region Security
+            if (timing == EffectTiming.SecuritySkill)
+            {
+                cardEffects.Add(CardEffectFactory.PlaySelfDigimonAfterBattleSecurityEffect(card: card));
+            }
+            #endregion
+
+            #region On Play/When-Digivolving shared
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return CardEffectCommons.IsExistOnBattleAreaDigimon(card) && CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanSelectReturn); ;
+            }
+
+            bool CanSelectReturn(CardSource card)
+            {
+                return card.EqualsTraits("ADVENTURE") && card.IsDigimon;
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Return adventure trait", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] You may return 1 Digimon card with the [ADVENTURE] trait from your trash to the hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanSelectReturn,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: null,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 card to add to your hand.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.AddHand,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Return adventure trait", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] You may return 1 Digimon card with the [ADVENTURE] trait from your trash to the hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanSelectReturn,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: null,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 card to add to your hand.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.AddHand,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                }
+            }
+            #endregion
+
+            #region Inherit - When Attacking
+
+            if (timing == EffectTiming.OnAllyAttack)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Draw 1 and trash 1 card from hand", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, 1, false, EffectDiscription());
+                activateClass.SetIsInheritedEffect(true);
+                activateClass.SetHashString("Draw_BT21_067");
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[When Attacking] [Once Per Turn] <Draw 1> and trash 1 card in your hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnAttack(hashtable, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleAreaDigimon(card))
+                    {
+                        return true;
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(new DrawClass(card.Owner, 1, activateClass).Draw());
+
+                    if (card.Owner.HandCards.Count >= 1)
+                    {
+                        int discardCount = 1;
+
+                        SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                        selectHandEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: (cardSource) => true,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: discardCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            isShowOpponent: true,
+                            selectCardCoroutine: null,
+                            afterSelectCardCoroutine: null,
+                            mode: SelectHandEffect.Mode.Discard,
+                            cardEffect: activateClass);
+
+                        yield return StartCoroutine(selectHandEffect.Activate());
+                    }
+                }
+            }
+
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_067.cs.meta

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

+ 230 - 0
Assets/CardEffect/BT21/Purple/BT21_068.cs

@@ -0,0 +1,230 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21_068 growlmon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_068 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region alternative digivolution requirement
+            if (timing == EffectTiming.None)
+            {
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return permanent.Level == 3 && permanent.TopCard.ContainsCardName("Guilmon");
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(
+                    permanentCondition: PermanentCondition, 
+                    digivolutionCost: 2, 
+                    ignoreDigivolutionRequirement: false, 
+                    card: card, 
+                    condition: null));
+            }
+            #endregion
+
+            #region on-play/when-digivolving shared
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return CardEffectCommons.IsExistOnBattleAreaDigimon(card);
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Delete 3k or mill 2", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] Delete 1 of your opponent's Digimon with 4000 DP or less. If this effect didn't delete, trash the top 2 cards of your deck.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                bool CanTarget(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card))
+                    {
+                        return permanent.DP <= card.Owner.MaxDP_DeleteEffect(3000, activateClass);
+                    }
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    List<Permanent> deleteTargetPermanents = new List<Permanent>();
+
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanTarget))
+                    {
+                        int maxCount = Math.Min(1, CardEffectCommons.MatchConditionPermanentCount(CanTarget));
+
+                        SelectPermanentEffect selectPermanentEffect =
+                            GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanTarget,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: maxCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: null,
+                            afterSelectPermanentCoroutine: AfterSelectPermanentCoroutine,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to delete.", "The opponent is selecting 1 Digimon to delete.");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator AfterSelectPermanentCoroutine(List<Permanent> permanents)
+                        {
+                            deleteTargetPermanents = permanents.Clone();
+                            yield return null;
+                        }
+                    }
+
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.DeletePeremanentAndProcessAccordingToResult(targetPermanents: deleteTargetPermanents, activateClass: activateClass, successProcess: null, failureProcess: FailureProcess));
+
+                    IEnumerator FailureProcess()
+                    {
+                        if (card.Owner.LibraryCards.Count >= 1)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(new IAddTrashCardsFromLibraryTop(2, card.Owner, activateClass).AddTrashCardsFromLibraryTop());
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Delete 3k or mill 2", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] Delete 1 of your opponent's Digimon with 4000 DP or less. If this effect didn't delete, trash the top 2 cards of your deck.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                bool CanTarget(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card))
+                    {
+                        return permanent.DP <= card.Owner.MaxDP_DeleteEffect(3000, activateClass);
+                    }
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    List<Permanent> deleteTargetPermanents = new List<Permanent>();
+
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanTarget))
+                    {
+                        int maxCount = Math.Min(1, CardEffectCommons.MatchConditionPermanentCount(CanTarget));
+
+                        SelectPermanentEffect selectPermanentEffect =
+                            GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanTarget,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: maxCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: null,
+                            afterSelectPermanentCoroutine: AfterSelectPermanentCoroutine,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to delete.", "The opponent is selecting 1 Digimon to delete.");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator AfterSelectPermanentCoroutine(List<Permanent> permanents)
+                        {
+                            deleteTargetPermanents = permanents.Clone();
+                            yield return null;
+                        }
+                    }
+
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.DeletePeremanentAndProcessAccordingToResult(targetPermanents: deleteTargetPermanents, activateClass: activateClass, successProcess: null, failureProcess: FailureProcess));
+
+                    IEnumerator FailureProcess()
+                    {
+                        if (card.Owner.LibraryCards.Count >= 1)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(new IAddTrashCardsFromLibraryTop(2, card.Owner, activateClass).AddTrashCardsFromLibraryTop());
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region On Deletion inherit
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Memory +1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                activateClass.SetIsInheritedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Deletion] Gain 1 memory.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletionInherited(hashtable, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.CanActivateOnDeletion(card))
+                    {
+                        if (card.Owner.CanAddMemory(activateClass))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(card.Owner.AddMemory(1, activateClass));
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_068.cs.meta

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

+ 380 - 0
Assets/CardEffect/BT21/Purple/BT21_069.cs

@@ -0,0 +1,380 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21-069 GulusGammamon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_069 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Alt digivolution cost
+            if (timing == EffectTiming.None)
+            {
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return permanent.TopCard.EqualsCardName("Gammamon");
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(
+                    permanentCondition: PermanentCondition, 
+                    digivolutionCost: 2, 
+                    ignoreDigivolutionRequirement: false, 
+                    card: card, 
+                    condition: null));
+            }
+            #endregion
+
+            #region Security
+            if (timing == EffectTiming.SecuritySkill)
+            {
+                cardEffects.Add(CardEffectFactory.PlaySelfDigimonAfterBattleSecurityEffect(card: card));
+            }
+            #endregion
+
+            #region On-play/When-digivolving shared
+            bool HasGammamonNameDigimon(CardSource card)
+            {
+                return card.IsDigimon && card.ContainsCardName("Gammamon");
+            }
+
+            bool CanActivateShared(Hashtable hashtable)
+            {
+                if (CardEffectCommons.IsExistOnBattleAreaDigimon(card))
+                {
+                    return CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, HasGammamonNameDigimon)
+                        || CardEffectCommons.HasMatchConditionOwnersHand(card, HasGammamonNameDigimon);
+                }
+                return false;
+            }
+            #endregion
+
+            #region On-Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Tuck gammamon to delete", CanUseEffect, card);
+                activateClass.SetUpActivateClass(CanActivateShared, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] By placing 1 Digimon card with [Gammamon] in its name from your hand or trash as this Digimon's bottom digivolution card, delete 1 of your opponent's level 4 or lower Digimon.";
+                }
+
+                bool CanUseEffect(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                bool CanSelectPermanentCondition(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card))
+                    {
+                        if (CardEffectCommons.IsExistOnBattleArea(card))
+                        {
+                            return permanent.Level == 4;
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectHand = card.Owner.HandCards.Count(HasGammamonNameDigimon) >= 1;
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, HasGammamonNameDigimon);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>()
+                        {
+                            new SelectionElement<bool>(message: $"From hand", value : true, spriteIndex: 0),
+                            new SelectionElement<bool>(message: $"From trash", value : false, spriteIndex: 1),
+                        };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            int maxCount = 1;
+
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: HasGammamonNameDigimon,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+
+                        else
+                        {
+                            int maxCount = 1;
+
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: HasGammamonNameDigimon,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to place on bottom of digivolution cards.",
+                                maxCount: maxCount,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(card.PermanentOfThisCard().AddDigivolutionCardsBottom(selectedCards, activateClass));
+
+                            if (card.Owner.Enemy.GetBattleAreaPermanents().Count(CanSelectPermanentCondition) >= 1)
+                            {
+                                int maxCount = Math.Min(1, CardEffectCommons.MatchConditionPermanentCount(CanSelectPermanentCondition));
+
+                                SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                                selectPermanentEffect.SetUp(
+                                    selectPlayer: card.Owner,
+                                    canTargetCondition: CanSelectPermanentCondition,
+                                    canTargetCondition_ByPreSelecetedList: null,
+                                    canEndSelectCondition: null,
+                                    maxCount: maxCount,
+                                    canNoSelect: false,
+                                    canEndNotMax: false,
+                                    selectPermanentCoroutine: null,
+                                    afterSelectPermanentCoroutine: null,
+                                    mode: SelectPermanentEffect.Mode.Destroy,
+                                    cardEffect: activateClass);
+
+                                yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Tuck gammamon to delete", CanUseEffect, card);
+                activateClass.SetUpActivateClass(CanActivateShared, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] By placing 1 Digimon card with [Gammamon] in its name from your hand or trash as this Digimon's bottom digivolution card, delete 1 of your opponent's level 4 or lower Digimon.";
+                }
+
+                bool CanUseEffect(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                bool CanSelectPermanentCondition(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card))
+                    {
+                        if (CardEffectCommons.IsExistOnBattleArea(card))
+                        {
+                            return permanent.Level == 4;
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectHand = card.Owner.HandCards.Count(HasGammamonNameDigimon) >= 1;
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, HasGammamonNameDigimon);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>()
+                        {
+                            new SelectionElement<bool>(message: $"From hand", value : true, spriteIndex: 0),
+                            new SelectionElement<bool>(message: $"From trash", value : false, spriteIndex: 1),
+                        };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            int maxCount = 1;
+
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: HasGammamonNameDigimon,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+
+                        else
+                        {
+                            int maxCount = 1;
+
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: HasGammamonNameDigimon,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to place on bottom of digivolution cards.",
+                                maxCount: maxCount,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(card.PermanentOfThisCard().AddDigivolutionCardsBottom(selectedCards, activateClass));
+
+                            if (card.Owner.Enemy.GetBattleAreaPermanents().Count(CanSelectPermanentCondition) >= 1)
+                            {
+                                int maxCount = Math.Min(1, CardEffectCommons.MatchConditionPermanentCount(CanSelectPermanentCondition));
+
+                                SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                                selectPermanentEffect.SetUp(
+                                    selectPlayer: card.Owner,
+                                    canTargetCondition: CanSelectPermanentCondition,
+                                    canTargetCondition_ByPreSelecetedList: null,
+                                    canEndSelectCondition: null,
+                                    maxCount: maxCount,
+                                    canNoSelect: false,
+                                    canEndNotMax: false,
+                                    selectPermanentCoroutine: null,
+                                    afterSelectPermanentCoroutine: null,
+                                    mode: SelectPermanentEffect.Mode.Destroy,
+                                    cardEffect: activateClass);
+
+                                yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region Inherit
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                cardEffects.Add(CardEffectFactory.RetaliationSelfEffect(isInheritedEffect: true, card: card, condition: null));
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_069.cs.meta

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

+ 195 - 0
Assets/CardEffect/BT21/Purple/BT21_070.cs

@@ -0,0 +1,195 @@
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21_070 Gossipmon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_070 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Security
+            if (timing == EffectTiming.SecuritySkill)
+            {
+                cardEffects.Add(CardEffectFactory.PlaySelfDigimonAfterBattleSecurityEffect(card: card));
+            }
+            #endregion
+
+            #region On Play/When-Digivolving/When Linking shared
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return isExistOnField(card) && CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanSelectReturn); ;
+            }
+
+            bool CanSelectReturn(CardSource card)
+            {
+                return card.EqualsTraits("Appmon") && card.IsDigimon;
+            }
+            #endregion
+
+            #region On Play
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Return Appmon trait", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] You may return 1 Digimon card with the [Appmon] trait from your trash to the hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanSelectReturn,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: null,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 card to add to your hand.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.AddHand,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Return Appmon trait", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] You may return 1 Digimon card with the [Appmon] trait from your trash to the hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanSelectReturn,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: null,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 card to add to your hand.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.AddHand,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                }
+            }
+            #endregion
+
+            #region Linking
+            if (timing == EffectTiming.OnDeclaration)
+            {
+                cardEffects.Add(CardEffectFactory.LinkEffect(card));
+            }
+            #endregion
+
+            #region Link condition
+            if (timing == EffectTiming.None)
+            {
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return permanent.TopCard.HasAppmonTraits;
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfLinkConditionStaticEffect(permanentCondition: PermanentCondition, linkCost: 2, card: card));
+
+            }
+            #endregion
+
+            #region When Linking
+            if (timing == EffectTiming.WhenLinked)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Return Appmon", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDiscription());
+                activateClass.SetIsLinkedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[When Linking] You may return 1 Digimon card with the [Appmon] trait from your trash to the hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenLinking(hashtable, null, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return isExistOnField(card) && CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanSelectReturn);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanSelectReturn,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: null,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 card to add to your hand.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.AddHand,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_070.cs.meta

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

+ 427 - 0
Assets/CardEffect/BT21/Purple/BT21_071.cs

@@ -0,0 +1,427 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_071 Scopemon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_071 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Digivolution Condition
+            if(timing == EffectTiming.None)
+            {
+                bool Condition(Permanent permanent)
+                {
+                    return permanent.TopCard.HasText("Three Musketeers") && permanent.Level == 3;
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(Condition, 2, false, card, null));
+            }
+            #endregion
+
+            #region On Play/When Digivolving shared
+            bool CanTuckCondition(CardSource card)
+            {
+                return card.EqualsTraits("Appmon") || card.HasThreeMusketeersTraits;
+            }
+
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return isExistOnField(card) &&
+                    (card.Owner.HandCards.Count >= 1 || card.Owner.TrashCards.Count >= 1) &&
+                    CardEffectCommons.HasMatchConditionOwnersPermanent(card, CanTuckUnderCondition);
+            }
+
+            bool CanTuckUnderCondition(Permanent permanent)
+            {
+                return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card) && !permanent.IsToken;
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Tuck appmon/muskets for memory", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] By placing 1 card with the [Appmon] or [Three Musketeers] trait from your hand or trash as 1 of your Digimon's bottom digivolution card, gain 1 memory.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    bool canSelectHand = card.Owner.HandCards.Count(CanTuckCondition) >= 1;
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanTuckCondition);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From hand", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            int maxCount = 1;
+
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+
+                        else
+                        {
+                            int maxCount = 1;
+
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanTuckCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to place on bottom of digivolution cards.",
+                                maxCount: maxCount,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            int maxCount = Math.Min(1, CardEffectCommons.MatchConditionOwnersPermanentCount(card, CanTuckUnderCondition));
+
+                            SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                            selectPermanentEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckUnderCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                selectPermanentCoroutine: SelectPermanentCoroutine,
+                                afterSelectPermanentCoroutine: null,
+                                mode: SelectPermanentEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get a digivolution card.", "The opponent is selecting 1 Digimon that will get a digivolution card.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                            IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                            {
+                                Permanent selectedPermanent = permanent;
+
+                                if (selectedPermanent != null)
+                                {
+                                    yield return ContinuousController.instance.StartCoroutine(selectedPermanent.AddDigivolutionCardsBottom(new List<CardSource>() { selectedCards[0] }, activateClass));
+
+                                    yield return ContinuousController.instance.StartCoroutine(
+                                            card.Owner.AddMemory(1, activateClass));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Tuck appmon/muskets for memory", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] By placing 1 card with the [Appmon] or [Three Musketeers] trait from your hand or trash as 1 of your Digimon's bottom digivolution card, gain 1 memory.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    bool canSelectHand = card.Owner.HandCards.Count(CanTuckCondition) >= 1;
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanTuckCondition);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From hand", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            int maxCount = 1;
+
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+
+                        else
+                        {
+                            int maxCount = 1;
+
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanTuckCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to place on bottom of digivolution cards.",
+                                maxCount: maxCount,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            int maxCount = Math.Min(1, CardEffectCommons.MatchConditionOwnersPermanentCount(card, CanTuckUnderCondition));
+
+                            SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                            selectPermanentEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckUnderCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                selectPermanentCoroutine: SelectPermanentCoroutine,
+                                afterSelectPermanentCoroutine: null,
+                                mode: SelectPermanentEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get a digivolution card.", "The opponent is selecting 1 Digimon that will get a digivolution card.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                            IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                            {
+                                Permanent selectedPermanent = permanent;
+
+                                if (selectedPermanent != null)
+                                {
+                                    yield return ContinuousController.instance.StartCoroutine(selectedPermanent.AddDigivolutionCardsBottom(new List<CardSource>() { selectedCards[0] }, activateClass));
+
+                                    yield return ContinuousController.instance.StartCoroutine(
+                                            card.Owner.AddMemory(1, activateClass));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region Generic link capacity/condition
+            if (timing == EffectTiming.OnDeclaration)
+            {
+                cardEffects.Add(CardEffectFactory.LinkEffect(card));
+            }
+
+            if (timing == EffectTiming.None)
+            {
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return permanent.TopCard.HasAppmonTraits;
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfLinkConditionStaticEffect(permanentCondition: PermanentCondition, linkCost: 2, card: card));
+                
+            }
+            #endregion
+
+            #region When Linking
+            if (timing == EffectTiming.WhenLinked)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Trash 2 draw 2", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDiscription());
+                activateClass.SetIsLinkedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[When Linking] <Draw 2> and trash 2 cards in your hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenLinking(hashtable, null, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return isExistOnField(card) && (card.Owner.HandCards.Count >= 1 || card.Owner.LibraryCards.Count >= 1);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(new DrawClass(card.Owner, 2, activateClass).Draw());
+
+                    if (card.Owner.HandCards.Count >= 1)
+                    {
+                        int discardCount = Math.Min(2, card.Owner.HandCards.Count);
+
+                        SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                        selectHandEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: (cardSource) => true,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: discardCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            isShowOpponent: true,
+                            selectCardCoroutine: null,
+                            afterSelectCardCoroutine: null,
+                            mode: SelectHandEffect.Mode.Discard,
+                            cardEffect: activateClass);
+
+                        yield return StartCoroutine(selectHandEffect.Activate());
+                    }
+                }
+            }
+            #endregion
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_071.cs.meta

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

+ 128 - 0
Assets/CardEffect/BT21/Purple/BT21_072.cs

@@ -0,0 +1,128 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_072 Arresterdramon: Superior Mode
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_072 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Alternative Digivolution Cost
+            if (timing == EffectTiming.None)
+            {
+                bool validDigivolutionCondition(Permanent permanent)
+                {
+                    return permanent.Level == 4 && (permanent.TopCard.EqualsTraits("Hero") || permanent.TopCard.HasSaveText);
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(validDigivolutionCondition, 3, false, card, null));
+            }
+            #endregion
+            #region raid, piercing
+            if (timing == EffectTiming.OnAllyAttack)
+            {
+                cardEffects.Add(CardEffectFactory.RaidSelfEffect(isInheritedEffect: false, card: card, condition: null));
+            }
+
+            if (timing == EffectTiming.OnDetermineDoSecurityCheck)
+            {
+                cardEffects.Add(CardEffectFactory.PierceSelfEffect(isInheritedEffect: false, card: card, condition: null));
+            }
+            #endregion
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Attack with this Digimon without suspending", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] This Digimon may attack without suspending.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        return card.PermanentOfThisCard().CanAttack(activateClass, withoutTap: true);
+
+                    }
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (card.PermanentOfThisCard().CanAttack(activateClass, withoutTap: true))
+                        {
+                            SelectAttackEffect selectAttackEffect = GManager.instance.GetComponent<SelectAttackEffect>();
+
+                            selectAttackEffect.SetUp(
+                                attacker: card.PermanentOfThisCard(),
+                                canAttackPlayerCondition: () => true,
+                                defenderCondition: (permanent) => true,
+                                cardEffect: activateClass);
+
+                            selectAttackEffect.SetWithoutTap();
+                            yield return ContinuousController.instance.StartCoroutine(selectAttackEffect.Activate());
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region All Turns
+            if (timing == EffectTiming.None)
+            {
+                int count()
+                {
+                    return card.PermanentOfThisCard().DigivolutionCards.Count();
+                }
+
+                bool condition()
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (count() >= 1)
+                        {
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+                cardEffects.Add(CardEffectFactory.ChangeSelfDPStaticEffect(
+                    changeValue: 1000 * count(),
+                    isInheritedEffect: false,
+                    card: card,
+                    condition: condition));
+            }
+            #endregion
+
+            #region inherit your turn +2k
+            if(timing == EffectTiming.None)
+            {
+                bool condition()
+                {
+                    return CardEffectCommons.IsExistOnBattleArea(card) && CardEffectCommons.IsOwnerTurn(card);
+                }
+
+                cardEffects.Add(CardEffectFactory.ChangeSelfDPStaticEffect(changeValue: 2000, isInheritedEffect: true, card: card, condition: condition));
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_072.cs.meta

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

+ 578 - 0
Assets/CardEffect/BT21/Purple/BT21_073.cs

@@ -0,0 +1,578 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_073 Charismon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_073 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region  Appfusion
+            if (timing == EffectTiming.None)
+            {
+                AddAppFusionConditionClass addAppFusionConditionClass = new AddAppFusionConditionClass();
+                addAppFusionConditionClass.SetUpICardEffect($"App Fusion", CanUseCondition, card);
+                addAppFusionConditionClass.SetUpAddAppFusionConditionClass(getAppFusionCondition: GetAppFusion);
+                addAppFusionConditionClass.SetNotShowUI(true);
+                cardEffects.Add(addAppFusionConditionClass);
+
+                
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return true;
+                }
+
+                AppFusionCondition GetAppFusion(CardSource cardSource)
+                {
+                    string[] validCards = { "Sociamon", "Gossipmon" };
+                    if (cardSource == card)
+                    {
+                        bool linkCondition(CardSource source)
+                        {
+                            foreach (string name in validCards)
+                            {
+                                if (source.EqualsCardName(name))
+                                {
+                                    foreach(string otherName in validCards)
+                                    {
+                                        if(otherName != name && source.PermanentOfThisCard().TopCard.EqualsCardName(otherName))
+                                        {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+                            return false;
+                        }
+
+                        bool digimonCondition(Permanent permanent)
+                        {
+                            if (!card.CanNotEvolve(permanent))
+                            {
+                                foreach(string name in validCards)
+                                {
+                                    if (permanent.TopCard.EqualsCardName(name))
+                                    {
+                                        return true;
+                                    }
+                                }
+                            }
+
+                            return false;
+                        }
+
+                        AppFusionCondition AppFusionCondition = new AppFusionCondition(
+                            linkedCondition: linkCondition,
+                            selectLinkMessage: "1 [Sociamon] or [Gossipmon]",
+                            digimonCondition: digimonCondition,
+                            selectDigimonMessage: "1 [Sociamon] or [Gossipmon]",
+                            cost: 0);
+
+                        return AppFusionCondition;
+                    }
+
+                    return null;
+                }
+            }
+            #endregion
+
+            #region Blocker
+            if (timing == EffectTiming.None)
+            {
+                cardEffects.Add(CardEffectFactory.BlockerSelfStaticEffect(isInheritedEffect: false, card: card, condition: null));
+            }
+            #endregion
+
+            #region On Play/When Digivolving shared
+            bool CanLinkCondition(CardSource cardSource)
+            {
+                return cardSource.HasLevel && cardSource.Level <= 4 && cardSource.CanLinkFromTargetPermanent(card.PermanentOfThisCard(), false);
+            }
+
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return isExistOnField(card) && (CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanLinkCondition) ||
+                    card.PermanentOfThisCard().DigivolutionCards.Exists(CanLinkCondition));
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Link from trash or sources", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] You may link 1 level 4 or lower Digimon card from your trash or this Digimon's digivolution cards to this Digimon without paying the cost.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanLinkCondition);
+                    bool canSelectSources = card.PermanentOfThisCard().DigivolutionCards.Exists(CanLinkCondition);
+
+                    if(canSelectSources || canSelectTrash)
+                    {
+                        if(canSelectTrash && canSelectSources)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From sources", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectSources);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromSources = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromSources)
+                        {
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanLinkCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 digivolution card to link.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Custom,
+                                customRootCardList: card.PermanentOfThisCard().DigivolutionCards,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage("Select 1 digivolution card to link.", "The opponent is selecting 1 digivolution card to link.");
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Linked Card");
+
+                            yield return StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        else
+                        {
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanLinkCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to link.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage("Select 1 digivolution card to link.", "The opponent is selecting 1 digivolution card to link.");
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Linked Card");
+
+                            yield return StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            yield return card.PermanentOfThisCard().AddLinkCard(selectedCards[0], activateClass);
+                        }
+                    }
+                
+                    
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Link from trash or sources", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] You may link 1 level 4 or lower Digimon card from your trash or this Digimon's digivolution cards to this Digimon without paying the cost.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanLinkCondition);
+                    bool canSelectSources = card.PermanentOfThisCard().DigivolutionCards.Exists(CanLinkCondition);
+
+                    if (canSelectSources || canSelectTrash)
+                    {
+                        if (canSelectTrash && canSelectSources)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From sources", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectSources);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromSources = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromSources)
+                        {
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanLinkCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 digivolution card to link.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Custom,
+                                customRootCardList: card.PermanentOfThisCard().DigivolutionCards,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage("Select 1 digivolution card to link.", "The opponent is selecting 1 digivolution card to link.");
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Linked Card");
+
+                            yield return StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        else
+                        {
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanLinkCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to link.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage("Select 1 digivolution card to link.", "The opponent is selecting 1 digivolution card to link.");
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Linked Card");
+
+                            yield return StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            yield return card.PermanentOfThisCard().AddLinkCard(selectedCards[0], activateClass);
+                        }
+                    }
+
+
+                }
+            }
+            #endregion
+
+            #region Your turn
+            if(timing == EffectTiming.WhenLinked)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Taunt when linked", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, 1, false, EffectDescription());
+                activateClass.SetHashString("BT21_073_tauntOnLink");
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[Your Turn][Once Per Turn] When this Digimon gets linked, give 1 of your opponent's Digimon \"[Start of Your Main Phase] This Digimon attacks.\" until their turn ends.";
+                }
+
+                bool targetPermanentCondition( Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card);
+                }
+
+                bool LinkedPermanentCondition(Permanent permanent)
+                {
+                    return permanent == card.PermanentOfThisCard();
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenLinked(hashtable, LinkedPermanentCondition, null);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return isExistOnField(card) && CardEffectCommons.HasMatchConditionOpponentsPermanent(card, targetPermanentCondition);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.HasMatchConditionPermanent(targetPermanentCondition))
+                    {
+                        Permanent selectedPermanent = null;
+
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: targetPermanentCondition,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get effects.",
+                            "The opponent is selecting 1 Digimon that will get effects.");
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            selectedPermanent = permanent;
+
+                            yield return null;
+                        }
+
+                        if (selectedPermanent != null)
+                        {
+                            ActivateClass activateClassDebuff = new ActivateClass();
+                            activateClassDebuff.SetUpICardEffect("Attack with this Digimon", CanUseConditionDebuff,
+                                selectedPermanent.TopCard);
+                            activateClassDebuff.SetUpActivateClass(CanActivateConditionDebuff, ActivateCoroutineDebuff, -1, false,
+                                EffectDescriptionDebuff());
+                            activateClassDebuff.SetEffectSourcePermanent(selectedPermanent);
+                            selectedPermanent.UntilOwnerTurnEndEffects.Add(GetCardEffect);
+
+                            if (!selectedPermanent.TopCard.CanNotBeAffected(activateClass))
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>()
+                                    .CreateDebuffEffect(selectedPermanent));
+                            }
+
+                            string EffectDescriptionDebuff()
+                            {
+                                return "[Start of Your Main Phase] Attack with this Digimon.";
+                            }
+
+                            bool CanUseConditionDebuff(Hashtable hashtable1)
+                            {
+                                return CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(selectedPermanent) &&
+                                       selectedPermanent.TopCard.Owner.GetBattleAreaDigimons().Contains(selectedPermanent) &&
+                                       GManager.instance.turnStateMachine.gameContext.TurnPlayer == selectedPermanent.TopCard.Owner;
+                            }
+
+                            bool CanActivateConditionDebuff(Hashtable hashtable1)
+                            {
+                                return CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(selectedPermanent) &&
+                                       !selectedPermanent.TopCard.CanNotBeAffected(activateClass) &&
+                                       selectedPermanent.CanAttack(activateClassDebuff);
+                            }
+
+                            IEnumerator ActivateCoroutineDebuff(Hashtable hashtableDebuff)
+                            {
+                                if (CardEffectCommons.IsPermanentExistsOnBattleArea(selectedPermanent) &&
+                                    selectedPermanent.CanAttack(activateClassDebuff))
+                                {
+                                    SelectAttackEffect selectAttackEffect =
+                                        GManager.instance.GetComponent<SelectAttackEffect>();
+
+                                    selectAttackEffect.SetUp(
+                                        attacker: selectedPermanent,
+                                        canAttackPlayerCondition: () => true,
+                                        defenderCondition: _ => true,
+                                        cardEffect: activateClassDebuff);
+
+                                    selectAttackEffect.SetCanNotSelectNotAttack();
+
+                                    yield return ContinuousController.instance.StartCoroutine(selectAttackEffect.Activate());
+                                }
+                            }
+
+                            ICardEffect GetCardEffect(EffectTiming timingDebuff)
+                            {
+                                return timingDebuff == EffectTiming.OnStartMainPhase ? activateClassDebuff : null;
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region Linking
+            if (timing == EffectTiming.None)
+            {
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return permanent.TopCard.HasAppmonTraits;
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfLinkConditionStaticEffect(permanentCondition: PermanentCondition, linkCost: 3, card: card));
+            }
+
+            if(timing == EffectTiming.OnDeclaration)
+            {
+                cardEffects.Add(CardEffectFactory.LinkEffect(card));
+            }
+            #endregion
+
+            #region Link effect
+            if (timing == EffectTiming.WhenRemoveField)
+            {
+                List<Permanent> removedPermanents = new List<Permanent>();
+
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Trash a linked card to prevent this digimon from leaving", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, 1, true, EffectDescription());
+                activateClass.SetIsLinkedEffect(true);
+                activateClass.SetHashString("AllTurns_BT21_073");
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return
+                        "[All Turns][Once Per Turn] When this Digimon would leave the battle area, by trashing 1 of this Digimon's link cards, it doesn't leave.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) &&
+                           CardEffectCommons.CanTriggerWhenRemoveField(hashtable, card);
+                    
+                }
+
+                bool CanSelectPermanentCondition(Permanent permanent)
+                {
+                    if (permanent == card.PermanentOfThisCard())
+                    {
+                        if (permanent.LinkedCards.Count(CanSelectCardCondition) >= 1)
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanSelectCardCondition(CardSource cardSource)
+                {
+                    return true;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) &&
+                           !card.PermanentOfThisCard().HasNoLinkCards;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.SelectTrashLinkedCards(CanSelectPermanentCondition, CanSelectCardCondition, 1, true, true, activateClass,afterSelectionCoroutine: AfterSelectCardCoroutine));
+
+                    bool trashed = false;
+
+                    IEnumerator AfterSelectCardCoroutine(Permanent permanent, List<CardSource> cardSources)
+                    {
+                        if(cardSources.Count == 1)
+                        {
+                            trashed = true;
+                        }
+                        yield return null;
+                    }
+
+                    if (trashed)
+                    {
+                        card.PermanentOfThisCard().willBeRemoveField = false;
+
+                        card.PermanentOfThisCard().HideHandBounceEffect();
+                        card.PermanentOfThisCard().HideDeckBounceEffect();
+                        card.PermanentOfThisCard().HideWillRemoveFieldEffect();
+                        card.PermanentOfThisCard().HideDeleteEffect();
+                    }
+                }
+            }
+            #endregion
+
+            return cardEffects; 
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_073.cs.meta

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

+ 698 - 0
Assets/CardEffect/BT21/Purple/BT21_074.cs

@@ -0,0 +1,698 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_074 Satellamon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_074 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Digivolution condition
+            if(timing == EffectTiming.None)
+            {
+                bool Condition(Permanent permanent)
+                {
+                    return permanent.Level == 4 && permanent.TopCard.HasText("Three Musketeers");
+                }
+            }
+            #endregion
+
+            #region On Play/When Digivolving shared
+            bool CanActivateConditionSharedOP(Hashtable hashtable)
+            {
+                return isExistOnField(card) &&
+                    (card.Owner.HandCards.Count >= 1 || card.Owner.TrashCards.Count >= 1) &&
+                    CardEffectCommons.HasMatchConditionOwnersPermanent(card, CanTuckUnderCondition);
+            }
+
+            bool CanTuckUnderCondition(Permanent permanent)
+            {
+                return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card) && !permanent.IsToken;
+            }
+
+            void ActivateDeDigivolveProtection()
+            {
+                ImmuneFromDeDigivolveClass immuneFromDeDigivolveClass = new ImmuneFromDeDigivolveClass();
+                immuneFromDeDigivolveClass.SetUpICardEffect("Isn't affected by <De-Digivolve>", CanUseImmunityCondition,
+                    card.PermanentOfThisCard().TopCard);
+                immuneFromDeDigivolveClass.SetUpImmuneFromDeDigivolveClass(PermanentCondition: PermanentImmunityCondition);
+                card.PermanentOfThisCard().UntilOpponentTurnEndEffects.Add(_ => immuneFromDeDigivolveClass);
+            }
+
+            bool CanUseImmunityCondition(Hashtable hashtable1)
+            {
+                return card.PermanentOfThisCard().TopCard != null;
+            }
+
+            bool PermanentImmunityCondition(Permanent permanent)
+            {
+                return permanent == card.PermanentOfThisCard();
+            }
+            #endregion
+
+            #region OnPlay/WhenDigivolving/WhenAttacking shared
+            bool CanTuckOrTrash(CardSource cardSource)
+            {
+                return card.EqualsTraits("Appmon") || card.HasThreeMusketeersTraits;
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Tuck to get protections", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionSharedOP, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] By placing 1 [Appmon] or [Three Musketeers] trait card from your hand or trash as any of your Digimon's bottom digivolution cards, until your opponent's turn ends, their effects can't return that Digimon to hand or decks or affect it with <De-Digivolve> effects.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectHand = card.Owner.HandCards.Count(CanTuckOrTrash) >= 1;
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanTuckOrTrash);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From hand", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            int maxCount = 1;
+
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckOrTrash,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+
+                        else
+                        {
+                            int maxCount = 1;
+
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanTuckOrTrash,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to place on bottom of digivolution cards.",
+                                maxCount: maxCount,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            int maxCount = Math.Min(1, CardEffectCommons.MatchConditionOwnersPermanentCount(card, CanTuckUnderCondition));
+
+                            SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                            selectPermanentEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckUnderCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                selectPermanentCoroutine: SelectPermanentCoroutine,
+                                afterSelectPermanentCoroutine: null,
+                                mode: SelectPermanentEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get a digivolution card.", "The opponent is selecting 1 Digimon that will get a digivolution card.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                            IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                            {
+                                Permanent selectedPermanent = permanent;
+
+                                if (selectedPermanent != null)
+                                {
+                                    yield return ContinuousController.instance.StartCoroutine(selectedPermanent.AddDigivolutionCardsBottom(new List<CardSource>() { selectedCards[0] }, activateClass));
+
+                                    #region Immunities
+
+                                    bool CardEffectCondition(ICardEffect cardEffect)
+                                    {
+                                        return CardEffectCommons.IsOpponentEffect(cardEffect, card);
+                                    }
+
+                                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainCanNotReturnToHand(
+                                        targetPermanent: card.PermanentOfThisCard(),
+                                        cardEffectCondition: CardEffectCondition,
+                                        effectDuration: EffectDuration.UntilOpponentTurnEnd,
+                                        activateClass: activateClass,
+                                        effectName: "Can't return to hand by opponent's effects"));
+
+                                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainCanNotReturnToDeck(
+                                        targetPermanent: card.PermanentOfThisCard(),
+                                        cardEffectCondition: CardEffectCondition,
+                                        effectDuration: EffectDuration.UntilOpponentTurnEnd,
+                                        activateClass: activateClass,
+                                        effectName: "Can't return to deck by opponent's effects"));
+
+                                    ActivateDeDigivolveProtection();
+                                    #endregion
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving (tuck)
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Tuck to get protections", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionSharedOP, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] By placing 1 [Appmon] or [Three Musketeers] trait card from your hand or trash as any of your Digimon's bottom digivolution cards, until your opponent's turn ends, their effects can't return that Digimon to hand or decks or affect it with <De-Digivolve> effects.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectHand = card.Owner.HandCards.Count(CanTuckOrTrash) >= 1;
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanTuckOrTrash);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From hand", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you select a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            int maxCount = 1;
+
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckOrTrash,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+
+                        else
+                        {
+                            int maxCount = 1;
+
+                            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                            selectCardEffect.SetUp(
+                                canTargetCondition: CanTuckOrTrash,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 card to place on bottom of digivolution cards.",
+                                maxCount: maxCount,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to place on bottom of digivolution cards.", "The opponent is selecting 1 card to place on bottom of digivolution cards.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        if (selectedCards.Count >= 1)
+                        {
+                            int maxCount = Math.Min(1, CardEffectCommons.MatchConditionOwnersPermanentCount(card, CanTuckUnderCondition));
+
+                            SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                            selectPermanentEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanTuckUnderCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                selectPermanentCoroutine: SelectPermanentCoroutine,
+                                afterSelectPermanentCoroutine: null,
+                                mode: SelectPermanentEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get a digivolution card.", "The opponent is selecting 1 Digimon that will get a digivolution card.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                            IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                            {
+                                Permanent selectedPermanent = permanent;
+
+                                if (selectedPermanent != null)
+                                {
+                                    yield return ContinuousController.instance.StartCoroutine(selectedPermanent.AddDigivolutionCardsBottom(new List<CardSource>() { selectedCards[0] }, activateClass));
+
+                                    #region Immunities
+
+                                    bool CardEffectCondition(ICardEffect cardEffect)
+                                    {
+                                        return CardEffectCommons.IsOpponentEffect(cardEffect, card);
+                                    }
+
+                                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainCanNotReturnToHand(
+                                        targetPermanent: card.PermanentOfThisCard(),
+                                        cardEffectCondition: CardEffectCondition,
+                                        effectDuration: EffectDuration.UntilOpponentTurnEnd,
+                                        activateClass: activateClass,
+                                        effectName: "Can't return to hand by opponent's effects"));
+
+                                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainCanNotReturnToDeck(
+                                        targetPermanent: card.PermanentOfThisCard(),
+                                        cardEffectCondition: CardEffectCondition,
+                                        effectDuration: EffectDuration.UntilOpponentTurnEnd,
+                                        activateClass: activateClass,
+                                        effectName: "Can't return to deck by opponent's effects"));
+
+                                    ActivateDeDigivolveProtection();
+                                    #endregion
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving/When Attacking shared
+            bool CanActivateConditionAtkShared(Hashtable hashtable)
+            {
+                return isExistOnField(card) && card.PermanentOfThisCard().DigivolutionCards.Some(CanTuckOrTrash);
+            }
+
+            bool DedigivolveTarget(Permanent permanent)
+            {
+                return CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card);
+            }
+            #endregion
+
+            #region When Digivolving (trash)
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Trash source to de-digivolve", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionAtkShared, ActivateCoroutine, 1, false, EffectDescription());
+                activateClass.SetHashString("BT21_074De-digivolve");
+                cardEffects.Add(activateClass);
+                    
+                string EffectDescription()
+                {
+                    return "[When Digivolving][Once Per Turn] By trashing 1 card with the [Appmon] or [Three Musketeers] trait from your Digimon's digivolution cards, <De-Digivolve 1> 1 of your opponent's Digimon.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool trashed = false;
+
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                                canTargetCondition: CanTuckOrTrash,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 [Three Musketeers] or [Appmon] card to trash.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Custom,
+                                customRootCardList: card.PermanentOfThisCard().DigivolutionCards,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: null);
+
+                    selectCardEffect.SetUpCustomMessage("Select 1 [Three Musketeers] or [Appmon] card to trash.", "The opponent is selecting 1 [Three Musketeers] or [Appmon] card to trash.");
+
+                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    if (selectedCards.Count >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(new ITrashDigivolutionCards(card.PermanentOfThisCard(), selectedCards, activateClass).TrashDigivolutionCards());
+
+                        trashed = true;
+                        selectedCards.Clear();
+                    }
+
+                    if (trashed)
+                    {
+                        if (CardEffectCommons.HasMatchConditionPermanent(DedigivolveTarget))
+                        {
+                            SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                            selectPermanentEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: DedigivolveTarget,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: 1,
+                                canNoSelect: false,
+                                canEndNotMax: false,
+                                selectPermanentCoroutine: SelectedDedigivolveTarget,
+                                afterSelectPermanentCoroutine: null,
+                                mode: SelectPermanentEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to De-Digivolve.", "The opponent is selecting 1 Digimon to De-Digivolve.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                            IEnumerator SelectedDedigivolveTarget(Permanent target)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(new IDegeneration(target, 1, activateClass).Degeneration());
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When Attacking
+            if (timing == EffectTiming.OnAllyAttack)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Trash source to de-digivolve", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionAtkShared, ActivateCoroutine, 1, false, EffectDescription());
+                activateClass.SetHashString("BT21_074De-digivolve");
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving][Once Per Turn] By trashing 1 card with the [Appmon] or [Three Musketeers] trait from your Digimon's digivolution cards, <De-Digivolve 1> 1 of your opponent's Digimon.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnAttack(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool trashed = false;
+
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                                canTargetCondition: CanTuckOrTrash,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                canNoSelect: () => true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                message: "Select 1 [Three Musketeers] or [Appmon] card to trash.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Custom,
+                                customRootCardList: card.PermanentOfThisCard().DigivolutionCards,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: null);
+
+                    selectCardEffect.SetUpCustomMessage("Select 1 [Three Musketeers] or [Appmon] card to trash.", "The opponent is selecting 1 [Three Musketeers] or [Appmon] card to trash.");
+
+                    yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    if (selectedCards.Count >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(new ITrashDigivolutionCards(card.PermanentOfThisCard(), selectedCards, activateClass).TrashDigivolutionCards());
+
+                        trashed = true;
+                        selectedCards.Clear();
+                    }
+
+                    if (trashed)
+                    {
+                        if (CardEffectCommons.HasMatchConditionPermanent(DedigivolveTarget))
+                        {
+                            SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                            selectPermanentEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: DedigivolveTarget,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: 1,
+                                canNoSelect: false,
+                                canEndNotMax: false,
+                                selectPermanentCoroutine: SelectedDedigivolveTarget,
+                                afterSelectPermanentCoroutine: null,
+                                mode: SelectPermanentEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to De-Digivolve.", "The opponent is selecting 1 Digimon to De-Digivolve.");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                            IEnumerator SelectedDedigivolveTarget(Permanent target)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(new IDegeneration(target, 1, activateClass).Degeneration());
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region Ability to link
+            if (timing == EffectTiming.None)
+            {
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return permanent.TopCard.HasAppmonTraits;
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfLinkConditionStaticEffect(permanentCondition: PermanentCondition, linkCost: 3, card: card));
+
+            }
+
+            if(timing == EffectTiming.OnDeclaration)
+            {
+                cardEffects.Add(CardEffectFactory.LinkEffect(card));
+            }
+            #endregion
+
+            #region When Linking
+            if (timing == EffectTiming.WhenLinked)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Delete level 4", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDiscription());
+                activateClass.SetIsLinkedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[When Linking] Delete 1 of your opponent's level 4 or lower Digimon.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenLinking(hashtable, null, card);
+                }
+
+                bool DeletionTargetCondition(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card) && permanent.TopCard.HasLevel && permanent.Level <= 4;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return isExistOnField(card) && CardEffectCommons.HasMatchConditionOpponentsPermanent(card, DeletionTargetCondition);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if(CardEffectCommons.HasMatchConditionOpponentsPermanent(card, DeletionTargetCondition))
+                    {
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+                        int maxCount = 1;
+
+                        selectPermanentEffect.SetUp(
+
+                            selectPlayer: card.Owner,
+                            canTargetCondition: DeletionTargetCondition,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: maxCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: null,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Destroy,
+                            cardEffect: activateClass);
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+                    }
+                    
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_074.cs.meta

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

+ 330 - 0
Assets/CardEffect/BT21/Purple/BT21_075.cs

@@ -0,0 +1,330 @@
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21_075 Skullgreymon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_075 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Digivolution Requirement
+            if(timing == EffectTiming.None)
+            {
+                bool Condition(Permanent permanent)
+                {
+                    return (permanent.TopCard.EqualsTraits("ADVENTURE") || permanent.TopCard.ContainsCardName("Greymon")) && permanent.Level == 4;
+                }
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(Condition, 3, false, card, null));
+            }
+            #endregion
+
+            #region On Play/When Digivolving Shared
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return CardEffectCommons.IsExistOnBattleAreaDigimon(card);
+            }
+
+            bool CanTargetDigimonConditionShared(Permanent permanent)
+            {
+                return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card);
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Give raid and retal", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] 1 of your Digimon gains <Raid> and <Retaliation> until your opponent's turn ends.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanTargetDigimonConditionShared))
+                    {
+                        Permanent selectedPermanent = null;
+
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanTargetDigimonConditionShared,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to gain Raid and Retaliation", "Opponent is select 1 Digimon to gain Raid and Retaliation");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            selectedPermanent = permanent;
+
+                            yield return null;
+                        }
+
+                        if (selectedPermanent != null)
+                        {
+
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainRaid(
+                                targetPermanent: selectedPermanent,
+                                effectDuration: EffectDuration.UntilEachTurnEnd,
+                                activateClass: activateClass));
+
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainRetaliation(
+                                targetPermanent: selectedPermanent,
+                                effectDuration: EffectDuration.UntilEachTurnEnd,
+                                activateClass: activateClass));
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Give raid and retal", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] 1 of your Digimon gains <Raid> and <Retaliation> until your opponent's turn ends.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanTargetDigimonConditionShared))
+                    {
+                        Permanent selectedPermanent = null;
+
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanTargetDigimonConditionShared,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to gain Raid and Retaliation", "Opponent is select 1 Digimon to gain Raid and Retaliation");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            selectedPermanent = permanent;
+
+                            yield return null;
+                        }
+
+                        if (selectedPermanent != null)
+                        {
+
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainRaid(
+                                targetPermanent: selectedPermanent,
+                                effectDuration: EffectDuration.UntilEachTurnEnd,
+                                activateClass: activateClass));
+
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainRetaliation(
+                                targetPermanent: selectedPermanent,
+                                effectDuration: EffectDuration.UntilEachTurnEnd,
+                                activateClass: activateClass));
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region On deletion regular and inherit shared
+            string EffectDescriptionShared()
+            {
+                return
+                    "[On Deletion] You may play 1 [ADVENTURE] trait card with a play cost of 4 or less form your trash without paying the cost.";
+            }
+            #endregion
+
+            #region On Deletion non-inherit
+            if(timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Play ADVENTURE cost 4 or less", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, true, EffectDescriptionShared());
+                cardEffects.Add(activateClass);
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnDeletion(hashtable, card);
+                }
+
+                bool CanPlay(CardSource cardSource)
+                {
+                    return cardSource.EqualsTraits("ADVENTURE") && cardSource.HasPlayCost && cardSource.GetCostItself <= 4 &&
+                           CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletion(card) &&
+                           CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanPlay);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanPlay,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 [ADVENTURE] card to play.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.Custom,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    selectCardEffect.SetUpCustomMessage("Select 1 [ADVENTURE] card to play.",
+                        "The opponent is selecting 1 [ADVENTURE] card to play.");
+                    selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                    yield return StartCoroutine(selectCardEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                        cardSources: selectedCards,
+                        activateClass: activateClass,
+                        payCost: false,
+                        isTapped: false,
+                        root: SelectCardEffect.Root.Trash,
+                        activateETB: true));
+                }
+            }
+            #endregion
+
+            #region On Deletion inherit
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Play ADVENTURE cost 4 or less", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, true, EffectDescriptionShared());
+                activateClass.SetIsInheritedEffect(true);
+                cardEffects.Add(activateClass);
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletionInherited(hashtable, card);
+                }
+
+                bool CanPlay(CardSource cardSource)
+                {
+                    return cardSource.EqualsTraits("ADVENTURE") && cardSource.HasPlayCost && cardSource.GetCostItself <= 4 &&
+                           CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletion(card) &&
+                           CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanPlay);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanPlay,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 [ADVENTURE] card to play.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.Custom,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    selectCardEffect.SetUpCustomMessage("Select 1 [ADVENTURE] card to play.",
+                        "The opponent is selecting 1 [ADVENTURE] card to play.");
+                    selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                    yield return StartCoroutine(selectCardEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                        cardSources: selectedCards,
+                        activateClass: activateClass,
+                        payCost: false,
+                        isTapped: false,
+                        root: SelectCardEffect.Root.Trash,
+                        activateETB: true));
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_075.cs.meta

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

+ 189 - 0
Assets/CardEffect/BT21/Purple/BT21_076.cs

@@ -0,0 +1,189 @@
+    using System.Collections;
+using System.Collections.Generic;
+
+//BT21-076 Wargrowlmon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_076 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region alternative digivolution method
+            if(timing == EffectTiming.None)
+            {
+
+                CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(permanent => permanent.Level == 4 && permanent.TopCard.ContainsCardName("Growlmon"), 3, false, card, null);
+            }
+            #endregion
+
+            #region On Play/When Digivolving shared
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return CardEffectCommons.IsExistOnBattleAreaDigimon(card);
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("trash 2, get raid retal", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] Trash the top 2 cards of your deck. Then, this Digimon gains <Raid> and <Retaliation> until your opponent's turn ends.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (card.Owner.LibraryCards.Count >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(new IAddTrashCardsFromLibraryTop(2, card.Owner, activateClass).AddTrashCardsFromLibraryTop());
+                    }
+                    yield return CardEffectCommons.GainRaid(card.PermanentOfThisCard(), EffectDuration.UntilOpponentTurnEnd, activateClass);
+                    yield return CardEffectCommons.GainRetaliation(card.PermanentOfThisCard(), EffectDuration.UntilOpponentTurnEnd, activateClass);
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("trash 2, get raid retal", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] Trash the top 2 cards of your deck. Then, this Digimon gains <Raid> and <Retaliation> until your opponent's turn ends.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (card.Owner.LibraryCards.Count >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(new IAddTrashCardsFromLibraryTop(2, card.Owner, activateClass).AddTrashCardsFromLibraryTop());
+                    }
+                    yield return CardEffectCommons.GainRaid(card.PermanentOfThisCard(), EffectDuration.UntilOpponentTurnEnd, activateClass);
+                    yield return CardEffectCommons.GainRetaliation(card.PermanentOfThisCard(), EffectDuration.UntilOpponentTurnEnd, activateClass);
+                }
+            }
+            #endregion
+
+            #region When Attacking
+            if(timing == EffectTiming.OnAllyAttack)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Digivolve to Megidra or ChaosGallant", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, 1, true, EffectDescription());
+                activateClass.SetHashString("BT21_076 when attacking");
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Attacking][Once Per Turn] This Digimon may digivolve into a Digimon card with [Megidramon] or [ChaosGallantmon] in its name in the hand. For every 10 total cards in both players' trashes, reduce this effect's digivolution cost by 1.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnAttack(hashtable, card);
+                }
+
+                bool CanDigivolveIntoCardCondition(CardSource cardsource)
+                {
+                    return cardsource.ContainsCardName("Megidramon") || cardsource.ContainsCardName("ChaosGallantmon");
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) && CardEffectCommons.HasMatchConditionOwnersHand(card, CanDigivolveIntoCardCondition);
+                }
+
+                int Count()
+                {
+                    return (card.Owner.TrashCards.Count + card.Owner.Enemy.TrashCards.Count) / 10;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if(CardEffectCommons.HasMatchConditionOwnersHand(card, CanDigivolveIntoCardCondition))
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(
+                            CardEffectCommons.DigivolveIntoHandOrTrashCard(
+                                targetPermanent: card.PermanentOfThisCard(),
+                                cardCondition: CanDigivolveIntoCardCondition,
+                                payCost: true,
+                                reduceCostTuple: (reduceCost: Count(), reduceCostCardCondition: null),
+                                fixedCostTuple: null,
+                                ignoreDigivolutionRequirementFixedCost: -1,
+                                isHand: true,
+                                activateClass: activateClass,
+                                successProcess: null));
+                    }
+
+                    
+                }
+            }
+            #endregion
+
+            #region On Deletion Inherit
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Trash the top card of your opponent's security stack.", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                activateClass.SetIsInheritedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Deletion] Trash the top card of your opponent's security stack.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnDeletion(hashtable, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.CanActivateOnDeletionInherited(hashtable, card))
+                    {
+                        if (card.Owner.Enemy.SecurityCards.Count >= 1)
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(new IDestroySecurity(
+                        player: card.Owner.Enemy,
+                        destroySecurityCount: 1,
+                        cardEffect: activateClass,
+                        fromTop: true).DestroySecurity());
+                }
+            }
+            #endregion
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_076.cs.meta

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

+ 517 - 0
Assets/CardEffect/BT21/Purple/BT21_077.cs

@@ -0,0 +1,517 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_077 Regulusmon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_077 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Digivolution condition
+            if(timing == EffectTiming.None)
+            {
+                bool Condition(Permanent permanent)
+                {
+                    return permanent.Level == 4 && permanent.TopCard.HasText("Gammamon");
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(Condition, 3, false, card, null));
+            }
+            #endregion
+
+            #region On Play/When Digivolving shared
+            bool CanTargetPermanent(Permanent permanent)
+            {
+                return permanent.IsDigimon && CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card);
+            }
+
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return isExistOnField(card);
+            }
+
+            bool CanTrashCard(CardSource card)
+            {
+                return card.HasText("Gammamon");
+            }
+            #endregion
+
+            #region On Play
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Force attack and give collision", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Play] By trashing 1 card with [Gammamon] in its text from your hand, give 1 of your opponent's Digimon <Collision> and \"[Start of Your Main Phase] This Digimon attacks.\" until their turn ends.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (card.Owner.HandCards.Count(CanTrashCard) >= 1)
+                    {
+                        bool discarded = false;
+
+                        int discardCount = 1;
+
+                        SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                        selectHandEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanTrashCard,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: discardCount,
+                            canNoSelect: true,
+                            canEndNotMax: false,
+                            isShowOpponent: true,
+                            selectCardCoroutine: null,
+                            afterSelectCardCoroutine: AfterSelectCardCoroutine,
+                            mode: SelectHandEffect.Mode.Discard,
+                            cardEffect: activateClass);
+
+                        yield return StartCoroutine(selectHandEffect.Activate());
+
+                        IEnumerator AfterSelectCardCoroutine(List<CardSource> cardSources)
+                        {
+                            if (cardSources.Count >= 1)
+                            {
+                                discarded = true;
+
+                                yield return null;
+                            }
+                        }
+
+                        if (discarded)
+                        {
+                            if (CardEffectCommons.HasMatchConditionPermanent(CanTargetPermanent))
+                            {
+                                Permanent selectedPermanent = null;
+
+                                SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                                selectPermanentEffect.SetUp(
+                                    selectPlayer: card.Owner,
+                                    canTargetCondition: CanTargetPermanent,
+                                    canTargetCondition_ByPreSelecetedList: null,
+                                    canEndSelectCondition: null,
+                                    maxCount: 1,
+                                    canNoSelect: false,
+                                    canEndNotMax: false,
+                                    selectPermanentCoroutine: SelectPermanentCoroutine,
+                                    afterSelectPermanentCoroutine: null,
+                                    mode: SelectPermanentEffect.Mode.Custom,
+                                    cardEffect: activateClass);
+
+                                selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get effects.",
+                                    "The opponent is selecting 1 Digimon that will get effects.");
+                                yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                                IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                                {
+                                    selectedPermanent = permanent;
+
+                                    yield return null;
+                                }
+
+                                if (selectedPermanent != null)
+                                {
+
+                                    CardEffectCommons.GainCollision(selectedPermanent, EffectDuration.UntilOpponentTurnEnd, activateClass);
+
+                                    ActivateClass activateClassDebuff = new ActivateClass();
+                                    activateClassDebuff.SetUpICardEffect("Attack with this Digimon", CanUseConditionDebuff,
+                                        selectedPermanent.TopCard);
+                                    activateClassDebuff.SetUpActivateClass(CanActivateConditionDebuff, ActivateCoroutineDebuff, -1, false,
+                                        EffectDescriptionDebuff());
+                                    activateClassDebuff.SetEffectSourcePermanent(selectedPermanent);
+                                    selectedPermanent.UntilOwnerTurnEndEffects.Add(GetCardEffect);
+
+                                    if (!selectedPermanent.TopCard.CanNotBeAffected(activateClass))
+                                    {
+                                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>()
+                                            .CreateDebuffEffect(selectedPermanent));
+                                    }
+
+                                    string EffectDescriptionDebuff()
+                                    {
+                                        return "[Start of Your Main Phase] Attack with this Digimon.";
+                                    }
+
+                                    bool CanUseConditionDebuff(Hashtable hashtable1)
+                                    {
+                                        return CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(selectedPermanent) &&
+                                               selectedPermanent.TopCard.Owner.GetBattleAreaDigimons().Contains(selectedPermanent) &&
+                                               GManager.instance.turnStateMachine.gameContext.TurnPlayer == selectedPermanent.TopCard.Owner;
+                                    }
+
+                                    bool CanActivateConditionDebuff(Hashtable hashtable1)
+                                    {
+                                        return CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(selectedPermanent) &&
+                                               !selectedPermanent.TopCard.CanNotBeAffected(activateClass) &&
+                                               selectedPermanent.CanAttack(activateClassDebuff);
+                                    }
+
+                                    IEnumerator ActivateCoroutineDebuff(Hashtable hashtableDebuff)
+                                    {
+                                        if (CardEffectCommons.IsPermanentExistsOnBattleArea(selectedPermanent) &&
+                                            selectedPermanent.CanAttack(activateClassDebuff))
+                                        {
+                                            SelectAttackEffect selectAttackEffect =
+                                                GManager.instance.GetComponent<SelectAttackEffect>();
+
+                                            selectAttackEffect.SetUp(
+                                                attacker: selectedPermanent,
+                                                canAttackPlayerCondition: () => true,
+                                                defenderCondition: _ => true,
+                                                cardEffect: activateClassDebuff);
+
+                                            selectAttackEffect.SetCanNotSelectNotAttack();
+
+                                            yield return ContinuousController.instance.StartCoroutine(selectAttackEffect.Activate());
+                                        }
+                                    }
+
+                                    ICardEffect GetCardEffect(EffectTiming timingDebuff)
+                                    {
+                                        return timingDebuff == EffectTiming.OnStartMainPhase ? activateClassDebuff : null;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Force attack and give collision", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[When Digivolving] By trashing 1 card with [Gammamon] in its text from your hand, give 1 of your opponent's Digimon <Collision> and \"[Start of Your Main Phase] This Digimon attacks.\" until their turn ends.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (card.Owner.HandCards.Count(CanTrashCard) >= 1)
+                    {
+                        bool discarded = false;
+
+                        int discardCount = 1;
+
+                        SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                        selectHandEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanTrashCard,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: discardCount,
+                            canNoSelect: true,
+                            canEndNotMax: false,
+                            isShowOpponent: true,
+                            selectCardCoroutine: null,
+                            afterSelectCardCoroutine: AfterSelectCardCoroutine,
+                            mode: SelectHandEffect.Mode.Discard,
+                            cardEffect: activateClass);
+
+                        yield return StartCoroutine(selectHandEffect.Activate());
+
+                        IEnumerator AfterSelectCardCoroutine(List<CardSource> cardSources)
+                        {
+                            if (cardSources.Count >= 1)
+                            {
+                                discarded = true;
+
+                                yield return null;
+                            }
+                        }
+
+                        if (discarded)
+                        {
+                            if (CardEffectCommons.HasMatchConditionPermanent(CanTargetPermanent))
+                            {
+                                Permanent selectedPermanent = null;
+
+                                SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                                selectPermanentEffect.SetUp(
+                                    selectPlayer: card.Owner,
+                                    canTargetCondition: CanTargetPermanent,
+                                    canTargetCondition_ByPreSelecetedList: null,
+                                    canEndSelectCondition: null,
+                                    maxCount: 1,
+                                    canNoSelect: false,
+                                    canEndNotMax: false,
+                                    selectPermanentCoroutine: SelectPermanentCoroutine,
+                                    afterSelectPermanentCoroutine: null,
+                                    mode: SelectPermanentEffect.Mode.Custom,
+                                    cardEffect: activateClass);
+
+                                selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get effects.",
+                                    "The opponent is selecting 1 Digimon that will get effects.");
+                                yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                                IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                                {
+                                    selectedPermanent = permanent;
+
+                                    yield return null;
+                                }
+
+                                if (selectedPermanent != null)
+                                {
+
+                                    CardEffectCommons.GainCollision(selectedPermanent, EffectDuration.UntilOpponentTurnEnd, activateClass);
+
+                                    ActivateClass activateClassDebuff = new ActivateClass();
+                                    activateClassDebuff.SetUpICardEffect("Attack with this Digimon", CanUseConditionDebuff,
+                                        selectedPermanent.TopCard);
+                                    activateClassDebuff.SetUpActivateClass(CanActivateConditionDebuff, ActivateCoroutineDebuff, -1, false,
+                                        EffectDescriptionDebuff());
+                                    activateClassDebuff.SetEffectSourcePermanent(selectedPermanent);
+                                    selectedPermanent.UntilOwnerTurnEndEffects.Add(GetCardEffect);
+
+                                    if (!selectedPermanent.TopCard.CanNotBeAffected(activateClass))
+                                    {
+                                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>()
+                                            .CreateDebuffEffect(selectedPermanent));
+                                    }
+
+                                    string EffectDescriptionDebuff()
+                                    {
+                                        return "[Start of Your Main Phase] Attack with this Digimon.";
+                                    }
+
+                                    bool CanUseConditionDebuff(Hashtable hashtable1)
+                                    {
+                                        return CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(selectedPermanent) &&
+                                               selectedPermanent.TopCard.Owner.GetBattleAreaDigimons().Contains(selectedPermanent) &&
+                                               GManager.instance.turnStateMachine.gameContext.TurnPlayer == selectedPermanent.TopCard.Owner;
+                                    }
+
+                                    bool CanActivateConditionDebuff(Hashtable hashtable1)
+                                    {
+                                        return CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(selectedPermanent) &&
+                                               !selectedPermanent.TopCard.CanNotBeAffected(activateClass) &&
+                                               selectedPermanent.CanAttack(activateClassDebuff);
+                                    }
+
+                                    IEnumerator ActivateCoroutineDebuff(Hashtable hashtableDebuff)
+                                    {
+                                        if (CardEffectCommons.IsPermanentExistsOnBattleArea(selectedPermanent) &&
+                                            selectedPermanent.CanAttack(activateClassDebuff))
+                                        {
+                                            SelectAttackEffect selectAttackEffect =
+                                                GManager.instance.GetComponent<SelectAttackEffect>();
+
+                                            selectAttackEffect.SetUp(
+                                                attacker: selectedPermanent,
+                                                canAttackPlayerCondition: () => true,
+                                                defenderCondition: _ => true,
+                                                cardEffect: activateClassDebuff);
+
+                                            selectAttackEffect.SetCanNotSelectNotAttack();
+
+                                            yield return ContinuousController.instance.StartCoroutine(selectAttackEffect.Activate());
+                                        }
+                                    }
+
+                                    ICardEffect GetCardEffect(EffectTiming timingDebuff)
+                                    {
+                                        return timingDebuff == EffectTiming.OnStartMainPhase ? activateClassDebuff : null;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region On Deletions Shared
+            
+            #endregion
+
+            #region On deletion regular
+            if(timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Play Cannonweissmon or level 4 or lower gammamon in text digimon", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Deletion] You may play 1 [Canoweissmon] or 1 level 4 or lower Digimon card with [Gammamon] in its text from your trash without paying the cost.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnDeletion(hashtable, card);
+                }
+
+                bool CanPlay(CardSource cardSource)
+                {
+                    return ((cardSource.HasText("Gammamon") && cardSource.HasLevel && cardSource.Level <= 4) || cardSource.EqualsCardName("Cannonweissmon")) &&
+                           CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnDeletion(hashtable, card) && CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanPlay);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanPlay,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 [Cannonweissmon] or level 4 or lower [Gammamon] in text Digimon to play.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.Custom,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    selectCardEffect.SetUpCustomMessage("Select 1 [Cannonweissmon] or level 4 or lower [Gammamon] in text Digimon to play.",
+                        "The opponent is selecting 1 [Cannonweissmon] or level 4 or lower [Gammamon] in text Digimon to play.");
+                    selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                    yield return StartCoroutine(selectCardEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                        cardSources: selectedCards,
+                        activateClass: activateClass,
+                        payCost: false,
+                        isTapped: false,
+                        root: SelectCardEffect.Root.Trash,
+                        activateETB: true));
+                }
+            }
+            #endregion
+
+            #region On deletion inherit
+            if (timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Play Cannonweissmon or level 4 or lower gammamon in text digimon", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                activateClass.SetIsInheritedEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Deletion] You may play 1 level 4 or lower Digimon card with [Gammamon] in its text from your trash without paying the cost.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanActivateOnDeletionInherited(hashtable, card);
+                }
+
+                bool CanPlay(CardSource cardSource)
+                {
+                    return cardSource.HasText("Gammamon") && cardSource.HasLevel && cardSource.Level <= 4 &&
+                           CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnDeletion(hashtable, card) && CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanPlay);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    List<CardSource> selectedCards = new List<CardSource>();
+
+                    SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                    selectCardEffect.SetUp(
+                        canTargetCondition: CanPlay,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: null,
+                        message: "Select 1 level 4 or lower [Gammamon] in text Digimon to play.",
+                        maxCount: 1,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.Custom,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: activateClass);
+
+                    selectCardEffect.SetUpCustomMessage("Select 1 level 4 or lower [Gammamon] in text Digimon to play.",
+                        "The opponent is selecting 1 level 4 or lower [Gammamon] in text Digimon to play.");
+                    selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                    yield return StartCoroutine(selectCardEffect.Activate());
+
+                    IEnumerator SelectCardCoroutine(CardSource cardSource)
+                    {
+                        selectedCards.Add(cardSource);
+
+                        yield return null;
+                    }
+
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                        cardSources: selectedCards,
+                        activateClass: activateClass,
+                        payCost: false,
+                        isTapped: false,
+                        root: SelectCardEffect.Root.Trash,
+                        activateETB: true));
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_077.cs.meta

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

+ 300 - 0
Assets/CardEffect/BT21/Purple/BT21_078.cs

@@ -0,0 +1,300 @@
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21-078 Weregarurumon
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_078 : CEntity_Effect
+    {
+            public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Alternate Digivolution Requirement
+            if (timing == EffectTiming.None)
+            {
+                static bool PermanentCondition(Permanent targetPermanent)
+                {
+                    return (targetPermanent.TopCard.EqualsTraits("ADVENTURE") || targetPermanent.TopCard.ContainsCardName("Garurumon")) && targetPermanent.TopCard.HasLevel && targetPermanent.TopCard.Level == 4;
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(permanentCondition: PermanentCondition, digivolutionCost: 3, ignoreDigivolutionRequirement: false, card: card, condition: null));
+            }
+            #endregion
+
+            #region On Play/When Digivolving shared
+
+            bool CanActivateConditionShared(Hashtable hashtable)
+            {
+                return CardEffectCommons.IsExistOnBattleAreaDigimon(card) && CardEffectCommons.HasMatchConditionOpponentsPermanent(card, CanSelectPermanentCondition);
+            }
+
+            bool TamerTwoColourCount()
+            {
+                List<CardSource> tamerCards = new List<CardSource>();
+
+                foreach (Permanent permanent in card.Owner.GetBattleAreaPermanents())
+                {
+                    if (permanent.IsTamer)
+                    {
+                        tamerCards.Add(permanent.TopCard);
+                    }
+                }
+                return Combinations.GetDifferenetColorCardCount(tamerCards) >= 2;
+            }
+
+            bool CanSelectPermanentCondition(Permanent permanent)
+            {
+                return CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, card) && permanent.Level <= (TamerTwoColourCount() ? 5 : 4);
+            }
+            #endregion
+
+            #region On Play
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Delete a level 4 digimon, or 5 if tamers have 2+ colour", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDiscription());
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[On Play][When Digivolving] Delete 1 of your opponent's level 4 or lower Digimon. If your Tamers have 2 or more total colors, add 1 to this effect's level maximum.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnPlay(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanSelectPermanentCondition))
+                    {
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanSelectPermanentCondition,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: null,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Destroy,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage(
+                            "Select 1 opposing Digimon to delete.",
+                            "The opponent is selecting 1 of your Digimon to delete");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+                    }
+                }
+            }
+            #endregion
+
+            #region When Digivolving
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Delete a level 4 digimon, or 5 if tamers have 2+ colour", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateConditionShared, ActivateCoroutine, -1, false, EffectDiscription());
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[On Play][When Digivolving] Delete 1 of your opponent's level 4 or lower Digimon. If your Tamers have 2 or more total colors, add 1 to this effect's level maximum.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerWhenDigivolving(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanSelectPermanentCondition))
+                    {
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanSelectPermanentCondition,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: null,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Destroy,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage(
+                            "Select 1 opposing Digimon to delete.",
+                            "The opponent is selecting 1 of your Digimon to delete");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+                    }
+                }
+            }
+            #endregion
+
+
+            #region Your Turn
+            if (timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Gain alliance then attack", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, 1, false, EffectDiscription());
+                activateClass.SetHashString("alliance-attack-BT21_078");
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[Your Turn][Once Per Turn] When your other Digimon are played or digivolve, if any of them have the [ADVENTURE] trait, 1 of your Digimon gains <Alliance> for the turn. Then, 1 of your Digimon may attack.";
+                }
+
+                bool MyDigimonPlayedDigid(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card) && permanent != card.PermanentOfThisCard())
+                    {
+                        return permanent.TopCard.EqualsTraits("ADVENTURE");
+                    }
+                    return false;
+                }
+
+                bool MyDigimonAlliance(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card);
+                }
+
+                bool MyDigimonAttacking(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card) &&
+                           permanent.CanAttack(activateClass);
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleAreaDigimon(card))
+                    {
+                        if (CardEffectCommons.IsOwnerTurn(card))
+                        {
+                            if (CardEffectCommons.CanTriggerOnPermanentPlay(hashtable, MyDigimonPlayedDigid))
+                                return true;
+
+                            if (CardEffectCommons.CanTriggerWhenPermanentDigivolving(hashtable, MyDigimonPlayedDigid))
+                                return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleAreaDigimon(card))
+                    {
+                        return true;
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.HasMatchConditionPermanent(MyDigimonAlliance))
+                    {
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: MyDigimonAlliance,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectBoostedDigimon,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to gain <Alliance>", "The opponent is selecting 1 Digimon to gain <Alliance>");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectBoostedDigimon(Permanent target)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainAlliance(targetPermanent: target, effectDuration: EffectDuration.UntilEachTurnEnd, activateClass: activateClass)); ;
+                        }
+                    }
+
+                    if (CardEffectCommons.HasMatchConditionPermanent(MyDigimonAttacking))
+                    {
+                        Permanent selectedPermanent = null;
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: MyDigimonAttacking,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to attack.", "The opponent is selecting 1 Digimon to attack.");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            selectedPermanent = permanent;
+
+                            yield return null;
+                        }
+
+                        if (selectedPermanent != null)
+                        {
+                            SelectAttackEffect selectAttackEffect = GManager.instance.GetComponent<SelectAttackEffect>();
+
+                            selectAttackEffect.SetUp(
+                                attacker: selectedPermanent,
+                                canAttackPlayerCondition: () => true,
+                                defenderCondition: _ => true,
+                                cardEffect: activateClass);
+
+                            yield return ContinuousController.instance.StartCoroutine(selectAttackEffect.Activate());
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region Alliance Inherit
+            if (timing == EffectTiming.OnAllyAttack)
+            {
+                bool Condition()
+                {
+                    return CardEffectCommons.IsExistOnBattleArea(card);
+                }
+
+                cardEffects.Add(CardEffectFactory.AllianceSelfEffect(isInheritedEffect: true, card: card, condition: Condition));
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_078.cs.meta

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

+ 180 - 0
Assets/CardEffect/BT21/Purple/BT21_079.cs

@@ -0,0 +1,180 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_079 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Alternative Digivolution Requirement
+            if(timing == EffectTiming.None)
+            {
+                bool DigivolutionCondition(Permanent permanent)
+                {
+                    return permanent.Level == 5 && permanent.TopCard.ContainsCardName("Growlmon");
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(DigivolutionCondition, 4, false, card, null));
+            }
+            #endregion
+
+            #region Security attack
+            if (timing == EffectTiming.None)
+            {
+                cardEffects.Add(CardEffectFactory.ChangeSelfSAttackStaticEffect(
+                    changeValue: 1,
+                    isInheritedEffect: false,
+                    card: card,
+                    condition: null));
+            }
+            #endregion
+
+            #region Rule Text
+
+            if (timing == EffectTiming.None)
+            {
+                ChangeCardNamesClass changeCardNamesClass = new ChangeCardNamesClass();
+                changeCardNamesClass.SetUpICardEffect("Also treated as [ChaosGallantmon]", _ => true, card);
+                changeCardNamesClass.SetUpChangeCardNamesClass(changeCardNames: ChangeCardNames);
+                cardEffects.Add(changeCardNamesClass);
+
+                List<string> ChangeCardNames(CardSource cardSource, List<string> cardNames)
+                {
+                    if (cardSource == card)
+                    {
+                        cardNames.Add("ChaosGallantmon");
+                    }
+
+                    return cardNames;
+                }
+            }
+
+            #endregion
+
+            #region End of attack
+            if (timing == EffectTiming.OnEndAttack)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Delete all digimon", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, 1, false, EffectDescription());
+                activateClass.SetHashString("BT21_079 EOA");
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[End of Attack][Once Per Turn] Delete all Digimon.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnEndAttack(hashtable, card);
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card);
+                }
+                
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    List<Permanent> DestroyTargetPermanents = GManager.instance.turnStateMachine.gameContext.Players.Map(player => player.GetBattleAreaDigimons()).Flat();
+                    yield return ContinuousController.instance.StartCoroutine(new DestroyPermanentsClass(DestroyTargetPermanents, CardEffectCommons.CardEffectHashtable(activateClass)).Destroy());
+                }
+            }
+            #endregion
+
+            #region On Deletion
+            if(timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Play guilmon or growlmonname", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[On Deletion] You may play 1 play cost 3 or lower Digimon card with [Guilmon] or [Growlmon] in its name from your trash without paying the cost. For every 10 cards in both players' trashes, add 2 to this effect's play cost maximum.";
+                }
+
+                int Count()
+                {
+                    return (card.Owner.TrashCards.Count + card.Owner.Enemy.TrashCards.Count) / 10;
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOnDeletion(hashtable, card);
+                }
+
+                bool CanSelectCardCondition(CardSource card)
+                {
+                    return card.IsDigimon 
+                        && (card.ContainsCardName("Guilmon") || card.ContainsCardName("Growlmon"))
+                        && card.GetCostItself <= 3 + Count() * 2;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card) && CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanSelectCardCondition);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanSelectCardCondition))
+                    {
+                        int maxCount = Math.Min(1, card.Owner.TrashCards.Count(CanSelectCardCondition));
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        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 play.",
+                                    maxCount: maxCount,
+                                    canEndNotMax: false,
+                                    isShowOpponent: true,
+                                    mode: SelectCardEffect.Mode.Custom,
+                                    root: SelectCardEffect.Root.Trash,
+                                    customRootCardList: null,
+                                    canLookReverseCard: true,
+                                    selectPlayer: card.Owner,
+                                    cardEffect: activateClass);
+
+                        selectCardEffect.SetUpCustomMessage("Select 1 card to play.", "The opponent is selecting 1 card to play.");
+                        selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                        yield return StartCoroutine(selectCardEffect.Activate());
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+
+                            yield return null;
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                                cardSources: selectedCards,
+                                activateClass: activateClass,
+                                payCost: false,
+                                isTapped: false,
+                                root: SelectCardEffect.Root.Trash,
+                                activateETB: true));
+                    }
+                }
+            }
+            #endregion
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_079.cs.meta

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

+ 441 - 0
Assets/CardEffect/BT21/Purple/BT21_088.cs

@@ -0,0 +1,441 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_088 Tagiru
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_088 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Start of main
+            if (timing == EffectTiming.OnStartMainPhase)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Place 1 card under this Tamer from hand to Draw 1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDiscription());
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[Start of Your Main Phase] By placing 1 Digimon card with <Save> in its text or the [Hero] trait from your hand under this Tamer, <Draw 1> and gain 1 memory.";
+                }
+
+                bool CanSelectCardCondition(CardSource cardSource)
+                {
+                    if (cardSource.IsDigimon)
+                    {
+                        if (cardSource.HasSaveText || cardSource.EqualsTraits("Hero"))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (CardEffectCommons.IsOwnerTurn(card))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (card.Owner.HandCards.Count >= 1)
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (card.Owner.HandCards.Some(CanSelectCardCondition))
+                        {
+                            bool placed = false;
+
+                            int maxCount = 1;
+
+                            List<CardSource> selectedCards = new List<CardSource>();
+
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanSelectCardCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: CanEndSelectCondition,
+                                maxCount: maxCount,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to place in Digivolution cards.", "The opponent is selecting 1 card to place in Digivolution cards.");
+                            selectHandEffect.SetNotShowCard();
+
+                            yield return StartCoroutine(selectHandEffect.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)
+                            {
+                                if (!card.PermanentOfThisCard().IsToken)
+                                {
+                                    yield return ContinuousController.instance.StartCoroutine(card.PermanentOfThisCard().AddDigivolutionCardsBottom(selectedCards, activateClass));
+
+                                    placed = true;
+                                }
+                            }
+
+                            if (placed)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(new DrawClass(card.Owner, 1, activateClass).Draw());
+
+                                yield return ContinuousController.instance.StartCoroutine(
+                                            card.Owner.AddMemory(1, activateClass));
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region When you would digivolve
+            if (timing == EffectTiming.BeforePayCost)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Digivolution Cost -1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, true, EffectDiscription());
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[Your Turn] When any of your Digimon would digivolve into a Digimon card with<Save> in its text or the [Hero] trait, by suspending this Tamer and placing 1 card from under your Tamers as any of their bottom digivolution card, reduce the digivolution cost by 1.";
+                }
+
+                bool CanSelectCardCondition(CardSource cardSource)
+                {
+                    return true;
+                }
+
+                bool CanSelectPermanentCondition(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOwnerBattleArea(permanent, card))
+                    {
+                        if (permanent.IsTamer)
+                        {
+                            if (permanent.DigivolutionCards.Count(CanSelectCardCondition) >= 1)
+                            {
+                                return true;
+                            }
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleArea(permanent, card);
+                }
+
+                bool CardCondition(CardSource cardSource)
+                {
+                    if (cardSource.IsDigimon)
+                    {
+                        if (cardSource.HasSaveText || cardSource.EqualsTraits("Hero"))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (CardEffectCommons.IsOwnerTurn(card))
+                        {
+                            if (CardEffectCommons.CanTriggerWhenPermanentWouldDigivolve(hashtable, PermanentCondition, CardCondition))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (CardEffectCommons.CanActivateSuspendCostEffect(card))
+                        {
+                            if (card.Owner.GetBattleAreaPermanents().Count(CanSelectPermanentCondition) >= 1)
+                            {
+                                return true;
+                            }
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    if (card.Owner.GetBattleAreaPermanents().Count(CanSelectPermanentCondition) >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(new SuspendPermanentsClass(new List<Permanent>() { card.PermanentOfThisCard() }, CardEffectCommons.CardEffectHashtable(activateClass)).Tap());
+
+                        Permanent giveDigivolutionCardsTamer = null;
+                        List<CardSource> selectedDigivolutionCards = new List<CardSource>();
+                        Permanent getDigivolutionCardsDigimon = null;
+
+                        int maxCount = 1;
+
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanSelectPermanentCondition,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: maxCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Tamer that has digivolution cards.", "The opponent is selecting 1 Tamer that has digivolution cards.");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            giveDigivolutionCardsTamer = permanent;
+
+                            yield return null;
+                        }
+
+                        if (giveDigivolutionCardsTamer != null)
+                        {
+                            if (giveDigivolutionCardsTamer.DigivolutionCards.Count((cardSource) => CanSelectCardCondition(cardSource)) >= 1)
+                            {
+                                maxCount = 1;
+
+                                SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                                selectCardEffect.SetUp(
+                                            canTargetCondition: CanSelectCardCondition,
+                                            canTargetCondition_ByPreSelecetedList: null,
+                                            canEndSelectCondition: null,
+                                            canNoSelect: () => false,
+                                            selectCardCoroutine: SelectCardCoroutine,
+                                            afterSelectCardCoroutine: null,
+                                            message: "Select 1 digivolution card.",
+                                            maxCount: maxCount,
+                                            canEndNotMax: false,
+                                            isShowOpponent: true,
+                                            mode: SelectCardEffect.Mode.Custom,
+                                            root: SelectCardEffect.Root.Custom,
+                                            customRootCardList: giveDigivolutionCardsTamer.DigivolutionCards,
+                                            canLookReverseCard: true,
+                                            selectPlayer: card.Owner,
+                                            cardEffect: activateClass);
+
+                                selectCardEffect.SetUpCustomMessage("Select 1 digivolution card.", "The opponent is selecting 1 digivolution card.");
+                                selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                                yield return StartCoroutine(selectCardEffect.Activate());
+
+                                IEnumerator SelectCardCoroutine(CardSource cardSource)
+                                {
+                                    selectedDigivolutionCards.Add(cardSource);
+
+                                    yield return null;
+                                }
+
+                                bool CanSelectPermanentCondition1(Permanent permanent)
+                                {
+                                    List<Permanent> Permanents = CardEffectCommons.GetPermanentsFromHashtable(_hashtable);
+
+                                    if (Permanents != null)
+                                    {
+                                        if (Permanents.Contains(permanent))
+                                        {
+                                            if (CardEffectCommons.IsPermanentExistsOnOwnerBattleArea(permanent, card))
+                                            {
+                                                if (!permanent.IsToken)
+                                                {
+                                                    return true;
+                                                }
+                                            }
+                                        }
+                                    }
+
+                                    return false;
+                                }
+
+                                if (card.Owner.GetBattleAreaPermanents().Count(CanSelectPermanentCondition1) >= 1)
+                                {
+                                    maxCount = 1;
+
+                                    selectPermanentEffect.SetUp(
+                                        selectPlayer: card.Owner,
+                                        canTargetCondition: CanSelectPermanentCondition1,
+                                        canTargetCondition_ByPreSelecetedList: null,
+                                        canEndSelectCondition: null,
+                                        maxCount: maxCount,
+                                        canNoSelect: false,
+                                        canEndNotMax: false,
+                                        selectPermanentCoroutine: SelectPermanentCoroutine1,
+                                        afterSelectPermanentCoroutine: null,
+                                        mode: SelectPermanentEffect.Mode.Custom,
+                                        cardEffect: activateClass);
+
+                                    selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will get digivolution cards.", "The opponent is selecting 1 Digimon that will get digivolution cards.");
+
+                                    yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                                    IEnumerator SelectPermanentCoroutine1(Permanent permanent)
+                                    {
+                                        getDigivolutionCardsDigimon = permanent;
+
+                                        yield return null;
+                                    }
+                                }
+
+                                if (getDigivolutionCardsDigimon != null)
+                                {
+                                    if (selectedDigivolutionCards.Count >= 1)
+                                    {
+                                        foreach (CardSource selectedCard in selectedDigivolutionCards)
+                                        {
+                                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().RemoveDigivolveRootEffect(selectedCard, giveDigivolutionCardsTamer));
+                                        }
+
+                                        yield return ContinuousController.instance.StartCoroutine(getDigivolutionCardsDigimon.AddDigivolutionCardsBottom(selectedDigivolutionCards, activateClass));
+
+                                        ContinuousController.instance.PlaySE(GManager.instance.GetComponent<Effects>().BuffSE);
+
+                                        ChangeCostClass changeCostClass = new ChangeCostClass();
+                                        changeCostClass.SetUpICardEffect("Digivolution Cost -1", CanUseCondition1, card);
+                                        changeCostClass.SetUpChangeCostClass(changeCostFunc: ChangeCost, cardSourceCondition: CardSourceCondition, rootCondition: RootCondition, isUpDown: isUpDown, isCheckAvailability: () => false, isChangePayingCost: () => true);
+                                        card.Owner.UntilCalculateFixedCostEffect.Add((_timing) => changeCostClass);
+
+                                        yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.ShowReducedCost(_hashtable));
+
+                                        bool CanUseCondition1(Hashtable hashtable)
+                                        {
+                                            return true;
+                                        }
+
+                                        int ChangeCost(CardSource cardSource, int Cost, SelectCardEffect.Root root, List<Permanent> targetPermanents)
+                                        {
+                                            if (CardSourceCondition(cardSource))
+                                            {
+                                                if (RootCondition(root))
+                                                {
+                                                    if (PermanentsCondition(targetPermanents))
+                                                    {
+                                                        Cost -= 1;
+                                                    }
+                                                }
+                                            }
+
+                                            return Cost;
+                                        }
+
+                                        bool PermanentsCondition(List<Permanent> targetPermanents)
+                                        {
+                                            if (targetPermanents != null)
+                                            {
+                                                if (targetPermanents.Count(PermanentCondition) >= 1)
+                                                {
+                                                    return true;
+                                                }
+                                            }
+
+                                            return false;
+                                        }
+
+                                        bool PermanentCondition(Permanent targetPermanent)
+                                        {
+                                            return CardEffectCommons.IsPermanentExistsOnOwnerBattleArea(targetPermanent, card);
+                                        }
+
+                                        bool CardSourceCondition(CardSource cardSource)
+                                        {
+                                            return cardSource.HasSaveText;
+                                        }
+
+                                        bool RootCondition(SelectCardEffect.Root root)
+                                        {
+                                            return true;
+                                        }
+
+                                        bool isUpDown()
+                                        {
+                                            return true;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region Security
+            if (timing == EffectTiming.SecuritySkill)
+            {
+                cardEffects.Add(CardEffectFactory.PlaySelfTamerSecurityEffect(card));
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_088.cs.meta

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

+ 169 - 0
Assets/CardEffect/BT21/Purple/BT21_089.cs

@@ -0,0 +1,169 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21_089 Takato
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_089 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+
+            #region Start of Main Phase
+            if (timing == EffectTiming.OnStartMainPhase)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Memory +1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, false, EffectDiscription());
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[Start of Your Main Phase] If your opponent has a Digimon, gain 1 memory.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (CardEffectCommons.IsOwnerTurn(card))
+                        {
+                            return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleArea(card))
+                    {
+                        if (card.Owner.Enemy.GetBattleAreaDigimons().Count >= 1)
+                        {
+                            if (card.Owner.CanAddMemory(activateClass))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable _hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(card.Owner.AddMemory(1, activateClass));
+                }
+            }
+            #endregion
+
+            #region All turns
+            if(timing == EffectTiming.OnEnterFieldAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Gain blocker and maybe +2k", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[All Turns] When any of your Digimon are played or digivolve, by suspending this Tamer, until your opponent's turn ends, 1 of your Digimon with [Guilmon], [Growlmon], [Gallantmon], or [Megidramon] in its name or the [Hero] trait gains <Blocker> and, it here are 10 or more total cards in both players' trashes, gets + 2000 DP.";
+                }
+
+                bool MyDigimonPlayedDigid(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card);
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    if (CardEffectCommons.IsExistOnBattleAreaDigimon(card))
+                    {
+                        if (CardEffectCommons.IsOwnerTurn(card))
+                        {
+                            if (CardEffectCommons.CanTriggerOnPermanentPlay(hashtable, MyDigimonPlayedDigid))
+                                return true;
+
+                            if (CardEffectCommons.CanTriggerWhenPermanentDigivolving(hashtable, MyDigimonPlayedDigid))
+                                return true;
+                        }
+                    }
+
+                    return false;
+                }
+
+                bool CanReceiveGainCondtion(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card) && (
+                        permanent.TopCard.ContainsCardName("Guilmon") ||
+                        permanent.TopCard.ContainsCardName("Growlmon") ||
+                        permanent.TopCard.ContainsCardName("Gallantmon") ||
+                        permanent.TopCard.ContainsCardName("Megidramon") ||
+                        permanent.TopCard.EqualsTraits("Hero"));
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return isExistOnField(card) 
+                        && CardEffectCommons.HasMatchConditionOwnersPermanent(card, CanReceiveGainCondtion) 
+                        && CardEffectCommons.CanActivateSuspendCostEffect(card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(new SuspendPermanentsClass(
+                        new List<Permanent>() { card.PermanentOfThisCard() }, CardEffectCommons.CardEffectHashtable(activateClass)).Tap());
+
+
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanReceiveGainCondtion))
+                    {
+                        int maxCount = Math.Min(1, CardEffectCommons.MatchConditionPermanentCount(CanReceiveGainCondtion));
+
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanReceiveGainCondtion,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: maxCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will gain <Blocker> and 2k DP if 10+ cards in trashs.", "The opponent is selecting 1 Digimon that will gain <Blocker> and 2k DP if 10+ cards in trashs.");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainBlocker(targetPermanent: permanent, effectDuration: EffectDuration.UntilOpponentTurnEnd, activateClass: activateClass));
+
+                            if (card.Owner.TrashCards.Count + card.Owner.Enemy.TrashCards.Count >= 10)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.ChangeDigimonDP(permanent, 2000, EffectDuration.UntilOpponentTurnEnd, activateClass));
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region Security
+            if (timing == EffectTiming.SecuritySkill)
+            {
+                cardEffects.Add(CardEffectFactory.PlaySelfTamerSecurityEffect(card));
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_089.cs.meta

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

+ 381 - 0
Assets/CardEffect/BT21/Purple/BT21_099.cs

@@ -0,0 +1,381 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+//BT21_099 Xros Up
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_099 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Main
+            if(timing == EffectTiming.OptionSkill)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("May tuck then may digivolve", CanUseCondition, card);
+                activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[Main] You may place 1 Digimon card with <Save> in its text from your hand or trash under any of your Tamers. Then, 1 of your Digimon may digivolve into a Digimon card with <Save> in its text in the trash.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOptionMainEffect(hashtable, card);
+                }
+
+                bool CanPlaceOrDigivolveTo(CardSource cardSource)
+                {
+                    return cardSource.HasSaveText && cardSource.IsDigimon;
+                }
+
+                bool CanPlaceUnder(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleArea(permanent, card) && permanent.IsTamer;
+                }
+
+                bool CanDigivolveOn(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card))
+                    {
+                        foreach (CardSource cardSource in card.Owner.TrashCards)
+                        {
+                            if (CanPlaceOrDigivolveTo(cardSource))
+                            {
+                                if (cardSource.CanPlayCardTargetFrame(permanent.PermanentFrame, false, activateClass))
+                                {
+                                    return true;
+                                }
+                            }
+                        }
+                    }
+
+                    return false;
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+
+                    #region Tucking
+                    if (CardEffectCommons.HasMatchConditionOwnersPermanent(card, CanPlaceUnder))
+                    {
+                        bool canSelectHand = card.Owner.HandCards.Count(CanPlaceOrDigivolveTo) >= 1;
+                        bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanPlaceOrDigivolveTo);
+
+                        if (canSelectHand || canSelectTrash)
+                        {
+                            if (canSelectHand && canSelectTrash)
+                            {
+                                List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From hand", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                                string selectPlayerMessage = "From which area do you select a card?";
+                                string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
+
+                                GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+                            }
+
+                            else
+                            {
+                                GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                            }
+
+                            yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                            bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                            List<CardSource> selectedCards = new List<CardSource>();
+
+                            IEnumerator SelectCardCoroutine(CardSource cardSource)
+                            {
+                                selectedCards.Add(cardSource);
+
+                                yield return null;
+                            }
+
+                            if (fromHand)
+                            {
+                                int maxCount = 1;
+
+                                SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                                selectHandEffect.SetUp(
+                                    selectPlayer: card.Owner,
+                                    canTargetCondition: CanPlaceOrDigivolveTo,
+                                    canTargetCondition_ByPreSelecetedList: null,
+                                    canEndSelectCondition: null,
+                                    maxCount: maxCount,
+                                    canNoSelect: true,
+                                    canEndNotMax: false,
+                                    isShowOpponent: true,
+                                    selectCardCoroutine: SelectCardCoroutine,
+                                    afterSelectCardCoroutine: null,
+                                    mode: SelectHandEffect.Mode.Custom,
+                                    cardEffect: activateClass);
+
+                                selectHandEffect.SetUpCustomMessage("Select 1 card to place under tamer.", "The opponent is selecting 1 card to place under tamer.");
+                                selectHandEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+
+                                yield return StartCoroutine(selectHandEffect.Activate());
+                            }
+
+                            else
+                            {
+                                int maxCount = 1;
+
+                                SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+                                selectCardEffect.SetUp(
+                                    canTargetCondition: CanPlaceOrDigivolveTo,
+                                    canTargetCondition_ByPreSelecetedList: null,
+                                    canEndSelectCondition: null,
+                                    canNoSelect: () => true,
+                                    selectCardCoroutine: SelectCardCoroutine,
+                                    afterSelectCardCoroutine: null,
+                                    message: "Select 1 card to place under tamer.",
+                                    maxCount: maxCount,
+                                    canEndNotMax: false,
+                                    isShowOpponent: true,
+                                    mode: SelectCardEffect.Mode.Custom,
+                                    root: SelectCardEffect.Root.Trash,
+                                    customRootCardList: null,
+                                    canLookReverseCard: true,
+                                    selectPlayer: card.Owner,
+                                    cardEffect: activateClass);
+
+                                selectCardEffect.SetUpCustomMessage_ShowCard("Digivolution Card");
+                                selectCardEffect.SetUpCustomMessage("Select 1 card to place under tamer.", "The opponent is selecting 1 card to place under tamer.");
+
+                                yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                            }
+
+                            if (selectedCards.Count >= 1)
+                            {
+                                int maxCount = Math.Min(1, CardEffectCommons.MatchConditionOwnersPermanentCount(card, CanPlaceUnder));
+
+                                SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                                selectPermanentEffect.SetUp(
+                                    selectPlayer: card.Owner,
+                                    canTargetCondition: CanPlaceUnder,
+                                    canTargetCondition_ByPreSelecetedList: null,
+                                    canEndSelectCondition: null,
+                                    maxCount: maxCount,
+                                    canNoSelect: true,
+                                    canEndNotMax: false,
+                                    selectPermanentCoroutine: SelectPermanentCoroutine,
+                                    afterSelectPermanentCoroutine: null,
+                                    mode: SelectPermanentEffect.Mode.Custom,
+                                    cardEffect: activateClass);
+
+                                selectPermanentEffect.SetUpCustomMessage("Select 1 Tamer to place the card under.", "The opponent is selecting 1 Tamer to place the card under.");
+
+                                yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                                IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                                {
+                                    Permanent selectedPermanent = permanent;
+
+                                    if (selectedPermanent != null)
+                                    {
+                                        yield return ContinuousController.instance.StartCoroutine(selectedPermanent.AddDigivolutionCardsBottom(new List<CardSource>() { selectedCards[0] }, activateClass));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    #endregion
+
+                    #region Digivolving
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanDigivolveOn))
+                    {
+                        Permanent selectedPermanent = null;
+
+                        int maxCount = Math.Min(1, CardEffectCommons.MatchConditionPermanentCount(CanDigivolveOn));
+
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanDigivolveOn,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: maxCount,
+                            canNoSelect: true,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will digivolve.",
+                            "The opponent is selecting 1 Digimon that will digivolve.");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            selectedPermanent = permanent;
+
+                            yield return null;
+                        }
+
+                        if (selectedPermanent != null)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.DigivolveIntoHandOrTrashCard(
+                                targetPermanent: selectedPermanent,
+                                cardCondition: CanPlaceOrDigivolveTo,
+                                payCost: true,
+                                reduceCostTuple: null,
+                                fixedCostTuple: null,
+                                ignoreDigivolutionRequirementFixedCost: -1,
+                                isHand: false,
+                                activateClass: activateClass,
+                                successProcess: null));
+                        }
+                    }
+                    #endregion
+                }
+            }
+            #endregion  
+
+            #region Security
+            if (timing == EffectTiming.SecuritySkill)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect($"Play a <Save> card from hand or trash.", CanUseCondition, card);
+                activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, false, EffectDiscription());
+                activateClass.SetIsSecurityEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[Security] You may play 1 card with <Save> in its text and a play cost of 5 or less from your hand or trash without paying the cost. Then, add this card to the hand.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerSecurityEffect(hashtable, card);
+                }
+
+                bool CanSelectCardCondition(CardSource cardSource)
+                {
+                    return cardSource.HasSaveText &&
+                           cardSource.HasPlayCost && cardSource.GetCostItself <= 5 &&
+                           CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    bool canSelectHand = CardEffectCommons.HasMatchConditionOwnersHand(card, CanSelectCardCondition);
+                    bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanSelectCardCondition);
+
+                    if (canSelectHand || canSelectTrash)
+                    {
+                        if (canSelectHand && canSelectTrash)
+                        {
+                            List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>
+                            {
+                                new(message: "From hand", value: true, spriteIndex: 0),
+                                new(message: "From trash", value: false, spriteIndex: 1),
+                            };
+
+                            string selectPlayerMessage = "From which area do you play a card?";
+                            string notSelectPlayerMessage = "The opponent is choosing from which area to play a card.";
+
+                            GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements,
+                                selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage,
+                                notSelectPlayerMessage: notSelectPlayerMessage);
+                        }
+
+                        else
+                        {
+                            GManager.instance.userSelectionManager.SetBool(canSelectHand);
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager
+                            .WaitForEndSelect());
+
+                        bool fromHand = GManager.instance.userSelectionManager.SelectedBoolValue;
+
+                        List<CardSource> selectedCards = new List<CardSource>();
+
+                        IEnumerator SelectCardCoroutine(CardSource cardSource)
+                        {
+                            selectedCards.Add(cardSource);
+                            yield return null;
+                        }
+
+                        if (fromHand)
+                        {
+                            SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                            selectHandEffect.SetUp(
+                                selectPlayer: card.Owner,
+                                canTargetCondition: CanSelectCardCondition,
+                                canTargetCondition_ByPreSelecetedList: null,
+                                canEndSelectCondition: null,
+                                maxCount: 1,
+                                canNoSelect: true,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                selectCardCoroutine: SelectCardCoroutine,
+                                afterSelectCardCoroutine: null,
+                                mode: SelectHandEffect.Mode.Custom,
+                                cardEffect: activateClass);
+
+                            selectHandEffect.SetUpCustomMessage("Select 1 card to play.", "The opponent is selecting 1 card to play.");
+                            selectHandEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                            yield return StartCoroutine(selectHandEffect.Activate());
+                        }
+
+                        else
+                        {
+                            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 play.",
+                                maxCount: 1,
+                                canEndNotMax: false,
+                                isShowOpponent: true,
+                                mode: SelectCardEffect.Mode.Custom,
+                                root: SelectCardEffect.Root.Trash,
+                                customRootCardList: null,
+                                canLookReverseCard: true,
+                                selectPlayer: card.Owner,
+                                cardEffect: activateClass);
+
+                            selectCardEffect.SetUpCustomMessage("Select 1 card to play.", "The opponent is selecting 1 card to play.");
+                            selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
+
+                            yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
+                        }
+
+                        yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
+                            cardSources: selectedCards, activateClass: activateClass, payCost: false, isTapped: false,
+                            root: fromHand ? SelectCardEffect.Root.Hand : SelectCardEffect.Root.Trash, activateETB: true));
+                    }
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.AddThisCardToHand(card, activateClass));
+                }
+            }
+            #endregion
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_099.cs.meta

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

+ 243 - 0
Assets/CardEffect/BT21/Purple/BT21_100.cs

@@ -0,0 +1,243 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+//BT21_100 The Digimon I Designed
+namespace DCGO.CardEffects.BT21
+{
+    public class BT21_100 : CEntity_Effect
+    {
+        public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
+        {
+            List<ICardEffect> cardEffects = new List<ICardEffect>();
+
+            #region Ignore Color Requirements
+            if (timing == EffectTiming.None)
+            {
+                IgnoreColorConditionClass ignoreColorConditionClass = new IgnoreColorConditionClass();
+                ignoreColorConditionClass.SetUpICardEffect("Ignore color requirements", CanUseCondition, card);
+                ignoreColorConditionClass.SetUpIgnoreColorConditionClass(cardCondition: CardCondition);
+                cardEffects.Add(ignoreColorConditionClass);
+
+                bool IgnoreColorConditions(Permanent permanent)
+                {
+                    return permanent.TopCard.EqualsCardName("Takato Matsuki");
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.HasMatchConditionOwnersPermanent(card, IgnoreColorConditions);
+                }
+
+                bool CardCondition(CardSource cardSource)
+                {
+                    return cardSource == card;
+                }
+            }
+            #endregion
+
+
+            #region Main
+            if (timing == EffectTiming.OptionSkill)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Draw 1 trash 1", CanUseCondition, card);
+                activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, false, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[Main] <Draw 1> and trash 1 card in your hand. Then, place this card in the battle area.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerOptionMainEffect(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(new DrawClass(card.Owner, 1, activateClass).Draw());
+
+                    if (card.Owner.HandCards.Count >= 1)
+                    {
+                        int discardCount = Math.Min(1, card.Owner.HandCards.Count);
+
+                        SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
+
+                        selectHandEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: (cardSource) => true,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: discardCount,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            isShowOpponent: true,
+                            selectCardCoroutine: null,
+                            afterSelectCardCoroutine: null,
+                            mode: SelectHandEffect.Mode.Discard,
+                            cardEffect: activateClass);
+
+                        yield return StartCoroutine(selectHandEffect.Activate());
+                    }
+                    yield return ContinuousController.instance.StartCoroutine(
+                        CardEffectCommons.PlaceDelayOptionCards(card: card, cardEffect: activateClass));
+                }
+
+            }
+            #endregion
+
+            #region Delay
+            if(timing == EffectTiming.OnDestroyedAnyone)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Digivolve to Gallant line when deletion happens", CanUseCondition, card);
+                activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, true, EffectDescription());
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return "[Your Turn] When effects delete Digimon, <Delay>.\r\n• 1 of your Digimon with [Guilmon] or [Growlmon] in its name may digivolve into a Digimon card with [Growlmon], [Gallantmon] or [Megidramon] in its name in the trash without paying the cost.";
+                }
+
+                bool TriggerPermanentCondition(Permanent permanent)
+                {
+                    return permanent.IsDigimon;
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanDeclareOptionDelayEffect(card) &&
+                           CardEffectCommons.CanTriggerOnPermanentDeleted(hashtable, TriggerPermanentCondition) &&
+                           CardEffectCommons.IsByEffect(hashtable, null);
+                }
+
+                bool CanSelectPermanentCondition(Permanent permanent)
+                {
+                    if (CardEffectCommons.IsPermanentExistsOnOwnerBattleArea(permanent, card))
+                    {
+                        if (permanent.TopCard.ContainsCardName("Guilmon") || permanent.TopCard.ContainsCardName("Growlmon"))
+                        {
+                            foreach (CardSource cardSource in card.Owner.HandCards)
+                            {
+                                if (CanSelectCardCondition(cardSource))
+                                {
+                                    if (cardSource.CanPlayCardTargetFrame(permanent.PermanentFrame, false, activateClass))
+                                    {
+                                        return true;
+                                    }
+                                }
+                            }
+                        }
+                        
+                    }
+
+                    return false;
+                }
+
+                bool CanSelectCardCondition(CardSource cardSource)
+                {
+                    return cardSource.ContainsCardName("Growlmon") ||
+                        cardSource.ContainsCardName("Gallantmon") ||
+                        cardSource.ContainsCardName("Megidramon");
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(
+                        CardEffectCommons.DeletePeremanentAndProcessAccordingToResult(
+                            targetPermanents: new List<Permanent>() { card.PermanentOfThisCard() },
+                            activateClass: activateClass, successProcess: _ => SuccessProcess(),
+                            failureProcess: null));
+                }
+
+                IEnumerator SuccessProcess()
+                {
+
+                    if (CardEffectCommons.HasMatchConditionPermanent(CanSelectPermanentCondition))
+                    {
+                        Permanent selectedPermanent = null;
+
+                        int maxCount = Math.Min(1, CardEffectCommons.MatchConditionPermanentCount(CanSelectPermanentCondition));
+
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: CanSelectPermanentCondition,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: maxCount,
+                            canNoSelect: true,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: SelectPermanentCoroutine,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.Custom,
+                            cardEffect: activateClass);
+
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will digivolve.",
+                            "The opponent is selecting 1 Digimon that will digivolve.");
+
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+
+                        IEnumerator SelectPermanentCoroutine(Permanent permanent)
+                        {
+                            selectedPermanent = permanent;
+
+                            yield return null;
+                        }
+
+                        if (selectedPermanent != null)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.DigivolveIntoHandOrTrashCard(
+                                targetPermanent: selectedPermanent,
+                                cardCondition: CanSelectCardCondition,
+                                payCost: false,
+                                reduceCostTuple: null,
+                                fixedCostTuple: null,
+                                ignoreDigivolutionRequirementFixedCost: -1,
+                                isHand: false,
+                                activateClass: activateClass,
+                                successProcess: null));
+                        }
+                    }
+                }
+
+            }
+            #endregion
+
+            #region Security
+            if (timing == EffectTiming.SecuritySkill)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("Gain 1 memory", CanUseCondition, card);
+                activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, false, EffectDescription());
+                activateClass.SetIsSecurityEffect(true);
+                cardEffects.Add(activateClass);
+
+                string EffectDescription()
+                {
+                    return
+                        "[Security] Gain 1 memory. Then, place this card in the battle area.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.CanTriggerSecurityEffect(hashtable, card);
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    yield return ContinuousController.instance.StartCoroutine(
+                                            card.Owner.AddMemory(1, activateClass));
+                    yield return ContinuousController.instance.StartCoroutine(
+                        CardEffectCommons.PlaceDelayOptionCards(card: card, cardEffect: activateClass));
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 11 - 0
Assets/CardEffect/BT21/Purple/BT21_100.cs.meta

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