using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using EntityStates; using UnityEngine; using UnityEngine.UI; namespace RoR2.UI; [RequireComponent(typeof(RectTransform))] [ExecuteAlways] public class CreditsPanelController : MonoBehaviour { public abstract class BaseCreditsPanelState : BaseState { protected CreditsPanelController creditsPanelController { get; private set; } protected abstract bool enableSkipButton { get; } public override void OnEnter() { base.OnEnter(); creditsPanelController = GetComponent(); if ((bool)creditsPanelController && (bool)creditsPanelController.skipButton) { creditsPanelController.skipButton.gameObject.SetActive(enableSkipButton); } } protected void SetScroll(float scroll) { if ((bool)creditsPanelController) { creditsPanelController.SetScroll(scroll); } } protected void SetFade(float fade) { fade = Mathf.Clamp01(fade); if ((bool)creditsPanelController && (bool)creditsPanelController.fadePanel) { Color color = creditsPanelController.fadePanel.color; color.a = fade; creditsPanelController.fadePanel.color = color; } } } public class IntroState : BaseCreditsPanelState { protected override bool enableSkipButton => false; public override void OnEnter() { base.OnEnter(); SetScroll(0f); SetFade(base.creditsPanelController.introFadeCurve.Evaluate(0f)); base.creditsPanelController.StartCoroutine(PrepareContent()); } public override void Update() { base.Update(); float num = Mathf.Clamp01(base.age / base.creditsPanelController.introDuration); SetFade(1f - num); if (num >= 1f) { outer.SetNextState(new MainScrollState()); } } private IEnumerator PrepareContent() { SetIgnoreLayout(value: false); yield return null; VerticalLayoutGroup component = base.creditsPanelController.content.GetComponent(); if (component != null) { component.enabled = false; } ContentSizeFitter component2 = base.creditsPanelController.content.GetComponent(); if (component2 != null) { component2.enabled = false; } yield return null; SetIgnoreLayout(value: true); } private void SetIgnoreLayout(bool value) { for (int i = 0; i < base.creditsPanelController.content.childCount; i++) { LayoutElement component = base.creditsPanelController.content.GetChild(i).GetComponent(); if (component != null) { component.ignoreLayout = value; } } } } public class MainScrollState : BaseCreditsPanelState { public static AnimationCurve scrollCurve; protected override bool enableSkipButton => true; public override void OnEnter() { base.OnEnter(); SetFade(0f); base.creditsPanelController.skipButton.gameObject.SetActive(value: true); } public override void Update() { base.Update(); float num = Mathf.Clamp01(base.age / base.creditsPanelController.scrollDuration); SetScroll(scrollCurve.Evaluate(num)); base.creditsPanelController.DisableInvisibleElements(); if (num >= 1f) { outer.SetNextState(new OutroState()); } } } public class OutroState : BaseCreditsPanelState { protected override bool enableSkipButton => true; public override void OnEnter() { base.OnEnter(); SetScroll(1f); SetFade(base.creditsPanelController.outroFadeCurve.Evaluate(0f)); } public override void Update() { base.Update(); float num = Mathf.Clamp01(base.age / base.creditsPanelController.outroDuration); SetFade(num); if (num >= 1f) { EntityState.Destroy(base.gameObject); } } } public RectTransform content; public ScrollRect scrollRect; public float introDuration; public AnimationCurve introFadeCurve; public float outroDuration; public AnimationCurve outroFadeCurve; public float scrollDuration; public RawImage fadePanel; public MPButton skipButton; public VoteInfoPanelController voteInfoPanel; [Range(0f, 1f)] public float editorScroll; private Dictionary> canvases = new Dictionary>(); private const float SCREEN_HEIGHT = 1080f; private void OnEnable() { InstanceTracker.Add(this); GameObject[] array = GameObject.FindGameObjectsWithTag("CreditsGroup"); for (int i = 0; i < array.Length; i++) { Canvas component = array[i].GetComponent(); if (component != null) { canvases.Add(component, new List(component.GetComponentsInChildren())); } } } private void OnDisable() { InstanceTracker.Remove(this); } private void SetScroll(float scroll) { if ((bool)scrollRect) { scrollRect.verticalNormalizedPosition = 1f - scroll; } } private void Update() { if (!Application.IsPlaying(this)) { SetScroll(editorScroll); } } public void DisableInvisibleElements() { float height = scrollRect.viewport.rect.height; float num = 100f; for (int i = 1; i < scrollRect.content.childCount; i++) { RectTransform component = scrollRect.content.GetChild(i).GetComponent(); float num2 = component.sizeDelta.y * 0.5f + num; float num3 = Mathf.Abs(component.localPosition.y) - num2; float num4 = Mathf.Abs(component.localPosition.y) + num2; float y = ((RectTransform)content.transform).anchoredPosition.y; bool active = num4 > y && num3 < y + height; component.gameObject.SetActive(active); } } [ContextMenu("Generate Credits Roles JSON")] private void GenerateCreditsRoles() { CreditsStripGroupBuilder[] componentsInChildren = GetComponentsInChildren(); Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); CreditsStripGroupBuilder[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { foreach (var namesAndEnglishRole in array[i].GetNamesAndEnglishRoles()) { string text = CreditsStripGroupBuilder.EnglishRoleToToken(namesAndEnglishRole.englishRoleName); if (dictionary.TryGetValue(text, out var value)) { if (!string.Equals(namesAndEnglishRole.englishRoleName, value, StringComparison.Ordinal)) { Debug.LogError("Conflict in role \"" + text + "\": a=\"" + value + "\" b=\"" + namesAndEnglishRole.englishRoleName + "\""); } } else { dictionary.Add(text, namesAndEnglishRole.englishRoleName); } } } List> list = dictionary.OrderBy((KeyValuePair kv) => kv.Key).ToList(); StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair item in list) { stringBuilder.Append("\"").Append(item.Key).Append("\": \"") .Append(item.Value) .Append("\",") .AppendLine(); } GUIUtility.systemCopyBuffer = stringBuilder.ToString(); } [ConCommand(commandName = "credits_start", flags = ConVarFlags.None, helpText = "Begins the credits sequence.")] private static void CCCreditsStart(ConCommandArgs args) { if (InstanceTracker.GetInstancesList().Count != 0) { throw new ConCommandException("Already in credits sequence."); } CreditsPanelController creditsPanelController = UnityEngine.Object.Instantiate(LegacyResourcesAPI.Load("Prefabs/UI/Credits/CreditsPanel"), RoR2Application.instance.mainCanvas.transform).GetComponent(); creditsPanelController.skipButton.onClick.AddListener(delegate { UnityEngine.Object.Destroy(creditsPanelController.gameObject); }); } }