diff --git a/README.md b/README.md index b4d4bcc9..93b36034 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ Also, the command `.\cne test` uses the source assets folder instead of the expo ## Codename Engine Codename Engine is a new Friday Night Funkin' Engine aimed at simplifying modding, along with extensiblity and ease of use.
-Make sure to read the wiki and join the Discord server linked there!
-#### It includes many new features, as seen [here](FEATURES.md)
+### Before making issues or need help with something, check our website [HERE](https://fnf-cne-devs.github.io/) (it contains a wiki of how to mod with EXAMPLES, an api, lists of mods made with Codename Engine and more)!!! +#### The Engine includes many new features, as seen [here](FEATURES.md)
#### Wanna see the new features added in the most recent update? Click [here](PATCHNOTES.md)
## How to download diff --git a/assets/data/config/credits.xml b/assets/data/config/credits.xml deleted file mode 100644 index 4f300fcb..00000000 --- a/assets/data/config/credits.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/assets/data/config/options.xml b/assets/data/config/options.xml deleted file mode 100644 index 888288d7..00000000 --- a/assets/data/config/options.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/assets/data/titlescreen/titlescreen.xml b/assets/data/titlescreen/titlescreen.xml index f16c8b62..323e9ef1 100644 --- a/assets/data/titlescreen/titlescreen.xml +++ b/assets/data/titlescreen/titlescreen.xml @@ -7,7 +7,7 @@ - + diff --git a/assets/shaders/engine/editorBlur.frag b/assets/shaders/engine/editorBlur.frag index 59b91c72..85754b99 100644 --- a/assets/shaders/engine/editorBlur.frag +++ b/assets/shaders/engine/editorBlur.frag @@ -3,19 +3,17 @@ // Used for editors -int steps = 16; -int stepsInside = 2; -float strength = 0.0075; +const int steps = 16; +const int stepsInside = 2; +const float strength = 0.0075; + vec4 getColor(vec2 pos) { - vec2 ps = (pos); - ps = clamp(ps, vec2(0.0), 1.0 - (1.0 / openfl_TextureSize.xy)); - return flixel_texture2D(bitmap, (ps)); + pos = clamp(pos, vec2(0.0), vec2(1.0));//1.0 - (1.0 / openfl_TextureSize.xy)); + return flixel_texture2D(bitmap, pos); } + void main() { - // vec2 camPos = getCamPos(openfl_TextureCoordv); vec2 camPos = openfl_TextureCoordv; - if (camPos.x < 0.0 || camPos.x > 1.0 || camPos.y < 0.0 || camPos.y > 1.0) - return; vec4 color = getColor(camPos); float fsteps = float(steps); diff --git a/assets/shaders/engine/editorBlurFast.frag b/assets/shaders/engine/editorBlurFast.frag index 75ef96af..db476ae8 100644 --- a/assets/shaders/engine/editorBlurFast.frag +++ b/assets/shaders/engine/editorBlurFast.frag @@ -2,58 +2,29 @@ // Used for editors (faster) -//#define iResolution _camSize -#define getTexture textureCam - -#define iResolution openfl_TextureSize -//#define getTexture flixel_texture2D - -float uBlur = 0.015; -float uBrightness = 0.6; +const float uBlur = 0.015; +const float uBrightness = 0.6; vec4 getColor(vec2 pos) { - vec2 ps = (pos); - if (ps.x < 0.0) ps.x = 0.0; - //else if (ps.x > 1.0 - (1.0 / iResolution.x)) ps.x = 1.0 - (1.0 / iResolution.x); - else if (ps.x > 1.0) return vec4(0.0); - if (ps.y < 0.0) ps.y = 0.0; - //else if (ps.y > 1.0 - (1.0 / iResolution.y)) return ps.y = 1.0 - (1.0 / iResolution.y); - else if (ps.y > 1.0) return vec4(0.0); - return flixel_texture2D(bitmap, (ps)); + pos = clamp(pos, vec2(0.0), vec2(1.0));//1.0 - (1.0 / openfl_TextureSize.xy)); + return flixel_texture2D(bitmap, pos); } - -vec2 fixvec2(float x, float y) { // makes an uv the same across sizes - vec2 val = vec2(x, y); - val.xy *= vec2(1280.0, 720.0); - val.xy /= iResolution.xy; - return val; -} -vec2 fixvec2(vec2 uv) { // makes an uv the same across sizes - vec2 val = uv; - val.xy *= vec2(1280.0, 720.0); - val.xy /= iResolution.xy; - return val; -} +uniform sampler2D noiseTexture; +uniform vec2 noiseTextureSize; vec2 random(vec2 p) { - p = vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))); - return fract(sin(p)*4375.5); + p *= openfl_TextureSize; + return texture2D(noiseTexture, p / noiseTextureSize).rg - vec2(0.5); } void main() { - vec2 camPos = (openfl_TextureCoordv); - //vec2 camPos = openfl_TextureCoordv; - if (camPos.x < 0.0 || camPos.x > 1.0 || camPos.y < 0.0 || camPos.y > 1.0) - return; + vec2 camPos = openfl_TextureCoordv; + vec2 blur = vec2(uBlur) * vec2(1.0, openfl_TextureSize.x / openfl_TextureSize.y); - //vec4 color = getColor(camPos); - - vec2 blur = vec2(uBlur) * vec2(1.0, iResolution.x / iResolution.y); - - vec4 a = getColor(camPos+(random(camPos)*blur - blur / 2.0)) * uBrightness; - a += getColor(camPos+(random(camPos+0.1)*blur - blur / 2.0)) * uBrightness; - a += getColor(camPos+(random(camPos+0.2)*blur - blur / 2.0)) * uBrightness; - //a += getColor(camPos+(random(camPos+0.3)*blur - blur / 2.0)) * uBrightness; - gl_FragColor = a / 3.0; + vec4 a = getColor(camPos+random(camPos)*blur); + a += getColor(camPos+random(camPos+0.1)*blur); + //a += getColor(camPos+random(camPos+0.2)*blur); + //a += getColor(camPos+random(camPos+0.3)*blur); + gl_FragColor = (a / 2.0) * uBrightness; } \ No newline at end of file diff --git a/assets/shaders/noise128.png b/assets/shaders/noise128.png new file mode 100644 index 00000000..682cb32a Binary files /dev/null and b/assets/shaders/noise128.png differ diff --git a/assets/shaders/noise256.png b/assets/shaders/noise256.png new file mode 100644 index 00000000..fd2a1410 Binary files /dev/null and b/assets/shaders/noise256.png differ diff --git a/assets/shaders/noise512.png b/assets/shaders/noise512.png new file mode 100644 index 00000000..d50270af Binary files /dev/null and b/assets/shaders/noise512.png differ diff --git a/project.xml b/project.xml index 20d7d549..34683e4b 100644 --- a/project.xml +++ b/project.xml @@ -118,9 +118,6 @@ - - - diff --git a/source/funkin/backend/assets/Paths.hx b/source/funkin/backend/assets/Paths.hx index 21be721d..52357c8e 100644 --- a/source/funkin/backend/assets/Paths.hx +++ b/source/funkin/backend/assets/Paths.hx @@ -255,58 +255,6 @@ class Paths content[k] = '$key$e'; } return content; - /* - if (!key.endsWith("/")) key = key + "/"; - - if (ModsFolder.currentModFolder == null && !scanSource) - return getFolderContent(key, false, addPath, true); - - var folderPath:String = scanSource ? getAssetsPath(key) : getLibraryPathForce(key, 'mods/${ModsFolder.currentModFolder}'); - var libThing = new LimeLibrarySymbol(folderPath); - var library = libThing.library; - - if (library is openfl.utils.AssetLibrary) { - var lib = cast(libThing.library, openfl.utils.AssetLibrary); - @:privateAccess - if (lib.__proxy != null) library = lib.__proxy; - } - - var content:Array = []; - #if MOD_SUPPORT - if (library is funkin.backend.assets.IModsAssetLibrary) { - // easy task, can immediately scan for files! - var lib = cast(library, funkin.backend.assets.IModsAssetLibrary); - content = lib.getFiles(libThing.symbolName); - if (addPath) - for(i in 0...content.length) - content[i] = '$folderPath${content[i]}'; - } else #end { - @:privateAccess - for(k=>e in library.paths) { - if (k.toLowerCase().startsWith(libThing.symbolName.toLowerCase())) { - if (addPath) { - if (libThing.libraryName != "") - content.push('${libThing.libraryName}:$k'); - else - content.push(k); - } else { - var barebonesFileName = k.substr(libThing.symbolName.length); - if (!barebonesFileName.contains("/")) - content.push(barebonesFileName); - } - } - } - } - - if (includeSource) { - var sourceResult = getFolderContent(key, false, addPath, true); - for(e in sourceResult) - if (!content.contains(e)) - content.push(e); - } - - return content; - */ } // Used in Script.hx diff --git a/source/funkin/backend/system/Logs.hx b/source/funkin/backend/system/Logs.hx index 1f083324..60713004 100644 --- a/source/funkin/backend/system/Logs.hx +++ b/source/funkin/backend/system/Logs.hx @@ -11,8 +11,7 @@ class Logs { public static var nativeTrace = Log.trace; public static function init() { - - Log.trace = function(v : Dynamic, ?infos : Null) { + Log.trace = function(v:Dynamic, ?infos:Null) { var data = [ logText('${infos.fileName}:${infos.lineNumber}: ', CYAN), logText(Std.string(v)) @@ -28,22 +27,48 @@ class Logs { __showInConsole(prepareColoredTrace(data, TRACE)); }; - LogFrontEnd.onLogs = function(Data, Style, FireOnce) { + LogFrontEnd.onLogs = function(data, style, fireOnce) { var prefix = "[FLIXEL]"; var color:ConsoleColor = LIGHTGRAY; var level:Level = INFO; - if (Style == LogStyle.CONSOLE) {prefix = "> "; color = WHITE; level = INFO; } else - if (Style == LogStyle.ERROR) {prefix = "[FLIXEL]"; color = RED; level = ERROR; } else - if (Style == LogStyle.NORMAL) {prefix = "[FLIXEL]"; color = WHITE; level = INFO; } else - if (Style == LogStyle.NOTICE) {prefix = "[FLIXEL]"; color = GREEN; level = VERBOSE;} else - if (Style == LogStyle.WARNING) {prefix = "[FLIXEL]"; color = YELLOW; level = WARNING;} + if (style == LogStyle.CONSOLE) // cant place a switch here as these arent inline values - Nex + { + prefix = "> "; + color = WHITE; + level = INFO; + } + else if (style == LogStyle.ERROR) + { + prefix = "[FLIXEL]"; + color = RED; + level = ERROR; + } + else if (style == LogStyle.NORMAL) + { + prefix = "[FLIXEL]"; + color = WHITE; + level = INFO; + } + else if (style == LogStyle.NOTICE) + { + prefix = "[FLIXEL]"; + color = GREEN; + level = VERBOSE; + } + else if (style == LogStyle.WARNING) + { + prefix = "[FLIXEL]"; + color = YELLOW; + level = WARNING; + } - var d:Dynamic = Data; + var d:Dynamic = data; if (!(d is Array)) d = [d]; var a:Array = d; var strs = [for(e in a) Std.string(e)]; - for(e in strs) { + for(e in strs) + { Logs.trace('$prefix $e', level, color); } }; @@ -55,12 +80,18 @@ class Logs { logText('[ '), logText('${Std.string(time.getHours()).addZeros(2)}:${Std.string(time.getMinutes()).addZeros(2)}:${Std.string(time.getSeconds()).addZeros(2)}', DARKMAGENTA), logText(' |'), - switch(level) { - case WARNING: logText(' WARNING ', DARKYELLOW); - case ERROR: logText(' ERROR ', DARKRED); - case TRACE: logText(' TRACE ', GRAY); - case VERBOSE: logText(' VERBOSE ', DARKMAGENTA); - default: logText(' INFORMATION ', CYAN); + switch (level) + { + case WARNING: + logText(' WARNING ', DARKYELLOW); + case ERROR: + logText(' ERROR ', DARKRED); + case TRACE: + logText(' TRACE ', GRAY); + case VERBOSE: + logText(' VERBOSE ', DARKMAGENTA); + default: + logText(' INFORMATION ', CYAN); }, logText('] ') ]; @@ -77,7 +108,7 @@ class Logs { } public static function __showInConsole(text:Array) { - #if sys + #if (sys && !mobile) while(__showing) { Sys.sleep(0.05); } @@ -89,20 +120,30 @@ class Logs { NativeAPI.setConsoleColors(); Sys.print("\r\n"); __showing = false; + #elseif mobile + while(__showing) { + Sys.sleep(0.05); + } + __showing = true; + @:privateAccess + Sys.print([for(t in text) t.text].join("")); + __showing = false; #else @:privateAccess nativeTrace([for(t in text) t.text].join("")); #end } - public static function traceColored(text:Array, level:Level = INFO) { + public static function traceColored(text:Array, level:Level = INFO) __showInConsole(prepareColoredTrace(text, level)); - } + public static function trace(text:String, level:Level = INFO, color:ConsoleColor = LIGHTGRAY) { - traceColored([{ - text: text, - color: color - }], level); + traceColored([ + { + text: text, + color: color + } + ], level); } } @@ -113,7 +154,8 @@ enum abstract Level(Int) { var TRACE = 3; var VERBOSE = 4; } + typedef LogText = { var text:String; var color:ConsoleColor; -} \ No newline at end of file +} diff --git a/source/funkin/backend/utils/CoolUtil.hx b/source/funkin/backend/utils/CoolUtil.hx index 15147f00..7dc0857f 100644 --- a/source/funkin/backend/utils/CoolUtil.hx +++ b/source/funkin/backend/utils/CoolUtil.hx @@ -721,7 +721,10 @@ class CoolUtil */ @:noUsing public static inline function openURL(url:String) { #if linux - Sys.command('/usr/bin/xdg-open', [url]); + // generally `xdg-open` should work in every distro + var cmd = Sys.command("xdg-open", [url]); + // run old command JUST IN CASE it fails, which it shouldn't + if (cmd != 0) cmd = Sys.command("/usr/bin/xdg-open", [url]); #else FlxG.openURL(url); #end diff --git a/source/funkin/backend/utils/MemoryUtil.hx b/source/funkin/backend/utils/MemoryUtil.hx index 6c27629e..cd27cb0e 100644 --- a/source/funkin/backend/utils/MemoryUtil.hx +++ b/source/funkin/backend/utils/MemoryUtil.hx @@ -140,14 +140,16 @@ class MemoryUtil { reg.match(process.stdout.readAll().toString()); if (process.exitCode() == 0) return reg.matched(1); #elseif linux - var process = new HiddenProcess("sudo", ["dmidecode", "--type", "17"]); + /*var process = new HiddenProcess("sudo", ["dmidecode", "--type", "17"]); if (process.exitCode() != 0) return "Unknown"; var lines = process.stdout.readAll().toString().split("\n"); for (line in lines) { if (line.startsWith("Type:")) { return line.substring("Type:".length).trim(); } - } + }*/ + // TODO: sort of unsafe? also requires users to use `sudo` + // when launching the engine through the CLI, REIMPLEMENT LATER. #end return "Unknown"; } diff --git a/source/funkin/editors/character/CharacterSelection.hx b/source/funkin/editors/character/CharacterSelection.hx index eb9a1e3a..3776b353 100644 --- a/source/funkin/editors/character/CharacterSelection.hx +++ b/source/funkin/editors/character/CharacterSelection.hx @@ -4,6 +4,7 @@ import funkin.game.Character; import funkin.options.OptionsScreen; import funkin.options.type.IconOption; import funkin.options.type.NewOption; +import funkin.options.type.TextOption; import funkin.options.type.OptionType; class CharacterSelection extends EditorTreeMenu @@ -13,21 +14,45 @@ class CharacterSelection extends EditorTreeMenu bgType = "charter"; super.create(); - var modsList:Array = Character.getList(true); + var isMods:Bool = true; + var modsList:Array = Character.getList(true, true); - var list:Array = [ - for (char in (modsList.length == 0 ? Character.getList(false) : modsList)) - new IconOption(char, "Press ACCEPT to edit this character.", Character.getIconFromCharName(char), - function() { - FlxG.switchState(new CharacterEditor(char)); - }) - ]; + if(modsList.length == 0) { + modsList = Character.getList(false, true); + isMods = false; + } - list.insert(0, new NewOption("New Character", "New Character", function() { - openSubState(new UIWarningSubstate("New Character: Feature Not Implemented!", "This feature isnt implemented yet. Please wait for more cne updates to have this functional.\n\n\n- Codename Devs", [ - {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}} - ])); - })); + function generateList(modsList:Array, isMods:Bool, folderPath:String = ""):Array { + var list:Array = []; + + for(char in modsList) { + if(char.endsWith("/")) { + var folderName = CoolUtil.getFilename(char.substr(0, char.length-1)); + + list.push(new TextOption(folderName + " >", "Press ACCEPT to edit this folder.", function() { + var newModsList = Character.getList(isMods, true, char); + var newList:Array = generateList(newModsList, isMods, folderPath + folderName + "/"); + optionsTree.add(new OptionsScreen(folderPath + folderName, "Select a character to edit in " + folderPath + folderName + "/", newList)); + })); + } else { + list.push(new IconOption(char, "Press ACCEPT to edit this character.", Character.getIconFromCharName(folderPath + char, char), + function() { + FlxG.switchState(new CharacterEditor(folderPath + char)); + }) + ); + } + } + + list.insert(0, new NewOption("New Character", "New Character", function() { + openSubState(new UIWarningSubstate("New Character: Feature Not Implemented!", "This feature isnt implemented yet. Please wait for more cne updates to have this functional.\n\n\n- Codename Devs", [ + {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}} + ])); + })); + + return list; + } + + var list = generateList(modsList, isMods); main = new OptionsScreen("Character Editor", "Select a character to edit", list); diff --git a/source/funkin/editors/charter/CharterEventScreen.hx b/source/funkin/editors/charter/CharterEventScreen.hx index 20d84715..f3df422a 100644 --- a/source/funkin/editors/charter/CharterEventScreen.hx +++ b/source/funkin/editors/charter/CharterEventScreen.hx @@ -162,7 +162,11 @@ class CharterEventScreen extends UISubstateWindow { colorWheel; case TDropDown(options): addLabel(); - var dropdown = new UIDropDown(eventName.x, y, 320, 32, options, Std.int(Math.abs(options.indexOf(cast value)))); + var optionIndex = options.indexOf(cast value); + if(optionIndex < 0) { + optionIndex = 0; + } + var dropdown = new UIDropDown(eventName.x, y, 320, 32, options, optionIndex); paramsPanel.add(dropdown); paramsFields.push(dropdown); dropdown; case TCharacter: diff --git a/source/funkin/editors/ui/UISubstateWindow.hx b/source/funkin/editors/ui/UISubstateWindow.hx index f99e184b..71550ef0 100644 --- a/source/funkin/editors/ui/UISubstateWindow.hx +++ b/source/funkin/editors/ui/UISubstateWindow.hx @@ -1,5 +1,8 @@ package funkin.editors.ui; +import openfl.display.ShaderParameter; +import openfl.display.ShaderInput; +import openfl.filters.ShaderFilter; import flixel.tweens.FlxTween; import funkin.backend.shaders.CustomShader; import openfl.filters.ShaderFilter; @@ -7,7 +10,17 @@ import openfl.filters.ShaderFilter; // TODO: make UIWarningSubstate extend this class UISubstateWindow extends MusicBeatSubstate { var camShaders:Array = []; - var blurShader:CustomShader = new CustomShader(Options.intensiveBlur ? "engine/editorBlur" : "engine/editorBlurFast"); + var blurShader:CustomShader = { + var _ = new CustomShader(Options.intensiveBlur ? "engine/editorBlur" : "engine/editorBlurFast"); + if(!Options.intensiveBlur) { + var noiseTexture:ShaderInput = _.data.noiseTexture; + noiseTexture.input = Assets.getBitmapData("assets/shaders/noise256.png"); + noiseTexture.wrap = REPEAT; + var noiseTextureSize:ShaderParameter = _.data.noiseTextureSize; + noiseTextureSize.value = [noiseTexture.input.width, noiseTexture.input.height]; + } + _; + }; var titleSpr:UIText; var messageSpr:UIText; diff --git a/source/funkin/editors/ui/UIWarningSubstate.hx b/source/funkin/editors/ui/UIWarningSubstate.hx index 84edf922..4f4a0380 100644 --- a/source/funkin/editors/ui/UIWarningSubstate.hx +++ b/source/funkin/editors/ui/UIWarningSubstate.hx @@ -1,5 +1,8 @@ package funkin.editors.ui; +import openfl.display.ShaderParameter; +import openfl.display.ShaderInput; +import openfl.filters.ShaderFilter; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import funkin.backend.shaders.CustomShader; @@ -7,7 +10,17 @@ import openfl.filters.ShaderFilter; class UIWarningSubstate extends MusicBeatSubstate { var camShaders:Array = []; - var blurShader:CustomShader = new CustomShader(Options.intensiveBlur ? "engine/editorBlur" : "engine/editorBlurFast"); + var blurShader:CustomShader = { + var _ = new CustomShader(Options.intensiveBlur ? "engine/editorBlur" : "engine/editorBlurFast"); + if(!Options.intensiveBlur) { + var noiseTexture:ShaderInput = _.data.noiseTexture; + noiseTexture.input = Assets.getBitmapData("assets/shaders/noise256.png"); + noiseTexture.wrap = REPEAT; + var noiseTextureSize:ShaderParameter = _.data.noiseTextureSize; + noiseTextureSize.value = [noiseTexture.input.width, noiseTexture.input.height]; + } + _; + }; var title:String; var message:String; diff --git a/source/funkin/game/Character.hx b/source/funkin/game/Character.hx index 3d0590d3..306a7062 100644 --- a/source/funkin/game/Character.hx +++ b/source/funkin/game/Character.hx @@ -538,9 +538,10 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset return xml; } - public static function getIconFromCharName(?character:String) { + public static function getIconFromCharName(?character:String, ?defaultIcon:String = null) { if(character == null) return Constants.DEFAULT_HEALTH_ICON; - var icon:String = character; + if(defaultIcon == null) defaultIcon = character; + var icon:String = defaultIcon; var xml:Access = getXMLFromCharName(character); if (xml != null && xml.x.exists("icon")) icon = xml.x.get("icon"); @@ -548,9 +549,17 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset return icon; } - public static function getList(?mods:Bool = false):Array - return [ - for (path in Paths.getFolderContent('data/characters/', true, mods ? MODS : BOTH)) - if (Path.extension(path) == "xml") CoolUtil.getFilename(path) - ]; + public static function getList(?mods:Bool = false, includeFolders:Bool = false, folder:String = 'data/characters/'):Array { + var list:Array = []; + if(includeFolders) { + for (path in Paths.getFolderDirectories(folder, true, mods ? MODS : BOTH)) { + if(!path.endsWith("/")) path += "/"; + list.push(path); + } + } + for (path in Paths.getFolderContent(folder, true, mods ? MODS : BOTH)) + if (Path.extension(path) == "xml") + list.push(CoolUtil.getFilename(path)); + return list; + } } \ No newline at end of file diff --git a/source/funkin/game/HealthIcon.hx b/source/funkin/game/HealthIcon.hx index 4dd9a4fb..16b0d729 100644 --- a/source/funkin/game/HealthIcon.hx +++ b/source/funkin/game/HealthIcon.hx @@ -90,11 +90,9 @@ class HealthIcon extends FlxSprite if (animation.curAnim != null) { var i:Int = -1; var oldKey:Int = -1; - for(k=>icon in healthSteps) { - if (k > oldKey && k < health * 100) { - oldKey = k; - i = icon; - } + for (k=>icon in healthSteps) if (k > oldKey && k <= health * 100) { + oldKey = k; + i = icon; } if (i >= 0 && curAnimState != i) { var event = EventManager.get(funkin.backend.scripting.events.HealthIconChangeEvent).recycle(i, this); diff --git a/source/funkin/game/cutscenes/DialogueCutscene.hx b/source/funkin/game/cutscenes/DialogueCutscene.hx index 39713943..7a4d7a38 100644 --- a/source/funkin/game/cutscenes/DialogueCutscene.hx +++ b/source/funkin/game/cutscenes/DialogueCutscene.hx @@ -95,7 +95,7 @@ class DialogueCutscene extends ScriptedCutscene { musicVolume: node.has.musicVolume ? (volume = Std.parseFloat(node.att.speed).getDefault(0.8)) : null, changeMusic: node.has.changeMusic ? FlxG.sound.load(Paths.music(node.att.changeMusic), volume, true) : null, playSound: node.has.playSound ? FlxG.sound.load(Paths.sound(node.att.playSound)) : null, - nextSound: node.has.nextSound ? FlxG.sound.load(Paths.music(node.att.nextSound)) : null, + nextSound: node.has.nextSound ? FlxG.sound.load(Paths.sound(node.att.nextSound)) : null, textSound: null }; @@ -218,4 +218,4 @@ typedef DialogueLine = { var nextSound:FlxSound; var textSound:FlxSound; var changeDefAnim:String; -} \ No newline at end of file +} diff --git a/source/funkin/menus/MainMenuState.hx b/source/funkin/menus/MainMenuState.hx index 5f88f888..ac4a5b3f 100644 --- a/source/funkin/menus/MainMenuState.hx +++ b/source/funkin/menus/MainMenuState.hx @@ -158,7 +158,7 @@ class MainMenuState extends MusicBeatState var event = event("onSelectItem", EventManager.get(NameEvent).recycle(daChoice)); if (event.cancelled) return; - switch (daChoice) + switch (event.name) { case 'story mode': FlxG.switchState(new StoryMenuState()); case 'freeplay': FlxG.switchState(new FreeplayState()); diff --git a/source/funkin/menus/PauseSubState.hx b/source/funkin/menus/PauseSubState.hx index 30884a89..390788dd 100644 --- a/source/funkin/menus/PauseSubState.hx +++ b/source/funkin/menus/PauseSubState.hx @@ -14,6 +14,7 @@ import funkin.editors.charter.Charter; import funkin.menus.StoryMenuState; import funkin.options.OptionsMenu; import funkin.options.keybinds.KeybindsOptions; +import funkin.options.TreeMenu; class PauseSubState extends MusicBeatSubstate { @@ -154,9 +155,10 @@ class PauseSubState extends MusicBeatSubstate persistentDraw = false; openSubState(new KeybindsOptions()); case "Change Options": + TreeMenu.lastState = PlayState; FlxG.switchState(new OptionsMenu()); case "Exit to charter": - FlxG.switchState(new funkin.editors.charter.Charter(PlayState.SONG.meta.name, PlayState.difficulty, false)); + FlxG.switchState(new Charter(PlayState.SONG.meta.name, PlayState.difficulty, false)); case "Exit to menu": if (PlayState.chartingMode && Charter.undos.unsaved) game.saveWarn(false); @@ -207,4 +209,4 @@ class PauseSubState extends MusicBeatSubstate item.alpha = 0.6; } } -} \ No newline at end of file +} diff --git a/source/funkin/menus/StoryMenuState.hx b/source/funkin/menus/StoryMenuState.hx index 44a4d538..01c61640 100644 --- a/source/funkin/menus/StoryMenuState.hx +++ b/source/funkin/menus/StoryMenuState.hx @@ -118,6 +118,13 @@ class StoryMenuState extends MusicBeatState { } interpColor = new FlxInterpolateColor(weekBG.color); + + // default difficulty should be the middle difficulty in the array + // to be consistent with base game and whatnot, you know the drill + curDifficulty = Math.floor(weeks[0].difficulties.length * 0.5); + // debug stuff lol + Logs.trace('Middle Difficulty for Week 1 is ${weeks[0].difficulties[curDifficulty]} (ID: $curDifficulty)'); + changeWeek(0, true); DiscordUtil.call("onMenuLoaded", ["Story Menu"]); @@ -170,6 +177,7 @@ class StoryMenuState extends MusicBeatState { if (!force) CoolUtil.playMenuSFX(); for(k=>e in weekSprites.members) { e.targetY = k - curWeek; + e.alpha = k == curWeek ? 1.0 : 0.6; } tracklist.text = 'TRACKS\n\n${[for(e in weeks[curWeek].songs) if (!e.hide) e.name].join('\n')}'; weekTitle.text = weeks[curWeek].name.getDefault(""); @@ -362,13 +370,13 @@ class StoryMenuState extends MusicBeatState { if(characterSprites != null) characterSprites.forEachAlive(function(spr) spr.playAnim("confirm", true, LOCK)); - PlayState.loadWeek(weeks[curWeek], weeks[curWeek].difficulties[curDifficulty]); + PlayState.loadWeek(event.week, event.difficulty); new FlxTimer().start(1, function(tmr:FlxTimer) { FlxG.switchState(new PlayState()); }); - weekSprites.members[curWeek].startFlashing(); + weekSprites.members[event.weekID].startFlashing(); } } diff --git a/source/funkin/menus/TitleState.hx b/source/funkin/menus/TitleState.hx index e1245a1e..a4a42385 100644 --- a/source/funkin/menus/TitleState.hx +++ b/source/funkin/menus/TitleState.hx @@ -25,8 +25,6 @@ class TitleState extends MusicBeatState public var textGroup:FlxGroup; public var ngSpr:FlxSprite; - public var wackyImage:FlxSprite; - override public function create():Void { curWacky = FlxG.random.getObject(getIntroTextShit()); @@ -40,9 +38,6 @@ class TitleState extends MusicBeatState DiscordUtil.call("onMenuLoaded", ["Title Screen"]); } - var logoBl:FlxSprite; - var gfDance:FlxSprite; - var danceLeft:Bool = false; var titleText:FlxSprite; var titleScreenSprites:MusicBeatGroup; @@ -56,11 +51,9 @@ class TitleState extends MusicBeatState var bg:FlxSprite = new FlxSprite().makeSolid(FlxG.width, FlxG.height, FlxColor.BLACK); add(bg); - #if TITLESCREEN_XML titleScreenSprites = new MusicBeatGroup(); add(titleScreenSprites); loadXML(); - #end if (titleText == null) { titleText = new FlxSprite(100, FlxG.height * 0.8); @@ -78,16 +71,6 @@ class TitleState extends MusicBeatState blackScreen = new FlxSprite().makeGraphic(FlxG.width, FlxG.height, FlxColor.BLACK); add(blackScreen); - #if !TITLESCREEN_XML - ngSpr = new FlxSprite(0, FlxG.height * 0.52).loadAnimatedGraphic(Paths.image('newgrounds_logo')); - add(ngSpr); - ngSpr.visible = false; - ngSpr.setGraphicSize(Std.int(ngSpr.width * 0.8)); - ngSpr.updateHitbox(); - ngSpr.screenCenter(X); - ngSpr.antialiasing = true; - #end - FlxG.mouse.visible = false; if (initialized) @@ -217,7 +200,6 @@ class TitleState extends MusicBeatState { super.beatHit(curBeat); - #if TITLESCREEN_XML if (curBeat >= titleLength || skippedIntro) { if (!skippedIntro) skipIntro(); return; @@ -225,27 +207,8 @@ class TitleState extends MusicBeatState var introText = titleLines[curBeat]; if (introText != null) introText.show(); - #else - switch (curBeat) - { - case 1: createCoolText(['ninjamuffin99', 'phantomArcade', 'kawaisprite', 'evilsk8er']); - case 3: addMoreText('present'); - case 4: deleteCoolText(); - case 5: createCoolText(['In association', 'with']); - case 7: addMoreText('newgrounds'); ngSpr.visible = true; - case 8: deleteCoolText(); ngSpr.visible = false; - case 9: createCoolText([curWacky[0]]); - case 11: addMoreText(curWacky[1]); - case 12: deleteCoolText(); - case 13: addMoreText('Friday'); - case 14: addMoreText('Night'); - case 15: addMoreText('Funkin'); - case 16: skipIntro(); - } - #end } - #if TITLESCREEN_XML public var xml:Access; public var titleLength:Int = 16; public var titleLines:Map = [ @@ -267,12 +230,14 @@ class TitleState extends MusicBeatState 15 => new IntroText(['Friday', 'Night', "Funkin'"]), ]; + public var titleSprites:Map = []; + public function loadXML() { try { xml = new Access(Xml.parse(Assets.getText(Paths.xml('titlescreen/titlescreen'))).firstElement()); if (xml.hasNode.intro) { titleLines = []; - if (xml.node.intro.has.length) titleLength = CoolUtil.getDefault(Std.parseInt(xml.node.intro.att.length), 16); + if (xml.node.intro.has.length) titleLength = Std.parseInt(xml.node.intro.att.length).getDefault(16); for(node in xml.nodes.sprites) { var parentFolder:String = node.getAtt("folder").getDefault(""); if (parentFolder != "" && !parentFolder.endsWith("/")) parentFolder += "/"; @@ -284,26 +249,28 @@ class TitleState extends MusicBeatState default: titleScreenSprites.add(spr); } + if(node.has.name) titleSprites[node.att.name] = spr; } } for(text in xml.node.intro.nodes.text) { - var beat:Int = CoolUtil.getDefault(text.has.beat ? Std.parseInt(text.att.beat) : null, 0); + var beat:Int = text.has.beat ? Std.parseInt(text.att.beat).getDefault(0) : 0; var texts:Array> = []; - for(e in text.elements) { - switch(e.name) { + for(node in text.elements) { + switch(node.name) { case "line": - if (!e.has.text) continue; - texts.push(e.att.text); + if (!node.has.text) continue; + texts.push(node.att.text); case "introtext": - if (!e.has.line) continue; - texts.push('{introText${e.att.line}}'); + if (!node.has.line) continue; + texts.push('{introText${node.att.line}}'); case "sprite": - if (!e.has.path) continue; - var name:String = e.has.name ? e.att.name : null; - var path:String = e.att.path; - var flipX:Bool = e.has.flipX ? e.att.flipX == "true" : false; - var flipY:Bool = e.has.flipY ? e.att.flipY == "true" : false; - var scale:Float = e.has.scale ? CoolUtil.getDefault(Std.parseFloat(e.att.scale), 1) : 1; + if (!node.has.path) continue; + var name:String = node.has.name ? node.att.name : null; + var path:String = node.att.path; + var flipX:Bool = node.has.flipX ? node.att.flipX == "true" : false; + var flipY:Bool = node.has.flipY ? node.att.flipY == "true" : false; + var scale:Float = node.has.scale ? Std.parseFloat(node.att.scale).getDefault(1) : 1; + texts.push({ name: name, path: path, @@ -320,7 +287,6 @@ class TitleState extends MusicBeatState Logs.trace('Failed to load titlescreen XML: $e', ERROR); } } - #end var skippedIntro:Bool = false; @@ -328,10 +294,6 @@ class TitleState extends MusicBeatState { if (!skippedIntro) { - #if !TITLESCREEN_XML - remove(ngSpr); - #end - FlxG.camera.flash(FlxColor.WHITE, 4); remove(blackScreen); blackScreen.destroy(); @@ -361,7 +323,7 @@ class IntroText { var image:TitleStateImage = e; if (image.path == null) continue; - var scale:Float = CoolUtil.getDefault(image.scale, 1); + var scale:Float = image.scale.getDefault(1); var yPos:Float = 200; if(state.textGroup.members.length > 0) { @@ -370,8 +332,8 @@ class IntroText { } var sprite = new FlxSprite(0, yPos).loadAnimatedGraphic(Paths.image(image.path)); - sprite.flipX = CoolUtil.getDefault(image.flipX, false); - sprite.flipY = CoolUtil.getDefault(image.flipY, false); + sprite.flipX = image.flipX.getDefault(false); + sprite.flipY = image.flipY.getDefault(false); sprite.scale.set(scale, scale); sprite.updateHitbox(); sprite.screenCenter(X); diff --git a/source/lime/system/System.hx b/source/lime/system/System.hx index 98efafe3..64f8c771 100644 --- a/source/lime/system/System.hx +++ b/source/lime/system/System.hx @@ -367,7 +367,10 @@ class System #elseif mac Sys.command("/usr/bin/open", [path]); #elseif linux - Sys.command("/usr/bin/xdg-open", [path]); + // generally `xdg-open` should work in every distro + var cmd = Sys.command("xdg-open", [path, "&"]); + // run old command JUST IN CASE it fails, which it shouldn't + if (cmd != 0) cmd = Sys.command("/usr/bin/xdg-open", [path, "&"]); #elseif (js && html5) Browser.window.open(path, "_blank"); #elseif flash