Merge pull request #10 from teejusb/tns
Add support for disabling timing windows on a per-player basis
This commit is contained in:
@@ -1248,6 +1248,7 @@
|
|||||||
<Function name='DigitalZSteps'/>
|
<Function name='DigitalZSteps'/>
|
||||||
<Function name='Dizzy'/>
|
<Function name='Dizzy'/>
|
||||||
<Function name='DizzyHolds'/>
|
<Function name='DizzyHolds'/>
|
||||||
|
<Function name='DisableTimingWindow'/>
|
||||||
<Function name='Distant'/>
|
<Function name='Distant'/>
|
||||||
<Function name='DrainSetting'/>
|
<Function name='DrainSetting'/>
|
||||||
<Function name='DrawSize'/>
|
<Function name='DrawSize'/>
|
||||||
@@ -1267,6 +1268,7 @@
|
|||||||
<Function name='Flip'/>
|
<Function name='Flip'/>
|
||||||
<Function name='Floored'/>
|
<Function name='Floored'/>
|
||||||
<Function name='FromString'/>
|
<Function name='FromString'/>
|
||||||
|
<Function name='GetDisabledTimingWindows'/>
|
||||||
<Function name='GetReversePercentForColumn'/>
|
<Function name='GetReversePercentForColumn'/>
|
||||||
<Function name='GetStepAttacks'/>
|
<Function name='GetStepAttacks'/>
|
||||||
<Function name='IsEasierForSongAndSteps'/>
|
<Function name='IsEasierForSongAndSteps'/>
|
||||||
@@ -1319,6 +1321,7 @@
|
|||||||
<Function name='RandAttack'/>
|
<Function name='RandAttack'/>
|
||||||
<Function name='RandomSpeed'/>
|
<Function name='RandomSpeed'/>
|
||||||
<Function name='RandomVanish'/>
|
<Function name='RandomVanish'/>
|
||||||
|
<Function name='ResetDisabledTimingWindows'/>
|
||||||
<Function name='Reverse'/>
|
<Function name='Reverse'/>
|
||||||
<Function name='Reversen'/>
|
<Function name='Reversen'/>
|
||||||
<Function name='Right'/>
|
<Function name='Right'/>
|
||||||
@@ -1368,6 +1371,7 @@
|
|||||||
<Function name='Twirl'/>
|
<Function name='Twirl'/>
|
||||||
<Function name='Twister'/>
|
<Function name='Twister'/>
|
||||||
<Function name='UsingReverse'/>
|
<Function name='UsingReverse'/>
|
||||||
|
<Function name='VisualDelay'/>
|
||||||
<Function name='Wave'/>
|
<Function name='Wave'/>
|
||||||
<Function name='WavePeriod'/>
|
<Function name='WavePeriod'/>
|
||||||
<Function name='Wide'/>
|
<Function name='Wide'/>
|
||||||
|
|||||||
@@ -3915,6 +3915,10 @@ a,b = options:Boost(5)
|
|||||||
</Function>
|
</Function>
|
||||||
<Function name='Dizzy' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='Dizzy' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
<Function name='DizzyHolds' return='bool' arguments='bool value'> </Function>
|
<Function name='DizzyHolds' return='bool' arguments='bool value'> </Function>
|
||||||
|
<Function name='DisableTimingWindow' return='' arguments='TimingWindow tw'>
|
||||||
|
Selectively disable specific timing windows for a player. <br />
|
||||||
|
Valid values are <code>W1</code> to <code>W5</code> as defined in the <Link class='ENUM' function='TimingWindow' /> enum.
|
||||||
|
</Function>
|
||||||
<Function name='Distant' return='float, float' arguments='float value, float approach_speed'>
|
<Function name='Distant' return='float, float' arguments='float value, float approach_speed'>
|
||||||
If the player is using Distant (zero skew and positive tilt), returns the value of tilt and its approach_speed.<br />
|
If the player is using Distant (zero skew and positive tilt), returns the value of tilt and its approach_speed.<br />
|
||||||
Returns nil otherwise.<br />
|
Returns nil otherwise.<br />
|
||||||
@@ -3960,6 +3964,9 @@ a,b = options:Boost(5)
|
|||||||
</Function>
|
</Function>
|
||||||
<Function name='Flip' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='Flip' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
<Function name='Floored' return='bool' arguments='bool value'> </Function>
|
<Function name='Floored' return='bool' arguments='bool value'> </Function>
|
||||||
|
<Function name='GetDisabledTimingWindows' return='{TimingWindow}' arguments=''>
|
||||||
|
Returns a table of the currently disabled <Link class='ENUM' function='TimingWindow' />s for the player.
|
||||||
|
</Function>
|
||||||
<Function name='GetStepAttacks' return='bool' arguments=''>
|
<Function name='GetStepAttacks' return='bool' arguments=''>
|
||||||
Returns true if step attacks or random attacks are enabled.
|
Returns true if step attacks or random attacks are enabled.
|
||||||
</Function>
|
</Function>
|
||||||
@@ -4065,6 +4072,9 @@ prev_note_name, succeeded = options:NoteSkin("cel")
|
|||||||
<Function name='RandAttack' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='RandAttack' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
<Function name='RandomSpeed' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='RandomSpeed' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
<Function name='RandomVanish' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='RandomVanish' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
|
<Function name='ResetDisabledTimingWindows' return='' arguments=''>
|
||||||
|
Re-enable all <Link class='ENUM' function='TimingWindow' />s that may have previously been disabled.
|
||||||
|
</Function>
|
||||||
<Function name='Reverse' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='Reverse' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
<Function name='Reversen' return= 'float, float' arguments='float value, float approach_speed'>
|
<Function name='Reversen' return= 'float, float' arguments='float value, float approach_speed'>
|
||||||
Use 1-16 in place of 'n' to apply Reverse on a specific column.
|
Use 1-16 in place of 'n' to apply Reverse on a specific column.
|
||||||
@@ -4165,6 +4175,11 @@ prev_note_name, succeeded = options:NoteSkin("cel")
|
|||||||
<Function name='UsingReverse' return='bool' arguments=''>
|
<Function name='UsingReverse' return='bool' arguments=''>
|
||||||
Returns <code>true</code> if the player is using reverse. (equivalent to <code>GetReverse() == 1.0</code>)
|
Returns <code>true</code> if the player is using reverse. (equivalent to <code>GetReverse() == 1.0</code>)
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name='VisualDelay' return='' arguments='float'>
|
||||||
|
The time in seconds to adjust a player's visual delay by.<br />
|
||||||
|
Negative values will shift the arrows up, while positive values will push them down.<br />
|
||||||
|
Sub-millisecond visual delay values are not saved and are instead rounded to the closest millisecond.
|
||||||
|
</Function>
|
||||||
<Function name='Wave' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='Wave' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
<Function name='WavePeriod' return='float, float' arguments='float value, float approach_speed'> </Function>
|
<Function name='WavePeriod' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||||
<Function name='Wide' return='bool' arguments='bool value'> </Function>
|
<Function name='Wide' return='bool' arguments='bool value'> </Function>
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ static const char *TimingWindowNames[] = {
|
|||||||
"Checkpoint"
|
"Checkpoint"
|
||||||
};
|
};
|
||||||
XToString( TimingWindow );
|
XToString( TimingWindow );
|
||||||
|
LuaXType( TimingWindow );
|
||||||
|
StringToX( TimingWindow );
|
||||||
|
|
||||||
static const char *ScoreEventNames[] = {
|
static const char *ScoreEventNames[] = {
|
||||||
"CheckpointHit",
|
"CheckpointHit",
|
||||||
|
|||||||
@@ -294,9 +294,11 @@ enum TimingWindow
|
|||||||
TW_Hold,
|
TW_Hold,
|
||||||
TW_Roll,
|
TW_Roll,
|
||||||
TW_Checkpoint,
|
TW_Checkpoint,
|
||||||
NUM_TimingWindow
|
NUM_TimingWindow,
|
||||||
|
TimingWindow_Invalid,
|
||||||
};
|
};
|
||||||
const RString& TimingWindowToString( TimingWindow tw );
|
const RString& TimingWindowToString( TimingWindow tw );
|
||||||
|
LuaDeclareType( TimingWindow );
|
||||||
|
|
||||||
/** @brief The list of score events that can take place while playing. */
|
/** @brief The list of score events that can take place while playing. */
|
||||||
enum ScoreEvent
|
enum ScoreEvent
|
||||||
|
|||||||
+27
-6
@@ -104,7 +104,7 @@ static const float StepSearchDistance = 1.0f;
|
|||||||
|
|
||||||
void TimingWindowSecondsInit( size_t /*TimingWindow*/ i, RString &sNameOut, float &defaultValueOut )
|
void TimingWindowSecondsInit( size_t /*TimingWindow*/ i, RString &sNameOut, float &defaultValueOut )
|
||||||
{
|
{
|
||||||
sNameOut = "TimingWindowSeconds" + TimingWindowToString( (TimingWindow)i );
|
sNameOut = "TimingWindowSeconds" + TimingWindowToString( static_cast<TimingWindow>(i) );
|
||||||
switch( i )
|
switch( i )
|
||||||
{
|
{
|
||||||
case TW_W1:
|
case TW_W1:
|
||||||
@@ -1002,10 +1002,16 @@ void Player::Update( float fDeltaTime )
|
|||||||
// were held at some point before getting judged.
|
// were held at some point before getting judged.
|
||||||
{
|
{
|
||||||
float largestWindow = 0.0f;
|
float largestWindow = 0.0f;
|
||||||
|
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||||
|
if (!disabledWindows[TW_W1])
|
||||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W1));
|
largestWindow = max(largestWindow, GetWindowSeconds(TW_W1));
|
||||||
|
if (!disabledWindows[TW_W2])
|
||||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W2));
|
largestWindow = max(largestWindow, GetWindowSeconds(TW_W2));
|
||||||
|
if (!disabledWindows[TW_W3])
|
||||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W3));
|
largestWindow = max(largestWindow, GetWindowSeconds(TW_W3));
|
||||||
|
if (!disabledWindows[TW_W4])
|
||||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W4));
|
largestWindow = max(largestWindow, GetWindowSeconds(TW_W4));
|
||||||
|
if (!disabledWindows[TW_W5])
|
||||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W5));
|
largestWindow = max(largestWindow, GetWindowSeconds(TW_W5));
|
||||||
|
|
||||||
// We have to check the unjudged notes that are within the
|
// We have to check the unjudged notes that are within the
|
||||||
@@ -2264,18 +2270,31 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
|||||||
// bug. (It was fNoteOffset > 0.f before) -DaisuMaster
|
// bug. (It was fNoteOffset > 0.f before) -DaisuMaster
|
||||||
if( !REQUIRE_STEP_ON_HOLD_HEADS && ( fNoteOffset <= GetWindowSeconds( TW_W5 ) && GetWindowSeconds( TW_W5 ) != 0 ) )
|
if( !REQUIRE_STEP_ON_HOLD_HEADS && ( fNoteOffset <= GetWindowSeconds( TW_W5 ) && GetWindowSeconds( TW_W5 ) != 0 ) )
|
||||||
{
|
{
|
||||||
|
// Set it to the first non-disabled window.
|
||||||
|
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||||
|
if (!disabledWindows[TW_W1])
|
||||||
score = TNS_W1;
|
score = TNS_W1;
|
||||||
|
else if (!disabledWindows[TW_W2])
|
||||||
|
score = TNS_W2;
|
||||||
|
else if (!disabledWindows[TW_W3])
|
||||||
|
score = TNS_W3;
|
||||||
|
else if (!disabledWindows[TW_W4])
|
||||||
|
score = TNS_W4;
|
||||||
|
else if (!disabledWindows[TW_W5])
|
||||||
|
score = TNS_W5;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Fall through to default.
|
// Fall through to default.
|
||||||
default:
|
default:
|
||||||
if( (pTN->type == TapNoteType_Lift) == bRelease )
|
if( (pTN->type == TapNoteType_Lift) == bRelease )
|
||||||
{
|
{
|
||||||
if( fSecondsFromExact <= GetWindowSeconds(TW_W1) ) score = TNS_W1;
|
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W2) ) score = TNS_W2;
|
if( fSecondsFromExact <= GetWindowSeconds(TW_W1) && !disabledWindows[TW_W1] ) score = TNS_W1;
|
||||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W3) ) score = TNS_W3;
|
else if( fSecondsFromExact <= GetWindowSeconds(TW_W2) && !disabledWindows[TW_W2] ) score = TNS_W2;
|
||||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W4) ) score = TNS_W4;
|
else if( fSecondsFromExact <= GetWindowSeconds(TW_W3) && !disabledWindows[TW_W3] ) score = TNS_W3;
|
||||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W5) ) score = TNS_W5;
|
else if( fSecondsFromExact <= GetWindowSeconds(TW_W4) && !disabledWindows[TW_W4] ) score = TNS_W4;
|
||||||
|
else if( fSecondsFromExact <= GetWindowSeconds(TW_W5) && !disabledWindows[TW_W5] ) score = TNS_W5;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2283,6 +2302,7 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
|||||||
|
|
||||||
case PC_CPU:
|
case PC_CPU:
|
||||||
case PC_AUTOPLAY:
|
case PC_AUTOPLAY:
|
||||||
|
{
|
||||||
score = PlayerAI::GetTapNoteScore(m_pPlayerState);
|
score = PlayerAI::GetTapNoteScore(m_pPlayerState);
|
||||||
|
|
||||||
/* XXX: This doesn't make sense.
|
/* XXX: This doesn't make sense.
|
||||||
@@ -2399,6 +2419,7 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
|||||||
fNoteOffset = TapNoteOffset attribute
|
fNoteOffset = TapNoteOffset attribute
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
FAIL_M(ssprintf("Invalid player controller type: %i", m_pPlayerState->m_PlayerController));
|
FAIL_M(ssprintf("Invalid player controller type: %i", m_pPlayerState->m_PlayerController));
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -141,7 +141,21 @@ TapNoteScore PlayerAI::GetTapNoteScore( const PlayerState* pPlayerState )
|
|||||||
|
|
||||||
TapScoreDistribution& distribution = g_Distributions[iCpuSkill];
|
TapScoreDistribution& distribution = g_Distributions[iCpuSkill];
|
||||||
|
|
||||||
return distribution.GetTapNoteScore();
|
TapNoteScore score = distribution.GetTapNoteScore();
|
||||||
|
|
||||||
|
const auto& disabledWindows = pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||||
|
// Downgrade the TapNoteScore if that specific window is disabled.
|
||||||
|
if (score == TNS_W1 && disabledWindows[TW_W1])
|
||||||
|
score = TNS_W2;
|
||||||
|
if (score == TNS_W2 && disabledWindows[TW_W2])
|
||||||
|
score = TNS_W3;
|
||||||
|
if (score == TNS_W3 && disabledWindows[TW_W3])
|
||||||
|
score = TNS_W4;
|
||||||
|
if (score == TNS_W4 && disabledWindows[TW_W4])
|
||||||
|
score = TNS_W5;
|
||||||
|
if (score == TNS_W5 && disabledWindows[TW_W5])
|
||||||
|
score = TNS_None;
|
||||||
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+86
-1
@@ -10,6 +10,7 @@
|
|||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
#include "CommonMetrics.h"
|
#include "CommonMetrics.h"
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
static const char *LifeTypeNames[] = {
|
static const char *LifeTypeNames[] = {
|
||||||
"Bar",
|
"Bar",
|
||||||
@@ -96,6 +97,7 @@ void PlayerOptions::Init()
|
|||||||
m_bCosecant = false;
|
m_bCosecant = false;
|
||||||
m_sNoteSkin = "";
|
m_sNoteSkin = "";
|
||||||
m_fVisualDelay = 0.0f;
|
m_fVisualDelay = 0.0f;
|
||||||
|
m_twDisabledWindows.reset();
|
||||||
ZERO( m_fMovesX ); ONE( m_SpeedfMovesX );
|
ZERO( m_fMovesX ); ONE( m_SpeedfMovesX );
|
||||||
ZERO( m_fMovesY ); ONE( m_SpeedfMovesY );
|
ZERO( m_fMovesY ); ONE( m_SpeedfMovesY );
|
||||||
ZERO( m_fMovesZ ); ONE( m_SpeedfMovesZ );
|
ZERO( m_fMovesZ ); ONE( m_SpeedfMovesZ );
|
||||||
@@ -187,6 +189,7 @@ void PlayerOptions::Approach( const PlayerOptions& other, float fDeltaSeconds )
|
|||||||
DO_COPY( m_MinTNSToHideNotes );
|
DO_COPY( m_MinTNSToHideNotes );
|
||||||
DO_COPY( m_sNoteSkin );
|
DO_COPY( m_sNoteSkin );
|
||||||
DO_COPY( m_fVisualDelay );
|
DO_COPY( m_fVisualDelay );
|
||||||
|
DO_COPY( m_twDisabledWindows );
|
||||||
#undef APPROACH
|
#undef APPROACH
|
||||||
#undef DO_COPY
|
#undef DO_COPY
|
||||||
}
|
}
|
||||||
@@ -564,6 +567,25 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
|
|||||||
// Note that we don't process sub-millisecond visual delay.
|
// Note that we don't process sub-millisecond visual delay.
|
||||||
AddTo.push_back( ssprintf("%.0fms VisualDelay", m_fVisualDelay * 1000.0f) );
|
AddTo.push_back( ssprintf("%.0fms VisualDelay", m_fVisualDelay * 1000.0f) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_twDisabledWindows.count() != 0) {
|
||||||
|
std::stringstream ss;
|
||||||
|
bool is_first = true;
|
||||||
|
ss << "No ";
|
||||||
|
for (int i=TW_W1; i != TW_W5; ++i) {
|
||||||
|
if (m_twDisabledWindows[i]) {
|
||||||
|
if (!is_first) {
|
||||||
|
ss << "/";
|
||||||
|
} else {
|
||||||
|
is_first = true;
|
||||||
|
}
|
||||||
|
ss << TimingWindowToString(static_cast<TimingWindow>(i)).c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final string will be something like "No W4/W5"
|
||||||
|
AddTo.push_back(ss.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Options are added to the current settings; call Init() beforehand if
|
/* Options are added to the current settings; call Init() beforehand if
|
||||||
@@ -644,6 +666,7 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
|
|||||||
const bool on = (level > 0.5f);
|
const bool on = (level > 0.5f);
|
||||||
|
|
||||||
static Regex mult("^([0-9]+(\\.[0-9]+)?)x$");
|
static Regex mult("^([0-9]+(\\.[0-9]+)?)x$");
|
||||||
|
static Regex disabledWindows("(w[1-5])");
|
||||||
vector<RString> matches;
|
vector<RString> matches;
|
||||||
if( mult.Compare(sBit, matches) )
|
if( mult.Compare(sBit, matches) )
|
||||||
{
|
{
|
||||||
@@ -1142,6 +1165,26 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
|
|||||||
else if( sBit == "zbuffer" ) m_bZBuffer = on;
|
else if( sBit == "zbuffer" ) m_bZBuffer = on;
|
||||||
else if( sBit == "cosecant" ) m_bCosecant = on;
|
else if( sBit == "cosecant" ) m_bCosecant = on;
|
||||||
else if( sBit == "visualdelay" ) m_fVisualDelay = level;
|
else if( sBit == "visualdelay" ) m_fVisualDelay = level;
|
||||||
|
else if( level == 0 && disabledWindows.Compare(sBit)) // "No w1" etc.
|
||||||
|
{
|
||||||
|
// We come into this condition if there is at least a single window present but there may be more.
|
||||||
|
// To get all of the windows, we go through in a loop to extract all of them.
|
||||||
|
static Regex allDisabledWindows("(w[1-5])(.*)$");
|
||||||
|
RString input = sBit;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!allDisabledWindows.Compare(input, matches))
|
||||||
|
break;
|
||||||
|
|
||||||
|
TimingWindow tw;
|
||||||
|
bool ret = StringConversion::FromString(matches[0].MakeUpper(), tw);
|
||||||
|
if (ret && TW_W1 <= tw && tw <= TW_W5)
|
||||||
|
{
|
||||||
|
m_twDisabledWindows.set(tw);
|
||||||
|
}
|
||||||
|
input = matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
// deprecated mods/left in for compatibility
|
// deprecated mods/left in for compatibility
|
||||||
else if( sBit == "converge" ) SET_FLOAT( fScrolls[SCROLL_CENTERED] )
|
else if( sBit == "converge" ) SET_FLOAT( fScrolls[SCROLL_CENTERED] )
|
||||||
// end of the list
|
// end of the list
|
||||||
@@ -1395,6 +1438,7 @@ bool PlayerOptions::operator==( const PlayerOptions &other ) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
COMPARE(m_fVisualDelay);
|
COMPARE(m_fVisualDelay);
|
||||||
|
COMPARE(m_twDisabledWindows); // != is defined correctly for ordered sets.
|
||||||
for( int i = 0; i < PlayerOptions::NUM_ACCELS; ++i )
|
for( int i = 0; i < PlayerOptions::NUM_ACCELS; ++i )
|
||||||
COMPARE(m_fAccels[i]);
|
COMPARE(m_fAccels[i]);
|
||||||
for( int i = 0; i < PlayerOptions::NUM_EFFECTS; ++i )
|
for( int i = 0; i < PlayerOptions::NUM_EFFECTS; ++i )
|
||||||
@@ -1461,6 +1505,7 @@ PlayerOptions& PlayerOptions::operator=(PlayerOptions const& other)
|
|||||||
CPY(m_bZBuffer);
|
CPY(m_bZBuffer);
|
||||||
CPY(m_bCosecant);
|
CPY(m_bCosecant);
|
||||||
CPY(m_fVisualDelay);
|
CPY(m_fVisualDelay);
|
||||||
|
CPY(m_twDisabledWindows);
|
||||||
CPY_SPEED(fDark);
|
CPY_SPEED(fDark);
|
||||||
CPY_SPEED(fBlind);
|
CPY_SPEED(fBlind);
|
||||||
CPY_SPEED(fCover);
|
CPY_SPEED(fCover);
|
||||||
@@ -1693,6 +1738,7 @@ RString PlayerOptions::GetSavedPrefsString() const
|
|||||||
SAVE( m_bMuteOnError );
|
SAVE( m_bMuteOnError );
|
||||||
SAVE( m_sNoteSkin );
|
SAVE( m_sNoteSkin );
|
||||||
SAVE( m_fVisualDelay );
|
SAVE( m_fVisualDelay );
|
||||||
|
SAVE( m_twDisabledWindows );
|
||||||
#undef SAVE
|
#undef SAVE
|
||||||
return po_prefs.GetString();
|
return po_prefs.GetString();
|
||||||
}
|
}
|
||||||
@@ -1741,6 +1787,7 @@ void PlayerOptions::ResetPrefs( ResetPrefsType type )
|
|||||||
// Don't clear this.
|
// Don't clear this.
|
||||||
// CPY( m_sNoteSkin );
|
// CPY( m_sNoteSkin );
|
||||||
CPY(m_fVisualDelay);
|
CPY(m_fVisualDelay);
|
||||||
|
CPY(m_twDisabledWindows);
|
||||||
#undef CPY
|
#undef CPY
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1991,6 +2038,41 @@ public:
|
|||||||
|
|
||||||
FLOAT_NO_SPEED_INTERFACE(VisualDelay, VisualDelay, true);
|
FLOAT_NO_SPEED_INTERFACE(VisualDelay, VisualDelay, true);
|
||||||
|
|
||||||
|
static int DisableTimingWindow(T* p, lua_State* L)
|
||||||
|
{
|
||||||
|
int original_top= lua_gettop(L);
|
||||||
|
if (original_top >= 1 && !lua_isnil(L, 1))
|
||||||
|
{
|
||||||
|
// Insert the specified TimingWindow into the disabled windows set.
|
||||||
|
p->m_twDisabledWindows.set(Enum::Check<TimingWindow>(L, 1));
|
||||||
|
}
|
||||||
|
OPTIONAL_RETURN_SELF(original_top);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ResetDisabledTimingWindows(T* p, lua_State* L)
|
||||||
|
{
|
||||||
|
int original_top= lua_gettop(L);
|
||||||
|
p->m_twDisabledWindows.reset();
|
||||||
|
OPTIONAL_RETURN_SELF(original_top);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetDisabledTimingWindows(T* p, lua_State* L)
|
||||||
|
{
|
||||||
|
int original_top= lua_gettop(L);
|
||||||
|
lua_newtable( L );
|
||||||
|
int j = 0;
|
||||||
|
for (int i=TW_W1; i != TW_W5; ++i) {
|
||||||
|
if (p->m_twDisabledWindows[i]) {
|
||||||
|
Enum::Push(L, static_cast<TimingWindow>(i));
|
||||||
|
lua_rawseti( L, -2, j+1 );
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// NoteSkins
|
// NoteSkins
|
||||||
static int NoteSkin(T* p, lua_State* L)
|
static int NoteSkin(T* p, lua_State* L)
|
||||||
{
|
{
|
||||||
@@ -2509,12 +2591,15 @@ public:
|
|||||||
ADD_MULTICOL_METHOD(Bumpy);
|
ADD_MULTICOL_METHOD(Bumpy);
|
||||||
ADD_MULTICOL_METHOD(Reverse);
|
ADD_MULTICOL_METHOD(Reverse);
|
||||||
|
|
||||||
|
|
||||||
ADD_METHOD(NoteSkin);
|
ADD_METHOD(NoteSkin);
|
||||||
ADD_METHOD(FailSetting);
|
ADD_METHOD(FailSetting);
|
||||||
ADD_METHOD(MinTNSToHideNotes);
|
ADD_METHOD(MinTNSToHideNotes);
|
||||||
ADD_METHOD(VisualDelay);
|
ADD_METHOD(VisualDelay);
|
||||||
|
|
||||||
|
ADD_METHOD(DisableTimingWindow);
|
||||||
|
ADD_METHOD(ResetDisabledTimingWindows);
|
||||||
|
ADD_METHOD(GetDisabledTimingWindows);
|
||||||
|
|
||||||
// Speed
|
// Speed
|
||||||
ADD_METHOD( CMod );
|
ADD_METHOD( CMod );
|
||||||
ADD_METHOD( XMod );
|
ADD_METHOD( XMod );
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ struct lua_State;
|
|||||||
|
|
||||||
#define ONE( arr ) { for( unsigned Z = 0; Z < ARRAYLEN(arr); ++Z ) arr[Z]=1.0f; }
|
#define ONE( arr ) { for( unsigned Z = 0; Z < ARRAYLEN(arr); ++Z ) arr[Z]=1.0f; }
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
#include "PlayerNumber.h"
|
#include "PlayerNumber.h"
|
||||||
#include "PrefsManager.h"
|
#include "PrefsManager.h"
|
||||||
@@ -398,6 +400,11 @@ public:
|
|||||||
/** @brief The Visual Delay additionally applied on a per-player basis in ms. */
|
/** @brief The Visual Delay additionally applied on a per-player basis in ms. */
|
||||||
float m_fVisualDelay;
|
float m_fVisualDelay;
|
||||||
|
|
||||||
|
/** @brief The TimingWindow that can be disabled.
|
||||||
|
* Valid values are only W1-W5 which map to indices 0-5 respectively.
|
||||||
|
* Other values are ignored. */
|
||||||
|
std::bitset<5> m_twDisabledWindows;
|
||||||
|
|
||||||
void NextAccel();
|
void NextAccel();
|
||||||
void NextEffect();
|
void NextEffect();
|
||||||
void NextAppearance();
|
void NextAppearance();
|
||||||
|
|||||||
Reference in New Issue
Block a user