Skip to content

Instantly share code, notes, and snippets.

@AldoMX
Last active March 10, 2017 07:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AldoMX/a27975e9c8a7df8f9e56093b5148e728 to your computer and use it in GitHub Desktop.
Save AldoMX/a27975e9c8a7df8f9e56093b5148e728 to your computer and use it in GitHub Desktop.
Steps::PredictMeter()
float Steps::PredictMeter() const
{
// Aldo_MX: I'm calculating the meter taking into account the step density.
// It will just give a "base value", you need to increase the value if you
// use pivots and/or it's a gimmicky chart.
//
// In other words, this value should be considered the "minimum possible"
// meter value using 1 ~ 10 difficulty scale.
//
// The following formula is used ONLY with checkpoint combinations possible
// with one press (ie. up to quads in double)*:
//
// - 1 / (NumCheckpoints * 4)
//
// *If the song has too many single holds like Love is a Danger Zone CZ, the
// substracted value should not be greater than 25% of the total value.
//
// The following formula is used with any other combination:
//
// SQRT( (NumCheckpoints ^ 1.5) + (NumSteps ^ 1.5) )
//
// If the combination is NOT possible with one press (ex. quads in single),
// the result gets multiplied by 2.
//
// The total value gets divided by the steps length in seconds to get
// the predicted meter value.
//
// EDIT: We multiply by 3 and substract 1.5 (substract only in Single Modes)
// to get meter values similar to NX2 ~ NXA
int iMaxPossibleCols = 4;
switch (m_StepsType)
{
case STEPS_TYPE_PUMP_SINGLE:
case STEPS_TYPE_PUMP_COUPLE:
iMaxPossibleCols--;
}
float fStepsLengthInSeconds = m_Timing.GetElapsedTimeFromBeat(
notes->GetLastBeat()
);
float fDifficulty = 0;
float fHoldDifficultyToDecrease = 0;
// Load TimingData to apply tickcounts
NoteDataUtil::ParseTiming( *notes, m_Timing, true );
for (int r=0; r < notes->GetNumRows(); ++r)
{
int iColsWithAny = notes->GetNumColsWithCheckpoint(r, false),
// Do not count hold heads as checkpoints!
// Phantom-style Holds will increase the base difficulty :/, but
// holds should not decrease the difficulty before a certain amount
// of combo...
iColsWithHoldBodyOrTail = notes->GetNumColsWithCheckpoint(r, true, true);
// No Steps in this row
if (iColsWithAny <= 0)
continue;
int iColsWithNotes = iColsWithAny - iColsWithHoldBodyOrTail;
// Only checkpoints
if (iColsWithNotes <= 0)
{
// Combinations possible with a single press
if (iColsWithHoldBodyOrTail <= iMaxPossibleCols)
fHoldDifficultyToDecrease += 1.f / (iColsWithHoldBodyOrTail*4);
// Combinations NOT possible with a single press
else
fDifficulty += sqrt(powf((float)iColsWithHoldBodyOrTail, 1.5f))
* 2.f;
}
// Checkpoints and steps or only steps in this row
else
{
// Any combination
float fValueToAdd = sqrt(powf((float)iColsWithHoldBodyOrTail, 1.5f)
+ powf((float)iColsWithNotes, 1.5f));
// Combinations NOT possible with a single press, multiply by 2
if (iColsWithAny > iMaxPossibleCols)
fValueToAdd *= 2;
fDifficulty += fValueToAdd;
}
}
// Revert NoteData
NoteDataUtil::UnparseTiming( *notes, m_Timing, true );
// Substract a maximum of 25%
fHoldDifficultyToDecrease = min(fHoldDifficultyToDecrease, fDifficulty*.25f);
fDifficulty -= fHoldDifficultyToDecrease;
// Divide by the steps length in seconds
fDifficulty /= fStepsLengthInSeconds;
// HACK: Adjust the final value to get NX2~NXA-like values...
fDifficulty *= 3.0f;
if (iMaxPossibleCols == 3)
fDifficulty -= 1.50000001f;
// Lowest value should be 1
fDifficulty = max(fDifficulty, 1.f);
return fDifficulty;
}
/*
* StepMania AMX is (c) 2008-2017 Aldo Fregoso "Aldo_MX".
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment