Input Improvements & Fixes (#837)

* Input

* Health

* optimize

* Update StrumLine.hx

* Update StrumLine.hx

* Delete directly?

* Update StrumLine.hx

* optimize

* Update StrumLine.hx

* Options.sustainsAsOneNote

* languages

* Update Options.xml

* Update PlayState.hx

* Flags

* Automatically set SUSTAINS_AS_ONE_NOTE

---------

Co-authored-by: Ralty <78720179+Raltyro@users.noreply.github.com>
This commit is contained in:
HEIHUAa
2025-12-15 22:18:47 +07:00
committed by GitHub
co-authored by Ralty
parent 8bab844e0c
commit 4a99e7eda7
3 changed files with 39 additions and 25 deletions
+6 -3
View File
@@ -136,6 +136,8 @@ class Flags {
public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4;
#end
public static var SUSTAINS_AS_ONE_NOTE:Null<Bool> = null;
@:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER)
public static var DEFAULT_GAMEOVER_CHARACTER:String = "bf-dead";
@@ -305,8 +307,9 @@ class Flags {
private static function loadPost() {
if (MOD_API_VERSION == null) MOD_API_VERSION = CURRENT_API_VERSION;
if (WINDOW_TITLE_USE_MOD_NAME == null) WINDOW_TITLE_USE_MOD_NAME = !overridenFlags.exists('TITLE') && overridenFlags.exists('MOD_NAME');
if (USE_LEGACY_TIMING == null) USE_LEGACY_TIMING = MOD_API_VERSION <= 1;
if (USE_LEGACY_ZOOM_FACTOR == null) USE_LEGACY_ZOOM_FACTOR = MOD_API_VERSION <= 1;
if (USE_LEGACY_TIMING == null) USE_LEGACY_TIMING = MOD_API_VERSION < 2;
if (USE_LEGACY_ZOOM_FACTOR == null) USE_LEGACY_ZOOM_FACTOR = MOD_API_VERSION < 2;
if (SUSTAINS_AS_ONE_NOTE == null) SUSTAINS_AS_ONE_NOTE = MOD_API_VERSION >= 2;
}
public static function loadFromDatas(datas:Array<String>):Map<String, String> {
@@ -381,4 +384,4 @@ class Flags {
}
loadPost();
}
}
}
+8 -1
View File
@@ -1837,7 +1837,14 @@ class PlayState extends MusicBeatState
var directionID:Null<Int> = note == null ? direction : note.strumID;
if (playerID == null || directionID == null || playerID == -1) return;
var event:NoteMissEvent = gameAndCharsEvent("onPlayerMiss", EventManager.get(NoteMissEvent).recycle(note, -10, 1, muteVocalsOnMiss, note != null ? -0.0475 : -0.04, Paths.sound(FlxG.random.getObject(Flags.DEFAULT_MISS_SOUNDS)), FlxG.random.float(0.1, 0.2), note == null, combo > 5, "sad", true, true, "miss", strumLines.members[playerID].characters, playerID, note != null ? note.noteType : null, directionID, 0));
if (Flags.SUSTAINS_AS_ONE_NOTE) {
if (note != null ? (note.isSustainNote && note.prevNote != null && note.prevNote.isSustainNote && !note.prevNote.wasGoodHit) : false) {
strumLine.deleteNote(note);
return;
}
}
var event:NoteMissEvent = gameAndCharsEvent("onPlayerMiss", EventManager.get(NoteMissEvent).recycle(note, -10, 1, muteVocalsOnMiss, note != null ? ((note.isSustainNote && Flags.SUSTAINS_AS_ONE_NOTE) ? -0.1425 : -0.0475) : -0.04, Paths.sound(FlxG.random.getObject(Flags.DEFAULT_MISS_SOUNDS)), FlxG.random.float(0.1, 0.2), note == null, combo > 5, "sad", true, true, "miss", strumLines.members[playerID].characters, playerID, note != null ? note.noteType : null, directionID, 0));
strumLine.onMiss.dispatch(event);
if (event.cancelled) {
gameAndCharsEvent("onPostPlayerMiss", event);
+25 -21
View File
@@ -258,14 +258,19 @@ class StrumLine extends FlxTypedGroup<Strum> {
}
}
var __funcsToExec:Array<Note->Void> = [];
var __pressed:Array<Bool> = [];
var __justPressed:Array<Bool> = [];
var __justReleased:Array<Bool> = [];
var __notePerStrum:Array<Note> = [];
function __inputProcessPressed(note:Note) {
if (__pressed[note.strumID] && note.isSustainNote && note.sustainParent != null && note.sustainParent.wasGoodHit && note.strumTime < __updateNote_songPos && !note.wasGoodHit) {
if (__pressed[note.strumID] && note.isSustainNote && note.strumTime < __updateNote_songPos && !note.wasGoodHit) {
note.tripTimer = 1;
PlayState.instance.goodNoteHit(this, note);
}
}
function __inputProcessPressedOne(note:Note) {
if (__pressed[note.strumID] && note.isSustainNote && note.sustainParent != null && note.prevNote != null && note.prevNote.wasGoodHit && note.strumTime < __updateNote_songPos && !note.wasGoodHit) {
note.tripTimer = 1;
PlayState.instance.goodNoteHit(this, note);
}
@@ -297,12 +302,11 @@ class StrumLine extends FlxTypedGroup<Strum> {
if (cpu) return;
__funcsToExec.clear();
__pressed.resize(members.length);
__justPressed.resize(members.length);
__justReleased.resize(members.length);
for(i in 0...members.length) {
for (i in 0...members.length) {
__pressed[i] = members[i].__getPressed(this);
__justPressed[i] = members[i].__getJustPressed(this);
__justReleased[i] = members[i].__getJustReleased(this);
@@ -316,34 +320,34 @@ class StrumLine extends FlxTypedGroup<Strum> {
__justPressed = CoolUtil.getDefault(event.justPressed, []);
__justReleased = CoolUtil.getDefault(event.justReleased, []);
__notePerStrum = cast new haxe.ds.Vector(members.length);//[for(_ in 0...members.length) null];
__notePerStrum = cast new haxe.ds.Vector(members.length); // [for(_ in 0...members.length) null];
if (__justPressed.contains(true)) {
notes.forEachAlive(__inputProcessJustPressed);
if (!ghostTapping) for (k => pr in __justPressed) if (pr && __notePerStrum[k] == null)
PlayState.instance.noteMiss(this, null, k, ID); // FUCK YOU
}
if (__pressed.contains(true)) {
for(c in characters)
for (e in __notePerStrum)
if (e != null)
PlayState.instance.goodNoteHit(this, e);
for (c in characters)
if (c.lastAnimContext != DANCE)
c.__lockAnimThisFrame = true;
__funcsToExec.push(__inputProcessPressed);
if (Flags.SUSTAINS_AS_ONE_NOTE)
notes.forEachAlive(__inputProcessPressedOne);
else
notes.forEachAlive(__inputProcessPressed);
}
if (__justPressed.contains(true))
__funcsToExec.push(__inputProcessJustPressed);
if (__funcsToExec.length > 0) {
notes.forEachAlive(function(note:Note) {
for(e in __funcsToExec) if (e != null) e(note);
});
}
if (!ghostTapping) for(k=>pr in __justPressed) if (pr && __notePerStrum[k] == null) {
// FUCK YOU
PlayState.instance.noteMiss(this, null, k, ID);
}
for(e in __notePerStrum) if (e != null) PlayState.instance.goodNoteHit(this, e);
forEach(function(str:Strum) {
str.updatePlayerInput(str.__getPressed(this), str.__getJustPressed(this), str.__getJustReleased(this));
});
PlayState.instance.gameAndCharsCall("onPostInputUpdate");
}