using System.Collections; using System.Collections.Generic; using System.Linq; using Ichni.RhythmGame; using Sirenix.OdinInspector; using UnityEngine; namespace Ichni { public partial class NoteJudgeManager : SerializedMonoBehaviour { public List checkingTapList; public List checkingStayList; public List checkingHoldList; public List checkingFlickList; public List inputUnitTapList; public List inputUnitTouchList; public List inputUnitSwipeList; private void Start() { checkingTapList = new List(); checkingStayList = new List(); checkingHoldList = new List(); checkingFlickList = new List(); inputUnitTapList = new List(); inputUnitTouchList = new List(); inputUnitSwipeList = new List(); } public void Update() { if (!GameManager.instance.audioManager.isPlaying) { return; } List tapSwipeList = inputUnitSwipeList.Where(x => x.isFirst).ToList(); List holdSwipeList = inputUnitSwipeList.Where(x => !x.isFirst).ToList(); foreach (InputUnitSwipe tapSwipe in tapSwipeList) { List availableFlicks = new List(); foreach (Flick flick in checkingFlickList) { if (flick.CheckJudgeAvailability(tapSwipe)) { availableFlicks.Add(flick); } } List minFlicks = GetAllMinNotes(availableFlicks); if (minFlicks.Count == 1) { minFlicks[0].ExecuteStartJudge(); } else if (minFlicks.Count > 1) { GetNearestNote(minFlicks, tapSwipe.inputPosition).ExecuteTapJudge(); } } foreach (InputUnitSwipe inputUnitSwipe in holdSwipeList) { List availableFlicks = new List(); foreach (Flick flick in checkingFlickList) { if (flick.CheckJudgeAvailability(inputUnitSwipe)) { availableFlicks.Add(flick); } } if (availableFlicks.Count > 0) { availableFlicks.Sort(); Flick closestFlick = availableFlicks[0]; closestFlick.ExecuteStartJudge(); } } foreach (InputUnitTap inputUnitTap in inputUnitTapList) { List availableTaps = new List(); foreach (Tap tap in checkingTapList) { if (tap.CheckJudgeAvailability(inputUnitTap)) { availableTaps.Add(tap); } } List availableHolds = new List(); foreach (Hold hold in checkingHoldList) { if (hold.CheckJudgeAvailability(inputUnitTap)) { availableHolds.Add(hold); } } bool haveTap = availableTaps.Count > 0; bool haveHold = availableHolds.Count > 0; Flick closestFlick = null; InputUnitSwipe assumedSwipe = new InputUnitSwipe(inputUnitTap.fingerId, inputUnitTap.inputPosition, true, true, Vector2.zero); foreach (Flick flick in checkingFlickList) { if (flick.CheckJudgeAvailability(assumedSwipe)) { if (closestFlick == null || flick.exactJudgeTime < closestFlick.exactJudgeTime) { closestFlick = flick; } } } if (haveHold && haveTap) { List minHolds = GetAllMinNotes(availableHolds); List minTaps = GetAllMinNotes(availableTaps); Hold closestHold = minHolds[0]; Tap closestTap = minTaps[0]; bool holdBlockedByFlick = false; bool tapBlockedByFlick = false; if (closestFlick != null) { if (closestFlick.exactJudgeTime < closestHold.exactJudgeTime) { holdBlockedByFlick = true; } if (closestFlick.exactJudgeTime < closestTap.exactJudgeTime) { tapBlockedByFlick = true; } } if (!holdBlockedByFlick && closestHold.exactJudgeTime < closestTap.exactJudgeTime) { if (minHolds.Count == 1) { minHolds[0].ExecuteStartJudge(); } else { GetNearestNote(minHolds, inputUnitTap.inputPosition).ExecuteStartJudge(); } } else if (!tapBlockedByFlick) { if (minTaps.Count == 1) { minTaps[0].ExecuteStartJudge(); } else { GetNearestNote(minTaps, inputUnitTap.inputPosition).ExecuteStartJudge(); } } } else if (haveHold) { List minHolds = GetAllMinNotes(availableHolds); bool holdBlockedByFlick = closestFlick != null && closestFlick.exactJudgeTime < minHolds[0].exactJudgeTime; if (!holdBlockedByFlick) { if (minHolds.Count == 1) { minHolds[0].ExecuteStartJudge(); } else { GetNearestNote(minHolds, inputUnitTap.inputPosition).ExecuteStartJudge(); } } } else if (haveTap) { List minTaps = GetAllMinNotes(availableTaps); bool tapBlockedByFlick = closestFlick != null && closestFlick.exactJudgeTime < minTaps[0].exactJudgeTime; if (!tapBlockedByFlick) { if (minTaps.Count == 1) { minTaps[0].ExecuteStartJudge(); } else { GetNearestNote(minTaps, inputUnitTap.inputPosition).ExecuteStartJudge(); } } } } foreach (InputUnitTouch inputUnitTouch in inputUnitTouchList) { List availableStays = new List(); foreach (Stay stay in checkingStayList) { if (stay.CheckJudgeAvailability(inputUnitTouch)) { availableStays.Add(stay); } } List availableHolds = new List(); foreach (Hold hold in checkingHoldList) { if (hold.CheckJudgeAvailability(inputUnitTouch)) { availableHolds.Add(hold); } } foreach (Stay stay in availableStays) { stay.ExecuteStartJudge(); } foreach (Hold hold in availableHolds) { hold.ExecuteProcessJudge(); } } inputUnitTapList.Clear(); inputUnitTouchList.Clear(); inputUnitSwipeList.Clear(); } public void SetNewInputUnitTap(int fingerId, Vector2 inputPosition) { InputUnitTap inputUnitTap = new InputUnitTap(fingerId, inputPosition); if(!inputUnitTapList.Exists(x => x.fingerId == fingerId)) { inputUnitTapList.Add(inputUnitTap); } } public void SetNewInputUnitTouch(int fingerId, Vector2 inputPosition) { InputUnitTouch inputUnitTouch = new InputUnitTouch(fingerId, inputPosition); if(!inputUnitTouchList.Exists(x => x.fingerId == fingerId)) { inputUnitTouchList.Add(inputUnitTouch); } } public void SetNewInputUnitSwipe(int fingerId, Vector2 inputPosition, bool isGeneric, bool isFirst, Vector2 delta) { InputUnitSwipe inputUnitSwipe = new InputUnitSwipe(fingerId, inputPosition, isGeneric, isFirst, delta); if(!inputUnitSwipeList.Exists(x => x.fingerId == fingerId)) { inputUnitSwipeList.Add(inputUnitSwipe); } } } public partial class NoteJudgeManager { private List GetAllMinNotes(List availableFlicks) where T : NoteBase { List minFlicks = new List(); float minTime = float.MaxValue; foreach (T flick in availableFlicks) { if (flick.exactJudgeTime < minTime) { minTime = flick.exactJudgeTime; minFlicks.Clear(); minFlicks.Add(flick); } else if (Mathf.Approximately(flick.exactJudgeTime, minTime)) { minFlicks.Add(flick); } } return minFlicks; } private T GetNearestNote(List notes, Vector2 inputPosition) where T : NoteBase { float minDistance = float.MaxValue; T closestNote = null; foreach (T note in notes) { float distance = Vector2.Distance(inputPosition, note.noteScreenPosition); if (distance < minDistance) { minDistance = distance; closestNote = note; } } return closestNote; } } public class InputUnit { public int fingerId; public Vector2 inputPosition; } public class InputUnitTap : InputUnit { public InputUnitTap(int fingerId, Vector2 inputPosition) { this.fingerId = fingerId; this.inputPosition = inputPosition; } } public class InputUnitTouch : InputUnit { public InputUnitTouch(int fingerId, Vector2 inputPosition) { this.fingerId = fingerId; this.inputPosition = inputPosition; } } public class InputUnitSwipe : InputUnit { public Vector2 swipeDirection; public bool isGeneric; public bool isFirst; public InputUnitSwipe(int fingerId, Vector2 inputPosition, bool isGeneric, bool isFirst, Vector2 swipeDirection) { this.fingerId = fingerId; this.inputPosition = inputPosition; this.isGeneric = isGeneric; this.isFirst = isFirst; this.swipeDirection = swipeDirection.normalized; } } }