Funkin/source/funkin/freeplayStuff/DJBoyfriend.hx
Eric 42d8d55067 Unit Test Suite (#119)
* Initial test suite

* Fix some build warnings

* Implemented working unit tests with coverage

* Reduced some warnings

* Fix a mac-specific issue

* Add 2 additional unit test classes.

* Multiple new unit tests

* Some fixins

* Remove auto-generated file

* WIP on hiding ignored tests

* Added list of debug hotkeys

* Remove old website

* Remove empty file

* Add more unit tests

* Fix bug where arrows would nudge BF

* Fix bug where ctrl/alt would flash capsules

* Fixed bug where bf-old easter egg broke

* Remove duplicate lines

* More test-related stuff

* Some code cleanup

* Add mocking and a test assets folder

* More TESTS!

* Update Hmm...

* Update artist on Monster

* More minor fixes to individual functions

* 1.38% unit test coverage!

* Even more tests? :O

* More unit test work

* Rework migration for BaseRegistry

* gameover fix

* Fix an issue with Lime

* Fix issues with version parsing on data files

* 100 total unit tests!

* Added even MORE unit tests!

* Additional test tweaks :3

* Fixed tests on windows by updating libraries.

* Set versions for flixel-ui and hamcrest

---------

Co-authored-by: Cameron Taylor <cameron.taylor.ninja@gmail.com>
2023-08-22 04:27:30 -04:00

159 lines
3.9 KiB
Haxe

package funkin.freeplayStuff;
import flixel.FlxSprite;
import flixel.util.FlxSignal;
import funkin.util.assets.FlxAnimationUtil;
class DJBoyfriend extends FlxSprite
{
// Represents the sprite's current status.
// Without state machines I would have driven myself crazy years ago.
public var currentState:DJBoyfriendState = Intro;
// A callback activated when the intro animation finishes.
public var onIntroDone:FlxSignal = new FlxSignal();
// A callback activated when Boyfriend gets spooked.
public var onSpook:FlxSignal = new FlxSignal();
// playAnim stolen from Character.hx, cuz im lazy lol!
// TODO: Switch this class to use SwagSprite instead.
public var animOffsets:Map<String, Array<Dynamic>>;
static final SPOOK_PERIOD:Float = 180.0;
// Time since dad last SPOOKED you.
var timeSinceSpook:Float = 0;
public function new(x:Float, y:Float)
{
super(x, y);
animOffsets = new Map<String, Array<Dynamic>>();
setupAnimations();
animation.finishCallback = onFinishAnim;
}
public override function update(elapsed:Float):Void
{
super.update(elapsed);
switch (currentState)
{
case Intro:
// Play the intro animation then leave this state immediately.
if (getCurrentAnimation() != 'intro') playAnimation('intro', true);
timeSinceSpook = 0;
case Idle:
// We are in this state the majority of the time.
if (getCurrentAnimation() != 'idle' || animation.finished)
{
if (timeSinceSpook > SPOOK_PERIOD)
{
currentState = Spook;
}
else
{
playAnimation('idle', false);
}
}
timeSinceSpook += elapsed;
case Confirm:
if (getCurrentAnimation() != 'confirm') playAnimation('confirm', false);
timeSinceSpook = 0;
case Spook:
if (getCurrentAnimation() != 'spook')
{
onSpook.dispatch();
playAnimation('spook', false);
}
timeSinceSpook = 0;
default:
// I shit myself.
}
}
function onFinishAnim(name:String):Void
{
switch (name)
{
case "intro":
// trace('Finished intro');
currentState = Idle;
onIntroDone.dispatch();
case "idle":
// trace('Finished idle');
case "spook":
// trace('Finished spook');
currentState = Idle;
case "confirm":
// trace('Finished confirm');
}
}
public function resetAFKTimer():Void
{
timeSinceSpook = 0;
}
function setupAnimations():Void
{
frames = FlxAnimationUtil.combineFramesCollections(Paths.getSparrowAtlas('freeplay/bfFreeplay'), Paths.getSparrowAtlas('freeplay/bf-freeplay-afk'));
animation.addByPrefix('intro', "boyfriend dj intro", 24, false);
addOffset('intro', 0, 0);
animation.addByPrefix('idle', "Boyfriend DJ0", 24, false);
addOffset('idle', -4, -426);
animation.addByPrefix('confirm', "Boyfriend DJ confirm", 24, false);
addOffset('confirm', 40, -451);
animation.addByPrefix('spook', "bf dj afk0", 24, false);
addOffset('spook', -3, -272);
}
public function confirm():Void
{
currentState = Confirm;
}
public inline function addOffset(name:String, x:Float = 0, y:Float = 0)
{
animOffsets[name] = [x, y];
}
public function getCurrentAnimation():String
{
if (this.animation == null || this.animation.curAnim == null) return "";
return this.animation.curAnim.name;
}
public function playAnimation(AnimName:String, Force:Bool = false, Reversed:Bool = false, Frame:Int = 0):Void
{
animation.play(AnimName, Force, Reversed, Frame);
applyAnimOffset();
}
function applyAnimOffset()
{
var AnimName = getCurrentAnimation();
var daOffset = animOffsets.get(AnimName);
if (animOffsets.exists(AnimName))
{
offset.set(daOffset[0], daOffset[1]);
}
else
offset.set(0, 0);
}
}
enum DJBoyfriendState
{
Intro;
Idle;
Confirm;
Spook;
}