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; }
static void Postfix(FlyingScoreEffect __instance, ref Color ____color, NoteCutInfo noteCutInfo) { void earlyJudge(SaberSwingRatingCounter counter) { ScoreController.RawScoreWithoutMultiplier(noteCutInfo, out int before, out int after, out int accuracy); int total = before + 30 + accuracy; Config.judge(__instance, noteCutInfo, counter, total, before, 30, accuracy); // If the counter is finished, remove our event from it counter.didFinishEvent -= judge; } void judge(SaberSwingRatingCounter counter) { ScoreController.RawScoreWithoutMultiplier(noteCutInfo, out int before, out int after, out int accuracy); int total = before + after + accuracy; Config.judge(__instance, noteCutInfo, counter, total, before, after, accuracy); // 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. earlyJudge(noteCutInfo.swingRatingCounter); noteCutInfo.swingRatingCounter.didFinishEvent += judge; }
// ReSharper disable InconsistentNaming internal static void Prefix(FlyingScoreEffect __instance, ref Vector3 targetPos) // ReSharper restore InconsistentNaming { if (ConfigProvider.CurrentConfig?.UseFixedPos ?? false) { var transform = __instance.transform; // Set current and target position to the desired fixed position transform.position = ConfigProvider.CurrentConfig.FixedPos; targetPos = transform.position; // If there's an existing judgment effect, clear that first if (_currentEffect != null) { // Remove it gracefully by setting its duration to 0 _currentEffect.SetField("_duration", 0f); // We don't need to clear currentEffect when it disappears, because we'll be setting it to the new effect anyway _currentEffect.didFinishEvent -= HandleEffectDidFinish; } // Save the existing effect to clear if a new one spawns _currentEffect = __instance; // In case it despawns before the next note is hit, don't try to clear it _currentEffect.didFinishEvent += HandleEffectDidFinish; } }
private static void HandleEffectDidFinish(FlyingObjectEffect effect) { effect.didFinishEvent -= HandleEffectDidFinish; if (_currentEffect == effect) { _currentEffect = null !; } }
static void handleEffectDidFinish(FlyingObjectEffect effect) { effect.didFinishEvent -= handleEffectDidFinish; if (currentEffect == effect) { currentEffect = null; } }
static bool Prefix(SaberSwingRatingCounter saberSwingRatingCounter, FlyingScoreEffect __instance, NoteCutInfo ____noteCutInfo) { if (Config.instance.doIntermediateUpdates) { ScoreModel.RawScoreWithoutMultiplier(____noteCutInfo, out int before, out int after, out int accuracy); int total = before + after + accuracy; Config.judge(__instance, ____noteCutInfo, saberSwingRatingCounter, total, before, after, accuracy); } return(false); }
public static bool Prefix(FlyingScoreSpawner __instance, NoteCutInfo noteCutInfo, int noteLineIndex, int multiplier, Vector3 pos, Color color, ref float[,] ___lineSlotSpawnTimes, ref FlyingScoreEffect.Pool ____flyingScoreEffectPool) { if (!Plugin.active) { return(true); } if (noteLineIndex >= ___lineSlotSpawnTimes.GetLength(0)) { float[,] array = new float[noteLineIndex, 1]; for (int i = 0; i < ___lineSlotSpawnTimes.GetLength(0); i++) { for (int j = 0; j < 1; j++) { array[i, j] = ___lineSlotSpawnTimes[i, j]; } } ___lineSlotSpawnTimes = array; } int num = 0; while (num < 0 && ___lineSlotSpawnTimes[noteLineIndex, num] + 0.4f >= Time.timeSinceLevelLoad) { num++; } ___lineSlotSpawnTimes[noteLineIndex, num] = Time.timeSinceLevelLoad; FlyingScoreEffect flyingScoreEffect = ____flyingScoreEffectPool.Spawn(); flyingScoreEffect.didFinishEvent += __instance.HandleFlyingScoreEffectDidFinish; Vector3 targetPos = Vector3.zero; if (lastNoteRotationSet) { flyingScoreEffect.transform.SetPositionAndRotation(lastNoteRotation * pos, lastNoteRotation); pos.z = 0f; pos.y = -0.24f; targetPos = lastNoteRotation * (pos + new Vector3(0f, -0.23f * num, 7.55f)); } else { flyingScoreEffect.transform.SetPositionAndRotation(pos, Quaternion.identity); pos.z = 0f; pos.y = -0.24f; targetPos = pos + new Vector3(0f, -0.23f * num, 7.55f); } flyingScoreEffect.InitAndPresent(noteCutInfo, multiplier, 0.7f, targetPos, color); return(false); }
private static bool Prefix(FlyingScoreSpawner __instance, FlyingScoreEffect.Pool ____flyingScoreEffectPool, Vector3 pos, NoteCutInfo noteCutInfo, Quaternion rotation, Quaternion inverseRotation) { IEnumerator g__SpawnFlyingScoreEffectCoroutine(int index, Vector3 position) { yield return(new WaitForSecondsRealtime(FlyingObjectEffectParameters.timeShift * index)); FlyingScoreEffect flyingScoreEffect = ____flyingScoreEffectPool.Spawn(); flyingScoreEffect.didFinishEvent += __instance.HandleFlyingScoreEffectDidFinish; flyingScoreEffect.transform.localPosition = position; position = inverseRotation * position; position.z = 0f; if (PluginConfig.Instance.forward) { float offsetY = (PluginConfig.Instance.scale - 0.5f) * FlyingObjectEffectParameters.scaleOffsetCoefY; position = new Vector3(position.x, PluginConfig.Instance.forwardTargetY + offsetY, pos.z + PluginConfig.Instance.forwardTargetZ); position = rotation * position; } flyingScoreEffect.InitAndPresent(noteCutInfo, index * -1, -0.7f, position, rotation, Color.white); } bool noScoreText = PluginConfig.Instance.noScoreText; bool result; if (noScoreText) { result = false; } else { bool flag = !PluginConfig.Instance.pro; if (flag) { float offsetX = FlyingObjectEffectParameters.scoreNumberOffsetX * PluginConfig.Instance.scale; bool forward = PluginConfig.Instance.forward; if (forward) { offsetX *= FlyingObjectEffectParameters.forwardScale; } Vector3 offset = new Vector3(offsetX, 0f, 0f); Vector3 pos2 = rotation * (Quaternion.Inverse(rotation) * pos - offset); Vector3 pos3 = rotation * (Quaternion.Inverse(rotation) * pos + offset); PersistentSingleton <SharedCoroutineStarter> .instance.StartCoroutine(g__SpawnFlyingScoreEffectCoroutine(1, pos2)); PersistentSingleton <SharedCoroutineStarter> .instance.StartCoroutine(g__SpawnFlyingScoreEffectCoroutine(2, pos)); PersistentSingleton <SharedCoroutineStarter> .instance.StartCoroutine(g__SpawnFlyingScoreEffectCoroutine(3, pos3)); } result = true; } return(result); }
public static void Judge(FlyingScoreEffect scoreEffect, int score, int before, int after, int accuracy) { var instance = ConfigProvider.CurrentConfig; if (instance == null) { return; } // as of 0.13, the TextMeshPro is private; use reflection to grab it out of a private field var text = FlyingScoreEffectText(ref scoreEffect); // enable rich text text.richText = true; // disable word wrap, make sure full text displays text.enableWordWrapping = false; text.overflowMode = TextOverflowModes.Overflow; // save in case we need to fade var index = instance.Judgments !.FindIndex(j => j.Threshold <= score); var judgment = index >= 0 ? instance.Judgments[index] : Judgment.Default; Color color; if (judgment.Fade) { var fadeJudgment = instance.Judgments[index - 1]; var baseColor = judgment.Color.ToColor(); var fadeColor = fadeJudgment.Color.ToColor(); var lerpDistance = Mathf.InverseLerp(judgment.Threshold, fadeJudgment.Threshold, score); color = Color.Lerp(baseColor, fadeColor, lerpDistance); } else { color = judgment.Color.ToColor(); } FieldAccessor <FlyingScoreEffect, Color> .Set(scoreEffect, "_color", color); scoreEffect.SetField("_color", color); text.text = instance.DisplayMode switch { "format" => DisplayModeFormat(score, before, after, accuracy, judgment, instance), "textOnly" => judgment.Text, "numeric" => score.ToString(), "scoreOnTop" => $"{score}\n{judgment.Text}\n", _ => $"{judgment.Text}\n{score}\n" }; }
// ReSharper disable InconsistentNaming internal static bool Prefix(FlyingScoreEffect __instance, NoteCutInfo ____noteCutInfo) // ReSharper enable InconsistentNaming { if (ConfigProvider.CurrentConfig == null) { return(true); } if (ConfigProvider.CurrentConfig.DoIntermediateUpdates) { ScoreModel.RawScoreWithoutMultiplier(____noteCutInfo, out var before, out var after, out var accuracy); var total = before + after + accuracy; JudgmentService.Judge(__instance, total, before, after, accuracy); } return(false); }
static void Prefix(ref Vector3 targetPos, FlyingScoreEffect __instance) { if (Config.instance.useFixedPos) { // Set current and target position to the desired fixed position __instance.transform.position = new Vector3(Config.instance.fixedPosX, Config.instance.fixedPosY, Config.instance.fixedPosZ); targetPos = __instance.transform.position; // If there's an existing judgment effect, clear that first if (currentEffect != null) { // Remove it gracefully by setting its duration to 0 currentEffect.setPrivateFieldBase("_duration", 0f); // We don't need to clear currentEffect when it disappears, because we'll be setting it to the new effect anyway currentEffect.didFinishEvent -= handleEffectDidFinish; } // Save the existing effect to clear if a new one spawns currentEffect = __instance; // In case it despawns before the next note is hit, don't try to clear it currentEffect.didFinishEvent += handleEffectDidFinish; } }
private static void Postfix(FlyingScoreEffect __instance, NoteCutInfo ____noteCutInfo, TextMeshPro ____text, SpriteRenderer ____maxCutDistanceScoreIndicator, ref float ____colorAMultiplier, int multiplier) { c__DisplayClass2_0 scoreUtils = new c__DisplayClass2_0(); scoreUtils.noteCutInfo = ____noteCutInfo; scoreUtils.text = ____text; scoreUtils.instance = __instance; scoreUtils.text.richText = PluginConfig.Instance.pro; scoreUtils.text.SetText(""); if (PluginConfig.Instance.italic) { scoreUtils.text.fontStyle = FontStyles.Italic; } else { scoreUtils.text.fontStyle = FontStyles.Normal; } if (Plugin.uiFontEnabled) { scoreUtils.text.font = Plugin.uiFont; } ____colorAMultiplier = (float)multiplier; ____maxCutDistanceScoreIndicator.enabled = false; bool flag = !scoreUtils.noteCutInfo.swingRatingCounter.didFinish; if (flag) { scoreUtils.noteCutInfo.swingRatingCounter.didChangeEvent -= scoreUtils.g__HandleSaberSwingRatingCounterDidChange; scoreUtils.noteCutInfo.swingRatingCounter.didChangeEvent += scoreUtils.g__HandleSaberSwingRatingCounterDidChange; scoreUtils.noteCutInfo.swingRatingCounter.didFinishEvent -= scoreUtils.g__HandleSaberSwingRatingCounterDidFinish; scoreUtils.noteCutInfo.swingRatingCounter.didFinishEvent += scoreUtils.g__HandleSaberSwingRatingCounterDidFinish; } scoreUtils.g__UpdateScore(); }
// ReSharper disable InconsistentNaming internal static void Postfix(FlyingScoreEffect __instance, NoteCutInfo noteCutInfo) // ReSharper restore InconsistentNaming { if (ConfigProvider.CurrentConfig == null) { return; } void Judge(SaberSwingRatingCounter counter) { ScoreModel.RawScoreWithoutMultiplier(noteCutInfo, out var before, out var after, out var accuracy); var total = before + after + accuracy; JudgmentService.Judge(__instance, total, before, after, accuracy); // 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"; }
static bool Prefix(SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, FlyingScoreEffect __instance, NoteCutInfo ____noteCutInfo) { if (Config.instance.doIntermediateUpdates) { ScoreController.RawScoreWithoutMultiplier(____noteCutInfo, saberAfterCutSwingRatingCounter, out int before_plus_acc, out int after, out int accuracy); int total = before_plus_acc + after; Config.judge(__instance, ____noteCutInfo, saberAfterCutSwingRatingCounter, total, before_plus_acc - accuracy, after, accuracy); } return(false); }
static void Postfix(SaberAfterCutSwingRatingCounter saberAfterCutSwingRatingCounter, FlyingScoreEffect __instance, ref Color ____color, NoteCutInfo noteCutInfo) { void judge(SaberAfterCutSwingRatingCounter counter) { ScoreController.RawScoreWithoutMultiplier(noteCutInfo, counter, out int before_plus_acc, out int after, out int accuracy); int total = before_plus_acc + after; Config.judge(__instance, noteCutInfo, counter, total, before_plus_acc - accuracy, after, accuracy); // 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(saberAfterCutSwingRatingCounter); saberAfterCutSwingRatingCounter.didFinishEvent += judge; }
static void Prefix(ref Vector3 targetPos, FlyingScoreEffect __instance) { }