diff --git a/source/funkin/editors/character/CharacterAnimButton.hx b/source/funkin/editors/character/CharacterAnimButton.hx index 6a73ddf8..6e8f30e0 100644 --- a/source/funkin/editors/character/CharacterAnimButton.hx +++ b/source/funkin/editors/character/CharacterAnimButton.hx @@ -136,7 +136,7 @@ class CharacterAnimButton extends UIButton { playIcon.antialiasing = false; members.push(playIcon); - deleteButton = new UIButton(0, 0, "", null, 28*2,24); + deleteButton = new UIButton(0, 0, "", () -> {parent.deleteAnimation(this);}, 28*2,24); deleteButton.frames = Paths.getFrames("editors/ui/grayscale-button"); deleteButton.color = 0xFFAC3D3D; members.push(deleteButton); @@ -215,6 +215,11 @@ class CharacterAnimButton extends UIButton { public function changeName(newName:String) @:privateAccess { if (newName == anim) return; + if (parent.character.getNameList().indexOf(newName) != -1) { + nameTextBox.label.text = anim; + return; + } + if (parent.character.animateAtlas != null) { var animSymbol:SymbolStuff = parent.character.animateAtlas.anim.animsMap[anim]; diff --git a/source/funkin/editors/character/CharacterAnimsWindow.hx b/source/funkin/editors/character/CharacterAnimsWindow.hx index caf959f1..af9be287 100644 --- a/source/funkin/editors/character/CharacterAnimsWindow.hx +++ b/source/funkin/editors/character/CharacterAnimsWindow.hx @@ -1,5 +1,6 @@ package funkin.editors.character; +import funkin.backend.utils.XMLUtil.AnimData; import flixel.animation.FlxAnimation; import flixel.graphics.FlxGraphic; import openfl.geom.Rectangle; @@ -16,9 +17,11 @@ class CharacterAnimsWindow extends UIButtonList { public var displayAnimsFramesList:Map = []; public var animButtons:Map = []; + public var animsList:Array = []; public function new(x:Float, y:Float, character:CharacterGhost) { super(x, y, Std.int(500-16), 419, "", FlxPoint.get(Std.int(500-16-32), 208)); + this.character = character; cameraSpacing = 0; frames = Paths.getFrames('editors/ui/inputbox'); @@ -35,26 +38,16 @@ class CharacterAnimsWindow extends UIButtonList { alpha = 0.7; - @:privateAccess - for (name => anim in displayWindowSprite.animation._animations) - buildAnimDisplay(name, anim); - - for (anim in character.getAnimOrder()) { - var button:CharacterAnimButton = new CharacterAnimButton(0, 0, character.animDatas.get(anim), this); - add(button); animButtons.set(anim, button); - } - this.character = character; + for (anim in character.getAnimOrder()) + addAnimation(character.animDatas.get(anim)); + addButton.callback = generateAnimation; } public var ghosts:Array = []; public override function update(elapsed:Float) { super.update(elapsed); - // if (CharacterEditor.instance.draggingCharacter && ghosts[0] != character.getAnimName()) { - // if (ghosts.indexOf(character.getAnimName()) != -1) - // ghosts.remove(character.getAnimName()); - // ghosts.insert(0, character.getAnimName()); - // } + animsList = [for (button in buttons) button.anim]; character.ghosts = ghosts; } @@ -67,4 +60,48 @@ class CharacterAnimsWindow extends UIButtonList { displayAnimsFramesList.set(name, {frame: anim.frames.getDefault([0])[0], scale: 104/animBounds.height, animBounds: animBounds}); } + + public function deleteAnimation(button:CharacterAnimButton) { + if (buttons.members.length <= 1) return; + if (character.getAnimName() == button.anim) + @:privateAccess CharacterEditor.instance._animation_down(null); + + character.removeAnimation(button.anim); + if (character.animOffsets.exists(button.anim)) character.animOffsets.remove(button.anim); + if (character.animDatas.exists(button.anim)) character.animDatas.remove(button.anim); + + remove(button); button.destroy(); + } + + public function generateAnimation() { + var animName:String = "New Anim"; + var animNames:Array = character.getNameList(); + + var newAnimCount:Int = 0; + while (animNames.indexOf(animName) != -1) { + newAnimCount++; + animName = 'New Anim - $newAnimCount'; + } + + var animData:AnimData = { + name: animName, + anim: character.frames.getByIndex(0).name, + fps: 24, loop: false, + x: 0, y: 0, + indices: [], + animType: NONE, + }; + addAnimation(animData); + } + + public function addAnimation(animData:AnimData, animID:Int = -1) @:privateAccess { + XMLUtil.addAnimToSprite(character, animData); + buildAnimDisplay(animData.name, character.animation._animations[animData.name]); + + var newButton:CharacterAnimButton = new CharacterAnimButton(0, 0, animData, this); + newButton.alpha = 0.25; animButtons.set(animData.name, newButton); + + if (animID == -1) add(newButton); + else insert(newButton, animID); + } } \ No newline at end of file diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx index 40516708..19d281a7 100644 --- a/source/funkin/editors/character/CharacterEditor.hx +++ b/source/funkin/editors/character/CharacterEditor.hx @@ -264,29 +264,24 @@ class CharacterEditor extends UIState { uiGroup.cameras = [uiCamera]; add(cameraHoverDummy = new CameraHoverDummy(uiGroup, FlxPoint.weak(0, 0))); - characterPropertiesWindow = new CharacterPropertiesWindow((FlxG.width-(432)), 23+12+10, character); + characterPropertiesWindow = new CharacterPropertiesWindow((FlxG.width-(440)-16) - (((500-16)-(440))/2), 23+12+10, character); uiGroup.add(characterPropertiesWindow); topMenuSpr = new UITopMenu(topMenu); uiGroup.add(topMenuSpr); - // dragOffsetsCheckbox = new UICheckbox(FlxG.width - 440, 5, "Drag Offsets With Mouse?", false, 0, true); - // uiGroup.add(dragOffsetsCheckbox); - - // lockCameraCheckbox = new UICheckbox(FlxG.width - 200, 5, "Lock Camera?", false, 0, true); - // uiGroup.add(lockCameraCheckbox); - animationText = new UIText(0, 0, 0, ""); uiGroup.add(animationText); - characterAnimsWindow = new CharacterAnimsWindow(characterPropertiesWindow.x - 60, characterPropertiesWindow.y+224+16, character); + characterAnimsWindow = new CharacterAnimsWindow((FlxG.width-(500-16)-16), characterPropertiesWindow.y+224+16, character); uiGroup.add(characterAnimsWindow); add(uiGroup); playAnimation(character.getAnimOrder()[0]); - _view_focus_character(null); + changeStage("stage"); + _view_focus_character(null); if(Framerate.isLoaded) { Framerate.fpsCounter.alpha = 0.4; @@ -300,6 +295,7 @@ class CharacterEditor extends UIState { override function destroy() { _point.put(); draggingOffset.put(); + clipboard.put(); super.destroy(); if(Framerate.isLoaded) { @@ -360,7 +356,7 @@ class CharacterEditor extends UIState { inline function handleMouseOffsets() { if (draggingCharacter) { - cameraHoverDummy.cursor = #if (mac) DRAG; #elseif (linux) DRAG; #else MOVE; #end + cameraHoverDummy.cursor = #if (mac) DRAG; #elseif (linux) DRAG; #else BUTTON; #end if (FlxG.mouse.justReleased) { draggingOffset.x /= character.scale.x; @@ -426,6 +422,9 @@ class CharacterEditor extends UIState { } function buildCharacter():String { + if (character.extra.exists(StageEditor.exID("bounds"))) + character.extra.remove(StageEditor.exID("bounds")); + var charXML:Xml = character.buildXML([ for (button in characterAnimsWindow.buttons.members) button.anim @@ -434,8 +433,13 @@ class CharacterEditor extends UIState { return "\n" + Printer.print(charXML, true); } - function _edit_copy_offset(_) {} - function _edit_paste_offset(_) {} + var clipboard:FlxPoint = FlxPoint.get(); + function _edit_copy_offset(_) { + clipboard.copyFrom(character.animOffsets[character.getAnimName()]); + } + function _edit_paste_offset(_) { + _set_offset(clipboard.x, clipboard.y); + } function _edit_undo(_) {} function _edit_redo(_) {} @@ -459,9 +463,15 @@ class CharacterEditor extends UIState { } function _change_offset(x:Float, y:Float) { + _set_offset( + character.animOffsets[character.getAnimName()].x - x, + character.animOffsets[character.getAnimName()].y - y + ); + } + + function _set_offset(x:Float, y:Float) { characterAnimsWindow.animButtons.get(character.getAnimName()).changeOffset( - FlxMath.roundDecimal(character.animOffsets[character.getAnimName()].x - x, 2), - FlxMath.roundDecimal(character.animOffsets[character.getAnimName()].y - y, 2) + FlxMath.roundDecimal(x, 2), FlxMath.roundDecimal(y, 2) ); } @@ -507,7 +517,9 @@ class CharacterEditor extends UIState { remove(character); if (__stage == null) { - updateStagePositions(["NONE"]); + updateStagePositions([]); + changeStagePosition("NONE"); + add(character); } else { stage = new Stage(__stage, this, false); @@ -543,24 +555,28 @@ class CharacterEditor extends UIState { } public function changeStagePosition(position:String) { - if (stage == null) return; - - if (stage.characterPoses.exists(stagePosition)) - stage.characterPoses[stagePosition].revertCharacter(character); - - stagePosition = position.toLowerCase(); - remove(character); - - if (stage.characterPoses.exists(stagePosition)) - stage.applyCharStuff(character, stagePosition, 0); - _animation_play(null); + if (stage != null && position != "NONE") { + if (stage.characterPoses.exists(stagePosition)) + stage.characterPoses[stagePosition].revertCharacter(character); + + stagePosition = position.toLowerCase(); + remove(character); + + if (stage.characterPoses.exists(stagePosition)) + stage.applyCharStuff(character, stagePosition, 0); + _animation_play(null); + } else + stagePosition = position.toLowerCase(); characterPropertiesWindow.testAsDropDown.index = characterPropertiesWindow.testAsDropDown.options.indexOf(stagePosition.toUpperCase()); characterPropertiesWindow.testAsDropDown.label.text = stagePosition.toUpperCase(); } public function changeCharacterDesginedAs(player:Bool) @:privateAccess { - if (stage == null) return; + if (stage == null) { + changeCharacterIsPlayer(player); + return; + } if (stage.characterPoses.exists(stagePosition)) stage.characterPoses[stagePosition].revertCharacter(character); @@ -645,8 +661,21 @@ class CharacterEditor extends UIState { character.stopAnimation(); } - function _animation_up(_) {} - function _animation_down(_) {} + function _animation_up(_) + playAnimation( + characterAnimsWindow.animsList[ + FlxMath.wrap( + characterAnimsWindow.animsList.indexOf(character.getAnimName()) - 1, + 0, characterAnimsWindow.animsList.length-1 + )] + ); + function _animation_down(_) + playAnimation( + characterAnimsWindow.animsList[FlxMath.wrap( + characterAnimsWindow.animsList.indexOf(character.getAnimName()) + 1, + 0, characterAnimsWindow.animsList.length-1 + )] + ); public function playAnimation(anim:String) { character.playAnim(anim, true); diff --git a/source/funkin/editors/character/CharacterPropertiesWindow.hx b/source/funkin/editors/character/CharacterPropertiesWindow.hx index fe0e41ca..4349bab4 100644 --- a/source/funkin/editors/character/CharacterPropertiesWindow.hx +++ b/source/funkin/editors/character/CharacterPropertiesWindow.hx @@ -8,6 +8,7 @@ class CharacterPropertiesWindow extends UISliceSprite { public var positionXStepper:UINumericStepper; public var positionYStepper:UINumericStepper; public var scaleStepper:UINumericStepper; + public var editCharacterButton:UIButton; public var flipXCheckbox:UICheckbox; public var cameraXStepper:UINumericStepper; @@ -17,7 +18,7 @@ class CharacterPropertiesWindow extends UISliceSprite { public var designedAsDropDown:UIDropDown; public function new(x:Float, y:Float, character:Character) @:privateAccess { - super(x, y, 424, 204+20, "editors/ui/inputbox"); + super(x, y, 424+16, 204+20, "editors/ui/inputbox"); function addLabelOn(ui:UISprite, text:String) members.push(new UIText(ui.x, ui.y - 24, 0, text)); @@ -39,7 +40,7 @@ class CharacterPropertiesWindow extends UISliceSprite { }; members.push(positionYStepper); - scaleStepper = new UINumericStepper(positionYStepper.x+104+16, positionYStepper.y, character.scale.x, 0.001, 2, 0, null, 104); + scaleStepper = new UINumericStepper(positionYStepper.x+104-32+26, positionYStepper.y, character.scale.x, 0.001, 2, 0, null, 90); scaleStepper.onChange = (text:String) -> { @:privateAccess scaleStepper.__onChange(text); this.changeScale(scaleStepper.value); @@ -47,7 +48,10 @@ class CharacterPropertiesWindow extends UISliceSprite { members.push(scaleStepper); addLabelOn(scaleStepper, "Scale"); - flipXCheckbox = new UICheckbox(scaleStepper.x, scaleStepper.y+32+14, "Flipped?", character.isPlayer ? !character.__baseFlipped : character.__baseFlipped); + editCharacterButton = new UIButton(scaleStepper.x + 90 -32 + 26, scaleStepper.y, "Edit Info", null); + members.push(editCharacterButton); + + flipXCheckbox = new UICheckbox(scaleStepper.x+22, scaleStepper.y+32+14, "Flipped?", character.isPlayer ? !character.__baseFlipped : character.__baseFlipped); flipXCheckbox.onChecked = (checked:Bool) -> {this.changeFlipX(checked);}; members.push(flipXCheckbox); @@ -68,25 +72,25 @@ class CharacterPropertiesWindow extends UISliceSprite { }; members.push(cameraYStepper); - antialiasingCheckbox = new UICheckbox(scaleStepper.x, flipXCheckbox.y+32, "Antialiased?", character.antialiasing); + antialiasingCheckbox = new UICheckbox(scaleStepper.x+22, flipXCheckbox.y+32, "Antialiased?", character.antialiasing); antialiasingCheckbox.onChecked = (checked:Bool) -> {this.changeAntialiasing(checked);}; members.push(antialiasingCheckbox); - testAsDropDown = new UIDropDown(cameraXStepper.x, cameraXStepper.y+32+32+4, 170, 32, ["BOYFRIEND", "DAD"], character.playerOffsets ? 0 : 1); + testAsDropDown = new UIDropDown(cameraXStepper.x, cameraXStepper.y+32+32+4, 193, 32, ["BOYFRIEND", "DAD"], character.playerOffsets ? 0 : 1); testAsDropDown.onChange = (index:Int) -> { CharacterEditor.instance.changeStagePosition(testAsDropDown.options[index]); }; members.push(testAsDropDown); addLabelOn(testAsDropDown, "Test Character As..."); - testAsDropDown.bWidth = 170; //REFUSES TO FUCKING SET TO 170 PIECE OF SHIT!! + testAsDropDown.bWidth = 193; //REFUSES TO FUCKING SET TO 170 PIECE OF SHIT!! - designedAsDropDown = new UIDropDown(scaleStepper.x, testAsDropDown.y, 170, 32, ["BOYFRIEND", "DAD"], character.playerOffsets ? 0 : 1); + designedAsDropDown = new UIDropDown(testAsDropDown.x+193+22, testAsDropDown.y, 193, 32, ["BOYFRIEND", "DAD"], character.playerOffsets ? 0 : 1); designedAsDropDown.onChange = (index:Int) -> { CharacterEditor.instance.changeCharacterDesginedAs(designedAsDropDown.options[index] == "BOYFRIEND"); }; members.push(designedAsDropDown); addLabelOn(designedAsDropDown, "Char Desgined As..."); - designedAsDropDown.bWidth = 170; + designedAsDropDown.bWidth = 193; alpha = 0.7; diff --git a/source/funkin/options/Options.hx b/source/funkin/options/Options.hx index f85ff711..f1b0c464 100644 --- a/source/funkin/options/Options.hx +++ b/source/funkin/options/Options.hx @@ -75,7 +75,7 @@ class Options public static var characterHitbox:Bool = true; public static var characterCamera:Bool = true; public static var characterAxis:Bool = true; - public static var characterDragging:Bool = true; + public static var characterDragging:Bool = false; /** * PLAYER 1 CONTROLS