diff --git a/.github/label-actions.yml b/.github/label-actions.yml new file mode 100644 index 000000000..1234d1526 --- /dev/null +++ b/.github/label-actions.yml @@ -0,0 +1,44 @@ +# Configuration for Label Actions - https://github.com/dessant/label-actions + +# Automatically close issues and pull requests when the `status: duplicate` label is applied +'status: duplicate': + issues: + # Post a comment + comment: > + This issue is a duplicate. Please direct all discussion to the original issue. + # Close the issue + close: true + # Remove other status labels + unlabel: + - 'status: pending triage' + # Set a close reason + close-reason: 'not planned' + prs: + # Post a comment + comment: > + This pull request is a duplicate. Please direct all discussion to the original pull request. + # Remove other status labels + unlabel: + - 'status: pending triage' + # Close the pull request + close: true + # Set a close reason + close-reason: 'not planned' + +'status: rejected': + issues: + # Close the issue + close: true + # Remove other status labels + unlabel: + - 'status: pending triage' + # Set a close reason + close-reason: 'not planned' + prs: + # Close the pull request + close: true + # Remove other status labels + unlabel: + - 'status: pending triage' + # Set a close reason + close-reason: 'not planned' diff --git a/.github/workflows/label-actions.yml b/.github/workflows/label-actions.yml new file mode 100644 index 000000000..bc4cf0add --- /dev/null +++ b/.github/workflows/label-actions.yml @@ -0,0 +1,29 @@ +# Perform actions when labels are applied to issues, discussions, or pull requests +# See .github/label-actions.yml +name: 'Label Actions' + +on: + issues: + types: + - labeled + - unlabeled + pull_request_target: + types: + - labeled + - unlabeled + discussion: + types: + - labeled + - unlabeled + +permissions: + contents: read + issues: write + pull-requests: write + discussions: write + +jobs: + action: + runs-on: ubuntu-latest + steps: + - uses: dessant/label-actions@v4 diff --git a/.github/workflows/label-issue.yml b/.github/workflows/label-issue.yml new file mode 100644 index 000000000..eeb83350c --- /dev/null +++ b/.github/workflows/label-issue.yml @@ -0,0 +1,52 @@ +name: "Issue Labeler" +on: + issues: + types: + - opened + - reopened + - edited + +jobs: + # When an issue is opened, perform a similarity check for potential duplicates. + # If some are found, add a label and comment listing the potential duplicate issues. + potential-duplicate: + name: Detect potential duplicate issues + runs-on: ubuntu-latest + steps: + - uses: wow-actions/potential-duplicates@v1 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Issue title filter work with anymatch https://www.npmjs.com/package/anymatch. + # Any matched issue will stop detection immediately. + # You can specify multi filters in each line. + filter: '' + # Exclude keywords in title before detecting. + exclude: '' + # Label to set, when potential duplicates are detected. + label: 'potential duplicate' + # Get issues with state to compare. Supported state: 'all', 'closed', 'open'. + state: all + # If similarity is higher than this threshold([0,1]), issue will be marked as duplicate. + # Turn this up if the detection is too sensitive + threshold: 0.6 + # Reactions to be add to comment when potential duplicates are detected. + # Available reactions: "-1", "+1", "confused", "laugh", "heart", "hooray", "rocket", "eyes" + # reactions: '-1' + # Comment to post when potential duplicates are detected. + comment: > + Potential duplicates: {{#issues}} + - [#{{ number }}] {{ title }} ({{ accuracy }}%) + {{/issues}} + # When an issue is opened, detect if it has an empty body or incomplete issue form. + # If it does, close the issue immediately. + empty-issues: + name: Close empty issues + runs-on: ubuntu-latest + steps: + - name: Run empty issues closer action + uses: rickstaa/empty-issues-closer-action@v1 + env: + github_token: ${{ secrets.GITHUB_TOKEN }} + with: + close_comment: Closing this issue because it appears to be empty. Please update the issue for it to be reopened. + open_comment: Reopening this issue because the author provided more information. diff --git a/.github/workflows/labeler.yml b/.github/workflows/label-pull-request.yml similarity index 84% rename from .github/workflows/labeler.yml rename to .github/workflows/label-pull-request.yml index a861af578..525e1b5a6 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/label-pull-request.yml @@ -3,6 +3,7 @@ on: - pull_request_target jobs: + # Apply labels to pull requests based on which files were edited labeler: permissions: contents: read @@ -13,6 +14,7 @@ jobs: uses: actions/labeler@v5 with: sync-labels: true + # Apply labels to pull requests based on how many lines were edited changed-lines-count-labeler: permissions: contents: read diff --git a/.gitmodules b/.gitmodules index be5e0aaa8..ad8099e60 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "assets"] path = assets - url = https://github.com/FunkinCrew/funkin.assets + url = https://github.com/FunkinCrew/Funkin-assets-secret [submodule "art"] path = art - url = https://github.com/FunkinCrew/funkin.art + url = https://github.com/FunkinCrew/Funkin-art-secret diff --git a/assets b/assets index bc7009b42..72bb24ac9 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit bc7009b4242691faa5c4552f7ca8a2f28e8cb1d2 +Subproject commit 72bb24ac9b0b9db4b2f9c38ef091e146ef16a1a4 diff --git a/example_mods/introMod/_polymod_meta.json b/example_mods/introMod/_polymod_meta.json index 4dc0cd804..74c4a2504 100644 --- a/example_mods/introMod/_polymod_meta.json +++ b/example_mods/introMod/_polymod_meta.json @@ -6,7 +6,7 @@ "name": "EliteMasterEric" } ], - "api_version": "0.1.0", + "api_version": "0.5.0", "mod_version": "1.0.0", "license": "Apache-2.0" } diff --git a/hmm.json b/hmm.json index 78c891078..bbe4897b7 100644 --- a/hmm.json +++ b/hmm.json @@ -70,14 +70,14 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "22f7c5a8ffca90d4677cffd6e570f53761709fbc", + "ref": "c9d96b168ea2a19274ad7c766ab1a34b57baa793", "url": "https://github.com/haxeui/haxeui-core" }, { "name": "haxeui-flixel", "type": "git", "dir": null, - "ref": "28bb710d0ae5d94b5108787593052165be43b980", + "ref": "013b9d4e56bfe9a034e028a8d685f0b274cb73c4", "url": "https://github.com/haxeui/haxeui-flixel" }, { diff --git a/project.hxp b/project.hxp index 1193a9cd4..ac047ff91 100644 --- a/project.hxp +++ b/project.hxp @@ -941,6 +941,8 @@ class Project extends HXProject { var commitHash:String = process.stdout.readLine(); var commitHashSplice:String = commitHash.substr(0, 7); + process.close(); + return commitHashSplice; } @@ -955,6 +957,8 @@ class Project extends HXProject { var branchName:String = branchProcess.stdout.readLine(); + branchProcess.close(); + return branchName; } @@ -979,6 +983,8 @@ class Project extends HXProject { } } + branchProcess.close(); + return output.length > 0; } diff --git a/source/Main.hx b/source/Main.hx index 724b118f8..1e1f8832d 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -2,6 +2,7 @@ package; import flixel.FlxGame; import flixel.FlxState; +import funkin.Preferences; import funkin.util.logging.CrashHandler; import funkin.ui.debug.MemoryCounter; import funkin.save.Save; @@ -22,12 +23,6 @@ class Main extends Sprite var gameHeight:Int = 720; // Height of the game in pixels (might be less / more in actual pixels depending on your zoom). var initialState:Class = funkin.InitState; // The FlxState the game starts with. var zoom:Float = -1; // If -1, zoom is automatically calculated to fit the window dimensions. - #if (web || CHEEMS) - var framerate:Int = 60; // How many frames per second the game should run at. - #else - // TODO: This should probably be in the options menu? - var framerate:Int = 144; // How many frames per second the game should run at. - #end var skipSplash:Bool = true; // Whether to skip the flixel splash screen that appears in release mode. var startFullscreen:Bool = false; // Whether to start the game in fullscreen on desktop targets @@ -109,7 +104,7 @@ class Main extends Sprite // George recommends binding the save before FlxGame is created. Save.load(); - var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, framerate, framerate, skipSplash, startFullscreen); + var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, Preferences.framerate, Preferences.framerate, skipSplash, startFullscreen); // FlxG.game._customSoundTray wants just the class, it calls new from // create() in there, which gets called when it's added to stage @@ -123,8 +118,6 @@ class Main extends Sprite game.debugger.interaction.addTool(new funkin.util.TrackerToolButtonUtil()); #end - addChild(fpsCounter); - #if hxcpp_debug_server trace('hxcpp_debug_server is enabled! You can now connect to the game with a debugger.'); #else diff --git a/source/funkin/Assets.hx b/source/funkin/Assets.hx index 5351676d4..967e4b0ca 100644 --- a/source/funkin/Assets.hx +++ b/source/funkin/Assets.hx @@ -1,38 +1,161 @@ package funkin; +import openfl.utils.Future; + /** * A wrapper around `openfl.utils.Assets` which disallows access to the harmful functions. * Later we'll add Funkin-specific caching to this. */ class Assets { - public static function getText(path:String):String + /** + * Get the file system path for an asset + * @param path The asset path to load from, relative to the assets folder + * @return The path to the asset on the file system + */ + public static function getPath(path:String):String { - return openfl.utils.Assets.getText(path); - } - - public static function getMusic(path:String):openfl.media.Sound - { - return openfl.utils.Assets.getMusic(path); - } - - public static function getBitmapData(path:String):openfl.display.BitmapData - { - return openfl.utils.Assets.getBitmapData(path); + return openfl.utils.Assets.getPath(path); } + /** + * Load bytes from an asset + * May cause stutters or throw an error if the asset is not cached + * @param path The asset path to load from + * @return The byte contents of the file + */ public static function getBytes(path:String):haxe.io.Bytes { return openfl.utils.Assets.getBytes(path); } + /** + * Load bytes from an asset asynchronously + * @param path The asset path to load from + * @return A future which promises to return the byte contents of the file + */ + public static function loadBytes(path:String):Future + { + return openfl.utils.Assets.loadBytes(path); + } + + /** + * Load text from an asset. + * May cause stutters or throw an error if the asset is not cached + * @param path The asset path to load from + * @return The text contents of the file + */ + public static function getText(path:String):String + { + return openfl.utils.Assets.getText(path); + } + + /** + * Load text from an asset asynchronously + * @param path The asset path to load from + * @return A future which promises to return the text contents of the file + */ + public static function loadText(path:String):Future + { + return openfl.utils.Assets.loadText(path); + } + + /** + * Load a Sound file from an asset + * May cause stutters or throw an error if the asset is not cached + * @param path The asset path to load from + * @return The loaded sound + */ + public static function getSound(path:String):openfl.media.Sound + { + return openfl.utils.Assets.getSound(path); + } + + /** + * Load a Sound file from an asset asynchronously + * @param path The asset path to load from + * @return A future which promises to return the loaded sound + */ + public static function loadSound(path:String):Future + { + return openfl.utils.Assets.loadSound(path); + } + + /** + * Load a Sound file from an asset, with optimizations specific to long-duration music + * May cause stutters or throw an error if the asset is not cached + * @param path The asset path to load from + * @return The loaded sound + */ + public static function getMusic(path:String):openfl.media.Sound + { + return openfl.utils.Assets.getMusic(path); + } + + /** + * Load a Sound file from an asset asynchronously, with optimizations specific to long-duration music + * @param path The asset path to load from + * @return A future which promises to return the loaded sound + */ + public static function loadMusic(path:String):Future + { + return openfl.utils.Assets.loadMusic(path); + } + + /** + * Load a Bitmap from an asset + * May cause stutters or throw an error if the asset is not cached + * @param path The asset path to load from + * @return The loaded Bitmap image + */ + public static function getBitmapData(path:String):openfl.display.BitmapData + { + return openfl.utils.Assets.getBitmapData(path); + } + + /** + * Load a Bitmap from an asset asynchronously + * @param path The asset path to load from + * @return The future which promises to return the loaded Bitmap image + */ + public static function loadBitmapData(path:String):Future + { + return openfl.utils.Assets.loadBitmapData(path); + } + + /** + * Determines whether the given asset of the given type exists. + * @param path The asset path to check + * @param type The asset type to check + * @return Whether the asset exists + */ public static function exists(path:String, ?type:openfl.utils.AssetType):Bool { return openfl.utils.Assets.exists(path, type); } - public static function list(type:openfl.utils.AssetType):Array + /** + * Retrieve a list of all assets of the given type + * @param type The asset type to check + * @return A list of asset paths + */ + public static function list(?type:openfl.utils.AssetType):Array { return openfl.utils.Assets.list(type); } + + public static function hasLibrary(name:String):Bool + { + return openfl.utils.Assets.hasLibrary(name); + } + + public static function getLibrary(name:String):lime.utils.AssetLibrary + { + return openfl.utils.Assets.getLibrary(name); + } + + public static function loadLibrary(name:String):Future + { + return openfl.utils.Assets.loadLibrary(name); + } } diff --git a/source/funkin/Paths.hx b/source/funkin/Paths.hx index 285af7ca2..ae77ac2da 100644 --- a/source/funkin/Paths.hx +++ b/source/funkin/Paths.hx @@ -2,7 +2,6 @@ package funkin; import flixel.graphics.frames.FlxAtlasFrames; import openfl.utils.AssetType; -import openfl.utils.Assets as OpenFlAssets; /** * A core class which handles determining asset paths. @@ -44,11 +43,11 @@ class Paths if (currentLevel != null) { var levelPath:String = getLibraryPathForce(file, currentLevel); - if (OpenFlAssets.exists(levelPath, type)) return levelPath; + if (Assets.exists(levelPath, type)) return levelPath; } var levelPath:String = getLibraryPathForce(file, 'shared'); - if (OpenFlAssets.exists(levelPath, type)) return levelPath; + if (Assets.exists(levelPath, type)) return levelPath; return getPreloadPath(file); } diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index daeded897..648880ad4 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -7,6 +7,35 @@ import funkin.save.Save; */ class Preferences { + /** + * FPS + * @default `60` + */ + public static var framerate(get, set):Int; + + static function get_framerate():Int + { + #if web + return 60; + #else + return Save?.instance?.options?.framerate ?? 60; + #end + } + + static function set_framerate(value:Int):Int + { + #if web + return 60; + #else + var save:Save = Save.instance; + save.options.framerate = value; + save.flush(); + FlxG.updateFramerate = value; + FlxG.drawFramerate = value; + return value; + #end + } + /** * Whether some particularly fowl language is displayed. * @default `true` diff --git a/source/funkin/data/freeplay/player/PlayerData.hx b/source/funkin/data/freeplay/player/PlayerData.hx index de293c24e..91df7a232 100644 --- a/source/funkin/data/freeplay/player/PlayerData.hx +++ b/source/funkin/data/freeplay/player/PlayerData.hx @@ -264,12 +264,32 @@ class PlayerCharSelectData */ @:optional public var position:Null; + + /** + * The GF name to assign for this character. + */ + @:optional + public var gf:PlayerCharSelectGFData; +} + +typedef PlayerCharSelectGFData = +{ + @:optional + public var assetPath:String; + + @:optional + public var animInfoPath:String; + + @:optional + @:default(false) + public var visualizer:Bool; } typedef PlayerResultsData = { var music:PlayerResultsMusicData; + var perfectGold:Array; var perfect:Array; var excellent:Array; var great:Array; diff --git a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx index 952fa8b71..aedb477bb 100644 --- a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx +++ b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx @@ -7,7 +7,6 @@ import flxanimate.frames.FlxAnimateFrames; import flixel.graphics.frames.FlxFrame; import flixel.system.FlxAssets.FlxGraphicAsset; import openfl.display.BitmapData; -import openfl.utils.Assets; import flixel.math.FlxPoint; import flxanimate.animate.FlxKeyFrame; @@ -184,7 +183,7 @@ class FlxAtlasSprite extends FlxAnimate // Move to the first frame of the animation. // goToFrameLabel(id); - trace('Playing animation $id'); + // trace('Playing animation $id'); if ((id == null || id == "") || this.anim.symbolDictionary.exists(id) || (this.anim.getByName(id) != null)) { this.anim.play(id, restart, false, startFrame); diff --git a/source/funkin/graphics/shaders/AdjustColorShader.hx b/source/funkin/graphics/shaders/AdjustColorShader.hx index 2b0970eeb..a6efc3e65 100644 --- a/source/funkin/graphics/shaders/AdjustColorShader.hx +++ b/source/funkin/graphics/shaders/AdjustColorShader.hx @@ -1,8 +1,6 @@ package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; -import funkin.Paths; -import openfl.utils.Assets; class AdjustColorShader extends FlxRuntimeShader { diff --git a/source/funkin/graphics/shaders/BlendModesShader.hx b/source/funkin/graphics/shaders/BlendModesShader.hx index b7a405dd1..e6ae45dd7 100644 --- a/source/funkin/graphics/shaders/BlendModesShader.hx +++ b/source/funkin/graphics/shaders/BlendModesShader.hx @@ -1,8 +1,6 @@ package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; -import funkin.Paths; -import openfl.utils.Assets; import openfl.display.BitmapData; import openfl.display.ShaderInput; diff --git a/source/funkin/graphics/shaders/GaussianBlurShader.hx b/source/funkin/graphics/shaders/GaussianBlurShader.hx index cecfdab80..023a66853 100644 --- a/source/funkin/graphics/shaders/GaussianBlurShader.hx +++ b/source/funkin/graphics/shaders/GaussianBlurShader.hx @@ -1,8 +1,6 @@ package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; -import funkin.Paths; -import openfl.utils.Assets; /** * Note... not actually gaussian! diff --git a/source/funkin/graphics/shaders/Grayscale.hx b/source/funkin/graphics/shaders/Grayscale.hx index fbd0970e5..6fbdd1881 100644 --- a/source/funkin/graphics/shaders/Grayscale.hx +++ b/source/funkin/graphics/shaders/Grayscale.hx @@ -1,8 +1,6 @@ package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; -import funkin.Paths; -import openfl.utils.Assets; class Grayscale extends FlxRuntimeShader { diff --git a/source/funkin/graphics/shaders/HSVShader.hx b/source/funkin/graphics/shaders/HSVShader.hx index 587008ce2..dda841ad9 100644 --- a/source/funkin/graphics/shaders/HSVShader.hx +++ b/source/funkin/graphics/shaders/HSVShader.hx @@ -1,8 +1,6 @@ package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; -import funkin.Paths; -import openfl.utils.Assets; class HSVShader extends FlxRuntimeShader { diff --git a/source/funkin/graphics/shaders/MosaicEffect.hx b/source/funkin/graphics/shaders/MosaicEffect.hx index fc3737aff..76a6b6f3d 100644 --- a/source/funkin/graphics/shaders/MosaicEffect.hx +++ b/source/funkin/graphics/shaders/MosaicEffect.hx @@ -1,8 +1,6 @@ package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; -import openfl.utils.Assets; -import funkin.Paths; import flixel.math.FlxPoint; class MosaicEffect extends FlxRuntimeShader diff --git a/source/funkin/graphics/shaders/RuntimeCustomBlendShader.hx b/source/funkin/graphics/shaders/RuntimeCustomBlendShader.hx index 3e8dfedd3..74ce7f4ea 100644 --- a/source/funkin/graphics/shaders/RuntimeCustomBlendShader.hx +++ b/source/funkin/graphics/shaders/RuntimeCustomBlendShader.hx @@ -2,7 +2,6 @@ package funkin.graphics.shaders; import openfl.display.BitmapData; import openfl.display.BlendMode; -import openfl.utils.Assets; class RuntimeCustomBlendShader extends RuntimePostEffectShader { diff --git a/source/funkin/graphics/shaders/RuntimeRainShader.hx b/source/funkin/graphics/shaders/RuntimeRainShader.hx index d0c036623..5d8df3f2c 100644 --- a/source/funkin/graphics/shaders/RuntimeRainShader.hx +++ b/source/funkin/graphics/shaders/RuntimeRainShader.hx @@ -5,7 +5,6 @@ import openfl.display.BitmapData; import openfl.display.ShaderParameter; import openfl.display.ShaderParameterType; import flixel.util.FlxColor; -import openfl.utils.Assets; typedef Light = { diff --git a/source/funkin/import.hx b/source/funkin/import.hx index c8431be33..a29e19977 100644 --- a/source/funkin/import.hx +++ b/source/funkin/import.hx @@ -3,6 +3,7 @@ package; #if !macro // Only import these when we aren't in a macro. import funkin.util.Constants; +import funkin.Assets; import funkin.Paths; import funkin.Preferences; import flixel.FlxG; // This one in particular causes a compile error if you're using macros. diff --git a/source/funkin/input/Cursor.hx b/source/funkin/input/Cursor.hx index 39f399465..554a6b2c1 100644 --- a/source/funkin/input/Cursor.hx +++ b/source/funkin/input/Cursor.hx @@ -1,7 +1,6 @@ package funkin.input; import haxe.ui.backend.flixel.CursorHelper; -import openfl.utils.Assets; import lime.app.Future; import openfl.display.BitmapData; diff --git a/source/funkin/modding/PolymodHandler.hx b/source/funkin/modding/PolymodHandler.hx index 75c69e506..ec3acf3b3 100644 --- a/source/funkin/modding/PolymodHandler.hx +++ b/source/funkin/modding/PolymodHandler.hx @@ -228,6 +228,8 @@ class PolymodHandler static function buildImports():Void { // Add default imports for common classes. + Polymod.addDefaultImport(funkin.Assets); + Polymod.addDefaultImport(funkin.Paths); // Add import aliases for certain classes. // NOTE: Scripted classes are automatically aliased to their parent class. @@ -258,7 +260,7 @@ class PolymodHandler Polymod.blacklistImport('cpp.Lib'); // `Unserializer` - // Unserializerr.DEFAULT_RESOLVER.resolveClass() can access blacklisted packages + // Unserializer.DEFAULT_RESOLVER.resolveClass() can access blacklisted packages Polymod.blacklistImport('Unserializer'); // `lime.system.CFFI` diff --git a/source/funkin/play/Countdown.hx b/source/funkin/play/Countdown.hx index 643883a43..94a7548b9 100644 --- a/source/funkin/play/Countdown.hx +++ b/source/funkin/play/Countdown.hx @@ -11,7 +11,6 @@ import funkin.modding.events.ScriptEvent.CountdownScriptEvent; import flixel.util.FlxTimer; import funkin.util.EaseUtil; import funkin.audio.FunkinSound; -import openfl.utils.Assets; import funkin.data.notestyle.NoteStyleRegistry; import funkin.play.notes.notestyle.NoteStyle; diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index f6a7148f8..bf8735647 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -15,7 +15,6 @@ import funkin.ui.freeplay.FreeplayState; import funkin.ui.MusicBeatSubState; import funkin.ui.story.StoryMenuState; import funkin.util.MathUtil; -import openfl.utils.Assets; import funkin.effects.RetroCameraFade; import flixel.math.FlxPoint; diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index a25d3b231..b304381cc 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1612,7 +1612,7 @@ class PlayState extends MusicBeatSubState if (girlfriend != null) { - girlfriend.characterType = CharacterType.GF; + // Don't need to do anything. } else if (currentCharacterData.girlfriend != '') { @@ -1630,8 +1630,6 @@ class PlayState extends MusicBeatSubState if (dad != null) { - dad.characterType = CharacterType.DAD; - // // OPPONENT HEALTH ICON // @@ -1650,8 +1648,6 @@ class PlayState extends MusicBeatSubState if (boyfriend != null) { - boyfriend.characterType = CharacterType.BF; - // // PLAYER HEALTH ICON // @@ -3046,7 +3042,6 @@ class PlayState extends MusicBeatSubState GameOverSubState.reset(); PauseSubState.reset(); Countdown.reset(); - PopUpStuff.reset(); // Clear the static reference to this state. instance = null; diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 739df167d..33f3587ea 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -472,9 +472,12 @@ class ResultState extends MusicBeatSubState { ease: FlxEase.quartOut, onUpdate: _ -> { + clearPercentLerp = Math.round(clearPercentLerp); + clearPercentCounter.curNumber = Math.round(clearPercentCounter.curNumber); // Only play the tick sound if the number increased. if (clearPercentLerp != clearPercentCounter.curNumber) { + trace('$clearPercentLerp and ${clearPercentCounter.curNumber}'); clearPercentLerp = clearPercentCounter.curNumber; FunkinSound.playOnce(Paths.sound('scrollMenu')); } diff --git a/source/funkin/play/character/CharacterData.hx b/source/funkin/play/character/CharacterData.hx index bac2c7141..54e7a6afb 100644 --- a/source/funkin/play/character/CharacterData.hx +++ b/source/funkin/play/character/CharacterData.hx @@ -11,7 +11,7 @@ import funkin.play.character.ScriptedCharacter.ScriptedSparrowCharacter; import funkin.util.assets.DataAssets; import funkin.util.VersionUtil; import haxe.Json; -import openfl.utils.Assets; +import flixel.graphics.frames.FlxFrame; class CharacterDataParser { @@ -281,41 +281,78 @@ class CharacterDataParser } /** - * TODO: Hardcode this. + * Returns the idle frame of a character. */ - public static function getCharPixelIconAsset(char:String):String + public static function getCharPixelIconAsset(char:String):FlxFrame { - var icon:String = char; + var charPath:String = "freeplay/icons/"; - switch (icon) + // FunkinCrew please dont skin me alive for copying pixelated icon and changing it a tiny bit + switch (char) { - case "bf-christmas" | "bf-car" | "bf-pixel" | "bf-holding-gf": - icon = "bf"; + case "bf-christmas" | "bf-car" | "bf-pixel" | "bf-holding-gf" | "bf-dark": + charPath += "bfpixel"; case "monster-christmas": - icon = "monster"; + charPath += "monsterpixel"; case "mom" | "mom-car": - icon = "mommy"; + charPath += "mommypixel"; case "pico-blazin" | "pico-playable" | "pico-speaker": - icon = "pico"; - case "gf-christmas" | "gf-car" | "gf-pixel" | "gf-tankmen": - icon = "gf"; + charPath += "picopixel"; + case "gf-christmas" | "gf-car" | "gf-pixel" | "gf-tankmen" | "gf-dark": + charPath += "gfpixel"; case "dad": - icon = "daddy"; + charPath += "dadpixel"; case "darnell-blazin": - icon = "darnell"; + charPath += "darnellpixel"; case "senpai-angry": - icon = "senpai"; + charPath += "senpaipixel"; case "spooky-dark": - icon = "spooky"; + charPath += "spookypixel"; case "tankman-atlas": - icon = "tankman"; + charPath += "tankmanpixel"; + case "pico-christmas" | "pico-dark": + charPath += "picopixel"; + default: + charPath += '${char}pixel'; } - var path = Paths.image("freeplay/icons/" + icon + "pixel"); - if (Assets.exists(path)) return path; + if (!Assets.exists(Paths.image(charPath))) + { + trace('[WARN] Character ${char} has no freeplay icon.'); + return null; + } - // TODO: Hardcode some additional behavior or a fallback. - return null; + var isAnimated = Assets.exists(Paths.file('images/$charPath.xml')); + var frame:FlxFrame = null; + + if (isAnimated) + { + var frames = Paths.getSparrowAtlas(charPath); + + var idleFrame:FlxFrame = frames.frames.find(function(frame:FlxFrame):Bool { + return frame.name.startsWith('idle'); + }); + + if (idleFrame == null) + { + trace('[WARN] Character ${char} has no idle in their freeplay icon.'); + return null; + } + + // so, haxe.ui.backend.AssetsImpl uses the parent width and height, which makes the image go crazy when rendered + // so this is a work around so that it uses the actual width and height + var imageGraphic = flixel.graphics.FlxGraphic.fromFrame(idleFrame); + + var imageFrame = flixel.graphics.frames.FlxImageFrame.fromImage(imageGraphic); + frame = imageFrame.frame; + } + else + { + var imageFrame = flixel.graphics.frames.FlxImageFrame.fromImage(Paths.image(charPath)); + frame = imageFrame.frame; + } + + return frame; } /** diff --git a/source/funkin/play/components/HealthIcon.hx b/source/funkin/play/components/HealthIcon.hx index 358f39fe5..f6430457f 100644 --- a/source/funkin/play/components/HealthIcon.hx +++ b/source/funkin/play/components/HealthIcon.hx @@ -5,7 +5,6 @@ import flixel.FlxSprite; import flixel.math.FlxMath; import flixel.math.FlxPoint; import funkin.play.character.CharacterData.CharacterDataParser; -import openfl.utils.Assets; import funkin.graphics.FunkinSprite; import funkin.util.MathUtil; diff --git a/source/funkin/play/components/PopUpStuff.hx b/source/funkin/play/components/PopUpStuff.hx index e5e9b4681..fbc97283f 100644 --- a/source/funkin/play/components/PopUpStuff.hx +++ b/source/funkin/play/components/PopUpStuff.hx @@ -8,7 +8,6 @@ import funkin.graphics.FunkinSprite; import funkin.play.PlayState; import funkin.util.TimerUtil; import funkin.util.EaseUtil; -import openfl.utils.Assets; import funkin.data.notestyle.NoteStyleRegistry; import funkin.play.notes.notestyle.NoteStyle; @@ -125,13 +124,4 @@ class PopUpStuff extends FlxTypedGroup daLoop++; } } - - /** - * Reset the popup configuration to the default. - */ - public static function reset() - { - noteStyle = NoteStyleRegistry.instance.fetchDefault(); - isPixel = false; - } } diff --git a/source/funkin/play/notes/StrumlineNote.hx b/source/funkin/play/notes/StrumlineNote.hx index d8230aa28..16df9f502 100644 --- a/source/funkin/play/notes/StrumlineNote.hx +++ b/source/funkin/play/notes/StrumlineNote.hx @@ -85,7 +85,8 @@ class StrumlineNote extends FlxSprite noteStyle.applyStrumlineFrames(this); noteStyle.applyStrumlineAnimations(this, this.direction); - this.setGraphicSize(Std.int(Strumline.STRUMLINE_SIZE * noteStyle.getStrumlineScale())); + var scale = noteStyle.getStrumlineScale(); + this.scale.set(scale, scale); this.updateHitbox(); noteStyle.applyStrumlineOffsets(this); diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index 90b36b009..a9af468b9 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -87,6 +87,7 @@ class SustainTrail extends FlxSprite public var bottomClip:Float = 0.9; public var isPixel:Bool; + public var noteStyleOffsets:Array; var graphicWidth:Float = 0; var graphicHeight:Float = 0; @@ -107,6 +108,7 @@ class SustainTrail extends FlxSprite this.noteDirection = noteDirection; setupHoldNoteGraphic(noteStyle); + noteStyleOffsets = noteStyle.getHoldNoteOffsets(); indices = new DrawData(12, true, TRIANGLE_VERTEX_INDICES); @@ -137,7 +139,6 @@ class SustainTrail extends FlxSprite zoom = 1.0; zoom *= noteStyle.fetchHoldNoteScale(); - zoom *= 0.7; // CALCULATE SIZE graphicWidth = graphic.width / 8 * zoom; // amount of notes * 2 @@ -202,7 +203,7 @@ class SustainTrail extends FlxSprite { width = graphicWidth; height = graphicHeight; - offset.set(0, 0); + offset.set(noteStyleOffsets[0], noteStyleOffsets[1]); origin.set(width * 0.5, height * 0.5); } diff --git a/source/funkin/play/notes/notestyle/NoteStyle.hx b/source/funkin/play/notes/notestyle/NoteStyle.hx index ee07703f1..c2f7ec009 100644 --- a/source/funkin/play/notes/notestyle/NoteStyle.hx +++ b/source/funkin/play/notes/notestyle/NoteStyle.hx @@ -93,7 +93,8 @@ class NoteStyle implements IRegistryEntry buildNoteAnimations(target); // Set the scale. - target.setGraphicSize(Strumline.STRUMLINE_SIZE * getNoteScale()); + var scale = getNoteScale(); + target.scale.set(scale, scale); target.updateHitbox(); } @@ -224,6 +225,13 @@ class NoteStyle implements IRegistryEntry return data?.scale ?? 1.0; } + public function getHoldNoteOffsets():Array + { + var data = _data?.assets?.holdNote; + if (data == null && fallback != null) return fallback.getHoldNoteOffsets(); + return data?.offsets ?? [0.0, 0.0]; + } + public function applyStrumlineFrames(target:StrumlineNote):Void { // TODO: Add support for multi-Sparrow. @@ -304,9 +312,16 @@ class NoteStyle implements IRegistryEntry return thx.Arrays.filterNull(result); } + public function getStrumlineOffsets():Array + { + var data = _data?.assets?.noteStrumline; + if (data == null && fallback != null) return fallback.getStrumlineOffsets(); + return data?.offsets ?? [0.0, 0.0]; + } + public function applyStrumlineOffsets(target:StrumlineNote):Void { - var offsets = _data?.assets?.noteStrumline?.offsets ?? [0.0, 0.0]; + var offsets = getStrumlineOffsets(); target.x += offsets[0]; target.y += offsets[1]; } @@ -575,7 +590,7 @@ class NoteStyle implements IRegistryEntry var result = _data.assets.judgementBad?.isPixel; if (result == null && fallback != null) result = fallback.isJudgementSpritePixel(rating); return result ?? false; - case "GO": + case "shit": var result = _data.assets.judgementShit?.isPixel; if (result == null && fallback != null) result = fallback.isJudgementSpritePixel(rating); return result ?? false; diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 9d35902b0..9023b872e 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -16,7 +16,6 @@ import funkin.modding.IScriptedClass.IPlayStateScriptedClass; import funkin.modding.events.ScriptEvent; import funkin.ui.freeplay.charselect.PlayableCharacter; import funkin.util.SortUtil; -import openfl.utils.Assets; /** * This is a data structure managing information about the current song. diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index c42e41cad..ad768769c 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -464,6 +464,9 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements #end } + // Set the characters type + character.characterType = charType; + // Add the character to the scene. this.add(character); diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 2bbda15c0..0d86c628b 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -17,7 +17,7 @@ import thx.semver.Version; @:nullSafety class Save { - public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.5"; + public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.4"; public static final SAVE_DATA_VERSION_RULE:thx.semver.VersionRule = "2.0.x"; // We load this version's saves from a new save path, to maintain SOME level of backwards compatibility. @@ -34,19 +34,19 @@ class Save { if (_instance == null) { - _instance = new Save(FlxG.save.data); + return _instance = load(); } return _instance; } var data:RawSaveData; - public static function load():Void + public static function load():Save { trace("[SAVE] Loading save..."); // Bind save data. - loadFromSlot(1); + return loadFromSlot(1); } /** @@ -65,7 +65,9 @@ class Save public static function getDefault():RawSaveData { return { - version: Save.SAVE_DATA_VERSION, + // Version number is an abstract(Array) internally. + // This means it copies by reference, so merging save data overides the version number lol. + version: thx.Dynamics.clone(Save.SAVE_DATA_VERSION), volume: 1.0, mute: false, @@ -89,6 +91,7 @@ class Save options: { // Reasonable defaults. + framerate: 60, naughtyness: true, downscroll: false, flashingLights: true, @@ -433,7 +436,9 @@ class Save { if (!data.unlocks.charactersSeen.contains(character)) { + trace('Character seen: ' + character); data.unlocks.charactersSeen.push(character); + trace('New characters seen list: ' + data.unlocks.charactersSeen); flush(); } } @@ -832,7 +837,7 @@ class Save * If you set slot to `2`, it will load an independe * @param slot */ - static function loadFromSlot(slot:Int):Void + static function loadFromSlot(slot:Int):Save { trace("[SAVE] Loading save from slot " + slot + "..."); @@ -850,12 +855,14 @@ class Save trace('[SAVE] Found legacy save data, converting...'); var gameSave = SaveDataMigrator.migrateFromLegacy(legacySaveData); FlxG.save.mergeData(gameSave.data, true); + return gameSave; } else { trace('[SAVE] No legacy save data found.'); var gameSave = new Save(); FlxG.save.mergeData(gameSave.data, true); + return gameSave; } } else @@ -863,6 +870,8 @@ class Save trace('[SAVE] Found existing save data.'); var gameSave = SaveDataMigrator.migrate(FlxG.save.data); FlxG.save.mergeData(gameSave.data, true); + + return gameSave; } } @@ -1133,6 +1142,12 @@ typedef SaveScoreTallyData = */ typedef SaveDataOptions = { + /** + * FPS + * @default `60` + */ + var framerate:Int; + /** * Whether some particularly fowl language is displayed. * @default `true` diff --git a/source/funkin/save/changelog.md b/source/funkin/save/changelog.md index e3038373d..41d6e68ae 100644 --- a/source/funkin/save/changelog.md +++ b/source/funkin/save/changelog.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.4] - 2024-09-12 +Note to self: Only update to 2.1.0 when migration is needed. +### Added +- `unlocks.charactersSeen:Array` to `Save` +- `unlocks.oldChar:Bool` to `Save` + ## [2.0.5] - 2024-05-21 ### Fixed - Resolved an issue where HTML5 wouldn't store the semantic version properly, causing the game to fail to load the save. diff --git a/source/funkin/ui/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx index 02cebeb45..37e5a31f7 100644 --- a/source/funkin/ui/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -37,17 +37,25 @@ class MusicBeatSubState extends FlxSubState implements IEventHandler return _conductorInUse = value; } - public function new(bgColor:FlxColor = FlxColor.TRANSPARENT) - { - super(); - this.bgColor = bgColor; - } - var controls(get, never):Controls; inline function get_controls():Controls return PlayerSettings.player1.controls; + public function new(bgColor:FlxColor = FlxColor.TRANSPARENT) + { + super(); + this.bgColor = bgColor; + + initCallbacks(); + } + + function initCallbacks() + { + subStateOpened.add(onOpenSubStateComplete); + subStateClosed.add(onCloseSubStateComplete); + } + override function create():Void { super.create(); diff --git a/source/funkin/ui/charSelect/CharSelectGF.hx b/source/funkin/ui/charSelect/CharSelectGF.hx index e8eeded40..89fc6deb0 100644 --- a/source/funkin/ui/charSelect/CharSelectGF.hx +++ b/source/funkin/ui/charSelect/CharSelectGF.hx @@ -11,6 +11,7 @@ import funkin.modding.IScriptedClass.IBPMSyncedScriptedClass; import flixel.math.FlxMath; import funkin.modding.events.ScriptEvent; import funkin.vis.dsp.SpectralAnalyzer; +import funkin.data.freeplay.player.PlayerRegistry; class CharSelectGF extends FlxAtlasSprite implements IBPMSyncedScriptedClass { @@ -27,7 +28,8 @@ class CharSelectGF extends FlxAtlasSprite implements IBPMSyncedScriptedClass var analyzer:SpectralAnalyzer; - var curGF:GFChar = GF; + var currentGFPath:Null; + var enableVisualizer:Bool = false; public function new() { @@ -97,7 +99,7 @@ class CharSelectGF extends FlxAtlasSprite implements IBPMSyncedScriptedClass function drawFFT() { - if (curGF == NENE) + if (enableVisualizer) { var levels = analyzer.getLevels(); var frame = anim.curSymbol.timeline.get("VIZ_bars").get(anim.curFrame); @@ -172,28 +174,33 @@ class CharSelectGF extends FlxAtlasSprite implements IBPMSyncedScriptedClass */ public function switchGF(bf:String):Void { - var prevGF:GFChar = curGF; - switch (bf) - { - case "pico": - curGF = NENE; - case "bf": - curGF = GF; - default: - curGF = GF; - } + var previousGFPath = currentGFPath; + + var bfObj = PlayerRegistry.instance.fetchEntry(bf); + var gfData = bfObj?.getCharSelectData()?.gf; + currentGFPath = gfData?.assetPath != null ? Paths.animateAtlas(gfData?.assetPath) : null; // We don't need to update any anims if we didn't change GF - if (prevGF != curGF) + trace('currentGFPath(${currentGFPath})'); + if (currentGFPath == null) { - loadAtlas(Paths.animateAtlas("charSelect/" + curGF + "Chill")); + this.visible = false; + return; + } + else if (previousGFPath != currentGFPath) + { + this.visible = true; + loadAtlas(currentGFPath); - animInInfo = FramesJSFLParser.parse(Paths.file("images/charSelect/" + curGF + "AnimInfo/" + curGF + "In.txt")); - animOutInfo = FramesJSFLParser.parse(Paths.file("images/charSelect/" + curGF + "AnimInfo/" + curGF + "Out.txt")); + enableVisualizer = gfData?.visualizer ?? false; + + var animInfoPath = Paths.file('images/${gfData?.animInfoPath}'); + + animInInfo = FramesJSFLParser.parse(animInfoPath + '/In.txt'); + animOutInfo = FramesJSFLParser.parse(animInfoPath + '/Out.txt'); } playAnimation("idle", true, false, false); - // addFrameCallback(getNextFrameLabel("idle"), () -> playAnimation("idle", true, false, false)); updateHitbox(); } @@ -213,9 +220,3 @@ enum FadeStatus FADE_OUT; FADE_IN; } - -enum abstract GFChar(String) from String to String -{ - var GF = "gf"; - var NENE = "nene"; -} diff --git a/source/funkin/ui/charSelect/CharSelectPlayer.hx b/source/funkin/ui/charSelect/CharSelectPlayer.hx index b6319f16d..1eef52bed 100644 --- a/source/funkin/ui/charSelect/CharSelectPlayer.hx +++ b/source/funkin/ui/charSelect/CharSelectPlayer.hx @@ -47,7 +47,6 @@ class CharSelectPlayer extends FlxAtlasSprite implements IBPMSyncedScriptedClass // if (getCurrentAnimation() == "idle") { - trace('Player beat hit'); playAnimation("idle", true, false, false); } }; diff --git a/source/funkin/ui/charSelect/CharSelectSubState.hx b/source/funkin/ui/charSelect/CharSelectSubState.hx index 3109dc8f1..70731ac2e 100644 --- a/source/funkin/ui/charSelect/CharSelectSubState.hx +++ b/source/funkin/ui/charSelect/CharSelectSubState.hx @@ -71,6 +71,7 @@ class CharSelectSubState extends MusicBeatSubState var availableChars:Map = new Map(); var pressedSelect:Bool = false; var selectTimer:FlxTimer = new FlxTimer(); + var allowInput:Bool = false; var selectSound:FunkinSound; var unlockSound:FunkinSound; @@ -430,6 +431,8 @@ class CharSelectSubState extends MusicBeatSubState overrideExisting: true, restartTrack: true, onLoad: function() { + allowInput = true; + @:privateAccess gfChill.analyzer = new SpectralAnalyzer(FlxG.sound.music._channel.__audioSource, 7, 0.1); #if desktop @@ -573,6 +576,8 @@ class CharSelectSubState extends MusicBeatSubState overrideExisting: true, restartTrack: true, onLoad: function() { + allowInput = true; + @:privateAccess gfChill.analyzer = new SpectralAnalyzer(FlxG.sound.music._channel.__audioSource, 7, 0.1); #if desktop @@ -642,6 +647,7 @@ class CharSelectSubState extends MusicBeatSubState function goToFreeplay():Void { + allowInput = false; autoFollow = false; FlxTween.tween(cursor, {alpha: 0}, 0.8, {ease: FlxEase.expoOut}); @@ -695,7 +701,7 @@ class CharSelectSubState extends MusicBeatSubState syncAudio(elapsed); - if (!pressedSelect) + if (allowInput && !pressedSelect) { if (controls.UI_UP) holdTmrUp += elapsed; if (controls.UI_UP_R) @@ -786,10 +792,9 @@ class CharSelectSubState extends MusicBeatSubState && availableChars.exists(getCurrentSelected()) && Save.instance.charactersSeen.contains(availableChars[getCurrentSelected()])) { - gfChill.visible = true; curChar = availableChars.get(getCurrentSelected()); - if (!pressedSelect && controls.ACCEPT) + if (allowInput && !pressedSelect && controls.ACCEPT) { cursorConfirmed.visible = true; cursorConfirmed.x = cursor.x - 2; @@ -817,7 +822,7 @@ class CharSelectSubState extends MusicBeatSubState }); } - if (pressedSelect && controls.BACK) + if (allowInput && pressedSelect && controls.BACK) { cursorConfirmed.visible = false; grpCursors.visible = true; @@ -847,7 +852,7 @@ class CharSelectSubState extends MusicBeatSubState gfChill.visible = false; - if (controls.ACCEPT) + if (allowInput && controls.ACCEPT) { cursorDenied.visible = true; cursorDenied.x = cursor.x - 2; diff --git a/source/funkin/ui/debug/anim/DebugBoundingState.hx b/source/funkin/ui/debug/anim/DebugBoundingState.hx index 19391f8d9..4573ffbc7 100644 --- a/source/funkin/ui/debug/anim/DebugBoundingState.hx +++ b/source/funkin/ui/debug/anim/DebugBoundingState.hx @@ -24,7 +24,6 @@ import haxe.ui.core.Screen; import haxe.ui.events.UIEvent; import haxe.ui.RuntimeComponentBuilder; import lime.utils.Assets as LimeAssets; -import openfl.Assets; import openfl.events.Event; import openfl.events.IOErrorEvent; import openfl.geom.Rectangle; @@ -77,7 +76,7 @@ class DebugBoundingState extends FlxState { // get the screen position, according to the HUD camera, temp default to FlxG.camera juuust in case? var hudMousePos:FlxPoint = FlxG.mouse.getScreenPosition(hudCam ?? FlxG.camera); - return Screen.instance.hasSolidComponentUnderPoint(hudMousePos.x, hudMousePos.y) || FlxG.mouse.overlaps(animDropDownMenu, hudCam); + return Screen.instance.hasSolidComponentUnderPoint(hudMousePos.x, hudMousePos.y); } override function create() diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 467b6e29f..7f8bfdca7 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -700,7 +700,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState function get_isCursorOverHaxeUI():Bool { - return Screen.instance.hasSolidComponentUnderPoint(FlxG.mouse.screenX, FlxG.mouse.screenY); + return Screen.instance.hasSolidComponentUnderPoint(FlxG.mouse.viewX, FlxG.mouse.viewY); } /** @@ -3840,7 +3840,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Handle scroll anchor if (scrollAnchorScreenPos != null) { - var currentScreenPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY); + var currentScreenPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewX); var distance = currentScreenPos - scrollAnchorScreenPos; var verticalDistance = distance.y; @@ -4121,8 +4121,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var overlapsRenderedEvents:Bool = FlxG.mouse.overlaps(renderedEvents); // Cursor position relative to the grid. - var cursorX:Float = FlxG.mouse.screenX - gridTiledSprite.x; - var cursorY:Float = FlxG.mouse.screenY - gridTiledSprite.y; + var cursorX:Float = FlxG.mouse.viewX - gridTiledSprite.x; + var cursorY:Float = FlxG.mouse.viewY - gridTiledSprite.y; var overlapsSelectionBorder:Bool = overlapsGrid && ((cursorX % 40) < (GRID_SELECTION_BORDER_WIDTH / 2) @@ -4137,7 +4137,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState { if (scrollAnchorScreenPos == null) { - scrollAnchorScreenPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY); + scrollAnchorScreenPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewY); selectionBoxStartPos = null; } else @@ -4159,11 +4159,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState else if (notePreview != null && FlxG.mouse.overlaps(notePreview) && !isCursorOverHaxeUI) { // Clicked note preview - notePreviewScrollAreaStartPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY); + notePreviewScrollAreaStartPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewY); } else if (!isCursorOverHaxeUI && (!overlapsGrid || overlapsSelectionBorder)) { - selectionBoxStartPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY); + selectionBoxStartPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewY); // Drawing selection box. targetCursorMode = Crosshair; } @@ -4188,7 +4188,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState { // Clicked on the playhead scroll area. // Move the playhead to the cursor position. - this.playheadPositionInPixels = FlxG.mouse.screenY - (GRID_INITIAL_Y_POS); + this.playheadPositionInPixels = FlxG.mouse.viewY - (GRID_INITIAL_Y_POS); moveSongToScrollPosition(); // Cursor should be a grabby hand. @@ -4313,27 +4313,27 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Clicking and dragging. // Scroll the screen if the mouse is above or below the grid. - if (FlxG.mouse.screenY < MENU_BAR_HEIGHT) + if (FlxG.mouse.viewY < MENU_BAR_HEIGHT) { // Scroll up. - var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.screenY; + var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.viewY; scrollPositionInPixels -= diff * 0.5; // Too fast! moveSongToScrollPosition(); } - else if (FlxG.mouse.screenY > (playbarHeadLayout?.y ?? 0.0)) + else if (FlxG.mouse.viewY > (playbarHeadLayout?.y ?? 0.0)) { // Scroll down. - var diff:Float = FlxG.mouse.screenY - (playbarHeadLayout?.y ?? 0.0); + var diff:Float = FlxG.mouse.viewY - (playbarHeadLayout?.y ?? 0.0); scrollPositionInPixels += diff * 0.5; // Too fast! moveSongToScrollPosition(); } // Render the selection box. var selectionRect:FlxRect = new FlxRect(); - selectionRect.x = Math.min(FlxG.mouse.screenX, selectionBoxStartPos.x); - selectionRect.y = Math.min(FlxG.mouse.screenY, selectionBoxStartPos.y); - selectionRect.width = Math.abs(FlxG.mouse.screenX - selectionBoxStartPos.x); - selectionRect.height = Math.abs(FlxG.mouse.screenY - selectionBoxStartPos.y); + selectionRect.x = Math.min(FlxG.mouse.viewX, selectionBoxStartPos.x); + selectionRect.y = Math.min(FlxG.mouse.viewY, selectionBoxStartPos.y); + selectionRect.width = Math.abs(FlxG.mouse.viewX - selectionBoxStartPos.x); + selectionRect.height = Math.abs(FlxG.mouse.viewY - selectionBoxStartPos.y); setSelectionBoxBounds(selectionRect); targetCursorMode = Crosshair; @@ -4461,8 +4461,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Player is clicking and holding on note preview to scrub around. targetCursorMode = Grabbing; - var clickedPosInPixels:Float = FlxMath.remapToRange(FlxG.mouse.screenY, (notePreview?.y ?? 0.0), - (notePreview?.y ?? 0.0) + (notePreview?.height ?? 0.0), 0, songLengthInPixels); + var clickedPosInPixels:Float = FlxMath.remapToRange(FlxG.mouse.viewY, (notePreview?.y ?? 0.0), (notePreview?.y ?? 0.0) + (notePreview?.height ?? 0.0), + 0, songLengthInPixels); scrollPositionInPixels = clickedPosInPixels; moveSongToScrollPosition(); @@ -4520,17 +4520,17 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState targetCursorMode = Grabbing; // Scroll the screen if the mouse is above or below the grid. - if (FlxG.mouse.screenY < MENU_BAR_HEIGHT) + if (FlxG.mouse.viewY < MENU_BAR_HEIGHT) { // Scroll up. - var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.screenY; + var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.viewY; scrollPositionInPixels -= diff * 0.5; // Too fast! moveSongToScrollPosition(); } - else if (FlxG.mouse.screenY > (playbarHeadLayout?.y ?? 0.0)) + else if (FlxG.mouse.viewY > (playbarHeadLayout?.y ?? 0.0)) { // Scroll down. - var diff:Float = FlxG.mouse.screenY - (playbarHeadLayout?.y ?? 0.0); + var diff:Float = FlxG.mouse.viewY - (playbarHeadLayout?.y ?? 0.0); scrollPositionInPixels += diff * 0.5; // Too fast! moveSongToScrollPosition(); } @@ -4811,11 +4811,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Show the context menu connected to the note. if (useSingleNoteContextMenu) { - this.openNoteContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY, highlightedNote.noteData); + this.openNoteContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY, highlightedNote.noteData); } else { - this.openSelectionContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY); + this.openSelectionContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY); } } else @@ -4835,11 +4835,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState || (isHighlightedEventSelected && currentEventSelection.length == 1); if (useSingleEventContextMenu) { - this.openEventContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY, highlightedEvent.eventData); + this.openEventContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY, highlightedEvent.eventData); } else { - this.openSelectionContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY); + this.openSelectionContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY); } } else @@ -4860,11 +4860,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState // Show the context menu connected to the note. if (useSingleNoteContextMenu) { - this.openHoldNoteContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY, highlightedHoldNote.noteData); + this.openHoldNoteContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY, highlightedHoldNote.noteData); } else { - this.openSelectionContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY); + this.openSelectionContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY); } } else @@ -5139,10 +5139,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState } var songPos:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset; + var songPosMilliseconds:String = Std.string(Math.floor(Math.abs(songPos) % 1000)).lpad('0', 2).substr(0, 2); var songPosSeconds:String = Std.string(Math.floor((Math.abs(songPos) / 1000) % 60)).lpad('0', 2); var songPosMinutes:String = Std.string(Math.floor((Math.abs(songPos) / 1000) / 60)).lpad('0', 2); if (songPos < 0) songPosMinutes = '-' + songPosMinutes; - var songPosString:String = '${songPosMinutes}:${songPosSeconds}'; + var songPosString:String = '${songPosMinutes}:${songPosSeconds}:${songPosMilliseconds}'; if (playbarSongPos.value != songPosString) playbarSongPos.value = songPosString; @@ -5614,7 +5615,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState } else { - trace('Ignoring keybinds for View menu items because we are in live input mode (${currentLiveInputStyle}).'); + // trace('Ignoring keybinds for View menu items because we are in live input mode (${currentLiveInputStyle}).'); } } diff --git a/source/funkin/ui/debug/charting/components/ChartEditorEventSprite.hx b/source/funkin/ui/debug/charting/components/ChartEditorEventSprite.hx index c996079bc..4c4a8d200 100644 --- a/source/funkin/ui/debug/charting/components/ChartEditorEventSprite.hx +++ b/source/funkin/ui/debug/charting/components/ChartEditorEventSprite.hx @@ -3,7 +3,6 @@ package funkin.ui.debug.charting.components; import funkin.data.event.SongEventRegistry; import flixel.graphics.frames.FlxAtlasFrames; import openfl.display.BitmapData; -import openfl.utils.Assets; import flixel.FlxObject; import flixel.FlxBasic; import flixel.FlxSprite; diff --git a/source/funkin/ui/debug/charting/dialogs/ChartEditorCharacterIconSelectorMenu.hx b/source/funkin/ui/debug/charting/dialogs/ChartEditorCharacterIconSelectorMenu.hx index 1edbb6c00..90d998a02 100644 --- a/source/funkin/ui/debug/charting/dialogs/ChartEditorCharacterIconSelectorMenu.hx +++ b/source/funkin/ui/debug/charting/dialogs/ChartEditorCharacterIconSelectorMenu.hx @@ -95,7 +95,7 @@ class ChartEditorCharacterIconSelectorMenu extends ChartEditorBaseMenu } var LIMIT = 6; - charButton.icon = CharacterDataParser.getCharPixelIconAsset(charId); + charButton.icon = haxe.ui.util.Variant.fromImageData(CharacterDataParser.getCharPixelIconAsset(charId)); charButton.text = charData.name.length > LIMIT ? '${charData.name.substr(0, LIMIT)}.' : '${charData.name}'; charButton.onClick = _ -> { diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx index 26e246371..329873d68 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorAudioHandler.hx @@ -13,7 +13,6 @@ import funkin.audio.waveform.WaveformSprite; import flixel.util.FlxColor; import haxe.io.Bytes; import haxe.io.Path; -import openfl.utils.Assets; /** * Functions for loading audio for the chart editor. diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx index c97e8142d..f68776cab 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx @@ -221,7 +221,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox var charDataOpponent:Null = CharacterDataParser.fetchCharacterData(chartEditorState.currentSongMetadata.playData.characters.opponent); if (charDataOpponent != null) { - buttonCharacterOpponent.icon = CharacterDataParser.getCharPixelIconAsset(chartEditorState.currentSongMetadata.playData.characters.opponent); + buttonCharacterOpponent.icon = haxe.ui.util.Variant.fromImageData(CharacterDataParser.getCharPixelIconAsset(chartEditorState.currentSongMetadata.playData.characters.opponent)); buttonCharacterOpponent.text = charDataOpponent.name.length > LIMIT ? '${charDataOpponent.name.substr(0, LIMIT)}.' : '${charDataOpponent.name}'; } else @@ -233,7 +233,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox var charDataGirlfriend:Null = CharacterDataParser.fetchCharacterData(chartEditorState.currentSongMetadata.playData.characters.girlfriend); if (charDataGirlfriend != null) { - buttonCharacterGirlfriend.icon = CharacterDataParser.getCharPixelIconAsset(chartEditorState.currentSongMetadata.playData.characters.girlfriend); + buttonCharacterGirlfriend.icon = haxe.ui.util.Variant.fromImageData(CharacterDataParser.getCharPixelIconAsset(chartEditorState.currentSongMetadata.playData.characters.girlfriend)); buttonCharacterGirlfriend.text = charDataGirlfriend.name.length > LIMIT ? '${charDataGirlfriend.name.substr(0, LIMIT)}.' : '${charDataGirlfriend.name}'; } else @@ -245,7 +245,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox var charDataPlayer:Null = CharacterDataParser.fetchCharacterData(chartEditorState.currentSongMetadata.playData.characters.player); if (charDataPlayer != null) { - buttonCharacterPlayer.icon = CharacterDataParser.getCharPixelIconAsset(chartEditorState.currentSongMetadata.playData.characters.player); + buttonCharacterPlayer.icon = haxe.ui.util.Variant.fromImageData(CharacterDataParser.getCharPixelIconAsset(chartEditorState.currentSongMetadata.playData.characters.player)); buttonCharacterPlayer.text = charDataPlayer.name.length > LIMIT ? '${charDataPlayer.name.substr(0, LIMIT)}.' : '${charDataPlayer.name}'; } else diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index 4107369d2..81a9fe858 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -11,7 +11,6 @@ import funkin.data.freeplay.album.AlbumRegistry; import funkin.util.assets.FlxAnimationUtil; import funkin.graphics.FunkinSprite; import funkin.util.SortUtil; -import openfl.utils.Assets; /** * The graphic for the album roll in the FreeplayState. diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index af0a9b841..aef40ef91 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -51,7 +51,6 @@ import funkin.ui.transition.LoadingState; import funkin.ui.transition.StickerSubState; import funkin.util.MathUtil; import funkin.util.SortUtil; -import lime.utils.Assets; import openfl.display.BlendMode; import funkin.data.freeplay.style.FreeplayStyleRegistry; import funkin.data.song.SongData.SongMusicData; @@ -586,13 +585,13 @@ class FreeplayState extends MusicBeatSubState } }; - exitMovers.set([fp, txtCompletion, fnfHighscoreSpr, txtCompletion, clearBoxSprite], + exitMovers.set([fp, txtCompletion, fnfHighscoreSpr, clearBoxSprite], { x: FlxG.width, speed: 0.3 }); - exitMoversCharSel.set([fp, txtCompletion, fnfHighscoreSpr, txtCompletion, clearBoxSprite], + exitMoversCharSel.set([fp, txtCompletion, fnfHighscoreSpr, clearBoxSprite], { y: -270, speed: 0.8, @@ -1376,7 +1375,7 @@ class FreeplayState extends MusicBeatSubState #if FEATURE_DEBUG_FUNCTIONS if (FlxG.keys.justPressed.P) { - FlxG.switchState(FreeplayState.build( + FlxG.switchState(() -> FreeplayState.build( { { character: currentCharacterId == "pico" ? Constants.DEFAULT_CHARACTER : "pico", @@ -1777,12 +1776,13 @@ class FreeplayState extends MusicBeatSubState FlxG.log.warn('WARN: could not find song with id (${daSong.songId})'); return; } - var targetVariation:String = targetSong.getFirstValidVariation(currentDifficulty) ?? ''; + var targetVariation:String = targetSong.getFirstValidVariation(currentDifficulty, currentCharacter) ?? ''; // TODO: This line of code makes me sad, but you can't really fix it without a breaking migration. var suffixedDifficulty = (targetVariation != Constants.DEFAULT_VARIATION && targetVariation != 'erect') ? '$currentDifficulty-${targetVariation}' : currentDifficulty; var songScore:Null = Save.instance.getSongScore(daSong.songId, suffixedDifficulty); + trace(songScore); intendedScore = songScore?.score ?? 0; intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes); rememberedDifficulty = suffixedDifficulty; @@ -1859,7 +1859,7 @@ class FreeplayState extends MusicBeatSubState albumRoll.setDifficultyStars(daSong?.difficultyRating); } - // Clears the cache of songs, frees up memory, they' ll have to be loaded in later tho function clearDaCache(actualSongTho:String) + // Clears the cache of songs to free up memory, they'll have to be loaded in later tho function clearDaCache(actualSongTho:String):Void { for (song in songs) diff --git a/source/funkin/ui/freeplay/backcards/BackingCard.hx b/source/funkin/ui/freeplay/backcards/BackingCard.hx index bb662cc8d..713b6edcf 100644 --- a/source/funkin/ui/freeplay/backcards/BackingCard.hx +++ b/source/funkin/ui/freeplay/backcards/BackingCard.hx @@ -18,7 +18,6 @@ import funkin.graphics.adobeanimate.FlxAtlasSprite; import funkin.graphics.FunkinSprite; import funkin.ui.freeplay.charselect.PlayableCharacter; import funkin.ui.MusicBeatSubState; -import lime.utils.Assets; import openfl.display.BlendMode; import flixel.group.FlxSpriteGroup; diff --git a/source/funkin/ui/freeplay/backcards/BoyfriendCard.hx b/source/funkin/ui/freeplay/backcards/BoyfriendCard.hx index 597fd1a34..a049c4f42 100644 --- a/source/funkin/ui/freeplay/backcards/BoyfriendCard.hx +++ b/source/funkin/ui/freeplay/backcards/BoyfriendCard.hx @@ -18,7 +18,6 @@ import funkin.graphics.adobeanimate.FlxAtlasSprite; import funkin.graphics.FunkinSprite; import funkin.ui.freeplay.charselect.PlayableCharacter; import funkin.ui.MusicBeatSubState; -import lime.utils.Assets; import openfl.display.BlendMode; import flixel.group.FlxSpriteGroup; @@ -177,20 +176,21 @@ class BoyfriendCard extends BackingCard } var beatFreq:Int = 1; - var beatFreqList:Array = [1,2,4,8]; + var beatFreqList:Array = [1, 2, 4, 8]; - public override function beatHit():Void { + public override function beatHit():Void + { // increases the amount of beats that need to go by to pulse the glow because itd flash like craazy at high bpms..... - beatFreq = beatFreqList[Math.floor(Conductor.instance.bpm/140)]; + beatFreq = beatFreqList[Math.floor(Conductor.instance.bpm / 140)]; - if(Conductor.instance.currentBeat % beatFreq != 0) return; + if (Conductor.instance.currentBeat % beatFreq != 0) return; FlxTween.cancelTweensOf(glow); FlxTween.cancelTweensOf(glowDark); glow.alpha = 0.8; - FlxTween.tween(glow, {alpha: 0}, 16/24, {ease: FlxEase.quartOut}); + FlxTween.tween(glow, {alpha: 0}, 16 / 24, {ease: FlxEase.quartOut}); glowDark.alpha = 0; - FlxTween.tween(glowDark, {alpha: 0.6}, 18/24, {ease: FlxEase.quartOut}); + FlxTween.tween(glowDark, {alpha: 0.6}, 18 / 24, {ease: FlxEase.quartOut}); } public override function introDone():Void diff --git a/source/funkin/ui/freeplay/backcards/NewCharacterCard.hx b/source/funkin/ui/freeplay/backcards/NewCharacterCard.hx index a44ff88a6..1e3d81299 100644 --- a/source/funkin/ui/freeplay/backcards/NewCharacterCard.hx +++ b/source/funkin/ui/freeplay/backcards/NewCharacterCard.hx @@ -20,7 +20,6 @@ import funkin.graphics.adobeanimate.FlxAtlasSprite; import funkin.graphics.FunkinSprite; import funkin.ui.freeplay.charselect.PlayableCharacter; import funkin.ui.MusicBeatSubState; -import lime.utils.Assets; import openfl.display.BlendMode; import flixel.group.FlxSpriteGroup; import funkin.graphics.shaders.AdjustColorShader; diff --git a/source/funkin/ui/freeplay/backcards/PicoCard.hx b/source/funkin/ui/freeplay/backcards/PicoCard.hx index f5db1ccc3..8cfe7756e 100644 --- a/source/funkin/ui/freeplay/backcards/PicoCard.hx +++ b/source/funkin/ui/freeplay/backcards/PicoCard.hx @@ -20,7 +20,6 @@ import funkin.graphics.adobeanimate.FlxAtlasSprite; import funkin.graphics.FunkinSprite; import funkin.ui.freeplay.charselect.PlayableCharacter; import funkin.ui.MusicBeatSubState; -import lime.utils.Assets; import openfl.display.BlendMode; import flixel.group.FlxSpriteGroup; import funkin.graphics.shaders.AdjustColorShader; @@ -233,20 +232,21 @@ class PicoCard extends BackingCard } var beatFreq:Int = 1; - var beatFreqList:Array = [1,2,4,8]; + var beatFreqList:Array = [1, 2, 4, 8]; - public override function beatHit():Void { + public override function beatHit():Void + { // increases the amount of beats that need to go by to pulse the glow because itd flash like craazy at high bpms..... - beatFreq = beatFreqList[Math.floor(Conductor.instance.bpm/140)]; + beatFreq = beatFreqList[Math.floor(Conductor.instance.bpm / 140)]; - if(Conductor.instance.currentBeat % beatFreq != 0) return; + if (Conductor.instance.currentBeat % beatFreq != 0) return; FlxTween.cancelTweensOf(glow); FlxTween.cancelTweensOf(glowDark); glow.alpha = 1; - FlxTween.tween(glow, {alpha: 0}, 16/24, {ease: FlxEase.quartOut}); + FlxTween.tween(glow, {alpha: 0}, 16 / 24, {ease: FlxEase.quartOut}); glowDark.alpha = 0; - FlxTween.tween(glowDark, {alpha: 1}, 18/24, {ease: FlxEase.quartOut}); + FlxTween.tween(glowDark, {alpha: 1}, 18 / 24, {ease: FlxEase.quartOut}); } public override function introDone():Void diff --git a/source/funkin/ui/freeplay/charselect/PlayableCharacter.hx b/source/funkin/ui/freeplay/charselect/PlayableCharacter.hx index 93d643ae4..408a91672 100644 --- a/source/funkin/ui/freeplay/charselect/PlayableCharacter.hx +++ b/source/funkin/ui/freeplay/charselect/PlayableCharacter.hx @@ -113,7 +113,9 @@ class PlayableCharacter implements IRegistryEntry switch (rank) { - case PERFECT | PERFECT_GOLD: + case PERFECT_GOLD: + return _data.results.perfectGold; + case PERFECT: return _data.results.perfect; case EXCELLENT: return _data.results.excellent; diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 13d68da6d..3bb5777f9 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -123,7 +123,7 @@ class MainMenuState extends MusicBeatState })); }); - #if CAN_OPEN_LINKS + #if FEATURE_OPEN_URL // In order to prevent popup blockers from triggering, // we need to open the link as an immediate result of a keypress event, // so we can't wait for the flicker animation to complete. @@ -234,7 +234,7 @@ class MainMenuState extends MusicBeatState camFollow.setPosition(selected.getGraphicMidpoint().x, selected.getGraphicMidpoint().y); } - #if CAN_OPEN_LINKS + #if FEATURE_OPEN_URL function selectDonate() { WindowUtil.openURL(Constants.URL_ITCH); @@ -356,7 +356,7 @@ class MainMenuState extends MusicBeatState #if FEATURE_DEBUG_FUNCTIONS // Ctrl+Alt+Shift+P = Character Unlock screen // Ctrl+Alt+Shift+W = Meet requirements for Pico Unlock - // Ctrl+Alt+Shift+L = Revoke requirements for Pico Unlock + // Ctrl+Alt+Shift+M = Revoke requirements for Pico Unlock // Ctrl+Alt+Shift+R = Score/Rank conflict test // Ctrl+Alt+Shift+N = Mark all characters as not seen // Ctrl+Alt+Shift+E = Dump save data @@ -369,7 +369,7 @@ class MainMenuState extends MusicBeatState if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.W) { FunkinSound.playOnce(Paths.sound('confirmMenu')); - // Give the user a score of 1 point on Weekend 1 story mode. + // Give the user a score of 1 point on Weekend 1 story mode (Easy difficulty). // This makes the level count as cleared and displays the songs in Freeplay. funkin.save.Save.instance.setLevelScore('weekend1', 'easy', { @@ -389,27 +389,30 @@ class MainMenuState extends MusicBeatState }); } - if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.L) + if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.M) { FunkinSound.playOnce(Paths.sound('confirmMenu')); - // Give the user a score of 0 points on Weekend 1 story mode. + // Give the user a score of 0 points on Weekend 1 story mode (all difficulties). // This makes the level count as uncleared and no longer displays the songs in Freeplay. - funkin.save.Save.instance.setLevelScore('weekend1', 'easy', - { - score: 1, - tallies: - { - sick: 0, - good: 0, - bad: 0, - shit: 0, - missed: 0, - combo: 0, - maxCombo: 0, - totalNotesHit: 0, - totalNotes: 0, - } - }); + for (diff in ['easy', 'normal', 'hard']) + { + funkin.save.Save.instance.setLevelScore('weekend1', diff, + { + score: 0, + tallies: + { + sick: 0, + good: 0, + bad: 0, + shit: 0, + missed: 0, + combo: 0, + maxCombo: 0, + totalNotesHit: 0, + totalNotes: 0, + } + }); + } } if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.R) diff --git a/source/funkin/ui/options/FunkinSoundTray.hx b/source/funkin/ui/options/FunkinSoundTray.hx index 170ad8497..8ae53524a 100644 --- a/source/funkin/ui/options/FunkinSoundTray.hx +++ b/source/funkin/ui/options/FunkinSoundTray.hx @@ -6,7 +6,6 @@ import flixel.system.FlxAssets; import flixel.tweens.FlxEase; import openfl.display.Bitmap; import openfl.display.BitmapData; -import openfl.utils.Assets; import funkin.util.MathUtil; /** diff --git a/source/funkin/ui/options/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx index eb7b88792..fb4980762 100644 --- a/source/funkin/ui/options/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -77,6 +77,10 @@ class PreferencesMenu extends Page createPrefItemCheckbox('Unlocked Framerate', 'Enable to unlock the framerate', function(value:Bool):Void { Preferences.unlockedFramerate = value; }, Preferences.unlockedFramerate); + #else + createPrefItemNumber('FPS', 'The maximum framerate that the game targets', function(value:Float) { + Preferences.framerate = Std.int(value); + }, null, Preferences.framerate, 30, 300, 5, 0); #end } @@ -87,7 +91,6 @@ class PreferencesMenu extends Page // Indent the selected item. items.forEach(function(daItem:TextMenuItem) { var thyOffset:Int = 0; - // Initializing thy text width (if thou text present) var thyTextWidth:Int = 0; if (Std.isOfType(daItem, EnumPreferenceItem)) thyTextWidth = cast(daItem, EnumPreferenceItem).lefthandText.getWidth(); diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 18614d414..c0ed2712a 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -23,7 +23,6 @@ import funkin.ui.MusicBeatState; import funkin.ui.transition.LoadingState; import funkin.ui.transition.StickerSubState; import funkin.util.MathUtil; -import openfl.utils.Assets; class StoryMenuState extends MusicBeatState { diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index f5c641d0c..10e7dfaae 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -273,11 +273,6 @@ class TitleState extends MusicBeatState } #end - if (Save.instance.charactersSeen.contains("pico")) - { - Save.instance.charactersSeen.remove("pico"); - Save.instance.oldChar = false; - } Conductor.instance.update(); /* if (FlxG.onMobile) diff --git a/source/funkin/ui/transition/LoadingState.hx b/source/funkin/ui/transition/LoadingState.hx index 0514bba3d..f3620c893 100644 --- a/source/funkin/ui/transition/LoadingState.hx +++ b/source/funkin/ui/transition/LoadingState.hx @@ -3,24 +3,23 @@ package funkin.ui.transition; import flixel.FlxSprite; import flixel.math.FlxMath; import flixel.tweens.FlxEase; -import funkin.graphics.FunkinSprite; import flixel.tweens.FlxTween; import flixel.util.FlxTimer; +import flixel.util.typeLimit.NextState; +import funkin.graphics.FunkinSprite; import funkin.graphics.shaders.ScreenWipeShader; import funkin.play.PlayState; import funkin.play.PlayStatePlaylist; import funkin.play.song.Song.SongDifficulty; import funkin.ui.MusicBeatState; import haxe.io.Path; -import funkin.graphics.FunkinSprite; import lime.app.Future; import lime.app.Promise; import lime.utils.AssetLibrary; import lime.utils.AssetManifest; import lime.utils.Assets as LimeAssets; import openfl.filters.ShaderFilter; -import openfl.utils.Assets; -import flixel.util.typeLimit.NextState; +import openfl.utils.Assets as OpenFLAssets; class LoadingState extends MusicBeatSubState { @@ -98,7 +97,7 @@ class LoadingState extends MusicBeatSubState function checkLoadSong(path:String):Void { - if (!Assets.cache.hasSound(path)) + if (!OpenFLAssets.cache.hasSound(path)) { var library = Assets.getLibrary('songs'); var symbolPath = path.split(':').pop(); @@ -277,7 +276,7 @@ class LoadingState extends MusicBeatSubState #if NO_PRELOAD_ALL static function isSoundLoaded(path:String):Bool { - return Assets.cache.hasSound(path); + return OpenFLAssets.cache.hasSound(path); } static function isLibraryLoaded(library:String):Bool diff --git a/source/funkin/ui/transition/StickerSubState.hx b/source/funkin/ui/transition/StickerSubState.hx index e5abef872..e8d6877d8 100644 --- a/source/funkin/ui/transition/StickerSubState.hx +++ b/source/funkin/ui/transition/StickerSubState.hx @@ -2,7 +2,6 @@ package funkin.ui.transition; import flixel.FlxSprite; import haxe.Json; -import lime.utils.Assets; import funkin.graphics.FunkinSprite; // import flxtyped group import funkin.ui.MusicBeatSubState; @@ -56,7 +55,7 @@ class StickerSubState extends MusicBeatSubState // make sure that ONLY plays mp3/ogg files // if there's no mp3/ogg file, then it regenerates/reloads the random folder - var assetsInList = openfl.utils.Assets.list(); + var assetsInList = Assets.list(); var soundFilterFunc = function(a:String) { return a.startsWith('assets/shared/sounds/stickersounds/'); @@ -84,7 +83,7 @@ class StickerSubState extends MusicBeatSubState var filterFunc = function(a:String) { return a.startsWith('assets/shared/sounds/stickersounds/' + soundSelection + '/'); }; - var assetsInList3 = openfl.utils.Assets.list(); + var assetsInList3 = Assets.list(); sounds = assetsInList3.filter(filterFunc); for (i in 0...sounds.length) { diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index 57fc484b8..cf58d191a 100644 --- a/source/funkin/util/Constants.hx +++ b/source/funkin/util/Constants.hx @@ -481,10 +481,6 @@ class Constants public static final JUDGEMENT_BAD_COMBO_BREAK:Bool = true; public static final JUDGEMENT_SHIT_COMBO_BREAK:Bool = true; - // % Sick - public static final RANK_PERFECT_PLAT_THRESHOLD:Float = 1.0; // % Sick - public static final RANK_PERFECT_GOLD_THRESHOLD:Float = 0.85; // % Sick - // % Hit public static final RANK_PERFECT_THRESHOLD:Float = 1.00; public static final RANK_EXCELLENT_THRESHOLD:Float = 0.90; diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index 0fe63fe32..aabaa495b 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -22,7 +22,7 @@ class WindowUtil */ public static function openURL(targetUrl:String):Void { - #if CAN_OPEN_LINKS + #if FEATURE_OPEN_URL #if linux Sys.command('/usr/bin/xdg-open $targetUrl &'); #else @@ -40,7 +40,7 @@ class WindowUtil */ public static function openFolder(targetPath:String):Void { - #if CAN_OPEN_LINKS + #if FEATURE_OPEN_URL #if windows Sys.command('explorer', [targetPath.replace('/', '\\')]); #elseif mac @@ -59,7 +59,7 @@ class WindowUtil */ public static function openSelectFile(targetPath:String):Void { - #if CAN_OPEN_LINKS + #if FEATURE_OPEN_URL #if windows Sys.command('explorer', ['/select,' + targetPath.replace('/', '\\')]); #elseif mac diff --git a/source/funkin/util/macro/GitCommit.hx b/source/funkin/util/macro/GitCommit.hx index 161856caa..9e3305c41 100644 --- a/source/funkin/util/macro/GitCommit.hx +++ b/source/funkin/util/macro/GitCommit.hx @@ -23,6 +23,8 @@ class GitCommit var commitHash:String = process.stdout.readLine(); var commitHashSplice:String = commitHash.substr(0, 7); + process.close(); + trace('Git Commit ID: ${commitHashSplice}'); // Generates a string expression @@ -52,6 +54,7 @@ class GitCommit } var branchName:String = branchProcess.stdout.readLine(); + branchProcess.close(); trace('Git Branch Name: ${branchName}'); // Generates a string expression @@ -84,6 +87,7 @@ class GitCommit try { output = branchProcess.stdout.readLine(); + branchProcess.close(); } catch (e) {