diff --git a/assets/images/editors/charter/add-button.png b/assets/images/editors/charter/add-button.png new file mode 100644 index 00000000..ff942a42 Binary files /dev/null and b/assets/images/editors/charter/add-button.png differ diff --git a/assets/shaders/engine/editorBlur.frag b/assets/shaders/engine/editorBlur.frag index 958c9f54..de6ff524 100644 --- a/assets/shaders/engine/editorBlur.frag +++ b/assets/shaders/engine/editorBlur.frag @@ -9,10 +9,12 @@ vec4 getColor(vec2 pos) { else if (pos.x > 1.0 - (1.0 / openfl_TextureSize.x)) pos.x = 1.0 - (1.0 / openfl_TextureSize.x); if (pos.y < 0) pos.y = 0; else if (pos.y > 1.0 - (1.0 / openfl_TextureSize.y)) pos.y = 1.0 - (1.0 / openfl_TextureSize.y); - return textureCam(bitmap, pos); + // return textureCam(bitmap, pos); + return flixel_texture2D(bitmap, pos); } void main() { - vec2 camPos = getCamPos(openfl_TextureCoordv); + // vec2 camPos = getCamPos(openfl_TextureCoordv); + vec2 camPos = openfl_TextureCoordv; if (camPos.x < 0 || camPos.x > 1 || camPos.y < 0 || camPos.y > 1) return; diff --git a/source/funkin/backend/chart/ChartData.hx b/source/funkin/backend/chart/ChartData.hx index 8cda4c35..3dd309e7 100644 --- a/source/funkin/backend/chart/ChartData.hx +++ b/source/funkin/backend/chart/ChartData.hx @@ -100,4 +100,10 @@ abstract ChartEventType(Int) from Int to Int { * - Whenever its going to be toggled or not (Bool) */ var ALT_ANIM_TOGGLE = 3; + + /** + * Returns all usable event types. + */ + public static inline function getChartEventTypes():Array + return [CUSTOM, CAM_MOVEMENT, BPM_CHANGE, ALT_ANIM_TOGGLE]; } \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index d35224d6..0d62361d 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -1,11 +1,12 @@ package funkin.editors.charter; +import funkin.backend.system.Conductor; 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:ChartEventType) { + public static function getEventInfo(id:ChartEventType):EventDefineInfo { return switch(id) { case CUSTOM: // hscript @@ -14,11 +15,13 @@ class CharterEvent extends UISliceSprite { params: [ { name: "Function name", - type: TString + type: TString, + defValue: "myFunc" }, { name: "Function parameters (string)", - type: TArrayOfString + type: TArrayOfString, + defValue: [] } ] } @@ -28,7 +31,8 @@ class CharterEvent extends UISliceSprite { params: [ { name: "Camera Target", - type: TStrumLine + type: TStrumLine, + defValue: 0 } ] } @@ -38,7 +42,8 @@ class CharterEvent extends UISliceSprite { params: [ { name: "Target BPM", - type: TFloat(1) + type: TFloat(1), + defValue: Conductor.bpm } ] } @@ -48,11 +53,13 @@ class CharterEvent extends UISliceSprite { params: [ { name: "Strumline", - type: TStrumLine + type: TStrumLine, + defValue: 0 }, { name: "Enable", - type: TBool + type: TBool, + defValue: true } ] } @@ -108,6 +115,12 @@ class CharterEvent extends UISliceSprite { } } + public override function onHovered() { + super.onHovered(); + if (FlxG.mouse.justReleased) + FlxG.state.openSubState(new CharterEventScreen(this)); + } + public function refreshEventIcons() { while(icons.length > 0) { var i = icons.shift(); @@ -125,15 +138,19 @@ class CharterEvent extends UISliceSprite { } } -typedef EventInfo = { +typedef EventDefineInfo = { var name:String; var params:Array; +} +typedef EventInfo = { + > EventDefineInfo, var paramValues:Array; } typedef EventParamInfo = { var name:String; var type:EventParamType; + var defValue:Dynamic; } enum EventParamType { diff --git a/source/funkin/editors/charter/CharterEventScreen.hx b/source/funkin/editors/charter/CharterEventScreen.hx index 9738c43b..b81ee135 100644 --- a/source/funkin/editors/charter/CharterEventScreen.hx +++ b/source/funkin/editors/charter/CharterEventScreen.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import funkin.backend.system.Conductor; import flixel.group.FlxGroup; class CharterEventScreen extends UISubstateWindow { @@ -12,6 +13,10 @@ class CharterEventScreen extends UISubstateWindow { public var paramsPanel:FlxGroup; public var paramsFields:Array = []; + + public var addButton:UIButton; + public var saveButton:UIButton; + public var deleteButton:UIButton; public function new(chartEvent:CharterEvent) { super(); @@ -34,9 +39,50 @@ class CharterEventScreen extends UISubstateWindow { iconsPanel = new FlxGroup(); add(iconsPanel); + addButton = new UIButton(windowSpr.x + 1, windowSpr.y + 31, "", function() { + openSubState(new CharterEventTypeSelection(function(eventType) { + chartEvent.events.push({ + time: Conductor.getTimeForStep(chartEvent.step), + params: [], + type: eventType + }); + changeTab(chartEvent.events.length-1); + })); + }); + addButton.bWidth = addButton.bHeight = 30; + add(addButton); + + var addButtonIcon = new FlxSprite(addButton.x, addButton.y, Paths.image('editors/charter/add-button')); + addButtonIcon.x += (30 - addButtonIcon.width) / 2; + addButtonIcon.y += (30 - addButtonIcon.height) / 2; + add(addButtonIcon); + paramsPanel = new FlxGroup(); add(paramsPanel); + saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 10, windowSpr.y + windowSpr.bHeight - 10, "Save & Close", function() { + saveCurTab(); + chartEvent.refreshEventIcons(); + + if (chartEvent.events.length <= 0) { + var state = cast(FlxG.state, Charter); + state.eventsGroup.remove(chartEvent, true); + } + close(); + }); + saveButton.x -= saveButton.bWidth; + saveButton.y -= saveButton.bHeight; + add(saveButton); + + deleteButton = new UIButton(saveButton.x - 10, saveButton.y, "Delete", function() { + if (curEvent >= 0) { + chartEvent.events.splice(curEvent, 1); + changeTab(curEvent, false); + } + }); + deleteButton.x -= deleteButton.bWidth; + add(deleteButton); + eventName = new UIText(windowSpr.x + 40, windowSpr.y + 41, 0, "", 24); add(eventName); @@ -45,8 +91,9 @@ class CharterEventScreen extends UISubstateWindow { public var curEvent:Int = -1; - public function changeTab(id:Int) { - saveCurTab(); + public function changeTab(id:Int, save:Bool = true) { + if (save) + saveCurTab(); // destroy old elements paramsFields = []; @@ -63,39 +110,40 @@ class CharterEventScreen extends UISubstateWindow { // add new elements var y:Float = eventName.y + eventName.height + 10; for(k=>param in data.params) { - function addLabel() { + function addLabel() { var label:UIText = new UIText(eventName.x, y, 0, param.name); y += label.height + 4; paramsPanel.add(label); }; + var value:Dynamic = CoolUtil.getDefault(curEvent.params[k], param.defValue); switch(param.type) { case TString: addLabel(); - var textBox:UITextBox = new UITextBox(eventName.x, y, cast curEvent.params[k]); + var textBox:UITextBox = new UITextBox(eventName.x, y, cast value); y += textBox.height + 10; paramsPanel.add(textBox); paramsFields.push(textBox); case TBool: - var checkbox = new UICheckbox(eventName.x, y, param.name, cast curEvent.params[k]); + var checkbox = new UICheckbox(eventName.x, y, param.name, cast value); y += checkbox.height + 10; paramsPanel.add(checkbox); paramsFields.push(checkbox); case TInt(min, max, step): addLabel(); - var numericStepper = new UINumericStepper(eventName.x, y, cast curEvent.params[k], step.getDefault(1), 0, min, max); + var numericStepper = new UINumericStepper(eventName.x, y, cast value, step.getDefault(1), 0, min, max); y += numericStepper.height + 10; paramsPanel.add(numericStepper); paramsFields.push(numericStepper); case TFloat(min, max, step, precision): addLabel(); - var numericStepper = new UINumericStepper(eventName.x, y, cast curEvent.params[k], step.getDefault(1), precision, min, max); + var numericStepper = new UINumericStepper(eventName.x, y, cast value, step.getDefault(1), precision, min, max); y += numericStepper.height + 10; paramsPanel.add(numericStepper); paramsFields.push(numericStepper); case TStrumLine: addLabel(); - var dropdown = new UIDropDown(eventName.x, y, 320, 32, [for(k=>s in cast(FlxG.state, Charter).strumLines.members) 'Strumline #${k+1} (${s.strumLine.characters[0]})'], cast curEvent.params[k]); + var dropdown = new UIDropDown(eventName.x, y, 320, 32, [for(k=>s in cast(FlxG.state, Charter).strumLines.members) 'Strumline #${k+1} (${s.strumLine.characters[0]})'], cast value); y += dropdown.height + 10; paramsPanel.add(dropdown); paramsFields.push(dropdown); @@ -104,8 +152,10 @@ class CharterEventScreen extends UISubstateWindow { paramsFields.push(null); } } - } else + } else { + eventName.text = "No event"; curEvent = -1; + } refreshIcons(); } @@ -115,11 +165,15 @@ class CharterEventScreen extends UISubstateWindow { iconsPanel.remove(iconsPanel.members[0], true).destroy(); for(k=>e in chartEvent.events) { - var butt = new UIButton(windowSpr.x + 1, windowSpr.y + 31 + (k*30), "", function() { + var butt = new UIButton(windowSpr.x + 1, windowSpr.y + 66 + (k*30), "", function() { changeTab(k); }); butt.bWidth = butt.bHeight = 30; - butt.visible = (k != curEvent); + if (k == curEvent) { + butt.framesOffset = 18; + butt.active = false; + } + iconsPanel.add(butt); var icon = CharterEvent.generateEventIcon(e); diff --git a/source/funkin/editors/charter/CharterEventTypeSelection.hx b/source/funkin/editors/charter/CharterEventTypeSelection.hx new file mode 100644 index 00000000..d04a0970 --- /dev/null +++ b/source/funkin/editors/charter/CharterEventTypeSelection.hx @@ -0,0 +1,35 @@ +package funkin.editors.charter; + +import funkin.backend.chart.ChartData.ChartEventType; + +class CharterEventTypeSelection extends UISubstateWindow { + var callback:ChartEventType->Void; + + public function new(callback:ChartEventType->Void) { + super(); + this.callback = callback; + } + + public override function create() { + winTitle = "Choose an event type..."; + super.create(); + var w:Int = winWidth - 20; + var lastIndex:Int = 0; + + for(k=>eventType in ChartEventType.getChartEventTypes()) { + var type = CharterEvent.getEventInfo(eventType); + add(new UIButton(10, 41 + (32 * k), type.name, function() { + close(); + callback(eventType); + }, w)); + + lastIndex = k; + } + + add(new UIButton(10, 51 + (32 * (lastIndex+1)), "Cancel", function() { + close(); + }, w)); + + windowSpr.bHeight = 61 + (32 * (lastIndex+2)); + } +} \ No newline at end of file diff --git a/source/funkin/editors/ui/UISubstateWindow.hx b/source/funkin/editors/ui/UISubstateWindow.hx index 7862db3b..6e468068 100644 --- a/source/funkin/editors/ui/UISubstateWindow.hx +++ b/source/funkin/editors/ui/UISubstateWindow.hx @@ -40,8 +40,6 @@ class UISubstateWindow extends MusicBeatSubstate { 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)); @@ -59,4 +57,9 @@ class UISubstateWindow extends MusicBeatSubstate { FlxTween.cancelTweensOf(subCam); FlxG.cameras.remove(subCam); } + + public override function update(elapsed:Float) { + super.update(elapsed); + subCam.scroll.set(Std.int(-(FlxG.width - windowSpr.bWidth) / 2), Std.int(-(FlxG.height - windowSpr.bHeight) / 2)); + } } \ No newline at end of file