mirror of
https://github.com/Ed94/Cog.git
synced 2026-06-13 08:02:23 -07:00
253 lines
11 KiB
C++
253 lines
11 KiB
C++
#include "CogSampleFunctionLibrary_Gameplay.h"
|
|
|
|
#include "Abilities/GameplayAbility.h"
|
|
#include "AbilitySystemComponent.h"
|
|
#include "AbilitySystemGlobals.h"
|
|
#include "CogSampleGameplayEffectContext.h"
|
|
#include "CogSampleTargetableInterface.h"
|
|
#include "Components/CapsuleComponent.h"
|
|
#include "GameFramework/Character.h"
|
|
#include "GameplayCueNotifyTypes.h"
|
|
#include "GameplayEffectTypes.h"
|
|
#include "Kismet/KismetMathLibrary.h"
|
|
#include "Particles/ParticleSystemComponent.h"
|
|
#include "ScalableFloat.h"
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
void UCogSampleFunctionLibrary_Gameplay::AdjustAttributeForMaxChange(UAbilitySystemComponent* AbilityComponent, FGameplayAttributeData& AffectedAttribute, float OldValue, float NewMaxValue, const FGameplayAttribute& AffectedAttributeProperty)
|
|
{
|
|
if (AbilityComponent == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (FMath::IsNearlyEqual(OldValue, NewMaxValue))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Change current value to maintain the current Val / Max percent
|
|
const float CurrentValue = AffectedAttribute.GetCurrentValue();
|
|
const float NewDelta = (OldValue > 0.f) ? (CurrentValue * NewMaxValue / OldValue) - CurrentValue : NewMaxValue;
|
|
|
|
AbilityComponent->ApplyModToAttributeUnsafe(AffectedAttributeProperty, EGameplayModOp::Additive, NewDelta);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
FVector UCogSampleFunctionLibrary_Gameplay::GetActorBottomLocation(const AActor* Actor)
|
|
{
|
|
const FVector Location = Actor->GetActorLocation();
|
|
|
|
if (const ACharacter* Character = Cast<ACharacter>(Actor))
|
|
{
|
|
const UCapsuleComponent* CapsuleComponent = Character->GetCapsuleComponent();
|
|
const FVector BottomLocation = Location - FVector::UpVector * CapsuleComponent->GetScaledCapsuleHalfHeight();
|
|
return BottomLocation;
|
|
}
|
|
|
|
return Location;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
bool UCogSampleFunctionLibrary_Gameplay::FindAbilitySpecHandleFromClass(UAbilitySystemComponent* AbilitySystemComponent, TSubclassOf<UGameplayAbility> AbilityClass, FGameplayAbilitySpecHandle& SpecHandle)
|
|
{
|
|
if (const FGameplayAbilitySpec* Spec = AbilitySystemComponent->FindAbilitySpecFromClass(AbilityClass))
|
|
{
|
|
SpecHandle = Spec->Handle;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
void UCogSampleFunctionLibrary_Gameplay::ApplyAllGameplayEffectContextValues(const FGameplayCueParameters& Parameters, const FGameplayCueNotify_SpawnResult& SpawnResult)
|
|
{
|
|
TArray<FCogSampleGameplayEffectContextFloatValue> Entries;
|
|
UCogSampleEffectContextLibrary::EffectContextGetAllFloatValues(Parameters.EffectContext, Entries);
|
|
|
|
for (TObjectPtr<UFXSystemComponent> FXSystemComponent : SpawnResult.FxSystemComponents)
|
|
{
|
|
if (UFXSystemComponent* FXSystemComponentPtr = FXSystemComponent.Get())
|
|
{
|
|
for (const FCogSampleGameplayEffectContextFloatValue& Entry : Entries)
|
|
{
|
|
FXSystemComponentPtr->SetFloatParameter(Entry.Name, Entry.Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
void UCogSampleFunctionLibrary_Gameplay::SendMontageEvent(AActor* Actor, FGameplayTag EventTag, FGameplayEventData Payload)
|
|
{
|
|
if (::IsValid(Actor))
|
|
{
|
|
UAbilitySystemComponent* AbilitySystemComponent = UAbilitySystemGlobals::GetAbilitySystemComponentFromActor(Actor);
|
|
if (AbilitySystemComponent != nullptr && IsValidChecked(AbilitySystemComponent))
|
|
{
|
|
FScopedPredictionWindow NewScopedWindow(AbilitySystemComponent, true);
|
|
AbilitySystemComponent->HandleGameplayEvent(EventTag, &Payload);
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
float UCogSampleFunctionLibrary_Gameplay::GetFloatValue(const FScalableFloat& ScalableFloat, int32 Level)
|
|
{
|
|
return ScalableFloat.GetValueAtLevel(Level);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
bool UCogSampleFunctionLibrary_Gameplay::GetBoolValue(const FScalableFloat& ScalableFloat, int32 Level)
|
|
{
|
|
return ScalableFloat.GetValueAtLevel(Level) > 0;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
int32 UCogSampleFunctionLibrary_Gameplay::GetIntValue(const FScalableFloat& ScalableFloat, int32 Level)
|
|
{
|
|
return (int32)ScalableFloat.GetValueAtLevel(Level);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
FCollisionObjectQueryParams UCogSampleFunctionLibrary_Gameplay::ConfigureCollisionObjectParams(const TArray<TEnumAsByte<EObjectTypeQuery>>& ObjectTypes)
|
|
{
|
|
TArray<TEnumAsByte<ECollisionChannel>> CollisionObjectTraces;
|
|
CollisionObjectTraces.AddUninitialized(ObjectTypes.Num());
|
|
|
|
for (auto Iter = ObjectTypes.CreateConstIterator(); Iter; ++Iter)
|
|
{
|
|
CollisionObjectTraces[Iter.GetIndex()] = UEngineTypes::ConvertToCollisionChannel(*Iter);
|
|
}
|
|
|
|
FCollisionObjectQueryParams ObjectParams;
|
|
for (auto Iter = CollisionObjectTraces.CreateConstIterator(); Iter; ++Iter)
|
|
{
|
|
const ECollisionChannel& Channel = (*Iter);
|
|
if (FCollisionObjectQueryParams::IsValidObjectQuery(Channel))
|
|
{
|
|
ObjectParams.AddObjectTypesToQuery(Channel);
|
|
}
|
|
}
|
|
|
|
return ObjectParams;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
FVector UCogSampleFunctionLibrary_Gameplay::GetActorTargetLocation(const AActor* Actor)
|
|
{
|
|
if (Actor == nullptr)
|
|
{
|
|
return FVector::ZeroVector;
|
|
}
|
|
|
|
if (const ICogSampleTargetableInterface* Targetable = Cast<ICogSampleTargetableInterface>(Actor))
|
|
{
|
|
return Targetable->GetTargetLocation();
|
|
}
|
|
|
|
return Actor->GetActorLocation();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
float UCogSampleFunctionLibrary_Gameplay::AngleBetweenVector2D(FVector2D A, FVector2D B)
|
|
{
|
|
A.Normalize();
|
|
B.Normalize();
|
|
return FMath::RadiansToDegrees(FMath::Acos(FVector2D::DotProduct(A, B)));
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
void UCogSampleFunctionLibrary_Gameplay::FindSegmentPointDistance(const FVector2D& Segment1, const FVector2D& Segment2, const FVector2D& Point, FVector2D& Projection, float& Time, float& Distance)
|
|
{
|
|
const float DistSquared = FVector2D::DistSquared(Segment1, Segment2);
|
|
if (FMath::IsNearlyZero(DistSquared))
|
|
{
|
|
Time = 0.0f;
|
|
Projection = Segment1;
|
|
Distance = FVector2D::Distance(Point, Segment1);
|
|
}
|
|
else
|
|
{
|
|
Time = FMath::Max(0.0f, FMath::Min(1.0f, FVector2D::DotProduct(Point - Segment1, Segment2 - Segment1) / DistSquared));
|
|
Projection = Segment1 + Time * (Segment2 - Segment1);
|
|
Distance = FVector2D::Distance(Point, Projection);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
void UCogSampleFunctionLibrary_Gameplay::FindCapsulePointDistance(const FVector2D& CapsulePoint1, const FVector2D& CapsulePoint2, const float CapsuleRadius, const FVector2D& Point, FVector2D& Projection, float& Time, float& Distance)
|
|
{
|
|
FindSegmentPointDistance(CapsulePoint1, CapsulePoint2, Point, Projection, Time, Distance);
|
|
|
|
float projectionToPointDistance = Distance;
|
|
Distance -= CapsuleRadius;
|
|
|
|
if (Distance > 0.0f)
|
|
{
|
|
Projection = Point + ((Projection - Point) / projectionToPointDistance) * Distance;
|
|
}
|
|
else
|
|
{
|
|
Projection = Point;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
FVector2D UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(const FVector2D& value, const FVector2D& displaySize)
|
|
{
|
|
FVector2D result;
|
|
|
|
if (displaySize.X > displaySize.Y)
|
|
{
|
|
const float screenXStart = (displaySize.X - displaySize.Y) * 0.5f;
|
|
const float screenXEnd = displaySize.X - screenXStart;
|
|
result.X = UKismetMathLibrary::MapRangeUnclamped(value.X, -1.0f, 1.0f, screenXStart, screenXEnd);
|
|
result.Y = UKismetMathLibrary::MapRangeUnclamped(value.Y, -1.0f, 1.0f, displaySize.Y, 0.0f);
|
|
}
|
|
else
|
|
{
|
|
const float ScreenYStart = (displaySize.Y - displaySize.X) * 0.5f;
|
|
const float ScreenYEnd = displaySize.Y - ScreenYStart;
|
|
result.X = UKismetMathLibrary::MapRangeUnclamped(value.X, -1.0f, 1.0f, 0.0f, displaySize.X);
|
|
result.Y = UKismetMathLibrary::MapRangeUnclamped(value.Y, -1.0f, 1.0f, ScreenYEnd, ScreenYStart);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
float UCogSampleFunctionLibrary_Gameplay::ViewportToScreen(const float Value, const FVector2D& DisplaySize)
|
|
{
|
|
return Value * 0.5f * FMath::Min(DisplaySize.X, DisplaySize.Y);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
FVector2D UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const FVector2D& Value, const FVector2D& DisplaySize)
|
|
{
|
|
FVector2D Result;
|
|
|
|
if (DisplaySize.X > DisplaySize.Y)
|
|
{
|
|
const float screenXStart = (DisplaySize.X - DisplaySize.Y) * 0.5f;
|
|
const float screenXEnd = DisplaySize.X - screenXStart;
|
|
Result.X = UKismetMathLibrary::MapRangeUnclamped(Value.X, screenXStart, screenXEnd, -1.0f, 1.0f);
|
|
Result.Y = UKismetMathLibrary::MapRangeUnclamped(Value.Y, 0.0f, DisplaySize.Y, -1.0f, 1.0f);
|
|
}
|
|
else
|
|
{
|
|
const float screenYStart = (DisplaySize.Y - DisplaySize.X) * 0.5f;
|
|
const float screenYEnd = DisplaySize.Y - screenYStart;
|
|
Result.X = UKismetMathLibrary::MapRangeUnclamped(Value.X, 0.0f, DisplaySize.X, -1.0f, 1.0f);
|
|
Result.Y = UKismetMathLibrary::MapRangeUnclamped(Value.Y, screenYStart, screenYEnd, -1.0f, 1.0f);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------------------------
|
|
float UCogSampleFunctionLibrary_Gameplay::ScreenToViewport(const float Value, const FVector2D& DisplaySize)
|
|
{
|
|
return Value * 2.0f / FMath::Min(DisplaySize.X, DisplaySize.Y);
|
|
} |