1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-12-27 07:27:12 +00:00

Fix issues with playtest and backwards time travel

This commit is contained in:
EliteMasterEric 2023-07-26 21:34:38 -04:00
parent 03444161e8
commit b974e6d6d7
3 changed files with 59 additions and 13 deletions

View file

@ -684,7 +684,7 @@ class PlayState extends MusicBeatSubState
vocals.playerVolume = 1; vocals.playerVolume = 1;
vocals.opponentVolume = 1; vocals.opponentVolume = 1;
currentStage.resetStage(); if (currentStage != null) currentStage.resetStage();
playerStrumline.clean(); playerStrumline.clean();
opponentStrumline.clean(); opponentStrumline.clean();
@ -871,6 +871,13 @@ class PlayState extends MusicBeatSubState
trace('Found ${songEventsToActivate.length} event(s) to activate.'); trace('Found ${songEventsToActivate.length} event(s) to activate.');
for (event in songEventsToActivate) for (event in songEventsToActivate)
{ {
// If an event is trying to play, but it's over 5 seconds old, skip it.
if (event.time - Conductor.songPosition < -5000)
{
event.activated = true;
continue;
};
var eventEvent:SongEventScriptEvent = new SongEventScriptEvent(event); var eventEvent:SongEventScriptEvent = new SongEventScriptEvent(event);
dispatchEvent(eventEvent); dispatchEvent(eventEvent);
// Calling event.cancelEvent() skips the event. Neat! // Calling event.cancelEvent() skips the event. Neat!
@ -1828,6 +1835,7 @@ class PlayState extends MusicBeatSubState
// Judge the miss. // Judge the miss.
// NOTE: This is what handles the scoring. // NOTE: This is what handles the scoring.
trace('Missed note! ${note.noteData}');
onNoteMiss(note); onNoteMiss(note);
note.handledMiss = true; note.handledMiss = true;
@ -1861,8 +1869,7 @@ class PlayState extends MusicBeatSubState
{ {
for (note in playerStrumline.notes.members) for (note in playerStrumline.notes.members)
{ {
var hitWindowStart = note.strumTime - Constants.HIT_WINDOW_MS; if (note == null || note.hasBeenHit) continue;
var hitWindowCenter = note.strumTime;
var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS; var hitWindowEnd = note.strumTime + Constants.HIT_WINDOW_MS;
if (Conductor.songPosition > hitWindowEnd) if (Conductor.songPosition > hitWindowEnd)
@ -1872,6 +1879,9 @@ class PlayState extends MusicBeatSubState
note.handledMiss = true; note.handledMiss = true;
} }
} }
playerStrumline.handleSkippedNotes();
opponentStrumline.handleSkippedNotes();
} }
/** /**
@ -1935,6 +1945,7 @@ class PlayState extends MusicBeatSubState
if (targetNote == null) continue; if (targetNote == null) continue;
// Judge and hit the note. // Judge and hit the note.
trace('Hit note! ${targetNote.noteData}');
goodNoteHit(targetNote, input); goodNoteHit(targetNote, input);
targetNote.visible = false; targetNote.visible = false;
@ -2262,12 +2273,12 @@ class PlayState extends MusicBeatSubState
if (FlxG.keys.justPressed.NINE) iconP1.toggleOldIcon(); if (FlxG.keys.justPressed.NINE) iconP1.toggleOldIcon();
#if debug #if debug
// PAGEUP: Skip forward one section. // PAGEUP: Skip forward two sections.
// SHIFT+PAGEUP: Skip forward ten sections. // SHIFT+PAGEUP: Skip forward twenty sections.
if (FlxG.keys.justPressed.PAGEUP) changeSection(FlxG.keys.pressed.SHIFT ? 10 : 1); if (FlxG.keys.justPressed.PAGEUP) changeSection(FlxG.keys.pressed.SHIFT ? 20 : 2);
// PAGEDOWN: Skip backward one section. Doesn't replace notes. // PAGEDOWN: Skip backward two section. Doesn't replace notes.
// SHIFT+PAGEDOWN: Skip backward ten sections. // SHIFT+PAGEDOWN: Skip backward twenty sections.
if (FlxG.keys.justPressed.PAGEDOWN) changeSection(FlxG.keys.pressed.SHIFT ? -10 : -1); if (FlxG.keys.justPressed.PAGEDOWN) changeSection(FlxG.keys.pressed.SHIFT ? -20 : -2);
#end #end
if (FlxG.keys.justPressed.B) trace(inputSpitter.join('\n')); if (FlxG.keys.justPressed.B) trace(inputSpitter.join('\n'));
@ -2550,6 +2561,7 @@ class PlayState extends MusicBeatSubState
public override function close():Void public override function close():Void
{ {
criticalFailure = true; // Stop game updates.
performCleanup(); performCleanup();
super.close(); super.close();
} }
@ -2564,6 +2576,10 @@ class PlayState extends MusicBeatSubState
// TODO: Uncache the song. // TODO: Uncache the song.
} }
// Stop the music.
FlxG.sound.music.pause();
vocals.stop();
// Remove reference to stage and remove sprites from it to save memory. // Remove reference to stage and remove sprites from it to save memory.
if (currentStage != null) if (currentStage != null)
{ {

View file

@ -55,7 +55,12 @@ class Strumline extends FlxSpriteGroup
final noteStyle:NoteStyle; final noteStyle:NoteStyle;
/**
* The note data for the song. Should NOT be altered after the song starts,
* so we can easily rewind.
*/
var noteData:Array<SongNoteData> = []; var noteData:Array<SongNoteData> = [];
var nextNoteIndex:Int = -1; var nextNoteIndex:Int = -1;
var heldKeys:Array<Bool> = []; var heldKeys:Array<Bool> = [];
@ -221,15 +226,21 @@ class Strumline extends FlxSpriteGroup
if (noteData.length == 0) return; if (noteData.length == 0) return;
var songStart:Float = PlayState.instance.startTimestamp ?? 0.0; var songStart:Float = PlayState.instance.startTimestamp ?? 0.0;
var hitWindowStart:Float = Conductor.songPosition - Constants.HIT_WINDOW_MS;
var renderWindowStart:Float = Conductor.songPosition + RENDER_DISTANCE_MS; var renderWindowStart:Float = Conductor.songPosition + RENDER_DISTANCE_MS;
for (noteIndex in nextNoteIndex...noteData.length) for (noteIndex in nextNoteIndex...noteData.length)
{ {
var note:Null<SongNoteData> = noteData[noteIndex]; var note:Null<SongNoteData> = noteData[noteIndex];
if (note == null) continue; if (note == null) continue; // Note is blank
if (note.time < songStart) continue; if (note.time < songStart || note.time < hitWindowStart)
if (note.time > renderWindowStart) break; {
// Note is in the past, skip it.
nextNoteIndex = noteIndex + 1;
continue;
}
if (note.time > renderWindowStart) break; // Note is too far ahead to render
var noteSprite = buildNoteSprite(note); var noteSprite = buildNoteSprite(note);
@ -238,7 +249,7 @@ class Strumline extends FlxSpriteGroup
noteSprite.holdNoteSprite = buildHoldNoteSprite(note); noteSprite.holdNoteSprite = buildHoldNoteSprite(note);
} }
nextNoteIndex++; // Increment the nextNoteIndex rather than splicing the array, because splicing is slow. nextNoteIndex = noteIndex + 1; // Increment the nextNoteIndex rather than splicing the array, because splicing is slow.
} }
// Update rendering of notes. // Update rendering of notes.
@ -376,6 +387,17 @@ class Strumline extends FlxSpriteGroup
} }
} }
/**
* Called when the PlayState skips a large amount of time forward or backward.
*/
public function handleSkippedNotes():Void
{
// By calling clean(), we remove all existing notes so they can be re-added.
clean();
// By setting noteIndex to 0, the next update will skip past all the notes that are in the past.
nextNoteIndex = 0;
}
public function onBeatHit():Void public function onBeatHit():Void
{ {
if (notes.members.length > 1) notes.members.insertionSort(compareNoteSprites.bind(FlxSort.ASCENDING)); if (notes.members.length > 1) notes.members.insertionSort(compareNoteSprites.bind(FlxSort.ASCENDING));

View file

@ -3063,6 +3063,7 @@ class ChartEditorState extends HaxeUIState
var targetSong:Song = Song.buildRaw(currentSongId, songMetadata.values(), availableVariations, songChartData, false); var targetSong:Song = Song.buildRaw(currentSongId, songMetadata.values(), availableVariations, songChartData, false);
subStateClosed.add(fixCamera); subStateClosed.add(fixCamera);
subStateClosed.add(updateConductor);
openSubState(new PlayState( openSubState(new PlayState(
{ {
@ -3080,10 +3081,17 @@ class ChartEditorState extends HaxeUIState
{ {
FlxG.cameras.reset(new FlxCamera()); FlxG.cameras.reset(new FlxCamera());
FlxG.camera.focusOn(new FlxPoint(FlxG.width / 2, FlxG.height / 2)); FlxG.camera.focusOn(new FlxPoint(FlxG.width / 2, FlxG.height / 2));
FlxG.camera.zoom = 1.0;
add(this.component); add(this.component);
} }
function updateConductor(_:FlxSubState = null):Void
{
var targetPos = scrollPositionInMs;
Conductor.update(targetPos);
}
/** /**
* Loads an instrumental from an absolute file path, replacing the current instrumental. * Loads an instrumental from an absolute file path, replacing the current instrumental.
* *