diff --git a/Project.xml b/Project.xml index a83db1677..ccf6c83a3 100644 --- a/Project.xml +++ b/Project.xml @@ -200,6 +200,12 @@ --> --> + + +
+ +
+
diff --git a/hmm.json b/hmm.json index e2670420a..f06b295e4 100644 --- a/hmm.json +++ b/hmm.json @@ -49,8 +49,8 @@ "name": "haxeui-core", "type": "git", "dir": null, - "ref": "f5daafe93bdfa957538f199294a54e0476c805b7", - "url": "https://github.com/haxeui/haxeui-core/" + "ref": "e92d5cfac847943fac84696b103670d55c2c774f", + "url": "https://github.com/haxeui/haxeui-core" }, { "name": "haxeui-flixel", @@ -137,7 +137,7 @@ "name": "openfl", "type": "git", "dir": null, - "ref": "ef43deb2c68d8a4bcd73abfbd77324fc8220d0c1", + "ref": "d33d489a137ff8fdece4994cf1302f0b6334ed08", "url": "https://github.com/EliteMasterEric/openfl" }, { diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 9bd668b69..b0ad6c221 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -47,7 +47,7 @@ class Conductor /** * Beats per minute of the current song at the current time. */ - public static var bpm(get, null):Float; + public static var bpm(get, never):Float; static function get_bpm():Float { @@ -67,7 +67,7 @@ class Conductor /** * Duration of a measure in milliseconds. Calculated based on bpm. */ - public static var measureLengthMs(get, null):Float; + public static var measureLengthMs(get, never):Float; static function get_measureLengthMs():Float { @@ -77,7 +77,7 @@ class Conductor /** * Duration of a beat (quarter note) in milliseconds. Calculated based on bpm. */ - public static var beatLengthMs(get, null):Float; + public static var beatLengthMs(get, never):Float; static function get_beatLengthMs():Float { @@ -88,14 +88,14 @@ class Conductor /** * Duration of a step (sixtennth note) in milliseconds. Calculated based on bpm. */ - public static var stepLengthMs(get, null):Float; + public static var stepLengthMs(get, never):Float; static function get_stepLengthMs():Float { return beatLengthMs / timeSignatureNumerator; } - public static var timeSignatureNumerator(get, null):Int; + public static var timeSignatureNumerator(get, never):Int; static function get_timeSignatureNumerator():Int { @@ -104,7 +104,7 @@ class Conductor return currentTimeChange.timeSignatureNum; } - public static var timeSignatureDenominator(get, null):Int; + public static var timeSignatureDenominator(get, never):Int; static function get_timeSignatureDenominator():Int { @@ -151,7 +151,7 @@ class Conductor public static var audioOffset:Float = 0; public static var offset:Float = 0; - public static var beatsPerMeasure(get, null):Float; + public static var beatsPerMeasure(get, never):Float; static function get_beatsPerMeasure():Float { @@ -159,7 +159,7 @@ class Conductor return stepsPerMeasure / Constants.STEPS_PER_BEAT; } - public static var stepsPerMeasure(get, null):Int; + public static var stepsPerMeasure(get, never):Int; static function get_stepsPerMeasure():Int { diff --git a/source/funkin/input/Cursor.hx b/source/funkin/input/Cursor.hx index 37e819469..edd9e70f3 100644 --- a/source/funkin/input/Cursor.hx +++ b/source/funkin/input/Cursor.hx @@ -4,9 +4,34 @@ import openfl.utils.Assets; import lime.app.Future; import openfl.display.BitmapData; +@:nullSafety class Cursor { - public static var cursorMode(default, set):CursorMode; + /** + * The current cursor mode. + * Set this value to change the cursor graphic. + */ + public static var cursorMode(default, set):Null = null; + + /** + * Show the cursor. + */ + public static inline function show():Void + { + FlxG.mouse.visible = true; + // Reset the cursor mode. + Cursor.cursorMode = Default; + } + + /** + * Hide the cursor. + */ + public static inline function hide():Void + { + FlxG.mouse.visible = false; + // Reset the cursor mode. + Cursor.cursorMode = null; + } static final CURSOR_DEFAULT_PARAMS:CursorParams = { @@ -15,7 +40,7 @@ class Cursor offsetX: 0, offsetY: 0, }; - static var assetCursorDefault:BitmapData = null; + static var assetCursorDefault:Null = null; static final CURSOR_CROSS_PARAMS:CursorParams = { @@ -24,7 +49,7 @@ class Cursor offsetX: 0, offsetY: 0, }; - static var assetCursorCross:BitmapData = null; + static var assetCursorCross:Null = null; static final CURSOR_ERASER_PARAMS:CursorParams = { @@ -33,16 +58,16 @@ class Cursor offsetX: 0, offsetY: 0, }; - static var assetCursorEraser:BitmapData = null; + static var assetCursorEraser:Null = null; static final CURSOR_GRABBING_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-grabbing.png", scale: 1.0, - offsetX: 32, + offsetX: -8, offsetY: 0, }; - static var assetCursorGrabbing:BitmapData = null; + static var assetCursorGrabbing:Null = null; static final CURSOR_HOURGLASS_PARAMS:CursorParams = { @@ -51,25 +76,34 @@ class Cursor offsetX: 0, offsetY: 0, }; - static var assetCursorHourglass:BitmapData = null; + static var assetCursorHourglass:Null = null; static final CURSOR_POINTER_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-pointer.png", scale: 1.0, - offsetX: 8, + offsetX: -8, offsetY: 0, }; - static var assetCursorPointer:BitmapData = null; + static var assetCursorPointer:Null = null; static final CURSOR_TEXT_PARAMS:CursorParams = { graphic: "assets/images/cursor/cursor-text.png", - scale: 1.0, + scale: 0.2, offsetX: 0, offsetY: 0, }; - static var assetCursorText:BitmapData = null; + static var assetCursorText:Null = null; + + static final CURSOR_TEXT_VERTICAL_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-text-vertical.png", + scale: 0.2, + offsetX: 0, + offsetY: 0, + }; + static var assetCursorTextVertical:Null = null; static final CURSOR_ZOOM_IN_PARAMS:CursorParams = { @@ -78,7 +112,7 @@ class Cursor offsetX: 0, offsetY: 0, }; - static var assetCursorZoomIn:BitmapData = null; + static var assetCursorZoomIn:Null = null; static final CURSOR_ZOOM_OUT_PARAMS:CursorParams = { @@ -87,11 +121,36 @@ class Cursor offsetX: 0, offsetY: 0, }; - static var assetCursorZoomOut:BitmapData = null; + static var assetCursorZoomOut:Null = null; - static function set_cursorMode(value:CursorMode):CursorMode + static final CURSOR_CROSSHAIR_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-crosshair.png", + scale: 1.0, + offsetX: -16, + offsetY: -16, + }; + static var assetCursorCrosshair:Null = null; + + static final CURSOR_CELL_PARAMS:CursorParams = + { + graphic: "assets/images/cursor/cursor-cell.png", + scale: 1.0, + offsetX: -16, + offsetY: -16, + }; + static var assetCursorCell:Null = null; + + // DESIRED CURSOR: Resize NS (vertical) + // DESIRED CURSOR: Resize EW (horizontal) + // DESIRED CURSOR: Resize NESW (diagonal) + // DESIRED CURSOR: Resize NWSE (diagonal) + // DESIRED CURSOR: Help (Cursor with question mark) + // DESIRED CURSOR: Menu (Cursor with menu icon) + + static function set_cursorMode(value:Null):Null { - if (cursorMode != value) + if (value != null && cursorMode != value) { cursorMode = value; setCursorGraphic(cursorMode); @@ -99,16 +158,9 @@ class Cursor return cursorMode; } - public static inline function show():Void - { - FlxG.mouse.visible = true; - } - - public static inline function hide():Void - { - FlxG.mouse.visible = false; - } - + /** + * Synchronous. + */ static function setCursorGraphic(?value:CursorMode = null):Void { if (value == null) @@ -117,6 +169,156 @@ class Cursor return; } + switch (value) + { + case Default: + if (assetCursorDefault == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_DEFAULT_PARAMS.graphic); + assetCursorDefault = bitmapData; + applyCursorParams(assetCursorDefault, CURSOR_DEFAULT_PARAMS); + } + else + { + applyCursorParams(assetCursorDefault, CURSOR_DEFAULT_PARAMS); + } + + case Cross: + if (assetCursorCross == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_CROSS_PARAMS.graphic); + assetCursorCross = bitmapData; + applyCursorParams(assetCursorCross, CURSOR_CROSS_PARAMS); + } + else + { + applyCursorParams(assetCursorCross, CURSOR_CROSS_PARAMS); + } + + case Eraser: + if (assetCursorEraser == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_ERASER_PARAMS.graphic); + assetCursorEraser = bitmapData; + applyCursorParams(assetCursorEraser, CURSOR_ERASER_PARAMS); + } + else + { + applyCursorParams(assetCursorEraser, CURSOR_ERASER_PARAMS); + } + + case Grabbing: + if (assetCursorGrabbing == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_GRABBING_PARAMS.graphic); + assetCursorGrabbing = bitmapData; + applyCursorParams(assetCursorGrabbing, CURSOR_GRABBING_PARAMS); + } + else + { + applyCursorParams(assetCursorGrabbing, CURSOR_GRABBING_PARAMS); + } + + case Hourglass: + if (assetCursorHourglass == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_HOURGLASS_PARAMS.graphic); + assetCursorHourglass = bitmapData; + applyCursorParams(assetCursorHourglass, CURSOR_HOURGLASS_PARAMS); + } + else + { + applyCursorParams(assetCursorHourglass, CURSOR_HOURGLASS_PARAMS); + } + + case Pointer: + if (assetCursorPointer == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_POINTER_PARAMS.graphic); + assetCursorPointer = bitmapData; + applyCursorParams(assetCursorPointer, CURSOR_POINTER_PARAMS); + } + else + { + applyCursorParams(assetCursorPointer, CURSOR_POINTER_PARAMS); + } + + case Text: + if (assetCursorText == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_TEXT_PARAMS.graphic); + assetCursorText = bitmapData; + applyCursorParams(assetCursorText, CURSOR_TEXT_PARAMS); + } + else + { + applyCursorParams(assetCursorText, CURSOR_TEXT_PARAMS); + } + + case ZoomIn: + if (assetCursorZoomIn == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_ZOOM_IN_PARAMS.graphic); + assetCursorZoomIn = bitmapData; + applyCursorParams(assetCursorZoomIn, CURSOR_ZOOM_IN_PARAMS); + } + else + { + applyCursorParams(assetCursorZoomIn, CURSOR_ZOOM_IN_PARAMS); + } + + case ZoomOut: + if (assetCursorZoomOut == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_ZOOM_OUT_PARAMS.graphic); + assetCursorZoomOut = bitmapData; + applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); + } + else + { + applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); + } + + case Crosshair: + if (assetCursorCrosshair == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_CROSSHAIR_PARAMS.graphic); + assetCursorCrosshair = bitmapData; + applyCursorParams(assetCursorCrosshair, CURSOR_CROSSHAIR_PARAMS); + } + else + { + applyCursorParams(assetCursorCrosshair, CURSOR_CROSSHAIR_PARAMS); + } + + case Cell: + if (assetCursorCell == null) + { + var bitmapData:BitmapData = Assets.getBitmapData(CURSOR_CELL_PARAMS.graphic); + assetCursorCell = bitmapData; + applyCursorParams(assetCursorCell, CURSOR_CELL_PARAMS); + } + else + { + applyCursorParams(assetCursorCell, CURSOR_CELL_PARAMS); + } + + default: + setCursorGraphic(null); + } + } + + /** + * Asynchronous. + */ + static function loadCursorGraphic(?value:CursorMode = null):Void + { + if (value == null) + { + FlxG.mouse.unload(); + return; + } + switch (value) { case Default: @@ -127,6 +329,7 @@ class Cursor assetCursorDefault = bitmapData; applyCursorParams(assetCursorDefault, CURSOR_DEFAULT_PARAMS); }); + future.onError(onCursorError.bind(Default)); } else { @@ -141,6 +344,7 @@ class Cursor assetCursorCross = bitmapData; applyCursorParams(assetCursorCross, CURSOR_CROSS_PARAMS); }); + future.onError(onCursorError.bind(Cross)); } else { @@ -155,6 +359,7 @@ class Cursor assetCursorEraser = bitmapData; applyCursorParams(assetCursorEraser, CURSOR_ERASER_PARAMS); }); + future.onError(onCursorError.bind(Eraser)); } else { @@ -169,6 +374,7 @@ class Cursor assetCursorGrabbing = bitmapData; applyCursorParams(assetCursorGrabbing, CURSOR_GRABBING_PARAMS); }); + future.onError(onCursorError.bind(Grabbing)); } else { @@ -183,6 +389,7 @@ class Cursor assetCursorHourglass = bitmapData; applyCursorParams(assetCursorHourglass, CURSOR_HOURGLASS_PARAMS); }); + future.onError(onCursorError.bind(Hourglass)); } else { @@ -197,6 +404,7 @@ class Cursor assetCursorPointer = bitmapData; applyCursorParams(assetCursorPointer, CURSOR_POINTER_PARAMS); }); + future.onError(onCursorError.bind(Pointer)); } else { @@ -211,6 +419,7 @@ class Cursor assetCursorText = bitmapData; applyCursorParams(assetCursorText, CURSOR_TEXT_PARAMS); }); + future.onError(onCursorError.bind(Text)); } else { @@ -225,6 +434,7 @@ class Cursor assetCursorZoomIn = bitmapData; applyCursorParams(assetCursorZoomIn, CURSOR_ZOOM_IN_PARAMS); }); + future.onError(onCursorError.bind(ZoomIn)); } else { @@ -239,14 +449,45 @@ class Cursor assetCursorZoomOut = bitmapData; applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); }); + future.onError(onCursorError.bind(ZoomOut)); } else { applyCursorParams(assetCursorZoomOut, CURSOR_ZOOM_OUT_PARAMS); } + case Crosshair: + if (assetCursorCrosshair == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_CROSSHAIR_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) { + assetCursorCrosshair = bitmapData; + applyCursorParams(assetCursorCrosshair, CURSOR_CROSSHAIR_PARAMS); + }); + future.onError(onCursorError.bind(Crosshair)); + } + else + { + applyCursorParams(assetCursorCrosshair, CURSOR_CROSSHAIR_PARAMS); + } + + case Cell: + if (assetCursorCell == null) + { + var future:Future = Assets.loadBitmapData(CURSOR_CELL_PARAMS.graphic); + future.onComplete(function(bitmapData:BitmapData) { + assetCursorCell = bitmapData; + applyCursorParams(assetCursorCell, CURSOR_CELL_PARAMS); + }); + future.onError(onCursorError.bind(Cell)); + } + else + { + applyCursorParams(assetCursorCell, CURSOR_CELL_PARAMS); + } + default: - setCursorGraphic(null); + loadCursorGraphic(null); } } @@ -254,6 +495,11 @@ class Cursor { FlxG.mouse.load(graphic, params.scale, params.offsetX, params.offsetY); } + + static function onCursorError(cursorMode:CursorMode, error:String):Void + { + trace("Failed to load cursor graphic for cursor mode " + cursorMode + ": " + error); + } } // https://developer.mozilla.org/en-US/docs/Web/CSS/cursor @@ -268,6 +514,8 @@ enum CursorMode Text; ZoomIn; ZoomOut; + Crosshair; + Cell; } /** diff --git a/source/funkin/input/TurboKeyHandler.hx b/source/funkin/input/TurboKeyHandler.hx index 3719ff7cc..099d373b4 100644 --- a/source/funkin/input/TurboKeyHandler.hx +++ b/source/funkin/input/TurboKeyHandler.hx @@ -26,7 +26,7 @@ class TurboKeyHandler extends FlxBasic /** * Whether all of the keys for this handler are pressed. */ - public var allPressed(get, null):Bool; + public var allPressed(get, never):Bool; /** * Whether all of the keys for this handler are activated, diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index ed82d6e99..068f32f97 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -251,14 +251,14 @@ class PlayState extends MusicBeatSubState var overrideMusic:Bool = false; - public var isSubState(get, null):Bool; + public var isSubState(get, never):Bool; function get_isSubState():Bool { return this._parentState != null; } - public var isChartingMode(get, null):Bool; + public var isChartingMode(get, never):Bool; function get_isChartingMode():Bool { @@ -427,7 +427,7 @@ class PlayState extends MusicBeatSubState * Data for the current difficulty for the current song. * Includes chart data, scroll speed, and other information. */ - public var currentChart(get, null):SongDifficulty; + public var currentChart(get, never):SongDifficulty; function get_currentChart():SongDifficulty { @@ -439,7 +439,7 @@ class PlayState extends MusicBeatSubState * The internal ID of the currently active Stage. * Used to retrieve the data required to build the `currentStage`. */ - public var currentStageId(get, null):String; + public var currentStageId(get, never):String; function get_currentStageId():String { diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index c7b58c393..30b549fd3 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -66,7 +66,7 @@ class BaseCharacter extends Bopper * The offset between the corner of the sprite and the origin of the sprite (at the character's feet). * cornerPosition = stageData - characterOrigin */ - public var characterOrigin(get, null):FlxPoint; + public var characterOrigin(get, never):FlxPoint; function get_characterOrigin():FlxPoint { @@ -103,7 +103,7 @@ class BaseCharacter extends Bopper /** * The absolute position of the character's feet, at the bottom-center of the sprite. */ - public var feetPosition(get, null):FlxPoint; + public var feetPosition(get, never):FlxPoint; function get_feetPosition():FlxPoint { @@ -264,7 +264,7 @@ class BaseCharacter extends Bopper /** * The per-character camera offset. */ - var characterCameraOffsets(get, null):Array; + var characterCameraOffsets(get, never):Array; function get_characterCameraOffsets():Array { diff --git a/source/funkin/play/cutscene/dialogue/Conversation.hx b/source/funkin/play/cutscene/dialogue/Conversation.hx index a6851f0f9..2b7db381c 100644 --- a/source/funkin/play/cutscene/dialogue/Conversation.hx +++ b/source/funkin/play/cutscene/dialogue/Conversation.hx @@ -50,7 +50,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass */ var currentDialogueEntry:Int = 0; - var currentDialogueEntryCount(get, null):Int; + var currentDialogueEntryCount(get, never):Int; function get_currentDialogueEntryCount():Int { @@ -62,14 +62,14 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass * **/ var currentDialogueLine:Int = 0; - var currentDialogueLineCount(get, null):Int; + var currentDialogueLineCount(get, never):Int; function get_currentDialogueLineCount():Int { return currentDialogueEntryData.text.length; } - var currentDialogueEntryData(get, null):DialogueEntryData; + var currentDialogueEntryData(get, never):DialogueEntryData; function get_currentDialogueEntryData():DialogueEntryData { @@ -79,7 +79,7 @@ class Conversation extends FlxSpriteGroup implements IDialogueScriptedClass return conversationData.dialogue[currentDialogueEntry]; } - var currentDialogueLineString(get, null):String; + var currentDialogueLineString(get, never):String; function get_currentDialogueLineString():String { diff --git a/source/funkin/play/cutscene/dialogue/DialogueBox.hx b/source/funkin/play/cutscene/dialogue/DialogueBox.hx index bfc0e9233..cdac3c233 100644 --- a/source/funkin/play/cutscene/dialogue/DialogueBox.hx +++ b/source/funkin/play/cutscene/dialogue/DialogueBox.hx @@ -13,7 +13,7 @@ import flixel.util.FlxColor; class DialogueBox extends FlxSpriteGroup implements IDialogueScriptedClass { public final dialogueBoxId:String; - public var dialogueBoxName(get, null):String; + public var dialogueBoxName(get, never):String; function get_dialogueBoxName():String { diff --git a/source/funkin/play/cutscene/dialogue/Speaker.hx b/source/funkin/play/cutscene/dialogue/Speaker.hx index 1fb341009..d7ed004f1 100644 --- a/source/funkin/play/cutscene/dialogue/Speaker.hx +++ b/source/funkin/play/cutscene/dialogue/Speaker.hx @@ -8,7 +8,7 @@ import funkin.modding.IScriptedClass.IDialogueScriptedClass; /** * The character sprite which displays during dialogue. - * + * * Most conversations have two speakers, with one being flipped. */ class Speaker extends FlxSprite implements IDialogueScriptedClass @@ -26,7 +26,7 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass /** * A readable name for this speaker. */ - public var speakerName(get, null):String; + public var speakerName(get, never):String; function get_speakerName():String { @@ -129,7 +129,7 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass /** * Set the sprite scale to the appropriate value. - * @param scale + * @param scale */ public function setScale(scale:Null):Void { @@ -184,7 +184,7 @@ class Speaker extends FlxSprite implements IDialogueScriptedClass /** * Ensure that a given animation exists before playing it. * Will gracefully check for name, then name with stripped suffixes, then 'idle', then fail to play. - * @param name + * @param name */ function correctAnimationName(name:String):String { diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 8847636bd..2b21e6b7e 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -31,7 +31,7 @@ class Strumline extends FlxSpriteGroup static final KEY_COUNT:Int = 4; static final NOTE_SPLASH_CAP:Int = 6; - static var RENDER_DISTANCE_MS(get, null):Float; + static var RENDER_DISTANCE_MS(get, never):Float; static function get_RENDER_DISTANCE_MS():Float { diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index 72d22191b..4bcbe0528 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -31,7 +31,7 @@ class SustainTrail extends FlxSprite public var noteDirection:NoteDirection = 0; public var sustainLength(default, set):Float = 0; // millis public var fullSustainLength:Float = 0; - public var noteData:SongNoteData; + public var noteData:Null; public var cover:NoteHoldCover = null; diff --git a/source/funkin/play/song/SongMigrator.hx b/source/funkin/play/song/SongMigrator.hx index bb8718bb7..f33d9bbe9 100644 --- a/source/funkin/play/song/SongMigrator.hx +++ b/source/funkin/play/song/SongMigrator.hx @@ -179,7 +179,7 @@ class SongMigrator songMetadata.playData.playableChars = {}; try { - Reflect.setField(songMetadata.playData.playableChars, songData.song.player1, new SongPlayableChar('', songData.song.player2)); + songMetadata.playData.playableChars.set(songData.song.player1, new SongPlayableChar('', songData.song.player2)); } catch (e) { diff --git a/source/funkin/play/song/SongValidator.hx b/source/funkin/play/song/SongValidator.hx index 16ea88664..11cc758b9 100644 --- a/source/funkin/play/song/SongValidator.hx +++ b/source/funkin/play/song/SongValidator.hx @@ -20,7 +20,7 @@ class SongValidator public static final DEFAULT_STAGE:String = "mainStage"; public static final DEFAULT_SCROLLSPEED:Float = 1.0; - public static var DEFAULT_GENERATEDBY(get, null):String; + public static var DEFAULT_GENERATEDBY(get, never):String; static function get_DEFAULT_GENERATEDBY():String { diff --git a/source/funkin/ui/debug/charting/ChartEditorCommand.hx b/source/funkin/ui/debug/charting/ChartEditorCommand.hx index fd179c481..f0ecb573b 100644 --- a/source/funkin/ui/debug/charting/ChartEditorCommand.hx +++ b/source/funkin/ui/debug/charting/ChartEditorCommand.hx @@ -35,6 +35,7 @@ interface ChartEditorCommand public function toString():String; } +@:nullSafety class AddNotesCommand implements ChartEditorCommand { var notes:Array; @@ -98,6 +99,7 @@ class AddNotesCommand implements ChartEditorCommand } } +@:nullSafety class RemoveNotesCommand implements ChartEditorCommand { var notes:Array; @@ -153,6 +155,7 @@ class RemoveNotesCommand implements ChartEditorCommand /** * Appends one or more items to the selection. */ +@:nullSafety class SelectItemsCommand implements ChartEditorCommand { var notes:Array; @@ -220,6 +223,7 @@ class SelectItemsCommand implements ChartEditorCommand } } +@:nullSafety class AddEventsCommand implements ChartEditorCommand { var events:Array; @@ -278,6 +282,7 @@ class AddEventsCommand implements ChartEditorCommand } } +@:nullSafety class RemoveEventsCommand implements ChartEditorCommand { var events:Array; @@ -327,6 +332,7 @@ class RemoveEventsCommand implements ChartEditorCommand } } +@:nullSafety class RemoveItemsCommand implements ChartEditorCommand { var notes:Array; @@ -385,6 +391,7 @@ class RemoveItemsCommand implements ChartEditorCommand } } +@:nullSafety class SwitchDifficultyCommand implements ChartEditorCommand { var prevDifficulty:String; @@ -424,6 +431,7 @@ class SwitchDifficultyCommand implements ChartEditorCommand } } +@:nullSafety class DeselectItemsCommand implements ChartEditorCommand { var notes:Array; @@ -478,6 +486,7 @@ class DeselectItemsCommand implements ChartEditorCommand * Sets the selection rather than appends it. * Deselects any notes that are not in the new selection. */ +@:nullSafety class SetItemSelectionCommand implements ChartEditorCommand { var notes:Array; @@ -518,6 +527,7 @@ class SetItemSelectionCommand implements ChartEditorCommand } } +@:nullSafety class SelectAllItemsCommand implements ChartEditorCommand { var previousNoteSelection:Array; @@ -553,6 +563,7 @@ class SelectAllItemsCommand implements ChartEditorCommand } } +@:nullSafety class InvertSelectedItemsCommand implements ChartEditorCommand { var previousNoteSelection:Array; @@ -587,6 +598,7 @@ class InvertSelectedItemsCommand implements ChartEditorCommand } } +@:nullSafety class DeselectAllItemsCommand implements ChartEditorCommand { var previousNoteSelection:Array; @@ -622,6 +634,7 @@ class DeselectAllItemsCommand implements ChartEditorCommand } } +@:nullSafety class CutItemsCommand implements ChartEditorCommand { var notes:Array; @@ -679,14 +692,16 @@ class CutItemsCommand implements ChartEditorCommand } } +@:nullSafety class FlipNotesCommand implements ChartEditorCommand { - var notes:Array; - var flippedNotes:Array; + var notes:Array = []; + var flippedNotes:Array = []; public function new(notes:Array) { this.notes = notes; + this.flippedNotes = SongDataUtils.flipNotes(notes); } public function execute(state:ChartEditorState):Void @@ -695,7 +710,6 @@ class FlipNotesCommand implements ChartEditorCommand state.currentSongChartNoteData = SongDataUtils.subtractNotes(state.currentSongChartNoteData, notes); // Add the flipped notes. - flippedNotes = SongDataUtils.flipNotes(notes); state.currentSongChartNoteData = state.currentSongChartNoteData.concat(flippedNotes); state.currentNoteSelection = flippedNotes; @@ -729,12 +743,13 @@ class FlipNotesCommand implements ChartEditorCommand } } +@:nullSafety class PasteItemsCommand implements ChartEditorCommand { var targetTimestamp:Float; // Notes we added with this command, for undo. - var addedNotes:Array; - var addedEvents:Array; + var addedNotes:Array = []; + var addedEvents:Array = []; public function new(targetTimestamp:Float) { @@ -787,6 +802,7 @@ class PasteItemsCommand implements ChartEditorCommand } } +@:nullSafety class ExtendNoteLengthCommand implements ChartEditorCommand { var note:SongNoteData; diff --git a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx index 276a14a32..59bee0d74 100644 --- a/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx +++ b/source/funkin/ui/debug/charting/ChartEditorDialogHandler.hx @@ -6,6 +6,7 @@ import funkin.util.SerializerUtil; import funkin.play.song.SongData.SongChartData; import funkin.play.song.SongData.SongMetadata; import flixel.util.FlxTimer; +import funkin.ui.haxeui.components.FunkinLink; import funkin.util.SortUtil; import funkin.input.Cursor; import funkin.play.character.BaseCharacter; @@ -40,6 +41,7 @@ using Lambda; /** * Handles dialogs for the new Chart Editor. */ +@:nullSafety class ChartEditorDialogHandler { static final CHART_EDITOR_DIALOG_ABOUT_LAYOUT:String = Paths.ui('chart-editor/dialogs/about'); @@ -59,7 +61,7 @@ class ChartEditorDialogHandler * @param state The current chart editor state. * @return The dialog that was opened. */ - public static inline function openAboutDialog(state:ChartEditorState):Dialog + public static inline function openAboutDialog(state:ChartEditorState):Null { return openDialog(state, CHART_EDITOR_DIALOG_ABOUT_LAYOUT, true, true); } @@ -70,12 +72,14 @@ class ChartEditorDialogHandler * @param closable Whether the dialog can be closed by the user. * @return The dialog that was opened. */ - public static function openWelcomeDialog(state:ChartEditorState, closable:Bool = true):Dialog + public static function openWelcomeDialog(state:ChartEditorState, closable:Bool = true):Null { - var dialog:Dialog = openDialog(state, CHART_EDITOR_DIALOG_WELCOME_LAYOUT, true, closable); + var dialog:Null = openDialog(state, CHART_EDITOR_DIALOG_WELCOME_LAYOUT, true, closable); + if (dialog == null) throw 'Could not locate Welcome dialog'; // Add handlers to the "Create From Song" section. - var linkCreateBasic:Link = dialog.findComponent('splashCreateFromSongBasic', Link); + var linkCreateBasic:Null = dialog.findComponent('splashCreateFromSongBasic', Link); + if (linkCreateBasic == null) throw 'Could not locate splashCreateFromSongBasic link in Welcome dialog'; linkCreateBasic.onClick = function(_event) { // Hide the welcome dialog dialog.hideDialog(DialogButton.CANCEL); @@ -86,7 +90,8 @@ class ChartEditorDialogHandler openCreateSongWizard(state, false); } - var linkImportChartLegacy:Link = dialog.findComponent('splashImportChartLegacy', Link); + var linkImportChartLegacy:Null = dialog.findComponent('splashImportChartLegacy', Link); + if (linkImportChartLegacy == null) throw 'Could not locate splashImportChartLegacy link in Welcome dialog'; linkImportChartLegacy.onClick = function(_event) { // Hide the welcome dialog dialog.hideDialog(DialogButton.CANCEL); @@ -95,7 +100,8 @@ class ChartEditorDialogHandler openImportChartWizard(state, 'legacy', false); }; - var buttonBrowse:Button = dialog.findComponent('splashBrowse', Button); + var buttonBrowse:Null