diff --git a/source/funkin/backend/utils/XMLUtil.hx b/source/funkin/backend/utils/XMLUtil.hx index b6040374..b03d067c 100644 --- a/source/funkin/backend/utils/XMLUtil.hx +++ b/source/funkin/backend/utils/XMLUtil.hx @@ -1,5 +1,6 @@ package funkin.backend.utils; +import flixel.animation.FlxAnimation; import funkin.backend.FunkinSprite; import funkin.backend.system.ErrorCode; import funkin.backend.FunkinSprite.XMLAnimType; @@ -163,6 +164,25 @@ class XMLUtil { return addAnimToSprite(sprite, extractAnimFromXML(anim, animType, loop)); } + public static function getAnimationData(sprite:FlxSprite, name:String):AnimData { + var flxanim:FlxAnimation = sprite.animation.getByName(name); + var animData:AnimData = { + name: name, + anim: flxanim.prefix, + fps: flxanim.frameRate, + loop: flxanim.looped, + x: 0, + y: 0, + indices: flxanim.usesIndicies ? flxanim.frames : [], + animType: NONE + }; + if (sprite is FunkinSprite) { + var animOffset = cast(sprite, FunkinSprite).getAnimOffset(name); + animData.x = animOffset.x; animData.y = animOffset.y; + } + return animData; + } + public static function addAnimToSprite(sprite:FlxSprite, animData:AnimData):ErrorCode { if (animData.name != null && animData.anim != null) { if (animData.fps <= 0 #if web || animData.fps == null #end) animData.fps = 24; @@ -174,6 +194,7 @@ class XMLUtil { else animateAnim.addBySymbol(animData.name, animData.anim, animData.fps, animData.loop); } else { + trace("ge"); if (animData.indices.length > 0) sprite.animation.addByIndices(animData.name, animData.anim, animData.indices, "", animData.fps, animData.loop); else diff --git a/source/funkin/editors/character/CharacterAnimScreen.hx b/source/funkin/editors/character/CharacterAnimScreen.hx index 598f6209..d29b45e2 100644 --- a/source/funkin/editors/character/CharacterAnimScreen.hx +++ b/source/funkin/editors/character/CharacterAnimScreen.hx @@ -5,28 +5,44 @@ import flixel.animation.FlxAnimation; import funkin.backend.utils.XMLUtil.AnimData; class CharacterAnimScreen extends UISubstateWindow { - public var animName:Null; public var animData:AnimData; + public var nameTextBox:UITextBox; + public var animTextBox:UITextBox; + public var fpsStepper:UINumericStepper; + public var loopedCheckbox:UICheckbox; + public var indicesTextBox:UITextBox; + public var offsetXStepper:UINumericStepper; + public var offsetYStepper:UINumericStepper; + public var saveButton:UIButton; public var closeButton:UIButton; - private var onSave:(animData:AnimData) -> Void = null; + public var onSave:(animData:AnimData) -> Void = null; - public function new(animName:Null, animData:AnimData) { - this.animName = animName; + public function new(animData:AnimData, ?onSave:(animData:AnimData) -> Void) { + this.animData = animData; + this.onSave = onSave; super(); } public override function create() { - var creatingAnim:Bool = animName == null; + var creatingAnim:Bool = animData == null; - if (creatingAnim) { - animName = ""; - } + if (creatingAnim) + animData = { + name: "name", + anim: "anim", + fps: 24, + loop: false, + animType: NONE, + x: 0, + y: 0, + indices: [] + }; - winTitle = creatingAnim ? 'Creating Animation' : 'Animation $animName properties'; - winWidth = 690; winHeight = 334; + winTitle = creatingAnim ? 'Creating Animation' : 'Animation ${animData.name} properties'; + winWidth = 690; winHeight = 314; super.create(); @@ -36,17 +52,64 @@ class CharacterAnimScreen extends UISubstateWindow { var title:UIText; add(title = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, creatingAnim ? "Create New Animation" : "Edit Animation Properties", 28)); + nameTextBox = new UITextBox(title.x, title.y + title.height + 38, animData.name, 160); + add(nameTextBox); + addLabelOn(nameTextBox, "Name"); + + animTextBox = new UITextBox(nameTextBox.x + 160 + 26, nameTextBox.y, animData.anim, 180); + add(animTextBox); + addLabelOn(animTextBox, "Animation"); + + fpsStepper = new UINumericStepper(animTextBox.x + 180 + 26, animTextBox.y, animData.fps, 0.1, 2, 1, 100, 82); + add(fpsStepper); + addLabelOn(fpsStepper, "FPS"); + + loopedCheckbox = new UICheckbox(fpsStepper.x + 82 - 32 + 26, fpsStepper.y, "Looped", animData.loop); + add(loopedCheckbox); + addLabelOn(loopedCheckbox, "Looping"); + loopedCheckbox.x += 8; loopedCheckbox.y += 6; + + indicesTextBox = new UITextBox(nameTextBox.x, nameTextBox.y + 32 + 40, animData.indices.join(", "), 270); + add(indicesTextBox); + addLabelOn(indicesTextBox, "Indices"); + + offsetXStepper = new UINumericStepper(indicesTextBox.x + 270 + 26, indicesTextBox.y, animData.x, 0.001, 2, null, null, 84); + add(offsetXStepper); + addLabelOn(offsetXStepper, "Offset (X,Y)"); + + add(new UIText(offsetXStepper.x + 84 - 32 + 0, offsetXStepper.y + 9, 0, ",", 22)); + + offsetYStepper = new UINumericStepper(offsetXStepper.x + 84 - 32 + 26, offsetXStepper.y, animData.y, 0.001, 2, null, null, 84); + add(offsetYStepper); + saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20 - 125, windowSpr.y + windowSpr.bHeight - 16 - 32, "Save & Close", function() { - // saveStrumline(); + saveAnimData(); close(); }, 125); add(saveButton); closeButton = new UIButton(saveButton.x - 20, saveButton.y, creatingAnim ? "Cancel" : "Close", function() { - if (creatingAnim) onSave(null); + if (creatingAnim && onSave != null) onSave(null); close(); }, 125); add(closeButton); closeButton.x -= closeButton.bWidth; } + + public function saveAnimData() { + for (stepper in [offsetXStepper, offsetYStepper, fpsStepper]) + @:privateAccess stepper.__onChange(stepper.label.text); + + animData = { + name: nameTextBox.label.text, + anim: animTextBox.label.text, + fps: fpsStepper.value, + loop: loopedCheckbox.checked, + animType: NONE, + x: offsetXStepper.value, + y: offsetYStepper.value, + indices: [for (indice in indicesTextBox.label.text.split(",")) Std.parseInt(indice.trim())] + } + if (onSave != null) onSave(animData); + } } \ No newline at end of file diff --git a/source/funkin/editors/character/CharacterAnimsWindow.hx b/source/funkin/editors/character/CharacterAnimsWindow.hx index 824c0e2a..953e57b1 100644 --- a/source/funkin/editors/character/CharacterAnimsWindow.hx +++ b/source/funkin/editors/character/CharacterAnimsWindow.hx @@ -27,7 +27,11 @@ class CharacterAnimsWindow extends UIWindow { for (i=>anim in character.animation.getNameList()) createNewButton(anim, character.getAnimOffset(anim), false, -1, false); - addButton = new UIButton(25, 16+((32+16)*(character.animation.getNameList().length)), "", null, 429); + addButton = new UIButton(25, 16+((32+16)*(character.animation.getNameList().length)), "", + function () { + CharacterEditor.instance.createAnimWithUI(); + } + , 426); addButton.cameras = [CharacterEditor.instance.animsCamera]; addButton.color = FlxColor.GREEN; @@ -40,7 +44,7 @@ class CharacterAnimsWindow extends UIWindow { updateButtonsPos(); } - public function createNewButton(anim:String, offset:FlxPoint, ghost:Bool = false, id:Int = -1, updatePos:Bool = true) { + public function createNewButton(anim:String, offset:FlxPoint, ghost:Bool = false, id:Int = -1, ?updatePos:Bool = true) { var button = new CharacterAnimButtons(0,0, anim, offset); if (id == -1) buttons.add(button); else buttons.members.insert(id, button); diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx index fa4fc990..7f280dd4 100644 --- a/source/funkin/editors/character/CharacterEditor.hx +++ b/source/funkin/editors/character/CharacterEditor.hx @@ -338,21 +338,33 @@ class CharacterEditor extends UIState { } function _char_add_anim(_) { - FlxG.state.openSubState(new CharacterAnimScreen(null, null)); + createAnimWithUI(); } function _char_update_anim(_) { } function _char_remove_anim(_) { + deleteAnim(character.animation.name); } function _char_edit_info(_) { FlxG.state.openSubState(new CharacterInfoScreen(character)); } + public function createAnimWithUI() { + FlxG.state.openSubState(new CharacterAnimScreen(null, (_) -> { + if (_ != null) createAnim(_); + })); + } + + public function editAnimWithUI() { + + } + public function createAnim(animData:AnimData, animID:Int = -1, addtoUndo:Bool = true) { XMLUtil.addAnimToSprite(character, animData); + trace(character.animation.getNameList()); characterAnimsWindow.createNewButton(animData.name, FlxPoint.get(animData.x,animData.y), false, animID); playAnimation(animData.name); @@ -364,21 +376,11 @@ class CharacterEditor extends UIState { public function deleteAnim(name:String, addtoUndo:Bool = true) { playAnimation(character.animation.getNameList()[Std.int(Math.abs(character.animation.getNameList().indexOf(name)-1))]); - @:privateAccess var flxanim:FlxAnimation = character.animation._animations.get(name); + // undo shit blah blah var oldID:Int = character.animation.getNameList().indexOf(name); - var oldAnimData:AnimData = { - name: name, - anim: flxanim.prefix, - fps: flxanim.frameRate, - loop: flxanim.looped, - x: character.animOffsets.get(name).x, - y: character.animOffsets.get(name).y, - indices: flxanim.usesIndicies ? flxanim.frames : [], - animType: NONE - }; - @:privateAccess character.animation._animations.remove(name); - flxanim.destroy(); + var oldAnimData:AnimData = XMLUtil.getAnimationData(character, name); + character.animation.remove(name); character.animOffsets.remove(name); characterAnimsWindow.removeButton(name); diff --git a/source/funkin/editors/character/CharacterInfoScreen.hx b/source/funkin/editors/character/CharacterInfoScreen.hx index 336e67ca..5d5dddc4 100644 --- a/source/funkin/editors/character/CharacterInfoScreen.hx +++ b/source/funkin/editors/character/CharacterInfoScreen.hx @@ -16,6 +16,7 @@ class CharacterInfoScreen extends UISubstateWindow { public var scaleStepper:UINumericStepper; public var singTimeStepper:UINumericStepper; public var isPlayerCheckbox:UICheckbox; + // TODO: ADD THESE OPTIONS AND A HEALTH BAR COLOR OPTION public var isGFCheckbox:UICheckbox; public var flipXCheckbox:UICheckbox; public var antialiasingCheckbox:UICheckbox; @@ -81,7 +82,7 @@ class CharacterInfoScreen extends UISubstateWindow { singTimeStepper = new UINumericStepper(scaleStepper.x + 74 - 32 + 36, scaleStepper.y, character.holdTime, 0.001, 2, null, null, 74); add(singTimeStepper); - addLabelOn(singTimeStepper, "Sing Time"); + addLabelOn(singTimeStepper, "Sing Duration (Steps)"); isPlayerCheckbox = new UICheckbox(positionXStepper.x, positionXStepper.y + 10 + 32 + 26, "isPlayer", character.playerOffsets); add(isPlayerCheckbox); diff --git a/source/funkin/editors/charter/CharterStrumlineScreen.hx b/source/funkin/editors/charter/CharterStrumlineScreen.hx index 91167d5c..c3c978f1 100644 --- a/source/funkin/editors/charter/CharterStrumlineScreen.hx +++ b/source/funkin/editors/charter/CharterStrumlineScreen.hx @@ -135,7 +135,7 @@ class CharterStrumlineScreen extends UISubstateWindow { add(saveButton); closeButton = new UIButton(saveButton.x - 20, saveButton.y, creatingStrumLine ? "Cancel" : "Close", function() { - if (creatingStrumLine) onSave(null); + if (creatingStrumLine && onSave != null) onSave(null); close(); }, 125); add(closeButton);