280 lines
9.0 KiB
C++
280 lines
9.0 KiB
C++
// Unreal Fighting Framework by Kevin Poretti
|
|
|
|
#pragma once
|
|
|
|
// FF includes
|
|
#include "Input/FFInputBufferComponent.h"
|
|
|
|
// UE includes
|
|
#include "CoreMinimal.h"
|
|
|
|
#include "FFState.generated.h"
|
|
|
|
USTRUCT(BlueprintType)
|
|
struct FFFStateContext
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Actor that owns the avatar. Typically a player controller. */
|
|
UPROPERTY(BlueprintReadOnly)
|
|
AActor* Owner;
|
|
|
|
/**
|
|
* Actor that represents the player's avatar or an object associated with the player's avatar.
|
|
* This is typically a character or a weapon.
|
|
*/
|
|
UPROPERTY(BlueprintReadOnly)
|
|
AActor* Avatar;
|
|
|
|
/**
|
|
* Parent state machine that controls this state
|
|
*/
|
|
UPROPERTY(BlueprintReadOnly)
|
|
class UFFStateMachineComponent* Parent;
|
|
};
|
|
|
|
DECLARE_DYNAMIC_DELEGATE_OneParam(FFFInputEventDelegate, const FFFStateContext&, InStateContext);
|
|
|
|
USTRUCT(BlueprintType)
|
|
struct FFFInputEventHandler
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
// TODO: document
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
|
FFFInputSequence RequiredSequence;
|
|
|
|
// TODO: document
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
|
|
FFFInputEventDelegate Delegate;
|
|
};
|
|
|
|
UENUM(BlueprintType)
|
|
enum class EFFStateFinishReason : uint8
|
|
{
|
|
// TODO: document
|
|
SFT_Interrupted UMETA(DisplayName="Interrupted"),
|
|
SFT_DurationMetOrExceeded UMETA(DisplayName="Duration Reached"),
|
|
SFT_NotInReqMovementMode UMETA(DisplayName="Not In Required Movement Mode"),
|
|
SFT_MAX UMETA(Hidden)
|
|
};
|
|
|
|
|
|
/**
|
|
* A state is an object that provides rules and conditions for when a state can be transitioned into
|
|
* and logic to run when the state is entered, exited, and active.
|
|
*/
|
|
UCLASS(Blueprintable)
|
|
class UNREALFIGHTINGFRAMEWORK_API UFFState : public UObject
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// State parameters (should be read-only)
|
|
/** Name of this state behavior */
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
FName Name;
|
|
|
|
/**
|
|
* True if this state has some duration where it should return to the entry state
|
|
* if this state is not cancelled out of by other means.
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
bool bStateHasDuration;
|
|
|
|
// TODO: this should only be editable if bStateHasDuration is true
|
|
/**
|
|
* How long this state will be active before finishing if this state is not cancelled out of
|
|
* by other means.
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category="UFF State Properties")
|
|
int64 StateDuration;
|
|
|
|
/**
|
|
* What stance the object this state represents must be in.
|
|
* For example this is usually an enumerated value that signifies if a character needs to be
|
|
* crouching, standing, or airborne for this state to be eligible for transitioning.
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
int32 StanceRequired;
|
|
|
|
/**
|
|
* What is this state's category.
|
|
* Used for determining what types of state can prematurely cancel this one.
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
int32 StateType;
|
|
|
|
/**
|
|
* Input sequences that needs to be present in the controlling player's input buffer for this
|
|
* state to be eligible for transitioning.
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
TArray<FFFInputSequence> InputSequences;
|
|
|
|
/**
|
|
* If true the state can transition from itself into itself without having to go through
|
|
* another state like Idle
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
bool bCanTransitionToSelf = false;
|
|
|
|
/**
|
|
* Animation to begin playing when this state is entered
|
|
*/
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
UAnimMontage* MontageToPlay;
|
|
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
bool bStopMontageOnStateEnd;
|
|
|
|
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="UFF State Properties")
|
|
bool bStopMontageOnMovementModeChange;
|
|
|
|
/**
|
|
* Event delegates to call when a certain input condition is detected in the Owner's input buffer
|
|
*/
|
|
UPROPERTY(BlueprintReadOnly, Category="UFF State Events")
|
|
TArray<FFFInputEventHandler> InputHandlers;
|
|
|
|
/**
|
|
* Called when state is first created.
|
|
*/
|
|
virtual void Init(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Returns true if Avatar's is in the correct stance AND
|
|
* the state type is enabled (or the state can be hit or whiff cancelled from the current state) AND
|
|
* all state entry conditions were met AND
|
|
* at least one input sequence is present in the Owner's input buffer
|
|
*/
|
|
virtual bool CanTransition(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Called whenever this state is transitioned into.
|
|
*
|
|
* Calls appropriate Blueprint hooks.
|
|
*/
|
|
virtual void Enter(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Called whenever this state is transitioned out of into a new state.
|
|
*
|
|
* Calls appropriate Blueprint hooks.
|
|
*
|
|
* TODO: document StateFinishReason
|
|
*/
|
|
virtual void Exit(const FFFStateContext& InStateContext, EFFStateFinishReason StateFinishReason);
|
|
|
|
/**
|
|
* Called whenever this state is active and the game logic ticks.
|
|
*
|
|
* Calls appropriate Blueprint hooks.
|
|
*
|
|
* @param OneFrame the time that elapses during one fixed tick
|
|
*/
|
|
virtual void Update(float OneFrame, const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
virtual void Landed(const FHitResult& Hit, const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
virtual void MovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode,
|
|
EMovementMode NewMovementMode, uint8 NewCustomMode, const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
// TODO: pass in hitdata struct as well
|
|
virtual void Hit(const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
// TODO: pass in hitdata struct as well
|
|
virtual void Block(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Called when you want to exit from this state but no eligible transitions exist to other states,
|
|
* usually due to a lack of player input.
|
|
*
|
|
* By default this will transition to the owning state machine's entry state, which is usually
|
|
* an idle state.
|
|
*
|
|
* This function will get called automatically when the ticks in this state reaches the
|
|
* threshold set by the StateDuration member, but you can call it whenever you wish to return
|
|
* to the entry state.
|
|
*
|
|
* @param InStateContext
|
|
*/
|
|
UFUNCTION(BlueprintCallable)
|
|
virtual void Finish(const FFFStateContext& InStateContext, EFFStateFinishReason StateFinishReason);
|
|
|
|
// TODO: document
|
|
UFUNCTION(BlueprintCallable)
|
|
virtual void RegisterInputHandler(
|
|
const FFFInputSequence& InRequiredSequence, FFFInputEventDelegate InDelegate);
|
|
|
|
// TODO: document
|
|
UFUNCTION(BlueprintNativeEvent, Category="UFF|State|Events")
|
|
void OnInit(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Blueprint hook for overriding the CanTransition logic
|
|
*/
|
|
UFUNCTION(BlueprintNativeEvent, Category="UFF|State|Events")
|
|
bool OnCanTransition(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Blueprint hook for whenever this state is transitioned into
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
|
|
void OnEnter(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Blueprint hook for whenever this state is transitioned out of into a new state
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
|
|
void OnExit(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Blueprint hook for whenever this state is active and the game logic ticks.
|
|
*
|
|
* @param OneFrame the time that elapses during one fixed tick
|
|
*/
|
|
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
|
|
void OnUpdate(float OneFrame, const FFFStateContext& InStateContext);
|
|
|
|
UFUNCTION(BlueprintCallable, Category="UFF|State|Animations")
|
|
void PlayMontage(const FFFStateContext& InStateContext);
|
|
|
|
/**
|
|
* Blueprint hook for overriding the logic for when a anim montage plays at the start of a state
|
|
* @param InStateContext
|
|
*/
|
|
UFUNCTION(BlueprintNativeEvent, Category="UFF|State|Events")
|
|
void OnPlayMontage(const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
|
|
void OnLanded(const FHitResult& Hit, const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
|
|
void OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode,
|
|
EMovementMode NewMovementMode, uint8 NewCustomMode, const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
// TODO: pass in hitdata struct as well
|
|
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
|
|
void OnHit(const FFFStateContext& InStateContext);
|
|
|
|
// TODO: document
|
|
// TODO: pass in hitdata struct as well
|
|
UFUNCTION(BlueprintImplementableEvent, Category="UFF|State|Events")
|
|
void OnBlock(const FFFStateContext& InStateContext);
|
|
|
|
// UObject interface
|
|
virtual UWorld* GetWorld() const override;
|
|
// End of UObject interface
|
|
|
|
private:
|
|
void StopCurrentAnimMontage(const FFFStateContext& InStateContext);
|
|
};
|