diff --git a/DisplaySection.cs b/DisplaySection.cs new file mode 100644 index 0000000..4608ad2 --- /dev/null +++ b/DisplaySection.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TMPro; +using UnityEngine; + +namespace PerfectionDisplay +{ + class DisplaySection : MonoBehaviour + { + TextMeshPro scoreMesh; + public string title; + public string color; + + void Awake() + { + scoreMesh = this.gameObject.AddComponent(); + scoreMesh.text = ""; + scoreMesh.fontSize = 3; + scoreMesh.lineSpacing = -25f; + scoreMesh.lineSpacingAdjustment = -25f; + scoreMesh.enableAutoSizing = false; + scoreMesh.paragraphSpacing = -25f; + scoreMesh.color = Color.white; + scoreMesh.font = Resources.Load("Teko-Medium SDF No Glow"); + scoreMesh.alignment = TextAlignmentOptions.Center; + } + public void UpdateText(int score, string percent) + { + string text = "" + title+"\n"; + if (PerfectDisplay.showNumbers) text += score + "\n"; + if (PerfectDisplay.showPercent) text += percent + "%\n"; + scoreMesh.text = text; + scoreMesh.ForceMeshUpdate(); + } + public void UpdatePosition(float x) + { + transform.localPosition = PerfectDisplay.displayPosition+new Vector3(x,0,0); + } + + public float GetWidth() + { + return scoreMesh.GetRenderedValues().x+0.1f; + } + } +} diff --git a/PerfectDisplay.cs b/PerfectDisplay.cs index 3f9ec7f..2050c66 100644 --- a/PerfectDisplay.cs +++ b/PerfectDisplay.cs @@ -1,22 +1,20 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; -using TMPro; using System.Collections; namespace PerfectionDisplay { class PerfectDisplay : MonoBehaviour { - TextMeshPro scoreMesh; ScoreController scoreController; public static Vector3 displayPosition = new Vector3(0, 2.3f, 7f); public static int[] scoreRanges = { 100, 90, 50 }; + public static string[] hitScoreNames; + public static bool shouldHitscore = true; public static string[] colors = { "#2175ff", "green", "yellow", "orange", "red" }; int[] scoreCount; + DisplaySection[] sections; int misses = 0; int notes = 0; public static bool showNumbers = true; @@ -42,13 +40,21 @@ void Awake() } private void Init() { - scoreMesh = this.gameObject.AddComponent(); - scoreMesh.text = ""; - scoreMesh.fontSize = 3; - scoreMesh.color = Color.white; - scoreMesh.font = Resources.Load("Teko-Medium SDF No Glow"); - scoreMesh.alignment = TextAlignmentOptions.Center; - scoreMesh.rectTransform.position = displayPosition; + sections = new DisplaySection[colors.Length]; + sections[scoreRanges.Length] = new GameObject().AddComponent(); + sections[scoreRanges.Length].color = colors[scoreRanges.Length]; + sections[scoreRanges.Length].title = "<" + scoreRanges[scoreRanges.Length - 1]; + if(shouldHitscore) sections[scoreRanges.Length].title = hitScoreNames[hitScoreNames.Length-1]; + sections[scoreRanges.Length + 1] = new GameObject().AddComponent(); + sections[scoreRanges.Length + 1].color = colors[scoreRanges.Length + 1]; + sections[scoreRanges.Length + 1].title = "MISS"; + for (int i = 0; i < scoreRanges.Length; i++) + { + sections[i] = new GameObject().AddComponent(); + sections[i].color = colors[i]; + sections[i].title = ">" + scoreRanges[i]; + if (shouldHitscore) sections[i].title = hitScoreNames[i]; + } if (scoreController != null) { scoreController.noteWasMissedEvent += Miss; @@ -93,47 +99,46 @@ public void Cut(NoteData data, NoteCutInfo info, int combo) public void UpdateText() { - String text = ""; - if (showNumbers) + float width = 0; + for(int i = 0; i < scoreCount.Length; i++) { - for (int i = 0; i < scoreRanges.Length; i++) - { - text += "" + ">" + scoreRanges[i] + "-" + scoreCount[i] + "|"; - } - text += "" + "<" + scoreRanges[scoreRanges.Length - 1] + "-" + scoreCount[scoreRanges.Length] + "|"; - text += "" + "MISS-" + misses +"\n"; + sections[i].UpdateText(scoreCount[i], GetPercent(scoreCount[i])); + width += sections[i].GetWidth(); } - if (showPercent) + sections[scoreRanges.Length+1].UpdateText(misses, GetPercent(misses)); + width += sections[scoreRanges.Length + 1].GetWidth(); + + float curX = sections[0].GetWidth() / 2; ; + for (int i = 0; i < scoreCount.Length; i++) { - for (int i = 0; i < scoreRanges.Length; i++) - { - text += "" + ">" + scoreRanges[i] + "-" + GetPercent(scoreCount[i]) + "%|"; - } - text += "" + "<" + scoreRanges[scoreRanges.Length - 1] + "-" + GetPercent(scoreCount[scoreRanges.Length]) + "%|"; - text += "" + "MISS-" + GetPercent(misses) + "%"; + sections[i].UpdatePosition(-(width/2)+curX); + curX += sections[i].GetWidth() / 2; + curX += sections[i + 1].GetWidth() / 2; } + sections[scoreRanges.Length+1].UpdatePosition(-(width / 2) + curX); + + Plugin.lastText = "Range\n"; for (int i = 0; i < scoreRanges.Length; i++) { - Plugin.lastText += "" + ">" + scoreRanges[i] + "\n"; + Plugin.lastText += "" + (shouldHitscore?hitScoreNames[i]:(">" + scoreRanges[i])) + "\n"; } - Plugin.lastText += "" + "<" + scoreRanges[scoreRanges.Length - 1] + "\n"; + Plugin.lastText += "" + (shouldHitscore ? hitScoreNames[scoreRanges.Length - 1] : ("<" + scoreRanges[scoreRanges.Length - 1])) + "\n"; Plugin.lastText += "" + "MISS"; Plugin.lastCount = "Count\n"; for (int i = 0; i < scoreRanges.Length; i++) { Plugin.lastCount += "" + scoreCount[i] + "\n"; } - Plugin.lastCount += "" + scoreCount[scoreRanges.Length - 1] + "\n"; + Plugin.lastCount += "" + scoreCount[scoreRanges.Length] + "\n"; Plugin.lastCount += "" + misses; Plugin.lastPercent = "Percent\n"; for (int i = 0; i < scoreRanges.Length; i++) { Plugin.lastPercent += "" + GetPercent(scoreCount[i]) + "%\n"; } - Plugin.lastPercent += "" + GetPercent(scoreCount[scoreRanges.Length - 1]) + "%\n"; - Plugin.lastPercent += "" + GetPercent(misses); - scoreMesh.text = text; + Plugin.lastPercent += "" + GetPercent(scoreCount[scoreRanges.Length]) + "%\n"; + Plugin.lastPercent += "" + GetPercent(misses)+"%"; } private String GetPercent(int hits) { diff --git a/Perfection Display.csproj b/Perfection Display.csproj index e6a2803..b1224c8 100644 --- a/Perfection Display.csproj +++ b/Perfection Display.csproj @@ -36,6 +36,10 @@ E:\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\Assembly-CSharp.dll + + False + ..\..\..\..\Desktop\HitScoreVisualizer.dll + E:\Program Files (x86)\Steam\steamapps\common\Beat Saber\Beat Saber_Data\Managed\IllusionPlugin.dll @@ -68,6 +72,7 @@ + diff --git a/Plugin.cs b/Plugin.cs index f7360c9..067db54 100644 --- a/Plugin.cs +++ b/Plugin.cs @@ -1,7 +1,9 @@ using IllusionPlugin; using System; using System.Globalization; +using System.IO; using System.Linq; +using System.Reflection; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; @@ -11,13 +13,15 @@ namespace PerfectionDisplay public class Plugin : IPlugin { public string Name => "Perfection Display"; - public string Version => "1.2.0"; + public string Version => "1.3.0"; public static string lastText = ""; public static string lastPercent = ""; public static string lastCount = ""; private readonly string[] env = { "DefaultEnvironment", "BigMirrorEnvironment", "TriangleEnvironment", "NiceEnvironment" }; + + bool init = true; public void OnApplicationStart() { @@ -68,15 +72,35 @@ public void OnApplicationStart() } PerfectDisplay.showNumbers = ModPrefs.GetBool("PerfectionDisplay", "Show Count", PerfectDisplay.showNumbers, true); PerfectDisplay.showPercent = ModPrefs.GetBool("PerfectionDisplay", "Show Percent", PerfectDisplay.showPercent, true); + PerfectDisplay.shouldHitscore = ModPrefs.GetBool("PerfectionDisplay", "HitScoreVisualizer Integration", PerfectDisplay.shouldHitscore, true); } public void OnApplicationQuit() { SceneManager.activeSceneChanged -= OnSceneChanged; } - + private void LoadHitScore() + { + HitScoreVisualizer.Config.Judgment[] judgments = HitScoreVisualizer.Config.instance.judgments; + PerfectDisplay.scoreRanges = new int[judgments.Length - 1]; + PerfectDisplay.hitScoreNames = new string[judgments.Length]; + PerfectDisplay.colors = new string[judgments.Length + 1]; + for (int i = 0; i < judgments.Length; i++) + { + if (i != PerfectDisplay.scoreRanges.Length) PerfectDisplay.scoreRanges[i] = judgments[i].threshold - 1; + PerfectDisplay.hitScoreNames[i] = judgments[i].text.Replace("%n", "").Replace("%s", "").Replace("%B", "").Replace("%C", "").Replace("%A", "").Trim(); + PerfectDisplay.colors[i] = "#" + ((int)(judgments[i].color[0] * 255)).ToString("X2") + ((int)(judgments[i].color[1] * 255)).ToString("X2") + ((int)(judgments[i].color[2] * 255)).ToString("X2") + ((int)(judgments[i].color[3] * 255)).ToString("X2"); + } + PerfectDisplay.colors[PerfectDisplay.colors.Length - 1] = "#FF0000"; + } private void OnSceneChanged(Scene _, Scene scene) { + if (init) + { + init = false; + if (PerfectDisplay.shouldHitscore && HasType("HitScoreVisualizer")) LoadHitScore(); + else PerfectDisplay.shouldHitscore = false; + } if(scene.name.Equals("Menu")) { foreach (var rootGameObject in scene.GetRootGameObjects()) @@ -86,21 +110,24 @@ private void OnSceneChanged(Scene _, Scene scene) TextMeshProUGUI text = MonoBehaviour.Instantiate(Resources.FindObjectsOfTypeAll().Last(x => (x.name == "Title")), rootGameObject.transform.Find("Results").Find("Cleared"), false); text.fontSize = 4; text.color = Color.white; + text.paragraphSpacing = -15f; text.text = lastText; - text.alignment = TextAlignmentOptions.Left; - text.rectTransform.localPosition = new Vector3(-20, 28, 0); + text.alignment = TextAlignmentOptions.TopLeft; + text.rectTransform.localPosition = new Vector3(-25, 40, 0); text = MonoBehaviour.Instantiate(Resources.FindObjectsOfTypeAll().Last(x => (x.name == "Title")), rootGameObject.transform.Find("Results").Find("Cleared"), false); text.fontSize = 4; text.color = Color.white; + text.paragraphSpacing = -15f; text.text = lastCount; - text.alignment = TextAlignmentOptions.Left; - text.rectTransform.localPosition = new Vector3(3, 28, 0); + text.alignment = TextAlignmentOptions.TopLeft; + text.rectTransform.localPosition = new Vector3(0-5, 40, 0); text = MonoBehaviour.Instantiate(Resources.FindObjectsOfTypeAll().Last(x => (x.name == "Title")), rootGameObject.transform.Find("Results").Find("Cleared"), false); text.fontSize = 4; text.color = Color.white; + text.paragraphSpacing = -15f; text.text = lastPercent; - text.alignment = TextAlignmentOptions.Left; - text.rectTransform.localPosition = new Vector3(-10, 28, 0); + text.alignment = TextAlignmentOptions.TopLeft; + text.rectTransform.localPosition = new Vector3(10-5, 40, 0); return; } } @@ -110,6 +137,20 @@ private void OnSceneChanged(Scene _, Scene scene) new GameObject("PerfectDisplay").AddComponent(); } + private bool HasType(string typeName) + { + foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + foreach (Type type in assembly.GetTypes()) + { + if (type.Namespace == typeName) + return true; + } + } + + return false; + } + public void OnLevelWasLoaded(int level) { }