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] 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;