AutoProcessing.cs 39 KB

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