diff --git a/Elistria_Calling/Config/DefaultEngine.ini b/Elistria_Calling/Config/DefaultEngine.ini index 3ad91ac..80c21cd 100644 --- a/Elistria_Calling/Config/DefaultEngine.ini +++ b/Elistria_Calling/Config/DefaultEngine.ini @@ -32,6 +32,9 @@ r.DefaultFeature.LocalExposure.ShadowContrastScale=0.8 r.VirtualTextures=True r.VirtualTexturedLightmaps=True r.VT.AnisotropicFiltering=True +r.Substrate=True +r.Substrate.OpaqueMaterialRoughRefraction=True +r.Substrate.Debug.AdvancedVisualizationShaders=False [/Script/WindowsTargetPlatform.WindowsTargetSettings] DefaultGraphicsRHI=DefaultGraphicsRHI_DX12 @@ -170,4 +173,5 @@ EndpointSettings=(bEnableLogging=False,PurgeProcessedMessageDelaySeconds=30,Remo [CoreRedirects] +ClassRedirects=(OldName="/Script/Elistria_Calling.MagickPlayerState",NewName="/Script/Elistria_Calling.MagickPlayerState") ++FunctionRedirects=(OldName="/Script/Elistria_Calling.PlayerGameplayAbilitiesDataAsset.GetAllMapings",NewName="/Script/Elistria_Calling.PlayerGameplayAbilitiesDataAsset.GetAllMappings") diff --git a/Elistria_Calling/Config/DefaultGame.ini b/Elistria_Calling/Config/DefaultGame.ini index b403098..ad8152c 100644 --- a/Elistria_Calling/Config/DefaultGame.ini +++ b/Elistria_Calling/Config/DefaultGame.ini @@ -1,6 +1,6 @@ [/Script/EngineSettings.GeneralProjectSettings] -ProjectID=34F4655F445E2B07E97EE9BB8110A0B8 -ProjectName=Third Person BP Game Template +ProjectID=36220C6945401B1B4EE12D8C5C8FBF0C +ProjectName=Elistria Calling [StartupActions] bAddPacks=True @@ -25,3 +25,8 @@ bShouldAcquireMissingChunksOnLoad=False bShouldWarnAboutInvalidAssets=True MetaDataTagsForAssetRegistry=() +[/Script/GameplayAbilitiesEditor.GameplayEffectCreationMenu] + +[/Script/CommonInput.CommonInputSettings] +bEnableEnhancedInputSupport=True + diff --git a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BPC_PlayerStats.uasset b/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BPC_PlayerStats.uasset index e62f0f9..7841ec3 100644 --- a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BPC_PlayerStats.uasset +++ b/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BPC_PlayerStats.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2fca5fa64f876a1b12fcd1fe7c4bfc348c3e34bff57f993d18d9bdf1d5e924c -size 667751 +oid sha256:2ec66674d2d9e69070623df4415cc3e9aa4dde08c596f7542395b7aa6d17f689 +size 649922 diff --git a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_MagickPlayerController.uasset b/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_MagickPlayerController.uasset deleted file mode 100644 index 8dd614b..0000000 --- a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_MagickPlayerController.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:64b8cb2d0256d3c6932480de5d06f2a5db803cb779fbd761955166227c217ecc -size 20676 diff --git a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_MagickPlayerState.uasset b/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_MagickPlayerState.uasset index 2544782..95a633c 100644 --- a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_MagickPlayerState.uasset +++ b/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_MagickPlayerState.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dd7ca32875e7caa8f3e9e4a00416de21444af9b3c2a0e5ca05d1f08a8d6f3d6 -size 55123 +oid sha256:32c737068ad3102e827b56fc507ec6f09af31675de8b39bb5f5a9425bcbba782 +size 55159 diff --git a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_PlayerController.uasset b/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_PlayerController.uasset index c21577e..686f5ab 100644 --- a/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_PlayerController.uasset +++ b/Elistria_Calling/Content/MAIN_CONTENT/Blueprints/BP_PlayerController.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2883660e8ccfd47a993c66c71d641f8efb27304e1189f5f1bd237b47426c9a78 -size 708021 +oid sha256:b2a63a8d7c6c299457440daa83f3253926505ff43a3ba972e68a7ae3f4269312 +size 711377 diff --git a/Elistria_Calling/Content/MAIN_CONTENT/GameplayAbilitySystem/GameplayEffects/GE_StaminaResting.uasset b/Elistria_Calling/Content/MAIN_CONTENT/GameplayAbilitySystem/GameplayEffects/GE_StaminaResting.uasset new file mode 100644 index 0000000..c81c04f --- /dev/null +++ b/Elistria_Calling/Content/MAIN_CONTENT/GameplayAbilitySystem/GameplayEffects/GE_StaminaResting.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e645e3fffbf56152e487346e783eec4ae53f648d636d3b25d903afe5c0490f6 +size 13452 diff --git a/Elistria_Calling/Content/MAIN_CONTENT/GameplayAbilitySystem/GameplayEffects/GE_XP20Gain.uasset b/Elistria_Calling/Content/MAIN_CONTENT/GameplayAbilitySystem/GameplayEffects/GE_XP20Gain.uasset new file mode 100644 index 0000000..ec53f7b --- /dev/null +++ b/Elistria_Calling/Content/MAIN_CONTENT/GameplayAbilitySystem/GameplayEffects/GE_XP20Gain.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f204ed985bfc0ee3c5f44a2e5771d7ebdfe0b3050eca6504c697a4e5b4a1463 +size 13092 diff --git a/Elistria_Calling/Content/MAIN_CONTENT/UI/Materials/M_RadialProgress.uasset b/Elistria_Calling/Content/MAIN_CONTENT/UI/Materials/M_RadialProgress.uasset new file mode 100644 index 0000000..a6068c5 --- /dev/null +++ b/Elistria_Calling/Content/MAIN_CONTENT/UI/Materials/M_RadialProgress.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdac82707eef815ea933250125d73a551a77a07afbf21bd2aa6a7885b3d26322 +size 20590 diff --git a/Elistria_Calling/Content/MAIN_CONTENT/UI/WB_MainHUD.uasset b/Elistria_Calling/Content/MAIN_CONTENT/UI/WB_MainHUD.uasset index 81bcf26..8c0fc5f 100644 --- a/Elistria_Calling/Content/MAIN_CONTENT/UI/WB_MainHUD.uasset +++ b/Elistria_Calling/Content/MAIN_CONTENT/UI/WB_MainHUD.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5fbb7205f5b42be72c79b2ad0a7b5c07a1eec2db75ba696e89e33e5cbfbef51b -size 51057 +oid sha256:420587b59805823464de8d2c8e1fa202dee011608b7c52e2cc8a947901099b2a +size 367136 diff --git a/Elistria_Calling/Content/StarterContent/Architecture/Floor_400x400.uasset b/Elistria_Calling/Content/StarterContent/Architecture/Floor_400x400.uasset index 3f00340..a9c59a6 100644 --- a/Elistria_Calling/Content/StarterContent/Architecture/Floor_400x400.uasset +++ b/Elistria_Calling/Content/StarterContent/Architecture/Floor_400x400.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6d2d79168f442b1b8573130dc5d76681167a55a3ea1af46db55cf9d02228312 +oid sha256:7e4d29566853dff28656c57968876d7f867e251ea5e84244f1f54baf8204e081 size 15406 diff --git a/Elistria_Calling/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset b/Elistria_Calling/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset index d8017db..a921d14 100644 --- a/Elistria_Calling/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset +++ b/Elistria_Calling/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f83429c8b44857832774510ea1e4ea247ade5362a051bfbfede143d66ea45e67 -size 1467356 +oid sha256:da40da021e32f6cc63b30a447fc40b587371ad7f5d8967eaf606b9621528bb7d +size 1511514 diff --git a/Elistria_Calling/Source/Elistria_Calling/Elistria_Calling.Build.cs b/Elistria_Calling/Source/Elistria_Calling/Elistria_Calling.Build.cs index d3ca392..d399e4b 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Elistria_Calling.Build.cs +++ b/Elistria_Calling/Source/Elistria_Calling/Elistria_Calling.Build.cs @@ -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 } diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/HealthAttributeSet.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/HealthAttributeSet.cpp new file mode 100644 index 0000000..969b2f0 --- /dev/null +++ b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/HealthAttributeSet.cpp @@ -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& 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); + } +} + diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/LevelAttributeSet.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/LevelAttributeSet.cpp new file mode 100644 index 0000000..f7e8873 --- /dev/null +++ b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/LevelAttributeSet.cpp @@ -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& 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(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(Lvl)); + SetXP(FMath::Clamp(GetXP(),0.0f,ComputeXPForLevel(Lvl))); + SetXPToNextLevel(ComputeXPForLevel(Lvl)); + } +} diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/ManaAttributeSet.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/ManaAttributeSet.cpp similarity index 95% rename from Elistria_Calling/Source/Elistria_Calling/Private/ManaAttributeSet.cpp rename to Elistria_Calling/Source/Elistria_Calling/Private/Attributes/ManaAttributeSet.cpp index fcb14b4..993ec7a 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Private/ManaAttributeSet.cpp +++ b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/ManaAttributeSet.cpp @@ -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(); diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/StaminaAttributeSet.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/StaminaAttributeSet.cpp new file mode 100644 index 0000000..f3b92bc --- /dev/null +++ b/Elistria_Calling/Source/Elistria_Calling/Private/Attributes/StaminaAttributeSet.cpp @@ -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& 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); + } + } +} \ No newline at end of file diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaAbilitySystemComponent.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaAbilitySystemComponent.cpp index f687cc3..840a3ca 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaAbilitySystemComponent.cpp +++ b/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaAbilitySystemComponent.cpp @@ -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 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); } } + diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/HealthAttributeSet.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaAttributeSetBase.cpp similarity index 68% rename from Elistria_Calling/Source/Elistria_Calling/Private/HealthAttributeSet.cpp rename to Elistria_Calling/Source/Elistria_Calling/Private/ElistriaAttributeSetBase.cpp index e2c623e..d99e65b 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Private/HealthAttributeSet.cpp +++ b/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaAttributeSetBase.cpp @@ -1,5 +1,5 @@ // Fill out your copyright notice in the Description page of Project Settings. -#include "HealthAttributeSet.h" +#include "ElistriaAttributeSetBase.h" diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaEnhancedInputComponent.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaEnhancedInputComponent.cpp index 4d5b4b3..eee1db4 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaEnhancedInputComponent.cpp +++ b/Elistria_Calling/Source/Elistria_Calling/Private/ElistriaEnhancedInputComponent.cpp @@ -7,7 +7,7 @@ void UElistriaEnhancedInputComponent::ClearAbilityBindings() { - for (uint32 Handle : AbilityActionBindings) + for (int32 Handle : AbilityActionBindings) { RemoveBindingByHandle(Handle); } diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/MagickPlayerController.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/MagickPlayerController.cpp deleted file mode 100644 index 87d9712..0000000 --- a/Elistria_Calling/Source/Elistria_Calling/Private/MagickPlayerController.cpp +++ /dev/null @@ -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(); - 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(InputComponent)) - { - if (InputAbilitiesDataAsset) - { - EIC->BindAbilityActions(InputAbilitiesDataAsset, this, &AMagickPlayerController::AbilityInputPressed); - } - } -} - -void AMagickPlayerController::AbilityInputPressed(int32 InputID) -{ - if (AMagickPlayerState* PS = GetPlayerState()) - { - if (UElistriaAbilitySystemComponent* ASC = PS ? PS->GetAbilitySystemComponent() : nullptr) - { - ASC->AbilityLocalInputPressed(InputID); - } - } -} - -void AMagickPlayerController::BeginPlay() -{ - Super::BeginPlay(); - if (UInputMappingContext* IMC = InputMappingContext) - { - if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem(GetLocalPlayer())) - { - Subsystem->AddMappingContext(IMC, 0); - } - } -} - -void AMagickPlayerController::RebindAbilityInputs() -{ - if (UElistriaEnhancedInputComponent* EIC = Cast(InputComponent)) - { - EIC -> ClearAbilityBindings(); - if (InputAbilitiesDataAsset) - { - EIC->BindAbilityActions(InputAbilitiesDataAsset,this,&AMagickPlayerController::AbilityInputPressed); - } - } -} diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/Player/MagickPlayerController.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/Player/MagickPlayerController.cpp new file mode 100644 index 0000000..503487c --- /dev/null +++ b/Elistria_Calling/Source/Elistria_Calling/Private/Player/MagickPlayerController.cpp @@ -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(GetLocalPlayer())) + { + Sub->AddMappingContext(InputMappingContext,0); + } + } +} + +void AMagickPlayerController::OnPossess(APawn *InPawn) +{ + Super::OnPossess(InPawn); + if (AMagickPlayerState* PS = GetPlayerState()) + { + 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(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()) + { + 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()) + { + if (UElistriaAbilitySystemComponent* ASC = PS->GetAbilitySystemComponent()) + { + ASC->HandleInputTag(Instance.GetTriggerEvent(), InputTag); + } + } +} diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/MagickPlayerState.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/Player/MagickPlayerState.cpp similarity index 60% rename from Elistria_Calling/Source/Elistria_Calling/Private/MagickPlayerState.cpp rename to Elistria_Calling/Source/Elistria_Calling/Private/Player/MagickPlayerState.cpp index c394434..58e8716 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Private/MagickPlayerState.cpp +++ b/Elistria_Calling/Source/Elistria_Calling/Private/Player/MagickPlayerState.cpp @@ -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(TEXT("AbilitySystem")); ManaSet = CreateDefaultSubobject(TEXT("ManaSet")); + HealthSet = CreateDefaultSubobject(TEXT("HealthSet")); + StaminaSet = CreateDefaultSubobject(TEXT("StaminaSet")); + LevelSet = CreateDefaultSubobject(TEXT("XPSet")); } UElistriaAbilitySystemComponent* AMagickPlayerState::GetAbilitySystemComponent() const @@ -30,6 +31,8 @@ void AMagickPlayerState::GetLifetimeReplicatedProps(TArray& 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()); + } } } diff --git a/Elistria_Calling/Source/Elistria_Calling/Private/PlayerGameplayAbilitiesDataAsset.cpp b/Elistria_Calling/Source/Elistria_Calling/Private/PlayerGameplayAbilitiesDataAsset.cpp index 68702b5..8ab78f0 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Private/PlayerGameplayAbilitiesDataAsset.cpp +++ b/Elistria_Calling/Source/Elistria_Calling/Private/PlayerGameplayAbilitiesDataAsset.cpp @@ -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& 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 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& 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; +}; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/LevelAttributeSet.h b/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/LevelAttributeSet.h new file mode 100644 index 0000000..af6f0b1 --- /dev/null +++ b/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/LevelAttributeSet.h @@ -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& 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(); +}; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/ManaAttributeSet.h b/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/ManaAttributeSet.h similarity index 73% rename from Elistria_Calling/Source/Elistria_Calling/Public/ManaAttributeSet.h rename to Elistria_Calling/Source/Elistria_Calling/Public/Attributes/ManaAttributeSet.h index eee9c06..9b9714b 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Public/ManaAttributeSet.h +++ b/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/ManaAttributeSet.h @@ -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() diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/StaminaAttributeSet.h b/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/StaminaAttributeSet.h new file mode 100644 index 0000000..956a511 --- /dev/null +++ b/Elistria_Calling/Source/Elistria_Calling/Public/Attributes/StaminaAttributeSet.h @@ -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& 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; +}; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaAbilitySystemComponent.h b/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaAbilitySystemComponent.h index 33924cc..f416ca4 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaAbilitySystemComponent.h +++ b/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaAbilitySystemComponent.h @@ -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 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 InputIDToAbilitySpecHandleMap; - UPROPERTY() - TMap SlotToAbilityHandleMap; - - void ServerActivateAbilityByInputID_Implementation(FGameplayAbilitySpecHandle Handle, int32 InputID); + TMap TagToSpecHandleMap; }; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaAttributeSetBase.h b/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaAttributeSetBase.h new file mode 100644 index 0000000..b351967 --- /dev/null +++ b/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaAttributeSetBase.h @@ -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() + +}; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaEnhancedInputComponent.h b/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaEnhancedInputComponent.h index 5b7fe51..fb427c6 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaEnhancedInputComponent.h +++ b/Elistria_Calling/Source/Elistria_Calling/Public/ElistriaEnhancedInputComponent.h @@ -14,26 +14,42 @@ UCLASS() class ELISTRIA_CALLING_API UElistriaEnhancedInputComponent : public UEnhancedInputComponent { GENERATED_BODY() -public: - template - void BindAbilityActions(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, FuncType Func); +public: + template + void BindAbilityActionsByTag(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, + void (UserClass::*Func)(const FInputActionInstance&, FGameplayTag)); + UFUNCTION(BlueprintCallable, Category="Input") void ClearAbilityBindings(); - + private: - TArray AbilityActionBindings; + TArray AbilityActionBindings; }; -template -void UElistriaEnhancedInputComponent::BindAbilityActions(const UPlayerGameplayAbilitiesDataAsset* InputConfig, UserClass* Object, FuncType Func) +template +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()); } } -} \ No newline at end of file + { + + } +} + diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/HealthAttributeSet.h b/Elistria_Calling/Source/Elistria_Calling/Public/HealthAttributeSet.h deleted file mode 100644 index c56acab..0000000 --- a/Elistria_Calling/Source/Elistria_Calling/Public/HealthAttributeSet.h +++ /dev/null @@ -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() - -}; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/MagickPlayerController.h b/Elistria_Calling/Source/Elistria_Calling/Public/Player/MagickPlayerController.h similarity index 65% rename from Elistria_Calling/Source/Elistria_Calling/Public/MagickPlayerController.h rename to Elistria_Calling/Source/Elistria_Calling/Public/Player/MagickPlayerController.h index d2e3d06..83acffa 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Public/MagickPlayerController.h +++ b/Elistria_Calling/Source/Elistria_Calling/Public/Player/MagickPlayerController.h @@ -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 InputAbilitiesDataAsset; UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Input") TObjectPtr InputMappingContext; - - virtual void SetupInputComponent() override; - - UFUNCTION() - void AbilityInputPressed(int32 InputID); - - virtual void BeginPlay() override; - - void RebindAbilityInputs(); }; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/MagickPlayerState.h b/Elistria_Calling/Source/Elistria_Calling/Public/Player/MagickPlayerState.h similarity index 70% rename from Elistria_Calling/Source/Elistria_Calling/Public/MagickPlayerState.h rename to Elistria_Calling/Source/Elistria_Calling/Public/Player/MagickPlayerState.h index 6670e30..33420d9 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Public/MagickPlayerState.h +++ b/Elistria_Calling/Source/Elistria_Calling/Public/Player/MagickPlayerState.h @@ -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 ManaSet; + UPROPERTY(Replicated) + TObjectPtr StaminaSet; + + UPROPERTY(Replicated) + TObjectPtr HealthSet; + + UPROPERTY(Replicated) + TObjectPtr LevelSet; + private: }; diff --git a/Elistria_Calling/Source/Elistria_Calling/Public/PlayerGameplayAbilitiesDataAsset.h b/Elistria_Calling/Source/Elistria_Calling/Public/PlayerGameplayAbilitiesDataAsset.h index 32f5655..22221fa 100644 --- a/Elistria_Calling/Source/Elistria_Calling/Public/PlayerGameplayAbilitiesDataAsset.h +++ b/Elistria_Calling/Source/Elistria_Calling/Public/PlayerGameplayAbilitiesDataAsset.h @@ -12,43 +12,32 @@ */ class UInputAction; -USTRUCT() +USTRUCT(BlueprintType) struct FGameplayInputAbilityInfo { GENERATED_USTRUCT_BODY() - UPROPERTY(EditAnywhere, Category = "GameplayInputAbilityInfo") + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Ability") TSubclassOf AbilityClass; - UPROPERTY(EditAnywhere, Category = "GameplayInputAbilityInfo") + UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Ability") TObjectPtr 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 InputAbilities; - public: - UPlayerGameplayAbilitiesDataAsset(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); - - const TSet& GetInputAbilities() const; + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="AbilitySystem") + TArray AbilityMappings; + UFUNCTION(BlueprintPure, Category = "AbilitySystem") + void GetAllMappings(TArray& 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& Out) const + { + for (const auto& E : AbilityMappings) + { + if (E.InputTag == InputTag) + { + Out.Add(E); + } + } + } + const TArray& 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 };