From dd760b83cdad7d1d7d5cd066bcd8f9e400bae366 Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Mon, 5 Jul 2010 14:16:18 -0500 Subject: [PATCH] [Player] add RequireStepOnMines metric. This allows DDR's Shock Arrows to be emulated. [FSX] --- Docs/Changelog_sm-ssc.txt | 27 +++++++-- Themes/_fallback/metrics.ini | 1 + src/Player.cpp | 111 ++++++++++++++++++++++++++++++----- 3 files changed, 119 insertions(+), 20 deletions(-) diff --git a/Docs/Changelog_sm-ssc.txt b/Docs/Changelog_sm-ssc.txt index 0454633fb1..e7f354d89e 100644 --- a/Docs/Changelog_sm-ssc.txt +++ b/Docs/Changelog_sm-ssc.txt @@ -9,17 +9,34 @@ Not all changes are documented, for various reasons. supported but exist anyways.) _____________________________________________________________________________ +================================================================================ +sm-ssc v1.0 Release Candidate 2 | 201007xx +-------------------------------------------------------------------------------- +(work in progress, it's not out yet [hence the "xx" above].) + +20100705 +-------- +* [Player] add RequireStepOnMines metric. This allows DDR's Shock Arrows to + be emulated. [FSX] + +20100703 +-------- +sm4svn: + * r28374: add GetBestFullComboTapNoteScore [Chris Danford] + (This replaces the IsFullComboW* bindings, which we never took in. -aj) + +sm-ssc: + * [Course] add GetCourseEntries() Lua binding. + * [Trail] add GetEntries() Lua binding. + * [ScreenTextEntry] replace hardcoded underscore and double space with + AnswerCaret and AnswerBlank strings. + 20100702 -------- sm4svn: * r28372: use MercifulDrain logic for MercifulBeginner [Chris Danford] * r28373: don't override user scroll in courses [Chris Danford] -================================================================================ -sm-ssc v1.0 Release Candidate 2 | 201007xx --------------------------------------------------------------------------------- -(work in progress, it's not out yet [hence the "xx" above].) - 20100630 -------- sm4svn commits: diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index b567daa003..9d300dd87f 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -893,6 +893,7 @@ CheckpointsTapsSeparateJudgment=CheckpointsTapsSeparateJudgment() CheckpointsFlashOnHold=false ImmediateHoldLetGo=ImmediateHoldLetGo() RequireStepOnHoldHeads=HoldHeadStep() +RequireStepOnMines=false InitialHoldLife=InitialHoldLife() MaxHoldLife=MaxHoldLife() RollBodyIncrementsCombo=RollBodyIncrementsCombo() diff --git a/src/Player.cpp b/src/Player.cpp index f89923c9c9..4f20adf604 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -135,6 +135,7 @@ ThemeMetric CHECKPOINTS_USE_TIME_SIGNATURES ( "Player", "CheckpointsUseTim ThemeMetric CHECKPOINTS_FLASH_ON_HOLD ( "Player", "CheckpointsFlashOnHold" ); // sm-ssc addition ThemeMetric IMMEDIATE_HOLD_LET_GO ( "Player", "ImmediateHoldLetGo" ); ThemeMetric REQUIRE_STEP_ON_HOLD_HEADS ( "Player", "RequireStepOnHoldHeads" ); +ThemeMetric REQUIRE_STEP_ON_MINES ( "Player", "RequireStepOnMines" ); //ThemeMetric HOLD_TRIGGERS_TAP_NOTES ( "Player", "HoldTriggersTapNotes" ); // parastar stuff; leave in though ThemeMetric ROLL_BODY_INCREMENTS_COMBO ( "Player", "RollBodyIncrementsCombo" ); ThemeMetric CHECKPOINTS_TAPS_SEPARATE_JUDGMENT ( "Player", "CheckpointsTapsSeparateJudgment" ); @@ -476,7 +477,7 @@ void Player::Load() const Song* pSong = GAMESTATE->m_pCurSong; if( GAMESTATE->m_pCurGame->m_bAllowHopos ) NoteDataUtil::SetHopoPossibleFlags( pSong, m_NoteData ); - + switch( GAMESTATE->m_PlayMode ) { case PLAY_MODE_RAVE: @@ -836,6 +837,7 @@ void Player::Update( float fDeltaTime ) { vector v; v.push_back( trtn ); + //LOG->Trace("UpdateHoldNotes from a roll"); UpdateHoldNotes( iSongRow, fDeltaTime, v ); } continue; // don't process this below @@ -849,6 +851,7 @@ void Player::Update( float fDeltaTime ) { if( !vHoldNotesToGradeTogether.empty() ) { + //LOG->Trace( ssprintf("UpdateHoldNotes; %i != %i || !judge holds on same row together",iRow,iRowOfLastHoldNote) ); UpdateHoldNotes( iSongRow, fDeltaTime, vHoldNotesToGradeTogether ); vHoldNotesToGradeTogether.clear(); } @@ -859,6 +862,7 @@ void Player::Update( float fDeltaTime ) if( !vHoldNotesToGradeTogether.empty() ) { + //LOG->Trace("UpdateHoldNotes since !vHoldNotesToGradeTogether.empty()"); UpdateHoldNotes( iSongRow, fDeltaTime, vHoldNotesToGradeTogether ); vHoldNotesToGradeTogether.clear(); } @@ -909,6 +913,11 @@ void Player::Update( float fDeltaTime ) void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vector &vTN ) { ASSERT( !vTN.empty() ); + /* + LOG->Trace("--------------------------------"); + LOG->Trace("[Player::UpdateHoldNotes] begins"); + LOG->Trace( ssprintf("song row %i, deltaTime = %f",iSongRow,fDeltaTime) ); + */ int iStartRow = vTN[0].iRow; int iMaxEndRow = INT_MIN; @@ -936,6 +945,8 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace( ssprintf("start row: %i; max/end row: = %i",iStartRow,iMaxEndRow) ); + //LOG->Trace( ssprintf("first track with max end row = %i",iFirstTrackWithMaxEndRow) ); FOREACH( TrackRowTapNote, vTN, trtn ) { @@ -946,28 +957,50 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectoriRow; + //LOG->Trace( ssprintf("this row: %i",iRow) ); // If the song beat is in the range of this hold: if( iRow <= iSongRow && iRow <= iMaxEndRow ) + { + //LOG->Trace( ssprintf("overlap time before: %f",tn.HoldResult.fOverlappedTime) ); tn.HoldResult.fOverlappedTime += fDeltaTime; + //LOG->Trace( ssprintf("overlap time after: %f",tn.HoldResult.fOverlappedTime) ); + } else + { + //LOG->Trace( "overlap time = 0" ); tn.HoldResult.fOverlappedTime = 0; + } } HoldNoteScore hns = vTN[0].pTN->HoldResult.hns; float fLife = vTN[0].pTN->HoldResult.fLife; + if( hns != HNS_None ) // if this HoldNote already has a result return; // we don't need to update the logic for this group + //LOG->Trace( ssprintf("[C++] hold note score: %s",HoldNoteScoreToString(hns).c_str()) ); + //LOG->Trace(ssprintf("[Player::UpdateHoldNotes] fLife = %f",fLife)); + bool bSteppedOnHead = true; FOREACH( TrackRowTapNote, vTN, trtn ) { TapNote &tn = *trtn->pTN; TapNoteScore tns = tn.result.tns; + //LOG->Trace( ssprintf("[C++] tap note score: %s",TapNoteScoreToString(tns).c_str()) ); // TODO: When using JUDGE_HOLD_NOTES_ON_SAME_ROW_TOGETHER, require that the whole row of // taps was hit before activating this group of holds. - bSteppedOnHead &= tns != TNS_None && tns != TNS_Miss; // did they step on the start of this hold? + /* Something about the logic in this section is causing 192nd steps to + * fail for some odd reason. -aj */ + bSteppedOnHead &= (tns != TNS_None && tns != TNS_Miss); // did they step on the start of this hold? + + /* + if(bSteppedOnHead) + LOG->Trace("[Player::UpdateHoldNotes] player stepped on head"); + else + LOG->Trace("[Player::UpdateHoldNotes] player didn't step on the head"); + */ } bool bInitiatedNote; @@ -1012,7 +1045,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorGetCurrentStyle()->StyleInputToGameInput( iTrack, pn ); // this previously read as bIsHoldingButton &= // was there a specific reason for this? - Friez - bIsHoldingButton = INPUTMAPPER->IsBeingPressed( GameI, m_pPlayerState->m_mp ); + bIsHoldingButton &= INPUTMAPPER->IsBeingPressed( GameI, m_pPlayerState->m_mp ); if( m_vAlterMap.size() > 0 ) // alternate input is being used { @@ -1030,6 +1063,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("[Player::UpdateHoldNotes] initiated note, fLife != 0"); /* This hold note is not judged and we stepped on its head. * Update iLastHeldRow. Do this even if we're a little beyond the end * of the hold note, to make sure iLastHeldRow is clamped to iEndRow @@ -1060,11 +1094,25 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("bInitiatedNote && bIsHoldingButton; Increasing hold life to MAX_HOLD_LIFE"); // Increase life fLife = MAX_HOLD_LIFE; // was 1 -aj } else { + /* + LOG->Trace("Checklist:"); + if(bInitiatedNote) + LOG->Trace("[X] Initiated Note"); + else + LOG->Trace("[ ] Initiated Note"); + + if(bIsHoldingButton) + LOG->Trace("[X] Holding Button"); + else + LOG->Trace("[ ] Holding Button"); + */ + // Decrease life fLife -= fDeltaTime/GetWindowSeconds(TW_Hold); fLife = max( fLife, 0 ); // clamp @@ -1109,7 +1157,10 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("LetGo from life == 0 (did initiate hold)"); hns = HNS_LetGo; + } } // score hold notes that have passed @@ -1139,6 +1190,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("(hold checkpoints are allowed and enabled.)"); int iCheckpointsHit = 0; int iCheckpointsMissed = 0; FOREACH( TrackRowTapNote, vTN, v ) @@ -1152,28 +1204,53 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("let go of hold note, life is 0"); + else + LOG->Trace("did not let go of hold note :D"); + */ } else { + //LOG->Trace("(hold checkpoints disabled.)"); bLetGoOfHoldNote = fLife == 0; + /* + if(bLetGoOfHoldNote) + LOG->Trace("let go of hold note, life is 0"); + else + LOG->Trace("did not let go of hold note :D"); + */ } - if( bInitiatedNote && !bLetGoOfHoldNote ) + if( bInitiatedNote ) { - fLife = 1; - hns = HNS_Held; - bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; - if( m_pNoteField ) + if(!bLetGoOfHoldNote) { - FOREACH( TrackRowTapNote, vTN, trtn ) + //LOG->Trace("initiated note and didn't let go"); + fLife = 1; // xxx: should be MAX_HOLD_LIFE instead? -aj + hns = HNS_Held; + bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo>(int)BRIGHT_GHOST_COMBO_THRESHOLD; + if( m_pNoteField ) { - int iTrack = trtn->iTrack; - m_pNoteField->DidHoldNote( iTrack, HNS_Held, bBright ); // bright ghost flash + FOREACH( TrackRowTapNote, vTN, trtn ) + { + int iTrack = trtn->iTrack; + m_pNoteField->DidHoldNote( iTrack, HNS_Held, bBright ); // bright ghost flash + } } } + /* + else + { + LOG->Trace("initiated note and let go :("); + } + */ } else { + //LOG->Trace("did not initiate note"); if( !bInitiatedNote && !SCORE_MISSED_HOLDS_AND_ROLLS ) hns = HNS_None; else @@ -1202,10 +1279,12 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("tap note scoring time."); TapNote &tn = *vTN[0].pTN; HandleHoldScore( tn ); SetHoldJudgment( tn.result.tns, tn.HoldResult.hns, iFirstTrackWithMaxEndRow ); } + //LOG->Trace("[Player::UpdateHoldNotes] ends"); } void Player::ApplyWaitingTransforms() @@ -1884,9 +1963,11 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b // The offset from the actual step in seconds: fNoteOffset = (fStepSeconds - fMusicSeconds) / GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; // account for music rate -// LOG->Trace("step was %.3f ago, music is off by %f: %f vs %f, step was %f off", -// fTimeSinceStep, GAMESTATE->m_LastBeatUpdate.Ago()/GAMESTATE->m_SongOptions.m_fMusicRate, -// fStepSeconds, fMusicSeconds, fNoteOffset ); + /* + LOG->Trace("step was %.3f ago, music is off by %f: %f vs %f, step was %f off", + fTimeSinceStep, GAMESTATE->m_LastBeatUpdate.Ago()/GAMESTATE->m_SongOptions.m_fMusicRate, + fStepSeconds, fMusicSeconds, fNoteOffset ); + */ } const float fSecondsFromExact = fabsf( fNoteOffset ); @@ -1914,7 +1995,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b { case TapNote::mine: // Stepped too close to mine? - if( !bRelease && fSecondsFromExact <= GetWindowSeconds(TW_Mine) ) + if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) && fSecondsFromExact <= GetWindowSeconds(TW_Mine) ) score = TNS_HitMine; break;