public TargetData(Cue cue, float offset) { Vector2 pos = NotePosCalc.PitchToPos(cue); x = pos.x; y = pos.y; beatTime = (cue.tick - offset) / 480f; beatLength = cue.tickLength; velocity = cue.velocity; handType = cue.handType; behavior = cue.behavior; }
public TargetData(Cue cue) { ID = GetNextId(); Vector2 pos = NotePosCalc.PitchToPos(cue); x = pos.x; y = pos.y; time = new QNT_Timestamp((UInt64)cue.tick); beatLength = new QNT_Duration((UInt64)cue.tickLength); velocity = cue.velocity; handType = cue.handType; behavior = cue.behavior; }
public void Export() { string dirpath = Application.persistentDataPath; CueFile export = new CueFile(); export.cues = new List <Cue>(); foreach (Target target in orderedNotes) { if (target.data.beatLength == 0) { target.data.beatLength = 120; } if (target.data.behavior == TargetBehavior.Metronome) { continue; } export.cues.Add(NotePosCalc.ToCue(target, offset, false)); } switch (difficultyManager.loadedIndex) { case 0: audicaFile.diffs.expert = export; break; case 1: audicaFile.diffs.advanced = export; break; case 2: audicaFile.diffs.moderate = export; break; case 3: audicaFile.diffs.beginner = export; break; } audicaFile.desc = desc; AudicaExporter.ExportToAudicaFile(audicaFile); NotificationShower.AddNotifToQueue(new NRNotification("Map saved successfully!")); }
// execute simple actions which don't require any state management' private void UpdateActions() { //if (EditorInput.selectedTool != EditorTool.DragSelect) return; /** Setting hitsounds **/ if (frameIntentSetHitSoundStandard) { SetHitsoundAction(TargetVelocity.Standard); } if (frameIntentSetHitSoundSnare) { SetHitsoundAction(TargetVelocity.Snare); } if (frameIntentSetHitSoundPercussion) { SetHitsoundAction(TargetVelocity.Percussion); } if (frameIntentSetHitSoundChain) { SetHitsoundAction(TargetVelocity.Chain); } if (frameIntentSetHitSoundChainStart) { SetHitsoundAction(TargetVelocity.ChainStart); } if (frameIntentSetHitSoundMelee) { SetHitsoundAction(TargetVelocity.Melee); } /** Cut Copy Paste Delete **/ if (frameIntentCut) { frameIntentCopy = true; frameIntentDelete = true; } if (frameIntentCopy) { clipboardNotes = new List <Cue>(); timeline.selectedNotes.ForEach(note => clipboardNotes.Add(NotePosCalc.ToCue(note, 0, false))); } if (frameIntentPaste) { timeline.DeselectAllTargets(); timeline.PasteCues(clipboardNotes, Timeline.BeatTime()); } if (frameIntentDelete) { if (timeline.selectedNotes.Count > 0) { timeline.DeleteTargets(timeline.selectedNotes); } timeline.selectedNotes = new List <Target>(); } /** Note flipping **/ if (frameIntentSwapColors) { timeline.SwapTargets(timeline.selectedNotes); } if (frameIntentFlipTargetsHorizontally) { timeline.FlipTargetsHorizontal(timeline.selectedNotes); } if (frameIntentFlipTargetsVertically) { timeline.FlipTargetsVertical(timeline.selectedNotes); } /** Note selection and movement **/ if (frameIntentDeselectAll) { timeline.DeselectAllTargets(); } }
void Update() { //If the user decides they hate productivity and want to unselect all their notes, so be it. if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.D)) { timeline.DeselectAllTargets(); } //Applying hitsounds to selected: if (!activated) { return; } //TODO: Add shift + ctrl detection up here instead of multipule times if (Input.GetKeyDown(KeyCode.Q)) { SetHitsoundAction(TargetVelocity.Standard); } else if (Input.GetKeyDown(KeyCode.W)) { SetHitsoundAction(TargetVelocity.Snare); } else if (Input.GetKeyDown(KeyCode.E)) { SetHitsoundAction(TargetVelocity.Percussion); } else if (Input.GetKeyDown(KeyCode.R)) { SetHitsoundAction(TargetVelocity.ChainStart); } else if (Input.GetKeyDown(KeyCode.T)) { SetHitsoundAction(TargetVelocity.Chain); } else if (Input.GetKeyDown(KeyCode.Y)) { SetHitsoundAction(TargetVelocity.Melee); } var iconsUnderMouse = MouseUtil.IconsUnderMouse(notesLayer); TargetIcon iconUnderMouse = iconsUnderMouse.Length > 0 ? iconsUnderMouse[0] : null; /** Click Detection **/ if (isSelectionDown && !hasMovedOutOfClickBounds) { // Check for a tiny amount of mouse movement to ensure this was meant to be a click float movement = Math.Abs(startClickDetectPos.magnitude - Input.mousePosition.magnitude); if (movement > 2) { hasMovedOutOfClickBounds = true; } } /** Cut Copy Paste Delete **/ // TODO: Move these actions into timeline to record sane undo actions! Action delete = () => { if (timeline.selectedNotes.Count > 0) { timeline.DeleteTargets(timeline.selectedNotes); } timeline.selectedNotes = new List <Target>(); }; Action copy = () => { clipboardNotes = new List <Cue>(); timeline.selectedNotes.ForEach(note => clipboardNotes.Add(NotePosCalc.ToCue(note, 0, false))); }; Action paste = () => { timeline.DeselectAllTargets(); timeline.PasteCues(clipboardNotes, Timeline.BeatTime()); }; if (Input.GetKeyDown(KeyCode.Delete)) { delete(); } bool dev = false; bool modifierHeld = dev ? Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift) : Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); if (modifierHeld) { if (Input.GetKeyDown(KeyCode.X)) { copy(); delete(); } if (Input.GetKeyDown(KeyCode.C)) { copy(); } if (Input.GetKeyDown(KeyCode.V)) { paste(); } } /** Note flipping **/ if (Input.GetKeyDown(KeyCode.F)) { var ctrlHeld = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); var shiftHeld = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); // flip horizontal if (ctrlHeld && !shiftHeld) { timeline.FlipTargetsHorizontal(timeline.selectedNotes); } // flip vertical else if (shiftHeld) { timeline.FlipTargetsVertical(timeline.selectedNotes); } // invert else { timeline.SwapTargets(timeline.selectedNotes); } } /** Click + Drag Handling **/ //TODOUNDO I think I fixed this? //TODO: it should deselect when resiszing the grid dragger, but not deselect when scrubbing through the timeline while grid dragging if (EditorInput.selectedTool == EditorTool.DragSelect) { if (Input.GetMouseButtonDown(0)) { if (iconUnderMouse) { var anySelectedIconUnderMouse = iconsUnderMouse.Where(icon => icon.isSelected).ToArray(); if (anySelectedIconUnderMouse.Length == 0) { return; } switch (iconUnderMouse.location) { case TargetIconLocation.Grid: StartDragGridTargetAction(iconUnderMouse); break; case TargetIconLocation.Timeline: StartDragTimelineTargetAction(iconUnderMouse); break; } } } if (Input.GetMouseButtonUp(0)) { if (isDraggingNotesOnGrid) { EndDragGridTargetAction(); } if (isDraggingNotesOnTimeline) { EndDragTimelineTargetAction(); } foreach (Target target in timeline.selectedNotes) { if (target.gridTargetIcon) { target.gridTargetPos = target.gridTargetIcon.transform.localPosition; } } } if (Input.GetMouseButton(0)) { //If we're not already dragging if (!isDraggingTimeline && !isDraggingGrid && !isDraggingNotesOnGrid && !isDraggingNotesOnTimeline && !iconUnderMouse ) { if (timeline.hover) { StartTimelineDrag(); } else { StartGridDrag(); } } else if (isDraggingTimeline) { float diff = Camera.main.ScreenToWorldPoint(Input.mousePosition).x - dragSelectTimeline.position.x; float timelineScaleMulti = Timeline.scale / 20f; dragSelectTimeline.localScale = new Vector3(diff * timelineScaleMulti, 1.1f * (Timeline.scale / 20f), 1); } else if (isDraggingGrid) { Vector3 diff = Camera.main.ScreenToWorldPoint(Input.mousePosition) - dragSelectGrid.transform.position; dragSelectGrid.transform.localScale = new Vector3(diff.x, diff.y * -1, 1f); } else if (iconUnderMouse && !isSelectionDown) { StartSelectionAction(); } else if (iconUnderMouse && timeline.selectedNotes.Count == 0 && hasMovedOutOfClickBounds) { iconUnderMouse.TrySelect(); if (iconUnderMouse.location == TargetIconLocation.Grid) { StartDragGridTargetAction(iconUnderMouse); } if (iconUnderMouse.location == TargetIconLocation.Timeline) { StartDragTimelineTargetAction(iconUnderMouse); } } } else { if (isDraggingTimeline) { EndTimelineDrag(); } else if (isDraggingGrid) { EndGridDrag(); } } if (Input.GetMouseButtonUp(0)) { EndSelectionAction(); if (!hasMovedOutOfClickBounds) { TryToggleSelection(); } } if (isDraggingNotesOnGrid) { // TODO: this should really be handled by intermediary semi-transparent objects rather than updating "real" state as we go ... var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); Vector3 newPos = NoteGridSnap.SnapToGrid(mousePos, EditorInput.selectedSnappingMode); foreach (TargetMoveIntent intent in gridTargetMoveIntents) { //var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); var offsetFromDragPoint = intent.target.gridTargetPos - startDragMovePos; //Vector3 newPos = NoteGridSnap.SnapToGrid(mousePos, EditorInput.selectedSnappingMode); var tempNewPos = newPos + offsetFromDragPoint; intent.target.gridTargetIcon.transform.localPosition = new Vector3(tempNewPos.x, tempNewPos.y, intent.target.gridTargetPos.z); if (intent.target.behavior == TargetBehavior.Hold) { var holdEnd = intent.target.gridTargetIcon.GetComponentInChildren <HoldTargetManager>().endMarker; if (holdEnd) { holdEnd.transform.localPosition = new Vector3(tempNewPos.x, tempNewPos.y, holdEnd.transform.localPosition.z); } } //target.gridTargetPos = target.gridTargetIcon.transform.localPosition; intent.intendedPosition = new Vector3(tempNewPos.x, tempNewPos.y, intent.target.gridTargetPos.z); } } if (isDraggingNotesOnTimeline) { foreach (TargetMoveIntent intent in timelineTargetMoveIntents) { var pos = intent.startingPosition; var gridPos = intent.target.gridTargetIcon.transform.localPosition; var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); var offsetFromDragPoint = pos - startDragMovePos; Vector3 newPos = SnapToBeat(mousePos); // TODO: Snap! newPos += offsetFromDragPoint; intent.target.timelineTargetIcon.transform.localPosition = new Vector3(newPos.x, pos.y, pos.z); intent.target.gridTargetIcon.transform.localPosition = new Vector3(gridPos.x, gridPos.y, newPos.x); intent.intendedPosition = new Vector3(newPos.x, pos.y, pos.z); } } } }
public void ExportAsCues() { //Pick folder //string prevDir = PlayerPrefs.GetString("recentDirCues", ""); string diff; switch (DifficultyManager.I.loadedIndex) { case 0: diff = "Expert"; break; case 1: diff = "Advanced"; break; case 2: diff = "Standard"; break; default: diff = "Easy"; break; } string fileName = Path.GetFileName(Timeline.audicaFile.filepath)?.Replace(".audica", ""); fileName = fileName + "_NRExport-" + diff + ".cues"; string path; if (!String.IsNullOrEmpty(NRSettings.config.cuesSavePath)) { path = Path.Combine(NRSettings.config.cuesSavePath, fileName); } else { path = StandaloneFileBrowser.SaveFilePanel("Find community_maps/maps folder in Audica folder", Path.Combine(Application.dataPath, @"../"), fileName, "cues"); if (String.IsNullOrEmpty(path)) { return; } NRSettings.config.cuesSavePath = Path.GetDirectoryName(path); NRSettings.SaveSettingsJson(); } //Ensure all chains are generated List <TargetData> nonGeneratedNotes = new List <TargetData>(); foreach (Target note in Timeline.instance.notes) { if (note.data.behavior == TargetBehavior.NR_Pathbuilder && note.data.pathBuilderData.createdNotes == false) { nonGeneratedNotes.Add(note.data); } } foreach (var data in nonGeneratedNotes) { ChainBuilder.GenerateChainNotes(data); } CueFile export = new CueFile(); export.cues = new List <Cue>(); export.NRCueData = new NRCueData(); foreach (Target target in Timeline.orderedNotes) { if (target.data.beatLength == 0) { target.data.beatLength = Constants.SixteenthNoteDuration; } if (target.data.behavior == TargetBehavior.Metronome) { continue; } var cue = NotePosCalc.ToCue(target, Timeline.offset); if (target.data.behavior == TargetBehavior.NR_Pathbuilder) { export.NRCueData.pathBuilderNoteCues.Add(cue); export.NRCueData.pathBuilderNoteData.Add(target.data.pathBuilderData); continue; } export.cues.Add(cue); } File.WriteAllText(path, JsonUtility.ToJson(export)); NotificationShower.Queue(new NRNotification("Saved cues!")); }
public Cue ToCue() => NotePosCalc.ToCue(this, Timeline.offset);