//Kimimaru: Think of a faster way to do this; it's rather slow //The idea is to look through and see the inputs that would be held at the same time and avoid the given combo //One list is for held inputs with another for pressed inputs - the sum of their counts is compared with the invalid combo list's count //Released inputs do not count public static bool ValidateButtonCombos(List <List <Parser.Input> > inputs, List <string> invalidCombo) { int controllerCount = InputGlobals.ControllerMngr.ControllerCount; //These dictionaries are for each controller port Dictionary <int, List <string> > currentComboDict = new Dictionary <int, List <string> >(controllerCount); Dictionary <int, List <string> > subComboDict = new Dictionary <int, List <string> >(controllerCount); for (int i = 0; i < controllerCount; i++) { IVirtualController controller = InputGlobals.ControllerMngr.GetController(i); if (controller.IsAcquired == false) { continue; } //Add already pressed inputs from all controllers for (int j = 0; j < invalidCombo.Count; j++) { string button = invalidCombo[j]; if (controller.GetButtonState(InputGlobals.CurrentConsole.ButtonInputMap[button]) == ButtonStates.Pressed) { if (currentComboDict.ContainsKey(i) == false) { currentComboDict[i] = new List <string>(invalidCombo.Count); } currentComboDict[i].Add(button); } } } //If all these inputs are somehow pressed already, whatever we do now doesn't matter //However, returning false here would prevent any further inputs from working, so //give a chance to check other inputs (such as releasing) for (int i = 0; i < inputs.Count; i++) { List <Parser.Input> inputList = inputs[i]; //Clear sublists foreach (List <string> subList in subComboDict.Values) { subList.Clear(); } for (int j = 0; j < inputList.Count; j++) { Parser.Input input = inputList[j]; //Get controller port and initialize int port = input.controllerPort; //Ensure a currentcombo entry is available for this port if (currentComboDict.ContainsKey(port) == false) { currentComboDict[port] = new List <string>(invalidCombo.Count); } //Ensure a subcombo entry is available for this port if (subComboDict.ContainsKey(port) == false) { subComboDict[port] = new List <string>(invalidCombo.Count); } //Current and sub combo lists List <string> currentCombo = currentComboDict[port]; List <string> subCombo = subComboDict[port]; //Check if this input is in the invalid combo if (invalidCombo.Contains(input.name) == true) { //If it's not a release input and isn't in the held or current inputs, add it if (input.release == false && subCombo.Contains(input.name) == false && currentCombo.Contains(input.name) == false) { subCombo.Add(input.name); //Check the count after adding if ((subCombo.Count + currentCombo.Count) == invalidCombo.Count) { return(false); } } //For holds, use the held combo if (input.hold == true) { if (currentCombo.Contains(input.name) == false) { //Remove from the subcombo to avoid duplicates currentCombo.Add(input.name); subCombo.Remove(input.name); if ((currentCombo.Count + subCombo.Count) == invalidCombo.Count) { return(false); } } } //If released, remove from the current combo else if (input.release == true) { currentCombo.Remove(input.name); } } } } return(true); }