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; + } + + + + + <section> + <set name="curY" value="title.y + TO" /> + + <textbox name="nodeNameTextBox" label="Element Name" value="button.getName()" x="col(0)" y="curY" width="280" height="32" /> + </section> + <section> + <set name="curY" value="nodeNameTextBox.y + nodeNameTextBox.bHeight + YOFFSET - 20" /> + + <radio for="memoryCheck" name="highMemoryRadio" text="High Memory Only" value="button.highMemory" x="col(0)" y="curY" /> + <radio for="memoryCheck" name="lowMemoryRadio" text="Low Memory Only" value="button.lowMemory" x="col(0)" y="last.y + last.check.height + YOFFSET - 30" /> + </section> + + <section> + <set name="curY" value="lowMemoryRadio.y + lowMemoryRadio.check.height + YOFFSET - 20" /> + + <!-- TODO: attribute button list --> + </section> + + <exec> + function onSave() { + button.xml.nodeName = nodeNameTextBox.label.text; + button.highMemory = highMemoryRadio.checked; + button.lowMemory = lowMemoryRadio.checked; + } + </exec> +</window> \ 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