using System; using System.Collections.Generic; using Dreamteck.Splines; using Ichni.RhythmGame.Beatmap; using Lean.Pool; using Unity.VisualScripting; namespace Ichni.RhythmGame { public class Stay : NoteBase { #region [特有属性字段] Special Fields public NoteJudgeType preJudgeType; #endregion #region [生成与初始化] Generation & Initialization public static Stay GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, GameElement parentElement, float exactJudgeTime) { Stay stay = LeanPool.Spawn(GameManager.Instance.basePrefabs.stayNote, parentElement.transform).GetComponent(); stay.Initialize(elementName, id, tags, isFirstGenerated, parentElement); stay.exactJudgeTime = exactJudgeTime; stay.preJudgeType = NoteJudgeType.NotJudged; stay.judgeIntervals = NoteJudgeIntervals.StayDefault; if (parentElement.TryGetComponent(out Track track) && track.trackTimeSubmodule != null) { stay.track = track; stay.trackPositioner.enabled = true; stay.trackPositioner.spline = track.trackPathSubmodule.path; stay.isOnTrack = true; stay.UpdateNoteInTrack(CoreServices.TimeProvider.SongTime); } else { stay.track = null; stay.isOnTrack = false; } return stay; } public override void SetDefaultSubmodules() { base.SetDefaultSubmodules(); NoteAudioSubmodule = new NoteAudioSubmodule(this, "DefaultStay"); } #endregion #region [主循环阶段] Main Update public override bool ManualUpdate(float currentSongTime) { if (!isFirstJudged && !isDuringJudging && currentSongTime >= exactJudgeTime + judgeIntervals.beforeMiss.intervalStart && !GameManager.Instance.noteJudgeManager.checkingStayList.Contains(this)) { isDuringJudging = true; GameManager.Instance.noteJudgeManager.checkingStayList.Add(this); } ExecuteFinalJudge(currentSongTime); return base.ManualUpdate(currentSongTime); } protected override void RemoveFromCheckingList() { if (GameManager.Instance.noteJudgeManager.checkingStayList.Contains(this)) GameManager.Instance.noteJudgeManager.checkingStayList.Remove(this); } #endregion #region [核心判定逻辑] Judgement Logic public bool CheckJudgeAvailability(InputUnitTouch inputUnitTouch) { foreach (var judgeUnit in NoteJudgeSubmodule.judgeUnitList) { if (!judgeUnit.CheckJudgeAvailability(inputUnitTouch)) return false; } return true; } public override void ExecuteStartJudge(float triggerTime) { NoteJudgeType startJudgeType = GetStartJudgeType(triggerTime - exactJudgeTime); if (startJudgeType != NoteJudgeType.Perfect) return; RemoveFromCheckingList(); preJudgeType = startJudgeType; isFirstJudged = true; } public void ExecuteFinalJudge(float triggerTime) { if (isFirstJudged && !isFinalJudged && preJudgeType != NoteJudgeType.NotJudged && triggerTime >= exactJudgeTime) { switch (preJudgeType) { case NoteJudgeType.Perfect: Perfect(triggerTime); GameManager.Instance.playingRecorder.resultData.Add(0); break; case NoteJudgeType.Good: Good(triggerTime); break; case NoteJudgeType.Bad: Bad(triggerTime); break; case NoteJudgeType.Miss: Miss(triggerTime); break; } if (preJudgeType != NoteJudgeType.Miss) NoteAudioSubmodule.PlayGeneralJudgeAudios(); isFinalJudged = true; } } #endregion #region [谱面功能] Beatmap Method #endregion } }