Skip to content

Commit

Permalink
[#60] Implement PF2TagLibrary::RequestCombinedTag*() Methods
Browse files Browse the repository at this point in the history
This makes assembling a gameplay tag from a root tag and suffix name
more efficient by using a `NameBuilder` for this instead of
concatenation.
  • Loading branch information
GuyPaddock committed Jul 19, 2024
1 parent 680aef6 commit 83a88e3
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ FPF2TemlCalculation::FPF2TemlCalculation(const FGameplayTag TagPrefix,
// option.
if (CharacterTags->HasTag(TagPrefix))
{
const FString TagPrefixString = TagPrefix.ToString();

// "When attempting a check that involves something you have some training in, you will also add your
// proficiency bonus. This bonus depends on your proficiency rank: untrained, trained, expert, master, or
// legendary. If you’re untrained, your bonus is +0—you must rely on raw talent and any bonuses from the
Expand All @@ -52,22 +50,22 @@ FPF2TemlCalculation::FPF2TemlCalculation(const FGameplayTag TagPrefix,
//
// Source: Pathfinder 2E Core Rulebook, page 444, "Step 1: Roll D20 and Identify The Modifiers, Bonuses, and
// Penalties That Apply".
if (UPF2TagLibrary::ContainerHasTag(*CharacterTags, TagPrefixString + ".Legendary"))
if (CharacterTags->HasTag(UPF2TagLibrary::RequestCombinedTagByString(TagPrefix, TEXT("Legendary"))))
{
// Legendary -> Your level + 8
ProficiencyBonus = CharacterLevel + 8;
}
else if (UPF2TagLibrary::ContainerHasTag(*CharacterTags, TagPrefixString + ".Master"))
else if (CharacterTags->HasTag(UPF2TagLibrary::RequestCombinedTagByString(TagPrefix, TEXT("Master"))))
{
// Master -> Your level + 6
ProficiencyBonus = CharacterLevel + 6;
}
else if (UPF2TagLibrary::ContainerHasTag(*CharacterTags, TagPrefixString + ".Expert"))
else if (CharacterTags->HasTag(UPF2TagLibrary::RequestCombinedTagByString(TagPrefix, TEXT("Expert"))))
{
// Expert -> Your level + 4
ProficiencyBonus = CharacterLevel + 4;
}
else if (UPF2TagLibrary::ContainerHasTag(*CharacterTags, TagPrefixString + ".Trained"))
else if (CharacterTags->HasTag(UPF2TagLibrary::RequestCombinedTagByString(TagPrefix, TEXT("Trained"))))
{
// Trained -> Your level + 2
ProficiencyBonus = CharacterLevel + 2;
Expand Down
170 changes: 170 additions & 0 deletions Source/OpenPF2GameFramework/Public/Libraries/PF2TagLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,174 @@ class OPENPF2GAMEFRAMEWORK_API UPF2TagLibrary final : public UBlueprintFunctionL
UFUNCTION(BlueprintCallable, BlueprintPure, meta=(AutoCreateRefTerm="ParentTag"), Category="OpenPF2|Gameplay Tags")
static uint8 ParseConditionLevel(const FGameplayTag& Tag,
const FGameplayTag& ParentTag);

/**
* Combines a tag with the name of a tag that is defined within/underneath it, and returns the resulting tag.
*
* For example, given a parent tag of "PF2.Trait.Condition" and a child tag fragment of "Dying.2", this returns the
* tag "PF2.Trait.Condition.Dying.2".
*
* The combined tag must be a valid tag that has been defined either in Gameplay Tags INI files or in static tags.
*
* @tparam T
* The type of text or string being used to represent the name of the child fragment.
*
* @param ParentTag
* The parent/prefix tag under which the target tag is defined.
* @param ChildTagFragment
* The name or fragment of the tag under the parent tag.
*
* @return
* The gameplay tag that corresponds to the combination of the give child tag under the given parent tag.
*/
template<typename T>
FORCEINLINE static FGameplayTag RequestCombinedTag(const FGameplayTag& ParentTag, const T& ChildTagFragment)
{
return RequestCombinedTag(ParentTag.GetTagName(), ChildTagFragment);
}

/**
* Concatenates the names of two tags together and returns the resulting tag.
*
* For example, given a parent tag of "PF2.Trait.Condition" and a child tag fragment of "Dying.2", this returns the
* tag "PF2.Trait.Condition.Dying.2".
*
* The combined tag must be a valid tag that has been defined either in Gameplay Tags INI files or in static tags.
*
* @tparam P
* The type of text or string being used to represent the name of the parent tag.
* @tparam C
* The type of text or string being used to represent the name of the child fragment.
*
* @param ParentTagName
* The name of the parent/prefix tag under which the target tag is defined.
* @param ChildTagFragment
* The name of the desired tag under the parent tag.
*
* @return
* The gameplay tag that corresponds to the combination of the give child tag under the given parent tag.
*/
template<typename P, typename C>
static FGameplayTag RequestCombinedTag(const P& ParentTagName, const C& ChildTagFragment)
{
FNameBuilder TagNameBuilder;

TagNameBuilder << ParentTagName;
TagNameBuilder << TEXT(".");
TagNameBuilder << ChildTagFragment;

return FGameplayTag::RequestGameplayTag(FName(TagNameBuilder.ToString()));
}

/**
* Combines a tag with the name of a tag that is defined within/underneath it, and returns the resulting tag.
*
* For example, given a parent tag of "PF2.Trait.Condition" and a child tag fragment of "Dying.2", this returns the
* tag "PF2.Trait.Condition.Dying.2".
*
* The combined tag must be a valid tag that has been defined either in Gameplay Tags INI files or in static tags.
*
* @param ParentTag
* The parent/prefix tag under which the target tag is defined.
* @param ChildTagFragment
* The name of the desired tag under the parent tag.
*
* @return
* The gameplay tag that corresponds to the combination of the give child tag under the given parent tag.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
meta=(AutoCreateRefTerm="ParentTag,ChildTagFragment"),
Category="OpenPF2|Gameplay Tags"
)
static FORCEINLINE FGameplayTag RequestCombinedTagByName(const FGameplayTag& ParentTag,
const FName& ChildTagFragment)
{
return RequestCombinedTag(ParentTag, ChildTagFragment);
}

/**
* Combines a tag with the name of a tag that is defined within/underneath it, and returns the resulting tag.
*
* For example, given a parent tag of "PF2.Trait.Condition" and a child tag fragment of "Dying.2", this returns the
* tag "PF2.Trait.Condition.Dying.2".
*
* The combined tag must be a valid tag that has been defined either in Gameplay Tags INI files or in static tags.
*
* @param ParentTag
* The parent/prefix tag under which the target tag is defined.
* @param ChildTagFragment
* The name of the desired tag under the parent tag.
*
* @return
* The gameplay tag that corresponds to the combination of the give child tag under the given parent tag.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
meta=(AutoCreateRefTerm="ParentTag,ChildTagFragment"),
Category="OpenPF2|Gameplay Tags"
)
static FORCEINLINE FGameplayTag RequestCombinedTagByString(const FGameplayTag& ParentTag,
const FString& ChildTagFragment)
{
return RequestCombinedTag(ParentTag, ChildTagFragment);
}

/**
* Concatenates the names of two tags together and returns the resulting tag.
*
* For example, given a parent tag of "PF2.Trait.Condition" and a child tag fragment of "Dying.2", this returns the
* tag "PF2.Trait.Condition.Dying.2".
*
* The combined tag must be a valid tag that has been defined either in Gameplay Tags INI files or in static tags.
*
* @param ParentTagName
* The name of the parent/prefix tag under which the target tag is defined.
* @param ChildTagFragment
* The name of the desired tag under the parent tag.
*
* @return
* The gameplay tag that corresponds to the combination of the give child tag under the given parent tag.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
meta=(AutoCreateRefTerm="ParentTagName,ChildTagFragment"),
Category="OpenPF2|Gameplay Tags"
)
static FORCEINLINE FGameplayTag RequestCombinedTagFromNames(const FName& ParentTagName,
const FName& ChildTagFragment)
{
return RequestCombinedTag(ParentTagName, ChildTagFragment);
}

/**
* Concatenates the names of two tags together and returns the resulting tag.
*
* For example, given a parent tag of "PF2.Trait.Condition" and a child tag fragment of "Dying.2", this returns the
* tag "PF2.Trait.Condition.Dying.2".
*
* The combined tag must be a valid tag that has been defined either in Gameplay Tags INI files or in static tags.
*
* @param ParentTagName
* The name of the parent/prefix tag under which the target tag is defined.
* @param ChildTagFragment
* The name of the desired tag under the parent tag.
*
* @return
* The gameplay tag that corresponds to the combination of the give child tag under the given parent tag.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
meta=(AutoCreateRefTerm="ParentTagName,ChildTagFragment"),
Category="OpenPF2|Gameplay Tags"
)
static FORCEINLINE FGameplayTag RequestCombinedTagFromStrings(const FString& ParentTagName,
const FString& ChildTagFragment)
{
return RequestCombinedTag(ParentTagName, ChildTagFragment);
}
};

0 comments on commit 83a88e3

Please sign in to comment.