SelectCardPanel.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using System;
  6. using UnityEngine.EventSystems;
  7. using UnityEngine.Events;
  8. using DG.Tweening;
  9. using TMPro;
  10. public class SelectCardPanel : MonoBehaviour
  11. {
  12. [Header("Message Text")]
  13. public TextMeshProUGUI MessageText;
  14. [Header("ScrollRect")]
  15. public ScrollRect scrollRect;
  16. [Header("Do not select button")]
  17. public GameObject NoSelectButton;
  18. [Header("Select Decision button")]
  19. public GameObject EndSelectButton;
  20. [Header("BackGround")]
  21. public GameObject BackGround;
  22. [Header("Parents other than background")]
  23. public GameObject Parent;
  24. [Header("Return to card selection button")]
  25. public Button ReturnToSelectCardButton;
  26. [Header("Text of the button not to be selected")]
  27. public Text NotSelectButtonText;
  28. [Header("Text of the selection end button")]
  29. public Text EndSelectButtonText;
  30. public Text CountText;
  31. //Selected card list
  32. public List<CardSource> SelectedList { get; set; } = new List<CardSource>();
  33. public List<int> SelectedIndex { get; set; } = new List<int>();
  34. //Eligibility Criteria for Eligible Cards
  35. Func<CardSource, bool> _canTargetCondition = null;
  36. //Whether the unit can be selected with the current selection list status
  37. Func<List<CardSource>, CardSource, bool> _canTargetCondition_ByPreSelecetedList = null;
  38. //Conditions under which a selection can be terminated (see list of selection termination points)
  39. Func<List<CardSource>, bool> _canEndSelectCondition = null;
  40. //Maximum number of cards that can be selected
  41. int _maxCount = 0;
  42. //Whether it can be terminated with less than the maximum number of cards
  43. bool _canEndNotMax = false;
  44. //Whether you can choose not to choose
  45. Func<bool> _canNoSelect = () => false;
  46. //provisional selection card list
  47. List<HandCard> _preSelectedHandCardList = new List<HandCard>();
  48. //Whether the selection has been completed or not
  49. bool _isEndSelection = false;
  50. //List of cards with scroll view
  51. List<HandCard> _handCards = new List<HandCard>();
  52. UnityAction _onClickNotSelectButtonAction;
  53. UnityAction _onClickEndSelectButtonAction;
  54. public string _customCountText = null;
  55. #region Notification that selection has been made
  56. public void SetIsEndSelection(bool isEndSelection)
  57. {
  58. _isEndSelection = isEndSelection;
  59. }
  60. #endregion
  61. //Select cards normally
  62. public IEnumerator OpenSelectCardPanel(string Message, List<CardSource> RootCardSources, Func<CardSource, bool> _CanTargetCondition, Func<List<CardSource>, CardSource, bool> _CanTargetCondition_ByPreSelecetedList, Func<List<CardSource>, bool> _CanEndSelectCondition, int _MaxCount, bool _CanEndNotMax, Func<bool> _CanNoSelect, bool CanLookReverseCard, List<SkillInfo> skillInfos, SelectCardEffect.Root root, bool isCenter = false, CardSource[][] evoRootsArray = null, List<string> titleStrings = null)
  63. {
  64. yield return ContinuousController.instance.StartCoroutine(OpenSelectCardPanel(Message, "No Selection", "End Selection", null, null, RootCardSources, _CanTargetCondition, _CanTargetCondition_ByPreSelecetedList, _CanEndSelectCondition, _MaxCount, _CanEndNotMax, _CanNoSelect, CanLookReverseCard, skillInfos, root, isCenter: isCenter, evoRootsArray: evoRootsArray, titleStrings: titleStrings));
  65. }
  66. //Select cards(Custom button text and click handling)
  67. public IEnumerator OpenSelectCardPanel(string Message, string NotSelectButtonMessage, string EndSelectButtonMessage, UnityAction _OnClickNotSelectButtonAction, UnityAction _OnClickEndSelectButtonAction, List<CardSource> RootCardSources, Func<CardSource, bool> _CanTargetCondition, Func<List<CardSource>, CardSource, bool> _CanTargetCondition_ByPreSelecetedList, Func<List<CardSource>, bool> _CanEndSelectCondition, int _MaxCount, bool _CanEndNotMax, Func<bool> _CanNoSelect, bool CanLookReverseCard, List<SkillInfo> skillInfos, SelectCardEffect.Root root, bool isCenter = false, CardSource[][] evoRootsArray = null, List<string> titleStrings = null)
  68. {
  69. #region Initialization
  70. this.gameObject.SetActive(true);
  71. _onClickNotSelectButtonAction = _OnClickNotSelectButtonAction;
  72. _onClickEndSelectButtonAction = _OnClickEndSelectButtonAction;
  73. NotSelectButtonText.text = NotSelectButtonMessage;
  74. EndSelectButtonText.text = EndSelectButtonMessage;
  75. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players)
  76. {
  77. GManager.instance.turnStateMachine.OffFieldCardTarget(player);
  78. GManager.instance.turnStateMachine.OffHandCardTarget(player);
  79. }
  80. GManager.instance.turnStateMachine.IsSelecting = true;
  81. BackGround.SetActive(true);
  82. Parent.SetActive(false);
  83. SetIsEndSelection(false);
  84. ReturnToSelectCardButton.gameObject.SetActive(false);
  85. _preSelectedHandCardList = new List<HandCard>();
  86. SelectedList = new List<CardSource>();
  87. SelectedIndex = new List<int>();
  88. _handCards = new List<HandCard>();
  89. MessageText.text = Message;
  90. _canTargetCondition = _CanTargetCondition;
  91. _canTargetCondition_ByPreSelecetedList = _CanTargetCondition_ByPreSelecetedList;
  92. _canEndSelectCondition = _CanEndSelectCondition;
  93. _maxCount = _MaxCount;
  94. _canEndNotMax = _CanEndNotMax;
  95. _canNoSelect = _CanNoSelect;
  96. if (!GManager.instance.turnStateMachine.DoneStartGame)
  97. {
  98. CountText.text = "";
  99. }
  100. else
  101. {
  102. if (!string.IsNullOrEmpty(_customCountText))
  103. {
  104. CountText.text = _customCountText;
  105. }
  106. else
  107. {
  108. if (_canEndNotMax)
  109. {
  110. CountText.text = $"Select up to {_maxCount} card{Utils.PluralFormSuffix(_maxCount)}.";
  111. }
  112. else
  113. {
  114. CountText.text = $"Select {_maxCount} card{Utils.PluralFormSuffix(_maxCount)}.";
  115. }
  116. }
  117. }
  118. #endregion
  119. yield return StartCoroutine(OpenSelectCardPanelAnimation(root));
  120. yield return StartCoroutine(OpenSelectCardPanelCoroutine(RootCardSources, CanLookReverseCard, skillInfos, isCenter: isCenter, evoRootsArray: evoRootsArray, titleStrings: titleStrings));
  121. CheckSelection();
  122. yield return new WaitWhile(() => !_isEndSelection);
  123. SetIsEndSelection(false);
  124. }
  125. IEnumerator OpenSelectCardPanelAnimation(SelectCardEffect.Root root)
  126. {
  127. bool end = false;
  128. var sequence = DOTween.Sequence();
  129. float time = 0.4f;
  130. this.transform.localScale = new Vector3(0.1f, 0.1f, 1f);
  131. if (root == SelectCardEffect.Root.Security)
  132. {
  133. this.transform.localPosition = new Vector3(-580f, -110f, 0f);
  134. }
  135. else
  136. {
  137. this.transform.localPosition = new Vector3(0f, 0f, 0f);
  138. }
  139. sequence
  140. .Append(this.transform.DOLocalMove(new Vector3(0f, 0f, 0f), time))
  141. .Join(this.transform.DOScale(new Vector3(1f, 1f, 1f), time))
  142. .AppendCallback(() => { end = true; });
  143. sequence.Play();
  144. yield return new WaitWhile(() => !end);
  145. end = false;
  146. }
  147. #region Open panel to generate card prefab
  148. IEnumerator OpenSelectCardPanelCoroutine(List<CardSource> RootCardSources, bool CanLookReverseCard, List<SkillInfo> skillInfos, bool isCenter, CardSource[][] evoRootsArray, List<string> titleStrings)
  149. {
  150. List<CardSource> root = new List<CardSource>();
  151. foreach (CardSource cardSource in RootCardSources)
  152. {
  153. root.Add(cardSource);
  154. }
  155. GridLayoutGroup grid = scrollRect.content.GetComponent<GridLayoutGroup>();
  156. if (grid != null)
  157. {
  158. if (isCenter)
  159. {
  160. grid.padding.left = 550;
  161. grid.spacing = new Vector2(600f, 0);
  162. }
  163. else
  164. {
  165. grid.padding.left = 248;
  166. grid.spacing = new Vector2(191.7f, 0);
  167. }
  168. }
  169. yield return new WaitForSeconds(Time.deltaTime);
  170. #region Do not select button
  171. NoSelectButton.SetActive(_canNoSelect());
  172. #endregion
  173. #region Initialize card list
  174. while (scrollRect.content.childCount > 0)
  175. {
  176. for (int i = 0; i < scrollRect.content.childCount; i++)
  177. {
  178. if (scrollRect.content.GetChild(i) != null)
  179. {
  180. if (scrollRect.content.GetChild(i).gameObject != null)
  181. {
  182. Destroy(scrollRect.content.GetChild(i).gameObject);
  183. yield return null;
  184. }
  185. }
  186. }
  187. }
  188. yield return new WaitWhile(() => scrollRect.content.childCount > 0);
  189. #endregion
  190. #region card generation
  191. foreach (CardSource cardSource in root)
  192. {
  193. HandCard handCard = Instantiate(GManager.instance.handCardPrefab, scrollRect.content);
  194. handCard.gameObject.name = $"selectCardPanel_{cardSource.Owner.PlayerName}";
  195. handCard.GetComponent<Draggable_HandCard>().startScale = new Vector3(2.7f, 2.7f, 1);
  196. handCard.GetComponent<Draggable_HandCard>().DefaultY = -292;
  197. EventTrigger eventTrigger = handCard.CardImage.GetComponent<EventTrigger>();
  198. eventTrigger.triggers.Clear();
  199. EventTrigger.Entry entry = new EventTrigger.Entry();
  200. entry.eventID = EventTriggerType.PointerClick;
  201. entry.callback.AddListener((x) => { PointerClick(cardSource); });
  202. #region Processing on click
  203. void PointerClick(CardSource cardSource1)
  204. {
  205. #region right click
  206. if (Input.GetMouseButtonUp(1))
  207. {
  208. if (cardSource1 != null)
  209. {
  210. //If you can't see the face down card
  211. if (!CanLookReverseCard)
  212. {
  213. if (!cardSource1.IsFlipped)
  214. {
  215. GManager.instance.cardDetail.OpenCardDetail(cardSource1, true);
  216. GManager.instance.PlayDecisionSE();
  217. }
  218. }
  219. //If you can see the card face down
  220. else
  221. {
  222. GManager.instance.cardDetail.OpenCardDetail(cardSource1, true);
  223. GManager.instance.PlayDecisionSE();
  224. }
  225. }
  226. }
  227. #endregion
  228. #region left click
  229. else if (Input.GetMouseButtonUp(0))
  230. {
  231. handCard.OnClickAction?.Invoke(handCard);
  232. }
  233. #endregion
  234. }
  235. #endregion
  236. eventTrigger.triggers.Add(entry);
  237. handCard.SetUpHandCard(cardSource);
  238. if (!cardSource.IsFlipped || CanLookReverseCard)
  239. {
  240. handCard.SetUpHandCardImage();
  241. }
  242. else
  243. {
  244. handCard.SetUpReverseCard();
  245. }
  246. handCard.AddClickTarget(OnClickHandCard);
  247. _handCards.Add(handCard);
  248. }
  249. yield return new WaitWhile(() => scrollRect.content.childCount < root.Count);
  250. yield return new WaitWhile(() => scrollRect.content.childCount != _handCards.Count);
  251. yield return new WaitForSeconds(Time.deltaTime * 2);
  252. for (int i = 0; i < scrollRect.content.childCount; i++)
  253. {
  254. scrollRect.content.GetChild(i).localScale = new Vector3(2.7f, 2.7f, 1);
  255. }
  256. #endregion
  257. CheckSelection();
  258. Parent.SetActive(true);
  259. ReturnToSelectCardButton.gameObject.SetActive(false);
  260. scrollRect.horizontalNormalizedPosition = 0;
  261. yield return new WaitForSeconds(Time.deltaTime * 1f);
  262. #region 効果名を表示
  263. if (skillInfos != null)
  264. {
  265. List<Permanent> permanents = new List<Permanent>();
  266. foreach (HandCard handCard in _handCards)
  267. {
  268. int index = _handCards.IndexOf(handCard);
  269. if (0 <= index && index < skillInfos.Count)
  270. {
  271. if (skillInfos[index] != null)
  272. {
  273. Permanent permanent = handCard.cardSource.PermanentOfThisCard();
  274. if (permanent != null)
  275. {
  276. if (!permanents.Contains(permanent))
  277. {
  278. permanents.Add(permanent);
  279. }
  280. }
  281. }
  282. }
  283. }
  284. foreach (HandCard handCard in _handCards)
  285. {
  286. int index = _handCards.IndexOf(handCard);
  287. if (0 <= index && index < skillInfos.Count)
  288. {
  289. if (skillInfos[index] != null)
  290. {
  291. if (!string.IsNullOrEmpty(skillInfos[index].CardEffect.EffectName))
  292. {
  293. handCard.SetSkillName(skillInfos[index].CardEffect);
  294. handCard.SetUpCardPositionText(permanents);
  295. }
  296. if (handCard.cardSource.PermanentOfThisCard() != null)
  297. {
  298. foreach (FieldPermanentCard fieldPermanentCard in handCard.cardSource.Owner.FieldPermanentObjects)
  299. {
  300. if (fieldPermanentCard.ThisPermanent != null)
  301. {
  302. if (fieldPermanentCard.ThisPermanent.cardSources.Contains(handCard.cardSource))
  303. {
  304. fieldPermanentCard.SetPermanentIndexText(permanents);
  305. break;
  306. }
  307. }
  308. }
  309. }
  310. }
  311. }
  312. }
  313. }
  314. #endregion
  315. #region 進化元画像を表示
  316. if (evoRootsArray != null)
  317. {
  318. for (int i = 0; i < evoRootsArray.Length; i++)
  319. {
  320. if (i < _handCards.Count)
  321. {
  322. _handCards[i].SetEvoRootCardImages(evoRootsArray[i]);
  323. }
  324. }
  325. }
  326. #endregion
  327. #region タイトルテキストを表示
  328. if (titleStrings != null)
  329. {
  330. for (int i = 0; i < titleStrings.Count; i++)
  331. {
  332. if (i < _handCards.Count)
  333. {
  334. _handCards[i].SetTitleText(titleStrings[i]);
  335. }
  336. }
  337. }
  338. #endregion
  339. }
  340. #endregion
  341. #region Left-click processing
  342. public void OnClickHandCard(HandCard handCard)
  343. {
  344. if (_canTargetCondition(handCard.cardSource))
  345. {
  346. if (_preSelectedHandCardList.Contains(handCard))
  347. {
  348. _preSelectedHandCardList.Remove(handCard);
  349. SelectedIndex.Remove(_handCards.IndexOf(handCard));
  350. }
  351. else
  352. {
  353. if (_canTargetCondition_ByPreSelecetedList != null)
  354. {
  355. List<CardSource> _PreSelectedList = new List<CardSource>();
  356. for (int i = 0; i < _preSelectedHandCardList.Count; i++)
  357. {
  358. if (_preSelectedHandCardList.Count >= _maxCount && i == _preSelectedHandCardList.Count - 1)
  359. {
  360. continue;
  361. }
  362. _PreSelectedList.Add(_preSelectedHandCardList[i].cardSource);
  363. }
  364. if (!_canTargetCondition_ByPreSelecetedList(_PreSelectedList, handCard.cardSource))
  365. {
  366. return;
  367. }
  368. }
  369. if (_preSelectedHandCardList.Count < _maxCount)
  370. {
  371. _preSelectedHandCardList.Add(handCard);
  372. SelectedIndex.Add(_handCards.IndexOf(handCard));
  373. }
  374. else
  375. {
  376. if (_preSelectedHandCardList.Count > 0)
  377. {
  378. _preSelectedHandCardList.RemoveAt(_preSelectedHandCardList.Count - 1);
  379. SelectedIndex.RemoveAt(SelectedIndex.Count - 1);
  380. _preSelectedHandCardList.Add(handCard);
  381. SelectedIndex.Add(_handCards.IndexOf(handCard));
  382. }
  383. }
  384. if (!ContinuousController.instance.checkBeforeEndingSelection
  385. && !_canNoSelect()
  386. && !_canEndNotMax
  387. && _maxCount == _preSelectedHandCardList.Count)
  388. {
  389. OnClickEndSelectButton();
  390. return;
  391. }
  392. }
  393. CheckSelection();
  394. }
  395. }
  396. #endregion
  397. #region UI reflects whether the selection can be terminated.
  398. public void CheckSelection()
  399. {
  400. EndSelectButton.SetActive(CanEndSelection());
  401. foreach (HandCard handCard in _handCards)
  402. {
  403. handCard.RemoveSelectEffect();
  404. handCard.OffSelectedIndexText();
  405. if (_canTargetCondition(handCard.cardSource))
  406. {
  407. if (_preSelectedHandCardList.Contains(handCard))
  408. {
  409. handCard.SetOrangeOutline();
  410. handCard.OnOutline();
  411. handCard.SetSelectedIndexText(_preSelectedHandCardList.IndexOf(handCard) + 1);
  412. }
  413. else
  414. {
  415. handCard.SetBlueOutline();
  416. handCard.OnOutline();
  417. if (_canTargetCondition_ByPreSelecetedList != null)
  418. {
  419. List<CardSource> _PreSelectedList = new List<CardSource>();
  420. for (int i = 0; i < _preSelectedHandCardList.Count; i++)
  421. {
  422. if (_preSelectedHandCardList.Count >= _maxCount && i == _preSelectedHandCardList.Count - 1)
  423. {
  424. continue;
  425. }
  426. _PreSelectedList.Add(_preSelectedHandCardList[i].cardSource);
  427. }
  428. if (!_canTargetCondition_ByPreSelecetedList(_PreSelectedList, handCard.cardSource))
  429. {
  430. handCard.RemoveSelectEffect();
  431. }
  432. }
  433. if (_preSelectedHandCardList.Count >= _maxCount)
  434. {
  435. handCard.RemoveSelectEffect();
  436. }
  437. }
  438. }
  439. }
  440. if (_preSelectedHandCardList.Count >= 1)
  441. {
  442. NoSelectButton.SetActive(false);
  443. }
  444. else
  445. {
  446. NoSelectButton.SetActive(_canNoSelect());
  447. }
  448. }
  449. #endregion
  450. #region Determines if selection can be terminated
  451. bool CanEndSelection()
  452. {
  453. if (_maxCount <= 0) return true;
  454. List<CardSource> _PreSelectedList = new List<CardSource>();
  455. foreach (HandCard handCard1 in _preSelectedHandCardList)
  456. {
  457. _PreSelectedList.Add(handCard1.cardSource);
  458. }
  459. if (_canEndSelectCondition != null)
  460. {
  461. if (!_canEndSelectCondition(_PreSelectedList))
  462. {
  463. return false;
  464. }
  465. }
  466. if (_canEndNotMax)
  467. {
  468. return true;
  469. }
  470. else
  471. {
  472. if (_PreSelectedList.Count == _maxCount)
  473. {
  474. return true;
  475. }
  476. }
  477. return false;
  478. }
  479. #endregion
  480. #region Exit card selection
  481. public void CloseSelectCardPanel()
  482. {
  483. this.gameObject.SetActive(false);
  484. ReturnToSelectCardButton.gameObject.SetActive(false);
  485. }
  486. #endregion
  487. #region Processing when a button is pressed that does not select anything
  488. public void OnClickNotSelectButton()
  489. {
  490. GManager.instance.PlayDecisionSE();
  491. SelectedList = new List<CardSource>();
  492. CloseSelectCardPanel();
  493. SetIsEndSelection(true);
  494. ContinuousController.instance.StartCoroutine(OnClickButtonActionCoroutine(_onClickNotSelectButtonAction));
  495. }
  496. #endregion
  497. #region Processing when the Select End button is pressed
  498. public void OnClickEndSelectButton()
  499. {
  500. if (CanEndSelection())
  501. {
  502. GManager.instance.PlayDecisionSE();
  503. List<CardSource> _PreSelectedList = new List<CardSource>();
  504. foreach (HandCard handCard1 in _preSelectedHandCardList)
  505. {
  506. _PreSelectedList.Add(handCard1.cardSource);
  507. }
  508. SelectedList = new List<CardSource>();
  509. foreach (CardSource cardSource in _PreSelectedList)
  510. {
  511. SelectedList.Add(cardSource);
  512. }
  513. foreach (Player player in GManager.instance.turnStateMachine.gameContext.Players_ForTurnPlayer)
  514. {
  515. foreach (FieldPermanentCard fieldPermanentCard in player.FieldPermanentObjects)
  516. {
  517. fieldPermanentCard.OffPermanentIndexText();
  518. }
  519. }
  520. CloseSelectCardPanel();
  521. SetIsEndSelection(true);
  522. ContinuousController.instance.StartCoroutine(OnClickButtonActionCoroutine(_onClickEndSelectButtonAction));
  523. }
  524. }
  525. IEnumerator OnClickButtonActionCoroutine(UnityAction Action)
  526. {
  527. yield return new WaitForSeconds(0.1f);
  528. Action?.Invoke();
  529. }
  530. #endregion
  531. #region Temporarily display/hide panel
  532. public void OnClickReturnToSelectCardButton()
  533. {
  534. this.gameObject.SetActive(true);
  535. ReturnToSelectCardButton.gameObject.SetActive(false);
  536. }
  537. public void OnClickCheckFieldButton()
  538. {
  539. this.gameObject.SetActive(false);
  540. ReturnToSelectCardButton.gameObject.SetActive(true);
  541. ReturnToSelectCardButton.onClick.RemoveAllListeners();
  542. ReturnToSelectCardButton.onClick.AddListener(() => OnClickReturnToSelectCardButton());
  543. }
  544. #endregion
  545. }