ComboInput/Source/ComboInput/Public/Components/ComboManagerComponent.h

118 lines
4.6 KiB
C++

// ©2022 Batty Bovine Productions, LLC. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "ComboInputAssets.h"
#include "Events/ComboActionDelegateBinding.h"
#include "ComboManagerComponent.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogComboManagerComponent, Log, All);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FComboActionHandlerDelegate, const class UComboAction *, ComboAction, const bool, Activated);
DECLARE_DYNAMIC_DELEGATE_TwoParams(FComboActionHandlerDynamicSignature, const class UComboAction *, ComboAction, const EComboActionTriggerEvent &, TriggerEvent);
struct COMBOINPUT_API FComboDelegateKey
{
public:
FComboDelegateKey(const class UComboAction *ComboAction, const EComboActionTriggerEvent &TriggerEvent)
{
this->Key = FName(ComboAction->GetName() + TEXT("_") + StaticEnum<EComboActionTriggerEvent>()->GetDisplayNameTextByIndex((uint8)TriggerEvent).ToString());
}
FName Key;
};
USTRUCT(BlueprintType)
struct COMBOINPUT_API FComboOffsetMap
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, EditAnywhere) TObjectPtr<const class UComboInputAsset> ComboInput;
UPROPERTY(BlueprintReadOnly, EditAnywhere) TObjectPtr<const class UComboAction> ComboAction;
};
UCLASS(BlueprintType, ClassGroup=(Input), meta=(BlueprintSpawnableComponent))
class COMBOINPUT_API UComboManagerComponent : public UActorComponent
{
GENERATED_BODY()
public:
UComboManagerComponent();
virtual void InitializeComponent() override;
UFUNCTION(BlueprintCallable)
void SetComboGraph(const class UComboActionGraph *Graph);
UFUNCTION(BlueprintCallable)
void HandleComboInput(const class UComboInputAsset *Input, const EComboActionTriggerEvent &TriggerEvent);
void BindAction(UObject *ObjectToBindTo, FName FunctionName, const class UComboAction *ComboAction, const EComboActionTriggerEvent &TriggerEvent)
{
FComboActionHandlerDynamicSignature Delegate;
Delegate.BindUFunction(ObjectToBindTo, FunctionName);
const FComboDelegateKey Key(ComboAction, TriggerEvent);
this->ComboActionEventBindings.Emplace(Key.Key, MoveTemp(Delegate));
}
// Recursively search the graph for all inputs used by the graph.
TSet<const UComboInputAsset *> &FindAllUsedInputs();
protected:
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TObjectPtr<const class UComboActionGraph> ComboGraph;
// This input will be recognised as an offset input, which cancels a node transition
// if activated early enough in the transition. This locks the current place in the
// combo and allows this combo string to be continued after this input has executed.
// The associated combo action will then be activated.
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
FComboOffsetMap OffsetMap;
// A list of default input->action mappings. If you wish for an action to be handled
// outside the scope of a combo sequence node, it should go here.
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TMap<TObjectPtr<const class UComboInputAsset>, TObjectPtr<const class UComboAction>> FallbackActions;
UPROPERTY(BlueprintReadOnly, EditDefaultsOnly)
TMap<TObjectPtr<const class UComboInputAsset>, float> DEBUG__UnlockTimers;
UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
FComboActionHandlerDelegate OnUnhandledAction;
private:
void ActivateComboAction(const class UComboInputAsset *Input);
void ReleaseComboAction(const class UComboInputAsset *Input);
void BeginNodeTransition(const class UComboActionGraphNode *NextNode);
void FinishTransition();
void ResetCombo();
const UComboActionGraphNode *FindActiveNodeData(const UComboActionGraphNode *CurrentNode, const UComboInputAsset *Input, const EComboActionTriggerEvent TriggerEvent, const UComboAction *&ComboAction);
void FindAllUsedInputs_RecurseGraph(const UComboActionGraphNode *CurrentNode, TSet<const UComboInputAsset *> &FoundInputs);
void BroadcastDelegates(const class UComboAction *ComboAction, const EComboActionTriggerEvent &TriggerEvent);
void DEBUG__UnlockAction(TObjectPtr<const class UComboInputAsset> Unlock);
TObjectPtr<const class UComboActionGraphNode> ActiveNode = nullptr;
TObjectPtr<const class UComboActionGraphNode> PreviousNode = nullptr;
TObjectPtr<const class UComboAction> LastComboAction = nullptr;
TMap<FName, FComboActionHandlerDynamicSignature> ComboActionEventBindings;
TObjectPtr<class UInputBufferComponent> AttachedInputBuffer;
// Cache of combo inputs found in the current graph.
TSet<const UComboInputAsset *> FoundInputsCache;
FTimerHandle FinishTransitionTimer;
FTimerHandle DEBUG__ResetComboTimer;
TMap<TObjectPtr<const class UComboInputAsset>, FTimerHandle> DEBUG__TimerHandles;
};