Added Stage Info Edit Screen + Bug fixes
This commit is contained in:
@@ -119,6 +119,13 @@
|
||||
button.xml.set(name + "y", y.value);
|
||||
}
|
||||
}
|
||||
function save(name:String, value:Dynamic) {
|
||||
button.xml.remove(name);
|
||||
button.xml.set(name, value);
|
||||
}
|
||||
|
||||
// TODO: remove old attributes to prevent possible errors
|
||||
// button.xml.remove();
|
||||
|
||||
button.xml.set("name", nameTextBox.label.text);
|
||||
button.xml.set("sprite", spriteTextBox.label.text);
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<window width="470" height="620" title="Editing Stage Info '${stage.stageName}'">
|
||||
<set name="MARGIN" value="20" />
|
||||
<set name="XOFFSET" value="50" />
|
||||
<set name="YOFFSET" value="40" />
|
||||
<set name="TO" value="64" />
|
||||
<set name="storedProps" value="[]" />
|
||||
|
||||
<exec>
|
||||
function col(c:Int) {
|
||||
return MARGIN + (170 + XOFFSET) * c;
|
||||
}
|
||||
|
||||
for(prop => val in stage.extra)
|
||||
if(!StringTools.startsWith(prop, "stageEditor."))
|
||||
storedProps.push(prop);
|
||||
</exec>
|
||||
|
||||
<title name="title" x="MARGIN" y="30 + 16" text="Stage Info" />
|
||||
|
||||
<section> <!-- ROW 1 -->
|
||||
<set name="curY" value="title.y + TO" />
|
||||
|
||||
<textbox name="nameTextBox" label="Stage Name" value="stage.stageName" x="col(0)" y="curY" width="200" height="32" />
|
||||
<textbox name="spritePathTextBox" value="stage.spritesParentFolder" x="col(1)" y="curY" width="200" height="32" />
|
||||
<label text="Sprite Path (Needs Refresh)" x="spritePathTextBox.x" y="spritePathTextBox.y - 14" size="15" />
|
||||
</section>
|
||||
|
||||
<section> <!-- ROW 2 -->
|
||||
<set name="curY" value="nameTextBox.y + nameTextBox.bHeight + YOFFSET" />
|
||||
|
||||
<label text="Start Cam Pos (X, Y)" x="col(0)" y="curY" />
|
||||
<stepper name="camxStepper" value="stage.startCam.x" x="col(0)" y="curY" step="1" width="120" />
|
||||
<stepper name="camyStepper" value="stage.startCam.y" x="last.x + last.bWidth + XOFFSET - 30" y="curY" step="1" width="120" />
|
||||
|
||||
<stepper name="zoomStepper" label="Zoom" value="stage.defaultZoom" x="col(1)" y="curY" precision="2" step="0.01" width="100" />
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<set name="curY" value="camxStepper.y + camxStepper.bHeight + YOFFSET" />
|
||||
<set name="listWidth" value="self.winWidth - MARGIN * 2" />
|
||||
|
||||
<buttonlist name="attributesList" label="Custom Attributes" x="col(0)" y="curY" width="listWidth" height="290" buttonSizeX="listWidth-10" buttonSizeY="35" buttonSpacing="5">
|
||||
<texture path="editors/ui/inputbox" />
|
||||
<camSpacing value="0" />
|
||||
|
||||
<code>
|
||||
import funkin.editors.extra.PropertyButton;
|
||||
|
||||
var buttonList = buttonlist; // important for now, since it gets reset after the code is run
|
||||
|
||||
var width = buttonList.buttonSize.x;
|
||||
var height = buttonList.buttonSize.y;
|
||||
|
||||
buttonList.addButton.callback = function() {
|
||||
buttonList.add(new PropertyButton("newProperty", "valueHere", buttonList, width, height, 150, 220, 25));
|
||||
}
|
||||
|
||||
//var defaultAttribs = Stage.DEFAULT_ATTRIBUTES;
|
||||
//for (i in stage.stageXML.attributes()) {
|
||||
// trace(i, defaultAttribs);
|
||||
// if (!defaultAttribs.contains(i))
|
||||
// buttonList.add(new PropertyButton(i, stage.stageXML.get(i), buttonList, width, height, 150, 220, 25));
|
||||
//}
|
||||
for(key => val in stage.extra)
|
||||
buttonList.add(new PropertyButton(key, val, buttonList, width, height, 150, 220, 25));
|
||||
</code>
|
||||
</buttonlist>
|
||||
</section>
|
||||
|
||||
<exec>
|
||||
function onSave() {
|
||||
stage.startCam.x = camxStepper.value;
|
||||
stage.startCam.y = camyStepper.value;
|
||||
stage.defaultZoom = zoomStepper.value;
|
||||
stage.stageName = nameTextBox.label.text;
|
||||
stage.spritesParentFolder = spritePathTextBox.label.text;
|
||||
|
||||
for(prop in storedProps)
|
||||
stage.extra.remove(prop);
|
||||
|
||||
for(prop in attributesList.buttons.members)
|
||||
stage.extra.set(prop.propertyText.label.text, prop.valueText.label.text);
|
||||
}
|
||||
</exec>
|
||||
</window>
|
||||
@@ -56,6 +56,9 @@
|
||||
button.highMemory = highMemoryRadio.checked;
|
||||
button.lowMemory = lowMemoryRadio.checked;
|
||||
|
||||
for (i in xml.attributes())
|
||||
xml.remove(i);
|
||||
|
||||
for (val in attributesList.buttons.members)
|
||||
xml.set(val.propertyText.label.text, val.valueText.label.text);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!-- praying to god we remove this file later on -->
|
||||
|
||||
<stage zoom="0.9" name="stage" folder="stages/default/" startCamPosY="600" startCamPosX="1000">
|
||||
<stage zoom="0.9" name="stage" folder="stages/default/" startCamPosY="600" startCamPosX="1000" example="value">
|
||||
<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" />
|
||||
|
||||
@@ -28,7 +28,7 @@ class WindowUtils {
|
||||
static var __triedClosing:Bool = false;
|
||||
public static inline function resetClosing() __triedClosing = false;
|
||||
|
||||
public static inline function init() {
|
||||
public static function init() {
|
||||
resetTitle();
|
||||
resetClosing();
|
||||
|
||||
|
||||
@@ -96,10 +96,10 @@ class StageEditor extends UIState {
|
||||
}
|
||||
]
|
||||
},
|
||||
/*{
|
||||
{
|
||||
label: "Edit",
|
||||
childs: [
|
||||
{
|
||||
/*{
|
||||
label: "Undo",
|
||||
keybind: [CONTROL, Z],
|
||||
onSelect: _edit_undo,
|
||||
@@ -109,9 +109,25 @@ class StageEditor extends UIState {
|
||||
keybind: [CONTROL, SHIFT, Z],
|
||||
onSelect: _edit_redo,
|
||||
},
|
||||
null,
|
||||
null,*/
|
||||
{
|
||||
label: "Edit Stage Info",
|
||||
onSelect: (_) -> {
|
||||
openSubState(new UISoftcodedWindow(
|
||||
"layouts/stage/stageInfoScreen",
|
||||
[
|
||||
"winTitle" => "Editing Stage Info",
|
||||
"hasSaveButton" => true,
|
||||
"hasCloseButton" => true,
|
||||
"stage" => stage,
|
||||
"Stage" => Stage,
|
||||
"exID" => exID
|
||||
]
|
||||
));
|
||||
},
|
||||
}
|
||||
]
|
||||
},*/
|
||||
},
|
||||
{
|
||||
label: "Select",
|
||||
childs: [
|
||||
@@ -586,6 +602,10 @@ class StageEditor extends UIState {
|
||||
saveToXml(xml, "startCamPosX", stage.startCam.x, 0);
|
||||
saveToXml(xml, "startCamPosY", stage.startCam.y, 0);
|
||||
|
||||
for(prop in stage.extra.keys())
|
||||
if(!Stage.DEFAULT_ATTRIBUTES.contains(prop) && !prop.startsWith("stageEditor."))
|
||||
saveToXml(xml, prop, stage.extra.get(prop));
|
||||
|
||||
var group:Xml = null;
|
||||
var curGroup:String = null;
|
||||
|
||||
@@ -742,11 +762,11 @@ class StageEditor extends UIState {
|
||||
}
|
||||
}*/
|
||||
|
||||
public function editInfoWithUI() {
|
||||
/*public function editInfoWithUI() {
|
||||
FlxG.state.openSubState(new StageInfoScreen(stage, (_) -> {
|
||||
if (_ != null) editInfo(_);
|
||||
}));
|
||||
}
|
||||
}*/
|
||||
|
||||
public function editInfo(newInfo:Xml, addtoUndo:Bool = true) {
|
||||
/*var oldInfo = stage.buildXML();
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
package funkin.editors.stage;
|
||||
|
||||
import flixel.math.FlxPoint;
|
||||
import funkin.editors.extra.PropertyButton;
|
||||
import funkin.game.Stage;
|
||||
import haxe.xml.Access;
|
||||
|
||||
class StageInfoScreen extends UISubstateWindow {
|
||||
public var stage:Stage;
|
||||
|
||||
public var saveButton:UIButton;
|
||||
public var closeButton:UIButton;
|
||||
|
||||
public var onSave:(xml:Xml) -> Void = null;
|
||||
|
||||
public function new(stage:Stage, ?onSave:(xml:Xml) -> Void) {
|
||||
this.stage = stage;
|
||||
this.onSave = onSave;
|
||||
super();
|
||||
}
|
||||
|
||||
public override function create() {
|
||||
winTitle = "Editing Stage";
|
||||
winWidth = 1014;
|
||||
winHeight = 600;
|
||||
|
||||
super.create();
|
||||
|
||||
function addLabelOn(ui:UISprite, text:String)
|
||||
add(new UIText(ui.x, ui.y - 24, 0, text));
|
||||
|
||||
/*var title:UIText;
|
||||
add(title = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, "Sprite Data", 28));
|
||||
|
||||
spriteTextBox = new UITextBox(title.x, title.y + title.height + 38, character.sprite, 200);
|
||||
add(spriteTextBox);
|
||||
addLabelOn(spriteTextBox, "Sprite");
|
||||
|
||||
iconTextBox = new UITextBox(spriteTextBox.x + 200 + 26, spriteTextBox.y, character.getIcon(), 150);
|
||||
iconTextBox.onChange = (newIcon:String) -> {updateIcon(newIcon);}
|
||||
add(iconTextBox);
|
||||
addLabelOn(iconTextBox, "Icon");
|
||||
|
||||
updateIcon(character.getIcon());
|
||||
|
||||
gameOverCharTextBox = new UITextBox(iconTextBox.x + 150 + (75 + 12), iconTextBox.y, character.gameOverCharacter, 200);
|
||||
add(gameOverCharTextBox);
|
||||
addLabelOn(gameOverCharTextBox, "Game Over Character");
|
||||
|
||||
antialiasingCheckbox = new UICheckbox(spriteTextBox.x, spriteTextBox.y + 10 + 32 + 28, "Antialiasing", character.antialiasing);
|
||||
add(antialiasingCheckbox);
|
||||
addLabelOn(antialiasingCheckbox, "Antialiased");
|
||||
|
||||
flipXCheckbox = new UICheckbox(antialiasingCheckbox.x + 172, spriteTextBox.y + 10 + 32 + 28, "FlipX", character.flipX);
|
||||
add(flipXCheckbox);
|
||||
addLabelOn(flipXCheckbox, "Flipped");
|
||||
|
||||
iconColorWheel = new UIColorwheel(gameOverCharTextBox.x + 200 + 20, gameOverCharTextBox.y, character.iconColor);
|
||||
add(iconColorWheel);
|
||||
addLabelOn(iconColorWheel, "Icon Color");
|
||||
|
||||
add(title = new UIText(spriteTextBox.x, spriteTextBox.y + 10 + 46 + 84, 0, "Character Data", 28));
|
||||
|
||||
positionXStepper = new UINumericStepper(title.x, title.y + title.height + 36, character.globalOffset.x, 0.001, 2, null, null, 84);
|
||||
add(positionXStepper);
|
||||
addLabelOn(positionXStepper, "Position (X,Y)");
|
||||
|
||||
add(new UIText(positionXStepper.x + 84 - 32 + 0, positionXStepper.y + 9, 0, ",", 22));
|
||||
|
||||
positionYStepper = new UINumericStepper(positionXStepper.x + 84 - 32 + 26, positionXStepper.y, character.globalOffset.y, 0.001, 2, null, null, 84);
|
||||
add(positionYStepper);
|
||||
|
||||
cameraXStepper = new UINumericStepper(positionYStepper.x + 36 + 84 - 32, positionYStepper.y, character.cameraOffset.x, 0.001, 2, null, null, 84);
|
||||
add(cameraXStepper);
|
||||
addLabelOn(cameraXStepper, "Camera Position (X,Y)");
|
||||
|
||||
add(new UIText(cameraXStepper.x + 84 - 32 + 0, cameraXStepper.y + 9, 0, ",", 22));
|
||||
|
||||
cameraYStepper = new UINumericStepper(cameraXStepper.x + 84 - 32 + 26, cameraXStepper.y, character.cameraOffset.y, 0.001, 2, null, null, 84);
|
||||
add(cameraYStepper);
|
||||
|
||||
scaleStepper = new UINumericStepper(cameraYStepper.x + 84 - 32 + 90, cameraYStepper.y, character.scale.x, 0.001, 2, null, null, 74);
|
||||
add(scaleStepper);
|
||||
addLabelOn(scaleStepper, "Scale");
|
||||
|
||||
singTimeStepper = new UINumericStepper(scaleStepper.x + 74 - 32 + 36, scaleStepper.y, character.holdTime, 0.001, 2, null, null, 74);
|
||||
add(singTimeStepper);
|
||||
addLabelOn(singTimeStepper, "Sing Duration (Steps)");
|
||||
|
||||
customPropertiesButtonList = new UIButtonList<PropertyButton>(singTimeStepper.x + singTimeStepper.width + 200, singTimeStepper.y, 290, 200, '', FlxPoint.get(280, 35), null, 5);
|
||||
customPropertiesButtonList.frames = Paths.getFrames('editors/ui/inputbox');
|
||||
customPropertiesButtonList.cameraSpacing = 0;
|
||||
customPropertiesButtonList.addButton.callback = function() {
|
||||
customPropertiesButtonList.add(new PropertyButton("newProperty", "valueHere", customPropertiesButtonList));
|
||||
}
|
||||
for (prop=>val in character.extra)
|
||||
customPropertiesButtonList.add(new PropertyButton(prop, val, customPropertiesButtonList));
|
||||
add(customPropertiesButtonList);
|
||||
addLabelOn(customPropertiesButtonList, "Custom Values (Advanced)");
|
||||
|
||||
isPlayerCheckbox = new UICheckbox(positionXStepper.x, positionXStepper.y + 10 + 32 + 28, "isPlayer", character.playerOffsets);
|
||||
add(isPlayerCheckbox);
|
||||
addLabelOn(isPlayerCheckbox, "Is Player");
|
||||
|
||||
isGFCheckbox = new UICheckbox(isPlayerCheckbox.x + 128, positionXStepper.y + 10 + 32 + 28, "isGF", character.isGF);
|
||||
add(isGFCheckbox);
|
||||
addLabelOn(isGFCheckbox, "Is GF");
|
||||
|
||||
for (checkbox in [isPlayerCheckbox, isGFCheckbox, antialiasingCheckbox, flipXCheckbox])
|
||||
{checkbox.y += 4; checkbox.x += 6;}*/
|
||||
|
||||
saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20, windowSpr.y + windowSpr.bHeight- 20, "Save & Close", function() {
|
||||
//saveCharacterInfo();
|
||||
close();
|
||||
}, 125);
|
||||
saveButton.x -= saveButton.bWidth;
|
||||
saveButton.y -= saveButton.bHeight;
|
||||
|
||||
closeButton = new UIButton(saveButton.x - 20, saveButton.y, "Close", function() {
|
||||
if (onSave != null) onSave(null);
|
||||
close();
|
||||
}, 125);
|
||||
closeButton.x -= closeButton.bWidth;
|
||||
closeButton.color = 0xFFFF0000;
|
||||
add(closeButton);
|
||||
add(saveButton);
|
||||
}
|
||||
|
||||
/*function saveCharacterInfo() {
|
||||
for (stepper in [positionXStepper, positionYStepper, cameraXStepper, cameraYStepper, singTimeStepper, scaleStepper])
|
||||
@:privateAccess stepper.__onChange(stepper.label.text);
|
||||
|
||||
var xml = Xml.createElement("character");
|
||||
xml.set("isPlayer", isPlayerCheckbox.checked ? "true" : "false");
|
||||
xml.set("isGF", isGFCheckbox.checked ? "true" : "false");
|
||||
xml.set("x", Std.string(positionXStepper.value));
|
||||
xml.set("y", Std.string(positionYStepper.value));
|
||||
xml.set("gameOverChar", gameOverCharTextBox.label.text);
|
||||
xml.set("camx", Std.string(cameraXStepper.value));
|
||||
xml.set("camy", Std.string(cameraYStepper.value));
|
||||
xml.set("holdTime", Std.string(singTimeStepper.value));
|
||||
xml.set("flipX", Std.string(flipXCheckbox.checked));
|
||||
xml.set("icon", iconTextBox.label.text);
|
||||
xml.set("scale", Std.string(scaleStepper.value));
|
||||
xml.set("antialiasing", antialiasingCheckbox.checked ? "true" : "false");
|
||||
xml.set("sprite", spriteTextBox.label.text);
|
||||
if (iconColorWheel.colorChanged)
|
||||
xml.set("color", iconColorWheel.curColor.toWebString());
|
||||
for (val in customPropertiesButtonList.buttons.members)
|
||||
xml.set(val.propertyText.label.text, val.valueText.label.text);
|
||||
|
||||
for (anim in character.animDatas)
|
||||
{
|
||||
var animXml:Xml = Xml.createElement('anim');
|
||||
animXml.set("name", anim.name);
|
||||
animXml.set("anim", anim.anim);
|
||||
animXml.set("loop", Std.string(anim.loop));
|
||||
animXml.set("fps", Std.string(anim.fps));
|
||||
var offset:FlxPoint = character.getAnimOffset(anim.name);
|
||||
animXml.set("x", Std.string(offset.x));
|
||||
animXml.set("y", Std.string(offset.y));
|
||||
if (anim.indices.length > 0)
|
||||
animXml.set("indices", anim.indices.join(","));
|
||||
xml.addChild(animXml);
|
||||
}
|
||||
|
||||
if (onSave != null) onSave(xml);
|
||||
}*/
|
||||
}
|
||||
@@ -57,6 +57,8 @@ class Stage extends FlxBasic implements IBeatReceiver {
|
||||
if (autoLoad) loadXml(stageXML);
|
||||
}
|
||||
|
||||
public static var DEFAULT_ATTRIBUTES:Array<String> = ["name", "startCamPosX", "startCamPosY", "zoom", "folder"];
|
||||
|
||||
public function loadXml(xml:Access, forceLoadAll:Bool = false) {
|
||||
if (PlayState.instance == state) {
|
||||
stageScript = Script.create(Paths.script('data/stages/$stageFile'));
|
||||
@@ -83,6 +85,11 @@ class Stage extends FlxBasic implements IBeatReceiver {
|
||||
if (!spritesParentFolder.endsWith("/")) spritesParentFolder += "/";
|
||||
}
|
||||
|
||||
// Load custom attributes
|
||||
for(att in xml.x.attributes())
|
||||
if(!DEFAULT_ATTRIBUTES.contains(att))
|
||||
extra.set(att, xml.x.get(att));
|
||||
|
||||
var elems:Array<Access> = [];
|
||||
// some way to tag that the sprites are from the group
|
||||
for(node in xml.elements) {
|
||||
|
||||
Reference in New Issue
Block a user