Compare commits
No commits in common. "bac7ff7498e49f5889766d01212ebf06a94a300b" and "b9b7e5344b80a43470f5e220703547e31ce3b16f" have entirely different histories.
bac7ff7498
...
b9b7e5344b
@ -1,30 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
|
|
||||||
#include "AbilitySystem/Attributes/OLSCombatAttributeSet.h"
|
|
||||||
|
|
||||||
#include "Net/UnrealNetwork.h"
|
|
||||||
|
|
||||||
UOLSCombatAttributeSet::UOLSCombatAttributeSet()
|
|
||||||
: BaseDamage(0.0f)
|
|
||||||
, BaseHeal(0.0f)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSCombatAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
|
||||||
{
|
|
||||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
|
||||||
|
|
||||||
DOREPLIFETIME_CONDITION_NOTIFY(ThisClass, BaseDamage, COND_OwnerOnly, REPNOTIFY_Always);
|
|
||||||
DOREPLIFETIME_CONDITION_NOTIFY(ThisClass, BaseHeal, COND_OwnerOnly, REPNOTIFY_Always);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSCombatAttributeSet::OnRep_BaseDamage(const FGameplayAttributeData& oldValue)
|
|
||||||
{
|
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY(ThisClass, BaseDamage, oldValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSCombatAttributeSet::OnRep_BaseHeal(const FGameplayAttributeData& oldValue)
|
|
||||||
{
|
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY(ThisClass, BaseHeal, oldValue);
|
|
||||||
}
|
|
@ -1,243 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
|
|
||||||
#include "AbilitySystem/Attributes/OLSHealthAttributeSet.h"
|
|
||||||
|
|
||||||
#include "GameplayEffectExtension.h"
|
|
||||||
#include "AbilitySystem/OLSAbilitySystemComponent.h"
|
|
||||||
#include "GameFramework/GameplayMessageSubsystem.h"
|
|
||||||
#include "Messages/OLSVerbMessage.h"
|
|
||||||
#include "Net/UnrealNetwork.h"
|
|
||||||
|
|
||||||
UE_DEFINE_GAMEPLAY_TAG(TAG_Gameplay_Damage, "Gameplay.Damage");
|
|
||||||
UE_DEFINE_GAMEPLAY_TAG(TAG_Gameplay_DamageImmunity, "Gameplay.DamageImmunity");
|
|
||||||
UE_DEFINE_GAMEPLAY_TAG(TAG_Gameplay_DamageSelfDestruct, "Gameplay.Damage.SelfDestruct");
|
|
||||||
UE_DEFINE_GAMEPLAY_TAG(TAG_Gameplay_FellOutOfWorld, "Gameplay.Damage.FellOutOfWorld");
|
|
||||||
UE_DEFINE_GAMEPLAY_TAG(TAG_OLS_Damage_Message, "Lyra.Damage.Message");
|
|
||||||
|
|
||||||
UOLSHealthAttributeSet::UOLSHealthAttributeSet()
|
|
||||||
: Health(100.0f)
|
|
||||||
, MaxHealth(100.0f)
|
|
||||||
{
|
|
||||||
bIsOutOfHealth = false;
|
|
||||||
MaxHealthBeforeAttributeChange = 0.0f;
|
|
||||||
HealthBeforeAttributeChange = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
|
||||||
{
|
|
||||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
|
||||||
|
|
||||||
DOREPLIFETIME_CONDITION_NOTIFY(UOLSHealthAttributeSet, Health, COND_None, REPNOTIFY_Always);
|
|
||||||
DOREPLIFETIME_CONDITION_NOTIFY(UOLSHealthAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::OnRep_Health(const FGameplayAttributeData& oldValue)
|
|
||||||
{
|
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY(UOLSHealthAttributeSet, Health, oldValue);
|
|
||||||
|
|
||||||
// Call the change callback, but without an instigator
|
|
||||||
// This could be changed to an explicit RPC in the future
|
|
||||||
// These events on the client should not be changing attributes
|
|
||||||
|
|
||||||
const float currentHealth = GetHealth();
|
|
||||||
const float estimatedMagnitude = currentHealth - oldValue.GetCurrentValue();
|
|
||||||
|
|
||||||
OnHealthChanged.Broadcast(
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
estimatedMagnitude,
|
|
||||||
oldValue.GetCurrentValue(),
|
|
||||||
currentHealth);
|
|
||||||
|
|
||||||
const bool isCurrentHealthEqualOrBelowZero = (currentHealth <= 0.0f);
|
|
||||||
|
|
||||||
if (!bIsOutOfHealth && isCurrentHealthEqualOrBelowZero)
|
|
||||||
{
|
|
||||||
OnOutOfHealth.Broadcast(nullptr, nullptr, nullptr, estimatedMagnitude, oldValue.GetCurrentValue(), currentHealth);
|
|
||||||
}
|
|
||||||
|
|
||||||
bIsOutOfHealth = isCurrentHealthEqualOrBelowZero;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldValue)
|
|
||||||
{
|
|
||||||
GAMEPLAYATTRIBUTE_REPNOTIFY(UOLSHealthAttributeSet, MaxHealth, OldValue);
|
|
||||||
|
|
||||||
// Call the change callback, but without an instigator
|
|
||||||
// This could be changed to an explicit RPC in the future
|
|
||||||
OnMaxHealthChanged.Broadcast(
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
GetMaxHealth() - OldValue.GetCurrentValue(),
|
|
||||||
OldValue.GetCurrentValue(), GetMaxHealth());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UOLSHealthAttributeSet::PreGameplayEffectExecute(FGameplayEffectModCallbackData& data)
|
|
||||||
{
|
|
||||||
if (!Super::PreGameplayEffectExecute(data))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle modifying incoming normal damage
|
|
||||||
if (data.EvaluatedData.Attribute == GetDamageAttribute())
|
|
||||||
{
|
|
||||||
if (data.EvaluatedData.Magnitude > 0.0f)
|
|
||||||
{
|
|
||||||
const bool isDamageFromSelfDestruct = data.EffectSpec.GetDynamicAssetTags().HasTagExact(TAG_Gameplay_DamageSelfDestruct);
|
|
||||||
|
|
||||||
if (data.Target.HasMatchingGameplayTag(TAG_Gameplay_DamageImmunity) && !isDamageFromSelfDestruct)
|
|
||||||
{
|
|
||||||
// Do not take away any health.
|
|
||||||
data.EvaluatedData.Magnitude = 0.0f;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !UE_BUILD_SHIPPING
|
|
||||||
// Check GodMode cheat, unlimited health is checked below
|
|
||||||
// if (data.Target.HasMatchingGameplayTag(LyraGameplayTags::Cheat_GodMode) && !isDamageFromSelfDestruct)
|
|
||||||
// {
|
|
||||||
// // Do not take away any health.
|
|
||||||
// data.EvaluatedData.Magnitude = 0.0f;
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
#endif // #if !UE_BUILD_SHIPPING
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the current health
|
|
||||||
HealthBeforeAttributeChange = GetHealth();
|
|
||||||
MaxHealthBeforeAttributeChange = GetMaxHealth();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
|
|
||||||
{
|
|
||||||
Super::PostGameplayEffectExecute(Data);
|
|
||||||
|
|
||||||
const bool isDamageFromSelfDestruct = Data.EffectSpec.GetDynamicAssetTags().HasTagExact(TAG_Gameplay_DamageSelfDestruct);
|
|
||||||
float minimumHealth = 0.0f;
|
|
||||||
|
|
||||||
#if !UE_BUILD_SHIPPING
|
|
||||||
// Godmode and unlimited health stop death unless it's a self destruct
|
|
||||||
// if (!bIsDamageFromSelfDestruct &&
|
|
||||||
// (Data.Target.HasMatchingGameplayTag(LyraGameplayTags::Cheat_GodMode) || Data.Target.HasMatchingGameplayTag(LyraGameplayTags::Cheat_UnlimitedHealth) ))
|
|
||||||
// {
|
|
||||||
// MinimumHealth = 1.0f;
|
|
||||||
// }
|
|
||||||
#endif // #if !UE_BUILD_SHIPPING
|
|
||||||
|
|
||||||
const FGameplayEffectContextHandle& effectContext = Data.EffectSpec.GetEffectContext();
|
|
||||||
AActor* instigator = effectContext.GetOriginalInstigator();
|
|
||||||
AActor* causer = effectContext.GetEffectCauser();
|
|
||||||
|
|
||||||
if (Data.EvaluatedData.Attribute == GetDamageAttribute())
|
|
||||||
{
|
|
||||||
// Send a standardized verb message that other systems can observe
|
|
||||||
if (Data.EvaluatedData.Magnitude > 0.0f)
|
|
||||||
{
|
|
||||||
FOLSVerbMessage message;
|
|
||||||
message.Verb = TAG_OLS_Damage_Message;
|
|
||||||
message.Instigator = Data.EffectSpec.GetEffectContext().GetEffectCauser();
|
|
||||||
message.InstigatorTags = *Data.EffectSpec.CapturedSourceTags.GetAggregatedTags();
|
|
||||||
message.Target = GetOwningActor();
|
|
||||||
message.TargetTags = *Data.EffectSpec.CapturedTargetTags.GetAggregatedTags();
|
|
||||||
//@TODO: Fill out context tags, and any non-ability-system source/instigator tags
|
|
||||||
//@TODO: Determine if it's an opposing team kill, self-own, team kill, etc...
|
|
||||||
message.Magnitude = Data.EvaluatedData.Magnitude;
|
|
||||||
|
|
||||||
UGameplayMessageSubsystem& messageSystem = UGameplayMessageSubsystem::Get(GetWorld());
|
|
||||||
messageSystem.BroadcastMessage(message.Verb, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert into -Health and then clamp
|
|
||||||
SetHealth(FMath::Clamp(GetHealth() - GetDamage(), minimumHealth, GetMaxHealth()));
|
|
||||||
SetDamage(0.0f);
|
|
||||||
}
|
|
||||||
else if (Data.EvaluatedData.Attribute == GetHealingAttribute())
|
|
||||||
{
|
|
||||||
// Convert into +Health and then clamo
|
|
||||||
SetHealth(FMath::Clamp(GetHealth() + GetHealing(), minimumHealth, GetMaxHealth()));
|
|
||||||
SetHealing(0.0f);
|
|
||||||
}
|
|
||||||
else if (Data.EvaluatedData.Attribute == GetHealthAttribute())
|
|
||||||
{
|
|
||||||
// Clamp and fall into out of health handling below
|
|
||||||
SetHealth(FMath::Clamp(GetHealth(), minimumHealth, GetMaxHealth()));
|
|
||||||
}
|
|
||||||
else if (Data.EvaluatedData.Attribute == GetMaxHealthAttribute())
|
|
||||||
{
|
|
||||||
// TODO clamp current health?
|
|
||||||
|
|
||||||
// Notify on any requested max health changes
|
|
||||||
OnMaxHealthChanged.Broadcast(instigator, causer, &Data.EffectSpec, Data.EvaluatedData.Magnitude, MaxHealthBeforeAttributeChange, GetMaxHealth());
|
|
||||||
}
|
|
||||||
|
|
||||||
// If health has actually changed activate callbacks
|
|
||||||
if (GetHealth() != HealthBeforeAttributeChange)
|
|
||||||
{
|
|
||||||
OnHealthChanged.Broadcast(instigator, causer, &Data.EffectSpec, Data.EvaluatedData.Magnitude, HealthBeforeAttributeChange, GetHealth());
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((GetHealth() <= 0.0f) && !bIsOutOfHealth)
|
|
||||||
{
|
|
||||||
OnOutOfHealth.Broadcast(instigator, causer, &Data.EffectSpec, Data.EvaluatedData.Magnitude, HealthBeforeAttributeChange, GetHealth());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check health again in case an event above changed it.
|
|
||||||
bIsOutOfHealth = (GetHealth() <= 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::PreAttributeBaseChange(const FGameplayAttribute& attribute, float& newValue) const
|
|
||||||
{
|
|
||||||
Super::PreAttributeBaseChange(attribute, newValue);
|
|
||||||
|
|
||||||
ClampAttribute(attribute, newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::PreAttributeChange(const FGameplayAttribute& attribute, float& newValue)
|
|
||||||
{
|
|
||||||
Super::PreAttributeChange(attribute, newValue);
|
|
||||||
|
|
||||||
ClampAttribute(attribute, newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::PostAttributeChange(const FGameplayAttribute& attribute, float oldValue, float newValue)
|
|
||||||
{
|
|
||||||
Super::PostAttributeChange(attribute, oldValue, newValue);
|
|
||||||
|
|
||||||
if (attribute == GetMaxHealthAttribute())
|
|
||||||
{
|
|
||||||
// Make sure current health is not greater than the new max health.
|
|
||||||
if (GetHealth() > newValue)
|
|
||||||
{
|
|
||||||
UOLSAbilitySystemComponent* asc = GetOLSAbilitySystemComponent();
|
|
||||||
check(asc);
|
|
||||||
|
|
||||||
asc->ApplyModToAttribute(GetHealthAttribute(), EGameplayModOp::Override, newValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bIsOutOfHealth && (GetHealth() > 0.0f))
|
|
||||||
{
|
|
||||||
bIsOutOfHealth = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UOLSHealthAttributeSet::ClampAttribute(const FGameplayAttribute& attribute, float& outNewValue) const
|
|
||||||
{
|
|
||||||
if (attribute == GetHealthAttribute())
|
|
||||||
{
|
|
||||||
// Do not allow health to go negative or above max health.
|
|
||||||
outNewValue = FMath::Clamp(outNewValue, 0.0f, GetMaxHealth());
|
|
||||||
}
|
|
||||||
else if (attribute == GetMaxHealthAttribute())
|
|
||||||
{
|
|
||||||
// Do not allow max health to drop below 1.
|
|
||||||
outNewValue = FMath::Max(outNewValue, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,7 +18,7 @@ AOLSCharacter::AOLSCharacter(const FObjectInitializer& objectInitializer) : Supe
|
|||||||
PrimaryActorTick.bCanEverTick = false;
|
PrimaryActorTick.bCanEverTick = false;
|
||||||
PrimaryActorTick.bStartWithTickEnabled = false;
|
PrimaryActorTick.bStartWithTickEnabled = false;
|
||||||
|
|
||||||
SetNetCullDistanceSquared(900000000.0f);
|
NetCullDistanceSquared = 900000000.0f;
|
||||||
|
|
||||||
LocomotionComponent = CreateDefaultSubobject<UOLSLocomotionComponent>(TEXT("Locomotion Component"));
|
LocomotionComponent = CreateDefaultSubobject<UOLSLocomotionComponent>(TEXT("Locomotion Component"));
|
||||||
}
|
}
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
|
|
||||||
#include "Messages/OLSVerbMessage.h"
|
|
||||||
|
|
||||||
FString FOLSVerbMessage::ToString() const
|
|
||||||
{
|
|
||||||
FString HumanReadableMessage;
|
|
||||||
FOLSVerbMessage::StaticStruct()->ExportText(/*out*/ HumanReadableMessage, this, /*Defaults=*/ nullptr, /*OwnerObject=*/ nullptr, PPF_None, /*ExportRootScope=*/ nullptr);
|
|
||||||
return HumanReadableMessage;
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
|
|
||||||
#include "Messages/OLSVerbMessageHelpers.h"
|
|
||||||
|
|
||||||
#include "GameplayEffectTypes.h"
|
|
||||||
#include "GameFramework/PlayerState.h"
|
|
||||||
#include "Messages/OLSVerbMessage.h"
|
|
||||||
|
|
||||||
APlayerState* UOLSVerbMessageHelpers::GetPlayerStateFromObject(UObject* object)
|
|
||||||
{
|
|
||||||
if (APlayerController* playerController = Cast<APlayerController>(object))
|
|
||||||
{
|
|
||||||
return playerController->PlayerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (APlayerState* targetPlayerState = Cast<APlayerState>(object))
|
|
||||||
{
|
|
||||||
return targetPlayerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (APawn* targetPawn = Cast<APawn>(object))
|
|
||||||
{
|
|
||||||
if (APlayerState* targetPlayerState = targetPawn->GetPlayerState())
|
|
||||||
{
|
|
||||||
return targetPlayerState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
APlayerController* UOLSVerbMessageHelpers::GetPlayerControllerFromObject(UObject* object)
|
|
||||||
{
|
|
||||||
if (APlayerController* playerController = Cast<APlayerController>(object))
|
|
||||||
{
|
|
||||||
return playerController;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (APlayerState* targetPlayerState = Cast<APlayerState>(object))
|
|
||||||
{
|
|
||||||
return targetPlayerState->GetPlayerController();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (APawn* targetPawn = Cast<APawn>(object))
|
|
||||||
{
|
|
||||||
return Cast<APlayerController>(targetPawn->GetController());
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FGameplayCueParameters UOLSVerbMessageHelpers::VerbMessageToCueParameters(const FOLSVerbMessage& message)
|
|
||||||
{
|
|
||||||
FGameplayCueParameters Result;
|
|
||||||
|
|
||||||
Result.OriginalTag = message.Verb;
|
|
||||||
Result.Instigator = Cast<AActor>(message.Instigator);
|
|
||||||
Result.EffectCauser = Cast<AActor>(message.Target);
|
|
||||||
Result.AggregatedSourceTags = message.InstigatorTags;
|
|
||||||
Result.AggregatedTargetTags = message.TargetTags;
|
|
||||||
//@TODO: = Message.ContextTags;
|
|
||||||
Result.RawMagnitude = message.Magnitude;
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLSVerbMessage UOLSVerbMessageHelpers::CueParametersToVerbMessage(const FGameplayCueParameters& params)
|
|
||||||
{
|
|
||||||
FOLSVerbMessage result;
|
|
||||||
|
|
||||||
result.Verb = params.OriginalTag;
|
|
||||||
result.Instigator = params.Instigator.Get();
|
|
||||||
result.Target = params.EffectCauser.Get();
|
|
||||||
result.InstigatorTags = params.AggregatedSourceTags;
|
|
||||||
result.TargetTags = params.AggregatedTargetTags;
|
|
||||||
//@TODO: Result.ContextTags = ???;
|
|
||||||
result.Magnitude = params.RawMagnitude;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -4,8 +4,6 @@
|
|||||||
#include "Player/OLSPlayerState.h"
|
#include "Player/OLSPlayerState.h"
|
||||||
|
|
||||||
#include "AbilitySystem/OLSAbilitySystemComponent.h"
|
#include "AbilitySystem/OLSAbilitySystemComponent.h"
|
||||||
#include "AbilitySystem/Attributes/OLSCombatAttributeSet.h"
|
|
||||||
#include "AbilitySystem/Attributes/OLSHealthAttributeSet.h"
|
|
||||||
#include "Components/GameFrameworkComponentManager.h"
|
#include "Components/GameFrameworkComponentManager.h"
|
||||||
#include "DataAssets/OLSAbilitySetPrimaryDataAsset.h"
|
#include "DataAssets/OLSAbilitySetPrimaryDataAsset.h"
|
||||||
#include "GameModes/OLSExperienceManagerComponent.h"
|
#include "GameModes/OLSExperienceManagerComponent.h"
|
||||||
@ -20,17 +18,6 @@ const FName AOLSPlayerState::NAME_OLSAbilityReady("OLSAbilitiesReady");
|
|||||||
AOLSPlayerState::AOLSPlayerState(const FObjectInitializer& objectInitializer) : Super(objectInitializer)
|
AOLSPlayerState::AOLSPlayerState(const FObjectInitializer& objectInitializer) : Super(objectInitializer)
|
||||||
{
|
{
|
||||||
// Create attribute sets here.
|
// Create attribute sets here.
|
||||||
|
|
||||||
AbilitySystemComponent = objectInitializer.CreateDefaultSubobject<UOLSAbilitySystemComponent>(this, TEXT("AbilitySystemComponent"));
|
|
||||||
AbilitySystemComponent->SetIsReplicated(true);
|
|
||||||
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
|
|
||||||
|
|
||||||
// These attribute sets will be detected by AbilitySystemComponent::InitializeComponent. Keeping a reference so that the sets don't get garbage collected before that.
|
|
||||||
HealthSet = CreateDefaultSubobject<UOLSHealthAttributeSet>(TEXT("HealthSet"));
|
|
||||||
CombatSet = CreateDefaultSubobject<UOLSCombatAttributeSet>(TEXT("CombatSet"));
|
|
||||||
|
|
||||||
// AbilitySystemComponent needs to be updated at a high frequency.
|
|
||||||
SetNetUpdateFrequency(100.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AOLSPlayerState::SetPawnData(const UOLSPawnDataAsset* pawnData)
|
void AOLSPlayerState::SetPawnData(const UOLSPawnDataAsset* pawnData)
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "AbilitySystemComponent.h"
|
|
||||||
#include "OLSAttributeSetBase.h"
|
|
||||||
#include "OLSCombatAttributeSet.generated.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UOLSCombatAttributeSet
|
|
||||||
*
|
|
||||||
* Class that defines attributes that are necessary for applying damage or healing.
|
|
||||||
* Attribute examples include: damage, healing, attack power, and shield penetrations.
|
|
||||||
*/
|
|
||||||
UCLASS(BlueprintType)
|
|
||||||
class OLS_API UOLSCombatAttributeSet : public UOLSAttributeSetBase
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
UOLSCombatAttributeSet();
|
|
||||||
|
|
||||||
//~ Begin UObject interface.
|
|
||||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
|
||||||
//~ End UObject interface.
|
|
||||||
|
|
||||||
ATTRIBUTE_ACCESSORS(ThisClass, BaseDamage);
|
|
||||||
ATTRIBUTE_ACCESSORS(ThisClass, BaseHeal);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void OnRep_BaseDamage(const FGameplayAttributeData& oldValue);
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void OnRep_BaseHeal(const FGameplayAttributeData& oldValue);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// The base amount of damage to apply in the damage execution.
|
|
||||||
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_BaseDamage, Category = "OLS|Combat", Meta = (AllowPrivateAccess = true))
|
|
||||||
FGameplayAttributeData BaseDamage;
|
|
||||||
|
|
||||||
// The base amount of healing to apply in the heal execution.
|
|
||||||
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_BaseHeal, Category = "OLS|Combat", Meta = (AllowPrivateAccess = true))
|
|
||||||
FGameplayAttributeData BaseHeal;
|
|
||||||
};
|
|
@ -1,96 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "AbilitySystemComponent.h"
|
|
||||||
#include "NativeGameplayTags.h"
|
|
||||||
#include "OLSAttributeSetBase.h"
|
|
||||||
#include "OLSHealthAttributeSet.generated.h"
|
|
||||||
|
|
||||||
OLS_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_Gameplay_Damage);
|
|
||||||
OLS_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_Gameplay_DamageImmunity);
|
|
||||||
OLS_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_Gameplay_DamageSelfDestruct);
|
|
||||||
OLS_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_Gameplay_FellOutOfWorld);
|
|
||||||
OLS_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_OLS_Damage_Message);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UOLSHealthAttributeSet
|
|
||||||
*
|
|
||||||
* Class that defines attributes that are necessary for taking damage.
|
|
||||||
* Attribute examples include: health, shields, and resistances.
|
|
||||||
*/
|
|
||||||
UCLASS(BlueprintType)
|
|
||||||
class OLS_API UOLSHealthAttributeSet : public UOLSAttributeSetBase
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
UOLSHealthAttributeSet();
|
|
||||||
|
|
||||||
//~ Begin UObject interface.
|
|
||||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
|
||||||
//~ End UObject interface.
|
|
||||||
|
|
||||||
ATTRIBUTE_ACCESSORS(ThisClass, Health);
|
|
||||||
ATTRIBUTE_ACCESSORS(ThisClass, MaxHealth);
|
|
||||||
ATTRIBUTE_ACCESSORS(ThisClass, Healing);
|
|
||||||
ATTRIBUTE_ACCESSORS(ThisClass, Damage);
|
|
||||||
|
|
||||||
// Delegate when health changes due to damage/healing, some information may be missing on the client
|
|
||||||
mutable FOLSAttributeEventNativeDelegate OnHealthChanged;
|
|
||||||
|
|
||||||
// Delegate when max health changes
|
|
||||||
mutable FOLSAttributeEventNativeDelegate OnMaxHealthChanged;
|
|
||||||
|
|
||||||
// Delegate to broadcast when the health attribute reaches zero
|
|
||||||
mutable FOLSAttributeEventNativeDelegate OnOutOfHealth;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void OnRep_Health(const FGameplayAttributeData& oldValue);
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void OnRep_MaxHealth(const FGameplayAttributeData& OldValue);
|
|
||||||
|
|
||||||
virtual bool PreGameplayEffectExecute(FGameplayEffectModCallbackData& data) override;
|
|
||||||
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
|
|
||||||
|
|
||||||
virtual void PreAttributeBaseChange(const FGameplayAttribute& attribute, float& newValue) const override;
|
|
||||||
virtual void PreAttributeChange(const FGameplayAttribute& attribute, float& newValue) override;
|
|
||||||
virtual void PostAttributeChange(const FGameplayAttribute& attribute, float oldValue, float newValue) override;
|
|
||||||
|
|
||||||
void ClampAttribute(const FGameplayAttribute& attribute, float& outNewValue) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
|
||||||
// The current health attribute. The health will be capped by the max health attribute. Health is hidden from modifiers so only executions can modify it.
|
|
||||||
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = "OLS|Health", Meta = (HideFromModifiers, AllowPrivateAccess = true))
|
|
||||||
FGameplayAttributeData Health;
|
|
||||||
|
|
||||||
// The current max health attribute. Max health is an attribute since gameplay effects can modify it.
|
|
||||||
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth, Category = "OLS|Health", Meta = (AllowPrivateAccess = true))
|
|
||||||
FGameplayAttributeData MaxHealth;
|
|
||||||
|
|
||||||
// Used to track when the health reaches 0.
|
|
||||||
uint8 bIsOutOfHealth : 1 = false;
|
|
||||||
|
|
||||||
// Store the health before any changes
|
|
||||||
float MaxHealthBeforeAttributeChange = 0.f;
|
|
||||||
float HealthBeforeAttributeChange = 0.f
|
|
||||||
;
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Meta Attribute (please keep attributes that aren't 'stateful' below
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Incoming healing. This is mapped directly to +Health
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category="Lyra|Health", Meta=(AllowPrivateAccess=true))
|
|
||||||
FGameplayAttributeData Healing;
|
|
||||||
|
|
||||||
// Incoming damage. This is mapped directly to -Health
|
|
||||||
UPROPERTY(BlueprintReadOnly, Category="Lyra|Health", Meta=(HideFromModifiers, AllowPrivateAccess=true))
|
|
||||||
FGameplayAttributeData Damage;
|
|
||||||
};
|
|
@ -1,38 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "GameplayTagContainer.h"
|
|
||||||
#include "OLSVerbMessage.generated.h"
|
|
||||||
|
|
||||||
// Represents a generic message of the form Instigator Verb Target (in Context, with Magnitude)
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct FOLSVerbMessage
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite, Category=Gameplay)
|
|
||||||
FGameplayTag Verb = FGameplayTag::EmptyTag;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite, Category=Gameplay)
|
|
||||||
TObjectPtr<class UObject> Instigator = nullptr;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite, Category=Gameplay)
|
|
||||||
TObjectPtr<class UObject> Target = nullptr;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite, Category=Gameplay)
|
|
||||||
FGameplayTagContainer InstigatorTags;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite, Category=Gameplay)
|
|
||||||
FGameplayTagContainer TargetTags;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite, Category=Gameplay)
|
|
||||||
FGameplayTagContainer ContextTags;
|
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadWrite, Category=Gameplay)
|
|
||||||
double Magnitude = 1.0;
|
|
||||||
|
|
||||||
// Returns a debug string representation of this message
|
|
||||||
OLS_API FString ToString() const;
|
|
||||||
};
|
|
@ -1,30 +0,0 @@
|
|||||||
// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
|
||||||
#include "OLSVerbMessageHelpers.generated.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class OLS_API UOLSVerbMessageHelpers : public UBlueprintFunctionLibrary
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Lyra")
|
|
||||||
static class APlayerState* GetPlayerStateFromObject(UObject* object);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Lyra")
|
|
||||||
static class APlayerController* GetPlayerControllerFromObject(UObject* object);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Lyra")
|
|
||||||
static struct FGameplayCueParameters VerbMessageToCueParameters(const struct FOLSVerbMessage& message);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Lyra")
|
|
||||||
static struct FOLSVerbMessage CueParametersToVerbMessage(const FGameplayCueParameters& params);
|
|
||||||
};
|
|
@ -85,14 +85,4 @@ private:
|
|||||||
|
|
||||||
UPROPERTY(Replicated)
|
UPROPERTY(Replicated)
|
||||||
FOLSGameplayTagStackContainer StatTags;
|
FOLSGameplayTagStackContainer StatTags;
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Health attribute set used by this actor.
|
|
||||||
UPROPERTY()
|
|
||||||
TObjectPtr<const class UOLSHealthAttributeSet> HealthSet = nullptr;
|
|
||||||
|
|
||||||
// Combat attribute set used by this actor.
|
|
||||||
UPROPERTY()
|
|
||||||
TObjectPtr<const class UOLSCombatAttributeSet> CombatSet = nullptr;
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user