diff --git a/assets/data/editors/layouts/stage/characterEditScreen.xml b/assets/data/editors/layouts/stage/characterEditScreen.xml index 22b64ac5..a497f0ea 100644 --- a/assets/data/editors/layouts/stage/characterEditScreen.xml +++ b/assets/data/editors/layouts/stage/characterEditScreen.xml @@ -21,47 +21,47 @@
- - + + - - + + - - + +
- - + +
- - + + - + -
- +
+
- + @@ -86,7 +86,7 @@ var ratio = char.frameWidth / char.frameHeight; previewSprite.setGraphicSize(145 * scaleXStepper.value * ratio, 145 * scaleYStepper.value); previewSprite.updateHitbox(); - if(flipXCheckbox.checked != (charPos.name == "boyfriend")) + if(flipXCheckbox.checked != char.playerOffsets) previewSprite.scale.x *= -1; previewSprite.x = 30; @@ -97,23 +97,30 @@ setEx("highMemory", highMemoryRadio.checked); setEx("lowMemory", lowMemoryRadio.checked); - charPos.x = xStepper.value; - charPos.y = yStepper.value; - charPos.scrollFactor.set(scrollXStepper.value, scrollYStepper.value); - charPos.scale.set(scaleXStepper.value, scaleYStepper.value); - charPos.camxoffset = camxStepper.value; - charPos.camyoffset = camyStepper.value; - charPos.skewX = skewXStepper.value; - charPos.skewY = skewYStepper.value; - charPos.alpha = alphaStepper.value; - charPos.charSpacingX = spacingXStepper.value; - charPos.charSpacingY = spacingYStepper.value; - charPos.flipX = flipXCheckbox.checked; - charPos.zoomFactor = zoomFactorStepper.value; - charPos.angle = angleStepper.value; + if (!StringTools.startsWith(char.name, 'NO_DELETE_')) + char.name = charName.field.text; - charPos.revertCharacter(char); - charPos.prepareCharacter(char, charPos._id); + char.x = xStepper.value; + char.y = yStepper.value; + char.scrollFactor.set(scrollXStepper.value, scrollYStepper.value); + char.scale.set(scaleXStepper.value * charScale, scaleYStepper.value * charScale); + char.cameraOffset.x -= getEx("camX"); + char.cameraOffset.x += camxStepper.value; + setEx("camX", camxStepper.value); + char.cameraOffset.y -= getEx("camY"); + char.cameraOffset.y += camyStepper.value; + setEx("camY", camyStepper.value); + char.skew.x = skewXStepper.value; + char.skew.y = skewYStepper.value; + char.alpha = alphaStepper.value * 0.75; + setEx("spacingX", spacingXStepper.value); + setEx("spacingY", spacingYStepper.value); + if (flipXCheckbox.checked != char.isPlayer) { + char.isPlayer = flipXCheckbox.checked; + char.swapLeftRightAnimations(); + } + char.zoomFactor = zoomFactorStepper.value; + char.angle = angleStepper.value; } \ No newline at end of file diff --git a/assets/data/states/StageEditor.hx b/assets/data/states/StageEditor.hx index aee3afac..dfca00e9 100644 --- a/assets/data/states/StageEditor.hx +++ b/assets/data/states/StageEditor.hx @@ -181,10 +181,8 @@ function SCALE_TOP_RIGHT(sprite, relative) { } function MOVE_CENTER(sprite, relative) { - preRotBullshit(sprite, relative); sprite.x = storedPos.x-relative.x; sprite.y = storedPos.y-relative.y; - postRotBullshit(sprite, relative); } function SCALE_TOP_LEFT(sprite, relative) { diff --git a/source/funkin/editors/stage/StageEditor.hx b/source/funkin/editors/stage/StageEditor.hx index 51f20731..c2e0d010 100644 --- a/source/funkin/editors/stage/StageEditor.hx +++ b/source/funkin/editors/stage/StageEditor.hx @@ -251,14 +251,22 @@ class StageEditor extends UIState { } if(sprite is StageCharPos) { var charPos:StageCharPos = cast sprite; + // TODO: fix default characters not being added - var charName = switch(charPos.name) { - case "boyfriend": "bf"; - case "girlfriend": "gf"; - default: charPos.name; + var charName = switch(node.name) { + case "dad" | "opponent": "dad"; + case "gf" | "girlfriend": "gf"; + case "bf" | "boyfriend" | "player": "bf"; + default: (charPos.flipX) ? "bf" : "dad"; } //name = charPos.name; - var char = new Character(0,0, charName, stage.isCharFlipped(charPos.name, charName == "bf"), true); + var char = new Character(0,0, charName, charPos.flipX, true); + charName = switch(node.name) { + case "dad" | "opponent": "NO_DELETE_dad"; + case "gf" | "girlfriend": "NO_DELETE_girlfriend"; + case "bf" | "boyfriend" | "player": "NO_DELETE_boyfriend"; + default: node.att.name; + } char.name = charName; char.debugMode = true; // Play first anim, and make it the last frame @@ -272,19 +280,24 @@ class StageEditor extends UIState { // Add it to the stage char.visible = true; - char.alpha = 0.5; - function setEx(name:String, value:Dynamic) { - char.extra.set(exID(name), value); - charPos.extra.set(exID(name), value); - } - setEx("node", node); - setEx("pos", charPos); - setEx("char", char); + char.alpha = 0.75; + char.extra.set(exID("node"), node); + char.extra.set(exID("spacingX"), charPos.charSpacingX); + char.extra.set(exID("spacingY"), charPos.charSpacingY); + char.extra.set(exID("camX"), charPos.camxoffset); + char.extra.set(exID("camY"), charPos.camyoffset); + + char.extra.set(exID("parentNode"), parent); + char.extra.set(exID("highMemory"), parent.name == "highMemory"); + char.extra.set(exID("lowMemory"), parent.name == "lowMemory"); - setEx("parentNode", parent); - setEx("highMemory", parent.name == "highMemory"); - setEx("lowMemory", parent.name == "lowMemory"); chars.push(char); + stage.applyCharStuff(char, charPos.name, 0); + charMap[charName] = char; + + remove(charPos, true); + charPos.destroy(); + sprite = char; } order.push(sprite); orderNodes.push(node); @@ -295,14 +308,6 @@ class StageEditor extends UIState { stage.loadXml(stage.stageXML, true); add(stage); - for(char in chars) { - var charPos = char.extra.get(exID("pos")); - //var node:Access = cast char.extra.get(exID("node")); - - stage.applyCharStuff(char, charPos.name, 0); - charMap[charPos.name] = char; - } - setZoom(stage.defaultZoom); topMenuSpr = new UITopMenu(topMenu); @@ -319,7 +324,7 @@ class StageEditor extends UIState { stageSpritesWindow.bottomAlpha = 0.5; stageSpritesWindow.buttonSpacing = 0; stageSpritesWindow.dragCallback = (button, oldID, newID) -> { - var sprite:FunkinSprite = button.getSprite(); + var sprite:FlxBasic = (button is StageUnknownButton) ? cast(button, StageUnknownButton).basic : button.getSprite(); var idx = members.indexOf(sprite); members.splice(idx, 1); members.insert(newID, sprite); @@ -354,23 +359,22 @@ class StageEditor extends UIState { } for (i=>sprite in order) { var xml = (sprite != null) ? xmlMap.get(sprite) : orderNodes[i]; - if(xml != null) { - if(sprite is FunkinSprite) { + if (xml != null) { + if (sprite is Character) { + var char:Character = cast sprite; + var button = new StageCharacterButton(0,0, char, xml); + char.extra.set(exID("button"), button); + stageSpritesWindow.add(button); + } else if (sprite is FunkinSprite) { var sprite:FunkinSprite = cast sprite; var type = sprite.extra.get(exID("type")); var button:StageElementButton = (type == "box" || type == "solid") ? new StageSolidButton(0,0, sprite, xml) : new StageSpriteButton(0,0, sprite, xml); sprite.extra.set(exID("button"), button); stageSpritesWindow.add(button); - } - else if(sprite is StageCharPos) { - var charPos:StageCharPos = cast sprite; - var char = charMap[charPos.name]; - var button = new StageCharacterButton(0,0, charPos, xml); - 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); + var basic = new FlxBasic(); // prevent awkward layering + insert(i, basic); + var button = new StageUnknownButton(0,0, basic, xml); stageSpritesWindow.add(button); } } @@ -510,7 +514,7 @@ class StageEditor extends UIState { function _sprite_new(_) { var node:Access = new Access(Xml.createElement("sprite")); stage.stageXML.x.addChild(node.x); - node.att.name = "sprite_" + stageSpritesWindow.buttons.length; + node.att.name = "sprite_" + stageSpritesWindow.buttons.members.length; var sprite:FunkinSprite = new FunkinSprite(); insert(members.indexOf(stage), sprite); @@ -534,16 +538,10 @@ class StageEditor extends UIState { function _character_new(_) { var node:Access = new Access(Xml.createElement("char")); stage.stageXML.x.addChild(node.x); - node.att.name = "character_" + stageSpritesWindow.buttons.length; + node.att.name = "character_" + stageSpritesWindow.buttons.members.length; - var charPos = new StageCharPos(); - charPos.visible = charPos.active = false; - charPos.name = "character_" + stageSpritesWindow.buttons.length; - charPos.extra.set(exID("extraChar"), true); - stage.characterPoses[charPos.name] = charPos; - - var char = new Character(0,0, "bf", stage.isCharFlipped(charPos.name, true), true); - char.name = "bf"; + var char = new Character(0,0, "bf", false, true); + char.name = node.att.name; char.debugMode = true; // Play first anim, and make it the last frame var animToPlay = char.getAnimOrder()[0]; @@ -556,26 +554,25 @@ class StageEditor extends UIState { // Add it to the stage char.visible = true; - char.alpha = 0.5; - function setEx(name:String, value:Dynamic) { - char.extra.set(exID(name), value); - charPos.extra.set(exID(name), value); - } - setEx("node", node); - setEx("pos", charPos); - setEx("char", char); + char.alpha = 0.75; - setEx("parentNode", stage.stageXML); - setEx("highMemory", false); - setEx("lowMemory", false); + char.extra.set(exID("node"), node); + char.extra.set(exID("spacingX"), 20); + char.extra.set(exID("spacingY"), 0); + char.extra.set(exID("camX"), 0); + char.extra.set(exID("camY"), 0); + + char.extra.set(exID("parentNode"), stage.stageXML); + char.extra.set(exID("highMemory"), false); + char.extra.set(exID("lowMemory"), false); + xmlMap.set(char, node); chars.push(char); - stage.applyCharStuff(char, charPos.name, 0); - charMap[charPos.name] = char; + insert(members.indexOf(stage), char); + charMap[node.att.name] = char; - var button = new StageCharacterButton(0,0, charPos, node); + var button = new StageCharacterButton(0,0, char, node); char.extra.set(exID("button"), button); - charPos.extra.set(exID("button"), button); stageSpritesWindow.add(button); } @@ -659,33 +656,26 @@ class StageEditor extends UIState { newNode = spriteXML; } else if(button is StageCharacterButton) { var button:StageCharacterButton = cast button; - var charPos:StageCharPos = button.charPos; - var char:Character = cast charPos.extra.get(exID("char")); - var node:Access = cast charPos.extra.get(exID("node")); - var nodeName = switch(charPos.name) { - case "boyfriend": "boyfriend"; - case "dad": "dad"; - case "girlfriend": "girlfriend"; - default: "character"; - } - var defaultPos = Stage.getDefaultPos(charPos.name); - var charXML:Xml = Xml.createElement(nodeName); - if(nodeName == "character") - saveToXml(charXML, "name", char.curCharacter); - saveToXml(charXML, "x", charPos.x, defaultPos.x); - saveToXml(charXML, "y", charPos.y, defaultPos.y); - saveToXml(charXML, "camxoffset", charPos.camxoffset, 0); - saveToXml(charXML, "camyoffset", charPos.camyoffset, 0); - saveToXml(charXML, "skewx", charPos.skewX, 0); - saveToXml(charXML, "skewy", charPos.skewY, 0); - 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); + var char:Character = button.char; + var node:Access = cast char.extra.get(exID("node")); + var defaultPos = Stage.getDefaultPos(char.name.replace("NO_DELETE_", "")); + var charXML:Xml = Xml.createElement(node.name); + if(!char.name.startsWith("NO_DELETE_")) + saveToXml(charXML, "name", char.name); + saveToXml(charXML, "x", char.x, defaultPos.x); + saveToXml(charXML, "y", char.y, defaultPos.y); + saveToXml(charXML, "camxoffset", char.extra.get(exID("camX")), 0); + saveToXml(charXML, "camyoffset", char.extra.get(exID("camY")), 0); + saveToXml(charXML, "skewx", char.skew.x, 0); + saveToXml(charXML, "skewy", char.skew.y, 0); + saveToXml(charXML, "spacingx", char.extra.get(exID("spacingX")), 20); + saveToXml(charXML, "spacingy", char.extra.get(exID("spacingY")), 0); + saveToXml(charXML, "alpha", char.alpha / 0.75, 1); + saveToXml(charXML, "angle", char.angle, 0); + saveToXml(charXML, "zoomfactor", char.zoomFactor, 1); + saveToXml(charXML, "flipX", char.isPlayer, defaultPos.flip); + savePointToXml(charXML, "scroll", char.scrollFactor, defaultPos.scroll); + savePointToXml(charXML, "scale", char.scale.scaleNew(button.charScale), 1); // TODO: save custom parameters newNode = charXML; } else if(button is StageUnknownButton) { @@ -871,13 +861,13 @@ class StageEditor extends UIState { } function _view_focusdad(_) { - focusCharacter(charMap["dad"]); + focusCharacter(charMap["NO_DELETE_dad"]); } function _view_focusgf(_) { - focusCharacter(charMap["girlfriend"]); + focusCharacter(charMap["NO_DELETE_girlfriend"]); } function _view_focusbf(_) { - focusCharacter(charMap["boyfriend"]); + focusCharacter(charMap["NO_DELETE_boyfriend"]); } function focusCharacter(char:Character) { diff --git a/source/funkin/editors/stage/elements/StageCharacterButton.hx b/source/funkin/editors/stage/elements/StageCharacterButton.hx index d74e8834..bee4d119 100644 --- a/source/funkin/editors/stage/elements/StageCharacterButton.hx +++ b/source/funkin/editors/stage/elements/StageCharacterButton.hx @@ -1,17 +1,19 @@ package funkin.editors.stage.elements; import funkin.editors.stage.StageEditor.StageXMLEditScreen; +import funkin.editors.ui.notifications.UIBaseNotification; +import funkin.editors.ui.UIState; import funkin.game.Character; -import funkin.game.Stage.StageCharPos; import haxe.xml.Access; -class StageCharacterButton extends StageElementButton { - public var charPos:StageCharPos; - public var char:Character; +using StringTools; - public function new(x:Float,y:Float, charPos:StageCharPos, xml:Access) { - this.charPos = charPos; - this.char = charPos.extra.get(StageEditor.exID("char")); +class StageCharacterButton extends StageElementButton { + public var char:Character; + public var charScale(get, null):Float; + + public function new(x:Float,y:Float, char:Character, xml:Access) { + this.char = char; super(x,y, xml); color = 0xff7aa8ff; @@ -27,13 +29,7 @@ class StageCharacterButton extends StageElementButton { public override function updateInfo() { char.visible = !isHidden; - char.alpha = 0.5 * charPos.alpha; - var charScale = (char.xml.has.scale ? Std.parseFloat(char.xml.att.scale).getDefault(1) : 1); - charPos.scale.x = char.scale.x / charScale; - charPos.scale.y = char.scale.y / charScale; - charPos.x = char.x; - charPos.y = char.y; - char.scale.copyFrom(charPos.scale); + char.scale.scale(1 / charScale); super.updateInfo(); char.scale.scale(charScale); } @@ -58,52 +54,69 @@ class StageCharacterButton extends StageElementButton { FlxG.state.openSubState(new StageXMLEditScreen(this.xml, updateInfo, "Character")); } } - //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 onDelete() { + if (char.name.startsWith("NO_DELETE_")) { + var text = "This character position is required in stages!"; + if (char.name == "NO_DELTE_girlfriend" && FlxG.random.bool(1)) + text = "You can't delete Girlfriend"; + UIState.state.displayNotification(new UIBaseNotification(text, 2, BOTTOM_LEFT)); + return; + } + + char.destroy(); + xml.x.parent.removeChild(xml.x); + StageEditor.instance.stage.characterPoses.remove(xml.att.name); + StageEditor.instance.xmlMap.remove(char); + StageEditor.instance.stageSpritesWindow.remove(this); + } + public override function onVisiblityToggle() { isHidden = !isHidden; updateInfo(); } public override function getName():String { - return charPos.name; + return char.name.replace("NO_DELETE_", ""); } public override function getPos():FlxPoint { - return FlxPoint.get(charPos.x, charPos.y); + return FlxPoint.get(char.x, char.y); } public override function updatePos() { super.updatePos(); } + + function get_charScale():Float { + return (char.xml.has.scale ? Std.parseFloat(char.xml.att.scale).getDefault(1) : 1); + } } class StageCharacterEditScreen extends UISoftcodedWindow { public var button:StageCharacterButton; public var char:Character; - public var charPos:StageCharPos; public function new(button:StageCharacterButton) { this.button = button; this.char = button.char; - this.charPos = button.charPos; super("layouts/stage/characterEditScreen", [ "stage" => StageEditor.instance.stage, "char" => char, - "charPos" => charPos, + "charScale" => button.charScale, "button" => button, "xml" => button.xml, "exID" => StageEditor.exID, + "StringTools" => StringTools, "getEx" => function(name:String):Dynamic { return char.extra.get(StageEditor.exID(name)); }, "setEx" => function(name:String, value:Dynamic) { char.extra.set(StageEditor.exID(name), value); - charPos.extra.set(StageEditor.exID(name), value); }, ]); } diff --git a/source/funkin/editors/stage/elements/StageUnknownButton.hx b/source/funkin/editors/stage/elements/StageUnknownButton.hx index 12c8c5d3..a1beb0bc 100644 --- a/source/funkin/editors/stage/elements/StageUnknownButton.hx +++ b/source/funkin/editors/stage/elements/StageUnknownButton.hx @@ -7,8 +7,10 @@ import haxe.xml.Access; class StageUnknownButton extends StageElementButton { public var lowMemory:Bool = false; public var highMemory:Bool = false; + public var basic:FlxBasic; - public function new(x:Float,y:Float, xml:Access) { + public function new(x:Float,y:Float, basic:FlxBasic, xml:Access) { + this.basic = basic; super(x,y, xml); if(xml.x.parent != null) {