diff --git a/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs b/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs index 8c6efbc72d..de5b7c4d2f 100644 --- a/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs +++ b/osu.Game.Rulesets.Mania/ManiaFilterCriteria.cs @@ -17,20 +17,50 @@ namespace osu.Game.Rulesets.Mania { public class ManiaFilterCriteria : IRulesetFilterCriteria { - private FilterCriteria.OptionalRange keys; - + private FilterCriteria.OptionalRange included_key_range; + private HashSet included_keys = new HashSet(); + private HashSet excluded_keys = new HashSet(); public bool Matches(BeatmapInfo beatmapInfo, FilterCriteria criteria) { - return !keys.HasFilter || keys.IsInRange(ManiaBeatmapConverter.GetColumnCount(LegacyBeatmapConversionDifficultyInfo.FromBeatmapInfo(beatmapInfo), criteria.Mods)); + bool result = (!included_key_range.HasFilter) && (included_keys.Count == 0); + int key_index = ManiaBeatmapConverter.GetColumnCount(LegacyBeatmapConversionDifficultyInfo.FromBeatmapInfo(beatmapInfo), criteria.Mods); + + result |= (included_key_range.HasFilter && included_key_range.IsInRange(key_index)) || included_keys.Contains(key_index); + result &= !excluded_keys.Contains(key_index); + + return result; } - public bool TryParseCustomKeywordCriteria(string key, Operator op, string value) + public bool TryParseCustomKeywordCriteria(string key, Operator op, string str_values) { switch (key) { case "key": case "keys": - return FilterQueryParser.TryUpdateCriteriaRange(ref keys, op, value); + if (op == Operator.Equal) + { + foreach (string str_value in str_values.Split(',')) + { + if (int.TryParse(str_value, out int value)) + { + if (value > 0) + { + included_keys.Add(value); + } + else + { + excluded_keys.Add(-value); + } + } + } + + return true; + } + else + { + // In this case, the str_values is a string of a single value + return FilterQueryParser.TryUpdateCriteriaRange(ref included_key_range, op, str_values); + } } return false; @@ -38,7 +68,7 @@ namespace osu.Game.Rulesets.Mania public bool FilterMayChangeFromMods(ValueChangedEvent> mods) { - if (keys.HasFilter) + if (included_key_range.HasFilter || included_keys.Count != 0 || excluded_keys.Count != 0) { // Interpreting as the Mod type is required for equality comparison. HashSet oldSet = mods.OldValue.OfType().AsEnumerable().ToHashSet();