diff --git a/assets/images/editors/ui/button small.png b/assets/images/editors/ui/button small.png
new file mode 100644
index 00000000..9b0a33e4
Binary files /dev/null and b/assets/images/editors/ui/button small.png differ
diff --git a/assets/images/editors/ui/button small.xml b/assets/images/editors/ui/button small.xml
new file mode 100644
index 00000000..5f1cae61
--- /dev/null
+++ b/assets/images/editors/ui/button small.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/funkin/editors/character/CharacterAnimButton.hx b/source/funkin/editors/character/CharacterAnimButton.hx
index eb08bd30..f57aead6 100644
--- a/source/funkin/editors/character/CharacterAnimButton.hx
+++ b/source/funkin/editors/character/CharacterAnimButton.hx
@@ -285,7 +285,7 @@ class CharacterAnimButton extends UIButton {
if (parent.character.getAnimName() == anim)
CharacterEditor.instance.playAnimation(anim);
- field.text = '${animData.name} (${animData.x}, ${animData.y})';
+ field.text = '${animData.name} (${positionXStepper.value = animData.x}, ${positionYStepper.value = animData.y})';
}
public function changeFPS(newFPS:Float) @:privateAccess {
diff --git a/source/funkin/editors/character/CharacterAnimsWindow.hx b/source/funkin/editors/character/CharacterAnimsWindow.hx
index 0360f31c..0fea6514 100644
--- a/source/funkin/editors/character/CharacterAnimsWindow.hx
+++ b/source/funkin/editors/character/CharacterAnimsWindow.hx
@@ -15,6 +15,8 @@ class CharacterAnimsWindow extends UIButtonList {
public var displayWindowGraphic:FlxGraphic;
public var displayAnimsFramesList:Map = [];
+ public var animButtons:Map = [];
+
public function new(x:Float, y:Float, character:Character) {
super(x, y, Std.int(500-16), 419, "", FlxPoint.get(Std.int(500-16-32), 208));
@@ -36,10 +38,11 @@ class CharacterAnimsWindow extends UIButtonList {
@:privateAccess
for (name => anim in displayWindowSprite.animation._animations)
buildAnimDisplay(name, anim);
-
- for (anim in character.getAnimOrder())
- add(new CharacterAnimButton(0,0, character.animDatas.get(anim), this));
-
+
+ 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;
}
diff --git a/source/funkin/editors/character/CharacterEditor.hx b/source/funkin/editors/character/CharacterEditor.hx
index 5f0663ab..3cf6523f 100644
--- a/source/funkin/editors/character/CharacterEditor.hx
+++ b/source/funkin/editors/character/CharacterEditor.hx
@@ -1,5 +1,7 @@
package funkin.editors.character;
+import flixel.math.FlxRect;
+import funkin.editors.stage.StageEditor;
import funkin.game.Stage;
import funkin.editors.ui.UITopMenu.UITopMenuButton;
import funkin.editors.extra.CameraHoverDummy;
@@ -27,7 +29,9 @@ class CharacterEditor extends UIState {
@:noCompletion private var stageIndex:Int = 3;
public var topMenuSpr:UITopMenu;
-
+ // public var dragOffsetsCheckbox:UICheckbox;
+ // public var lockCameraCheckbox:UICheckbox;
+
public var drawAxis:DrawAxis;
public var uiGroup:FlxTypedGroup = new FlxTypedGroup();
@@ -229,6 +233,8 @@ class CharacterEditor extends UIState {
character.debugHitbox = Options.characterHitbox;
character.debugCamera = Options.characterCamera;
+ changeCharacterIsPlayer(character.playerOffsets);
+
add(character);
drawAxis = new DrawAxis();
@@ -244,6 +250,12 @@ class CharacterEditor extends UIState {
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);
@@ -266,6 +278,9 @@ class CharacterEditor extends UIState {
}
override function destroy() {
+ _point.put();
+ draggingOffset.put();
+
super.destroy();
if(Framerate.isLoaded) {
Framerate.fpsCounter.alpha = 1;
@@ -274,13 +289,17 @@ class CharacterEditor extends UIState {
}
}
+ var _point:FlxPoint = new FlxPoint();
var _nextScroll:FlxPoint = FlxPoint.get(0,0);
var _cameraZoomMulti:Float = 1;
+
+ var draggingCharacter:Bool = false;
+ var draggingOffset:FlxPoint = new FlxPoint();
public override function update(elapsed:Float) {
if(FlxG.keys.justPressed.ANY)
UIUtil.processShortcuts(topMenu);
- if (cameraHoverDummy.hovered) {
+ if (cameraHoverDummy.hovered && !draggingCharacter) {
if (FlxG.mouse.wheel != 0) {
zoom += 0.25 * FlxG.mouse.wheel;
__camZoom = Math.pow(2, zoom);
@@ -313,10 +332,46 @@ class CharacterEditor extends UIState {
}
animationText.text = '"${character.getAnimName()}"';
- // members.remove(drawAxis);
- // var characterIndex:Int = members.indexOf(character);
- // if (characterIndex != -1)
- // members.insert(characterIndex, drawAxis);
+ var point = FlxG.mouse.getWorldPosition(charCamera, _point);
+ if(character.animateAtlas == null) {
+ StageEditor.calcSpriteBounds(character);
+ var bounds:FlxRect = cast character.extra.get(StageEditor.exID("bounds"));
+
+ // my poor attempt at fixing the global offset flip hitbox bug
+ /*
+ if (character.isPlayer != character.playerOffsets) {
+ bounds.x = character.globalOffset.x + character.animOffsets[character.getAnimName()].x;
+ if (stage != null && stage.characterPoses.exists(stagePosition))
+ bounds.x += stage.characterPoses.get(stagePosition).x;
+ }
+ */
+
+ if (bounds.containsPoint(point)) {
+ cameraHoverDummy.cursor = #if (mac) DRAG_OPEN; #elseif (linux) CLICK; #elseif MOVE; #end
+ if (FlxG.mouse.justPressed)
+ draggingCharacter = true;
+ }
+ }
+
+ if (draggingCharacter) {
+ cameraHoverDummy.cursor = #if (mac) DRAG; #elseif (linux) DRAG; #elseif MOVE; #end
+
+ draggingOffset.x += FlxG.mouse.deltaScreenX; draggingOffset.y += FlxG.mouse.deltaScreenY;
+ character.extraOffset = draggingOffset;
+ trace(draggingOffset);
+
+ if (FlxG.mouse.justReleased) {
+ draggingOffset.x /= character.scale.x;
+ draggingOffset.y /= character.scale.y;
+ characterAnimsWindow.animButtons.get(character.getAnimName()).changeOffset(
+ FlxMath.roundDecimal(character.animOffsets[character.getAnimName()].x - (draggingOffset.x * (character.isPlayer != character.playerOffsets ? -1 : 1)), 2),
+ FlxMath.roundDecimal(character.animOffsets[character.getAnimName()].y - (draggingOffset.y), 2)
+ );
+
+ draggingOffset.set(0, 0); draggingCharacter = false;
+ character.extraOffset = draggingOffset;
+ }
+ }
super.update(elapsed);
}
@@ -448,15 +503,9 @@ class CharacterEditor extends UIState {
if (stage.characterPoses.exists(stagePosition))
stage.characterPoses[stagePosition].revertCharacter(character);
- if (character.__swappedLeftRightAnims)
- character.swapLeftRightAnimations();
- if (character.isPlayer)
- character.flipX = !character.__baseFlipped;
+ changeCharacterIsPlayer(player);
remove(character);
- character.isPlayer = player;
- character.fixChar(false, false);
-
if (stage.characterPoses.exists(stagePosition))
stage.applyCharStuff(character, stagePosition, 0);
_playback_play_anim(null);
@@ -465,6 +514,16 @@ class CharacterEditor extends UIState {
characterPropertiesWindow.designedAsDropDown.label.text = player ? "BOYFRIEND" : "DAD";
}
+ public function changeCharacterIsPlayer(player:Bool) @:privateAccess {
+ if (character.__swappedLeftRightAnims)
+ character.swapLeftRightAnimations();
+ if (character.isPlayer)
+ character.flipX = !character.__baseFlipped;
+
+ character.isPlayer = player;
+ character.fixChar(false, false);
+ }
+
function buildCharacter():String {
var charXML:Xml = character.buildXML([
for (button in characterAnimsWindow.buttons.members)
diff --git a/source/funkin/editors/stage/StageEditor.hx b/source/funkin/editors/stage/StageEditor.hx
index 5d10ce6f..24f1844b 100644
--- a/source/funkin/editors/stage/StageEditor.hx
+++ b/source/funkin/editors/stage/StageEditor.hx
@@ -1016,7 +1016,7 @@ class StageEditor extends UIState {
}
}
- function calcSpriteBounds(sprite:FlxSprite) {
+ public static function calcSpriteBounds(sprite:FlxSprite) {
var oldWidth = sprite.width;
var oldHeight = sprite.height;
var oldOffset = sprite.offset.clone(FlxPoint.weak());
@@ -1211,7 +1211,7 @@ class StageEditor extends UIState {
relative.put();
}
- var dotCheckSize:Float = 53;
+ public static var dotCheckSize:Float = 53;
function checkDot(point:FlxPoint):Bool {
if(point!=null){
diff --git a/source/funkin/game/Character.hx b/source/funkin/game/Character.hx
index 7d016be4..eb2e8ca7 100644
--- a/source/funkin/game/Character.hx
+++ b/source/funkin/game/Character.hx
@@ -45,6 +45,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
public var cameraOffset:FlxPoint = FlxPoint.get(0, 0);
public var globalOffset:FlxPoint = FlxPoint.get(0, 0);
+ public var extraOffset:FlxPoint = FlxPoint.get(0, 0);
public var script:Script;
public var xml:Access;
@@ -195,6 +196,9 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
return (isPlayer != playerOffsets) != (flipX != __baseFlipped);
public override function draw() {
+ x += extraOffset.x;
+ y += extraOffset.y;
+
if (isFlippedOffsets()) {
__reverseDrawProcedure = true;
flipX = !flipX;
@@ -207,6 +211,9 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
__reverseDrawProcedure = false;
} else super.draw();
+ x -= extraOffset.x;
+ y -= extraOffset.y;
+
if (debugHitbox) drawHitbox();
if (debugCamera) drawCamera();
}
@@ -261,9 +268,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
public var singAnims = ["singLEFT", "singDOWN", "singUP", "singRIGHT"];
public inline function getSingAnim(direction:Int, suffix:String = ""):String
- {
return singAnims[direction % singAnims.length] + suffix;
- }
/**
* Like `playSingAnimUnsafe` but checks if the character has the animation with the suffix part, otherwise it plays the animation without the suffix part.
@@ -317,6 +322,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
cameraOffset.put();
globalOffset.put();
+ extraOffset.put();
}
@:noCompletion var __reverseTrailProcedure:Bool = false;
@@ -383,11 +389,6 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
for (anim in xml.nodes.anim)
XMLUtil.addXMLAnimation(this, anim);
- for (offset in animOffsets) {
- offset.x = FlxMath.roundDecimal(offset.x, 2);
- offset.y = FlxMath.roundDecimal(offset.y, 2);
- }
-
for (attribute in xml.x.attributes())
if (!characterProperties.contains(attribute))
extra[attribute] = xml.x.get(attribute);