فهرست منبع

Adding Assembly

mbunch_kascope 1 سال پیش
والد
کامیت
e52740ecf1

+ 22 - 1
Assets/Scripts/CardController.cs

@@ -276,7 +276,6 @@ public class PlayCardClass
     {
         if (_appFusionFrameIDs != null && _appFusionFrameIDs.Length == 2)
         {
-            UnityEngine.Debug.Log($"GETTING LINKED CARD: {_appFusionFrameIDs[0]}, {_appFusionFrameIDs[1]}");
             if (0 <= _appFusionFrameIDs[0] && _appFusionFrameIDs[0] <= card.Owner.fieldCardFrames.Count - 1)
             {
                 Permanent targetPermanent = card.Owner.fieldCardFrames[_appFusionFrameIDs[0]].GetFramePermanent();
@@ -303,6 +302,7 @@ public class PlayCardClass
         foreach (CardSource card in CardSources)
         {
             GManager.instance.GetComponent<SelectDigiXrosClass>().ResetSelectDigiXrosClass();
+            GManager.instance.GetComponent<SelectAssemblyClass>().ResetSelectAssemblyClass();
 
             if (card == null)
             {
@@ -727,6 +727,13 @@ public class PlayCardClass
             }
             #endregion
 
+            #region select Assembly
+            if (card.HasAssembly && !isEvolution)
+            {
+                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<SelectAssemblyClass>().Select(card));
+            }
+            #endregion
+
             #region Bounce Tamer of Burst digivolution
 
             if (IsBurst(card))
@@ -868,6 +875,8 @@ public class PlayCardClass
 
                 GManager.instance.GetComponent<SelectDigiXrosClass>().ResetSelectDigiXrosClass();
 
+                GManager.instance.GetComponent<SelectAssemblyClass>().ResetSelectAssemblyClass();
+
                 yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().FailedPlayCardEffect(card));
 
                 if (card.Owner.HandCards.Contains(card))
@@ -1137,6 +1146,7 @@ public class PlayPermanentClass
     bool _activateETB = true;
     int[] _jogressEvoRootsFrameIDs = null;
     int _digiXrosCount = 0;
+    int _assemblyCount = 0;
     bool _burstDigivolved = false;
     int[] _appFusionFrameIDs = null;
     bool _appFusion = false;
@@ -1164,6 +1174,11 @@ public class PlayPermanentClass
                 _digiXrosCount = GManager.instance.GetComponent<SelectDigiXrosClass>().selectedDigicrossCards.Count;
             }
 
+            if (GManager.instance.GetComponent<SelectAssemblyClass>().playCard == card)
+            {
+                _assemblyCount = GManager.instance.GetComponent<SelectAssemblyClass>().selectedAssemblyCards.Count;
+            }
+
             bool isFromDigimonDigivolutionCards = card.Owner.GetBattleAreaDigimons().Some((permanent) => permanent.DigivolutionCards.Contains(card));
 
             bool isFromSecurity = card.Owner.SecurityCards.Contains(card);
@@ -1302,6 +1317,7 @@ public class PlayPermanentClass
                                 isEvolution: isEvolution,
                                 isJogress: isJogress,
                                 digiXrosCount: _digiXrosCount,
+                                assemblyCount: _assemblyCount,
                                 cardEffect: CardEffect);
 
                                 bool HasETB = permanent.EffectList(EffectTiming.OnEnterFieldAnyone).Some(cardEffect =>
@@ -1516,6 +1532,9 @@ public class PlayPermanentClass
                 yield return GManager.instance.GetComponent<SelectDigiXrosClass>().AddDigivolutiuonCardsByEffect(card);
                 yield return GManager.instance.GetComponent<SelectDigiXrosClass>().AddDigivolutiuonCards(card);
 
+                yield return GManager.instance.GetComponent<SelectAssemblyClass>().AddDigivolutiuonCardsByEffect(card);
+                yield return GManager.instance.GetComponent<SelectAssemblyClass>().AddDigivolutiuonCards(card);
+
                 if (GManager.instance.turnStateMachine.DoneStartGame)
                 {
                     hashtableParams.Add(
@@ -1532,6 +1551,7 @@ public class PlayPermanentClass
             }
 
             GManager.instance.GetComponent<SelectDigiXrosClass>().ResetSelectDigiXrosClass();
+            GManager.instance.GetComponent<SelectAssemblyClass>().ResetSelectAssemblyClass();
 
             yield return GManager.instance.photonWaitController.StartWait("EndPlayPermanent");
         }
@@ -1563,6 +1583,7 @@ public class PlayPermanentClass
             isEvolution: isEvolution,
             isJogress: isJogress,
             digiXrosCount: _digiXrosCount,
+            assemblyCount: _assemblyCount,
             cardEffect: CardEffect);
 
         #region "When permanents are played" effect

+ 2 - 1
Assets/Scripts/CardEffectCommons/GameContextDeterminarion.cs

@@ -151,7 +151,8 @@ public partial class CardEffectCommons
         int fixedCost = -1) =>
     cardSource != null &&
     (isPlayOption || !cardSource.IsOption) &&
-    !GManager.instance.GetComponent<SelectDigiXrosClass>().selectedDigicrossCards.Contains(cardSource)
+    !GManager.instance.GetComponent<SelectDigiXrosClass>().selectedDigicrossCards.Contains(cardSource) &&
+    !GManager.instance.GetComponent<SelectAssemblyClass>().selectedAssemblyCards.Contains(cardSource)
     && cardSource.Owner.fieldCardFrames.Some((frame) =>
     frame.IsEmptyFrame()
     && cardSource.CanPlayCardTargetFrame(frame, payCost, cardEffect, root, isBreedingArea: isBreedingArea, fixedCost:fixedCost));

+ 2 - 1
Assets/Scripts/CardEffectCommons/HashtableSetting.cs

@@ -130,7 +130,7 @@ public partial class CardEffectCommons
     #endregion
 
     #region Hashtable used when check whether the permanent can activate [On Play] [When Digivolving] or "Permanent enters the field" effect
-    public static Hashtable OnEnterFieldHashtable(List<OnEnterFieldHashtableParams> hashtableParams, bool isEvolution, bool isJogress, int digiXrosCount,
+    public static Hashtable OnEnterFieldHashtable(List<OnEnterFieldHashtableParams> hashtableParams, bool isEvolution, bool isJogress, int digiXrosCount, int assemblyCount,
     ICardEffect cardEffect)
     {
         Hashtable hashtable = new Hashtable()
@@ -138,6 +138,7 @@ public partial class CardEffectCommons
             {"isEvolution", isEvolution},
             {"isJogress", isJogress},
             {"DigiXrosCount", digiXrosCount },
+            {"AssemblyCount", assemblyCount },
             {"isFromDigimonDigivolutionCards", hashtableParams.Some(param => param.IsFromDigimonDigivolutionCards)}
         };
 

+ 14 - 0
Assets/Scripts/CardEffectInterfaces.cs

@@ -385,6 +385,13 @@ public interface IAddDigiXrosConditionEffect
 }
 #endregion
 
+#region "Target card gains Assembly conditions" effect
+public interface IAddAssemblyConditionEffect
+{
+    AssemblyCondition GetAssemblyCondition(CardSource cardSource);
+}
+#endregion
+
 #region "Target card gains Burst digivolution conditions" effect
 public interface IAddBurstDigivolutionConditionEffect
 {
@@ -427,6 +434,13 @@ public interface ICanSelectDigiXrosEffect
 }
 #endregion
 
+#region "Target card be selected in Assembly" effect
+public interface ICanSelectAssemblyEffect
+{
+    bool CanSelect(CardSource cardSource, Permanent permanent);
+}
+#endregion
+
 #region "Target permanent's attack target cannot be switched" effect"
 public interface ICanNotSwitchAttackTargetEffect
 {

+ 28 - 0
Assets/Scripts/CardEffects/AddAssemblyConditionClass.cs

@@ -0,0 +1,28 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System;
+
+public class AddAssemblyConditionClass : ICardEffect, IAddAssemblyConditionEffect
+{
+    Func<CardSource, AssemblyCondition> _getAssemblyCondition { get; set; }
+    public void SetUpAddAssemblyConditionClass(Func<CardSource, AssemblyCondition> getAssemblyCondition)
+    {
+        _getAssemblyCondition = getAssemblyCondition;
+    }
+    public AssemblyCondition GetAssemblyCondition(CardSource cardSource)
+    {
+        if (cardSource != null)
+        {
+            if (_getAssemblyCondition != null)
+            {
+                if (_getAssemblyCondition(cardSource) != null)
+                {
+                    return _getAssemblyCondition(cardSource);
+                }
+            }
+        }
+
+        return null;
+    }
+}

+ 11 - 0
Assets/Scripts/CardEffects/AddAssemblyConditionClass.cs.meta

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

+ 38 - 0
Assets/Scripts/CardEffects/CanSelectAssemblyClass.cs

@@ -0,0 +1,38 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Linq;
+using Photon;
+using System;
+
+public class CanSelectAssemblyClass : ICardEffect, ICanSelectAssemblyEffect
+{
+    public void SetUpCanSelectAssemblyClass(Func<CardSource, Permanent, bool> CanSelectCondition)
+    {
+        this.CanSelectCondition = CanSelectCondition;
+    }
+
+    Func<CardSource, Permanent, bool> CanSelectCondition { get; set; }
+
+    public bool CanSelect(CardSource cardSource, Permanent permanent)
+    {
+        if (CanSelectCondition != null)
+        {
+            if (permanent != null)
+            {
+                if (permanent.TopCard != null)
+                {
+                    if (cardSource != null)
+                    {
+                        if (CanSelectCondition(cardSource, permanent))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+}

+ 11 - 0
Assets/Scripts/CardEffects/CanSelectAssemblyClass.cs.meta

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

+ 97 - 0
Assets/Scripts/CardSource.cs

@@ -509,6 +509,39 @@ public class CardSource : MonoBehaviour
         }
         #endregion
 
+        #region Assembly
+        if (!isEvolution)
+        {
+            if (HasAssembly)
+            {
+                if (Owner.CanReduceCost(null, this))
+                {
+                    //AI
+                    if (!(!Owner.isYou && GManager.instance.IsAI))
+                    {
+                        if (checkAvailability)
+                        {
+                            return 0;
+                        }
+                    }
+
+                    if (!checkAvailability)
+                    {
+                        SelectAssemblyClass selectAssemblyClass = GManager.instance.GetComponent<SelectAssemblyClass>();
+
+                        if (selectAssemblyClass != null)
+                        {
+                            if (selectAssemblyClass.playCard == this)
+                            {
+                                Cost -= selectAssemblyClass.selectedAssemblyCards.Count * assemblyCondition.reduceCost;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        #endregion
+
         Cost = GetChangedCostItselef(Cost, root, targetPermanents, checkAvailability);
 
         Cost = GetChangedPayingCost(Cost, root, targetPermanents, checkAvailability);
@@ -2011,6 +2044,10 @@ public class CardSource : MonoBehaviour
     public bool HasDigiXros => digiXrosCondition != null;
     #endregion
 
+    #region whether this card has [Assembly]
+    public bool HasAssembly => assemblyCondition != null;
+    #endregion
+
     #region traits
     public List<string> CardTraits
     {
@@ -2414,6 +2451,32 @@ public class CardSource : MonoBehaviour
     }
     #endregion
 
+    #region Assembly requirement
+    public AssemblyCondition assemblyCondition
+    {
+        get
+        {
+            foreach (ICardEffect cardEffect in this.EffectList(EffectTiming.None))
+            {
+                if (cardEffect is IAddAssemblyConditionEffect)
+                {
+                    if (cardEffect.CanUse(null))
+                    {
+                        AssemblyCondition assemblyCondition = ((IAddAssemblyConditionEffect)cardEffect).GetAssemblyCondition(this);
+
+                        if (assemblyCondition != null)
+                        {
+                            return assemblyCondition;
+                        }
+                    }
+                }
+            }
+
+            return null;
+        }
+    }
+    #endregion
+
     #region whether this card can Burst digivolve
     public bool CanPlayBurst(bool PayCost)
     {
@@ -3002,4 +3065,38 @@ public class AppFusionCondition
     public Func<Permanent, bool> digimonCondition { get; private set; } = null;
 
     public int cost { get; private set; } = 0;
+}
+
+public class AssemblyCondition
+{
+    public AssemblyCondition(List<AssemblyConditionElement> elements, Func<List<CardSource>, CardSource, bool> CanTargetCondition_ByPreSelecetedList, int reduceCost)
+    {
+        this.elements = new List<AssemblyConditionElement>();
+
+        foreach (AssemblyConditionElement element in elements)
+        {
+            this.elements.Add(element);
+        }
+
+        this.CanTargetCondition_ByPreSelecetedList = CanTargetCondition_ByPreSelecetedList;
+        this.reduceCost = reduceCost;
+    }
+    public List<AssemblyConditionElement> elements { get; private set; } = new List<AssemblyConditionElement>();
+    public Func<List<CardSource>, CardSource, bool> CanTargetCondition_ByPreSelecetedList { get; private set; } = null;
+
+    public int reduceCost { get; private set; } = 0;
+}
+
+public class AssemblyConditionElement
+{
+    public AssemblyConditionElement(Func<CardSource, bool> cardCondition, string selectMessage, bool skipAllIfNoSelect = false)
+    {
+        this.CardCondition = cardCondition;
+
+        this.selectMessage = selectMessage;
+        this.skipAllIfNoSelect = skipAllIfNoSelect;
+    }
+    public Func<CardSource, bool> CardCondition { get; private set; } = null;
+    public string selectMessage { get; private set; } = "";
+    public bool skipAllIfNoSelect { get; private set; } = false;
 }

+ 7 - 1
Assets/Scripts/CommandText.cs

@@ -8,6 +8,7 @@ public class CommandText : MonoBehaviour
 {
     public TextMeshProUGUI commandText;
     public GameObject digiXrosObject;
+    public GameObject assemblyObject;
 
     public void Init()
     {
@@ -20,7 +21,7 @@ public class CommandText : MonoBehaviour
     }
 
     #region Open command message
-    public void OpenCommandText(string Text, bool digiXros = false)
+    public void OpenCommandText(string Text, bool digiXros = false, bool assembly = false)
     {
         commandText.text = Text;
         this.gameObject.SetActive(true);
@@ -31,6 +32,11 @@ public class CommandText : MonoBehaviour
         {
             digiXrosObject.SetActive(digiXros);
         }
+
+        if(assemblyObject != null)
+        {
+            assemblyObject.SetActive(assembly);
+        }
     }
     #endregion
 

+ 39 - 0
Assets/Scripts/Effects.cs

@@ -1552,6 +1552,45 @@ public class Effects : MonoBehaviour
     }
     #endregion
 
+    #region Assembly Effect
+    [Header("Assembly Select Effect")]
+    [SerializeField] GameObject AssemblySelectCardEffect;
+
+    [Header("Assembly Select Audio")]
+    public AudioClip AssemblySelectCardEffectSE;
+
+    public IEnumerator CreateAssemblySelectCardEffect(Permanent permanent, Player player = null)
+    {
+        if (AssemblySelectCardEffect != null)
+        {
+            Vector3 position = new Vector3();
+
+            if (permanent != null)
+            {
+                if (permanent.ShowingPermanentCard != null)
+                {
+                    position = new Vector3(permanent.ShowingPermanentCard.transform.position.x, permanent.ShowingPermanentCard.transform.position.y, permanent.ShowingPermanentCard.transform.position.z);
+                }
+            }
+
+            else if (player != null)
+            {
+                position = new Vector3(player.TrashCardImage.transform.position.x, player.TrashCardImage.transform.position.y, player.TrashCardImage.transform.position.z);
+            }
+
+            GameObject effect = Instantiate(AssemblySelectCardEffect, effectParent);
+
+            effect.transform.position = position;
+
+            StartCoroutine(DeleteCoroutine(effect, permanent.ShowingPermanentCard));
+
+            ContinuousController.instance.PlaySE(AssemblySelectCardEffectSE);
+        }
+
+        yield return new WaitForSeconds(0.3f);
+    }
+    #endregion
+
     #region 攻撃・ブロック不可付与エフェクト
     [Header("凍結SE")]
     [SerializeField] AudioClip FreezeSE;

+ 47 - 0
Assets/Scripts/Permanent.cs

@@ -3440,6 +3440,53 @@ public class Permanent
     }
     #endregion
 
+    #region Can Substitue for Assembly
+    public bool CanSubstituteForAssemblyCondition(CardSource cardSource)
+    {
+        #region Effects that can be used in place of Assembly conditions
+        foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
+        {
+            foreach (Permanent permanent in player.GetFieldPermanents())
+            {
+                #region Effects of permanents in play
+                foreach (ICardEffect cardEffect in permanent.EffectList(EffectTiming.None))
+                {
+                    if (cardEffect is ICanSelectAssemblyEffect)
+                    {
+                        if (cardEffect.CanUse(null))
+                        {
+                            if (((ICanSelectAssemblyEffect)cardEffect).CanSelect(cardSource, this))
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                }
+                #endregion
+            }
+
+            #region player effect
+            foreach (ICardEffect cardEffect in player.EffectList(EffectTiming.None))
+            {
+                if (cardEffect is ICanSelectAssemblyEffect)
+                {
+                    if (cardEffect.CanUse(null))
+                    {
+                        if (((ICanSelectAssemblyEffect)cardEffect).CanSelect(cardSource, this))
+                        {
+                            return true;
+                        }
+                    }
+                }
+            }
+            #endregion
+        }
+        #endregion
+
+        return false;
+    }
+    #endregion
+
     #region 登場した直後のLevel
     public int LevelJustAfterPlayed { get; set; } = -1;
     #endregion

+ 411 - 0
Assets/Scripts/SelectAssemblyClass.cs

@@ -0,0 +1,411 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Linq;
+using Photon;
+using Photon.Pun;
+using System;
+using UnityEngine.Events;
+
+public class SelectAssemblyClass : MonoBehaviourPunCallbacks
+{
+    public List<CardSource> selectedAssemblyCards { get; private set; } = new List<CardSource>();
+    public List<AddDigivolutionCardsInfo> addDigivolutionCardInfos { get; private set; } = new List<AddDigivolutionCardsInfo>();
+    public CardSource playCard { get; private set; } = null;
+
+    public void ResetSelectAssemblyClass()
+    {
+        selectedAssemblyCards = new List<CardSource>();
+        addDigivolutionCardInfos = new List<AddDigivolutionCardsInfo>();
+        playCard = null;
+    }
+
+    public void AddDigivolutionCardInfos(AddDigivolutionCardsInfo digivolutionCardsInfo)
+    {
+        addDigivolutionCardInfos.Add(digivolutionCardsInfo);
+    }
+
+    #region Is Trash Card
+    bool isTrashCard(CardSource cardSource)
+    {
+        if (cardSource != null)
+        {
+            if (CardEffectCommons.IsExistOnTrash(cardSource))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Can Select Assembly
+    bool CanSelectAssembly(AssemblyConditionElement element, CardSource targetCard, CardSource card)
+    {
+        if (card != targetCard)
+        {
+            if (card != null)
+            {
+                if (element != null)
+                {
+                    if (element.CardCondition != null)
+                    {
+                        if (targetCard != null)
+                        {
+                            if (card.assemblyCondition != null)
+                            {
+                                if (!targetCard.IsToken)
+                                {
+                                    if (!selectedAssemblyCards.Contains(targetCard))
+                                    {
+                                        if (addDigivolutionCardInfos.Count((addDigivolutionCardInfo) => addDigivolutionCardInfo.cardSources.Contains(targetCard)) == 0)
+                                        {
+                                            if (card.assemblyCondition.CanTargetCondition_ByPreSelecetedList != null)
+                                            {
+                                                if (!card.assemblyCondition.CanTargetCondition_ByPreSelecetedList(selectedAssemblyCards, targetCard))
+                                                {
+                                                    return false;
+                                                }
+                                            }
+
+                                            if (element.CardCondition(targetCard))
+                                            {
+                                                return true;
+                                            }
+
+                                            if (targetCard.PermanentOfThisCard() != null)
+                                            {
+                                                if (targetCard == targetCard.PermanentOfThisCard().TopCard)
+                                                {
+                                                    if (targetCard.PermanentOfThisCard().CanSubstituteForAssemblyCondition(card))
+                                                    {
+                                                        return true;
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+    #endregion
+
+    #region Select
+    public IEnumerator Select(CardSource card)
+    {
+        GManager.instance.turnStateMachine.isSync = true;
+
+        selectedAssemblyCards = new List<CardSource>();
+
+        playCard = card;
+
+        if (card != null)
+        {
+            if (card.HasAssembly)
+            {
+                AssemblyCondition AssemblyCondition = card.assemblyCondition;
+
+                foreach (AssemblyConditionElement element in AssemblyCondition.elements)
+                {
+                    yield return GManager.instance.photonWaitController.StartWait("SelectAssemblys");
+
+                    if (selectedAssemblyCards.Count >= 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect2(selectedAssemblyCards, "Assembly Cards", false, true));
+                    }
+
+                    if (_endSelectAssembly)
+                    {
+                        _endSelectAssembly = false;
+                        //break; TODO: Removed for not triggering Assembly in all situations
+                    }
+
+                    bool canSelectTrash = false;
+
+                    if (CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, (cardSource) => CanSelectAssembly(element, cardSource, card)))
+                    {
+                        canSelectTrash = true;
+                    }
+
+                    Func<IEnumerator> _SelectTrashCard = () => SelectTrashCard(AssemblyCondition, element, card);
+                    Func<IEnumerator> _EndSelectAssembly = () => EndSelectAssembly();
+
+                    List<Func<IEnumerator>> actions = new List<Func<IEnumerator>>() { _SelectTrashCard, _EndSelectAssembly };
+
+                    List<Func<IEnumerator>> canSelectActions = new List<Func<IEnumerator>>();
+
+                    if (canSelectTrash)
+                    {
+                        canSelectActions.Add(_SelectTrashCard);
+                    }
+
+                    canSelectActions.Add(_EndSelectAssembly);
+
+                    if (canSelectActions.Count == 1)
+                    {
+                        if (AssemblyCondition.CanTargetCondition_ByPreSelecetedList != null || element.skipAllIfNoSelect)
+                        {
+                            break;
+                        }
+
+                        else
+                        {
+                            continue;
+                        }
+                    }
+
+                    else if (canSelectActions.Count == 2 && AssemblyCondition.CanTargetCondition_ByPreSelecetedList == null && !element.skipAllIfNoSelect)
+                    {
+                        SetTargetAssemblysIndex(actions.IndexOf(canSelectActions[0]));
+                    }
+
+                    else
+                    {
+                        if (card.Owner.isYou)
+                        {
+                            GManager.instance.commandText.OpenCommandText($"From which area will you select {element.selectMessage}?", assembly: true);
+
+                            List<Command_SelectCommand> command_SelectCommands = new List<Command_SelectCommand>();
+
+                            for (int i = 0; i < canSelectActions.Count; i++)
+                            {
+                                int k = actions.IndexOf(canSelectActions[i]);
+                                int spriteIndex = 0;
+
+                                string message = "";
+
+                                switch (k)
+                                {
+                                    case 0:
+                                        message = "Trash";
+                                        break;
+
+                                    case 1:
+                                        message = "End Selection";
+                                        spriteIndex = 1;
+                                        break;
+                                }
+
+                                command_SelectCommands.Add(new Command_SelectCommand(message, () => photonView.RPC("SetTargetAssemblysIndex", RpcTarget.All, k), spriteIndex));
+                            }
+
+                            GManager.instance.selectCommandPanel.SetUpCommandButton(command_SelectCommands);
+                        }
+
+                        else
+                        {
+                            GManager.instance.commandText.OpenCommandText($"The opponent is choosing from which area to select {element.selectMessage}.", assembly: true);
+
+                            #region AI
+                            if (GManager.instance.IsAI)
+                            {
+                                List<int> indexes = new List<int>();
+
+                                for (int i = 0; i < canSelectActions.Count; i++)
+                                {
+                                    int k = actions.IndexOf(canSelectActions[i]);
+
+                                    indexes.Add(k);
+                                }
+
+                                SetTargetAssemblysIndex(UnityEngine.Random.Range(0, indexes.Count));
+                            }
+                            #endregion
+                        }
+                    }
+
+                    yield return new WaitWhile(() => !_endSelect);
+                    _endSelect = false;
+
+                    GManager.instance.commandText.CloseCommandText();
+                    yield return new WaitWhile(() => GManager.instance.commandText.gameObject.activeSelf);
+
+                    if (0 <= _targetIndex && _targetIndex <= actions.Count - 1)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(actions[_targetIndex]());
+
+                        if (!card.Owner.isYou && GManager.instance.IsAI)
+                        {
+                            yield return new WaitForSeconds(0.3f);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (selectedAssemblyCards.Count >= 1)
+        {
+            yield return new WaitForSeconds(0.4f);
+        }
+
+        GManager.instance.GetComponent<Effects>().OffShowCard2();
+
+        GManager.instance.turnStateMachine.isSync = false;
+    }
+    #endregion
+
+    #region Select Trash Card
+    IEnumerator SelectTrashCard(AssemblyCondition AssemblyCondition, AssemblyConditionElement element, CardSource card)
+    {
+        bool CanSelectCardCondition(CardSource cardSource) => CanSelectAssembly(element, cardSource, card);
+
+        if (CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, (cardSource) => CanSelectCardCondition(cardSource)))
+        {
+            int maxCount = 1;
+
+            SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
+
+            selectCardEffect.SetUp(
+                        canTargetCondition: CanSelectCardCondition,
+                        canTargetCondition_ByPreSelecetedList: null,
+                        canEndSelectCondition: null,
+                        canNoSelect: () => true,
+                        selectCardCoroutine: SelectCardCoroutine,
+                        afterSelectCardCoroutine: AfterSelectCardCoroutine,
+                        message: $"<color=#FF633E>Assembly</color>: Select {element.selectMessage} from trash.",
+                        maxCount: maxCount,
+                        canEndNotMax: false,
+                        isShowOpponent: true,
+                        mode: SelectCardEffect.Mode.Custom,
+                        root: SelectCardEffect.Root.Trash,
+                        customRootCardList: null,
+                        canLookReverseCard: true,
+                        selectPlayer: card.Owner,
+                        cardEffect: null);
+
+            selectCardEffect.SetUpCustomMessage($"Select {element.selectMessage}.", $"The opponent is selecting {element.selectMessage}.");
+            selectCardEffect.SetUpCustomMessage_ShowCard("Selected Trash Card");
+            selectCardEffect.SetAssembly();
+
+            yield return StartCoroutine(selectCardEffect.Activate());
+
+            IEnumerator SelectCardCoroutine(CardSource cardSource)
+            {
+                selectedAssemblyCards.Add(cardSource);
+
+                yield return null;
+            }
+
+            IEnumerator AfterSelectCardCoroutine(List<CardSource> cardSources)
+            {
+                if (cardSources.Count == 0)
+                {
+                    if (AssemblyCondition != null)
+                    {
+                        if (AssemblyCondition.CanTargetCondition_ByPreSelecetedList != null || element.skipAllIfNoSelect)
+                        {
+                            EndSelectAssembly();
+                        }
+                    }
+                }
+
+                yield return null;
+            }
+        }
+    }
+    #endregion
+
+    #region End Select Assembly
+    IEnumerator EndSelectAssembly()
+    {
+        _endSelectAssembly = true;
+        yield return null;
+    }
+    #endregion
+
+    #region Add Digivolution Cards
+    public IEnumerator AddDigivolutiuonCards(CardSource card)
+    {
+        if (selectedAssemblyCards.Count >= 1)
+        {
+            if (card != null)
+            {
+                if (card == playCard)
+                {
+                    if (card.PermanentOfThisCard() != null)
+                    {
+                        yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(selectedAssemblyCards, "Assembly Cards", true, true));
+
+                        foreach (CardSource cardSource in selectedAssemblyCards)
+                        {
+                            if (isTrashCard(cardSource))
+                            {
+                                yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().CreateAssemblySelectCardEffect(null, player: cardSource.Owner));
+
+                                yield return ContinuousController.instance.StartCoroutine(card.PermanentOfThisCard().AddDigivolutionCardsBottom(new List<CardSource>() { cardSource }, null));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        ResetSelectAssemblyClass();
+
+        yield return null;
+    }
+    #endregion
+
+    #region Add Digivolution Card
+    public IEnumerator AddDigivolutiuonCardsByEffect(CardSource card)
+    {
+        if (addDigivolutionCardInfos.Count >= 1)
+        {
+            if (card != null)
+            {
+                if (card.PermanentOfThisCard() != null)
+                {
+                    List<CardSource> addedCards = new List<CardSource>();
+
+                    foreach (AddDigivolutionCardsInfo info in addDigivolutionCardInfos)
+                    {
+                        List<CardSource> underTamerCards = new List<CardSource>();
+                        List<Permanent> digimonPermanents = new List<Permanent>();
+                        List<CardSource> trashCards = new List<CardSource>();
+
+                        foreach (CardSource cardSource in info.cardSources)
+                        {
+                            if (isTrashCard(cardSource))
+                            {
+                                trashCards.Add(cardSource);
+                                addedCards.Add(cardSource);
+                            }
+                        }
+
+                        if (trashCards.Count >= 1)
+                        {
+                            yield return ContinuousController.instance.StartCoroutine(card.PermanentOfThisCard().AddDigivolutionCardsBottom(trashCards, info.cardEffect));
+                        }
+                    }
+
+                    yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect2(addedCards, "Digivolution Cards", true, true));
+                }
+            }
+        }
+
+        addDigivolutionCardInfos = new List<AddDigivolutionCardsInfo>();
+
+        yield return null;
+    }
+    #endregion
+
+    int _targetIndex = 0;
+    bool _endSelect = false;
+
+    bool _endSelectAssembly = false;
+
+    [PunRPC]
+    public void SetTargetAssemblysIndex(int targetIndex)
+    {
+        this._targetIndex = targetIndex;
+        _endSelect = true;
+    }
+}

+ 11 - 0
Assets/Scripts/SelectAssemblyClass.cs.meta

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

+ 11 - 4
Assets/Scripts/SelectCardEffect.cs

@@ -50,6 +50,7 @@ public class SelectCardEffect : MonoBehaviourPunCallbacks
         _showReverseCard = true;
         _showCard = true;
         _isDigiXros = false;
+        _isAssembly = false;
         _isDeckBottom = false;
         _isDeckTop = false;
         _notAddLog = false;
@@ -92,6 +93,11 @@ public class SelectCardEffect : MonoBehaviourPunCallbacks
         _isDigiXros = true;
     }
 
+    public void SetAssembly()
+    {
+        _isAssembly = true;
+    }
+
     public void SetIsSecurity()
     {
         _isSecurity = true;
@@ -154,6 +160,7 @@ public class SelectCardEffect : MonoBehaviourPunCallbacks
     bool _showCard = true;
     bool _notAddLog = false;
     bool _isDigiXros = false;
+    bool _isAssembly = false;
     bool _isSecurity = false;
 
     public enum Mode
@@ -339,7 +346,7 @@ public class SelectCardEffect : MonoBehaviourPunCallbacks
 
                     if (!string.IsNullOrEmpty(_customMessage))
                     {
-                        GManager.instance.commandText.OpenCommandText(_customMessage, _isDigiXros);
+                        GManager.instance.commandText.OpenCommandText(_customMessage, _isDigiXros, _isAssembly);
                     }
                     else
                     {
@@ -362,7 +369,7 @@ public class SelectCardEffect : MonoBehaviourPunCallbacks
 
                         if (!string.IsNullOrEmpty(message))
                         {
-                            GManager.instance.commandText.OpenCommandText(message, _isDigiXros);
+                            GManager.instance.commandText.OpenCommandText(message, _isDigiXros, _isAssembly);
                         }
                     }
 
@@ -513,11 +520,11 @@ public class SelectCardEffect : MonoBehaviourPunCallbacks
             {
                 if (!string.IsNullOrEmpty(_customMessage_Enemy))
                 {
-                    GManager.instance.commandText.OpenCommandText(_customMessage_Enemy, _isDigiXros);
+                    GManager.instance.commandText.OpenCommandText(_customMessage_Enemy, _isDigiXros, _isAssembly);
                 }
                 else
                 {
-                    GManager.instance.commandText.OpenCommandText("The opponent is selecting cards.", _isDigiXros);
+                    GManager.instance.commandText.OpenCommandText("The opponent is selecting cards.", _isDigiXros, _isAssembly);
                 }
 
                 #region AI