Skip to content

Commit

Permalink
Make chart length have to be matched even in a non-exclusive filter
Browse files Browse the repository at this point in the history
No-one really wants the meaning of "Find a chart with 10-12 Technical,
 or 12-14 Jackspeed, or 120-140 seconds in duration".
The chart length range should always be required to be matched when set.

Additionally, this commit lightly changes some other filter workings in
 preperation for adding in max chart clear % filterability.
  • Loading branch information
bluebandit21 committed Dec 30, 2020
1 parent 08474fd commit 6db8dc3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 21 deletions.
46 changes: 30 additions & 16 deletions src/Etterna/Models/Songs/Song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1730,22 +1730,27 @@ Song::MatchesFilter(const float rate,
bool
Song::ChartMatchesFilter(Steps* chart, float rate) const
{
auto addchart = FILTERMAN->ExclusiveFilter;

// TODO: ADD CHECKS FOR CLEAR %
auto matches_skills = FILTERMAN->ExclusiveFilter;
/* The default behaviour of an exclusive filter is to accept
* by default, (i.e. addsong=true) and reject if any
* by default, (i.e. matches_skills=true) and reject if any skill
* filters fail. The default behaviour of a non-exclusive filter is
* the exact opposite: reject by default (i.e.
* addsong=false), and accept if any filters match.
* matches_skills=false), and accept if any skill filters match.
*/

for (auto ss = 0; ss < NUM_Skillset + 1; ss++) {
// Iterate over all skillsets, up to and
// including the placeholder NUM_Skillset
for (auto ss = 0; ss < NUM_Skillset + 2; ss++) {
/* Iterate over all skillsets, as well as
* two placeholders for song length and best clear %
*/
const auto lb = FILTERMAN->SSFilterLowerBounds[ss];
const auto ub = FILTERMAN->SSFilterUpperBounds[ss];
if (lb > 0.F || ub > 0.F) { // If either bound is active, continue
if (!FILTERMAN->ExclusiveFilter) { // Non-Exclusive filter
if (!FILTERMAN->ExclusiveFilter) {
/* Non-Exclusive filter
* (It doesn't make sense for either to trigger on exclusive
* filters, as it would have to be true for *all* skillsets)
*/
if (FILTERMAN->HighestSkillsetsOnly && ss < NUM_Skillset) {
if (!chart->IsSkillsetHighestOfChart(
static_cast<Skillset>(ss), rate)) {
Expand All @@ -1765,33 +1770,41 @@ Song::ChartMatchesFilter(Steps* chart, float rate) const
float val;
if (ss < NUM_Skillset) {
val = chart->GetMSD(rate, ss);
} else {
// If we are on the placeholder skillset, look at song
} else if (ss == NUM_Skillset) {
// If we are on the first placeholder skillset, look at chart
// length instead of a skill
val = chart->GetLengthSeconds(rate);
} else { // ss == NUM_Skillset + 1
// If we are on the second placeholder skillset, look at best
// clear percent instead of a skill
// TODO: ADD IN MAGIC "GET BEST CLEAR% VALUE HERE"
continue; // Unimplemented
}
if (FILTERMAN->ExclusiveFilter) {
/* Our behaviour is to accept by default,
* but reject if any filters don't match.*/
if ((val < lb && lb > 0.F) || (val > ub && ub > 0.F)) {
/* If we're below the lower bound and it's set,
* or above the upper bound and it's set*/
addchart = false;
break;
matches_skills = false;
break; // We've already failed
}
} else { // Non-Exclusive Filter
/* Our behaviour is to reject by default,
* but accept if any filters match.*/
if ((val > lb || !(lb > 0.F)) && (val < ub || !(ub > 0.F))) {
/* If we're above the lower bound or it's not set
* and also below the upper bound or it isn't set*/
addchart = true;
break;
matches_skills = true;
} else if ((ss == NUM_Skillset) || (ss == NUM_Skillset + 1)) {
// This is an always-required filter,
// but we didn't match it.
return false;
}
}
}
}
return addchart;
return matches_skills;
}

bool
Expand Down Expand Up @@ -2419,7 +2432,8 @@ class LunaSong : public Luna<Song>
}
static int GetHighestGrade(T* p, lua_State* L)
{
// this shadows (and essentially doesnt even do remotely the same thing as) the MusicWheelItem best grade thing for the item grades
// this shadows (and essentially doesnt even do remotely the same thing
// as) the MusicWheelItem best grade thing for the item grades
auto charts = p->GetChartsMatchingFilter();

Grade best = Grade_Invalid;
Expand Down
7 changes: 4 additions & 3 deletions src/Etterna/Singletons/FilterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ FilterManager::SetSSFilter(float v, Skillset ss, int bound)
void
FilterManager::ResetSSFilters()
{
for (int ss = 0; ss < NUM_Skillset + 1; ss++) {
for (int ss = 0; ss < NUM_Skillset + 2; ss++) {
// Skillsets + 2 other values (time, clear %)
SSFilterLowerBounds[ss] = 0;
SSFilterUpperBounds[ss] = 0;
}
Expand All @@ -65,7 +66,6 @@ FilterManager::ResetAllFilters()
ExclusiveFilter = false;
HighestSkillsetsOnly = false;
HighestDifficultyOnly = false;

MinFilterRate = 1.F;
MaxFilterRate = 1.F;
}
Expand All @@ -74,7 +74,8 @@ FilterManager::ResetAllFilters()
bool
FilterManager::AnyActiveFilter()
{
for (int ss = 0; ss < NUM_Skillset + 1; ss++) {
for (int ss = 0; ss < NUM_Skillset + 2; ss++) {
// Skillsets + 2 other values (time, clear %)
if (SSFilterLowerBounds[ss] > 0)
return true;
if (SSFilterUpperBounds[ss] > 0)
Expand Down
15 changes: 13 additions & 2 deletions src/Etterna/Singletons/FilterManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,19 @@ class FilterManager

PlayerState* m_pPlayerState;

float SSFilterLowerBounds[NUM_Skillset + 1];
float SSFilterUpperBounds[NUM_Skillset + 1];
float SSFilterLowerBounds[NUM_Skillset + 2] = { 0 }; // Zero-initialize
float SSFilterUpperBounds[NUM_Skillset + 2] = { 0 }; // Zero-initialize
/* Skill_Overall,
* Skill_Stream,
* Skill_Jumpstream,
* Skill_Handstream,
* Skill_Stamina,
* Skill_JackSpeed,
* Skill_Chordjack,
* Skill_Technical,
* Length, //REQUIRED in non-exclusive filter if set
* Clear % //REQUIRED in non-exclusive filter if set
*/
float MaxFilterRate = 1.F;
float MinFilterRate = 1.F;
bool ExclusiveFilter = false; // if true the filter system will only match
Expand Down

0 comments on commit 6db8dc3

Please sign in to comment.