diff --git a/art b/art index 00463685f..03e7c2a23 160000 --- a/art +++ b/art @@ -1 +1 @@ -Subproject commit 00463685fa570f0c853d08e250b46ef80f30bc48 +Subproject commit 03e7c2a2353b184e45955c96d763b7cdf1acbc34 diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 7ac6382f2..104682ffd 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -39,27 +39,39 @@ class Conductor static var _instance:Null = null; - static function get_instance():Conductor - { - if (_instance == null) _instance = new Conductor(); - return _instance; - } - /** - * Signal fired when the current Conductor instance advances to a new measure. + * Signal fired when the current static Conductor instance advances to a new measure. */ public static var measureHit(default, null):FlxSignal = new FlxSignal(); + /** + * Signal fired when THIS Conductor instance advances to a new measure. + * TODO: This naming sucks but we can't make a static and instance field with the same name! + */ + public var onMeasureHit(default, null):FlxSignal = new FlxSignal(); + /** * Signal fired when the current Conductor instance advances to a new beat. */ public static var beatHit(default, null):FlxSignal = new FlxSignal(); + /** + * Signal fired when THIS Conductor instance advances to a new beat. + * TODO: This naming sucks but we can't make a static and instance field with the same name! + */ + public var onBeatHit(default, null):FlxSignal = new FlxSignal(); + /** * Signal fired when the current Conductor instance advances to a new step. */ public static var stepHit(default, null):FlxSignal = new FlxSignal(); + /** + * Signal fired when THIS Conductor instance advances to a new step. + * TODO: This naming sucks but we can't make a static and instance field with the same name! + */ + public var onStepHit(default, null):FlxSignal = new FlxSignal(); + /** * The list of time changes in the song. * There should be at least one time change (at the beginning of the song) to define the BPM. @@ -247,6 +259,69 @@ class Conductor return Std.int(timeSignatureNumerator / timeSignatureDenominator * Constants.STEPS_PER_BEAT * Constants.STEPS_PER_BEAT); } + /** + * Reset the Conductor, replacing the current instance with a fresh one. + */ + public static function reset():Void + { + set_instance(new Conductor()); + } + + static function dispatchMeasureHit():Void + { + Conductor.measureHit.dispatch(); + } + + static function dispatchBeatHit():Void + { + Conductor.beatHit.dispatch(); + } + + static function dispatchStepHit():Void + { + Conductor.stepHit.dispatch(); + } + + static function setupSingleton(input:Conductor):Void + { + input.onMeasureHit.add(dispatchMeasureHit); + + input.onBeatHit.add(dispatchBeatHit); + + input.onStepHit.add(dispatchStepHit); + } + + static function clearSingleton(input:Conductor):Void + { + input.onMeasureHit.remove(dispatchMeasureHit); + + input.onBeatHit.remove(dispatchBeatHit); + + input.onStepHit.remove(dispatchStepHit); + } + + static function get_instance():Conductor + { + if (Conductor._instance == null) set_instance(new Conductor()); + if (Conductor._instance == null) throw "Could not initialize singleton Conductor!"; + return Conductor._instance; + } + + static function set_instance(instance:Conductor):Conductor + { + // Use _instance in here to avoid recursion + if (Conductor._instance != null) clearSingleton(Conductor._instance); + + Conductor._instance = instance; + + if (Conductor._instance != null) setupSingleton(Conductor._instance); + + return Conductor._instance; + } + + /** + * The constructor. + */ public function new() {} /** @@ -257,6 +332,7 @@ class Conductor * * WARNING: Avoid this for things like setting the BPM of the title screen music, * you should have a metadata file for it instead. + * We should probably deprecate this in the future. */ public function forceBPM(?bpm:Float):Void { @@ -277,7 +353,7 @@ class Conductor * BPM, current step, etc. will be re-calculated based on the song position. * * @param songPosition The current position in the song in milliseconds. - * Leave blank to use the FlxG.sound.music position. + * Leave blank to use the `FlxG.sound.music` position. */ public function update(?songPos:Float):Void { @@ -330,24 +406,20 @@ class Conductor this.currentMeasure = Math.floor(currentMeasureTime); } - // Only fire the signal if we are THE Conductor. - if (this == Conductor.instance) + // FlxSignals are really cool. + if (currentStep != oldStep) { - // FlxSignals are really cool. - if (currentStep != oldStep) - { - Conductor.stepHit.dispatch(); - } + this.onStepHit.dispatch(); + } - if (currentBeat != oldBeat) - { - Conductor.beatHit.dispatch(); - } + if (currentBeat != oldBeat) + { + this.onBeatHit.dispatch(); + } - if (currentMeasure != oldMeasure) - { - Conductor.measureHit.dispatch(); - } + if (currentMeasure != oldMeasure) + { + this.onMeasureHit.dispatch(); } } @@ -517,20 +589,14 @@ class Conductor /** * Add variables of the current Conductor instance to the Flixel debugger. */ - public static function watchQuick():Void + public static function watchQuick(?target:Conductor):Void { - FlxG.watch.addQuick('songPosition', Conductor.instance.songPosition); - FlxG.watch.addQuick('bpm', Conductor.instance.bpm); - FlxG.watch.addQuick('currentMeasureTime', Conductor.instance.currentMeasureTime); - FlxG.watch.addQuick('currentBeatTime', Conductor.instance.currentBeatTime); - FlxG.watch.addQuick('currentStepTime', Conductor.instance.currentStepTime); - } + if (target == null) target = Conductor.instance; - /** - * Reset the Conductor, replacing the current instance with a fresh one. - */ - public static function reset():Void - { - _instance = new Conductor(); + FlxG.watch.addQuick('songPosition', target.songPosition); + FlxG.watch.addQuick('bpm', target.bpm); + FlxG.watch.addQuick('currentMeasureTime', target.currentMeasureTime); + FlxG.watch.addQuick('currentBeatTime', target.currentBeatTime); + FlxG.watch.addQuick('currentStepTime', target.currentStepTime); } } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 572eb6135..4e388407e 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -813,6 +813,7 @@ class PlayState extends MusicBeatSubState super.update(elapsed); + var list = FlxG.sound.list; updateHealthBar(); updateScoreText(); @@ -969,7 +970,7 @@ class PlayState extends MusicBeatSubState if (health < Constants.HEALTH_MIN) health = Constants.HEALTH_MIN; // Apply camera zoom + multipliers. - if (subState == null && cameraZoomRate > 0.0 && !isInCutscene) + if (subState == null && cameraZoomRate > 0.0) // && !isInCutscene) { cameraBopMultiplier = FlxMath.lerp(1.0, cameraBopMultiplier, 0.95); // Lerp bop multiplier back to 1.0x var zoomPlusBop = currentCameraZoom * cameraBopMultiplier; // Apply camera bop multiplier. @@ -1869,6 +1870,8 @@ class PlayState extends MusicBeatSubState isInCutscene = false; camCutscene.visible = false; + + // TODO: Maybe tween in the camera after any cutscenes. camHUD.visible = true; } diff --git a/source/funkin/play/event/FocusCameraSongEvent.hx b/source/funkin/play/event/FocusCameraSongEvent.hx index 1bcac9ad3..569dcb87a 100644 --- a/source/funkin/play/event/FocusCameraSongEvent.hx +++ b/source/funkin/play/event/FocusCameraSongEvent.hx @@ -127,7 +127,7 @@ class FocusCameraSongEvent extends SongEvent switch (ease) { case 'CLASSIC': // Old-school. No ease. Just set follow point. - PlayState.instance.cancelCameraFollowTween(); + PlayState.instance.resetCamera(); PlayState.instance.cameraFollowPoint.setPosition(targetX, targetY); case 'INSTANT': // Instant ease. Duration is automatically 0. PlayState.instance.tweenCameraToPosition(targetX, targetY, 0); diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index 75766a75a..6c05e19e8 100644 --- a/source/funkin/util/Constants.hx +++ b/source/funkin/util/Constants.hx @@ -218,7 +218,7 @@ class Constants public static final DEFAULT_VARIATION:String = 'default'; /** - * Standard variations used by the game. + * Standardized variations for charts */ public static final DEFAULT_VARIATION_LIST:Array = ['default', 'erect', 'pico'];