From 2c4df59ccd8a41ccb6312e0f9e582b3fe642564f Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Thu, 24 Aug 2023 19:06:10 -0700 Subject: [PATCH 01/72] remove hover note for now --- assets/images/editors/ui/warning-popup.png | Bin 2564 -> 0 bytes .../funkin/editors/charter/ChartHoverNote.hx | 66 ------------------ source/funkin/editors/charter/Charter.hx | 16 +---- source/funkin/editors/ui/UIWarningSubstate.hx | 14 ++-- 4 files changed, 13 insertions(+), 83 deletions(-) delete mode 100644 assets/images/editors/ui/warning-popup.png delete mode 100644 source/funkin/editors/charter/ChartHoverNote.hx diff --git a/assets/images/editors/ui/warning-popup.png b/assets/images/editors/ui/warning-popup.png deleted file mode 100644 index c190bffaab6265c54dc208e3e587ff58b3de368f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2564 zcmbVO2~-p59S@HzQc>22wPryu4IZtUOeTaQvxJC5N$f@x@InJSOeSQ6WI{4X01w>V zswkSGz$=HKBI2UZ6(TAW*aAgF4&@LzJXmY9R1l~jqER~GdT!sg+iu>Q%s2D>zTfYE zze(7<$#?!-`?(YfWxiM>^e6AxEfl0b#CCfGoDzt4W{?nZ>E2G!c{HG6X;) zP$jA&v?Las#i|uJfom1`f1sY-{(%4)U5R8?<40{#DrY6M#QMFY8`A;#QM5KNMvVgg zs1}dXAn5wNq?yiUZ`6>F289V+6NuvxGr8J4V=|q?Wx3OTBY_c2Wp?7X9~?o2FoE(J z=Dac4?o5y!$Yw(v4g|7SvpEo(Jq4BEGE5%xA=HBj@&Y*^1d=Is`2m!y8yQT%KM9s0 zkQ~=2VbWzx35TJ8S{25i&ju3m!6R@DDNI`DGHHcG0*O^x0#+fYSjcCPUb8Sv2EiN< zbp=6$iMn$`nOwHJ2NUMs#JrRILPOl;``eYqIFk-H6J_9i)7L_rkUt>Qz0#mfn3X~-MFX^6w zX>mCb4Qo*EFfv;ILqP$g`GC0>r#u1v-O0(l5BhcnP7VX}a&{1r53{2TRgv>cLk=pz z)rTv{`Bx$qdI#z<2YMRAcWxaf$7^9RB5v6mx-cp_DH`fX{$9fUSOuxz?luV_$+zt{iY|4 z=WoY7N;6(>?6|{k<_)H42Tw#c^?K)x`FWmkyq(?Ps1iIhdj02A5Y=l0^tqX$>N_*&54l~I!w zXgeo3GtoahZ8Z0|AamFIr(JO&SEPkRh4JxFdHR9B-%UF0w=XOInXOcMBmP7gdbR57 zgEZt160c*HfFME0*fKtvGZ_5(im5f~tYbxIKN7dH`Ok*Um)rf1hZ*l#Z>(A#AV}8@ zQ0;SDvX6%}FP$hNa#a>jp6Ghd#Fl5hdDn`6;@Ra!Vw3WpZSb`@BCw#?P>|EjXG+K0 z@uHM1kHe|UcazdR{UalN?-mBUI*})rukNgD3Ez6)(%FIQk=GMz>*p3Zj|Y^nqf7-E zk9Ql&PwqZi;xpdDDY{jAG2-d)NZkf>YpIhx{rT^%!}^o@?zR^X6Dm6{w~XGU+$@f@ ze0%ta&uXdleAZ!o4SV0R!@bVnyrl{7Ytg)F-%y&DUG-2B?I*WZP~we`_wOpTwO?xy zZyN7-oLu;&RYOD1oPw0*LxcS-P2orM3M06083`1X&b1fq9-riYuva{9`=rJn_jaQu zg)#Ekth_!*G`&YFk=j+K=xc_=a=X^z0ejjZ|M$lie%Cu3ufy>|`SNmV6f5<{DKS9MNmMUHXRM-&y04oK^^ebZOl zO3-p6ntdY;iD*u6bkEBqYhz}~P~Z5nmAi~Z9w9+MThl5 zs-BvWUzKOBE} znnPI|eCOEtoQ*q!YV9@~{)u(ki?s2lI%<=)7aLo-Ik{Np*fo8Ssq!zi-z(3gCgh(V z*s~+;-FI(~mRwSl1<8y2xQ5`t?Ot;#pTFEnoyb-Xzj@VFzNmBT&iC0(N8gxkcXXF@ z2MwFb)j>3U$i>74xWErE0Rc(LVb7)Ng4E&pNiqi__K(F1}EDpo00T z;KsRgzy1ogHZG}u#>sDAb-r#QXQ}eawK^Hcx_Uvafw5!FuaJYRV+`SzzjdWI-Mk21 zOcyPCMI30hJea3S#3+|OHSTG;S;up4c^*AsnelN#_o?`vbLQ_f@%l}|!gZg2@h|gs B9;5&O diff --git a/source/funkin/editors/charter/ChartHoverNote.hx b/source/funkin/editors/charter/ChartHoverNote.hx deleted file mode 100644 index d3eee237..00000000 --- a/source/funkin/editors/charter/ChartHoverNote.hx +++ /dev/null @@ -1,66 +0,0 @@ -package funkin.editors.charter; - -import flixel.tweens.misc.VarTween; -import flixel.tweens.FlxTween; - -class ChartHoverNote extends UISprite { - public var angleTween:FlxTween; - - public var onGrid:Bool = false; - public var id:Int = 0; - public var nextID:Int = 0; - - public function new() { - super(); - antialiasing = true; - loadGraphic(Paths.image('editors/charter/note'), true, 157, 154); - animation.add("note", [for(i in 0...frames.frames.length) i], 0, true); - animation.play("note"); - this.setUnstretchedGraphicSize(40, 40, false); - - moves = selectable = false; - colorTransform.color = 0xFFFFFF; - } - - public override function update(elapsed:Float) { - super.update(elapsed); - - var mousePos = FlxG.mouse.getWorldPosition(__lastDrawCameras[0]); - alpha = FlxMath.lerp(alpha, onGrid ? 0.2 : 0, 1/8); - id = Math.floor(x / 40); - - if (onGrid) { - Charter.instance.gridBackdropDummy.cursor = BUTTON; - x = (nextID = Math.floor(mousePos.x / 40)) * 40; - y = (FlxG.keys.pressed.SHIFT ? (mousePos.y / 40) : Math.floor(mousePos.y / 40)) * 40; - - if (id != nextID) { - if (angleTween != null) angleTween.cancel(); - - angle = switch(id % 4) { - case 0: -90; - case 1: 180; - case 2: 0; - case 3: 90; - default: 0; // how is that even possible - }; - - var destAngle = switch((nextID % 4)) { - case 0: -90; - case 1: 180; - case 2: 0; - case 3: 90; - default: 0; // how is that even possible - }; - - angleTween = FlxTween.tween(this, {angle: destAngle}, 2/3, {ease: function(t) { - return ((Math.sin(t * Math.PI) * 0.35) * 3 * t * Math.sqrt(1 - t)) + t; - }, onComplete: function (t) {angleTween = null;}}); - } - } else if (alpha > 0) { - Charter.instance.gridBackdropDummy.cursor = ARROW; - x = mousePos.x - 20; y = mousePos.y -20; - } - mousePos.put(); - } -} \ No newline at end of file diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 57dd195c..9309f12e 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -55,7 +55,6 @@ class Charter extends UIState { public var topLimit:FlxSprite; public var bottomLimit:FlxSprite; public var bottomSeparator:FlxSprite; - public var hoverNote:ChartHoverNote; public var strumlineInfoBG:FlxSprite; public var strumlineAddButton:CharterStrumlineExtraButton; @@ -353,9 +352,6 @@ class Charter extends UIState { eventsBackdrop.cameras = [charterCamera]; add(eventsBackdrop); - hoverNote = new ChartHoverNote(); - hoverNote.cameras = [charterCamera]; - add(gridBackdropDummy = new CharterBackdropDummy(gridBackdrop)); sectionSeparator = new FlxBackdrop(null, Y, 0, 0); sectionSeparator.x = -20; @@ -435,7 +431,6 @@ class Charter extends UIState { // adds grid and notes so that they're ALWAYS behind the UI add(gridBackdrop); - add(hoverNote); add(sectionSeparator); add(beatSeparator); add(addEventSpr); @@ -564,7 +559,6 @@ class Charter extends UIState { if (!gridBackdropDummy.hoveredByChild && !FlxG.mouse.pressed) gridActionType = NONE; selectionBox.visible = false; - hoverNote.onGrid = false; switch(gridActionType) { case BOX: if (gridBackdropDummy.hoveredByChild) { @@ -643,8 +637,6 @@ class Charter extends UIState { if (FlxG.mouse.justPressed) FlxG.mouse.getWorldPosition(charterCamera, dragStartPos); - hoverNote.visible = hoveredSprite != null ? hoveredSprite is CharterNote : true; - if (gridBackdropDummy.hovered) { // AUTO DETECT if (FlxG.mouse.pressed && (Math.abs(mousePos.x - dragStartPos.x) > 20 || Math.abs(mousePos.y - dragStartPos.y) > 20)) @@ -653,8 +645,6 @@ class Charter extends UIState { var id = Math.floor(mousePos.x / 40); var mouseOnGrid = id >= 0 && id < 4 * gridBackdrop.strumlinesAmount && mousePos.y >= 0; - hoverNote.onGrid = mouseOnGrid; - if (FlxG.mouse.justReleased) { if (selection.length > 1) { selection = []; // clear selection @@ -1021,16 +1011,16 @@ class Charter extends UIState { #if REGION function _file_exit(_) { if (undos.unsaved) { - FlxG.state.openSubState(new UIWarningSubstate("Unsaved Changes", "Your changes will be lost if you don't save them.", [ + FlxG.state.openSubState(new UIWarningSubstate("Unsaved Changes", "Your changes will be lost if you don't save them. (Can't be recovered)\n\n\nWould you like to Cancel?", [ { - label: "Exit", + label: "Exit To Menu", onClick: function(_) FlxG.switchState(new CharterSelection()) }, { label: "Cancel", onClick: function (_) {} } - ])); + ], false)); } else FlxG.switchState(new CharterSelection()); } diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx index b20e78f0..9fee13e2 100644 --- a/source/funkin/editors/ui/UIWarningSubstate.hx +++ b/source/funkin/editors/ui/UIWarningSubstate.hx @@ -12,6 +12,7 @@ class UIWarningSubstate extends MusicBeatSubstate { var title:String; var message:String; var buttons:Array; + var isError:Bool = true; var titleSpr:UIText; var messageSpr:UIText; @@ -55,19 +56,23 @@ class UIWarningSubstate extends MusicBeatSubstate { warnCam.zoom = 0.1; FlxG.cameras.add(warnCam, false); - var spr = new UISliceSprite(0, 0, CoolUtil.maxInt(560, 30 + (170 * buttons.length)), 280, "editors/ui/warning-popup"); + var spr = new UISliceSprite(0, 0, CoolUtil.maxInt(560, 30 + (170 * buttons.length)), 232, "editors/ui/normal-popup"); spr.x = (FlxG.width - spr.bWidth) / 2; spr.y = (FlxG.height - spr.bHeight) / 2; + spr.color = 0xFFFF0000; 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 sprIcon:FlxSprite = new FlxSprite(spr.x + 26, spr.y + 28 + 26).makeSolid(100, 100, -1); + add(sprIcon); + + add(messageSpr = new UIText(sprIcon.x + 100 + 16, sprIcon.y + 12, spr.bWidth - 100 - (26 * 2), message)); var xPos = (FlxG.width - (30 + (170 * buttons.length))) / 2; for(k=>b in buttons) { - var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - 40, b.label, function() { + var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - (32 + 16), b.label, function() { b.onClick(this); close(); }, 160, 30); @@ -89,11 +94,12 @@ class UIWarningSubstate extends MusicBeatSubstate { FlxG.cameras.remove(warnCam); } - public function new(title:String, message:String, buttons:Array) { + public function new(title:String, message:String, buttons:Array, ?isError:Bool = true) { super(); this.title = title; this.message = message; this.buttons = buttons; + this.isError = isError; } } From 8badd79d0c5b0d2ea5c5af6417548a184fc0409d Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Fri, 25 Aug 2023 23:20:00 -0700 Subject: [PATCH 02/72] fixing saving in character editor --- source/funkin/editors/character/CharacterEditor.hx | 3 ++- source/funkin/editors/charter/Charter.hx | 3 +-- source/funkin/editors/ui/UIState.hx | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx index 970288ff..b41a89cc 100644 --- a/source/funkin/editors/character/CharacterEditor.hx +++ b/source/funkin/editors/character/CharacterEditor.hx @@ -51,6 +51,7 @@ class CharacterEditor extends UIState { public override function create() { super.create(); + WindowTitle.endfix = " (Character Editor)"; topMenu = [ { label: "File", @@ -323,7 +324,7 @@ class CharacterEditor extends UIState { function _file_save(_) { #if sys sys.io.File.saveContent( - Assets.getPath(Paths.xml('characters/${character.curCharacter}')), + '${Paths.getAssetsRoot()}/data/characters/${character.curCharacter}.xml', buildCharacter() ); return; diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 9309f12e..6e7a89f2 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -464,7 +464,6 @@ class Charter extends UIState { Framerate.memoryCounter.alpha = 1; Framerate.codenameBuildField.alpha = 1; } - WindowTitle.reset(); super.destroy(); } @@ -954,7 +953,7 @@ class Charter extends UIState { updateDisplaySprites(); } - WindowTitle.prefix = undos.unsaved ? "UNSAVED | " : ""; + WindowTitle.prefix = undos.unsaved ? "● " : ""; } public static var startTime:Float = 0; diff --git a/source/funkin/editors/ui/UIState.hx b/source/funkin/editors/ui/UIState.hx index 716e277d..9aa8cac3 100644 --- a/source/funkin/editors/ui/UIState.hx +++ b/source/funkin/editors/ui/UIState.hx @@ -120,6 +120,7 @@ class UIState extends MusicBeatState { public override function destroy() { super.destroy(); + WindowTitle.reset(); __mousePos.put(); FlxG.stage.window.onKeyDown.remove(onKeyDown); FlxG.stage.window.onKeyUp.remove(onKeyUp); From dcd267525788f0eee19176fca3baca0f5ddf9daa Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sat, 26 Aug 2023 18:31:43 +0300 Subject: [PATCH 03/72] reorderable wip --- source/funkin/editors/charter/Charter.hx | 8 +++++- source/funkin/editors/charter/CharterNote.hx | 18 ++++++++----- .../editors/charter/CharterStrumline.hx | 25 +++++++++++++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 6e7a89f2..4e7b4f55 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -456,6 +456,7 @@ class Charter extends UIState { Framerate.memoryCounter.alpha = 0.4; Framerate.codenameBuildField.alpha = 0.4; } + updateDisplaySprites(); } override function destroy() { @@ -596,6 +597,7 @@ class Charter extends UIState { if (FlxG.mouse.pressed) { selection.loop(function (n:CharterNote) { n.setPosition(n.id * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); + n.dragging = true; n.cursor = HAND; }, function (e:CharterEvent) { e.y = e.step * 40 + (mousePos.y - dragStartPos.y) - 17; @@ -620,6 +622,7 @@ class Charter extends UIState { for (s in selection) { if (!s.draggable) continue; s.handleDrag(changePoint); + if (s is CharterNote) cast(s, CharterNote).dragging = false; if (s is UISprite) cast(s, UISprite).cursor = BUTTON; } sortNotes(); @@ -954,6 +957,9 @@ class Charter extends UIState { } WindowTitle.prefix = undos.unsaved ? "● " : ""; + strumLines.sort(function(o, a, b) return FlxSort.byValues(o, a.x - 80, b.x - 80), -1); + for (it=>i in strumLines.members) + if (!i.dragging) i.x = CoolUtil.fpsLerp(i.x, 160 * it, 0.3); } public static var startTime:Float = 0; @@ -993,7 +999,7 @@ class Charter extends UIState { str.y = strumlineInfoBG.y; } - strumlineAddButton.x = strumLines.members.length * (40 * 4); + strumlineAddButton.x = strumLines.length * (40 * 4); strumlineAddButton.y = strumlineInfoBG.y; } diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index 9a3359f4..1fa9d296 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -22,7 +22,8 @@ class CharterNote extends UISprite implements ICharterSelectable { public var selected:Bool = false; public var draggable:Bool = true; - + public var dragging:Bool = false; + public var strumLine:CharterStrumline = null; public function new() { super(); antialiasing = true; @@ -52,17 +53,22 @@ class CharterNote extends UISprite implements ICharterSelectable { public var step:Float; - public var id:Int; + public var realId:Int; + @:isVar public var id(get, set):Int; public var susLength:Float; public var type:Int; - + function set_id(d:Int) { + strumLine = Charter.instance.strumLines.members[Math.floor(d / 4)]; + id = d % 4; + realId = d; + return id; + } + function get_id() return id + 4 * Charter.instance.strumLines.members.indexOf(strumLine); public function updatePos(step:Float, id:Int, susLength:Float = 0, type:Int = 0) { this.step = step; this.id = id; this.susLength = susLength; this.type = type; - - x = id * 40; y = step * 40; sustainSpr.scale.set(10, (40 * susLength)); @@ -116,7 +122,7 @@ class CharterNote extends UISprite implements ICharterSelectable { var __passed:Bool = false; public override function update(elapsed:Float) { super.update(elapsed); - + if (!dragging) x = (strumLine != null ? strumLine.button.x : 0) + (id % 4) * 40; if(sustainSpr.exists) sustainSpr.follow(this, 15, 20); diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx index 14f4d671..05a65e81 100644 --- a/source/funkin/editors/charter/CharterStrumline.hx +++ b/source/funkin/editors/charter/CharterStrumline.hx @@ -13,6 +13,7 @@ class CharterStrumline extends UISprite { public var healthIcon:HealthIcon; public var button:CharterStrumlineButton; + public var dragging:Bool = false; public var curMenu:UIContextMenu = null; @@ -37,12 +38,32 @@ class CharterStrumline extends UISprite { button = new CharterStrumlineButton(this); members.push(button); } - + var __pastStrumlines:Array; public override function update(elapsed:Float) { if (healthIcon != null) - healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, 0); + healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, 50); button.follow(this, 0, 95); super.update(elapsed); + if (FlxG.mouse.overlaps(healthIcon) && FlxG.mouse.justPressed) { + dragging = true; + trace(__pastStrumlines = Charter.instance.strumLines.members.copy()); + } + if (dragging) x = FlxG.mouse.x - 80; + if (FlxG.mouse.justReleased && dragging) { + dragging = false; + /*if (FlxG.keys.pressed.ALT) { + for (i in Charter.instance.notesGroup.members) { + trace(i.realId); + } + }*/ + for (i in Charter.instance.eventsGroup.members) { + for (j in i.events) + if (j.name == "Camera Movement" && !FlxG.keys.pressed.SHIFT) + j.params[0] = Charter.instance.strumLines.members.indexOf(__pastStrumlines[j.params[0]]); + i.refreshEventIcons(); + } + + } } public function updateInfo() { From 34d9a9b49ed453aaea758aa7f322fe78cf640c99 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sat, 26 Aug 2023 20:16:38 +0300 Subject: [PATCH 04/72] its so good --- source/funkin/editors/charter/CharterBackdrop.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index 5768e461..e05a9acc 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -27,11 +27,11 @@ class CharterBackdrop extends FlxBackdrop { public override function draw() { var ogX:Float = x; for(_ in 0...strumlinesAmount) { + x = Charter.instance.strumLines.members[_].x; if (Charter.instance.strumLines.members[_] != null) alpha = Charter.instance.strumLines.members[_].strumLine.visible ? 1 : 0.4; else alpha = 0.9; super.draw(); - x += width; } x = ogX; } From 66b98057c7a9d1ca668c2d2a31b5459c72f8f21e Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sat, 26 Aug 2023 20:18:24 +0300 Subject: [PATCH 05/72] guh --- source/funkin/editors/charter/CharterBackdrop.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index e05a9acc..39d93eaa 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -27,8 +27,8 @@ class CharterBackdrop extends FlxBackdrop { public override function draw() { var ogX:Float = x; for(_ in 0...strumlinesAmount) { - x = Charter.instance.strumLines.members[_].x; if (Charter.instance.strumLines.members[_] != null) + x = Charter.instance.strumLines.members[_].x; alpha = Charter.instance.strumLines.members[_].strumLine.visible ? 1 : 0.4; else alpha = 0.9; super.draw(); From d21bd52b6dea6169a78ac7f8fb878b53471b1232 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sat, 26 Aug 2023 20:19:09 +0300 Subject: [PATCH 06/72] ong --- source/funkin/editors/charter/CharterBackdrop.hx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index 39d93eaa..0ac2ed7d 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -27,9 +27,10 @@ class CharterBackdrop extends FlxBackdrop { public override function draw() { var ogX:Float = x; for(_ in 0...strumlinesAmount) { - if (Charter.instance.strumLines.members[_] != null) + if (Charter.instance.strumLines.members[_] != null) { x = Charter.instance.strumLines.members[_].x; alpha = Charter.instance.strumLines.members[_].strumLine.visible ? 1 : 0.4; + } else alpha = 0.9; super.draw(); } From 22638048d87c68daa52cde6bee1de56c0e76002c Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 26 Aug 2023 11:37:39 -0700 Subject: [PATCH 07/72] making dragging look a bit better (still need to add limits) --- assets/images/editors/warning.aseprite | Bin 0 -> 1970 bytes assets/images/editors/warning.png | Bin 0 -> 1929 bytes source/funkin/editors/charter/Charter.hx | 90 +++++++----------- .../funkin/editors/charter/CharterBackdrop.hx | 45 ++++++++- .../editors/charter/CharterNoteGroup.hx | 8 +- 5 files changed, 82 insertions(+), 61 deletions(-) create mode 100644 assets/images/editors/warning.aseprite create mode 100644 assets/images/editors/warning.png diff --git a/assets/images/editors/warning.aseprite b/assets/images/editors/warning.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..74aa0e65202489ef627499bd184f1c3f983a75e0 GIT binary patch literal 1970 zcmcJN`#)RvAIIa?)H;o{E-jI!l4WX!#3n`R(yk3^ZCz@N?}8M?cOj{iR#nGJu_O&z z)TLFd7q^-!UnW+UN?dA6r!!%R&}zOd(W%msz0>Z8{sa4*$9aA}kMlX_@p`__IX@v0 zh(9Ye5J%v^Av6#OnBN}+gogSeLLZKQV~`<#MXB>PRR;o$;6&oyM!pxf0PC$d!arB= z@9n%@st^cs+-JbO7F1w_0}06YcLGkbh``^kL;#<6UIM;eum=`S9|A@TZGn_LCUAe0 z4bW#l0Z67g09{<-fwm#3z#yg+$S6_)=>u|L-yd&)Di{bvQB4!@`_mb~sOV^5puZ3B z`0gxVHJJ?j{VN7=G^qv1&-Vmo#j4Zg<95J?8ntsw1fmRqFflPv9fxAt>hGa04dtL2 z)Phb>2--ju=m9050qBD}h=VmKgD=Q}DQK!4RVuIpHShu{FajNL0THkO1;~eRNQT&L z>QtQ8+n4$dAca68yh2ZevvH)e@P%}6|7>W!o7F$e5kz9~vyz|~1CqfRt-T)@b z(;qP6P4-4VU_49?Gi}*~sODQCa`&7#PMQGk(UGBpryc4Xg$J&rbGz@=*r%+7a4{YR zhneH;l9?hKC%OC8I2I$Rp>ru=RE(C#aTs%qeAP0m1mm`G8%3LMNj$;3x>c%3-+&6! zM4dC0uRq`_!O`N(yY$!u=Jzdbye{q*=6O8J{GzGcz4+YhI)_b0^>9arW~Uxo+b96` zZk=f%xlky1a`!}6iN#h?T_cIqc#!uYvI|Q5Hl-1svnEm)>r=d}3bZy4Cy4~+!IHS} zyPAa+yH-x>jOYz39ujD8I!3txRFPn4eW7pRL^*Mwaa>Eb&kHLT;esW)psdK4s|Xs0Wg{6$8}=BiCR}jD)`Hr@^z^^{>Wg@pdWw<7OYKGeof|a$&-5X6& zbGMg&tJ*lZ`s;LiJ0HnsMT9X}vE>7oUC_+M(z7827&yR1$jB&v@%mS*59UvSCI>NPRyF zWqoYzm~e>KB}5sgWz1ha5-J1MC+>Jqu+4w9VP=y)&FK`_QXKKCwfCvG z)qD4}(lYBz)21wXDu!0QEl?7wXMP-Zjp6S}!!h%O`HzE}jFD3G)SOtpr6G*0sUS>ihzefCn%1ja1JJLqC#-QZyPH$2xmN<7u?VAfnv8>@P{t0RGH zyin|R0bl$1;63eL&690q+v>g^WA)`NN{52>D1&`(DbLvI23<25@1tXBfrE_s`NFvw z8G2YS&#_z%%s&z@rP-g9@j{-(c7<)Xs}Db~<#Um9a4FEYIwtgatn1*e<1PJz1E>9(P#nV21YP*q zYf?_zigeg{M9}hVwbFxSbv30%$u=7+{q~!YqD0l^b+UcpJ+G8et@~#Sg}g@rhh#tY zmiOv;p2CthhY4KvV>t?$-6ekm Da2QNX literal 0 HcmV?d00001 diff --git a/assets/images/editors/warning.png b/assets/images/editors/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..71c841547a2569029f922d172e5ffe4d2e711974 GIT binary patch literal 1929 zcmV;42X^?0P)Px+LrFwIRCt{2oXc+8Mi_<9h%_z9cH*K1637KAXj5-fxOtW!kCK&Fd6c4?uCgn- z>#oQHbY*y9d(lnn^rAo(JzWfkq9}4W_lxZV5Rf2VMswzyf35@`fEM#Jx|pBQ(CK&* zm>B>lfCpj9D0Bi$)MY^GrX+0$09;&t?EIXnk~Ks`LdujRYY5OyMCz0zX^0E~sZx@p zA%K{KlqpHh5S5ajA|=Tg0>}}NDkVu7qEq5iqa-Oq0JV~zA|=TfVp7smq9hqZfc_Hy z;ip&l^_TCIu8CDi7&27C$NRwXb7FLlSd@ezfS8W)m|#2x{{G{8rE6nU^oGdNar~TM zJWijI=nVnn=-_7DeR{2QkJuEoAvWody=Q1eZ3v)72Up6JL~Do(I%Mx1QqdX$=+VKI zDkV`G;*t*8XM|Feh5%-CaHU8|bcXn#L-tuA6rCY}9XhyDqa-Rre9|HNOy7#i5Wp@S zTq#i!jUgfEkbSmK<)IVMlnNd5(<|Y-*iO*VudZTjw(u^E1s9+gB8Z=+be0 zbJKbL$!w;ThKtLOcG1&NG*y-?9rM$xK{^0*o|i%_32ulE9oIKEy>!U@uA3Gg3T_A> zN5}E8outN2Nl-&n=n)P39{} zI|@ZfFhYjtIQ@3p4B7riTcYb?q{O=+CaVxt`xm z#JM34fetPolz1UTM8{WO5*!@FV@7C7oEkDzqNY>e=!oF(0NCGmnG$<)O^I_t`byT% zA70^LN-&)OMIol+haWGD)1h*Ykd!zxWT+(V?E#Z9u)j}`MX~lpUM?wdN{EP#$%Ms@ z$r#wn0YZGokP^TOge*IM4Mm9)LxxHaA&id6gy86Cge(gY&`S`)49T-=<*Qv$;*5}? zUioxN@a!mD%Zd;Qeu^mbm(AeR$J_Q z0Yd)iJl7W`Rt!mx4z6~!Rf1FEPO>1f=Y33cIGn$PnLj=CX^Tvl6LH9OTOn0xT8eNkcUPG z({{CG5=Q`iO0*|WL($O;(l%clu&c7_k7U*G{4O~z-VUK`NJu)Gf&JZiAsaER66K(7wsUrc z5xE5+ON_{}DvkP+LvEzjCjsoXxTFm++x=9Pwrb!mJ`=WOvrhu3wYZe3EEPKP?7FId zi+T}(?x0;;vb%BH@63`{71)tMw%W4Q;*v5%hmLzX!H6tz51{@Nh9wQym@%}w_GC80 z{ParGlufn8{!!Buy}k3Yu|&GcQlVpaHQ**d+K|jvXOr#Fz;3lAnkV715laRQF@5U- zLHD0&PoMJN^6a`k!phz}371SPks`!wUwO&e^k@h3<{xIJg*Txowb?{2Q%Zz}*w|N2 zs<_b=J2vzzdlx;2m48YG39^;>r5OL{woX7e3Y$Etp0DcpzA zR#*JsVi|macjsbL)Xd;RJ6#QrRikxuULM@EVo*lDu_- z)7ijS3}}mGa#5A|p_928!$!!cP03DBe^@I?WJCevpmdD;`@`XbPOBekArP>#^y7HRrEfAxnpH P00000NkvXXu0mjf7>|`# literal 0 HcmV?d00001 diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 4e7b4f55..eae34370 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -48,12 +48,9 @@ class Charter extends UIState { public var gridBackdrop:CharterBackdrop; public var eventsBackdrop:FlxBackdrop; public var addEventSpr:CharterEventAdd; - public var beatSeparator:FlxBackdrop; - public var sectionSeparator:FlxBackdrop; + public var eventBeatSeparator:FlxBackdrop; + public var eventSecSeparator:FlxBackdrop; public var gridBackdropDummy:CharterBackdropDummy; - public var conductorFollowerSpr:FlxSprite; - public var topLimit:FlxSprite; - public var bottomLimit:FlxSprite; public var bottomSeparator:FlxSprite; public var strumlineInfoBG:FlxSprite; @@ -267,12 +264,12 @@ class Charter extends UIState { null, { label: 'Show Sections Separator', - onSelect: _view_showsectionseparator, + onSelect: _view_showeventSecSeparator, icon: Options.charterShowSections ? 1 : 0 }, { label: 'Show Beats Separator', - onSelect: _view_showbeatseparator, + onSelect: _view_showeventBeatSeparator, icon: Options.charterShowBeats ? 1 : 0 } ] @@ -353,15 +350,15 @@ class Charter extends UIState { add(eventsBackdrop); 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]) { + eventSecSeparator = new FlxBackdrop(null, Y, 0, 0); + eventSecSeparator.x = -20; + eventSecSeparator.y = -2; + eventSecSeparator.visible = Options.charterShowSections; + eventBeatSeparator = new FlxBackdrop(null, Y, 0, 0); + eventBeatSeparator.x = -10; + eventBeatSeparator.y = -1; + eventSecSeparator.visible = Options.charterShowBeats; + for(sep in [eventSecSeparator, eventBeatSeparator]) { sep.makeGraphic(1, 1, -1); sep.alpha = 0.5; sep.scrollFactor.set(1, 1); @@ -373,11 +370,7 @@ class Charter extends UIState { selectionBox.scrollFactor.set(1, 1); selectionBox.incorporeal = true; - conductorFollowerSpr = new FlxSprite(0, 0).makeGraphic(1, 1, -1); - conductorFollowerSpr.scale.set(gridBackdrop.strumlinesAmount * 4 * 40, 4); - conductorFollowerSpr.updateHitbox(); - - conductorFollowerSpr.cameras = selectionBox.cameras = notesGroup.cameras = gridBackdrop.cameras = [charterCamera]; + selectionBox.cameras = notesGroup.cameras = gridBackdrop.cameras = [charterCamera]; topMenuSpr = new UITopMenu(topMenu); topMenuSpr.cameras = uiGroup.cameras = [uiCamera]; @@ -394,16 +387,6 @@ class Charter extends UIState { songPosInfo.alignment = RIGHT; uiGroup.add(songPosInfo); - topLimit = new FlxSprite(); - topLimit.makeGraphic(1, 1, -1); - topLimit.color = 0xFF888888; - topLimit.blend = MULTIPLY; - - bottomLimit = new FlxSprite(); - bottomLimit.makeGraphic(1, 1, -1); - bottomLimit.color = 0xFF888888; - bottomLimit.blend = MULTIPLY; - bottomSeparator = new FlxSprite(); bottomSeparator.makeGraphic(1, 1, -1); bottomSeparator.alpha = 0.5; @@ -431,15 +414,14 @@ class Charter extends UIState { // adds grid and notes so that they're ALWAYS behind the UI add(gridBackdrop); - add(sectionSeparator); - add(beatSeparator); + add(eventSecSeparator); + add(eventBeatSeparator); add(addEventSpr); add(eventsGroup); add(notesGroup); add(topLimit); add(bottomLimit); add(bottomSeparator); - add(conductorFollowerSpr); add(selectionBox); add(strumlineInfoBG); add(strumlineAddButton); @@ -909,8 +891,8 @@ class Charter extends UIState { if (gridBackdrop.strumlinesAmount != strumLines.members.length) updateDisplaySprites(); - sectionSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; - beatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; + eventSecSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; + eventBeatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; // TODO: canTypeText in case an ui input element is focused if (true) { @@ -947,16 +929,19 @@ class Charter extends UIState { + '\nTime Signature: ${Conductor.beatsPerMesure}/${Conductor.stepsPerBeat}'; if (FlxG.sound.music.playing) { - conductorFollowerSpr.y = curStepFloat * 40; + gridBackdrop.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))) { - updateDisplaySprites(); + gridBackdrop.conductorFollowerSpr.y = lerp(gridBackdrop.conductorFollowerSpr.y, curStepFloat * 40, 1/3); } + charterCamera.scroll.set( + (((gridBackdrop.conductorFollowerSpr.scale.x * gridBackdrop.strumlinesAmount) - FlxG.width) / 2), + gridBackdrop.conductorFollowerSpr.y - (FlxG.height * 0.5) + ); - WindowTitle.prefix = undos.unsaved ? "● " : ""; + if (charterCamera.zoom != (charterCamera.zoom = lerp(charterCamera.zoom, __camZoom, 0.125))) + updateDisplaySprites(); + + WindowTitle.prefix = undos.unsaved ? "* " : ""; strumLines.sort(function(o, a, b) return FlxSort.byValues(o, a.x - 80, b.x - 80), -1); for (it=>i in strumLines.members) if (!i.dragging) i.x = CoolUtil.fpsLerp(i.x, 160 * it, 0.3); @@ -968,14 +953,11 @@ class Charter extends UIState { function updateDisplaySprites() { gridBackdrop.strumlinesAmount = strumLines.members.length; - conductorFollowerSpr.scale.set(gridBackdrop.strumlinesAmount * 4 * 40, 4); - conductorFollowerSpr.updateHitbox(); + eventSecSeparator.scale.set(20, 4); + eventSecSeparator.updateHitbox(); - sectionSeparator.scale.set((gridBackdrop.strumlinesAmount * 4 * 40) + 20, 4); - sectionSeparator.updateHitbox(); - - beatSeparator.scale.set((gridBackdrop.strumlinesAmount * 4 * 40) + 10, 2); - beatSeparator.updateHitbox(); + eventBeatSeparator.scale.set(10, 2); + eventBeatSeparator.updateHitbox(); charterBG.scale.set(1 / charterCamera.zoom, 1 / charterCamera.zoom); topLimit.scale.set(gridBackdrop.strumlinesAmount * 4 * 40, Math.ceil(FlxG.height / charterCamera.zoom)); @@ -1260,13 +1242,13 @@ class Charter extends UIState { zoom = 0; __camZoom = Math.pow(2, zoom); } - function _view_showsectionseparator(t) { + function _view_showeventSecSeparator(t) { t.icon = (Options.charterShowSections = !Options.charterShowSections) ? 1 : 0; - sectionSeparator.visible = Options.charterShowSections; + eventSecSeparator.visible = gridBackdrop.sectionSeparator.visible = Options.charterShowSections; } - function _view_showbeatseparator(t) { + function _view_showeventBeatSeparator(t) { t.icon = (Options.charterShowBeats = !Options.charterShowBeats) ? 1 : 0; - beatSeparator.visible = Options.charterShowBeats; + eventBeatSeparator.visible = gridBackdrop.beatSeparator.visible = Options.charterShowBeats; } inline function _note_addsustain(t) diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index 0ac2ed7d..efd536da 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -1,11 +1,16 @@ package funkin.editors.charter; +import funkin.backend.system.Conductor; import openfl.geom.Rectangle; import flixel.addons.display.FlxBackdrop; class CharterBackdrop extends FlxBackdrop { public var strumlinesAmount:Int = 1; + public var conductorFollowerSpr:FlxSprite; + public var beatSeparator:FlxBackdrop; + public var sectionSeparator:FlxBackdrop; + public function new() { super(null, Y, 0, 0); @@ -21,7 +26,28 @@ class CharterBackdrop extends FlxBackdrop { pixels.fillRect(new Rectangle(0, 0, 1, 160), 0xFFDDDDDD); pixels.fillRect(new Rectangle(159, 0, 1, 160), 0xFFDDDDDD); pixels.unlock(); - // loadFrame(frame); + + // Seperators + sectionSeparator = new FlxBackdrop(null, Y, 0, 0); + sectionSeparator.y = -2; + sectionSeparator.visible = Options.charterShowSections; + + beatSeparator = new FlxBackdrop(null, Y, 0, 0); + beatSeparator.y = -1; + beatSeparator.visible = Options.charterShowBeats; + + for(sep in [sectionSeparator, beatSeparator]) { + sep.makeGraphic(1, 1, -1); + sep.alpha = 0.5; + sep.scrollFactor.set(1, 1); + sep.scale.set((4 * 40), sep == sectionSeparator ? 4 : 2); + sep.updateHitbox(); + } + + // Follower + conductorFollowerSpr = new FlxSprite(0, 0).makeGraphic(1, 1, -1); + conductorFollowerSpr.scale.set(4 * 40, 4); + conductorFollowerSpr.updateHitbox(); } public override function draw() { @@ -30,9 +56,22 @@ class CharterBackdrop extends FlxBackdrop { if (Charter.instance.strumLines.members[_] != null) { x = Charter.instance.strumLines.members[_].x; alpha = Charter.instance.strumLines.members[_].strumLine.visible ? 1 : 0.4; - } - else alpha = 0.9; + } else alpha = 0.9; + + sectionSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; + beatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; + super.draw(); + + for (sep in [sectionSeparator, beatSeparator]) { + sep.x = this.x; + sep.cameras = this.cameras; + if (sep.visible) sep.draw(); + } + + conductorFollowerSpr.x = this.x; + conductorFollowerSpr.cameras = this.cameras; + if (conductorFollowerSpr.visible) conductorFollowerSpr.draw(); } x = ogX; } diff --git a/source/funkin/editors/charter/CharterNoteGroup.hx b/source/funkin/editors/charter/CharterNoteGroup.hx index 775601d0..8478daa9 100644 --- a/source/funkin/editors/charter/CharterNoteGroup.hx +++ b/source/funkin/editors/charter/CharterNoteGroup.hx @@ -17,18 +17,18 @@ class CharterNoteGroup extends FlxTypedGroup { __currentlyLooping = true; var curStep = Conductor.curStepFloat; - if (FlxG.state is Charter && !FlxG.sound.music.playing) - curStep = cast(FlxG.state, Charter).conductorFollowerSpr.y / 40; + if (!FlxG.sound.music.playing) + curStep = Charter.instance.gridBackdrop.conductorFollowerSpr.y / 40; var begin = SortedArrayUtil.binarySearch(members, curStep - max, getVarForEachAdd); var end = SortedArrayUtil.binarySearch(members, curStep + max, getVarForEachRemove); for(i in begin...end) { __loopSprite = members[i]; - if (!cast(FlxG.state, Charter).selection.contains(__loopSprite)) + if (!Charter.instance.selection.contains(__loopSprite)) noteFunc(__loopSprite); } - for(c in cast(FlxG.state, Charter).selection.copy()) + for(c in Charter.instance.selection.copy()) if (c is CharterNote) noteFunc(cast (c, CharterNote)); __currentlyLooping = oldCur; From 5d9baa6a3d66186ad9a06e58f8fa46ae06504092 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 26 Aug 2023 12:56:00 -0700 Subject: [PATCH 08/72] seperate each strum and events --- source/funkin/editors/charter/Charter.hx | 66 ++------- .../funkin/editors/charter/CharterBackdrop.hx | 125 ++++++++++++++++++ 2 files changed, 133 insertions(+), 58 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index eae34370..5d9d3c4d 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import funkin.editors.charter.CharterBackdrop.EventBackdrop; import funkin.backend.system.framerate.Framerate; import haxe.Json; import flixel.input.keyboard.FlxKey; @@ -46,12 +47,9 @@ class Charter extends UIState { public var topMenuSpr:UITopMenu; public var gridBackdrop:CharterBackdrop; - public var eventsBackdrop:FlxBackdrop; + public var eventsBackdrop:EventBackdrop; public var addEventSpr:CharterEventAdd; - public var eventBeatSeparator:FlxBackdrop; - public var eventSecSeparator:FlxBackdrop; public var gridBackdropDummy:CharterBackdropDummy; - public var bottomSeparator:FlxSprite; public var strumlineInfoBG:FlxSprite; public var strumlineAddButton:CharterStrumlineExtraButton; @@ -343,28 +341,11 @@ class Charter extends UIState { gridBackdrop = new CharterBackdrop(); - eventsBackdrop = new FlxBackdrop(Paths.image('editors/charter/events-grid'), Y, 0, 0); + eventsBackdrop = new EventBackdrop(); eventsBackdrop.x = -eventsBackdrop.width; - eventsBackdrop.alpha = 0.9; eventsBackdrop.cameras = [charterCamera]; - add(eventsBackdrop); add(gridBackdropDummy = new CharterBackdropDummy(gridBackdrop)); - eventSecSeparator = new FlxBackdrop(null, Y, 0, 0); - eventSecSeparator.x = -20; - eventSecSeparator.y = -2; - eventSecSeparator.visible = Options.charterShowSections; - eventBeatSeparator = new FlxBackdrop(null, Y, 0, 0); - eventBeatSeparator.x = -10; - eventBeatSeparator.y = -1; - eventSecSeparator.visible = Options.charterShowBeats; - for(sep in [eventSecSeparator, eventBeatSeparator]) { - 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; selectionBox.scrollFactor.set(1, 1); @@ -387,15 +368,6 @@ class Charter extends UIState { songPosInfo.alignment = RIGHT; uiGroup.add(songPosInfo); - bottomSeparator = new FlxSprite(); - bottomSeparator.makeGraphic(1, 1, -1); - bottomSeparator.alpha = 0.5; - bottomSeparator.scrollFactor.set(1, 1); - bottomSeparator.cameras = [charterCamera]; - - bottomSeparator.x = -20; - bottomSeparator.y = -2; - strumlineInfoBG = new UISprite(); strumlineInfoBG.loadGraphic(Paths.image('editors/charter/strumline-info-bg')); strumlineInfoBG.y = 23; @@ -414,14 +386,10 @@ class Charter extends UIState { // adds grid and notes so that they're ALWAYS behind the UI add(gridBackdrop); - add(eventSecSeparator); - add(eventBeatSeparator); + add(eventsBackdrop); add(addEventSpr); add(eventsGroup); add(notesGroup); - add(topLimit); - add(bottomLimit); - add(bottomSeparator); add(selectionBox); add(strumlineInfoBG); add(strumlineAddButton); @@ -491,8 +459,8 @@ class Charter extends UIState { var length = FlxG.sound.music.getDefault(vocals).length; scrollBar.length = Conductor.getStepForTime(length); - bottomLimit.y = Conductor.getStepForTime(length) * 40; - bottomSeparator.y = bottomLimit.y-2; + gridBackdrop.bottomLimit.y = Conductor.getStepForTime(length) * 40; + eventsBackdrop.bottomSeparator.y = gridBackdrop.bottomSeparator.y = gridBackdrop.bottomLimit.y-2; } public override function beatHit(curBeat:Int) { @@ -891,9 +859,6 @@ class Charter extends UIState { if (gridBackdrop.strumlinesAmount != strumLines.members.length) updateDisplaySprites(); - eventSecSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; - eventBeatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; - // TODO: canTypeText in case an ui input element is focused if (true) { __crochet = ((60 / Conductor.bpm) * 1000); @@ -953,22 +918,7 @@ class Charter extends UIState { function updateDisplaySprites() { gridBackdrop.strumlinesAmount = strumLines.members.length; - eventSecSeparator.scale.set(20, 4); - eventSecSeparator.updateHitbox(); - - eventBeatSeparator.scale.set(10, 2); - eventBeatSeparator.updateHitbox(); - charterBG.scale.set(1 / charterCamera.zoom, 1 / charterCamera.zoom); - topLimit.scale.set(gridBackdrop.strumlinesAmount * 4 * 40, Math.ceil(FlxG.height / charterCamera.zoom)); - topLimit.updateHitbox(); - topLimit.y = -topLimit.height; - - bottomLimit.scale.set(gridBackdrop.strumlinesAmount * 4 * 40, Math.ceil(FlxG.height / charterCamera.zoom)); - bottomLimit.updateHitbox(); - - bottomSeparator.scale.set((gridBackdrop.strumlinesAmount * 4 * 40) + 20, 4); - bottomSeparator.updateHitbox(); strumlineInfoBG.scale.set(FlxG.width / charterCamera.zoom, 1); strumlineInfoBG.updateHitbox(); @@ -1244,11 +1194,11 @@ class Charter extends UIState { } function _view_showeventSecSeparator(t) { t.icon = (Options.charterShowSections = !Options.charterShowSections) ? 1 : 0; - eventSecSeparator.visible = gridBackdrop.sectionSeparator.visible = Options.charterShowSections; + eventsBackdrop.eventSecSeparator.visible = gridBackdrop.sectionSeparator.visible = Options.charterShowSections; } function _view_showeventBeatSeparator(t) { t.icon = (Options.charterShowBeats = !Options.charterShowBeats) ? 1 : 0; - eventBeatSeparator.visible = gridBackdrop.beatSeparator.visible = Options.charterShowBeats; + eventsBackdrop.eventBeatSeparator.visible = gridBackdrop.beatSeparator.visible = Options.charterShowBeats; } inline function _note_addsustain(t) diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index efd536da..d365cdcc 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -7,6 +7,11 @@ import flixel.addons.display.FlxBackdrop; class CharterBackdrop extends FlxBackdrop { public var strumlinesAmount:Int = 1; + public var topLimit:FlxSprite; + public var topSeparator:FlxSprite; + public var bottomLimit:FlxSprite; + public var bottomSeparator:FlxSprite; + public var conductorFollowerSpr:FlxSprite; public var beatSeparator:FlxBackdrop; public var sectionSeparator:FlxBackdrop; @@ -44,6 +49,31 @@ class CharterBackdrop extends FlxBackdrop { sep.updateHitbox(); } + bottomSeparator = new FlxSprite(0,-2); + bottomSeparator.makeGraphic(1, 1, -1); + bottomSeparator.alpha = 0.5; + bottomSeparator.scrollFactor.set(1, 1); + bottomSeparator.scale.set(4 * 40, 4); + bottomSeparator.updateHitbox(); + + topSeparator = new FlxSprite(0, -2); + topSeparator.makeGraphic(1, 1, -1); + topSeparator.alpha = 0.5; + topSeparator.scrollFactor.set(1, 1); + topSeparator.scale.set(4 * 40, 4); + topSeparator.updateHitbox(); + + // Limits + topLimit = new FlxSprite(); + topLimit.makeGraphic(1, 1, -1); + topLimit.color = 0xFF888888; + topLimit.blend = MULTIPLY; + + bottomLimit = new FlxSprite(); + bottomLimit.makeGraphic(1, 1, -1); + bottomLimit.color = 0xFF888888; + bottomLimit.blend = MULTIPLY; + // Follower conductorFollowerSpr = new FlxSprite(0, 0).makeGraphic(1, 1, -1); conductorFollowerSpr.scale.set(4 * 40, 4); @@ -69,6 +99,29 @@ class CharterBackdrop extends FlxBackdrop { if (sep.visible) sep.draw(); } + topLimit.x = this.x; + topLimit.cameras = this.cameras; + + topLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); + topLimit.updateHitbox(); + topLimit.y = -topLimit.height; + topLimit.draw(); + + bottomLimit.x = this.x; + bottomLimit.cameras = this.cameras; + + bottomLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); + bottomLimit.updateHitbox(); + bottomLimit.draw(); + + topSeparator.x = this.x; + topSeparator.cameras = this.cameras; + if (!sectionSeparator.visible) topSeparator.draw(); + + bottomSeparator.x = this.x; + bottomSeparator.cameras = this.cameras; + bottomSeparator.draw(); + conductorFollowerSpr.x = this.x; conductorFollowerSpr.cameras = this.cameras; if (conductorFollowerSpr.visible) conductorFollowerSpr.draw(); @@ -95,4 +148,76 @@ class CharterBackdropDummy extends UISprite { @:privateAccess __lastDrawCameras = [for(c in cameras) c]; } +} + +class EventBackdrop extends FlxBackdrop { + public var eventBeatSeparator:FlxBackdrop; + public var eventSecSeparator:FlxBackdrop; + + public var topSeparator:FlxSprite; + public var bottomSeparator:FlxSprite; + + public function new() { + super(Paths.image('editors/charter/events-grid'), Y, 0, 0); + alpha = 0.9; + + // Separators + eventSecSeparator = new FlxBackdrop(null, Y, 0, 0); + eventSecSeparator.y = -2; + eventSecSeparator.visible = Options.charterShowSections; + + eventBeatSeparator = new FlxBackdrop(null, Y, 0, 0); + eventBeatSeparator.y = -1; + eventBeatSeparator.visible = Options.charterShowBeats; + + for(sep in [eventSecSeparator, eventBeatSeparator]) { + sep.makeGraphic(1, 1, -1); + sep.alpha = 0.5; + sep.scrollFactor.set(1, 1); + } + + eventSecSeparator.scale.set(20, 4); + eventSecSeparator.updateHitbox(); + + eventBeatSeparator.scale.set(10, 2); + eventBeatSeparator.updateHitbox(); + + bottomSeparator = new FlxSprite(0,-2); + bottomSeparator.makeGraphic(1, 1, -1); + bottomSeparator.alpha = 0.5; + bottomSeparator.scrollFactor.set(1, 1); + bottomSeparator.scale.set(20, 4); + bottomSeparator.updateHitbox(); + + topSeparator = new FlxSprite(0, -2); + topSeparator.makeGraphic(1, 1, -1); + topSeparator.alpha = 0.5; + topSeparator.scrollFactor.set(1, 1); + topSeparator.scale.set(20, 4); + topSeparator.updateHitbox(); + + } + + public override function draw() { + super.draw(); + + eventSecSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; + eventBeatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; + + eventSecSeparator.cameras = cameras; + eventSecSeparator.x = (x+width) - 20; + if (eventSecSeparator.visible) eventSecSeparator.draw(); + + eventBeatSeparator.cameras = cameras; + eventBeatSeparator.x = (x+width) - 10; + if (eventBeatSeparator.visible) eventBeatSeparator.draw(); + + topSeparator.x = (x+width) - 20; + topSeparator.cameras = this.cameras; + if (!eventSecSeparator.visible) topSeparator.draw(); + + bottomSeparator.x = (x+width) - 20; + bottomSeparator.cameras = this.cameras; + bottomSeparator.draw(); + } } \ No newline at end of file From cb1c334215332e1589e0c5f422c7227df6930224 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 26 Aug 2023 13:12:34 -0700 Subject: [PATCH 09/72] Change how notes are rendered in charter --- source/funkin/editors/charter/Charter.hx | 3 +-- source/funkin/editors/charter/CharterBackdrop.hx | 8 ++++++++ source/funkin/editors/charter/CharterNote.hx | 13 ++++++++----- source/funkin/editors/charter/CharterNoteGroup.hx | 12 ++++++++---- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 5d9d3c4d..e5aa923b 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -340,6 +340,7 @@ class Charter extends UIState { add(charterBG); gridBackdrop = new CharterBackdrop(); + gridBackdrop.notesGroup = this.notesGroup; eventsBackdrop = new EventBackdrop(); eventsBackdrop.x = -eventsBackdrop.width; @@ -430,11 +431,9 @@ class Charter extends UIState { vocals = FlxG.sound.load(Paths.voices(__song, __diff)); vocals.group = FlxG.sound.defaultMusicGroup; - trace("generating notes..."); for(strL in PlayState.SONG.strumLines) createStrumline(strumLines.members.length, strL, false); - trace("generating events..."); var __last:CharterEvent = null; var __lastTime:Float = Math.NaN; for(e in PlayState.SONG.events) { diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index d365cdcc..8c66ce43 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -16,6 +16,8 @@ class CharterBackdrop extends FlxBackdrop { public var beatSeparator:FlxBackdrop; public var sectionSeparator:FlxBackdrop; + public var notesGroup:CharterNoteGroup; + public function new() { super(null, Y, 0, 0); @@ -102,6 +104,12 @@ class CharterBackdrop extends FlxBackdrop { topLimit.x = this.x; topLimit.cameras = this.cameras; + // Draw notes + notesGroup.forEach((n) -> { + if(n.exists && n.visible && (Math.floor(n.id/4) == _)) + n.draw(); + }); + topLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); topLimit.updateHitbox(); topLimit.y = -topLimit.height; diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index 1fa9d296..b05ad1db 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -53,17 +53,20 @@ class CharterNote extends UISprite implements ICharterSelectable { public var step:Float; - public var realId:Int; - @:isVar public var id(get, set):Int; public var susLength:Float; public var type:Int; + + public var realId:Int; + @:isVar public var id(get, set):Int; function set_id(d:Int) { strumLine = Charter.instance.strumLines.members[Math.floor(d / 4)]; - id = d % 4; realId = d; - return id; + return id = d % 4; } - function get_id() return id + 4 * Charter.instance.strumLines.members.indexOf(strumLine); + + function get_id():Int + return id + 4 * Charter.instance.strumLines.members.indexOf(strumLine); + public function updatePos(step:Float, id:Int, susLength:Float = 0, type:Int = 0) { this.step = step; this.id = id; diff --git a/source/funkin/editors/charter/CharterNoteGroup.hx b/source/funkin/editors/charter/CharterNoteGroup.hx index 8478daa9..60dd393f 100644 --- a/source/funkin/editors/charter/CharterNoteGroup.hx +++ b/source/funkin/editors/charter/CharterNoteGroup.hx @@ -7,6 +7,7 @@ class CharterNoteGroup extends FlxTypedGroup { var i:Int = 0; var max:Float = 0; var __currentlyLooping:Bool = false; + var __autoDraw:Bool = false; public override function forEach(noteFunc:CharterNote->Void, recursive:Bool = false) { __loopSprite = null; @@ -54,10 +55,13 @@ class CharterNoteGroup extends FlxTypedGroup { @:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras; @:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras; - forEach((n) -> { - if(n.exists && n.visible) - n.draw(); - }); + if (__autoDraw) { + forEach((n) -> { + if(n.exists && n.visible) + n.draw(); + }); + } + @:privateAccess FlxCamera._defaultCameras = oldDefaultCameras; } From 240351798987912e23ea172acc06a560851ed620 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:21:21 -0700 Subject: [PATCH 10/72] sdaifhagf strumlines draggable smoth --- source/funkin/editors/charter/Charter.hx | 13 +++-- .../funkin/editors/charter/CharterBackdrop.hx | 6 ++- source/funkin/editors/charter/CharterEvent.hx | 11 +++- .../editors/charter/CharterEventGroup.hx | 14 ++++- source/funkin/editors/charter/CharterNote.hx | 13 +++-- .../editors/charter/CharterStrumLineGroup.hx | 53 +++++++++++++++++++ .../editors/charter/CharterStrumline.hx | 23 +------- 7 files changed, 96 insertions(+), 37 deletions(-) create mode 100644 source/funkin/editors/charter/CharterStrumLineGroup.hx diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index e5aa923b..8a60889a 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -62,7 +62,7 @@ class Charter extends UIState { /** * ACTUAL CHART DATA */ - public var strumLines:FlxTypedGroup = new FlxTypedGroup(); + public var strumLines:CharterStrumLineGroup = new CharterStrumLineGroup(); public var notesGroup:CharterNoteGroup = new CharterNoteGroup(); public var eventsGroup:CharterEventGroup = new CharterEventGroup(); @@ -345,6 +345,7 @@ class Charter extends UIState { eventsBackdrop = new EventBackdrop(); eventsBackdrop.x = -eventsBackdrop.width; eventsBackdrop.cameras = [charterCamera]; + eventsGroup.eventsBackdrop = eventsBackdrop; add(gridBackdropDummy = new CharterBackdropDummy(gridBackdrop)); selectionBox = new UISliceSprite(0, 0, 2, 2, 'editors/ui/selection'); @@ -546,7 +547,7 @@ class Charter extends UIState { if (FlxG.mouse.pressed) { selection.loop(function (n:CharterNote) { n.setPosition(n.id * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); - n.dragging = true; + n.snappedToStrumline = false; n.cursor = HAND; }, function (e:CharterEvent) { e.y = e.step * 40 + (mousePos.y - dragStartPos.y) - 17; @@ -571,7 +572,7 @@ class Charter extends UIState { for (s in selection) { if (!s.draggable) continue; s.handleDrag(changePoint); - if (s is CharterNote) cast(s, CharterNote).dragging = false; + if (s is CharterNote) cast(s, CharterNote).snappedToStrumline = true; if (s is UISprite) cast(s, UISprite).cursor = BUTTON; } sortNotes(); @@ -598,6 +599,7 @@ class Charter extends UIState { if (FlxG.mouse.justReleased) { if (selection.length > 1) { + for (n in selection) n.selected = false; selection = []; // clear selection } else { if (mouseOnGrid) { @@ -619,7 +621,6 @@ class Charter extends UIState { noteHovered = true; break; } - gridActionType = noteHovered ? DRAG : INVALID_DRAG; } } @@ -630,6 +631,7 @@ class Charter extends UIState { } } addEventSpr.selectable = !selectionBox.visible; + if (gridActionType == NONE && mousePos.x < 0 && mousePos.x > -addEventSpr.bWidth) { addEventSpr.incorporeal = false; addEventSpr.sprAlpha = lerp(addEventSpr.sprAlpha, 0.75, 0.25); @@ -906,9 +908,6 @@ class Charter extends UIState { updateDisplaySprites(); WindowTitle.prefix = undos.unsaved ? "* " : ""; - strumLines.sort(function(o, a, b) return FlxSort.byValues(o, a.x - 80, b.x - 80), -1); - for (it=>i in strumLines.members) - if (!i.dragging) i.x = CoolUtil.fpsLerp(i.x, 160 * it, 0.3); } public static var startTime:Float = 0; diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index 8c66ce43..1bc937b3 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -87,7 +87,7 @@ class CharterBackdrop extends FlxBackdrop { for(_ in 0...strumlinesAmount) { if (Charter.instance.strumLines.members[_] != null) { x = Charter.instance.strumLines.members[_].x; - alpha = Charter.instance.strumLines.members[_].strumLine.visible ? 1 : 0.4; + alpha = Charter.instance.strumLines.members[_].strumLine.visible ? 0.9 : 0.4; } else alpha = 0.9; sectionSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; @@ -106,8 +106,10 @@ class CharterBackdrop extends FlxBackdrop { // Draw notes notesGroup.forEach((n) -> { - if(n.exists && n.visible && (Math.floor(n.id/4) == _)) + if(n.exists && n.visible && (Math.floor(n.id/4) == _)) { + n.cameras = cameras; n.draw(); + } }); topLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index aa593a50..7f544fc6 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -3,8 +3,8 @@ package funkin.editors.charter; import funkin.editors.charter.Charter.ICharterSelectable; import flixel.math.FlxPoint; import funkin.game.Character; -import funkin.backend.system.Conductor; import funkin.game.HealthIcon; +import funkin.editors.charter.CharterBackdrop.EventBackdrop; import funkin.backend.chart.ChartData.ChartEvent; class CharterEvent extends UISliceSprite implements ICharterSelectable { @@ -15,6 +15,9 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { public var selected:Bool = false; public var draggable:Bool = true; + public var eventsBackdrop:EventBackdrop; + public var snappedToGrid:Bool = true; + public function new(step:Float, ?events:Array) { super(-100, (step * 40) - 17, 100, 34, 'editors/charter/event-spr'); this.step = step; @@ -25,6 +28,10 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { public override function update(elapsed:Float) { super.update(elapsed); + + if (snappedToGrid && eventsBackdrop != null) + x = eventsBackdrop.x + eventsBackdrop.width - (bWidth = 37 + (icons.length * 22)); + for(k=>i in icons) { i.follow(this, (k * 22) + 30 - (i.width / 2), (bHeight - i.height) / 2); } @@ -100,6 +107,6 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { break; } - x = -(bWidth = 37 + (icons.length * 22)); + x = (snappedToGrid && eventsBackdrop != null ? eventsBackdrop.x : 0) - (bWidth = 37 + (icons.length * 22)); } } \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterEventGroup.hx b/source/funkin/editors/charter/CharterEventGroup.hx index 90719fec..e28ac29a 100644 --- a/source/funkin/editors/charter/CharterEventGroup.hx +++ b/source/funkin/editors/charter/CharterEventGroup.hx @@ -1,3 +1,15 @@ package funkin.editors.charter; -class CharterEventGroup extends FlxTypedGroup {} \ No newline at end of file +import funkin.editors.charter.CharterBackdrop.EventBackdrop; + +class CharterEventGroup extends FlxTypedGroup { + public var eventsBackdrop:EventBackdrop; + + public override function draw() { + for (event in members) { + event.eventsBackdrop = eventsBackdrop; + event.snappedToGrid = true; + } + super.draw(); + } +} \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index b05ad1db..210bdede 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -22,8 +22,10 @@ class CharterNote extends UISprite implements ICharterSelectable { public var selected:Bool = false; public var draggable:Bool = true; - public var dragging:Bool = false; + + public var snappedToStrumline:Bool = true; public var strumLine:CharterStrumline = null; + public function new() { super(); antialiasing = true; @@ -34,8 +36,6 @@ class CharterNote extends UISprite implements ICharterSelectable { cursor = BUTTON; - //canBeHovered = false; - moves = false; sustainSpr = new FlxSprite(10, 40); @@ -60,6 +60,8 @@ class CharterNote extends UISprite implements ICharterSelectable { @:isVar public var id(get, set):Int; function set_id(d:Int) { strumLine = Charter.instance.strumLines.members[Math.floor(d / 4)]; + if (strumLine != null) + alpha = strumLine.strumLine.visible ? 1 : 0.4; realId = d; return id = d % 4; } @@ -125,7 +127,7 @@ class CharterNote extends UISprite implements ICharterSelectable { var __passed:Bool = false; public override function update(elapsed:Float) { super.update(elapsed); - if (!dragging) x = (strumLine != null ? strumLine.button.x : 0) + (id % 4) * 40; + if(sustainSpr.exists) sustainSpr.follow(this, 15, 20); @@ -165,6 +167,9 @@ class CharterNote extends UISprite implements ICharterSelectable { } public override function draw() { + if (snappedToStrumline) + x = (strumLine != null ? strumLine.button.x : 0) + (id % 4) * 40; + drawMembers(); drawSuper(); } diff --git a/source/funkin/editors/charter/CharterStrumLineGroup.hx b/source/funkin/editors/charter/CharterStrumLineGroup.hx new file mode 100644 index 00000000..42ee9773 --- /dev/null +++ b/source/funkin/editors/charter/CharterStrumLineGroup.hx @@ -0,0 +1,53 @@ +package funkin.editors.charter; + +import funkin.backend.chart.EventsData; +import flixel.util.FlxSort; + +class CharterStrumLineGroup extends FlxTypedGroup { + var __pastStrumlines:Array; + var draggingObj:CharterStrumline = null; + var draggingOffset:Float = 0; + + public override function update(elapsed:Float) { + super.update(elapsed); + + for (strumLine in members) { + if (FlxG.mouse.overlaps(strumLine.healthIcon) && FlxG.mouse.justPressed) { + draggingObj = strumLine; + strumLine.dragging = true; + + draggingOffset = FlxG.mouse.x - strumLine.button.x; + __pastStrumlines = members.copy(); + break; + } + } + + if (draggingObj != null) + draggingObj.x = FlxG.mouse.x - draggingOffset; + + + this.sort(function(o, a, b) return FlxSort.byValues(o, a.x, b.x), -1); + for (i=>strum in members) + if (!strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.3); + + Charter.instance.eventsBackdrop.x = members[0].button.x - Charter.instance.eventsBackdrop.width; + + if (FlxG.mouse.justReleased && draggingObj != null) { + draggingObj.dragging = false; + draggingObj = null; + + // Fix Events that use strumline param + for (i in Charter.instance.eventsGroup.members) { + for (j in i.events) { + var paramTypes:Array = EventsData.getEventParams(j.name); + for (i => param in paramTypes) { + if (param.type != TStrumLine) continue; + j.params[i] = Charter.instance.strumLines.members.indexOf(__pastStrumlines[j.params[i]]); + } + } + } + + __pastStrumlines = null; + } + } +} \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx index 05a65e81..90f0fe05 100644 --- a/source/funkin/editors/charter/CharterStrumline.hx +++ b/source/funkin/editors/charter/CharterStrumline.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import funkin.backend.chart.EventsData; import funkin.game.Character; import funkin.editors.ui.UIContextMenu.UIContextMenuOption; import funkin.editors.ui.UITopMenu.UITopMenuButton; @@ -38,32 +39,12 @@ class CharterStrumline extends UISprite { button = new CharterStrumlineButton(this); members.push(button); } - var __pastStrumlines:Array; + public override function update(elapsed:Float) { if (healthIcon != null) healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, 50); button.follow(this, 0, 95); super.update(elapsed); - if (FlxG.mouse.overlaps(healthIcon) && FlxG.mouse.justPressed) { - dragging = true; - trace(__pastStrumlines = Charter.instance.strumLines.members.copy()); - } - if (dragging) x = FlxG.mouse.x - 80; - if (FlxG.mouse.justReleased && dragging) { - dragging = false; - /*if (FlxG.keys.pressed.ALT) { - for (i in Charter.instance.notesGroup.members) { - trace(i.realId); - } - }*/ - for (i in Charter.instance.eventsGroup.members) { - for (j in i.events) - if (j.name == "Camera Movement" && !FlxG.keys.pressed.SHIFT) - j.params[0] = Charter.instance.strumLines.members.indexOf(__pastStrumlines[j.params[0]]); - i.refreshEventIcons(); - } - - } } public function updateInfo() { From 857904cba8472cb6838ac728b63b75e1a22186ee Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:08:39 +0300 Subject: [PATCH 11/72] finally fixed offsets in charter --- source/funkin/editors/charter/Charter.hx | 12 ++++++------ source/funkin/options/categories/GameplayOptions.hx | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 8a60889a..b019bbc9 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -362,7 +362,7 @@ class Charter extends UIState { scrollBar.cameras = [uiCamera]; scrollBar.onChange = function(v) { if (!FlxG.sound.music.playing) - Conductor.songPosition = Conductor.getTimeForStep(v); + Conductor.songPosition = Conductor.getTimeForStep(v) + Conductor.songOffset; }; uiGroup.add(scrollBar); @@ -874,7 +874,7 @@ class Charter extends UIState { } } else { if (!FlxG.sound.music.playing) { - Conductor.songPosition -= __crochet * FlxG.mouse.wheel; + Conductor.songPosition -= (__crochet * FlxG.mouse.wheel) - Conductor.songOffset; } } } @@ -1139,7 +1139,7 @@ class Charter extends UIState { FlxG.state.openSubState(new MetaDataScreen(PlayState.SONG.meta)); function _playback_play(_) { - if (Conductor.songPosition >= FlxG.sound.music.getDefault(vocals).length) return; + if (Conductor.songPosition >= FlxG.sound.music.getDefault(vocals).length - Conductor.songOffset) return; if (FlxG.sound.music.playing) { FlxG.sound.music.pause(); @@ -1147,7 +1147,7 @@ class Charter extends UIState { } else { FlxG.sound.music.play(); vocals.play(); - vocals.time = FlxG.sound.music.time = Conductor.songPosition; + vocals.time = FlxG.sound.music.time = Conductor.songPosition + Conductor.songOffset * 2; } } @@ -1164,11 +1164,11 @@ class Charter extends UIState { } function _playback_back(_) { if (FlxG.sound.music.playing) return; - Conductor.songPosition -= Conductor.beatsPerMesure * __crochet; + Conductor.songPosition -= Conductor.songOffset - (Conductor.beatsPerMesure * __crochet); } function _playback_forward(_) { if (FlxG.sound.music.playing) return; - Conductor.songPosition += Conductor.beatsPerMesure * __crochet; + Conductor.songPosition += (Conductor.beatsPerMesure * __crochet) + Conductor.songOffset; } function _playback_start(_) { if (FlxG.sound.music.playing) return; diff --git a/source/funkin/options/categories/GameplayOptions.hx b/source/funkin/options/categories/GameplayOptions.hx index 397b8069..8adaabce 100644 --- a/source/funkin/options/categories/GameplayOptions.hx +++ b/source/funkin/options/categories/GameplayOptions.hx @@ -43,9 +43,9 @@ class GameplayOptions extends OptionsScreen { FlxG.camera.zoom += 0.03; __lastBeat = Conductor.curBeat; } - if (__lastSongBeat != Math.floor(Conductor.getStepForTime(FlxG.sound.music.time / 2) / Conductor.stepsPerBeat)) { + if (__lastSongBeat != Math.floor(Conductor.getStepForTime(FlxG.sound.music.time) / Conductor.stepsPerBeat)) { __metronome.replay(); - __lastSongBeat = Math.floor(Conductor.getStepForTime(FlxG.sound.music.time / 2) / Conductor.stepsPerBeat); + __lastSongBeat = Math.floor(Conductor.getStepForTime(FlxG.sound.music.time) / Conductor.stepsPerBeat); } } else FlxG.sound.music.volume = 1; From 4621e34a483764f40e5acad2868ae3da888c67b5 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:31:03 +0300 Subject: [PATCH 12/72] minor fix --- source/funkin/editors/charter/Charter.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index b019bbc9..67208022 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1164,11 +1164,11 @@ class Charter extends UIState { } function _playback_back(_) { if (FlxG.sound.music.playing) return; - Conductor.songPosition -= Conductor.songOffset - (Conductor.beatsPerMesure * __crochet); + Conductor.songPosition -= (Conductor.beatsPerMesure * __crochet); } function _playback_forward(_) { if (FlxG.sound.music.playing) return; - Conductor.songPosition += (Conductor.beatsPerMesure * __crochet) + Conductor.songOffset; + Conductor.songPosition += (Conductor.beatsPerMesure * __crochet); } function _playback_start(_) { if (FlxG.sound.music.playing) return; From 1c9f8c2f59802d34439dd4aa3ce2a50a83adebd4 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:16:53 -0700 Subject: [PATCH 13/72] bug fixes/lock --- .../images/editors/charter/drag-strumline.png | Bin 0 -> 129 bytes source/funkin/editors/charter/Charter.hx | 14 +++- .../funkin/editors/charter/CharterBackdrop.hx | 19 ++--- .../editors/charter/CharterStrumLineGroup.hx | 72 +++++++++++++----- .../editors/charter/CharterStrumline.hx | 46 +++++++++-- .../charter/CharterStrumlineExtraButton.hx | 5 +- source/funkin/editors/ui/UIState.hx | 7 ++ 7 files changed, 120 insertions(+), 43 deletions(-) create mode 100644 assets/images/editors/charter/drag-strumline.png diff --git a/assets/images/editors/charter/drag-strumline.png b/assets/images/editors/charter/drag-strumline.png new file mode 100644 index 0000000000000000000000000000000000000000..9fb8fa5ef1208549c02d90da164a002241fadafc GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^20+Zi!3HE%cG(32DaPU;cPEB*=VV?2Io6&ojv*eM z$q5pA59~#FObgv+C~Q)4b33M}e6Ho)VMT5>?@0>bH6lC~5;>kpTSTOa5;mxC79DNZ aVPFtEYA { var draggingObj:CharterStrumline = null; var draggingOffset:Float = 0; - public override function update(elapsed:Float) { - super.update(elapsed); + public var draggable:Bool = false; + public override function update(elapsed:Float) { + var mousePos = FlxG.mouse.getWorldPosition(cameras[0], FlxPoint.get()); for (strumLine in members) { - if (FlxG.mouse.overlaps(strumLine.healthIcon) && FlxG.mouse.justPressed) { + strumLine.draggable = draggable; + if (draggable && UIState.state.isOverlapping(strumLine.draggingSprite, @:privateAccess strumLine.draggingSprite.__rect) && FlxG.mouse.justPressed) { draggingObj = strumLine; strumLine.dragging = true; - draggingOffset = FlxG.mouse.x - strumLine.button.x; + draggingOffset = mousePos.x - strumLine.button.x; __pastStrumlines = members.copy(); break; } } if (draggingObj != null) - draggingObj.x = FlxG.mouse.x - draggingOffset; - + draggingObj.x = mousePos.x - draggingOffset; this.sort(function(o, a, b) return FlxSort.byValues(o, a.x, b.x), -1); for (i=>strum in members) if (!strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.3); - Charter.instance.eventsBackdrop.x = members[0].button.x - Charter.instance.eventsBackdrop.width; + if (Charter.instance.eventsBackdrop != null) + Charter.instance.eventsBackdrop.x = members[0].button.x - Charter.instance.eventsBackdrop.width; + if (Charter.instance.strumlineLockButton != null) + Charter.instance.strumlineLockButton.x = members[0].x - (40*4); + if (Charter.instance.strumlineAddButton != null) + Charter.instance.strumlineAddButton.x = members[members.length-1].x + (40*4); - if (FlxG.mouse.justReleased && draggingObj != null) { - draggingObj.dragging = false; - draggingObj = null; + if ((FlxG.mouse.justReleased || !draggable) && draggingObj != null) + finishDrag(); - // Fix Events that use strumline param - for (i in Charter.instance.eventsGroup.members) { - for (j in i.events) { - var paramTypes:Array = EventsData.getEventParams(j.name); - for (i => param in paramTypes) { - if (param.type != TStrumLine) continue; - j.params[i] = Charter.instance.strumLines.members.indexOf(__pastStrumlines[j.params[i]]); - } + mousePos.put(); + + super.update(elapsed); + } + + inline function finishDrag() { + draggingObj.dragging = false; + draggingObj = null; + + // Fix Events that use strumline param + for (i in Charter.instance.eventsGroup.members) { + for (j in i.events) { + var paramTypes:Array = EventsData.getEventParams(j.name); + for (i => param in paramTypes) { + if (param.type != TStrumLine) continue; + j.params[i] = members.indexOf(__pastStrumlines[j.params[i]]); } } - - __pastStrumlines = null; } + + __pastStrumlines = null; + } + + override function draw() @:privateAccess { + var i:Int = 0; + var basic:FlxBasic = null; + + var oldDefaultCameras = FlxCamera._defaultCameras; + if (cameras != null) + FlxCamera._defaultCameras = cameras; + + while (i < length) + { + basic = members[i++]; + if (basic != null && basic != draggingObj && basic.exists && basic.visible) + basic.draw(); + } + if (draggingObj != null) draggingObj.draw(); + + FlxCamera._defaultCameras = oldDefaultCameras; } } \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx index 90f0fe05..31636780 100644 --- a/source/funkin/editors/charter/CharterStrumline.hx +++ b/source/funkin/editors/charter/CharterStrumline.hx @@ -9,11 +9,13 @@ import funkin.backend.chart.ChartData.ChartStrumLine; class CharterStrumline extends UISprite { public var strumLine:ChartStrumLine; - public var hitsounds:Bool = true; + public var draggingSprite:UISprite; public var healthIcon:HealthIcon; public var button:CharterStrumlineButton; + + public var draggable:Bool = false; public var dragging:Bool = false; public var curMenu:UIContextMenu = null; @@ -28,22 +30,48 @@ class CharterStrumline extends UISprite { var icon = Character.getIconFromCharName(strumLine.characters != null ? strumLine.characters[0] : null); healthIcon = new HealthIcon(icon); - healthIcon.scale.set(80 / 150, 80 / 150); + healthIcon.scale.set((80 - (draggable ? 21 : 0)) / 150, (80 - (draggable ? 21 : 0)) / 150); healthIcon.updateHitbox(); - if(strumLine.visible == null) - strumLine.visible = true; + healthIcon.y = draggable ? 29 : 7; + + if(strumLine.visible == null) strumLine.visible = true; healthIcon.alpha = strumLine.visible ? 1 : 0.4; members.push(healthIcon); + draggingSprite = new UISprite(); + draggingSprite.loadGraphic(Paths.image("editors/charter/drag-strumline")); + draggingSprite.alpha = 0.4; + draggingSprite.y = 9; + draggingSprite.antialiasing = true; + draggingSprite.cursor = BUTTON; + members.push(draggingSprite); + button = new CharterStrumlineButton(this); members.push(button); } public override function update(elapsed:Float) { - if (healthIcon != null) - healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, 50); + if (FlxG.keys.justPressed.K) draggable = !draggable; + if (healthIcon != null) { + var healthScale:Float = FlxMath.lerp(healthIcon.scale.x, (80 - (draggable ? 21 : 0)) / 150, 1/20); + healthIcon.scale.set(healthScale, healthScale); + healthIcon.updateHitbox(); + + healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, FlxMath.lerp(healthIcon.y - y, draggable ? 29 : 7, 1/20)); + } + + var dragScale:Float = FlxMath.lerp(draggingSprite.scale.x, draggable ? 1 : 0.8, 1/16); + draggingSprite.scale.set(dragScale, dragScale); + draggingSprite.updateHitbox(); + + draggingSprite.follow(this, (160/2) - (draggingSprite.width/2), FlxMath.lerp(draggingSprite.y - y, draggable ? 9 : 6, 1/12)); + draggingSprite.alpha = FlxMath.lerp(draggingSprite.alpha, draggable ? 0.4 : 0, 1/12); button.follow(this, 0, 95); + + draggingSprite.selectable = draggable; + + UIState.state.updateSpriteRect(draggingSprite); super.update(elapsed); } @@ -54,8 +82,10 @@ class CharterStrumline extends UISprite { var icon = Character.getIconFromCharName(strumLine.characters != null ? strumLine.characters[0] : null); healthIcon = new HealthIcon(icon); - healthIcon.scale.set(80 / 150, 80 / 150); + healthIcon.scale.set((80 - (draggable ? 21 : 0)) / 150, (80 - (draggable ? 21 : 0)) / 150); healthIcon.updateHitbox(); + healthIcon.y = draggable ? 29 : 7; + healthIcon.alpha = strumLine.visible ? 1 : 0.4; members.push(healthIcon); } @@ -72,7 +102,7 @@ class CharterStrumlineButton extends UITopMenuButton { public override function update(elapsed:Float) { super.update(elapsed); - alpha = FlxMath.lerp(1/3, 1, alpha); // so that instead of 0% it is 33% visible + alpha = FlxMath.lerp(1/20, 1, alpha); // so that instead of 0% it is 33% visible } public override function openContextMenu() { diff --git a/source/funkin/editors/charter/CharterStrumlineExtraButton.hx b/source/funkin/editors/charter/CharterStrumlineExtraButton.hx index f19e4c30..471aebe5 100644 --- a/source/funkin/editors/charter/CharterStrumlineExtraButton.hx +++ b/source/funkin/editors/charter/CharterStrumlineExtraButton.hx @@ -35,10 +35,7 @@ class CharterStrumlineExtraButton extends UISprite { super.update(elapsed); - button.__rect.x = button.x; - button.__rect.y = button.y; - button.__rect.width = button.width; - button.__rect.height = button.height; + UIState.state.updateSpriteRect(button); if(UIState.state.isOverlapping(button, button.__rect)) { buttonScale.set(0.85, 0.85); if (FlxG.mouse.justReleased && onClick != null) onClick(); diff --git a/source/funkin/editors/ui/UIState.hx b/source/funkin/editors/ui/UIState.hx index 9aa8cac3..4987d8fb 100644 --- a/source/funkin/editors/ui/UIState.hx +++ b/source/funkin/editors/ui/UIState.hx @@ -59,6 +59,13 @@ class UIState extends MusicBeatState { currentFocus.onTextEdit(str, start, end); } + public inline function updateSpriteRect(spr:UISprite) { + spr.__rect.x = spr.x; + spr.__rect.y = spr.y; + spr.__rect.width = spr.width; + spr.__rect.height = spr.height; + } + public function updateButtonHandler(spr:UISprite, buttonHandler:Void->Void) { spr.__rect.x = spr.x; spr.__rect.y = spr.y; From 691825af6a7ecea53b4b566f88a7435fe28cea80 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Fri, 1 Sep 2023 19:52:46 -0700 Subject: [PATCH 14/72] fix alot of issues with draggable strumlines (dragging broken af rn tho) --- source/funkin/editors/charter/Charter.hx | 111 ++++++++---------- .../funkin/editors/charter/CharterBackdrop.hx | 2 +- source/funkin/editors/charter/CharterNote.hx | 41 +++---- .../editors/charter/CharterStrumLineGroup.hx | 40 +++++-- 4 files changed, 98 insertions(+), 96 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index cfd2dbb0..b77af211 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import funkin.editors.charter.CharterStrumline; import funkin.editors.charter.CharterBackdrop.EventBackdrop; import funkin.backend.system.framerate.Framerate; import haxe.Json; @@ -553,8 +554,8 @@ class Charter extends UIState { case DRAG: if (FlxG.mouse.pressed) { selection.loop(function (n:CharterNote) { - n.setPosition(n.id * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); n.snappedToStrumline = false; + n.setPosition(n.id * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); n.cursor = HAND; }, function (e:CharterEvent) { e.y = e.step * 40 + (mousePos.y - dragStartPos.y) - 17; @@ -611,7 +612,7 @@ class Charter extends UIState { } else { if (mouseOnGrid) { var note = new CharterNote(); - note.updatePos(FlxG.keys.pressed.SHIFT ? (mousePos.y / 40) : Math.floor(mousePos.y / 40), id, 0, 0); + note.updatePos(FlxG.keys.pressed.SHIFT ? (mousePos.y / 40) : Math.floor(mousePos.y / 40), id % 4, 0, 0, strumLines.members[Std.int(id/4)]); notesGroup.add(note); selection = [note]; sortNotes(); @@ -620,7 +621,6 @@ class Charter extends UIState { } } } else if (gridBackdropDummy.hoveredByChild) { - // TODO: NOTE DRAGGING if (FlxG.mouse.pressed && (Math.abs(mousePos.x - dragStartPos.x) > 5 || Math.abs(mousePos.y - dragStartPos.y) > 5)) { var noteHovered:Bool = false; for(n in selection) @@ -741,18 +741,10 @@ class Charter extends UIState { var cStr = new CharterStrumline(strL); strumLines.insert(strumLineID, cStr); - // Push forward notes that are infront of the strumLine - for (note in notesGroup.members) { - if (Std.int(note.id / 4) >= strumLineID) - note.updatePos(note.step, note.id + 4, note.susLength, note.type); - } - - var noteOffset = (strumLines.members.indexOf(cStr)) * 4; - for(note in strL.notes) { var n = new CharterNote(); var t = Conductor.getStepForTime(note.time); - n.updatePos(t, noteOffset + note.id, Conductor.getStepForTime(note.time + note.sLen) - t, note.type); + n.updatePos(t, note.id, Conductor.getStepForTime(note.time + note.sLen) - t, note.type, cStr); notesGroup.add(n); } sortNotes(); @@ -762,45 +754,28 @@ class Charter extends UIState { } public function deleteStrumline(strumLineID:Int, addToUndo:Bool = true) { + var undoNotes:Array = []; removeStrumlineFromSelection(strumLineID); + var i = 0; + while(i < notesGroup.members.length) { + var note = notesGroup.members[i]; + if (note.strumLineID == strumLineID) { + undoNotes.push(buildNote(note)); + deleteSingleSelection(note, false); + } else i++; + } + var strL = strumLines.members[strumLineID].strumLine; strumLines.members[strumLineID].destroy(); strumLines.members.remove(strumLines.members[strumLineID]); - var deletedstrumNotes:Array = []; - // Delete this strums notes - var i = 0; // thanks yosh!!!!! (deleteNote removes a index) - while(i < notesGroup.members.length) { - var note = notesGroup.members[i]; - if (Std.int(note.id / 4) == strumLineID) { // thanks neo lol!!!!! - deletedstrumNotes.push(note); - deleteSingleSelection(note, false); - } else - i++; - } - - // Push back strumline notes that are infront - for (note in notesGroup.members) { - if (Std.int(note.id / 4) > strumLineID) - note.updatePos(note.step, note.id - 4, note.susLength, note.type); - } sortNotes(); - // Undo shit if (addToUndo) { var newStrL = Reflect.copy(strL); - newStrL.notes.clear(); + newStrL.notes = undoNotes; - for (note in deletedstrumNotes) { - var time = Conductor.getTimeForStep(note.step); - newStrL.notes.push({ - type: note.type, - time: time, - sLen: Conductor.getTimeForStep(note.step + note.susLength) - time, - id: note.id % 4 - }); - } undos.addToUndo(CDeleteStrumLine(strumLineID, newStrL)); } } @@ -819,6 +794,8 @@ class Charter extends UIState { })); } + public function orderStrumline() {} + public inline function deleteStrumlineFromData(strL:ChartStrumLine) deleteStrumline(getStrumlineID(strL)); @@ -839,7 +816,7 @@ class Charter extends UIState { while(i < selection.length) { if (selection[i] is CharterNote) { var note = cast (selection[i], CharterNote); - if (Std.int(note.id / 4) == strumLineID) + if (note.strumLineID == strumLineID) selection.remove(note); else i++; } @@ -1021,7 +998,7 @@ class Charter extends UIState { for (s in selection) if (s is CharterNote) { var note:CharterNote = cast(s, CharterNote); - CNote(note.step - minStep, note.id, note.susLength, note.type); + CNote(note.step - minStep, note.id, note.strumLineID, note.susLength, note.type); } else if (s is CharterEvent) { var event = cast(s,CharterEvent); CEvent(event.step - minStep, [for (event in event.events) Reflect.copy(event)]); @@ -1035,13 +1012,13 @@ class Charter extends UIState { var sObjects:Array = []; for(c in clipboard) { switch(c) { - case CNote(step, id, sLen, type): + case CNote(step, id, strumLineID, susLength, type): var note = new CharterNote(); - note.updatePos(minStep + step + 1, id, sLen, type); + note.updatePos(minStep + step, id, susLength, type, strumLines.members[Std.int(FlxMath.bound(strumLineID, 0, strumLines.length-1))]); notesGroup.add(note); sObjects.push(note); case CEvent(step, events): - var event = new CharterEvent(minStep + step + 1, events); + var event = new CharterEvent(minStep + step, events); event.refreshEventIcons(); eventsGroup.add(event); sObjects.push(event); @@ -1064,6 +1041,8 @@ class Charter extends UIState { } function _edit_undo(_) { + if (strumLines.isDragging) return; + selection = []; var undo = undos.undo(); switch(undo) { @@ -1072,6 +1051,8 @@ class Charter extends UIState { createStrumline(strumLineID, strumLine, false); case CCreateStrumLine(strumLineID, strumLine): deleteStrumline(strumLineID, false); + case COrderStrumLine(strumLine, oldID, newID): + strumLines.orderStrumline(strumLine, oldID); case CEditStrumLine(strumLineID, oldStrumLine, newStrumLine): strumLines.members[strumLineID].strumLine = oldStrumLine; strumLines.members[strumLineID].updateInfo(); @@ -1098,6 +1079,8 @@ class Charter extends UIState { } function _edit_redo(_) { + if (strumLines.isDragging) return; + selection = []; var redo = undos.redo(); switch(redo) { @@ -1106,6 +1089,8 @@ class Charter extends UIState { deleteStrumline(strumLineID, false); case CCreateStrumLine(strumLineID, strumLine): createStrumline(strumLineID, strumLine, false); + case COrderStrumLine(strumLine, oldID, newID): + strumLines.orderStrumline(strumLine, newID); case CEditStrumLine(strumLineID, oldStrumLine, newStrumLine): strumLines.members[strumLineID].strumLine = newStrumLine; strumLines.members[strumLineID].updateInfo(); @@ -1236,12 +1221,7 @@ class Charter extends UIState { var n:CharterNote = cast(s, CharterNote); var old:Float = n.susLength; n.updatePos(n.step, n.id, Math.max(n.susLength + change, 0)); - - { - before: old, - after: n.susLength, - note: n - }; + {before: old, after: n.susLength, note: n}; } } ])); @@ -1256,6 +1236,16 @@ class Charter extends UIState { FlxG.switchState(new PlayState()); } + public inline function buildNote(note:CharterNote):ChartNote { + var time = Conductor.getTimeForStep(note.step); + return { + type: note.type, + time: time, + sLen: Conductor.getTimeForStep(note.step + note.susLength) - time, + id: note.id + }; + } + public function buildChart() { PlayState.SONG.strumLines = []; for(s in strumLines) { @@ -1263,16 +1253,8 @@ class Charter extends UIState { PlayState.SONG.strumLines.push(s.strumLine); } for(n in notesGroup.members) { - var strLineID = Std.int(n.id / 4); - if (PlayState.SONG.strumLines[strLineID] != null) { - var time = Conductor.getTimeForStep(n.step); - PlayState.SONG.strumLines[strLineID].notes.push({ - type: n.type, - time: time, - sLen: Conductor.getTimeForStep(n.step + n.susLength) - time, - id: n.id % 4 - }); - } + if (PlayState.SONG.strumLines[n.strumLineID] != null) + PlayState.SONG.strumLines[n.strumLineID].notes.push(buildNote(n)); } buildEvents(); } @@ -1297,23 +1279,24 @@ class Charter extends UIState { } public inline function hitsoundsEnabled(id:Int) - return strumLines.members[Std.int(id / 4)] != null && strumLines.members[Std.int(id / 4)].hitsounds; + return strumLines.members[id] != null && strumLines.members[id].hitsounds; } enum CharterChange { CCreateStrumLine(strumLineID:Int, strumLine:ChartStrumLine); + CEditStrumLine(strumLineID:Int, oldStrumLine:ChartStrumLine, newStrumLine:ChartStrumLine); + COrderStrumLine(strumLine:CharterStrumline, oldID:Int, newID:Int); CDeleteStrumLine(strumLineID:Int, strumLine:ChartStrumLine); CCreateSelection(selection:Selection); CDeleteSelection(selection:Selection); CSelectionDrag(selection:Selection, change:FlxPoint); - CEditStrumLine(strumLineID:Int, oldStrumLine:ChartStrumLine, newStrumLine:ChartStrumLine); CEditSustains(notes:Array); CEditEvent(event:CharterEvent, oldEvents:Array, newEvents:Array); CEditChartData(oldData:{stage:String, speed:Float}, newData:{stage:String, speed:Float}); } enum CharterCopyboardObject { - CNote(step:Float, id:Int, susLength:Float, type:Int); + CNote(step:Float, id:Int, strumLineID:Int, susLength:Float, type:Int); CEvent(step:Float, events:Array); } diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index dab36825..8b0577a4 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -107,7 +107,7 @@ class CharterBackdrop extends FlxBackdrop { // Draw notes notesGroup.forEach((n) -> { - if(n.exists && n.visible && (Math.floor(n.id/4) == _)) { + if(n.exists && n.visible) { n.cameras = cameras; n.draw(); } diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index 210bdede..311114dd 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -23,9 +23,6 @@ class CharterNote extends UISprite implements ICharterSelectable { public var selected:Bool = false; public var draggable:Bool = true; - public var snappedToStrumline:Bool = true; - public var strumLine:CharterStrumline = null; - public function new() { super(); antialiasing = true; @@ -51,29 +48,28 @@ class CharterNote extends UISprite implements ICharterSelectable { UIState.state.updateRectButtonHandler(this, __rect, onHovered); } - public var step:Float; + public var id:Int; public var susLength:Float; public var type:Int; - public var realId:Int; - @:isVar public var id(get, set):Int; - function set_id(d:Int) { - strumLine = Charter.instance.strumLines.members[Math.floor(d / 4)]; - if (strumLine != null) - alpha = strumLine.strumLine.visible ? 1 : 0.4; - realId = d; - return id = d % 4; - } + public var strumLine:CharterStrumline; + public var strumLineID(get, never):Int; + public function get_strumLineID():Int + return strumLine == null ? -1 : Charter.instance.strumLines.members.indexOf(strumLine); - function get_id():Int - return id + 4 * Charter.instance.strumLines.members.indexOf(strumLine); + public var snappedToStrumline:Bool = true; - public function updatePos(step:Float, id:Int, susLength:Float = 0, type:Int = 0) { + public var fullID(get, never):Int; // instead of %4 get fullID (for mousepos stuff) + public function get_fullID():Int + return (strumLineID * 4) + id; + + public function updatePos(step:Float, id:Int, susLength:Float = 0, type:Int = 0, ?strumLine:CharterStrumline) { this.step = step; this.id = id; this.susLength = susLength; this.type = type; + this.strumLine = strumLine; y = step * 40; sustainSpr.scale.set(10, (40 * susLength)); @@ -132,8 +128,8 @@ class CharterNote extends UISprite implements ICharterSelectable { sustainSpr.follow(this, 15, 20); if (__passed != (__passed = step < Conductor.curStepFloat)) { - alpha = __passed ? 0.6 : 1; - if (__passed && FlxG.sound.music.playing && Charter.instance.hitsoundsEnabled(id)) + alpha = (__passed ? 0.8 : 1) - (!strumLine.strumLine.visible ? .6 : 0); + if (__passed && FlxG.sound.music.playing && Charter.instance.hitsoundsEnabled(strumLineID)) Charter.instance.hitsound.replay(); } if(sustainSpr.exists) @@ -156,18 +152,15 @@ class CharterNote extends UISprite implements ICharterSelectable { } public function handleDrag(change:FlxPoint) { - var newID:Int = id + Std.int(change.y); + var newID:Int = fullID + Std.int(change.y); if (newID > ((Charter.instance.strumLines.members.length*4)-1)) newID %= 4; else if (newID < 0) newID = (Charter.instance.strumLines.members.length*4) + newID % 4; - updatePos(step + change.x, newID, susLength, type); - - Charter.instance.notesGroup.remove(this); - Charter.instance.notesGroup.add(this); + updatePos(step + change.x, newID % 4, susLength, type, Charter.instance.strumLines.members[Std.int(newID/4)]); } public override function draw() { - if (snappedToStrumline) + if (snappedToStrumline) x = (strumLine != null ? strumLine.button.x : 0) + (id % 4) * 40; drawMembers(); diff --git a/source/funkin/editors/charter/CharterStrumLineGroup.hx b/source/funkin/editors/charter/CharterStrumLineGroup.hx index 26bc806d..ec74847c 100644 --- a/source/funkin/editors/charter/CharterStrumLineGroup.hx +++ b/source/funkin/editors/charter/CharterStrumLineGroup.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import funkin.backend.chart.ChartData.ChartStrumLine; import funkin.backend.chart.EventsData; import flixel.util.FlxSort; @@ -9,6 +10,9 @@ class CharterStrumLineGroup extends FlxTypedGroup { var draggingOffset:Float = 0; public var draggable:Bool = false; + public var isDragging(get, never):Bool; + public function get_isDragging():Bool + return draggingObj != null; public override function update(elapsed:Float) { var mousePos = FlxG.mouse.getWorldPosition(cameras[0], FlxPoint.get()); @@ -29,7 +33,7 @@ class CharterStrumLineGroup extends FlxTypedGroup { this.sort(function(o, a, b) return FlxSort.byValues(o, a.x, b.x), -1); for (i=>strum in members) - if (!strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.3); + if (!strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.225); if (Charter.instance.eventsBackdrop != null) Charter.instance.eventsBackdrop.x = members[0].button.x - Charter.instance.eventsBackdrop.width; @@ -42,15 +46,38 @@ class CharterStrumLineGroup extends FlxTypedGroup { finishDrag(); mousePos.put(); - super.update(elapsed); } - inline function finishDrag() { - draggingObj.dragging = false; - draggingObj = null; + public function orderStrumline(strumLine:CharterStrumline, newID:Int) { + __pastStrumlines = members.copy(); - // Fix Events that use strumline param + members.remove(strumLine); + members.insert(newID, strumLine); + + for (i=>strum in members) + strum.x = 160 * i; + + finishDrag(false); + } + + public function finishDrag(?addToUndo:Bool = true) { + if (draggingObj != null) + draggingObj.dragging = false; + + // Undo + if (addToUndo) { + var oldID = __pastStrumlines.indexOf(draggingObj); + var newID = members.indexOf(draggingObj); + Charter.instance.undos.addToUndo(COrderStrumLine(draggingObj, oldID, newID)); + } + + + draggingObj = null; + fixEvents(); + } + + public inline function fixEvents() { for (i in Charter.instance.eventsGroup.members) { for (j in i.events) { var paramTypes:Array = EventsData.getEventParams(j.name); @@ -60,7 +87,6 @@ class CharterStrumLineGroup extends FlxTypedGroup { } } } - __pastStrumlines = null; } From 9a0310c721331dc9dca3bd3bf77c40252cdfe242 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Fri, 1 Sep 2023 23:31:57 -0700 Subject: [PATCH 15/72] change sorting blah blah blah --- source/funkin/editors/charter/Charter.hx | 16 ---------------- source/funkin/editors/charter/CharterBackdrop.hx | 1 - .../funkin/editors/charter/CharterEventGroup.hx | 16 ++++++++++++++++ source/funkin/editors/charter/CharterNote.hx | 2 +- .../funkin/editors/charter/CharterNoteGroup.hx | 15 ++++++++++++++- .../editors/charter/CharterStrumLineGroup.hx | 13 +++++-------- 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index b77af211..03c9503b 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -583,7 +583,6 @@ class Charter extends UIState { if (s is CharterNote) cast(s, CharterNote).snappedToStrumline = true; if (s is UISprite) cast(s, UISprite).cursor = BUTTON; } - sortNotes(); undos.addToUndo(CSelectionDrag(selection, changePoint.clone())); changePoint.put(); @@ -615,7 +614,6 @@ class Charter extends UIState { note.updatePos(FlxG.keys.pressed.SHIFT ? (mousePos.y / 40) : Math.floor(mousePos.y / 40), id % 4, 0, 0, strumLines.members[Std.int(id/4)]); notesGroup.add(note); selection = [note]; - sortNotes(); undos.addToUndo(CCreateSelection([note])); } } @@ -678,7 +676,6 @@ class Charter extends UIState { eventsGroup.remove(event, true); event.kill(); } - sortNotes(); if (addToUndo) undos.addToUndo(CDeleteSelection([selected])); @@ -697,7 +694,6 @@ class Charter extends UIState { e.revive(); e.refreshEventIcons(); }, false); - sortNotes(); for (s in selection) if (s is CharterEvent) { @@ -723,7 +719,6 @@ class Charter extends UIState { else member++; } } - sortNotes(); for (s in selection) if (s is CharterEvent) { @@ -747,7 +742,6 @@ class Charter extends UIState { n.updatePos(t, note.id, Conductor.getStepForTime(note.time + note.sLen) - t, note.type, cStr); notesGroup.add(n); } - sortNotes(); if (addToUndo) undos.addToUndo(CCreateStrumLine(strumLineID, strL)); @@ -770,8 +764,6 @@ class Charter extends UIState { strumLines.members[strumLineID].destroy(); strumLines.members.remove(strumLines.members[strumLineID]); - sortNotes(); - if (addToUndo) { var newStrL = Reflect.copy(strL); newStrL.notes = undoNotes; @@ -822,14 +814,6 @@ class Charter extends UIState { } } } - - public inline function sortNotes() { - notesGroup.sort(function(i, n1, n2) { - if (n1.step == n2.step) - return FlxSort.byValues(FlxSort.ASCENDING, n1.id, n2.id); - return FlxSort.byValues(FlxSort.ASCENDING, n1.step, n2.step); - }); - } #end var __crochet:Float; diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdrop.hx index 8b0577a4..7b440d30 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdrop.hx @@ -105,7 +105,6 @@ class CharterBackdrop extends FlxBackdrop { topLimit.x = this.x; topLimit.cameras = this.cameras; - // Draw notes notesGroup.forEach((n) -> { if(n.exists && n.visible) { n.cameras = cameras; diff --git a/source/funkin/editors/charter/CharterEventGroup.hx b/source/funkin/editors/charter/CharterEventGroup.hx index e28ac29a..cef8913c 100644 --- a/source/funkin/editors/charter/CharterEventGroup.hx +++ b/source/funkin/editors/charter/CharterEventGroup.hx @@ -1,9 +1,18 @@ package funkin.editors.charter; import funkin.editors.charter.CharterBackdrop.EventBackdrop; +import flixel.util.FlxSort; class CharterEventGroup extends FlxTypedGroup { public var eventsBackdrop:EventBackdrop; + var __lastSort:Int = 0; + + public override function update(elapsed:Float) { + if (length != __lastSort) + sortEvents(); + + super.update(elapsed); + } public override function draw() { for (event in members) { @@ -12,4 +21,11 @@ class CharterEventGroup extends FlxTypedGroup { } super.draw(); } + + public function sortEvents() { + __lastSort = length; + this.sort(function(i, e1, e2) { + return FlxSort.byValues(FlxSort.ASCENDING, e1.step, e2.step); + }); + } } \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index 311114dd..85f7f961 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -128,7 +128,7 @@ class CharterNote extends UISprite implements ICharterSelectable { sustainSpr.follow(this, 15, 20); if (__passed != (__passed = step < Conductor.curStepFloat)) { - alpha = (__passed ? 0.8 : 1) - (!strumLine.strumLine.visible ? .6 : 0); + alpha = (__passed ? 0.6 : 1); if (__passed && FlxG.sound.music.playing && Charter.instance.hitsoundsEnabled(strumLineID)) Charter.instance.hitsound.replay(); } diff --git a/source/funkin/editors/charter/CharterNoteGroup.hx b/source/funkin/editors/charter/CharterNoteGroup.hx index 60dd393f..4051545f 100644 --- a/source/funkin/editors/charter/CharterNoteGroup.hx +++ b/source/funkin/editors/charter/CharterNoteGroup.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import flixel.util.FlxSort; import funkin.backend.system.Conductor; class CharterNoteGroup extends FlxTypedGroup { @@ -8,6 +9,7 @@ class CharterNoteGroup extends FlxTypedGroup { var max:Float = 0; var __currentlyLooping:Bool = false; var __autoDraw:Bool = false; + var __lastSort:Int = 0; public override function forEach(noteFunc:CharterNote->Void, recursive:Bool = false) { __loopSprite = null; @@ -62,7 +64,6 @@ class CharterNoteGroup extends FlxTypedGroup { }); } - @:privateAccess FlxCamera._defaultCameras = oldDefaultCameras; } @@ -70,6 +71,9 @@ class CharterNoteGroup extends FlxTypedGroup { @:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras; @:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras; + if (length != __lastSort) + sortNotes(); + forEach((n) -> { if(n.exists && n.active) n.update(elapsed); @@ -77,4 +81,13 @@ class CharterNoteGroup extends FlxTypedGroup { @:privateAccess FlxCamera._defaultCameras = oldDefaultCameras; } + + public function sortNotes() { + __lastSort = length; + this.sort(function(i, n1, n2) { + if (n1.step == n2.step) + return FlxSort.byValues(FlxSort.ASCENDING, n1.fullID, n2.fullID); + return FlxSort.byValues(FlxSort.ASCENDING, n1.step, n2.step); + }); + } } \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterStrumLineGroup.hx b/source/funkin/editors/charter/CharterStrumLineGroup.hx index ec74847c..fd7156f5 100644 --- a/source/funkin/editors/charter/CharterStrumLineGroup.hx +++ b/source/funkin/editors/charter/CharterStrumLineGroup.hx @@ -28,10 +28,11 @@ class CharterStrumLineGroup extends FlxTypedGroup { } } - if (draggingObj != null) + if (isDragging) { draggingObj.x = mousePos.x - draggingOffset; + this.sort(function(o, a, b) return FlxSort.byValues(o, a.x, b.x), -1); + } - this.sort(function(o, a, b) return FlxSort.byValues(o, a.x, b.x), -1); for (i=>strum in members) if (!strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.225); @@ -42,7 +43,7 @@ class CharterStrumLineGroup extends FlxTypedGroup { if (Charter.instance.strumlineAddButton != null) Charter.instance.strumlineAddButton.x = members[members.length-1].x + (40*4); - if ((FlxG.mouse.justReleased || !draggable) && draggingObj != null) + if ((FlxG.mouse.justReleased || !draggable) && isDragging) finishDrag(); mousePos.put(); @@ -55,14 +56,11 @@ class CharterStrumLineGroup extends FlxTypedGroup { members.remove(strumLine); members.insert(newID, strumLine); - for (i=>strum in members) - strum.x = 160 * i; - finishDrag(false); } public function finishDrag(?addToUndo:Bool = true) { - if (draggingObj != null) + if (isDragging) draggingObj.dragging = false; // Undo @@ -72,7 +70,6 @@ class CharterStrumLineGroup extends FlxTypedGroup { Charter.instance.undos.addToUndo(COrderStrumLine(draggingObj, oldID, newID)); } - draggingObj = null; fixEvents(); } From f19896505d46b0db47da27c77db40b72c6d9a5bb Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 2 Sep 2023 22:13:03 -0700 Subject: [PATCH 16/72] fix dragging --- source/funkin/editors/charter/Charter.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 03c9503b..00801a34 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -555,7 +555,7 @@ class Charter extends UIState { if (FlxG.mouse.pressed) { selection.loop(function (n:CharterNote) { n.snappedToStrumline = false; - n.setPosition(n.id * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); + n.setPosition(n.fullID * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); n.cursor = HAND; }, function (e:CharterEvent) { e.y = e.step * 40 + (mousePos.y - dragStartPos.y) - 17; From 7a11b63bb01b58765c4d2df6c5dbf89cb4ba10f5 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 2 Sep 2023 22:16:42 -0700 Subject: [PATCH 17/72] fix dragging undo when same spot --- source/funkin/editors/charter/CharterStrumLineGroup.hx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/funkin/editors/charter/CharterStrumLineGroup.hx b/source/funkin/editors/charter/CharterStrumLineGroup.hx index fd7156f5..64e629a1 100644 --- a/source/funkin/editors/charter/CharterStrumLineGroup.hx +++ b/source/funkin/editors/charter/CharterStrumLineGroup.hx @@ -67,7 +67,8 @@ class CharterStrumLineGroup extends FlxTypedGroup { if (addToUndo) { var oldID = __pastStrumlines.indexOf(draggingObj); var newID = members.indexOf(draggingObj); - Charter.instance.undos.addToUndo(COrderStrumLine(draggingObj, oldID, newID)); + if (newID != oldID) + Charter.instance.undos.addToUndo(COrderStrumLine(draggingObj, oldID, newID)); } draggingObj = null; From fe4bfe9bb14bf4518985c2a69f5c491b9d0f0d56 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 2 Sep 2023 22:49:35 -0700 Subject: [PATCH 18/72] pluh --- source/funkin/editors/charter/Charter.hx | 12 +++++++----- .../funkin/editors/charter/CharterStrumLineGroup.hx | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 00801a34..bda0e310 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -786,8 +786,6 @@ class Charter extends UIState { })); } - public function orderStrumline() {} - public inline function deleteStrumlineFromData(strL:ChartStrumLine) deleteStrumline(getStrumlineID(strL)); @@ -1035,8 +1033,10 @@ class Charter extends UIState { createStrumline(strumLineID, strumLine, false); case CCreateStrumLine(strumLineID, strumLine): deleteStrumline(strumLineID, false); - case COrderStrumLine(strumLine, oldID, newID): + case COrderStrumLine(strumLineID, oldID, newID): + var strumLine:CharterStrumline = strumLines.members[strumLineID]; strumLines.orderStrumline(strumLine, oldID); + undos.redoList[0] = COrderStrumLine(strumLines.members.indexOf(strumLine), oldID, newID); case CEditStrumLine(strumLineID, oldStrumLine, newStrumLine): strumLines.members[strumLineID].strumLine = oldStrumLine; strumLines.members[strumLineID].updateInfo(); @@ -1073,8 +1073,10 @@ class Charter extends UIState { deleteStrumline(strumLineID, false); case CCreateStrumLine(strumLineID, strumLine): createStrumline(strumLineID, strumLine, false); - case COrderStrumLine(strumLine, oldID, newID): + case COrderStrumLine(strumLineID, oldID, newID): + var strumLine:CharterStrumline = strumLines.members[strumLineID]; strumLines.orderStrumline(strumLine, newID); + undos.undoList[0] = COrderStrumLine(strumLines.members.indexOf(strumLine), oldID, newID); case CEditStrumLine(strumLineID, oldStrumLine, newStrumLine): strumLines.members[strumLineID].strumLine = newStrumLine; strumLines.members[strumLineID].updateInfo(); @@ -1269,7 +1271,7 @@ class Charter extends UIState { enum CharterChange { CCreateStrumLine(strumLineID:Int, strumLine:ChartStrumLine); CEditStrumLine(strumLineID:Int, oldStrumLine:ChartStrumLine, newStrumLine:ChartStrumLine); - COrderStrumLine(strumLine:CharterStrumline, oldID:Int, newID:Int); + COrderStrumLine(strumLineID:Int, oldID:Int, newID:Int); CDeleteStrumLine(strumLineID:Int, strumLine:ChartStrumLine); CCreateSelection(selection:Selection); CDeleteSelection(selection:Selection); diff --git a/source/funkin/editors/charter/CharterStrumLineGroup.hx b/source/funkin/editors/charter/CharterStrumLineGroup.hx index 64e629a1..a970918a 100644 --- a/source/funkin/editors/charter/CharterStrumLineGroup.hx +++ b/source/funkin/editors/charter/CharterStrumLineGroup.hx @@ -17,6 +17,7 @@ class CharterStrumLineGroup extends FlxTypedGroup { public override function update(elapsed:Float) { var mousePos = FlxG.mouse.getWorldPosition(cameras[0], FlxPoint.get()); for (strumLine in members) { + if (strumLine == null) continue; strumLine.draggable = draggable; if (draggable && UIState.state.isOverlapping(strumLine.draggingSprite, @:privateAccess strumLine.draggingSprite.__rect) && FlxG.mouse.justPressed) { draggingObj = strumLine; @@ -34,7 +35,7 @@ class CharterStrumLineGroup extends FlxTypedGroup { } for (i=>strum in members) - if (!strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.225); + if (strum != null && !strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.225); if (Charter.instance.eventsBackdrop != null) Charter.instance.eventsBackdrop.x = members[0].button.x - Charter.instance.eventsBackdrop.width; @@ -67,8 +68,7 @@ class CharterStrumLineGroup extends FlxTypedGroup { if (addToUndo) { var oldID = __pastStrumlines.indexOf(draggingObj); var newID = members.indexOf(draggingObj); - if (newID != oldID) - Charter.instance.undos.addToUndo(COrderStrumLine(draggingObj, oldID, newID)); + if (newID != oldID) Charter.instance.undos.addToUndo(COrderStrumLine(newID, oldID, newID)); } draggingObj = null; From 0d17236e3b7d0173fe2b8c0668d22ad6d2043055 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Mon, 4 Sep 2023 13:39:53 -0700 Subject: [PATCH 19/72] sexy grid layering (shitton of bug fixes) --- source/funkin/editors/charter/Charter.hx | 40 ++-- ...terBackdrop.hx => CharterBackdropGroup.hx} | 213 ++++++++++++------ source/funkin/editors/charter/CharterEvent.hx | 2 +- .../editors/charter/CharterEventGroup.hx | 2 +- source/funkin/editors/charter/CharterNote.hx | 10 +- .../editors/charter/CharterNoteGroup.hx | 17 +- 6 files changed, 171 insertions(+), 113 deletions(-) rename source/funkin/editors/charter/{CharterBackdrop.hx => CharterBackdropGroup.hx} (50%) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index bda0e310..35c1148b 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1,14 +1,14 @@ package funkin.editors.charter; import funkin.editors.charter.CharterStrumline; -import funkin.editors.charter.CharterBackdrop.EventBackdrop; +import funkin.editors.charter.CharterBackdropGroup.EventBackdrop; import funkin.backend.system.framerate.Framerate; import haxe.Json; import flixel.input.keyboard.FlxKey; import flixel.sound.FlxSound; import flixel.util.FlxSort; import flixel.math.FlxPoint; -import funkin.editors.charter.CharterBackdrop.CharterBackdropDummy; +import funkin.editors.charter.CharterBackdropGroup.CharterBackdropDummy; import funkin.backend.system.Conductor; import funkin.backend.chart.*; import funkin.backend.chart.ChartData; @@ -47,7 +47,7 @@ class Charter extends UIState { public var songPosInfo:UIText; public var topMenuSpr:UITopMenu; - public var gridBackdrop:CharterBackdrop; + public var gridBackdropGroup:CharterBackdropGroup; public var eventsBackdrop:EventBackdrop; public var addEventSpr:CharterEventAdd; public var gridBackdropDummy:CharterBackdropDummy; @@ -341,21 +341,21 @@ class Charter extends UIState { charterBG.scrollFactor.set(); add(charterBG); - gridBackdrop = new CharterBackdrop(); - gridBackdrop.notesGroup = this.notesGroup; + gridBackdropGroup = new CharterBackdropGroup(strumLines); + gridBackdropGroup.notesGroup = this.notesGroup; eventsBackdrop = new EventBackdrop(); eventsBackdrop.x = -eventsBackdrop.width; eventsBackdrop.cameras = [charterCamera]; eventsGroup.eventsBackdrop = eventsBackdrop; - add(gridBackdropDummy = new CharterBackdropDummy(gridBackdrop)); + add(gridBackdropDummy = new CharterBackdropDummy(gridBackdropGroup)); selectionBox = new UISliceSprite(0, 0, 2, 2, 'editors/ui/selection'); selectionBox.visible = false; selectionBox.scrollFactor.set(1, 1); selectionBox.incorporeal = true; - selectionBox.cameras = notesGroup.cameras = gridBackdrop.cameras = [charterCamera]; + selectionBox.cameras = notesGroup.cameras = gridBackdropGroup.cameras = [charterCamera]; topMenuSpr = new UITopMenu(topMenu); topMenuSpr.cameras = uiGroup.cameras = [uiCamera]; @@ -394,7 +394,7 @@ class Charter extends UIState { addEventSpr.cameras = [charterCamera]; // adds grid and notes so that they're ALWAYS behind the UI - add(gridBackdrop); + add(gridBackdropGroup); add(eventsBackdrop); add(addEventSpr); add(eventsGroup); @@ -440,6 +440,8 @@ class Charter extends UIState { vocals = FlxG.sound.load(Paths.voices(__song, __diff)); vocals.group = FlxG.sound.defaultMusicGroup; + gridBackdropGroup.createGrids(PlayState.SONG.strumLines.length); + for(strL in PlayState.SONG.strumLines) createStrumline(strumLines.members.length, strL, false); @@ -467,8 +469,8 @@ class Charter extends UIState { var length = FlxG.sound.music.getDefault(vocals).length; scrollBar.length = Conductor.getStepForTime(length); - gridBackdrop.bottomLimit.y = Conductor.getStepForTime(length) * 40; - eventsBackdrop.bottomSeparator.y = gridBackdrop.bottomSeparator.y = gridBackdrop.bottomLimit.y-2; + gridBackdropGroup.bottomLimitY = Conductor.getStepForTime(length) * 40; + eventsBackdrop.bottomSeparator.y = gridBackdropGroup.bottomLimitY-2; } public override function beatHit(curBeat:Int) { @@ -602,7 +604,7 @@ class Charter extends UIState { gridActionType = BOX; var id = Math.floor(mousePos.x / 40); - var mouseOnGrid = id >= 0 && id < 4 * gridBackdrop.strumlinesAmount && mousePos.y >= 0; + var mouseOnGrid = id >= 0 && id < 4 * gridBackdropGroup.strumlinesAmount && mousePos.y >= 0; if (FlxG.mouse.justReleased) { if (selection.length > 1) { @@ -823,7 +825,7 @@ class Charter extends UIState { scrollBar.size = (FlxG.height / 40 / charterCamera.zoom); scrollBar.start = Conductor.curStepFloat - (scrollBar.size / 2); - if (gridBackdrop.strumlinesAmount != strumLines.members.length) + if (gridBackdropGroup.strumlinesAmount != strumLines.members.length) updateDisplaySprites(); // TODO: canTypeText in case an ui input element is focused @@ -861,13 +863,13 @@ class Charter extends UIState { + '\nTime Signature: ${Conductor.beatsPerMesure}/${Conductor.stepsPerBeat}'; if (FlxG.sound.music.playing) { - gridBackdrop.conductorFollowerSpr.y = curStepFloat * 40; + gridBackdropGroup.conductorSprY = curStepFloat * 40; } else { - gridBackdrop.conductorFollowerSpr.y = lerp(gridBackdrop.conductorFollowerSpr.y, curStepFloat * 40, 1/3); + gridBackdropGroup.conductorSprY = lerp(gridBackdropGroup.conductorSprY, curStepFloat * 40, 1/3); } charterCamera.scroll.set( - (((gridBackdrop.conductorFollowerSpr.scale.x * gridBackdrop.strumlinesAmount) - FlxG.width) / 2), - gridBackdrop.conductorFollowerSpr.y - (FlxG.height * 0.5) + ((((40*4) * gridBackdropGroup.strumlinesAmount) - FlxG.width) / 2), + gridBackdropGroup.conductorSprY - (FlxG.height * 0.5) ); if (charterCamera.zoom != (charterCamera.zoom = lerp(charterCamera.zoom, __camZoom, 0.125))) @@ -880,7 +882,7 @@ class Charter extends UIState { public static var startHere:Bool = false; function updateDisplaySprites() { - gridBackdrop.strumlinesAmount = strumLines.members.length; + gridBackdropGroup.strumlinesAmount = strumLines.members.length; charterBG.scale.set(1 / charterCamera.zoom, 1 / charterCamera.zoom); @@ -1173,11 +1175,11 @@ class Charter extends UIState { } function _view_showeventSecSeparator(t) { t.icon = (Options.charterShowSections = !Options.charterShowSections) ? 1 : 0; - eventsBackdrop.eventSecSeparator.visible = gridBackdrop.sectionSeparator.visible = Options.charterShowSections; + eventsBackdrop.eventSecSeparator.visible = gridBackdropGroup.sectionsVisible = Options.charterShowSections; } function _view_showeventBeatSeparator(t) { t.icon = (Options.charterShowBeats = !Options.charterShowBeats) ? 1 : 0; - eventsBackdrop.eventBeatSeparator.visible = gridBackdrop.beatSeparator.visible = Options.charterShowBeats; + eventsBackdrop.eventBeatSeparator.visible = gridBackdropGroup.beatsVisible = Options.charterShowBeats; } inline function _note_addsustain(t) diff --git a/source/funkin/editors/charter/CharterBackdrop.hx b/source/funkin/editors/charter/CharterBackdropGroup.hx similarity index 50% rename from source/funkin/editors/charter/CharterBackdrop.hx rename to source/funkin/editors/charter/CharterBackdropGroup.hx index 7b440d30..3934f73c 100644 --- a/source/funkin/editors/charter/CharterBackdrop.hx +++ b/source/funkin/editors/charter/CharterBackdropGroup.hx @@ -1,12 +1,115 @@ package funkin.editors.charter; +import flixel.util.FlxPool; +import flixel.graphics.FlxGraphic; import funkin.backend.system.Conductor; import openfl.geom.Rectangle; import flixel.addons.display.FlxBackdrop; -class CharterBackdrop extends FlxBackdrop { - public var strumlinesAmount:Int = 1; +class CharterBackdropGroup extends FlxTypedGroup { + public var strumLineGroup:CharterStrumLineGroup; + public var notesGroup:CharterNoteGroup; + var __gridGraphic:FlxGraphic; + public var conductorSprY:Float = 0; + public var bottomLimitY:Float = 0; + public var sectionsVisible:Bool = true; + public var beatsVisible:Bool = true; + + // Just here so you can update display sprites all dat and above + public var strumlinesAmount:Int = 0; + + public function new(strumLineGroup:CharterStrumLineGroup) { + super(); + this.strumLineGroup = strumLineGroup; + + __gridGraphic = FlxG.bitmap.create(160, 160, 0xFF272727, true); + __gridGraphic.bitmap.lock(); + + // Checkerboard + for(y in 0...4) + for(x in 0...2) __gridGraphic.bitmap.fillRect(new Rectangle(40*((x*2)+(y%2)), 40*y, 40, 40), 0xFF545454); + + // Edges + __gridGraphic.bitmap.fillRect(new Rectangle(0, 0, 1, 160), 0xFFDDDDDD); + __gridGraphic.bitmap.fillRect(new Rectangle(159, 0, 1, 160), 0xFFDDDDDD); + __gridGraphic.bitmap.unlock(); + } + + public function createGrids(amount:Int = 0) { + for (i in 0...amount) { + var grid = new CharterBackdrop(__gridGraphic); + grid.active = grid.visible = false; + add(grid); + } + } + + public override function update(elapsed:Float) { + for (grid in members) + grid.active = grid.visible = false; + + for (i => strumLine in strumLineGroup.members) { + if (strumLine == null) continue; + + if (members[i] == null) + members[i] = recycle(CharterBackdrop, () -> {return new CharterBackdrop(__gridGraphic);}); + + var grid = members[i]; + grid.cameras = this.cameras; + grid.strumLine = strumLine; + + grid.conductorFollowerSpr.y = conductorSprY; + grid.bottomSeparator.y = (grid.bottomLimit.y = bottomLimitY)-2; + grid.sectionSeparator.visible = sectionsVisible; + grid.beatSeparator.visible = beatsVisible; + + grid.notesGroup.clear(); + notesGroup.forEach((n) -> { + var onStr:Bool = (n.snappedToStrumline ? n.strumLineID : Std.int(FlxMath.bound((n.x+n.width)/(40*4), 0, strumLineGroup.members.length-1))) == i; + if(n.exists && n.visible && onStr) + grid.notesGroup.add(n); + }); + + grid.active = grid.visible = true; + grid.updateSprites(); + } + + super.update(elapsed); + } + + public var draggingObj:CharterBackdrop = null; + override function draw() @:privateAccess { + var i:Int = 0; + var basic:FlxBasic = null; + + for (grid in members) { + if (strumLineGroup.draggingObj == null) break; + if (grid.strumLine == null) continue; + + if (strumLineGroup.draggingObj.strumLine == grid.strumLine.strumLine) { + draggingObj = grid; + break; + } + } + + var oldDefaultCameras = FlxCamera._defaultCameras; + if (cameras != null) + FlxCamera._defaultCameras = cameras; + + while (i < length) + { + basic = members[i++]; + if (basic != null && basic != draggingObj && basic.exists && basic.visible) + basic.draw(); + } + if (draggingObj != null) draggingObj.draw(); + + FlxCamera._defaultCameras = oldDefaultCameras; + } +} + +class CharterBackdrop extends FlxTypedGroup { + public var gridBackDrop:FlxBackdrop; public var topLimit:FlxSprite; public var topSeparator:FlxSprite; public var bottomLimit:FlxSprite; @@ -16,25 +119,15 @@ class CharterBackdrop extends FlxBackdrop { public var beatSeparator:FlxBackdrop; public var sectionSeparator:FlxBackdrop; - public var notesGroup:CharterNoteGroup; + public var notesGroup:FlxTypedGroup = new FlxTypedGroup(); + public var strumLine:CharterStrumline; - public function new() { - super(null, Y, 0, 0); + public function new(gridGraphic:FlxGraphic) { + super(); - makeGraphic(160, 160, 0xFF272727, true); - pixels.lock(); + gridBackDrop = new FlxBackdrop(gridGraphic, Y, 0, 0); + add(gridBackDrop); - // Checkerboard - for(y in 0...4) - for(x in 0...2) - pixels.fillRect(new Rectangle(40*((x*2)+(y%2)), 40*y, 40, 40), 0xFF545454); - - // Edges - pixels.fillRect(new Rectangle(0, 0, 1, 160), 0xFFDDDDDD); - pixels.fillRect(new Rectangle(159, 0, 1, 160), 0xFFDDDDDD); - pixels.unlock(); - - // Seperators sectionSeparator = new FlxBackdrop(null, Y, 0, 0); sectionSeparator.y = -2; sectionSeparator.visible = Options.charterShowSections; @@ -50,6 +143,9 @@ class CharterBackdrop extends FlxBackdrop { sep.scale.set((4 * 40), sep == sectionSeparator ? 4 : 2); sep.updateHitbox(); } + add(beatSeparator); + add(sectionSeparator); + add(notesGroup); bottomSeparator = new FlxSprite(0,-2); bottomSeparator.makeSolid(1, 1, -1); @@ -57,6 +153,7 @@ class CharterBackdrop extends FlxBackdrop { bottomSeparator.scrollFactor.set(1, 1); bottomSeparator.scale.set(4 * 40, 4); bottomSeparator.updateHitbox(); + add(bottomSeparator); topSeparator = new FlxSprite(0, -2); topSeparator.makeSolid(1, 1, -1); @@ -64,85 +161,57 @@ class CharterBackdrop extends FlxBackdrop { topSeparator.scrollFactor.set(1, 1); topSeparator.scale.set(4 * 40, 4); topSeparator.updateHitbox(); + add(topSeparator); // Limits topLimit = new FlxSprite(); topLimit.makeSolid(1, 1, -1); topLimit.color = 0xFF888888; topLimit.blend = MULTIPLY; + add(topLimit); bottomLimit = new FlxSprite(); bottomLimit.makeSolid(1, 1, -1); bottomLimit.color = 0xFF888888; bottomLimit.blend = MULTIPLY; + add(bottomLimit); // Follower conductorFollowerSpr = new FlxSprite(0, 0).makeSolid(1, 1, -1); conductorFollowerSpr.scale.set(4 * 40, 4); conductorFollowerSpr.updateHitbox(); + add(conductorFollowerSpr); } - public override function draw() { - var ogX:Float = x; - //FlxG.watch.addQuick("gridXs", [for (strum in Charter.instance.strumLines.members) strum.x]); - for(_ in 0...strumlinesAmount) { - if (Charter.instance.strumLines.members[_] != null) { - x = Charter.instance.strumLines.members[_].x; - alpha = Charter.instance.strumLines.members[_].strumLine.visible ? 0.9 : 0.4; - } else alpha = 0.9; + public function updateSprites() { + var x:Float = 0; // fuck you + var alpha:Float = 0.9; - sectionSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; - beatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; - - super.draw(); + if (strumLine != null) { + x = strumLine.x; + alpha = strumLine.strumLine.visible ? 0.9 : 0.4; + } else alpha = 0.9; - for (sep in [sectionSeparator, beatSeparator]) { - sep.x = this.x; - sep.cameras = this.cameras; - if (sep.visible) sep.draw(); - } - - topLimit.x = this.x; - topLimit.cameras = this.cameras; - - notesGroup.forEach((n) -> { - if(n.exists && n.visible) { - n.cameras = cameras; - n.draw(); - } - }); - - topLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); - topLimit.updateHitbox(); - topLimit.y = -topLimit.height; - topLimit.draw(); - - bottomLimit.x = this.x; - bottomLimit.cameras = this.cameras; - - bottomLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); - bottomLimit.updateHitbox(); - bottomLimit.draw(); - - topSeparator.x = this.x; - topSeparator.cameras = this.cameras; - if (!sectionSeparator.visible) topSeparator.draw(); - - bottomSeparator.x = this.x; - bottomSeparator.cameras = this.cameras; - bottomSeparator.draw(); - - conductorFollowerSpr.x = this.x; - conductorFollowerSpr.cameras = this.cameras; - if (conductorFollowerSpr.visible) conductorFollowerSpr.draw(); + for (spr in [gridBackDrop, sectionSeparator, beatSeparator, topLimit, bottomLimit, topSeparator, bottomSeparator, conductorFollowerSpr]) { + spr.x = x; spr.alpha = alpha; + spr.cameras = this.cameras; } - x = ogX; + + sectionSeparator.spacing.y = (10 * Conductor.beatsPerMesure * Conductor.stepsPerBeat) - 1; + beatSeparator.spacing.y = (20 * Conductor.stepsPerBeat) - 1; + + topLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); + topLimit.updateHitbox(); + topLimit.y = -topLimit.height; + + bottomLimit.scale.set(4 * 40, Math.ceil(FlxG.height / cameras[0].zoom)); + bottomLimit.updateHitbox(); } } class CharterBackdropDummy extends UISprite { - var parent:CharterBackdrop; - public function new(parent:CharterBackdrop) { + var parent:CharterBackdropGroup; + public function new(parent:CharterBackdropGroup) { super(); this.parent = parent; cameras = parent.cameras; diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index 7f544fc6..7eb5a157 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -4,7 +4,7 @@ import funkin.editors.charter.Charter.ICharterSelectable; import flixel.math.FlxPoint; import funkin.game.Character; import funkin.game.HealthIcon; -import funkin.editors.charter.CharterBackdrop.EventBackdrop; +import funkin.editors.charter.CharterBackdropGroup.EventBackdrop; import funkin.backend.chart.ChartData.ChartEvent; class CharterEvent extends UISliceSprite implements ICharterSelectable { diff --git a/source/funkin/editors/charter/CharterEventGroup.hx b/source/funkin/editors/charter/CharterEventGroup.hx index cef8913c..06450ddb 100644 --- a/source/funkin/editors/charter/CharterEventGroup.hx +++ b/source/funkin/editors/charter/CharterEventGroup.hx @@ -1,6 +1,6 @@ package funkin.editors.charter; -import funkin.editors.charter.CharterBackdrop.EventBackdrop; +import funkin.editors.charter.CharterBackdropGroup.EventBackdrop; import flixel.util.FlxSort; class CharterEventGroup extends FlxTypedGroup { diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index 85f7f961..d4df4b26 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -64,7 +64,7 @@ class CharterNote extends UISprite implements ICharterSelectable { public function get_fullID():Int return (strumLineID * 4) + id; - public function updatePos(step:Float, id:Int, susLength:Float = 0, type:Int = 0, ?strumLine:CharterStrumline) { + public function updatePos(step:Float, id:Int, susLength:Float = 0, ?type:Int = 0, ?strumLine:CharterStrumline) { this.step = step; this.id = id; this.susLength = susLength; @@ -128,12 +128,12 @@ class CharterNote extends UISprite implements ICharterSelectable { sustainSpr.follow(this, 15, 20); if (__passed != (__passed = step < Conductor.curStepFloat)) { - alpha = (__passed ? 0.6 : 1); if (__passed && FlxG.sound.music.playing && Charter.instance.hitsoundsEnabled(strumLineID)) Charter.instance.hitsound.replay(); } - if(sustainSpr.exists) - sustainSpr.alpha = alpha; + + alpha = strumLine != null && !strumLine.strumLine.visible ? (__passed ? 0.2 : 0.4) : (__passed ? 0.6 : 1); + if(sustainSpr.exists) sustainSpr.alpha = alpha; colorTransform.redMultiplier = colorTransform.greenMultiplier = colorTransform.blueMultiplier = selected ? 0.75 : 1; colorTransform.redOffset = colorTransform.greenOffset = selected ? 96 : 0; @@ -148,7 +148,7 @@ class CharterNote extends UISprite implements ICharterSelectable { var maxX = Std.int(Math.ceil((selectionBox.x + selectionBox.bWidth) / 40)); var maxY = ((selectionBox.y + selectionBox.bHeight) / 40); - return this.id >= minX && this.id < maxX && this.step >= minY && this.step < maxY; + return this.fullID >= minX && this.fullID < maxX && this.step >= minY && this.step < maxY; } public function handleDrag(change:FlxPoint) { diff --git a/source/funkin/editors/charter/CharterNoteGroup.hx b/source/funkin/editors/charter/CharterNoteGroup.hx index 4051545f..41523995 100644 --- a/source/funkin/editors/charter/CharterNoteGroup.hx +++ b/source/funkin/editors/charter/CharterNoteGroup.hx @@ -8,7 +8,6 @@ class CharterNoteGroup extends FlxTypedGroup { var i:Int = 0; var max:Float = 0; var __currentlyLooping:Bool = false; - var __autoDraw:Bool = false; var __lastSort:Int = 0; public override function forEach(noteFunc:CharterNote->Void, recursive:Bool = false) { @@ -21,7 +20,7 @@ class CharterNoteGroup extends FlxTypedGroup { var curStep = Conductor.curStepFloat; if (!FlxG.sound.music.playing) - curStep = Charter.instance.gridBackdrop.conductorFollowerSpr.y / 40; + curStep = Charter.instance.gridBackdropGroup.conductorSprY / 40; var begin = SortedArrayUtil.binarySearch(members, curStep - max, getVarForEachAdd); var end = SortedArrayUtil.binarySearch(members, curStep + max, getVarForEachRemove); @@ -53,19 +52,7 @@ class CharterNoteGroup extends FlxTypedGroup { private static function getVarForEachRemove(n:CharterNote) return n.step - n.susLength; - public override function draw() { - @:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras; - @:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras; - - if (__autoDraw) { - forEach((n) -> { - if(n.exists && n.visible) - n.draw(); - }); - } - - @:privateAccess FlxCamera._defaultCameras = oldDefaultCameras; - } + public override function draw() {} public override function update(elapsed:Float) { @:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras; From feb107981f046693a295bea9ddb3ea1db988bc95 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:34:26 -0700 Subject: [PATCH 20/72] some changes --- source/funkin/editors/charter/Charter.hx | 8 +++++--- source/funkin/editors/charter/CharterNote.hx | 3 ++- source/funkin/editors/charter/CharterStrumLineGroup.hx | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 35c1148b..b7fa5fca 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -464,10 +464,11 @@ class Charter extends UIState { refreshBPMSensitive(); } + public var __endStep:Float = 0; public function refreshBPMSensitive() { // refreshes everything dependant on BPM, and BPM changes var length = FlxG.sound.music.getDefault(vocals).length; - scrollBar.length = Conductor.getStepForTime(length); + scrollBar.length = __endStep = Conductor.getStepForTime(length); gridBackdropGroup.bottomLimitY = Conductor.getStepForTime(length) * 40; eventsBackdrop.bottomSeparator.y = gridBackdropGroup.bottomLimitY-2; @@ -558,6 +559,7 @@ class Charter extends UIState { selection.loop(function (n:CharterNote) { n.snappedToStrumline = false; n.setPosition(n.fullID * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); + n.y = FlxMath.bound(n.y, 0, (__endStep*40) - n.height); n.cursor = HAND; }, function (e:CharterEvent) { e.y = e.step * 40 + (mousePos.y - dragStartPos.y) - 17; @@ -611,9 +613,9 @@ class Charter extends UIState { for (n in selection) n.selected = false; selection = []; // clear selection } else { - if (mouseOnGrid) { + if (mouseOnGrid && mousePos.y > 0 && mousePos.y < (__endStep)*40) { var note = new CharterNote(); - note.updatePos(FlxG.keys.pressed.SHIFT ? (mousePos.y / 40) : Math.floor(mousePos.y / 40), id % 4, 0, 0, strumLines.members[Std.int(id/4)]); + note.updatePos(FlxMath.bound(FlxG.keys.pressed.SHIFT ? (mousePos.y / 40) : Math.floor(mousePos.y / 40), 0, __endStep-1), id % 4, 0, 0, strumLines.members[Std.int(id/4)]); notesGroup.add(note); selection = [note]; undos.addToUndo(CCreateSelection([note])); diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index d4df4b26..df2b522e 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -152,11 +152,12 @@ class CharterNote extends UISprite implements ICharterSelectable { } public function handleDrag(change:FlxPoint) { + var newStep = FlxMath.bound(step + change.x, 0, Charter.instance.__endStep-1); var newID:Int = fullID + Std.int(change.y); if (newID > ((Charter.instance.strumLines.members.length*4)-1)) newID %= 4; else if (newID < 0) newID = (Charter.instance.strumLines.members.length*4) + newID % 4; - updatePos(step + change.x, newID % 4, susLength, type, Charter.instance.strumLines.members[Std.int(newID/4)]); + updatePos(newStep, newID % 4, susLength, type, Charter.instance.strumLines.members[Std.int(newID/4)]); } public override function draw() { diff --git a/source/funkin/editors/charter/CharterStrumLineGroup.hx b/source/funkin/editors/charter/CharterStrumLineGroup.hx index a970918a..f2f3667b 100644 --- a/source/funkin/editors/charter/CharterStrumLineGroup.hx +++ b/source/funkin/editors/charter/CharterStrumLineGroup.hx @@ -37,11 +37,11 @@ class CharterStrumLineGroup extends FlxTypedGroup { for (i=>strum in members) if (strum != null && !strum.dragging) strum.x = CoolUtil.fpsLerp(strum.x, 160 * i, 0.225); - if (Charter.instance.eventsBackdrop != null) + if (Charter.instance.eventsBackdrop != null && members[0] != null) Charter.instance.eventsBackdrop.x = members[0].button.x - Charter.instance.eventsBackdrop.width; - if (Charter.instance.strumlineLockButton != null) + if (Charter.instance.strumlineLockButton != null && members[0] != null) Charter.instance.strumlineLockButton.x = members[0].x - (40*4); - if (Charter.instance.strumlineAddButton != null) + if (Charter.instance.strumlineAddButton != null && members[Std.int(Math.max(0, members.length-1))] != null) Charter.instance.strumlineAddButton.x = members[members.length-1].x + (40*4); if ((FlxG.mouse.justReleased || !draggable) && isDragging) From 4d2b7b5d268588bb41fb4109042dce89acd52ae7 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:54:10 -0700 Subject: [PATCH 21/72] fixing a bunch of visual bugs --- source/funkin/editors/charter/Charter.hx | 49 +++++++++---------- .../editors/charter/CharterNoteGroup.hx | 2 +- .../editors/charter/CharterStrumLineGroup.hx | 5 ++ 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index b7fa5fca..291b1479 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -47,7 +47,7 @@ class Charter extends UIState { public var songPosInfo:UIText; public var topMenuSpr:UITopMenu; - public var gridBackdropGroup:CharterBackdropGroup; + public var gridBackdrops:CharterBackdropGroup; public var eventsBackdrop:EventBackdrop; public var addEventSpr:CharterEventAdd; public var gridBackdropDummy:CharterBackdropDummy; @@ -341,21 +341,21 @@ class Charter extends UIState { charterBG.scrollFactor.set(); add(charterBG); - gridBackdropGroup = new CharterBackdropGroup(strumLines); - gridBackdropGroup.notesGroup = this.notesGroup; + gridBackdrops = new CharterBackdropGroup(strumLines); + gridBackdrops.notesGroup = this.notesGroup; eventsBackdrop = new EventBackdrop(); eventsBackdrop.x = -eventsBackdrop.width; eventsBackdrop.cameras = [charterCamera]; eventsGroup.eventsBackdrop = eventsBackdrop; - add(gridBackdropDummy = new CharterBackdropDummy(gridBackdropGroup)); + add(gridBackdropDummy = new CharterBackdropDummy(gridBackdrops)); selectionBox = new UISliceSprite(0, 0, 2, 2, 'editors/ui/selection'); selectionBox.visible = false; selectionBox.scrollFactor.set(1, 1); selectionBox.incorporeal = true; - selectionBox.cameras = notesGroup.cameras = gridBackdropGroup.cameras = [charterCamera]; + selectionBox.cameras = notesGroup.cameras = gridBackdrops.cameras = [charterCamera]; topMenuSpr = new UITopMenu(topMenu); topMenuSpr.cameras = uiGroup.cameras = [uiCamera]; @@ -394,7 +394,7 @@ class Charter extends UIState { addEventSpr.cameras = [charterCamera]; // adds grid and notes so that they're ALWAYS behind the UI - add(gridBackdropGroup); + add(gridBackdrops); add(eventsBackdrop); add(addEventSpr); add(eventsGroup); @@ -440,7 +440,7 @@ class Charter extends UIState { vocals = FlxG.sound.load(Paths.voices(__song, __diff)); vocals.group = FlxG.sound.defaultMusicGroup; - gridBackdropGroup.createGrids(PlayState.SONG.strumLines.length); + gridBackdrops.createGrids(PlayState.SONG.strumLines.length); for(strL in PlayState.SONG.strumLines) createStrumline(strumLines.members.length, strL, false); @@ -470,8 +470,8 @@ class Charter extends UIState { var length = FlxG.sound.music.getDefault(vocals).length; scrollBar.length = __endStep = Conductor.getStepForTime(length); - gridBackdropGroup.bottomLimitY = Conductor.getStepForTime(length) * 40; - eventsBackdrop.bottomSeparator.y = gridBackdropGroup.bottomLimitY-2; + gridBackdrops.bottomLimitY = Conductor.getStepForTime(length) * 40; + eventsBackdrop.bottomSeparator.y = gridBackdrops.bottomLimitY-2; } public override function beatHit(curBeat:Int) { @@ -556,6 +556,7 @@ class Charter extends UIState { gridActionType = NONE; case DRAG: if (FlxG.mouse.pressed) { + gridBackdrops.draggingObj = null; selection.loop(function (n:CharterNote) { n.snappedToStrumline = false; n.setPosition(n.fullID * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); @@ -606,7 +607,7 @@ class Charter extends UIState { gridActionType = BOX; var id = Math.floor(mousePos.x / 40); - var mouseOnGrid = id >= 0 && id < 4 * gridBackdropGroup.strumlinesAmount && mousePos.y >= 0; + var mouseOnGrid = id >= 0 && id < 4 * gridBackdrops.strumlinesAmount && mousePos.y >= 0; if (FlxG.mouse.justReleased) { if (selection.length > 1) { @@ -739,6 +740,7 @@ class Charter extends UIState { public function createStrumline(strumLineID:Int, strL:ChartStrumLine, addToUndo:Bool = true) { var cStr = new CharterStrumline(strL); strumLines.insert(strumLineID, cStr); + strumLines.snapStrums(); for(note in strL.notes) { var n = new CharterNote(); @@ -767,6 +769,7 @@ class Charter extends UIState { var strL = strumLines.members[strumLineID].strumLine; strumLines.members[strumLineID].destroy(); strumLines.members.remove(strumLines.members[strumLineID]); + strumLines.snapStrums(); if (addToUndo) { var newStrL = Reflect.copy(strL); @@ -827,7 +830,7 @@ class Charter extends UIState { scrollBar.size = (FlxG.height / 40 / charterCamera.zoom); scrollBar.start = Conductor.curStepFloat - (scrollBar.size / 2); - if (gridBackdropGroup.strumlinesAmount != strumLines.members.length) + if (gridBackdrops.strumlinesAmount != strumLines.members.length) updateDisplaySprites(); // TODO: canTypeText in case an ui input element is focused @@ -865,13 +868,13 @@ class Charter extends UIState { + '\nTime Signature: ${Conductor.beatsPerMesure}/${Conductor.stepsPerBeat}'; if (FlxG.sound.music.playing) { - gridBackdropGroup.conductorSprY = curStepFloat * 40; + gridBackdrops.conductorSprY = curStepFloat * 40; } else { - gridBackdropGroup.conductorSprY = lerp(gridBackdropGroup.conductorSprY, curStepFloat * 40, 1/3); + gridBackdrops.conductorSprY = lerp(gridBackdrops.conductorSprY, curStepFloat * 40, 1/3); } charterCamera.scroll.set( - ((((40*4) * gridBackdropGroup.strumlinesAmount) - FlxG.width) / 2), - gridBackdropGroup.conductorSprY - (FlxG.height * 0.5) + ((((40*4) * gridBackdrops.strumlinesAmount) - FlxG.width) / 2), + gridBackdrops.conductorSprY - (FlxG.height * 0.5) ); if (charterCamera.zoom != (charterCamera.zoom = lerp(charterCamera.zoom, __camZoom, 0.125))) @@ -884,7 +887,7 @@ class Charter extends UIState { public static var startHere:Bool = false; function updateDisplaySprites() { - gridBackdropGroup.strumlinesAmount = strumLines.members.length; + gridBackdrops.strumlinesAmount = strumLines.members.length; charterBG.scale.set(1 / charterCamera.zoom, 1 / charterCamera.zoom); @@ -893,16 +896,10 @@ class Charter extends UIState { strumlineInfoBG.screenCenter(X); strumlineInfoBG.y = -(((FlxG.height - (2 * topMenuSpr.bHeight)) / charterCamera.zoom) - FlxG.height) / 2; - for(id=>str in strumLines.members) { - if (str == null) continue; - str.x = id * 40 * 4; - str.y = strumlineInfoBG.y; - } + for(id=>str in strumLines.members) + if (str != null) str.y = strumlineInfoBG.y; - strumlineAddButton.x = strumLines.length * (40 * 4); strumlineAddButton.y = strumlineInfoBG.y; - - strumlineLockButton.x = -1 * (40 * 4); strumlineLockButton.y = strumlineInfoBG.y; } @@ -1177,11 +1174,11 @@ class Charter extends UIState { } function _view_showeventSecSeparator(t) { t.icon = (Options.charterShowSections = !Options.charterShowSections) ? 1 : 0; - eventsBackdrop.eventSecSeparator.visible = gridBackdropGroup.sectionsVisible = Options.charterShowSections; + eventsBackdrop.eventSecSeparator.visible = gridBackdrops.sectionsVisible = Options.charterShowSections; } function _view_showeventBeatSeparator(t) { t.icon = (Options.charterShowBeats = !Options.charterShowBeats) ? 1 : 0; - eventsBackdrop.eventBeatSeparator.visible = gridBackdropGroup.beatsVisible = Options.charterShowBeats; + eventsBackdrop.eventBeatSeparator.visible = gridBackdrops.beatsVisible = Options.charterShowBeats; } inline function _note_addsustain(t) diff --git a/source/funkin/editors/charter/CharterNoteGroup.hx b/source/funkin/editors/charter/CharterNoteGroup.hx index 41523995..9a825a28 100644 --- a/source/funkin/editors/charter/CharterNoteGroup.hx +++ b/source/funkin/editors/charter/CharterNoteGroup.hx @@ -20,7 +20,7 @@ class CharterNoteGroup extends FlxTypedGroup { var curStep = Conductor.curStepFloat; if (!FlxG.sound.music.playing) - curStep = Charter.instance.gridBackdropGroup.conductorSprY / 40; + curStep = Charter.instance.gridBackdrops.conductorSprY / 40; var begin = SortedArrayUtil.binarySearch(members, curStep - max, getVarForEachAdd); var end = SortedArrayUtil.binarySearch(members, curStep + max, getVarForEachRemove); diff --git a/source/funkin/editors/charter/CharterStrumLineGroup.hx b/source/funkin/editors/charter/CharterStrumLineGroup.hx index f2f3667b..c4c3c17c 100644 --- a/source/funkin/editors/charter/CharterStrumLineGroup.hx +++ b/source/funkin/editors/charter/CharterStrumLineGroup.hx @@ -51,6 +51,11 @@ class CharterStrumLineGroup extends FlxTypedGroup { super.update(elapsed); } + public function snapStrums() { + for (i=>strum in members) + if (strum != null && !strum.dragging) strum.x = 160 * i; + } + public function orderStrumline(strumLine:CharterStrumline, newID:Int) { __pastStrumlines = members.copy(); From 59be4ecd08f8012f743bd412dd7d10abac19b53e Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Wed, 6 Sep 2023 16:46:52 +0200 Subject: [PATCH 22/72] Added autocomplete --- project.xml | 2 +- .../backend/system/macros/ScriptsMacro.hx | 1 + .../editors/charter/CharterStrumlineScreen.hx | 5 +- .../editors/ui/UIAutoCompleteTextBox.hx | 97 +++++++++++++++++++ 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 source/funkin/editors/ui/UIAutoCompleteTextBox.hx diff --git a/project.xml b/project.xml index 1a008240..d8bc062f 100644 --- a/project.xml +++ b/project.xml @@ -113,7 +113,7 @@ - + diff --git a/source/funkin/backend/system/macros/ScriptsMacro.hx b/source/funkin/backend/system/macros/ScriptsMacro.hx index db0f9f55..c6509335 100644 --- a/source/funkin/backend/system/macros/ScriptsMacro.hx +++ b/source/funkin/backend/system/macros/ScriptsMacro.hx @@ -42,6 +42,7 @@ class ScriptsMacro { Compiler.addGlobalMetadata('haxe.xml', '@:build(hscript.UsingHandler.build())'); Compiler.addGlobalMetadata('haxe.CallStack', '@:build(hscript.UsingHandler.build())'); #if HL HashLinkFixer.init(); #end + // Todo rewrite this to use if(Context.defined("")) } } #end \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx index da7e369c..56b33e0a 100644 --- a/source/funkin/editors/charter/CharterStrumlineScreen.hx +++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx @@ -158,7 +158,7 @@ class CharterStrumlineScreen extends UISubstateWindow { class CharacterButton extends UIButton { public var charIcon:HealthIcon; - public var textBox:UITextBox; + public var textBox:UIAutoCompleteTextBox; public var deleteButton:UIButton; public var deleteIcon:FlxSprite; @@ -174,7 +174,8 @@ class CharacterButton extends UIButton { members.push(charIcon); - members.push(textBox = new UITextBox(charIcon.x + charIcon.width + 16, bHeight/2 - (32/2), char, 115)); + members.push(textBox = new UIAutoCompleteTextBox(charIcon.x + charIcon.width + 16, bHeight/2 - (32/2), char, 115)); + textBox.suggestItems = Character.getList(false); textBox.antialiasing = true; textBox.onChange = function(char:String) { char = Character.getIconFromCharName(char); diff --git a/source/funkin/editors/ui/UIAutoCompleteTextBox.hx b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx new file mode 100644 index 00000000..c2cb4f73 --- /dev/null +++ b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx @@ -0,0 +1,97 @@ +package funkin.editors.ui; + +import flixel.math.FlxPoint; +import lime.ui.KeyModifier; +import lime.ui.KeyCode; +import openfl.desktop.Clipboard; +import openfl.geom.Rectangle; + +class UIAutoCompleteTextBox extends UITextBox { + public var suggestionText:UIText; + + public var suggestItems(default, set):Array = []; + var suggestIndex = 0; + + public function new(x:Float, y:Float, text:String = "", width:Int = 320, height:Int = 32, multiline:Bool = false) { + super(x, y, text, width, height, multiline); + + suggestionText = new UIText(0, 0, width, ""); + suggestionText.color = 0xFF888888; + suggestionText.visible = false; + members.insert(members.indexOf(label), suggestionText); + } + + public override function update(elapsed:Float) { + super.update(elapsed); + + var selected = selectable && focused; + + suggestionText.exists = selected; + + suggestionText.follow(label, 0, 0); + } + + public override function onKeyDown(e:KeyCode, modifier:KeyModifier) { + super.onKeyDown(e, modifier); + switch(e) { + //case RETURN: + // focused = false; + case TAB: + if(_suggestions.length > 0) { + label.text = suggestionText.text; + position = label.text.length; + updateSuggestion(true); + } + case BACKSPACE: + updateSuggestion(true); + case UP: + suggestIndex--; + updateSuggestion(false); + case DOWN: + suggestIndex++; + updateSuggestion(false); + default: + // nothing + } + } + + var _suggestions:Array = []; + + public function updateSuggestion(refreshSuggestions:Bool = true) { + if(refreshSuggestions) { + var text = label.text; + _suggestions = []; + if(text.length > 0) { + for(i in suggestItems) if(!_suggestions.contains(i) && i.startsWith(text)) _suggestions.push(i); + //for(i in suggestItems) if(!_suggestions.contains(i) && i.contains(text)) _suggestions.push(i); + _suggestions.remove(text); + } + } + + if(suggestionText.visible = (_suggestions.length != 0)) { + if(suggestIndex >= _suggestions.length) + suggestIndex = 0; + suggestIndex = FlxMath.wrap(suggestIndex, 0, _suggestions.length - 1); + + suggestionText.text = _suggestions[suggestIndex]; + } + } + + public override function onTextInput(text:String):Void { + super.onTextInput(text); + + updateSuggestion(); + } + + public override function onTextEdit(text:String, start:Int, end:Int):Void { + super.onTextEdit(text, start, end); + + updateSuggestion(); + } + + function set_suggestItems(v:Array) { + suggestItems = v; + updateSuggestion(); + return v; + } +} \ No newline at end of file From 68810795a80ea4ae9658dce140ee84f7fa7a121b Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Thu, 7 Sep 2023 16:38:35 -0700 Subject: [PATCH 23/72] some changes to autocomplete --- source/funkin/editors/charter/CharterStrumlineScreen.hx | 9 +++++---- source/funkin/editors/ui/UIAutoCompleteTextBox.hx | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx index 56b33e0a..00eea694 100644 --- a/source/funkin/editors/charter/CharterStrumlineScreen.hx +++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx @@ -59,11 +59,12 @@ class CharterStrumlineScreen extends UISubstateWindow { var title:UIText; add(title = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, creatingStrumLine ? "Create New Strumline" : "Edit Strumline Properties", 28)); + var charFileList = Character.getList(false); charactersList = new UIButtonList(15, title.y + title.height + 36, 250, 259, "", FlxPoint.get(250, 54), null, 0); - charactersList.addButton.callback = () -> charactersList.add(new CharacterButton(0, 0, "New Char", charactersList)); + charactersList.addButton.callback = () -> charactersList.add(new CharacterButton(0, 0, "New Char", charFileList, charactersList)); charactersList.cameraSpacing = 0; for (i in strumLine.characters) - charactersList.add(new CharacterButton(0, 0, i, charactersList)); + charactersList.add(new CharacterButton(0, 0, i, charFileList, charactersList)); add(charactersList); addLabelOn(charactersList, "Characters"); @@ -162,7 +163,7 @@ class CharacterButton extends UIButton { public var deleteButton:UIButton; public var deleteIcon:FlxSprite; - public function new(x:Float, y:Float, char:String, parent:UIButtonList) { + public function new(x:Float, y:Float, char:String, charsList:Array, parent:UIButtonList) { super(x, y, "", null, 250, 54); autoAlpha = false; @@ -175,7 +176,7 @@ class CharacterButton extends UIButton { members.push(charIcon); members.push(textBox = new UIAutoCompleteTextBox(charIcon.x + charIcon.width + 16, bHeight/2 - (32/2), char, 115)); - textBox.suggestItems = Character.getList(false); + textBox.suggestItems = charsList; textBox.antialiasing = true; textBox.onChange = function(char:String) { char = Character.getIconFromCharName(char); diff --git a/source/funkin/editors/ui/UIAutoCompleteTextBox.hx b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx index c2cb4f73..8686bd31 100644 --- a/source/funkin/editors/ui/UIAutoCompleteTextBox.hx +++ b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx @@ -66,6 +66,7 @@ class UIAutoCompleteTextBox extends UITextBox { //for(i in suggestItems) if(!_suggestions.contains(i) && i.contains(text)) _suggestions.push(i); _suggestions.remove(text); } + _suggestions.sort(function(a, b) return a.length - b.length); } if(suggestionText.visible = (_suggestions.length != 0)) { From 6774061fca56ae09d75b851fe8eaeb3881dad22f Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 9 Sep 2023 20:31:12 -0700 Subject: [PATCH 24/72] i forgot what i added --- source/funkin/editors/charter/Charter.hx | 2 +- .../funkin/editors/charter/CharterEventScreen.hx | 3 +-- source/funkin/editors/charter/CharterNote.hx | 2 +- .../funkin/editors/charter/CharterStrumline.hx | 16 ++++++++++------ .../editors/charter/CharterStrumlineScreen.hx | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 291b1479..2e42977b 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -616,7 +616,7 @@ class Charter extends UIState { } else { if (mouseOnGrid && mousePos.y > 0 && mousePos.y < (__endStep)*40) { var note = new CharterNote(); - note.updatePos(FlxMath.bound(FlxG.keys.pressed.SHIFT ? (mousePos.y / 40) : Math.floor(mousePos.y / 40), 0, __endStep-1), id % 4, 0, 0, strumLines.members[Std.int(id/4)]); + note.updatePos(FlxMath.bound(FlxG.keys.pressed.SHIFT ? ((mousePos.y-20) / 40) : Math.floor(mousePos.y / 40), 0, __endStep-1), id % 4, 0, 0, strumLines.members[Std.int(id/4)]); notesGroup.add(note); selection = [note]; undos.addToUndo(CCreateSelection([note])); diff --git a/source/funkin/editors/charter/CharterEventScreen.hx b/source/funkin/editors/charter/CharterEventScreen.hx index ee8107c4..257922c2 100644 --- a/source/funkin/editors/charter/CharterEventScreen.hx +++ b/source/funkin/editors/charter/CharterEventScreen.hx @@ -62,7 +62,7 @@ class CharterEventScreen extends UISubstateWindow { paramsPanel = new FlxGroup(); add(paramsPanel); - saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 10, windowSpr.y + windowSpr.bHeight - 10, "Save & Close", function() { + saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20, windowSpr.y + windowSpr.bHeight - 16 - 32, "Save & Close", function() { saveCurTab(); chartEvent.refreshEventIcons(); @@ -88,7 +88,6 @@ class CharterEventScreen extends UISubstateWindow { Charter.instance.updateBPMEvents(); }); saveButton.x -= saveButton.bWidth; - saveButton.y -= saveButton.bHeight; add(saveButton); closeButton = new UIButton(saveButton.x - 10, saveButton.y, "Close", ()->close()); diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index df2b522e..95bfa53d 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -162,7 +162,7 @@ class CharterNote extends UISprite implements ICharterSelectable { public override function draw() { if (snappedToStrumline) - x = (strumLine != null ? strumLine.button.x : 0) + (id % 4) * 40; + x = (strumLine != null ? strumLine.x : 0) + (id % 4) * 40; drawMembers(); drawSuper(); diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx index 31636780..0f53f092 100644 --- a/source/funkin/editors/charter/CharterStrumline.hx +++ b/source/funkin/editors/charter/CharterStrumline.hx @@ -51,6 +51,9 @@ class CharterStrumline extends UISprite { members.push(button); } + private var __healthYOffset:Float = 0; + private var __draggingYOffset:Float = 0; + public override function update(elapsed:Float) { if (FlxG.keys.justPressed.K) draggable = !draggable; if (healthIcon != null) { @@ -58,20 +61,21 @@ class CharterStrumline extends UISprite { healthIcon.scale.set(healthScale, healthScale); healthIcon.updateHitbox(); - healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, FlxMath.lerp(healthIcon.y - y, draggable ? 29 : 7, 1/20)); + healthIcon.follow(this, ((40 * 4) - healthIcon.width) / 2, 7 + (__healthYOffset = FlxMath.lerp(__healthYOffset, draggable ? 22 : 0, 1/20))); } + draggingSprite.selectable = draggable; + UIState.state.updateSpriteRect(draggingSprite); + var dragScale:Float = FlxMath.lerp(draggingSprite.scale.x, draggable ? 1 : 0.8, 1/16); draggingSprite.scale.set(dragScale, dragScale); draggingSprite.updateHitbox(); - draggingSprite.follow(this, (160/2) - (draggingSprite.width/2), FlxMath.lerp(draggingSprite.y - y, draggable ? 9 : 6, 1/12)); - draggingSprite.alpha = FlxMath.lerp(draggingSprite.alpha, draggable ? 0.4 : 0, 1/12); + draggingSprite.follow(this, (160/2) - (draggingSprite.width/2), 6 + (__draggingYOffset = FlxMath.lerp(__draggingYOffset, draggable ? 3 : 0, 1/12))); + var fullAlpha:Float = UIState.state.isOverlapping(draggingSprite, @:privateAccess draggingSprite.__rect) ? 0.8 : 0.35; + draggingSprite.alpha = FlxMath.lerp(draggingSprite.alpha, draggable ? fullAlpha : 0, 1/12); button.follow(this, 0, 95); - draggingSprite.selectable = draggable; - - UIState.state.updateSpriteRect(draggingSprite); super.update(elapsed); } diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx index 00eea694..57914860 100644 --- a/source/funkin/editors/charter/CharterStrumlineScreen.hx +++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx @@ -127,7 +127,7 @@ class CharterStrumlineScreen extends UISubstateWindow { }, 125); add(saveButton); - closeButton = new UIButton(saveButton.x - 20, saveButton.y, creatingStrumLine ? "Cancel" : "Close", function() { + closeButton = new UIButton(saveButton.x - 20 - saveButton.bWidth, saveButton.y, creatingStrumLine ? "Cancel" : "Close", function() { if (creatingStrumLine && onSave != null) onSave(null); close(); }, 125); From 6c4d194b0c82ef407a9b0fc9ad4b5b2681ea8313 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 10 Sep 2023 12:40:52 -0700 Subject: [PATCH 25/72] auto complete fixes (stages) --- source/funkin/editors/charter/ChartDataScreen.hx | 9 +++++++-- .../funkin/editors/charter/CharterStrumlineScreen.hx | 5 +++-- source/funkin/editors/ui/UIAutoCompleteTextBox.hx | 7 ++++--- source/funkin/editors/ui/UITextBox.hx | 1 - source/funkin/game/Stage.hx | 11 +++++++++++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/source/funkin/editors/charter/ChartDataScreen.hx b/source/funkin/editors/charter/ChartDataScreen.hx index 175a51c4..d05f5d0f 100644 --- a/source/funkin/editors/charter/ChartDataScreen.hx +++ b/source/funkin/editors/charter/ChartDataScreen.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import funkin.game.Stage; import funkin.backend.chart.ChartData; import flixel.math.FlxPoint; import funkin.backend.chart.ChartData.ChartMetaData; @@ -12,7 +13,7 @@ class ChartDataScreen extends UISubstateWindow { public var closeButton:UIButton; public var scrollSpeedStepper:UINumericStepper; - public var stageTextBox:UITextBox; + public var stageTextBox:UIAutoCompleteTextBox; public function new(data:ChartData) { super(); @@ -34,7 +35,11 @@ class ChartDataScreen extends UISubstateWindow { var title:UIText; add(title = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, "Edit Chart Data", 28)); - stageTextBox = new UITextBox(title.x, title.y + title.height + 38, PlayState.SONG.stage, 200); + var stageFileList = Stage.getList(true); + if (stageFileList.length == 0) stageFileList = Stage.getList(false); + + stageTextBox = new UIAutoCompleteTextBox(title.x, title.y + title.height + 38, PlayState.SONG.stage, 200); + stageTextBox.suggestItems = stageFileList; add(stageTextBox); addLabelOn(stageTextBox, "Stage"); diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx index 57914860..e6a04399 100644 --- a/source/funkin/editors/charter/CharterStrumlineScreen.hx +++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx @@ -59,7 +59,9 @@ class CharterStrumlineScreen extends UISubstateWindow { var title:UIText; add(title = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, creatingStrumLine ? "Create New Strumline" : "Edit Strumline Properties", 28)); - var charFileList = Character.getList(false); + var charFileList = Character.getList(true); + if (charFileList.length == 0) charFileList = Character.getList(false); + charactersList = new UIButtonList(15, title.y + title.height + 36, 250, 259, "", FlxPoint.get(250, 54), null, 0); charactersList.addButton.callback = () -> charactersList.add(new CharacterButton(0, 0, "New Char", charFileList, charactersList)); charactersList.cameraSpacing = 0; @@ -133,7 +135,6 @@ class CharterStrumlineScreen extends UISubstateWindow { }, 125); add(closeButton); closeButton.color = 0xFFFF0000; - closeButton.x -= closeButton.bWidth; } function saveStrumline() { diff --git a/source/funkin/editors/ui/UIAutoCompleteTextBox.hx b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx index 8686bd31..091efc7c 100644 --- a/source/funkin/editors/ui/UIAutoCompleteTextBox.hx +++ b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx @@ -63,10 +63,11 @@ class UIAutoCompleteTextBox extends UITextBox { _suggestions = []; if(text.length > 0) { for(i in suggestItems) if(!_suggestions.contains(i) && i.startsWith(text)) _suggestions.push(i); - //for(i in suggestItems) if(!_suggestions.contains(i) && i.contains(text)) _suggestions.push(i); - _suggestions.remove(text); + + // Clean up suggestions + for(i in suggestItems) if(i == text) {_suggestions = [];} + if (_suggestions.length > 0) _suggestions.sort(function(a, b) return a.length - b.length); } - _suggestions.sort(function(a, b) return a.length - b.length); } if(suggestionText.visible = (_suggestions.length != 0)) { diff --git a/source/funkin/editors/ui/UITextBox.hx b/source/funkin/editors/ui/UITextBox.hx index 17f7222e..9e7dae4f 100644 --- a/source/funkin/editors/ui/UITextBox.hx +++ b/source/funkin/editors/ui/UITextBox.hx @@ -140,7 +140,6 @@ class UITextBox extends UISliceSprite implements IUIFocusable { } // untested, but this should be a fix for if the text wont type public function onTextEdit(text:String, start:Int, end:Int):Void { - trace(text, start, end); label.text = label.text.substr(0, position) + text + label.text.substr(position); position += text.length; } diff --git a/source/funkin/game/Stage.hx b/source/funkin/game/Stage.hx index 70fd260f..f8c5f0ce 100644 --- a/source/funkin/game/Stage.hx +++ b/source/funkin/game/Stage.hx @@ -238,6 +238,17 @@ class Stage extends FlxBasic implements IBeatReceiver { public function stepHit(curStep:Int) {} public function measureHit(curMeasure:Int) {} + + public static function getList(?mods:Bool = false):Array { + var list:Array = []; + for (path in Paths.getFolderContent('data/stages/', true, mods ? MODS : BOTH)) + if (Path.extension(path) == "xml" || Path.extension(path) == "hx") { + var file:String = Path.withoutDirectory(Path.withoutExtension(path)); + if (!list.contains(file)) list.push(file); + } + + return list; + } } class StageCharPos extends FlxObject { From 80115e222413be55925e3813667e9343ad76c1fd Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 10 Sep 2023 12:51:49 -0700 Subject: [PATCH 26/72] all dat --- source/funkin/editors/charter/CharterStrumline.hx | 2 +- source/funkin/editors/ui/UIAutoCompleteTextBox.hx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx index 0f53f092..8e34ee46 100644 --- a/source/funkin/editors/charter/CharterStrumline.hx +++ b/source/funkin/editors/charter/CharterStrumline.hx @@ -72,7 +72,7 @@ class CharterStrumline extends UISprite { draggingSprite.updateHitbox(); draggingSprite.follow(this, (160/2) - (draggingSprite.width/2), 6 + (__draggingYOffset = FlxMath.lerp(__draggingYOffset, draggable ? 3 : 0, 1/12))); - var fullAlpha:Float = UIState.state.isOverlapping(draggingSprite, @:privateAccess draggingSprite.__rect) ? 0.8 : 0.35; + var fullAlpha:Float = UIState.state.isOverlapping(draggingSprite, @:privateAccess draggingSprite.__rect) || dragging ? 0.9 : 0.35; draggingSprite.alpha = FlxMath.lerp(draggingSprite.alpha, draggable ? fullAlpha : 0, 1/12); button.follow(this, 0, 95); diff --git a/source/funkin/editors/ui/UIAutoCompleteTextBox.hx b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx index 091efc7c..6b5d31b3 100644 --- a/source/funkin/editors/ui/UIAutoCompleteTextBox.hx +++ b/source/funkin/editors/ui/UIAutoCompleteTextBox.hx @@ -65,7 +65,7 @@ class UIAutoCompleteTextBox extends UITextBox { for(i in suggestItems) if(!_suggestions.contains(i) && i.startsWith(text)) _suggestions.push(i); // Clean up suggestions - for(i in suggestItems) if(i == text) {_suggestions = [];} + if(suggestItems.contains(text)) {_suggestions = [];} if (_suggestions.length > 0) _suggestions.sort(function(a, b) return a.length - b.length); } } From 0543f6c4012dfa66c39eedd0f62da095da82e228 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 16 Sep 2023 12:40:08 -0700 Subject: [PATCH 27/72] hopefully fix empty events --- .../{drag-strumline.png => strumline-drag.png} | Bin source/funkin/editors/charter/CharterEventGroup.hx | 11 ++++++++++- source/funkin/editors/charter/CharterStrumline.hx | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) rename assets/images/editors/charter/{drag-strumline.png => strumline-drag.png} (100%) diff --git a/assets/images/editors/charter/drag-strumline.png b/assets/images/editors/charter/strumline-drag.png similarity index 100% rename from assets/images/editors/charter/drag-strumline.png rename to assets/images/editors/charter/strumline-drag.png diff --git a/source/funkin/editors/charter/CharterEventGroup.hx b/source/funkin/editors/charter/CharterEventGroup.hx index 06450ddb..5022b3a4 100644 --- a/source/funkin/editors/charter/CharterEventGroup.hx +++ b/source/funkin/editors/charter/CharterEventGroup.hx @@ -8,6 +8,7 @@ class CharterEventGroup extends FlxTypedGroup { var __lastSort:Int = 0; public override function update(elapsed:Float) { + filterEvents(); if (length != __lastSort) sortEvents(); @@ -22,10 +23,18 @@ class CharterEventGroup extends FlxTypedGroup { super.draw(); } - public function sortEvents() { + public inline function sortEvents() { __lastSort = length; this.sort(function(i, e1, e2) { return FlxSort.byValues(FlxSort.ASCENDING, e1.step, e2.step); }); } + + public inline function filterEvents() { + for (event in members) + if (event.events.length == 0) { + remove(event, true); + event.kill(); + } + } } \ No newline at end of file diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx index 8e34ee46..0319bf7b 100644 --- a/source/funkin/editors/charter/CharterStrumline.hx +++ b/source/funkin/editors/charter/CharterStrumline.hx @@ -40,7 +40,7 @@ class CharterStrumline extends UISprite { members.push(healthIcon); draggingSprite = new UISprite(); - draggingSprite.loadGraphic(Paths.image("editors/charter/drag-strumline")); + draggingSprite.loadGraphic(Paths.image("editors/charter/strumline-drag")); draggingSprite.alpha = 0.4; draggingSprite.y = 9; draggingSprite.antialiasing = true; @@ -98,7 +98,7 @@ class CharterStrumline extends UISprite { class CharterStrumlineButton extends UITopMenuButton { var strLine:CharterStrumline; public function new(parent:CharterStrumline) { - super(0, 95, null, "Options", []); + super(0, 95, null, "Options ↓", []); strLine = parent; bWidth = 40 * 4; this.label.fieldWidth = bWidth; From b814011d73f2da0d5205ab70d85ade6603269937 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 16 Sep 2023 23:54:52 -0700 Subject: [PATCH 28/72] sorry i went afk for 3987 hours --- source/funkin/editors/charter/Charter.hx | 47 ++++++++++++++----- source/funkin/editors/charter/CharterEvent.hx | 6 ++- source/funkin/editors/charter/CharterNote.hx | 4 +- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 2e42977b..e0bfeac4 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -561,6 +561,7 @@ class Charter extends UIState { n.snappedToStrumline = false; n.setPosition(n.fullID * 40 + (mousePos.x - dragStartPos.x), n.step * 40 + (mousePos.y - dragStartPos.y)); n.y = FlxMath.bound(n.y, 0, (__endStep*40) - n.height); + n.x = FlxMath.bound(n.x, 0, ((strumLines.members.length * 4)-1) * 40); n.cursor = HAND; }, function (e:CharterEvent) { e.y = e.step * 40 + (mousePos.y - dragStartPos.y) - 17; @@ -581,14 +582,30 @@ class Charter extends UIState { : CoolUtil.floorInt((mousePos.y - dragStartPos.y) / 40); var horizontalChange:Int = CoolUtil.floorInt((mousePos.x - dragStartPos.x) / 40); var changePoint:FlxPoint = FlxPoint.get(verticalChange, horizontalChange); + var undoDrags:Array = []; for (s in selection) { - if (!s.draggable) continue; - s.handleDrag(changePoint); + if (s.draggable) { + var boundedChange:FlxPoint = changePoint.clone(); + + // Some maths, so cool bro -lunar (i dont know why i quopte my self here) + if (s.step + changePoint.x < 0) boundedChange.x += Math.abs(s.step + changePoint.x); + if (s.step + changePoint.x > Charter.instance.__endStep-1) boundedChange.x -= (s.step + changePoint.x) - (Charter.instance.__endStep-1); + + if (s is CharterNote) { + var note:CharterNote = cast (s, CharterNote); + if (note.fullID + changePoint.y < 0) boundedChange.y += Math.abs(note.fullID + changePoint.y); + if (note.fullID + changePoint.y > (strumLines.members.length*4)-1) boundedChange.y -= (note.fullID + changePoint.y) - ((strumLines.members.length*4)-1); + } + + s.handleDrag(changePoint); + undoDrags.push({selectable:s, change: boundedChange}); + } + if (s is CharterNote) cast(s, CharterNote).snappedToStrumline = true; if (s is UISprite) cast(s, UISprite).cursor = BUTTON; } - undos.addToUndo(CSelectionDrag(selection, changePoint.clone())); + if (!(changePoint.x == 0 && changePoint.y == 0)) undos.addToUndo(CSelectionDrag(undoDrags)); changePoint.put(); hoverOffset.put(); @@ -1045,10 +1062,11 @@ class Charter extends UIState { deleteSelection(selection, false); case CDeleteSelection(selection): createSelection(selection, false); - case CSelectionDrag(selection, change): - for (s in selection) - if (s.draggable) s.handleDrag(change * -1); - this.selection = selection; + case CSelectionDrag(selectionDrags): + for (s in selectionDrags) + if (s.selectable.draggable) s.selectable.handleDrag(s.change * -1); + + this.selection = [for (s in selectionDrags) s.selectable]; case CEditSustains(changes): for(n in changes) n.note.updatePos(n.note.step, n.note.id, n.before, n.note.type); @@ -1085,10 +1103,10 @@ class Charter extends UIState { createSelection(selection, false); case CDeleteSelection(selection): deleteSelection(selection, false); - case CSelectionDrag(selection, change): - for (s in selection) - if (s.draggable) s.handleDrag(change); - this.selection = selection; + case CSelectionDrag(selectionDrags): + for (s in selectionDrags) + if (s.selectable.draggable) s.selectable.handleDrag(s.change); + //this.selection = selection; case CEditSustains(changes): for(n in changes) n.note.updatePos(n.note.step, n.note.id, n.after, n.note.type); @@ -1276,7 +1294,7 @@ enum CharterChange { CDeleteStrumLine(strumLineID:Int, strumLine:ChartStrumLine); CCreateSelection(selection:Selection); CDeleteSelection(selection:Selection); - CSelectionDrag(selection:Selection, change:FlxPoint); + CSelectionDrag(selectionDrags:Array); CEditSustains(notes:Array); CEditEvent(event:CharterEvent, oldEvents:Array, newEvents:Array); CEditChartData(oldData:{stage:String, speed:Float}, newData:{stage:String, speed:Float}); @@ -1293,6 +1311,11 @@ typedef NoteSustainChange = { var after:Float; } +typedef SelectionDragChange = { + var selectable:ICharterSelectable; + var change:FlxPoint; +} + @:forward abstract Selection(Array) from Array to Array { public inline function new(?array:Array) this = array == null ? [] : array; diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index 7eb5a157..7fe4fff6 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -84,8 +84,10 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { return (selectionBox.x + selectionBox.bWidth > x) && (selectionBox.x < x + bWidth) && (selectionBox.y + selectionBox.bHeight > y) && (selectionBox.y < y + bHeight); } - public function handleDrag(change:FlxPoint) - y = ((step += change.x) * 40) - 17; + public function handleDrag(change:FlxPoint) { + var newStep:Float = FlxMath.bound(step + change.x, 0, Charter.instance.__endStep-1); + y = ((step = newStep) * 40) - 17; + } public function refreshEventIcons() { while(icons.length > 0) { diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index 95bfa53d..0b2fd10e 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -153,9 +153,7 @@ class CharterNote extends UISprite implements ICharterSelectable { public function handleDrag(change:FlxPoint) { var newStep = FlxMath.bound(step + change.x, 0, Charter.instance.__endStep-1); - var newID:Int = fullID + Std.int(change.y); - if (newID > ((Charter.instance.strumLines.members.length*4)-1)) newID %= 4; - else if (newID < 0) newID = (Charter.instance.strumLines.members.length*4) + newID % 4; + var newID:Int = Std.int(FlxMath.bound(fullID + Std.int(change.y), 0, (Charter.instance.strumLines.members.length*4)-1)); updatePos(newStep, newID % 4, susLength, type, Charter.instance.strumLines.members[Std.int(newID/4)]); } From 0d4152a59256cbf186e5c87d355287b44ea013b1 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 17 Sep 2023 00:06:34 -0700 Subject: [PATCH 29/72] hi guyts --- source/funkin/editors/charter/Charter.hx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index e0bfeac4..4e4d9d98 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -565,6 +565,7 @@ class Charter extends UIState { n.cursor = HAND; }, function (e:CharterEvent) { e.y = e.step * 40 + (mousePos.y - dragStartPos.y) - 17; + e.y = FlxMath.bound(e.y, -17, (__endStep*40)-17); e.cursor = HAND; }); currentCursor = HAND; @@ -627,10 +628,9 @@ class Charter extends UIState { var mouseOnGrid = id >= 0 && id < 4 * gridBackdrops.strumlinesAmount && mousePos.y >= 0; if (FlxG.mouse.justReleased) { - if (selection.length > 1) { for (n in selection) n.selected = false; - selection = []; // clear selection - } else { + selection = []; + if (mouseOnGrid && mousePos.y > 0 && mousePos.y < (__endStep)*40) { var note = new CharterNote(); note.updatePos(FlxMath.bound(FlxG.keys.pressed.SHIFT ? ((mousePos.y-20) / 40) : Math.floor(mousePos.y / 40), 0, __endStep-1), id % 4, 0, 0, strumLines.members[Std.int(id/4)]); @@ -638,7 +638,6 @@ class Charter extends UIState { selection = [note]; undos.addToUndo(CCreateSelection([note])); } - } } } else if (gridBackdropDummy.hoveredByChild) { if (FlxG.mouse.pressed && (Math.abs(mousePos.x - dragStartPos.x) > 5 || Math.abs(mousePos.y - dragStartPos.y) > 5)) { From 3556d96f6ba393bef3b3a264812bca578a8026ce Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 17 Sep 2023 17:34:05 -0700 Subject: [PATCH 30/72] Warning shit added --- assets/images/editors/ui/grayscale-popup.png | Bin 0 -> 1585 bytes assets/images/editors/ui/grayscale-popup.xml | 13 ++++++ assets/images/editors/warning.aseprite | Bin 1970 -> 0 bytes assets/images/editors/warning.png | Bin 1929 -> 0 bytes assets/images/editors/warnings/warning.png | Bin 0 -> 1921 bytes source/funkin/backend/system/Main.hx | 4 +- .../utils/{WindowTitle.hx => WindowUtils.hx} | 20 ++++++++- source/funkin/editors/SaveWarning.hx | 39 ++++++++++++++++++ .../editors/character/CharacterEditor.hx | 11 ++++- source/funkin/editors/charter/Charter.hx | 23 ++++------- source/funkin/editors/ui/UIState.hx | 5 ++- source/funkin/editors/ui/UIWarningSubstate.hx | 6 +-- source/funkin/menus/PauseSubState.hx | 9 +++- 13 files changed, 103 insertions(+), 27 deletions(-) create mode 100644 assets/images/editors/ui/grayscale-popup.png create mode 100644 assets/images/editors/ui/grayscale-popup.xml delete mode 100644 assets/images/editors/warning.aseprite delete mode 100644 assets/images/editors/warning.png create mode 100644 assets/images/editors/warnings/warning.png rename source/funkin/backend/utils/{WindowTitle.hx => WindowUtils.hx} (63%) create mode 100644 source/funkin/editors/SaveWarning.hx diff --git a/assets/images/editors/ui/grayscale-popup.png b/assets/images/editors/ui/grayscale-popup.png new file mode 100644 index 0000000000000000000000000000000000000000..b01136031a3d21d074066ab513a4ff6a82cf6fad GIT binary patch literal 1585 zcmV-12G043P)Px)>q$gGRCr$Pol8h7R~X07gc|i?uHv&@)JqjXL>Foa6}qyzZx_;qm4dkQd3}S= z#K#yl7~d|ei>gpiSFUyALMsGZsI+7y;=NabFO;j%nki@II=yYvP7=pC8S_8jM!q@U zoZt83`!r4rM|`Z};^Hrplas$qOicVLK0f}7q@<*1Uvc;z2>c%bx7&T-a=C^V78X`~ z#c>~hGe18+A~Q4dr|j(PqVw}}a&~q`PESwC$;k;QgFrw8qNAfpOiT<(PfzzoMMYh> zT&|Uii;IEP)z$Y88_Dt&78btB%F6mBCMM?9{{B9>yu1u38G=E;7XgF8Kw@KKNm^PO zF&d5Ux3;#vSzlj2ps}KSMMXuiX0zGp@pxYB?(UM?+gp$X0o4iQ<>e8N$8)&3x%suz z>AVx=D=RDGQ&LiXbUK}?C&Y#z@Ib(5G?LuhTyk`Dv_3yS|AQ!>)oT51XJ_Xn{TUAn z1fG(B$z&o01qEbdW8*unw6yg5)YMe__V%{H>-9cmUhEA5A_246Ob!nZf95O}%ddNT zd!M`AZlD1HO$cOUWRS?n$lp1;-F~pPwia=HeXU7iBmsehgane4ljGs0rl#I3EiHiv z2xv;6q@;vEK24D$*#iN{2N#$TfPBo*BQfNI1I!3OK4$2V81lgZW&|J~GxSId`QQLE z0+5dxdL)K?aDW*B$j1yl5<@;Xz>EOoV}>4yAs-xIMga0LLyyFe4-POR0Qs1qM`Fka z2bd9ne9X`zu`C}@fB*{u^gSFxZ*MP)+{hWm1lrr%#WxT^zA%=6)zM}7dU|?T-2?K5 zDS?iT4yp4&zA!a_;jv};tX3<-+d%4YB+%K}DRn-`7mnp;duGVTmVa1hm*ulqEMW}- zhu5A!S67!bb|Ihk@WVZ$EMIqbcet~_`86g$ofA7B3DAdG#Lfr# zw8V~Flz=QBeXtJ;1hgbTpPm;xALP>#J91G1kPjX(BOuGy*48H91jqgD!^fH398D|; z0@M7@A$h3Qv#+mD8oM9M_Z)!Z453c|@`Zklp6wlq^3BZ52(7KHB$V2-FX9-%fq59} z_2hY;aEptJLS8t)BjJbUyzXhkDneCz+j{CEUu& zicnr&?*GXU2?8n*n46n}d@69n7C{i0o}QLoYN5YyV1a;^1O^5MAfJ}Nk?Su4vV1Kq zE#LwIni8y`IL*Vm(IuYydcWg(9nR+r(9P=s7Qe4d9SYI zL+4YjzFs3lYu?M#&K_3PK@e9Co2 zgo*_0cKbWXry@{nA|E=R za`pAn`5>QiEp->6H~ECx+FIQ~#trM6!070xICga*A4abKvgx7wjgF2=&-2yP)cAig zM1p_{1jfe3AfE~xu|*IBbR!=|ZeZ2b!`PMOtFEpN>~x3*fkzS;A0L;-ZYax#t`~fj zL%9RW@>Nw;1%EJ=J0`A1-Ka#HGi zgpjxYyo8h1C-jRDLchrU{rw912LIQBI}1vczk@Ucs;F!*XtENtb3{fA><|^BI2d5j%qL%?l_M7gAj5j j2*Rx(2=wAleI@!6i(Siuud1b#00000NkvXXu0mjfFH!NW literal 0 HcmV?d00001 diff --git a/assets/images/editors/ui/grayscale-popup.xml b/assets/images/editors/ui/grayscale-popup.xml new file mode 100644 index 00000000..021dd81a --- /dev/null +++ b/assets/images/editors/ui/grayscale-popup.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/images/editors/warning.aseprite b/assets/images/editors/warning.aseprite deleted file mode 100644 index 74aa0e65202489ef627499bd184f1c3f983a75e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1970 zcmcJN`#)RvAIIa?)H;o{E-jI!l4WX!#3n`R(yk3^ZCz@N?}8M?cOj{iR#nGJu_O&z z)TLFd7q^-!UnW+UN?dA6r!!%R&}zOd(W%msz0>Z8{sa4*$9aA}kMlX_@p`__IX@v0 zh(9Ye5J%v^Av6#OnBN}+gogSeLLZKQV~`<#MXB>PRR;o$;6&oyM!pxf0PC$d!arB= z@9n%@st^cs+-JbO7F1w_0}06YcLGkbh``^kL;#<6UIM;eum=`S9|A@TZGn_LCUAe0 z4bW#l0Z67g09{<-fwm#3z#yg+$S6_)=>u|L-yd&)Di{bvQB4!@`_mb~sOV^5puZ3B z`0gxVHJJ?j{VN7=G^qv1&-Vmo#j4Zg<95J?8ntsw1fmRqFflPv9fxAt>hGa04dtL2 z)Phb>2--ju=m9050qBD}h=VmKgD=Q}DQK!4RVuIpHShu{FajNL0THkO1;~eRNQT&L z>QtQ8+n4$dAca68yh2ZevvH)e@P%}6|7>W!o7F$e5kz9~vyz|~1CqfRt-T)@b z(;qP6P4-4VU_49?Gi}*~sODQCa`&7#PMQGk(UGBpryc4Xg$J&rbGz@=*r%+7a4{YR zhneH;l9?hKC%OC8I2I$Rp>ru=RE(C#aTs%qeAP0m1mm`G8%3LMNj$;3x>c%3-+&6! zM4dC0uRq`_!O`N(yY$!u=Jzdbye{q*=6O8J{GzGcz4+YhI)_b0^>9arW~Uxo+b96` zZk=f%xlky1a`!}6iN#h?T_cIqc#!uYvI|Q5Hl-1svnEm)>r=d}3bZy4Cy4~+!IHS} zyPAa+yH-x>jOYz39ujD8I!3txRFPn4eW7pRL^*Mwaa>Eb&kHLT;esW)psdK4s|Xs0Wg{6$8}=BiCR}jD)`Hr@^z^^{>Wg@pdWw<7OYKGeof|a$&-5X6& zbGMg&tJ*lZ`s;LiJ0HnsMT9X}vE>7oUC_+M(z7827&yR1$jB&v@%mS*59UvSCI>NPRyF zWqoYzm~e>KB}5sgWz1ha5-J1MC+>Jqu+4w9VP=y)&FK`_QXKKCwfCvG z)qD4}(lYBz)21wXDu!0QEl?7wXMP-Zjp6S}!!h%O`HzE}jFD3G)SOtpr6G*0sUS>ihzefCn%1ja1JJLqC#-QZyPH$2xmN<7u?VAfnv8>@P{t0RGH zyin|R0bl$1;63eL&690q+v>g^WA)`NN{52>D1&`(DbLvI23<25@1tXBfrE_s`NFvw z8G2YS&#_z%%s&z@rP-g9@j{-(c7<)Xs}Db~<#Um9a4FEYIwtgatn1*e<1PJz1E>9(P#nV21YP*q zYf?_zigeg{M9}hVwbFxSbv30%$u=7+{q~!YqD0l^b+UcpJ+G8et@~#Sg}g@rhh#tY zmiOv;p2CthhY4KvV>t?$-6ekm Da2QNX diff --git a/assets/images/editors/warning.png b/assets/images/editors/warning.png deleted file mode 100644 index 71c841547a2569029f922d172e5ffe4d2e711974..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1929 zcmV;42X^?0P)Px+LrFwIRCt{2oXc+8Mi_<9h%_z9cH*K1637KAXj5-fxOtW!kCK&Fd6c4?uCgn- z>#oQHbY*y9d(lnn^rAo(JzWfkq9}4W_lxZV5Rf2VMswzyf35@`fEM#Jx|pBQ(CK&* zm>B>lfCpj9D0Bi$)MY^GrX+0$09;&t?EIXnk~Ks`LdujRYY5OyMCz0zX^0E~sZx@p zA%K{KlqpHh5S5ajA|=Tg0>}}NDkVu7qEq5iqa-Oq0JV~zA|=TfVp7smq9hqZfc_Hy z;ip&l^_TCIu8CDi7&27C$NRwXb7FLlSd@ezfS8W)m|#2x{{G{8rE6nU^oGdNar~TM zJWijI=nVnn=-_7DeR{2QkJuEoAvWody=Q1eZ3v)72Up6JL~Do(I%Mx1QqdX$=+VKI zDkV`G;*t*8XM|Feh5%-CaHU8|bcXn#L-tuA6rCY}9XhyDqa-Rre9|HNOy7#i5Wp@S zTq#i!jUgfEkbSmK<)IVMlnNd5(<|Y-*iO*VudZTjw(u^E1s9+gB8Z=+be0 zbJKbL$!w;ThKtLOcG1&NG*y-?9rM$xK{^0*o|i%_32ulE9oIKEy>!U@uA3Gg3T_A> zN5}E8outN2Nl-&n=n)P39{} zI|@ZfFhYjtIQ@3p4B7riTcYb?q{O=+CaVxt`xm z#JM34fetPolz1UTM8{WO5*!@FV@7C7oEkDzqNY>e=!oF(0NCGmnG$<)O^I_t`byT% zA70^LN-&)OMIol+haWGD)1h*Ykd!zxWT+(V?E#Z9u)j}`MX~lpUM?wdN{EP#$%Ms@ z$r#wn0YZGokP^TOge*IM4Mm9)LxxHaA&id6gy86Cge(gY&`S`)49T-=<*Qv$;*5}? zUioxN@a!mD%Zd;Qeu^mbm(AeR$J_Q z0Yd)iJl7W`Rt!mx4z6~!Rf1FEPO>1f=Y33cIGn$PnLj=CX^Tvl6LH9OTOn0xT8eNkcUPG z({{CG5=Q`iO0*|WL($O;(l%clu&c7_k7U*G{4O~z-VUK`NJu)Gf&JZiAsaER66K(7wsUrc z5xE5+ON_{}DvkP+LvEzjCjsoXxTFm++x=9Pwrb!mJ`=WOvrhu3wYZe3EEPKP?7FId zi+T}(?x0;;vb%BH@63`{71)tMw%W4Q;*v5%hmLzX!H6tz51{@Nh9wQym@%}w_GC80 z{ParGlufn8{!!Buy}k3Yu|&GcQlVpaHQ**d+K|jvXOr#Fz;3lAnkV715laRQF@5U- zLHD0&PoMJN^6a`k!phz}371SPks`!wUwO&e^k@h3<{xIJg*Txowb?{2Q%Zz}*w|N2 zs<_b=J2vzzdlx;2m48YG39^;>r5OL{woX7e3Y$Etp0DcpzA zR#*JsVi|macjsbL)Xd;RJ6#QrRikxuULM@EVo*lDu_- z)7ijS3}}mGa#5A|p_928!$!!cP03DBe^@I?WJCevpmdD;`@`XbPOBekArP>#^y7HRrEfAxnpH P00000NkvXXu0mjf7>|`# diff --git a/assets/images/editors/warnings/warning.png b/assets/images/editors/warnings/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..6c864eafa5ff855137d735914990cdba2afcee10 GIT binary patch literal 1921 zcmV-{2Y&d8P)Px+J4r-ARCt{2ox5%vHyDKvhpW}j%CZH-fQ?mv2yUX*0pe#d{3xze`B98CsoVwW z(&Y(K87V9ksUpXQjCDp#L2{Qn%bDT*qUZnv*q$4ghaZ35h6e6{PFE{-x>~W^>9`lT z82}i7J7G$bI{`k@8Bn_^RT}~TmseNXKi8^i4H+Y$W=g6x1ke*vJ0(>bVnRTzlvHU5 zFit|vlvHPkP06p3lIjcr%m}EJlBx`GDe<*YQk5ZqUCFPJl4=a`Dd{y)QjHkn4QLrKxB`LegRS%-ky45WtQOshTM%){q!AP~MI75IibV$`kNl}KRq{H-`sa2FAKv+7Y zYNDhVLvqkz`tFpPb5GT{_}LEluk)jLu}|!6?36nZc4HfVnatLl}t%CLtN=dp`4UtB_szOQl(Oo#Sl|E z&c36mlC-B>lw>1hijMQ|_swu=%8uPrA|=TU@m+cYzM66qF<(WQ>l--w+%fO`Gxdr}xh9x4AbrB~cBTDpAWNaC}Vg;0QQ8jG2;f zicLv$LWWA#FYlh?Xi2baf%$xzj@K7+=QO;&m{&tdG()CJ(!l}HE`Y;B0&2MS#U(>x zWMWK8q7pJjN89q)(Jp|489+$tfZhREgOD5T*<6%FF=VO)5yI(cTY}@`29)M#U3DOY z8#1Gp)_2FEBpM-8z4GOf;Nfw;W-cMzkY<1oAP*(M4XJU=iZQnaLkvoy5K{7(m0sOo zwUwHZpoY{$2V)dq6pT?2(m6jTG$p|asfP{<1`1$$Aw^0`f*Dd19bDWDrWoSV+5*B- z5|og7=-^VTE&lg82>GPFHWej745^O}seZN9frt*HtwK=}jF8&s;G$q`E)Kfsn-H=F z@5%2f1ts2w)Juod5GD34uMm_3A*4<^r1mKR=?0s^u_^H~BsCo_A7`4~vrEaAko1&z z6Ow|CS1+I8&4qoSm3nir#;cdlMy}{Lfyb+@n3OmhQh)5&)n3niq}rO24<%lN)Ezte zGVi$q@hEXJB=fEdQLgP*TRw3_yxWNq=ZynW)4^i^pIh%|v`mZ6fa&-#q)zlls2HB# zCnv`45Y~p|q(hpbs&7y~_}iGl7zGiO5Yhom7-CVCsdCvJ!ikWav131j-%p&k5e35> z05^k>4otMT*g!E1O^KBuq3CGHH9)#ehYWCE;^SvPU$T0VEi7TiCYHpf#5$<^eL1^E zL#{!{4H|MI#*N%3hvLYtPXdH(aTy!p_w|z~ZDQcAJQH>mvQGlowYaRREE_sz^b)tM zRjMU858Cx*`Zcc0Hceb2u!F+1+6om*j0|z1O;BYwn<(W=$*3VAzAGmpZs=mi zmY$ozMbCMao{~vILhabYMD?UrQPPY?9IF29PWPVS@)ecOmshs4iBdk44CZ90T^F_{ z?8X>%u`{m*N);bYVXRe}@qW7$jpglV(RLlP;wH?+4`}%ha%?W@WYVtBy%(=5C0axL z$E+mk+foH!FqW7~oyr}{aCy#s=v|eF86w?k+~e!F!p@frb`1SSbVbK%^U7}YJB+?` z@k45CUPP6h8FFYx*YH>?tt)JL@SJ!#3K6dNzGp~``3}Zfqw9ciGo*C$BKm7g)$L@u zs(!0#I|_`=D8$gv{FHRP_q`ky7ik|LcU^e;gy89u#(K`9-_J0~{1lSSZWD@S1BGp> zbF7KYjje{d{sC(96<);h?cx0Px_%00000NkvXX Hu0mjfybh3V literal 0 HcmV?d00001 diff --git a/source/funkin/backend/system/Main.hx b/source/funkin/backend/system/Main.hx index fbe59ac1..088c8619 100644 --- a/source/funkin/backend/system/Main.hx +++ b/source/funkin/backend/system/Main.hx @@ -1,5 +1,6 @@ package funkin.backend.system; +import funkin.editors.SaveWarning; import funkin.backend.assets.AssetsLibraryList; import funkin.backend.system.framerate.SystemInfo; import openfl.utils.AssetLibrary; @@ -107,7 +108,8 @@ class Main extends Sprite } public static function loadGameSettings() { - WindowTitle.init(); + WindowUtils.init(); + SaveWarning.init(); MemoryUtil.init(); @:privateAccess FlxG.game.getTimer = getTimer; diff --git a/source/funkin/backend/utils/WindowTitle.hx b/source/funkin/backend/utils/WindowUtils.hx similarity index 63% rename from source/funkin/backend/utils/WindowTitle.hx rename to source/funkin/backend/utils/WindowUtils.hx index 239efa4f..d1ddec7c 100644 --- a/source/funkin/backend/utils/WindowTitle.hx +++ b/source/funkin/backend/utils/WindowUtils.hx @@ -2,7 +2,7 @@ package funkin.backend.utils; import openfl.Lib; -class WindowTitle { +class WindowUtils { public static var winTitle(default, set):String; public static function set_winTitle(newWinTitle:String):String { winTitle = newWinTitle; @@ -22,9 +22,25 @@ class WindowTitle { return endPrefix; } - public static inline function init() + public static var preventClosing:Bool = true; + public static var onClosing:Void->Void; + + static var __triedClosing:Bool = false; + public static inline function resetClosing() __triedClosing = false; + + public static inline function init() { reset(); + Lib.application.window.onClose.add(function () { + if (preventClosing && !__triedClosing) { + Lib.application.window.onClose.cancel(); + __triedClosing = true; + } + if (onClosing != null) onClosing(); + }); + } + + public static inline function reset() { winTitle = Lib.application.meta["name"]; prefix = endfix = ""; diff --git a/source/funkin/editors/SaveWarning.hx b/source/funkin/editors/SaveWarning.hx new file mode 100644 index 00000000..fc30ea32 --- /dev/null +++ b/source/funkin/editors/SaveWarning.hx @@ -0,0 +1,39 @@ +package funkin.editors; + +class SaveWarning { + public static var showWarning(default, set):Bool; + public static function set_showWarning(warning:Bool):Bool + return WindowUtils.preventClosing = showWarning = warning; + + public static var selectionClass:Class = null; + + public static function init() { + showWarning = false; + + WindowUtils.onClosing = function () { + if (SaveWarning.showWarning) triggerWarning(true); + } + } + + public static function triggerWarning(?resetClosing:Bool = false) { + if (FlxG.state != null && FlxG.state is UIState) { + FlxG.state.openSubState(new UIWarningSubstate("Unsaved Changes!", "Your changes will be lost if you don't save them. (Can't be recovered)\n\n\nWould you like to Cancel?", + [{ + label: "Exit To Menu", + onClick: function(_) { + if (selectionClass != null) FlxG.switchState(Type.createInstance(SaveWarning.selectionClass, [])); + if (resetClosing) WindowUtils.resetClosing(); + } + }, + { + label: "Cancel", + onClick: function (_) {if (resetClosing) WindowUtils.resetClosing();} + }], false)); + } + } + + public static inline function reset() { + SaveWarning.showWarning = false; + SaveWarning.selectionClass = null; + } +} \ No newline at end of file diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx index b41a89cc..cf0434d4 100644 --- a/source/funkin/editors/character/CharacterEditor.hx +++ b/source/funkin/editors/character/CharacterEditor.hx @@ -51,7 +51,8 @@ class CharacterEditor extends UIState { public override function create() { super.create(); - WindowTitle.endfix = " (Character Editor)"; + WindowUtils.endfix = " (Character Editor)"; + SaveWarning.selectionClass = CharacterSelection; topMenu = [ { label: "File", @@ -310,12 +311,16 @@ class CharacterEditor extends UIState { characterBG.scale.set(FlxG.width/characterBG.width, FlxG.height/characterBG.height); characterBG.scale.set(characterBG.scale.x / charCamera.zoom, characterBG.scale.y / charCamera.zoom); + + WindowUtils.prefix = undos.unsaved ? "* " : ""; + SaveWarning.showWarning = undos.unsaved; } // TOP MENU OPTIONS #if REGION function _file_exit(_) { - FlxG.switchState(new CharacterSelection()); + if (undos.unsaved) SaveWarning.triggerWarning(); + else FlxG.switchState(new CharacterSelection()); } function _file_new(_) { @@ -327,6 +332,7 @@ class CharacterEditor extends UIState { '${Paths.getAssetsRoot()}/data/characters/${character.curCharacter}.xml', buildCharacter() ); + undos.save(); return; #end _file_saveas(_); @@ -336,6 +342,7 @@ class CharacterEditor extends UIState { openSubState(new SaveSubstate(buildCharacter(), { defaultSaveFile: '${character.curCharacter}.xml' })); + undos.save(); } function buildCharacter():String { diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 4e4d9d98..a5207063 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -93,7 +93,8 @@ class Charter extends UIState { public override function create() { super.create(); - WindowTitle.endfix = " (Chart Editor)"; + WindowUtils.endfix = " (Chart Editor)"; + SaveWarning.selectionClass = CharterSelection; topMenu = [ { label: "File", @@ -591,7 +592,7 @@ class Charter extends UIState { // Some maths, so cool bro -lunar (i dont know why i quopte my self here) if (s.step + changePoint.x < 0) boundedChange.x += Math.abs(s.step + changePoint.x); - if (s.step + changePoint.x > Charter.instance.__endStep-1) boundedChange.x -= (s.step + changePoint.x) - (Charter.instance.__endStep-1); + if (s.step + changePoint.x > __endStep-1) boundedChange.x -= (s.step + changePoint.x) - (__endStep-1); if (s is CharterNote) { var note:CharterNote = cast (s, CharterNote); @@ -896,7 +897,8 @@ class Charter extends UIState { if (charterCamera.zoom != (charterCamera.zoom = lerp(charterCamera.zoom, __camZoom, 0.125))) updateDisplaySprites(); - WindowTitle.prefix = undos.unsaved ? "* " : ""; + WindowUtils.prefix = undos.unsaved ? "* " : ""; + SaveWarning.showWarning = undos.unsaved; } public static var startTime:Float = 0; @@ -931,19 +933,8 @@ class Charter extends UIState { // TOP MENU OPTIONS #if REGION function _file_exit(_) { - if (undos.unsaved) { - FlxG.state.openSubState(new UIWarningSubstate("Unsaved Changes", "Your changes will be lost if you don't save them. (Can't be recovered)\n\n\nWould you like to Cancel?", [ - { - label: "Exit To Menu", - onClick: function(_) FlxG.switchState(new CharterSelection()) - }, - { - label: "Cancel", - onClick: function (_) {} - } - ], false)); - } else - FlxG.switchState(new CharterSelection()); + if (undos.unsaved) SaveWarning.triggerWarning(); + else FlxG.switchState(new CharterSelection()); } function _file_save(_) { diff --git a/source/funkin/editors/ui/UIState.hx b/source/funkin/editors/ui/UIState.hx index 4987d8fb..1120c614 100644 --- a/source/funkin/editors/ui/UIState.hx +++ b/source/funkin/editors/ui/UIState.hx @@ -127,8 +127,11 @@ class UIState extends MusicBeatState { public override function destroy() { super.destroy(); - WindowTitle.reset(); __mousePos.put(); + + WindowUtils.reset(); + SaveWarning.reset(); + FlxG.stage.window.onKeyDown.remove(onKeyDown); FlxG.stage.window.onKeyUp.remove(onKeyUp); FlxG.stage.window.onTextInput.remove(onTextInput); diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx index 9fee13e2..43633410 100644 --- a/source/funkin/editors/ui/UIWarningSubstate.hx +++ b/source/funkin/editors/ui/UIWarningSubstate.hx @@ -56,16 +56,16 @@ class UIWarningSubstate extends MusicBeatSubstate { warnCam.zoom = 0.1; FlxG.cameras.add(warnCam, false); - var spr = new UISliceSprite(0, 0, CoolUtil.maxInt(560, 30 + (170 * buttons.length)), 232, "editors/ui/normal-popup"); + var spr = new UISliceSprite(0, 0, CoolUtil.maxInt(560, 30 + (170 * buttons.length)), 232, 'editors/ui/${isError ? "normal" : "grayscale"}-popup'); spr.x = (FlxG.width - spr.bWidth) / 2; spr.y = (FlxG.height - spr.bHeight) / 2; - spr.color = 0xFFFF0000; + spr.color = isError ? 0xFFFF0000 : 0xFFFFFF00; 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); - var sprIcon:FlxSprite = new FlxSprite(spr.x + 26, spr.y + 28 + 26).makeSolid(100, 100, -1); + var sprIcon:FlxSprite = new FlxSprite(spr.x + 26, spr.y + 28 + 26).loadGraphic(Paths.image('editors/warnings/${isError ? "error" : "warning"}')); add(sprIcon); add(messageSpr = new UIText(sprIcon.x + 100 + 16, sprIcon.y + 12, spr.bWidth - 100 - (26 * 2), message)); diff --git a/source/funkin/menus/PauseSubState.hx b/source/funkin/menus/PauseSubState.hx index 7568c27a..3464f3ce 100644 --- a/source/funkin/menus/PauseSubState.hx +++ b/source/funkin/menus/PauseSubState.hx @@ -22,7 +22,7 @@ class PauseSubState extends MusicBeatSubstate var grpMenuShit:FlxTypedGroup; - var menuItems:Array = ['Resume', 'Restart Song', 'Change Controls', 'Options','Exit to menu']; + var menuItems:Array = ['Resume', 'Restart Song', 'Change Controls', 'Change Options', 'Exit to menu', "Exit to charter"]; var curSelected:Int = 0; var pauseMusic:FlxSound; @@ -42,6 +42,9 @@ class PauseSubState extends MusicBeatSubstate { super.create(); + if (menuItems.contains("Exit to charter") && !PlayState.chartingMode) + menuItems.remove("Exit to charter"); + add(parentDisabler = new FunkinParentDisabler()); pauseScript = Script.create(Paths.script(script)); @@ -147,8 +150,10 @@ class PauseSubState extends MusicBeatSubstate case "Change Controls": persistentDraw = false; openSubState(new KeybindsOptions()); - case "Options": + case "Change Options": FlxG.switchState(new OptionsMenu()); + case "Exit to charter": + FlxG.switchState(new funkin.editors.charter.Charter(PlayState.SONG.meta.name, PlayState.difficulty, false)); case "Exit to menu": CoolUtil.playMenuSong(); FlxG.switchState(PlayState.isStoryMode ? new StoryMenuState() : new FreeplayState()); From f5dbe5e7c3dba38b997e06d0f65c1504589c801a Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Mon, 18 Sep 2023 15:15:11 -0700 Subject: [PATCH 31/72] warning changes --- assets/images/editors/ui/grayscale-button.png | Bin 0 -> 867 bytes assets/images/editors/ui/grayscale-button.xml | 33 ++++++++++++++++++ source/funkin/backend/utils/WindowUtils.hx | 6 ++-- source/funkin/editors/SaveWarning.hx | 17 ++++++--- .../editors/character/CharacterAnimButtons.hx | 1 + source/funkin/editors/ui/UIState.hx | 2 +- source/funkin/editors/ui/UIWarningSubstate.hx | 7 +++- 7 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 assets/images/editors/ui/grayscale-button.png create mode 100644 assets/images/editors/ui/grayscale-button.xml diff --git a/assets/images/editors/ui/grayscale-button.png b/assets/images/editors/ui/grayscale-button.png new file mode 100644 index 0000000000000000000000000000000000000000..1467fece5a4b6fbc0cf733a2d019a250413afdcd GIT binary patch literal 867 zcmV-p1DyPcP)Px&9Z5t%R9HvtnOjRLQ546Q8j_Vsgd%i-P|ky9Wsz?Zy`K+YWzT*AFVF`NynF$l z)#?MBZ_t~9mWdCN1YID6pt}}c4*z}53~DdUo)H>s!=Mba{_ORewP&rpwub(XR4UaK z{`33>0s&30U8PcyrRQ)shN`EOzig5a%VaWtc)$rZe!u^>01@yak%$~Qip63iK!jek zTBT;Q$u245{r#OZ;N{H*K9Vk`|WmHiX3%19qM+w^!oZr@K>V*yk3Z2ub1S) z6Z8NP1MuqgI@M}5YBU;>9DaCsAg9ww)6>(mwY5bjCnp4WcoEP75Ge!CkB^U&PN!oK zRRQqq?2JmK65ZU~kVezDvcKdz9NyU2AiP`voSB)S=jUg7dV2bj{oq5Blaqw&<>h5K z0K?%h*Te>m;_*1UmCxs?SS-^0{XLiN?CdPL-EP|4+++YvCKGcW5P62tXr!sBDSCW- z91g%xD8w_bPd14}g5AsIa&&rnDhuG++8TL0p3wyO6M>xZC`91M0SpF%oXGmklF6j_ z4J;H2vX=1r`nr0)fx`fZOpH>7XILy2T3uZoZGb-!$PqfdOZZzyU^E)7a`^Yjv7xGT8MD8?uL!_&I?Z%0E-vWq?v5@mFX`jsLz1>$ucxJ@C9+zrWVhSJb{4wP zZ*OmsJJJ9+F)={~gW+F45VKLD7DN% literal 0 HcmV?d00001 diff --git a/assets/images/editors/ui/grayscale-button.xml b/assets/images/editors/ui/grayscale-button.xml new file mode 100644 index 00000000..0c0811f4 --- /dev/null +++ b/assets/images/editors/ui/grayscale-button.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/funkin/backend/utils/WindowUtils.hx b/source/funkin/backend/utils/WindowUtils.hx index d1ddec7c..609e3977 100644 --- a/source/funkin/backend/utils/WindowUtils.hx +++ b/source/funkin/backend/utils/WindowUtils.hx @@ -29,7 +29,8 @@ class WindowUtils { public static inline function resetClosing() __triedClosing = false; public static inline function init() { - reset(); + resetTitle(); + resetClosing(); Lib.application.window.onClose.add(function () { if (preventClosing && !__triedClosing) { @@ -39,9 +40,8 @@ class WindowUtils { if (onClosing != null) onClosing(); }); } - - public static inline function reset() { + public static inline function resetTitle() { winTitle = Lib.application.meta["name"]; prefix = endfix = ""; updateTitle(); diff --git a/source/funkin/editors/SaveWarning.hx b/source/funkin/editors/SaveWarning.hx index fc30ea32..73b465ac 100644 --- a/source/funkin/editors/SaveWarning.hx +++ b/source/funkin/editors/SaveWarning.hx @@ -15,19 +15,26 @@ class SaveWarning { } } - public static function triggerWarning(?resetClosing:Bool = false) { + public static function triggerWarning(?closingWindow:Bool = false) { if (FlxG.state != null && FlxG.state is UIState) { FlxG.state.openSubState(new UIWarningSubstate("Unsaved Changes!", "Your changes will be lost if you don't save them. (Can't be recovered)\n\n\nWould you like to Cancel?", [{ - label: "Exit To Menu", + label: closingWindow ? "Exit Window" : "Exit To Menu", + color: 0x74732D, onClick: function(_) { - if (selectionClass != null) FlxG.switchState(Type.createInstance(SaveWarning.selectionClass, [])); - if (resetClosing) WindowUtils.resetClosing(); + if (!closingWindow) { + if (selectionClass != null) FlxG.switchState(Type.createInstance(SaveWarning.selectionClass, [])); + if (closingWindow) WindowUtils.resetClosing(); + } else { + WindowUtils.preventClosing = false; WindowUtils.resetClosing(); + Sys.exit(0); + } } }, { label: "Cancel", - onClick: function (_) {if (resetClosing) WindowUtils.resetClosing();} + color: 0x969533, + onClick: function (_) {if (closingWindow) WindowUtils.resetClosing();} }], false)); } } diff --git a/source/funkin/editors/character/CharacterAnimButtons.hx b/source/funkin/editors/character/CharacterAnimButtons.hx index e0ebd3b9..bccc51a4 100644 --- a/source/funkin/editors/character/CharacterAnimButtons.hx +++ b/source/funkin/editors/character/CharacterAnimButtons.hx @@ -39,6 +39,7 @@ class CharacterAnimButtons extends UIButton { editButton = new UIButton(ghostButton.x+32+17, y, "", function () { CharacterEditor.instance.editAnimWithUI(this.anim); }, 32); + editButton.frames = Paths.getFrames("editors/ui/grayscale-button"); editButton.color = FlxColor.YELLOW; editButton.autoAlpha = false; members.push(editButton); diff --git a/source/funkin/editors/ui/UIState.hx b/source/funkin/editors/ui/UIState.hx index 1120c614..ba7a3943 100644 --- a/source/funkin/editors/ui/UIState.hx +++ b/source/funkin/editors/ui/UIState.hx @@ -129,7 +129,7 @@ class UIState extends MusicBeatState { super.destroy(); __mousePos.put(); - WindowUtils.reset(); + WindowUtils.resetTitle(); SaveWarning.reset(); FlxG.stage.window.onKeyDown.remove(onKeyDown); diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx index 43633410..a67db6f9 100644 --- a/source/funkin/editors/ui/UIWarningSubstate.hx +++ b/source/funkin/editors/ui/UIWarningSubstate.hx @@ -72,10 +72,14 @@ class UIWarningSubstate extends MusicBeatSubstate { var xPos = (FlxG.width - (30 + (170 * buttons.length))) / 2; for(k=>b in buttons) { - var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - (32 + 16), b.label, function() { + var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - (42 + 16), b.label, function() { b.onClick(this); close(); }, 160, 30); + if (b.color != null) { + button.frames = Paths.getFrames("editors/ui/grayscale-button"); + button.color = b.color; + } add(button); } @@ -105,5 +109,6 @@ class UIWarningSubstate extends MusicBeatSubstate { typedef WarningButton = { var label:String; + var ?color:Int; var onClick:UIWarningSubstate->Void; } \ No newline at end of file From 357815187f11cb7d65325b70ce59e1c78b8be4a8 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Mon, 18 Sep 2023 21:21:29 -0700 Subject: [PATCH 32/72] Finish update --- .../images/editors/charter/add-strumline.png | Bin 652 -> 5969 bytes .../images/editors/charter/lock-strumline.png | Bin 0 -> 3397 bytes assets/images/editors/new.png | Bin 652 -> 5596 bytes assets/images/editors/ui/context-icons.png | Bin 737 -> 1114 bytes assets/images/editors/warnings/error.png | Bin 0 -> 10845 bytes assets/images/editors/warnings/warning.png | Bin 1921 -> 8772 bytes .../editors/character/CharacterSelection.hx | 9 ++---- source/funkin/editors/charter/Charter.hx | 8 +++--- .../editors/charter/CharterSelection.hx | 27 +++++++++--------- .../editors/charter/CharterStrumline.hx | 14 +++++---- ...traButton.hx => CharterStrumlineButton.hx} | 4 +-- source/funkin/editors/ui/UIContextMenu.hx | 2 ++ source/funkin/editors/ui/UIWarningSubstate.hx | 2 +- source/funkin/options/type/NewOption.hx | 1 + 14 files changed, 34 insertions(+), 33 deletions(-) create mode 100644 assets/images/editors/charter/lock-strumline.png create mode 100644 assets/images/editors/warnings/error.png rename source/funkin/editors/charter/{CharterStrumlineExtraButton.hx => CharterStrumlineButton.hx} (91%) diff --git a/assets/images/editors/charter/add-strumline.png b/assets/images/editors/charter/add-strumline.png index d205c17ef58da963538144b3ad6c0fcf569adb70..d890a9a1e73c9c97781c4795afdd22491848b602 100644 GIT binary patch literal 5969 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 literal 652 zcmeAS@N?(olHy`uVBq!ia0vp^-XP4u1|%)~s$Kyp#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvNA9*$#}XrhE&A8o$cs%*g(Mb@`|LBU9tKM>2B#!p-`q} zo3yX{uK9Q5v+Sw*AQAmVDxZxC=Sr4d6^z_}r?x#Y^xJuBFBy}_xJ61liM}a!?eDf- zw6Tk`Kir|bn!j3VtBa)R`BKi3NXy@6#kXu-vT}{)!R;b$^EW?QJ(=zAhDx5rM(=NL zH~3|H|J$<-{hzOeo{O}c-eoi)*)~J(wZ38`!z5M(!i2-br+1A_B(7UrSt}{t^~AJd zONh+t50$+4q*s6ZuIqBO<*K!b|LPF2*N1|wtS2ty>sQZwCii@e*rI2LUMMb$>zg_C zbkdy;L-oyjP8ge|U4O9tVUVk2&%K8cf6`}8l{>LxzD%wVNzv%Jku!rK^>?<;Qc^d0R8eo^F!h|E9C~Qq*R3 z)8^zZBR?szdpu{mgN?OCk5*l-@mWA>w|Y0_w=2UI2-TGEq61@X?o~p z>BFzyxV$KyCf;M&t#?TfNTyR27yb# PlR=cHtDnm{r-UW|LplaR diff --git a/assets/images/editors/charter/lock-strumline.png b/assets/images/editors/charter/lock-strumline.png new file mode 100644 index 0000000000000000000000000000000000000000..0583bec202b8aafaa978dd7fdc63936a5bf12ecf GIT binary patch literal 3397 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 b00;m8000000Mb*F00000NkvXXu0mjfe^z+s literal 0 HcmV?d00001 diff --git a/assets/images/editors/new.png b/assets/images/editors/new.png index d205c17ef58da963538144b3ad6c0fcf569adb70..945c49e04578324be65fc1c26195b527301076f4 100644 GIT binary patch literal 5596 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 PlR=cHtDnm{r-UW|LplaR diff --git a/assets/images/editors/ui/context-icons.png b/assets/images/editors/ui/context-icons.png index 73b8ff97642017741a10ddc90ca6bce3fa29c9ca..7bf464486da3e6eeb6892501dd015dc75a996578 100644 GIT binary patch literal 1114 zcmV-g1f~0lP)Px(6iGxuR9J=0m_cY9RT#&AZ!()~vrUuICQDeCjfqyKm5L>L=tU_aBF(W8Dnc)U zFo$*tq>Ey_sI9HF5ex`=D2Rdu5wX2Vs0S-*$e|FUmL?n47`D;G6x(FGyYoD}dD*ww zNiva|^ba5JF|+&L{O0@5_uh<Pjqm^oNM|}(4m;px>6Zt7U+&u>|D(YyzpeB8 zmVdsCg1+xyS1Js!32UKXZNIJae^c^9_-$x8ZbFU^O^YzUJ=$FgZAY!oM(nDw*8?_T zHE6_$I+T@*Kw+a7HT@&+O37|vG12)9uSQ}lQK{7H!shd{WYT$tMh2_S>r97% zHmx1h4}#UewjcFA*tUR(0ga_4ntr>?>(b*9Ay{ZXKwnD-f1!$2i8Yob$4$sgI!``7 zyL@aVbgDhc(8wTRtM-49S&$m2zy-$GMPBww91?M#nC41ZehS2hap;AOC{qOG_LBh_>){*RzZOi@*|a7X@5H zW!l(OJl?w8&!qF40t=O5WqT#Mq-1wtfwv}yc@hP?18ABY=JCZjG5~gz3ww`n83n6> z11-H4ta*cIf$G1`vnZLn1vpj2fz8a5tp-E>$`z-5#ji%kjU6Hky4f_drjaP|uCNsmq;_%nHs z*J5qV0k=`G8rX!b$?)-BhcCbSfpn&NPm<19n+^-rzy)A2{uq-xyErKXo|Loz-mX2I zY~4$iYFIO~l2x{qPrrD9E1w<%lzq1`=DIH_*@?F0dCU(0LQ1*vJvU;sx~S=8$6S5_t!x6{FIxGpHlSxEDRCwBrluc+8K@`XTyZPM4kVd1BgQT{UKuhcA%|oDwUeud{ zLZubNfWfnfR*Hv$2M;QegV0hz^x#DWL8Rb8!JbUDXbCogL~7zbH+5WV z&BC8IJ3I5+_cfzAj)Nv2Z4=of0dlk^fpVkH*280+zgrBongOaXonc@8!=aj_y08+cZ32`q2?>ybB>(gy9IG$lk~fGuz5U42TulJo2?qaFj#ZcdwUCV2 zm*|}@V2u3n>0XTQJ&VgUUll-)D>S!Gr^q@sk_4M=KZL>7HhiORzevjh7*xXYy7H+j-WiP=!tWp8y4^sZrePtz z9|Q4y$TO@Wa~M*R?N?giFJNvQ=LtGMFf)=srsFUs875Q{l@`E=*f4b;X|O zmp|jCs3^6_*zPm9tAtsVJt&%c9cWgt^}|Elwk@OxTHbjO7q@re=iD@6U*F&s!6MWi z6FsLfM9>8WRyouadHiI^1}VH$L_Gf-_o#xMRKa{(3L{@$;R?OC)B8;FI5MFfn4`5z z3ark@&X&L}oOEHsr5rkolLU1TB~Rzcwvzo$9;eCU06QiOHS zSWr)jJP`p!8ZWFXl3_O7FbQ4Tx07!|ImIqW*SsKUhd+Ci9h=7z(Lzg05O6Z{o(!oYZLI@>>gwSlLh$Aqf zh=^cCM?e%Dl_Ggz#|j)|q?h5>|pXuuv2*&K<884?l*5Y0UQuJ^r2E~4A!Q?>s6 z_x~zIE>FS%0181ko-5&`B76!NZ5)v}9RQRFiR)#ii>9~~VP!GWAi_0M%%A4ADUP4! z?(aF_p`Hl;4gj9aW{dd%kj9WWJ%htX>X4D$0!txRAVk<5VOLHfn~QKR!e*(dE2j7; z!bb6bsl)$U&3IW&Hk&Ww>Aidx-b)}6rLeRA&)4z4m6{@*SwjyQhmPt zVKdAY&#om+j$q2x<*{Tna}vX&W;jC-xp0Oh$zcJrIi9k(SQ;wpIYI0r+heNaFZ&X( zWceKSY(MFV;eNAyM$3BO^1QrdabbikUzF}4t1n6kk>&GJd}VP-Mwo1FI&#=%=Z47M zPZHZdWQKtN1OYbSr1P@UryBNLA<7mD_=)LsCURqVbe51~VMe#Mw6+0Y>i$jty>DsX z?-fM5HXBQ82f(oa3G!!SY~&oAeg**b{cKF{4RSQL0&u3ABNb;%$Iw$>7(fK_KpCh3 zE#&+d0drst?0_?H2j0LR1cPu81C{{}NCc@s3^Ktguny#dLa-I=02N>#I0$OMF>nGj zgEnv;Tn5)cH@FKPf_^XrUV<_39!x+Ggo7v$6;gw=Ap^)1vW6TWSI8R*ghHVhC=TL7 zLP!d&f;K>fPzh849e`?~pP|#xdFU$C1Ko!Ppb_W|^chCMWLO#2gbm?&umjA51K@CY zDa?n{;2by)-U64yRq#=`2|f>BhwsAu@Jo0c1yCdu4W)xJM>(K8QNgHKR02wjT7xP; zm7%Io^{7@%d`u=LA5(@ojA_JN!ra9SVcui0SQ?grwa5BlW3WlsmDnQe9&7`) z9ovH)#E#=|I5nIp&IK2YW8>0s`M6!UqquXpTeuAo8(S;aJOd_r$mJ{oVmxzyuZ%HJQ zF3FL!h$JB8lFCWPNmob%q)%ievI*Ifyo4+zZy{Hc+sXIIZz&XtA;p~%OG&3}q0~|? zP@Yge%2DMkLKbS z>X0&4nW4;5PEsyZKBnBIJf@FYWUj%{k0D zyg8fa)X%v!=Y#58Rd-dMYJqBl>Rr{(YIHSkwPdwzYRzho)zRuE>WkDf)%U7jQXieG zJlA@LfKHdrgf2rjLU+AxgYIKJqMn0Zf?la! zhu)aJwtkTQD*ZbB2L=QK2ZKa|od%r-9}F3WQHGlgn+=~cR2eKr4x^6o$cSR(W|U@B zWpu|FYwTd0Y`n*~+XObTHAyt7G`VRCo7$NQO!t`fm|@Hu&4gxEW_{*lbEbKQd7b%y z1u+ zdY3YmW-YzCOnq6(vNOx&m$R3jjKjo5#T|+J!VYFvvB%?C@w?;4IG&uHoR?g8ZYg(! z=fW%D4JWuHlq5XoyYRR3M-tr<%MwQgo`MR&>m?MJI0%YU5QlCY(#*sgf*R_s>c*4}My+iFS_OL9sEw+C%+Dy5ee zl)l@se8<(Y`DOcd5_d{>_Lm2ix9rm2wRP8*io}Y$l^&H1yES%i-u+<@ch9Z8?tAO^ zY3?iB_j$iy|Gfjg2b!u3tI7^y4`v*Eb|~^t=T8nl)gD$qTzL3vwXnLsCbZ^at$l6n z5sf3ob#R@uZsh2aqus~6jmD9VZ=5)}JyswY!np zSkMGDWjBpACpP!D#I*FB_CMXx>fGA+i^VV1Z8~k0XH?D{9&YrbxGz3GPSjmBSX ze{Jlt>uS1bf3v0AvAeZrLC@J+Znw_g_PTxf4(rbKy9@93^hWgF>s!*-e~)|b`Tdmp zuODPQn0T1`2=l1mvBKlBCmK(xelz~9q2I3m%z)Rxji+Hx9}aQ`U;Zxn{mW3^Gs?5F zVeR4C=hn~LMtnxPUo3tx^iuS4Vl@8`#XokxGJ19DPxn7>j75(Py%xWod{gvR?QQkD z`R_W$L&l%HPkle}q2Qz1$C^(LpE^HBeIB03{DS*Z{?+(v>$iY!k0w(mCq-;A`@0oD zAp=fG0N_nE0F)TSJ0QN9xOmzhe-||E>Aw^BPdx3RzsnAQYIgu4asdcLJjz~V7$8hW zo>Mj`+#SF+HnQC>lw{eAs)pFVd&IQ-n3Rpr~|r<(L! zOBs*2Hnu>kQ0j&G2)qWN%@mkg01r8ET@5y5r?La+V)^Cu-eAZ3-ygcVyF+l_l{|`v zaY0eq(7WFqpQ#mJqYRhHudbD`)8}UsRNZiPy!X8!cwDLh?2bjc-NN>Ml~z-AIuO+ee<{`PFcxby&IaxzTG8=U?7r;j}?du8d!r3Wy* zy&)t%jmPQ0B)?xHfJ5(lUs0)^Hlx613KWp8^e2qN?QeVA^kD+Tqy_+qH$Vptgdjju zgz{7S_E~6oblp^59ja7QfiyglBuHKT{UP-Ag)Vsu0jD$r7pIX9M6OFDb4X)i1$U9s zJ3fYW8dOCo+WywJmKuSEprL`{5Re#wFetzQ3TXf$PXsIl1>~GdK>-UuE>Q^-O9LLT z1_sP~+(PmJI0p8C59ID*haH!$PJ$|wqHS+_Q%Sw}<0ew%FsAnG31RPEgEOVjpd^qi z?m!i$s*o}YB+71)sIzp8LQ)c78R;4v3|;ae3A^UZDS-oE0?Z^ck+At6`j9_C9Cl2) zIt8j2(uEh6q=-g!DMC5`0USX}K>;b2szeRi7)6}xlX9%39F&JigSzT6RYqC@&W;lm z=aPj~87Lslog09a9=qiEH7aNRhd&%c@_0vJwHp+G%H~5`U;Ek&AX8z$0TMs}1SpRu zs?Go=fKp2j5bnKc9F8C7Lx)DX!y=A!0S?uMibHZxgOOAPhn9ddsUwdAQ!(>D`cX=Y zUE5V*J3$pn(bm_zX1ZY+WAf7Dkbna$&ihyeBp{&L+|`2O`D%qRJU|JUK?8t*rDGP* zfHiMk=o%U-g&dqpo$^A`qiaIR)ZS=R2g7)?=Go0LYE`}kqLtf>69z-kAmGDurr^{P^Z zX?UaqK&UmqxcBi0NkY;bkc08C=+Qfw=8~3-Wp26~5MUuycwpguEOY77_46;iG+)D( zVYLdX9Ma2Qo{mQb35jtyyLMUJ$E4JXLxKP^TX6Et>c=i&s6|vF(gQ5uB%r#7hfCm; z&UqX6fc1$_cqtyX1gjNLWsoLb{NfansV-M_0DAc0l9wc<)*OHwl0VL&7y>LAi!eCM z*l<{Ya#*BEvTOxJ*9>3AdTz!w4XasD<&ZA8pj0EI0#)Xa1SkLrsR9y~9%^o;$DmAm zHE{qeJko`A=thRrph*?5kg`OwERXUIf95m!n>7Wi8Bpbrp8x#RI!o1^8x4utGbu_8 zhQmUN^3ChViFBDNWL)xb%T*zvEJOndP+)!TbAGjl4Z~^_R2ii4XFaQQbC;yN(ZDg% zg;9YN9g1U-H($MBB3VB7%BaGTk&-IJoJZ;$*5#MyOK%8Pqo8>6nZDc`f9g|9GyTMz zHgzWnO0B!YS=Hs6HGf>B3I)eZcZY>_h=GA2A~$m7m2oLdidV!5)#941)$Nd`H+b&x zbI&bFhomH(#G>YWOhWbjE2uhu;G)pAgTk)JFzO;52TTI{(-q!*`sv}Lx7}uG`mu9l;8u1w|Gk`5K3f*1&x;mNp^jz_3Ff0)|$I6QOkd~{aTzKiGA@j-du zbaT!DV%lRlW}S=J>TGiPkrujYx-v*x&N-(90P8LSgk_gm2BM<)DsD&%n~NWKAS{t2 z;zzH&HuNq}wQH3tJ9Dac<;pPji(jPmp>9JT{9yH)@r=NtW6~a2xjS}*sqNcKAzFrX z<=J-Oh5538MH^RjCE2W+#rDvpEw|}QwV zod=xI_;+9pYJBEg@2RJTvETl-WVPjPyZ6UG4%=Swid<^$Ft!M>1{t$_yuun}o|PCE zBUfD&UtDv%swGj7o`&?qC#K_)sXJ7jU;!+(?COCeYiRWQ-!Ftj?U_K1{^Td256PV& z*RPH-`qQ5lLZS)-FL*&1{lO2a*Cv)MIxb`O&YfW@S&^}!fpJ@%eB0|@7nemFSCy)2 zptumRoOTl3bY+_xIv^wqK%B2b-3@>BtD*17Po6HfAl7~4kzw>lKMH+MctXM1_9pc| z;~Ca5x)&{~T5$g}pBaX~{N<{7?D-Ql=wr5l5-`A7ho*zmR#`_|SAN7Qn$>yD1lj5Ao-32e5QqVWn)?t$l>JbPuf?UQpwpfb|5 z>BJLD1yU$JQF*B((QCX1Wp8LlSU#A$1HNcmkf)v`#;mbl|2p)Za!NhftLEu@%2P^) zgDkRE+@Q7?jC|``m5YdA*)V}|;XbjFk*bO8P*5mUMWC`oV`)O7@TB2^gvz5r72N0# ze;E2$#b|@;Ua-Ih{hs5FYr3>vjkTlS`A$XauF--SZ%3s*t2)|DwQah%T`DDI;DzQvWzEAxVkpSg?edVS zs61|fYUqUPKKf`=gFPpmRCn?H=bvxabhW7ND&269H`|q*t3b7r5ufS@0wht;??Tj%m4)Zmzw zn;5%lIaVA-uD-ffwwBJ80kAmQpUfYdQF~0h1upE?bl#WX^ z8v8++)ss>)Jz9($)M^BNj^GVwfwEuo2-5LvJR-mI46PfW&2cG{|n!G7t{~q#;!dKVOr-d9nrphT}nT&A>wa zVGVA5-t)rbz4ux<{-^IrPYR>o{jM!Zd0Hc(Ljnq#0FPF{?~^nDjy%+VP^&0qYvV;X zOFBG~m0He<+n&Pm{4g<45eZwVx2zkPTc~kOqJRYyKq0#LIzjC`_SkU!yWVAGB0&He zRoVCvjTJxxR-bxVtCDr_!3S+2ck-TlO7}bOJX?vkgC_puApr(J4{PFz8s9BrfHWXd z_s6{94WW1a`r3D*UE>uCBq~{{@Yf&}Tu_`eAUPxd}{Obhd1r4du zmTS4?X6;Vu)mu&;%*QD5Sec$#VJnhlYlB);op{>QLXT9?h)nQiT@j=`8vKE@L$5D( zYTb@F&qLl5wMtPJBq~H3dWXl5ke_0sr`p@b{|c3MP#Fv3fC}nGf>23_DpEzrO>iET zj;j7W?&h0Aw;t}dS}Fk&>LPY|b=L|k04@0a?*o>dZ7_*%RA;;rB%}yH+w}^DIN&A~ zuK4`t!`Sp&+xqU3z%qdlD3c`GnD&l`n^I}8S?y}|zjeT?VRQc>(ZuyQ5D$UXgd36N zHzw7zR!cxWAbT;4U+I9XO2&po9-?1UEwnv$EO<8IszE}MT$)_%t<)yVvA_Pci96{M zG#1ZG=zus@TVJY|m61D1@yi|5=l#V0YS2e+x^lRfhDl_}liLzLRu4+0ey`WtI3J^8wdeQ8S|lCkX?DcG}V)4#8o? zH$VlpTMZULicRo5B*vt+Lh=U$P9kBcEr3*I-Nk@f?rFEE;V_ehUAoH_!vZx=m~$CW+9wkxbukUY31(AfSSaiytYw0=L(58k*Lxit_ea$M zhA|57$L&&qKw_G(UlUGN7#N2zAP51+YEiyJUjTjZxfTX8_gBc*f%I)ub2ocPI4h9ONOX2j_kt#i;xxS>B&HBi7|&a_vV z_0rfTzs#euY?aVKw^WifPpj;kUjO=3l4#6!Ifv^i)aPrcS0uPszvtIGQ;>KlfM8G{ zQ8))xI!ga$Bnl{aE@7+tX~$Akm=IUX7ktB;2DMkY@yj&ksH03^v* zLfB)s@A~UoDY~(1U1|v3dkKCnIWFs}F%+Q9mK%}jew0?h7cN|wzPADvjq45F&bqNj z{NR1}wX?{^%gVut3&?si0_*Lg}RHqk5icI6xIo;>VNvv!{{~Fls@y1Yt~>qo(#wF28+pLw=W;H zVWyL6kT#`lX=9Tpg)l(7#STzwJmCthZ$WmSsB)2q6ylIP^lMrP8MOJTP?Mylig6$; z0}=OC3=c{3Wg_CuI5x?c8f?Q?B!2(6CdBc;a?e}#GuiSy?bZM)^UF$PCL=2oKqHR# zLKJO_8+hqU?bDZL3yUEEhJ{rYQ+cO^CmwH4^Zd=+&(xs4&+6kF<~BNqWFZ|*Wz)_a z=iFt!SeBl9qvk4%6bm(TKSush@<+(?CDEWlmNNXJTw!$|n&F_Y%-bPJta9U71;-P| zF)?P|#m3KeZJ*|A{c)}ExB8i?H#VUQh8Yn$_NBYCvl7*nSwi9gxzN;~LUbkL6c@+p zPlruAwi%CTn{m4!AvH)4uO|qBh4iqB!6cdGA$$ys$~Q9?W6T<3lc(NFPp(_nbQ}1E zv^DKY*CO;d>3LTMs?;A#<~f$1TYvi`O{}K-1;VMAj5o!rfx@7$ zSMvX*hkCUha<{->c{nH=uT)5%(wiCj2ehr3FXEeZ)gW!#wk_b5-n9#K1Koc7RFjKE& zc~{9x5n^A*&g)#V& zm)NV3gV}A!6PMUW1qZ}?#)5(fKcfTI0S0P`!#!@v` zX~1)-%3PQ`=soSUwtrROkQ|V2L^&vn?A*_OHjLhXztv)%zH+=)pQi3e>g1rjiVmh# z$>OIK_%LByrh7eVFjafBu`0uC$!q}~qXJ#(yq+GqL~;B|`Nc%m>mtl@9>yd}Ari%K zj8w(rR5hs@zT%3|qn|%$##I`V7=vO+K4&_E4g1lDY(oOKNWJ`y6)Q56UI&IWAzd7| zDp@>V_u|E2FV<`Y=Kx}9Lgg{MAWg)Pus5O-tC1>2^8E4oSkx8uMpk7Ew7na}Sw1ai5z+67&uDil{T0_L3050DWZ`rcN!max0 z9;DGH#%^%LMn@f0O|$f!byga$6ag0AEIoy^C2*KS5oQqSST1D}tG?Ab!LC`e{%(|R zKS#X|u>=yZP=Oc~NLMdCQ6a99R6U@^=vL46i6`?KtTB$gH+v5+m81vJeeih`JTFNO zY1OAbRdq|(iHTMAKm62p6-PaA)C=dwc2LKkYG2#O(v-3E^qjx~5Nhz>%cTh>=3-DJ zWUN0D7_R^{f!D)~C`1MNoGR9xO3t_~dY!&kpN9elNX%=P&tQ$kTfkiXGy-W-9pE(W z78+T*HgnIS17P)PBK+&Z5v7Fvio6KW1^ zg@&Si0ac)(QfboZvMEu<`g^o0Kmn5qkswTSOmsKX-Kd~17D?3}N#(uAAD@2n%Bn$Z zDl<03ZVYReF133A0B4O%L(Au--19gf)GXE|p1tWl zB|zG{_2pqt0W9uh1UGSHZSuy^XN|P&~9ZP972s!+BqEC{lL^G_J50eC+nyb@#>` zu;!_O*U7+fiQt}IpFAwi;gKNfPkn&Ico%;}(4*~TqviiKAhqCVe#UjiA|P#5I4-|c zacls_r+2AsBDY3yGa@{#2o&Hi@C<;$Q5ZL5Lne@zTg4V2u!^MWXnnl4LBF&zA+;Az zK9xO{CV<6|u;geEpC`Eqj=FoC{z1v;9d~efQ*NQY`lIXcHB;ptjd_=ZNy>_Glb?4>h zLnLdyEWo?;8x^r+c|M@Ub>jYXmbl{pX+Rod`A0qyy0b=r72_%oNW9kr5~^;qLOc?+ zT^?iN6O!1-Ax&?LjxAaQiW7xW#R&|H9z6(>1u(w;Kqa~gbYMzK9bXt8CslQ~U_C5Y zG!6~njp2}Zc+`tGic8V~rJu@I6$N8JdXoktNL9Z8te3G9*T?IH^t%dnNuoY3Ndx+6 zhJO>J9@Q=H9FmVqbnuA;(nf`wr|X}3_3Ak9Tu(4epwbwZFdR^IKzc~tq)EqY9{PG#Wfn@4vQ`Aexr|h~VZjM{ z3S$;h1ti8Rq{~+Oj=T>lD|AdU>6O^xI2k$l@%5HOW$Dq^j0vhLMSYO|Uh*NJiKgg^Z$oTZ-&>MoZ8t6~O{Qh>oY1RNv@m52Ic zl?PSz(`-2vRi3h%s|AWo6;&W7v0N}D+_*sf5s!aRByS0F9R|k90&$dj^B$?eU0SVJ zBx~%Hzx*Yf`|WRsd5X`pTc}@{StSb<7`wHU#9Qs-WHg+kH@eHTLSD(0K~kGwhHugZ z56V9z4+@e1PtU92g-4SGlz zp2D#NW0U<~1sH&ESa)Vz>G?4nfP|{MFYz0c#<;{e#-;U&N3JeNrF)po$ zj;luNl_)Qy>Uc$UHmg!B;u3c#gl4iUJx=pN52w%}Aw@I>tKiI&Fd8<<-Qr-7T?~mf z@M{Vn)vfZpQ5prsb#=jFsfnJ3Ugle1hedd}jax27uIhM)gqh9Q<5G0D;*39ZT#N>H z?SMpC&4A*%x?mwySUkYuA-#tgG#z7n5Xa*@EFI1MU#~AA&wy#oCrNZbo(m}g&N_KO zq4wiZs9lhByQV>LZC$XaI1j+87-JX521Ie3ygT>)ffx8g_U_> zhDxMO$*DT*6tEZ&bubmDIwB!HFJgrOQyXIe6=#r?#!5r%0K{|WTuYMVWwiqoWtG7q zu?QCF=y;Y@0LGdajpCa;=*2V`9wVgev6YT%7Mzzyh({WL5vSV%iGtb%in1KmNs2Ef0apnY4~o90r_wXg|3CvCMhMauOB?wy_g&4z z4X#t>^6)$lCy84b3LOmZgSZ#>1r8HdRv4+%eG1)BxJ$=)7FOv@)s=<2tJxyBF~3(W6CgJA=}gD$onf5Ryk~yo>1p)GOc+2 zVSs}NF1vgHpwvK2Zk7Em#On6T2BD!BqcWNn)i#rMrWTYRq7cvG;rX}>(M z05>K-tm7et0P~GCfFqy1uvCa@;9=qi0#K~lfC3z(2vv*91rj@fkZ9j{0;D3zQI^!r zBqVMcKUZ3bHb#JTvHbFUnYE-EMN`So4W&@PpyCyKt*l9_t0miE_qY~sd^>8*pc^wGrhUOPF3$IQn zew$f^v*P)Q*F000W7X+uL$Nkc;* zP;zf(X>4Tx07!|ImIqW*SsKUhd+Ci9h=7z(Lzg05O6Z{o(!oYZLI@>>gwSlLh$Aqf zh=^cCM?e%Dl_Ggz#|j)|q?h5>|pXuuv2*&K<884?l*5Y0UQuJ^r2E~4A!Q?>s6 z_x~zIE>FS%0181ko-5&`B76!NZ5)v}9RQRFiR)#ii>9~~VP!GWAi_0M%%A4ADUP4! z?(aF_p`Hl;4gj9aW{dd%kj9WWJ%htX>X4D$0!txRAVk<5VOLHfn~QKR!e*(dE2j7; z!bb6bsl)$U&3IW&Hk&Ww>Aidx-b)}6rLeRA&)4z4m6{@*SwjyQhmPt zVKdAY&#om+j$q2x<*{Tna}vX&W;jC-xp0Oh$zcJrIi9k(SQ;wpIYI0r+heNaFZ&X( zWceKSY(MFV;eNAyM$3BO^1QrdabbikUzF}4t1n6kk>&GJd}VP-Mwo1FI&#=%=Z47M zPZHZdWQKtN1OYbSr1P@UryBNLA<7mD_=)LsCURqVbe51~VMe#Mw6+0Y>i$jty>DsX z?-fM5HXBQ82f(oa3G!!SY~&oAeg**b{cKF{4RSQL0&u3ABNb;%$Iw$>7(fK_KpCh3 zE#&+d0drst?0_?H2j0LR1cPu81C{{}NCc@s3^Ktguny#dLa-I=02N>#I0$OMF>nGj zgEnv;Tn5)cH@FKPf_^XrUV<_39!x+Ggo7v$6;gw=Ap^)1vW6TWSI8R*ghHVhC=TL7 zLP!d&f;K>fPzh849e`?~pP|#xdFU$C1Ko!Ppb_W|^chCMWLO#2gbm?&umjA51K@CY zDa?n{;2by)-U64yRq#=`2|f>BhwsAu@Jo0c1yCdu4W)xJM>(K8QNgHKR02wjT7xP; zm7%Io^{7@%d`u=LA5(@ojA_JN!ra9SVcui0SQ?grwa5BlW3WlsmDnQe9&7`) z9ovH)#E#=|I5nIp&IK2YW8>0s`M6!UqquXpTeuAo8(S;aJOd_r$mJ{oVmxzyuZ%HJQ zF3FL!h$JB8lFCWPNmob%q)%ievI*Ifyo4+zZy{Hc+sXIIZz&XtA;p~%OG&3}q0~|? zP@Yge%2DMkLKbS z>X0&4nW4;5PEsyZKBnBIJf@FYWUj%{k0D zyg8fa)X%v!=Y#58Rd-dMYJqBl>Rr{(YIHSkwPdwzYRzho)zRuE>WkDf)%U7jQXieG zJlA@LfKHdrgf2rjLU+AxgYIKJqMn0Zf?la! zhu)aJwtkTQD*ZbB2L=QK2ZKa|od%r-9}F3WQHGlgn+=~cR2eKr4x^6o$cSR(W|U@B zWpu|FYwTd0Y`n*~+XObTHAyt7G`VRCo7$NQO!t`fm|@Hu&4gxEW_{*lbEbKQd7b%y z1u+ zdY3YmW-YzCOnq6(vNOx&m$R3jjKjo5#T|+J!VYFvvB%?C@w?;4IG&uHoR?g8ZYg(! z=fW%D4JWuHlq5XoyYRR3M-tr<%MwQgo`MR&>m?MJI0%YU5QlCY(#*sgf*R_s>c*4}My+iFS_OL9sEw+C%+Dy5ee zl)l@se8<(Y`DOcd5_d{>_Lm2ix9rm2wRP8*io}Y$l^&H1yES%i-u+<@ch9Z8?tAO^ zY3?iB_j$iy|Gfjg2b!u3tI7^y4`v*Eb|~^t=T8nl)gD$qTzL3vwXnLsCbZ^at$l6n z5sf3ob#R@uZsh2aqus~6jmD9VZ=5)}JyswY!np zSkMGDWjBpACpP!D#I*FB_CMXx>fGA+i^VV1Z8~k0XH?D{9&YrbxGz3GPSjmBSX ze{Jlt>uS1bf3v0AvAeZrLC@J+Znw_g_PTxf4(rbKy9@93^hWgF>s!*-e~)|b`Tdmp zuODPQn0T1`2=l1mvBKlBCmK(xelz~9q2I3m%z)Rxji+Hx9}aQ`U;Zxn{mW3^Gs?5F zVeR4C=hn~LMtnxPUo3tx^iuS4Vl@8`#XokxGJ19DPxn7>j75(Py%xWod{gvR?QQkD z`R_W$L&l%HPkle}q2Qz1$C^(LpE^HBeIB03{DS*Z{?+(v>$iY!k0w(mCq-;A`@0oD zAp=fG0N_nE0F)TSJ0QN9xOmzhe-||E>Aw^BPdx3RzsnAQYIgu4asdcLJjz~V7$8hW zo>Mj`+#SF+HnQ`Yz3*XhB0DpG<^Aga%>0#AE%L>oUg*ju zxZlCO3%3LAf8f@^HNbUJ8I8b^XbV9~WpD)V2)IrvgAtgGHoOIw2`uGzf>s7#bX#Yr}`t$sb=j7OX0`xa-F%W$)gE zjGFMUytgx?2_HtH)8IN3bwmj}A0r$9izB}3s*#dPB@s%%wYVD=(XXc!*8~ zXKsjF=8TReVO=qv+u??q<2q(^y=?#8kzlbqaFDE+R3c1Cqm+q^oxDxnerGr00s1{+ z(*v9`kFZxAiLOCo=h+Q@^e59XUvciDgmGO#AGkTUV@#^5DrE5BuJZ6Be{uN6Pb0#A zg?rB6m36QqsYDL$rS@pfpVwawo7n?wf<)&oIH(p=DTe7%GJoC>r0aulh?aokKpVPJ zhK!B`*yR{M8hCw*$78bP`Z0*>YMt|!F^3T}2QU}J+isrW=QRRcMzZVsk(fst*wx4 z4^5LUUDyRxhwxJ_IF8hLbC|>`p!0Zd#$>{TUUJvnuR~q>MKM5~+6?zJBjrpTLBhC- z3xLG|U3Sq>>D7~~KwV@IECtS!HU~UNnlEKZ89%l`&Ny`_i?C^h%_zrsN0@AXhJicD z9K4=A;_~LJM@qM@lrB#NI^cLfIUurYxE|w1y2f#_82u{w%Z_GencvbvfCF?ZVwVLt zWfm!S2|F3%6#$Flw_)vQfJGp5v7wShUwNM7sg(JPk0j>3I$6GK9E-APIT&SavMP58 z`!xn|wmGWf$90t#pCyZc*wV$g0>-YXlu>o6lvN`fm(M>J89Ct*`RhlVx&rhA#1;iO zWfY-KDOXyEhH>>4pu29LC}T!(!RSelzd8)5HzOZ_b9T`&cvLDCQe9ms@#-r1k6-d+ zL4Y`C{v7U|0JlscyamgVC=N71jWioKeOiP3_Gy|CP3hwDonV>LrMcKWI-ScXT{QrW z#aGL|eK8q6?orwKe#kKV7!rh3F?c1Xa+R>FFfymvqw_C6nj%96s|m`Sw+{+m9n)KmIE>pRk_VQ*jMsUK zeiZ3-N?~xBf8MzxW%S5~s7!03n5E{GqlDdnL0M@IOl4(E9{cGb-oDG0ES0WIV3{Q$ z?9FAmnXag)z^bvE{P>|iTM31>%d#^Jm)ji1IqP+MC4&%f}A%$WVSS+#~YBCu8?rS{87 zCC#iLo#~t0<<0a&dJ9o;zJ@Kgn06|D5lMWCBLjfTuncTj8`{dg8QP4%bq7Xc&LpkmP=GdX7z3#xivyc>HMQx51=U+~bF=R#b!OZQ^P0|U1iY>biuDb{JY_|T zNkY0eRLY9WxiAdTMc~W`aod?uYQVapzqD!uh-WnB9;XWp4=it!TutkeMXKfqpzR2b z^0+`@TKY9L1fFFRsQus*G}pYfeA!qmNc2fI*lAju4wfcVYQT7wVyNBqTW{o^i^Kt? zN=&;hc+#AS2!`#LmOS+}Twm`2=08URXdZaAkm9wg4tDZbKPMu7ip6W!Xy)FxPcuR` zq0{F#%CxD<4oVk+a~C1`H;zXP(l-Jn3(j~leZj&}nM_uz^RK<_C6p4do6u}dv1(e3QHG(?9wIsCfh4Uw_NwPuFjM&uP#T*JZVGy|2TJ`95tt(nN7oN zd!0tw)6c&5g>BW9c5ysVv+C-RU}usp@}Ux|)2l?gjBMfxBIhZW+;ZI&Bf&~b8P(*C zHyjdG>@YA(a+a|afXzl{7uut6&6Ojhp_^LDRJu5Tsv6xK?%ZSN&OM$k#{-P@=mJE2 z+#o#5cffFG4A^~vvA zZ+2blVO`!b-|=1bNRt&G@mR!N{YHyd^r+eDqF06r&VxI`u4w(5QLqVeKsa#b;Bf$h zl&?x;Y1JXM>fQ{_&EecA0L@=9res)Cy(~P3>N-SRF%AoHi^ynCz_?alXZM9BsB^zD z5Nrb|XWyjYsqf}Yt1`Q!?Bmf37o&bh%3YI{EAa_uUxwFjqbk`F#Vi)DJptn+J=pHZ z9b455q`*+B)Y+*;4zzI&r;g^-MXFWSPl6gWmiexVOv-@9TDkfPZL6Eo`{mh_;{%)` zM%oiF-3|NQIpw5&a`>zsh#PlzE9W#^lagOVn*y2Ds(I6RbD5(W8BWTT%g1BeQ6E+3 zwNcDs@Y)NoThREx5olU0Zr-9MD084R%H2Xc_80;!5r73#o&ZBZdC9j=wbDmV}|+QfaC zFJ&n#@rTItX$J*Tdl5c>jhy7761SDt9)N|O)N+%&@~RPNvknY_QjqAA)OTb0TM!95 zfB`w(4oVr9^`2^U79y@{yk$$|W}0Uii@upIHeg4i6AN^()#n@k;Z1Vu(#8Dw0H*t} z=vAV&j=tVJ+9m+yFY}W)AK6DvI&qMhLBj-0p9?9kpnkCdTW`0Pw!$TghJejM@dm_K zg^cT9**V>K+N2bHJsWQHD$&mAwa>SD1Wi_(H%`X`)|j1%hR32xSup`SAB{iU?$M@o zV~kC*-ofhIsl)Mn_F?)gEW4E^0VAPpsv3PMOW}o#Zo*T;5p+oeuVAcV0mk=xLQj&X zPHB)cPwS6MrgW)9nSSQ})l}!+WCe;(n(4BaQlp&_o9Xpyrl2gffBJ3ax<7PW&%c^y zAot#9S0U8`A8Z9^>rGt7n}eW|ML#>rPCDGO6e#*;xb;<{wuNma8B*pgLdfH}#>+3! zt%;k``{m~;4i0b%6e$K^+zE%?>zaFPAABc+NBl@0Q2yMNopiZ*VE{hhDo;}deU&Z( zmka2@8_ZiV`l>PMSU-C8j5uf#p<#k8YFn%rfKj?=9Q28k^UYhvdU1kf0;G4b`hK>I zfwr2b2o{0MUc%S}Z7ZdWZFfO){e;_o%v^1|yEjX3rjxSxLVos-{R`2G5GPMYp#l32+7oCb z)z|tpx|-6vHOkMvCvDk_aSx_0yJfxE9&InBjDUHdc?*$vJcY9;Q_Tz-rcs#2;et^i z0i(_ffW=nQ1jPrGnWc-Va-(eLFx@CCPNaL$@lqX2o!?IkqZfT<_c*T8yOG+7oqU$kG)&hTAp=YFpt4q>OVK zB`zsjHceykHqnk%u;T=U0*o7EZj=MG3id+R1f`wzKy!c!B+V(3i%KMD>R1V-taZ~= zrsf#^P|(yzpN>1G5oW8tQJI&6$-QabR4BmK*e&VXr&^Zc^Fl7EbQv9Pqja&nY*nIH zxdRxFYwOZJ_c=^UqHp#==d!ev-LfU}@eB8)1u0m+sVq0Kp<1yq=QphMCHMOJIOfb4 zJ|(f!E_VhPkHfudU&tnI)R;~3K$?(MV?E-!bM(9brohT~a zR=`4FaX?<*ek80KJXn)f6KTK*6!~8?;t+CXf%=Pas|B!}?|%@qxZL@}H)Ppm&mtV6 zW5Ibc#BGJqmN{%J$_(jYo{e|GQeXg1XzpsIH68Y{_Sw@W{#=%n3(p%V!u1?7G)nN<-abzc^sw4d7V;4=S=Q=9PGQsl~(hT)t{R=G;p z1E^pSoKO5(%>(yObzU*`SA@PQG$qW>@&yifO9D&EILA#I-%IZM=Qr%W^F-<{xZl_p zGR1R|unSShEW4mB*N?*~DCP1_)4PoRmx&B13vH&8a@efia^eYrdtC=7r^heZt`hm; z@pic3S_}OtlN;o@XK1KrV|BvSWjuZD1cC*o9d9M%M-Md1TW?oMRh*wMs&vi?@=K#O zC1J6T#S$`cTtd!XP+0)elwE_ySvQ@%V&uv>E`NMumrR=eulQ~V$0b15Bepug$q)(m zE;=FK&e&vMdgiHFGIItG)+k{65mdkwtWe|ZVseh}+J!szAKsBYduw1|uEh&_)y^mQ z^Z}(=pgvlmwVsCGX_FIj_Z^X|HZxluVJa;;1&!ZjtVNv5{3^NlvghRcKYR`05RCxm z|3X}gk&Q~Eohft*ivKD!bA~=)_0*t0cNGsTwtw4WAIm%M?s7g7#t((5+p}knA2xa9 z)9u9{i9P+yZu#It-c-dR_Fbn1_vUraf4JfGYbWCwp+AS1jaX(zGKI5QbWl`}w+r|g z{`aJ358Oq5D?bd3pTd1$Uohj@w33!Leuhtv0;tc58CKQEhnNf(mvmeR9Ht4Fu2LzrGgiu_OUKIA@4YG?{jJ$< z#!4`FJT4=(rV{T(&V^=fKJ8t74b?4)4a?-51V#DL@#etui*2g%s0QsY)gT?ysr2E{ zKvCM2E>y<^qU7Aj1WjM2*bggy1zxwBm`^Q2=dbiLvn0N>IyTc;#!cF< zDE~l!-DGFz)4Lk~=1S?Z?;vfM^6i|3jjM#2rBd2-C8%?n`g)dwaYrSZ8H*OyvCtcu zQpP9K9(V}x`yUa+y)O5>k(3FrZz1(eJICgYWAS)G*D1VnOlPMqU0mlY`Z{MZOj5sn zT4#Xfj1@pL48sdfZ^B+S(qy#;?F+rc&o)N^#!U(zP6mjZu%KkivpL*O`v={%NYwgM$H$Bg4;N?A%~9(s_RKEElduF#A8OcVtex8wo( z+R6Ro&_lRMX5}78C6X>SEL#a+`wm+1j+zRf%8*#1~QKT$Bl$BbU-tu41X^&s16@(p#}>P9~5)& zeKG+X4sHM}rdqOSsP)lFta3t|WNnaNZczh$`$n2}vaYkSe}4J1t|*YuyxHBAqG__? z=hristgbMNF#%g=USPO;LzS#qIT9hWGKSSL6~paI^Zu!)XBNx7-s6wyUcggRxzw-Y z#2cP~ahb0!;k<)D&?4vp@MyMjNVlLzA@(bmmHyqZc9g7Kq5Cctu9dMuRgv0|biVco zz3}30S#j+SEZeiMpSI7tzBfz`>Q&VqO^m36!%c^+k#ow5%Z2p6EWsdy|K;2k^^buM zBHK*GDT%+q;9drX6{sM` z9LGy^os`=M5HRGxA2Q)dIsUy2-yMk&H0O_0A!U%dhaY)Q7Mv4#mho~b^G3VI^UmoF zt9P>_N!YeX3xIOK!lP}@83c^fiI+PLx&9I`ep!K_RRgfv+64X!rWtXn#cF&puBY5J zrx%WS|IIFXF7v(&H{QJR)Dz=`FAeP52gxE>j&xxb^TFa> zd^?ga8S)r8T^D>^=jB&gWXi1H+r@6Dgz0mB|6&Tj@Z5THa}uDX9MBQ~PE}ziR{l`6 zIY3F_p9AvMr#LI4ea&xo*E0*&`7}EgBxJ-Z~OlHvUE{DoR3IKvnOQ< zs79J}Iwi{-srRNahY{!SEn!@ z%OX&nVA-RTf81F$LeeTd;F1{YU;p=Kc;lrds_+{LSWh@E83R%lmAaEx(h>LwwNK;@ z?(c95;NFGnr1BjBVzkq2-kFGSJ<;jPZw!b{B+TF0000Px+J4r-ARCt{2ox5%vHyDKvhpW}j%CZH-fQ?mv2yUX*0pe#d{3xze`B98CsoVwW z(&Y(K87V9ksUpXQjCDp#L2{Qn%bDT*qUZnv*q$4ghaZ35h6e6{PFE{-x>~W^>9`lT z82}i7J7G$bI{`k@8Bn_^RT}~TmseNXKi8^i4H+Y$W=g6x1ke*vJ0(>bVnRTzlvHU5 zFit|vlvHPkP06p3lIjcr%m}EJlBx`GDe<*YQk5ZqUCFPJl4=a`Dd{y)QjHkn4QLrKxB`LegRS%-ky45WtQOshTM%){q!AP~MI75IibV$`kNl}KRq{H-`sa2FAKv+7Y zYNDhVLvqkz`tFpPb5GT{_}LEluk)jLu}|!6?36nZc4HfVnatLl}t%CLtN=dp`4UtB_szOQl(Oo#Sl|E z&c36mlC-B>lw>1hijMQ|_swu=%8uPrA|=TU@m+cYzM66qF<(WQ>l--w+%fO`Gxdr}xh9x4AbrB~cBTDpAWNaC}Vg;0QQ8jG2;f zicLv$LWWA#FYlh?Xi2baf%$xzj@K7+=QO;&m{&tdG()CJ(!l}HE`Y;B0&2MS#U(>x zWMWK8q7pJjN89q)(Jp|489+$tfZhREgOD5T*<6%FF=VO)5yI(cTY}@`29)M#U3DOY z8#1Gp)_2FEBpM-8z4GOf;Nfw;W-cMzkY<1oAP*(M4XJU=iZQnaLkvoy5K{7(m0sOo zwUwHZpoY{$2V)dq6pT?2(m6jTG$p|asfP{<1`1$$Aw^0`f*Dd19bDWDrWoSV+5*B- z5|og7=-^VTE&lg82>GPFHWej745^O}seZN9frt*HtwK=}jF8&s;G$q`E)Kfsn-H=F z@5%2f1ts2w)Juod5GD34uMm_3A*4<^r1mKR=?0s^u_^H~BsCo_A7`4~vrEaAko1&z z6Ow|CS1+I8&4qoSm3nir#;cdlMy}{Lfyb+@n3OmhQh)5&)n3niq}rO24<%lN)Ezte zGVi$q@hEXJB=fEdQLgP*TRw3_yxWNq=ZynW)4^i^pIh%|v`mZ6fa&-#q)zlls2HB# zCnv`45Y~p|q(hpbs&7y~_}iGl7zGiO5Yhom7-CVCsdCvJ!ikWav131j-%p&k5e35> z05^k>4otMT*g!E1O^KBuq3CGHH9)#ehYWCE;^SvPU$T0VEi7TiCYHpf#5$<^eL1^E zL#{!{4H|MI#*N%3hvLYtPXdH(aTy!p_w|z~ZDQcAJQH>mvQGlowYaRREE_sz^b)tM zRjMU858Cx*`Zcc0Hceb2u!F+1+6om*j0|z1O;BYwn<(W=$*3VAzAGmpZs=mi zmY$ozMbCMao{~vILhabYMD?UrQPPY?9IF29PWPVS@)ecOmshs4iBdk44CZ90T^F_{ z?8X>%u`{m*N);bYVXRe}@qW7$jpglV(RLlP;wH?+4`}%ha%?W@WYVtBy%(=5C0axL z$E+mk+foH!FqW7~oyr}{aCy#s=v|eF86w?k+~e!F!p@frb`1SSbVbK%^U7}YJB+?` z@k45CUPP6h8FFYx*YH>?tt)JL@SJ!#3K6dNzGp~``3}Zfqw9ciGo*C$BKm7g)$L@u zs(!0#I|_`=D8$gv{FHRP_q`ky7ik|LcU^e;gy89u#(K`9-_J0~{1lSSZWD@S1BGp> zbF7KYjje{d{sC(96<);h?cx0Px_%00000NkvXX Hu0mjfybh3V diff --git a/source/funkin/editors/character/CharacterSelection.hx b/source/funkin/editors/character/CharacterSelection.hx index ae5e6635..9d1a60ed 100644 --- a/source/funkin/editors/character/CharacterSelection.hx +++ b/source/funkin/editors/character/CharacterSelection.hx @@ -27,13 +27,8 @@ class CharacterSelection extends EditorTreeMenu ]; list.insert(0, new NewOption("New Character", "New Character", function() { - openSubState(new UIWarningSubstate("New Character", "This feature isnt implemented yet", [ - { - label: "OK", - onClick: function(t) { - - } - } + openSubState(new UIWarningSubstate("New Character: Feature Not Implemented!", "This feature isnt implemented yet. Please wait for more cne updates to have this functional.\n\n\n- Codename Devs", [ + {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}} ])); })); diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index a5207063..49ec899c 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -53,8 +53,8 @@ class Charter extends UIState { public var gridBackdropDummy:CharterBackdropDummy; public var strumlineInfoBG:FlxSprite; - public var strumlineAddButton:CharterStrumlineExtraButton; - public var strumlineLockButton:CharterStrumlineExtraButton; + public var strumlineAddButton:CharterStrumlineButton; + public var strumlineLockButton:CharterStrumlineButton; public var hitsound:FlxSound; public var metronome:FlxSound; @@ -378,10 +378,10 @@ class Charter extends UIState { strumlineInfoBG.y = 23; strumlineInfoBG.scrollFactor.set(); - strumlineAddButton = new CharterStrumlineExtraButton("editors/charter/add-strumline", "Create New"); + strumlineAddButton = new CharterStrumlineButton("editors/charter/add-strumline", "Create New"); strumlineAddButton.onClick = createStrumWithUI; - strumlineLockButton = new CharterStrumlineExtraButton("editors/charter/add-strumline", "Lock/Unlock"); + strumlineLockButton = new CharterStrumlineButton("editors/charter/lock-strumline", "Lock/Unlock"); strumlineLockButton.onClick = function () { if (strumLines != null) strumLines.draggable = !strumLines.draggable; }; diff --git a/source/funkin/editors/charter/CharterSelection.hx b/source/funkin/editors/charter/CharterSelection.hx index e7d2277f..d850b4aa 100644 --- a/source/funkin/editors/charter/CharterSelection.hx +++ b/source/funkin/editors/charter/CharterSelection.hx @@ -32,13 +32,8 @@ class CharterSelection extends EditorTreeMenu { }) ]; list.push(new NewOption("New Difficulty", "New Difficulty", function() { - openSubState(new UIWarningSubstate("New Difficulty", "This feature isnt implemented yet", [ - { - label: "OK", - onClick: function(t) { - - } - } + openSubState(new UIWarningSubstate("New Difficulty: Feature Not Implemented!", "This feature isnt implemented yet. Please wait for more cne updates to have this functional.\n\n\n- Codename Devs", [ + {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}} ])); })); optionsTree.add(new OptionsScreen(s.name, "Select a difficulty to continue.", list)); @@ -91,6 +86,15 @@ class CharterSelection extends EditorTreeMenu { } public function saveSong(creation:SongCreationData) { + var songAlreadlyExsits:Bool = [for (s in freeplayList.songs) s.name.toLowerCase()].contains(creation.meta.name.toLowerCase().replace("-", " ")); + + if (songAlreadlyExsits) { + openSubState(new UIWarningSubstate("Creating Song: Error!", "The song you are trying to create alreadly exists, if you would like to override it delete the song first!", [ + {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}} + ])); + return; + } + // Paths var songsDir:String = '${Paths.getAssetsRoot()}/songs/'; var songFolder:String = '$songsDir${creation.meta.name.replace("-", " ")}'; @@ -115,13 +119,8 @@ class CharterSelection extends EditorTreeMenu { }) ]; list.push(new NewOption("New Difficulty", "New Difficulty", function() { - openSubState(new UIWarningSubstate("New Difficulty", "This feature isnt implemented yet", [ - { - label: "OK", - onClick: function(t) { - - } - } + openSubState(new UIWarningSubstate("New Difficulty: Feature Not Implemented!", "This feature isnt implemented yet. Please wait for more cne updates to have this functional.\n\n\n- Codename Devs", [ + {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}} ])); })); optionsTree.add(new OptionsScreen(creation.meta.name, "Select a difficulty to continue.", list)); diff --git a/source/funkin/editors/charter/CharterStrumline.hx b/source/funkin/editors/charter/CharterStrumline.hx index 0319bf7b..78fb0275 100644 --- a/source/funkin/editors/charter/CharterStrumline.hx +++ b/source/funkin/editors/charter/CharterStrumline.hx @@ -13,7 +13,7 @@ class CharterStrumline extends UISprite { public var draggingSprite:UISprite; public var healthIcon:HealthIcon; - public var button:CharterStrumlineButton; + public var button:CharterStrumlineOptions; public var draggable:Bool = false; public var dragging:Bool = false; @@ -47,7 +47,7 @@ class CharterStrumline extends UISprite { draggingSprite.cursor = BUTTON; members.push(draggingSprite); - button = new CharterStrumlineButton(this); + button = new CharterStrumlineOptions(this); members.push(button); } @@ -95,7 +95,7 @@ class CharterStrumline extends UISprite { } } -class CharterStrumlineButton extends UITopMenuButton { +class CharterStrumlineOptions extends UITopMenuButton { var strLine:CharterStrumline; public function new(parent:CharterStrumline) { super(0, 95, null, "Options ↓", []); @@ -132,13 +132,17 @@ class CharterStrumlineButton extends UITopMenuButton { label: "Edit", onSelect: function (_) { Charter.instance.editStrumline(strLine.strumLine); - } + }, + color: 0xFFFFFF00, + icon: 2 }, { label: "Delete", onSelect: function (_) { Charter.instance.deleteStrumlineFromData(strLine.strumLine); - } + }, + color: 0xFFFF0000, + icon: 3 } ]; super.openContextMenu(); diff --git a/source/funkin/editors/charter/CharterStrumlineExtraButton.hx b/source/funkin/editors/charter/CharterStrumlineButton.hx similarity index 91% rename from source/funkin/editors/charter/CharterStrumlineExtraButton.hx rename to source/funkin/editors/charter/CharterStrumlineButton.hx index 471aebe5..2cd156cf 100644 --- a/source/funkin/editors/charter/CharterStrumlineExtraButton.hx +++ b/source/funkin/editors/charter/CharterStrumlineButton.hx @@ -2,7 +2,7 @@ package funkin.editors.charter; import flixel.math.FlxPoint; -class CharterStrumlineExtraButton extends UISprite { +class CharterStrumlineButton extends UISprite { public var button:UISprite; public var text:UIText; @@ -30,7 +30,7 @@ class CharterStrumlineExtraButton extends UISprite { var buttonScale:FlxPoint = FlxPoint.get(0,0); public override function update(elapsed:Float) { - button.follow(this, ((40 * 4) - button.width) / 2, 18); + button.follow(this, ((40 * 4) - button.width) / 2, 24); text.follow(this, 0, 84); super.update(elapsed); diff --git a/source/funkin/editors/ui/UIContextMenu.hx b/source/funkin/editors/ui/UIContextMenu.hx index bf4d08fc..8a60a0ff 100644 --- a/source/funkin/editors/ui/UIContextMenu.hx +++ b/source/funkin/editors/ui/UIContextMenu.hx @@ -115,6 +115,7 @@ typedef UIContextMenuOption = { var ?keybind:Array; var ?keybinds:Array>; var ?keybindText:String; + var ?color:Int; var ?icon:Int; var ?onSelect:UIContextMenuOption->Void; var ?childs:Array; @@ -132,6 +133,7 @@ class UIContextMenuOptionSpr extends UISliceSprite { label = new UIText(20, 2, 0, option.label); this.option = option; this.parent = parent; + this.color = option.color; if (option.icon != null && option.icon > 0) { icon = new FlxSprite(0, 0).loadGraphic(Paths.image('editors/ui/context-icons'), true, 20, 20); diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx index a67db6f9..cd1a70de 100644 --- a/source/funkin/editors/ui/UIWarningSubstate.hx +++ b/source/funkin/editors/ui/UIWarningSubstate.hx @@ -72,7 +72,7 @@ class UIWarningSubstate extends MusicBeatSubstate { var xPos = (FlxG.width - (30 + (170 * buttons.length))) / 2; for(k=>b in buttons) { - var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - (42 + 16), b.label, function() { + var button = new UIButton(xPos + 20 + (170 * k), spr.y + spr.bHeight - (36 + 16), b.label, function() { b.onClick(this); close(); }, 160, 30); diff --git a/source/funkin/options/type/NewOption.hx b/source/funkin/options/type/NewOption.hx index bd7d1a14..e5c0f9eb 100644 --- a/source/funkin/options/type/NewOption.hx +++ b/source/funkin/options/type/NewOption.hx @@ -13,6 +13,7 @@ class NewOption extends TextOption { iconSpr = new FlxSprite().loadGraphic(Paths.image("editors/new")); iconSpr.setPosition(90 - iconSpr.width, (__text.height - iconSpr.height) / 2); + iconSpr.offset.set(20, -15); add(iconSpr); } } \ No newline at end of file From b92f2f5a33ab2689a2cdfab4023e44f5ab52bd58 Mon Sep 17 00:00:00 2001 From: bctix <51544115+bctix@users.noreply.github.com> Date: Tue, 19 Sep 2023 00:31:26 -0700 Subject: [PATCH 33/72] fix for base game noteTypes (#202) --- source/funkin/backend/chart/BaseGameParser.hx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/funkin/backend/chart/BaseGameParser.hx b/source/funkin/backend/chart/BaseGameParser.hx index b8d2d6b9..71e707cc 100644 --- a/source/funkin/backend/chart/BaseGameParser.hx +++ b/source/funkin/backend/chart/BaseGameParser.hx @@ -69,12 +69,13 @@ class BaseGameParser { var gottaHitNote:Bool = daNoteData >= 4 ? !section.mustHitSection : section.mustHitSection; if (note.length > 2) { - if (note[3] is Int) + if (note[3] is Int && data.noteTypes != null) daNoteType = Chart.addNoteType(result, data.noteTypes[Std.int(note[3])-1]); else if (note[3] is String) daNoteType = Chart.addNoteType(result, note[3]); } else { - daNoteType = Chart.addNoteType(result, data.noteTypes[daNoteType-1]); + if(data.noteTypes != null) + daNoteType = Chart.addNoteType(result, data.noteTypes[daNoteType-1]); } result.strumLines[gottaHitNote ? 1 : 0].notes.push({ From 40046906a642c86df85a338ad13a20267e6920b6 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 19 Sep 2023 15:29:01 -0700 Subject: [PATCH 34/72] pretty big bug i just noticed --- source/funkin/editors/charter/Charter.hx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 49ec899c..e969385f 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -489,6 +489,7 @@ class Charter extends UIState { #if REGION var gridActionType:CharterGridActionType = NONE; var dragStartPos:FlxPoint = new FlxPoint(); + var selectionDragging:Bool = false; public function updateNoteLogic(elapsed:Float) { for (group in [notesGroup, eventsGroup]) { @@ -556,7 +557,8 @@ class Charter extends UIState { if (!FlxG.mouse.pressed) gridActionType = NONE; case DRAG: - if (FlxG.mouse.pressed) { + selectionDragging = FlxG.mouse.pressed; + if (selectionDragging) { gridBackdrops.draggingObj = null; selection.loop(function (n:CharterNote) { n.snappedToStrumline = false; @@ -1031,7 +1033,7 @@ class Charter extends UIState { } function _edit_undo(_) { - if (strumLines.isDragging) return; + if (strumLines.isDragging || selectionDragging) return; selection = []; var undo = undos.undo(); @@ -1072,7 +1074,7 @@ class Charter extends UIState { } function _edit_redo(_) { - if (strumLines.isDragging) return; + if (strumLines.isDragging || selectionDragging) return; selection = []; var redo = undos.redo(); From 6eb90995773a61c74538c5e625ce0befafe5aefe Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 19 Sep 2023 20:33:19 -0700 Subject: [PATCH 35/72] acuttaly cant belive this --- source/funkin/editors/charter/Charter.hx | 19 ++++++++++--------- source/funkin/editors/charter/CharterNote.hx | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index e969385f..12d7c23b 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1212,16 +1212,17 @@ class Charter extends UIState { function changeNoteSustain(change:Float) { if (selection.length <= 0 || change == 0) return; - undos.addToUndo(CEditSustains([ - for(s in selection) { - if (s is CharterNote) { - var n:CharterNote = cast(s, CharterNote); - var old:Float = n.susLength; - n.updatePos(n.step, n.id, Math.max(n.susLength + change, 0)); - {before: old, after: n.susLength, note: n}; - } + var undoChanges:Array = []; + for(s in selection) { + if (s is CharterNote) { + var n:CharterNote = cast(s, CharterNote); + var old:Float = n.susLength; + n.updatePos(n.step, n.id, Math.max(n.susLength + change, 0)); + undoChanges.push({before: old, after: n.susLength, note: n}); } - ])); + } + + undos.addToUndo(CEditSustains(undoChanges)); } public function playtestChart(time:Float = 0, opponentMode = false, here = false) { diff --git a/source/funkin/editors/charter/CharterNote.hx b/source/funkin/editors/charter/CharterNote.hx index 0b2fd10e..5156ebdd 100644 --- a/source/funkin/editors/charter/CharterNote.hx +++ b/source/funkin/editors/charter/CharterNote.hx @@ -64,12 +64,12 @@ class CharterNote extends UISprite implements ICharterSelectable { public function get_fullID():Int return (strumLineID * 4) + id; - public function updatePos(step:Float, id:Int, susLength:Float = 0, ?type:Int = 0, ?strumLine:CharterStrumline) { + public function updatePos(step:Float, id:Int, susLength:Float = 0, ?type:Int = 0, ?strumLine:CharterStrumline = null) { this.step = step; this.id = id; this.susLength = susLength; this.type = type; - this.strumLine = strumLine; + if (strumLine != null) this.strumLine = strumLine; y = step * 40; sustainSpr.scale.set(10, (40 * susLength)); From e041e0d605210623d668237f9f3d57153ce817c4 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Fri, 22 Sep 2023 23:10:29 -0700 Subject: [PATCH 36/72] remove "-" change to " " --- source/funkin/editors/charter/Charter.hx | 4 ++-- source/funkin/editors/charter/CharterSelection.hx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 12d7c23b..280795bb 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -941,7 +941,7 @@ class Charter extends UIState { function _file_save(_) { #if sys - saveTo('${Paths.getAssetsRoot()}/songs/${__song.toLowerCase().replace("-", " ")}'); + saveTo('${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}'); undos.save(); return; #end @@ -958,7 +958,7 @@ class Charter extends UIState { function _file_meta_save(_) { #if sys sys.io.File.saveContent( - '${Paths.getAssetsRoot()}/songs/${__song.toLowerCase().replace("-", " ")}/meta.json', + '${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}/meta.json', Json.stringify(PlayState.SONG.meta == null ? {} : PlayState.SONG.meta, null, "\t") ); return; diff --git a/source/funkin/editors/charter/CharterSelection.hx b/source/funkin/editors/charter/CharterSelection.hx index d850b4aa..5e7ffff8 100644 --- a/source/funkin/editors/charter/CharterSelection.hx +++ b/source/funkin/editors/charter/CharterSelection.hx @@ -86,7 +86,7 @@ class CharterSelection extends EditorTreeMenu { } public function saveSong(creation:SongCreationData) { - var songAlreadlyExsits:Bool = [for (s in freeplayList.songs) s.name.toLowerCase()].contains(creation.meta.name.toLowerCase().replace("-", " ")); + var songAlreadlyExsits:Bool = [for (s in freeplayList.songs) s.name.toLowerCase()].contains(creation.meta.name.toLowerCase()); if (songAlreadlyExsits) { openSubState(new UIWarningSubstate("Creating Song: Error!", "The song you are trying to create alreadly exists, if you would like to override it delete the song first!", [ @@ -97,7 +97,7 @@ class CharterSelection extends EditorTreeMenu { // Paths var songsDir:String = '${Paths.getAssetsRoot()}/songs/'; - var songFolder:String = '$songsDir${creation.meta.name.replace("-", " ")}'; + var songFolder:String = '$songsDir${creation.meta.name}'; #if sys // Make Directories From 96216d42580cac3db05b0c6bba537d747933ddcf Mon Sep 17 00:00:00 2001 From: Mihai Alexandru <77043862+MAJigsaw77@users.noreply.github.com> Date: Sat, 23 Sep 2023 11:38:10 +0300 Subject: [PATCH 37/72] Implement `hxvlc`. (#207) * Implement hxvlc. * Better define for `VIDEO_CUTSCENES`. * Update linux.yml * Removed the libraries that aren't required * Ok? --- .github/workflows/linux.yml | 3 ++ libs.xml | 30 +++++++++---------- project.xml | 30 +++++++------------ .../backend/system/macros/ScriptsMacro.hx | 2 +- source/funkin/game/cutscenes/VideoCutscene.hx | 2 +- 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 08e9b4d2..f7e7ef90 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -25,6 +25,9 @@ jobs: export/release/linux/obj/ restore-keys: | cache-build-linux + - name: Installing LibVLC + run: | + sudo apt-get install libvlc-dev libvlccore-dev - name: Installing/Updating libraries run: | haxe -cp commandline -D analyzer-optimize --run Main setup diff --git a/libs.xml b/libs.xml index aad494a6..70e72592 100644 --- a/libs.xml +++ b/libs.xml @@ -1,24 +1,22 @@ - + - - - + + + - + + + + + - - - - + + + - - + + - - - - - diff --git a/project.xml b/project.xml index d8bc062f..f6dbb443 100644 --- a/project.xml +++ b/project.xml @@ -21,7 +21,6 @@ - @@ -53,12 +52,11 @@ - + - @@ -74,17 +72,11 @@ - - - - - - @@ -113,10 +105,12 @@ - + - +
+ +
@@ -157,7 +151,9 @@ - +
+ +
@@ -177,18 +173,13 @@ - -
- -
+ + - - - @@ -208,5 +199,6 @@ + diff --git a/source/funkin/backend/system/macros/ScriptsMacro.hx b/source/funkin/backend/system/macros/ScriptsMacro.hx index c6509335..555dc8c1 100644 --- a/source/funkin/backend/system/macros/ScriptsMacro.hx +++ b/source/funkin/backend/system/macros/ScriptsMacro.hx @@ -21,7 +21,7 @@ class ScriptsMacro { "flixel.addons.util", // OTHER LIBRARIES & STUFF "away3d", "flx3d", - #if VIDEO_CUTSCENES "hxcodec.flixel", "hxcodec.openfl", "hxcodec.lime", #end + #if VIDEO_CUTSCENES "hxvlc.flixel", "hxvlc.openfl", #end // BASE HAXE "DateTools", "EReg", "Lambda", "StringBuf", "haxe.crypto", "haxe.display", "haxe.exceptions", "haxe.extern", "scripting" ]) diff --git a/source/funkin/game/cutscenes/VideoCutscene.hx b/source/funkin/game/cutscenes/VideoCutscene.hx index 301cd9d3..68a86b92 100644 --- a/source/funkin/game/cutscenes/VideoCutscene.hx +++ b/source/funkin/game/cutscenes/VideoCutscene.hx @@ -9,7 +9,7 @@ import sys.io.File; import funkin.backend.FunkinText; import haxe.xml.Access; #if VIDEO_CUTSCENES -import hxcodec.flixel.FlxVideo; +import hxvlc.flixel.FlxVideo; #end /** From 371ee854a7044ef3477a18ebdfb5828c3340d0f4 Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Sat, 23 Sep 2023 21:44:33 +0200 Subject: [PATCH 38/72] Improved Hscript --- .../backend/system/macros/ScriptsMacro.hx | 3 -- source/hscript/Config.hx | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 source/hscript/Config.hx diff --git a/source/funkin/backend/system/macros/ScriptsMacro.hx b/source/funkin/backend/system/macros/ScriptsMacro.hx index 555dc8c1..013d58b6 100644 --- a/source/funkin/backend/system/macros/ScriptsMacro.hx +++ b/source/funkin/backend/system/macros/ScriptsMacro.hx @@ -38,9 +38,6 @@ class ScriptsMacro { Compiler.include("funkin", #if !UPDATE_CHECKING ['funkin.backend.system.updating'] #end); - // FOR ABSTRACTS - Compiler.addGlobalMetadata('haxe.xml', '@:build(hscript.UsingHandler.build())'); - Compiler.addGlobalMetadata('haxe.CallStack', '@:build(hscript.UsingHandler.build())'); #if HL HashLinkFixer.init(); #end // Todo rewrite this to use if(Context.defined("")) } diff --git a/source/hscript/Config.hx b/source/hscript/Config.hx new file mode 100644 index 00000000..bba205c5 --- /dev/null +++ b/source/hscript/Config.hx @@ -0,0 +1,31 @@ +package hscript; + +class Config { + // Runs support for custom classes in these + public static final ALLOWED_CUSTOM_CLASSES = [ + "flixel", + + "funkin", + ]; + + // Runs support for abstract support in these + public static final ALLOWED_ABSTRACT_AND_ENUM = [ + "flixel", + "openfl.display.BlendMode", + + "haxe.xml", + "haxe.CallStack", + "funkin", + ]; + + // Incase any of your files fail + // These are the module names + public static final DISALLOW_CUSTOM_CLASSES = [ + + ]; + + public static final DISALLOW_ABSTRACT_AND_ENUM = [ + "funkin.backend.FunkinSprite", // Error: String has no field trim, Due to Func + "funkin.backend.scripting.events.PlayAnimEvent", // Error: expected member name or ';' after declaration specifiers, Due to Func + ]; +} \ No newline at end of file From b4782ad5f4727bf77d99beae5ad6a548dc95250a Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sun, 24 Sep 2023 10:36:24 +0300 Subject: [PATCH 39/72] made some editor vars static --- source/funkin/editors/character/CharacterEditor.hx | 4 ++-- source/funkin/editors/charter/Charter.hx | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx index cf0434d4..287b4a44 100644 --- a/source/funkin/editors/character/CharacterEditor.hx +++ b/source/funkin/editors/character/CharacterEditor.hx @@ -11,7 +11,7 @@ import flixel.input.keyboard.FlxKey; import funkin.game.Character; class CharacterEditor extends UIState { - var __character:String; + static var __character:String; public var character:Character; public var ghosts:CharacterGhostsHandler; @@ -45,7 +45,7 @@ class CharacterEditor extends UIState { public function new(character:String) { super(); - __character = character; + if (character != null) __character = character; } public override function create() { diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 280795bb..34ba79b0 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -20,9 +20,9 @@ import funkin.editors.ui.UIState; import openfl.net.FileReference; class Charter extends UIState { - var __song:String; - var __diff:String; - var __reload:Bool; + static var __song:String; + static var __diff:String; + static var __reload:Bool; var chart(get, null):ChartData; private function get_chart() @@ -85,9 +85,11 @@ class Charter extends UIState { public function new(song:String, diff:String, reload:Bool = true) { super(); - __song = song; - __diff = diff; - __reload = reload; + if (song != null) { + __song = song; + __diff = diff; + __reload = reload; + } } public override function create() { From b245b8476ac38c8926367f4c9e3e21ebf7e2c8fe Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Sun, 24 Sep 2023 12:32:28 +0200 Subject: [PATCH 40/72] Small Fixes --- source/funkin/editors/charter/Charter.hx | 2 +- source/funkin/game/NoteGroup.hx | 11 ++++++++--- source/funkin/game/PlayState.hx | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 34ba79b0..85ef6a6c 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -231,7 +231,7 @@ class Charter extends UIState { onSelect: _note_selectall }, { - label: "Select maeasure", + label: "Select measure", keybind: [CONTROL, SHIFT, A], onSelect: _note_selectmeasure }, diff --git a/source/funkin/game/NoteGroup.hx b/source/funkin/game/NoteGroup.hx index dc066ea4..ca617eec 100644 --- a/source/funkin/game/NoteGroup.hx +++ b/source/funkin/game/NoteGroup.hx @@ -8,6 +8,11 @@ class NoteGroup extends FlxTypedGroup { var i:Int = 0; var __currentlyLooping:Bool = false; + /** + * How many ms it should show a note before it should be hit + **/ + public var limit:Float = 1500; + /** * Preallocates the members array with nulls, but if theres anything in the array already it clears it **/ @@ -36,7 +41,7 @@ class NoteGroup extends FlxTypedGroup { if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.active) { continue; } - if (__loopSprite.strumTime - Conductor.songPosition > 1500) + if (__loopSprite.strumTime - Conductor.songPosition > limit) break; __loopSprite.update(elapsed); } @@ -55,7 +60,7 @@ class NoteGroup extends FlxTypedGroup { __loopSprite = members[i--]; if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.visible) continue; - if (__loopSprite.strumTime - Conductor.songPosition > 1500) break; + if (__loopSprite.strumTime - Conductor.songPosition > limit) break; __loopSprite.draw(); } __currentlyLooping = oldCur; @@ -74,7 +79,7 @@ class NoteGroup extends FlxTypedGroup { __loopSprite = members[i--]; if (__loopSprite == null || !__loopSprite.exists) continue; - if (__loopSprite.strumTime - Conductor.songPosition > 1500) break; + if (__loopSprite.strumTime - Conductor.songPosition > limit) break; noteFunc(__loopSprite); } __currentlyLooping = oldCur; diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 2629e7ca..fbf8dba8 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -565,8 +565,8 @@ class PlayState extends MusicBeatState for(folder in scriptsFolders) { for(file in Paths.getFolderContent(folder, true, fromMods ? MODS : BOTH)) { if (folder == 'data/charts/') - Logs.trace('data/charts/ is deprecrated and will be removed in the future. Please move script $file.hx to songs/', WARNING, DARKYELLOW); - + Logs.trace('data/charts/ is deprecrated and will be removed in the future. Please move script $file to songs/', WARNING, DARKYELLOW); + addScript(file); } } From 74f430154a0070922c33f3375161c8f32fd398d1 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 26 Sep 2023 16:44:58 -0700 Subject: [PATCH 41/72] remove all ivan assets --- .../images/editors/charter/add-strumline.png | Bin 5969 -> 5712 bytes .../images/editors/charter/lock-strumline.png | Bin 3397 -> 5712 bytes assets/images/editors/ui/audio-time-empty.png | Bin 347 -> 685 bytes assets/images/editors/ui/audio-time-full.png | Bin 538 -> 882 bytes .../images/editors/ui/audio-volume-empty.png | Bin 223 -> 407 bytes .../images/editors/ui/audio-volume-full.png | Bin 288 -> 560 bytes source/funkin/editors/charter/Charter.hx | 5 ++ source/funkin/editors/charter/CharterEvent.hx | 4 +- source/funkin/editors/ui/UISlider.hx | 69 ++++++++++++++++++ 9 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 source/funkin/editors/ui/UISlider.hx diff --git a/assets/images/editors/charter/add-strumline.png b/assets/images/editors/charter/add-strumline.png index d890a9a1e73c9c97781c4795afdd22491848b602..f2262c21c103dccac52cd3b1713e93412eeeb91a 100644 GIT binary patch delta 5705 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 literal 5969 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 diff --git a/assets/images/editors/charter/lock-strumline.png b/assets/images/editors/charter/lock-strumline.png index 0583bec202b8aafaa978dd7fdc63936a5bf12ecf..f2262c21c103dccac52cd3b1713e93412eeeb91a 100644 GIT binary patch delta 5704 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 Y00000007cclK=n!07*qoM6N<$g1GgApa1{> diff --git a/assets/images/editors/ui/audio-time-empty.png b/assets/images/editors/ui/audio-time-empty.png index d5a36361f3ece19d51f36de1ae9440157a67b07c..0f380282989aec8c0de8987bb9fe4cae4e17aafb 100644 GIT binary patch delta 649 zcmV;40(Sk|0<8s*Fn<69XF*Lt006O%3;baP00009a7bBm000tn000tn0p4aGcmMzb zLPzox1qDao7L=5f9D|Z$KnEQ&G?dONV-ZDsd+k7x z*!ySRgq19>A(E}#${1rCI(6z4(1-h5yyo+{IUbM3S_>iHa(}sWqr;lbX03D4{r-}8 z&24L|>)K2v6Ehx+LK&L z+JCd#GogZy@rMYhE0zb)m<_Ad%Kgj32~LT&-|yd&6tRlg?HS*$Pog45Ck=~!12iWi zMc48-Bc-e}W1z7(I1%5G6tRkJzjRAQaqIQkT|GN@mnA_l1R=%%0000wCK^;7oy{b3k} zOVczkGnm=hVDsgDVQXyZHQz2vij!f@zwN#5foU(YM$_>>>#vFchL+mRm4Y zomZ44#zORys=_f0qW_s0Ts((j!3dBs{x$5uHy?m(Np~3 zn5HSb_eTMM-7Ri+csw4LzVFu_AJI#Q|2=NE+xm99eS87<|D=^R!no%E00001o8%uFn<69XF*Lt006O%3;baP00009a7bBm000tn000tn0p4aGcmMzZ z4rN$LW=%~1DgXcg2mk;800000(o>TF00QkvL_t(&L+zS9XcR#d$6t(GKs-<)#;B3l zh>D0L5D9*PB3M{iNI=BKG*;S}MjNfPvN45F`SGI@w0$_L90&AHQd2 z>E@o-sugnV?p9jXx|9e{u_?S~!`9dH|KPk(I(o~rYhYc&;*h)>{zi{3eO9fI{wLd2 zEg4(iIHaJbCx2(?`Hins8Tp|;oeSH8G+Q8_NtW?Fjtd12vH#)*DwUhn9Xs_nv56@Z z9;;Dj?Cx)ioSun`Mz#o2t?+^V#jHrycn8_B1c?m#k;GyYd3;TAS}?N)DFA6 zDU#8%aJdG$Rg2$XiE0XyP*M7#U55k5_`VJsbR@?$pHM(Q#TRi-k<@(#}2* zK+mZ)s#OySqMnR=2QPPOLWCXW;0TGr{Qw+3E~+qWiw#AJERRjYHM~%A1`)(e@8Yn% zY>>{5u^8#R5TdkW(3XA7sDk+Wv2F#ZQDK<}t7fQ~sIIv6ep&P}P_qP}#G1D}N!4yQA6UPY%*xq(YIAu&r z7mJ7&N{&cznAqNW;dcvQ6A8mMAjwW5#S(W;LG&|A)|9b`6zVT5HsIV0oTXl5e;e4P zA4p!9SWpM-J+qd!^{oo(n0M&Fo8UU%?^Z%qU&v|paB2?002ovPDHLkV1f=Ki`oDH delta 500 zcmeywHj8C~K|SLxPZ!6K4A!@|_Io=8%CLU$=5KlaByP1$jF@{UV6v%`I%CIHD4aBx42fG;o=|IU!tOBUBFi#Fnz{bg-eCHb6!|q zVB_z6Bx-qS`wE^dfn2$Z1#-N2$|h`=o-pHW16xL;8sAsmbwT+B3$HBxJ%ihHB4>_L z?p0Mb>lyE&+mGb1n>cWrI7-{7=}lR6+38r^;U%HYL2EshFyGH_5X)#Xv(fN=DC=|6 zG-GvF%PNF$y^Y4x0%p%@N#QWb$61a_vOnsWw>SuIdFZIwx_!ci(-ND#Btl&~OCJ2@ zy};yqp^ZKD-pvCuVh?qMI`}+Qz0~;L9Bi%Jl%f)D;e|>`jWTU()*MM-Z?2W}I8){T zHS6YO@fok;k5sH^c=(_PC~IiV-FcHQ1L&~aMQeAzSQ_`BF8<}Q`4=ud*EkktD814H z=1*lUrXnm+I(#0?xWWk i7#R3cBRtc5eHpZXYz`m>flI-YL6oPfpUXO@geCyF{MK*q*62$VU@VR%WL#3}AcpA_St1e@?V zWtgUE%(iVttK&FKUDsD`P9DW}UH9z!XI>-ckfdcuQE!5aU?1rdW&tUV{p0MK8zGBldm2p1TJR)tsiuiX*s&E4OASjvIrqCzj!XlKhNT zfkRwVi3xLJ621(}@IXm^CP&ie8JY?Ub5L#D-m6zw_rx+hP?Dd?k^6bl{n3b~n3^;R zYoAz#2TJlYC}_zaBQ`yn9E;YeNeg$|GCXht$1DFlf|*G~VE2N(a2Mtg@wVuRh`_dOyY96Yo$mtQ&)7c1aV! kG)=9wW$MmwXM zWS4^Ne|aT1z#BK4P18$ofaP)-3~n$O7{6$79Gk{A2hQ+sF4{ccRWOPo>UO)A*Wic zrYZmlDV0jrx=NS{-PLEw4e*r>Lud+c6M~BI>&ew~0|rtd60PdFx_ji_x!^z{DTgG- zaK-QjFbEhD=Cv{*T9qZAKmRpEK@sDy^?Kcmv0;)VW*p*jx!la3&*$clXxdu5*oDGX nL|i?W!{KnV)}4>N??dzr&DG3eGlN5h00000NkvXXu0mjf@Yw0- delta 247 zcmVTsw&VF zfb%>f%QB>CDk2VwrU2ac9eJK3NfHt9snPTYe)oO*pQrD8#2P;q#`|yE2AceukiO`D xK#4n3>z8jE0000EWmrjOO-%qQ00008000000002eQ = []; + public var barWidth:Int = 120; + + public var barStartSpr:FlxSprite; + public var startText:UIText; + public var barEndSpr:FlxSprite; + public var endText:UIText; + + public var barSegements:Map<{segment:Float, size:Float}, UISprite> = []; + + public function new(x:Float, y:Float, width:Int = 120, segments:Array) { + this.segments = segments; + this.barWidth = width; + + super(x, y); + makeSolid(barWidth, 4, -1); + + members.push(barStartSpr = new FlxSprite(x-4,y+((4/2))).makeSolid(4, 12, -1)); + members.push(barEndSpr = new FlxSprite(x+barWidth,y+((4/2))).makeSolid(4, 12, -1)); + + members.push(startText = new UIText(x, y, 0, Std.string(segments[0].start).replace("0.", "."))); + members.push(endText = new UIText(x + barWidth + 8, y, 0, Std.string(segments[segments.length-1].end))); + + var midSegments:Map = []; + for (segment in segments) { + var isFront:Bool = segment.start == segments[0].start; + var isEnd:Bool = segment.end == segments[segments.length-1].end; + + if (isFront && !midSegments.exists(Std.int(segment.end*1000))) midSegments.set(Std.int(segment.end*1000), segment.size); + if (isEnd && !midSegments.exists(Std.int(segment.start*1000))) midSegments.set(Std.int(segment.start*1000), segment.size); + } + + for (segment => size in midSegments) { + var segmentSpr:UISprite = new UISprite(x,y); + segmentSpr.makeSolid(4, 8, -1); + segmentSpr.members = [new UIText(x, y, 0, Std.string(segment/1000).replace("0.", "."), 10)]; + members.push(segmentSpr); + + barSegements.set({segment: segment/1000, size: size}, segmentSpr); + } + } + + public override function update(elapsed:Float) { + barStartSpr.follow(this, -4, (4-12)/2); + barEndSpr.follow(this, barWidth, (4-12)/2); + + startText.follow(this, -startText.width-10, (4/2) - (startText.height/2)); + endText.follow(this, barWidth + 10, (4/2) - (endText.height/2)); + + for (segmentData => sprite in barSegements) { + sprite.follow(this, (barWidth * segmentData.size) - (sprite.width/2), ((4-8)/2) -2); + if (sprite.members[0] != null && sprite.members[0] is UIText) + cast(sprite.members[0], UIText).follow(sprite,0,sprite.height); + } + + super.update(elapsed); + } +} \ No newline at end of file From 13474adcc90f46a893c04924f597cf710ba0daee Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Wed, 27 Sep 2023 01:48:32 +0200 Subject: [PATCH 42/72] Small fix --- project.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/project.xml b/project.xml index f6dbb443..6155a799 100644 --- a/project.xml +++ b/project.xml @@ -92,6 +92,7 @@ + From c8bc2d5bc27d110c87586885b55c380febfef6d3 Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Thu, 28 Sep 2023 17:10:42 +0200 Subject: [PATCH 43/72] Added onScriptCreated --- source/funkin/backend/scripting/HScript.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/funkin/backend/scripting/HScript.hx b/source/funkin/backend/scripting/HScript.hx index 158012a6..2d54ce40 100644 --- a/source/funkin/backend/scripting/HScript.hx +++ b/source/funkin/backend/scripting/HScript.hx @@ -45,6 +45,8 @@ class HScript extends Script { this.trace(v); })); + funkin.backend.scripting.GlobalScript.call("onScriptCreated", [this, "hscript"]); + try { if (code != null && code.trim() != "") expr = parser.parseString(code, fileName); From 8f3897779a56972ead422e5ab158b9f1bc963375 Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Sat, 30 Sep 2023 12:18:02 +0200 Subject: [PATCH 44/72] Added Script.fromString --- source/funkin/backend/scripting/HScript.hx | 7 +++++++ source/funkin/backend/scripting/Script.hx | 24 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/source/funkin/backend/scripting/HScript.hx b/source/funkin/backend/scripting/HScript.hx index 2d54ce40..86851984 100644 --- a/source/funkin/backend/scripting/HScript.hx +++ b/source/funkin/backend/scripting/HScript.hx @@ -47,6 +47,11 @@ class HScript extends Script { funkin.backend.scripting.GlobalScript.call("onScriptCreated", [this, "hscript"]); + if (code != null && code.trim() != "") + loadFromString(code); + } + + public override function loadFromString(code:String) { try { if (code != null && code.trim() != "") expr = parser.parseString(code, fileName); @@ -55,6 +60,8 @@ class HScript extends Script { } catch(e) { _errorHandler(new Error(ECustom(e.toString()), 0, 0, fileName, 0)); } + + return this; } private function importFailedCallback(cl:Array):Bool { diff --git a/source/funkin/backend/scripting/Script.hx b/source/funkin/backend/scripting/Script.hx index 927e1189..90dfce81 100644 --- a/source/funkin/backend/scripting/Script.hx +++ b/source/funkin/backend/scripting/Script.hx @@ -148,6 +148,22 @@ class Script extends FlxBasic implements IFlxDestroyable { return new DummyScript(path); } + /** + * Creates a script from the specified asset path. The language is automatically determined. + * @param path Path in assets + */ + public static function fromString(code:String, ext:String, path:String):Script { + return switch(ext.toLowerCase()) { + case "hx" | "hscript" | "hsc" | "hxs": + new HScript(path).loadFromString(code); + case "lua": + Logs.trace("Lua is not supported in this engine. Use HScript instead.", ERROR); + new DummyScript(path).loadFromString(code); + default: + new DummyScript(path).loadFromString(code); + } + } + /** * Creates a new instance of the script class. * @param path @@ -224,6 +240,14 @@ class Script extends FlxBasic implements IFlxDestroyable { return result; } + /** + * Loads the code from a string, doesnt really work after the script has been loaded + * @param code The code. + */ + public function loadFromString(code:String) { + return this; + } + /** * Sets a script's parent object so that its properties can be accessed easily. Ex: Passing `PlayState.instance` will allow `boyfriend` to be typed instead of `PlayState.instance.boyfriend`. * @param variable Parent variable. From 64c9371a8b1da32fae6fb9a7c9b99b7ee8922c81 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sat, 30 Sep 2023 14:32:17 +0300 Subject: [PATCH 45/72] event/script packing wip --- source/funkin/backend/assets/Paths.hx | 3 +++ source/funkin/backend/chart/EventsData.hx | 11 +++++++---- source/funkin/editors/charter/CharterEvent.hx | 9 +++++++-- source/funkin/game/PlayState.hx | 8 +++++++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx index 2d7c0c75..921d6584 100644 --- a/source/funkin/backend/assets/Paths.hx +++ b/source/funkin/backend/assets/Paths.hx @@ -48,6 +48,9 @@ class Paths inline static public function txt(key:String, ?library:String) return getPath('data/$key.txt', library); + inline static public function pack(key:String, ?library:String) + return getPath('data/$key.pack', library); + inline static public function ini(key:String, ?library:String) return getPath('data/$key.ini', library); diff --git a/source/funkin/backend/chart/EventsData.hx b/source/funkin/backend/chart/EventsData.hx index 0c8f0a97..254ce779 100644 --- a/source/funkin/backend/chart/EventsData.hx +++ b/source/funkin/backend/chart/EventsData.hx @@ -42,15 +42,18 @@ class EventsData { hscriptParser.allowJSON = hscriptParser.allowMetadata = false; for (file in Paths.getFolderContent('data/events/', true, BOTH)) { - if (Path.extension(file) != "json") continue; + if (Path.extension(file) != "json" && Path.extension(file) != "pack") continue; var eventName:String = Path.withoutExtension(Path.withoutDirectory(file)); + var fileTxt:String = Assets.getText(file); + if (fileTxt.trim() == "") continue; + if (Path.extension(file) == "pack") { + eventName = Path.withoutExtension(fileTxt.split("________PACKSEP________")[0]); + fileTxt = fileTxt.split("________PACKSEP________")[2]; + } eventsList.push(eventName); eventsParams.set(eventName, []); - var fileTxt:String = Assets.getText(file); - if (fileTxt.trim() == "") continue; - try { var data:Dynamic = Json.parse(fileTxt); if (data == null || data.params == null) continue; diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index 6de57ceb..1e6cab0c 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -45,10 +45,15 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { } private static function generateDefaultIcon(name:String) { + var isBase64:Bool = false; var path:String = Paths.image('editors/charter/event-icons/$name'); - if (!Assets.exists(path)) path = Paths.image('editors/charter/event-icons/Unknown'); + if (!Assets.exists(path) && Assets.exists(Paths.pack('events/$name'))) { + path = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3]; + isBase64 = true; + } + else if (!Assets.exists(path)) path = Paths.image('editors/charter/event-icons/Unknown'); - var spr = new FlxSprite().loadGraphic(path); + var spr = new FlxSprite().loadGraphic(isBase64 ? openfl.display.BitmapData.fromBase64(path.trim(), 'UTF8') : path); return spr; } diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index fbf8dba8..16d6abe6 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -576,7 +576,13 @@ class PlayState extends MusicBeatState for (file in Paths.getFolderContent('data/events/', true, fromMods ? MODS : BOTH)) { var fileName:String = Path.withoutExtension(Path.withoutDirectory(file)); - if (EventsData.eventsList.contains(fileName) && songEvents.contains(fileName)) addScript(file); + if (EventsData.eventsList.contains(fileName) && songEvents.contains(fileName)) { + if (Path.extension(file) == "pack"){ + var txtArray:Array = Assets.getText(Paths.pack('events/$fileName')).split("________PACKSEP________"); + scripts.add(Script.fromString(txtArray[1], Path.extension(txtArray[0]), Path.withoutExtension(txtArray[0]))); + } + else addScript(file); + } } } } From bfb8f4c771afd0bc37b4b12b79403ca82e5cf8ce Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Sat, 30 Sep 2023 13:45:44 +0200 Subject: [PATCH 46/72] Improved code for packed events --- source/funkin/backend/chart/EventsData.hx | 9 ++++++--- source/funkin/backend/scripting/HScript.hx | 2 +- source/funkin/backend/scripting/Script.hx | 13 +++++++++---- source/funkin/game/PlayState.hx | 6 +----- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/source/funkin/backend/chart/EventsData.hx b/source/funkin/backend/chart/EventsData.hx index 254ce779..2cb50557 100644 --- a/source/funkin/backend/chart/EventsData.hx +++ b/source/funkin/backend/chart/EventsData.hx @@ -45,12 +45,15 @@ class EventsData { if (Path.extension(file) != "json" && Path.extension(file) != "pack") continue; var eventName:String = Path.withoutExtension(Path.withoutDirectory(file)); var fileTxt:String = Assets.getText(file); - if (fileTxt.trim() == "") continue; + if (Path.extension(file) == "pack") { - eventName = Path.withoutExtension(fileTxt.split("________PACKSEP________")[0]); - fileTxt = fileTxt.split("________PACKSEP________")[2]; + var arr = fileTxt.split("________PACKSEP________"); + eventName = Path.withoutExtension(arr[0]); + fileTxt = arr[2]; } + if (fileTxt.trim() == "") continue; + eventsList.push(eventName); eventsParams.set(eventName, []); diff --git a/source/funkin/backend/scripting/HScript.hx b/source/funkin/backend/scripting/HScript.hx index 86851984..adb829a6 100644 --- a/source/funkin/backend/scripting/HScript.hx +++ b/source/funkin/backend/scripting/HScript.hx @@ -29,7 +29,7 @@ class HScript extends Script { interp = new Interp(); - code = Assets.getText(path); + code = Assets.exists(path) ? Assets.getText(path) : null; parser = initParser(); folderlessPath = Path.directory(path); __importedPaths = [path]; diff --git a/source/funkin/backend/scripting/Script.hx b/source/funkin/backend/scripting/Script.hx index 90dfce81..bdfe59bf 100644 --- a/source/funkin/backend/scripting/Script.hx +++ b/source/funkin/backend/scripting/Script.hx @@ -109,6 +109,7 @@ class Script extends FlxBasic implements IFlxDestroyable { */ public static var scriptExtensions:Array = [ "hx", "hscript", "hsc", "hxs", + "pack", // combined file "lua" /** ACTUALLY NOT SUPPORTED, ONLY FOR THE MESSAGE **/ ]; @@ -138,6 +139,9 @@ class Script extends FlxBasic implements IFlxDestroyable { return switch(Path.extension(path).toLowerCase()) { case "hx" | "hscript" | "hsc" | "hxs": new HScript(path); + case "pack": + var arr = Assets.getText(path).split("________PACKSEP________"); + fromString(arr[1], arr[0]); case "lua": Logs.trace("Lua is not supported in this engine. Use HScript instead.", ERROR); new DummyScript(path); @@ -149,11 +153,12 @@ class Script extends FlxBasic implements IFlxDestroyable { } /** - * Creates a script from the specified asset path. The language is automatically determined. - * @param path Path in assets + * Creates a script from the string. The language is determined based on the path. + * @param code code + * @param path filename */ - public static function fromString(code:String, ext:String, path:String):Script { - return switch(ext.toLowerCase()) { + public static function fromString(code:String, path:String):Script { + return switch(Path.extension(path).toLowerCase()) { case "hx" | "hscript" | "hsc" | "hxs": new HScript(path).loadFromString(code); case "lua": diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index 16d6abe6..c307fbde 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -577,11 +577,7 @@ class PlayState extends MusicBeatState for (file in Paths.getFolderContent('data/events/', true, fromMods ? MODS : BOTH)) { var fileName:String = Path.withoutExtension(Path.withoutDirectory(file)); if (EventsData.eventsList.contains(fileName) && songEvents.contains(fileName)) { - if (Path.extension(file) == "pack"){ - var txtArray:Array = Assets.getText(Paths.pack('events/$fileName')).split("________PACKSEP________"); - scripts.add(Script.fromString(txtArray[1], Path.extension(txtArray[0]), Path.withoutExtension(txtArray[0]))); - } - else addScript(file); + addScript(file); } } } From f1ea88ec02f35ffdf42acc72750747d43b880746 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 30 Sep 2023 12:41:50 -0700 Subject: [PATCH 47/72] playback speed WIP --- source/funkin/editors/charter/Charter.hx | 7 ++- source/funkin/editors/ui/UISlider.hx | 72 +++++++++++++++++++----- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 3d125f6a..00156e8e 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -376,8 +376,11 @@ class Charter extends UIState { songPosInfo.alignment = RIGHT; uiGroup.add(songPosInfo); - //playBackSlider = new UISlider(FlxG.width - 180 - 26 - 12, (23/2) - (4/2), 180, [{start: 0.25, end: 1, size: 0.5}, {start: 1, end: 3, size: 0.5}]); - //uiGroup.add(playBackSlider); + playBackSlider = new UISlider(FlxG.width - 180 - 26 - 12, (23/2) - (4/2), 180, [{start: 0.5, end: 1, size: 0.5}, {start: 1, end: 3, size: 0.5}], 0.5); + playBackSlider.onChange = function (v) { + FlxG.sound.music.pitch = vocals.pitch = v; + }; + uiGroup.add(playBackSlider); strumlineInfoBG = new UISprite(); strumlineInfoBG.loadGraphic(Paths.image('editors/charter/strumline-info-bg')); diff --git a/source/funkin/editors/ui/UISlider.hx b/source/funkin/editors/ui/UISlider.hx index f8faeefc..29e3990f 100644 --- a/source/funkin/editors/ui/UISlider.hx +++ b/source/funkin/editors/ui/UISlider.hx @@ -18,19 +18,28 @@ class UISlider extends UISprite { public var endText:UIText; public var barSegements:Map<{segment:Float, size:Float}, UISprite> = []; + public var selectableBar:UISprite; + public var selectableHitbox:UISprite; - public function new(x:Float, y:Float, width:Int = 120, segments:Array) { + public var value:Float = 0; + public var onChange:Float->Void; + + public function new(x:Float, y:Float, width:Int = 120, segments:Array, defaultStart:Float = 0) { this.segments = segments; this.barWidth = width; + x -= 6; super(x, y); - makeSolid(barWidth, 4, -1); + makeSolid((barWidth+6), 4, -1); + cursor = BUTTON; + + __barProgress = defaultStart; members.push(barStartSpr = new FlxSprite(x-4,y+((4/2))).makeSolid(4, 12, -1)); - members.push(barEndSpr = new FlxSprite(x+barWidth,y+((4/2))).makeSolid(4, 12, -1)); + members.push(barEndSpr = new FlxSprite(x+barWidth+6,y+((4/2))).makeSolid(4, 12, -1)); members.push(startText = new UIText(x, y, 0, Std.string(segments[0].start).replace("0.", "."))); - members.push(endText = new UIText(x + barWidth + 8, y, 0, Std.string(segments[segments.length-1].end))); + members.push(endText = new UIText(x + (barWidth+6) + 8, y, 0, Std.string(segments[segments.length-1].end))); var midSegments:Map = []; for (segment in segments) { @@ -44,26 +53,61 @@ class UISlider extends UISprite { for (segment => size in midSegments) { var segmentSpr:UISprite = new UISprite(x,y); segmentSpr.makeSolid(4, 8, -1); - segmentSpr.members = [new UIText(x, y, 0, Std.string(segment/1000).replace("0.", "."), 10)]; members.push(segmentSpr); barSegements.set({segment: segment/1000, size: size}, segmentSpr); } + + selectableBar = new UISprite(x,y); + selectableBar.makeSolid(6, 12, 0xFFA0A0A0); + selectableBar.cursor = BUTTON; + members.push(selectableBar); + + selectableHitbox = new UISprite(x,y); + selectableHitbox.makeSolid(barWidth+6, 16, -1); + selectableHitbox.cursor = BUTTON; + selectableHitbox.alpha = 0; + members.push(selectableHitbox); } - + + var __barProgress:Float = 0; + public override function update(elapsed:Float) { - barStartSpr.follow(this, -4, (4-12)/2); - barEndSpr.follow(this, barWidth, (4-12)/2); + barStartSpr.follow(this, -4, (height-barStartSpr.height)/2); + barEndSpr.follow(this, barWidth+6, (height-barEndSpr.height)/2); + + selectableHitbox.follow(this, 0, (height-selectableHitbox.height)/2); + var lastBarProgress:Float = __barProgress; + + if (selectableHitbox.hovered && FlxG.mouse.pressed) { + var mousePos = FlxG.mouse.getScreenPosition(__lastDrawCameras[0], FlxPoint.get()); + __barProgress = FlxMath.bound(mousePos.x-x, 0, barWidth)/barWidth; + mousePos.put(); + } + + if (__barProgress != lastBarProgress) + onChange(value = calcValue(__barProgress)); + + selectableBar.follow(this, __barProgress * barWidth, (4-12)/2); startText.follow(this, -startText.width-10, (4/2) - (startText.height/2)); - endText.follow(this, barWidth + 10, (4/2) - (endText.height/2)); + endText.follow(this, barWidth+6 + 10, (4/2) - (endText.height/2)); - for (segmentData => sprite in barSegements) { - sprite.follow(this, (barWidth * segmentData.size) - (sprite.width/2), ((4-8)/2) -2); - if (sprite.members[0] != null && sprite.members[0] is UIText) - cast(sprite.members[0], UIText).follow(sprite,0,sprite.height); - } + for (segmentData => sprite in barSegements) + sprite.follow(this, (barWidth * segmentData.size) + ((selectableBar.width-sprite.width)/2), ((4-8)/2)); super.update(elapsed); } + + function calcValue(progress:Float):Float { + var totalProgress:Float = 0; + for (segment in segments) { + if (progress < totalProgress + segment.size) { + var relativeProgress = (progress - totalProgress) / segment.size; + return FlxMath.remapToRange(relativeProgress, 0, 1, segment.start, segment.end); + } + totalProgress += segment.size; + } + return segments[segments.length-1].end; + } } \ No newline at end of file From 4e15462df9ec3a5baf9e87c4d64b898a93ce533f Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 1 Oct 2023 02:32:04 -0700 Subject: [PATCH 48/72] fix for weird events bug (hopefully) --- source/funkin/editors/charter/Charter.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 00156e8e..0461c873 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1026,6 +1026,8 @@ class Charter extends UIState { } } selection = sObjects; + _edit_copy(_); + undos.addToUndo(CCreateSelection(sObjects.copy())); } From 2af38af129d2fab1fdc0b0ffc402b830c64b2be8 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sun, 1 Oct 2023 15:15:34 +0300 Subject: [PATCH 49/72] missing event icon check --- source/funkin/editors/charter/CharterEvent.hx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index 1e6cab0c..442021a3 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -47,11 +47,10 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { private static function generateDefaultIcon(name:String) { var isBase64:Bool = false; var path:String = Paths.image('editors/charter/event-icons/$name'); - if (!Assets.exists(path) && Assets.exists(Paths.pack('events/$name'))) { + if (!Assets.exists(path)) path = Paths.image('editors/charter/event-icons/Unknown'); + var packimg = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3]; + if (isBase64 = (packimg != null)) path = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3]; - isBase64 = true; - } - else if (!Assets.exists(path)) path = Paths.image('editors/charter/event-icons/Unknown'); var spr = new FlxSprite().loadGraphic(isBase64 ? openfl.display.BitmapData.fromBase64(path.trim(), 'UTF8') : path); return spr; From 14491a0b9c3b1c132c37d5ffd4b3f354e3829612 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sun, 1 Oct 2023 15:37:13 +0300 Subject: [PATCH 50/72] fixed the dumbass conductor line in charter --- source/funkin/editors/charter/Charter.hx | 20 +++++++++---------- .../editors/charter/CharterBackdropGroup.hx | 5 +++-- source/funkin/editors/charter/CharterEvent.hx | 9 +++++---- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 0461c873..209947fc 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -853,6 +853,16 @@ class Charter extends UIState { public override function update(elapsed:Float) { updateNoteLogic(elapsed); + if (FlxG.sound.music.playing) { + gridBackdrops.conductorSprY = curStepFloat * 40; + } else { + gridBackdrops.conductorSprY = lerp(gridBackdrops.conductorSprY, curStepFloat * 40, 1/3); + } + charterCamera.scroll.set( + ((((40*4) * gridBackdrops.strumlinesAmount) - FlxG.width) / 2), + gridBackdrops.conductorSprY - (FlxG.height * 0.5) + ); + super.update(elapsed); scrollBar.size = (FlxG.height / 40 / charterCamera.zoom); @@ -895,16 +905,6 @@ class Charter extends UIState { + '\nBPM: ${Conductor.bpm}' + '\nTime Signature: ${Conductor.beatsPerMesure}/${Conductor.stepsPerBeat}'; - if (FlxG.sound.music.playing) { - gridBackdrops.conductorSprY = curStepFloat * 40; - } else { - gridBackdrops.conductorSprY = lerp(gridBackdrops.conductorSprY, curStepFloat * 40, 1/3); - } - charterCamera.scroll.set( - ((((40*4) * gridBackdrops.strumlinesAmount) - FlxG.width) / 2), - gridBackdrops.conductorSprY - (FlxG.height * 0.5) - ); - if (charterCamera.zoom != (charterCamera.zoom = lerp(charterCamera.zoom, __camZoom, 0.125))) updateDisplaySprites(); diff --git a/source/funkin/editors/charter/CharterBackdropGroup.hx b/source/funkin/editors/charter/CharterBackdropGroup.hx index 3934f73c..62324276 100644 --- a/source/funkin/editors/charter/CharterBackdropGroup.hx +++ b/source/funkin/editors/charter/CharterBackdropGroup.hx @@ -48,6 +48,8 @@ class CharterBackdropGroup extends FlxTypedGroup { for (grid in members) grid.active = grid.visible = false; + super.update(elapsed); + for (i => strumLine in strumLineGroup.members) { if (strumLine == null) continue; @@ -73,8 +75,7 @@ class CharterBackdropGroup extends FlxTypedGroup { grid.active = grid.visible = true; grid.updateSprites(); } - - super.update(elapsed); + } public var draggingObj:CharterBackdrop = null; diff --git a/source/funkin/editors/charter/CharterEvent.hx b/source/funkin/editors/charter/CharterEvent.hx index 442021a3..ff62f465 100644 --- a/source/funkin/editors/charter/CharterEvent.hx +++ b/source/funkin/editors/charter/CharterEvent.hx @@ -48,10 +48,11 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable { var isBase64:Bool = false; var path:String = Paths.image('editors/charter/event-icons/$name'); if (!Assets.exists(path)) path = Paths.image('editors/charter/event-icons/Unknown'); - var packimg = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3]; - if (isBase64 = (packimg != null)) - path = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3]; - + if (Assets.exists(Paths.pack('events/$name'))) { + var packimg = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3]; + if (isBase64 = (packimg != null)) + path = Assets.getText(Paths.pack('events/$name')).split('________PACKSEP________')[3]; + } var spr = new FlxSprite().loadGraphic(isBase64 ? openfl.display.BitmapData.fromBase64(path.trim(), 'UTF8') : path); return spr; } From 926f67d4cd48bea7930d2c5dfa405dbc71738b40 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 3 Oct 2023 19:16:21 -0700 Subject: [PATCH 51/72] added F2 for alloc console shortcut --- source/funkin/backend/scripting/GlobalScript.hx | 2 ++ source/funkin/editors/charter/Charter.hx | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/funkin/backend/scripting/GlobalScript.hx b/source/funkin/backend/scripting/GlobalScript.hx index 14803c8b..d6d10000 100644 --- a/source/funkin/backend/scripting/GlobalScript.hx +++ b/source/funkin/backend/scripting/GlobalScript.hx @@ -56,6 +56,8 @@ class GlobalScript { Logs.trace('Global script successfully loaded.', WARNING, GREEN); } } + if (FlxG.keys.justPressed.F2) + NativeAPI.allocConsole(); }); FlxG.signals.preDraw.add(function() { call("preDraw"); diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 0461c873..6157d353 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1026,7 +1026,7 @@ class Charter extends UIState { } } selection = sObjects; - _edit_copy(_); + _edit_copy(_); // to fix stupid bugs undos.addToUndo(CCreateSelection(sObjects.copy())); } From 66155e75b47c3a218e880b624f93b89956da161f Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Tue, 3 Oct 2023 19:40:03 -0700 Subject: [PATCH 52/72] optimize the notes a bit in the charter --- source/funkin/editors/charter/Charter.hx | 48 +++++++++++++++---- .../editors/charter/CharterNoteGroup.hx | 9 +++- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index fa1366df..9ea81a47 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -453,8 +453,28 @@ class Charter extends UIState { gridBackdrops.createGrids(PlayState.SONG.strumLines.length); for(strL in PlayState.SONG.strumLines) - createStrumline(strumLines.members.length, strL, false); + createStrumline(strumLines.members.length, strL, false, false); + + // create notes + notesGroup.autoSort = false; + var noteCount:Int = 0; + for (strL in PlayState.SONG.strumLines) + for (note in strL.notes) noteCount++; + notesGroup.preallocate(noteCount); + var notesCreated:Int = 0; + for (i => strL in PlayState.SONG.strumLines) + for (note in strL.notes) { + var n = new CharterNote(); + var t = Conductor.getStepForTime(note.time); + n.updatePos(t, note.id, Conductor.getStepForTime(note.time + note.sLen) - t, note.type, strumLines.members[i]); + notesGroup.members[notesCreated++] = n; + } + notesGroup.sortNotes(); + notesGroup.autoSort = true; + + + // create events var __last:CharterEvent = null; var __lastTime:Float = Math.NaN; for(e in PlayState.SONG.events) { @@ -719,6 +739,7 @@ class Charter extends UIState { public function createSelection(selection:Selection, addToUndo:Bool = true) { if (selection.length <= 0) return []; + notesGroup.autoSort = false; selection.loop(function (n:CharterNote) { notesGroup.add(n); n.revive(); @@ -727,6 +748,8 @@ class Charter extends UIState { e.revive(); e.refreshEventIcons(); }, false); + notesGroup.sortNotes(); + notesGroup.autoSort = true; for (s in selection) if (s is CharterEvent) { @@ -742,6 +765,7 @@ class Charter extends UIState { public function deleteSelection(selection:Selection, addToUndo:Bool = true) { if (selection.length <= 0) return []; + notesGroup.autoSort = false; for (objects in [notesGroup, eventsGroup]) { var group = cast(objects, FlxTypedGroup); var member = 0; @@ -752,6 +776,8 @@ class Charter extends UIState { else member++; } } + notesGroup.sortNotes(); + notesGroup.autoSort = true; for (s in selection) if (s is CharterEvent) { @@ -765,16 +791,20 @@ class Charter extends UIState { } // STRUMLINE DELETION/CREATION - public function createStrumline(strumLineID:Int, strL:ChartStrumLine, addToUndo:Bool = true) { + public function createStrumline(strumLineID:Int, strL:ChartStrumLine, addToUndo:Bool = true, ?__createNotes:Bool = true) { var cStr = new CharterStrumline(strL); strumLines.insert(strumLineID, cStr); strumLines.snapStrums(); - for(note in strL.notes) { - var n = new CharterNote(); - var t = Conductor.getStepForTime(note.time); - n.updatePos(t, note.id, Conductor.getStepForTime(note.time + note.sLen) - t, note.type, cStr); - notesGroup.add(n); + if (__createNotes) { + var toBeCreated:Selection = []; + for(note in strL.notes) { + var n = new CharterNote(); + var t = Conductor.getStepForTime(note.time); + n.updatePos(t, note.id, Conductor.getStepForTime(note.time + note.sLen) - t, note.type, cStr); + notesGroup.add(n); + } + createSelection(toBeCreated, false); } if (addToUndo) @@ -786,13 +816,15 @@ class Charter extends UIState { removeStrumlineFromSelection(strumLineID); var i = 0; + var toBeDeleted:Selection = []; while(i < notesGroup.members.length) { var note = notesGroup.members[i]; if (note.strumLineID == strumLineID) { undoNotes.push(buildNote(note)); - deleteSingleSelection(note, false); + toBeDeleted.push(note); } else i++; } + deleteSelection(toBeDeleted, false); var strL = strumLines.members[strumLineID].strumLine; strumLines.members[strumLineID].destroy(); diff --git a/source/funkin/editors/charter/CharterNoteGroup.hx b/source/funkin/editors/charter/CharterNoteGroup.hx index 9a825a28..0cfebeb9 100644 --- a/source/funkin/editors/charter/CharterNoteGroup.hx +++ b/source/funkin/editors/charter/CharterNoteGroup.hx @@ -8,6 +8,8 @@ class CharterNoteGroup extends FlxTypedGroup { var i:Int = 0; var max:Float = 0; var __currentlyLooping:Bool = false; + + public var autoSort:Bool = true; var __lastSort:Int = 0; public override function forEach(noteFunc:CharterNote->Void, recursive:Bool = false) { @@ -58,7 +60,7 @@ class CharterNoteGroup extends FlxTypedGroup { @:privateAccess var oldDefaultCameras = FlxCamera._defaultCameras; @:privateAccess if (cameras != null) FlxCamera._defaultCameras = cameras; - if (length != __lastSort) + if (length != __lastSort && autoSort) sortNotes(); forEach((n) -> { @@ -77,4 +79,9 @@ class CharterNoteGroup extends FlxTypedGroup { return FlxSort.byValues(FlxSort.ASCENDING, n1.step, n2.step); }); } + + public inline function preallocate(len:Int) { + members = cast new haxe.ds.Vector(len); + length = len; + } } \ No newline at end of file From 559a308558d9ca1a128017319988c7b2e01b9664 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 7 Oct 2023 16:22:23 -0700 Subject: [PATCH 53/72] playback speed looks good --- .../event-icons/Alt Animation Toggle.png | Bin 436 -> 209 bytes source/funkin/editors/charter/Charter.hx | 15 ++- source/funkin/editors/ui/UIButton.hx | 3 - source/funkin/editors/ui/UISlider.hx | 93 +++++++++++------- source/funkin/editors/ui/UIState.hx | 1 + source/funkin/editors/ui/UIText.hx | 7 +- 6 files changed, 75 insertions(+), 44 deletions(-) diff --git a/assets/images/editors/charter/event-icons/Alt Animation Toggle.png b/assets/images/editors/charter/event-icons/Alt Animation Toggle.png index f2180276fa5df35e20297dfa33a07a8695360ac9..39e1afd14082fba9419bd998a0004b1d3350beae 100644 GIT binary patch delta 166 zcmdnOe35a2gcJue0|SGGE`KnPVk{1FcVbv~PUa<$qdqZEzP`8XFDJ`p7W2&vIx|Am zCGvsdyd^&t;uc H0%H>ZcAi0- literal 436 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFvNcITwWnidMV_;}#VPN&XcW%!~#nmmJ98NLyiH$kxPqC&;DQu}CYkbLql1 zg~lx=9|IUCI7CGyDY`J62xu_4 = []; public var barWidth:Int = 120; - public var barStartSpr:FlxSprite; + public var progressbar:UISprite; + public var progressCentered:Bool; + public var startText:UIText; - public var barEndSpr:FlxSprite; public var endText:UIText; - public var barSegements:Map<{segment:Float, size:Float}, UISprite> = []; public var selectableBar:UISprite; public var selectableHitbox:UISprite; public var value:Float = 0; public var onChange:Float->Void; - public function new(x:Float, y:Float, width:Int = 120, segments:Array, defaultStart:Float = 0) { + public function new(x:Float, y:Float, width:Int = 120, segments:Array, centered:Bool, defaultStart:Float = 0) { this.segments = segments; this.barWidth = width; + this.progressCentered = centered; - x -= 6; super(x, y); - makeSolid((barWidth+6), 4, -1); + + makeGraphic(barWidth, 12, 0x00000000, true); + this.drawRoundRect(0, 0, barWidth, 12, 8, 6, 0xFFC0C0C0); + this.drawRoundRect(1, 1, barWidth-2, 12-2, 8, 5, 0xFF140013); cursor = BUTTON; + progressbar = new UISprite(centered ? barWidth/2 : 0); + progressbar.makeGraphic(barWidth, 8, 0x00000000, true); + progressbar.drawRoundRect(2, 0, barWidth-4, 8-.1, 8, 2, 0xFF67009B); + progressbar.origin.x = 0; + members.push(progressbar); + __barProgress = defaultStart; - members.push(barStartSpr = new FlxSprite(x-4,y+((4/2))).makeSolid(4, 12, -1)); - members.push(barEndSpr = new FlxSprite(x+barWidth+6,y+((4/2))).makeSolid(4, 12, -1)); - members.push(startText = new UIText(x, y, 0, Std.string(segments[0].start).replace("0.", "."))); - members.push(endText = new UIText(x + (barWidth+6) + 8, y, 0, Std.string(segments[segments.length-1].end))); - - var midSegments:Map = []; - for (segment in segments) { - var isFront:Bool = segment.start == segments[0].start; - var isEnd:Bool = segment.end == segments[segments.length-1].end; - - if (isFront && !midSegments.exists(Std.int(segment.end*1000))) midSegments.set(Std.int(segment.end*1000), segment.size); - if (isEnd && !midSegments.exists(Std.int(segment.start*1000))) midSegments.set(Std.int(segment.start*1000), segment.size); - } + members.push(endText = new UIText(x + (barWidth) + 8, y, 0, Std.string(segments[segments.length-1].end).replace("0.", "."))); - for (segment => size in midSegments) { - var segmentSpr:UISprite = new UISprite(x,y); - segmentSpr.makeSolid(4, 8, -1); - members.push(segmentSpr); - - barSegements.set({segment: segment/1000, size: size}, segmentSpr); - } - selectableBar = new UISprite(x,y); - selectableBar.makeSolid(6, 12, 0xFFA0A0A0); + selectableBar.loadGraphic(Paths.image("editors/ui/slider")); + selectableBar.antialiasing = true; selectableBar.cursor = BUTTON; members.push(selectableBar); selectableHitbox = new UISprite(x,y); - selectableHitbox.makeSolid(barWidth+6, 16, -1); + selectableHitbox.makeSolid(barWidth, 16, -1); selectableHitbox.cursor = BUTTON; selectableHitbox.alpha = 0; members.push(selectableHitbox); @@ -73,10 +64,8 @@ class UISlider extends UISprite { var __barProgress:Float = 0; public override function update(elapsed:Float) { - barStartSpr.follow(this, -4, (height-barStartSpr.height)/2); - barEndSpr.follow(this, barWidth+6, (height-barEndSpr.height)/2); - selectableHitbox.follow(this, 0, (height-selectableHitbox.height)/2); + var lastBarProgress:Float = __barProgress; if (selectableHitbox.hovered && FlxG.mouse.pressed) { @@ -87,14 +76,14 @@ class UISlider extends UISprite { if (__barProgress != lastBarProgress) onChange(value = calcValue(__barProgress)); + + progressbar.follow(this, progressCentered ? barWidth/2 : 0, (height-progressbar.height)/2); + progressbar.scale.x = FlxMath.bound(__barProgress-(progressCentered?0.5:0),-1,1); - selectableBar.follow(this, __barProgress * barWidth, (4-12)/2); + selectableBar.follow(this, (__barProgress * barWidth) - (selectableBar.width/2), (height-selectableBar.height)/2); - startText.follow(this, -startText.width-10, (4/2) - (startText.height/2)); - endText.follow(this, barWidth+6 + 10, (4/2) - (endText.height/2)); - - for (segmentData => sprite in barSegements) - sprite.follow(this, (barWidth * segmentData.size) + ((selectableBar.width-sprite.width)/2), ((4-8)/2)); + startText.follow(this, -startText.width-10, (height/2) - (startText.height/2)); + endText.follow(this, barWidth + 10, (height/2) - (endText.height/2)); super.update(elapsed); } @@ -110,4 +99,32 @@ class UISlider extends UISprite { } return segments[segments.length-1].end; } +} + +typedef UISliderPreset = { + var value:Float; + var barProgress:Float; + var ?color:Int; +} + +class UISliderExtras extends UISliceSprite { + public var buttonText:UIText; + public var buttons:Map = []; + + public function new(x:Float, y:Float, presets:Array, presetValueName:String = "Presets:") { + super(x - 12, y, (presets.length * (40 + 2)) + 22, 40+10, 'editors/ui/inputbox'); + alpha = 0.6; + + members.push(buttonText = new UIText(x-4,y+5, 0, presetValueName, 12)); + buttonText.borderStyle = OUTLINE; buttonText.borderColor = 0x88000000; buttonText.borderSize = 1; + + for (i => preset in presets) { + var button = new UIButton(x + (i*(40 + 2)), y + buttonText.height + 5 + 2, Std.string(preset.value).replace("0.", "."), null, 40, 20); + button.field.size = 14; + if (preset.color != null) button.color = preset.color; + members.push(button); + + buttons.set(preset, button); + } + } } \ No newline at end of file diff --git a/source/funkin/editors/ui/UIState.hx b/source/funkin/editors/ui/UIState.hx index ba7a3943..b43e605e 100644 --- a/source/funkin/editors/ui/UIState.hx +++ b/source/funkin/editors/ui/UIState.hx @@ -33,6 +33,7 @@ class UIState extends MusicBeatState { __mousePos = FlxPoint.get(); super.create(); Framerate.offset.y = 30; + FlxG.mouse.visible = true; FlxG.stage.window.onKeyDown.add(onKeyDown); FlxG.stage.window.onKeyUp.add(onKeyUp); diff --git a/source/funkin/editors/ui/UIText.hx b/source/funkin/editors/ui/UIText.hx index 413630b2..5f2aaf72 100644 --- a/source/funkin/editors/ui/UIText.hx +++ b/source/funkin/editors/ui/UIText.hx @@ -5,10 +5,15 @@ import funkin.backend.FunkinText; class UIText extends FunkinText { // PUTTING THIS HERE IN CASE IMMA MAKE FUTURE CHANGES - public function new(x, y, w, text, size:Int = 15, color:FlxColor = 0xFFFFFFFF) { + public function new(x, y, w, text, size:Int = 15, color:FlxColor = 0xFFFFFFFF, ?outline:Bool = true) { super(x, y, w, text, size, false); this.color = color; + if (outline) { + this.borderStyle = OUTLINE_FAST; + this.borderColor = 0x88000000; + this.borderSize = 1; + } this.active = false; } } \ No newline at end of file From 91390b4d8bcb83fe40bd0364778d0b8d21020926 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:18:34 -0700 Subject: [PATCH 54/72] optimized text outlines (idk if we gonna keep it) --- source/funkin/editors/ui/UISlider.hx | 2 +- source/funkin/editors/ui/UIText.hx | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/source/funkin/editors/ui/UISlider.hx b/source/funkin/editors/ui/UISlider.hx index 134df9d7..d86508c5 100644 --- a/source/funkin/editors/ui/UISlider.hx +++ b/source/funkin/editors/ui/UISlider.hx @@ -39,7 +39,7 @@ class UISlider extends UISprite { progressbar = new UISprite(centered ? barWidth/2 : 0); progressbar.makeGraphic(barWidth, 8, 0x00000000, true); - progressbar.drawRoundRect(2, 0, barWidth-4, 8-.1, 8, 2, 0xFF67009B); + progressbar.drawRoundRect(2, 0, barWidth-4, 8, 8, 2, 0xFF67009B); progressbar.origin.x = 0; members.push(progressbar); diff --git a/source/funkin/editors/ui/UIText.hx b/source/funkin/editors/ui/UIText.hx index 5f2aaf72..dc5b5535 100644 --- a/source/funkin/editors/ui/UIText.hx +++ b/source/funkin/editors/ui/UIText.hx @@ -16,4 +16,29 @@ class UIText extends FunkinText { } this.active = false; } + + public override function applyBorderStyle() { + if (borderStyle == OUTLINE_FAST) { + var iterations:Int = Std.int(borderSize * borderQuality); + if (iterations <= 0) + { + iterations = 1; + } + var delta:Float = borderSize / iterations; + + applyFormats(_formatAdjusted, true); + + var curDelta:Float = delta; + for (i in 0...iterations) + { + copyTextWithOffset(-curDelta, -curDelta); // upper-left + copyTextWithOffset(curDelta * 2, curDelta * 2); // lower-right + + _matrix.translate(-curDelta, -curDelta); // return to center + curDelta += delta; + } + return; + } + super.applyBorderStyle(); + } } \ No newline at end of file From c0da2fadf2068ca8220eabcb7195388dcfd3a0cb Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 7 Oct 2023 21:16:44 -0700 Subject: [PATCH 55/72] add text box to slider (still needs to be visually fixed) --- .../images/editors/charter/add-strumline.png | Bin 5712 -> 611 bytes .../images/editors/charter/lock-strumline.png | Bin 5712 -> 949 bytes source/funkin/editors/ui/UISlider.hx | 51 +++++++++++++++--- source/funkin/editors/ui/UITextBox.hx | 2 +- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/assets/images/editors/charter/add-strumline.png b/assets/images/editors/charter/add-strumline.png index f2262c21c103dccac52cd3b1713e93412eeeb91a..f6355d051bbc3a2310c2d3006fc8388cbbe13dc7 100644 GIT binary patch delta 586 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 public function new(x:Float, y:Float, width:Int = 120, segments:Array, centered:Bool, defaultStart:Float = 0) { @@ -39,8 +46,8 @@ class UISlider extends UISprite { progressbar = new UISprite(centered ? barWidth/2 : 0); progressbar.makeGraphic(barWidth, 8, 0x00000000, true); - progressbar.drawRoundRect(2, 0, barWidth-4, 8, 8, 2, 0xFF67009B); - progressbar.origin.x = 0; + progressbar.drawRoundRect(2, 0, barWidth-4, 8, 8, 2, 0xFFFFFFFF); + progressbar.origin.x = 0; progressbar.colorTransform.color = 0xFF67009B; members.push(progressbar); __barProgress = defaultStart; @@ -55,16 +62,27 @@ class UISlider extends UISprite { members.push(selectableBar); selectableHitbox = new UISprite(x,y); - selectableHitbox.makeSolid(barWidth, 16, -1); + selectableHitbox.makeSolid(barWidth, 18, -1); selectableHitbox.cursor = BUTTON; selectableHitbox.alpha = 0; members.push(selectableHitbox); + + valueStepper = new UINumericStepper(x - 64 - 64, y, 1, 0.01, 2, segments[0].start, segments[segments.length-1].end, 0, 18); + valueStepper.antialiasing = true; + valueStepper.onChange = function (text:String) { + @:privateAccess valueStepper.__onChange(text); + value = valueStepper.value; + } + members.push(valueStepper); } var __barProgress:Float = 0; public override function update(elapsed:Float) { selectableHitbox.follow(this, 0, (height-selectableHitbox.height)/2); + + valueStepper.bWidth = valueStepper.label.text.length <= 0 ? 25 : Std.int(valueStepper.label.textField.width) + 12; + valueStepper.follow(this, -startText.width-10 - valueStepper.bWidth - 4, (height-valueStepper.bHeight)/2); var lastBarProgress:Float = __barProgress; @@ -74,13 +92,17 @@ class UISlider extends UISprite { mousePos.put(); } - if (__barProgress != lastBarProgress) - onChange(value = calcValue(__barProgress)); + if (__barProgress != lastBarProgress) { + onChange(@:bypassAccessor value = calcValue(__barProgress)); + valueStepper.value = value; + } progressbar.follow(this, progressCentered ? barWidth/2 : 0, (height-progressbar.height)/2); progressbar.scale.x = FlxMath.bound(__barProgress-(progressCentered?0.5:0),-1,1); + progressbar.colorTransform.color = FlxColor.interpolate(progressbar.colorTransform.color, selectableHitbox.hovered ? 0xFFB235F0 : 0xFF67009B, 1/14); selectableBar.follow(this, (__barProgress * barWidth) - (selectableBar.width/2), (height-selectableBar.height)/2); + //selectableBar.colorTransform.color = FlxColor.interpolate(selectableBar.colorTransform.color, selectableHitbox.hovered ? 0x6DFFFFFF : 0x00000000, 1/14); startText.follow(this, -startText.width-10, (height/2) - (startText.height/2)); endText.follow(this, barWidth + 10, (height/2) - (endText.height/2)); @@ -88,7 +110,7 @@ class UISlider extends UISprite { super.update(elapsed); } - function calcValue(progress:Float):Float { + private function calcValue(progress:Float):Float { var totalProgress:Float = 0; for (segment in segments) { if (progress < totalProgress + segment.size) { @@ -99,6 +121,21 @@ class UISlider extends UISprite { } return segments[segments.length-1].end; } + + private function calcProgress(value:Float):Float { + if (value >= segments[segments.length-1].end) return 1; + if (value <= segments[0].start) return 0; + + var totalProgress:Float = 0; + for (segment in segments) { + if (value >= segment.start && value <= segment.end) { + var relativeProgress = FlxMath.remapToRange(value, segment.start, segment.end, 0, 1); + return totalProgress + relativeProgress * segment.size; + } + totalProgress += segment.size; + } + return -1; + } } typedef UISliderPreset = { diff --git a/source/funkin/editors/ui/UITextBox.hx b/source/funkin/editors/ui/UITextBox.hx index 9e7dae4f..8c072e63 100644 --- a/source/funkin/editors/ui/UITextBox.hx +++ b/source/funkin/editors/ui/UITextBox.hx @@ -68,7 +68,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable { } var off = multiline ? 4 : ((bHeight - label.height) / 2); - label.follow(this, 4, off); + label.follow(this, label.autoSize ? (bWidth-label.textField.width)/2 : 4, off); framesOffset = (selected ? 18 : (hovered ? 9 : 0)); @:privateAccess { if (selected) { From 0ab560d2b05e76c9fb30ef57f8d69efb4958c598 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sat, 7 Oct 2023 23:10:05 -0700 Subject: [PATCH 56/72] polish slider --- source/funkin/editors/charter/Charter.hx | 14 +---- source/funkin/editors/ui/UISlider.hx | 72 +++++++++--------------- 2 files changed, 29 insertions(+), 57 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index d7a5a3c0..9e19bc10 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1,6 +1,5 @@ package funkin.editors.charter; -import funkin.editors.ui.UISlider.UISliderExtras; import funkin.editors.charter.CharterStrumline; import funkin.editors.charter.CharterBackdropGroup.EventBackdrop; import funkin.backend.system.framerate.Framerate; @@ -377,18 +376,7 @@ class Charter extends UIState { songPosInfo.alignment = RIGHT; uiGroup.add(songPosInfo); - /* - var extraInfo = new UISliderExtras(FlxG.width - 20 - (5*42) - 18, scrollBar.y + 8, [ - {value: .25, barProgress: 0.5, color: 0xFF870000}, - {value: .5, barProgress: 0.5, color: 0xFF870000}, - {value: 1, barProgress: 0.5, color: 0x6B6B6B}, - {value: 1.5, barProgress: 0.5, color: 0xFF008000}, - {value: 2, barProgress: 0.5, color: 0xFF008000}] - , "Preset Playback Speeds:"); - uiGroup.add(extraInfo); - */ - - playBackSlider = new UISlider(FlxG.width - 160 - 26 - 20, (23/2) - (12/2), 160, [{start: 0.25, end: 1, size: 0.5}, {start: 1, end: 2, size: 0.5}], true, 0.5); + playBackSlider = new UISlider(FlxG.width - 160 - 26 - 20, (23/2) - (12/2), 160, 1, [{start: 0.25, end: 1, size: 0.5}, {start: 1, end: 2, size: 0.5}], true); playBackSlider.onChange = function (v) { FlxG.sound.music.pitch = vocals.pitch = v; }; diff --git a/source/funkin/editors/ui/UISlider.hx b/source/funkin/editors/ui/UISlider.hx index 4291b1be..7968df41 100644 --- a/source/funkin/editors/ui/UISlider.hx +++ b/source/funkin/editors/ui/UISlider.hx @@ -21,18 +21,19 @@ class UISlider extends UISprite { public var endText:UIText; public var selectableBar:UISprite; + public var selectableBarHighlight:UISprite; public var selectableHitbox:UISprite; public var value(default, set):Float = 0; public function set_value(newVal:Float):Float { - __barProgress = calcProgress(newVal); onChange(newVal); + __barProgress = __calcProgress(newVal); onChange(newVal); return value = newVal; } public var valueStepper:UINumericStepper; public var onChange:Float->Void; - public function new(x:Float, y:Float, width:Int = 120, segments:Array, centered:Bool, defaultStart:Float = 0) { + public function new(x:Float, y:Float, width:Int = 120, value:Float, segments:Array, centered:Bool) { this.segments = segments; this.barWidth = width; this.progressCentered = centered; @@ -50,16 +51,23 @@ class UISlider extends UISprite { progressbar.origin.x = 0; progressbar.colorTransform.color = 0xFF67009B; members.push(progressbar); - __barProgress = defaultStart; + __barProgress = visualProgress = __calcProgress(value); members.push(startText = new UIText(x, y, 0, Std.string(segments[0].start).replace("0.", "."))); members.push(endText = new UIText(x + (barWidth) + 8, y, 0, Std.string(segments[segments.length-1].end).replace("0.", "."))); - selectableBar = new UISprite(x,y); - selectableBar.loadGraphic(Paths.image("editors/ui/slider")); - selectableBar.antialiasing = true; - selectableBar.cursor = BUTTON; - members.push(selectableBar); + for (i in 0...2) { + var selectableBar:UISprite = new UISprite(x,y); + selectableBar.loadGraphic(Paths.image("editors/ui/slider")); + selectableBar.antialiasing = true; + selectableBar.cursor = BUTTON; + members.push(selectableBar); + + switch (i) { + case 0: this.selectableBar = selectableBar; + case 1: this.selectableBarHighlight = selectableBar; selectableBarHighlight.colorTransform.color = 0xFFFFFFFF; selectableBarHighlight.alpha = 0; + } + } selectableHitbox = new UISprite(x,y); selectableHitbox.makeSolid(barWidth, 18, -1); @@ -77,6 +85,9 @@ class UISlider extends UISprite { } var __barProgress:Float = 0; + var visualProgress:Float = 0; + + var __highLightTimer:Float = 0; public override function update(elapsed:Float) { selectableHitbox.follow(this, 0, (height-selectableHitbox.height)/2); @@ -93,16 +104,17 @@ class UISlider extends UISprite { } if (__barProgress != lastBarProgress) { - onChange(@:bypassAccessor value = calcValue(__barProgress)); + onChange(@:bypassAccessor value = __calcValue(__barProgress)); valueStepper.value = value; } - + + visualProgress = FlxMath.lerp(visualProgress, __barProgress, 1/2.25); progressbar.follow(this, progressCentered ? barWidth/2 : 0, (height-progressbar.height)/2); - progressbar.scale.x = FlxMath.bound(__barProgress-(progressCentered?0.5:0),-1,1); - progressbar.colorTransform.color = FlxColor.interpolate(progressbar.colorTransform.color, selectableHitbox.hovered ? 0xFFB235F0 : 0xFF67009B, 1/14); + progressbar.scale.x = FlxMath.bound(visualProgress-(progressCentered?0.5:0),-1,1); + progressbar.colorTransform.color = FlxColor.interpolate(progressbar.colorTransform.color, selectableHitbox.hovered ? 0xFF7F00BF : 0xFF67009B, 1/14); - selectableBar.follow(this, (__barProgress * barWidth) - (selectableBar.width/2), (height-selectableBar.height)/2); - //selectableBar.colorTransform.color = FlxColor.interpolate(selectableBar.colorTransform.color, selectableHitbox.hovered ? 0x6DFFFFFF : 0x00000000, 1/14); + selectableBar.follow(this, (visualProgress * barWidth) - (selectableBar.width/2), (height-selectableBar.height)/2); selectableBarHighlight.follow(selectableBar); + selectableBarHighlight.alpha = FlxMath.lerp(selectableBarHighlight.alpha, selectableHitbox.hovered ? 0.075: 0, 1/14); startText.follow(this, -startText.width-10, (height/2) - (startText.height/2)); endText.follow(this, barWidth + 10, (height/2) - (endText.height/2)); @@ -110,7 +122,7 @@ class UISlider extends UISprite { super.update(elapsed); } - private function calcValue(progress:Float):Float { + private function __calcValue(progress:Float):Float { var totalProgress:Float = 0; for (segment in segments) { if (progress < totalProgress + segment.size) { @@ -122,7 +134,7 @@ class UISlider extends UISprite { return segments[segments.length-1].end; } - private function calcProgress(value:Float):Float { + private function __calcProgress(value:Float):Float { if (value >= segments[segments.length-1].end) return 1; if (value <= segments[0].start) return 0; @@ -136,32 +148,4 @@ class UISlider extends UISprite { } return -1; } -} - -typedef UISliderPreset = { - var value:Float; - var barProgress:Float; - var ?color:Int; -} - -class UISliderExtras extends UISliceSprite { - public var buttonText:UIText; - public var buttons:Map = []; - - public function new(x:Float, y:Float, presets:Array, presetValueName:String = "Presets:") { - super(x - 12, y, (presets.length * (40 + 2)) + 22, 40+10, 'editors/ui/inputbox'); - alpha = 0.6; - - members.push(buttonText = new UIText(x-4,y+5, 0, presetValueName, 12)); - buttonText.borderStyle = OUTLINE; buttonText.borderColor = 0x88000000; buttonText.borderSize = 1; - - for (i => preset in presets) { - var button = new UIButton(x + (i*(40 + 2)), y + buttonText.height + 5 + 2, Std.string(preset.value).replace("0.", "."), null, 40, 20); - button.field.size = 14; - if (preset.color != null) button.color = preset.color; - members.push(button); - - buttons.set(preset, button); - } - } } \ No newline at end of file From 744b62bf5e4a29c2a99636549c0ea67a891b320f Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 8 Oct 2023 14:31:15 -0700 Subject: [PATCH 57/72] optimize updating text --- source/funkin/editors/charter/Charter.hx | 2 +- source/funkin/editors/ui/UIText.hx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 9e19bc10..d464b3e3 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -373,7 +373,7 @@ class Charter extends UIState { uiGroup.add(scrollBar); songPosInfo = new UIText(FlxG.width - 30 - 400, scrollBar.y + 10, 400, "00:00\nBeat: 0\nStep: 0\nMeasure: 0\nBPM: 0\nTime Signature: 4/4"); - songPosInfo.alignment = RIGHT; + songPosInfo.alignment = RIGHT; songPosInfo.optimized = true; uiGroup.add(songPosInfo); playBackSlider = new UISlider(FlxG.width - 160 - 26 - 20, (23/2) - (12/2), 160, 1, [{start: 0.25, end: 1, size: 0.5}, {start: 1, end: 2, size: 0.5}], true); diff --git a/source/funkin/editors/ui/UIText.hx b/source/funkin/editors/ui/UIText.hx index dc5b5535..83daab60 100644 --- a/source/funkin/editors/ui/UIText.hx +++ b/source/funkin/editors/ui/UIText.hx @@ -4,6 +4,7 @@ import flixel.util.FlxColor; import funkin.backend.FunkinText; class UIText extends FunkinText { + public var optimized:Bool = false; // PUTTING THIS HERE IN CASE IMMA MAKE FUTURE CHANGES public function new(x, y, w, text, size:Int = 15, color:FlxColor = 0xFFFFFFFF, ?outline:Bool = true) { super(x, y, w, text, size, false); @@ -18,7 +19,7 @@ class UIText extends FunkinText { } public override function applyBorderStyle() { - if (borderStyle == OUTLINE_FAST) { + if (borderStyle == OUTLINE_FAST && optimized) { var iterations:Int = Std.int(borderSize * borderQuality); if (iterations <= 0) { From ae2b4e38f77013f34342ce33d03621026e7c7595 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 8 Oct 2023 15:07:54 -0700 Subject: [PATCH 58/72] ok its finally finished --- source/funkin/editors/charter/Charter.hx | 2 +- source/funkin/editors/ui/UISlider.hx | 8 +++----- source/funkin/editors/ui/UITextBox.hx | 1 + 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index d464b3e3..dd257318 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -906,7 +906,7 @@ class Charter extends UIState { if (true) { __crochet = ((60 / Conductor.bpm) * 1000); - if(FlxG.keys.justPressed.ANY) + if(FlxG.keys.justPressed.ANY && !strumLines.isDragging && this.currentFocus == null) UIUtil.processShortcuts(topMenu); if (FlxG.keys.pressed.CONTROL) { diff --git a/source/funkin/editors/ui/UISlider.hx b/source/funkin/editors/ui/UISlider.hx index 7968df41..5ef8c9bb 100644 --- a/source/funkin/editors/ui/UISlider.hx +++ b/source/funkin/editors/ui/UISlider.hx @@ -75,11 +75,11 @@ class UISlider extends UISprite { selectableHitbox.alpha = 0; members.push(selectableHitbox); - valueStepper = new UINumericStepper(x - 64 - 64, y, 1, 0.01, 2, segments[0].start, segments[segments.length-1].end, 0, 18); - valueStepper.antialiasing = true; + valueStepper = new UINumericStepper(x - 64 - 64, y, 1, 0.01, 2, segments[0].start, segments[segments.length-1].end, 0, 16); + valueStepper.antialiasing = valueStepper.label.antialiasing = true; valueStepper.onChange = function (text:String) { @:privateAccess valueStepper.__onChange(text); - value = valueStepper.value; + visualProgress = __barProgress = __calcProgress(value = valueStepper.value); } members.push(valueStepper); } @@ -87,8 +87,6 @@ class UISlider extends UISprite { var __barProgress:Float = 0; var visualProgress:Float = 0; - var __highLightTimer:Float = 0; - public override function update(elapsed:Float) { selectableHitbox.follow(this, 0, (height-selectableHitbox.height)/2); diff --git a/source/funkin/editors/ui/UITextBox.hx b/source/funkin/editors/ui/UITextBox.hx index 8c072e63..3aa97fd2 100644 --- a/source/funkin/editors/ui/UITextBox.hx +++ b/source/funkin/editors/ui/UITextBox.hx @@ -104,6 +104,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable { switch(e) { case RETURN: focused = false; + if (onChange != null) onChange(label.text); case LEFT: changeSelection(-1); case RIGHT: From a77164d630786ab7b135e5fc8473f96e537d2459 Mon Sep 17 00:00:00 2001 From: lunarcleint <88809950+lunarcleint@users.noreply.github.com> Date: Sun, 8 Oct 2023 22:24:06 -0700 Subject: [PATCH 59/72] asodj --- source/funkin/editors/charter/Charter.hx | 7 +++++++ source/funkin/editors/ui/UISlider.hx | 10 +++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index dd257318..e04119e8 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -1,5 +1,6 @@ package funkin.editors.charter; +import funkin.editors.ui.UITopMenu.UITopMenuButton; import funkin.editors.charter.CharterStrumline; import funkin.editors.charter.CharterBackdropGroup.EventBackdrop; import funkin.backend.system.framerate.Framerate; @@ -893,6 +894,12 @@ class Charter extends UIState { ((((40*4) * gridBackdrops.strumlinesAmount) - FlxG.width) / 2), gridBackdrops.conductorSprY - (FlxG.height * 0.5) ); + + if (topMenuSpr.members[5] != null) { + var playBackMenu:UITopMenuButton = cast topMenuSpr.members[5]; + playBackMenu.x = playBackSlider.x-playBackSlider.startText.width-10-playBackSlider.valueStepper.bWidth-playBackMenu.bWidth-10; + playBackMenu.label.offset.x = -2; + } super.update(elapsed); diff --git a/source/funkin/editors/ui/UISlider.hx b/source/funkin/editors/ui/UISlider.hx index 5ef8c9bb..fca67325 100644 --- a/source/funkin/editors/ui/UISlider.hx +++ b/source/funkin/editors/ui/UISlider.hx @@ -80,17 +80,21 @@ class UISlider extends UISprite { valueStepper.onChange = function (text:String) { @:privateAccess valueStepper.__onChange(text); visualProgress = __barProgress = __calcProgress(value = valueStepper.value); + if (onChange != null) onChange(value); } members.push(valueStepper); } var __barProgress:Float = 0; var visualProgress:Float = 0; + + var __stepperWidth = 25; public override function update(elapsed:Float) { selectableHitbox.follow(this, 0, (height-selectableHitbox.height)/2); - valueStepper.bWidth = valueStepper.label.text.length <= 0 ? 25 : Std.int(valueStepper.label.textField.width) + 12; + __stepperWidth = valueStepper.label.text.length <= 0 ? 25 : Std.int(valueStepper.label.textField.width) + 12; + valueStepper.bWidth = Std.int(FlxMath.lerp(valueStepper.bWidth, __stepperWidth, 1/2.25)); valueStepper.follow(this, -startText.width-10 - valueStepper.bWidth - 4, (height-valueStepper.bHeight)/2); var lastBarProgress:Float = __barProgress; @@ -102,7 +106,7 @@ class UISlider extends UISprite { } if (__barProgress != lastBarProgress) { - onChange(@:bypassAccessor value = __calcValue(__barProgress)); + if (onChange != null) onChange(@:bypassAccessor value = __calcValue(__barProgress)); valueStepper.value = value; } @@ -112,7 +116,7 @@ class UISlider extends UISprite { progressbar.colorTransform.color = FlxColor.interpolate(progressbar.colorTransform.color, selectableHitbox.hovered ? 0xFF7F00BF : 0xFF67009B, 1/14); selectableBar.follow(this, (visualProgress * barWidth) - (selectableBar.width/2), (height-selectableBar.height)/2); selectableBarHighlight.follow(selectableBar); - selectableBarHighlight.alpha = FlxMath.lerp(selectableBarHighlight.alpha, selectableHitbox.hovered ? 0.075: 0, 1/14); + selectableBarHighlight.alpha = FlxMath.lerp(selectableBarHighlight.alpha, selectableHitbox.hovered ? 0.1: 0, 1/14); startText.follow(this, -startText.width-10, (height/2) - (startText.height/2)); endText.follow(this, barWidth + 10, (height/2) - (endText.height/2)); From d4ec095e4288879ab4f84a40dd19f36284470627 Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Mon, 9 Oct 2023 17:42:49 +0200 Subject: [PATCH 60/72] Multi Spritesheets + Bug Fixes --- source/funkin/backend/FlxAnimate.hx | 2 +- .../backend/assets/MultiFramesCollection.hx | 72 +++++++++++++++++++ source/funkin/backend/assets/Paths.hx | 15 ++-- source/funkin/game/PlayState.hx | 2 +- 4 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 source/funkin/backend/assets/MultiFramesCollection.hx diff --git a/source/funkin/backend/FlxAnimate.hx b/source/funkin/backend/FlxAnimate.hx index ea1644bc..c6559dfd 100644 --- a/source/funkin/backend/FlxAnimate.hx +++ b/source/funkin/backend/FlxAnimate.hx @@ -25,7 +25,7 @@ class FlxAnimate extends flxanimate.FlxAnimate { getScreenPosition(_point, camera).subtractPoint(offset); rMatrix.translate(-origin.x, -origin.y); - if (!showPivot && limb.name != "pivot") { + if (limb != _pivot) { if (frameOffsetAngle != null && frameOffsetAngle != angle) { var angleOff = (-angle + frameOffsetAngle) * FlxAngle.TO_RAD; diff --git a/source/funkin/backend/assets/MultiFramesCollection.hx b/source/funkin/backend/assets/MultiFramesCollection.hx new file mode 100644 index 00000000..a3d9c733 --- /dev/null +++ b/source/funkin/backend/assets/MultiFramesCollection.hx @@ -0,0 +1,72 @@ +package funkin.backend.assets; + +import flixel.graphics.frames.FlxFramesCollection; +import flixel.FlxG; +import flixel.graphics.FlxGraphic; +import flixel.graphics.frames.FlxFrame.FlxFrameAngle; +import flixel.graphics.frames.FlxFrame.FlxFrameType; +import flixel.math.FlxMath; +import flixel.math.FlxPoint; +import flixel.math.FlxRect; +import flixel.util.FlxDestroyUtil; +import flixel.util.FlxStringUtil; + +/** + * Base class for all frame collections. + */ +class MultiFramesCollection extends FlxFramesCollection +{ + public var parentedFrames:Array = []; + + public function new(parent:FlxGraphic, ?border:FlxPoint) + { + super(parent, USER("MULTI"), border); + } + + /** + * Returns the `FlxAtlasFrame` of the specified `FlxGraphic` object. + * + * @param graphic `FlxGraphic` object to find the `FlxAtlasFrames` collection for. + * @return `FlxAtlasFrames` collection for the specified `FlxGraphic` object + * Could be `null` if `FlxGraphic` doesn't have it yet. + */ + public static function findFrame(graphic:FlxGraphic, ?border:FlxPoint):MultiFramesCollection + { + if (border == null) + border = FlxPoint.weak(); + + var atlasFrames:Array = cast graphic.getFramesCollections(USER("MULTI")); + + for (atlas in atlasFrames) + if (atlas.border.equals(border)) + return atlas; + + return null; + } + + public function addFrames(collection:FlxFramesCollection) { + if (collection == null || collection.frames == null) return; + + collection.parent.useCount++; + parentedFrames.push(collection); + + for(f in collection.frames) { + if (f != null) { + pushFrame(f); + f.parent = collection.parent; + } + } + } + + public override function destroy():Void + { + if(parentedFrames != null) { + for(collection in parentedFrames) { + if(collection != null) + collection.parent.useCount--; + } + parentedFrames = null; + } + super.destroy(); + } +} \ No newline at end of file diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx index 921d6584..7f847670 100644 --- a/source/funkin/backend/assets/Paths.hx +++ b/source/funkin/backend/assets/Paths.hx @@ -199,25 +199,18 @@ class Paths // MULTIPLE SPRITESHEETS!! var graphic = FlxG.bitmap.add("flixel/images/logo/default.png", false, '$noExt/mult'); - var frames = FlxAtlasFrames.findFrame(graphic); + var frames = MultiFramesCollection.findFrame(graphic); if (frames != null) return frames; trace("no frames yet for multiple atlases!!"); - var spritesheets = []; var cur = 1; - var finalFrames = new FlxFramesCollection(graphic, ATLAS); + var finalFrames = new MultiFramesCollection(graphic); while(Assets.exists('$noExt/$cur.png')) { - spritesheets.push(loadFrames('$noExt/$cur.png')); + var spr = loadFrames('$noExt/$cur.png'); + finalFrames.addFrames(spr); cur++; } - for(frames in spritesheets) - if (frames != null && frames.frames != null) - for(f in frames.frames) - if (f != null) { - finalFrames.frames.push(f); - f.parent = frames.parent; - } return finalFrames; } else if (Assets.exists('$noExt.xml')) { return Paths.getSparrowAtlasAlt(noExt); diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index c307fbde..ac0d77d4 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -1486,7 +1486,7 @@ class PlayState extends MusicBeatState if (event.showRating || (event.showRating == null && event.player)) { displayCombo(event); - displayRating(daRating, event); + displayRating(event.rating, event); ratingNum += 1; } } From a620c0ceed0966624fa18a15564674dbb84e394c Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Thu, 12 Oct 2023 12:22:05 +0200 Subject: [PATCH 61/72] Added library redirecting + Addons fixes --- .../backend/assets/IModsAssetLibrary.hx | 1 + source/funkin/backend/assets/ModsFolder.hx | 19 +++++++++------ .../backend/assets/ModsFolderLibrary.hx | 16 ++++++++++++- source/funkin/backend/assets/Paths.hx | 2 +- .../backend/assets/ScriptedAssetLibrary.hx | 12 ++++++++-- .../funkin/backend/assets/ZipFolderLibrary.hx | 21 +++++++++++++++-- .../backend/system/CommandLineHandler.hx | 23 +++++++++++++++---- source/funkin/backend/system/Main.hx | 1 + source/funkin/backend/system/MainState.hx | 4 ++-- .../backend/system/framerate/AssetTreeInfo.hx | 4 ++-- 10 files changed, 81 insertions(+), 22 deletions(-) diff --git a/source/funkin/backend/assets/IModsAssetLibrary.hx b/source/funkin/backend/assets/IModsAssetLibrary.hx index 5c90b185..a080189b 100644 --- a/source/funkin/backend/assets/IModsAssetLibrary.hx +++ b/source/funkin/backend/assets/IModsAssetLibrary.hx @@ -23,6 +23,7 @@ using StringTools; interface IModsAssetLibrary { public var prefix:String; + public var modName:String; public var libName:String; #if MOD_SUPPORT diff --git a/source/funkin/backend/assets/ModsFolder.hx b/source/funkin/backend/assets/ModsFolder.hx index 33458fe0..fc37ed52 100644 --- a/source/funkin/backend/assets/ModsFolder.hx +++ b/source/funkin/backend/assets/ModsFolder.hx @@ -41,6 +41,11 @@ class ModsFolder { */ public static var addonsPath:String = "./addons/"; + /** + * If accessing a file as assets/data/global/LIB_mymod.hx should redirect to mymod:assets/data/global.hx + */ + public static var useLibFile:Bool = true; + /** * Whenever its the first time mods has been reloaded. */ @@ -72,12 +77,12 @@ class ModsFolder { * @param modName Name of the mod * @param force Whenever the mod should be reloaded if it has already been loaded */ - public static function loadModLib(path:String, force:Bool = false) { + public static function loadModLib(path:String, force:Bool = false, ?modName:String) { #if MOD_SUPPORT if (FileSystem.exists('$path.zip')) - return loadLibraryFromZip('$path'.toLowerCase(), '$path.zip', force); + return loadLibraryFromZip('$path'.toLowerCase(), '$path.zip', force, modName); else - return loadLibraryFromFolder('$path'.toLowerCase(), '$path', force); + return loadLibraryFromFolder('$path'.toLowerCase(), '$path', force, modName); #else return null; @@ -111,12 +116,12 @@ class ModsFolder { } #if MOD_SUPPORT - public static function loadLibraryFromFolder(libName:String, folder:String, force:Bool = false) { - return prepareModLibrary(libName, new ModsFolderLibrary(folder, libName), force); + public static function loadLibraryFromFolder(libName:String, folder:String, force:Bool = false, ?modName:String) { + return prepareModLibrary(libName, new ModsFolderLibrary(folder, libName, modName), force); } - public static function loadLibraryFromZip(libName:String, zipPath:String, force:Bool = false) { - return prepareModLibrary(libName, new ZipFolderLibrary(zipPath, libName), force); + public static function loadLibraryFromZip(libName:String, zipPath:String, force:Bool = false, ?modName:String) { + return prepareModLibrary(libName, new ZipFolderLibrary(zipPath, libName, modName), force); } #end } \ No newline at end of file diff --git a/source/funkin/backend/assets/ModsFolderLibrary.hx b/source/funkin/backend/assets/ModsFolderLibrary.hx index 69f87693..ed608bda 100644 --- a/source/funkin/backend/assets/ModsFolderLibrary.hx +++ b/source/funkin/backend/assets/ModsFolderLibrary.hx @@ -17,14 +17,19 @@ using StringTools; class ModsFolderLibrary extends AssetLibrary implements IModsAssetLibrary { public var folderPath:String; + public var modName:String; public var libName:String; public var useImageCache:Bool = true; public var prefix = 'assets/'; - public function new(folderPath:String, libName:String) { + public function new(folderPath:String, libName:String, ?modName:String) { this.folderPath = folderPath; this.libName = libName; this.prefix = 'assets/$libName/'; + if(modName == null) + this.modName = libName; + else + this.modName = modName; super(); } @@ -133,6 +138,15 @@ class ModsFolderLibrary extends AssetLibrary implements IModsAssetLibrary { private function __parseAsset(asset:String):Bool { if (!asset.startsWith(prefix)) return false; _parsedAsset = asset.substr(prefix.length); + if(ModsFolder.useLibFile) { + var file = new haxe.io.Path(_parsedAsset); + if(file.file.startsWith("LIB_")) { + var library = file.file.substr(4); + if(library != modName) return false; + + _parsedAsset = file.dir + "." + file.ext; + } + } return true; } #end diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx index 7f847670..495d5577 100644 --- a/source/funkin/backend/assets/Paths.hx +++ b/source/funkin/backend/assets/Paths.hx @@ -164,7 +164,7 @@ class Paths inline static public function getPackerAtlasAlt(key:String) return FlxAtlasFrames.fromSpriteSheetPacker('$key.png', '$key.txt'); - inline static public function getAssetsRoot():String + inline static public function getAssetsRoot():String return ModsFolder.currentModFolder != null ? '${ModsFolder.modsPath}${ModsFolder.currentModFolder}' : './assets'; /** diff --git a/source/funkin/backend/assets/ScriptedAssetLibrary.hx b/source/funkin/backend/assets/ScriptedAssetLibrary.hx index 972f74e2..0b72a426 100644 --- a/source/funkin/backend/assets/ScriptedAssetLibrary.hx +++ b/source/funkin/backend/assets/ScriptedAssetLibrary.hx @@ -21,8 +21,8 @@ class ScriptedAssetLibrary extends ModsFolderLibrary { public var scriptName:String; private static var nullValue:Dynamic = {}; - public function new(scriptName:String, args:Array = null, folderPath:String="./assets/", libName:String="assets") { - super(folderPath, libName); + public function new(scriptName:String, args:Array = null, folderPath:String="./assets/", libName:String="assets", ?modName:String) { + super(folderPath, libName, modName); this.scriptName = scriptName; script = Script.create(Paths.script("data/library/" + scriptName)); @@ -107,6 +107,14 @@ class ScriptedAssetLibrary extends ModsFolderLibrary { return super.getAssetPath(); } + public override function list(type:String) { + var result:Dynamic = script.call("list", [type]); + if(result != null) { + return result == nullValue ? null : result; + } + return super.list(type); + } + private override function __isCacheValid(cache:Map, asset:String, isLocalCache:Bool = false) { var result:Dynamic = script.call("__isCacheValid", [cache, asset, isLocalCache]); if(result != null) { diff --git a/source/funkin/backend/assets/ZipFolderLibrary.hx b/source/funkin/backend/assets/ZipFolderLibrary.hx index 7465482e..21e425d8 100644 --- a/source/funkin/backend/assets/ZipFolderLibrary.hx +++ b/source/funkin/backend/assets/ZipFolderLibrary.hx @@ -27,6 +27,7 @@ import funkin.backend.utils.SysZip.SysZipEntry; class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary { public var zipPath:String; + public var modName:String; public var libName:String; public var useImageCache:Bool = false; public var prefix = 'assets/'; @@ -34,10 +35,15 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary { public var zip:SysZip; public var assets:Map = []; - public function new(zipPath:String, libName:String) { + public function new(zipPath:String, libName:String, ?modName:String) { this.zipPath = zipPath; this.libName = libName; + if(modName == null) + this.modName = libName; + else + this.modName = modName; + zip = SysZip.openFromFile(zipPath); zip.read(); for(entry in zip.entries) @@ -77,7 +83,18 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary { public function __parseAsset(asset:String):Bool { if (!asset.startsWith(prefix)) return false; - _parsedAsset = asset.substr(prefix.length).toLowerCase(); + _parsedAsset = asset.substr(prefix.length); + if(ModsFolder.useLibFile) { + var file = new haxe.io.Path(_parsedAsset); + if(file.file.startsWith("LIB_")) { + var library = file.file.substr(4); + if(library != modName) return false; + + _parsedAsset = file.dir + "." + file.ext; + } + } + + _parsedAsset = _parsedAsset.toLowerCase(); return true; } diff --git a/source/funkin/backend/system/CommandLineHandler.hx b/source/funkin/backend/system/CommandLineHandler.hx index d00af9a5..9be7928c 100644 --- a/source/funkin/backend/system/CommandLineHandler.hx +++ b/source/funkin/backend/system/CommandLineHandler.hx @@ -11,13 +11,14 @@ class CommandLineHandler { break; case "-h" | "-help" | "help": Sys.println("-- Codename Engine Command Line help --"); - Sys.println("-help | Show this help"); + Sys.println("-help | Show this help"); #if MOD_SUPPORT - Sys.println("-mod [mod name] | Load a specific mod"); - Sys.println("-modfolder [path] | Sets the mod folder path"); + Sys.println("-mod [mod name] | Load a specific mod"); + Sys.println("-modfolder [path] | Sets the mod folder path"); + Sys.println("-addonsfolder [path] | Sets the addons folder path"); #end - Sys.println("-nocolor | Disables colors in the terminal"); - Sys.println("-nogpubitmap | Forces GPU only bitmaps off"); + Sys.println("-nocolor | Disables colors in the terminal"); + Sys.println("-nogpubitmap | Forces GPU only bitmaps off"); Sys.exit(0); #if MOD_SUPPORT case "-m" | "-mod" | "-currentmod": @@ -41,6 +42,18 @@ class CommandLineHandler { Sys.println('[ERROR] Mod folder at "${arg}" does not exist.'); Sys.exit(0); } + case "-addonsfolder": + i++; + var arg = cmd[i]; + if (arg == null) { + Sys.println("[ERROR] You need to specify the addon folder path"); + Sys.exit(0); + } else if (FileSystem.exists(arg)) { + funkin.backend.assets.ModsFolder.addonsPath = arg; + } else { + Sys.println('[ERROR] Addons folder at "${arg}" does not exist.'); + Sys.exit(0); + } #end case "-nocolor": Main.noTerminalColor = true; diff --git a/source/funkin/backend/system/Main.hx b/source/funkin/backend/system/Main.hx index 088c8619..79ef9adc 100644 --- a/source/funkin/backend/system/Main.hx +++ b/source/funkin/backend/system/Main.hx @@ -136,6 +136,7 @@ class Main extends Sprite trace("Used cne test / cne build. Switching into source assets."); #if MOD_SUPPORT ModsFolder.modsPath = './${pathBack}mods/'; + ModsFolder.addonsPath = './${pathBack}addons/'; #end Paths.assetsTree.__defaultLibraries.push(ModsFolder.loadLibraryFromFolder('assets', './${pathBack}assets/', true)); #elseif USE_ADAPTED_ASSETS diff --git a/source/funkin/backend/system/MainState.hx b/source/funkin/backend/system/MainState.hx index ba67513d..f2284350 100644 --- a/source/funkin/backend/system/MainState.hx +++ b/source/funkin/backend/system/MainState.hx @@ -33,11 +33,11 @@ class MainState extends FlxState { #if MOD_SUPPORT if (ModsFolder.currentModFolder != null) - Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.modsPath}${ModsFolder.currentModFolder}')); + Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.modsPath}${ModsFolder.currentModFolder}', ModsFolder.currentModFolder)); if (FileSystem.exists(ModsFolder.addonsPath) && FileSystem.isDirectory(ModsFolder.addonsPath)) for(addon in [for(dir in FileSystem.readDirectory(ModsFolder.addonsPath)) if (FileSystem.isDirectory('${ModsFolder.addonsPath}$dir')) dir]) - Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.addonsPath}$addon')); + Paths.assetsTree.addLibrary(ModsFolder.loadModLib('${ModsFolder.addonsPath}$addon', addon)); #end Main.refreshAssets(); diff --git a/source/funkin/backend/system/framerate/AssetTreeInfo.hx b/source/funkin/backend/system/framerate/AssetTreeInfo.hx index 3f8c0388..b886abb4 100644 --- a/source/funkin/backend/system/framerate/AssetTreeInfo.hx +++ b/source/funkin/backend/system/framerate/AssetTreeInfo.hx @@ -22,9 +22,9 @@ class AssetTreeInfo extends FramerateCategory { } if (l is ScriptedAssetLibrary) - text += '${Type.getClassName(Type.getClass(l))} - ${cast(l, ScriptedAssetLibrary).scriptName} (${cast(l, ScriptedAssetLibrary).libName} | ${cast(l, ScriptedAssetLibrary).prefix})\n'; + text += '${Type.getClassName(Type.getClass(l))} - ${cast(l, ScriptedAssetLibrary).scriptName} (${cast(l, ScriptedAssetLibrary).modName} | ${cast(l, ScriptedAssetLibrary).libName} | ${cast(l, ScriptedAssetLibrary).prefix})\n'; else if (l is IModsAssetLibrary) - text += '${Type.getClassName(Type.getClass(l))} - ${cast(l, IModsAssetLibrary).libName} (${cast(l, IModsAssetLibrary).prefix})\n'; + text += '${Type.getClassName(Type.getClass(l))} - ${cast(l, IModsAssetLibrary).modName} - ${cast(l, IModsAssetLibrary).libName} (${cast(l, IModsAssetLibrary).prefix})\n'; else text += Std.string(e) + "\n"; } From b6e8202c3c04d311c780ee7beb3a970b261835df Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Fri, 13 Oct 2023 02:00:34 +0200 Subject: [PATCH 62/72] Small utility function + Fixes --- .../backend/system/CommandLineHandler.hx | 10 ++++---- .../backend/system/GraphicCacheSprite.hx | 23 ++++++++++++------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/source/funkin/backend/system/CommandLineHandler.hx b/source/funkin/backend/system/CommandLineHandler.hx index 9be7928c..4050b049 100644 --- a/source/funkin/backend/system/CommandLineHandler.hx +++ b/source/funkin/backend/system/CommandLineHandler.hx @@ -26,7 +26,7 @@ class CommandLineHandler { var arg = cmd[i]; if (arg == null) { Sys.println("[ERROR] You need to specify the mod name"); - Sys.exit(0); + Sys.exit(1); } else { Main.modToLoad = arg.trim(); } @@ -35,24 +35,24 @@ class CommandLineHandler { var arg = cmd[i]; if (arg == null) { Sys.println("[ERROR] You need to specify the mod folder path"); - Sys.exit(0); + Sys.exit(1); } else if (FileSystem.exists(arg)) { funkin.backend.assets.ModsFolder.modsPath = arg; } else { Sys.println('[ERROR] Mod folder at "${arg}" does not exist.'); - Sys.exit(0); + Sys.exit(1); } case "-addonsfolder": i++; var arg = cmd[i]; if (arg == null) { Sys.println("[ERROR] You need to specify the addon folder path"); - Sys.exit(0); + Sys.exit(1); } else if (FileSystem.exists(arg)) { funkin.backend.assets.ModsFolder.addonsPath = arg; } else { Sys.println('[ERROR] Addons folder at "${arg}" does not exist.'); - Sys.exit(0); + Sys.exit(1); } #end case "-nocolor": diff --git a/source/funkin/backend/system/GraphicCacheSprite.hx b/source/funkin/backend/system/GraphicCacheSprite.hx index 4f0fe98f..fd03bdc4 100644 --- a/source/funkin/backend/system/GraphicCacheSprite.hx +++ b/source/funkin/backend/system/GraphicCacheSprite.hx @@ -25,14 +25,21 @@ class GraphicCacheSprite extends FlxSprite { * @param path Path to the graphic. */ public function cache(path:String) { - var graphic = FlxG.bitmap.add(path); - if (graphic != null) { - // make their useCount one time higher to prevent them from auto being cleared from cache - graphic.useCount++; - graphic.destroyOnNoUse = false; - cachedGraphics.push(graphic); - nonRenderedCachedGraphics.push(graphic); - } + cacheGraphic(FlxG.bitmap.add(path)); + } + + /** + * Caches a graphic. + * @param graphic The FlxGraphic + */ + public function cacheGraphic(graphic:FlxGraphic) { + if (graphic == null) return; + + // make their useCount one time higher to prevent them from auto being cleared from cache + graphic.useCount++; + graphic.destroyOnNoUse = false; + cachedGraphics.push(graphic); + nonRenderedCachedGraphics.push(graphic); } public override function destroy() { From 19837f0143ba77e5ab4b31d9d7351acd986af049 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:29:10 +0300 Subject: [PATCH 63/72] made MusicBeatTransition more scriptable --- source/funkin/backend/MusicBeatTransition.hx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/funkin/backend/MusicBeatTransition.hx b/source/funkin/backend/MusicBeatTransition.hx index c49f88a8..6313c10b 100644 --- a/source/funkin/backend/MusicBeatTransition.hx +++ b/source/funkin/backend/MusicBeatTransition.hx @@ -11,14 +11,14 @@ class MusicBeatTransition extends MusicBeatSubstate { public var transitionCamera:FlxCamera; public var newState:FlxState; + public var blackSpr:FlxSprite; + public var transitionSprite:FunkinSprite; public function new(?newState:FlxState) { super(); this.newState = newState; } public override function create() { - super.create(); - if (newState != null) add(new FunkinParentDisabler(true)); @@ -29,13 +29,13 @@ class MusicBeatTransition extends MusicBeatSubstate { cameras = [transitionCamera]; var out = newState != null; - var blackSpr = new FlxSprite(0, out ? -transitionCamera.height : transitionCamera.height).makeGraphic(1, 1, -1); + blackSpr = new FlxSprite(0, out ? -transitionCamera.height : transitionCamera.height).makeGraphic(1, 1, -1); blackSpr.scale.set(transitionCamera.width, transitionCamera.height); blackSpr.color = 0xFF000000; blackSpr.updateHitbox(); add(blackSpr); - var transitionSprite = new FunkinSprite(); + transitionSprite = new FunkinSprite(); transitionSprite.loadSprite(Paths.image('menus/transitionSpr')); if (transitionSprite.animateAtlas == null) { transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height); @@ -53,6 +53,8 @@ class MusicBeatTransition extends MusicBeatSubstate { finish(); } }); + + super.create(); } public override function update(elapsed:Float) { From 8b1a40e5528fa574a6b0c0f4fb6af8e05a738548 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Fri, 13 Oct 2023 15:32:40 +0300 Subject: [PATCH 64/72] titlescreen now runs postCreate after startIntro --- source/funkin/menus/TitleState.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/menus/TitleState.hx b/source/funkin/menus/TitleState.hx index d46e04b9..da7e25f8 100644 --- a/source/funkin/menus/TitleState.hx +++ b/source/funkin/menus/TitleState.hx @@ -48,9 +48,9 @@ class TitleState extends MusicBeatState MusicBeatState.skipTransIn = true; - super.create(); - startIntro(); + + super.create(); } var logoBl:FlxSprite; From 0844ea44813456760fdd4a04cb7f8bf440f2e7b9 Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Fri, 13 Oct 2023 15:10:23 +0200 Subject: [PATCH 65/72] Fix graphic destroying (EXPERIMENTAL) --- project.xml | 2 ++ source/funkin/game/PlayState.hx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/project.xml b/project.xml index 6155a799..5e4aaa8a 100644 --- a/project.xml +++ b/project.xml @@ -169,6 +169,8 @@ + + diff --git a/source/funkin/game/PlayState.hx b/source/funkin/game/PlayState.hx index ac0d77d4..634e0581 100644 --- a/source/funkin/game/PlayState.hx +++ b/source/funkin/game/PlayState.hx @@ -1527,7 +1527,7 @@ class PlayState extends MusicBeatState rating.velocity.y -= FlxG.random.int(140, 175); rating.velocity.x -= FlxG.random.int(0, 10); if (evt != null) { - rating.scale.set(evt.ratingScale,evt.ratingScale); + rating.scale.set(evt.ratingScale, evt.ratingScale); rating.antialiasing = evt.ratingAntialiasing; } rating.updateHitbox(); @@ -1543,7 +1543,7 @@ class PlayState extends MusicBeatState public function displayCombo(?evt:NoteHitEvent = null):Void { var pre:String = evt != null ? evt.ratingPrefix : ""; var suf:String = evt != null ? evt.ratingSuffix : ""; - + var separatedScore:String = Std.string(combo).addZeros(3); if (combo == 0 || combo >= 10) { From db153070fdfc891640dac46211c10a691cbc0a8a Mon Sep 17 00:00:00 2001 From: MAZ12211 Date: Fri, 13 Oct 2023 18:55:01 +0300 Subject: [PATCH 66/72] Fix startDialogue for scripted cutscenes (#209) --- source/funkin/game/cutscenes/ScriptedCutscene.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/game/cutscenes/ScriptedCutscene.hx b/source/funkin/game/cutscenes/ScriptedCutscene.hx index 65d48958..b17639eb 100644 --- a/source/funkin/game/cutscenes/ScriptedCutscene.hx +++ b/source/funkin/game/cutscenes/ScriptedCutscene.hx @@ -72,7 +72,7 @@ class ScriptedCutscene extends Cutscene { #if REGION public function startDialogue(path:String, ?callback:Void->Void) { persistentDraw = true; - openSubState(new VideoCutscene(path, function() { + openSubState(new DialogueCutscene(path, function() { if (callback != null) callback(); })); @@ -83,4 +83,4 @@ class ScriptedCutscene extends Cutscene { private inline function get_isDialoguePlaying() return subState is DialogueCutscene; #end -} \ No newline at end of file +} From 9992490d14d363bbd9911a6deb6c3e4ed026f95a Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Fri, 13 Oct 2023 20:57:46 +0300 Subject: [PATCH 67/72] [BREAKING i think] state scriptpacks --- source/funkin/backend/MusicBeatState.hx | 35 ++++++++++--------- source/funkin/backend/MusicBeatSubstate.hx | 35 ++++++++++--------- source/funkin/backend/assets/ModsFolder.hx | 16 +++++++++ .../backend/assets/ScriptedAssetLibrary.hx | 2 +- .../funkin/backend/scripting/GlobalScript.hx | 30 ++++++++-------- 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/source/funkin/backend/MusicBeatState.hx b/source/funkin/backend/MusicBeatState.hx index eca0c466..b0a9980e 100644 --- a/source/funkin/backend/MusicBeatState.hx +++ b/source/funkin/backend/MusicBeatState.hx @@ -9,6 +9,7 @@ import flixel.FlxState; import flixel.FlxSubState; import funkin.backend.scripting.events.*; import funkin.backend.scripting.Script; +import funkin.backend.scripting.ScriptPack; import funkin.backend.system.interfaces.IBeatReceiver; import funkin.backend.system.Conductor; import funkin.options.PlayerSettings; @@ -89,7 +90,7 @@ class MusicBeatState extends FlxState implements IBeatReceiver /** * Current injected script attached to the state. To add one, create a file at path "data/states/stateName" (ex: data/states/FreeplayState) */ - public var stateScript:Script; + public var stateScripts:ScriptPack; public var scriptsAllowed:Bool = true; @@ -113,14 +114,21 @@ class MusicBeatState extends FlxState implements IBeatReceiver function loadScript() { if (scriptsAllowed) { - if (stateScript == null || stateScript is DummyScript) { - var className = Type.getClassName(Type.getClass(this)); + var className = Type.getClassName(Type.getClass(this)); + if (stateScripts == null) + (stateScripts = new ScriptPack(className)).setParent(this); + if (stateScripts.scripts.length == 0) { var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1); - stateScript = Script.create(Paths.script('data/states/${scriptName}')); - stateScript.setParent(this); - stateScript.load(); - } else - stateScript.reload(); + for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { + var path = Paths.script('data/states/${scriptName}/LIB_$i'); + var script = Script.create(path); + if (script is DummyScript) continue; + script.fileName = '$i:$scriptName'; + stateScripts.add(script); + script.load(); + } + } + else stateScripts.reload(); } } @@ -161,13 +169,11 @@ class MusicBeatState extends FlxState implements IBeatReceiver } public function call(name:String, ?args:Array, ?defaultVal:Dynamic):Dynamic { // calls the function on the assigned script - if (stateScript == null) return defaultVal; - return stateScript.call(name, args); + return stateScripts.call(name, args); } public function event(name:String, event:T):T { - if (stateScript == null) return event; - stateScript.call(name, [event]); + stateScripts.call(name, [event]); return event; } @@ -176,8 +182,6 @@ class MusicBeatState extends FlxState implements IBeatReceiver // TODO: DEBUG MODE!! if (FlxG.keys.justPressed.F5) { loadScript(); - if (stateScript != null && !(stateScript is DummyScript)) - Logs.trace('State script successfully reloaded', WARNING, GREEN); } call("update", [elapsed]); @@ -234,8 +238,7 @@ class MusicBeatState extends FlxState implements IBeatReceiver super.destroy(); graphicCache.destroy(); call("onDestroy"); - if (stateScript != null) - stateScript.destroy(); + stateScripts = FlxDestroyUtil.destroy(stateScripts); } public override function draw() { diff --git a/source/funkin/backend/MusicBeatSubstate.hx b/source/funkin/backend/MusicBeatSubstate.hx index d1d96f43..b7987f7d 100644 --- a/source/funkin/backend/MusicBeatSubstate.hx +++ b/source/funkin/backend/MusicBeatSubstate.hx @@ -3,6 +3,7 @@ package funkin.backend; import flixel.FlxState; import funkin.backend.scripting.events.*; import funkin.backend.scripting.Script; +import funkin.backend.scripting.ScriptPack; import funkin.backend.scripting.DummyScript; import funkin.backend.system.interfaces.IBeatReceiver; import funkin.backend.system.Conductor.BPMChangeEvent; @@ -63,7 +64,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver /** * Current injected script attached to the state. To add one, create a file at path "data/states/stateName" (ex: "data/states/PauseMenuSubstate.hx") */ - public var stateScript:Script; + public var stateScripts:ScriptPack; public var scriptsAllowed:Bool = true; @@ -100,14 +101,21 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver function loadScript() { if (scriptsAllowed) { - if (stateScript == null || stateScript is DummyScript) { - var className = Type.getClassName(Type.getClass(this)); + var className = Type.getClassName(Type.getClass(this)); + if (stateScripts == null) + (stateScripts = new ScriptPack(className)).setParent(this); + if (stateScripts.scripts.length == 0) { var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1); - stateScript = Script.create(Paths.script('data/states/${scriptName}')); - stateScript.setParent(this); - stateScript.load(); - } else - stateScript.reload(); + for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { + var path = Paths.script('data/states/${scriptName}/LIB_$i'); + var script = Script.create(path); + if (script is DummyScript) continue; + script.fileName = '$i:$scriptName'; + stateScripts.add(script); + script.load(); + } + } + else stateScripts.reload(); } } @@ -151,13 +159,11 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver } public function call(name:String, ?args:Array, ?defaultVal:Dynamic):Dynamic { // calls the function on the assigned script - if (stateScript == null) return defaultVal; - return stateScript.call(name, args); + return stateScripts.call(name, args); } public function event(name:String, event:T):T { - if (stateScript == null) return event; - stateScript.call(name, [event]); + stateScripts.call(name, [event]); return event; } @@ -166,8 +172,6 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver // TODO: DEBUG MODE!! if (FlxG.keys.justPressed.F5) { loadScript(); - if (stateScript != null && !(stateScript is DummyScript)) - Logs.trace('State script successfully reloaded', WARNING, GREEN); } call("update", [elapsed]); super.update(elapsed); @@ -222,8 +226,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver public override function destroy() { super.destroy(); call("onDestroy"); - if(stateScript != null) - stateScript.destroy(); + stateScripts = FlxDestroyUtil.destroy(stateScripts); } public override function switchTo(nextState:FlxState) { diff --git a/source/funkin/backend/assets/ModsFolder.hx b/source/funkin/backend/assets/ModsFolder.hx index fc37ed52..a88377ad 100644 --- a/source/funkin/backend/assets/ModsFolder.hx +++ b/source/funkin/backend/assets/ModsFolder.hx @@ -89,6 +89,22 @@ class ModsFolder { #end } + public static function getLoadedMods():Array { + var libs = []; + for (i in Paths.assetsTree.libraries) { + var l = i; + if (l is openfl.utils.AssetLibrary) { + var al = cast(l, openfl.utils.AssetLibrary); + @:privateAccess + if (al.__proxy != null) l = al.__proxy; + } + var libString:String; + if (l is ScriptedAssetLibrary || l is IModsAssetLibrary) libString = cast(l, IModsAssetLibrary).modName; + else continue; + libs.push(libString); + } + return libs; + } public static function prepareLibrary(libName:String, force:Bool = false) { var assets:AssetManifest = new AssetManifest(); assets.name = libName; diff --git a/source/funkin/backend/assets/ScriptedAssetLibrary.hx b/source/funkin/backend/assets/ScriptedAssetLibrary.hx index 0b72a426..a5087be3 100644 --- a/source/funkin/backend/assets/ScriptedAssetLibrary.hx +++ b/source/funkin/backend/assets/ScriptedAssetLibrary.hx @@ -23,7 +23,7 @@ class ScriptedAssetLibrary extends ModsFolderLibrary { public function new(scriptName:String, args:Array = null, folderPath:String="./assets/", libName:String="assets", ?modName:String) { super(folderPath, libName, modName); - + if(modName == null) modName = scriptName; this.scriptName = scriptName; script = Script.create(Paths.script("data/library/" + scriptName)); script.setParent(this); diff --git a/source/funkin/backend/scripting/GlobalScript.hx b/source/funkin/backend/scripting/GlobalScript.hx index d6d10000..dbca645c 100644 --- a/source/funkin/backend/scripting/GlobalScript.hx +++ b/source/funkin/backend/scripting/GlobalScript.hx @@ -9,7 +9,7 @@ import funkin.backend.assets.ModsFolder; * Class for THE Global Script, aka script that runs in the background at all times. */ class GlobalScript { - public static var script:Script; + public static var scripts:ScriptPack; public static function init() { #if MOD_SUPPORT @@ -43,17 +43,13 @@ class GlobalScript { FlxG.signals.postUpdate.add(function() { call("postUpdate", [FlxG.elapsed]); if (FlxG.keys.justPressed.F5) { - if (script != null && !(script is DummyScript)) { + if (scripts.scripts.length > 0) { Logs.trace('Reloading global script...', WARNING, YELLOW); - script.reload(); + scripts.reload(); Logs.trace('Global script successfully reloaded.', WARNING, GREEN); } else { Logs.trace('Loading global script...', WARNING, YELLOW); onModSwitch(#if MOD_SUPPORT ModsFolder.currentModFolder #else null #end); - if (script is DummyScript) - Logs.trace('Global script not found. Are you sure "data/global.hx" exists?', ERROR, RED); - else - Logs.trace('Global script successfully loaded.', WARNING, GREEN); } } if (FlxG.keys.justPressed.F2) @@ -83,23 +79,25 @@ class GlobalScript { } public static function event(name:String, event:T):T { - if (script == null) return event; - script.call(name, [event]); + if (scripts != null) scripts.call(name, [event]); return event; } public static function call(name:String, ?args:Array) { - if (script == null) return; - script.call(name, args); + if (scripts != null) scripts.call(name, args); } public static function onModSwitch(newMod:String) { call("onDestroy"); - if (script != null) { - script.destroy(); - script = null; + scripts = FlxDestroyUtil.destroy(scripts); + scripts = new ScriptPack("GlobalScript"); + for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { + var path = Paths.script('data/global/LIB_$i'); + var script = Script.create(path); + if (script is DummyScript) continue; + script.fileName = '$i:global.hx'; + scripts.add(script); + script.load(); } - script = Script.create(Paths.script('data/global')); - script.load(); } public static function beatHit(curBeat:Int) { From 2d2099e37a804de0c75da5f727e82a87377f4163 Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Fri, 13 Oct 2023 21:01:28 +0300 Subject: [PATCH 68/72] oops --- source/funkin/backend/assets/ScriptedAssetLibrary.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/backend/assets/ScriptedAssetLibrary.hx b/source/funkin/backend/assets/ScriptedAssetLibrary.hx index a5087be3..0fd8d380 100644 --- a/source/funkin/backend/assets/ScriptedAssetLibrary.hx +++ b/source/funkin/backend/assets/ScriptedAssetLibrary.hx @@ -22,8 +22,8 @@ class ScriptedAssetLibrary extends ModsFolderLibrary { private static var nullValue:Dynamic = {}; public function new(scriptName:String, args:Array = null, folderPath:String="./assets/", libName:String="assets", ?modName:String) { - super(folderPath, libName, modName); if(modName == null) modName = scriptName; + super(folderPath, libName, modName); this.scriptName = scriptName; script = Script.create(Paths.script("data/library/" + scriptName)); script.setParent(this); From e49b0653e351f869d4b3b9a982b156bc6321573e Mon Sep 17 00:00:00 2001 From: Frakist <90983918+Frakist@users.noreply.github.com> Date: Sat, 14 Oct 2023 08:48:43 +0300 Subject: [PATCH 69/72] oops #2 --- source/funkin/backend/MusicBeatState.hx | 6 +++--- source/funkin/backend/MusicBeatSubstate.hx | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/funkin/backend/MusicBeatState.hx b/source/funkin/backend/MusicBeatState.hx index b0a9980e..88309c82 100644 --- a/source/funkin/backend/MusicBeatState.hx +++ b/source/funkin/backend/MusicBeatState.hx @@ -113,10 +113,10 @@ class MusicBeatState extends FlxState implements IBeatReceiver } function loadScript() { + var className = Type.getClassName(Type.getClass(this)); + if (stateScripts == null) + (stateScripts = new ScriptPack(className)).setParent(this); if (scriptsAllowed) { - var className = Type.getClassName(Type.getClass(this)); - if (stateScripts == null) - (stateScripts = new ScriptPack(className)).setParent(this); if (stateScripts.scripts.length == 0) { var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1); for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { diff --git a/source/funkin/backend/MusicBeatSubstate.hx b/source/funkin/backend/MusicBeatSubstate.hx index b7987f7d..5db43fce 100644 --- a/source/funkin/backend/MusicBeatSubstate.hx +++ b/source/funkin/backend/MusicBeatSubstate.hx @@ -100,10 +100,10 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver } function loadScript() { + var className = Type.getClassName(Type.getClass(this)); + if (stateScripts == null) + (stateScripts = new ScriptPack(className)).setParent(this); if (scriptsAllowed) { - var className = Type.getClassName(Type.getClass(this)); - if (stateScripts == null) - (stateScripts = new ScriptPack(className)).setParent(this); if (stateScripts.scripts.length == 0) { var scriptName = this.scriptName != null ? this.scriptName : className.substr(className.lastIndexOf(".")+1); for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { From 7f06b6504df2f6d50838d2210195cfdf7301dc0b Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Sat, 14 Oct 2023 13:06:09 +0200 Subject: [PATCH 70/72] Fix crash --- source/funkin/backend/MusicBeatState.hx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/funkin/backend/MusicBeatState.hx b/source/funkin/backend/MusicBeatState.hx index 88309c82..791007f4 100644 --- a/source/funkin/backend/MusicBeatState.hx +++ b/source/funkin/backend/MusicBeatState.hx @@ -169,11 +169,15 @@ class MusicBeatState extends FlxState implements IBeatReceiver } public function call(name:String, ?args:Array, ?defaultVal:Dynamic):Dynamic { // calls the function on the assigned script - return stateScripts.call(name, args); + if(stateScripts != null) + return stateScripts.call(name, args); + else + return null; } public function event(name:String, event:T):T { - stateScripts.call(name, [event]); + if(stateScripts != null) + stateScripts.call(name, [event]); return event; } From 7ec91e908c721ed198bb8568d5757ff8de43a33f Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Sat, 14 Oct 2023 14:34:26 +0200 Subject: [PATCH 71/72] heck --- source/funkin/backend/MusicBeatState.hx | 3 +-- source/funkin/backend/MusicBeatSubstate.hx | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/funkin/backend/MusicBeatState.hx b/source/funkin/backend/MusicBeatState.hx index 791007f4..fc89b4d5 100644 --- a/source/funkin/backend/MusicBeatState.hx +++ b/source/funkin/backend/MusicBeatState.hx @@ -171,8 +171,7 @@ class MusicBeatState extends FlxState implements IBeatReceiver // calls the function on the assigned script if(stateScripts != null) return stateScripts.call(name, args); - else - return null; + return null; } public function event(name:String, event:T):T { diff --git a/source/funkin/backend/MusicBeatSubstate.hx b/source/funkin/backend/MusicBeatSubstate.hx index 5db43fce..3d1ad3fc 100644 --- a/source/funkin/backend/MusicBeatSubstate.hx +++ b/source/funkin/backend/MusicBeatSubstate.hx @@ -159,11 +159,14 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver } public function call(name:String, ?args:Array, ?defaultVal:Dynamic):Dynamic { // calls the function on the assigned script - return stateScripts.call(name, args); + if(stateScripts != null) + return stateScripts.call(name, args); + return null; } public function event(name:String, event:T):T { - stateScripts.call(name, [event]); + if(stateScripts != null) + stateScripts.call(name, [event]); return event; } From 150ae69d572b46c88d04370aeb92d228ce482f67 Mon Sep 17 00:00:00 2001 From: NeeEoo Date: Sat, 14 Oct 2023 14:36:05 +0200 Subject: [PATCH 72/72] Oops --- source/funkin/backend/MusicBeatState.hx | 2 +- source/funkin/backend/MusicBeatSubstate.hx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/backend/MusicBeatState.hx b/source/funkin/backend/MusicBeatState.hx index fc89b4d5..1b5499de 100644 --- a/source/funkin/backend/MusicBeatState.hx +++ b/source/funkin/backend/MusicBeatState.hx @@ -171,7 +171,7 @@ class MusicBeatState extends FlxState implements IBeatReceiver // calls the function on the assigned script if(stateScripts != null) return stateScripts.call(name, args); - return null; + return defaultVal; } public function event(name:String, event:T):T { diff --git a/source/funkin/backend/MusicBeatSubstate.hx b/source/funkin/backend/MusicBeatSubstate.hx index 3d1ad3fc..4b4315ca 100644 --- a/source/funkin/backend/MusicBeatSubstate.hx +++ b/source/funkin/backend/MusicBeatSubstate.hx @@ -161,7 +161,7 @@ class MusicBeatSubstate extends FlxSubState implements IBeatReceiver // calls the function on the assigned script if(stateScripts != null) return stateScripts.call(name, args); - return null; + return defaultVal; } public function event(name:String, event:T):T {