From 9d9db8dee16a312d97c3ebd4c7793c58447a509b Mon Sep 17 00:00:00 2001 From: Guy Elsmore-Paddock Date: Fri, 19 Jul 2024 00:26:29 -0400 Subject: [PATCH] [#60] Switch Key Ability TEML Calcs. to Use Nat. Tags instead of Strings This makes the code less fragile if tags get renamed in the future, since the tag names no longer appear in the code as strings. If the variable name is wrong, it will fail to build, rather than it being a run-time error. --- .../Attacks/PF2SpellAttackRollCalculation.cpp | 5 ++- .../PF2ClassDifficultyClassCalculation.cpp | 5 ++- .../PF2KeyAbilityTemlCalculationBase.cpp | 45 +++++++++---------- .../PF2SpellDifficultyClassCalculation.cpp | 5 ++- .../PF2KeyAbilityTemlCalculationBase.h | 40 +++++------------ 5 files changed, 44 insertions(+), 56 deletions(-) diff --git a/Source/OpenPF2GameFramework/Private/Abilities/Attacks/PF2SpellAttackRollCalculation.cpp b/Source/OpenPF2GameFramework/Private/Abilities/Attacks/PF2SpellAttackRollCalculation.cpp index a465dfa1..86e12c8b 100644 --- a/Source/OpenPF2GameFramework/Private/Abilities/Attacks/PF2SpellAttackRollCalculation.cpp +++ b/Source/OpenPF2GameFramework/Private/Abilities/Attacks/PF2SpellAttackRollCalculation.cpp @@ -5,7 +5,10 @@ #include "Abilities/Attacks/PF2SpellAttackRollCalculation.h" +#include "GameplayTags/Stats/KeyAbilities.h" +#include "GameplayTags/Stats/Proficiencies/SpellAttacks.h" + UPF2SpellAttackRollCalculation::UPF2SpellAttackRollCalculation() : - UPF2KeyAbilityTemlCalculationBase(TEXT("PF2.Proficiency.SpellAttack"), TEXT("PF2.SpellcastingAbility")) + UPF2KeyAbilityTemlCalculationBase(Pf2TagProficiencySpellAttack, Pf2TagSpellcastingAbilities) { } diff --git a/Source/OpenPF2GameFramework/Private/CharacterStats/PF2ClassDifficultyClassCalculation.cpp b/Source/OpenPF2GameFramework/Private/CharacterStats/PF2ClassDifficultyClassCalculation.cpp index 72bb8446..0d8cc7b2 100644 --- a/Source/OpenPF2GameFramework/Private/CharacterStats/PF2ClassDifficultyClassCalculation.cpp +++ b/Source/OpenPF2GameFramework/Private/CharacterStats/PF2ClassDifficultyClassCalculation.cpp @@ -5,7 +5,10 @@ #include "CharacterStats/PF2ClassDifficultyClassCalculation.h" +#include "GameplayTags/Stats/KeyAbilities.h" +#include "GameplayTags/Stats/Proficiencies/ClassDc.h" + UPF2ClassDifficultyClassCalculation::UPF2ClassDifficultyClassCalculation() : - UPF2KeyAbilityTemlCalculationBase(TEXT("PF2.Proficiency.ClassDc"), TEXT("PF2.KeyAbility"), 10.0f) + UPF2KeyAbilityTemlCalculationBase(Pf2TagProficiencyClassDc, Pf2TagKeyAbilities, 10.0f) { } diff --git a/Source/OpenPF2GameFramework/Private/CharacterStats/PF2KeyAbilityTemlCalculationBase.cpp b/Source/OpenPF2GameFramework/Private/CharacterStats/PF2KeyAbilityTemlCalculationBase.cpp index 241ce109..aef5aad7 100644 --- a/Source/OpenPF2GameFramework/Private/CharacterStats/PF2KeyAbilityTemlCalculationBase.cpp +++ b/Source/OpenPF2GameFramework/Private/CharacterStats/PF2KeyAbilityTemlCalculationBase.cpp @@ -17,6 +17,8 @@ #include "CharacterStats/PF2CharacterAttributeSet.h" #include "CharacterStats/PF2TemlCalculation.h" +#include "GameplayTags/Stats/KeyAbilities.h" + #include "Libraries/PF2AbilitySystemLibrary.h" #include "Libraries/PF2TagLibrary.h" @@ -24,62 +26,56 @@ UPF2KeyAbilityTemlCalculationBase::UPF2KeyAbilityTemlCalculationBase() : UPF2KeyAbilityTemlCalculationBase( - TEXT(""), - TEXT("PF2.KeyAbility") + FGameplayTag(), + Pf2TagKeyAbilities ) { } -UPF2KeyAbilityTemlCalculationBase::UPF2KeyAbilityTemlCalculationBase( - const FString& StatGameplayTagPrefix, - const FString& KeyAbilityGameplayTagPrefix, - const float BaseValue) : - StatGameplayTagPrefix(StatGameplayTagPrefix), +UPF2KeyAbilityTemlCalculationBase::UPF2KeyAbilityTemlCalculationBase(const FGameplayTag& StatPrefixTag, + const FGameplayTag& KeyAbilityPrefixTag, + const float BaseValue) : + StatPrefixTag(StatPrefixTag), BaseValue(BaseValue) { this->DefineKeyAbilityCapture( - KeyAbilityGameplayTagPrefix + ".Strength", + UPF2TagLibrary::RequestCombinedTagByString(KeyAbilityPrefixTag, TEXT("Strength")), UPF2CharacterAttributeSet::GetAbStrengthModifierAttribute() ); this->DefineKeyAbilityCapture( - KeyAbilityGameplayTagPrefix + ".Dexterity", + UPF2TagLibrary::RequestCombinedTagByString(KeyAbilityPrefixTag, TEXT("Dexterity")), UPF2CharacterAttributeSet::GetAbDexterityModifierAttribute() ); this->DefineKeyAbilityCapture( - KeyAbilityGameplayTagPrefix + ".Constitution", + UPF2TagLibrary::RequestCombinedTagByString(KeyAbilityPrefixTag, TEXT("Constitution")), UPF2CharacterAttributeSet::GetAbConstitutionModifierAttribute() ); this->DefineKeyAbilityCapture( - KeyAbilityGameplayTagPrefix + ".Intelligence", + UPF2TagLibrary::RequestCombinedTagByString(KeyAbilityPrefixTag, TEXT("Intelligence")), UPF2CharacterAttributeSet::GetAbIntelligenceModifierAttribute() ); this->DefineKeyAbilityCapture( - KeyAbilityGameplayTagPrefix + ".Wisdom", + UPF2TagLibrary::RequestCombinedTagByString(KeyAbilityPrefixTag, TEXT("Wisdom")), UPF2CharacterAttributeSet::GetAbWisdomModifierAttribute() ); this->DefineKeyAbilityCapture( - KeyAbilityGameplayTagPrefix + ".Charisma", + UPF2TagLibrary::RequestCombinedTagByString(KeyAbilityPrefixTag, TEXT("Charisma")), UPF2CharacterAttributeSet::GetAbCharismaModifierAttribute() ); } -void UPF2KeyAbilityTemlCalculationBase::DefineKeyAbilityCapture( - const FString& KeyAbilityTagName, - const FGameplayAttribute& Attribute) +void UPF2KeyAbilityTemlCalculationBase::DefineKeyAbilityCapture(const FGameplayTag& KeyAbilityTag, + const FGameplayAttribute& Attribute) { const FGameplayEffectAttributeCaptureDefinition CaptureDefinition = PF2GameplayAbilityUtilities::BuildSourceCaptureFor(Attribute); - this->KeyAbilityCaptureDefinitions.Add( - KeyAbilityTagName, - CaptureDefinition - ); - + this->KeyAbilityCaptureDefinitions.Add(KeyAbilityTag, CaptureDefinition); this->RelevantAttributesToCapture.Add(CaptureDefinition); } @@ -96,7 +92,7 @@ float UPF2KeyAbilityTemlCalculationBase::CalculateBaseMagnitude_Implementation(c // Spell DC = 10 + your spellcasting ability modifier + proficiency bonus + other bonuses + penalties" // // Source: Pathfinder 2E Core Rulebook, page 298, "Spell Attack Roll and Spell DC". - const float ProficiencyBonus = FPF2TemlCalculation(this->StatGameplayTagPrefix, Spec).GetValue(), + const float ProficiencyBonus = FPF2TemlCalculation(this->StatPrefixTag, Spec).GetValue(), KeyAbilityModifier = this->CalculateKeyAbilityModifier(Spec), AbilityScore = this->BaseValue + ProficiencyBonus + KeyAbilityModifier; @@ -104,7 +100,7 @@ float UPF2KeyAbilityTemlCalculationBase::CalculateBaseMagnitude_Implementation(c LogPf2Stats, VeryVerbose, TEXT("Calculated key ability score ('%s'): %f + %f + %f = %f"), - *(this->StatGameplayTagPrefix), + *(this->StatPrefixTag.ToString()), this->BaseValue, ProficiencyBonus, KeyAbilityModifier, @@ -119,6 +115,7 @@ float UPF2KeyAbilityTemlCalculationBase::CalculateKeyAbilityModifier(const FGame float KeyAbilityModifier = 0.0f; const FGameplayTagContainer* SourceTags = Spec.CapturedSourceTags.GetAggregatedTags(); + // ReSharper disable once CppTooWideScopeInitStatement const FGameplayEffectAttributeCaptureDefinition KeyAbilityCaptureDefinition = this->DetermineKeyAbility(SourceTags); @@ -145,7 +142,7 @@ FGameplayEffectAttributeCaptureDefinition UPF2KeyAbilityTemlCalculationBase::Det for (auto PairIterator = this->KeyAbilityCaptureDefinitions.CreateConstIterator(); PairIterator; ++PairIterator) { - if (const FString TagName = PairIterator.Key(); UPF2TagLibrary::ContainerHasTag(*SourceTags, TagName)) + if (const FGameplayTag Tag = PairIterator.Key(); SourceTags->HasTag(Tag)) { KeyAbilityCaptureDefinition = PairIterator.Value(); break; diff --git a/Source/OpenPF2GameFramework/Private/CharacterStats/PF2SpellDifficultyClassCalculation.cpp b/Source/OpenPF2GameFramework/Private/CharacterStats/PF2SpellDifficultyClassCalculation.cpp index daf61d17..f982d587 100644 --- a/Source/OpenPF2GameFramework/Private/CharacterStats/PF2SpellDifficultyClassCalculation.cpp +++ b/Source/OpenPF2GameFramework/Private/CharacterStats/PF2SpellDifficultyClassCalculation.cpp @@ -5,7 +5,10 @@ #include "CharacterStats/PF2SpellDifficultyClassCalculation.h" +#include "GameplayTags/Stats/KeyAbilities.h" +#include "GameplayTags/Stats/Proficiencies/SpellDc.h" + UPF2SpellDifficultyClassCalculation::UPF2SpellDifficultyClassCalculation() : - UPF2KeyAbilityTemlCalculationBase(TEXT("PF2.Proficiency.SpellDc"), TEXT("PF2.SpellcastingAbility"), 10.0f) + UPF2KeyAbilityTemlCalculationBase(Pf2TagProficiencySpellDc, Pf2TagSpellcastingAbilities, 10.0f) { } diff --git a/Source/OpenPF2GameFramework/Public/CharacterStats/PF2KeyAbilityTemlCalculationBase.h b/Source/OpenPF2GameFramework/Public/CharacterStats/PF2KeyAbilityTemlCalculationBase.h index 4b01da6e..4c0d8fc1 100644 --- a/Source/OpenPF2GameFramework/Public/CharacterStats/PF2KeyAbilityTemlCalculationBase.h +++ b/Source/OpenPF2GameFramework/Public/CharacterStats/PF2KeyAbilityTemlCalculationBase.h @@ -43,10 +43,10 @@ class OPENPF2GAMEFRAMEWORK_API UPF2KeyAbilityTemlCalculationBase : public UGamep * proficiency bonus, and TEML tags on the character that have the specified prefix determine the magnitude of the * boost. * - * @param StatGameplayTagPrefix + * @param StatPrefixTag * The tag prefix to use for checking a character's training in the stat. For example, "PF2.Proficiency.ClassDc", * "PF2.Proficiency.SpellAttack", or "PF2.Proficiency.SpellDc". - * @param KeyAbilityGameplayTagPrefix + * @param KeyAbilityPrefixTag * The tag prefix to use to determine the key ability for this stat. For the Class DC, this is "PF2.KeyAbility". * For Spell Attack and Spell DC, this is "PF2.SpellcastingAbility". * @param BaseValue @@ -54,9 +54,9 @@ class OPENPF2GAMEFRAMEWORK_API UPF2KeyAbilityTemlCalculationBase : public UGamep * this is 0. */ explicit UPF2KeyAbilityTemlCalculationBase( - const FString& StatGameplayTagPrefix, - const FString& KeyAbilityGameplayTagPrefix, - const float BaseValue = 0.0f); + const FGameplayTag& StatPrefixTag, + const FGameplayTag& KeyAbilityPrefixTag, + const float BaseValue = 0.0f); // ================================================================================================================= // Public Methods - UGameplayModMagnitudeCalculation Implementation @@ -70,7 +70,7 @@ class OPENPF2GAMEFRAMEWORK_API UPF2KeyAbilityTemlCalculationBase : public UGamep /** * The tag prefix to use for checking a character's training in this stat. */ - FString StatGameplayTagPrefix; + FGameplayTag StatPrefixTag; /** * The base value for this stat. @@ -82,28 +82,10 @@ class OPENPF2GAMEFRAMEWORK_API UPF2KeyAbilityTemlCalculationBase : public UGamep /** * Map from Key Ability tag names to capture definitions. * - * Each key in the map is a gameplay tag, which corresponds to a key character ability; and the value is the + * Each key in the map is a gameplay tag that corresponds to a key character ability, while the value is the * definition for capturing the modifier of that ability. */ - TMap KeyAbilityCaptureDefinitions; - - /** - * The name of the gameplay tag that indicates the character's Key Ability. - * - * From the Pathfinder 2E Core Rulebook, page 67: - * "This is the ability score that a member of your class cares about the most. Many of your most useful and - * powerful abilities are tied to this ability in some way. - * - * For instance, this is the ability score you’ll use to determine the Difficulty Class (DC) associated with your - * character’s class features and feats. This is called your class DC. If your character is a member of a - * spellcasting class, this Key Ability is used to calculate spell DCs and similar values. - * - * Most classes are associated with one Key Ability score, but some allow you to choose from two options. For - * instance, if you’re a fighter, you can choose either Strength or Dexterity as your Key Ability. A fighter who - * chooses Strength will excel in hand-to-hand combat, while those who choose Dexterity prefer ranged or finesse - * weapons." - */ - FString KeyAbilityGameplayTag; + TMap KeyAbilityCaptureDefinitions; // ================================================================================================================= // Protected Methods @@ -113,13 +95,13 @@ class OPENPF2GAMEFRAMEWORK_API UPF2KeyAbilityTemlCalculationBase : public UGamep * * This is used to ensure we can retrieve the modifier for the specified ability later in the calculation phase. * - * @param KeyAbilityTagName - * The name of the gameplay tag that a character must have for the ability to be considered "key". For example, + * @param KeyAbilityTag + * The gameplay tag that a character must have for the ability to be considered "key". For example, * "PF2.KeyAbility.Strength" or "PF2.SpellcastingAbility.Intelligence". * @param Attribute * The definition of the attribute to capture. */ - void DefineKeyAbilityCapture(const FString& KeyAbilityTagName, const FGameplayAttribute& Attribute); + void DefineKeyAbilityCapture(const FGameplayTag& KeyAbilityTag, const FGameplayAttribute& Attribute); /** * Calculates the Key Ability modifier for the character.