mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-01-01 09:48:14 +00:00
Messing around with logic for hold note misses/health gain
This commit is contained in:
parent
47d8d9e4db
commit
a672db7b0e
|
@ -136,10 +136,8 @@ class PlayState extends MusicBeatState
|
|||
|
||||
/**
|
||||
* The player's current health.
|
||||
* The default maximum health is 2.0, and the default starting health is 1.0.
|
||||
* TODO: Refactor this to [0.0, 1.0]
|
||||
*/
|
||||
public var health:Float = 1;
|
||||
public var health:Float = Constants.HEALTH_STARTING;
|
||||
|
||||
/**
|
||||
* The player's current score.
|
||||
|
@ -255,7 +253,7 @@ class PlayState extends MusicBeatState
|
|||
* The displayed value of the player's health.
|
||||
* Used to provide smooth animations based on linear interpolation of the player's health.
|
||||
*/
|
||||
var healthLerp:Float = 1;
|
||||
var healthLerp:Float = Constants.HEALTH_STARTING;
|
||||
|
||||
/**
|
||||
* How long the user has held the "Skip Video Cutscene" button for.
|
||||
|
@ -643,7 +641,7 @@ class PlayState extends MusicBeatState
|
|||
hudCameraZoomIntensity = Constants.DEFAULT_ZOOM_INTENSITY * 2.0;
|
||||
cameraZoomRate = Constants.DEFAULT_ZOOM_RATE;
|
||||
|
||||
health = 1;
|
||||
health = Constants.HEALTH_STARTING;
|
||||
songScore = 0;
|
||||
Highscore.tallies.combo = 0;
|
||||
Countdown.performCountdown(currentStageId.startsWith('school'));
|
||||
|
@ -735,8 +733,8 @@ class PlayState extends MusicBeatState
|
|||
}
|
||||
|
||||
// Cap health.
|
||||
if (health > 2.0) health = 2.0;
|
||||
if (health < 0.0) health = 0.0;
|
||||
if (health > Constants.HEALTH_MAX) health = Constants.HEALTH_MAX;
|
||||
if (health < Constants.HEALTH_MIN) health = Constants.HEALTH_MIN;
|
||||
|
||||
// Lerp the camera zoom towards the target level.
|
||||
if (subState == null)
|
||||
|
@ -761,19 +759,19 @@ class PlayState extends MusicBeatState
|
|||
// RESET = Quick Game Over Screen
|
||||
if (controls.RESET)
|
||||
{
|
||||
health = 0;
|
||||
health = Constants.HEALTH_MIN;
|
||||
trace('RESET = True');
|
||||
}
|
||||
|
||||
#if CAN_CHEAT // brandon's a pussy
|
||||
if (controls.CHEAT)
|
||||
{
|
||||
health += 1;
|
||||
health += 0.25 * Constants.HEALTH_MAX; // +25% health.
|
||||
trace('User is cheating!');
|
||||
}
|
||||
#end
|
||||
|
||||
if (health <= 0 && !isPracticeMode)
|
||||
if (health <= Constants.HEALTH_MIN && !isPracticeMode)
|
||||
{
|
||||
vocals.pause();
|
||||
FlxG.sound.music.pause();
|
||||
|
@ -934,7 +932,7 @@ class PlayState extends MusicBeatState
|
|||
*/
|
||||
public override function onFocus():Void
|
||||
{
|
||||
if (health > 0 && !paused && FlxG.autoPause)
|
||||
if (health > Constants.HEALTH_MIN && !paused && FlxG.autoPause)
|
||||
{
|
||||
if (Conductor.songPosition > 0.0) DiscordClient.changePresence(detailsText, currentSong.song
|
||||
+ ' ('
|
||||
|
@ -954,7 +952,8 @@ class PlayState extends MusicBeatState
|
|||
*/
|
||||
public override function onFocusLost():Void
|
||||
{
|
||||
if (health > 0 && !paused && FlxG.autoPause) DiscordClient.changePresence(detailsPausedText, currentSong.song + ' (' + storyDifficultyText + ')', iconRPC);
|
||||
if (health > Constants.HEALTH_MIN && !paused && FlxG.autoPause) DiscordClient.changePresence(detailsPausedText,
|
||||
currentSong.song + ' (' + storyDifficultyText + ')', iconRPC);
|
||||
|
||||
super.onFocusLost();
|
||||
}
|
||||
|
@ -1645,7 +1644,8 @@ class PlayState extends MusicBeatState
|
|||
{
|
||||
note.tooEarly = false;
|
||||
note.mayHit = false;
|
||||
note.tooLate = true;
|
||||
note.hasMissed = true;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true;
|
||||
}
|
||||
else if (Conductor.songPosition > hitWindowCenter)
|
||||
{
|
||||
|
@ -1660,20 +1660,20 @@ class PlayState extends MusicBeatState
|
|||
// Command the opponent to hit the note on time.
|
||||
// NOTE: This is what handles the strumline and cleaning up the note itself!
|
||||
opponentStrumline.hitNote(note);
|
||||
|
||||
// scoreNote();
|
||||
}
|
||||
else if (Conductor.songPosition > hitWindowStart)
|
||||
{
|
||||
note.tooEarly = false;
|
||||
note.mayHit = true;
|
||||
note.tooLate = false;
|
||||
note.hasMissed = false;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
note.tooEarly = true;
|
||||
note.mayHit = false;
|
||||
note.tooLate = false;
|
||||
note.hasMissed = false;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1682,8 +1682,35 @@ class PlayState extends MusicBeatState
|
|||
{
|
||||
if (note == null || note.hasBeenHit) continue;
|
||||
|
||||
// If this is true, the note is already properly off the screen.
|
||||
if (note.hasMissed)
|
||||
var hitWindowStart = note.strumTime - Conductor.HIT_WINDOW_MS;
|
||||
var hitWindowCenter = note.strumTime;
|
||||
var hitWindowEnd = note.strumTime + Conductor.HIT_WINDOW_MS;
|
||||
|
||||
if (Conductor.songPosition > hitWindowEnd)
|
||||
{
|
||||
note.tooEarly = false;
|
||||
note.mayHit = false;
|
||||
note.hasMissed = true;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true;
|
||||
}
|
||||
else if (Conductor.songPosition > hitWindowStart)
|
||||
{
|
||||
note.tooEarly = false;
|
||||
note.mayHit = true;
|
||||
note.hasMissed = false;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
note.tooEarly = true;
|
||||
note.mayHit = false;
|
||||
note.hasMissed = false;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false;
|
||||
}
|
||||
|
||||
// This becomes true when the note leaves the hit window.
|
||||
// It might still be on screen.
|
||||
if (note.hasMissed && !note.handledMiss)
|
||||
{
|
||||
// Call an event to allow canceling the note miss.
|
||||
// NOTE: This is what handles the character animations!
|
||||
|
@ -1696,6 +1723,8 @@ class PlayState extends MusicBeatState
|
|||
// Judge the miss.
|
||||
// NOTE: This is what handles the scoring.
|
||||
onNoteMiss(note);
|
||||
|
||||
note.handledMiss = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1725,11 +1754,9 @@ class PlayState extends MusicBeatState
|
|||
}
|
||||
|
||||
// Generate a list of notes within range.
|
||||
var notesInRange:Array<NoteSprite> = playerStrumline.getNotesInRange(Conductor.songPosition, Conductor.HIT_WINDOW_MS);
|
||||
var notesInRange:Array<NoteSprite> = playerStrumline.getNotesMayHit();
|
||||
|
||||
// If there are notes in range, pressing a key will cause a ghost miss.
|
||||
// var canMiss:Bool = notesInRange.length > 0;
|
||||
var canMiss:Bool = true; // Forced to true for consistency with other input systems.
|
||||
|
||||
var notesByDirection:Array<Array<NoteSprite>> = [[], [], [], []];
|
||||
|
||||
|
@ -1744,10 +1771,19 @@ class PlayState extends MusicBeatState
|
|||
|
||||
var notesInDirection:Array<NoteSprite> = notesByDirection[input.noteDirection];
|
||||
|
||||
if (canMiss && notesInDirection.length == 0)
|
||||
if (!Constants.GHOST_TAPPING && notesInDirection.length == 0)
|
||||
{
|
||||
// Pressed a wrong key with notes in range.
|
||||
// Perform a ghost miss.
|
||||
// Pressed a wrong key with no notes nearby.
|
||||
// Perform a ghost miss (anti-spam).
|
||||
ghostNoteMiss(input.noteDirection, notesInRange.length > 0);
|
||||
|
||||
// Play the strumline animation.
|
||||
playerStrumline.playPress(input.noteDirection);
|
||||
}
|
||||
else if (Constants.GHOST_TAPPING && notesInRange.length > 0 && notesInDirection.length == 0)
|
||||
{
|
||||
// Pressed a wrong key with no notes nearby AND with notes in a different direction available.
|
||||
// Perform a ghost miss (anti-spam).
|
||||
ghostNoteMiss(input.noteDirection, notesInRange.length > 0);
|
||||
|
||||
// Play the strumline animation.
|
||||
|
@ -1837,37 +1873,6 @@ class PlayState extends MusicBeatState
|
|||
var directionList:Array<Int> = []; // directions that can be hit
|
||||
var dumbNotes:Array<NoteSprite> = []; // notes to kill later
|
||||
|
||||
/*
|
||||
activeNotes.forEachAlive(function(daNote:Note) {
|
||||
if (daNote.canBeHit && daNote.mustPress && !daNote.tooLate && !daNote.hasBeenHit)
|
||||
{
|
||||
if (directionList.contains(daNote.data.noteData))
|
||||
{
|
||||
for (coolNote in possibleNotes)
|
||||
{
|
||||
if (coolNote.data.noteData == daNote.data.noteData && Math.abs(daNote.data.strumTime - coolNote.data.strumTime) < 10)
|
||||
{ // if it's the same note twice at < 10ms distance, just delete it
|
||||
// EXCEPT u cant delete it in this loop cuz it fucks with the collection lol
|
||||
dumbNotes.push(daNote);
|
||||
break;
|
||||
}
|
||||
else if (coolNote.data.noteData == daNote.data.noteData && daNote.data.strumTime < coolNote.data.strumTime)
|
||||
{ // if daNote is earlier than existing note (coolNote), replace
|
||||
possibleNotes.remove(coolNote);
|
||||
possibleNotes.push(daNote);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
possibleNotes.push(daNote);
|
||||
directionList.push(daNote.data.noteData);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
for (note in dumbNotes)
|
||||
{
|
||||
FlxG.log.add('killing dumb ass note at ' + note.noteData.time);
|
||||
|
@ -1955,7 +1960,7 @@ class PlayState extends MusicBeatState
|
|||
// Calling event.cancelEvent() skips all the other logic! Neat!
|
||||
if (event.eventCanceled) return;
|
||||
|
||||
health -= 0.0775;
|
||||
health -= Constants.HEALTH_MISS_PENALTY;
|
||||
|
||||
if (!isPracticeMode)
|
||||
{
|
||||
|
@ -2008,9 +2013,6 @@ class PlayState extends MusicBeatState
|
|||
vocals.playerVolume = 0;
|
||||
FlxG.sound.play(Paths.soundRandom('missnote', 1, 3), FlxG.random.float(0.1, 0.2));
|
||||
}
|
||||
|
||||
note.active = false;
|
||||
note.visible = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2025,7 +2027,7 @@ class PlayState extends MusicBeatState
|
|||
{
|
||||
var event:GhostMissNoteScriptEvent = new GhostMissNoteScriptEvent(direction, // Direction missed in.
|
||||
hasPossibleNotes, // Whether there was a note you could have hit.
|
||||
- 0.035 * 2, // How much health to add (negative).
|
||||
- 1 * Constants.HEALTH_MISS_PENALTY, // How much health to add (negative).
|
||||
- 10 // Amount of score to add (negative).
|
||||
);
|
||||
dispatchEvent(event);
|
||||
|
@ -2098,10 +2100,10 @@ class PlayState extends MusicBeatState
|
|||
if (FlxG.keys.justPressed.ONE) endSong();
|
||||
|
||||
// 2: Gain 10% health.
|
||||
if (FlxG.keys.justPressed.TWO) health += 0.1 * 2.0;
|
||||
if (FlxG.keys.justPressed.TWO) health += 0.1 * Constants.HEALTH_MAX;
|
||||
|
||||
// 3: Lose 5% health.
|
||||
if (FlxG.keys.justPressed.THREE) health -= 0.05 * 2.0;
|
||||
if (FlxG.keys.justPressed.THREE) health -= 0.05 * Constants.HEALTH_MAX;
|
||||
#end
|
||||
|
||||
// 7: Move to the charter.
|
||||
|
@ -2146,36 +2148,33 @@ class PlayState extends MusicBeatState
|
|||
var score = Scoring.scoreNote(noteDiff, PBOT1);
|
||||
var daRating = Scoring.judgeNote(noteDiff, PBOT1);
|
||||
|
||||
var isSick:Bool = false;
|
||||
var healthMulti:Float = 0;
|
||||
|
||||
switch (daRating)
|
||||
{
|
||||
case 'killer':
|
||||
Highscore.tallies.killer += 1;
|
||||
healthMulti = 0.033;
|
||||
health += Constants.HEALTH_KILLER_BONUS;
|
||||
case 'sick':
|
||||
Highscore.tallies.sick += 1;
|
||||
healthMulti = 0.033;
|
||||
health += Constants.HEALTH_SICK_BONUS;
|
||||
case 'good':
|
||||
Highscore.tallies.good += 1;
|
||||
healthMulti = 0.033 * 0.78;
|
||||
health += Constants.HEALTH_GOOD_BONUS;
|
||||
case 'bad':
|
||||
Highscore.tallies.bad += 1;
|
||||
healthMulti = 0.033 * 0.2;
|
||||
health += Constants.HEALTH_BAD_BONUS;
|
||||
case 'shit':
|
||||
Highscore.tallies.shit += 1;
|
||||
healthMulti = 0;
|
||||
health += Constants.HEALTH_SHIT_BONUS;
|
||||
case 'miss':
|
||||
Highscore.tallies.missed += 1;
|
||||
healthMulti = 0;
|
||||
health -= Constants.HEALTH_MISS_PENALTY;
|
||||
}
|
||||
|
||||
health += healthMulti;
|
||||
if (daRating == "sick" || daRating == "killer")
|
||||
{
|
||||
playerStrumline.playNoteSplash(daNote.noteData.getDirection());
|
||||
}
|
||||
|
||||
// Only add the score if you're not on practice mode
|
||||
if (!isPracticeMode)
|
||||
{
|
||||
|
|
|
@ -87,8 +87,10 @@ class NoteSprite extends FlxSprite
|
|||
public var lowPriority:Bool = false;
|
||||
|
||||
/**
|
||||
* This is true if the note has been fully missed by the player.
|
||||
* It will be destroyed immediately.
|
||||
* This is true if the note is later than 10 frames within the strumline,
|
||||
* and thus can't be hit by the player.
|
||||
* It will be destroyed after it moves offscreen.
|
||||
* Managed by PlayState.
|
||||
*/
|
||||
public var hasMissed:Bool;
|
||||
|
||||
|
@ -107,11 +109,10 @@ class NoteSprite extends FlxSprite
|
|||
public var mayHit:Bool;
|
||||
|
||||
/**
|
||||
* This is true if the note is earlier than 10 frames after the strumline,
|
||||
* and thus can't be hit by the player.
|
||||
* Managed by PlayState.
|
||||
* This is true if the PlayState has performed the logic for missing this note.
|
||||
* Subtracting score, subtracting health, etc.
|
||||
*/
|
||||
public var tooLate:Bool;
|
||||
public var handledMiss:Bool;
|
||||
|
||||
public function new(strumTime:Float = 0, direction:Int = 0)
|
||||
{
|
||||
|
@ -171,7 +172,6 @@ class NoteSprite extends FlxSprite
|
|||
this.tooEarly = false;
|
||||
this.hasBeenHit = false;
|
||||
this.mayHit = false;
|
||||
this.tooLate = false;
|
||||
this.hasMissed = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,13 @@ class Strumline extends FlxSpriteGroup
|
|||
});
|
||||
}
|
||||
|
||||
public function getNotesMayHit():Array<NoteSprite>
|
||||
{
|
||||
return notes.members.filter(function(note:NoteSprite) {
|
||||
return note != null && note.alive && !note.hasBeenHit && note.mayHit;
|
||||
});
|
||||
}
|
||||
|
||||
public function getHoldNotesInRange(strumTime:Float, hitWindow:Float):Array<SustainTrail>
|
||||
{
|
||||
var hitWindowStart:Float = strumTime - hitWindow;
|
||||
|
@ -207,24 +214,17 @@ class Strumline extends FlxSpriteGroup
|
|||
// Update rendering of notes.
|
||||
for (note in notes.members)
|
||||
{
|
||||
if (note == null || note.hasBeenHit) continue;
|
||||
if (note == null || !note.alive || note.hasBeenHit) continue;
|
||||
|
||||
var vwoosh:Bool = note.holdNoteSprite == null;
|
||||
// Set the note's position.
|
||||
note.y = this.y - INITIAL_OFFSET + calculateNoteYPos(note.strumTime, vwoosh);
|
||||
|
||||
// Check if the note is outside the hit window, and if so, mark it as missed.
|
||||
// TODO: Check to make sure this doesn't happen when the note is on screen because it'll probably get deleted.
|
||||
if (Conductor.songPosition > (note.noteData.time + Conductor.HIT_WINDOW_MS))
|
||||
// If the note is miss
|
||||
var isOffscreen = PreferencesMenu.getPref('downscroll') ? note.y > FlxG.height : note.y < -note.height;
|
||||
if (note.handledMiss && isOffscreen)
|
||||
{
|
||||
note.visible = false;
|
||||
note.hasMissed = true;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
note.visible = true;
|
||||
note.hasMissed = false;
|
||||
if (note.holdNoteSprite != null) note.holdNoteSprite.missedNote = false;
|
||||
killNote(note);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,80 @@ class Constants
|
|||
*/
|
||||
public static final DEFAULT_VARIATION:String = 'default';
|
||||
|
||||
/**
|
||||
* HEALTH VALUES
|
||||
*/
|
||||
// ==============================
|
||||
|
||||
/**
|
||||
* The player's maximum health.
|
||||
* If the player is at this value, they can't gain any more health.
|
||||
*/
|
||||
public static final HEALTH_MAX:Float = 2.0;
|
||||
|
||||
/**
|
||||
* The player's starting health.
|
||||
*/
|
||||
public static final HEALTH_STARTING = HEALTH_MAX / 2.0;
|
||||
|
||||
/**
|
||||
* The player's minimum health.
|
||||
* If the player is at or below this value, they lose.
|
||||
*/
|
||||
public static final HEALTH_MIN:Float = 0.0;
|
||||
|
||||
/**
|
||||
* The amount of health the player gains when hitting a note with the KILLER rating.
|
||||
*/
|
||||
public static final HEALTH_KILLER_BONUS:Float = 2.0 / 100.0 / HEALTH_MAX; // +2.0%
|
||||
|
||||
/**
|
||||
* The amount of health the player gains when hitting a note with the SICK rating.
|
||||
*/
|
||||
public static final HEALTH_SICK_BONUS:Float = 1.5 / 100.0 / HEALTH_MAX; // +1.0%
|
||||
|
||||
/**
|
||||
* The amount of health the player gains when hitting a note with the GOOD rating.
|
||||
*/
|
||||
public static final HEALTH_GOOD_BONUS:Float = 0.75 / 100.0 / HEALTH_MAX; // +0.75%
|
||||
|
||||
/**
|
||||
* The amount of health the player gains when hitting a note with the BAD rating.
|
||||
*/
|
||||
public static final HEALTH_BAD_BONUS:Float = 0.0 / 100.0 / HEALTH_MAX; // +0.0%
|
||||
|
||||
/**
|
||||
* The amount of health the player gains when hitting a note with the SHIT rating.
|
||||
* If negative, the player will actually lose health.
|
||||
*/
|
||||
public static final HEALTH_SHIT_BONUS:Float = -1.0 / 100.0 / HEALTH_MAX; // -1.0%
|
||||
|
||||
/**
|
||||
* The amount of health the player loses upon missing a note.
|
||||
*/
|
||||
public static final HEALTH_MISS_PENALTY:Float = 4.0 / 100.0 / HEALTH_MAX; // 4.0%
|
||||
|
||||
/**
|
||||
* The amount of health the player loses upon pressing a key when no note is there.
|
||||
*/
|
||||
public static final HEALTH_GHOST_MISS_PENALTY:Float = 2.0 / 100.0 / HEALTH_MAX; // 2.0%
|
||||
|
||||
/**
|
||||
* The amount of health the player loses upon letting go of a hold note while it is still going.
|
||||
*/
|
||||
public static final HEALTH_HOLD_DROP_PENALTY:Float = 0.0; // 0.0%
|
||||
|
||||
/**
|
||||
* The amount of health the player loses upon hitting a mine.
|
||||
*/
|
||||
public static final HEALTH_MINE_PENALTY:Float = 15.0 / 100.0 / HEALTH_MAX; // 15.0%
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static final GHOST_TAPPING:Bool = true;
|
||||
|
||||
/**
|
||||
* OTHER
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue