瀏覽代碼

Implement ST23-05 and SelectPermanentEffect.Mode.PutSecurity methods

hooperk 4 月之前
父節點
當前提交
51e231230a

+ 198 - 0
Assets/Scripts/CardEffect/ST23/Yellow/ST23_05.cs

@@ -0,0 +1,198 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+// Gekkomon
+namespace DCGO.CardEffects.ST23
+{
+    public class ST23_05 : 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.EqualsTraits("Glowing Dawn");
+                }
+
+                cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(level: 5, permanentCondition: PermanentCondition, digivolutionCost: 3, ignoreDigivolutionRequirement: false, card: card, condition: null));
+            }
+            #endregion
+
+            #region shared WD / WA
+
+            string SharedHashString = "ST23-05_WD_WA";
+
+            string SharedEffectName = "Place 1 opponent's lowest DP Digimon on top of security. Then may trash top security from the player with most security to Recover +1";
+
+            string SharedEffectDescription(string tag) => $"[{tag}] [Once Per Turn] Place 1 of your opponent's lowest DP Digimon as the top security card. Then, by trashing the top security card of 1 player with the most security cards, <Recovery +1>.";
+
+            CardEffectFactory.ActivateClassesForSharedEffects(ref cardEffects, timing, card,
+                                                              SharedEffectName,
+                                                              SharedActivateCoroutine,
+                                                              SharedEffectDescription,
+                                                              false,
+                                                              isOptionalFunction: IsOptional,
+                                                              maxCountPerTurn: 1,
+                                                              hashValue: SharedHashString,
+                                                              whenDigivolving: true,
+                                                              whenAttacking: true
+                                                              );
+
+            bool IsOptional(Hashtable hashtable) => !CardEffectCommons.HasMatchConditionPermanent(IsWeakestEnemyDigimon);
+
+            bool IsWeakestEnemyDigimon(Permanent permanent) => CardEffectCommons.IsMinDP(permanent, card.Owner.Enemy);
+
+            IEnumerator SharedActivateCoroutine(Hashtable hashtable, ActivateClass activateClass)
+            {
+                if (card.Owner.CanAddSecurity(activateClass))
+                {
+                    int validTargets = CardEffectCommons.MatchConditionOpponentsPermanentCount(card, IsWeakestEnemyDigimon);
+                    if (validTargets == 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(new IPutSecurityPermanent(
+                                card.Owner.Enemy.GetBattleAreaDigimons().Filter(IsWeakestEnemyDigimon).FirstOrDefault(), 
+                                CardEffectCommons.CardEffectHashtable(activateClass), true, false).PutSecurity());
+                    }
+                    else if (validTargets > 1)
+                    {
+                        SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
+    
+                        selectPermanentEffect.SetUp(
+                            selectPlayer: card.Owner,
+                            canTargetCondition: IsWeakestEnemyDigimon,
+                            canTargetCondition_ByPreSelecetedList: null,
+                            canEndSelectCondition: null,
+                            maxCount: 1,
+                            canNoSelect: false,
+                            canEndNotMax: false,
+                            selectPermanentCoroutine: null,
+                            afterSelectPermanentCoroutine: null,
+                            mode: SelectPermanentEffect.Mode.PutSecurityTop,
+                            cardEffect: activateClass);
+    
+                        selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to place in security.", "The opponent is selecting 1 Digimon to place in security.");
+    
+                        yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
+                    }
+                }
+                bool validOwnerSecurity = card.Owner.SecurityCards.Count > 0 && card.Owner.SecurityCards.Count >= card.Owner.Enemy.SecurityCards.Count;
+                bool validEnemySecurity = card.Owner.Enemy.SecurityCards.Count > 0 && card.Owner.Enemy.SecurityCards.Count >= card.Owner.SecurityCards.Count;
+
+                if (validOwnerSecurity || validEnemySecurity)
+                {
+                    List<SelectionElement<int>> selectionElements = new List<SelectionElement<int>>();
+                    if (validOwnerSecurity)
+                    {
+                        selectionElements.Add(new (message: $"Trash your own top security card", value : 1, spriteIndex: 0));
+                    }
+                    if (validEnemySecurity)
+                    {
+                        selectionElements.Add(new (message: $"Trash your opponent's top security card", value : 2, spriteIndex: 0));
+                    }
+                    selectionElements.Add( new (message: $"Don't trash security", value: 3, spriteIndex: 1));
+
+                    string selectPlayerMessage = "Will you trash 1 player's security to <Recover +1>?";
+                    string notSelectPlayerMessage = "The opponent is choosing if they will trash a security.";
+
+                    GManager.instance.userSelectionManager.SetIntSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
+
+                    bool doTrash = GManager.instance.userSelectionManager.SelectedIntValue != 3;
+                    bool ownSecurity = GManager.instance.userSelectionManager.SelectedIntValue == 1;
+                    if (doTrash)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.TrashSecurityAndProcessAccordingToResult(
+                            player: ownSecurity ? card.Owner : card.Owner.Enemy,
+                            trashAmount: 1,
+                            activateClass: activateClass,
+                            fromTop: true,
+                            successProcess: SuccessProcess,
+                            failureProcess: null
+                        ));
+
+                        IEnumerator SuccessProcess(List<CardSource> cardSources)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(new IRecovery(card.Owner, 1, activateClass).Recovery());
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            #region All Turns Protect Glowing Dawn
+            if (timing == EffectTiming.WhenRemoveField)
+            {
+                ActivateClass activateClass = new ActivateClass();
+                activateClass.SetUpICardEffect("By trashing top security, card doesn't leave", CanUseCondition, card);
+                activateClass.SetUpActivateClass(CanActivateCondition, ActivateCoroutine, 1, true, EffectDiscription());
+                activateClass.SetHashString("ST23_15_AT_Protect");
+                cardEffects.Add(activateClass);
+
+                string EffectDiscription()
+                {
+                    return "[All Turns] [Once Per Turn] When any of your [Glowing Dawn] trait Digimon would leave the battle area, by trashing your top security card, they don't leave.";
+                }
+
+                bool CanUseCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleArea(card)
+                        && CardEffectCommons.CanTriggerWhenPermanentRemoveField(hashtable, PermanentCondition);
+                        
+                }
+
+                bool CanActivateCondition(Hashtable hashtable)
+                {
+                    return CardEffectCommons.IsExistOnBattleAreaDigimon(card)
+                        && card.Owner.SecurityCards.Count > 0;
+                }
+
+                bool PermanentCondition(Permanent permanent)
+                {
+                    return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card)
+                        && permanent.TopCard.EqualsTraits("Glowing Dawn");
+                }
+
+                IEnumerator ActivateCoroutine(Hashtable hashtable)
+                {
+                    CardSource secCard = card.Owner.SecurityCards[0];
+
+                    yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.TrashSecurityAndProcessAccordingToResult(
+                        player: card.Owner,
+                        trashAmount: 1,
+                        activateClass: activateClass,
+                        fromTop: true,
+                        successProcess: SuccessProcess,
+                        failureProcess: null
+                    ));
+
+                    IEnumerator SuccessProcess(List<CardSource> cardSources)
+                    {
+                        List<Permanent> protectedPermanents = CardEffectCommons.GetPermanentsFromHashtable(hashtable)
+                                    .Filter(PermanentCondition);
+
+                        foreach (Permanent permanent in protectedPermanents)
+                        {
+                            permanent.willBeRemoveField = false;
+                            permanent.HideDeleteEffect();
+                            permanent.HideHandBounceEffect();
+                            permanent.HideDeckBounceEffect();
+                            permanent.HideWillRemoveFieldEffect();
+                        }
+
+                        yield return null;
+                    }
+                }
+            }
+            #endregion
+
+            return cardEffects;
+        }
+    }
+}

+ 55 - 32
Assets/Scripts/Script/CardEffectFactory.cs

@@ -825,6 +825,7 @@ public partial class CardEffectFactory
                                                                     bool optional,
                                                                     Func<Hashtable, bool> additionalUseCondition = null,
                                                                     Func<Hashtable, bool> additionalActivateCondition = null, 
+                                                                    Func<Hashtable, bool> isOptionalFunction = null,
                                                                     int maxCountPerTurn = -1,
                                                                     string hashValue = null,
                                                                     bool whenMoving = false,
@@ -842,51 +843,51 @@ public partial class CardEffectFactory
     {
         if (whenMoving && timing == EffectTiming.OnMove)
         {
-            cardEffects.Add(WhenMovingClass(card, effectName, activateCoroutine, effectDescription("When Moving"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(WhenMovingClass(card, effectName, activateCoroutine, effectDescription("When Moving"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (onPlay && timing == EffectTiming.OnEnterFieldAnyone)
         {
-            cardEffects.Add(OnPlayClass(card, effectName, activateCoroutine, effectDescription("On Play"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(OnPlayClass(card, effectName, activateCoroutine, effectDescription("On Play"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (whenDigivolving && timing == EffectTiming.OnEnterFieldAnyone)
         {
-            cardEffects.Add(WhenDigivolvingClass(card, effectName, activateCoroutine, effectDescription("When Digivolving"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(WhenDigivolvingClass(card, effectName, activateCoroutine, effectDescription("When Digivolving"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (whenAttacking && timing == EffectTiming.OnAllyAttack)
         {
-            cardEffects.Add(WhenAttackingClass(card, effectName, activateCoroutine, effectDescription("When Attacking"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(WhenAttackingClass(card, effectName, activateCoroutine, effectDescription("When Attacking"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (onDeletion && timing == EffectTiming.OnDestroyedAnyone)
         {
-            cardEffects.Add(OnDeletionClass(card, effectName, activateCoroutine, effectDescription("On Deletion"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(OnDeletionClass(card, effectName, activateCoroutine, effectDescription("On Deletion"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (whenLinking && timing == EffectTiming.WhenLinked)
         {
-            cardEffects.Add(WhenLinkingClass(card, effectName, activateCoroutine, effectDescription("When Linking"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(WhenLinkingClass(card, effectName, activateCoroutine, effectDescription("When Linking"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (endOfAttack && timing == EffectTiming.OnEndAttack)
         {
-            cardEffects.Add(EndOfAttackClass(card, effectName, activateCoroutine, effectDescription("End of Attack"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(EndOfAttackClass(card, effectName, activateCoroutine, effectDescription("End of Attack"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (endOfYourTurn && timing == EffectTiming.OnEndTurn)
         {
-            cardEffects.Add(EndOfYourTurnClass(card, effectName, activateCoroutine, effectDescription("End of Your Turn"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(EndOfYourTurnClass(card, effectName, activateCoroutine, effectDescription("End of Your Turn"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (endOfOpponentTurn && timing == EffectTiming.OnEndTurn)
         {
-            cardEffects.Add(EndOfYourOpponentsTurnClass(card, effectName, activateCoroutine, effectDescription("End of Opponent's Turn"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(EndOfYourOpponentsTurnClass(card, effectName, activateCoroutine, effectDescription("End of Opponent's Turn"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (endOfAllTurns && timing == EffectTiming.OnEndTurn)
         {
-            cardEffects.Add(EndOfAllTurnsClass(card, effectName, activateCoroutine, effectDescription("End of All Turns"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(EndOfAllTurnsClass(card, effectName, activateCoroutine, effectDescription("End of All Turns"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if(startOfYourMainPhase && timing == EffectTiming.OnStartMainPhase)
         {
-            cardEffects.Add(StartOfYourMainPhaseClass(card, effectName, activateCoroutine, effectDescription("Start of Your Main Phase"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(StartOfYourMainPhaseClass(card, effectName, activateCoroutine, effectDescription("Start of Your Main Phase"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
         if (counter && timing == EffectTiming.OnCounterTiming)
         {
-            cardEffects.Add(CounterClass(card, effectName, activateCoroutine, effectDescription("Counter"), optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
+            cardEffects.Add(CounterClass(card, effectName, activateCoroutine, effectDescription("Counter"), optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue));
         }
 
         return cardEffects;
@@ -903,6 +904,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 int maxCountPerTurn = -1,
                                                 string hashValue = null,
                                                 bool isInheritedEffect = false,
@@ -915,6 +917,7 @@ public partial class CardEffectFactory
         activateClass.SetUpActivateClass(canActivateCondition, hashtable => activateCoroutine(hashtable, activateClass), maxCountPerTurn, optional, effectDescription);
         activateClass.SetHashString(hashValue);
         activateClass.SetIsSecurityEffect(isSecurityEffect);
+        activateClass.SetIsOptionalOverride(isOptionalFunction);
         return activateClass;
     }
 
@@ -927,13 +930,14 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
                                                 string hashValue = null,
                                                 bool isInherited = false)
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, false);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, false);
 
         bool PermanentCondition(Permanent permanent)
         {
@@ -963,13 +967,14 @@ public partial class CardEffectFactory
                                             Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                             string effectDescription,
                                             bool optional,
+                                            Func<Hashtable, bool> isOptionalFunction = null,
                                             Func<Hashtable, bool> additionalUseCondition = null,
                                             Func<Hashtable, bool> additionalActivateCondition = null,
                                             int maxCountPerTurn = -1,
                                             string hashValue = null,
                                             bool isInherited = false)
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, false);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, false);
 
         bool CanUseCondition(Hashtable hashtable)
         {
@@ -994,6 +999,7 @@ public partial class CardEffectFactory
                                                         Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                         string effectDescription,
                                                         bool optional,
+                                                        Func<Hashtable, bool> isOptionalFunction = null,
                                                         Func<Hashtable, bool> additionalUseCondition = null,
                                                         Func<Hashtable, bool> additionalActivateCondition = null,
                                                         int maxCountPerTurn = -1,
@@ -1001,7 +1007,7 @@ public partial class CardEffectFactory
                                                         bool isInherited = false,
                                                         bool isLinked = false)
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, isLinked);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, isLinked);
 
         bool CanUseCondition(Hashtable hashtable)
         {
@@ -1025,6 +1031,7 @@ public partial class CardEffectFactory
                                                     Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                     string effectDescription,
                                                     bool optional,
+                                                    Func<Hashtable, bool> isOptionalFunction = null,
                                                     Func<Hashtable, bool> additionalUseCondition = null,
                                                     Func<Hashtable, bool> additionalActivateCondition = null,
                                                     int maxCountPerTurn = -1,
@@ -1032,7 +1039,7 @@ public partial class CardEffectFactory
                                                     bool isInherited = false,
                                                     bool isLinked = false)
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, isLinked);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, isLinked);
 
         bool CanUseCondition(Hashtable hashtable)
         {
@@ -1057,6 +1064,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1064,7 +1072,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, isLinked);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, isLinked);
 
         bool CanUseCondition(Hashtable hashtable)
         {
@@ -1089,6 +1097,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1097,7 +1106,7 @@ public partial class CardEffectFactory
                                                 bool isLinked = false
                                                 )
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, isLinked);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, isLinked);
 
         bool CanUseCondition(Hashtable hashtable)
         {
@@ -1122,10 +1131,11 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null)
     {
-        ActivateClass activateClass = ActivateClass(card, effectName, CanUseCondition, additionalActivateCondition, activateCoroutine, effectDescription, optional, -1, null, false, false);
+        ActivateClass activateClass = ActivateClass(card, effectName, CanUseCondition, additionalActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, -1, null, false, false);
         activateClass.SetIsSecurityEffect(true);
         return activateClass;
 
@@ -1145,6 +1155,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1152,7 +1163,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, isLinked);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, isLinked);
 
         bool CanUseCondition(Hashtable hashtable)
         {
@@ -1179,6 +1190,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1186,7 +1198,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        ActivateClass activateClass = ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, isLinked);
+        ActivateClass activateClass = ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, isLinked);
         activateClass.SetIsCounterEffect(true);
         return activateClass;
 
@@ -1219,6 +1231,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1228,7 +1241,7 @@ public partial class CardEffectFactory
                                                 bool yourTurn = false,
                                                 bool opponentTurn = false)
     {
-        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, maxCountPerTurn, hashValue, isInherited, isLinked);
+        return ActivateClass(card, effectName, CanUseCondition, CanActivateCondition, activateCoroutine, effectDescription, optional, isOptionalFunction, maxCountPerTurn, hashValue, isInherited, isLinked);
 
         bool CanUseCondition(Hashtable hashtable)
         {
@@ -1255,6 +1268,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1262,7 +1276,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
     }
 
     public static ActivateClass StartOfYourMainPhaseClass(CardSource card,
@@ -1270,6 +1284,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1277,7 +1292,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
     }
 
     public static ActivateClass EndOfYourTurnClass(CardSource card,
@@ -1285,6 +1300,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1292,7 +1308,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
     }
 
     public static ActivateClass YourTurnClass(CardSource card,
@@ -1300,6 +1316,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1307,7 +1324,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, false);
     }
 
     #endregion
@@ -1319,6 +1336,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1326,7 +1344,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
     }
 
     public static ActivateClass StartOfYourOpponentsMainPhaseClass(CardSource card,
@@ -1334,6 +1352,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1341,7 +1360,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
     }
 
     public static ActivateClass EndOfYourOpponentsTurnClass(CardSource card,
@@ -1349,6 +1368,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1356,7 +1376,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
     }
 
     public static ActivateClass OpponentsTurnClass(CardSource card,
@@ -1364,6 +1384,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1371,7 +1392,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, false, true);
     }
 
     #endregion
@@ -1383,6 +1404,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1390,7 +1412,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, true);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, true);
     }
 
     public static ActivateClass AllTurnsClass(CardSource card,
@@ -1398,6 +1420,7 @@ public partial class CardEffectFactory
                                                 Func<Hashtable, ActivateClass, IEnumerator> activateCoroutine,
                                                 string effectDescription,
                                                 bool optional,
+                                                Func<Hashtable, bool> isOptionalFunction = null,
                                                 Func<Hashtable, bool> additionalUseCondition = null,
                                                 Func<Hashtable, bool> additionalActivateCondition = null,
                                                 int maxCountPerTurn = -1,
@@ -1405,7 +1428,7 @@ public partial class CardEffectFactory
                                                 bool isInherited = false,
                                                 bool isLinked = false)
     {
-        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, true);
+        return TurnTimingClass(card, effectName, activateCoroutine, effectDescription, optional, isOptionalFunction, additionalUseCondition, additionalActivateCondition, maxCountPerTurn, hashValue, isInherited, isLinked, true, true);
     }
 
     #endregion

+ 49 - 0
Assets/Scripts/Script/SelectPermanentEffect.cs

@@ -89,6 +89,11 @@ public class SelectPermanentEffect : MonoBehaviourPunCallbacks
         _defenderCondition = defenderCondition;
     }
 
+    public void SetPlaceFaceUp()
+    {
+        _isFaceUp = true;
+    }
+
     //Player to select
     Player _selectPlayer = null;
     //Conditions of units that can be selected
@@ -116,6 +121,7 @@ public class SelectPermanentEffect : MonoBehaviourPunCallbacks
     int _degenerationCount = 1;
     bool _canAttackPlayer = true;
     Func<Permanent, bool> _defenderCondition = (permanent) => true;
+    bool _isFaceUp = false;
 
     public enum Mode
     {
@@ -125,6 +131,8 @@ public class SelectPermanentEffect : MonoBehaviourPunCallbacks
         Bounce,
         PutLibraryBottom,
         PutLibraryTop,
+        PutSecurityBottom,
+        PutSecurityTop,
         Degenerate,
         Attack,
         Custom
@@ -244,6 +252,8 @@ public class SelectPermanentEffect : MonoBehaviourPunCallbacks
         List<Permanent> untapPermanents = new List<Permanent>();
         List<Permanent> libraryBottomPermanents = new List<Permanent>();
         List<Permanent> libraryTopPermanents = new List<Permanent>();
+        List<Permanent> securityBottomPermanents = new List<Permanent>();
+        List<Permanent> securityTopPermanents = new List<Permanent>();
         List<Permanent> handBouncePermanents = new List<Permanent>();
         List<Permanent> degeneratePermanents = new List<Permanent>();
         List<Permanent> attackPermanents = new List<Permanent>();
@@ -327,6 +337,14 @@ public class SelectPermanentEffect : MonoBehaviourPunCallbacks
                             message = "Select cards to put on top of the deck.";
                             break;
 
+                        case Mode.PutSecurityBottom:
+                            message = "Select cards to put on bottom of security.";
+                            break;
+
+                        case Mode.PutSecurityTop:
+                            message = "Select cards to put on top of security.";
+                            break;
+
                         case Mode.Degenerate:
                             message = $"Select cards to De-Digivolve {_degenerationCount}.";
                             break;
@@ -863,6 +881,15 @@ public class SelectPermanentEffect : MonoBehaviourPunCallbacks
                                 libraryTopPermanents.Add(targetPermanent);
                                 break;
 
+                            case Mode.PutSecurityBottom:
+
+                                securityBottomPermanents.Add(targetPermanent);
+                                break;
+
+                            case Mode.PutSecurityTop:
+                                securityTopPermanents.Add(targetPermanent);
+                                break;
+
                             case Mode.Degenerate:
                                 degeneratePermanents.Add(targetPermanent);
                                 break;
@@ -919,6 +946,28 @@ public class SelectPermanentEffect : MonoBehaviourPunCallbacks
                         yield return ContinuousController.instance.StartCoroutine(new DeckTopBounceClass(libraryTopPermanents, hashtable).DeckBounce());
                     }
 
+                    if (securityBottomPermanents.Count > 0)
+                    {
+                        if (_cardEffect.EffectSourceCard.Owner.CanAddSecurity(_cardEffect))
+                        {
+                            foreach (Permanent targetPermanent in securityBottomPermanents)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(new IPutSecurityPermanent(targetPermanent, CardEffectCommons.CardEffectHashtable(_cardEffect), false, _isFaceUp).PutSecurity());
+                            }
+                        }
+                    }
+
+                    if (securityTopPermanents.Count > 0)
+                    {
+                        if (_cardEffect.EffectSourceCard.Owner.CanAddSecurity(_cardEffect))
+                        {
+                            foreach (Permanent targetPermanent in securityTopPermanents)
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(new IPutSecurityPermanent(targetPermanent, CardEffectCommons.CardEffectHashtable(_cardEffect), true, _isFaceUp).PutSecurity());
+                            }
+                        }
+                    }
+
                     if (handBouncePermanents.Count > 0)
                     {
                         yield return ContinuousController.instance.StartCoroutine(new HandBounceClaass(handBouncePermanents, hashtable).Bounce());