public static int FindButton2Presses(InputBufferReader reader, Factory inputFactory, List <Combination> activeInputs) { int numFound = 0; reader.ResetCurrIndex(); bool butAPrev = true; bool butBPrev = true; bool butCPrev = true; bool butDPrev = true; bool butSPrev = true; while (reader.ReadyNext()) { int inputFrameIndex = reader.ReadBuffer(out GameInputStruct curr); FindSingleButtonPress(butAPrev, butBPrev, butCPrev, butDPrev, butSPrev, curr, ignoreBut: FightingGameInputCodeBut.None, callback: buttonCode0 => { FindSingleButtonPress(butAPrev, butBPrev, butCPrev, butDPrev, butSPrev, curr, ignoreBut: buttonCode0, callback: buttonCode1 => { AddToActiveInputs <Button2Press>(activeInputs, inputFactory, reader.currentFrame, newInput => { numFound++; newInput.Init(inputFrameIndex, buttonCode1, buttonCode0); }); }); for (int n = 0; n < 2 && reader.ReadyNextLookBehind(); ++n) { int inputLookBehindFrameIndex = reader.LookBehind(out GameInputStruct lb); // If you both reverse the order of the 2 frames AND negate both values, it's the same as checking in the correct order FindSingleButtonPress(!butAPrev, !butBPrev, !butCPrev, !butDPrev, !butSPrev, !lb, ignoreBut: buttonCode0, callback: buttonCode1 => { AddToActiveInputs <Button2Press>(activeInputs, inputFactory, reader.currentFrame, newInput => { numFound++; //newInput.Init(inputLookBehindFrameIndex + 1, buttonCode0, buttonCode1); // This uses the button press as the trigger newInput.Init(inputFrameIndex, buttonCode0, buttonCode1); // This uses the end of the quarter circle as the trigger }); }); butAPrev = lb.butA; butBPrev = lb.butB; butCPrev = lb.butC; butDPrev = lb.butD; butSPrev = lb.butS; } }); butAPrev = curr.butA; butBPrev = curr.butB; butCPrev = curr.butC; butDPrev = curr.butD; butSPrev = curr.butS; } return(numFound); }
public static int FindQuarterCircleButtonPresses(InputBufferReader reader, Factory inputFactory, List <Combination> activeInputs) { int numFound = 0; reader.ResetCurrIndex(); List <Combination> quarterCircles = activeInputs.FindAll(combo => { return(combo.GetType() == typeof(QuarterCircle)); }); foreach (QuarterCircle qc in quarterCircles) { reader.SetReadIndex(-(reader.currentFrame - qc.GetFrame()) - 1); reader.ReadBuffer(out GameInputStruct curr); bool butAPrev = curr.butA; bool butBPrev = curr.butB; bool butCPrev = curr.butC; bool butDPrev = curr.butD; bool butSPrev = curr.butS; for (int n = 0; n < 8 && reader.ReadyNextLookAhead(); ++n) { int inputFrameIndex = reader.LookAhead(out GameInputStruct la); FindSingleButtonPress(butAPrev, butBPrev, butCPrev, butDPrev, butSPrev, la, ignoreBut: FightingGameInputCodeBut.None, callback: buttonCode => { AddToActiveInputs <QuarterCircleButtonPress>(activeInputs, inputFactory, reader.currentFrame, newInput => { numFound++; newInput.Init(inputFrameIndex, qc.endDirection, buttonCode); }); }); butAPrev = la.butA; butBPrev = la.butB; butCPrev = la.butC; butDPrev = la.butD; butSPrev = la.butS; } butAPrev = curr.butA; butBPrev = curr.butB; butCPrev = curr.butC; butDPrev = curr.butD; butSPrev = curr.butS; for (int n = 0; n < 8 && reader.ReadyNextLookBehind(); ++n) { int inputFrameIndex = reader.LookBehind(out GameInputStruct lb); // If you both reverse the order of the 2 frames AND negate both values, it's the same as checking in the correct order FindSingleButtonPress(!butAPrev, !butBPrev, !butCPrev, !butDPrev, !butSPrev, !lb, ignoreBut: FightingGameInputCodeBut.None, callback: buttonCode => { AddToActiveInputs <QuarterCircleButtonPress>(activeInputs, inputFactory, reader.currentFrame, newInput => { numFound++; //newInput.Init(inputFrameIndex + 1, qc.endDirection, buttonCode); // This uses the button press as the trigger newInput.Init(qc.GetFrame(), qc.endDirection, buttonCode); // This uses the end of the quarter circle as the trigger }); }); butAPrev = lb.butA; butBPrev = lb.butB; butCPrev = lb.butC; butDPrev = lb.butD; butSPrev = lb.butS; } } return(numFound); }
// regex = /(?<=([^5])[^5\1]{0,4}5{1,7})(?=[^5\1]{0,3}\1)/g public static int FindDoubleTaps(InputBufferReader reader, Factory inputFactory, List <Combination> activeInputs) { int numFound = 0; reader.ResetCurrIndex(); FightingGameAbsInputCodeDir currDir = FightingGameAbsInputCodeDir.None; while (reader.ReadyNext()) { int inputFrameIndex = reader.ReadBuffer(out GameInputStruct curr); if (currDir != curr.direction) { currDir = curr.direction; FightingGameAbsInputCodeDir direction = FightingGameAbsInputCodeDir.None; if (curr.direction != FightingGameAbsInputCodeDir.Neutral) { direction = curr.direction; bool continueSearch = true; int n = 0; //FightingGameInputCodeDir prevDir = direction; n = 0; while (continueSearch && reader.ReadyNextLookBehind()) { if (n < 5) { int lookBehindFrameIndex = reader.LookBehind(out GameInputStruct lb); if (lb.direction == FightingGameAbsInputCodeDir.Neutral) { break; } ++n; } else { continueSearch = false; break; } } n = 0; while (continueSearch && reader.ReadyNextLookBehind()) { if (n < 8) { int lookBehindFrameIndex = reader.LookBehind(out GameInputStruct lb); if (lb.direction != FightingGameAbsInputCodeDir.Neutral) { break; } ++n; } else { continueSearch = false; break; } } n = 0; while (continueSearch && reader.ReadyNextLookBehind()) { if (n < 4) { int lookBehindFrameIndex = reader.LookBehind(out GameInputStruct lb); if (lb.direction == direction) { DoubleTap input = AddToActiveInputs <DoubleTap>(activeInputs, inputFactory, reader.currentFrame, newInput => { numFound++; newInput.Init(inputFrameIndex, lookBehindFrameIndex, direction); }); } ++n; } else { continueSearch = false; break; } } } } } return(numFound); }