using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UI; namespace RoR2.UI; public class SpriteAsNumberManager : MonoBehaviour, ILayoutGroup, ILayoutController { private enum Alignment { Right, Center, Left } private enum SpriteCharacterType { Number, Punctuation } [Tooltip("This is only used internally on editor refresh to tell the object how to format itself.")] [SerializeField] private bool internalUseOnlyIsTimer; [SerializeField] private Alignment textAlignment = Alignment.Center; [SerializeField] private int debugValue; [SerializeField] [FormerlySerializedAs("spaceBetweenImages")] [Tooltip("Additional Space between non-punctuation characters.")] private float spaceBetweenCharacters; [Tooltip("Will scale punctuation sprites up or down (1 = normal). It will not change the spacing around the sprite.")] [SerializeField] private float scalePunctuationBy; [SerializeField] private float spaceBetweenPunctuation; [SerializeField] private Transform imagePrefab; [SerializeField] private int startingNumberOfPrefabs; [SerializeField] private Sprite colonSprite; [SerializeField] private Sprite forwardSlashSprite; [SerializeField] private Sprite questionMarkSprite; [SerializeField] private Sprite negativeSymbolSprite; [SerializeField] private Sprite percentSymbolSprite; [SerializeField] private Sprite dollarSignSymbolSprite; [SerializeField] private Sprite xSprite; private const int CONST_COLON = -1111; private const int CONST_NEGATIVE = -2222; private const int CONST_FSLASH = -3333; private const int CONST_PERCENT = -4444; private const int CONST_DOLLARSIGN = -5555; private const int CONST_X = -6666; private RectTransform rectTransform; private int cachedValue = -1111; private float cachedCanvasHeight; private float defaultSpriteHeight; private float defaultSpriteWidth; private bool isVisible = true; [SerializeField] private Sprite[] referenceArray; private List imageList = new List(); private List rtList = new List(); private List charTypeList = new List(); private int totalImagesInUse; private bool finishedSetup; private void Awake() { TrySetup(); } public void TrySetup() { if (!finishedSetup) { rectTransform = GetComponent(); rtList = new List(); imageList = new List(); charTypeList = new List(); defaultSpriteHeight = referenceArray[0].rect.height; defaultSpriteWidth = referenceArray[0].rect.width; LoadAnyExistingChildren(); int num = Mathf.Max(startingNumberOfPrefabs - base.transform.childCount, 0); for (int i = 0; i < num; i++) { InstantiateNewImage(); } totalImagesInUse = 0; RebuildLayout(); finishedSetup = true; } } public void LoadAnyExistingChildren() { foreach (RectTransform item in base.transform) { if (item.TryGetComponent(out var component)) { rtList.Add(item); imageList.Add(component); charTypeList.Add(SpriteCharacterType.Number); } } } public void SetVisible(bool b) { isVisible = b; HandleActivationOfImages(); } public void SetPercentValue(int intPercent) { TrySetup(); if (intPercent != cachedValue || !isVisible) { cachedValue = intPercent; isVisible = true; List list = new List(); list.Add(-4444); LoadListWithDigitPositions(intPercent, ref list); UpdateSpriteObjectsWithListValues(list); } } public void SetItemCount(int count) { TrySetup(); if (count != cachedValue || !isVisible) { cachedValue = count; isVisible = true; List list = new List(); LoadListWithDigitPositions(count, ref list); list.Add(-6666); UpdateSpriteObjectsWithListValues(list); } } public void SetTimerValue(int totalTimeInSeconds) { TrySetup(); if (totalTimeInSeconds == cachedValue && isVisible) { return; } cachedValue = totalTimeInSeconds; isVisible = true; List list = new List(); float num = totalTimeInSeconds; int num2 = Mathf.Min(Mathf.FloorToInt(num * (1f / 60f)), 999); int value = (int)num - num2 * 60; list.Add(GetDigitPosition(value, 0)); list.Add(GetDigitPosition(value, 1)); list.Add(-1111); int num3 = Mathf.Max(GetTotalDigitPositions(num2), 2); for (int i = 0; i < num3; i++) { int digitPosition = GetDigitPosition(num2, i); if (digitPosition > 0 || i < 2) { list.Add(digitPosition); } } UpdateSpriteObjectsWithListValues(list); } public void SetHitPointValues(int currentHP, int totalHP) { TrySetup(); List list = new List(); LoadListWithDigitPositions(totalHP, ref list); list.Add(-3333); LoadListWithDigitPositions(currentHP, ref list); UpdateSpriteObjectsWithListValues(list); } public int GetDigitPosition(int value, int position) { value = Mathf.Abs(value); int num = (int)Mathf.Pow(10f, (float)position + 1f); position = (int)Mathf.Pow(10f, position); if (value >= num) { float num2 = value / num; value -= (int)num2 * num; } return value / position; } public void LoadListWithDigitPositions(int value, ref List list, int forceZeroTillAtLeastXPosition = 0) { bool flag = value < 0; value = Mathf.Abs(value); if (value == 0 && forceZeroTillAtLeastXPosition == 0) { list.Add(0); return; } int num = Math.Max(GetTotalDigitPositions(value), forceZeroTillAtLeastXPosition); for (int i = 0; i < num; i++) { int digitPosition = GetDigitPosition(value, i); list.Add(digitPosition); } if (flag) { list.Add(-2222); } } public int GetTotalDigitPositions(int val) { val = Mathf.Abs(val); int i; for (i = 0; (float)val >= Mathf.Pow(10f, i); i++) { } return i; } public void SetSpriteColor(Color color) { for (int i = 0; i < totalImagesInUse; i++) { imageList[i].color = color; } } public void UpdateSpriteObjectsWithListValues(List listValues, int startingImageIndex = 0) { VerifyAllObjectsInList(); int count = listValues.Count; int count2; for (count2 = imageList.Count; count2 <= startingImageIndex + count; count2 = imageList.Count) { InstantiateNewImage(); } totalImagesInUse = count2 + startingImageIndex; for (int i = 0; i < count2; i++) { if (i >= count) { totalImagesInUse = i; break; } Image image = imageList[i]; switch (listValues[i]) { case -1111: image.sprite = colonSprite; charTypeList[i] = SpriteCharacterType.Punctuation; break; case -2222: image.sprite = negativeSymbolSprite ?? questionMarkSprite; charTypeList[i] = SpriteCharacterType.Punctuation; break; case -3333: image.sprite = forwardSlashSprite ?? questionMarkSprite; charTypeList[i] = SpriteCharacterType.Punctuation; break; case -4444: image.sprite = percentSymbolSprite ?? questionMarkSprite; charTypeList[i] = SpriteCharacterType.Punctuation; break; case -5555: image.sprite = dollarSignSymbolSprite ?? questionMarkSprite; charTypeList[i] = SpriteCharacterType.Punctuation; break; case -6666: image.sprite = xSprite ?? questionMarkSprite; charTypeList[i] = SpriteCharacterType.Punctuation; break; default: image.sprite = referenceArray[Mathf.Clamp(listValues[i], 0, 9)]; charTypeList[i] = SpriteCharacterType.Number; break; } } UpdateSpriteSizes(); RebuildLayout(); } private void VerifyAllObjectsInList() { int count = rtList.Count; if (count < 1) { return; } for (int num = count - 1; num >= 0; num--) { if (rtList[num] == null || imageList[num] == null) { rtList.RemoveAt(num); imageList.RemoveAt(num); charTypeList.RemoveAt(num); } } } private void UpdateSpriteSizes() { cachedCanvasHeight = rectTransform.rect.height; float num = cachedCanvasHeight / defaultSpriteHeight; Vector2 sizeDelta = default(Vector2); for (int i = 0; i < totalImagesInUse; i++) { if (charTypeList[i] == SpriteCharacterType.Punctuation) { sizeDelta.x = imageList[i].sprite.rect.width * num * scalePunctuationBy; sizeDelta.y = imageList[i].sprite.rect.height * num * scalePunctuationBy; } else { sizeDelta.x = imageList[i].sprite.rect.width * num; sizeDelta.y = imageList[i].sprite.rect.height * num; } sizeDelta.x = Mathf.Round(sizeDelta.x * 100f) / 100f; sizeDelta.y = Mathf.Round(sizeDelta.y * 100f) / 100f; rtList[i].sizeDelta = sizeDelta; } } private void InstantiateNewImage() { RectTransform component = UnityEngine.Object.Instantiate(imagePrefab, rectTransform).GetComponent(); rtList.Add(component); Image component2 = component.GetComponent(); imageList.Add(component2); charTypeList.Add(SpriteCharacterType.Number); component.sizeDelta = new Vector2(defaultSpriteWidth, defaultSpriteHeight); component2.preserveAspect = true; } private void RebuildLayout() { if (base.transform.childCount < 1) { return; } HandleActivationOfImages(); if (isVisible && totalImagesInUse >= 1) { if (cachedCanvasHeight != this.rectTransform.rect.height) { UpdateSpriteSizes(); } float num = this.rectTransform.rect.height / defaultSpriteHeight; float singleImageWidth = defaultSpriteWidth * num; float totalImageWidth = GetTotalImageWidth(); float num2 = GetStartingX(textAlignment, singleImageWidth, totalImageWidth, rtList[0].pivot.x); float y = 0f; for (int i = 0; i < totalImagesInUse; i++) { RectTransform rectTransform = rtList[i]; bool num3 = charTypeList[i] != SpriteCharacterType.Punctuation && i + 1 < totalImagesInUse && charTypeList[i + 1] != SpriteCharacterType.Punctuation; singleImageWidth = rtList[i].rect.width * 0.5f; num2 -= singleImageWidth; rectTransform.anchoredPosition = new Vector2(num2, y); num2 = ((!num3) ? (num2 - (singleImageWidth + spaceBetweenPunctuation)) : (num2 - (singleImageWidth + spaceBetweenCharacters))); } } } private void InitializeVariablesForInEditorViewing() { rectTransform = GetComponent(); rtList = new List(); imageList = new List(); charTypeList = new List(); defaultSpriteHeight = referenceArray[0].rect.height; defaultSpriteWidth = referenceArray[0].rect.width; LoadAnyExistingChildren(); totalImagesInUse = rtList.Count; } private float GetTotalImageWidth() { float num = 0f; for (int i = 0; i < totalImagesInUse; i++) { num += rtList[i].rect.width; num = ((charTypeList[i] != 0) ? (num + spaceBetweenPunctuation) : (num + spaceBetweenCharacters)); } return num; } private float GetStartingX(Alignment textAlignment, float singleImageWidth, float totalImageWidth, float singleImageAlignment) { singleImageAlignment *= singleImageWidth; float num = rectTransform.pivot.x * rectTransform.rect.width; switch (textAlignment) { case Alignment.Left: return totalImageWidth - (singleImageWidth - singleImageAlignment) - num; case Alignment.Right: return num; default: num = rectTransform.rect.width * 0.5f - num; return num + totalImageWidth * 0.5f; } } private void HandleActivationOfImages() { for (int num = rtList.Count - 1; num >= 0; num--) { if (rtList[num] == null) { rtList.RemoveAt(num); imageList.RemoveAt(num); if (num < charTypeList.Count) { charTypeList.RemoveAt(num); } } else if (num < totalImagesInUse) { rtList[num].gameObject.SetActive(isVisible); } else { rtList[num].gameObject.SetActive(value: false); } } } public void SetLayoutHorizontal() { } public void SetLayoutVertical() { VerifyAllObjectsInList(); RebuildLayout(); } [ContextMenu("Format As Timer")] public void FormatAsTimer() { InitializeVariablesForInEditorViewing(); SetTimerValue(754); } [ContextMenu("Format As ItemCounter")] public void FormatAsItemCounter() { InitializeVariablesForInEditorViewing(); SetItemCount(debugValue); } [ContextMenu("Format As Hitpoints")] public void FormatAsHitpoints() { InitializeVariablesForInEditorViewing(); SetHitPointValues(1234, 5768); } [ContextMenu("Format as Percent")] public void FormatAsPercent() { InitializeVariablesForInEditorViewing(); SetPercentValue(100); } }