Use bitset instead of map and adjust files accordingly.

This commit is contained in:
teejusb
2021-12-21 23:44:37 -08:00
parent 2967165235
commit 99ee1f2b84
7 changed files with 109 additions and 83 deletions
+4
View File
@@ -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'/>
+16
View File
@@ -3915,6 +3915,11 @@ 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='{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'> <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 +3965,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 +4073,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 +4176,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>
+1
View File
@@ -284,6 +284,7 @@ static const char *TimingWindowNames[] = {
}; };
XToString( TimingWindow ); XToString( TimingWindow );
LuaXType( TimingWindow ); LuaXType( TimingWindow );
StringToX( TimingWindow );
static const char *ScoreEventNames[] = { static const char *ScoreEventNames[] = {
"CheckpointHit", "CheckpointHit",
+16 -32
View File
@@ -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:
@@ -1003,15 +1003,15 @@ void Player::Update( float fDeltaTime )
{ {
float largestWindow = 0.0f; float largestWindow = 0.0f;
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows; 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)); largestWindow = max(largestWindow, GetWindowSeconds(TW_W1));
if (disabledWindows.find(TW_W2) == disabledWindows.end()) if (!disabledWindows[TW_W2])
largestWindow = max(largestWindow, GetWindowSeconds(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)); largestWindow = max(largestWindow, GetWindowSeconds(TW_W3));
if (disabledWindows.find(TW_W4) == disabledWindows.end()) if (!disabledWindows[TW_W4])
largestWindow = max(largestWindow, GetWindowSeconds(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)); 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
@@ -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. // Set it to the first non-disabled window.
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows; const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
if (disabledWindows.find(TW_W1) == disabledWindows.end()) if (!disabledWindows[TW_W1])
score = TNS_W1; score = TNS_W1;
else if (disabledWindows.find(TW_W2) == disabledWindows.end()) else if (!disabledWindows[TW_W2])
score = TNS_W2; score = TNS_W2;
else if (disabledWindows.find(TW_W3) == disabledWindows.end()) else if (!disabledWindows[TW_W3])
score = TNS_W3; score = TNS_W3;
else if (disabledWindows.find(TW_W4) == disabledWindows.end()) else if (!disabledWindows[TW_W4])
score = TNS_W4; score = TNS_W4;
else if (disabledWindows.find(TW_W5) == disabledWindows.end()) else if (!disabledWindows[TW_W5])
score = TNS_W5; score = TNS_W5;
break; 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 ) if( (pTN->type == TapNoteType_Lift) == bRelease )
{ {
const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows; const auto &disabledWindows = m_pPlayerState->m_PlayerOptions.GetCurrent().m_twDisabledWindows;
if( fSecondsFromExact <= GetWindowSeconds(TW_W1) && disabledWindows.find(TW_W1) == disabledWindows.end()) score = TNS_W1; if( fSecondsFromExact <= GetWindowSeconds(TW_W1) && !disabledWindows[TW_W1] ) score = TNS_W1;
else if( fSecondsFromExact <= GetWindowSeconds(TW_W2) && disabledWindows.find(TW_W2) == disabledWindows.end()) score = TNS_W2; else if( fSecondsFromExact <= GetWindowSeconds(TW_W2) && !disabledWindows[TW_W2] ) score = TNS_W2;
else if( fSecondsFromExact <= GetWindowSeconds(TW_W3) && disabledWindows.find(TW_W3) == disabledWindows.end()) score = TNS_W3; else if( fSecondsFromExact <= GetWindowSeconds(TW_W3) && !disabledWindows[TW_W3] ) score = TNS_W3;
else if( fSecondsFromExact <= GetWindowSeconds(TW_W4) && disabledWindows.find(TW_W4) == disabledWindows.end()) score = TNS_W4; else if( fSecondsFromExact <= GetWindowSeconds(TW_W4) && !disabledWindows[TW_W4] ) score = TNS_W4;
else if( fSecondsFromExact <= GetWindowSeconds(TW_W5) && disabledWindows.find(TW_W5) == disabledWindows.end()) score = TNS_W5; else if( fSecondsFromExact <= GetWindowSeconds(TW_W5) && !disabledWindows[TW_W5] ) score = TNS_W5;
} }
break; break;
} }
@@ -2304,22 +2304,6 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele
case PC_AUTOPLAY: case PC_AUTOPLAY:
{ {
score = PlayerAI::GetTapNoteScore(m_pPlayerState); 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. /* XXX: This doesn't make sense.
* Step should only be called in autoplay for hit notes. */ * Step should only be called in autoplay for hit notes. */
+19 -1
View File
@@ -141,7 +141,25 @@ 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;
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;
} }
/* /*
+30 -26
View File
@@ -97,7 +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.clear(); 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 );
@@ -568,14 +568,19 @@ void PlayerOptions::GetMods( vector<RString> &AddTo, bool bForceNoteSkin ) const
AddTo.push_back( ssprintf("%.0fms VisualDelay", m_fVisualDelay * 1000.0f) ); AddTo.push_back( ssprintf("%.0fms VisualDelay", m_fVisualDelay * 1000.0f) );
} }
if (!m_twDisabledWindows.empty()) { if (m_twDisabledWindows.count() != 0) {
std::stringstream ss; std::stringstream ss;
bool is_first = true;
ss << "No "; ss << "No ";
for (auto it=m_twDisabledWindows.begin(); it != m_twDisabledWindows.end(); ++it) { for (int i=TW_W1; i != TW_W5; ++i) {
if (it != m_twDisabledWindows.begin()) { if (m_twDisabledWindows[i]) {
if (!is_first) {
ss << "/"; 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" // 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( sBit == "visualdelay" ) m_fVisualDelay = level;
else if( level == 0 && disabledWindows.Compare(sBit)) // "No w1" etc. 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. // 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. // To get all of the windows, we go through in a loop to extract all of them.
static Regex allDisabledWindows("(w[1-5])(.*)$"); static Regex allDisabledWindows("(w[1-5])(.*)$");
@@ -1178,9 +1176,11 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut
if (!allDisabledWindows.Compare(input, matches)) if (!allDisabledWindows.Compare(input, matches))
break; 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]; input = matches[1];
} }
@@ -2044,13 +2044,17 @@ public:
if (original_top >= 1 && !lua_isnil(L, 1)) if (original_top >= 1 && !lua_isnil(L, 1))
{ {
// Insert the specified TimingWindow into the disabled windows set. // 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. // Construct a new table indicating all of the disabled windows.
lua_newtable( L ); lua_newtable( L );
for (TimingWindow window : p->m_twDisabledWindows) int j = 0;
{ for (int i=TW_W1; i != TW_W5; ++i) {
Enum::Push(L, window); if (p->m_twDisabledWindows[i]) {
Enum::Push(L, static_cast<TimingWindow>(i));
lua_rawseti( L, -2, j+1 );
++j;
}
} }
OPTIONAL_RETURN_SELF(original_top); OPTIONAL_RETURN_SELF(original_top);
return 1; return 1;
@@ -2059,7 +2063,7 @@ public:
static int ResetDisabledTimingWindows(T* p, lua_State* L) static int ResetDisabledTimingWindows(T* p, lua_State* L)
{ {
int original_top= lua_gettop(L); int original_top= lua_gettop(L);
p->m_twDisabledWindows.clear(); p->m_twDisabledWindows.reset();
OPTIONAL_RETURN_SELF(original_top); OPTIONAL_RETURN_SELF(original_top);
return 1; return 1;
} }
@@ -2068,14 +2072,14 @@ public:
{ {
int original_top= lua_gettop(L); int original_top= lua_gettop(L);
lua_newtable( L ); lua_newtable( L );
int i = 0; int j = 0;
for (TimingWindow window : p->m_twDisabledWindows) for (int i=TW_W1; i != TW_W5; ++i) {
{ if (p->m_twDisabledWindows[i]) {
Enum::Push(L, window); Enum::Push(L, static_cast<TimingWindow>(i));
lua_rawseti( L, -2, i+1 ); lua_rawseti( L, -2, j+1 );
++i; ++j;
}
} }
OPTIONAL_RETURN_SELF(original_top);
return 1; return 1;
} }
+5 -6
View File
@@ -9,7 +9,7 @@ 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 <set> #include <bitset>
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
#include "PlayerNumber.h" #include "PlayerNumber.h"
@@ -400,11 +400,10 @@ 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. /** @brief The TimingWindow that can be disabled.
* Other values are ignore. * Valid values are only W1-W5 which map to indices 0-5 respectively.
* We use a set instead of unordered_set because we want the ordering so that * Other values are ignored. */
* the generated player options string is consistent. */ std::bitset<5> m_twDisabledWindows;
std::set<TimingWindow> m_twDisabledWindows;
void NextAccel(); void NextAccel();
void NextEffect(); void NextEffect();