diff --git a/TODO.md b/TODO.md index 853efbfa..9ee95f22 100644 --- a/TODO.md +++ b/TODO.md @@ -9,13 +9,13 @@ - [x] Selection box & dragging - [x] Scroll bar at the right + Song info - [x] Fix the strumlines bar when zooming out - - [ ] Step based zooming - - [ ] Algorithm to make note placements faster & sorted out + - [x] Algorithm to make note placements faster & sorted out - [x] Play here working - [ ] Events (including Camera Movement) - [ ] Custom Notes - [ ] Metadata Editing - - [ ] Waveforms (maybe in v1.1.0, dont wanna slow shit down) + - [ ] Cap zoom in & out + - [ ] Step based zooming - [ ] Multiple state scripts & Multiple global scripts - [ ] Make update.bat use libs.xml instead of hmm.json - [ ] New Switch Mod menu @@ -27,7 +27,7 @@ - [ ] Fix bugs ## `v1.1.0` - +- [ ] Charter Waveforms (maybe in v1.1.0, dont wanna slow shit down) - [ ] Custom classes - [ ] Full 3D support via stages files - [ ] Multithread sprites loading (for faster load times) ? diff --git a/assets/images/editors/ui/warning-popup.png b/assets/images/editors/ui/warning-popup.png index 26678e77..f0f00305 100644 Binary files a/assets/images/editors/ui/warning-popup.png and b/assets/images/editors/ui/warning-popup.png differ diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index d420a67b..80759bf3 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -618,7 +618,6 @@ class Charter extends UIState { openContextMenu(topMenu[1].childs); } - if (gridActionType == NONE && mousePos.x < 0) { addEventSpr.incorporeal = false; addEventSpr.sprAlpha = lerp(addEventSpr.sprAlpha, 0.75, 0.25); diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index 0f21248d..e7f611d7 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -1,15 +1,60 @@ package funkin.editors.charter; +import funkin.backend.chart.ChartData.ChartEventType; import funkin.game.HealthIcon; import funkin.backend.chart.ChartData.ChartEvent; class CharterEvent extends UISliceSprite { - public static function getEventInfo(id:Int) { + public static function getEventInfo(id:ChartEventType) { return switch(id) { - case -1: + case CUSTOM: // hscript { - name: "HScript Parameters" + name: "HScript Call", + params: [ + { + name: "Function name", + type: TString + }, + { + name: "Function parameters (string)", + type: TArrayOfString + } + ] + } + case CAM_MOVEMENT: + { + name: "Camera Movement", + params: [ + { + name: "Camera Target", + type: TStrumLine + } + ] + } + case BPM_CHANGE: + { + name: "BPM Change", + params: [ + { + name: "Target BPM", + type: TFloat(1) + } + ] + } + case ALT_ANIM_TOGGLE: + { + name: "Alt Animation Toggle", + params: [ + { + name: "Strumline", + type: TStrumLine + }, + { + name: "Enable", + type: TBool + } + ] } default: { @@ -29,7 +74,7 @@ class CharterEvent extends UISliceSprite { super(-100, (step * 40) - 17, 100, 34, 'editors/charter/event-spr'); this.step = step; this.events = events.getDefault([]); - + cursor = BUTTON; } @@ -40,6 +85,29 @@ class CharterEvent extends UISliceSprite { } } + private static function generateDefaultIcon(type:Int) { + var spr = new FlxSprite().loadGraphic(Paths.image('editors/charter/event-icons'), true, 16, 16); + spr.frame = spr.frames.frames[type+1]; + return spr; + } + + public static function generateEventIcon(event:ChartEvent) { + return switch(event.type) { + default: + generateDefaultIcon(event.type); + case CAM_MOVEMENT: + // custom icon for camera movement + var state = cast(FlxG.state, Charter); + if (event.params[0] != null && event.params[0] >= 0 && event.params[0] < state.strumLines.length) { + // camera movement, use health icon + var healthIcon = new HealthIcon('${state.strumLines.members[event.params[0]].strumLine.characters[0]}'); + healthIcon.setUnstretchedGraphicSize(32, 32, false); + healthIcon; + } else + generateDefaultIcon(event.type); + } + } + public function refreshEventIcons() { while(icons.length > 0) { var i = icons.shift(); @@ -47,44 +115,32 @@ class CharterEvent extends UISliceSprite { i.destroy(); } - var f = function(type) { - var spr = new FlxSprite().loadGraphic(Paths.image('editors/charter/event-icons'), true, 16, 16); - spr.frame = spr.frames.frames[type+1]; + for(event in events) { + var spr = generateEventIcon(event); icons.push(spr); members.push(spr); - }; - - for(event in events) { - switch(event.type) { - default: - f(event.type); - case CAM_MOVEMENT: - // custom icon for camera movement - var state = cast(FlxG.state, Charter); - if (event.params[0] != null && event.params[0] >= 0 && event.params[0] < state.strumLines.length) { - // camera movement, use health icon - var healthIcon = new HealthIcon('${state.strumLines.members[event.params[0]].strumLine.characters[0]}'); - healthIcon.setUnstretchedGraphicSize(32, 32, false); - icons.push(healthIcon); - members.push(healthIcon); - } else - f(event.type); - } } + x = -(bWidth = 37 + (icons.length * 22)); } } typedef EventInfo = { var name:String; - var params:Array; + var params:Array; var paramValues:Array; } +typedef EventParamInfo = { + var name:String; + var type:EventParamType; +} + enum EventParamType { TBool; TInt(?min:Int, ?max:Int); TFloat(?min:Int, ?max:Int); TString; TArrayOfString; + TStrumLine; } \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterEventAdd.hx b/source/funkin/editors/charter/CharterEventAdd.hx index 888fe739..545e749a 100644 --- a/source/funkin/editors/charter/CharterEventAdd.hx +++ b/source/funkin/editors/charter/CharterEventAdd.hx @@ -3,6 +3,9 @@ package funkin.editors.charter; class CharterEventAdd extends UISliceSprite { var text:UIText; public var sprAlpha:Float = 0; + public var step:Float = 0; + + public var curCharterEvent:CharterEvent = null; public function new() { super(0, 0, 100, 34, 'editors/charter/event-spr-add'); @@ -14,6 +17,20 @@ class CharterEventAdd extends UISliceSprite { } + public override function onHovered() { + super.onHovered(); + if (FlxG.mouse.justReleased) { + var state = cast(FlxG.state, Charter); + if (curCharterEvent != null) { + FlxG.state.openSubState(new CharterEventScreen(curCharterEvent)); + } else { + var event:CharterEvent = new CharterEvent(step, []); + state.eventsGroup.add(event); + FlxG.state.openSubState(new CharterEventScreen(event)); + } + } + } + public override function update(elapsed:Float) { super.update(elapsed); @@ -23,13 +40,16 @@ class CharterEventAdd extends UISliceSprite { } public function updatePos(y:Float) { - this.y = (FlxG.keys.pressed.SHIFT ? y : 40 * (Math.floor((y + 20) / 40))) - (bHeight / 2); + curCharterEvent = null; + step = FlxG.keys.pressed.SHIFT ? (y / 40) : Math.floor((y + 20) / 40); + this.y = (step * 40) - (bHeight / 2); text.text = "Add event"; framesOffset = 0; x = -(bWidth = 37 + Math.ceil(text.width)); } public function updateEdit(event:CharterEvent) { + curCharterEvent = event; this.y = event.y; text.text = "Edit"; framesOffset = 9; diff --git a/source/funkin/editors/charter/CharterEventScreen.hx b/source/funkin/editors/charter/CharterEventScreen.hx new file mode 100644 index 00000000..54771f6e --- /dev/null +++ b/source/funkin/editors/charter/CharterEventScreen.hx @@ -0,0 +1,72 @@ +package funkin.editors.charter; + +import flixel.group.FlxGroup; + +class CharterEventScreen extends UISubstateWindow { + public var cam:FlxCamera; + public var chartEvent:CharterEvent; + + public var iconsPanel:FlxGroup; + + public var paramsPanel:FlxGroup; + public var paramsFields:Array = []; + + public function new(chartEvent:CharterEvent) { + super(); + this.chartEvent = chartEvent; + } + + public override function create() { + winTitle = "Event group properties"; + winWidth = 960; + + super.create(); + + FlxG.sound.music.pause(); // prevent the song from continuing + + iconsPanel = new FlxGroup(); + + for(k=>e in chartEvent.events) { + var butt = new UIButton(windowSpr.x + 1, windowSpr.y + 31 + (k*30), "", function() { + changeTab(k); + }); + butt.bWidth = butt.bHeight = 30; + iconsPanel.add(butt); + + var icon = CharterEvent.generateEventIcon(e); + icon.setPosition(butt.x + ((butt.bWidth - icon.width) / 2), butt.y + ((butt.bHeight - icon.height) / 2)); + iconsPanel.add(icon); + } + + add(iconsPanel); + + paramsPanel = new FlxGroup(); + add(paramsPanel); + } + + public var curEvent:Int = -1; + + public function changeTab(id:Int) { + // TODO + saveCurTab(); + } + + public function saveCurTab() { + if (curEvent < 0) return; + + chartEvent.events[curEvent].params = [for(p in paramsFields) { + if (p is UITextBox) + cast(p, UITextBox).label.text; + else + null; + } + ]; + } + + public override function update(elapsed:Float) { + super.update(elapsed); + + if (controls.BACK) + close(); + } +} \ No newline at end of file diff --git a/source/funkin/editors/ui/UISubstateWindow.hx b/source/funkin/editors/ui/UISubstateWindow.hx new file mode 100644 index 00000000..7862db3b --- /dev/null +++ b/source/funkin/editors/ui/UISubstateWindow.hx @@ -0,0 +1,62 @@ +package funkin.editors.ui; + +import flixel.tweens.FlxTween; +import funkin.backend.shaders.CustomShader; + +// TODO: make UIWarningSubstate extend this +class UISubstateWindow extends MusicBeatSubstate { + var camShaders:Array = []; + var blurShader:CustomShader = new CustomShader("engine/editorBlur"); + + var titleSpr:UIText; + var messageSpr:UIText; + + var subCam:FlxCamera; + + var windowSpr:UISliceSprite; + + public override function onSubstateOpen() { + super.onSubstateOpen(); + parent.persistentUpdate = false; + parent.persistentDraw = true; + } + + var winWidth:Int = 560; + var winHeight:Int = 570; + var winTitle:String = ""; + + public override function create() { + super.create(); + + for(c in FlxG.cameras.list) { + camShaders.push(c); + c.addShader(blurShader); + } + + camera = subCam = new FlxCamera(); + subCam.bgColor = 0; + subCam.alpha = 0; + subCam.zoom = 0.1; + FlxG.cameras.add(subCam, false); + + windowSpr = new UISliceSprite(0, 0, winWidth, winHeight, "editors/ui/warning-popup"); + windowSpr.x = (FlxG.width - windowSpr.bWidth) / 2; + windowSpr.y = (FlxG.height - windowSpr.bHeight) / 2; + add(windowSpr); + + add(titleSpr = new UIText(windowSpr.x + 25, windowSpr.y, windowSpr.bWidth - 50, winTitle, 15, -1)); + titleSpr.y = windowSpr.y + ((30 - titleSpr.height) / 2); + + FlxTween.tween(camera, {alpha: 1}, 0.25, {ease: FlxEase.cubeOut}); + FlxTween.tween(camera, {zoom: 1}, 0.66, {ease: FlxEase.elasticOut}); + } + + public override function destroy() { + super.destroy(); + for(e in camShaders) + e.removeShader(blurShader); + + FlxTween.cancelTweensOf(subCam); + FlxG.cameras.remove(subCam); + } +} \ No newline at end of file diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx index 1ad656fb..88948721 100644 --- a/source/funkin/editors/ui/UIWarningSubstate.hx +++ b/source/funkin/editors/ui/UIWarningSubstate.hx @@ -40,10 +40,9 @@ class UIWarningSubstate extends MusicBeatSubstate { spr.y = (FlxG.height - spr.bHeight) / 2; add(spr); - add(titleSpr = new UIText(spr.x + 25, spr.y, spr.bWidth - 50, title, 15, -1)); titleSpr.y = spr.y + ((30 - titleSpr.height) / 2); - + add(messageSpr = new UIText(spr.x + 10, spr.y + 40, spr.bWidth - 20, message, 15, -1)); var xPos = (FlxG.width - (30 + (170 * buttons.length))) / 2; diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index fb023e12..e0f26b6e 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -713,6 +713,8 @@ class PlayState extends MusicBeatState updateDiscordPresence(); + __updateNote_event = EventManager.get(NoteUpdateEvent); + scripts.call("postCreate"); } @@ -1325,9 +1327,6 @@ class PlayState extends MusicBeatState var __justReleased:Array = []; private function keyShit():Void { - if (generatedMusic) { - __updateNote_event = EventManager.get(NoteUpdateEvent); - } for(id=>p in strumLines) { p.updateNotes();