add a new heroes push back abilities

This commit is contained in:
Arnaud Jamin
2023-10-05 01:54:26 -04:00
parent ad397dbf7e
commit 27f4b9485a
73 changed files with 1077 additions and 233 deletions
@@ -1 +0,0 @@
#include "CogAbilitySystemComponent.h"
@@ -1,22 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "CogAbilitySystemComponent.generated.h"
UCLASS(BlueprintType)
class UCogAbilitySystemComponent : public UAbilitySystemComponent
{
GENERATED_BODY()
public:
template <class T>
const T* GetAttributeSet() const
{
UClass* DesiredClass = T::StaticClass();
check(DesiredClass->IsChildOf(UAttributeSet::StaticClass()));
return Cast<T>(Super::GetAttributeSet(DesiredClass));
}
};
@@ -0,0 +1,8 @@
#include "CogSampleAbilitySystemGlobals.h"
#include "CogSampleGameplayEffectContext.h"
FGameplayEffectContext* UCogSampleAbilitySystemGlobals::AllocGameplayEffectContext() const
{
return new FCogSampleGameplayEffectContext();
}
@@ -0,0 +1,13 @@
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystemGlobals.h"
#include "CogSampleAbilitySystemGlobals.generated.h"
UCLASS()
class UCogSampleAbilitySystemGlobals : public UAbilitySystemGlobals
{
GENERATED_BODY()
virtual FGameplayEffectContext* AllocGameplayEffectContext() const override;
};
+92 -1
View File
@@ -6,6 +6,7 @@
#include "CogSampleAttributeSet_Health.h"
#include "CogSampleAttributeSet_Misc.h"
#include "CogSampleCharacterMovementComponent.h"
#include "CogSampleForcedMove.h"
#include "CogSampleLogCategories.h"
#include "CogSampleTagLibrary.h"
#include "Components/CapsuleComponent.h"
@@ -15,6 +16,7 @@
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/CheatManagerDefines.h"
#include "GameFramework/Controller.h"
#include "GameFramework/RootMotionSource.h"
#include "GameFramework/SpringArmComponent.h"
#include "Net/Core/PushModel/PushModel.h"
#include "Net/UnrealNetwork.h"
@@ -74,6 +76,7 @@ void ACogSampleCharacter::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >
Params.Condition = COND_OwnerOnly;
DOREPLIFETIME_WITH_PARAMS_FAST(ACogSampleCharacter, ActiveAbilityHandles, Params);
DOREPLIFETIME_WITH_PARAMS_FAST(ACogSampleCharacter, TeamID, Params);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -109,6 +112,23 @@ UAbilitySystemComponent* ACogSampleCharacter::GetAbilitySystemComponent() const
return AbilitySystem;
}
//--------------------------------------------------------------------------------------------------------------------------
ECogInterfacesAllegiance ACogSampleCharacter::GetAllegianceWithOtherActor(const AActor* OtherActor) const
{
const ACogSampleCharacter* OtherCharacter = Cast<ACogSampleCharacter>(OtherActor);
if (OtherCharacter == nullptr)
{
return ECogInterfacesAllegiance::Neutral;
}
if (TeamID == OtherCharacter->TeamID)
{
return ECogInterfacesAllegiance::Friendly;
}
return ECogInterfacesAllegiance::Enemy;
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::InitializeAbilitySystem()
{
@@ -301,7 +321,7 @@ void ACogSampleCharacter::OnAbilityInputCompleted(const FInputActionValue& Value
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::ActivateItem(const FInputActionValue& Value, int32 Index)
{
COG_LOG_ACTOR(LogCogInput, ELogVerbosity::Verbose, this, TEXT("%d"), Index);
COG_LOG_OBJECT(LogCogInput, ELogVerbosity::Verbose, this, TEXT("%d"), Index);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -468,3 +488,74 @@ void ACogSampleCharacter::OnScaleAttributeChanged(const FOnAttributeChangeData&
{
SetActorScale3D(FVector(Data.NewValue));
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::SetTeamID(int32 Value)
{
TeamID = Value;
MARK_PROPERTY_DIRTY_FROM_NAME(ACogSampleCharacter, TeamID, this);
}
//--------------------------------------------------------------------------------------------------------------------------
int32 ACogSampleCharacter::ApplyForcedMove(const FCogSampleForcedMoveParams& Params)
{
if (HasAuthority() == false)
{
return (uint16)ERootMotionSourceID::Invalid;;
}
if (IsValid(Params.Effect))
{
FGameplayEffectContextHandle EffectContextHandle = AbilitySystem->MakeEffectContext();
EffectContextHandle.AddInstigator(Params.Instigator, Params.Causer);
FGameplayEffectSpecHandle SpecHandle = AbilitySystem->MakeOutgoingSpec(Params.Effect, 1.0f, EffectContextHandle);
SpecHandle.Data->SetDuration(Params.Duration, true);
if (SpecHandle.IsValid())
{
AbilitySystem->ApplyGameplayEffectSpecToSelf(*SpecHandle.Data.Get());
}
}
Client_ApplyForcedMove(Params);
int32 RootMotionSourceID = ApplyForcedMoveInternal(Params);
return RootMotionSourceID;
}
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleCharacter::Client_ApplyForcedMove_Implementation(const FCogSampleForcedMoveParams& Params)
{
if (GetWorld()->GetNetMode() == NM_Client)
{
ApplyForcedMoveInternal(Params);
}
}
//--------------------------------------------------------------------------------------------------------------------------
uint16 ACogSampleCharacter::ApplyForcedMoveInternal(const FCogSampleForcedMoveParams& Params)
{
UCogSampleCharacterMovementComponent* MovementComponent = Cast<UCogSampleCharacterMovementComponent>(GetMovementComponent());
if (MovementComponent == nullptr)
{
return (uint16)ERootMotionSourceID::Invalid;;
}
TSharedPtr<FRootMotionSource_JumpForce> JumpForce = MakeShared<FRootMotionSource_JumpForce>();
JumpForce->InstanceName = "ForceMove";
JumpForce->AccumulateMode = Params.IsAdditive ? ERootMotionAccumulateMode::Additive : ERootMotionAccumulateMode::Override;
JumpForce->Priority = (uint16)Params.Priority;
JumpForce->Duration = Params.Duration;
JumpForce->Rotation = Params.Rotation;
JumpForce->Distance = Params.Distance;
JumpForce->Height = Params.Height;
JumpForce->bDisableTimeout = Params.bFinishOnLanded; // If we finish on landed, we need to disable force's timeout
JumpForce->PathOffsetCurve = Params.PathOffsetCurve;
JumpForce->TimeMappingCurve = Params.TimeMappingCurve;
JumpForce->FinishVelocityParams.Mode = Params.FinishVelocityMode;
JumpForce->FinishVelocityParams.SetVelocity = Params.FinishSetVelocity;
JumpForce->FinishVelocityParams.ClampVelocity = Params.FinishClampVelocity;
uint16 RootMotionSourceID = MovementComponent->ApplyRootMotionSource(JumpForce);
return RootMotionSourceID;
}
+63 -9
View File
@@ -5,7 +5,8 @@
#include "ActiveGameplayEffectHandle.h"
#include "AttributeSet.h"
#include "CogDefines.h"
#include "CogInterfaceFilteredActor.h"
#include "CogInterfaceAllegianceActor.h"
#include "CogInterfaceDebugFilteredActor.h"
#include "GameFramework/Character.h"
#include "GameplayAbilitySpecHandle.h"
#include "GameplayTagContainer.h"
@@ -21,9 +22,21 @@ class UInputAction;
class UInputMappingContext;
class USpringArmComponent;
struct FActiveGameplayEffect;
struct FCogSampleForcedMoveParams;
struct FGameplayEffectSpec;
struct FOnAttributeChangeData;
//--------------------------------------------------------------------------------------------------------------------------
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
enum class ECogSampleAllegianceFilter : uint8
{
None = 0 UMETA(Hidden),
Ally = 1 << 0,
Neutral = 1 << 1,
Enemy = 1 << 2,
};
ENUM_CLASS_FLAGS(ECogSampleAllegianceFilter);
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT(BlueprintType)
struct FActiveAbilityInfo
@@ -57,7 +70,8 @@ public:
UCLASS(config=Game)
class ACogSampleCharacter : public ACharacter
, public IAbilitySystemInterface
, public ICogInterfacesFilteredActor
, public ICogInterfacesDebugFilteredActor
, public ICogInterfacesAllegianceActor
{
GENERATED_BODY()
@@ -83,6 +97,11 @@ public:
UFUNCTION(BlueprintPure)
UAbilitySystemComponent* GetAbilitySystemComponent() const override;
//----------------------------------------------------------------------------------------------------------------------
// ICogInterfacesAllegianceActor overrides
//----------------------------------------------------------------------------------------------------------------------
ECogInterfacesAllegiance GetAllegianceWithOtherActor(const AActor* OtherActor) const override;
//----------------------------------------------------------------------------------------------------------------------
void OnAcknowledgePossession(APlayerController* InController);
@@ -94,13 +113,13 @@ public:
void OnRevived(AActor* InInstigator, AActor* InCauser, const FGameplayEffectSpec& InEffectSpec, float InMagnitude);
//----------------------------------------------------------------------------------------------------------------------
// Camera
//----------------------------------------------------------------------------------------------------------------------
USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
UCameraComponent* GetFollowCamera() const { return FollowCamera; }
//----------------------------------------------------------------------------------------------------------------------
// Camera
//----------------------------------------------------------------------------------------------------------------------
/** Camera boom positioning the camera behind the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
USpringArmComponent* CameraBoom;
@@ -157,12 +176,30 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Ability)
TArray<TSubclassOf<UGameplayEffect>> Effects;
//----------------------------------------------------------------------------------------------------------------------
// Team
//----------------------------------------------------------------------------------------------------------------------
UFUNCTION(BlueprintPure)
int32 GetTeamID() const { return TeamID; }
UFUNCTION(BlueprintCallable)
void SetTeamID(int32 Value);
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Team, Replicated, meta = (AllowPrivateAccess = "true"))
int32 TeamID = 0;
//----------------------------------------------------------------------------------------------------------------------
// Forced Move
//----------------------------------------------------------------------------------------------------------------------
UFUNCTION(BlueprintCallable)
int32 ApplyForcedMove(const FCogSampleForcedMoveParams& Params);
private:
void InitializeAbilitySystem();
void ShutdownAbilitySystem();
//----------------------------------------------------------------------------------------------------------------------
// Inputs
//----------------------------------------------------------------------------------------------------------------------
void Move(const FInputActionValue& Value);
void MoveZ(const FInputActionValue& Value);
@@ -175,6 +212,13 @@ private:
void ActivateItem(const FInputActionValue& Value, int32 Index);
//----------------------------------------------------------------------------------------------------------------------
// Ability system
//----------------------------------------------------------------------------------------------------------------------
void InitializeAbilitySystem();
void ShutdownAbilitySystem();
void OnGameplayEffectAdded(UAbilitySystemComponent* AbilitySystemComponent, const FGameplayEffectSpec& GameplayEffectSpec, FActiveGameplayEffectHandle Handle);
void OnGameplayEffectRemoved(const FActiveGameplayEffect& RemovedGameplayEffect);
@@ -183,6 +227,15 @@ private:
void OnScaleAttributeChanged(const FOnAttributeChangeData& Data);
//----------------------------------------------------------------------------------------------------------------------
// Forced Move
//----------------------------------------------------------------------------------------------------------------------
UFUNCTION(Reliable, Client)
void Client_ApplyForcedMove(const FCogSampleForcedMoveParams& Params);
uint16 ApplyForcedMoveInternal(const FCogSampleForcedMoveParams& Params);
//----------------------------------------------------------------------------------------------------------------------
UPROPERTY(Replicated, Transient)
TArray<FGameplayAbilitySpecHandle> ActiveAbilityHandles;
@@ -197,5 +250,6 @@ private:
bool bIsGhost = false;
bool bIsInitialized = false;
};
@@ -220,7 +220,7 @@ void UCogSampleCharacterMovementComponent::TickComponent(float DeltaTime, enum E
const ACharacter* Character = GetCharacterOwner();
const UCapsuleComponent* CapsuleComponent = Character->GetCapsuleComponent();
if (FCogDebugSettings::IsDebugActiveForActor(GetPawnOwner()))
if (FCogDebugSettings::IsDebugActiveForObject(GetPawnOwner()))
{
FCogDebugPlot::PlotValue(GetPawnOwner(), "Move Input X", GetPendingInputVector().X);
FCogDebugPlot::PlotValue(GetPawnOwner(), "Move Input Y", GetPendingInputVector().Y);
@@ -236,7 +236,7 @@ void UCogSampleCharacterMovementComponent::TickComponent(float DeltaTime, enum E
const FVector DebugLocation = Character->GetActorLocation();
const FVector DebugBottomLocation = DebugLocation - FVector::UpVector * CapsuleComponent->GetScaledCapsuleHalfHeight();
if (FCogDebugSettings::IsDebugActiveForActor(GetPawnOwner()))
if (FCogDebugSettings::IsDebugActiveForObject(GetPawnOwner()))
{
const FRotator Rotation = Character->GetActorRotation();
const FVector Forward = Character->GetActorForwardVector();
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/RootMotionSource.h"
#include "CogSampleForcedMove.generated.h"
class UGameplayEffect;
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT(BlueprintType)
struct FCogSampleForcedMoveParams
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
AActor* Instigator;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
AActor* Causer;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSubclassOf<UGameplayEffect> Effect;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FRotator Rotation;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool IsAdditive = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 Priority = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Duration = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Distance = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Height = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float MinimumLandedTriggerTime = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
bool bFinishOnLanded = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
ERootMotionFinishVelocityMode FinishVelocityMode = ERootMotionFinishVelocityMode::MaintainLastRootMotionVelocity;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector FinishSetVelocity = FVector::ZeroVector;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float FinishClampVelocity = 0.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UCurveVector* PathOffsetCurve = nullptr;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UCurveFloat* TimeMappingCurve = nullptr;
};
@@ -0,0 +1,252 @@
#include "CogSampleGameplayEffectContext.h"
#include "AbilitySystemComponent.h"
//--------------------------------------------------------------------------------------------------------------------------
bool FCogSampleGameplayEffectContextFloatValue::NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
{
enum RepFlag
{
REP_Name = 0,
REP_Value,
REP_MAX
};
uint16 RepBits = 0;
if (Ar.IsSaving())
{
if (Name.IsValid())
{
RepBits |= (1 << REP_Name);
}
if (Value != 0.f)
{
RepBits |= (1 << REP_Value);
}
}
Ar.SerializeBits(&RepBits, REP_MAX);
if (RepBits & (1 << REP_Name))
{
Ar << Name;
}
if (RepBits & (1 << REP_Value))
{
Ar << Value;
}
bOutSuccess = true;
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
FCogSampleGameplayEffectContext* FCogSampleGameplayEffectContext::ExtractEffectContext(struct FGameplayEffectContextHandle Handle)
{
FGameplayEffectContext* BaseEffectContext = Handle.Get();
if ((BaseEffectContext != nullptr) && BaseEffectContext->GetScriptStruct()->IsChildOf(FCogSampleGameplayEffectContext::StaticStruct()))
{
return (FCogSampleGameplayEffectContext*)BaseEffectContext;
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogSampleGameplayEffectContext::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
enum RepFlag
{
Rep_Instigator = 0,
Rep_EffectCauser,
Rep_AbilityCDO,
Rep_SourceObject,
Rep_Actors,
Rep_HitResult,
Rep_HasWorldOrigin,
Rep_FloatValues,
Rep_MAX
};
uint32 RepBits = 0;
if (Ar.IsSaving())
{
if (Instigator.IsValid())
{
RepBits |= 1 << Rep_Instigator;
}
if (EffectCauser.IsValid())
{
RepBits |= 1 << Rep_EffectCauser;
}
if (AbilityCDO.IsValid())
{
RepBits |= 1 << Rep_AbilityCDO;
}
if (bReplicateSourceObject && SourceObject.IsValid())
{
RepBits |= 1 << Rep_SourceObject;
}
if (Actors.Num() > 0)
{
RepBits |= 1 << Rep_Actors;
}
if (HitResult.IsValid())
{
RepBits |= 1 << Rep_HitResult;
}
if (bHasWorldOrigin)
{
RepBits |= 1 << Rep_HasWorldOrigin;
}
//------------------------------
// Our custom fields
//------------------------------
if (FloatValues.Num() > 0)
{
RepBits |= 1 << Rep_FloatValues;
}
//------------------------------
}
Ar.SerializeBits(&RepBits, Rep_MAX);
if (RepBits & (1 << Rep_Instigator))
{
Ar << Instigator;
}
if (RepBits & (1 << Rep_EffectCauser))
{
Ar << EffectCauser;
}
if (RepBits & (1 << Rep_AbilityCDO))
{
Ar << AbilityCDO;
}
if (RepBits & (1 << Rep_SourceObject))
{
Ar << SourceObject;
}
if (RepBits & (1 << Rep_Actors))
{
SafeNetSerializeTArray_Default<31>(Ar, Actors);
}
if (RepBits & (1 << Rep_HitResult))
{
if (Ar.IsLoading())
{
if (!HitResult.IsValid())
{
HitResult = TSharedPtr<FHitResult>(new FHitResult());
}
}
HitResult->NetSerialize(Ar, Map, bOutSuccess);
}
if (RepBits & (1 << Rep_HasWorldOrigin))
{
Ar << WorldOrigin;
bHasWorldOrigin = true;
}
else
{
bHasWorldOrigin = false;
}
//------------------------------
// Our custom fields
//------------------------------
if (RepBits & (1 << Rep_FloatValues))
{
SafeNetSerializeTArray_WithNetSerialize<31>(Ar, FloatValues, Map);
}
if (Ar.IsLoading())
{
AddInstigator(Instigator.Get(), EffectCauser.Get()); // Just to initialize InstigatorAbilitySystemComponent
}
bOutSuccess = true;
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
UScriptStruct* FCogSampleGameplayEffectContext::GetScriptStruct() const
{
return FCogSampleGameplayEffectContext::StaticStruct();
}
//--------------------------------------------------------------------------------------------------------------------------
FCogSampleGameplayEffectContext* FCogSampleGameplayEffectContext::Duplicate() const
{
FCogSampleGameplayEffectContext* newContext = new FCogSampleGameplayEffectContext();
*newContext = *this;
newContext->AddActors(Actors);
if (GetHitResult())
{
// Does a deep copy of the hit result
newContext->AddHitResult(*GetHitResult(), true);
}
return newContext;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleEffectContextLibrary::EffectContextSetFloatValue(FGameplayEffectContextHandle EffectContext, FName Name, float Value)
{
if (FCogSampleGameplayEffectContext* TypedEffectContext = FCogSampleGameplayEffectContext::ExtractEffectContext(EffectContext))
{
FCogSampleGameplayEffectContextFloatValue* Result = TypedEffectContext->FloatValues.FindByPredicate([&Name](const FCogSampleGameplayEffectContextFloatValue& Entry)
{
return Entry.Name == Name;
});
if (Result != nullptr)
{
Result->Value = Value;
}
else
{
FCogSampleGameplayEffectContextFloatValue Entry;
Entry.Name = Name;
Entry.Value = Value;
TypedEffectContext->FloatValues.Emplace(Entry);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleEffectContextLibrary::EffectContextGetFloatValue(FGameplayEffectContextHandle EffectContext, FName Name, float& Value, bool& Found)
{
Found = false;
if (FCogSampleGameplayEffectContext* TypedEffectContext = FCogSampleGameplayEffectContext::ExtractEffectContext(EffectContext))
{
const FCogSampleGameplayEffectContextFloatValue* Result = TypedEffectContext->FloatValues.FindByPredicate([&Name](const FCogSampleGameplayEffectContextFloatValue& Entry)
{
return Entry.Name == Name;
});
if (Result != nullptr)
{
Value = Result->Value;
Found = true;
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleEffectContextLibrary::EffectContextGetAllFloatValues(FGameplayEffectContextHandle EffectContext, TArray<FCogSampleGameplayEffectContextFloatValue>& Entries)
{
if (FCogSampleGameplayEffectContext* TypedEffectContext = FCogSampleGameplayEffectContext::ExtractEffectContext(EffectContext))
{
Entries = TypedEffectContext->FloatValues;
}
}
@@ -0,0 +1,102 @@
#pragma once
#include "CoreMinimal.h"
#include "GameplayEffectTypes.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "CogSampleGameplayEffectContext.generated.h"
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT(BlueprintType)
struct FCogSampleGameplayEffectContextFloatValue
{
GENERATED_BODY()
virtual ~FCogSampleGameplayEffectContextFloatValue()
{
}
UPROPERTY(BlueprintReadWrite)
FName Name;
UPROPERTY(BlueprintReadWrite)
float Value = 0.0f;
virtual bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess);
};
//--------------------------------------------------------------------------------------------------------------------------
template<>
struct TStructOpsTypeTraits<FCogSampleGameplayEffectContextFloatValue> : public TStructOpsTypeTraitsBase2<FCogSampleGameplayEffectContextFloatValue>
{
enum
{
WithNetSerializer = true
};
};
//--------------------------------------------------------------------------------------------------------------------------
USTRUCT()
struct FCogSampleGameplayEffectContext : public FGameplayEffectContext
{
GENERATED_BODY()
public:
FCogSampleGameplayEffectContext()
: FGameplayEffectContext()
{
}
FCogSampleGameplayEffectContext(AActor* InInstigator, AActor* InEffectCauser)
: FGameplayEffectContext(InInstigator, InEffectCauser)
{
}
/** Returns the wrapped FGPCoreGameplayEffectContext from the handle, or nullptr if it doesn't exist or is the wrong type */
static FCogSampleGameplayEffectContext* ExtractEffectContext(struct FGameplayEffectContextHandle Handle);
virtual UScriptStruct* GetScriptStruct() const override;
virtual FCogSampleGameplayEffectContext* Duplicate() const override;
virtual bool NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess) override;
bool CanGameplayCueBePredicted();
/* REPLICATED */
UPROPERTY()
TArray<FCogSampleGameplayEffectContextFloatValue> FloatValues;
};
//--------------------------------------------------------------------------------------------------------------------------
template<>
struct TStructOpsTypeTraits<FCogSampleGameplayEffectContext> : public TStructOpsTypeTraitsBase2<FCogSampleGameplayEffectContext>
{
enum
{
WithNetSerializer = true,
WithCopy = true
};
};
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(meta = (ScriptName = "CogSampleEffectContextLibrary"))
class UCogSampleEffectContextLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
static void EffectContextSetFloatValue(FGameplayEffectContextHandle EffectContext, FName Name, float Value);
UFUNCTION(BlueprintPure)
static void EffectContextGetFloatValue(FGameplayEffectContextHandle EffectContext, FName Name, float& Value, bool& Found);
UFUNCTION(BlueprintPure)
static void EffectContextGetAllFloatValues(FGameplayEffectContextHandle EffectContext, TArray<FCogSampleGameplayEffectContextFloatValue>& Entries);
};
@@ -0,0 +1,69 @@
#include "CogSampleGameplayLibrary.h"
#include "Abilities/GameplayAbility.h"
#include "AbilitySystemComponent.h"
#include "AbilitySystemGlobals.h"
#include "CogSampleGameplayEffectContext.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/Character.h"
#include "GameplayCueNotifyTypes.h"
#include "Particles/ParticleSystemComponent.h"
//--------------------------------------------------------------------------------------------------------------------------
FVector UCogSampleGameplayLibrary::GetActorBottomLocation(const AActor* Actor)
{
const FVector Location = Actor->GetActorLocation();
if (const ACharacter* Character = Cast<ACharacter>(Actor))
{
const UCapsuleComponent* CapsuleComponent = Character->GetCapsuleComponent();
const FVector BottomLocation = Location - FVector::UpVector * CapsuleComponent->GetScaledCapsuleHalfHeight();
return BottomLocation;
}
return Location;
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogSampleGameplayLibrary::FindAbilitySpecHandleFromClass(UAbilitySystemComponent* AbilitySystemComponent, TSubclassOf<UGameplayAbility> AbilityClass, FGameplayAbilitySpecHandle& SpecHandle)
{
if (const FGameplayAbilitySpec* Spec = AbilitySystemComponent->FindAbilitySpecFromClass(AbilityClass))
{
SpecHandle = Spec->Handle;
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleGameplayLibrary::ApplyAllGameplayEffectContextValues(const FGameplayCueParameters& Parameters, const FGameplayCueNotify_SpawnResult& SpawnResult)
{
TArray<FCogSampleGameplayEffectContextFloatValue> Entries;
UCogSampleEffectContextLibrary::EffectContextGetAllFloatValues(Parameters.EffectContext, Entries);
for (TObjectPtr<UFXSystemComponent> FXSystemComponent : SpawnResult.FxSystemComponents)
{
if (UFXSystemComponent* FXSystemComponentPtr = FXSystemComponent.Get())
{
for (const FCogSampleGameplayEffectContextFloatValue& Entry : Entries)
{
FXSystemComponentPtr->SetFloatParameter(Entry.Name, Entry.Value);
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogSampleGameplayLibrary::SendMontageEvent(AActor* Actor, FGameplayTag EventTag, FGameplayEventData Payload)
{
if (::IsValid(Actor))
{
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Actor);
if (AbilitySystemComponent != nullptr && IsValidChecked(AbilitySystemComponent))
{
FScopedPredictionWindow NewScopedWindow(AbilitySystemComponent, true);
AbilitySystemComponent->HandleGameplayEvent(EventTag, &Payload);
}
}
}
@@ -0,0 +1,37 @@
#pragma once
#include "CoreMinimal.h"
#include "Kismet/KismetSystemLibrary.h"
#include "CogSampleGameplayLibrary.generated.h"
class UAbilitySystemComponent;
class UGameplayAbility;
struct FGameplayAbilitySpecHandle;
struct FGameplayCueParameters;
struct FGameplayCueNotify_SpawnResult;
//--------------------------------------------------------------------------------------------------------------------------
UCLASS(meta = (ScriptName = "CogSampleGameplayLibrary"))
class UCogSampleGameplayLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure)
static FVector GetActorBottomLocation(const AActor* Actor);
UFUNCTION(BlueprintCallable)
static bool FindAbilitySpecHandleFromClass(UAbilitySystemComponent* AbilitySystemComponent, TSubclassOf<UGameplayAbility> AbilityClass, FGameplayAbilitySpecHandle& SpecHandle);
UFUNCTION(BlueprintCallable)
static void ApplyAllGameplayEffectContextValues(const FGameplayCueParameters& Parameters, const FGameplayCueNotify_SpawnResult& SpawnResult);
/* Same as UAbilitySystemBlueprintLibrary::SendGameplayEventToActor but doesn't log an error when the ability system
* is not found. When a montage is played in the montage editor the notifications are executed and if a notification
* uses SendGameplayEventToActor it will log an error. */
UFUNCTION(BlueprintCallable)
static void SendMontageEvent(AActor* Actor, FGameplayTag EventTag, FGameplayEventData Payload);
};
@@ -7,6 +7,7 @@
#include "CogDebugLogCategoryManager.h"
#endif //USE_COG
DEFINE_LOG_CATEGORY(LogCogAlways);
DEFINE_LOG_CATEGORY(LogCogCollision);
DEFINE_LOG_CATEGORY(LogCogInput);
DEFINE_LOG_CATEGORY(LogCogPosition);
@@ -20,6 +21,7 @@ namespace CogSampleLog
void RegiterAllLogCategories()
{
#if USE_COG
FCogDebugLogCategoryManager::AddLogCategory(LogCogAlways, "Always", false);
FCogDebugLogCategoryManager::AddLogCategory(LogAbilitySystem, "AbilitySystem");
FCogDebugLogCategoryManager::AddLogCategory(LogGameplayEffects, "Gameplay Effects");
FCogDebugLogCategoryManager::AddLogCategory(LogCogCollision, "Collision");
@@ -1,5 +1,6 @@
#include "CoreMinimal.h"
DECLARE_LOG_CATEGORY_EXTERN(LogCogAlways, VeryVerbose, All);
DECLARE_LOG_CATEGORY_EXTERN(LogCogCollision, Warning, All);
DECLARE_LOG_CATEGORY_EXTERN(LogCogInput, Warning, All);
DECLARE_LOG_CATEGORY_EXTERN(LogCogPosition, Warning, All);
+3
View File
@@ -14,6 +14,9 @@ UE_DEFINE_GAMEPLAY_TAG(Tag_Effect_Type_Heal_Revive, "Effect.Type.Heal.Revive");
UE_DEFINE_GAMEPLAY_TAG(Tag_GameplayEvent_Killed, "GameplayEvent.Killed");
UE_DEFINE_GAMEPLAY_TAG(Tag_GameplayEvent_Revived, "GameplayEvent.Revived");
UE_DEFINE_GAMEPLAY_TAG(Tag_MontageEvent_Cast_Begin, "MontageEvent.Cast.Begin");
UE_DEFINE_GAMEPLAY_TAG(Tag_MontageEvent_Cast_End, "MontageEvent.Cast.End");
UE_DEFINE_GAMEPLAY_TAG(Tag_Status_Dead, "Effect.Status.Dead");
UE_DEFINE_GAMEPLAY_TAG(Tag_Status_Ghost, "Effect.Status.Ghost");
UE_DEFINE_GAMEPLAY_TAG(Tag_Status_Immobilized, "Effect.Status.Immobilized");
+3
View File
@@ -17,6 +17,9 @@ UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Effect_Type_Heal_Revive);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_GameplayEvent_Killed);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_GameplayEvent_Revived);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_MontageEvent_Cast_Begin);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_MontageEvent_Cast_End);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Status_Dead);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Status_Ghost);
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Tag_Status_Immobilized);