Added Stage Info Edit Screen + Bug fixes

This commit is contained in:
NeeEoo
2024-04-17 21:51:10 +02:00
parent f081470554
commit 75e3ab79c5
8 changed files with 130 additions and 177 deletions
@@ -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 =&gt; 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&#10;(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 =&gt; 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 -1
View File
@@ -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" />
+1 -1
View File
@@ -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();
+26 -6
View File
@@ -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);
}*/
}
+7
View File
@@ -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) {