1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-11-15 11:22:55 +00:00

Reimplement ghost tapping (disabled via compile define)

This commit is contained in:
EliteMasterEric 2024-08-28 05:42:14 -04:00
parent 469ff6690f
commit 382af3b485
3 changed files with 71 additions and 20 deletions

View file

@ -2323,7 +2323,11 @@ class PlayState extends MusicBeatSubState
var notesInDirection:Array<NoteSprite> = notesByDirection[input.noteDirection];
if (!Constants.GHOST_TAPPING && notesInDirection.length == 0)
#if FEATURE_GHOST_TAPPING
if ((!playerStrumline.mayGhostTap()) && notesInDirection.length == 0)
#else
if (notesInDirection.length == 0)
#end
{
// Pressed a wrong key with no notes nearby.
// Perform a ghost miss (anti-spam).
@ -2333,16 +2337,6 @@ class PlayState extends MusicBeatSubState
playerStrumline.playPress(input.noteDirection);
trace('PENALTY Score: ${songScore}');
}
else if (Constants.GHOST_TAPPING && (!playerStrumline.mayGhostTap()) && notesInDirection.length == 0)
{
// Pressed a wrong key with notes visible on-screen.
// Perform a ghost miss (anti-spam).
ghostNoteMiss(input.noteDirection, notesInRange.length > 0);
// Play the strumline animation.
playerStrumline.playPress(input.noteDirection);
trace('PENALTY Score: ${songScore}');
}
else if (notesInDirection.length == 0)
{
// Press a key with no penalty.

View file

@ -94,6 +94,10 @@ class Strumline extends FlxSpriteGroup
final noteStyle:NoteStyle;
#if FEATURE_GHOST_TAPPING
var ghostTapTimer:Float = 0.0;
#end
/**
* The note data for the song. Should NOT be altered after the song starts,
* so we can easily rewind.
@ -179,21 +183,36 @@ class Strumline extends FlxSpriteGroup
super.update(elapsed);
updateNotes();
#if FEATURE_GHOST_TAPPING
updateGhostTapTimer(elapsed);
#end
}
#if FEATURE_GHOST_TAPPING
/**
* Returns `true` if no notes are in range of the strumline and the player can spam without penalty.
*/
public function mayGhostTap():Bool
{
// TODO: Refine this. Only querying "can be hit" is too tight but "is being rendered" is too loose.
// Also, if you just hit a note, there should be a (short) period where this is off so you can't spam.
// Any notes in range of the strumline.
if (getNotesMayHit().length > 0)
{
return false;
}
// Any hold notes in range of the strumline.
if (getHoldNotesHitOrMissed().length > 0)
{
return false;
}
// If there are any notes on screen, we can't ghost tap.
return notes.members.filter(function(note:NoteSprite) {
return note != null && note.alive && !note.hasBeenHit;
}).length == 0;
// Note has been hit recently.
if (ghostTapTimer > 0.0) return false;
// **yippee**
return true;
}
#end
/**
* Return notes that are within `Constants.HIT_WINDOW` ms of the strumline.
@ -492,6 +511,32 @@ class Strumline extends FlxSpriteGroup
}
}
/**
* Return notes that are within, or way after, `Constants.HIT_WINDOW` ms of the strumline.
* @return An array of `NoteSprite` objects.
*/
public function getNotesOnScreen():Array<NoteSprite>
{
return notes.members.filter(function(note:NoteSprite) {
return note != null && note.alive && !note.hasBeenHit;
});
}
#if FEATURE_GHOST_TAPPING
function updateGhostTapTimer(elapsed:Float):Void
{
// If it's still our turn, don't update the ghost tap timer.
if (getNotesOnScreen().length > 0) return;
ghostTapTimer -= elapsed;
if (ghostTapTimer <= 0)
{
ghostTapTimer = 0;
}
}
#end
/**
* Called when the PlayState skips a large amount of time forward or backward.
*/
@ -563,6 +608,10 @@ class Strumline extends FlxSpriteGroup
playStatic(dir);
}
resetScrollSpeed();
#if FEATURE_GHOST_TAPPING
ghostTapTimer = 0;
#end
}
public function applyNoteData(data:Array<SongNoteData>):Void
@ -602,6 +651,10 @@ class Strumline extends FlxSpriteGroup
note.holdNoteSprite.sustainLength = (note.holdNoteSprite.strumTime + note.holdNoteSprite.fullSustainLength) - conductorInUse.songPosition;
}
#if FEATURE_GHOST_TAPPING
ghostTapTimer = Constants.GHOST_TAP_DELAY;
#end
}
public function killNote(note:NoteSprite):Void

View file

@ -524,12 +524,16 @@ class Constants
* OTHER
*/
// ==============================
#if FEATURE_GHOST_TAPPING
// Hey there, Eric here.
// This feature is currently still in development. You can test it out by creating a special debug build!
// lime build windows -DFEATURE_GHOST_TAPPING
/**
* If true, the player will not receive the ghost miss penalty if there are no notes within the hit window.
* This is the thing people have been begging for forever lolol.
* Duration, in seconds, after the player's section ends before the player can spam without penalty.
*/
public static final GHOST_TAPPING:Bool = false;
public static final GHOST_TAP_DELAY:Float = 3 / 8;
#end
/**
* The maximum number of previous file paths for the Chart Editor to remember.