diff --git a/assets b/assets index 4a3483439a..d6833c55a7 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4a3483439a55c4387c18d7d67b9784a2bd71d3ba +Subproject commit d6833c55a73157066fab19c801649da3494c786b diff --git a/source/funkin/ui/debug/char/CharCreatorState.hx b/source/funkin/ui/debug/char/CharCreatorState.hx index 1be7c510cb..aaffac24ef 100644 --- a/source/funkin/ui/debug/char/CharCreatorState.hx +++ b/source/funkin/ui/debug/char/CharCreatorState.hx @@ -109,7 +109,10 @@ class CharCreatorState extends UIState menubarItemExit.onClick = _ -> exitEditor(); menubarItemAbout.onClick = _ -> new CharCreatorAboutDialog().showDialog(); - menubarSliderAnimSpeed.onChange = function(_) menubarLabelAnimSpeed.text = 'Animation Speed: ${menubarSliderAnimSpeed.pos}%'; + menubarSliderAnimSpeed.onChange = function(_) { + FlxG.animationTimeScale = (menubarSliderAnimSpeed.pos / 100); + menubarLabelAnimSpeed.text = 'Animation Speed: ${menubarSliderAnimSpeed.pos}%'; + } } function handleShortcuts():Void @@ -146,7 +149,7 @@ class CharCreatorState extends UIState menubarOptionCharSelect.disabled = menubarOptionFreeplay.disabled = menubarOptionResults.disabled = !params.generatePlayerData; menubarOptionGameplay.selected = (params.generateCharacter); - menubarOptionCharSelect.selected = !menubarOptionGameplay.selected; + menubarOptionCharSelect.selected = !(params.generateCharacter); menubarOptionFreeplay.selected = menubarOptionResults.selected = false; switchToPage(params.generateCharacter ? Gameplay : CharacterSelect); @@ -154,6 +157,7 @@ class CharCreatorState extends UIState function exitEditor():Void { + menubarSliderAnimSpeed.pos = 100; Cursor.hide(); FlxG.switchState(() -> new DebugMenuSubState()); FunkinSound.playMusic('freakyMenu', diff --git a/source/funkin/ui/debug/char/animate/CharSelectAtlasSprite.hx b/source/funkin/ui/debug/char/animate/CharSelectAtlasSprite.hx index a9fb001e2c..5f5d545c1e 100644 --- a/source/funkin/ui/debug/char/animate/CharSelectAtlasSprite.hx +++ b/source/funkin/ui/debug/char/animate/CharSelectAtlasSprite.hx @@ -81,13 +81,10 @@ class CharSelectAtlasSprite extends FlxAnimate initSymbols(); } - var symbolsInitialized:Bool = false; - public function initSymbols() { - if (symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; - symbolsInitialized = true; onAnimationComplete.add(cleanupAnimation); // This defaults the sprite to play the first animation in the atlas, @@ -104,7 +101,7 @@ class CharSelectAtlasSprite extends FlxAnimate */ public function listAnimations():Array { - if (!symbolsInitialized) return []; + if (this.frames == null || this.anim == null) return []; var mainSymbol = this.anim.symbolDictionary[this.anim.stageInstance.symbol.name]; if (mainSymbol == null) @@ -121,7 +118,7 @@ class CharSelectAtlasSprite extends FlxAnimate */ public function hasAnimation(id:String):Bool { - if (!symbolsInitialized) return false; + if (this.frames == null || this.anim == null) return false; return getLabelIndex(id) != -1 || anim.symbolDictionary.exists(id); } @@ -130,7 +127,7 @@ class CharSelectAtlasSprite extends FlxAnimate */ public function getCurrentAnimation():String { - if (!symbolsInitialized) return ""; + if (this.frames == null || this.anim == null) return ""; return this.currentAnimation; } @@ -155,7 +152,7 @@ class CharSelectAtlasSprite extends FlxAnimate */ public function playAnimation(id:String, restart:Bool = false, ignoreOther:Bool = false, loop:Bool = false, startFrame:Int = 0):Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; // Skip if not allowed to play animations. if ((!canPlayOtherAnims)) @@ -255,7 +252,7 @@ class CharSelectAtlasSprite extends FlxAnimate */ public function isAnimationFinished():Bool { - if (!symbolsInitialized) return false; + if (this.frames == null || this.anim == null) return false; return this.anim.finished; } @@ -265,7 +262,7 @@ class CharSelectAtlasSprite extends FlxAnimate */ public function isLoopComplete():Bool { - if (!symbolsInitialized) return false; + if (this.frames == null || this.anim == null) return false; if (this.anim == null) return false; if (!this.anim.isPlaying) return false; @@ -279,7 +276,7 @@ class CharSelectAtlasSprite extends FlxAnimate */ public function stopAnimation():Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; if (this.currentAnimation == null) return; this.anim.removeAllCallbacksFrom(getNextFrameLabel(this.currentAnimation)); @@ -289,20 +286,20 @@ class CharSelectAtlasSprite extends FlxAnimate function addFrameCallback(label:String, callback:Void->Void):Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; var frameLabel = this.anim.getFrameLabel(label); frameLabel.add(callback); } function goToFrameLabel(label:String):Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; this.anim.goToFrameLabel(label); } function getFrameLabelNames(?layer:haxe.extern.EitherType = null) { - if (!symbolsInitialized) return []; + if (this.frames == null || this.anim == null) return []; var labels = this.anim.getFrameLabels(layer); var array = []; for (label in labels) @@ -315,25 +312,25 @@ class CharSelectAtlasSprite extends FlxAnimate function getNextFrameLabel(label:String):String { - if (!symbolsInitialized) return ""; + if (this.frames == null || this.anim == null) return ""; return listAnimations()[(getLabelIndex(label) + 1) % listAnimations().length]; } function getLabelIndex(label:String):Int { - if (!symbolsInitialized) return -1; + if (this.frames == null || this.anim == null) return -1; return listAnimations().indexOf(label); } function goToFrameIndex(index:Int):Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; this.anim.curFrame = index; } public function cleanupAnimation(_:String):Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; canPlayOtherAnims = true; // this.currentAnimation = null; @@ -342,7 +339,7 @@ class CharSelectAtlasSprite extends FlxAnimate function _onAnimationFrame(frame:Int):Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; if (currentAnimation != null) { @@ -368,7 +365,7 @@ class CharSelectAtlasSprite extends FlxAnimate function _onAnimationComplete():Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; if (currentAnimation != null) { @@ -384,7 +381,7 @@ class CharSelectAtlasSprite extends FlxAnimate public function replaceFrameGraphic(index:Int, ?graphic:FlxGraphicAsset):Void { - if (!symbolsInitialized) return; + if (this.frames == null || this.anim == null) return; if (graphic == null || !Assets.exists(graphic)) { @@ -424,7 +421,7 @@ class CharSelectAtlasSprite extends FlxAnimate public function getPivotPosition():Null { - if (!symbolsInitialized) return null; + if (this.frames == null || this.anim == null) return null; return anim?.curInstance?.symbol?.transformationPoint; } diff --git a/source/funkin/ui/debug/char/components/dialogs/gameplay/CharMetadataDialog.hx b/source/funkin/ui/debug/char/components/dialogs/gameplay/CharMetadataDialog.hx index 96221c6bb9..16293f7fba 100644 --- a/source/funkin/ui/debug/char/components/dialogs/gameplay/CharMetadataDialog.hx +++ b/source/funkin/ui/debug/char/components/dialogs/gameplay/CharMetadataDialog.hx @@ -17,6 +17,7 @@ class CharMetadataDialog extends DefaultPageDialog charIsPixel.selected = char.isPixel; charHasDeathData.selected = (char.deathData != null); charDeathBox.disabled = !charHasDeathData.selected; + charName.text = char.characterName; charDeathCamOffsetX.pos = char.deathData?.cameraOffsets[0] ?? 0; charDeathCamOffsetY.pos = char.deathData?.cameraOffsets[1] ?? 0; @@ -24,6 +25,8 @@ class CharMetadataDialog extends DefaultPageDialog charDeathTransDelay.pos = char.deathData?.preTransitionDelay ?? 0; // callbaccd + charName.onChange = function(_) char.characterName = charName.text; + charOffsetsX.onChange = charOffsetsY.onChange = function(_) { char.globalOffsets = [charOffsetsX.pos, charOffsetsY.pos]; daPage.updateCharPerStageData(char.characterType); diff --git a/source/funkin/ui/debug/char/components/dialogs/gameplay/HealthIconDialog.hx b/source/funkin/ui/debug/char/components/dialogs/gameplay/HealthIconDialog.hx index d0f9ae1e30..4134ef7252 100644 --- a/source/funkin/ui/debug/char/components/dialogs/gameplay/HealthIconDialog.hx +++ b/source/funkin/ui/debug/char/components/dialogs/gameplay/HealthIconDialog.hx @@ -16,17 +16,23 @@ class HealthIconDialog extends DefaultPageDialog { super(daPage); - if (char.healthIcon != null && char.healthIconFiles.length >= 1) // set the data considering we have all the stuff we need + if (char.healthIcon != null) // set the data considering we have all the stuff we need { healthIcon = new FlxSprite(); - var bitmap = openfl.display.BitmapData.fromBytes(char.healthIconFiles[0].bytes); - if (char.healthIconFiles.length == 1) // legacy + if (!Assets.exists(Paths.image('icons/icon-${char.healthIcon.id}'))) { - var iconSize = HealthIcon.HEALTH_ICON_SIZE; + return; + } + + var isRetro = !Assets.exists(Paths.file('images/icons/icon-${char.healthIcon.id}')); + healthIconLoadField.text = char.healthIcon.id; + if (isRetro) + { + var iconSize:Int = HealthIcon.HEALTH_ICON_SIZE; @:privateAccess if (char.healthIcon.isPixel) iconSize = HealthIcon.PIXEL_ICON_SIZE; - healthIcon.loadGraphic(bitmap, true, iconSize, iconSize); + healthIcon.loadGraphic(Paths.image('icons/icon-${char.healthIcon.id}'), true, iconSize, iconSize); healthIcon.animation.add("idle", [0], 0, false, false); healthIcon.animation.add("losing", [1], 0, false, false); if (healthIcon.animation.numFrames >= 3) @@ -36,9 +42,7 @@ class HealthIconDialog extends DefaultPageDialog } else { - healthIcon.frames = FlxAtlasFrames.fromSparrow(bitmap, char.healthIconFiles[1].bytes.toString()); - if (healthIcon.frames.frames.length == 0) return; - + healthIcon.frames = Paths.getSparrowAtlas('icons/icon-${char.healthIcon.id}'); healthIcon.animation.addByPrefix("idle", "idle", 24, true); healthIcon.animation.addByPrefix("winning", "winning", 24, true); healthIcon.animation.addByPrefix("losing", "losing", 24, true); @@ -46,8 +50,6 @@ class HealthIconDialog extends DefaultPageDialog healthIcon.animation.addByPrefix("toLosing", "toLosing", 24, false); healthIcon.animation.addByPrefix("fromWinning", "fromWinning", 24, false); healthIcon.animation.addByPrefix("fromLosing", "fromLosing", 24, false); - - if (healthIcon.animation.getNameList().length == 0) return; } // some cosmetic stuff @@ -71,12 +73,25 @@ class HealthIconDialog extends DefaultPageDialog } healthIconPreviewBtn.onClick = function(_) { - if (healthIconLoadField.text == null || !healthIconLoadField.text.endsWith(".png")) return; - if (CharCreatorUtil.gimmeTheBytes(healthIconLoadField.text) == null) return; + if (healthIconLoadField.text.length == 0) + { + return; + } + + if (haxe.io.Path.isAbsolute(healthIconLoadField.text) && haxe.io.Path.extension(healthIconLoadField.text) != "png") + { + return; + } + + var endPath = haxe.io.Path.isAbsolute(healthIconLoadField.text) ? healthIconLoadField.text : Paths.image("icons/icon-" + healthIconLoadField.text); + if (CharCreatorUtil.gimmeTheBytes(endPath) == null) + { + return; + } // getting bitmap - var imgBytes = CharCreatorUtil.gimmeTheBytes(healthIconLoadField.text); - var xmlBytes = CharCreatorUtil.gimmeTheBytes(healthIconLoadField.text.replace(".png", ".xml")); + var imgBytes = CharCreatorUtil.gimmeTheBytes(endPath); + var xmlBytes = CharCreatorUtil.gimmeTheBytes(endPath.replace(".png", ".xml")); var bitmap = openfl.display.BitmapData.fromBytes(imgBytes); if (bitmap == null) return; @@ -131,12 +146,12 @@ class HealthIconDialog extends DefaultPageDialog healthIcon.animation.play("idle"); char.healthIconFiles = [ - {name: healthIconLoadField.text, bytes: imgBytes}]; - if (xmlBytes != null) char.healthIconFiles.push({name: healthIconLoadField.text.replace(".png", ".xml"), bytes: xmlBytes}); + {name: endPath, bytes: imgBytes}]; + if (xmlBytes != null) char.healthIconFiles.push({name: endPath.replace(".png", ".xml"), bytes: xmlBytes}); char.healthIcon = { scale: healthIconScale.pos, - id: char.characterId, + id: haxe.io.Path.isAbsolute(endPath) ? char.characterId : healthIconLoadField.text, offsets: [healthIconOffsetX.pos, healthIconOffsetY.pos], flipX: healthIconFlipX.selected, isPixel: healthIconPixelated.selected diff --git a/source/funkin/ui/debug/char/components/dialogs/results/ResultsAnimDialog.hx b/source/funkin/ui/debug/char/components/dialogs/results/ResultsAnimDialog.hx index 5c69dba17a..d727e95b2f 100644 --- a/source/funkin/ui/debug/char/components/dialogs/results/ResultsAnimDialog.hx +++ b/source/funkin/ui/debug/char/components/dialogs/results/ResultsAnimDialog.hx @@ -22,6 +22,7 @@ class ResultsAnimDialog extends DefaultPageDialog public var currentRank(get, never):ScoringRank; public var rankAnimationDataMap:Map> = []; + public var rankAnimationFiles:Map>> = []; public var previousRank:ScoringRank; var rankAnimationBox:AddRankAnimationDataBox; @@ -36,6 +37,7 @@ class ResultsAnimDialog extends DefaultPageDialog { var playerAnimations = currentChar?.getResultsAnimationDatas(rank) ?? []; rankAnimationDataMap.set(rank, playerAnimations); + rankAnimationFiles.set(rank, [for (bs in playerAnimations) []]); } rankAnimationBox = new AddRankAnimationDataBox(this); @@ -119,6 +121,7 @@ private class AddRankAnimationDataBox extends HBox var newBox = createNewBox(); daDialog.rankAnimationDataMap[daDialog.previousRank].push(newBox.animData); + daDialog.rankAnimationFiles[daDialog.previousRank].push([]); parentList.addComponentAt(newBox, parentList.childComponents.length - 1); // considering this box is last removeButton.disabled = false; @@ -139,6 +142,7 @@ private class AddRankAnimationDataBox extends HBox daDataSprite.destroy(); daDialog.rankAnimationDataMap[daDialog.previousRank].pop(); + daDialog.rankAnimationFiles[daDialog.previousRank].pop(); if (parentList.childComponents.length < 2) removeButton.disabled = true; } @@ -280,6 +284,7 @@ private class AddRankAnimationDataBox extends HBox var isAbsolute:Bool = Path.isAbsolute(box.animData.assetPath); var newObj:Dynamic = null; + var wizFiles:Array = []; if (box.animData.renderType == "animateatlas") { @@ -288,7 +293,9 @@ private class AddRankAnimationDataBox extends HBox if (isAbsolute) { if (Path.extension(box.animData.assetPath) != "zip") return; - newObj.loadFromZip(FileUtil.readBytesFromPath(box.animData.assetPath)); + + wizFiles.push({name: box.animData.assetPath, bytes: FileUtil.readBytesFromPath(box.animData.assetPath)}); + newObj.loadFromZip(wizFiles[0].bytes); } else { @@ -307,8 +314,16 @@ private class AddRankAnimationDataBox extends HBox { if (Path.extension(box.animData.assetPath) != "png") return; - var bitmap = openfl.display.BitmapData.fromBytes(FileUtil.readBytesFromPath(box.animData.assetPath)); - newObj.frames = flixel.graphics.frames.FlxAtlasFrames.fromSparrow(bitmap, FileUtil.readStringFromPath(box.animData.assetPath.replace(".png", ".xml"))); + var bitBytes = FileUtil.readBytesFromPath(box.animData.assetPath); + var datBytes = FileUtil.readBytesFromPath(box.animData.assetPath.replace(".png", ".xml")); + + var bitmap = openfl.display.BitmapData.fromBytes(bitBytes); + newObj.frames = flixel.graphics.frames.FlxAtlasFrames.fromSparrow(bitmap, datBytes.toString()); + + wizFiles = [ + {name: box.animData.assetPath, bytes: bitBytes}, + {name: box.animData.assetPath.replace(".png", ".xml"), bytes: datBytes} + ]; } else { @@ -334,6 +349,7 @@ private class AddRankAnimationDataBox extends HBox page.makeMarkers(); page.refresh(); + dialog.rankAnimationFiles[dialog.currentRank][box.ID] = wizFiles; copyData(dialog.rankAnimationDataMap[dialog.currentRank][box.ID], box.animData); } @@ -364,7 +380,10 @@ private class AddRankAnimationDataBox extends HBox - + + +