public static Flags GetBannedFlagsForGameMode(Chart.GameMode gameMode) { Flags bannedFlags = Flags.None; switch (gameMode) { case Chart.GameMode.Guitar: case Chart.GameMode.GHLGuitar: { bannedFlags = Flags.ProDrums_Cymbal; break; } case Chart.GameMode.Drums: { bannedFlags = Flags.Forced | Flags.Tap; break; } default: { break; } } return(bannedFlags); }
void Update() { float time = ChartEditor.Instance.currentVisibleTime; ChartEditor editor = ChartEditor.Instance; Chart.GameMode gameMode = editor.currentChart.gameMode; // Enter window for (int i = physicsWindow.Count - 1; i >= 0; --i) { NoteController note = physicsWindow[i]; if (gameMode == Chart.GameMode.Guitar) { if (guitarHitWindow.DetectEnter(note.note, time)) { physicsWindow.Remove(note); } } else if (gameMode == Chart.GameMode.Drums) { if (drumsHitWindow.DetectEnter(note.note, time)) { physicsWindow.Remove(note); } } } }
int[] LookupPaletteMapForGameMode(Chart.GameMode gameMode, LaneInfo laneInfo) { int[] paletteMap = null; int laneCount = laneInfo.laneCount; switch (gameMode) { case (Chart.GameMode.Guitar): paletteMap = guitarModeLaneColorIndicies; break; case (Chart.GameMode.Drums): paletteMap = laneCount == 4 ? drumModeLaneColorIndicies4LaneOverride : drumModeLaneColorIndicies; break; case (Chart.GameMode.GHLGuitar): paletteMap = ghlGuitarModeLaneColorIndicies; break; default: throw new System.Exception("Unhandled gamemode"); } return(paletteMap); }
// Update is called once per frame void Update() { if (Globals.applicationMode == Globals.ApplicationMode.Playing && !GameSettings.bot) { ChartEditor editor = ChartEditor.Instance; GamepadInput input = editor.inputManager.mainGamepad; Chart.GameMode gameMode = editor.currentChart.gameMode; LaneInfo laneInfo = editor.laneInfo; if (gameMode == Chart.GameMode.Drums) { foreach (Note.DrumPad drumPad in System.Enum.GetValues(typeof(Note.DrumPad))) { if (bannedDrumPadInputs.ContainsKey(drumPad)) { continue; } if (input.GetPadInputControllerOrKeyboard(drumPad, laneInfo)) { animations[(int)drumPad].Press(); } else { animations[(int)drumPad].Release(); } } } else { foreach (Note.GuitarFret fret in System.Enum.GetValues(typeof(Note.GuitarFret))) { if (bannedFretInputs.ContainsKey(fret)) { continue; } if (input.GetFretInputControllerOrKeyboard(fret)) { animations[(int)fret].Press(); } else { animations[(int)fret].Release(); } } } } else { for (int i = 0; i < animations.Length; ++i) { if (!animations[i].running) { animations[i].Release(); } } } }
// Update is called once per frame void Update() { ChartEditor editor = ChartEditor.Instance; if (editor.currentState == ChartEditor.State.Playing && !GameSettings.bot) { Chart.GameMode gameMode = editor.currentChart.gameMode; LaneInfo laneInfo = editor.laneInfo; if (gameMode == Chart.GameMode.Drums) { foreach (Note.DrumPad drumPad in EnumX <Note.DrumPad> .Values) { if (bannedDrumPadInputs.ContainsKey(drumPad)) { continue; } if (DrumsInput.GetPadPressedInput(drumPad, laneInfo)) { animations[(int)drumPad].Press(); } else { animations[(int)drumPad].Release(); } } } else { foreach (Note.GuitarFret fret in EnumX <Note.GuitarFret> .Values) { if (bannedFretInputs.ContainsKey(fret)) { continue; } if (GuitarInput.GetFretInput(fret)) { animations[(int)fret].Press(); } else { animations[(int)fret].Release(); } } } } else { for (int i = 0; i < animations.Length; ++i) { if (!animations[i].running) { animations[i].Release(); } } } }
void SetMaterialColours(Chart.GameMode gameMode, int laneCount) { Dictionary <int, Color> colorDict = GetColorDict(gameMode, laneCount); foreach (var keyValue in colorDict) { flameMaterials[keyValue.Key].color = keyValue.Value; } }
public void UpdateStrikerColors(int laneCount) { Chart.GameMode gameMode = ChartEditor.GetInstance().currentGameMode; Color[] colours = laneInfo.laneColours; for (int i = 0; i < colours.Length; ++i) { fretRenders[i * 2].color = colours[i]; fretRenders[i * 2 + 1].color = colours[i]; } }
Dropdown GetCurrentFretSelector(Chart.GameMode gameMode, int laneCount) { Dropdown dropdown = fretSelectDropdown; Dictionary <int, Dropdown> overrideLookup; if (!(laneSelectLaneCountOverrideLookup.TryGetValue(gameMode, out overrideLookup) && overrideLookup.TryGetValue(laneCount, out dropdown))) { // No overrides present, go with the defaults laneSelectForGamemodeLookup.TryGetValue(gameMode, out dropdown); } return(dropdown); }
static GameplayType DetermineGameplayType(bool botEnabled, Chart.GameMode gameMode) { if (botEnabled) { return(GameplayType.Bot); } else if (gameMode == Chart.GameMode.Guitar) { return(GameplayType.Guitar); } else if (gameMode == Chart.GameMode.Drums) { return(GameplayType.Drums); } return(GameplayType.None); }
public IndicatorPressedInputSystem(HitAnimation[] animations, Chart.GameMode gameMode) { this.animations = animations; switch (gameMode) { case Chart.GameMode.Drums: { updateFn = UpdateDrumPadPresses; break; } default: { updateFn = UpdateGuitarFretPresses; break; } } }
Dictionary <int, Color> GetColorDict(Chart.GameMode gameMode, int laneCount) { Dictionary <int, Color> colorDict; Dictionary <int, Dictionary <int, Color> > laneOverrideDict; if (gameModeColourDictLaneOverride.TryGetValue(gameMode, out laneOverrideDict)) { if (laneOverrideDict.TryGetValue(laneCount, out colorDict)) { return(colorDict); } } if (gameModeColourDict.TryGetValue(gameMode, out colorDict)) { return(colorDict); } return(null); // Shouldn't ever be here }
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); }
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()); }
private static void ReadNotes(IList <MidiEvent> track, Song song, Song.Instrument instrument) { List <NoteOnEvent> forceNotesList = new List <NoteOnEvent>(); List <NoteOnEvent> proDrumsNotesList = new List <NoteOnEvent>(); List <SysexEvent> tapAndOpenEvents = new List <SysexEvent>(); Chart unrecognised = new Chart(song, Song.Instrument.Unrecognised); Chart.GameMode gameMode = Song.InstumentToChartGameMode(instrument); if (instrument == Song.Instrument.Unrecognised) { song.unrecognisedCharts.Add(unrecognised); } int rbSustainFixLength = (int)(64 * song.resolution / SongConfig.STANDARD_BEAT_RESOLUTION); // Load all the notes for (int i = 0; i < track.Count; i++) { var text = track[i] as TextEvent; if (text != null) { if (i == 0) { if (instrument == Song.Instrument.Unrecognised) { unrecognised.name = text.Text; } continue; // We don't want the first event because that is the name of the track } var tick = (uint)text.AbsoluteTime; var eventName = text.Text.Trim(new char[] { '[', ']' }); ChartEvent chartEvent = new ChartEvent(tick, eventName); if (instrument == Song.Instrument.Unrecognised) { unrecognised.Add(chartEvent); } else { song.GetChart(instrument, Song.Difficulty.Expert).Add(chartEvent); } } var note = track[i] as NoteOnEvent; if (note != null && note.OffEvent != null) { Song.Difficulty difficulty; var tick = (uint)note.AbsoluteTime; var sus = (uint)(note.OffEvent.AbsoluteTime - tick); if (instrument == Song.Instrument.Unrecognised) { int rawNote = SelectRawNoteValue(note.NoteNumber); Note newNote = new Note(tick, rawNote, sus); //difficulty = SelectRawNoteDifficulty(note.NoteNumber); unrecognised.Add(newNote); continue; } // Check if starpower event if (note.NoteNumber == MidIOHelper.STARPOWER_NOTE) { foreach (Song.Difficulty diff in EnumX <Song.Difficulty> .Values) { song.GetChart(instrument, diff).Add(new Starpower(tick, sus), false); } continue; } if (note.NoteNumber == MidIOHelper.SOLO_NOTE) { foreach (Song.Difficulty diff in EnumX <Song.Difficulty> .Values) { Chart chart = song.GetChart(instrument, diff); chart.Add(new ChartEvent(tick, MidIOHelper.SoloEventText)); chart.Add(new ChartEvent(tick + sus, MidIOHelper.SoloEndEventText)); } continue; } if (gameMode == Chart.GameMode.Drums) { Note.DrumPad dummy; if (MidIOHelper.CYMBAL_TO_PAD_LOOKUP.TryGetValue(note.NoteNumber, out dummy)) { // Cymbals toggles proDrumsNotesList.Add(note); continue; } } // Determine which difficulty we are manipulating try { if (gameMode == Chart.GameMode.GHLGuitar) { difficulty = SelectGHLNoteDifficulty(note.NoteNumber); } else { difficulty = SelectNoteDifficulty(note.NoteNumber); } } catch { continue; } // Check if we're reading a forcing event instead of a regular note if (gameMode != Chart.GameMode.Drums) { switch (note.NoteNumber) { case 65: case 66: case 77: case 78: case 89: case 90: case 101: case 102: forceNotesList.Add(note); // Store the event for later processing and continue continue; default: break; } } int fret; if (sus <= rbSustainFixLength) { sus = 0; } Note.Flags flags = Note.Flags.None; if (gameMode == Chart.GameMode.Drums) { fret = (int)GetDrumFretType(note.NoteNumber); int cymbalToggleId; if (MidIOHelper.PAD_TO_CYMBAL_LOOKUP.TryGetValue((Note.DrumPad)fret, out cymbalToggleId)) { flags |= Note.Flags.ProDrums_Cymbal; } } else if (gameMode == Chart.GameMode.GHLGuitar) { fret = (int)GetGHLFretType(note.NoteNumber); } else { fret = (int)GetStandardFretType(note.NoteNumber); } { // Add the note to the correct chart Note newNote = new Note(tick, fret, sus, flags); song.GetChart(instrument, difficulty).Add(newNote, false); } } var sysexEvent = track[i] as SysexEvent; if (sysexEvent != null) { tapAndOpenEvents.Add(sysexEvent); } } // Update all chart arrays if (instrument != Song.Instrument.Unrecognised) { foreach (Song.Difficulty diff in EnumX <Song.Difficulty> .Values) { song.GetChart(instrument, diff).UpdateCache(); } } else { unrecognised.UpdateCache(); } // Apply tap and open note events Chart[] chartsOfInstrument; if (instrument == Song.Instrument.Unrecognised) { chartsOfInstrument = new Chart[] { unrecognised }; } else { chartsOfInstrument = new Chart[EnumX <Song.Difficulty> .Count]; int difficultyCount = 0; foreach (Song.Difficulty difficulty in EnumX <Song.Difficulty> .Values) { chartsOfInstrument[difficultyCount++] = song.GetChart(instrument, difficulty); } } for (int i = 0; i < tapAndOpenEvents.Count; ++i) { var se1 = tapAndOpenEvents[i]; byte[] bytes = se1.GetData(); // Check for tap event if (bytes.Length == 8 && bytes[5] == 255 && bytes[7] == 1) { // Identified a tap section // 8 total bytes, 5th byte is FF, 7th is 1 to start, 0 to end uint tick = (uint)se1.AbsoluteTime; uint endPos = 0; // Find the end of the tap section for (int j = i; j < tapAndOpenEvents.Count; ++j) { var se2 = tapAndOpenEvents[j]; var bytes2 = se2.GetData(); /// Check for tap section end if (bytes2.Length == 8 && bytes2[5] == 255 && bytes2[7] == 0) { endPos = (uint)(se2.AbsoluteTime - tick); if (endPos > 0) { --endPos; } break; } } // Apply tap property foreach (Chart chart in chartsOfInstrument) { int index, length; SongObjectHelper.GetRange(chart.notes, tick, tick + endPos, out index, out length); for (int k = index; k < index + length; ++k) { chart.notes[k].SetType(Note.NoteType.Tap); } } } // Check for open notes // 5th byte determines the difficulty to apply to else if (bytes.Length == 8 && bytes[5] >= 0 && bytes[5] < 4 && bytes[7] == 1) { uint tick = (uint)se1.AbsoluteTime; Song.Difficulty difficulty; switch (bytes[5]) { case 0: difficulty = Song.Difficulty.Easy; break; case 1: difficulty = Song.Difficulty.Medium; break; case 2: difficulty = Song.Difficulty.Hard; break; case 3: difficulty = Song.Difficulty.Expert; break; default: continue; } uint endPos = 0; for (int j = i; j < tapAndOpenEvents.Count; ++j) { var se2 = tapAndOpenEvents[j] as SysexEvent; if (se2 != null) { var b2 = se2.GetData(); if (b2.Length == 8 && b2[5] == bytes[5] && b2[7] == 0) { endPos = (uint)(se2.AbsoluteTime - tick); if (endPos > 0) { --endPos; } break; } } } int index, length; SongObjectCache <Note> notes; if (instrument == Song.Instrument.Unrecognised) { notes = unrecognised.notes; } else { notes = song.GetChart(instrument, difficulty).notes; } SongObjectHelper.GetRange(notes, tick, tick + endPos, out index, out length); for (int k = index; k < index + length; ++k) { notes[k].guitarFret = Note.GuitarFret.Open; if (gameMode == Chart.GameMode.Drums) { notes[k].guitarFret = NoteFunctions.LoadDrumNoteToGuitarNote(notes[k].guitarFret); } } } } // Apply forcing events foreach (NoteOnEvent flagEvent in forceNotesList) { uint tick = (uint)flagEvent.AbsoluteTime; uint endPos = (uint)(flagEvent.OffEvent.AbsoluteTime - tick); Song.Difficulty difficulty; // Determine which difficulty we are manipulating try { difficulty = SelectNoteDifficulty(flagEvent.NoteNumber); } catch { continue; } Chart chart; if (instrument != Song.Instrument.Unrecognised) { chart = song.GetChart(instrument, difficulty); } else { chart = unrecognised; } int index, length; SongObjectHelper.GetRange(chart.notes, tick, tick + endPos, out index, out length); for (int i = index; i < index + length; ++i) { if ((chart.notes[i].flags & Note.Flags.Tap) != 0) { continue; } // if NoteNumber is odd force hopo, if even force strum if (flagEvent.NoteNumber % 2 != 0) { chart.notes[i].SetType(Note.NoteType.Hopo); } else { chart.notes[i].SetType(Note.NoteType.Strum); } } } foreach (var flagEvent in proDrumsNotesList) { uint tick = (uint)flagEvent.AbsoluteTime; uint endPos = (uint)(flagEvent.OffEvent.AbsoluteTime - tick); if (endPos > 0) { --endPos; } Debug.Assert(instrument == Song.Instrument.Drums); foreach (Song.Difficulty difficulty in EnumX <Song.Difficulty> .Values) { Chart chart = song.GetChart(instrument, difficulty); int index, length; SongObjectHelper.GetRange(chart.notes, tick, tick + endPos, out index, out length); Note.DrumPad drumPadForFlag; if (!MidIOHelper.CYMBAL_TO_PAD_LOOKUP.TryGetValue(flagEvent.NoteNumber, out drumPadForFlag)) { Debug.Assert(false, "Unknown note number flag " + flagEvent.NoteNumber); continue; } for (int i = index; i < index + length; ++i) { Note note = chart.notes[i]; if (note.drumPad == drumPadForFlag) { // Reverse cymbal flag note.flags ^= Note.Flags.ProDrums_Cymbal; } } } } }
// Update is called once per frame public override void UpdateVisuals() { if (!meshFilter) { Awake(); } base.UpdateVisuals(); Note note = nCon.note; if (note != null) { // Visuals // Update mesh if (note.IsOpenNote())// fret_type == Note.Fret_Type.OPEN) { meshFilter.sharedMesh = resources.openModel.sharedMesh; } else if (specialType == Note.SpecialType.StarPower) { meshFilter.sharedMesh = resources.spModel.sharedMesh; } else { meshFilter.sharedMesh = resources.standardModel.sharedMesh; } Material[] materials; ChartEditor editor = ChartEditor.Instance; Chart.GameMode gameMode = editor.currentGameMode; Note.NoteType visualNoteType = noteType; // Determine materials if (note.IsOpenNote()) { materials = resources.openRenderer.sharedMaterials; int colourIndex = 0; if (specialType == Note.SpecialType.StarPower) { if (visualNoteType == Note.NoteType.Hopo) { colourIndex = 3; } else { colourIndex = 2; } } else { if (visualNoteType == Note.NoteType.Hopo) { colourIndex = 1; } else { colourIndex = isTool ? 4 : 0; } } materials[2] = resources.openMaterials[colourIndex]; } else { LaneInfo laneInfo = editor.laneInfo; Material colorMat; if (isTool) { switch (visualNoteType) { case Note.NoteType.Tap: { colorMat = resources.GetToolTapMaterial(gameMode, laneInfo, note.rawNote); break; } case Note.NoteType.Cymbal: { colorMat = resources.GetToolCymbalMaterial(gameMode, laneInfo, note.rawNote); break; } default: { colorMat = resources.GetToolStrumMaterial(gameMode, laneInfo, note.rawNote); break; } } } else { switch (visualNoteType) { case Note.NoteType.Tap: { colorMat = resources.GetTapMaterial(gameMode, laneInfo, note.rawNote); break; } case Note.NoteType.Cymbal: { colorMat = resources.GetCymbalMaterial(gameMode, laneInfo, note.rawNote); break; } default: { colorMat = resources.GetStrumMaterial(gameMode, laneInfo, note.rawNote); break; } } } materials = GetMaterials(colorMat, visualNoteType); } noteRenderer.sharedMaterials = materials; } }
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()); }
// Update is called once per frame public override void UpdateVisuals() { if (!meshFilter) { Awake(); } base.UpdateVisuals(); Note note = nCon.note; if (note != null) { // Visuals // Update mesh if (note.IsOpenNote())// fret_type == Note.Fret_Type.OPEN) { meshFilter.sharedMesh = resources.openModel.sharedMesh; } else if (specialType == Note.SpecialType.StarPower) { meshFilter.sharedMesh = resources.spModel.sharedMesh; } else { meshFilter.sharedMesh = resources.standardModel.sharedMesh; } Material[] materials; ChartEditor editor = ChartEditor.Instance; Chart.GameMode gameMode = editor.currentGameMode; Note.NoteType visualNoteType = noteType; // Determine materials if (note.IsOpenNote()) { materials = resources.openRenderer.sharedMaterials; int colourIndex = 0; if (specialType == Note.SpecialType.StarPower) { if (visualNoteType == Note.NoteType.Hopo) { colourIndex = 3; } else { colourIndex = 2; } } else { if (visualNoteType == Note.NoteType.Hopo) { colourIndex = 1; } else { colourIndex = isTool ? 4 : 0; } } materials[2] = resources.openMaterials[colourIndex]; } else { LaneInfo laneInfo = editor.laneInfo; Material colorMat; int noteIndex = note.rawNote; if (note.ShouldBeCulledFromLanes(laneInfo)) // Should have been culled, but we want to display it anyway, clamp it to the last lane { noteIndex = Mathf.Min(note.rawNote, laneInfo.laneCount - 1); // Clamp to the edge of the lanes } if (isTool) { switch (visualNoteType) { case Note.NoteType.Tap: { colorMat = resources.GetToolTapMaterial(gameMode, laneInfo, noteIndex); break; } case Note.NoteType.Cymbal: { colorMat = resources.GetToolCymbalMaterial(gameMode, laneInfo, noteIndex); break; } default: { colorMat = resources.GetToolStrumMaterial(gameMode, laneInfo, noteIndex); break; } } } else { switch (visualNoteType) { case Note.NoteType.Tap: { colorMat = resources.GetTapMaterial(gameMode, laneInfo, noteIndex); break; } case Note.NoteType.Cymbal: { colorMat = resources.GetCymbalMaterial(gameMode, laneInfo, noteIndex); break; } default: { colorMat = resources.GetStrumMaterial(gameMode, laneInfo, noteIndex); break; } } } materials = GetMaterials(colorMat, visualNoteType); } noteRenderer.sharedMaterials = materials; } }
// Update is called once per frame void Update() { ChartEditor editor = ChartEditor.Instance; if (editor.currentState == ChartEditor.State.Playing && !GameSettings.bot) { Chart.GameMode gameMode = editor.currentChart.gameMode; LaneInfo laneInfo = editor.laneInfo; if (gameMode == Chart.GameMode.Drums) { foreach (Note.DrumPad drumPad in EnumX <Note.DrumPad> .Values) { if (bannedDrumPadInputs.ContainsKey(drumPad)) { continue; } bool lanePressed = false; switch (GameSettings.drumsModeOptions) { case GameSettings.DrumModeOptions.ProDrums: { lanePressed = DrumsInput.GetTomPressedInput(drumPad, laneInfo) || DrumsInput.GetCymbalPressedInput(drumPad, laneInfo); break; } default: { lanePressed = DrumsInput.GetPadPressedInput(drumPad, laneInfo); break; } } if (lanePressed) { animations[(int)drumPad].Press(); } else { animations[(int)drumPad].Release(); } } } else { foreach (Note.GuitarFret fret in EnumX <Note.GuitarFret> .Values) { if (bannedFretInputs.ContainsKey(fret)) { continue; } if (GuitarInput.GetFretInput(fret)) { animations[(int)fret].Press(); } else { animations[(int)fret].Release(); } } } } else { for (int i = 0; i < animations.Length; ++i) { if (!animations[i].running) { animations[i].Release(); } } } }
public Material GetStarpowerColorMaterial(Chart.GameMode gameMode, LaneInfo laneInfo, int noteIndex) { return(strumColorPalette[starpowerLaneColorIndex]); }
public Material GetToolTapMaterial(Chart.GameMode gameMode, LaneInfo laneInfo, int noteIndex) { return(tapColorPalette[toolNoteLaneColorIndex]); }
public Material GetCymbalMaterial(Chart.GameMode gameMode, LaneInfo laneInfo, int noteIndex) { int[] paletteMap = LookupPaletteMapForGameMode(gameMode, laneInfo); return(cymbalColorPalette[paletteMap[noteIndex]]); }