protected override void Controls() { if (!Globals.gameSettings.keysModeEnabled) { if (Input.GetMouseButtonDown(0)) { AddObject(); } } else if (MSChartEditorInput.GetInputDown(MSChartEditorInputActions.AddSongObject)) { IList <SyncTrack> searchArray = editor.currentSong.syncTrack; int pos = SongObjectHelper.FindObjectPosition(ts, searchArray); if (pos == SongObjectHelper.NOTFOUND) { AddObject(); } else if (searchArray[pos].tick != 0) { editor.commandStack.Push(new SongEditDelete(searchArray[pos])); editor.selectedObjectsManager.currentSelectedObject = null; } } }
bool AdjustForAnchors(uint newBpmValue) { ChartEditor.GetInstance().songObjectPoolManager.SetAllPoolsDirty(); int pos = SongObjectHelper.FindObjectPosition(currentBPM, currentBPM.song.bpms); if (pos != SongObjectHelper.NOTFOUND) { BPM anchor = null; BPM bpmToAdjust = null; int anchorPos = 0; // Get the next anchor for (int i = pos + 1; i < currentBPM.song.bpms.Count; ++i) { if (currentBPM.song.bpms[i].anchor != null) { anchor = currentBPM.song.bpms[i]; anchorPos = i; // Get the bpm before that anchor bpmToAdjust = currentBPM.song.bpms[i - 1]; break; } } if (anchor == null || bpmToAdjust == currentBPM) { if (currentBPM.value != newBpmValue) { ChartEditor.isDirty = true; } currentBPM.value = newBpmValue; return(true); } // Calculate the minimum the bpm can adjust to const float MIN_DT = 0.01f; float bpmTime = (float)anchor.anchor - MIN_DT; float resolution = currentBPM.song.resolution; // Calculate the time of the 2nd bpm pretending that the adjustable one is super close to the anchor for (int i = anchorPos - 1; i > pos + 1; --i) { // Calculate up until 2 bpms before the anchor // Re-hash of the actual time calculation equation in Song.cs bpmTime -= (float)TickFunctions.DisToTime(currentBPM.song.bpms[i - 1].tick, currentBPM.song.bpms[i].tick, resolution, currentBPM.song.bpms[i - 1].value / 1000.0f); } float timeBetweenFirstAndSecond = bpmTime - currentBPM.time; // What bpm will result in this exact time difference? uint minVal = (uint)(Mathf.Ceil((float)TickFunctions.DisToBpm(currentBPM.song.bpms[pos].tick, currentBPM.song.bpms[pos + 1].tick, timeBetweenFirstAndSecond, currentBPM.song.resolution)) * 1000); if (newBpmValue < minVal) { newBpmValue = minVal; } if (anchorAdjustment == null) { anchorAdjustment = bpmToAdjust; anchorAdjustmentOriginalValue = new BPM(bpmToAdjust); } BPM anchorBPM = anchor; uint oldValue = currentBPM.value; currentBPM.value = newBpmValue; double deltaTime = (double)anchorBPM.anchor - editor.currentSong.LiveTickToTime(bpmToAdjust.tick, editor.currentSong.resolution); uint newValue = (uint)Mathf.Round((float)(TickFunctions.DisToBpm(bpmToAdjust.tick, anchorBPM.tick, deltaTime, editor.currentSong.resolution) * 1000.0d)); currentBPM.value = oldValue; if (deltaTime > 0 && newValue > 0) { if (newValue != 0) { bpmToAdjust.value = newValue; } currentBPM.value = newBpmValue; ChartEditor.isDirty = true; } } else { if (currentBPM.value != newBpmValue) { ChartEditor.isDirty = true; } currentBPM.value = newBpmValue; } return(true); }
public bool IsSelected(SongObject songObject) { return(SongObjectHelper.FindObjectPosition(songObject, currentSelectedObjects) != SongObjectHelper.NOTFOUND); }
public static SongObject FindObjectToModify(SongObject so) { ChartEditor editor = ChartEditor.Instance; Song song = editor.currentSong; Chart chart = editor.currentChart; int index; switch ((SongObject.ID)so.classID) { case SongObject.ID.Note: index = SongObjectHelper.FindObjectPosition(so as Note, chart.notes); if (index == SongObjectHelper.NOTFOUND) { return(null); } return(chart.notes[index]); case SongObject.ID.Starpower: index = SongObjectHelper.FindObjectPosition(so as Starpower, chart.starPower); if (index == SongObjectHelper.NOTFOUND) { return(null); } return(chart.starPower[index]); case SongObject.ID.ChartEvent: index = SongObjectHelper.FindObjectPosition(so as ChartEvent, chart.events); if (index == SongObjectHelper.NOTFOUND) { return(null); } return(chart.events[index]); case SongObject.ID.BPM: index = SongObjectHelper.FindObjectPosition(so as BPM, song.bpms); if (index == SongObjectHelper.NOTFOUND) { return(null); } return(song.bpms[index]); case SongObject.ID.TimeSignature: index = SongObjectHelper.FindObjectPosition(so as TimeSignature, song.timeSignatures); if (index == SongObjectHelper.NOTFOUND) { return(null); } return(song.timeSignatures[index]); case SongObject.ID.Section: index = SongObjectHelper.FindObjectPosition(so as Section, song.sections); if (index == SongObjectHelper.NOTFOUND) { return(null); } return(song.sections[index]); case SongObject.ID.Event: index = SongObjectHelper.FindObjectPosition(so as Event, song.events); if (index == SongObjectHelper.NOTFOUND) { return(null); } return(song.events[index]); default: Debug.LogError("Object to modify not implemented for object. Object will not be modified."); break; } return(so); }
static MoonscraperEngine.ICommand GenerateCommandsAdjustedForAnchors(BPM currentBPM, uint desiredBpmValue) { List <SongEditCommand> commands = new List <SongEditCommand>(); int pos = SongObjectHelper.FindObjectPosition(currentBPM, currentBPM.song.bpms); if (pos != SongObjectHelper.NOTFOUND) { BPM anchor = null; BPM bpmToAdjust = null; int anchorPos = 0; // Get the next anchor for (int i = pos + 1; i < currentBPM.song.bpms.Count; ++i) { if (currentBPM.song.bpms[i].anchor != null) { anchor = currentBPM.song.bpms[i]; anchorPos = i; // Get the bpm before that anchor bpmToAdjust = currentBPM.song.bpms[i - 1]; break; } } if (anchor == null || bpmToAdjust == currentBPM) { commands.Add(new SongEditModify <BPM>(currentBPM, new BPM(currentBPM.tick, desiredBpmValue, currentBPM.anchor))); return(new BatchedSongEditCommand(commands)); } // Calculate the minimum the bpm can adjust to const float MIN_DT = 0.01f; float bpmTime = (float)anchor.anchor - MIN_DT; float resolution = currentBPM.song.resolution; // Calculate the time of the 2nd bpm pretending that the adjustable one is super close to the anchor for (int i = anchorPos - 1; i > pos + 1; --i) { // Calculate up until 2 bpms before the anchor // Re-hash of the actual time calculation equation in Song.cs bpmTime -= (float)TickFunctions.DisToTime(currentBPM.song.bpms[i - 1].tick, currentBPM.song.bpms[i].tick, resolution, currentBPM.song.bpms[i - 1].value / 1000.0f); } float timeBetweenFirstAndSecond = bpmTime - currentBPM.time; // What bpm will result in this exact time difference? uint minVal = (uint)(Mathf.Ceil((float)TickFunctions.DisToBpm(currentBPM.song.bpms[pos].tick, currentBPM.song.bpms[pos + 1].tick, timeBetweenFirstAndSecond, currentBPM.song.resolution)) * 1000); if (desiredBpmValue < minVal) { desiredBpmValue = minVal; } BPM anchorBPM = anchor; uint oldValue = currentBPM.value; ChartEditor editor = ChartEditor.Instance; currentBPM.value = desiredBpmValue; // Very much cheating, better to not do this double deltaTime = (double)anchorBPM.anchor - editor.currentSong.LiveTickToTime(bpmToAdjust.tick, editor.currentSong.resolution); uint newValue = (uint)Mathf.Round((float)(TickFunctions.DisToBpm(bpmToAdjust.tick, anchorBPM.tick, deltaTime, editor.currentSong.resolution) * 1000.0d)); currentBPM.value = oldValue; uint finalValue = oldValue; if (deltaTime > 0 && newValue > 0) { if (newValue != 0) { commands.Add(new SongEditModify <BPM>(bpmToAdjust, new BPM(bpmToAdjust.tick, newValue, bpmToAdjust.anchor))); } finalValue = desiredBpmValue; } desiredBpmValue = finalValue; } if (desiredBpmValue == currentBPM.value) { return(null); } commands.Add(new SongEditModify <BPM>(currentBPM, new BPM(currentBPM.tick, desiredBpmValue, currentBPM.anchor))); return(new BatchedSongEditCommand(commands)); }
public void TryFindAndSelectSongObjects(IList <SongObject> songObjects) { Song song = editor.currentSong; Chart chart = editor.currentChart; foundSongObjects.Clear(); int warnChartObj = 0; int warnSyncObj = 0; int warnEventObj = 0; foreach (SongObject so in songObjects) { ChartObject chartObject = so as ChartObject; SyncTrack syncTrack = so as SyncTrack; Event eventObject = so as Event; if (chartObject != null) { int insertionIndex = SongObjectHelper.FindObjectPosition(chartObject, chart.chartObjects); if (insertionIndex != SongObjectHelper.NOTFOUND) { if (!foundSongObjects.Contains(chart.chartObjects[insertionIndex])) { foundSongObjects.Add(chart.chartObjects[insertionIndex]); } } else { ++warnChartObj; } } else if (syncTrack != null) { int insertionIndex = SongObjectHelper.FindObjectPosition(syncTrack, song.syncTrack); if (insertionIndex != SongObjectHelper.NOTFOUND) { if (!foundSongObjects.Contains(song.syncTrack[insertionIndex])) { foundSongObjects.Add(song.syncTrack[insertionIndex]); } } else { ++warnSyncObj; } } else if (eventObject != null) { int insertionIndex = SongObjectHelper.FindObjectPosition(eventObject, song.eventsAndSections); if (insertionIndex != SongObjectHelper.NOTFOUND) { if (!foundSongObjects.Contains(song.eventsAndSections[insertionIndex])) { foundSongObjects.Add(song.eventsAndSections[insertionIndex]); } } else { ++warnEventObj; } } else { UnityEngine.Debug.LogError("Unable to handle object " + so.ToString()); } } if (warnChartObj > 0) { UnityEngine.Debug.LogWarning(string.Format("Failed to find {0} chart object/s to highlight", warnChartObj)); } if (warnSyncObj > 0) { UnityEngine.Debug.LogWarning(string.Format("Failed to find {0} synctrack/s to highlight", warnSyncObj)); } if (warnEventObj > 0) { UnityEngine.Debug.LogWarning(string.Format("Failed to find {0} event/s to highlight", warnEventObj)); } currentSelectedObjects = foundSongObjects; foundSongObjects.Clear(); }
void FillNotesKeyboardControlsSustainMode(LaneInfo laneInfo) { int laneCount = laneInfo.laneCount; bool isTyping = Services.IsTyping; // Tell the system to stop updating the sustain length for (int i = 0; i < heldNotes.Length; ++i) { if (isTyping || Input.GetKeyUp(NumToStringLUT[(i + 1)])) { ClearHeldNotes(i); } } // Guard to prevent users from pressing keys while dragging out sustains if (!GameSettings.extendedSustainsEnabled) { foreach (Note heldNote in heldNotes) { if (heldNote != null && heldNote.length > 0) { return; } } } if (isTyping) { return; } bool openNotesBanned, nonOpenNotesBanned; CheckBannedInputsForSustainHolds(out openNotesBanned, out nonOpenNotesBanned); if (nonOpenNotesBanned) { return; } for (int i = 0; i < laneCount + 1; ++i) // Start at 1 to ignore the multinote { // Need to make sure the note is at it's correct tick position if (Input.GetKeyDown(NumToStringLUT[(i + 1)])) { int notePos = i; if (Input.GetKeyDown(GetOpenNoteInputKey(laneCount))) { if (openNotesBanned) // Ban conflicting inputs as the command stack REALLY doesn't like this. { continue; } notePos = allPlaceableNotes.IndexOf(openNote); } LeftyFlipReflectionCheck(ref notePos, laneCount); allPlaceableNotes[notePos].ExplicitUpdate(); int pos = SongObjectHelper.FindObjectPosition(allPlaceableNotes[notePos].note, editor.currentChart.notes); if (currentPlacementMode == KeysPlacementMode.None) { currentPlacementMode = pos == SongObjectHelper.NOTFOUND ? KeysPlacementMode.Adding : KeysPlacementMode.Deleting; } if (currentPlacementMode == KeysPlacementMode.Adding && pos == SongObjectHelper.NOTFOUND) { heldNotes[i] = allPlaceableNotes[notePos].note.CloneAs <Note>(); heldNotes[i].length = 0; currentlyAddingNotes.Add(heldNotes[i]); Debug.Log("Added " + allPlaceableNotes[notePos].note.rawNote + " note at position " + allPlaceableNotes[notePos].note.tick + " using keyboard controls"); } else if (currentPlacementMode == KeysPlacementMode.Deleting) { currentlyAddingNotes.Add(editor.currentChart.notes[pos]); Debug.Log("Removed " + editor.currentChart.notes[pos].rawNote + " note at position " + editor.currentChart.notes[pos].tick + " using keyboard controls"); } } } }
void KeyboardControlsSustainMode(LaneInfo laneInfo) { int laneCount = laneInfo.laneCount; bool isTyping = Services.IsTyping; for (int i = 0; i < heldNotes.Length; ++i) { // Add in the held note history when user lifts off the keys if (isTyping || Input.GetKeyUp((i + 1).ToString())) { KeySustainActionHistoryInsert(i); } } // Guard to prevent users from pressing keys while dragging out sustains if (!GameSettings.extendedSustainsEnabled) { foreach (Note heldNote in heldNotes) { if (heldNote != null && heldNote.length > 0) { return; } } } if (isTyping) { return; } for (int i = 0; i < laneCount + 1; ++i) // Start at 1 to ignore the multinote { // Need to make sure the note is at it's correct tick position if (Input.GetKeyDown((i + 1).ToString())) { int notePos = i; if (Input.GetKeyDown(GetOpenNoteInputKey(laneCount))) { notePos = allPlaceableNotes.IndexOf(openNote); } LeftyFlipReflectionCheck(ref notePos, laneCount); allPlaceableNotes[notePos].ExplicitUpdate(); int pos = SongObjectHelper.FindObjectPosition(allPlaceableNotes[notePos].note, editor.currentChart.notes); if (pos == SongObjectHelper.NOTFOUND) { Debug.Log("Added " + allPlaceableNotes[notePos].note.rawNote + " note at position " + allPlaceableNotes[notePos].note.tick + " using keyboard controls"); heldInitialOverwriteActions[i] = PlaceNote.AddObjectToCurrentChart((Note)allPlaceableNotes[notePos].note.Clone(), editor, out heldNotes[i]); //editor.actionHistory.Insert(PlaceNote.AddObjectToCurrentChart((Note)notes[notePos].note.Clone(), editor, out heldNotes[i - 1])); } else { editor.actionHistory.Insert(new ActionHistory.Delete(editor.currentChart.notes[pos])); Debug.Log("Removed " + editor.currentChart.notes[pos].rawNote + " note at position " + editor.currentChart.notes[pos].tick + " using keyboard controls"); editor.currentChart.notes[pos].Delete(); } } } }