character creatioin tests >:D
This commit is contained in:
@@ -417,7 +417,7 @@ class CharacterAnimButton extends UIButton {
|
||||
|
||||
public function updateText() {
|
||||
field.applyMarkup(
|
||||
'${anim} ' + (valid ? '(${parent.character.animOffsets[anim].x} ${parent.character.animOffsets[anim].y})' : "|(Invalid Animation!!!)|"),
|
||||
'${anim} ' + (valid ? '(${parent.character.animOffsets[anim].x}, ${parent.character.animOffsets[anim].y})' : "|(Invalid Animation!!!)|"),
|
||||
[new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFF29797), "|")]);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
package funkin.editors.character;
|
||||
|
||||
import haxe.xml.Printer;
|
||||
import funkin.game.Character;
|
||||
import funkin.editors.ui.UIImageExplorer.ImageSaveData;
|
||||
import flixel.text.FlxText.FlxTextFormat;
|
||||
import flixel.text.FlxText.FlxTextFormatMarkerPair;
|
||||
|
||||
class CharacterCreationScreen extends UISubstateWindow {
|
||||
private var onSave:(String, ImageSaveData, Xml)-> Void = null;
|
||||
|
||||
public var characterNameTextBox:UITextBox;
|
||||
public var imageExplorer:UIImageExplorer;
|
||||
|
||||
public var saveButton:UIButton;
|
||||
public var closeButton:UIButton;
|
||||
|
||||
public function new(?onSave:(String, ImageSaveData, Xml)->Void) {
|
||||
super();
|
||||
if (onSave != null) this.onSave = onSave;
|
||||
}
|
||||
|
||||
public override function create() {
|
||||
winTitle = "Creating New Character";
|
||||
|
||||
winWidth = 360;
|
||||
winHeight = 520;
|
||||
|
||||
super.create();
|
||||
|
||||
function addLabelOn(ui:UISprite, text:String):UIText {
|
||||
var text:UIText = new UIText(ui.x, ui.y - 24, 0, text);
|
||||
ui.members.push(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
characterNameTextBox = new UITextBox(windowSpr.x + 20, windowSpr.y + 30 + 16 + 20, "character", 320);
|
||||
characterNameTextBox.onChange = (_) -> {checkRequired();};
|
||||
add(characterNameTextBox);
|
||||
addLabelOn(characterNameTextBox, "Character File Name").applyMarkup(
|
||||
"Character File Name $* Required$",
|
||||
[new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFAD1212), "$")]);
|
||||
|
||||
imageExplorer = new UIImageExplorer(characterNameTextBox.x, characterNameTextBox.y + 30 + 16 + 20, null, 320, 58, (_, _) -> {onLoadImage();});
|
||||
add(imageExplorer);
|
||||
addLabelOn(imageExplorer, "Character Image File").applyMarkup(
|
||||
"Character Image File $* Required$",
|
||||
[new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFAD1212), "$")]);
|
||||
imageExplorer.maxSize.y -= 100;
|
||||
|
||||
saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20 - 125, windowSpr.y + windowSpr.bHeight - 16 - 32, "Save & Close", function() {
|
||||
createCharacter();
|
||||
close();
|
||||
}, 125);
|
||||
add(saveButton);
|
||||
|
||||
closeButton = new UIButton(saveButton.x - 20 - saveButton.bWidth, saveButton.y, "Cancel", function() {
|
||||
close();
|
||||
}, 125);
|
||||
add(closeButton);
|
||||
closeButton.color = 0xFFFF0000;
|
||||
|
||||
onLoadImage();
|
||||
}
|
||||
|
||||
public function onLoadImage() {
|
||||
refreshWindowSize();
|
||||
checkRequired();
|
||||
}
|
||||
|
||||
public function refreshWindowSize() {
|
||||
if (imageExplorer == null) return;
|
||||
windowSpr.bWidth = 20 + imageExplorer.bWidth + 20;
|
||||
windowSpr.bHeight = 30 + 16 + 20 + 32 + 30 + 10 + imageExplorer.bHeight + 14 + saveButton.bHeight + 14;
|
||||
|
||||
saveButton.x = windowSpr.x + windowSpr.bWidth - 20 - saveButton.bWidth;
|
||||
closeButton.x = saveButton.x - 20 - closeButton.bWidth;
|
||||
closeButton.y = saveButton.y = imageExplorer.y + imageExplorer.bHeight + 14;
|
||||
}
|
||||
|
||||
public function checkRequired() {
|
||||
saveButton.selectable = characterNameTextBox.label.text.length > 0 && !CoolUtil.isMapEmpty(imageExplorer.imageFiles) && (imageExplorer.animationList.length > 0);
|
||||
}
|
||||
|
||||
public function createCharacter() {
|
||||
var imageSaveData:ImageSaveData = imageExplorer.getSaveData();
|
||||
|
||||
var xml:Xml = Xml.createElement("character");
|
||||
xml.attributeOrder = Character.characterProperties.copy();
|
||||
|
||||
xml.set("sprite", imageSaveData.imageName);
|
||||
|
||||
// Look for animations >:D
|
||||
var animationList:Array<String> = imageExplorer.animationList.copy();
|
||||
animationList.sort((a, b) -> {
|
||||
var lengthCompare = a.length - b.length;
|
||||
if (lengthCompare != 0) return lengthCompare;
|
||||
|
||||
// Miss animations don't show up as regular if they are the same length as regular >:D
|
||||
var aIsMiss = a.toLowerCase().contains("miss");
|
||||
var bIsMiss = b.toLowerCase().contains("miss");
|
||||
return aIsMiss == bIsMiss ? 0 : (aIsMiss ? 1 : -1);
|
||||
});
|
||||
|
||||
var animationsFound:Map<String, String> = [
|
||||
"singLEFT" => null,
|
||||
"singRIGHT" => null,
|
||||
"singUP" => null,
|
||||
"singDOWN" => null,
|
||||
"idle" => null
|
||||
];
|
||||
|
||||
for (anim => found in animationsFound) {
|
||||
var animToLookFor:String = StringTools.replace(anim, "sing", "").toLowerCase();
|
||||
for (imageAnim in animationList)
|
||||
if (imageAnim.toLowerCase().contains(animToLookFor)) {
|
||||
animationsFound.set(anim, imageAnim);
|
||||
animationList.remove(imageAnim);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add said animations >:D
|
||||
for (anim => found in animationsFound) {
|
||||
var animXml:Xml = Xml.createElement('anim');
|
||||
animXml.attributeOrder = Character.characterAnimProperties;
|
||||
|
||||
animXml.set("name", anim);
|
||||
animXml.set("anim", found.getDefault(animationList[0]));
|
||||
|
||||
xml.addChild(animXml);
|
||||
}
|
||||
|
||||
// Do the rest only if not atlas (until we make it animations and not symbols >:D)
|
||||
if (!imageSaveData.isAtlas) {
|
||||
for (imageAnim in animationList) {
|
||||
var animXml:Xml = Xml.createElement('anim');
|
||||
animXml.attributeOrder = Character.characterAnimProperties;
|
||||
|
||||
animXml.set("name", imageAnim);
|
||||
animXml.set("anim", imageAnim);
|
||||
|
||||
xml.addChild(animXml);
|
||||
}
|
||||
}
|
||||
|
||||
if (onSave != null) onSave(characterNameTextBox.label.text, imageSaveData, xml);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package funkin.editors.character;
|
||||
|
||||
import haxe.xml.Printer;
|
||||
import funkin.editors.ui.UIImageExplorer.ImageSaveData;
|
||||
import funkin.game.Character;
|
||||
import funkin.options.OptionsScreen;
|
||||
import funkin.options.type.IconOption;
|
||||
@@ -44,9 +46,7 @@ class CharacterSelection extends EditorTreeMenu
|
||||
}
|
||||
|
||||
list.insert(0, new NewOption("New Character", "New Character", function() {
|
||||
openSubState(new UIWarningSubstate("New Character: Feature Not Implemented!", "This feature isn't implemented yet. Please wait for more cne updates to have this functional.\n\n\n- Codename Devs", [
|
||||
{label: "Ok", color: 0xFFFF0000, onClick: function(t) {}}
|
||||
]));
|
||||
openSubState(new CharacterCreationScreen(createCharacter));
|
||||
}));
|
||||
|
||||
return list;
|
||||
@@ -64,4 +64,30 @@ class CharacterSelection extends EditorTreeMenu
|
||||
|
||||
main.changeSelection(1);
|
||||
}
|
||||
|
||||
public function createCharacter(name:String, imageSaveData:ImageSaveData, xml:Xml) {
|
||||
var characterAlreadyExists:Bool = Character.getList().contains(name);
|
||||
|
||||
if (characterAlreadyExists) {
|
||||
openSubState(new UIWarningSubstate("Creating Character: Error!", "The character you are trying to create already exists, if you would like to override it delete the character first!", [
|
||||
{label: "Ok", color: 0xFFFF0000, onClick: function(t) {}}
|
||||
]));
|
||||
return;
|
||||
}
|
||||
|
||||
// Save Data file
|
||||
var characterPath:String = '${Paths.getAssetsRoot()}/data/characters/${name}.xml';
|
||||
CoolUtil.safeSaveFile(characterPath, "<!DOCTYPE codename-engine-character>\n" + Printer.print(xml, true));
|
||||
|
||||
// Save Image files
|
||||
UIImageExplorer.saveFilesGlobal(imageSaveData, '${Paths.getAssetsRoot()}/images/characters');
|
||||
|
||||
// Add to Menu >:D
|
||||
var option:IconOption = new IconOption(name, "Press ACCEPT to edit this character.", Character.getIconFromCharName(name),
|
||||
function() {
|
||||
FlxG.switchState(new CharacterEditor(name));
|
||||
}
|
||||
);
|
||||
optionsTree.members[optionsTree.members.length-1].insert(1, option);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user