using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace Wizard; public class TournamentController : MonoBehaviour { [SerializeField] private GameObject _tournamentRoot; [SerializeField] private Transform _roundsRoot; [SerializeField] private GameObject _originalRound; [SerializeField] private UIDragMultiScrollView _dragMultiScrollView; [SerializeField] private UIButton _prevButton; [SerializeField] private UIButton _nextButton; [SerializeField] private UIPanel _panel; [SerializeField] private UISprite _leftCurtainSprite; [SerializeField] private UISprite _rightCurtainSprite; [SerializeField] private Transform _scrollBarRoot; [SerializeField] private GameObject _originalScrollBarObj; [SerializeField] private UIGrid _radioIconGrid; [SerializeField] private GameObject _originalRadioIconObj; private List _rounds; private bool _isChangeableSelectRound = true; private int _selectRoundIndex; private (float, float)[][] _cellPosBank; private SpringPanelWithUpdate _currentSpring; private List _radioIcons; private const float ROUND_OFFSET_X = -16f; private const float ROUND_WIDTH = 240f; private const float PARENT_CELL_INTERVAL = 200f; private const float CHANGE_SELECT_ROUND_DRAG_THRESHOLD_X = 45.5f; private const float CHANGE_SELECT_ROUND_DRAG_NG_THRESHOLD_Y = 16.25f; private const float CHANGE_SELECT_ROUND_DURATION = 0.15f; private const float CURTAIN_ALPHA_MAX = 0.5f; private void Start() { _originalRound.SetActive(value: false); UIEventListener uIEventListener = UIEventListener.Get(_dragMultiScrollView.gameObject); uIEventListener.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener.onDrag, new UIEventListener.VectorDelegate(OnDrag)); _prevButton.onClick.Add(new EventDelegate(ChangeSelectRoundToPrevious)); _nextButton.onClick.Add(new EventDelegate(ChangeSelectRoundToNext)); } public IEnumerator Setup(TournamentData data, TournamentCellData currentCell, GatheringInfo info, bool isVisible) { int count = data.Rounds.Count; _rounds = new List(count); _radioIcons = new List(count); _originalRound.SetActive(value: true); _originalRadioIconObj.SetActive(value: true); _originalScrollBarObj.SetActive(value: true); Vector3 localPosition = _originalScrollBarObj.transform.localPosition; int currentRound = 0; for (int i = 0; i < count; i++) { TournamentRoundData tournamentRoundData = data.Rounds[i]; TournamentRound component = NGUITools.AddChild(_roundsRoot.gameObject, _originalRound).GetComponent(); UIScrollBar component2 = NGUITools.AddChild(_scrollBarRoot.gameObject, _originalScrollBarObj).GetComponent(); component2.transform.localPosition = localPosition; component.ScrollView.verticalScrollBar = component2; component.ScrollBarPanel = component2.GetComponent(); component.ScrollBarCollider = component2.backgroundWidget.GetComponent(); component.Setup(tournamentRoundData, info); component.transform.localPosition = new Vector3(240f * (float)i, 0f, 0f); _dragMultiScrollView.AddScrollView(component.ScrollView); _rounds.Add(component); _radioIcons.Add(NGUITools.AddChild(_radioIconGrid.gameObject, _originalRadioIconObj).GetComponent()); if (currentCell != null && tournamentRoundData.Cells.Contains(currentCell)) { currentRound = i; } } _originalRound.SetActive(value: false); _originalRadioIconObj.SetActive(value: false); _originalScrollBarObj.SetActive(value: false); _radioIconGrid.Reposition(); _cellPosBank = new(float, float)[_rounds.Count][]; for (int j = 0; j < _cellPosBank.Length; j++) { (float, float)[] array = new(float, float)[_rounds[j].Cells.Count]; for (int k = 0; k < array.Length; k++) { array[k] = (0f, 0f); } _cellPosBank[j] = array; } _dragMultiScrollView.OnPressCallback = OnPressScrollView; _dragMultiScrollView.OnScrollCallback = OnScrollWheel; if (count > 0) { _rounds[0].ScrollView.onMomentumMove = OnMomentumMove; } _panel.alpha = 0f; yield return null; AppendScrollBarEvent(); foreach (TournamentRound round in _rounds) { round.SetCellEnable(isEnabled: true); } SetupCellLineEnd(); PropagateScrollValue(currentRound); ChangeSelectRoundIndex(currentRound, isImmediate: true, isPlaySe: false); ChangeFocusCellImmediate(currentCell); RestrictWithinBounds(isImmediate: true); SetVisible(isVisible); if (isVisible && currentCell != null && currentCell.ViewerId == PlayerStaticData.UserViewerID) { TournamentCell tournamentCell = GetTournamentCell(currentCell); if (tournamentCell != null) { tournamentCell.SetYouMarkVisible(isVisible: true); } } yield return null; _panel.alpha = 1f; } private void OnDrag(GameObject obj, Vector2 delta) { if (!(delta.y > 16.25f) && !(delta.y < -16.25f)) { if (delta.x > 45.5f) { ChangeSelectRoundToPrevious(); } else if (delta.x < -45.5f) { ChangeSelectRoundToNext(); } } } private void ChangeSelectRoundToPrevious() { if (_isChangeableSelectRound && _selectRoundIndex > 0) { ChangeSelectRoundIndex(_selectRoundIndex - 1); } } private void ChangeSelectRoundToNext() { if (_isChangeableSelectRound && _selectRoundIndex < _rounds.Count - 1) { ChangeSelectRoundIndex(_selectRoundIndex + 1); } } private void ChangeSelectRoundIndex(int index, bool isImmediate = false, bool isPlaySe = true) { if (!_isChangeableSelectRound) { return; } SetupCellPosition(index); Vector3 vector = new Vector3((float)(-index) * 240f + -16f, 0f, 0f); if (isImmediate) { _roundsRoot.localPosition = vector; ApplyCellPosition(1f); UpdateCellLine(); UpdateWatchPosition(); UpdateRoundAlpha(_selectRoundIndex, index, 1f); UpdateCurtainAlpha(_selectRoundIndex, index, 1f); UpdateScrollViewBounds(); _panel.SetDirty(); } else { _isChangeableSelectRound = false; AdjustCellPositionToFocusCell(index); UpdateRoundWatchEnable(-1); int beforeIndex = _selectRoundIndex; TweenPosition tweenPosition = TweenPositionWithUpdate.Begin(_roundsRoot.gameObject, 0.15f, vector, delegate(float factor) { ApplyCellPosition(factor); UpdateCellLine(); UpdateWatchPosition(); UpdateRoundAlpha(beforeIndex, index, factor); UpdateCurtainAlpha(beforeIndex, index, factor); UpdateScrollViewBounds(); RestrictWithinBounds(isImmediate: true); _panel.SetDirty(); }); tweenPosition.method = UITweener.Method.EaseOut; tweenPosition.onFinished.Add(new EventDelegate(delegate { _isChangeableSelectRound = true; RestrictWithinBounds(isImmediate: false); })); } _selectRoundIndex = index; UpdateRoundWatchEnable(index); ChangeScrollBarController(); UpdateRadioIcon(); UpdateArrowButton(); if (isPlaySe) { GameMgr.GetIns().GetSoundMgr().PlaySe(Se.TYPE.SYS_SLIDE_BTN); } } private void ChangeFocusCellImmediate(TournamentCellData focusCell) { if (focusCell != null) { TournamentRound tournamentRound = _rounds[_selectRoundIndex]; TournamentCell tournamentCell = tournamentRound.Cells.FirstOrDefault((TournamentCell c) => c != null && c.Data == focusCell); if (!(tournamentCell == null)) { Transform transform = tournamentRound.ScrollView.panel.transform; Vector3 relative = -transform.transform.InverseTransformPoint(tournamentCell.transform.position); relative.x = transform.localPosition.x; tournamentRound.ScrollView.MoveRelative(relative); PropagateScrollValue(_selectRoundIndex); } } } private void UpdateRadioIcon() { int i = 0; for (int count = _radioIcons.Count; i < count; i++) { _radioIcons[i].spriteName = ((i == _selectRoundIndex) ? "carousel_marker_on" : "carousel_marker_off"); } } private void UpdateArrowButton() { _prevButton.gameObject.SetActive(_selectRoundIndex > 0); _nextButton.gameObject.SetActive(_selectRoundIndex < _rounds.Count - 1); } private void SetupCellPosition(int selectRoundIndex) { for (int i = 0; i < _rounds.Count; i++) { TournamentRound tournamentRound = _rounds[i]; for (int j = 0; j < tournamentRound.Cells.Count; j++) { _cellPosBank[i][j].Item1 = tournamentRound.Cells[j].transform.localPosition.y; } } int num = 0; float num2 = 200f; for (int num3 = selectRoundIndex + 1; num3 >= selectRoundIndex - 1; num3--) { if (num3 < _rounds.Count && num3 >= 0) { num = num3; TournamentRound tournamentRound2 = _rounds[num3]; for (int k = 0; k < tournamentRound2.Cells.Count; k++) { _cellPosBank[num3][k].Item2 = -200f * (float)k; } break; } } float num4 = num2 * 0.5f; for (int num5 = num - 1; num5 >= 0; num5--) { TournamentRound tournamentRound3 = _rounds[num5]; TournamentRound tournamentRound4 = _rounds[num5 + 1]; if (tournamentRound4.Data.IsExtraRound) { for (int l = 0; l < tournamentRound3.Cells.Count; l++) { _cellPosBank[num5][l].Item2 = _cellPosBank[num5 + 1][l].Item2; } } else { num2 *= 0.5f; num4 = num2 * 0.5f; for (int m = 0; m < tournamentRound3.Cells.Count; m++) { TournamentCell childCell = tournamentRound3.Cells[m]; int childIndex; int parentCellIndex = GetParentCellIndex(childCell, tournamentRound4, out childIndex); float item = _cellPosBank[num5 + 1][parentCellIndex].Item2; _cellPosBank[num5][m].Item2 = item + num4 - num2 * (float)childIndex; } } } for (int n = num + 1; n < _rounds.Count; n++) { TournamentRound tournamentRound5 = _rounds[n]; TournamentRound childRound = _rounds[n - 1]; if (tournamentRound5.Data.IsExtraRound) { for (int num6 = 0; num6 < tournamentRound5.Cells.Count; num6++) { _cellPosBank[n][num6].Item2 = _cellPosBank[n - 1][num6].Item2; } continue; } float num7 = 0f; for (int num8 = 0; num8 < tournamentRound5.Cells.Count; num8++) { TournamentCell parentCell = tournamentRound5.Cells[num8]; int childCellIndex = GetChildCellIndex(parentCell, childRound); if (childCellIndex >= 0) { num7 = (_cellPosBank[n][num8].Item2 = (_cellPosBank[n - 1][childCellIndex].Item2 + _cellPosBank[n - 1][childCellIndex + 1].Item2) * 0.5f); } else { _cellPosBank[n][num8].Item2 = num7 - 200f; } } } } private int GetParentCellIndex(TournamentCell childCell, TournamentRound parentRound, out int childIndex) { TournamentCellData data = childCell.Data; List cells = parentRound.Cells; for (int i = 0; i < cells.Count; i++) { TournamentCellData data2 = cells[i].Data; if (data2.Children == null) { continue; } for (int j = 0; j < data2.Children.Length; j++) { if (data2.Children[j] == data) { childIndex = j; return i; } } } childIndex = -1; return -1; } private int GetChildCellIndex(TournamentCell parentCell, TournamentRound childRound) { TournamentCellData data = parentCell.Data; List cells = childRound.Cells; for (int i = 0; i < cells.Count; i++) { if (cells[i].Data.Parent == data) { return i; } } return -1; } private void AdjustCellPositionToFocusCell(int selectRoundIndex) { int num = selectRoundIndex - _selectRoundIndex; if (num < -1 || num > 1 || num == 0) { return; } TournamentRound tournamentRound = _rounds[_selectRoundIndex]; float y = tournamentRound.ScrollView.panel.clipOffset.y; int num2 = -1; float num3 = float.MaxValue; for (int i = 0; i < tournamentRound.Cells.Count; i++) { float num4 = Mathf.Abs(tournamentRound.Cells[i].transform.localPosition.y - y); if (!(num4 > num3)) { num3 = num4; num2 = i; } } (float, float) tuple = _cellPosBank[_selectRoundIndex][num2]; float item = tuple.Item1; float item2 = tuple.Item2; float num5 = item - item2; int j = 0; for (int count = _rounds.Count; j < count; j++) { int k = 0; for (int count2 = _rounds[j].Cells.Count; k < count2; k++) { _cellPosBank[j][k].Item2 += num5; } } } private void ApplyCellPosition(float factor) { int i = 0; for (int count = _rounds.Count; i < count; i++) { TournamentRound tournamentRound = _rounds[i]; int j = 0; for (int count2 = tournamentRound.Cells.Count; j < count2; j++) { TournamentCell tournamentCell = tournamentRound.Cells[j]; (float, float) tuple = _cellPosBank[i][j]; UIUtil.SetLocalPositionY(tournamentCell.transform, Mathf.Lerp(tuple.Item1, tuple.Item2, factor)); } } } private void UpdateWatchPosition() { foreach (TournamentRound round in _rounds) { round.UpdateWatchPosition(); } } private void UpdateRoundAlpha(int beforeIndex, int afterIndex, float factor) { int i = 0; for (int count = _rounds.Count; i < count; i++) { TournamentRound tournamentRound = _rounds[i]; float a = CalcRoundAlpha(i - beforeIndex); float b = CalcRoundAlpha(i - afterIndex); tournamentRound.ScrollView.panel.alpha = Mathf.Lerp(a, b, factor); a = CalcWatchAlpha(i - beforeIndex); b = CalcWatchAlpha(i - afterIndex); tournamentRound.SetWatchAlpha(Mathf.Lerp(a, b, factor)); } static float CalcRoundAlpha(int indexDiff) { return Mathf.Max(0f, Mathf.Min(1f, 2f - (float)Mathf.Abs(indexDiff))); } static float CalcWatchAlpha(int indexDiff) { return Mathf.Max(0f, Mathf.Min(1f, 1f - (float)Mathf.Abs(indexDiff))); } } private void UpdateRoundWatchEnable(int selectRoundIndex) { for (int i = 0; i < _rounds.Count; i++) { _rounds[i].SetWatchEnable(i == selectRoundIndex); } } private void UpdateCurtainAlpha(int beforeIndex, int afterIndex, float factor) { float a = ((beforeIndex <= 0) ? 0f : 0.5f); float b = ((afterIndex <= 0) ? 0f : 0.5f); _leftCurtainSprite.alpha = Mathf.Lerp(a, b, factor); int num = _rounds.Count - 1; float a2 = ((beforeIndex >= num) ? 0f : 0.5f); float b2 = ((afterIndex >= num) ? 0f : 0.5f); _rightCurtainSprite.alpha = Mathf.Lerp(a2, b2, factor); } private void UpdateCellLine() { int i = 0; for (int count = _rounds.Count; i < count; i++) { List cells = _rounds[i].Cells; int j = 0; for (int count2 = cells.Count; j < count2; j++) { cells[j].UpdateLine(); } } } private void SetupCellLineEnd() { int i = 0; for (int num = _rounds.Count - 1; i < num; i++) { List cells = _rounds[i].Cells; List cells2 = _rounds[i + 1].Cells; int j = 0; for (int count = cells.Count; j < count; j++) { TournamentCell cell = cells[j]; if (cell.Data.IsPreExtra) { cell.SetLineEndTransform(cells.Find((TournamentCell c) => c != cell).RightConnectorTransform); continue; } TournamentCellData parentCellData = cell.Data.Parent; TournamentCell tournamentCell = cells2.Find((TournamentCell c) => c != null && c.Data == parentCellData); if (tournamentCell != null) { cell.SetLineEndTransform(tournamentCell.LeftConnectorTransform); } } } } private void UpdateScrollViewBounds() { foreach (TournamentRound round in _rounds) { round.ScrollView.NeedsCalculateBounds = true; } } private void ChangeScrollBarController() { int scrollTargetRoundIndex = GetScrollTargetRoundIndex(); int i = 0; for (int count = _rounds.Count; i < count; i++) { _rounds[i].SetScrollBarEnable(i == scrollTargetRoundIndex); } } private int GetScrollTargetRoundIndex() { return Mathf.Max(0, _selectRoundIndex - 1); } private void AppendScrollBarEvent() { foreach (TournamentRound round in _rounds) { UIEventListener uIEventListener = UIEventListener.Get(round.ScrollView.verticalScrollBar.backgroundWidget.gameObject); uIEventListener.onPress = (UIEventListener.BoolDelegate)Delegate.Combine(uIEventListener.onPress, new UIEventListener.BoolDelegate(OnPressScrollBar)); uIEventListener.onDrag = (UIEventListener.VectorDelegate)Delegate.Combine(uIEventListener.onDrag, new UIEventListener.VectorDelegate(OnDragScrollBar)); } } private void OnPressScrollBar(GameObject go, bool isPressed) { PropagateScrollValue(GetRoundIndexByScrollBar(go.GetComponentInParent())); } private void OnDragScrollBar(GameObject go, Vector2 delta) { PropagateScrollValue(GetRoundIndexByScrollBar(go.GetComponentInParent())); } private int GetRoundIndexByScrollBar(UIScrollBar scrollBar) { int i = 0; for (int count = _rounds.Count; i < count; i++) { if (!(_rounds[i].ScrollView.verticalScrollBar != scrollBar)) { return i; } } return -1; } private void PropagateScrollValue(int roundIndex) { TournamentRound tournamentRound = _rounds[roundIndex]; UIScrollView scrollView = tournamentRound.ScrollView; Vector3 localPosition = scrollView.transform.localPosition; Vector2 clipOffset = scrollView.panel.clipOffset; Vector3 currentMomentum = scrollView.currentMomentum; foreach (TournamentRound round in _rounds) { if (!(round == tournamentRound)) { UIScrollView scrollView2 = round.ScrollView; scrollView2.transform.localPosition = localPosition; scrollView2.panel.clipOffset = clipOffset; scrollView2.panel.SetDirty(); scrollView2.currentMomentum = currentMomentum; } } } private void OnPressScrollView(bool isPressed) { if (!isPressed) { RestrictWithinBounds(isImmediate: false); } } private void OnScrollWheel(float delta) { RestrictWithinBounds(isImmediate: false); } private void OnMomentumMove() { RestrictWithinBounds(isImmediate: false); } private void RestrictWithinBounds(bool isImmediate) { int targetIndex = GetScrollTargetRoundIndex(); UIScrollView scrollView = _rounds[targetIndex].ScrollView; Bounds bounds = scrollView.bounds; for (int i = Mathf.Max(0, _selectRoundIndex - 1); i <= Mathf.Min(_selectRoundIndex + 1, _rounds.Count - 1); i++) { Bounds bounds2 = _rounds[i].ScrollView.bounds; if (bounds2.min.y < bounds.min.y) { Vector3 min = bounds.min; min.y = bounds2.min.y; bounds.min = min; } if (bounds2.max.y > bounds.max.y) { Vector3 max = bounds.max; max.y = bounds2.max.y; bounds.max = max; } } Vector3 vector = scrollView.panel.CalculateConstrainOffset(bounds.min, bounds.max); vector.x = 0f; if (!(vector.sqrMagnitude > 0.1f)) { return; } if (isImmediate) { scrollView.MoveRelative(vector); scrollView.currentMomentum = Vector3.zero; scrollView.CurrentScroll = 0f; PropagateScrollValue(targetIndex); return; } Vector3 pos = scrollView.transform.localPosition + vector; pos.x = Mathf.Round(pos.x); pos.y = Mathf.Round(pos.y); StopSpring(); SpringPanelWithUpdate springPanelWithUpdate = SpringPanelWithUpdate.Begin(scrollView.gameObject, pos, 8f, delegate { PropagateScrollValue(targetIndex); }); springPanelWithUpdate.onUpdate = delegate { PropagateScrollValue(targetIndex); }; _currentSpring = springPanelWithUpdate; } private void StopSpring() { if (_currentSpring == null) { return; } if (!_currentSpring.enabled) { _currentSpring = null; return; } if (_currentSpring.onFinished != null) { _currentSpring.onFinished(); } _currentSpring.enabled = false; _currentSpring = null; } public void SetVisible(bool isVisible) { _tournamentRoot.SetActive(isVisible); } private TournamentCell GetTournamentCell(TournamentCellData cellData) { foreach (TournamentRound round in _rounds) { TournamentCell tournamentCell = round.Cells.FirstOrDefault((TournamentCell cell) => cell.Data == cellData); if (tournamentCell != null) { return tournamentCell; } } return null; } }