Files
UnrealEngineUWP/Engine/Source/Runtime/SkillSystem/Private/SkillSystemTestAttributeSet.cpp
Billy Bramer b8d692da28 Merge CLs with refactor of GameplayTags to main. Largely WIP, more changes coming.
[AUTOMERGE]

- Step one of gameplay tag refactor: deletion of un-used and unfixed content

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2067362 by Billy.Bramer on 2014/05/08 16:08:55.

[AUTOMERGE]

Gameplay Tag Refactor

Unshelved from AntonyC's pending changelist '2003772':

#TTP 322200 - Gameplay Tags: Refactor how tags are stored/queried

#proj Fortnite.Editor

#summary Refactored Tags from FName array to a FGamplayTag

#change removed all FName Tags and replaces with FGameplayTag
#added added tag verification so that new tags are not created at runtime
#added added new object version for data upgrade on all tagcontainers to be in new format and only store leaf most tags
#added requestgameplaytag function to FortGlobals, so that the tag manager can be started up before first use
#added New GraphPin for single tags
#change Added mode to SGamplayTagWidget to allow single select
#change PropertyArray fixed to now support empty arrays in the ImportText

---------------------

Additional Changes/Modifications
- Add new BlueprintGameplayTagLibrary to expose tag container functions to blueprints; Will add more in future post-refactor
- Fix bug with AddLeafTagToContainer incorrectly clearing the wrong container
- Remove default parameters for TagContainer.HasTag and fix call-sites to remain logically consistent with old behavior
- Make FName constructor for tag explicit
- Fix incorrect requirements check in combat effect
- Expose tag asset interface to blueprints
- Remove serialization fix-up from game data (manually fixed up)
- Remove version bump and serialization fix-up on tag container (will be re-done from main branch post merge)

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2067378 by Billy.Bramer on 2014/05/08 16:15:42.

[AUTOMERGE]

#UE4 Fixed up GameplayTag usage in the SkillSystem module

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2067576 by Bob.Tellez on 2014/05/08 18:38:58.

[AUTOMERGE]

- Linker build fix on gameplay tags

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2067708 by Billy.Bramer on 2014/05/08 21:18:36.

[AUTOMERGE]

- Minor optimization in header

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2067709 by Billy.Bramer on 2014/05/08 21:22:27.

[AUTOMERGE]

- Gameplay tag refactor, round 3
- Fortnite asset conversion/update

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2068202 by Billy.Bramer on 2014/05/09 11:13:36.

[AUTOMERGE]

- Fix gameplay tag reimporting failing to reinitialize the tag table

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2068787 by Billy.Bramer on 2014/05/09 18:11:23.

[AUTOMERGE]

#UE4 Fixed up GameplayTag usage in the SkillSystem module after merge from main

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2070710 by Fred.Kimberley on 2014/05/12 15:57:13.

#codereview Fred.Kimberley, David.Ratti

[CL 2078452 by Billy Bramer in Main branch]
2014-05-19 23:21:13 -04:00

133 lines
6.0 KiB
C++

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#include "SkillSystemModulePrivatePCH.h"
#include "GameplayTagsModule.h"
USkillSystemTestAttributeSet::USkillSystemTestAttributeSet(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
Health = MaxHealth = 100.f;
Mana = MaxMana = 100.f;
Damage = 0.f;
CritChance = 0.f;
SpellDamage = 0.f;
PhysicalDamage = 0.f;
Strength = 0.f;
StackingAttribute1 = 0.f;
StackingAttribute2 = 0.f;
NoStackAttribute = 0.f;
}
FGameplayTag RequestGameplayTag_TestAttributeSet(FName Name)
{
IGameplayTagsModule& GameplayTagsModule = IGameplayTagsModule::Get();
return GameplayTagsModule.GetGameplayTagsManager().RequestGameplayTag(Name);
}
void USkillSystemTestAttributeSet::PreAttributeModify(struct FGameplayEffectModCallbackData &Data)
{
static UProperty *HealthProperty = FindFieldChecked<UProperty>(USkillSystemTestAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED(USkillSystemTestAttributeSet, Health));
static UProperty *DamageProperty = FindFieldChecked<UProperty>(USkillSystemTestAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED(USkillSystemTestAttributeSet, Damage));
// In this function, our GameplayEffect mod has been evaluated. We have a magnitude and a Tags collection that we can still modify before it is applied.
// We also still have the Aggregation data that calculated Data.EvaluatedData. If we really needed to, we could look at this, remove or change things at the aggregator level, and reevaluate ourselves.
// But that would be considered very advanced/rare.
UProperty *ModifiedProperty = Data.ModifierSpec.Info.Attribute.GetUProperty();
// Is Damage about to be applied?
if (DamageProperty == ModifiedProperty)
{
// Can the target dodge this completely?
if (DodgeChance > 0.f)
{
if (FMath::FRand() <= DodgeChance)
{
// Dodge!
Data.EvaluatedData.Magnitude = 0.f;
Data.EvaluatedData.Tags.AddTag( RequestGameplayTag_TestAttributeSet(FName(TEXT("Dodged"))) );
// How dodge is handled will be game dependant. There are a few options I think of:
// -We still apply 0 damage, but tag it as Dodged. The GameplayCue system could pick up on this and play a visual effect. The combat log could pick up in and print it out too.
// -We throw out this GameplayEffect right here, and apply another GameplayEffect for 'Dodge' it wouldn't modify an attribute but could trigger gameplay cues, it could serve as a 'cooldown' for dodge
// if the game wanted rules like 'you can't dodge more than once every .5 seconds', etc.
}
}
if (Data.EvaluatedData.Magnitude > 0.f)
{
// Check the source - does he have Crit?
USkillSystemTestAttributeSet * SourceAttributes = Data.EffectSpec.InstigatorStack.GetOriginInstigatorAttributeComponent()->GetSet<USkillSystemTestAttributeSet>();
if (SourceAttributes && SourceAttributes->CritChance > 0.f)
{
if (FMath::FRand() <= SourceAttributes->CritChance)
{
// Crit!
Data.EvaluatedData.Magnitude *= SourceAttributes->CritMultiplier;
Data.EvaluatedData.Tags.AddTag( RequestGameplayTag_TestAttributeSet(FName(TEXT("Damage.Crit"))) );
}
}
// Now apply armor reduction
if (Data.EvaluatedData.Tags.HasTag( RequestGameplayTag_TestAttributeSet(FName(TEXT("Damage.Physical"))), EGameplayTagMatchType::IncludeParentTags, EGameplayTagMatchType::Explicit ))
{
// This is a trivial/naive implementation of armor. It assumes the rmorDamageReduction is an actual % to reduce physics damage by.
// Real games would probably use armor rating as an attribute and calculate a % here based on the damage source's level, etc.
Data.EvaluatedData.Magnitude *= (1.f - ArmorDamageReduction);
Data.EvaluatedData.Tags.AddTag( RequestGameplayTag_TestAttributeSet(FName(TEXT("Damage.Mitigatd.Armor"))) );
}
}
// At this point, the Magnitude of the applied damage may have been modified by us. We still do the translation to Health in USkillSystemTestAttributeSet::PostAttributeModify.
}
}
void USkillSystemTestAttributeSet::PostAttributeModify(const struct FGameplayEffectModCallbackData &Data)
{
static UProperty *HealthProperty = FindFieldChecked<UProperty>(USkillSystemTestAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED(USkillSystemTestAttributeSet, Health));
static UProperty *DamageProperty = FindFieldChecked<UProperty>(USkillSystemTestAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED(USkillSystemTestAttributeSet, Damage));
UProperty *ModifiedProperty = Data.ModifierSpec.Info.Attribute.GetUProperty();
// What property was modified?
if (DamageProperty == ModifiedProperty)
{
// Anytime Damage is applied with 'Damage.Fire' tag, there is a chance to apply a burning DOT
if (Data.EvaluatedData.Tags.HasTag( RequestGameplayTag_TestAttributeSet(FName(TEXT("FireDamage"))), EGameplayTagMatchType::IncludeParentTags, EGameplayTagMatchType::Explicit ))
{
// Logic to rand() a burning DOT, if successful, apply DOT GameplayEffect to the target
}
// Treat damage as minus health
Health -= Damage;
Damage = 0.f;
// Check for Death?
// -This could be defined here or at the actor level.
// -Doing it here makes a lot of sense to me, but we have legacy code in ::TakeDamage function, so some games may just want to punt to that pipeline from here.
}
}
void USkillSystemTestAttributeSet::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
{
/*
DOREPLIFETIME( USkillSystemTestAttributeSet, MaxHealth);
DOREPLIFETIME( USkillSystemTestAttributeSet, Health);
DOREPLIFETIME( USkillSystemTestAttributeSet, Mana);
DOREPLIFETIME( USkillSystemTestAttributeSet, MaxMana);
DOREPLIFETIME( USkillSystemTestAttributeSet, SpellDamage);
DOREPLIFETIME( USkillSystemTestAttributeSet, PhysicalDamage);
DOREPLIFETIME( USkillSystemTestAttributeSet, CritChance);
DOREPLIFETIME( USkillSystemTestAttributeSet, CritMultiplier);
DOREPLIFETIME( USkillSystemTestAttributeSet, ArmorDamageReduction);
DOREPLIFETIME( USkillSystemTestAttributeSet, DodgeChance);
DOREPLIFETIME( USkillSystemTestAttributeSet, LifeSteal);
DOREPLIFETIME( USkillSystemTestAttributeSet, Strength);
*/
}