static void Postfix(FlyingScoreEffect __instance, ref Color ____color, NoteCutInfo noteCutInfo) { float score = RageSaber.RageScore.calculateFromSpeed(noteCutInfo.saberSpeed); RageSaber.RageScore.instance.curScore += score; RageSaber.RageScore.instance.hitCount++; void judge(SaberSwingRatingCounter counter) { TextMeshPro text = __instance.getPrivateField <TextMeshPro>("_text"); // enable rich text text.richText = true; // disable word wrap, make sure full text displays text.enableWordWrapping = false; text.overflowMode = TextOverflowModes.Overflow; text.text = score.ToString("n0"); // If the counter is finished, remove our event from it counter.didFinishEvent -= judge; } // Apply judgments a total of twice - once when the effect is created, once when it finishes. judge(noteCutInfo.swingRatingCounter); noteCutInfo.swingRatingCounter.didFinishEvent += judge; }
public static void judge(FlyingScoreEffect scoreEffect, NoteCutInfo noteCutInfo, SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, int score, int before, int after, int accuracy) { // as of 0.13, the TextMeshPro is private; use reflection to grab it out of a private field TextMeshPro text = scoreEffect.getPrivateField <TextMeshPro>("_text"); // enable rich text text.richText = true; // disable word wrap, make sure full text displays text.enableWordWrapping = false; text.overflowMode = TextOverflowModes.Overflow; Judgment judgment = DEFAULT_JUDGMENT; int index; // save in case we need to fade for (index = 0; index < instance.judgments.Length; index++) { Judgment j = instance.judgments[index]; if (score >= j.threshold) { judgment = j; break; } } Color color; if (judgment.fade) { Judgment fadeJudgment = instance.judgments[index - 1]; Color baseColor = toColor(judgment.color); Color fadeColor = toColor(fadeJudgment.color); float lerpDistance = Mathf.InverseLerp(judgment.threshold, fadeJudgment.threshold, score); color = Color.Lerp(baseColor, fadeColor, lerpDistance); } else { color = toColor(judgment.color); } scoreEffect.setPrivateField("_color", color); if (instance.displayMode == "format") { StringBuilder formattedBuilder = new StringBuilder(); string formatString = judgment.text; int nextPercentIndex = formatString.IndexOf('%'); while (nextPercentIndex != -1) { formattedBuilder.Append(formatString.Substring(0, nextPercentIndex)); if (formatString.Length == nextPercentIndex + 1) { formatString += " "; } char specifier = formatString[nextPercentIndex + 1]; switch (specifier) { case 'b': formattedBuilder.Append(before); break; case 'c': formattedBuilder.Append(accuracy); break; case 'a': formattedBuilder.Append(after); break; case 'B': formattedBuilder.Append(judgeSegment(before, instance.beforeCutAngleJudgments)); break; case 'C': formattedBuilder.Append(judgeSegment(accuracy, instance.accuracyJudgments)); break; case 'A': formattedBuilder.Append(judgeSegment(after, instance.afterCutAngleJudgments)); break; case 's': formattedBuilder.Append(score); break; case 'p': formattedBuilder.Append(string.Format("{0:0}", score / 115d * 100)); break; case '%': formattedBuilder.Append("%"); break; case 'n': formattedBuilder.Append("\n"); break; default: formattedBuilder.Append("%" + specifier); break; } formatString = formatString.Remove(0, nextPercentIndex + 2); nextPercentIndex = formatString.IndexOf('%'); } formattedBuilder.Append(formatString); text.text = formattedBuilder.ToString(); return; } if (instance.displayMode == "textOnly") { text.text = judgment.text; return; } if (instance.displayMode == "numeric") { text.text = score.ToString(); return; } if (instance.displayMode == "scoreOnTop") { text.text = score + "\n" + judgment.text + "\n"; return; } text.text = judgment.text + "\n" + score + "\n"; }