AutoProcessing.cs 37 KB

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