BT25_085.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. // BeelStarMon // Fly Bullet
  5. namespace DCGO.CardEffects.BT25
  6. {
  7. public class BT25_085 : CEntity_Effect
  8. {
  9. public override List<ICardEffect> CardEffects(EffectTiming timing, CardSource card)
  10. {
  11. List<ICardEffect> cardEffects = new List<ICardEffect>();
  12. #region Digimon Effects
  13. #region Alt Digivolution
  14. if (timing == EffectTiming.None)
  15. {
  16. bool PermanentCondition(Permanent permanent)
  17. {
  18. return permanent.TopCard.HasText("Three Musketeers")
  19. || permanent.TopCard.EqualsTraits("TS");
  20. }
  21. cardEffects.Add(CardEffectFactory.AddSelfDigivolutionRequirementStaticEffect(PermanentCondition, 3, true, card, null, level: 5));
  22. }
  23. #endregion
  24. #region Blocker
  25. if (timing == EffectTiming.None)
  26. {
  27. cardEffects.Add(CardEffectFactory.BlockerSelfStaticEffect(isInheritedEffect: false, card: card, condition: null));
  28. }
  29. #endregion
  30. #region Shared WD / WA
  31. string UseOptionHashString = "BT25_085_WD_WA";
  32. string UseOptionEffectName = "Use a [Three Musketeers] or [TS] Option from hand or under this digimon for free";
  33. string UseOptionEffectDescription(string tag)
  34. => $"[{tag}] [Once Per Turn] You may use 1 [Three Musketeers] or [TS] trait Option card from your hand or this Digimon's digivolution cards without paying the cost.";
  35. CardEffectFactory.ActivateClassesForSharedEffects
  36. (ref cardEffects, timing, card,
  37. UseOptionEffectName,
  38. UseOptionActivateCoroutine,
  39. UseOptionEffectDescription,
  40. optional: false,
  41. isSkippable: true,
  42. additionalActivateCondition: CanActivateUseOption,
  43. maxCountPerTurn: 1,
  44. hashValue: UseOptionHashString,
  45. whenDigivolving: true,
  46. whenAttacking: true);
  47. bool IsTraitedOption(CardSource cardSource)
  48. {
  49. return cardSource.IsOption
  50. && (cardSource.EqualsTraits("Three Musketeers")
  51. || cardSource.EqualsTraits("TS"))
  52. && !cardSource.CanNotPlayThisOption;
  53. }
  54. bool CanActivateUseOption(Hashtable hashtable, ActivateClass activateClass)
  55. {
  56. return CardEffectCommons.HasMatchConditionOwnersHand(card, IsTraitedOption)
  57. || card.PermanentOfThisCard().DigivolutionCards.Any(IsTraitedOption);
  58. }
  59. IEnumerator UseOptionActivateCoroutine(Hashtable hashtable, ActivateClass activateClass)
  60. {
  61. bool executed = false;
  62. bool validHandCards = CardEffectCommons.HasMatchConditionOwnersHand(card, IsTraitedOption);
  63. bool validDigivolutionCards = card.PermanentOfThisCard().DigivolutionCards.Any(IsTraitedOption);
  64. List<SelectionElement<int>> selectionElements = new List<SelectionElement<int>>();
  65. if (validHandCards)
  66. {
  67. selectionElements.Add(new (message: $"Use from Hand", value : 1, spriteIndex: 0));
  68. }
  69. if (validDigivolutionCards)
  70. {
  71. selectionElements.Add(new (message: $"Use from Digivolution Cards", value : 2, spriteIndex: 0));
  72. }
  73. selectionElements.Add( new (message: "Don't use an Option", value: 3, spriteIndex: 1));
  74. string selectPlayerMessage = "From which area will you use an Option?";
  75. string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
  76. GManager.instance.userSelectionManager.SetIntSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
  77. yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
  78. bool doUse = GManager.instance.userSelectionManager.SelectedIntValue != 3;
  79. bool fromHand = GManager.instance.userSelectionManager.SelectedIntValue == 1;
  80. if (doUse)
  81. {
  82. if (fromHand)
  83. {
  84. SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
  85. selectHandEffect.SetUp(
  86. selectPlayer: card.Owner,
  87. canTargetCondition: IsTraitedOption,
  88. canTargetCondition_ByPreSelecetedList: null,
  89. canEndSelectCondition: null,
  90. maxCount: 1,
  91. canNoSelect: true,
  92. canEndNotMax: false,
  93. isShowOpponent: true,
  94. selectCardCoroutine: cardSource => SelectCardCoroutine(cardSource, SelectCardEffect.Root.Hand),
  95. afterSelectCardCoroutine: null,
  96. mode: SelectHandEffect.Mode.Custom,
  97. cardEffect: activateClass);
  98. selectHandEffect.SetUpCustomMessage("Select a [Three Musketeers] Option to place use.", "Opponent is selecting a card to use.");
  99. yield return StartCoroutine(selectHandEffect.Activate());
  100. }
  101. else
  102. {
  103. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  104. selectCardEffect.SetUp(
  105. canTargetCondition: IsTraitedOption,
  106. canTargetCondition_ByPreSelecetedList: null,
  107. canEndSelectCondition: null,
  108. canNoSelect: () => true,
  109. selectCardCoroutine: cardSource => SelectCardCoroutine(cardSource, SelectCardEffect.Root.DigivolutionCards),
  110. afterSelectCardCoroutine: null,
  111. message: "Select 1 card to place.",
  112. maxCount: 1,
  113. canEndNotMax: false,
  114. isShowOpponent: true,
  115. mode: SelectCardEffect.Mode.Custom,
  116. root: SelectCardEffect.Root.DigivolutionCards,
  117. customRootCardList: card.PermanentOfThisCard().DigivolutionCards,
  118. canLookReverseCard: true,
  119. selectPlayer: card.Owner,
  120. cardEffect: activateClass);
  121. selectCardEffect.SetUpCustomMessage("Select a [Three Musketeers] Option to place use.", "Opponent is selecting a card to use.");
  122. yield return StartCoroutine(selectCardEffect.Activate());
  123. }
  124. IEnumerator SelectCardCoroutine(CardSource cardSource, SelectCardEffect.Root root)
  125. {
  126. executed = true;
  127. yield return ContinuousController.instance.StartCoroutine(CardEffectCommons.PlayOptionCards(
  128. cardSources: new List<CardSource> { cardSource },
  129. activateClass: activateClass,
  130. payCost: false,
  131. root: root));
  132. }
  133. }
  134. if (!executed)
  135. {
  136. activateClass.RemoveUse();
  137. }
  138. }
  139. #endregion
  140. #region Shared WD / WA / Counter
  141. string UnsuspendHashString = "BT25_085_WD_WA_Counter";
  142. string UnsuspendEffectName = "By trashing 1 Option from any of your digivolution cards or link cards, unsuspend";
  143. string UnsuspendEffectDescription(string tag)
  144. => $"[{tag}] [Once Per Turn] By trashing 1 Option card from any of your Digimon's digivolution cards or link cards, this Digimon unsuspends.";
  145. CardEffectFactory.ActivateClassesForSharedEffects
  146. (ref cardEffects, timing, card,
  147. UnsuspendEffectName,
  148. UnsuspendActivateCoroutine,
  149. UnsuspendEffectDescription,
  150. optional: false,
  151. isSkippable: true,
  152. additionalActivateCondition: CanActivateUnsuspend,
  153. maxCountPerTurn: 1,
  154. hashValue: UnsuspendHashString,
  155. whenDigivolving: true,
  156. whenAttacking: true,
  157. counter: true);
  158. bool CanTrashCardSource(CardSource cardSource) => cardSource.IsOption;
  159. bool PermanentWithTrashableCard(Permanent permanent)
  160. {
  161. return CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card)
  162. && permanent.DigivolutionOrLinkCards.Any(CanTrashCardSource);
  163. }
  164. bool CanActivateUnsuspend(Hashtable hashtable, ActivateClass activateClass) => CardEffectCommons.HasMatchConditionOwnersPermanent(card, PermanentWithTrashableCard);
  165. IEnumerator UnsuspendActivateCoroutine(Hashtable hashtable, ActivateClass activateClass)
  166. {
  167. bool executed = false;
  168. SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
  169. selectPermanentEffect.SetUp(
  170. selectPlayer: card.Owner,
  171. canTargetCondition: PermanentWithTrashableCard,
  172. canTargetCondition_ByPreSelecetedList: null,
  173. canEndSelectCondition: null,
  174. maxCount: 1,
  175. canNoSelect: true,
  176. canEndNotMax: false,
  177. selectPermanentCoroutine: SelectPermanentCoroutine,
  178. afterSelectPermanentCoroutine: null,
  179. mode: SelectPermanentEffect.Mode.Custom,
  180. cardEffect: activateClass);
  181. selectPermanentEffect.SetUpCustomMessage("Select a Digimon to trash a card from", "Opponent is selecting a card to trash a card from");
  182. yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
  183. IEnumerator SelectPermanentCoroutine(Permanent permanent)
  184. {
  185. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  186. selectCardEffect.SetUp(
  187. canTargetCondition: CanTrashCardSource,
  188. canTargetCondition_ByPreSelecetedList: null,
  189. canEndSelectCondition: null,
  190. canNoSelect: () => true,
  191. selectCardCoroutine: null,
  192. afterSelectCardCoroutine: AfterSelectCardCoroutine,
  193. message: "Select 1 card to trash.",
  194. maxCount: 1,
  195. canEndNotMax: false,
  196. isShowOpponent: true,
  197. mode: SelectCardEffect.Mode.Discard,
  198. root: SelectCardEffect.Root.DigivolutionCards,//This only sets behavior, so currently is safe to use for this combined list. Will ensure pending effects show
  199. customRootCardList: permanent.DigivolutionOrLinkCards,
  200. canLookReverseCard: true,
  201. selectPlayer: card.Owner,
  202. cardEffect: activateClass);
  203. selectCardEffect.SetUpCustomMessage("Select a [Three Musketeers] card to place under 1 of your Digimon.", "Opponent is selecting a card to place.");
  204. yield return StartCoroutine(selectCardEffect.Activate());
  205. IEnumerator AfterSelectCardCoroutine(List<CardSource> cardSources)
  206. {
  207. executed = cardSources.Count > 0;
  208. yield return ContinuousController.instance.StartCoroutine(new IUnsuspendPermanents(
  209. new List<Permanent>() { card.PermanentOfThisCard() },
  210. activateClass).Unsuspend());
  211. }
  212. }
  213. if (!executed)
  214. {
  215. activateClass.RemoveUse();
  216. }
  217. }
  218. #endregion
  219. #endregion
  220. #region Option Effects
  221. #region Ignore Colour Requirement
  222. if (timing == EffectTiming.None)
  223. {
  224. cardEffects.Add(CardEffectFactory.UseRequirements(card, CardCondition));
  225. bool CardCondition(CardSource cardSource)
  226. {
  227. return cardSource.HasText("Three Musketeers");
  228. }
  229. }
  230. #endregion
  231. #region Main
  232. if (timing == EffectTiming.OptionSkill)
  233. {
  234. ActivateClass activateClass = new ActivateClass();
  235. activateClass.SetUpICardEffect("Delete 1 highest level enemy Digimon. Place 1 [Three Musketeers] card from hand or trash under any of your Digimon.", CanUseCondition, card);
  236. activateClass.SetUpActivateClass(null, ActivateCoroutine, -1, false, EffectDescription());
  237. cardEffects.Add(activateClass);
  238. string EffectDescription()
  239. => "[Main] Delete 1 of your opponent's highest level Digimon. Then, you may place 1 [Three Musketeer] trait card from your hand or trash as any of your Digimon's bottom digivolution card.";
  240. bool CanUseCondition(Hashtable hashtable)
  241. => CardEffectCommons.CanTriggerOptionMainEffect(hashtable, card);
  242. bool IsStrongestEnemy(Permanent permanent)
  243. => CardEffectCommons.IsMaxLevel(permanent, card.Owner.Enemy);
  244. bool CanSelectCardCondition(CardSource cardSource)
  245. => cardSource.EqualsTraits("Three Musketeers");
  246. bool CanSelectPermamentCondition(Permanent permanent)
  247. => CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card);
  248. IEnumerator ActivateCoroutine(Hashtable _hashtable)
  249. {
  250. if (CardEffectCommons.HasMatchConditionOpponentsPermanent(card, IsStrongestEnemy))
  251. {
  252. SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
  253. selectPermanentEffect.SetUp(
  254. selectPlayer: card.Owner,
  255. canTargetCondition: IsStrongestEnemy,
  256. canTargetCondition_ByPreSelecetedList: null,
  257. canEndSelectCondition: null,
  258. maxCount: 1,
  259. canNoSelect: false,
  260. canEndNotMax: false,
  261. selectPermanentCoroutine: null,
  262. afterSelectPermanentCoroutine: null,
  263. mode: SelectPermanentEffect.Mode.Destroy,
  264. cardEffect: activateClass);
  265. yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
  266. }
  267. if(CardEffectCommons.HasMatchConditionOwnersPermanent(card, CanSelectPermamentCondition))
  268. {
  269. bool canSelectHand = CardEffectCommons.HasMatchConditionOwnersHand(card, CanSelectCardCondition);
  270. bool canSelectTrash = CardEffectCommons.HasMatchConditionOwnersCardInTrash(card, CanSelectCardCondition);
  271. if (canSelectHand || canSelectTrash)
  272. {
  273. #region Setup Location Selection
  274. List<SelectionElement<int>> selectionElements = new List<SelectionElement<int>>();
  275. if (canSelectHand)
  276. {
  277. selectionElements.Add(new(message: $"From hand", value: 1, spriteIndex: 0));
  278. }
  279. if (canSelectTrash)
  280. {
  281. selectionElements.Add(new(message: $"From trash", value: 2, spriteIndex: 0));
  282. }
  283. selectionElements.Add(new(message: $"Do not place a card", value: 3, spriteIndex: 1));
  284. string selectPlayerMessage = "From which area will you place a card to digivolution cards?";
  285. string notSelectPlayerMessage = "The opponent is choosing from which area to select a card.";
  286. GManager.instance.userSelectionManager.SetIntSelection(selectionElements: selectionElements, selectPlayer: card.Owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
  287. yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
  288. #endregion
  289. bool doPlace = GManager.instance.userSelectionManager.SelectedIntValue != 3;
  290. bool fromHand = GManager.instance.userSelectionManager.SelectedIntValue == 1;
  291. if (doPlace)
  292. {
  293. if (fromHand)
  294. {
  295. SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
  296. selectHandEffect.SetUp(
  297. selectPlayer: card.Owner,
  298. canTargetCondition: CanSelectCardCondition,
  299. canTargetCondition_ByPreSelecetedList: null,
  300. canEndSelectCondition: null,
  301. maxCount: 1,
  302. canNoSelect: true,
  303. canEndNotMax: false,
  304. isShowOpponent: true,
  305. selectCardCoroutine: SelectCardCoroutine,
  306. afterSelectCardCoroutine: null,
  307. mode: SelectHandEffect.Mode.Custom,
  308. cardEffect: activateClass);
  309. selectHandEffect.SetUpCustomMessage("Select a [Three Musketeers] card to place under 1 of your Digimon.", "Opponent is selecting a card to place.");
  310. yield return StartCoroutine(selectHandEffect.Activate());
  311. }
  312. else
  313. {
  314. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  315. selectCardEffect.SetUp(
  316. canTargetCondition: CanSelectCardCondition,
  317. canTargetCondition_ByPreSelecetedList: null,
  318. canEndSelectCondition: null,
  319. canNoSelect: () => true,
  320. selectCardCoroutine: SelectCardCoroutine,
  321. afterSelectCardCoroutine: null,
  322. message: "Select 1 card to place.",
  323. maxCount: 1,
  324. canEndNotMax: false,
  325. isShowOpponent: true,
  326. mode: SelectCardEffect.Mode.Custom,
  327. root: SelectCardEffect.Root.Trash,
  328. customRootCardList: null,
  329. canLookReverseCard: true,
  330. selectPlayer: card.Owner,
  331. cardEffect: activateClass);
  332. selectCardEffect.SetUpCustomMessage("Select a [Three Musketeers] card to place under 1 of your Digimon.", "Opponent is selecting a card to place.");
  333. yield return StartCoroutine(selectCardEffect.Activate());
  334. }
  335. IEnumerator SelectCardCoroutine(CardSource cardSource)
  336. {
  337. SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
  338. selectPermanentEffect.SetUp(
  339. selectPlayer: card.Owner,
  340. canTargetCondition: CanSelectPermamentCondition,
  341. canTargetCondition_ByPreSelecetedList: null,
  342. canEndSelectCondition: null,
  343. maxCount: 1,
  344. canNoSelect: true,
  345. canEndNotMax: false,
  346. selectPermanentCoroutine: SelectPermanentCoroutine,
  347. afterSelectPermanentCoroutine: null,
  348. mode: SelectPermanentEffect.Mode.Custom,
  349. cardEffect: activateClass);
  350. selectPermanentEffect.SetUpCustomMessage("Select 1 digimon to place card underneath", "The opponent is selecting 1 digimon to place card underneath");
  351. yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
  352. IEnumerator SelectPermanentCoroutine(Permanent permanent)
  353. {
  354. if (permanent != null)
  355. {
  356. yield return ContinuousController.instance.StartCoroutine(permanent.AddDigivolutionCardsBottom(new List<CardSource>() { cardSource }, activateClass));
  357. }
  358. }
  359. }
  360. }
  361. }
  362. }
  363. }
  364. }
  365. #endregion
  366. #region Arts Digivolution
  367. if (timing == EffectTiming.None)
  368. {
  369. cardEffects.Add(CardEffectFactory.ArtsDigivolveEffect(card));
  370. }
  371. #endregion
  372. #endregion
  373. return cardEffects;
  374. }
  375. }
  376. }