diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 9ae13a76..449f82c6 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -7,7 +7,7 @@ jobs:
build:
name: Mac OS Build
permissions: write-all
- runs-on: macos-latest
+ runs-on: macos-13
steps:
- name: Pulling the new commit
uses: actions/checkout@v2
diff --git a/assets/data/characters/bf.xml b/assets/data/characters/bf.xml
index 04e2b3c5..245fbffd 100644
--- a/assets/data/characters/bf.xml
+++ b/assets/data/characters/bf.xml
@@ -11,4 +11,8 @@
-
\ No newline at end of file
+
+
+
+
+
diff --git a/assets/data/notes/Alt Anim Note.hx b/assets/data/notes/Alt Anim Note.hx
index 08acea42..b44b1398 100644
--- a/assets/data/notes/Alt Anim Note.hx
+++ b/assets/data/notes/Alt Anim Note.hx
@@ -1 +1,2 @@
-function onNoteHit(event) if (event.noteType == "Alt Anim Note") event.animSuffix = "-alt";
\ No newline at end of file
+function onNoteHit(event) if (event.noteType == "Alt Anim Note") event.animSuffix = "-alt";
+function onPlayerMiss(event) if (event.noteType == "Alt Anim Note") event.animSuffix = "-alt";
\ No newline at end of file
diff --git a/assets/data/notes/No Anim Note.hx b/assets/data/notes/No Anim Note.hx
index 31eb0c63..206d4f96 100644
--- a/assets/data/notes/No Anim Note.hx
+++ b/assets/data/notes/No Anim Note.hx
@@ -1 +1,2 @@
-function onNoteHit(event) if (event.noteType == "No Anim Note") event.animCancelled = true;
\ No newline at end of file
+function onNoteHit(event) if (event.noteType == "No Anim Note") event.animCancelled = true;
+function onPlayerMiss(event) if (event.noteType == "No Anim Note") event.animCancelled = true;
\ No newline at end of file
diff --git a/source/funkin/backend/chart/EventsData.hx b/source/funkin/backend/chart/EventsData.hx
index e801f18f..05f35bde 100644
--- a/source/funkin/backend/chart/EventsData.hx
+++ b/source/funkin/backend/chart/EventsData.hx
@@ -48,7 +48,7 @@ class EventsData {
}
],
"Alt Animation Toggle" => [{name: "Enable On Sing Poses", type: TBool, defValue: true}, {name: "Enable On Idle", type: TBool, defValue: true}, {name: "Strumline", type: TStrumLine, defValue: 0}],
- "Play Animation" => [{name: "Character", type: TStrumLine, defValue: 0}, {name: "Animation", type: TString, defValue: "animation"}],
+ "Play Animation" => [{name: "Character", type: TStrumLine, defValue: 0}, {name: "Animation", type: TString, defValue: "animation"}, {name: "Is forced?", type: TBool, defValue: true}],
];
public static var eventsList:Array = defaultEventsList.copy();
diff --git a/source/funkin/backend/system/Controls.hx b/source/funkin/backend/system/Controls.hx
index d1a11142..651b510f 100644
--- a/source/funkin/backend/system/Controls.hx
+++ b/source/funkin/backend/system/Controls.hx
@@ -428,13 +428,18 @@ class Controls extends FlxActionSet
return byName[name].check();
}
+ public function getKeyName(control:Control):String
+ {
+ return getDialogueName(getActionFromControl(control));
+ }
+
public function getDialogueName(action:FlxActionDigital):String
{
var input = action.inputs[0];
return switch input.device
{
- case KEYBOARD: return '[${(input.inputID : FlxKey)}]';
- case GAMEPAD: return '(${(input.inputID : FlxGamepadInputID)})';
+ case KEYBOARD: return '${(input.inputID : FlxKey)}';
+ case GAMEPAD: return '${(input.inputID : FlxGamepadInputID)}';
case device: throw 'unhandled device: $device';
}
}
diff --git a/source/funkin/backend/utils/FunkinParentDisabler.hx b/source/funkin/backend/utils/FunkinParentDisabler.hx
index 4a7efc3b..07e71a2a 100644
--- a/source/funkin/backend/utils/FunkinParentDisabler.hx
+++ b/source/funkin/backend/utils/FunkinParentDisabler.hx
@@ -41,7 +41,9 @@ class FunkinParentDisabler extends FlxBasic {
}
}
- public override function update(elapsed:Float) {}
+ public override function update(elapsed:Float) {
+ @:privateAccess for(c in __cameras) c.updateFlashSpritePosition();
+ }
public override function draw() {}
public function reset() {
diff --git a/source/funkin/game/Character.hx b/source/funkin/game/Character.hx
index 40ddcd74..689296d2 100644
--- a/source/funkin/game/Character.hx
+++ b/source/funkin/game/Character.hx
@@ -56,6 +56,8 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
public var shadowFrame:CharacterShadowFrame;
public var idleSuffix:String = "";
+ public var anims = ["singLEFT", "singDOWN", "singUP", "singRIGHT"]; // Not making these inline so theyre editable through scripts! - Nex
+
public inline function getCameraPosition()
{
var midpoint = getMidpoint();
@@ -68,12 +70,26 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
return new FlxPoint(event.x, event.y);
}
- var singAnims = ["singLEFT", "singDOWN", "singUP", "singRIGHT"];
+ public inline function getSingAnim(direction:Int, suffix:String = ""):String
+ {
+ return anims[direction % anims.length] + suffix;
+ }
+ /**
+ * Like `playSingAnimUnsafe` but checks if the character has the animation with the suffix part, otherwhise tries to play the animation without the suffix part.
+ */
public function playSingAnim(direction:Int, suffix:String = "", Context:PlayAnimContext = SING, Force:Bool = true, Reversed:Bool = false, Frame:Int = 0)
{
- var event = EventManager.get(DirectionAnimEvent).recycle(singAnims[direction % singAnims.length] + suffix, direction, suffix, Context, Reversed, Frame, Force);
+ var event = EventManager.get(DirectionAnimEvent).recycle(getSingAnim(direction, suffix), direction, suffix, Context, Reversed, Frame, Force);
script.call("onPlaySingAnim", [event]);
+ if (!event.cancelled)
+ playSingAnimUnsafe(event.direction, hasAnimation(event.animName) ? event.suffix : "", event.context, event.force, event.reversed, event.frame);
+ }
+
+ public function playSingAnimUnsafe(direction:Int, suffix:String = "", Context:PlayAnimContext = SING, Force:Bool = true, Reversed:Bool = false, Frame:Int = 0)
+ {
+ var event = EventManager.get(DirectionAnimEvent).recycle(getSingAnim(direction, suffix), direction, suffix, Context, Reversed, Frame, Force);
+ script.call("onPlaySingAnimUnsafe", [event]);
if (!event.cancelled)
playAnim(event.animName, event.force, event.context, event.reversed, event.frame);
}
@@ -161,7 +177,7 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
// [ true ][ false ][ true ]
// [ false ][ true ][ true ]
// [ true ][ true ][ false ]
- // bros provided evedince :skull:
+ // bros provided evidence :skull:
if (isPlayer != playerOffsets && switchAnims)
{
// character is flipped
diff --git a/source/funkin/game/GameOverSubstate.hx b/source/funkin/game/GameOverSubstate.hx
index af36ff29..4351a9dc 100644
--- a/source/funkin/game/GameOverSubstate.hx
+++ b/source/funkin/game/GameOverSubstate.hx
@@ -108,7 +108,7 @@ class GameOverSubstate extends MusicBeatSubstate
if (controls.BACK)
{
if (PlayState.chartingMode && Charter.undos.unsaved)
- PlayState.instance.saveWarn(false);
+ game.saveWarn(false);
else {
PlayState.resetSongInfos();
if (Charter.instance != null) Charter.instance.__clearStatics();
diff --git a/source/funkin/game/StrumLine.hx b/source/funkin/game/StrumLine.hx
index 037f9744..d743dd79 100644
--- a/source/funkin/game/StrumLine.hx
+++ b/source/funkin/game/StrumLine.hx
@@ -29,9 +29,9 @@ class StrumLine extends FlxTypedGroup {
*/
public var onNoteUpdate:FlxTypedSignalVoid> = new FlxTypedSignalVoid>();
/**
- * Signal that triggers whenever a note is being updated. Similar to onNoteUpdate, except strumline specific.
+ * Signal that triggers whenever a note is being deleted. Similar to onNoteDelete, except strumline specific.
* To add a listener, do
- * `strumLine.onNoteUpdate.add(function(e:NoteUpdateEvent) {});`
+ * `strumLine.onNoteDelete.add(function(e:SimpleNoteEvent) {});`
*/
public var onNoteDelete:FlxTypedSignalVoid> = new FlxTypedSignalVoid>();
/**
diff --git a/source/funkin/menus/MainMenuState.hx b/source/funkin/menus/MainMenuState.hx
index 171f7959..2f5ea12c 100644
--- a/source/funkin/menus/MainMenuState.hx
+++ b/source/funkin/menus/MainMenuState.hx
@@ -70,7 +70,7 @@ class MainMenuState extends MusicBeatState
FlxG.camera.follow(camFollow, null, 0.06);
- var versionShit:FunkinText = new FunkinText(5, FlxG.height - 2, 0, 'Codename Engine v${Application.current.meta.get('version')}\nCommit ${funkin.backend.system.macros.GitCommitMacro.commitNumber} (${funkin.backend.system.macros.GitCommitMacro.commitHash})\n[TAB] Open Mods menu\n');
+ var versionShit:FunkinText = new FunkinText(5, FlxG.height - 2, 0, 'Codename Engine v${Application.current.meta.get('version')}\nCommit ${funkin.backend.system.macros.GitCommitMacro.commitNumber} (${funkin.backend.system.macros.GitCommitMacro.commitHash})\n[${controls.getKeyName(SWITCHMOD)}] Open Mods menu\n');
versionShit.y -= versionShit.height;
versionShit.scrollFactor.set();
add(versionShit);
diff --git a/source/funkin/menus/PauseSubState.hx b/source/funkin/menus/PauseSubState.hx
index 53dc65bb..ff45f20a 100644
--- a/source/funkin/menus/PauseSubState.hx
+++ b/source/funkin/menus/PauseSubState.hx
@@ -106,7 +106,7 @@ class PauseSubState extends MusicBeatSubstate
pauseScript.call("postCreate");
- PlayState.instance.updateDiscordPresence();
+ game.updateDiscordPresence();
}
override function update(elapsed:Float)
@@ -146,7 +146,7 @@ class PauseSubState extends MusicBeatSubstate
close();
case "Restart Song":
parentDisabler.reset();
- PlayState.instance.registerSmoothTransition();
+ game.registerSmoothTransition();
FlxG.resetState();
case "Change Controls":
persistentDraw = false;
@@ -157,7 +157,7 @@ class PauseSubState extends MusicBeatSubstate
FlxG.switchState(new funkin.editors.charter.Charter(PlayState.SONG.meta.name, PlayState.difficulty, false));
case "Exit to menu":
if (PlayState.chartingMode && Charter.undos.unsaved)
- PlayState.instance.saveWarn(false);
+ game.saveWarn(false);
else {
PlayState.resetSongInfos();
if (Charter.instance != null) Charter.instance.__clearStatics();
diff --git a/source/openfl/utils/Assets.hx b/source/openfl/utils/Assets.hx
index e08852cd..db92e530 100644
--- a/source/openfl/utils/Assets.hx
+++ b/source/openfl/utils/Assets.hx
@@ -91,7 +91,7 @@ class Assets
@usage var bitmap = new Bitmap (Assets.getBitmapData ("image.png"));
@param id The ID or asset path for the bitmap
@param useCache (Optional) Whether to allow use of the asset cache (Default: true)
- @param useCache Whenever the image should be immediately pushed to GPU.
+ @param pushToGPU Whenever the image should be immediately pushed to GPU.
@return A new BitmapData object
**/
public static function getBitmapData(id:String, useCache:Bool = true, pushToGPU:Bool = true):BitmapData