From fb4a3071953a8cfd1017f150efc817978b7ace59 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Thu, 19 Oct 2023 01:24:20 -0400 Subject: [PATCH 01/21] Update hmm and HaxeUI --- hmm.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/hmm.json b/hmm.json index 070d96cd0..f289e96d6 100644 --- a/hmm.json +++ b/hmm.json @@ -49,22 +49,20 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "e92d5cfac847943fac84696b103670d55c2c774f", + "ref": "a0b37242910a83e792aae1b5b785f2482ed848e0", "url": "https://github.com/haxeui/haxeui-core" }, { "name": "haxeui-flixel", "type": "git", "dir": null, - "ref": "be0b18553189a55fd42821026618a18615b070e3", + "ref": "bcbcac94dc852b253fff807e05f16a4ef01fb067", "url": "https://github.com/haxeui/haxeui-flixel" }, { "name": "hmm", - "type": "git", - "dir": null, - "ref": "d514d7786cabf18b90e60fcee38399fd44c2ddfb", - "url": "https://github.com/andywhite37/hmm" + "type": "haxelib", + "version": "3.1.0" }, { "name": "hscript", From 8042f6c5a84fb3bb7c4bbe9c2f5c8411d7775dd8 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Thu, 19 Oct 2023 15:05:54 -0400 Subject: [PATCH 02/21] Update HaxeUI again --- hmm.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hmm.json b/hmm.json index f289e96d6..1d9e51d69 100644 --- a/hmm.json +++ b/hmm.json @@ -49,14 +49,14 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "a0b37242910a83e792aae1b5b785f2482ed848e0", + "ref": "db6f81191abe386d891aca5a65c27ba6f8e10598", "url": "https://github.com/haxeui/haxeui-core" }, { "name": "haxeui-flixel", "type": "git", "dir": null, - "ref": "bcbcac94dc852b253fff807e05f16a4ef01fb067", + "ref": "e10f51fe33b8d8d2dd3f21a0fd1d7c4d88d5d5c0", "url": "https://github.com/haxeui/haxeui-flixel" }, { From ffd0a9839346cb65ab95643ba2f5fa790988c20c Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Sat, 21 Oct 2023 01:04:50 -0400 Subject: [PATCH 03/21] FNFC file rework (includes command line quicklaunch) --- Project.xml | 5 +- assets | 2 +- source/Main.hx | 1 + source/funkin/InitState.hx | 20 +- source/{ => funkin}/Preloader.hx | 5 +- source/funkin/data/DataParse.hx | 16 ++ source/funkin/data/DataWrite.hx | 24 +- source/funkin/data/animation/AnimationData.hx | 3 + .../data/notestyle/NoteStyleRegistry.hx | 4 +- source/funkin/data/song/SongData.hx | 32 ++- source/funkin/data/song/SongRegistry.hx | 52 +++- .../data/song/importer/ChartManifestData.hx | 84 +++++++ .../data/song/migrator/SongDataMigrator.hx | 56 ++++- .../data/song/migrator/SongData_v2_0_0.hx | 9 +- .../data/song/migrator/SongData_v2_1_0.hx | 108 ++++++++ source/funkin/play/PlayState.hx | 6 +- source/funkin/play/song/Song.hx | 25 +- source/funkin/play/stage/Stage.hx | 23 +- source/funkin/play/stage/StageData.hx | 130 +++++++--- .../funkin/save/migrator/SaveDataMigrator.hx | 5 +- .../debug/charting/ChartEditorAudioHandler.hx | 2 +- .../ui/debug/charting/ChartEditorCommand.hx | 16 +- .../charting/ChartEditorDialogHandler.hx | 158 ++++++++++-- .../ChartEditorImportExportHandler.hx | 232 +++++++++++++++--- .../ui/debug/charting/ChartEditorState.hx | 93 +++++-- source/funkin/ui/haxeui/HaxeUIState.hx | 17 ++ source/funkin/util/CLIUtil.hx | 134 ++++++++++ source/funkin/util/FileUtil.hx | 65 ++++- source/funkin/util/SerializerUtil.hx | 2 + source/funkin/util/VersionUtil.hx | 18 ++ .../data/notestyle/NoteStyleRegistryTest.hx | 2 +- 31 files changed, 1162 insertions(+), 187 deletions(-) rename source/{ => funkin}/Preloader.hx (93%) create mode 100644 source/funkin/data/song/importer/ChartManifestData.hx create mode 100644 source/funkin/data/song/migrator/SongData_v2_1_0.hx create mode 100644 source/funkin/util/CLIUtil.hx diff --git a/Project.xml b/Project.xml index 69400d8b1..9fad26fd7 100644 --- a/Project.xml +++ b/Project.xml @@ -4,10 +4,7 @@ <app title="Friday Night Funkin'" file="Funkin" packageName="com.funkin.fnf" package="com.funkin.fnf" main="Main" version="0.3.0" company="ninjamuffin99" /> <!--Switch Export with Unique ApplicationID and Icon--> <set name="APP_ID" value="0x0100f6c013bbc000" /> - <!--The flixel preloader is not accurate in Chrome. You can use it regularly if you embed the swf into a html file - or you can set the actual size of your file manually at "FlxPreloaderBase-onUpdate-bytesTotal"--> - <!-- <app preloader="Preloader" resizable="true" /> --> - <app preloader="Preloader" /> + <app preloader="funkin.Preloader" /> <!--Minimum without FLX_NO_GAMEPAD: 11.8, without FLX_NO_NATIVE_CURSOR: 11.2--> <set name="SWF_VERSION" value="11.8" /> <!-- ____________________________ Window Settings ___________________________ --> diff --git a/assets b/assets index ef79a6cf1..118b62295 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ef79a6cf1ae3dcbd86a5b798f8117a6c692c0156 +Subproject commit 118b622953171aaf127cb160538e21bc468620e2 diff --git a/source/Main.hx b/source/Main.hx index dffe666b7..726c1fdbf 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -11,6 +11,7 @@ import openfl.display.Sprite; import openfl.events.Event; import openfl.Lib; import openfl.media.Video; +import funkin.util.CLIUtil; import openfl.net.NetStream; class Main extends Sprite diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index ecfa32eb3..fbde22e1b 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -1,5 +1,6 @@ package funkin; +import funkin.ui.debug.charting.ChartEditorState; import flixel.FlxState; import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; @@ -26,6 +27,8 @@ import funkin.play.stage.StageData.StageDataParser; import funkin.play.character.CharacterData.CharacterDataParser; import funkin.modding.module.ModuleHandler; import funkin.ui.title.TitleState; +import funkin.util.CLIUtil; +import funkin.util.CLIUtil.CLIParams; #if discord_rpc import Discord.DiscordClient; #end @@ -247,8 +250,21 @@ class InitState extends FlxState */ function startGameNormally():Void { - FlxG.sound.cache(Paths.music('freakyMenu/freakyMenu')); - FlxG.switchState(new TitleState()); + var params:CLIParams = CLIUtil.processArgs(); + trace('Command line args: ${params}'); + + if (params.chart.shouldLoadChart) + { + FlxG.switchState(new ChartEditorState( + { + fnfcTargetPath: params.chart.chartPath, + })); + } + else + { + FlxG.sound.cache(Paths.music('freakyMenu/freakyMenu')); + FlxG.switchState(new TitleState()); + } } /** diff --git a/source/Preloader.hx b/source/funkin/Preloader.hx similarity index 93% rename from source/Preloader.hx rename to source/funkin/Preloader.hx index 3603d1a16..24015be05 100644 --- a/source/Preloader.hx +++ b/source/funkin/Preloader.hx @@ -1,4 +1,4 @@ -package; +package funkin; import flash.Lib; import flash.display.Bitmap; @@ -7,6 +7,7 @@ import flash.display.BlendMode; import flash.display.Sprite; import flixel.system.FlxBasePreloader; import openfl.display.Sprite; +import funkin.util.CLIUtil; @:bitmap("art/preloaderArt.png") class LogoImage extends BitmapData {} @@ -15,6 +16,8 @@ class Preloader extends FlxBasePreloader public function new(MinDisplayTime:Float = 0, ?AllowedURLs:Array<String>) { super(MinDisplayTime, AllowedURLs); + + CLIUtil.resetWorkingDir(); // Bug fix for drag-and-drop. } var logo:Sprite; diff --git a/source/funkin/data/DataParse.hx b/source/funkin/data/DataParse.hx index 64a53d2a4..cbd168a61 100644 --- a/source/funkin/data/DataParse.hx +++ b/source/funkin/data/DataParse.hx @@ -104,6 +104,22 @@ class DataParse } } + /** + * Parser which outputs a `Either<Float, Array<Float>>`. + */ + public static function eitherFloatOrFloats(json:Json, name:String):Null<Either<Float, Array<Float>>> + { + switch (json.value) + { + case JNumber(f): + return Either.Left(Std.parseFloat(f)); + case JArray(fields): + return Either.Right(fields.map((field) -> cast Tools.getValue(field))); + default: + throw 'Expected property $name to be one or multiple floats, but it was ${json.value}.'; + } + } + /** * Parser which outputs a `Either<Float, LegacyScrollSpeeds>`. * Used by the FNF legacy JSON importer. diff --git a/source/funkin/data/DataWrite.hx b/source/funkin/data/DataWrite.hx index 2f3a7632f..e277cb01c 100644 --- a/source/funkin/data/DataWrite.hx +++ b/source/funkin/data/DataWrite.hx @@ -3,11 +3,14 @@ package funkin.data; import funkin.util.SerializerUtil; import thx.semver.Version; import thx.semver.VersionRule; +import haxe.ds.Either; /** * `json2object` has an annotation `@:jcustomwrite` which allows for custom serialization of values to be written to JSON. * * Functions must be of the signature `(T) -> String`, where `T` is the type of the property. + * + * NOTE: Result must include quotation marks if the value is a string! json2object will not add them for you! */ class DataWrite { @@ -23,11 +26,12 @@ class DataWrite } /** + * * `@:jcustomwrite(funkin.data.DataWrite.semverVersion)` */ public static function semverVersion(value:Version):String { - return value.toString(); + return '"${value.toString()}"'; } /** @@ -35,6 +39,22 @@ class DataWrite */ public static function semverVersionRule(value:VersionRule):String { - return value.toString(); + return '"${value.toString()}"'; + } + + /** + * `@:jcustomwrite(funkin.data.DataWrite.eitherFloatOrFloats)` + */ + public static function eitherFloatOrFloats(value:Null<Either<Float, Array<Float>>>):String + { + switch (value) + { + case null: + return '${1.0}'; + case Left(inner): + return '$inner'; + case Right(inner): + return dynamicValue(inner); + } } } diff --git a/source/funkin/data/animation/AnimationData.hx b/source/funkin/data/animation/AnimationData.hx index 9765f784c..a0214096c 100644 --- a/source/funkin/data/animation/AnimationData.hx +++ b/source/funkin/data/animation/AnimationData.hx @@ -59,7 +59,10 @@ typedef UnnamedAnimationData = * The prefix for the frames of the animation as defined by the XML file. * This will may or may not differ from the `name` of the animation, * depending on how your animator organized their FLA or whatever. + * + * NOTE: For Sparrow animations, this is not optional, but for Packer animations it is. */ + @:optional var prefix:String; /** diff --git a/source/funkin/data/notestyle/NoteStyleRegistry.hx b/source/funkin/data/notestyle/NoteStyleRegistry.hx index da45da5f2..4255a644b 100644 --- a/source/funkin/data/notestyle/NoteStyleRegistry.hx +++ b/source/funkin/data/notestyle/NoteStyleRegistry.hx @@ -15,8 +15,6 @@ class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData> public static final NOTE_STYLE_DATA_VERSION_RULE:thx.semver.VersionRule = "1.0.x"; - public static final DEFAULT_NOTE_STYLE_ID:String = "funkin"; - public static final instance:NoteStyleRegistry = new NoteStyleRegistry(); public function new() @@ -26,7 +24,7 @@ class NoteStyleRegistry extends BaseRegistry<NoteStyle, NoteStyleData> public function fetchDefault():NoteStyle { - return fetchEntry(DEFAULT_NOTE_STYLE_ID); + return fetchEntry(Constants.DEFAULT_NOTE_STYLE); } /** diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 88993e519..c0bd26332 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -1,9 +1,13 @@ package funkin.data.song; -import flixel.util.typeLimit.OneOfTwo; import funkin.data.song.SongRegistry; import thx.semver.Version; +/** + * Data containing information about a song. + * It should contain all the data needed to display a song in the Freeplay menu, or to load the assets required to play its chart. + * Data which is only necessary in-game should be stored in the SongChartData. + */ @:nullSafety class SongMetadata { @@ -35,13 +39,11 @@ class SongMetadata */ public var playData:SongPlayData; - // @:default(funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY) + @:default(funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY) public var generatedBy:String; - // @:default(funkin.data.song.SongData.SongTimeFormat.MILLISECONDS) public var timeFormat:SongTimeFormat; - // @:default(funkin.data.song.SongData.SongTimeChange.DEFAULT_SONGTIMECHANGES) public var timeChanges:Array<SongTimeChange>; /** @@ -64,7 +66,7 @@ class SongMetadata this.playData.difficulties = []; this.playData.characters = new SongCharacterData('bf', 'gf', 'dad'); this.playData.stage = 'mainStage'; - this.playData.noteSkin = 'funkin'; + this.playData.noteStyle = Constants.DEFAULT_NOTE_STYLE; this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY; // Variation ID. this.variation = (variation == null) ? Constants.DEFAULT_VARIATION : variation; @@ -298,23 +300,27 @@ class SongPlayData /** * The note style used by this song. - * TODO: Rename to `noteStyle`? Renaming values is a breaking change to the metadata format. */ - public var noteSkin:String; + public var noteStyle:String; /** - * The difficulty rating for this song as displayed in Freeplay. - * TODO: Adding this is a non-breaking change to the metadata format. + * The difficulty ratings for this song as displayed in Freeplay. + * Key is a difficulty ID or `default`. */ - // public var rating:Int; + @:default(['default' => 1]) + public var ratings:Map<String, Int>; /** * The album ID for the album to display in Freeplay. - * TODO: Adding this is a non-breaking change to the metadata format. + * If `null`, display no album. */ - // public var album:String; + @:optional + public var album:Null<String>; - public function new() {} + public function new() + { + ratings = new Map<String, Int>(); + } /** * Produces a string representation suitable for debugging. diff --git a/source/funkin/data/song/SongRegistry.hx b/source/funkin/data/song/SongRegistry.hx index 889fca707..8e0f4577d 100644 --- a/source/funkin/data/song/SongRegistry.hx +++ b/source/funkin/data/song/SongRegistry.hx @@ -2,6 +2,7 @@ package funkin.data.song; import funkin.data.song.SongData; import funkin.data.song.migrator.SongData_v2_0_0.SongMetadata_v2_0_0; +import funkin.data.song.migrator.SongData_v2_1_0.SongMetadata_v2_1_0; import funkin.data.song.SongData.SongChartData; import funkin.data.song.SongData.SongMetadata; import funkin.play.song.ScriptedSong; @@ -18,9 +19,9 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> * Handle breaking changes by incrementing this value * and adding migration to the `migrateStageData()` function. */ - public static final SONG_METADATA_VERSION:thx.semver.Version = "2.1.0"; + public static final SONG_METADATA_VERSION:thx.semver.Version = "2.2.0"; - public static final SONG_METADATA_VERSION_RULE:thx.semver.VersionRule = "2.1.x"; + public static final SONG_METADATA_VERSION_RULE:thx.semver.VersionRule = "2.2.x"; public static final SONG_CHART_DATA_VERSION:thx.semver.Version = "2.0.0"; @@ -165,6 +166,10 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> { return parseEntryMetadata(id, variation); } + else if (VersionUtil.validateVersion(version, "2.1.x")) + { + return parseEntryMetadata_v2_1_0(id, variation); + } else if (VersionUtil.validateVersion(version, "2.0.x")) { return parseEntryMetadata_v2_0_0(id, variation); @@ -182,6 +187,10 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> { return parseEntryMetadataRaw(contents, fileName); } + else if (VersionUtil.validateVersion(version, "2.1.x")) + { + return parseEntryMetadataRaw_v2_1_0(contents, fileName); + } else if (VersionUtil.validateVersion(version, "2.0.x")) { return parseEntryMetadataRaw_v2_0_0(contents, fileName); @@ -192,12 +201,12 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> } } - function parseEntryMetadata_v2_0_0(id:String, ?variation:String):Null<SongMetadata> + function parseEntryMetadata_v2_1_0(id:String, ?variation:String):Null<SongMetadata> { variation = variation == null ? Constants.DEFAULT_VARIATION : variation; - var parser = new json2object.JsonParser<SongMetadata_v2_0_0>(); - switch (loadEntryMetadataFile(id)) + var parser = new json2object.JsonParser<SongMetadata_v2_1_0>(); + switch (loadEntryMetadataFile(id, variation)) { case {fileName: fileName, contents: contents}: parser.fromJson(contents, fileName); @@ -209,6 +218,39 @@ class SongRegistry extends BaseRegistry<Song, SongMetadata> printErrors(parser.errors, id); return null; } + return cleanMetadata(parser.value.migrate(), variation); + } + + function parseEntryMetadata_v2_0_0(id:String, ?variation:String):Null<SongMetadata> + { + variation = variation == null ? Constants.DEFAULT_VARIATION : variation; + + var parser = new json2object.JsonParser<SongMetadata_v2_0_0>(); + switch (loadEntryMetadataFile(id, variation)) + { + case {fileName: fileName, contents: contents}: + parser.fromJson(contents, fileName); + default: + return null; + } + if (parser.errors.length > 0) + { + printErrors(parser.errors, id); + return null; + } + return cleanMetadata(parser.value.migrate(), variation); + } + + function parseEntryMetadataRaw_v2_1_0(contents:String, ?fileName:String = 'raw'):Null<SongMetadata> + { + var parser = new json2object.JsonParser<SongMetadata_v2_1_0>(); + parser.fromJson(contents, fileName); + + if (parser.errors.length > 0) + { + printErrors(parser.errors, fileName); + return null; + } return parser.value.migrate(); } diff --git a/source/funkin/data/song/importer/ChartManifestData.hx b/source/funkin/data/song/importer/ChartManifestData.hx new file mode 100644 index 000000000..0c7d2f0b0 --- /dev/null +++ b/source/funkin/data/song/importer/ChartManifestData.hx @@ -0,0 +1,84 @@ +package funkin.data.song.importer; + +/** + * A helper JSON blob found in `.fnfc` files. + */ +class ChartManifestData +{ + /** + * The current semantic version of the chart manifest data. + */ + public static final CHART_MANIFEST_DATA_VERSION:thx.semver.Version = "1.0.0"; + + @:default(funkin.data.song.importer.ChartManifestData.CHART_MANIFEST_DATA_VERSION) + @:jcustomparse(funkin.data.DataParse.semverVersion) + @:jcustomwrite(funkin.data.DataWrite.semverVersion) + public var version:thx.semver.Version; + + /** + * The internal song ID for this chart. + * The metadata and chart data file names are derived from this. + */ + public var songId:String; + + public function new(songId:String) + { + this.version = CHART_MANIFEST_DATA_VERSION; + this.songId = songId; + } + + public function getMetadataFileName(?variation:String):String + { + if (variation == null || variation == '') variation = Constants.DEFAULT_VARIATION; + + return '$songId-metadata${variation == Constants.DEFAULT_VARIATION ? '' : '-$variation'}.${Constants.EXT_DATA}'; + } + + public function getChartDataFileName(?variation:String):String + { + if (variation == null || variation == '') variation = Constants.DEFAULT_VARIATION; + + return '$songId-chart${variation == Constants.DEFAULT_VARIATION ? '' : '-$variation'}.${Constants.EXT_DATA}'; + } + + public function getInstFileName(?variation:String):String + { + if (variation == null || variation == '') variation = Constants.DEFAULT_VARIATION; + + return 'Inst${variation == Constants.DEFAULT_VARIATION ? '' : '-$variation'}.${Constants.EXT_SOUND}'; + } + + public function getVocalsFileName(charId:String, ?variation:String):String + { + if (variation == null || variation == '') variation = Constants.DEFAULT_VARIATION; + + return 'Voices-$charId${variation == Constants.DEFAULT_VARIATION ? '' : '-$variation'}.${Constants.EXT_SOUND}'; + } + + /** + * Serialize this ChartManifestData into a JSON string. + * @return The JSON string. + */ + public function serialize(pretty:Bool = true):String + { + var writer = new json2object.JsonWriter<ChartManifestData>(); + return writer.write(this, pretty ? ' ' : null); + } + + public static function deserialize(contents:String):Null<ChartManifestData> + { + var parser = new json2object.JsonParser<ChartManifestData>(); + parser.fromJson(contents, 'manifest.json'); + + if (parser.errors.length > 0) + { + trace('[ChartManifest] Failed to parse chart file manifest'); + + for (error in parser.errors) + DataError.printError(error); + + return null; + } + return parser.value; + } +} diff --git a/source/funkin/data/song/migrator/SongDataMigrator.hx b/source/funkin/data/song/migrator/SongDataMigrator.hx index b5e08c832..2603ab1f8 100644 --- a/source/funkin/data/song/migrator/SongDataMigrator.hx +++ b/source/funkin/data/song/migrator/SongDataMigrator.hx @@ -7,6 +7,8 @@ import funkin.data.song.migrator.SongData_v2_0_0.SongMetadata_v2_0_0; import funkin.data.song.migrator.SongData_v2_0_0.SongPlayData_v2_0_0; import funkin.data.song.migrator.SongData_v2_0_0.SongPlayableChar_v2_0_0; +using funkin.data.song.migrator.SongDataMigrator; // Does this even work lol? + /** * This class contains functions to migrate older data formats to the current one. * @@ -15,6 +17,48 @@ import funkin.data.song.migrator.SongData_v2_0_0.SongPlayableChar_v2_0_0; */ class SongDataMigrator { + public static overload extern inline function migrate(input:SongData_v2_1_0.SongMetadata_v2_1_0):SongMetadata + { + return migrate_SongMetadata_v2_1_0(input); + } + + public static function migrate_SongMetadata_v2_1_0(input:SongData_v2_1_0.SongMetadata_v2_1_0):SongMetadata + { + var result:SongMetadata = new SongMetadata(input.songName, input.artist, input.variation); + result.version = SongRegistry.SONG_METADATA_VERSION; + result.timeFormat = input.timeFormat; + result.divisions = input.divisions; + result.timeChanges = input.timeChanges; + result.looped = input.looped; + result.playData = input.playData.migrate(); + result.generatedBy = input.generatedBy; + + return result; + } + + public static overload extern inline function migrate(input:SongData_v2_1_0.SongPlayData_v2_1_0):SongPlayData + { + return migrate_SongPlayData_v2_1_0(input); + } + + public static function migrate_SongPlayData_v2_1_0(input:SongData_v2_1_0.SongPlayData_v2_1_0):SongPlayData + { + var result:SongPlayData = new SongPlayData(); + result.songVariations = input.songVariations; + result.difficulties = input.difficulties; + result.stage = input.stage; + result.characters = input.characters; + + // Renamed + result.noteStyle = input.noteSkin; + + // Added + result.ratings = ['default' => 1]; + result.album = null; + + return result; + } + public static overload extern inline function migrate(input:SongData_v2_0_0.SongMetadata_v2_0_0):SongMetadata { return migrate_SongMetadata_v2_0_0(input); @@ -23,12 +67,12 @@ class SongDataMigrator public static function migrate_SongMetadata_v2_0_0(input:SongData_v2_0_0.SongMetadata_v2_0_0):SongMetadata { var result:SongMetadata = new SongMetadata(input.songName, input.artist, input.variation); - result.version = input.version; + result.version = SongRegistry.SONG_METADATA_VERSION; result.timeFormat = input.timeFormat; result.divisions = input.divisions; result.timeChanges = input.timeChanges; result.looped = input.looped; - result.playData = migrate_SongPlayData_v2_0_0(input.playData); + result.playData = input.playData.migrate(); result.generatedBy = input.generatedBy; return result; @@ -45,7 +89,13 @@ class SongDataMigrator result.songVariations = input.songVariations; result.difficulties = input.difficulties; result.stage = input.stage; - result.noteSkin = input.noteSkin; + + // Added + result.ratings = ['default' => 1]; + result.album = null; + + // Renamed + result.noteStyle = input.noteSkin; // Fetch the first playable character and migrate it. var firstCharKey:Null<String> = input.playableChars.size() == 0 ? null : input.playableChars.keys().array()[0]; diff --git a/source/funkin/data/song/migrator/SongData_v2_0_0.hx b/source/funkin/data/song/migrator/SongData_v2_0_0.hx index eeeed2f2b..62e3faf4c 100644 --- a/source/funkin/data/song/migrator/SongData_v2_0_0.hx +++ b/source/funkin/data/song/migrator/SongData_v2_0_0.hx @@ -42,6 +42,7 @@ class SongMetadata_v2_0_0 @:default(false) public var looped:Bool; + @:default(funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY) public var generatedBy:String; public var timeFormat:SongData.SongTimeFormat; @@ -70,6 +71,13 @@ class SongPlayData_v2_0_0 */ public var playableChars:Map<String, SongPlayableChar_v2_0_0>; + /** + * In metadata version `v2.2.0`, this was renamed to `noteStyle`. + */ + public var noteSkin:String; + + // In 2.2.0, the ratings value was added. + // In 2.2.0, the album value was added. // ========== // UNMODIFIED VALUES // ========== @@ -77,7 +85,6 @@ class SongPlayData_v2_0_0 public var difficulties:Array<String>; public var stage:String; - public var noteSkin:String; public function new() {} diff --git a/source/funkin/data/song/migrator/SongData_v2_1_0.hx b/source/funkin/data/song/migrator/SongData_v2_1_0.hx new file mode 100644 index 000000000..57e4102d9 --- /dev/null +++ b/source/funkin/data/song/migrator/SongData_v2_1_0.hx @@ -0,0 +1,108 @@ +package funkin.data.song.migrator; + +import funkin.data.song.SongData; +import funkin.data.song.SongRegistry; +import thx.semver.Version; + +@:nullSafety +class SongMetadata_v2_1_0 +{ + // ========== + // MODIFIED VALUES + // =========== + + /** + * In metadata `v2.2.0`, `SongPlayData` was refactored. + */ + public var playData:SongPlayData_v2_1_0; + + // ========== + // UNMODIFIED VALUES + // ========== + @:jcustomparse(funkin.data.DataParse.semverVersion) + @:jcustomwrite(funkin.data.DataWrite.semverVersion) + public var version:Version; + + @:default("Unknown") + public var songName:String; + + @:default("Unknown") + public var artist:String; + + @:optional + @:default(96) + public var divisions:Null<Int>; // Optional field + + @:optional + @:default(false) + public var looped:Bool; + + @:default(funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY) + public var generatedBy:String; + + public var timeFormat:SongData.SongTimeFormat; + + public var timeChanges:Array<SongData.SongTimeChange>; + + /** + * Defaults to `Constants.DEFAULT_VARIATION`. Populated later. + */ + @:jignored + public var variation:String; + + public function new(songName:String, artist:String, ?variation:String) + { + this.version = SongRegistry.SONG_METADATA_VERSION; + this.songName = songName; + this.artist = artist; + this.timeFormat = 'ms'; + this.divisions = null; + this.timeChanges = [new SongTimeChange(0, 100)]; + this.looped = false; + this.playData = new SongPlayData_v2_1_0(); + this.playData.songVariations = []; + this.playData.difficulties = []; + this.playData.characters = new SongCharacterData('bf', 'gf', 'dad'); + this.playData.stage = 'mainStage'; + this.playData.noteSkin = 'funkin'; + this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY; + // Variation ID. + this.variation = (variation == null) ? Constants.DEFAULT_VARIATION : variation; + } + + /** + * Produces a string representation suitable for debugging. + */ + public function toString():String + { + return 'SongMetadata[LEGACY:v2.1.0](${this.songName} by ${this.artist}, variation ${this.variation})'; + } +} + +class SongPlayData_v2_1_0 +{ + /** + * In `v2.2.0`, this value was renamed to `noteStyle`. + */ + public var noteSkin:String; + + // In 2.2.0, the ratings value was added. + // In 2.2.0, the album value was added. + // ========== + // UNMODIFIED VALUES + // ========== + public var songVariations:Array<String>; + public var difficulties:Array<String>; + public var characters:SongData.SongCharacterData; + public var stage:String; + + public function new() {} + + /** + * Produces a string representation suitable for debugging. + */ + public function toString():String + { + return 'SongPlayData[LEGACY:v2.1.0](${this.songVariations}, ${this.difficulties})'; + } +} diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 1d3480efe..9a126e509 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1471,7 +1471,7 @@ class PlayState extends MusicBeatSubState { case 'school': 'pixel'; case 'schoolEvil': 'pixel'; - default: 'funkin'; + default: Constants.DEFAULT_NOTE_STYLE; } var noteStyle:NoteStyle = NoteStyleRegistry.instance.fetchEntry(noteStyleId); if (noteStyle == null) noteStyle = NoteStyleRegistry.instance.fetchDefault(); @@ -2389,8 +2389,8 @@ class PlayState extends MusicBeatSubState #if sys // spitter for ravy, teehee!! - - var output = SerializerUtil.toJSON(inputSpitter); + var writer = new json2object.JsonWriter<Array<ScoreInput>>(); + var output = writer.write(inputSpitter, ' '); sys.io.File.saveContent("./scores.json", output); #end diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 60b8b9864..90920a710 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -96,11 +96,13 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta if (_data != null && _data.playData != null) { for (vari in _data.playData.songVariations) + { variations.push(vari); - } - for (meta in fetchVariationMetadata(id)) - _metadata.push(meta); + var variMeta = fetchVariationMetadata(id, vari); + if (variMeta != null) _metadata.push(variMeta); + } + } if (_metadata.length == 0) { @@ -178,7 +180,7 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta difficulty.generatedBy = metadata.generatedBy; difficulty.stage = metadata.playData.stage; - difficulty.noteStyle = metadata.playData.noteSkin; + difficulty.noteStyle = metadata.playData.noteStyle; difficulties.set(diffId, difficulty); @@ -337,17 +339,12 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta return SongRegistry.instance.parseEntryMetadataWithMigration(id, Constants.DEFAULT_VARIATION, version); } - function fetchVariationMetadata(id:String):Array<SongMetadata> + function fetchVariationMetadata(id:String, vari:String):Null<SongMetadata> { - var result:Array<SongMetadata> = []; - for (vari in variations) - { - var version:Null<thx.semver.Version> = SongRegistry.instance.fetchEntryMetadataVersion(id, vari); - if (version == null) continue; - var meta:Null<SongMetadata> = SongRegistry.instance.parseEntryMetadataWithMigration(id, vari, version); - if (meta != null) result.push(meta); - } - return result; + var version:Null<thx.semver.Version> = SongRegistry.instance.fetchEntryMetadataVersion(id, vari); + if (version == null) return null; + var meta:Null<SongMetadata> = SongRegistry.instance.parseEntryMetadataWithMigration(id, vari, version); + return meta; } } diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index d9875e456..89b85d14c 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -176,13 +176,13 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass continue; } - if (Std.isOfType(dataProp.scale, Array)) + switch (dataProp.scale) { - propSprite.scale.set(dataProp.scale[0], dataProp.scale[1]); - } - else - { - propSprite.scale.set(dataProp.scale); + case Left(value): + propSprite.scale.set(value); + + case Right(values): + propSprite.scale.set(values[0], values[1]); } propSprite.updateHitbox(); @@ -194,8 +194,15 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass // If pixel, disable antialiasing. propSprite.antialiasing = !dataProp.isPixel; - propSprite.scrollFactor.x = dataProp.scroll[0]; - propSprite.scrollFactor.y = dataProp.scroll[1]; + switch (dataProp.scroll) + { + case Left(value): + propSprite.scrollFactor.x = value; + propSprite.scrollFactor.y = value; + case Right(values): + propSprite.scrollFactor.x = values[0]; + propSprite.scrollFactor.y = values[1]; + } propSprite.zIndex = dataProp.zIndex; diff --git a/source/funkin/play/stage/StageData.hx b/source/funkin/play/stage/StageData.hx index c14e05aaf..29ca03b84 100644 --- a/source/funkin/play/stage/StageData.hx +++ b/source/funkin/play/stage/StageData.hx @@ -1,7 +1,6 @@ package funkin.play.stage; import funkin.data.animation.AnimationData; -import flixel.util.typeLimit.OneOfTwo; import funkin.play.stage.ScriptedStage; import funkin.play.stage.Stage; import funkin.util.VersionUtil; @@ -157,15 +156,26 @@ class StageDataParser return rawJson; } - static function migrateStageData(rawJson:String, stageId:String) + static function migrateStageData(rawJson:String, stageId:String):Null<StageData> { // If you update the stage data format in a breaking way, // handle migration here by checking the `version` value. try { - var stageData:StageData = cast Json.parse(rawJson); - return stageData; + var parser = new json2object.JsonParser<StageData>(); + parser.fromJson(rawJson, '$stageId.json'); + + if (parser.errors.length > 0) + { + trace('[STAGE] Failed to parse stage data'); + + for (error in parser.errors) + funkin.data.DataError.printError(error); + + return null; + } + return parser.value; } catch (e) { @@ -269,24 +279,29 @@ class StageDataParser inputProp.danceEvery = DEFAULT_DANCEEVERY; } - if (inputProp.scale == null) - { - inputProp.scale = DEFAULT_SCALE; - } - if (inputProp.animType == null) { inputProp.animType = DEFAULT_ANIMTYPE; } - if (Std.isOfType(inputProp.scale, Float)) + switch (inputProp.scale) { - inputProp.scale = [inputProp.scale, inputProp.scale]; + case null: + inputProp.scale = Right([DEFAULT_SCALE, DEFAULT_SCALE]); + case Left(value): + inputProp.scale = Right([value, value]); + case Right(_): + // Do nothing } - if (inputProp.scroll == null) + switch (inputProp.scroll) { - inputProp.scroll = DEFAULT_SCROLL; + case null: + inputProp.scroll = Right(DEFAULT_SCROLL); + case Left(value): + inputProp.scroll = Right([value, value]); + case Right(_): + // Do nothing } if (inputProp.alpha == null) @@ -294,11 +309,6 @@ class StageDataParser inputProp.alpha = DEFAULT_ALPHA; } - if (Std.isOfType(inputProp.scroll, Float)) - { - inputProp.scroll = [inputProp.scroll, inputProp.scroll]; - } - if (inputProp.animations == null) { inputProp.animations = []; @@ -392,23 +402,39 @@ class StageDataParser } } -typedef StageData = +class StageData { /** * The sematic version number of the stage data JSON format. * Supports fancy comparisons like NPM does it's neat. */ - var version:String; + public var version:String; - var name:String; - var cameraZoom:Null<Float>; - var props:Array<StageDataProp>; - var characters: - { - bf:StageDataCharacter, - dad:StageDataCharacter, - gf:StageDataCharacter, - }; + public var name:String; + public var cameraZoom:Null<Float>; + public var props:Array<StageDataProp>; + public var characters:StageDataCharacters; + + public function new() + { + this.version = StageDataParser.STAGE_DATA_VERSION; + } + + /** + * Convert this StageData into a JSON string. + */ + public function serialize(pretty:Bool = true):String + { + var writer = new json2object.JsonWriter<StageData>(); + return writer.write(this, pretty ? ' ' : null); + } +} + +typedef StageDataCharacters = +{ + var bf:StageDataCharacter; + var dad:StageDataCharacter; + var gf:StageDataCharacter; }; typedef StageDataProp = @@ -417,6 +443,7 @@ typedef StageDataProp = * The name of the prop for later lookup by scripts. * Optional; if unspecified, the prop can't be referenced by scripts. */ + @:optional var name:String; /** @@ -435,27 +462,35 @@ typedef StageDataProp = * This is just like CSS, it isn't hard. * @default 0 */ - var zIndex:Null<Int>; + @:optional + @:default(0) + var zIndex:Int; /** * If set to true, anti-aliasing will be forcibly disabled on the sprite. * This prevents blurry images on pixel-art levels. * @default false */ - var isPixel:Null<Bool>; + @:optional + @:default(false) + var isPixel:Bool; /** * Either the scale of the prop as a float, or the [w, h] scale as an array of two floats. * Pro tip: On pixel-art levels, save the sprite small and set this value to 6 or so to save memory. - * @default 1 */ - var scale:OneOfTwo<Float, Array<Float>>; + @:jcustomparse(funkin.data.DataParse.eitherFloatOrFloats) + @:jcustomwrite(funkin.data.DataWrite.eitherFloatOrFloats) + @:optional + var scale:haxe.ds.Either<Float, Array<Float>>; /** * The alpha of the prop, as a float. * @default 1.0 */ - var alpha:Null<Float>; + @:optional + @:default(1.0) + var alpha:Float; /** * If not zero, this prop will play an animation every X beats of the song. @@ -464,7 +499,9 @@ typedef StageDataProp = * * @default 0 */ - var danceEvery:Null<Int>; + @:default(0) + @:optional + var danceEvery:Int; /** * How much the prop scrolls relative to the camera. Used to create a parallax effect. @@ -474,25 +511,32 @@ typedef StageDataProp = * [0, 0] means the prop is not moved. * @default [0, 0] */ - var scroll:OneOfTwo<Float, Array<Float>>; + @:jcustomparse(funkin.data.DataParse.eitherFloatOrFloats) + @:jcustomwrite(funkin.data.DataWrite.eitherFloatOrFloats) + @:optional + var scroll:haxe.ds.Either<Float, Array<Float>>; /** * An optional array of animations which the prop can play. * @default Prop has no animations. */ + @:optional var animations:Array<AnimationData>; /** * If animations are used, this is the name of the animation to play first. * @default Don't play an animation. */ - var startingAnimation:String; + @:optional + var startingAnimation:Null<String>; /** * The animation type to use. * Options: "sparrow", "packer" * @default "sparrow" */ + @:default("sparrow") + @:optional var animType:String; }; @@ -503,16 +547,22 @@ typedef StageDataCharacter = * Again, just like CSS. * @default 0 */ - ?zIndex:Int, + @:optional + @:default(0) + var zIndex:Int; /** * The position to render the character at. */ - position:Array<Float>, + @:optional + @:default([0, 0]) + var position:Array<Float>; /** * The camera offsets to apply when focusing on the character on this stage. * @default [-100, -100] for BF, [100, -100] for DAD/OPPONENT, [0, 0] for GF */ - cameraOffsets:Array<Float>, + @:optional + @:default([0, 0]) + var cameraOffsets:Array<Float>; }; diff --git a/source/funkin/save/migrator/SaveDataMigrator.hx b/source/funkin/save/migrator/SaveDataMigrator.hx index e7b7c7583..d5b23cfd9 100644 --- a/source/funkin/save/migrator/SaveDataMigrator.hx +++ b/source/funkin/save/migrator/SaveDataMigrator.hx @@ -13,8 +13,7 @@ class SaveDataMigrator */ public static function migrate(inputData:Dynamic):Save { - // This deserializes directly into a `Version` object, not a `String`. - var version:Null<Version> = inputData?.version ?? null; + var version:Null<thx.semver.Version> = VersionUtil.parseVersion(inputData?.version ?? null); if (version == null) { @@ -24,7 +23,7 @@ class SaveDataMigrator } else { - if (VersionUtil.validateVersionStr(version, Save.SAVE_DATA_VERSION_RULE)) + if (VersionUtil.validateVersion(version, Save.SAVE_DATA_VERSION_RULE)) { // Simply cast the structured data. var save:Save = inputData; diff --git a/source/funkin/ui/debug/charting/ChartEditorAudioHandler.hx b/source/funkin/ui/debug/charting/ChartEditorAudioHandler.hx index b5a6f36be..6f390e604 100644 --- a/source/funkin/ui/debug/charting/ChartEditorAudioHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorAudioHandler.hx @@ -265,7 +265,7 @@ class ChartEditorAudioHandler { var data:Null<Bytes> = state.audioVocalTrackData.get(key); if (data == null) continue; - zipEntries.push(FileUtil.makeZIPEntryFromBytes('Vocals-${key}.ogg', data)); + zipEntries.push(FileUtil.makeZIPEntryFromBytes('Voices-${key}.ogg', data)); } return zipEntries; diff --git a/source/funkin/ui/debug/charting/ChartEditorCommand.hx b/source/funkin/ui/debug/charting/ChartEditorCommand.hx index 1014e67c2..98ca810d3 100644 --- a/source/funkin/ui/debug/charting/ChartEditorCommand.hx +++ b/source/funkin/ui/debug/charting/ChartEditorCommand.hx @@ -182,8 +182,8 @@ class SelectItemsCommand implements ChartEditorCommand state.currentEventSelection.push(event); } - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + // state.noteDisplayDirty = true; + // state.notePreviewDirty = true; } public function undo(state:ChartEditorState):Void @@ -191,8 +191,8 @@ class SelectItemsCommand implements ChartEditorCommand state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentNoteSelection, this.notes); state.currentEventSelection = SongDataUtils.subtractEvents(state.currentEventSelection, this.events); - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + // state.noteDisplayDirty = true; + // state.notePreviewDirty = true; } public function toString():String @@ -452,8 +452,8 @@ class DeselectItemsCommand implements ChartEditorCommand state.currentNoteSelection = SongDataUtils.subtractNotes(state.currentNoteSelection, this.notes); state.currentEventSelection = SongDataUtils.subtractEvents(state.currentEventSelection, this.events); - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + // state.noteDisplayDirty = true; + // state.notePreviewDirty = true; } public function undo(state:ChartEditorState):Void @@ -468,8 +468,8 @@ class DeselectItemsCommand implements ChartEditorCommand state.currentEventSelection.push(event); } - state.noteDisplayDirty = true; - state.notePreviewDirty = true; + // state.noteDisplayDirty = true; + // state.notePreviewDirty = true; } public function toString():String diff --git a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx index c26f6c805..dd5ddb06c 100644 --- a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx @@ -51,12 +51,13 @@ class ChartEditorDialogHandler { static final CHART_EDITOR_DIALOG_ABOUT_LAYOUT:String = Paths.ui('chart-editor/dialogs/about'); static final CHART_EDITOR_DIALOG_WELCOME_LAYOUT:String = Paths.ui('chart-editor/dialogs/welcome'); + static final CHART_EDITOR_DIALOG_UPLOAD_CHART_LAYOUT:String = Paths.ui('chart-editor/dialogs/upload-chart'); static final CHART_EDITOR_DIALOG_UPLOAD_INST_LAYOUT:String = Paths.ui('chart-editor/dialogs/upload-inst'); static final CHART_EDITOR_DIALOG_SONG_METADATA_LAYOUT:String = Paths.ui('chart-editor/dialogs/song-metadata'); static final CHART_EDITOR_DIALOG_UPLOAD_VOCALS_LAYOUT:String = Paths.ui('chart-editor/dialogs/upload-vocals'); static final CHART_EDITOR_DIALOG_UPLOAD_VOCALS_ENTRY_LAYOUT:String = Paths.ui('chart-editor/dialogs/upload-vocals-entry'); - static final CHART_EDITOR_DIALOG_OPEN_CHART_LAYOUT:String = Paths.ui('chart-editor/dialogs/open-chart'); - static final CHART_EDITOR_DIALOG_OPEN_CHART_ENTRY_LAYOUT:String = Paths.ui('chart-editor/dialogs/open-chart-entry'); + static final CHART_EDITOR_DIALOG_OPEN_CHART_PARTS_LAYOUT:String = Paths.ui('chart-editor/dialogs/open-chart-parts'); + static final CHART_EDITOR_DIALOG_OPEN_CHART_PARTS_ENTRY_LAYOUT:String = Paths.ui('chart-editor/dialogs/open-chart-parts-entry'); static final CHART_EDITOR_DIALOG_IMPORT_CHART_LAYOUT:String = Paths.ui('chart-editor/dialogs/import-chart'); static final CHART_EDITOR_DIALOG_USER_GUIDE_LAYOUT:String = Paths.ui('chart-editor/dialogs/user-guide'); static final CHART_EDITOR_DIALOG_ADD_VARIATION_LAYOUT:String = Paths.ui('chart-editor/dialogs/add-variation'); @@ -83,6 +84,11 @@ class ChartEditorDialogHandler var dialog:Null<Dialog> = openDialog(state, CHART_EDITOR_DIALOG_WELCOME_LAYOUT, true, closable); if (dialog == null) throw 'Could not locate Welcome dialog'; + dialog.onDialogClosed = function(_event) { + // Called when the Welcome dialog is closed while it is closable. + state.stopWelcomeMusic(); + } + // Create New Song "Easy/Normal/Hard" var linkCreateBasic:Null<Link> = dialog.findComponent('splashCreateFromSongBasic', Link); if (linkCreateBasic == null) throw 'Could not locate splashCreateFromSongBasic link in Welcome dialog'; @@ -129,7 +135,7 @@ class ChartEditorDialogHandler state.stopWelcomeMusic(); // Open the "Open Chart" dialog - openBrowseWizard(state, false); + openBrowseFNFC(state, false); } var splashTemplateContainer:Null<VBox> = dialog.findComponent('splashTemplateContainer', VBox); @@ -168,6 +174,126 @@ class ChartEditorDialogHandler return dialog; } + public static function openBrowseFNFC(state:ChartEditorState, closable:Bool):Null<Dialog> + { + var dialog:Null<Dialog> = openDialog(state, CHART_EDITOR_DIALOG_UPLOAD_CHART_LAYOUT, true, closable); + if (dialog == null) throw 'Could not locate Upload Chart dialog'; + + dialog.onDialogClosed = function(_event) { + if (_event.button == DialogButton.APPLY) + { + // Simply let the dialog close. + } + else + { + // User cancelled the wizard! Back to the welcome dialog. + openWelcomeDialog(state); + } + }; + + var buttonCancel:Null<Button> = dialog.findComponent('dialogCancel', Button); + if (buttonCancel == null) throw 'Could not locate dialogCancel button in Upload Chart dialog'; + + buttonCancel.onClick = function(_event) { + dialog.hideDialog(DialogButton.CANCEL); + } + + var chartBox:Null<Box> = dialog.findComponent('chartBox', Box); + if (chartBox == null) throw 'Could not locate chartBox in Upload Chart dialog'; + + chartBox.onMouseOver = function(_event) { + chartBox.swapClass('upload-bg', 'upload-bg-hover'); + Cursor.cursorMode = Pointer; + } + + chartBox.onMouseOut = function(_event) { + chartBox.swapClass('upload-bg-hover', 'upload-bg'); + Cursor.cursorMode = Default; + } + + var onDropFile:String->Void; + + chartBox.onClick = function(_event) { + Dialogs.openBinaryFile('Open Chart', [ + {label: 'Friday Night Funkin\' Chart (.fnfc)', extension: 'fnfc'}], function(selectedFile:SelectedFileInfo) { + if (selectedFile != null && selectedFile.bytes != null) + { + try + { + if (ChartEditorImportExportHandler.loadFromFNFC(state, selectedFile.bytes)) + { + #if !mac + NotificationManager.instance.addNotification( + { + title: 'Success', + body: 'Loaded chart (${selectedFile.name})', + type: NotificationType.Success, + expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + }); + #end + + if (selectedFile.fullPath != null) state.currentWorkingFilePath = selectedFile.fullPath; + dialog.hideDialog(DialogButton.APPLY); + removeDropHandler(onDropFile); + } + } + catch (err) + { + #if !mac + NotificationManager.instance.addNotification( + { + title: 'Failure', + body: 'Failed to load chart (${selectedFile.name}): ${err}', + type: NotificationType.Error, + expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + }); + #end + } + } + }); + } + + onDropFile = function(pathStr:String) { + var path:Path = new Path(pathStr); + trace('Dropped file (${path})'); + + try + { + if (ChartEditorImportExportHandler.loadFromFNFCPath(state, path.toString())) + { + #if !mac + NotificationManager.instance.addNotification( + { + title: 'Success', + body: 'Loaded chart (${path.toString()})', + type: NotificationType.Success, + expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + }); + #end + + dialog.hideDialog(DialogButton.APPLY); + removeDropHandler(onDropFile); + } + } + catch (err) + { + #if !mac + NotificationManager.instance.addNotification( + { + title: 'Failure', + body: 'Failed to load chart (${path.toString()}): ${err}', + type: NotificationType.Error, + expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + }); + #end + } + }; + + addDropHandler(chartBox, onDropFile); + + return dialog; + } + /** * Open the wizard for opening an existing chart from individual files. * @param state @@ -622,9 +748,9 @@ class ChartEditorDialogHandler if (inputNoteStyle == null) throw 'Could not locate inputNoteStyle DropDown in Song Metadata dialog'; inputNoteStyle.onChange = function(event:UIEvent) { if (event.data.id == null) return; - newSongMetadata.playData.noteSkin = event.data.id; + newSongMetadata.playData.noteStyle = event.data.id; }; - var startingValueNoteStyle = ChartEditorDropdowns.populateDropdownWithNoteStyles(inputNoteStyle, newSongMetadata.playData.noteSkin); + var startingValueNoteStyle = ChartEditorDropdowns.populateDropdownWithNoteStyles(inputNoteStyle, newSongMetadata.playData.noteStyle); inputNoteStyle.value = startingValueNoteStyle; var inputCharacterPlayer:Null<FunkinDropDown> = dialog.findComponent('inputCharacterPlayer', FunkinDropDown); @@ -765,9 +891,9 @@ class ChartEditorDialogHandler }); #end #if FILE_DROP_SUPPORTED - vocalsEntryLabel.text = 'Vocals for $charName (drag and drop, or click to browse)\nSelected file: ${path.file}.${path.ext}'; + vocalsEntryLabel.text = 'Voices for $charName (drag and drop, or click to browse)\nSelected file: ${path.file}.${path.ext}'; #else - vocalsEntryLabel.text = 'Vocals for $charName (click to browse)\n${path.file}.${path.ext}'; + vocalsEntryLabel.text = 'Voices for $charName (click to browse)\n${path.file}.${path.ext}'; #end dialogNoVocals.hidden = true; @@ -820,9 +946,9 @@ class ChartEditorDialogHandler }); #end #if FILE_DROP_SUPPORTED - vocalsEntryLabel.text = 'Vocals for $charName (drag and drop, or click to browse)\nSelected file: ${selectedFile.name}'; + vocalsEntryLabel.text = 'Voices for $charName (drag and drop, or click to browse)\nSelected file: ${selectedFile.name}'; #else - vocalsEntryLabel.text = 'Vocals for $charName (click to browse)\n${selectedFile.name}'; + vocalsEntryLabel.text = 'Voices for $charName (click to browse)\n${selectedFile.name}'; #end dialogNoVocals.hidden = true; @@ -877,7 +1003,7 @@ class ChartEditorDialogHandler @:haxe.warning('-WVarInit') public static function openChartDialog(state:ChartEditorState, closable:Bool = true):Dialog { - var dialog:Null<Dialog> = openDialog(state, CHART_EDITOR_DIALOG_OPEN_CHART_LAYOUT, true, closable); + var dialog:Null<Dialog> = openDialog(state, CHART_EDITOR_DIALOG_OPEN_CHART_PARTS_LAYOUT, true, closable); if (dialog == null) throw 'Could not locate Open Chart dialog'; var buttonCancel:Null<Button> = dialog.findComponent('dialogCancel', Button); @@ -915,7 +1041,7 @@ class ChartEditorDialogHandler } // Build an entry for -chart.json. - var songDefaultChartDataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_ENTRY_LAYOUT); + var songDefaultChartDataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_PARTS_ENTRY_LAYOUT); var songDefaultChartDataEntryLabel:Null<Label> = songDefaultChartDataEntry.findComponent('chartEntryLabel', Label); if (songDefaultChartDataEntryLabel == null) throw 'Could not locate chartEntryLabel in Open Chart dialog'; #if FILE_DROP_SUPPORTED @@ -931,7 +1057,7 @@ class ChartEditorDialogHandler for (variation in variations) { // Build entries for -metadata-<variation>.json. - var songVariationMetadataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_ENTRY_LAYOUT); + var songVariationMetadataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_PARTS_ENTRY_LAYOUT); var songVariationMetadataEntryLabel:Null<Label> = songVariationMetadataEntry.findComponent('chartEntryLabel', Label); if (songVariationMetadataEntryLabel == null) throw 'Could not locate chartEntryLabel in Open Chart dialog'; #if FILE_DROP_SUPPORTED @@ -955,7 +1081,7 @@ class ChartEditorDialogHandler chartContainerB.addComponent(songVariationMetadataEntry); // Build entries for -chart-<variation>.json. - var songVariationChartDataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_ENTRY_LAYOUT); + var songVariationChartDataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_PARTS_ENTRY_LAYOUT); var songVariationChartDataEntryLabel:Null<Label> = songVariationChartDataEntry.findComponent('chartEntryLabel', Label); if (songVariationChartDataEntryLabel == null) throw 'Could not locate chartEntryLabel in Open Chart dialog'; #if FILE_DROP_SUPPORTED @@ -1230,7 +1356,7 @@ class ChartEditorDialogHandler }); } - var metadataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_ENTRY_LAYOUT); + var metadataEntry:Component = state.buildComponent(CHART_EDITOR_DIALOG_OPEN_CHART_PARTS_ENTRY_LAYOUT); var metadataEntryLabel:Null<Label> = metadataEntry.findComponent('chartEntryLabel', Label); if (metadataEntryLabel == null) throw 'Could not locate chartEntryLabel in Open Chart dialog'; @@ -1447,7 +1573,7 @@ class ChartEditorDialogHandler var dialogNoteStyle:Null<DropDown> = dialog.findComponent('dialogNoteStyle', DropDown); if (dialogNoteStyle == null) throw 'Could not locate dialogNoteStyle DropDown in Add Variation dialog'; - dialogNoteStyle.value = state.currentSongMetadata.playData.noteSkin; + dialogNoteStyle.value = state.currentSongMetadata.playData.noteStyle; var dialogCharacterPlayer:Null<DropDown> = dialog.findComponent('dialogCharacterPlayer', DropDown); if (dialogCharacterPlayer == null) throw 'Could not locate dialogCharacterPlayer DropDown in Add Variation dialog'; @@ -1479,7 +1605,7 @@ class ChartEditorDialogHandler var pendingVariation:SongMetadata = new SongMetadata(dialogSongName.text, dialogSongArtist.text, dialogVariationName.text.toLowerCase()); pendingVariation.playData.stage = dialogStage.value.id; - pendingVariation.playData.noteSkin = dialogNoteStyle.value; + pendingVariation.playData.noteStyle = dialogNoteStyle.value; pendingVariation.timeChanges[0].bpm = dialogBPM.value; state.songMetadata.set(pendingVariation.variation, pendingVariation); diff --git a/source/funkin/ui/debug/charting/ChartEditorImportExportHandler.hx b/source/funkin/ui/debug/charting/ChartEditorImportExportHandler.hx index 4d8ff18cb..c5cbdd5de 100644 --- a/source/funkin/ui/debug/charting/ChartEditorImportExportHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorImportExportHandler.hx @@ -1,5 +1,6 @@ package funkin.ui.debug.charting; +import funkin.util.VersionUtil; import haxe.ui.notifications.NotificationType; import funkin.util.DateUtil; import haxe.io.Path; @@ -7,10 +8,12 @@ import funkin.util.SerializerUtil; import haxe.ui.notifications.NotificationManager; import funkin.util.FileUtil; import funkin.util.FileUtil; +import haxe.io.Bytes; import funkin.play.song.Song; import funkin.data.song.SongData.SongChartData; import funkin.data.song.SongData.SongMetadata; import funkin.data.song.SongRegistry; +import funkin.data.song.importer.ChartManifestData; /** * Contains functions for importing, loading, saving, and exporting charts. @@ -104,7 +107,7 @@ class ChartEditorImportExportHandler } /** - * Loads song metadata and chart data into the editor. + * Loads a chart from parsed song metadata and chart data into the editor. * @param newSongMetadata The song metadata to load. * @param newSongChartData The song chart data to load. */ @@ -135,15 +138,179 @@ class ChartEditorImportExportHandler } } - /** - * @param force Whether to force the export without prompting the user for a file location. - */ - public static function exportAllSongData(state:ChartEditorState, force:Bool = false):Void + public static function loadFromFNFCPath(state:ChartEditorState, path:String):Bool + { + var bytes:Null<Bytes> = FileUtil.readBytesFromPath(path); + if (bytes == null) return false; + + trace('Loaded ${bytes.length} bytes from $path'); + + var result:Bool = loadFromFNFC(state, bytes); + if (result) + { + state.currentWorkingFilePath = path; + } + + return result; + } + + /** + * Load a chart's metadata, chart data, and audio from an FNFC archive.. + * @param state + * @param bytes + * @param instId + * @return Bool + */ + public static function loadFromFNFC(state:ChartEditorState, bytes:Bytes):Bool + { + var songMetadatas:Map<String, SongMetadata> = []; + var songChartDatas:Map<String, SongChartData> = []; + + var fileEntries:Array<haxe.zip.Entry> = FileUtil.readZIPFromBytes(bytes); + var mappedFileEntries:Map<String, haxe.zip.Entry> = FileUtil.mapZIPEntriesByName(fileEntries); + + var manifestBytes:Null<Bytes> = mappedFileEntries.get('manifest.json')?.data; + if (manifestBytes == null) throw 'Could not locate manifest.'; + var manifestString = manifestBytes.toString(); + var manifest:Null<ChartManifestData> = ChartManifestData.deserialize(manifestString); + if (manifest == null) throw 'Could not read manifest.'; + + // Get the song ID. + var songId:String = manifest.songId; + + var baseMetadataPath:String = manifest.getMetadataFileName(); + var baseChartDataPath:String = manifest.getChartDataFileName(); + + var baseMetadataBytes:Null<Bytes> = mappedFileEntries.get(baseMetadataPath)?.data; + if (baseMetadataBytes == null) throw 'Could not locate metadata (default).'; + var baseMetadataString:String = baseMetadataBytes.toString(); + var baseMetadataVersion:Null<thx.semver.Version> = VersionUtil.getVersionFromJSON(baseMetadataString); + if (baseMetadataVersion == null) throw 'Could not read metadata version (default).'; + + var baseMetadata:Null<SongMetadata> = SongRegistry.instance.parseEntryMetadataRawWithMigration(baseMetadataString, baseMetadataPath, baseMetadataVersion); + if (baseMetadata == null) throw 'Could not read metadata (default).'; + songMetadatas.set(Constants.DEFAULT_VARIATION, baseMetadata); + + var baseChartDataBytes:Null<Bytes> = mappedFileEntries.get(baseChartDataPath)?.data; + if (baseChartDataBytes == null) throw 'Could not locate chart data (default).'; + var baseChartDataString:String = baseChartDataBytes.toString(); + var baseChartDataVersion:Null<thx.semver.Version> = VersionUtil.getVersionFromJSON(baseChartDataString); + if (baseChartDataVersion == null) throw 'Could not read chart data (default) version.'; + + var baseChartData:Null<SongChartData> = SongRegistry.instance.parseEntryChartDataRawWithMigration(baseChartDataString, baseChartDataPath, + baseChartDataVersion); + if (baseChartData == null) throw 'Could not read chart data (default).'; + songChartDatas.set(Constants.DEFAULT_VARIATION, baseChartData); + + var variationList:Array<String> = baseMetadata.playData.songVariations; + + for (variation in variationList) + { + var variMetadataPath:String = manifest.getMetadataFileName(variation); + var variChartDataPath:String = manifest.getChartDataFileName(variation); + + var variMetadataBytes:Null<Bytes> = mappedFileEntries.get(variMetadataPath)?.data; + if (variMetadataBytes == null) throw 'Could not locate metadata ($variation).'; + var variMetadataString:String = variMetadataBytes.toString(); + var variMetadataVersion:Null<thx.semver.Version> = VersionUtil.getVersionFromJSON(variMetadataString); + if (variMetadataVersion == null) throw 'Could not read metadata ($variation) version.'; + + var variMetadata:Null<SongMetadata> = SongRegistry.instance.parseEntryMetadataRawWithMigration(baseMetadataString, variMetadataPath, variMetadataVersion); + if (variMetadata == null) throw 'Could not read metadata ($variation).'; + songMetadatas.set(variation, variMetadata); + + var variChartDataBytes:Null<Bytes> = mappedFileEntries.get(variChartDataPath)?.data; + if (variChartDataBytes == null) throw 'Could not locate chart data ($variation).'; + var variChartDataString:String = variChartDataBytes.toString(); + var variChartDataVersion:Null<thx.semver.Version> = VersionUtil.getVersionFromJSON(variChartDataString); + if (variChartDataVersion == null) throw 'Could not read chart data version ($variation).'; + + var variChartData:Null<SongChartData> = SongRegistry.instance.parseEntryChartDataRawWithMigration(variChartDataString, variChartDataPath, + variChartDataVersion); + if (variChartData == null) throw 'Could not read chart data ($variation).'; + songChartDatas.set(variation, variChartData); + } + + ChartEditorAudioHandler.stopExistingInstrumental(state); + ChartEditorAudioHandler.stopExistingVocals(state); + + // Load instrumentals + for (variation in [Constants.DEFAULT_VARIATION].concat(variationList)) + { + var variMetadata:Null<SongMetadata> = songMetadatas.get(variation); + if (variMetadata == null) continue; + + var instId:String = variMetadata?.playData?.characters?.instrumental ?? ''; + var playerCharId:String = variMetadata?.playData?.characters?.player ?? Constants.DEFAULT_CHARACTER; + var opponentCharId:Null<String> = variMetadata?.playData?.characters?.opponent; + + var instFileName:String = manifest.getInstFileName(instId); + var instFileBytes:Null<Bytes> = mappedFileEntries.get(instFileName)?.data; + if (instFileBytes != null) + { + if (!ChartEditorAudioHandler.loadInstFromBytes(state, instFileBytes, instId)) + { + throw 'Could not load instrumental ($instFileName).'; + } + } + else + { + throw 'Could not find instrumental ($instFileName).'; + } + + var playerVocalsFileName:String = manifest.getVocalsFileName(playerCharId); + var playerVocalsFileBytes:Null<Bytes> = mappedFileEntries.get(playerVocalsFileName)?.data; + if (playerVocalsFileBytes != null) + { + if (!ChartEditorAudioHandler.loadVocalsFromBytes(state, playerVocalsFileBytes, playerCharId, instId)) + { + throw 'Could not load vocals ($playerCharId).'; + } + } + else + { + throw 'Could not find vocals ($playerVocalsFileName).'; + } + + if (opponentCharId != null) + { + var opponentVocalsFileName:String = manifest.getVocalsFileName(opponentCharId); + var opponentVocalsFileBytes:Null<Bytes> = mappedFileEntries.get(opponentVocalsFileName)?.data; + if (opponentVocalsFileBytes != null) + { + if (!ChartEditorAudioHandler.loadVocalsFromBytes(state, opponentVocalsFileBytes, opponentCharId, instId)) + { + throw 'Could not load vocals ($opponentCharId).'; + } + } + else + { + throw 'Could not load vocals ($playerCharId-$instId).'; + } + } + } + + // Apply chart data. + trace(songMetadatas); + trace(songChartDatas); + loadSong(state, songMetadatas, songChartDatas); + + state.switchToCurrentInstrumental(); + + return true; + } + + /** + * @param force Whether to export without prompting. `false` will prompt the user for a location. + * @param targetPath where to export if `force` is `true`. If `null`, will export to the `backups` folder. + */ + public static function exportAllSongData(state:ChartEditorState, force:Bool = false, ?targetPath:String):Void { - var tmp = false; var zipEntries:Array<haxe.zip.Entry> = []; - for (variation in state.availableVariations) + var variations = state.availableVariations; + + for (variation in variations) { var variationId:String = variation; if (variation == '' || variation == 'default' || variation == 'normal') @@ -162,50 +329,51 @@ class ChartEditorImportExportHandler { var variationMetadata:Null<SongMetadata> = state.songMetadata.get(variation); if (variationMetadata != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata-$variationId.json', - SerializerUtil.toJSON(variationMetadata))); + variationMetadata.serialize())); var variationChart:Null<SongChartData> = state.songChartData.get(variation); - if (variationChart != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart-$variationId.json', - SerializerUtil.toJSON(variationChart))); + if (variationChart != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart-$variationId.json', variationChart.serialize())); } } - if (state.audioInstTrackData != null) zipEntries.concat(ChartEditorAudioHandler.makeZIPEntriesFromInstrumentals(state)); - if (state.audioVocalTrackData != null) zipEntries.concat(ChartEditorAudioHandler.makeZIPEntriesFromVocals(state)); + if (state.audioInstTrackData != null) zipEntries = zipEntries.concat(ChartEditorAudioHandler.makeZIPEntriesFromInstrumentals(state)); + if (state.audioVocalTrackData != null) zipEntries = zipEntries.concat(ChartEditorAudioHandler.makeZIPEntriesFromVocals(state)); + + var manifest:ChartManifestData = new ChartManifestData(state.currentSongId); + zipEntries.push(FileUtil.makeZIPEntry('manifest.json', manifest.serialize())); trace('Exporting ${zipEntries.length} files to ZIP...'); if (force) { - var targetPath:String = if (tmp) + if (targetPath == null) { - Path.join([ - FileUtil.getTempDir(), - 'chart-editor-exit-${DateUtil.generateTimestamp()}.${Constants.EXT_CHART}' - ]); - } - else - { - Path.join([ + targetPath = Path.join([ './backups/', - 'chart-editor-exit-${DateUtil.generateTimestamp()}.${Constants.EXT_CHART}' + 'chart-editor-${DateUtil.generateTimestamp()}.${Constants.EXT_CHART}' ]); } // We have to force write because the program will die before the save dialog is closed. trace('Force exporting to $targetPath...'); FileUtil.saveFilesAsZIPToPath(zipEntries, targetPath); - return; } + else + { + // Prompt and save. + var onSave:Array<String>->Void = function(paths:Array<String>) { + trace('Successfully exported files.'); + }; - // Prompt and save. - var onSave:Array<String>->Void = function(paths:Array<String>) { - trace('Successfully exported files.'); - }; + var onCancel:Void->Void = function() { + trace('Export cancelled.'); + }; - var onCancel:Void->Void = function() { - trace('Export cancelled.'); - }; - - FileUtil.saveMultipleFiles(zipEntries, onSave, onCancel, '${state.currentSongId}-chart.${Constants.EXT_CHART}'); + trace('Exporting to user-defined location...'); + try + { + FileUtil.saveChartAsFNFC(zipEntries, onSave, onCancel, '${state.currentSongId}.${Constants.EXT_CHART}'); + } + catch (e) {} + } } } diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 05173726f..d392c2c06 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -1011,17 +1011,17 @@ class ChartEditorState extends HaxeUIState function get_currentSongNoteStyle():String { - if (currentSongMetadata.playData.noteSkin == null) + if (currentSongMetadata.playData.noteStyle == null) { // Initialize to the default value if not set. - currentSongMetadata.playData.noteSkin = 'funkin'; + currentSongMetadata.playData.noteStyle = Constants.DEFAULT_NOTE_STYLE; } - return currentSongMetadata.playData.noteSkin; + return currentSongMetadata.playData.noteStyle; } function set_currentSongNoteStyle(value:String):String { - return currentSongMetadata.playData.noteSkin = value; + return currentSongMetadata.playData.noteStyle = value; } var currentSongStage(get, set):String; @@ -1232,10 +1232,22 @@ class ChartEditorState extends HaxeUIState var renderedSelectionSquares:FlxTypedSpriteGroup<FlxSprite> = new FlxTypedSpriteGroup<FlxSprite>(); - public function new() + /** + * The params which were passed in when the Chart Editor was initialized. + */ + var params:Null<ChartEditorParams>; + + /** + * The current file path which the chart editor is working with. + */ + public var currentWorkingFilePath:Null<String>; + + public function new(?params:ChartEditorParams) { // Load the HaxeUI XML file. super(CHART_EDITOR_LAYOUT); + + this.params = params; } override function create():Void @@ -1251,7 +1263,7 @@ class ChartEditorState extends HaxeUIState fixCamera(); // Get rid of any music from the previous state. - FlxG.sound.music.stop(); + if (FlxG.sound.music != null) FlxG.sound.music.stop(); // Play the welcome music. setupWelcomeMusic(); @@ -1277,7 +1289,33 @@ class ChartEditorState extends HaxeUIState refresh(); - ChartEditorDialogHandler.openWelcomeDialog(this, false); + if (params != null && params.fnfcTargetPath != null) + { + // Chart editor was opened from the command line. Open the FNFC file now! + if (ChartEditorImportExportHandler.loadFromFNFCPath(this, params.fnfcTargetPath)) + { + // Don't open the welcome dialog! + + #if !mac + NotificationManager.instance.addNotification( + { + title: 'Success', + body: 'Loaded chart (${params.fnfcTargetPath})', + type: NotificationType.Success, + expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + }); + #end + } + else + { + // Song failed to load, open the Welcome dialog so we aren't in a broken state. + ChartEditorDialogHandler.openWelcomeDialog(this, false); + } + } + else + { + ChartEditorDialogHandler.openWelcomeDialog(this, false); + } } function setupWelcomeMusic() @@ -1632,11 +1670,15 @@ class ChartEditorState extends HaxeUIState noteSnapQuantIndex++; if (noteSnapQuantIndex >= SNAP_QUANTS.length) noteSnapQuantIndex = 0; }); + addUIRightClickListener('playbarNoteSnap', function(_) { + noteSnapQuantIndex--; + if (noteSnapQuantIndex < 0) noteSnapQuantIndex = SNAP_QUANTS.length - 1; + }); // Add functionality to the menu items. addUIClickListener('menubarItemNewChart', _ -> ChartEditorDialogHandler.openWelcomeDialog(this, true)); - addUIClickListener('menubarItemOpenChart', _ -> ChartEditorDialogHandler.openBrowseWizard(this, true)); + addUIClickListener('menubarItemOpenChart', _ -> ChartEditorDialogHandler.openBrowseFNFC(this, true)); addUIClickListener('menubarItemSaveChartAs', _ -> ChartEditorImportExportHandler.exportAllSongData(this)); addUIClickListener('menubarItemLoadInst', _ -> ChartEditorDialogHandler.openUploadInstDialog(this, true)); addUIClickListener('menubarItemImportChart', _ -> ChartEditorDialogHandler.openImportChartDialog(this, 'legacy', true)); @@ -1776,7 +1818,7 @@ class ChartEditorState extends HaxeUIState addUIChangeListener('menubarItemVolumeVocals', function(event:UIEvent) { var volume:Float = (event?.value ?? 0) / 100.0; if (audioVocalTrackGroup != null) audioVocalTrackGroup.volume = volume; - vocalsVolumeLabel.text = 'Vocals - ${Std.int(event.value)}%'; + vocalsVolumeLabel.text = 'Voices - ${Std.int(event.value)}%'; }); } @@ -1913,6 +1955,15 @@ class ChartEditorState extends HaxeUIState { FlxG.watch.addQuick('scrollPosInPixels', scrollPositionInPixels); FlxG.watch.addQuick('playheadPosInPixels', playheadPositionInPixels); + + // Add a debug value which displays the current size of the note pool. + // The pool will grow as more notes need to be rendered at once. + // If this gets too big, something needs to be optimized somewhere! -Eric + if (renderedNotes != null && renderedNotes.members != null) FlxG.watch.addQuick("tapNotesRendered", renderedNotes.members.length); + if (renderedHoldNotes != null && renderedHoldNotes.members != null) FlxG.watch.addQuick("holdNotesRendered", renderedHoldNotes.members.length); + if (renderedEvents != null && renderedEvents.members != null) FlxG.watch.addQuick("eventsRendered", renderedEvents.members.length); + if (currentNoteSelection != null) FlxG.watch.addQuick("notesSelected", currentNoteSelection.length); + if (currentEventSelection != null) FlxG.watch.addQuick("eventsSelected", currentEventSelection.length); } /** @@ -3037,15 +3088,6 @@ class ChartEditorState extends HaxeUIState // Sort the events DESCENDING. This keeps the sustain behind the associated note. renderedEvents.sort(FlxSort.byY, FlxSort.DESCENDING); // TODO: .group.insertionSort() } - - // Add a debug value which displays the current size of the note pool. - // The pool will grow as more notes need to be rendered at once. - // If this gets too big, something needs to be optimized somewhere! -Eric - FlxG.watch.addQuick("tapNotesRendered", renderedNotes.members.length); - FlxG.watch.addQuick("holdNotesRendered", renderedHoldNotes.members.length); - FlxG.watch.addQuick("eventsRendered", renderedEvents.members.length); - FlxG.watch.addQuick("notesSelected", currentNoteSelection.length); - FlxG.watch.addQuick("eventsSelected", currentEventSelection.length); } /** @@ -3152,7 +3194,7 @@ class ChartEditorState extends HaxeUIState // CTRL + O = Open Chart if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.O) { - ChartEditorDialogHandler.openBrowseWizard(this, true); + ChartEditorDialogHandler.openBrowseFNFC(this, true); } // CTRL + SHIFT + S = Save As @@ -3168,10 +3210,13 @@ class ChartEditorState extends HaxeUIState } } + @:nullSafety(Off) function quitChartEditor():Void { autoSave(); stopWelcomeMusic(); + // TODO: PR Flixel to make onComplete nullable. + if (audioInstTrack != null) audioInstTrack.onComplete = null; FlxG.switchState(new MainMenuState()); } @@ -3691,7 +3736,7 @@ class ChartEditorState extends HaxeUIState if (inputStage != null) inputStage.value = currentSongMetadata.playData.stage; var inputNoteStyle:Null<DropDown> = toolbox.findComponent('inputNoteStyle', DropDown); - if (inputNoteStyle != null) inputNoteStyle.value = currentSongMetadata.playData.noteSkin; + if (inputNoteStyle != null) inputNoteStyle.value = currentSongMetadata.playData.noteStyle; var inputBPM:Null<NumberStepper> = toolbox.findComponent('inputBPM', NumberStepper); if (inputBPM != null) inputBPM.value = currentSongMetadata.timeChanges[0].bpm; @@ -4351,3 +4396,11 @@ enum LiveInputStyle NumberKeys; WASD; } + +typedef ChartEditorParams = +{ + /** + * If non-null, load this song immediately instead of the welcome screen. + */ + var ?fnfcTargetPath:String; +}; diff --git a/source/funkin/ui/haxeui/HaxeUIState.hx b/source/funkin/ui/haxeui/HaxeUIState.hx index 6d432b68c..78b93c431 100644 --- a/source/funkin/ui/haxeui/HaxeUIState.hx +++ b/source/funkin/ui/haxeui/HaxeUIState.hx @@ -108,6 +108,23 @@ class HaxeUIState extends MusicBeatState } } + /** + * Add an onRightClick listener to a HaxeUI menu bar item. + */ + function addUIRightClickListener(key:String, callback:MouseEvent->Void):Void + { + var target:Component = findComponent(key); + if (target == null) + { + // Gracefully handle the case where the item can't be located. + trace('WARN: Could not locate menu item: $key'); + } + else + { + target.onRightClick = callback; + } + } + function setComponentText(key:String, text:String):Void { var target:Component = findComponent(key); diff --git a/source/funkin/util/CLIUtil.hx b/source/funkin/util/CLIUtil.hx new file mode 100644 index 000000000..a085ada6d --- /dev/null +++ b/source/funkin/util/CLIUtil.hx @@ -0,0 +1,134 @@ +package funkin.util; + +/** + * Utilties for interpreting command line arguments. + */ +@:nullSafety +class CLIUtil +{ + /** + * If we don't do this, dragging and dropping a file onto the executable + * causes it to be unable to find the assets folder. + */ + public static function resetWorkingDir():Void + { + #if sys + var exeDir:String = haxe.io.Path.directory(Sys.programPath()); + trace('Changing working directory from ${Sys.getCwd()} to ${exeDir}'); + Sys.setCwd(exeDir); + #end + } + + public static function processArgs():CLIParams + { + #if sys + return interpretArgs(cleanArgs(Sys.args())); + #else + return buildDefaultParams(); + #end + } + + static function interpretArgs(args:Array<String>):CLIParams + { + var result = buildDefaultParams(); + + result.args = [for (arg in args) arg]; // Copy the array. + + while (args.length > 0) + { + var arg:Null<String> = args.shift(); + if (arg == null) continue; + + if (arg.startsWith('-')) + { + switch (arg) + { + // Flags + case '-h' | '--help': + printUsage(); + case '-v' | '--version': + trace(Constants.GENERATED_BY); + case '--chart': + if (args.length == 0) + { + trace('No chart path provided.'); + printUsage(); + } + else + { + result.chart.shouldLoadChart = true; + result.chart.chartPath = args.shift(); + } + } + } + else + { + // Make an attempt to interpret the argument. + + if (arg.endsWith(Constants.EXT_CHART)) + { + result.chart.shouldLoadChart = true; + result.chart.chartPath = arg; + } + else + { + trace('Unrecognized argument: ${arg}'); + printUsage(); + } + } + } + + return result; + } + + static function printUsage():Void + { + trace('Usage: Funkin.exe [--chart <chart>]'); + } + + static function buildDefaultParams():CLIParams + { + return { + args: [], + + chart: + { + shouldLoadChart: false, + chartPath: null + } + }; + } + + /** + * Clean up the arguments passed to the application before parsing them. + * @param args The arguments to clean up. + * @return The cleaned up arguments. + */ + static function cleanArgs(args:Array<String>):Array<String> + { + var result:Array<String> = []; + + if (args == null || args.length == 0) return result; + + return args.map(function(arg:String):String { + if (arg == null) return ''; + + return arg.trim(); + }).filter(function(arg:String):Bool { + return arg != null && arg != ''; + }); + } +} + +typedef CLIParams = +{ + var args:Array<String>; + + var chart:CLIChartParams; +} + +typedef CLIChartParams = +{ + var shouldLoadChart:Bool; + var chartPath:Null<String>; +}; diff --git a/source/funkin/util/FileUtil.hx b/source/funkin/util/FileUtil.hx index bae3126fb..72c9c43f1 100644 --- a/source/funkin/util/FileUtil.hx +++ b/source/funkin/util/FileUtil.hx @@ -14,6 +14,9 @@ import openfl.events.IOErrorEvent; */ class FileUtil { + public static final FILE_FILTER_FNFC:FileFilter = new FileFilter("Friday Night Funkin' Chart (.fnfc)", "*.fnfc"); + public static final FILE_FILTER_ZIP:FileFilter = new FileFilter("ZIP Archive (.zip)", "*.zip"); + /** * Browses for a single file, then calls `onSelect(path)` when a path chosen. * Note that on HTML5 this will immediately fail, you should call `openFile(onOpen:Resource->Void)` instead. @@ -173,10 +176,11 @@ class FileUtil * * @return Whether the file dialog was opened successfully. */ - public static function saveFile(data:Bytes, ?onSave:String->Void, ?onCancel:Void->Void, ?defaultFileName:String, ?dialogTitle:String):Bool + public static function saveFile(data:Bytes, ?typeFilter:Array<FileFilter>, ?onSave:String->Void, ?onCancel:Void->Void, ?defaultFileName:String, + ?dialogTitle:String):Bool { #if desktop - var filter:String = defaultFileName != null ? Path.extension(defaultFileName) : null; + var filter:String = convertTypeFilter(typeFilter); var fileDialog:FileDialog = new FileDialog(); if (onSave != null) fileDialog.onSelect.add(onSave); @@ -231,8 +235,7 @@ class FileUtil } catch (_) { - trace('Failed to write file (probably already exists): $filePath' + filePath); - continue; + throw 'Failed to write file (probably already exists): $filePath'; } paths.push(filePath); } @@ -269,7 +272,26 @@ class FileUtil }; // Prompt the user to save the ZIP file. - saveFile(zipBytes, onSave, onCancel, defaultPath, 'Save files as ZIP...'); + saveFile(zipBytes, [FILE_FILTER_ZIP], onSave, onCancel, defaultPath, 'Save files as ZIP...'); + + return true; + } + + /** + * Takes an array of file entries and prompts the user to save them as a FNFC file. + */ + public static function saveChartAsFNFC(resources:Array<Entry>, ?onSave:Array<String>->Void, ?onCancel:Void->Void, ?defaultPath:String, + force:Bool = false):Bool + { + // Create a ZIP file. + var zipBytes:Bytes = createZIPFromEntries(resources); + + var onSave:String->Void = function(path:String) { + onSave([path]); + }; + + // Prompt the user to save the ZIP file. + saveFile(zipBytes, [FILE_FILTER_FNFC], onSave, onCancel, defaultPath, 'Save chart as FNFC...'); return true; } @@ -322,7 +344,8 @@ class FileUtil public static function readBytesFromPath(path:String):Bytes { #if sys - return Bytes.ofString(sys.io.File.getContent(path)); + if (!sys.FileSystem.exists(path)) return null; + return sys.io.File.getBytes(path); #else return null; #end @@ -559,6 +582,36 @@ class FileUtil return o.getBytes(); } + public static function readZIPFromBytes(input:Bytes):Array<Entry> + { + trace('TEST: ' + input.length); + trace(input.sub(0, 30).toHex()); + + var bytesInput = new haxe.io.BytesInput(input); + var zippedEntries = haxe.zip.Reader.readZip(bytesInput); + + var results:Array<Entry> = []; + for (entry in zippedEntries) + { + if (entry.compressed) + { + entry.data = haxe.zip.Reader.unzip(entry); + } + results.push(entry); + } + return results; + } + + public static function mapZIPEntriesByName(input:Array<Entry>):Map<String, Entry> + { + var results:Map<String, Entry> = []; + for (entry in input) + { + results.set(entry.fileName, entry); + } + return results; + } + /** * Create a ZIP file entry from a file name and its string contents. * diff --git a/source/funkin/util/SerializerUtil.hx b/source/funkin/util/SerializerUtil.hx index 0af0fc9ea..e73dde15f 100644 --- a/source/funkin/util/SerializerUtil.hx +++ b/source/funkin/util/SerializerUtil.hx @@ -21,6 +21,8 @@ class SerializerUtil /** * Convert a Haxe object to a JSON string. + * NOTE: Use `json2object.JsonWriter<T>` WHEREVER POSSIBLE. Do not use this one unless you ABSOLUTELY HAVE TO it's SLOW! + * And don't even THINK about using `haxe.Json.stringify` without the replacer! */ public static function toJSON(input:Dynamic, pretty:Bool = true):String { diff --git a/source/funkin/util/VersionUtil.hx b/source/funkin/util/VersionUtil.hx index 1dc00473a..d6f95c7c5 100644 --- a/source/funkin/util/VersionUtil.hx +++ b/source/funkin/util/VersionUtil.hx @@ -61,4 +61,22 @@ class VersionUtil var version:thx.semver.Version = versionStr; // Implicit, not explicit, cast. return version; } + + public static function parseVersion(input:Dynamic):Null<thx.semver.Version> + { + if (input == null) return null; + + if (Std.isOfType(input, String)) + { + var inputStr:String = input; + var version:thx.semver.Version = inputStr; + return version; + } + else + { + var semVer:thx.semver.Version.SemVer = input; + var version:thx.semver.Version = semVer; + return version; + } + } } diff --git a/tests/unit/source/funkin/data/notestyle/NoteStyleRegistryTest.hx b/tests/unit/source/funkin/data/notestyle/NoteStyleRegistryTest.hx index 447ee7831..0c8cd2d71 100644 --- a/tests/unit/source/funkin/data/notestyle/NoteStyleRegistryTest.hx +++ b/tests/unit/source/funkin/data/notestyle/NoteStyleRegistryTest.hx @@ -95,6 +95,6 @@ class NoteStyleRegistryTest extends FunkinTest // Verify the underlying call. - nsrMock.fetchEntry(NoteStyleRegistry.DEFAULT_NOTE_STYLE_ID).verify(times(1)); + nsrMock.fetchEntry(Constants.DEFAULT_NOTE_STYLE).verify(times(1)); } } From b2dd58b9049a7ae9beec475d2fd6944baf3d09a7 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Fri, 27 Oct 2023 01:42:05 -0400 Subject: [PATCH 04/21] Resolve several bugs related to event note placement. --- Project.xml | 3 ++ assets | 2 +- source/funkin/MusicBeatState.hx | 30 ++++++++++++--- source/funkin/data/event/SongEventData.hx | 9 ++++- source/funkin/data/song/SongData.hx | 14 ++++++- source/funkin/import.hx | 1 + .../debug/charting/ChartEditorEventSprite.hx | 24 +++++++----- .../ui/debug/charting/ChartEditorState.hx | 37 ++++++++----------- .../charting/ChartEditorToolboxHandler.hx | 26 ++++++++++--- source/funkin/util/tools/DynamicTools.hx | 14 +++++++ 10 files changed, 112 insertions(+), 48 deletions(-) create mode 100644 source/funkin/util/tools/DynamicTools.hx diff --git a/Project.xml b/Project.xml index 69400d8b1..a1772a9ef 100644 --- a/Project.xml +++ b/Project.xml @@ -165,7 +165,10 @@ <icon path="art/iconOG.png" /> <haxedef name="CAN_OPEN_LINKS" unless="switch" /> <haxedef name="CAN_CHEAT" if="switch debug" /> + <!-- I don't --> <haxedef name="haxeui_no_mouse_reset" /> + <!-- Clicking outside a dialog should deselect the current focused component. --> + <haxedef name="haxeui_focus_out_on_click" /> <!-- Skip the Intro --> <section if="debug"> <!-- Starts the game at the specified week, at the first song --> diff --git a/assets b/assets index ef79a6cf1..6b6f2462a 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ef79a6cf1ae3dcbd86a5b798f8117a6c692c0156 +Subproject commit 6b6f2462afb099a7301a782ae521a0175fb7c71b diff --git a/source/funkin/MusicBeatState.hx b/source/funkin/MusicBeatState.hx index 9a986a8b5..b045fdc24 100644 --- a/source/funkin/MusicBeatState.hx +++ b/source/funkin/MusicBeatState.hx @@ -56,27 +56,45 @@ class MusicBeatState extends FlxTransitionableState implements IEventHandler Conductor.stepHit.remove(this.stepHit); } - override function update(elapsed:Float) + function handleControls():Void { - super.update(elapsed); + var isHaxeUIFocused:Bool = haxe.ui.focus.FocusManager.instance?.focus != null; - // Rebindable volume keys. - if (controls.VOLUME_MUTE) FlxG.sound.toggleMuted(); - else if (controls.VOLUME_UP) FlxG.sound.changeVolume(0.1); - else if (controls.VOLUME_DOWN) FlxG.sound.changeVolume(-0.1); + if (!isHaxeUIFocused) + { + // Rebindable volume keys. + if (controls.VOLUME_MUTE) FlxG.sound.toggleMuted(); + else if (controls.VOLUME_UP) FlxG.sound.changeVolume(0.1); + else if (controls.VOLUME_DOWN) FlxG.sound.changeVolume(-0.1); + } + } + function handleFunctionControls():Void + { // Emergency exit button. if (FlxG.keys.justPressed.F4) FlxG.switchState(new MainMenuState()); // This can now be used in EVERY STATE YAY! if (FlxG.keys.justPressed.F5) debug_refreshModules(); + } + function handleQuickWatch():Void + { // Display Conductor info in the watch window. FlxG.watch.addQuick("songPosition", Conductor.songPosition); FlxG.watch.addQuick("bpm", Conductor.bpm); FlxG.watch.addQuick("currentMeasureTime", Conductor.currentBeatTime); FlxG.watch.addQuick("currentBeatTime", Conductor.currentBeatTime); FlxG.watch.addQuick("currentStepTime", Conductor.currentStepTime); + } + + override function update(elapsed:Float) + { + super.update(elapsed); + + handleControls(); + handleFunctionControls(); + handleQuickWatch(); dispatchEvent(new UpdateScriptEvent(elapsed)); } diff --git a/source/funkin/data/event/SongEventData.hx b/source/funkin/data/event/SongEventData.hx index 831a53fbd..7a167b031 100644 --- a/source/funkin/data/event/SongEventData.hx +++ b/source/funkin/data/event/SongEventData.hx @@ -208,25 +208,32 @@ typedef SongEventSchemaField = type:SongEventFieldType, /** - * Used for ENUM values. + * Used only for ENUM values. * The key is the display name and the value is the actual value. */ ?keys:Map<String, Dynamic>, + /** * Used for INTEGER and FLOAT values. * The minimum value that can be entered. + * @default No minimum */ ?min:Float, + /** * Used for INTEGER and FLOAT values. * The maximum value that can be entered. + * @default No maximum */ ?max:Float, + /** * Used for INTEGER and FLOAT values. * The step value that will be used when incrementing/decrementing the value. + * @default `0.1` */ ?step:Float, + /** * An optional default value for the field. */ diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 88993e519..eac4a4cb5 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -516,12 +516,22 @@ class SongEventData public inline function getInt(key:String):Null<Int> { - return value == null ? null : cast Reflect.field(value, key); + if (value == null) return null; + var result = Reflect.field(value, key); + if (result == null) return null; + if (Std.isOfType(result, Int)) return result; + if (Std.isOfType(result, String)) return Std.parseInt(cast result); + return cast result; } public inline function getFloat(key:String):Null<Float> { - return value == null ? null : cast Reflect.field(value, key); + if (value == null) return null; + var result = Reflect.field(value, key); + if (result == null) return null; + if (Std.isOfType(result, Float)) return result; + if (Std.isOfType(result, String)) return Std.parseFloat(cast result); + return cast result; } public inline function getString(key:String):String diff --git a/source/funkin/import.hx b/source/funkin/import.hx index 1c3a0fdb4..62241c4f4 100644 --- a/source/funkin/import.hx +++ b/source/funkin/import.hx @@ -12,6 +12,7 @@ using Lambda; using StringTools; using funkin.util.tools.ArraySortTools; using funkin.util.tools.ArrayTools; +using funkin.util.tools.DynamicTools; using funkin.util.tools.Int64Tools; using funkin.util.tools.IteratorTools; using funkin.util.tools.MapTools; diff --git a/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx b/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx index 021abde0f..d5d81ae29 100644 --- a/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx +++ b/source/funkin/ui/debug/charting/ChartEditorEventSprite.hx @@ -123,21 +123,25 @@ class ChartEditorEventSprite extends FlxSprite function set_eventData(value:Null<SongEventData>):Null<SongEventData> { - this.eventData = value; - - if (this.eventData == null) + if (value == null) { + this.eventData = null; // Disown parent. MAKE SURE TO REVIVE BEFORE REUSING this.kill(); + this.visible = false; + return null; + } + else + { + this.visible = true; + // Only play the animation if the event type has changed. + // if (this.eventData == null || this.eventData.event != value.event) + playAnimation(value.event); + this.eventData = value; + // Update the position to match the note data. + updateEventPosition(); return this.eventData; } - - this.visible = true; - playAnimation(this.eventData.event); - // Update the position to match the note data. - updateEventPosition(); - - return this.eventData; } public function updateEventPosition(?origin:FlxObject) diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 05173726f..c421c08f2 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -71,6 +71,7 @@ import haxe.ui.core.Component; import haxe.ui.core.Screen; import haxe.ui.events.DragEvent; import haxe.ui.events.UIEvent; +import haxe.ui.focus.FocusManager; import haxe.ui.notifications.NotificationManager; import haxe.ui.notifications.NotificationType; import openfl.Assets; @@ -492,22 +493,14 @@ class ChartEditorState extends HaxeUIState var hitsoundsEnabledOpponent:Bool = true; /** - * Whether the user's mouse cursor is hovering over a SOLID component of the HaxeUI. - * If so, ignore mouse events underneath. + * Whether the user is focused on an input in the Haxe UI, and inputs are being fed into it. + * If the user clicks off the input, focus will leave. */ - var isCursorOverHaxeUI(get, never):Bool; + var isHaxeUIFocused(get, never):Bool; - function get_isCursorOverHaxeUI():Bool + function get_isHaxeUIFocused():Bool { - return Screen.instance.hasSolidComponentUnderPoint(FlxG.mouse.screenX, FlxG.mouse.screenY); - } - - var isCursorOverHaxeUIButton(get, never):Bool; - - function get_isCursorOverHaxeUIButton():Bool - { - return Screen.instance.hasSolidComponentUnderPoint(FlxG.mouse.screenX, FlxG.mouse.screenY, haxe.ui.components.Button) - || Screen.instance.hasSolidComponentUnderPoint(FlxG.mouse.screenX, FlxG.mouse.screenY, haxe.ui.components.Link); + return FocusManager.instance.focus != null; } /** @@ -1905,11 +1898,11 @@ class ChartEditorState extends HaxeUIState handleHelpKeybinds(); #if debug - handleQuickWatch(); + handleQuickWatches(); #end } - function handleQuickWatch():Void + function handleQuickWatches():Void { FlxG.watch.addQuick('scrollPosInPixels', scrollPositionInPixels); FlxG.watch.addQuick('playheadPosInPixels', playheadPositionInPixels); @@ -1957,8 +1950,8 @@ class ChartEditorState extends HaxeUIState **/ function handleScrollKeybinds():Void { - // Don't scroll when the cursor is over the UI, unless a playbar button (the << >> ones) is pressed. - if (isCursorOverHaxeUI && playbarButtonPressed == null) return; + // Don't scroll when the user is interacting with the UI, unless a playbar button (the << >> ones) is pressed. + if (isHaxeUIFocused && playbarButtonPressed == null) return; var scrollAmount:Float = 0; // Amount to scroll the grid. var playheadAmount:Float = 0; // Amount to scroll the playhead relative to the grid. @@ -2157,7 +2150,7 @@ class ChartEditorState extends HaxeUIState if (FlxG.mouse.justReleased) FlxG.sound.play(Paths.sound("chartingSounds/ClickUp")); // Note: If a menu is open in HaxeUI, don't handle cursor behavior. - var shouldHandleCursor:Bool = !isCursorOverHaxeUI || (selectionBoxStartPos != null); + var shouldHandleCursor:Bool = !isHaxeUIFocused || (selectionBoxStartPos != null); var eventColumn:Int = (STRUMLINE_SIZE * 2 + 1) - 1; if (shouldHandleCursor) @@ -2612,14 +2605,14 @@ class ChartEditorState extends HaxeUIState { // Create an event and place it in the chart. // TODO: Figure out configuring event data. - var newEventData:SongEventData = new SongEventData(cursorSnappedMs, selectedEventKind, selectedEventData); + var newEventData:SongEventData = new SongEventData(cursorSnappedMs, selectedEventKind, selectedEventData.clone()); performCommand(new AddEventsCommand([newEventData], FlxG.keys.pressed.CONTROL)); } else { // Create a note and place it in the chart. - var newNoteData:SongNoteData = new SongNoteData(cursorSnappedMs, cursorColumn, 0, selectedNoteKind); + var newNoteData:SongNoteData = new SongNoteData(cursorSnappedMs, cursorColumn, 0, selectedNoteKind.clone()); performCommand(new AddNotesCommand([newNoteData], FlxG.keys.pressed.CONTROL)); @@ -3392,7 +3385,7 @@ class ChartEditorState extends HaxeUIState */ function handleTestKeybinds():Void { - if (!isHaxeUIDialogOpen && !isCursorOverHaxeUI && FlxG.keys.justPressed.ENTER) + if (!isHaxeUIDialogOpen && !isHaxeUIFocused && FlxG.keys.justPressed.ENTER) { var minimal = FlxG.keys.pressed.SHIFT; ChartEditorToolboxHandler.hideAllToolboxes(this); @@ -3889,7 +3882,7 @@ class ChartEditorState extends HaxeUIState } } - if (FlxG.keys.justPressed.SPACE && !isHaxeUIDialogOpen) + if (FlxG.keys.justPressed.SPACE && !(isHaxeUIDialogOpen || isHaxeUIFocused)) { toggleAudioPlayback(); } diff --git a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx index 7cee1edde..fb0981bae 100644 --- a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx @@ -346,6 +346,8 @@ class ChartEditorToolboxHandler trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event type changed: $eventType'); + state.selectedEventKind = eventType; + var schema:SongEventSchema = SongEventParser.getEventSchema(eventType); if (schema == null) @@ -356,6 +358,7 @@ class ChartEditorToolboxHandler buildEventDataFormFromSchema(state, toolboxEventsDataGrid, schema); } + toolboxEventsEventKind.value = state.selectedEventKind; return toolbox; } @@ -379,6 +382,7 @@ class ChartEditorToolboxHandler // Add a label. var label:Label = new Label(); label.text = field.title; + label.verticalAlign = "center"; target.addComponent(label); var input:Component; @@ -396,8 +400,8 @@ class ChartEditorToolboxHandler var numberStepper:NumberStepper = new NumberStepper(); numberStepper.id = field.name; numberStepper.step = field.step ?? 0.1; - numberStepper.min = field.min ?? 0.0; - numberStepper.max = field.max ?? 1.0; + if (field.min != null) numberStepper.min = field.min; + if (field.max != null) numberStepper.max = field.max; if (field.defaultValue != null) numberStepper.value = field.defaultValue; input = numberStepper; case BOOL: @@ -416,7 +420,7 @@ class ChartEditorToolboxHandler for (optionName in field.keys.keys()) { - var optionValue:Null<String> = field.keys.get(optionName); + var optionValue:Null<Dynamic> = field.keys.get(optionName); trace('$optionName : $optionValue'); dropDown.dataSource.add({value: optionValue, text: optionName}); } @@ -438,11 +442,21 @@ class ChartEditorToolboxHandler target.addComponent(input); input.onChange = function(event:UIEvent) { - trace('ChartEditorToolboxHandler.buildEventDataFormFromSchema() - ${event.target.id} = ${event.target.value}'); + var value = event.target.value; + if (field.type == ENUM) + { + value = event.target.value.value; + } + trace('ChartEditorToolboxHandler.buildEventDataFormFromSchema() - ${event.target.id} = ${value}'); - if (event.target.value == null) state.selectedEventData.remove(event.target.id); + if (value == null) + { + state.selectedEventData.remove(event.target.id); + } else - state.selectedEventData.set(event.target.id, event.target.value); + { + state.selectedEventData.set(event.target.id, value); + } } } } diff --git a/source/funkin/util/tools/DynamicTools.hx b/source/funkin/util/tools/DynamicTools.hx new file mode 100644 index 000000000..47501ea22 --- /dev/null +++ b/source/funkin/util/tools/DynamicTools.hx @@ -0,0 +1,14 @@ +package funkin.util.tools; + +class DynamicTools +{ + /** + * Creates a full clone of the input `Dynamic`. Only guaranteed to work on anonymous structures. + * @param input The `Dynamic` to clone. + * @return A clone of the input `Dynamic`. + */ + public static function clone(input:Dynamic):Dynamic + { + return Reflect.copy(input); + } +} From 73107dbc07bcdd6f6de64b6e9b2de69694ee894b Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Tue, 31 Oct 2023 14:43:01 -0400 Subject: [PATCH 05/21] Update HaxeUI cursor handling, and remove Funkin components --- assets | 2 +- hmm.json | 4 +- source/Main.hx | 1 + source/funkin/Conductor.hx | 4 ++ source/funkin/data/song/SongDataUtils.hx | 13 +++++ source/funkin/input/Cursor.hx | 47 ++++++++++++++----- .../charting/ChartEditorDialogHandler.hx | 12 ++--- .../charting/ChartEditorToolboxHandler.hx | 11 ++--- .../ui/haxeui/components/FunkinButton.hx | 30 ------------ .../ui/haxeui/components/FunkinClickLabel.hx | 30 ------------ .../ui/haxeui/components/FunkinDropDown.hx | 30 ------------ .../components/FunkinHorizontalSlider.hx | 30 ------------ .../funkin/ui/haxeui/components/FunkinLink.hx | 30 ------------ .../ui/haxeui/components/FunkinMenuBar.hx | 32 ------------- .../haxeui/components/FunkinMenuCheckBox.hx | 30 ------------ .../ui/haxeui/components/FunkinMenuItem.hx | 30 ------------ .../haxeui/components/FunkinMenuOptionBox.hx | 30 ------------ .../haxeui/components/FunkinNumberStepper.hx | 30 ------------ .../ui/haxeui/components/FunkinTextField.hx | 30 ------------ 19 files changed, 66 insertions(+), 360 deletions(-) delete mode 100644 source/funkin/ui/haxeui/components/FunkinButton.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinClickLabel.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinDropDown.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinHorizontalSlider.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinLink.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinMenuBar.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinMenuCheckBox.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinMenuItem.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinMenuOptionBox.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinNumberStepper.hx delete mode 100644 source/funkin/ui/haxeui/components/FunkinTextField.hx diff --git a/assets b/assets index 6b6f2462a..3f8299aba 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6b6f2462afb099a7301a782ae521a0175fb7c71b +Subproject commit 3f8299aba4e308a6c86ce8f499b697de04909ad2 diff --git a/hmm.json b/hmm.json index 070d96cd0..69e086fd5 100644 --- a/hmm.json +++ b/hmm.json @@ -49,14 +49,14 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "e92d5cfac847943fac84696b103670d55c2c774f", + "ref": "815e94dd5aa6cf09c5ddcef1666a54449ffde8dc", "url": "https://github.com/haxeui/haxeui-core" }, { "name": "haxeui-flixel", "type": "git", "dir": null, - "ref": "be0b18553189a55fd42821026618a18615b070e3", + "ref": "bc706d67efc093cd3b1623d0e9d599b326bbd330", "url": "https://github.com/haxeui/haxeui-flixel" }, { diff --git a/source/Main.hx b/source/Main.hx index dffe666b7..a9879c1a5 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -110,5 +110,6 @@ class Main extends Sprite Toolkit.init(); Toolkit.theme = 'dark'; // don't be cringe Toolkit.autoScale = false; + funkin.input.Cursor.registerHaxeUICursors(); } } diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index b79ae0fc4..10bf505f0 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -5,6 +5,7 @@ import flixel.util.FlxSignal; import flixel.math.FlxMath; import funkin.play.song.Song.SongDifficulty; import funkin.data.song.SongData.SongTimeChange; +import funkin.data.song.SongDataUtils; /** * A core class which handles musical timing throughout the game, @@ -257,6 +258,9 @@ class Conductor { timeChanges = []; + // Sort in place just in case it's out of order. + SongDataUtils.sortTimeChanges(songTimeChanges); + for (currentTimeChange in songTimeChanges) { // TODO: Maybe handle this different? diff --git a/source/funkin/data/song/SongDataUtils.hx b/source/funkin/data/song/SongDataUtils.hx index 3ff3943c6..256c9e8f0 100644 --- a/source/funkin/data/song/SongDataUtils.hx +++ b/source/funkin/data/song/SongDataUtils.hx @@ -3,6 +3,7 @@ package funkin.data.song; import flixel.util.FlxSort; import funkin.data.song.SongData.SongEventData; import funkin.data.song.SongData.SongNoteData; +import funkin.data.song.SongData.SongTimeChange; import funkin.util.ClipboardUtil; import funkin.util.SerializerUtil; @@ -157,6 +158,18 @@ class SongDataUtils return events; } + /** + * Sort an array of notes by strum time. + */ + public static function sortTimeChanges(timeChanges:Array<SongTimeChange>, desc:Bool = false):Array<SongTimeChange> + { + // TODO: Modifies the array in place. Is this okay? + timeChanges.sort(function(a:SongTimeChange, b:SongTimeChange):Int { + return FlxSort.byValues(desc ? FlxSort.DESCENDING : FlxSort.ASCENDING, a.timeStamp, b.timeStamp); + }); + return timeChanges; + } + /** * Serialize note and event data and write it to the clipboard. */ diff --git a/source/funkin/input/Cursor.hx b/source/funkin/input/Cursor.hx index edd9e70f3..c609c9e30 100644 --- a/source/funkin/input/Cursor.hx +++ b/source/funkin/input/Cursor.hx @@ -1,5 +1,6 @@ package funkin.input; +import haxe.ui.backend.flixel.CursorHelper; import openfl.utils.Assets; import lime.app.Future; import openfl.display.BitmapData; @@ -33,7 +34,7 @@ class Cursor Cursor.cursorMode = null; } - static final CURSOR_DEFAULT_PARAMS:CursorParams = + public static final CURSOR_DEFAULT_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-default.png", scale: 1.0, @@ -42,7 +43,7 @@ class Cursor }; static var assetCursorDefault:Null<BitmapData> = null; - static final CURSOR_CROSS_PARAMS:CursorParams = + public static final CURSOR_CROSS_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-cross.png", scale: 1.0, @@ -51,7 +52,7 @@ class Cursor }; static var assetCursorCross:Null<BitmapData> = null; - static final CURSOR_ERASER_PARAMS:CursorParams = + public static final CURSOR_ERASER_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-eraser.png", scale: 1.0, @@ -60,7 +61,7 @@ class Cursor }; static var assetCursorEraser:Null<BitmapData> = null; - static final CURSOR_GRABBING_PARAMS:CursorParams = + public static final CURSOR_GRABBING_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-grabbing.png", scale: 1.0, @@ -69,7 +70,7 @@ class Cursor }; static var assetCursorGrabbing:Null<BitmapData> = null; - static final CURSOR_HOURGLASS_PARAMS:CursorParams = + public static final CURSOR_HOURGLASS_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-hourglass.png", scale: 1.0, @@ -78,7 +79,7 @@ class Cursor }; static var assetCursorHourglass:Null<BitmapData> = null; - static final CURSOR_POINTER_PARAMS:CursorParams = + public static final CURSOR_POINTER_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-pointer.png", scale: 1.0, @@ -87,7 +88,7 @@ class Cursor }; static var assetCursorPointer:Null<BitmapData> = null; - static final CURSOR_TEXT_PARAMS:CursorParams = + public static final CURSOR_TEXT_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-text.png", scale: 0.2, @@ -96,7 +97,7 @@ class Cursor }; static var assetCursorText:Null<BitmapData> = null; - static final CURSOR_TEXT_VERTICAL_PARAMS:CursorParams = + public static final CURSOR_TEXT_VERTICAL_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-text-vertical.png", scale: 0.2, @@ -105,7 +106,7 @@ class Cursor }; static var assetCursorTextVertical:Null<BitmapData> = null; - static final CURSOR_ZOOM_IN_PARAMS:CursorParams = + public static final CURSOR_ZOOM_IN_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-zoom-in.png", scale: 1.0, @@ -114,7 +115,7 @@ class Cursor }; static var assetCursorZoomIn:Null<BitmapData> = null; - static final CURSOR_ZOOM_OUT_PARAMS:CursorParams = + public static final CURSOR_ZOOM_OUT_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-zoom-out.png", scale: 1.0, @@ -123,7 +124,7 @@ class Cursor }; static var assetCursorZoomOut:Null<BitmapData> = null; - static final CURSOR_CROSSHAIR_PARAMS:CursorParams = + public static final CURSOR_CROSSHAIR_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-crosshair.png", scale: 1.0, @@ -132,7 +133,7 @@ class Cursor }; static var assetCursorCrosshair:Null<BitmapData> = null; - static final CURSOR_CELL_PARAMS:CursorParams = + public static final CURSOR_CELL_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-cell.png", scale: 1.0, @@ -500,6 +501,28 @@ class Cursor { trace("Failed to load cursor graphic for cursor mode " + cursorMode + ": " + error); } + + public static function registerHaxeUICursors():Void + { + CursorHelper.useCustomCursors = true; + registerHaxeUICursor('default', CURSOR_DEFAULT_PARAMS); + registerHaxeUICursor('cross', CURSOR_CROSS_PARAMS); + registerHaxeUICursor('eraser', CURSOR_ERASER_PARAMS); + registerHaxeUICursor('grabbing', CURSOR_GRABBING_PARAMS); + registerHaxeUICursor('hourglass', CURSOR_HOURGLASS_PARAMS); + registerHaxeUICursor('pointer', CURSOR_POINTER_PARAMS); + registerHaxeUICursor('text', CURSOR_TEXT_PARAMS); + registerHaxeUICursor('text-vertical', CURSOR_TEXT_VERTICAL_PARAMS); + registerHaxeUICursor('zoom-in', CURSOR_ZOOM_IN_PARAMS); + registerHaxeUICursor('zoom-out', CURSOR_ZOOM_OUT_PARAMS); + registerHaxeUICursor('crosshair', CURSOR_CROSSHAIR_PARAMS); + registerHaxeUICursor('cell', CURSOR_CELL_PARAMS); + } + + public static function registerHaxeUICursor(id:String, params:CursorParams):Void + { + CursorHelper.registerCursor(id, params.graphic, params.scale, params.offsetX, params.offsetY); + } } // https://developer.mozilla.org/en-US/docs/Web/CSS/cursor diff --git a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx index c26f6c805..a98aa5e86 100644 --- a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx @@ -1,6 +1,5 @@ package funkin.ui.debug.charting; -import funkin.ui.haxeui.components.FunkinDropDown; import flixel.util.FlxTimer; import funkin.data.song.importer.FNFLegacyData; import funkin.data.song.importer.FNFLegacyImporter; @@ -15,7 +14,6 @@ import funkin.play.character.CharacterData; import funkin.play.character.CharacterData.CharacterDataParser; import funkin.play.song.Song; import funkin.play.stage.StageData; -import funkin.ui.haxeui.components.FunkinLink; import funkin.util.Constants; import funkin.util.FileUtil; import funkin.util.SerializerUtil; @@ -151,7 +149,7 @@ class ChartEditorDialogHandler continue; } - var linkTemplateSong:Link = new FunkinLink(); + var linkTemplateSong:Link = new Link(); linkTemplateSong.text = songName; linkTemplateSong.onClick = function(_event) { dialog.hideDialog(DialogButton.CANCEL); @@ -618,7 +616,7 @@ class ChartEditorDialogHandler var startingValueStage = ChartEditorDropdowns.populateDropdownWithStages(inputStage, newSongMetadata.playData.stage); inputStage.value = startingValueStage; - var inputNoteStyle:Null<FunkinDropDown> = dialog.findComponent('inputNoteStyle', FunkinDropDown); + var inputNoteStyle:Null<DropDown> = dialog.findComponent('inputNoteStyle', DropDown); if (inputNoteStyle == null) throw 'Could not locate inputNoteStyle DropDown in Song Metadata dialog'; inputNoteStyle.onChange = function(event:UIEvent) { if (event.data.id == null) return; @@ -627,7 +625,7 @@ class ChartEditorDialogHandler var startingValueNoteStyle = ChartEditorDropdowns.populateDropdownWithNoteStyles(inputNoteStyle, newSongMetadata.playData.noteSkin); inputNoteStyle.value = startingValueNoteStyle; - var inputCharacterPlayer:Null<FunkinDropDown> = dialog.findComponent('inputCharacterPlayer', FunkinDropDown); + var inputCharacterPlayer:Null<DropDown> = dialog.findComponent('inputCharacterPlayer', DropDown); if (inputCharacterPlayer == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputCharacterPlayer component.'; inputCharacterPlayer.onChange = function(event:UIEvent) { if (event.data?.id == null) return; @@ -637,7 +635,7 @@ class ChartEditorDialogHandler newSongMetadata.playData.characters.player); inputCharacterPlayer.value = startingValuePlayer; - var inputCharacterOpponent:Null<FunkinDropDown> = dialog.findComponent('inputCharacterOpponent', FunkinDropDown); + var inputCharacterOpponent:Null<DropDown> = dialog.findComponent('inputCharacterOpponent', DropDown); if (inputCharacterOpponent == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputCharacterOpponent component.'; inputCharacterOpponent.onChange = function(event:UIEvent) { if (event.data?.id == null) return; @@ -647,7 +645,7 @@ class ChartEditorDialogHandler newSongMetadata.playData.characters.opponent); inputCharacterOpponent.value = startingValueOpponent; - var inputCharacterGirlfriend:Null<FunkinDropDown> = dialog.findComponent('inputCharacterGirlfriend', FunkinDropDown); + var inputCharacterGirlfriend:Null<DropDown> = dialog.findComponent('inputCharacterGirlfriend', DropDown); if (inputCharacterGirlfriend == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputCharacterGirlfriend component.'; inputCharacterGirlfriend.onChange = function(event:UIEvent) { if (event.data?.id == null) return; diff --git a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx index fb0981bae..bd4f9ed06 100644 --- a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx @@ -1,6 +1,5 @@ package funkin.ui.debug.charting; -import funkin.ui.haxeui.components.FunkinDropDown; import funkin.play.stage.StageData.StageDataParser; import funkin.play.stage.StageData; import funkin.play.character.CharacterData; @@ -596,7 +595,7 @@ class ChartEditorToolboxHandler }; inputSongArtist.value = state.currentSongMetadata.artist; - var inputStage:Null<FunkinDropDown> = toolbox.findComponent('inputStage', FunkinDropDown); + var inputStage:Null<DropDown> = toolbox.findComponent('inputStage', DropDown); if (inputStage == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputStage component.'; inputStage.onChange = function(event:UIEvent) { var valid:Bool = event.data != null && event.data.id != null; @@ -609,7 +608,7 @@ class ChartEditorToolboxHandler var startingValueStage = ChartEditorDropdowns.populateDropdownWithStages(inputStage, state.currentSongMetadata.playData.stage); inputStage.value = startingValueStage; - var inputNoteStyle:Null<FunkinDropDown> = toolbox.findComponent('inputNoteStyle', FunkinDropDown); + var inputNoteStyle:Null<DropDown> = toolbox.findComponent('inputNoteStyle', DropDown); if (inputNoteStyle == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputNoteStyle component.'; inputNoteStyle.onChange = function(event:UIEvent) { if (event.data?.id == null) return; @@ -619,7 +618,7 @@ class ChartEditorToolboxHandler // By using this flag, we prevent the dropdown value from changing while it is being populated. - var inputCharacterPlayer:Null<FunkinDropDown> = toolbox.findComponent('inputCharacterPlayer', FunkinDropDown); + var inputCharacterPlayer:Null<DropDown> = toolbox.findComponent('inputCharacterPlayer', DropDown); if (inputCharacterPlayer == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputCharacterPlayer component.'; inputCharacterPlayer.onChange = function(event:UIEvent) { if (event.data?.id == null) return; @@ -629,7 +628,7 @@ class ChartEditorToolboxHandler state.currentSongMetadata.playData.characters.player); inputCharacterPlayer.value = startingValuePlayer; - var inputCharacterOpponent:Null<FunkinDropDown> = toolbox.findComponent('inputCharacterOpponent', FunkinDropDown); + var inputCharacterOpponent:Null<DropDown> = toolbox.findComponent('inputCharacterOpponent', DropDown); if (inputCharacterOpponent == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputCharacterOpponent component.'; inputCharacterOpponent.onChange = function(event:UIEvent) { if (event.data?.id == null) return; @@ -639,7 +638,7 @@ class ChartEditorToolboxHandler state.currentSongMetadata.playData.characters.opponent); inputCharacterOpponent.value = startingValueOpponent; - var inputCharacterGirlfriend:Null<FunkinDropDown> = toolbox.findComponent('inputCharacterGirlfriend', FunkinDropDown); + var inputCharacterGirlfriend:Null<DropDown> = toolbox.findComponent('inputCharacterGirlfriend', DropDown); if (inputCharacterGirlfriend == null) throw 'ChartEditorToolboxHandler.buildToolboxMetadataLayout() - Could not find inputCharacterGirlfriend component.'; inputCharacterGirlfriend.onChange = function(event:UIEvent) { if (event.data?.id == null) return; diff --git a/source/funkin/ui/haxeui/components/FunkinButton.hx b/source/funkin/ui/haxeui/components/FunkinButton.hx deleted file mode 100644 index 45987b9ec..000000000 --- a/source/funkin/ui/haxeui/components/FunkinButton.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; -import haxe.ui.components.Button; - -/** - * A HaxeUI button which: - * - Changes the current cursor when hovered over. - */ -class FunkinButton extends Button -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinClickLabel.hx b/source/funkin/ui/haxeui/components/FunkinClickLabel.hx deleted file mode 100644 index 77c9dbc0f..000000000 --- a/source/funkin/ui/haxeui/components/FunkinClickLabel.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import haxe.ui.components.Label; -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; - -/** - * A HaxeUI label which: - * - Changes the current cursor when hovered over (assume an onClick handler will be added!). - */ -class FunkinClickLabel extends Label -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinDropDown.hx b/source/funkin/ui/haxeui/components/FunkinDropDown.hx deleted file mode 100644 index ad396856c..000000000 --- a/source/funkin/ui/haxeui/components/FunkinDropDown.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import haxe.ui.components.DropDown; -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; - -/** - * A HaxeUI dropdown which: - * - Changes the current cursor when hovered over. - */ -class FunkinDropDown extends DropDown -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinHorizontalSlider.hx b/source/funkin/ui/haxeui/components/FunkinHorizontalSlider.hx deleted file mode 100644 index baf42aada..000000000 --- a/source/funkin/ui/haxeui/components/FunkinHorizontalSlider.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import haxe.ui.components.HorizontalSlider; -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; - -/** - * A HaxeUI horizontal slider which: - * - Changes the current cursor when hovered over. - */ -class FunkinHorizontalSlider extends HorizontalSlider -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinLink.hx b/source/funkin/ui/haxeui/components/FunkinLink.hx deleted file mode 100644 index 74eb6e7c4..000000000 --- a/source/funkin/ui/haxeui/components/FunkinLink.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; -import haxe.ui.components.Link; - -/** - * A HaxeUI link which: - * - Changes the current cursor when hovered over. - */ -class FunkinLink extends Link -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinMenuBar.hx b/source/funkin/ui/haxeui/components/FunkinMenuBar.hx deleted file mode 100644 index 393372d74..000000000 --- a/source/funkin/ui/haxeui/components/FunkinMenuBar.hx +++ /dev/null @@ -1,32 +0,0 @@ -package funkin.ui.haxeui.components; - -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; -import haxe.ui.containers.menus.MenuBar; -import haxe.ui.core.CompositeBuilder; - -/** - * A HaxeUI menu bar which: - * - Changes the current cursor when each button is hovered over. - */ -class FunkinMenuBar extends MenuBar -{ - public function new() - { - super(); - - registerListeners(); - } - - private function registerListeners():Void {} - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinMenuCheckBox.hx b/source/funkin/ui/haxeui/components/FunkinMenuCheckBox.hx deleted file mode 100644 index 263277c6f..000000000 --- a/source/funkin/ui/haxeui/components/FunkinMenuCheckBox.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; -import haxe.ui.containers.menus.MenuCheckBox; - -/** - * A HaxeUI menu checkbox which: - * - Changes the current cursor when hovered over. - */ -class FunkinMenuCheckBox extends MenuCheckBox -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinMenuItem.hx b/source/funkin/ui/haxeui/components/FunkinMenuItem.hx deleted file mode 100644 index 2eb7db729..000000000 --- a/source/funkin/ui/haxeui/components/FunkinMenuItem.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; -import haxe.ui.containers.menus.MenuItem; - -/** - * A HaxeUI menu item which: - * - Changes the current cursor when hovered over. - */ -class FunkinMenuItem extends MenuItem -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinMenuOptionBox.hx b/source/funkin/ui/haxeui/components/FunkinMenuOptionBox.hx deleted file mode 100644 index d9985eede..000000000 --- a/source/funkin/ui/haxeui/components/FunkinMenuOptionBox.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import haxe.ui.containers.menus.MenuOptionBox; -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; - -/** - * A HaxeUI menu option box which: - * - Changes the current cursor when hovered over. - */ -class FunkinMenuOptionBox extends MenuOptionBox -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinNumberStepper.hx b/source/funkin/ui/haxeui/components/FunkinNumberStepper.hx deleted file mode 100644 index db8d4fb7f..000000000 --- a/source/funkin/ui/haxeui/components/FunkinNumberStepper.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import haxe.ui.components.NumberStepper; -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; - -/** - * A HaxeUI number stepper which: - * - Changes the current cursor when hovered over. - */ -class FunkinNumberStepper extends NumberStepper -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Pointer; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} diff --git a/source/funkin/ui/haxeui/components/FunkinTextField.hx b/source/funkin/ui/haxeui/components/FunkinTextField.hx deleted file mode 100644 index 3ecab0684..000000000 --- a/source/funkin/ui/haxeui/components/FunkinTextField.hx +++ /dev/null @@ -1,30 +0,0 @@ -package funkin.ui.haxeui.components; - -import haxe.ui.components.TextField; -import funkin.input.Cursor; -import haxe.ui.events.MouseEvent; - -/** - * A HaxeUI text field which: - * - Changes the current cursor when hovered over. - */ -class FunkinTextField extends TextField -{ - public function new() - { - super(); - - this.onMouseOver = handleMouseOver; - this.onMouseOut = handleMouseOut; - } - - private function handleMouseOver(event:MouseEvent) - { - Cursor.cursorMode = Text; - } - - private function handleMouseOut(event:MouseEvent) - { - Cursor.cursorMode = Default; - } -} From 15ffbf2fe7657f8d6d73c873c8c96e09f7231fc5 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Wed, 1 Nov 2023 23:09:52 -0400 Subject: [PATCH 06/21] Fixed a MacOS-specific issue --- source/funkin/util/CLIUtil.hx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/source/funkin/util/CLIUtil.hx b/source/funkin/util/CLIUtil.hx index a085ada6d..0ca707c34 100644 --- a/source/funkin/util/CLIUtil.hx +++ b/source/funkin/util/CLIUtil.hx @@ -1,5 +1,7 @@ package funkin.util; +import haxe.io.Path; + /** * Utilties for interpreting command line arguments. */ @@ -13,9 +15,20 @@ class CLIUtil public static function resetWorkingDir():Void { #if sys - var exeDir:String = haxe.io.Path.directory(Sys.programPath()); - trace('Changing working directory from ${Sys.getCwd()} to ${exeDir}'); - Sys.setCwd(exeDir); + var exeDir:String = Path.addTrailingSlash(Path.directory(Sys.programPath())); + #if mac + exeDir = Path.addTrailingSlash(Path.join([exeDir, '../Resources/'])); + #end + var cwd:String = Path.addTrailingSlash(Sys.getCwd()); + if (cwd == exeDir) + { + trace('Working directory is already correct.'); + } + else + { + trace('Changing working directory from ${Sys.getCwd()} to ${exeDir}'); + Sys.setCwd(exeDir); + } #end } From 2b468ad926cdd4724e99abf57cef1d4603dedb35 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Thu, 2 Nov 2023 17:40:00 -0400 Subject: [PATCH 07/21] Fix issue where changing width of dropdown would cause a crash --- assets | 2 +- source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/assets b/assets index 3f8299aba..9098a1df3 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 3f8299aba4e308a6c86ce8f499b697de04909ad2 +Subproject commit 9098a1df39f1320f2ea65fbac674b410ea3829dd diff --git a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx index bd4f9ed06..4ee894f07 100644 --- a/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorToolboxHandler.hx @@ -411,6 +411,7 @@ class ChartEditorToolboxHandler case ENUM: var dropDown:DropDown = new DropDown(); dropDown.id = field.name; + dropDown.width = 200.0; dropDown.dataSource = new ArrayDataSource(); if (field.keys == null) throw 'Field "${field.name}" is of Enum type but has no keys.'; From a605f53e07ba54b75c5beecb4f84a11a31a45b7d Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Sun, 5 Nov 2023 00:07:49 -0400 Subject: [PATCH 08/21] Updated git references for haxeui-core and haxeui-flixel --- hmm.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hmm.json b/hmm.json index 1d9e51d69..778b85604 100644 --- a/hmm.json +++ b/hmm.json @@ -49,14 +49,14 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "db6f81191abe386d891aca5a65c27ba6f8e10598", + "ref": "815e94dd5aa6cf09c5ddcef1666a54449ffde8dc", "url": "https://github.com/haxeui/haxeui-core" }, { "name": "haxeui-flixel", "type": "git", "dir": null, - "ref": "e10f51fe33b8d8d2dd3f21a0fd1d7c4d88d5d5c0", + "ref": "95c7d66e779626eabd6f48a1cd7aa7f9a503a7f3", "url": "https://github.com/haxeui/haxeui-flixel" }, { From 27de7dc036dbd9b0ad22e87c65e03daea72f0231 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Sun, 5 Nov 2023 00:08:06 -0400 Subject: [PATCH 09/21] Update notification expiry time constant in ChartEditorState and ChartEditorDialogHandler --- source/funkin/ui/debug/charting/ChartEditorState.hx | 2 +- .../debug/charting/handlers/ChartEditorDialogHandler.hx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 3fee7ce93..8255a8c7d 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -1425,7 +1425,7 @@ class ChartEditorState extends HaxeUIState title: 'Success', body: 'Loaded chart (${params.fnfcTargetPath})', type: NotificationType.Success, - expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + expiryMs: Constants.NOTIFICATION_DISMISS_TIME }); #end } diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx index 0574cea4f..dba513c32 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx @@ -231,7 +231,7 @@ class ChartEditorDialogHandler title: 'Success', body: 'Loaded chart (${selectedFile.name})', type: NotificationType.Success, - expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + expiryMs: Constants.NOTIFICATION_DISMISS_TIME }); #end @@ -248,7 +248,7 @@ class ChartEditorDialogHandler title: 'Failure', body: 'Failed to load chart (${selectedFile.name}): ${err}', type: NotificationType.Error, - expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + expiryMs: Constants.NOTIFICATION_DISMISS_TIME }); #end } @@ -270,7 +270,7 @@ class ChartEditorDialogHandler title: 'Success', body: 'Loaded chart (${path.toString()})', type: NotificationType.Success, - expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + expiryMs: Constants.NOTIFICATION_DISMISS_TIME }); #end @@ -286,7 +286,7 @@ class ChartEditorDialogHandler title: 'Failure', body: 'Failed to load chart (${path.toString()}): ${err}', type: NotificationType.Error, - expiryMs: ChartEditorState.NOTIFICATION_DISMISS_TIME + expiryMs: Constants.NOTIFICATION_DISMISS_TIME }); #end } From de5edb3cc208255303541e98044dfb8e70db9da9 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Sun, 5 Nov 2023 00:08:18 -0400 Subject: [PATCH 10/21] Fix variation metadata and error message in ChartEditorImportExportHandler --- source/funkin/play/song/Song.hx | 6 +++--- .../charting/handlers/ChartEditorImportExportHandler.hx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 01f0a5893..b48eda224 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -98,10 +98,10 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta for (vari in _data.playData.songVariations) { variations.push(vari); - } - for (meta in fetchVariationMetadata(id)) - _metadata.set(meta.variation, meta); + var variMeta = fetchVariationMetadata(id, vari); + if (variMeta != null) _metadata.set(variMeta.variation, variMeta); + } } if (_metadata.size() == 0) diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx index 001caea8b..be850e93e 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx @@ -285,7 +285,7 @@ class ChartEditorImportExportHandler } else { - throw 'Could not load vocals ($playerCharId-$instId).'; + throw 'Could not load vocals ($opponentCharId).'; } } } From bdb3fe28bb80742dcfda156ca93974a2ae998779 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Sun, 5 Nov 2023 00:35:23 -0400 Subject: [PATCH 11/21] Update assets --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 36f8134b6..d491f5d87 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 36f8134b6c0d9e4bbb7252e23a980ffdf32a3695 +Subproject commit d491f5d87a0deba0b5642beeb801c8e130754038 From 66ae60e9e48966f4c5555416560d53e635b6f02e Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Sun, 5 Nov 2023 01:19:47 -0400 Subject: [PATCH 12/21] Updated syntax after merge --- assets | 2 +- source/funkin/data/song/SongData.hx | 8 ++++---- source/funkin/ui/debug/charting/ChartEditorState.hx | 4 +++- .../debug/charting/handlers/ChartEditorDialogHandler.hx | 2 -- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assets b/assets index 49901dee1..d491f5d87 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 49901dee1fae3fdfd784e9d48374255282cc2042 +Subproject commit d491f5d87a0deba0b5642beeb801c8e130754038 diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 9523f23c0..83b336606 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -528,8 +528,8 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR public inline function getInt(key:String):Null<Int> { - if (value == null) return null; - var result = Reflect.field(value, key); + if (this.value == null) return null; + var result = Reflect.field(this.value, key); if (result == null) return null; if (Std.isOfType(result, Int)) return result; if (Std.isOfType(result, String)) return Std.parseInt(cast result); @@ -538,8 +538,8 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR public inline function getFloat(key:String):Null<Float> { - if (value == null) return null; - var result = Reflect.field(value, key); + if (this.value == null) return null; + var result = Reflect.field(this.value, key); if (result == null) return null; if (Std.isOfType(result, Float)) return result; if (Std.isOfType(result, String)) return Std.parseFloat(cast result); diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 023aeda4b..71e86ad1f 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -3921,8 +3921,10 @@ class ChartEditorState extends HaxeUIState if (FlxG.keys.justPressed.F1) this.openUserGuideDialog(); } - function handleQuickWatch():Void + override function handleQuickWatch():Void { + super.handleQuickWatch(); + FlxG.watch.addQuick('scrollPosInPixels', scrollPositionInPixels); FlxG.watch.addQuick('playheadPosInPixels', playheadPositionInPixels); diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx index d773e6489..bb066a923 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorDialogHandler.hx @@ -15,8 +15,6 @@ import funkin.play.character.CharacterData.CharacterDataParser; import funkin.play.song.Song; import funkin.play.stage.StageData; import funkin.ui.debug.charting.util.ChartEditorDropdowns; -import funkin.ui.haxeui.components.FunkinDropDown; -import funkin.ui.haxeui.components.FunkinLink; import funkin.util.Constants; import funkin.util.FileUtil; import funkin.util.SerializerUtil; From d4fedfb99ea2a41bd0edf58f3697b6716a1793a0 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Sun, 5 Nov 2023 01:31:57 -0400 Subject: [PATCH 13/21] Update assets --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index d491f5d87..6ca2ae9a5 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d491f5d87a0deba0b5642beeb801c8e130754038 +Subproject commit 6ca2ae9a575b672da6c8243aa46a6cb2434eca7f From ce97a002cb01fee2e86a9a96075665d499e671aa Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Tue, 7 Nov 2023 04:04:22 -0500 Subject: [PATCH 14/21] Reorganize a whole bunch of classes and perform syntax cleanup. --- assets | 2 +- source/Main.hx | 2 +- source/funkin/Controls.hx | 177 ++++++------ source/funkin/CoolUtil.hx | 129 --------- source/funkin/DialogueBox.hx | 265 ------------------ source/funkin/FlxSwf.hx | 43 --- source/funkin/Highscore.hx | 3 + source/funkin/InitState.hx | 11 +- source/funkin/MenuCharacter.hx | 42 --- source/funkin/NoteSplash.hx | 65 ----- source/funkin/Options.hx | 6 - source/funkin/Paths.hx | 3 + source/funkin/PlayerSettings.hx | 5 +- source/funkin/Preferences.hx | 2 +- source/funkin/TankCutscene.hx | 27 -- source/funkin/{ => api/discord}/Discord.hx | 2 +- source/funkin/api/newgrounds/NGUtil.hx | 12 - source/funkin/{ => api/newgrounds}/NGio.hx | 2 +- source/funkin/api/newgrounds/README.md | 2 +- .../{audiovis => audio/visualize}/ABot.hx | 2 +- .../{audiovis => audio/visualize}/ABotVis.hx | 7 +- .../audio/visualize/PolygonSpectogram.hx | 2 +- .../visualize}/SpectogramSprite.hx | 6 +- .../{audiovis => audio/visualize}/VisShit.hx | 7 +- .../visualize}/dsp/Complex.hx | 2 +- .../{audiovis => audio/visualize}/dsp/FFT.hx | 8 +- .../visualize}/dsp/OffsetArray.hx | 2 +- .../visualize}/dsp/Signal.hx | 2 +- .../shaders}/AngleMask.hx | 2 +- .../shaders}/BlendModeEffect.hx | 2 +- .../shaders}/BlendModesShader.hx | 2 +- .../shaders}/ColorSwap.hx | 2 +- .../shaders}/GaussianBlurShader.hx | 2 +- .../shaders}/Grayscale.hx | 2 +- .../shaders}/HSVShader.hx | 2 +- .../shaders}/LeftMaskShader.hx | 2 +- .../shaders}/MultiplyShader.hx | 2 +- .../shaders}/OverlayBlend.hx | 2 +- .../shaders}/PureColor.hx | 2 +- .../shaders}/ScreenWipeShader.hx | 2 +- .../shaders}/StrokeShader.hx | 2 +- .../shaders}/TitleOutline.hx | 2 +- .../shaders}/WaveShader.hx | 2 +- .../shaders}/WiggleEffectRuntime.hx | 2 +- source/funkin/input/TurboKeyHandler.hx | 3 +- .../modding/base/ScriptedMusicBeatState.hx | 2 +- .../modding/base/ScriptedMusicBeatSubState.hx | 2 +- source/funkin/play/Fighter.hx | 68 ----- source/funkin/play/GameOverSubState.hx | 2 + source/funkin/{ => play}/GitarooPause.hx | 4 +- source/funkin/{ => play}/PauseSubState.hx | 8 +- source/funkin/play/PlayState.hx | 16 +- source/funkin/play/ResultState.hx | 6 +- source/funkin/play/character/BaseCharacter.hx | 2 +- .../{ => play/components}/ComboMilestone.hx | 2 +- .../play/{ => components}/HealthIcon.hx | 9 +- .../{ui => play/components}/PopUpStuff.hx | 2 +- .../{ui => play/components}/TallyCounter.hx | 4 +- .../dialogue/ConversationDebugState.hx | 1 + source/funkin/play/notes/Strumline.hx | 2 +- source/funkin/play/notes/SustainTrail.hx | 2 +- source/funkin/play/stage/Bopper.hx | 2 +- source/funkin/{ => ui}/Alphabet.hx | 8 +- source/funkin/ui/AtlasMenuList.hx | 2 +- source/funkin/{ => ui}/MenuItem.hx | 5 +- source/funkin/ui/MenuList.hx | 6 +- source/funkin/{ => ui}/MusicBeatState.hx | 3 +- source/funkin/{ => ui}/MusicBeatSubState.hx | 3 +- source/funkin/{ => ui}/SwagCamera.hx | 11 +- source/funkin/ui/debug/DebugMenuSubState.hx | 7 +- source/funkin/{ => ui/debug}/MemoryCounter.hx | 2 +- .../anim}/DebugBoundingState.hx | 9 +- .../anim}/FlxAnimateTest.hx | 3 +- .../ui/debug/charting/ChartEditorState.hx | 3 +- .../ui/{ => debug/latency}/CoolStatsGraph.hx | 2 +- .../{ => ui/debug/latency}/LatencyState.hx | 5 +- .../stage}/CharStage.hx | 2 +- .../stage}/SprStage.hx | 2 +- .../stage}/StageBuilderState.hx | 8 +- .../stage}/StageEditorCommand.hx | 4 +- .../stage}/StageOffsetSubState.hx | 13 +- .../stage}/StagetoolBar.hx | 10 +- .../freeplay}/BGScrollingText.hx | 2 +- .../freeplay}/CapsuleText.hx | 4 +- .../freeplay}/DJBoyfriend.hx | 2 +- .../freeplay}/DifficultyStars.hx | 4 +- .../freeplay}/FreeplayFlames.hx | 2 +- .../freeplay}/FreeplayScore.hx | 2 +- .../funkin/{ => ui/freeplay}/FreeplayState.hx | 38 +-- .../freeplay}/LetterSort.hx | 2 +- .../freeplay}/SongMenuItem.hx | 15 +- source/funkin/ui/haxeui/HaxeUIState.hx | 1 + source/funkin/ui/haxeui/HaxeUISubState.hx | 3 + source/funkin/ui/haxeui/components/README.md | 2 +- .../funkin/{ => ui/mainmenu}/MainMenuState.hx | 8 +- .../{ => ui/options}/ButtonRemapSubstate.hx | 2 +- source/funkin/ui/{ => options}/ColorsMenu.hx | 4 +- .../funkin/ui/{ => options}/ControlsMenu.hx | 7 +- source/funkin/ui/{ => options}/ModMenu.hx | 4 +- .../funkin/ui/{ => options}/OptionsState.hx | 4 +- .../ui/{ => options}/PreferencesMenu.hx | 4 +- source/funkin/ui/story/LevelTitle.hx | 4 +- source/funkin/ui/story/StoryMenuState.hx | 8 +- source/funkin/ui/title/AttractState.hx | 1 + source/funkin/ui/title/FlxSpriteOverlay.hx | 2 +- .../funkin/{ => ui/title}/OutdatedSubState.hx | 3 +- source/funkin/ui/title/TitleState.hx | 17 +- .../{ => ui/transition}/LoadingState.hx | 25 +- .../ui/{ => transition}/StickerSubState.hx | 5 +- source/funkin/util/BezierUtil.hx | 3 + source/funkin/util/DateUtil.hx | 3 + source/funkin/util/FlxGamepadUtil.hx | 3 + .../{InputFormatter.hx => util/InputUtil.hx} | 11 +- source/funkin/util/MathUtil.hx | 31 ++ source/funkin/util/MouseUtil.hx | 45 +++ source/funkin/util/PlatformUtil.hx | 3 + source/funkin/util/SerializerUtil.hx | 4 +- source/funkin/util/SortUtil.hx | 2 +- source/funkin/util/VersionUtil.hx | 2 + source/funkin/util/WindowUtil.hx | 3 + 120 files changed, 462 insertions(+), 938 deletions(-) delete mode 100644 source/funkin/CoolUtil.hx delete mode 100644 source/funkin/DialogueBox.hx delete mode 100644 source/funkin/FlxSwf.hx delete mode 100644 source/funkin/MenuCharacter.hx delete mode 100644 source/funkin/NoteSplash.hx delete mode 100644 source/funkin/Options.hx delete mode 100644 source/funkin/TankCutscene.hx rename source/funkin/{ => api/discord}/Discord.hx (98%) rename source/funkin/{ => api/newgrounds}/NGio.hx (99%) rename source/funkin/{audiovis => audio/visualize}/ABot.hx (85%) rename source/funkin/{audiovis => audio/visualize}/ABotVis.hx (96%) rename source/funkin/{audiovis => audio/visualize}/SpectogramSprite.hx (98%) rename source/funkin/{audiovis => audio/visualize}/VisShit.hx (93%) rename source/funkin/{audiovis => audio/visualize}/dsp/Complex.hx (98%) rename source/funkin/{audiovis => audio/visualize}/dsp/FFT.hx (97%) rename source/funkin/{audiovis => audio/visualize}/dsp/OffsetArray.hx (98%) rename source/funkin/{audiovis => audio/visualize}/dsp/Signal.hx (98%) rename source/funkin/{shaderslmfao => graphics/shaders}/AngleMask.hx (96%) rename source/funkin/{shaderslmfao => graphics/shaders}/BlendModeEffect.hx (95%) rename source/funkin/{shaderslmfao => graphics/shaders}/BlendModesShader.hx (92%) rename source/funkin/{shaderslmfao => graphics/shaders}/ColorSwap.hx (99%) rename source/funkin/{shaderslmfao => graphics/shaders}/GaussianBlurShader.hx (93%) rename source/funkin/{shaderslmfao => graphics/shaders}/Grayscale.hx (92%) rename source/funkin/{shaderslmfao => graphics/shaders}/HSVShader.hx (96%) rename source/funkin/{shaderslmfao => graphics/shaders}/LeftMaskShader.hx (97%) rename source/funkin/{shaderslmfao => graphics/shaders}/MultiplyShader.hx (94%) rename source/funkin/{shaderslmfao => graphics/shaders}/OverlayBlend.hx (97%) rename source/funkin/{shaderslmfao => graphics/shaders}/PureColor.hx (96%) rename source/funkin/{shaderslmfao => graphics/shaders}/ScreenWipeShader.hx (98%) rename source/funkin/{shaderslmfao => graphics/shaders}/StrokeShader.hx (98%) rename source/funkin/{shaderslmfao => graphics/shaders}/TitleOutline.hx (98%) rename source/funkin/{shaderslmfao => graphics/shaders}/WaveShader.hx (90%) rename source/funkin/{shaderslmfao => graphics/shaders}/WiggleEffectRuntime.hx (98%) delete mode 100644 source/funkin/play/Fighter.hx rename source/funkin/{ => play}/GitarooPause.hx (96%) rename source/funkin/{ => play}/PauseSubState.hx (97%) rename source/funkin/{ => play/components}/ComboMilestone.hx (98%) rename source/funkin/play/{ => components}/HealthIcon.hx (98%) rename source/funkin/{ui => play/components}/PopUpStuff.hx (99%) rename source/funkin/{ui => play/components}/TallyCounter.hx (94%) rename source/funkin/{ => ui}/Alphabet.hx (97%) rename source/funkin/{ => ui}/MenuItem.hx (93%) rename source/funkin/{ => ui}/MusicBeatState.hx (98%) rename source/funkin/{ => ui}/MusicBeatSubState.hx (98%) rename source/funkin/{ => ui}/SwagCamera.hx (87%) rename source/funkin/{ => ui/debug}/MemoryCounter.hx (97%) rename source/funkin/ui/{animDebugShit => debug/anim}/DebugBoundingState.hx (98%) rename source/funkin/ui/{animDebugShit => debug/anim}/FlxAnimateTest.hx (94%) rename source/funkin/ui/{ => debug/latency}/CoolStatsGraph.hx (99%) rename source/funkin/{ => ui/debug/latency}/LatencyState.hx (98%) rename source/funkin/ui/{stageBuildShit => debug/stage}/CharStage.hx (81%) rename source/funkin/ui/{stageBuildShit => debug/stage}/SprStage.hx (97%) rename source/funkin/ui/{stageBuildShit => debug/stage}/StageBuilderState.hx (98%) rename source/funkin/ui/{stageBuildShit => debug/stage}/StageEditorCommand.hx (95%) rename source/funkin/ui/{stageBuildShit => debug/stage}/StageOffsetSubState.hx (97%) rename source/funkin/ui/{stageBuildShit => debug/stage}/StagetoolBar.hx (67%) rename source/funkin/{freeplayStuff => ui/freeplay}/BGScrollingText.hx (98%) rename source/funkin/{freeplayStuff => ui/freeplay}/CapsuleText.hx (93%) rename source/funkin/{freeplayStuff => ui/freeplay}/DJBoyfriend.hx (99%) rename source/funkin/{freeplayStuff => ui/freeplay}/DifficultyStars.hx (96%) rename source/funkin/{freeplayStuff => ui/freeplay}/FreeplayFlames.hx (98%) rename source/funkin/{freeplayStuff => ui/freeplay}/FreeplayScore.hx (98%) rename source/funkin/{ => ui/freeplay}/FreeplayState.hx (97%) rename source/funkin/{freeplayStuff => ui/freeplay}/LetterSort.hx (99%) rename source/funkin/{freeplayStuff => ui/freeplay}/SongMenuItem.hx (96%) rename source/funkin/{ => ui/mainmenu}/MainMenuState.hx (97%) rename source/funkin/{ => ui/options}/ButtonRemapSubstate.hx (82%) rename source/funkin/ui/{ => options}/ColorsMenu.hx (96%) rename source/funkin/ui/{ => options}/ControlsMenu.hx (98%) rename source/funkin/ui/{ => options}/ModMenu.hx (97%) rename source/funkin/ui/{ => options}/OptionsState.hx (98%) rename source/funkin/ui/{ => options}/PreferencesMenu.hx (98%) rename source/funkin/{ => ui/title}/OutdatedSubState.hx (95%) rename source/funkin/{ => ui/transition}/LoadingState.hx (89%) rename source/funkin/ui/{ => transition}/StickerSubState.hx (98%) rename source/funkin/{InputFormatter.hx => util/InputUtil.hx} (96%) create mode 100644 source/funkin/util/MathUtil.hx create mode 100644 source/funkin/util/MouseUtil.hx diff --git a/assets b/assets index e634c8f50..53f63f549 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e634c8f50c34845097283e0f411e1f89409e1498 +Subproject commit 53f63f549f34b9c03d0e2d7149dde551a61acb26 diff --git a/source/Main.hx b/source/Main.hx index dffe666b7..ffc3edd76 100644 --- a/source/Main.hx +++ b/source/Main.hx @@ -3,7 +3,7 @@ package; import flixel.FlxGame; import flixel.FlxState; import funkin.util.logging.CrashHandler; -import funkin.MemoryCounter; +import funkin.ui.debug.MemoryCounter; import funkin.save.Save; import haxe.ui.Toolkit; import openfl.display.FPS; diff --git a/source/funkin/Controls.hx b/source/funkin/Controls.hx index 9372c4dc6..9f2dcff49 100644 --- a/source/funkin/Controls.hx +++ b/source/funkin/Controls.hx @@ -23,96 +23,14 @@ import flixel.util.FlxTimer; import lime.ui.Haptic; /** - * Since, in many cases multiple actions should use similar keys, we don't want the - * rebinding UI to list every action. ActionBinders are what the user percieves as - * an input so, for instance, they can't set jump-press and jump-release to different keys. - */ -enum Control -{ - // List notes in order from left to right on gameplay screen. - NOTE_LEFT; - NOTE_DOWN; - NOTE_UP; - NOTE_RIGHT; - UI_UP; - UI_LEFT; - UI_RIGHT; - UI_DOWN; - RESET; - ACCEPT; - BACK; - PAUSE; - CUTSCENE_ADVANCE; - CUTSCENE_SKIP; - VOLUME_UP; - VOLUME_DOWN; - VOLUME_MUTE; - #if CAN_CHEAT - CHEAT; - #end -} - -enum -abstract Action(String) to String from String -{ - var UI_UP = "ui_up"; - var UI_LEFT = "ui_left"; - var UI_RIGHT = "ui_right"; - var UI_DOWN = "ui_down"; - var UI_UP_P = "ui_up-press"; - var UI_LEFT_P = "ui_left-press"; - var UI_RIGHT_P = "ui_right-press"; - var UI_DOWN_P = "ui_down-press"; - var UI_UP_R = "ui_up-release"; - var UI_LEFT_R = "ui_left-release"; - var UI_RIGHT_R = "ui_right-release"; - var UI_DOWN_R = "ui_down-release"; - var NOTE_UP = "note_up"; - var NOTE_LEFT = "note_left"; - var NOTE_RIGHT = "note_right"; - var NOTE_DOWN = "note_down"; - var NOTE_UP_P = "note_up-press"; - var NOTE_LEFT_P = "note_left-press"; - var NOTE_RIGHT_P = "note_right-press"; - var NOTE_DOWN_P = "note_down-press"; - var NOTE_UP_R = "note_up-release"; - var NOTE_LEFT_R = "note_left-release"; - var NOTE_RIGHT_R = "note_right-release"; - var NOTE_DOWN_R = "note_down-release"; - var ACCEPT = "accept"; - var BACK = "back"; - var PAUSE = "pause"; - var CUTSCENE_ADVANCE = "cutscene_advance"; - var CUTSCENE_SKIP = "cutscene_skip"; - var VOLUME_UP = "volume_up"; - var VOLUME_DOWN = "volume_down"; - var VOLUME_MUTE = "volume_mute"; - var RESET = "reset"; - #if CAN_CHEAT - var CHEAT = "cheat"; - #end -} - -enum Device -{ - Keys; - Gamepad(id:Int); -} - -enum KeyboardScheme -{ - Solo; - Duo(first:Bool); - None; - Custom; -} - -/** - * A list of actions that a player would invoke via some input device. - * Uses FlxActions to funnel various inputs to a single action. + * A core class which handles receiving player input and interpreting it into game actions. */ class Controls extends FlxActionSet { + /** + * A list of actions that a player would invoke via some input device. + * Uses FlxActions to funnel various inputs to a single action. + */ var _ui_up = new FlxActionDigital(Action.UI_UP); var _ui_left = new FlxActionDigital(Action.UI_LEFT); var _ui_right = new FlxActionDigital(Action.UI_RIGHT); @@ -1241,3 +1159,88 @@ class FlxActionInputDigitalAndroid extends FlxActionInputDigital } } #end + +/** + * Since, in many cases multiple actions should use similar keys, we don't want the + * rebinding UI to list every action. ActionBinders are what the user percieves as + * an input so, for instance, they can't set jump-press and jump-release to different keys. + */ +enum Control +{ + // List notes in order from left to right on gameplay screen. + NOTE_LEFT; + NOTE_DOWN; + NOTE_UP; + NOTE_RIGHT; + UI_UP; + UI_LEFT; + UI_RIGHT; + UI_DOWN; + RESET; + ACCEPT; + BACK; + PAUSE; + CUTSCENE_ADVANCE; + CUTSCENE_SKIP; + VOLUME_UP; + VOLUME_DOWN; + VOLUME_MUTE; + #if CAN_CHEAT + CHEAT; + #end +} + +enum +abstract Action(String) to String from String +{ + var UI_UP = "ui_up"; + var UI_LEFT = "ui_left"; + var UI_RIGHT = "ui_right"; + var UI_DOWN = "ui_down"; + var UI_UP_P = "ui_up-press"; + var UI_LEFT_P = "ui_left-press"; + var UI_RIGHT_P = "ui_right-press"; + var UI_DOWN_P = "ui_down-press"; + var UI_UP_R = "ui_up-release"; + var UI_LEFT_R = "ui_left-release"; + var UI_RIGHT_R = "ui_right-release"; + var UI_DOWN_R = "ui_down-release"; + var NOTE_UP = "note_up"; + var NOTE_LEFT = "note_left"; + var NOTE_RIGHT = "note_right"; + var NOTE_DOWN = "note_down"; + var NOTE_UP_P = "note_up-press"; + var NOTE_LEFT_P = "note_left-press"; + var NOTE_RIGHT_P = "note_right-press"; + var NOTE_DOWN_P = "note_down-press"; + var NOTE_UP_R = "note_up-release"; + var NOTE_LEFT_R = "note_left-release"; + var NOTE_RIGHT_R = "note_right-release"; + var NOTE_DOWN_R = "note_down-release"; + var ACCEPT = "accept"; + var BACK = "back"; + var PAUSE = "pause"; + var CUTSCENE_ADVANCE = "cutscene_advance"; + var CUTSCENE_SKIP = "cutscene_skip"; + var VOLUME_UP = "volume_up"; + var VOLUME_DOWN = "volume_down"; + var VOLUME_MUTE = "volume_mute"; + var RESET = "reset"; + #if CAN_CHEAT + var CHEAT = "cheat"; + #end +} + +enum Device +{ + Keys; + Gamepad(id:Int); +} + +enum KeyboardScheme +{ + Solo; + Duo(first:Bool); + None; + Custom; +} diff --git a/source/funkin/CoolUtil.hx b/source/funkin/CoolUtil.hx deleted file mode 100644 index d07bb4e22..000000000 --- a/source/funkin/CoolUtil.hx +++ /dev/null @@ -1,129 +0,0 @@ -package funkin; - -import flixel.FlxSprite; -import flixel.FlxState; -import flixel.graphics.FlxGraphic; -import flixel.graphics.frames.FlxAtlasFrames; -import flixel.math.FlxMath; -import flixel.math.FlxPoint; -import flixel.math.FlxRect; -import flixel.system.FlxAssets.FlxGraphicAsset; -import flixel.tweens.FlxEase; -import flixel.tweens.FlxTween; -import funkin.play.PlayState; -import funkin.shaderslmfao.ScreenWipeShader; -import haxe.format.JsonParser; -import lime.math.Rectangle; -import lime.utils.Assets; -import openfl.filters.ShaderFilter; - -class CoolUtil -{ - public static function coolBaseLog(base:Float, fin:Float):Float - { - return Math.log(fin) / Math.log(base); - } - - public static function coolTextFile(path:String):Array<String> - { - var daList:Array<String> = []; - - var swagArray:Array<String> = Assets.getText(path).trim().split('\n'); - - for (item in swagArray) - { - // comment support in the quick lil text formats??? using // - if (!item.trim().startsWith('//')) daList.push(item); - } - - for (i in 0...daList.length) - { - daList[i] = daList[i].trim(); - } - - return daList; - } - - public static function numberArray(max:Int, ?min = 0):Array<Int> - { - var dumbArray:Array<Int> = []; - for (i in min...max) - { - dumbArray.push(i); - } - return dumbArray; - } - - static var oldCamPos:FlxPoint = new FlxPoint(); - static var oldMousePos:FlxPoint = new FlxPoint(); - - /** - * Used to be for general camera middle click dragging, now generalized for any click and drag type shit! - * Listen I don't make the rules here - * @param target what you want to be dragged, defaults to CAMERA SCROLL - * @param jusPres the "justPressed", should be a button of some sort - * @param pressed the "pressed", which should be the same button as `jusPres` - */ - public static function mouseCamDrag(?target:FlxPoint, ?jusPres:Bool, ?pressed:Bool):Void - { - if (target == null) target = FlxG.camera.scroll; - - if (jusPres == null) jusPres = FlxG.mouse.justPressedMiddle; - - if (pressed == null) pressed = FlxG.mouse.pressedMiddle; - - if (jusPres) - { - oldCamPos.set(target.x, target.y); - oldMousePos.set(FlxG.mouse.screenX, FlxG.mouse.screenY); - } - - if (pressed) - { - target.x = oldCamPos.x - (FlxG.mouse.screenX - oldMousePos.x); - target.y = oldCamPos.y - (FlxG.mouse.screenY - oldMousePos.y); - } - } - - public static function mouseWheelZoom():Void - { - if (FlxG.mouse.wheel != 0) FlxG.camera.zoom += FlxG.mouse.wheel * (0.1 * FlxG.camera.zoom); - } - - /** - Lerps camera, but accountsfor framerate shit? - Right now it's simply for use to change the followLerp variable of a camera during update - TODO LATER MAYBE: - Actually make and modify the scroll and lerp shit in it's own function - instead of solely relying on changing the lerp on the fly - */ - public static function camLerpShit(lerp:Float):Float - { - return lerp * (FlxG.elapsed / (1 / 60)); - } - - public static function coolSwitchState(state:FlxState, transitionTex:String = "shaderTransitionStuff/coolDots", time:Float = 2) - { - var screenShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("shaderTransitionStuff/coolDots")); - var screenWipeShit:ScreenWipeShader = new ScreenWipeShader(); - - screenWipeShit.funnyShit.input = screenShit.pixels; - FlxTween.tween(screenWipeShit, {daAlphaShit: 1}, time, - { - ease: FlxEase.quadInOut, - onComplete: function(twn) { - screenShit.destroy(); - FlxG.switchState(new MainMenuState()); - } - }); - FlxG.camera.setFilters([new ShaderFilter(screenWipeShit)]); - } - - /* - * frame dependant lerp kinda lol - */ - public static function coolLerp(base:Float, target:Float, ratio:Float):Float - { - return base + camLerpShit(ratio) * (target - base); - } -} diff --git a/source/funkin/DialogueBox.hx b/source/funkin/DialogueBox.hx deleted file mode 100644 index 68d330dbe..000000000 --- a/source/funkin/DialogueBox.hx +++ /dev/null @@ -1,265 +0,0 @@ -package funkin; - -import flixel.FlxSprite; -import flixel.addons.text.FlxTypeText; -import flixel.group.FlxSpriteGroup; -import flixel.text.FlxText; -import flixel.util.FlxColor; -import flixel.util.FlxTimer; -import funkin.play.PlayState; - -/** - * Handles dialog boxes and text, like the ones in Week 6. - */ -class DialogueBox extends FlxSpriteGroup -{ - var box:FlxSprite; - - var curCharacter:String = ''; - - var dialogue:Alphabet; - var dialogueList:Array<String> = []; - - // SECOND DIALOGUE FOR THE PIXEL SHIT INSTEAD??? - var swagDialogue:FlxTypeText; - - var dropText:FlxText; - - public var finishThing:Void->Void; - - var portraitLeft:FlxSprite; - var portraitRight:FlxSprite; - - var handSelect:FlxSprite; - var bgFade:FlxSprite; - - public function new(talkingRight:Bool = true, ?dialogueList:Array<String>) - { - super(); - - switch (PlayState.instance.currentSong.id.toLowerCase()) - { - case 'senpai': - FlxG.sound.playMusic(Paths.music('Lunchbox'), 0); - FlxG.sound.music.fadeIn(1, 0, 0.8); - case 'thorns': - FlxG.sound.playMusic(Paths.music('LunchboxScary'), 0); - FlxG.sound.music.fadeIn(1, 0, 0.8); - } - - bgFade = new FlxSprite(-200, -200).makeGraphic(Std.int(FlxG.width * 1.3), Std.int(FlxG.height * 1.3), 0xFFB3DFD8); - bgFade.scrollFactor.set(); - bgFade.alpha = 0; - add(bgFade); - - new FlxTimer().start(0.83, function(tmr:FlxTimer) { - bgFade.alpha += (1 / 5) * 0.7; - if (bgFade.alpha > 0.7) bgFade.alpha = 0.7; - }, 5); - - portraitLeft = new FlxSprite(-20, 40); - portraitLeft.frames = Paths.getSparrowAtlas('weeb/senpaiPortrait'); - portraitLeft.animation.addByPrefix('enter', 'Senpai Portrait Enter', 24, false); - portraitLeft.setGraphicSize(Std.int(portraitLeft.width * Constants.PIXEL_ART_SCALE * 0.9)); - portraitLeft.updateHitbox(); - portraitLeft.scrollFactor.set(); - add(portraitLeft); - portraitLeft.visible = false; - - portraitRight = new FlxSprite(0, 40); - portraitRight.frames = Paths.getSparrowAtlas('weeb/bfPortrait'); - portraitRight.animation.addByPrefix('enter', 'Boyfriend portrait enter', 24, false); - portraitRight.setGraphicSize(Std.int(portraitRight.width * Constants.PIXEL_ART_SCALE * 0.9)); - portraitRight.updateHitbox(); - portraitRight.scrollFactor.set(); - add(portraitRight); - portraitRight.visible = false; - - box = new FlxSprite(-20, 45); - - var hasDialog:Bool = false; - switch (PlayState.instance.currentSong.id.toLowerCase()) - { - case 'senpai': - hasDialog = true; - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-pixel'); - box.animation.addByPrefix('normalOpen', 'Text Box Appear', 24, false); - box.animation.addByIndices('normal', 'Text Box Appear', [4], '', 24); - case 'roses': - hasDialog = true; - FlxG.sound.play(Paths.sound('ANGRY_TEXT_BOX')); - - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-senpaiMad'); - box.animation.addByPrefix('normalOpen', 'SENPAI ANGRY IMPACT SPEECH', 24, false); - box.animation.addByIndices('normal', 'SENPAI ANGRY IMPACT SPEECH', [4], '', 24); - - case 'thorns': - hasDialog = true; - box.frames = Paths.getSparrowAtlas('weeb/pixelUI/dialogueBox-evil'); - box.animation.addByPrefix('normalOpen', 'Spirit Textbox spawn', 24, false); - box.animation.addByIndices('normal', 'Spirit Textbox spawn', [11], '', 24); - - var face:FlxSprite = new FlxSprite(320, 170).loadGraphic(Paths.image('weeb/spiritFaceForward')); - face.setGraphicSize(Std.int(face.width * 6)); - add(face); - } - - this.dialogueList = dialogueList; - - if (!hasDialog) return; - - box.animation.play('normalOpen'); - box.setGraphicSize(Std.int(box.width * Constants.PIXEL_ART_SCALE * 0.9)); - box.updateHitbox(); - add(box); - - box.screenCenter(X); - portraitLeft.screenCenter(X); - - handSelect = new FlxSprite(1042, 590).loadGraphic(Paths.image('weeb/pixelUI/hand_textbox')); - handSelect.setGraphicSize(Std.int(handSelect.width * Constants.PIXEL_ART_SCALE * 0.9)); - handSelect.updateHitbox(); - handSelect.visible = false; - add(handSelect); - - if (!talkingRight) - { - // box.flipX = true; - } - - dropText = new FlxText(242, 502, Std.int(FlxG.width * 0.6), '', 32); - dropText.font = 'Pixel Arial 11 Bold'; - dropText.color = 0xFFD89494; - add(dropText); - - swagDialogue = new FlxTypeText(240, 500, Std.int(FlxG.width * 0.6), '', 32); - swagDialogue.font = 'Pixel Arial 11 Bold'; - swagDialogue.color = 0xFF3F2021; - swagDialogue.sounds = [FlxG.sound.load(Paths.sound('pixelText'), 0.6)]; - add(swagDialogue); - - dialogue = new Alphabet(0, 80, '', false, true); - // dialogue.x = 90; - // add(dialogue); - } - - var dialogueOpened:Bool = false; - var dialogueStarted:Bool = false; - var dialogueEnded:Bool = false; - - override function update(elapsed:Float):Void - { - // HARD CODING CUZ IM STUPDI - if (PlayState.instance.currentSong.id.toLowerCase() == 'roses') portraitLeft.visible = false; - if (PlayState.instance.currentSong.id.toLowerCase() == 'thorns') - { - portraitLeft.color = FlxColor.BLACK; - swagDialogue.color = FlxColor.WHITE; - dropText.color = FlxColor.BLACK; - } - - dropText.text = swagDialogue.text; - - if (box.animation.curAnim != null) - { - if (box.animation.curAnim.name == 'normalOpen' && box.animation.curAnim.finished) - { - box.animation.play('normal'); - dialogueOpened = true; - } - } - - if (dialogueOpened && !dialogueStarted) - { - startDialogue(); - dialogueStarted = true; - } - - if (FlxG.keys.justPressed.ANY && dialogueEnded) - { - remove(dialogue); - - FlxG.sound.play(Paths.sound('clickText'), 0.8); - - if (dialogueList[1] == null && dialogueList[0] != null) - { - if (!isEnding) - { - isEnding = true; - - if (PlayState.instance.currentSong.id.toLowerCase() == 'senpai' - || PlayState.instance.currentSong.id.toLowerCase() == 'thorns') FlxG.sound.music.fadeOut(2.2, 0); - - new FlxTimer().start(0.2, function(tmr:FlxTimer) { - box.alpha -= 1 / 5; - bgFade.alpha -= 1 / 5 * 0.7; - portraitLeft.visible = false; - portraitRight.visible = false; - swagDialogue.alpha -= 1 / 5; - handSelect.alpha -= 1 / 5; - dropText.alpha = swagDialogue.alpha; - }, 5); - - new FlxTimer().start(1.2, function(tmr:FlxTimer) { - finishThing(); - kill(); - }); - } - } - else - { - dialogueList.remove(dialogueList[0]); - startDialogue(); - } - } - else if (FlxG.keys.justPressed.ANY && dialogueStarted) swagDialogue.skip(); - - super.update(elapsed); - } - - var isEnding:Bool = false; - - function startDialogue():Void - { - cleanDialog(); - // var theDialog:Alphabet = new Alphabet(0, 70, dialogueList[0], false, true); - // dialogue = theDialog; - // add(theDialog); - - // swagDialogue.text = ; - swagDialogue.resetText(dialogueList[0]); - swagDialogue.start(0.04); - swagDialogue.completeCallback = function() { - trace('dialogue finish'); - handSelect.visible = true; - dialogueEnded = true; - }; - handSelect.visible = false; - dialogueEnded = false; - - switch (curCharacter) - { - case 'dad': - portraitRight.visible = false; - if (!portraitLeft.visible) - { - portraitLeft.visible = true; - portraitLeft.animation.play('enter'); - } - case 'bf': - portraitLeft.visible = false; - if (!portraitRight.visible) - { - portraitRight.visible = true; - portraitRight.animation.play('enter'); - } - } - } - - function cleanDialog():Void - { - var splitName:Array<String> = dialogueList[0].split(':'); - curCharacter = splitName[1]; - dialogueList[0] = dialogueList[0].substr(splitName[1].length + 2).trim(); - } -} diff --git a/source/funkin/FlxSwf.hx b/source/funkin/FlxSwf.hx deleted file mode 100644 index d37343894..000000000 --- a/source/funkin/FlxSwf.hx +++ /dev/null @@ -1,43 +0,0 @@ -package funkin; - -import flixel.FlxCamera; -import flixel.FlxSprite; -import flixel.graphics.tile.FlxDrawBaseItem; -import openfl.display.MovieClip; - -class FlxSwf extends FlxSprite -{ - public var swf:MovieClip; - - public function new() - { - super(); - } - - override function draw() - { - for (camera in cameras) - { - if (!camera.visible || !camera.exists) continue; - - getScreenPosition(_point, camera).subtractPoint(offset); - // assume no render blit for now - // use camera.canvas - // camera.canvas.graphics. - } - } -} - -class FlxDrawSwfItem extends FlxDrawBaseItem<FlxDrawSwfItem> -{ - public function new() - { - super(); - type = FlxDrawItemType.TILES; - } - - override function render(camera:FlxCamera) - { - super.render(camera); - } -} diff --git a/source/funkin/Highscore.hx b/source/funkin/Highscore.hx index 3c9fd82e4..2c18ffa2d 100644 --- a/source/funkin/Highscore.hx +++ b/source/funkin/Highscore.hx @@ -1,5 +1,8 @@ package funkin; +/** + * A core class which handles tracking score and combo for the current song. + */ class Highscore { public static var tallies:Tallies = new Tallies(); diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 5299a3aa0..d74b5f639 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -1,5 +1,6 @@ package funkin; +import funkin.ui.transition.LoadingState; import flixel.FlxState; import flixel.addons.transition.FlxTransitionableState; import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond; @@ -10,7 +11,7 @@ import flixel.math.FlxRect; import flixel.FlxSprite; import flixel.system.debug.log.LogStyle; import flixel.util.FlxColor; -import funkin.ui.PreferencesMenu; +import funkin.ui.options.PreferencesMenu; import funkin.util.macro.MacroUtil; import funkin.util.WindowUtil; import funkin.play.PlayStatePlaylist; @@ -26,11 +27,13 @@ import funkin.play.stage.StageData.StageDataParser; import funkin.play.character.CharacterData.CharacterDataParser; import funkin.modding.module.ModuleHandler; import funkin.ui.title.TitleState; +import funkin.ui.transition.LoadingState; #if discord_rpc import Discord.DiscordClient; #end /** + * A core class which performs initialization of the game. * The initialization state has several functions: * - Calls code to set up the game, including loading saves and parsing game data. * - Chooses whether to start via debug or via launching normally. @@ -228,13 +231,13 @@ class InitState extends FlxState #elseif FREEPLAY // -DFREEPLAY FlxG.switchState(new FreeplayState()); #elseif ANIMATE // -DANIMATE - FlxG.switchState(new funkin.ui.animDebugShit.FlxAnimateTest()); + FlxG.switchState(new funkin.ui.debug.anim.FlxAnimateTest()); #elseif CHARTING // -DCHARTING FlxG.switchState(new funkin.ui.debug.charting.ChartEditorState()); #elseif STAGEBUILD // -DSTAGEBUILD - FlxG.switchState(new funkin.ui.stageBullshit.StageBuilderState()); + FlxG.switchState(new funkin.ui.debug.stage.StageBuilderState()); #elseif ANIMDEBUG // -DANIMDEBUG - FlxG.switchState(new funkin.ui.animDebugShit.DebugBoundingState()); + FlxG.switchState(new funkin.ui.debug.anim.DebugBoundingState()); #elseif LATENCY // -DLATENCY FlxG.switchState(new funkin.LatencyState()); #else diff --git a/source/funkin/MenuCharacter.hx b/source/funkin/MenuCharacter.hx deleted file mode 100644 index 3e05b9e9f..000000000 --- a/source/funkin/MenuCharacter.hx +++ /dev/null @@ -1,42 +0,0 @@ -package funkin; - -import flixel.FlxSprite; -import flixel.graphics.frames.FlxAtlasFrames; - -class MenuCharacter extends FlxSprite -{ - public var character:String; - - public function new(x:Float, character:String = 'bf') - { - super(x); - - this.character = character; - - var suffix:String = character; - - if (character != "darnell" && character != "nene") suffix = "characters"; - - var tex = Paths.getSparrowAtlas('campaign_menu_UI_' + suffix); - frames = tex; - - trace(character); - - animation.addByPrefix('bf', "BF idle dance white", 24); - animation.addByPrefix('bfConfirm', 'BF HEY!!', 24, false); - animation.addByPrefix('gf', "GF Dancing Beat WHITE", 24); - animation.addByPrefix('dad', "Dad idle dance BLACK LINE", 24); - animation.addByPrefix('spooky', "spooky dance idle BLACK LINES", 24); - animation.addByPrefix('pico', "Pico Idle Dance", 24); - animation.addByPrefix('mom', "Mom Idle BLACK LINES", 24); - animation.addByPrefix('parents-christmas', "Parent Christmas Idle", 24); - animation.addByPrefix('senpai', "SENPAI idle Black Lines", 24); - animation.addByPrefix('tankman', "Tankman Menu BLACK", 24); - animation.addByPrefix('darnell', "Darnell Black Lines To Scale", 24); - animation.addByPrefix('nene', "Nene Black Lines To Scale", 24); - // Parent Christmas Idle - - animation.play(character); - updateHitbox(); - } -} diff --git a/source/funkin/NoteSplash.hx b/source/funkin/NoteSplash.hx deleted file mode 100644 index 81b35b36d..000000000 --- a/source/funkin/NoteSplash.hx +++ /dev/null @@ -1,65 +0,0 @@ -package funkin; - -import flixel.FlxSprite; -import haxe.io.Path; -import flixel.graphics.frames.FlxAtlasFrames; - -class NoteSplash extends FlxSprite -{ - public function new(x:Float, y:Float, noteData:Int = 0):Void - { - super(x, y); - - animation.addByPrefix('note0-0', 'note impact 1 purple', 24, false); - animation.addByPrefix('note1-0', 'note impact 1 blue', 24, false); - animation.addByPrefix('note2-0', 'note impact 1 green', 24, false); - animation.addByPrefix('note3-0', 'note impact 1 red', 24, false); - animation.addByPrefix('note0-1', 'note impact 2 purple', 24, false); - animation.addByPrefix('note1-1', 'note impact 2 blue', 24, false); - animation.addByPrefix('note2-1', 'note impact 2 green', 24, false); - animation.addByPrefix('note3-1', 'note impact 2 red', 24, false); - - setupNoteSplash(x, y, noteData); - - // alpha = 0.75; - } - - public override function update(elapsed:Float):Void - { - super.update(elapsed); - - if (animation.finished) - { - kill(); - } - } - - public static function buildSplashFrames(force:Bool = false):FlxAtlasFrames - { - // static variables inside functions are a cool of Haxe 4.3.0. - static var splashFrames:FlxAtlasFrames = null; - - if (splashFrames != null && !force) return splashFrames; - - splashFrames = Paths.getSparrowAtlas('noteSplashes'); - - splashFrames.parent.persist = true; - - return splashFrames; - } - - public function setupNoteSplash(x:Float, y:Float, noteData:Int = 0) - { - setPosition(x, y); - alpha = 0.6; - - animation.play('note' + noteData + '-' + FlxG.random.int(0, 1), true); - animation.curAnim.frameRate = 24 + FlxG.random.int(-2, 2); - animation.finishCallback = function(name) { - kill(); - }; - updateHitbox(); - - offset.set(width * 0.3, height * 0.3); - } -} diff --git a/source/funkin/Options.hx b/source/funkin/Options.hx deleted file mode 100644 index bc8a98570..000000000 --- a/source/funkin/Options.hx +++ /dev/null @@ -1,6 +0,0 @@ -package funkin; - -class Options -{ - public static var masterVolume:Float = 1; -} diff --git a/source/funkin/Paths.hx b/source/funkin/Paths.hx index 07a15dae1..e0212e573 100644 --- a/source/funkin/Paths.hx +++ b/source/funkin/Paths.hx @@ -4,6 +4,9 @@ import flixel.graphics.frames.FlxAtlasFrames; import openfl.utils.AssetType; import openfl.utils.Assets as OpenFlAssets; +/** + * A core class which handles determining asset paths. + */ class Paths { static var currentLevel:String; diff --git a/source/funkin/PlayerSettings.hx b/source/funkin/PlayerSettings.hx index e97cfe384..0e728f57e 100644 --- a/source/funkin/PlayerSettings.hx +++ b/source/funkin/PlayerSettings.hx @@ -8,8 +8,9 @@ import flixel.input.actions.FlxActionInput; import flixel.input.gamepad.FlxGamepad; import flixel.util.FlxSignal; -// import ui.DeviceManager; -// import props.Player; +/** + * A core class which represents the current player(s) and their controls and other configuration. + */ class PlayerSettings { public static var numPlayers(default, null) = 0; diff --git a/source/funkin/Preferences.hx b/source/funkin/Preferences.hx index 7e3c3c6d7..6b0911ede 100644 --- a/source/funkin/Preferences.hx +++ b/source/funkin/Preferences.hx @@ -3,7 +3,7 @@ package funkin; import funkin.save.Save; /** - * A store of user-configurable, globally relevant values. + * A core class which provides a store of user-configurable, globally relevant values. */ class Preferences { diff --git a/source/funkin/TankCutscene.hx b/source/funkin/TankCutscene.hx deleted file mode 100644 index 4bc7349ad..000000000 --- a/source/funkin/TankCutscene.hx +++ /dev/null @@ -1,27 +0,0 @@ -package funkin; - -import flixel.FlxSprite; -import flixel.sound.FlxSound; - -class TankCutscene extends FlxSprite -{ - public var startSyncAudio:FlxSound; - - public function new(x:Float, y:Float) - { - super(x, y); - } - - var startedPlayingSound:Bool = false; - - override function update(elapsed:Float) - { - if (animation.curAnim.curFrame >= 1 && !startedPlayingSound) - { - startSyncAudio.play(); - startedPlayingSound = true; - } - - super.update(elapsed); - } -} diff --git a/source/funkin/Discord.hx b/source/funkin/api/discord/Discord.hx similarity index 98% rename from source/funkin/Discord.hx rename to source/funkin/api/discord/Discord.hx index d2cf12535..a4d65684e 100644 --- a/source/funkin/Discord.hx +++ b/source/funkin/api/discord/Discord.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.api.discord; import Sys.sleep; #if discord_rpc diff --git a/source/funkin/api/newgrounds/NGUtil.hx b/source/funkin/api/newgrounds/NGUtil.hx index ba7d5f916..c8289fc46 100644 --- a/source/funkin/api/newgrounds/NGUtil.hx +++ b/source/funkin/api/newgrounds/NGUtil.hx @@ -241,15 +241,3 @@ class NGUtil } #end } - -enum ConnectionResult -{ - /** Log in successful */ - Success; - - /** Could not login */ - Fail(msg:String); - - /** User cancelled the login */ - Cancelled; -} diff --git a/source/funkin/NGio.hx b/source/funkin/api/newgrounds/NGio.hx similarity index 99% rename from source/funkin/NGio.hx rename to source/funkin/api/newgrounds/NGio.hx index e5f60c8b5..e505bdedf 100644 --- a/source/funkin/NGio.hx +++ b/source/funkin/api/newgrounds/NGio.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.api.newgrounds; #if newgrounds import flixel.util.FlxSignal; diff --git a/source/funkin/api/newgrounds/README.md b/source/funkin/api/newgrounds/README.md index f61e1b0fd..09534fb71 100644 --- a/source/funkin/api/newgrounds/README.md +++ b/source/funkin/api/newgrounds/README.md @@ -6,4 +6,4 @@ This package contains two main classes: such as retrieving achievement status. - `NGUnsafe` contains sensitive utility functions for interacting with the Newgrounds API. - This includes any functions which scripts should not be able to use, - such as writing high scores or posting achievements. \ No newline at end of file + such as writing high scores or posting achievements. diff --git a/source/funkin/audiovis/ABot.hx b/source/funkin/audio/visualize/ABot.hx similarity index 85% rename from source/funkin/audiovis/ABot.hx rename to source/funkin/audio/visualize/ABot.hx index 11c123fb2..0b2ec619e 100644 --- a/source/funkin/audiovis/ABot.hx +++ b/source/funkin/audio/visualize/ABot.hx @@ -1,4 +1,4 @@ -package funkin.audiovis; +package funkin.audio.visualize; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; diff --git a/source/funkin/audiovis/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx similarity index 96% rename from source/funkin/audiovis/ABotVis.hx rename to source/funkin/audio/visualize/ABotVis.hx index 060bddcf7..681287808 100644 --- a/source/funkin/audiovis/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -1,12 +1,13 @@ -package funkin.audiovis; +package funkin.audio.visualize; -import funkin.audiovis.dsp.FFT; +import funkin.audio.visualize.dsp.FFT; import flixel.FlxSprite; import flixel.addons.plugin.taskManager.FlxTask; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import flixel.math.FlxMath; import flixel.sound.FlxSound; +import funkin.util.MathUtil; using Lambda; @@ -86,7 +87,7 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite> for (i in 0...group.members.length) { var getSliceShit = function(s:Int) { - var powShit = FlxMath.remapToRange(s, 0, group.members.length, 0, CoolUtil.coolBaseLog(10, freqShit[0].length)); + var powShit = FlxMath.remapToRange(s, 0, group.members.length, 0, MathUtil.logBase(10, freqShit[0].length)); return Math.round(Math.pow(10, powShit)); }; diff --git a/source/funkin/audio/visualize/PolygonSpectogram.hx b/source/funkin/audio/visualize/PolygonSpectogram.hx index 6b7e280ec..604bc910b 100644 --- a/source/funkin/audio/visualize/PolygonSpectogram.hx +++ b/source/funkin/audio/visualize/PolygonSpectogram.hx @@ -4,7 +4,7 @@ import flixel.math.FlxMath; import flixel.math.FlxPoint; import flixel.sound.FlxSound; import flixel.util.FlxColor; -import funkin.audiovis.VisShit; +import funkin.audio.visualize.VisShit; import funkin.graphics.rendering.MeshRender; import lime.utils.Int16Array; diff --git a/source/funkin/audiovis/SpectogramSprite.hx b/source/funkin/audio/visualize/SpectogramSprite.hx similarity index 98% rename from source/funkin/audiovis/SpectogramSprite.hx rename to source/funkin/audio/visualize/SpectogramSprite.hx index c4f8234eb..63d0fcd2e 100644 --- a/source/funkin/audiovis/SpectogramSprite.hx +++ b/source/funkin/audio/visualize/SpectogramSprite.hx @@ -1,4 +1,4 @@ -package funkin.audiovis; +package funkin.audio.visualize; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; @@ -8,8 +8,8 @@ import flixel.math.FlxVector; import flixel.sound.FlxSound; import flixel.util.FlxColor; import funkin.audio.visualize.PolygonSpectogram.VISTYPE; -import funkin.audiovis.VisShit.CurAudioInfo; -import funkin.audiovis.dsp.FFT; +import funkin.audio.visualize.VisShit.CurAudioInfo; +import funkin.audio.visualize.dsp.FFT; import haxe.Timer; import lime.system.ThreadPool; import lime.utils.Int16Array; diff --git a/source/funkin/audiovis/VisShit.hx b/source/funkin/audio/visualize/VisShit.hx similarity index 93% rename from source/funkin/audiovis/VisShit.hx rename to source/funkin/audio/visualize/VisShit.hx index ee531a977..5bfb8c7c5 100644 --- a/source/funkin/audiovis/VisShit.hx +++ b/source/funkin/audio/visualize/VisShit.hx @@ -1,11 +1,12 @@ -package funkin.audiovis; +package funkin.audio.visualize; import flixel.math.FlxMath; import flixel.sound.FlxSound; -import funkin.audiovis.dsp.FFT; +import funkin.audio.visualize.dsp.FFT; import haxe.Timer; import lime.system.ThreadPool; import lime.utils.Int16Array; +import funkin.util.MathUtil; using Lambda; @@ -42,7 +43,7 @@ class VisShit // helpers, note that spectrum indexes suppose non-negative frequencies final binSize = fs / fftN; final indexToFreq = function(k:Int) { - var powShit:Float = FlxMath.remapToRange(k, 0, halfN, 0, CoolUtil.coolBaseLog(10, halfN)); // 4.3 is almost the log of 20Khz or so. Close enuf lol + var powShit:Float = FlxMath.remapToRange(k, 0, halfN, 0, MathUtil.logBase(10, halfN)); // 4.3 is almost the log of 20Khz or so. Close enuf lol return 1.0 * (Math.pow(10, powShit)); // we need the `1.0` to avoid overflows }; diff --git a/source/funkin/audiovis/dsp/Complex.hx b/source/funkin/audio/visualize/dsp/Complex.hx similarity index 98% rename from source/funkin/audiovis/dsp/Complex.hx rename to source/funkin/audio/visualize/dsp/Complex.hx index 523549e99..37861bcc3 100644 --- a/source/funkin/audiovis/dsp/Complex.hx +++ b/source/funkin/audio/visualize/dsp/Complex.hx @@ -1,4 +1,4 @@ -package funkin.audiovis.dsp; +package funkin.audio.visualize.dsp; /** Complex number representation. diff --git a/source/funkin/audiovis/dsp/FFT.hx b/source/funkin/audio/visualize/dsp/FFT.hx similarity index 97% rename from source/funkin/audiovis/dsp/FFT.hx rename to source/funkin/audio/visualize/dsp/FFT.hx index d1d99140e..dc75acb81 100644 --- a/source/funkin/audiovis/dsp/FFT.hx +++ b/source/funkin/audio/visualize/dsp/FFT.hx @@ -1,9 +1,9 @@ -package funkin.audiovis.dsp; +package funkin.audio.visualize.dsp; -import funkin.audiovis.dsp.Complex; +import funkin.audio.visualize.dsp.Complex; -using funkin.audiovis.dsp.OffsetArray; -using funkin.audiovis.dsp.Signal; +using funkin.audio.visualize.dsp.OffsetArray; +using funkin.audio.visualize.dsp.Signal; // these are only used for testing, down in FFT.main() diff --git a/source/funkin/audiovis/dsp/OffsetArray.hx b/source/funkin/audio/visualize/dsp/OffsetArray.hx similarity index 98% rename from source/funkin/audiovis/dsp/OffsetArray.hx rename to source/funkin/audio/visualize/dsp/OffsetArray.hx index bd066a727..c8a5c27c3 100644 --- a/source/funkin/audiovis/dsp/OffsetArray.hx +++ b/source/funkin/audio/visualize/dsp/OffsetArray.hx @@ -1,4 +1,4 @@ -package funkin.audiovis.dsp; +package funkin.audio.visualize.dsp; /** A view into an Array with an indexing offset. diff --git a/source/funkin/audiovis/dsp/Signal.hx b/source/funkin/audio/visualize/dsp/Signal.hx similarity index 98% rename from source/funkin/audiovis/dsp/Signal.hx rename to source/funkin/audio/visualize/dsp/Signal.hx index 1f7cc6114..4557dc199 100644 --- a/source/funkin/audiovis/dsp/Signal.hx +++ b/source/funkin/audio/visualize/dsp/Signal.hx @@ -1,4 +1,4 @@ -package funkin.audiovis.dsp; +package funkin.audio.visualize.dsp; using Lambda; diff --git a/source/funkin/shaderslmfao/AngleMask.hx b/source/funkin/graphics/shaders/AngleMask.hx similarity index 96% rename from source/funkin/shaderslmfao/AngleMask.hx rename to source/funkin/graphics/shaders/AngleMask.hx index b9188201b..30e508a58 100644 --- a/source/funkin/shaderslmfao/AngleMask.hx +++ b/source/funkin/graphics/shaders/AngleMask.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.system.FlxAssets.FlxShader; diff --git a/source/funkin/shaderslmfao/BlendModeEffect.hx b/source/funkin/graphics/shaders/BlendModeEffect.hx similarity index 95% rename from source/funkin/shaderslmfao/BlendModeEffect.hx rename to source/funkin/graphics/shaders/BlendModeEffect.hx index 8fe98f70a..bf2246795 100644 --- a/source/funkin/shaderslmfao/BlendModeEffect.hx +++ b/source/funkin/graphics/shaders/BlendModeEffect.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.util.FlxColor; import openfl.display.ShaderParameter; diff --git a/source/funkin/shaderslmfao/BlendModesShader.hx b/source/funkin/graphics/shaders/BlendModesShader.hx similarity index 92% rename from source/funkin/shaderslmfao/BlendModesShader.hx rename to source/funkin/graphics/shaders/BlendModesShader.hx index 6807a65c0..acd2c1586 100644 --- a/source/funkin/shaderslmfao/BlendModesShader.hx +++ b/source/funkin/graphics/shaders/BlendModesShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; import funkin.Paths; diff --git a/source/funkin/shaderslmfao/ColorSwap.hx b/source/funkin/graphics/shaders/ColorSwap.hx similarity index 99% rename from source/funkin/shaderslmfao/ColorSwap.hx rename to source/funkin/graphics/shaders/ColorSwap.hx index 2c1f5664b..1be4d5429 100644 --- a/source/funkin/shaderslmfao/ColorSwap.hx +++ b/source/funkin/graphics/shaders/ColorSwap.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.system.FlxAssets.FlxShader; import flixel.util.FlxColor; diff --git a/source/funkin/shaderslmfao/GaussianBlurShader.hx b/source/funkin/graphics/shaders/GaussianBlurShader.hx similarity index 93% rename from source/funkin/shaderslmfao/GaussianBlurShader.hx rename to source/funkin/graphics/shaders/GaussianBlurShader.hx index ad472ac31..81167655b 100644 --- a/source/funkin/shaderslmfao/GaussianBlurShader.hx +++ b/source/funkin/graphics/shaders/GaussianBlurShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; import funkin.Paths; diff --git a/source/funkin/shaderslmfao/Grayscale.hx b/source/funkin/graphics/shaders/Grayscale.hx similarity index 92% rename from source/funkin/shaderslmfao/Grayscale.hx rename to source/funkin/graphics/shaders/Grayscale.hx index 016d64b46..6673ace24 100644 --- a/source/funkin/shaderslmfao/Grayscale.hx +++ b/source/funkin/graphics/shaders/Grayscale.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; import funkin.Paths; diff --git a/source/funkin/shaderslmfao/HSVShader.hx b/source/funkin/graphics/shaders/HSVShader.hx similarity index 96% rename from source/funkin/shaderslmfao/HSVShader.hx rename to source/funkin/graphics/shaders/HSVShader.hx index 066a49c96..733bbca7f 100644 --- a/source/funkin/shaderslmfao/HSVShader.hx +++ b/source/funkin/graphics/shaders/HSVShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; import funkin.Paths; diff --git a/source/funkin/shaderslmfao/LeftMaskShader.hx b/source/funkin/graphics/shaders/LeftMaskShader.hx similarity index 97% rename from source/funkin/shaderslmfao/LeftMaskShader.hx rename to source/funkin/graphics/shaders/LeftMaskShader.hx index e921a7f2b..f82a5c208 100644 --- a/source/funkin/shaderslmfao/LeftMaskShader.hx +++ b/source/funkin/graphics/shaders/LeftMaskShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.math.FlxRect; import flixel.system.FlxAssets.FlxShader; diff --git a/source/funkin/shaderslmfao/MultiplyShader.hx b/source/funkin/graphics/shaders/MultiplyShader.hx similarity index 94% rename from source/funkin/shaderslmfao/MultiplyShader.hx rename to source/funkin/graphics/shaders/MultiplyShader.hx index 2868982a2..5fe95f04e 100644 --- a/source/funkin/shaderslmfao/MultiplyShader.hx +++ b/source/funkin/graphics/shaders/MultiplyShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.system.FlxAssets.FlxShader; diff --git a/source/funkin/shaderslmfao/OverlayBlend.hx b/source/funkin/graphics/shaders/OverlayBlend.hx similarity index 97% rename from source/funkin/shaderslmfao/OverlayBlend.hx rename to source/funkin/graphics/shaders/OverlayBlend.hx index 8845a3b55..e44f3152a 100644 --- a/source/funkin/shaderslmfao/OverlayBlend.hx +++ b/source/funkin/graphics/shaders/OverlayBlend.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.math.FlxPoint; import flixel.system.FlxAssets.FlxShader; diff --git a/source/funkin/shaderslmfao/PureColor.hx b/source/funkin/graphics/shaders/PureColor.hx similarity index 96% rename from source/funkin/shaderslmfao/PureColor.hx rename to source/funkin/graphics/shaders/PureColor.hx index 767a29d0d..1d2216a8c 100644 --- a/source/funkin/shaderslmfao/PureColor.hx +++ b/source/funkin/graphics/shaders/PureColor.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.system.FlxAssets.FlxShader; import flixel.util.FlxColor; diff --git a/source/funkin/shaderslmfao/ScreenWipeShader.hx b/source/funkin/graphics/shaders/ScreenWipeShader.hx similarity index 98% rename from source/funkin/shaderslmfao/ScreenWipeShader.hx rename to source/funkin/graphics/shaders/ScreenWipeShader.hx index 1aeb069ba..bc45f0ef6 100644 --- a/source/funkin/shaderslmfao/ScreenWipeShader.hx +++ b/source/funkin/graphics/shaders/ScreenWipeShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.system.FlxAssets.FlxShader; diff --git a/source/funkin/shaderslmfao/StrokeShader.hx b/source/funkin/graphics/shaders/StrokeShader.hx similarity index 98% rename from source/funkin/shaderslmfao/StrokeShader.hx rename to source/funkin/graphics/shaders/StrokeShader.hx index 38dc41636..fd133ac0a 100644 --- a/source/funkin/shaderslmfao/StrokeShader.hx +++ b/source/funkin/graphics/shaders/StrokeShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.system.FlxAssets.FlxShader; import flixel.util.FlxColor; diff --git a/source/funkin/shaderslmfao/TitleOutline.hx b/source/funkin/graphics/shaders/TitleOutline.hx similarity index 98% rename from source/funkin/shaderslmfao/TitleOutline.hx rename to source/funkin/graphics/shaders/TitleOutline.hx index 9a849f795..db60fc3ae 100644 --- a/source/funkin/shaderslmfao/TitleOutline.hx +++ b/source/funkin/graphics/shaders/TitleOutline.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.math.FlxPoint; import flixel.system.FlxAssets.FlxShader; diff --git a/source/funkin/shaderslmfao/WaveShader.hx b/source/funkin/graphics/shaders/WaveShader.hx similarity index 90% rename from source/funkin/shaderslmfao/WaveShader.hx rename to source/funkin/graphics/shaders/WaveShader.hx index 89171b089..8738cc405 100644 --- a/source/funkin/shaderslmfao/WaveShader.hx +++ b/source/funkin/graphics/shaders/WaveShader.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.system.FlxAssets.FlxShader; diff --git a/source/funkin/shaderslmfao/WiggleEffectRuntime.hx b/source/funkin/graphics/shaders/WiggleEffectRuntime.hx similarity index 98% rename from source/funkin/shaderslmfao/WiggleEffectRuntime.hx rename to source/funkin/graphics/shaders/WiggleEffectRuntime.hx index 23f93b672..a04941df5 100644 --- a/source/funkin/shaderslmfao/WiggleEffectRuntime.hx +++ b/source/funkin/graphics/shaders/WiggleEffectRuntime.hx @@ -1,4 +1,4 @@ -package funkin.shaderslmfao; +package funkin.graphics.shaders; import flixel.addons.display.FlxRuntimeShader; import openfl.Assets; diff --git a/source/funkin/input/TurboKeyHandler.hx b/source/funkin/input/TurboKeyHandler.hx index 099d373b4..36b8e2087 100644 --- a/source/funkin/input/TurboKeyHandler.hx +++ b/source/funkin/input/TurboKeyHandler.hx @@ -108,8 +108,7 @@ class TurboKeyHandler extends FlxBasic * @param repeatDelay How long to wait between repeats. * @return A TurboKeyHandler */ - public static overload inline extern function build(inputKeys:Array<FlxKey>, ?delay:Float = DEFAULT_DELAY, - ?interval:Float = DEFAULT_INTERVAL):TurboKeyHandler + public static overload inline extern function build(inputKeys:Array<FlxKey>, ?delay:Float = DEFAULT_DELAY, ?interval:Float = DEFAULT_INTERVAL):TurboKeyHandler { return new TurboKeyHandler(inputKeys, delay, interval); } diff --git a/source/funkin/modding/base/ScriptedMusicBeatState.hx b/source/funkin/modding/base/ScriptedMusicBeatState.hx index 782e4d0b8..6dc6826c4 100644 --- a/source/funkin/modding/base/ScriptedMusicBeatState.hx +++ b/source/funkin/modding/base/ScriptedMusicBeatState.hx @@ -5,4 +5,4 @@ package funkin.modding.base; * Create a scripted class that extends MusicBeatState to use this. */ @:hscriptClass -class ScriptedMusicBeatState extends funkin.MusicBeatState implements HScriptedClass {} +class ScriptedMusicBeatState extends funkin.ui.MusicBeatState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedMusicBeatSubState.hx b/source/funkin/modding/base/ScriptedMusicBeatSubState.hx index 7dab3d7dd..79c98ea3f 100644 --- a/source/funkin/modding/base/ScriptedMusicBeatSubState.hx +++ b/source/funkin/modding/base/ScriptedMusicBeatSubState.hx @@ -5,4 +5,4 @@ package funkin.modding.base; * Create a scripted class that extends MusicBeatSubState to use this. */ @:hscriptClass -class ScriptedMusicBeatSubState extends funkin.MusicBeatSubState implements HScriptedClass {} +class ScriptedMusicBeatSubState extends funkin.ui.MusicBeatSubState implements HScriptedClass {} diff --git a/source/funkin/play/Fighter.hx b/source/funkin/play/Fighter.hx deleted file mode 100644 index 691d21b83..000000000 --- a/source/funkin/play/Fighter.hx +++ /dev/null @@ -1,68 +0,0 @@ -package funkin.play; - -import funkin.play.character.BaseCharacter; -import flixel.FlxSprite; - -class Fighter extends BaseCharacter -{ - public function new(?x:Float = 0, ?y:Float = 0, ?char:String = "pico-fighter") - { - super(char, Custom); - this.x = x; - this.y = y; - - animation.finishCallback = function(anim:String) { - switch anim - { - case "punch low" | "punch high" | "block" | 'dodge': - dance(true); - } - }; - } - - public var actions:Array<ACTIONS> = [PUNCH, BLOCK, DODGE]; - - public function doSomething(?forceAction:ACTIONS) - { - var daAction:ACTIONS = FlxG.random.getObject(actions); - - if (forceAction != null) daAction = forceAction; - - switch (daAction) - { - case PUNCH: - punch(); - case BLOCK: - block(); - case DODGE: - dodge(); - } - } - - public var curAction:ACTIONS = DODGE; - - function dodge() - { - playAnimation('dodge'); - curAction = DODGE; - } - - public function block() - { - playAnimation('block'); - curAction = BLOCK; - } - - public function punch() - { - curAction = PUNCH; - playAnimation('punch ' + (FlxG.random.bool() ? "low" : "high")); - } -} - -enum ACTIONS -{ - DODGE; - BLOCK; - PUNCH; -} diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index c5d9b4b0b..6eb53e2d5 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -7,9 +7,11 @@ import flixel.sound.FlxSound; import funkin.ui.story.StoryMenuState; import flixel.util.FlxColor; import flixel.util.FlxTimer; +import funkin.ui.MusicBeatSubState; import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEventDispatcher; import funkin.play.PlayState; +import funkin.ui.freeplay.FreeplayState; import funkin.play.character.BaseCharacter; /** diff --git a/source/funkin/GitarooPause.hx b/source/funkin/play/GitarooPause.hx similarity index 96% rename from source/funkin/GitarooPause.hx rename to source/funkin/play/GitarooPause.hx index a4dc766be..dbfbf5961 100644 --- a/source/funkin/GitarooPause.hx +++ b/source/funkin/play/GitarooPause.hx @@ -1,9 +1,11 @@ -package funkin; +package funkin.play; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import funkin.play.PlayState; +import funkin.ui.MusicBeatState; import flixel.addons.transition.FlxTransitionableState; +import funkin.ui.mainmenu.MainMenuState; class GitarooPause extends MusicBeatState { diff --git a/source/funkin/PauseSubState.hx b/source/funkin/play/PauseSubState.hx similarity index 97% rename from source/funkin/PauseSubState.hx rename to source/funkin/play/PauseSubState.hx index 2ce9abf65..f5555b66e 100644 --- a/source/funkin/PauseSubState.hx +++ b/source/funkin/play/PauseSubState.hx @@ -1,9 +1,10 @@ -package funkin; +package funkin.play; import funkin.play.PlayStatePlaylist; import flixel.FlxSprite; import flixel.addons.transition.FlxTransitionableState; import flixel.group.FlxGroup.FlxTypedGroup; +import funkin.ui.MusicBeatSubState; import flixel.sound.FlxSound; import flixel.text.FlxText; import flixel.tweens.FlxEase; @@ -11,6 +12,7 @@ import flixel.tweens.FlxTween; import flixel.util.FlxColor; import funkin.play.PlayState; import funkin.data.song.SongRegistry; +import funkin.ui.Alphabet; class PauseSubState extends MusicBeatSubState { @@ -231,11 +233,11 @@ class PauseSubState extends MusicBeatSubState if (PlayStatePlaylist.isStoryMode) { - openSubState(new funkin.ui.StickerSubState(null, STORY)); + openSubState(new funkin.ui.transition.StickerSubState(null, STORY)); } else { - openSubState(new funkin.ui.StickerSubState(null, FREEPLAY)); + openSubState(new funkin.ui.transition.StickerSubState(null, FREEPLAY)); } case 'Exit to Chart Editor': diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 4542b9f98..c1e62146b 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1,5 +1,6 @@ package funkin.play; +import funkin.ui.SwagCamera; import flixel.addons.transition.FlxTransitionableSubState; import funkin.ui.debug.charting.ChartEditorState; import haxe.Int64; @@ -16,19 +17,24 @@ import flixel.FlxState; import flixel.FlxSubState; import flixel.input.keyboard.FlxKey; import flixel.math.FlxMath; +import funkin.play.components.ComboMilestone; import flixel.math.FlxPoint; +import funkin.play.components.HealthIcon; +import funkin.ui.MusicBeatSubState; import flixel.math.FlxRect; import flixel.text.FlxText; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.ui.FlxBar; import flixel.util.FlxColor; +import funkin.api.newgrounds.NGio; import flixel.util.FlxTimer; import funkin.audio.VoicesGroup; import funkin.save.Save; import funkin.Highscore.Tallies; import funkin.input.PreciseInputManager; import funkin.modding.events.ScriptEvent; +import funkin.ui.mainmenu.MainMenuState; import funkin.modding.events.ScriptEventDispatcher; import funkin.play.character.BaseCharacter; import funkin.play.character.CharacterData.CharacterDataParser; @@ -42,7 +48,6 @@ import funkin.play.notes.NoteDirection; import funkin.play.notes.Strumline; import funkin.play.notes.SustainTrail; import funkin.play.scoring.Scoring; -import funkin.NoteSplash; import funkin.play.song.Song; import funkin.data.song.SongRegistry; import funkin.data.song.SongData.SongEventData; @@ -50,9 +55,10 @@ import funkin.data.song.SongData.SongNoteData; import funkin.data.song.SongData.SongCharacterData; import funkin.play.stage.Stage; import funkin.play.stage.StageData.StageDataParser; -import funkin.ui.PopUpStuff; -import funkin.ui.PreferencesMenu; -import funkin.ui.stageBuildShit.StageOffsetSubState; +import funkin.ui.transition.LoadingState; +import funkin.play.components.PopUpStuff; +import funkin.ui.options.PreferencesMenu; +import funkin.ui.debug.stage.StageOffsetSubState; import funkin.ui.story.StoryMenuState; import funkin.util.SerializerUtil; import funkin.util.SortUtil; @@ -510,8 +516,6 @@ class PlayState extends MusicBeatSubState } instance = this; - NoteSplash.buildSplashFrames(); - if (!assertChartExists()) return; if (false) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 3f7231c2a..507fa1236 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -8,16 +8,18 @@ import flixel.graphics.frames.FlxAtlasFrames; import flixel.graphics.frames.FlxBitmapFont; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxPoint; +import funkin.ui.MusicBeatSubState; import flixel.math.FlxRect; import flixel.text.FlxBitmapText; import flixel.text.FlxText; import flixel.tweens.FlxEase; +import funkin.ui.freeplay.FreeplayState; import flixel.tweens.FlxTween; import flixel.util.FlxColor; import flixel.util.FlxGradient; import flixel.util.FlxTimer; -import funkin.shaderslmfao.LeftMaskShader; -import funkin.ui.TallyCounter; +import funkin.graphics.shaders.LeftMaskShader; +import funkin.play.components.TallyCounter; import flxanimate.FlxAnimate.Settings; class ResultState extends MusicBeatSubState diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index 588b5663d..7ad0892f6 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -58,7 +58,7 @@ class BaseCharacter extends Bopper */ public var dropNoteCounts(default, null):Array<Int>; - @:allow(funkin.ui.animDebugShit.DebugBoundingState) + @:allow(funkin.ui.debug.anim.DebugBoundingState) final _data:CharacterData; final singTimeSec:Float; diff --git a/source/funkin/ComboMilestone.hx b/source/funkin/play/components/ComboMilestone.hx similarity index 98% rename from source/funkin/ComboMilestone.hx rename to source/funkin/play/components/ComboMilestone.hx index 79e454c44..54d1438f1 100644 --- a/source/funkin/ComboMilestone.hx +++ b/source/funkin/play/components/ComboMilestone.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.play.components; import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; diff --git a/source/funkin/play/HealthIcon.hx b/source/funkin/play/components/HealthIcon.hx similarity index 98% rename from source/funkin/play/HealthIcon.hx rename to source/funkin/play/components/HealthIcon.hx index 958933df8..0d90df5a0 100644 --- a/source/funkin/play/HealthIcon.hx +++ b/source/funkin/play/components/HealthIcon.hx @@ -1,4 +1,4 @@ -package funkin.play; +package funkin.play.components; import funkin.play.character.CharacterData; import flixel.FlxSprite; @@ -6,6 +6,7 @@ import flixel.math.FlxMath; import flixel.math.FlxPoint; import funkin.play.character.CharacterData.CharacterDataParser; import openfl.utils.Assets; +import funkin.util.MathUtil; /** * This is a rework of the health icon with the following changes: @@ -201,19 +202,19 @@ class HealthIcon extends FlxSprite if (this.width > this.height) { // Apply linear interpolation while accounting for frame rate. - var targetSize:Int = Std.int(CoolUtil.coolLerp(this.width, HEALTH_ICON_SIZE * this.size.x, 0.15)); + var targetSize:Int = Std.int(MathUtil.coolLerp(this.width, HEALTH_ICON_SIZE * this.size.x, 0.15)); setGraphicSize(targetSize, 0); } else { - var targetSize:Int = Std.int(CoolUtil.coolLerp(this.height, HEALTH_ICON_SIZE * this.size.y, 0.15)); + var targetSize:Int = Std.int(MathUtil.coolLerp(this.height, HEALTH_ICON_SIZE * this.size.y, 0.15)); setGraphicSize(0, targetSize); } // Lerp the health icon back to its normal angle. - this.angle = CoolUtil.coolLerp(this.angle, 0, 0.15); + this.angle = MathUtil.coolLerp(this.angle, 0, 0.15); this.updateHitbox(); } diff --git a/source/funkin/ui/PopUpStuff.hx b/source/funkin/play/components/PopUpStuff.hx similarity index 99% rename from source/funkin/ui/PopUpStuff.hx rename to source/funkin/play/components/PopUpStuff.hx index 75fc87c8b..38a6ec15a 100644 --- a/source/funkin/ui/PopUpStuff.hx +++ b/source/funkin/play/components/PopUpStuff.hx @@ -1,4 +1,4 @@ -package funkin.ui; +package funkin.play.components; import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; diff --git a/source/funkin/ui/TallyCounter.hx b/source/funkin/play/components/TallyCounter.hx similarity index 94% rename from source/funkin/ui/TallyCounter.hx rename to source/funkin/play/components/TallyCounter.hx index 72857671e..77e6ef4ec 100644 --- a/source/funkin/ui/TallyCounter.hx +++ b/source/funkin/play/components/TallyCounter.hx @@ -1,4 +1,4 @@ -package funkin.ui; +package funkin.play.components; import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; @@ -8,7 +8,7 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; /** - * Similar to ComboCounter, but it's not! + * Numerical counters used next to each judgement in the Results screen. */ class TallyCounter extends FlxTypedSpriteGroup<FlxSprite> { diff --git a/source/funkin/play/cutscene/dialogue/ConversationDebugState.hx b/source/funkin/play/cutscene/dialogue/ConversationDebugState.hx index 70ac011a2..13697b9f4 100644 --- a/source/funkin/play/cutscene/dialogue/ConversationDebugState.hx +++ b/source/funkin/play/cutscene/dialogue/ConversationDebugState.hx @@ -4,6 +4,7 @@ import flixel.FlxState; import funkin.modding.events.ScriptEventDispatcher; import funkin.modding.events.ScriptEvent; import flixel.util.FlxColor; +import funkin.ui.MusicBeatState; /** * A state with displays a conversation with no background. diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 60b995c06..369a4144a 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -12,7 +12,7 @@ import funkin.play.notes.NoteSplash; import funkin.play.notes.NoteSprite; import funkin.play.notes.SustainTrail; import funkin.data.song.SongData.SongNoteData; -import funkin.ui.PreferencesMenu; +import funkin.ui.options.PreferencesMenu; import funkin.util.SortUtil; /** diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index f55799828..ab4bf5f16 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -8,7 +8,7 @@ import flixel.FlxSprite; import flixel.graphics.FlxGraphic; import flixel.graphics.tile.FlxDrawTrianglesItem; import flixel.math.FlxMath; -import funkin.ui.PreferencesMenu; +import funkin.ui.options.PreferencesMenu; /** * This is based heavily on the `FlxStrip` class. It uses `drawTriangles()` to clip a sustain note diff --git a/source/funkin/play/stage/Bopper.hx b/source/funkin/play/stage/Bopper.hx index 187b5ec32..1bc0632f9 100644 --- a/source/funkin/play/stage/Bopper.hx +++ b/source/funkin/play/stage/Bopper.hx @@ -85,7 +85,7 @@ class Bopper extends StageProp implements IPlayStateScriptedClass return globalOffsets = value; } - @:allow(funkin.ui.animDebugShit.DebugBoundingState) + @:allow(funkin.ui.debug.anim.DebugBoundingState) var animOffsets(default, set):Array<Float> = [0, 0]; public var originalPosition:FlxPoint = new FlxPoint(0, 0); diff --git a/source/funkin/Alphabet.hx b/source/funkin/ui/Alphabet.hx similarity index 97% rename from source/funkin/Alphabet.hx rename to source/funkin/ui/Alphabet.hx index 45e9a2aee..66b95f5b8 100644 --- a/source/funkin/Alphabet.hx +++ b/source/funkin/ui/Alphabet.hx @@ -1,9 +1,10 @@ -package funkin; +package funkin.ui; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup; import flixel.math.FlxMath; import flixel.util.FlxTimer; +import funkin.util.MathUtil; /** * Loosley based on FlxTypeText lolol @@ -151,7 +152,6 @@ class Alphabet extends FlxSpriteGroup if (AlphaCharacter.alphabet.indexOf(splitWords[loopNum].toLowerCase()) != -1 || isNumber || isSymbol) // if (AlphaCharacter.alphabet.contains(splitWords[loopNum].toLowerCase()) || isNumber || isSymbol) - { if (lastSprite != null && !xPosResetted) { @@ -220,8 +220,8 @@ class Alphabet extends FlxSpriteGroup { var scaledY = FlxMath.remapToRange(targetY, 0, 1, 0, 1.3); - y = CoolUtil.coolLerp(y, (scaledY * 120) + (FlxG.height * 0.48), 0.16); - x = CoolUtil.coolLerp(x, (targetY * 20) + 90, 0.16); + y = MathUtil.coolLerp(y, (scaledY * 120) + (FlxG.height * 0.48), 0.16); + x = MathUtil.coolLerp(x, (targetY * 20) + 90, 0.16); } super.update(elapsed); diff --git a/source/funkin/ui/AtlasMenuList.hx b/source/funkin/ui/AtlasMenuList.hx index 028a00eef..efff6da93 100644 --- a/source/funkin/ui/AtlasMenuList.hx +++ b/source/funkin/ui/AtlasMenuList.hx @@ -38,7 +38,7 @@ class AtlasMenuList extends MenuTypedList<AtlasMenuItem> /** * A menu list item which uses single texture atlas. */ -class AtlasMenuItem extends MenuItem +class AtlasMenuItem extends MenuListItem { var atlas:FlxAtlasFrames; diff --git a/source/funkin/MenuItem.hx b/source/funkin/ui/MenuItem.hx similarity index 93% rename from source/funkin/MenuItem.hx rename to source/funkin/ui/MenuItem.hx index 261092a1a..ba5cc066b 100644 --- a/source/funkin/MenuItem.hx +++ b/source/funkin/ui/MenuItem.hx @@ -1,9 +1,10 @@ -package funkin; +package funkin.ui; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup; import flixel.math.FlxMath; +import funkin.util.MathUtil; import flixel.util.FlxColor; class MenuItem extends FlxSpriteGroup @@ -44,7 +45,7 @@ class MenuItem extends FlxSpriteGroup override function update(elapsed:Float) { super.update(elapsed); - y = CoolUtil.coolLerp(y, (targetY * 120) + 480, 0.17); + y = MathUtil.coolLerp(y, (targetY * 120) + 480, 0.17); if (isFlashing) flashingInt += 1; diff --git a/source/funkin/ui/MenuList.hx b/source/funkin/ui/MenuList.hx index f1de8d40e..3ffe3c330 100644 --- a/source/funkin/ui/MenuList.hx +++ b/source/funkin/ui/MenuList.hx @@ -6,7 +6,7 @@ import flixel.group.FlxGroup; import flixel.math.FlxPoint; import flixel.util.FlxSignal; -class MenuTypedList<T:MenuItem> extends FlxTypedGroup<T> +class MenuTypedList<T:MenuListItem> extends FlxTypedGroup<T> { public var selectedIndex(default, null) = 0; public var selectedItem(get, never):T; @@ -206,7 +206,7 @@ class MenuTypedList<T:MenuItem> extends FlxTypedGroup<T> } } -class MenuItem extends FlxSprite +class MenuListItem extends FlxSprite { public var callback:Void->Void; public var name:String; @@ -261,7 +261,7 @@ class MenuItem extends FlxSprite } } -class MenuTypedItem<T:FlxSprite> extends MenuItem +class MenuTypedItem<T:FlxSprite> extends MenuListItem { public var label(default, set):T; diff --git a/source/funkin/MusicBeatState.hx b/source/funkin/ui/MusicBeatState.hx similarity index 98% rename from source/funkin/MusicBeatState.hx rename to source/funkin/ui/MusicBeatState.hx index 9861c48c7..6d592f438 100644 --- a/source/funkin/MusicBeatState.hx +++ b/source/funkin/ui/MusicBeatState.hx @@ -1,6 +1,7 @@ -package funkin; +package funkin.ui; import funkin.modding.IScriptedClass.IEventHandler; +import funkin.ui.mainmenu.MainMenuState; import flixel.FlxState; import flixel.FlxSubState; import flixel.addons.transition.FlxTransitionableState; diff --git a/source/funkin/MusicBeatSubState.hx b/source/funkin/ui/MusicBeatSubState.hx similarity index 98% rename from source/funkin/MusicBeatSubState.hx rename to source/funkin/ui/MusicBeatSubState.hx index 53fe19bdd..c4eedc7c6 100644 --- a/source/funkin/MusicBeatSubState.hx +++ b/source/funkin/ui/MusicBeatSubState.hx @@ -1,8 +1,9 @@ -package funkin; +package funkin.ui; import flixel.addons.transition.FlxTransitionableSubState; import flixel.FlxSubState; import flixel.text.FlxText; +import funkin.ui.mainmenu.MainMenuState; import flixel.util.FlxColor; import funkin.modding.events.ScriptEvent; import funkin.modding.IScriptedClass.IEventHandler; diff --git a/source/funkin/SwagCamera.hx b/source/funkin/ui/SwagCamera.hx similarity index 87% rename from source/funkin/SwagCamera.hx rename to source/funkin/ui/SwagCamera.hx index 386eaea62..70791d38f 100644 --- a/source/funkin/SwagCamera.hx +++ b/source/funkin/ui/SwagCamera.hx @@ -1,8 +1,9 @@ -package funkin; +package funkin.ui; import flixel.FlxCamera; import flixel.FlxSprite; import flixel.math.FlxPoint; +import funkin.util.MathUtil; class SwagCamera extends FlxCamera { @@ -92,10 +93,10 @@ class SwagCamera extends FlxCamera else { // THIS THE PART THAT ACTUALLY MATTERS LOL - scroll.x = CoolUtil.coolLerp(scroll.x, _scrollTarget.x, followLerp); - scroll.y = CoolUtil.coolLerp(scroll.y, _scrollTarget.y, followLerp); - // scroll.x += (_scrollTarget.x - scroll.x) * CoolUtil.camLerpShit(followLerp); - // scroll.y += (_scrollTarget.y - scroll.y) * CoolUtil.camLerpShit(followLerp); + scroll.x = MathUtil.coolLerp(scroll.x, _scrollTarget.x, followLerp); + scroll.y = MathUtil.coolLerp(scroll.y, _scrollTarget.y, followLerp); + // scroll.x += (_scrollTarget.x - scroll.x) * MathUtil.cameraLerp(followLerp); + // scroll.y += (_scrollTarget.y - scroll.y) * MathUtil.cameraLerp(followLerp); } } } diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 7ef4cb238..ef02a802e 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -3,9 +3,10 @@ package funkin.ui.debug; import flixel.math.FlxPoint; import flixel.FlxObject; import flixel.FlxSprite; -import funkin.MusicBeatSubState; +import funkin.ui.MusicBeatSubState; import funkin.ui.TextMenuList; import funkin.ui.debug.charting.ChartEditorState; +import funkin.ui.MusicBeatSubState; class DebugMenuSubState extends MusicBeatSubState { @@ -85,13 +86,13 @@ class DebugMenuSubState extends MusicBeatSubState function openAnimationEditor() { - FlxG.switchState(new funkin.ui.animDebugShit.DebugBoundingState()); + FlxG.switchState(new funkin.ui.debug.anim.DebugBoundingState()); trace('Animation Editor'); } function testStickers() { - openSubState(new funkin.ui.StickerSubState()); + openSubState(new funkin.ui.transition.StickerSubState()); trace('opened stickers'); } diff --git a/source/funkin/MemoryCounter.hx b/source/funkin/ui/debug/MemoryCounter.hx similarity index 97% rename from source/funkin/MemoryCounter.hx rename to source/funkin/ui/debug/MemoryCounter.hx index 658febe59..312d853e7 100644 --- a/source/funkin/MemoryCounter.hx +++ b/source/funkin/ui/debug/MemoryCounter.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.ui.debug; import openfl.text.TextFormat; import openfl.system.System; diff --git a/source/funkin/ui/animDebugShit/DebugBoundingState.hx b/source/funkin/ui/debug/anim/DebugBoundingState.hx similarity index 98% rename from source/funkin/ui/animDebugShit/DebugBoundingState.hx rename to source/funkin/ui/debug/anim/DebugBoundingState.hx index 297c44e8e..4e06913b4 100644 --- a/source/funkin/ui/animDebugShit/DebugBoundingState.hx +++ b/source/funkin/ui/debug/anim/DebugBoundingState.hx @@ -1,4 +1,4 @@ -package funkin.ui.animDebugShit; +package funkin.ui.debug.anim; import funkin.util.SerializerUtil; import funkin.play.character.CharacterData; @@ -15,6 +15,7 @@ import flixel.math.FlxPoint; import flixel.sound.FlxSound; import flixel.text.FlxText; import flixel.util.FlxColor; +import funkin.util.MouseUtil; import flixel.util.FlxSpriteUtil; import flixel.util.FlxTimer; import funkin.play.character.BaseCharacter; @@ -25,6 +26,7 @@ import haxe.ui.components.DropDown; import haxe.ui.core.Component; import haxe.ui.events.ItemEvent; import haxe.ui.events.UIEvent; +import funkin.ui.mainmenu.MainMenuState; import lime.utils.Assets as LimeAssets; import openfl.Assets; import openfl.events.Event; @@ -32,6 +34,7 @@ import openfl.events.IOErrorEvent; import openfl.geom.Rectangle; import openfl.net.FileReference; import openfl.net.URLLoader; +import funkin.ui.mainmenu.MainMenuState; import openfl.net.URLRequest; import openfl.utils.ByteArray; import funkin.input.Cursor; @@ -363,8 +366,8 @@ class DebugBoundingState extends FlxState if (FlxG.keys.justPressed.F4) FlxG.switchState(new MainMenuState()); - CoolUtil.mouseCamDrag(); - CoolUtil.mouseWheelZoom(); + MouseUtil.mouseCamDrag(); + MouseUtil.mouseWheelZoom(); // bg.scale.x = FlxG.camera.zoom; // bg.scale.y = FlxG.camera.zoom; diff --git a/source/funkin/ui/animDebugShit/FlxAnimateTest.hx b/source/funkin/ui/debug/anim/FlxAnimateTest.hx similarity index 94% rename from source/funkin/ui/animDebugShit/FlxAnimateTest.hx rename to source/funkin/ui/debug/anim/FlxAnimateTest.hx index 738e109ef..c83d2c370 100644 --- a/source/funkin/ui/animDebugShit/FlxAnimateTest.hx +++ b/source/funkin/ui/debug/anim/FlxAnimateTest.hx @@ -1,7 +1,8 @@ -package funkin.ui.animDebugShit; +package funkin.ui.debug.anim; import flixel.FlxG; import funkin.graphics.adobeanimate.FlxAtlasSprite; +import funkin.ui.MusicBeatState; /** * A simple test of FlxAnimate. diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 366e446e5..abe3ebf6f 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -16,6 +16,7 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.tweens.misc.VarTween; import flixel.util.FlxColor; +import funkin.ui.mainmenu.MainMenuState; import flixel.util.FlxSort; import flixel.util.FlxTimer; import funkin.audio.visualize.PolygonSpectogram; @@ -31,7 +32,7 @@ import funkin.input.TurboKeyHandler; import funkin.modding.events.ScriptEvent; import funkin.play.character.BaseCharacter.CharacterType; import funkin.play.character.CharacterData; -import funkin.play.HealthIcon; +import funkin.play.components.HealthIcon; import funkin.play.notes.NoteSprite; import funkin.play.PlayState; import funkin.play.song.Song; diff --git a/source/funkin/ui/CoolStatsGraph.hx b/source/funkin/ui/debug/latency/CoolStatsGraph.hx similarity index 99% rename from source/funkin/ui/CoolStatsGraph.hx rename to source/funkin/ui/debug/latency/CoolStatsGraph.hx index d3c4c3895..01689f494 100644 --- a/source/funkin/ui/CoolStatsGraph.hx +++ b/source/funkin/ui/debug/latency/CoolStatsGraph.hx @@ -1,4 +1,4 @@ -package funkin.ui; +package funkin.ui.debug.latency; import flash.display.Graphics; import flash.display.Shape; diff --git a/source/funkin/LatencyState.hx b/source/funkin/ui/debug/latency/LatencyState.hx similarity index 98% rename from source/funkin/LatencyState.hx rename to source/funkin/ui/debug/latency/LatencyState.hx index 7385ca640..7cb18a3de 100644 --- a/source/funkin/LatencyState.hx +++ b/source/funkin/ui/debug/latency/LatencyState.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.ui.debug.latency; import funkin.data.notestyle.NoteStyleRegistry; import flixel.FlxSprite; @@ -6,13 +6,14 @@ import flixel.FlxSubState; import flixel.group.FlxGroup; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxMath; +import funkin.ui.MusicBeatSubState; import flixel.sound.FlxSound; import flixel.system.debug.stats.StatsGraph; import flixel.text.FlxText; import flixel.util.FlxColor; import funkin.audio.visualize.PolygonSpectogram; import funkin.play.notes.NoteSprite; -import funkin.ui.CoolStatsGraph; +import funkin.ui.debug.latency.CoolStatsGraph; import haxe.Timer; import openfl.events.KeyboardEvent; diff --git a/source/funkin/ui/stageBuildShit/CharStage.hx b/source/funkin/ui/debug/stage/CharStage.hx similarity index 81% rename from source/funkin/ui/stageBuildShit/CharStage.hx rename to source/funkin/ui/debug/stage/CharStage.hx index cd13a7251..37e2e1c26 100644 --- a/source/funkin/ui/stageBuildShit/CharStage.hx +++ b/source/funkin/ui/debug/stage/CharStage.hx @@ -1,4 +1,4 @@ -package funkin.ui.stageBuildShit; +package funkin.ui.debug.stage; class CharStage extends SprStage { diff --git a/source/funkin/ui/stageBuildShit/SprStage.hx b/source/funkin/ui/debug/stage/SprStage.hx similarity index 97% rename from source/funkin/ui/stageBuildShit/SprStage.hx rename to source/funkin/ui/debug/stage/SprStage.hx index 2229adfe9..e53f3bc26 100644 --- a/source/funkin/ui/stageBuildShit/SprStage.hx +++ b/source/funkin/ui/debug/stage/SprStage.hx @@ -1,4 +1,4 @@ -package funkin.ui.stageBuildShit; +package funkin.ui.debug.stage; import flixel.FlxSprite; import flixel.input.mouse.FlxMouseEvent; diff --git a/source/funkin/ui/stageBuildShit/StageBuilderState.hx b/source/funkin/ui/debug/stage/StageBuilderState.hx similarity index 98% rename from source/funkin/ui/stageBuildShit/StageBuilderState.hx rename to source/funkin/ui/debug/stage/StageBuilderState.hx index 31a73ff8f..074914f58 100644 --- a/source/funkin/ui/stageBuildShit/StageBuilderState.hx +++ b/source/funkin/ui/debug/stage/StageBuilderState.hx @@ -1,4 +1,4 @@ -package funkin.ui.stageBuildShit; +package funkin.ui.debug.stage; import flixel.FlxCamera; import flixel.FlxSprite; @@ -7,10 +7,12 @@ import flixel.group.FlxGroup; import flixel.input.mouse.FlxMouseButton.FlxMouseButtonID; import flixel.input.mouse.FlxMouseEvent; import flixel.math.FlxPoint; +import funkin.ui.MusicBeatState; import flixel.text.FlxText; import flixel.ui.FlxButton; import flixel.util.FlxColor; import flixel.util.FlxSort; +import funkin.util.MouseUtil; import flixel.util.FlxTimer; class StageBuilderState extends MusicBeatState @@ -185,9 +187,9 @@ class StageBuilderState extends MusicBeatState if (curSelectedSpr != null) sprGrp.remove(curSelectedSpr, true); } - CoolUtil.mouseCamDrag(); + MouseUtil.mouseCamDrag(); - if (FlxG.keys.pressed.CONTROL) CoolUtil.mouseWheelZoom(); + if (FlxG.keys.pressed.CONTROL) MouseUtil.mouseWheelZoom(); if (isShaking) { diff --git a/source/funkin/ui/stageBuildShit/StageEditorCommand.hx b/source/funkin/ui/debug/stage/StageEditorCommand.hx similarity index 95% rename from source/funkin/ui/stageBuildShit/StageEditorCommand.hx rename to source/funkin/ui/debug/stage/StageEditorCommand.hx index d61281e07..ff59f67e5 100644 --- a/source/funkin/ui/stageBuildShit/StageEditorCommand.hx +++ b/source/funkin/ui/debug/stage/StageEditorCommand.hx @@ -1,6 +1,6 @@ -package funkin.ui.stageBuildShit; +package funkin.ui.debug.stage; -import funkin.ui.stageBuildShit.StageOffsetSubState; +import funkin.ui.debug.stage.StageOffsetSubState; import flixel.FlxSprite; /** diff --git a/source/funkin/ui/stageBuildShit/StageOffsetSubState.hx b/source/funkin/ui/debug/stage/StageOffsetSubState.hx similarity index 97% rename from source/funkin/ui/stageBuildShit/StageOffsetSubState.hx rename to source/funkin/ui/debug/stage/StageOffsetSubState.hx index a6aa6fa68..68546f1c7 100644 --- a/source/funkin/ui/stageBuildShit/StageOffsetSubState.hx +++ b/source/funkin/ui/debug/stage/StageOffsetSubState.hx @@ -1,4 +1,4 @@ -package funkin.ui.stageBuildShit; +package funkin.ui.debug.stage; import flixel.FlxSprite; import flixel.input.mouse.FlxMouseEvent; @@ -7,10 +7,11 @@ import funkin.play.character.BaseCharacter; import funkin.play.PlayState; import funkin.play.stage.StageData; import funkin.play.stage.StageProp; -import funkin.shaderslmfao.StrokeShader; +import funkin.graphics.shaders.StrokeShader; import funkin.ui.haxeui.HaxeUISubState; -import funkin.ui.stageBuildShit.StageEditorCommand; +import funkin.ui.debug.stage.StageEditorCommand; import funkin.util.SerializerUtil; +import funkin.util.MouseUtil; import haxe.ui.containers.ListView; import haxe.ui.core.Component; import haxe.ui.events.UIEvent; @@ -28,7 +29,7 @@ import openfl.net.FileReference; * @author ninjamuffin99 */ // Give other classes access to private instance fields -@:allow(funkin.ui.stageBuildShit.StageEditorCommand) +@:allow(funkin.ui.debug.stage.StageEditorCommand) class StageOffsetSubState extends HaxeUISubState { var uiStuff:Component; @@ -244,9 +245,9 @@ class StageOffsetSubState extends HaxeUISubState FlxG.mouse.visible = true; - CoolUtil.mouseCamDrag(); + MouseUtil.mouseCamDrag(); - if (FlxG.keys.pressed.CONTROL) CoolUtil.mouseWheelZoom(); + if (FlxG.keys.pressed.CONTROL) MouseUtil.mouseWheelZoom(); if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.Z) undoLastCommand(); diff --git a/source/funkin/ui/stageBuildShit/StagetoolBar.hx b/source/funkin/ui/debug/stage/StagetoolBar.hx similarity index 67% rename from source/funkin/ui/stageBuildShit/StagetoolBar.hx rename to source/funkin/ui/debug/stage/StagetoolBar.hx index 1a443f42a..243fd3f69 100644 --- a/source/funkin/ui/stageBuildShit/StagetoolBar.hx +++ b/source/funkin/ui/debug/stage/StagetoolBar.hx @@ -1,4 +1,4 @@ -package funkin.ui.stageBuildShit; +package funkin.ui.debug.stage; import flixel.group.FlxGroup; @@ -10,13 +10,5 @@ class StagetoolBar extends FlxGroup public function new() { super(); - - for (icon in icons) - { - // switch (icon) - // { - // case SELECT: - // } - } } } diff --git a/source/funkin/freeplayStuff/BGScrollingText.hx b/source/funkin/ui/freeplay/BGScrollingText.hx similarity index 98% rename from source/funkin/freeplayStuff/BGScrollingText.hx rename to source/funkin/ui/freeplay/BGScrollingText.hx index 586f83822..5511959f5 100644 --- a/source/funkin/freeplayStuff/BGScrollingText.hx +++ b/source/funkin/ui/freeplay/BGScrollingText.hx @@ -1,4 +1,4 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; import flixel.FlxObject; import flixel.group.FlxGroup.FlxTypedGroup; diff --git a/source/funkin/freeplayStuff/CapsuleText.hx b/source/funkin/ui/freeplay/CapsuleText.hx similarity index 93% rename from source/funkin/freeplayStuff/CapsuleText.hx rename to source/funkin/ui/freeplay/CapsuleText.hx index dda687f5e..1a5a0a335 100644 --- a/source/funkin/freeplayStuff/CapsuleText.hx +++ b/source/funkin/ui/freeplay/CapsuleText.hx @@ -1,9 +1,9 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; import openfl.filters.BitmapFilterQuality; import flixel.text.FlxText; import flixel.group.FlxSpriteGroup; -import funkin.shaderslmfao.GaussianBlurShader; +import funkin.graphics.shaders.GaussianBlurShader; class CapsuleText extends FlxSpriteGroup { diff --git a/source/funkin/freeplayStuff/DJBoyfriend.hx b/source/funkin/ui/freeplay/DJBoyfriend.hx similarity index 99% rename from source/funkin/freeplayStuff/DJBoyfriend.hx rename to source/funkin/ui/freeplay/DJBoyfriend.hx index ba0ce464d..2417cdf9a 100644 --- a/source/funkin/freeplayStuff/DJBoyfriend.hx +++ b/source/funkin/ui/freeplay/DJBoyfriend.hx @@ -1,4 +1,4 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; import flixel.FlxSprite; import flixel.util.FlxSignal; diff --git a/source/funkin/freeplayStuff/DifficultyStars.hx b/source/funkin/ui/freeplay/DifficultyStars.hx similarity index 96% rename from source/funkin/freeplayStuff/DifficultyStars.hx rename to source/funkin/ui/freeplay/DifficultyStars.hx index 8611727be..51526bcbe 100644 --- a/source/funkin/freeplayStuff/DifficultyStars.hx +++ b/source/funkin/ui/freeplay/DifficultyStars.hx @@ -1,8 +1,8 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; import flixel.group.FlxSpriteGroup; import funkin.graphics.adobeanimate.FlxAtlasSprite; -import funkin.shaderslmfao.HSVShader; +import funkin.graphics.shaders.HSVShader; class DifficultyStars extends FlxSpriteGroup { diff --git a/source/funkin/freeplayStuff/FreeplayFlames.hx b/source/funkin/ui/freeplay/FreeplayFlames.hx similarity index 98% rename from source/funkin/freeplayStuff/FreeplayFlames.hx rename to source/funkin/ui/freeplay/FreeplayFlames.hx index 8f54d210b..a116fb813 100644 --- a/source/funkin/freeplayStuff/FreeplayFlames.hx +++ b/source/funkin/ui/freeplay/FreeplayFlames.hx @@ -1,4 +1,4 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; import flixel.group.FlxSpriteGroup; import flixel.FlxSprite; diff --git a/source/funkin/freeplayStuff/FreeplayScore.hx b/source/funkin/ui/freeplay/FreeplayScore.hx similarity index 98% rename from source/funkin/freeplayStuff/FreeplayScore.hx rename to source/funkin/ui/freeplay/FreeplayScore.hx index ec8f4baa7..e266efca1 100644 --- a/source/funkin/freeplayStuff/FreeplayScore.hx +++ b/source/funkin/ui/freeplay/FreeplayScore.hx @@ -1,4 +1,4 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; diff --git a/source/funkin/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx similarity index 97% rename from source/funkin/FreeplayState.hx rename to source/funkin/ui/freeplay/FreeplayState.hx index 918e7c725..5c8c35753 100644 --- a/source/funkin/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1,6 +1,5 @@ -package funkin; +package funkin.ui.freeplay; -import funkin.play.song.Song; import flash.text.TextField; import flixel.addons.display.FlxGridOverlay; import flixel.addons.transition.FlxTransitionableState; @@ -26,24 +25,31 @@ import flixel.util.FlxTimer; import funkin.Controls.Control; import funkin.data.level.LevelRegistry; import funkin.data.song.SongRegistry; -import funkin.freeplayStuff.BGScrollingText; -import funkin.freeplayStuff.DifficultyStars; -import funkin.freeplayStuff.DJBoyfriend; -import funkin.freeplayStuff.FreeplayScore; -import funkin.freeplayStuff.LetterSort; -import funkin.freeplayStuff.SongMenuItem; import funkin.graphics.adobeanimate.FlxAtlasSprite; -import funkin.play.HealthIcon; +import funkin.graphics.shaders.AngleMask; +import funkin.graphics.shaders.HSVShader; +import funkin.graphics.shaders.PureColor; +import funkin.util.MathUtil; +import funkin.graphics.shaders.StrokeShader; +import funkin.play.components.HealthIcon; import funkin.play.PlayState; import funkin.play.PlayStatePlaylist; import funkin.play.song.Song; +import funkin.play.song.Song; import funkin.save.Save; import funkin.save.Save.SaveScoreData; -import funkin.shaderslmfao.AngleMask; -import funkin.shaderslmfao.HSVShader; -import funkin.shaderslmfao.PureColor; -import funkin.shaderslmfao.StrokeShader; -import funkin.ui.StickerSubState; +import funkin.ui.freeplay.BGScrollingText; +import funkin.ui.freeplay.DifficultyStars; +import funkin.ui.freeplay.DJBoyfriend; +import funkin.ui.freeplay.FreeplayScore; +import funkin.ui.freeplay.LetterSort; +import funkin.ui.freeplay.SongMenuItem; +import funkin.ui.MusicBeatState; +import funkin.ui.MusicBeatSubState; +import funkin.ui.mainmenu.MainMenuState; +import funkin.ui.transition.LoadingState; +import funkin.ui.transition.StickerSubState; +import funkin.util.MathUtil; import lime.app.Future; import lime.utils.Assets; @@ -664,8 +670,8 @@ class FreeplayState extends MusicBeatSubState } } - lerpScore = CoolUtil.coolLerp(lerpScore, intendedScore, 0.2); - lerpCompletion = CoolUtil.coolLerp(lerpCompletion, intendedCompletion, 0.9); + lerpScore = MathUtil.coolLerp(lerpScore, intendedScore, 0.2); + lerpCompletion = MathUtil.coolLerp(lerpCompletion, intendedCompletion, 0.9); fp.updateScore(Std.int(lerpScore)); diff --git a/source/funkin/freeplayStuff/LetterSort.hx b/source/funkin/ui/freeplay/LetterSort.hx similarity index 99% rename from source/funkin/freeplayStuff/LetterSort.hx rename to source/funkin/ui/freeplay/LetterSort.hx index e6d923c90..a66b386ee 100644 --- a/source/funkin/freeplayStuff/LetterSort.hx +++ b/source/funkin/ui/freeplay/LetterSort.hx @@ -1,4 +1,4 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; diff --git a/source/funkin/freeplayStuff/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx similarity index 96% rename from source/funkin/freeplayStuff/SongMenuItem.hx rename to source/funkin/ui/freeplay/SongMenuItem.hx index 06de92886..477047c68 100644 --- a/source/funkin/freeplayStuff/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -1,8 +1,8 @@ -package funkin.freeplayStuff; +package funkin.ui.freeplay; -import funkin.FreeplayState.FreeplaySongData; -import funkin.shaderslmfao.HSVShader; -import funkin.shaderslmfao.GaussianBlurShader; +import funkin.ui.freeplay.FreeplayState.FreeplaySongData; +import funkin.graphics.shaders.HSVShader; +import funkin.graphics.shaders.GaussianBlurShader; import flixel.group.FlxGroup; import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; @@ -12,7 +12,8 @@ import flixel.math.FlxMath; import flixel.math.FlxPoint; import flixel.text.FlxText; import flixel.util.FlxTimer; -import funkin.shaderslmfao.Grayscale; +import funkin.util.MathUtil; +import funkin.graphics.shaders.Grayscale; class SongMenuItem extends FlxSpriteGroup { @@ -312,8 +313,8 @@ class SongMenuItem extends FlxSpriteGroup if (doLerp) { - x = CoolUtil.coolLerp(x, targetPos.x, 0.3); - y = CoolUtil.coolLerp(y, targetPos.y, 0.4); + x = MathUtil.coolLerp(x, targetPos.x, 0.3); + y = MathUtil.coolLerp(y, targetPos.y, 0.4); } super.update(elapsed); diff --git a/source/funkin/ui/haxeui/HaxeUIState.hx b/source/funkin/ui/haxeui/HaxeUIState.hx index d9d00dd23..fa95b2d1d 100644 --- a/source/funkin/ui/haxeui/HaxeUIState.hx +++ b/source/funkin/ui/haxeui/HaxeUIState.hx @@ -5,6 +5,7 @@ import haxe.ui.containers.menus.MenuCheckBox; import haxe.ui.containers.menus.MenuItem; import haxe.ui.core.Component; import haxe.ui.core.Screen; +import funkin.ui.MusicBeatState; import haxe.ui.events.MouseEvent; import haxe.ui.events.UIEvent; import haxe.ui.RuntimeComponentBuilder; diff --git a/source/funkin/ui/haxeui/HaxeUISubState.hx b/source/funkin/ui/haxeui/HaxeUISubState.hx index ba218f37c..82c15be4c 100644 --- a/source/funkin/ui/haxeui/HaxeUISubState.hx +++ b/source/funkin/ui/haxeui/HaxeUISubState.hx @@ -4,6 +4,9 @@ import haxe.ui.RuntimeComponentBuilder; import haxe.ui.components.CheckBox; import haxe.ui.containers.menus.MenuCheckBox; import haxe.ui.core.Component; +import funkin.ui.MusicBeatState; +import funkin.ui.mainmenu.MainMenuState; +import funkin.ui.MusicBeatSubState; import haxe.ui.events.MouseEvent; import haxe.ui.events.UIEvent; diff --git a/source/funkin/ui/haxeui/components/README.md b/source/funkin/ui/haxeui/components/README.md index f051a6236..90f8ab553 100644 --- a/source/funkin/ui/haxeui/components/README.md +++ b/source/funkin/ui/haxeui/components/README.md @@ -1,3 +1,3 @@ # funkin.ui.haxeui.components -Since there is a line in `source/module.xml` pointing to this folder, all components in this folder will automatically be accessible in any HaxeUI layouts. \ No newline at end of file +Since there is a line in `source/module.xml` pointing to this folder, all components in this folder will automatically be accessible in any HaxeUI layouts. diff --git a/source/funkin/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx similarity index 97% rename from source/funkin/MainMenuState.hx rename to source/funkin/ui/mainmenu/MainMenuState.hx index 7267a6da8..769493c45 100644 --- a/source/funkin/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.ui.mainmenu; import flixel.addons.transition.FlxTransitionableSubState; import funkin.ui.debug.DebugMenuSubState; @@ -13,8 +13,10 @@ import flixel.input.touch.FlxTouch; import flixel.text.FlxText; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; +import funkin.ui.MusicBeatState; import flixel.util.FlxTimer; import funkin.ui.AtlasMenuList; +import funkin.ui.freeplay.FreeplayState; import funkin.ui.MenuList; import funkin.ui.title.TitleState; import funkin.ui.story.StoryMenuState; @@ -108,7 +110,7 @@ class MainMenuState extends MusicBeatState #end createMenuItem('options', 'mainmenu/options', function() { - startExitState(new funkin.ui.OptionsState()); + startExitState(new funkin.ui.options.OptionsState()); }); // Reset position of menu items. @@ -187,7 +189,7 @@ class MainMenuState extends MusicBeatState // #end } - function onMenuItemChange(selected:MenuItem) + function onMenuItemChange(selected:MenuListItem) { camFollow.setPosition(selected.getGraphicMidpoint().x, selected.getGraphicMidpoint().y); } diff --git a/source/funkin/ButtonRemapSubstate.hx b/source/funkin/ui/options/ButtonRemapSubstate.hx similarity index 82% rename from source/funkin/ButtonRemapSubstate.hx rename to source/funkin/ui/options/ButtonRemapSubstate.hx index 8905ec8ba..b692dbe82 100644 --- a/source/funkin/ButtonRemapSubstate.hx +++ b/source/funkin/ui/options/ButtonRemapSubstate.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.ui.options; import flixel.FlxSubState; diff --git a/source/funkin/ui/ColorsMenu.hx b/source/funkin/ui/options/ColorsMenu.hx similarity index 96% rename from source/funkin/ui/ColorsMenu.hx rename to source/funkin/ui/options/ColorsMenu.hx index 6a844eef3..928f74ba8 100644 --- a/source/funkin/ui/ColorsMenu.hx +++ b/source/funkin/ui/options/ColorsMenu.hx @@ -1,11 +1,11 @@ -package funkin.ui; +package funkin.ui.options; import funkin.data.notestyle.NoteStyleRegistry; import flixel.addons.effects.chainable.FlxEffectSprite; import flixel.addons.effects.chainable.FlxOutlineEffect; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.util.FlxColor; -import funkin.ui.OptionsState.Page; +import funkin.ui.options.OptionsState.Page; import funkin.play.notes.NoteSprite; class ColorsMenu extends Page diff --git a/source/funkin/ui/ControlsMenu.hx b/source/funkin/ui/options/ControlsMenu.hx similarity index 98% rename from source/funkin/ui/ControlsMenu.hx rename to source/funkin/ui/options/ControlsMenu.hx index 8197424ee..2aee473d3 100644 --- a/source/funkin/ui/ControlsMenu.hx +++ b/source/funkin/ui/options/ControlsMenu.hx @@ -1,5 +1,6 @@ -package funkin.ui; +package funkin.ui.options; +import funkin.util.InputUtil; import flixel.FlxCamera; import flixel.FlxObject; import flixel.FlxSprite; @@ -12,7 +13,7 @@ import funkin.ui.AtlasText; import funkin.ui.MenuList; import funkin.ui.TextMenuList; -class ControlsMenu extends funkin.ui.OptionsState.Page +class ControlsMenu extends funkin.ui.options.OptionsState.Page { public static inline final COLUMNS = 2; static var controlList = Control.createAll(); @@ -456,6 +457,6 @@ class InputItem extends TextMenuItem public function getLabel(input:Int) { - return input == FlxKey.NONE ? "---" : InputFormatter.format(input, device); + return input == FlxKey.NONE ? "---" : InputUtil.format(input, device); } } diff --git a/source/funkin/ui/ModMenu.hx b/source/funkin/ui/options/ModMenu.hx similarity index 97% rename from source/funkin/ui/ModMenu.hx rename to source/funkin/ui/options/ModMenu.hx index 769d3eca2..574a93c49 100644 --- a/source/funkin/ui/ModMenu.hx +++ b/source/funkin/ui/options/ModMenu.hx @@ -1,11 +1,11 @@ -package funkin.ui; +package funkin.ui.options; import funkin.modding.PolymodHandler; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.text.FlxText; import flixel.util.FlxColor; import polymod.Polymod; -import funkin.ui.OptionsState.Page; +import funkin.ui.options.OptionsState.Page; class ModMenu extends Page { diff --git a/source/funkin/ui/OptionsState.hx b/source/funkin/ui/options/OptionsState.hx similarity index 98% rename from source/funkin/ui/OptionsState.hx rename to source/funkin/ui/options/OptionsState.hx index 6c32c7f4c..72bb6c60c 100644 --- a/source/funkin/ui/OptionsState.hx +++ b/source/funkin/ui/options/OptionsState.hx @@ -1,10 +1,12 @@ -package funkin.ui; +package funkin.ui.options; import flixel.FlxSprite; import flixel.FlxSubState; import flixel.addons.transition.FlxTransitionableState; import flixel.group.FlxGroup; import flixel.util.FlxSignal; +import funkin.ui.mainmenu.MainMenuState; +import funkin.ui.MusicBeatState; import funkin.util.WindowUtil; class OptionsState extends MusicBeatState diff --git a/source/funkin/ui/PreferencesMenu.hx b/source/funkin/ui/options/PreferencesMenu.hx similarity index 98% rename from source/funkin/ui/PreferencesMenu.hx rename to source/funkin/ui/options/PreferencesMenu.hx index 812d0ab49..b4b3c7db8 100644 --- a/source/funkin/ui/PreferencesMenu.hx +++ b/source/funkin/ui/options/PreferencesMenu.hx @@ -1,11 +1,11 @@ -package funkin.ui; +package funkin.ui.options; import flixel.FlxCamera; import flixel.FlxObject; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import funkin.ui.AtlasText.AtlasFont; -import funkin.ui.OptionsState.Page; +import funkin.ui.options.OptionsState.Page; import funkin.ui.TextMenuList.TextMenuItem; class PreferencesMenu extends Page diff --git a/source/funkin/ui/story/LevelTitle.hx b/source/funkin/ui/story/LevelTitle.hx index e1765d453..e6f989016 100644 --- a/source/funkin/ui/story/LevelTitle.hx +++ b/source/funkin/ui/story/LevelTitle.hx @@ -4,7 +4,7 @@ import flixel.FlxSprite; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup; import flixel.util.FlxColor; -import funkin.CoolUtil; +import funkin.util.MathUtil; class LevelTitle extends FlxSpriteGroup { @@ -54,7 +54,7 @@ class LevelTitle extends FlxSpriteGroup public override function update(elapsed:Float):Void { - this.y = CoolUtil.coolLerp(y, targetY, 0.17); + this.y = MathUtil.coolLerp(y, targetY, 0.17); if (isFlashing) flashingInt += 1; if (flashingInt % fakeFramerate >= Math.floor(fakeFramerate / 2)) title.color = 0xFF33ffff; diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 09b9cb600..e5bb6c34c 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -1,5 +1,6 @@ package funkin.ui.story; +import funkin.ui.mainmenu.MainMenuState; import funkin.save.Save; import funkin.save.Save.SaveScoreData; import openfl.utils.Assets; @@ -9,6 +10,7 @@ import flixel.group.FlxGroup.FlxTypedGroup; import flixel.text.FlxText; import flixel.addons.transition.FlxTransitionableState; import flixel.tweens.FlxEase; +import funkin.ui.MusicBeatState; import flixel.tweens.FlxTween; import flixel.util.FlxColor; import flixel.util.FlxTimer; @@ -17,9 +19,13 @@ import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEventDispatcher; import funkin.play.PlayState; import funkin.play.PlayStatePlaylist; +import funkin.ui.mainmenu.MainMenuState; import funkin.play.song.Song; import funkin.data.song.SongData.SongMusicData; import funkin.data.song.SongRegistry; +import funkin.util.MathUtil; +import funkin.ui.transition.LoadingState; +import funkin.ui.transition.StickerSubState; class StoryMenuState extends MusicBeatState { @@ -313,7 +319,7 @@ class StoryMenuState extends MusicBeatState { Conductor.update(); - highScoreLerp = Std.int(CoolUtil.coolLerp(highScoreLerp, highScore, 0.5)); + highScoreLerp = Std.int(MathUtil.coolLerp(highScoreLerp, highScore, 0.5)); scoreText.text = 'LEVEL SCORE: ${Math.round(highScoreLerp)}'; diff --git a/source/funkin/ui/title/AttractState.hx b/source/funkin/ui/title/AttractState.hx index 67c762da4..38cff7cc8 100644 --- a/source/funkin/ui/title/AttractState.hx +++ b/source/funkin/ui/title/AttractState.hx @@ -5,6 +5,7 @@ import funkin.graphics.video.FlxVideo; #else import hxcodec.flixel.FlxVideoSprite; #end +import funkin.ui.MusicBeatState; /** * After about 2 minutes of inactivity on the title screen, diff --git a/source/funkin/ui/title/FlxSpriteOverlay.hx b/source/funkin/ui/title/FlxSpriteOverlay.hx index ddf58bbfd..1900e25f0 100644 --- a/source/funkin/ui/title/FlxSpriteOverlay.hx +++ b/source/funkin/ui/title/FlxSpriteOverlay.hx @@ -1,7 +1,7 @@ package funkin.ui.title; import flixel.FlxSprite; -import funkin.shaderslmfao.BlendModesShader; +import funkin.graphics.shaders.BlendModesShader; import openfl.display.BitmapData; import flixel.FlxCamera; import flixel.FlxG; diff --git a/source/funkin/OutdatedSubState.hx b/source/funkin/ui/title/OutdatedSubState.hx similarity index 95% rename from source/funkin/OutdatedSubState.hx rename to source/funkin/ui/title/OutdatedSubState.hx index 7684e5ae4..d262fc4e4 100644 --- a/source/funkin/OutdatedSubState.hx +++ b/source/funkin/ui/title/OutdatedSubState.hx @@ -1,9 +1,10 @@ -package funkin; +package funkin.ui.title; import flixel.FlxSprite; import flixel.FlxSubState; import flixel.text.FlxText; import flixel.util.FlxColor; +import funkin.ui.MusicBeatState; import lime.app.Application; #if newgrounds diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index 9820e4ecc..da3ba6c89 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -9,20 +9,25 @@ import flixel.tweens.FlxTween; import flixel.util.FlxColor; import flixel.util.FlxDirectionFlags; import flixel.util.FlxTimer; -import funkin.audiovis.SpectogramSprite; -import funkin.shaderslmfao.ColorSwap; -import funkin.shaderslmfao.LeftMaskShader; +import funkin.audio.visualize.SpectogramSprite; +import funkin.graphics.shaders.ColorSwap; +import funkin.graphics.shaders.LeftMaskShader; import funkin.data.song.SongRegistry; +import funkin.ui.MusicBeatState; import funkin.data.song.SongData.SongMusicData; -import funkin.shaderslmfao.TitleOutline; +import funkin.graphics.shaders.TitleOutline; +import funkin.ui.freeplay.FreeplayState; import funkin.ui.AtlasText; import openfl.Assets; import openfl.display.Sprite; import openfl.events.AsyncErrorEvent; +import funkin.ui.mainmenu.MainMenuState; import openfl.events.MouseEvent; import openfl.events.NetStatusEvent; +import funkin.ui.freeplay.FreeplayState; import openfl.media.Video; import openfl.net.NetStream; +import funkin.api.newgrounds.NGio; import openfl.display.BlendMode; #if desktop @@ -167,10 +172,6 @@ class TitleState extends MusicBeatState credGroup.add(textGroup); } - // var atlasBullShit:FlxSprite = new FlxSprite(); - // atlasBullShit.frames = CoolUtil.fromAnimate(Paths.image('money'), Paths.file('images/money.json')); - // credGroup.add(atlasBullShit); - ngSpr = new FlxSprite(0, FlxG.height * 0.52); if (FlxG.random.bool(1)) diff --git a/source/funkin/LoadingState.hx b/source/funkin/ui/transition/LoadingState.hx similarity index 89% rename from source/funkin/LoadingState.hx rename to source/funkin/ui/transition/LoadingState.hx index 216d9ba74..69590bfe3 100644 --- a/source/funkin/LoadingState.hx +++ b/source/funkin/ui/transition/LoadingState.hx @@ -1,18 +1,24 @@ -package funkin; +package funkin.ui.transition; import funkin.play.PlayStatePlaylist; import flixel.FlxSprite; import flixel.FlxState; +import funkin.graphics.shaders.ScreenWipeShader; import flixel.math.FlxMath; import flixel.util.FlxTimer; import funkin.play.PlayState; import haxe.io.Path; import lime.app.Future; +import flixel.tweens.FlxTween; +import funkin.ui.MusicBeatState; import lime.app.Promise; import lime.utils.AssetLibrary; +import flixel.tweens.FlxEase; import lime.utils.AssetManifest; import lime.utils.Assets as LimeAssets; import openfl.utils.Assets; +import funkin.ui.mainmenu.MainMenuState; +import openfl.filters.ShaderFilter; class LoadingState extends MusicBeatState { @@ -321,4 +327,21 @@ class MultiCallback public function getUnfired():Array<Void->Void> return unfired.array(); + + public static function coolSwitchState(state:FlxState, transitionTex:String = "shaderTransitionStuff/coolDots", time:Float = 2) + { + var screenShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("shaderTransitionStuff/coolDots")); + var screenWipeShit:ScreenWipeShader = new ScreenWipeShader(); + + screenWipeShit.funnyShit.input = screenShit.pixels; + FlxTween.tween(screenWipeShit, {daAlphaShit: 1}, time, + { + ease: FlxEase.quadInOut, + onComplete: function(twn) { + screenShit.destroy(); + FlxG.switchState(new MainMenuState()); + } + }); + FlxG.camera.setFilters([new ShaderFilter(screenWipeShit)]); + } } diff --git a/source/funkin/ui/StickerSubState.hx b/source/funkin/ui/transition/StickerSubState.hx similarity index 98% rename from source/funkin/ui/StickerSubState.hx rename to source/funkin/ui/transition/StickerSubState.hx index a4e3a6acb..1c012e00c 100644 --- a/source/funkin/ui/StickerSubState.hx +++ b/source/funkin/ui/transition/StickerSubState.hx @@ -1,9 +1,10 @@ -package funkin.ui; +package funkin.ui.transition; import flixel.FlxSprite; import haxe.Json; import lime.utils.Assets; // import flxtyped group +import funkin.ui.MusicBeatSubState; import funkin.ui.story.StoryMenuState; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.util.FlxTimer; @@ -11,8 +12,10 @@ import flixel.FlxG; import flixel.math.FlxMath; import flixel.util.FlxSort; import flixel.util.FlxSignal; +import funkin.ui.mainmenu.MainMenuState; import flixel.addons.transition.FlxTransitionableState; import openfl.display.BitmapData; +import funkin.ui.freeplay.FreeplayState; import openfl.geom.Matrix; import openfl.display.Sprite; import openfl.display.Bitmap; diff --git a/source/funkin/util/BezierUtil.hx b/source/funkin/util/BezierUtil.hx index b3cf51d1d..37d91223b 100644 --- a/source/funkin/util/BezierUtil.hx +++ b/source/funkin/util/BezierUtil.hx @@ -2,6 +2,9 @@ package funkin.util; import flixel.math.FlxPoint; +/** + * Utilities for performing math with bezier curves. + */ class BezierUtil { /** diff --git a/source/funkin/util/DateUtil.hx b/source/funkin/util/DateUtil.hx index 72838477c..2d08fd48b 100644 --- a/source/funkin/util/DateUtil.hx +++ b/source/funkin/util/DateUtil.hx @@ -1,5 +1,8 @@ package funkin.util; +/** + * Utilities for performing operations on dates. + */ class DateUtil { public static function generateTimestamp(?date:Date = null):String diff --git a/source/funkin/util/FlxGamepadUtil.hx b/source/funkin/util/FlxGamepadUtil.hx index d768b42c4..7e72e7138 100644 --- a/source/funkin/util/FlxGamepadUtil.hx +++ b/source/funkin/util/FlxGamepadUtil.hx @@ -6,6 +6,9 @@ import lime.ui.Gamepad as LimeGamepad; import lime.ui.GamepadAxis as LimeGamepadAxis; import lime.ui.GamepadButton as LimeGamepadButton; +/** + * Utilities for working with Flixel gamepads. + */ class FlxGamepadUtil { public static function getInputID(gamepad:FlxGamepad, button:LimeGamepadButton):FlxGamepadInputID diff --git a/source/funkin/InputFormatter.hx b/source/funkin/util/InputUtil.hx similarity index 96% rename from source/funkin/InputFormatter.hx rename to source/funkin/util/InputUtil.hx index 2a7011f64..97478294a 100644 --- a/source/funkin/InputFormatter.hx +++ b/source/funkin/util/InputUtil.hx @@ -1,4 +1,4 @@ -package funkin; +package funkin.util; import funkin.Controls; import flixel.input.gamepad.FlxGamepad; @@ -7,9 +7,12 @@ import flixel.input.keyboard.FlxKey; using flixel.util.FlxStringUtil; -class InputFormatter +/** + * Utilities for working with inputs. + */ +class InputUtil { - static public function format(id:Int, device:Device):String + public static function format(id:Int, device:Device):String { return switch (device) { @@ -18,7 +21,7 @@ class InputFormatter } } - static public function getKeyName(id:Int):String + public static function getKeyName(id:Int):String { return switch (id) { diff --git a/source/funkin/util/MathUtil.hx b/source/funkin/util/MathUtil.hx new file mode 100644 index 000000000..3cb6621a7 --- /dev/null +++ b/source/funkin/util/MathUtil.hx @@ -0,0 +1,31 @@ +package funkin.util; + +/** + * Utilities for performing mathematical operations. + */ +class MathUtil +{ + /** + * Perform linear interpolation between the base and the target, based on the current framerate. + */ + public static function coolLerp(base:Float, target:Float, ratio:Float):Float + { + return base + cameraLerp(ratio) * (target - base); + } + + public static function cameraLerp(lerp:Float):Float + { + return lerp * (FlxG.elapsed / (1 / 60)); + } + + /** + * Get the logarithm of a value with a given base. + * @param base The base of the logarithm. + * @param value The value to get the logarithm of. + * @return `log_base(value)` + */ + public static function logBase(base:Float, value:Float):Float + { + return Math.log(value) / Math.log(base); + } +} diff --git a/source/funkin/util/MouseUtil.hx b/source/funkin/util/MouseUtil.hx new file mode 100644 index 000000000..c3f46819e --- /dev/null +++ b/source/funkin/util/MouseUtil.hx @@ -0,0 +1,45 @@ +package funkin.util; + +import flixel.math.FlxPoint; + +/** + * Utility functions related to the mouse. + */ +class MouseUtil +{ + static var oldCamPos:FlxPoint = new FlxPoint(); + static var oldMousePos:FlxPoint = new FlxPoint(); + + /** + * Used to be for general camera middle click dragging, now generalized for any click and drag type shit! + * Listen I don't make the rules here + * @param target what you want to be dragged, defaults to CAMERA SCROLL + * @param jusPres the "justPressed", should be a button of some sort + * @param pressed the "pressed", which should be the same button as `jusPres` + */ + public static function mouseCamDrag(?target:FlxPoint, ?jusPres:Bool, ?pressed:Bool):Void + { + if (target == null) target = FlxG.camera.scroll; + + if (jusPres == null) jusPres = FlxG.mouse.justPressedMiddle; + + if (pressed == null) pressed = FlxG.mouse.pressedMiddle; + + if (jusPres) + { + oldCamPos.set(target.x, target.y); + oldMousePos.set(FlxG.mouse.screenX, FlxG.mouse.screenY); + } + + if (pressed) + { + target.x = oldCamPos.x - (FlxG.mouse.screenX - oldMousePos.x); + target.y = oldCamPos.y - (FlxG.mouse.screenY - oldMousePos.y); + } + } + + public static function mouseWheelZoom():Void + { + if (FlxG.mouse.wheel != 0) FlxG.camera.zoom += FlxG.mouse.wheel * (0.1 * FlxG.camera.zoom); + } +} diff --git a/source/funkin/util/PlatformUtil.hx b/source/funkin/util/PlatformUtil.hx index b709eb475..e11a21c9f 100644 --- a/source/funkin/util/PlatformUtil.hx +++ b/source/funkin/util/PlatformUtil.hx @@ -1,5 +1,8 @@ package funkin.util; +/** + * Utility functions related to specific platforms. + */ class PlatformUtil { /** diff --git a/source/funkin/util/SerializerUtil.hx b/source/funkin/util/SerializerUtil.hx index 0af0fc9ea..abac04115 100644 --- a/source/funkin/util/SerializerUtil.hx +++ b/source/funkin/util/SerializerUtil.hx @@ -12,8 +12,8 @@ typedef ScoreInput = } /** - * A class of functions dedicated to serializing and deserializing data. - * TODO: Rewrite/refactor this to use json2object. + * Functions dedicated to serializing and deserializing data. + * NOTE: Use `json2object` wherever possible, it's way more efficient. */ class SerializerUtil { diff --git a/source/funkin/util/SortUtil.hx b/source/funkin/util/SortUtil.hx index 178015068..d87592c91 100644 --- a/source/funkin/util/SortUtil.hx +++ b/source/funkin/util/SortUtil.hx @@ -10,7 +10,7 @@ import funkin.data.song.SongData.SongEventData; import funkin.data.song.SongData.SongNoteData; /** - * A set of functions related to sorting. + * Utility functions related to sorting. * * NOTE: `Array.sort()` takes a function `(x, y) -> Int`. * If the objects are in the correct order (x before y), return a negative value. diff --git a/source/funkin/util/VersionUtil.hx b/source/funkin/util/VersionUtil.hx index 1dc00473a..480bcea71 100644 --- a/source/funkin/util/VersionUtil.hx +++ b/source/funkin/util/VersionUtil.hx @@ -4,6 +4,8 @@ import thx.semver.Version; import thx.semver.VersionRule; /** + * Utility functions for operating on semantic versions. + * * Remember, increment the patch version (1.0.x) if you make a bugfix, * increment the minor version (1.x.0) if you make a new feature (but previous content is still compatible), * and increment the major version (x.0.0) if you make a breaking change (e.g. new API or reorganized file format). diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index 6e6a41641..0e9b76bc2 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -2,6 +2,9 @@ package funkin.util; import flixel.util.FlxSignal.FlxTypedSignal; +/** + * Utilities for operating on the current window, such as changing the title. + */ #if (cpp && windows) @:cppFileCode(' #include <iostream> From 2728f34512e31bcf87953dcec6b7e1bc86212d2f Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Tue, 7 Nov 2023 18:53:50 -0500 Subject: [PATCH 15/21] Fix bug where Freeplay random would crash the game --- source/funkin/FreeplayState.hx | 14 +++++++++++++- source/funkin/freeplayStuff/LetterSort.hx | 9 +++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/source/funkin/FreeplayState.hx b/source/funkin/FreeplayState.hx index 918e7c725..0ba5d5175 100644 --- a/source/funkin/FreeplayState.hx +++ b/source/funkin/FreeplayState.hx @@ -84,6 +84,7 @@ class FreeplayState extends MusicBeatSubState var dj:DJBoyfriend; + var letterSort:LetterSort; var typing:FlxInputText; var exitMovers:Map<Array<FlxSprite>, MoveData> = new Map(); @@ -413,7 +414,7 @@ class FreeplayState extends MusicBeatSubState txtCompletion.visible = false; add(txtCompletion); - var letterSort:LetterSort = new LetterSort(400, 75); + letterSort = new LetterSort(400, 75); add(letterSort); letterSort.visible = false; @@ -953,6 +954,7 @@ class FreeplayState extends MusicBeatSubState trace("RANDOM SELECTED"); busy = true; + letterSort.inputEnabled = false; var availableSongCapsules:Array<SongMenuItem> = grpCapsules.members.filter(function(cap:SongMenuItem) { // Dead capsules are ones which were removed from the list when changing filters. @@ -963,6 +965,15 @@ class FreeplayState extends MusicBeatSubState return cap.songData.songName; })}'); + if (availableSongCapsules.length == 0) + { + trace("No songs available!"); + busy = false; + letterSort.inputEnabled = true; + FlxG.sound.play(Paths.sound('cancelMenu')); + return; + } + var targetSong:SongMenuItem = FlxG.random.getObject(availableSongCapsules); // Seeing if I can do an animation... @@ -976,6 +987,7 @@ class FreeplayState extends MusicBeatSubState function capsuleOnConfirmDefault(cap:SongMenuItem):Void { busy = true; + letterSort.inputEnabled = false; PlayStatePlaylist.isStoryMode = false; diff --git a/source/funkin/freeplayStuff/LetterSort.hx b/source/funkin/freeplayStuff/LetterSort.hx index e6d923c90..edf1221d2 100644 --- a/source/funkin/freeplayStuff/LetterSort.hx +++ b/source/funkin/freeplayStuff/LetterSort.hx @@ -23,6 +23,8 @@ class LetterSort extends FlxTypedSpriteGroup<FlxSprite> var rightArrow:FlxSprite; var grpSeperators:Array<FlxSprite> = []; + public var inputEnabled:Bool = true; + public function new(x, y) { super(x, y); @@ -72,8 +74,11 @@ class LetterSort extends FlxTypedSpriteGroup<FlxSprite> { super.update(elapsed); - if (FlxG.keys.justPressed.E) changeSelection(1); - if (FlxG.keys.justPressed.Q) changeSelection(-1); + if (inputEnabled) + { + if (FlxG.keys.justPressed.E) changeSelection(1); + if (FlxG.keys.justPressed.Q) changeSelection(-1); + } } public function changeSelection(diff:Int = 0) From da08e0fa39ca4e66751cd462f1a9f74f7e4fb94d Mon Sep 17 00:00:00 2001 From: Cameron Taylor <cameron.taylor.ninja@gmail.com> Date: Wed, 8 Nov 2023 23:22:55 -0500 Subject: [PATCH 16/21] assets update --- .gitmodules | 1 + assets | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 8968471e3..c7aa48202 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,4 @@ [submodule "art"] path = art url = https://github.com/FunkinCrew/Funkin-history-rewrite-art + branch = master diff --git a/assets b/assets index 53f63f549..bbd6386e1 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 53f63f549f34b9c03d0e2d7149dde551a61acb26 +Subproject commit bbd6386e11e3d0a8278ffcdef77f53e0f7ade750 From f8ec09b7c257df88241c0a93453faee51bfbfc74 Mon Sep 17 00:00:00 2001 From: Cameron Taylor <cameron.taylor.ninja@gmail.com> Date: Thu, 9 Nov 2023 06:28:50 -0500 Subject: [PATCH 17/21] update modules + assets merge --- .gitmodules | 3 +++ assets | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 8968471e3..17c3cc026 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,6 +2,9 @@ path = assets url = https://github.com/FunkinCrew/Funkin-history-rewrite-assets branch = master + update = merge [submodule "art"] path = art url = https://github.com/FunkinCrew/Funkin-history-rewrite-art + branch = master + update = merge diff --git a/assets b/assets index e634c8f50..11a1af02f 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e634c8f50c34845097283e0f411e1f89409e1498 +Subproject commit 11a1af02fd38ed6086f09bf59567e1efa57b5715 From a9dfd4adcf50aaaad3cfa9bec71540a460bd7c57 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Thu, 9 Nov 2023 17:00:46 -0500 Subject: [PATCH 18/21] Fix a bug where multiple vocal tracks would play at once --- source/funkin/play/PlayState.hx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 4542b9f98..0438ffecc 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -700,6 +700,8 @@ class PlayState extends MusicBeatSubState if (!overrideMusic) { + // Stop the vocals if they already exist. + if (vocals != null) vocals.stop(); vocals = currentChart.buildVocals(); if (vocals.members.length == 0) @@ -1554,6 +1556,8 @@ class PlayState extends MusicBeatSubState if (!overrideMusic) { + // Stop the vocals if they already exist. + if (vocals != null) vocals.stop(); vocals = currentChart.buildVocals(); if (vocals.members.length == 0) From 6956144df7164c0f759d22d8c824bca37ffd26aa Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Thu, 9 Nov 2023 17:03:13 -0500 Subject: [PATCH 19/21] Update haxeui-flixel --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index 22dd6e42f..778b85604 100644 --- a/hmm.json +++ b/hmm.json @@ -56,7 +56,7 @@ "name": "haxeui-flixel", "type": "git", "dir": null, - "ref": "9bd0b9e0fea40b8e06a89aac4949512d95064609", + "ref": "95c7d66e779626eabd6f48a1cd7aa7f9a503a7f3", "url": "https://github.com/haxeui/haxeui-flixel" }, { From 01be0293e3ef16d7c691f9568fb38707750b0631 Mon Sep 17 00:00:00 2001 From: EliteMasterEric <ericmyllyoja@gmail.com> Date: Mon, 13 Nov 2023 18:03:24 -0500 Subject: [PATCH 20/21] Revert asset changes (temporarily) --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 11a1af02f..be9d790af 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 11a1af02fd38ed6086f09bf59567e1efa57b5715 +Subproject commit be9d790af9c6f1f5e3afc7aed2b1d5c21823bc20 From 70049765ee8f4b8090f6697d1e47f1aeb99e6b67 Mon Sep 17 00:00:00 2001 From: Cameron Taylor <cameron.taylor.ninja@gmail.com> Date: Tue, 14 Nov 2023 15:30:49 -0500 Subject: [PATCH 21/21] assets push / update --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index bbd6386e1..69283c667 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit bbd6386e11e3d0a8278ffcdef77f53e0f7ade750 +Subproject commit 69283c667d93e44da8d63f0588c7554f608575fb