mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-11-25 13:45:49 +00:00
Reimplement ghost tapping (disabled via compile define)
This commit is contained in:
parent
469ff6690f
commit
382af3b485
|
|
@ -2323,7 +2323,11 @@ class PlayState extends MusicBeatSubState
|
||||||
|
|
||||||
var notesInDirection:Array<NoteSprite> = notesByDirection[input.noteDirection];
|
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.
|
// Pressed a wrong key with no notes nearby.
|
||||||
// Perform a ghost miss (anti-spam).
|
// Perform a ghost miss (anti-spam).
|
||||||
|
|
@ -2333,16 +2337,6 @@ class PlayState extends MusicBeatSubState
|
||||||
playerStrumline.playPress(input.noteDirection);
|
playerStrumline.playPress(input.noteDirection);
|
||||||
trace('PENALTY Score: ${songScore}');
|
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)
|
else if (notesInDirection.length == 0)
|
||||||
{
|
{
|
||||||
// Press a key with no penalty.
|
// Press a key with no penalty.
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,10 @@ class Strumline extends FlxSpriteGroup
|
||||||
|
|
||||||
final noteStyle:NoteStyle;
|
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,
|
* The note data for the song. Should NOT be altered after the song starts,
|
||||||
* so we can easily rewind.
|
* so we can easily rewind.
|
||||||
|
|
@ -179,21 +183,36 @@ class Strumline extends FlxSpriteGroup
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
|
|
||||||
updateNotes();
|
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.
|
* Returns `true` if no notes are in range of the strumline and the player can spam without penalty.
|
||||||
*/
|
*/
|
||||||
public function mayGhostTap():Bool
|
public function mayGhostTap():Bool
|
||||||
{
|
{
|
||||||
// TODO: Refine this. Only querying "can be hit" is too tight but "is being rendered" is too loose.
|
// Any notes in range of the strumline.
|
||||||
// Also, if you just hit a note, there should be a (short) period where this is off so you can't spam.
|
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.
|
// Note has been hit recently.
|
||||||
return notes.members.filter(function(note:NoteSprite) {
|
if (ghostTapTimer > 0.0) return false;
|
||||||
return note != null && note.alive && !note.hasBeenHit;
|
|
||||||
}).length == 0;
|
// **yippee**
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return notes that are within `Constants.HIT_WINDOW` ms of the strumline.
|
* 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.
|
* Called when the PlayState skips a large amount of time forward or backward.
|
||||||
*/
|
*/
|
||||||
|
|
@ -563,6 +608,10 @@ class Strumline extends FlxSpriteGroup
|
||||||
playStatic(dir);
|
playStatic(dir);
|
||||||
}
|
}
|
||||||
resetScrollSpeed();
|
resetScrollSpeed();
|
||||||
|
|
||||||
|
#if FEATURE_GHOST_TAPPING
|
||||||
|
ghostTapTimer = 0;
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyNoteData(data:Array<SongNoteData>):Void
|
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;
|
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
|
public function killNote(note:NoteSprite):Void
|
||||||
|
|
|
||||||
|
|
@ -524,12 +524,16 @@ class Constants
|
||||||
* OTHER
|
* 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.
|
* Duration, in seconds, after the player's section ends before the player can spam without penalty.
|
||||||
* This is the thing people have been begging for forever lolol.
|
|
||||||
*/
|
*/
|
||||||
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.
|
* The maximum number of previous file paths for the Chart Editor to remember.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue