Stage Editor now recognizes unknown elements

Added a unknown element editor
Added angle to sprites and characters
This commit is contained in:
NeeEoo
2024-04-16 17:54:17 +02:00
parent 0e92c664b3
commit 4ca8d66aa6
10 changed files with 183 additions and 43 deletions
+3 -29
View File
@@ -4,33 +4,7 @@
<sprite name="normBG" sprite="stagefront" x="-500" y="100" scale="0.75" updateHitbox="true" />
<sprite name="noUpdateHitbox" sprite="stagefront" x="-500" y="300" scale="0.75" />
<sprite name="ro-tat-ay" sprite="stagefront" x="-500" y="700" scale="0.75" updateHitbox="true" angle="37" />
<!-- oh yeah those exist
where the first one go
you saw the video?
the wha
https://www.youtube.com/watch?v=d6iQrh2TK98
well that explains a bit
whats weird is that i typically think of the number *twenty* seven
guess my favortie number
37
-23.47
interesting
oops
you will be surprised how it looks after me wizard and yosh used it lol, 268kb
also i love how most of nthis files size comes from the convo
37 is a wacky number so im using that for testing
// maybe box? so its colors
wrong format lol (im on stepmania xml)
also just realized i cant scale boxes, you can, just not <solid>
we may need a different func for boxes/solids.
storedScale should still work
and when we save we just have to save either width and scale.x, or calculate the width from the scale
i think we can do sprite.frameWidth * sprite.scale.x when saving boxes luckfully
oh yeah -->
<!-- <box == makeGraphic -->
<!-- <solid == makeSolid -->
<box name="box" x="0" y="0" width="200" height="200" color="0xFF0000" />
<solid name="box2" x="0" y="300" width="200" height="200" color="0x00FF00" />
<unknown-sprite />
</stage>
@@ -49,7 +49,9 @@
<set name="curY" value="camxStepper.y + camxStepper.bHeight + YOFFSET" />
<stepper name="alphaStepper" label="Alpha" value="charPos.alpha" x="col(0)" y="curY" precision="2" step="0.01" width="100" />
<stepper name="zoomFactorStepper" label="Zoom Factor" value="charPos.zoomFactor" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
<stepper name="angleStepper" label="Angle" value="charPos.angle" x="last.x + last.bWidth + XOFFSET - 20" y="curY" precision="2" step="0.01" width="100" />
<stepper name="zoomFactorStepper" label="Zoom Factor" value="charPos.zoomFactor" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
</section>
<section>
@@ -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);
@@ -0,0 +1,39 @@
<window width="310" height="570" title="Editing XML <${button.getName()} />">
<set name="XOFFSET" value="30" />
<set name="YOFFSET" value="40" />
<set name="TO" value="64" />
<exec>
function col(c:Int) {
return 20 + (150 + XOFFSET) * c;
}
</exec>
<title name="title" x="20" y="30 + 16" text="Xml Data" />
<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>
+3
View File
@@ -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)
+18 -6
View File
@@ -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();
}
@@ -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));
@@ -154,6 +154,10 @@ class StageElementButton extends UIButton {
return null;
}
public function canRender() {
return true;
}
public function getName():String {
return "UNKNOWN";
}
@@ -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));
@@ -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();
}
}
+6 -2
View File
@@ -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;
}