Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Search Gists
Sign in Sign up

Instantly share code, notes, and snippets.

@michaeltchapman
CreatedApril 8, 2020 15:16
    • Star(2)You must be signed in to star a gist
    • Fork(1)You must be signed in to fork a gist
    Save michaeltchapman/e305f6468f302f52a85ca767935afb08 to your computer and use it in GitHub Desktop.
    #include"EffectTypes.h"
    #include"maladius.h"
    #include"AbilitySystemGlobals.h"
    #include"AbilitySystemComponent.h"
    #include"AsyncAbilitySystemComponent.h"
    #include"GlobalGameStateBase.h"
    #include"GameplayEffect.h"
    #include"GameplayAbility.h"
    #include"BaseGameplayAbility.h"
    #include"BaseCharacter.h"
    #include"Spell.h"
    boolFMActorFilter::PassesFilter(UAbilitySystemComponent* Source, UAbilitySystemComponent* Target)
    {
    if (AllowSelf != EMActorFilterMatchType::Skip && ((Source == Target) != (AllowSelf == EMActorFilterMatchType::MustPass)))
    {
    returnfalse;
    }
    returntrue;
    }
    boolFMFactionFilter::PassesFilter(UAbilitySystemComponent* Source, UAbilitySystemComponent* Target)
    {
    ABaseCharacter* SourceChar = Cast<ABaseCharacter>(Source->GetAvatarActor());
    ABaseCharacter* TargetChar = Cast<ABaseCharacter>(Target->GetAvatarActor());
    if (SourceChar && TargetChar)
    {
    AGlobalGameStateBase *GameState = Cast<AGlobalGameStateBase>(SourceChar->GetWorld()->GetGameState());
    check(GameState);
    EHostility Relationship = GameState->GetHostility(SourceChar->GetFactionIndex(), TargetChar->GetFactionIndex());
    bool FriendlyTest =false;
    if (FriendlyFaction == EMFactionFilterMatchType::Skip)
    {
    FriendlyTest =true;
    }
    elseif (FriendlyFaction == EMFactionFilterMatchType::MustPass && Relationship == EHostility::E_Friendly)
    {
    FriendlyTest =true;
    }
    elseif (FriendlyFaction == EMFactionFilterMatchType::MustFail && Relationship != EHostility::E_Friendly)
    {
    FriendlyTest =true;
    }
    bool NeutralTest =false;
    if (NeutralFaction == EMFactionFilterMatchType::Skip)
    {
    NeutralTest =true;
    }
    elseif (NeutralFaction == EMFactionFilterMatchType::MustPass && Relationship == EHostility::E_Neutral)
    {
    NeutralTest =true;
    }
    elseif (NeutralFaction == EMFactionFilterMatchType::MustFail && Relationship != EHostility::E_Neutral)
    {
    NeutralTest =true;
    }
    bool HostileTest =false;
    if (HostileFaction == EMFactionFilterMatchType::Skip)
    {
    HostileTest =true;
    }
    elseif (HostileFaction == EMFactionFilterMatchType::MustPass && Relationship == EHostility::E_Hostile)
    {
    HostileTest =true;
    }
    elseif (HostileFaction == EMFactionFilterMatchType::MustFail && Relationship != EHostility::E_Hostile)
    {
    HostileTest =true;
    }
    return HostileTest && NeutralTest && FriendlyTest;
    }
    returntrue;
    }
    voidFMEffectApplicationContainer::InitialiseEffectContainer(AActor* Source,float VariableLevel,float NormalisedCharge,float VariableRatio,float NormalisedRatio, AActor* AbilityOrigin,float Period,bool bClean)
    {
    if (UAbilitySystemComponent* ASC =UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Source))
    {
    SourceAbilitySystemComponent = ASC;
    for (FMEffectApplicationItem& Item : Items)
    {
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GeneratedSpec.IsValid())
    {
    if (bClean)
    {
    EffectItem.GeneratedSpec.Clear();
    }
    else {
    UE_LOG(LogTemp, Warning,TEXT("GenerateEffectSpecs called on ApplicationContainer that already has generated specs!"));
    continue;
    }
    }
    if (*EffectItem.GameplayEffect ==nullptr)
    {
    UE_LOG(LogTemp, Warning,TEXT("GenerateEffectSpecs called on ApplicationContainer with invalid GameplayEffect!"));
    continue;
    }
    float Level =GetLevelForEffect(EffectItem, VariableLevel, NormalisedCharge, VariableRatio, NormalisedRatio) * Period;
    int32 StackCount = EffectItem.StackCount;
    if (AbilityOrigin && Cast<ASpell>(AbilityOrigin) && Cast<ASpell>(AbilityOrigin)->OwningAbility)
    {
    UBaseGameplayAbility* SourceAbility = Cast<ASpell>(AbilityOrigin)->OwningAbility;
    if (SourceAbility)
    {
    EffectItem.GeneratedSpec = SourceAbility->MakeGameplayEffectSpec(EffectItem.GameplayEffect, Level);
    }
    }
    else {
    FGameplayEffectContextHandle ContextHandle = ASC->MakeEffectContext();
    if (AbilityOrigin && Source->GetInstigator())
    {
    ContextHandle.AddInstigator(Source->GetInstigator(), AbilityOrigin);
    }
    else {
    ContextHandle.AddInstigator(Source, Source);
    }
    EffectItem.GeneratedSpec =FGameplayEffectSpecHandle(newFGameplayEffectSpec(EffectItem.GameplayEffect.GetDefaultObject(), ContextHandle, Level));
    }
    EffectItem.GeneratedSpec.Data->StackCount = StackCount;
    for (FMEffectModifier& Modifier : EffectItem.Modifiers)
    {
    EffectItem.GeneratedSpec.Data->SetSetByCallerMagnitude(Modifier.ModifierName,GetLevelForStrategy(Modifier.ModifierLevelStrategy, Modifier.ModifierMagnitude, VariableLevel, NormalisedCharge, VariableRatio, NormalisedRatio * Period));
    }
    }
    }
    }
    else
    {
    UE_LOG(LogTemp, Warning,TEXT("GenerateEffectSpecs called on Source %s with no ASC"), *GetNameSafe(Source));
    }
    }
    floatFMEffectApplicationContainer::GetLevelForEffect(FMEffectItem &Item,float VariableLevel,float NormalisedCharge,float VariableRatio,float NormalisedRatio)
    {
    returnGetLevelForStrategy(Item.LevelStrategy, Item.Level, VariableLevel, NormalisedCharge, VariableRatio, NormalisedRatio);
    }
    floatFMEffectApplicationContainer::GetLevelForStrategy(EMEffectLevelStrategy Strategy,float Base,float VariableLevel,float NormalisedCharge,float VariableRatio,float NormalisedRatio)
    {
    switch (Strategy)
    {
    case EMEffectLevelStrategy::Base:
    return Base;
    case EMEffectLevelStrategy::BaseVarianceCharge:
    return Base + VariableLevel*NormalisedCharge;
    case EMEffectLevelStrategy::BaseVarianceInvCharge:
    return Base + VariableLevel*(1.0f - NormalisedCharge);
    case EMEffectLevelStrategy::BaseVarianceRatio:
    return Base + VariableRatio*NormalisedRatio;
    case EMEffectLevelStrategy::BaseVarianceInvRatio:
    return Base + VariableRatio*(1.0f - NormalisedRatio);
    case EMEffectLevelStrategy::BaseVarianceInvChargeInvRatio:
    return Base + VariableRatio*(1.f - NormalisedRatio) + VariableLevel*(1.f - NormalisedCharge);
    case EMEffectLevelStrategy::BaseVarianceChargeInvRatio:
    return Base + VariableRatio*(1.f - NormalisedRatio) + VariableLevel*NormalisedCharge;
    case EMEffectLevelStrategy::BaseVarianceChargeRatio:
    return Base + VariableRatio*NormalisedRatio + VariableLevel*NormalisedCharge;
    case EMEffectLevelStrategy::BaseVarianceChargeSquared:
    return Base + VariableLevel*NormalisedCharge*NormalisedCharge;
    case EMEffectLevelStrategy::BaseVarianceChargeSquaredRatioSquared:
    return Base + VariableLevel * NormalisedCharge*NormalisedCharge + VariableRatio * NormalisedRatio*NormalisedRatio;
    case EMEffectLevelStrategy::BaseVarianceChargeSquaredInvRatioSquared:
    return Base + VariableLevel * NormalisedCharge*NormalisedCharge + VariableRatio * (1.f-NormalisedRatio)*(1.f-NormalisedRatio);
    default:
    return Base;
    break;
    }
    }
    voidFMEffectApplicationContainer::GenerateEffectSpecs(AActor* Source,float LevelOverride, int32 StackOverride, AActor* AbilityOrigin)
    {
    if (UAbilitySystemComponent* ASC =UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Source))
    {
    SourceAbilitySystemComponent = ASC;
    for (FMEffectApplicationItem& Item : Items)
    {
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GeneratedSpec.IsValid())
    {
    UE_LOG(LogTemp, Warning,TEXT("GenerateEffectSpecs called on ApplicationContainer that already has generated specs!"));
    continue;
    }
    if (*EffectItem.GameplayEffect ==nullptr)
    {
    UE_LOG(LogTemp, Warning,TEXT("GenerateEffectSpecs called on ApplicationContainer with invalid GameplayEffect!"));
    continue;
    }
    float Level = LevelOverride >0.f ? LevelOverride : EffectItem.Level;
    int32 StackCount = StackOverride >0 ? StackOverride : EffectItem.StackCount;
    if (AbilityOrigin && Cast<ASpell>(AbilityOrigin) && Cast<ASpell>(AbilityOrigin)->OwningAbility)
    {
    UBaseGameplayAbility* SourceAbility = Cast<ASpell>(AbilityOrigin)->OwningAbility;
    if (SourceAbility)
    {
    EffectItem.GeneratedSpec = SourceAbility->MakeGameplayEffectSpec(EffectItem.GameplayEffect, Level);
    }
    }
    else {
    FGameplayEffectContextHandle ContextHandle = ASC->MakeEffectContext();
    if (AbilityOrigin && Source->GetInstigator())
    {
    ContextHandle.AddInstigator(Source->GetInstigator(), AbilityOrigin);
    }
    else {
    ContextHandle.AddInstigator(Source, AbilityOrigin);
    }
    EffectItem.GeneratedSpec =FGameplayEffectSpecHandle(newFGameplayEffectSpec(EffectItem.GameplayEffect.GetDefaultObject(), ContextHandle, Level));
    }
    EffectItem.GeneratedSpec.Data->StackCount = StackCount;
    for (FMEffectModifier& Modifer : EffectItem.Modifiers)
    {
    EffectItem.GeneratedSpec.Data->SetSetByCallerMagnitude(Modifer.ModifierName, Modifer.ModifierMagnitude);
    }
    }
    }
    }
    else
    {
    UE_LOG(LogTemp, Warning,TEXT("GenerateEffectSpecs called on Source %s with no ASC"), *GetNameSafe(Source));
    }
    }
    voidFMEffectApplicationContainer::SetCallerMagnitude(FName AttributeName,float Magnitude)
    {
    for (FMEffectApplicationItem& Item : Items)
    {
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    EffectItem.GeneratedSpec.Data->SetSetByCallerMagnitude(AttributeName, Magnitude);
    }
    }
    }
    voidFMEffectApplicationContainer::SetCallerMagnitudeOnEffect(FName AttributeName,float Magnitude, TSubclassOf<UGameplayEffect> Effect)
    {
    if (Effect)
    {
    for (FMEffectApplicationItem& Item : Items)
    {
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GameplayEffect == Effect)
    {
    EffectItem.GeneratedSpec.Data->SetSetByCallerMagnitude(AttributeName, Magnitude);
    }
    }
    }
    }
    }
    voidFMEffectApplicationContainer::AddModifierForEffect(FName AttributeName,float Magnitude, TSubclassOf<UGameplayEffect> Effect)
    {
    if (Effect)
    {
    for (FMEffectApplicationItem& Item : Items)
    {
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GameplayEffect == Effect)
    {
    EffectItem.Modifiers.Add(FMEffectModifier(AttributeName, Magnitude));
    }
    }
    }
    }
    }
    voidFMEffectApplicationContainer::AddHitResult(FHitResult Result)
    {
    for (FMEffectApplicationItem& Item : Items)
    {
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GeneratedSpec.Data.IsValid())
    {
    EffectItem.GeneratedSpec.Data->GetContext().AddHitResult(Result,true);
    }
    }
    }
    }
    boolFMEffectApplicationContainer::ApplyEffectApplicationContainerToTargetASC(UAsyncAbilitySystemComponent* TargetASC, FHitResult HitResult, EMCueSimulation SimulateCue)
    {
    bool RetVal =false;
    if (TargetASC)
    {
    if (!SourceAbilitySystemComponent)
    {
    UE_LOG(LogTemp, Warning,TEXT("ApplyEffectApplicationContainerToTarget called on container with no SourceAbilitySystemComponent. call GeneratEffectSpecs first"));
    returnfalse;
    }
    for (FMEffectApplicationItem& Item : Items)
    {
    if (Item.Filter.PassesFilter(SourceAbilitySystemComponent, TargetASC) ==false)
    {
    continue;
    }
    if (Item.FactionFilter.PassesFilter(SourceAbilitySystemComponent, TargetASC) ==false)
    {
    continue;
    }
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GeneratedSpec.IsValid() ==false)
    {
    UE_LOG(LogTemp, Warning,TEXT("ApplyEffectApplicationContainerToTarget called on ApplicationContainer that has NO generated specs!"));
    continue;
    }
    if (!EffectItem.GeneratedSpec.Data->GetContext().GetHitResult())
    {
    if (!HitResult.GetActor())
    {
    HitResult.Actor = TargetASC->GetAvatarActor();
    }
    AddHitResult(HitResult);
    }
    FActiveGameplayEffectHandle NewHandle;
    if (SourceAbilitySystemComponent->ScopedPredictionKey.IsLocalClientKey() || SourceAbilitySystemComponent->IsOwnerActorAuthoritative())
    {
    NewHandle = TargetASC->ApplyGameplayEffectSpecToSelf(*EffectItem.GeneratedSpec.Data.Get(), SourceAbilitySystemComponent->ScopedPredictionKey);
    }
    else {
    // Execute client-side instant FX and triggers cues
    TargetASC->SimulateEffect(*EffectItem.GeneratedSpec.Data.Get());
    }
    /*
    // Ghetto weak prediction
    // If we're a client, check if the spec can be applied and if so, execute its weak predicted cues immediately
    if (SimulateCue == EMCueSimulation::Local && TargetASC->GetNetMode() != ENetMode::NM_DedicatedServer)
    {
    }*/
    if (NewHandle.WasSuccessfullyApplied())
    {
    RetVal =true;
    }
    }
    }
    }
    return RetVal;
    }
    boolFMEffectApplicationContainer::ApplyEffectApplicationContainerToTarget(AActor* Target, UBaseGameplayAbility* SourceAbility, FHitResult HitResult, EMCueSimulation CueSimulation)
    {
    bool RetVal =false;
    if (SourceAbilitySystemComponent ==nullptr)
    {
    UE_LOG(LogTemp, Warning,TEXT("ApplyEffectApplicationContainerToTarget called on container with no SourceAbilitySystemComponent. call GeneratEffectSpecs first"));
    returnfalse;
    }
    UAsyncAbilitySystemComponent* ASC = Cast<UAsyncAbilitySystemComponent>(UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Target));
    returnApplyEffectApplicationContainerToTargetASC(ASC, HitResult, CueSimulation);
    /*
    if (UAsyncAbilitySystemComponent* ASC = Cast<UAsyncAbilitySystemComponent>(UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Target)))
    {
    for (FMEffectApplicationItem& Item : Items)
    {
    if (Item.Filter.PassesFilter(SourceAbilitySystemComponent, ASC) == false)
    {
    continue;
    }
    if (Item.FactionFilter.PassesFilter(SourceAbilitySystemComponent, ASC) == false)
    {
    continue;
    }
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GeneratedSpec.IsValid() == false)
    {
    UE_LOG(LogTemp, Warning, TEXT("ApplyEffectApplicationContainerToTarget called on ApplicationContainer that has NO generated specs!"));
    continue;
    }
    HitResult.Actor = Target;
    AddHitResult(HitResult);
    FActiveGameplayEffectHandle NewHandle;
    // Ghetto weak prediction
    // If we're a client, check if the spec can be applied and if so, execute its weak predicted cues immediately
    if (CueSimulation == EMCueSimulation::Local && ASC->GetNetMode() != ENetMode::NM_DedicatedServer)
    {
    // Execute client-side instant FX cues
    ASC->SimulateEffect(*EffectItem.GeneratedSpec.Data.Get());
    }
    NewHandle = ASC->ApplyGameplayEffectSpecToSelf(*EffectItem.GeneratedSpec.Data.Get(), SourceAbilitySystemComponent->ScopedPredictionKey);
    if (NewHandle.WasSuccessfullyApplied())
    {
    RetVal = true;
    }
    }
    }
    }
    return RetVal;*/
    }
    TArray<FActiveGameplayEffectHandle>FMEffectApplicationContainer::ApplyEffectApplicationContainerToTargetWithHandles(AActor* Target, UBaseGameplayAbility* SourceAbility)
    {
    TArray<FActiveGameplayEffectHandle> Handles;
    if (SourceAbilitySystemComponent ==nullptr)
    {
    UE_LOG(LogTemp, Warning,TEXT("ApplyEffectApplicationContainerToTarget called on container with no SourceAbilitySystemComponent. call GeneratEffectSpecs first"));
    return Handles;
    }
    if (UAbilitySystemComponent* ASC =UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Target))
    {
    for (FMEffectApplicationItem& Item : Items)
    {
    if (Item.Filter.PassesFilter(SourceAbilitySystemComponent, ASC) ==false)
    {
    continue;
    }
    if (Item.FactionFilter.PassesFilter(SourceAbilitySystemComponent, ASC) ==false)
    {
    continue;
    }
    for (FMEffectItem& EffectItem : Item.Effects)
    {
    if (EffectItem.GeneratedSpec.IsValid() ==false)
    {
    UE_LOG(LogTemp, Warning,TEXT("ApplyEffectApplicationContainerToTarget called on ApplicationContainer that has NO generated specs!"));
    continue;
    }
    //FActiveGameplayEffectHandle NewHandle = ASC->ApplyGameplayEffectSpecToSelf(*EffectItem.GeneratedSpec.Data.Get(), SourceAbilitySystemComponent->ScopedPredictionKey);
    FActiveGameplayEffectHandle NewHandle;
    if (SourceAbility)
    {
    NewHandle = SourceAbilitySystemComponent->ApplyGameplayEffectSpecToTarget(*EffectItem.GeneratedSpec.Data.Get(), ASC, SourceAbility->GetCurrentActivationInfo().GetActivationPredictionKey());
    }
    else {
    NewHandle = ASC->ApplyGameplayEffectSpecToSelf(*EffectItem.GeneratedSpec.Data.Get(), ASC->ScopedPredictionKey);
    }
    if (NewHandle.IsValid())
    {
    Handles.Add(NewHandle);
    }
    }
    }
    }
    return Handles;
    }
    voidFMEffectApplicationContainer::PopulateEffectContainer(FMEffectApplicationContainer &Container,
    TSubclassOf<UGameplayEffect> Effect,
    float Level,
    EMActorFilterMatchType SelfFilter,
    EMFactionFilterMatchType FriendlyFilter,
    EMFactionFilterMatchType NeutralFilter,
    EMFactionFilterMatchType HostileFilter)
    {
    FMEffectItem Item;
    Item.GameplayEffect = Effect;
    Item.Level = Level;
    FMEffectApplicationItem ApplicationItem;
    ApplicationItem.Effects.Add(Item);
    ApplicationItem.Filter.AllowSelf = SelfFilter;
    ApplicationItem.FactionFilter.FriendlyFaction = FriendlyFilter;
    ApplicationItem.FactionFilter.NeutralFaction = NeutralFilter;
    ApplicationItem.FactionFilter.HostileFaction = HostileFilter;
    Container.Items.Add(ApplicationItem);
    }
    #pragma once
    #include"GameplayEffectTypes.h"
    #include"GameplayEffect.h"
    #include"EffectTypes.generated.h"
    /*
    Depending on the type of event occurring, we might fall into a few different categories, each requiring different replication strategies.
    We want to avoid having the cue fire twice, so mainly either:
    - cues fire locally on all clients
    - cue is fired replicated from server
    - cue is fired replicated from instigating client
    */
    UENUM()
    enumclassEMCueSimulation :uint8
    {
    /** Cues are fired locally, no replication. */
    Local,
    /** Cue is executed from the server via ASC and replicated */
    Server,
    /** Cue is executed from instigating client and replicated */
    Instigator,
    };
    UENUM()
    enumclassEMActorFilterMatchType :uint8
    {
    /** Skip this check completely. */
    Skip,
    /** Actor must pass this check (true) */
    MustPass,
    /** Actor must fail this check (not true) */
    MustFail,
    };
    UENUM()
    enumclassEMFactionFilterMatchType :uint8
    {
    /** Skip this check completely. */
    Skip,
    /** Actor must pass this check (true) */
    MustPass,
    /** Actor must fail this check (not true) */
    MustFail,
    };
    USTRUCT(BlueprintType)
    structFMFactionFilter
    {
    GENERATED_USTRUCT_BODY()
    UPROPERTY(EditAnywhere)
    EMFactionFilterMatchTypeFriendlyFaction;
    UPROPERTY(EditAnywhere)
    EMFactionFilterMatchTypeNeutralFaction;
    UPROPERTY(EditAnywhere)
    EMFactionFilterMatchTypeHostileFaction;
    boolPassesFilter(UAbilitySystemComponent*Source,UAbilitySystemComponent*Target);
    };
    USTRUCT(BlueprintType)
    structFMActorFilter
    {
    GENERATED_USTRUCT_BODY()
    UPROPERTY(EditAnywhere)
    EMActorFilterMatchTypeAllowSelf;
    boolPassesFilter(UAbilitySystemComponent*Source,UAbilitySystemComponent*Target);
    };
    // ----------------------------------------
    /*
    Assume NormalisedCharge and Ratio are both 0..1.f
    */
    UENUM()
    enumclassEMEffectLevelStrategy :uint8
    {
    /** The level is always the same */
    Base,
    /** Level is determined by BaseLevel + NormalisedCharge*VariableCharge */
    BaseVarianceCharge,
    /** Level is determined by BaseLevel + (1.0f - NormalisedCharge)*VariableCharge */
    BaseVarianceInvCharge,
    /** Level is determined by BaseLevel + (1.0f - Ratio)*VariableRatio */
    BaseVarianceRatio,
    /** Level is determined by BaseLevel + Ratio*VariableRatio */
    BaseVarianceInvRatio,
    /** Level is determined by BaseLevel + NormalisedCharge*VariableCharge + (1.0f - Ratio)*VariableRatio */
    BaseVarianceChargeInvRatio,
    /** Level is determined by BaseLevel + (1.0f - NormalisedCharge)*VariableCharge + (1.0f - Ratio)*VariableRatio */
    BaseVarianceInvChargeInvRatio,
    /** Level is determined by BaseLevel + NormalisedCharge*VariableCharge + Ratio*VariableRatio */
    BaseVarianceChargeRatio,
    /** Level is determined by BaseLevel + NormalisedCharge^2*VariableCharge */
    BaseVarianceChargeSquared,
    /** Level is determined by BaseLevel + NormalisedCharge^2*VariableCharge + Ratio^2*VariableRatio */
    BaseVarianceChargeSquaredRatioSquared,
    /** Level is determined by BaseLevel + NormalisedCharge^2*VariableCharge + (1.f-Ratio)^2*VariableRatio */
    BaseVarianceChargeSquaredInvRatioSquared,
    };
    USTRUCT(BlueprintType)
    structFMEffectModifier
    {
    GENERATED_USTRUCT_BODY()
    UPROPERTY(EditAnywhere)
    FNameModifierName;
    UPROPERTY(EditAnywhere)
    floatModifierMagnitude;
    UPROPERTY(EditAnywhere)
    EMEffectLevelStrategyModifierLevelStrategy;
    FMEffectModifier() :ModifierName(NAME_None),ModifierMagnitude(-1.f)
    {
    }
    FMEffectModifier(FNameModifier,floatMagnitude) :
    ModifierName(Modifier),
    ModifierMagnitude(Magnitude),
    ModifierLevelStrategy(EMEffectLevelStrategy::Base)
    {
    }
    FMEffectModifier(FNameModifier,floatMagnitude,EMEffectLevelStrategyModifierStrategy) :
    ModifierName(Modifier),
    ModifierMagnitude(Magnitude),
    ModifierLevelStrategy(ModifierStrategy)
    {
    }
    };
    USTRUCT(BlueprintType)
    structFMEffectItem
    {
    GENERATED_USTRUCT_BODY()
    FMEffectItem() :Level(1.f),StackCount(1)
    {
    }
    UPROPERTY(EditAnywhere)
    TSubclassOf<UGameplayEffect>GameplayEffect;
    UPROPERTY(EditAnywhere)
    floatLevel;
    UPROPERTY(EditAnywhere)
    int32StackCount;
    UPROPERTY(EditAnywhere)
    TArray<FMEffectModifier>Modifiers;
    UPROPERTY()
    FGameplayEffectSpecHandleGeneratedSpec;
    UPROPERTY(EditAnywhere)
    EMEffectLevelStrategyLevelStrategy;
    };
    USTRUCT(BlueprintType)
    structFMEffectApplicationItem
    {
    GENERATED_USTRUCT_BODY()
    UPROPERTY(EditAnywhere)
    FMActorFilterFilter;
    UPROPERTY(EditAnywhere)
    FMFactionFilterFactionFilter;
    UPROPERTY(EditAnywhere)
    TArray<FMEffectItem>Effects;
    };
    /** A generic utility struct that can hold a list of "Apply this GE (Spec, Level, StackCount) to actors matching this filter". */
    USTRUCT(BlueprintType)
    structFMEffectApplicationContainer
    {
    GENERATED_USTRUCT_BODY()
    UPROPERTY(EditAnywhere)
    TArray<FMEffectApplicationItem>Items;
    /** Cached source when specs are generated */
    UPROPERTY(BlueprintReadWrite)
    UAbilitySystemComponent*SourceAbilitySystemComponent;
    // Source is the instigator actor, AbilityOrigin is the spell actor
    voidInitialiseEffectContainer(AActor*Source,floatVariableLevel=0.f,floatNormalisedCharge=0.f,floatVariableRatio=0.f,floatNormalisedRatio=0.f,AActor*AbilityOrigin=nullptr,floatPeriod=1.f,boolbClean= false);
    floatGetLevelForEffect(FMEffectItem&Item,floatVariableLevel=0.f,floatNormalisedCharge=0.f,floatVariableRatio=0.f,floatNormalisedRatio=0.f);
    floatGetLevelForStrategy(EMEffectLevelStrategyStrategy,floatBase=0.f,floatVariableLevel=0.f,floatNormalisedCharge=0.f,floatVariableRatio=0.f,floatNormalisedRatio=0.f);
    voidGenerateEffectSpecs(AActor*Source,floatLevelOverride=0.f,int32StackOverride=0,AActor*AbilityOrigin=nullptr);
    voidSetCallerMagnitude(FNameAttributeName,floatMagnitude);
    voidSetCallerMagnitudeOnEffect(FNameAttributeName,floatMagnitude,TSubclassOf<UGameplayEffect>Effect);
    voidAddModifierForEffect(FNameAttributeName,floatMagnitude,TSubclassOf<UGameplayEffect>Effect);
    voidAddHitResult(FHitResultResult);
    TArray<FActiveGameplayEffectHandle>ApplyEffectApplicationContainerToTargetWithHandles(AActor*Target,classUBaseGameplayAbility*SourceAbility=nullptr);
    staticvoidPopulateEffectContainer(FMEffectApplicationContainer&Container,
    TSubclassOf<UGameplayEffect>Effect,
    floatLevel=0.f,
    EMActorFilterMatchTypeSelfFilter=EMActorFilterMatchType::Skip,
    EMFactionFilterMatchTypeFriendlyFilter=EMFactionFilterMatchType::Skip,
    EMFactionFilterMatchTypeNeutralFilter=EMFactionFilterMatchType::Skip,
    EMFactionFilterMatchTypeHostileFilter=EMFactionFilterMatchType::Skip);
    // returns true if any effect was applied successfully
    boolApplyEffectApplicationContainerToTarget(AActor*Target,classUBaseGameplayAbility*SourceAbility=nullptr,FHitResultHitResult=FHitResult(),EMCueSimulationSimulateCue=EMCueSimulation::Local);
    boolApplyEffectApplicationContainerToTargetASC(classUAsyncAbilitySystemComponent*TargetASC,FHitResultHitResult=FHitResult(),EMCueSimulationSimulateCue=EMCueSimulation::Local);
    };
    Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

    [8]ページ先頭

    ©2009-2025 Movatter.jp