Files
UnrealEngineUWP/Engine/Source/Runtime/SkillSystem/Private/SkillSystemTestAttributeSet.cpp
Billy Bramer 8dd6c092d2 Second batch of merging of gameplay tag changes.
#codereview Fred.Kimberley

[AUTOMERGE]

fixed smasher picking first non tagged skill for wall attacks

#codereview Billy.Bramer

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2070195 by Lukasz.Furman on 2014/05/12 06:41:54.

[AUTOMERGE]

- Back out changelist 2070195, which caused bugs in other areas (player skills not working correctly)
- Fix bug in MatchesAll in tag container (only care that filter results > 0)
- Allow MatchesAny/All in tag container to specify whether an empty container should count as a match or not

- Fortnite AI still afflicted with issues due to content problem with interface nodes. Email pending re: how to resolve

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2071165 by Billy.Bramer on 2014/05/12 22:31:32.

[AUTOMERGE]

- Remove deprecated function usage from tag asset interface
- Remove deprecated function usage from Fortnite
#fortress

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

[AUTOMERGE]

- Minor commenting/clean-up on recent gameplay tag stuff

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2072435 by Billy.Bramer on 2014/05/13 22:04:18.

[AUTOMERGE]

- Clean up on some tag refactor stuff; Give the tag module a static function for requesting tags

--------
Integrated using branch Ue4-To-UE4-Fortnite-Simple (reversed) of change#2072475 by Billy.Bramer on 2014/05/13 22:50:45.

[CL 2079409 by Billy Bramer in Main branch]
2014-05-20 16:40:26 -04:00

127 lines
5.8 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;
}
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(IGameplayTagsModule::RequestGameplayTag(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(IGameplayTagsModule::RequestGameplayTag(FName(TEXT("Damage.Crit"))));
}
}
// Now apply armor reduction
if (Data.EvaluatedData.Tags.HasTag(IGameplayTagsModule::RequestGameplayTag(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(IGameplayTagsModule::RequestGameplayTag(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( IGameplayTagsModule::RequestGameplayTag(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);
*/
}