From 3008cb9d2ade770c88b9191ad0bd5ee93c170d73 Mon Sep 17 00:00:00 2001 From: Yoshman29 <81191621+YoshiCrafter29@users.noreply.github.com> Date: Fri, 7 Apr 2023 01:05:01 +0200 Subject: [PATCH] charter playtesting + copy paste --- source/funkin/editors/charter/Charter.hx | 316 ++++++++++++++++------- source/funkin/game/PlayState.hx | 7 + source/funkin/options/Options.hx | 2 + source/funkin/utils/CoolUtil.hx | 2 + 4 files changed, 233 insertions(+), 94 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 8b55c649..17191883 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -18,6 +18,7 @@ import openfl.net.FileReference; class Charter extends UIState { var __song:String; var __diff:String; + var __reload:Bool; var chart(get, null):ChartData; private function get_chart() @@ -39,6 +40,8 @@ class Charter extends UIState { public var topMenuSpr:UITopMenu; public var gridBackdrop:CharterBackdrop; + public var beatSeparator:FlxBackdrop; + public var sectionSeparator:FlxBackdrop; public var gridBackdropDummy:CharterBackdropDummy; public var conductorFollowerSpr:FlxSprite; @@ -68,10 +71,13 @@ class Charter extends UIState { public var undoList:Array = []; public var redoList:Array = []; - public function new(song:String, diff:String) { + public var clipboard:Array = []; + + public function new(song:String, diff:String, reload:Bool = true) { super(); __song = song; __diff = diff; + __reload = reload; } public override function create() { @@ -111,11 +117,13 @@ class Charter extends UIState { }, { label: "Copy", - keybind: [CONTROL, C] + keybind: [CONTROL, C], + onSelect: _edit_copy }, { label: "Paste", - keybind: [CONTROL, V] + keybind: [CONTROL, V], + onSelect: _edit_paste }, null, { @@ -130,36 +138,24 @@ class Charter extends UIState { childs: [ { label: "Playtest", - keybind: [ENTER] + keybind: [ENTER], + onSelect: _chart_playtest }, { label: "Playtest here", - keybind: [SHIFT, ENTER] + keybind: [SHIFT, ENTER], + onSelect: _chart_playtest_here }, null, { label: "Playtest as opponent", - keybind: [CONTROL, ENTER] + keybind: [CONTROL, ENTER], + onSelect: _chart_playtest_opponent }, { label: "Playtest as opponent here", - keybind: [CONTROL, SHIFT, ENTER] - }, - null, - { - label: "Zoom in", - keybind: [CONTROL, NUMPADPLUS], - onSelect: _chart_zoomin - }, - { - label: "Zoom out", - keybind: [CONTROL, NUMPADMINUS], - onSelect: _chart_zoomout - }, - { - label: "Reset zoom", - keybind: [CONTROL, NUMPADZERO], - onSelect: _chart_zoomreset + keybind: [CONTROL, SHIFT, ENTER], + onSelect: _chart_playtest_opponent_here }, null, { @@ -167,6 +163,37 @@ class Charter extends UIState { } ] }, + { + label: "View", + childs: [ + { + label: "Zoom in", + keybind: [CONTROL, NUMPADPLUS], + onSelect: _view_zoomin + }, + { + label: "Zoom out", + keybind: [CONTROL, NUMPADMINUS], + onSelect: _view_zoomout + }, + { + label: "Reset zoom", + keybind: [CONTROL, NUMPADZERO], + onSelect: _view_zoomreset + }, + null, + { + label: 'Show Sections Separator', + onSelect: _view_showsectionseparator, + icon: Options.charterShowSections ? 1 : 0 + }, + { + label: 'Show Beats Separator', + onSelect: _view_showbeatseparator, + icon: Options.charterShowBeats ? 1 : 0 + } + ] + }, { label: "Playback", childs: [ @@ -200,7 +227,8 @@ class Charter extends UIState { null, { label: "Metronome", - onSelect: _playback_metronome + onSelect: _playback_metronome, + icon: Options.charterMetronomeEnabled ? 1 : 0 }, { label: "Visual metronome" @@ -227,10 +255,25 @@ class Charter extends UIState { uiCamera.bgColor = 0; FlxG.cameras.add(uiCamera); - + gridBackdrop = new CharterBackdrop(); add(gridBackdropDummy = new CharterBackdropDummy(gridBackdrop)); + sectionSeparator = new FlxBackdrop(null, Y, 0, 0); + sectionSeparator.x = -20; + sectionSeparator.y = -2; + sectionSeparator.visible = Options.charterShowSections; + beatSeparator = new FlxBackdrop(null, Y, 0, 0); + beatSeparator.x = -10; + beatSeparator.y = -1; + sectionSeparator.visible = Options.charterShowBeats; + for(sep in [sectionSeparator, beatSeparator]) { + sep.makeGraphic(1, 1, -1); + sep.alpha = 0.5; + sep.scrollFactor.set(1, 1); + sep.cameras = [charterCamera]; + } + selectionBox = new UISliceSprite(0, 0, 2, 2, 'editors/ui/selection'); selectionBox.visible = false; @@ -250,6 +293,8 @@ class Charter extends UIState { // adds grid and notes so that they're ALWAYS behind the UI add(gridBackdrop); + add(sectionSeparator); + add(beatSeparator); add(notesGroup); add(conductorFollowerSpr); add(selectionBox); @@ -257,18 +302,20 @@ class Charter extends UIState { add(uiGroup); // add the top menu last OUT of the ui group so that it stays on top add(topMenuSpr); - + loadSong(); } public function loadSong() { - CoolUtil.loadSong(__song, __diff, false, false); + if (__reload) + CoolUtil.loadSong(__song, __diff, false, false); Conductor.setupSong(PlayState.SONG); - FlxG.sound.music = FlxG.sound.load(Paths.inst(__song, __diff)); + FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff))); vocals = FlxG.sound.load(Paths.voices(__song, __diff)); - + vocals.group = FlxG.sound.defaultMusicGroup; + for(strID=>strL in PlayState.SONG.strumLines) { for(note in strL.notes) { var n = new CharterNote(); @@ -410,7 +457,101 @@ class Charter extends UIState { while(undoList.length > Options.maxUndos) undoList.pop(); } - + #end + + public inline function sortNotes() + notesGroup.sort((i, c1, c2) -> FlxSort.byValues(i, c1.step, c2.step), FlxSort.ASCENDING); + #end + + var __crochet:Float; + public override function update(elapsed:Float) { + updateNoteLogic(elapsed); + + super.update(elapsed); + + if (gridBackdrop.strumlinesAmount != (gridBackdrop.strumlinesAmount = strumLines.length)) { + conductorFollowerSpr.scale.set(gridBackdrop.strumlinesAmount * 4 * 40, 4); + conductorFollowerSpr.updateHitbox(); + + sectionSeparator.scale.set((gridBackdrop.strumlinesAmount * 4 * 40) + 20, 4); + sectionSeparator.updateHitbox(); + + beatSeparator.scale.set((gridBackdrop.strumlinesAmount * 4 * 40) + 10, 2); + beatSeparator.updateHitbox(); + } + sectionSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; + beatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; + + // TODO: canTypeText in case an ui input element is focused + if (true) { + __crochet = ((60 / Conductor.bpm) * 1000); + + UIUtil.processShortcuts(topMenu); + + if (FlxG.keys.pressed.CONTROL) { + if (FlxG.mouse.wheel != 0) { + zoom += 0.25 * FlxG.mouse.wheel; + __camZoom = Math.pow(2, zoom); + } + } else { + if (!FlxG.sound.music.playing) { + Conductor.songPosition -= __crochet * FlxG.mouse.wheel; + } + } + } + + Conductor.songPosition = FlxMath.bound(Conductor.songPosition, 0, FlxG.sound.music.length); + + if (FlxG.sound.music.playing) { + conductorFollowerSpr.y = curStepFloat * 40; + } else { + conductorFollowerSpr.y = lerp(conductorFollowerSpr.y, curStepFloat * 40, 1/3); + } + charterCamera.scroll.set(conductorFollowerSpr.x + ((conductorFollowerSpr.scale.x - FlxG.width) / 2), conductorFollowerSpr.y - (FlxG.height * 0.5)); + if (charterCamera.zoom != (charterCamera.zoom = lerp(charterCamera.zoom, __camZoom, 0.125))) { + + } + } + + var zoom:Float = 0; + var __camZoom:Float = 1; + + // TOP MENU OPTIONS + #if REGION + function _file_exit(_) { + FlxG.switchState(new CharterSelection()); + } + function _edit_copy(_) { + var minStep:Float = selection[0].step; + for(s in selection) + if (s.step < minStep) + minStep = s.step; + + clipboard = [for(s in selection) CNote(s.step - minStep, s.id, s.susLength, s.type)]; + } + function _edit_paste(_) { + if (clipboard.length <= 0) return; + + var minStep = curStep; + var notes:Array = []; + for(c in clipboard) { + switch(c) { + case CNote(step, id, sLen, type): + var note = new CharterNote(); + note.updatePos(minStep + step, id, sLen, type); + notes.push(note); + notesGroup.add(note); + } + } + selection = notes; + addToUndo(CCreateNotes(notes.copy())); + + } + function _edit_delete(_) { + if (selection == null) return; + selection = deleteNotes(selection); + } + function _edit_undo(_) { selection = []; var v = undoList.shift(); @@ -473,6 +614,15 @@ class Charter extends UIState { undoList.insert(0, v); } + inline function _chart_playtest(_) + playtestChart(0, false); + inline function _chart_playtest_here(_) + playtestChart(Conductor.songPosition, false); + inline function _chart_playtest_opponent(_) + playtestChart(0, true); + inline function _chart_playtest_opponent_here(_) + playtestChart(Conductor.songPosition, true); + function _playback_metronome(t) { t.icon = (Options.charterMetronomeEnabled = !Options.charterMetronomeEnabled) ? 1 : 0; } @@ -484,66 +634,6 @@ class Charter extends UIState { vocals.volume = vocals.volume > 0 ? 0 : 1; t.icon = 1 - Std.int(Math.ceil(vocals.volume)); } - #end - - public inline function sortNotes() - notesGroup.sort((i, c1, c2) -> FlxSort.byValues(i, c1.step, c2.step), FlxSort.ASCENDING); - #end - - var __crochet:Float; - public override function update(elapsed:Float) { - updateNoteLogic(elapsed); - - super.update(elapsed); - - if (gridBackdrop.strumlinesAmount != (gridBackdrop.strumlinesAmount = strumLines.length)) { - conductorFollowerSpr.scale.set(gridBackdrop.strumlinesAmount * 4 * 40, 4); - conductorFollowerSpr.updateHitbox(); - } - - // TODO: canTypeText in case an ui input element is focused - if (true) { - __crochet = ((60 / Conductor.bpm) * 1000); - - UIUtil.processShortcuts(topMenu); - - if (FlxG.keys.pressed.CONTROL) { - if (FlxG.mouse.wheel != 0) { - zoom += 0.25 * FlxG.mouse.wheel; - __camZoom = Math.pow(2, zoom); - } - } else { - if (!FlxG.sound.music.playing) { - Conductor.songPosition -= __crochet * FlxG.mouse.wheel; - } - } - } - - Conductor.songPosition = FlxMath.bound(Conductor.songPosition, 0, FlxG.sound.music.length); - - if (FlxG.sound.music.playing) { - conductorFollowerSpr.y = curStepFloat * 40; - } else { - conductorFollowerSpr.y = lerp(conductorFollowerSpr.y, curStepFloat * 40, 1/3); - } - charterCamera.scroll.set(conductorFollowerSpr.x + ((conductorFollowerSpr.scale.x - FlxG.width) / 2), conductorFollowerSpr.y - (FlxG.height * 0.5)); - if (charterCamera.zoom != (charterCamera.zoom = lerp(charterCamera.zoom, __camZoom, 0.125))) { - - } - } - - var zoom:Float = 0; - var __camZoom:Float = 1; - - // TOP MENU OPTIONS - #if REGION - function _file_exit(_) { - FlxG.switchState(new CharterSelection()); - } - function _edit_delete(_) { - if (selection == null) return; - selection = deleteNotes(selection); - } function _playback_back(_) { if (FlxG.sound.music.playing) return; Conductor.songPosition -= Conductor.beatsPerMesure * __crochet; @@ -560,20 +650,54 @@ class Charter extends UIState { if (FlxG.sound.music.playing) return; Conductor.songPosition = FlxG.sound.music.length; } - function _chart_zoomin(_) { + function _view_zoomin(_) { zoom += 0.25; __camZoom = Math.pow(2, zoom); } - function _chart_zoomout(_) { + function _view_zoomout(_) { zoom -= 0.25; __camZoom = Math.pow(2, zoom); } - function _chart_zoomreset(_) { + function _view_zoomreset(_) { zoom = 0; __camZoom = Math.pow(2, zoom); } + function _view_showsectionseparator(t) { + t.icon = (Options.charterShowSections = !Options.charterShowSections) ? 1 : 0; + sectionSeparator.visible = Options.charterShowSections; + } + function _view_showbeatseparator(t) { + t.icon = (Options.charterShowBeats = !Options.charterShowBeats) ? 1 : 0; + beatSeparator.visible = Options.charterShowBeats; + } #end - + + public function playtestChart(time:Float = 0, opponentMode = false) { + buildChart(); + PlayState.opponentMode = opponentMode; + PlayState.chartingMode = true; + FlxG.switchState(new PlayState()); + } + + public function buildChart() { + PlayState.SONG.strumLines = []; + for(s in strumLines) { + s.strumLine.notes = []; + PlayState.SONG.strumLines.push(s.strumLine); + } + for(n in notesGroup.members) { + var strLineID = Std.int(n.id / 4); + if (PlayState.SONG.strumLines[strLineID] != null) { + PlayState.SONG.strumLines[strLineID].notes.push({ + type: n.type, + time: Conductor.getTimeForStep(n.step), + sLen: n.susLength, + id: n.id % 4 + }); + } + } + } + public inline function hitsoundsEnabled(id:Int) return strumLines[Std.int(id / 4)] != null && strumLines[Std.int(id / 4)].hitsounds; } @@ -584,6 +708,10 @@ enum CharterChange { CDeleteNotes(notes:Array); } +enum CharterCopyboardObject { + CNote(step:Float, id:Int, susLength:Float, type:Int); +} + typedef CharterStrumline = { var strumLine:ChartStrumLine; var hitsounds:Bool; diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 9ac25ee6..b8bbd01d 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -64,6 +64,10 @@ class PlayState extends MusicBeatState * Whenever the week is coming from the mods folder or not. */ public static var fromMods:Bool = false; + /** + * Whenever Charting Mode has been enabled for this song. + */ + public static var chartingMode:Bool = false; /** * Whenever the song has been started with opponent mode on. */ @@ -1048,6 +1052,9 @@ class PlayState extends MusicBeatState pauseGame(); if (canAccessDebugMenus) { + if (chartingMode && FlxG.keys.justPressed.SEVEN) { + FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, false)); + } if (FlxG.keys.justPressed.F5) { Logs.trace('Reloading scripts...', WARNING, YELLOW); scripts.reload(); diff --git a/source/funkin/options/Options.hx b/source/funkin/options/Options.hx index 4448448e..c97b25d5 100644 --- a/source/funkin/options/Options.hx +++ b/source/funkin/options/Options.hx @@ -51,6 +51,8 @@ class Options // CHARTER public static var charterMetronomeEnabled:Bool = false; + public static var charterShowSections:Bool = true; + public static var charterShowBeats:Bool = true; /** * PLAYER 1 CONTROLS diff --git a/source/funkin/utils/CoolUtil.hx b/source/funkin/utils/CoolUtil.hx index 688221c9..df22ad82 100644 --- a/source/funkin/utils/CoolUtil.hx +++ b/source/funkin/utils/CoolUtil.hx @@ -419,6 +419,7 @@ class CoolUtil PlayState.storyPlaylist = [for(e in weekData.songs) e.name]; PlayState.isStoryMode = true; PlayState.campaignScore = 0; + PlayState.chartingMode = false; PlayState.opponentMode = PlayState.coopMode = false; __loadSong(PlayState.storyPlaylist[0], difficulty); } @@ -434,6 +435,7 @@ class CoolUtil PlayState.campaignScore = 0; PlayState.isStoryMode = false; PlayState.opponentMode = opponentMode; + PlayState.chartingMode = false; PlayState.coopMode = coopMode; __loadSong(name, difficulty); }