package funkin.ui.debug.charting.commands; import funkin.data.song.SongData.SongNoteData; import funkin.data.song.SongData.SongEventData; import funkin.data.song.SongDataUtils; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; /** * Command that copies a given set of notes and song events to the clipboard, * without deleting them from the chart editor. */ @:nullSafety @:access(funkin.ui.debug.charting.ChartEditorState) class SetAudioOffsetCommand implements ChartEditorCommand { var type:AudioOffsetType; var oldOffset:Float = 0; var newOffset:Float; var refreshOffsetsToolbox:Bool; public function new(type:AudioOffsetType, newOffset:Float, refreshOffsetsToolbox:Bool = true) { this.type = type; this.newOffset = newOffset; this.refreshOffsetsToolbox = refreshOffsetsToolbox; } public function execute(state:ChartEditorState):Void { switch (type) { case INSTRUMENTAL: oldOffset = state.currentInstrumentalOffset; state.currentInstrumentalOffset = newOffset; // Update rendering. Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; state.songLengthInMs = (state.audioInstTrack?.length ?? 1000.0) + Conductor.instance.instrumentalOffset; case PLAYER: oldOffset = state.currentVocalOffsetPlayer; state.currentVocalOffsetPlayer = newOffset; // Update rendering. state.audioVocalTrackGroup.playerVoicesOffset = state.currentVocalOffsetPlayer; case OPPONENT: oldOffset = state.currentVocalOffsetOpponent; state.currentVocalOffsetOpponent = newOffset; // Update rendering. state.audioVocalTrackGroup.opponentVoicesOffset = state.currentVocalOffsetOpponent; } // Update the offsets toolbox. if (refreshOffsetsToolbox) { state.refreshToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_OFFSETS_LAYOUT); state.refreshToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_FREEPLAY_LAYOUT); } } public function undo(state:ChartEditorState):Void { switch (type) { case INSTRUMENTAL: state.currentInstrumentalOffset = oldOffset; // Update rendering. Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; state.songLengthInMs = (state.audioInstTrack?.length ?? 1000.0) + Conductor.instance.instrumentalOffset; case PLAYER: state.currentVocalOffsetPlayer = oldOffset; // Update rendering. state.audioVocalTrackGroup.playerVoicesOffset = state.currentVocalOffsetPlayer; case OPPONENT: state.currentVocalOffsetOpponent = oldOffset; // Update rendering. state.audioVocalTrackGroup.opponentVoicesOffset = state.currentVocalOffsetOpponent; } // Update the offsets toolbox. state.refreshToolbox(ChartEditorState.CHART_EDITOR_TOOLBOX_OFFSETS_LAYOUT); } public function shouldAddToHistory(state:ChartEditorState):Bool { // This command is undoable. Add to the history if we actually performed an action. return (newOffset != oldOffset); } public function toString():String { switch (type) { case INSTRUMENTAL: return 'Set Inst. Audio Offset to $newOffset'; case PLAYER: return 'Set Player Audio Offset to $newOffset'; case OPPONENT: return 'Set Opponent Audio Offset to $newOffset'; } } } enum AudioOffsetType { INSTRUMENTAL; PLAYER; OPPONENT; }