FGAEffectHandle FGAActiveEffectContainer::ApplyEffect(const FGAEffectSpec& SpecIn, const FGAEffectContext& Ctx)
{
	switch (SpecIn.Policy.Type)
	{
	case EGAEffectType::Instant:
	{
		FGAEffectSpec& nonConst = const_cast<FGAEffectSpec&>(SpecIn);
		FGAEffectInstant instntEffect(nonConst, Ctx);
		return HandleInstantEffect(instntEffect, Ctx);
	}
	case EGAEffectType::Periodic:
	{	
		FGAEffectSpec& nonConst = const_cast<FGAEffectSpec&>(SpecIn);
		return HandleDurationEffect(nonConst, Ctx);
	}
	case EGAEffectType::Duration:
	{
		FGAEffectSpec& nonConst = const_cast<FGAEffectSpec&>(SpecIn);
		return HandleDurationEffect(nonConst, Ctx);
	}
	case EGAEffectType::Infinite:
	{
		break;
	}
	default:
	{
		return FGAEffectHandle();
	}
	}
	return FGAEffectHandle();
}
示例#2
0
FGAEffectHandle FGAActiveEffectContainer::ApplyEffect(TSubclassOf<class UGAEffectSpecification> SpecIn,
	const FGAEffectContext& Ctx, const FName& EffectName)
{
	if (!SpecIn)
		return FGAEffectHandle();

	FGAEffectSpec spec(SpecIn.GetDefaultObject(), Ctx);
	spec.EffectName.EffectName = EffectName;
	switch (spec.Policy.Type)
	{
	case EGAEffectType::Instant:
	{
		FGAEffectInstant instntEffect(spec, Ctx);
		return HandleInstantEffect(instntEffect, Ctx);
	}
	case EGAEffectType::Periodic:
	{
		return HandleDurationEffect(spec, Ctx);
	}
	case EGAEffectType::Duration:
	{
		return HandleDurationEffect(spec, Ctx);
	}
	case EGAEffectType::Infinite:
	{
		break;
	}
	default:
	{
		return FGAEffectHandle();
	}
	}
	return FGAEffectHandle();
}
FGAEffectHandle UGAAttributeComponent::ApplyEffectToTarget(const FGAGameEffect& EffectIn
	, const FGAGameEffectHandle& HandleIn)
{
	if(EffectIn.IsValid())
		return EffectIn.Context.TargetComp->ApplyEffectToSelf(EffectIn, HandleIn);
	return FGAEffectHandle();
}
FGAEffectHandle FGAActiveEffectContainer::HandleTargetAggregationEffect(FGAEffectSpec& EffectIn, const FGAEffectContext& Ctx)
{
	switch (EffectIn.Policy.Stacking)
	{
	case EGAEffectStacking::StrongerOverride:
	{
		return HandleTargetEffectStrongerOverride(EffectIn, Ctx);
	}
	case EGAEffectStacking::Override:
	{
		return HandleTargetEffectOverride(EffectIn, Ctx);
	}
	case EGAEffectStacking::Duration:
	{
		break;
	}
	case EGAEffectStacking::Intensity:
	{
		return HandleTargetEffectDuration(EffectIn, Ctx);
	}
	case EGAEffectStacking::Add:
	{
		return HandleTargetEffectAdd(EffectIn, Ctx);
	}
	default:
		break;
	}
	return FGAEffectHandle();
}
FGAEffectHandle FGAActiveEffectContainer::HandleDurationEffect(FGAEffectSpec& EffectIn, const FGAEffectContext& Ctx)
{
	//TODO::
	//1. Comment this.
	//2. Handle stacking.
	//3. Handle conditional effect applying (if have this tags, apply this effect)
	//4. effect apply effect. Not really important for Instant effect, but Duration based, have 
	//   stages at which additonal effects can be applied, and only those effects can know when to do it.
	//5. Add support for UObject effect extensions which are instanced per application, for special logic.

	/*
		Determine against whom we should check stacking rules.
		Idea is, if effect is grouped by Instigator, stacking rules are checked ONLY
		against other effects from the same instigator, and never checked against anything else.
		If effect is grouped by target, stacking rules, are checked ONLY against other effects, grouped
		by target.
		
		The two of them never talk to each other, and never check for each other effects.
		So you must be careful, when setting up effects, and stacking rules!.

		A good example, would Bleed Condition effect, and simple Corruption spell (which just deals damage over time).
		Bleed condition, would be aggregated by target. So who applied it wouldn't matter.
		Stacking rules, would be check for all existing bleed condition on target. So for example,
		we can set that there can only be ever ONE bleed condition on target, and strongest one
		will always override anything that is on target.

		Corruption would be stacked by Instigator. This means, that if two players attack one enemy, and
		they both apply Corruption to it, target will have TWO Corruption effects applied.
		Neither Corruption effect, cares, about the other. If one  player apply Corruption again,
		it will just check stacking rules against corruption, applied by the same player.

		If you want to make non stackable buffs (like +50hp, +100 mana etc), you should always aggregate
		aggregate them by Target.
		If you aggregate them by Instigator, various buffs, from various instigator will stack, togather.
		If one player will apply +50hp and other +100hp, in this case you will end up with +150HP buff.

		If you group by target, and set to Highest Override, only +100HP buff will be applied, and all
		others will be removed from target.
	*/
	switch (EffectIn.Policy.Aggregation)
	{
	case EGAEffectAggregation::AggregateByInstigator:
	{
		return HandleInstigatorAggregationEffect(EffectIn, Ctx);
		break;
	}
	case EGAEffectAggregation::AggregateByTarget:
	{
		return HandleTargetAggregationEffect(EffectIn, Ctx);
		break;
	}
	default:
		break;
	}

	//we got to this point, it should be safe to generate handle.

	return FGAEffectHandle();
}
FGAEffectHandle UGAAttributeComponent::ApplyEffectToSelf(const FGAGameEffect& EffectIn
	, const FGAGameEffectHandle& HandleIn)
{
	GameEffectContainer.ApplyEffect(EffectIn, HandleIn);

	//ExecuteEffect(EffectIn);
	return FGAEffectHandle();
}
FGAEffectHandle FGAActiveEffectContainer::HandleInstantEffect(FGAEffectInstant& SpecIn, const FGAEffectContext& Ctx)
{
	if (Ctx.TargetComp.IsValid() && Ctx.InstigatorComp.IsValid())
	{
		FGAEffectHandle handle;
		SpecIn.OnApplied();
	}
	return FGAEffectHandle();
}
FGAEffectHandle UGAAttributeComponent::ApplySelfEffect(AActor* Target, APawn* Instigator,
	UObject* Causer, FGAEffectSpec SpecIn)
{
	UE_LOG(GameAttributesEffects, Log, TEXT("Apply effect to self: %f , Effect: %d"), *GetOwner()->GetName(), *SpecIn.GetNameAsString());
	//this is bad btw. I need to change it. LAter.
	IIGAAttributes* targetAttr = Cast<IIGAAttributes>(Target);
	IIGAAttributes* instiAttr = Cast<IIGAAttributes>(Instigator);
	if (!targetAttr || !instiAttr)
		return FGAEffectHandle();

	UGAAttributeComponent* targetComp = targetAttr->GetAttributeComponent();
	UGAAttributeComponent* instiComp = instiAttr->GetAttributeComponent();
	FGAEffectContext context(Target->GetActorLocation(), Target, Causer,
		Instigator, targetComp, instiComp);

	SpecIn.Context = context;

	//SpecIn.GetModifiers();
	return FGAEffectHandle(); // ActiveEffects.ApplyEffect(SpecIn, context);
}
FGAEffectHandle FGAActiveEffectContainer::HandleInstigatorAggregationEffect(FGAEffectSpec& EffectIn, const FGAEffectContext& Ctx)
{
	/*
		1. StrongerOverride - if incoming effect of the same type as existing one (have the same
		EffectIn.MyTag), is stronger than existing one it will override it.
		Other wise existing effect, will remain unchanged on target.
		2. Override - Effect will simplt override existing effect on the same type.
		3. Duration - will take remaning duration of existing effect, and add it's duration to stack.
		Nothing else is changed.
		4. Inensity - Will add existing attribute modifiers, with the new one.
		Technically it might look like StackCount*Magnitude.
		5. Add - Adds new effect to stack. Check for nothing, and change nothing.
	*/
	switch (EffectIn.Policy.Stacking)
	{
		case EGAEffectStacking::StrongerOverride:
		{
			HandleInstigatorEffectStrongerOverride(EffectIn, Ctx);
			break;
		}
		case EGAEffectStacking::Override:
		{
			return HandleInstigatorEffectOverride(EffectIn, Ctx);
			break;
		}
		case EGAEffectStacking::Duration:
		{
			return HandleInstigatorEffectDuration(EffectIn, Ctx);
			break;
		}
		case EGAEffectStacking::Intensity:
		{
			break;
		}
		case EGAEffectStacking::Add:
		{
			return HandleInstigatorEffectAdd(EffectIn, Ctx);
			break;
		}
		default:
			break;
	}
	return FGAEffectHandle();
}
FGAEffectHandle UGAAttributeComponent::ApplySelfEffect(AActor* Target, APawn* Instigator,
	UObject* Causer, FGAEffectSpec SpecIn)
{
	//this is bad btw. I need to change it. LAter.
	IIGAAttributes* targetAttr = Cast<IIGAAttributes>(Target);
	IIGAAttributes* instiAttr = Cast<IIGAAttributes>(Instigator);
	if (!targetAttr || !instiAttr)
		return FGAEffectHandle();

	UGAAttributeComponent* targetComp = targetAttr->GetAttributeComponent();
	UGAAttributeComponent* instiComp = instiAttr->GetAttributeComponent();
	FGAEffectContext context(Target->GetActorLocation(), Target, Causer,
		Instigator, targetComp, instiComp);

	SpecIn.Context = context;

	//SpecIn.GetModifiers();
	return ActiveEffects.ApplyEffect(SpecIn, context);
}
示例#11
0
FGAEffectHandle UGABlueprintLibrary::ApplyEffectActorSpec(AActor* Target, APawn* Instigator,
	UObject* Causer, TSubclassOf<class UGAEffectSpecification> SpecIn)
{
	IIGAAttributes* targetAttr = Cast<IIGAAttributes>(Target);
	IIGAAttributes* instiAttr = Cast<IIGAAttributes>(Instigator);
	if (!targetAttr || !instiAttr)
		return FGAEffectHandle();

	UGAAttributeComponent* targetComp = targetAttr->GetAttributeComponent();
	UGAAttributeComponent* instiComp = instiAttr->GetAttributeComponent();
	FGAEffectContext context(Target->GetActorLocation(), Target, Causer,
		Instigator, targetComp, instiComp);
	FName EffectName;
	if (SpecIn.GetDefaultObject()->Policy.Type != EGAEffectType::Instant)
	{
		if (SpecIn.GetDefaultObject()->EffectName.CustomName)
			EffectName = SpecIn.GetDefaultObject()->EffectName.EffectName;
		else
			EffectName = SpecIn->GetFName();// Causer->GetClass()->GetFName();
	}

	//SpecIn.GetModifiers();
	return instiComp->ApplyEffectToTarget(SpecIn, context, EffectName);
}
void UGAAttributeComponent::RemoveEffectCue(int32 Handle)
{
	ActiveCues.CueRemoved(FGAEffectHandle(Handle));
}
void UGAAttributeComponent::MulticastEffectCueExpired_Implementation(int32 Handle)
{
	ActiveCues.CueExpired(FGAEffectHandle(Handle));
}
void UGAAttributeComponent::MulticastRemoveEffectCue_Implementation(int32 Handle)
{
	ActiveCues.CueRemoved(FGAEffectHandle(Handle));
}
FGAEffectHandle FGAActiveEffectContainer::HandleTargetEffectIntensity(FGAEffectSpec& EffectIn, const FGAEffectContext& Ctx)
{
	return FGAEffectHandle();
}
FGAEffectHandle	FGAActiveEffectContainer::HandleInstigatorEffectDIntensity(FGAEffectSpec& EffectIn, const FGAEffectContext& Ctx)
{
	return FGAEffectHandle();
}