diff --git a/source/funkin/Conductor.hx b/source/funkin/Conductor.hx index 331dd46f7..f21afeaac 100644 --- a/source/funkin/Conductor.hx +++ b/source/funkin/Conductor.hx @@ -40,7 +40,11 @@ class Conductor return crochet / 4; } + /** + * The current position in the song in milliseconds. + */ public static var songPosition:Float; + public static var lastSongPos:Float; public static var offset:Float = 0; diff --git a/source/funkin/play/stage/Bopper.hx b/source/funkin/play/stage/Bopper.hx index 95b9cfea2..c98437071 100644 --- a/source/funkin/play/stage/Bopper.hx +++ b/source/funkin/play/stage/Bopper.hx @@ -1,6 +1,8 @@ package funkin.play.stage; import flixel.FlxSprite; +import flixel.math.FlxPoint; +import flixel.util.FlxTimer; import funkin.modding.IScriptedClass.IPlayStateScriptedClass; import funkin.modding.events.ScriptEvent; @@ -42,7 +44,7 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass */ public var shouldBop:Bool = true; - public var finishCallbackMap:MapVoid> = new MapVoid>(); + private var finishCallbackMap:MapVoid> = new MapVoid>(); function set_idleSuffix(value:String):String { @@ -54,10 +56,28 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass /** * The offset of the character relative to the position specified by the stage. */ - public var globalOffsets(default, null):Array = [0, 0]; + public var globalOffsets(default, set):Array = [0, 0]; + + function set_globalOffsets(value:Array) + { + if (globalOffsets == null) + globalOffsets = [0, 0]; + if (globalOffsets == value) + return value; + + var xDiff = globalOffsets[0] - value[0]; + var yDiff = globalOffsets[1] - value[1]; + + this.x += xDiff; + this.y += yDiff; + + return animOffsets = value; + } private var animOffsets(default, set):Array = [0, 0]; + public var originalPosition:FlxPoint = new FlxPoint(0, 0); + function set_animOffsets(value:Array) { if (animOffsets == null) @@ -91,6 +111,15 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass }; } + /** + * If this Bopper was defined by the stage, return the prop to its original position. + */ + public function resetPosition() + { + this.x = originalPosition.x + animOffsets[0]; + this.y = originalPosition.y + animOffsets[1]; + } + function update_shouldAlternate():Void { if (hasAnimation('danceLeft')) @@ -219,6 +248,31 @@ class Bopper extends FlxSprite implements IPlayStateScriptedClass applyAnimationOffsets(correctName); } + var forceAnimationTimer:FlxTimer = new FlxTimer(); + + /** + * @param name The animation to play. + * @param duration The duration in which other (non-forced) animations will be skipped, in seconds. + */ + public function forceAnimationForDuration(name:String, duration:Float):Void + { + if (this.animation == null) + return; + + var correctName = correctAnimationName(name); + if (correctName == null) + return; + + this.animation.play(correctName, false, false); + applyAnimationOffsets(correctName); + + canPlayOtherAnims = false; + forceAnimationTimer.start(duration, (timer) -> + { + canPlayOtherAnims = true; + }, 1); + } + function applyAnimationOffsets(name:String) { var offsets = animationOffsets.get(name); diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index 768938608..172b0dc9c 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -166,6 +166,8 @@ class Stage extends FlxSpriteGroup implements IHook implements IPlayStateScripte { cast(propSprite, Bopper).setAnimationOffsets(propAnim.name, propAnim.offsets[0], propAnim.offsets[1]); } + cast(propSprite, Bopper).originalPosition.x = dataProp.position[0]; + cast(propSprite, Bopper).originalPosition.y = dataProp.position[1]; } if (dataProp.startingAnimation != null)