AutoProcessing.cs 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. using Photon.Pun;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using UnityEngine;
  7. public class AutoProcessing : MonoBehaviourPunCallbacks
  8. {
  9. //Skill list before triggering and entering resolution timing
  10. public List<SkillInfo> StackedSkillInfos { get; set; } = new List<SkillInfo>();
  11. //Skill Processing Component List
  12. public List<MultipleSkills> multipleSkills = new List<MultipleSkills>();
  13. [SerializeField] bool SkipSameEffect;
  14. public List<SkillInfo> skipSkillInfos = new List<SkillInfo>();
  15. #region Available Skill Processing Component
  16. public MultipleSkills availableMultipleSkills
  17. {
  18. get
  19. {
  20. foreach (MultipleSkills _multipleSkills in multipleSkills)
  21. {
  22. if (!_multipleSkills.IsUsing)
  23. {
  24. return _multipleSkills;
  25. }
  26. }
  27. return null;
  28. }
  29. }
  30. #endregion
  31. #region Stack during effect processing
  32. public MultipleSkills executingMultipleSkills
  33. {
  34. get
  35. {
  36. for (int i = 0; i < multipleSkills.Count; i++)
  37. {
  38. if (multipleSkills[multipleSkills.Count - 1 - i].IsUsing)
  39. {
  40. return multipleSkills[multipleSkills.Count - 1 - i];
  41. }
  42. }
  43. return null;
  44. }
  45. }
  46. #endregion
  47. #region put the effect on the stack
  48. public void PutStackedSkill(SkillInfo skillInfo)
  49. {
  50. if (skillInfo == null) return;
  51. if (skillInfo.CardEffect == null) return;
  52. if (skillInfo.CardEffect.EffectSourceCard == null) return;
  53. if (!(skillInfo.CardEffect is ActivateICardEffect)) return;
  54. CardSource card = skillInfo.CardEffect.EffectSourceCard;
  55. Permanent permanent = card.PermanentOfThisCard();
  56. #region set the flag whether it is Digimon's effect
  57. if (permanent != null)
  58. {
  59. if (permanent.IsDigimon)
  60. {
  61. skillInfo.CardEffect.SetIsDigimonEffect(true);
  62. }
  63. }
  64. if (card == GManager.instance.attackProcess.SecurityDigimon)
  65. {
  66. skillInfo.CardEffect.SetIsDigimonEffect(true);
  67. }
  68. #endregion
  69. #region set the flag whether it is Tamer's effect
  70. if (permanent != null)
  71. {
  72. if (permanent.IsTamer)
  73. {
  74. skillInfo.CardEffect.SetIsTamerEffect(true);
  75. }
  76. }
  77. else if (card.IsTamer)
  78. {
  79. skillInfo.CardEffect.SetIsTamerEffect(true);
  80. }
  81. #endregion
  82. #region set permanent and topCard when triggered
  83. ((ActivateICardEffect)skillInfo.CardEffect).PermanentWhenTriggered = permanent;
  84. if (permanent != null)
  85. {
  86. ((ActivateICardEffect)skillInfo.CardEffect).TopCardWhenTriggered = permanent.TopCard;
  87. }
  88. #endregion
  89. StackedSkillInfos.Add(skillInfo);
  90. }
  91. #endregion
  92. #region Automated processing checks
  93. public IEnumerator AutoProcessCheck()
  94. {
  95. if (!GManager.instance.turnStateMachine.DoneStartGame) yield break;
  96. yield return ContinuousController.instance.StartCoroutine(ShrinkSecurityDigimonDisplay());
  97. GManager.instance.turnStateMachine.IsSelecting = true;
  98. GManager.instance.turnStateMachine.isSync = true;
  99. //Rule processing
  100. yield return ContinuousController.instance.StartCoroutine(RuleProcess());
  101. //Trigger effect processing
  102. yield return ContinuousController.instance.StartCoroutine(TriggeredSkillProcess(false, null));
  103. GManager.instance.turnStateMachine.IsSelecting = false;
  104. GManager.instance.turnStateMachine.isSync = false;
  105. }
  106. #endregion
  107. #region Rule processing
  108. public bool IsRuleProcessing { get; set; } = false;
  109. bool IsNotDigimonInBreeding(Permanent permanent)
  110. {
  111. if (permanent != null)
  112. {
  113. if (permanent.TopCard != null)
  114. {
  115. if (CardEffectCommons.IsExistOnBreedingArea(permanent.TopCard))
  116. {
  117. if (!permanent.IsDigimon)
  118. {
  119. return true;
  120. }
  121. }
  122. }
  123. }
  124. return false;
  125. }
  126. bool IsNotHavingDP(Permanent permanent)
  127. {
  128. if (permanent != null)
  129. {
  130. if (permanent.TopCard != null)
  131. {
  132. if (permanent.DP < 0)
  133. {
  134. if (permanent.IsPlaceToTrashDueToNotHavingDP)
  135. {
  136. if (permanent.IsDigimon)
  137. {
  138. return true;
  139. }
  140. if (permanent.TopCard.IsOption)
  141. {
  142. if (!permanent.IsPlayedOptionPermanent)
  143. {
  144. return true;
  145. }
  146. }
  147. }
  148. }
  149. }
  150. }
  151. return false;
  152. }
  153. bool IsDigimonLackDP(Permanent permanent)
  154. {
  155. if (permanent != null)
  156. {
  157. if (permanent.TopCard != null)
  158. {
  159. if (permanent.DP == 0)
  160. {
  161. if (permanent.IsDigimon)
  162. {
  163. if (permanent.CanBeDestroyed())
  164. {
  165. return true;
  166. }
  167. }
  168. }
  169. }
  170. }
  171. return false;
  172. }
  173. bool IsAttackerNotADigimon()
  174. {
  175. if (!GManager.instance.attackProcess.IsAttacking)
  176. return false;
  177. if (GManager.instance.attackProcess.AttackingPermanent != null)
  178. {
  179. if (!GManager.instance.attackProcess.AttackingPermanent.IsDigimon)
  180. return true;
  181. //if (GManager.instance.attackProcess.HasDefender && GManager.instance.attackProcess.DefendingPermanent == null)
  182. // return true;
  183. }
  184. return false;
  185. }
  186. bool IsDigimonLackLinkCondition(Permanent permanent)
  187. {
  188. if (permanent != null)
  189. {
  190. if (permanent.TopCard != null)
  191. {
  192. if (permanent.LinkedCards.Any(source => !source.CanLinkToTargetPermanent(permanent, false)))
  193. {
  194. return true;
  195. }
  196. }
  197. }
  198. return false;
  199. }
  200. bool IsDigimonLackLinkCount(Permanent permanent)
  201. {
  202. if (permanent != null)
  203. {
  204. if (permanent.TopCard != null)
  205. {
  206. if (permanent.LinkedCards.Count >= permanent.LinkedMax)
  207. {
  208. return true;
  209. }
  210. }
  211. }
  212. return false;
  213. }
  214. public IEnumerator RuleProcess()
  215. {
  216. while (DoRuleProcess())
  217. {
  218. IsRuleProcessing = true;
  219. //敗北処理
  220. yield return ContinuousController.instance.StartCoroutine(EndGameProcess());
  221. if (GManager.instance.turnStateMachine.endGame) yield break;
  222. //Trash Non Digimon from Breeding
  223. yield return ContinuousController.instance.StartCoroutine(TrashNonDigimonPermanentProcess());
  224. //DPを持たないカードをトラッシュする処理
  225. yield return ContinuousController.instance.StartCoroutine(TrashNoDPPermanentProcess());
  226. //DP不足処理
  227. yield return ContinuousController.instance.StartCoroutine(DigimonLackDPProcess());
  228. //Battle as Tamer
  229. yield return ContinuousController.instance.StartCoroutine(BattleWithoutDigimon());
  230. //Link Lacking condition
  231. yield return ContinuousController.instance.StartCoroutine(DigimonLackLinkConditionProcess());
  232. //TODO: Add link count correction
  233. IsRuleProcessing = false;
  234. }
  235. }
  236. #region Whether rule processing needs to be done
  237. bool DoRuleProcess()
  238. {
  239. if (IsRuleProcessing) return false;
  240. #region Whether it is necessary to perform game end processing
  241. if (GManager.instance.turnStateMachine.gameContext.Players.Count(player => player.IsLose) >= 1)
  242. {
  243. return true;
  244. }
  245. #endregion
  246. #region Is it necessary to discard cards in breeding?
  247. if (CardEffectCommons.HasMatchConditionPermanent(IsNotDigimonInBreeding, true))
  248. {
  249. return true;
  250. }
  251. #endregion
  252. #region Is it necessary to discard cards without DP?
  253. if (CardEffectCommons.HasMatchConditionPermanent(IsNotHavingDP))
  254. {
  255. return true;
  256. }
  257. #endregion
  258. #region Is it necessary to deal with Digimon's DP shortage?
  259. if (CardEffectCommons.HasMatchConditionPermanent(IsDigimonLackDP))
  260. {
  261. return true;
  262. }
  263. #endregion
  264. #region Is it necessary to deal with Battle Without Digimon?
  265. if (IsAttackerNotADigimon())
  266. {
  267. //return true;
  268. }
  269. #endregion
  270. #region Is it necessary to deal with Digimon's Link Cards?
  271. if (CardEffectCommons.HasMatchConditionPermanent(IsDigimonLackLinkCondition))
  272. {
  273. return true;
  274. }
  275. #endregion
  276. //TODO: Add link count condition
  277. return false;
  278. }
  279. #endregion
  280. #region Each rule processing
  281. #region Game end processing
  282. IEnumerator EndGameProcess()
  283. {
  284. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players)
  285. {
  286. if (player.IsLose)
  287. {
  288. if (!player.Enemy.IsLose)
  289. {
  290. GManager.instance.turnStateMachine.EndGame(player.Enemy, false);
  291. }
  292. else
  293. {
  294. GManager.instance.turnStateMachine.EndGame(null, false);
  295. }
  296. yield break;
  297. }
  298. }
  299. }
  300. #endregion
  301. #region Process of trashing cards in Breeding
  302. IEnumerator TrashNonDigimonPermanentProcess()
  303. {
  304. List<Permanent> BreedingPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
  305. .Map(player => player.GetBreedingAreaPermanents()
  306. .Filter(IsNotDigimonInBreeding)).Flat();
  307. if (BreedingPermanents.Count >= 1)
  308. {
  309. foreach (Permanent permanent in BreedingPermanents)
  310. {
  311. if (permanent != null)
  312. {
  313. if (permanent.TopCard != null)
  314. {
  315. yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
  316. CardSource cardSource = permanent.TopCard;
  317. yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { cardSource }, "Cards put to trash", true, true));
  318. yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
  319. yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
  320. }
  321. }
  322. }
  323. }
  324. }
  325. #endregion
  326. #region Process of trashing cards without DP
  327. IEnumerator TrashNoDPPermanentProcess()
  328. {
  329. List<Permanent> DigitamaPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
  330. .Map(player => player.GetBattleAreaPermanents()
  331. .Filter(IsNotHavingDP)).Flat();
  332. if (DigitamaPermanents.Count >= 1)
  333. {
  334. foreach (Permanent permanent in DigitamaPermanents)
  335. {
  336. if (permanent != null)
  337. {
  338. if (permanent.TopCard != null)
  339. {
  340. yield return ContinuousController.instance.StartCoroutine(permanent.DiscardEvoRoots());
  341. CardSource cardSource = permanent.TopCard;
  342. yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().ShowCardEffect(new List<CardSource>() { cardSource }, "Cards put to trash", true, true));
  343. yield return ContinuousController.instance.StartCoroutine(CardObjectController.RemoveField(permanent));
  344. yield return ContinuousController.instance.StartCoroutine(CardObjectController.AddTrashCard(cardSource));
  345. }
  346. }
  347. }
  348. }
  349. }
  350. #endregion
  351. #region Digimon DP shortage handling
  352. IEnumerator DigimonLackDPProcess()
  353. {
  354. List<Permanent> LackPowerPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
  355. .Map(player => player.GetFieldPermanents()
  356. .Filter(IsDigimonLackDP)).Flat();
  357. if (LackPowerPermanents.Count >= 1)
  358. {
  359. Hashtable hashtable = new Hashtable()
  360. {
  361. { "DPZero", true }
  362. };
  363. yield return ContinuousController.instance.StartCoroutine(new DestroyPermanentsClass(LackPowerPermanents, hashtable).Destroy());
  364. }
  365. }
  366. #endregion
  367. #region Battle Concerning Tamer
  368. IEnumerator BattleWithoutDigimon()
  369. {
  370. if(GManager.instance.attackProcess.AttackingPermanent == null)
  371. yield break;
  372. if(!GManager.instance.attackProcess.AttackingPermanent.IsDigimon)
  373. GManager.instance.attackProcess.IsEndAttack = true;
  374. if(GManager.instance.attackProcess.DefendingPermanent == null && GManager.instance.attackProcess.HasDefender)
  375. GManager.instance.attackProcess.IsEndAttack = true;
  376. }
  377. #endregion
  378. #region Link Card Lacking conditions handling
  379. IEnumerator DigimonLackLinkConditionProcess()
  380. {
  381. List<Permanent> LackLinkConditionPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
  382. .Map(player => player.GetFieldPermanents()
  383. .Filter(IsDigimonLackLinkCondition)).Flat();
  384. if (LackLinkConditionPermanents.Count >= 1)
  385. {
  386. foreach(Permanent permanent in LackLinkConditionPermanents)
  387. {
  388. List<CardSource> selectedCards = permanent.LinkedCards.FindAll(source => !source.CanLinkToTargetPermanent(permanent, false));
  389. yield return ContinuousController.instance.StartCoroutine(new ITrashLinkCards(
  390. permanent,
  391. selectedCards,
  392. null).TrashLinkCards());
  393. }
  394. }
  395. }
  396. #endregion
  397. #region Link Card Lacking Max Count handling
  398. IEnumerator DigimonLackLinkMaxCountProcess()
  399. {
  400. List<Permanent> LackLinkCountPermanents = GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
  401. .Map(player => player.GetFieldPermanents()
  402. .Filter(IsDigimonLackLinkCount)).Flat();
  403. if (LackLinkCountPermanents.Count >= 1)
  404. {
  405. foreach (Permanent permanent in LackLinkCountPermanents)
  406. {
  407. if (permanent.LinkedCards.Count >= permanent.LinkedMax)
  408. {
  409. if (permanent.LinkedMax > 1)
  410. yield return ContinuousController.instance.StartCoroutine(permanent.RemoveLinkedCard(null, (permanent.LinkedCards.Count - permanent.LinkedMax)));
  411. else
  412. yield return ContinuousController.instance.StartCoroutine(permanent.RemoveLinkedCard(permanent.LinkedCards[0]));
  413. }
  414. }
  415. }
  416. }
  417. #endregion
  418. #endregion
  419. #endregion
  420. #region Trigger effect processing
  421. public IEnumerator TriggeredSkillProcess(bool CheckNewTriggredSkill_mainStack, Func<List<SkillInfo>, SkillInfo, bool> skipCondition)
  422. {
  423. yield return ContinuousController.instance.StartCoroutine(ShrinkSecurityDigimonDisplay());
  424. if (StackedSkillInfos.Count > 0)
  425. {
  426. List<SkillInfo> skillInfos = StackedSkillInfos.Filter(skillInfo => skillInfo != null && !skipSkillInfos.Contains(skillInfo));
  427. if (skillInfos.Count >= 1)
  428. {
  429. //Clear the list of triggering skills not included in the resolution timing
  430. foreach (SkillInfo skillInfo in skillInfos)
  431. {
  432. StackedSkillInfos.Remove(skillInfo);
  433. }
  434. //Process the list of skills being triggered
  435. if (availableMultipleSkills != null)
  436. {
  437. yield return ContinuousController.instance.StartCoroutine(availableMultipleSkills.ActivateMultipleSkills(
  438. skillInfos,
  439. this,
  440. CheckNewTriggredSkill_mainStack,
  441. skipCondition));
  442. }
  443. yield return ContinuousController.instance.StartCoroutine(StackSkillInfos(null, EffectTiming.AfterEffectsActivate));
  444. }
  445. }
  446. }
  447. #endregion
  448. #region List of effects already achieved
  449. public List<SkillInfo> skillInfos_used
  450. {
  451. get
  452. {
  453. List<SkillInfo> skillInfos_used = new List<SkillInfo>();
  454. foreach (MultipleSkills multipleSkills in multipleSkills)
  455. {
  456. foreach (SkillInfo skillInfo in multipleSkills.SkillInfos_used)
  457. {
  458. skillInfos_used.Add(skillInfo);
  459. }
  460. }
  461. return skillInfos_used;
  462. }
  463. }
  464. #endregion
  465. #region The same effect has already been achieved
  466. public static bool HasExecutedSameEffect(List<SkillInfo> skillInfos, SkillInfo skillInfo)
  467. {
  468. return skillInfos.Some((skillInfo1) => skillInfo1.CardEffect.IsSameEffect(skillInfo.CardEffect));
  469. }
  470. #endregion
  471. #region Check end of turn
  472. public IEnumerator EndTurnCheck()
  473. {
  474. if (GManager.instance.turnStateMachine.gameContext.TurnPhase != GameContext.phase.End)
  475. {
  476. if (GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.MemoryForPlayer >= TurnEndMinMemory)
  477. {
  478. GManager.instance.turnStateMachine.Passed = false;
  479. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.EndTurnProcess());
  480. }
  481. }
  482. }
  483. #endregion
  484. #region Minimum memory to end turn
  485. static int TurnEndMinMemory
  486. {
  487. get
  488. {
  489. int turnEndMinMemory = 1;
  490. #region the effects of players
  491. GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
  492. .Map(player => player.EffectList(EffectTiming.None))
  493. .Flat()
  494. .Filter(cardEffect => cardEffect is IChangeEndTurnMinMemoryEffect && cardEffect.CanUse(null))
  495. .ForEach(cardEffect => turnEndMinMemory = ((IChangeEndTurnMinMemoryEffect)cardEffect).GetMinMemory(turnEndMinMemory));
  496. #endregion
  497. #region the effects of permanents
  498. GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer
  499. .Map(player => player.GetFieldPermanents())
  500. .Flat()
  501. .Map(permanent => permanent.EffectList(EffectTiming.None))
  502. .Flat()
  503. .Filter(cardEffect => cardEffect is IChangeEndTurnMinMemoryEffect && cardEffect.CanUse(null))
  504. .ForEach(cardEffect => turnEndMinMemory = ((IChangeEndTurnMinMemoryEffect)cardEffect).GetMinMemory(turnEndMinMemory));
  505. #endregion
  506. return turnEndMinMemory;
  507. }
  508. }
  509. #endregion
  510. #region Turn end processing
  511. public IEnumerator EndTurnProcess()
  512. {
  513. if (GManager.instance.turnStateMachine.gameContext.TurnPhase != GameContext.phase.End)
  514. {
  515. GManager.instance.turnStateMachine.isSync = true;
  516. // yield return GManager.instance.photonWaitController.StartWait("EndTurnProcess");
  517. if (GManager.instance.turnStateMachine.Passed && GManager.instance.turnStateMachine.gameContext.TurnPhase == GameContext.phase.Main)
  518. {
  519. if (GManager.instance.turnStateMachine.gameContext.TurnPlayer.PlayerID == 0)
  520. {
  521. GManager.instance.turnStateMachine.gameContext.Memory = 3;
  522. }
  523. else
  524. {
  525. GManager.instance.turnStateMachine.gameContext.Memory = -3;
  526. }
  527. yield return ContinuousController.instance.StartCoroutine(GManager.instance.memoryObject.SetMemory());
  528. }
  529. GManager.instance.turnStateMachine.Passed = true;
  530. //Effect at end of turn
  531. yield return ContinuousController.instance.StartCoroutine(StackSkillInfos(null, EffectTiming.OnEndTurn));
  532. //Automatic processing check timing
  533. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
  534. if (GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.MemoryForPlayer >= TurnEndMinMemory)
  535. {
  536. GManager.instance.turnStateMachine.gameContext.TurnPhase = GameContext.phase.End;
  537. }
  538. else
  539. {
  540. GManager.instance.turnStateMachine.isSync = false;
  541. if (GManager.instance.turnStateMachine.gameContext.TurnPhase == GameContext.phase.Main)
  542. {
  543. StartCoroutine(GManager.instance.turnStateMachine.SetMainPhase());
  544. }
  545. }
  546. }
  547. }
  548. #endregion
  549. #region Shrink security Digimon display
  550. public IEnumerator ShrinkSecurityDigimonDisplay()
  551. {
  552. if (!HasAwaitingActivateEffects()) yield break;
  553. if (GManager.instance.attackProcess.IsAttacking)
  554. {
  555. if (GManager.instance.attackProcess.SecurityDigimon != null)
  556. {
  557. if (GManager.instance.GetComponent<Effects>().ShowUseHandCard.gameObject.activeSelf && GManager.instance.GetComponent<Effects>().ShowUseHandCard.cardSource == GManager.instance.attackProcess.SecurityDigimon)
  558. {
  559. yield return ContinuousController.instance.StartCoroutine(GManager.instance.GetComponent<Effects>().MoveToExecuteCardEffect(GManager.instance.attackProcess.SecurityDigimon));
  560. yield return ContinuousController.instance.StartCoroutine(GManager.instance.attackProcess.SecurityDigimon.Owner.brainStormObject.BrainStormCoroutine(GManager.instance.attackProcess.SecurityDigimon));
  561. }
  562. }
  563. }
  564. }
  565. #endregion
  566. #region Whether there is awaiting activate effects
  567. public bool HasAwaitingActivateEffects()
  568. {
  569. if (StackedSkillInfos.Count >= 2)
  570. {
  571. return true;
  572. }
  573. else if (StackedSkillInfos.Count == 1)
  574. {
  575. if (StackedSkillInfos[0].CardEffect.CanActivate(StackedSkillInfos[0].Hashtable))
  576. {
  577. return true;
  578. }
  579. }
  580. return false;
  581. }
  582. #endregion
  583. #region Get skillInfos
  584. public static List<SkillInfo> GetSkillInfos(Hashtable hashtable, EffectTiming timing, Func<ICardEffect, bool> cardEffectCondition = null)
  585. {
  586. List<SkillInfo> skillInfos = new List<SkillInfo>();
  587. #region player effect
  588. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  589. {
  590. foreach (ICardEffect cardEffect in player.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  591. {
  592. if (cardEffect is ActivateICardEffect)
  593. {
  594. if (!cardEffect.IsBackgroundProcess)
  595. {
  596. if (cardEffect.CanTrigger(hashtable))
  597. {
  598. skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
  599. }
  600. }
  601. }
  602. }
  603. }
  604. #endregion
  605. #region Effects of permanents in play
  606. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  607. {
  608. foreach (Permanent permanent in player.GetFieldPermanents())
  609. {
  610. foreach (ICardEffect cardEffect in permanent.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  611. {
  612. if (cardEffect is ActivateICardEffect)
  613. {
  614. if (!cardEffect.IsBackgroundProcess)
  615. {
  616. if (cardEffect.CanTrigger(hashtable))
  617. {
  618. skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
  619. }
  620. }
  621. }
  622. }
  623. }
  624. }
  625. #endregion
  626. #region Trash card effect
  627. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  628. {
  629. foreach (CardSource cardSource in player.TrashCards)
  630. {
  631. foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  632. {
  633. if (cardEffect is ActivateICardEffect)
  634. {
  635. if (!cardEffect.IsBackgroundProcess)
  636. {
  637. if (cardEffect.CanTrigger(hashtable))
  638. {
  639. skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
  640. }
  641. }
  642. }
  643. }
  644. }
  645. }
  646. #endregion
  647. #region Effects of cards in hand
  648. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  649. {
  650. foreach (CardSource cardSource in player.HandCards)
  651. {
  652. foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  653. {
  654. if (cardEffect is ActivateICardEffect)
  655. {
  656. if (!cardEffect.IsBackgroundProcess)
  657. {
  658. if (cardEffect.CanTrigger(hashtable))
  659. {
  660. skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
  661. }
  662. }
  663. }
  664. }
  665. }
  666. }
  667. #endregion
  668. #region Effects of faceup security
  669. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  670. {
  671. foreach (CardSource source in player.SecurityCards)
  672. {
  673. if (source.IsFlipped)
  674. continue;
  675. foreach (ICardEffect cardEffect in source.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  676. {
  677. if (cardEffect is ActivateICardEffect)
  678. {
  679. if (!cardEffect.IsBackgroundProcess)
  680. {
  681. if (cardEffect.CanTrigger(hashtable))
  682. {
  683. skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
  684. }
  685. }
  686. }
  687. }
  688. }
  689. }
  690. #endregion
  691. return skillInfos;
  692. }
  693. #endregion
  694. #region Activate background effects
  695. public static IEnumerator ActivateBackgroundEffects(Hashtable hashtable, EffectTiming timing, Func<ICardEffect, bool> cardEffectCondition = null)
  696. {
  697. #region Player effect
  698. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  699. {
  700. foreach (ICardEffect cardEffect in player.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  701. {
  702. if (cardEffect is ActivateICardEffect)
  703. {
  704. if (cardEffect.IsBackgroundProcess)
  705. {
  706. if (cardEffect.CanUse(hashtable))
  707. {
  708. cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
  709. yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
  710. }
  711. }
  712. }
  713. }
  714. }
  715. #endregion
  716. #region Effects of permanents in play
  717. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  718. {
  719. foreach (Permanent permanent in player.GetFieldPermanents())
  720. {
  721. foreach (ICardEffect cardEffect in permanent.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  722. {
  723. if (cardEffect is ActivateICardEffect)
  724. {
  725. if (cardEffect.IsBackgroundProcess)
  726. {
  727. if (cardEffect.CanUse(hashtable))
  728. {
  729. cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
  730. yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
  731. }
  732. }
  733. }
  734. }
  735. }
  736. }
  737. #endregion
  738. #region Trash card effect
  739. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  740. {
  741. foreach (CardSource cardSource in player.TrashCards)
  742. {
  743. foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  744. {
  745. if (cardEffect is ActivateICardEffect)
  746. {
  747. if (cardEffect.IsBackgroundProcess)
  748. {
  749. if (cardEffect.CanUse(hashtable))
  750. {
  751. cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
  752. yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
  753. }
  754. }
  755. }
  756. }
  757. }
  758. }
  759. #endregion
  760. #region Effects of cards in hand
  761. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  762. {
  763. foreach (CardSource cardSource in player.HandCards)
  764. {
  765. foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  766. {
  767. if (cardEffect is ActivateICardEffect)
  768. {
  769. if (cardEffect.IsBackgroundProcess)
  770. {
  771. if (cardEffect.CanUse(hashtable))
  772. {
  773. cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
  774. yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
  775. }
  776. }
  777. }
  778. }
  779. }
  780. }
  781. #endregion
  782. }
  783. #endregion
  784. #region Stack skillInfos
  785. public IEnumerator StackSkillInfos(Hashtable hashtable, EffectTiming timing, Func<ICardEffect, bool> cardEffectCondition = null)
  786. {
  787. GetSkillInfos(hashtable, timing, cardEffectCondition).ForEach(skillInfo => PutStackedSkill(skillInfo));
  788. yield return ContinuousController.instance.StartCoroutine(ActivateBackgroundEffects(hashtable, timing, cardEffectCondition));
  789. }
  790. #endregion
  791. #region Get skillInfos of cards
  792. public static List<SkillInfo> GetSkillInfosOfCards(Hashtable hashtable, EffectTiming timing, List<CardSource> cardSources, Func<ICardEffect, bool> cardEffectCondition = null)
  793. {
  794. List<SkillInfo> skillInfos = new List<SkillInfo>();
  795. #region カードリストの効果
  796. foreach (CardSource cardSource in cardSources)
  797. {
  798. if (cardSource.PermanentOfThisCard() == null)
  799. {
  800. foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  801. {
  802. if (cardEffect is ActivateICardEffect)
  803. {
  804. if (!cardEffect.IsBackgroundProcess)
  805. {
  806. if (cardEffect.CanTrigger(hashtable))
  807. {
  808. skillInfos.Add(new SkillInfo(cardEffect, hashtable, timing));
  809. }
  810. }
  811. }
  812. }
  813. }
  814. }
  815. #endregion
  816. return skillInfos;
  817. }
  818. #endregion
  819. #region Activate background effects of cards
  820. public static IEnumerator ActivateBackgroundEffectsOfCards(Hashtable hashtable, EffectTiming timing, List<CardSource> cardSources, Func<ICardEffect, bool> cardEffectCondition = null)
  821. {
  822. #region Effect of card list
  823. foreach (CardSource cardSource in cardSources)
  824. {
  825. if (cardSource.PermanentOfThisCard() == null)
  826. {
  827. foreach (ICardEffect cardEffect in cardSource.EffectList(timing).Filter(cardEffect => cardEffectCondition == null || cardEffectCondition(cardEffect)))
  828. {
  829. if (cardEffect is ActivateICardEffect)
  830. {
  831. if (cardEffect.IsBackgroundProcess)
  832. {
  833. if (cardEffect.CanUse(hashtable))
  834. {
  835. cardEffect.EffectSourceCard.cEntity_EffectController.RegisterUseEfffectThisTurn(cardEffect);
  836. yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate(hashtable));
  837. }
  838. }
  839. }
  840. }
  841. }
  842. }
  843. #endregion
  844. }
  845. #endregion
  846. #region Stack skillInfos of cards
  847. public IEnumerator StackSkillInfosOfCards(Hashtable hashtable, EffectTiming timing, List<CardSource> cardSources, Func<ICardEffect, bool> cardEffectCondition = null)
  848. {
  849. GetSkillInfosOfCards(hashtable, timing, cardSources, cardEffectCondition).ForEach(skillInfo => PutStackedSkill(skillInfo));
  850. yield return ContinuousController.instance.StartCoroutine(ActivateBackgroundEffectsOfCards(hashtable, timing, cardSources, cardEffectCondition));
  851. }
  852. #endregion
  853. public ICardEffect MainProcessingEffect { get; private set; } = null;
  854. List<ICardEffect> _usedCutinEffects = new List<ICardEffect>();
  855. public IEnumerator ActivateEffectProcess(ICardEffect cardEffect, Hashtable hashtable, bool isCheckOptional = true)
  856. {
  857. if (cardEffect == null) yield break;
  858. if (!(cardEffect is ActivateICardEffect)) yield break;
  859. if (cardEffect.CanActivate(hashtable) || cardEffect.IsDeclarative)
  860. {
  861. bool isEffectProcessing = MainProcessingEffect != null;
  862. if (!isEffectProcessing)
  863. {
  864. MainProcessingEffect = cardEffect;
  865. _usedCutinEffects = new List<ICardEffect>();
  866. }
  867. yield return ContinuousController.instance.StartCoroutine(((ActivateICardEffect)cardEffect).Activate_Optional_Effect_Execute(hashtable, isCheckOptional));
  868. if (!isEffectProcessing)
  869. {
  870. MainProcessingEffect = null;
  871. _usedCutinEffects = new List<ICardEffect>();
  872. }
  873. }
  874. }
  875. public bool IsCutInEffectHasUsed(ICardEffect cutinEffect)
  876. {
  877. return false;//TODO: General line 17 - _usedCutinEffects.Some(cardEffect => cardEffect.IsSameEffect(cutinEffect));
  878. }
  879. public bool IsCutInEffectUsedMaxCount(ICardEffect cutinEffect)
  880. {
  881. return _usedCutinEffects.Count(cardEffect => cardEffect.IsSameEffect(cutinEffect)) < cutinEffect.ChainActivations;
  882. }
  883. public void AddCutinEffect(ICardEffect cardEffect)
  884. {
  885. if (GManager.instance.autoProcessing.MainProcessingEffect != null)
  886. {
  887. _usedCutinEffects.Add(cardEffect);
  888. }
  889. }
  890. }