BT20_098.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace DCGO.CardEffects.BT20
  6. {
  7. public class BT20_098 : CEntity_Effect
  8. {
  9. public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
  10. {
  11. List<ICardEffect> cardEffects = new List<ICardEffect>();
  12. #region Main Effect
  13. if (timing == EffectTiming.OptionSkill)
  14. {
  15. int maxLevel = 9;
  16. ActivateClass activateClass = new ActivateClass();
  17. activateClass.SetUpICardEffect(card.BaseENGCardNameFromEntity, CanUseCondition, card);
  18. activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, false, EffectDescription());
  19. cardEffects.Add(activateClass);
  20. string EffectDescription()
  21. {
  22. return
  23. "[Main] By returning 9 levels' total worth of Digimon cards from your opponent's trash to the bottom of the deck, you may play 1 [Ghost] trait Digimon card of each returned card's level from your trash without paying the costs. Then, the Digimon this effect played gain <Rush> and <Blocker> until the end of your opponent's turn.";
  24. }
  25. bool CanUseCondition(Hashtable hashtable)
  26. {
  27. return CardEffectCommons.CanTriggerOptionMainEffect(hashtable, card);
  28. }
  29. bool CanSelectReturnCardCondition(CardSource cardSource)
  30. {
  31. return cardSource.IsDigimon && cardSource.HasLevel && cardSource.Level <= maxLevel;
  32. }
  33. IEnumerator ActivateCoroutine(Hashtable hashtable)
  34. {
  35. if (CardEffectCommons.HasMatchConditionOpponentsCardInTrash(card, CanSelectReturnCardCondition))
  36. {
  37. List<CardSource> selectedCardsToReturn = new();
  38. int maxCount = Math.Min(3,
  39. CardEffectCommons.MatchConditionOpponentsCardCountInTrash(card, CanSelectReturnCardCondition));
  40. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  41. selectCardEffect.SetUp(
  42. canTargetCondition: CanSelectReturnCardCondition,
  43. canTargetCondition_ByPreSelecetedList: CanTargetConditionByPreSelectedList,
  44. canEndSelectCondition: CanEndSelectCondition,
  45. canNoSelect: () => true,
  46. selectCardCoroutine: SelectCardCoroutine1,
  47. afterSelectCardCoroutine: null,
  48. message:
  49. "Select cards to place at the bottom of the deck\n(cards will be placed back to the bottom of the deck so that cards with lower numbers are on top).",
  50. maxCount: maxCount,
  51. canEndNotMax: true,
  52. isShowOpponent: true,
  53. mode: SelectCardEffect.Mode.Custom,
  54. root: SelectCardEffect.Root.Custom,
  55. customRootCardList: card.Owner.Enemy.TrashCards,
  56. canLookReverseCard: true,
  57. selectPlayer: card.Owner,
  58. cardEffect: activateClass);
  59. yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
  60. IEnumerator SelectCardCoroutine1(CardSource cardSource)
  61. {
  62. selectedCardsToReturn.Add(cardSource);
  63. yield return null;
  64. }
  65. bool CanEndSelectCondition(List<CardSource> cardSources)
  66. {
  67. if (cardSources.Count <= 0)
  68. {
  69. return false;
  70. }
  71. int sumLevel = cardSources.Sum(source => source.Level);
  72. if (sumLevel != maxLevel)
  73. {
  74. return false;
  75. }
  76. return true;
  77. }
  78. bool CanTargetConditionByPreSelectedList(List<CardSource> cardSources, CardSource cardSource)
  79. {
  80. int sumLevel = cardSources.Sum(source => source.Level);
  81. sumLevel += cardSource.Level;
  82. if (sumLevel > maxLevel)
  83. {
  84. return false;
  85. }
  86. return true;
  87. }
  88. if (selectedCardsToReturn.Count >= 1)
  89. {
  90. // Return opponent's cards from trash to the bottom of their deck
  91. yield return ContinuousController.instance.StartCoroutine(
  92. CardObjectController.AddLibraryBottomCards(selectedCardsToReturn));
  93. // For each returned card, choose a card from your trash with the same level, then play them
  94. List<CardSource> selectedCardsToPlay = new List<CardSource>();
  95. IEnumerator SelectCardCoroutine2(CardSource cardSource)
  96. {
  97. selectedCardsToPlay.Add(cardSource);
  98. yield return null;
  99. }
  100. foreach (CardSource returnedCard in selectedCardsToReturn)
  101. {
  102. bool CanSelectPlayCardCondition(CardSource cardSource)
  103. {
  104. return cardSource.IsDigimon && cardSource.EqualsTraits("Ghost") &&
  105. cardSource.HasLevel && cardSource.Level == returnedCard.Level &&
  106. !selectedCardsToPlay.Contains(cardSource) &&
  107. CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false,
  108. cardEffect: activateClass);
  109. }
  110. bool CanNoSelect()
  111. {
  112. return selectedCardsToPlay.Count == 0;
  113. }
  114. bool RemoveOptionsAlreadySelected(List<CardSource> cardSources, CardSource cardSource)
  115. {
  116. if (cardSources.Contains(cardSource))
  117. return false;
  118. return true;
  119. }
  120. selectCardEffect.SetUp(
  121. canTargetCondition: CanSelectPlayCardCondition,
  122. canTargetCondition_ByPreSelecetedList: RemoveOptionsAlreadySelected,
  123. canEndSelectCondition: null,
  124. canNoSelect: CanNoSelect,
  125. selectCardCoroutine: SelectCardCoroutine2,
  126. afterSelectCardCoroutine: null,
  127. message: "Select 1 card to play.",
  128. maxCount: 1,
  129. canEndNotMax: false,
  130. isShowOpponent: true,
  131. mode: SelectCardEffect.Mode.Custom,
  132. root: SelectCardEffect.Root.Trash,
  133. customRootCardList: null,
  134. canLookReverseCard: true,
  135. selectPlayer: card.Owner,
  136. cardEffect: activateClass);
  137. selectCardEffect.SetUpCustomMessage("Select 1 card to play.", "The opponent is selecting 1 card to play.");
  138. selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
  139. yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
  140. }
  141. yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
  142. cardSources: selectedCardsToPlay,
  143. activateClass: activateClass,
  144. payCost: false,
  145. isTapped: false,
  146. root: SelectCardEffect.Root.Trash,
  147. activateETB: true));
  148. // Give all played cards <Rush> and <Blocker>
  149. foreach (CardSource playedCard in selectedCardsToPlay)
  150. {
  151. Permanent permanent = playedCard.PermanentOfThisCard();
  152. yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainRush(
  153. targetPermanent: permanent,
  154. effectDuration: EffectDuration.UntilOpponentTurnEnd,
  155. activateClass: activateClass));
  156. yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.GainBlocker(
  157. targetPermanent: permanent,
  158. effectDuration: EffectDuration.UntilOpponentTurnEnd,
  159. activateClass: activateClass));
  160. }
  161. }
  162. }
  163. }
  164. }
  165. #endregion
  166. #region Security Effect
  167. if (timing == EffectTiming.SecuritySkill)
  168. {
  169. ActivateClass activateClass = new ActivateClass();
  170. activateClass.SetUpICardEffect($"Play a Digimon from trash without paying the cost", CanUseCondition, card);
  171. activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, false, EffectDescription());
  172. activateClass.SetIsSecurityEffect(true);
  173. cardEffects.Add(activateClass);
  174. string EffectDescription()
  175. {
  176. return
  177. "[Security] You may play 1 level 5 or lower Digimon card with the [Ghost] trait from your trash without paying the cost.";
  178. }
  179. bool CanUseCondition(Hashtable hashtable)
  180. {
  181. return CardEffectCommons.CanTriggerSecurityEffect(hashtable, card);
  182. }
  183. bool CanSelectCardCondition(CardSource cardSource)
  184. {
  185. return cardSource.IsDigimon && cardSource.EqualsTraits("Ghost") &&
  186. cardSource.HasLevel && cardSource.Level <= 5 &&
  187. CardEffectCommons.CanPlayAsNewPermanent(cardSource: cardSource, payCost: false, cardEffect: activateClass);
  188. }
  189. IEnumerator ActivateCoroutine(Hashtable hashtable)
  190. {
  191. List<CardSource> selectedCards = new List<CardSource>();
  192. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  193. selectCardEffect.SetUp(
  194. canTargetCondition: CanSelectCardCondition,
  195. canTargetCondition_ByPreSelecetedList: null,
  196. canEndSelectCondition: null,
  197. canNoSelect: () => true,
  198. selectCardCoroutine: SelectCardCoroutine,
  199. afterSelectCardCoroutine: null,
  200. message: "Select 1 card to play.",
  201. maxCount: 1,
  202. canEndNotMax: false,
  203. isShowOpponent: true,
  204. mode: SelectCardEffect.Mode.Custom,
  205. root: SelectCardEffect.Root.Trash,
  206. customRootCardList: null,
  207. canLookReverseCard: true,
  208. selectPlayer: card.Owner,
  209. cardEffect: activateClass);
  210. selectCardEffect.SetUpCustomMessage("Select 1 card to play.", "The opponent is selecting 1 card to play.");
  211. selectCardEffect.SetUpCustomMessage_ShowCard("Played Card");
  212. yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
  213. IEnumerator SelectCardCoroutine(CardSource cardSource)
  214. {
  215. selectedCards.Add(cardSource);
  216. yield return null;
  217. }
  218. yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayPermanentCards(
  219. cardSources: selectedCards,
  220. activateClass: activateClass,
  221. payCost: false,
  222. isTapped: false,
  223. root: SelectCardEffect.Root.Trash,
  224. activateETB: true));
  225. }
  226. }
  227. #endregion
  228. return cardEffects;
  229. }
  230. }
  231. }