public void SetDifficulty(string value) { try { currentDifficulty = (Song.Difficulty)System.Enum.Parse(typeof(Song.Difficulty), value, true); } catch { Debug.LogError("Invalid difficulty set: " + value); } }
public RenderTexture Initialize(int _playerNumber, Song _song, Song.Difficulty _difficulty, Vector2 _output, Pool _pool, PoolIndex _poolIndex, uint _resolution, float _speed) { playerNumber = _playerNumber; layerMask = 1 << (10 + playerNumber); song = _song; switch (_difficulty) { case Song.Difficulty.Easy: notes = song.data.notes.easy; break; case Song.Difficulty.Medium: notes = song.data.notes.medium; break; case Song.Difficulty.Hard: notes = song.data.notes.hard; break; case Song.Difficulty.Expert: notes = song.data.notes.expert; break; } pool = _pool; index = new PoolIndex(); resolution = _resolution; nextBar = resolution; speed = _speed; index = _poolIndex; lastNoteHit = true; activeNotes = new List <NoteInstance>(); activeBars = new List <BarInstance>(); willRemove = new List <NoteInstance>(); willRemoveBars = new List <BarInstance>(); nextLine = new Line(); nextLine.note = new List <NoteInstance>(); nextLine.fred = new bool[5]; noteCounter.Initialize(); output = new RenderTexture(Mathf.CeilToInt(_output.x), Mathf.CeilToInt(_output.y), 16, RenderTextureFormat.ARGB32); cam.GetComponent <Camera>().targetTexture = output; cam.GetComponent <Camera>().cullingMask = layerMask; SetLayerRecursive(transform, 10 + playerNumber); playerInput = new PlayerInput(PlayerInput.Device.Xinput, playerNumber); return(output); }
public bool IsPlayable(Song.Difficulty difficulty) { if (!c797f98945fa1137ccf124ed256a6cca3.ceeb5be9cc96dff470c7b191db9930716(this.c29df49907877de440240adc2b4b21da7, c4e2d2055e31b0e0d929410973f6d8238.c56715cb40fd0662990dfc29403dcba40) || !c797f98945fa1137ccf124ed256a6cca3.ceeb5be9cc96dff470c7b191db9930716(this.c29df49907877de440240adc2b4b21da7.GetChart(difficulty), c4e2d2055e31b0e0d929410973f6d8238.c56715cb40fd0662990dfc29403dcba40)) { return(false); } Label_002E: switch (7) { case 0: goto Label_002E; } if (1 == 0) { } Chart chart = this.c29df49907877de440240adc2b4b21da7.GetChart(difficulty); return(chart.c0b1b8c3c211f7e5aef6658bc73532491); }
static int GetMidiNoteNumber(Note note, Chart.GameMode gameMode, Song.Difficulty difficulty) { Dictionary <int, int> noteToMidiOffsetDict; int difficultyNumber; int offset; if (!c_gameModeNoteWriteOffsetDictLookup.TryGetValue(gameMode, out noteToMidiOffsetDict)) { throw new System.Exception("Unhandled game mode, unable to get offset dictionary"); } if (!noteToMidiOffsetDict.TryGetValue(note.rawNote, out offset)) { throw new System.Exception("Unhandled note, unable to get offset"); } if (!c_difficultyToMidiNoteWriteDict.TryGetValue(difficulty, out difficultyNumber)) { throw new System.Exception("Unhandled difficulty"); } return(difficultyNumber + offset); }
public void Write(Song song, ExportOptions exportOptions, out string errorList) { song.UpdateCache(); errorList = string.Empty; string saveString = string.Empty; try { string musicString = string.Empty; string guitarString = string.Empty; string bassString = string.Empty; string rhythmString = string.Empty; string drumString = string.Empty; GetAudioStreamSaveString GetSaveAudioString = audio => { string audioString; string audioLocation = song.GetAudioLocation(audio); if (audioLocation != string.Empty && Path.GetDirectoryName(audioLocation).Replace("\\", "/") == Path.GetDirectoryName(path).Replace("\\", "/")) { audioString = Path.GetFileName(audioLocation); } else { audioString = audioLocation; } return(audioString); }; musicString = GetSaveAudioString(Song.AudioInstrument.Song); guitarString = GetSaveAudioString(Song.AudioInstrument.Guitar); bassString = GetSaveAudioString(Song.AudioInstrument.Bass); rhythmString = GetSaveAudioString(Song.AudioInstrument.Rhythm); drumString = GetSaveAudioString(Song.AudioInstrument.Drum); // Song properties Debug.Log("Writing song properties"); saveString += s_chartHeaderSong; saveString += GetPropertiesStringWithoutAudio(song, exportOptions); // Song audio if (song.GetAudioIsLoaded(Song.AudioInstrument.Song) || (musicString != null && musicString != string.Empty)) { saveString += string.Format(s_audioStreamFormat, "MusicStream", musicString); } if (song.GetAudioIsLoaded(Song.AudioInstrument.Guitar) || (guitarString != null && guitarString != string.Empty)) { saveString += string.Format(s_audioStreamFormat, "GuitarStream", guitarString); } if (song.GetAudioIsLoaded(Song.AudioInstrument.Bass) || (bassString != null && bassString != string.Empty)) { saveString += string.Format(s_audioStreamFormat, "BassStream", bassString); } if (song.GetAudioIsLoaded(Song.AudioInstrument.Rhythm) || (rhythmString != null && rhythmString != string.Empty)) { saveString += string.Format(s_audioStreamFormat, "RhythmStream", rhythmString); } if (song.GetAudioIsLoaded(Song.AudioInstrument.Drum) || (drumString != null && drumString != string.Empty)) { saveString += string.Format(s_audioStreamFormat, "DrumStream", drumString); } saveString += s_chartSectionFooter; } catch (System.Exception e) { string error = Logger.LogException(e, "Error with saving song properties"); errorList += error + Globals.LINE_ENDING; saveString = string.Empty; // Clear all the song properties because we don't want braces left open, which will screw up the loading of the chart #if UNITY_EDITOR System.Diagnostics.Debugger.Break(); #endif } // SyncTrack Debug.Log("Writing synctrack"); saveString += s_chartHeaderSyncTrack; if (exportOptions.tickOffset > 0) { saveString += new BPM().GetSaveString(); saveString += new TimeSignature().GetSaveString(); } saveString += GetSaveString(song, song.syncTrack, exportOptions, ref errorList); saveString += s_chartSectionFooter; // Events Debug.Log("Writing events"); saveString += s_chartHeaderEvents; saveString += GetSaveString(song, song.eventsAndSections, exportOptions, ref errorList); saveString += s_chartSectionFooter; // Charts foreach (Song.Instrument instrument in EnumX <Song.Instrument> .Values) { string instrumentSaveString = string.Empty; switch (instrument) { case (Song.Instrument.Guitar): instrumentSaveString = "Single"; break; case (Song.Instrument.GuitarCoop): instrumentSaveString = "DoubleGuitar"; break; case (Song.Instrument.Bass): instrumentSaveString = "DoubleBass"; break; case (Song.Instrument.Rhythm): instrumentSaveString = "DoubleRhythm"; break; case (Song.Instrument.Drums): instrumentSaveString = "Drums"; break; case (Song.Instrument.Keys): instrumentSaveString = "Keyboard"; break; case (Song.Instrument.GHLiveGuitar): instrumentSaveString = "GHLGuitar"; break; case (Song.Instrument.GHLiveBass): instrumentSaveString = "GHLBass"; break; default: continue; } foreach (Song.Difficulty difficulty in EnumX <Song.Difficulty> .Values) { string difficultySaveString = difficulty.ToString(); string chartString = GetSaveString(song, song.GetChart(instrument, difficulty).chartObjects, exportOptions, ref errorList, instrument); if (chartString == string.Empty) { if (exportOptions.copyDownEmptyDifficulty) { Song.Difficulty chartDiff = difficulty; bool exit = false; while (chartString == string.Empty) { switch (chartDiff) { case (Song.Difficulty.Easy): chartDiff = Song.Difficulty.Medium; break; case (Song.Difficulty.Medium): chartDiff = Song.Difficulty.Hard; break; case (Song.Difficulty.Hard): chartDiff = Song.Difficulty.Expert; break; case (Song.Difficulty.Expert): default: exit = true; break; } chartString = GetSaveString(song, song.GetChart(instrument, chartDiff).chartObjects, exportOptions, ref errorList, instrument); if (exit) { break; } } if (exit) { continue; } } else { continue; } } saveString += string.Format(s_chartHeaderTrackFormat, difficultySaveString, instrumentSaveString); saveString += chartString; saveString += s_chartSectionFooter; } } // Unrecognised charts foreach (Chart chart in song.unrecognisedCharts) { string chartString = GetSaveString(song, chart.chartObjects, exportOptions, ref errorList, Song.Instrument.Unrecognised); saveString += string.Format(s_chartSectionHeaderFormat, chart.name); saveString += chartString; saveString += s_chartSectionFooter; } try { // Save to file File.WriteAllText(path, saveString, System.Text.Encoding.UTF8); } catch (Exception e) { Logger.LogException(e, "Error when writing text to file"); } }
static SortableBytes[] GetChartSortableBytes(Song song, Song.Instrument instrument, Song.Difficulty difficulty, ExportOptions exportOptions) { Chart chart = song.GetChart(instrument, difficulty); Chart.GameMode gameMode = chart.gameMode; if (exportOptions.copyDownEmptyDifficulty) { Song.Difficulty chartDiff = difficulty; while (chart.notes.Count <= 0) { switch (chartDiff) { case (Song.Difficulty.Easy): chartDiff = Song.Difficulty.Medium; break; case (Song.Difficulty.Medium): chartDiff = Song.Difficulty.Hard; break; case (Song.Difficulty.Hard): chartDiff = Song.Difficulty.Expert; break; case (Song.Difficulty.Expert): default: return(new SortableBytes[0]); } chart = song.GetChart(instrument, chartDiff); } } List <SortableBytes> eventList = new List <SortableBytes>(); ChartEvent soloOnEvent = null; foreach (ChartObject chartObject in chart.chartObjects) { Note note = chartObject as Note; SortableBytes onEvent = null; SortableBytes offEvent = null; if (note != null) { int noteNumber = GetMidiNoteNumber(note, gameMode, difficulty); GetNoteNumberBytes(noteNumber, note, out onEvent, out offEvent); if (exportOptions.forced) { // Forced notes if ((note.flags & Note.Flags.Forced) != 0 && note.type != Note.NoteType.Tap && (note.previous == null || (note.previous.tick != note.tick))) // Don't overlap on chords { // Add a note int difficultyNumber; int forcingOffset; if (!c_difficultyToMidiNoteWriteDict.TryGetValue(difficulty, out difficultyNumber)) { throw new Exception("Unhandled difficulty"); } if (!c_forcingMidiWriteOffsets.TryGetValue(note.type, out forcingOffset)) { throw new Exception("Unhandled note type found when trying to write forcing flag"); } int forcedNoteNumber = difficultyNumber + forcingOffset; SortableBytes forceOnEvent = new SortableBytes(note.tick, new byte[] { ON_EVENT, (byte)forcedNoteNumber, VELOCITY }); SortableBytes forceOffEvent = new SortableBytes(note.tick + 1, new byte[] { OFF_EVENT, (byte)forcedNoteNumber, VELOCITY }); InsertionSort(eventList, forceOnEvent); InsertionSort(eventList, forceOffEvent); } if (instrument == Song.Instrument.Drums && ((note.flags & Note.Flags.ProDrums_Cymbal) == 0)) // We want to write our flags if the cymbal is toggled OFF, as these notes are cymbals by default { int tomToggleNoteNumber; if (MidIOHelper.PAD_TO_CYMBAL_LOOKUP.TryGetValue(note.drumPad, out tomToggleNoteNumber)) { SortableBytes tomToggleOnEvent = new SortableBytes(note.tick, new byte[] { ON_EVENT, (byte)tomToggleNoteNumber, VELOCITY }); SortableBytes tomToggleOffEvent = new SortableBytes(note.tick + 1, new byte[] { OFF_EVENT, (byte)tomToggleNoteNumber, VELOCITY }); InsertionSort(eventList, tomToggleOnEvent); InsertionSort(eventList, tomToggleOffEvent); } } int openNote = gameMode == Chart.GameMode.GHLGuitar ? (int)Note.GHLiveGuitarFret.Open : (int)Note.GuitarFret.Open; // Add tap sysex events if (difficulty == Song.Difficulty.Expert && note.rawNote != openNote && (note.flags & Note.Flags.Tap) != 0 && (note.previous == null || (note.previous.flags & Note.Flags.Tap) == 0)) // This note is a tap while the previous one isn't as we're creating a range { // Find the next non-tap note Note nextNonTap = note; while (nextNonTap.next != null && nextNonTap.rawNote != openNote && (nextNonTap.next.flags & Note.Flags.Tap) != 0) { nextNonTap = nextNonTap.next; } // Tap event = 08-50-53-00-00-FF-04-01, end with 01 for On, 00 for Off byte[] tapOnEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, 0xFF, 0x04, SYSEX_ON, SYSEX_END }; byte[] tapOffEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, 0xFF, 0x04, SYSEX_OFF, SYSEX_END }; SortableBytes tapOnEvent = new SortableBytes(note.tick, tapOnEventBytes); SortableBytes tapOffEvent = new SortableBytes(nextNonTap.tick + 1, tapOffEventBytes); InsertionSort(eventList, tapOnEvent); InsertionSort(eventList, tapOffEvent); } } if (gameMode != Chart.GameMode.Drums && gameMode != Chart.GameMode.GHLGuitar && difficulty == Song.Difficulty.Expert && note.guitarFret == Note.GuitarFret.Open && (note.previous == null || (note.previous.guitarFret != Note.GuitarFret.Open))) { // Find the next non-open note Note nextNonOpen = note; while (nextNonOpen.next != null && nextNonOpen.next.guitarFret == Note.GuitarFret.Open) { nextNonOpen = nextNonOpen.next; } byte diff; switch (difficulty) { case (Song.Difficulty.Easy): diff = 0; break; case (Song.Difficulty.Medium): diff = 1; break; case (Song.Difficulty.Hard): diff = 2; break; case (Song.Difficulty.Expert): diff = 3; break; default: continue; } byte[] openOnEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, diff, 0x01, SYSEX_ON, SYSEX_END }; byte[] openOffEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, diff, 0x01, SYSEX_OFF, SYSEX_END }; SortableBytes openOnEvent = new SortableBytes(note.tick, openOnEventBytes); SortableBytes openOffEvent = new SortableBytes(nextNonOpen.tick + 1, openOffEventBytes); InsertionSort(eventList, openOnEvent); InsertionSort(eventList, openOffEvent); } } Starpower sp = chartObject as Starpower; if (sp != null && difficulty == Song.Difficulty.Expert) // Starpower cannot be split up between charts in a midi file { GetStarpowerBytes(sp, out onEvent, out offEvent); } ChartEvent chartEvent = chartObject as ChartEvent; if (chartEvent != null && difficulty == Song.Difficulty.Expert) // Text events cannot be split up in the file { if (soloOnEvent != null && chartEvent.eventName == MidIOHelper.SoloEndEventText) { GetSoloBytes(soloOnEvent, chartEvent.tick, out onEvent, out offEvent); soloOnEvent = null; } else if (chartEvent.eventName == MidIOHelper.SoloEventText) { soloOnEvent = chartEvent; } else { InsertionSort(eventList, GetChartEventBytes(chartEvent)); } } if (onEvent != null && offEvent != null) { InsertionSort(eventList, onEvent); if (offEvent.tick == onEvent.tick) { ++offEvent.tick; } InsertionSort(eventList, offEvent); } } if (soloOnEvent != null) // Found a solo event with no end. Assume the solo lasts for the rest of the song { SortableBytes onEvent = null; SortableBytes offEvent = null; uint soloEndTick = chart.chartObjects[chart.chartObjects.Count - 1].tick; // In order to get a solo event the chart objects needed to have some object in this container, no need to check size, hopefully... GetSoloBytes(soloOnEvent, soloEndTick, out onEvent, out offEvent); if (onEvent != null && offEvent != null) { InsertionSort(eventList, onEvent); if (offEvent.tick == onEvent.tick) { ++offEvent.tick; } InsertionSort(eventList, offEvent); } } return(eventList.ToArray()); }
public PlayerInfo(Song.Difficulty _difficulty) { difficulty = _difficulty; }
static SortableBytes[] GetChartSortableBytes(Song song, Song.Instrument instrument, Song.Difficulty difficulty, ExportOptions exportOptions) { Chart chart = song.GetChart(instrument, difficulty); Chart.GameMode gameMode = chart.gameMode; if (exportOptions.copyDownEmptyDifficulty) { Song.Difficulty chartDiff = difficulty; while (chart.notes.Count <= 0) { switch (chartDiff) { case (Song.Difficulty.Easy): chartDiff = Song.Difficulty.Medium; break; case (Song.Difficulty.Medium): chartDiff = Song.Difficulty.Hard; break; case (Song.Difficulty.Hard): chartDiff = Song.Difficulty.Expert; break; case (Song.Difficulty.Expert): default: return(new SortableBytes[0]); } chart = song.GetChart(instrument, chartDiff); } } List <SortableBytes> eventList = new List <SortableBytes>(); del InsertionSort = (sortableByte) => { int index = eventList.Count - 1; while (index >= 0 && sortableByte.tick < eventList[index].tick) { --index; } eventList.Insert(index + 1, sortableByte); }; foreach (ChartObject chartObject in chart.chartObjects) { Note note = chartObject as Note; SortableBytes onEvent = null; SortableBytes offEvent = null; if (note != null) { int noteNumber = GetMidiNoteNumber(note, gameMode, difficulty); GetNoteNumberBytes(noteNumber, note, out onEvent, out offEvent); if (exportOptions.forced) { // Forced notes if ((note.flags & Note.Flags.Forced) != 0 && note.type != Note.NoteType.Tap && (note.previous == null || (note.previous.tick != note.tick))) // Don't overlap on chords { // Add a note int difficultyNumber; int forcingOffset; if (!c_difficultyToMidiNoteWriteDict.TryGetValue(difficulty, out difficultyNumber)) { throw new Exception("Unhandled difficulty"); } if (!c_forcingMidiWriteOffsets.TryGetValue(note.type, out forcingOffset)) { throw new Exception("Unhandled note type found when trying to write forcing flag"); } int forcedNoteNumber = difficultyNumber + forcingOffset; SortableBytes forceOnEvent = new SortableBytes(note.tick, new byte[] { ON_EVENT, (byte)forcedNoteNumber, VELOCITY }); SortableBytes forceOffEvent = new SortableBytes(note.tick + 1, new byte[] { OFF_EVENT, (byte)forcedNoteNumber, VELOCITY }); InsertionSort(forceOnEvent); InsertionSort(forceOffEvent); } int openNote = gameMode == Chart.GameMode.GHLGuitar ? (int)Note.GHLiveGuitarFret.Open : (int)Note.GuitarFret.Open; // Add tap sysex events if (difficulty == Song.Difficulty.Expert && note.rawNote != openNote && (note.flags & Note.Flags.Tap) != 0 && (note.previous == null || (note.previous.flags & Note.Flags.Tap) == 0)) // This note is a tap while the previous one isn't as we're creating a range { // Find the next non-tap note Note nextNonTap = note; while (nextNonTap.next != null && nextNonTap.rawNote != openNote && (nextNonTap.next.flags & Note.Flags.Tap) != 0) { nextNonTap = nextNonTap.next; } // Tap event = 08-50-53-00-00-FF-04-01, end with 01 for On, 00 for Off byte[] tapOnEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, 0xFF, 0x04, SYSEX_ON, SYSEX_END }; byte[] tapOffEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, 0xFF, 0x04, SYSEX_OFF, SYSEX_END }; SortableBytes tapOnEvent = new SortableBytes(note.tick, tapOnEventBytes); SortableBytes tapOffEvent = new SortableBytes(nextNonTap.tick + 1, tapOffEventBytes); InsertionSort(tapOnEvent); InsertionSort(tapOffEvent); } } if (gameMode != Chart.GameMode.Drums && gameMode != Chart.GameMode.GHLGuitar && difficulty == Song.Difficulty.Expert && note.guitarFret == Note.GuitarFret.Open && (note.previous == null || (note.previous.guitarFret != Note.GuitarFret.Open))) { // Find the next non-open note Note nextNonOpen = note; while (nextNonOpen.next != null && nextNonOpen.next.guitarFret == Note.GuitarFret.Open) { nextNonOpen = nextNonOpen.next; } byte diff; switch (difficulty) { case (Song.Difficulty.Easy): diff = 0; break; case (Song.Difficulty.Medium): diff = 1; break; case (Song.Difficulty.Hard): diff = 2; break; case (Song.Difficulty.Expert): diff = 3; break; default: continue; } byte[] openOnEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, diff, 0x01, SYSEX_ON, SYSEX_END }; byte[] openOffEventBytes = new byte[] { SYSEX_START, 0x08, 0x50, 0x53, 0x00, 0x00, diff, 0x01, SYSEX_OFF, SYSEX_END }; SortableBytes openOnEvent = new SortableBytes(note.tick, openOnEventBytes); SortableBytes openOffEvent = new SortableBytes(nextNonOpen.tick + 1, openOffEventBytes); InsertionSort(openOnEvent); InsertionSort(openOffEvent); } } Starpower sp = chartObject as Starpower; if (sp != null && difficulty == Song.Difficulty.Expert) // Starpower cannot be split up between charts in a midi file { GetStarpowerBytes(sp, out onEvent, out offEvent); } ChartEvent chartEvent = chartObject as ChartEvent; if (chartEvent != null && difficulty == Song.Difficulty.Expert) // Text events cannot be split up in the file { InsertionSort(GetChartEventBytes(chartEvent)); } if (onEvent != null && offEvent != null) { InsertionSort(onEvent); if (offEvent.tick == onEvent.tick) { ++offEvent.tick; } InsertionSort(offEvent); } } return(eventList.ToArray()); }
public static bool AllowedToBeDoubleKick(Note note, Song.Difficulty difficulty) { return(note.IsOpenNote() && difficulty == Song.Difficulty.Expert); }
static void SubmitChartData(Song song, string dataName, List <string> stringData, string filePath = "") { switch (dataName) { case ChartIOHelper.c_dataBlockSong: #if SONG_DEBUG Debug.Log("Loading chart properties"); #endif SubmitDataSong(song, stringData, new FileInfo(filePath).Directory.FullName); break; case ChartIOHelper.c_dataBlockSyncTrack: #if SONG_DEBUG Debug.Log("Loading sync data"); #endif case ChartIOHelper.c_dataBlockEvents: #if SONG_DEBUG Debug.Log("Loading events data"); #endif SubmitDataGlobals(song, stringData); break; default: // Determine what difficulty foreach (var kvPair in ChartIOHelper.c_trackNameToTrackDifficultyLookup) { if (Regex.IsMatch(dataName, string.Format(@"\[{0}.", kvPair.Key))) { Song.Difficulty chartDiff = kvPair.Value; int instumentStringOffset = 1 + kvPair.Key.Length; string instrumentKey = dataName.Substring(instumentStringOffset, dataName.Length - instumentStringOffset - 1); Song.Instrument instrument; if (ChartIOHelper.c_instrumentStrToEnumLookup.TryGetValue(instrumentKey, out instrument)) { Song.Instrument instrumentParsingType; if (!ChartIOHelper.c_instrumentParsingTypeLookup.TryGetValue(instrument, out instrumentParsingType)) { instrumentParsingType = Song.Instrument.Guitar; } LoadChart(song.GetChart(instrument, chartDiff), stringData, instrumentParsingType); } else { LoadUnrecognisedChart(song, dataName, stringData); } goto OnChartLoaded; } } { // Add to the unused chart list LoadUnrecognisedChart(song, dataName, stringData); goto OnChartLoaded; } // Easy break out of loop OnChartLoaded: return; } }
void SetDifficultyToggle(Toggle toggle, Song.Difficulty diff) { toggle.isOn = ChartEditor.Instance.currentDifficulty == diff; }