void UGAAttributeComponent::InternalRemoveEffect(FGAGameEffectHandle& HandleIn)
{
	FTimerManager& timer = GetWorld()->GetTimerManager();
	timer.ClearTimer(HandleIn.GetEffectRef().PeriodTimerHandle);
	timer.ClearTimer(HandleIn.GetEffectRef().DurationTimerHandle);
	UE_LOG(GameAttributesEffects, Log, TEXT("UGAAttributeComponent:: Reset Timers and Remove Effect"));
	
	FGAGameEffect& Effect = HandleIn.GetEffectRef();
	TArray<FGAEffectMod> Mods = Effect.GetOnAppliedMods();

	for (FGAEffectMod& mod : Mods)
	{
		FGAAttributeBase* attr = DefaultAttributes->GetAttribute(mod.Attribute);
		if (attr)
		{
			UE_LOG(GameAttributes, Log, TEXT("Value Before bonus of attribute = %f"), attr->GetFinalValue());
			attr->RemoveBonus(HandleIn);
			UE_LOG(GameAttributes, Log, TEXT("Value After bonus of attribute = %f"), attr->GetFinalValue());
			
		}
	}
	
	GameEffectContainer.RemoveEffect(HandleIn);


}
void FGAGameEffectContainer::InternalApplyDuration(const FGAGameEffectHandle& HandleIn)
{
	FTimerDelegate delDuration = FTimerDelegate::CreateUObject(HandleIn.GetContext().TargetComp.Get(), &UGAAttributeComponent::ExpireEffect, HandleIn);
	FTimerManager& timerDuration = HandleIn.GetEffectRef().Context.TargetComp->GetWorld()->GetTimerManager();

	timerDuration.SetTimer(HandleIn.GetEffectRef().DurationTimerHandle, delDuration,
		HandleIn.GetEffectSpec()->Duration, false, HandleIn.GetEffectSpec()->Duration);

	TArray<FGAEffectMod> Modifiers = HandleIn.GetEffectRef().GetAttributeModifiers();
	EGAEffectStacking Stacking = HandleIn.GetEffectSpec()->EffectStacking;
	InternalApplyEffectTags(HandleIn);
	for (FGAEffectMod& Modifier : Modifiers)
	{
		if (Modifier.Attribute.IsValid())
		{
			UGAAttributesBase* attr = HandleIn.GetContextRef().GetTargetAttributes();
			FGAAttributeBase* Attribute = attr->GetAttribute(Modifier.Attribute);

			if (Attribute)
			{
				Attribute->AddBonus(FGAModifier(Modifier.AttributeMod, Modifier.Value), HandleIn, Stacking);
			}
		}
	}
}
float UGAAttributesBase::GetFinalAttributeValue(const FGAAttribute& Name)
{
	FGAAttributeBase* attrPtr = GetAttribute(Name);
	if (attrPtr)
	{
		return attrPtr->GetFinalValue();
	}
	return 0;
}
Beispiel #4
0
void FGAGameEffectContainer::RemoveEffect(FGAGameEffectHandle& HandleIn)
{
	EGAEffectAggregation aggregatiopn = HandleIn.GetEffectRef().GameEffect->EffectAggregation;
	UObject* Instigator = HandleIn.GetContextRef().Instigator.Get();
	TSharedPtr<FGAGameEffect> effect = ActiveEffects.FindAndRemoveChecked(HandleIn);

	if (effect.IsValid())
	{
		switch (aggregatiopn)
		{
			case EGAEffectAggregation::AggregateByInstigator:
			{
				TMap<FGAGameEffectHandle, TSharedPtr<FGAGameEffect>>* effects = InstigatorEffects.Find(Instigator);
				TMap<FName, TSet<FGAGameEffectHandle>>* EffectByClass = InstigatorEffectHandles.Find(Instigator);
				if (EffectByClass)
				{
					//Probabaly need another path for removing just single effect from stack.
					EffectByClass->Remove(HandleIn.GetEffectSpec()->GetFName());
				}
				if (effects)
				{
					effects->FindAndRemoveChecked(HandleIn);
					if (effects->Num() == 0)
					{
						InstigatorEffects.Remove(Instigator);
					}
				}
				break;
			}
			case EGAEffectAggregation::AggregateByTarget:
			{
				//TargetEffects.FindAndRemoveChecked(HandleIn);
				TSet<FGAGameEffectHandle>* Handles = TargetEffectByType.Find(HandleIn.GetEffectSpec()->GetFName());
				//check aggregation type to know which effect to remove exactly ?
				TargetEffectByType.Remove(HandleIn.GetEffectSpec()->GetFName());
				break;
			}
		}
		for (FGAGameEffectModifier& Modifier : effect->GameEffect->Modifiers)
		{
			if (Modifier.Attribute.IsValid())
			{
				FGAAttributeBase* Attribute = OwningComp->GetAttribute(Modifier.Attribute);
				if (Attribute)
				{
					Attribute->RemoveBonus(HandleIn);
				}
			}
		}
		UE_LOG(GameAttributesEffects, Log, TEXT("FGAGameEffectContainer:: Removing Effect"))
			effect.Reset();
	}
}
Beispiel #5
0
FGAEffectHandle	FGAActiveEffectContainer::HandleInstigatorEffectStrongerOverride(FGAEffectSpec& EffectIn, const FGAEffectContext& Ctx)
{
	/*
		How does it work ?
		1. If there effect of the same name active, we find it and remove it.
		WE can safely assume, that effect of the same name is either the same or stronger.
		2. For effect modifiers, we don't check for effect, we just check for it's tag and type.
		If it is weaker, remove it, and replace with new one.
		3. The same goes for attribute modifiers.

		It's bit inconsistent to say at least..
	*/
	FGAInstigatorEffectContainer& instCont = InstigatorEffects.FindOrAdd(Ctx.InstigatorComp);
	FGAEffectHandle foundHandle;
	for (FGAEffectTagHandle& eff : instCont.Effects)
	{
		if (eff.EffectName == EffectIn.EffectName)
		{
			foundHandle = eff.Handle;
			break;
		}
	}

	/*
		If stacking is StrongerOverride, we first check if attribute is already modified by anything.
		If it is, we remove any applicable mods which are weaker than ours.

		We do not make any checks for tags or other effects, They are of no concern to us, when it comes
		to modifing complex attribute.
	*/

	TArray<FGAAttributeData> AttributeModifiers = EffectIn.EffectSpec->GetDurationAttribute(Ctx);
	for (const FGAAttributeData& data : AttributeModifiers)
	{
		FGAAttributeBase* AtrPtr = Ctx.TargetComp->GetAttribute(data.Attribute);
		if (AtrPtr)
		{
			AtrPtr->RemoveWeakerBonus(data.Mod, data.Value);
		}
	}

	ModifierContainer.RemoveWeakerModifiers(EffectIn.EffectSpec->RequiredTags, EffectIn.EffectSpec->EffectModifiers);

	RemoveActiveEffect(foundHandle);
	FGAEffectHandle handle = AddActiveEffect(EffectIn, Ctx);

	FGAEffectTagHandle nameHandle(EffectIn.EffectName, handle);
	instCont.Effects.Add(nameHandle);
	return handle;
}
void FGAGameEffectContainer::RemoveEffect(FGAGameEffectHandle& HandleIn)
{
	EGAEffectAggregation aggregatiopn = HandleIn.GetEffectRef().GameEffect->EffectAggregation;
	UObject* Instigator = HandleIn.GetContextRef().Instigator.Get();
	TSharedPtr<FGAGameEffect> effect = ActiveEffects.FindAndRemoveChecked(HandleIn);

	if (effect.IsValid())
	{
		switch (aggregatiopn)
		{
		case EGAEffectAggregation::AggregateByInstigator:
		{
			TMap<FGAGameEffectHandle, TSharedPtr<FGAGameEffect>>* effects = InstigatorEffects.Find(Instigator);
			TMap<UClass*, FGAGameEffectHandle>* EffectByClass = InstigatorEffectHandles.Find(Instigator);
			if (EffectByClass)
			{
				EffectByClass->Remove(HandleIn.GetEffectSpec()->StaticClass());
			}
			if (effects)
			{
				effects->FindAndRemoveChecked(HandleIn);
				if (effects->Num() == 0)
				{
					InstigatorEffects.Remove(Instigator);
				}
			}
			break;
		}
		case EGAEffectAggregation::AggregateByTarget:
		{
			TargetEffects.FindAndRemoveChecked(HandleIn);
			break;
		}
		}
		for (FGAGameEffectModifier& Modifier : effect->GameEffect->Modifiers)
		{
			if (Modifier.Attribute.IsValid())
			{
				FGAAttributeBase* Attribute = OwningComp->GetAttribute(Modifier.Attribute);
				if (Attribute)
				{
					Attribute->RemoveBonus(HandleIn);
				}
			}
		}
		UE_LOG(GameAttributesEffects, Log, TEXT("FGAGameEffectContainer:: Removing Effect"))
			effect.Reset();
	}
}
void FGAGameEffectContainer::InternalApplyModifiers(const FGAGameEffectHandle& HandleIn)
{
	TArray<FGAGameEffectModifier>& Modifiers = HandleIn.GetEffectSpec()->Modifiers;
	EGAEffectStacking Stacking = HandleIn.GetEffectSpec()->EffectStacking;
	for (FGAGameEffectModifier& Modifier : Modifiers)
	{
		if (Modifier.Attribute.IsValid())
		{
			UGAAttributesBase* attr = HandleIn.GetContextRef().GetTargetAttributes();
			FGAAttributeBase* Attribute = attr->GetAttribute(Modifier.Attribute);

			if (Attribute)
			{
				Attribute->AddBonus(FGAModifier(Modifier.ModType, Modifier.Value), HandleIn, Stacking);
			}
		}
	}
}
void UGAAttributeComponent::ApplyEffectForDuration(FGAGameEffectHandle& HandleIn)
{
	FGAGameEffect& Effect = HandleIn.GetEffectRef();
	TArray<FGAEffectMod> Mods = Effect.GetOnAppliedMods();

	for (FGAEffectMod& mod : Mods)
	{
		FGAAttributeBase* attr = DefaultAttributes->GetAttribute(mod.Attribute);
		if (attr)
		{
			FGAModifier Modifier(mod.AttributeMod, mod.Value);
			float val = attr->GetFinalValue();
			UE_LOG(GameAttributes, Log, TEXT("Value Before bonus of attribute = %f"), val);
			attr->AddBonus(Modifier, HandleIn, EGAEffectStacking::Override);
			val = attr->GetFinalValue();
			UE_LOG(GameAttributes, Log, TEXT("Value After bonus of attribute = %f"), val);
		}
	}
}
void FGAActiveDuration::FinishEffect()
{
	if (Context.Target.IsValid())
	{
		Context.Target->GetWorldTimerManager().ClearTimer(PeriodTimerHandle);
		Context.Target->GetWorldTimerManager().ClearTimer(DurationTimerHandle);
	}

	if (Context.TargetComp.IsValid())
	{
		for (const FGAAttributeData& data : DurationAttribute)
		{
			FGAAttributeBase* attr = Context.TargetComp->GetAttribute(data.Attribute);
			if (attr)
			{
				attr->RemoveBonus(MyHandle);
			}
		}
	}
}
Beispiel #10
0
void FGAActiveDuration::OnApplied()
{
	TArray<FGAAttributeData> InitialModifiers = EffectSpec->GetInitialAttribute(Context);
	for (const FGAAttributeData& data : InitialModifiers)
	{
		//FGAAttributeData data = InitialAttribute;
		if (Context.InstigatorComp.IsValid())
			Context.InstigatorComp->ModifyAttributesOnTarget(data, Context, OwnedTags, MyHandle);
	}
	TArray<FGAAttributeData> AttributeModifiers = EffectSpec->GetDurationAttribute(Context);
	for (const FGAAttributeData& data : AttributeModifiers)
	{
		FGAAttributeBase* attr = Context.TargetComp->GetAttribute(data.Attribute);
		if (attr)
		{
			TSharedPtr<FGAActiveDuration> temp = AsShared();
			attr->AddBonus(FGAModifier(data.Mod, data.Value, temp), MyHandle);
		}
	}
}
void UGAEffectExecution::ExecuteEffect(const FGAGameEffectHandle& HandleIn, FGAEffectMod& ModIn, FGAExecutionContext& Context)
{
	UE_LOG(GameAttributesEffects, Log, TEXT("Sample execution class implementation"));
	
	FGAAttributeBase* TargetAttribute = Context.GetTargetAttribute(ModIn.Attribute);
	if (TargetAttribute)
	{
		switch (ModIn.ChangeType)
		{
		case EGAAttributeChangeType::Damage:
			UE_LOG(GameAttributesEffects, Log, TEXT("Sample execution::Damage Value = %f"), ModIn.Value);
			TargetAttribute->Subtract(ModIn.Value);
			break;
		case EGAAttributeChangeType::DamagePercentage:
			break;
		case EGAAttributeChangeType::Heal:
			TargetAttribute->Add(ModIn.Value);
			break;
		case EGAAttributeChangeType::HealPercentage:
			break;
		}
	}
}
void FGAActiveDuration::OnApplied()
{
	for (const FGAAttributeData& data : PeriodModifiers)
	{
		//FGAAttributeData data = InitialAttribute;
		if (Context.InstigatorComp.IsValid())
			Context.InstigatorComp->ModifyAttributesOnTarget(data, Context, OwnedTags, MyHandle);
	}	
	/*
		If stacking is StrongerOverride, we first check if attribute is already modified by anything.
		If it is, we remove any applicable mods which are weaker than ours.

		We do not make any checks for tags or other effects, They are of no concern to us, when it comes
		to modifing complex attribute.
	*/
	if (Stacking == EGAEffectStacking::StrongerOverride)
	{
		for (const FGAAttributeData& data : DurationAttribute)
		{
			FGAAttributeBase* AtrPtr = Context.TargetComp->GetAttribute(data.Attribute);
			if (AtrPtr)
			{
				AtrPtr->RemoveWeakerBonus(data.Mod, data.Value);
			}
		}
	}

	for (const FGAAttributeData& data : DurationAttribute)
	{
		FGAAttributeBase* attr = Context.TargetComp->GetAttribute(data.Attribute);
		if (attr)
		{
			TSharedPtr<FGAActiveDuration> temp = AsShared();
			attr->AddBonus(FGAModifier(data.Mod, data.Value, temp), MyHandle);
		}
	}
}
Beispiel #13
0
FGAEffectHandle FGAActiveEffectContainer::HandleInstigatorEffectOverride(FGAEffectSpec& EffectIn, const FGAEffectContext& Ctx)
{
	FGAInstigatorEffectContainer& instCont = InstigatorEffects.FindOrAdd(Ctx.InstigatorComp);
	FGAEffectHandle foundHandle;// = instCont.EffectsByName.FindRef(EffectIn.EffectName);
	for (FGAEffectTagHandle& eff : instCont.Effects)
	{
		if (eff.EffectName == EffectIn.EffectName)
		{
			foundHandle = eff.Handle;
			break;
		}
	}
	ModifierContainer.RemoveModifiersByType(EffectIn.EffectSpec->RequiredTags, EffectIn.EffectSpec->EffectModifiers);

	/*
		1. If effect is set to override should:
		a). Remove all attribute modifiers, which are the same as ours ?
		b). Or should we just override modifiers, applied by the same effect (identified, by effects name/handle).
	*/
	TArray<FGAAttributeData> AttributeModifiers = EffectIn.EffectSpec->GetDurationAttribute(Ctx);
	for (const FGAAttributeData& data : AttributeModifiers)
	{
		FGAAttributeBase* AtrPtr = Ctx.TargetComp->GetAttribute(data.Attribute);
		if (AtrPtr)
		{
			AtrPtr->RemoveBonusByType(data.Mod);
		}
	}

	RemoveActiveEffect(foundHandle);

	FGAEffectHandle handle = AddActiveEffect(EffectIn, Ctx);
	FGAEffectTagHandle nameHandle(EffectIn.EffectName, handle);
	instCont.Effects.Add(nameHandle);

	return handle;
}