public virtual void Clear(NoteGrade grade) { if (IsCleared || grade == NoteGrade.Undetermined) { return; } IsCleared = true; Game.OnClear(this); View.OnClear(grade); if (!(Game.Instance is StoryboardGame)) { StartCoroutine(DestroyLater()); } if (TimeUntilEnd > -5) // Prevent storyboard seeking { EventKit.Broadcast("note clear", this); } // Hit sound if (grade != NoteGrade.Miss && (!(this is HoldNote) || !PlayerPrefsExt.GetBool("early hit sounds"))) { PlayHitSound(); } // gameObject.GetComponent<SpriteRenderer> ().material.SetFloat("_HRate", 1.0f); // Animation speed = 1.0f; }
public override void OnClear(NoteGrade grade) { base.OnClear(grade); // They still display Ring.enabled = true; Fill.enabled = true; }
public override void OnClear(NoteGrade grade) { base.OnClear(grade); if (!(Game is StoryboardGame)) { Fill.enabled = true; // Still render it SpriteMask.enabled = false; } }
public override void OnClear(NoteGrade grade) { base.OnClear(grade); Line.enabled = false; CompletedLine.enabled = false; ProgressRing.Reset(); ProgressRing.enabled = false; Triangle.Reset(); Triangle.enabled = false; SpriteMask.enabled = false; }
public override void OnClear(NoteGrade grade) { base.OnClear(grade); Line2.enabled = false; CompletedLine2.enabled = false; if (!(Game is StoryboardGame)) { Object.Destroy(Line2.gameObject); Object.Destroy(CompletedLine2.gameObject); } }
public static double GetScoreWeight(this NoteGrade grade, bool ranked) { if (!ranked) { switch (grade) { case NoteGrade.Perfect: return(1.0); case NoteGrade.Great: return(1.0); case NoteGrade.Good: return(0.7); case NoteGrade.Bad: return(0.3); case NoteGrade.Miss: return(0); } } else { switch (grade) { case NoteGrade.Perfect: return(1.0); case NoteGrade.Great: return(0.9); case NoteGrade.Good: return(0.5); case NoteGrade.Bad: return(0.1); case NoteGrade.Miss: return(0f); } } return(0f); }
public static float ScoreWeight(this NoteGrade grade, bool ranked) { if (!ranked) { switch (grade) { case NoteGrade.Perfect: return(1f); case NoteGrade.Great: return(1f); case NoteGrade.Good: return(0.7f); case NoteGrade.Bad: return(0.3f); case NoteGrade.Miss: return(0f); } } else { switch (grade) { case NoteGrade.Perfect: return(1f); case NoteGrade.Great: return(0.9f); case NoteGrade.Good: return(0.5f); case NoteGrade.Bad: return(0.1f); case NoteGrade.Miss: return(0f); } } return(0f); }
public override void OnClear(NoteGrade grade) { SimpleEffects.Instance.PlayClearFx( this, grade, Note.TimeUntilEnd, GameOptions.Instance.ShowEarlyLateIndicator ); rendered = false; if (Ring != null) { Ring.enabled = false; Fill.enabled = false; Collider.enabled = false; } }
public override void OnClear(NoteGrade grade) { base.OnClear(grade); Line.enabled = false; CompletedLine.enabled = false; ProgressRing.Reset(); ProgressRing.enabled = false; Triangle.Reset(); Triangle.enabled = false; SpriteMask.enabled = false; if (!(Game is StoryboardGame)) { Object.Destroy(Line.gameObject); Object.Destroy(CompletedLine.gameObject); Object.Destroy(ProgressRing.gameObject); Object.Destroy(Triangle.gameObject); Object.Destroy(SpriteMask.gameObject); } }
public virtual void Clear(NoteGrade grade) { if (IsCleared) { return; } IsCleared = true; Renderer.OnClear(grade); Game.State.Judge(this, grade, -TimeUntilEnd, GreatGradeWeight); Game.onNoteJudged.Invoke(Game, this, new JudgeData(grade, -TimeUntilEnd, GreatGradeWeight)); // Hit sound if (grade != NoteGrade.Miss && (!(this is HoldNote) || Context.Player.Settings.HoldHitSoundTiming.Let(it => it == HoldHitSoundTiming.End || it == HoldHitSoundTiming.Both))) { PlayHitSound(); } Game.onNoteClear.Invoke(Game, this); AwaitAndCollect(); }
public static float TpWeight(this NoteGrade grade) { switch (grade) { case NoteGrade.Perfect: return(1f); case NoteGrade.Great: return(0.7f); case NoteGrade.Good: return(0.3f); case NoteGrade.Bad: return(0f); case NoteGrade.Miss: return(0f); } return(0f); }
public static double GetAccuracyWeight(this NoteGrade grade) { switch (grade) { case NoteGrade.Perfect: return(1.0); case NoteGrade.Great: return(0.7); case NoteGrade.Good: return(0.3); case NoteGrade.Bad: return(0); case NoteGrade.Miss: return(0); } return(0f); }
public void PlayClearEffect(NoteRenderer noteRenderer, NoteGrade grade, float timeUntilEnd, bool earlyLateIndicator) { if (game.State.Mode == GameMode.GlobalCalibration) { return; } var color = game.Config.NoteGradeEffectColors[grade]; var at = noteRenderer.Note.transform.position; if (noteRenderer.Note.Type == NoteType.Hold || noteRenderer.Note.Type == NoteType.LongHold) { if (noteRenderer.Note.Model.style == 1) { at = new Vector3(at.x, Scanner.Instance.transform.position.y, at.z); } } var speed = 1f; switch (grade) { case NoteGrade.Great: speed = 0.9f; break; case NoteGrade.Good: speed = 0.7f; break; case NoteGrade.Bad: speed = 0.5f; break; case NoteGrade.Miss: speed = 0.3f; break; } var isDragType = noteRenderer.Note.Type == NoteType.DragHead || noteRenderer.Note.Type == NoteType.DragChild || noteRenderer.Note.Type == NoteType.CDragChild; var settings = flatFx.settings[1]; settings.lifetime = 0.4f / speed; settings.sectorCount = noteRenderer.Note.Type == NoteType.Flick ? 4 : 24; settings.start.innerColor = settings.start.outerColor = color.WithAlpha(1); settings.end.innerColor = settings.end.outerColor = color.WithAlpha(0); settings.end.size = (isDragType ? 4f : 5f) * noteRenderer.Game.Config.GlobalNoteSizeMultiplier * (1 + clearEffectSizeMultiplier); settings.start.thickness = 1.333f; settings.end.thickness = 0.333f; flatFx.AddEffect(at, 1); if (grade == NoteGrade.Miss) { var fx = game.ObjectPool.SpawnEffect(Effect.Miss, at); fx.Stop(); var mainModule = fx.main; mainModule.simulationSpeed = 0.3f; mainModule.duration /= 0.3f; mainModule.startColor = game.Config.NoteGradeEffectColors[grade]; if (isDragType) { fx.transform.localScale = new Vector3(2, 2, 2); } fx.Play(); AwaitAndCollect(Effect.Miss, fx); } else { var clearEffect = isDragType ? Effect.ClearDrag : Effect.Clear; var fx = game.ObjectPool.SpawnEffect(clearEffect, at); fx.Stop(); if (!isDragType) { var t = fx.transform.GetChild(0); var early = t.GetChild(0); var late = t.GetChild(1); if (earlyLateIndicator) { if (grade != NoteGrade.Perfect) { t.gameObject.SetActive(true); if (timeUntilEnd > 0) { early.gameObject.SetActive(true); late.gameObject.SetActive(false); } else { early.gameObject.SetActive(false); late.gameObject.SetActive(true); } } else { t.gameObject.SetActive(false); } } else { t.gameObject.SetActive(false); } } var mainModule = fx.main; mainModule.simulationSpeed = speed; mainModule.duration /= speed; mainModule.startColor = color.WithAlpha(1); if (isDragType) { fx.transform.localScale = new Vector3(3f, 3f, 3f); } fx.Play(); AwaitAndCollect(clearEffect, fx); } }
public void Judge(Note note, NoteGrade grade, double error, double greatGradeWeight) { if (IsCompleted || IsFailed) { return; } if (Judgements[note.Model.id].IsJudged) { return; Debug.LogWarning($"Trying to judge note {note.Model.id} which is already judged."); } ClearCount++; Judgements[note.Model.id].Apply(it => { it.IsJudged = true; it.Grade = grade; it.Error = error; }); if (Mode == GameMode.Practice) { if (grade != NoteGrade.Perfect && grade != NoteGrade.Great) { isFullScorePossible = false; } } else { if (grade != NoteGrade.Perfect) { isFullScorePossible = false; } } // Combo var miss = grade == NoteGrade.Bad || grade == NoteGrade.Miss; if (miss) { Combo = 0; } else { Combo++; } if (Combo > MaxCombo) { MaxCombo = Combo; } if (Mode == GameMode.Tier) { if (miss) { Context.TierState.Combo = 0; } else { Context.TierState.Combo++; } if (Context.TierState.Combo > Context.TierState.MaxCombo) { Context.TierState.MaxCombo = Context.TierState.Combo; } } // Score multiplier if (Mode != GameMode.Practice) { switch (grade) { case NoteGrade.Perfect: NoteScoreMultiplier += 0.004D * noteScoreMultiplierFactor; break; case NoteGrade.Great: NoteScoreMultiplier += 0.002D * noteScoreMultiplierFactor; break; case NoteGrade.Good: NoteScoreMultiplier += 0.001D * noteScoreMultiplierFactor; break; case NoteGrade.Bad: NoteScoreMultiplier -= 0.025D * noteScoreMultiplierFactor; break; case NoteGrade.Miss: NoteScoreMultiplier -= 0.05D * noteScoreMultiplierFactor; break; } if (NoteScoreMultiplier > 1) { NoteScoreMultiplier = 1; } if (NoteScoreMultiplier < 0) { NoteScoreMultiplier = 0; } } // Score if (Mode == GameMode.Practice) { Score += 900000.0 / NoteCount * grade.GetScoreWeight(false) + 100000.0 / (NoteCount * (NoteCount + 1) / 2.0) * Combo; } else { var maxNoteScore = 1000000.0 / NoteCount; double noteScore; if (grade == NoteGrade.Great) { noteScore = maxNoteScore * (NoteGrade.Great.GetScoreWeight(true) + (NoteGrade.Perfect.GetScoreWeight(true) - NoteGrade.Great.GetScoreWeight(true)) * greatGradeWeight); } else { noteScore = maxNoteScore * grade.GetScoreWeight(true); } noteScore *= NoteScoreMultiplier; Score += noteScore; } if (Score > 999500) { if (ClearCount == NoteCount && isFullScorePossible) { Score = 1000000; } } if (Score > 1000000) { Score = 1000000; } if (Score == 1000000 && !isFullScorePossible) { Score = 999999; // In case of double inaccuracy } // Accuracy if (Mode == GameMode.Practice || grade != NoteGrade.Great) { accumulatedAccuracy += 1.0 * grade.GetAccuracyWeight(); } else { accumulatedAccuracy += 1.0 * (NoteGrade.Great.GetAccuracyWeight() + (NoteGrade.Perfect.GetAccuracyWeight() - NoteGrade.Great.GetAccuracyWeight()) * greatGradeWeight); } Accuracy = accumulatedAccuracy / ClearCount; // Health mods if (UseHealthSystem) { var mods = Mods.Contains(Mod.ExHard) ? exHardHpMods : hardHpMods; if (Mode == GameMode.Tier) { mods = tierHpMods; } var mod = mods .Select[note.Type] .Select[Mode == GameMode.Practice ? unrankedGradingIndex[grade] : rankedGradingIndex[grade]]; double change = 0; switch (mod.Type) { case HpModType.Absolute: change = mod.Value; break; case HpModType.Percentage: change = mod.Value / 100f * MaxHealth; break; case HpModType.DivideByNoteCount: change = mod.Value / NoteCount / 100f * MaxHealth; break; } if (change < 0 && mod.UseHealthBuffer) { double a; if (HealthPercentage > 0.3) { a = 1; } else { a = 0.25 + 2.5 * HealthPercentage; } change *= a; } Health += change; Health = Math.Min(Math.Max(Health, 0), MaxHealth); if (Health <= 0) { ShouldFail = true; } if (Mode == GameMode.Tier) { Context.TierState.Health = Health; } } if ( Mods.Contains(Mod.AP) && grade != NoteGrade.Perfect || Mods.Contains(Mod.FC) && (grade == NoteGrade.Bad || grade == NoteGrade.Miss) ) { ShouldFail = true; } }
public void PlayClearEffect(NoteRenderer noteRenderer, NoteGrade grade, float timeUntilEnd) { PlayClearEffect(noteRenderer, grade, timeUntilEnd, Context.Player.Settings.DisplayEarlyLateIndicators); }
public virtual void OnClear(NoteGrade grade) { }
public JudgeData(NoteGrade grade, double error, double greatGradeWeight) { Grade = grade; Error = error; GreatGradeWeight = greatGradeWeight; }
public override void OnClear(NoteGrade grade) { base.OnClear(grade); leftArrow.enabled = false; rightArrow.enabled = false; }
public void OnClear(GameNote note, NoteGrade grade, float timeUntilEnd, double greatGradeWeight) { if (grade == NoteGrade.Undetermined) { return; } if (NoteRankings[note.Note.id] != NoteGrade.Undetermined) { return; } if (!IsRanked) { if (grade != NoteGrade.Perfect && grade != NoteGrade.Great) { isMillionMasterPossible = false; } } else { if (grade != NoteGrade.Perfect) { isMillionMasterPossible = false; } } NoteCleared++; NoteRankings[note.Note.id] = grade; if (grade != NoteGrade.Perfect && grade != NoteGrade.Miss) { if (timeUntilEnd > 0) { Early++; } else { Late++; } } timeOffs.Add(timeUntilEnd); // Combo if (grade == NoteGrade.Bad || grade == NoteGrade.Miss) { Combo = 0; } else { Combo++; if (MaxCombo < Combo) { MaxCombo = Combo; } } if (IsRanked) { switch (grade) { case NoteGrade.Perfect: ComboMultiplier += 0.002D * magicNumber; break; case NoteGrade.Great: ComboMultiplier += 0.0005D * magicNumber; break; case NoteGrade.Good: ComboMultiplier -= -0.005D * magicNumber; break; case NoteGrade.Bad: ComboMultiplier -= 0.025D * magicNumber; break; case NoteGrade.Miss: ComboMultiplier -= 0.05D * magicNumber; break; } if (ComboMultiplier > 1) { ComboMultiplier = 1; } if (ComboMultiplier < 0) { ComboMultiplier = 0; } } // Score if (!IsRanked) { Score += 900000f / NoteCount * grade.ScoreWeight(ranked: false) + 100000f / (NoteCount * (double)(NoteCount + 1) / 2f) * Combo; } else { var maxNoteScore = 1000000.0 / NoteCount; double noteScore; if (grade == NoteGrade.Great) { noteScore = maxNoteScore * (NoteGrade.Great.ScoreWeight(ranked: true) + (NoteGrade.Perfect.ScoreWeight(ranked: true) - NoteGrade.Great.ScoreWeight(ranked: true)) * greatGradeWeight); } else { noteScore = maxNoteScore * grade.ScoreWeight(ranked: true); } noteScore *= ComboMultiplier; Score += noteScore; } if (Score > 999500) { if (NoteCleared == NoteCount && isMillionMasterPossible) { Score = 1000000; } } if (Score > 1000000) { Score = 1000000; } // TP if (!IsRanked || grade != NoteGrade.Great) { currentTp += 100f * grade.TpWeight(); } else { currentTp += 100f * (NoteGrade.Great.TpWeight() + (NoteGrade.Perfect.TpWeight() - NoteGrade.Great.TpWeight()) * greatGradeWeight); } Tp = currentTp / NoteCleared; // HP if (Mods.Contains(Mod.Hard) || Mods.Contains(Mod.ExHard)) { var mods = Mods.Contains(Mod.ExHard) ? ExHardHpMods : HardHpMods; var mod = mods.Select[note.Note.type] .Select[IsRanked ? RankedGradingIndices[grade] : UnrankedGradingIndices[grade]]; switch (mod.Type) { case HpModType.Absolute: Hp += mod.Value; break; case HpModType.Percentage: Hp += mod.Value / 100f * MaxHp; break; case HpModType.DivideByNoteCount: Hp += (mod.Value / NoteCount) / 100f * MaxHp; break; } if (Hp > MaxHp) { Hp = MaxHp; } if (Hp < 0) { Game.Instance.Fail(); } } if ( (Mods.Contains(Mod.AP) && grade != NoteGrade.Perfect) || (Mods.Contains(Mod.FC) && (grade == NoteGrade.Bad || grade == NoteGrade.Miss)) ) { Game.Instance.Fail(); } }
public override void OnClear(NoteGrade grade) { base.OnClear(grade); Game.effectController.PlayClearEffect(this, grade, Note.TimeUntilEnd + Note.JudgmentOffset); }
public void PlayClearFx(SimpleNoteView noteView, NoteGrade grade, float timeUntilEnd, bool earlyLateIndicator) { if (grade == NoteGrade.Undetermined) { return; } var at = noteView.Note.Note.position; var clearFx = ClearFx; if (noteView is DragChildNoteView || noteView is DragHeadNoteView) { clearFx = ClearDragFx; } if (noteView.Note.Note.type == NoteType.Hold) { at = new Vector3(at.x, ScanlineView.Instance.transform.position.y, at.z); } if (grade == NoteGrade.Miss) { var fx = Instantiate(MissFx, at, Quaternion.identity); fx.Stop(); var mainModule = fx.main; mainModule.simulationSpeed = 0.3f; mainModule.duration = mainModule.duration / 0.3f; mainModule.startColor = options.MissColor; if (noteView.Note.Note.type == NoteType.DragHead || noteView.Note.Note.type == NoteType.DragChild) { fx.transform.localScale = new Vector3(2, 2, 2); } fx.Play(); Destroy(fx.gameObject, fx.main.duration); } else { var fx = Instantiate(clearFx, at, Quaternion.identity); fx.Stop(); if (!(noteView is DragChildNoteView) && !(noteView is DragHeadNoteView)) { if (earlyLateIndicator) { if (grade != NoteGrade.Perfect) { fx.transform.GetChild(0).GetChild(timeUntilEnd > 0 ? 1 : 0).gameObject .SetActive(false); } else { fx.transform.GetChild(0).GetChild(0).gameObject.SetActive(false); fx.transform.GetChild(0).GetChild(1).gameObject.SetActive(false); } } else { fx.transform.GetChild(0).GetChild(0).gameObject.SetActive(false); fx.transform.GetChild(0).GetChild(1).gameObject.SetActive(false); } } var speed = 1f; var color = options.PerfectColor; switch (grade) { case NoteGrade.Great: speed = 0.9f; color = options.GreatColor; break; case NoteGrade.Good: speed = 0.7f; color = options.GoodColor; break; case NoteGrade.Bad: speed = 0.5f; color = options.BadColor; break; } var mainModule = fx.main; mainModule.simulationSpeed = speed; mainModule.duration = mainModule.duration / speed; mainModule.startColor = color.WithAlpha(1); if (noteView.Note.Note.type == NoteType.DragHead || noteView.Note.Note.type == NoteType.DragChild) { fx.transform.localScale = new Vector3(3f, 3f, 3f); } fx.Play(); Destroy(fx.gameObject, fx.main.duration); } }
public virtual void OnClear(NoteGrade grade) => Expression.Empty();