package editors; #if desktop import Discord.DiscordClient; #end import flixel.FlxG; import flixel.FlxObject; import flixel.FlxSprite; import flixel.FlxState; import flixel.FlxCamera; import flixel.input.keyboard.FlxKey; import flixel.addons.display.FlxGridOverlay; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.graphics.FlxGraphic; import flixel.text.FlxText; import flixel.util.FlxColor; import flixel.addons.ui.FlxInputText; import flixel.addons.ui.FlxUI9SliceSprite; import flixel.addons.ui.FlxUI; import flixel.addons.ui.FlxUICheckBox; import flixel.addons.ui.FlxUIInputText; import flixel.addons.ui.FlxUINumericStepper; import flixel.addons.ui.FlxUITabMenu; import flixel.addons.ui.FlxUITooltip.FlxUITooltipStyle; import flixel.ui.FlxButton; import flixel.ui.FlxSpriteButton; import openfl.net.FileReference; import openfl.events.Event; import openfl.events.IOErrorEvent; import haxe.Json; import Character; import flixel.system.debug.interaction.tools.Pointer.GraphicCursorCross; import lime.system.Clipboard; import flixel.animation.FlxAnimation; #if MODS_ALLOWED import sys.FileSystem; #end using StringTools; /** *DEBUG MODE */ class CharacterEditorState extends MusicBeatState { var char:Character; var ghostChar:Character; var textAnim:FlxText; var bgLayer:FlxTypedGroup; var charLayer:FlxTypedGroup; var dumbTexts:FlxTypedGroup; //var animList:Array = []; var curAnim:Int = 0; var daAnim:String = 'spooky'; var goToPlayState:Bool = true; var camFollow:FlxObject; public function new(daAnim:String = 'spooky', goToPlayState:Bool = true) { super(); this.daAnim = daAnim; this.goToPlayState = goToPlayState; } var UI_box:FlxUITabMenu; var UI_characterbox:FlxUITabMenu; private var camEditor:FlxCamera; private var camHUD:FlxCamera; private var camMenu:FlxCamera; var changeBGbutton:FlxButton; var leHealthIcon:HealthIcon; var characterList:Array = []; var cameraFollowPointer:FlxSprite; var healthBarBG:FlxSprite; override function create() { //FlxG.sound.playMusic(Paths.music('breakfast'), 0.5); camEditor = new FlxCamera(); camHUD = new FlxCamera(); camHUD.bgColor.alpha = 0; camMenu = new FlxCamera(); camMenu.bgColor.alpha = 0; FlxG.cameras.reset(camEditor); FlxG.cameras.add(camHUD); FlxG.cameras.add(camMenu); FlxCamera.defaultCameras = [camEditor]; bgLayer = new FlxTypedGroup(); add(bgLayer); charLayer = new FlxTypedGroup(); add(charLayer); var pointer:FlxGraphic = FlxGraphic.fromClass(GraphicCursorCross); cameraFollowPointer = new FlxSprite().loadGraphic(pointer); cameraFollowPointer.setGraphicSize(40, 40); cameraFollowPointer.updateHitbox(); cameraFollowPointer.color = FlxColor.WHITE; add(cameraFollowPointer); changeBGbutton = new FlxButton(FlxG.width - 360, 25, "", function() { onPixelBG = !onPixelBG; reloadBGs(); }); changeBGbutton.cameras = [camMenu]; loadChar(!daAnim.startsWith('bf'), false); healthBarBG = new FlxSprite(30, FlxG.height - 75).loadGraphic(Paths.image('healthBar')); healthBarBG.scrollFactor.set(); add(healthBarBG); healthBarBG.cameras = [camHUD]; leHealthIcon = new HealthIcon(char.healthIcon, false); leHealthIcon.y = FlxG.height - 150; add(leHealthIcon); leHealthIcon.cameras = [camHUD]; dumbTexts = new FlxTypedGroup(); add(dumbTexts); dumbTexts.cameras = [camHUD]; textAnim = new FlxText(300, 16); textAnim.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, RIGHT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); textAnim.borderSize = 1; textAnim.size = 32; textAnim.scrollFactor.set(); textAnim.cameras = [camHUD]; add(textAnim); genBoyOffsets(); camFollow = new FlxObject(0, 0, 2, 2); camFollow.screenCenter(); add(camFollow); var tipText:FlxText = new FlxText(FlxG.width - 20, FlxG.height, 0, "E/Q - Camera Zoom In/Out \nJKLI - Move Camera \nW/S - Previous/Next Animation \nSpace - Play Animation \nArrow Keys - Move Character Offset \nHold Shift to Move 10x faster\n", 12); tipText.cameras = [camHUD]; tipText.setFormat(null, 12, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); tipText.scrollFactor.set(); tipText.borderSize = 1; tipText.x -= tipText.width; tipText.y -= tipText.height - 10; add(tipText); FlxG.camera.follow(camFollow); var tabs = [ //{name: 'Offsets', label: 'Offsets'}, {name: 'Settings', label: 'Settings'}, ]; UI_box = new FlxUITabMenu(null, tabs, true); UI_box.cameras = [camMenu]; UI_box.resize(250, 120); UI_box.x = FlxG.width - 275; UI_box.y = 25; UI_box.scrollFactor.set(); var tabs = [ {name: 'Character', label: 'Character'}, {name: 'Animations', label: 'Animations'}, ]; UI_characterbox = new FlxUITabMenu(null, tabs, true); UI_characterbox.cameras = [camMenu]; UI_characterbox.resize(350, 250); UI_characterbox.x = UI_box.x - 100; UI_characterbox.y = UI_box.y + UI_box.height; UI_characterbox.scrollFactor.set(); add(UI_characterbox); add(UI_box); add(changeBGbutton); //addOffsetsUI(); addSettingsUI(); addCharacterUI(); addAnimationsUI(); UI_characterbox.selected_tab_id = 'Character'; FlxG.mouse.visible = true; reloadCharacterOptions(); super.create(); } var onPixelBG:Bool = false; var OFFSET_X:Float = 300; function reloadBGs() { var i:Int = bgLayer.members.length-1; while(i >= 0) { var memb:FlxSprite = bgLayer.members[i]; if(memb != null) { memb.kill(); bgLayer.remove(memb); memb.destroy(); } --i; } bgLayer.clear(); var playerXDifference = 0; if(char.isPlayer) playerXDifference = 670; if(onPixelBG) { var playerYDifference:Float = 0; if(char.isPlayer) { playerXDifference += 200; playerYDifference = 220; } var bgSky:BGSprite = new BGSprite('weeb/weebSky', OFFSET_X - (playerXDifference / 2) - 300, 0 - playerYDifference, 0.1, 0.1); bgLayer.add(bgSky); bgSky.antialiasing = false; var repositionShit = -200 + OFFSET_X - playerXDifference; var bgSchool:BGSprite = new BGSprite('weeb/weebSchool', repositionShit, -playerYDifference + 6, 0.6, 0.90); bgLayer.add(bgSchool); bgSchool.antialiasing = false; var bgStreet:BGSprite = new BGSprite('weeb/weebStreet', repositionShit, -playerYDifference, 0.95, 0.95); bgLayer.add(bgStreet); bgStreet.antialiasing = false; var widShit = Std.int(bgSky.width * 6); var bgTrees:FlxSprite = new FlxSprite(repositionShit - 380, -800 - playerYDifference); bgTrees.frames = Paths.getPackerAtlas('weeb/weebTrees'); bgTrees.animation.add('treeLoop', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], 12); bgTrees.animation.play('treeLoop'); bgTrees.scrollFactor.set(0.85, 0.85); bgLayer.add(bgTrees); bgTrees.antialiasing = false; bgSky.setGraphicSize(widShit); bgSchool.setGraphicSize(widShit); bgStreet.setGraphicSize(widShit); bgTrees.setGraphicSize(Std.int(widShit * 1.4)); bgSky.updateHitbox(); bgSchool.updateHitbox(); bgStreet.updateHitbox(); bgTrees.updateHitbox(); changeBGbutton.text = "Regular BG"; } else { var bg:BGSprite = new BGSprite('stageback', -600 + OFFSET_X - playerXDifference, -300, 0.9, 0.9); bgLayer.add(bg); var stageFront:BGSprite = new BGSprite('stagefront', -650 + OFFSET_X - playerXDifference, 500, 0.9, 0.9); stageFront.setGraphicSize(Std.int(stageFront.width * 1.1)); stageFront.updateHitbox(); bgLayer.add(stageFront); changeBGbutton.text = "Pixel BG"; } } /*var animationInputText:FlxUIInputText; function addOffsetsUI() { var tab_group = new FlxUI(null, UI_box); tab_group.name = "Offsets"; animationInputText = new FlxUIInputText(15, 30, 100, 'idle', 8); var addButton:FlxButton = new FlxButton(animationInputText.x + animationInputText.width + 23, animationInputText.y - 2, "Add", function() { var theText:String = animationInputText.text; if(theText != '') { var alreadyExists:Bool = false; for (i in 0...animList.length) { if(animList[i] == theText) { alreadyExists = true; break; } } if(!alreadyExists) { char.animOffsets.set(theText, [0, 0]); animList.push(theText); } } }); var removeButton:FlxButton = new FlxButton(animationInputText.x + animationInputText.width + 23, animationInputText.y + 20, "Remove", function() { var theText:String = animationInputText.text; if(theText != '') { for (i in 0...animList.length) { if(animList[i] == theText) { if(char.animOffsets.exists(theText)) { char.animOffsets.remove(theText); } animList.remove(theText); if(char.animation.curAnim.name == theText && animList.length > 0) { char.playAnim(animList[0], true); } break; } } } }); var saveButton:FlxButton = new FlxButton(animationInputText.x, animationInputText.y + 35, "Save Offsets", function() { saveOffsets(); }); tab_group.add(new FlxText(10, animationInputText.y - 18, 0, 'Add/Remove Animation:')); tab_group.add(addButton); tab_group.add(removeButton); tab_group.add(saveButton); tab_group.add(animationInputText); UI_box.addGroup(tab_group); }*/ var charDropDown:FlxUIDropDownMenuCustom; function addSettingsUI() { var tab_group = new FlxUI(null, UI_box); tab_group.name = "Settings"; var check_player = new FlxUICheckBox(10, 60, null, null, "Playable Character", 100); check_player.checked = daAnim.startsWith('bf'); check_player.callback = function() { char.isPlayer = !char.isPlayer; char.flipX = !char.flipX; updatePointerPos(); reloadBGs(); ghostChar.flipX = char.flipX; }; charDropDown = new FlxUIDropDownMenuCustom(10, 30, FlxUIDropDownMenuCustom.makeStrIdLabelArray([''], true), function(character:String) { daAnim = characterList[Std.parseInt(character)]; check_player.checked = daAnim.startsWith('bf'); loadChar(!check_player.checked); updatePresence(); reloadCharacterDropDown(); }); charDropDown.selectedLabel = daAnim; reloadCharacterDropDown(); var reloadCharacter:FlxButton = new FlxButton(140, 30, "Reload Char", function() { loadChar(!check_player.checked); reloadCharacterDropDown(); }); tab_group.add(new FlxText(charDropDown.x, charDropDown.y - 18, 0, 'Character:')); tab_group.add(check_player); tab_group.add(reloadCharacter); tab_group.add(charDropDown); tab_group.add(reloadCharacter); UI_box.addGroup(tab_group); } var imageInputText:FlxUIInputText; var healthIconInputText:FlxUIInputText; var singDurationStepper:FlxUINumericStepper; var scaleStepper:FlxUINumericStepper; var positionXStepper:FlxUINumericStepper; var positionYStepper:FlxUINumericStepper; var positionCameraXStepper:FlxUINumericStepper; var positionCameraYStepper:FlxUINumericStepper; var flipXCheckBox:FlxUICheckBox; var noAntialiasingCheckBox:FlxUICheckBox; var healthColorStepperR:FlxUINumericStepper; var healthColorStepperG:FlxUINumericStepper; var healthColorStepperB:FlxUINumericStepper; function addCharacterUI() { var tab_group = new FlxUI(null, UI_box); tab_group.name = "Character"; imageInputText = new FlxUIInputText(15, 30, 200, 'characters/BOYFRIEND', 8); var reloadImage:FlxButton = new FlxButton(imageInputText.x + 210, imageInputText.y - 3, "Reload Image", function() { char.imageFile = imageInputText.text; reloadCharacterImage(); if(char.animation.curAnim != null) { char.playAnim(char.animation.curAnim.name, true); } }); healthIconInputText = new FlxUIInputText(15, imageInputText.y + 35, 75, leHealthIcon.getCharacter(), 8); singDurationStepper = new FlxUINumericStepper(15, healthIconInputText.y + 45, 0.1, 4, 0, 999, 1); scaleStepper = new FlxUINumericStepper(15, singDurationStepper.y + 40, 0.1, 1, 0.05, 10, 1); flipXCheckBox = new FlxUICheckBox(singDurationStepper.x + 80, singDurationStepper.y, null, null, "Flip X", 50); flipXCheckBox.checked = char.flipX; if(char.isPlayer) flipXCheckBox.checked = !flipXCheckBox.checked; flipXCheckBox.callback = function() { char.originalFlipX = !char.originalFlipX; char.flipX = char.originalFlipX; if(char.isPlayer) char.flipX = !char.flipX; ghostChar.flipX = char.flipX; }; noAntialiasingCheckBox = new FlxUICheckBox(flipXCheckBox.x, flipXCheckBox.y + 40, null, null, "No Antialiasing", 80); noAntialiasingCheckBox.checked = char.noAntialiasing; noAntialiasingCheckBox.callback = function() { char.antialiasing = false; if(!noAntialiasingCheckBox.checked && ClientPrefs.globalAntialiasing) { char.antialiasing = true; } char.noAntialiasing = noAntialiasingCheckBox.checked; }; positionXStepper = new FlxUINumericStepper(flipXCheckBox.x + 110, flipXCheckBox.y, 10, char.positionArray[0], -9000, 9000, 0); positionYStepper = new FlxUINumericStepper(positionXStepper.x + 60, positionXStepper.y, 10, char.positionArray[1], -9000, 9000, 0); positionCameraXStepper = new FlxUINumericStepper(positionXStepper.x, positionXStepper.y + 40, 10, char.cameraPosition[0], -9000, 9000, 0); positionCameraYStepper = new FlxUINumericStepper(positionYStepper.x, positionYStepper.y + 40, 10, char.cameraPosition[1], -9000, 9000, 0); var saveCharacterButton:FlxButton = new FlxButton(reloadImage.x, noAntialiasingCheckBox.y + 40, "Save Character", function() { saveCharacter(); }); healthColorStepperR = new FlxUINumericStepper(singDurationStepper.x, saveCharacterButton.y, 20, char.healthColorArray[0], 0, 255, 0); healthColorStepperG = new FlxUINumericStepper(singDurationStepper.x + 65, saveCharacterButton.y, 20, char.healthColorArray[1], 0, 255, 0); healthColorStepperB = new FlxUINumericStepper(singDurationStepper.x + 130, saveCharacterButton.y, 20, char.healthColorArray[2], 0, 255, 0); tab_group.add(new FlxText(15, imageInputText.y - 18, 0, 'Image file name:')); tab_group.add(new FlxText(15, healthIconInputText.y - 18, 0, 'Health icon name:')); tab_group.add(new FlxText(15, singDurationStepper.y - 18, 0, 'Sing Animation length:')); tab_group.add(new FlxText(15, scaleStepper.y - 18, 0, 'Scale:')); tab_group.add(new FlxText(positionXStepper.x, positionXStepper.y - 18, 0, 'Character X/Y:')); tab_group.add(new FlxText(positionCameraXStepper.x, positionCameraXStepper.y - 18, 0, 'Camera X/Y:')); tab_group.add(new FlxText(healthColorStepperR.x, healthColorStepperR.y - 18, 0, 'Health bar R/G/B:')); tab_group.add(imageInputText); tab_group.add(reloadImage); tab_group.add(healthIconInputText); tab_group.add(singDurationStepper); tab_group.add(scaleStepper); tab_group.add(flipXCheckBox); tab_group.add(noAntialiasingCheckBox); tab_group.add(positionXStepper); tab_group.add(positionYStepper); tab_group.add(positionCameraXStepper); tab_group.add(positionCameraYStepper); tab_group.add(healthColorStepperR); tab_group.add(healthColorStepperG); tab_group.add(healthColorStepperB); tab_group.add(saveCharacterButton); UI_characterbox.addGroup(tab_group); } var ghostDropDown:FlxUIDropDownMenuCustom; var animationDropDown:FlxUIDropDownMenuCustom; var animationInputText:FlxUIInputText; var animationNameInputText:FlxUIInputText; var animationIndicesInputText:FlxUIInputText; var animationNameFramerate:FlxUINumericStepper; var animationLoopCheckBox:FlxUICheckBox; function addAnimationsUI() { var tab_group = new FlxUI(null, UI_box); tab_group.name = "Animations"; animationInputText = new FlxUIInputText(15, 85, 80, '', 8); animationNameInputText = new FlxUIInputText(animationInputText.x, animationInputText.y + 35, 150, '', 8); animationIndicesInputText = new FlxUIInputText(animationNameInputText.x, animationNameInputText.y + 40, 250, '', 8); animationNameFramerate = new FlxUINumericStepper(animationInputText.x + 170, animationInputText.y, 1, 24, 0, 240, 0); animationLoopCheckBox = new FlxUICheckBox(animationNameInputText.x + 170, animationNameInputText.y - 1, null, null, "Should it Loop?", 100); animationDropDown = new FlxUIDropDownMenuCustom(15, animationInputText.y - 55, FlxUIDropDownMenuCustom.makeStrIdLabelArray([''], true), function(pressed:String) { var selectedAnimation:Int = Std.parseInt(pressed); var anim:AnimArray = char.animationsArray[selectedAnimation]; animationInputText.text = anim.anim; animationNameInputText.text = anim.name; animationLoopCheckBox.checked = anim.loop; animationNameFramerate.value = anim.fps; var indicesStr:String = anim.indices.toString(); animationIndicesInputText.text = indicesStr.substr(1, indicesStr.length - 2); }); ghostDropDown = new FlxUIDropDownMenuCustom(animationDropDown.x + 150, animationDropDown.y, FlxUIDropDownMenuCustom.makeStrIdLabelArray([''], true), function(pressed:String) { var selectedAnimation:Int = Std.parseInt(pressed); ghostChar.visible = false; char.alpha = 1; if(selectedAnimation > 0) { ghostChar.visible = true; ghostChar.playAnim(ghostChar.animationsArray[selectedAnimation-1].anim, true); char.alpha = 0.85; } }); var addUpdateButton:FlxButton = new FlxButton(70, animationIndicesInputText.y + 30, "Add/Update", function() { var indices:Array = []; var indicesStr:Array = animationIndicesInputText.text.trim().split(','); if(indicesStr.length > 1) { for (i in 0...indicesStr.length) { var index:Int = Std.parseInt(indicesStr[i]); if(indicesStr[i] != null && indicesStr[i] != '' && !Math.isNaN(index) && index > -1) { indices.push(index); } } } var lastAnim:String = ''; if(char.animationsArray[curAnim] != null) { lastAnim = char.animationsArray[curAnim].anim; } var lastOffsets:Array = [0, 0]; for (anim in char.animationsArray) { if(animationInputText.text == anim.anim) { lastOffsets = anim.offsets; if(char.animation.getByName(animationInputText.text) != null) { char.animation.remove(animationInputText.text); } char.animationsArray.remove(anim); } } var newAnim:AnimArray = { anim: animationInputText.text, name: animationNameInputText.text, fps: Math.round(animationNameFramerate.value), loop: animationLoopCheckBox.checked, indices: indices, offsets: lastOffsets }; if(indices != null && indices.length > 0) { char.animation.addByIndices(newAnim.anim, newAnim.name, newAnim.indices, "", newAnim.fps, newAnim.loop); } else { char.animation.addByPrefix(newAnim.anim, newAnim.name, newAnim.fps, newAnim.loop); } if(!char.animOffsets.exists(newAnim.anim)) { char.addOffset(newAnim.anim, 0, 0); } char.animationsArray.push(newAnim); if(lastAnim == animationInputText.text) { var leAnim:FlxAnimation = char.animation.getByName(lastAnim); if(leAnim != null && leAnim.frames.length > 0) { char.playAnim(lastAnim, true); } else { for(i in 0...char.animationsArray.length) { if(char.animationsArray[i] != null) { leAnim = char.animation.getByName(char.animationsArray[i].anim); if(leAnim != null && leAnim.frames.length > 0) { char.playAnim(char.animationsArray[i].anim, true); curAnim = i; break; } } } } } reloadAnimationDropDown(); genBoyOffsets(); trace('Added/Updated animation: ' + animationInputText.text); }); var removeButton:FlxButton = new FlxButton(180, animationIndicesInputText.y + 30, "Remove", function() { for (anim in char.animationsArray) { if(animationInputText.text == anim.anim) { var resetAnim:Bool = false; if(char.animation.curAnim != null && anim.anim == char.animation.curAnim.name) resetAnim = true; if(char.animation.getByName(anim.anim) != null) { char.animation.remove(anim.anim); } if(char.animOffsets.exists(anim.anim)) { char.animOffsets.remove(anim.anim); } char.animationsArray.remove(anim); if(resetAnim && char.animationsArray.length > 0) { char.playAnim(char.animationsArray[0].anim, true); } reloadAnimationDropDown(); genBoyOffsets(); trace('Removed animation: ' + animationInputText.text); break; } } }); tab_group.add(new FlxText(animationDropDown.x, animationDropDown.y - 18, 0, 'Animations:')); tab_group.add(new FlxText(ghostDropDown.x, ghostDropDown.y - 18, 0, 'Animation Ghost:')); tab_group.add(new FlxText(animationInputText.x, animationInputText.y - 18, 0, 'Animation name:')); tab_group.add(new FlxText(animationNameFramerate.x, animationNameFramerate.y - 18, 0, 'Framerate:')); tab_group.add(new FlxText(animationNameInputText.x, animationNameInputText.y - 18, 0, 'Animation on .XML/.TXT file:')); tab_group.add(new FlxText(animationIndicesInputText.x, animationIndicesInputText.y - 18, 0, 'ADVANCED - Animation Indices:')); tab_group.add(animationInputText); tab_group.add(animationNameInputText); tab_group.add(animationIndicesInputText); tab_group.add(animationNameFramerate); tab_group.add(animationLoopCheckBox); tab_group.add(addUpdateButton); tab_group.add(removeButton); tab_group.add(ghostDropDown); tab_group.add(animationDropDown); UI_characterbox.addGroup(tab_group); } override function getEvent(id:String, sender:Dynamic, data:Dynamic, ?params:Array) { if(id == FlxUIInputText.CHANGE_EVENT && (sender is FlxUIInputText)) { if(sender == healthIconInputText) { leHealthIcon.changeIcon(healthIconInputText.text); char.healthIcon = healthIconInputText.text; updatePresence(); } else if(sender == imageInputText) { char.imageFile = imageInputText.text; } } else if(id == FlxUINumericStepper.CHANGE_EVENT && (sender is FlxUINumericStepper)) { if (sender == scaleStepper) { reloadCharacterImage(); char.jsonScale = sender.value; char.setGraphicSize(Std.int(char.width * char.jsonScale)); char.updateHitbox(); reloadGhost(); updatePointerPos(); if(char.animation.curAnim != null) { char.playAnim(char.animation.curAnim.name, true); } } else if(sender == positionXStepper) { char.positionArray[0] = positionXStepper.value; char.x = char.positionArray[0] + OFFSET_X + 100; updatePointerPos(); } else if(sender == positionYStepper) { char.positionArray[1] = positionYStepper.value; char.y = char.positionArray[1]; updatePointerPos(); } else if(sender == positionCameraXStepper) { char.cameraPosition[0] = positionCameraXStepper.value; updatePointerPos(); } else if(sender == positionCameraYStepper) { char.cameraPosition[1] = positionCameraYStepper.value; updatePointerPos(); } else if(sender == healthColorStepperR) { char.healthColorArray[0] = Math.round(healthColorStepperR.value); healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); } else if(sender == healthColorStepperG) { char.healthColorArray[1] = Math.round(healthColorStepperG.value); healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); } else if(sender == healthColorStepperB) { char.healthColorArray[2] = Math.round(healthColorStepperB.value); healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); } } } function reloadCharacterImage() { var lastAnim:String = ''; if(char.animation.curAnim != null) { lastAnim = char.animation.curAnim.name; } var anims:Array = char.animationsArray.copy(); if(Paths.fileExists('images/' + char.imageFile + '.txt', TEXT)) { char.frames = Paths.getPackerAtlas(char.imageFile); } else { char.frames = Paths.getSparrowAtlas(char.imageFile); } if(char.animationsArray != null && char.animationsArray.length > 0) { for (anim in char.animationsArray) { var animAnim:String = '' + anim.anim; var animName:String = '' + anim.name; var animFps:Int = anim.fps; var animLoop:Bool = !!anim.loop; //Bruh var animIndices:Array = anim.indices; if(animIndices != null && animIndices.length > 0) { char.animation.addByIndices(animAnim, animName, animIndices, "", animFps, animLoop); } else { char.animation.addByPrefix(animAnim, animName, animFps, animLoop); } } } else { char.quickAnimAdd('idle', 'BF idle dance'); } if(lastAnim != '') { char.playAnim(lastAnim, true); } else { char.dance(); } ghostDropDown.selectedLabel = ''; reloadGhost(); } function genBoyOffsets():Void { var daLoop:Int = 0; var i:Int = dumbTexts.members.length-1; while(i >= 0) { var memb:FlxText = dumbTexts.members[i]; if(memb != null) { memb.kill(); dumbTexts.remove(memb); memb.destroy(); } --i; } dumbTexts.clear(); for (anim => offsets in char.animOffsets) { var text:FlxText = new FlxText(10, 20 + (18 * daLoop), 0, anim + ": " + offsets, 15); text.setFormat(null, 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK); text.scrollFactor.set(); text.borderSize = 1; dumbTexts.add(text); text.cameras = [camHUD]; daLoop++; } textAnim.visible = true; if(dumbTexts.length < 1) { var text:FlxText = new FlxText(10, 38, 0, "ERROR! No animations found.", 15); text.scrollFactor.set(); text.borderSize = 1; dumbTexts.add(text); textAnim.visible = false; } } function loadChar(isDad:Bool, blahBlahBlah:Bool = true) { var i:Int = charLayer.members.length-1; while(i >= 0) { var memb:Character = charLayer.members[i]; if(memb != null) { memb.kill(); charLayer.remove(memb); memb.destroy(); } --i; } charLayer.clear(); ghostChar = new Character(0, 0, daAnim, !isDad); ghostChar.screenCenter(); ghostChar.debugMode = true; ghostChar.alpha = 0.6; char = new Character(0, 0, daAnim, !isDad); if(char.animationsArray[0] != null) { char.playAnim(char.animationsArray[0].anim, true); } char.screenCenter(); char.debugMode = true; charLayer.add(ghostChar); charLayer.add(char); char.setPosition(char.positionArray[0] + OFFSET_X + 100, char.positionArray[1]); /* THIS FUNCTION WAS USED TO PUT THE .TXT OFFSETS INTO THE .JSON for (anim => offset in char.animOffsets) { var leAnim:AnimArray = findAnimationByName(anim); if(leAnim != null) { leAnim.offsets = [offset[0], offset[1]]; } }*/ if(blahBlahBlah) { genBoyOffsets(); } reloadCharacterOptions(); reloadBGs(); updatePointerPos(); } function updatePointerPos() { var x:Float = char.getMidpoint().x; var y:Float = char.getMidpoint().y; if(!char.isPlayer) { x += 150 + char.cameraPosition[0]; } else { x -= 100 + char.cameraPosition[0]; } y -= 100 - char.cameraPosition[1]; x -= cameraFollowPointer.width / 2; y -= cameraFollowPointer.height / 2; cameraFollowPointer.setPosition(x, y); } function findAnimationByName(name:String):AnimArray { for (anim in char.animationsArray) { if(anim.anim == name) { return anim; } } return null; } function reloadCharacterOptions() { if(UI_characterbox != null) { imageInputText.text = char.imageFile; healthIconInputText.text = char.healthIcon; singDurationStepper.value = char.singDuration; scaleStepper.value = char.jsonScale; flipXCheckBox.checked = char.originalFlipX; noAntialiasingCheckBox.checked = char.noAntialiasing; resetHealthBarColor(); leHealthIcon.changeIcon(healthIconInputText.text); positionXStepper.value = char.positionArray[0]; positionYStepper.value = char.positionArray[1]; positionCameraXStepper.value = char.cameraPosition[0]; positionCameraYStepper.value = char.cameraPosition[1]; reloadAnimationDropDown(); updatePresence(); } } function reloadAnimationDropDown() { var anims:Array = []; var ghostAnims:Array = ['']; for (anim in char.animationsArray) { anims.push(anim.anim); ghostAnims.push(anim.anim); } if(anims.length < 1) anims.push('NO ANIMATIONS'); //Prevents crash animationDropDown.setData(FlxUIDropDownMenuCustom.makeStrIdLabelArray(anims, true)); ghostDropDown.setData(FlxUIDropDownMenuCustom.makeStrIdLabelArray(ghostAnims, true)); reloadGhost(); } function reloadGhost() { ghostChar.frames = char.frames; for (anim in char.animationsArray) { var animAnim:String = '' + anim.anim; var animName:String = '' + anim.name; var animFps:Int = anim.fps; var animLoop:Bool = !!anim.loop; //Bruh var animIndices:Array = anim.indices; if(animIndices != null && animIndices.length > 0) { ghostChar.animation.addByIndices(animAnim, animName, animIndices, "", animFps, animLoop); } else { ghostChar.animation.addByPrefix(animAnim, animName, animFps, animLoop); } if(anim.offsets != null && anim.offsets.length > 1) { ghostChar.addOffset(anim.anim, anim.offsets[0], anim.offsets[1]); } } char.alpha = 0.85; ghostChar.visible = true; if(ghostDropDown.selectedLabel == '') { ghostChar.visible = false; char.alpha = 1; } ghostChar.color = 0xFF666688; ghostChar.setGraphicSize(Std.int(ghostChar.width * char.jsonScale)); ghostChar.updateHitbox(); } function reloadCharacterDropDown() { var charsLoaded:Map = new Map(); #if MODS_ALLOWED characterList = []; var directories:Array = [Paths.mods('characters/'), Paths.mods(Paths.currentModDirectory + '/characters/'), Paths.getPreloadPath('characters/')]; for (i in 0...directories.length) { var directory:String = directories[i]; if(FileSystem.exists(directory)) { for (file in FileSystem.readDirectory(directory)) { var path = haxe.io.Path.join([directory, file]); if (!sys.FileSystem.isDirectory(path) && file.endsWith('.json')) { var charToCheck:String = file.substr(0, file.length - 5); if(!charsLoaded.exists(charToCheck)) { characterList.push(charToCheck); charsLoaded.set(charToCheck, true); } } } } } #else characterList = CoolUtil.coolTextFile(Paths.txt('characterList')); #end charDropDown.setData(FlxUIDropDownMenuCustom.makeStrIdLabelArray(characterList, true)); charDropDown.selectedLabel = daAnim; } function resetHealthBarColor() { healthColorStepperR.value = char.healthColorArray[0]; healthColorStepperG.value = char.healthColorArray[1]; healthColorStepperB.value = char.healthColorArray[2]; healthBarBG.color = FlxColor.fromRGB(char.healthColorArray[0], char.healthColorArray[1], char.healthColorArray[2]); } function updatePresence() { #if desktop // Updating Discord Rich Presence DiscordClient.changePresence("Character Editor", "Character: " + daAnim, leHealthIcon.getCharacter()); #end } override function update(elapsed:Float) { if(char.animationsArray[curAnim] != null) { textAnim.text = char.animationsArray[curAnim].anim; var curAnim:FlxAnimation = char.animation.getByName(char.animationsArray[curAnim].anim); if(curAnim == null || curAnim.frames.length < 1) { textAnim.text += ' (ERROR!)'; } } else { textAnim.text = ''; } var inputTexts:Array = [animationInputText, imageInputText, healthIconInputText, animationNameInputText, animationIndicesInputText]; for (i in 0...inputTexts.length) { if(inputTexts[i].hasFocus) { if(FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.V && Clipboard.text != null) { //Copy paste inputTexts[i].text = ClipboardAdd(inputTexts[i].text); inputTexts[i].caretIndex = inputTexts[i].text.length; getEvent(FlxUIInputText.CHANGE_EVENT, inputTexts[i], null, []); } if(FlxG.keys.justPressed.ENTER) { inputTexts[i].hasFocus = false; } FlxG.sound.muteKeys = []; FlxG.sound.volumeDownKeys = []; FlxG.sound.volumeUpKeys = []; super.update(elapsed); return; } } FlxG.sound.muteKeys = TitleState.muteKeys; FlxG.sound.volumeDownKeys = TitleState.volumeDownKeys; FlxG.sound.volumeUpKeys = TitleState.volumeUpKeys; if(!charDropDown.dropPanel.visible) { if (FlxG.keys.justPressed.ESCAPE) { if(goToPlayState) { MusicBeatState.switchState(new PlayState()); } else { MusicBeatState.switchState(new editors.MasterEditorMenu()); FlxG.sound.playMusic(Paths.music('freakyMenu')); } FlxG.mouse.visible = false; return; } if (FlxG.keys.justPressed.R) { FlxG.camera.zoom = 1; } if (FlxG.keys.pressed.E && FlxG.camera.zoom < 3) { FlxG.camera.zoom += elapsed * FlxG.camera.zoom; if(FlxG.camera.zoom > 3) FlxG.camera.zoom = 3; } if (FlxG.keys.pressed.Q && FlxG.camera.zoom > 0.1) { FlxG.camera.zoom -= elapsed * FlxG.camera.zoom; if(FlxG.camera.zoom < 0.1) FlxG.camera.zoom = 0.1; } if (FlxG.keys.pressed.I || FlxG.keys.pressed.J || FlxG.keys.pressed.K || FlxG.keys.pressed.L) { var addToCam:Float = 500 * elapsed; if (FlxG.keys.pressed.SHIFT) addToCam *= 4; if (FlxG.keys.pressed.I) camFollow.y -= addToCam; else if (FlxG.keys.pressed.K) camFollow.y += addToCam; if (FlxG.keys.pressed.J) camFollow.x -= addToCam; else if (FlxG.keys.pressed.L) camFollow.x += addToCam; } if(char.animationsArray.length > 0) { if (FlxG.keys.justPressed.W) { curAnim -= 1; } if (FlxG.keys.justPressed.S) { curAnim += 1; } if (curAnim < 0) curAnim = char.animationsArray.length - 1; if (curAnim >= char.animationsArray.length) curAnim = 0; if (FlxG.keys.justPressed.S || FlxG.keys.justPressed.W || FlxG.keys.justPressed.SPACE) { char.playAnim(char.animationsArray[curAnim].anim, true); genBoyOffsets(); } var controlArray:Array = [FlxG.keys.justPressed.LEFT, FlxG.keys.justPressed.RIGHT, FlxG.keys.justPressed.UP, FlxG.keys.justPressed.DOWN]; for (i in 0...controlArray.length) { if(controlArray[i]) { var holdShift = FlxG.keys.pressed.SHIFT; var multiplier = 1; if (holdShift) multiplier = 10; var arrayVal = 0; if(i > 1) arrayVal = 1; var negaMult:Int = 1; if(i % 2 == 1) negaMult = -1; char.animationsArray[curAnim].offsets[arrayVal] += negaMult * multiplier; char.addOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].offsets[0], char.animationsArray[curAnim].offsets[1]); ghostChar.addOffset(char.animationsArray[curAnim].anim, char.animationsArray[curAnim].offsets[0], char.animationsArray[curAnim].offsets[1]); char.playAnim(char.animationsArray[curAnim].anim, false); if(ghostChar.animation.curAnim != null && char.animation.curAnim != null && char.animation.curAnim.name == ghostChar.animation.curAnim.name) { ghostChar.playAnim(char.animation.curAnim.name, false); } genBoyOffsets(); } } } } camMenu.zoom = FlxG.camera.zoom; ghostChar.setPosition(char.x, char.y); super.update(elapsed); } var _file:FileReference; /*private function saveOffsets() { var data:String = ''; for (anim => offsets in char.animOffsets) { data += anim + ' ' + offsets[0] + ' ' + offsets[1] + '\n'; } if (data.length > 0) { _file = new FileReference(); _file.addEventListener(Event.COMPLETE, onSaveComplete); _file.addEventListener(Event.CANCEL, onSaveCancel); _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); _file.save(data, daAnim + "Offsets.txt"); } }*/ function onSaveComplete(_):Void { _file.removeEventListener(Event.COMPLETE, onSaveComplete); _file.removeEventListener(Event.CANCEL, onSaveCancel); _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); _file = null; FlxG.log.notice("Successfully saved file."); } /** * Called when the save file dialog is cancelled. */ function onSaveCancel(_):Void { _file.removeEventListener(Event.COMPLETE, onSaveComplete); _file.removeEventListener(Event.CANCEL, onSaveCancel); _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); _file = null; } /** * Called if there is an error while saving the gameplay recording. */ function onSaveError(_):Void { _file.removeEventListener(Event.COMPLETE, onSaveComplete); _file.removeEventListener(Event.CANCEL, onSaveCancel); _file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError); _file = null; FlxG.log.error("Problem saving file"); } function saveCharacter() { var json = { "animations": char.animationsArray, "image": char.imageFile, "scale": char.jsonScale, "sing_duration": char.singDuration, "healthicon": char.healthIcon, "position": char.positionArray, "camera_position": char.cameraPosition, "flip_x": char.originalFlipX, "no_antialiasing": char.noAntialiasing, "healthbar_colors": char.healthColorArray }; var data:String = Json.stringify(json, "\t"); if (data.length > 0) { _file = new FileReference(); _file.addEventListener(Event.COMPLETE, onSaveComplete); _file.addEventListener(Event.CANCEL, onSaveCancel); _file.addEventListener(IOErrorEvent.IO_ERROR, onSaveError); _file.save(data, daAnim + ".json"); } } function ClipboardAdd(prefix:String = ''):String { if(prefix.toLowerCase().endsWith('v')) //probably copy paste attempt { prefix = prefix.substring(0, prefix.length-1); } var text:String = prefix + Clipboard.text.replace('\n', ''); return text; } }