From b8fa3415037edc9cb96db9554d22cfa93c4f4afb Mon Sep 17 00:00:00 2001 From: Kevin Poretti Date: Sat, 1 Jul 2023 16:18:09 -0400 Subject: [PATCH] Detect button press/release and disable inputs when they trigger a sequence --- .../Input/FFInputBufferComponent.cpp | 44 +++++++++++++++---- .../Input/FFInputBufferComponent.h | 32 ++++++++++++-- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/Source/UnrealFightingFramework/Input/FFInputBufferComponent.cpp b/Source/UnrealFightingFramework/Input/FFInputBufferComponent.cpp index f767b1d..2dde5cc 100644 --- a/Source/UnrealFightingFramework/Input/FFInputBufferComponent.cpp +++ b/Source/UnrealFightingFramework/Input/FFInputBufferComponent.cpp @@ -12,28 +12,54 @@ void UFFInputBufferComponent::AddInput(const FFFInputState& InputState) InputBuffer.ForcePush(InputState); } -bool UFFInputBufferComponent::CheckInputSequence(const FFFInputCondition& InputCondition) +bool UFFInputBufferComponent::CheckInputSequence(const FFFInputSequence& InputSequence) { - int CondIdx = InputCondition.Sequence.Num() - 1; + int CondIdx = InputSequence.Sequence.Num() - 1; int FramesSinceValidInput = 0; - for(int InpIdx = 0; InpIdx < InputBuffer.Num(); InpIdx++) + for(int InpIdx = 0; InpIdx < InputBuffer.Num() - 1; InpIdx++) { - int32 CurrCondition = InputCondition.Sequence[CondIdx].Buttons; - int32 ThisInput = InputBuffer[InpIdx].Buttons; - if(ThisInput & CurrCondition) + int32 RequiredButtons = InputSequence.Sequence[CondIdx].RequiredButtons; + EFFButtonState RequiredButtonState = InputSequence.Sequence[CondIdx].RequiredButtonState; + int32 PrevInput = InputBuffer[InpIdx + 1].Buttons; + int32 CurrInput = InputBuffer[InpIdx].Buttons; + int32 PrevDisable = InputBuffer[InpIdx + 1].DisabledButtons; + int32 CurrDisable = InputBuffer[InpIdx].DisabledButtons; + switch (RequiredButtonState) { - CondIdx--; - FramesSinceValidInput = 0; + case EFFButtonState::BTNS_Pressed: + if(!(PrevInput & RequiredButtons | PrevDisable) && + CurrInput & RequiredButtons & ~CurrDisable) + { + CondIdx--; + FramesSinceValidInput = 0; + } + break; + case EFFButtonState::BTNS_Released: + if(PrevInput & RequiredButtons & ~PrevDisable && + !(CurrInput & RequiredButtons | CurrDisable)) + { + CondIdx--; + FramesSinceValidInput = 0; + } + break; + // TODO: implement button held condition + /* + case EFFButtonState::BTNS_Held: + break; + */ } // All conditions were met if(CondIdx == -1) { + // disable inputs that triggered the sequence + InputBuffer[InpIdx].DisabledButtons |= InputBuffer[InpIdx].Buttons; + InputBuffer[InpIdx + 1].DisabledButtons |= InputBuffer[InpIdx + 1].Buttons; return true; } FramesSinceValidInput++; - if(FramesSinceValidInput > InputCondition.Lenience) + if(FramesSinceValidInput > InputSequence.Sequence[CondIdx].Lenience) { return false; } diff --git a/Source/UnrealFightingFramework/Input/FFInputBufferComponent.h b/Source/UnrealFightingFramework/Input/FFInputBufferComponent.h index c4c5109..1363683 100644 --- a/Source/UnrealFightingFramework/Input/FFInputBufferComponent.h +++ b/Source/UnrealFightingFramework/Input/FFInputBufferComponent.h @@ -11,6 +11,15 @@ #include "FFInputBufferComponent.generated.h" +UENUM(BlueprintType) +enum class EFFButtonState : uint8 +{ + BTNS_Pressed UMETA(DisplayName="Pressed"), + BTNS_Released UMETA(DisplayName="Released"), + //BTNS_Held UMETA(DisplayName="Held"), + BTNS_MAX UMETA(Hidden) +}; + /** * Struct representing the state of a player's inputs for one frame */ @@ -24,6 +33,7 @@ struct FFFInputState UPROPERTY(EditAnywhere, Meta = (Bitmask)) int32 Buttons; + int32 DisabledButtons; }; USTRUCT(BlueprintType) @@ -31,13 +41,27 @@ struct FFFInputCondition { GENERATED_BODY() - UPROPERTY(EditAnywhere) - TArray Sequence; - + // Buttons required for this specific condition to be valid UPROPERTY(EditAnywhere) + int32 RequiredButtons; + + // The button state required for condition to be valid i.e. pressed or released + UPROPERTY(EditAnywhere) + EFFButtonState RequiredButtonState; + + UPROPERTY(EditAnywhere) int32 Lenience; }; +USTRUCT(BlueprintType) +struct FFFInputSequence +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere) + TArray Sequence; +}; + UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class UNREALFIGHTINGFRAMEWORK_API UFFInputBufferComponent : public UActorComponent { @@ -48,7 +72,7 @@ public: void AddInput(const FFFInputState& InputState); - bool CheckInputSequence(const FFFInputCondition& InputCondition); + bool CheckInputSequence(const FFFInputSequence& InputSequence); protected: /** The underlying buffer data structure for holding past input states */