From 768ae85c271fab85b0c677d4c3c8b8628adc362f Mon Sep 17 00:00:00 2001 From: Narrik Synthfox <80410683+NarrikSynthfox@users.noreply.github.com> Date: Fri, 21 Apr 2023 15:50:39 -0400 Subject: [PATCH] Taps (#144) * Taps work kinda * tap logic, ignore force strum/hopo if sysex tap * Merge branch 'EliteAsian123:master' into taps * Start implementing tap model * Fully implement tap note model. --- Assets/Prefabs/Note.prefab | 11 ++++- Assets/Script/Data/NoteInfo.cs | 5 ++- .../DiffDownsample/FiveFretDownsample.cs | 3 ++ Assets/Script/PlayMode/FiveFretTrack.cs | 19 ++++---- Assets/Script/Pools/NoteComponent.cs | 8 ++-- .../Parser/MidiParser.FiveFret.cs | 45 ++++++++++++++----- 6 files changed, 65 insertions(+), 26 deletions(-) diff --git a/Assets/Prefabs/Note.prefab b/Assets/Prefabs/Note.prefab index 7b86319b1..5877e36e0 100644 --- a/Assets/Prefabs/Note.prefab +++ b/Assets/Prefabs/Note.prefab @@ -54,8 +54,9 @@ MonoBehaviour: meshRenderers: - {fileID: 4571971630462908758} - {fileID: 6846950644507852135} + - {fileID: 6376229487116774476} - {fileID: 7147253800328892818} - meshRendererMiddleIndices: 020000000100000001000000 + meshRendererMiddleIndices: 02000000010000000200000001000000 noteGroup: {fileID: 1397812567785855241} hopoGroup: {fileID: 1294466957868725440} tapGroup: {fileID: 3624981743589644049} @@ -141,7 +142,7 @@ GameObject: m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 - m_IsActive: 0 + m_IsActive: 1 --- !u!4 &2078363896503798061 Transform: m_ObjectHideFlags: 0 @@ -588,6 +589,12 @@ Transform: type: 3} m_PrefabInstance: {fileID: 6392612060457181869} m_PrefabAsset: {fileID: 0} +--- !u!23 &6376229487116774476 stripped +MeshRenderer: + m_CorrespondingSourceObject: {fileID: 57407852433297121, guid: 0f0950362ca41164899b1391a673053d, + type: 3} + m_PrefabInstance: {fileID: 6392612060457181869} + m_PrefabAsset: {fileID: 0} --- !u!1001 &7866531513016969808 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Script/Data/NoteInfo.cs b/Assets/Script/Data/NoteInfo.cs index 00ab78108..022af9e84 100644 --- a/Assets/Script/Data/NoteInfo.cs +++ b/Assets/Script/Data/NoteInfo.cs @@ -8,7 +8,10 @@ public class NoteInfo : AbstractInfo { /// Hammer-on/pull-off, or Cymbal for drums. /// </summary> public bool hopo; - + /// <summary> + /// Tap note. Only used for guitar, coop guitar, rhythm, and bass. + /// </summary> + public bool tap; /// <summary> /// Whether or not this HOPO is automatic.<br/> /// Used for difficulty downsampling. diff --git a/Assets/Script/DiffDownsample/FiveFretDownsample.cs b/Assets/Script/DiffDownsample/FiveFretDownsample.cs index 2b4350f41..a0d4f1118 100644 --- a/Assets/Script/DiffDownsample/FiveFretDownsample.cs +++ b/Assets/Script/DiffDownsample/FiveFretDownsample.cs @@ -129,6 +129,7 @@ private class ChordedNoteInfo { public FretFlag frets; public bool hopo; + public bool tap; public bool autoHopo; } @@ -155,6 +156,7 @@ private static List<ChordedNoteInfo> ConsolidateToChords(List<NoteInfo> input) { length = new float[5], frets = (FretFlag) (1 << note.fret), hopo = note.hopo, + tap = note.tap, autoHopo = note.autoHopo }; @@ -187,6 +189,7 @@ private static List<NoteInfo> SplitToNotes(List<ChordedNoteInfo> chords) { length = chord.length[i], fret = i, hopo = chord.hopo, + tap = chord.tap, autoHopo = chord.autoHopo }); } diff --git a/Assets/Script/PlayMode/FiveFretTrack.cs b/Assets/Script/PlayMode/FiveFretTrack.cs index 3daea2cc7..1f0cc7aa6 100644 --- a/Assets/Script/PlayMode/FiveFretTrack.cs +++ b/Assets/Script/PlayMode/FiveFretTrack.cs @@ -215,14 +215,15 @@ private void UpdateInput() { // Handle hits (one per frame so no double hits) var chord = expectedHits.Peek(); - // If the note is not a HOPO and the player has not strummed, nothing happens. - if (!chord[0].hopo && !strummed && strumLeniency == 0f) { + // If the note is not a HOPO or tap and the player has not strummed, nothing happens. + if (!chord[0].hopo && !chord[0].tap && !strummed && strumLeniency == 0f) { return; } + // If the note is a HOPO, the player has not strummed, and the HOPO can't be hit, nothing happens. - if (chord[0].hopo && !strummed && strumLeniency == 0f) { - if (Combo <= 0) { + if ((chord[0].hopo || chord[0].tap) && !strummed && strumLeniency == 0f) { + if (Combo <= 0 && chord[0].hopo) { return; } @@ -277,7 +278,7 @@ private void UpdateInput() { } // Avoid multi-hits - if (chord[0].hopo) { + if (chord[0].hopo || chord[0].tap) { // If latest input is cleared, it was already used if (latestInput == null) { return; @@ -342,10 +343,10 @@ private void UpdateInput() { // add it to the allowed overstrums. This is so the player // doesn't lose their combo when they strum AFTER they hit // the tap note. - if (chord[0].hopo && !strummedCurrentNote) { + if ((chord[0].hopo||chord[0].tap) && !strummedCurrentNote) { allowedOverstrums.Clear(); // Only allow overstrumming latest HO/PO allowedOverstrums.Add(chord); - } else if (allowedOverstrums.Count > 0 && !chord[0].hopo) { + } else if (allowedOverstrums.Count > 0 && !chord[0].hopo && !chord[0].tap) { for (int i = 0; i < allowedOverstrums.Count; i++) { if (!ChordEquals(chord, allowedOverstrums[i])) { allowedOverstrums.Clear(); // If latest strum is different from latest HO/PO, disallow overstrumming @@ -565,13 +566,14 @@ private void SpawnNote(NoteInfo noteInfo, float time) { float lagCompensation = CalcLagCompensation(time, noteInfo.time); float x = noteInfo.fret == 5 ? 0f : frets[noteInfo.fret].transform.localPosition.x; var pos = new Vector3(x, 0f, TRACK_SPAWN_OFFSET - lagCompensation); - // Get model type var model = NoteComponent.ModelType.NOTE; if (noteInfo.fret == 5) { model = NoteComponent.ModelType.FULL; } else if (noteInfo.hopo) { model = NoteComponent.ModelType.HOPO; + } else if (noteInfo.tap){ + model = NoteComponent.ModelType.TAP; } @@ -584,6 +586,7 @@ private void SpawnNote(NoteInfo noteInfo, float time) { noteInfo.length, model ); + } private string PrintFrets() { // Debug function; remove later? diff --git a/Assets/Script/Pools/NoteComponent.cs b/Assets/Script/Pools/NoteComponent.cs index dc88ad140..3be4009da 100644 --- a/Assets/Script/Pools/NoteComponent.cs +++ b/Assets/Script/Pools/NoteComponent.cs @@ -7,6 +7,7 @@ public class NoteComponent : Poolable { public enum ModelType { NOTE, HOPO, + TAP, FULL } @@ -81,8 +82,8 @@ private void OnDisable() { public void SetInfo(Color notes, Color sustains, float length, ModelType hopo) { noteGroup.SetActive(hopo == ModelType.NOTE); hopoGroup.SetActive(hopo == ModelType.HOPO); + tapGroup.SetActive( hopo == ModelType.TAP); fullGroup.SetActive(hopo == ModelType.FULL); - state = State.WAITING; SetLength(length); @@ -160,7 +161,8 @@ public void HitNote() { noteGroup.SetActive(false); hopoGroup.SetActive(false); fullGroup.SetActive(false); - + tapGroup.SetActive(false); + if (fretNumber != null) { fretNumber.gameObject.SetActive(false); } @@ -173,7 +175,7 @@ public void MissNote() { if (fretNumber != null) { fretNumber.gameObject.SetActive(false); } - + state = State.MISSED; UpdateLineColor(); } diff --git a/Assets/Script/Serialization/Parser/MidiParser.FiveFret.cs b/Assets/Script/Serialization/Parser/MidiParser.FiveFret.cs index 933483f57..c60baab7d 100644 --- a/Assets/Script/Serialization/Parser/MidiParser.FiveFret.cs +++ b/Assets/Script/Serialization/Parser/MidiParser.FiveFret.cs @@ -20,9 +20,10 @@ private enum ForceState { NONE, HOPO, STRUM, - OPEN + OPEN, + TAP } - + private bool isCurrentlyTap=false; private class FiveFretIR { public long startTick; // This is an array due to extended sustains @@ -30,7 +31,7 @@ private class FiveFretIR { public FretFlag fretFlag; public bool hopo; - + public bool tap; // Used for difficulty downsampling public bool autoHopo; } @@ -63,7 +64,7 @@ private List<ForceStateIR> FiveFretGetForceState(TrackChunk trackChunk, int diff // we must store the ON events and wait until the // OFF event to actually add the state. This stores // the ON event timings. - long?[] forceStateArray = new long?[4]; + long?[] forceStateArray = new long?[5]; // Convert track events into intermediate representation foreach (var trackEvent in trackChunk.Events) { @@ -87,7 +88,7 @@ private List<ForceStateIR> FiveFretGetForceState(TrackChunk trackChunk, int diff forceState = ForceState.OPEN; } else if (header.SequenceEqual(SYSEX_TAP_NOTE)) { i = 3; - forceState = ForceState.HOPO; + forceState = ForceState.TAP; } else { continue; } @@ -96,11 +97,16 @@ private List<ForceStateIR> FiveFretGetForceState(TrackChunk trackChunk, int diff // If it is a flag on, wait until we get the flag // off so we can get the length of the flag period. forceStateArray[i] = totalDelta; + if(forceState==ForceState.TAP){ + isCurrentlyTap=true; + } } else { if (forceStateArray[i] == null) { continue; } - + if(forceState==ForceState.TAP){ + isCurrentlyTap=false; + } forceIR.Add(new ForceStateIR { startTick = forceStateArray[i].Value, endTick = totalDelta, @@ -109,16 +115,19 @@ private List<ForceStateIR> FiveFretGetForceState(TrackChunk trackChunk, int diff forceStateArray[i] = null; } - } else if (trackEvent is NoteEvent noteEvent) { + } else if (trackEvent is NoteEvent noteEvent && !isCurrentlyTap) { // Note based flags // Look for correct octave if (noteEvent.GetNoteOctave() != 4 + difficulty) { continue; } - + ForceState forceState = ForceState.NONE; + if(noteEvent.GetNoteOctave() == 7 && noteEvent.GetNoteName()==NoteName.GSharp){ + forceState = ForceState.TAP; + }else{ // Convert note to force state - ForceState forceState = noteEvent.GetNoteName() switch { + forceState = noteEvent.GetNoteName() switch { // Force HOPO NoteName.F => ForceState.HOPO, // Force strum @@ -126,6 +135,9 @@ private List<ForceStateIR> FiveFretGetForceState(TrackChunk trackChunk, int diff // Default _ => ForceState.NONE }; + } + + // Skip if not an actual state if (forceState == ForceState.NONE) { @@ -197,7 +209,7 @@ private List<FiveFretIR> FiveFretNotePass(TrackChunk trackChunk, int difficulty) // Default _ => -1 }; - + // Skip if not an actual note if (fret == -1) { continue; @@ -288,11 +300,15 @@ private void FiveFretNoteStatePass(List<FiveFretIR> noteIR, List<ForceStateIR> f // Set as open if requested note.fretFlag = FretFlag.OPEN; note.hopo = false; - } else { + } else{ // Otherwise, just set as a HOPO if requested note.hopo = force == ForceState.HOPO; } - + if (force == ForceState.TAP) { + note.tap=true; + note.hopo=false; + note.autoHopo=false; + } lastTime = note.startTick; lastFret = note.fretFlag; } @@ -319,6 +335,10 @@ private List<NoteInfo> FiveFretIrToRealPass(List<FiveFretIR> noteIR, TempoMap te int fret = i - 1; + if(noteInfo.tap){ + noteInfo.hopo=false; + noteInfo.autoHopo=false; + } // Get the end tick (different for open notes) long endTick; if (fret == 5) { @@ -336,6 +356,7 @@ private List<NoteInfo> FiveFretIrToRealPass(List<FiveFretIR> noteIR, TempoMap te time = startTime, length = endTime - startTime, fret = fret, + tap = noteInfo.tap, hopo = noteInfo.hopo, autoHopo = noteInfo.autoHopo });