AttackProcess.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using Photon.Pun;
  5. using System;
  6. using System.Linq;
  7. using UnityEngine.UI;
  8. public class AttackProcess : MonoBehaviourPunCallbacks
  9. {
  10. public Permanent AttackingPermanent { get; private set; } = null;
  11. public Permanent DefendingPermanent { get; private set; } = null;
  12. public int AttackCount { get; set; } = 0;
  13. public bool IsAttacking { get; set; } = false;
  14. public bool HasDefender { get; set; } = false;
  15. public bool IsBlocking { get; set; } = false;
  16. public CardSource SecurityDigimon { get; set; } = null;
  17. public bool DoSecurityCheck { get; set; } = false;
  18. public bool IsEndAttack { get; set; } = false;
  19. public bool UsedBlitz { get; set; } = false;
  20. void SetAttackerDefender(Permanent attackingPermanent, Permanent defendingPermanent)
  21. {
  22. AttackingPermanent = attackingPermanent;
  23. DefendingPermanent = defendingPermanent;
  24. if (defendingPermanent != null)
  25. HasDefender = true;
  26. }
  27. public IEnumerator Attack(Permanent attackingPermanent, Permanent defendingPermanent, ICardEffect attackEffect, bool withoutTap = false, Func<IEnumerator> beforeOnAttackCoroutine = null)
  28. {
  29. if (IsAttacking)
  30. {
  31. if (beforeOnAttackCoroutine != null)
  32. {
  33. yield return ContinuousController.instance.StartCoroutine(beforeOnAttackCoroutine());
  34. }
  35. yield break;
  36. }
  37. AttackingPermanent = null;
  38. DefendingPermanent = null;
  39. DoSecurityCheck = false;
  40. IsBlocking = false;
  41. SecurityDigimon = null;
  42. IsAttacking = false;
  43. HasDefender = false;
  44. IsEndAttack = false;
  45. SetAttackerDefender(attackingPermanent, defendingPermanent);
  46. Hashtable effectHashtable = CardEffectCommons.OnAttackCheckHashtableOfPermanent(AttackingPermanent, attackEffect);
  47. Hashtable counterEffectHashtable = CardEffectCommons.OnAttackCheckHashtableOfPermanent(new Permanent(AttackingPermanent.cardSources), attackEffect);
  48. IsAttacking = true;
  49. // check timing
  50. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
  51. GManager.instance.turnStateMachine.IsSelecting = true;
  52. // force to end attack
  53. if (IsEndAttack)
  54. {
  55. goto EndAttack;
  56. }
  57. #region Attack Process
  58. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(AttackingPermanent))
  59. {
  60. AttackCount++;
  61. GManager.instance.turnStateMachine.IsSelecting = true;
  62. if (DefendingPermanent != null)
  63. {
  64. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
  65. {
  66. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  67. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  68. GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.securityObject.securityBreakGlass.gameObject.SetActive(false);
  69. }
  70. }
  71. else
  72. {
  73. if (GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.SecurityCards.Count >= 1)
  74. {
  75. GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.securityObject.securityBreakGlass.ShowBlueMatarial();
  76. }
  77. }
  78. AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
  79. AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  80. // add log
  81. string log = $"\nAttack:\n{AttackingPermanent.TopCard.BaseENGCardNameFromEntity}({AttackingPermanent.TopCard.CardID})";
  82. if (DefendingPermanent != null)
  83. {
  84. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
  85. log += $"\n�«\n{DefendingPermanent.TopCard.BaseENGCardNameFromEntity}({DefendingPermanent.TopCard.CardID})\n";
  86. }
  87. else
  88. {
  89. log += $"\n�«\nSecurity\n";
  90. }
  91. PlayLog.OnAddLog?.Invoke(log);
  92. List<SkillInfo> stackedSkillInfos = new List<SkillInfo>();
  93. if (GManager.instance.autoProcessing.executingMultipleSkills != null)
  94. {
  95. if (GManager.instance.autoProcessing.executingMultipleSkills.StackedSkillInfos.Count >= 1)
  96. {
  97. foreach (SkillInfo skillInfo in GManager.instance.autoProcessing.executingMultipleSkills.StackedSkillInfos)
  98. {
  99. stackedSkillInfos.Add(skillInfo);
  100. }
  101. }
  102. foreach (SkillInfo skillInfo in stackedSkillInfos)
  103. {
  104. GManager.instance.autoProcessing.executingMultipleSkills.StackedSkillInfos.Remove(skillInfo);
  105. }
  106. }
  107. // suspend
  108. if (!withoutTap)
  109. {
  110. Hashtable attackerTapHashtable = new Hashtable()
  111. {
  112. {"IsAttack", true}
  113. };
  114. yield return ContinuousController.instance.StartCoroutine(new SuspendPermanentsClass(
  115. new List<Permanent>() { AttackingPermanent },
  116. attackerTapHashtable).Tap());
  117. }
  118. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
  119. // target arrow
  120. if (DefendingPermanent == null)
  121. {
  122. yield return GManager.instance.OnTargetArrow(
  123. AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
  124. GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.SecurityAttackLocalCanvasPosition + GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.playerUIObjectParent.localPosition,
  125. null,
  126. null);
  127. }
  128. else
  129. {
  130. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
  131. {
  132. yield return GManager.instance.OnTargetArrow(
  133. AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
  134. DefendingPermanent.PermanentFrame.GetLocalCanvasPosition() + DefendingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
  135. null,
  136. null);
  137. }
  138. }
  139. // activate cutin effects
  140. //yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
  141. //yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, null));
  142. // callback that is processed before [On Attack]
  143. if (beforeOnAttackCoroutine != null)
  144. {
  145. yield return ContinuousController.instance.StartCoroutine(beforeOnAttackCoroutine());
  146. }
  147. // trigger [On Attack] effect
  148. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
  149. effectHashtable,
  150. EffectTiming.OnAllyAttack));
  151. // activate cutin effects
  152. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
  153. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, null));
  154. if (stackedSkillInfos.Count >= 1)
  155. {
  156. foreach (SkillInfo skillInfo in stackedSkillInfos)
  157. {
  158. GManager.instance.autoProcessing.PutStackedSkill(skillInfo);
  159. }
  160. }
  161. GManager.instance.turnStateMachine.IsSelecting = true;
  162. if (AttackingPermanent.TopCard != null)
  163. {
  164. AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
  165. AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  166. }
  167. if (DefendingPermanent != null)
  168. {
  169. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
  170. {
  171. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  172. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  173. }
  174. }
  175. // check timing
  176. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
  177. GManager.instance.turnStateMachine.IsSelecting = true;
  178. // force to end attack
  179. if (IsEndAttack)
  180. {
  181. goto EndAttack;
  182. }
  183. if (AttackingPermanent.TopCard != null)
  184. {
  185. AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
  186. AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  187. }
  188. if (DefendingPermanent != null)
  189. {
  190. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
  191. {
  192. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  193. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  194. }
  195. }
  196. // trigger effects when counter timing (except [Counter] effects)
  197. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
  198. counterEffectHashtable,
  199. EffectTiming.OnCounterTiming,
  200. cardEffect => !cardEffect.IsCounterEffect));
  201. // activate cutin effects
  202. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
  203. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, null));
  204. GManager.instance.turnStateMachine.IsSelecting = true;
  205. // force to end attack
  206. if (IsEndAttack)
  207. {
  208. goto EndAttack;
  209. }
  210. // trigger effects when counter timing ([Counter] effects)
  211. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.StackSkillInfos(
  212. counterEffectHashtable,
  213. EffectTiming.OnCounterTiming,
  214. cardEffect => cardEffect.IsCounterEffect));
  215. bool HasCounterEffect(List<SkillInfo> skillInfos, SkillInfo skillInfo)
  216. {
  217. return skillInfos.Count((skillInfo1) => skillInfo1.CardEffect.IsCounterEffect) >= 1;
  218. }
  219. // activate cutin effects
  220. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.RuleProcess());
  221. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing_CutIn.TriggeredSkillProcess(true, HasCounterEffect));
  222. GManager.instance.turnStateMachine.IsSelecting = true;
  223. // force to end attack
  224. if (IsEndAttack)
  225. {
  226. goto EndAttack;
  227. }
  228. if (AttackingPermanent.TopCard == null)
  229. {
  230. goto EndAttack;
  231. }
  232. AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
  233. AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  234. if (DefendingPermanent != null)
  235. {
  236. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
  237. {
  238. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  239. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  240. }
  241. }
  242. #region select blocker
  243. bool CanSelectBlockerCondition(Permanent permanent)
  244. {
  245. if (CardEffectCommons.IsPermanentExistsOnOpponentBattleAreaDigimon(permanent, AttackingPermanent.TopCard))
  246. {
  247. if (permanent != DefendingPermanent)
  248. {
  249. if (permanent.HasBlocker && permanent.CanBlock(AttackingPermanent))
  250. {
  251. return true;
  252. }
  253. }
  254. }
  255. return false;
  256. }
  257. if (AttackingPermanent.TopCard.Owner.Enemy.GetBattleAreaDigimons().Count(CanSelectBlockerCondition) >= 1)
  258. {
  259. int maxCount = 1;
  260. Permanent selectedPermanent = null;
  261. SelectPermanentEffect selectPermanentEffect = GManager.instance.GetComponent<SelectPermanentEffect>();
  262. selectPermanentEffect.SetUp(
  263. selectPlayer: AttackingPermanent.TopCard.Owner.Enemy,
  264. canTargetCondition: CanSelectBlockerCondition,
  265. canTargetCondition_ByPreSelecetedList: null,
  266. canEndSelectCondition: null,
  267. maxCount: maxCount,
  268. canNoSelect: (!IsBlocking),
  269. canEndNotMax: false,
  270. selectPermanentCoroutine: SelectPermanentCoroutine,
  271. afterSelectPermanentCoroutine: null,
  272. mode: SelectPermanentEffect.Mode.Custom,
  273. cardEffect: null);
  274. selectPermanentEffect.SetUpCustomMessage("Select 1 Digimon that will block.", "The opponent is selecting 1 Digimon that will block.");
  275. if(!IsBlocking)
  276. selectPermanentEffect.SetUpCustomBackButtonMessage("Not Block");
  277. yield return ContinuousController.instance.StartCoroutine(selectPermanentEffect.Activate());
  278. IEnumerator SelectPermanentCoroutine(Permanent permanent)
  279. {
  280. selectedPermanent = permanent;
  281. yield return null;
  282. }
  283. if (selectedPermanent != null)
  284. {
  285. yield return ContinuousController.instance.StartCoroutine(SwitchDefender(null, true, selectedPermanent));
  286. }
  287. }
  288. #endregion
  289. GManager.instance.turnStateMachine.IsSelecting = true;
  290. //end attack
  291. if (IsEndAttack)
  292. {
  293. goto EndAttack;
  294. }
  295. if (AttackingPermanent.TopCard == null)
  296. {
  297. goto EndAttack;
  298. }
  299. AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
  300. AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  301. if (DefendingPermanent != null)
  302. {
  303. if (CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent))
  304. {
  305. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  306. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  307. }
  308. }
  309. #region there is no Defending Permanent
  310. if (DefendingPermanent == null)
  311. {
  312. if (AttackingPermanent.Strike >= 1)
  313. {
  314. //if there is no security, end the game
  315. if (AttackingPermanent.TopCard.Owner.Enemy.SecurityCards.Count == 0)
  316. {
  317. GManager.instance.turnStateMachine.EndGame(AttackingPermanent.TopCard.Owner, false);
  318. yield break;
  319. }
  320. }
  321. DoSecurityCheck = true;
  322. }
  323. #endregion
  324. #region there is Defending Permanent
  325. else
  326. {
  327. if (!CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(DefendingPermanent) || !CardEffectCommons.IsPermanentExistsOnBattleAreaDigimon(AttackingPermanent))
  328. {
  329. goto EndAttack;
  330. }
  331. DefendingPermanent.TopCard.Owner.securityObject.securityBreakGlass.gameObject.SetActive(false);
  332. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  333. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  334. // battle
  335. IBattle battle = new IBattle(AttackingPermanent: AttackingPermanent, DefendingPermanent: DefendingPermanent, null);
  336. yield return ContinuousController.instance.StartCoroutine(battle.Battle());
  337. /*#region effect when determine whether to do security check
  338. Hashtable hashtable = new Hashtable()
  339. {
  340. {"battle", battle}
  341. };
  342. List<SkillInfo> skillInfos_Pierce = AutoProcessing.GetSkillInfos(hashtable, EffectTiming.OnDetermineDoSecurityCheck)
  343. .Filter(skillInfo => skillInfo.CardEffect != null && skillInfo.CardEffect.CanActivate(skillInfo.Hashtable));
  344. if (skillInfos_Pierce.Count >= 1)
  345. {
  346. GManager.instance.autoProcessing.PutStackedSkill(skillInfos_Pierce[0]);
  347. }
  348. #endregion*/
  349. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.TriggeredSkillProcess(true, null));
  350. GManager.instance.turnStateMachine.IsSelecting = true;
  351. }
  352. #endregion
  353. if (AttackingPermanent.TopCard == null)
  354. {
  355. goto EndAttack;
  356. }
  357. #region do security check
  358. if (DoSecurityCheck && AttackingPermanent.TopCard.Owner.Enemy.SecurityCards.Count >= 1)
  359. {
  360. //security check process
  361. yield return ContinuousController.instance.StartCoroutine(new ISecurityCheck(
  362. AttackingPermanent: AttackingPermanent,
  363. player: GManager.instance.turnStateMachine.gameContext.NonTurnPlayer).SecurityCheck());
  364. }
  365. #endregion
  366. }
  367. else
  368. {
  369. if (beforeOnAttackCoroutine != null)
  370. {
  371. yield return ContinuousController.instance.StartCoroutine(beforeOnAttackCoroutine());
  372. }
  373. }
  374. #endregion
  375. #region End Attack
  376. EndAttack:;
  377. // [On End Attack] effect
  378. if (AttackingPermanent != null && AttackingPermanent.TopCard != null)
  379. {
  380. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(effectHashtable, EffectTiming.OnEndAttack));
  381. }
  382. // activate cutin effects
  383. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.AutoProcessCheck());
  384. #region reset effects which continues until the end of attack
  385. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  386. {
  387. foreach (Permanent permanent in player.GetFieldPermanents())
  388. {
  389. permanent.UntilEndAttackEffects = new List<Func<EffectTiming, ICardEffect>>();
  390. }
  391. }
  392. #endregion
  393. GManager.instance.turnStateMachine.IsSelecting = true;
  394. #endregion
  395. DoSecurityCheck = false;
  396. IsBlocking = false;
  397. SecurityDigimon = null;
  398. IsAttacking = false;
  399. IsEndAttack = false;
  400. UnityEngine.Debug.Log("ATTACK IS OVER");
  401. }
  402. public IEnumerator SwitchDefender(ICardEffect cardEffect, bool isBlock, Permanent newDefendingPermanent)
  403. {
  404. if (AttackingPermanent == null) yield break;
  405. if (AttackingPermanent.TopCard == null) yield break;
  406. if (newDefendingPermanent != null && newDefendingPermanent.TopCard == null) yield break;
  407. if (!AttackingPermanent.CanSwitchAttackTarget) yield break;
  408. Permanent oldDefendingPermanent = DefendingPermanent;
  409. DefendingPermanent = newDefendingPermanent;
  410. IsBlocking = isBlock;
  411. if (DefendingPermanent != null)
  412. {
  413. if (DefendingPermanent.ShowingPermanentCard != null)
  414. {
  415. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  416. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  417. }
  418. }
  419. Hashtable hashtable = new Hashtable(){
  420. {"AttackingPermanent", AttackingPermanent},
  421. {"DefendingPermanent", DefendingPermanent},
  422. {"CardEffect", cardEffect}
  423. };
  424. if (isBlock)
  425. {
  426. hashtable.Add("IsBlock", isBlock);
  427. }
  428. if (isBlock)
  429. {
  430. if (DefendingPermanent != null)
  431. {
  432. // add log
  433. string log1 = $"\nBlock:\n{DefendingPermanent.TopCard.BaseENGCardNameFromEntity}({DefendingPermanent.TopCard.CardID})\n";
  434. PlayLog.OnAddLog?.Invoke(log1);
  435. // suspend
  436. yield return ContinuousController.instance.StartCoroutine(new SuspendPermanentsClass(new List<Permanent>() { DefendingPermanent }, hashtable).Tap());
  437. // the effects when blocking
  438. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(
  439. hashtable,
  440. EffectTiming.OnBlockAnyone));
  441. }
  442. }
  443. if (AttackingPermanent != null)
  444. {
  445. if (AttackingPermanent.TopCard == null)
  446. {
  447. IsBlocking = false;
  448. yield break;
  449. }
  450. }
  451. if (DefendingPermanent != null)
  452. {
  453. if (DefendingPermanent.TopCard == null)
  454. {
  455. IsBlocking = false;
  456. yield break;
  457. }
  458. }
  459. if (AttackingPermanent != null)
  460. {
  461. // target arrow
  462. for (int i = 0; i < 3; i++)
  463. {
  464. GManager.instance.OffTargetArrow();
  465. yield return null;
  466. }
  467. if (DefendingPermanent != null)
  468. {
  469. DefendingPermanent.ShowingPermanentCard.SetOrangeOutline();
  470. DefendingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  471. yield return GManager.instance.OnTargetArrow(
  472. AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
  473. DefendingPermanent.PermanentFrame.GetLocalCanvasPosition() + DefendingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
  474. null,
  475. null);
  476. }
  477. else
  478. {
  479. yield return GManager.instance.OnTargetArrow(
  480. AttackingPermanent.PermanentFrame.GetLocalCanvasPosition() + AttackingPermanent.TopCard.Owner.playerUIObjectParent.localPosition,
  481. GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.SecurityAttackLocalCanvasPosition + GManager.instance.turnStateMachine.gameContext.NonTurnPlayer.playerUIObjectParent.localPosition,
  482. null,
  483. null);
  484. }
  485. AttackingPermanent.ShowingPermanentCard.SetOrangeOutline();
  486. AttackingPermanent.ShowingPermanentCard.Outline_Select.gameObject.SetActive(true);
  487. }
  488. if (newDefendingPermanent != oldDefendingPermanent)
  489. {
  490. // the effects when attack target switched
  491. yield return ContinuousController.instance.StartCoroutine(GManager.instance.autoProcessing.StackSkillInfos(
  492. hashtable,
  493. EffectTiming.OnAttackTargetChanged));
  494. }
  495. }
  496. }