Attempted fix of Tick Holds

NoteDataUtil::GetTotalHoldTicks() was not counting the last tick of
holds which ended on the last row of the song. Extended the range to
include the last row.

NoteDataUtil::GetTotalHoldTicks() was counting number of rows held, when
it should only count 1 regardless of number( at least to mimic pump )

Player::CrossedRows() was assuming a constant tick rate over the crossed
rows, leading to potentially inaccurate tick counts.

Pump holds were counting "HoldNote_Held" due to capitalization in the
metrics. Fixed metrics and made "IsGame" function case insensitive.
This commit is contained in:
sigatrev
2014-04-23 21:45:37 -05:00
parent f1adf16dc5
commit c4f7aab9a1
4 changed files with 25 additions and 48 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ local function CurGameName()
end
-- Check the active game mode against a string. Cut down typing this in metrics.
function IsGame(str) return CurGameName() == str end
function IsGame(str) return CurGameName():lower() == str:lower() end
-- GetExtraColorThreshold()
-- [en] returns the difficulty threshold in meter
+4 -4
View File
@@ -642,8 +642,8 @@ LifePercentChangeW4=0.000
LifePercentChangeW5=-0.040
LifePercentChangeMiss=-0.080
LifePercentChangeHitMine=-0.160
LifePercentChangeHeld=IsGame("Pump") and 0.000 or 0.008
LifePercentChangeLetGo=IsGame("Pump") and 0.000 or -0.080
LifePercentChangeHeld=IsGame("pump") and 0.000 or 0.008
LifePercentChangeLetGo=IsGame("pump") and 0.000 or -0.080
LifePercentChangeMissedHold=0.000
LifePercentChangeCheckpointMiss=-0.080
LifePercentChangeCheckpointHit=0.008
@@ -1337,7 +1337,7 @@ FrameOverP2OffCommand=
[ScoreKeeperNormal]
PercentScoreWeightCheckpointHit=3
PercentScoreWeightCheckpointMiss=0
PercentScoreWeightHeld=IsGame("Pump") and 0 or 3
PercentScoreWeightHeld=IsGame("pump") and 0 or 3
PercentScoreWeightHitMine=-2
PercentScoreWeightMissedHold=0
PercentScoreWeightLetGo=0
@@ -1349,7 +1349,7 @@ PercentScoreWeightW4=0
PercentScoreWeightW5=0
GradeWeightCheckpointHit=2
GradeWeightCheckpointMiss=-8
GradeWeightHeld=IsGame("Pump") and 0 or 6
GradeWeightHeld=IsGame("pump") and 0 or 6
GradeWeightHitMine=-8
GradeWeightMissedHold=0
GradeWeightLetGo=0
+5 -3
View File
@@ -2616,7 +2616,8 @@ void NoteDataUtil::SetHopoPossibleFlags( const Song *pSong, NoteData& ndInOut )
unsigned int NoteDataUtil::GetTotalHoldTicks( NoteData* nd, const TimingData* td )
{
unsigned int ret = 0;
int end = nd->GetLastRow();
// Last row must be included. -- Matt
int end = nd->GetLastRow()+1;
vector<TimingSegment*> segments = td->GetTimingSegments( SEGMENT_TICKCOUNT );
// We start with the LAST TimingSegment and work our way backwards.
// This way we can continually update end instead of having to lookup when
@@ -2627,9 +2628,10 @@ unsigned int NoteDataUtil::GetTotalHoldTicks( NoteData* nd, const TimingData* td
if( ts->GetTicks() > 0)
{
// Jump to each point where holds would tick and add the number of holds there to ret.
// XXX: Assuming each segment starts on the beat
for(int j = ts->GetRow(); j < end; j += ROWS_PER_BEAT / ts->GetTicks() )
ret += nd->GetNumTracksHeldAtRow(j);
// 1 tick per row.
if( nd->GetNumTracksHeldAtRow(j) > 0 )
ret++;
}
end = ts->GetRow();
}
+15 -40
View File
@@ -618,7 +618,7 @@ void Player::Load()
// Figured this is probably a little expensive so let's cache it
m_bTickHolds = GAMESTATE->GetCurrentGame()->m_bTickHolds;
m_LastTapNoteScore = TNS_None;
// The editor can start playing in the middle of the song.
const int iNoteRow = BeatToNoteRowNotRounded( m_pPlayerState->m_Position.m_fSongBeat );
@@ -1289,7 +1289,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vector<TrackRowTap
// For tickholds, the concept of "life" doesn't really apply.
// XXX: if IMMEDIATE_HOLD_LET_GO this will kill holds if it's EVER let go,
// not just at the first missed checkpoint.
if( GAMESTATE->GetCurrentGame()->m_bTickHolds ) fLife = 0.0;
if( m_bTickHolds ) fLife = 0.0;
else
{
// Decrease life
@@ -3022,23 +3022,16 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
* TODO: Move this to a separate function. */
if( m_bTickHolds && m_pPlayerState->m_PlayerController != PC_AUTOPLAY )
{
int tickCurrent = m_Timing->GetTickcountAtRow( iLastRowCrossed );
// There are some charts that don't want tickcounts involved at all.
int iCheckpointFrequencyRows = ( tickCurrent > 0 ? ROWS_PER_BEAT / tickCurrent : 0 );
if( iCheckpointFrequencyRows > 0 )
// Few rows typically cross per update. Easier to check all crossed rows
// than to calculate from timing segments.
for( int r = m_iFirstUncrossedRow; r <= iLastRowCrossed; ++r )
{
// "the first row after the start of the range that lands on a beat"
int iFirstCheckpointInRange = ((m_iFirstUncrossedRow+iCheckpointFrequencyRows-1)
/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
int tickCurrent = m_Timing->GetTickcountAtRow( r );
// "the last row or first row earlier that lands on a beat"
int iLastCheckpointInRange = ((iLastRowCrossed)/iCheckpointFrequencyRows)
* iCheckpointFrequencyRows;
for( int r = iFirstCheckpointInRange; r <= iLastCheckpointInRange; r += iCheckpointFrequencyRows )
// There is a tick count at this row
if( tickCurrent > 0 && r % ( ROWS_PER_BEAT / tickCurrent ) == 0 )
{
//LOG->Trace( "%d...", r );
vector<int> viColsWithHold;
int iNumHoldsHeldThisRow = 0;
int iNumHoldsMissedThisRow = 0;
@@ -3051,27 +3044,9 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
if( tn.type != TapNote::hold_head )
continue;
int iStartRow = nIter.Row();
int iEndRow = iStartRow + tn.iDuration;
int iTrack = nIter.Track();
// "the first row after the hold head that lands on a beat"
int iFirstCheckpointOfHold = ((iStartRow+iCheckpointFrequencyRows)/iCheckpointFrequencyRows)
* iCheckpointFrequencyRows;
// "the end row or the first earlier row that lands on a beat"
int iLastCheckpointOfHold = ((iEndRow)/iCheckpointFrequencyRows)
* iCheckpointFrequencyRows;
// count the end of the hold as a checkpoint
bool bHoldOverlapsRow = iFirstCheckpointOfHold <= r && r <= iLastCheckpointOfHold;
if( !bHoldOverlapsRow )
continue;
viColsWithHold.push_back( iTrack );
if( tn.HoldResult.fLife > 0 )
{
++iNumHoldsHeldThisRow;
@@ -3086,12 +3061,12 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
GAMESTATE->SetProcessedTimingData(this->m_Timing);
// TODO: Find a better way of handling hold checkpoints with other taps.
if( !viColsWithHold.empty() && ( CHECKPOINTS_TAPS_SEPARATE_JUDGMENT || m_NoteData.GetNumTapNotesInRow( iLastRowCrossed ) == 0 ) )
if( !viColsWithHold.empty() && ( CHECKPOINTS_TAPS_SEPARATE_JUDGMENT || m_NoteData.GetNumTapNotesInRow( r ) == 0 ) )
{
HandleHoldCheckpoint(r,
iNumHoldsHeldThisRow,
iNumHoldsMissedThisRow,
viColsWithHold );
HandleHoldCheckpoint(r,
iNumHoldsHeldThisRow,
iNumHoldsMissedThisRow,
viColsWithHold );
}
}
}