Use a float internally to hold the Score, ensuring hold notes get scored correctly relative to the current framerate.

This commit is contained in:
EliteMasterEric
2026-03-02 01:38:30 -07:00
committed by Hundrec
parent dc23a116dd
commit f8841bab35
3 changed files with 28 additions and 24 deletions
+6 -6
View File
@@ -140,7 +140,7 @@ class HitNoteScriptEvent extends NoteScriptEvent
/**
* The score the player received for hitting the note.
*/
public var score:Int;
public var score:Float;
/**
* If the hit causes a combo break.
@@ -158,7 +158,7 @@ class HitNoteScriptEvent extends NoteScriptEvent
*/
public var doesNotesplash:Bool = false;
public function new(note:NoteSprite, healthChange:Float, score:Int, judgement:String, isComboBreak:Bool, comboCount:Int = 0, hitDiff:Float = 0,
public function new(note:NoteSprite, healthChange:Float, score:Float, judgement:String, isComboBreak:Bool, comboCount:Int = 0, hitDiff:Float = 0,
doesNotesplash:Bool = false):Void
{
super(NOTE_HIT, note, healthChange, comboCount, true);
@@ -200,7 +200,7 @@ class GhostMissNoteScriptEvent extends ScriptEvent
/**
* How much score should be lost when this ghost note is pressed.
*/
public var scoreChange(default, default):Int;
public var scoreChange(default, default):Float;
/**
* Whether to play the record scratch sound.
@@ -212,7 +212,7 @@ class GhostMissNoteScriptEvent extends ScriptEvent
*/
public var playAnim(default, default):Bool;
public function new(dir:NoteDirection, hasPossibleNotes:Bool, healthChange:Float, scoreChange:Int):Void
public function new(dir:NoteDirection, hasPossibleNotes:Bool, healthChange:Float, scoreChange:Float):Void
{
super(NOTE_GHOST_MISS, true);
this.dir = dir;
@@ -239,7 +239,7 @@ class HoldNoteScriptEvent extends NoteScriptEvent
/**
* The score the player received for hitting the note.
*/
public var score:Int;
public var score:Float;
/**
* If the hit causes a combo break.
@@ -257,7 +257,7 @@ class HoldNoteScriptEvent extends NoteScriptEvent
*/
public var doesNotesplash:Bool = false;
public function new(type:ScriptEventType, holdNote:SustainTrail, healthChange:Float, score:Int, isComboBreak:Bool, comboCount:Int = 0,
public function new(type:ScriptEventType, holdNote:SustainTrail, healthChange:Float, score:Float, isComboBreak:Bool, comboCount:Int = 0,
cancelable:Bool = false):Void
{
super(type, null, healthChange, comboCount, true);
+17 -18
View File
@@ -239,9 +239,10 @@ class PlayState extends MusicBeatSubState
/**
* The player's current score.
* TODO: Move this to its own class.
* This needs to be a float because you gain partial points as you hold a hold note,
* possibly less than one point each update depending on your framerate.
*/
public var songScore:Int = 0;
public var songScore:Float = 0;
/**
* Start at this point in the song once the countdown is done.
@@ -1119,7 +1120,7 @@ class PlayState extends MusicBeatSubState
cameraZoomRate = Constants.DEFAULT_ZOOM_RATE;
health = Constants.HEALTH_STARTING;
songScore = 0;
songScore = 0.0;
Highscore.tallies.combo = 0;
// so the song doesn't start too early :D
@@ -1445,7 +1446,7 @@ class PlayState extends MusicBeatSubState
vwooshTimer.cancel();
songScore = 0;
songScore = 0.0;
updateScoreText();
health = Constants.HEALTH_STARTING;
@@ -2704,9 +2705,9 @@ class PlayState extends MusicBeatSubState
}
else
{
// TODO: Add an option for this maybe?
var commaSeparated:Bool = true;
scoreText.text = 'Score: ${FlxStringUtil.formatMoney(songScore, false, commaSeparated)}';
final SHOW_DECIMALS:Bool = false;
final COMMA_SEPARATED:Bool = true;
scoreText.text = 'Score: ${FlxStringUtil.formatMoney(songScore, SHOW_DECIMALS, COMMA_SEPARATED)}';
}
}
@@ -2872,7 +2873,7 @@ class PlayState extends MusicBeatSubState
if (!isBotPlayMode && holdNote.scoreable)
{
health += Constants.HEALTH_HOLD_BONUS_PER_SECOND * elapsed;
songScore += Std.int(Constants.SCORE_HOLD_BONUS_PER_SECOND * elapsed);
songScore += Constants.SCORE_HOLD_BONUS_PER_SECOND * elapsed;
}
// Make sure the player keeps singing while the note is held by the bot.
@@ -2905,7 +2906,7 @@ class PlayState extends MusicBeatSubState
// If the base note of the hold was missed, don't penalize them more on top of that.
var healthChangeMax = Constants.HEALTH_HOLD_DROP_PENALTY_MAX - (holdNote.hitNote ? -Constants.HEALTH_MISS_PENALTY : 0);
var healthChange = healthChangeUncapped.clamp(healthChangeMax, 0);
var scoreChange = Std.int(Constants.SCORE_HOLD_DROP_PENALTY_PER_SECOND * remainingLengthSec);
var scoreChange:Float = Constants.SCORE_HOLD_DROP_PENALTY_PER_SECOND * remainingLengthSec;
var event:HoldNoteScriptEvent = new HoldNoteScriptEvent(NOTE_HOLD_DROP, holdNote, healthChange, scoreChange, true, Highscore.tallies.combo);
dispatchEvent(event);
@@ -3021,9 +3022,7 @@ class PlayState extends MusicBeatSubState
if (targetNote == null) continue;
// Judge and hit the note.
// trace('Hit note! ${targetNote.noteData}');
goodNoteHit(targetNote, input);
// trace('Score: ${songScore}');
notesInDirection.remove(targetNote);
@@ -3150,7 +3149,7 @@ class PlayState extends MusicBeatSubState
var event:GhostMissNoteScriptEvent = new GhostMissNoteScriptEvent(direction, // Direction missed in.
hasPossibleNotes, // Whether there was a note you could have hit.
Constants.HEALTH_GHOST_MISS_PENALTY, // How much health to add (negative).
- 10 // Amount of score to add (negative).
Constants.SCORE_GHOST_MISS_PENALTY // Amount of score to add (negative).
);
dispatchEvent(event);
@@ -3269,7 +3268,7 @@ class PlayState extends MusicBeatSubState
/**
* Handles applying health, score, and ratings.
*/
function applyScore(score:Int, daRating:String, healthChange:Float, isComboBreak:Bool)
function applyScore(score:Float, daRating:String, healthChange:Float, isComboBreak:Bool)
{
switch (daRating)
{
@@ -3426,7 +3425,7 @@ class PlayState extends MusicBeatSubState
{
// crackhead double thingie, sets whether was new highscore, AND saves the song!
var data = {
score: songScore,
score: Std.int(songScore),
tallies: {
sick: Highscore.tallies.sick,
good: Highscore.tallies.good,
@@ -3444,7 +3443,7 @@ class PlayState extends MusicBeatSubState
Highscore.talliesLevel = Highscore.combineTallies(Highscore.tallies, Highscore.talliesLevel);
#if FEATURE_NEWGROUNDS
Leaderboards.submitSongScore(currentSong.id, suffixedDifficulty, songScore);
Leaderboards.submitSongScore(currentSong.id, suffixedDifficulty, Std.int(songScore));
#end
if (!isPracticeMode && !isBotPlayMode)
@@ -3475,7 +3474,7 @@ class PlayState extends MusicBeatSubState
// Determine the score rank for this song we just finished.
var scoreRank:Null<ScoringRank> = Scoring.calculateRank({
score: songScore,
score: Std.int(songScore),
tallies: {
sick: Highscore.tallies.sick,
good: Highscore.tallies.good,
@@ -3510,7 +3509,7 @@ class PlayState extends MusicBeatSubState
{
isNewHighscore = false;
PlayStatePlaylist.campaignScore += songScore;
PlayStatePlaylist.campaignScore += Std.int(songScore);
// Pop the next song ID from the list.
// Returns null if the list is empty.
@@ -3836,7 +3835,7 @@ class PlayState extends MusicBeatSubState
title: PlayStatePlaylist.isStoryMode ? ('${PlayStatePlaylist.campaignTitle}') : ('${currentChart.songName} by ${currentChart.songArtist}'),
prevScoreData: prevScoreData,
scoreData: {
score: PlayStatePlaylist.isStoryMode ? PlayStatePlaylist.campaignScore : songScore,
score: PlayStatePlaylist.isStoryMode ? PlayStatePlaylist.campaignScore : Std.int(songScore),
tallies: {
sick: talliesToUse.sick,
good: talliesToUse.good,
+5
View File
@@ -487,6 +487,11 @@ class Constants
*/
// ==============================
/**
* The amount of score the player loses for pressing a key when no note is there.
*/
public static final SCORE_GHOST_MISS_PENALTY:Float = -10.0;
/**
* The amount of score the player gains for every second they hold a hold note.
* A fraction of this value is granted every frame.