Use bitset instead of map and adjust files accordingly.
This commit is contained in:
@@ -1248,6 +1248,7 @@
|
||||
<Function name='DigitalZSteps'/>
|
||||
<Function name='Dizzy'/>
|
||||
<Function name='DizzyHolds'/>
|
||||
<Function name='DisableTimingWindow'/>
|
||||
<Function name='Distant'/>
|
||||
<Function name='DrainSetting'/>
|
||||
<Function name='DrawSize'/>
|
||||
@@ -1267,6 +1268,7 @@
|
||||
<Function name='Flip'/>
|
||||
<Function name='Floored'/>
|
||||
<Function name='FromString'/>
|
||||
<Function name='GetDisabledTimingWindows'/>
|
||||
<Function name='GetReversePercentForColumn'/>
|
||||
<Function name='GetStepAttacks'/>
|
||||
<Function name='IsEasierForSongAndSteps'/>
|
||||
@@ -1319,6 +1321,7 @@
|
||||
<Function name='RandAttack'/>
|
||||
<Function name='RandomSpeed'/>
|
||||
<Function name='RandomVanish'/>
|
||||
<Function name='ResetDisabledTimingWindows'/>
|
||||
<Function name='Reverse'/>
|
||||
<Function name='Reversen'/>
|
||||
<Function name='Right'/>
|
||||
@@ -1368,6 +1371,7 @@
|
||||
<Function name='Twirl'/>
|
||||
<Function name='Twister'/>
|
||||
<Function name='UsingReverse'/>
|
||||
<Function name='VisualDelay'/>
|
||||
<Function name='Wave'/>
|
||||
<Function name='WavePeriod'/>
|
||||
<Function name='Wide'/>
|
||||
|
||||
@@ -3915,6 +3915,11 @@ a,b = options:Boost(5)
|
||||
</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='DisableTimingWindow' return='{TimingWindow}' 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. <br />
|
||||
Returns a table of <code>TimingWindow</code> with the set of disabled windows after the function call.
|
||||
</Function>
|
||||
<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 />
|
||||
Returns nil otherwise.<br />
|
||||
@@ -3960,6 +3965,9 @@ a,b = options:Boost(5)
|
||||
</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='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=''>
|
||||
Returns true if step attacks or random attacks are enabled.
|
||||
</Function>
|
||||
@@ -4065,6 +4073,9 @@ prev_note_name, succeeded = options:NoteSkin("cel")
|
||||
<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='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='Reversen' return= 'float, float' arguments='float value, float approach_speed'>
|
||||
Use 1-16 in place of 'n' to apply Reverse on a specific column.
|
||||
@@ -4165,6 +4176,11 @@ prev_note_name, succeeded = options:NoteSkin("cel")
|
||||
<Function name='UsingReverse' return='bool' arguments=''>
|
||||
Returns <code>true</code> if the player is using reverse. (equivalent to <code>GetReverse() == 1.0</code>)
|
||||
</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='WavePeriod' return='float, float' arguments='float value, float approach_speed'> </Function>
|
||||
<Function name='Wide' return='bool' arguments='bool value'> </Function>
|
||||
|
||||
@@ -284,6 +284,7 @@ static const char *TimingWindowNames[] = {
|
||||
};
|
||||
XToString( TimingWindow );
|
||||
LuaXType( TimingWindow );
|
||||
StringToX( TimingWindow );
|
||||
|
||||
static const char *ScoreEventNames[] = {
|
||||
"CheckpointHit",
|
||||
|
||||
+33
-49
@@ -104,7 +104,7 @@ static const float StepSearchDistance = 1.0f;
|
||||
|
||||
void TimingWindowSecondsInit( size_t /*TimingWindow*/ i, RString &sNameOut, float &defaultValueOut )
|
||||
{
|
||||
sNameOut = "TimingWindowSeconds" + TimingWindowToString( (TimingWindow)i );
|
||||
sNameOut = "TimingWindowSeconds" + TimingWindowToString( static_cast<TimingWindow>(i) );
|
||||
switch( i )
|
||||
{
|
||||
case TW_W1:
|
||||
@@ -1003,15 +1003,15 @@ void Player::Update( float fDeltaTime )
|
||||
{
|
||||
float largestWindow = 0.0f;
|
||||
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||
if (disabledWindows.find(TW_W1) == disabledWindows.end())
|
||||
if (!disabledWindows[TW_W1])
|
||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W1));
|
||||
if (disabledWindows.find(TW_W2) == disabledWindows.end())
|
||||
if (!disabledWindows[TW_W2])
|
||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W2));
|
||||
if (disabledWindows.find(TW_W3) == disabledWindows.end())
|
||||
if (!disabledWindows[TW_W3])
|
||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W3));
|
||||
if (disabledWindows.find(TW_W4) == disabledWindows.end())
|
||||
if (!disabledWindows[TW_W4])
|
||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W4));
|
||||
if (disabledWindows.find(TW_W5) == disabledWindows.end())
|
||||
if (!disabledWindows[TW_W5])
|
||||
largestWindow = max(largestWindow, GetWindowSeconds(TW_W5));
|
||||
|
||||
// We have to check the unjudged notes that are within the
|
||||
@@ -2272,15 +2272,15 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
||||
{
|
||||
// Set it to the first non-disabled window.
|
||||
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||
if (disabledWindows.find(TW_W1) == disabledWindows.end())
|
||||
if (!disabledWindows[TW_W1])
|
||||
score = TNS_W1;
|
||||
else if (disabledWindows.find(TW_W2) == disabledWindows.end())
|
||||
else if (!disabledWindows[TW_W2])
|
||||
score = TNS_W2;
|
||||
else if (disabledWindows.find(TW_W3) == disabledWindows.end())
|
||||
else if (!disabledWindows[TW_W3])
|
||||
score = TNS_W3;
|
||||
else if (disabledWindows.find(TW_W4) == disabledWindows.end())
|
||||
else if (!disabledWindows[TW_W4])
|
||||
score = TNS_W4;
|
||||
else if (disabledWindows.find(TW_W5) == disabledWindows.end())
|
||||
else if (!disabledWindows[TW_W5])
|
||||
score = TNS_W5;
|
||||
|
||||
break;
|
||||
@@ -2290,11 +2290,11 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
||||
if( (pTN->type == TapNoteType_Lift) == bRelease )
|
||||
{
|
||||
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||
if( fSecondsFromExact <= GetWindowSeconds(TW_W1) && disabledWindows.find(TW_W1) == disabledWindows.end()) score = TNS_W1;
|
||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W2) && disabledWindows.find(TW_W2) == disabledWindows.end()) score = TNS_W2;
|
||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W3) && disabledWindows.find(TW_W3) == disabledWindows.end()) score = TNS_W3;
|
||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W4) && disabledWindows.find(TW_W4) == disabledWindows.end()) score = TNS_W4;
|
||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W5) && disabledWindows.find(TW_W5) == disabledWindows.end()) score = TNS_W5;
|
||||
if( fSecondsFromExact <= GetWindowSeconds(TW_W1) && !disabledWindows[TW_W1] ) score = TNS_W1;
|
||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W2) && !disabledWindows[TW_W2] ) score = TNS_W2;
|
||||
else if( fSecondsFromExact <= GetWindowSeconds(TW_W3) && !disabledWindows[TW_W3] ) score = TNS_W3;
|
||||
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;
|
||||
}
|
||||
@@ -2304,30 +2304,14 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
||||
case PC_AUTOPLAY:
|
||||
{
|
||||
score = PlayerAI::GetTapNoteScore(m_pPlayerState);
|
||||
const auto& disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||
for (int i = score; i >= TNS_W5; i--)
|
||||
{
|
||||
TapNoteScore cur_score = (TapNoteScore)i;
|
||||
// Downgrade the TapNoteScore if that specific window is disabled.
|
||||
if (cur_score == TNS_W1 && disabledWindows.find(TW_W1) == disabledWindows.end())
|
||||
score = TNS_W2;
|
||||
else if (cur_score == TNS_W2 && disabledWindows.find(TW_W2) == disabledWindows.end())
|
||||
score = TNS_W3;
|
||||
else if (cur_score == TNS_W3 && disabledWindows.find(TW_W3) == disabledWindows.end())
|
||||
score = TNS_W4;
|
||||
else if (cur_score == TNS_W4 && disabledWindows.find(TW_W4) == disabledWindows.end())
|
||||
score = TNS_W5;
|
||||
else if (cur_score == TNS_W5 && disabledWindows.find(TW_W5) == disabledWindows.end())
|
||||
score = TNS_None;
|
||||
}
|
||||
|
||||
/* XXX: This doesn't make sense.
|
||||
* Step should only be called in autoplay for hit notes. */
|
||||
#if 0
|
||||
// GetTapNoteScore always returns TNS_W1 in autoplay.
|
||||
// If the step is far away, don't judge it.
|
||||
if (m_pPlayerState->m_PlayerController == PC_AUTOPLAY &&
|
||||
fSecondsFromExact > GetWindowSeconds(TW_W5))
|
||||
// GetTapNoteScore always returns TNS_W1 in autoplay.
|
||||
// If the step is far away, don't judge it.
|
||||
if( m_pPlayerState->m_PlayerController == PC_AUTOPLAY &&
|
||||
fSecondsFromExact > GetWindowSeconds(TW_W5) )
|
||||
{
|
||||
score = TNS_None;
|
||||
break;
|
||||
@@ -2336,36 +2320,36 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
||||
|
||||
// TRICKY: We're asking the AI to judge mines. Consider TNS_W4 and
|
||||
// below as "mine was hit" and everything else as "mine was avoided"
|
||||
if (pTN->type == TapNoteType_Mine)
|
||||
if ( pTN->type == TapNoteType_Mine )
|
||||
{
|
||||
// The CPU hits a lot of mines. Only consider hitting the
|
||||
// first mine for a row. We know we're the first mine if
|
||||
// there are are no mines to the left of us.
|
||||
for (int t = 0; t < col; t++)
|
||||
for ( int t=0; t<col; t++ )
|
||||
{
|
||||
if (m_NoteData.GetTapNote(t, iRowOfOverlappingNoteOrRow).type == TapNoteType_Mine) // there's a mine to the left of us
|
||||
if( m_NoteData.GetTapNote(t, iRowOfOverlappingNoteOrRow).type == TapNoteType_Mine ) // there's a mine to the left of us
|
||||
return; // avoid
|
||||
}
|
||||
|
||||
// The CPU hits a lot of mines. Make it less likely to hit
|
||||
// mines that don't have a tap note on the same row.
|
||||
bool bTapsOnRow = m_NoteData.IsThereATapOrHoldHeadAtRow(iRowOfOverlappingNoteOrRow);
|
||||
bool bTapsOnRow = m_NoteData.IsThereATapOrHoldHeadAtRow( iRowOfOverlappingNoteOrRow );
|
||||
TapNoteScore get_to_avoid = bTapsOnRow ? TNS_W3 : TNS_W4;
|
||||
|
||||
if (score >= get_to_avoid)
|
||||
if (score >= get_to_avoid )
|
||||
return; // avoided
|
||||
else
|
||||
score = TNS_HitMine;
|
||||
}
|
||||
|
||||
if (pTN->type == TapNoteType_Attack && score > TNS_W4)
|
||||
if ( pTN->type == TapNoteType_Attack && score > TNS_W4 )
|
||||
score = TNS_W2; // sentinel
|
||||
|
||||
/* AI will generate misses here. Don't handle a miss like a regular
|
||||
* note because we want the judgment animation to appear delayed.
|
||||
* Instead, return early if AI generated a miss, and let
|
||||
* UpdateTapNotesMissedOlderThan() detect and handle the misses. */
|
||||
if (score == TNS_Miss)
|
||||
if ( score == TNS_Miss )
|
||||
return;
|
||||
|
||||
// Put some small, random amount in fNoteOffset so that demonstration
|
||||
@@ -2383,7 +2367,7 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
||||
float fWindowW5 = GetWindowSeconds(TW_W5);
|
||||
|
||||
// W1 is the top judgment, there is no overlap.
|
||||
if (score == TNS_W1)
|
||||
if ( score == TNS_W1 )
|
||||
fNoteOffset = randomf(-fWindowW1, fWindowW1);
|
||||
else
|
||||
{
|
||||
@@ -2391,25 +2375,25 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
||||
float fLowerBound = 0.0f; // negative upper limit
|
||||
float fUpperBound = 0.0f; // positive lower limit
|
||||
float fCompareWindow = 0.0f; // filled in here:
|
||||
if (score == TNS_W2)
|
||||
if ( score == TNS_W2 )
|
||||
{
|
||||
fLowerBound = -fWindowW1;
|
||||
fUpperBound = fWindowW1;
|
||||
fCompareWindow = fWindowW2;
|
||||
}
|
||||
else if (score == TNS_W3)
|
||||
else if ( score == TNS_W3 )
|
||||
{
|
||||
fLowerBound = -fWindowW2;
|
||||
fUpperBound = fWindowW2;
|
||||
fCompareWindow = fWindowW3;
|
||||
}
|
||||
else if (score == TNS_W4)
|
||||
else if ( score == TNS_W4 )
|
||||
{
|
||||
fLowerBound = -fWindowW3;
|
||||
fUpperBound = fWindowW3;
|
||||
fCompareWindow = fWindowW4;
|
||||
}
|
||||
else if (score == TNS_W5)
|
||||
else if ( score == TNS_W5 )
|
||||
{
|
||||
fLowerBound = -fWindowW4;
|
||||
fUpperBound = fWindowW4;
|
||||
@@ -2418,7 +2402,7 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
|
||||
float f1 = randomf(-fCompareWindow, fLowerBound);
|
||||
float f2 = randomf(fUpperBound, fCompareWindow);
|
||||
|
||||
if (randomf() * 100 >= 50)
|
||||
if(randomf() * 100 >= 50)
|
||||
fNoteOffset = f1;
|
||||
else
|
||||
fNoteOffset = f2;
|
||||
|
||||
+19
-1
@@ -141,7 +141,25 @@ TapNoteScore PlayerAI::GetTapNoteScore( const PlayerState* pPlayerState )
|
||||
|
||||
TapScoreDistribution& distribution = g_Distributions[iCpuSkill];
|
||||
|
||||
return distribution.GetTapNoteScore();
|
||||
TapNoteScore score = distribution.GetTapNoteScore();
|
||||
|
||||
const auto& disabledWindows = pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
|
||||
for (int i = score; i >= TNS_W5; i--)
|
||||
{
|
||||
TapNoteScore cur_score = (TapNoteScore)i;
|
||||
// Downgrade the TapNoteScore if that specific window is disabled.
|
||||
if (cur_score == TNS_W1 && disabledWindows[TW_W1])
|
||||
score = TNS_W2;
|
||||
if (cur_score == TNS_W2 && disabledWindows[TW_W2])
|
||||
score = TNS_W3;
|
||||
if (cur_score == TNS_W3 && disabledWindows[TW_W3])
|
||||
score = TNS_W4;
|
||||
if (cur_score == TNS_W4 && disabledWindows[TW_W4])
|
||||
score = TNS_W5;
|
||||
if (cur_score == TNS_W5 && disabledWindows[TW_W5])
|
||||
score = TNS_None;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+31
-27
@@ -97,7 +97,7 @@ void PlayerOptions::Init()
|
||||
m_bCosecant = false;
|
||||
m_sNoteSkin = "";
|
||||
m_fVisualDelay = 0.0f;
|
||||
m_twDisabledWindows.clear();
|
||||
m_twDisabledWindows.reset();
|
||||
ZERO( m_fMovesX ); ONE( m_SpeedfMovesX );
|
||||
ZERO( m_fMovesY ); ONE( m_SpeedfMovesY );
|
||||
ZERO( m_fMovesZ ); ONE( m_SpeedfMovesZ );
|
||||
@@ -568,14 +568,19 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
|
||||
AddTo.push_back( ssprintf("%.0fms VisualDelay", m_fVisualDelay * 1000.0f) );
|
||||
}
|
||||
|
||||
if (!m_twDisabledWindows.empty()) {
|
||||
if (m_twDisabledWindows.count() != 0) {
|
||||
std::stringstream ss;
|
||||
bool is_first = true;
|
||||
ss << "No ";
|
||||
for (auto it=m_twDisabledWindows.begin(); it != m_twDisabledWindows.end(); ++it) {
|
||||
if (it != m_twDisabledWindows.begin()) {
|
||||
ss << "/";
|
||||
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();
|
||||
}
|
||||
ss << TimingWindowToString(*it).c_str();
|
||||
}
|
||||
|
||||
// Final string will be something like "No W4/W5"
|
||||
@@ -1162,13 +1167,6 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
|
||||
else if( sBit == "visualdelay" ) m_fVisualDelay = level;
|
||||
else if( level == 0 && disabledWindows.Compare(sBit)) // "No w1" etc.
|
||||
{
|
||||
static std::map<RString, TimingWindow> nameToWindow = {
|
||||
{"w1", TW_W1},
|
||||
{"w2", TW_W2},
|
||||
{"w3", TW_W3},
|
||||
{"w4", TW_W4},
|
||||
{"w5", TW_W5},
|
||||
};
|
||||
// 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])(.*)$");
|
||||
@@ -1178,9 +1176,11 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
|
||||
if (!allDisabledWindows.Compare(input, matches))
|
||||
break;
|
||||
|
||||
if (nameToWindow.find(matches[0]) != nameToWindow.end())
|
||||
TimingWindow tw;
|
||||
bool ret = StringConversion::FromString(matches[0].MakeUpper(), tw);
|
||||
if (ret && TW_W1 <= tw && tw <= TW_W5)
|
||||
{
|
||||
m_twDisabledWindows.insert(nameToWindow[matches[0]]);
|
||||
m_twDisabledWindows.set(tw);
|
||||
}
|
||||
input = matches[1];
|
||||
}
|
||||
@@ -2044,13 +2044,17 @@ public:
|
||||
if (original_top >= 1 && !lua_isnil(L, 1))
|
||||
{
|
||||
// Insert the specified TimingWindow into the disabled windows set.
|
||||
p->m_twDisabledWindows.insert(Enum::Check<TimingWindow>(L, 1));
|
||||
p->m_twDisabledWindows.set(Enum::Check<TimingWindow>(L, 1));
|
||||
}
|
||||
// Construct a new table indicating all of the disabled windows.
|
||||
lua_newtable( L );
|
||||
for (TimingWindow window : p->m_twDisabledWindows)
|
||||
{
|
||||
Enum::Push(L, window);
|
||||
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;
|
||||
}
|
||||
}
|
||||
OPTIONAL_RETURN_SELF(original_top);
|
||||
return 1;
|
||||
@@ -2059,7 +2063,7 @@ public:
|
||||
static int ResetDisabledTimingWindows(T* p, lua_State* L)
|
||||
{
|
||||
int original_top= lua_gettop(L);
|
||||
p->m_twDisabledWindows.clear();
|
||||
p->m_twDisabledWindows.reset();
|
||||
OPTIONAL_RETURN_SELF(original_top);
|
||||
return 1;
|
||||
}
|
||||
@@ -2068,14 +2072,14 @@ public:
|
||||
{
|
||||
int original_top= lua_gettop(L);
|
||||
lua_newtable( L );
|
||||
int i = 0;
|
||||
for (TimingWindow window : p->m_twDisabledWindows)
|
||||
{
|
||||
Enum::Push(L, window);
|
||||
lua_rawseti( L, -2, i+1 );
|
||||
++i;
|
||||
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;
|
||||
}
|
||||
}
|
||||
OPTIONAL_RETURN_SELF(original_top);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -9,7 +9,7 @@ struct lua_State;
|
||||
|
||||
#define ONE( arr ) { for( unsigned Z = 0; Z < ARRAYLEN(arr); ++Z ) arr[Z]=1.0f; }
|
||||
|
||||
#include <set>
|
||||
#include <bitset>
|
||||
|
||||
#include "GameConstantsAndTypes.h"
|
||||
#include "PlayerNumber.h"
|
||||
@@ -400,11 +400,10 @@ public:
|
||||
/** @brief The Visual Delay additionally applied on a per-player basis in ms. */
|
||||
float m_fVisualDelay;
|
||||
|
||||
/** @brief The TimingWindow that can be disabled. Valid values are only W1-W5.
|
||||
* Other values are ignore.
|
||||
* We use a set instead of unordered_set because we want the ordering so that
|
||||
* the generated player options string is consistent. */
|
||||
std::set<TimingWindow> m_twDisabledWindows;
|
||||
/** @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 NextEffect();
|
||||
|
||||
Reference in New Issue
Block a user