DNADigivolveEffects.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Linq;
  5. using Photon;
  6. using System;
  7. using Photon.Pun;
  8. public partial class CardEffectCommons
  9. {
  10. #region DNA With Hand Or Trash Card into Hand or Trash Card
  11. /// <summary>
  12. /// Creates a temporary permanent. Calling method can later ensure clear the frame
  13. /// </summary>
  14. /// <param name="card">Card to make a permanent of</param>
  15. /// <param name="finalCard">If true, CardObjectController will be used to more properly create the permanent so it works fully with the jogress, so this will not place the permanent into any frames</param>
  16. /// <returns>The created Permanent</returns>
  17. private static Permanent PlayTempPermanent(CardSource card, bool finalCard = false)
  18. {
  19. Permanent playedPermanent;
  20. if (card != null)
  21. {
  22. int frameID = card.PreferredFrame().FrameID;
  23. if (0 <= frameID && frameID < card.Owner.fieldCardFrames.Count)
  24. {
  25. playedPermanent = new Permanent(new List<CardSource>() { card }) { IsSuspended = false };
  26. if (!finalCard)
  27. {
  28. card.Owner.FieldPermanents[frameID] = playedPermanent;
  29. }
  30. return playedPermanent;
  31. }
  32. }
  33. return null;
  34. }
  35. /// <summary>
  36. /// Check for if a cardSource can meet the jogress requirements of another given card
  37. /// </summary>
  38. /// <param name="cardSource">The Card to verify if it is a potential jogress root</param>
  39. /// <param name="jogressTarget">Card that will be DNA digivolved into</param>
  40. /// <param name="firstCondition">If the first root has already been found, it is passed here so we only check if this card can fulfill the second root. Otherwise we check if this card can fulfill the first root and some permanent can fulfill the second</param>
  41. /// <param name="permanentCondition">Condition to filter which permaments may be used for this effect</param>
  42. /// <param name="cardCondition">Condition to filter which cards may be used for this effect</param>
  43. /// <returns></returns>
  44. private static bool CardFulfillsRequirement(Player owner, CardSource cardSource, CardSource jogressTarget, Permanent firstCondition, Func<Permanent, bool> permanentCondition = null, Func<CardSource, bool> cardCondition = null)
  45. {
  46. if (jogressTarget.jogressCondition.Count <= 0)
  47. return false;
  48. bool isValid = false;
  49. if(cardCondition == null || cardCondition(cardSource))
  50. {
  51. Permanent tempPermanent = PlayTempPermanent(cardSource);
  52. if (tempPermanent == null)
  53. return false;
  54. if (firstCondition == null)
  55. {
  56. foreach (JogressCondition DNACondition in jogressTarget.jogressCondition)
  57. {
  58. if(isValid)
  59. break;
  60. if (DNACondition.elements[0].EvoRootCondition(tempPermanent))
  61. {
  62. foreach(Permanent secondPermanent in owner.GetBattleAreaDigimons().Filter(permanent => permanentCondition == null || permanentCondition(permanent)))
  63. {
  64. if (secondPermanent == tempPermanent)
  65. continue;
  66. if(DNACondition.elements[1].EvoRootCondition(secondPermanent))
  67. {
  68. isValid = true;
  69. break;
  70. }
  71. }
  72. }
  73. }
  74. }
  75. else
  76. {
  77. foreach (JogressCondition DNACondition in jogressTarget.jogressCondition)
  78. {
  79. if (DNACondition.elements[0].EvoRootCondition(firstCondition) && DNACondition.elements[1].EvoRootCondition(tempPermanent))
  80. {
  81. isValid = true;
  82. break;
  83. }
  84. }
  85. }
  86. owner.FieldPermanents[tempPermanent.PermanentFrame.FrameID] = null;
  87. }
  88. return isValid;
  89. }
  90. private static IEnumerator SelectHandCard(Player owner, CardSource jogressTarget, Permanent firstCondition, bool isOptional, ICardEffect activateClass, Func<CardSource, IEnumerator> SelectCardCoroutine, Func<Permanent, bool> permanentCondition = null, Func<CardSource, bool> digivolutionCardCondition = null)
  91. {
  92. SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
  93. selectHandEffect.SetUp(
  94. selectPlayer: owner,
  95. canTargetCondition: cardSource => CardFulfillsRequirement(owner, cardSource, jogressTarget, firstCondition, permanentCondition, digivolutionCardCondition),
  96. canTargetCondition_ByPreSelecetedList: null,
  97. canEndSelectCondition: null,
  98. maxCount: 1,
  99. canNoSelect: isOptional,
  100. canEndNotMax: false,
  101. isShowOpponent: true,
  102. selectCardCoroutine: SelectCardCoroutine,
  103. afterSelectCardCoroutine: null,
  104. mode: SelectHandEffect.Mode.Custom,
  105. cardEffect: activateClass);
  106. selectHandEffect.SetUpCustomMessage("Select 1 Digimon to DNA digivolve.", "The opponent is selecting DNA digivolution cards.");
  107. selectHandEffect.SetNotShowCard();
  108. yield return ContinuousController.instance.StartCoroutine(selectHandEffect.Activate());
  109. }
  110. private static IEnumerator SelectTrashCard(Player owner, CardSource jogressTarget, Permanent firstCondition, bool isOptional, ICardEffect activateClass, Func<CardSource, IEnumerator> SelectCardCoroutine, Func<Permanent, bool> permanentCondition = null, Func<CardSource, bool> digivolutionCardCondition = null)
  111. {
  112. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  113. selectCardEffect.SetUp(
  114. canTargetCondition: cardSource => CardFulfillsRequirement(owner, cardSource, jogressTarget, firstCondition, permanentCondition, digivolutionCardCondition),
  115. canTargetCondition_ByPreSelecetedList: null,
  116. canEndSelectCondition: null,
  117. canNoSelect: () => isOptional,
  118. selectCardCoroutine: SelectCardCoroutine,
  119. afterSelectCardCoroutine: null,
  120. message: "Select 1 Digimon to DNA digivolve.",
  121. maxCount: 1,
  122. canEndNotMax: false,
  123. isShowOpponent: false,
  124. mode: SelectCardEffect.Mode.Custom,
  125. root: SelectCardEffect.Root.Trash,
  126. customRootCardList: null,
  127. canLookReverseCard: true,
  128. selectPlayer: owner,
  129. cardEffect: activateClass);
  130. selectCardEffect.SetNotShowCard();
  131. selectCardEffect.SetNotAddLog();
  132. yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
  133. }
  134. /// <summary>
  135. /// Check for if a permanent can meet the jogress requirements of another given card.
  136. /// </summary>
  137. /// <param name="permanent">The Permanent to verify if it is a potential jogress root</param>
  138. /// <param name="jogressTarget">Card that will be DNA digivolved into</param>
  139. /// <param name="firstCondition">If the first root has already been found, it is passed here so we only check if this permanent can fulfill the second root. Otherwise we check if this permanent can fulfill the first root and some card can fulfill the second</param>
  140. /// <param name="isWithHand">If the cardsource for the second condition is coming form hand, otherwise it will be taken from trash</param>
  141. /// <param name="permanentCondition">Condition to filter which permaments may be used for this effect</param>
  142. /// <param name="cardCondition">Condition to filter which cards may be used for this effect</param>
  143. /// <returns></returns>
  144. private static bool PermanentFulfillsRequirement(Player owner, Permanent permanent, CardSource jogressTarget, Permanent firstCondition, bool isWithHandCard, Func<Permanent, bool> permanentCondition = null, Func<CardSource, bool> cardCondition = null)
  145. {
  146. if (jogressTarget.jogressCondition.Count <= 0 || jogressTarget.CanNotEvolve(permanent))
  147. return false;
  148. if(permanentCondition == null || permanentCondition(permanent))
  149. {
  150. if (firstCondition == null)
  151. {
  152. foreach (JogressCondition DNACondition in jogressTarget.jogressCondition)
  153. {
  154. if (DNACondition.elements[0].EvoRootCondition(permanent))
  155. {
  156. List<CardSource> sources = isWithHandCard ? owner.HandCards : owner.TrashCards;
  157. foreach(CardSource cardSource in sources.Filter(cardSource => cardCondition == null || cardCondition(cardSource)))
  158. {
  159. Permanent tempPermanent = PlayTempPermanent(cardSource);
  160. if (tempPermanent == null)
  161. continue;
  162. bool isValid = DNACondition.elements[1].EvoRootCondition(tempPermanent);
  163. owner.FieldPermanents[tempPermanent.PermanentFrame.FrameID] = null;
  164. if(isValid)
  165. return true;
  166. }
  167. }
  168. }
  169. }
  170. else
  171. {
  172. if (permanent == firstCondition)
  173. {
  174. return false;
  175. }
  176. foreach (JogressCondition DNACondition in jogressTarget.jogressCondition)
  177. {
  178. if (DNACondition.elements[0].EvoRootCondition(firstCondition) && DNACondition.elements[1].EvoRootCondition(permanent))
  179. {
  180. return true;
  181. }
  182. }
  183. }
  184. }
  185. return false;
  186. }
  187. private static IEnumerator SelectPermanent(Player owner, CardSource jogressTarget, Permanent firstCondition, bool isOptional, ICardEffect activateClass, bool isWithHand, Func<Permanent, IEnumerator> SelectPermanentCoroutine, Func<Permanent, bool> permanentCondition = null, Func<CardSource, bool> digivolutionCardCondition = null)
  188. {
  189. SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
  190. selectPermanentEffect.SetUp(
  191. selectPlayer: owner,
  192. canTargetCondition: permanent => PermanentFulfillsRequirement(owner, permanent, jogressTarget, firstCondition, isWithHand, permanentCondition, digivolutionCardCondition),
  193. canTargetCondition_ByPreSelecetedList: null,
  194. canEndSelectCondition: null,
  195. maxCount: 1,
  196. canNoSelect: isOptional,
  197. canEndNotMax: false,
  198. selectPermanentCoroutine: SelectPermanentCoroutine,
  199. afterSelectPermanentCoroutine: null,
  200. mode: SelectPermanentEffect.Mode.Custom,
  201. cardEffect: activateClass);
  202. selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon to DNA digivolve.", "The opponent is selecting 1 Digimon to DNA digivolve.");
  203. yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
  204. }
  205. public static bool CanJogressWithHandOrTrash(CardSource source, Player owner, bool isWithHandCard, bool isIntoHandCard, Func<CardSource, bool> targetCardCondition = null, Func<Permanent, bool> permanentCondition = null, Func<CardSource, bool> digivolutionCardCondition = null)
  206. {
  207. return (isIntoHandCard ? IsExistOnHand(source) : IsExistOnTrash(source))
  208. && (targetCardCondition == null || targetCardCondition(source))
  209. && source.jogressCondition.Count > 0
  210. && (HasMatchConditionPermanent(permanent => PermanentFulfillsRequirement(owner, permanent, source, null, isWithHandCard, permanentCondition, digivolutionCardCondition))
  211. || (isWithHandCard ?
  212. owner.HandCards.Some(cardSource => CardFulfillsRequirement(owner, cardSource, source, null, permanentCondition, digivolutionCardCondition)) :
  213. owner.TrashCards.Some(cardSource => CardFulfillsRequirement(owner, cardSource, source, null, permanentCondition, digivolutionCardCondition))));
  214. }
  215. /// <summary>
  216. /// Method that allows the user to DNA digivolve a Permanent on the field with a card in hand or trash as the other DNA root into a card in the hand or trash
  217. /// </summary>
  218. /// <param name="targetCardCondition">CardCondition for the digimon that will be DNA Digivolved into</param>
  219. /// <param name="permanentCondition">PermanentCondition for the permanent which will make one of the roots</param>
  220. /// <param name="digivolutionCardCondition">CardCondition for the card that will become one of the roots</param>
  221. /// <param name="payCost">If the pay cost for the digivolution must be payed</param>
  222. /// <param name="isWithHandCard">If the card that will a root is coming from the Hand, if false it comes from trash</param>
  223. /// <param name="isIntoHandCard">If the card to be DNA digivolved into is coming from hand, if false it comes from trash</param>
  224. /// <param name="activateClass">ActivateClass for the effect causing this DNA Digivolution</param>
  225. /// <param name="successProcess">IEnumerator to run on success</param>
  226. /// <param name="failedProcess">IEnumerator to run on failure</param>
  227. /// <param name="isOptional">If this effect is optional. If true, the user may no select at any time</param>
  228. /// <returns></returns>
  229. public static IEnumerator DNADigivolveWithHandOrTrashCardIntoHandOrTrash(
  230. Func<CardSource, bool> targetCardCondition,
  231. Func<Permanent, bool> permanentCondition,
  232. Func<CardSource, bool> digivolutionCardCondition,
  233. bool payCost,
  234. bool isWithHandCard,
  235. bool isIntoHandCard,
  236. ICardEffect activateClass,
  237. IEnumerator successProcess,
  238. bool ignoreSelection = false,
  239. IEnumerator failedProcess = null,
  240. bool isOptional = true)
  241. {
  242. CardSource dnaTarget = null;
  243. Permanent selectedPermanent = null;
  244. CardSource selectedCardSource = null;
  245. Permanent playedPermanent = null;
  246. Player owner = activateClass.EffectSourceCard.Owner;
  247. IEnumerator SelectDNACardCoroutine(CardSource source)
  248. {
  249. dnaTarget = source;
  250. yield return null;
  251. }
  252. IEnumerator SelectPermanentCoroutine(Permanent permanent)
  253. {
  254. selectedPermanent = permanent;
  255. yield return null;
  256. }
  257. IEnumerator SelectCardCoroutine(CardSource cardSource)
  258. {
  259. selectedCardSource = cardSource;
  260. yield return null;
  261. }
  262. if(ignoreSelection)
  263. {
  264. dnaTarget = activateClass.EffectSourceCard;
  265. }
  266. else if (isIntoHandCard && owner.HandCards.Some(cardSource => CanJogressWithHandOrTrash(cardSource, owner, isWithHandCard, isIntoHandCard, targetCardCondition, permanentCondition, digivolutionCardCondition)))
  267. {
  268. SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
  269. selectHandEffect.SetUp(
  270. selectPlayer: owner,
  271. canTargetCondition: cardSource => CanJogressWithHandOrTrash(cardSource, owner, isWithHandCard, isIntoHandCard, targetCardCondition, permanentCondition, digivolutionCardCondition),
  272. canTargetCondition_ByPreSelecetedList: null,
  273. canEndSelectCondition: null,
  274. maxCount: 1,
  275. canNoSelect: isOptional,
  276. canEndNotMax: false,
  277. isShowOpponent: true,
  278. selectCardCoroutine: SelectDNACardCoroutine,
  279. afterSelectCardCoroutine: null,
  280. mode: SelectHandEffect.Mode.Custom,
  281. cardEffect: activateClass);
  282. selectHandEffect.SetUpCustomMessage("Select 1 Digimon to DNA digivolve.", "The opponent is selecting 1 Digimon to DNA digivolve.");
  283. yield return ContinuousController.instance.StartCoroutine(selectHandEffect.Activate());
  284. }
  285. else if (!isIntoHandCard && owner.TrashCards.Some(cardSource => CanJogressWithHandOrTrash(cardSource, owner, isWithHandCard, isIntoHandCard, targetCardCondition, permanentCondition, digivolutionCardCondition)))
  286. {
  287. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  288. selectCardEffect.SetUp(
  289. canTargetCondition: cardSource => CanJogressWithHandOrTrash(cardSource, owner, isWithHandCard, isIntoHandCard, targetCardCondition, permanentCondition, digivolutionCardCondition),
  290. canTargetCondition_ByPreSelecetedList: null,
  291. canEndSelectCondition: null,
  292. canNoSelect: () => isOptional,
  293. selectCardCoroutine: SelectDNACardCoroutine,
  294. afterSelectCardCoroutine: null,
  295. message: "Select 1 Digimon to DNA digivolve.",
  296. maxCount: 1,
  297. canEndNotMax: false,
  298. isShowOpponent: false,
  299. mode: SelectCardEffect.Mode.Custom,
  300. root: SelectCardEffect.Root.Trash,
  301. customRootCardList: null,
  302. canLookReverseCard: true,
  303. selectPlayer: owner,
  304. cardEffect: activateClass);
  305. selectCardEffect.SetNotShowCard();
  306. selectCardEffect.SetNotAddLog();
  307. yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
  308. }
  309. if (dnaTarget == null)
  310. yield break;
  311. bool validPermanent = HasMatchConditionPermanent(permanent => PermanentFulfillsRequirement(owner, permanent, dnaTarget, null, isWithHandCard, permanentCondition, digivolutionCardCondition));
  312. bool validHandOrTrash = isWithHandCard ?
  313. owner.HandCards.Some(cardSource => CardFulfillsRequirement(owner, cardSource, dnaTarget, null, permanentCondition, digivolutionCardCondition)) :
  314. owner.TrashCards.Some(cardSource => CardFulfillsRequirement(owner, cardSource, dnaTarget, null, permanentCondition, digivolutionCardCondition));
  315. if(validPermanent || validHandOrTrash)
  316. {
  317. #region select source cards
  318. if (validPermanent && validHandOrTrash)
  319. {
  320. List<SelectionElement<bool>> selectionElements = new List<SelectionElement<bool>>()
  321. {
  322. new SelectionElement<bool>(message: $"From Battle Area", value : true, spriteIndex: 0),
  323. new SelectionElement<bool>(message: isWithHandCard ? $"From Hand" : $"From Trash", value : false, spriteIndex: 1),
  324. };
  325. string selectPlayerMessage = "From where will you select the first digimon?";
  326. string notSelectPlayerMessage = "The opponent is selecting 1 Digimon to DNA digivolve.";
  327. GManager.instance.userSelectionManager.SetBoolSelection(selectionElements: selectionElements, selectPlayer: owner, selectPlayerMessage: selectPlayerMessage, notSelectPlayerMessage: notSelectPlayerMessage);
  328. }
  329. else
  330. {
  331. GManager.instance.userSelectionManager.SetBool(validPermanent);
  332. }
  333. yield return ContinuousController.instance.StartCoroutine(GManager.instance.userSelectionManager.WaitForEndSelect());
  334. bool isPermanentFirst = GManager.instance.userSelectionManager.SelectedBoolValue;
  335. if (isPermanentFirst)
  336. {
  337. yield return ContinuousController.instance.StartCoroutine(SelectPermanent(owner, dnaTarget, null, isOptional, activateClass, isWithHandCard, SelectPermanentCoroutine, permanentCondition, digivolutionCardCondition));
  338. if (selectedPermanent != null)
  339. {
  340. if (isWithHandCard)
  341. yield return ContinuousController.instance.StartCoroutine(SelectHandCard(owner, dnaTarget, selectedPermanent, isOptional, activateClass, SelectCardCoroutine, permanentCondition, digivolutionCardCondition));
  342. else
  343. yield return ContinuousController.instance.StartCoroutine(SelectTrashCard(owner, dnaTarget, selectedPermanent, isOptional, activateClass, SelectCardCoroutine, permanentCondition, digivolutionCardCondition));
  344. if (selectedCardSource != null)
  345. {
  346. playedPermanent = PlayTempPermanent(selectedCardSource, true);
  347. if (playedPermanent != null) yield return ContinuousController.instance.StartCoroutine(CardObjectController.CreateNewPermanent(playedPermanent, selectedCardSource.PreferredFrame().FrameID));
  348. }
  349. }
  350. }
  351. else
  352. {
  353. if (isWithHandCard)
  354. yield return ContinuousController.instance.StartCoroutine(SelectHandCard(owner, dnaTarget, null, isOptional, activateClass, SelectCardCoroutine, permanentCondition, digivolutionCardCondition));
  355. else
  356. yield return ContinuousController.instance.StartCoroutine(SelectTrashCard(owner, dnaTarget, null, isOptional, activateClass, SelectCardCoroutine, permanentCondition, digivolutionCardCondition));
  357. if(selectedCardSource != null)
  358. {
  359. playedPermanent = PlayTempPermanent(selectedCardSource, true);
  360. if (playedPermanent != null)
  361. {
  362. yield return ContinuousController.instance.StartCoroutine(CardObjectController.CreateNewPermanent(playedPermanent, selectedCardSource.PreferredFrame().FrameID));
  363. yield return ContinuousController.instance.StartCoroutine(SelectPermanent(owner, dnaTarget, playedPermanent, isOptional, activateClass, isWithHandCard, SelectPermanentCoroutine, permanentCondition, digivolutionCardCondition));
  364. }
  365. }
  366. }
  367. #endregion
  368. if (selectedPermanent != null && playedPermanent != null)
  369. {
  370. List<Permanent> orderedRoots = isPermanentFirst ? new List<Permanent>() { selectedPermanent, playedPermanent } : new List<Permanent>() { playedPermanent, selectedPermanent };
  371. int[] JogressEvoRootsFrameIDs = orderedRoots.Map(permanent => permanent.PermanentFrame.FrameID).ToArray();
  372. if (dnaTarget.CanJogressFromTargetPermanents(orderedRoots, payCost))
  373. {
  374. PlayCardClass playCard = new PlayCardClass(
  375. cardSources: new List<CardSource>() { dnaTarget },
  376. hashtable: CardEffectCommons.CardEffectHashtable(activateClass),
  377. payCost: payCost,
  378. targetPermanent: null,
  379. isTapped: false,
  380. root: isIntoHandCard ? SelectCardEffect.Root.Hand : SelectCardEffect.Root.Trash,
  381. activateETB: true);
  382. playCard.SetJogress(JogressEvoRootsFrameIDs);
  383. yield return ContinuousController.instance.StartCoroutine(playCard.PlayCard());
  384. }
  385. }
  386. }
  387. if (dnaTarget == null || dnaTarget.PermanentOfThisCard() == null)
  388. {
  389. if (playedPermanent != null)
  390. {
  391. if (isWithHandCard)
  392. yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddHandCard(selectedCardSource, false));
  393. else
  394. yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(selectedCardSource));
  395. }
  396. }
  397. }
  398. #endregion
  399. #region digivolve Permanents on Field into Hand or Trash Card
  400. public static IEnumerator DNADigivolvePermanentsIntoHandOrTrashCard(
  401. Func<CardSource, bool> canSelectDNACardCondition,
  402. bool payCost,
  403. bool isHand,
  404. ICardEffect activateClass,
  405. Func<Permanent, bool>[] permanentConditions = null,
  406. Func<CardSource, IEnumerator> successProcess = null,
  407. bool ignoreSelection = false,
  408. Func<IEnumerator> failedProcess = null,
  409. bool isOptional = true)
  410. {
  411. Player owner = activateClass.EffectSourceCard.Owner;
  412. CardSource dnaTarget = null;
  413. const int DnaPermanentCount = 2;
  414. IEnumerator SelectCardCoroutine(CardSource cardSource)
  415. {
  416. dnaTarget = cardSource;
  417. yield return null;
  418. }
  419. //bool CanJogressCondition(CardSource cardSource)
  420. //{
  421. // return (canSelectDNACardCondition == null || canSelectDNACardCondition(cardSource))
  422. // && cardSource.CanPlayJogress(true);
  423. //}
  424. if (owner.GetBattleAreaDigimons().Count < DnaPermanentCount)
  425. {
  426. yield return ContinuousController.instance.StartCoroutine(failedProcess());
  427. yield break;
  428. }
  429. int maxCount = 1;
  430. if (ignoreSelection)
  431. {
  432. dnaTarget = activateClass.EffectSourceCard;
  433. }
  434. else if (isHand && owner.HandCards.Some(canSelectDNACardCondition))
  435. {
  436. SelectHandEffect selectHandEffect = GManager.instance.GetComponent<SelectHandEffect>();
  437. selectHandEffect.SetUp(
  438. selectPlayer: owner,
  439. canTargetCondition: canSelectDNACardCondition,
  440. canTargetCondition_ByPreSelecetedList: null,
  441. canEndSelectCondition: null,
  442. maxCount: maxCount,
  443. canNoSelect: isOptional,
  444. canEndNotMax: false,
  445. isShowOpponent: true,
  446. selectCardCoroutine: SelectCardCoroutine,
  447. afterSelectCardCoroutine: null,
  448. mode: SelectHandEffect.Mode.Custom,
  449. cardEffect: activateClass);
  450. selectHandEffect.SetUpCustomMessage("Select 1 card to DNA digivolve.", "The opponent is selecting 1 card to DNA digivolve.");
  451. selectHandEffect.SetNotShowCard();
  452. yield return ContinuousController.instance.StartCoroutine(selectHandEffect.Activate());
  453. }
  454. else if(!isHand && owner.TrashCards.Some(canSelectDNACardCondition))
  455. {
  456. SelectCardEffect selectCardEffect = GManager.instance.GetComponent<SelectCardEffect>();
  457. selectCardEffect.SetUp(
  458. canTargetCondition: canSelectDNACardCondition,
  459. canTargetCondition_ByPreSelecetedList: null,
  460. canEndSelectCondition: null,
  461. canNoSelect: () => isOptional,
  462. selectCardCoroutine: SelectCardCoroutine,
  463. afterSelectCardCoroutine: null,
  464. message: "Select 1 card to digivolve.",
  465. maxCount: maxCount,
  466. canEndNotMax: false,
  467. isShowOpponent: true,
  468. mode: SelectCardEffect.Mode.Custom,
  469. root: SelectCardEffect.Root.Trash,
  470. customRootCardList: null,
  471. canLookReverseCard: true,
  472. selectPlayer: owner,
  473. cardEffect: activateClass);
  474. selectCardEffect.SetUpCustomMessage("Select 1 card to DNA digivolve.", "The opponent is selecting 1 card to DNA digivolve.");
  475. selectCardEffect.SetUpCustomMessage_ShowCard("Selected Card");
  476. yield return ContinuousController.instance.StartCoroutine(selectCardEffect.Activate());
  477. }
  478. bool processSuccessful = false;
  479. if (dnaTarget != null)
  480. {
  481. Component component = activateClass.EffectSourceCard.cEntity_EffectController.gameObject.AddComponent(typeof (SetJogressEvoRootsController));
  482. SetJogressEvoRootsController controller = (SetJogressEvoRootsController)component;
  483. int[] _jogressEvoRootsFrameIDs = new int[0];
  484. yield return GManager.instance.photonWaitController.StartWait("DNA_Digivolve_by_Effect");
  485. if (owner.isYou || GManager.instance.IsAI)
  486. {
  487. GManager.instance.selectJogressEffect.SetUp_SelectDigivolutionRoots
  488. (card: dnaTarget,
  489. isLocal: true,
  490. isPayCost: true,
  491. canNoSelect: true,
  492. endSelectCoroutine_SelectDigivolutionRoots: EndSelectCoroutine_SelectDigivolutionRoots,
  493. noSelectCoroutine: null);
  494. if(permanentConditions != null)
  495. GManager.instance.selectJogressEffect.SetUpCustomPermanentConditions(permanentConditions);
  496. yield return ContinuousController.instance.StartCoroutine(GManager.instance.selectJogressEffect.SelectDigivolutionRoots());
  497. IEnumerator EndSelectCoroutine_SelectDigivolutionRoots(List<Permanent> permanents)
  498. {
  499. if (permanents.Count == DnaPermanentCount)
  500. {
  501. _jogressEvoRootsFrameIDs = permanents.Distinct().ToArray().Map(permanent => permanent.PermanentFrame.FrameID);
  502. }
  503. yield return null;
  504. }
  505. controller.photonView.RPC("SetJogressEvoRootsFrameIDs", RpcTarget.All, _jogressEvoRootsFrameIDs);
  506. }
  507. else
  508. {
  509. GManager.instance.commandText.OpenCommandText("The opponent is choosing a card to DNA digivolve.");
  510. }
  511. yield return new WaitWhile(() => !controller.EndSelect);
  512. controller.EndSelect = false;
  513. GManager.instance.commandText.CloseCommandText();
  514. yield return new WaitWhile(() => GManager.instance.commandText.gameObject.activeSelf);
  515. if (controller.JogressEvoRootsFrameIDs.Length == DnaPermanentCount)
  516. {
  517. yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { dnaTarget }, "Played Card", true, true));
  518. PlayCardClass playCard = new PlayCardClass(
  519. cardSources: new List<CardSource>() { dnaTarget },
  520. hashtable: CardEffectCommons.CardEffectHashtable(activateClass),
  521. payCost: true,
  522. targetPermanent: null,
  523. isTapped: false,
  524. root: isHand ? SelectCardEffect.Root.Hand : SelectCardEffect.Root.Trash,
  525. activateETB: true);
  526. playCard.SetJogress(controller.JogressEvoRootsFrameIDs);
  527. yield return ContinuousController.instance.StartCoroutine(playCard.PlayCard());
  528. processSuccessful = CardEffectCommons.IsExistOnBattleArea(dnaTarget);
  529. }
  530. }
  531. if (processSuccessful && successProcess != null)
  532. {
  533. yield return ContinuousController.instance.StartCoroutine(successProcess(dnaTarget));
  534. }
  535. else if (!processSuccessful && failedProcess != null)
  536. {
  537. yield return ContinuousController.instance.StartCoroutine(failedProcess());
  538. }
  539. }
  540. #endregion
  541. #region Create Jogress Conditions from Permanent Conditions
  542. public static JogressCondition GetJogressConditions(Func<Permanent, bool> permanentCondition1, string description1, Func<Permanent, bool> permanentCondition2, string description2, CardSource card, int cost = 0)
  543. {
  544. JogressConditionElement[] elements =
  545. {
  546. new JogressConditionElement(permanentCondition1, description1),
  547. new JogressConditionElement(permanentCondition2, description2)
  548. };
  549. JogressCondition jogressCondition = new (elements, cost);
  550. return jogressCondition;
  551. //bool PermanentCondition(Permanent permanent)
  552. //{
  553. // return permanent != null
  554. // && permanent.TopCard != null
  555. // && permanent.TopCard.Owner == card.Owner
  556. // && permanent.IsDigimon
  557. // && CardEffectCommons.IsPermanentExistsOnOwnerBattleAreaDigimon(permanent, card);
  558. //}
  559. //
  560. //bool FullPermanentCondition1(Permanent permanent) => PermanentCondition(permanent) && permanentCondition1 != null && permanentCondition1(permanent);
  561. //
  562. //bool FullPermanentCondition2(Permanent permanent) => PermanentCondition(permanent) && permanentCondition2 != null && permanentCondition2(permanent);
  563. }
  564. //Private class used to register the callback so this doesn't need to be defined in every card that uses DNA by effect
  565. private class SetJogressEvoRootsController : MonoBehaviourPunCallbacks
  566. {
  567. public bool EndSelect = false;
  568. public int[] JogressEvoRootsFrameIDs = new int[0];
  569. [PunRPC]
  570. public void SetJogressEvoRootsFrameIDs(int[] JogressEvoRootsFrameIDs)
  571. {
  572. this.JogressEvoRootsFrameIDs = JogressEvoRootsFrameIDs;
  573. EndSelect = true;
  574. }
  575. }
  576. #endregion
  577. }