From 51d36ea25e11466de297457cca75caba65e0556e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 24 Mar 2024 04:53:05 -0400 Subject: [PATCH 1/7] Work in progress on fixing Boyfriend's spook/tv animations --- .../graphics/adobeanimate/FlxAtlasSprite.hx | 17 +++ source/funkin/ui/freeplay/DJBoyfriend.hx | 133 ++++++++++++++---- source/funkin/ui/freeplay/FreeplayState.hx | 56 ++++---- 3 files changed, 145 insertions(+), 61 deletions(-) diff --git a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx index c5a3a3771..5394bce1a 100644 --- a/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx +++ b/source/funkin/graphics/adobeanimate/FlxAtlasSprite.hx @@ -79,6 +79,23 @@ class FlxAtlasSprite extends FlxAnimate return this.currentAnimation; } + /** + * `anim.finished` always returns false on looping animations, + * but this function will return true if we are on the last frame of the looping animation. + */ + public function isLoopFinished():Bool + { + if (this.anim == null) return false; + if (!this.anim.isPlaying) return false; + + // Reverse animation finished. + if (this.anim.reversed && this.anim.curFrame == 0) return true; + // Forward animation finished. + if (!this.anim.reversed && this.anim.curFrame >= (this.anim.length - 1)) return true; + + return false; + } + /** * Plays an animation. * @param id A string ID of the animation to play. diff --git a/source/funkin/ui/freeplay/DJBoyfriend.hx b/source/funkin/ui/freeplay/DJBoyfriend.hx index 8cd63dba1..c77762d73 100644 --- a/source/funkin/ui/freeplay/DJBoyfriend.hx +++ b/source/funkin/ui/freeplay/DJBoyfriend.hx @@ -4,6 +4,7 @@ import flixel.FlxSprite; import flixel.util.FlxSignal; import funkin.util.assets.FlxAnimationUtil; import funkin.graphics.adobeanimate.FlxAtlasSprite; +import funkin.audio.FunkinSound; import flixel.util.FlxTimer; import funkin.audio.FunkinSound; import funkin.audio.FlxStreamSound; @@ -26,8 +27,8 @@ class DJBoyfriend extends FlxAtlasSprite var gotSpooked:Bool = false; - static final SPOOK_PERIOD:Float = 120.0; - static final TV_PERIOD:Float = 180.0; + static final SPOOK_PERIOD:Float = 10.0; + static final TV_PERIOD:Float = 10.0; // Time since dad last SPOOKED you. var timeSinceSpook:Float = 0; @@ -87,20 +88,21 @@ class DJBoyfriend extends FlxAtlasSprite timeSinceSpook = 0; case Idle: // We are in this state the majority of the time. - if (getCurrentAnimation() != 'Boyfriend DJ' || anim.finished) + if (getCurrentAnimation() != 'Boyfriend DJ') { - if (timeSinceSpook > SPOOK_PERIOD && !gotSpooked) + playFlashAnimation('Boyfriend DJ', true); + } + + if (getCurrentAnimation() == 'Boyfriend DJ' && this.isLoopFinished()) + { + if (timeSinceSpook >= SPOOK_PERIOD && !gotSpooked) { currentState = Spook; } - else if (timeSinceSpook > TV_PERIOD) + else if (timeSinceSpook >= TV_PERIOD) { currentState = TV; } - else - { - playFlashAnimation('Boyfriend DJ', false); - } } timeSinceSpook += elapsed; case Confirm: @@ -111,6 +113,7 @@ class DJBoyfriend extends FlxAtlasSprite { onSpook.dispatch(); playFlashAnimation('bf dj afk', false); + gotSpooked = true; } timeSinceSpook = 0; case TV: @@ -119,6 +122,34 @@ class DJBoyfriend extends FlxAtlasSprite default: // I shit myself. } + + if (FlxG.keys.pressed.CONTROL) + { + if (FlxG.keys.justPressed.LEFT) + { + this.offsetX -= FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); + } + + if (FlxG.keys.justPressed.RIGHT) + { + this.offsetX += FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); + } + + if (FlxG.keys.justPressed.UP) + { + this.offsetY -= FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); + } + + if (FlxG.keys.justPressed.DOWN) + { + this.offsetY += FlxG.keys.pressed.ALT ? 0.1 : (FlxG.keys.pressed.SHIFT ? 10.0 : 1.0); + } + + if (FlxG.keys.justPressed.SPACE) + { + currentState = (currentState == Idle ? TV : Idle); + } + } } function onFinishAnim():Void @@ -139,11 +170,15 @@ class DJBoyfriend extends FlxAtlasSprite case "Boyfriend DJ watchin tv OG": var frame:Int = FlxG.random.bool(33) ? 112 : 166; - if (FlxG.random.bool(10)) + + // BF switches channels when the video ends, or at a 10% chance each time his idle loops. + if (FlxG.random.bool(5)) { frame = 60; // boyfriend switches channel code? + // runTvLogic(); } + trace('Replay idle: ${frame}'); anim.play("Boyfriend DJ watchin tv OG", true, false, frame); // trace('Finished confirm'); } @@ -152,24 +187,31 @@ class DJBoyfriend extends FlxAtlasSprite public function resetAFKTimer():Void { timeSinceSpook = 0; + gotSpooked = false; } + var offsetX:Float = 0.0; + var offsetY:Float = 0.0; + function setupAnimations():Void { - // animation.addByPrefix('intro', "boyfriend dj intro", 24, false); - addOffset('boyfriend dj intro', 8, 3); + // Intro + addOffset('boyfriend dj intro', 8.0 - 1.3, 3.0 - 0.4); - // animation.addByPrefix('idle', "Boyfriend DJ0", 24, false); + // Idle addOffset('Boyfriend DJ', 0, 0); - // animation.addByPrefix('confirm', "Boyfriend DJ confirm", 24, false); + // Confirm addOffset('Boyfriend DJ confirm', 0, 0); - // animation.addByPrefix('spook', "bf dj afk0", 24, false); - addOffset('bf dj afk', 0, 0); + // AFK: Spook + addOffset('bf dj afk', 649.5, 58.5); + + // AFK: TV + addOffset('Boyfriend DJ watchin tv OG', 0, 0); } - var cartoonSnd:FlxStreamSound; + var cartoonSnd:Null = null; public var playingCartoon:Bool = false; @@ -178,39 +220,47 @@ class DJBoyfriend extends FlxAtlasSprite if (cartoonSnd == null) { // tv is OFF, but getting turned on - FunkinSound.playOnce(Paths.sound('tv_on')); - - cartoonSnd = new FlxStreamSound(); - FlxG.sound.defaultSoundGroup.add(cartoonSnd); + // Eric got FUCKING TROLLED there is no `tv_on` or `channel_switch` sound! + // FunkinSound.playOnce(Paths.sound('tv_on'), 1.0, function() { + // }); + loadCartoon(); } else { // plays it smidge after the click - new FlxTimer().start(0.1, function(_) { - FunkinSound.playOnce(Paths.sound('channel_switch')); - }); + // new FlxTimer().start(0.1, function(_) { + // // FunkinSound.playOnce(Paths.sound('channel_switch')); + // }); + cartoonSnd.destroy(); + loadCartoon(); } - // cartoonSnd.loadEmbedded(Paths.sound("cartoons/peck")); - // cartoonSnd.play(); - loadCartoon(); + // loadCartoon(); } function loadCartoon() { - cartoonSnd.loadEmbedded(Paths.sound(getRandomFlashToon()), false, false, function() { + cartoonSnd = FunkinSound.load(Paths.sound(getRandomFlashToon()), 1.0, false, true, true, function() { anim.play("Boyfriend DJ watchin tv OG", true, false, 60); }); - cartoonSnd.play(true, FlxG.random.float(0, cartoonSnd.length)); + + // Fade out music to 40% volume over 1 second. + // This helps make the TV a bit more audible. + FlxG.sound.music.fadeOut(1.0, 0.4); + + // Play the cartoon at a random time between the start and 5 seconds from the end. + cartoonSnd.time = FlxG.random.float(0, Math.max(cartoonSnd.length - (5 * Constants.MS_PER_SEC), 0.0)); } - var cartoonList:Array = openfl.utils.Assets.list().filter(function(path) return path.startsWith("assets/sounds/cartoons/")); + final cartoonList:Array = openfl.utils.Assets.list().filter(function(path) return path.startsWith("assets/sounds/cartoons/")); function getRandomFlashToon():String { var randomFile = FlxG.random.getObject(cartoonList); + // Strip folder prefix randomFile = randomFile.replace("assets/sounds/", ""); + // Strip file extension randomFile = randomFile.substring(0, randomFile.length - 4); return randomFile; @@ -244,10 +294,31 @@ class DJBoyfriend extends FlxAtlasSprite var daOffset = animOffsets.get(AnimName); if (animOffsets.exists(AnimName)) { - offset.set(daOffset[0], daOffset[1]); + var xValue = daOffset[0]; + var yValue = daOffset[1]; + if (AnimName == "Boyfriend DJ watchin tv OG") + { + xValue += offsetX; + yValue += offsetY; + } + + offset.set(xValue, yValue); } else + { offset.set(0, 0); + } + } + + public override function destroy():Void + { + super.destroy(); + + if (cartoonSnd != null) + { + cartoonSnd.destroy(); + cartoonSnd = null; + } } } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 249c7ffae..55c36e03f 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -688,14 +688,6 @@ class FreeplayState extends MusicBeatSubState if (FlxG.keys.justPressed.T) typing.hasFocus = true; - if (FlxG.sound.music != null) - { - if (FlxG.sound.music.volume < 0.7) - { - FlxG.sound.music.volume += 0.5 * elapsed; - } - } - lerpScore = MathUtil.coolLerp(lerpScore, intendedScore, 0.2); lerpCompletion = MathUtil.coolLerp(lerpCompletion, intendedCompletion, 0.9); @@ -733,9 +725,9 @@ class FreeplayState extends MusicBeatSubState { if (busy) return; - var upP:Bool = controls.UI_UP_P; - var downP:Bool = controls.UI_DOWN_P; - var accepted:Bool = controls.ACCEPT; + var upP:Bool = controls.UI_UP_P && !FlxG.keys.pressed.CONTROL; + var downP:Bool = controls.UI_DOWN_P && !FlxG.keys.pressed.CONTROL; + var accepted:Bool = controls.ACCEPT && !FlxG.keys.pressed.CONTROL; if (FlxG.onMobile) { @@ -809,10 +801,8 @@ class FreeplayState extends MusicBeatSubState } #end - if (controls.UI_UP || controls.UI_DOWN) + if (!FlxG.keys.pressed.CONTROL && (controls.UI_UP || controls.UI_DOWN)) { - spamTimer += elapsed; - if (spamming) { if (spamTimer >= 0.07) @@ -829,7 +819,24 @@ class FreeplayState extends MusicBeatSubState } } } - else if (spamTimer >= 0.9) spamming = true; + else if (spamTimer >= 0.9) + { + spamming = true; + } + else if (spamTimer <= 0) + { + if (controls.UI_UP) + { + changeSelection(-1); + } + else + { + changeSelection(1); + } + } + + spamTimer += elapsed; + dj.resetAFKTimer(); } else { @@ -837,29 +844,18 @@ class FreeplayState extends MusicBeatSubState spamTimer = 0; } - if (upP) - { - dj.resetAFKTimer(); - changeSelection(-1); - } - if (downP) - { - dj.resetAFKTimer(); - changeSelection(1); - } - if (FlxG.mouse.wheel != 0) { dj.resetAFKTimer(); changeSelection(-Math.round(FlxG.mouse.wheel / 4)); } - if (controls.UI_LEFT_P) + if (controls.UI_LEFT_P && !FlxG.keys.pressed.CONTROL) { dj.resetAFKTimer(); changeDiff(-1); } - if (controls.UI_RIGHT_P) + if (controls.UI_RIGHT_P && !FlxG.keys.pressed.CONTROL) { dj.resetAFKTimer(); changeDiff(1); @@ -1227,8 +1223,8 @@ class DifficultySelector extends FlxSprite override function update(elapsed:Float):Void { - if (flipX && controls.UI_RIGHT_P) moveShitDown(); - if (!flipX && controls.UI_LEFT_P) moveShitDown(); + if (flipX && controls.UI_RIGHT_P && !FlxG.keys.pressed.CONTROL) moveShitDown(); + if (!flipX && controls.UI_LEFT_P && !FlxG.keys.pressed.CONTROL) moveShitDown(); super.update(elapsed); } From e84fdf9fac2def3e6b880732b767585477ae5cc9 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 26 Mar 2024 19:38:42 -0400 Subject: [PATCH 2/7] Resolve FlxG.sound.music crash --- source/funkin/play/PlayState.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index a8cb879a3..62801028f 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2941,7 +2941,7 @@ class PlayState extends MusicBeatSubState if (overrideMusic) { // Stop the music. Do NOT destroy it, something still references it! - FlxG.sound.music.pause(); + if (FlxG.sound.music != null) FlxG.sound.music.pause(); if (vocals != null) { vocals.pause(); @@ -2951,7 +2951,7 @@ class PlayState extends MusicBeatSubState else { // Stop and destroy the music. - FlxG.sound.music.pause(); + if (FlxG.sound.music != null) FlxG.sound.music.pause(); if (vocals != null) { vocals.destroy(); From 9ebb253b53a931c019a54794b0805a4d3a830654 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 26 Mar 2024 19:38:56 -0400 Subject: [PATCH 3/7] Fix music updating issue. --- source/funkin/audio/FunkinSound.hx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index 687860265..9d6dee6ef 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -50,6 +50,11 @@ class FunkinSound extends FlxSound implements ICloneable */ static var pool(default, null):FlxTypedGroup = new FlxTypedGroup(); + /** + * Calculate the current time of the sound. + * NOTE: You need to `add()` the sound to the scene for `update()` to increment the time. + */ + // public var muted(default, set):Bool = false; function set_muted(value:Bool):Bool @@ -392,8 +397,6 @@ class FunkinSound extends FlxSound implements ICloneable // Call onLoad() because the sound already loaded if (onLoad != null && sound._sound != null) onLoad(); - FlxG.sound.list.remove(FlxG.sound.music); - return sound; } From 291a9f630d9a29406d75fe8a50b49a24ab07bd2d Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 26 Mar 2024 19:39:02 -0400 Subject: [PATCH 4/7] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 8bb6214e1..d2946604e 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 8bb6214e16c823b8b5a522a39b7a7e01d6283abf +Subproject commit d2946604e1dfb4fb80f6bf3cb73da8538963eade From 843095e3deb7619bab5d0a97200370072b579acc Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 27 Mar 2024 01:25:38 -0400 Subject: [PATCH 5/7] Add debug logging to Flixel debugger for miss judgements --- source/funkin/play/scoring/Scoring.hx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index edfb2cae7..744091b44 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -43,7 +43,7 @@ class Scoring case WEEK7: scoreNoteWEEK7(msTiming); case PBOT1: scoreNotePBOT1(msTiming); default: - trace('ERROR: Unknown scoring system: ' + scoringSystem); + FlxG.log.error('Unknown scoring system: ${scoringSystem}'); 0; } } @@ -62,7 +62,7 @@ class Scoring case WEEK7: judgeNoteWEEK7(msTiming); case PBOT1: judgeNotePBOT1(msTiming); default: - trace('ERROR: Unknown scoring system: ' + scoringSystem); + FlxG.log.error('Unknown scoring system: ${scoringSystem}'); 'miss'; } } @@ -145,7 +145,9 @@ class Scoring case(_ < PBOT1_PERFECT_THRESHOLD) => true: PBOT1_MAX_SCORE; default: + // Fancy equation. var factor:Float = 1.0 - (1.0 / (1.0 + Math.exp(-PBOT1_SCORING_SLOPE * (absTiming - PBOT1_SCORING_OFFSET)))); + var score:Int = Std.int(PBOT1_MAX_SCORE * factor + PBOT1_MIN_SCORE); score; @@ -169,6 +171,7 @@ class Scoring case(_ < PBOT1_SHIT_THRESHOLD) => true: 'shit'; default: + FlxG.log.warn('Missed note: Bad timing ($absTiming < $PBOT1_SHIT_THRESHOLD)'); 'miss'; } } @@ -257,6 +260,7 @@ class Scoring case(_ < LEGACY_HIT_WINDOW * LEGACY_SHIT_THRESHOLD) => true: 'shit'; default: + FlxG.log.warn('Missed note: Bad timing ($absTiming < $LEGACY_SHIT_THRESHOLD)'); 'miss'; } } @@ -336,6 +340,7 @@ class Scoring } else { + FlxG.log.warn('Missed note: Bad timing ($absTiming < $WEEK7_HIT_WINDOW)'); return 'miss'; } } From 31817959855104d50f54b814697e0862c1b1901a Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 27 Mar 2024 20:58:58 -0400 Subject: [PATCH 6/7] remove trace() calls from ages ago while im here --- source/funkin/ui/freeplay/DJBoyfriend.hx | 1 - source/funkin/ui/freeplay/SongMenuItem.hx | 2 -- 2 files changed, 3 deletions(-) diff --git a/source/funkin/ui/freeplay/DJBoyfriend.hx b/source/funkin/ui/freeplay/DJBoyfriend.hx index c77762d73..33f264301 100644 --- a/source/funkin/ui/freeplay/DJBoyfriend.hx +++ b/source/funkin/ui/freeplay/DJBoyfriend.hx @@ -49,7 +49,6 @@ class DJBoyfriend extends FlxAtlasSprite }; setupAnimations(); - trace(listAnimations()); FlxG.debugger.track(this); FlxG.console.registerObject("dj", this); diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index c20d81328..bffa821b3 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -182,8 +182,6 @@ class SongMenuItem extends FlxSpriteGroup { var charPath:String = "freeplay/icons/"; - trace(char); - // TODO: Put this in the character metadata where it belongs. // TODO: Also, can use CharacterDataParser.getCharPixelIconAsset() switch (char) From 17df6a515fa3c79e2bd25f7fbdd4f9d545564128 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 27 Mar 2024 22:11:31 -0400 Subject: [PATCH 7/7] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index d2946604e..485243fdd 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d2946604e1dfb4fb80f6bf3cb73da8538963eade +Subproject commit 485243fdd44acbc4db6a97ec7bf10a8b18350be9