diff --git a/assets/data/stages/test.xml b/assets/data/stages/test.xml
index f74dbd01..82cfbadd 100644
--- a/assets/data/stages/test.xml
+++ b/assets/data/stages/test.xml
@@ -4,33 +4,7 @@
-
-
-
-
-
-
+
+
+
\ No newline at end of file
diff --git a/assets/editors/layouts/stage/characterEditScreen.xml b/assets/editors/layouts/stage/characterEditScreen.xml
index 654db6ea..3fc6e08e 100644
--- a/assets/editors/layouts/stage/characterEditScreen.xml
+++ b/assets/editors/layouts/stage/characterEditScreen.xml
@@ -49,7 +49,9 @@
-
+
+
+
@@ -75,6 +77,7 @@
if(previewSprite == null) return;
previewSprite.skew.x = skewXStepper.value;
previewSprite.skew.y = skewYStepper.value;
+ previewSprite.angle = angleStepper.value;
previewSprite.antialiasing = char.antialiasing;
var ratio = char.frameWidth / char.frameHeight;
previewSprite.setGraphicSize(145 * scaleXStepper.value * ratio, 145 * scaleYStepper.value);
@@ -103,6 +106,7 @@
charPos.charSpacingY = spacingYStepper.value;
charPos.flipX = flipXCheckbox.checked;
charPos.zoomFactor = zoomFactorStepper.value;
+ charPos.angle = angleStepper.value;
charPos.revertCharacter(char);
charPos.prepareCharacter(char, charPos._id);
diff --git a/assets/editors/layouts/stage/unknownEditScreen.xml b/assets/editors/layouts/stage/unknownEditScreen.xml
new file mode 100644
index 00000000..4c053731
--- /dev/null
+++ b/assets/editors/layouts/stage/unknownEditScreen.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ function col(c:Int) {
+ return 20 + (150 + XOFFSET) * c;
+ }
+
+
+
+
+
+
+
+
+
+
+ function onSave() {
+ button.xml.nodeName = nodeNameTextBox.label.text;
+ button.highMemory = highMemoryRadio.checked;
+ button.lowMemory = lowMemoryRadio.checked;
+ }
+
+
\ No newline at end of file
diff --git a/source/funkin/backend/utils/XMLUtil.hx b/source/funkin/backend/utils/XMLUtil.hx
index 97d28ffe..52a3bd47 100644
--- a/source/funkin/backend/utils/XMLUtil.hx
+++ b/source/funkin/backend/utils/XMLUtil.hx
@@ -150,6 +150,9 @@ class XMLUtil {
if(node.has.color)
spr.color = FlxColor.fromString(node.getAtt("color")).getDefault(0xFFFFFFFF);
+ if(node.has.angle)
+ spr.angle = Std.parseFloat(node.getAtt("angle")).getDefault(spr.angle);
+
if (node.has.playOnCountdown)
spr.skipNegativeBeats = node.att.playOnCountdown == "true";
if (node.has.beatInterval)
diff --git a/source/funkin/editors/stage/StageEditor.hx b/source/funkin/editors/stage/StageEditor.hx
index 03be9548..1ca88bcd 100644
--- a/source/funkin/editors/stage/StageEditor.hx
+++ b/source/funkin/editors/stage/StageEditor.hx
@@ -213,6 +213,7 @@ class StageEditor extends UIState {
stage.onNodeLoaded = function(node:Access, sprite:Dynamic):Dynamic {
var parent = new Access(node.x.parent);
var name = "";
+ trace(node, sprite);
if(sprite is FlxSprite) {
//sprite.forceIsOnScreen = true; // hack
}
@@ -340,6 +341,9 @@ class StageEditor extends UIState {
char.extra.set(exID("button"), button);
charPos.extra.set(exID("button"), button);
stageSpritesWindow.add(button);
+ } else if(sprite == null) {
+ var button = new StageUnknownButton(0,0, xml);
+ stageSpritesWindow.add(button);
}
}
}
@@ -486,7 +490,7 @@ class StageEditor extends UIState {
function _file_save(_) {
#if sys
CoolUtil.safeSaveFile(
- '${Paths.getAssetsRoot()}/data/stages/${stage.stageName}.xml',
+ '${Paths.getAssetsRoot()}/data/stages/${__stage}.xml',
buildStage()
);
undos.save();
@@ -497,7 +501,7 @@ class StageEditor extends UIState {
function _file_saveas(_) {
openSubState(new SaveSubstate(buildStage(), {
- defaultSaveFile: '${stage.stageName}.xml'
+ defaultSaveFile: '${__stage}.xml'
}));
undos.save();
}
@@ -557,6 +561,7 @@ class StageEditor extends UIState {
saveToXml(spriteXML, "skewx", sprite.skew.x, 0);
saveToXml(spriteXML, "skewy", sprite.skew.y, 0);
saveToXml(spriteXML, "alpha", sprite.alpha, 1);
+ saveToXml(spriteXML, "angle", sprite.angle, 0);
//saveToXml(spriteXML, "graphicSize", sprite.width, sprite.width);
//saveToXml(spriteXML, "graphicSizex", sprite.height, sprite.height);
//saveToXml(spriteXML, "graphicSizey", sprite.height, sprite.height);
@@ -577,7 +582,6 @@ class StageEditor extends UIState {
var button:StageCharacterButton = cast button;
var charPos:StageCharPos = button.charPos;
var char:Character = cast charPos.extra.get(exID("char"));
- sprite = button.getSprite();
var node:Access = cast charPos.extra.get(exID("node"));
var nodeName = switch(charPos.name) {
case "boyfriend": "boyfriend";
@@ -598,12 +602,17 @@ class StageEditor extends UIState {
saveToXml(charXML, "spacingx", charPos.charSpacingX, 20);
saveToXml(charXML, "spacingy", charPos.charSpacingY, 0);
saveToXml(charXML, "alpha", charPos.alpha, 1);
+ saveToXml(charXML, "angle", charPos.angle, 0);
saveToXml(charXML, "zoomfactor", charPos.zoomFactor, 1);
saveToXml(charXML, "flipX", charPos.flipX, defaultPos.flip);
savePointToXml(charXML, "scroll", charPos.scrollFactor, defaultPos.scroll);
savePointToXml(charXML, "scale", charPos.scale, 1);
newNode = charXML;
- } else {
+ } else if(button is StageUnknownButton) {
+ var button:StageUnknownButton = cast button;
+ newNode = button.xml.x;
+ }
+ else {
Logs.trace("Unknown Stage Type : " + Type.getClassName(Type.getClass(button)));
Logs.trace("> Sprite : " + Type.getClassName(Type.getClass(sprite)));
}
@@ -714,9 +723,12 @@ class StageEditor extends UIState {
function getSprites() {
return stageSpritesWindow.buttons.members.map((o) -> o.getSprite()).filter((o) -> o != null);
}
+ function getRealSprites() {
+ return stageSpritesWindow.buttons.members.filter(o -> o.canRender()).map((o) -> o.getSprite()).filter((o) -> o != null);
+ }
function updateSelection() {
- var sprites = getSprites();
+ var sprites = getRealSprites();
// Unselect all
for(sprite in sprites) {
if(sprite is FunkinSprite) {
@@ -738,7 +750,7 @@ class StageEditor extends UIState {
function _select_all(_, checkSelection:Bool = true) {
_select_deselect(null, false);
- var sprites = getSprites();
+ var sprites = getRealSprites();
selection = new Selection(sprites);
if(checkSelection) updateSelection();
}
diff --git a/source/funkin/editors/stage/elements/StageCharacterButton.hx b/source/funkin/editors/stage/elements/StageCharacterButton.hx
index 3fcb88ef..b271fbc9 100644
--- a/source/funkin/editors/stage/elements/StageCharacterButton.hx
+++ b/source/funkin/editors/stage/elements/StageCharacterButton.hx
@@ -19,11 +19,6 @@ class StageCharacterButton extends StageElementButton {
}
public override function update(elapsed:Float) {
- editButton.selectable = ghostButton.selectable = deleteButton.selectable = selectable;
- editButton.shouldPress = ghostButton.shouldPress = deleteButton.shouldPress = shouldPress;
-
- hovered = !deleteButton.hovered;
- updatePos();
super.update(elapsed);
}
@@ -83,6 +78,7 @@ class StageCharacterEditScreen extends UISoftcodedWindow {
"char" => char,
"charPos" => charPos,
"button" => button,
+ "xml" => button.xml,
"exID" => StageEditor.exID,
"getEx" => function(name:String):Dynamic {
return char.extra.get(StageEditor.exID(name));
diff --git a/source/funkin/editors/stage/elements/StageElementButton.hx b/source/funkin/editors/stage/elements/StageElementButton.hx
index 11f3edf1..f41915b3 100644
--- a/source/funkin/editors/stage/elements/StageElementButton.hx
+++ b/source/funkin/editors/stage/elements/StageElementButton.hx
@@ -154,6 +154,10 @@ class StageElementButton extends UIButton {
return null;
}
+ public function canRender() {
+ return true;
+ }
+
public function getName():String {
return "UNKNOWN";
}
diff --git a/source/funkin/editors/stage/elements/StageSpriteButton.hx b/source/funkin/editors/stage/elements/StageSpriteButton.hx
index 5c584548..ac133b14 100644
--- a/source/funkin/editors/stage/elements/StageSpriteButton.hx
+++ b/source/funkin/editors/stage/elements/StageSpriteButton.hx
@@ -77,6 +77,7 @@ class StageSpriteEditScreen extends UISoftcodedWindow {
"stage" => StageEditor.instance.stage,
"sprite" => sprite,
"button" => button,
+ "xml" => button.xml,
"exID" => StageEditor.exID,
"getEx" => function(name:String):Dynamic {
return sprite.extra.get(StageEditor.exID(name));
diff --git a/source/funkin/editors/stage/elements/StageUnknownButton.hx b/source/funkin/editors/stage/elements/StageUnknownButton.hx
new file mode 100644
index 00000000..70c4f7ae
--- /dev/null
+++ b/source/funkin/editors/stage/elements/StageUnknownButton.hx
@@ -0,0 +1,103 @@
+package funkin.editors.stage.elements;
+
+import funkin.game.Character;
+import funkin.game.Stage.StageCharPos;
+import haxe.xml.Access;
+
+class StageUnknownButton extends StageElementButton {
+ public var lowMemory:Bool = false;
+ public var highMemory:Bool = false;
+
+ public function new(x:Float,y:Float, xml:Access) {
+ super(x,y, xml);
+
+ if(xml.x.parent != null) {
+ lowMemory = xml.x.parent.nodeName == "low-memory";
+ highMemory = xml.x.parent.nodeName == "high-memory";
+ }
+
+ color = 0xff000000;
+
+ ghostButton.exists = false;
+ members.remove(ghostButton);
+
+ ghostIcon.exists = false;
+ members.remove(ghostIcon);
+
+ updateInfo();
+ }
+
+ public override function update(elapsed:Float) {
+ super.update(elapsed);
+ }
+
+ public override function updateInfo() {
+ super.updateInfo();
+ }
+
+ public override function getSprite():FunkinSprite {
+ var sprite = new FunkinSprite(); // to allow it to be saved
+ sprite.extra.set(StageEditor.exID("lowMemory"), lowMemory);
+ sprite.extra.set(StageEditor.exID("highMemory"), highMemory);
+ sprite.extra.set(StageEditor.exID("button"), this);
+ return sprite;
+ }
+
+ public override function canRender() {
+ return false;
+ }
+
+ public override function onSelect() {
+ }
+
+ public override function onEdit() {
+ FlxG.state.openSubState(new StageUnknownEditScreen(this));
+ }
+
+ //public override function onEdit() {
+ // UIState.state.displayNotification(new UIBaseNotification("Editing a character isnt implemented yet!", 2, BOTTOM_LEFT));
+ // CoolUtil.playMenuSFX(WARNING, 0.45);
+ //}
+
+ public override function onGhostClick() {
+ }
+
+ public override function getName():String {
+ return xml.name;
+ }
+
+ public override function getPos():FlxPoint {
+ return FlxPoint.get(0, 0);
+ }
+
+ public override function getInfoText():String {
+ return 'Unknown\n<${getName()} />';
+ }
+
+ public override function updatePos() {
+ super.updatePos();
+ }
+}
+
+class StageUnknownEditScreen extends UISoftcodedWindow {
+ public var button:StageUnknownButton;
+
+ public function new(button:StageUnknownButton) {
+ this.button = button;
+ super("layouts/stage/unknownEditScreen.xml", [
+ "stage" => StageEditor.instance.stage,
+ "button" => button,
+ "xml" => button.xml,
+ "exID" => StageEditor.exID
+ ]);
+ }
+
+ public override function create() {
+ super.create();
+ }
+
+ public override function saveData() {
+ super.saveData();
+ button.updateInfo();
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/game/Stage.hx b/source/funkin/game/Stage.hx
index 6a98e173..b5547770 100644
--- a/source/funkin/game/Stage.hx
+++ b/source/funkin/game/Stage.hx
@@ -248,6 +248,7 @@ class Stage extends FlxBasic implements IBeatReceiver {
charPos.skewX = Std.parseFloat(node.getAtt("skewx")).getDefault(charPos.skewX);
charPos.skewY = Std.parseFloat(node.getAtt("skewy")).getDefault(charPos.skewY);
charPos.alpha = Std.parseFloat(node.getAtt("alpha")).getDefault(charPos.alpha);
+ charPos.angle = Std.parseFloat(node.getAtt("angle")).getDefault(charPos.angle);
charPos.flipX = (node.has.flip || node.has.flipX) ? (node.getAtt("flip") == "true" || node.getAtt("flipX") == "true") : charPos.flipX;
charPos.zoomFactor = Std.parseFloat(node.getAtt("zoomfactor")).getDefault(charPos.zoomFactor);
@@ -364,6 +365,7 @@ class StageCharPos extends FlxObject {
char.cameraOffset += FlxPoint.weak(camxoffset, camyoffset);
char.skew.x += skewX; char.skew.y += skewY;
char.alpha *= alpha;
+ char.angle += angle;
char.zoomFactor *= zoomFactor;
}
@@ -374,7 +376,8 @@ class StageCharPos extends FlxObject {
scaleX: char.scale.x, scaleY: char.scale.y,
camxoffset: char.cameraOffset.x, camyoffset: char.cameraOffset.y,
skewX: char.skew.x, skewY: char.skew.y,
- alpha: char.alpha, zoomFactor: char.zoomFactor
+ alpha: char.alpha, zoomFactor: char.zoomFactor,
+ angle: char.angle
}
}
@@ -390,7 +393,7 @@ class StageCharPos extends FlxObject {
case "camyoffset": char.cameraOffset.y = oldInfo.camyoffset;
case "skewX": char.skew.x = oldInfo.skewX;
case "skewY": char.skew.y = oldInfo.skewY;
- default: Reflect.setField(char, field, Reflect.field(oldInfo, field));
+ default: Reflect.setProperty(char, field, Reflect.field(oldInfo, field));
}
}
oldInfo = null;
@@ -416,4 +419,5 @@ typedef OldCharInfo = {
var skewY:Float;
var alpha:Float;
var zoomFactor:Float;
+ var angle:Float;
}
\ No newline at end of file