diff --git a/source/funkin/TitleState.hx b/source/funkin/TitleState.hx index 8e7dd19c8..3ae12dd43 100644 --- a/source/funkin/TitleState.hx +++ b/source/funkin/TitleState.hx @@ -19,7 +19,6 @@ import openfl.display.Sprite; import openfl.events.AsyncErrorEvent; import openfl.events.MouseEvent; import openfl.events.NetStatusEvent; -import openfl.filters.ShaderFilter; import openfl.media.Video; import openfl.net.NetStream; @@ -580,7 +579,8 @@ class TitleState extends MusicBeatState if (cheatActive && curBeat % 2 == 0) swagShader.update(0.125); - logoBl.animation.play('bump', true); + if (logoBl != null) + logoBl.animation.play('bump', true); danceLeft = !danceLeft; diff --git a/source/funkin/modding/IHook.hx b/source/funkin/modding/IHook.hx deleted file mode 100644 index e5e94a3fc..000000000 --- a/source/funkin/modding/IHook.hx +++ /dev/null @@ -1,16 +0,0 @@ -package funkin.modding; - -import polymod.hscript.HScriptable; - -/** - * Functions annotated with @:hscript will call the relevant script. - * Functions annotated with @:hookable can be reassigned. - * NOTE: If you receive the following error when making a function use @:hookable: - * `Cannot access this or other member field in variable initialization` - * This is because you need to perform calls and assignments using a static variable referencing the target object. - */ -@:hscript({ - // ALL of these values are added to ALL scripts in the child classes. - context: [FlxG, FlxSprite, Math, Paths, Std] -}) -interface IHook extends HScriptable {} diff --git a/source/funkin/modding/PolymodHandler.hx b/source/funkin/modding/PolymodHandler.hx index 32cff8884..c1d95a23c 100644 --- a/source/funkin/modding/PolymodHandler.hx +++ b/source/funkin/modding/PolymodHandler.hx @@ -220,14 +220,14 @@ class PolymodHandler { // Forcibly clear scripts so that scripts can be edited. ModuleHandler.clearModuleCache(); - polymod.hscript.PolymodScriptClass.clearScriptClasses(); + Polymod.clearScripts(); // Forcibly reload Polymod so it finds any new files. // TODO: Replace this with loadEnabledMods(). funkin.modding.PolymodHandler.loadAllMods(); // Reload scripted classes so stages and modules will update. - polymod.hscript.PolymodScriptClass.registerAllScriptClasses(); + Polymod.registerAllScriptClasses(); // Reload everything that is cached. // Currently this freezes the game for a second but I guess that's tolerable? diff --git a/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx b/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx index 5b3bebd16..50af136ff 100644 --- a/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx +++ b/source/funkin/modding/base/ScriptedFlxRuntimeShader.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import flixel.addons.display.FlxRuntimeShader; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedFlxRuntimeShader extends FlxRuntimeShader implements IHook {} +class ScriptedFlxRuntimeShader extends FlxRuntimeShader implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxSprite.hx b/source/funkin/modding/base/ScriptedFlxSprite.hx index d13d968a8..e4ae69107 100644 --- a/source/funkin/modding/base/ScriptedFlxSprite.hx +++ b/source/funkin/modding/base/ScriptedFlxSprite.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import flixel.FlxSprite; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedFlxSprite extends FlxSprite implements IHook {} +class ScriptedFlxSprite extends FlxSprite implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx b/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx index 5db61b81e..7d35aab47 100644 --- a/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx +++ b/source/funkin/modding/base/ScriptedFlxSpriteGroup.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import flixel.group.FlxSpriteGroup; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedFlxSpriteGroup extends FlxSpriteGroup implements IHook {} +class ScriptedFlxSpriteGroup extends FlxSpriteGroup implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxState.hx b/source/funkin/modding/base/ScriptedFlxState.hx index 73aaf4247..2a498e66b 100644 --- a/source/funkin/modding/base/ScriptedFlxState.hx +++ b/source/funkin/modding/base/ScriptedFlxState.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import flixel.FlxState; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedFlxState extends FlxState implements IHook {} +class ScriptedFlxState extends FlxState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxSubState.hx b/source/funkin/modding/base/ScriptedFlxSubState.hx index 46c54adeb..90c2a6474 100644 --- a/source/funkin/modding/base/ScriptedFlxSubState.hx +++ b/source/funkin/modding/base/ScriptedFlxSubState.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import flixel.FlxSubState; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedFlxSubState extends FlxSubState implements IHook {} +class ScriptedFlxSubState extends FlxSubState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxTransitionableState.hx b/source/funkin/modding/base/ScriptedFlxTransitionableState.hx index b66124de3..1d2b92b27 100644 --- a/source/funkin/modding/base/ScriptedFlxTransitionableState.hx +++ b/source/funkin/modding/base/ScriptedFlxTransitionableState.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import flixel.addons.transition.FlxTransitionableState; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedFlxTransitionableState extends FlxTransitionableState implements IHook {} +class ScriptedFlxTransitionableState extends FlxTransitionableState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedFlxUIState.hx b/source/funkin/modding/base/ScriptedFlxUIState.hx index 55358f43f..1799be32a 100644 --- a/source/funkin/modding/base/ScriptedFlxUIState.hx +++ b/source/funkin/modding/base/ScriptedFlxUIState.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import flixel.addons.ui.FlxUIState; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedFlxUIState extends FlxUIState implements IHook {} +class ScriptedFlxUIState extends FlxUIState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedMusicBeatState.hx b/source/funkin/modding/base/ScriptedMusicBeatState.hx index 31850c24c..430022029 100644 --- a/source/funkin/modding/base/ScriptedMusicBeatState.hx +++ b/source/funkin/modding/base/ScriptedMusicBeatState.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import funkin.MusicBeatState; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedMusicBeatState extends MusicBeatState implements IHook {} +class ScriptedMusicBeatState extends MusicBeatState implements HScriptedClass {} diff --git a/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx b/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx index d18448b64..dd399a74c 100644 --- a/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx +++ b/source/funkin/modding/base/ScriptedMusicBeatSubstate.hx @@ -1,7 +1,7 @@ package funkin.modding.base; import funkin.MusicBeatSubstate; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedMusicBeatSubstate extends MusicBeatSubstate implements IHook {} +class ScriptedMusicBeatSubstate extends MusicBeatSubstate implements HScriptedClass {} diff --git a/source/funkin/modding/module/ScriptedModule.hx b/source/funkin/modding/module/ScriptedModule.hx index 7369707e3..acb2ce031 100644 --- a/source/funkin/modding/module/ScriptedModule.hx +++ b/source/funkin/modding/module/ScriptedModule.hx @@ -1,6 +1,6 @@ package funkin.modding.module; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedModule extends Module implements IHook {} +class ScriptedModule extends Module implements HScriptedClass {} diff --git a/source/funkin/play/GameOverSubstate.hx b/source/funkin/play/GameOverSubstate.hx index e6162999d..48a65df0a 100644 --- a/source/funkin/play/GameOverSubstate.hx +++ b/source/funkin/play/GameOverSubstate.hx @@ -1,7 +1,7 @@ package funkin.play; -import flixel.FlxSprite; import flixel.FlxObject; +import flixel.FlxSprite; import flixel.system.FlxSound; import flixel.util.FlxColor; import flixel.util.FlxTimer; @@ -183,13 +183,13 @@ class GameOverSubstate extends MusicBeatSubstate playingJeffQuote = true; playJeffQuote(); // Start music at lower volume - startDeathMusic(0.2); + startDeathMusic(0.2, false); } default: // Start music at normal volume once the initial death animation finishes. if (boyfriend.getCurrentAnimation().startsWith('firstDeath') && boyfriend.isAnimationFinished()) { - startDeathMusic(); + startDeathMusic(1.0, false); } } } @@ -206,7 +206,7 @@ class GameOverSubstate extends MusicBeatSubstate if (!isEnding) { isEnding = true; - startDeathMusic(); // isEnding changes this function's behavior. + startDeathMusic(1.0, true); // isEnding changes this function's behavior. boyfriend.playAnimation('deathConfirm' + animationSuffix, true); @@ -243,17 +243,16 @@ class GameOverSubstate extends MusicBeatSubstate * Starts the death music at the appropriate volume. * @param startingVolume */ - function startDeathMusic(?startingVolume:Float = 1):Void + function startDeathMusic(?startingVolume:Float = 1, ?force:Bool = false):Void { - if (!isEnding) + var musicPath = Paths.music('gameOver' + musicSuffix); + if (isEnding) { - gameOverMusic.loadEmbedded(Paths.music('gameOver' + musicSuffix)); - gameOverMusic.volume = startingVolume; - gameOverMusic.play(); + musicPath = Paths.music('gameOverEnd' + musicSuffix); } - else + if (!gameOverMusic.playing || force) { - gameOverMusic.loadEmbedded(Paths.music('gameOverEnd' + musicSuffix)); + gameOverMusic.loadEmbedded(musicPath); gameOverMusic.volume = startingVolume; gameOverMusic.play(); } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 6749c2a59..a965b04fb 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -20,7 +20,6 @@ import funkin.Note; import funkin.Section.SwagSection; import funkin.SongLoad.SwagSong; import funkin.charting.ChartingState; -import funkin.modding.IHook; import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEventDispatcher; import funkin.play.GameOverSubstate; @@ -38,6 +37,7 @@ import funkin.ui.stageBuildShit.StageOffsetSubstate; import funkin.util.Constants; import funkin.util.SortUtil; import lime.ui.Haptic; +import polymod.hscript.HScriptedClass; using StringTools; @@ -45,7 +45,7 @@ using StringTools; import Discord.DiscordClient; #end -class PlayState extends MusicBeatState implements IHook +class PlayState extends MusicBeatState { /** * STATIC VARIABLES diff --git a/source/funkin/play/character/BaseCharacter.hx b/source/funkin/play/character/BaseCharacter.hx index edd178629..8a2a4af5f 100644 --- a/source/funkin/play/character/BaseCharacter.hx +++ b/source/funkin/play/character/BaseCharacter.hx @@ -166,15 +166,19 @@ class BaseCharacter extends Bopper return _data.flipX; } - function findCountAnimations(prefix:String):Array { + function findCountAnimations(prefix:String):Array + { var animNames:Array = this.animation.getNameList(); var result:Array = []; - for (anim in animNames) { - if (anim.startsWith(prefix)) { + for (anim in animNames) + { + if (anim.startsWith(prefix)) + { var comboNum:Null = Std.parseInt(anim.substring(prefix.length)); - if (comboNum != null) { + if (comboNum != null) + { result.push(comboNum); } } @@ -189,15 +193,16 @@ class BaseCharacter extends Bopper * Reset the character so it can be used at the start of the level. * Call this when restarting the level. */ - public function resetCharacter(resetCamera:Bool = true):Void { + public function resetCharacter(resetCamera:Bool = true):Void + { // Reset the animation offsets. This will modify x and y to be the absolute position of the character. this.animOffsets = [0, 0]; - + // Now we can set the x and y to be their original values without having to account for animOffsets. this.resetPosition(); - + // Make sure we are playing the idle animation (to reapply animOffsets)... - this.dance(); + this.dance(true); // Force to avoid the old animation playing with the wrong offset at the start of the song. // ...then update the hitbox so that this.width and this.height are correct. this.updateHitbox(); @@ -205,7 +210,7 @@ class BaseCharacter extends Bopper if (resetCamera) this.resetCameraFocusPoint(); } - + /** * Set the sprite scale to the appropriate value. * @param scale @@ -252,7 +257,7 @@ class BaseCharacter extends Bopper // trace('${this.animation.getNameList()}'); // trace('Combo note counts: ' + this.comboNoteCounts); // trace('Drop note counts: ' + this.dropNoteCounts); - + super.onCreate(event); } @@ -314,6 +319,11 @@ class BaseCharacter extends Bopper // Handle character note hold time. if (getCurrentAnimation().startsWith("sing")) { + // TODO: Rework this code (and all character animations ugh) + // such that the hold time is handled by padding frames, + // and reverting to the idle animation is done when `isAnimationFinished()`. + // This lets you add frames to the end of the sing animation to ease back into the idle! + holdTimer += event.elapsed; var singTimeMs:Float = singTimeCrochet * (Conductor.crochet * 0.001); // x beats, to ms. // Without this check here, the player character would only play the `sing` animation @@ -454,8 +464,11 @@ class BaseCharacter extends Bopper { // If the note is from the same strumline, play the sing animation. this.playSingAnimation(event.note.data.dir, false); - } else if (characterType == GF) { - if (event.note.mustPress && this.comboNoteCounts.contains(event.comboCount)) { + } + else if (characterType == GF) + { + if (event.note.mustPress && this.comboNoteCounts.contains(event.comboCount)) + { trace('Playing GF combo animation: combo${event.comboCount}'); this.playAnimation('combo${event.comboCount}', true, true); } @@ -479,19 +492,24 @@ class BaseCharacter extends Bopper { // If the note is from the same strumline, play the sing animation. this.playSingAnimation(event.note.data.dir, true); - } else if (event.note.mustPress && characterType == GF) { + } + else if (event.note.mustPress && characterType == GF) + { var dropAnim = ''; // Choose the combo drop anim to play. // If there are several (for example, drop10 and drop50) the highest one will be used. // If the combo count is too low, no animation will be played. - for (count in dropNoteCounts) { - if (event.comboCount >= count) { + for (count in dropNoteCounts) + { + if (event.comboCount >= count) + { dropAnim = 'drop${count}'; } } - if (dropAnim != '') { + if (dropAnim != '') + { trace('Playing GF combo drop animation: ${dropAnim}'); this.playAnimation(dropAnim, true, true); } @@ -549,6 +567,7 @@ enum CharacterType * - If the player misses or hits a ghost note, plays the appropriate `singDIR-miss` animation until BF is done singing. */ BF; + /** * The DAD character has the following behaviors. * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. @@ -557,6 +576,7 @@ enum CharacterType * - When the CPU misses a note (NOTE: This only happens via script, not by default), plays the appropriate `singDIR-miss` animation until DAD is done singing. */ DAD; + /** * The GF character has the following behaviors. * - At idle, dances with `danceLeft` and `danceRight` if available, or `idle` if not. @@ -569,6 +589,7 @@ enum CharacterType * - No drop animation will play if one isn't applicable (i.e. if the combo count is too low). */ GF; + /** * The OTHER character will only perform the `danceLeft`/`danceRight` or `idle` animation by default, depending on what's available. * Additional behaviors can be performed via scripts. diff --git a/source/funkin/play/character/ScriptedCharacter.hx b/source/funkin/play/character/ScriptedCharacter.hx index 9a87af968..72c1d7477 100644 --- a/source/funkin/play/character/ScriptedCharacter.hx +++ b/source/funkin/play/character/ScriptedCharacter.hx @@ -1,9 +1,9 @@ package funkin.play.character; -import funkin.modding.IHook; import funkin.play.character.MultiSparrowCharacter; import funkin.play.character.PackerCharacter; import funkin.play.character.SparrowCharacter; +import polymod.hscript.HScriptedClass; /** * Note: Making a scripted class extending BaseCharacter is not recommended. @@ -11,13 +11,13 @@ import funkin.play.character.SparrowCharacter; * and can't use one of the built-in render modes. */ @:hscriptClass -class ScriptedBaseCharacter extends BaseCharacter implements IHook {} +class ScriptedBaseCharacter extends BaseCharacter implements HScriptedClass {} @:hscriptClass -class ScriptedSparrowCharacter extends SparrowCharacter implements IHook {} +class ScriptedSparrowCharacter extends SparrowCharacter implements HScriptedClass {} @:hscriptClass -class ScriptedMultiSparrowCharacter extends MultiSparrowCharacter implements IHook {} +class ScriptedMultiSparrowCharacter extends MultiSparrowCharacter implements HScriptedClass {} @:hscriptClass -class ScriptedPackerCharacter extends PackerCharacter implements IHook {} +class ScriptedPackerCharacter extends PackerCharacter implements HScriptedClass {} diff --git a/source/funkin/play/stage/ScriptedBopper.hx b/source/funkin/play/stage/ScriptedBopper.hx index 405ef57f6..ab69703fc 100644 --- a/source/funkin/play/stage/ScriptedBopper.hx +++ b/source/funkin/play/stage/ScriptedBopper.hx @@ -1,6 +1,6 @@ package funkin.play.stage; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedBopper extends Bopper implements IHook {} +class ScriptedBopper extends Bopper implements HScriptedClass {} diff --git a/source/funkin/play/stage/ScriptedStage.hx b/source/funkin/play/stage/ScriptedStage.hx index e6a92d8b8..5534e94a2 100644 --- a/source/funkin/play/stage/ScriptedStage.hx +++ b/source/funkin/play/stage/ScriptedStage.hx @@ -1,6 +1,6 @@ package funkin.play.stage; -import funkin.modding.IHook; +import polymod.hscript.HScriptedClass; @:hscriptClass -class ScriptedStage extends Stage implements IHook {} +class ScriptedStage extends Stage implements HScriptedClass {} diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index 3f3debc63..de7b167a0 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -4,7 +4,6 @@ import flixel.FlxSprite; import flixel.group.FlxSpriteGroup; import flixel.math.FlxPoint; import flixel.util.FlxSort; -import funkin.modding.IHook; import funkin.modding.IScriptedClass; import funkin.modding.events.ScriptEvent; import funkin.modding.events.ScriptEventDispatcher; @@ -19,7 +18,7 @@ import funkin.util.assets.FlxAnimationUtil; * * A Stage is comprised of one or more props, each of which is a FlxSprite. */ -class Stage extends FlxSpriteGroup implements IHook implements IPlayStateScriptedClass +class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass { public final stageId:String; public final stageName:String;