Misc Fixes
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
using System.IO;
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class Elistria_Calling : ModuleRules
|
||||
@@ -17,6 +18,10 @@ public class Elistria_Calling : ModuleRules
|
||||
|
||||
// Uncomment if you are using online features
|
||||
PrivateDependencyModuleNames.Add("OnlineSubsystem");
|
||||
|
||||
PublicIncludePaths.AddRange(new string[]{Path.Combine(ModuleDirectory, "Public")});
|
||||
|
||||
PrivateIncludePaths.AddRange(new string[]{Path.Combine(ModuleDirectory, "Private")});
|
||||
|
||||
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Attributes/HealthAttributeSet.h"
|
||||
|
||||
|
||||
UHealthAttributeSet::UHealthAttributeSet()
|
||||
{
|
||||
InitHealth(100.0f);
|
||||
InitMaxHealth(100.0f);
|
||||
}
|
||||
|
||||
void UHealthAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||
{
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(UHealthAttributeSet, Health, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(UHealthAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
|
||||
}
|
||||
|
||||
void UHealthAttributeSet::OnRep_Health(const FGameplayAttributeData& OldValue)
|
||||
{
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(UHealthAttributeSet, Health, OldValue);
|
||||
const float OldHealth = OldValue.GetCurrentValue();
|
||||
const float NewHealth = GetHealth();
|
||||
OnHealthChanged.Broadcast(this, OldHealth, NewHealth);
|
||||
}
|
||||
|
||||
void UHealthAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldValue)
|
||||
{
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(UHealthAttributeSet, MaxHealth, OldValue);
|
||||
const float OldMaxHealth = OldValue.GetCurrentValue();
|
||||
const float NewMaxHealth = GetMaxHealth();
|
||||
OnMaxHealthChanged.Broadcast(this, OldMaxHealth, NewMaxHealth);
|
||||
}
|
||||
void UHealthAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
|
||||
{
|
||||
Super::PostGameplayEffectExecute(Data);
|
||||
if (Data.EvaluatedData.Attribute == GetHealthAttribute())
|
||||
{
|
||||
SetHealth(FMath::Clamp(GetHealth(), 0.0f, GetMaxHealth()));
|
||||
}
|
||||
if (Data.EvaluatedData.Attribute == GetDamageAttribute())
|
||||
{
|
||||
const float DamageValue = GetDamage();
|
||||
const float OldHealth = GetHealth();
|
||||
const float HealthMax = GetMaxHealth();
|
||||
const float NewHealth = FMath::Clamp(OldHealth-DamageValue,0.0f, HealthMax);
|
||||
if (OldHealth!=NewHealth)
|
||||
{
|
||||
SetHealth(NewHealth);
|
||||
}
|
||||
SetDamage(0.0f);
|
||||
}
|
||||
if (Data.EvaluatedData.Attribute == GetHealthAttribute())
|
||||
{
|
||||
const float HealValue = GetHeal();
|
||||
const float OldHealth = GetHealth();
|
||||
const float HealthMax = GetMaxHealth();
|
||||
const float NewHealth = FMath::Clamp(OldHealth+HealValue,0.0f, HealthMax);
|
||||
if (OldHealth!=NewHealth)
|
||||
{
|
||||
SetHealth(NewHealth);
|
||||
}
|
||||
SetHeal(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Attributes/LevelAttributeSet.h"
|
||||
|
||||
ULevelAttributeSet::ULevelAttributeSet()
|
||||
{
|
||||
InitLevel(1.0f);
|
||||
InitXP(0.0f);
|
||||
InitXPToNextLevel(ComputeXPForLevel(1));
|
||||
}
|
||||
|
||||
void ULevelAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||
{
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(ULevelAttributeSet, Level, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(ULevelAttributeSet, XP, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(ULevelAttributeSet, XPToNextLevel, COND_None, REPNOTIFY_Always);
|
||||
}
|
||||
|
||||
float ULevelAttributeSet::ComputeXPForLevel(int32 InLevel) const
|
||||
{
|
||||
return 100.f + 50.f * FMath::Max(0, InLevel - 1);
|
||||
}
|
||||
|
||||
|
||||
void ULevelAttributeSet::OnRep_Level(const FGameplayAttributeData& OldValue)
|
||||
{
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(ULevelAttributeSet, Level, OldValue);
|
||||
UE_LOG(LogTemp, Log, TEXT("Level changed from %f to %f"), OldValue.GetCurrentValue(), Level.GetCurrentValue());
|
||||
OnLevelChanged.Broadcast(this, OldValue.GetCurrentValue(), Level.GetCurrentValue());
|
||||
}
|
||||
|
||||
void ULevelAttributeSet::OnRep_XP(const FGameplayAttributeData& OldValue)
|
||||
{
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(ULevelAttributeSet, XP, OldValue);
|
||||
UE_LOG( LogTemp, Log, TEXT("XP changed from %f to %f"), OldValue.GetCurrentValue(), XP.GetCurrentValue());
|
||||
OnXPChanged.Broadcast(this, OldValue.GetCurrentValue(), XP.GetCurrentValue());
|
||||
}
|
||||
|
||||
void ULevelAttributeSet::OnRep_XPToNextLevel(const FGameplayAttributeData& OldValue)
|
||||
{
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(ULevelAttributeSet, XPToNextLevel, OldValue);
|
||||
OnXPToNextLevelChanged.Broadcast(this, OldValue.GetCurrentValue(), XPToNextLevel.GetCurrentValue());
|
||||
}
|
||||
void ULevelAttributeSet::ConsumeXPGain()
|
||||
{
|
||||
const float Gain = GetXPGain();
|
||||
if (Gain > 0.0f)
|
||||
{
|
||||
SetXP(GetXP() + Gain);
|
||||
SetXPGain(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void ULevelAttributeSet::TryProcessLevelUp()
|
||||
{
|
||||
bool Leveled = false;
|
||||
int32 LevelsGained = 0;
|
||||
float CurrentXP = GetXP();
|
||||
float Needed = GetXPToNextLevel();
|
||||
int32 CurrentLevelInt = FMath::FloorToInt(GetLevel());
|
||||
|
||||
while (CurrentXP>= Needed)
|
||||
{
|
||||
CurrentXP -= Needed;
|
||||
CurrentLevelInt+=1;
|
||||
Needed = ComputeXPForLevel(CurrentLevelInt);
|
||||
Leveled = true;
|
||||
}
|
||||
if (Leveled)
|
||||
{
|
||||
SetLevel(static_cast<float>(CurrentLevelInt));
|
||||
SetXPToNextLevel(Needed);
|
||||
}
|
||||
SetXP(FMath::Max(0.0f, CurrentXP));
|
||||
if (Leveled)
|
||||
{
|
||||
HandleLevelUp(LevelsGained);
|
||||
}
|
||||
}
|
||||
|
||||
void ULevelAttributeSet::HandleLevelUp(int32 LevelsGained)
|
||||
{
|
||||
// This function can be expanded to include additional logic when a level-up occurs.
|
||||
// For example, you might want to notify other systems, play a sound, etc.
|
||||
|
||||
OnLevelChanged.Broadcast(this, GetLevel() - LevelsGained, GetLevel());
|
||||
}
|
||||
|
||||
void ULevelAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
|
||||
{
|
||||
Super::PostGameplayEffectExecute(Data);
|
||||
if (Data.EvaluatedData.Attribute == GetXPAttribute())
|
||||
{
|
||||
ConsumeXPGain();
|
||||
}
|
||||
|
||||
if (Data.EvaluatedData.Attribute == GetXPGainAttribute()||Data.EvaluatedData.Attribute == GetXPAttribute())
|
||||
{
|
||||
SetXP(FMath::Max(0.0f, GetXP()));
|
||||
TryProcessLevelUp();
|
||||
}
|
||||
|
||||
if (Data.EvaluatedData.Attribute == GetLevelAttribute())
|
||||
{
|
||||
const int32 Lvl = FMath::Max(1,FMath::FloorToInt(GetLevel()));
|
||||
SetLevel(static_cast<float>(Lvl));
|
||||
SetXP(FMath::Clamp(GetXP(),0.0f,ComputeXPForLevel(Lvl)));
|
||||
SetXPToNextLevel(ComputeXPForLevel(Lvl));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "ManaAttributeSet.h"
|
||||
#include "Attributes/ManaAttributeSet.h"
|
||||
|
||||
UManaAttributeSet::UManaAttributeSet()
|
||||
{
|
||||
@@ -51,7 +51,7 @@ void UManaAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallba
|
||||
}
|
||||
SetCost(0.0f);
|
||||
}
|
||||
if (Data.EvaluatedData.Attribute==GetMaxManaAttribute())
|
||||
if (Data.EvaluatedData.Attribute==GetRestoreAttribute())
|
||||
{
|
||||
const float RestoreValue = GetMaxMana();
|
||||
const float OldMana = GetMana();
|
||||
@@ -0,0 +1,62 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "Attributes/StaminaAttributeSet.h"
|
||||
|
||||
UStaminaAttributeSet::UStaminaAttributeSet()
|
||||
{
|
||||
InitStamina(100.0f);
|
||||
InitMaxStamina(100.0f);
|
||||
}
|
||||
void UStaminaAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
|
||||
{
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(UStaminaAttributeSet, Stamina, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(UStaminaAttributeSet, MaxStamina, COND_None, REPNOTIFY_Always);
|
||||
}
|
||||
|
||||
void UStaminaAttributeSet::OnRep_Stamina(const FGameplayAttributeData& OldValue)
|
||||
{
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(UStaminaAttributeSet, Stamina, OldValue);
|
||||
const float OldStamina = OldValue.GetCurrentValue();
|
||||
const float NewStamina = GetStamina();
|
||||
OnStaminaChanged.Broadcast(this, OldStamina, NewStamina);
|
||||
}
|
||||
void UStaminaAttributeSet::OnRep_MaxStamina(const FGameplayAttributeData& OldValue)
|
||||
{
|
||||
GAMEPLAYATTRIBUTE_REPNOTIFY(UStaminaAttributeSet, MaxStamina, OldValue);
|
||||
const float OldMaxStamina = OldValue.GetCurrentValue();
|
||||
const float NewMaxStamina = GetMaxStamina();
|
||||
OnMaxStaminaChanged.Broadcast(this, OldMaxStamina, NewMaxStamina);
|
||||
}
|
||||
void UStaminaAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
|
||||
{
|
||||
Super::PostGameplayEffectExecute(Data);
|
||||
if (Data.EvaluatedData.Attribute == GetStaminaAttribute())
|
||||
{
|
||||
SetStamina(FMath::Clamp(GetStamina(), 0.0f, GetMaxStamina()));
|
||||
}
|
||||
if (Data.EvaluatedData.Attribute == GetDrainAttribute())
|
||||
{
|
||||
const float DrainValue = GetDrain();
|
||||
const float OldStamina = GetStamina();
|
||||
const float StaminaMax = GetMaxStamina();
|
||||
const float NewStamina = FMath::Clamp(OldStamina-DrainValue,0.0f, StaminaMax);
|
||||
if (OldStamina!=NewStamina)
|
||||
{
|
||||
SetStamina(NewStamina);
|
||||
}
|
||||
SetDrain(0.0f);
|
||||
}
|
||||
if (Data.EvaluatedData.Attribute==GetRestoreAttribute())
|
||||
{
|
||||
const float RestoreValue = GetRestore();
|
||||
const float OldStamina = GetStamina();
|
||||
const float StaminaMax = GetMaxStamina();
|
||||
const float NewStamina = FMath::Clamp(OldStamina+RestoreValue,0.0f, StaminaMax);
|
||||
if (OldStamina!=NewStamina)
|
||||
{
|
||||
SetStamina(NewStamina);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,59 +3,54 @@
|
||||
|
||||
#include "ElistriaAbilitySystemComponent.h"
|
||||
|
||||
#include "NativeGameplayTags.h"
|
||||
#include "PlayerGameplayAbilitiesDataAsset.h"
|
||||
|
||||
void UElistriaAbilitySystemComponent::ServerActivateAbilityByInputID_Implementation(FGameplayAbilitySpecHandle Handle,int32 InputID)
|
||||
{
|
||||
TryActivateAbility(Handle);
|
||||
}
|
||||
|
||||
UE_DEFINE_GAMEPLAY_TAG_STATIC(TAG_Input_Confirm, "Input.Confirm");
|
||||
UE_DEFINE_GAMEPLAY_TAG_STATIC(TAG_Input_Cancel, "Input.Cancel");
|
||||
void UElistriaAbilitySystemComponent::GrantAbilitiesFromDataAsset(const UPlayerGameplayAbilitiesDataAsset* AbilitiesDataAsset)
|
||||
{
|
||||
if (!AbilitiesDataAsset) return;
|
||||
if (!AbilitiesDataAsset) return;
|
||||
for (const FGameplayInputAbilityInfo& AbilityInfo : AbilitiesDataAsset->GetMappings())
|
||||
{
|
||||
if (!AbilityInfo.IsValid()||!AbilityInfo.bAutoGive) continue;
|
||||
|
||||
for (const FGameplayInputAbilityInfo& AbilityInfo : AbilitiesDataAsset->GetInputAbilities())
|
||||
{
|
||||
if (AbilityInfo.IsValid())
|
||||
FGameplayAbilitySpec Spec(AbilityInfo.AbilityClass,1,INDEX_NONE);
|
||||
|
||||
FGameplayAbilitySpecHandle Handle = GiveAbility(Spec);
|
||||
|
||||
if (FGameplayAbilitySpec* Found = FindAbilitySpecFromHandle(Handle))
|
||||
{
|
||||
FGameplayAbilitySpec AbilitySpec(AbilityInfo.AbilityClass, 1, AbilityInfo.InputID);
|
||||
FGameplayAbilitySpecHandle SpecHandle = GiveAbility(AbilitySpec);
|
||||
InputIDToAbilitySpecHandleMap.Add(AbilityInfo.InputID, SpecHandle);
|
||||
if (AbilityInfo.InputTag.IsValid()&&!Found->DynamicAbilityTags.HasTagExact(AbilityInfo.InputTag))
|
||||
{
|
||||
Found->DynamicAbilityTags.AddTagFast(AbilityInfo.InputTag);
|
||||
MarkAbilitySpecDirty(*Found);
|
||||
}
|
||||
TagToSpecHandleMap.Add(AbilityInfo.InputTag, Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UElistriaAbilitySystemComponent::AbilityLocalInputPressed(int32 InputID)
|
||||
{
|
||||
if (FGameplayAbilitySpecHandle* HandlePtr = SlotToAbilityHandleMap.Find(InputID))
|
||||
{
|
||||
if (GetOwnerRole() < ROLE_Authority)
|
||||
{
|
||||
ServerActivateAbilityByInputID(*HandlePtr, InputID);
|
||||
}
|
||||
TryActivateAbility(*HandlePtr);
|
||||
}
|
||||
}
|
||||
|
||||
void UElistriaAbilitySystemComponent::EquipAbility(TSubclassOf<UGameplayAbility> NewAbility, int32 SlotIndex)
|
||||
{
|
||||
if (!NewAbility) return;
|
||||
UnequipAbility(SlotIndex);
|
||||
|
||||
FGameplayAbilitySpec Spec(NewAbility,1,SlotIndex);
|
||||
FGameplayAbilitySpecHandle SpecHandle = GiveAbility(Spec);
|
||||
SlotToAbilityHandleMap.Add(SlotIndex, SpecHandle);
|
||||
|
||||
}
|
||||
OnAbilitiesChanged.Broadcast(this);
|
||||
}
|
||||
|
||||
void UElistriaAbilitySystemComponent::UnequipAbility(int32 SlotIndex)
|
||||
void UElistriaAbilitySystemComponent::HandleInputTag(ETriggerEvent EventType, FGameplayTag InputTag)
|
||||
{
|
||||
if (FGameplayAbilitySpecHandle* HandlePtr = SlotToAbilityHandleMap.Find(SlotIndex))
|
||||
if (!InputTag.IsValid()) return;
|
||||
|
||||
if (InputTag == TAG_Input_Confirm)
|
||||
{
|
||||
ClearAbility(*HandlePtr);
|
||||
SlotToAbilityHandleMap.Remove(SlotIndex);
|
||||
|
||||
OnAbilitiesChanged.Broadcast(this);
|
||||
TargetConfirm();
|
||||
return;
|
||||
}
|
||||
if (InputTag == TAG_Input_Cancel)
|
||||
{
|
||||
TargetCancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (EventType == ETriggerEvent::Started||EventType == ETriggerEvent::Triggered)
|
||||
{
|
||||
FGameplayTagContainer Tags(InputTag);
|
||||
TryActivateAbilitiesByTag(Tags, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "HealthAttributeSet.h"
|
||||
#include "ElistriaAttributeSetBase.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
void UElistriaEnhancedInputComponent::ClearAbilityBindings()
|
||||
{
|
||||
for (uint32 Handle : AbilityActionBindings)
|
||||
for (int32 Handle : AbilityActionBindings)
|
||||
{
|
||||
RemoveBindingByHandle(Handle);
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "MagickPlayerController.h"
|
||||
|
||||
#include "ElistriaEnhancedInputComponent.h"
|
||||
#include "MagickPlayerState.h"
|
||||
|
||||
void AMagickPlayerController::OnPossess(APawn *InPawn)
|
||||
{
|
||||
Super::OnPossess(InPawn);
|
||||
UE_LOG(LogTemp, Display, TEXT("OnPossess"));
|
||||
AMagickPlayerState* PS = GetPlayerState<AMagickPlayerState>();
|
||||
UElistriaAbilitySystemComponent* ASC = PS ? PS->GetAbilitySystemComponent() : nullptr;
|
||||
if (PS)
|
||||
{
|
||||
PS->SetupAbilityActorInfo();
|
||||
if (ASC)
|
||||
{
|
||||
ASC->OnAbilitiesChanged.AddDynamic(this,&AMagickPlayerController::OnAbilitiesChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::OnAbilitiesChanged(UElistriaAbilitySystemComponent* ASC)
|
||||
{
|
||||
RebindAbilityInputs();
|
||||
}
|
||||
|
||||
void AMagickPlayerController::SetupInputComponent()
|
||||
{
|
||||
Super::SetupInputComponent();
|
||||
if (UElistriaEnhancedInputComponent* EIC = Cast<UElistriaEnhancedInputComponent>(InputComponent))
|
||||
{
|
||||
if (InputAbilitiesDataAsset)
|
||||
{
|
||||
EIC->BindAbilityActions(InputAbilitiesDataAsset, this, &AMagickPlayerController::AbilityInputPressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::AbilityInputPressed(int32 InputID)
|
||||
{
|
||||
if (AMagickPlayerState* PS = GetPlayerState<AMagickPlayerState>())
|
||||
{
|
||||
if (UElistriaAbilitySystemComponent* ASC = PS ? PS->GetAbilitySystemComponent() : nullptr)
|
||||
{
|
||||
ASC->AbilityLocalInputPressed(InputID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
if (UInputMappingContext* IMC = InputMappingContext)
|
||||
{
|
||||
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
|
||||
{
|
||||
Subsystem->AddMappingContext(IMC, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::RebindAbilityInputs()
|
||||
{
|
||||
if (UElistriaEnhancedInputComponent* EIC = Cast<UElistriaEnhancedInputComponent>(InputComponent))
|
||||
{
|
||||
EIC -> ClearAbilityBindings();
|
||||
if (InputAbilitiesDataAsset)
|
||||
{
|
||||
EIC->BindAbilityActions(InputAbilitiesDataAsset,this,&AMagickPlayerController::AbilityInputPressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "Player/MagickPlayerController.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "InputMappingContext.h"
|
||||
#include "PlayerGameplayAbilitiesDataAsset.h"
|
||||
#include "ElistriaEnhancedInputComponent.h"
|
||||
#include "ElistriaAbilitySystemComponent.h"
|
||||
#include "Player/MagickPlayerState.h"
|
||||
|
||||
void AMagickPlayerController::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
if (InputMappingContext)
|
||||
{
|
||||
if (UEnhancedInputLocalPlayerSubsystem* Sub = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
|
||||
{
|
||||
Sub->AddMappingContext(InputMappingContext,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::OnPossess(APawn *InPawn)
|
||||
{
|
||||
Super::OnPossess(InPawn);
|
||||
if (AMagickPlayerState* PS = GetPlayerState<AMagickPlayerState>())
|
||||
{
|
||||
if (UElistriaAbilitySystemComponent* ASC = PS->GetAbilitySystemComponent())
|
||||
{
|
||||
PS->SetupAbilityActorInfo();
|
||||
ASC->OnAbilitiesChanged.AddDynamic(this, &AMagickPlayerController::OnASCGranted);
|
||||
if (InputAbilitiesDataAsset)
|
||||
{
|
||||
ASC->GrantAbilitiesFromDataAsset(InputAbilitiesDataAsset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::OnAbilitiesChanged(UElistriaAbilitySystemComponent* ASC)
|
||||
{
|
||||
RebindAbilityInputs();
|
||||
}
|
||||
|
||||
void AMagickPlayerController::SetupInputComponent()
|
||||
{
|
||||
Super::SetupInputComponent();
|
||||
RebindAbilityInputs();
|
||||
}
|
||||
|
||||
void AMagickPlayerController::OnASCGranted(UElistriaAbilitySystemComponent* ASC)
|
||||
{
|
||||
RebindAbilityInputs();
|
||||
}
|
||||
|
||||
|
||||
void AMagickPlayerController::RebindAbilityInputs()
|
||||
{
|
||||
if (UElistriaEnhancedInputComponent* EIC = Cast<UElistriaEnhancedInputComponent>(InputComponent))
|
||||
{
|
||||
EIC->ClearAbilityBindings();
|
||||
if (InputAbilitiesDataAsset)
|
||||
{
|
||||
EIC->BindAbilityActionsByTag(InputAbilitiesDataAsset,this,&AMagickPlayerController::HandleInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::AbilityInputTag(const FInputActionInstance& Instance, FGameplayTag InputTag)
|
||||
{
|
||||
if (!InputTag.IsValid()) return;
|
||||
|
||||
if (AMagickPlayerState* PS = GetPlayerState<AMagickPlayerState>())
|
||||
{
|
||||
if (UElistriaAbilitySystemComponent* ASC = PS->GetAbilitySystemComponent())
|
||||
{
|
||||
ASC->HandleInputTag(Instance.GetTriggerEvent(), InputTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AMagickPlayerController::HandleInput(const FInputActionInstance& Instance, FGameplayTag InputTag)
|
||||
{
|
||||
if (!InputTag.IsValid()) return;
|
||||
|
||||
if (AMagickPlayerState* PS = GetPlayerState<AMagickPlayerState>())
|
||||
{
|
||||
if (UElistriaAbilitySystemComponent* ASC = PS->GetAbilitySystemComponent())
|
||||
{
|
||||
ASC->HandleInputTag(Instance.GetTriggerEvent(), InputTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "MagickPlayerState.h"
|
||||
|
||||
|
||||
|
||||
#include "Player/MagickPlayerState.h"
|
||||
#include "Player/MagickPlayerController.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
AMagickPlayerState::AMagickPlayerState()
|
||||
{
|
||||
ElistriaAbilitySystemComponent = CreateDefaultSubobject<UElistriaAbilitySystemComponent>(TEXT("AbilitySystem"));
|
||||
ManaSet = CreateDefaultSubobject<UManaAttributeSet>(TEXT("ManaSet"));
|
||||
HealthSet = CreateDefaultSubobject<UHealthAttributeSet>(TEXT("HealthSet"));
|
||||
StaminaSet = CreateDefaultSubobject<UStaminaAttributeSet>(TEXT("StaminaSet"));
|
||||
LevelSet = CreateDefaultSubobject<ULevelAttributeSet>(TEXT("XPSet"));
|
||||
}
|
||||
|
||||
UElistriaAbilitySystemComponent* AMagickPlayerState::GetAbilitySystemComponent() const
|
||||
@@ -30,6 +31,8 @@ void AMagickPlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& O
|
||||
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(AMagickPlayerState, ElistriaAbilitySystemComponent, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(AMagickPlayerState, ManaSet, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(AMagickPlayerState, HealthSet, COND_None, REPNOTIFY_Always);
|
||||
DOREPLIFETIME_CONDITION_NOTIFY(AMagickPlayerState, StaminaSet, COND_None, REPNOTIFY_Always);
|
||||
}
|
||||
|
||||
void AMagickPlayerState::SetupAbilityActorInfo()
|
||||
@@ -54,6 +57,18 @@ void AMagickPlayerState::SetupAbilityActorInfo()
|
||||
{
|
||||
ElistriaAbilitySystemComponent->AddAttributeSetSubobject(ManaSet.Get());
|
||||
}
|
||||
if (HealthSet)
|
||||
{
|
||||
ElistriaAbilitySystemComponent->AddAttributeSetSubobject(HealthSet.Get());
|
||||
}
|
||||
if (StaminaSet)
|
||||
{
|
||||
ElistriaAbilitySystemComponent->AddAttributeSetSubobject(StaminaSet.Get());
|
||||
}
|
||||
if (LevelSet)
|
||||
{
|
||||
ElistriaAbilitySystemComponent->AddAttributeSetSubobject(LevelSet.Get());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +1,4 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "PlayerGameplayAbilitiesDataAsset.h"
|
||||
|
||||
UPlayerGameplayAbilitiesDataAsset::UPlayerGameplayAbilitiesDataAsset(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
// Constructor implementation
|
||||
}
|
||||
|
||||
const TSet<FGameplayInputAbilityInfo>& UPlayerGameplayAbilitiesDataAsset::GetInputAbilities() const
|
||||
{
|
||||
return InputAbilities;
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
void UPlayerGameplayAbilitiesDataAsset::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
|
||||
const FProperty* Property = PropertyChangedEvent.Property;
|
||||
if (Property && Property->GetName()==GET_MEMBER_NAME_CHECKED(UPlayerGameplayAbilitiesDataAsset, InputAbilities)&& !InputAbilities.IsEmpty())
|
||||
{
|
||||
TArray<FGameplayInputAbilityInfo> InputAbilitiesArray = InputAbilities.Array();
|
||||
for (int32 i = InputAbilitiesArray.Num() - 1; i >= 0; i--)
|
||||
{
|
||||
const int32 PrevIndex = i - 1;
|
||||
if (InputAbilitiesArray[i]==InputAbilitiesArray[PrevIndex])
|
||||
{
|
||||
InputAbilitiesArray.RemoveAtSwap(i);
|
||||
}
|
||||
}
|
||||
InputAbilities.Reset();
|
||||
|
||||
for (int32 i=0; i<InputAbilitiesArray.Num(); i++)
|
||||
{
|
||||
FGameplayInputAbilityInfo& AbilityInfo = InputAbilitiesArray[i];
|
||||
AbilityInfo.InputID = i;
|
||||
InputAbilities.Add(AbilityInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#include "PlayerGameplayAbilitiesDataAsset.h"
|
||||
@@ -0,0 +1,57 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "AttributeSet.h"
|
||||
#include "ElistriaAttributeSetBase.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
#include "GameplayEffectExtension.h"
|
||||
#include "HealthAttributeSet.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API UHealthAttributeSet : public UElistriaAttributeSetBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UHealthAttributeSet();
|
||||
|
||||
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
|
||||
|
||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||
|
||||
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,ReplicatedUsing=OnRep_Health)
|
||||
FGameplayAttributeData Health;
|
||||
|
||||
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,ReplicatedUsing=OnRep_MaxHealth)
|
||||
FGameplayAttributeData MaxHealth;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FGameplayAttributeData Damage;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FGameplayAttributeData Heal;
|
||||
|
||||
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, Health)
|
||||
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, MaxHealth)
|
||||
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, Damage)
|
||||
ATTRIBUTE_ACCESSORS(UHealthAttributeSet, Heal)
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_Health(const FGameplayAttributeData& OldValue);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_MaxHealth(const FGameplayAttributeData& OldValue);
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FAttributeChangedEvent OnHealthChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FAttributeChangedEvent OnMaxHealthChanged;
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "ElistriaAttributeSetBase.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
#include "GameplayEffectExtension.h"
|
||||
#include "ManaAttributeSet.h"
|
||||
#include "LevelAttributeSet.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API ULevelAttributeSet : public UElistriaAttributeSetBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
ULevelAttributeSet();
|
||||
|
||||
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
|
||||
|
||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_Level)
|
||||
FGameplayAttributeData Level;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_XP)
|
||||
FGameplayAttributeData XP;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing = OnRep_XPToNextLevel)
|
||||
FGameplayAttributeData XPToNextLevel;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FGameplayAttributeData XPGain;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FGameplayAttributeData XPLoss;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FGameplayAttributeData MaxLevel;
|
||||
|
||||
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XP)
|
||||
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, Level)
|
||||
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, MaxLevel)
|
||||
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XPToNextLevel)
|
||||
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XPGain)
|
||||
ATTRIBUTE_ACCESSORS(ULevelAttributeSet, XPLoss)
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_Level(const FGameplayAttributeData& OldValue);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_XP(const FGameplayAttributeData& OldValue);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_XPToNextLevel(const FGameplayAttributeData& OldValue);
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FAttributeChangedEvent OnLevelChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FAttributeChangedEvent OnXPChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FAttributeChangedEvent OnXPToNextLevelChanged;
|
||||
|
||||
protected:
|
||||
float ComputeXPForLevel(int32 InLevel) const;
|
||||
void HandleLevelUp(int32 LevelsGained);
|
||||
void ConsumeXPGain();
|
||||
void TryProcessLevelUp();
|
||||
};
|
||||
@@ -3,8 +3,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AttributeSet.h"
|
||||
#include "AbilitySystemComponent.h"
|
||||
#include "ElistriaAttributeSetBase.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
#include "GameplayEffectExtension.h"
|
||||
#include "ManaAttributeSet.generated.h"
|
||||
@@ -13,16 +13,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAttributeChangedEvent, UAttributeSet*, AttributeSet, float, OldValue, float, NewValue);
|
||||
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API UManaAttributeSet : public UAttributeSet
|
||||
class ELISTRIA_CALLING_API UManaAttributeSet : public UElistriaAttributeSetBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AttributeSet.h"
|
||||
#include "ElistriaAttributeSetBase.h"
|
||||
#include "HealthAttributeSet.h"
|
||||
#include "StaminaAttributeSet.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API UStaminaAttributeSet : public UElistriaAttributeSetBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UStaminaAttributeSet();
|
||||
|
||||
virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
|
||||
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_Stamina)
|
||||
FGameplayAttributeData Stamina;
|
||||
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, Stamina)
|
||||
|
||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_MaxStamina)
|
||||
FGameplayAttributeData MaxStamina;
|
||||
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, MaxStamina)
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FGameplayAttributeData Drain;
|
||||
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, Drain)
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
FGameplayAttributeData Restore;
|
||||
ATTRIBUTE_ACCESSORS(UStaminaAttributeSet, Restore)
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_Stamina(const FGameplayAttributeData& OldValue);
|
||||
|
||||
UFUNCTION()
|
||||
void OnRep_MaxStamina(const FGameplayAttributeData& OldValue);
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FAttributeChangedEvent OnStaminaChanged;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FAttributeChangedEvent OnMaxStaminaChanged;
|
||||
};
|
||||
@@ -11,35 +11,36 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class UPlayerGameplayAbilitiesDataAsset;
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnASCGrantedInputAbilties, UElistriaAbilitySystemComponent*, ASC);
|
||||
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API UElistriaAbilitySystemComponent : public UAbilitySystemComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(Server, Reliable)
|
||||
void ServerActivateAbilityByInputID(FGameplayAbilitySpecHandle Handle, int32 InputID);
|
||||
UPROPERTY(BlueprintAssignable, Category="AbilitySystem")
|
||||
FOnASCGrantedInputAbilties OnGrantedInputAbilties;
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void EquipAbility(TSubclassOf<UGameplayAbility> NewAbility, int32 SlotIndex);
|
||||
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
|
||||
void GrantAbilitiesFromDataAsset(const UPlayerGameplayAbilitiesDataAsset* AbilitiesDataAsset);
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void UnequipAbility(int32 SlotIndex);
|
||||
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
|
||||
void HandleInputTag(ETriggerEvent EventType, FGameplayTag InputTag);
|
||||
|
||||
void RefreshInputBindings();
|
||||
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
|
||||
void ConfirmTargetingInput(){TargetConfirm();}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="AbilitySystem")
|
||||
void CancelTargetingInput(){TargetCancel();}
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAbilitiesChanged, UElistriaAbilitySystemComponent*, ASC);
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FOnAbilitiesChanged OnAbilitiesChanged;
|
||||
|
||||
void GrantAbilitiesFromDataAsset(const UPlayerGameplayAbilitiesDataAsset* AbilitiesDataAsset);
|
||||
virtual void AbilityLocalInputPressed(int32 InputID) override;
|
||||
|
||||
private:
|
||||
TMap<int32, FGameplayAbilitySpecHandle> InputIDToAbilitySpecHandleMap;
|
||||
|
||||
UPROPERTY()
|
||||
TMap<int32, FGameplayAbilitySpecHandle> SlotToAbilityHandleMap;
|
||||
|
||||
void ServerActivateAbilityByInputID_Implementation(FGameplayAbilitySpecHandle Handle, int32 InputID);
|
||||
TMap<FGameplayTag, FGameplayAbilitySpecHandle> TagToSpecHandleMap;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AttributeSet.h"
|
||||
#include "ElistriaAttributeSetBase.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
|
||||
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FAttributeChangedEvent, UAttributeSet*, AttributeSet, float, OldValue, float, NewValue);
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API UElistriaAttributeSetBase : public UAttributeSet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
};
|
||||
@@ -14,26 +14,42 @@ UCLASS()
|
||||
class ELISTRIA_CALLING_API UElistriaEnhancedInputComponent : public UEnhancedInputComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
template<class UserClass, typename FuncType>
|
||||
void BindAbilityActions(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, FuncType Func);
|
||||
|
||||
public:
|
||||
template <class UserClass>
|
||||
void BindAbilityActionsByTag(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object,
|
||||
void (UserClass::*Func)(const FInputActionInstance&, FGameplayTag));
|
||||
UFUNCTION(BlueprintCallable, Category="Input")
|
||||
void ClearAbilityBindings();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
TArray<uint32> AbilityActionBindings;
|
||||
TArray<int32> AbilityActionBindings;
|
||||
};
|
||||
template<class UserClass, typename FuncType>
|
||||
void UElistriaEnhancedInputComponent::BindAbilityActions(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, FuncType Func)
|
||||
template <class UserClass>
|
||||
void UElistriaEnhancedInputComponent::BindAbilityActionsByTag(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, void (UserClass::*Func)(const FInputActionInstance&, FGameplayTag))
|
||||
{
|
||||
if (!InputConfig) return;
|
||||
if (!InputConfig||!Func) return;
|
||||
|
||||
for (const FGameplayInputAbilityInfo& AbilityInfo : InputConfig->GetInputAbilities())
|
||||
static const ETriggerEvent EventsToBind[]={
|
||||
ETriggerEvent::Started,
|
||||
ETriggerEvent::Completed,
|
||||
ETriggerEvent::Canceled,
|
||||
ETriggerEvent::Triggered,
|
||||
ETriggerEvent::Ongoing
|
||||
};
|
||||
for (const FGameplayInputAbilityInfo& Info : InputConfig->AbilityMappings)
|
||||
{
|
||||
if (AbilityInfo.IsValid())
|
||||
if (!Info.IsValid()) continue;
|
||||
|
||||
for (ETriggerEvent Event : EventsToBind)
|
||||
{
|
||||
BindAction(AbilityInfo.InputAction,ETriggerEvent::Triggered,Object,Func,AbilityInfo.InputID);
|
||||
FEnhancedInputActionEventBinding& Binding = BindAction(Info.InputAction,Event,Object,Func,Info.InputTag);
|
||||
AbilityActionBindings.Add(Binding.GetHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AttributeSet.h"
|
||||
#include "HealthAttributeSet.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API UHealthAttributeSet : public UAttributeSet
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
};
|
||||
@@ -7,35 +7,50 @@
|
||||
#include "GameFramework/PlayerController.h"
|
||||
#include "InputMappingContext.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "ElistriaEnhancedInputComponent.h"
|
||||
|
||||
class UPlayerGameplayAbilitiesDataAsset;
|
||||
class UInputMappingContext;
|
||||
class UElistriaEnhancedInputComponent;
|
||||
class UElistriaAbilitySystemComponent;
|
||||
class AMagickPlayerState;
|
||||
struct FInputActionInstance;
|
||||
|
||||
#include "MagickPlayerController.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
UCLASS()
|
||||
class ELISTRIA_CALLING_API AMagickPlayerController : public APlayerController
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
virtual void OnPossess(APawn* InPawn) override;
|
||||
|
||||
public:
|
||||
virtual void SetupInputComponent() override;
|
||||
virtual void OnPossess(APawn* InPawn) override;
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Input")
|
||||
void RebindAbilityInputs();
|
||||
|
||||
UFUNCTION()
|
||||
void OnASCGranted(UElistriaAbilitySystemComponent* ASC);
|
||||
|
||||
UFUNCTION()
|
||||
void HandleInput(const FInputActionInstance& Instance, FGameplayTag InputTag);
|
||||
|
||||
UFUNCTION()
|
||||
void OnAbilitiesChanged(UElistriaAbilitySystemComponent* ASC);
|
||||
|
||||
public:
|
||||
UFUNCTION()
|
||||
void AbilityInputTag(const FInputActionInstance& Instance, FGameplayTag InputTag);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Input")
|
||||
TObjectPtr<UPlayerGameplayAbilitiesDataAsset> InputAbilitiesDataAsset;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Input")
|
||||
TObjectPtr<UInputMappingContext> InputMappingContext;
|
||||
|
||||
virtual void SetupInputComponent() override;
|
||||
|
||||
UFUNCTION()
|
||||
void AbilityInputPressed(int32 InputID);
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
void RebindAbilityInputs();
|
||||
};
|
||||
@@ -6,8 +6,13 @@
|
||||
#include "GameFramework/PlayerState.h"
|
||||
#include "AbilitySystemInterface.h"
|
||||
#include "ElistriaAbilitySystemComponent.h"
|
||||
#include "ManaAttributeSet.h"
|
||||
#include "MagickPlayerController.h"
|
||||
#include "Attributes/ManaAttributeSet.h"
|
||||
#include "Attributes/StaminaAttributeSet.h"
|
||||
#include "Attributes/HealthAttributeSet.h"
|
||||
#include "Attributes/LevelAttributeSet.h"
|
||||
|
||||
class AMagickPlayerController;
|
||||
|
||||
#include "MagickPlayerState.generated.h"
|
||||
|
||||
UCLASS(Config=game)
|
||||
@@ -15,8 +20,6 @@ class ELISTRIA_CALLING_API AMagickPlayerState : public APlayerState, public IAbi
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
public:
|
||||
@@ -34,6 +37,15 @@ protected:
|
||||
UPROPERTY(Replicated)
|
||||
TObjectPtr<class UManaAttributeSet> ManaSet;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TObjectPtr<UStaminaAttributeSet> StaminaSet;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TObjectPtr<UHealthAttributeSet> HealthSet;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TObjectPtr<ULevelAttributeSet> LevelSet;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
@@ -12,43 +12,32 @@
|
||||
*/
|
||||
class UInputAction;
|
||||
|
||||
USTRUCT()
|
||||
USTRUCT(BlueprintType)
|
||||
struct FGameplayInputAbilityInfo
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "GameplayInputAbilityInfo")
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ability")
|
||||
TSubclassOf<UGameplayAbility> AbilityClass;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "GameplayInputAbilityInfo")
|
||||
UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Ability")
|
||||
TObjectPtr<UInputAction> InputAction;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, Category = "GameplayInputAbilityInfo")
|
||||
int32 InputID;
|
||||
UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Ability", meta = (Categories="Input"))
|
||||
FGameplayTag InputTag;
|
||||
|
||||
bool IsValid() const
|
||||
UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Ability")
|
||||
bool bAutoGive = true;
|
||||
|
||||
bool IsValid() const{ return AbilityClass && InputAction && InputTag.IsValid();}
|
||||
|
||||
bool operator==(const FGameplayInputAbilityInfo& Other) const
|
||||
{
|
||||
return AbilityClass && InputAction;
|
||||
return AbilityClass == Other.AbilityClass && InputAction == Other.InputAction && InputTag == Other.InputTag;
|
||||
}
|
||||
|
||||
bool operator==(const FGameplayInputAbilityInfo& other) const
|
||||
{
|
||||
return AbilityClass == other.AbilityClass && InputID == other.InputID;
|
||||
}
|
||||
|
||||
bool operator!=(const FGameplayInputAbilityInfo& other) const
|
||||
{
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
friend uint32 GetTypeHash(const FGameplayInputAbilityInfo& Item)
|
||||
{
|
||||
return HashCombine(GetTypeHash(Item.AbilityClass), Item.InputID);
|
||||
}
|
||||
|
||||
FGameplayInputAbilityInfo()
|
||||
: InputID(INDEX_NONE)
|
||||
{
|
||||
return HashCombine(GetTypeHash(Item.AbilityClass), GetTypeHash(Item.InputTag));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -57,16 +46,44 @@ class ELISTRIA_CALLING_API UPlayerGameplayAbilitiesDataAsset : public UDataAsset
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
UPROPERTY(EditAnywhere, Category = "AbilitySystem")
|
||||
TSet<FGameplayInputAbilityInfo> InputAbilities;
|
||||
|
||||
public:
|
||||
UPlayerGameplayAbilitiesDataAsset(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
|
||||
|
||||
const TSet<FGameplayInputAbilityInfo>& GetInputAbilities() const;
|
||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="AbilitySystem")
|
||||
TArray<FGameplayInputAbilityInfo> AbilityMappings;
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AbilitySystem")
|
||||
void GetAllMappings(TArray<FGameplayInputAbilityInfo>& Out) const { Out = AbilityMappings; }
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AbilitySystem")
|
||||
void AddMapping(const FGameplayInputAbilityInfo& Entry)
|
||||
{
|
||||
if (!Entry.IsValid()) return;
|
||||
|
||||
AbilityMappings.Add(Entry);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "AbilitySystem")
|
||||
void RemoveByTag(FGameplayTag InputTag)
|
||||
{
|
||||
AbilityMappings.RemoveAll([&](const FGameplayInputAbilityInfo& E) { return E.InputTag == InputTag; });
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "AbilitySystem")
|
||||
void FindByTag(FGameplayTag InputTag, TArray<FGameplayInputAbilityInfo>& Out) const
|
||||
{
|
||||
for (const auto& E : AbilityMappings)
|
||||
{
|
||||
if (E.InputTag == InputTag)
|
||||
{
|
||||
Out.Add(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
const TArray<FGameplayInputAbilityInfo>& GetMappings() const { return AbilityMappings; }
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
// Ensure uniqueness (Set already helps). Could add validation if needed.
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user