Stage Editor now recognizes unknown elements
Added a unknown element editor Added angle to sprites and characters
This commit is contained in:
@@ -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>
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user